@ankhorage/zora 25.2.1 → 25.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +2 -1
  3. package/dist/features/grid-rulers/adapters/inbound/GridLineOverlay.d.ts +5 -0
  4. package/dist/features/grid-rulers/adapters/inbound/GridLineOverlay.d.ts.map +1 -0
  5. package/dist/features/grid-rulers/adapters/inbound/GridLineOverlay.js +69 -0
  6. package/dist/features/grid-rulers/adapters/inbound/GridLineOverlay.js.map +1 -0
  7. package/dist/features/grid-rulers/adapters/inbound/GridRuler.d.ts +5 -0
  8. package/dist/features/grid-rulers/adapters/inbound/GridRuler.d.ts.map +1 -0
  9. package/dist/features/grid-rulers/adapters/inbound/GridRuler.js +59 -0
  10. package/dist/features/grid-rulers/adapters/inbound/GridRuler.js.map +1 -0
  11. package/dist/features/grid-rulers/application/projectGridRulerPosition.d.ts +4 -0
  12. package/dist/features/grid-rulers/application/projectGridRulerPosition.d.ts.map +1 -0
  13. package/dist/features/grid-rulers/application/projectGridRulerPosition.js +10 -0
  14. package/dist/features/grid-rulers/application/projectGridRulerPosition.js.map +1 -0
  15. package/dist/features/grid-rulers/application/resolveGridRulerMarks.d.ts +5 -0
  16. package/dist/features/grid-rulers/application/resolveGridRulerMarks.d.ts.map +1 -0
  17. package/dist/features/grid-rulers/application/resolveGridRulerMarks.js +22 -0
  18. package/dist/features/grid-rulers/application/resolveGridRulerMarks.js.map +1 -0
  19. package/dist/features/grid-rulers/meta.d.ts +21 -0
  20. package/dist/features/grid-rulers/meta.d.ts.map +1 -0
  21. package/dist/features/grid-rulers/meta.js +22 -0
  22. package/dist/features/grid-rulers/meta.js.map +1 -0
  23. package/dist/features/grid-rulers/public.d.ts +5 -0
  24. package/dist/features/grid-rulers/public.d.ts.map +1 -0
  25. package/dist/features/grid-rulers/public.js +4 -0
  26. package/dist/features/grid-rulers/public.js.map +1 -0
  27. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.d.ts.map +1 -1
  28. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js +5 -0
  29. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js.map +1 -1
  30. package/dist/features/registry/componentMeta.d.ts.map +1 -1
  31. package/dist/features/registry/componentMeta.js +5 -0
  32. package/dist/features/registry/componentMeta.js.map +1 -1
  33. package/dist/features/spatial-grid/adapters/inbound/SpatialGrid.d.ts +5 -0
  34. package/dist/features/spatial-grid/adapters/inbound/SpatialGrid.d.ts.map +1 -0
  35. package/dist/features/spatial-grid/adapters/inbound/SpatialGrid.js +38 -0
  36. package/dist/features/spatial-grid/adapters/inbound/SpatialGrid.js.map +1 -0
  37. package/dist/features/spatial-grid/application/sortSpatialGridItems.d.ts +4 -0
  38. package/dist/features/spatial-grid/application/sortSpatialGridItems.d.ts.map +1 -0
  39. package/dist/features/spatial-grid/application/sortSpatialGridItems.js +8 -0
  40. package/dist/features/spatial-grid/application/sortSpatialGridItems.js.map +1 -0
  41. package/dist/features/spatial-grid/meta.d.ts +11 -0
  42. package/dist/features/spatial-grid/meta.d.ts.map +1 -0
  43. package/dist/features/spatial-grid/meta.js +11 -0
  44. package/dist/features/spatial-grid/meta.js.map +1 -0
  45. package/dist/features/spatial-grid/public.d.ts +3 -0
  46. package/dist/features/spatial-grid/public.d.ts.map +1 -0
  47. package/dist/features/spatial-grid/public.js +2 -0
  48. package/dist/features/spatial-grid/public.js.map +1 -0
  49. package/dist/index.d.ts +4 -0
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +2 -0
  52. package/dist/index.js.map +1 -1
  53. package/dist/types/grid-rulers.d.ts +48 -0
  54. package/dist/types/grid-rulers.d.ts.map +1 -0
  55. package/dist/types/grid-rulers.js +2 -0
  56. package/dist/types/grid-rulers.js.map +1 -0
  57. package/dist/types/spatial-grid.d.ts +41 -0
  58. package/dist/types/spatial-grid.d.ts.map +1 -0
  59. package/dist/types/spatial-grid.js +2 -0
  60. package/dist/types/spatial-grid.js.map +1 -0
  61. package/package.json +3 -3
  62. package/src/features/grid-rulers/adapters/inbound/GridLineOverlay.tsx +123 -0
  63. package/src/features/grid-rulers/adapters/inbound/GridRuler.tsx +96 -0
  64. package/src/features/grid-rulers/adapters/inbound/GridRulers.test.tsx +162 -0
  65. package/src/features/grid-rulers/application/projectGridRulerPosition.ts +19 -0
  66. package/src/features/grid-rulers/application/resolveGridRulerMarks.test.ts +90 -0
  67. package/src/features/grid-rulers/application/resolveGridRulerMarks.ts +39 -0
  68. package/src/features/grid-rulers/meta.ts +26 -0
  69. package/src/features/grid-rulers/public.ts +10 -0
  70. package/src/features/registry/ZORA_COMPONENT_REGISTRY.ts +5 -0
  71. package/src/features/registry/componentMeta.ts +5 -0
  72. package/src/features/spatial-grid/adapters/inbound/SpatialGrid.test.tsx +248 -0
  73. package/src/features/spatial-grid/adapters/inbound/SpatialGrid.tsx +112 -0
  74. package/src/features/spatial-grid/application/sortSpatialGridItems.test.ts +42 -0
  75. package/src/features/spatial-grid/application/sortSpatialGridItems.ts +14 -0
  76. package/src/features/spatial-grid/meta.ts +12 -0
  77. package/src/features/spatial-grid/public.ts +6 -0
  78. package/src/index.ts +14 -0
  79. package/src/types/grid-rulers.ts +59 -0
  80. package/src/types/spatial-grid.ts +44 -0
  81. package/web-dist/chunks/{Accordion-mh67wb34.js → Accordion-090y18cv.js} +2 -2
  82. package/web-dist/chunks/{Accordion-7yazfxr6.js → Accordion-3d4wkzg7.js} +4 -4
  83. package/web-dist/chunks/{Accordion-ndf3jqhb.js → Accordion-40tenzcg.js} +3 -3
  84. package/web-dist/chunks/{Accordion-cbfa2b8j.js → Accordion-4s68t3h7.js} +5 -5
  85. package/web-dist/chunks/{Accordion-7asr7vb0.js → Accordion-4zqd7twp.js} +4 -4
  86. package/web-dist/chunks/{Accordion-sdcfa14w.js → Accordion-5g05kfmx.js} +3 -3
  87. package/web-dist/chunks/Accordion-60wn9xn9.js +201 -0
  88. package/web-dist/chunks/{Accordion-wgejzesa.js → Accordion-61ntvh14.js} +3 -3
  89. package/web-dist/chunks/{Accordion-q09fjenx.js → Accordion-6rrqpb2h.js} +1 -1
  90. package/web-dist/chunks/{Accordion-mej71qnw.js → Accordion-a4cma5b6.js} +2 -2
  91. package/web-dist/chunks/{Accordion-9dqkq9am.js → Accordion-ejx5gcf9.js} +8 -8
  92. package/web-dist/chunks/{Accordion-pe66x9cv.js → Accordion-ewf1zen9.js} +4 -4
  93. package/web-dist/chunks/{Accordion-xvzrx6bh.js → Accordion-fjxcn6g9.js} +7 -7
  94. package/web-dist/chunks/{Accordion-teg40mpt.js → Accordion-fmzxat3v.js} +3 -3
  95. package/web-dist/chunks/{Accordion-016wvwpg.js → Accordion-h3y8qev2.js} +1 -1
  96. package/web-dist/chunks/{Accordion-t0hbez90.js → Accordion-h7zsx9eg.js} +2 -2
  97. package/web-dist/chunks/{Accordion-ch4q5w0z.js → Accordion-jnc315h7.js} +1 -1
  98. package/web-dist/chunks/{Accordion-fkc50r9z.js → Accordion-kjtcbe09.js} +2 -2
  99. package/web-dist/chunks/{Accordion-tmrjy46p.js → Accordion-nssr5gep.js} +1 -1
  100. package/web-dist/chunks/{Accordion-54k0ncs3.js → Accordion-nxsda1my.js} +5 -73
  101. package/web-dist/chunks/{Accordion-ntndskbj.js → Accordion-pvj5npzc.js} +2 -2
  102. package/web-dist/chunks/{Accordion-ggwxv6k3.js → Accordion-r1cj2w9e.js} +2 -2
  103. package/web-dist/chunks/Accordion-r2w86rwv.js +209 -0
  104. package/web-dist/chunks/{Accordion-kkr7xfh2.js → Accordion-s3d6g59s.js} +4 -4
  105. package/web-dist/chunks/{Accordion-5ga4549x.js → Accordion-sp4k08kw.js} +3 -3
  106. package/web-dist/chunks/{Accordion-1p9r2ack.js → Accordion-sy1cc5my.js} +2 -2
  107. package/web-dist/chunks/{Accordion-hmhdwvqp.js → Accordion-tqpsmdrk.js} +3 -3
  108. package/web-dist/chunks/{Accordion-fzkrrc4z.js → Accordion-v0grdh6q.js} +1 -1
  109. package/web-dist/chunks/{Accordion-ajawc6nq.js → Accordion-zt9yghdz.js} +3 -3
  110. package/web-dist/components/accordion/Accordion.js +4 -4
  111. package/web-dist/components/accordion-item/AccordionItem.js +4 -4
  112. package/web-dist/components/app-bar/AppBar.js +6 -6
  113. package/web-dist/components/app-header/AppHeader.js +6 -6
  114. package/web-dist/components/app-shell/AppShell.js +1 -1
  115. package/web-dist/components/auth-screen/AuthScreen.js +9 -9
  116. package/web-dist/components/avatar/Avatar.js +4 -4
  117. package/web-dist/components/avatar-group/AvatarGroup.js +4 -4
  118. package/web-dist/components/badge/Badge.js +1 -1
  119. package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +9 -9
  120. package/web-dist/components/bottom-sheet/BottomSheet.js +2 -2
  121. package/web-dist/components/bottom-sheet-flat-list/BottomSheetFlatList.js +2 -2
  122. package/web-dist/components/bottom-sheet-scroll-view/BottomSheetScrollView.js +2 -2
  123. package/web-dist/components/bottom-sheet-section-list/BottomSheetSectionList.js +2 -2
  124. package/web-dist/components/bottom-sheet-view/BottomSheetView.js +2 -2
  125. package/web-dist/components/bottom-sheet-virtualized-list/BottomSheetVirtualizedList.js +2 -2
  126. package/web-dist/components/breadcrumbs/Breadcrumbs.js +4 -4
  127. package/web-dist/components/button/Button.js +2 -2
  128. package/web-dist/components/button-group/ButtonGroup.js +2 -2
  129. package/web-dist/components/camera-permission-view/CameraPermissionView.js +9 -9
  130. package/web-dist/components/card/Card.js +8 -8
  131. package/web-dist/components/card-back/CardBack.js +1 -1
  132. package/web-dist/components/card-hand/CardHand.js +1 -1
  133. package/web-dist/components/chat-list-item/ChatListItem.js +6 -6
  134. package/web-dist/components/checkbox/Checkbox.js +3 -3
  135. package/web-dist/components/checkbox-group/CheckboxGroup.js +3 -3
  136. package/web-dist/components/chess-board/ChessBoard.js +1 -1
  137. package/web-dist/components/chip/Chip.js +4 -4
  138. package/web-dist/components/chip-group/ChipGroup.js +4 -4
  139. package/web-dist/components/collection-editor/CollectionEditor.js +8 -8
  140. package/web-dist/components/content-rail/ContentRail.js +3 -3
  141. package/web-dist/components/data-table/DataTable.js +13 -13
  142. package/web-dist/components/date-picker/DatePicker.js +4 -4
  143. package/web-dist/components/dialog/Dialog.js +3 -3
  144. package/web-dist/components/divider/Divider.js +1 -1
  145. package/web-dist/components/empty-state/EmptyState.js +9 -9
  146. package/web-dist/components/explorer/Explorer.js +6 -6
  147. package/web-dist/components/field/Field.js +3 -3
  148. package/web-dist/components/file-explorer/FileExplorer.js +6 -6
  149. package/web-dist/components/flat-list/FlatList.js +4 -4
  150. package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +9 -9
  151. package/web-dist/components/form/Form.js +5 -5
  152. package/web-dist/components/form-actions/FormActions.js +5 -5
  153. package/web-dist/components/form-error/FormError.js +5 -5
  154. package/web-dist/components/game/Game.js +2 -2
  155. package/web-dist/components/game-entity/GameEntity.js +2 -2
  156. package/web-dist/components/game-field/GameField.js +2 -2
  157. package/web-dist/components/game-input-zone/GameInputZone.js +2 -2
  158. package/web-dist/components/game-measurement-probe/GameMeasurementProbe.js +2 -2
  159. package/web-dist/components/game-overlay/GameOverlay.js +2 -2
  160. package/web-dist/components/gradient/Gradient.js +2 -2
  161. package/web-dist/components/gradient-renderer-provider/GradientRendererProvider.js +2 -2
  162. package/web-dist/components/grid/Grid.js +1 -1
  163. package/web-dist/components/grid-line-overlay/GridLineOverlay.d.ts +4 -0
  164. package/web-dist/components/grid-line-overlay/GridLineOverlay.js +13 -0
  165. package/web-dist/components/grid-line-overlay/index.d.ts +1 -0
  166. package/web-dist/components/grid-line-overlay/index.js +2 -0
  167. package/web-dist/components/grid-ruler/GridRuler.d.ts +4 -0
  168. package/web-dist/components/grid-ruler/GridRuler.js +13 -0
  169. package/web-dist/components/grid-ruler/index.d.ts +1 -0
  170. package/web-dist/components/grid-ruler/index.js +2 -0
  171. package/web-dist/components/grid-view/GridView.js +1 -1
  172. package/web-dist/components/heading/Heading.js +1 -1
  173. package/web-dist/components/hero/Hero.js +8 -8
  174. package/web-dist/components/icon/Icon.js +1 -1
  175. package/web-dist/components/icon-button/IconButton.js +2 -2
  176. package/web-dist/components/image/Image.js +3 -3
  177. package/web-dist/components/keyboard-avoiding-view/KeyboardAvoidingView.js +1 -1
  178. package/web-dist/components/list/List.js +4 -4
  179. package/web-dist/components/list-item/ListItem.js +4 -4
  180. package/web-dist/components/list-section/ListSection.js +4 -4
  181. package/web-dist/components/media-card/MediaCard.js +8 -8
  182. package/web-dist/components/media-explorer/MediaExplorer.js +6 -6
  183. package/web-dist/components/message-bubble/MessageBubble.js +6 -6
  184. package/web-dist/components/metric-card/MetricCard.js +8 -8
  185. package/web-dist/components/missing-element/MissingElement.js +3 -3
  186. package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +9 -9
  187. package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +9 -9
  188. package/web-dist/components/opening-book/OpeningBook.js +1 -1
  189. package/web-dist/components/otp-form/OtpForm.js +9 -9
  190. package/web-dist/components/pagination/Pagination.js +3 -3
  191. package/web-dist/components/palette-item/PaletteItem.js +8 -8
  192. package/web-dist/components/playing-card/PlayingCard.js +1 -1
  193. package/web-dist/components/poker-training-table/PokerTrainingTable.js +1 -1
  194. package/web-dist/components/popover-menu/PopoverMenu.js +3 -3
  195. package/web-dist/components/post-card/PostCard.js +8 -8
  196. package/web-dist/components/product-card/ProductCard.js +8 -8
  197. package/web-dist/components/progress/Progress.js +3 -3
  198. package/web-dist/components/progress-ring/ProgressRing.js +3 -3
  199. package/web-dist/components/radio/Radio.js +4 -4
  200. package/web-dist/components/radio-group/RadioGroup.js +4 -4
  201. package/web-dist/components/rating/Rating.js +2 -2
  202. package/web-dist/components/reader/Reader.js +9 -9
  203. package/web-dist/components/scan-overlay/ScanOverlay.js +9 -9
  204. package/web-dist/components/screen/Screen.js +1 -1
  205. package/web-dist/components/screen-section/ScreenSection.js +3 -3
  206. package/web-dist/components/scroll-view/ScrollView.js +1 -1
  207. package/web-dist/components/search-input/SearchInput.js +3 -3
  208. package/web-dist/components/section-header/SectionHeader.js +3 -3
  209. package/web-dist/components/section-list/SectionList.js +4 -4
  210. package/web-dist/components/select/Select.js +3 -3
  211. package/web-dist/components/selectable-item/SelectableItem.js +1 -1
  212. package/web-dist/components/selection-provider/SelectionProvider.js +1 -1
  213. package/web-dist/components/sign-in-form/SignInForm.js +9 -9
  214. package/web-dist/components/sign-up-form/SignUpForm.js +9 -9
  215. package/web-dist/components/skeleton/Skeleton.js +11 -11
  216. package/web-dist/components/skeleton-card/SkeletonCard.js +11 -11
  217. package/web-dist/components/skeleton-list/SkeletonList.js +11 -11
  218. package/web-dist/components/skeleton-text/SkeletonText.js +11 -11
  219. package/web-dist/components/spatial-grid/SpatialGrid.d.ts +3 -0
  220. package/web-dist/components/spatial-grid/SpatialGrid.js +102 -0
  221. package/web-dist/components/spatial-grid/index.d.ts +1 -0
  222. package/web-dist/components/spatial-grid/index.js +2 -0
  223. package/web-dist/components/surface/Surface.js +1 -1
  224. package/web-dist/components/tab/Tab.js +1 -1
  225. package/web-dist/components/tab-list/TabList.js +1 -1
  226. package/web-dist/components/tab-panel/TabPanel.js +1 -1
  227. package/web-dist/components/tabletop-table/TabletopTable.js +1 -1
  228. package/web-dist/components/tabs/Tabs.js +1 -1
  229. package/web-dist/components/text/Text.js +1 -1
  230. package/web-dist/components/text-input/TextInput.js +3 -3
  231. package/web-dist/components/tile-grid/TileGrid.js +1 -1
  232. package/web-dist/components/time-picker/TimePicker.js +4 -4
  233. package/web-dist/components/timeline/Timeline.js +3 -3
  234. package/web-dist/components/toast/Toast.js +1 -1
  235. package/web-dist/components/toast-provider/ToastProvider.js +1 -1
  236. package/web-dist/components/toolbar/Toolbar.js +8 -8
  237. package/web-dist/components/tree-item/TreeItem.js +7 -7
  238. package/web-dist/components/uploader/Uploader.js +11 -11
  239. package/web-dist/components/view/View.js +1 -1
  240. package/web-dist/manifest.json +555 -493
  241. package/web-dist/runtime/ZoraProvider.js +3 -3
  242. /package/web-dist/chunks/{Accordion-qkh5yy94.js → Accordion-7kq500r1.js} +0 -0
  243. /package/web-dist/chunks/{Accordion-f0jsd9f9.js → Accordion-7tjz25jh.js} +0 -0
  244. /package/web-dist/chunks/{Accordion-3m3572sa.js → Accordion-88t8fgxv.js} +0 -0
  245. /package/web-dist/chunks/{Accordion-afmybp67.js → Accordion-9w8wg9mf.js} +0 -0
  246. /package/web-dist/chunks/{Accordion-bb8y34wh.js → Accordion-b96evb46.js} +0 -0
  247. /package/web-dist/chunks/{Accordion-nmpmdrba.js → Accordion-dbf93gxh.js} +0 -0
  248. /package/web-dist/chunks/{Accordion-x12fca21.js → Accordion-fhnazn3n.js} +0 -0
  249. /package/web-dist/chunks/{Accordion-n9c5tsqw.js → Accordion-qn398m1x.js} +0 -0
  250. /package/web-dist/chunks/{Accordion-2rgexkze.js → Accordion-rsvphbe4.js} +0 -0
  251. /package/web-dist/chunks/{Accordion-c69374jn.js → Accordion-sw7ep29d.js} +0 -0
  252. /package/web-dist/chunks/{Accordion-8jxc7tx9.js → Accordion-w6qedeba.js} +0 -0
