diff --git a/packages/react-resizable-panels-website/root.css b/packages/react-resizable-panels-website/root.css index bd7e38c0c..1e7039153 100644 --- a/packages/react-resizable-panels-website/root.css +++ b/packages/react-resizable-panels-website/root.css @@ -35,13 +35,6 @@ code { border-radius: 0.25em; } -hr { - width: 100%; - height: 1px; - border: none; - background-color: #454950; -} - h2 { font-weight: normal; margin: 0.5rem 0; diff --git a/packages/react-resizable-panels-website/src/HorizontalGroup.tsx b/packages/react-resizable-panels-website/src/HorizontalGroup.tsx index 5e37c5f45..e57481808 100644 --- a/packages/react-resizable-panels-website/src/HorizontalGroup.tsx +++ b/packages/react-resizable-panels-website/src/HorizontalGroup.tsx @@ -72,7 +72,7 @@ export default function HorizontalGroup({ reset vertical sizes
-
+ - )} -
- - {isPanelHidden || ( +
+ + {showTopPanel && ( + +
+

+ This is a "vertical" PanelGroup. +

+

+ +

+
+ +
+ + + )} - -
- -
+

- This panel's visibility can be toggled on or off. + This panel uses the minSize prop to prevent it from + shrinking to less than 35% of the total height.

-

- -

+ )} + + {!showBottomPanel && ( + + )}
- )} - + {showBottomPanel && ( + + +
+ +
+

+ This group uses a solid resize bar, similar to Chrome devtools + or VS Code. +

+

+ +

+
+ + )} + +
); } diff --git a/packages/react-resizable-panels-website/src/styles.module.css b/packages/react-resizable-panels-website/src/styles.module.css index ebf8f68e6..dd5e9a1e0 100644 --- a/packages/react-resizable-panels-website/src/styles.module.css +++ b/packages/react-resizable-panels-website/src/styles.module.css @@ -15,12 +15,9 @@ .HorizontalFiller, .HorizontalFillerLeft, .HorizontalFillerRight, -.VerticalFiller, -.VerticalFillerBottom, -.VerticalFillerTop { +.VerticalFiller { height: 100%; width: 100%; - background-color: #192230; display: flex; flex-direction: column; align-items: center; @@ -31,14 +28,6 @@ .VerticalFiller { border-radius: 0.5rem; } -.VerticalFillerTop { - border-top-left-radius: 0.5rem; - border-top-right-radius: 0.5rem; -} -.VerticalFillerBottom { - border-bottom-left-radius: 0.5rem; - border-bottom-right-radius: 0.5rem; -} .PanelRow { display: flex; @@ -62,7 +51,8 @@ } .Button, -.ButtonBottom { +.ButtonBottom, +.ButtonTop { color: #ffffff; background: #2a3343; border: 1px solid #18181a; @@ -71,7 +61,8 @@ cursor: pointer; } .Button:hover, -.ButtonBottom:hover { +.ButtonBottom:hover, +.ButtonTop:hover { background: #454950; } @@ -101,3 +92,17 @@ bottom: 1ch; right: 1ch; } +.ButtonTop { + position: absolute; + top: 1ch; + right: 1ch; +} + +.HorizontalDivider { + display: block; + width: 100%; + height: 1px; + border: none; + background-color: #454950; + margin: 0.5rem 0; +} diff --git a/packages/react-resizable-panels/CHANGELOG.md b/packages/react-resizable-panels/CHANGELOG.md index 36dc47938..1afa7b552 100644 --- a/packages/react-resizable-panels/CHANGELOG.md +++ b/packages/react-resizable-panels/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 0.0.4 +* [#8](https://github.com/bvaughn/react-resizable-panels/issues/8): Added optional `order` prop to `Panel` to improve conditional rendering. + ## 0.0.3 * [#3](https://github.com/bvaughn/react-resizable-panels/issues/3): `Panel`s can be conditionally rendered within a group. `PanelGroup` will persist separate layouts for each combination of visible panels. diff --git a/packages/react-resizable-panels/README.md b/packages/react-resizable-panels/README.md index 28f45788f..745887f4f 100644 --- a/packages/react-resizable-panels/README.md +++ b/packages/react-resizable-panels/README.md @@ -39,6 +39,7 @@ import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels"; | `defaultSize` | `?number` | Initial size of panel (relative to other panels within the group) | `id` | `string` | Panel id (must be unique within the current group) | `minSize` | `?number` | Minum allowable size of panel (0.0 - 1.0) +| `order` | `?number` | Order of panel within group; required for groups with conditionally rendered panels ### `PanelResizeHandle` | prop | type | description diff --git a/packages/react-resizable-panels/src/Panel.tsx b/packages/react-resizable-panels/src/Panel.tsx index 0c29f09c4..d23492892 100644 --- a/packages/react-resizable-panels/src/Panel.tsx +++ b/packages/react-resizable-panels/src/Panel.tsx @@ -11,12 +11,14 @@ export default function Panel({ defaultSize = 0.1, id, minSize = 0.1, + order = null, }: { children?: ReactNode; className?: string; defaultSize?: number; id: string; minSize?: number; + order?: number | null; }) { const context = useContext(PanelGroupContext); if (context === null) { @@ -40,6 +42,7 @@ export default function Panel({ defaultSize, id, minSize, + order, }; registerPanel(id, panel); @@ -47,7 +50,7 @@ export default function Panel({ return () => { unregisterPanel(id); }; - }, [defaultSize, id, minSize, registerPanel, unregisterPanel]); + }, [defaultSize, id, minSize, order, registerPanel, unregisterPanel]); const style = getPanelStyle(id); diff --git a/packages/react-resizable-panels/src/PanelGroup.tsx b/packages/react-resizable-panels/src/PanelGroup.tsx index 5a80d1dff..998e4f13e 100644 --- a/packages/react-resizable-panels/src/PanelGroup.tsx +++ b/packages/react-resizable-panels/src/PanelGroup.tsx @@ -91,7 +91,7 @@ export default function PanelGroup({ if (defaultSizes != null) { setSizes(defaultSizes); } else { - const panelsArray: PanelData[] = Array.from(panels.values()); + const panelsArray = panelsMapToSortedArray(panels); const totalWeight = panelsArray.reduce((weight, panel) => { return weight + panel.defaultSize; }, 0); @@ -237,7 +237,7 @@ function adjustByDelta( return prevSizes; } - const panelsArray: PanelData[] = Array.from(panels.values()); + const panelsArray = panelsMapToSortedArray(panels); const nextSizes = prevSizes.concat(); @@ -295,7 +295,8 @@ function createLocalStorageKey( autoSaveId: string, panels: Map ): string { - const panelIds = Array.from(panels.keys()).sort(); + const panelsArray = panelsMapToSortedArray(panels); + const panelIds = panelsArray.map((panel) => panel.id); return `PanelGroup:sizes:${autoSaveId}${panelIds.join("|")}`; } @@ -308,7 +309,7 @@ function getOffset( height: number, width: number ): number { - const panelsArray: PanelData[] = Array.from(panels.values()); + const panelsArray = panelsMapToSortedArray(panels); let index = panelsArray.findIndex((panel) => panel.id === id); if (index < 0) { @@ -339,7 +340,7 @@ function getSize( return totalSize; } - const panelsArray: PanelData[] = Array.from(panels.values()); + const panelsArray = panelsMapToSortedArray(panels); const index = panelsArray.findIndex((panel) => panel.id === id); const size = sizes[index]; @@ -349,3 +350,7 @@ function getSize( return Math.round(size * totalSize); } + +function panelsMapToSortedArray(panels: Map): PanelData[] { + return Array.from(panels.values()).sort((a, b) => a.order - b.order); +} diff --git a/packages/react-resizable-panels/src/types.ts b/packages/react-resizable-panels/src/types.ts index ff5744d8b..0f5d2e689 100644 --- a/packages/react-resizable-panels/src/types.ts +++ b/packages/react-resizable-panels/src/types.ts @@ -4,6 +4,7 @@ export type PanelData = { defaultSize: number; id: string; minSize: number; + order: number | null; }; export type ResizeHandler = (event: MouseEvent) => void;