@ankhorage/zora 25.6.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +1 -1
  3. package/dist/capabilities/index.d.ts +2 -74
  4. package/dist/capabilities/index.d.ts.map +1 -1
  5. package/dist/capabilities/index.js +6158 -59
  6. package/dist/capabilities/index.js.map +118 -1
  7. package/dist/cli/index.d.ts +2 -74
  8. package/dist/cli/index.d.ts.map +1 -1
  9. package/dist/cli/index.js +2 -1
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.d.ts +5 -0
  12. package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.d.ts.map +1 -0
  13. package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.js +59 -0
  14. package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.js.map +1 -0
  15. package/dist/features/matrix-grid/application/resolveMatrixGridContentSize.d.ts +7 -0
  16. package/dist/features/matrix-grid/application/resolveMatrixGridContentSize.d.ts.map +1 -0
  17. package/dist/features/matrix-grid/application/resolveMatrixGridContentSize.js +24 -0
  18. package/dist/features/matrix-grid/application/resolveMatrixGridContentSize.js.map +1 -0
  19. package/dist/features/matrix-grid/application/resolveMatrixGridSelection.d.ts +5 -0
  20. package/dist/features/matrix-grid/application/resolveMatrixGridSelection.d.ts.map +1 -0
  21. package/dist/features/matrix-grid/application/resolveMatrixGridSelection.js +8 -0
  22. package/dist/features/matrix-grid/application/resolveMatrixGridSelection.js.map +1 -0
  23. package/dist/features/matrix-grid/meta.d.ts +11 -0
  24. package/dist/features/matrix-grid/meta.d.ts.map +1 -0
  25. package/dist/features/matrix-grid/meta.js +11 -0
  26. package/dist/features/matrix-grid/meta.js.map +1 -0
  27. package/dist/features/matrix-grid/public.d.ts +4 -0
  28. package/dist/features/matrix-grid/public.d.ts.map +1 -0
  29. package/dist/features/matrix-grid/public.js +3 -0
  30. package/dist/features/matrix-grid/public.js.map +1 -0
  31. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.d.ts.map +1 -1
  32. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js +2 -0
  33. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js.map +1 -1
  34. package/dist/features/registry/componentMeta.d.ts.map +1 -1
  35. package/dist/features/registry/componentMeta.js +2 -0
  36. package/dist/features/registry/componentMeta.js.map +1 -1
  37. package/dist/features/registry/createEventCapabilities.d.ts +4 -0
  38. package/dist/features/registry/createEventCapabilities.d.ts.map +1 -0
  39. package/dist/features/registry/createEventCapabilities.js +76 -0
  40. package/dist/features/registry/createEventCapabilities.js.map +1 -0
  41. package/dist/index.d.ts +2 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +1 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/types/matrix-grid.d.ts +23 -0
  46. package/dist/types/matrix-grid.d.ts.map +1 -0
  47. package/dist/types/matrix-grid.js +2 -0
  48. package/dist/types/matrix-grid.js.map +1 -0
  49. package/package.json +1822 -4
  50. package/src/capabilities/index.test.ts +87 -15
  51. package/src/capabilities/index.ts +5 -2
  52. package/src/cli/index.test.ts +5 -3
  53. package/src/cli/index.ts +5 -2
  54. package/src/features/matrix-grid/adapters/inbound/MatrixGrid.test.tsx +232 -0
  55. package/src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx +142 -0
  56. package/src/features/matrix-grid/application/resolveMatrixGridContentSize.test.ts +32 -0
  57. package/src/features/matrix-grid/application/resolveMatrixGridContentSize.ts +28 -0
  58. package/src/features/matrix-grid/application/resolveMatrixGridSelection.test.ts +10 -0
  59. package/src/features/matrix-grid/application/resolveMatrixGridSelection.ts +15 -0
  60. package/src/features/matrix-grid/application/resolveMatrixGridVisibleCells.test.ts +35 -0
  61. package/src/features/matrix-grid/meta.ts +12 -0
  62. package/src/features/matrix-grid/public.ts +3 -0
  63. package/src/features/registry/ZORA_COMPONENT_REGISTRY.ts +2 -0
  64. package/src/features/registry/componentMeta.ts +2 -0
  65. package/src/features/registry/createEventCapabilities.ts +108 -0
  66. package/src/index.ts +2 -0
  67. package/src/structureOwnership.test.ts +5 -0
  68. package/src/types/matrix-grid.ts +29 -0
  69. package/web-dist/chunks/{Accordion-f43jba23.js → Accordion-2r0gqk3x.js} +1 -1
  70. package/web-dist/chunks/{Accordion-q8exgc3h.js → Accordion-a6551mh4.js} +1 -1
  71. package/web-dist/chunks/{Accordion-ebghcyzj.js → Accordion-bz04casa.js} +92 -3
  72. package/web-dist/chunks/{Accordion-szar8dt5.js → Accordion-jh72azm2.js} +1 -1
  73. package/web-dist/components/explorer/Explorer.js +2 -2
  74. package/web-dist/components/file-explorer/FileExplorer.js +2 -2
  75. package/web-dist/components/grid-line-overlay/GridLineOverlay.js +1 -1
  76. package/web-dist/components/grid-ruler/GridRuler.js +1 -1
  77. package/web-dist/components/grid-view/GridView.js +1 -1
  78. package/web-dist/components/matrix-grid/MatrixGrid.d.ts +3 -0
  79. package/web-dist/components/matrix-grid/MatrixGrid.js +153 -0
  80. package/web-dist/components/matrix-grid/index.d.ts +1 -0
  81. package/web-dist/components/matrix-grid/index.js +2 -0
  82. package/web-dist/components/media-explorer/MediaExplorer.js +2 -2
  83. package/web-dist/components/reader/Reader.js +1 -1
  84. package/web-dist/components/spatial-grid/SpatialGrid.js +1 -1
  85. package/web-dist/components/tile-grid/TileGrid.js +1 -1
  86. package/web-dist/components/time-grid/TimeGrid.js +2 -2
  87. package/web-dist/components/uploader/Uploader.js +2 -2
  88. package/web-dist/manifest.json +53 -24
