react-resizable-panels 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,81 @@
1
+ import { ReactNode, useContext, useEffect, useState } from "react";
2
+
3
+ import { PanelGroupContext } from "./PanelContexts";
4
+ import { PanelId, ResizeHandler } from "./types";
5
+
6
+ export default function PanelResizeHandle({
7
+ children = null,
8
+ className = "",
9
+ disabled = false,
10
+ panelAfter,
11
+ panelBefore,
12
+ }: {
13
+ children?: ReactNode;
14
+ className?: string;
15
+ disabled?: boolean;
16
+ panelAfter: PanelId;
17
+ panelBefore: PanelId;
18
+ }) {
19
+ const context = useContext(PanelGroupContext);
20
+ if (context === null) {
21
+ throw Error(`PanelResizeHandle components must be rendered within a PanelGroup container`);
22
+ }
23
+
24
+ const { direction, registerResizeHandle } = context;
25
+
26
+ const [resizeHandler, setResizeHandler] = useState<ResizeHandler | null>(null);
27
+ const [isDragging, setIsDragging] = useState(false);
28
+
29
+ useEffect(() => {
30
+ if (disabled) {
31
+ setResizeHandler(null);
32
+ } else {
33
+ setResizeHandler(() => registerResizeHandle(panelBefore, panelAfter));
34
+ }
35
+ }, [disabled, panelAfter, panelBefore, registerResizeHandle]);
36
+
37
+ useEffect(() => {
38
+ if (disabled || resizeHandler == null || !isDragging) {
39
+ return;
40
+ }
41
+
42
+ document.body.style.cursor = direction === "horizontal" ? "ew-resize" : "ns-resize";
43
+
44
+ const onMouseLeave = (_: MouseEvent) => {
45
+ setIsDragging(false);
46
+ };
47
+
48
+ const onMouseMove = (event: MouseEvent) => {
49
+ resizeHandler(event);
50
+ };
51
+
52
+ const onMouseUp = (_: MouseEvent) => {
53
+ setIsDragging(false);
54
+ };
55
+
56
+ document.body.addEventListener("mouseleave", onMouseLeave);
57
+ document.body.addEventListener("mousemove", onMouseMove);
58
+ document.body.addEventListener("mouseup", onMouseUp);
59
+
60
+ return () => {
61
+ document.body.style.cursor = "";
62
+
63
+ document.body.removeEventListener("mouseleave", onMouseLeave);
64
+ document.body.removeEventListener("mousemove", onMouseMove);
65
+ document.body.removeEventListener("mouseup", onMouseUp);
66
+ };
67
+ }, [direction, disabled, isDragging, resizeHandler]);
68
+
69
+ return (
70
+ <div
71
+ className={className}
72
+ onMouseDown={() => setIsDragging(true)}
73
+ onMouseUp={() => setIsDragging(false)}
74
+ style={{
75
+ cursor: direction === 'horizontal' ? 'ew-resize' : 'ns-resize'
76
+ }}
77
+ >
78
+ {children}
79
+ </div>
80
+ );
81
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ import Panel from "./Panel";
2
+ import PanelGroup from "./PanelGroup";
3
+ import PanelResizeHandle from "./PanelResizeHandle";
4
+
5
+ export { Panel, PanelGroup, PanelResizeHandle };
package/src/types.ts ADDED
@@ -0,0 +1,11 @@
1
+ export type Direction = "horizontal" | "vertical";
2
+
3
+ export type PanelId = string;
4
+
5
+ export type Panel = {
6
+ defaultSize: number;
7
+ id: PanelId;
8
+ minSize: number;
9
+ };
10
+
11
+ export type ResizeHandler = (event: MouseEvent) => void;
package/tsconfig.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["ES2015", "DOM"],
4
+ "jsx": "react-jsx"
5
+ }
6
+ }
@@ -0,0 +1,140 @@
1
+ import AutoSizer from "react-virtualized-auto-sizer";
2
+
3
+ import { Panel, PanelGroup, PanelResizeHandle } from "../src";
4
+
5
+ import styles from "./styles.module.css";
6
+
7
+ function clearSavedSizes() {
8
+ localStorage.removeItem("PanelGroup:sizes:inner-horizontal");
9
+ localStorage.removeItem("PanelGroup:sizes:outer-horizontal");
10
+ localStorage.removeItem("PanelGroup:sizes:vertical");
11
+
12
+ window.location.reload();
13
+ }
14
+
15
+ export default function App() {
16
+ return (
17
+ <div className={styles.FullHeightAndWidth}>
18
+ <AutoSizer>
19
+ {({ height, width }) => (
20
+ <PanelGroup
21
+ height={height}
22
+ width={width}
23
+ autoSaveId="outer-horizontal"
24
+ direction="horizontal"
25
+ >
26
+ <Panel className={styles.PanelRow} defaultSize={0.2} id="left">
27
+ <div className={styles.HorizontalFiller}>
28
+ left [1]
29
+ <br />
30
+ <br />
31
+ <button
32
+ className={styles.ResetButton}
33
+ onClick={clearSavedSizes}
34
+ >
35
+ reset sizes
36
+ </button>
37
+ </div>
38
+ </Panel>
39
+ <Panel className={styles.PanelRow} defaultSize={0.4} id="middle">
40
+ <PanelResizeHandle
41
+ className={styles.HorizontalResizeHandle}
42
+ panelBefore="left"
43
+ panelAfter="middle"
44
+ />
45
+ <div className={styles.HorizontalFiller}>middle [3]</div>
46
+ <PanelResizeHandle
47
+ className={styles.HorizontalResizeHandle}
48
+ panelBefore="middle"
49
+ panelAfter="stacked"
50
+ />
51
+ </Panel>
52
+ <Panel className={styles.PanelRow} defaultSize={0.3} id="stacked">
53
+ <div className={styles.Grower}>
54
+ <AutoSizer>
55
+ {({ height, width }) => (
56
+ <PanelGroup
57
+ height={height}
58
+ width={width}
59
+ autoSaveId="vertical"
60
+ direction="vertical"
61
+ >
62
+ <Panel
63
+ className={styles.PanelRow}
64
+ defaultSize={0.4}
65
+ id="top"
66
+ >
67
+ <div className={styles.VerticalFillerTop}>
68
+ top [2, 1]
69
+ </div>
70
+ </Panel>
71
+ <Panel
72
+ className={styles.PanelColumn}
73
+ defaultSize={0.6}
74
+ id="bottom"
75
+ >
76
+ <PanelResizeHandle
77
+ panelBefore="top"
78
+ panelAfter="bottom"
79
+ >
80
+ <div className={styles.VerticalResizeBar} />
81
+ </PanelResizeHandle>
82
+ <div className={styles.VerticalFillerBottom}>
83
+ <AutoSizer>
84
+ {({ height, width }) => (
85
+ <PanelGroup
86
+ height={height}
87
+ width={width}
88
+ autoSaveId="inner-horizontal"
89
+ direction="horizontal"
90
+ >
91
+ <Panel
92
+ className={styles.PanelRow}
93
+ defaultSize={0.5}
94
+ id="bottom-left"
95
+ >
96
+ <div className={styles.HorizontalFillerLeft}>
97
+ bottom-left [2, 2, 1]
98
+ </div>
99
+ </Panel>
100
+ <Panel
101
+ className={styles.PanelRow}
102
+ defaultSize={0.5}
103
+ id="bottom-right"
104
+ >
105
+ <PanelResizeHandle
106
+ panelBefore="bottom-left"
107
+ panelAfter="bottom-right"
108
+ >
109
+ <div
110
+ className={styles.HorizontalResizeBar}
111
+ />
112
+ </PanelResizeHandle>
113
+ <div className={styles.HorizontalFillerRight}>
114
+ bottom-right [2, 2, 1]
115
+ </div>
116
+ </Panel>
117
+ </PanelGroup>
118
+ )}
119
+ </AutoSizer>
120
+ </div>
121
+ </Panel>
122
+ </PanelGroup>
123
+ )}
124
+ </AutoSizer>
125
+ </div>
126
+ </Panel>
127
+ <Panel className={styles.PanelRow} defaultSize={0.2} id="right">
128
+ <PanelResizeHandle
129
+ className={styles.HorizontalResizeHandle}
130
+ panelBefore="stacked"
131
+ panelAfter="right"
132
+ />
133
+ <div className={styles.HorizontalFiller}>right [1]</div>
134
+ </Panel>
135
+ </PanelGroup>
136
+ )}
137
+ </AutoSizer>
138
+ </div>
139
+ );
140
+ }
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <html>
3
+ <link rel="stylesheet" href="./root.css" />
4
+ </html>
5
+ <body>
6
+ <div id="root"></div>
7
+ <script type="module" src="index.tsx"></script>
8
+ </body>
9
+ </html>
@@ -0,0 +1,12 @@
1
+ import { StrictMode } from "react";
2
+ import { createRoot } from "react-dom/client";
3
+
4
+ import Demo from "./demo";
5
+
6
+ const rootElement = document.getElementById("root");
7
+ const root = createRoot(rootElement);
8
+ root.render(
9
+ <StrictMode>
10
+ <Demo />
11
+ </StrictMode>
12
+ );
@@ -0,0 +1,15 @@
1
+ :root, html, body {
2
+ width: 100vw;
3
+ height: 100vh;
4
+ padding: 0;
5
+ margin: 0;
6
+ overflow: hidden;
7
+
8
+ background-color: #081120;
9
+ color: #ffffff;
10
+ }
11
+
12
+ #root {
13
+ width: calc(100vw - 1rem);
14
+ height: calc(100vh - 1rem);
15
+ }
@@ -0,0 +1,77 @@
1
+ .FullHeightAndWidth {
2
+ width: calc(100vw - 1rem);
3
+ height: calc(100vh - 1rem);
4
+ margin: 0.5rem;
5
+ }
6
+
7
+ .Grower {
8
+ width: 100%;
9
+ height: 100%;
10
+ }
11
+
12
+ .HorizontalFiller,
13
+ .HorizontalFillerLeft,
14
+ .HorizontalFillerRight,
15
+ .VerticalFillerBottom,
16
+ .VerticalFillerTop {
17
+ height: 100%;
18
+ width: 100%;
19
+ background-color: #192230;
20
+ display: flex;
21
+ flex-direction: column;
22
+ align-items: center;
23
+ justify-content: center;
24
+ overflow: hidden;
25
+ }
26
+ .HorizontalFiller {
27
+ border-radius: 0.5rem;
28
+ }
29
+ .VerticalFillerTop {
30
+ border-top-left-radius: 0.5rem;
31
+ border-top-right-radius: 0.5rem;
32
+ }
33
+ .VerticalFillerBottom {
34
+ border-bottom-left-radius: 0.5rem;
35
+ border-bottom-right-radius: 0.5rem;
36
+ }
37
+
38
+ .PanelRow {
39
+ display: flex;
40
+ flex-direction: row;
41
+ }
42
+ .PanelColumn {
43
+ display: flex;
44
+ flex-direction: column;
45
+ }
46
+
47
+ .HorizontalResizeHandle {
48
+ padding: 0 0.25rem;
49
+ }
50
+
51
+ .VerticalResizeBar {
52
+ height: 4px;
53
+ width: 100%;
54
+ background-color: #2a3343;
55
+ border-bottom: 1px solid #454950;
56
+ border-top: 1px solid #454950;
57
+ }
58
+
59
+ .HorizontalResizeBar {
60
+ height: 100%;
61
+ width: 4px;
62
+ background-color: #2a3343;
63
+ border-left: 1px solid #454950;
64
+ border-right: 1px solid #454950;
65
+ }
66
+
67
+ .ResetButton {
68
+ color: #ffffff;
69
+ background: #2a3343;
70
+ border: 1px solid #18181a;
71
+ border-radius: 0.25rem;
72
+ padding: 0.25rem 0.5rem;
73
+ cursor: pointer;
74
+ }
75
+ .ResetButton:hover {
76
+ background: #454950;
77
+ }