@inf-monkeys-tech/monkeys-design 2.0.271 → 2.0.272
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/dist/components/capabilities/index.js +46 -46
- package/dist/components/capabilities/index.js.map +1 -1
- package/dist/components/capabilities/index.mjs +3 -3
- package/dist/components/capabilities/index.mjs.map +1 -1
- package/dist/components/ui/index.js +39 -39
- package/dist/components/ui/index.js.map +1 -1
- package/dist/components/ui/index.mjs +11 -11
- package/dist/components/ui/index.mjs.map +1 -1
- package/dist/components/ui-cards/index.js +22 -22
- package/dist/components/ui-cards/index.js.map +1 -1
- package/dist/components/ui-cards/index.mjs +11 -11
- package/dist/components/ui-cards/index.mjs.map +1 -1
- package/dist/sources/{74648a5f915c0bb5c62302200082831805032ad77b34d4834ccf14f48cf1adf7.ts → 568395c3cde80014adcd7ad3b0ecb7b6546a3ff197fece0206ed1a81bff31007.ts} +17 -11
- package/dist/sources/{7c8819fd9dea7d22ca7b31ade688ad068ff0a861b7797fa1dda486187d8a32e8.tsx → 9dd5e2cf837136a8ad4b5ad6de70a006120b7faa0f7d39e7c9f8e8e4c9aa27c4.tsx} +1 -1
- package/package.json +1 -1
|
@@ -27,9 +27,13 @@ export function normalizeCardGridRange(count: number, range?: CardGridWindowRang
|
|
|
27
27
|
return { start, end };
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export function calculateCardGridRange(count: number, offset: number, viewport: number, extent: number, gap: number, overscan: number): CardGridWindowRange {
|
|
30
|
+
export function calculateCardGridRange(count: number, offset: number, viewport: number, extent: number, gap: number, overscan: number, columns = 1): CardGridWindowRange {
|
|
31
31
|
const stride = extent + gap;
|
|
32
32
|
const extra = Math.max(0, Math.trunc(overscan));
|
|
33
|
+
if (columns > 1) {
|
|
34
|
+
const rows = calculateCardGridRange(Math.ceil(count / columns), offset, viewport, extent, gap, overscan);
|
|
35
|
+
return { start: rows.start * columns, end: Math.min(count, rows.end * columns) };
|
|
36
|
+
}
|
|
33
37
|
return normalizeCardGridRange(count, { start: Math.max(0, Math.floor(offset / stride) - extra), end: Math.ceil(Math.max(0, offset + viewport) / stride) + extra });
|
|
34
38
|
}
|
|
35
39
|
|
|
@@ -56,7 +60,7 @@ export function useCardGridWindow(config: CardGridWindowing | undefined, count:
|
|
|
56
60
|
const currentRange = normalizeCardGridRange(count, range);
|
|
57
61
|
const committed = useRef(currentRange);
|
|
58
62
|
committed.current = currentRange;
|
|
59
|
-
const [geometry, setGeometry] = useState({ extent: config?.itemExtent ?? 0, gap: config?.gap ?? 0, fallback: false, grid: false });
|
|
63
|
+
const [geometry, setGeometry] = useState({ extent: config?.itemExtent ?? 0, gap: config?.gap ?? 0, fallback: false, grid: false, columns: 1 });
|
|
60
64
|
const [focused, setFocused] = useState(false);
|
|
61
65
|
const focusedElement = useRef<Element | null>(null);
|
|
62
66
|
const axis = config?.axis ?? 'vertical';
|
|
@@ -72,7 +76,7 @@ export function useCardGridWindow(config: CardGridWindowing | undefined, count:
|
|
|
72
76
|
callback.current?.(next);
|
|
73
77
|
}, [count]);
|
|
74
78
|
useEffect(() => {
|
|
75
|
-
setGeometry({ extent: config?.itemExtent ?? 0, gap: config?.gap ?? 0, fallback: false, grid: false });
|
|
79
|
+
setGeometry({ extent: config?.itemExtent ?? 0, gap: config?.gap ?? 0, fallback: false, grid: false, columns: 1 });
|
|
76
80
|
lastSent.current = undefined;
|
|
77
81
|
}, [config?.itemExtent, config?.gap, config?.enabled, axis]);
|
|
78
82
|
useEffect(() => {
|
|
@@ -97,7 +101,9 @@ export function useCardGridWindow(config: CardGridWindowing | undefined, count:
|
|
|
97
101
|
const horizontal = axis === 'horizontal';
|
|
98
102
|
// Retain the complete layout rather than estimate wrapping or mixed-size cards.
|
|
99
103
|
const crossTracks = (horizontal ? css.gridTemplateRows : css.gridTemplateColumns).trim().split(/\s+/);
|
|
100
|
-
const
|
|
104
|
+
const rowGrid = !horizontal && css.display === 'grid' && css.gridAutoFlow === 'row' && crossTracks.every(track => Number.parseFloat(track) > 0);
|
|
105
|
+
const grid = rowGrid || css.display === 'grid' && css.gridAutoFlow === (horizontal ? 'column' : 'row') && crossTracks.length === 1 && Number.parseFloat(horizontal ? css.gridAutoColumns : css.gridAutoRows) > 0;
|
|
106
|
+
const columns = rowGrid ? crossTracks.length : 1;
|
|
101
107
|
const flex = css.display === 'flex' && css.flexWrap !== 'wrap' && css.flexWrap !== 'wrap-reverse' && (horizontal ? css.flexDirection !== 'column' : css.flexDirection === 'column');
|
|
102
108
|
if (!grid && !flex) {
|
|
103
109
|
setGeometry(previous => previous.fallback ? previous : ({ ...previous, fallback: true }));
|
|
@@ -116,8 +122,8 @@ export function useCardGridWindow(config: CardGridWindowing | undefined, count:
|
|
|
116
122
|
}
|
|
117
123
|
}
|
|
118
124
|
}
|
|
119
|
-
const geometryChanged = Math.abs(extent - geometry.extent) > .25 || Math.abs(gap - geometry.gap) > .25 || grid !== geometry.grid || geometry.fallback;
|
|
120
|
-
if (geometryChanged) setGeometry(previous => ({ ...previous, extent, gap, grid, fallback: false }));
|
|
125
|
+
const geometryChanged = Math.abs(extent - geometry.extent) > .25 || Math.abs(gap - geometry.gap) > .25 || grid !== geometry.grid || columns !== geometry.columns || geometry.fallback;
|
|
126
|
+
if (geometryChanged) setGeometry(previous => ({ ...previous, extent, gap, grid, columns, fallback: false }));
|
|
121
127
|
// Restore after measured spacer tracks exist; restoring earlier can clamp the offset.
|
|
122
128
|
if (windowKey && restored.current !== windowKey) {
|
|
123
129
|
const saved = retention.get(windowKey);
|
|
@@ -134,7 +140,7 @@ export function useCardGridWindow(config: CardGridWindowing | undefined, count:
|
|
|
134
140
|
const selfOffset = owner === root ? (horizontal ? root.scrollLeft : root.scrollTop) : 0;
|
|
135
141
|
const offset = Math.max(0, viewportStart - start + selfOffset - lead);
|
|
136
142
|
const visibleEnd = Math.max(0, viewportEnd - start + selfOffset - lead);
|
|
137
|
-
const next = calculateCardGridRange(count, offset, Math.max(0, visibleEnd - offset), extent, gap, config?.overscan ?? 2);
|
|
143
|
+
const next = calculateCardGridRange(count, offset, Math.max(0, visibleEnd - offset), extent, gap, config?.overscan ?? 2, columns);
|
|
138
144
|
if (focused && config?.preserveFocus !== false) {
|
|
139
145
|
let item = focusedElement.current?.closest<HTMLElement>('[data-collection-window-item]') ?? null;
|
|
140
146
|
while (item && item.closest('.monkeys-ui-card-grid') !== root) item = item.parentElement?.closest<HTMLElement>('[data-collection-window-item]') ?? null;
|
|
@@ -158,7 +164,7 @@ export function useCardGridWindow(config: CardGridWindowing | undefined, count:
|
|
|
158
164
|
root.querySelectorAll<HTMLElement>('[data-collection-window-item]').forEach(item => observer?.observe(item));
|
|
159
165
|
schedule();
|
|
160
166
|
return () => { disposed = true; retain(); if (frame) cancelAnimationFrame(frame); observer?.disconnect(); owner.removeEventListener('scroll', onScroll); window.removeEventListener('resize', schedule); };
|
|
161
|
-
}, [requested, active, suspended, count, axis, geometry.extent, geometry.gap, geometry.grid, config?.itemExtent, config?.gap, config?.leadingExtent, config?.overscan, config?.scrollOwner, config?.measureItems, config?.sizeTolerance, currentRange.start, currentRange.end, focused, config?.preserveFocus, send, windowKey, retention, config?.retentionLimit]);
|
|
167
|
+
}, [requested, active, suspended, count, axis, geometry.extent, geometry.gap, geometry.grid, geometry.columns, config?.itemExtent, config?.gap, config?.leadingExtent, config?.overscan, config?.scrollOwner, config?.measureItems, config?.sizeTolerance, currentRange.start, currentRange.end, focused, config?.preserveFocus, send, windowKey, retention, config?.retentionLimit]);
|
|
162
168
|
useEffect(() => {
|
|
163
169
|
if (!focused) return;
|
|
164
170
|
const release = () => {
|
|
@@ -174,7 +180,7 @@ export function useCardGridWindow(config: CardGridWindowing | undefined, count:
|
|
|
174
180
|
}, [focused]);
|
|
175
181
|
const stride = geometry.extent + geometry.gap;
|
|
176
182
|
// Keep spacers until the author has applied the full-range fallback request.
|
|
177
|
-
const before = requested && currentRange.start > 0 ? Math.max(0, currentRange.start * stride - geometry.gap) : 0;
|
|
178
|
-
const after = requested && currentRange.end < count ? Math.max(0, (count - currentRange.end) * stride - geometry.gap) : 0;
|
|
179
|
-
return { ref, before, after, beforeCount: currentRange.start, afterCount: count - currentRange.end, grid: geometry.grid, axis, retention, onFocus: (target: EventTarget | null) => { if (requested && config?.preserveFocus !== false) { focusedElement.current = target instanceof Element ? target : null; setFocused(true); } } };
|
|
183
|
+
const before = requested && currentRange.start > 0 ? Math.max(0, Math.floor(currentRange.start / geometry.columns) * stride - geometry.gap) : 0;
|
|
184
|
+
const after = requested && currentRange.end < count ? Math.max(0, Math.ceil((count - currentRange.end) / geometry.columns) * stride - geometry.gap) : 0;
|
|
185
|
+
return { ref, before, after, beforeCount: currentRange.start, afterCount: count - currentRange.end, grid: geometry.grid, columns: geometry.columns, axis, retention, onFocus: (target: EventTarget | null) => { if (requested && config?.preserveFocus !== false) { focusedElement.current = target instanceof Element ? target : null; setFocused(true); } } };
|
|
180
186
|
}
|
|
@@ -100,7 +100,7 @@ export const CardGrid = forwardRef<HTMLDivElement, CardGridProps>(function CardG
|
|
|
100
100
|
const window = useCardGridWindow(windowing, windowItemCount, windowRange, onWindowRangeChange, sorting, windowKey);
|
|
101
101
|
useCardGridRowCapacity(window.ref, rowPreview, onRowCapacityChange);
|
|
102
102
|
const attach = useCallback((node: HTMLDivElement | null) => { window.ref.current = node; if (typeof forwardedRef === 'function') forwardedRef(node); else if (forwardedRef) forwardedRef.current = node; }, [forwardedRef, window.ref]);
|
|
103
|
-
const spacer = (size: number, key: string) => size > 0 ? <div key={key} aria-hidden="true" data-collection-window-spacer={key} style={{ flex: '0 0 auto', pointerEvents: 'none', ...(window.grid ? window.axis === 'horizontal' ? { gridColumn: 'span ' + (key === 'before' ? window.beforeCount : window.afterCount) } : { gridRow: 'span ' + (key === 'before' ? window.beforeCount : window.afterCount) } : {}), ...(window.axis === 'horizontal' ? { width: size, height: 1 } : { height: size, width: 1 }) }} /> : null;
|
|
103
|
+
const spacer = (size: number, key: string) => size > 0 ? <div key={key} aria-hidden="true" data-collection-window-spacer={key} style={{ flex: '0 0 auto', pointerEvents: 'none', ...(window.grid ? window.axis === 'horizontal' ? { gridColumn: 'span ' + (key === 'before' ? window.beforeCount : window.afterCount) } : window.columns > 1 ? { gridColumn: '1 / -1' } : { gridRow: 'span ' + (key === 'before' ? window.beforeCount : window.afterCount) } : {}), ...(window.axis === 'horizontal' ? { width: size, height: 1 } : { height: size, width: 1 }) }} /> : null;
|
|
104
104
|
return <CardGridWindowRetention.Provider value={window.retention}><div {...props} ref={attach} role="list" data-view={view} className={cx('monkeys-ui-card-grid', className)} onFocusCapture={event => { onFocusCapture?.(event); window.onFocus(event.target); }} style={{ '--monkeys-ui-card-width': minCardWidth === undefined ? 'var(--monkeys-ui-layout-card-min-width,var(--monkeys-ui-default-layout-card-min-width))' : minCardWidth + 'px', ...(columnGap !== undefined ? { '--monkeys-ui-grid-column-gap': columnGap + 'px' } : {}), ...style } as CSSProperties}>
|
|
105
105
|
<SortableCollection {...{reorderItems, reorderAxis, reorderGroupField, reorderDisabled, onReorder}} onSortingActiveChange={setSorting}>{leading}{spacer(window.before, 'before')}{children}{spacer(window.after, 'after')}{trailing}</SortableCollection>
|
|
106
106
|
</div></CardGridWindowRetention.Provider>;
|