@ankhorage/zora 25.7.0 → 25.8.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.
- package/CHANGELOG.md +31 -0
- package/README.md +1 -1
- package/dist/capabilities/index.d.ts +2 -74
- package/dist/capabilities/index.d.ts.map +1 -1
- package/dist/capabilities/index.js +6170 -59
- package/dist/capabilities/index.js.map +119 -1
- package/dist/cli/index.d.ts +2 -74
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/features/grid-interactions/adapters/inbound/GridInteractions.d.ts +5 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractions.d.ts.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractions.js +40 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractions.js.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.d.ts +2 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.d.ts.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.js +2 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.js.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.d.ts +11 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.d.ts.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.js +5 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.js.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.d.ts +11 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.d.ts.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.js +20 -0
- package/dist/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.js.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.d.ts +17 -0
- package/dist/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.d.ts.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.js +76 -0
- package/dist/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.js.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.d.ts +21 -0
- package/dist/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.d.ts.map +1 -0
- package/dist/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.js +20 -0
- package/dist/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.js.map +1 -0
- package/dist/features/grid-interactions/application/createGridInteractionsController.d.ts +4 -0
- package/dist/features/grid-interactions/application/createGridInteractionsController.d.ts.map +1 -0
- package/dist/features/grid-interactions/application/createGridInteractionsController.js +191 -0
- package/dist/features/grid-interactions/application/createGridInteractionsController.js.map +1 -0
- package/dist/features/grid-interactions/meta.d.ts +11 -0
- package/dist/features/grid-interactions/meta.d.ts.map +1 -0
- package/dist/features/grid-interactions/meta.js +11 -0
- package/dist/features/grid-interactions/meta.js.map +1 -0
- package/dist/features/grid-interactions/public.d.ts +4 -0
- package/dist/features/grid-interactions/public.d.ts.map +1 -0
- package/dist/features/grid-interactions/public.js +3 -0
- package/dist/features/grid-interactions/public.js.map +1 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.d.ts.map +1 -1
- package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.js +73 -19
- package/dist/features/matrix-grid/adapters/inbound/MatrixGrid.js.map +1 -1
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.d.ts +9 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.d.ts.map +1 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.js +5 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.js.map +1 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.d.ts +9 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.d.ts.map +1 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.js +5 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.js.map +1 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.d.ts +9 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.d.ts.map +1 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.js +28 -0
- package/dist/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.js.map +1 -0
- package/dist/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.d.ts +14 -0
- package/dist/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.d.ts.map +1 -0
- package/dist/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.js +50 -0
- package/dist/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.js.map +1 -0
- package/dist/features/matrix-grid/application/createMatrixGridSparseIndex.d.ts +18 -0
- package/dist/features/matrix-grid/application/createMatrixGridSparseIndex.d.ts.map +1 -0
- package/dist/features/matrix-grid/application/createMatrixGridSparseIndex.js +56 -0
- package/dist/features/matrix-grid/application/createMatrixGridSparseIndex.js.map +1 -0
- package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.d.ts +4 -0
- package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.d.ts.map +1 -0
- package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.js +65 -0
- package/dist/features/matrix-grid/application/getMatrixGridNextFocusId.js.map +1 -0
- package/dist/features/matrix-grid/application/resolveMatrixGridSelection.d.ts +8 -1
- package/dist/features/matrix-grid/application/resolveMatrixGridSelection.d.ts.map +1 -1
- package/dist/features/matrix-grid/application/resolveMatrixGridSelection.js +15 -4
- package/dist/features/matrix-grid/application/resolveMatrixGridSelection.js.map +1 -1
- package/dist/features/registry/ZORA_COMPONENT_REGISTRY.d.ts.map +1 -1
- package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js +2 -0
- package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js.map +1 -1
- package/dist/features/registry/componentMeta.d.ts.map +1 -1
- package/dist/features/registry/componentMeta.js +2 -0
- package/dist/features/registry/componentMeta.js.map +1 -1
- package/dist/features/registry/createEventCapabilities.d.ts +4 -0
- package/dist/features/registry/createEventCapabilities.d.ts.map +1 -0
- package/dist/features/registry/createEventCapabilities.js +76 -0
- package/dist/features/registry/createEventCapabilities.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types/grid-interactions.d.ts +58 -0
- package/dist/types/grid-interactions.d.ts.map +1 -0
- package/dist/types/grid-interactions.js +2 -0
- package/dist/types/grid-interactions.js.map +1 -0
- package/dist/types/matrix-grid.d.ts +2 -0
- package/dist/types/matrix-grid.d.ts.map +1 -1
- package/dist/types/matrix-grid.js.map +1 -1
- package/package.json +1825 -7
- package/src/capabilities/index.test.ts +87 -15
- package/src/capabilities/index.ts +5 -2
- package/src/cli/index.test.ts +5 -3
- package/src/cli/index.ts +5 -2
- package/src/features/grid-interactions/adapters/inbound/GridInteractions.test.tsx +143 -0
- package/src/features/grid-interactions/adapters/inbound/GridInteractions.tsx +79 -0
- package/src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.native.tsx +14 -0
- package/src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.tsx +1 -0
- package/src/features/grid-interactions/adapters/inbound/GridInteractionsKeyboardProxy.web.tsx +41 -0
- package/src/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.test.ts +98 -0
- package/src/features/grid-interactions/adapters/inbound/createGridInteractionsPointerQueue.ts +94 -0
- package/src/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.test.ts +33 -0
- package/src/features/grid-interactions/adapters/inbound/resolveGridInteractionPointer.ts +45 -0
- package/src/features/grid-interactions/application/createGridInteractionsController.test.ts +115 -0
- package/src/features/grid-interactions/application/createGridInteractionsController.ts +231 -0
- package/src/features/grid-interactions/meta.ts +12 -0
- package/src/features/grid-interactions/public.ts +11 -0
- package/src/features/matrix-grid/adapters/inbound/MatrixGrid.test.tsx +280 -2
- package/src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx +121 -31
- package/src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.tsx +11 -0
- package/src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.tsx +11 -0
- package/src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.tsx +43 -0
- package/src/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.ts +70 -0
- package/src/features/matrix-grid/application/createMatrixGridSparseIndex.test.ts +35 -0
- package/src/features/matrix-grid/application/createMatrixGridSparseIndex.ts +105 -0
- package/src/features/matrix-grid/application/getMatrixGridNextFocusId.test.ts +93 -0
- package/src/features/matrix-grid/application/getMatrixGridNextFocusId.ts +112 -0
- package/src/features/matrix-grid/application/resolveMatrixGridSelection.test.ts +63 -2
- package/src/features/matrix-grid/application/resolveMatrixGridSelection.ts +27 -4
- package/src/features/registry/ZORA_COMPONENT_REGISTRY.ts +2 -0
- package/src/features/registry/componentMeta.ts +2 -0
- package/src/features/registry/createEventCapabilities.ts +108 -0
- package/src/index.ts +11 -0
- package/src/structureOwnership.test.ts +5 -0
- package/src/types/grid-interactions.ts +72 -0
- package/src/types/matrix-grid.ts +2 -0
- package/web-dist/chunks/{Accordion-5g05kfmx.js → Accordion-0q2wzjdd.js} +4 -4
- package/web-dist/chunks/{Accordion-b96evb46.js → Accordion-1fsrnq73.js} +1 -1
- package/web-dist/chunks/{Accordion-h3y8qev2.js → Accordion-38ts3gnn.js} +2 -2
- package/web-dist/chunks/{Accordion-jnc315h7.js → Accordion-8pkw32q9.js} +2 -2
- package/web-dist/chunks/{Accordion-h7zsx9eg.js → Accordion-9jrxktne.js} +3 -3
- package/web-dist/chunks/{Accordion-9w8wg9mf.js → Accordion-9rnsg9pk.js} +1 -1
- package/web-dist/chunks/{Accordion-4zqd7twp.js → Accordion-9ygakvwk.js} +5 -5
- package/web-dist/chunks/{Accordion-fhnazn3n.js → Accordion-b74j4hdt.js} +1 -1
- package/web-dist/chunks/{Accordion-nssr5gep.js → Accordion-c50pywj3.js} +2 -2
- package/web-dist/chunks/{Accordion-pvj5npzc.js → Accordion-ddrn94v3.js} +3 -3
- package/web-dist/chunks/{Accordion-090y18cv.js → Accordion-dk0dtyc0.js} +3 -3
- package/web-dist/chunks/{Accordion-59pa0677.js → Accordion-fcczvwgg.js} +0 -1
- package/web-dist/chunks/{Accordion-sp4k08kw.js → Accordion-geah5s4f.js} +4 -4
- package/web-dist/chunks/{Accordion-6rrqpb2h.js → Accordion-h4ekm5cp.js} +2 -2
- package/web-dist/chunks/{Accordion-3d4wkzg7.js → Accordion-hecpczme.js} +5 -5
- package/web-dist/chunks/{Accordion-a6551mh4.js → Accordion-hn43wt45.js} +1 -1
- package/web-dist/chunks/{Accordion-sw7ep29d.js → Accordion-hnx7hx55.js} +2 -2
- package/web-dist/chunks/{Accordion-rsvphbe4.js → Accordion-j1chy29e.js} +1 -1
- package/web-dist/chunks/{Accordion-ewf1zen9.js → Accordion-k9cxpg08.js} +5 -5
- package/web-dist/chunks/{Accordion-5df6cgyf.js → Accordion-md1g54wg.js} +1 -1
- package/web-dist/chunks/{Accordion-kjtcbe09.js → Accordion-p1ebrt17.js} +3 -3
- package/web-dist/chunks/{Accordion-qn398m1x.js → Accordion-r2g18vxa.js} +1 -1
- package/web-dist/chunks/{Accordion-zt9yghdz.js → Accordion-rctfgyfv.js} +4 -4
- package/web-dist/chunks/{Accordion-88t8fgxv.js → Accordion-rfc5mdbv.js} +1 -1
- package/web-dist/chunks/{Accordion-fmzxat3v.js → Accordion-sdnzqktc.js} +4 -4
- package/web-dist/chunks/{Accordion-v0grdh6q.js → Accordion-sq7ya2ye.js} +2 -2
- package/web-dist/chunks/{Accordion-ejx5gcf9.js → Accordion-t5scffdr.js} +9 -9
- package/web-dist/chunks/{Accordion-sy1cc5my.js → Accordion-ts788t7b.js} +3 -3
- package/web-dist/chunks/{Accordion-4s68t3h7.js → Accordion-v3rzy273.js} +6 -6
- package/web-dist/chunks/{Accordion-7tjz25jh.js → Accordion-vbzjq3z8.js} +1 -1
- package/web-dist/chunks/{Accordion-jh72azm2.js → Accordion-vg337250.js} +2 -2
- package/web-dist/chunks/{Accordion-42jfy1a1.js → Accordion-vj1m2wck.js} +1 -1
- package/web-dist/chunks/{Accordion-tqpsmdrk.js → Accordion-vxg5sw01.js} +4 -4
- package/web-dist/chunks/{Accordion-61ntvh14.js → Accordion-w59y0jdf.js} +4 -4
- package/web-dist/chunks/{Accordion-fjxcn6g9.js → Accordion-wcmrasqx.js} +8 -8
- package/web-dist/chunks/{Accordion-r1cj2w9e.js → Accordion-wpk8dxqp.js} +3 -3
- package/web-dist/chunks/{Accordion-w6qedeba.js → Accordion-x055n3b3.js} +1 -1
- package/web-dist/chunks/{Accordion-dbf93gxh.js → Accordion-xcm1qc39.js} +1 -1
- package/web-dist/chunks/{Accordion-7kq500r1.js → Accordion-xgxxg1hz.js} +1 -1
- package/web-dist/chunks/{Accordion-a4cma5b6.js → Accordion-y3083394.js} +3 -3
- package/web-dist/chunks/{Accordion-40tenzcg.js → Accordion-yexfbrzg.js} +4 -4
- package/web-dist/chunks/{Accordion-2r0gqk3x.js → Accordion-ztw7zp6v.js} +5 -5
- package/web-dist/chunks/{Accordion-bz04casa.js → Accordion-zypyr9xw.js} +211 -6
- package/web-dist/components/accordion/Accordion.js +5 -5
- package/web-dist/components/accordion-item/AccordionItem.js +5 -5
- package/web-dist/components/activity-indicator/ActivityIndicator.js +1 -1
- package/web-dist/components/app-bar/AppBar.js +7 -7
- package/web-dist/components/app-header/AppHeader.js +7 -7
- package/web-dist/components/app-shell/AppShell.js +2 -2
- package/web-dist/components/auth-screen/AuthScreen.js +10 -10
- package/web-dist/components/avatar/Avatar.js +5 -5
- package/web-dist/components/avatar-group/AvatarGroup.js +5 -5
- package/web-dist/components/badge/Badge.js +2 -2
- package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +10 -10
- package/web-dist/components/bottom-sheet/BottomSheet.js +3 -3
- package/web-dist/components/bottom-sheet-flat-list/BottomSheetFlatList.js +3 -3
- package/web-dist/components/bottom-sheet-scroll-view/BottomSheetScrollView.js +3 -3
- package/web-dist/components/bottom-sheet-section-list/BottomSheetSectionList.js +3 -3
- package/web-dist/components/bottom-sheet-view/BottomSheetView.js +3 -3
- package/web-dist/components/bottom-sheet-virtualized-list/BottomSheetVirtualizedList.js +3 -3
- package/web-dist/components/breadcrumbs/Breadcrumbs.js +5 -5
- package/web-dist/components/button/Button.js +3 -3
- package/web-dist/components/button-group/ButtonGroup.js +3 -3
- package/web-dist/components/camera-permission-view/CameraPermissionView.js +10 -10
- package/web-dist/components/card/Card.js +9 -9
- package/web-dist/components/card-back/CardBack.js +2 -2
- package/web-dist/components/card-hand/CardHand.js +2 -2
- package/web-dist/components/chat-list-item/ChatListItem.js +7 -7
- package/web-dist/components/checkbox/Checkbox.js +4 -4
- package/web-dist/components/checkbox-group/CheckboxGroup.js +4 -4
- package/web-dist/components/chess-board/ChessBoard.js +2 -2
- package/web-dist/components/chip/Chip.js +5 -5
- package/web-dist/components/chip-group/ChipGroup.js +5 -5
- package/web-dist/components/collection-editor/CollectionEditor.js +9 -9
- package/web-dist/components/content-rail/ContentRail.js +4 -4
- package/web-dist/components/data-table/DataTable.js +14 -14
- package/web-dist/components/date-picker/DatePicker.js +5 -5
- package/web-dist/components/dialog/Dialog.js +4 -4
- package/web-dist/components/divider/Divider.js +2 -2
- package/web-dist/components/empty-state/EmptyState.js +10 -10
- package/web-dist/components/explorer/Explorer.js +7 -7
- package/web-dist/components/field/Field.js +4 -4
- package/web-dist/components/file-explorer/FileExplorer.js +7 -7
- package/web-dist/components/flat-list/FlatList.js +5 -5
- package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +10 -10
- package/web-dist/components/form/Form.js +6 -6
- package/web-dist/components/form-actions/FormActions.js +6 -6
- package/web-dist/components/form-error/FormError.js +6 -6
- package/web-dist/components/game/Game.js +3 -3
- package/web-dist/components/game-entity/GameEntity.js +3 -3
- package/web-dist/components/game-field/GameField.js +3 -3
- package/web-dist/components/game-input-zone/GameInputZone.js +3 -3
- package/web-dist/components/game-measurement-probe/GameMeasurementProbe.js +3 -3
- package/web-dist/components/game-overlay/GameOverlay.js +3 -3
- package/web-dist/components/gradient/Gradient.js +3 -3
- package/web-dist/components/gradient-renderer-provider/GradientRendererProvider.js +3 -3
- package/web-dist/components/graph-view/GraphView.js +2 -2
- package/web-dist/components/grid/Grid.js +2 -2
- package/web-dist/components/grid-interactions/GridInteractions.d.ts +3 -0
- package/web-dist/components/grid-interactions/GridInteractions.js +371 -0
- package/web-dist/components/grid-interactions/index.d.ts +1 -0
- package/web-dist/components/grid-interactions/index.js +2 -0
- package/web-dist/components/grid-line-overlay/GridLineOverlay.js +2 -2
- package/web-dist/components/grid-ruler/GridRuler.js +2 -2
- package/web-dist/components/grid-view/GridView.js +1 -1
- package/web-dist/components/heading/Heading.js +2 -2
- package/web-dist/components/hero/Hero.js +9 -9
- package/web-dist/components/icon/Icon.js +2 -2
- package/web-dist/components/icon-button/IconButton.js +3 -3
- package/web-dist/components/image/Image.js +4 -4
- package/web-dist/components/keyboard-avoiding-view/KeyboardAvoidingView.js +2 -2
- package/web-dist/components/list/List.js +5 -5
- package/web-dist/components/list-item/ListItem.js +5 -5
- package/web-dist/components/list-section/ListSection.js +5 -5
- package/web-dist/components/matrix-grid/MatrixGrid.js +296 -47
- package/web-dist/components/media-card/MediaCard.js +9 -9
- package/web-dist/components/media-explorer/MediaExplorer.js +7 -7
- package/web-dist/components/message-bubble/MessageBubble.js +7 -7
- package/web-dist/components/metric-card/MetricCard.js +9 -9
- package/web-dist/components/missing-element/MissingElement.js +4 -4
- package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +10 -10
- package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +10 -10
- package/web-dist/components/opening-book/OpeningBook.js +2 -2
- package/web-dist/components/otp-form/OtpForm.js +10 -10
- package/web-dist/components/pagination/Pagination.js +4 -4
- package/web-dist/components/palette-item/PaletteItem.js +9 -9
- package/web-dist/components/playing-card/PlayingCard.js +2 -2
- package/web-dist/components/poker-training-table/PokerTrainingTable.js +2 -2
- package/web-dist/components/popover-menu/PopoverMenu.js +4 -4
- package/web-dist/components/post-card/PostCard.js +9 -9
- package/web-dist/components/product-card/ProductCard.js +9 -9
- package/web-dist/components/progress/Progress.js +4 -4
- package/web-dist/components/progress-ring/ProgressRing.js +4 -4
- package/web-dist/components/radio/Radio.js +5 -5
- package/web-dist/components/radio-group/RadioGroup.js +5 -5
- package/web-dist/components/rating/Rating.js +3 -3
- package/web-dist/components/reader/Reader.js +10 -10
- package/web-dist/components/scan-overlay/ScanOverlay.js +10 -10
- package/web-dist/components/screen/Screen.js +2 -2
- package/web-dist/components/screen-section/ScreenSection.js +4 -4
- package/web-dist/components/scroll-view/ScrollView.js +2 -2
- package/web-dist/components/search-input/SearchInput.js +4 -4
- package/web-dist/components/section-header/SectionHeader.js +4 -4
- package/web-dist/components/section-list/SectionList.js +5 -5
- package/web-dist/components/select/Select.js +4 -4
- package/web-dist/components/selectable-item/SelectableItem.js +2 -2
- package/web-dist/components/selection-provider/SelectionProvider.js +2 -2
- package/web-dist/components/sign-in-form/SignInForm.js +10 -10
- package/web-dist/components/sign-up-form/SignUpForm.js +10 -10
- package/web-dist/components/skeleton/Skeleton.js +12 -12
- package/web-dist/components/skeleton-card/SkeletonCard.js +12 -12
- package/web-dist/components/skeleton-list/SkeletonList.js +12 -12
- package/web-dist/components/skeleton-text/SkeletonText.js +12 -12
- package/web-dist/components/spatial-grid/SpatialGrid.js +1 -1
- package/web-dist/components/surface/Surface.js +2 -2
- package/web-dist/components/switch/Switch.js +1 -1
- package/web-dist/components/tab/Tab.js +2 -2
- package/web-dist/components/tab-list/TabList.js +2 -2
- package/web-dist/components/tab-panel/TabPanel.js +2 -2
- package/web-dist/components/tabletop-table/TabletopTable.js +2 -2
- package/web-dist/components/tabs/Tabs.js +2 -2
- package/web-dist/components/text/Text.js +2 -2
- package/web-dist/components/text-input/TextInput.js +4 -4
- package/web-dist/components/tile-grid/TileGrid.js +1 -1
- package/web-dist/components/time-grid/TimeGrid.js +2 -2
- package/web-dist/components/time-picker/TimePicker.js +5 -5
- package/web-dist/components/timeline/Timeline.js +4 -4
- package/web-dist/components/toast/Toast.js +2 -2
- package/web-dist/components/toast-provider/ToastProvider.js +2 -2
- package/web-dist/components/toolbar/Toolbar.js +9 -9
- package/web-dist/components/tree-item/TreeItem.js +9 -9
- package/web-dist/components/tree-view/TreeView.js +1 -1
- package/web-dist/components/uploader/Uploader.js +12 -12
- package/web-dist/components/view/View.js +2 -2
- package/web-dist/manifest.json +787 -772
- package/web-dist/runtime/ZoraProvider.js +3 -3
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { hitTestWorldRects, moveWorldRects, panViewport, resizeWorldRect, resolveWorldSnapCandidate, selectWorldRects, viewportToWorld, } from '@ankhorage/grid-view';
|
|
2
|
+
/*** Create a platform-neutral controlled interaction controller using grid-view geometry only. */
|
|
3
|
+
export function createGridInteractionsController(props) {
|
|
4
|
+
let currentProps = props;
|
|
5
|
+
let state = { kind: 'idle' };
|
|
6
|
+
let previousIntent;
|
|
7
|
+
const point = (pointer) => Number.isFinite(pointer.x) && Number.isFinite(pointer.y)
|
|
8
|
+
? viewportToWorld(pointer, currentProps.viewport)
|
|
9
|
+
: undefined;
|
|
10
|
+
const emit = (intent) => {
|
|
11
|
+
if (JSON.stringify(previousIntent) === JSON.stringify(intent))
|
|
12
|
+
return;
|
|
13
|
+
previousIntent = intent;
|
|
14
|
+
currentProps.onIntent(intent);
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
begin: (pointer, handle) => {
|
|
18
|
+
if (!canEdit(currentProps))
|
|
19
|
+
return;
|
|
20
|
+
const start = point(pointer);
|
|
21
|
+
if (start === undefined)
|
|
22
|
+
return;
|
|
23
|
+
if (pointer.spaceKey === true || pointer.altKey === true) {
|
|
24
|
+
state = { kind: 'pan', start };
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const target = hitTestWorldRects(currentProps.items, start);
|
|
28
|
+
if (target === undefined || isProtected(target)) {
|
|
29
|
+
state = { kind: 'marquee', start };
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (handle !== undefined && target.resizable !== false) {
|
|
33
|
+
state = { kind: 'resize', start, item: target, handle };
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const itemIds = currentProps.selectedIds?.includes(target.id) === true
|
|
37
|
+
? currentProps.selectedIds
|
|
38
|
+
: [target.id];
|
|
39
|
+
state = { kind: 'move', start, itemIds };
|
|
40
|
+
},
|
|
41
|
+
move: (pointer) => {
|
|
42
|
+
if (!canEdit(currentProps))
|
|
43
|
+
return;
|
|
44
|
+
const current = point(pointer);
|
|
45
|
+
if (current !== undefined)
|
|
46
|
+
emitPreview(state, current, currentProps, emit);
|
|
47
|
+
},
|
|
48
|
+
end: (pointer) => {
|
|
49
|
+
if (!canEdit(currentProps)) {
|
|
50
|
+
state = { kind: 'idle' };
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const current = point(pointer);
|
|
54
|
+
if (current !== undefined)
|
|
55
|
+
emitPreview(state, current, currentProps, emit);
|
|
56
|
+
state = { kind: 'idle' };
|
|
57
|
+
},
|
|
58
|
+
cancel: () => {
|
|
59
|
+
state = { kind: 'idle' };
|
|
60
|
+
},
|
|
61
|
+
keyDown: (key, pointer = { x: 0, y: 0 }) => {
|
|
62
|
+
if (!canEdit(currentProps))
|
|
63
|
+
return false;
|
|
64
|
+
const focusedId = currentProps.selectedIds?.at(-1);
|
|
65
|
+
const focused = currentProps.items.find((item) => item.id === focusedId);
|
|
66
|
+
if (!focused || isProtected(focused))
|
|
67
|
+
return false;
|
|
68
|
+
const increment = pointer.shiftKey === true ? 10 : 1;
|
|
69
|
+
const delta = keyToDelta(key, increment);
|
|
70
|
+
if (delta === undefined)
|
|
71
|
+
return false;
|
|
72
|
+
if (pointer.altKey === true) {
|
|
73
|
+
emit({
|
|
74
|
+
type: 'resize',
|
|
75
|
+
itemIds: [focused.id],
|
|
76
|
+
rects: [resizeWorldRect(focused, resizeHandleForDelta(delta), delta)],
|
|
77
|
+
});
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
emit({ type: 'move', itemIds: [focused.id], rects: moveWorldRects([focused], delta) });
|
|
81
|
+
return true;
|
|
82
|
+
},
|
|
83
|
+
update: (nextProps) => {
|
|
84
|
+
currentProps = nextProps;
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/*** Determines whether the component-wide interaction policy permits edit intents. */
|
|
89
|
+
function canEdit(props) {
|
|
90
|
+
return props.interactionPolicy !== 'passive';
|
|
91
|
+
}
|
|
92
|
+
/*** Emit one controlled preview/intention without retaining or mutating caller-owned item data. */
|
|
93
|
+
function emitPreview(state, current, props, emit) {
|
|
94
|
+
if (state.kind === 'idle')
|
|
95
|
+
return;
|
|
96
|
+
if (state.kind === 'pan') {
|
|
97
|
+
emit({
|
|
98
|
+
type: 'pan',
|
|
99
|
+
itemIds: [],
|
|
100
|
+
viewport: panViewport(props.viewport, {
|
|
101
|
+
x: state.start.x - current.x,
|
|
102
|
+
y: state.start.y - current.y,
|
|
103
|
+
}),
|
|
104
|
+
});
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (state.kind === 'marquee') {
|
|
108
|
+
const marquee = normalizeRect(state.start, current);
|
|
109
|
+
const itemIds = selectWorldRects(props.items, marquee, {
|
|
110
|
+
mode: props.marqueeMode ?? 'intersect',
|
|
111
|
+
}).filter((id) => {
|
|
112
|
+
const item = props.items.find((candidate) => candidate.id === id);
|
|
113
|
+
return item !== undefined && !isProtected(item);
|
|
114
|
+
});
|
|
115
|
+
emit({ type: 'marquee', itemIds, marquee });
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const delta = resolveSnapDelta(state, current, props);
|
|
119
|
+
if (state.kind === 'move') {
|
|
120
|
+
const selected = props.items.filter((item) => state.itemIds.includes(item.id));
|
|
121
|
+
emit({ type: 'move', itemIds: state.itemIds, rects: moveWorldRects(selected, delta) });
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
emit({
|
|
125
|
+
type: 'resize',
|
|
126
|
+
itemIds: [state.item.id],
|
|
127
|
+
rects: [resizeWorldRect(state.item, state.handle, delta)],
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/*** Resolve explicit per-axis candidate snapping without inventing geometry outside grid-view. */
|
|
131
|
+
function resolveSnapDelta(state, current, props) {
|
|
132
|
+
if (state.kind === 'idle' || state.kind === 'marquee' || state.kind === 'pan') {
|
|
133
|
+
return { x: 0, y: 0 };
|
|
134
|
+
}
|
|
135
|
+
const raw = { x: current.x - state.start.x, y: current.y - state.start.y };
|
|
136
|
+
if (props.snap?.enabled !== true)
|
|
137
|
+
return raw;
|
|
138
|
+
const anchor = state.kind === 'resize' ? state.item : props.items.find((item) => item.id === state.itemIds[0]);
|
|
139
|
+
if (anchor === undefined)
|
|
140
|
+
return raw;
|
|
141
|
+
const options = {
|
|
142
|
+
enabled: true,
|
|
143
|
+
tolerancePixels: props.snap.tolerancePixels,
|
|
144
|
+
priorities: props.snap.priorities,
|
|
145
|
+
};
|
|
146
|
+
return {
|
|
147
|
+
x: resolveWorldSnapCandidate(anchor.x + raw.x, props.snap.x ?? [], {
|
|
148
|
+
...options,
|
|
149
|
+
pixelsPerUnit: props.viewport.pixelsPerUnitX,
|
|
150
|
+
}) - anchor.x,
|
|
151
|
+
y: resolveWorldSnapCandidate(anchor.y + raw.y, props.snap.y ?? [], {
|
|
152
|
+
...options,
|
|
153
|
+
pixelsPerUnit: props.viewport.pixelsPerUnitY,
|
|
154
|
+
}) - anchor.y,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/*** Keep all caller-declared protected items out of selection and edit intents. */
|
|
158
|
+
function isProtected(item) {
|
|
159
|
+
return (item.disabled === true ||
|
|
160
|
+
item.locked === true ||
|
|
161
|
+
item.readOnly === true ||
|
|
162
|
+
item.passive === true);
|
|
163
|
+
}
|
|
164
|
+
/*** Normalize an arbitrary-direction drag into the world rectangle expected by grid-view selection. */
|
|
165
|
+
function normalizeRect(start, end) {
|
|
166
|
+
return {
|
|
167
|
+
x: Math.min(start.x, end.x),
|
|
168
|
+
y: Math.min(start.y, end.y),
|
|
169
|
+
width: Math.abs(end.x - start.x),
|
|
170
|
+
height: Math.abs(end.y - start.y),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/** Maps accessible arrow keys to caller-controlled world-space edit increments. */
|
|
174
|
+
function keyToDelta(key, increment) {
|
|
175
|
+
if (key === 'ArrowUp')
|
|
176
|
+
return { x: 0, y: -increment };
|
|
177
|
+
if (key === 'ArrowRight')
|
|
178
|
+
return { x: increment, y: 0 };
|
|
179
|
+
if (key === 'ArrowDown')
|
|
180
|
+
return { x: 0, y: increment };
|
|
181
|
+
if (key === 'ArrowLeft')
|
|
182
|
+
return { x: -increment, y: 0 };
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
/** Chooses the physical edge matching an accessible resize direction. */
|
|
186
|
+
function resizeHandleForDelta(delta) {
|
|
187
|
+
if (delta.x < 0)
|
|
188
|
+
return delta.y < 0 ? 'top-left' : delta.y > 0 ? 'bottom-left' : 'left';
|
|
189
|
+
return delta.y < 0 ? 'top-right' : delta.y > 0 ? 'bottom-right' : 'right';
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=createGridInteractionsController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createGridInteractionsController.js","sourceRoot":"","sources":["../../../../src/features/grid-interactions/application/createGridInteractionsController.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type GridPoint,\n type GridRect,\n type GridResizeHandle,\n hitTestWorldRects,\n moveWorldRects,\n panViewport,\n resizeWorldRect,\n resolveWorldSnapCandidate,\n selectWorldRects,\n viewportToWorld,\n} from '@ankhorage/grid-view';\n\nimport type {\n GridInteractionIntent,\n GridInteractionItem,\n GridInteractionPointer,\n GridInteractionsController,\n GridInteractionsControllerProps,\n} from '../../../types/grid-interactions';\n\ntype InteractionState =\n | { readonly kind: 'idle' }\n | { readonly kind: 'marquee'; readonly start: GridPoint }\n | { readonly kind: 'pan'; readonly start: GridPoint }\n | { readonly kind: 'move'; readonly start: GridPoint; readonly itemIds: readonly string[] }\n | {\n readonly kind: 'resize';\n readonly start: GridPoint;\n readonly item: GridInteractionItem;\n readonly handle: GridResizeHandle;\n };\n\n/*** Create a platform-neutral controlled interaction controller using grid-view geometry only. */\nexport function createGridInteractionsController(\n props: GridInteractionsControllerProps,\n): GridInteractionsController {\n let currentProps = props;\n let state: InteractionState = { kind: 'idle' };\n let previousIntent: GridInteractionIntent | undefined;\n const point = (pointer: GridInteractionPointer) =>\n Number.isFinite(pointer.x) && Number.isFinite(pointer.y)\n ? viewportToWorld(pointer, currentProps.viewport)\n : undefined;\n const emit = (intent: GridInteractionIntent) => {\n if (JSON.stringify(previousIntent) === JSON.stringify(intent)) return;\n previousIntent = intent;\n currentProps.onIntent(intent);\n };\n\n return {\n begin: (pointer, handle) => {\n if (!canEdit(currentProps)) return;\n const start = point(pointer);\n if (start === undefined) return;\n if (pointer.spaceKey === true || pointer.altKey === true) {\n state = { kind: 'pan', start };\n return;\n }\n const target = hitTestWorldRects(currentProps.items, start);\n if (target === undefined || isProtected(target)) {\n state = { kind: 'marquee', start };\n return;\n }\n if (handle !== undefined && target.resizable !== false) {\n state = { kind: 'resize', start, item: target, handle };\n return;\n }\n const itemIds =\n currentProps.selectedIds?.includes(target.id) === true\n ? currentProps.selectedIds\n : [target.id];\n state = { kind: 'move', start, itemIds };\n },\n move: (pointer) => {\n if (!canEdit(currentProps)) return;\n const current = point(pointer);\n if (current !== undefined) emitPreview(state, current, currentProps, emit);\n },\n end: (pointer) => {\n if (!canEdit(currentProps)) {\n state = { kind: 'idle' };\n return;\n }\n const current = point(pointer);\n if (current !== undefined) emitPreview(state, current, currentProps, emit);\n state = { kind: 'idle' };\n },\n cancel: () => {\n state = { kind: 'idle' };\n },\n keyDown: (key, pointer = { x: 0, y: 0 }) => {\n if (!canEdit(currentProps)) return false;\n const focusedId = currentProps.selectedIds?.at(-1);\n const focused = currentProps.items.find((item) => item.id === focusedId);\n if (!focused || isProtected(focused)) return false;\n const increment = pointer.shiftKey === true ? 10 : 1;\n const delta = keyToDelta(key, increment);\n if (delta === undefined) return false;\n if (pointer.altKey === true) {\n emit({\n type: 'resize',\n itemIds: [focused.id],\n rects: [resizeWorldRect(focused, resizeHandleForDelta(delta), delta)],\n });\n return true;\n }\n emit({ type: 'move', itemIds: [focused.id], rects: moveWorldRects([focused], delta) });\n return true;\n },\n update: (nextProps) => {\n currentProps = nextProps;\n },\n };\n}\n\n/*** Determines whether the component-wide interaction policy permits edit intents. */\nfunction canEdit(props: GridInteractionsControllerProps): boolean {\n return props.interactionPolicy !== 'passive';\n}\n\n/*** Emit one controlled preview/intention without retaining or mutating caller-owned item data. */\nfunction emitPreview(\n state: InteractionState,\n current: GridPoint,\n props: GridInteractionsControllerProps,\n emit: (intent: GridInteractionIntent) => void,\n) {\n if (state.kind === 'idle') return;\n if (state.kind === 'pan') {\n emit({\n type: 'pan',\n itemIds: [],\n viewport: panViewport(props.viewport, {\n x: state.start.x - current.x,\n y: state.start.y - current.y,\n }),\n });\n return;\n }\n if (state.kind === 'marquee') {\n const marquee = normalizeRect(state.start, current);\n const itemIds = selectWorldRects(props.items, marquee, {\n mode: props.marqueeMode ?? 'intersect',\n }).filter((id) => {\n const item = props.items.find((candidate) => candidate.id === id);\n return item !== undefined && !isProtected(item);\n });\n emit({ type: 'marquee', itemIds, marquee });\n return;\n }\n const delta = resolveSnapDelta(state, current, props);\n if (state.kind === 'move') {\n const selected = props.items.filter((item) => state.itemIds.includes(item.id));\n emit({ type: 'move', itemIds: state.itemIds, rects: moveWorldRects(selected, delta) });\n return;\n }\n emit({\n type: 'resize',\n itemIds: [state.item.id],\n rects: [resizeWorldRect(state.item, state.handle, delta)],\n });\n}\n\n/*** Resolve explicit per-axis candidate snapping without inventing geometry outside grid-view. */\nfunction resolveSnapDelta(\n state: InteractionState,\n current: GridPoint,\n props: GridInteractionsControllerProps,\n): GridPoint {\n if (state.kind === 'idle' || state.kind === 'marquee' || state.kind === 'pan') {\n return { x: 0, y: 0 };\n }\n const raw = { x: current.x - state.start.x, y: current.y - state.start.y };\n if (props.snap?.enabled !== true) return raw;\n const anchor =\n state.kind === 'resize' ? state.item : props.items.find((item) => item.id === state.itemIds[0]);\n if (anchor === undefined) return raw;\n const options = {\n enabled: true,\n tolerancePixels: props.snap.tolerancePixels,\n priorities: props.snap.priorities,\n };\n return {\n x:\n resolveWorldSnapCandidate(anchor.x + raw.x, props.snap.x ?? [], {\n ...options,\n pixelsPerUnit: props.viewport.pixelsPerUnitX,\n }) - anchor.x,\n y:\n resolveWorldSnapCandidate(anchor.y + raw.y, props.snap.y ?? [], {\n ...options,\n pixelsPerUnit: props.viewport.pixelsPerUnitY,\n }) - anchor.y,\n };\n}\n\n/*** Keep all caller-declared protected items out of selection and edit intents. */\nfunction isProtected(item: GridInteractionItem): boolean {\n return (\n item.disabled === true ||\n item.locked === true ||\n item.readOnly === true ||\n item.passive === true\n );\n}\n\n/*** Normalize an arbitrary-direction drag into the world rectangle expected by grid-view selection. */\nfunction normalizeRect(start: GridPoint, end: GridPoint): GridRect {\n return {\n x: Math.min(start.x, end.x),\n y: Math.min(start.y, end.y),\n width: Math.abs(end.x - start.x),\n height: Math.abs(end.y - start.y),\n };\n}\n\n/** Maps accessible arrow keys to caller-controlled world-space edit increments. */\nfunction keyToDelta(key: string, increment: number): GridPoint | undefined {\n if (key === 'ArrowUp') return { x: 0, y: -increment };\n if (key === 'ArrowRight') return { x: increment, y: 0 };\n if (key === 'ArrowDown') return { x: 0, y: increment };\n if (key === 'ArrowLeft') return { x: -increment, y: 0 };\n return undefined;\n}\n\n/** Chooses the physical edge matching an accessible resize direction. */\nfunction resizeHandleForDelta(delta: GridPoint): GridResizeHandle {\n if (delta.x < 0) return delta.y < 0 ? 'top-left' : delta.y > 0 ? 'bottom-left' : 'left';\n return delta.y < 0 ? 'top-right' : delta.y > 0 ? 'bottom-right' : 'right';\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Grid input is a code composition boundary because it accepts live geometry and callbacks. */
|
|
2
|
+
export declare const gridInteractionsMeta: {
|
|
3
|
+
readonly name: "GridInteractions";
|
|
4
|
+
readonly category: "foundation";
|
|
5
|
+
readonly description: "Maps native and web input to controlled world-space grid interaction intents.";
|
|
6
|
+
readonly directManifestNode: false;
|
|
7
|
+
readonly note: "Requires live viewport geometry, item data, and an executable intent callback; available through code APIs only.";
|
|
8
|
+
readonly allowedChildren: readonly [];
|
|
9
|
+
readonly props: {};
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=meta.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../../src/features/grid-interactions/meta.ts"],"names":[],"mappings":"AAEA,gGAAgG;AAChG,eAAO,MAAM,oBAAoB;;;;;;;;CAQK,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Grid input is a code composition boundary because it accepts live geometry and callbacks. */
|
|
2
|
+
export const gridInteractionsMeta = {
|
|
3
|
+
name: 'GridInteractions',
|
|
4
|
+
category: 'foundation',
|
|
5
|
+
description: 'Maps native and web input to controlled world-space grid interaction intents.',
|
|
6
|
+
directManifestNode: false,
|
|
7
|
+
note: 'Requires live viewport geometry, item data, and an executable intent callback; available through code APIs only.',
|
|
8
|
+
allowedChildren: [],
|
|
9
|
+
props: {},
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta.js","sourceRoot":"","sources":["../../../src/features/grid-interactions/meta.ts"],"names":[],"mappings":"AAEA,gGAAgG;AAChG,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,kBAAkB;IACxB,QAAQ,EAAE,YAAY;IACtB,WAAW,EAAE,+EAA+E;IAC5F,kBAAkB,EAAE,KAAK;IACzB,IAAI,EAAE,kHAAkH;IACxH,eAAe,EAAE,EAAE;IACnB,KAAK,EAAE,EAAE;CAC2B,CAAC","sourcesContent":["import type { ZoraComponentMeta } from '../../types/authoring';\n\n/** Grid input is a code composition boundary because it accepts live geometry and callbacks. */\nexport const gridInteractionsMeta = {\n name: 'GridInteractions',\n category: 'foundation',\n description: 'Maps native and web input to controlled world-space grid interaction intents.',\n directManifestNode: false,\n note: 'Requires live viewport geometry, item data, and an executable intent callback; available through code APIs only.',\n allowedChildren: [],\n props: {},\n} as const satisfies ZoraComponentMeta;\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { GridInteractionIntent, GridInteractionItem, GridInteractionPointer, GridInteractionsController, GridInteractionsControllerProps, GridInteractionSnap, GridInteractionsProps, } from '../../types/grid-interactions';
|
|
2
|
+
export { GridInteractions } from './adapters/inbound/GridInteractions';
|
|
3
|
+
export { createGridInteractionsController } from './application/createGridInteractionsController';
|
|
4
|
+
//# sourceMappingURL=public.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../../src/features/grid-interactions/public.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,EAC/B,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public.js","sourceRoot":"","sources":["../../../src/features/grid-interactions/public.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AACvE,OAAO,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC","sourcesContent":["export type {\n GridInteractionIntent,\n GridInteractionItem,\n GridInteractionPointer,\n GridInteractionsController,\n GridInteractionsControllerProps,\n GridInteractionSnap,\n GridInteractionsProps,\n} from '../../types/grid-interactions';\nexport { GridInteractions } from './adapters/inbound/GridInteractions';\nexport { createGridInteractionsController } from './application/createGridInteractionsController';\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MatrixGrid.d.ts","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MatrixGrid.d.ts","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AA4NrE,gGAAgG;AAChG,eAAO,MAAM,UAAU,uDAAsC,CAAC"}
|
|
@@ -1,55 +1,109 @@
|
|
|
1
|
-
import { getVisibleMatrixCells, } from '@ankhorage/grid-view';
|
|
2
|
-
import {
|
|
1
|
+
import { getMatrixCellPlacement, getVisibleMatrixCells, } from '@ankhorage/grid-view';
|
|
2
|
+
import { isRecord } from '@ankhorage/utility/object';
|
|
3
3
|
import React from 'react';
|
|
4
|
-
import { StyleSheet, View } from 'react-native';
|
|
4
|
+
import { Platform, Pressable as NativePressable, StyleSheet, View } from 'react-native';
|
|
5
5
|
import { GridView } from '../../../grid-view/public';
|
|
6
6
|
import { resolveSelectionEventIntent } from '../../../selection/public';
|
|
7
7
|
import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';
|
|
8
8
|
import { useZoraTheme } from '../../../theme/composition/useZoraTheme';
|
|
9
|
+
import { createMatrixGridSparseIndex } from '../../application/createMatrixGridSparseIndex';
|
|
9
10
|
import { resolveMatrixGridContentSize } from '../../application/resolveMatrixGridContentSize';
|
|
10
11
|
import { resolveMatrixGridSelection } from '../../application/resolveMatrixGridSelection';
|
|
12
|
+
import { MatrixGridKeyboardProxy } from './MatrixGridKeyboardProxy';
|
|
13
|
+
import { useMatrixGridKeyboardFocus } from './useMatrixGridKeyboardFocus';
|
|
11
14
|
/*** Compose the canonical GridView around released sparse matrix placement and culling geometry. */
|
|
12
|
-
function MatrixGridInner({ accessibilityLabel = 'Matrix grid', cells, height, interactionPolicy, layout, onSelectionChange, onViewportChange, overscanPixels = 160, renderCell, selectedCellIds = [], selectionMode = 'single', testID, viewport: controlledViewport, width, zoomX = 1, zoomY = 1, }) {
|
|
15
|
+
function MatrixGridInner({ accessibilityLabel = 'Matrix grid', cells, height, interactionPolicy, layout, onSelectionChange, onViewportChange, overscanPixels = 160, readOnly = false, renderCell, selectedCellIds = [], selectionMode = 'single', testID, viewport: controlledViewport, width, zoomX = 1, zoomY = 1, }) {
|
|
13
16
|
const { theme } = useZoraTheme();
|
|
14
17
|
const contentSize = React.useMemo(() => resolveMatrixGridContentSize(layout), [layout]);
|
|
15
18
|
const initialViewport = React.useMemo(() => ({ height, offsetX: 0, offsetY: 0, pixelsPerUnitX: zoomX, pixelsPerUnitY: zoomY, width }), [height, width, zoomX, zoomY]);
|
|
16
19
|
const [uncontrolledViewport, setUncontrolledViewport] = React.useState(initialViewport);
|
|
17
20
|
const viewport = controlledViewport ?? uncontrolledViewport;
|
|
18
|
-
const
|
|
19
|
-
const
|
|
21
|
+
const sparseIndex = React.useMemo(() => createMatrixGridSparseIndex(layout, cells), [cells, layout]);
|
|
22
|
+
const cellPlacements = React.useMemo(() => getVisibleMatrixCells(layout, cells, viewport, overscanPixels), [cells, layout, overscanPixels, viewport]);
|
|
23
|
+
const [visibleIds, setVisibleIds] = React.useState([]);
|
|
24
|
+
const anchorId = React.useRef(null);
|
|
20
25
|
const handleViewportChange = React.useCallback((proposal) => {
|
|
21
26
|
if (controlledViewport === undefined)
|
|
22
27
|
setUncontrolledViewport(proposal);
|
|
23
28
|
onViewportChange?.(proposal);
|
|
24
29
|
}, [controlledViewport, onViewportChange]);
|
|
25
30
|
const activateCell = React.useCallback((cell, event) => {
|
|
26
|
-
if (interactionPolicy === 'passive')
|
|
31
|
+
if (interactionPolicy === 'passive' || readOnly)
|
|
27
32
|
return;
|
|
28
|
-
const intent =
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
const intent = isRangeSelectionEvent(event)
|
|
34
|
+
? 'range'
|
|
35
|
+
: resolveSelectionEventIntent(event, 'pointer');
|
|
36
|
+
onSelectionChange?.(resolveMatrixGridSelection(sparseIndex.entries, selectedCellIds, cell.id, anchorId.current, intent, selectionMode));
|
|
37
|
+
if (intent !== 'range')
|
|
38
|
+
anchorId.current = cell.id;
|
|
39
|
+
}, [
|
|
40
|
+
interactionPolicy,
|
|
41
|
+
onSelectionChange,
|
|
42
|
+
readOnly,
|
|
43
|
+
selectedCellIds,
|
|
44
|
+
selectionMode,
|
|
45
|
+
sparseIndex.entries,
|
|
46
|
+
]);
|
|
47
|
+
const handleKeyboardNavigation = React.useCallback((targetId, originId, shiftKey) => {
|
|
48
|
+
anchorId.current ??= originId;
|
|
49
|
+
if (!shiftKey)
|
|
50
|
+
return;
|
|
51
|
+
const cell = sparseIndex.cellById.get(targetId);
|
|
52
|
+
if (cell)
|
|
53
|
+
activateCell(getMatrixCellPlacement(layout, cell), { shiftKey: true });
|
|
54
|
+
}, [activateCell, layout, sparseIndex]);
|
|
55
|
+
const keyboard = useMatrixGridKeyboardFocus(sparseIndex, interactionPolicy === 'passive', visibleIds, handleKeyboardNavigation);
|
|
56
|
+
const focusedPlacement = React.useMemo(() => {
|
|
57
|
+
const focusedCell = keyboard.focusedId === null ? undefined : sparseIndex.cellById.get(keyboard.focusedId);
|
|
58
|
+
return focusedCell ? getMatrixCellPlacement(layout, focusedCell) : undefined;
|
|
59
|
+
}, [keyboard.focusedId, layout, sparseIndex.cellById]);
|
|
60
|
+
const gridItems = React.useMemo(() => focusedPlacement && !cellPlacements.some((cell) => cell.id === focusedPlacement.id)
|
|
61
|
+
? [...cellPlacements, focusedPlacement]
|
|
62
|
+
: cellPlacements, [cellPlacements, focusedPlacement]);
|
|
63
|
+
const cellById = React.useMemo(() => new Map(gridItems.map((cell) => [cell.id, cell])), [gridItems]);
|
|
31
64
|
return (<View accessibilityLabel={accessibilityLabel}>
|
|
32
|
-
<GridView contentHeight={contentSize.height} contentWidth={contentSize.width} height={height} interactionPolicy={interactionPolicy} items={
|
|
33
|
-
const cell =
|
|
65
|
+
<GridView contentHeight={contentSize.height} contentWidth={contentSize.width} height={height} interactionPolicy={interactionPolicy} items={gridItems} focusedItemId={keyboard.focusedId ?? undefined} overscanPixels={0} onVisibleItemIdsChange={setVisibleIds} renderItem={(item) => {
|
|
66
|
+
const cell = cellById.get(item.id);
|
|
34
67
|
if (!cell)
|
|
35
68
|
return null;
|
|
36
|
-
return renderMatrixCell(cell, selectedCellIds, theme.semantics.neutral.divider, theme.colors.primary, renderCell, activateCell, testID);
|
|
69
|
+
return renderMatrixCell(cell, selectedCellIds, theme.semantics.neutral.divider, theme.colors.primary, renderCell, activateCell, keyboard, interactionPolicy === 'passive', readOnly, testID);
|
|
37
70
|
}} testID={testID} viewport={viewport} width={width} onViewportChange={handleViewportChange}/>
|
|
38
71
|
</View>);
|
|
39
72
|
}
|
|
40
73
|
/*** Render one positioned sparse cell with native/web accessible selection semantics. */
|
|
41
|
-
function renderMatrixCell(cell, selectedCellIds, dividerColor, selectedColor, renderCell, activateCell, testID) {
|
|
74
|
+
function renderMatrixCell(cell, selectedCellIds, dividerColor, selectedColor, renderCell, activateCell, keyboard, passive, readOnly, testID) {
|
|
42
75
|
const selected = selectedCellIds.includes(cell.id);
|
|
43
|
-
|
|
76
|
+
const canInteract = keyboard.tabStopId === cell.id;
|
|
77
|
+
return (<MatrixGridKeyboardProxy onKeyDown={(event) => {
|
|
78
|
+
if (keyboard.onKeyDown(cell.id, event.key, event.shiftKey))
|
|
79
|
+
return true;
|
|
80
|
+
if (!['Enter', ' '].includes(event.key))
|
|
81
|
+
return false;
|
|
82
|
+
if (passive || readOnly)
|
|
83
|
+
return false;
|
|
84
|
+
activateCell(cell, event);
|
|
85
|
+
return true;
|
|
86
|
+
}}>
|
|
87
|
+
<NativePressable key={cell.id} accessibilityActions={[{ name: 'activate' }]} accessibilityLabel={`Cell ${cell.id}`} accessibilityRole="button" accessibilityState={{ disabled: passive, selected }} disabled={passive} focusable={Platform.OS !== 'web' || canInteract} style={[
|
|
44
88
|
styles.cell,
|
|
45
89
|
{
|
|
46
|
-
borderColor: selected ? selectedColor : dividerColor,
|
|
90
|
+
borderColor: selected || keyboard.focusedId === cell.id ? selectedColor : dividerColor,
|
|
47
91
|
height: '100%',
|
|
48
92
|
width: '100%',
|
|
49
93
|
},
|
|
50
|
-
]} testID={testID === undefined ? undefined : `${testID}-cell-${cell.id}`} onPress={(event) => activateCell(cell, event)}>
|
|
51
|
-
|
|
52
|
-
|
|
94
|
+
]} testID={testID === undefined ? undefined : `${testID}-cell-${cell.id}`} onAccessibilityAction={() => activateCell(cell, {})} onFocus={() => keyboard.onFocus(cell.id)} onPress={(event) => activateCell(cell, event)} ref={(node) => keyboard.registerCell(cell.id, node)}>
|
|
95
|
+
{renderCell(cell)}
|
|
96
|
+
</NativePressable>
|
|
97
|
+
</MatrixGridKeyboardProxy>);
|
|
98
|
+
}
|
|
99
|
+
/*** Recognize range intent without changing the shared replace-or-toggle selection contract. */
|
|
100
|
+
function isRangeSelectionEvent(event) {
|
|
101
|
+
if (!isRecord(event))
|
|
102
|
+
return false;
|
|
103
|
+
if (event.shiftKey === true)
|
|
104
|
+
return true;
|
|
105
|
+
return ((isRecord(event.nativeEvent) && event.nativeEvent.shiftKey === true) ||
|
|
106
|
+
(isRecord(event.originalEvent) && event.originalEvent.shiftKey === true));
|
|
53
107
|
}
|
|
54
108
|
const styles = StyleSheet.create({
|
|
55
109
|
cell: { borderWidth: 1, height: '100%', overflow: 'hidden', width: '100%' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MatrixGrid.js","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getVisibleMatrixCells,\n type GridMatrixCellPlacement,\n type GridViewport,\n} from '@ankhorage/grid-view';\nimport { Pressable } from '@ankhorage/surface';\nimport React from 'react';\nimport { StyleSheet, View } from 'react-native';\n\nimport type { MatrixGridProps } from '../../../../types/matrix-grid';\nimport { GridView } from '../../../grid-view/public';\nimport { resolveSelectionEventIntent } from '../../../selection/public';\nimport { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';\nimport { useZoraTheme } from '../../../theme/composition/useZoraTheme';\nimport { resolveMatrixGridContentSize } from '../../application/resolveMatrixGridContentSize';\nimport { resolveMatrixGridSelection } from '../../application/resolveMatrixGridSelection';\n\n/*** Compose the canonical GridView around released sparse matrix placement and culling geometry. */\nfunction MatrixGridInner({\n accessibilityLabel = 'Matrix grid',\n cells,\n height,\n interactionPolicy,\n layout,\n onSelectionChange,\n onViewportChange,\n overscanPixels = 160,\n renderCell,\n selectedCellIds = [],\n selectionMode = 'single',\n testID,\n viewport: controlledViewport,\n width,\n zoomX = 1,\n zoomY = 1,\n}: MatrixGridProps) {\n const { theme } = useZoraTheme();\n const contentSize = React.useMemo(() => resolveMatrixGridContentSize(layout), [layout]);\n const initialViewport = React.useMemo<GridViewport>(\n () => ({ height, offsetX: 0, offsetY: 0, pixelsPerUnitX: zoomX, pixelsPerUnitY: zoomY, width }),\n [height, width, zoomX, zoomY],\n );\n const [uncontrolledViewport, setUncontrolledViewport] = React.useState(initialViewport);\n const viewport = controlledViewport ?? uncontrolledViewport;\n const visibleCells = React.useMemo(\n () => getVisibleMatrixCells(layout, cells, viewport, overscanPixels),\n [cells, layout, overscanPixels, viewport],\n );\n\n const visibleCellById = React.useMemo(\n () => new Map(visibleCells.map((cell) => [cell.id, cell])),\n [visibleCells],\n );\n\n const handleViewportChange = React.useCallback(\n (proposal: GridViewport) => {\n if (controlledViewport === undefined) setUncontrolledViewport(proposal);\n onViewportChange?.(proposal);\n },\n [controlledViewport, onViewportChange],\n );\n\n const activateCell = React.useCallback(\n (cell: GridMatrixCellPlacement, event: unknown) => {\n if (interactionPolicy === 'passive') return;\n const intent = resolveSelectionEventIntent(event, 'pointer');\n onSelectionChange?.(\n resolveMatrixGridSelection(selectedCellIds, cell.id, intent, selectionMode),\n );\n },\n [interactionPolicy, onSelectionChange, selectedCellIds, selectionMode],\n );\n return (\n <View accessibilityLabel={accessibilityLabel}>\n <GridView\n contentHeight={contentSize.height}\n contentWidth={contentSize.width}\n height={height}\n interactionPolicy={interactionPolicy}\n items={visibleCells}\n overscanPixels={0}\n renderItem={(item) => {\n const cell = visibleCellById.get(item.id);\n if (!cell) return null;\n return renderMatrixCell(\n cell,\n selectedCellIds,\n theme.semantics.neutral.divider,\n theme.colors.primary,\n renderCell,\n activateCell,\n testID,\n );\n }}\n testID={testID}\n viewport={viewport}\n width={width}\n onViewportChange={handleViewportChange}\n />\n </View>\n );\n}\n\n/*** Render one positioned sparse cell with native/web accessible selection semantics. */\nfunction renderMatrixCell(\n cell: GridMatrixCellPlacement,\n selectedCellIds: readonly string[],\n dividerColor: string,\n selectedColor: string,\n renderCell: MatrixGridProps['renderCell'],\n activateCell: (cell: GridMatrixCellPlacement, event: unknown) => void,\n testID: string | undefined,\n) {\n const selected = selectedCellIds.includes(cell.id);\n return (\n <Pressable\n key={cell.id}\n accessibilityLabel={`Cell ${cell.id}`}\n accessibilityRole=\"button\"\n accessibilityState={{ selected }}\n style={[\n styles.cell,\n {\n borderColor: selected ? selectedColor : dividerColor,\n height: '100%',\n width: '100%',\n },\n ]}\n testID={testID === undefined ? undefined : `${testID}-cell-${cell.id}`}\n onPress={(event) => activateCell(cell, event)}\n >\n {renderCell(cell)}\n </Pressable>\n );\n}\n\nconst styles = StyleSheet.create({\n cell: { borderWidth: 1, height: '100%', overflow: 'hidden', width: '100%' },\n});\n\n/*** A code-first generic sparse matrix grid; formulas and domain vocabulary remain external. */\nexport const MatrixGrid = withZoraThemeScope(MatrixGridInner);\n"]}
|
|
1
|
+
{"version":3,"file":"MatrixGrid.js","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGrid.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getMatrixCellPlacement,\n getVisibleMatrixCells,\n type GridMatrixCellPlacement,\n type GridViewport,\n} from '@ankhorage/grid-view';\nimport { isRecord } from '@ankhorage/utility/object';\nimport React from 'react';\nimport { Platform, Pressable as NativePressable, StyleSheet, View } from 'react-native';\n\nimport type { MatrixGridProps } from '../../../../types/matrix-grid';\nimport { GridView } from '../../../grid-view/public';\nimport { resolveSelectionEventIntent } from '../../../selection/public';\nimport { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';\nimport { useZoraTheme } from '../../../theme/composition/useZoraTheme';\nimport { createMatrixGridSparseIndex } from '../../application/createMatrixGridSparseIndex';\nimport { resolveMatrixGridContentSize } from '../../application/resolveMatrixGridContentSize';\nimport { resolveMatrixGridSelection } from '../../application/resolveMatrixGridSelection';\nimport { MatrixGridKeyboardProxy } from './MatrixGridKeyboardProxy';\nimport { useMatrixGridKeyboardFocus } from './useMatrixGridKeyboardFocus';\n\n/*** Compose the canonical GridView around released sparse matrix placement and culling geometry. */\nfunction MatrixGridInner({\n accessibilityLabel = 'Matrix grid',\n cells,\n height,\n interactionPolicy,\n layout,\n onSelectionChange,\n onViewportChange,\n overscanPixels = 160,\n readOnly = false,\n renderCell,\n selectedCellIds = [],\n selectionMode = 'single',\n testID,\n viewport: controlledViewport,\n width,\n zoomX = 1,\n zoomY = 1,\n}: MatrixGridProps) {\n const { theme } = useZoraTheme();\n const contentSize = React.useMemo(() => resolveMatrixGridContentSize(layout), [layout]);\n const initialViewport = React.useMemo<GridViewport>(\n () => ({ height, offsetX: 0, offsetY: 0, pixelsPerUnitX: zoomX, pixelsPerUnitY: zoomY, width }),\n [height, width, zoomX, zoomY],\n );\n const [uncontrolledViewport, setUncontrolledViewport] = React.useState(initialViewport);\n const viewport = controlledViewport ?? uncontrolledViewport;\n const sparseIndex = React.useMemo(\n () => createMatrixGridSparseIndex(layout, cells),\n [cells, layout],\n );\n const cellPlacements = React.useMemo(\n () => getVisibleMatrixCells(layout, cells, viewport, overscanPixels),\n [cells, layout, overscanPixels, viewport],\n );\n const [visibleIds, setVisibleIds] = React.useState<readonly string[]>([]);\n const anchorId = React.useRef<string | null>(null);\n\n const handleViewportChange = React.useCallback(\n (proposal: GridViewport) => {\n if (controlledViewport === undefined) setUncontrolledViewport(proposal);\n onViewportChange?.(proposal);\n },\n [controlledViewport, onViewportChange],\n );\n\n const activateCell = React.useCallback(\n (cell: GridMatrixCellPlacement, event: unknown) => {\n if (interactionPolicy === 'passive' || readOnly) return;\n const intent = isRangeSelectionEvent(event)\n ? 'range'\n : resolveSelectionEventIntent(event, 'pointer');\n onSelectionChange?.(\n resolveMatrixGridSelection(\n sparseIndex.entries,\n selectedCellIds,\n cell.id,\n anchorId.current,\n intent,\n selectionMode,\n ),\n );\n if (intent !== 'range') anchorId.current = cell.id;\n },\n [\n interactionPolicy,\n onSelectionChange,\n readOnly,\n selectedCellIds,\n selectionMode,\n sparseIndex.entries,\n ],\n );\n const handleKeyboardNavigation = React.useCallback(\n (targetId: string, originId: string, shiftKey: boolean) => {\n anchorId.current ??= originId;\n if (!shiftKey) return;\n const cell = sparseIndex.cellById.get(targetId);\n if (cell) activateCell(getMatrixCellPlacement(layout, cell), { shiftKey: true });\n },\n [activateCell, layout, sparseIndex],\n );\n const keyboard = useMatrixGridKeyboardFocus(\n sparseIndex,\n interactionPolicy === 'passive',\n visibleIds,\n handleKeyboardNavigation,\n );\n const focusedPlacement = React.useMemo(() => {\n const focusedCell =\n keyboard.focusedId === null ? undefined : sparseIndex.cellById.get(keyboard.focusedId);\n return focusedCell ? getMatrixCellPlacement(layout, focusedCell) : undefined;\n }, [keyboard.focusedId, layout, sparseIndex.cellById]);\n const gridItems = React.useMemo(\n () =>\n focusedPlacement && !cellPlacements.some((cell) => cell.id === focusedPlacement.id)\n ? [...cellPlacements, focusedPlacement]\n : cellPlacements,\n [cellPlacements, focusedPlacement],\n );\n const cellById = React.useMemo(\n () => new Map(gridItems.map((cell) => [cell.id, cell])),\n [gridItems],\n );\n\n return (\n <View accessibilityLabel={accessibilityLabel}>\n <GridView\n contentHeight={contentSize.height}\n contentWidth={contentSize.width}\n height={height}\n interactionPolicy={interactionPolicy}\n items={gridItems}\n focusedItemId={keyboard.focusedId ?? undefined}\n overscanPixels={0}\n onVisibleItemIdsChange={setVisibleIds}\n renderItem={(item) => {\n const cell = cellById.get(item.id);\n if (!cell) return null;\n return renderMatrixCell(\n cell,\n selectedCellIds,\n theme.semantics.neutral.divider,\n theme.colors.primary,\n renderCell,\n activateCell,\n keyboard,\n interactionPolicy === 'passive',\n readOnly,\n testID,\n );\n }}\n testID={testID}\n viewport={viewport}\n width={width}\n onViewportChange={handleViewportChange}\n />\n </View>\n );\n}\n\n/*** Render one positioned sparse cell with native/web accessible selection semantics. */\nfunction renderMatrixCell(\n cell: GridMatrixCellPlacement,\n selectedCellIds: readonly string[],\n dividerColor: string,\n selectedColor: string,\n renderCell: MatrixGridProps['renderCell'],\n activateCell: (cell: GridMatrixCellPlacement, event: unknown) => void,\n keyboard: ReturnType<typeof useMatrixGridKeyboardFocus>,\n passive: boolean,\n readOnly: boolean,\n testID: string | undefined,\n) {\n const selected = selectedCellIds.includes(cell.id);\n const canInteract = keyboard.tabStopId === cell.id;\n return (\n <MatrixGridKeyboardProxy\n onKeyDown={(event) => {\n if (keyboard.onKeyDown(cell.id, event.key, event.shiftKey)) return true;\n if (!['Enter', ' '].includes(event.key)) return false;\n if (passive || readOnly) return false;\n activateCell(cell, event);\n return true;\n }}\n >\n <NativePressable\n key={cell.id}\n accessibilityActions={[{ name: 'activate' }]}\n accessibilityLabel={`Cell ${cell.id}`}\n accessibilityRole=\"button\"\n accessibilityState={{ disabled: passive, selected }}\n disabled={passive}\n focusable={Platform.OS !== 'web' || canInteract}\n style={[\n styles.cell,\n {\n borderColor: selected || keyboard.focusedId === cell.id ? selectedColor : dividerColor,\n height: '100%',\n width: '100%',\n },\n ]}\n testID={testID === undefined ? undefined : `${testID}-cell-${cell.id}`}\n onAccessibilityAction={() => activateCell(cell, {})}\n onFocus={() => keyboard.onFocus(cell.id)}\n onPress={(event) => activateCell(cell, event)}\n ref={(node) => keyboard.registerCell(cell.id, node)}\n >\n {renderCell(cell)}\n </NativePressable>\n </MatrixGridKeyboardProxy>\n );\n}\n\n/*** Recognize range intent without changing the shared replace-or-toggle selection contract. */\nfunction isRangeSelectionEvent(event: unknown): boolean {\n if (!isRecord(event)) return false;\n if (event.shiftKey === true) return true;\n return (\n (isRecord(event.nativeEvent) && event.nativeEvent.shiftKey === true) ||\n (isRecord(event.originalEvent) && event.originalEvent.shiftKey === true)\n );\n}\n\nconst styles = StyleSheet.create({\n cell: { borderWidth: 1, height: '100%', overflow: 'hidden', width: '100%' },\n});\n\n/*** A code-first generic sparse matrix grid; formulas and domain vocabulary remain external. */\nexport const MatrixGrid = withZoraThemeScope(MatrixGridInner);\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
/*** Provides the native fallback type surface; RNW resolves the web adapter at runtime. */
|
|
3
|
+
export declare function MatrixGridKeyboardProxy({ children }: MatrixGridKeyboardProxyProps): React.JSX.Element;
|
|
4
|
+
interface MatrixGridKeyboardProxyProps {
|
|
5
|
+
readonly children: React.ReactNode;
|
|
6
|
+
readonly onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => boolean;
|
|
7
|
+
}
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=MatrixGridKeyboardProxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MatrixGridKeyboardProxy.d.ts","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,2FAA2F;AAC3F,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,EAAE,4BAA4B,qBAEjF;AAED,UAAU,4BAA4B;IACpC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,OAAO,CAAC;CAC7E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MatrixGridKeyboardProxy.js","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.tsx"],"names":[],"mappings":"AAEA,2FAA2F;AAC3F,MAAM,UAAU,uBAAuB,CAAC,EAAE,QAAQ,EAAgC;IAChF,OAAO,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;AACzB,CAAC","sourcesContent":["import type React from 'react';\n\n/*** Provides the native fallback type surface; RNW resolves the web adapter at runtime. */\nexport function MatrixGridKeyboardProxy({ children }: MatrixGridKeyboardProxyProps) {\n return <>{children}</>;\n}\n\ninterface MatrixGridKeyboardProxyProps {\n readonly children: React.ReactNode;\n readonly onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => boolean;\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
/*** Retain native accessibility focus while physical-key dispatch remains a web host concern. */
|
|
3
|
+
export declare function MatrixGridKeyboardProxy({ children }: MatrixGridKeyboardProxyProps): React.JSX.Element;
|
|
4
|
+
interface MatrixGridKeyboardProxyProps {
|
|
5
|
+
readonly children: React.ReactNode;
|
|
6
|
+
readonly onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => boolean;
|
|
7
|
+
}
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=MatrixGridKeyboardProxy.native.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MatrixGridKeyboardProxy.native.d.ts","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,iGAAiG;AACjG,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,EAAE,4BAA4B,qBAEjF;AAED,UAAU,4BAA4B;IACpC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,OAAO,CAAC;CAC7E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MatrixGridKeyboardProxy.native.js","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.native.tsx"],"names":[],"mappings":"AAEA,iGAAiG;AACjG,MAAM,UAAU,uBAAuB,CAAC,EAAE,QAAQ,EAAgC;IAChF,OAAO,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC;AACzB,CAAC","sourcesContent":["import type React from 'react';\n\n/*** Retain native accessibility focus while physical-key dispatch remains a web host concern. */\nexport function MatrixGridKeyboardProxy({ children }: MatrixGridKeyboardProxyProps) {\n return <>{children}</>;\n}\n\ninterface MatrixGridKeyboardProxyProps {\n readonly children: React.ReactNode;\n readonly onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => boolean;\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
/*** Bridge browser keyboard events into the matrix's platform-neutral focus policy. */
|
|
3
|
+
export declare function MatrixGridKeyboardProxy({ children, onKeyDown }: MatrixGridKeyboardProxyProps): React.JSX.Element;
|
|
4
|
+
interface MatrixGridKeyboardProxyProps {
|
|
5
|
+
readonly children: React.ReactNode;
|
|
6
|
+
readonly onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => boolean;
|
|
7
|
+
}
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=MatrixGridKeyboardProxy.web.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MatrixGridKeyboardProxy.web.d.ts","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,uFAAuF;AACvF,wBAAgB,uBAAuB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,4BAA4B,qBAY5F;AAwBD,UAAU,4BAA4B;IACpC,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,OAAO,CAAC;CAC7E"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*** Bridge browser keyboard events into the matrix's platform-neutral focus policy. */
|
|
2
|
+
export function MatrixGridKeyboardProxy({ children, onKeyDown }) {
|
|
3
|
+
return (<div onKeyDownCapture={(event) => {
|
|
4
|
+
if (isNestedInteractiveElement(event.target, event.currentTarget))
|
|
5
|
+
return;
|
|
6
|
+
if (onKeyDown(event))
|
|
7
|
+
event.preventDefault();
|
|
8
|
+
}} style={{ display: 'flex', flex: 1 }}>
|
|
9
|
+
{children}
|
|
10
|
+
</div>);
|
|
11
|
+
}
|
|
12
|
+
/*** Leave editable and independently interactive cell content in control of its own keyboard events. */
|
|
13
|
+
function isNestedInteractiveElement(target, boundary) {
|
|
14
|
+
if (target === boundary || !hasClosest(target))
|
|
15
|
+
return false;
|
|
16
|
+
const interactiveElement = target.closest(interactiveSelector);
|
|
17
|
+
return interactiveElement !== null && interactiveElement !== getFirstElementChild(boundary);
|
|
18
|
+
}
|
|
19
|
+
/*** Recognize the browser-only closest capability without leaking DOM globals into shared code. */
|
|
20
|
+
function hasClosest(target) {
|
|
21
|
+
return 'closest' in target && typeof target.closest === 'function';
|
|
22
|
+
}
|
|
23
|
+
/*** Exempt the cell's own Pressable while preserving keyboard ownership for nested controls. */
|
|
24
|
+
function getFirstElementChild(boundary) {
|
|
25
|
+
return 'firstElementChild' in boundary ? boundary.firstElementChild : undefined;
|
|
26
|
+
}
|
|
27
|
+
const interactiveSelector = 'a, button, input, select, textarea, [contenteditable="true"], [role="button"], [role="checkbox"], [role="combobox"], [role="link"], [role="menuitem"], [role="option"], [role="slider"], [role="spinbutton"], [role="switch"], [role="tab"]';
|
|
28
|
+
//# sourceMappingURL=MatrixGridKeyboardProxy.web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MatrixGridKeyboardProxy.web.js","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/MatrixGridKeyboardProxy.web.tsx"],"names":[],"mappings":"AAEA,uFAAuF;AACvF,MAAM,UAAU,uBAAuB,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAgC;IAC3F,OAAO,CACL,CAAC,GAAG,CACF,gBAAgB,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE;YAC1B,IAAI,0BAA0B,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC;gBAAE,OAAO;YAC1E,IAAI,SAAS,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,cAAc,EAAE,CAAC;QAC/C,CAAC,CAAC,CACF,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAEpC;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC;AAED,wGAAwG;AACxG,SAAS,0BAA0B,CAAC,MAAmB,EAAE,QAAqB;IAC5E,IAAI,MAAM,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7D,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC/D,OAAO,kBAAkB,KAAK,IAAI,IAAI,kBAAkB,KAAK,oBAAoB,CAAC,QAAQ,CAAC,CAAC;AAC9F,CAAC;AAED,mGAAmG;AACnG,SAAS,UAAU,CACjB,MAAmB;IAEnB,OAAO,SAAS,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU,CAAC;AACrE,CAAC;AAED,gGAAgG;AAChG,SAAS,oBAAoB,CAAC,QAAqB;IACjD,OAAO,mBAAmB,IAAI,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;AAClF,CAAC;AAED,MAAM,mBAAmB,GACvB,6OAA6O,CAAC","sourcesContent":["import type React from 'react';\n\n/*** Bridge browser keyboard events into the matrix's platform-neutral focus policy. */\nexport function MatrixGridKeyboardProxy({ children, onKeyDown }: MatrixGridKeyboardProxyProps) {\n return (\n <div\n onKeyDownCapture={(event) => {\n if (isNestedInteractiveElement(event.target, event.currentTarget)) return;\n if (onKeyDown(event)) event.preventDefault();\n }}\n style={{ display: 'flex', flex: 1 }}\n >\n {children}\n </div>\n );\n}\n\n/*** Leave editable and independently interactive cell content in control of its own keyboard events. */\nfunction isNestedInteractiveElement(target: EventTarget, boundary: EventTarget): boolean {\n if (target === boundary || !hasClosest(target)) return false;\n const interactiveElement = target.closest(interactiveSelector);\n return interactiveElement !== null && interactiveElement !== getFirstElementChild(boundary);\n}\n\n/*** Recognize the browser-only closest capability without leaking DOM globals into shared code. */\nfunction hasClosest(\n target: EventTarget,\n): target is EventTarget & { closest: (selector: string) => unknown } {\n return 'closest' in target && typeof target.closest === 'function';\n}\n\n/*** Exempt the cell's own Pressable while preserving keyboard ownership for nested controls. */\nfunction getFirstElementChild(boundary: EventTarget): unknown {\n return 'firstElementChild' in boundary ? boundary.firstElementChild : undefined;\n}\n\nconst interactiveSelector =\n 'a, button, input, select, textarea, [contenteditable=\"true\"], [role=\"button\"], [role=\"checkbox\"], [role=\"combobox\"], [role=\"link\"], [role=\"menuitem\"], [role=\"option\"], [role=\"slider\"], [role=\"spinbutton\"], [role=\"switch\"], [role=\"tab\"]';\n\ninterface MatrixGridKeyboardProxyProps {\n readonly children: React.ReactNode;\n readonly onKeyDown: (event: React.KeyboardEvent<HTMLDivElement>) => boolean;\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MatrixGridSparseIndex } from '../../application/createMatrixGridSparseIndex';
|
|
2
|
+
/*** Keep one roving focus target and restore it after GridView virtualizes a sparse cell. */
|
|
3
|
+
export declare function useMatrixGridKeyboardFocus(index: MatrixGridSparseIndex, disabled: boolean, visibleIds: readonly string[], onNavigate: (targetId: string, originId: string, shiftKey: boolean) => void): {
|
|
4
|
+
focusedId: string | null;
|
|
5
|
+
onFocus: (id: string) => void;
|
|
6
|
+
onKeyDown: (id: string, key: string, shiftKey: boolean) => boolean;
|
|
7
|
+
registerCell: (id: string, node: FocusableCell | null) => void;
|
|
8
|
+
tabStopId: string | undefined;
|
|
9
|
+
};
|
|
10
|
+
interface FocusableCell {
|
|
11
|
+
focus: () => void;
|
|
12
|
+
}
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=useMatrixGridKeyboardFocus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useMatrixGridKeyboardFocus.d.ts","sourceRoot":"","sources":["../../../../../src/features/matrix-grid/adapters/inbound/useMatrixGridKeyboardFocus.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AAG3F,6FAA6F;AAC7F,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,qBAAqB,EAC5B,QAAQ,EAAE,OAAO,EACjB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI;;kBAYpC,MAAM;oBAmBtC,MAAM,OAAO,MAAM,YAAY,OAAO,KAAG,OAAO;uBAbX,MAAM,QAAQ,aAAa,GAAG,IAAI;;EAqC/E;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB"}
|