Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 4.3.2

- Moved `flex-grow` `Panel` style to an inline value instead of a CSS variable defined on the parent `Group` to improve rendering performance. (This significantly reduces the negative impact from forced-reflow)

## 4.3.1

- [588](https://github.com/bvaughn/react-resizable-panels/pull/588): Replace `"unset"` styles with safer override values
Expand Down
61 changes: 60 additions & 1 deletion lib/components/group/Group.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { render } from "@testing-library/react";
import { createRef, useEffect } from "react";
import {
createRef,
useEffect,
useLayoutEffect,
useRef,
type PropsWithChildren
} from "react";
import { beforeEach, describe, expect, test, vi } from "vitest";
import { eventEmitter } from "../../global/mutableState";
import { moveSeparator } from "../../global/test/moveSeparator";
Expand All @@ -9,6 +15,7 @@ import {
setElementBoundsFunction
} from "../../utils/test/mockBoundingClientRect";
import { Panel } from "../panel/Panel";
import type { PanelImperativeHandle } from "../panel/types";
import { Separator } from "../separator/Separator";
import { Group } from "./Group";
import type { GroupImperativeHandle } from "./types";
Expand Down Expand Up @@ -137,6 +144,58 @@ describe("Group", () => {
baz: 50
});
});

test("should note require multiple render passes", () => {
setElementBoundsFunction((element) => {
if (element.hasAttribute("data-panel")) {
return new DOMRect(0, 0, 50, 50);
} else {
return new DOMRect(0, 0, 100, 50);
}
});

const onLayoutChange = vi.fn();

function DomChecker({ children }: PropsWithChildren) {
const ref = useRef<HTMLDivElement>(null);

// Easiest way to confirm the Group didn't render temporarily invalid values during mount
useLayoutEffect(() => {
const element = ref.current;
assert(element);

const fooPanel = element.querySelector('[data-testid="foo"]');
expect((fooPanel as HTMLDivElement).style.flexGrow).toEqual("40");

const barPanel = element.querySelector('[data-testid="bar"]');
expect((barPanel as HTMLDivElement).style.flexGrow).toEqual("60");
});

return <div ref={ref}>{children}</div>;
}

const groupRef = createRef<GroupImperativeHandle>();
const panelRef = createRef<PanelImperativeHandle>();

render(
<DomChecker>
<Group
defaultLayout={{
foo: 40,
bar: 60
}}
groupRef={groupRef}
onLayoutChange={onLayoutChange}
>
<Panel defaultSize="50%" id="foo" panelRef={panelRef} />
<Panel id="bar" />
</Group>
</DomChecker>
);

expect(onLayoutChange).toHaveBeenCalledTimes(1);
expect(onLayoutChange).toHaveBeenCalledWith({ foo: 40, bar: 60 });
});
});

describe("groupRef", () => {
Expand Down
4 changes: 2 additions & 2 deletions lib/components/group/Group.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ export function Group({
}
}

// This is unexpected
// This is unexpected except for the initial mount (before the group has registered with the global store)
return {
flexGrow: 1
flexGrow: defaultLayout?.[panelId] ?? 1
} satisfies CSSProperties;
}
);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-resizable-panels",
"version": "4.3.1",
"version": "4.3.2",
"type": "module",
"author": "Brian Vaughn <brian.david.vaughn@gmail.com> (https://github.com/bvaughn/)",
"contributors": [
Expand Down
Loading