@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.
- package/CHANGELOG.md +33 -0
- package/LICENSE.md +788 -0
- package/README.md +534 -0
- package/build/dashboard-grid/grid-item.cjs +308 -0
- package/build/dashboard-grid/grid-item.cjs.map +7 -0
- package/build/dashboard-grid/index.cjs +591 -0
- package/build/dashboard-grid/index.cjs.map +7 -0
- package/build/dashboard-grid/resolve-fill-widths.cjs +189 -0
- package/build/dashboard-grid/resolve-fill-widths.cjs.map +7 -0
- package/build/dashboard-grid/types.cjs +19 -0
- package/build/dashboard-grid/types.cjs.map +7 -0
- package/build/dashboard-lanes/index.cjs +558 -0
- package/build/dashboard-lanes/index.cjs.map +7 -0
- package/build/dashboard-lanes/lane-placement.cjs +110 -0
- package/build/dashboard-lanes/lane-placement.cjs.map +7 -0
- package/build/dashboard-lanes/lanes-item.cjs +295 -0
- package/build/dashboard-lanes/lanes-item.cjs.map +7 -0
- package/build/dashboard-lanes/types.cjs +19 -0
- package/build/dashboard-lanes/types.cjs.map +7 -0
- package/build/dashboard-lanes/use-lane-placement.cjs +206 -0
- package/build/dashboard-lanes/use-lane-placement.cjs.map +7 -0
- package/build/index.cjs +34 -0
- package/build/index.cjs.map +7 -0
- package/build/shared/drag-overlay-drop-animation.cjs +70 -0
- package/build/shared/drag-overlay-drop-animation.cjs.map +7 -0
- package/build/shared/grid-item-key.cjs +31 -0
- package/build/shared/grid-item-key.cjs.map +7 -0
- package/build/shared/grid-overlay.cjs +187 -0
- package/build/shared/grid-overlay.cjs.map +7 -0
- package/build/shared/item-exit-overlay.cjs +150 -0
- package/build/shared/item-exit-overlay.cjs.map +7 -0
- package/build/shared/resize-handle.cjs +224 -0
- package/build/shared/resize-handle.cjs.map +7 -0
- package/build/shared/resize-snap.cjs +47 -0
- package/build/shared/resize-snap.cjs.map +7 -0
- package/build/shared/types.cjs +19 -0
- package/build/shared/types.cjs.map +7 -0
- package/build/shared/use-item-exit-animation.cjs +148 -0
- package/build/shared/use-item-exit-animation.cjs.map +7 -0
- package/build/shared/use-layout-shift-animation.cjs +167 -0
- package/build/shared/use-layout-shift-animation.cjs.map +7 -0
- package/build-module/dashboard-grid/grid-item.mjs +273 -0
- package/build-module/dashboard-grid/grid-item.mjs.map +7 -0
- package/build-module/dashboard-grid/index.mjs +579 -0
- package/build-module/dashboard-grid/index.mjs.map +7 -0
- package/build-module/dashboard-grid/resolve-fill-widths.mjs +164 -0
- package/build-module/dashboard-grid/resolve-fill-widths.mjs.map +7 -0
- package/build-module/dashboard-grid/types.mjs +1 -0
- package/build-module/dashboard-grid/types.mjs.map +7 -0
- package/build-module/dashboard-lanes/index.mjs +547 -0
- package/build-module/dashboard-lanes/index.mjs.map +7 -0
- package/build-module/dashboard-lanes/lane-placement.mjs +85 -0
- package/build-module/dashboard-lanes/lane-placement.mjs.map +7 -0
- package/build-module/dashboard-lanes/lanes-item.mjs +260 -0
- package/build-module/dashboard-lanes/lanes-item.mjs.map +7 -0
- package/build-module/dashboard-lanes/types.mjs +1 -0
- package/build-module/dashboard-lanes/types.mjs.map +7 -0
- package/build-module/dashboard-lanes/use-lane-placement.mjs +181 -0
- package/build-module/dashboard-lanes/use-lane-placement.mjs.map +7 -0
- package/build-module/index.mjs +8 -0
- package/build-module/index.mjs.map +7 -0
- package/build-module/shared/drag-overlay-drop-animation.mjs +47 -0
- package/build-module/shared/drag-overlay-drop-animation.mjs.map +7 -0
- package/build-module/shared/grid-item-key.mjs +6 -0
- package/build-module/shared/grid-item-key.mjs.map +7 -0
- package/build-module/shared/grid-overlay.mjs +152 -0
- package/build-module/shared/grid-overlay.mjs.map +7 -0
- package/build-module/shared/item-exit-overlay.mjs +125 -0
- package/build-module/shared/item-exit-overlay.mjs.map +7 -0
- package/build-module/shared/resize-handle.mjs +193 -0
- package/build-module/shared/resize-handle.mjs.map +7 -0
- package/build-module/shared/resize-snap.mjs +21 -0
- package/build-module/shared/resize-snap.mjs.map +7 -0
- package/build-module/shared/types.mjs +1 -0
- package/build-module/shared/types.mjs.map +7 -0
- package/build-module/shared/use-item-exit-animation.mjs +128 -0
- package/build-module/shared/use-item-exit-animation.mjs.map +7 -0
- package/build-module/shared/use-layout-shift-animation.mjs +140 -0
- package/build-module/shared/use-layout-shift-animation.mjs.map +7 -0
- package/build-types/dashboard-grid/grid-item.d.ts +3 -0
- package/build-types/dashboard-grid/grid-item.d.ts.map +1 -0
- package/build-types/dashboard-grid/index.d.ts +35 -0
- package/build-types/dashboard-grid/index.d.ts.map +1 -0
- package/build-types/dashboard-grid/resolve-fill-widths.d.ts +26 -0
- package/build-types/dashboard-grid/resolve-fill-widths.d.ts.map +1 -0
- package/build-types/dashboard-grid/stories/index.story.d.ts +98 -0
- package/build-types/dashboard-grid/stories/index.story.d.ts.map +1 -0
- package/build-types/dashboard-grid/types.d.ts +232 -0
- package/build-types/dashboard-grid/types.d.ts.map +1 -0
- package/build-types/dashboard-lanes/index.d.ts +40 -0
- package/build-types/dashboard-lanes/index.d.ts.map +1 -0
- package/build-types/dashboard-lanes/lane-placement.d.ts +126 -0
- package/build-types/dashboard-lanes/lane-placement.d.ts.map +1 -0
- package/build-types/dashboard-lanes/lanes-item.d.ts +52 -0
- package/build-types/dashboard-lanes/lanes-item.d.ts.map +1 -0
- package/build-types/dashboard-lanes/stories/index.story.d.ts +64 -0
- package/build-types/dashboard-lanes/stories/index.story.d.ts.map +1 -0
- package/build-types/dashboard-lanes/types.d.ts +151 -0
- package/build-types/dashboard-lanes/types.d.ts.map +1 -0
- package/build-types/dashboard-lanes/use-lane-placement.d.ts +74 -0
- package/build-types/dashboard-lanes/use-lane-placement.d.ts.map +1 -0
- package/build-types/index.d.ts +6 -0
- package/build-types/index.d.ts.map +1 -0
- package/build-types/shared/drag-overlay-drop-animation.d.ts +13 -0
- package/build-types/shared/drag-overlay-drop-animation.d.ts.map +1 -0
- package/build-types/shared/grid-item-key.d.ts +6 -0
- package/build-types/shared/grid-item-key.d.ts.map +1 -0
- package/build-types/shared/grid-overlay.d.ts +19 -0
- package/build-types/shared/grid-overlay.d.ts.map +1 -0
- package/build-types/shared/item-exit-overlay.d.ts +20 -0
- package/build-types/shared/item-exit-overlay.d.ts.map +1 -0
- package/build-types/shared/resize-handle.d.ts +23 -0
- package/build-types/shared/resize-handle.d.ts.map +1 -0
- package/build-types/shared/resize-snap.d.ts +41 -0
- package/build-types/shared/resize-snap.d.ts.map +1 -0
- package/build-types/shared/types.d.ts +144 -0
- package/build-types/shared/types.d.ts.map +1 -0
- package/build-types/shared/use-item-exit-animation.d.ts +37 -0
- package/build-types/shared/use-item-exit-animation.d.ts.map +1 -0
- package/build-types/shared/use-layout-shift-animation.d.ts +77 -0
- package/build-types/shared/use-layout-shift-animation.d.ts.map +1 -0
- package/package.json +80 -0
- package/src/dashboard-grid/grid-item.module.css +94 -0
- package/src/dashboard-grid/grid-item.tsx +205 -0
- package/src/dashboard-grid/grid.module.css +134 -0
- package/src/dashboard-grid/index.tsx +713 -0
- package/src/dashboard-grid/resolve-fill-widths.ts +224 -0
- package/src/dashboard-grid/stories/index.story.tsx +930 -0
- package/src/dashboard-grid/test/keyboard-activation.test.tsx +76 -0
- package/src/dashboard-grid/test/resolve-fill-widths.test.ts +250 -0
- package/src/dashboard-grid/types.ts +271 -0
- package/src/dashboard-lanes/index.tsx +629 -0
- package/src/dashboard-lanes/lane-placement.ts +245 -0
- package/src/dashboard-lanes/lanes-item.module.css +93 -0
- package/src/dashboard-lanes/lanes-item.tsx +236 -0
- package/src/dashboard-lanes/lanes.module.css +152 -0
- package/src/dashboard-lanes/stories/index.story.tsx +518 -0
- package/src/dashboard-lanes/test/keyboard-activation.test.tsx +71 -0
- package/src/dashboard-lanes/test/lane-placement.test.ts +442 -0
- package/src/dashboard-lanes/test/use-lane-placement.test.tsx +358 -0
- package/src/dashboard-lanes/types.ts +176 -0
- package/src/dashboard-lanes/use-lane-placement.ts +313 -0
- package/src/index.ts +17 -0
- package/src/shared/actionable-area-slot.module.css +16 -0
- package/src/shared/drag-overlay-drop-animation.ts +66 -0
- package/src/shared/grid-item-key.ts +5 -0
- package/src/shared/grid-overlay.module.css +82 -0
- package/src/shared/grid-overlay.tsx +93 -0
- package/src/shared/item-exit-animation.module.css +49 -0
- package/src/shared/item-exit-overlay.tsx +57 -0
- package/src/shared/layout-shift-animation.module.css +16 -0
- package/src/shared/resize-handle.module.css +88 -0
- package/src/shared/resize-handle.tsx +163 -0
- package/src/shared/resize-snap.ts +63 -0
- package/src/shared/test/resize-snap.test.ts +35 -0
- package/src/shared/types.ts +164 -0
- package/src/shared/use-item-exit-animation.ts +199 -0
- package/src/shared/use-layout-shift-animation.ts +284 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { DashboardGridLayoutItem } from './types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Resolves items with `width: 'fill'` by computing how many columns they
|
|
8
|
+
* should span. Simulates CSS Grid's row-sparse auto-flow placement so the
|
|
9
|
+
* resolved span matches the free run that CSS Grid will actually use.
|
|
10
|
+
*
|
|
11
|
+
* Two paths:
|
|
12
|
+
* - Fast path (no `height > 1` items): single-row column tracker, O(n).
|
|
13
|
+
* Each fixed item between two fills is visited at most once by a fill's
|
|
14
|
+
* look-ahead.
|
|
15
|
+
* - Multi-row path (any item with `height > 1`): per-column skyline that
|
|
16
|
+
* tracks shadow occupation of tall tiles. Placement scans rows in
|
|
17
|
+
* row-major order, so worst-case cost depends on both columns and rows
|
|
18
|
+
* scanned (rows bounded by the sum of item heights), not only on
|
|
19
|
+
* `maxColumns`.
|
|
20
|
+
*
|
|
21
|
+
* @param sortedKeys - Item keys in display order.
|
|
22
|
+
* @param layoutMap - Map of key to DashboardGridLayoutItem.
|
|
23
|
+
* @param maxColumns - Total columns in the grid.
|
|
24
|
+
* @return Map of fill item keys to their resolved column spans.
|
|
25
|
+
*/
|
|
26
|
+
export function resolveFillWidths(
|
|
27
|
+
sortedKeys: string[],
|
|
28
|
+
layoutMap: Map< string, DashboardGridLayoutItem >,
|
|
29
|
+
maxColumns: number
|
|
30
|
+
): Map< string, number > {
|
|
31
|
+
const resolved = new Map< string, number >();
|
|
32
|
+
const n = sortedKeys.length;
|
|
33
|
+
|
|
34
|
+
// Pre-extract items, clamp widths and heights, detect which path to take.
|
|
35
|
+
const items = new Array< DashboardGridLayoutItem | undefined >( n );
|
|
36
|
+
const widths = new Array< number >( n );
|
|
37
|
+
const heights = new Array< number >( n );
|
|
38
|
+
let hasFill = false;
|
|
39
|
+
let hasMultiRow = false;
|
|
40
|
+
let totalRows = 0;
|
|
41
|
+
|
|
42
|
+
for ( let i = 0; i < n; i++ ) {
|
|
43
|
+
const item = layoutMap.get( sortedKeys[ i ] );
|
|
44
|
+
items[ i ] = item;
|
|
45
|
+
widths[ i ] =
|
|
46
|
+
item && typeof item.width === 'number'
|
|
47
|
+
? Math.min( item.width, maxColumns )
|
|
48
|
+
: 1;
|
|
49
|
+
// Clamp to a positive integer so `0`, fractional, or negative
|
|
50
|
+
// values match the `|| 1` defaulting used in GridItem styles.
|
|
51
|
+
const h = Math.max( 1, Math.floor( item?.height ?? 1 ) );
|
|
52
|
+
heights[ i ] = h;
|
|
53
|
+
if ( item?.width === 'fill' ) {
|
|
54
|
+
hasFill = true;
|
|
55
|
+
}
|
|
56
|
+
if ( h > 1 ) {
|
|
57
|
+
hasMultiRow = true;
|
|
58
|
+
}
|
|
59
|
+
totalRows += h;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if ( ! hasFill ) {
|
|
63
|
+
return resolved;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if ( ! hasMultiRow ) {
|
|
67
|
+
let currentCol = 0;
|
|
68
|
+
|
|
69
|
+
for ( let i = 0; i < n; i++ ) {
|
|
70
|
+
const item = items[ i ];
|
|
71
|
+
if ( ! item ) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if ( item.width === 'full' ) {
|
|
76
|
+
currentCol = 0;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if ( item.width === 'fill' ) {
|
|
81
|
+
let reserved = 0;
|
|
82
|
+
for ( let j = i + 1; j < n; j++ ) {
|
|
83
|
+
const next = items[ j ];
|
|
84
|
+
if (
|
|
85
|
+
! next ||
|
|
86
|
+
next.width === 'full' ||
|
|
87
|
+
next.width === 'fill'
|
|
88
|
+
) {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
const nextW = widths[ j ];
|
|
92
|
+
if ( currentCol + 1 + reserved + nextW <= maxColumns ) {
|
|
93
|
+
reserved += nextW;
|
|
94
|
+
} else {
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const fillCols = Math.max(
|
|
99
|
+
1,
|
|
100
|
+
maxColumns - currentCol - reserved
|
|
101
|
+
);
|
|
102
|
+
resolved.set( item.key, fillCols );
|
|
103
|
+
currentCol += fillCols;
|
|
104
|
+
} else {
|
|
105
|
+
const w = widths[ i ];
|
|
106
|
+
if ( currentCol + w > maxColumns ) {
|
|
107
|
+
currentCol = 0;
|
|
108
|
+
}
|
|
109
|
+
currentCol += w;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if ( currentCol >= maxColumns ) {
|
|
113
|
+
currentCol = 0;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return resolved;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// `rowOccupancy[ col ]` is the index of the next free row at that
|
|
121
|
+
// column; rows below it are taken by previously placed items. This
|
|
122
|
+
// captures the "shadow" of tall tiles into the rows they span.
|
|
123
|
+
const rowOccupancy = new Array< number >( maxColumns ).fill( 0 );
|
|
124
|
+
let cursorRow = 0;
|
|
125
|
+
let cursorCol = 0;
|
|
126
|
+
|
|
127
|
+
for ( let i = 0; i < n; i++ ) {
|
|
128
|
+
const item = items[ i ];
|
|
129
|
+
if ( ! item ) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const h = heights[ i ];
|
|
134
|
+
|
|
135
|
+
if ( item.width === 'full' ) {
|
|
136
|
+
let r = cursorRow;
|
|
137
|
+
for ( let c = 0; c < maxColumns; c++ ) {
|
|
138
|
+
if ( rowOccupancy[ c ] > r ) {
|
|
139
|
+
r = rowOccupancy[ c ];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
for ( let c = 0; c < maxColumns; c++ ) {
|
|
143
|
+
rowOccupancy[ c ] = r + h;
|
|
144
|
+
}
|
|
145
|
+
cursorRow = r + h;
|
|
146
|
+
cursorCol = 0;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if ( item.width === 'fill' ) {
|
|
151
|
+
let r = cursorRow;
|
|
152
|
+
let c = cursorCol;
|
|
153
|
+
scan: for ( ; r <= totalRows; r++ ) {
|
|
154
|
+
const start = r === cursorRow ? cursorCol : 0;
|
|
155
|
+
for ( c = start; c < maxColumns; c++ ) {
|
|
156
|
+
if ( rowOccupancy[ c ] <= r ) {
|
|
157
|
+
break scan;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const fillStartRow = r;
|
|
162
|
+
const fillStartCol = c;
|
|
163
|
+
let runLength = 0;
|
|
164
|
+
while (
|
|
165
|
+
fillStartCol + runLength < maxColumns &&
|
|
166
|
+
rowOccupancy[ fillStartCol + runLength ] <= fillStartRow
|
|
167
|
+
) {
|
|
168
|
+
runLength++;
|
|
169
|
+
}
|
|
170
|
+
let reserved = 0;
|
|
171
|
+
for ( let j = i + 1; j < n; j++ ) {
|
|
172
|
+
const next = items[ j ];
|
|
173
|
+
if (
|
|
174
|
+
! next ||
|
|
175
|
+
next.width === 'full' ||
|
|
176
|
+
next.width === 'fill'
|
|
177
|
+
) {
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
const nextW = widths[ j ];
|
|
181
|
+
if ( 1 + reserved + nextW <= runLength ) {
|
|
182
|
+
reserved += nextW;
|
|
183
|
+
} else {
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const fillCols = Math.max( 1, runLength - reserved );
|
|
188
|
+
resolved.set( item.key, fillCols );
|
|
189
|
+
for ( let k = 0; k < fillCols; k++ ) {
|
|
190
|
+
rowOccupancy[ fillStartCol + k ] = fillStartRow + h;
|
|
191
|
+
}
|
|
192
|
+
cursorRow = fillStartRow;
|
|
193
|
+
cursorCol = fillStartCol + fillCols;
|
|
194
|
+
continue;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const w = widths[ i ];
|
|
198
|
+
let r = cursorRow;
|
|
199
|
+
let c = cursorCol;
|
|
200
|
+
place: for ( ; r <= totalRows; r++ ) {
|
|
201
|
+
c = r === cursorRow ? cursorCol : 0;
|
|
202
|
+
while ( c + w <= maxColumns ) {
|
|
203
|
+
let blocked = -1;
|
|
204
|
+
for ( let k = 0; k < w; k++ ) {
|
|
205
|
+
if ( rowOccupancy[ c + k ] > r ) {
|
|
206
|
+
blocked = c + k;
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
if ( blocked === -1 ) {
|
|
211
|
+
break place;
|
|
212
|
+
}
|
|
213
|
+
c = blocked + 1;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
for ( let k = 0; k < w; k++ ) {
|
|
217
|
+
rowOccupancy[ c + k ] = r + h;
|
|
218
|
+
}
|
|
219
|
+
cursorRow = r;
|
|
220
|
+
cursorCol = c + w;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return resolved;
|
|
224
|
+
}
|