@wordpress/grid 0.1.0

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.
Files changed (158) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE.md +788 -0
  3. package/README.md +534 -0
  4. package/build/dashboard-grid/grid-item.cjs +308 -0
  5. package/build/dashboard-grid/grid-item.cjs.map +7 -0
  6. package/build/dashboard-grid/index.cjs +591 -0
  7. package/build/dashboard-grid/index.cjs.map +7 -0
  8. package/build/dashboard-grid/resolve-fill-widths.cjs +189 -0
  9. package/build/dashboard-grid/resolve-fill-widths.cjs.map +7 -0
  10. package/build/dashboard-grid/types.cjs +19 -0
  11. package/build/dashboard-grid/types.cjs.map +7 -0
  12. package/build/dashboard-lanes/index.cjs +558 -0
  13. package/build/dashboard-lanes/index.cjs.map +7 -0
  14. package/build/dashboard-lanes/lane-placement.cjs +110 -0
  15. package/build/dashboard-lanes/lane-placement.cjs.map +7 -0
  16. package/build/dashboard-lanes/lanes-item.cjs +295 -0
  17. package/build/dashboard-lanes/lanes-item.cjs.map +7 -0
  18. package/build/dashboard-lanes/types.cjs +19 -0
  19. package/build/dashboard-lanes/types.cjs.map +7 -0
  20. package/build/dashboard-lanes/use-lane-placement.cjs +206 -0
  21. package/build/dashboard-lanes/use-lane-placement.cjs.map +7 -0
  22. package/build/index.cjs +34 -0
  23. package/build/index.cjs.map +7 -0
  24. package/build/shared/drag-overlay-drop-animation.cjs +70 -0
  25. package/build/shared/drag-overlay-drop-animation.cjs.map +7 -0
  26. package/build/shared/grid-item-key.cjs +31 -0
  27. package/build/shared/grid-item-key.cjs.map +7 -0
  28. package/build/shared/grid-overlay.cjs +187 -0
  29. package/build/shared/grid-overlay.cjs.map +7 -0
  30. package/build/shared/item-exit-overlay.cjs +150 -0
  31. package/build/shared/item-exit-overlay.cjs.map +7 -0
  32. package/build/shared/resize-handle.cjs +224 -0
  33. package/build/shared/resize-handle.cjs.map +7 -0
  34. package/build/shared/resize-snap.cjs +47 -0
  35. package/build/shared/resize-snap.cjs.map +7 -0
  36. package/build/shared/types.cjs +19 -0
  37. package/build/shared/types.cjs.map +7 -0
  38. package/build/shared/use-item-exit-animation.cjs +148 -0
  39. package/build/shared/use-item-exit-animation.cjs.map +7 -0
  40. package/build/shared/use-layout-shift-animation.cjs +167 -0
  41. package/build/shared/use-layout-shift-animation.cjs.map +7 -0
  42. package/build-module/dashboard-grid/grid-item.mjs +273 -0
  43. package/build-module/dashboard-grid/grid-item.mjs.map +7 -0
  44. package/build-module/dashboard-grid/index.mjs +579 -0
  45. package/build-module/dashboard-grid/index.mjs.map +7 -0
  46. package/build-module/dashboard-grid/resolve-fill-widths.mjs +164 -0
  47. package/build-module/dashboard-grid/resolve-fill-widths.mjs.map +7 -0
  48. package/build-module/dashboard-grid/types.mjs +1 -0
  49. package/build-module/dashboard-grid/types.mjs.map +7 -0
  50. package/build-module/dashboard-lanes/index.mjs +547 -0
  51. package/build-module/dashboard-lanes/index.mjs.map +7 -0
  52. package/build-module/dashboard-lanes/lane-placement.mjs +85 -0
  53. package/build-module/dashboard-lanes/lane-placement.mjs.map +7 -0
  54. package/build-module/dashboard-lanes/lanes-item.mjs +260 -0
  55. package/build-module/dashboard-lanes/lanes-item.mjs.map +7 -0
  56. package/build-module/dashboard-lanes/types.mjs +1 -0
  57. package/build-module/dashboard-lanes/types.mjs.map +7 -0
  58. package/build-module/dashboard-lanes/use-lane-placement.mjs +181 -0
  59. package/build-module/dashboard-lanes/use-lane-placement.mjs.map +7 -0
  60. package/build-module/index.mjs +8 -0
  61. package/build-module/index.mjs.map +7 -0
  62. package/build-module/shared/drag-overlay-drop-animation.mjs +47 -0
  63. package/build-module/shared/drag-overlay-drop-animation.mjs.map +7 -0
  64. package/build-module/shared/grid-item-key.mjs +6 -0
  65. package/build-module/shared/grid-item-key.mjs.map +7 -0
  66. package/build-module/shared/grid-overlay.mjs +152 -0
  67. package/build-module/shared/grid-overlay.mjs.map +7 -0
  68. package/build-module/shared/item-exit-overlay.mjs +125 -0
  69. package/build-module/shared/item-exit-overlay.mjs.map +7 -0
  70. package/build-module/shared/resize-handle.mjs +193 -0
  71. package/build-module/shared/resize-handle.mjs.map +7 -0
  72. package/build-module/shared/resize-snap.mjs +21 -0
  73. package/build-module/shared/resize-snap.mjs.map +7 -0
  74. package/build-module/shared/types.mjs +1 -0
  75. package/build-module/shared/types.mjs.map +7 -0
  76. package/build-module/shared/use-item-exit-animation.mjs +128 -0
  77. package/build-module/shared/use-item-exit-animation.mjs.map +7 -0
  78. package/build-module/shared/use-layout-shift-animation.mjs +140 -0
  79. package/build-module/shared/use-layout-shift-animation.mjs.map +7 -0
  80. package/build-types/dashboard-grid/grid-item.d.ts +3 -0
  81. package/build-types/dashboard-grid/grid-item.d.ts.map +1 -0
  82. package/build-types/dashboard-grid/index.d.ts +35 -0
  83. package/build-types/dashboard-grid/index.d.ts.map +1 -0
  84. package/build-types/dashboard-grid/resolve-fill-widths.d.ts +26 -0
  85. package/build-types/dashboard-grid/resolve-fill-widths.d.ts.map +1 -0
  86. package/build-types/dashboard-grid/stories/index.story.d.ts +98 -0
  87. package/build-types/dashboard-grid/stories/index.story.d.ts.map +1 -0
  88. package/build-types/dashboard-grid/types.d.ts +232 -0
  89. package/build-types/dashboard-grid/types.d.ts.map +1 -0
  90. package/build-types/dashboard-lanes/index.d.ts +40 -0
  91. package/build-types/dashboard-lanes/index.d.ts.map +1 -0
  92. package/build-types/dashboard-lanes/lane-placement.d.ts +126 -0
  93. package/build-types/dashboard-lanes/lane-placement.d.ts.map +1 -0
  94. package/build-types/dashboard-lanes/lanes-item.d.ts +52 -0
  95. package/build-types/dashboard-lanes/lanes-item.d.ts.map +1 -0
  96. package/build-types/dashboard-lanes/stories/index.story.d.ts +64 -0
  97. package/build-types/dashboard-lanes/stories/index.story.d.ts.map +1 -0
  98. package/build-types/dashboard-lanes/types.d.ts +151 -0
  99. package/build-types/dashboard-lanes/types.d.ts.map +1 -0
  100. package/build-types/dashboard-lanes/use-lane-placement.d.ts +74 -0
  101. package/build-types/dashboard-lanes/use-lane-placement.d.ts.map +1 -0
  102. package/build-types/index.d.ts +6 -0
  103. package/build-types/index.d.ts.map +1 -0
  104. package/build-types/shared/drag-overlay-drop-animation.d.ts +13 -0
  105. package/build-types/shared/drag-overlay-drop-animation.d.ts.map +1 -0
  106. package/build-types/shared/grid-item-key.d.ts +6 -0
  107. package/build-types/shared/grid-item-key.d.ts.map +1 -0
  108. package/build-types/shared/grid-overlay.d.ts +19 -0
  109. package/build-types/shared/grid-overlay.d.ts.map +1 -0
  110. package/build-types/shared/item-exit-overlay.d.ts +20 -0
  111. package/build-types/shared/item-exit-overlay.d.ts.map +1 -0
  112. package/build-types/shared/resize-handle.d.ts +23 -0
  113. package/build-types/shared/resize-handle.d.ts.map +1 -0
  114. package/build-types/shared/resize-snap.d.ts +41 -0
  115. package/build-types/shared/resize-snap.d.ts.map +1 -0
  116. package/build-types/shared/types.d.ts +144 -0
  117. package/build-types/shared/types.d.ts.map +1 -0
  118. package/build-types/shared/use-item-exit-animation.d.ts +37 -0
  119. package/build-types/shared/use-item-exit-animation.d.ts.map +1 -0
  120. package/build-types/shared/use-layout-shift-animation.d.ts +77 -0
  121. package/build-types/shared/use-layout-shift-animation.d.ts.map +1 -0
  122. package/package.json +80 -0
  123. package/src/dashboard-grid/grid-item.module.css +94 -0
  124. package/src/dashboard-grid/grid-item.tsx +205 -0
  125. package/src/dashboard-grid/grid.module.css +134 -0
  126. package/src/dashboard-grid/index.tsx +713 -0
  127. package/src/dashboard-grid/resolve-fill-widths.ts +224 -0
  128. package/src/dashboard-grid/stories/index.story.tsx +930 -0
  129. package/src/dashboard-grid/test/keyboard-activation.test.tsx +76 -0
  130. package/src/dashboard-grid/test/resolve-fill-widths.test.ts +250 -0
  131. package/src/dashboard-grid/types.ts +271 -0
  132. package/src/dashboard-lanes/index.tsx +629 -0
  133. package/src/dashboard-lanes/lane-placement.ts +245 -0
  134. package/src/dashboard-lanes/lanes-item.module.css +93 -0
  135. package/src/dashboard-lanes/lanes-item.tsx +236 -0
  136. package/src/dashboard-lanes/lanes.module.css +152 -0
  137. package/src/dashboard-lanes/stories/index.story.tsx +518 -0
  138. package/src/dashboard-lanes/test/keyboard-activation.test.tsx +71 -0
  139. package/src/dashboard-lanes/test/lane-placement.test.ts +442 -0
  140. package/src/dashboard-lanes/test/use-lane-placement.test.tsx +358 -0
  141. package/src/dashboard-lanes/types.ts +176 -0
  142. package/src/dashboard-lanes/use-lane-placement.ts +313 -0
  143. package/src/index.ts +17 -0
  144. package/src/shared/actionable-area-slot.module.css +16 -0
  145. package/src/shared/drag-overlay-drop-animation.ts +66 -0
  146. package/src/shared/grid-item-key.ts +5 -0
  147. package/src/shared/grid-overlay.module.css +82 -0
  148. package/src/shared/grid-overlay.tsx +93 -0
  149. package/src/shared/item-exit-animation.module.css +49 -0
  150. package/src/shared/item-exit-overlay.tsx +57 -0
  151. package/src/shared/layout-shift-animation.module.css +16 -0
  152. package/src/shared/resize-handle.module.css +88 -0
  153. package/src/shared/resize-handle.tsx +163 -0
  154. package/src/shared/resize-snap.ts +63 -0
  155. package/src/shared/test/resize-snap.test.ts +35 -0
  156. package/src/shared/types.ts +164 -0
  157. package/src/shared/use-item-exit-animation.ts +199 -0
  158. package/src/shared/use-layout-shift-animation.ts +284 -0
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // packages/grid/src/shared/use-item-exit-animation.ts
21
+ var use_item_exit_animation_exports = {};
22
+ __export(use_item_exit_animation_exports, {
23
+ useItemExitAnimation: () => useItemExitAnimation
24
+ });
25
+ module.exports = __toCommonJS(use_item_exit_animation_exports);
26
+ var import_element = require("@wordpress/element");
27
+ var EXIT_SAFETY_TIMEOUT_MS = 1e3;
28
+ function prefersReducedMotion() {
29
+ return typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
30
+ }
31
+ function useItemExitAnimation({
32
+ container,
33
+ enabled,
34
+ layoutKeys,
35
+ getPositionsBeforeLastChange,
36
+ childrenCacheRef
37
+ }) {
38
+ const [exitingItems, setExitingItems] = (0, import_element.useState)(
39
+ []
40
+ );
41
+ const prevLayoutKeysRef = (0, import_element.useRef)(/* @__PURE__ */ new Set());
42
+ const exitTimeoutsRef = (0, import_element.useRef)(/* @__PURE__ */ new Map());
43
+ const clearExitingItem = (0, import_element.useCallback)(
44
+ (key) => {
45
+ const timeout = exitTimeoutsRef.current.get(key);
46
+ if (timeout) {
47
+ clearTimeout(timeout);
48
+ exitTimeoutsRef.current.delete(key);
49
+ }
50
+ setExitingItems(
51
+ (current) => current.filter((item) => item.key !== key)
52
+ );
53
+ childrenCacheRef.current.delete(key);
54
+ },
55
+ [childrenCacheRef]
56
+ );
57
+ const scheduleExitComplete = (0, import_element.useCallback)(
58
+ (key) => {
59
+ if (exitTimeoutsRef.current.has(key)) {
60
+ return;
61
+ }
62
+ const timeout = setTimeout(() => {
63
+ exitTimeoutsRef.current.delete(key);
64
+ clearExitingItem(key);
65
+ }, EXIT_SAFETY_TIMEOUT_MS);
66
+ exitTimeoutsRef.current.set(key, timeout);
67
+ },
68
+ [clearExitingItem]
69
+ );
70
+ (0, import_element.useLayoutEffect)(() => {
71
+ if (!enabled || !container) {
72
+ prevLayoutKeysRef.current = new Set(layoutKeys);
73
+ for (const timeout of exitTimeoutsRef.current.values()) {
74
+ clearTimeout(timeout);
75
+ }
76
+ exitTimeoutsRef.current.clear();
77
+ setExitingItems([]);
78
+ return;
79
+ }
80
+ const prevKeys = prevLayoutKeysRef.current;
81
+ const removed = [];
82
+ for (const key of prevKeys) {
83
+ if (!layoutKeys.has(key)) {
84
+ removed.push(key);
85
+ }
86
+ }
87
+ prevLayoutKeysRef.current = new Set(layoutKeys);
88
+ if (removed.length === 0) {
89
+ return;
90
+ }
91
+ const lastPositions = getPositionsBeforeLastChange();
92
+ if (!lastPositions) {
93
+ return;
94
+ }
95
+ const nextExiting = [];
96
+ for (const key of removed) {
97
+ const position = lastPositions.get(key);
98
+ const child = childrenCacheRef.current.get(key);
99
+ if (!position || !child) {
100
+ continue;
101
+ }
102
+ nextExiting.push({
103
+ key,
104
+ rect: position,
105
+ child
106
+ });
107
+ }
108
+ if (nextExiting.length === 0) {
109
+ return;
110
+ }
111
+ if (prefersReducedMotion()) {
112
+ for (const { key } of nextExiting) {
113
+ childrenCacheRef.current.delete(key);
114
+ }
115
+ return;
116
+ }
117
+ setExitingItems((current) => [...current, ...nextExiting]);
118
+ for (const { key } of nextExiting) {
119
+ scheduleExitComplete(key);
120
+ }
121
+ }, [
122
+ container,
123
+ enabled,
124
+ getPositionsBeforeLastChange,
125
+ layoutKeys,
126
+ childrenCacheRef,
127
+ scheduleExitComplete
128
+ ]);
129
+ (0, import_element.useLayoutEffect)(() => {
130
+ const exitTimeouts = exitTimeoutsRef.current;
131
+ return () => {
132
+ for (const timeout of exitTimeouts.values()) {
133
+ clearTimeout(timeout);
134
+ }
135
+ exitTimeouts.clear();
136
+ };
137
+ }, []);
138
+ return {
139
+ exitingItems,
140
+ hasExitingItems: exitingItems.length > 0,
141
+ clearExitingItem
142
+ };
143
+ }
144
+ // Annotate the CommonJS export names for ESM import in node:
145
+ 0 && (module.exports = {
146
+ useItemExitAnimation
147
+ });
148
+ //# sourceMappingURL=use-item-exit-animation.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shared/use-item-exit-animation.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport {\n\tuseCallback,\n\tuseLayoutEffect,\n\tuseRef,\n\tuseState,\n} from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport type { ItemExitOverlayRect } from './item-exit-overlay';\nimport type { RectSnapshot } from './use-layout-shift-animation';\n\n/*\n * Last-resort cleanup if `animationend` never fires (the overlay's\n * `onAnimationEnd` is the primary path). Kept well above the motion\n * token durations so the timeout can never clip the exit animation.\n */\nconst EXIT_SAFETY_TIMEOUT_MS = 1000;\n\nexport type ExitingGridItem = {\n\tkey: string;\n\trect: ItemExitOverlayRect;\n\tchild: React.ReactElement;\n};\n\ntype UseItemExitAnimationOptions = {\n\tcontainer: HTMLElement | null;\n\tenabled: boolean;\n\tlayoutKeys: ReadonlySet< string >;\n\tgetPositionsBeforeLastChange: () => ReadonlyMap<\n\t\tstring,\n\t\tRectSnapshot\n\t> | null;\n\tchildrenCacheRef: React.MutableRefObject<\n\t\tMap< string, React.ReactElement >\n\t>;\n};\n\ntype UseItemExitAnimationResult = {\n\texitingItems: ExitingGridItem[];\n\thasExitingItems: boolean;\n\tclearExitingItem: ( key: string ) => void;\n};\n\nfunction prefersReducedMotion(): boolean {\n\treturn (\n\t\ttypeof window !== 'undefined' &&\n\t\twindow.matchMedia( '(prefers-reduced-motion: reduce)' ).matches\n\t);\n}\n\n/**\n * When `layout` loses keys in edit mode, keeps a short-lived overlay at\n * the removed tile's last position (scale + fade) while siblings FLIP.\n *\n * @param root0 Hook options.\n * @param root0.container Surface root that contains grid tiles.\n * @param root0.enabled When false, exiting state is cleared.\n * @param root0.layoutKeys Keys in the committed `layout` prop.\n * @param root0.getPositionsBeforeLastChange Container-relative rects before the latest layout commit.\n * @param root0.childrenCacheRef Last rendered children keyed by tile id.\n * @return Exiting overlays and a callback to dismiss one by key.\n */\nexport function useItemExitAnimation( {\n\tcontainer,\n\tenabled,\n\tlayoutKeys,\n\tgetPositionsBeforeLastChange,\n\tchildrenCacheRef,\n}: UseItemExitAnimationOptions ): UseItemExitAnimationResult {\n\tconst [ exitingItems, setExitingItems ] = useState< ExitingGridItem[] >(\n\t\t[]\n\t);\n\tconst prevLayoutKeysRef = useRef< Set< string > >( new Set() );\n\tconst exitTimeoutsRef = useRef<\n\t\tMap< string, ReturnType< typeof setTimeout > >\n\t>( new Map() );\n\n\tconst clearExitingItem = useCallback(\n\t\t( key: string ) => {\n\t\t\tconst timeout = exitTimeoutsRef.current.get( key );\n\t\t\tif ( timeout ) {\n\t\t\t\tclearTimeout( timeout );\n\t\t\t\texitTimeoutsRef.current.delete( key );\n\t\t\t}\n\t\t\tsetExitingItems( ( current ) =>\n\t\t\t\tcurrent.filter( ( item ) => item.key !== key )\n\t\t\t);\n\t\t\tchildrenCacheRef.current.delete( key );\n\t\t},\n\t\t[ childrenCacheRef ]\n\t);\n\n\tconst scheduleExitComplete = useCallback(\n\t\t( key: string ) => {\n\t\t\tif ( exitTimeoutsRef.current.has( key ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst timeout = setTimeout( () => {\n\t\t\t\texitTimeoutsRef.current.delete( key );\n\t\t\t\tclearExitingItem( key );\n\t\t\t}, EXIT_SAFETY_TIMEOUT_MS );\n\t\t\texitTimeoutsRef.current.set( key, timeout );\n\t\t},\n\t\t[ clearExitingItem ]\n\t);\n\n\tuseLayoutEffect( () => {\n\t\tif ( ! enabled || ! container ) {\n\t\t\tprevLayoutKeysRef.current = new Set( layoutKeys );\n\t\t\tfor ( const timeout of exitTimeoutsRef.current.values() ) {\n\t\t\t\tclearTimeout( timeout );\n\t\t\t}\n\t\t\texitTimeoutsRef.current.clear();\n\t\t\tsetExitingItems( [] );\n\t\t\treturn;\n\t\t}\n\n\t\tconst prevKeys = prevLayoutKeysRef.current;\n\t\tconst removed: string[] = [];\n\t\tfor ( const key of prevKeys ) {\n\t\t\tif ( ! layoutKeys.has( key ) ) {\n\t\t\t\tremoved.push( key );\n\t\t\t}\n\t\t}\n\t\tprevLayoutKeysRef.current = new Set( layoutKeys );\n\n\t\tif ( removed.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst lastPositions = getPositionsBeforeLastChange();\n\t\tif ( ! lastPositions ) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst nextExiting: ExitingGridItem[] = [];\n\t\tfor ( const key of removed ) {\n\t\t\tconst position = lastPositions.get( key );\n\t\t\tconst child = childrenCacheRef.current.get( key );\n\t\t\tif ( ! position || ! child ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tnextExiting.push( {\n\t\t\t\tkey,\n\t\t\t\trect: position,\n\t\t\t\tchild,\n\t\t\t} );\n\t\t}\n\n\t\tif ( nextExiting.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( prefersReducedMotion() ) {\n\t\t\t// Siblings snap into place via the layout-shift hook; skip the\n\t\t\t// exit ghost (and its synchronous mount) entirely.\n\t\t\tfor ( const { key } of nextExiting ) {\n\t\t\t\tchildrenCacheRef.current.delete( key );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// A state update inside a layout effect is flushed before paint,\n\t\t// so the ghost mounts in the same frame the tile is removed.\n\t\tsetExitingItems( ( current ) => [ ...current, ...nextExiting ] );\n\n\t\tfor ( const { key } of nextExiting ) {\n\t\t\tscheduleExitComplete( key );\n\t\t}\n\t}, [\n\t\tcontainer,\n\t\tenabled,\n\t\tgetPositionsBeforeLastChange,\n\t\tlayoutKeys,\n\t\tchildrenCacheRef,\n\t\tscheduleExitComplete,\n\t] );\n\n\tuseLayoutEffect( () => {\n\t\tconst exitTimeouts = exitTimeoutsRef.current;\n\t\treturn () => {\n\t\t\tfor ( const timeout of exitTimeouts.values() ) {\n\t\t\t\tclearTimeout( timeout );\n\t\t\t}\n\t\t\texitTimeouts.clear();\n\t\t};\n\t}, [] );\n\n\treturn {\n\t\texitingItems,\n\t\thasExitingItems: exitingItems.length > 0,\n\t\tclearExitingItem,\n\t};\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // packages/grid/src/shared/use-layout-shift-animation.ts
21
+ var use_layout_shift_animation_exports = {};
22
+ __export(use_layout_shift_animation_exports, {
23
+ getLayoutFingerprint: () => getLayoutFingerprint,
24
+ getPlacementFingerprint: () => getPlacementFingerprint,
25
+ useLayoutShiftAnimation: () => useLayoutShiftAnimation
26
+ });
27
+ module.exports = __toCommonJS(use_layout_shift_animation_exports);
28
+ var import_element = require("@wordpress/element");
29
+ var import_grid_item_key = require("./grid-item-key.cjs");
30
+ function queryGridItems(container) {
31
+ return Array.from(
32
+ container.querySelectorAll(
33
+ `[${import_grid_item_key.GRID_ITEM_DATA_KEY}]:not([data-wp-grid-item-exiting])`
34
+ )
35
+ );
36
+ }
37
+ function readItemKey(element) {
38
+ return element.getAttribute(import_grid_item_key.GRID_ITEM_DATA_KEY);
39
+ }
40
+ function snapshotPositions(container) {
41
+ const base = container.getBoundingClientRect();
42
+ const positions = /* @__PURE__ */ new Map();
43
+ for (const element of queryGridItems(container)) {
44
+ const key = readItemKey(element);
45
+ if (!key) {
46
+ continue;
47
+ }
48
+ const { left, top, width, height } = element.getBoundingClientRect();
49
+ positions.set(key, {
50
+ left: left - base.left,
51
+ top: top - base.top,
52
+ width,
53
+ height
54
+ });
55
+ }
56
+ return positions;
57
+ }
58
+ function clearLayoutShiftStyles(element) {
59
+ element.style.removeProperty("transform");
60
+ element.style.removeProperty("transition");
61
+ }
62
+ function playLayoutShift(element, deltaX, deltaY) {
63
+ if (deltaX === 0 && deltaY === 0) {
64
+ return;
65
+ }
66
+ element.style.transition = "none";
67
+ element.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
68
+ void element.offsetHeight;
69
+ requestAnimationFrame(() => {
70
+ element.style.removeProperty("transition");
71
+ element.style.transform = "";
72
+ const onTransitionEnd = (event) => {
73
+ if (event.propertyName !== "transform") {
74
+ return;
75
+ }
76
+ element.removeEventListener("transitionend", onTransitionEnd);
77
+ clearLayoutShiftStyles(element);
78
+ };
79
+ element.addEventListener("transitionend", onTransitionEnd);
80
+ });
81
+ }
82
+ function useLayoutShiftAnimation({
83
+ container,
84
+ enabled,
85
+ layoutFingerprint,
86
+ excludeItemKey = null
87
+ }) {
88
+ const snapshotBeforeChangeRef = (0, import_element.useRef)(null);
89
+ const lastRenderedPositionsRef = (0, import_element.useRef)(null);
90
+ const positionsBeforeLastChangeRef = (0, import_element.useRef)(null);
91
+ const captureLayoutSnapshot = (0, import_element.useCallback)(() => {
92
+ if (container) {
93
+ snapshotBeforeChangeRef.current = snapshotPositions(container);
94
+ }
95
+ }, [container]);
96
+ (0, import_element.useLayoutEffect)(() => {
97
+ if (!container || !enabled) {
98
+ snapshotBeforeChangeRef.current = null;
99
+ lastRenderedPositionsRef.current = null;
100
+ positionsBeforeLastChangeRef.current = null;
101
+ if (container) {
102
+ for (const element of queryGridItems(container)) {
103
+ clearLayoutShiftStyles(element);
104
+ }
105
+ }
106
+ return;
107
+ }
108
+ for (const element of queryGridItems(container)) {
109
+ clearLayoutShiftStyles(element);
110
+ }
111
+ const previous = snapshotBeforeChangeRef.current ?? lastRenderedPositionsRef.current;
112
+ snapshotBeforeChangeRef.current = null;
113
+ positionsBeforeLastChangeRef.current = previous ? new Map(previous) : null;
114
+ lastRenderedPositionsRef.current = snapshotPositions(container);
115
+ if (previous) {
116
+ const base = container.getBoundingClientRect();
117
+ for (const element of queryGridItems(container)) {
118
+ const key = readItemKey(element);
119
+ if (!key || key === excludeItemKey) {
120
+ continue;
121
+ }
122
+ const old = previous.get(key);
123
+ if (!old) {
124
+ continue;
125
+ }
126
+ const { left, top } = element.getBoundingClientRect();
127
+ const deltaX = old.left - (left - base.left);
128
+ const deltaY = old.top - (top - base.top);
129
+ playLayoutShift(element, deltaX, deltaY);
130
+ }
131
+ }
132
+ }, [container, enabled, layoutFingerprint, excludeItemKey]);
133
+ const getLastPositions = (0, import_element.useCallback)(() => {
134
+ return lastRenderedPositionsRef.current;
135
+ }, []);
136
+ const getPositionsBeforeLastChange = (0, import_element.useCallback)(() => {
137
+ return positionsBeforeLastChangeRef.current;
138
+ }, []);
139
+ return {
140
+ captureLayoutSnapshot,
141
+ getLastPositions,
142
+ getPositionsBeforeLastChange
143
+ };
144
+ }
145
+ function getLayoutFingerprint(layout) {
146
+ return layout.map(
147
+ (item) => `${item.key}:${String(item.width ?? "")}:${item.height ?? 1}:${item.order ?? ""}:${item.lane ?? ""}`
148
+ ).join("|");
149
+ }
150
+ function getPlacementFingerprint(itemStyles) {
151
+ return [...itemStyles.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([key, style]) => {
152
+ const column = style.gridColumn ?? "";
153
+ const columnStart = style.gridColumnStart ?? "";
154
+ const rowStart = style.gridRowStart ?? "";
155
+ const rowEnd = style.gridRowEnd ?? "";
156
+ return `${key}:${String(column)}:${String(
157
+ columnStart
158
+ )}:${String(rowStart)}:${String(rowEnd)}`;
159
+ }).join("|");
160
+ }
161
+ // Annotate the CommonJS export names for ESM import in node:
162
+ 0 && (module.exports = {
163
+ getLayoutFingerprint,
164
+ getPlacementFingerprint,
165
+ useLayoutShiftAnimation
166
+ });
167
+ //# sourceMappingURL=use-layout-shift-animation.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shared/use-layout-shift-animation.ts"],
4
+ "sourcesContent": ["/**\n * WordPress dependencies\n */\nimport { useCallback, useLayoutEffect, useRef } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport { GRID_ITEM_DATA_KEY } from './grid-item-key';\n\n/* `left`/`top` are relative to the grid container, not the viewport. */\nexport type RectSnapshot = {\n\tleft: number;\n\ttop: number;\n\twidth: number;\n\theight: number;\n};\n\ntype UseLayoutShiftAnimationOptions = {\n\t/**\n\t * Surface root that contains grid tiles.\n\t */\n\tcontainer: HTMLElement | null;\n\n\t/**\n\t * When false, snapshots are cleared and no transforms run.\n\t */\n\tenabled: boolean;\n\n\t/**\n\t * Serialized layout/placement state. The hook runs FLIP when this\n\t * value changes while `enabled` is true.\n\t */\n\tlayoutFingerprint: string;\n\n\t/**\n\t * Item key to skip (the tile being dragged or resized).\n\t */\n\texcludeItemKey?: string | null;\n};\n\ntype UseLayoutShiftAnimationResult = {\n\t/**\n\t * Capture tile positions synchronously **before** a layout update\n\t * (call immediately before `setTemporaryLayout` / similar).\n\t */\n\tcaptureLayoutSnapshot: () => void;\n\n\t/**\n\t * Container-relative rects from the last committed paint (settled, no\n\t * FLIP invert transforms).\n\t */\n\tgetLastPositions: () => ReadonlyMap< string, RectSnapshot > | null;\n\n\t/**\n\t * Tile positions immediately before the latest layout commit. Used\n\t * by item-exit animation when keys drop out of `layout`.\n\t */\n\tgetPositionsBeforeLastChange: () => ReadonlyMap<\n\t\tstring,\n\t\tRectSnapshot\n\t> | null;\n};\n\nfunction queryGridItems( container: HTMLElement ): HTMLElement[] {\n\treturn Array.from(\n\t\tcontainer.querySelectorAll< HTMLElement >(\n\t\t\t`[${ GRID_ITEM_DATA_KEY }]:not([data-wp-grid-item-exiting])`\n\t\t)\n\t);\n}\n\nfunction readItemKey( element: HTMLElement ): string | null {\n\treturn element.getAttribute( GRID_ITEM_DATA_KEY );\n}\n\nfunction snapshotPositions(\n\tcontainer: HTMLElement\n): Map< string, RectSnapshot > {\n\t// Measure relative to the container so positions stay valid even if the\n\t// page scroll shifts between capture and use (e.g. the document reflowing\n\t// shorter after a tile is removed).\n\tconst base = container.getBoundingClientRect();\n\tconst positions = new Map< string, RectSnapshot >();\n\tfor ( const element of queryGridItems( container ) ) {\n\t\tconst key = readItemKey( element );\n\t\tif ( ! key ) {\n\t\t\tcontinue;\n\t\t}\n\t\tconst { left, top, width, height } = element.getBoundingClientRect();\n\t\tpositions.set( key, {\n\t\t\tleft: left - base.left,\n\t\t\ttop: top - base.top,\n\t\t\twidth,\n\t\t\theight,\n\t\t} );\n\t}\n\treturn positions;\n}\n\nfunction clearLayoutShiftStyles( element: HTMLElement ): void {\n\telement.style.removeProperty( 'transform' );\n\telement.style.removeProperty( 'transition' );\n}\n\nfunction playLayoutShift(\n\telement: HTMLElement,\n\tdeltaX: number,\n\tdeltaY: number\n): void {\n\tif ( deltaX === 0 && deltaY === 0 ) {\n\t\treturn;\n\t}\n\n\t// Invert: show the tile where it was before the layout change.\n\telement.style.transition = 'none';\n\telement.style.transform = `translate(${ deltaX }px, ${ deltaY }px)`;\n\tvoid element.offsetHeight;\n\n\t// Play on the next frame so the inverted transform paints before\n\t// the transition back to the committed grid position.\n\trequestAnimationFrame( () => {\n\t\telement.style.removeProperty( 'transition' );\n\t\telement.style.transform = '';\n\n\t\tconst onTransitionEnd = ( event: TransitionEvent ) => {\n\t\t\tif ( event.propertyName !== 'transform' ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telement.removeEventListener( 'transitionend', onTransitionEnd );\n\t\t\tclearLayoutShiftStyles( element );\n\t\t};\n\t\telement.addEventListener( 'transitionend', onTransitionEnd );\n\t} );\n}\n\n/**\n * Animates sibling tiles when grid layout reflows during drag or resize\n * using a FLIP transform (see `layout-shift-animation.module.css`).\n *\n * @param root0 Hook options.\n * @param root0.container Surface root that contains grid tiles.\n * @param root0.enabled When false, snapshots are cleared and no transforms run.\n * @param root0.layoutFingerprint Serialized layout/placement state.\n * @param root0.excludeItemKey Item key to skip (the tile being dragged or resized).\n * @return Snapshot capture callback for use before layout updates.\n */\nexport function useLayoutShiftAnimation( {\n\tcontainer,\n\tenabled,\n\tlayoutFingerprint,\n\texcludeItemKey = null,\n}: UseLayoutShiftAnimationOptions ): UseLayoutShiftAnimationResult {\n\tconst snapshotBeforeChangeRef = useRef< Map<\n\t\tstring,\n\t\tRectSnapshot\n\t> | null >( null );\n\tconst lastRenderedPositionsRef = useRef< Map<\n\t\tstring,\n\t\tRectSnapshot\n\t> | null >( null );\n\tconst positionsBeforeLastChangeRef = useRef< Map<\n\t\tstring,\n\t\tRectSnapshot\n\t> | null >( null );\n\n\tconst captureLayoutSnapshot = useCallback( () => {\n\t\tif ( container ) {\n\t\t\tsnapshotBeforeChangeRef.current = snapshotPositions( container );\n\t\t}\n\t}, [ container ] );\n\n\tuseLayoutEffect( () => {\n\t\tif ( ! container || ! enabled ) {\n\t\t\tsnapshotBeforeChangeRef.current = null;\n\t\t\tlastRenderedPositionsRef.current = null;\n\t\t\tpositionsBeforeLastChangeRef.current = null;\n\t\t\tif ( container ) {\n\t\t\t\tfor ( const element of queryGridItems( container ) ) {\n\t\t\t\t\tclearLayoutShiftStyles( element );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( const element of queryGridItems( container ) ) {\n\t\t\tclearLayoutShiftStyles( element );\n\t\t}\n\n\t\tconst previous =\n\t\t\tsnapshotBeforeChangeRef.current ?? lastRenderedPositionsRef.current;\n\t\tsnapshotBeforeChangeRef.current = null;\n\n\t\tpositionsBeforeLastChangeRef.current = previous\n\t\t\t? new Map( previous )\n\t\t\t: null;\n\n\t\t// Record settled grid positions for the next FLIP. Must run before\n\t\t// invert transforms — measuring after `playLayoutShift` would bake\n\t\t// translate offsets into the baseline and skew the next animation.\n\t\tlastRenderedPositionsRef.current = snapshotPositions( container );\n\n\t\tif ( previous ) {\n\t\t\tconst base = container.getBoundingClientRect();\n\t\t\tfor ( const element of queryGridItems( container ) ) {\n\t\t\t\tconst key = readItemKey( element );\n\t\t\t\tif ( ! key || key === excludeItemKey ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst old = previous.get( key );\n\t\t\t\tif ( ! old ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst { left, top } = element.getBoundingClientRect();\n\t\t\t\tconst deltaX = old.left - ( left - base.left );\n\t\t\t\tconst deltaY = old.top - ( top - base.top );\n\t\t\t\tplayLayoutShift( element, deltaX, deltaY );\n\t\t\t}\n\t\t}\n\t}, [ container, enabled, layoutFingerprint, excludeItemKey ] );\n\n\tconst getLastPositions = useCallback( () => {\n\t\treturn lastRenderedPositionsRef.current;\n\t}, [] );\n\n\tconst getPositionsBeforeLastChange = useCallback( () => {\n\t\treturn positionsBeforeLastChangeRef.current;\n\t}, [] );\n\n\treturn {\n\t\tcaptureLayoutSnapshot,\n\t\tgetLastPositions,\n\t\tgetPositionsBeforeLastChange,\n\t};\n}\n\n/**\n * Stable fingerprint for {@link useLayoutShiftAnimation}. Width/height\n * values may be numbers or layout keywords (`'fill'`, `'full'`).\n *\n * @param layout Layout items to serialize.\n * @return Fingerprint string.\n */\nexport function getLayoutFingerprint(\n\tlayout: ReadonlyArray< {\n\t\tkey: string;\n\t\twidth?: number | string;\n\t\theight?: number;\n\t\torder?: number;\n\t\tlane?: number;\n\t} >\n): string {\n\treturn layout\n\t\t.map(\n\t\t\t( item ) =>\n\t\t\t\t`${ item.key }:${ String( item.width ?? '' ) }:${\n\t\t\t\t\titem.height ?? 1\n\t\t\t\t}:${ item.order ?? '' }:${ item.lane ?? '' }`\n\t\t)\n\t\t.join( '|' );\n}\n\n/**\n * Placement fingerprint for lanes polyfill / explicit grid positions.\n *\n * @param itemStyles Per-item inline placement styles.\n * @return Fingerprint string.\n */\nexport function getPlacementFingerprint(\n\titemStyles: Map< string, React.CSSProperties >\n): string {\n\treturn [ ...itemStyles.entries() ]\n\t\t.sort( ( [ a ], [ b ] ) => a.localeCompare( b ) )\n\t\t.map( ( [ key, style ] ) => {\n\t\t\tconst column = style.gridColumn ?? '';\n\t\t\tconst columnStart = style.gridColumnStart ?? '';\n\t\t\tconst rowStart = style.gridRowStart ?? '';\n\t\t\tconst rowEnd = style.gridRowEnd ?? '';\n\t\t\treturn `${ key }:${ String( column ) }:${ String(\n\t\t\t\tcolumnStart\n\t\t\t) }:${ String( rowStart ) }:${ String( rowEnd ) }`;\n\t\t} )\n\t\t.join( '|' );\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,273 @@
1
+ // packages/grid/src/dashboard-grid/grid-item.tsx
2
+ import { useSortable } from "@dnd-kit/sortable";
3
+ import clsx from "clsx";
4
+ import { useState, useRef } from "@wordpress/element";
5
+ import { useMergeRefs } from "@wordpress/compose";
6
+
7
+ // packages/style-runtime/src/index.ts
8
+ var STYLE_HASH_ATTRIBUTE = "data-wp-hash";
9
+ function getRuntime() {
10
+ const globalScope = globalThis;
11
+ if (globalScope.__wpStyleRuntime) {
12
+ return globalScope.__wpStyleRuntime;
13
+ }
14
+ globalScope.__wpStyleRuntime = {
15
+ documents: /* @__PURE__ */ new Map(),
16
+ styles: /* @__PURE__ */ new Map(),
17
+ injectedStyles: /* @__PURE__ */ new WeakMap()
18
+ };
19
+ if (typeof document !== "undefined") {
20
+ registerDocument(document);
21
+ }
22
+ return globalScope.__wpStyleRuntime;
23
+ }
24
+ function documentContainsStyleHash(targetDocument, hash) {
25
+ if (!targetDocument.head) {
26
+ return false;
27
+ }
28
+ for (const style of targetDocument.head.querySelectorAll(
29
+ `style[${STYLE_HASH_ATTRIBUTE}]`
30
+ )) {
31
+ if (style.getAttribute(STYLE_HASH_ATTRIBUTE) === hash) {
32
+ return true;
33
+ }
34
+ }
35
+ return false;
36
+ }
37
+ function injectStyle(targetDocument, hash, css) {
38
+ if (!targetDocument.head) {
39
+ return;
40
+ }
41
+ const runtime = getRuntime();
42
+ let injectedStyles = runtime.injectedStyles.get(targetDocument);
43
+ if (!injectedStyles) {
44
+ injectedStyles = /* @__PURE__ */ new Set();
45
+ runtime.injectedStyles.set(targetDocument, injectedStyles);
46
+ }
47
+ if (injectedStyles.has(hash)) {
48
+ return;
49
+ }
50
+ if (documentContainsStyleHash(targetDocument, hash)) {
51
+ injectedStyles.add(hash);
52
+ return;
53
+ }
54
+ const style = targetDocument.createElement("style");
55
+ style.setAttribute(STYLE_HASH_ATTRIBUTE, hash);
56
+ style.appendChild(targetDocument.createTextNode(css));
57
+ targetDocument.head.appendChild(style);
58
+ injectedStyles.add(hash);
59
+ }
60
+ function registerDocument(targetDocument) {
61
+ const runtime = getRuntime();
62
+ runtime.documents.set(
63
+ targetDocument,
64
+ (runtime.documents.get(targetDocument) ?? 0) + 1
65
+ );
66
+ for (const [hash, css] of runtime.styles) {
67
+ injectStyle(targetDocument, hash, css);
68
+ }
69
+ return () => {
70
+ const count = runtime.documents.get(targetDocument);
71
+ if (count === void 0) {
72
+ return;
73
+ }
74
+ if (count <= 1) {
75
+ runtime.documents.delete(targetDocument);
76
+ return;
77
+ }
78
+ runtime.documents.set(targetDocument, count - 1);
79
+ };
80
+ }
81
+ function registerStyle(hash, css) {
82
+ const runtime = getRuntime();
83
+ runtime.styles.set(hash, css);
84
+ for (const targetDocument of runtime.documents.keys()) {
85
+ injectStyle(targetDocument, hash, css);
86
+ }
87
+ }
88
+
89
+ // packages/grid/src/shared/actionable-area-slot.module.css
90
+ if (typeof process === "undefined" || process.env.NODE_ENV !== "test") {
91
+ registerStyle("ac1094954c", "._1c54fe8165d3023e__actionable-area-slot{opacity:1}@media (prefers-reduced-motion:no-preference){._1c54fe8165d3023e__actionable-area-slot{transition:opacity var(--wpds-motion-duration-md,.2s) var(--wpds-motion-easing-subtle,cubic-bezier(.15,0,.15,1))}}[data-wp-grid-resizing] ._1c54fe8165d3023e__actionable-area-slot{opacity:0;pointer-events:none}");
92
+ }
93
+ var actionable_area_slot_default = { "actionable-area-slot": "_1c54fe8165d3023e__actionable-area-slot" };
94
+
95
+ // packages/grid/src/dashboard-grid/grid-item.tsx
96
+ import { GRID_ITEM_DATA_KEY } from "../shared/grid-item-key.mjs";
97
+ import ResizeHandle from "../shared/resize-handle.mjs";
98
+ import { clampResizeDelta } from "../shared/resize-snap.mjs";
99
+
100
+ // packages/grid/src/dashboard-grid/grid-item.module.css
101
+ if (typeof process === "undefined" || process.env.NODE_ENV !== "test") {
102
+ registerStyle("62860ded21", "._5d1abcb332a18701__item{position:relative}._54de57c12d3ce67e__item-content{height:100%;position:relative}._3e086aa073b9bbd9__is-resizing{overflow:visible;z-index:1}._3e086aa073b9bbd9__is-resizing ._54de57c12d3ce67e__item-content{overflow:visible;position:relative;z-index:2}._81d4e1a6c979f1e4__is-dragging{pointer-events:none}[data-wp-grid-dragging] ._81d4e1a6c979f1e4__is-dragging{border-radius:var(--wp-grid-placeholder-radius,0)}@media not (prefers-reduced-motion:reduce){[data-wp-grid-dragging] ._81d4e1a6c979f1e4__is-dragging{animation:_0447be8a7068a873__wp-grid-item-placeholder-in 0ms linear var(--wpds-motion-duration-sm,.1s) forwards;opacity:1;outline-color:transparent;outline-style:var(--wp-grid-placeholder-outline-style,dashed);outline-width:0}@keyframes _0447be8a7068a873__wp-grid-item-placeholder-in{to{opacity:var(--wp-grid-placeholder-opacity,.4);outline-color:var(--wp-grid-placeholder-outline-color,var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9)));outline-width:var(--wpds-border-width-sm,2px)}}}@media (prefers-reduced-motion:reduce){[data-wp-grid-dragging] ._81d4e1a6c979f1e4__is-dragging{opacity:var(--wp-grid-placeholder-opacity,.4);outline:var(--wpds-border-width-sm,2px) var(--wp-grid-placeholder-outline-style,dashed) var(--wp-grid-placeholder-outline-color,var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9)))}}@media (forced-colors:active){[data-wp-grid-dragging] ._81d4e1a6c979f1e4__is-dragging{--wp-grid-placeholder-outline-color:Highlight}}._2028fc095dbc5cb2__preview-overlay{background:transparent;border:var(--wpds-border-width-sm,2px) var(--wp-grid-resize-preview-outline-style,solid) var(--wp-grid-placeholder-outline-color,var(--wpds-color-stroke-interactive-brand,var(--wp-admin-theme-color,#3858e9)));border-radius:var(--wp-grid-placeholder-radius,0);box-sizing:border-box;inset-inline-start:0;pointer-events:none;position:absolute;top:0;z-index:0}@media (forced-colors:active){._2028fc095dbc5cb2__preview-overlay{border-color:Highlight}}");
103
+ }
104
+ var grid_item_default = { "item": "_5d1abcb332a18701__item", "item-content": "_54de57c12d3ce67e__item-content", "is-resizing": "_3e086aa073b9bbd9__is-resizing", "is-dragging": "_81d4e1a6c979f1e4__is-dragging", "wp-grid-item-placeholder-in": "_0447be8a7068a873__wp-grid-item-placeholder-in", "preview-overlay": "_2028fc095dbc5cb2__preview-overlay" };
105
+
106
+ // packages/grid/src/dashboard-grid/grid-item.tsx
107
+ import { jsx, jsxs } from "react/jsx-runtime";
108
+ function getItemCursor(disabled, interacting) {
109
+ if (disabled) {
110
+ return "default";
111
+ }
112
+ if (interacting) {
113
+ return void 0;
114
+ }
115
+ return "grab";
116
+ }
117
+ function GridItem({
118
+ item,
119
+ maxColumns,
120
+ disabled = false,
121
+ verticalResizable = true,
122
+ interacting = false,
123
+ dragging = false,
124
+ children,
125
+ actionableArea = null,
126
+ onResize,
127
+ onResizeEnd,
128
+ resizeSnapPreview = null,
129
+ minResizeWidthPx,
130
+ minResizeHeightPx,
131
+ renderResizeHandle
132
+ }) {
133
+ const [resizeDelta, setResizeDelta] = useState(
134
+ null
135
+ );
136
+ const [initialContentSize, setInitialContentSize] = useState(null);
137
+ const itemRef = useRef(null);
138
+ const contentRef = useRef(null);
139
+ const {
140
+ attributes,
141
+ listeners,
142
+ setNodeRef,
143
+ setActivatorNodeRef,
144
+ isDragging
145
+ } = useSortable({
146
+ id: item.key,
147
+ disabled
148
+ });
149
+ const mergedRef = useMergeRefs([itemRef, setNodeRef]);
150
+ const contentMergedRef = useMergeRefs([contentRef]);
151
+ const style = {
152
+ gridColumnEnd: `span ${item.width === "full" ? maxColumns : Math.min(
153
+ typeof item.width === "number" ? item.width : 1,
154
+ maxColumns
155
+ )}`,
156
+ gridRowEnd: `span ${item.height || 1}`
157
+ };
158
+ const isResizing = resizeDelta !== null;
159
+ const itemClassName = clsx(
160
+ grid_item_default.item,
161
+ isDragging && grid_item_default["is-dragging"],
162
+ isResizing && grid_item_default["is-resizing"]
163
+ );
164
+ const handleResize = (delta) => {
165
+ const contentNode = contentRef.current;
166
+ let baselineSize = initialContentSize;
167
+ if (contentNode && !baselineSize) {
168
+ const { width, height } = contentNode.getBoundingClientRect();
169
+ baselineSize = { width, height };
170
+ setInitialContentSize(baselineSize);
171
+ }
172
+ let clamped = {
173
+ width: delta.width,
174
+ height: verticalResizable ? delta.height : 0
175
+ };
176
+ if (baselineSize) {
177
+ clamped = clampResizeDelta(clamped, baselineSize, {
178
+ width: minResizeWidthPx,
179
+ height: verticalResizable ? minResizeHeightPx : void 0
180
+ });
181
+ }
182
+ setResizeDelta(clamped);
183
+ onResize(item.key, clamped);
184
+ };
185
+ const handleResizeEnd = () => {
186
+ setResizeDelta(null);
187
+ setInitialContentSize(null);
188
+ onResizeEnd();
189
+ };
190
+ const continuousContentStyle = resizeDelta && initialContentSize ? {
191
+ width: initialContentSize.width + resizeDelta.width,
192
+ height: verticalResizable ? initialContentSize.height + resizeDelta.height : void 0
193
+ } : void 0;
194
+ const previewOverlay = resizeSnapPreview ? /* @__PURE__ */ jsx(SnapPreviewOverlay, { snap: resizeSnapPreview }) : null;
195
+ return /* @__PURE__ */ jsxs(
196
+ "div",
197
+ {
198
+ ref: mergedRef,
199
+ className: itemClassName,
200
+ style,
201
+ ...{ [GRID_ITEM_DATA_KEY]: item.key },
202
+ "data-wp-grid-item-resizing": isResizing || void 0,
203
+ children: [
204
+ actionableArea ? /* @__PURE__ */ jsx(
205
+ "div",
206
+ {
207
+ className: actionable_area_slot_default["actionable-area-slot"],
208
+ children: /* @__PURE__ */ jsx(
209
+ "div",
210
+ {
211
+ style: { display: "contents" },
212
+ ...dragging ? { inert: "" } : {},
213
+ children: actionableArea
214
+ }
215
+ )
216
+ }
217
+ ) : null,
218
+ /* @__PURE__ */ jsxs(
219
+ "div",
220
+ {
221
+ ref: setActivatorNodeRef,
222
+ ...attributes,
223
+ ...listeners,
224
+ style: {
225
+ height: "100%",
226
+ cursor: getItemCursor(disabled, interacting)
227
+ },
228
+ children: [
229
+ /* @__PURE__ */ jsxs(
230
+ "div",
231
+ {
232
+ ref: contentMergedRef,
233
+ className: grid_item_default["item-content"],
234
+ style: continuousContentStyle,
235
+ children: [
236
+ children,
237
+ !disabled && /* @__PURE__ */ jsx(
238
+ ResizeHandle,
239
+ {
240
+ itemId: item.key,
241
+ verticalResizable,
242
+ onResize: handleResize,
243
+ onResizeEnd: handleResizeEnd,
244
+ renderResizeHandle
245
+ }
246
+ )
247
+ ]
248
+ }
249
+ ),
250
+ previewOverlay
251
+ ]
252
+ }
253
+ )
254
+ ]
255
+ }
256
+ );
257
+ }
258
+ function SnapPreviewOverlay({ snap }) {
259
+ return /* @__PURE__ */ jsx(
260
+ "div",
261
+ {
262
+ className: grid_item_default["preview-overlay"],
263
+ style: {
264
+ width: snap.widthPx,
265
+ height: snap.heightPx ?? "100%"
266
+ }
267
+ }
268
+ );
269
+ }
270
+ export {
271
+ GridItem
272
+ };
273
+ //# sourceMappingURL=grid-item.mjs.map