Skip to content

Commit

Permalink
Version 1.0 release (#230)
Browse files Browse the repository at this point in the history
Checklist:
- [x] Remove pixel size constraints
- [x] Replaced `dataAttributes` prop with ...rest (to support all
HTMLAttributes)
- [x] Review and pull in changes from open PRs:
  - [x] #228
  - [x] #224
- [x] Audit open issues and close ones that are no longer releveant
- [x] Remove any unnecessary async initialization logic necessitated by
pixel constraints

I think this library's feature set is stable enough in my mind for a 1.0
release. It might be controversial but I have decided to cut pixel-based
constraints from that release as they added too much complexity to the
initialization and validation logic.

---------

Co-authored-by: Timur Sufiev <[email protected]>
  • Loading branch information
bvaughn and Timur Sufiev authored Dec 13, 2023
1 parent 1133472 commit bce573c
Show file tree
Hide file tree
Showing 82 changed files with 1,511 additions and 3,501 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ Supported input methods include mouse, touch, and keyboard (via [Window Splitter

## FAQ

### Can panel sizes be specified in pixels?

No. Pixel-based constraints [added significant complexity](https://github.com/bvaughn/react-resizable-panels/pull/176) to the initialization and validation logic and so I've decided not to support them. You may be able to implement a version of this yourself following [a pattern like this](https://github.com/bvaughn/react-resizable-panels/issues/46#issuecomment-1368108416) but it is not officially supported by this library.

### How can I fix layout/sizing problems with conditionally rendered panels?

The `Panel` API doesn't _require_ `id` and `order` props because they aren't necessary for static layouts. When panels are conditionally rendered though, it's best to supply these values.
Expand All @@ -27,13 +31,13 @@ The `Panel` API doesn't _require_ `id` and `order` props because they aren't nec
<PanelGroup direction="horizontal">
{renderSideBar && (
<>
<Panel id="sidebar" minSizePercentage={25} order={1}>
<Panel id="sidebar" minSize={25} order={1}>
<Sidebar />
</Panel>
<PanelResizeHandle />
</>
)}
<Panel minSizePercentage={25} order={2}>
<Panel minSize={25} order={2}>
<Main />
</Panel>
</PanelGroup>
Expand Down Expand Up @@ -79,9 +83,9 @@ export function ClientComponent({

return (
<PanelGroup direction="horizontal" onLayout={onLayout}>
<Panel defaultSizePercentage={defaultLayout[0]}>{/* ... */}</Panel>
<Panel defaultSize={defaultLayout[0]}>{/* ... */}</Panel>
<PanelResizeHandle className="w-2 bg-blue-800" />
<Panel defaultSizePercentage={defaultLayout[1]}>{/* ... */}</Panel>
<Panel defaultSize={defaultLayout[1]}>{/* ... */}</Panel>
</PanelGroup>
);
}
Expand Down
5 changes: 0 additions & 5 deletions packages/react-resizable-panels-website/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { createBrowserRouter, RouterProvider } from "react-router-dom";

import HomeRoute from "./src/routes/Home";
import ConditionalExampleRoute from "./src/routes/examples/Conditional";
import PixelBasedLayoutsRoute from "./src/routes/examples/PixelBasedLayouts";
import ExternalPersistenceExampleRoute from "./src/routes/examples/ExternalPersistence";
import HorizontalExampleRoute from "./src/routes/examples/Horizontal";
import ImperativePanelApiExampleRoute from "./src/routes/examples/ImperativePanelApi";
Expand All @@ -25,10 +24,6 @@ const router = createBrowserRouter([
path: "/examples/conditional",
element: <ConditionalExampleRoute />,
},
{
path: "/examples/pixel-based-layouts",
element: <PixelBasedLayoutsRoute />,
},
{
path: "/examples/external-persistence",
element: <ExternalPersistenceExampleRoute />,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { assert } from "react-resizable-panels";

export const Targets = {
bottomLeft: "bottomLeft",
bottomRight: "bottomRight",
Expand Down Expand Up @@ -107,6 +109,8 @@ const stages = frames.filter((step): step is Stage => step.type === "stage");

for (let index = 0; index < frames.length; index++) {
const frame = frames[index];
assert(frame);

switch (frame.type) {
case "pause":
sequence.push(frame);
Expand All @@ -116,6 +120,7 @@ for (let index = 0; index < frames.length; index++) {

const index = stages.indexOf(fromStage);
const toStage = index + 1 < stages.length ? stages[index + 1] : stages[0];
assert(toStage != null);

const changedProperties: AnimatedProperty[] = [];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { RefObject, useEffect } from "react";
import { assert } from "react-resizable-panels";
import { Sequence, Target } from "./LogoAnimation";

export function useLogoAnimation(
Expand Down Expand Up @@ -31,6 +32,8 @@ export function useLogoAnimation(
let accumulatedDuration = 0;
for (let index = 0; index < sequence.length; index++) {
segment = sequence[index];
assert(segment);

if (
elapsed >= accumulatedDuration &&
elapsed <= accumulatedDuration + segment.duration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,22 @@ import {
Component,
ErrorInfo,
PropsWithChildren,
useLayoutEffect,
useRef,
useState,
} from "react";
import {
ImperativePanelGroupHandle,
ImperativePanelHandle,
MixedSizes,
assert,
} from "react-resizable-panels";

import { urlPanelGroupToPanelGroup, urlToUrlData } from "../../utils/UrlData";

import DebugLog, { ImperativeDebugLogHandle } from "../examples/DebugLog";

import { useLayoutEffect } from "react";
import {
assertImperativePanelGroupHandle,
assertImperativePanelHandle,
} from "../../../tests/utils/assert";
import Icon from "../../components/Icon";
import { urlPanelGroupToPanelGroup, urlToUrlData } from "../../utils/UrlData";
import DebugLog, { ImperativeDebugLogHandle } from "../examples/DebugLog";
import "./styles.css";
import styles from "./styles.module.css";

Expand Down Expand Up @@ -54,10 +51,7 @@ function EndToEndTesting() {
const [panelIds, setPanelIds] = useState<string[]>([]);
const [panelGroupId, setPanelGroupId] = useState("");
const [panelGroupIds, setPanelGroupIds] = useState<string[]>([]);
const [sizePercentage, setSizePercentage] = useState<number | undefined>(
undefined
);
const [sizePixels, setSizePixels] = useState<number | undefined>(undefined);
const [size, setSize] = useState<number>(0);
const [layoutString, setLayoutString] = useState("");

const debugLogRef = useRef<ImperativeDebugLogHandle>(null);
Expand All @@ -71,16 +65,24 @@ function EndToEndTesting() {
const panelIds = Array.from(panelElements).map(
(element) => element.getAttribute("data-panel-id")!
);

const firstPanelId = panelIds[0];
assert(firstPanelId != null);

setPanelIds(panelIds);
setPanelId(panelIds[0]);
setPanelId(firstPanelId);

const panelGroupElements =
document.querySelectorAll("[data-panel-group]");
const panelGroupIds = Array.from(panelGroupElements).map(
(element) => element.getAttribute("data-panel-group-id")!
);

const firstPanelGroupId = panelGroupIds[0];
assert(firstPanelGroupId != null);

setPanelGroupIds(panelGroupIds);
setPanelGroupId(panelGroupIds[0]);
setPanelGroupId(firstPanelGroupId);
};

window.addEventListener("popstate", (event) => {
Expand Down Expand Up @@ -110,11 +112,9 @@ function EndToEndTesting() {
panelId
) as ImperativePanelHandle;
if (panel != null) {
const { sizePercentage, sizePixels } = panel.getSize();
const size = panel.getSize();

panelElement.textContent = `${sizePercentage.toFixed(
1
)}%\n${sizePixels.toFixed(1)}px`;
panelElement.textContent = `${size.toFixed(1)}%`;
}
}
}, 0);
Expand Down Expand Up @@ -171,15 +171,7 @@ function EndToEndTesting() {
const onSizeInputChange = (event: ChangeEvent<HTMLInputElement>) => {
const value = event.currentTarget.value;

if (value.endsWith("%")) {
setSizePercentage(parseFloat(value));
setSizePixels(undefined);
} else if (value.endsWith("px")) {
setSizePercentage(undefined);
setSizePixels(parseFloat(value));
} else {
throw Error(`Invalid size: ${value}`);
}
setSize(parseFloat(value));
};

const onCollapseButtonClick = () => {
Expand All @@ -202,7 +194,7 @@ function EndToEndTesting() {
const idToRefMap = idToRefMapRef.current;
const panel = idToRefMap.get(panelId);
if (panel && assertImperativePanelHandle(panel)) {
panel.resize({ sizePercentage, sizePixels });
panel.resize(size);
}
};

Expand All @@ -214,15 +206,9 @@ function EndToEndTesting() {
1,
layoutString.length - 1
);
const layout = trimmedLayoutString.split(",").map((text) => {
if (text.endsWith("%")) {
return { sizePercentage: parseFloat(text) };
} else if (text.endsWith("px")) {
return { sizePixels: parseFloat(text) };
} else {
throw Error(`Invalid layout: ${layoutString}`);
}
}) satisfies Partial<MixedSizes>[];
const layout = trimmedLayoutString
.split(",")
.map((text) => parseFloat(text));
panelGroup.setLayout(layout);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const LINKS = [
{ path: "overflow", title: "Overflow content" },
{ path: "collapsible", title: "Collapsible panels" },
{ path: "conditional", title: "Conditional panels" },
{ path: "pixel-based-layouts", title: "Pixel based layouts" },
{ path: "external-persistence", title: "External persistence" },
{ path: "imperative-panel-api", title: "Imperative Panel API" },
{ path: "imperative-panel-group-api", title: "Imperative PanelGroup API" },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { useReducer } from "react";

import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";

import {
Panel,
PanelGroup,
PanelResizeHandle,
assert,
} from "react-resizable-panels";
import {
TUTORIAL_CODE_CSS,
TUTORIAL_CODE_HTML,
Expand All @@ -11,7 +14,6 @@ import {
import Code from "../../components/Code";
import Icon from "../../components/Icon";
import { Language } from "../../suspense/SyntaxParsingCache";

import styles from "./Collapsible.module.css";
import Example from "./Example";
import sharedStyles from "./shared.module.css";
Expand Down Expand Up @@ -74,11 +76,11 @@ function Content() {
</div>
<Panel
className={sharedStyles.PanelColumn}
collapsedSizePixels={36}
collapsedSize={5}
collapsible={true}
defaultSizePixels={150}
maxSizePixels={150}
minSizePixels={60}
defaultSize={15}
maxSize={20}
minSize={15}
onCollapse={onCollapse}
onExpand={onExpand}
>
Expand Down Expand Up @@ -109,7 +111,7 @@ function Content() {
: styles.ResizeHandle
}
/>
<Panel className={sharedStyles.PanelColumn} minSizePercentage={50}>
<Panel className={sharedStyles.PanelColumn} minSize={50}>
<div className={styles.SourceTabs}>
{Array.from(openFiles).map((file) => (
<div
Expand Down Expand Up @@ -175,7 +177,7 @@ const FILES: File[] = FILE_PATHS.map(([path, code]) => {
const CODE = `
<PanelGroup direction="horizontal">
<SideTabBar />
<Panel collapsible={true} collapsedSizePixels={35} minSizePercentage={10}>
<Panel collapsible={true} collapsedSizePixels={35} minSize={10}>
<SourceBrowser />
</Panel>
<PanelResizeHandle />
Expand All @@ -197,10 +199,13 @@ type FilesState = {
openFiles: File[];
};

const FIRST_FILE = FILES[0];
assert(FIRST_FILE);

const initialState: FilesState = {
currentFileIndex: 0,
fileListCollapsed: false,
openFiles: [FILES[0]],
openFiles: [FIRST_FILE],
};

function reducer(state: FilesState, action: FilesAction): FilesState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,34 +66,19 @@ function Content({
>
{showLeftPanel && (
<>
<Panel
className={styles.Panel}
id="left"
minSizePercentage={10}
order={1}
>
<Panel className={styles.Panel} id="left" minSize={10} order={1}>
<div className={styles.Centered}>left</div>
</Panel>
<ResizeHandle className={styles.ResizeHandle} />
</>
)}
<Panel
className={styles.Panel}
id="center"
minSizePercentage={10}
order={2}
>
<Panel className={styles.Panel} id="center" minSize={10} order={2}>
<div className={styles.Centered}>middle</div>
</Panel>
{showRightPanel && (
<>
<ResizeHandle className={styles.ResizeHandle} />
<Panel
className={styles.Panel}
id="right"
minSizePercentage={10}
order={3}
>
<Panel className={styles.Panel} id="right" minSize={10} order={3}>
<div className={styles.Centered}>right</div>
</Panel>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,23 +81,15 @@ function Content() {
direction="horizontal"
storage={urlStorage}
>
<Panel
className={styles.PanelRow}
collapsible={true}
minSizePercentage={10}
>
<Panel className={styles.PanelRow} collapsible={true} minSize={10}>
<div className={styles.Centered}>left</div>
</Panel>
<ResizeHandle className={styles.ResizeHandle} />
<Panel className={styles.PanelRow} minSizePercentage={10}>
<Panel className={styles.PanelRow} minSize={10}>
<div className={styles.Centered}>middle</div>
</Panel>
<ResizeHandle className={styles.ResizeHandle} />
<Panel
className={styles.PanelRow}
collapsible={true}
minSizePercentage={10}
>
<Panel className={styles.PanelRow} collapsible={true} minSize={10}>
<div className={styles.Centered}>right</div>
</Panel>
</PanelGroup>
Expand Down
Loading

1 comment on commit bce573c

@vercel
Copy link

@vercel vercel bot commented on bce573c Dec 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.