@@ -0,0 +1,35 @@
1
+ import { getMatrixCellPlacement, getVisibleMatrixCells } from '@ankhorage/grid-view';
2
+ import { describe, expect, test } from 'bun:test';
3
+
4
+ describe('MatrixGrid sparse geometry', () => {
5
+ test('culls a 10k sparse cell catalogue in a million-cell logical matrix', () => {
6
+ const layout = {
7
+ columns: Array.from({ length: 1000 }, (_, index) => ({ id: `column-${index}`, size: 20 })),
8
+ rows: Array.from({ length: 1000 }, (_, index) => ({
9
+ id: `row-${index}`,
10
+ size: index % 2 === 0 ? 16 : 24,
11
+ })),
12
+ };
13
+ const cells = Array.from({ length: 10001 }, (_, index) => ({
14
+ columnId: `column-${(index * 37) % 1000}`,
15
+ id: `cell-${index}`,
16
+ rowId: `row-${(index * 91) % 1000}`,
17
+ }));
18
+
19
+ const firstCell = cells.at(0);
20
+ if (!firstCell) throw new Error('The sparse test catalogue must contain a first cell.');
21
+ const first = getMatrixCellPlacement(layout, firstCell);
22
+ const visible = getVisibleMatrixCells(layout, cells, {
23
+ height: 120,
24
+ offsetX: first.x,
25
+ offsetY: first.y,
26
+ pixelsPerUnitX: 1,
27
+ pixelsPerUnitY: 1,
28
+ width: 120,
29
+ });
30
+
31
+ expect(first).toMatchObject({ id: 'cell-0', width: 20 });
32
+ expect(visible.length).toBeLessThan(cells.length);
33
+ expect(visible.every((cell) => cell.width === 20 && cell.height > 0)).toBe(true);
34
+ });
35
+ });
@@ -0,0 +1,12 @@
1
+ import type { ZoraComponentMeta } from '../../types/authoring';
2
+
3
+ /** Code-only rendering and non-serializable cell callbacks stay outside manifest authoring. */
4
+ export const matrixGridMeta = {
5
+ name: 'MatrixGrid',
6
+ category: 'foundation',
7
+ description: 'Virtualized sparse matrix renderer for executable code APIs.',
8
+ directManifestNode: false,
9
+ note: 'Requires a renderCell callback and is intentionally code-only.',
10
+ allowedChildren: [],
11
+ props: {},
12
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,3 @@
1
+ export type { MatrixGridProps } from '../../types/matrix-grid';
2
+ export { MatrixGrid } from './adapters/inbound/MatrixGrid';
3
+ export { resolveMatrixGridContentSize } from './application/resolveMatrixGridContentSize';
@@ -55,6 +55,7 @@ import { Image } from '../image/public';
55
55
  import { KeyboardAvoidingView } from '../keyboard-avoiding-view/public';
56
56
  import { AppShell, Divider, Grid, Screen, ScrollView, View } from '../layout/public';
57
57
  import { FlatList, List, ListItem, ListSection, SectionList } from '../list/public';
58
+ import { MatrixGrid } from '../matrix-grid/public';
58
59
  import { MissingElement } from '../missing-element/public';
59
60
  import { Pagination } from '../pagination/public';
60
61
  import { PaletteItem } from '../palette-item/public';
@@ -202,6 +203,7 @@ const _ZORA_COMPONENT_REGISTRY = {
202
203
  GridView,
203
204
  TileGrid,
204
205
  TimeGrid,
206
+ MatrixGrid,
205
207
  MediaExplorer,
206
208
  Hero,
207
209
  List,
@@ -68,6 +68,7 @@ import { viewMeta } from '../layout/viewMeta';
68
68
  import { flatListMeta } from '../list/flatListMeta';
69
69
  import { listItemMeta, listMeta, listSectionMeta } from '../list/meta';
70
70
  import { sectionListMeta } from '../list/sectionListMeta';
71
+ import { matrixGridMeta } from '../matrix-grid/meta';
71
72
  import { missingElementMeta } from '../missing-element/missingElementMeta';
72
73
  import { paginationMeta } from '../pagination/paginationMeta';
73
74
  import { paletteItemMeta } from '../palette-item/paletteItemMeta';
@@ -206,6 +207,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = finalizeFeatureMet
206
207
  GridView: gridViewMeta,
207
208
  TileGrid: tileGridMeta,
208
209
  TimeGrid: timeGridMeta,
210
+ MatrixGrid: matrixGridMeta,
209
211
  Hero: heroMeta,
210
212
  List: listMeta,
211
213
  ListItem: listItemMeta,
@@ -0,0 +1,108 @@
1
+ import { areCapabilitiesEqual, isCapabilityId } from '@ankhorage/capability';
2
+ import type { Capability } from '@ankhorage/contracts/capability';
3
+ import type { DataSchema } from '@ankhorage/contracts/data';
4
+
5
+ import type {
6
+ ZoraComponentEventMeta,
7
+ ZoraComponentEventPayloadFieldMeta,
8
+ } from '../../types/authoring';
9
+ import { ZORA_COMPONENT_META } from './componentMeta';
10
+
11
+ /*** Projects direct-manifest ZORA event metadata into unique portable event capabilities. */
12
+ export function createEventCapabilities(): readonly Capability[] {
13
+ const capabilitiesById = Object.values(ZORA_COMPONENT_META)
14
+ .filter((component) => component.directManifestNode)
15
+ .flatMap((component) => Object.values(component.events ?? {}))
16
+ .reduce<ReadonlyMap<Capability['id'], Capability>>(
17
+ (capabilities, event) => addEventCapability(capabilities, event),
18
+ new Map(),
19
+ );
20
+
21
+ return [...capabilitiesById.values()].sort((left, right) => left.id.localeCompare(right.id));
22
+ }
23
+
24
+ /*** Adds one namespaced metadata event while rejecting conflicting duplicate identities. */
25
+ function addEventCapability(
26
+ capabilities: ReadonlyMap<Capability['id'], Capability>,
27
+ event: ZoraComponentEventMeta,
28
+ ): ReadonlyMap<Capability['id'], Capability> {
29
+ if (!isCapabilityId(event.eventType)) return capabilities;
30
+
31
+ const capability = createEventCapability(event);
32
+ const existing = capabilities.get(capability.id);
33
+ if (existing !== undefined && !areCapabilitiesEqual(existing, capability)) {
34
+ throw new Error(`ZORA event metadata defines conflicting capability "${capability.id}".`);
35
+ }
36
+
37
+ return new Map([...capabilities, [capability.id, capability]]);
38
+ }
39
+
40
+ /*** Converts one emitted component event into its serializable canonical descriptor. */
41
+ function createEventCapability(event: ZoraComponentEventMeta): Capability {
42
+ if (!isCapabilityId(event.eventType)) {
43
+ throw new Error(
44
+ `ZORA event metadata must use a namespaced capability id: "${event.eventType}".`,
45
+ );
46
+ }
47
+
48
+ return {
49
+ id: event.eventType,
50
+ owner: '@ankhorage/zora',
51
+ access: ['emit'],
52
+ binding: { kind: 'event', bindableAs: ['source'] },
53
+ label: event.label,
54
+ ...(event.description === undefined ? {} : { description: event.description }),
55
+ output: { schema: createEventPayloadSchema(event.payloadFields ?? []) },
56
+ };
57
+ }
58
+
59
+ /*** Projects the documented event payload fields into an open object schema. */
60
+ function createEventPayloadSchema(
61
+ fields: readonly ZoraComponentEventPayloadFieldMeta[],
62
+ ): DataSchema {
63
+ return {
64
+ type: 'object',
65
+ properties: fields.reduce<Readonly<Record<string, DataSchema>>>(addPayloadField, {}),
66
+ };
67
+ }
68
+
69
+ /*** Adds one dotted metadata path to an immutable object-schema property map. */
70
+ function addPayloadField(
71
+ properties: Readonly<Record<string, DataSchema>>,
72
+ field: ZoraComponentEventPayloadFieldMeta,
73
+ ): Readonly<Record<string, DataSchema>> {
74
+ return addPayloadFieldAtPath(properties, field.path.split('.'), createPayloadFieldSchema(field));
75
+ }
76
+
77
+ /*** Recursively embeds a leaf schema below its documented object-property path. */
78
+ function addPayloadFieldAtPath(
79
+ properties: Readonly<Record<string, DataSchema>>,
80
+ path: readonly string[],
81
+ schema: DataSchema,
82
+ ): Readonly<Record<string, DataSchema>> {
83
+ const [key, ...remainingPath] = path;
84
+ if (key === undefined || key === '') return properties;
85
+ if (remainingPath.length === 0) return { ...properties, [key]: schema };
86
+
87
+ const current = Object.entries(properties).find(([propertyKey]) => propertyKey === key)?.[1];
88
+ const nestedProperties = addPayloadFieldAtPath(current?.properties ?? {}, remainingPath, schema);
89
+ return {
90
+ ...properties,
91
+ [key]: { ...current, type: 'object', properties: nestedProperties },
92
+ };
93
+ }
94
+
95
+ /*** Maps one authoring payload-field type and annotations to its portable data schema. */
96
+ function createPayloadFieldSchema(field: ZoraComponentEventPayloadFieldMeta): DataSchema {
97
+ return {
98
+ ...(field.type === 'object'
99
+ ? { type: 'object' as const }
100
+ : field.type === 'record'
101
+ ? { type: 'object' as const, additionalProperties: true }
102
+ : field.type === 'unknown'
103
+ ? {}
104
+ : { type: field.type }),
105
+ ...(field.label === undefined ? {} : { title: field.label }),
106
+ ...(field.description === undefined ? {} : { description: field.description }),
107
+ };
108
+ }
package/src/index.ts CHANGED
@@ -314,6 +314,8 @@ export type {
314
314
  } from './features/list/public';
315
315
  export { FlatList, SectionList } from './features/list/public';
316
316
  export { List, ListItem, ListSection } from './features/list/public';
317
+ export type { MatrixGridProps } from './features/matrix-grid/public';
318
+ export { MatrixGrid } from './features/matrix-grid/public';
317
319
  export { MissingElement, type MissingElementProps } from './features/missing-element/public';
318
320
  export { Pagination, type PaginationProps } from './features/pagination/public';
319
321
  export type { PaletteItemProps } from './features/palette-item/public';
@@ -63,4 +63,9 @@ describe('src ownership', () => {
63
63
  expect(existsSync(path), path).toBe(false);
64
64
  }
65
65
  });
66
+
67
+ test('keeps event capability projection with the registry metadata owner', () => {
68
+ expect(existsSync('src/features/registry/createEventCapabilities.ts')).toBe(true);
69
+ expect(existsSync('src/capabilities/createEventCapabilities.ts')).toBe(false);
70
+ });
66
71
  });
