Skip to content

Commit

Permalink
Panel visibility can be toggled on/off
Browse files Browse the repository at this point in the history
PanelGroup will persist separate layouts for each combination of visible panels.
  • Loading branch information
bvaughn committed Dec 23, 2022
1 parent efec480 commit e5ed8d4
Show file tree
Hide file tree
Showing 22 changed files with 619 additions and 100 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Changelog

## 0.0.3
* [#3](https://github.com/bvaughn/react-resizable-panels/issues/3): `Panel` visibility can be toggled on/off. `PanelGroup` will persist separate layouts for each combination of visible panels.

## 0.0.2
* Documentation-only update.

## 0.0.1
* Initial release.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
| `children` | `?ReactNode` | Custom drag UI; can be any arbitrary React element(s)
| `className` | `?string` | Class name
| `disabled` | `?boolean` | Disable drag handle
| `panelAfter` | `PanelId` | Id of panel after (below or to the right of) the drag handle
| `panelBefore` | `PanelId` | Id of panel before (above or to the left of) the drag handle
| `panelAfter` | `string` | Id of panel after (below or to the right of) the drag handle
| `panelBefore` | `string` | Id of panel before (above or to the left of) the drag handle
7 changes: 7 additions & 0 deletions packages/react-resizable-panels-website/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./src/App";
var rootElement = document.getElementById("root");
var root = createRoot(rootElement);
root.render(_jsx(StrictMode, { children: _jsx(App, {}) }));
29 changes: 29 additions & 0 deletions packages/react-resizable-panels-website/src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import { jsx as _jsx } from "react/jsx-runtime";
import { useCallback, useState } from "react";
import HorizontalGroup from "./HorizontalGroup";
import styles from "./styles.module.css";
export default function DemoApp() {
var _a = useState(0), key = _a[0], setKey = _a[1];
var clearSavedSizes = useCallback(function () {
var groupIds = [];
for (var _i = 0; _i < arguments.length; _i++) {
groupIds[_i] = arguments[_i];
}
groupIds.forEach(function (groupId) {
localStorage.removeItem("PanelGroup:sizes:".concat(groupId));
});
setKey(function (prevKey) { return prevKey + 1; });
}, []);
return (_jsx("div", __assign({ className: styles.FullHeightAndWidth }, { children: _jsx(HorizontalGroup, { clearSavedSizes: clearSavedSizes }, key) })));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { PanelGroup } from "react-resizable-panels";
import withAutoSizer from "./withAutoSizer";
var AutoSizedPanelGroup = withAutoSizer(PanelGroup);
export default AutoSizedPanelGroup;
21 changes: 21 additions & 0 deletions packages/react-resizable-panels-website/src/HorizontalGroup.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 4 additions & 8 deletions packages/react-resizable-panels-website/src/HorizontalGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
Panel,
PanelGroup as PanelGroupWithSizes,
PanelResizeHandle,
} from "react-resizable-panels";
import { Panel, PanelResizeHandle } from "react-resizable-panels";

import PanelGroup from "./AutoSizedPanelGroup";
import styles from "./styles.module.css";
Expand Down Expand Up @@ -62,23 +58,23 @@ export default function HorizontalGroup({
</p>
<p className={styles.ParagraphOfText}>
<button
className={styles.ResetButton}
className={styles.Button}
onClick={() => clearSavedSizes(GROUP_ID)}
>
reset horizontal sizes
<div className={styles.HorizontalDot} />
</button>
<br />
<button
className={styles.ResetButton}
className={styles.Button}
onClick={() => clearSavedSizes(GROUP_ID_VERTICAL)}
>
reset vertical sizes
<div className={styles.VerticalDot} />
</button>
<hr />
<button
className={styles.ResetButton}
className={styles.Button}
onClick={() => clearSavedSizes(GROUP_ID, GROUP_ID_VERTICAL)}
>
reset both
Expand Down
23 changes: 23 additions & 0 deletions packages/react-resizable-panels-website/src/VerticalGroup.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 41 additions & 21 deletions packages/react-resizable-panels-website/src/VerticalGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { Panel, PanelResizeHandle } from "react-resizable-panels";
import { useState } from "react";

import PanelGroup from "./AutoSizedPanelGroup";
import styles from "./styles.module.css";

export const GROUP_ID = "vertical";

export function VerticalGroup() {
const [isPanelHidden, setIsPanelHidden] = useState(false);

const hidePanel = () => setIsPanelHidden(true);
const showPanel = () => setIsPanelHidden(false);

return (
<PanelGroup autoSaveId={GROUP_ID} direction="vertical">
<Panel
className={styles.PanelRow}
defaultSize={0.65}
defaultSize={0.35}
id="top"
minSize={0.35}
minSize={0.25}
>
<div
className={styles.VerticalFillerTop}
Expand All @@ -24,30 +30,44 @@ export function VerticalGroup() {
<p className={styles.ParagraphOfText}>
It has a solid resize bar, similar to Chrome devtools or VS Code.
</p>
<p className={styles.ParagraphOfText}>
It won't shrink beyond 35% of the total height.
</p>
</div>
</Panel>
<Panel
className={styles.PanelColumn}
defaultSize={0.35}
id="bottom"
minSize={0.25}
>
<PanelResizeHandle panelBefore="top" panelAfter="bottom">
<div className={styles.VerticalResizeBar} />
</PanelResizeHandle>
<div
className={styles.VerticalFillerBottom}
style={{ backgroundColor: "var(--color-vertical)" }}
>
<p className={styles.ParagraphOfText}>
It uses the <code>minSize</code> prop to prevent it from shrinking
past 25% of the total height.
to less than 35% of the total height.
</p>
{isPanelHidden && (
<p className={styles.ParagraphOfText}>
<button className={styles.Button} onClick={showPanel}>
Show the bottom panel
</button>
</p>
)}
</div>
</Panel>
{isPanelHidden || (
<Panel
className={styles.PanelColumn}
defaultSize={0.65}
id="bottom"
minSize={0.35}
>
<PanelResizeHandle panelBefore="top" panelAfter="bottom">
<div className={styles.VerticalResizeBar} />
</PanelResizeHandle>
<div
className={styles.VerticalFillerBottom}
style={{ backgroundColor: "var(--color-vertical)" }}
>
<p className={styles.ParagraphOfText}>
This panel's visibility can be toggled on or off.
</p>
<p className={styles.ParagraphOfText}>
<button className={styles.Button} onClick={hidePanel}>
Hide this panel
</button>
</p>
</div>
</Panel>
)}
</PanelGroup>
);
}
4 changes: 2 additions & 2 deletions packages/react-resizable-panels-website/src/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@
border-top: 1px solid #4a4c50;
}

.ResetButton {
.Button {
color: #ffffff;
background: #2a3343;
border: 1px solid #18181a;
border-radius: 0.25rem;
padding: 0.25rem 0.5rem;
cursor: pointer;
}
.ResetButton:hover {
.Button:hover {
background: #454950;
}

Expand Down
22 changes: 22 additions & 0 deletions packages/react-resizable-panels-website/src/withAutoSizer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import { createElement } from "react";
import AutoSizer from "react-virtualized-auto-sizer";
export default function withAutoSizer(Component, autoSizerProps) {
var AutoSizerWrapper = function (props) {
return createElement(AutoSizer, __assign(__assign({}, autoSizerProps), { children: function (_a) {
var height = _a.height, width = _a.width;
return createElement(Component, __assign(__assign({}, props), { height: height, width: width }));
} }));
};
return AutoSizerWrapper;
}
42 changes: 42 additions & 0 deletions packages/react-resizable-panels/src/Panel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
import { jsx as _jsx } from "react/jsx-runtime";
import { useContext, useLayoutEffect } from "react";
import { PanelGroupContext } from "./PanelContexts";
// TODO [panels]
// Support min pixel size too.
// PanelGroup should warn if total width is less min pixel widths.
export default function Panel(_a) {
var _b = _a.children, children = _b === void 0 ? null : _b, _c = _a.className, className = _c === void 0 ? "" : _c, _d = _a.defaultSize, defaultSize = _d === void 0 ? 0.1 : _d, id = _a.id, _e = _a.minSize, minSize = _e === void 0 ? 0.1 : _e;
var context = useContext(PanelGroupContext);
if (context === null) {
throw Error("Panel components must be rendered within a PanelGroup container");
}
if (minSize > defaultSize) {
console.error("Panel minSize ".concat(minSize, " cannot be greater than defaultSize ").concat(defaultSize));
defaultSize = minSize;
}
var getPanelStyle = context.getPanelStyle, registerPanel = context.registerPanel, unregisterPanel = context.unregisterPanel;
useLayoutEffect(function () {
var panel = {
defaultSize: defaultSize,
id: id,
minSize: minSize
};
registerPanel(id, panel);
return function () {
unregisterPanel(id);
};
}, [defaultSize, id, minSize, registerPanel, unregisterPanel]);
var style = getPanelStyle(id);
return (_jsx("div", __assign({ className: className, style: style }, { children: children })));
}
15 changes: 9 additions & 6 deletions packages/react-resizable-panels/src/Panel.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import { ReactNode, useContext, useLayoutEffect } from "react";

import { PanelGroupContext } from "./PanelContexts";
import { PanelId } from "./types";

// TODO [panels]
// Support min pixel size too.
// PanelGroup should warn if total width is less min pixel widths.
export default function Panel({
children,
children = null,
className = "",
defaultSize = 0.1,
id,
minSize = 0.1,
}: {
children: ReactNode;
children?: ReactNode;
className?: string;
defaultSize?: number;
id: PanelId;
id: string;
minSize?: number;
}) {
const context = useContext(PanelGroupContext);
Expand All @@ -34,7 +33,7 @@ export default function Panel({
defaultSize = minSize;
}

const { getPanelStyle, registerPanel } = context;
const { getPanelStyle, registerPanel, unregisterPanel } = context;

useLayoutEffect(() => {
const panel = {
Expand All @@ -44,7 +43,11 @@ export default function Panel({
};

registerPanel(id, panel);
}, [defaultSize, minSize, registerPanel, id]);

return () => {
unregisterPanel(id);
};
}, [defaultSize, id, minSize, registerPanel, unregisterPanel]);

const style = getPanelStyle(id);

Expand Down
2 changes: 2 additions & 0 deletions packages/react-resizable-panels/src/PanelContexts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { createContext } from "react";
export var PanelGroupContext = createContext(null);
9 changes: 5 additions & 4 deletions packages/react-resizable-panels/src/PanelContexts.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { CSSProperties, createContext } from "react";

import { PanelData, PanelId, ResizeHandler } from "./types";
import { PanelData, ResizeHandler } from "./types";

export const PanelGroupContext = createContext<{
direction: "horizontal" | "vertical";
getPanelStyle: (id: PanelId) => CSSProperties;
registerResizeHandle: (idBefore: PanelId, idAfter: PanelId) => ResizeHandler;
registerPanel: (id: PanelId, panel: PanelData) => void;
getPanelStyle: (id: string) => CSSProperties;
registerPanel: (id: string, panel: PanelData) => void;
registerResizeHandle: (idBefore: string, idAfter: string) => ResizeHandler;
unregisterPanel: (id: string) => void;
} | null>(null);
Loading

0 comments on commit e5ed8d4

Please sign in to comment.