@@ -0,0 +1,248 @@
1
+ import { join } from 'node:path';
2
+ import { pathToFileURL } from 'node:url';
3
+
4
+ import { expect, test } from 'bun:test';
5
+ import { Window } from 'happy-dom';
6
+ import React, { act } from 'react';
7
+ import { createRoot } from 'react-dom/client';
8
+ import { renderToStaticMarkup } from 'react-dom/server';
9
+
10
+ import type { SpatialGrid as SpatialGridComponent } from './SpatialGrid';
11
+
12
+ const webDistRoot = join(import.meta.dir, '../../../../../web-dist');
13
+
14
+ /** Loads the independently bundled React Native Web component through its public artifact path. */
15
+ function loadSpatialGrid() {
16
+ return import(
17
+ pathToFileURL(join(webDistRoot, 'components/spatial-grid/index.js')).href
18
+ ) as Promise<{
19
+ SpatialGrid: typeof SpatialGridComponent;
20
+ }>;
21
+ }
22
+
23
+ test('renders a bounded, accessible 10k free-placement catalog in deterministic overlap order', async () => {
24
+ const items = [
25
+ { height: 30, id: 'back', width: 30, x: 0, y: 0, zIndex: -1 },
26
+ { height: 30, id: 'front', width: 30, x: 0, y: 0, zIndex: 1 },
27
+ ...Array.from({ length: 9998 }, (_, index) => ({
28
+ height: 20,
29
+ id: `item-${index}`,
30
+ width: 20,
31
+ x: 1000 + (index % 100) * 100,
32
+ y: 1000 + Math.floor(index / 100) * 100,
33
+ })),
34
+ ];
35
+ await withBrowserRoot(async (browserWindow) => {
36
+ const { SpatialGrid } = await loadSpatialGrid();
37
+ browserWindow.document.body.innerHTML = renderToStaticMarkup(
38
+ <SpatialGrid
39
+ contentHeight={11000}
40
+ contentWidth={11000}
41
+ height={100}
42
+ items={items}
43
+ selectedItemId="front"
44
+ testID="board"
45
+ width={100}
46
+ zoom={2}
47
+ renderItem={(item) => <span>{item.id}</span>}
48
+ />,
49
+ );
50
+ const mounted = [...browserWindow.document.querySelectorAll('[data-testid^="board-item-"]')];
51
+
52
+ expect(mounted).toHaveLength(2);
53
+ expect(mounted.map((element) => element.getAttribute('data-testid'))).toEqual([
54
+ 'board-item-back',
55
+ 'board-item-front',
56
+ ]);
57
+ expect(
58
+ browserWindow.document
59
+ .querySelector('[data-testid="board-item-front"]')
60
+ ?.getAttribute('role'),
61
+ ).toBe('button');
62
+ expect(
63
+ browserWindow.document
64
+ .querySelector('[data-testid="board-item-front"]')
65
+ ?.getAttribute('tabindex'),
66
+ ).toBe('0');
67
+ expect(
68
+ browserWindow.document
69
+ .querySelector('[data-testid="board-item-front"]')
70
+ ?.getAttribute('aria-label'),
71
+ ).toBe('Spatial grid item front');
72
+ });
73
+ });
74
+
75
+ test('activates the topmost overlapping item by pointer and keyboard', async () => {
76
+ const { SpatialGrid } = await loadSpatialGrid();
77
+ const selection: string[] = [];
78
+ const activation: string[] = [];
79
+ await withBrowserRoot(async (browserWindow, host, root) => {
80
+ await renderSpatialGrid(
81
+ root,
82
+ <SpatialGrid
83
+ contentHeight={100}
84
+ contentWidth={100}
85
+ height={100}
86
+ items={[
87
+ { height: 50, id: 'back', width: 50, x: 10, y: 20, zIndex: -1 },
88
+ { height: 50, id: 'front', width: 50, x: 10, y: 20, zIndex: 1 },
89
+ ]}
90
+ testID="interactive-board"
91
+ width={100}
92
+ onActivation={(id) => activation.push(id)}
93
+ onSelectionChange={(id) => selection.push(id)}
94
+ renderItem={(item) => <span>{item.id}</span>}
95
+ />,
96
+ );
97
+ const front = requireItem(host, 'interactive-board-item-front');
98
+ await dispatch(front, new browserWindow.MouseEvent('click', { bubbles: true }));
99
+ await dispatch(
100
+ front,
101
+ new browserWindow.KeyboardEvent('keydown', { bubbles: true, key: 'Enter' }),
102
+ );
103
+ await dispatch(
104
+ front,
105
+ new browserWindow.KeyboardEvent('keyup', { bubbles: true, key: 'Enter' }),
106
+ );
107
+ // happy-dom does not synthesize the browser click dispatched for an activated button.
108
+ await dispatch(front, new browserWindow.MouseEvent('click', { bubbles: true }));
109
+ expect(selection).toEqual(['front', 'front']);
110
+ expect(activation).toEqual(['front', 'front']);
111
+ });
112
+ });
113
+
114
+ test('separates disabled, read-only, and passive interaction behavior', async () => {
115
+ const { SpatialGrid } = await loadSpatialGrid();
116
+ const selection: string[] = [];
117
+ const activation: string[] = [];
118
+ const focus: string[] = [];
119
+ await withBrowserRoot(async (browserWindow, host, root) => {
120
+ const render = (
121
+ props: Pick<
122
+ React.ComponentProps<typeof SpatialGrid>,
123
+ 'disabled' | 'readOnly' | 'interactionPolicy'
124
+ >,
125
+ ) => (
126
+ <SpatialGrid
127
+ contentHeight={100}
128
+ contentWidth={100}
129
+ height={100}
130
+ items={[{ height: 50, id: 'node', width: 50, x: 10, y: 20 }]}
131
+ testID="interactive-board"
132
+ width={100}
133
+ onActivation={(id) => activation.push(id)}
134
+ onFocusChange={(id) => focus.push(id)}
135
+ onSelectionChange={(id) => selection.push(id)}
136
+ renderItem={(item) => <span>{item.id}</span>}
137
+ {...props}
138
+ />
139
+ );
140
+ for (const props of [
141
+ { disabled: true },
142
+ { readOnly: true },
143
+ { interactionPolicy: 'passive' as const },
144
+ ]) {
145
+ await renderSpatialGrid(root, render(props));
146
+ const item = requireItem(host, 'interactive-board-item-node');
147
+ await dispatch(item, new browserWindow.FocusEvent('focusin', { bubbles: true }));
148
+ await dispatch(item, new browserWindow.MouseEvent('click', { bubbles: true }));
149
+ }
150
+
151
+ expect(selection).toEqual([]);
152
+ expect(activation).toEqual([]);
153
+ expect(focus).toEqual(['node']);
154
+ });
155
+ });
156
+
157
+ test('reveals a focused offscreen item through the composed GridView viewport', async () => {
158
+ const { SpatialGrid } = await loadSpatialGrid();
159
+ await withBrowserRoot(async (_browserWindow, host, root) => {
160
+ const scrollCalls: unknown[] = [];
161
+ const render = (focusedItemId?: string) => (
162
+ <SpatialGrid
163
+ contentHeight={1000}
164
+ contentWidth={1000}
165
+ focusedItemId={focusedItemId}
166
+ height={100}
167
+ items={[{ height: 20, id: 'distant', width: 20, x: 400, y: 500 }]}
168
+ revealPaddingPixels={10}
169
+ width={100}
170
+ renderItem={(item) => <span>{item.id}</span>}
171
+ />
172
+ );
173
+ await renderSpatialGrid(root, render());
174
+ const scrollableNodes = [...host.querySelectorAll('div')] as HTMLElement[];
175
+ for (const node of scrollableNodes) {
176
+ node.scrollTo = (options: unknown) => scrollCalls.push(options);
177
+ }
178
+ await renderSpatialGrid(root, render('distant'));
179
+
180
+ expect(scrollCalls).toContainEqual({ animated: true, x: 330 });
181
+ expect(scrollCalls).toContainEqual({ animated: true, y: 430 });
182
+ });
183
+ });
184
+
185
+ /** Runs a mounted RNW test with its DOM globals restored after the assertion. */
186
+ async function withBrowserRoot(
187
+ callback: (
188
+ browserWindow: Window,
189
+ host: HTMLDivElement,
190
+ root: ReturnType<typeof createRoot>,
191
+ ) => Promise<void>,
192
+ ) {
193
+ const browserWindow = new Window();
194
+ const keys = [
195
+ 'window',
196
+ 'document',
197
+ 'Node',
198
+ 'navigator',
199
+ 'ShadowRoot',
200
+ 'IS_REACT_ACT_ENVIRONMENT',
201
+ ] as const;
202
+ const previous = keys.map(
203
+ (key) => [key, Object.getOwnPropertyDescriptor(globalThis, key)] as const,
204
+ );
205
+ Object.assign(globalThis, {
206
+ IS_REACT_ACT_ENVIRONMENT: true,
207
+ window: browserWindow,
208
+ document: browserWindow.document,
209
+ Node: browserWindow.Node,
210
+ navigator: browserWindow.navigator,
211
+ ShadowRoot: browserWindow.ShadowRoot,
212
+ });
213
+ const host = document.createElement('div');
214
+ document.body.appendChild(host);
215
+ const root = createRoot(host);
216
+
217
+ try {
218
+ await callback(browserWindow, host, root);
219
+ } finally {
220
+ await act(() => Promise.resolve().then(() => root.unmount()));
221
+ browserWindow.close();
222
+ for (const [key, descriptor] of previous) {
223
+ if (descriptor) Object.defineProperty(globalThis, key, descriptor);
224
+ else Reflect.deleteProperty(globalThis, key);
225
+ }
226
+ }
227
+ }
228
+
229
+ /** Renders a component through React's mounted interaction boundary. */
230
+ function renderSpatialGrid(root: ReturnType<typeof createRoot>, component: React.ReactNode) {
231
+ return act(() => Promise.resolve().then(() => root.render(component)));
232
+ }
233
+
234
+ /** Retrieves one mounted item by its stable test identifier. */
235
+ function requireItem(host: HTMLDivElement, testID: string): HTMLElement {
236
+ const item = host.querySelector(`[data-testid="${testID}"]`);
237
+ if (!item) throw new Error(`SpatialGrid did not render ${testID}.`);
238
+ return item as HTMLElement;
239
+ }
240
+
241
+ /** Dispatches one mounted native-web event through React's synthetic event boundary. */
242
+ function dispatch(target: EventTarget, event: Event) {
243
+ return act(() =>
244
+ Promise.resolve().then(() => {
245
+ target.dispatchEvent(event);
246
+ }),
247
+ );
248
+ }
@@ -0,0 +1,112 @@
1
+ import React from 'react';
2
+ import { Pressable as NativePressable, View as NativeView } from 'react-native';
3
+
4
+ import type { SpatialGridItem, SpatialGridProps } from '../../../../types/spatial-grid';
5
+ import { GridView } from '../../../grid-view/public';
6
+ import { sortSpatialGridItems } from '../../application/sortSpatialGridItems';
7
+
8
+ /** Renders virtualized free-placement items without owning geometry, pan, zoom, or drag orchestration. */
9
+ export function SpatialGrid({
10
+ items,
11
+ contentWidth,
12
+ contentHeight,
13
+ width,
14
+ height,
15
+ zoom,
16
+ overscanPixels,
17
+ selectedItemId,
18
+ focusedItemId,
19
+ revealPaddingPixels,
20
+ disabled = false,
21
+ readOnly = false,
22
+ interactionPolicy,
23
+ onSelectionChange,
24
+ onActivation,
25
+ onFocusChange,
26
+ onViewportChange,
27
+ onVisibleItemIdsChange,
28
+ renderItem,
29
+ testID,
30
+ }: SpatialGridProps) {
31
+ const orderedItems = React.useMemo(() => sortSpatialGridItems(items), [items]);
32
+ const itemLookup = React.useMemo(
33
+ () => new Map(orderedItems.map((item) => [item.id, item])),
34
+ [orderedItems],
35
+ );
36
+ const interactionBlocked = disabled || interactionPolicy === 'passive';
37
+
38
+ return (
39
+ <NativeView style={{ height, overflow: 'hidden', width }} testID={testID}>
40
+ <GridView
41
+ contentHeight={contentHeight}
42
+ contentWidth={contentWidth}
43
+ focusedItemId={focusedItemId ?? selectedItemId}
44
+ height={height}
45
+ interactionPolicy={interactionPolicy}
46
+ items={orderedItems}
47
+ onViewportChange={onViewportChange}
48
+ onVisibleItemIdsChange={onVisibleItemIdsChange}
49
+ overscanPixels={overscanPixels}
50
+ renderItem={(gridItem) => {
51
+ const item = itemLookup.get(gridItem.id);
52
+ if (!item) return null;
53
+ return renderSpatialGridItem(
54
+ item,
55
+ item.id === selectedItemId,
56
+ item.id === focusedItemId,
57
+ interactionBlocked,
58
+ readOnly,
59
+ onSelectionChange,
60
+ onActivation,
61
+ onFocusChange,
62
+ renderItem,
63
+ testID,
64
+ );
65
+ }}
66
+ revealPaddingPixels={revealPaddingPixels}
67
+ width={width}
68
+ zoom={zoom}
69
+ />
70
+ </NativeView>
71
+ );
72
+ }
73
+
74
+ /** Adds serializable selection, activation, and focus boundaries around a caller-rendered item. */
75
+ function renderSpatialGridItem(
76
+ item: SpatialGridItem,
77
+ selected: boolean,
78
+ focused: boolean,
79
+ interactionBlocked: boolean,
80
+ readOnly: boolean,
81
+ onSelectionChange: SpatialGridProps['onSelectionChange'],
82
+ onActivation: SpatialGridProps['onActivation'],
83
+ onFocusChange: SpatialGridProps['onFocusChange'],
84
+ renderItem: SpatialGridProps['renderItem'],
85
+ testID: string | undefined,
86
+ ) {
87
+ const interactionDisabled = interactionBlocked || item.disabled === true;
88
+ const editingDisabled = interactionDisabled || readOnly;
89
+ return (
90
+ <NativePressable
91
+ accessibilityLabel={item.accessibilityLabel ?? `Spatial grid item ${item.id}`}
92
+ accessibilityRole="button"
93
+ accessibilityState={{ disabled: editingDisabled, selected }}
94
+ disabled={interactionDisabled}
95
+ style={{ height: '100%', width: '100%' }}
96
+ testID={testID === undefined ? undefined : `${testID}-item-${item.id}`}
97
+ onFocus={() => {
98
+ if (!interactionDisabled) onFocusChange?.(item.id);
99
+ }}
100
+ onLongPress={() => {
101
+ if (!editingDisabled) onActivation?.(item.id);
102
+ }}
103
+ onPress={() => {
104
+ if (editingDisabled) return;
105
+ onSelectionChange?.(item.id);
106
+ onActivation?.(item.id);
107
+ }}
108
+ >
109
+ {renderItem(item, { disabled: editingDisabled, focused, selected })}
110
+ </NativePressable>
111
+ );
112
+ }
@@ -0,0 +1,42 @@
1
+ import { getVisibleGridItems } from '@ankhorage/grid-view';
2
+ import { describe, expect, test } from 'bun:test';
3
+
4
+ import { sortSpatialGridItems } from './sortSpatialGridItems';
5
+
6
+ describe('SpatialGrid presentation', () => {
7
+ test('preserves free world rectangles and establishes deterministic overlap hit order', () => {
8
+ const ordered = sortSpatialGridItems([
9
+ { height: 40, id: 'middle', width: 40, x: 24, y: 18 },
10
+ { height: 30, id: 'back', width: 30, x: 16, y: 12, zIndex: -1 },
11
+ { height: 20, id: 'front', width: 20, x: 24, y: 18, zIndex: 2 },
12
+ { height: 10, id: 'front-later', width: 10, x: 24, y: 18, zIndex: 2 },
13
+ ]);
14
+
15
+ expect(ordered.map((item) => item.id)).toEqual(['back', 'middle', 'front', 'front-later']);
16
+ expect(ordered[1]).toMatchObject({ height: 40, width: 40, x: 24, y: 18 });
17
+ });
18
+
19
+ test('keeps a 10k free-placement catalogue bounded to the viewport subset', () => {
20
+ const items = sortSpatialGridItems(
21
+ Array.from({ length: 10000 }, (_, index) => ({
22
+ height: 20,
23
+ id: `item-${index}`,
24
+ width: 20,
25
+ x: (index % 100) * 100,
26
+ y: Math.floor(index / 100) * 100,
27
+ })),
28
+ );
29
+
30
+ const visible = getVisibleGridItems(items, {
31
+ height: 160,
32
+ offsetX: 0,
33
+ offsetY: 0,
34
+ pixelsPerUnitX: 1,
35
+ pixelsPerUnitY: 1,
36
+ width: 160,
37
+ });
38
+
39
+ expect(visible).toHaveLength(4);
40
+ expect(visible.map((item) => item.id)).toEqual(['item-0', 'item-1', 'item-100', 'item-101']);
41
+ });
42
+ });
@@ -0,0 +1,14 @@
1
+ import type { SpatialGridItem } from '../../../types/spatial-grid';
2
+
3
+ /** Orders free-placement items for deterministic paint and overlap hit-testing. */
4
+ export function sortSpatialGridItems(
5
+ items: readonly SpatialGridItem[],
6
+ ): readonly SpatialGridItem[] {
7
+ return [...items]
8
+ .map((item, index) => ({ index, item }))
9
+ .sort(
10
+ (left, right) =>
11
+ (left.item.zIndex ?? 0) - (right.item.zIndex ?? 0) || left.index - right.index,
12
+ )
13
+ .map(({ item }) => item);
14
+ }
@@ -0,0 +1,12 @@
1
+ import type { ZoraComponentMeta } from '../../types/authoring';
2
+
3
+ /** Free-placement rendering requires a caller-owned React renderer and is therefore code-only. */
4
+ export const spatialGridMeta = {
5
+ name: 'SpatialGrid',
6
+ category: 'foundation',
7
+ description: 'Virtualized free-placement board. Item rendering belongs to the code API.',
8
+ directManifestNode: false,
9
+ note: 'SpatialGrid requires a caller-owned React item renderer and cannot be serialized as a manifest node.',
10
+ allowedChildren: [],
11
+ props: {},
12
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,6 @@
1
+ export type {
2
+ SpatialGridItem,
3
+ SpatialGridItemState,
4
+ SpatialGridProps,
5
+ } from '../../types/spatial-grid';
6
+ export { SpatialGrid } from './adapters/inbound/SpatialGrid';
package/src/index.ts CHANGED
@@ -263,6 +263,14 @@ export type {
263
263
  GradientRendererProviderProps,
264
264
  } from './features/gradient/public';
265
265
  export { Gradient, GradientRendererProvider } from './features/gradient/public';
266
+ export type {
267
+ GridGuide,
268
+ GridLineOverlayProps,
269
+ GridRulerMark,
270
+ GridRulerProps,
271
+ GridRulerTickSource,
272
+ } from './features/grid-rulers/public';
273
+ export { GridLineOverlay, GridRuler, resolveGridRulerMarks } from './features/grid-rulers/public';
266
274
  export type { GridViewProps, TileGridItem, TileGridProps } from './features/grid-view/public';
267
275
  export { GridView, layoutTileGrid, TileGrid } from './features/grid-view/public';
268
276
  export {
@@ -408,6 +416,12 @@ export {
408
416
  SkeletonText,
409
417
  type SkeletonTextProps,
410
418
  } from './features/skeleton/public';
419
+ export type {
420
+ SpatialGridItem,
421
+ SpatialGridItemState,
422
+ SpatialGridProps,
423
+ } from './features/spatial-grid/public';
424
+ export { SpatialGrid } from './features/spatial-grid/public';
411
425
  export type { SurfaceProps, SurfaceVariant } from './features/surface/public';
412
426
  export { Surface } from './features/surface/public';
413
427
  export type {
@@ -0,0 +1,59 @@
1
+ import type {
2
+ GridAxisCategory,
3
+ GridAxisName,
4
+ GridAxisTick,
5
+ GridTickProvider,
6
+ GridTickSpecification,
7
+ GridViewport,
8
+ } from '@ankhorage/grid-view';
9
+
10
+ import type { ZoraBaseProps } from './base';
11
+
12
+ /** A tick source is display-only; it never configures interaction snapping. */
13
+ export type GridRulerTickSource =
14
+ | {
15
+ readonly kind: 'ticks';
16
+ readonly specification: GridTickSpecification;
17
+ readonly provider?: GridTickProvider;
18
+ }
19
+ | { readonly kind: 'categories'; readonly categories: readonly GridAxisCategory[] };
20
+
21
+ /** A projected mark is measured in viewport pixels from the supplied viewport's origin. */
22
+ export interface GridRulerMark {
23
+ readonly position: number;
24
+ readonly level: GridAxisTick['level'];
25
+ readonly label?: string;
26
+ readonly categoryId?: string;
27
+ }
28
+
29
+ /** A passive guide belongs to one world-space axis. */
30
+ export interface GridGuide {
31
+ readonly id: string;
32
+ readonly axis: GridAxisName;
33
+ readonly position: number;
34
+ readonly label?: string;
35
+ }
36
+
37
+ /** A single horizontal or vertical passive ruler strip. */
38
+ export interface GridRulerProps extends ZoraBaseProps {
39
+ readonly axis: GridAxisName;
40
+ readonly viewport: GridViewport;
41
+ readonly tickSource: GridRulerTickSource;
42
+ readonly thickness?: number;
43
+ readonly offset?: number;
44
+ readonly position?: 'start' | 'end';
45
+ readonly direction?: 'ltr' | 'rtl';
46
+ readonly accessibilityLabel?: string;
47
+ readonly formatLabel?: (tick: GridAxisTick) => string | undefined;
48
+ }
49
+
50
+ /** A passive overlay of visible major/minor grid lines and explicit guides. */
51
+ export interface GridLineOverlayProps extends ZoraBaseProps {
52
+ readonly viewport: GridViewport;
53
+ /** Mirrors horizontal world positions using the same projection as an RTL GridRuler. */
54
+ readonly direction?: 'ltr' | 'rtl';
55
+ readonly xTickSource?: GridRulerTickSource;
56
+ readonly yTickSource?: GridRulerTickSource;
57
+ readonly guides?: readonly GridGuide[];
58
+ readonly accessibilityLabel?: string;
59
+ }
@@ -0,0 +1,44 @@
1
+ import type { GridRectItem, GridViewport } from '@ankhorage/grid-view';
2
+ import type React from 'react';
3
+
4
+ import type { ZoraBaseProps } from './base';
5
+
6
+ /** A free-positioned item retains the grid-view world rectangle and adds presentation policy. */
7
+ export interface SpatialGridItem extends GridRectItem {
8
+ /** Higher values are painted and hit-tested above lower values; equal values preserve input order. */
9
+ readonly zIndex?: number;
10
+ /** Accessible name for the item; defaults to a stable ID-derived board-item name. */
11
+ readonly accessibilityLabel?: string;
12
+ /** Prevents selection and activation for this item while keeping it visible. */
13
+ readonly disabled?: boolean;
14
+ }
15
+
16
+ /** State supplied to the code-only item renderer. */
17
+ export interface SpatialGridItemState {
18
+ readonly selected: boolean;
19
+ readonly focused: boolean;
20
+ readonly disabled: boolean;
21
+ }
22
+
23
+ /** Props for the virtualized, free-placement presentation over canonical GridView geometry. */
24
+ export interface SpatialGridProps extends ZoraBaseProps {
25
+ readonly items: readonly SpatialGridItem[];
26
+ readonly contentWidth: number;
27
+ readonly contentHeight: number;
28
+ readonly width: number;
29
+ readonly height: number;
30
+ readonly zoom?: number;
31
+ readonly overscanPixels?: number;
32
+ readonly selectedItemId?: string;
33
+ readonly focusedItemId?: string;
34
+ readonly revealPaddingPixels?: number;
35
+ readonly disabled?: boolean;
36
+ /** Prevents selection and activation while retaining focus and viewport navigation. */
37
+ readonly readOnly?: boolean;
38
+ readonly onSelectionChange?: (id: string) => void;
39
+ readonly onActivation?: (id: string) => void;
40
+ readonly onFocusChange?: (id: string) => void;
41
+ readonly onViewportChange?: (viewport: GridViewport) => void;
42
+ readonly onVisibleItemIdsChange?: (ids: readonly string[]) => void;
43
+ readonly renderItem: (item: SpatialGridItem, state: SpatialGridItemState) => React.ReactNode;
44
+ }
@@ -20,11 +20,11 @@ import {
20
20
  } from "./Accordion-42jfy1a1.js";
21
21
  import {
22
22
  View2
23
- } from "./Accordion-f0jsd9f9.js";
23
+ } from "./Accordion-7tjz25jh.js";
24
24
  import {
25
25
  Heading2,
26
26
  Text3
27
- } from "./Accordion-afmybp67.js";
27
+ } from "./Accordion-9w8wg9mf.js";
28
28
  import {
29
29
  resolveOverlayAnimation
30
30
  } from "./Accordion-n7y08rz5.js";
@@ -7,16 +7,16 @@ import {
7
7
  } from "./Accordion-42jfy1a1.js";
8
8
  import {
9
9
  View2
10
- } from "./Accordion-f0jsd9f9.js";
10
+ } from "./Accordion-7tjz25jh.js";
11
11
  import {
12
12
  Text3
13
- } from "./Accordion-afmybp67.js";
13
+ } from "./Accordion-9w8wg9mf.js";
14
14
  import {
15
15
  Avatar2
16
- } from "./Accordion-wgejzesa.js";
16
+ } from "./Accordion-61ntvh14.js";
17
17
  import {
18
18
  Badge2
19
- } from "./Accordion-qkh5yy94.js";
19
+ } from "./Accordion-7kq500r1.js";
20
20
  import {
21
21
  useZoraTheme2
22
22
  } from "./Accordion-srjya6dz.js";