@@ -0,0 +1,29 @@
1
+ import type {
2
+ GridMatrixCell,
3
+ GridMatrixCellPlacement,
4
+ GridMatrixLayout,
5
+ GridViewport,
6
+ } from '@ankhorage/grid-view';
7
+ import type React from 'react';
8
+
9
+ import type { ZoraBaseProps } from './base';
10
+ import type { SelectionMode } from './selection';
11
+
12
+ /** Code-first virtualized sparse-matrix presentation over the published grid-view geometry API. */
13
+ export interface MatrixGridProps extends ZoraBaseProps {
14
+ readonly layout: GridMatrixLayout;
15
+ readonly cells: readonly GridMatrixCell[];
16
+ readonly width: number;
17
+ readonly height: number;
18
+ /** A supplied viewport is controlled by the caller, including independent axis zoom. */
19
+ readonly viewport?: GridViewport;
20
+ readonly zoomX?: number;
21
+ readonly zoomY?: number;
22
+ readonly overscanPixels?: number;
23
+ readonly selectedCellIds?: readonly string[];
24
+ readonly selectionMode?: SelectionMode;
25
+ readonly onSelectionChange?: (ids: readonly string[]) => void;
26
+ readonly onViewportChange?: (viewport: GridViewport) => void;
27
+ readonly renderCell: (cell: GridMatrixCellPlacement) => React.ReactNode;
28
+ readonly accessibilityLabel?: string;
29
+ }
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import {
3
3
  TileGrid2
4
- } from "./Accordion-q8exgc3h.js";
4
+ } from "./Accordion-a6551mh4.js";
5
5
  import {
6
6
  withZoraThemeScope
7
7
  } from "./Accordion-42jfy1a1.js";
