@ankhorage/zora 22.1.4 → 23.1.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 +12 -0
- package/README.md +1 -1
- package/dist/constants/authoring.d.ts +4 -4
- package/dist/constants/authoring.d.ts.map +1 -1
- package/dist/constants/authoring.js +2 -0
- package/dist/constants/authoring.js.map +1 -1
- package/dist/features/accordion/accordionItemMeta.d.ts +1 -1
- package/dist/features/auth/adapters/inbound/AuthScreen.d.ts +10 -0
- package/dist/features/auth/adapters/inbound/AuthScreen.d.ts.map +1 -0
- package/dist/features/auth/adapters/inbound/AuthScreen.js +67 -0
- package/dist/features/auth/adapters/inbound/AuthScreen.js.map +1 -0
- package/dist/features/auth/authScreenMeta.d.ts +204 -0
- package/dist/features/auth/authScreenMeta.d.ts.map +1 -0
- package/dist/features/auth/authScreenMeta.js +112 -0
- package/dist/features/auth/authScreenMeta.js.map +1 -0
- package/dist/features/auth/public.d.ts +2 -1
- package/dist/features/auth/public.d.ts.map +1 -1
- package/dist/features/auth/public.js +1 -0
- package/dist/features/auth/public.js.map +1 -1
- package/dist/features/bottom-sheet/bottomSheetMeta.d.ts +1 -1
- package/dist/features/card/cardMeta.d.ts +1 -1
- package/dist/features/card/mediaCardMeta.d.ts +1 -1
- package/dist/features/card/postCardMeta.d.ts +1 -1
- package/dist/features/chat/messageBubbleMeta.d.ts +1 -1
- package/dist/features/dialog/dialogMeta.d.ts +2 -2
- package/dist/features/gradient/gradientMeta.d.ts +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.d.ts +2 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.js +2 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.js +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.js +12 -4
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.js.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.d.ts +2 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.d.ts.map +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js +3 -3
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js.map +1 -1
- package/dist/features/keyboard-avoiding-view/keyboardAvoidingViewMeta.d.ts +1 -1
- package/dist/features/layout/gridMeta.d.ts +1 -1
- package/dist/features/layout/screenMeta.d.ts +1 -1
- package/dist/features/layout/scrollViewMeta.d.ts +1 -1
- package/dist/features/layout/viewMeta.d.ts +1 -1
- package/dist/features/list/flatListMeta.d.ts +1 -1
- package/dist/features/list/sectionListMeta.d.ts +1 -1
- package/dist/features/reader/meta.d.ts +2 -2
- package/dist/features/registry/ZORA_COMPONENT_REGISTRY.d.ts.map +1 -1
- package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js +2 -1
- package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js.map +1 -1
- package/dist/features/registry/bindableComponentMeta.d.ts +2 -2
- 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/scanner/meta.d.ts +2 -2
- package/dist/features/section/screenSectionMeta.d.ts +1 -1
- package/dist/features/selection/adapters/inbound/SelectableItem.d.ts +1 -5
- package/dist/features/selection/adapters/inbound/SelectableItem.d.ts.map +1 -1
- package/dist/features/selection/adapters/inbound/SelectableItem.js +30 -54
- package/dist/features/selection/adapters/inbound/SelectableItem.js.map +1 -1
- package/dist/features/selection/adapters/inbound/SelectionProvider.d.ts +2 -6
- package/dist/features/selection/adapters/inbound/SelectionProvider.d.ts.map +1 -1
- package/dist/features/selection/adapters/inbound/SelectionProvider.js +36 -32
- package/dist/features/selection/adapters/inbound/SelectionProvider.js.map +1 -1
- package/dist/features/selection/application/resolveSelectionEventIntent.d.ts +5 -0
- package/dist/features/selection/application/resolveSelectionEventIntent.d.ts.map +1 -0
- package/dist/features/selection/application/resolveSelectionEventIntent.js +49 -0
- package/dist/features/selection/application/resolveSelectionEventIntent.js.map +1 -0
- package/dist/features/selection/public.d.ts +2 -0
- package/dist/features/selection/public.d.ts.map +1 -1
- package/dist/features/selection/public.js +1 -0
- package/dist/features/selection/public.js.map +1 -1
- package/dist/features/selection/utils/resolveSelectionNextIds.d.ts +4 -5
- package/dist/features/selection/utils/resolveSelectionNextIds.d.ts.map +1 -1
- package/dist/features/selection/utils/resolveSelectionNextIds.js +6 -13
- package/dist/features/selection/utils/resolveSelectionNextIds.js.map +1 -1
- package/dist/features/surface/surfaceMeta.d.ts +1 -1
- package/dist/features/tabs/tabPanelMeta.d.ts +1 -1
- package/dist/features/tree-view/adapters/inbound/TreeItem.d.ts +3 -2
- package/dist/features/tree-view/adapters/inbound/TreeItem.d.ts.map +1 -1
- package/dist/features/tree-view/adapters/inbound/TreeItem.js +11 -4
- package/dist/features/tree-view/adapters/inbound/TreeItem.js.map +1 -1
- package/dist/features/tree-view/adapters/inbound/TreeView.d.ts.map +1 -1
- package/dist/features/tree-view/adapters/inbound/TreeView.js +4 -5
- package/dist/features/tree-view/adapters/inbound/TreeView.js.map +1 -1
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.d.ts +3 -2
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.d.ts.map +1 -1
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.js +17 -9
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.js.map +1 -1
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeView.d.ts +4 -3
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeView.d.ts.map +1 -1
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeView.js +8 -8
- package/dist/features/tree-view/adapters/inbound/web-artifact/TreeView.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/types/auth.d.ts +19 -0
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/auth.js.map +1 -1
- package/dist/types/graph-view.d.ts +2 -0
- package/dist/types/graph-view.d.ts.map +1 -1
- package/dist/types/graph-view.js.map +1 -1
- package/dist/types/selection.d.ts +3 -0
- package/dist/types/selection.d.ts.map +1 -1
- package/dist/types/selection.js.map +1 -1
- package/dist/types/tree-view.d.ts +3 -2
- package/dist/types/tree-view.d.ts.map +1 -1
- package/dist/types/tree-view.js.map +1 -1
- package/package.json +2 -2
- package/src/constants/authoring.ts +2 -0
- package/src/features/auth/adapters/inbound/AuthScreen.tsx +202 -0
- package/src/features/auth/authScreenMeta.ts +114 -0
- package/src/features/auth/public.test.ts +6 -0
- package/src/features/auth/public.ts +3 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.tsx +10 -2
- package/src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx +3 -1
- package/src/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.ts +22 -5
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.test.ts +21 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.ts +10 -3
- package/src/features/registry/ZORA_COMPONENT_REGISTRY.ts +2 -0
- package/src/features/registry/componentMeta.test.ts +1 -0
- package/src/features/registry/componentMeta.ts +2 -0
- package/src/features/selection/adapters/inbound/SelectableItem.tsx +33 -50
- package/src/features/selection/adapters/inbound/SelectionProvider.tsx +34 -35
- package/src/features/selection/application/resolveSelectionEventIntent.test.ts +35 -0
- package/src/features/selection/application/resolveSelectionEventIntent.ts +55 -0
- package/src/features/selection/public.ts +2 -0
- package/src/features/selection/utils/resolveSelectionNextIds.test.ts +1 -14
- package/src/features/selection/utils/resolveSelectionNextIds.ts +6 -28
- package/src/features/tree-view/adapters/inbound/TreeItem.tsx +25 -9
- package/src/features/tree-view/adapters/inbound/TreeView.tsx +4 -6
- package/src/features/tree-view/adapters/inbound/web-artifact/TreeItemRow.tsx +26 -8
- package/src/features/tree-view/adapters/inbound/web-artifact/TreeView.test.tsx +77 -7
- package/src/features/tree-view/adapters/inbound/web-artifact/TreeView.tsx +11 -9
- package/src/index.ts +4 -0
- package/src/showcaseCoverage.test.ts +1 -0
- package/src/types/auth.ts +21 -0
- package/src/types/graph-view.ts +2 -0
- package/src/types/selection.ts +3 -0
- package/src/types/tree-view.ts +3 -2
- package/web-dist/chunks/{Accordion-j2aw3d5b.js → Accordion-01e56hb5.js} +1 -1
- package/web-dist/chunks/{Accordion-784f23tq.js → Accordion-14p7zanv.js} +1 -1
- package/web-dist/chunks/{Accordion-cecn51ry.js → Accordion-17pht8jd.js} +3 -3
- package/web-dist/chunks/{Accordion-555gnfmw.js → Accordion-2ak69ntj.js} +11 -11
- package/web-dist/chunks/{Accordion-ycmg06sq.js → Accordion-46vwm9xv.js} +3 -3
- package/web-dist/chunks/{Accordion-nn38n7q4.js → Accordion-4r9a9qny.js} +5 -5
- package/web-dist/chunks/Accordion-5df6cgyf.js +55 -0
- package/web-dist/chunks/{Accordion-v1dtv6v0.js → Accordion-5pskbqss.js} +7 -7
- package/web-dist/chunks/{Accordion-sr353w95.js → Accordion-78mj69zp.js} +2 -2
- package/web-dist/chunks/{Accordion-emczc5rg.js → Accordion-8xdet564.js} +16 -16
- package/web-dist/chunks/{Accordion-ajydqhjp.js → Accordion-8xk2zmr5.js} +2 -2
- package/web-dist/chunks/{Accordion-8af800ts.js → Accordion-9n7h9hag.js} +8 -8
- package/web-dist/chunks/{Accordion-73m7z73v.js → Accordion-b9myvfep.js} +5 -5
- package/web-dist/chunks/{Accordion-vmz8y01b.js → Accordion-bmp1ab7m.js} +496 -303
- package/web-dist/chunks/{Accordion-s1jhv8gk.js → Accordion-cqgbx1pw.js} +4 -4
- package/web-dist/chunks/{Accordion-2fm2tm5r.js → Accordion-cydzrpk2.js} +2 -2
- package/web-dist/chunks/{Accordion-07rdw2vh.js → Accordion-ejns5mga.js} +5 -5
- package/web-dist/chunks/{Accordion-yz7b7njb.js → Accordion-ejy7gr0a.js} +6 -6
- package/web-dist/chunks/{Accordion-mpnb4qqw.js → Accordion-f2mfgcx6.js} +15 -15
- package/web-dist/chunks/{Accordion-bsy1jrak.js → Accordion-ff583p4q.js} +2 -2
- package/web-dist/chunks/{Accordion-jj3bg8c1.js → Accordion-jksn8783.js} +6 -6
- package/web-dist/chunks/{Accordion-tj61sa5s.js → Accordion-jnwa02s7.js} +4 -4
- package/web-dist/chunks/{Accordion-rkv7jyaj.js → Accordion-kemavggr.js} +1 -1
- package/web-dist/chunks/{Accordion-mvfz28m8.js → Accordion-kmv2fp6m.js} +7 -7
- package/web-dist/chunks/{Accordion-jhwsvx3g.js → Accordion-kpnwdpb5.js} +1 -1
- package/web-dist/chunks/{Accordion-avmgvcef.js → Accordion-mm4kx13n.js} +10 -10
- package/web-dist/chunks/{Accordion-qvt6qdqm.js → Accordion-nggjwm07.js} +6 -6
- package/web-dist/chunks/{Accordion-yf6vseep.js → Accordion-q0st659f.js} +82 -89
- package/web-dist/chunks/{Accordion-zx0jc0kg.js → Accordion-qb8ppq9t.js} +5 -5
- package/web-dist/chunks/Accordion-r23sx4gf.js +34 -0
- package/web-dist/chunks/{Accordion-9rnepkvk.js → Accordion-rev0zb75.js} +6 -6
- package/web-dist/chunks/{Accordion-z585n0mr.js → Accordion-rjgdrn7y.js} +1 -1
- package/web-dist/chunks/{Accordion-pnvt10cv.js → Accordion-rnjt5z4y.js} +19 -19
- package/web-dist/chunks/{Accordion-45ej9brb.js → Accordion-tyqds4zr.js} +6 -6
- package/web-dist/chunks/{Accordion-8hhvtcxp.js → Accordion-v166qr59.js} +4 -4
- package/web-dist/chunks/{Accordion-1cgz6f8t.js → Accordion-x4rjd7yn.js} +1 -1
- package/web-dist/chunks/{Accordion-zf3kzvef.js → Accordion-xw1gkpfk.js} +6 -6
- package/web-dist/chunks/{Accordion-nc5gnvnb.js → Accordion-yms7x22j.js} +9 -9
- package/web-dist/chunks/{Accordion-b3qy1trj.js → Accordion-z1trs7s1.js} +26 -26
- package/web-dist/chunks/{Accordion-5qmfa7vr.js → Accordion-z8h1hn96.js} +5 -5
- 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 +9 -9
- package/web-dist/components/app-shell/AppShell.js +2 -2
- package/web-dist/components/auth-screen/AuthScreen.d.ts +9 -0
- package/web-dist/components/auth-screen/AuthScreen.js +43 -0
- package/web-dist/components/auth-screen/index.d.ts +1 -0
- package/web-dist/components/auth-screen/index.js +2 -0
- 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 +3 -3
- package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +12 -12
- 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 +11 -11
- package/web-dist/components/button/Button.js +5 -5
- package/web-dist/components/button-group/ButtonGroup.js +5 -5
- package/web-dist/components/camera-permission-view/CameraPermissionView.js +12 -12
- package/web-dist/components/card/Card.js +11 -11
- 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 +9 -9
- package/web-dist/components/checkbox/Checkbox.js +6 -6
- package/web-dist/components/checkbox-group/CheckboxGroup.js +6 -6
- 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 +13 -13
- package/web-dist/components/content-rail/ContentRail.js +8 -8
- package/web-dist/components/data-table/DataTable.js +22 -22
- package/web-dist/components/date-picker/DatePicker.js +15 -15
- package/web-dist/components/dialog/Dialog.js +5 -5
- package/web-dist/components/divider/Divider.js +2 -2
- package/web-dist/components/empty-state/EmptyState.js +12 -12
- package/web-dist/components/field/Field.js +7 -7
- package/web-dist/components/flat-list/FlatList.js +7 -7
- package/web-dist/components/forgot-password-form/ForgotPasswordForm.d.ts +1 -0
- package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +21 -16
- package/web-dist/components/form/Form.js +9 -9
- package/web-dist/components/form-actions/FormActions.js +9 -9
- package/web-dist/components/form-error/FormError.js +9 -9
- 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 +20 -11
- package/web-dist/components/graph-view/GraphView.types-0.d.ts +2 -0
- package/web-dist/components/grid/Grid.js +2 -2
- package/web-dist/components/heading/Heading.js +4 -4
- package/web-dist/components/hero/Hero.js +14 -14
- package/web-dist/components/icon/Icon.js +2 -2
- package/web-dist/components/icon-button/IconButton.js +5 -5
- package/web-dist/components/image/Image.js +4 -4
- package/web-dist/components/keyboard-avoiding-view/KeyboardAvoidingView.js +5 -32
- package/web-dist/components/list/List.js +7 -7
- package/web-dist/components/list-item/ListItem.js +7 -7
- package/web-dist/components/list-section/ListSection.js +7 -7
- package/web-dist/components/media-card/MediaCard.js +11 -11
- package/web-dist/components/message-bubble/MessageBubble.js +9 -9
- package/web-dist/components/metric-card/MetricCard.js +11 -11
- package/web-dist/components/missing-element/MissingElement.js +10 -10
- package/web-dist/components/o-auth-provider-button/OAuthProviderButton.d.ts +1 -0
- package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +21 -16
- package/web-dist/components/o-auth-provider-list/OAuthProviderList.d.ts +1 -0
- package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +21 -16
- package/web-dist/components/opening-book/OpeningBook.js +2 -2
- package/web-dist/components/otp-form/OtpForm.d.ts +1 -0
- package/web-dist/components/otp-form/OtpForm.js +21 -16
- package/web-dist/components/pagination/Pagination.js +8 -8
- package/web-dist/components/palette-item/PaletteItem.js +13 -13
- 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 +6 -6
- package/web-dist/components/post-card/PostCard.js +11 -11
- package/web-dist/components/product-card/ProductCard.js +11 -11
- 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 +7 -7
- package/web-dist/components/radio-group/RadioGroup.js +7 -7
- package/web-dist/components/rating/Rating.js +3 -3
- package/web-dist/components/reader-surface/ReaderSurface.js +15 -15
- package/web-dist/components/scan-overlay/ScanOverlay.js +12 -12
- 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 +6 -6
- package/web-dist/components/section-header/SectionHeader.js +4 -4
- package/web-dist/components/section-list/SectionList.js +7 -7
- package/web-dist/components/select/Select.js +7 -7
- package/web-dist/components/selectable-item/SelectableItem.js +1 -1
- package/web-dist/components/selection-provider/SelectionProvider.js +1 -1
- package/web-dist/components/sign-in-form/SignInForm.d.ts +1 -0
- package/web-dist/components/sign-in-form/SignInForm.js +21 -16
- package/web-dist/components/sign-up-form/SignUpForm.d.ts +1 -0
- package/web-dist/components/sign-up-form/SignUpForm.js +21 -16
- package/web-dist/components/skeleton/Skeleton.js +14 -14
- package/web-dist/components/skeleton-card/SkeletonCard.js +14 -14
- package/web-dist/components/skeleton-list/SkeletonList.js +14 -14
- package/web-dist/components/skeleton-text/SkeletonText.js +14 -14
- package/web-dist/components/surface/Surface.js +2 -2
- package/web-dist/components/switch/Switch.js +4 -4
- package/web-dist/components/tab/Tab.js +3 -3
- package/web-dist/components/tab-list/TabList.js +3 -3
- package/web-dist/components/tab-panel/TabPanel.js +3 -3
- package/web-dist/components/tabletop-table/TabletopTable.js +2 -2
- package/web-dist/components/tabs/Tabs.js +3 -3
- package/web-dist/components/text/Text.js +4 -4
- package/web-dist/components/text-input/TextInput.js +6 -6
- package/web-dist/components/time-picker/TimePicker.js +13 -13
- package/web-dist/components/timeline/Timeline.js +7 -7
- package/web-dist/components/toast/Toast.js +4 -4
- package/web-dist/components/toast-provider/ToastProvider.js +4 -4
- package/web-dist/components/toolbar/Toolbar.js +11 -11
- package/web-dist/components/tree-item/TreeItem.js +43 -24
- package/web-dist/components/tree-view/TreeView.d.ts +4 -3
- package/web-dist/components/tree-view/TreeView.js +25 -12
- package/web-dist/components/uploader/Uploader.js +19 -19
- package/web-dist/components/view/View.js +2 -2
- package/web-dist/manifest.json +753 -684
- package/web-dist/runtime/ZoraProvider.js +6 -6
- /package/web-dist/chunks/{Accordion-k3bc4kad.js → Accordion-13y3zx87.js} +0 -0
|
@@ -3,6 +3,7 @@ import { accordionItemMeta } from '../accordion/accordionItemMeta';
|
|
|
3
3
|
import { accordionMeta } from '../accordion/accordionMeta';
|
|
4
4
|
import { activityIndicatorMeta } from '../activity-indicator/activityIndicatorMeta';
|
|
5
5
|
import { appBarMeta } from '../app-bar/appBarMeta';
|
|
6
|
+
import { authScreenMeta } from '../auth/authScreenMeta';
|
|
6
7
|
import { forgotPasswordFormMeta } from '../auth/forgotPasswordFormMeta';
|
|
7
8
|
import { oauthProviderButtonMeta } from '../auth/oauthProviderButtonMeta';
|
|
8
9
|
import { oauthProviderListMeta } from '../auth/oauthProviderListMeta';
|
|
@@ -178,6 +179,7 @@ export const ZORA_COMPONENT_META: ZoraComponentMetaRegistry = finalizeFeatureMet
|
|
|
178
179
|
AppShell: appShellMeta,
|
|
179
180
|
Screen: screenMeta,
|
|
180
181
|
ScreenSection: screenSectionMeta,
|
|
182
|
+
AuthScreen: authScreenMeta,
|
|
181
183
|
ForgotPasswordForm: forgotPasswordFormMeta,
|
|
182
184
|
OAuthProviderButton: oauthProviderButtonMeta,
|
|
183
185
|
OAuthProviderList: oauthProviderListMeta,
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import { Pressable } from '@ankhorage/surface';
|
|
2
|
+
import type { SelectionIntent } from '@ankhorage/utility/selection';
|
|
2
3
|
import React from 'react';
|
|
3
|
-
import type
|
|
4
|
+
import { type GestureResponderEvent, Platform } from 'react-native';
|
|
4
5
|
|
|
5
6
|
import type {
|
|
6
7
|
SelectableItemProps,
|
|
7
8
|
SelectableItemState,
|
|
8
9
|
SelectionTrigger,
|
|
9
10
|
} from '../../../../types/selection';
|
|
11
|
+
import { resolveSelectionEventIntent } from '../../application/resolveSelectionEventIntent';
|
|
10
12
|
import { useSelection } from './SelectionProvider';
|
|
11
13
|
|
|
14
|
+
/*** Resolve the configured selection trigger. */
|
|
12
15
|
function resolveTrigger(trigger: SelectionTrigger | undefined): SelectionTrigger {
|
|
13
16
|
return trigger ?? 'manual';
|
|
14
17
|
}
|
|
15
18
|
|
|
19
|
+
/*** Narrow render-prop children without changing ordinary React-node children. */
|
|
16
20
|
function isRenderProp(
|
|
17
21
|
children: SelectableItemProps['children'],
|
|
18
22
|
): children is (state: SelectableItemState) => React.ReactNode {
|
|
19
23
|
return typeof children === 'function';
|
|
20
24
|
}
|
|
21
25
|
|
|
22
|
-
/***
|
|
23
|
-
* Adds selection behavior to arbitrary child content via render props.
|
|
24
|
-
*
|
|
25
|
-
|
|
26
|
-
*/
|
|
26
|
+
/*** Adds selection behavior to arbitrary child content via render props. */
|
|
27
27
|
export function SelectableItem({
|
|
28
28
|
id,
|
|
29
29
|
trigger,
|
|
@@ -36,67 +36,50 @@ export function SelectableItem({
|
|
|
36
36
|
const resolvedDisabled = selection.disabled || disabled;
|
|
37
37
|
const selected = selection.isSelected(id);
|
|
38
38
|
|
|
39
|
+
const activate = React.useCallback(
|
|
40
|
+
(intent: SelectionIntent) => {
|
|
41
|
+
if (resolvedDisabled || interactionPolicy === 'passive') return;
|
|
42
|
+
selection.activate(id, intent);
|
|
43
|
+
},
|
|
44
|
+
[id, interactionPolicy, resolvedDisabled, selection],
|
|
45
|
+
);
|
|
39
46
|
const select = React.useCallback(() => {
|
|
40
|
-
if (resolvedDisabled) return;
|
|
41
|
-
if (interactionPolicy === 'passive') return;
|
|
47
|
+
if (resolvedDisabled || interactionPolicy === 'passive') return;
|
|
42
48
|
selection.select(id);
|
|
43
|
-
}, [id,
|
|
44
|
-
|
|
49
|
+
}, [id, interactionPolicy, resolvedDisabled, selection]);
|
|
45
50
|
const toggle = React.useCallback(() => {
|
|
46
|
-
if (resolvedDisabled) return;
|
|
47
|
-
if (interactionPolicy === 'passive') return;
|
|
51
|
+
if (resolvedDisabled || interactionPolicy === 'passive') return;
|
|
48
52
|
selection.toggle(id);
|
|
49
|
-
}, [id,
|
|
50
|
-
|
|
53
|
+
}, [id, interactionPolicy, resolvedDisabled, selection]);
|
|
51
54
|
const clear = React.useCallback(() => {
|
|
52
|
-
if (selection.disabled) return;
|
|
53
|
-
if (interactionPolicy === 'passive') return;
|
|
55
|
+
if (selection.disabled || interactionPolicy === 'passive') return;
|
|
54
56
|
selection.clear();
|
|
55
57
|
}, [interactionPolicy, selection]);
|
|
56
58
|
|
|
57
|
-
const itemState = React.useMemo<SelectableItemState>(
|
|
58
|
-
|
|
59
|
+
const itemState = React.useMemo<SelectableItemState>(
|
|
60
|
+
() => ({
|
|
59
61
|
id,
|
|
60
62
|
selected,
|
|
61
63
|
disabled: resolvedDisabled,
|
|
62
64
|
mode: selection.mode,
|
|
65
|
+
activate,
|
|
63
66
|
select,
|
|
64
67
|
toggle,
|
|
65
68
|
clear,
|
|
66
|
-
}
|
|
67
|
-
|
|
69
|
+
}),
|
|
70
|
+
[activate, clear, id, resolvedDisabled, select, selected, selection.mode, toggle],
|
|
71
|
+
);
|
|
68
72
|
|
|
69
|
-
// IMPORTANT:
|
|
70
|
-
// Do not pass `children` directly into Pressable. Pressable also supports function children,
|
|
71
|
-
// but its function signature receives interaction state, not SelectableItemState.
|
|
72
73
|
const content = isRenderProp(children) ? children(itemState) : children;
|
|
74
|
+
if (resolvedTrigger === 'manual') return <>{content}</>;
|
|
73
75
|
|
|
74
|
-
|
|
75
|
-
return <>{content}</>;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const handlePress = (event: GestureResponderEvent) => {
|
|
76
|
+
const handleActivation = (event: GestureResponderEvent) => {
|
|
79
77
|
event.stopPropagation();
|
|
80
|
-
if (resolvedDisabled) return;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
selection.toggle(id);
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const handleLongPress = (event: GestureResponderEvent) => {
|
|
91
|
-
event.stopPropagation();
|
|
92
|
-
if (resolvedDisabled) return;
|
|
93
|
-
if (interactionPolicy === 'passive') return;
|
|
94
|
-
if (selection.mode === 'single') {
|
|
95
|
-
selection.select(id);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
selection.toggle(id);
|
|
78
|
+
if (resolvedDisabled || interactionPolicy === 'passive') return;
|
|
79
|
+
selection.activate(
|
|
80
|
+
id,
|
|
81
|
+
resolveSelectionEventIntent(event, Platform.OS === 'web' ? 'pointer' : 'touch'),
|
|
82
|
+
);
|
|
100
83
|
};
|
|
101
84
|
|
|
102
85
|
return (
|
|
@@ -105,8 +88,8 @@ export function SelectableItem({
|
|
|
105
88
|
accessibilityRole="button"
|
|
106
89
|
accessibilityState={{ disabled: resolvedDisabled, selected }}
|
|
107
90
|
disabled={resolvedDisabled}
|
|
108
|
-
onLongPress={resolvedTrigger === 'longPress' ?
|
|
109
|
-
onPress={resolvedTrigger === 'press' ?
|
|
91
|
+
onLongPress={resolvedTrigger === 'longPress' ? handleActivation : undefined}
|
|
92
|
+
onPress={resolvedTrigger === 'press' ? handleActivation : undefined}
|
|
110
93
|
>
|
|
111
94
|
{content}
|
|
112
95
|
</Pressable>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { applySelectionIntent, type SelectionIntent } from '@ankhorage/utility/selection';
|
|
1
2
|
import React from 'react';
|
|
2
3
|
|
|
3
4
|
import type {
|
|
@@ -5,13 +6,7 @@ import type {
|
|
|
5
6
|
SelectionProviderProps,
|
|
6
7
|
UseSelectionResult,
|
|
7
8
|
} from '../../../../types/selection';
|
|
8
|
-
import {
|
|
9
|
-
areIdsEqual,
|
|
10
|
-
clearIds,
|
|
11
|
-
normalizeIds,
|
|
12
|
-
selectId,
|
|
13
|
-
toggleId,
|
|
14
|
-
} from '../../utils/resolveSelectionNextIds';
|
|
9
|
+
import { areIdsEqual, clearIds, normalizeIds, selectId } from '../../utils/resolveSelectionNextIds';
|
|
15
10
|
|
|
16
11
|
const MISSING_CONTEXT_MESSAGE =
|
|
17
12
|
'ZORA selection context is missing. Wrap this tree in <SelectionProvider>.';
|
|
@@ -30,21 +25,14 @@ function resolveDisabled(disabled: boolean | undefined): boolean {
|
|
|
30
25
|
return disabled ?? false;
|
|
31
26
|
}
|
|
32
27
|
|
|
33
|
-
/***
|
|
34
|
-
* Accesses selection state provided by `SelectionProvider`.
|
|
35
|
-
*/
|
|
28
|
+
/*** Accesses selection state provided by `SelectionProvider`. */
|
|
36
29
|
export function useSelection(): UseSelectionResult {
|
|
37
30
|
const value = React.use(SelectionContext);
|
|
38
|
-
if (!value)
|
|
39
|
-
throw new Error(MISSING_CONTEXT_MESSAGE);
|
|
40
|
-
}
|
|
41
|
-
|
|
31
|
+
if (!value) throw new Error(MISSING_CONTEXT_MESSAGE);
|
|
42
32
|
return value;
|
|
43
33
|
}
|
|
44
34
|
|
|
45
|
-
/***
|
|
46
|
-
* Provides selection state for building selectable lists and grids.
|
|
47
|
-
*/
|
|
35
|
+
/*** Provides selection state for building selectable lists and grids. */
|
|
48
36
|
export function SelectionProvider({
|
|
49
37
|
children,
|
|
50
38
|
selectedIds,
|
|
@@ -57,27 +45,20 @@ export function SelectionProvider({
|
|
|
57
45
|
const resolvedMode = resolveMode(mode);
|
|
58
46
|
const resolvedDisabled = resolveDisabled(disabled);
|
|
59
47
|
const isControlled = selectedIds !== undefined;
|
|
60
|
-
|
|
61
48
|
const [uncontrolledIds, setUncontrolledIds] = React.useState<readonly string[]>(
|
|
62
49
|
defaultSelectedIds ?? [],
|
|
63
50
|
);
|
|
64
51
|
|
|
65
52
|
const rawIds = isControlled ? selectedIds : uncontrolledIds;
|
|
66
53
|
const currentNormalizedIds = normalizeIds(rawIds, resolvedMode);
|
|
67
|
-
|
|
68
54
|
const selectedIdSet = React.useMemo(() => new Set(currentNormalizedIds), [currentNormalizedIds]);
|
|
69
55
|
|
|
70
56
|
const commitSelectionChange = React.useCallback(
|
|
71
57
|
(nextNormalizedIds: readonly string[]) => {
|
|
72
|
-
if (resolvedDisabled) return;
|
|
73
|
-
if (interactionPolicy === 'passive') return;
|
|
58
|
+
if (resolvedDisabled || interactionPolicy === 'passive') return;
|
|
74
59
|
if (areIdsEqual(nextNormalizedIds, currentNormalizedIds)) return;
|
|
75
|
-
|
|
76
60
|
onSelectionChange?.(nextNormalizedIds);
|
|
77
|
-
|
|
78
|
-
if (!isControlled) {
|
|
79
|
-
setUncontrolledIds(nextNormalizedIds);
|
|
80
|
-
}
|
|
61
|
+
if (!isControlled) setUncontrolledIds(nextNormalizedIds);
|
|
81
62
|
},
|
|
82
63
|
[currentNormalizedIds, interactionPolicy, isControlled, onSelectionChange, resolvedDisabled],
|
|
83
64
|
);
|
|
@@ -89,34 +70,52 @@ export function SelectionProvider({
|
|
|
89
70
|
const select = React.useCallback(
|
|
90
71
|
(id: string) => {
|
|
91
72
|
const nextIds = selectId({ mode: resolvedMode, ids: currentNormalizedIds, id });
|
|
92
|
-
|
|
93
|
-
commitSelectionChange(nextNormalizedIds);
|
|
73
|
+
commitSelectionChange(normalizeIds(nextIds, resolvedMode));
|
|
94
74
|
},
|
|
95
75
|
[commitSelectionChange, currentNormalizedIds, resolvedMode],
|
|
96
76
|
);
|
|
97
77
|
|
|
98
78
|
const toggle = React.useCallback(
|
|
99
79
|
(id: string) => {
|
|
100
|
-
const nextIds =
|
|
101
|
-
|
|
102
|
-
commitSelectionChange(nextNormalizedIds);
|
|
80
|
+
const nextIds = applySelectionIntent(currentNormalizedIds, id, 'toggle');
|
|
81
|
+
commitSelectionChange(normalizeIds(nextIds, resolvedMode));
|
|
103
82
|
},
|
|
104
83
|
[commitSelectionChange, currentNormalizedIds, resolvedMode],
|
|
105
84
|
);
|
|
106
85
|
|
|
107
|
-
const
|
|
108
|
-
|
|
86
|
+
const activate = React.useCallback(
|
|
87
|
+
(id: string, intent: SelectionIntent) => {
|
|
88
|
+
const effectiveIntent = resolvedMode === 'single' ? 'replace' : intent;
|
|
89
|
+
const nextIds = applySelectionIntent(currentNormalizedIds, id, effectiveIntent);
|
|
90
|
+
commitSelectionChange(normalizeIds(nextIds, resolvedMode));
|
|
91
|
+
},
|
|
92
|
+
[commitSelectionChange, currentNormalizedIds, resolvedMode],
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const value = React.useMemo<UseSelectionResult>(
|
|
96
|
+
() => ({
|
|
109
97
|
mode: resolvedMode,
|
|
110
98
|
disabled: resolvedDisabled,
|
|
111
99
|
selectedIds: currentNormalizedIds,
|
|
112
100
|
selectedCount: currentNormalizedIds.length,
|
|
113
101
|
hasSelection: currentNormalizedIds.length > 0,
|
|
114
102
|
isSelected: (id: string) => selectedIdSet.has(id),
|
|
103
|
+
activate,
|
|
115
104
|
select,
|
|
116
105
|
toggle,
|
|
117
106
|
clear,
|
|
118
|
-
}
|
|
119
|
-
|
|
107
|
+
}),
|
|
108
|
+
[
|
|
109
|
+
activate,
|
|
110
|
+
clear,
|
|
111
|
+
currentNormalizedIds,
|
|
112
|
+
resolvedDisabled,
|
|
113
|
+
resolvedMode,
|
|
114
|
+
select,
|
|
115
|
+
selectedIdSet,
|
|
116
|
+
toggle,
|
|
117
|
+
],
|
|
118
|
+
);
|
|
120
119
|
|
|
121
120
|
return <SelectionContext value={value}>{children}</SelectionContext>;
|
|
122
121
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { resolveSelectionEventIntent } from './resolveSelectionEventIntent';
|
|
4
|
+
|
|
5
|
+
describe('resolveSelectionEventIntent', () => {
|
|
6
|
+
test('replaces for an unmodified desktop pointer event', () => {
|
|
7
|
+
expect(resolveSelectionEventIntent({}, 'pointer')).toBe('replace');
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test('toggles for Command and Control modifiers', () => {
|
|
11
|
+
expect(resolveSelectionEventIntent({ metaKey: true }, 'pointer')).toBe('toggle');
|
|
12
|
+
expect(resolveSelectionEventIntent({ nativeEvent: { ctrlKey: true } }, 'pointer')).toBe(
|
|
13
|
+
'toggle',
|
|
14
|
+
);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('toggles pointer events reported as touch', () => {
|
|
18
|
+
expect(
|
|
19
|
+
resolveSelectionEventIntent({ originalEvent: { pointerType: 'touch' } }, 'pointer'),
|
|
20
|
+
).toBe('toggle');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('toggles renderer touch events without pointerType', () => {
|
|
24
|
+
expect(
|
|
25
|
+
resolveSelectionEventIntent(
|
|
26
|
+
{ originalEvent: { type: 'touchend', changedTouches: [] } },
|
|
27
|
+
'pointer',
|
|
28
|
+
),
|
|
29
|
+
).toBe('toggle');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('toggles native touch fallback without modifier data', () => {
|
|
33
|
+
expect(resolveSelectionEventIntent({}, 'touch')).toBe('toggle');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type InteractionModifiers,
|
|
3
|
+
resolveSelectionIntent,
|
|
4
|
+
type SelectionActivationKind,
|
|
5
|
+
type SelectionInteractionInput,
|
|
6
|
+
} from '@ankhorage/utility/interaction';
|
|
7
|
+
import { isRecord } from '@ankhorage/utility/object';
|
|
8
|
+
import type { SelectionIntent } from '@ankhorage/utility/selection';
|
|
9
|
+
|
|
10
|
+
/*** Normalize DOM, React Native, and renderer events into one semantic selection intent. */
|
|
11
|
+
export function resolveSelectionEventIntent(
|
|
12
|
+
event: unknown,
|
|
13
|
+
fallbackKind: SelectionActivationKind,
|
|
14
|
+
): SelectionIntent {
|
|
15
|
+
const source = readEventSource(event);
|
|
16
|
+
const kind: SelectionActivationKind = isTouchActivation(source) ? 'touch' : fallbackKind;
|
|
17
|
+
const sourceModifiers = readInteractionModifiers(source);
|
|
18
|
+
const wrapperModifiers = readInteractionModifiers(event);
|
|
19
|
+
const input: SelectionInteractionInput = {
|
|
20
|
+
kind,
|
|
21
|
+
modifiers: {
|
|
22
|
+
altKey: sourceModifiers.altKey === true || wrapperModifiers.altKey === true,
|
|
23
|
+
ctrlKey: sourceModifiers.ctrlKey === true || wrapperModifiers.ctrlKey === true,
|
|
24
|
+
metaKey: sourceModifiers.metaKey === true || wrapperModifiers.metaKey === true,
|
|
25
|
+
shiftKey: sourceModifiers.shiftKey === true || wrapperModifiers.shiftKey === true,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
return resolveSelectionIntent(input);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/*** Prefer one nested native/renderer event while preserving structural event compatibility. */
|
|
32
|
+
function readEventSource(event: unknown): Readonly<Record<string, unknown>> {
|
|
33
|
+
if (!isRecord(event)) return {};
|
|
34
|
+
if (isRecord(event.originalEvent)) return event.originalEvent;
|
|
35
|
+
if (isRecord(event.nativeEvent)) return event.nativeEvent;
|
|
36
|
+
return event;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/*** Recognize pointer and native/browser touch event shapes without depending on platform event types. */
|
|
40
|
+
function isTouchActivation(source: Readonly<Record<string, unknown>>): boolean {
|
|
41
|
+
if (source.pointerType === 'touch') return true;
|
|
42
|
+
if (typeof source.type === 'string' && source.type.startsWith('touch')) return true;
|
|
43
|
+
return 'touches' in source || 'changedTouches' in source;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/*** Read known modifiers explicitly so arbitrary event properties never become dynamic input keys. */
|
|
47
|
+
function readInteractionModifiers(value: unknown): InteractionModifiers {
|
|
48
|
+
if (!isRecord(value)) return {};
|
|
49
|
+
return {
|
|
50
|
+
altKey: value.altKey === true,
|
|
51
|
+
ctrlKey: value.ctrlKey === true,
|
|
52
|
+
metaKey: value.metaKey === true,
|
|
53
|
+
shiftKey: value.shiftKey === true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -8,3 +8,5 @@ export type {
|
|
|
8
8
|
} from '../../types/selection';
|
|
9
9
|
export { SelectableItem } from './adapters/inbound/SelectableItem';
|
|
10
10
|
export { SelectionProvider, useSelection } from './adapters/inbound/SelectionProvider';
|
|
11
|
+
export { resolveSelectionEventIntent } from './application/resolveSelectionEventIntent';
|
|
12
|
+
export type { SelectionIntent } from '@ankhorage/utility/selection';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from 'bun:test';
|
|
2
2
|
|
|
3
3
|
import type { SelectionMode } from '../../../types/selection';
|
|
4
|
-
import { areIdsEqual, clearIds, normalizeIds, selectId
|
|
4
|
+
import { areIdsEqual, clearIds, normalizeIds, selectId } from './resolveSelectionNextIds';
|
|
5
5
|
|
|
6
6
|
describe('resolveSelectionNextIds', () => {
|
|
7
7
|
test('normalizeIds removes duplicates, preserves order', () => {
|
|
@@ -40,19 +40,6 @@ describe('resolveSelectionNextIds', () => {
|
|
|
40
40
|
expect(selectId({ mode: 'multi', ids, id: 'b' })).toBe(ids);
|
|
41
41
|
});
|
|
42
42
|
|
|
43
|
-
test('toggleId clears id when already selected (single mode)', () => {
|
|
44
|
-
expect(toggleId({ mode: 'single', ids: ['a'], id: 'a' })).toEqual([]);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test('toggleId selects id when not selected (single mode)', () => {
|
|
48
|
-
expect(toggleId({ mode: 'single', ids: [], id: 'a' })).toEqual(['a']);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
test('toggleId toggles membership (multi mode)', () => {
|
|
52
|
-
expect(toggleId({ mode: 'multi', ids: ['a'], id: 'b' })).toEqual(['a', 'b']);
|
|
53
|
-
expect(toggleId({ mode: 'multi', ids: ['a', 'b'], id: 'b' })).toEqual(['a']);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
43
|
test('mode-change normalization example', () => {
|
|
57
44
|
const internalIds = ['a', 'b'];
|
|
58
45
|
const mode: SelectionMode = 'single';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SelectionMode } from '../../../types/selection';
|
|
2
2
|
|
|
3
|
+
/*** Normalize selected ids to stable unique membership within the configured selection mode. */
|
|
3
4
|
export function normalizeIds(
|
|
4
5
|
ids: readonly string[] | undefined,
|
|
5
6
|
mode: SelectionMode,
|
|
@@ -17,6 +18,7 @@ export function normalizeIds(
|
|
|
17
18
|
return uniqueIds;
|
|
18
19
|
}
|
|
19
20
|
|
|
21
|
+
/*** Compare ordered selection ids without allocating replacement arrays. */
|
|
20
22
|
export function areIdsEqual(a: readonly string[], b: readonly string[]): boolean {
|
|
21
23
|
if (a.length !== b.length) return false;
|
|
22
24
|
for (let index = 0; index < a.length; index += 1) {
|
|
@@ -26,10 +28,12 @@ export function areIdsEqual(a: readonly string[], b: readonly string[]): boolean
|
|
|
26
28
|
return true;
|
|
27
29
|
}
|
|
28
30
|
|
|
31
|
+
/*** Produce the canonical empty selection. */
|
|
29
32
|
export function clearIds(): readonly string[] {
|
|
30
33
|
return [];
|
|
31
34
|
}
|
|
32
35
|
|
|
36
|
+
/*** Ensure one id is selected while preserving multi-selection membership. */
|
|
33
37
|
export function selectId({
|
|
34
38
|
mode,
|
|
35
39
|
ids,
|
|
@@ -39,33 +43,7 @@ export function selectId({
|
|
|
39
43
|
ids: readonly string[];
|
|
40
44
|
id: string;
|
|
41
45
|
}): readonly string[] {
|
|
42
|
-
if (mode === 'single')
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (ids.includes(id)) {
|
|
47
|
-
return ids;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return [...ids, id];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function toggleId({
|
|
54
|
-
mode,
|
|
55
|
-
ids,
|
|
56
|
-
id,
|
|
57
|
-
}: {
|
|
58
|
-
mode: SelectionMode;
|
|
59
|
-
ids: readonly string[];
|
|
60
|
-
id: string;
|
|
61
|
-
}): readonly string[] {
|
|
62
|
-
if (ids.includes(id)) {
|
|
63
|
-
return ids.filter((existingId) => existingId !== id);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (mode === 'single') {
|
|
67
|
-
return [id];
|
|
68
|
-
}
|
|
69
|
-
|
|
46
|
+
if (mode === 'single') return [id];
|
|
47
|
+
if (ids.includes(id)) return ids;
|
|
70
48
|
return [...ids, id];
|
|
71
49
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { Pressable } from '@ankhorage/surface';
|
|
2
|
+
import type { SelectionIntent } from '@ankhorage/utility/selection';
|
|
1
3
|
import React from 'react';
|
|
4
|
+
import { Platform } from 'react-native';
|
|
2
5
|
|
|
3
6
|
import type { ZoraBaseProps } from '../../../../types/base';
|
|
4
7
|
import type { TreeItemNode, TreeItemRenderProps } from '../../../../types/tree-view';
|
|
@@ -6,15 +9,16 @@ import { IconButton } from '../../../button/public';
|
|
|
6
9
|
import { Icon } from '../../../icon/public';
|
|
7
10
|
import { View } from '../../../layout/public';
|
|
8
11
|
import { ListItem } from '../../../list/public';
|
|
12
|
+
import { resolveSelectionEventIntent } from '../../../selection/public';
|
|
9
13
|
import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThemeScope';
|
|
10
14
|
|
|
11
15
|
interface TreeItemProps<TId extends string = string> extends ZoraBaseProps {
|
|
12
16
|
node: TreeItemNode<TId>;
|
|
13
17
|
depth: number;
|
|
14
18
|
expansionIndicator: 'chevron' | 'folder';
|
|
15
|
-
|
|
19
|
+
selectedIds: readonly TId[];
|
|
16
20
|
expandedIds: readonly TId[];
|
|
17
|
-
onSelect?: (id: TId) => void;
|
|
21
|
+
onSelect?: (id: TId, intent: SelectionIntent) => void;
|
|
18
22
|
onToggleExpand: (id: TId) => void;
|
|
19
23
|
renderItem?: (props: TreeItemRenderProps<TId>) => React.ReactNode;
|
|
20
24
|
}
|
|
@@ -26,7 +30,7 @@ function TreeItemInner<TId extends string = string>({
|
|
|
26
30
|
node,
|
|
27
31
|
depth,
|
|
28
32
|
expansionIndicator,
|
|
29
|
-
|
|
33
|
+
selectedIds,
|
|
30
34
|
expandedIds,
|
|
31
35
|
onSelect,
|
|
32
36
|
onToggleExpand,
|
|
@@ -36,7 +40,7 @@ function TreeItemInner<TId extends string = string>({
|
|
|
36
40
|
}: TreeItemProps<TId>) {
|
|
37
41
|
const hasChildren = node.children !== undefined && node.children.length > 0;
|
|
38
42
|
const isExpanded = expandedIds.includes(node.id);
|
|
39
|
-
const isSelected =
|
|
43
|
+
const isSelected = selectedIds.includes(node.id);
|
|
40
44
|
|
|
41
45
|
/*** Compose custom content or the selectable row independently of the expansion control. */
|
|
42
46
|
const renderContent = () => {
|
|
@@ -62,10 +66,22 @@ function TreeItemInner<TId extends string = string>({
|
|
|
62
66
|
trailing: node.actions,
|
|
63
67
|
};
|
|
64
68
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
if (onSelect === undefined) return <ListItem {...listItemProps} />;
|
|
70
|
+
return (
|
|
71
|
+
<Pressable
|
|
72
|
+
accessibilityRole="button"
|
|
73
|
+
accessibilityState={{ disabled: node.disabled, selected: isSelected }}
|
|
74
|
+
disabled={node.disabled}
|
|
75
|
+
interactionPolicy={interactionPolicy}
|
|
76
|
+
onPress={(event) =>
|
|
77
|
+
onSelect(
|
|
78
|
+
node.id,
|
|
79
|
+
resolveSelectionEventIntent(event, Platform.OS === 'web' ? 'pointer' : 'touch'),
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
>
|
|
83
|
+
<ListItem {...listItemProps} />
|
|
84
|
+
</Pressable>
|
|
69
85
|
);
|
|
70
86
|
};
|
|
71
87
|
|
|
@@ -111,7 +127,7 @@ function TreeItemInner<TId extends string = string>({
|
|
|
111
127
|
onSelect={onSelect}
|
|
112
128
|
onToggleExpand={onToggleExpand}
|
|
113
129
|
renderItem={renderItem}
|
|
114
|
-
|
|
130
|
+
selectedIds={selectedIds}
|
|
115
131
|
/>
|
|
116
132
|
))}
|
|
117
133
|
</View>
|
|
@@ -6,12 +6,12 @@ import { withZoraThemeScope } from '../../../theme/adapters/inbound/withZoraThem
|
|
|
6
6
|
import { toggleExpandedIds } from '../../utils/toggleExpandedIds';
|
|
7
7
|
import { TreeItem } from './TreeItem';
|
|
8
8
|
|
|
9
|
-
/*** Render the themed TreeView while supporting controlled
|
|
9
|
+
/*** Render the themed TreeView while supporting controlled selection and expansion state. */
|
|
10
10
|
function TreeViewInner<TId extends string = string>({
|
|
11
11
|
themeId: _themeId,
|
|
12
12
|
mode: _mode,
|
|
13
13
|
nodes,
|
|
14
|
-
|
|
14
|
+
selectedIds = [],
|
|
15
15
|
expandedIds: controlledExpandedIds,
|
|
16
16
|
defaultExpandedIds,
|
|
17
17
|
onSelect,
|
|
@@ -32,9 +32,7 @@ function TreeViewInner<TId extends string = string>({
|
|
|
32
32
|
if (interactionPolicy === 'passive') return;
|
|
33
33
|
const nextExpandedIds = toggleExpandedIds(expandedIds, id);
|
|
34
34
|
|
|
35
|
-
if (!isControlled)
|
|
36
|
-
setInternalExpandedIds(nextExpandedIds);
|
|
37
|
-
}
|
|
35
|
+
if (!isControlled) setInternalExpandedIds(nextExpandedIds);
|
|
38
36
|
onExpandedChange?.(nextExpandedIds);
|
|
39
37
|
};
|
|
40
38
|
|
|
@@ -50,7 +48,7 @@ function TreeViewInner<TId extends string = string>({
|
|
|
50
48
|
onSelect={onSelect}
|
|
51
49
|
onToggleExpand={handleToggleExpand}
|
|
52
50
|
renderItem={renderItem}
|
|
53
|
-
|
|
51
|
+
selectedIds={selectedIds}
|
|
54
52
|
interactionPolicy={interactionPolicy}
|
|
55
53
|
/>
|
|
56
54
|
))}
|