react-resizable-panels 2.0.8-rc.1 → 2.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Panel.ts CHANGED
@@ -236,6 +236,7 @@ export function PanelWithForwardedRef({
236
236
 
237
237
  children,
238
238
  className: classNameFromProps,
239
+ id: idFromProps,
239
240
  style: {
240
241
  ...style,
241
242
  ...styleFromProps,
@@ -276,6 +276,42 @@ describe("PanelGroup", () => {
276
276
  });
277
277
  });
278
278
 
279
+ describe("a11y", () => {
280
+ it("should pass explicit id prop to DOM", () => {
281
+ act(() => {
282
+ root.render(
283
+ <PanelGroup direction="horizontal" id="explicit-id">
284
+ <Panel />
285
+ <PanelResizeHandle />
286
+ <Panel />
287
+ </PanelGroup>
288
+ );
289
+ });
290
+
291
+ const element = container.querySelector("[data-panel-group]");
292
+
293
+ expect(element).not.toBeNull();
294
+ expect(element?.getAttribute("id")).toBe("explicit-id");
295
+ });
296
+
297
+ it("should not pass auto-generated id prop to DOM", () => {
298
+ act(() => {
299
+ root.render(
300
+ <PanelGroup direction="horizontal">
301
+ <Panel />
302
+ <PanelResizeHandle />
303
+ <Panel />
304
+ </PanelGroup>
305
+ );
306
+ });
307
+
308
+ const element = container.querySelector("[data-panel-group]");
309
+
310
+ expect(element).not.toBeNull();
311
+ expect(element?.getAttribute("id")).toBeNull();
312
+ });
313
+ });
314
+
279
315
  describe("DEV warnings", () => {
280
316
  it("should warn about unstable layouts without id and order props", () => {
281
317
  act(() => {
package/src/PanelGroup.ts CHANGED
@@ -880,13 +880,16 @@ function PanelGroupWithForwardedRef({
880
880
  { value: context },
881
881
  createElement(Type, {
882
882
  ...rest,
883
+
883
884
  children,
884
885
  className: classNameFromProps,
886
+ id: idFromProps,
887
+ ref: panelGroupElementRef,
885
888
  style: {
886
889
  ...style,
887
890
  ...styleFromProps,
888
891
  },
889
- ref: panelGroupElementRef,
892
+
890
893
  // CSS selectors
891
894
  "data-panel-group": "",
892
895
  "data-panel-group-direction": direction,
@@ -269,4 +269,40 @@ describe("PanelResizeHandle", () => {
269
269
  verifyAttribute(rightElement, "data-resize-handle-active", null);
270
270
  });
271
271
  });
272
+
273
+ describe("a11y", () => {
274
+ it("should pass explicit id prop to DOM", () => {
275
+ act(() => {
276
+ root.render(
277
+ <PanelGroup direction="horizontal">
278
+ <Panel />
279
+ <PanelResizeHandle id="explicit-id" />
280
+ <Panel />
281
+ </PanelGroup>
282
+ );
283
+ });
284
+
285
+ const element = container.querySelector("[data-resize-handle]");
286
+
287
+ expect(element).not.toBeNull();
288
+ expect(element?.getAttribute("id")).toBe("explicit-id");
289
+ });
290
+
291
+ it("should not pass auto-generated id prop to DOM", () => {
292
+ act(() => {
293
+ root.render(
294
+ <PanelGroup direction="horizontal">
295
+ <Panel />
296
+ <PanelResizeHandle />
297
+ <Panel />
298
+ </PanelGroup>
299
+ );
300
+ });
301
+
302
+ const element = container.querySelector("[data-resize-handle]");
303
+
304
+ expect(element).not.toBeNull();
305
+ expect(element?.getAttribute("id")).toBeNull();
306
+ });
307
+ });
272
308
  });
@@ -203,6 +203,7 @@ export function PanelResizeHandle({
203
203
 
204
204
  children,
205
205
  className: classNameFromProps,
206
+ id: idFromProps,
206
207
  onBlur: () => setIsFocused(false),
207
208
  onFocus: () => setIsFocused(true),
208
209
  ref: elementRef,
@@ -1,9 +1,9 @@
1
- import { compare } from "stacking-order";
2
1
  import { Direction, ResizeEvent } from "./types";
3
2
  import { resetGlobalCursorStyle, setGlobalCursorStyle } from "./utils/cursor";
4
3
  import { getResizeEventCoordinates } from "./utils/events/getResizeEventCoordinates";
5
4
  import { getInputType } from "./utils/getInputType";
6
5
  import { intersects } from "./utils/rects/intersects";
6
+ import { compare } from "./vendor/stacking-order";
7
7
 
8
8
  export type ResizeHandlerAction = "down" | "move" | "up";
9
9
  export type SetResizeHandlerState = (
@@ -269,7 +269,7 @@ function updateListeners() {
269
269
  window.removeEventListener("touchcancel", handlePointerUp);
270
270
  window.removeEventListener("touchend", handlePointerUp);
271
271
 
272
- if (registerResizeHandle.length > 0) {
272
+ if (registeredResizeHandlers.size > 0) {
273
273
  if (isPointerDown) {
274
274
  if (intersectingHandles.length > 0) {
275
275
  ownerDocumentCounts.forEach((count, ownerDocument) => {
@@ -0,0 +1,130 @@
1
+ // Forked from NPM stacking-order@2.0.0
2
+ // Background at https://github.com/Rich-Harris/stacking-order/issues/3
3
+
4
+ import { assert } from "..";
5
+
6
+ /**
7
+ * Determine which of two nodes appears in front of the other —
8
+ * if `a` is in front, returns 1, otherwise returns -1
9
+ * @param {HTMLElement} a
10
+ * @param {HTMLElement} b
11
+ */
12
+ export function compare(a: HTMLElement, b: HTMLElement): number {
13
+ if (a === b) throw new Error("Cannot compare node with itself");
14
+
15
+ const ancestors = {
16
+ a: get_ancestors(a),
17
+ b: get_ancestors(b),
18
+ };
19
+
20
+ let common_ancestor;
21
+
22
+ // remove shared ancestors
23
+ while (ancestors.a.at(-1) === ancestors.b.at(-1)) {
24
+ a = ancestors.a.pop() as HTMLElement;
25
+ b = ancestors.b.pop() as HTMLElement;
26
+
27
+ common_ancestor = a;
28
+ }
29
+
30
+ assert(common_ancestor);
31
+
32
+ const z_indexes = {
33
+ a: get_z_index(find_stacking_context(ancestors.a)),
34
+ b: get_z_index(find_stacking_context(ancestors.b)),
35
+ };
36
+
37
+ if (z_indexes.a === z_indexes.b) {
38
+ const children = common_ancestor.childNodes;
39
+
40
+ const furthest_ancestors = {
41
+ a: ancestors.a.at(-1),
42
+ b: ancestors.b.at(-1),
43
+ };
44
+
45
+ let i = children.length;
46
+ while (i--) {
47
+ const child = children[i];
48
+ if (child === furthest_ancestors.a) return 1;
49
+ if (child === furthest_ancestors.b) return -1;
50
+ }
51
+ }
52
+
53
+ return Math.sign(z_indexes.a - z_indexes.b);
54
+ }
55
+
56
+ const props =
57
+ /\b(?:position|zIndex|opacity|transform|webkitTransform|mixBlendMode|filter|webkitFilter|isolation)\b/;
58
+
59
+ /** @param {HTMLElement} node */
60
+ function is_flex_item(node: HTMLElement) {
61
+ const display = getComputedStyle(get_parent(node)).display;
62
+ return display === "flex" || display === "inline-flex";
63
+ }
64
+
65
+ /** @param {HTMLElement} node */
66
+ function creates_stacking_context(node: HTMLElement) {
67
+ const style = getComputedStyle(node);
68
+
69
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
70
+ if (style.position === "fixed") return true;
71
+ // Forked to fix upstream bug https://github.com/Rich-Harris/stacking-order/issues/3
72
+ // if (
73
+ // (style.zIndex !== "auto" && style.position !== "static") ||
74
+ // is_flex_item(node)
75
+ // )
76
+ if (
77
+ style.zIndex !== "auto" &&
78
+ (style.position !== "static" || is_flex_item(node))
79
+ )
80
+ return true;
81
+ if (+style.opacity < 1) return true;
82
+ if ("transform" in style && style.transform !== "none") return true;
83
+ if ("webkitTransform" in style && style.webkitTransform !== "none")
84
+ return true;
85
+ if ("mixBlendMode" in style && style.mixBlendMode !== "normal") return true;
86
+ if ("filter" in style && style.filter !== "none") return true;
87
+ if ("webkitFilter" in style && style.webkitFilter !== "none") return true;
88
+ if ("isolation" in style && style.isolation === "isolate") return true;
89
+ if (props.test(style.willChange)) return true;
90
+ // @ts-expect-error
91
+ if (style.webkitOverflowScrolling === "touch") return true;
92
+
93
+ return false;
94
+ }
95
+
96
+ /** @param {HTMLElement[]} nodes */
97
+ function find_stacking_context(nodes: HTMLElement[]) {
98
+ let i = nodes.length;
99
+
100
+ while (i--) {
101
+ const node = nodes[i];
102
+ assert(node);
103
+ if (creates_stacking_context(node)) return node;
104
+ }
105
+
106
+ return null;
107
+ }
108
+
109
+ /** @param {HTMLElement} node */
110
+ function get_z_index(node: HTMLElement | null) {
111
+ return (node && Number(getComputedStyle(node).zIndex)) || 0;
112
+ }
113
+
114
+ /** @param {HTMLElement} node */
115
+ function get_ancestors(node: HTMLElement) {
116
+ const ancestors = [];
117
+
118
+ while (node) {
119
+ ancestors.push(node);
120
+ node = get_parent(node);
121
+ }
122
+
123
+ return ancestors; // [ node, ... <body>, <html>, document ]
124
+ }
125
+
126
+ /** @param {HTMLElement} node */
127
+ function get_parent(node: HTMLElement) {
128
+ // @ts-ignore
129
+ return node.parentNode?.host || node.parentNode;
130
+ }