@@ -6,7 +6,7 @@ import {
6
6
  revealWorldRect,
7
7
  worldToViewport,
8
8
  zoomViewportAt
9
- } from "./Accordion-ebghcyzj.js";
9
+ } from "./Accordion-bz04casa.js";
10
10
  import {
11
11
  require_cjs
12
12
  } from "./Accordion-xgpzh4wq.js";
@@ -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);
@@ -308,17 +391,23 @@ function adaptiveStep(minimum) {
308
391
  const multiplier = [1, 2, 5, 10].find((candidate) => candidate * magnitude >= minimum) ?? 10;
309
392
  return multiplier * magnitude;
310
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
+ }
311
400
  // node_modules/@ankhorage/grid-view/dist/features/layout/getVisibleLaneIntervals.js
312
401
  function getVisibleLaneIntervals(lanes, intervals, viewport, overscanPixels = 0) {
313
402
  const laneMetrics = createGridAxisMetrics(lanes.map(({ id, height }) => ({ id, size: height })));
314
403
  const bounds = getVisibleWorldBounds(viewport, overscanPixels);
315
- validateUniqueIds(intervals);
404
+ validateUniqueIds2(intervals);
316
405
  return intervals.flatMap((interval) => {
317
406
  const placement = resolveLaneIntervalPlacement(interval, laneMetrics);
318
407
  return intersects(placement.x, placement.width, bounds.x, bounds.width) && intersects(placement.y, placement.height, bounds.y, bounds.height) ? [placement] : [];
319
408
  });
320
409
  }
