@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,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/dashboard-grid/grid-item.tsx", "../../../style-runtime/src/index.ts", "../../src/shared/actionable-area-slot.module.css", "../../src/dashboard-grid/grid-item.module.css"],
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport { useSortable } from '@dnd-kit/sortable';\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport { useState, useRef } from '@wordpress/element';\nimport { useMergeRefs } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport actionableAreaStyles from '../shared/actionable-area-slot.module.css';\nimport { GRID_ITEM_DATA_KEY } from '../shared/grid-item-key';\nimport ResizeHandle from '../shared/resize-handle';\nimport { clampResizeDelta, type ResizeSnapSize } from '../shared/resize-snap';\nimport type { ResizeDelta } from '../shared/types';\nimport type { GridItemProps } from './types';\nimport styles from './grid-item.module.css';\n\nfunction getItemCursor(\n\tdisabled: boolean,\n\tinteracting: boolean\n): React.CSSProperties[ 'cursor' ] {\n\tif ( disabled ) {\n\t\treturn 'default';\n\t}\n\n\tif ( interacting ) {\n\t\treturn undefined;\n\t}\n\n\treturn 'grab';\n}\n\nexport function GridItem( {\n\titem,\n\tmaxColumns,\n\tdisabled = false,\n\tverticalResizable = true,\n\tinteracting = false,\n\tdragging = false,\n\tchildren,\n\tactionableArea = null,\n\tonResize,\n\tonResizeEnd,\n\tresizeSnapPreview = null,\n\tminResizeWidthPx,\n\tminResizeHeightPx,\n\trenderResizeHandle,\n}: GridItemProps ) {\n\tconst [ resizeDelta, setResizeDelta ] = useState< ResizeDelta | null >(\n\t\tnull\n\t);\n\tconst [ initialContentSize, setInitialContentSize ] = useState< {\n\t\twidth: number;\n\t\theight: number;\n\t} | null >( null );\n\tconst itemRef = useRef< HTMLDivElement >( null );\n\tconst contentRef = useRef< HTMLDivElement >( null );\n\tconst {\n\t\tattributes,\n\t\tlisteners,\n\t\tsetNodeRef,\n\t\tsetActivatorNodeRef,\n\t\tisDragging,\n\t} = useSortable( {\n\t\tid: item.key,\n\t\tdisabled,\n\t} );\n\tconst mergedRef = useMergeRefs( [ itemRef, setNodeRef ] );\n\tconst contentMergedRef = useMergeRefs( [ contentRef ] );\n\t/*\n\t * With `<DragOverlay>` handling the cursor-following clone, the\n\t * sortable item stays put in its grid cell and acts as a\n\t * placeholder. No `transform` is applied here — applying one\n\t * would double-move the placeholder alongside the overlay.\n\t */\n\tconst style = {\n\t\tgridColumnEnd: `span ${\n\t\t\titem.width === 'full'\n\t\t\t\t? maxColumns\n\t\t\t\t: Math.min(\n\t\t\t\t\t\ttypeof item.width === 'number' ? item.width : 1,\n\t\t\t\t\t\tmaxColumns\n\t\t\t\t )\n\t\t}`,\n\t\tgridRowEnd: `span ${ item.height || 1 }`,\n\t};\n\n\tconst isResizing = resizeDelta !== null;\n\tconst itemClassName = clsx(\n\t\tstyles.item,\n\t\tisDragging && styles[ 'is-dragging' ],\n\t\tisResizing && styles[ 'is-resizing' ]\n\t);\n\n\tconst handleResize = ( delta: ResizeDelta ) => {\n\t\tconst contentNode = contentRef.current;\n\t\tlet baselineSize = initialContentSize;\n\t\tif ( contentNode && ! baselineSize ) {\n\t\t\tconst { width, height } = contentNode.getBoundingClientRect();\n\t\t\tbaselineSize = { width, height };\n\t\t\tsetInitialContentSize( baselineSize );\n\t\t}\n\t\tlet clamped: ResizeDelta = {\n\t\t\twidth: delta.width,\n\t\t\theight: verticalResizable ? delta.height : 0,\n\t\t};\n\t\tif ( baselineSize ) {\n\t\t\tclamped = clampResizeDelta( clamped, baselineSize, {\n\t\t\t\twidth: minResizeWidthPx,\n\t\t\t\theight: verticalResizable ? minResizeHeightPx : undefined,\n\t\t\t} );\n\t\t}\n\t\tsetResizeDelta( clamped );\n\t\tonResize( item.key, clamped );\n\t};\n\n\tconst handleResizeEnd = () => {\n\t\tsetResizeDelta( null );\n\t\tsetInitialContentSize( null );\n\t\tonResizeEnd();\n\t};\n\n\tconst continuousContentStyle: React.CSSProperties | undefined =\n\t\tresizeDelta && initialContentSize\n\t\t\t? {\n\t\t\t\t\twidth: initialContentSize.width + resizeDelta.width,\n\t\t\t\t\theight: verticalResizable\n\t\t\t\t\t\t? initialContentSize.height + resizeDelta.height\n\t\t\t\t\t\t: undefined,\n\t\t\t }\n\t\t\t: undefined;\n\n\tconst previewOverlay = resizeSnapPreview ? (\n\t\t<SnapPreviewOverlay snap={ resizeSnapPreview } />\n\t) : null;\n\n\treturn (\n\t\t<div\n\t\t\tref={ mergedRef }\n\t\t\tclassName={ itemClassName }\n\t\t\tstyle={ style }\n\t\t\t{ ...{ [ GRID_ITEM_DATA_KEY ]: item.key } }\n\t\t\tdata-wp-grid-item-resizing={ isResizing || undefined }\n\t\t>\n\t\t\t{ actionableArea ? (\n\t\t\t\t<div\n\t\t\t\t\tclassName={ actionableAreaStyles[ 'actionable-area-slot' ] }\n\t\t\t\t>\n\t\t\t\t\t<div\n\t\t\t\t\t\tstyle={ { display: 'contents' } }\n\t\t\t\t\t\t{ ...( dragging ? { inert: '' } : {} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ actionableArea }\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t) : null }\n\n\t\t\t<div\n\t\t\t\tref={ setActivatorNodeRef }\n\t\t\t\t{ ...attributes }\n\t\t\t\t{ ...listeners }\n\t\t\t\tstyle={ {\n\t\t\t\t\theight: '100%',\n\t\t\t\t\tcursor: getItemCursor( disabled, interacting ),\n\t\t\t\t} }\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tref={ contentMergedRef }\n\t\t\t\t\tclassName={ styles[ 'item-content' ] }\n\t\t\t\t\tstyle={ continuousContentStyle }\n\t\t\t\t>\n\t\t\t\t\t{ children }\n\t\t\t\t\t{ ! disabled && (\n\t\t\t\t\t\t<ResizeHandle\n\t\t\t\t\t\t\titemId={ item.key }\n\t\t\t\t\t\t\tverticalResizable={ verticalResizable }\n\t\t\t\t\t\t\tonResize={ handleResize }\n\t\t\t\t\t\t\tonResizeEnd={ handleResizeEnd }\n\t\t\t\t\t\t\trenderResizeHandle={ renderResizeHandle }\n\t\t\t\t\t\t/>\n\t\t\t\t\t) }\n\t\t\t\t</div>\n\t\t\t\t{ previewOverlay }\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n\nfunction SnapPreviewOverlay( { snap }: { snap: ResizeSnapSize } ) {\n\treturn (\n\t\t<div\n\t\t\tclassName={ styles[ 'preview-overlay' ] }\n\t\t\tstyle={ {\n\t\t\t\twidth: snap.widthPx,\n\t\t\t\theight: snap.heightPx ?? '100%',\n\t\t\t} }\n\t\t/>\n\t);\n}\n", "type GlobalScopeWithStyleRuntime = typeof globalThis & {\n\t// This global is shared by separately bundled copies of this package.\n\t// Keep its shape backward compatible after release.\n\t__wpStyleRuntime?: {\n\t\tdocuments: Map< Document, number >;\n\t\tstyles: Map< string, string >;\n\t\tinjectedStyles: WeakMap< Document, Set< string > >;\n\t};\n};\n\nconst STYLE_HASH_ATTRIBUTE = 'data-wp-hash';\n\n/**\n * Returns the shared style runtime registry.\n *\n * The registry is stored on `globalThis` so separately bundled copies of this\n * package can coordinate through the same document and style maps.\n *\n * @return The shared runtime registry.\n */\nfunction getRuntime() {\n\tconst globalScope = globalThis as GlobalScopeWithStyleRuntime;\n\n\tif ( globalScope.__wpStyleRuntime ) {\n\t\treturn globalScope.__wpStyleRuntime;\n\t}\n\n\tglobalScope.__wpStyleRuntime = {\n\t\tdocuments: new Map(),\n\t\tstyles: new Map(),\n\t\tinjectedStyles: new WeakMap(),\n\t};\n\n\tif ( typeof document !== 'undefined' ) {\n\t\tregisterDocument( document );\n\t}\n\n\treturn globalScope.__wpStyleRuntime;\n}\n\n/**\n * Checks whether a document already contains a style tag for a hash.\n *\n * @param targetDocument Document to inspect.\n * @param hash Stable hash for the transformed CSS.\n *\n * @return Whether the style hash already exists in the document.\n */\nfunction documentContainsStyleHash(\n\ttargetDocument: Document,\n\thash: string\n): boolean {\n\tif ( ! targetDocument.head ) {\n\t\treturn false;\n\t}\n\n\tfor ( const style of targetDocument.head.querySelectorAll(\n\t\t`style[${ STYLE_HASH_ATTRIBUTE }]`\n\t) ) {\n\t\tif ( style.getAttribute( STYLE_HASH_ATTRIBUTE ) === hash ) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Injects a registered style into a document, unless that document already\n * contains a style tag for the same hash.\n *\n * @param targetDocument Document to inject the style into.\n * @param hash Stable hash for the transformed CSS.\n * @param css CSS text to inject.\n */\nfunction injectStyle( targetDocument: Document, hash: string, css: string ) {\n\tif ( ! targetDocument.head ) {\n\t\treturn;\n\t}\n\n\tconst runtime = getRuntime();\n\tlet injectedStyles = runtime.injectedStyles.get( targetDocument );\n\n\tif ( ! injectedStyles ) {\n\t\tinjectedStyles = new Set();\n\t\truntime.injectedStyles.set( targetDocument, injectedStyles );\n\t}\n\n\tif ( injectedStyles.has( hash ) ) {\n\t\treturn;\n\t}\n\n\t// Older generated CSS module output can still inject matching style tags\n\t// after this document's cache is created, so keep the DOM as the fallback\n\t// source of truth on cache misses.\n\tif ( documentContainsStyleHash( targetDocument, hash ) ) {\n\t\tinjectedStyles.add( hash );\n\t\treturn;\n\t}\n\n\tconst style = targetDocument.createElement( 'style' );\n\tstyle.setAttribute( STYLE_HASH_ATTRIBUTE, hash );\n\tstyle.appendChild( targetDocument.createTextNode( css ) );\n\ttargetDocument.head.appendChild( style );\n\tinjectedStyles.add( hash );\n}\n\n/**\n * Registers a document as a style injection target.\n *\n * Existing registered styles are replayed into the document immediately.\n * Documents are reference-counted so multiple providers can safely register the\n * same document without one cleanup removing it while another registration is\n * still active.\n *\n * @param targetDocument Document to receive registered styles.\n * @return Cleanup function that unregisters this document registration.\n */\nexport function registerDocument( targetDocument: Document ) {\n\tconst runtime = getRuntime();\n\n\truntime.documents.set(\n\t\ttargetDocument,\n\t\t( runtime.documents.get( targetDocument ) ?? 0 ) + 1\n\t);\n\n\tfor ( const [ hash, css ] of runtime.styles ) {\n\t\tinjectStyle( targetDocument, hash, css );\n\t}\n\n\treturn () => {\n\t\tconst count = runtime.documents.get( targetDocument );\n\n\t\tif ( count === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( count <= 1 ) {\n\t\t\truntime.documents.delete( targetDocument );\n\t\t\treturn;\n\t\t}\n\n\t\truntime.documents.set( targetDocument, count - 1 );\n\t};\n}\n\n/**\n * Registers a style and injects it into all registered documents.\n *\n * The hash is used as the deduplication key, so calling this repeatedly with\n * the same hash will not add duplicate style tags to a document.\n * Registered styles are retained for the lifetime of the page so they can be\n * replayed into documents that are registered later.\n *\n * @param hash Stable hash for the transformed CSS.\n * @param css CSS text to inject.\n */\nexport function registerStyle( hash: string, css: string ) {\n\tconst runtime = getRuntime();\n\n\truntime.styles.set( hash, css );\n\n\tfor ( const targetDocument of runtime.documents.keys() ) {\n\t\tinjectStyle( targetDocument, hash, css );\n\t}\n}\n", "import { registerStyle } from '@wordpress/style-runtime';\nif (typeof process === 'undefined' || process.env.NODE_ENV !== 'test') {\n\tregisterStyle(\"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}\");\n}\nexport default {\"actionable-area-slot\":\"_1c54fe8165d3023e__actionable-area-slot\"};\n", "import { registerStyle } from '@wordpress/style-runtime';\nif (typeof process === 'undefined' || process.env.NODE_ENV !== 'test') {\n\tregisterStyle(\"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}}\");\n}\nexport 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\"};\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,579 @@
1
+ // packages/grid/src/dashboard-grid/index.tsx
2
+ import {
3
+ DndContext,
4
+ DragOverlay,
5
+ KeyboardSensor,
6
+ PointerSensor,
7
+ useSensor,
8
+ useSensors
9
+ } from "@dnd-kit/core";
10
+ import {
11
+ arrayMove,
12
+ SortableContext,
13
+ sortableKeyboardCoordinates
14
+ } from "@dnd-kit/sortable";
15
+ import clsx from "clsx";
16
+ import { useResizeObserver, useEvent, useMergeRefs } from "@wordpress/compose";
17
+ import {
18
+ forwardRef,
19
+ useMemo,
20
+ Children,
21
+ cloneElement,
22
+ isValidElement,
23
+ useLayoutEffect,
24
+ useRef,
25
+ useState
26
+ } from "@wordpress/element";
27
+ import { GridItem } from "./grid-item.mjs";
28
+ import { GridOverlay } from "../shared/grid-overlay.mjs";
29
+ import { gridSpanToPixelSize } from "../shared/resize-snap.mjs";
30
+
31
+ // packages/style-runtime/src/index.ts
32
+ var STYLE_HASH_ATTRIBUTE = "data-wp-hash";
33
+ function getRuntime() {
34
+ const globalScope = globalThis;
35
+ if (globalScope.__wpStyleRuntime) {
36
+ return globalScope.__wpStyleRuntime;
37
+ }
38
+ globalScope.__wpStyleRuntime = {
39
+ documents: /* @__PURE__ */ new Map(),
40
+ styles: /* @__PURE__ */ new Map(),
41
+ injectedStyles: /* @__PURE__ */ new WeakMap()
42
+ };
43
+ if (typeof document !== "undefined") {
44
+ registerDocument(document);
45
+ }
46
+ return globalScope.__wpStyleRuntime;
47
+ }
48
+ function documentContainsStyleHash(targetDocument, hash) {
49
+ if (!targetDocument.head) {
50
+ return false;
51
+ }
52
+ for (const style of targetDocument.head.querySelectorAll(
53
+ `style[${STYLE_HASH_ATTRIBUTE}]`
54
+ )) {
55
+ if (style.getAttribute(STYLE_HASH_ATTRIBUTE) === hash) {
56
+ return true;
57
+ }
58
+ }
59
+ return false;
60
+ }
61
+ function injectStyle(targetDocument, hash, css) {
62
+ if (!targetDocument.head) {
63
+ return;
64
+ }
65
+ const runtime = getRuntime();
66
+ let injectedStyles = runtime.injectedStyles.get(targetDocument);
67
+ if (!injectedStyles) {
68
+ injectedStyles = /* @__PURE__ */ new Set();
69
+ runtime.injectedStyles.set(targetDocument, injectedStyles);
70
+ }
71
+ if (injectedStyles.has(hash)) {
72
+ return;
73
+ }
74
+ if (documentContainsStyleHash(targetDocument, hash)) {
75
+ injectedStyles.add(hash);
76
+ return;
77
+ }
78
+ const style = targetDocument.createElement("style");
79
+ style.setAttribute(STYLE_HASH_ATTRIBUTE, hash);
80
+ style.appendChild(targetDocument.createTextNode(css));
81
+ targetDocument.head.appendChild(style);
82
+ injectedStyles.add(hash);
83
+ }
84
+ function registerDocument(targetDocument) {
85
+ const runtime = getRuntime();
86
+ runtime.documents.set(
87
+ targetDocument,
88
+ (runtime.documents.get(targetDocument) ?? 0) + 1
89
+ );
90
+ for (const [hash, css] of runtime.styles) {
91
+ injectStyle(targetDocument, hash, css);
92
+ }
93
+ return () => {
94
+ const count = runtime.documents.get(targetDocument);
95
+ if (count === void 0) {
96
+ return;
97
+ }
98
+ if (count <= 1) {
99
+ runtime.documents.delete(targetDocument);
100
+ return;
101
+ }
102
+ runtime.documents.set(targetDocument, count - 1);
103
+ };
104
+ }
105
+ function registerStyle(hash, css) {
106
+ const runtime = getRuntime();
107
+ runtime.styles.set(hash, css);
108
+ for (const targetDocument of runtime.documents.keys()) {
109
+ injectStyle(targetDocument, hash, css);
110
+ }
111
+ }
112
+
113
+ // packages/grid/src/shared/layout-shift-animation.module.css
114
+ if (typeof process === "undefined" || process.env.NODE_ENV !== "test") {
115
+ registerStyle("9e5573e51f", "._2db63116caa90ae9__layout-animating [data-wp-grid-item-key]{transition:transform var(--wpds-motion-duration-md,.2s) var(--wpds-motion-easing-balanced,cubic-bezier(.4,0,.2,1))}@media (prefers-reduced-motion:reduce){._2db63116caa90ae9__layout-animating [data-wp-grid-item-key]{transition:none}}");
116
+ }
117
+ var layout_shift_animation_default = { "layout-animating": "_2db63116caa90ae9__layout-animating" };
118
+
119
+ // packages/grid/src/dashboard-grid/index.tsx
120
+ import { ItemExitOverlay } from "../shared/item-exit-overlay.mjs";
121
+ import {
122
+ getLayoutFingerprint,
123
+ useLayoutShiftAnimation
124
+ } from "../shared/use-layout-shift-animation.mjs";
125
+ import { useItemExitAnimation } from "../shared/use-item-exit-animation.mjs";
126
+ import { resolveFillWidths } from "./resolve-fill-widths.mjs";
127
+ import { createDashboardDragDropAnimation } from "../shared/drag-overlay-drop-animation.mjs";
128
+
129
+ // packages/grid/src/dashboard-grid/grid.module.css
130
+ if (typeof process === "undefined" || process.env.NODE_ENV !== "test") {
131
+ registerStyle("52d51e7d5c", "._960c435c33759f46__grid{display:grid;gap:var(--wp-grid-gap,var(--wpds-dimension-gap-xl,24px));position:relative}._48e8cd4225dcb813__drag-preview-frame{border-radius:var(--wp-grid-drag-preview-radius,0);box-shadow:var(--wpds-elevation-md,0 2px 3px 0 #0000000d,0 4px 5px 0 #0000000a,0 12px 12px 0 #00000008,0 16px 16px 0 #00000005);cursor:grabbing;height:100%;pointer-events:none}._4b471bf24f891d2d__drag-preview-frame__lift{height:100%;transform:scale(var(--wp-grid-drag-preview-scale,1.05));transform-origin:center}@media not (prefers-reduced-motion:reduce){._48e8cd4225dcb813__drag-preview-frame{animation:_08fdf90ef86c4706__wp-grid-drag-preview-shadow-enter var(--wpds-motion-duration-sm,.1s) var(--wpds-motion-easing-balanced,cubic-bezier(.4,0,.2,1)) both}._4b471bf24f891d2d__drag-preview-frame__lift{animation:_8aaeb335436989f9__wp-grid-drag-preview-scale-enter var(--wpds-motion-duration-sm,.1s) var(--wpds-motion-easing-balanced,cubic-bezier(.4,0,.2,1)) both}}@media not (prefers-reduced-motion:reduce){@keyframes _08fdf90ef86c4706__wp-grid-drag-preview-shadow-enter{0%{box-shadow:var(--wpds-elevation-xs,0 1px 1px 0 #00000008,0 1px 2px 0 #00000005,0 3px 3px 0 #00000005,0 4px 4px 0 #00000003)}to{box-shadow:var(--wpds-elevation-md,0 2px 3px 0 #0000000d,0 4px 5px 0 #0000000a,0 12px 12px 0 #00000008,0 16px 16px 0 #00000005)}}@keyframes _8aaeb335436989f9__wp-grid-drag-preview-scale-enter{0%{transform:scale(1)}to{transform:scale(var(--wp-grid-drag-preview-scale,1.05))}}}@media not (prefers-reduced-motion:reduce){._48e8cd4225dcb813__drag-preview-frame._66b0aefb2bc02eb9__dragPreviewFrameExiting{animation:a7ead84bfd25ff8a__wp-grid-drag-preview-shadow-exit var(--wpds-motion-duration-md,.2s) var(--wpds-motion-easing-balanced,cubic-bezier(.4,0,.2,1)) forwards}._48e8cd4225dcb813__drag-preview-frame._66b0aefb2bc02eb9__dragPreviewFrameExiting ._4b471bf24f891d2d__drag-preview-frame__lift{animation:_234ccad5c20d49f8__wp-grid-drag-preview-scale-exit var(--wpds-motion-duration-md,.2s) var(--wpds-motion-easing-balanced,cubic-bezier(.4,0,.2,1)) forwards}@keyframes a7ead84bfd25ff8a__wp-grid-drag-preview-shadow-exit{0%{box-shadow:var(--wpds-elevation-md,0 2px 3px 0 #0000000d,0 4px 5px 0 #0000000a,0 12px 12px 0 #00000008,0 16px 16px 0 #00000005)}to{box-shadow:var(--wpds-elevation-xs,0 1px 1px 0 #00000008,0 1px 2px 0 #00000005,0 3px 3px 0 #00000005,0 4px 4px 0 #00000003)}}@keyframes _234ccad5c20d49f8__wp-grid-drag-preview-scale-exit{0%{transform:scale(var(--wp-grid-drag-preview-scale,1.05))}to{transform:scale(1)}}}._48e8cd4225dcb813__drag-preview-frame._66b0aefb2bc02eb9__dragPreviewFrameExiting{box-shadow:var(--wpds-elevation-xs,0 1px 1px 0 #00000008,0 1px 2px 0 #00000005,0 3px 3px 0 #00000005,0 4px 4px 0 #00000003)}._48e8cd4225dcb813__drag-preview-frame._66b0aefb2bc02eb9__dragPreviewFrameExiting ._4b471bf24f891d2d__drag-preview-frame__lift{transform:scale(1)}@media (prefers-reduced-motion:reduce){._48e8cd4225dcb813__drag-preview-frame{box-shadow:var(--wpds-elevation-md,0 2px 3px 0 #0000000d,0 4px 5px 0 #0000000a,0 12px 12px 0 #00000008,0 16px 16px 0 #00000005)}._4b471bf24f891d2d__drag-preview-frame__lift{transform:none}._48e8cd4225dcb813__drag-preview-frame._66b0aefb2bc02eb9__dragPreviewFrameExiting{box-shadow:var(--wpds-elevation-xs,0 1px 1px 0 #00000008,0 1px 2px 0 #00000005,0 3px 3px 0 #00000005,0 4px 4px 0 #00000003);transition:none}._48e8cd4225dcb813__drag-preview-frame._66b0aefb2bc02eb9__dragPreviewFrameExiting ._4b471bf24f891d2d__drag-preview-frame__lift{transition:none}}");
132
+ }
133
+ var grid_default = { "grid": "_960c435c33759f46__grid", "drag-preview-frame": "_48e8cd4225dcb813__drag-preview-frame", "drag-preview-frame__lift": "_4b471bf24f891d2d__drag-preview-frame__lift", "wp-grid-drag-preview-shadow-enter": "_08fdf90ef86c4706__wp-grid-drag-preview-shadow-enter", "wp-grid-drag-preview-scale-enter": "_8aaeb335436989f9__wp-grid-drag-preview-scale-enter", "dragPreviewFrameExiting": "_66b0aefb2bc02eb9__dragPreviewFrameExiting", "wp-grid-drag-preview-shadow-exit": "a7ead84bfd25ff8a__wp-grid-drag-preview-shadow-exit", "wp-grid-drag-preview-scale-exit": "_234ccad5c20d49f8__wp-grid-drag-preview-scale-exit" };
134
+
135
+ // packages/grid/src/dashboard-grid/index.tsx
136
+ import { jsx, jsxs } from "react/jsx-runtime";
137
+ var dashboardDragDropAnimation = createDashboardDragDropAnimation(
138
+ grid_default["drag-preview-frame"],
139
+ grid_default.dragPreviewFrameExiting
140
+ );
141
+ var FALLBACK_GAP_PX = 24;
142
+ var DEFAULT_COLUMNS = 6;
143
+ var NO_SORT_STRATEGY = () => null;
144
+ var DashboardGrid = forwardRef(
145
+ function DashboardGrid2(props, ref) {
146
+ const {
147
+ layout,
148
+ columns,
149
+ children,
150
+ className,
151
+ style,
152
+ rowHeight = "auto",
153
+ minColumnWidth,
154
+ editMode = false,
155
+ onChangeLayout,
156
+ onPreviewLayout,
157
+ renderResizeHandle,
158
+ renderDragPreview,
159
+ renderGridOverlay,
160
+ ...divProps
161
+ } = props;
162
+ const [temporaryLayout, setTemporaryLayout] = useState();
163
+ const [activeId, setActiveId] = useState(null);
164
+ const [isResizing, setIsResizing] = useState(false);
165
+ const [resizeSnapPreview, setResizeSnapPreview] = useState(null);
166
+ const latestLayoutRef = useRef();
167
+ const lastReorderCursorRef = useRef(null);
168
+ const resizeBaselineRef = useRef(null);
169
+ const captureLayoutSnapshotRef = useRef(() => {
170
+ });
171
+ const childrenCacheRef = useRef(
172
+ /* @__PURE__ */ new Map()
173
+ );
174
+ const activeLayout = temporaryLayout ?? layout;
175
+ const [gridRoot, setGridRoot] = useState(
176
+ null
177
+ );
178
+ const [containerWidth, setContainerWidth] = useState(0);
179
+ const [containerHeight, setContainerHeight] = useState(0);
180
+ const [gapPx, setGapPx] = useState(FALLBACK_GAP_PX);
181
+ const resizeObserverRef = useResizeObserver(
182
+ ([{ contentRect }]) => {
183
+ setContainerWidth(contentRect.width);
184
+ setContainerHeight(contentRect.height);
185
+ }
186
+ );
187
+ const mergedGridRef = useMergeRefs([
188
+ setGridRoot,
189
+ resizeObserverRef,
190
+ ref
191
+ ]);
192
+ useLayoutEffect(() => {
193
+ if (!gridRoot) {
194
+ return;
195
+ }
196
+ const { width, height } = gridRoot.getBoundingClientRect();
197
+ if (width > 0) {
198
+ setContainerWidth(width);
199
+ }
200
+ if (height > 0) {
201
+ setContainerHeight(height);
202
+ }
203
+ const parsed = Number.parseFloat(
204
+ window.getComputedStyle(gridRoot).columnGap
205
+ );
206
+ if (Number.isFinite(parsed) && parsed > 0) {
207
+ setGapPx(parsed);
208
+ }
209
+ }, [gridRoot]);
210
+ const effectiveColumns = useMemo(() => {
211
+ if (!minColumnWidth) {
212
+ return columns ?? DEFAULT_COLUMNS;
213
+ }
214
+ const totalWidthPerColumn = minColumnWidth + gapPx;
215
+ const maxFit = Math.max(
216
+ 1,
217
+ Math.floor((containerWidth + gapPx) / totalWidthPerColumn)
218
+ );
219
+ return columns !== void 0 ? Math.min(columns, maxFit) : maxFit;
220
+ }, [minColumnWidth, gapPx, containerWidth, columns]);
221
+ const columnWidth = (containerWidth - (effectiveColumns - 1) * gapPx) / effectiveColumns;
222
+ const minResizeWidthPx = gridSpanToPixelSize(
223
+ 1,
224
+ 1,
225
+ columnWidth,
226
+ gapPx,
227
+ null
228
+ ).widthPx;
229
+ const rowHeightPx = typeof rowHeight === "number" ? rowHeight : null;
230
+ const minResizeHeightPx = rowHeightPx === null ? void 0 : gridSpanToPixelSize(1, 1, columnWidth, gapPx, rowHeightPx).heightPx ?? void 0;
231
+ const layoutMap = useMemo(() => {
232
+ const map = /* @__PURE__ */ new Map();
233
+ activeLayout.forEach((item) => map.set(item.key, item));
234
+ return map;
235
+ }, [activeLayout]);
236
+ const layoutKeys = useMemo(
237
+ () => new Set(layout.map((item) => item.key)),
238
+ [layout]
239
+ );
240
+ const sortedItems = useMemo(
241
+ () => activeLayout.map((item, index) => ({ item, index })).sort(
242
+ (a, b) => (a.item.order ?? a.index) - (b.item.order ?? b.index)
243
+ ).map(({ item }) => item.key),
244
+ [activeLayout]
245
+ );
246
+ const items = sortedItems;
247
+ const resolvedItemMap = useMemo(() => {
248
+ const fillWidths = resolveFillWidths(
249
+ items,
250
+ layoutMap,
251
+ effectiveColumns
252
+ );
253
+ if (fillWidths.size === 0) {
254
+ return layoutMap;
255
+ }
256
+ const map = /* @__PURE__ */ new Map();
257
+ for (const [key, item] of layoutMap) {
258
+ const fillW = fillWidths.get(key);
259
+ map.set(
260
+ key,
261
+ fillW !== void 0 ? { ...item, width: fillW } : item
262
+ );
263
+ }
264
+ return map;
265
+ }, [items, layoutMap, effectiveColumns]);
266
+ const [childrenMap, actionableAreaMap, remaining, renderedByKey] = useMemo(() => {
267
+ const childMap = /* @__PURE__ */ new Map();
268
+ const actionableMap = /* @__PURE__ */ new Map();
269
+ const rest = [];
270
+ const byKey = /* @__PURE__ */ new Map();
271
+ Children.forEach(children, (child) => {
272
+ if (!isValidElement(child)) {
273
+ rest.push(child);
274
+ return;
275
+ }
276
+ const key = child.key?.toString();
277
+ if (!key) {
278
+ rest.push(child);
279
+ return;
280
+ }
281
+ const { actionableArea } = child.props;
282
+ const stripped = actionableArea !== void 0 ? cloneElement(child, {
283
+ actionableArea: void 0
284
+ }) : child;
285
+ byKey.set(key, stripped);
286
+ if (layoutKeys.has(key)) {
287
+ if (actionableArea !== void 0) {
288
+ actionableMap.set(key, actionableArea);
289
+ }
290
+ childMap.set(key, stripped);
291
+ } else {
292
+ rest.push(child);
293
+ }
294
+ });
295
+ return [childMap, actionableMap, rest, byKey];
296
+ }, [children, layoutKeys]);
297
+ useLayoutEffect(() => {
298
+ for (const [key, child] of renderedByKey) {
299
+ childrenCacheRef.current.set(key, child);
300
+ }
301
+ }, [renderedByKey]);
302
+ const sensors = useSensors(
303
+ useSensor(PointerSensor),
304
+ useSensor(KeyboardSensor, {
305
+ coordinateGetter: sortableKeyboardCoordinates
306
+ })
307
+ );
308
+ const handleDragStart = useEvent((event) => {
309
+ setActiveId(String(event.active.id));
310
+ lastReorderCursorRef.current = null;
311
+ });
312
+ const handleDragCancel = useEvent(() => {
313
+ setActiveId(null);
314
+ latestLayoutRef.current = void 0;
315
+ lastReorderCursorRef.current = null;
316
+ resizeBaselineRef.current = null;
317
+ setIsResizing(false);
318
+ setResizeSnapPreview(null);
319
+ setTemporaryLayout(void 0);
320
+ });
321
+ const handleDragMove = useEvent((event) => {
322
+ const { active, over } = event;
323
+ if (!over || active.id === over.id) {
324
+ return;
325
+ }
326
+ const activeRect = active.rect.current.translated;
327
+ if (!activeRect) {
328
+ return;
329
+ }
330
+ const activeCenterX = activeRect.left + activeRect.width / 2;
331
+ const activeCenterY = activeRect.top + activeRect.height / 2;
332
+ const lastCursor = lastReorderCursorRef.current;
333
+ if (lastCursor) {
334
+ const dx = activeCenterX - lastCursor.x;
335
+ const dy = activeCenterY - lastCursor.y;
336
+ if (dx * dx + dy * dy < 100) {
337
+ return;
338
+ }
339
+ }
340
+ const overCenterX = over.rect.left + over.rect.width / 2;
341
+ const insertAfter = activeCenterX > overCenterX;
342
+ const currentIndex = items.indexOf(String(active.id));
343
+ const overIndex = items.indexOf(String(over.id));
344
+ let newIndex;
345
+ if (insertAfter) {
346
+ newIndex = currentIndex > overIndex ? overIndex + 1 : overIndex;
347
+ } else {
348
+ newIndex = currentIndex > overIndex ? overIndex : overIndex - 1;
349
+ }
350
+ newIndex = Math.max(0, Math.min(newIndex, items.length - 1));
351
+ if (newIndex === currentIndex) {
352
+ return;
353
+ }
354
+ const updatedItems = arrayMove(items, currentIndex, newIndex);
355
+ const updatedLayout = activeLayout.map((item) => ({
356
+ ...item,
357
+ order: updatedItems.indexOf(item.key)
358
+ }));
359
+ lastReorderCursorRef.current = {
360
+ x: activeCenterX,
361
+ y: activeCenterY
362
+ };
363
+ latestLayoutRef.current = updatedLayout;
364
+ captureLayoutSnapshotRef.current();
365
+ setTemporaryLayout(updatedLayout);
366
+ onPreviewLayout?.(updatedLayout);
367
+ });
368
+ const persistTemporaryLayout = useEvent(() => {
369
+ const latest = latestLayoutRef.current;
370
+ latestLayoutRef.current = void 0;
371
+ resizeBaselineRef.current = null;
372
+ setIsResizing(false);
373
+ setResizeSnapPreview(null);
374
+ if (!onChangeLayout || !latest) {
375
+ setTemporaryLayout(void 0);
376
+ return;
377
+ }
378
+ onChangeLayout(latest);
379
+ setTemporaryLayout(void 0);
380
+ });
381
+ const handleResize = useEvent((id, delta) => {
382
+ if (!editMode) {
383
+ return;
384
+ }
385
+ if (!isResizing) {
386
+ setIsResizing(true);
387
+ }
388
+ const relativeDelta = {
389
+ width: Math.round(delta.width / (columnWidth + gapPx)),
390
+ height: rowHeight === "auto" ? 0 : Math.round(delta.height / (rowHeight + gapPx))
391
+ };
392
+ if (!resizeBaselineRef.current) {
393
+ const baseItem = activeLayout.find(
394
+ (item) => item.key === id
395
+ );
396
+ const resolvedItem = resolvedItemMap.get(id);
397
+ let baseWidth;
398
+ if (baseItem?.width === "full") {
399
+ baseWidth = effectiveColumns;
400
+ } else if (baseItem?.width === "fill") {
401
+ baseWidth = typeof resolvedItem?.width === "number" ? resolvedItem.width : 1;
402
+ } else {
403
+ baseWidth = baseItem?.width ?? 1;
404
+ }
405
+ resizeBaselineRef.current = {
406
+ width: baseWidth,
407
+ height: baseItem?.height ?? 1
408
+ };
409
+ }
410
+ const baseline = resizeBaselineRef.current;
411
+ const newWidth = Math.max(
412
+ 1,
413
+ Math.min(
414
+ baseline.width + relativeDelta.width,
415
+ effectiveColumns
416
+ )
417
+ );
418
+ const newHeight = Math.max(
419
+ 1,
420
+ baseline.height + relativeDelta.height
421
+ );
422
+ setResizeSnapPreview({
423
+ id,
424
+ snap: gridSpanToPixelSize(
425
+ newWidth,
426
+ newHeight,
427
+ columnWidth,
428
+ gapPx,
429
+ rowHeightPx
430
+ )
431
+ });
432
+ const pendingItem = latestLayoutRef.current?.find(
433
+ (item) => item.key === id
434
+ );
435
+ const currentItem = pendingItem ?? activeLayout.find((item) => item.key === id);
436
+ if (currentItem && currentItem.width === newWidth && (currentItem.height ?? 1) === newHeight) {
437
+ return;
438
+ }
439
+ const updatedLayout = activeLayout.map(
440
+ (item) => item.key === id ? { ...item, width: newWidth, height: newHeight } : item
441
+ );
442
+ latestLayoutRef.current = updatedLayout;
443
+ captureLayoutSnapshotRef.current();
444
+ setTemporaryLayout(updatedLayout);
445
+ onPreviewLayout?.(updatedLayout);
446
+ });
447
+ const activeClone = activeId ? childrenMap.get(activeId) : null;
448
+ const DragPreview = renderDragPreview;
449
+ const dragOverlayContent = activeId && activeClone ? /* @__PURE__ */ jsx("div", { className: grid_default["drag-preview-frame"], children: /* @__PURE__ */ jsx("div", { className: grid_default["drag-preview-frame__lift"], children: DragPreview ? /* @__PURE__ */ jsx(DragPreview, { itemId: activeId, children: activeClone }) : activeClone }) }) : null;
450
+ const Overlay = renderGridOverlay ?? GridOverlay;
451
+ const overlayRowHeight = typeof rowHeight === "number" ? rowHeight : void 0;
452
+ const overlayRows = useMemo(() => {
453
+ if (overlayRowHeight === void 0 || containerHeight <= 0) {
454
+ return void 0;
455
+ }
456
+ const rowTile = overlayRowHeight + gapPx;
457
+ return Math.max(
458
+ 1,
459
+ Math.floor((containerHeight + gapPx) / rowTile)
460
+ );
461
+ }, [overlayRowHeight, containerHeight, gapPx]);
462
+ const gridOverlay = useMemo(
463
+ () => /* @__PURE__ */ jsx(
464
+ Overlay,
465
+ {
466
+ columns: effectiveColumns,
467
+ rowHeight: overlayRowHeight,
468
+ rows: overlayRows,
469
+ isActive: editMode
470
+ }
471
+ ),
472
+ [
473
+ Overlay,
474
+ editMode,
475
+ effectiveColumns,
476
+ overlayRowHeight,
477
+ overlayRows
478
+ ]
479
+ );
480
+ const layoutFingerprint = useMemo(
481
+ () => getLayoutFingerprint([...resolvedItemMap.values()]),
482
+ [resolvedItemMap]
483
+ );
484
+ const excludeLayoutAnimationKey = activeId ?? (isResizing ? resizeSnapPreview?.id : null);
485
+ const { captureLayoutSnapshot, getPositionsBeforeLastChange } = useLayoutShiftAnimation({
486
+ container: gridRoot,
487
+ enabled: editMode,
488
+ layoutFingerprint,
489
+ excludeItemKey: excludeLayoutAnimationKey
490
+ });
491
+ const { exitingItems, clearExitingItem } = useItemExitAnimation({
492
+ container: gridRoot,
493
+ enabled: editMode,
494
+ layoutKeys,
495
+ getPositionsBeforeLastChange,
496
+ childrenCacheRef
497
+ });
498
+ const layoutAnimating = editMode;
499
+ useLayoutEffect(() => {
500
+ captureLayoutSnapshotRef.current = captureLayoutSnapshot;
501
+ }, [captureLayoutSnapshot]);
502
+ return /* @__PURE__ */ jsxs(
503
+ DndContext,
504
+ {
505
+ sensors,
506
+ onDragStart: handleDragStart,
507
+ onDragCancel: handleDragCancel,
508
+ onDragMove: handleDragMove,
509
+ onDragEnd: () => {
510
+ persistTemporaryLayout();
511
+ lastReorderCursorRef.current = null;
512
+ setActiveId(null);
513
+ },
514
+ children: [
515
+ /* @__PURE__ */ jsx(SortableContext, { items, strategy: NO_SORT_STRATEGY, children: /* @__PURE__ */ jsxs(
516
+ "div",
517
+ {
518
+ ...divProps,
519
+ ref: mergedGridRef,
520
+ className: clsx(
521
+ grid_default.grid,
522
+ layoutAnimating && layout_shift_animation_default["layout-animating"],
523
+ className
524
+ ),
525
+ "data-wp-grid-dragging": activeId || void 0,
526
+ "data-wp-grid-resizing": isResizing || void 0,
527
+ style: {
528
+ ...style,
529
+ gridTemplateColumns: `repeat(${effectiveColumns}, minmax(0, 1fr))`,
530
+ gridAutoRows: rowHeight
531
+ },
532
+ children: [
533
+ gridOverlay,
534
+ items.map((id) => /* @__PURE__ */ jsx(
535
+ GridItem,
536
+ {
537
+ item: resolvedItemMap.get(
538
+ id
539
+ ),
540
+ maxColumns: effectiveColumns,
541
+ disabled: !editMode,
542
+ verticalResizable: rowHeight !== "auto",
543
+ interacting: activeId !== null || isResizing,
544
+ dragging: activeId !== null,
545
+ onResize: handleResize,
546
+ onResizeEnd: persistTemporaryLayout,
547
+ resizeSnapPreview: resizeSnapPreview?.id === id ? resizeSnapPreview.snap : null,
548
+ minResizeWidthPx,
549
+ minResizeHeightPx,
550
+ actionableArea: actionableAreaMap.get(id),
551
+ renderResizeHandle,
552
+ children: childrenMap.get(id)
553
+ },
554
+ id
555
+ )),
556
+ remaining,
557
+ exitingItems.map(({ key, rect, child }) => /* @__PURE__ */ jsx(
558
+ ItemExitOverlay,
559
+ {
560
+ itemKey: key,
561
+ rect,
562
+ onAnimationEnd: () => clearExitingItem(key),
563
+ children: child
564
+ },
565
+ `exiting-${key}`
566
+ ))
567
+ ]
568
+ }
569
+ ) }),
570
+ /* @__PURE__ */ jsx(DragOverlay, { dropAnimation: dashboardDragDropAnimation, children: dragOverlayContent })
571
+ ]
572
+ }
573
+ );
574
+ }
575
+ );
576
+ export {
577
+ DashboardGrid
578
+ };
579
+ //# sourceMappingURL=index.mjs.map