@ankhorage/zora 25.5.0 → 25.6.2
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 +30 -0
- package/README.md +2 -1
- package/dist/capabilities/index.d.ts +2 -74
- package/dist/capabilities/index.d.ts.map +1 -1
- package/dist/capabilities/index.js +6158 -59
- package/dist/capabilities/index.js.map +118 -1
- package/dist/cli/index.d.ts +2 -74
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/features/grid-view/adapters/inbound/GridView.d.ts +2 -7
- package/dist/features/grid-view/adapters/inbound/GridView.d.ts.map +1 -1
- package/dist/features/grid-view/adapters/inbound/GridView.js +309 -51
- package/dist/features/grid-view/adapters/inbound/GridView.js.map +1 -1
- package/dist/features/grid-view/adapters/inbound/TileGrid.d.ts +1 -1
- package/dist/features/grid-view/adapters/inbound/TileGrid.d.ts.map +1 -1
- package/dist/features/grid-view/adapters/inbound/TileGrid.js +11 -4
- package/dist/features/grid-view/adapters/inbound/TileGrid.js.map +1 -1
- package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.d.ts +5 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.d.ts.map +1 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.js +59 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.js.map +1 -0
- package/dist/features/matrix-grid/application/resolveMatrixGridContentSize.d.ts +7 -0
- package/dist/features/matrix-grid/application/resolveMatrixGridContentSize.d.ts.map +1 -0
- package/dist/features/matrix-grid/application/resolveMatrixGridContentSize.js +24 -0
- package/dist/features/matrix-grid/application/resolveMatrixGridContentSize.js.map +1 -0
- package/dist/features/matrix-grid/application/resolveMatrixGridSelection.d.ts +5 -0
- package/dist/features/matrix-grid/application/resolveMatrixGridSelection.d.ts.map +1 -0
- package/dist/features/matrix-grid/application/resolveMatrixGridSelection.js +8 -0
- package/dist/features/matrix-grid/application/resolveMatrixGridSelection.js.map +1 -0
- package/dist/features/matrix-grid/meta.d.ts +11 -0
- package/dist/features/matrix-grid/meta.d.ts.map +1 -0
- package/dist/features/matrix-grid/meta.js +11 -0
- package/dist/features/matrix-grid/meta.js.map +1 -0
- package/dist/features/matrix-grid/public.d.ts +4 -0
- package/dist/features/matrix-grid/public.d.ts.map +1 -0
- package/dist/features/matrix-grid/public.js +3 -0
- package/dist/features/matrix-grid/public.js.map +1 -0
- package/dist/features/registry/ZORA_COMPONENT_REGISTRY.d.ts.map +1 -1
- package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js +2 -0
- package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js.map +1 -1
- package/dist/features/registry/componentMeta.d.ts.map +1 -1
- package/dist/features/registry/componentMeta.js +2 -0
- package/dist/features/registry/componentMeta.js.map +1 -1
- package/dist/features/registry/createEventCapabilities.d.ts +4 -0
- package/dist/features/registry/createEventCapabilities.d.ts.map +1 -0
- package/dist/features/registry/createEventCapabilities.js +76 -0
- package/dist/features/registry/createEventCapabilities.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types/grid-view.d.ts +18 -1
- package/dist/types/grid-view.d.ts.map +1 -1
- package/dist/types/grid-view.js.map +1 -1
- package/dist/types/matrix-grid.d.ts +23 -0
- package/dist/types/matrix-grid.d.ts.map +1 -0
- package/dist/types/matrix-grid.js +2 -0
- package/dist/types/matrix-grid.js.map +1 -0
- package/package.json +1822 -4
- package/src/capabilities/index.test.ts +87 -15
- package/src/capabilities/index.ts +5 -2
- package/src/cli/index.test.ts +5 -3
- package/src/cli/index.ts +5 -2
- package/src/features/grid-view/adapters/inbound/GridView.interaction.test.tsx +585 -0
- package/src/features/grid-view/adapters/inbound/GridView.test.tsx +74 -0
- package/src/features/grid-view/adapters/inbound/GridView.tsx +506 -77
- package/src/features/grid-view/adapters/inbound/TileGrid.tsx +26 -3
- package/src/features/matrix-grid/adapters/inbound/MatrixGrid.test.tsx +232 -0
- package/src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx +142 -0
- package/src/features/matrix-grid/application/resolveMatrixGridContentSize.test.ts +32 -0
- package/src/features/matrix-grid/application/resolveMatrixGridContentSize.ts +28 -0
- package/src/features/matrix-grid/application/resolveMatrixGridSelection.test.ts +10 -0
- package/src/features/matrix-grid/application/resolveMatrixGridSelection.ts +15 -0
- package/src/features/matrix-grid/application/resolveMatrixGridVisibleCells.test.ts +35 -0
- package/src/features/matrix-grid/meta.ts +12 -0
- package/src/features/matrix-grid/public.ts +3 -0
- package/src/features/registry/ZORA_COMPONENT_REGISTRY.ts +2 -0
- package/src/features/registry/componentMeta.ts +2 -0
- package/src/features/registry/createEventCapabilities.ts +108 -0
- package/src/features/time-grid/adapters/inbound/TimeGrid.test.tsx +35 -8
- package/src/index.ts +2 -0
- package/src/structureOwnership.test.ts +5 -0
- package/src/types/grid-view.ts +27 -1
- package/src/types/matrix-grid.ts +29 -0
- package/web-dist/chunks/{Accordion-d6azgz09.js → Accordion-2r0gqk3x.js} +1 -1
- package/web-dist/chunks/Accordion-a6551mh4.js +515 -0
- package/web-dist/chunks/{Accordion-0my2z6qe.js → Accordion-bz04casa.js} +132 -3
- package/web-dist/chunks/{Accordion-7qfd4cb4.js → Accordion-jh72azm2.js} +1 -1
- package/web-dist/components/explorer/Explorer.js +2 -2
- package/web-dist/components/file-explorer/FileExplorer.js +2 -2
- package/web-dist/components/grid-line-overlay/GridLineOverlay.js +1 -1
- package/web-dist/components/grid-ruler/GridRuler.js +1 -1
- package/web-dist/components/grid-view/GridView.js +1 -1
- package/web-dist/components/matrix-grid/MatrixGrid.d.ts +3 -0
- package/web-dist/components/matrix-grid/MatrixGrid.js +153 -0
- package/web-dist/components/matrix-grid/index.d.ts +1 -0
- package/web-dist/components/matrix-grid/index.js +2 -0
- package/web-dist/components/media-explorer/MediaExplorer.js +2 -2
- package/web-dist/components/reader/Reader.js +1 -1
- package/web-dist/components/spatial-grid/SpatialGrid.js +1 -1
- package/web-dist/components/tile-grid/TileGrid.js +1 -1
- package/web-dist/components/time-grid/TimeGrid.js +2 -2
- package/web-dist/components/uploader/Uploader.js +2 -2
- package/web-dist/manifest.json +53 -24
- package/web-dist/chunks/Accordion-gxj5qbpr.js +0 -194
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
getVisibleGridItems,
|
|
4
|
+
constrainViewport,
|
|
5
|
+
panViewport,
|
|
6
|
+
revealWorldRect,
|
|
7
|
+
worldToViewport,
|
|
8
|
+
zoomViewportAt
|
|
9
|
+
} from "./Accordion-bz04casa.js";
|
|
10
|
+
import {
|
|
11
|
+
require_cjs
|
|
12
|
+
} from "./Accordion-xgpzh4wq.js";
|
|
13
|
+
import {
|
|
14
|
+
__toESM
|
|
15
|
+
} from "./Accordion-nh0cs9hq.js";
|
|
16
|
+
|
|
17
|
+
// src/features/grid-view/adapters/inbound/GridView.tsx
|
|
18
|
+
var import_react_native = __toESM(require_cjs(), 1);
|
|
19
|
+
import React from "react";
|
|
20
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
21
|
+
function GridView2({
|
|
22
|
+
items,
|
|
23
|
+
contentWidth,
|
|
24
|
+
contentHeight,
|
|
25
|
+
width,
|
|
26
|
+
height,
|
|
27
|
+
viewport: controlledViewport,
|
|
28
|
+
defaultViewport,
|
|
29
|
+
viewportConstraints,
|
|
30
|
+
zoomLimits,
|
|
31
|
+
zoom = 1,
|
|
32
|
+
overscanPixels = 160,
|
|
33
|
+
focusedItemId,
|
|
34
|
+
revealPaddingPixels = 8,
|
|
35
|
+
interactionPolicy,
|
|
36
|
+
onViewportChange,
|
|
37
|
+
onVisibleItemIdsChange,
|
|
38
|
+
renderItem,
|
|
39
|
+
testID
|
|
40
|
+
}) {
|
|
41
|
+
const [uncontrolledViewport, setUncontrolledViewport] = React.useState(() => createInitialViewport(width, height, zoom, defaultViewport));
|
|
42
|
+
const horizontalScrollRef = React.useRef(null);
|
|
43
|
+
const verticalScrollRef = React.useRef(null);
|
|
44
|
+
const gridRef = React.useRef(null);
|
|
45
|
+
const scrollPositionRef = React.useRef({ x: 0, y: 0 });
|
|
46
|
+
const pinchGestureRef = React.useRef(undefined);
|
|
47
|
+
const pinchMeasurementRef = React.useRef(0);
|
|
48
|
+
const pinchSessionRef = React.useRef(0);
|
|
49
|
+
const viewportOriginRef = React.useRef({ x: 0, y: 0 });
|
|
50
|
+
const focusRevealProposalRef = React.useRef(undefined);
|
|
51
|
+
const focusRevealViewportRef = React.useRef(undefined);
|
|
52
|
+
const [isPinching, setIsPinching] = React.useState(false);
|
|
53
|
+
const constraints = React.useMemo(() => viewportConstraints ?? createContentConstraints(contentWidth, contentHeight), [contentHeight, contentWidth, viewportConstraints]);
|
|
54
|
+
const sourceViewport = controlledViewport ?? uncontrolledViewport;
|
|
55
|
+
const viewport = React.useMemo(() => constrainViewport({ ...sourceViewport, height, width }, constraints), [constraints, height, sourceViewport, width]);
|
|
56
|
+
const viewportRef = React.useRef(viewport);
|
|
57
|
+
const visibleItems = React.useMemo(() => getVisibleGridItems(items, viewport, overscanPixels), [items, overscanPixels, viewport]);
|
|
58
|
+
const viewportVisibleIds = React.useMemo(() => getVisibleGridItems(visibleItems, viewport).map((item) => item.id), [viewport, visibleItems]);
|
|
59
|
+
const focusedItem = items.find((item) => item.id === focusedItemId);
|
|
60
|
+
const focusedItemHeight = focusedItem?.height;
|
|
61
|
+
const focusedItemIdForReveal = focusedItem?.id;
|
|
62
|
+
const focusedItemWidth = focusedItem?.width;
|
|
63
|
+
const focusedItemX = focusedItem?.x;
|
|
64
|
+
const focusedItemY = focusedItem?.y;
|
|
65
|
+
const previousVisibleIdsRef = React.useRef([]);
|
|
66
|
+
const uncontrolled = controlledViewport === undefined;
|
|
67
|
+
const interactive = interactionPolicy !== "passive";
|
|
68
|
+
const publish = React.useCallback((nextViewport) => {
|
|
69
|
+
if (areViewportsEqual(viewportRef.current, nextViewport))
|
|
70
|
+
return;
|
|
71
|
+
viewportRef.current = nextViewport;
|
|
72
|
+
if (uncontrolled)
|
|
73
|
+
setUncontrolledViewport(nextViewport);
|
|
74
|
+
onViewportChange?.(nextViewport);
|
|
75
|
+
}, [onViewportChange, uncontrolled]);
|
|
76
|
+
const publishRef = React.useRef(publish);
|
|
77
|
+
const pan = (displacement) => publish(panViewport(viewportRef.current, displacement, constraints));
|
|
78
|
+
const zoomAt = (focalPoint, factor) => publish(zoomViewportAt(viewportRef.current, focalPoint, {
|
|
79
|
+
pixelsPerUnitX: viewportRef.current.pixelsPerUnitX * factor,
|
|
80
|
+
pixelsPerUnitY: viewportRef.current.pixelsPerUnitY * factor
|
|
81
|
+
}, zoomLimits, constraints));
|
|
82
|
+
React.useEffect(() => {
|
|
83
|
+
viewportRef.current = viewport;
|
|
84
|
+
}, [viewport]);
|
|
85
|
+
React.useEffect(() => {
|
|
86
|
+
publishRef.current = publish;
|
|
87
|
+
}, [publish]);
|
|
88
|
+
const refreshViewportOrigin = React.useCallback(() => {
|
|
89
|
+
gridRef.current?.measureInWindow((x, y) => {
|
|
90
|
+
viewportOriginRef.current = { x, y };
|
|
91
|
+
});
|
|
92
|
+
}, []);
|
|
93
|
+
const measurePinchGesture = React.useCallback((touches, session, onMeasured) => {
|
|
94
|
+
const measurement = pinchMeasurementRef.current + 1;
|
|
95
|
+
pinchMeasurementRef.current = measurement;
|
|
96
|
+
gridRef.current?.measureInWindow((x, y) => {
|
|
97
|
+
if (measurement !== pinchMeasurementRef.current || session !== pinchSessionRef.current) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
viewportOriginRef.current = { x, y };
|
|
101
|
+
onMeasured(getPinchGesture(touches, width, height, { x, y }));
|
|
102
|
+
});
|
|
103
|
+
}, [height, width]);
|
|
104
|
+
React.useLayoutEffect(() => {
|
|
105
|
+
refreshViewportOrigin();
|
|
106
|
+
}, [height, refreshViewportOrigin, width]);
|
|
107
|
+
React.useEffect(() => () => {
|
|
108
|
+
pinchMeasurementRef.current += 1;
|
|
109
|
+
pinchSessionRef.current += 1;
|
|
110
|
+
}, []);
|
|
111
|
+
React.useEffect(() => {
|
|
112
|
+
if (!onVisibleItemIdsChange)
|
|
113
|
+
return;
|
|
114
|
+
const previous = previousVisibleIdsRef.current;
|
|
115
|
+
if (previous.length === viewportVisibleIds.length && previous.every((id, index) => id === viewportVisibleIds.at(index))) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
previousVisibleIdsRef.current = viewportVisibleIds;
|
|
119
|
+
onVisibleItemIdsChange(viewportVisibleIds);
|
|
120
|
+
}, [onVisibleItemIdsChange, viewportVisibleIds]);
|
|
121
|
+
React.useEffect(() => {
|
|
122
|
+
const position = createScrollMapping(viewport, constraints);
|
|
123
|
+
const nextPosition = {
|
|
124
|
+
x: position.horizontal.position,
|
|
125
|
+
y: position.vertical.position
|
|
126
|
+
};
|
|
127
|
+
if (areScrollPositionsEqual(scrollPositionRef.current, nextPosition))
|
|
128
|
+
return;
|
|
129
|
+
scrollPositionRef.current = nextPosition;
|
|
130
|
+
const animated = focusRevealViewportRef.current !== undefined && areViewportsEqual(viewport, focusRevealViewportRef.current);
|
|
131
|
+
horizontalScrollRef.current?.scrollTo({ animated, x: nextPosition.x });
|
|
132
|
+
verticalScrollRef.current?.scrollTo({ animated, y: nextPosition.y });
|
|
133
|
+
if (animated)
|
|
134
|
+
focusRevealViewportRef.current = undefined;
|
|
135
|
+
}, [constraints, viewport]);
|
|
136
|
+
React.useEffect(() => {
|
|
137
|
+
if (focusedItemHeight === undefined || focusedItemIdForReveal === undefined || focusedItemWidth === undefined || focusedItemX === undefined || focusedItemY === undefined) {
|
|
138
|
+
focusRevealProposalRef.current = undefined;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const sourceViewport = viewportRef.current;
|
|
142
|
+
const revealed = revealWorldRect(sourceViewport, {
|
|
143
|
+
height: focusedItemHeight,
|
|
144
|
+
width: focusedItemWidth,
|
|
145
|
+
x: focusedItemX,
|
|
146
|
+
y: focusedItemY
|
|
147
|
+
}, revealPaddingPixels, constraints);
|
|
148
|
+
if (isRepeatedControlledFocusRevealProposal({
|
|
149
|
+
controlled: !uncontrolled,
|
|
150
|
+
focusedItemId: focusedItemIdForReveal,
|
|
151
|
+
previous: focusRevealProposalRef.current,
|
|
152
|
+
sourceViewport,
|
|
153
|
+
viewport: revealed
|
|
154
|
+
})) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
focusRevealProposalRef.current = {
|
|
158
|
+
focusedItemId: focusedItemIdForReveal,
|
|
159
|
+
sourceViewport,
|
|
160
|
+
viewport: revealed
|
|
161
|
+
};
|
|
162
|
+
focusRevealViewportRef.current = areViewportsEqual(sourceViewport, revealed) ? undefined : revealed;
|
|
163
|
+
publishRef.current(revealed);
|
|
164
|
+
}, [
|
|
165
|
+
constraints,
|
|
166
|
+
focusedItemHeight,
|
|
167
|
+
focusedItemIdForReveal,
|
|
168
|
+
focusedItemWidth,
|
|
169
|
+
focusedItemX,
|
|
170
|
+
focusedItemY,
|
|
171
|
+
revealPaddingPixels,
|
|
172
|
+
uncontrolled
|
|
173
|
+
]);
|
|
174
|
+
const scrollMapping = createScrollMapping(viewport, constraints);
|
|
175
|
+
const syncScrollPosition = () => {
|
|
176
|
+
const nextMapping = createScrollMapping(viewportRef.current, constraints);
|
|
177
|
+
const nextPosition = {
|
|
178
|
+
x: nextMapping.horizontal.position,
|
|
179
|
+
y: nextMapping.vertical.position
|
|
180
|
+
};
|
|
181
|
+
scrollPositionRef.current = nextPosition;
|
|
182
|
+
horizontalScrollRef.current?.scrollTo({ animated: false, x: nextPosition.x });
|
|
183
|
+
verticalScrollRef.current?.scrollTo({ animated: false, y: nextPosition.y });
|
|
184
|
+
};
|
|
185
|
+
return /* @__PURE__ */ jsxs(import_react_native.View, {
|
|
186
|
+
ref: gridRef,
|
|
187
|
+
accessibilityLabel: "Interactive grid viewport",
|
|
188
|
+
onLayout: refreshViewportOrigin,
|
|
189
|
+
onTouchEnd: () => {
|
|
190
|
+
const wasPinching = pinchGestureRef.current !== undefined;
|
|
191
|
+
pinchMeasurementRef.current += 1;
|
|
192
|
+
pinchSessionRef.current += 1;
|
|
193
|
+
pinchGestureRef.current = undefined;
|
|
194
|
+
setIsPinching(false);
|
|
195
|
+
if (wasPinching)
|
|
196
|
+
syncScrollPosition();
|
|
197
|
+
},
|
|
198
|
+
onTouchCancel: () => {
|
|
199
|
+
const wasPinching = pinchGestureRef.current !== undefined;
|
|
200
|
+
pinchMeasurementRef.current += 1;
|
|
201
|
+
pinchSessionRef.current += 1;
|
|
202
|
+
pinchGestureRef.current = undefined;
|
|
203
|
+
setIsPinching(false);
|
|
204
|
+
if (wasPinching)
|
|
205
|
+
syncScrollPosition();
|
|
206
|
+
},
|
|
207
|
+
onTouchMove: (event) => {
|
|
208
|
+
if (!interactive)
|
|
209
|
+
return;
|
|
210
|
+
measurePinchGesture([...event.nativeEvent.touches], pinchSessionRef.current, (pinch) => {
|
|
211
|
+
const previous = pinchGestureRef.current;
|
|
212
|
+
pinchGestureRef.current = pinch;
|
|
213
|
+
setIsPinching(pinch !== undefined);
|
|
214
|
+
if (!pinch || !previous)
|
|
215
|
+
return;
|
|
216
|
+
zoomAt(pinch.focalPoint, pinch.distance / previous.distance);
|
|
217
|
+
});
|
|
218
|
+
},
|
|
219
|
+
onTouchStart: (event) => {
|
|
220
|
+
const session = pinchSessionRef.current + 1;
|
|
221
|
+
pinchSessionRef.current = session;
|
|
222
|
+
measurePinchGesture([...event.nativeEvent.touches], session, (pinch) => {
|
|
223
|
+
pinchGestureRef.current = pinch;
|
|
224
|
+
setIsPinching(pinch !== undefined);
|
|
225
|
+
});
|
|
226
|
+
},
|
|
227
|
+
style: { height, overflow: "hidden", width },
|
|
228
|
+
testID,
|
|
229
|
+
children: [
|
|
230
|
+
/* @__PURE__ */ jsx(import_react_native.ScrollView, {
|
|
231
|
+
ref: horizontalScrollRef,
|
|
232
|
+
testID: testID ? `${testID}-horizontal-scroll` : undefined,
|
|
233
|
+
horizontal: true,
|
|
234
|
+
scrollEnabled: interactive && !isPinching,
|
|
235
|
+
scrollEventThrottle: 16,
|
|
236
|
+
showsHorizontalScrollIndicator: true,
|
|
237
|
+
style: { height, width },
|
|
238
|
+
onScroll: (event) => {
|
|
239
|
+
if (pinchGestureRef.current)
|
|
240
|
+
return;
|
|
241
|
+
const { x } = event.nativeEvent.contentOffset;
|
|
242
|
+
const displacement = x - scrollPositionRef.current.x;
|
|
243
|
+
scrollPositionRef.current = { ...scrollPositionRef.current, x };
|
|
244
|
+
if (displacement !== 0)
|
|
245
|
+
pan({ x: -displacement, y: 0 });
|
|
246
|
+
},
|
|
247
|
+
children: /* @__PURE__ */ jsx(import_react_native.ScrollView, {
|
|
248
|
+
ref: verticalScrollRef,
|
|
249
|
+
testID: testID ? `${testID}-vertical-scroll` : undefined,
|
|
250
|
+
scrollEnabled: interactive && !isPinching,
|
|
251
|
+
scrollEventThrottle: 16,
|
|
252
|
+
showsVerticalScrollIndicator: true,
|
|
253
|
+
style: { height, width: scrollMapping.horizontal.contentSize },
|
|
254
|
+
onScroll: (event) => {
|
|
255
|
+
if (pinchGestureRef.current)
|
|
256
|
+
return;
|
|
257
|
+
const { y } = event.nativeEvent.contentOffset;
|
|
258
|
+
const displacement = y - scrollPositionRef.current.y;
|
|
259
|
+
scrollPositionRef.current = { ...scrollPositionRef.current, y };
|
|
260
|
+
if (displacement !== 0)
|
|
261
|
+
pan({ x: 0, y: -displacement });
|
|
262
|
+
},
|
|
263
|
+
children: /* @__PURE__ */ jsx(import_react_native.View, {
|
|
264
|
+
style: {
|
|
265
|
+
height: scrollMapping.vertical.contentSize,
|
|
266
|
+
width: scrollMapping.horizontal.contentSize
|
|
267
|
+
},
|
|
268
|
+
children: visibleItems.map((item) => {
|
|
269
|
+
const position = worldToViewport({ x: item.x, y: item.y }, { ...viewport, offsetX: 0, offsetY: 0 });
|
|
270
|
+
return /* @__PURE__ */ jsx(import_react_native.View, {
|
|
271
|
+
style: {
|
|
272
|
+
height: item.height * viewport.pixelsPerUnitY,
|
|
273
|
+
left: position.x + scrollMapping.horizontal.origin,
|
|
274
|
+
position: "absolute",
|
|
275
|
+
top: position.y + scrollMapping.vertical.origin,
|
|
276
|
+
width: item.width * viewport.pixelsPerUnitX
|
|
277
|
+
},
|
|
278
|
+
children: renderItem(item)
|
|
279
|
+
}, item.id);
|
|
280
|
+
})
|
|
281
|
+
})
|
|
282
|
+
})
|
|
283
|
+
}),
|
|
284
|
+
interactive ? /* @__PURE__ */ jsxs(import_react_native.View, {
|
|
285
|
+
accessibilityLabel: "Viewport controls",
|
|
286
|
+
style: controlsStyle,
|
|
287
|
+
children: [
|
|
288
|
+
/* @__PURE__ */ jsx(import_react_native.Pressable, {
|
|
289
|
+
accessibilityLabel: "Pan left",
|
|
290
|
+
accessibilityRole: "button",
|
|
291
|
+
onPress: () => pan({ x: 48, y: 0 }),
|
|
292
|
+
children: /* @__PURE__ */ jsx(import_react_native.Text, {
|
|
293
|
+
children: "←"
|
|
294
|
+
})
|
|
295
|
+
}),
|
|
296
|
+
/* @__PURE__ */ jsx(import_react_native.Pressable, {
|
|
297
|
+
accessibilityLabel: "Pan right",
|
|
298
|
+
accessibilityRole: "button",
|
|
299
|
+
onPress: () => pan({ x: -48, y: 0 }),
|
|
300
|
+
children: /* @__PURE__ */ jsx(import_react_native.Text, {
|
|
301
|
+
children: "→"
|
|
302
|
+
})
|
|
303
|
+
}),
|
|
304
|
+
/* @__PURE__ */ jsx(import_react_native.Pressable, {
|
|
305
|
+
accessibilityLabel: "Pan up",
|
|
306
|
+
accessibilityRole: "button",
|
|
307
|
+
onPress: () => pan({ x: 0, y: 48 }),
|
|
308
|
+
children: /* @__PURE__ */ jsx(import_react_native.Text, {
|
|
309
|
+
children: "↑"
|
|
310
|
+
})
|
|
311
|
+
}),
|
|
312
|
+
/* @__PURE__ */ jsx(import_react_native.Pressable, {
|
|
313
|
+
accessibilityLabel: "Pan down",
|
|
314
|
+
accessibilityRole: "button",
|
|
315
|
+
onPress: () => pan({ x: 0, y: -48 }),
|
|
316
|
+
children: /* @__PURE__ */ jsx(import_react_native.Text, {
|
|
317
|
+
children: "↓"
|
|
318
|
+
})
|
|
319
|
+
}),
|
|
320
|
+
/* @__PURE__ */ jsx(import_react_native.Pressable, {
|
|
321
|
+
accessibilityLabel: "Zoom in",
|
|
322
|
+
accessibilityRole: "button",
|
|
323
|
+
onPress: () => zoomAt({ x: width / 2, y: height / 2 }, 1.2),
|
|
324
|
+
children: /* @__PURE__ */ jsx(import_react_native.Text, {
|
|
325
|
+
children: "+"
|
|
326
|
+
})
|
|
327
|
+
}),
|
|
328
|
+
/* @__PURE__ */ jsx(import_react_native.Pressable, {
|
|
329
|
+
accessibilityLabel: "Zoom out",
|
|
330
|
+
accessibilityRole: "button",
|
|
331
|
+
onPress: () => zoomAt({ x: width / 2, y: height / 2 }, 1 / 1.2),
|
|
332
|
+
children: /* @__PURE__ */ jsx(import_react_native.Text, {
|
|
333
|
+
children: "−"
|
|
334
|
+
})
|
|
335
|
+
})
|
|
336
|
+
]
|
|
337
|
+
}) : null
|
|
338
|
+
]
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
var controlsStyle = { bottom: 8, gap: 4, position: "absolute", right: 8 };
|
|
342
|
+
function createInitialViewport(width, height, zoom, viewport) {
|
|
343
|
+
return {
|
|
344
|
+
height,
|
|
345
|
+
offsetX: viewport?.offsetX ?? 0,
|
|
346
|
+
offsetY: viewport?.offsetY ?? 0,
|
|
347
|
+
pixelsPerUnitX: viewport?.pixelsPerUnitX ?? zoom,
|
|
348
|
+
pixelsPerUnitY: viewport?.pixelsPerUnitY ?? zoom,
|
|
349
|
+
width
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function createContentConstraints(contentWidth, contentHeight) {
|
|
353
|
+
return { world: { height: contentHeight, width: contentWidth, x: 0, y: 0 } };
|
|
354
|
+
}
|
|
355
|
+
function createScrollMapping(viewport, constraints) {
|
|
356
|
+
const horizontalMinimum = constrainViewport({ ...viewport, offsetX: -Number.MAX_SAFE_INTEGER }, constraints).offsetX;
|
|
357
|
+
const horizontalMaximum = constrainViewport({ ...viewport, offsetX: Number.MAX_SAFE_INTEGER }, constraints).offsetX;
|
|
358
|
+
const verticalMinimum = constrainViewport({ ...viewport, offsetY: -Number.MAX_SAFE_INTEGER }, constraints).offsetY;
|
|
359
|
+
const verticalMaximum = constrainViewport({ ...viewport, offsetY: Number.MAX_SAFE_INTEGER }, constraints).offsetY;
|
|
360
|
+
return {
|
|
361
|
+
horizontal: createScrollAxisMapping({
|
|
362
|
+
maximum: horizontalMaximum,
|
|
363
|
+
minimum: horizontalMinimum,
|
|
364
|
+
offset: viewport.offsetX,
|
|
365
|
+
scale: viewport.pixelsPerUnitX,
|
|
366
|
+
viewportSize: viewport.width
|
|
367
|
+
}),
|
|
368
|
+
vertical: createScrollAxisMapping({
|
|
369
|
+
maximum: verticalMaximum,
|
|
370
|
+
minimum: verticalMinimum,
|
|
371
|
+
offset: viewport.offsetY,
|
|
372
|
+
scale: viewport.pixelsPerUnitY,
|
|
373
|
+
viewportSize: viewport.height
|
|
374
|
+
})
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
function createScrollAxisMapping({
|
|
378
|
+
maximum,
|
|
379
|
+
minimum,
|
|
380
|
+
offset,
|
|
381
|
+
scale,
|
|
382
|
+
viewportSize
|
|
383
|
+
}) {
|
|
384
|
+
const range = (maximum - minimum) * scale;
|
|
385
|
+
return {
|
|
386
|
+
contentSize: viewportSize + range,
|
|
387
|
+
origin: -minimum * scale,
|
|
388
|
+
position: (offset - minimum) * scale
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function areViewportsEqual(left, right) {
|
|
392
|
+
return left.width === right.width && left.height === right.height && left.offsetX === right.offsetX && left.offsetY === right.offsetY && left.pixelsPerUnitX === right.pixelsPerUnitX && left.pixelsPerUnitY === right.pixelsPerUnitY;
|
|
393
|
+
}
|
|
394
|
+
function areScrollPositionsEqual(left, right) {
|
|
395
|
+
return left.x === right.x && left.y === right.y;
|
|
396
|
+
}
|
|
397
|
+
function isRepeatedControlledFocusRevealProposal({
|
|
398
|
+
controlled,
|
|
399
|
+
focusedItemId,
|
|
400
|
+
previous,
|
|
401
|
+
sourceViewport,
|
|
402
|
+
viewport
|
|
403
|
+
}) {
|
|
404
|
+
return controlled && focusedItemId !== undefined && previous?.focusedItemId === focusedItemId && areViewportsEqual(previous.sourceViewport, sourceViewport) && areViewportsEqual(previous.viewport, viewport);
|
|
405
|
+
}
|
|
406
|
+
function getPinchGesture(touches, width, height, viewportOrigin) {
|
|
407
|
+
const [first, second] = touches;
|
|
408
|
+
if (!first || !second)
|
|
409
|
+
return;
|
|
410
|
+
const deltaX = second.pageX - first.pageX;
|
|
411
|
+
const deltaY = second.pageY - first.pageY;
|
|
412
|
+
const distance = Math.hypot(deltaX, deltaY);
|
|
413
|
+
if (!Number.isFinite(distance) || distance === 0)
|
|
414
|
+
return;
|
|
415
|
+
return {
|
|
416
|
+
distance,
|
|
417
|
+
focalPoint: {
|
|
418
|
+
x: Math.min(width, Math.max(0, (first.pageX + second.pageX) / 2 - viewportOrigin.x)),
|
|
419
|
+
y: Math.min(height, Math.max(0, (first.pageY + second.pageY) / 2 - viewportOrigin.y))
|
|
420
|
+
}
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
// src/features/grid-view/adapters/inbound/TileGrid.tsx
|
|
425
|
+
var import_react_native2 = __toESM(require_cjs(), 1);
|
|
426
|
+
import React2 from "react";
|
|
427
|
+
|
|
428
|
+
// src/features/grid-view/application/layoutTileGrid.ts
|
|
429
|
+
function layoutTileGrid(items, viewportWidth, tileSize, gap, zoom = 1) {
|
|
430
|
+
if (![viewportWidth, tileSize, gap, zoom].every(Number.isFinite) || viewportWidth < 0 || tileSize <= 0 || gap < 0 || zoom <= 0) {
|
|
431
|
+
throw new RangeError("Tile layout requires finite, nonnegative dimensions and positive scales.");
|
|
432
|
+
}
|
|
433
|
+
const columns = Math.max(1, Math.floor((viewportWidth / zoom + gap) / (tileSize + gap)));
|
|
434
|
+
const rows = Math.ceil(items.length / columns);
|
|
435
|
+
return {
|
|
436
|
+
columns,
|
|
437
|
+
width: columns * (tileSize + gap) - gap,
|
|
438
|
+
height: Math.max(0, rows * (tileSize + gap) - gap),
|
|
439
|
+
items: items.map((item, index) => ({
|
|
440
|
+
id: item.id,
|
|
441
|
+
x: index % columns * (tileSize + gap),
|
|
442
|
+
y: Math.floor(index / columns) * (tileSize + gap),
|
|
443
|
+
width: tileSize,
|
|
444
|
+
height: tileSize
|
|
445
|
+
}))
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// src/features/grid-view/adapters/inbound/TileGrid.tsx
|
|
450
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
451
|
+
function TileGrid2({
|
|
452
|
+
items,
|
|
453
|
+
width,
|
|
454
|
+
height = 440,
|
|
455
|
+
tileSize = 120,
|
|
456
|
+
gap = 12,
|
|
457
|
+
zoom = 1,
|
|
458
|
+
viewport,
|
|
459
|
+
defaultViewport,
|
|
460
|
+
viewportConstraints,
|
|
461
|
+
zoomLimits,
|
|
462
|
+
overscanPixels,
|
|
463
|
+
focusedItemId,
|
|
464
|
+
revealPaddingPixels,
|
|
465
|
+
onColumnsChange,
|
|
466
|
+
onViewportChange,
|
|
467
|
+
onVisibleItemIdsChange,
|
|
468
|
+
renderItem,
|
|
469
|
+
interactionPolicy,
|
|
470
|
+
testID
|
|
471
|
+
}) {
|
|
472
|
+
const [measuredWidth, setMeasuredWidth] = React2.useState(0);
|
|
473
|
+
const [uncontrolledPixelsPerUnitX, setUncontrolledPixelsPerUnitX] = React2.useState(() => defaultViewport?.pixelsPerUnitX ?? zoom);
|
|
474
|
+
const resolvedWidth = width ?? measuredWidth;
|
|
475
|
+
const pixelsPerUnitX = viewport?.pixelsPerUnitX ?? uncontrolledPixelsPerUnitX;
|
|
476
|
+
const layout = React2.useMemo(() => layoutTileGrid(items, resolvedWidth, tileSize, gap, pixelsPerUnitX), [gap, items, pixelsPerUnitX, resolvedWidth, tileSize]);
|
|
477
|
+
const itemLookup = React2.useMemo(() => new Map(items.map((item) => [item.id, item])), [items]);
|
|
478
|
+
React2.useEffect(() => {
|
|
479
|
+
if (resolvedWidth > 0)
|
|
480
|
+
onColumnsChange?.(layout.columns);
|
|
481
|
+
}, [layout.columns, onColumnsChange, resolvedWidth]);
|
|
482
|
+
const handleViewportChange = React2.useCallback((nextViewport) => {
|
|
483
|
+
if (viewport === undefined)
|
|
484
|
+
setUncontrolledPixelsPerUnitX(nextViewport.pixelsPerUnitX);
|
|
485
|
+
onViewportChange?.(nextViewport);
|
|
486
|
+
}, [onViewportChange, viewport]);
|
|
487
|
+
return /* @__PURE__ */ jsx2(import_react_native2.View, {
|
|
488
|
+
onLayout: (event) => setMeasuredWidth(event.nativeEvent.layout.width),
|
|
489
|
+
style: { width, height, overflow: "hidden" },
|
|
490
|
+
testID,
|
|
491
|
+
children: resolvedWidth > 0 ? /* @__PURE__ */ jsx2(GridView2, {
|
|
492
|
+
contentHeight: layout.height,
|
|
493
|
+
contentWidth: Math.max(resolvedWidth / pixelsPerUnitX, layout.width),
|
|
494
|
+
defaultViewport,
|
|
495
|
+
height,
|
|
496
|
+
focusedItemId,
|
|
497
|
+
interactionPolicy,
|
|
498
|
+
items: layout.items,
|
|
499
|
+
onVisibleItemIdsChange,
|
|
500
|
+
onViewportChange: handleViewportChange,
|
|
501
|
+
overscanPixels,
|
|
502
|
+
renderItem: (item) => {
|
|
503
|
+
const source = itemLookup.get(item.id);
|
|
504
|
+
return source ? renderItem(source) : null;
|
|
505
|
+
},
|
|
506
|
+
revealPaddingPixels,
|
|
507
|
+
width: resolvedWidth,
|
|
508
|
+
viewport,
|
|
509
|
+
viewportConstraints,
|
|
510
|
+
zoomLimits,
|
|
511
|
+
zoom
|
|
512
|
+
}) : null
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
export { GridView2, TileGrid2 };
|
|
@@ -109,6 +109,89 @@ function getLaneIntervalPlacement(lanes, interval) {
|
|
|
109
109
|
return resolveLaneIntervalPlacement(interval, laneMetrics);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
// node_modules/@ankhorage/grid-view/dist/features/layout/utils/resolveMatrixCellPlacement.js
|
|
113
|
+
function resolveMatrixCellPlacement(cell, rows, columns) {
|
|
114
|
+
if (!cell.id) {
|
|
115
|
+
throw new RangeError("Matrix cells require a nonempty ID.");
|
|
116
|
+
}
|
|
117
|
+
const rowIndex = rows.indexes.get(cell.rowId);
|
|
118
|
+
const columnIndex = columns.indexes.get(cell.columnId);
|
|
119
|
+
if (rowIndex === undefined || columnIndex === undefined) {
|
|
120
|
+
throw new RangeError("Matrix cells must reference an existing row and column.");
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
...cell,
|
|
124
|
+
rowIndex,
|
|
125
|
+
columnIndex,
|
|
126
|
+
x: readGridAxisMetric(columns.offsets, columnIndex),
|
|
127
|
+
y: readGridAxisMetric(rows.offsets, rowIndex),
|
|
128
|
+
width: readGridAxisMetric(columns.sizes, columnIndex),
|
|
129
|
+
height: readGridAxisMetric(rows.sizes, rowIndex)
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// node_modules/@ankhorage/grid-view/dist/features/layout/getVisibleMatrixCells.js
|
|
134
|
+
function getVisibleMatrixCells(layout, cells, viewport, overscanPixels = 0) {
|
|
135
|
+
const rows = createGridAxisMetrics(layout.rows);
|
|
136
|
+
const columns = createGridAxisMetrics(layout.columns);
|
|
137
|
+
validateUniqueIds(cells, "Matrix cells");
|
|
138
|
+
const bounds = getVisibleWorldBounds(viewport, overscanPixels);
|
|
139
|
+
const rowRange = getIntersectingRange(rows.offsets, rows.sizes, bounds.y, bounds.height);
|
|
140
|
+
const columnRange = getIntersectingRange(columns.offsets, columns.sizes, bounds.x, bounds.width);
|
|
141
|
+
if (rowRange === undefined || columnRange === undefined) {
|
|
142
|
+
return [];
|
|
143
|
+
}
|
|
144
|
+
return cells.flatMap((cell) => {
|
|
145
|
+
const placement = resolveMatrixCellPlacement(cell, rows, columns);
|
|
146
|
+
return placement.rowIndex >= rowRange.start && placement.rowIndex <= rowRange.end && placement.columnIndex >= columnRange.start && placement.columnIndex <= columnRange.end ? [placement] : [];
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function validateUniqueIds(cells, label) {
|
|
150
|
+
const ids = new Set;
|
|
151
|
+
cells.forEach(({ id }) => {
|
|
152
|
+
if (ids.has(id)) {
|
|
153
|
+
throw new RangeError(`${label} require unique IDs.`);
|
|
154
|
+
}
|
|
155
|
+
ids.add(id);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function getIntersectingRange(offsets, sizes, start, extent) {
|
|
159
|
+
const end = start + extent;
|
|
160
|
+
const first = findFirstEndingAtOrAfter(offsets, sizes, start);
|
|
161
|
+
const last = findLastStartingAtOrBefore(offsets, end);
|
|
162
|
+
return first === undefined || last === undefined || first > last ? undefined : { start: first, end: last };
|
|
163
|
+
}
|
|
164
|
+
function findFirstEndingAtOrAfter(offsets, sizes, coordinate) {
|
|
165
|
+
let low = 0;
|
|
166
|
+
let high = offsets.length - 1;
|
|
167
|
+
let result;
|
|
168
|
+
while (low <= high) {
|
|
169
|
+
const middle = Math.floor((low + high) / 2);
|
|
170
|
+
if (readGridAxisMetric(offsets, middle) + readGridAxisMetric(sizes, middle) >= coordinate) {
|
|
171
|
+
result = middle;
|
|
172
|
+
high = middle - 1;
|
|
173
|
+
} else {
|
|
174
|
+
low = middle + 1;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
function findLastStartingAtOrBefore(offsets, coordinate) {
|
|
180
|
+
let low = 0;
|
|
181
|
+
let high = offsets.length - 1;
|
|
182
|
+
let result;
|
|
183
|
+
while (low <= high) {
|
|
184
|
+
const middle = Math.floor((low + high) / 2);
|
|
185
|
+
if (readGridAxisMetric(offsets, middle) <= coordinate) {
|
|
186
|
+
result = middle;
|
|
187
|
+
low = middle + 1;
|
|
188
|
+
} else {
|
|
189
|
+
high = middle - 1;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
|
|
112
195
|
// node_modules/@ankhorage/grid-view/dist/features/viewport/constrainViewport.js
|
|
113
196
|
function constrainViewport(viewport, constraints) {
|
|
114
197
|
assertValidViewport(viewport);
|
|
@@ -143,6 +226,18 @@ function isAlignment(value) {
|
|
|
143
226
|
return value === "start" || value === "center" || value === "end";
|
|
144
227
|
}
|
|
145
228
|
|
|
229
|
+
// node_modules/@ankhorage/grid-view/dist/features/viewport/panViewport.js
|
|
230
|
+
function panViewport(viewport, displacement, constraints) {
|
|
231
|
+
if (![displacement.x, displacement.y].every(Number.isFinite)) {
|
|
232
|
+
throw new RangeError("Pan displacement must be finite.");
|
|
233
|
+
}
|
|
234
|
+
return constrainViewport({
|
|
235
|
+
...viewport,
|
|
236
|
+
offsetX: viewport.offsetX - displacement.x / viewport.pixelsPerUnitX,
|
|
237
|
+
offsetY: viewport.offsetY - displacement.y / viewport.pixelsPerUnitY
|
|
238
|
+
}, constraints);
|
|
239
|
+
}
|
|
240
|
+
|
|
146
241
|
// node_modules/@ankhorage/grid-view/dist/features/viewport/revealWorldRect.js
|
|
147
242
|
function revealWorldRect(viewport, rect, paddingPixels = 0, constraints) {
|
|
148
243
|
validateRevealInput(viewport, rect, paddingPixels);
|
|
@@ -192,6 +287,34 @@ function worldToViewport(point, viewport) {
|
|
|
192
287
|
};
|
|
193
288
|
}
|
|
194
289
|
|
|
290
|
+
// node_modules/@ankhorage/grid-view/dist/features/viewport/zoomViewportAt.js
|
|
291
|
+
function zoomViewportAt(viewport, focalPoint, nextScale, limits = {}, constraints) {
|
|
292
|
+
if (![focalPoint.x, focalPoint.y, nextScale.pixelsPerUnitX, nextScale.pixelsPerUnitY].every(Number.isFinite)) {
|
|
293
|
+
throw new RangeError("Focal points and scales must be finite.");
|
|
294
|
+
}
|
|
295
|
+
const focalWorld = viewportToWorld(focalPoint, viewport);
|
|
296
|
+
const x = constrainScale(nextScale.pixelsPerUnitX, limits.minX, limits.maxX);
|
|
297
|
+
const y = constrainScale(nextScale.pixelsPerUnitY, limits.minY, limits.maxY);
|
|
298
|
+
return constrainViewport({
|
|
299
|
+
...viewport,
|
|
300
|
+
pixelsPerUnitX: x,
|
|
301
|
+
pixelsPerUnitY: y,
|
|
302
|
+
offsetX: focalWorld.x - focalPoint.x / x,
|
|
303
|
+
offsetY: focalWorld.y - focalPoint.y / y
|
|
304
|
+
}, constraints);
|
|
305
|
+
}
|
|
306
|
+
function constrainScale(scale, minimum, maximum) {
|
|
307
|
+
const min = minimum ?? Number.EPSILON;
|
|
308
|
+
const max = maximum ?? Infinity;
|
|
309
|
+
if (!Number.isFinite(min) || min <= 0 || maximum !== undefined && (!Number.isFinite(max) || max <= 0 || min > max)) {
|
|
310
|
+
throw new RangeError("Zoom limits must be finite positive ranges.");
|
|
311
|
+
}
|
|
312
|
+
if (scale <= 0) {
|
|
313
|
+
throw new RangeError("Viewport scales must be positive.");
|
|
314
|
+
}
|
|
315
|
+
return Math.max(min, Math.min(max, scale));
|
|
316
|
+
}
|
|
317
|
+
|
|
195
318
|
// node_modules/@ankhorage/grid-view/dist/features/axes/getAxisCategoryTicks.js
|
|
196
319
|
function getAxisCategoryTicks(viewport, axis, categories) {
|
|
197
320
|
const bounds = getVisibleWorldBounds(viewport);
|
|
@@ -268,17 +391,23 @@ function adaptiveStep(minimum) {
|
|
|
268
391
|
const multiplier = [1, 2, 5, 10].find((candidate) => candidate * magnitude >= minimum) ?? 10;
|
|
269
392
|
return multiplier * magnitude;
|
|
270
393
|
}
|
|
394
|
+
// node_modules/@ankhorage/grid-view/dist/features/layout/getMatrixCellPlacement.js
|
|
395
|
+
function getMatrixCellPlacement(layout, cell) {
|
|
396
|
+
const rows = createGridAxisMetrics(layout.rows);
|
|
397
|
+
const columns = createGridAxisMetrics(layout.columns);
|
|
398
|
+
return resolveMatrixCellPlacement(cell, rows, columns);
|
|
399
|
+
}
|
|
271
400
|
// node_modules/@ankhorage/grid-view/dist/features/layout/getVisibleLaneIntervals.js
|
|
272
401
|
function getVisibleLaneIntervals(lanes, intervals, viewport, overscanPixels = 0) {
|
|
273
402
|
const laneMetrics = createGridAxisMetrics(lanes.map(({ id, height }) => ({ id, size: height })));
|
|
274
403
|
const bounds = getVisibleWorldBounds(viewport, overscanPixels);
|
|
275
|
-
|
|
404
|
+
validateUniqueIds2(intervals);
|
|
276
405
|
return intervals.flatMap((interval) => {
|
|
277
406
|
const placement = resolveLaneIntervalPlacement(interval, laneMetrics);
|
|
278
407
|
return intersects(placement.x, placement.width, bounds.x, bounds.width) && intersects(placement.y, placement.height, bounds.y, bounds.height) ? [placement] : [];
|
|
279
408
|
});
|
|
280
409
|
}
|
|
281
|
-
function
|
|
410
|
+
function validateUniqueIds2(intervals) {
|
|
282
411
|
const ids = new Set;
|
|
283
412
|
intervals.forEach(({ id }) => {
|
|
284
413
|
if (ids.has(id)) {
|
|
@@ -290,4 +419,4 @@ function validateUniqueIds(intervals) {
|
|
|
290
419
|
function intersects(firstStart, firstExtent, secondStart, secondExtent) {
|
|
291
420
|
return firstStart <= secondStart + secondExtent && firstStart + firstExtent >= secondStart;
|
|
292
421
|
}
|
|
293
|
-
export { getAxisCategoryTicks, getAxisTicks, getVisibleGridItems, getLaneIntervalPlacement, getVisibleLaneIntervals, revealWorldRect, worldToViewport };
|
|
422
|
+
export { getAxisCategoryTicks, getAxisTicks, getVisibleGridItems, getLaneIntervalPlacement, getMatrixCellPlacement, getVisibleLaneIntervals, getVisibleMatrixCells, constrainViewport, panViewport, revealWorldRect, worldToViewport, zoomViewportAt };
|