321
- function validateUniqueIds(intervals) {
410
+ function validateUniqueIds2(intervals) {
322
411
  const ids = new Set;
323
412
  intervals.forEach(({ id }) => {
324
413
  if (ids.has(id)) {
@@ -330,4 +419,4 @@ function validateUniqueIds(intervals) {
330
419
  function intersects(firstStart, firstExtent, secondStart, secondExtent) {
331
420
  return firstStart <= secondStart + secondExtent && firstStart + firstExtent >= secondStart;
332
421
  }
333
- export { getAxisCategoryTicks, getAxisTicks, getVisibleGridItems, getLaneIntervalPlacement, getVisibleLaneIntervals, constrainViewport, panViewport, revealWorldRect, worldToViewport, zoomViewportAt };
422
+ export { getAxisCategoryTicks, getAxisTicks, getVisibleGridItems, getLaneIntervalPlacement, getMatrixCellPlacement, getVisibleLaneIntervals, getVisibleMatrixCells, constrainViewport, panViewport, revealWorldRect, worldToViewport, zoomViewportAt };
@@ -6,7 +6,7 @@ import {
6
6
  getAxisCategoryTicks,
7
7
  getAxisTicks,
8
8
  worldToViewport
9
- } from "./Accordion-ebghcyzj.js";
9
+ } from "./Accordion-bz04casa.js";
10
10
  import {
11
11
  useZoraTheme2
12
12
  } from "./Accordion-srjya6dz.js";
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import"../../chunks/Accordion-q8exgc3h.js";
2
+ import"../../chunks/Accordion-a6551mh4.js";
3
3
  import"../../chunks/Accordion-bfzeab9x.js";
4
4
  import"../../chunks/Accordion-6wrr910w.js";
5
5
  import"../../chunks/Accordion-8f0nekwe.js";
@@ -14,7 +14,7 @@ import {
14
14
  Explorer2,
15
15
  FileExplorer2,
16
16
  MediaExplorer2
17
- } from "../../chunks/Accordion-f43jba23.js";
17
+ } from "../../chunks/Accordion-2r0gqk3x.js";
18
18
  import"../../chunks/Accordion-bff0p3x4.js";
19
19
  import"../../chunks/Accordion-srjya6dz.js";
20
20
  import"../../chunks/Accordion-184r2r82.js";
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import"../../chunks/Accordion-q8exgc3h.js";
2
+ import"../../chunks/Accordion-a6551mh4.js";
3
3
  import"../../chunks/Accordion-bfzeab9x.js";
4
4
  import"../../chunks/Accordion-6wrr910w.js";
5
5
  import"../../chunks/Accordion-8f0nekwe.js";
@@ -14,7 +14,7 @@ import {
14
14
  Explorer2,
15
15
  FileExplorer2,
16
16
  MediaExplorer2
17
- } from "../../chunks/Accordion-f43jba23.js";
17
+ } from "../../chunks/Accordion-2r0gqk3x.js";
18
18
  import"../../chunks/Accordion-bff0p3x4.js";
19
19
  import"../../chunks/Accordion-srjya6dz.js";
20
20
  import"../../chunks/Accordion-184r2r82.js";
@@ -4,7 +4,7 @@ import"../../chunks/Accordion-42jfy1a1.js";
4
4
  import {
5
5
  GridLineOverlay2,
6
6
  GridRuler2
7
- } from "../../chunks/Accordion-szar8dt5.js";
7
+ } from "../../chunks/Accordion-jh72azm2.js";
8
8
  import"../../chunks/Accordion-srjya6dz.js";
9
9
  import"../../chunks/Accordion-xgpzh4wq.js";
10
10
  export {
@@ -4,7 +4,7 @@ import"../../chunks/Accordion-42jfy1a1.js";
4
4
  import {
5
5
  GridLineOverlay2,
6
6
  GridRuler2
7
- } from "../../chunks/Accordion-szar8dt5.js";
7
+ } from "../../chunks/Accordion-jh72azm2.js";
8
8
  import"../../chunks/Accordion-srjya6dz.js";
9
9
  import"../../chunks/Accordion-xgpzh4wq.js";
10
10
  export {
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  GridView2,
4
4
  TileGrid2
5
- } from "../../chunks/Accordion-q8exgc3h.js";
5
+ } from "../../chunks/Accordion-a6551mh4.js";
6
6
  import"../../chunks/Accordion-xgpzh4wq.js";
7
7
  export {
8
8
  GridView2 as GridView,
@@ -0,0 +1,3 @@
1
+ import type React from 'react';
2
+
3
+ export declare const MatrixGrid: React.ComponentType<Record<string, unknown>>;
@@ -0,0 +1,153 @@
1
+ 'use client';
2
+ import"../../chunks/Accordion-09qs8gt1.js";
3
+ import"../../chunks/Accordion-6wrr910w.js";
4
+ import {
5
+ Pressable
6
+ } from "../../chunks/Accordion-nnv76yff.js";
7
+ import {
8
+ GridView2
9
+ } from "../../chunks/Accordion-a6551mh4.js";
10
+ import {
11
+ withZoraThemeScope
12
+ } from "../../chunks/Accordion-42jfy1a1.js";
13
+ import"../../chunks/Accordion-sw7ep29d.js";
14
+ import {
15
+ resolveSelectionEventIntent
16
+ } from "../../chunks/Accordion-5df6cgyf.js";
17
+ import {
18
+ applySelectionIntent
19
+ } from "../../chunks/Accordion-n4et7etk.js";
20
+ import {
21
+ getMatrixCellPlacement,
22
+ getVisibleMatrixCells
23
+ } from "../../chunks/Accordion-bz04casa.js";
24
+ import {
25
+ useZoraTheme2
26
+ } from "../../chunks/Accordion-srjya6dz.js";
27
+ import"../../chunks/Accordion-184r2r82.js";
28
+ import"../../chunks/Accordion-fre84yaq.js";
29
+ import {
30
+ require_cjs
31
+ } from "../../chunks/Accordion-xgpzh4wq.js";
32
+ import {
33
+ __toESM
34
+ } from "../../chunks/Accordion-nh0cs9hq.js";
35
+
36
+ // src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx
37
+ var import_react_native = __toESM(require_cjs(), 1);
38
+ import React from "react";
39
+
40
+ // src/features/matrix-grid/application/resolveMatrixGridContentSize.ts
41
+ function resolveMatrixGridContentSize(layout) {
42
+ const finalRow = layout.rows.at(-1);
43
+ const finalColumn = layout.columns.at(-1);
44
+ if (!finalRow || !finalColumn) {
45
+ getVisibleMatrixCells(layout, [], {
46
+ height: 1,
47
+ offsetX: 0,
48
+ offsetY: 0,
49
+ pixelsPerUnitX: 1,
50
+ pixelsPerUnitY: 1,
51
+ width: 1
52
+ });
53
+ return { height: 0, width: 0 };
54
+ }
55
+ const finalCell = getMatrixCellPlacement(layout, {
56
+ id: "matrix-grid-content-boundary",
57
+ rowId: finalRow.id,
58
+ columnId: finalColumn.id
59
+ });
60
+ return { height: finalCell.y + finalCell.height, width: finalCell.x + finalCell.width };
61
+ }
62
+
63
+ // src/features/matrix-grid/application/resolveMatrixGridSelection.ts
64
+ function resolveMatrixGridSelection(selectedIds, cellId, intent, mode) {
65
+ return mode === "single" ? applySelectionIntent(selectedIds, cellId, "replace") : applySelectionIntent(selectedIds, cellId, intent);
66
+ }
67
+
68
+ // src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx
69
+ import { jsx } from "react/jsx-runtime";
70
+ function MatrixGridInner({
71
+ accessibilityLabel = "Matrix grid",
72
+ cells,
73
+ height,
74
+ interactionPolicy,
75
+ layout,
76
+ onSelectionChange,
77
+ onViewportChange,
78
+ overscanPixels = 160,
79
+ renderCell,
80
+ selectedCellIds = [],
81
+ selectionMode = "single",
82
+ testID,
83
+ viewport: controlledViewport,
84
+ width,
85
+ zoomX = 1,
86
+ zoomY = 1
87
+ }) {
88
+ const { theme } = useZoraTheme2();
89
+ const contentSize = React.useMemo(() => resolveMatrixGridContentSize(layout), [layout]);
90
+ const initialViewport = React.useMemo(() => ({ height, offsetX: 0, offsetY: 0, pixelsPerUnitX: zoomX, pixelsPerUnitY: zoomY, width }), [height, width, zoomX, zoomY]);
91
+ const [uncontrolledViewport, setUncontrolledViewport] = React.useState(initialViewport);
92
+ const viewport = controlledViewport ?? uncontrolledViewport;
93
+ const visibleCells = React.useMemo(() => getVisibleMatrixCells(layout, cells, viewport, overscanPixels), [cells, layout, overscanPixels, viewport]);
94
+ const visibleCellById = React.useMemo(() => new Map(visibleCells.map((cell) => [cell.id, cell])), [visibleCells]);
95
+ const handleViewportChange = React.useCallback((proposal) => {
96
+ if (controlledViewport === undefined)
97
+ setUncontrolledViewport(proposal);
98
+ onViewportChange?.(proposal);
99
+ }, [controlledViewport, onViewportChange]);
100
+ const activateCell = React.useCallback((cell, event) => {
101
+ if (interactionPolicy === "passive")
102
+ return;
103
+ const intent = resolveSelectionEventIntent(event, "pointer");
104
+ onSelectionChange?.(resolveMatrixGridSelection(selectedCellIds, cell.id, intent, selectionMode));
105
+ }, [interactionPolicy, onSelectionChange, selectedCellIds, selectionMode]);
106
+ return /* @__PURE__ */ jsx(import_react_native.View, {
107
+ accessibilityLabel,
108
+ children: /* @__PURE__ */ jsx(GridView2, {
109
+ contentHeight: contentSize.height,
110
+ contentWidth: contentSize.width,
111
+ height,
112
+ interactionPolicy,
113
+ items: visibleCells,
114
+ overscanPixels: 0,
115
+ renderItem: (item) => {
116
+ const cell = visibleCellById.get(item.id);
117
+ if (!cell)
118
+ return null;
119
+ return renderMatrixCell(cell, selectedCellIds, theme.semantics.neutral.divider, theme.colors.primary, renderCell, activateCell, testID);
120
+ },
121
+ testID,
122
+ viewport,
123
+ width,
124
+ onViewportChange: handleViewportChange
125
+ })
126
+ });
127
+ }
128
+ function renderMatrixCell(cell, selectedCellIds, dividerColor, selectedColor, renderCell, activateCell, testID) {
129
+ const selected = selectedCellIds.includes(cell.id);
130
+ return /* @__PURE__ */ jsx(Pressable, {
131
+ accessibilityLabel: `Cell ${cell.id}`,
132
+ accessibilityRole: "button",
133
+ accessibilityState: { selected },
134
+ style: [
135
+ styles.cell,
136
+ {
137
+ borderColor: selected ? selectedColor : dividerColor,
138
+ height: "100%",
139
+ width: "100%"
140
+ }
141
+ ],
142
+ testID: testID === undefined ? undefined : `${testID}-cell-${cell.id}`,
143
+ onPress: (event) => activateCell(cell, event),
144
+ children: renderCell(cell)
145
+ }, cell.id);
146
+ }
147
+ var styles = import_react_native.StyleSheet.create({
148
+ cell: { borderWidth: 1, height: "100%", overflow: "hidden", width: "100%" }
149
+ });
150
+ var MatrixGrid = withZoraThemeScope(MatrixGridInner);
151
+ export {
152
+ MatrixGrid
153
+ };
@@ -0,0 +1 @@
1
+ export * from './MatrixGrid';
@@ -0,0 +1,2 @@
1
+ 'use client';
2
+ export * from './MatrixGrid.js';
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import"../../chunks/Accordion-q8exgc3h.js";
2
+ import"../../chunks/Accordion-a6551mh4.js";
3
3
  import"../../chunks/Accordion-bfzeab9x.js";
4
4
  import"../../chunks/Accordion-6wrr910w.js";
5
5
  import"../../chunks/Accordion-8f0nekwe.js";
@@ -14,7 +14,7 @@ import {
14
14
  Explorer2,
15
15
  FileExplorer2,
16
16
  MediaExplorer2
17
- } from "../../chunks/Accordion-f43jba23.js";
17
+ } from "../../chunks/Accordion-2r0gqk3x.js";
18
18
  import"../../chunks/Accordion-bff0p3x4.js";
19
19
  import"../../chunks/Accordion-srjya6dz.js";
20
20
  import"../../chunks/Accordion-184r2r82.js";