@octane-xplat/ui 0.6.0 → 0.7.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/README.md +14 -4
- package/dist/native/{Absolute.native.tsrx.js → Absolute.tsrx.js} +2 -2
- package/dist/native/{Accordion.native.tsrx.js → Accordion.tsrx.js} +3 -3
- package/dist/native/{ActivityIndicator.native.tsrx.js → ActivityIndicator.tsrx.js} +2 -2
- package/dist/native/{Alert.native.tsrx.js → Alert.tsrx.js} +3 -3
- package/dist/native/{Avatar.native.tsrx.js → Avatar.tsrx.js} +3 -3
- package/dist/native/{AvatarGroup.native.tsrx.js → AvatarGroup.tsrx.js} +3 -3
- package/dist/native/{Badge.native.tsrx.js → Badge.tsrx.js} +2 -2
- package/dist/native/{Banner.native.tsrx.js → Banner.tsrx.js} +3 -3
- package/dist/native/{Breadcrumb.native.tsrx.js → Breadcrumb.tsrx.js} +2 -2
- package/dist/native/{Button.native.tsrx.js → Button.tsrx.js} +3 -3
- package/dist/native/{Card.native.tsrx.js → Card.tsrx.js} +2 -2
- package/dist/native/{Checkbox.native.tsrx.js → Checkbox.tsrx.js} +2 -2
- package/dist/native/{CheckboxGroup.native.tsrx.js → CheckboxGroup.tsrx.js} +3 -3
- package/dist/native/{Chip.native.tsrx.js → Chip.tsrx.js} +2 -2
- package/dist/native/{Collapsible.native.tsrx.js → Collapsible.tsrx.js} +3 -3
- package/dist/native/{CommandPalette.native.tsrx.js → CommandPalette.tsrx.js} +4 -4
- package/dist/native/{ContextMenu.native.tsrx.js → ContextMenu.tsrx.js} +4 -4
- package/dist/native/{Drawer.native.tsrx.js → Drawer.tsrx.js} +2 -2
- package/dist/native/{DropdownMenu.native.tsrx.js → DropdownMenu.tsrx.js} +5 -5
- package/dist/native/{Empty.native.tsrx.js → Empty.tsrx.js} +3 -3
- package/dist/native/{FieldGroup.native.tsrx.js → FieldGroup.tsrx.js} +2 -2
- package/dist/native/{FormField.native.tsrx.js → FormField.tsrx.js} +2 -2
- package/dist/native/{Grid.native.tsrx.js → Grid.tsrx.js} +2 -2
- package/dist/native/{Heading.native.tsrx.js → Heading.tsrx.js} +3 -3
- package/dist/native/Hoverable.tsrx.js +139 -0
- package/dist/native/{Icon.native.tsrx.js → Icon.tsrx.js} +3 -3
- package/dist/native/{Image.native.tsrx.js → Image.tsrx.js} +4 -4
- package/dist/native/{InputNumber.native.tsrx.js → InputNumber.tsrx.js} +4 -4
- package/dist/native/{InputRating.native.tsrx.js → InputRating.tsrx.js} +3 -3
- package/dist/native/{InputTags.native.tsrx.js → InputTags.tsrx.js} +4 -4
- package/dist/native/{Kbd.native.tsrx.js → Kbd.tsrx.js} +2 -2
- package/dist/native/{KeyboardAvoiding.native.tsrx.js → KeyboardAvoiding.mobile.tsrx.js} +5 -3
- package/dist/native/{Link.native.tsrx.js → Link.tsrx.js} +2 -2
- package/dist/native/ListItem.tsrx.js +178 -0
- package/dist/native/Meter.tsrx.js +70 -0
- package/dist/native/{NavLink.native.tsrx.js → NavLink.tsrx.js} +3 -3
- package/dist/native/{NavigationMenu.native.tsrx.js → NavigationMenu.tsrx.js} +3 -3
- package/dist/native/{Overlay.native.tsrx.js → Overlay.tsrx.js} +2 -2
- package/dist/native/{Pagination.native.tsrx.js → Pagination.tsrx.js} +2 -2
- package/dist/native/{PinInput.native.tsrx.js → PinInput.tsrx.js} +3 -3
- package/dist/native/{Popover.native.tsrx.js → Popover.tsrx.js} +4 -4
- package/dist/native/{Pressable.native.tsrx.js → Pressable.tsrx.js} +4 -4
- package/dist/native/{ProgressGroup.native.tsrx.js → ProgressGroup.tsrx.js} +3 -3
- package/dist/native/{RadioGroup.native.tsrx.js → RadioGroup.tsrx.js} +2 -2
- package/dist/native/{RichText.native.tsrx.js → RichText.tsrx.js} +3 -3
- package/dist/native/{RouteHost.native.tsrx.js → RouteHost.mobile.tsrx.js} +13 -2
- package/dist/native/{Row.native.tsrx.js → Row.tsrx.js} +4 -4
- package/dist/native/{SafeArea.native.tsrx.js → SafeArea.tsrx.js} +9 -3
- package/dist/native/{Screen.native.tsrx.js → Screen.tsrx.js} +13 -5
- package/dist/native/{ScrollBox.native.tsrx.js → ScrollBox.tsrx.js} +2 -2
- package/dist/native/{ScrollView.native.tsrx.js → ScrollView.tsrx.js} +5 -5
- package/dist/native/{SearchInput.native.tsrx.js → SearchInput.tsrx.js} +4 -4
- package/dist/native/{SegmentedControl.native.tsrx.js → SegmentedControl.tsrx.js} +2 -2
- package/dist/native/{Select.native.tsrx.js → Select.tsrx.js} +4 -4
- package/dist/native/{Separator.native.tsrx.js → Separator.tsrx.js} +2 -2
- package/dist/native/{Sheet.native.tsrx.js → Sheet.tsrx.js} +11 -3
- package/dist/native/{Skeleton.native.tsrx.js → Skeleton.tsrx.js} +2 -2
- package/dist/native/{Slider.native.tsrx.js → Slider.tsrx.js} +5 -5
- package/dist/native/{Spacer.native.tsrx.js → Spacer.tsrx.js} +2 -2
- package/dist/native/{Stack.native.tsrx.js → Stack.tsrx.js} +2 -2
- package/dist/native/{Stepper.native.tsrx.js → Stepper.tsrx.js} +2 -2
- package/dist/native/{Switch.native.tsrx.js → Switch.tsrx.js} +2 -2
- package/dist/native/{Table.native.tsrx.js → Table.tsrx.js} +2 -2
- package/dist/native/{Tabs.native.tsrx.js → Tabs.tsrx.js} +8 -18
- package/dist/native/{Text.native.tsrx.js → Text.tsrx.js} +3 -3
- package/dist/native/{TextArea.native.tsrx.js → TextArea.tsrx.js} +3 -3
- package/dist/native/{TextInput.native.tsrx.js → TextInput.tsrx.js} +3 -3
- package/dist/native/{Timeline.native.tsrx.js → Timeline.tsrx.js} +3 -3
- package/dist/native/Tooltip.tsrx.js +131 -0
- package/dist/native/{Tree.native.tsrx.js → Tree.tsrx.js} +2 -2
- package/dist/native/{User.native.tsrx.js → User.tsrx.js} +3 -3
- package/dist/native/{View.native.tsrx.js → View.tsrx.js} +4 -4
- package/dist/native/VirtualList.tsrx.js +466 -0
- package/dist/native/{WebView.native.tsrx.js → WebView.tsrx.js} +31 -6
- package/dist/native/{aliases.native.tsrx.js → aliases.tsrx.js} +2 -2
- package/dist/native/android/BottomNavigationView.android.tsrx.js +72 -23
- package/dist/native/android/CircularProgressIndicator.android.tsrx.js +1 -1
- package/dist/native/android/DrawerLayout.android.tsrx.js +2 -1
- package/dist/native/android/MaterialDialog.android.tsrx.js +1 -1
- package/dist/native/android/MaterialSwitch.android.tsrx.js +1 -1
- package/dist/native/android/RecyclerView.android.tsrx.js +15 -3
- package/dist/native/android/SeekBar.android.tsrx.js +1 -1
- package/dist/native/android/icon.android.js +7 -0
- package/dist/native/android/index.js +3 -1
- package/dist/native/android/openModal.android.js +1 -1
- package/dist/native/{anim.native.tsrx.js → anim.tsrx.js} +1 -1
- package/dist/native/apply-native-modifiers.native.js +9 -0
- package/dist/native/{escape-props.native.js → escape-props.js} +3 -1
- package/dist/native/index.shared.js +92 -0
- package/dist/native/ios/LiquidGlass.ios.tsrx.js +2 -2
- package/dist/native/ios/LiquidGlassContainer.ios.tsrx.js +2 -2
- package/dist/native/ios/SideDrawer.ios.tsrx.js +2 -1
- package/dist/native/ios/UIActivityIndicatorView.ios.tsrx.js +1 -1
- package/dist/native/ios/UIModal.ios.tsrx.js +1 -1
- package/dist/native/ios/UISlider.ios.tsrx.js +1 -1
- package/dist/native/ios/UISwitch.ios.tsrx.js +1 -1
- package/dist/native/ios/UITabBar.ios.tsrx.js +33 -12
- package/dist/native/ios/UITableView.ios.tsrx.js +15 -3
- package/dist/native/ios/icon.ios.js +7 -0
- package/dist/native/ios/index.js +3 -1
- package/dist/native/ios/openModal.ios.js +1 -1
- package/dist/native/keyboard-inset.mobile.js +66 -0
- package/dist/native/{layout-child.native.js → layout-child.js} +1 -1
- package/dist/native/{modal-presenter.native.js → modal-presenter.mobile.js} +1 -1
- package/dist/native/modifier-factories.js +24 -0
- package/dist/native/native/index.js +3 -3
- package/dist/native/octane-client-build.json +1 -1
- package/dist/native/{pan.native.tsrx.js → pan.tsrx.js} +1 -1
- package/dist/native/{platform.native.js → platform.js} +3 -3
- package/dist/native/{platformProps.native.js → platformProps.js} +3 -1
- package/dist/native/{refresh.native.js → refresh.js} +1 -1
- package/dist/native/{root-layout.native.js → root-layout.mobile.js} +2 -2
- package/dist/native/route-host.mobile.js +2 -0
- package/dist/native/route-table.js +105 -4
- package/dist/native/{route.native.js → route.js} +49 -13
- package/dist/native/safeAreaInsets.tsrx.js +67 -0
- package/dist/native/shared.js +93 -0
- package/dist/native/{sheet-detents.native.js → sheet-detents.js} +1 -1
- package/dist/native/{sheet-service.native.js → sheet-service.js} +9 -3
- package/dist/native/{stacks.native.js → stacks.js} +1 -1
- package/dist/native/{styled.native.tsrx.js → styled.tsrx.js} +1 -1
- package/dist/native/{svg.native.js → svg.mobile.js} +2 -2
- package/dist/native/tap-to-blur.mobile.js +94 -0
- package/dist/native/{text-write.native.js → text-write.js} +1 -1
- package/dist/native/theme/{colorScheme.native.js → colorScheme.js} +2 -2
- package/dist/native/theme/{status-bar-scheme.native.js → status-bar-scheme.mobile.js} +1 -1
- package/dist/native/theme/theme-scheme.js +2 -2
- package/dist/native/{toast-anchor.native.tsrx.js → toast-anchor.tsrx.js} +3 -3
- package/dist/native/{translate.native.js → translate.js} +1 -1
- package/dist/native/ui.js +92 -90
- package/dist/native/{use-back.native.tsrx.js → use-back.tsrx.js} +2 -2
- package/dist/native/{use-store.native.tsrx.js → use-store.tsrx.js} +1 -1
- package/dist/native/{useMeasure.native.tsrx.js → useMeasure.tsrx.js} +1 -1
- package/dist/native/vendor/ui-svg/index.android.js +137 -0
- package/dist/native/vendor/ui-svg/index.common.js +10 -0
- package/dist/native/vendor/ui-svg/index.ios.js +111 -0
- package/dist/native/virtual-list-layout.js +146 -0
- package/dist/native/{windows.native.js → windows.js} +1 -1
- package/dist/web/{web/Hoverable.web.tsrx.js → Hoverable.web.tsrx.js} +7 -6
- package/dist/web/ListItem.web.tsrx.js +139 -0
- package/dist/web/SafeArea.web.tsrx.js +9 -3
- package/dist/web/Tabs.web.tsrx.js +88 -44
- package/dist/web/{web/Tooltip.web.tsrx.js → Tooltip.web.tsrx.js} +7 -6
- package/dist/web/VirtualList.web.tsrx.js +622 -0
- package/dist/web/WebView.web.tsrx.js +42 -5
- package/dist/web/index.shared.web.js +92 -0
- package/dist/web/octane-client-build.json +1 -1
- package/dist/web/platform.web.js +1 -1
- package/dist/web/route-table.js +105 -4
- package/dist/web/route.web.js +36 -11
- package/dist/web/ui.js +10 -8
- package/dist/web/virtual-list-layout.js +146 -0
- package/dist/web/web/index.js +2 -2
- package/package.json +35 -23
- package/platforms/android/include.gradle +8 -0
- package/platforms/android/native-api-usage.json +8 -0
- package/platforms/ios/Podfile +2 -0
- package/src/Absolute.tsrx +22 -0
- package/src/Absolute.web.tsrx +22 -0
- package/src/Accordion.macos.tsrx +50 -0
- package/src/Accordion.tsrx +50 -0
- package/src/Accordion.web.tsrx +43 -0
- package/src/ActivityIndicator.tsrx +29 -0
- package/src/ActivityIndicator.web.tsrx +14 -0
- package/src/Alert.macos.tsrx +42 -0
- package/src/Alert.tsrx +24 -0
- package/src/Alert.web.tsrx +23 -0
- package/src/Avatar.macos.tsrx +25 -0
- package/src/Avatar.tsrx +25 -0
- package/src/Avatar.web.tsrx +24 -0
- package/src/AvatarGroup.macos.tsrx +32 -0
- package/src/AvatarGroup.tsrx +32 -0
- package/src/AvatarGroup.web.tsrx +29 -0
- package/src/Badge.macos.tsrx +12 -0
- package/src/Badge.tsrx +12 -0
- package/src/Badge.web.tsrx +10 -0
- package/src/Banner.macos.tsrx +20 -0
- package/src/Banner.tsrx +20 -0
- package/src/Banner.web.tsrx +20 -0
- package/src/Breadcrumb.macos.tsrx +27 -0
- package/src/Breadcrumb.tsrx +27 -0
- package/src/Breadcrumb.web.tsrx +25 -0
- package/src/Button.tsrx +23 -0
- package/src/Button.web.tsrx +21 -0
- package/src/CameraView.macos.tsrx +6 -0
- package/src/Card.macos.tsrx +13 -0
- package/src/Card.tsrx +13 -0
- package/src/Card.web.tsrx +11 -0
- package/src/Checkbox.tsrx +23 -0
- package/src/Checkbox.web.tsrx +34 -0
- package/src/CheckboxGroup.macos.tsrx +39 -0
- package/src/CheckboxGroup.tsrx +39 -0
- package/src/CheckboxGroup.web.tsrx +38 -0
- package/src/Chip.macos.tsrx +25 -0
- package/src/Chip.tsrx +25 -0
- package/src/Chip.web.tsrx +25 -0
- package/src/Collapsible.macos.tsrx +39 -0
- package/src/Collapsible.tsrx +39 -0
- package/src/Collapsible.web.tsrx +33 -0
- package/src/CommandPalette.macos.tsrx +58 -0
- package/src/CommandPalette.tsrx +58 -0
- package/src/CommandPalette.web.tsrx +59 -0
- package/src/ContextMenu.macos.tsrx +59 -0
- package/src/ContextMenu.tsrx +59 -0
- package/src/ContextMenu.web.tsrx +69 -0
- package/src/Drawer.macos.tsrx +28 -0
- package/src/Drawer.tsrx +25 -0
- package/src/Drawer.web.tsrx +31 -0
- package/src/DropdownMenu.macos.tsrx +63 -0
- package/src/DropdownMenu.tsrx +63 -0
- package/src/DropdownMenu.web.tsrx +78 -0
- package/src/Empty.macos.tsrx +15 -0
- package/src/Empty.tsrx +15 -0
- package/src/Empty.web.tsrx +13 -0
- package/src/FieldGroup.macos.tsrx +17 -0
- package/src/FieldGroup.tsrx +17 -0
- package/src/FieldGroup.web.tsrx +17 -0
- package/src/FormField.macos.tsrx +25 -0
- package/src/FormField.tsrx +25 -0
- package/src/FormField.web.tsrx +24 -0
- package/src/Grid.tsrx +32 -0
- package/src/Grid.web.tsrx +43 -0
- package/src/Heading.macos.tsrx +8 -0
- package/src/Heading.tsrx +17 -0
- package/src/Heading.web.tsrx +15 -0
- package/src/Hoverable.mobile.tsrx +21 -0
- package/src/Hoverable.tsrx +113 -0
- package/src/Hoverable.web.tsrx +98 -0
- package/src/Icon.macos.tsrx +18 -0
- package/src/Icon.tsrx +65 -0
- package/src/Icon.web.tsrx +75 -0
- package/src/Image.macos.tsrx +12 -0
- package/src/Image.tsrx +51 -0
- package/src/Image.web.tsrx +14 -0
- package/src/InputNumber.macos.tsrx +49 -0
- package/src/InputNumber.tsrx +49 -0
- package/src/InputNumber.web.tsrx +47 -0
- package/src/InputRating.macos.tsrx +42 -0
- package/src/InputRating.tsrx +39 -0
- package/src/InputRating.web.tsrx +52 -0
- package/src/InputTags.macos.tsrx +49 -0
- package/src/InputTags.tsrx +49 -0
- package/src/InputTags.web.tsrx +49 -0
- package/src/Kbd.macos.tsrx +11 -0
- package/src/Kbd.tsrx +11 -0
- package/src/Kbd.web.tsrx +9 -0
- package/src/KeyboardAvoiding.macos.tsrx +8 -0
- package/src/KeyboardAvoiding.mobile.tsrx +63 -0
- package/src/Link.macos.tsrx +15 -0
- package/src/Link.tsrx +10 -0
- package/src/Link.web.tsrx +12 -0
- package/src/ListItem.macos.tsrx +52 -0
- package/src/ListItem.tsrx +52 -0
- package/src/ListItem.web.tsrx +50 -0
- package/src/Meter.macos.tsrx +8 -0
- package/src/Meter.tsrx +45 -0
- package/src/Meter.web.tsrx +32 -0
- package/src/NavLink.macos.tsrx +24 -0
- package/src/NavLink.tsrx +22 -0
- package/src/NavLink.web.tsrx +23 -0
- package/src/NavigationMenu.macos.tsrx +31 -0
- package/src/NavigationMenu.tsrx +28 -0
- package/src/NavigationMenu.web.tsrx +31 -0
- package/src/Overlay.macos.tsrx +11 -0
- package/src/Overlay.tsrx +84 -0
- package/src/Overlay.web.tsrx +23 -0
- package/src/Pagination.macos.tsrx +54 -0
- package/src/Pagination.tsrx +47 -0
- package/src/Pagination.web.tsrx +50 -0
- package/src/PinInput.macos.tsrx +46 -0
- package/src/PinInput.tsrx +46 -0
- package/src/PinInput.web.tsrx +45 -0
- package/src/Popover.macos.tsrx +11 -0
- package/src/Popover.tsrx +157 -0
- package/src/Popover.web.tsrx +109 -0
- package/src/Pressable.macos.tsrx +19 -0
- package/src/Pressable.tsrx +37 -0
- package/src/Pressable.web.tsrx +45 -0
- package/src/ProgressGroup.macos.tsrx +17 -0
- package/src/ProgressGroup.tsrx +17 -0
- package/src/ProgressGroup.web.tsrx +15 -0
- package/src/RadioGroup.macos.tsrx +50 -0
- package/src/RadioGroup.tsrx +34 -0
- package/src/RadioGroup.web.tsrx +43 -0
- package/src/RichText.tsrx +40 -0
- package/src/RichText.web.tsrx +24 -0
- package/src/RouteHost.macos.tsrx +18 -0
- package/src/RouteHost.mobile.tsrx +44 -0
- package/src/Row.macos.tsrx +26 -0
- package/src/Row.tsrx +27 -0
- package/src/Row.web.tsrx +27 -0
- package/src/SafeArea.macos.tsrx +8 -0
- package/src/SafeArea.tsrx +20 -0
- package/src/SafeArea.web.tsrx +24 -0
- package/src/Screen.macos.tsrx +14 -0
- package/src/Screen.tsrx +31 -0
- package/src/Screen.web.tsrx +7 -0
- package/src/ScrollBox.tsrx +8 -0
- package/src/ScrollBox.web.tsrx +7 -0
- package/src/ScrollView.macos.tsrx +19 -0
- package/src/ScrollView.tsrx +117 -0
- package/src/ScrollView.web.tsrx +109 -0
- package/src/SearchInput.tsrx +60 -0
- package/src/SearchInput.web.test.tsrx +58 -0
- package/src/SearchInput.web.tsrx +55 -0
- package/src/SegmentedControl.tsrx +43 -0
- package/src/SegmentedControl.web.test.tsrx +46 -0
- package/src/SegmentedControl.web.tsrx +51 -0
- package/src/Select.macos.tsrx +104 -0
- package/src/Select.tsrx +104 -0
- package/src/Select.web.tsrx +124 -0
- package/src/Separator.macos.tsrx +17 -0
- package/src/Separator.tsrx +17 -0
- package/src/Separator.web.tsrx +17 -0
- package/src/Sheet.macos.tsrx +15 -0
- package/src/Sheet.tsrx +122 -0
- package/src/Sheet.web.tsrx +56 -0
- package/src/Skeleton.macos.tsrx +15 -0
- package/src/Skeleton.tsrx +15 -0
- package/src/Skeleton.web.tsrx +15 -0
- package/src/Slider.tsrx +71 -0
- package/src/Slider.web.tsrx +60 -0
- package/src/Spacer.tsrx +8 -0
- package/src/Spacer.web.tsrx +6 -0
- package/src/Stack.tsrx +24 -0
- package/src/Stack.web.tsrx +22 -0
- package/src/Stepper.macos.tsrx +52 -0
- package/src/Stepper.tsrx +31 -0
- package/src/Stepper.web.tsrx +37 -0
- package/src/Switch.tsrx +21 -0
- package/src/Switch.web.tsrx +28 -0
- package/src/Table.macos.tsrx +37 -0
- package/src/Table.tsrx +37 -0
- package/src/Table.web.tsrx +37 -0
- package/src/Tabs.macos.tsrx +60 -0
- package/src/Tabs.tsrx +55 -0
- package/src/Tabs.web.tsrx +98 -0
- package/src/Text.macos.tsrx +18 -0
- package/src/Text.tsrx +62 -0
- package/src/Text.web.tsrx +31 -0
- package/src/TextArea.tsrx +65 -0
- package/src/TextArea.web.tsrx +61 -0
- package/src/TextInput.tsrx +39 -0
- package/src/TextInput.web.tsrx +28 -0
- package/src/Timeline.macos.tsrx +27 -0
- package/src/Timeline.tsrx +24 -0
- package/src/Timeline.web.tsrx +22 -0
- package/src/Tooltip.mobile.tsrx +20 -0
- package/src/Tooltip.tsrx +102 -0
- package/src/Tooltip.web.tsrx +156 -0
- package/src/Tree.macos.tsrx +45 -0
- package/src/Tree.tsrx +45 -0
- package/src/Tree.web.tsrx +52 -0
- package/src/User.macos.tsrx +24 -0
- package/src/User.tsrx +24 -0
- package/src/User.web.tsrx +24 -0
- package/src/View.macos.tsrx +29 -0
- package/src/View.tsrx +32 -0
- package/src/View.web.tsrx +33 -0
- package/src/VirtualList.macos.tsrx +298 -0
- package/src/VirtualList.tsrx +358 -0
- package/src/VirtualList.web.tsrx +313 -0
- package/src/WebView.macos.tsrx +6 -0
- package/src/WebView.tsrx +89 -0
- package/src/WebView.web.tsrx +92 -0
- package/src/aliases.macos.tsrx +18 -0
- package/src/aliases.tsrx +18 -0
- package/src/aliases.web.tsrx +17 -0
- package/src/android/BottomNavigationView.android.tsrx +170 -0
- package/src/android/CircularProgressIndicator.android.tsrx +19 -0
- package/src/android/DrawerLayout.android.tsrx +48 -0
- package/src/android/MaterialDialog.android.tsrx +62 -0
- package/src/android/MaterialSwitch.android.tsrx +18 -0
- package/src/android/RecyclerView.android.tsrx +173 -0
- package/src/android/SeekBar.android.tsrx +20 -0
- package/src/android/icon.android.ts +8 -0
- package/src/android/index.ts +37 -0
- package/src/android/openModal.android.ts +55 -0
- package/src/anim.macos.tsrx +20 -0
- package/src/anim.tsrx +65 -0
- package/src/anim.web.tsrx +55 -0
- package/src/apply-native-modifiers.native.ts +13 -0
- package/src/camera-permission.web.ts +11 -0
- package/src/child-array.ts +16 -0
- package/src/colorScheme.macos.ts +27 -0
- package/src/controls.macos.tsrx +171 -0
- package/src/cx.ts +8 -0
- package/src/escape-props.macos.ts +11 -0
- package/src/escape-props.ts +70 -0
- package/src/escape-props.web.ts +25 -0
- package/src/hosted-unsupported.macos.tsrx +9 -0
- package/src/icons.ts +60 -0
- package/src/index.linux.ts +10 -0
- package/src/index.macos.ts +106 -0
- package/src/index.mobile.ts +6 -0
- package/src/index.shared.ts +269 -0
- package/src/index.shared.web.ts +270 -0
- package/src/index.ts +1 -0
- package/src/index.web.ts +1 -0
- package/src/ios/LiquidGlass.ios.tsrx +41 -0
- package/src/ios/LiquidGlassContainer.ios.tsrx +34 -0
- package/src/ios/SideDrawer.ios.tsrx +49 -0
- package/src/ios/UIActivityIndicatorView.ios.tsrx +18 -0
- package/src/ios/UIModal.ios.tsrx +68 -0
- package/src/ios/UISlider.ios.tsrx +20 -0
- package/src/ios/UISwitch.ios.tsrx +18 -0
- package/src/ios/UITabBar.ios.tsrx +172 -0
- package/src/ios/UITableView.ios.tsrx +186 -0
- package/src/ios/icon.ios.ts +8 -0
- package/src/ios/index.ts +42 -0
- package/src/ios/openModal.ios.ts +55 -0
- package/src/keyboard-inset.mobile.ts +89 -0
- package/src/layout-child.ts +57 -0
- package/src/layout-child.web.ts +108 -0
- package/src/layout-shells.macos.tsrx +10 -0
- package/src/layout.macos.tsrx +41 -0
- package/src/macos-extras.macos.tsrx +40 -0
- package/src/meter-math.ts +6 -0
- package/src/modal-presenter.mobile.ts +24 -0
- package/src/modifier-factories.ts +20 -0
- package/src/native/index.ts +6 -0
- package/src/pan.tsrx +64 -0
- package/src/pan.web.tsrx +38 -0
- package/src/platform.macos.ts +1 -0
- package/src/platform.ts +7 -0
- package/src/platform.web.ts +6 -0
- package/src/platformProps.ts +23 -0
- package/src/platformProps.web.ts +14 -0
- package/src/popover-position.ts +62 -0
- package/src/popover.mobile.test.ts +54 -0
- package/src/props.ts +1812 -0
- package/src/references.d.ts +2 -0
- package/src/refresh-metrics.ts +11 -0
- package/src/refresh.ts +271 -0
- package/src/refresh.web.test.ts +111 -0
- package/src/refresh.web.ts +205 -0
- package/src/root-layout.mobile.ts +89 -0
- package/src/route-host.mobile.ts +1 -0
- package/src/route-table.test.ts +345 -0
- package/src/route-table.ts +585 -0
- package/src/route.macos.ts +201 -0
- package/src/route.ts +703 -0
- package/src/route.web.ts +366 -0
- package/src/safeAreaInsets.macos.tsrx +7 -0
- package/src/safeAreaInsets.tsrx +60 -0
- package/src/safeAreaInsets.web.tsrx +38 -0
- package/src/sheet-detents.ts +142 -0
- package/src/sheet-detents.web.ts +147 -0
- package/src/sheet-service.macos.ts +60 -0
- package/src/sheet-service.ts +124 -0
- package/src/sheet-service.web.ts +64 -0
- package/src/sheet-snap.test.ts +46 -0
- package/src/sheet-snap.ts +66 -0
- package/src/stacks.macos.ts +13 -0
- package/src/stacks.ts +44 -0
- package/src/stacks.web.ts +9 -0
- package/src/store.mobile.test.ts +149 -0
- package/src/store.ts +39 -0
- package/src/store.web.test.tsrx +58 -0
- package/src/styled.macos.tsrx +23 -0
- package/src/styled.test.ts +40 -0
- package/src/styled.tsrx +36 -0
- package/src/styled.web.tsrx +23 -0
- package/src/surfaces.macos.tsrx +27 -0
- package/src/svg.mobile.ts +76 -0
- package/src/tap-to-blur.mobile.ts +108 -0
- package/src/text-controls.macos.tsrx +11 -0
- package/src/text-write.ts +28 -0
- package/src/text-write.web.ts +13 -0
- package/src/theme/colorScheme.linux.ts +52 -0
- package/src/theme/colorScheme.ts +26 -0
- package/src/theme/colorScheme.web.ts +20 -0
- package/src/theme/status-bar-scheme.mobile.ts +39 -0
- package/src/theme/theme-scheme.macos.ts +50 -0
- package/src/theme/theme-scheme.ts +66 -0
- package/src/theme/tokens.css +44 -22
- package/src/toast-anchor.macos.tsrx +3 -0
- package/src/toast-anchor.tsrx +122 -0
- package/src/toast-anchor.web.tsrx +92 -0
- package/src/toast.tsrx +90 -0
- package/src/toast.web.tsrx +50 -0
- package/src/transform.web.ts +52 -0
- package/src/translate.macos.ts +5 -0
- package/src/translate.ts +13 -0
- package/src/translate.web.ts +15 -0
- package/src/tsconfig.json +8 -0
- package/src/unsupported.macos.tsrx +5 -0
- package/src/use-back.tsrx +11 -0
- package/src/use-back.web.tsrx +12 -0
- package/src/use-store.tsrx +18 -0
- package/src/use-store.web.tsrx +18 -0
- package/src/useMeasure.macos.tsrx +23 -0
- package/src/useMeasure.tsrx +66 -0
- package/src/useMeasure.web.tsrx +39 -0
- package/src/useStore.macos.tsrx +6 -0
- package/src/vendor/ui-svg/LICENSE +201 -0
- package/src/vendor/ui-svg/index.android.ts +189 -0
- package/src/vendor/ui-svg/index.common.ts +19 -0
- package/src/vendor/ui-svg/index.ios.ts +147 -0
- package/src/vendor/ui-svg/index.ts +1 -0
- package/src/vendor/ui-svg/typings/SVGKit.d.ts +2862 -0
- package/src/vendor/ui-svg/typings/android.d.ts +1483 -0
- package/src/vendor/ui-svg/typings/ios.d.ts +1511 -0
- package/src/virtual-list-layout.test.ts +81 -0
- package/src/virtual-list-layout.ts +246 -0
- package/src/web/index.ts +11 -0
- package/src/windows.linux.ts +59 -0
- package/src/windows.macos.ts +10 -0
- package/src/windows.ts +7 -0
- package/src/windows.web.ts +6 -0
- package/types/generated/.tsrx-typegen-manifest.json +250 -0
- package/types/generated/Absolute.d.ts +3 -0
- package/types/generated/Absolute.web.d.ts +3 -0
- package/types/generated/Accordion.d.ts +5 -0
- package/types/generated/Accordion.web.d.ts +5 -0
- package/types/generated/ActivityIndicator.d.ts +7 -0
- package/types/generated/ActivityIndicator.web.d.ts +3 -0
- package/types/generated/Alert.d.ts +4 -0
- package/types/generated/Alert.web.d.ts +5 -0
- package/types/generated/Avatar.d.ts +6 -0
- package/types/generated/Avatar.web.d.ts +7 -0
- package/types/generated/AvatarGroup.d.ts +6 -0
- package/types/generated/AvatarGroup.web.d.ts +6 -0
- package/types/generated/Badge.d.ts +5 -0
- package/types/generated/Badge.web.d.ts +5 -0
- package/types/generated/Banner.d.ts +4 -0
- package/types/generated/Banner.web.d.ts +4 -0
- package/types/generated/Breadcrumb.d.ts +4 -0
- package/types/generated/Breadcrumb.web.d.ts +5 -0
- package/types/generated/Button.d.ts +6 -0
- package/types/generated/Button.web.d.ts +6 -0
- package/types/generated/Card.d.ts +4 -0
- package/types/generated/Card.web.d.ts +4 -0
- package/types/generated/Checkbox.d.ts +5 -0
- package/types/generated/Checkbox.web.d.ts +6 -0
- package/types/generated/CheckboxGroup.d.ts +3 -0
- package/types/generated/CheckboxGroup.web.d.ts +3 -0
- package/types/generated/Chip.d.ts +5 -0
- package/types/generated/Chip.web.d.ts +5 -0
- package/types/generated/Collapsible.d.ts +5 -0
- package/types/generated/Collapsible.web.d.ts +5 -0
- package/types/generated/CommandPalette.d.ts +4 -0
- package/types/generated/CommandPalette.web.d.ts +4 -0
- package/types/generated/ContextMenu.d.ts +5 -0
- package/types/generated/ContextMenu.web.d.ts +4 -0
- package/types/generated/Drawer.d.ts +7 -0
- package/types/generated/Drawer.web.d.ts +7 -0
- package/types/generated/DropdownMenu.d.ts +5 -0
- package/types/generated/DropdownMenu.web.d.ts +5 -0
- package/types/generated/Empty.d.ts +4 -0
- package/types/generated/Empty.web.d.ts +4 -0
- package/types/generated/FieldGroup.d.ts +4 -0
- package/types/generated/FieldGroup.web.d.ts +4 -0
- package/types/generated/FormField.d.ts +5 -0
- package/types/generated/FormField.web.d.ts +5 -0
- package/types/generated/Grid.d.ts +3 -0
- package/types/generated/Grid.web.d.ts +3 -0
- package/types/generated/Heading.d.ts +2 -0
- package/types/generated/Heading.web.d.ts +2 -0
- package/types/generated/Hoverable.d.ts +10 -0
- package/types/generated/Hoverable.web.d.ts +9 -0
- package/types/generated/Icon.d.ts +3 -0
- package/types/generated/Icon.web.d.ts +3 -0
- package/types/generated/Image.d.ts +7 -0
- package/types/generated/Image.web.d.ts +3 -0
- package/types/generated/InputNumber.d.ts +5 -0
- package/types/generated/InputNumber.web.d.ts +5 -0
- package/types/generated/InputRating.d.ts +4 -0
- package/types/generated/InputRating.web.d.ts +4 -0
- package/types/generated/InputTags.d.ts +4 -0
- package/types/generated/InputTags.web.d.ts +5 -0
- package/types/generated/Kbd.d.ts +4 -0
- package/types/generated/Kbd.web.d.ts +4 -0
- package/types/generated/KeyboardAvoiding.mobile.d.ts +2 -0
- package/types/generated/Link.d.ts +2 -0
- package/types/generated/Link.web.d.ts +3 -0
- package/types/generated/ListItem.d.ts +3 -0
- package/types/generated/ListItem.web.d.ts +3 -0
- package/types/generated/Meter.d.ts +3 -0
- package/types/generated/Meter.web.d.ts +3 -0
- package/types/generated/NavLink.d.ts +3 -0
- package/types/generated/NavLink.web.d.ts +3 -0
- package/types/generated/NavigationMenu.d.ts +4 -0
- package/types/generated/NavigationMenu.web.d.ts +5 -0
- package/types/generated/Overlay.d.ts +3 -0
- package/types/generated/Overlay.web.d.ts +3 -0
- package/types/generated/Pagination.d.ts +4 -0
- package/types/generated/Pagination.web.d.ts +5 -0
- package/types/generated/PinInput.d.ts +4 -0
- package/types/generated/PinInput.web.d.ts +4 -0
- package/types/generated/Popover.d.ts +6 -0
- package/types/generated/Popover.web.d.ts +3 -0
- package/types/generated/Pressable.d.ts +6 -0
- package/types/generated/Pressable.web.d.ts +2 -0
- package/types/generated/ProgressGroup.d.ts +3 -0
- package/types/generated/ProgressGroup.web.d.ts +4 -0
- package/types/generated/RadioGroup.d.ts +5 -0
- package/types/generated/RadioGroup.web.d.ts +5 -0
- package/types/generated/RichText.d.ts +7 -0
- package/types/generated/RichText.web.d.ts +3 -0
- package/types/generated/RouteHost.mobile.d.ts +14 -0
- package/types/generated/Row.d.ts +2 -0
- package/types/generated/Row.web.d.ts +2 -0
- package/types/generated/SafeArea.d.ts +2 -0
- package/types/generated/SafeArea.web.d.ts +3 -0
- package/types/generated/Screen.d.ts +3 -0
- package/types/generated/Screen.web.d.ts +3 -0
- package/types/generated/ScrollBox.d.ts +3 -0
- package/types/generated/ScrollBox.web.d.ts +3 -0
- package/types/generated/ScrollView.d.ts +7 -0
- package/types/generated/ScrollView.web.d.ts +6 -0
- package/types/generated/SearchInput.d.ts +7 -0
- package/types/generated/SearchInput.web.d.ts +6 -0
- package/types/generated/SegmentedControl.d.ts +7 -0
- package/types/generated/SegmentedControl.web.d.ts +6 -0
- package/types/generated/Select.d.ts +6 -0
- package/types/generated/Select.web.d.ts +6 -0
- package/types/generated/Separator.d.ts +5 -0
- package/types/generated/Separator.web.d.ts +5 -0
- package/types/generated/Sheet.d.ts +5 -0
- package/types/generated/Sheet.web.d.ts +7 -0
- package/types/generated/Skeleton.d.ts +5 -0
- package/types/generated/Skeleton.web.d.ts +6 -0
- package/types/generated/Slider.d.ts +6 -0
- package/types/generated/Slider.web.d.ts +6 -0
- package/types/generated/Spacer.d.ts +3 -0
- package/types/generated/Spacer.web.d.ts +3 -0
- package/types/generated/Stack.d.ts +3 -0
- package/types/generated/Stack.web.d.ts +3 -0
- package/types/generated/Stepper.d.ts +4 -0
- package/types/generated/Stepper.web.d.ts +5 -0
- package/types/generated/Switch.d.ts +7 -0
- package/types/generated/Switch.web.d.ts +6 -0
- package/types/generated/Table.d.ts +4 -0
- package/types/generated/Table.web.d.ts +5 -0
- package/types/generated/Tabs.d.ts +10 -0
- package/types/generated/Tabs.web.d.ts +6 -0
- package/types/generated/Text.d.ts +2 -0
- package/types/generated/Text.web.d.ts +2 -0
- package/types/generated/TextArea.d.ts +8 -0
- package/types/generated/TextArea.web.d.ts +9 -0
- package/types/generated/TextInput.d.ts +9 -0
- package/types/generated/TextInput.web.d.ts +2 -0
- package/types/generated/Timeline.d.ts +3 -0
- package/types/generated/Timeline.web.d.ts +4 -0
- package/types/generated/Tooltip.d.ts +9 -0
- package/types/generated/Tooltip.web.d.ts +12 -0
- package/types/generated/Tree.d.ts +4 -0
- package/types/generated/Tree.web.d.ts +4 -0
- package/types/generated/User.d.ts +5 -0
- package/types/generated/User.web.d.ts +5 -0
- package/types/generated/View.d.ts +7 -0
- package/types/generated/View.web.d.ts +7 -0
- package/types/generated/VirtualList.d.ts +5 -0
- package/types/generated/VirtualList.web.d.ts +4 -0
- package/types/generated/WebView.d.ts +11 -0
- package/types/generated/WebView.web.d.ts +5 -0
- package/types/generated/aliases.d.ts +7 -0
- package/types/generated/aliases.web.d.ts +7 -0
- package/types/generated/android/BottomNavigationView.android.d.ts +9 -0
- package/types/generated/android/CircularProgressIndicator.android.d.ts +6 -0
- package/types/generated/android/DrawerLayout.android.d.ts +12 -0
- package/types/generated/android/MaterialDialog.android.d.ts +8 -0
- package/types/generated/android/MaterialSwitch.android.d.ts +6 -0
- package/types/generated/android/RecyclerView.android.d.ts +14 -0
- package/types/generated/android/SeekBar.android.d.ts +5 -0
- package/types/generated/android/icon.android.d.ts +5 -0
- package/types/generated/android/index.d.ts +12 -0
- package/types/generated/android/openModal.android.d.ts +4 -0
- package/types/generated/anim.d.ts +10 -0
- package/types/generated/anim.web.d.ts +3 -0
- package/types/generated/apply-native-modifiers.native.d.ts +3 -0
- package/types/generated/child-array.d.ts +3 -0
- package/types/generated/cx.d.ts +6 -0
- package/types/generated/escape-props.d.ts +16 -0
- package/types/generated/icons.d.ts +5 -0
- package/types/generated/index.d.ts +1 -0
- package/types/generated/index.linux.d.ts +5 -0
- package/types/generated/index.mobile.d.ts +4 -0
- package/types/generated/index.shared.d.ts +111 -0
- package/types/generated/index.shared.web.d.ts +111 -0
- package/types/generated/index.web.d.ts +1 -0
- package/types/generated/ios/LiquidGlass.ios.d.ts +12 -0
- package/types/generated/ios/LiquidGlassContainer.ios.d.ts +13 -0
- package/types/generated/ios/SideDrawer.ios.d.ts +12 -0
- package/types/generated/ios/UIActivityIndicatorView.ios.d.ts +5 -0
- package/types/generated/ios/UIModal.ios.d.ts +7 -0
- package/types/generated/ios/UISlider.ios.d.ts +5 -0
- package/types/generated/ios/UISwitch.ios.d.ts +6 -0
- package/types/generated/ios/UITabBar.ios.d.ts +7 -0
- package/types/generated/ios/UITableView.ios.d.ts +14 -0
- package/types/generated/ios/icon.ios.d.ts +5 -0
- package/types/generated/ios/index.d.ts +14 -0
- package/types/generated/ios/openModal.ios.d.ts +4 -0
- package/types/generated/keyboard-inset.mobile.d.ts +10 -0
- package/types/generated/layout-child.d.ts +6 -0
- package/types/generated/layout-child.web.d.ts +15 -0
- package/types/generated/meter-math.d.ts +6 -0
- package/types/generated/modal-presenter.mobile.d.ts +14 -0
- package/types/generated/modifier-factories.d.ts +15 -0
- package/types/generated/native/index.d.ts +3 -0
- package/types/generated/pan.d.ts +2 -0
- package/types/generated/pan.web.d.ts +9 -0
- package/types/generated/platform.d.ts +7 -0
- package/types/generated/platform.web.d.ts +6 -0
- package/types/generated/platformProps.d.ts +7 -0
- package/types/generated/platformProps.web.d.ts +2 -0
- package/types/generated/popover-position.d.ts +14 -0
- package/types/{props.d.ts → generated/props.d.ts} +127 -133
- package/types/generated/refresh-metrics.d.ts +8 -0
- package/types/generated/refresh.d.ts +42 -0
- package/types/generated/refresh.web.d.ts +23 -0
- package/types/generated/root-layout.mobile.d.ts +22 -0
- package/types/generated/route-host.mobile.d.ts +1 -0
- package/types/generated/route-table.d.ts +90 -0
- package/types/generated/route.d.ts +74 -0
- package/types/generated/route.web.d.ts +67 -0
- package/types/generated/safeAreaInsets.d.ts +8 -0
- package/types/generated/safeAreaInsets.web.d.ts +8 -0
- package/types/generated/sheet-detents.d.ts +23 -0
- package/types/generated/sheet-detents.web.d.ts +13 -0
- package/types/generated/sheet-service.d.ts +11 -0
- package/types/generated/sheet-service.web.d.ts +6 -0
- package/types/generated/sheet-snap.d.ts +18 -0
- package/types/generated/stacks.d.ts +9 -0
- package/types/generated/stacks.web.d.ts +4 -0
- package/types/generated/store.d.ts +14 -0
- package/types/generated/styled.d.ts +20 -0
- package/types/generated/styled.web.d.ts +10 -0
- package/types/generated/svg.mobile.d.ts +23 -0
- package/types/generated/tap-to-blur.mobile.d.ts +16 -0
- package/types/generated/text-write.d.ts +9 -0
- package/types/generated/theme/colorScheme.d.ts +6 -0
- package/types/generated/theme/colorScheme.linux.d.ts +5 -0
- package/types/generated/theme/colorScheme.web.d.ts +5 -0
- package/types/generated/theme/status-bar-scheme.mobile.d.ts +1 -0
- package/types/generated/theme/theme-scheme.d.ts +20 -0
- package/types/generated/toast-anchor.d.ts +4 -0
- package/types/generated/toast-anchor.web.d.ts +4 -0
- package/types/generated/transform.web.d.ts +8 -0
- package/types/generated/translate.d.ts +5 -0
- package/types/generated/translate.web.d.ts +6 -0
- package/types/generated/use-back.d.ts +6 -0
- package/types/generated/use-back.web.d.ts +7 -0
- package/types/generated/use-store.d.ts +9 -0
- package/types/generated/use-store.web.d.ts +9 -0
- package/types/generated/useMeasure.d.ts +3 -0
- package/types/generated/useMeasure.web.d.ts +3 -0
- package/types/generated/vendor/ui-svg/index.common.d.ts +7 -0
- package/types/generated/vendor/ui-svg/index.d.ts +1 -0
- package/types/generated/vendor/ui-svg/index.ios.d.ts +13 -0
- package/types/generated/virtual-list-layout.d.ts +44 -0
- package/types/generated/web/index.d.ts +3 -0
- package/types/generated/windows.d.ts +3 -0
- package/types/generated/windows.linux.d.ts +15 -0
- package/types/generated/windows.web.d.ts +3 -0
- package/types/index.macos.d.ts +142 -0
- package/dist/native/CameraView.native.tsrx.js +0 -165
- package/dist/native/Meter.native.tsrx.js +0 -92
- package/dist/native/Pager.native.tsrx.js +0 -282
- package/dist/native/Video.native.tsrx.js +0 -248
- package/dist/native/camera-permission.native.js +0 -47
- package/dist/native/safeAreaInsets.native.tsrx.js +0 -35
- package/dist/native/video-chrome.native.tsrx.js +0 -365
- package/dist/web/CameraView.web.tsrx.js +0 -310
- package/dist/web/Pager.web.tsrx.js +0 -337
- package/dist/web/Video.web.tsrx.js +0 -400
- package/dist/web/video-chrome.web.tsrx.js +0 -207
- package/types/android.d.ts +0 -53
- package/types/index.d.ts +0 -273
- package/types/index.native.d.ts +0 -273
- package/types/index.web.d.ts +0 -272
- package/types/ios.d.ts +0 -59
- package/types/native.d.ts +0 -5
- package/types/web.d.ts +0 -17
package/src/route.ts
ADDED
|
@@ -0,0 +1,703 @@
|
|
|
1
|
+
/** Native twin of route.web — same Route contract over Frame/Page stacks.
|
|
2
|
+
* `pushRoute` resolves a stack ('root' = the app's root Frame — an
|
|
3
|
+
* explicit registerStack('root') or, by default, the Frame returned by
|
|
4
|
+
* Application.getRootView(); named stacks come from TabSpec.stack panes
|
|
5
|
+
* or registerStack) and pushes a Page hosting the registered screen —
|
|
6
|
+
* each pushed Page is its own Octane root (decision #9: pages never
|
|
7
|
+
* share context with their presenter). Params land as props; named-stack
|
|
8
|
+
* pushes get `_stack` injected so the screen can popRoute its own stack.
|
|
9
|
+
*
|
|
10
|
+
* Registration contract (the footgun this module exists to defuse):
|
|
11
|
+
* - `registerScreens(table)` once — pushRoute resolves `name` through it.
|
|
12
|
+
* - 'root' needs nothing when the app boots a Frame as its root view
|
|
13
|
+
* (the standard shape); non-Frame roots can't host pushes at all.
|
|
14
|
+
* - named stacks register via `TabSpec.stack` or `registerStack`.
|
|
15
|
+
* Every drop path warns loudly — silent no-ops are how apps ship a
|
|
16
|
+
* default route on native while working fine on web. */
|
|
17
|
+
|
|
18
|
+
import { Application, Frame, GridLayout, Page } from '@nativescript/core'
|
|
19
|
+
import { createNativeScriptRoot } from '@nativescript-community/octane'
|
|
20
|
+
import type { UniversalComponent } from 'octane/universal/native'
|
|
21
|
+
|
|
22
|
+
import { useSyncExternalStore } from 'octane'
|
|
23
|
+
import { getStack, onStackRegistered, stackEntries } from './stacks'
|
|
24
|
+
import {
|
|
25
|
+
buildRoutePath,
|
|
26
|
+
layoutChain,
|
|
27
|
+
linkPath,
|
|
28
|
+
matchUrl,
|
|
29
|
+
mergeRouteManifests,
|
|
30
|
+
RouteRedirect,
|
|
31
|
+
} from './route-table'
|
|
32
|
+
|
|
33
|
+
import { RouteHost } from './route-host.mobile'
|
|
34
|
+
import { modalPresenter } from './modal-presenter.mobile'
|
|
35
|
+
import type { Route, RouteManifest, RouteMeta, ScreenTable } from './props'
|
|
36
|
+
|
|
37
|
+
export type { Route } from './props'
|
|
38
|
+
|
|
39
|
+
// ---------- screen registry ----------
|
|
40
|
+
|
|
41
|
+
// Effective tables = the file-derived base manifest merged under every
|
|
42
|
+
// addRoutes layer. Keeping the split means an HMR re-run of routes.gen.*
|
|
43
|
+
// (registerRoutes again) can't wipe routes an app added at runtime.
|
|
44
|
+
let baseManifest: RouteManifest = { screens: {}, routes: [], layouts: {} }
|
|
45
|
+
const dynamicManifests: RouteManifest[] = []
|
|
46
|
+
let screens: ScreenTable = {}
|
|
47
|
+
let routes: RouteMeta[] = []
|
|
48
|
+
let routeLayouts: Record<string, any> = {}
|
|
49
|
+
let routeLoaders: NonNullable<RouteManifest['loaders']> = {}
|
|
50
|
+
|
|
51
|
+
function rebuildRegistry(): void {
|
|
52
|
+
const merged = mergeRouteManifests(baseManifest, ...dynamicManifests)
|
|
53
|
+
screens = merged.screens
|
|
54
|
+
routes = merged.routes
|
|
55
|
+
routeLayouts = merged.layouts
|
|
56
|
+
routeLoaders = merged.loaders ?? {}
|
|
57
|
+
emit()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** Register the app's name → screen table (call once, from the shared
|
|
61
|
+
* routes module). Native `pushRoute` resolves `route.name` through it;
|
|
62
|
+
* on web the table feeds `screenFor` for outlets without a
|
|
63
|
+
* `resolveScreen` prop. `manifest` (from deriveRouteManifest) is stored
|
|
64
|
+
* for parity — the web leaf matches URLs through it; native navigation
|
|
65
|
+
* is name+params and only needs the table. */
|
|
66
|
+
export function registerScreens(table: ScreenTable, manifest?: RouteMeta[]): void {
|
|
67
|
+
baseManifest = { ...baseManifest, screens: table, routes: manifest ?? [] }
|
|
68
|
+
rebuildRegistry()
|
|
69
|
+
ensureBackWired()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** One-call registration for route-dir apps — screens + URL patterns +
|
|
73
|
+
* layouts all come from deriveRouteManifest. */
|
|
74
|
+
export function registerRoutes(manifest: RouteManifest): void {
|
|
75
|
+
baseManifest = manifest
|
|
76
|
+
rebuildRegistry()
|
|
77
|
+
ensureBackWired()
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Layer a programmatic manifest (from `defineRoutes`) over the registered
|
|
81
|
+
* routes — same-name entries win over the base with a warn, so a host
|
|
82
|
+
* framework can override a file route deliberately. Registered layers
|
|
83
|
+
* survive later registerRoutes re-registration (e.g. routes.gen HMR). */
|
|
84
|
+
export function addRoutes(manifest: RouteManifest): void {
|
|
85
|
+
dynamicManifests.push(manifest)
|
|
86
|
+
rebuildRegistry()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function layoutsForRoute(name: string): any[] {
|
|
90
|
+
return layoutChain(routeLayouts, name)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function screenFor(name: string): ScreenTable[string] | undefined {
|
|
94
|
+
return screens[name]
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Wrap a screen in its directory `_layout` chain (outermost →
|
|
98
|
+
* innermost) as a single root component — pushed Pages and modal roots
|
|
99
|
+
* render this, matching web's outlet wrapping. */
|
|
100
|
+
// ---------- stack resolution ----------
|
|
101
|
+
|
|
102
|
+
const tracked = new WeakSet<Frame>()
|
|
103
|
+
const listeners = new Set<() => void>()
|
|
104
|
+
const pageRoutes = new WeakMap<Page, Route>()
|
|
105
|
+
const warned = new Set<string>()
|
|
106
|
+
|
|
107
|
+
function emit() {
|
|
108
|
+
listeners.forEach((l) => l())
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function warnOnce(key: string, msg: string): void {
|
|
112
|
+
if (warned.has(key)) {
|
|
113
|
+
return
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
warned.add(key)
|
|
117
|
+
console.warn('[octane-xplat] ' + msg)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Attach the route-store emission hook once per frame. `navigatedTo`
|
|
121
|
+
* fires on push AND on pop (the revealed page re-fires it), so one
|
|
122
|
+
* listener keeps every useRoute snapshot honest. */
|
|
123
|
+
function trackFrame(frame: Frame): void {
|
|
124
|
+
if (tracked.has(frame)) {
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
tracked.add(frame)
|
|
129
|
+
frame.on('navigatedTo', () => {
|
|
130
|
+
// A page re-shown by pop can stay unloaded when the frame's nav
|
|
131
|
+
// bookkeeping stalls mid-transition (the iOS strand of #11444 — the
|
|
132
|
+
// same hole the isLoaded/callLoaded workaround in commitRoute covers
|
|
133
|
+
// for the frame itself). Views render but their gesture recognizers
|
|
134
|
+
// detached on unload never re-attach: real taps die while notify()
|
|
135
|
+
// probes still dispatch. onLoaded() early-returns when the flag is
|
|
136
|
+
// already set, so forcing the load pass is free on the normal path.
|
|
137
|
+
const page = frame.currentPage as any
|
|
138
|
+
if (page && page.isLoaded === false) {
|
|
139
|
+
page.callLoaded?.()
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
emit()
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function resolveStack(stack: string): Frame | undefined {
|
|
147
|
+
const frame = getStack(stack)
|
|
148
|
+
if (frame) {
|
|
149
|
+
trackFrame(frame)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return frame
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** TabViewItem-hosted frames report isLoaded=false after tab-selection
|
|
156
|
+
* lifecycle churn; without re-arming, the nav queue defers pushes AND pops
|
|
157
|
+
* forever (iOS strand of #11444 — goBack also gates on isLoaded via
|
|
158
|
+
* _processNextNavigationEntry). callLoaded is idempotent once the flag
|
|
159
|
+
* holds, so run it before every navigate/goBack on a registered frame. */
|
|
160
|
+
function rearmFrameLoaded(frame: Frame): void {
|
|
161
|
+
if (!(frame as any).isLoaded) {
|
|
162
|
+
;(frame as any).callLoaded?.()
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
onStackRegistered((_name, frame) => {
|
|
167
|
+
trackFrame(frame)
|
|
168
|
+
ensureBackWired()
|
|
169
|
+
emit()
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
// ---------- the contract ----------
|
|
173
|
+
|
|
174
|
+
// Open modal hosts, in open order — popRoute dismisses the newest first.
|
|
175
|
+
// showModal isn't a frame push: the underlying stack's currentPage never
|
|
176
|
+
// changes, so the route store emits through the modal's own bookkeeping.
|
|
177
|
+
const modalHosts: { host: GridLayout; route: Route; dismiss: () => void }[] = []
|
|
178
|
+
const swapTabRoutes = new Map<string, Route[]>()
|
|
179
|
+
const swapTabOrder: string[] = []
|
|
180
|
+
|
|
181
|
+
// ---------- hardware back ----------
|
|
182
|
+
|
|
183
|
+
/** App-supplied interceptors, consulted most-recent-first before the
|
|
184
|
+
* framework's default stack pop. Return true to consume the press. */
|
|
185
|
+
const backInterceptors: (() => boolean)[] = []
|
|
186
|
+
let backWired = false
|
|
187
|
+
|
|
188
|
+
/** Register an Android hardware-back interceptor. Interceptors run
|
|
189
|
+
* most-recent-first (so the topmost mounted screen wins) before the
|
|
190
|
+
* framework's default pop; returning true consumes the press. Returns
|
|
191
|
+
* an unsubscribe. iOS has no hardware back — interceptors simply never
|
|
192
|
+
* fire there. */
|
|
193
|
+
export function addBackInterceptor(fn: () => boolean): () => void {
|
|
194
|
+
backInterceptors.push(fn)
|
|
195
|
+
return () => {
|
|
196
|
+
const i = backInterceptors.indexOf(fn)
|
|
197
|
+
if (i !== -1) {
|
|
198
|
+
backInterceptors.splice(i, 1)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** Framework-owned default: the newest open modal, then the root stack's
|
|
204
|
+
* pushed page (a root push covers the shell), then the most recently
|
|
205
|
+
* used swap-pane stack, then any registered named stack that can pop.
|
|
206
|
+
* Returns false at the base of everything — the press falls through to
|
|
207
|
+
* the system (app exit). NS's own default pops `Frame.topmost()` — the
|
|
208
|
+
* innermost frame — which is wrong once nested stacks exist, so this
|
|
209
|
+
* ordering is deliberate. */
|
|
210
|
+
function defaultBackPress(): boolean {
|
|
211
|
+
const modal = modalHosts[modalHosts.length - 1]
|
|
212
|
+
if (modal) {
|
|
213
|
+
popRoute(modal.route.stack)
|
|
214
|
+
return true
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (canGoBack('root')) {
|
|
218
|
+
popRoute('root')
|
|
219
|
+
return true
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
for (const name of [...swapTabOrder].reverse()) {
|
|
223
|
+
if (canGoBack(name)) {
|
|
224
|
+
popRoute(name)
|
|
225
|
+
return true
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
for (const [name] of [...stackEntries()].reverse()) {
|
|
230
|
+
if (name === 'root') {
|
|
231
|
+
continue
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (canGoBack(name)) {
|
|
235
|
+
popRoute(name)
|
|
236
|
+
return true
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return false
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Install the Android activityBackPressed listener once. Called from
|
|
244
|
+
* registerScreens and from stack registration, so any app shape that
|
|
245
|
+
* can navigate (screens or stacks registered) is covered without a
|
|
246
|
+
* module-import-time read of Application.android. The subscription is
|
|
247
|
+
* singletoned on the Application object: under vite HMR this module's
|
|
248
|
+
* state resets but the listener must not duplicate — the press handler
|
|
249
|
+
* delegates through a slot so a reloaded module graph swaps in its fresh
|
|
250
|
+
* closures instead of double-popping. */
|
|
251
|
+
function ensureBackWired(): void {
|
|
252
|
+
if (backWired || !Application.android) {
|
|
253
|
+
return
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
backWired = true
|
|
257
|
+
const app = Application as any
|
|
258
|
+
app.__octaneXplatBackPress = (e: { cancel: boolean }) => {
|
|
259
|
+
for (let i = backInterceptors.length - 1; i >= 0; i--) {
|
|
260
|
+
if (backInterceptors[i]()) {
|
|
261
|
+
e.cancel = true
|
|
262
|
+
return
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (defaultBackPress()) {
|
|
267
|
+
e.cancel = true
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (app.__octaneXplatBackWired) {
|
|
272
|
+
return
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
app.__octaneXplatBackWired = true
|
|
276
|
+
Application.android.on(Application.AndroidApplication.activityBackPressedEvent, (e: {
|
|
277
|
+
cancel: boolean
|
|
278
|
+
}) => {
|
|
279
|
+
app.__octaneXplatBackPress?.(e)
|
|
280
|
+
})
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function presentationFor(name: string): Route['presentation'] {
|
|
284
|
+
return routes.find((m) => m.name === name)?.presentation
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function metaFor(name: string): RouteMeta | undefined {
|
|
288
|
+
return routes.find((meta) => meta.name === name)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function headFor(r: Route): { title?: string; meta?: Record<string, string> } | undefined {
|
|
292
|
+
const head = metaFor(r.name)?.head
|
|
293
|
+
return (typeof head === 'function' ? head(r.params) : head) as
|
|
294
|
+
| { title?: string; meta?: Record<string, string> }
|
|
295
|
+
| undefined
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
function contextFor(r: Route): Record<string, unknown> {
|
|
299
|
+
return r.context ?? {}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
async function prepareRoute(r: Route, redirects = 0): Promise<void> {
|
|
303
|
+
const beforeLoad = metaFor(r.name)?.beforeLoad
|
|
304
|
+
if (!beforeLoad) {
|
|
305
|
+
commitRoute(r)
|
|
306
|
+
return
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (redirects > 16) {
|
|
310
|
+
console.warn(`[octane-xplat] beforeLoad redirect loop for '${r.name}'`)
|
|
311
|
+
return
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
try {
|
|
315
|
+
const returned = await beforeLoad({ params: r.params, context: contextFor(r) })
|
|
316
|
+
const context = returned ? { ...contextFor(r), ...returned } : contextFor(r)
|
|
317
|
+
commitRoute({
|
|
318
|
+
...r,
|
|
319
|
+
context,
|
|
320
|
+
})
|
|
321
|
+
} catch (e) {
|
|
322
|
+
if (e instanceof RouteRedirect) {
|
|
323
|
+
await prepareRoute(e.route, redirects + 1)
|
|
324
|
+
return
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
console.warn(`[octane-xplat] beforeLoad('${r.name}') rejected: ${(e as Error)?.message ?? e}`)
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export function redirect(r: Route): never {
|
|
332
|
+
throw new RouteRedirect(r)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export function pushRoute(r: Route): void {
|
|
336
|
+
if (metaFor(r.name)?.beforeLoad) {
|
|
337
|
+
void prepareRoute(r)
|
|
338
|
+
return
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
commitRoute(r)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function commitRoute(r: Route): void {
|
|
345
|
+
const C = screenFor(r.name)
|
|
346
|
+
if (!C) {
|
|
347
|
+
warnOnce(
|
|
348
|
+
'screen:' + r.name,
|
|
349
|
+
`pushRoute('${r.name}') dropped — '${r.name}' isn't in the screen table. Call registerScreens({ ${r.name}: ... }) at boot.`,
|
|
350
|
+
)
|
|
351
|
+
|
|
352
|
+
return
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const presentation = r.presentation ?? presentationFor(r.name)
|
|
356
|
+
const loader = routeLoaders[r.name]
|
|
357
|
+
if (
|
|
358
|
+
loader &&
|
|
359
|
+
!Object.prototype.hasOwnProperty.call(r, 'loaderData') &&
|
|
360
|
+
!Object.prototype.hasOwnProperty.call(r, 'loaderError')
|
|
361
|
+
) {
|
|
362
|
+
void Promise.resolve()
|
|
363
|
+
.then(() => loader(r.params))
|
|
364
|
+
.then(
|
|
365
|
+
(loaderData) => commitRoute({ ...r, loaderData }),
|
|
366
|
+
(loaderError) => commitRoute({ ...r, loaderError }),
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
return
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (presentation === 'modal') {
|
|
373
|
+
const presenter = resolveStack(r.stack) ?? resolveStack('root')
|
|
374
|
+
if (presenter) {
|
|
375
|
+
pushModal(presenter, { ...r, presentation }, C)
|
|
376
|
+
} else {
|
|
377
|
+
warnOnce('modal:' + r.name, `modal route '${r.name}' dropped — no loaded presenter Frame.`)
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
return
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Swap-pane stacks live in the route store: on Android always (nested
|
|
384
|
+
// Frames inside tabs are unsafe — upstream #11444), and on any native
|
|
385
|
+
// target when no Frame registered the name — the self-drawn Tabs' panes
|
|
386
|
+
// (decision #44) render pushed routes through RouteHost, no Frame at
|
|
387
|
+
// all. A registered Frame still wins (platform UITabBar /
|
|
388
|
+
// BottomNavigationView panes navigate natively on iOS).
|
|
389
|
+
if (r.stack !== 'root' && (Application.android || !resolveStack(r.stack))) {
|
|
390
|
+
const entries = swapTabRoutes.get(r.stack) ?? []
|
|
391
|
+
entries.push({ ...r, presentation })
|
|
392
|
+
swapTabRoutes.set(r.stack, entries)
|
|
393
|
+
const at = swapTabOrder.indexOf(r.stack)
|
|
394
|
+
if (at !== -1) {
|
|
395
|
+
swapTabOrder.splice(at, 1)
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
swapTabOrder.push(r.stack)
|
|
399
|
+
const title = headFor(r)?.title
|
|
400
|
+
const page = resolveStack(r.stack)?.currentPage
|
|
401
|
+
if (title !== undefined && page) {
|
|
402
|
+
page.actionBar.title = title
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
emit()
|
|
406
|
+
return
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
const frame = resolveStack(r.stack)
|
|
410
|
+
if (!frame) {
|
|
411
|
+
warnOnce(
|
|
412
|
+
'stack:' + r.stack,
|
|
413
|
+
r.stack === 'root'
|
|
414
|
+
? `pushRoute('${r.name}') dropped — no root Frame. Boot with a Frame as the app root (Application.run create() returning new Frame) or call registerStack('root', frame).`
|
|
415
|
+
: `pushRoute('${r.name}') dropped — no stack '${r.stack}' is registered. Named stacks come from TabSpec.stack on <Tabs> or registerStack('${r.stack}', frame).`,
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
return
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
rearmFrameLoaded(frame)
|
|
422
|
+
|
|
423
|
+
const props: Record<string, unknown> = {
|
|
424
|
+
...r.params,
|
|
425
|
+
...contextFor(r),
|
|
426
|
+
...(r.stack === 'root' ? {} : { _stack: r.stack }),
|
|
427
|
+
_pushed: true,
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (Object.prototype.hasOwnProperty.call(r, 'loaderData')) {
|
|
431
|
+
props.data = r.loaderData
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
if (Object.prototype.hasOwnProperty.call(r, 'loaderError')) {
|
|
435
|
+
props.error = r.loaderError
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
try {
|
|
439
|
+
frame.navigate({
|
|
440
|
+
create: () => {
|
|
441
|
+
const page = new Page()
|
|
442
|
+
page.id = r.name + '-page'
|
|
443
|
+
page.actionBarHidden = true
|
|
444
|
+
const head = headFor(r)
|
|
445
|
+
if (head?.title !== undefined) {
|
|
446
|
+
page.actionBar.title = head.title
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
pageRoutes.set(page, r)
|
|
450
|
+
// Page is a ContentView — single-child (`.content` assignment
|
|
451
|
+
// drops all but the last root view). Root on a GridLayout
|
|
452
|
+
// child so multi-root screens can't silently lose siblings.
|
|
453
|
+
const host = new GridLayout()
|
|
454
|
+
page.content = host
|
|
455
|
+
// .ts → .tsrx component imports type as () => Element; the
|
|
456
|
+
// layout chain wraps it into a stamped universal component.
|
|
457
|
+
createNativeScriptRoot(host).render(RouteHost as unknown as UniversalComponent, {
|
|
458
|
+
screen: C,
|
|
459
|
+
layouts: layoutsForRoute(r.name),
|
|
460
|
+
params: props,
|
|
461
|
+
})
|
|
462
|
+
|
|
463
|
+
return page
|
|
464
|
+
},
|
|
465
|
+
transition: presentation === 'fade' ? { name: 'fade' } : undefined,
|
|
466
|
+
})
|
|
467
|
+
} catch (e) {
|
|
468
|
+
console.warn('[octane-xplat] pushRoute(' + r.name + ') threw: ' + (e as Error)?.message)
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/** A modal route is its own Octane root on a `showModal` host — the same
|
|
473
|
+
* shape as openModal in modal-service, but tracked as a Route so
|
|
474
|
+
* popRoute/currentModalRoute stay honest. The screen receives `close`
|
|
475
|
+
* alongside its params and calls it (or popRoute) to dismiss. */
|
|
476
|
+
function pushModal(frame: Frame, r: Route, C: any): void {
|
|
477
|
+
const host = new GridLayout()
|
|
478
|
+
const root = createNativeScriptRoot(host) as any
|
|
479
|
+
const entry = { host, route: r, dismiss: () => {} }
|
|
480
|
+
entry.dismiss = () => {
|
|
481
|
+
const i = modalHosts.indexOf(entry)
|
|
482
|
+
if (i === -1) {
|
|
483
|
+
return
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
modalHosts.splice(i, 1)
|
|
487
|
+
emit()
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
const presenter = modalPresenter(frame)
|
|
491
|
+
if (!presenter) {
|
|
492
|
+
warnOnce(
|
|
493
|
+
'modal-presenter:' + r.name,
|
|
494
|
+
`modal route '${r.name}' dropped — no live presenter. The stack's currentPage is mid-navigation; retry once the transition settles.`,
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
entry.dismiss()
|
|
498
|
+
root.unmount?.()
|
|
499
|
+
return
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
try {
|
|
503
|
+
modalHosts.push(entry)
|
|
504
|
+
const params: Record<string, unknown> = {
|
|
505
|
+
...r.params,
|
|
506
|
+
...contextFor(r),
|
|
507
|
+
_pushed: true,
|
|
508
|
+
close: () => (host as any).closeModal?.(),
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
if (Object.prototype.hasOwnProperty.call(r, 'loaderData')) {
|
|
512
|
+
params.data = r.loaderData
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (Object.prototype.hasOwnProperty.call(r, 'loaderError')) {
|
|
516
|
+
params.error = r.loaderError
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
root.render(RouteHost as unknown as UniversalComponent, {
|
|
520
|
+
screen: C,
|
|
521
|
+
layouts: layoutsForRoute(r.name),
|
|
522
|
+
params,
|
|
523
|
+
})
|
|
524
|
+
|
|
525
|
+
presenter.showModal(host, {
|
|
526
|
+
context: {},
|
|
527
|
+
closeCallback: entry.dismiss,
|
|
528
|
+
fullscreen: true,
|
|
529
|
+
animated: true,
|
|
530
|
+
})
|
|
531
|
+
|
|
532
|
+
emit()
|
|
533
|
+
} catch (e) {
|
|
534
|
+
entry.dismiss()
|
|
535
|
+
root.unmount?.()
|
|
536
|
+
console.warn('[octane-xplat] modal pushRoute(' + r.name + ') threw: ' + (e as Error)?.message)
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/** Pop the top page of a stack ('root' default) — or dismiss the top
|
|
541
|
+
* modal if one is open. Quiet no-op at the base page — matching web,
|
|
542
|
+
* where back at the app root is a no-op; loud only when the stack
|
|
543
|
+
* itself doesn't exist. */
|
|
544
|
+
export function popRoute(stack = 'root'): void {
|
|
545
|
+
const modal = modalHosts[modalHosts.length - 1]
|
|
546
|
+
if (modal) {
|
|
547
|
+
// Bookkeeping first: iOS drops dismissViewController completions
|
|
548
|
+
// that race a still-in-flight presentation, so the NS closeCallback
|
|
549
|
+
// isn't guaranteed to run — the route store can't gate on it.
|
|
550
|
+
modal.dismiss()
|
|
551
|
+
|
|
552
|
+
;(modal.host as any).closeModal?.()
|
|
553
|
+
return
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (stack !== 'root' && (Application.android || !resolveStack(stack))) {
|
|
557
|
+
const entries = swapTabRoutes.get(stack)
|
|
558
|
+
if (entries?.length) {
|
|
559
|
+
entries.pop()
|
|
560
|
+
if (!entries.length) {
|
|
561
|
+
swapTabRoutes.delete(stack)
|
|
562
|
+
const at = swapTabOrder.indexOf(stack)
|
|
563
|
+
if (at !== -1) {
|
|
564
|
+
swapTabOrder.splice(at, 1)
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
emit()
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const frame = resolveStack(stack)
|
|
575
|
+
if (!frame) {
|
|
576
|
+
warnOnce('pop:' + stack, `popRoute('${stack}') dropped — no such stack is registered.`)
|
|
577
|
+
return
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// Same stall as pushes: a queued goBack defers forever while isLoaded is
|
|
581
|
+
// stale, and nothing else re-arms the frame before the pop.
|
|
582
|
+
rearmFrameLoaded(frame)
|
|
583
|
+
frame.goBack()
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/** Route stamped on a stack's current page, or null at its base page. */
|
|
587
|
+
export function routeFor(stack: string): Route | null {
|
|
588
|
+
if (stack !== 'root' && (Application.android || !resolveStack(stack))) {
|
|
589
|
+
const entries = swapTabRoutes.get(stack)
|
|
590
|
+
if (entries?.length) {
|
|
591
|
+
return entries[entries.length - 1]
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
const page = resolveStack(stack)?.currentPage
|
|
596
|
+
return (page && pageRoutes.get(page)) ?? null
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/** The top route across stacks — root's current route wins (a root push
|
|
600
|
+
* covers the shell); otherwise the most recently registered named stack
|
|
601
|
+
* showing a pushed page. Native has no boot URL, so this is an
|
|
602
|
+
* approximation of web's "current URL route", not a deep link. */
|
|
603
|
+
export function currentRoute(): Route | null {
|
|
604
|
+
const root = routeFor('root')
|
|
605
|
+
if (root) {
|
|
606
|
+
return root
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
for (const name of [...swapTabOrder].reverse()) {
|
|
610
|
+
const route = routeFor(name)
|
|
611
|
+
if (route) {
|
|
612
|
+
return route
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const named = [...stackEntries()].reverse()
|
|
617
|
+
for (const [name] of named) {
|
|
618
|
+
const r = routeFor(name)
|
|
619
|
+
if (r) {
|
|
620
|
+
return r
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
return null
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/** Named stacks containing routes, including Android's swap-pane stacks. */
|
|
628
|
+
export function routeStacks(): string[] {
|
|
629
|
+
return [...new Set([...swapTabOrder, ...[...stackEntries()].map(([name]) => name)])]
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/** The modal route currently open, if any — parity with the web leaf. */
|
|
633
|
+
export function currentModalRoute(): Route | null {
|
|
634
|
+
return modalHosts[modalHosts.length - 1]?.route ?? null
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/** Deep-link entry: normalize a URL (http(s) or app-scheme) to a path,
|
|
638
|
+
* match it against the manifest, push the route. Wire it at boot:
|
|
639
|
+
* `onDeepLink(pushDeepLink)` plus one `consumeInitialUrl()` call. */
|
|
640
|
+
export function pushDeepLink(url: string): boolean {
|
|
641
|
+
const r = matchUrl(routes, linkPath(url))
|
|
642
|
+
if (!r) {
|
|
643
|
+
warnOnce('link:' + url, `pushDeepLink('${url}') dropped — no route matches.`)
|
|
644
|
+
return false
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
pushRoute(r)
|
|
648
|
+
return true
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/** Path-string parity for the web leaf's hrefFor — a canonical
|
|
652
|
+
* /<stack>/<path> rendering of the route (deep-linking consumes it
|
|
653
|
+
* there). Native navigation itself is name+params, not URLs. */
|
|
654
|
+
export function hrefFor(r: Route): string {
|
|
655
|
+
return buildRoutePath(routes, r)
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
export function useRoute(stack: string): Route | null {
|
|
659
|
+
return useSyncExternalStore(
|
|
660
|
+
(cb) => {
|
|
661
|
+
listeners.add(cb)
|
|
662
|
+
return () => listeners.delete(cb)
|
|
663
|
+
},
|
|
664
|
+
() => routeFor(stack),
|
|
665
|
+
)
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
/** Whether the selected native stack has a page (or route-owned Android swap
|
|
669
|
+
* entry) that can be popped. The modal root is also a back affordance. */
|
|
670
|
+
export function canGoBack(stack = 'root'): boolean {
|
|
671
|
+
const modal = modalHosts[modalHosts.length - 1]
|
|
672
|
+
if (modal?.route.stack === stack) {
|
|
673
|
+
return true
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
if (stack !== 'root' && (Application.android || !resolveStack(stack))) {
|
|
677
|
+
return !!swapTabRoutes.get(stack)?.length
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
const frame = resolveStack(stack)
|
|
681
|
+
return !!frame?.backStack?.length
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
export function useCanGoBack(stack = 'root'): boolean {
|
|
685
|
+
return useSyncExternalStore(
|
|
686
|
+
(cb) => {
|
|
687
|
+
listeners.add(cb)
|
|
688
|
+
return () => listeners.delete(cb)
|
|
689
|
+
},
|
|
690
|
+
() => canGoBack(stack),
|
|
691
|
+
)
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/** The modal route overlaying the shell — parity with the web leaf. */
|
|
695
|
+
export function useModalRoute(): Route | null {
|
|
696
|
+
return useSyncExternalStore(
|
|
697
|
+
(cb) => {
|
|
698
|
+
listeners.add(cb)
|
|
699
|
+
return () => listeners.delete(cb)
|
|
700
|
+
},
|
|
701
|
+
() => currentModalRoute(),
|
|
702
|
+
)
|
|
703
|
+
}
|