@@ -1,16 +1,16 @@
1
1
  'use client';
2
2
  import {
3
3
  Button2
4
- } from "./Accordion-q09fjenx.js";
4
+ } from "./Accordion-6rrqpb2h.js";
5
5
  import {
6
6
  withZoraThemeScope
7
7
  } from "./Accordion-42jfy1a1.js";
8
8
  import {
9
9
  View2
10
- } from "./Accordion-f0jsd9f9.js";
10
+ } from "./Accordion-7tjz25jh.js";
11
11
  import {
12
12
  Text3
13
- } from "./Accordion-afmybp67.js";
13
+ } from "./Accordion-9w8wg9mf.js";
14
14
  import {
15
15
  useZoraTheme2
16
16
  } from "./Accordion-srjya6dz.js";
@@ -1,22 +1,22 @@
1
1
  'use client';
2
2
  import {
3
3
  Button2
4
- } from "./Accordion-q09fjenx.js";
4
+ } from "./Accordion-6rrqpb2h.js";
5
5
  import {
6
6
  withZoraThemeScope
7
7
  } from "./Accordion-42jfy1a1.js";
8
8
  import {
9
9
  View2
10
- } from "./Accordion-f0jsd9f9.js";
10
+ } from "./Accordion-7tjz25jh.js";
11
11
  import {
12
12
  Card2
13
- } from "./Accordion-xvzrx6bh.js";
13
+ } from "./Accordion-fjxcn6g9.js";
14
14
  import {
15
15
  Text3
16
- } from "./Accordion-afmybp67.js";
16
+ } from "./Accordion-9w8wg9mf.js";
17
17
  import {
18
18
  Badge2
19
- } from "./Accordion-qkh5yy94.js";
19
+ } from "./Accordion-7kq500r1.js";
20
20
  import {
21
21
  useZoraTheme2
22
22
  } from "./Accordion-srjya6dz.js";
@@ -4,16 +4,16 @@ import {
4
4
  } from "./Accordion-42jfy1a1.js";
5
5
  import {
6
6
  View2
7
- } from "./Accordion-f0jsd9f9.js";
7
+ } from "./Accordion-7tjz25jh.js";
8
8
  import {
9
9
  ButtonGroup2
10
- } from "./Accordion-q09fjenx.js";
10
+ } from "./Accordion-6rrqpb2h.js";
11
11
  import {
12
12
  Card2
13
- } from "./Accordion-xvzrx6bh.js";
13
+ } from "./Accordion-fjxcn6g9.js";
14
14
  import {
15
15
  List2
16
- } from "./Accordion-sdcfa14w.js";
16
+ } from "./Accordion-5g05kfmx.js";
17
17
  import {
18
18
  useZoraTheme2
19
19
  } from "./Accordion-srjya6dz.js";