@ankhorage/zora 25.7.0 → 25.8.1

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 (311) hide show
  1. package/CHANGELOG.md +37 -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 +6170 -59
  6. package/dist/capabilities/index.js.map +119 -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/grid-interactions/adapters/inbound/GridInteractions.d.ts +5 -0
  12. package/dist/features/grid-interactions/adapters/inbound/GridInteractions.d.ts.map +1 -0
  13. package/dist/features/grid-interactions/adapters/inbound/GridInteractions.js +40 -0
  14. package/dist/features/grid-interactions/adapters/inbound/GridInteractions.js.map +1 -0
  15. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.d.ts +2 -0
  16. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.d.ts.map +1 -0
  17. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.js +2 -0
  18. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.js.map +1 -0
  19. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.d.ts +11 -0
  20. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.d.ts.map +1 -0
  21. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.js +5 -0
  22. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.js.map +1 -0
  23. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.d.ts +11 -0
  24. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.d.ts.map +1 -0
  25. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.js +20 -0
  26. package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.js.map +1 -0
  27. package/dist/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.d.ts +17 -0
  28. package/dist/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.d.ts.map +1 -0
  29. package/dist/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.js +76 -0
  30. package/dist/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.js.map +1 -0
  31. package/dist/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.d.ts +21 -0
  32. package/dist/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.d.ts.map +1 -0
  33. package/dist/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.js +20 -0
  34. package/dist/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.js.map +1 -0
  35. package/dist/features/grid-interactions/application/createGridInteractionsController.d.ts +4 -0
  36. package/dist/features/grid-interactions/application/createGridInteractionsController.d.ts.map +1 -0
  37. package/dist/features/grid-interactions/application/createGridInteractionsController.js +200 -0
  38. package/dist/features/grid-interactions/application/createGridInteractionsController.js.map +1 -0
  39. package/dist/features/grid-interactions/meta.d.ts +11 -0
  40. package/dist/features/grid-interactions/meta.d.ts.map +1 -0
  41. package/dist/features/grid-interactions/meta.js +11 -0
  42. package/dist/features/grid-interactions/meta.js.map +1 -0
  43. package/dist/features/grid-interactions/public.d.ts +4 -0
  44. package/dist/features/grid-interactions/public.d.ts.map +1 -0
  45. package/dist/features/grid-interactions/public.js +3 -0
  46. package/dist/features/grid-interactions/public.js.map +1 -0
  47. package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.d.ts.map +1 -1
  48. package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.js +73 -19
  49. package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.js.map +1 -1
  50. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.d.ts +9 -0
  51. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.d.ts.map +1 -0
  52. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.js +5 -0
  53. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.js.map +1 -0
  54. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.d.ts +9 -0
  55. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.d.ts.map +1 -0
  56. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.js +5 -0
  57. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.js.map +1 -0
  58. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.d.ts +9 -0
  59. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.d.ts.map +1 -0
  60. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.js +28 -0
  61. package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.js.map +1 -0
  62. package/dist/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.d.ts +14 -0
  63. package/dist/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.d.ts.map +1 -0
  64. package/dist/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.js +50 -0
  65. package/dist/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.js.map +1 -0
  66. package/dist/features/matrix-grid/application/createMatrixGridSparseIndex.d.ts +18 -0
  67. package/dist/features/matrix-grid/application/createMatrixGridSparseIndex.d.ts.map +1 -0
  68. package/dist/features/matrix-grid/application/createMatrixGridSparseIndex.js +56 -0
  69. package/dist/features/matrix-grid/application/createMatrixGridSparseIndex.js.map +1 -0
  70. package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.d.ts +4 -0
  71. package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.d.ts.map +1 -0
  72. package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.js +65 -0
  73. package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.js.map +1 -0
  74. package/dist/features/matrix-grid/application/resolveMatrixGridSelection.d.ts +8 -1
  75. package/dist/features/matrix-grid/application/resolveMatrixGridSelection.d.ts.map +1 -1
  76. package/dist/features/matrix-grid/application/resolveMatrixGridSelection.js +15 -4
  77. package/dist/features/matrix-grid/application/resolveMatrixGridSelection.js.map +1 -1
  78. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.d.ts.map +1 -1
  79. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js +2 -0
  80. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js.map +1 -1
  81. package/dist/features/registry/componentMeta.d.ts.map +1 -1
  82. package/dist/features/registry/componentMeta.js +2 -0
  83. package/dist/features/registry/componentMeta.js.map +1 -1
  84. package/dist/features/registry/createEventCapabilities.d.ts +4 -0
  85. package/dist/features/registry/createEventCapabilities.d.ts.map +1 -0
  86. package/dist/features/registry/createEventCapabilities.js +76 -0
  87. package/dist/features/registry/createEventCapabilities.js.map +1 -0
  88. package/dist/index.d.ts +1 -0
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +1 -0
  91. package/dist/index.js.map +1 -1
  92. package/dist/types/grid-interactions.d.ts +58 -0
  93. package/dist/types/grid-interactions.d.ts.map +1 -0
  94. package/dist/types/grid-interactions.js +2 -0
  95. package/dist/types/grid-interactions.js.map +1 -0
  96. package/dist/types/matrix-grid.d.ts +2 -0
  97. package/dist/types/matrix-grid.d.ts.map +1 -1
  98. package/dist/types/matrix-grid.js.map +1 -1
  99. package/package.json +1825 -7
  100. package/src/capabilities/index.test.ts +87 -15
  101. package/src/capabilities/index.ts +5 -2
  102. package/src/cli/index.test.ts +5 -3
  103. package/src/cli/index.ts +5 -2
  104. package/src/features/grid-interactions/adapters/inbound/GridInteractions.test.tsx +143 -0
  105. package/src/features/grid-interactions/adapters/inbound/GridInteractions.tsx +79 -0
  106. package/src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.tsx +14 -0
  107. package/src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.tsx +1 -0
  108. package/src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.tsx +41 -0
  109. package/src/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.test.ts +98 -0
  110. package/src/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.ts +94 -0
  111. package/src/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.test.ts +33 -0
  112. package/src/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.ts +45 -0
  113. package/src/features/grid-interactions/application/createGridInteractionsController.test.ts +229 -0
  114. package/src/features/grid-interactions/application/createGridInteractionsController.ts +248 -0
  115. package/src/features/grid-interactions/meta.ts +12 -0
  116. package/src/features/grid-interactions/public.ts +11 -0
  117. package/src/features/matrix-grid/adapters/inbound/MatrixGrid.test.tsx +280 -2
  118. package/src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx +121 -31
  119. package/src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.tsx +11 -0
  120. package/src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.tsx +11 -0
  121. package/src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.tsx +43 -0
  122. package/src/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.ts +70 -0
  123. package/src/features/matrix-grid/application/createMatrixGridSparseIndex.test.ts +35 -0
  124. package/src/features/matrix-grid/application/createMatrixGridSparseIndex.ts +105 -0
  125. package/src/features/matrix-grid/application/getMatrixGridNextFocusId.test.ts +93 -0
  126. package/src/features/matrix-grid/application/getMatrixGridNextFocusId.ts +112 -0
  127. package/src/features/matrix-grid/application/resolveMatrixGridSelection.test.ts +63 -2
  128. package/src/features/matrix-grid/application/resolveMatrixGridSelection.ts +27 -4
  129. package/src/features/registry/ZORA_COMPONENT_REGISTRY.ts +2 -0
  130. package/src/features/registry/componentMeta.ts +2 -0
  131. package/src/features/registry/createEventCapabilities.ts +108 -0
  132. package/src/index.ts +11 -0
  133. package/src/structureOwnership.test.ts +5 -0
  134. package/src/types/grid-interactions.ts +72 -0
  135. package/src/types/matrix-grid.ts +2 -0
  136. package/web-dist/chunks/{Accordion-5g05kfmx.js → Accordion-0q2wzjdd.js} +4 -4
  137. package/web-dist/chunks/{Accordion-b96evb46.js → Accordion-1fsrnq73.js} +1 -1
  138. package/web-dist/chunks/{Accordion-h3y8qev2.js → Accordion-38ts3gnn.js} +2 -2
  139. package/web-dist/chunks/{Accordion-jnc315h7.js → Accordion-8pkw32q9.js} +2 -2
  140. package/web-dist/chunks/{Accordion-h7zsx9eg.js → Accordion-9jrxktne.js} +3 -3
  141. package/web-dist/chunks/{Accordion-9w8wg9mf.js → Accordion-9rnsg9pk.js} +1 -1
  142. package/web-dist/chunks/{Accordion-4zqd7twp.js → Accordion-9ygakvwk.js} +5 -5
  143. package/web-dist/chunks/{Accordion-fhnazn3n.js → Accordion-b74j4hdt.js} +1 -1
  144. package/web-dist/chunks/{Accordion-nssr5gep.js → Accordion-c50pywj3.js} +2 -2
  145. package/web-dist/chunks/{Accordion-pvj5npzc.js → Accordion-ddrn94v3.js} +3 -3
  146. package/web-dist/chunks/{Accordion-090y18cv.js → Accordion-dk0dtyc0.js} +3 -3
  147. package/web-dist/chunks/{Accordion-59pa0677.js → Accordion-fcczvwgg.js} +0 -1
  148. package/web-dist/chunks/{Accordion-sp4k08kw.js → Accordion-geah5s4f.js} +4 -4
  149. package/web-dist/chunks/{Accordion-6rrqpb2h.js → Accordion-h4ekm5cp.js} +2 -2
  150. package/web-dist/chunks/{Accordion-3d4wkzg7.js → Accordion-hecpczme.js} +5 -5
  151. package/web-dist/chunks/{Accordion-a6551mh4.js → Accordion-hn43wt45.js} +1 -1
  152. package/web-dist/chunks/{Accordion-sw7ep29d.js → Accordion-hnx7hx55.js} +2 -2
  153. package/web-dist/chunks/{Accordion-rsvphbe4.js → Accordion-j1chy29e.js} +1 -1
  154. package/web-dist/chunks/{Accordion-ewf1zen9.js → Accordion-k9cxpg08.js} +5 -5
  155. package/web-dist/chunks/{Accordion-5df6cgyf.js → Accordion-md1g54wg.js} +1 -1
  156. package/web-dist/chunks/{Accordion-kjtcbe09.js → Accordion-p1ebrt17.js} +3 -3
  157. package/web-dist/chunks/{Accordion-qn398m1x.js → Accordion-r2g18vxa.js} +1 -1
  158. package/web-dist/chunks/{Accordion-zt9yghdz.js → Accordion-rctfgyfv.js} +4 -4
  159. package/web-dist/chunks/{Accordion-88t8fgxv.js → Accordion-rfc5mdbv.js} +1 -1
  160. package/web-dist/chunks/{Accordion-fmzxat3v.js → Accordion-sdnzqktc.js} +4 -4
  161. package/web-dist/chunks/{Accordion-v0grdh6q.js → Accordion-sq7ya2ye.js} +2 -2
  162. package/web-dist/chunks/{Accordion-ejx5gcf9.js → Accordion-t5scffdr.js} +9 -9
  163. package/web-dist/chunks/{Accordion-sy1cc5my.js → Accordion-ts788t7b.js} +3 -3
  164. package/web-dist/chunks/{Accordion-4s68t3h7.js → Accordion-v3rzy273.js} +6 -6
  165. package/web-dist/chunks/{Accordion-7tjz25jh.js → Accordion-vbzjq3z8.js} +1 -1
  166. package/web-dist/chunks/{Accordion-jh72azm2.js → Accordion-vg337250.js} +2 -2
  167. package/web-dist/chunks/{Accordion-42jfy1a1.js → Accordion-vj1m2wck.js} +1 -1
  168. package/web-dist/chunks/{Accordion-tqpsmdrk.js → Accordion-vxg5sw01.js} +4 -4
  169. package/web-dist/chunks/{Accordion-61ntvh14.js → Accordion-w59y0jdf.js} +4 -4
  170. package/web-dist/chunks/{Accordion-fjxcn6g9.js → Accordion-wcmrasqx.js} +8 -8
  171. package/web-dist/chunks/{Accordion-r1cj2w9e.js → Accordion-wpk8dxqp.js} +3 -3
  172. package/web-dist/chunks/{Accordion-w6qedeba.js → Accordion-x055n3b3.js} +1 -1
  173. package/web-dist/chunks/{Accordion-dbf93gxh.js → Accordion-xcm1qc39.js} +1 -1
  174. package/web-dist/chunks/{Accordion-7kq500r1.js → Accordion-xgxxg1hz.js} +1 -1
  175. package/web-dist/chunks/{Accordion-a4cma5b6.js → Accordion-y3083394.js} +3 -3
  176. package/web-dist/chunks/{Accordion-40tenzcg.js → Accordion-yexfbrzg.js} +4 -4
  177. package/web-dist/chunks/{Accordion-2r0gqk3x.js → Accordion-ztw7zp6v.js} +5 -5
  178. package/web-dist/chunks/{Accordion-bz04casa.js → Accordion-zypyr9xw.js} +211 -6
  179. package/web-dist/components/accordion/Accordion.js +5 -5
  180. package/web-dist/components/accordion-item/AccordionItem.js +5 -5
  181. package/web-dist/components/activity-indicator/ActivityIndicator.js +1 -1
  182. package/web-dist/components/app-bar/AppBar.js +7 -7
  183. package/web-dist/components/app-header/AppHeader.js +7 -7
  184. package/web-dist/components/app-shell/AppShell.js +2 -2
  185. package/web-dist/components/auth-screen/AuthScreen.js +10 -10
  186. package/web-dist/components/avatar/Avatar.js +5 -5
  187. package/web-dist/components/avatar-group/AvatarGroup.js +5 -5
  188. package/web-dist/components/badge/Badge.js +2 -2
  189. package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +10 -10
  190. package/web-dist/components/bottom-sheet/BottomSheet.js +3 -3
  191. package/web-dist/components/bottom-sheet-flat-list/BottomSheetFlatList.js +3 -3
  192. package/web-dist/components/bottom-sheet-scroll-view/BottomSheetScrollView.js +3 -3
  193. package/web-dist/components/bottom-sheet-section-list/BottomSheetSectionList.js +3 -3
  194. package/web-dist/components/bottom-sheet-view/BottomSheetView.js +3 -3
  195. package/web-dist/components/bottom-sheet-virtualized-list/BottomSheetVirtualizedList.js +3 -3
  196. package/web-dist/components/breadcrumbs/Breadcrumbs.js +5 -5
  197. package/web-dist/components/button/Button.js +3 -3
  198. package/web-dist/components/button-group/ButtonGroup.js +3 -3
  199. package/web-dist/components/camera-permission-view/CameraPermissionView.js +10 -10
  200. package/web-dist/components/card/Card.js +9 -9
  201. package/web-dist/components/card-back/CardBack.js +2 -2
  202. package/web-dist/components/card-hand/CardHand.js +2 -2
  203. package/web-dist/components/chat-list-item/ChatListItem.js +7 -7
  204. package/web-dist/components/checkbox/Checkbox.js +4 -4
  205. package/web-dist/components/checkbox-group/CheckboxGroup.js +4 -4
  206. package/web-dist/components/chess-board/ChessBoard.js +2 -2
  207. package/web-dist/components/chip/Chip.js +5 -5
  208. package/web-dist/components/chip-group/ChipGroup.js +5 -5
  209. package/web-dist/components/collection-editor/CollectionEditor.js +9 -9
  210. package/web-dist/components/content-rail/ContentRail.js +4 -4
  211. package/web-dist/components/data-table/DataTable.js +14 -14
  212. package/web-dist/components/date-picker/DatePicker.js +5 -5
  213. package/web-dist/components/dialog/Dialog.js +4 -4
  214. package/web-dist/components/divider/Divider.js +2 -2
  215. package/web-dist/components/empty-state/EmptyState.js +10 -10
  216. package/web-dist/components/explorer/Explorer.js +7 -7
  217. package/web-dist/components/field/Field.js +4 -4
  218. package/web-dist/components/file-explorer/FileExplorer.js +7 -7
  219. package/web-dist/components/flat-list/FlatList.js +5 -5
  220. package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +10 -10
  221. package/web-dist/components/form/Form.js +6 -6
  222. package/web-dist/components/form-actions/FormActions.js +6 -6
  223. package/web-dist/components/form-error/FormError.js +6 -6
  224. package/web-dist/components/game/Game.js +3 -3
  225. package/web-dist/components/game-entity/GameEntity.js +3 -3
  226. package/web-dist/components/game-field/GameField.js +3 -3
  227. package/web-dist/components/game-input-zone/GameInputZone.js +3 -3
  228. package/web-dist/components/game-measurement-probe/GameMeasurementProbe.js +3 -3
  229. package/web-dist/components/game-overlay/GameOverlay.js +3 -3
  230. package/web-dist/components/gradient/Gradient.js +3 -3
  231. package/web-dist/components/gradient-renderer-provider/GradientRendererProvider.js +3 -3
  232. package/web-dist/components/graph-view/GraphView.js +2 -2
  233. package/web-dist/components/grid/Grid.js +2 -2
  234. package/web-dist/components/grid-interactions/GridInteractions.d.ts +3 -0
  235. package/web-dist/components/grid-interactions/GridInteractions.js +379 -0
  236. package/web-dist/components/grid-interactions/index.d.ts +1 -0
  237. package/web-dist/components/grid-interactions/index.js +2 -0
  238. package/web-dist/components/grid-line-overlay/GridLineOverlay.js +2 -2
  239. package/web-dist/components/grid-ruler/GridRuler.js +2 -2
  240. package/web-dist/components/grid-view/GridView.js +1 -1
  241. package/web-dist/components/heading/Heading.js +2 -2
  242. package/web-dist/components/hero/Hero.js +9 -9
  243. package/web-dist/components/icon/Icon.js +2 -2
  244. package/web-dist/components/icon-button/IconButton.js +3 -3
  245. package/web-dist/components/image/Image.js +4 -4
  246. package/web-dist/components/keyboard-avoiding-view/KeyboardAvoidingView.js +2 -2
  247. package/web-dist/components/list/List.js +5 -5
  248. package/web-dist/components/list-item/ListItem.js +5 -5
  249. package/web-dist/components/list-section/ListSection.js +5 -5
  250. package/web-dist/components/matrix-grid/MatrixGrid.js +296 -47
  251. package/web-dist/components/media-card/MediaCard.js +9 -9
  252. package/web-dist/components/media-explorer/MediaExplorer.js +7 -7
  253. package/web-dist/components/message-bubble/MessageBubble.js +7 -7
  254. package/web-dist/components/metric-card/MetricCard.js +9 -9
  255. package/web-dist/components/missing-element/MissingElement.js +4 -4
  256. package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +10 -10
  257. package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +10 -10
  258. package/web-dist/components/opening-book/OpeningBook.js +2 -2
  259. package/web-dist/components/otp-form/OtpForm.js +10 -10
  260. package/web-dist/components/pagination/Pagination.js +4 -4
  261. package/web-dist/components/palette-item/PaletteItem.js +9 -9
  262. package/web-dist/components/playing-card/PlayingCard.js +2 -2
  263. package/web-dist/components/poker-training-table/PokerTrainingTable.js +2 -2
  264. package/web-dist/components/popover-menu/PopoverMenu.js +4 -4
  265. package/web-dist/components/post-card/PostCard.js +9 -9
  266. package/web-dist/components/product-card/ProductCard.js +9 -9
  267. package/web-dist/components/progress/Progress.js +4 -4
  268. package/web-dist/components/progress-ring/ProgressRing.js +4 -4
  269. package/web-dist/components/radio/Radio.js +5 -5
  270. package/web-dist/components/radio-group/RadioGroup.js +5 -5
  271. package/web-dist/components/rating/Rating.js +3 -3
  272. package/web-dist/components/reader/Reader.js +10 -10
  273. package/web-dist/components/scan-overlay/ScanOverlay.js +10 -10
  274. package/web-dist/components/screen/Screen.js +2 -2
  275. package/web-dist/components/screen-section/ScreenSection.js +4 -4
  276. package/web-dist/components/scroll-view/ScrollView.js +2 -2
  277. package/web-dist/components/search-input/SearchInput.js +4 -4
  278. package/web-dist/components/section-header/SectionHeader.js +4 -4
  279. package/web-dist/components/section-list/SectionList.js +5 -5
  280. package/web-dist/components/select/Select.js +4 -4
  281. package/web-dist/components/selectable-item/SelectableItem.js +2 -2
  282. package/web-dist/components/selection-provider/SelectionProvider.js +2 -2
  283. package/web-dist/components/sign-in-form/SignInForm.js +10 -10
  284. package/web-dist/components/sign-up-form/SignUpForm.js +10 -10
  285. package/web-dist/components/skeleton/Skeleton.js +12 -12
  286. package/web-dist/components/skeleton-card/SkeletonCard.js +12 -12
  287. package/web-dist/components/skeleton-list/SkeletonList.js +12 -12
  288. package/web-dist/components/skeleton-text/SkeletonText.js +12 -12
  289. package/web-dist/components/spatial-grid/SpatialGrid.js +1 -1
  290. package/web-dist/components/surface/Surface.js +2 -2
  291. package/web-dist/components/switch/Switch.js +1 -1
  292. package/web-dist/components/tab/Tab.js +2 -2
  293. package/web-dist/components/tab-list/TabList.js +2 -2
  294. package/web-dist/components/tab-panel/TabPanel.js +2 -2
  295. package/web-dist/components/tabletop-table/TabletopTable.js +2 -2
  296. package/web-dist/components/tabs/Tabs.js +2 -2
  297. package/web-dist/components/text/Text.js +2 -2
  298. package/web-dist/components/text-input/TextInput.js +4 -4
  299. package/web-dist/components/tile-grid/TileGrid.js +1 -1
  300. package/web-dist/components/time-grid/TimeGrid.js +2 -2
  301. package/web-dist/components/time-picker/TimePicker.js +5 -5
  302. package/web-dist/components/timeline/Timeline.js +4 -4
  303. package/web-dist/components/toast/Toast.js +2 -2
  304. package/web-dist/components/toast-provider/ToastProvider.js +2 -2
  305. package/web-dist/components/toolbar/Toolbar.js +9 -9
  306. package/web-dist/components/tree-item/TreeItem.js +9 -9
  307. package/web-dist/components/tree-view/TreeView.js +1 -1
  308. package/web-dist/components/uploader/Uploader.js +12 -12
  309. package/web-dist/components/view/View.js +2 -2
  310. package/web-dist/manifest.json +787 -772
  311. package/web-dist/runtime/ZoraProvider.js +3 -3
