Skip to content

Commit 279497c

Browse files
Merge pull request #64 from gridaco/staging
add `@code-editor/preview-pip`
2 parents be07129 + 4b896bd commit 279497c

File tree

12 files changed

+610
-21
lines changed

12 files changed

+610
-21
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016-2018 Samuel Reed
4+
Copyright (c) 2021 Grida Inc, softmarshmallow
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# PIP - Picture in picture
2+
3+
Picture in picture mode of preview inside the viewport for viewing UI Previews in more ux friendly way.
4+
5+
# Resizable-PIP
6+
7+
A resizable picture-in-picture component for React.
8+
9+
```js
10+
<ResizablePIP>
11+
<div>I can be resized and moved around!</div>
12+
</ResizablePIP>
13+
```
14+
15+
![](ResizablePIP.gif)
16+
17+
### Installing
18+
19+
```bash
20+
$ yarn add @code-editor/preview-pip
21+
```
22+
23+
### Usage
24+
25+
This package has two major exports:
26+
27+
- [`<ResizablePIP>`](/lib/resizable-pip.tsx): A simple PIP component that can be resized and moved around.
28+
- [`<PIP>`](/lib/pip.tsx): A simple PIP component that does not receive props and cannot be resized. Used as a base for the ResizablePIP component.
29+
30+
## `<ResizablePIP>`
31+
32+
A `<ResizablePIP>` element wraps an existing element and extends it with the ability to be resized and moved around, above all content in the app.
33+
34+
### ResizablePIP Usage
35+
36+
View the [source](/src/lib/components/ResizablePIP.jsx) for more.
37+
38+
```js
39+
import { ResizablePIP } from "@code-editor/preview-pip";
40+
41+
function App() {
42+
return (
43+
<div>
44+
<ResizablePIP
45+
width={500}
46+
heigt={500}
47+
minConstraints={[300, 300]}
48+
maxConstraints={[800, 800]}
49+
>
50+
<p>
51+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
52+
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
53+
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
54+
aliquip ex ea commodo consequat. Duis aute irure dolor in
55+
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
56+
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
57+
culpa qui officia deserunt mollit anim id est laborum.
58+
</p>
59+
</ResizablePIP>
60+
</div>
61+
);
62+
}
63+
64+
export default App;
65+
```
66+
67+
#### `<ResizablePIP>` Props:
68+
69+
```ts
70+
71+
//
72+
// Props:
73+
//
74+
{
75+
// Specifies initial PIP window width.
76+
// Example: 600
77+
// Default value: 500
78+
width: number,
79+
80+
// Specifies initial PIP window height.
81+
// Example: 600
82+
// Default value: 500
83+
height: number,
84+
85+
// Specifies the minimum size possible for the PIP window (width, height).
86+
// Example: [100, 100]
87+
// Default value: [300, 300]
88+
minConstraints: [number, number]
89+
90+
// Specifies the maximum size possible for the PIP window (width, height).
91+
// Example: [900, 900]
92+
// Default value: [800, 800]
93+
maxConstraints: [number, number]
94+
}
95+
```
96+
97+
## References
98+
99+
https://www.w3.org/TR/picture-in-picture/
100+
101+
## Disclaimer
102+
103+
The origin source was forked from - https://github.com/itielMaimon/resizable-pip under MIT License
104+
105+
### License
106+
107+
MIT
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
presets: [
3+
[
4+
"@babel/env",
5+
{
6+
targets: {
7+
edge: "17",
8+
firefox: "60",
9+
chrome: "67",
10+
safari: "11.1",
11+
},
12+
useBuiltIns: "usage",
13+
corejs: "3.6.5",
14+
},
15+
],
16+
"@babel/preset-react",
17+
],
18+
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import PIP from "./pip";
2+
import ResizablePIP from "./resizable-pip";
3+
4+
export { PIP, ResizablePIP };
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import React from "react";
2+
import Draggable from "react-draggable";
3+
import styled from "@emotion/styled";
4+
5+
interface DraggingBoxStyle {
6+
outline: string;
7+
outlineColor: string;
8+
outlineStyle: string;
9+
outlineWidth: number | string;
10+
}
11+
12+
const unit = (u: string | number) => {
13+
if (typeof u === "number") {
14+
return `${u}px`;
15+
}
16+
return u;
17+
};
18+
19+
function PIP({
20+
children,
21+
zIndex = 100,
22+
boxShadow = "1px 3px 3px 0 rgb(0 0 0 / 20%), 1px 3px 15px 2px rgb(0 0 0 / 20%)",
23+
borderRadius = "0.3rem",
24+
hoverCursor = "grab",
25+
draggingCursor = "grabbing",
26+
backgroundColor = "#242d36",
27+
draggingStyle = {
28+
outline: "-webkit-focus-ring-color auto 1px",
29+
outlineColor: "-webkit-focus-ring-color",
30+
outlineStyle: "auto",
31+
outlineWidth: 1,
32+
},
33+
}: {
34+
children: React.ReactNode;
35+
/**
36+
* @default 100
37+
*/
38+
zIndex?: number;
39+
/**
40+
* boxshadow css as string
41+
* @default "1px 3px 3px 0 rgb(0 0 0 / 20%), 1px 3px 15px 2px rgb(0 0 0 / 20%)"
42+
*/
43+
boxShadow?: string;
44+
/**
45+
* px in number or other unit (e.g. rem) as string
46+
* @default "0.3rem"
47+
*/
48+
borderRadius?: string | number;
49+
/**
50+
* @default grab
51+
*/
52+
hoverCursor?: string;
53+
/**
54+
* @default grabbing
55+
*/
56+
draggingCursor?: string;
57+
draggingStyle?: DraggingBoxStyle;
58+
/**
59+
* @default #242d36
60+
*/
61+
backgroundColor?: string;
62+
}) {
63+
return (
64+
<Draggable>
65+
<PipWindow
66+
borderRadius={borderRadius}
67+
boxShadow={boxShadow}
68+
zIndex={zIndex}
69+
hoverCursor={hoverCursor}
70+
draggingCursor={draggingCursor}
71+
draggingStyle={draggingStyle}
72+
backgroundColor={backgroundColor}
73+
>
74+
{children}
75+
</PipWindow>
76+
</Draggable>
77+
);
78+
}
79+
80+
const PipWindow = styled.div<{
81+
zIndex: number;
82+
boxShadow: string;
83+
borderRadius: string | number;
84+
hoverCursor: string;
85+
draggingCursor: string;
86+
draggingStyle: DraggingBoxStyle;
87+
backgroundColor: string;
88+
}>`
89+
background-color: ${(props) => props.backgroundColor};
90+
z-index: ${(props) => props.zIndex};
91+
position: fixed;
92+
color: rgb(248, 248, 249);
93+
box-sizing: content-box;
94+
box-shadow: ${(props) => props.boxShadow};
95+
border-radius: ${(props) => unit(props.boxShadow)};
96+
97+
:hover {
98+
cursor: ${(props) => props.hoverCursor};
99+
}
100+
101+
:active {
102+
cursor: ${(props) => props.draggingCursor};
103+
outline: ${(props) => props.draggingStyle.outline};
104+
outline-color: ${(props) => props.draggingStyle.outlineColor};
105+
outline-style: ${(props) => props.draggingStyle.outlineStyle};
106+
outline-width: ${(props) => unit(props.draggingStyle.outlineWidth)};
107+
}
108+
`;
109+
110+
export default PIP;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import React from "react";
2+
import PIP from "./PIP";
3+
import { ResizableBox } from "react-resizable";
4+
import type { ResizableBoxProps as RawResizableBoxProps } from "react-resizable";
5+
import styled from "@emotion/styled";
6+
7+
interface ResizableBoxProps
8+
extends Omit<RawResizableBoxProps, "width" | "height"> {
9+
/**
10+
* axis to allow resize to
11+
* @default "both"
12+
*/
13+
axis?: "x" | "y" | "both" | "none";
14+
15+
/**
16+
* resize handle to display - a react component
17+
* @default none
18+
*/
19+
resizeHandle?: React.ReactNode;
20+
/**
21+
* @default 500
22+
*/
23+
width?: number;
24+
/**
25+
* @default 500
26+
*/
27+
height?: number;
28+
/**
29+
* @default [300, 300]
30+
*/
31+
minConstraints?: [number, number];
32+
/**
33+
* @default [800, 800]
34+
*/
35+
maxConstraints?: [number, number];
36+
}
37+
38+
type ResizablePIPProps = {
39+
children?: React.ReactNode;
40+
} & ResizableBoxProps;
41+
42+
function ResizablePIP({
43+
children,
44+
axis = "both",
45+
resizeHandle,
46+
width = 500,
47+
height = 500,
48+
minConstraints = [300, 300],
49+
maxConstraints = [800, 800],
50+
...otherResizableProps
51+
}: ResizablePIPProps) {
52+
return (
53+
<PIP>
54+
<StyledResizableBox
55+
{...otherResizableProps}
56+
axis={axis}
57+
handle={resizeHandle}
58+
width={width}
59+
height={height}
60+
minConstraints={minConstraints}
61+
maxConstraints={maxConstraints}
62+
>
63+
{children}
64+
</StyledResizableBox>
65+
</PIP>
66+
);
67+
}
68+
69+
const StyledResizableBox = styled(ResizableBox)`
70+
overflow: auto;
71+
72+
:hover {
73+
cursor: default;
74+
}
75+
`;
76+
77+
export default ResizablePIP;

0 commit comments

Comments
 (0)