diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..ac1fbb593
--- /dev/null
+++ b/CHANGELOG.md
@@ -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.
diff --git a/README.md b/README.md
index 04775e8dd..455e16207 100644
--- a/README.md
+++ b/README.md
@@ -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
\ No newline at end of file
+| `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
\ No newline at end of file
diff --git a/declaration.d.ts b/declaration.d.ts
new file mode 100644
index 000000000..d0043f383
--- /dev/null
+++ b/declaration.d.ts
@@ -0,0 +1,4 @@
+declare module "*.module.css" {
+ const content: Record;
+ export default content;
+}
diff --git a/package.json b/package.json
index 448c10d09..e437bfdb2 100644
--- a/package.json
+++ b/package.json
@@ -14,5 +14,10 @@
"prettier": "latest",
"process": "^0.11.10",
"typescript": ">=3.0.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.26",
+ "@types/react-dom": "^18.0.10",
+ "@types/react-virtualized-auto-sizer": "^1.0.1"
}
}
diff --git a/packages/react-resizable-panels-website/index.js b/packages/react-resizable-panels-website/index.js
new file mode 100644
index 000000000..c030b3dd7
--- /dev/null
+++ b/packages/react-resizable-panels-website/index.js
@@ -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, {}) }));
diff --git a/packages/react-resizable-panels-website/src/App.js b/packages/react-resizable-panels-website/src/App.js
new file mode 100644
index 000000000..9ecf835a0
--- /dev/null
+++ b/packages/react-resizable-panels-website/src/App.js
@@ -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) })));
+}
diff --git a/packages/react-resizable-panels-website/src/AutoSizedPanelGroup.js b/packages/react-resizable-panels-website/src/AutoSizedPanelGroup.js
new file mode 100644
index 000000000..cc4a7e257
--- /dev/null
+++ b/packages/react-resizable-panels-website/src/AutoSizedPanelGroup.js
@@ -0,0 +1,4 @@
+import { PanelGroup } from "react-resizable-panels";
+import withAutoSizer from "./withAutoSizer";
+var AutoSizedPanelGroup = withAutoSizer(PanelGroup);
+export default AutoSizedPanelGroup;
diff --git a/packages/react-resizable-panels-website/src/HorizontalGroup.js b/packages/react-resizable-panels-website/src/HorizontalGroup.js
new file mode 100644
index 000000000..17b0cf0fc
--- /dev/null
+++ b/packages/react-resizable-panels-website/src/HorizontalGroup.js
@@ -0,0 +1,21 @@
+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, jsxs as _jsxs } from "react/jsx-runtime";
+import { Panel, PanelResizeHandle } from "react-resizable-panels";
+import PanelGroup from "./AutoSizedPanelGroup";
+import styles from "./styles.module.css";
+import { GROUP_ID as GROUP_ID_VERTICAL, VerticalGroup } from "./VerticalGroup";
+export var GROUP_ID = "horizontal";
+export default function HorizontalGroup(_a) {
+ var clearSavedSizes = _a.clearSavedSizes;
+ return (_jsxs(PanelGroup, __assign({ autoSaveId: GROUP_ID, direction: "horizontal" }, { children: [_jsx(Panel, __assign({ className: styles.PanelRow, defaultSize: 0.2, id: "left" }, { children: _jsxs("div", __assign({ className: styles.HorizontalFiller, style: { backgroundColor: "var(--color-horizontal)" } }, { children: [_jsxs("p", __assign({ className: styles.ParagraphOfText }, { children: ["This is a \"", _jsx("em", { children: "horizontal" }), "\" ", _jsx("code", { children: "PanelGroup" })] })), _jsxs("p", __assign({ className: styles.ParagraphOfText }, { children: ["It has an empty/implied resize bar, like", " ", _jsx("a", __assign({ href: "https://replay.io", target: "_blank", rel: "noreferrer noopener" }, { children: "Replay.io" })), "."] }))] })) })), _jsxs(Panel, __assign({ className: styles.PanelRow, defaultSize: 0.4, id: "middle", minSize: 0.25 }, { children: [_jsx(PanelResizeHandle, { className: styles.HorizontalResizeHandle, panelBefore: "left", panelAfter: "middle" }), _jsxs("div", __assign({ className: styles.HorizontalFiller, style: { backgroundColor: "var(--color-horizontal)" } }, { children: [_jsx("h2", { children: "Auto Save" }), _jsxs("p", __assign({ className: styles.ParagraphOfText }, { children: ["This demo uses the ", _jsx("code", { children: "autoSaveId" }), " prop to remember sizes."] })), _jsx("p", __assign({ className: styles.ParagraphOfText }, { children: "Reset saved sizes by clicking the buttons below." })), _jsxs("p", __assign({ className: styles.ParagraphOfText }, { children: [_jsxs("button", __assign({ className: styles.Button, onClick: function () { return clearSavedSizes(GROUP_ID); } }, { children: ["reset horizontal sizes", _jsx("div", { className: styles.HorizontalDot })] })), _jsx("br", {}), _jsxs("button", __assign({ className: styles.Button, onClick: function () { return clearSavedSizes(GROUP_ID_VERTICAL); } }, { children: ["reset vertical sizes", _jsx("div", { className: styles.VerticalDot })] })), _jsx("hr", {}), _jsxs("button", __assign({ className: styles.Button, onClick: function () { return clearSavedSizes(GROUP_ID, GROUP_ID_VERTICAL); } }, { children: ["reset both", _jsx("div", { className: styles.HorizontalDot }), _jsx("div", { className: styles.VerticalDot })] }))] })), _jsx("p", __assign({ className: styles.ParagraphOfText }, { children: "It won't shrink beyond 25% of the total width." }))] })), _jsx(PanelResizeHandle, { className: styles.HorizontalResizeHandle, panelBefore: "middle", panelAfter: "stacked" })] })), _jsx(Panel, __assign({ className: styles.PanelRow, defaultSize: 0.3, id: "stacked" }, { children: _jsx("div", __assign({ className: styles.Grower }, { children: _jsx(VerticalGroup, {}) })) })), _jsxs(Panel, __assign({ className: styles.PanelRow, defaultSize: 0.2, id: "right" }, { children: [_jsx(PanelResizeHandle, { className: styles.HorizontalResizeHandle, panelBefore: "stacked", panelAfter: "right" }), _jsx("div", __assign({ className: styles.HorizontalFiller, style: { backgroundColor: "var(--color-horizontal)" } }, { children: _jsxs("p", __assign({ className: styles.ParagraphOfText }, { children: ["Read more on", " ", _jsx("a", __assign({ href: "https://github.com/bvaughn/react-resizable-panels", target: "_blank", rel: "noreferrer noopener" }, { children: "GitHub" })), "."] })) }))] }))] })));
+}
diff --git a/packages/react-resizable-panels-website/src/HorizontalGroup.tsx b/packages/react-resizable-panels-website/src/HorizontalGroup.tsx
index e18b24959..5e37c5f45 100644
--- a/packages/react-resizable-panels-website/src/HorizontalGroup.tsx
+++ b/packages/react-resizable-panels-website/src/HorizontalGroup.tsx
@@ -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";
@@ -62,7 +58,7 @@ export default function HorizontalGroup({