@@ -0,0 +1,33 @@
1
+ import { expect, test } from 'bun:test';
2
+
3
+ import { resolveGridInteractionPointer } from './resolveGridInteractionPointer';
4
+
5
+ test('normalizes nested responder coordinates against the interaction surface origin', () => {
6
+ expect(
7
+ resolveGridInteractionPointer(
8
+ {
9
+ nativeEvent: {
10
+ locationX: 4,
11
+ locationY: 6,
12
+ pageX: 124,
13
+ pageY: 86,
14
+ },
15
+ },
16
+ { x: 120, y: 80 },
17
+ ),
18
+ ).toEqual({ x: 4, y: 6 });
19
+ });
20
+
21
+ test('uses responder-local coordinates when page coordinates are unavailable on native', () => {
22
+ expect(
23
+ resolveGridInteractionPointer(
24
+ {
25
+ nativeEvent: {
26
+ locationX: 4,
27
+ locationY: 6,
28
+ },
29
+ },
30
+ { x: 120, y: 80 },
31
+ ),
32
+ ).toEqual({ x: 4, y: 6 });
33
+ });
@@ -0,0 +1,45 @@
1
+ import type { GridInteractionPointer } from '../../../../types/grid-interactions';
2
+
3
+ /*** Converts a responder event into coordinates local to the interaction surface. */
4
+ export function resolveGridInteractionPointer(
5
+ event: GridInteractionNativePointerEvent,
6
+ surfaceOrigin: GridInteractionSurfaceOrigin,
7
+ ): GridInteractionPointer {
8
+ const { nativeEvent } = event;
9
+ const { pageX, pageY } = nativeEvent;
10
+ const x =
11
+ typeof pageX === 'number' && Number.isFinite(pageX)
12
+ ? pageX - surfaceOrigin.x
13
+ : nativeEvent.locationX;
14
+ const y =
15
+ typeof pageY === 'number' && Number.isFinite(pageY)
16
+ ? pageY - surfaceOrigin.y
17
+ : nativeEvent.locationY;
18
+
19
+ return {
20
+ altKey: nativeEvent.altKey,
21
+ ctrlKey: nativeEvent.ctrlKey,
22
+ metaKey: nativeEvent.metaKey,
23
+ shiftKey: nativeEvent.shiftKey,
24
+ x,
25
+ y,
26
+ };
27
+ }
28
+
29
+ interface GridInteractionNativePointerEvent {
30
+ readonly nativeEvent: {
31
+ readonly altKey?: boolean;
32
+ readonly ctrlKey?: boolean;
33
+ readonly locationX: number;
34
+ readonly locationY: number;
35
+ readonly metaKey?: boolean;
36
+ readonly pageX?: number;
37
+ readonly pageY?: number;
38
+ readonly shiftKey?: boolean;
39
+ };
40
+ }
41
+
42
+ interface GridInteractionSurfaceOrigin {
43
+ readonly x: number;
44
+ readonly y: number;
45
+ }
@@ -0,0 +1,229 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+
3
+ import { createGridInteractionsController } from './createGridInteractionsController';
4
+
5
+ const viewport = {
6
+ width: 100,
7
+ height: 100,
8
+ offsetX: 0,
9
+ offsetY: 0,
10
+ pixelsPerUnitX: 2,
11
+ pixelsPerUnitY: 4,
12
+ };
13
+ const items = [
14
+ { id: 'a', x: 1, y: 1, width: 3, height: 2 },
15
+ { id: 'locked', x: 10, y: 1, width: 2, height: 2, locked: true },
16
+ ];
17
+
18
+ describe('createGridInteractionsController', () => {
19
+ test('maps independent viewport scales to a move preview without mutating items', () => {
20
+ const intents: unknown[] = [];
21
+ const controller = createGridInteractionsController({
22
+ viewport,
23
+ items,
24
+ onIntent: (intent) => intents.push(intent),
25
+ });
26
+ controller.begin({ x: 3, y: 5 });
27
+ controller.move({ x: 7, y: 13 });
28
+ expect(intents).toEqual([
29
+ { type: 'move', itemIds: ['a'], rects: [{ id: 'a', x: 3, y: 3, width: 3, height: 2 }] },
30
+ ]);
31
+ expect(items[0]).toEqual({ id: 'a', x: 1, y: 1, width: 3, height: 2 });
32
+ });
33
+
34
+ test('normalizes negative marquee drags and protects locked items', () => {
35
+ const intents: unknown[] = [];
36
+ const controller = createGridInteractionsController({
37
+ viewport,
38
+ items,
39
+ marqueeMode: 'intersect',
40
+ onIntent: (intent) => intents.push(intent),
41
+ });
42
+ controller.begin({ x: 24, y: 12 });
43
+ controller.end({ x: 0, y: 0 });
44
+ expect(intents).toEqual([
45
+ { type: 'marquee', itemIds: ['a'], marquee: { x: 0, y: 0, width: 12, height: 3 } },
46
+ ]);
47
+ });
48
+
49
+ test('keeps an active gesture while updating controlled props after a parent rerender', () => {
50
+ const initialIntents: unknown[] = [];
51
+ const rerenderedIntents: unknown[] = [];
52
+ const controller = createGridInteractionsController({
53
+ viewport,
54
+ items,
55
+ onIntent: (intent) => initialIntents.push(intent),
56
+ });
57
+
58
+ controller.begin({ x: 3, y: 5 });
59
+ controller.update({
60
+ viewport,
61
+ items,
62
+ onIntent: (intent) => rerenderedIntents.push(intent),
63
+ });
64
+ controller.end({ x: 7, y: 13 });
65
+
66
+ expect(initialIntents).toEqual([]);
67
+ expect(rerenderedIntents).toEqual([
68
+ { type: 'move', itemIds: ['a'], rects: [{ id: 'a', x: 3, y: 3, width: 3, height: 2 }] },
69
+ ]);
70
+ });
71
+
72
+ test('emits keyboard resize and accelerated movement only while interaction is enabled', () => {
73
+ const intents: unknown[] = [];
74
+ const controller = createGridInteractionsController({
75
+ viewport,
76
+ items,
77
+ onIntent: (intent) => intents.push(intent),
78
+ selectedIds: ['a'],
79
+ });
80
+
81
+ expect(controller.keyDown('ArrowRight', { x: 0, y: 0, altKey: true })).toBe(true);
82
+ expect(controller.keyDown('ArrowDown', { x: 0, y: 0, shiftKey: true })).toBe(true);
83
+ controller.update({
84
+ interactionPolicy: 'passive',
85
+ viewport,
86
+ items,
87
+ onIntent: (intent) => intents.push(intent),
88
+ selectedIds: ['a'],
89
+ });
90
+ expect(controller.keyDown('ArrowLeft', { x: 0, y: 0 })).toBe(false);
91
+ controller.begin({ x: 3, y: 5 });
92
+ controller.end({ x: 7, y: 13 });
93
+
94
+ expect(intents).toEqual([
95
+ { type: 'resize', itemIds: ['a'], rects: [{ id: 'a', x: 1, y: 1, width: 4, height: 2 }] },
96
+ { type: 'move', itemIds: ['a'], rects: [{ id: 'a', x: 1, y: 11, width: 3, height: 2 }] },
97
+ ]);
98
+ });
99
+
100
+ test('emits handle-driven resize intents for a pointer gesture', () => {
101
+ const intents: unknown[] = [];
102
+ const controller = createGridInteractionsController({
103
+ viewport,
104
+ items,
105
+ onIntent: (intent) => intents.push(intent),
106
+ });
107
+
108
+ controller.begin({ x: 3, y: 5 }, 'bottom-right');
109
+ controller.end({ x: 7, y: 13 });
110
+
111
+ expect(intents).toEqual([
112
+ { type: 'resize', itemIds: ['a'], rects: [{ id: 'a', x: 1, y: 1, width: 5, height: 4 }] },
113
+ ]);
114
+ });
115
+
116
+ test('does not compound controlled move previews or reapply the release endpoint', () => {
117
+ const intents: unknown[] = [];
118
+ const initialItems = [{ id: 'a', x: 40, y: 40, width: 20, height: 20 }];
119
+ const controller = createGridInteractionsController({
120
+ viewport,
121
+ items: initialItems,
122
+ onIntent: (intent) => intents.push(intent),
123
+ });
124
+
125
+ controller.begin({ x: 80, y: 160 });
126
+ controller.move({ x: 100, y: 160 });
127
+ controller.update({
128
+ viewport,
129
+ items: [{ id: 'a', x: 50, y: 40, width: 20, height: 20 }],
130
+ onIntent: (intent) => intents.push(intent),
131
+ });
132
+ controller.move({ x: 120, y: 160 });
133
+ controller.update({
134
+ viewport,
135
+ items: [{ id: 'a', x: 60, y: 40, width: 20, height: 20 }],
136
+ onIntent: (intent) => intents.push(intent),
137
+ });
138
+ controller.end({ x: 120, y: 160 });
139
+
140
+ expect(intents).toEqual([
141
+ { type: 'move', itemIds: ['a'], rects: [{ id: 'a', x: 50, y: 40, width: 20, height: 20 }] },
142
+ { type: 'move', itemIds: ['a'], rects: [{ id: 'a', x: 60, y: 40, width: 20, height: 20 }] },
143
+ ]);
144
+ });
145
+
146
+ test('keeps controlled resize, negative multi-item movement, cancel, and pan non-compounding', () => {
147
+ const resizeIntents: unknown[] = [];
148
+ const resizeController = createGridInteractionsController({
149
+ viewport,
150
+ items: [{ id: 'a', x: 40, y: 40, width: 20, height: 20 }],
151
+ onIntent: (intent) => resizeIntents.push(intent),
152
+ });
153
+
154
+ resizeController.begin({ x: 120, y: 240 }, 'bottom-right');
155
+ resizeController.move({ x: 140, y: 280 });
156
+ resizeController.update({
157
+ viewport,
158
+ items: [{ id: 'a', x: 40, y: 40, width: 30, height: 30 }],
159
+ onIntent: (intent) => resizeIntents.push(intent),
160
+ });
161
+ resizeController.move({ x: 160, y: 320 });
162
+ resizeController.update({
163
+ viewport,
164
+ items: [{ id: 'a', x: 40, y: 40, width: 40, height: 40 }],
165
+ onIntent: (intent) => resizeIntents.push(intent),
166
+ });
167
+ resizeController.end({ x: 160, y: 320 });
168
+
169
+ const moveIntents: unknown[] = [];
170
+ const moveController = createGridInteractionsController({
171
+ viewport,
172
+ items: [
173
+ { id: 'a', x: 40, y: 40, width: 20, height: 20 },
174
+ { id: 'b', x: 80, y: 40, width: 20, height: 20 },
175
+ ],
176
+ selectedIds: ['a', 'b'],
177
+ onIntent: (intent) => moveIntents.push(intent),
178
+ });
179
+
180
+ moveController.begin({ x: 80, y: 160 });
181
+ moveController.move({ x: 60, y: 120 });
182
+ moveController.cancel();
183
+ moveController.end({ x: 40, y: 80 });
184
+
185
+ const panIntents: unknown[] = [];
186
+ const panController = createGridInteractionsController({
187
+ viewport,
188
+ items: [],
189
+ onIntent: (intent) => panIntents.push(intent),
190
+ });
191
+
192
+ panController.begin({ x: 20, y: 40, spaceKey: true });
193
+ panController.move({ x: 40, y: 80 });
194
+ panController.update({
195
+ viewport: { ...viewport, offsetX: 5, offsetY: 2.5 },
196
+ items: [],
197
+ onIntent: (intent) => panIntents.push(intent),
198
+ });
199
+ panController.move({ x: 60, y: 120 });
200
+ panController.end({ x: 60, y: 120 });
201
+
202
+ expect(resizeIntents).toEqual([
203
+ { type: 'resize', itemIds: ['a'], rects: [{ id: 'a', x: 40, y: 40, width: 30, height: 30 }] },
204
+ { type: 'resize', itemIds: ['a'], rects: [{ id: 'a', x: 40, y: 40, width: 40, height: 40 }] },
205
+ ]);
206
+ expect(moveIntents).toEqual([
207
+ {
208
+ type: 'move',
209
+ itemIds: ['a', 'b'],
210
+ rects: [
211
+ { id: 'a', x: 30, y: 30, width: 20, height: 20 },
212
+ { id: 'b', x: 70, y: 30, width: 20, height: 20 },
213
+ ],
214
+ },
215
+ ]);
216
+ expect(panIntents).toEqual([
217
+ {
218
+ type: 'pan',
219
+ itemIds: [],
220
+ viewport: { ...viewport, offsetX: 5, offsetY: 2.5 },
221
+ },
222
+ {
223
+ type: 'pan',
224
+ itemIds: [],
225
+ viewport: { ...viewport, offsetX: 10, offsetY: 5 },
226
+ },
227
+ ]);
228
+ });
229
+ });
@@ -0,0 +1,248 @@
1
+ import {
2
+ type GridPoint,
3
+ type GridRect,
4
+ type GridResizeHandle,
5
+ type GridViewport,
6
+ hitTestWorldRects,
7
+ moveWorldRects,
8
+ panViewport,
9
+ resizeWorldRect,
10
+ resolveWorldSnapCandidate,
11
+ selectWorldRects,
12
+ viewportToWorld,
13
+ } from '@ankhorage/grid-view';
14
+
15
+ import type {
16
+ GridInteractionIntent,
17
+ GridInteractionItem,
18
+ GridInteractionPointer,
19
+ GridInteractionsController,
20
+ GridInteractionsControllerProps,
21
+ } from '../../../types/grid-interactions';
22
+
23
+ type InteractionState =
24
+ | { readonly kind: 'idle' }
25
+ | { readonly kind: 'marquee'; readonly start: GridPoint; readonly viewport: GridViewport }
26
+ | { readonly kind: 'pan'; readonly start: GridPoint; readonly viewport: GridViewport }
27
+ | {
28
+ readonly kind: 'move';
29
+ readonly start: GridPoint;
30
+ readonly viewport: GridViewport;
31
+ readonly itemIds: readonly string[];
32
+ readonly items: readonly GridInteractionItem[];
33
+ }
34
+ | {
35
+ readonly kind: 'resize';
36
+ readonly start: GridPoint;
37
+ readonly viewport: GridViewport;
38
+ readonly item: GridInteractionItem;
39
+ readonly handle: GridResizeHandle;
40
+ };
41
+
42
+ /*** Create a platform-neutral controlled interaction controller using grid-view geometry only. */
43
+ export function createGridInteractionsController(
44
+ props: GridInteractionsControllerProps,
45
+ ): GridInteractionsController {
46
+ let currentProps = props;
47
+ let state: InteractionState = { kind: 'idle' };
48
+ let previousIntent: GridInteractionIntent | undefined;
49
+ const point = (pointer: GridInteractionPointer, viewport = currentProps.viewport) =>
50
+ Number.isFinite(pointer.x) && Number.isFinite(pointer.y)
51
+ ? viewportToWorld(pointer, viewport)
52
+ : undefined;
53
+ const emit = (intent: GridInteractionIntent) => {
54
+ if (JSON.stringify(previousIntent) === JSON.stringify(intent)) return;
55
+ previousIntent = intent;
56
+ currentProps.onIntent(intent);
57
+ };
58
+
59
+ return {
60
+ begin: (pointer, handle) => {
61
+ if (!canEdit(currentProps)) return;
62
+ const start = point(pointer);
63
+ if (start === undefined) return;
64
+ if (pointer.spaceKey === true || pointer.altKey === true) {
65
+ state = { kind: 'pan', start, viewport: currentProps.viewport };
66
+ return;
67
+ }
68
+ const target = hitTestWorldRects(currentProps.items, start);
69
+ if (target === undefined || isProtected(target)) {
70
+ state = { kind: 'marquee', start, viewport: currentProps.viewport };
71
+ return;
72
+ }
73
+ if (handle !== undefined && target.resizable !== false) {
74
+ state = { kind: 'resize', start, viewport: currentProps.viewport, item: target, handle };
75
+ return;
76
+ }
77
+ const itemIds =
78
+ currentProps.selectedIds?.includes(target.id) === true
79
+ ? currentProps.selectedIds
80
+ : [target.id];
81
+ state = {
82
+ kind: 'move',
83
+ start,
84
+ viewport: currentProps.viewport,
85
+ itemIds,
86
+ items: currentProps.items.filter((item) => itemIds.includes(item.id)),
87
+ };
88
+ },
89
+ move: (pointer) => {
90
+ if (!canEdit(currentProps)) return;
91
+ const current = point(pointer, viewportForState(state, currentProps.viewport));
92
+ if (current !== undefined) emitPreview(state, current, currentProps, emit);
93
+ },
94
+ end: (pointer) => {
95
+ if (!canEdit(currentProps)) {
96
+ state = { kind: 'idle' };
97
+ return;
98
+ }
99
+ const current = point(pointer, viewportForState(state, currentProps.viewport));
100
+ if (current !== undefined) emitPreview(state, current, currentProps, emit);
101
+ state = { kind: 'idle' };
102
+ },
103
+ cancel: () => {
104
+ state = { kind: 'idle' };
105
+ },
106
+ keyDown: (key, pointer = { x: 0, y: 0 }) => {
107
+ if (!canEdit(currentProps)) return false;
108
+ const focusedId = currentProps.selectedIds?.at(-1);
109
+ const focused = currentProps.items.find((item) => item.id === focusedId);
110
+ if (!focused || isProtected(focused)) return false;
111
+ const increment = pointer.shiftKey === true ? 10 : 1;
112
+ const delta = keyToDelta(key, increment);
113
+ if (delta === undefined) return false;
114
+ if (pointer.altKey === true) {
115
+ emit({
116
+ type: 'resize',
117
+ itemIds: [focused.id],
118
+ rects: [resizeWorldRect(focused, resizeHandleForDelta(delta), delta)],
119
+ });
120
+ return true;
121
+ }
122
+ emit({ type: 'move', itemIds: [focused.id], rects: moveWorldRects([focused], delta) });
123
+ return true;
124
+ },
125
+ update: (nextProps) => {
126
+ currentProps = nextProps;
127
+ },
128
+ };
129
+ }
130
+
131
+ /*** Determines whether the component-wide interaction policy permits edit intents. */
132
+ function canEdit(props: GridInteractionsControllerProps): boolean {
133
+ return props.interactionPolicy !== 'passive';
134
+ }
135
+
136
+ /*** Emit one controlled preview/intention without retaining or mutating caller-owned item data. */
137
+ function emitPreview(
138
+ state: InteractionState,
139
+ current: GridPoint,
140
+ props: GridInteractionsControllerProps,
141
+ emit: (intent: GridInteractionIntent) => void,
142
+ ) {
143
+ if (state.kind === 'idle') return;
144
+ if (state.kind === 'pan') {
145
+ emit({
146
+ type: 'pan',
147
+ itemIds: [],
148
+ viewport: panViewport(state.viewport, {
149
+ x: state.start.x - current.x,
150
+ y: state.start.y - current.y,
151
+ }),
152
+ });
153
+ return;
154
+ }
155
+ if (state.kind === 'marquee') {
156
+ const marquee = normalizeRect(state.start, current);
157
+ const itemIds = selectWorldRects(props.items, marquee, {
158
+ mode: props.marqueeMode ?? 'intersect',
159
+ }).filter((id) => {
160
+ const item = props.items.find((candidate) => candidate.id === id);
161
+ return item !== undefined && !isProtected(item);
162
+ });
163
+ emit({ type: 'marquee', itemIds, marquee });
164
+ return;
165
+ }
166
+ const delta = resolveSnapDelta(state, current, props);
167
+ if (state.kind === 'move') {
168
+ emit({ type: 'move', itemIds: state.itemIds, rects: moveWorldRects(state.items, delta) });
169
+ return;
170
+ }
171
+ emit({
172
+ type: 'resize',
173
+ itemIds: [state.item.id],
174
+ rects: [resizeWorldRect(state.item, state.handle, delta)],
175
+ });
176
+ }
177
+
178
+ /*** Resolve explicit per-axis candidate snapping without inventing geometry outside grid-view. */
179
+ function resolveSnapDelta(
180
+ state: InteractionState,
181
+ current: GridPoint,
182
+ props: GridInteractionsControllerProps,
183
+ ): GridPoint {
184
+ if (state.kind === 'idle' || state.kind === 'marquee' || state.kind === 'pan') {
185
+ return { x: 0, y: 0 };
186
+ }
187
+ const raw = { x: current.x - state.start.x, y: current.y - state.start.y };
188
+ if (props.snap?.enabled !== true) return raw;
189
+ const anchor = state.kind === 'resize' ? state.item : state.items.at(0);
190
+ if (anchor === undefined) return raw;
191
+ const options = {
192
+ enabled: true,
193
+ tolerancePixels: props.snap.tolerancePixels,
194
+ priorities: props.snap.priorities,
195
+ };
196
+ return {
197
+ x:
198
+ resolveWorldSnapCandidate(anchor.x + raw.x, props.snap.x ?? [], {
199
+ ...options,
200
+ pixelsPerUnit: props.viewport.pixelsPerUnitX,
201
+ }) - anchor.x,
202
+ y:
203
+ resolveWorldSnapCandidate(anchor.y + raw.y, props.snap.y ?? [], {
204
+ ...options,
205
+ pixelsPerUnit: props.viewport.pixelsPerUnitY,
206
+ }) - anchor.y,
207
+ };
208
+ }
209
+
210
+ /*** Keep pointer coordinates in the original gesture coordinate space across controlled updates. */
211
+ function viewportForState(state: InteractionState, fallback: GridViewport): GridViewport {
212
+ return state.kind === 'idle' ? fallback : state.viewport;
213
+ }
214
+
215
+ /*** Keep all caller-declared protected items out of selection and edit intents. */
216
+ function isProtected(item: GridInteractionItem): boolean {
217
+ return (
218
+ item.disabled === true ||
219
+ item.locked === true ||
220
+ item.readOnly === true ||
221
+ item.passive === true
222
+ );
223
+ }
224
+
225
+ /*** Normalize an arbitrary-direction drag into the world rectangle expected by grid-view selection. */
226
+ function normalizeRect(start: GridPoint, end: GridPoint): GridRect {
227
+ return {
228
+ x: Math.min(start.x, end.x),
229
+ y: Math.min(start.y, end.y),
230
+ width: Math.abs(end.x - start.x),
231
+ height: Math.abs(end.y - start.y),
232
+ };
233
+ }
234
+
235
+ /** Maps accessible arrow keys to caller-controlled world-space edit increments. */
236
+ function keyToDelta(key: string, increment: number): GridPoint | undefined {
237
+ if (key === 'ArrowUp') return { x: 0, y: -increment };
238
+ if (key === 'ArrowRight') return { x: increment, y: 0 };
239
+ if (key === 'ArrowDown') return { x: 0, y: increment };
240
+ if (key === 'ArrowLeft') return { x: -increment, y: 0 };
241
+ return undefined;
242
+ }
243
+
244
+ /** Chooses the physical edge matching an accessible resize direction. */
245
+ function resizeHandleForDelta(delta: GridPoint): GridResizeHandle {
246
+ if (delta.x < 0) return delta.y < 0 ? 'top-left' : delta.y > 0 ? 'bottom-left' : 'left';
247
+ return delta.y < 0 ? 'top-right' : delta.y > 0 ? 'bottom-right' : 'right';
248
+ }
@@ -0,0 +1,12 @@
1
+ import type { ZoraComponentMeta } from '../../types/authoring';
2
+
3
+ /** Grid input is a code composition boundary because it accepts live geometry and callbacks. */
4
+ export const gridInteractionsMeta = {
5
+ name: 'GridInteractions',
6
+ category: 'foundation',
7
+ description: 'Maps native and web input to controlled world-space grid interaction intents.',
8
+ directManifestNode: false,
9
+ note: 'Requires live viewport geometry, item data, and an executable intent callback; available through code APIs only.',
10
+ allowedChildren: [],
11
+ props: {},
12
+ } as const satisfies ZoraComponentMeta;
@@ -0,0 +1,11 @@
1
+ export type {
2
+ GridInteractionIntent,
3
+ GridInteractionItem,
4
+ GridInteractionPointer,
5
+ GridInteractionsController,
6
+ GridInteractionsControllerProps,
7
+ GridInteractionSnap,
8
+ GridInteractionsProps,
9
+ } from '../../types/grid-interactions';
10
+ export { GridInteractions } from './adapters/inbound/GridInteractions';
11
+ export { createGridInteractionsController } from './application/createGridInteractionsController';