@krizaka/ui 3.2.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/activity-feed.d.ts +199 -0
- package/dist/activity-feed.js +155 -0
- package/dist/activity-feed.js.map +1 -0
- package/dist/argument-card.js +3 -3
- package/dist/{chunk-I5RVM5CW.js → chunk-2FRWNSRO.js} +2 -6
- package/dist/chunk-2FRWNSRO.js.map +1 -0
- package/dist/chunk-7Z4KHPFC.js +42 -0
- package/dist/chunk-7Z4KHPFC.js.map +1 -0
- package/dist/chunk-BTMFZ66D.js +135 -0
- package/dist/chunk-BTMFZ66D.js.map +1 -0
- package/dist/chunk-C2BRIFJG.js +13 -0
- package/dist/chunk-C2BRIFJG.js.map +1 -0
- package/dist/chunk-KDXRYUD3.js +39 -0
- package/dist/chunk-KDXRYUD3.js.map +1 -0
- package/dist/{chunk-2PUDI7JS.js → chunk-ZKVQGXLD.js} +5 -3
- package/dist/{chunk-2PUDI7JS.js.map → chunk-ZKVQGXLD.js.map} +1 -1
- package/dist/command.js +1 -1
- package/dist/confirm-button.js +1 -1
- package/dist/data-table.js +101 -133
- package/dist/data-table.js.map +1 -1
- package/dist/date-picker.d.ts +3 -1
- package/dist/date-picker.js +13 -13
- package/dist/date-picker.js.map +1 -1
- package/dist/description-list.d.ts +105 -0
- package/dist/description-list.js +49 -0
- package/dist/description-list.js.map +1 -0
- package/dist/dropdown-menu.js +1 -1
- package/dist/filter-bar.js +3 -2
- package/dist/form.d.ts +23 -12
- package/dist/form.js +11 -47
- package/dist/form.js.map +1 -1
- package/dist/glow-card.js +1 -1
- package/dist/image-cropper.js +3 -1
- package/dist/image-cropper.js.map +1 -1
- package/dist/index.js +13 -66
- package/dist/index.js.map +1 -1
- package/dist/kanban.d.ts +132 -0
- package/dist/kanban.js +187 -0
- package/dist/kanban.js.map +1 -0
- package/dist/list.d.ts +153 -0
- package/dist/list.js +130 -0
- package/dist/list.js.map +1 -0
- package/dist/map.d.ts +463 -0
- package/dist/map.js +952 -0
- package/dist/map.js.map +1 -0
- package/dist/marquee.js +1 -1
- package/dist/motion.css +12 -1
- package/dist/native/form.d.ts +60 -15
- package/dist/native/form.js +103 -42
- package/dist/native/form.js.map +1 -1
- package/dist/native/map.d.ts +200 -0
- package/dist/native/map.js +673 -0
- package/dist/native/map.js.map +1 -0
- package/dist/native/media-picker.d.ts +58 -0
- package/dist/native/media-picker.js +63 -0
- package/dist/native/media-picker.js.map +1 -0
- package/dist/native.d.ts +772 -6
- package/dist/native.js +2493 -741
- package/dist/native.js.map +1 -1
- package/dist/nav-bar.js +1 -1
- package/dist/page-hero.js +3 -3
- package/dist/popover.js +1 -1
- package/dist/radio-group.d.ts +66 -32
- package/dist/radio-group.js +54 -10
- package/dist/radio-group.js.map +1 -1
- package/dist/slider.d.ts +96 -35
- package/dist/slider.js +67 -13
- package/dist/slider.js.map +1 -1
- package/dist/stat.d.ts +31 -2
- package/dist/stat.js +21 -4
- package/dist/stat.js.map +1 -1
- package/dist/terminal-replay.js +34 -60
- package/dist/terminal-replay.js.map +1 -1
- package/dist/toast.js +1 -1
- package/dist/tooltip.js +1 -1
- package/dist/tree-view.d.ts +111 -0
- package/dist/tree-view.js +154 -0
- package/dist/tree-view.js.map +1 -0
- package/dist/video-player.js +3 -1
- package/dist/video-player.js.map +1 -1
- package/package.json +148 -11
- package/registry/achievement.json +1 -1
- package/registry/action-bar.json +1 -1
- package/registry/action-sheet.json +121 -0
- package/registry/activity-feed.json +468 -0
- package/registry/alert.json +1 -1
- package/registry/app-shell.json +1 -1
- package/registry/argument-card.json +1 -1
- package/registry/audio-player.json +1 -1
- package/registry/auth-layout.json +1 -1
- package/registry/avatar.json +58 -3
- package/registry/badge.json +1 -1
- package/registry/button.json +1 -1
- package/registry/card-grid.json +1 -1
- package/registry/card.json +1 -1
- package/registry/catalogue-page.json +1 -1
- package/registry/changelog-page.json +1 -1
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +1 -1
- package/registry/chip.json +1 -1
- package/registry/choice-grid.json +1 -1
- package/registry/code-block.json +1 -1
- package/registry/combobox.json +226 -4
- package/registry/command.json +1 -1
- package/registry/component-page.json +1 -1
- package/registry/confirm-button.json +1 -1
- package/registry/contact-page.json +1 -1
- package/registry/continue-prompt.json +1 -1
- package/registry/countdown.json +1 -1
- package/registry/cta-panel.json +1 -1
- package/registry/dashboard-layout.json +1 -1
- package/registry/data-table.json +1 -1
- package/registry/date-picker.json +18 -4
- package/registry/decision-list.json +1 -1
- package/registry/description-list.json +232 -0
- package/registry/detail-layout.json +1 -1
- package/registry/dialog.json +75 -4
- package/registry/docs-article-page.json +1 -1
- package/registry/docs-hub-page.json +1 -1
- package/registry/docs-layout.json +1 -1
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/error-page.json +1 -1
- package/registry/examples/action-sheet/native/video-actions.d.ts +4 -0
- package/registry/examples/action-sheet/native/video-actions.dark.png +0 -0
- package/registry/examples/action-sheet/native/video-actions.js +30 -0
- package/registry/examples/action-sheet/native/video-actions.light.png +0 -0
- package/registry/examples/action-sheet/native/video-actions.tsx +24 -0
- package/registry/examples/activity-feed/job-activity.d.ts +4 -0
- package/registry/examples/activity-feed/job-activity.js +21 -0
- package/registry/examples/activity-feed/job-activity.tsx +17 -0
- package/registry/examples/activity-feed/live.d.ts +4 -0
- package/registry/examples/activity-feed/live.js +23 -0
- package/registry/examples/activity-feed/live.tsx +24 -0
- package/registry/examples/activity-feed/native/notifications.d.ts +4 -0
- package/registry/examples/activity-feed/native/notifications.dark.png +0 -0
- package/registry/examples/activity-feed/native/notifications.js +18 -0
- package/registry/examples/activity-feed/native/notifications.light.png +0 -0
- package/registry/examples/activity-feed/native/notifications.tsx +18 -0
- package/registry/examples/activity-feed/timeline.d.ts +4 -0
- package/registry/examples/activity-feed/timeline.js +25 -0
- package/registry/examples/activity-feed/timeline.tsx +19 -0
- package/registry/examples/avatar/native/presence.d.ts +4 -0
- package/registry/examples/avatar/native/presence.dark.png +0 -0
- package/registry/examples/avatar/native/presence.js +18 -0
- package/registry/examples/avatar/native/presence.light.png +0 -0
- package/registry/examples/avatar/native/presence.tsx +15 -0
- package/registry/examples/combobox/native/multiple.d.ts +4 -0
- package/registry/examples/combobox/native/multiple.dark.png +0 -0
- package/registry/examples/combobox/native/multiple.js +15 -0
- package/registry/examples/combobox/native/multiple.light.png +0 -0
- package/registry/examples/combobox/native/multiple.tsx +15 -0
- package/registry/examples/combobox/native/search.d.ts +4 -0
- package/registry/examples/combobox/native/search.dark.png +0 -0
- package/registry/examples/combobox/native/search.js +15 -0
- package/registry/examples/combobox/native/search.light.png +0 -0
- package/registry/examples/combobox/native/search.tsx +15 -0
- package/registry/examples/description-list/job-details.d.ts +4 -0
- package/registry/examples/description-list/job-details.js +23 -0
- package/registry/examples/description-list/job-details.tsx +17 -0
- package/registry/examples/description-list/key-value-grid.d.ts +4 -0
- package/registry/examples/description-list/key-value-grid.js +22 -0
- package/registry/examples/description-list/key-value-grid.tsx +16 -0
- package/registry/examples/description-list/native/job-details.d.ts +4 -0
- package/registry/examples/description-list/native/job-details.dark.png +0 -0
- package/registry/examples/description-list/native/job-details.js +33 -0
- package/registry/examples/description-list/native/job-details.light.png +0 -0
- package/registry/examples/description-list/native/job-details.tsx +24 -0
- package/registry/examples/description-list/receipt.d.ts +4 -0
- package/registry/examples/description-list/receipt.js +23 -0
- package/registry/examples/description-list/receipt.tsx +17 -0
- package/registry/examples/dialog/native/sheet.d.ts +4 -0
- package/registry/examples/dialog/native/sheet.dark.png +0 -0
- package/registry/examples/dialog/native/sheet.js +21 -0
- package/registry/examples/dialog/native/sheet.light.png +0 -0
- package/registry/examples/dialog/native/sheet.tsx +18 -0
- package/registry/examples/fab/native/extended.d.ts +4 -0
- package/registry/examples/fab/native/extended.dark.png +0 -0
- package/registry/examples/fab/native/extended.js +18 -0
- package/registry/examples/fab/native/extended.light.png +0 -0
- package/registry/examples/fab/native/extended.tsx +23 -0
- package/registry/examples/field/native/select.d.ts +4 -0
- package/registry/examples/field/native/select.dark.png +0 -0
- package/registry/examples/field/native/select.js +29 -0
- package/registry/examples/field/native/select.light.png +0 -0
- package/registry/examples/field/native/select.tsx +25 -0
- package/registry/examples/form/native/audience.dark.png +0 -0
- package/registry/examples/form/native/audience.light.png +0 -0
- package/registry/examples/form/native/profile.dark.png +0 -0
- package/registry/examples/form/native/profile.light.png +0 -0
- package/registry/examples/form/native/settings.dark.png +0 -0
- package/registry/examples/form/native/settings.light.png +0 -0
- package/registry/examples/form/native/sign-up.dark.png +0 -0
- package/registry/examples/form/native/sign-up.light.png +0 -0
- package/registry/examples/form/native/upload.dark.png +0 -0
- package/registry/examples/form/native/upload.light.png +0 -0
- package/registry/examples/header/native/large-title.d.ts +4 -0
- package/registry/examples/header/native/large-title.dark.png +0 -0
- package/registry/examples/header/native/large-title.js +23 -0
- package/registry/examples/header/native/large-title.light.png +0 -0
- package/registry/examples/header/native/large-title.tsx +31 -0
- package/registry/examples/image-viewer/native/gallery.d.ts +4 -0
- package/registry/examples/image-viewer/native/gallery.dark.png +0 -0
- package/registry/examples/image-viewer/native/gallery.js +22 -0
- package/registry/examples/image-viewer/native/gallery.light.png +0 -0
- package/registry/examples/image-viewer/native/gallery.tsx +21 -0
- package/registry/examples/kanban/moderation.d.ts +4 -0
- package/registry/examples/kanban/moderation.js +35 -0
- package/registry/examples/kanban/moderation.tsx +37 -0
- package/registry/examples/list/jobs.d.ts +4 -0
- package/registry/examples/list/jobs.js +35 -0
- package/registry/examples/list/jobs.tsx +33 -0
- package/registry/examples/list/selectable.d.ts +4 -0
- package/registry/examples/list/selectable.js +33 -0
- package/registry/examples/list/selectable.tsx +30 -0
- package/registry/examples/list/virtualized.d.ts +4 -0
- package/registry/examples/list/virtualized.js +22 -0
- package/registry/examples/list/virtualized.tsx +17 -0
- package/registry/examples/loader/native/block.d.ts +4 -0
- package/registry/examples/loader/native/block.dark.png +0 -0
- package/registry/examples/loader/native/block.js +12 -0
- package/registry/examples/loader/native/block.light.png +0 -0
- package/registry/examples/loader/native/block.tsx +11 -0
- package/registry/examples/loader/native/job-wait.d.ts +4 -0
- package/registry/examples/loader/native/job-wait.dark.png +0 -0
- package/registry/examples/loader/native/job-wait.js +17 -0
- package/registry/examples/loader/native/job-wait.light.png +0 -0
- package/registry/examples/loader/native/job-wait.tsx +14 -0
- package/registry/examples/map/cluster.d.ts +4 -0
- package/registry/examples/map/cluster.js +16 -0
- package/registry/examples/map/cluster.tsx +18 -0
- package/registry/examples/map/location-picker.d.ts +4 -0
- package/registry/examples/map/location-picker.js +24 -0
- package/registry/examples/map/location-picker.tsx +22 -0
- package/registry/examples/map/native/location-picker.d.ts +4 -0
- package/registry/examples/map/native/location-picker.dark.png +0 -0
- package/registry/examples/map/native/location-picker.js +14 -0
- package/registry/examples/map/native/location-picker.light.png +0 -0
- package/registry/examples/map/native/location-picker.tsx +13 -0
- package/registry/examples/map/native/places.d.ts +4 -0
- package/registry/examples/map/native/places.dark.png +0 -0
- package/registry/examples/map/native/places.js +25 -0
- package/registry/examples/map/native/places.light.png +0 -0
- package/registry/examples/map/native/places.tsx +27 -0
- package/registry/examples/map/places.d.ts +4 -0
- package/registry/examples/map/places.js +28 -0
- package/registry/examples/map/places.tsx +28 -0
- package/registry/examples/map/static.d.ts +4 -0
- package/registry/examples/map/static.js +22 -0
- package/registry/examples/map/static.tsx +18 -0
- package/registry/examples/media-picker/native/story.d.ts +4 -0
- package/registry/examples/media-picker/native/story.dark.png +0 -0
- package/registry/examples/media-picker/native/story.js +30 -0
- package/registry/examples/media-picker/native/story.light.png +0 -0
- package/registry/examples/media-picker/native/story.tsx +26 -0
- package/registry/examples/meter/native/credits.d.ts +4 -0
- package/registry/examples/meter/native/credits.dark.png +0 -0
- package/registry/examples/meter/native/credits.js +15 -0
- package/registry/examples/meter/native/credits.light.png +0 -0
- package/registry/examples/meter/native/credits.tsx +12 -0
- package/registry/examples/meter/native/split-ring.d.ts +4 -0
- package/registry/examples/meter/native/split-ring.dark.png +0 -0
- package/registry/examples/meter/native/split-ring.js +24 -0
- package/registry/examples/meter/native/split-ring.light.png +0 -0
- package/registry/examples/meter/native/split-ring.tsx +19 -0
- package/registry/examples/number-ticker/native/balance.d.ts +4 -0
- package/registry/examples/number-ticker/native/balance.dark.png +0 -0
- package/registry/examples/number-ticker/native/balance.js +18 -0
- package/registry/examples/number-ticker/native/balance.light.png +0 -0
- package/registry/examples/number-ticker/native/balance.tsx +17 -0
- package/registry/examples/onboarding/native/first-launch.d.ts +4 -0
- package/registry/examples/onboarding/native/first-launch.dark.png +0 -0
- package/registry/examples/onboarding/native/first-launch.js +23 -0
- package/registry/examples/onboarding/native/first-launch.light.png +0 -0
- package/registry/examples/onboarding/native/first-launch.tsx +19 -0
- package/registry/examples/otp-input/native/invalid.d.ts +4 -0
- package/registry/examples/otp-input/native/invalid.dark.png +0 -0
- package/registry/examples/otp-input/native/invalid.js +15 -0
- package/registry/examples/otp-input/native/invalid.light.png +0 -0
- package/registry/examples/otp-input/native/invalid.tsx +14 -0
- package/registry/examples/otp-input/native/verify.d.ts +4 -0
- package/registry/examples/otp-input/native/verify.dark.png +0 -0
- package/registry/examples/otp-input/native/verify.js +17 -0
- package/registry/examples/otp-input/native/verify.light.png +0 -0
- package/registry/examples/otp-input/native/verify.tsx +14 -0
- package/registry/examples/permission-prompt/native/blocked.d.ts +4 -0
- package/registry/examples/permission-prompt/native/blocked.dark.png +0 -0
- package/registry/examples/permission-prompt/native/blocked.js +25 -0
- package/registry/examples/permission-prompt/native/blocked.light.png +0 -0
- package/registry/examples/permission-prompt/native/blocked.tsx +21 -0
- package/registry/examples/permission-prompt/native/camera.d.ts +4 -0
- package/registry/examples/permission-prompt/native/camera.dark.png +0 -0
- package/registry/examples/permission-prompt/native/camera.js +25 -0
- package/registry/examples/permission-prompt/native/camera.light.png +0 -0
- package/registry/examples/permission-prompt/native/camera.tsx +21 -0
- package/registry/examples/pull-to-refresh/native/feed.d.ts +4 -0
- package/registry/examples/pull-to-refresh/native/feed.dark.png +0 -0
- package/registry/examples/pull-to-refresh/native/feed.js +14 -0
- package/registry/examples/pull-to-refresh/native/feed.light.png +0 -0
- package/registry/examples/pull-to-refresh/native/feed.tsx +19 -0
- package/registry/examples/radio-group/buttons.d.ts +4 -0
- package/registry/examples/radio-group/buttons.js +17 -0
- package/registry/examples/radio-group/buttons.tsx +21 -0
- package/registry/examples/radio-group/cards.js +1 -1
- package/registry/examples/radio-group/cards.tsx +2 -2
- package/registry/examples/radio-group/native/buttons.d.ts +4 -0
- package/registry/examples/radio-group/native/buttons.dark.png +0 -0
- package/registry/examples/radio-group/native/buttons.js +25 -0
- package/registry/examples/radio-group/native/buttons.light.png +0 -0
- package/registry/examples/radio-group/native/buttons.tsx +21 -0
- package/registry/examples/radio-group/native/cards.d.ts +4 -0
- package/registry/examples/radio-group/native/cards.dark.png +0 -0
- package/registry/examples/radio-group/native/cards.js +23 -0
- package/registry/examples/radio-group/native/cards.light.png +0 -0
- package/registry/examples/radio-group/native/cards.tsx +19 -0
- package/registry/examples/radio-group/native/list.d.ts +4 -0
- package/registry/examples/radio-group/native/list.dark.png +0 -0
- package/registry/examples/radio-group/native/list.js +24 -0
- package/registry/examples/radio-group/native/list.light.png +0 -0
- package/registry/examples/radio-group/native/list.tsx +20 -0
- package/registry/examples/radio-group/native/segmented.d.ts +4 -0
- package/registry/examples/radio-group/native/segmented.dark.png +0 -0
- package/registry/examples/radio-group/native/segmented.js +24 -0
- package/registry/examples/radio-group/native/segmented.light.png +0 -0
- package/registry/examples/radio-group/native/segmented.tsx +20 -0
- package/registry/examples/radio-group/segmented.d.ts +4 -0
- package/registry/examples/radio-group/segmented.js +15 -0
- package/registry/examples/radio-group/segmented.tsx +12 -0
- package/registry/examples/search-field/native/cancel.d.ts +4 -0
- package/registry/examples/search-field/native/cancel.dark.png +0 -0
- package/registry/examples/search-field/native/cancel.js +14 -0
- package/registry/examples/search-field/native/cancel.light.png +0 -0
- package/registry/examples/search-field/native/cancel.tsx +13 -0
- package/registry/examples/slider/floating.d.ts +4 -0
- package/registry/examples/slider/floating.js +11 -0
- package/registry/examples/slider/floating.tsx +12 -0
- package/registry/examples/slider/native/default.d.ts +4 -0
- package/registry/examples/slider/native/default.dark.png +0 -0
- package/registry/examples/slider/native/default.js +14 -0
- package/registry/examples/slider/native/default.light.png +0 -0
- package/registry/examples/slider/native/default.tsx +13 -0
- package/registry/examples/slider/native/range.d.ts +4 -0
- package/registry/examples/slider/native/range.dark.png +0 -0
- package/registry/examples/slider/native/range.js +12 -0
- package/registry/examples/slider/native/range.light.png +0 -0
- package/registry/examples/slider/native/range.tsx +11 -0
- package/registry/examples/slider/native/stepped.d.ts +4 -0
- package/registry/examples/slider/native/stepped.dark.png +0 -0
- package/registry/examples/slider/native/stepped.js +28 -0
- package/registry/examples/slider/native/stepped.light.png +0 -0
- package/registry/examples/slider/native/stepped.tsx +24 -0
- package/registry/examples/slider/native/vertical.d.ts +4 -0
- package/registry/examples/slider/native/vertical.dark.png +0 -0
- package/registry/examples/slider/native/vertical.js +16 -0
- package/registry/examples/slider/native/vertical.light.png +0 -0
- package/registry/examples/slider/native/vertical.tsx +13 -0
- package/registry/examples/slider/price-range.d.ts +4 -0
- package/registry/examples/slider/price-range.js +29 -0
- package/registry/examples/slider/price-range.tsx +27 -0
- package/registry/examples/slider/stepped.d.ts +4 -0
- package/registry/examples/slider/stepped.js +28 -0
- package/registry/examples/slider/stepped.tsx +24 -0
- package/registry/examples/slider/vertical.d.ts +4 -0
- package/registry/examples/slider/vertical.js +15 -0
- package/registry/examples/slider/vertical.tsx +14 -0
- package/registry/examples/stat/grid.d.ts +4 -0
- package/registry/examples/stat/grid.js +17 -0
- package/registry/examples/stat/grid.tsx +14 -0
- package/registry/examples/stepper/native/run.d.ts +4 -0
- package/registry/examples/stepper/native/run.dark.png +0 -0
- package/registry/examples/stepper/native/run.js +24 -0
- package/registry/examples/stepper/native/run.light.png +0 -0
- package/registry/examples/stepper/native/run.tsx +20 -0
- package/registry/examples/swipeable-row/native/conversation.d.ts +4 -0
- package/registry/examples/swipeable-row/native/conversation.dark.png +0 -0
- package/registry/examples/swipeable-row/native/conversation.js +30 -0
- package/registry/examples/swipeable-row/native/conversation.light.png +0 -0
- package/registry/examples/swipeable-row/native/conversation.tsx +27 -0
- package/registry/examples/switch/native/default.d.ts +4 -0
- package/registry/examples/switch/native/default.dark.png +0 -0
- package/registry/examples/switch/native/default.js +16 -0
- package/registry/examples/switch/native/default.light.png +0 -0
- package/registry/examples/switch/native/default.tsx +13 -0
- package/registry/examples/switch/native/settings.d.ts +4 -0
- package/registry/examples/switch/native/settings.dark.png +0 -0
- package/registry/examples/switch/native/settings.js +20 -0
- package/registry/examples/switch/native/settings.light.png +0 -0
- package/registry/examples/switch/native/settings.tsx +17 -0
- package/registry/examples/tab-bar/native/main-sections.d.ts +4 -0
- package/registry/examples/tab-bar/native/main-sections.dark.png +0 -0
- package/registry/examples/tab-bar/native/main-sections.js +29 -0
- package/registry/examples/tab-bar/native/main-sections.light.png +0 -0
- package/registry/examples/tab-bar/native/main-sections.tsx +30 -0
- package/registry/examples/tabs/native/sections.d.ts +4 -0
- package/registry/examples/tabs/native/sections.dark.png +0 -0
- package/registry/examples/tabs/native/sections.js +23 -0
- package/registry/examples/tabs/native/sections.light.png +0 -0
- package/registry/examples/tabs/native/sections.tsx +19 -0
- package/registry/examples/tabs/native/segmented.d.ts +4 -0
- package/registry/examples/tabs/native/segmented.dark.png +0 -0
- package/registry/examples/tabs/native/segmented.js +22 -0
- package/registry/examples/tabs/native/segmented.light.png +0 -0
- package/registry/examples/tabs/native/segmented.tsx +18 -0
- package/registry/examples/toast/native/snackbar.d.ts +4 -0
- package/registry/examples/toast/native/snackbar.dark.png +0 -0
- package/registry/examples/toast/native/snackbar.js +23 -0
- package/registry/examples/toast/native/snackbar.light.png +0 -0
- package/registry/examples/toast/native/snackbar.tsx +21 -0
- package/registry/examples/tree-view/docs.d.ts +4 -0
- package/registry/examples/tree-view/docs.js +24 -0
- package/registry/examples/tree-view/docs.tsx +22 -0
- package/registry/examples/tree-view/lazy.d.ts +4 -0
- package/registry/examples/tree-view/lazy.js +21 -0
- package/registry/examples/tree-view/lazy.tsx +19 -0
- package/registry/fab.json +122 -0
- package/registry/field.json +16 -4
- package/registry/file-upload.json +2 -2
- package/registry/filter-bar.json +1 -1
- package/registry/form.json +252 -44
- package/registry/gallery-page.json +1 -1
- package/registry/glow-card.json +1 -1
- package/registry/goal-gauge.json +1 -1
- package/registry/header.json +137 -0
- package/registry/how-it-works-page.json +1 -1
- package/registry/image-cropper.json +1 -1
- package/registry/image-viewer.json +107 -0
- package/registry/index.json +322 -44
- package/registry/iso.json +1 -1
- package/registry/kanban.json +253 -0
- package/registry/kbd.json +1 -1
- package/registry/landing-page.json +1 -1
- package/registry/landscape.json +1 -1
- package/registry/legal-page.json +1 -1
- package/registry/link-card.json +1 -1
- package/registry/list.json +367 -30
- package/registry/loader.json +157 -4
- package/registry/longform-page.json +1 -1
- package/registry/map.json +1368 -0
- package/registry/marketing-layout.json +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascot-quote.json +1 -1
- package/registry/mascot-state.json +1 -1
- package/registry/mascots.json +1 -1
- package/registry/media-capture.json +1 -1
- package/registry/media-picker.json +129 -0
- package/registry/meter.json +136 -4
- package/registry/nav-bar.json +1 -1
- package/registry/number-ticker.json +96 -4
- package/registry/onboarding.json +95 -0
- package/registry/otp-input.json +150 -0
- package/registry/page-header.json +1 -1
- package/registry/page-hero.json +1 -1
- package/registry/page.json +1 -1
- package/registry/pagination.json +1 -1
- package/registry/permission-prompt.json +172 -0
- package/registry/pointer-light.json +1 -1
- package/registry/popover.json +1 -1
- package/registry/pricing-page.json +1 -1
- package/registry/product-page.json +1 -1
- package/registry/profile-card.json +1 -1
- package/registry/progress.json +2 -2
- package/registry/promise-card.json +1 -1
- package/registry/pull-to-refresh.json +74 -0
- package/registry/radio-group.json +228 -16
- package/registry/scroll-stage.json +1 -1
- package/registry/search-field.json +30 -3
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/settings-layout.json +1 -1
- package/registry/skeleton.json +1 -1
- package/registry/slider.json +315 -14
- package/registry/slot.json +1 -1
- package/registry/spinner.json +1 -1
- package/registry/split-view.json +1 -1
- package/registry/stage-banner.json +1 -1
- package/registry/stat.json +68 -5
- package/registry/status-page.json +1 -1
- package/registry/stepper.json +75 -4
- package/registry/swipeable-row.json +124 -0
- package/registry/switch.json +116 -4
- package/registry/tab-bar.json +115 -0
- package/registry/tabs.json +96 -6
- package/registry/tag-input.json +1 -1
- package/registry/terminal-replay.json +1 -1
- package/registry/theme.json +8 -1
- package/registry/toast.json +17 -3
- package/registry/toc.json +1 -1
- package/registry/tooltip.json +1 -1
- package/registry/tree-view.json +291 -0
- package/registry/video-player.json +1 -1
- package/registry/video-trimmer.json +1 -1
- package/registry/virtual.json +1 -1
- package/skills/choice-controls/SKILL.md +39 -0
- package/skills/form/SKILL.md +3 -0
- package/skills/map/SKILL.md +35 -0
- package/dist/chunk-I5RVM5CW.js.map +0 -1
- package/dist/chunk-RUPRYJ45.js +0 -82
- package/dist/chunk-RUPRYJ45.js.map +0 -1
package/dist/native.js
CHANGED
|
@@ -151,10 +151,24 @@ function monthGrid(month, weekStartsOn) {
|
|
|
151
151
|
return Array.from({ length: 6 }, (_, w) => days.slice(w * 7, w * 7 + 7)).filter((week, w) => w < 5 || week[0].slice(0, 7) === first.slice(0, 7));
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
// src/native/
|
|
155
|
-
import
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
// src/native/action-sheet.tsx
|
|
155
|
+
import { Modal, Pressable, StyleSheet as StyleSheet2, View } from "react-native";
|
|
156
|
+
|
|
157
|
+
// src/native/overlay.tsx
|
|
158
|
+
import * as React from "react";
|
|
159
|
+
var modalName = (label) => ({ "aria-label": label });
|
|
160
|
+
function useOpen({ open, defaultOpen = false, onOpenChange }) {
|
|
161
|
+
const [own, setOwn] = React.useState(defaultOpen);
|
|
162
|
+
const value = open ?? own;
|
|
163
|
+
const set = React.useCallback(
|
|
164
|
+
(next) => {
|
|
165
|
+
if (open === void 0) setOwn(next);
|
|
166
|
+
onOpenChange?.(next);
|
|
167
|
+
},
|
|
168
|
+
[open, onOpenChange]
|
|
169
|
+
);
|
|
170
|
+
return [value, set];
|
|
171
|
+
}
|
|
158
172
|
|
|
159
173
|
// ../tokens/dist/native.js
|
|
160
174
|
var themes = /* @__PURE__ */ Object.freeze({ dark: /* @__PURE__ */ Object.freeze({
|
|
@@ -314,24 +328,25 @@ var marks = /* @__PURE__ */ Object.freeze({
|
|
|
314
328
|
});
|
|
315
329
|
|
|
316
330
|
// src/native/theme.tsx
|
|
317
|
-
import * as
|
|
331
|
+
import * as React2 from "react";
|
|
318
332
|
import { AccessibilityInfo, useColorScheme } from "react-native";
|
|
319
333
|
import { jsx } from "react/jsx-runtime";
|
|
320
334
|
var themes2 = themes;
|
|
321
335
|
var radius2 = radius;
|
|
322
336
|
var motion2 = motion;
|
|
323
337
|
var stillMotion = { ...motion2, duration: { instant: 0, fast: 0, base: 0 } };
|
|
324
|
-
var
|
|
338
|
+
var NO_INSETS = { top: 0, right: 0, bottom: 0, left: 0 };
|
|
339
|
+
var ThemeContext = React2.createContext(null);
|
|
325
340
|
var noop = () => void 0;
|
|
326
341
|
function resolve(mode, system) {
|
|
327
342
|
if (mode === "system") return system === "light" ? "light" : "dark";
|
|
328
343
|
return mode;
|
|
329
344
|
}
|
|
330
|
-
function ThemeProvider({ children, mode: controlled, defaultMode = "system", onModeChange, overrides, fonts, haptics }) {
|
|
345
|
+
function ThemeProvider({ children, mode: controlled, defaultMode = "system", onModeChange, overrides, fonts, haptics, insets }) {
|
|
331
346
|
const system = useColorScheme();
|
|
332
|
-
const [own, setOwn] =
|
|
347
|
+
const [own, setOwn] = React2.useState(defaultMode);
|
|
333
348
|
const mode = controlled ?? own;
|
|
334
|
-
const setMode =
|
|
349
|
+
const setMode = React2.useCallback(
|
|
335
350
|
(next) => {
|
|
336
351
|
if (controlled === void 0) setOwn(next);
|
|
337
352
|
onModeChange?.(next);
|
|
@@ -341,23 +356,23 @@ function ThemeProvider({ children, mode: controlled, defaultMode = "system", onM
|
|
|
341
356
|
const scheme = resolve(mode, system);
|
|
342
357
|
const override = overrides?.[scheme];
|
|
343
358
|
const reduce = useReducedMotion();
|
|
344
|
-
const theme =
|
|
345
|
-
const value =
|
|
346
|
-
() => ({ mode, setMode, scheme, theme, radius: radius2, motion: reduce ? stillMotion : motion2, fonts: fonts ?? {}, haptic: haptics ?? noop }),
|
|
347
|
-
[mode, setMode, scheme, theme, fonts, reduce, haptics]
|
|
359
|
+
const theme = React2.useMemo(() => override ? { ...themes2[scheme], ...override } : themes2[scheme], [scheme, override]);
|
|
360
|
+
const value = React2.useMemo(
|
|
361
|
+
() => ({ mode, setMode, scheme, theme, radius: radius2, motion: reduce ? stillMotion : motion2, fonts: fonts ?? {}, haptic: haptics ?? noop, insets: insets ?? NO_INSETS }),
|
|
362
|
+
[mode, setMode, scheme, theme, fonts, reduce, haptics, insets]
|
|
348
363
|
);
|
|
349
364
|
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
|
|
350
365
|
}
|
|
351
366
|
function useTheme() {
|
|
352
|
-
const context =
|
|
367
|
+
const context = React2.useContext(ThemeContext);
|
|
353
368
|
const system = useColorScheme();
|
|
354
369
|
if (context) return context;
|
|
355
370
|
const scheme = resolve("system", system);
|
|
356
|
-
return { mode: "system", setMode: noop, scheme, theme: themes2[scheme], radius: radius2, motion: motion2, fonts: {}, haptic: noop };
|
|
371
|
+
return { mode: "system", setMode: noop, scheme, theme: themes2[scheme], radius: radius2, motion: motion2, fonts: {}, haptic: noop, insets: NO_INSETS };
|
|
357
372
|
}
|
|
358
373
|
function useReducedMotion() {
|
|
359
|
-
const [reduce, setReduce] =
|
|
360
|
-
|
|
374
|
+
const [reduce, setReduce] = React2.useState(false);
|
|
375
|
+
React2.useEffect(() => {
|
|
361
376
|
let alive = true;
|
|
362
377
|
void AccessibilityInfo.isReduceMotionEnabled().then((value) => {
|
|
363
378
|
if (alive) setReduce(value);
|
|
@@ -377,77 +392,304 @@ function alpha(color, opacity) {
|
|
|
377
392
|
return `rgba(${r},${g},${b},${opacity})`;
|
|
378
393
|
}
|
|
379
394
|
function useSvgId(prefix) {
|
|
380
|
-
return `${prefix}${
|
|
395
|
+
return `${prefix}${React2.useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// src/native/txt.tsx
|
|
399
|
+
import { StyleSheet, Text } from "react-native";
|
|
400
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
401
|
+
var TONE = {
|
|
402
|
+
text: "textPrimary",
|
|
403
|
+
secondary: "textSecondary",
|
|
404
|
+
muted: "textMuted",
|
|
405
|
+
accent: "accentText",
|
|
406
|
+
success: "successText",
|
|
407
|
+
warning: "warningText",
|
|
408
|
+
danger: "dangerText",
|
|
409
|
+
onAccent: "onAccent",
|
|
410
|
+
onMedia: "textOnMedia"
|
|
411
|
+
};
|
|
412
|
+
function Txt({ variant = "body", tone: tone3 = "text", style, ...props }) {
|
|
413
|
+
const { theme, fonts } = useTheme();
|
|
414
|
+
const family = variant === "display" || variant === "title" ? fonts.display : variant === "mono" ? fonts.mono : fonts.sans;
|
|
415
|
+
return /* @__PURE__ */ jsx2(
|
|
416
|
+
Text,
|
|
417
|
+
{
|
|
418
|
+
role: variant === "display" || variant === "title" ? "heading" : void 0,
|
|
419
|
+
...props,
|
|
420
|
+
style: [styles[variant], { color: theme[TONE[tone3]] }, family ? { fontFamily: family } : null, style]
|
|
421
|
+
}
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
var textStyles = StyleSheet.create({
|
|
425
|
+
display: { fontSize: 30, lineHeight: 36, fontWeight: "900", letterSpacing: -0.5 },
|
|
426
|
+
title: { fontSize: 18, lineHeight: 24, fontWeight: "800" },
|
|
427
|
+
body: { fontSize: 15, lineHeight: 21 },
|
|
428
|
+
caption: { fontSize: 12, lineHeight: 16 },
|
|
429
|
+
label: { fontSize: 14, lineHeight: 18, fontWeight: "700" },
|
|
430
|
+
mono: { fontSize: 14, lineHeight: 18, fontWeight: "700", fontVariant: ["tabular-nums"] }
|
|
431
|
+
});
|
|
432
|
+
var styles = textStyles;
|
|
433
|
+
|
|
434
|
+
// src/native/action-sheet.tsx
|
|
435
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
436
|
+
function ActionSheet({ title, description, actions, cancelLabel, ...controlled }) {
|
|
437
|
+
const [open, setOpen] = useOpen(controlled);
|
|
438
|
+
const { theme, radius: radius3, insets, haptic } = useTheme();
|
|
439
|
+
const reduce = useReducedMotion();
|
|
440
|
+
const card = { backgroundColor: theme.glassBg, borderColor: theme.glassBorder, borderTopColor: theme.edgeLight, borderRadius: radius3.xl };
|
|
441
|
+
return /* @__PURE__ */ jsxs(Modal, { ...modalName(title), visible: open, transparent: true, animationType: reduce ? "none" : "slide", onRequestClose: () => setOpen(false), statusBarTranslucent: true, children: [
|
|
442
|
+
/* @__PURE__ */ jsx3(Pressable, { "aria-hidden": true, accessible: false, style: [StyleSheet2.absoluteFill, { backgroundColor: theme.scrim }], onPress: () => setOpen(false) }),
|
|
443
|
+
/* @__PURE__ */ jsxs(View, { style: [styles2.bottom, styles2.actionWrap, { paddingBottom: 8 + insets.bottom }], pointerEvents: "box-none", children: [
|
|
444
|
+
/* @__PURE__ */ jsxs(View, { role: "menu", "aria-label": title, style: [styles2.actionCard, card], children: [
|
|
445
|
+
/* @__PURE__ */ jsxs(View, { style: styles2.actionHead, children: [
|
|
446
|
+
/* @__PURE__ */ jsx3(Txt, { variant: "caption", tone: "secondary", style: styles2.centred, children: title }),
|
|
447
|
+
description ? /* @__PURE__ */ jsx3(Txt, { variant: "caption", tone: "muted", style: styles2.centred, children: description }) : null
|
|
448
|
+
] }),
|
|
449
|
+
actions.map((action, i) => /* @__PURE__ */ jsxs(
|
|
450
|
+
Pressable,
|
|
451
|
+
{
|
|
452
|
+
role: "menuitem",
|
|
453
|
+
"aria-disabled": action.disabled,
|
|
454
|
+
disabled: action.disabled,
|
|
455
|
+
onPress: () => {
|
|
456
|
+
haptic("selection");
|
|
457
|
+
setOpen(false);
|
|
458
|
+
action.onPress();
|
|
459
|
+
},
|
|
460
|
+
style: ({ pressed }) => [styles2.action, { borderTopColor: theme.borderSubtle, backgroundColor: pressed ? theme.surface2 : "transparent", opacity: action.disabled ? 0.4 : 1 }],
|
|
461
|
+
children: [
|
|
462
|
+
action.icon ? /* @__PURE__ */ jsx3(View, { "aria-hidden": true, children: action.icon }) : null,
|
|
463
|
+
/* @__PURE__ */ jsx3(Txt, { variant: "label", tone: action.destructive ? "danger" : "text", children: action.label })
|
|
464
|
+
]
|
|
465
|
+
},
|
|
466
|
+
i
|
|
467
|
+
))
|
|
468
|
+
] }),
|
|
469
|
+
/* @__PURE__ */ jsx3(Pressable, { role: "button", onPress: () => setOpen(false), style: ({ pressed }) => [styles2.cancel, card, { backgroundColor: pressed ? theme.surface2 : theme.surface1 }], children: /* @__PURE__ */ jsx3(Txt, { variant: "label", children: cancelLabel }) })
|
|
470
|
+
] })
|
|
471
|
+
] });
|
|
472
|
+
}
|
|
473
|
+
var styles2 = StyleSheet2.create({
|
|
474
|
+
bottom: { flex: 1, justifyContent: "flex-end" },
|
|
475
|
+
actionWrap: { paddingHorizontal: 8, gap: 8 },
|
|
476
|
+
actionCard: { borderWidth: StyleSheet2.hairlineWidth, overflow: "hidden" },
|
|
477
|
+
actionHead: { paddingVertical: 12, paddingHorizontal: 16, gap: 2 },
|
|
478
|
+
centred: { textAlign: "center" },
|
|
479
|
+
action: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 10, minHeight: 52, paddingHorizontal: 16, borderTopWidth: StyleSheet2.hairlineWidth },
|
|
480
|
+
cancel: { minHeight: 52, alignItems: "center", justifyContent: "center", borderWidth: StyleSheet2.hairlineWidth }
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
// src/native/activity-feed.tsx
|
|
484
|
+
import * as React3 from "react";
|
|
485
|
+
import { AccessibilityInfo as AccessibilityInfo2, SectionList, StyleSheet as StyleSheet3, View as View2 } from "react-native";
|
|
486
|
+
|
|
487
|
+
// src/activity-feed/group.ts
|
|
488
|
+
var dayKey = (date) => `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
|
|
489
|
+
function groupActivity(events, { now = /* @__PURE__ */ new Date(), locale = "en-US", today = "Today", yesterday = "Yesterday", fold = true } = {}) {
|
|
490
|
+
const sorted = [...events].sort((a, b) => new Date(b.at).getTime() - new Date(a.at).getTime());
|
|
491
|
+
const day = new Intl.DateTimeFormat(locale, { weekday: "long", month: "short", day: "numeric" });
|
|
492
|
+
const todayKey = dayKey(now);
|
|
493
|
+
const yesterdayKey = dayKey(new Date(now.getTime() - 864e5));
|
|
494
|
+
const groups = [];
|
|
495
|
+
let current = null;
|
|
496
|
+
let currentKey = "";
|
|
497
|
+
for (const event of sorted) {
|
|
498
|
+
const date = new Date(event.at);
|
|
499
|
+
const key = dayKey(date);
|
|
500
|
+
if (!current || key !== currentKey) {
|
|
501
|
+
currentKey = key;
|
|
502
|
+
current = { label: key === todayKey ? today : key === yesterdayKey ? yesterday : day.format(date), events: [] };
|
|
503
|
+
groups.push(current);
|
|
504
|
+
}
|
|
505
|
+
const last = current.events[current.events.length - 1];
|
|
506
|
+
if (fold && last && event.actor && event.kind && last.event.actor === event.actor && last.event.kind === event.kind) last.count += 1;
|
|
507
|
+
else current.events.push({ event, count: 1 });
|
|
508
|
+
}
|
|
509
|
+
return groups;
|
|
510
|
+
}
|
|
511
|
+
var UNITS = [
|
|
512
|
+
["second", 60],
|
|
513
|
+
["minute", 60],
|
|
514
|
+
["hour", 24],
|
|
515
|
+
["day", 7],
|
|
516
|
+
["week", 4.35],
|
|
517
|
+
["month", 12],
|
|
518
|
+
["year", Number.POSITIVE_INFINITY]
|
|
519
|
+
];
|
|
520
|
+
function timeAgo(at, { now = /* @__PURE__ */ new Date(), locale = "en-US", style = "short" } = {}) {
|
|
521
|
+
let value = (new Date(at).getTime() - now.getTime()) / 1e3;
|
|
522
|
+
let unit = "second";
|
|
523
|
+
for (const [name, size] of UNITS) {
|
|
524
|
+
unit = name;
|
|
525
|
+
if (Math.abs(value) < size - 0.5) break;
|
|
526
|
+
value /= size;
|
|
527
|
+
}
|
|
528
|
+
return new Intl.RelativeTimeFormat(locale, { numeric: "auto", style }).format(Math.round(value) + 0, unit);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// src/native/activity-feed.tsx
|
|
532
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
533
|
+
var LABELS = { today: "Today", yesterday: "Yesterday", times: (n) => `\xD7${n}`, newEvents: (n) => n === 1 ? "1 new event" : `${n} new events` };
|
|
534
|
+
var tone = (t, name) => ({ neutral: t.borderStrong, accent: t.accent, success: t.success, warning: t.warning, danger: t.danger, info: t.info })[name ?? "neutral"];
|
|
535
|
+
function ActivityFeed({ events, "aria-label": label, locale = "en-US", now: given, fold = true, live, leading, empty, labels: words, style }) {
|
|
536
|
+
const { theme } = useTheme();
|
|
537
|
+
const labels = { ...LABELS, ...words };
|
|
538
|
+
const [tick, setTick] = React3.useState(() => given ?? /* @__PURE__ */ new Date());
|
|
539
|
+
React3.useEffect(() => {
|
|
540
|
+
if (given) return;
|
|
541
|
+
const timer2 = setInterval(() => setTick(/* @__PURE__ */ new Date()), 6e4);
|
|
542
|
+
return () => clearInterval(timer2);
|
|
543
|
+
}, [given]);
|
|
544
|
+
const now = given ?? tick;
|
|
545
|
+
const seen = React3.useRef(events.length);
|
|
546
|
+
React3.useEffect(() => {
|
|
547
|
+
const added = events.length - seen.current;
|
|
548
|
+
seen.current = events.length;
|
|
549
|
+
if (live && added > 0) AccessibilityInfo2.announceForAccessibility(labels.newEvents(added));
|
|
550
|
+
}, [events.length, live]);
|
|
551
|
+
const sections = groupActivity(events, { now, locale, today: labels.today, yesterday: labels.yesterday, fold }).map((g) => ({ title: g.label, data: g.events }));
|
|
552
|
+
return /* @__PURE__ */ jsx4(
|
|
553
|
+
SectionList,
|
|
554
|
+
{
|
|
555
|
+
"aria-label": label,
|
|
556
|
+
style,
|
|
557
|
+
sections,
|
|
558
|
+
keyExtractor: (item) => item.event.id,
|
|
559
|
+
stickySectionHeadersEnabled: true,
|
|
560
|
+
ListEmptyComponent: empty ? /* @__PURE__ */ jsx4(Fragment, { children: empty }) : null,
|
|
561
|
+
renderSectionHeader: ({ section }) => /* @__PURE__ */ jsx4(View2, { style: [styles3.heading, { backgroundColor: theme.surface0 }], children: /* @__PURE__ */ jsx4(Txt, { variant: "caption", tone: "secondary", role: "heading", style: styles3.headingText, children: section.title }) }),
|
|
562
|
+
renderItem: ({ item: { event, count } }) => /* @__PURE__ */ jsxs2(View2, { style: styles3.row, accessible: true, children: [
|
|
563
|
+
leading ? leading(event) : /* @__PURE__ */ jsx4(View2, { "aria-hidden": true, style: [styles3.marker, { backgroundColor: tone(theme, event.tone) }] }),
|
|
564
|
+
/* @__PURE__ */ jsxs2(View2, { style: styles3.body, children: [
|
|
565
|
+
/* @__PURE__ */ jsxs2(Txt, { children: [
|
|
566
|
+
event.title,
|
|
567
|
+
count > 1 ? /* @__PURE__ */ jsx4(Txt, { variant: "caption", tone: "secondary", children: ` ${labels.times(count)}` }) : null
|
|
568
|
+
] }),
|
|
569
|
+
event.description ? /* @__PURE__ */ jsx4(Txt, { variant: "caption", tone: "secondary", children: event.description }) : null
|
|
570
|
+
] }),
|
|
571
|
+
/* @__PURE__ */ jsx4(Txt, { variant: "caption", tone: "secondary", children: timeAgo(event.at, { now, locale }) })
|
|
572
|
+
] })
|
|
573
|
+
}
|
|
574
|
+
);
|
|
381
575
|
}
|
|
576
|
+
var styles3 = StyleSheet3.create({
|
|
577
|
+
heading: { paddingVertical: 6 },
|
|
578
|
+
headingText: { fontWeight: "700", textTransform: "uppercase", letterSpacing: 0.6 },
|
|
579
|
+
row: { flexDirection: "row", alignItems: "flex-start", gap: 12, paddingVertical: 10 },
|
|
580
|
+
marker: { width: 10, height: 10, borderRadius: 5, marginTop: 5 },
|
|
581
|
+
body: { flex: 1, gap: 2 }
|
|
582
|
+
});
|
|
382
583
|
|
|
383
584
|
// src/native/avatar.tsx
|
|
384
|
-
import
|
|
585
|
+
import * as React4 from "react";
|
|
586
|
+
import { Image, StyleSheet as StyleSheet4, Text as Text2, View as View3 } from "react-native";
|
|
587
|
+
import Svg, { Circle, Defs, LinearGradient, Stop, SvgUri } from "react-native-svg";
|
|
588
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
385
589
|
var SIDE = { xs: 20, sm: 32, md: 40, lg: 56, xl: 80 };
|
|
386
590
|
function isSvgUri(uri) {
|
|
387
591
|
return /^data:image\/svg\+xml[;,]/i.test(uri) || /\.svg(?:[?#]|$)/i.test(uri);
|
|
388
592
|
}
|
|
389
|
-
function AvatarRoot({ src, svg, alt = "", fallback, size = "md", style, ...props }) {
|
|
593
|
+
function AvatarRoot({ src, svg, alt = "", fallback, size = "md", presence, presenceLabel, ring, style, ...props }) {
|
|
390
594
|
const { theme } = useTheme();
|
|
391
|
-
const
|
|
595
|
+
const gradient = useSvgId("kz-ring-");
|
|
596
|
+
const [failedSrc, setFailedSrc] = React4.useState(null);
|
|
392
597
|
const failed = Boolean(src) && failedSrc === src;
|
|
393
598
|
const side = typeof size === "number" ? size : SIDE[size];
|
|
394
599
|
const initial = alt.trim().charAt(0).toUpperCase();
|
|
395
600
|
const content = fallback ?? initial;
|
|
396
|
-
|
|
397
|
-
|
|
601
|
+
const picture = /* @__PURE__ */ jsx5(
|
|
602
|
+
View3,
|
|
398
603
|
{
|
|
399
|
-
accessible: Boolean(alt),
|
|
400
|
-
role: alt ? "img" : void 0,
|
|
401
|
-
"aria-label": alt
|
|
402
|
-
...props,
|
|
403
|
-
style: [
|
|
404
|
-
children: src && !failed && (svg || isSvgUri(src)) ? /* @__PURE__ */
|
|
604
|
+
accessible: Boolean(alt) && !presence && !ring,
|
|
605
|
+
role: alt && !presence && !ring ? "img" : void 0,
|
|
606
|
+
"aria-label": alt && !presence && !ring ? alt : void 0,
|
|
607
|
+
...presence || ring ? {} : props,
|
|
608
|
+
style: [styles4.root, { width: side, height: side, borderRadius: side / 2, backgroundColor: theme.surface3 }, presence || ring ? null : style],
|
|
609
|
+
children: src && !failed && (svg || isSvgUri(src)) ? /* @__PURE__ */ jsx5(View3, { style: StyleSheet4.absoluteFill, pointerEvents: "none", children: /* @__PURE__ */ jsx5(SvgUri, { testID: props.testID ? `${props.testID}.svg` : void 0, uri: src, width: "100%", height: "100%", preserveAspectRatio: "xMidYMid slice", onError: () => setFailedSrc(src) }) }) : src && !failed ? /* @__PURE__ */ jsx5(Image, { testID: props.testID ? `${props.testID}.image` : void 0, source: { uri: src }, onError: () => setFailedSrc(src), resizeMode: "cover", style: StyleSheet4.absoluteFill }) : typeof content === "string" ? /* @__PURE__ */ jsx5(Text2, { style: [styles4.initial, { color: theme.textSecondary, fontSize: Math.max(9, Math.round(side * 0.4)) }], children: content }) : content
|
|
405
610
|
}
|
|
406
611
|
);
|
|
612
|
+
if (!presence && !ring) return picture;
|
|
613
|
+
const gap = ring ? Math.max(2.5, Math.round(side * 0.07)) : 0;
|
|
614
|
+
const outer = side + gap * 4;
|
|
615
|
+
const dot = Math.max(8, Math.round(side * 0.28));
|
|
616
|
+
const dotColor = presence === "online" ? theme.success : presence === "away" ? theme.warning : presence === "busy" ? theme.danger : theme.surface0;
|
|
617
|
+
const name = [alt, presence ? presenceLabel : null].filter(Boolean).join(", ");
|
|
618
|
+
return /* @__PURE__ */ jsxs3(View3, { accessible: Boolean(name), role: name ? "img" : void 0, "aria-label": name || void 0, ...props, style: [{ width: outer, height: outer, alignItems: "center", justifyContent: "center" }, style], children: [
|
|
619
|
+
ring ? /* @__PURE__ */ jsxs3(Svg, { width: outer, height: outer, style: StyleSheet4.absoluteFill, "aria-hidden": true, children: [
|
|
620
|
+
/* @__PURE__ */ jsx5(Defs, { children: /* @__PURE__ */ jsxs3(LinearGradient, { id: gradient, x1: "0", y1: "1", x2: "1", y2: "0", children: [
|
|
621
|
+
/* @__PURE__ */ jsx5(Stop, { offset: "0", stopColor: theme.accent }),
|
|
622
|
+
/* @__PURE__ */ jsx5(Stop, { offset: "1", stopColor: theme.accent2 })
|
|
623
|
+
] }) }),
|
|
624
|
+
/* @__PURE__ */ jsx5(
|
|
625
|
+
Circle,
|
|
626
|
+
{
|
|
627
|
+
cx: outer / 2,
|
|
628
|
+
cy: outer / 2,
|
|
629
|
+
r: outer / 2 - gap / 2 - 0.5,
|
|
630
|
+
fill: "none",
|
|
631
|
+
strokeWidth: gap,
|
|
632
|
+
stroke: ring === "story" ? `url(#${gradient})` : ring === "live" ? theme.danger : theme.borderStrong
|
|
633
|
+
}
|
|
634
|
+
)
|
|
635
|
+
] }) : null,
|
|
636
|
+
picture,
|
|
637
|
+
presence ? /* @__PURE__ */ jsx5(
|
|
638
|
+
View3,
|
|
639
|
+
{
|
|
640
|
+
"aria-hidden": true,
|
|
641
|
+
style: [
|
|
642
|
+
styles4.dot,
|
|
643
|
+
{ width: dot, height: dot, borderRadius: dot / 2, right: gap * 2, bottom: gap * 2, backgroundColor: dotColor, borderColor: presence === "offline" ? theme.textMuted : theme.surface0 }
|
|
644
|
+
]
|
|
645
|
+
}
|
|
646
|
+
) : null
|
|
647
|
+
] });
|
|
407
648
|
}
|
|
408
649
|
function AvatarGroup({ max, size = "md", style, children, ...props }) {
|
|
409
650
|
const { theme } = useTheme();
|
|
410
|
-
const items2 =
|
|
651
|
+
const items2 = React4.Children.toArray(children);
|
|
411
652
|
const shown = max === void 0 ? items2 : items2.slice(0, max);
|
|
412
653
|
const rest = items2.length - shown.length;
|
|
413
654
|
const side = typeof size === "number" ? size : SIDE[size];
|
|
414
655
|
const ring = { borderWidth: 2, borderColor: theme.surface0, marginLeft: -side / 5 };
|
|
415
|
-
return /* @__PURE__ */
|
|
416
|
-
shown.map((child, i) => /* @__PURE__ */
|
|
417
|
-
rest > 0 ? /* @__PURE__ */
|
|
656
|
+
return /* @__PURE__ */ jsxs3(View3, { ...props, style: [styles4.group, { paddingLeft: side / 5 }, style], children: [
|
|
657
|
+
shown.map((child, i) => /* @__PURE__ */ jsx5(View3, { style: [ring, { borderRadius: side }], children: React4.isValidElement(child) ? React4.cloneElement(child, { size }) : child }, i)),
|
|
658
|
+
rest > 0 ? /* @__PURE__ */ jsx5(View3, { style: [ring, { borderRadius: side }], children: /* @__PURE__ */ jsx5(AvatarRoot, { size, fallback: `+${rest}` }) }) : null
|
|
418
659
|
] });
|
|
419
660
|
}
|
|
420
661
|
var Avatar = Object.assign(AvatarRoot, { Group: AvatarGroup });
|
|
421
|
-
var
|
|
662
|
+
var styles4 = StyleSheet4.create({
|
|
422
663
|
root: { overflow: "hidden", alignItems: "center", justifyContent: "center" },
|
|
423
664
|
initial: { fontWeight: "700" },
|
|
424
|
-
group: { flexDirection: "row", alignItems: "center" }
|
|
665
|
+
group: { flexDirection: "row", alignItems: "center" },
|
|
666
|
+
dot: { position: "absolute", borderWidth: 2 }
|
|
425
667
|
});
|
|
426
668
|
|
|
427
669
|
// src/native/badge.tsx
|
|
428
|
-
import * as
|
|
429
|
-
import { Animated, StyleSheet as
|
|
430
|
-
import { jsx as
|
|
431
|
-
function look(
|
|
432
|
-
switch (
|
|
670
|
+
import * as React5 from "react";
|
|
671
|
+
import { Animated, StyleSheet as StyleSheet5, Text as Text3 } from "react-native";
|
|
672
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
673
|
+
function look(tone3, t) {
|
|
674
|
+
switch (tone3) {
|
|
433
675
|
case "accent":
|
|
434
676
|
return { bg: t.accentSoft, fg: t.textPrimary, border: alpha(t.accent, 0.4), dot: t.accent };
|
|
435
677
|
case "success":
|
|
436
678
|
case "warning":
|
|
437
679
|
case "danger":
|
|
438
|
-
return { bg: alpha(t[
|
|
680
|
+
return { bg: alpha(t[tone3], 0.15), fg: t.textPrimary, border: alpha(t[tone3], 0.4), dot: t[tone3] };
|
|
439
681
|
case "scrim":
|
|
440
682
|
return { bg: t.scrim, fg: t.textOnMedia, border: "transparent", dot: t.textOnMedia };
|
|
441
683
|
default:
|
|
442
684
|
return { bg: t.surface3, fg: t.textSecondary, border: "transparent", dot: t.textSecondary };
|
|
443
685
|
}
|
|
444
686
|
}
|
|
445
|
-
function Badge({ tone:
|
|
687
|
+
function Badge({ tone: tone3 = "neutral", size = "sm", dot, pulse, style, children, ...props }) {
|
|
446
688
|
const { theme } = useTheme();
|
|
447
|
-
const colors = look(
|
|
689
|
+
const colors = look(tone3, theme);
|
|
448
690
|
const reduce = useReducedMotion();
|
|
449
|
-
const [opacity] =
|
|
450
|
-
|
|
691
|
+
const [opacity] = React5.useState(() => new Animated.Value(1));
|
|
692
|
+
React5.useEffect(() => {
|
|
451
693
|
if (!dot || !pulse || reduce) return;
|
|
452
694
|
const loop = Animated.loop(
|
|
453
695
|
Animated.sequence([
|
|
@@ -461,19 +703,19 @@ function Badge({ tone: tone2 = "neutral", size = "sm", dot, pulse, style, childr
|
|
|
461
703
|
opacity.setValue(1);
|
|
462
704
|
};
|
|
463
705
|
}, [dot, pulse, reduce, opacity]);
|
|
464
|
-
return /* @__PURE__ */
|
|
706
|
+
return /* @__PURE__ */ jsxs4(
|
|
465
707
|
Animated.View,
|
|
466
708
|
{
|
|
467
709
|
...props,
|
|
468
|
-
style: [
|
|
710
|
+
style: [styles5.root, size === "md" ? styles5.md : styles5.sm, { backgroundColor: colors.bg, borderColor: colors.border }, style],
|
|
469
711
|
children: [
|
|
470
|
-
dot ? /* @__PURE__ */
|
|
471
|
-
typeof children === "string" || typeof children === "number" ? /* @__PURE__ */
|
|
712
|
+
dot ? /* @__PURE__ */ jsx6(Animated.View, { "aria-hidden": true, style: [styles5.dot, { backgroundColor: colors.dot, opacity }] }) : null,
|
|
713
|
+
typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx6(Text3, { style: [styles5.text, { color: colors.fg, fontSize: size === "md" ? 11 : 10 }], children }) : children
|
|
472
714
|
]
|
|
473
715
|
}
|
|
474
716
|
);
|
|
475
717
|
}
|
|
476
|
-
var
|
|
718
|
+
var styles5 = StyleSheet5.create({
|
|
477
719
|
root: { flexDirection: "row", alignItems: "center", alignSelf: "flex-start", gap: 4, borderRadius: 9999, borderWidth: 1 },
|
|
478
720
|
sm: { paddingHorizontal: 8, paddingVertical: 2 },
|
|
479
721
|
md: { paddingHorizontal: 10, paddingVertical: 4 },
|
|
@@ -482,48 +724,10 @@ var styles2 = StyleSheet2.create({
|
|
|
482
724
|
});
|
|
483
725
|
|
|
484
726
|
// src/native/button.tsx
|
|
485
|
-
import * as
|
|
486
|
-
import { ActivityIndicator, Pressable, StyleSheet as
|
|
487
|
-
import
|
|
488
|
-
|
|
489
|
-
// src/native/txt.tsx
|
|
490
|
-
import { StyleSheet as StyleSheet3, Text as Text3 } from "react-native";
|
|
491
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
492
|
-
var TONE = {
|
|
493
|
-
text: "textPrimary",
|
|
494
|
-
secondary: "textSecondary",
|
|
495
|
-
muted: "textMuted",
|
|
496
|
-
accent: "accentText",
|
|
497
|
-
success: "successText",
|
|
498
|
-
warning: "warningText",
|
|
499
|
-
danger: "dangerText",
|
|
500
|
-
onAccent: "onAccent",
|
|
501
|
-
onMedia: "textOnMedia"
|
|
502
|
-
};
|
|
503
|
-
function Txt({ variant = "body", tone: tone2 = "text", style, ...props }) {
|
|
504
|
-
const { theme, fonts } = useTheme();
|
|
505
|
-
const family = variant === "display" || variant === "title" ? fonts.display : variant === "mono" ? fonts.mono : fonts.sans;
|
|
506
|
-
return /* @__PURE__ */ jsx4(
|
|
507
|
-
Text3,
|
|
508
|
-
{
|
|
509
|
-
role: variant === "display" || variant === "title" ? "heading" : void 0,
|
|
510
|
-
...props,
|
|
511
|
-
style: [styles3[variant], { color: theme[TONE[tone2]] }, family ? { fontFamily: family } : null, style]
|
|
512
|
-
}
|
|
513
|
-
);
|
|
514
|
-
}
|
|
515
|
-
var textStyles = StyleSheet3.create({
|
|
516
|
-
display: { fontSize: 30, lineHeight: 36, fontWeight: "900", letterSpacing: -0.5 },
|
|
517
|
-
title: { fontSize: 18, lineHeight: 24, fontWeight: "800" },
|
|
518
|
-
body: { fontSize: 15, lineHeight: 21 },
|
|
519
|
-
caption: { fontSize: 12, lineHeight: 16 },
|
|
520
|
-
label: { fontSize: 14, lineHeight: 18, fontWeight: "700" },
|
|
521
|
-
mono: { fontSize: 14, lineHeight: 18, fontWeight: "700", fontVariant: ["tabular-nums"] }
|
|
522
|
-
});
|
|
523
|
-
var styles3 = textStyles;
|
|
524
|
-
|
|
525
|
-
// src/native/button.tsx
|
|
526
|
-
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
727
|
+
import * as React6 from "react";
|
|
728
|
+
import { ActivityIndicator, Pressable as Pressable2, StyleSheet as StyleSheet6, View as View4 } from "react-native";
|
|
729
|
+
import Svg2, { Defs as Defs2, LinearGradient as LinearGradient2, Rect, Stop as Stop2 } from "react-native-svg";
|
|
730
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
527
731
|
function look2(variant, t) {
|
|
528
732
|
switch (variant) {
|
|
529
733
|
case "primary":
|
|
@@ -558,19 +762,19 @@ function useButton({ variant = "secondary", size = "md", shape = "rounded", load
|
|
|
558
762
|
}
|
|
559
763
|
function Fill({ colors, id }) {
|
|
560
764
|
if (!colors.gradient) return null;
|
|
561
|
-
return /* @__PURE__ */
|
|
562
|
-
/* @__PURE__ */
|
|
563
|
-
/* @__PURE__ */
|
|
564
|
-
/* @__PURE__ */
|
|
765
|
+
return /* @__PURE__ */ jsxs5(Svg2, { "aria-hidden": true, pointerEvents: "none", style: StyleSheet6.absoluteFill, width: "100%", height: "100%", children: [
|
|
766
|
+
/* @__PURE__ */ jsx7(Defs2, { children: /* @__PURE__ */ jsxs5(LinearGradient2, { id, x1: "0", y1: "0", x2: "1", y2: "0", children: [
|
|
767
|
+
/* @__PURE__ */ jsx7(Stop2, { offset: "0", stopColor: colors.gradient[0] }),
|
|
768
|
+
/* @__PURE__ */ jsx7(Stop2, { offset: "1", stopColor: colors.gradient[1] })
|
|
565
769
|
] }) }),
|
|
566
|
-
/* @__PURE__ */
|
|
770
|
+
/* @__PURE__ */ jsx7(Rect, { width: "100%", height: "100%", fill: `url(#${id})` })
|
|
567
771
|
] });
|
|
568
772
|
}
|
|
569
773
|
function Button({ label, icon, variant, size = "md", shape, loading = false, disabled, style, ...props }) {
|
|
570
774
|
const { colors, inactive, frame } = useButton({ variant, size, shape, loading, disabled });
|
|
571
|
-
const gradientId = `kz-button-${
|
|
572
|
-
return /* @__PURE__ */
|
|
573
|
-
|
|
775
|
+
const gradientId = `kz-button-${React6.useId().replace(/:/g, "")}`;
|
|
776
|
+
return /* @__PURE__ */ jsxs5(
|
|
777
|
+
Pressable2,
|
|
574
778
|
{
|
|
575
779
|
role: "button",
|
|
576
780
|
"aria-label": label,
|
|
@@ -578,12 +782,12 @@ function Button({ label, icon, variant, size = "md", shape, loading = false, dis
|
|
|
578
782
|
"aria-busy": loading,
|
|
579
783
|
...props,
|
|
580
784
|
disabled: inactive,
|
|
581
|
-
style: ({ pressed }) => [
|
|
785
|
+
style: ({ pressed }) => [styles6.base, { paddingHorizontal: PADDING[size] }, frame(pressed), style],
|
|
582
786
|
children: [
|
|
583
|
-
/* @__PURE__ */
|
|
584
|
-
/* @__PURE__ */
|
|
585
|
-
loading ? /* @__PURE__ */
|
|
586
|
-
/* @__PURE__ */
|
|
787
|
+
/* @__PURE__ */ jsx7(Fill, { colors, id: gradientId }),
|
|
788
|
+
/* @__PURE__ */ jsxs5(View4, { style: styles6.row, children: [
|
|
789
|
+
loading ? /* @__PURE__ */ jsx7(ActivityIndicator, { "aria-hidden": true, size: "small", color: colors.fg }) : icon,
|
|
790
|
+
/* @__PURE__ */ jsx7(Txt, { variant: "label", numberOfLines: 1, style: { color: colors.fg, fontSize: size === "sm" ? 12 : 14 }, children: label })
|
|
587
791
|
] })
|
|
588
792
|
]
|
|
589
793
|
}
|
|
@@ -591,10 +795,10 @@ function Button({ label, icon, variant, size = "md", shape, loading = false, dis
|
|
|
591
795
|
}
|
|
592
796
|
function IconButton({ label, icon, variant, size = "md", shape, loading = false, disabled, style, ...props }) {
|
|
593
797
|
const { colors, inactive, frame } = useButton({ variant, size, shape, loading, disabled });
|
|
594
|
-
const gradientId = `kz-button-${
|
|
798
|
+
const gradientId = `kz-button-${React6.useId().replace(/:/g, "")}`;
|
|
595
799
|
const side = HEIGHT[size];
|
|
596
|
-
return /* @__PURE__ */
|
|
597
|
-
|
|
800
|
+
return /* @__PURE__ */ jsxs5(
|
|
801
|
+
Pressable2,
|
|
598
802
|
{
|
|
599
803
|
role: "button",
|
|
600
804
|
"aria-label": label,
|
|
@@ -603,36 +807,36 @@ function IconButton({ label, icon, variant, size = "md", shape, loading = false,
|
|
|
603
807
|
hitSlop: side < 44 ? (44 - side) / 2 : void 0,
|
|
604
808
|
...props,
|
|
605
809
|
disabled: inactive,
|
|
606
|
-
style: ({ pressed }) => [
|
|
810
|
+
style: ({ pressed }) => [styles6.base, frame(pressed), { width: side }, style],
|
|
607
811
|
children: [
|
|
608
|
-
/* @__PURE__ */
|
|
609
|
-
loading ? /* @__PURE__ */
|
|
812
|
+
/* @__PURE__ */ jsx7(Fill, { colors, id: gradientId }),
|
|
813
|
+
loading ? /* @__PURE__ */ jsx7(ActivityIndicator, { "aria-hidden": true, size: "small", color: colors.fg }) : icon
|
|
610
814
|
]
|
|
611
815
|
}
|
|
612
816
|
);
|
|
613
817
|
}
|
|
614
|
-
var
|
|
818
|
+
var styles6 = StyleSheet6.create({
|
|
615
819
|
base: { alignItems: "center", justifyContent: "center", borderWidth: 1, overflow: "hidden" },
|
|
616
820
|
row: { flexDirection: "row", alignItems: "center", gap: 8 }
|
|
617
821
|
});
|
|
618
822
|
|
|
619
823
|
// src/native/card.tsx
|
|
620
|
-
import { Image as Image2, Pressable as
|
|
621
|
-
import { jsx as
|
|
622
|
-
function CardRoot({ tone:
|
|
824
|
+
import { Image as Image2, Pressable as Pressable3, StyleSheet as StyleSheet7, View as View5 } from "react-native";
|
|
825
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
826
|
+
function CardRoot({ tone: tone3 = "default", radius: radius3 = "xl", onPress, style, ...props }) {
|
|
623
827
|
const { theme, radius: r } = useTheme();
|
|
624
828
|
const frame = [
|
|
625
|
-
|
|
829
|
+
styles7.root,
|
|
626
830
|
{
|
|
627
|
-
backgroundColor:
|
|
831
|
+
backgroundColor: tone3 === "elevated" ? theme.surface2 : theme.surface1,
|
|
628
832
|
borderColor: theme.borderDefault,
|
|
629
833
|
borderRadius: r[radius3]
|
|
630
834
|
},
|
|
631
|
-
|
|
835
|
+
tone3 === "elevated" ? [styles7.shadow, { shadowColor: theme.scrimStrong }] : null
|
|
632
836
|
];
|
|
633
|
-
if (!onPress) return /* @__PURE__ */
|
|
634
|
-
return /* @__PURE__ */
|
|
635
|
-
|
|
837
|
+
if (!onPress) return /* @__PURE__ */ jsx8(View5, { ...props, style: [frame, style] });
|
|
838
|
+
return /* @__PURE__ */ jsx8(
|
|
839
|
+
Pressable3,
|
|
636
840
|
{
|
|
637
841
|
role: "button",
|
|
638
842
|
onPress,
|
|
@@ -644,14 +848,14 @@ function CardRoot({ tone: tone2 = "default", radius: radius3 = "xl", onPress, st
|
|
|
644
848
|
var ASPECT = { video: 16 / 9, square: 1, portrait: 3 / 4 };
|
|
645
849
|
function CardMedia({ aspect = "video", style, ...props }) {
|
|
646
850
|
const { theme } = useTheme();
|
|
647
|
-
return /* @__PURE__ */
|
|
851
|
+
return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.media, { backgroundColor: theme.media }, aspect === "auto" ? null : { aspectRatio: ASPECT[aspect] }, style] });
|
|
648
852
|
}
|
|
649
853
|
function CardImage({ src, fallback, alt, style, ...props }) {
|
|
650
854
|
const { theme } = useTheme();
|
|
651
855
|
if (!src) {
|
|
652
|
-
return /* @__PURE__ */
|
|
856
|
+
return /* @__PURE__ */ jsx8(View5, { "aria-hidden": true, style: [StyleSheet7.absoluteFill, styles7.center, { backgroundColor: theme.accentSoft }], children: fallback });
|
|
653
857
|
}
|
|
654
|
-
return /* @__PURE__ */
|
|
858
|
+
return /* @__PURE__ */ jsx8(Image2, { accessible: Boolean(alt), alt, "aria-label": alt, resizeMode: "cover", ...props, source: { uri: src }, style: [StyleSheet7.absoluteFill, style] });
|
|
655
859
|
}
|
|
656
860
|
var CORNER = {
|
|
657
861
|
"top-left": { top: 10, left: 10 },
|
|
@@ -660,21 +864,21 @@ var CORNER = {
|
|
|
660
864
|
"bottom-right": { bottom: 10, right: 10 }
|
|
661
865
|
};
|
|
662
866
|
function CardOverlay({ corner = "top-left", style, ...props }) {
|
|
663
|
-
return /* @__PURE__ */
|
|
867
|
+
return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.overlay, CORNER[corner], style] });
|
|
664
868
|
}
|
|
665
869
|
var PADDING2 = { none: 0, sm: 12, md: 16, lg: 24 };
|
|
666
870
|
function CardBody({ padding = "md", style, ...props }) {
|
|
667
|
-
return /* @__PURE__ */
|
|
871
|
+
return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.body, { padding: PADDING2[padding] }, style] });
|
|
668
872
|
}
|
|
669
873
|
function CardTitle({ numberOfLines = 1, ...props }) {
|
|
670
|
-
return /* @__PURE__ */
|
|
874
|
+
return /* @__PURE__ */ jsx8(Txt, { variant: "label", role: "heading", numberOfLines, ...props });
|
|
671
875
|
}
|
|
672
876
|
function CardDescription({ numberOfLines = 2, ...props }) {
|
|
673
|
-
return /* @__PURE__ */
|
|
877
|
+
return /* @__PURE__ */ jsx8(Txt, { variant: "caption", tone: "secondary", numberOfLines, ...props });
|
|
674
878
|
}
|
|
675
879
|
function CardFooter({ style, ...props }) {
|
|
676
880
|
const { theme } = useTheme();
|
|
677
|
-
return /* @__PURE__ */
|
|
881
|
+
return /* @__PURE__ */ jsx8(View5, { ...props, style: [styles7.footer, { borderTopColor: theme.borderSubtle }, style] });
|
|
678
882
|
}
|
|
679
883
|
var Card = {
|
|
680
884
|
Root: CardRoot,
|
|
@@ -686,37 +890,37 @@ var Card = {
|
|
|
686
890
|
Description: CardDescription,
|
|
687
891
|
Footer: CardFooter
|
|
688
892
|
};
|
|
689
|
-
var
|
|
690
|
-
root: { overflow: "hidden", borderWidth:
|
|
893
|
+
var styles7 = StyleSheet7.create({
|
|
894
|
+
root: { overflow: "hidden", borderWidth: StyleSheet7.hairlineWidth },
|
|
691
895
|
shadow: { shadowOpacity: 0.25, shadowRadius: 12, shadowOffset: { width: 0, height: 6 }, elevation: 4 },
|
|
692
896
|
media: { position: "relative", overflow: "hidden", width: "100%" },
|
|
693
897
|
center: { alignItems: "center", justifyContent: "center" },
|
|
694
898
|
overlay: { position: "absolute", zIndex: 1, flexDirection: "row", alignItems: "center", gap: 6 },
|
|
695
899
|
body: { gap: 12 },
|
|
696
|
-
footer: { flexDirection: "row", alignItems: "center", gap: 8, borderTopWidth:
|
|
900
|
+
footer: { flexDirection: "row", alignItems: "center", gap: 8, borderTopWidth: StyleSheet7.hairlineWidth, paddingTop: 12, marginTop: "auto" }
|
|
697
901
|
});
|
|
698
902
|
|
|
699
903
|
// src/native/checkbox.tsx
|
|
700
|
-
import * as
|
|
701
|
-
import { Pressable as
|
|
702
|
-
import
|
|
703
|
-
import { jsx as
|
|
904
|
+
import * as React7 from "react";
|
|
905
|
+
import { Pressable as Pressable4, StyleSheet as StyleSheet8, Text as Text4, View as View6 } from "react-native";
|
|
906
|
+
import Svg3, { Path } from "react-native-svg";
|
|
907
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
704
908
|
function Checkbox({ children, label, checked, defaultChecked = false, onCheckedChange, error, disabled, style }) {
|
|
705
909
|
const { theme, radius: radius3 } = useTheme();
|
|
706
|
-
const [own, setOwn] =
|
|
910
|
+
const [own, setOwn] = React7.useState(defaultChecked);
|
|
707
911
|
const on = checked ?? own;
|
|
708
912
|
const toggle = () => {
|
|
709
913
|
if (checked === void 0) setOwn(!on);
|
|
710
914
|
onCheckedChange?.(!on);
|
|
711
915
|
};
|
|
712
|
-
const box = /* @__PURE__ */
|
|
713
|
-
|
|
916
|
+
const box = /* @__PURE__ */ jsx9(
|
|
917
|
+
View6,
|
|
714
918
|
{
|
|
715
919
|
style: [
|
|
716
|
-
|
|
920
|
+
styles8.box,
|
|
717
921
|
{ borderRadius: radius3.xs + 2, borderColor: error ? theme.danger : on ? theme.accent : theme.borderStrong, backgroundColor: on ? theme.accent : theme.surface1 }
|
|
718
922
|
],
|
|
719
|
-
children: on ? /* @__PURE__ */
|
|
923
|
+
children: on ? /* @__PURE__ */ jsx9(Svg3, { width: 14, height: 14, viewBox: "0 0 24 24", fill: "none", stroke: theme.onAccent, strokeWidth: 3, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx9(Path, { d: "M20 6 9 17l-5-5" }) }) : null
|
|
720
924
|
}
|
|
721
925
|
);
|
|
722
926
|
const plain = children === void 0 || typeof children === "string";
|
|
@@ -729,21 +933,21 @@ function Checkbox({ children, label, checked, defaultChecked = false, onCheckedC
|
|
|
729
933
|
disabled,
|
|
730
934
|
onPress: toggle
|
|
731
935
|
};
|
|
732
|
-
return /* @__PURE__ */
|
|
733
|
-
plain ? /* @__PURE__ */
|
|
936
|
+
return /* @__PURE__ */ jsxs6(View6, { style: [styles8.root, style], children: [
|
|
937
|
+
plain ? /* @__PURE__ */ jsxs6(Pressable4, { ...a11y, hitSlop: 4, style: [styles8.row, disabled ? styles8.disabled : null], children: [
|
|
734
938
|
box,
|
|
735
|
-
children !== void 0 ? /* @__PURE__ */
|
|
939
|
+
children !== void 0 ? /* @__PURE__ */ jsx9(View6, { style: styles8.text, children: /* @__PURE__ */ jsx9(Text4, { style: [styles8.label, { color: theme.textPrimary }], children }) }) : null
|
|
736
940
|
] }) : (
|
|
737
941
|
// Words with links: the box alone is the control (a 44-pt target, named by `label`), the links stay links.
|
|
738
|
-
/* @__PURE__ */
|
|
739
|
-
/* @__PURE__ */
|
|
740
|
-
/* @__PURE__ */
|
|
942
|
+
/* @__PURE__ */ jsxs6(View6, { style: [styles8.row, disabled ? styles8.disabled : null], children: [
|
|
943
|
+
/* @__PURE__ */ jsx9(Pressable4, { ...a11y, hitSlop: 11, style: styles8.target, children: box }),
|
|
944
|
+
/* @__PURE__ */ jsx9(View6, { style: styles8.text, children })
|
|
741
945
|
] })
|
|
742
946
|
),
|
|
743
|
-
error ? /* @__PURE__ */
|
|
947
|
+
error ? /* @__PURE__ */ jsx9(Text4, { role: "alert", "aria-live": "polite", style: [styles8.error, { color: theme.dangerText }], children: error }) : null
|
|
744
948
|
] });
|
|
745
949
|
}
|
|
746
|
-
var
|
|
950
|
+
var styles8 = StyleSheet8.create({
|
|
747
951
|
root: { gap: 2, alignSelf: "stretch" },
|
|
748
952
|
row: { flexDirection: "row", alignItems: "center", gap: 12, minHeight: 44 },
|
|
749
953
|
target: { minHeight: 44, justifyContent: "center" },
|
|
@@ -755,18 +959,18 @@ var styles6 = StyleSheet6.create({
|
|
|
755
959
|
});
|
|
756
960
|
|
|
757
961
|
// src/native/chip.tsx
|
|
758
|
-
import * as
|
|
759
|
-
import { Pressable as
|
|
760
|
-
import { Fragment, jsx as
|
|
761
|
-
var ChipGroupContext =
|
|
962
|
+
import * as React8 from "react";
|
|
963
|
+
import { Pressable as Pressable5, ScrollView, StyleSheet as StyleSheet9, Text as Text5, View as View7 } from "react-native";
|
|
964
|
+
import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
965
|
+
var ChipGroupContext = React8.createContext(null);
|
|
762
966
|
function Label({ children, color, size }) {
|
|
763
|
-
if (typeof children !== "string" && typeof children !== "number") return /* @__PURE__ */
|
|
764
|
-
return /* @__PURE__ */
|
|
967
|
+
if (typeof children !== "string" && typeof children !== "number") return /* @__PURE__ */ jsx10(Fragment2, { children });
|
|
968
|
+
return /* @__PURE__ */ jsx10(Text5, { style: [styles9.label, { color, fontSize: size === "sm" ? 12 : 13 }], children });
|
|
765
969
|
}
|
|
766
970
|
function ChipBase(props) {
|
|
767
|
-
const group =
|
|
971
|
+
const group = React8.useContext(ChipGroupContext);
|
|
768
972
|
const { theme, radius: radius3 } = useTheme();
|
|
769
|
-
const [own, setOwn] =
|
|
973
|
+
const [own, setOwn] = React8.useState(props.removable ? false : props.defaultSelected ?? false);
|
|
770
974
|
const size = props.size ?? group?.size ?? "md";
|
|
771
975
|
const frame = (on2, pressed) => ({
|
|
772
976
|
height: size === "sm" ? 28 : 36,
|
|
@@ -777,9 +981,9 @@ function ChipBase(props) {
|
|
|
777
981
|
});
|
|
778
982
|
if (props.removable) {
|
|
779
983
|
const { removable: _r2, removeLabel, onRemove, disabled: disabled2, size: _s2, style: style2, children: children2, ...rest2 } = props;
|
|
780
|
-
return /* @__PURE__ */
|
|
781
|
-
/* @__PURE__ */
|
|
782
|
-
/* @__PURE__ */
|
|
984
|
+
return /* @__PURE__ */ jsxs7(View7, { ...rest2, style: [styles9.base, frame(false, false), disabled2 ? styles9.disabled : null, style2], children: [
|
|
985
|
+
/* @__PURE__ */ jsx10(Label, { color: theme.textSecondary, size, children: children2 }),
|
|
986
|
+
/* @__PURE__ */ jsx10(Pressable5, { role: "button", "aria-label": removeLabel, disabled: disabled2 ?? void 0, hitSlop: 10, onPress: onRemove, style: styles9.remove, children: /* @__PURE__ */ jsx10(Text5, { style: [styles9.cross, { color: theme.textSecondary }], children: "\xD7" }) })
|
|
783
987
|
] });
|
|
784
988
|
}
|
|
785
989
|
const { removable: _r, value, selected, defaultSelected: _d, onSelectedChange, disabled: ownDisabled, size: _s, style, children, ...rest } = props;
|
|
@@ -792,8 +996,8 @@ function ChipBase(props) {
|
|
|
792
996
|
onSelectedChange?.(!on);
|
|
793
997
|
};
|
|
794
998
|
const single = group?.type === "single";
|
|
795
|
-
return /* @__PURE__ */
|
|
796
|
-
|
|
999
|
+
return /* @__PURE__ */ jsx10(
|
|
1000
|
+
Pressable5,
|
|
797
1001
|
{
|
|
798
1002
|
role: single ? "radio" : "checkbox",
|
|
799
1003
|
"aria-checked": on,
|
|
@@ -801,17 +1005,17 @@ function ChipBase(props) {
|
|
|
801
1005
|
...rest,
|
|
802
1006
|
disabled,
|
|
803
1007
|
onPress: press,
|
|
804
|
-
style: ({ pressed }) => [
|
|
805
|
-
children: /* @__PURE__ */
|
|
1008
|
+
style: ({ pressed }) => [styles9.base, frame(on, pressed), disabled ? styles9.disabled : null, style],
|
|
1009
|
+
children: /* @__PURE__ */ jsx10(Label, { color: on ? theme.textPrimary : theme.textSecondary, size, children })
|
|
806
1010
|
}
|
|
807
1011
|
);
|
|
808
1012
|
}
|
|
809
1013
|
function ChipGroup(props) {
|
|
810
1014
|
const { size, disabled, scrollable, "aria-label": label, style, children } = props;
|
|
811
1015
|
const initial = props.type === "single" ? props.defaultValue ?? "" : props.defaultValue ?? [];
|
|
812
|
-
const [own, setOwn] =
|
|
1016
|
+
const [own, setOwn] = React8.useState(initial);
|
|
813
1017
|
const current = props.value ?? own;
|
|
814
|
-
const context =
|
|
1018
|
+
const context = React8.useMemo(() => {
|
|
815
1019
|
const list = Array.isArray(current) ? current : [current];
|
|
816
1020
|
return {
|
|
817
1021
|
type: props.type,
|
|
@@ -826,10 +1030,10 @@ function ChipGroup(props) {
|
|
|
826
1030
|
};
|
|
827
1031
|
}, [current, props.type, props.value, props.onValueChange, size, disabled]);
|
|
828
1032
|
const a11y = { role: props.type === "single" ? "radiogroup" : "group", "aria-label": label };
|
|
829
|
-
return /* @__PURE__ */
|
|
1033
|
+
return /* @__PURE__ */ jsx10(ChipGroupContext.Provider, { value: context, children: scrollable ? /* @__PURE__ */ jsx10(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, ...a11y, style, contentContainerStyle: styles9.row, children }) : /* @__PURE__ */ jsx10(View7, { ...a11y, style: [styles9.row, styles9.wrap, style], children }) });
|
|
830
1034
|
}
|
|
831
1035
|
var Chip = Object.assign(ChipBase, { Group: ChipGroup });
|
|
832
|
-
var
|
|
1036
|
+
var styles9 = StyleSheet9.create({
|
|
833
1037
|
base: { flexDirection: "row", alignItems: "center", justifyContent: "center", gap: 6, paddingHorizontal: 14, borderWidth: 1, alignSelf: "flex-start" },
|
|
834
1038
|
label: { fontWeight: "600" },
|
|
835
1039
|
remove: { marginRight: -6, width: 24, height: 24, alignItems: "center", justifyContent: "center" },
|
|
@@ -839,10 +1043,239 @@ var styles7 = StyleSheet7.create({
|
|
|
839
1043
|
wrap: { flexWrap: "wrap" }
|
|
840
1044
|
});
|
|
841
1045
|
|
|
1046
|
+
// src/native/combobox.tsx
|
|
1047
|
+
import * as React10 from "react";
|
|
1048
|
+
import { Pressable as Pressable7, ScrollView as ScrollView2, StyleSheet as StyleSheet11, Text as Text7, TextInput, View as View9 } from "react-native";
|
|
1049
|
+
import Svg4, { Path as Path2 } from "react-native-svg";
|
|
1050
|
+
|
|
1051
|
+
// src/native/dialog.tsx
|
|
1052
|
+
import * as React9 from "react";
|
|
1053
|
+
import { Animated as Animated2, Modal as Modal2, Pressable as Pressable6, StyleSheet as StyleSheet10, Text as Text6, View as View8 } from "react-native";
|
|
1054
|
+
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1055
|
+
function Sheet({ open, onOpenChange, title, closeLabel = "Close", children, style }) {
|
|
1056
|
+
const { theme, radius: radius3, motion: motion3 } = useTheme();
|
|
1057
|
+
const [rise] = React9.useState(() => new Animated2.Value(0));
|
|
1058
|
+
React9.useEffect(() => {
|
|
1059
|
+
if (open) Animated2.timing(rise, { toValue: 1, duration: motion3.duration.base * 1.6, useNativeDriver: true }).start();
|
|
1060
|
+
else rise.setValue(0);
|
|
1061
|
+
}, [open, rise, motion3.duration.base]);
|
|
1062
|
+
return /* @__PURE__ */ jsx11(Modal2, { transparent: true, visible: open, animationType: "none", onRequestClose: () => onOpenChange(false), statusBarTranslucent: true, children: /* @__PURE__ */ jsxs8(View8, { style: styles10.backdrop, children: [
|
|
1063
|
+
/* @__PURE__ */ jsx11(Animated2.View, { style: [StyleSheet10.absoluteFill, { opacity: rise }], children: /* @__PURE__ */ jsx11(Pressable6, { role: "button", "aria-label": closeLabel, onPress: () => onOpenChange(false), style: [StyleSheet10.absoluteFill, { backgroundColor: theme.scrim }] }) }),
|
|
1064
|
+
/* @__PURE__ */ jsxs8(
|
|
1065
|
+
Animated2.View,
|
|
1066
|
+
{
|
|
1067
|
+
role: "dialog",
|
|
1068
|
+
"aria-label": title,
|
|
1069
|
+
style: [
|
|
1070
|
+
styles10.sheet,
|
|
1071
|
+
{
|
|
1072
|
+
backgroundColor: theme.surface1,
|
|
1073
|
+
borderColor: theme.borderDefault,
|
|
1074
|
+
borderTopLeftRadius: radius3["2xl"],
|
|
1075
|
+
borderTopRightRadius: radius3["2xl"],
|
|
1076
|
+
shadowColor: theme.scrimStrong,
|
|
1077
|
+
transform: [{ translateY: rise.interpolate({ inputRange: [0, 1], outputRange: [48, 0] }) }],
|
|
1078
|
+
opacity: rise.interpolate({ inputRange: [0, 1], outputRange: [0.6, 1] })
|
|
1079
|
+
},
|
|
1080
|
+
style
|
|
1081
|
+
],
|
|
1082
|
+
children: [
|
|
1083
|
+
/* @__PURE__ */ jsx11(View8, { "aria-hidden": true, style: [styles10.grip, { backgroundColor: theme.borderStrong }] }),
|
|
1084
|
+
title ? /* @__PURE__ */ jsx11(Text6, { role: "heading", style: [styles10.title, { color: theme.textPrimary }], children: title }) : null,
|
|
1085
|
+
children
|
|
1086
|
+
]
|
|
1087
|
+
}
|
|
1088
|
+
)
|
|
1089
|
+
] }) });
|
|
1090
|
+
}
|
|
1091
|
+
var styles10 = StyleSheet10.create({
|
|
1092
|
+
backdrop: { flex: 1, justifyContent: "flex-end" },
|
|
1093
|
+
sheet: { maxHeight: "85%", paddingHorizontal: 16, paddingTop: 8, paddingBottom: 28, gap: 12, borderWidth: StyleSheet10.hairlineWidth, shadowOpacity: 0.3, shadowRadius: 16, shadowOffset: { width: 0, height: -4 }, elevation: 12 },
|
|
1094
|
+
grip: { alignSelf: "center", width: 40, height: 5, borderRadius: 3, marginBottom: 4 },
|
|
1095
|
+
title: { fontSize: 17, fontWeight: "700" }
|
|
1096
|
+
});
|
|
1097
|
+
|
|
1098
|
+
// src/native/combobox.tsx
|
|
1099
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1100
|
+
function Chevron({ color }) {
|
|
1101
|
+
return /* @__PURE__ */ jsx12(Svg4, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx12(Path2, { d: "m6 9 6 6 6-6" }) });
|
|
1102
|
+
}
|
|
1103
|
+
function Tick({ color }) {
|
|
1104
|
+
return /* @__PURE__ */ jsx12(Svg4, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2.6, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx12(Path2, { d: "M20 6 9 17l-5-5" }) });
|
|
1105
|
+
}
|
|
1106
|
+
function Trigger({ shared, text, onPress, open }) {
|
|
1107
|
+
const { theme, radius: radius3 } = useTheme();
|
|
1108
|
+
const { label, placeholder, hint, error, disabled } = shared;
|
|
1109
|
+
const caption = error ?? hint;
|
|
1110
|
+
return /* @__PURE__ */ jsxs9(View9, { style: [styles11.field, shared.style], children: [
|
|
1111
|
+
/* @__PURE__ */ jsx12(Text7, { style: [styles11.label, { color: theme.textSecondary }], children: label }),
|
|
1112
|
+
/* @__PURE__ */ jsxs9(
|
|
1113
|
+
Pressable7,
|
|
1114
|
+
{
|
|
1115
|
+
role: "button",
|
|
1116
|
+
"aria-label": `${label}, ${text ?? placeholder ?? ""}`.replace(/, $/, ""),
|
|
1117
|
+
"aria-expanded": open,
|
|
1118
|
+
"aria-haspopup": "listbox",
|
|
1119
|
+
"aria-disabled": disabled || void 0,
|
|
1120
|
+
accessibilityHint: caption,
|
|
1121
|
+
disabled,
|
|
1122
|
+
onPress,
|
|
1123
|
+
style: [styles11.trigger, { borderRadius: radius3.md, backgroundColor: theme.surface2, borderColor: error ? theme.danger : open ? theme.accent : theme.borderDefault }, disabled ? styles11.disabled : null],
|
|
1124
|
+
children: [
|
|
1125
|
+
/* @__PURE__ */ jsx12(Text7, { numberOfLines: 1, style: [styles11.triggerText, { color: text ? theme.textPrimary : theme.textSecondary }], children: text ?? placeholder ?? "" }),
|
|
1126
|
+
/* @__PURE__ */ jsx12(Chevron, { color: theme.textSecondary })
|
|
1127
|
+
]
|
|
1128
|
+
}
|
|
1129
|
+
),
|
|
1130
|
+
caption ? /* @__PURE__ */ jsx12(Text7, { role: error ? "alert" : void 0, "aria-live": error ? "polite" : void 0, style: [styles11.caption, { color: error ? theme.dangerText : theme.textSecondary }], children: caption }) : null
|
|
1131
|
+
] });
|
|
1132
|
+
}
|
|
1133
|
+
function Options({ options, isChosen, onPick, multiple }) {
|
|
1134
|
+
const { theme, radius: radius3, haptic } = useTheme();
|
|
1135
|
+
return /* @__PURE__ */ jsx12(ScrollView2, { role: multiple ? "list" : "radiogroup", keyboardShouldPersistTaps: "handled", style: styles11.options, children: options.map((o) => {
|
|
1136
|
+
const chosen = isChosen(o.value);
|
|
1137
|
+
return /* @__PURE__ */ jsxs9(
|
|
1138
|
+
Pressable7,
|
|
1139
|
+
{
|
|
1140
|
+
role: multiple ? "checkbox" : "radio",
|
|
1141
|
+
"aria-checked": chosen,
|
|
1142
|
+
"aria-label": o.description ? `${o.label}, ${o.description}` : o.label,
|
|
1143
|
+
"aria-disabled": o.disabled || void 0,
|
|
1144
|
+
disabled: o.disabled,
|
|
1145
|
+
onPress: () => {
|
|
1146
|
+
haptic("selection");
|
|
1147
|
+
onPick(o);
|
|
1148
|
+
},
|
|
1149
|
+
style: ({ pressed }) => [styles11.option, { borderRadius: radius3.md, backgroundColor: chosen ? theme.accentSoft : pressed ? theme.surface3 : "transparent" }, o.disabled ? styles11.disabled : null],
|
|
1150
|
+
children: [
|
|
1151
|
+
/* @__PURE__ */ jsxs9(View9, { style: styles11.optionText, children: [
|
|
1152
|
+
/* @__PURE__ */ jsx12(Text7, { style: [styles11.optionLabel, { color: theme.textPrimary, fontWeight: chosen ? "700" : "500" }], children: o.label }),
|
|
1153
|
+
o.description ? /* @__PURE__ */ jsx12(Text7, { style: [styles11.caption, { color: theme.textSecondary }], children: o.description }) : null
|
|
1154
|
+
] }),
|
|
1155
|
+
chosen ? /* @__PURE__ */ jsx12(Tick, { color: theme.accentText }) : null
|
|
1156
|
+
]
|
|
1157
|
+
},
|
|
1158
|
+
o.value
|
|
1159
|
+
);
|
|
1160
|
+
}) });
|
|
1161
|
+
}
|
|
1162
|
+
function Select({ options, value: valueProp, defaultValue = null, onValueChange, sheetTitle, ...shared }) {
|
|
1163
|
+
const [own, setOwn] = React10.useState(defaultValue);
|
|
1164
|
+
const value = valueProp !== void 0 ? valueProp : own;
|
|
1165
|
+
const [open, setOpen] = React10.useState(false);
|
|
1166
|
+
const close = () => {
|
|
1167
|
+
setOpen(false);
|
|
1168
|
+
shared.onBlur?.();
|
|
1169
|
+
};
|
|
1170
|
+
return /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
1171
|
+
/* @__PURE__ */ jsx12(Trigger, { shared, text: options.find((o) => o.value === value)?.label ?? null, open, onPress: () => setOpen(true) }),
|
|
1172
|
+
/* @__PURE__ */ jsx12(Sheet, { open, onOpenChange: (o) => o ? setOpen(true) : close(), title: sheetTitle ?? shared.label, children: /* @__PURE__ */ jsx12(
|
|
1173
|
+
Options,
|
|
1174
|
+
{
|
|
1175
|
+
options,
|
|
1176
|
+
isChosen: (v) => v === value,
|
|
1177
|
+
onPick: (o) => {
|
|
1178
|
+
if (valueProp === void 0) setOwn(o.value);
|
|
1179
|
+
onValueChange?.(o.value);
|
|
1180
|
+
close();
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
) })
|
|
1184
|
+
] });
|
|
1185
|
+
}
|
|
1186
|
+
var comboboxLabels = { search: "Search", loading: "Searching\u2026", empty: "No results", done: "Done" };
|
|
1187
|
+
function Combobox({ options = [], onSearch, multiple, value, onValueChange, labels: given, ...shared }) {
|
|
1188
|
+
const labels = { ...comboboxLabels, ...given };
|
|
1189
|
+
const { theme, radius: radius3 } = useTheme();
|
|
1190
|
+
const [open, setOpen] = React10.useState(false);
|
|
1191
|
+
const [query, setQuery] = React10.useState("");
|
|
1192
|
+
const [found, setFound] = React10.useState(null);
|
|
1193
|
+
const [loading, setLoading] = React10.useState(false);
|
|
1194
|
+
const [seen, setSeen] = React10.useState({});
|
|
1195
|
+
const chosen = value == null ? [] : typeof value === "string" ? value ? [value] : [] : [...value];
|
|
1196
|
+
React10.useEffect(() => {
|
|
1197
|
+
if (!onSearch || !open) return;
|
|
1198
|
+
const controller = new AbortController();
|
|
1199
|
+
const timer2 = setTimeout(() => {
|
|
1200
|
+
setLoading(true);
|
|
1201
|
+
onSearch(query, controller.signal).then((result) => {
|
|
1202
|
+
if (!controller.signal.aborted) setFound(result);
|
|
1203
|
+
}).catch(() => void 0).finally(() => {
|
|
1204
|
+
if (!controller.signal.aborted) setLoading(false);
|
|
1205
|
+
});
|
|
1206
|
+
}, 250);
|
|
1207
|
+
return () => {
|
|
1208
|
+
clearTimeout(timer2);
|
|
1209
|
+
controller.abort();
|
|
1210
|
+
};
|
|
1211
|
+
}, [query, onSearch, open]);
|
|
1212
|
+
const q = query.trim().toLowerCase();
|
|
1213
|
+
const list = onSearch ? found ?? [] : options.filter((o) => !q || o.label.toLowerCase().includes(q));
|
|
1214
|
+
const labelOf = (v) => options.find((o) => o.value === v)?.label ?? seen[v]?.label ?? v;
|
|
1215
|
+
const close = () => {
|
|
1216
|
+
setOpen(false);
|
|
1217
|
+
setQuery("");
|
|
1218
|
+
shared.onBlur?.();
|
|
1219
|
+
};
|
|
1220
|
+
return /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
1221
|
+
/* @__PURE__ */ jsx12(Trigger, { shared, text: chosen.length ? chosen.map(labelOf).join(", ") : null, open, onPress: () => setOpen(true) }),
|
|
1222
|
+
/* @__PURE__ */ jsxs9(Sheet, { open, onOpenChange: (o) => o ? setOpen(true) : close(), title: shared.label, children: [
|
|
1223
|
+
/* @__PURE__ */ jsx12(
|
|
1224
|
+
TextInput,
|
|
1225
|
+
{
|
|
1226
|
+
"aria-label": labels.search,
|
|
1227
|
+
placeholder: labels.search,
|
|
1228
|
+
placeholderTextColor: theme.textMuted,
|
|
1229
|
+
value: query,
|
|
1230
|
+
onChangeText: setQuery,
|
|
1231
|
+
autoFocus: true,
|
|
1232
|
+
autoCorrect: false,
|
|
1233
|
+
returnKeyType: "search",
|
|
1234
|
+
style: [styles11.search, { borderRadius: radius3.md, backgroundColor: theme.surface2, borderColor: theme.borderDefault, color: theme.textPrimary }]
|
|
1235
|
+
}
|
|
1236
|
+
),
|
|
1237
|
+
loading ? /* @__PURE__ */ jsx12(Text7, { style: [styles11.caption, { color: theme.textSecondary }], children: labels.loading }) : null,
|
|
1238
|
+
!loading && list.length === 0 ? /* @__PURE__ */ jsx12(Text7, { style: [styles11.caption, { color: theme.textSecondary }], children: labels.empty }) : null,
|
|
1239
|
+
/* @__PURE__ */ jsx12(
|
|
1240
|
+
Options,
|
|
1241
|
+
{
|
|
1242
|
+
options: list,
|
|
1243
|
+
multiple,
|
|
1244
|
+
isChosen: (v) => chosen.includes(v),
|
|
1245
|
+
onPick: (o) => {
|
|
1246
|
+
setSeen((known) => ({ ...known, [o.value]: o }));
|
|
1247
|
+
if (multiple) onValueChange?.(chosen.includes(o.value) ? chosen.filter((v) => v !== o.value) : [...chosen, o.value]);
|
|
1248
|
+
else {
|
|
1249
|
+
onValueChange?.(o.value);
|
|
1250
|
+
close();
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
),
|
|
1255
|
+
multiple ? /* @__PURE__ */ jsx12(Pressable7, { role: "button", onPress: close, style: [styles11.done, { borderRadius: radius3.md, backgroundColor: theme.accent }], children: /* @__PURE__ */ jsx12(Text7, { style: [styles11.doneText, { color: theme.onAccent }], children: labels.done }) }) : null
|
|
1256
|
+
] })
|
|
1257
|
+
] });
|
|
1258
|
+
}
|
|
1259
|
+
var styles11 = StyleSheet11.create({
|
|
1260
|
+
field: { gap: 6, alignSelf: "stretch" },
|
|
1261
|
+
label: { fontSize: 12, lineHeight: 16, fontWeight: "600" },
|
|
1262
|
+
trigger: { minHeight: 48, flexDirection: "row", alignItems: "center", gap: 8, paddingHorizontal: 14, borderWidth: 1 },
|
|
1263
|
+
triggerText: { flex: 1, fontSize: 16 },
|
|
1264
|
+
caption: { fontSize: 12, lineHeight: 16 },
|
|
1265
|
+
options: { flexGrow: 0 },
|
|
1266
|
+
option: { minHeight: 48, flexDirection: "row", alignItems: "center", gap: 12, paddingHorizontal: 12, paddingVertical: 8 },
|
|
1267
|
+
optionText: { flex: 1, gap: 2 },
|
|
1268
|
+
optionLabel: { fontSize: 16 },
|
|
1269
|
+
search: { height: 44, paddingHorizontal: 12, borderWidth: 1, fontSize: 16 },
|
|
1270
|
+
done: { height: 48, alignItems: "center", justifyContent: "center" },
|
|
1271
|
+
doneText: { fontSize: 15, fontWeight: "700" },
|
|
1272
|
+
disabled: { opacity: 0.4 }
|
|
1273
|
+
});
|
|
1274
|
+
|
|
842
1275
|
// src/native/countdown.tsx
|
|
843
|
-
import * as
|
|
844
|
-
import { Animated as
|
|
845
|
-
import { jsx as
|
|
1276
|
+
import * as React11 from "react";
|
|
1277
|
+
import { Animated as Animated3, StyleSheet as StyleSheet12, Text as Text8 } from "react-native";
|
|
1278
|
+
import { jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
846
1279
|
var FONT = { sm: 14, md: 20, lg: 32 };
|
|
847
1280
|
function Countdown({ target, skewMs = 0, units, urgentBelowMs = 6e4, size = "md", label, showLabel = false, style }) {
|
|
848
1281
|
const { theme, fonts } = useTheme();
|
|
@@ -850,13 +1283,13 @@ function Countdown({ target, skewMs = 0, units, urgentBelowMs = 6e4, size = "md"
|
|
|
850
1283
|
const ms = useCountdown(target, skewMs);
|
|
851
1284
|
const urgent = ms > 0 && ms < urgentBelowMs;
|
|
852
1285
|
const parts = countdownParts(ms, units);
|
|
853
|
-
const [opacity] =
|
|
854
|
-
|
|
1286
|
+
const [opacity] = React11.useState(() => new Animated3.Value(1));
|
|
1287
|
+
React11.useEffect(() => {
|
|
855
1288
|
if (!urgent || reduce) return;
|
|
856
|
-
const loop =
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1289
|
+
const loop = Animated3.loop(
|
|
1290
|
+
Animated3.sequence([
|
|
1291
|
+
Animated3.timing(opacity, { toValue: 0.4, duration: 500, useNativeDriver: true }),
|
|
1292
|
+
Animated3.timing(opacity, { toValue: 1, duration: 500, useNativeDriver: true })
|
|
860
1293
|
])
|
|
861
1294
|
);
|
|
862
1295
|
loop.start();
|
|
@@ -867,24 +1300,24 @@ function Countdown({ target, skewMs = 0, units, urgentBelowMs = 6e4, size = "md"
|
|
|
867
1300
|
}, [urgent, reduce, opacity]);
|
|
868
1301
|
const color = urgent ? theme.dangerText : theme.textPrimary;
|
|
869
1302
|
const text = parts.map(([value, unit]) => `${String(value).padStart(2, "0")}${unit}`).join(" ");
|
|
870
|
-
return /* @__PURE__ */
|
|
871
|
-
|
|
1303
|
+
return /* @__PURE__ */ jsxs10(
|
|
1304
|
+
Animated3.View,
|
|
872
1305
|
{
|
|
873
1306
|
accessible: true,
|
|
874
1307
|
role: "timer",
|
|
875
1308
|
"aria-label": `${label} ${text}`,
|
|
876
|
-
style: [
|
|
1309
|
+
style: [styles12.root, style],
|
|
877
1310
|
children: [
|
|
878
|
-
showLabel ? /* @__PURE__ */
|
|
879
|
-
parts.map(([value, unit], i) => /* @__PURE__ */
|
|
880
|
-
/* @__PURE__ */
|
|
881
|
-
/* @__PURE__ */
|
|
1311
|
+
showLabel ? /* @__PURE__ */ jsx13(Text8, { style: [styles12.label, { color: theme.textSecondary, fontSize: Math.max(11, Math.round(FONT[size] * 0.6)) }], children: label }) : null,
|
|
1312
|
+
parts.map(([value, unit], i) => /* @__PURE__ */ jsxs10(Animated3.View, { style: [styles12.segment, urgent && i === parts.length - 1 ? { opacity } : null], children: [
|
|
1313
|
+
/* @__PURE__ */ jsx13(Text8, { style: [styles12.value, { color, fontSize: FONT[size] }, fonts.display ? { fontFamily: fonts.display } : null], children: String(value).padStart(2, "0") }),
|
|
1314
|
+
/* @__PURE__ */ jsx13(Text8, { style: [styles12.unit, { color: theme.textSecondary, fontSize: Math.round(FONT[size] / 2) }], children: unit })
|
|
882
1315
|
] }, unit))
|
|
883
1316
|
]
|
|
884
1317
|
}
|
|
885
1318
|
);
|
|
886
1319
|
}
|
|
887
|
-
var
|
|
1320
|
+
var styles12 = StyleSheet12.create({
|
|
888
1321
|
root: { flexDirection: "row", alignItems: "baseline", gap: 6 },
|
|
889
1322
|
segment: { flexDirection: "row", alignItems: "baseline" },
|
|
890
1323
|
value: { fontWeight: "900", fontVariant: ["tabular-nums"], letterSpacing: -0.3 },
|
|
@@ -893,18 +1326,18 @@ var styles8 = StyleSheet8.create({
|
|
|
893
1326
|
});
|
|
894
1327
|
|
|
895
1328
|
// src/native/date-picker.tsx
|
|
896
|
-
import * as
|
|
897
|
-
import { Platform, StyleSheet as
|
|
898
|
-
import { jsx as
|
|
1329
|
+
import * as React12 from "react";
|
|
1330
|
+
import { Platform, StyleSheet as StyleSheet13, Text as Text9, TextInput as TextInput2, View as View10 } from "react-native";
|
|
1331
|
+
import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
899
1332
|
var LENGTH = DATE_PART_LENGTH;
|
|
900
1333
|
var dateFieldLabels = { day: "Day", month: "Month", year: "Year" };
|
|
901
1334
|
function DateField({ label, hint, error, value, defaultValue, onValueChange, onBlur, locale = "en-US", labels: given, autoComplete, disabled, inputRef, onSubmitEditing, returnKeyType = "done", style }) {
|
|
902
1335
|
const { theme, radius: radius3 } = useTheme();
|
|
903
1336
|
const labels = { ...dateFieldLabels, ...given };
|
|
904
|
-
const order =
|
|
905
|
-
const [parts, setParts] =
|
|
906
|
-
const [focused, setFocused] =
|
|
907
|
-
const refs = { day:
|
|
1337
|
+
const order = React12.useMemo(() => datePartsOrder(locale), [locale]);
|
|
1338
|
+
const [parts, setParts] = React12.useState(() => splitDate(value ?? defaultValue));
|
|
1339
|
+
const [focused, setFocused] = React12.useState(null);
|
|
1340
|
+
const refs = { day: React12.useRef(null), month: React12.useRef(null), year: React12.useRef(null) };
|
|
908
1341
|
if (value !== void 0 && value !== composeDate(parts) && composeDate(splitDate(value)) === value) setParts(splitDate(value));
|
|
909
1342
|
const caption = error ?? hint;
|
|
910
1343
|
const change = (part, text) => {
|
|
@@ -915,12 +1348,12 @@ function DateField({ label, hint, error, value, defaultValue, onValueChange, onB
|
|
|
915
1348
|
const following = order[order.indexOf(part) + 1];
|
|
916
1349
|
if (digits.length === LENGTH[part] && following) refs[following].current?.focus();
|
|
917
1350
|
};
|
|
918
|
-
return /* @__PURE__ */
|
|
919
|
-
/* @__PURE__ */
|
|
920
|
-
/* @__PURE__ */
|
|
921
|
-
/* @__PURE__ */
|
|
922
|
-
/* @__PURE__ */
|
|
923
|
-
|
|
1351
|
+
return /* @__PURE__ */ jsxs11(View10, { role: "group", "aria-label": label, style: [styles13.root, disabled ? styles13.disabled : null, style], children: [
|
|
1352
|
+
/* @__PURE__ */ jsx14(Text9, { style: [styles13.label, { color: theme.textSecondary }], children: label }),
|
|
1353
|
+
/* @__PURE__ */ jsx14(View10, { style: styles13.row, children: order.map((part, i) => /* @__PURE__ */ jsxs11(View10, { style: part === "year" ? styles13.yearBox : styles13.box, children: [
|
|
1354
|
+
/* @__PURE__ */ jsx14(Text9, { style: [styles13.part, { color: theme.textSecondary }], children: labels[part] }),
|
|
1355
|
+
/* @__PURE__ */ jsx14(
|
|
1356
|
+
TextInput2,
|
|
924
1357
|
{
|
|
925
1358
|
ref: (node) => {
|
|
926
1359
|
refs[part].current = node;
|
|
@@ -951,16 +1384,16 @@ function DateField({ label, hint, error, value, defaultValue, onValueChange, onB
|
|
|
951
1384
|
if (i === order.length - 1) onBlur?.();
|
|
952
1385
|
},
|
|
953
1386
|
style: [
|
|
954
|
-
|
|
1387
|
+
styles13.input,
|
|
955
1388
|
{ color: theme.textPrimary, backgroundColor: theme.surface2, borderRadius: radius3.md, borderColor: error ? theme.danger : focused === part ? theme.accent : theme.borderDefault }
|
|
956
1389
|
]
|
|
957
1390
|
}
|
|
958
1391
|
)
|
|
959
1392
|
] }, part)) }),
|
|
960
|
-
caption ? /* @__PURE__ */
|
|
1393
|
+
caption ? /* @__PURE__ */ jsx14(Text9, { role: error ? "alert" : void 0, "aria-live": error ? "polite" : void 0, style: [styles13.caption, { color: error ? theme.dangerText : theme.textSecondary }], children: caption }) : null
|
|
961
1394
|
] });
|
|
962
1395
|
}
|
|
963
|
-
var
|
|
1396
|
+
var styles13 = StyleSheet13.create({
|
|
964
1397
|
root: { gap: 6, alignSelf: "stretch" },
|
|
965
1398
|
label: { fontSize: 12, lineHeight: 16, fontWeight: "600" },
|
|
966
1399
|
row: { flexDirection: "row", gap: 10 },
|
|
@@ -973,26 +1406,26 @@ var styles9 = StyleSheet9.create({
|
|
|
973
1406
|
});
|
|
974
1407
|
|
|
975
1408
|
// src/native/date-time.tsx
|
|
976
|
-
import * as
|
|
977
|
-
import { Pressable as
|
|
978
|
-
import
|
|
1409
|
+
import * as React14 from "react";
|
|
1410
|
+
import { Pressable as Pressable9, ScrollView as ScrollView4, StyleSheet as StyleSheet15, Text as Text11, View as View12 } from "react-native";
|
|
1411
|
+
import Svg5, { Path as Path3 } from "react-native-svg";
|
|
979
1412
|
|
|
980
1413
|
// src/native/wheel.tsx
|
|
981
|
-
import * as
|
|
982
|
-
import { Pressable as
|
|
983
|
-
import { jsx as
|
|
1414
|
+
import * as React13 from "react";
|
|
1415
|
+
import { Pressable as Pressable8, ScrollView as ScrollView3, StyleSheet as StyleSheet14, Text as Text10, View as View11 } from "react-native";
|
|
1416
|
+
import { jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
984
1417
|
var ITEM = 44;
|
|
985
|
-
var
|
|
986
|
-
function WheelPicker({ label, children, visible = 5, invalid, style }) {
|
|
1418
|
+
var FrameContext = React13.createContext({ visible: 5, unset: false });
|
|
1419
|
+
function WheelPicker({ label, children, visible = 5, invalid, unset = false, style }) {
|
|
987
1420
|
const { theme, radius: radius3 } = useTheme();
|
|
988
|
-
return /* @__PURE__ */
|
|
989
|
-
|
|
1421
|
+
return /* @__PURE__ */ jsx15(FrameContext.Provider, { value: React13.useMemo(() => ({ visible, unset }), [visible, unset]), children: /* @__PURE__ */ jsxs12(
|
|
1422
|
+
View11,
|
|
990
1423
|
{
|
|
991
1424
|
role: "group",
|
|
992
1425
|
"aria-label": label,
|
|
993
|
-
style: [
|
|
1426
|
+
style: [styles14.root, { height: ITEM * visible, borderRadius: radius3.xl, backgroundColor: theme.surface1, borderColor: invalid ? theme.danger : theme.borderDefault }, style],
|
|
994
1427
|
children: [
|
|
995
|
-
/* @__PURE__ */
|
|
1428
|
+
/* @__PURE__ */ jsx15(View11, { pointerEvents: "none", style: [styles14.band, { top: ITEM * (visible - 1) / 2, height: ITEM, borderRadius: radius3.lg, backgroundColor: theme.surface3, borderColor: theme.borderSubtle }] }),
|
|
996
1429
|
children
|
|
997
1430
|
]
|
|
998
1431
|
}
|
|
@@ -1000,7 +1433,7 @@ function WheelPicker({ label, children, visible = 5, invalid, style }) {
|
|
|
1000
1433
|
}
|
|
1001
1434
|
function WheelDivider({ children }) {
|
|
1002
1435
|
const { theme } = useTheme();
|
|
1003
|
-
return /* @__PURE__ */
|
|
1436
|
+
return /* @__PURE__ */ jsx15(Text10, { "aria-hidden": true, style: [styles14.divider, { color: theme.textSecondary }], children });
|
|
1004
1437
|
}
|
|
1005
1438
|
var nearestEnabled = (options, index) => {
|
|
1006
1439
|
for (let d = 0; d < options.length; d++) {
|
|
@@ -1011,14 +1444,14 @@ var nearestEnabled = (options, index) => {
|
|
|
1011
1444
|
};
|
|
1012
1445
|
function Wheel({ label, options, value: valueProp, defaultValue, onValueChange, disabled, style }) {
|
|
1013
1446
|
const { theme, haptic } = useTheme();
|
|
1014
|
-
const visible =
|
|
1015
|
-
const [own, setOwn] =
|
|
1447
|
+
const { visible, unset } = React13.useContext(FrameContext);
|
|
1448
|
+
const [own, setOwn] = React13.useState(defaultValue ?? options[0]?.value ?? "");
|
|
1016
1449
|
const value = valueProp ?? own;
|
|
1017
1450
|
const index = Math.max(0, options.findIndex((o) => o.value === value));
|
|
1018
|
-
const scroller =
|
|
1019
|
-
const passing =
|
|
1020
|
-
const [shown, setShown] =
|
|
1021
|
-
const [seen, setSeen] =
|
|
1451
|
+
const scroller = React13.useRef(null);
|
|
1452
|
+
const passing = React13.useRef(index);
|
|
1453
|
+
const [shown, setShown] = React13.useState(index);
|
|
1454
|
+
const [seen, setSeen] = React13.useState(index);
|
|
1022
1455
|
if (seen !== index) {
|
|
1023
1456
|
setSeen(index);
|
|
1024
1457
|
setShown(index);
|
|
@@ -1031,7 +1464,7 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1031
1464
|
if (valueProp === void 0) setOwn(option.value);
|
|
1032
1465
|
if (option.value !== value) onValueChange?.(option.value);
|
|
1033
1466
|
};
|
|
1034
|
-
|
|
1467
|
+
React13.useEffect(() => {
|
|
1035
1468
|
passing.current = index;
|
|
1036
1469
|
scroller.current?.scrollTo({ y: index * ITEM, animated: false });
|
|
1037
1470
|
}, [index]);
|
|
@@ -1050,8 +1483,8 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1050
1483
|
if (options[i]) commit(i);
|
|
1051
1484
|
};
|
|
1052
1485
|
const pad = (visible - 1) / 2 * ITEM;
|
|
1053
|
-
return /* @__PURE__ */
|
|
1054
|
-
|
|
1486
|
+
return /* @__PURE__ */ jsx15(
|
|
1487
|
+
View11,
|
|
1055
1488
|
{
|
|
1056
1489
|
accessible: true,
|
|
1057
1490
|
role: "spinbutton",
|
|
@@ -1063,9 +1496,9 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1063
1496
|
"aria-disabled": disabled || void 0,
|
|
1064
1497
|
accessibilityActions: [{ name: "increment" }, { name: "decrement" }],
|
|
1065
1498
|
onAccessibilityAction: (e) => step(e.nativeEvent.actionName === "increment" ? 1 : -1),
|
|
1066
|
-
style: [
|
|
1067
|
-
children: /* @__PURE__ */
|
|
1068
|
-
|
|
1499
|
+
style: [styles14.column, disabled ? styles14.disabled : null, style],
|
|
1500
|
+
children: /* @__PURE__ */ jsx15(
|
|
1501
|
+
ScrollView3,
|
|
1069
1502
|
{
|
|
1070
1503
|
ref: scroller,
|
|
1071
1504
|
"aria-hidden": true,
|
|
@@ -1084,15 +1517,15 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1084
1517
|
},
|
|
1085
1518
|
children: options.map((o, i) => {
|
|
1086
1519
|
const distance = Math.abs(i - shown);
|
|
1087
|
-
return /* @__PURE__ */
|
|
1088
|
-
|
|
1520
|
+
return /* @__PURE__ */ jsx15(Pressable8, { focusable: false, tabIndex: -1, disabled: disabled || o.disabled, onPress: () => commit(i), style: [styles14.item, { height: ITEM }], children: /* @__PURE__ */ jsx15(
|
|
1521
|
+
Text10,
|
|
1089
1522
|
{
|
|
1090
1523
|
numberOfLines: 1,
|
|
1091
1524
|
style: [
|
|
1092
|
-
|
|
1525
|
+
styles14.itemText,
|
|
1093
1526
|
{
|
|
1094
|
-
color: o.disabled ? theme.textMuted : i === shown ? theme.textPrimary : theme.textSecondary,
|
|
1095
|
-
fontWeight: i === shown ? "600" : "400",
|
|
1527
|
+
color: o.disabled ? theme.textMuted : i === shown && !unset ? theme.textPrimary : theme.textSecondary,
|
|
1528
|
+
fontWeight: i === shown && !unset ? "600" : "400",
|
|
1096
1529
|
opacity: distance === 0 ? 1 : distance === 1 ? 0.7 : 0.4,
|
|
1097
1530
|
transform: [{ scale: distance === 0 ? 1 : 0.92 }],
|
|
1098
1531
|
textDecorationLine: o.disabled ? "line-through" : "none"
|
|
@@ -1107,9 +1540,9 @@ function Wheel({ label, options, value: valueProp, defaultValue, onValueChange,
|
|
|
1107
1540
|
}
|
|
1108
1541
|
);
|
|
1109
1542
|
}
|
|
1110
|
-
var
|
|
1111
|
-
root: { flexDirection: "row", alignItems: "stretch", borderWidth:
|
|
1112
|
-
band: { position: "absolute", left: 6, right: 6, borderWidth:
|
|
1543
|
+
var styles14 = StyleSheet14.create({
|
|
1544
|
+
root: { flexDirection: "row", alignItems: "stretch", borderWidth: StyleSheet14.hairlineWidth, paddingHorizontal: 6, gap: 4, overflow: "hidden", alignSelf: "flex-start" },
|
|
1545
|
+
band: { position: "absolute", left: 6, right: 6, borderWidth: StyleSheet14.hairlineWidth },
|
|
1113
1546
|
column: { minWidth: 56, flexGrow: 1 },
|
|
1114
1547
|
item: { alignItems: "center", justifyContent: "center", paddingHorizontal: 8 },
|
|
1115
1548
|
itemText: { fontSize: 18, fontVariant: ["tabular-nums"] },
|
|
@@ -1118,19 +1551,19 @@ var styles10 = StyleSheet10.create({
|
|
|
1118
1551
|
});
|
|
1119
1552
|
|
|
1120
1553
|
// src/native/date-time.tsx
|
|
1121
|
-
import { jsx as
|
|
1554
|
+
import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1122
1555
|
var longDate = (locale, iso) => new Intl.DateTimeFormat(locale, { dateStyle: "long" }).format(toLocalDate(iso));
|
|
1123
1556
|
var useOwn = (value, initial) => {
|
|
1124
|
-
const [own, setOwn] =
|
|
1557
|
+
const [own, setOwn] = React14.useState(initial);
|
|
1125
1558
|
return [value !== void 0 ? value : own, (next) => value === void 0 && setOwn(next)];
|
|
1126
1559
|
};
|
|
1127
|
-
function
|
|
1128
|
-
return /* @__PURE__ */
|
|
1560
|
+
function Chevron2({ direction, color }) {
|
|
1561
|
+
return /* @__PURE__ */ jsx16(Svg5, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx16(Path3, { d: direction === "left" ? "m15 18-6-6 6-6" : "m9 18 6-6-6-6" }) });
|
|
1129
1562
|
}
|
|
1130
1563
|
function NavButton({ label, direction, disabled, onPress }) {
|
|
1131
1564
|
const { theme, radius: radius3 } = useTheme();
|
|
1132
|
-
return /* @__PURE__ */
|
|
1133
|
-
|
|
1565
|
+
return /* @__PURE__ */ jsx16(
|
|
1566
|
+
Pressable9,
|
|
1134
1567
|
{
|
|
1135
1568
|
role: "button",
|
|
1136
1569
|
"aria-label": label,
|
|
@@ -1138,49 +1571,49 @@ function NavButton({ label, direction, disabled, onPress }) {
|
|
|
1138
1571
|
disabled,
|
|
1139
1572
|
hitSlop: 6,
|
|
1140
1573
|
onPress,
|
|
1141
|
-
style: ({ pressed }) => [
|
|
1142
|
-
children: /* @__PURE__ */
|
|
1574
|
+
style: ({ pressed }) => [styles15.nav, { borderRadius: radius3.md, backgroundColor: pressed ? theme.surface3 : theme.surface2, borderColor: theme.borderSubtle }, disabled ? styles15.disabled : null],
|
|
1575
|
+
children: /* @__PURE__ */ jsx16(Chevron2, { direction, color: theme.textSecondary })
|
|
1143
1576
|
}
|
|
1144
1577
|
);
|
|
1145
1578
|
}
|
|
1146
1579
|
function Node({ color, style }) {
|
|
1147
|
-
return /* @__PURE__ */
|
|
1580
|
+
return /* @__PURE__ */ jsx16(View12, { "aria-hidden": true, style: [styles15.node, { backgroundColor: color }, style] });
|
|
1148
1581
|
}
|
|
1149
1582
|
var calendarLabels = { previousMonth: "Previous month", nextMonth: "Next month" };
|
|
1150
1583
|
function Calendar({ locale, value, range, onSelect, defaultMonth, min, max, isDateDisabled, weekStartsOn, today: todayProp, labels: given, style }) {
|
|
1151
1584
|
const labels = { ...calendarLabels, ...given };
|
|
1152
1585
|
const { theme, radius: radius3, haptic } = useTheme();
|
|
1153
1586
|
const today = todayProp ?? todayIso();
|
|
1154
|
-
const [month, setMonth] =
|
|
1587
|
+
const [month, setMonth] = React14.useState(`${(defaultMonth ?? value ?? range?.start ?? today).slice(0, 7)}-01`);
|
|
1155
1588
|
const start = weekStartsOn ?? weekStartOf(locale);
|
|
1156
1589
|
const weeks = monthGrid(month, start);
|
|
1157
1590
|
const weekday = new Intl.DateTimeFormat(locale, { weekday: "narrow" });
|
|
1158
1591
|
const title = new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }).format(toLocalDate(month));
|
|
1159
1592
|
const [lo, hi] = range?.end ? range.start <= range.end ? [range.start, range.end] : [range.end, range.start] : [null, null];
|
|
1160
1593
|
const off = (iso) => Boolean(min && iso < min || max && iso > max || isDateDisabled?.(iso));
|
|
1161
|
-
return /* @__PURE__ */
|
|
1162
|
-
/* @__PURE__ */
|
|
1163
|
-
/* @__PURE__ */
|
|
1164
|
-
/* @__PURE__ */
|
|
1165
|
-
/* @__PURE__ */
|
|
1594
|
+
return /* @__PURE__ */ jsxs13(View12, { style: [styles15.calendar, { backgroundColor: theme.surface1, borderColor: theme.borderDefault, borderRadius: radius3.xl }, style], children: [
|
|
1595
|
+
/* @__PURE__ */ jsxs13(View12, { style: styles15.header, children: [
|
|
1596
|
+
/* @__PURE__ */ jsx16(NavButton, { label: labels.previousMonth, direction: "left", disabled: Boolean(min && addDays(month, -1) < min), onPress: () => setMonth(addMonths(month, -1)) }),
|
|
1597
|
+
/* @__PURE__ */ jsx16(Text11, { role: "heading", "aria-live": "polite", style: [styles15.title, { color: theme.textPrimary }], children: title }),
|
|
1598
|
+
/* @__PURE__ */ jsx16(NavButton, { label: labels.nextMonth, direction: "right", disabled: Boolean(max && addMonths(month, 1) > max), onPress: () => setMonth(addMonths(month, 1)) })
|
|
1166
1599
|
] }),
|
|
1167
|
-
/* @__PURE__ */
|
|
1168
|
-
/* @__PURE__ */
|
|
1600
|
+
/* @__PURE__ */ jsx16(View12, { style: styles15.week, "aria-hidden": true, children: weeks[0].map((iso) => /* @__PURE__ */ jsx16(Text11, { style: [styles15.weekday, { color: theme.textSecondary }], children: weekday.format(toLocalDate(iso)) }, iso)) }),
|
|
1601
|
+
/* @__PURE__ */ jsx16(View12, { role: "radiogroup", "aria-label": title, children: weeks.map((week) => /* @__PURE__ */ jsx16(View12, { style: styles15.week, children: week.map((iso) => {
|
|
1169
1602
|
const outside = iso.slice(0, 7) !== month.slice(0, 7);
|
|
1170
1603
|
const selected = iso === value || Boolean(range && (iso === range.start || iso === range.end));
|
|
1171
1604
|
const disabled = off(iso);
|
|
1172
1605
|
const band = lo && hi && lo !== hi && iso >= lo && iso <= hi;
|
|
1173
|
-
return /* @__PURE__ */
|
|
1174
|
-
|
|
1606
|
+
return /* @__PURE__ */ jsx16(
|
|
1607
|
+
View12,
|
|
1175
1608
|
{
|
|
1176
1609
|
style: [
|
|
1177
|
-
|
|
1610
|
+
styles15.cell,
|
|
1178
1611
|
band ? { backgroundColor: theme.accentSoft } : null,
|
|
1179
1612
|
band && iso === lo ? { borderTopLeftRadius: radius3.lg, borderBottomLeftRadius: radius3.lg } : null,
|
|
1180
1613
|
band && iso === hi ? { borderTopRightRadius: radius3.lg, borderBottomRightRadius: radius3.lg } : null
|
|
1181
1614
|
],
|
|
1182
|
-
children: /* @__PURE__ */
|
|
1183
|
-
|
|
1615
|
+
children: /* @__PURE__ */ jsxs13(
|
|
1616
|
+
Pressable9,
|
|
1184
1617
|
{
|
|
1185
1618
|
role: "radio",
|
|
1186
1619
|
"aria-label": longDate(locale, iso),
|
|
@@ -1193,16 +1626,16 @@ function Calendar({ locale, value, range, onSelect, defaultMonth, min, max, isDa
|
|
|
1193
1626
|
onSelect?.(iso);
|
|
1194
1627
|
},
|
|
1195
1628
|
style: ({ pressed }) => [
|
|
1196
|
-
|
|
1629
|
+
styles15.day,
|
|
1197
1630
|
{ borderRadius: radius3.lg },
|
|
1198
1631
|
selected ? { backgroundColor: theme.accent } : pressed ? { backgroundColor: theme.surface3 } : null
|
|
1199
1632
|
],
|
|
1200
1633
|
children: [
|
|
1201
|
-
/* @__PURE__ */
|
|
1202
|
-
|
|
1634
|
+
/* @__PURE__ */ jsx16(
|
|
1635
|
+
Text11,
|
|
1203
1636
|
{
|
|
1204
1637
|
style: [
|
|
1205
|
-
|
|
1638
|
+
styles15.dayText,
|
|
1206
1639
|
{
|
|
1207
1640
|
color: selected ? theme.onAccent : disabled ? theme.textMuted : iso === today ? theme.accentText : outside ? theme.textSecondary : theme.textPrimary,
|
|
1208
1641
|
fontWeight: selected || iso === today ? "700" : "400",
|
|
@@ -1212,7 +1645,7 @@ function Calendar({ locale, value, range, onSelect, defaultMonth, min, max, isDa
|
|
|
1212
1645
|
children: Number(iso.slice(8))
|
|
1213
1646
|
}
|
|
1214
1647
|
),
|
|
1215
|
-
iso === today ? /* @__PURE__ */
|
|
1648
|
+
iso === today ? /* @__PURE__ */ jsx16(Node, { color: selected ? theme.onAccent : theme.accent, style: styles15.todayNode }) : null
|
|
1216
1649
|
]
|
|
1217
1650
|
}
|
|
1218
1651
|
)
|
|
@@ -1224,21 +1657,21 @@ function Calendar({ locale, value, range, onSelect, defaultMonth, min, max, isDa
|
|
|
1224
1657
|
}
|
|
1225
1658
|
function MonthPicker({ locale, value, onValueChange, min, max, labels, style }) {
|
|
1226
1659
|
const { theme, radius: radius3, haptic } = useTheme();
|
|
1227
|
-
const [year, setYear] =
|
|
1660
|
+
const [year, setYear] = React14.useState(Number((value ?? todayIso()).slice(0, 4)));
|
|
1228
1661
|
const names = monthNames(locale, "short").map((n) => n.replace(/\.$/, ""));
|
|
1229
1662
|
const long = monthNames(locale, "long");
|
|
1230
|
-
return /* @__PURE__ */
|
|
1231
|
-
/* @__PURE__ */
|
|
1232
|
-
/* @__PURE__ */
|
|
1233
|
-
/* @__PURE__ */
|
|
1234
|
-
/* @__PURE__ */
|
|
1663
|
+
return /* @__PURE__ */ jsxs13(View12, { style: [styles15.calendar, { backgroundColor: theme.surface1, borderColor: theme.borderDefault, borderRadius: radius3.xl }, style], children: [
|
|
1664
|
+
/* @__PURE__ */ jsxs13(View12, { style: styles15.header, children: [
|
|
1665
|
+
/* @__PURE__ */ jsx16(NavButton, { label: labels?.previousYear ?? "Previous year", direction: "left", disabled: Boolean(min && year - 1 < Number(min.slice(0, 4))), onPress: () => setYear(year - 1) }),
|
|
1666
|
+
/* @__PURE__ */ jsx16(Text11, { role: "heading", "aria-live": "polite", style: [styles15.title, { color: theme.textPrimary }], children: year }),
|
|
1667
|
+
/* @__PURE__ */ jsx16(NavButton, { label: labels?.nextYear ?? "Next year", direction: "right", disabled: Boolean(max && year + 1 > Number(max.slice(0, 4))), onPress: () => setYear(year + 1) })
|
|
1235
1668
|
] }),
|
|
1236
|
-
/* @__PURE__ */
|
|
1669
|
+
/* @__PURE__ */ jsx16(View12, { role: "radiogroup", "aria-label": String(year), style: styles15.months, children: names.map((name, i) => {
|
|
1237
1670
|
const id = `${year}-${String(i + 1).padStart(2, "0")}`;
|
|
1238
1671
|
const selected = id === value;
|
|
1239
1672
|
const disabled = Boolean(min && id < min || max && id > max);
|
|
1240
|
-
return /* @__PURE__ */
|
|
1241
|
-
|
|
1673
|
+
return /* @__PURE__ */ jsx16(
|
|
1674
|
+
Pressable9,
|
|
1242
1675
|
{
|
|
1243
1676
|
role: "radio",
|
|
1244
1677
|
"aria-checked": selected,
|
|
@@ -1249,8 +1682,8 @@ function MonthPicker({ locale, value, onValueChange, min, max, labels, style })
|
|
|
1249
1682
|
haptic("selection");
|
|
1250
1683
|
onValueChange?.(id);
|
|
1251
1684
|
},
|
|
1252
|
-
style: ({ pressed }) => [
|
|
1253
|
-
children: /* @__PURE__ */
|
|
1685
|
+
style: ({ pressed }) => [styles15.month, { borderRadius: radius3.lg, backgroundColor: selected ? theme.accent : pressed ? theme.surface3 : "transparent" }, disabled ? styles15.disabled : null],
|
|
1686
|
+
children: /* @__PURE__ */ jsx16(Text11, { style: [styles15.monthText, { color: selected ? theme.onAccent : theme.textPrimary, fontWeight: selected ? "700" : "500" }], children: name })
|
|
1254
1687
|
},
|
|
1255
1688
|
id
|
|
1256
1689
|
);
|
|
@@ -1264,13 +1697,13 @@ function DayStrip({ label, locale, value: valueProp, defaultValue = null, onValu
|
|
|
1264
1697
|
const [value, setValue] = useOwn(valueProp, defaultValue);
|
|
1265
1698
|
const weekday = new Intl.DateTimeFormat(locale, { weekday: "short" });
|
|
1266
1699
|
const list = Array.from({ length: days }, (_, i) => addDays(first, i));
|
|
1267
|
-
return /* @__PURE__ */
|
|
1700
|
+
return /* @__PURE__ */ jsx16(ScrollView4, { horizontal: true, showsHorizontalScrollIndicator: false, role: "radiogroup", "aria-label": label, contentContainerStyle: styles15.strip, style, children: list.map((iso) => {
|
|
1268
1701
|
const selected = iso === value;
|
|
1269
1702
|
const disabled = Boolean(isDateDisabled?.(iso));
|
|
1270
1703
|
const marked = Boolean(isDateMarked?.(iso));
|
|
1271
1704
|
const name = longDate(locale, iso);
|
|
1272
|
-
return /* @__PURE__ */
|
|
1273
|
-
|
|
1705
|
+
return /* @__PURE__ */ jsxs13(
|
|
1706
|
+
Pressable9,
|
|
1274
1707
|
{
|
|
1275
1708
|
role: "radio",
|
|
1276
1709
|
"aria-checked": selected,
|
|
@@ -1284,7 +1717,7 @@ function DayStrip({ label, locale, value: valueProp, defaultValue = null, onValu
|
|
|
1284
1717
|
onValueChange?.(iso);
|
|
1285
1718
|
},
|
|
1286
1719
|
style: ({ pressed }) => [
|
|
1287
|
-
|
|
1720
|
+
styles15.stripDay,
|
|
1288
1721
|
{
|
|
1289
1722
|
borderRadius: radius3.xl,
|
|
1290
1723
|
backgroundColor: selected ? theme.accent : disabled ? "transparent" : theme.surface2,
|
|
@@ -1294,10 +1727,10 @@ function DayStrip({ label, locale, value: valueProp, defaultValue = null, onValu
|
|
|
1294
1727
|
}
|
|
1295
1728
|
],
|
|
1296
1729
|
children: [
|
|
1297
|
-
iso === today ? /* @__PURE__ */
|
|
1298
|
-
/* @__PURE__ */
|
|
1299
|
-
/* @__PURE__ */
|
|
1300
|
-
/* @__PURE__ */
|
|
1730
|
+
iso === today ? /* @__PURE__ */ jsx16(Node, { color: selected ? theme.onAccent : theme.accent, style: styles15.stripNode }) : null,
|
|
1731
|
+
/* @__PURE__ */ jsx16(Text11, { style: [styles15.stripWeekday, { color: selected ? theme.onAccent : disabled ? theme.textMuted : theme.textSecondary }], children: weekday.format(toLocalDate(iso)).replace(/\.$/, "").toUpperCase() }),
|
|
1732
|
+
/* @__PURE__ */ jsx16(Text11, { style: [styles15.stripNumber, { color: selected ? theme.onAccent : disabled ? theme.textMuted : theme.textPrimary }], children: Number(iso.slice(8)) }),
|
|
1733
|
+
/* @__PURE__ */ jsx16(View12, { style: [styles15.dot, marked ? { backgroundColor: selected ? theme.onAccent : theme.textSecondary } : null] })
|
|
1301
1734
|
]
|
|
1302
1735
|
},
|
|
1303
1736
|
iso
|
|
@@ -1312,11 +1745,11 @@ function TimePicker({ label, locale, value: valueProp, defaultValue = null, onVa
|
|
|
1312
1745
|
onValueChange?.(next);
|
|
1313
1746
|
};
|
|
1314
1747
|
if (variant === "slots")
|
|
1315
|
-
return /* @__PURE__ */
|
|
1748
|
+
return /* @__PURE__ */ jsx16(View12, { role: "radiogroup", "aria-label": label, style: [styles15.slots, style], children: slots.map((t) => {
|
|
1316
1749
|
const selected = t === value;
|
|
1317
1750
|
const off = disabled || Boolean(isTimeDisabled?.(t));
|
|
1318
|
-
return /* @__PURE__ */
|
|
1319
|
-
|
|
1751
|
+
return /* @__PURE__ */ jsx16(
|
|
1752
|
+
Pressable9,
|
|
1320
1753
|
{
|
|
1321
1754
|
role: "radio",
|
|
1322
1755
|
"aria-checked": selected,
|
|
@@ -1328,7 +1761,7 @@ function TimePicker({ label, locale, value: valueProp, defaultValue = null, onVa
|
|
|
1328
1761
|
set(t);
|
|
1329
1762
|
},
|
|
1330
1763
|
style: ({ pressed }) => [
|
|
1331
|
-
|
|
1764
|
+
styles15.slot,
|
|
1332
1765
|
{
|
|
1333
1766
|
borderRadius: radius3.lg,
|
|
1334
1767
|
backgroundColor: selected ? theme.accent : off ? "transparent" : theme.surface2,
|
|
@@ -1337,7 +1770,7 @@ function TimePicker({ label, locale, value: valueProp, defaultValue = null, onVa
|
|
|
1337
1770
|
transform: [{ scale: pressed ? 0.97 : 1 }]
|
|
1338
1771
|
}
|
|
1339
1772
|
],
|
|
1340
|
-
children: /* @__PURE__ */
|
|
1773
|
+
children: /* @__PURE__ */ jsx16(Text11, { style: [styles15.slotText, { color: selected ? theme.onAccent : off ? theme.textMuted : theme.textPrimary, textDecorationLine: off ? "line-through" : "none" }], children: formatTime(locale, t) })
|
|
1341
1774
|
},
|
|
1342
1775
|
t
|
|
1343
1776
|
);
|
|
@@ -1353,11 +1786,11 @@ function TimePicker({ label, locale, value: valueProp, defaultValue = null, onVa
|
|
|
1353
1786
|
const hours = twelve ? [12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((h) => ({ value: String(h), label: String(h) })) : Array.from({ length: 24 }, (_, h) => ({ value: String(h), label: two(h) }));
|
|
1354
1787
|
const minutes = Array.from({ length: Math.ceil(60 / minuteStep) }, (_, i) => ({ value: String(i * minuteStep), label: two(i * minuteStep) }));
|
|
1355
1788
|
const [am, pmLabel] = dayPeriods(locale);
|
|
1356
|
-
return /* @__PURE__ */
|
|
1357
|
-
/* @__PURE__ */
|
|
1358
|
-
/* @__PURE__ */
|
|
1359
|
-
/* @__PURE__ */
|
|
1360
|
-
twelve ? /* @__PURE__ */
|
|
1789
|
+
return /* @__PURE__ */ jsxs13(WheelPicker, { label: value ? `${label}, ${formatTime(locale, value)}` : label, style, children: [
|
|
1790
|
+
/* @__PURE__ */ jsx16(Wheel, { label: labels.hours, options: hours, disabled, value: twelve ? String(h24 % 12 === 0 ? 12 : h24 % 12) : String(h24), onValueChange: (v) => put(twelve ? Number(v) % 12 + (pm ? 12 : 0) : Number(v), minute) }),
|
|
1791
|
+
/* @__PURE__ */ jsx16(WheelDivider, { children: ":" }),
|
|
1792
|
+
/* @__PURE__ */ jsx16(Wheel, { label: labels.minutes, options: minutes, disabled, value: String(Math.min(60 - minuteStep, Math.round(minute / minuteStep) * minuteStep)), onValueChange: (v) => put(h24, Number(v)) }),
|
|
1793
|
+
twelve ? /* @__PURE__ */ jsx16(
|
|
1361
1794
|
Wheel,
|
|
1362
1795
|
{
|
|
1363
1796
|
label: labels.period,
|
|
@@ -1390,22 +1823,22 @@ function DateWheel({ label, locale, value: valueProp, defaultValue = null, onVal
|
|
|
1390
1823
|
};
|
|
1391
1824
|
const last = daysInMonth(year, month);
|
|
1392
1825
|
const columns = {
|
|
1393
|
-
day: /* @__PURE__ */
|
|
1394
|
-
month: /* @__PURE__ */
|
|
1395
|
-
year: /* @__PURE__ */
|
|
1826
|
+
day: /* @__PURE__ */ jsx16(Wheel, { label: names.day, disabled, options: Array.from({ length: last }, (_, i) => ({ value: String(i + 1), label: String(i + 1), disabled: isoOf(year, month, i + 1) > hi || isoOf(year, month, i + 1) < lo })), value: String(Math.min(day, last)), onValueChange: (v) => set(year, month, Number(v)), style: styles15.dayWheel }, "day"),
|
|
1827
|
+
month: /* @__PURE__ */ jsx16(Wheel, { label: names.month, disabled, options: months.map((n, i) => ({ value: String(i + 1), label: n, disabled: isoOf(year, i + 1, 1) > hi || isoOf(year, i + 1, daysInMonth(year, i + 1)) < lo })), value: String(month), onValueChange: (v) => set(year, Number(v), day), style: styles15.monthWheel }, "month"),
|
|
1828
|
+
year: /* @__PURE__ */ jsx16(Wheel, { label: names.year, disabled, options: yearRange(Number(hi.slice(0, 4)), Number(lo.slice(0, 4))).map((y) => ({ value: String(y), label: String(y) })), value: String(year), onValueChange: (v) => set(Number(v), month, day), style: styles15.yearWheel }, "year")
|
|
1396
1829
|
};
|
|
1397
1830
|
const caption = error ?? hint;
|
|
1398
|
-
return /* @__PURE__ */
|
|
1399
|
-
/* @__PURE__ */
|
|
1400
|
-
/* @__PURE__ */
|
|
1401
|
-
caption ? /* @__PURE__ */
|
|
1831
|
+
return /* @__PURE__ */ jsxs13(View12, { style: [styles15.field, style], children: [
|
|
1832
|
+
/* @__PURE__ */ jsx16(Text11, { "aria-hidden": true, style: [styles15.fieldLabel, { color: theme.textSecondary }], children: label }),
|
|
1833
|
+
/* @__PURE__ */ jsx16(WheelPicker, { label, invalid: Boolean(error), unset: !value, children: datePartsOrder(locale).map((part) => columns[part]) }),
|
|
1834
|
+
caption ? /* @__PURE__ */ jsx16(Text11, { role: error ? "alert" : void 0, "aria-live": error ? "polite" : void 0, style: [styles15.caption, { color: error ? theme.dangerText : theme.textSecondary }], children: caption }) : null
|
|
1402
1835
|
] });
|
|
1403
1836
|
}
|
|
1404
|
-
var
|
|
1405
|
-
calendar: { padding: 12, gap: 4, borderWidth:
|
|
1837
|
+
var styles15 = StyleSheet15.create({
|
|
1838
|
+
calendar: { padding: 12, gap: 4, borderWidth: StyleSheet15.hairlineWidth, alignSelf: "flex-start" },
|
|
1406
1839
|
header: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", marginBottom: 6, gap: 8 },
|
|
1407
1840
|
title: { fontSize: 15, fontWeight: "700", textTransform: "capitalize" },
|
|
1408
|
-
nav: { width: 36, height: 36, alignItems: "center", justifyContent: "center", borderWidth:
|
|
1841
|
+
nav: { width: 36, height: 36, alignItems: "center", justifyContent: "center", borderWidth: StyleSheet15.hairlineWidth },
|
|
1409
1842
|
week: { flexDirection: "row" },
|
|
1410
1843
|
weekday: { width: 44, textAlign: "center", fontSize: 11, fontWeight: "700", paddingBottom: 4 },
|
|
1411
1844
|
cell: { width: 44, height: 44, marginVertical: 1 },
|
|
@@ -1434,39 +1867,115 @@ var styles11 = StyleSheet11.create({
|
|
|
1434
1867
|
disabled: { opacity: 0.4 }
|
|
1435
1868
|
});
|
|
1436
1869
|
|
|
1437
|
-
// src/native/
|
|
1438
|
-
import { StyleSheet as
|
|
1439
|
-
import { jsx as
|
|
1440
|
-
function
|
|
1441
|
-
const { theme } = useTheme();
|
|
1442
|
-
return /* @__PURE__ */
|
|
1443
|
-
|
|
1444
|
-
/* @__PURE__ */
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1870
|
+
// src/native/description-list.tsx
|
|
1871
|
+
import { StyleSheet as StyleSheet16, View as View13 } from "react-native";
|
|
1872
|
+
import { jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1873
|
+
function DescriptionList({ items: items2, layout = "stacked", style }) {
|
|
1874
|
+
const { theme, radius: radius3 } = useTheme();
|
|
1875
|
+
return /* @__PURE__ */ jsx17(View13, { role: "list", style: [layout === "grid" ? styles16.grid : layout === "inline" ? null : styles16.stacked, style], children: items2.map((item, i) => {
|
|
1876
|
+
const value = typeof item.details === "string" || typeof item.details === "number" ? /* @__PURE__ */ jsx17(Txt, { variant: layout === "grid" ? "title" : "body", style: layout === "inline" ? styles16.right : null, children: item.details }) : item.details;
|
|
1877
|
+
return /* @__PURE__ */ jsxs14(
|
|
1878
|
+
View13,
|
|
1879
|
+
{
|
|
1880
|
+
role: "listitem",
|
|
1881
|
+
accessible: true,
|
|
1882
|
+
style: [
|
|
1883
|
+
layout === "inline" ? [styles16.inline, i > 0 ? { borderTopWidth: StyleSheet16.hairlineWidth, borderTopColor: theme.borderSubtle } : null] : null,
|
|
1884
|
+
layout === "grid" ? [styles16.card, { backgroundColor: theme.surface1, borderColor: theme.borderDefault, borderRadius: radius3.lg }] : null
|
|
1885
|
+
],
|
|
1886
|
+
children: [
|
|
1887
|
+
/* @__PURE__ */ jsx17(Txt, { variant: "caption", tone: "secondary", style: layout === "grid" ? styles16.upper : null, children: item.term }),
|
|
1888
|
+
/* @__PURE__ */ jsxs14(View13, { style: layout === "inline" ? styles16.valueInline : styles16.value, children: [
|
|
1889
|
+
value,
|
|
1890
|
+
item.hint ? /* @__PURE__ */ jsx17(Txt, { variant: "caption", tone: "secondary", style: layout === "inline" ? styles16.right : null, children: item.hint }) : null
|
|
1891
|
+
] })
|
|
1892
|
+
]
|
|
1893
|
+
},
|
|
1894
|
+
item.id ?? item.term
|
|
1895
|
+
);
|
|
1896
|
+
}) });
|
|
1897
|
+
}
|
|
1898
|
+
var styles16 = StyleSheet16.create({
|
|
1899
|
+
stacked: { gap: 14 },
|
|
1900
|
+
inline: { flexDirection: "row", alignItems: "baseline", justifyContent: "space-between", gap: 16, paddingVertical: 10 },
|
|
1901
|
+
grid: { flexDirection: "row", flexWrap: "wrap", gap: 10 },
|
|
1902
|
+
card: { flexBasis: "47%", flexGrow: 1, padding: 12, gap: 4, borderWidth: StyleSheet16.hairlineWidth },
|
|
1903
|
+
upper: { textTransform: "uppercase", letterSpacing: 0.6, fontWeight: "700" },
|
|
1904
|
+
value: { gap: 2, marginTop: 2 },
|
|
1905
|
+
valueInline: { flexShrink: 1, alignItems: "flex-end", gap: 2 },
|
|
1906
|
+
right: { textAlign: "right" }
|
|
1907
|
+
});
|
|
1908
|
+
|
|
1909
|
+
// src/native/empty-state.tsx
|
|
1910
|
+
import { StyleSheet as StyleSheet17, View as View14 } from "react-native";
|
|
1911
|
+
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1912
|
+
function EmptyState({ icon, title, description, action, style, ...props }) {
|
|
1913
|
+
const { theme } = useTheme();
|
|
1914
|
+
return /* @__PURE__ */ jsxs15(View14, { ...props, style: [styles17.root, style], children: [
|
|
1915
|
+
icon ? /* @__PURE__ */ jsx18(View14, { "aria-hidden": true, style: [styles17.icon, { backgroundColor: theme.surface2 }], children: icon }) : null,
|
|
1916
|
+
/* @__PURE__ */ jsx18(Txt, { variant: "label", role: "heading", style: styles17.center, children: title }),
|
|
1917
|
+
description ? /* @__PURE__ */ jsx18(Txt, { tone: "secondary", style: styles17.center, children: description }) : null,
|
|
1918
|
+
action ? /* @__PURE__ */ jsx18(View14, { style: styles17.action, children: action }) : null
|
|
1919
|
+
] });
|
|
1920
|
+
}
|
|
1921
|
+
var styles17 = StyleSheet17.create({
|
|
1922
|
+
root: { alignItems: "center", justifyContent: "center", gap: 8, paddingVertical: 40, paddingHorizontal: 24 },
|
|
1923
|
+
icon: { width: 48, height: 48, borderRadius: 24, alignItems: "center", justifyContent: "center", marginBottom: 4 },
|
|
1924
|
+
center: { textAlign: "center", maxWidth: 360 },
|
|
1453
1925
|
action: { marginTop: 8, flexDirection: "row", flexWrap: "wrap", justifyContent: "center", gap: 8 }
|
|
1454
1926
|
});
|
|
1455
1927
|
|
|
1928
|
+
// src/native/fab.tsx
|
|
1929
|
+
import { Pressable as Pressable10, StyleSheet as StyleSheet18, View as View15 } from "react-native";
|
|
1930
|
+
import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1931
|
+
function Fab({ label, icon, onPress, extended, placement = "end", offset = 0, style }) {
|
|
1932
|
+
const { theme, insets, haptic } = useTheme();
|
|
1933
|
+
const position = placement === "center" ? { alignSelf: "center" } : placement === "start" ? { left: 16 + insets.left } : { right: 16 + insets.right };
|
|
1934
|
+
return /* @__PURE__ */ jsx19(View15, { pointerEvents: "box-none", style: [styles18.layer, placement === "center" ? styles18.centre : null], children: /* @__PURE__ */ jsxs16(
|
|
1935
|
+
Pressable10,
|
|
1936
|
+
{
|
|
1937
|
+
role: "button",
|
|
1938
|
+
"aria-label": label,
|
|
1939
|
+
onPress: () => {
|
|
1940
|
+
haptic("impact");
|
|
1941
|
+
onPress();
|
|
1942
|
+
},
|
|
1943
|
+
style: ({ pressed }) => [
|
|
1944
|
+
styles18.fab,
|
|
1945
|
+
extended ? styles18.extended : null,
|
|
1946
|
+
position,
|
|
1947
|
+
{ bottom: 16 + insets.bottom + offset, backgroundColor: pressed ? theme.accentHover : theme.accent, borderTopColor: theme.edgeOnFill, shadowColor: theme.scrimStrong },
|
|
1948
|
+
style
|
|
1949
|
+
],
|
|
1950
|
+
children: [
|
|
1951
|
+
/* @__PURE__ */ jsx19(View15, { "aria-hidden": true, children: icon }),
|
|
1952
|
+
extended ? /* @__PURE__ */ jsx19(Txt, { variant: "label", tone: "onAccent", "aria-hidden": true, numberOfLines: 1, style: styles18.label, children: label }) : null
|
|
1953
|
+
]
|
|
1954
|
+
}
|
|
1955
|
+
) });
|
|
1956
|
+
}
|
|
1957
|
+
var styles18 = StyleSheet18.create({
|
|
1958
|
+
layer: { position: "absolute", top: 0, right: 0, bottom: 0, left: 0 },
|
|
1959
|
+
centre: { alignItems: "center" },
|
|
1960
|
+
fab: { borderTopWidth: 1, borderColor: "transparent", position: "absolute", minWidth: 56, height: 56, borderRadius: 28, alignItems: "center", justifyContent: "center", flexDirection: "row", gap: 8, shadowOpacity: 0.3, shadowRadius: 12, shadowOffset: { width: 0, height: 6 }, elevation: 6 },
|
|
1961
|
+
extended: { paddingHorizontal: 20 },
|
|
1962
|
+
label: { flexShrink: 0 }
|
|
1963
|
+
});
|
|
1964
|
+
|
|
1456
1965
|
// src/native/field.tsx
|
|
1457
|
-
import * as
|
|
1458
|
-
import { StyleSheet as
|
|
1459
|
-
import { jsx as
|
|
1966
|
+
import * as React15 from "react";
|
|
1967
|
+
import { StyleSheet as StyleSheet19, Text as Text12, TextInput as TextInput3, View as View16 } from "react-native";
|
|
1968
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1460
1969
|
function TextField({ label, hint, error, value, defaultValue, onValueChange, disabled, end, inputRef, style, multiline, onFocus, onBlur, ...props }) {
|
|
1461
1970
|
const { theme, radius: radius3 } = useTheme();
|
|
1462
|
-
const [focused, setFocused] =
|
|
1971
|
+
const [focused, setFocused] = React15.useState(false);
|
|
1463
1972
|
const caption = error ?? hint;
|
|
1464
1973
|
const border = error ? theme.danger : focused ? theme.accent : theme.borderDefault;
|
|
1465
|
-
return /* @__PURE__ */
|
|
1466
|
-
/* @__PURE__ */
|
|
1467
|
-
/* @__PURE__ */
|
|
1468
|
-
/* @__PURE__ */
|
|
1469
|
-
|
|
1974
|
+
return /* @__PURE__ */ jsxs17(View16, { style: [styles19.root, disabled ? styles19.disabled : null, style], children: [
|
|
1975
|
+
/* @__PURE__ */ jsx20(Text12, { style: [styles19.label, { color: theme.textSecondary }], children: label }),
|
|
1976
|
+
/* @__PURE__ */ jsxs17(View16, { style: [styles19.frame, multiline ? styles19.multiline : null, { borderRadius: radius3.md, borderColor: border, backgroundColor: theme.surface2 }], children: [
|
|
1977
|
+
/* @__PURE__ */ jsx20(
|
|
1978
|
+
TextInput3,
|
|
1470
1979
|
{
|
|
1471
1980
|
ref: inputRef,
|
|
1472
1981
|
"aria-label": label,
|
|
@@ -1487,16 +1996,16 @@ function TextField({ label, hint, error, value, defaultValue, onValueChange, dis
|
|
|
1487
1996
|
setFocused(false);
|
|
1488
1997
|
onBlur?.(event);
|
|
1489
1998
|
},
|
|
1490
|
-
style: [
|
|
1999
|
+
style: [styles19.input, multiline ? styles19.inputMultiline : null, { color: theme.textPrimary }],
|
|
1491
2000
|
...props
|
|
1492
2001
|
}
|
|
1493
2002
|
),
|
|
1494
|
-
end ? /* @__PURE__ */
|
|
2003
|
+
end ? /* @__PURE__ */ jsx20(View16, { style: styles19.end, children: end }) : null
|
|
1495
2004
|
] }),
|
|
1496
|
-
caption ? /* @__PURE__ */
|
|
2005
|
+
caption ? /* @__PURE__ */ jsx20(Text12, { role: error ? "alert" : void 0, "aria-live": error ? "polite" : void 0, style: [styles19.caption, { color: error ? theme.dangerText : theme.textSecondary }], children: caption }) : null
|
|
1497
2006
|
] });
|
|
1498
2007
|
}
|
|
1499
|
-
var
|
|
2008
|
+
var styles19 = StyleSheet19.create({
|
|
1500
2009
|
root: { gap: 6, alignSelf: "stretch" },
|
|
1501
2010
|
label: { fontSize: 12, lineHeight: 16, fontWeight: "600" },
|
|
1502
2011
|
frame: { flexDirection: "row", alignItems: "center", minHeight: 44, paddingHorizontal: 12, borderWidth: 1 },
|
|
@@ -1509,20 +2018,20 @@ var styles13 = StyleSheet13.create({
|
|
|
1509
2018
|
});
|
|
1510
2019
|
|
|
1511
2020
|
// src/native/goal-gauge.tsx
|
|
1512
|
-
import { Animated as
|
|
2021
|
+
import { Animated as Animated5, StyleSheet as StyleSheet20, View as View17 } from "react-native";
|
|
1513
2022
|
|
|
1514
2023
|
// src/native/story-motion.ts
|
|
1515
|
-
import * as
|
|
1516
|
-
import { AccessibilityInfo as
|
|
2024
|
+
import * as React16 from "react";
|
|
2025
|
+
import { AccessibilityInfo as AccessibilityInfo3, Animated as Animated4, Easing } from "react-native";
|
|
1517
2026
|
function useEntrance(animated, delay = 0, duration = 700) {
|
|
1518
|
-
const [value] =
|
|
1519
|
-
|
|
2027
|
+
const [value] = React16.useState(() => new Animated4.Value(animated ? 0 : 1));
|
|
2028
|
+
React16.useEffect(() => {
|
|
1520
2029
|
if (!animated) return;
|
|
1521
2030
|
let cancelled = false;
|
|
1522
|
-
void
|
|
2031
|
+
void AccessibilityInfo3.isReduceMotionEnabled().then((reduce) => {
|
|
1523
2032
|
if (cancelled) return;
|
|
1524
2033
|
if (reduce) value.setValue(1);
|
|
1525
|
-
else
|
|
2034
|
+
else Animated4.timing(value, { toValue: 1, duration, delay, easing: Easing.out(Easing.cubic), useNativeDriver: true }).start();
|
|
1526
2035
|
});
|
|
1527
2036
|
return () => {
|
|
1528
2037
|
cancelled = true;
|
|
@@ -1532,17 +2041,17 @@ function useEntrance(animated, delay = 0, duration = 700) {
|
|
|
1532
2041
|
}
|
|
1533
2042
|
|
|
1534
2043
|
// src/native/goal-gauge.tsx
|
|
1535
|
-
import { jsx as
|
|
2044
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1536
2045
|
function Cell({ lit, animate, order, animated, arcade }) {
|
|
1537
2046
|
const { theme } = useTheme();
|
|
1538
2047
|
const t = useEntrance(animated && animate, 300 + order * 100, 350);
|
|
1539
2048
|
const spentOpacity = arcade ? 0.14 : 1;
|
|
1540
2049
|
const opacity = !animate ? 1 : lit ? t.interpolate({ inputRange: [0, 1], outputRange: [0.25, 1] }) : t.interpolate({ inputRange: [0, 1], outputRange: [1, arcade ? 0.14 : 1] });
|
|
1541
2050
|
const color = lit || arcade ? theme.accent : theme.surface3;
|
|
1542
|
-
return /* @__PURE__ */
|
|
1543
|
-
|
|
2051
|
+
return /* @__PURE__ */ jsx21(
|
|
2052
|
+
Animated5.View,
|
|
1544
2053
|
{
|
|
1545
|
-
style: [
|
|
2054
|
+
style: [styles20.cell, arcade ? styles20.cellArcade : null, { backgroundColor: color, opacity: lit || animate ? opacity : spentOpacity }]
|
|
1546
2055
|
}
|
|
1547
2056
|
);
|
|
1548
2057
|
}
|
|
@@ -1552,8 +2061,8 @@ function GoalGauge({ label, segments, value, valueText, mode = "fill", showLabel
|
|
|
1552
2061
|
const lit = Math.min(total, Math.max(0, Math.round(value ?? total)));
|
|
1553
2062
|
const words = valueText ?? `${lit} / ${total}`;
|
|
1554
2063
|
const arcade = variant === "arcade";
|
|
1555
|
-
return /* @__PURE__ */
|
|
1556
|
-
|
|
2064
|
+
return /* @__PURE__ */ jsxs18(
|
|
2065
|
+
View17,
|
|
1557
2066
|
{
|
|
1558
2067
|
accessible: true,
|
|
1559
2068
|
role: "meter",
|
|
@@ -1563,22 +2072,22 @@ function GoalGauge({ label, segments, value, valueText, mode = "fill", showLabel
|
|
|
1563
2072
|
"aria-valuenow": lit,
|
|
1564
2073
|
"aria-valuetext": words,
|
|
1565
2074
|
...props,
|
|
1566
|
-
style: [
|
|
2075
|
+
style: [styles20.root, style],
|
|
1567
2076
|
children: [
|
|
1568
|
-
showLabel ? /* @__PURE__ */
|
|
1569
|
-
/* @__PURE__ */
|
|
1570
|
-
arcade ? null : /* @__PURE__ */
|
|
2077
|
+
showLabel ? /* @__PURE__ */ jsxs18(View17, { "aria-hidden": true, style: [styles20.head, arcade ? styles20.headArcade : null], children: [
|
|
2078
|
+
/* @__PURE__ */ jsx21(Txt, { variant: arcade ? "mono" : "caption", tone: "secondary", children: arcade ? label.toUpperCase() : label }),
|
|
2079
|
+
arcade ? null : /* @__PURE__ */ jsx21(Txt, { variant: "caption", children: words })
|
|
1571
2080
|
] }) : null,
|
|
1572
|
-
/* @__PURE__ */
|
|
2081
|
+
/* @__PURE__ */ jsx21(View17, { "aria-hidden": true, style: [styles20.cells, arcade ? [styles20.cellsArcade, { borderColor: theme.borderSubtle, backgroundColor: theme.surface1 }] : null], children: Array.from({ length: total }, (_, i) => {
|
|
1573
2082
|
const on = i < lit;
|
|
1574
2083
|
const animate = mode === "fill" ? on : !on;
|
|
1575
|
-
return /* @__PURE__ */
|
|
2084
|
+
return /* @__PURE__ */ jsx21(Cell, { lit: on, animate, order: mode === "fill" ? i : i - lit, animated, arcade }, i);
|
|
1576
2085
|
}) })
|
|
1577
2086
|
]
|
|
1578
2087
|
}
|
|
1579
2088
|
);
|
|
1580
2089
|
}
|
|
1581
|
-
var
|
|
2090
|
+
var styles20 = StyleSheet20.create({
|
|
1582
2091
|
root: { alignSelf: "stretch", gap: 8 },
|
|
1583
2092
|
head: { flexDirection: "row", justifyContent: "space-between", alignItems: "baseline", gap: 12 },
|
|
1584
2093
|
headArcade: { justifyContent: "center" },
|
|
@@ -1588,9 +2097,190 @@ var styles14 = StyleSheet14.create({
|
|
|
1588
2097
|
cellArcade: { height: 10, borderRadius: 1 }
|
|
1589
2098
|
});
|
|
1590
2099
|
|
|
2100
|
+
// src/native/header.tsx
|
|
2101
|
+
import * as React17 from "react";
|
|
2102
|
+
import { Animated as Animated6, Pressable as Pressable11, StyleSheet as StyleSheet21, View as View18 } from "react-native";
|
|
2103
|
+
import Svg6, { Path as Path4 } from "react-native-svg";
|
|
2104
|
+
import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
2105
|
+
var BAR = 44;
|
|
2106
|
+
var LARGE = 52;
|
|
2107
|
+
function Header({ title, subtitle, scrollY, size = "large", backLabel, onBack, actions, children, style }) {
|
|
2108
|
+
const { theme, insets } = useTheme();
|
|
2109
|
+
const reduce = useReducedMotion();
|
|
2110
|
+
const large = size === "large";
|
|
2111
|
+
const fixed = React17.useMemo(() => new Animated6.Value(large ? 0 : 1), [large]);
|
|
2112
|
+
const progress = scrollY && large ? scrollY.interpolate({ inputRange: [0, LARGE], outputRange: [0, 1], extrapolate: "clamp" }) : fixed;
|
|
2113
|
+
const smallOpacity = progress.interpolate({ inputRange: [0.6, 1], outputRange: [0, 1], extrapolate: "clamp" });
|
|
2114
|
+
const largeOpacity = progress.interpolate({ inputRange: [0, 0.7], outputRange: [1, 0], extrapolate: "clamp" });
|
|
2115
|
+
const largeShift = reduce ? 0 : progress.interpolate({ inputRange: [0, 1], outputRange: [0, -10] });
|
|
2116
|
+
const largeHeight = progress.interpolate({ inputRange: [0, 1], outputRange: [LARGE + (subtitle ? 18 : 0), 0] });
|
|
2117
|
+
return /* @__PURE__ */ jsxs19(View18, { style: [{ paddingTop: insets.top, backgroundColor: theme.surface0 }, style], children: [
|
|
2118
|
+
/* @__PURE__ */ jsxs19(View18, { style: styles21.bar, children: [
|
|
2119
|
+
/* @__PURE__ */ jsx22(View18, { style: styles21.side, children: onBack && backLabel ? /* @__PURE__ */ jsxs19(Pressable11, { role: "button", "aria-label": backLabel, onPress: onBack, hitSlop: 8, style: styles21.back, children: [
|
|
2120
|
+
/* @__PURE__ */ jsx22(Svg6, { width: 22, height: 22, viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsx22(Path4, { d: "M15 5l-7 7 7 7", stroke: theme.accentText, strokeWidth: 2.4, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
2121
|
+
/* @__PURE__ */ jsx22(Txt, { variant: "label", tone: "accent", numberOfLines: 1, children: backLabel })
|
|
2122
|
+
] }) : null }),
|
|
2123
|
+
/* @__PURE__ */ jsx22(Animated6.View, { style: [styles21.middle, { opacity: smallOpacity }], "aria-hidden": large, children: /* @__PURE__ */ jsx22(Txt, { variant: "label", numberOfLines: 1, role: large ? void 0 : "heading", children: title }) }),
|
|
2124
|
+
/* @__PURE__ */ jsx22(View18, { style: [styles21.side, styles21.right], children: actions })
|
|
2125
|
+
] }),
|
|
2126
|
+
large ? /* @__PURE__ */ jsx22(Animated6.View, { style: { height: largeHeight, overflow: "hidden" }, children: /* @__PURE__ */ jsxs19(Animated6.View, { style: [styles21.large, { opacity: largeOpacity, transform: [{ translateY: largeShift }] }], children: [
|
|
2127
|
+
/* @__PURE__ */ jsx22(Txt, { variant: "display", numberOfLines: 1, role: "heading", style: styles21.largeTitle, children: title }),
|
|
2128
|
+
subtitle ? /* @__PURE__ */ jsx22(Txt, { variant: "caption", tone: "secondary", children: subtitle }) : null
|
|
2129
|
+
] }) }) : null,
|
|
2130
|
+
children ? /* @__PURE__ */ jsx22(View18, { style: styles21.children, children }) : null,
|
|
2131
|
+
/* @__PURE__ */ jsx22(Animated6.View, { "aria-hidden": true, style: [styles21.rule, { backgroundColor: theme.borderSubtle, opacity: smallOpacity }] })
|
|
2132
|
+
] });
|
|
2133
|
+
}
|
|
2134
|
+
function useCollapsingHeader() {
|
|
2135
|
+
const [scrollY] = React17.useState(() => new Animated6.Value(0));
|
|
2136
|
+
const onScroll = React17.useMemo(() => Animated6.event([{ nativeEvent: { contentOffset: { y: scrollY } } }], { useNativeDriver: false }), [scrollY]);
|
|
2137
|
+
return { scrollY, onScroll };
|
|
2138
|
+
}
|
|
2139
|
+
var styles21 = StyleSheet21.create({
|
|
2140
|
+
bar: { height: BAR, flexDirection: "row", alignItems: "center", paddingHorizontal: 8 },
|
|
2141
|
+
side: { flex: 1, flexDirection: "row", alignItems: "center" },
|
|
2142
|
+
right: { justifyContent: "flex-end", gap: 4 },
|
|
2143
|
+
middle: { flex: 2, alignItems: "center" },
|
|
2144
|
+
back: { flexDirection: "row", alignItems: "center", gap: 2, minHeight: 44, paddingRight: 8 },
|
|
2145
|
+
large: { paddingHorizontal: 16, paddingBottom: 6 },
|
|
2146
|
+
largeTitle: { fontSize: 32, lineHeight: 40 },
|
|
2147
|
+
children: { paddingHorizontal: 16, paddingBottom: 8 },
|
|
2148
|
+
rule: { height: StyleSheet21.hairlineWidth }
|
|
2149
|
+
});
|
|
2150
|
+
|
|
2151
|
+
// src/native/image-viewer.tsx
|
|
2152
|
+
import * as React18 from "react";
|
|
2153
|
+
import { AccessibilityInfo as AccessibilityInfo4, Animated as Animated7, Image as Image3, Modal as Modal3, PanResponder, Pressable as Pressable12, StyleSheet as StyleSheet22, useWindowDimensions, View as View19 } from "react-native";
|
|
2154
|
+
import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
2155
|
+
var MAX_SCALE = 4;
|
|
2156
|
+
function ImageViewer({ images, index, onIndexChange, closeLabel, positionLabel = (n, total) => `${n} / ${total}` }) {
|
|
2157
|
+
const { theme, insets, haptic } = useTheme();
|
|
2158
|
+
const reduce = useReducedMotion();
|
|
2159
|
+
const { width, height } = useWindowDimensions();
|
|
2160
|
+
const open = index !== null && images[index] !== void 0;
|
|
2161
|
+
const [scale] = React18.useState(() => new Animated7.Value(1));
|
|
2162
|
+
const [pan] = React18.useState(() => new Animated7.ValueXY({ x: 0, y: 0 }));
|
|
2163
|
+
const [dismiss2] = React18.useState(() => new Animated7.Value(0));
|
|
2164
|
+
const state = React18.useRef({ scale: 1, x: 0, y: 0, pinch: 0, base: 1, lastTap: 0 });
|
|
2165
|
+
const reset = React18.useCallback(() => {
|
|
2166
|
+
state.current = { ...state.current, scale: 1, x: 0, y: 0 };
|
|
2167
|
+
scale.setValue(1);
|
|
2168
|
+
pan.setValue({ x: 0, y: 0 });
|
|
2169
|
+
dismiss2.setValue(0);
|
|
2170
|
+
}, [scale, pan, dismiss2]);
|
|
2171
|
+
React18.useEffect(() => {
|
|
2172
|
+
reset();
|
|
2173
|
+
if (open) AccessibilityInfo4.announceForAccessibility(`${images[index].alt}, ${positionLabel(index + 1, images.length)}`);
|
|
2174
|
+
}, [index]);
|
|
2175
|
+
const go = (to) => {
|
|
2176
|
+
if (to < 0 || to >= images.length) return;
|
|
2177
|
+
haptic("selection");
|
|
2178
|
+
onIndexChange(to);
|
|
2179
|
+
};
|
|
2180
|
+
const animateTo = (value, to) => reduce ? value.setValue(to) : Animated7.spring(value, { toValue: to, useNativeDriver: true, damping: 20 }).start();
|
|
2181
|
+
const distance = (touches) => Math.hypot(touches[0].pageX - touches[1].pageX, touches[0].pageY - touches[1].pageY);
|
|
2182
|
+
const responder = React18.useMemo(
|
|
2183
|
+
() => PanResponder.create({
|
|
2184
|
+
onStartShouldSetPanResponder: () => true,
|
|
2185
|
+
onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 4 || Math.abs(g.dy) > 4,
|
|
2186
|
+
onPanResponderGrant: (e) => {
|
|
2187
|
+
const now = Date.now();
|
|
2188
|
+
const s = state.current;
|
|
2189
|
+
if (e.nativeEvent.touches.length === 1 && now - s.lastTap < 280) {
|
|
2190
|
+
const next = s.scale > 1 ? 1 : 2.5;
|
|
2191
|
+
s.scale = next;
|
|
2192
|
+
s.x = 0;
|
|
2193
|
+
s.y = 0;
|
|
2194
|
+
animateTo(scale, next);
|
|
2195
|
+
pan.setValue({ x: 0, y: 0 });
|
|
2196
|
+
}
|
|
2197
|
+
s.lastTap = now;
|
|
2198
|
+
s.pinch = 0;
|
|
2199
|
+
},
|
|
2200
|
+
onPanResponderMove: (e, g) => {
|
|
2201
|
+
const s = state.current;
|
|
2202
|
+
const touches = e.nativeEvent.touches;
|
|
2203
|
+
if (touches.length === 2) {
|
|
2204
|
+
const d = distance(touches);
|
|
2205
|
+
if (!s.pinch) {
|
|
2206
|
+
s.pinch = d;
|
|
2207
|
+
s.base = s.scale;
|
|
2208
|
+
}
|
|
2209
|
+
s.scale = Math.min(MAX_SCALE, Math.max(1, s.base * (d / s.pinch)));
|
|
2210
|
+
scale.setValue(s.scale);
|
|
2211
|
+
return;
|
|
2212
|
+
}
|
|
2213
|
+
if (s.scale > 1) pan.setValue({ x: s.x + g.dx, y: s.y + g.dy });
|
|
2214
|
+
else if (Math.abs(g.dy) > Math.abs(g.dx)) dismiss2.setValue(Math.max(0, g.dy));
|
|
2215
|
+
else pan.setValue({ x: g.dx, y: 0 });
|
|
2216
|
+
},
|
|
2217
|
+
onPanResponderRelease: (_, g) => {
|
|
2218
|
+
const s = state.current;
|
|
2219
|
+
if (s.pinch) {
|
|
2220
|
+
s.pinch = 0;
|
|
2221
|
+
if (s.scale <= 1.02) reset();
|
|
2222
|
+
return;
|
|
2223
|
+
}
|
|
2224
|
+
if (s.scale > 1) {
|
|
2225
|
+
s.x += g.dx;
|
|
2226
|
+
s.y += g.dy;
|
|
2227
|
+
return;
|
|
2228
|
+
}
|
|
2229
|
+
if (g.dy > 120 || g.vy > 1.2) return onIndexChange(null);
|
|
2230
|
+
if (g.dx < -width / 4 || g.vx < -0.8) go((index ?? 0) + 1);
|
|
2231
|
+
else if (g.dx > width / 4 || g.vx > 0.8) go((index ?? 0) - 1);
|
|
2232
|
+
animateTo(dismiss2, 0);
|
|
2233
|
+
Animated7.spring(pan, { toValue: { x: 0, y: 0 }, useNativeDriver: true }).start();
|
|
2234
|
+
}
|
|
2235
|
+
}),
|
|
2236
|
+
[index, width, images.length]
|
|
2237
|
+
// eslint-disable-line react-hooks/exhaustive-deps -- the gesture reads refs
|
|
2238
|
+
);
|
|
2239
|
+
if (!open) return null;
|
|
2240
|
+
const image = images[index];
|
|
2241
|
+
const backdrop = dismiss2.interpolate({ inputRange: [0, height / 2], outputRange: [1, 0.3], extrapolate: "clamp" });
|
|
2242
|
+
return /* @__PURE__ */ jsxs20(Modal3, { ...modalName(image.alt), visible: true, transparent: true, animationType: reduce ? "none" : "fade", onRequestClose: () => onIndexChange(null), statusBarTranslucent: true, children: [
|
|
2243
|
+
/* @__PURE__ */ jsx23(Animated7.View, { style: [StyleSheet22.absoluteFill, { backgroundColor: theme.media, opacity: backdrop }] }),
|
|
2244
|
+
/* @__PURE__ */ jsx23(
|
|
2245
|
+
View19,
|
|
2246
|
+
{
|
|
2247
|
+
style: StyleSheet22.absoluteFill,
|
|
2248
|
+
accessible: true,
|
|
2249
|
+
role: "img",
|
|
2250
|
+
"aria-label": `${image.alt}, ${positionLabel(index + 1, images.length)}`,
|
|
2251
|
+
accessibilityActions: [{ name: "increment" }, { name: "decrement" }, { name: "escape" }],
|
|
2252
|
+
onAccessibilityAction: (e) => {
|
|
2253
|
+
const name = e.nativeEvent.actionName;
|
|
2254
|
+
if (name === "increment") go(index + 1);
|
|
2255
|
+
if (name === "decrement") go(index - 1);
|
|
2256
|
+
if (name === "escape") onIndexChange(null);
|
|
2257
|
+
},
|
|
2258
|
+
...responder.panHandlers,
|
|
2259
|
+
children: /* @__PURE__ */ jsx23(Animated7.View, { style: { width, height, transform: [{ translateX: pan.x }, { translateY: Animated7.add(pan.y, dismiss2) }, { scale }] }, children: /* @__PURE__ */ jsx23(Image3, { source: { uri: image.uri }, resizeMode: "contain", style: { width, height }, accessibilityIgnoresInvertColors: true }) })
|
|
2260
|
+
}
|
|
2261
|
+
),
|
|
2262
|
+
/* @__PURE__ */ jsxs20(View19, { pointerEvents: "box-none", style: [styles22.top, { paddingTop: insets.top + 8 }], children: [
|
|
2263
|
+
/* @__PURE__ */ jsx23(View19, { "aria-hidden": true, style: [styles22.counter, { backgroundColor: theme.scrimStrong }], children: /* @__PURE__ */ jsx23(Txt, { variant: "label", tone: "onMedia", children: positionLabel(index + 1, images.length) }) }),
|
|
2264
|
+
/* @__PURE__ */ jsx23(Pressable12, { role: "button", "aria-label": closeLabel, hitSlop: 12, onPress: () => onIndexChange(null), style: [styles22.close, { backgroundColor: theme.scrimStrong }], children: /* @__PURE__ */ jsx23(Txt, { tone: "onMedia", style: styles22.cross, "aria-hidden": true, children: "\xD7" }) })
|
|
2265
|
+
] }),
|
|
2266
|
+
image.caption ? /* @__PURE__ */ jsx23(View19, { pointerEvents: "none", style: [styles22.caption, { paddingBottom: insets.bottom + 16, backgroundColor: theme.scrimStrong }], children: /* @__PURE__ */ jsx23(Txt, { tone: "onMedia", children: image.caption }) }) : null
|
|
2267
|
+
] });
|
|
2268
|
+
}
|
|
2269
|
+
function prefetchNeighbours(images, index) {
|
|
2270
|
+
if (index === null) return;
|
|
2271
|
+
for (const i of [index - 1, index + 1]) if (images[i]) void Image3.prefetch(images[i].uri).catch(() => void 0);
|
|
2272
|
+
}
|
|
2273
|
+
var styles22 = StyleSheet22.create({
|
|
2274
|
+
top: { position: "absolute", top: 0, left: 0, right: 0, flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 },
|
|
2275
|
+
counter: { paddingHorizontal: 10, paddingVertical: 4, borderRadius: 999 },
|
|
2276
|
+
close: { width: 40, height: 40, borderRadius: 20, alignItems: "center", justifyContent: "center" },
|
|
2277
|
+
cross: { fontSize: 24, lineHeight: 26 },
|
|
2278
|
+
caption: { position: "absolute", left: 0, right: 0, bottom: 0, paddingTop: 12, paddingHorizontal: 16 }
|
|
2279
|
+
});
|
|
2280
|
+
|
|
1591
2281
|
// src/native/KrizakaMark.tsx
|
|
1592
|
-
import { View as
|
|
1593
|
-
import
|
|
2282
|
+
import { View as View20 } from "react-native";
|
|
2283
|
+
import Svg7, { Circle as Circle2, Defs as Defs3, G as Group, LinearGradient as LinearGradient3, Path as Path5, RadialGradient, Stop as Stop3 } from "react-native-svg";
|
|
1594
2284
|
|
|
1595
2285
|
// src/marks/krizaka-geometry.ts
|
|
1596
2286
|
var KRIZAKA = {
|
|
@@ -1612,24 +2302,24 @@ var KRIZAKA = {
|
|
|
1612
2302
|
};
|
|
1613
2303
|
|
|
1614
2304
|
// src/native/mark-motion.ts
|
|
1615
|
-
import { useEffect as
|
|
1616
|
-
import { AccessibilityInfo as
|
|
2305
|
+
import { useEffect as useEffect10, useState as useState18 } from "react";
|
|
2306
|
+
import { AccessibilityInfo as AccessibilityInfo5, Animated as Animated8, Easing as Easing2 } from "react-native";
|
|
1617
2307
|
var markA11y = (title) => title ? { accessible: true, accessibilityRole: "image", accessibilityLabel: title } : { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants" };
|
|
1618
2308
|
function useMarkMotion(size, animated, spinMs = 3e4) {
|
|
1619
|
-
const [spin] =
|
|
1620
|
-
const [pulse] =
|
|
1621
|
-
|
|
2309
|
+
const [spin] = useState18(() => new Animated8.Value(0));
|
|
2310
|
+
const [pulse] = useState18(() => new Animated8.Value(0));
|
|
2311
|
+
useEffect10(() => {
|
|
1622
2312
|
if (!animated) return;
|
|
1623
2313
|
let loops = [];
|
|
1624
2314
|
let cancelled = false;
|
|
1625
|
-
void
|
|
2315
|
+
void AccessibilityInfo5.isReduceMotionEnabled().then((reduce) => {
|
|
1626
2316
|
if (reduce || cancelled) return;
|
|
1627
2317
|
loops = [
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
2318
|
+
Animated8.loop(Animated8.timing(spin, { toValue: 1, duration: spinMs, easing: Easing2.linear, useNativeDriver: true })),
|
|
2319
|
+
Animated8.loop(
|
|
2320
|
+
Animated8.sequence([
|
|
2321
|
+
Animated8.timing(pulse, { toValue: 1, duration: 1600, easing: Easing2.inOut(Easing2.ease), useNativeDriver: true }),
|
|
2322
|
+
Animated8.timing(pulse, { toValue: 0, duration: 1600, easing: Easing2.inOut(Easing2.ease), useNativeDriver: true })
|
|
1633
2323
|
])
|
|
1634
2324
|
)
|
|
1635
2325
|
];
|
|
@@ -1641,7 +2331,7 @@ function useMarkMotion(size, animated, spinMs = 3e4) {
|
|
|
1641
2331
|
};
|
|
1642
2332
|
}, [animated, spin, pulse, spinMs]);
|
|
1643
2333
|
return {
|
|
1644
|
-
Animated:
|
|
2334
|
+
Animated: Animated8,
|
|
1645
2335
|
layer: { position: "absolute", width: size, height: size },
|
|
1646
2336
|
spinStyle: { transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] }) }] },
|
|
1647
2337
|
pulseStyle: { opacity: pulse.interpolate({ inputRange: [0, 1], outputRange: [0.85, 1] }) }
|
|
@@ -1649,39 +2339,39 @@ function useMarkMotion(size, animated, spinMs = 3e4) {
|
|
|
1649
2339
|
}
|
|
1650
2340
|
|
|
1651
2341
|
// src/native/KrizakaMark.tsx
|
|
1652
|
-
import { Fragment as
|
|
2342
|
+
import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1653
2343
|
function KrizakaMark({ size = 48, animated = true, title, neutral }) {
|
|
1654
2344
|
const { theme } = useTheme();
|
|
1655
|
-
const { Animated:
|
|
2345
|
+
const { Animated: Animated22, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
|
|
1656
2346
|
const id = useSvgId("kzm");
|
|
1657
2347
|
const viewBox = size < 48 ? KRIZAKA.croppedViewBox : KRIZAKA.viewBox;
|
|
1658
2348
|
const stroke = neutral ?? theme.textMuted;
|
|
1659
|
-
const blue = /* @__PURE__ */
|
|
1660
|
-
const dot = (c) => /* @__PURE__ */
|
|
1661
|
-
/* @__PURE__ */
|
|
1662
|
-
/* @__PURE__ */
|
|
2349
|
+
const blue = /* @__PURE__ */ jsx24(LinearGradient3, { id: `${id}b`, gradientUnits: "userSpaceOnUse", x1: KRIZAKA.blue.x1 + KRIZAKA.offset, y1: KRIZAKA.blue.y1 + KRIZAKA.offset, x2: KRIZAKA.blue.x2 + KRIZAKA.offset, y2: KRIZAKA.blue.y2 + KRIZAKA.offset, children: KRIZAKA.blue.stops.map(([offset, color]) => /* @__PURE__ */ jsx24(Stop3, { offset, stopColor: color }, offset)) });
|
|
2350
|
+
const dot = (c) => /* @__PURE__ */ jsxs21(Fragment4, { children: [
|
|
2351
|
+
/* @__PURE__ */ jsx24(Circle2, { cx: c.cx, cy: c.cy, r: c.r, fill: `url(#${id}b)` }),
|
|
2352
|
+
/* @__PURE__ */ jsx24(Circle2, { cx: c.cx, cy: c.cy, r: c.inner, fill: KRIZAKA.highlight })
|
|
1663
2353
|
] });
|
|
1664
|
-
return /* @__PURE__ */
|
|
1665
|
-
/* @__PURE__ */
|
|
1666
|
-
/* @__PURE__ */
|
|
1667
|
-
/* @__PURE__ */
|
|
1668
|
-
/* @__PURE__ */
|
|
1669
|
-
/* @__PURE__ */
|
|
2354
|
+
return /* @__PURE__ */ jsxs21(View20, { style: { width: size, height: size }, ...markA11y(title), children: [
|
|
2355
|
+
/* @__PURE__ */ jsxs21(Svg7, { viewBox, style: layer, children: [
|
|
2356
|
+
/* @__PURE__ */ jsxs21(Defs3, { children: [
|
|
2357
|
+
/* @__PURE__ */ jsxs21(RadialGradient, { id: `${id}g`, cx: "50%", cy: "50%", r: "50%", children: [
|
|
2358
|
+
/* @__PURE__ */ jsx24(Stop3, { offset: "0%", stopColor: KRIZAKA.glow.color, stopOpacity: KRIZAKA.glow.opacity }),
|
|
2359
|
+
/* @__PURE__ */ jsx24(Stop3, { offset: "100%", stopColor: KRIZAKA.glow.color, stopOpacity: 0 })
|
|
1670
2360
|
] }),
|
|
1671
|
-
/* @__PURE__ */
|
|
1672
|
-
/* @__PURE__ */
|
|
1673
|
-
/* @__PURE__ */
|
|
2361
|
+
/* @__PURE__ */ jsxs21(LinearGradient3, { id: `${id}i`, gradientUnits: "userSpaceOnUse", x1: KRIZAKA.ink.x1 + KRIZAKA.offset, y1: KRIZAKA.ink.y1 + KRIZAKA.offset, x2: KRIZAKA.ink.x2 + KRIZAKA.offset, y2: KRIZAKA.ink.y2 + KRIZAKA.offset, children: [
|
|
2362
|
+
/* @__PURE__ */ jsx24(Stop3, { offset: "0%", stopColor: theme.textSecondary }),
|
|
2363
|
+
/* @__PURE__ */ jsx24(Stop3, { offset: "100%", stopColor: theme.textPrimary })
|
|
1674
2364
|
] }),
|
|
1675
2365
|
blue
|
|
1676
2366
|
] }),
|
|
1677
|
-
size >= 48 ? /* @__PURE__ */
|
|
1678
|
-
/* @__PURE__ */
|
|
1679
|
-
/* @__PURE__ */
|
|
2367
|
+
size >= 48 ? /* @__PURE__ */ jsx24(Circle2, { cx: 200, cy: 200, r: 190, fill: `url(#${id}g)` }) : null,
|
|
2368
|
+
/* @__PURE__ */ jsx24(Circle2, { cx: 200, cy: 200, r: KRIZAKA.ring.r, stroke, strokeWidth: KRIZAKA.ring.width, opacity: 0.35, fill: "none" }),
|
|
2369
|
+
/* @__PURE__ */ jsx24(Group, { transform: `translate(${KRIZAKA.offset} ${KRIZAKA.offset})`, children: /* @__PURE__ */ jsx24(Path5, { d: KRIZAKA.shield, stroke: `url(#${id}i)`, strokeWidth: KRIZAKA.stroke, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }) })
|
|
1680
2370
|
] }),
|
|
1681
|
-
/* @__PURE__ */
|
|
1682
|
-
/* @__PURE__ */
|
|
1683
|
-
/* @__PURE__ */
|
|
1684
|
-
/* @__PURE__ */
|
|
2371
|
+
/* @__PURE__ */ jsx24(Animated22.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsx24(Svg7, { viewBox, style: layer, children: /* @__PURE__ */ jsx24(Circle2, { cx: 200, cy: 200, r: KRIZAKA.orbit.r, stroke, strokeWidth: KRIZAKA.orbit.width, strokeDasharray: KRIZAKA.orbit.dash, opacity: 0.6, fill: "none" }) }) }),
|
|
2372
|
+
/* @__PURE__ */ jsx24(Animated22.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs21(Svg7, { viewBox, style: layer, children: [
|
|
2373
|
+
/* @__PURE__ */ jsx24(Defs3, { children: blue }),
|
|
2374
|
+
/* @__PURE__ */ jsxs21(Group, { transform: `translate(${KRIZAKA.offset} ${KRIZAKA.offset})`, children: [
|
|
1685
2375
|
dot(KRIZAKA.node),
|
|
1686
2376
|
dot(KRIZAKA.core)
|
|
1687
2377
|
] })
|
|
@@ -1689,14 +2379,115 @@ function KrizakaMark({ size = 48, animated = true, title, neutral }) {
|
|
|
1689
2379
|
] });
|
|
1690
2380
|
}
|
|
1691
2381
|
|
|
2382
|
+
// src/native/loader.tsx
|
|
2383
|
+
import * as React19 from "react";
|
|
2384
|
+
import { AccessibilityInfo as AccessibilityInfo6, Animated as Animated9, Easing as Easing3, StyleSheet as StyleSheet23, View as View21 } from "react-native";
|
|
2385
|
+
import Svg8, { Circle as Circle3, Path as Path6 } from "react-native-svg";
|
|
2386
|
+
import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2387
|
+
var HEX = "M12 3 19.79 7.5 19.79 16.5 12 21 4.21 16.5 4.21 7.5Z";
|
|
2388
|
+
var PERIMETER = 54;
|
|
2389
|
+
function LoaderGlyph({ state = "loading", value, size = 20, color }) {
|
|
2390
|
+
const { theme } = useTheme();
|
|
2391
|
+
const reduce = useReducedMotion();
|
|
2392
|
+
const [spin] = React19.useState(() => new Animated9.Value(0));
|
|
2393
|
+
const known = typeof value === "number" && Number.isFinite(value);
|
|
2394
|
+
React19.useEffect(() => {
|
|
2395
|
+
if (state !== "loading" || known || reduce) return;
|
|
2396
|
+
const loop = Animated9.loop(Animated9.timing(spin, { toValue: 1, duration: 1400, easing: Easing3.linear, useNativeDriver: true }));
|
|
2397
|
+
loop.start();
|
|
2398
|
+
return () => loop.stop();
|
|
2399
|
+
}, [state, known, reduce, spin]);
|
|
2400
|
+
const stroke = color ?? (state === "success" ? theme.success : state === "error" ? theme.danger : theme.accent);
|
|
2401
|
+
const fill = state !== "loading" ? 1 : known ? Math.min(1, Math.max(0, value)) : 0.3;
|
|
2402
|
+
const rotate = spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] });
|
|
2403
|
+
return /* @__PURE__ */ jsx25(Animated9.View, { "aria-hidden": true, style: { width: size, height: size, transform: state === "loading" && !known ? [{ rotate }] : [] }, children: /* @__PURE__ */ jsxs22(Svg8, { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: [
|
|
2404
|
+
/* @__PURE__ */ jsx25(Path6, { d: HEX, stroke, strokeOpacity: 0.22, strokeWidth: 2.2, strokeLinejoin: "round" }),
|
|
2405
|
+
/* @__PURE__ */ jsx25(Path6, { d: HEX, stroke, strokeWidth: 2.2, strokeLinejoin: "round", strokeLinecap: "round", strokeDasharray: `${fill * PERIMETER} ${PERIMETER}` }),
|
|
2406
|
+
state === "loading" ? /* @__PURE__ */ jsx25(Circle3, { cx: 12, cy: 12, r: 2.6, fill: stroke }) : null,
|
|
2407
|
+
state === "success" ? /* @__PURE__ */ jsx25(Path6, { d: "M8.3 12.3l2.6 2.6 4.9-5.3", stroke, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round" }) : null,
|
|
2408
|
+
state === "error" ? /* @__PURE__ */ jsx25(Path6, { d: "M9.4 9.4l5.2 5.2M14.6 9.4l-5.2 5.2", stroke, strokeWidth: 2.2, strokeLinecap: "round" }) : null
|
|
2409
|
+
] }) });
|
|
2410
|
+
}
|
|
2411
|
+
function useDelayedWait(active, delay = 250, minDuration = 600) {
|
|
2412
|
+
const [shown, setShown] = React19.useState(false);
|
|
2413
|
+
const since = React19.useRef(0);
|
|
2414
|
+
React19.useEffect(() => {
|
|
2415
|
+
if (active && !shown) {
|
|
2416
|
+
const timer2 = setTimeout(() => {
|
|
2417
|
+
since.current = Date.now();
|
|
2418
|
+
setShown(true);
|
|
2419
|
+
}, delay);
|
|
2420
|
+
return () => clearTimeout(timer2);
|
|
2421
|
+
}
|
|
2422
|
+
if (!active && shown) {
|
|
2423
|
+
const timer2 = setTimeout(() => setShown(false), Math.max(0, minDuration - (Date.now() - since.current)));
|
|
2424
|
+
return () => clearTimeout(timer2);
|
|
2425
|
+
}
|
|
2426
|
+
return void 0;
|
|
2427
|
+
}, [active, shown, delay, minDuration]);
|
|
2428
|
+
return shown;
|
|
2429
|
+
}
|
|
2430
|
+
var GLYPH = { inline: 20, block: 36, overlay: 36, page: 56 };
|
|
2431
|
+
function Loader({ label, status = "loading", successLabel, errorLabel, value, eta, delay = 250, minDuration = 600, endDuration = 1600, variant = "inline", style }) {
|
|
2432
|
+
const { theme, radius: radius3 } = useTheme();
|
|
2433
|
+
const waiting = useDelayedWait(status === "loading", delay, minDuration);
|
|
2434
|
+
const [ending, setEnding] = React19.useState(null);
|
|
2435
|
+
const seen = React19.useRef(false);
|
|
2436
|
+
React19.useEffect(() => {
|
|
2437
|
+
if (waiting) {
|
|
2438
|
+
seen.current = true;
|
|
2439
|
+
return;
|
|
2440
|
+
}
|
|
2441
|
+
if (!seen.current || status === "loading") return;
|
|
2442
|
+
seen.current = false;
|
|
2443
|
+
if (endDuration <= 0) return;
|
|
2444
|
+
const show2 = setTimeout(() => setEnding(status), 0);
|
|
2445
|
+
const hide = Number.isFinite(endDuration) ? setTimeout(() => setEnding(null), endDuration) : void 0;
|
|
2446
|
+
return () => {
|
|
2447
|
+
clearTimeout(show2);
|
|
2448
|
+
clearTimeout(hide);
|
|
2449
|
+
};
|
|
2450
|
+
}, [waiting, status, endDuration]);
|
|
2451
|
+
const phase = waiting ? "loading" : ending;
|
|
2452
|
+
const words = phase === "success" ? successLabel ?? label : phase === "error" ? errorLabel ?? label : label;
|
|
2453
|
+
React19.useEffect(() => {
|
|
2454
|
+
if (phase) AccessibilityInfo6.announceForAccessibility(words);
|
|
2455
|
+
}, [phase, words]);
|
|
2456
|
+
if (!phase) return null;
|
|
2457
|
+
const known = phase === "loading" && typeof value === "number" && Number.isFinite(value);
|
|
2458
|
+
const detail = phase === "loading" ? [known ? `${Math.round(Math.min(1, Math.max(0, value)) * 100)} %` : null, eta].filter(Boolean).join(" \xB7 ") : "";
|
|
2459
|
+
const stacked = variant !== "inline";
|
|
2460
|
+
const box = /* @__PURE__ */ jsxs22(View21, { style: [stacked ? styles23.stacked : styles23.inline, variant === "overlay" ? { backgroundColor: alpha(theme.surface1, 0.92), borderColor: theme.borderDefault, borderRadius: radius3.lg, ...styles23.card } : null], children: [
|
|
2461
|
+
/* @__PURE__ */ jsx25(LoaderGlyph, { state: phase, value: known ? value : null, size: GLYPH[variant] }),
|
|
2462
|
+
/* @__PURE__ */ jsxs22(View21, { style: stacked ? styles23.center : styles23.text, children: [
|
|
2463
|
+
/* @__PURE__ */ jsx25(Txt, { variant: variant === "page" ? "title" : "label", style: stacked ? styles23.centered : null, children: words }),
|
|
2464
|
+
detail ? /* @__PURE__ */ jsx25(Txt, { variant: "caption", tone: "secondary", style: stacked ? styles23.centered : null, children: detail }) : null
|
|
2465
|
+
] })
|
|
2466
|
+
] });
|
|
2467
|
+
const a11y = { accessible: true, role: "progressbar", "aria-label": words, "aria-busy": phase === "loading", accessibilityLiveRegion: "polite" };
|
|
2468
|
+
if (variant === "overlay" || variant === "page")
|
|
2469
|
+
return /* @__PURE__ */ jsx25(View21, { ...a11y, style: [StyleSheet23.absoluteFill, styles23.cover, variant === "page" ? { backgroundColor: alpha(theme.surface0, 0.86) } : null, style], children: box });
|
|
2470
|
+
return /* @__PURE__ */ jsx25(View21, { ...a11y, style: [variant === "block" ? styles23.block : null, style], children: box });
|
|
2471
|
+
}
|
|
2472
|
+
var styles23 = StyleSheet23.create({
|
|
2473
|
+
inline: { flexDirection: "row", alignItems: "center", gap: 10 },
|
|
2474
|
+
stacked: { alignItems: "center", gap: 10 },
|
|
2475
|
+
card: { paddingHorizontal: 24, paddingVertical: 20, borderWidth: StyleSheet23.hairlineWidth },
|
|
2476
|
+
text: { flexShrink: 1, gap: 2 },
|
|
2477
|
+
center: { alignItems: "center", gap: 2 },
|
|
2478
|
+
centered: { textAlign: "center" },
|
|
2479
|
+
block: { paddingVertical: 40, alignItems: "center" },
|
|
2480
|
+
cover: { alignItems: "center", justifyContent: "center", zIndex: 10 }
|
|
2481
|
+
});
|
|
2482
|
+
|
|
1692
2483
|
// src/native/mascot-state.tsx
|
|
1693
|
-
import * as
|
|
1694
|
-
import { AccessibilityInfo as
|
|
2484
|
+
import * as React21 from "react";
|
|
2485
|
+
import { AccessibilityInfo as AccessibilityInfo8, Animated as Animated11, Easing as Easing5, StyleSheet as StyleSheet24, View as View23 } from "react-native";
|
|
1695
2486
|
|
|
1696
2487
|
// src/native/mascots.tsx
|
|
1697
|
-
import { useEffect as
|
|
1698
|
-
import { AccessibilityInfo as
|
|
1699
|
-
import
|
|
2488
|
+
import { useEffect as useEffect12, useState as useState20 } from "react";
|
|
2489
|
+
import { AccessibilityInfo as AccessibilityInfo7, Animated as Animated10, Easing as Easing4, View as View22 } from "react-native";
|
|
2490
|
+
import Svg9, { Circle as Circle4, Defs as Defs4, Ellipse, G, LinearGradient as LinearGradient4, Path as Path7, Rect as Rect2, Stop as Stop4 } from "react-native-svg";
|
|
1700
2491
|
|
|
1701
2492
|
// src/mascots/geometry.ts
|
|
1702
2493
|
var mirror = (d) => d.replace(/(-?\d+(?:\.\d+)?) (-?\d+(?:\.\d+)?)/g, (_, x, y) => `${120 - Number(x)} ${y}`);
|
|
@@ -1854,17 +2645,17 @@ var SHADE = "#000000";
|
|
|
1854
2645
|
var PARCEL = ["#f59e0b", "#d97706", "#b45309"];
|
|
1855
2646
|
|
|
1856
2647
|
// src/native/mascots.tsx
|
|
1857
|
-
import { jsx as
|
|
2648
|
+
import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1858
2649
|
function useBob(animated) {
|
|
1859
|
-
const [y] =
|
|
1860
|
-
|
|
2650
|
+
const [y] = useState20(() => new Animated10.Value(0));
|
|
2651
|
+
useEffect12(() => {
|
|
1861
2652
|
if (!animated) return;
|
|
1862
2653
|
let loop;
|
|
1863
2654
|
let cancelled = false;
|
|
1864
|
-
void
|
|
2655
|
+
void AccessibilityInfo7.isReduceMotionEnabled().then((reduce) => {
|
|
1865
2656
|
if (reduce || cancelled) return;
|
|
1866
|
-
const step = (toValue) =>
|
|
1867
|
-
loop =
|
|
2657
|
+
const step = (toValue) => Animated10.timing(y, { toValue, duration: 1800, easing: Easing4.inOut(Easing4.ease), useNativeDriver: true });
|
|
2658
|
+
loop = Animated10.loop(Animated10.sequence([step(-2.5), step(0)]));
|
|
1868
2659
|
loop.start();
|
|
1869
2660
|
});
|
|
1870
2661
|
return () => {
|
|
@@ -1874,13 +2665,13 @@ function useBob(animated) {
|
|
|
1874
2665
|
}, [animated, y]);
|
|
1875
2666
|
return y;
|
|
1876
2667
|
}
|
|
1877
|
-
function Mascot({ bird = "owl", mood = "welcome", tone:
|
|
2668
|
+
function Mascot({ bird = "owl", mood = "welcome", tone: tone3 = "brand", size = 96, animated = true, title, style }) {
|
|
1878
2669
|
const { theme } = useTheme();
|
|
1879
2670
|
const id = useSvgId("kzb");
|
|
1880
2671
|
const bob = useBob(animated);
|
|
1881
2672
|
const g = BIRDS[bird];
|
|
1882
2673
|
const brand = { from: theme.accent2, to: theme.accent, wing: theme.accent, detail: theme.accent2, beak: theme.warning, eye: theme.textPrimary };
|
|
1883
|
-
const p =
|
|
2674
|
+
const p = tone3 === "own" ? OWN_PALETTES[bird] : brand;
|
|
1884
2675
|
const outline = theme.borderStrong;
|
|
1885
2676
|
const body = `url(#${id})`;
|
|
1886
2677
|
const line = { stroke: outline, strokeWidth: 1.4, strokeLinejoin: "round" };
|
|
@@ -1888,62 +2679,62 @@ function Mascot({ bird = "owl", mood = "welcome", tone: tone2 = "brand", size =
|
|
|
1888
2679
|
const look3 = mood === "thinking" ? 1.4 : 0;
|
|
1889
2680
|
const rot = (deg, [x, y]) => `rotate(${deg} ${x} ${y})`;
|
|
1890
2681
|
const [wl, wr] = g.wings;
|
|
1891
|
-
return /* @__PURE__ */
|
|
1892
|
-
/* @__PURE__ */
|
|
1893
|
-
/* @__PURE__ */
|
|
1894
|
-
/* @__PURE__ */
|
|
2682
|
+
return /* @__PURE__ */ jsx26(View22, { style: [{ width: size, height: size }, style], ...markA11y(title), children: /* @__PURE__ */ jsx26(Animated10.View, { style: { transform: [{ translateY: bob }] }, children: /* @__PURE__ */ jsxs23(Svg9, { width: size, height: size, viewBox: "0 0 120 120", children: [
|
|
2683
|
+
/* @__PURE__ */ jsx26(Defs4, { children: /* @__PURE__ */ jsxs23(LinearGradient4, { id, x1: "0", y1: "0", x2: "0", y2: "1", children: [
|
|
2684
|
+
/* @__PURE__ */ jsx26(Stop4, { offset: "0%", stopColor: p.from }),
|
|
2685
|
+
/* @__PURE__ */ jsx26(Stop4, { offset: "100%", stopColor: p.to })
|
|
1895
2686
|
] }) }),
|
|
1896
|
-
/* @__PURE__ */
|
|
1897
|
-
mood === "empty" && /* @__PURE__ */
|
|
1898
|
-
g.legs.map((d) => /* @__PURE__ */
|
|
1899
|
-
g.back?.map((d) => d.endsWith("Z") ? /* @__PURE__ */
|
|
1900
|
-
g.parcel?.map((d, i) => /* @__PURE__ */
|
|
1901
|
-
/* @__PURE__ */
|
|
1902
|
-
/* @__PURE__ */
|
|
2687
|
+
/* @__PURE__ */ jsx26(Ellipse, { cx: g.shadow[0], cy: g.shadow[1], rx: g.shadow[2], ry: g.shadow[3], fill: SHADE, opacity: 0.14 }),
|
|
2688
|
+
mood === "empty" && /* @__PURE__ */ jsx26(Path7, { d: MOOD_PARTS.tray, stroke: outline, strokeWidth: 1.6, strokeDasharray: "3 3", fill: "none" }),
|
|
2689
|
+
g.legs.map((d) => /* @__PURE__ */ jsx26(Path7, { d, stroke: p.beak, strokeWidth: 2.6, strokeLinecap: "round", fill: "none" }, d)),
|
|
2690
|
+
g.back?.map((d) => d.endsWith("Z") ? /* @__PURE__ */ jsx26(Path7, { d, fill: p.detail, ...line }, d) : /* @__PURE__ */ jsx26(Path7, { d, stroke: outline, strokeWidth: 1.4, fill: "none" }, d)),
|
|
2691
|
+
g.parcel?.map((d, i) => /* @__PURE__ */ jsx26(Path7, { d, fill: PARCEL[i], ...line }, d)),
|
|
2692
|
+
/* @__PURE__ */ jsx26(Path7, { d: g.body, fill: body, ...line }),
|
|
2693
|
+
/* @__PURE__ */ jsx26(Path7, { d: g.belly, fill: LIGHT, opacity: 0.28 }),
|
|
1903
2694
|
[wl, wr].map((w, i) => {
|
|
1904
2695
|
const turn = mood === "success" ? i === 0 ? 28 : -28 : mood === "welcome" && i === 1 ? -20 : 0;
|
|
1905
|
-
return /* @__PURE__ */
|
|
1906
|
-
/* @__PURE__ */
|
|
1907
|
-
/* @__PURE__ */
|
|
2696
|
+
return /* @__PURE__ */ jsxs23(G, { transform: turn ? rot(turn, w.pivot) : void 0, children: [
|
|
2697
|
+
/* @__PURE__ */ jsx26(Path7, { d: w.d, fill: p.wing, ...line }),
|
|
2698
|
+
/* @__PURE__ */ jsx26(Path7, { d: w.d, fill: SHADE, opacity: 0.16 })
|
|
1908
2699
|
] }, i);
|
|
1909
2700
|
}),
|
|
1910
|
-
g.neck && /* @__PURE__ */
|
|
1911
|
-
g.head.r > 0 && /* @__PURE__ */
|
|
1912
|
-
g.details.map((d) => /* @__PURE__ */
|
|
1913
|
-
g.visor && /* @__PURE__ */
|
|
2701
|
+
g.neck && /* @__PURE__ */ jsx26(Path7, { d: g.neck.d, stroke: body, strokeWidth: g.neck.width, strokeLinecap: "round", fill: "none" }),
|
|
2702
|
+
g.head.r > 0 && /* @__PURE__ */ jsx26(Circle4, { cx: g.head.cx, cy: g.head.cy, r: g.head.r, fill: body, ...line }),
|
|
2703
|
+
g.details.map((d) => /* @__PURE__ */ jsx26(Path7, { d, fill: p.detail, ...line }, d)),
|
|
2704
|
+
g.visor && /* @__PURE__ */ jsx26(Rect2, { x: g.visor.x, y: g.visor.y, width: g.visor.w, height: g.visor.h, rx: 4, fill: theme.surface0, ...line }),
|
|
1914
2705
|
g.eyes.at.map(
|
|
1915
|
-
(at, i) => mood === "empty" && g.eyes.white > 0 ? /* @__PURE__ */
|
|
1916
|
-
/* @__PURE__ */
|
|
1917
|
-
/* @__PURE__ */
|
|
1918
|
-
/* @__PURE__ */
|
|
1919
|
-
] }, i) : mood === "success" || mood === "empty" ? /* @__PURE__ */
|
|
1920
|
-
g.eyes.white > 0 && /* @__PURE__ */
|
|
1921
|
-
/* @__PURE__ */
|
|
2706
|
+
(at, i) => mood === "empty" && g.eyes.white > 0 ? /* @__PURE__ */ jsxs23(G, { children: [
|
|
2707
|
+
/* @__PURE__ */ jsx26(Circle4, { cx: at[0], cy: at[1], r: g.eyes.white, fill: LIGHT, ...line }),
|
|
2708
|
+
/* @__PURE__ */ jsx26(Circle4, { cx: at[0], cy: at[1] + g.eyes.pupil * 0.7, r: g.eyes.pupil, fill: SHADE }),
|
|
2709
|
+
/* @__PURE__ */ jsx26(Path7, { d: upperLid(at, g.eyes.white), fill: p.detail, ...line })
|
|
2710
|
+
] }, i) : mood === "success" || mood === "empty" ? /* @__PURE__ */ jsx26(Path7, { d: mood === "success" ? archEye(at, eyeR * 0.85) : lidEye(at, eyeR * 0.8), stroke: g.visor ? p.eye : outline, strokeWidth: 2.2, strokeLinecap: "round", fill: "none" }, i) : /* @__PURE__ */ jsxs23(G, { children: [
|
|
2711
|
+
g.eyes.white > 0 && /* @__PURE__ */ jsx26(Circle4, { cx: at[0], cy: at[1], r: g.eyes.white, fill: LIGHT, ...line }),
|
|
2712
|
+
/* @__PURE__ */ jsx26(Circle4, { cx: at[0] + look3, cy: at[1] - look3, r: g.eyes.pupil, fill: g.visor ? p.eye : SHADE })
|
|
1922
2713
|
] }, i)
|
|
1923
2714
|
),
|
|
1924
|
-
g.glasses && g.eyes.at.map(([x, y]) => /* @__PURE__ */
|
|
1925
|
-
mood === "error" && g.eyes.at.map((at, i) => /* @__PURE__ */
|
|
1926
|
-
/* @__PURE__ */
|
|
1927
|
-
mood === "thinking" && MOOD_PARTS.dots.map(([cx, cy, r], i) => /* @__PURE__ */
|
|
1928
|
-
(mood === "success" || mood === "error") && /* @__PURE__ */
|
|
1929
|
-
mood === "success" && /* @__PURE__ */
|
|
1930
|
-
mood === "error" && /* @__PURE__ */
|
|
1931
|
-
mood === "error" && /* @__PURE__ */
|
|
2715
|
+
g.glasses && g.eyes.at.map(([x, y]) => /* @__PURE__ */ jsx26(Circle4, { cx: x, cy: y, r: 6.5, fill: "none", stroke: outline, strokeWidth: 1.3 }, x)),
|
|
2716
|
+
mood === "error" && g.eyes.at.map((at, i) => /* @__PURE__ */ jsx26(Path7, { d: brow(at, eyeR, g.eyes.at.length === 1 ? 1 : i === 0 ? -1 : 1), stroke: outline, strokeWidth: 2, strokeLinecap: "round" }, i)),
|
|
2717
|
+
/* @__PURE__ */ jsx26(Path7, { d: g.beak, fill: p.beak, ...line }),
|
|
2718
|
+
mood === "thinking" && MOOD_PARTS.dots.map(([cx, cy, r], i) => /* @__PURE__ */ jsx26(Circle4, { cx, cy, r, fill: theme.textSecondary, opacity: 0.5 + i * 0.25 }, cx)),
|
|
2719
|
+
(mood === "success" || mood === "error") && /* @__PURE__ */ jsx26(Circle4, { cx: MOOD_PARTS.badge.cx, cy: MOOD_PARTS.badge.cy, r: MOOD_PARTS.badge.r, fill: mood === "success" ? theme.success : theme.danger }),
|
|
2720
|
+
mood === "success" && /* @__PURE__ */ jsx26(Path7, { d: MOOD_PARTS.check, stroke: theme.surface0, strokeWidth: 2.6, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }),
|
|
2721
|
+
mood === "error" && /* @__PURE__ */ jsx26(Path7, { d: MOOD_PARTS.bang.line, stroke: theme.surface0, strokeWidth: 2.8, strokeLinecap: "round" }),
|
|
2722
|
+
mood === "error" && /* @__PURE__ */ jsx26(Circle4, { cx: MOOD_PARTS.bang.dot[0], cy: MOOD_PARTS.bang.dot[1], r: 1.6, fill: theme.surface0 })
|
|
1932
2723
|
] }) }) });
|
|
1933
2724
|
}
|
|
1934
2725
|
|
|
1935
2726
|
// src/native/mascot-state.tsx
|
|
1936
|
-
import { jsx as
|
|
2727
|
+
import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1937
2728
|
var SIZE = { sm: 64, md: 96, lg: 128 };
|
|
1938
2729
|
function useArrival(animated) {
|
|
1939
|
-
const [value] =
|
|
1940
|
-
|
|
2730
|
+
const [value] = React21.useState(() => new Animated11.Value(animated ? 0 : 1));
|
|
2731
|
+
React21.useEffect(() => {
|
|
1941
2732
|
if (!animated) return;
|
|
1942
2733
|
let cancelled = false;
|
|
1943
|
-
void
|
|
2734
|
+
void AccessibilityInfo8.isReduceMotionEnabled().then((reduce) => {
|
|
1944
2735
|
if (cancelled) return;
|
|
1945
2736
|
if (reduce) value.setValue(1);
|
|
1946
|
-
else
|
|
2737
|
+
else Animated11.timing(value, { toValue: 1, duration: 420, easing: Easing5.out(Easing5.cubic), useNativeDriver: true }).start();
|
|
1947
2738
|
});
|
|
1948
2739
|
return () => {
|
|
1949
2740
|
cancelled = true;
|
|
@@ -1951,33 +2742,33 @@ function useArrival(animated) {
|
|
|
1951
2742
|
}, [animated, value]);
|
|
1952
2743
|
return value;
|
|
1953
2744
|
}
|
|
1954
|
-
function MascotState({ bird = "owl", mood = "empty", title, description, action, size = "md", layout = "stacked", tone:
|
|
2745
|
+
function MascotState({ bird = "owl", mood = "empty", title, description, action, size = "md", layout = "stacked", tone: tone3, animated = true, style, ...props }) {
|
|
1955
2746
|
const opacity = useArrival(animated);
|
|
1956
2747
|
const inline = layout === "inline";
|
|
1957
|
-
return /* @__PURE__ */
|
|
1958
|
-
|
|
2748
|
+
return /* @__PURE__ */ jsxs24(
|
|
2749
|
+
Animated11.View,
|
|
1959
2750
|
{
|
|
1960
2751
|
role: mood === "error" ? "alert" : "status",
|
|
1961
2752
|
accessibilityLiveRegion: mood === "error" ? "assertive" : "polite",
|
|
1962
2753
|
"aria-busy": mood === "thinking" ? true : void 0,
|
|
1963
2754
|
...props,
|
|
1964
|
-
style: [inline ?
|
|
2755
|
+
style: [inline ? styles24.inline : styles24.stacked, { opacity, transform: [{ translateY: opacity.interpolate({ inputRange: [0, 1], outputRange: [6, 0] }) }] }, style],
|
|
1965
2756
|
children: [
|
|
1966
|
-
/* @__PURE__ */
|
|
1967
|
-
/* @__PURE__ */
|
|
1968
|
-
/* @__PURE__ */
|
|
1969
|
-
description ? /* @__PURE__ */
|
|
1970
|
-
action ? /* @__PURE__ */
|
|
2757
|
+
/* @__PURE__ */ jsx27(Mascot, { bird, mood, tone: tone3, size: SIZE[size], animated }),
|
|
2758
|
+
/* @__PURE__ */ jsxs24(View23, { style: inline ? styles24.wordsInline : styles24.words, children: [
|
|
2759
|
+
/* @__PURE__ */ jsx27(Txt, { variant: "label", role: "heading", style: inline ? null : styles24.center, children: title }),
|
|
2760
|
+
description ? /* @__PURE__ */ jsx27(Txt, { tone: "secondary", style: inline ? null : styles24.center, children: description }) : null,
|
|
2761
|
+
action ? /* @__PURE__ */ jsx27(View23, { style: [styles24.action, inline ? null : styles24.actionCentred], children: action }) : null
|
|
1971
2762
|
] })
|
|
1972
2763
|
]
|
|
1973
2764
|
}
|
|
1974
2765
|
);
|
|
1975
2766
|
}
|
|
1976
|
-
var ErrorState = (props) => /* @__PURE__ */
|
|
1977
|
-
var SuccessState = (props) => /* @__PURE__ */
|
|
1978
|
-
var LoadingState = (props) => /* @__PURE__ */
|
|
1979
|
-
var WelcomeState = (props) => /* @__PURE__ */
|
|
1980
|
-
var
|
|
2767
|
+
var ErrorState = (props) => /* @__PURE__ */ jsx27(MascotState, { mood: "error", ...props });
|
|
2768
|
+
var SuccessState = (props) => /* @__PURE__ */ jsx27(MascotState, { mood: "success", ...props });
|
|
2769
|
+
var LoadingState = (props) => /* @__PURE__ */ jsx27(MascotState, { mood: "thinking", ...props });
|
|
2770
|
+
var WelcomeState = (props) => /* @__PURE__ */ jsx27(MascotState, { mood: "welcome", ...props });
|
|
2771
|
+
var styles24 = StyleSheet24.create({
|
|
1981
2772
|
stacked: { alignItems: "center", justifyContent: "center", gap: 12, paddingVertical: 40, paddingHorizontal: 24 },
|
|
1982
2773
|
inline: { flexDirection: "row", alignItems: "center", gap: 16 },
|
|
1983
2774
|
words: { alignItems: "center", gap: 6 },
|
|
@@ -1987,9 +2778,150 @@ var styles15 = StyleSheet15.create({
|
|
|
1987
2778
|
actionCentred: { justifyContent: "center" }
|
|
1988
2779
|
});
|
|
1989
2780
|
|
|
2781
|
+
// src/native/meter.tsx
|
|
2782
|
+
import { StyleSheet as StyleSheet25, View as View24 } from "react-native";
|
|
2783
|
+
import Svg10, { Circle as Circle5 } from "react-native-svg";
|
|
2784
|
+
import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2785
|
+
var THICK = { sm: 6, md: 8, lg: 12 };
|
|
2786
|
+
var RING = { sm: 56, md: 96, lg: 144 };
|
|
2787
|
+
var partColor = (t, i) => [t.accent, t.warning, t.success, t.textSecondary, t.danger][i % 5];
|
|
2788
|
+
function Meter({ label, value = 0, min = 0, max = 100, valueText, thresholds, optimum = "low", parts, variant = "bar", size = "md", showLabel, children, style }) {
|
|
2789
|
+
const { theme } = useTheme();
|
|
2790
|
+
const span = max - min || 1;
|
|
2791
|
+
const ratio = Math.min(1, Math.max(0, (value - min) / span));
|
|
2792
|
+
const level = !thresholds ? "ok" : ratio >= thresholds.high ? optimum === "low" ? "danger" : "success" : ratio >= thresholds.low ? "warning" : optimum === "low" ? "success" : "danger";
|
|
2793
|
+
const tone3 = { ok: theme.accent, success: theme.success, warning: theme.warning, danger: theme.danger }[level];
|
|
2794
|
+
const words = valueText ?? `${Math.round(ratio * 100)} %`;
|
|
2795
|
+
const shares = (parts ?? []).map((p, i) => ({ ...p, color: partColor(theme, i), ratio: Math.min(1, Math.max(0, p.value / span)), words: p.valueText ?? `${Math.round(p.value / span * 100)} %` }));
|
|
2796
|
+
const a11y = parts ? { role: "group", "aria-label": `${label}: ${shares.map((p) => `${p.label} ${p.words}`).join(", ")}` } : { role: "meter", "aria-label": label, "aria-valuemin": min, "aria-valuemax": max, "aria-valuenow": Math.min(max, Math.max(min, value)), "aria-valuetext": words };
|
|
2797
|
+
const legend = parts ? /* @__PURE__ */ jsx28(View24, { style: styles25.legend, "aria-hidden": true, children: shares.map((p, i) => /* @__PURE__ */ jsxs25(View24, { style: styles25.legendItem, children: [
|
|
2798
|
+
/* @__PURE__ */ jsx28(View24, { style: [styles25.swatch, { backgroundColor: p.color }] }),
|
|
2799
|
+
/* @__PURE__ */ jsx28(Txt, { variant: "caption", children: p.label }),
|
|
2800
|
+
/* @__PURE__ */ jsx28(Txt, { variant: "caption", tone: "secondary", children: p.words })
|
|
2801
|
+
] }, i)) }) : null;
|
|
2802
|
+
if (variant === "ring") {
|
|
2803
|
+
const side = RING[size];
|
|
2804
|
+
const r = 44;
|
|
2805
|
+
const c = 2 * Math.PI * r;
|
|
2806
|
+
let offset = 0;
|
|
2807
|
+
const arcs = parts ? shares.map((p) => {
|
|
2808
|
+
const arc = { color: p.color, len: p.ratio, start: offset };
|
|
2809
|
+
offset += p.ratio;
|
|
2810
|
+
return arc;
|
|
2811
|
+
}) : [{ color: tone3, len: ratio, start: 0 }];
|
|
2812
|
+
return /* @__PURE__ */ jsxs25(View24, { accessible: true, ...a11y, style: [styles25.ringRoot, style], children: [
|
|
2813
|
+
/* @__PURE__ */ jsxs25(View24, { style: { width: side, height: side }, children: [
|
|
2814
|
+
/* @__PURE__ */ jsxs25(Svg10, { width: side, height: side, viewBox: "0 0 100 100", style: { transform: [{ rotate: "-90deg" }] }, children: [
|
|
2815
|
+
/* @__PURE__ */ jsx28(Circle5, { cx: 50, cy: 50, r, fill: "none", stroke: theme.borderDefault, strokeWidth: 9 }),
|
|
2816
|
+
arcs.map((a, i) => /* @__PURE__ */ jsx28(Circle5, { cx: 50, cy: 50, r, fill: "none", stroke: a.color, strokeWidth: 9, strokeDasharray: `${Math.max(0, a.len * c - (parts ? 2 : 0))} ${c}`, strokeDashoffset: -a.start * c, strokeLinecap: parts ? "butt" : "round" }, i))
|
|
2817
|
+
] }),
|
|
2818
|
+
children !== void 0 ? /* @__PURE__ */ jsx28(View24, { style: [StyleSheet25.absoluteFill, styles25.center], children }) : null
|
|
2819
|
+
] }),
|
|
2820
|
+
legend
|
|
2821
|
+
] });
|
|
2822
|
+
}
|
|
2823
|
+
return /* @__PURE__ */ jsxs25(View24, { accessible: true, ...a11y, style: [styles25.root, style], children: [
|
|
2824
|
+
showLabel ? /* @__PURE__ */ jsxs25(View24, { style: styles25.header, "aria-hidden": true, children: [
|
|
2825
|
+
/* @__PURE__ */ jsx28(Txt, { variant: "caption", numberOfLines: 1, style: styles25.caption, children: label }),
|
|
2826
|
+
!parts ? /* @__PURE__ */ jsx28(Txt, { variant: "caption", tone: "secondary", children: words }) : null
|
|
2827
|
+
] }) : null,
|
|
2828
|
+
/* @__PURE__ */ jsx28(View24, { style: [styles25.track, { height: THICK[size], backgroundColor: theme.surface3 }], children: parts ? shares.map((p, i) => /* @__PURE__ */ jsx28(View24, { style: { width: `${p.ratio * 100}%`, backgroundColor: p.color } }, i)) : /* @__PURE__ */ jsx28(View24, { style: [styles25.fill, { width: `${ratio * 100}%`, backgroundColor: tone3 }] }) }),
|
|
2829
|
+
legend
|
|
2830
|
+
] });
|
|
2831
|
+
}
|
|
2832
|
+
var styles25 = StyleSheet25.create({
|
|
2833
|
+
root: { width: "100%", gap: 6 },
|
|
2834
|
+
header: { flexDirection: "row", alignItems: "baseline", gap: 8 },
|
|
2835
|
+
caption: { flex: 1, fontWeight: "600" },
|
|
2836
|
+
track: { flexDirection: "row", gap: 2, borderRadius: 999, overflow: "hidden", width: "100%" },
|
|
2837
|
+
fill: { height: "100%", borderRadius: 999 },
|
|
2838
|
+
legend: { flexDirection: "row", flexWrap: "wrap", columnGap: 14, rowGap: 4, marginTop: 4 },
|
|
2839
|
+
legendItem: { flexDirection: "row", alignItems: "center", gap: 6 },
|
|
2840
|
+
swatch: { width: 8, height: 8, borderRadius: 4 },
|
|
2841
|
+
ringRoot: { alignItems: "center", gap: 8 },
|
|
2842
|
+
center: { alignItems: "center", justifyContent: "center" }
|
|
2843
|
+
});
|
|
2844
|
+
|
|
2845
|
+
// src/native/number-ticker.tsx
|
|
2846
|
+
import * as React22 from "react";
|
|
2847
|
+
import { AccessibilityInfo as AccessibilityInfo9, Animated as Animated12, Easing as Easing6, Text as Text13 } from "react-native";
|
|
2848
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
2849
|
+
function NumberTicker({ value, locale, format, trigger = "mount", duration = 1100, announce, variant = "display", tone: tone3 = "text", style }) {
|
|
2850
|
+
const reduce = useReducedMotion();
|
|
2851
|
+
const writer = React22.useMemo(() => new Intl.NumberFormat(locale, format), [locale, format]);
|
|
2852
|
+
const [shown, setShown] = React22.useState(() => reduce ? value : trigger === "mount" ? 0 : value);
|
|
2853
|
+
const [anim] = React22.useState(() => new Animated12.Value(trigger === "mount" ? 0 : value));
|
|
2854
|
+
const first = React22.useRef(true);
|
|
2855
|
+
React22.useEffect(() => {
|
|
2856
|
+
const isFirst = first.current;
|
|
2857
|
+
first.current = false;
|
|
2858
|
+
if (reduce || !isFirst && trigger === "mount" || isFirst && trigger === "change") {
|
|
2859
|
+
anim.setValue(value);
|
|
2860
|
+
setShown(value);
|
|
2861
|
+
if (!isFirst && announce) AccessibilityInfo9.announceForAccessibility(writer.format(value));
|
|
2862
|
+
return;
|
|
2863
|
+
}
|
|
2864
|
+
const id = anim.addListener(({ value: v }) => setShown(v));
|
|
2865
|
+
const run = Animated12.timing(anim, { toValue: value, duration, easing: Easing6.out(Easing6.cubic), useNativeDriver: false });
|
|
2866
|
+
run.start(({ finished }) => {
|
|
2867
|
+
if (finished) setShown(value);
|
|
2868
|
+
});
|
|
2869
|
+
if (!isFirst && announce) AccessibilityInfo9.announceForAccessibility(writer.format(value));
|
|
2870
|
+
return () => {
|
|
2871
|
+
run.stop();
|
|
2872
|
+
anim.removeListener(id);
|
|
2873
|
+
};
|
|
2874
|
+
}, [value, reduce, trigger, duration, announce, anim, writer]);
|
|
2875
|
+
const digits = Number.isInteger(value) ? Math.round(shown) : shown;
|
|
2876
|
+
return /* @__PURE__ */ jsx29(Txt, { variant, tone: tone3, "aria-label": writer.format(value), style: [{ fontVariant: ["tabular-nums"] }, style], children: /* @__PURE__ */ jsx29(Text13, { "aria-hidden": true, children: writer.format(digits) }) });
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
// src/native/onboarding.tsx
|
|
2880
|
+
import * as React23 from "react";
|
|
2881
|
+
import { ScrollView as ScrollView5, StyleSheet as StyleSheet26, View as View25 } from "react-native";
|
|
2882
|
+
import { jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2883
|
+
function Onboarding({ slides, labels, onDone, style }) {
|
|
2884
|
+
const { theme, insets, haptic } = useTheme();
|
|
2885
|
+
const [width, setWidth] = React23.useState(0);
|
|
2886
|
+
const [page, setPage] = React23.useState(0);
|
|
2887
|
+
const scroller = React23.useRef(null);
|
|
2888
|
+
const last = page === slides.length - 1;
|
|
2889
|
+
const go = (to) => {
|
|
2890
|
+
scroller.current?.scrollTo({ x: to * width, animated: true });
|
|
2891
|
+
setPage(to);
|
|
2892
|
+
haptic("selection");
|
|
2893
|
+
};
|
|
2894
|
+
const onScroll = (e) => {
|
|
2895
|
+
if (width > 0) setPage(Math.round(e.nativeEvent.contentOffset.x / width));
|
|
2896
|
+
};
|
|
2897
|
+
return /* @__PURE__ */ jsxs26(View25, { style: [styles26.root, { backgroundColor: theme.surface0, paddingTop: insets.top + 8, paddingBottom: insets.bottom + 16 }, style], onLayout: (e) => setWidth(e.nativeEvent.layout.width), children: [
|
|
2898
|
+
/* @__PURE__ */ jsx30(View25, { style: styles26.top, children: !last ? /* @__PURE__ */ jsx30(Button, { label: labels.skip, variant: "ghost", size: "sm", onPress: onDone }) : /* @__PURE__ */ jsx30(View25, { style: styles26.spacer }) }),
|
|
2899
|
+
/* @__PURE__ */ jsx30(ScrollView5, { ref: scroller, tabIndex: 0, horizontal: true, pagingEnabled: true, showsHorizontalScrollIndicator: false, onMomentumScrollEnd: onScroll, style: styles26.flex, children: slides.map((slide, i) => /* @__PURE__ */ jsxs26(View25, { style: [styles26.slide, { width: width || void 0 }], accessible: true, "aria-label": `${labels.position(i + 1, slides.length)}. ${slide.title}. ${slide.description}`, "aria-hidden": i !== page, children: [
|
|
2900
|
+
slide.visual ? /* @__PURE__ */ jsx30(View25, { style: styles26.visual, children: slide.visual }) : null,
|
|
2901
|
+
/* @__PURE__ */ jsx30(Txt, { variant: "display", style: styles26.centred, children: slide.title }),
|
|
2902
|
+
/* @__PURE__ */ jsx30(Txt, { tone: "secondary", style: [styles26.centred, styles26.description], children: slide.description })
|
|
2903
|
+
] }, i)) }),
|
|
2904
|
+
/* @__PURE__ */ jsx30(View25, { style: styles26.dots, "aria-hidden": true, children: slides.map((_, i) => /* @__PURE__ */ jsx30(View25, { style: [styles26.dot, { width: i === page ? 22 : 8, backgroundColor: i === page ? theme.accent : theme.borderStrong }] }, i)) }),
|
|
2905
|
+
/* @__PURE__ */ jsx30(View25, { style: styles26.bottom, children: /* @__PURE__ */ jsx30(Button, { label: last ? labels.done : labels.next, variant: last ? "gradient" : "primary", size: "lg", onPress: () => last ? onDone() : go(page + 1) }) })
|
|
2906
|
+
] });
|
|
2907
|
+
}
|
|
2908
|
+
var styles26 = StyleSheet26.create({
|
|
2909
|
+
root: { flex: 1 },
|
|
2910
|
+
top: { flexDirection: "row", justifyContent: "flex-end", paddingHorizontal: 16, minHeight: 32 },
|
|
2911
|
+
spacer: { height: 32 },
|
|
2912
|
+
flex: { flex: 1 },
|
|
2913
|
+
slide: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 32, gap: 12 },
|
|
2914
|
+
visual: { marginBottom: 12 },
|
|
2915
|
+
centred: { textAlign: "center" },
|
|
2916
|
+
description: { maxWidth: 340 },
|
|
2917
|
+
dots: { flexDirection: "row", justifyContent: "center", gap: 6, marginVertical: 16 },
|
|
2918
|
+
dot: { height: 8, borderRadius: 4 },
|
|
2919
|
+
bottom: { paddingHorizontal: 24 }
|
|
2920
|
+
});
|
|
2921
|
+
|
|
1990
2922
|
// src/native/OrazakaMark.tsx
|
|
1991
|
-
import { View as
|
|
1992
|
-
import
|
|
2923
|
+
import { View as View26 } from "react-native";
|
|
2924
|
+
import Svg11, { Circle as Circle6, Defs as Defs5, LinearGradient as LinearGradient5, Path as Path8, RadialGradient as RadialGradient2, Stop as Stop5 } from "react-native-svg";
|
|
1993
2925
|
|
|
1994
2926
|
// src/marks/orazaka-geometry.ts
|
|
1995
2927
|
var orange = marks.orazaka[marks.orazaka.length - 1][1];
|
|
@@ -2018,41 +2950,41 @@ var ORAZAKA = {
|
|
|
2018
2950
|
};
|
|
2019
2951
|
|
|
2020
2952
|
// src/native/OrazakaMark.tsx
|
|
2021
|
-
import { jsx as
|
|
2953
|
+
import { jsx as jsx31, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2022
2954
|
function OrazakaMark({ size = 48, animated = true, title, neutral }) {
|
|
2023
2955
|
const { theme } = useTheme();
|
|
2024
|
-
const { Animated:
|
|
2956
|
+
const { Animated: Animated22, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
|
|
2025
2957
|
const id = useSvgId("ozm");
|
|
2026
2958
|
const viewBox = size < 48 ? ORAZAKA.croppedViewBox : ORAZAKA.viewBox;
|
|
2027
2959
|
const stroke = neutral ?? theme.textMuted;
|
|
2028
|
-
const gradient = /* @__PURE__ */
|
|
2960
|
+
const gradient = /* @__PURE__ */ jsx31(LinearGradient5, { id: `${id}a`, gradientUnits: "userSpaceOnUse", x1: ORAZAKA.gradient.x1, y1: ORAZAKA.gradient.y1, x2: ORAZAKA.gradient.x2, y2: ORAZAKA.gradient.y2, children: ORAZAKA.gradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx31(Stop5, { offset, stopColor: color }, offset)) });
|
|
2029
2961
|
const fill = `url(#${id}a)`;
|
|
2030
|
-
return /* @__PURE__ */
|
|
2031
|
-
/* @__PURE__ */
|
|
2032
|
-
/* @__PURE__ */
|
|
2033
|
-
/* @__PURE__ */
|
|
2034
|
-
/* @__PURE__ */
|
|
2962
|
+
return /* @__PURE__ */ jsxs27(View26, { style: { width: size, height: size }, ...markA11y(title), children: [
|
|
2963
|
+
/* @__PURE__ */ jsxs27(Svg11, { viewBox, style: layer, children: [
|
|
2964
|
+
/* @__PURE__ */ jsx31(Defs5, { children: /* @__PURE__ */ jsxs27(RadialGradient2, { id: `${id}g`, cx: "50%", cy: "50%", r: "50%", children: [
|
|
2965
|
+
/* @__PURE__ */ jsx31(Stop5, { offset: "0%", stopColor: ORAZAKA.glow.color, stopOpacity: ORAZAKA.glow.opacity }),
|
|
2966
|
+
/* @__PURE__ */ jsx31(Stop5, { offset: "100%", stopColor: ORAZAKA.glow.color, stopOpacity: 0 })
|
|
2035
2967
|
] }) }),
|
|
2036
|
-
size >= 48 ? /* @__PURE__ */
|
|
2037
|
-
/* @__PURE__ */
|
|
2038
|
-
/* @__PURE__ */
|
|
2968
|
+
size >= 48 ? /* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: 190, fill: `url(#${id}g)` }) : null,
|
|
2969
|
+
/* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.orbit.r, stroke, strokeWidth: ORAZAKA.orbit.width, strokeDasharray: ORAZAKA.orbit.dash, opacity: 0.6, fill: "none" }),
|
|
2970
|
+
/* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.ring.r, stroke, strokeWidth: ORAZAKA.ring.width, opacity: 0.35, fill: "none" })
|
|
2039
2971
|
] }),
|
|
2040
|
-
/* @__PURE__ */
|
|
2041
|
-
/* @__PURE__ */
|
|
2042
|
-
ORAZAKA.shards.map((d) => /* @__PURE__ */
|
|
2972
|
+
/* @__PURE__ */ jsx31(Animated22.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs27(Svg11, { viewBox, style: layer, children: [
|
|
2973
|
+
/* @__PURE__ */ jsx31(Defs5, { children: gradient }),
|
|
2974
|
+
ORAZAKA.shards.map((d) => /* @__PURE__ */ jsx31(Path8, { d, fill, stroke: fill, strokeWidth: ORAZAKA.shardStroke, strokeLinejoin: "round" }, d))
|
|
2043
2975
|
] }) }),
|
|
2044
|
-
/* @__PURE__ */
|
|
2045
|
-
/* @__PURE__ */
|
|
2046
|
-
/* @__PURE__ */
|
|
2047
|
-
/* @__PURE__ */
|
|
2976
|
+
/* @__PURE__ */ jsx31(Animated22.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs27(Svg11, { viewBox, style: layer, children: [
|
|
2977
|
+
/* @__PURE__ */ jsx31(Defs5, { children: gradient }),
|
|
2978
|
+
/* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.core.r, fill }),
|
|
2979
|
+
/* @__PURE__ */ jsx31(Circle6, { cx: ORAZAKA.center, cy: ORAZAKA.center, r: ORAZAKA.core.inner, fill: ORAZAKA.highlight })
|
|
2048
2980
|
] }) })
|
|
2049
2981
|
] });
|
|
2050
2982
|
}
|
|
2051
2983
|
|
|
2052
2984
|
// src/native/OrochiaMark.tsx
|
|
2053
|
-
import { useEffect as
|
|
2054
|
-
import { AccessibilityInfo as
|
|
2055
|
-
import
|
|
2985
|
+
import { useEffect as useEffect15, useState as useState24 } from "react";
|
|
2986
|
+
import { AccessibilityInfo as AccessibilityInfo10, Animated as Animated13, Easing as Easing7, View as View27 } from "react-native";
|
|
2987
|
+
import Svg12, { Circle as Circle7, Defs as Defs6, Ellipse as Ellipse2, G as Group2, LinearGradient as LinearGradient6, Path as Path9, RadialGradient as RadialGradient3, Stop as Stop6 } from "react-native-svg";
|
|
2056
2988
|
|
|
2057
2989
|
// src/marks/orochia-geometry.ts
|
|
2058
2990
|
var OROCHIA = {
|
|
@@ -2079,25 +3011,25 @@ var OROCHIA = {
|
|
|
2079
3011
|
};
|
|
2080
3012
|
|
|
2081
3013
|
// src/native/OrochiaMark.tsx
|
|
2082
|
-
import { jsx as
|
|
3014
|
+
import { jsx as jsx32, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2083
3015
|
var CENTER = OROCHIA.offset + 180;
|
|
2084
3016
|
function OrochiaMark({ size = 48, animated = true, title, neutral: neutralProp }) {
|
|
2085
3017
|
const { theme } = useTheme();
|
|
2086
3018
|
const neutral = neutralProp ?? theme.textMuted;
|
|
2087
|
-
const [spin] =
|
|
2088
|
-
const [pulse] =
|
|
2089
|
-
|
|
3019
|
+
const [spin] = useState24(() => new Animated13.Value(0));
|
|
3020
|
+
const [pulse] = useState24(() => new Animated13.Value(0));
|
|
3021
|
+
useEffect15(() => {
|
|
2090
3022
|
if (!animated) return;
|
|
2091
3023
|
let loops = [];
|
|
2092
3024
|
let cancelled = false;
|
|
2093
|
-
void
|
|
3025
|
+
void AccessibilityInfo10.isReduceMotionEnabled().then((reduce) => {
|
|
2094
3026
|
if (reduce || cancelled) return;
|
|
2095
3027
|
loops = [
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
3028
|
+
Animated13.loop(Animated13.timing(spin, { toValue: 1, duration: 3e4, easing: Easing7.linear, useNativeDriver: true })),
|
|
3029
|
+
Animated13.loop(
|
|
3030
|
+
Animated13.sequence([
|
|
3031
|
+
Animated13.timing(pulse, { toValue: 1, duration: 1600, easing: Easing7.inOut(Easing7.ease), useNativeDriver: true }),
|
|
3032
|
+
Animated13.timing(pulse, { toValue: 0, duration: 1600, easing: Easing7.inOut(Easing7.ease), useNativeDriver: true })
|
|
2101
3033
|
])
|
|
2102
3034
|
)
|
|
2103
3035
|
];
|
|
@@ -2111,44 +3043,117 @@ function OrochiaMark({ size = 48, animated = true, title, neutral: neutralProp }
|
|
|
2111
3043
|
const viewBox = size < 48 ? OROCHIA.croppedViewBox : OROCHIA.viewBox;
|
|
2112
3044
|
const layer = { position: "absolute", width: size, height: size };
|
|
2113
3045
|
const a11y = title ? { accessible: true, accessibilityRole: "image", accessibilityLabel: title } : { accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants" };
|
|
2114
|
-
const bodyGradient = /* @__PURE__ */
|
|
2115
|
-
return /* @__PURE__ */
|
|
2116
|
-
/* @__PURE__ */
|
|
2117
|
-
/* @__PURE__ */
|
|
2118
|
-
/* @__PURE__ */
|
|
2119
|
-
/* @__PURE__ */
|
|
3046
|
+
const bodyGradient = /* @__PURE__ */ jsx32(LinearGradient6, { id: "body", gradientUnits: "userSpaceOnUse", x1: OROCHIA.body.x1 + OROCHIA.offset, y1: OROCHIA.body.y1 + OROCHIA.offset, x2: OROCHIA.body.x2 + OROCHIA.offset, y2: OROCHIA.body.y2 + OROCHIA.offset, children: OROCHIA.body.stops.map(([offset, color]) => /* @__PURE__ */ jsx32(Stop6, { offset, stopColor: color }, offset)) });
|
|
3047
|
+
return /* @__PURE__ */ jsxs28(View27, { style: { width: size, height: size }, ...a11y, children: [
|
|
3048
|
+
/* @__PURE__ */ jsxs28(Svg12, { viewBox, style: layer, children: [
|
|
3049
|
+
/* @__PURE__ */ jsx32(Defs6, { children: /* @__PURE__ */ jsxs28(RadialGradient3, { id: "glow", cx: "50%", cy: "50%", r: "50%", children: [
|
|
3050
|
+
/* @__PURE__ */ jsx32(Stop6, { offset: "0%", stopColor: OROCHIA.glow.color, stopOpacity: OROCHIA.glow.opacity }),
|
|
3051
|
+
/* @__PURE__ */ jsx32(Stop6, { offset: "100%", stopColor: OROCHIA.glow.color, stopOpacity: 0 })
|
|
2120
3052
|
] }) }),
|
|
2121
|
-
/* @__PURE__ */
|
|
2122
|
-
/* @__PURE__ */
|
|
3053
|
+
/* @__PURE__ */ jsx32(Circle7, { cx: CENTER, cy: CENTER, r: 170, fill: "url(#glow)" }),
|
|
3054
|
+
/* @__PURE__ */ jsx32(Circle7, { cx: CENTER, cy: CENTER, r: OROCHIA.ring.r, stroke: neutral, strokeWidth: OROCHIA.ring.width, opacity: 0.35, fill: "none" })
|
|
2123
3055
|
] }),
|
|
2124
|
-
/* @__PURE__ */
|
|
2125
|
-
/* @__PURE__ */
|
|
2126
|
-
/* @__PURE__ */
|
|
2127
|
-
/* @__PURE__ */
|
|
2128
|
-
/* @__PURE__ */
|
|
2129
|
-
/* @__PURE__ */
|
|
2130
|
-
/* @__PURE__ */
|
|
2131
|
-
/* @__PURE__ */
|
|
2132
|
-
/* @__PURE__ */
|
|
2133
|
-
/* @__PURE__ */
|
|
3056
|
+
/* @__PURE__ */ jsx32(Animated13.View, { style: [layer, { transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] }) }] }], children: /* @__PURE__ */ jsx32(Svg12, { viewBox, style: layer, children: /* @__PURE__ */ jsx32(Circle7, { cx: CENTER, cy: CENTER, r: OROCHIA.orbit.r, stroke: neutral, strokeWidth: OROCHIA.orbit.width, strokeDasharray: OROCHIA.orbit.dash, opacity: 0.6, fill: "none" }) }) }),
|
|
3057
|
+
/* @__PURE__ */ jsxs28(Svg12, { viewBox, style: layer, children: [
|
|
3058
|
+
/* @__PURE__ */ jsx32(Defs6, { children: bodyGradient }),
|
|
3059
|
+
/* @__PURE__ */ jsxs28(Group2, { transform: `translate(${OROCHIA.offset} ${OROCHIA.offset})`, children: [
|
|
3060
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.arc, stroke: "url(#body)", strokeWidth: 22, strokeLinecap: "round", fill: "none" }),
|
|
3061
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.arc, stroke: OROCHIA.scales.color, strokeOpacity: OROCHIA.scales.opacity, strokeWidth: OROCHIA.scales.width, strokeLinecap: "round", strokeDasharray: OROCHIA.scales.dash, fill: "none" }),
|
|
3062
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.neck, stroke: "url(#body)", strokeWidth: 14, strokeLinecap: "round", fill: "none" }),
|
|
3063
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.tail, stroke: "url(#body)", strokeWidth: 6, strokeLinecap: "round", fill: "none" }),
|
|
3064
|
+
/* @__PURE__ */ jsx32(Ellipse2, { cx: OROCHIA.head.cx, cy: OROCHIA.head.cy, rx: OROCHIA.head.rx, ry: OROCHIA.head.ry, rotation: OROCHIA.head.rotate, origin: `${OROCHIA.head.cx}, ${OROCHIA.head.cy}`, fill: "url(#body)" }),
|
|
3065
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.tongue.d, stroke: OROCHIA.tongue.color, strokeWidth: 3, strokeLinecap: "round", fill: "none" })
|
|
2134
3066
|
] })
|
|
2135
3067
|
] }),
|
|
2136
|
-
/* @__PURE__ */
|
|
2137
|
-
/* @__PURE__ */
|
|
2138
|
-
/* @__PURE__ */
|
|
2139
|
-
/* @__PURE__ */
|
|
2140
|
-
/* @__PURE__ */
|
|
3068
|
+
/* @__PURE__ */ jsx32(Animated13.View, { style: [layer, { opacity: pulse.interpolate({ inputRange: [0, 1], outputRange: [0.85, 1] }) }], children: /* @__PURE__ */ jsxs28(Svg12, { viewBox, style: layer, children: [
|
|
3069
|
+
/* @__PURE__ */ jsx32(Defs6, { children: /* @__PURE__ */ jsx32(LinearGradient6, { id: "flame", x1: "50%", y1: "100%", x2: "50%", y2: "0%", children: OROCHIA.flameGradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx32(Stop6, { offset, stopColor: color }, offset)) }) }),
|
|
3070
|
+
/* @__PURE__ */ jsxs28(Group2, { transform: `translate(${OROCHIA.offset} ${OROCHIA.offset})`, children: [
|
|
3071
|
+
/* @__PURE__ */ jsx32(Circle7, { cx: OROCHIA.eye.cx, cy: OROCHIA.eye.cy, r: OROCHIA.eye.r, fill: OROCHIA.eye.color }),
|
|
3072
|
+
/* @__PURE__ */ jsx32(Path9, { d: OROCHIA.flame.d, transform: `translate(${OROCHIA.flame.translate[0]} ${OROCHIA.flame.translate[1]}) scale(${OROCHIA.flame.scale})`, fill: "url(#flame)" })
|
|
2141
3073
|
] })
|
|
2142
3074
|
] }) })
|
|
2143
3075
|
] });
|
|
2144
3076
|
}
|
|
2145
3077
|
|
|
3078
|
+
// src/native/otp-input.tsx
|
|
3079
|
+
import * as React25 from "react";
|
|
3080
|
+
import { Platform as Platform2, Pressable as Pressable13, StyleSheet as StyleSheet27, TextInput as TextInput4, View as View28 } from "react-native";
|
|
3081
|
+
import { jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
3082
|
+
function OtpInput({ label, length = 6, value, onValueChange, onComplete, mode = "numeric", invalid, disabled, autoFocus, style }) {
|
|
3083
|
+
const { theme, radius: radius3, haptic } = useTheme();
|
|
3084
|
+
const [own, setOwn] = React25.useState("");
|
|
3085
|
+
const code = value ?? own;
|
|
3086
|
+
const [focused, setFocused] = React25.useState(false);
|
|
3087
|
+
const input = React25.useRef(null);
|
|
3088
|
+
React25.useEffect(() => {
|
|
3089
|
+
if (invalid) haptic("warning");
|
|
3090
|
+
}, [invalid, haptic]);
|
|
3091
|
+
const change = (raw) => {
|
|
3092
|
+
const next = (mode === "numeric" ? raw.replace(/\D/g, "") : raw.replace(/\s/g, "").toUpperCase()).slice(0, length);
|
|
3093
|
+
if (value === void 0) setOwn(next);
|
|
3094
|
+
onValueChange?.(next);
|
|
3095
|
+
if (next.length === length && code.length !== length) {
|
|
3096
|
+
haptic("success");
|
|
3097
|
+
onComplete?.(next);
|
|
3098
|
+
}
|
|
3099
|
+
};
|
|
3100
|
+
return /* @__PURE__ */ jsxs29(Pressable13, { onPress: () => input.current?.focus(), disabled, accessible: false, style: [styles27.root, style], children: [
|
|
3101
|
+
/* @__PURE__ */ jsx33(View28, { style: styles27.boxes, "aria-hidden": true, children: Array.from({ length }, (_, i) => {
|
|
3102
|
+
const active = focused && i === Math.min(code.length, length - 1);
|
|
3103
|
+
return /* @__PURE__ */ jsx33(
|
|
3104
|
+
View28,
|
|
3105
|
+
{
|
|
3106
|
+
style: [
|
|
3107
|
+
styles27.box,
|
|
3108
|
+
{
|
|
3109
|
+
borderRadius: radius3.md,
|
|
3110
|
+
backgroundColor: theme.surface2,
|
|
3111
|
+
borderColor: invalid ? theme.danger : active ? theme.ring : theme.borderDefault,
|
|
3112
|
+
borderWidth: invalid || active ? 2 : 1
|
|
3113
|
+
}
|
|
3114
|
+
],
|
|
3115
|
+
children: /* @__PURE__ */ jsx33(Txt, { variant: "title", children: code[i] ?? "" })
|
|
3116
|
+
},
|
|
3117
|
+
i
|
|
3118
|
+
);
|
|
3119
|
+
}) }),
|
|
3120
|
+
/* @__PURE__ */ jsx33(
|
|
3121
|
+
TextInput4,
|
|
3122
|
+
{
|
|
3123
|
+
ref: input,
|
|
3124
|
+
"aria-label": label,
|
|
3125
|
+
"aria-invalid": invalid || void 0,
|
|
3126
|
+
value: code,
|
|
3127
|
+
onChangeText: change,
|
|
3128
|
+
maxLength: length,
|
|
3129
|
+
editable: !disabled,
|
|
3130
|
+
autoFocus,
|
|
3131
|
+
keyboardType: mode === "numeric" ? "number-pad" : "default",
|
|
3132
|
+
textContentType: "oneTimeCode",
|
|
3133
|
+
autoComplete: Platform2.OS === "android" && mode === "numeric" ? "sms-otp" : "one-time-code",
|
|
3134
|
+
autoCapitalize: "characters",
|
|
3135
|
+
autoCorrect: false,
|
|
3136
|
+
caretHidden: true,
|
|
3137
|
+
onFocus: () => setFocused(true),
|
|
3138
|
+
onBlur: () => setFocused(false),
|
|
3139
|
+
style: styles27.hidden
|
|
3140
|
+
}
|
|
3141
|
+
)
|
|
3142
|
+
] });
|
|
3143
|
+
}
|
|
3144
|
+
var styles27 = StyleSheet27.create({
|
|
3145
|
+
root: { alignSelf: "flex-start" },
|
|
3146
|
+
boxes: { flexDirection: "row", gap: 8 },
|
|
3147
|
+
box: { width: 46, height: 56, alignItems: "center", justifyContent: "center" },
|
|
3148
|
+
hidden: { position: "absolute", top: 0, left: 0, right: 0, bottom: 0, opacity: 0.011, color: "transparent" }
|
|
3149
|
+
});
|
|
3150
|
+
|
|
2146
3151
|
// src/native/pagination.tsx
|
|
2147
|
-
import { Pressable as
|
|
2148
|
-
import
|
|
2149
|
-
import { jsx as
|
|
2150
|
-
function
|
|
2151
|
-
return /* @__PURE__ */
|
|
3152
|
+
import { Pressable as Pressable14, StyleSheet as StyleSheet28, Text as Text14, View as View29 } from "react-native";
|
|
3153
|
+
import Svg13, { Path as Path10 } from "react-native-svg";
|
|
3154
|
+
import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
3155
|
+
function Chevron3({ direction, color }) {
|
|
3156
|
+
return /* @__PURE__ */ jsx34(Svg13, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 2.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx34(Path10, { d: direction === "left" ? "m15 6-6 6 6 6" : "m9 6 6 6-6 6" }) });
|
|
2152
3157
|
}
|
|
2153
3158
|
function Pagination({ page = 1, pageCount, onPageChange, hasPrevious, hasNext, onPrevious, onNext, status, disabled, labels, style }) {
|
|
2154
3159
|
const { theme, radius: radius3 } = useTheme();
|
|
@@ -2157,8 +3162,8 @@ function Pagination({ page = 1, pageCount, onPageChange, hasPrevious, hasNext, o
|
|
|
2157
3162
|
const current = Math.min(Math.max(1, page), count);
|
|
2158
3163
|
const canPrevious = !disabled && (paged ? current > 1 : Boolean(hasPrevious));
|
|
2159
3164
|
const canNext = !disabled && (paged ? current < count : Boolean(hasNext));
|
|
2160
|
-
const button = (direction, enabled, onPress, label) => /* @__PURE__ */
|
|
2161
|
-
|
|
3165
|
+
const button = (direction, enabled, onPress, label) => /* @__PURE__ */ jsx34(
|
|
3166
|
+
Pressable14,
|
|
2162
3167
|
{
|
|
2163
3168
|
role: "button",
|
|
2164
3169
|
"aria-label": label,
|
|
@@ -2167,29 +3172,66 @@ function Pagination({ page = 1, pageCount, onPageChange, hasPrevious, hasNext, o
|
|
|
2167
3172
|
hitSlop: 6,
|
|
2168
3173
|
onPress,
|
|
2169
3174
|
style: ({ pressed }) => [
|
|
2170
|
-
|
|
3175
|
+
styles28.button,
|
|
2171
3176
|
{ borderRadius: radius3.sm, borderColor: theme.borderDefault, backgroundColor: theme.surface1, opacity: enabled ? pressed ? 0.8 : 1 : 0.4 }
|
|
2172
3177
|
],
|
|
2173
|
-
children: /* @__PURE__ */
|
|
3178
|
+
children: /* @__PURE__ */ jsx34(Chevron3, { direction, color: theme.textPrimary })
|
|
2174
3179
|
}
|
|
2175
3180
|
);
|
|
2176
3181
|
const text = status ?? (paged ? labels.compact(current, count) : null);
|
|
2177
|
-
return /* @__PURE__ */
|
|
3182
|
+
return /* @__PURE__ */ jsxs30(View29, { role: "navigation", style: [styles28.row, style], children: [
|
|
2178
3183
|
button("left", canPrevious, paged ? () => onPageChange?.(current - 1) : onPrevious, labels.previous),
|
|
2179
|
-
text ? /* @__PURE__ */
|
|
3184
|
+
text ? /* @__PURE__ */ jsx34(Text14, { "aria-live": "polite", style: [styles28.status, { color: theme.textSecondary }], children: text }) : null,
|
|
2180
3185
|
button("right", canNext, paged ? () => onPageChange?.(current + 1) : onNext, labels.next)
|
|
2181
3186
|
] });
|
|
2182
3187
|
}
|
|
2183
|
-
var
|
|
3188
|
+
var styles28 = StyleSheet28.create({
|
|
2184
3189
|
row: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: 12 },
|
|
2185
|
-
button: { width: 44, height: 44, alignItems: "center", justifyContent: "center", borderWidth:
|
|
3190
|
+
button: { width: 44, height: 44, alignItems: "center", justifyContent: "center", borderWidth: StyleSheet28.hairlineWidth },
|
|
2186
3191
|
status: { fontSize: 13, fontWeight: "600", fontVariant: ["tabular-nums"] }
|
|
2187
3192
|
});
|
|
2188
3193
|
|
|
3194
|
+
// src/native/permission-prompt.tsx
|
|
3195
|
+
import { StyleSheet as StyleSheet29, View as View30 } from "react-native";
|
|
3196
|
+
import { Fragment as Fragment5, jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
3197
|
+
function PermissionPrompt({
|
|
3198
|
+
status,
|
|
3199
|
+
title,
|
|
3200
|
+
description,
|
|
3201
|
+
allowLabel,
|
|
3202
|
+
onAllow,
|
|
3203
|
+
settingsLabel,
|
|
3204
|
+
onOpenSettings,
|
|
3205
|
+
blockedDescription,
|
|
3206
|
+
dismissLabel,
|
|
3207
|
+
onDismiss,
|
|
3208
|
+
mascot = "falcon",
|
|
3209
|
+
children,
|
|
3210
|
+
style
|
|
3211
|
+
}) {
|
|
3212
|
+
const { theme, radius: radius3 } = useTheme();
|
|
3213
|
+
if (status === "granted") return /* @__PURE__ */ jsx35(Fragment5, { children: children ?? null });
|
|
3214
|
+
const blocked = status === "blocked" || status === "denied" && Boolean(onOpenSettings);
|
|
3215
|
+
return /* @__PURE__ */ jsxs31(View30, { style: [styles29.root, { backgroundColor: theme.surface1, borderColor: theme.borderSubtle, borderRadius: radius3.xl }, style], children: [
|
|
3216
|
+
/* @__PURE__ */ jsx35(Mascot, { bird: mascot, mood: blocked ? "error" : "welcome", size: 104 }),
|
|
3217
|
+
/* @__PURE__ */ jsx35(Txt, { variant: "title", style: styles29.centred, children: title }),
|
|
3218
|
+
/* @__PURE__ */ jsx35(Txt, { tone: "secondary", style: styles29.centred, children: blocked && blockedDescription ? blockedDescription : description }),
|
|
3219
|
+
/* @__PURE__ */ jsxs31(View30, { style: styles29.actions, children: [
|
|
3220
|
+
blocked && settingsLabel && onOpenSettings ? /* @__PURE__ */ jsx35(Button, { label: settingsLabel, variant: "primary", onPress: onOpenSettings }) : /* @__PURE__ */ jsx35(Button, { label: allowLabel, variant: "primary", onPress: onAllow }),
|
|
3221
|
+
dismissLabel && onDismiss ? /* @__PURE__ */ jsx35(Button, { label: dismissLabel, variant: "ghost", onPress: onDismiss }) : null
|
|
3222
|
+
] })
|
|
3223
|
+
] });
|
|
3224
|
+
}
|
|
3225
|
+
var styles29 = StyleSheet29.create({
|
|
3226
|
+
root: { alignItems: "center", gap: 10, padding: 24, borderWidth: StyleSheet29.hairlineWidth },
|
|
3227
|
+
centred: { textAlign: "center", maxWidth: 340 },
|
|
3228
|
+
actions: { marginTop: 8, gap: 8, alignSelf: "stretch" }
|
|
3229
|
+
});
|
|
3230
|
+
|
|
2189
3231
|
// src/native/phoenix.tsx
|
|
2190
|
-
import { useEffect as
|
|
2191
|
-
import { AccessibilityInfo as
|
|
2192
|
-
import
|
|
3232
|
+
import { useEffect as useEffect17, useState as useState26 } from "react";
|
|
3233
|
+
import { AccessibilityInfo as AccessibilityInfo11, Animated as Animated14, Easing as Easing8, View as View31 } from "react-native";
|
|
3234
|
+
import Svg14, { Circle as Circle8, Defs as Defs7, LinearGradient as LinearGradient7, Path as Path11, RadialGradient as RadialGradient4, Stop as Stop7 } from "react-native-svg";
|
|
2193
3235
|
|
|
2194
3236
|
// src/mascots/phoenix-geometry.ts
|
|
2195
3237
|
var PHOENIX = {
|
|
@@ -2212,17 +3254,17 @@ var PHOENIX_PALETTES = {
|
|
|
2212
3254
|
};
|
|
2213
3255
|
|
|
2214
3256
|
// src/native/phoenix.tsx
|
|
2215
|
-
import { jsx as
|
|
3257
|
+
import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2216
3258
|
function useFloat(animated) {
|
|
2217
|
-
const [y] =
|
|
2218
|
-
|
|
3259
|
+
const [y] = useState26(() => new Animated14.Value(0));
|
|
3260
|
+
useEffect17(() => {
|
|
2219
3261
|
if (!animated) return;
|
|
2220
3262
|
let loop;
|
|
2221
3263
|
let cancelled = false;
|
|
2222
|
-
void
|
|
3264
|
+
void AccessibilityInfo11.isReduceMotionEnabled().then((reduce) => {
|
|
2223
3265
|
if (reduce || cancelled) return;
|
|
2224
|
-
const step = (toValue) =>
|
|
2225
|
-
loop =
|
|
3266
|
+
const step = (toValue) => Animated14.timing(y, { toValue, duration: 2500, easing: Easing8.inOut(Easing8.ease), useNativeDriver: true });
|
|
3267
|
+
loop = Animated14.loop(Animated14.sequence([step(-6), step(0)]));
|
|
2226
3268
|
loop.start();
|
|
2227
3269
|
});
|
|
2228
3270
|
return () => {
|
|
@@ -2232,41 +3274,41 @@ function useFloat(animated) {
|
|
|
2232
3274
|
}, [animated, y]);
|
|
2233
3275
|
return y;
|
|
2234
3276
|
}
|
|
2235
|
-
function Phoenix({ tone:
|
|
3277
|
+
function Phoenix({ tone: tone3 = "own", size = 120, animated = true, title, style }) {
|
|
2236
3278
|
const { theme } = useTheme();
|
|
2237
3279
|
const id = useSvgId("kzp");
|
|
2238
3280
|
const y = useFloat(animated);
|
|
2239
|
-
const p =
|
|
2240
|
-
return /* @__PURE__ */
|
|
2241
|
-
/* @__PURE__ */
|
|
2242
|
-
/* @__PURE__ */
|
|
2243
|
-
/* @__PURE__ */
|
|
2244
|
-
/* @__PURE__ */
|
|
3281
|
+
const p = tone3 === "brand" ? { left: [theme.accent2, theme.accent], right: [theme.accent, theme.accent2], core: ["#ffffff", theme.accent], body: theme.surface3, edge: theme.borderStrong, crest: theme.accent } : PHOENIX_PALETTES.own;
|
|
3282
|
+
return /* @__PURE__ */ jsx36(View31, { style: [{ width: size, height: size }, style], ...markA11y(title), children: /* @__PURE__ */ jsx36(Animated14.View, { style: { transform: [{ translateY: y }] }, children: /* @__PURE__ */ jsxs32(Svg14, { width: size, height: size, viewBox: "0 0 120 120", children: [
|
|
3283
|
+
/* @__PURE__ */ jsxs32(Defs7, { children: [
|
|
3284
|
+
/* @__PURE__ */ jsxs32(LinearGradient7, { id: `${id}l`, x1: "1", y1: "0", x2: "0", y2: "1", children: [
|
|
3285
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "0%", stopColor: p.left[0] }),
|
|
3286
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "100%", stopColor: p.left[1] })
|
|
2245
3287
|
] }),
|
|
2246
|
-
/* @__PURE__ */
|
|
2247
|
-
/* @__PURE__ */
|
|
2248
|
-
/* @__PURE__ */
|
|
3288
|
+
/* @__PURE__ */ jsxs32(LinearGradient7, { id: `${id}r`, x1: "0", y1: "0", x2: "1", y2: "1", children: [
|
|
3289
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "0%", stopColor: p.right[0] }),
|
|
3290
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "100%", stopColor: p.right[1] })
|
|
2249
3291
|
] }),
|
|
2250
|
-
/* @__PURE__ */
|
|
2251
|
-
/* @__PURE__ */
|
|
2252
|
-
/* @__PURE__ */
|
|
3292
|
+
/* @__PURE__ */ jsxs32(RadialGradient4, { id: `${id}c`, children: [
|
|
3293
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "0%", stopColor: p.core[0] }),
|
|
3294
|
+
/* @__PURE__ */ jsx36(Stop7, { offset: "100%", stopColor: p.core[1], stopOpacity: 0 })
|
|
2253
3295
|
] })
|
|
2254
3296
|
] }),
|
|
2255
|
-
/* @__PURE__ */
|
|
2256
|
-
/* @__PURE__ */
|
|
2257
|
-
/* @__PURE__ */
|
|
2258
|
-
/* @__PURE__ */
|
|
2259
|
-
/* @__PURE__ */
|
|
2260
|
-
/* @__PURE__ */
|
|
2261
|
-
/* @__PURE__ */
|
|
2262
|
-
/* @__PURE__ */
|
|
3297
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.wingL, fill: `url(#${id}l)` }),
|
|
3298
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.wingR, fill: `url(#${id}r)` }),
|
|
3299
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.tailL, fill: `url(#${id}l)`, opacity: 0.7 }),
|
|
3300
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.tailR, fill: `url(#${id}r)`, opacity: 0.7 }),
|
|
3301
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.body, fill: p.body, stroke: p.edge, strokeOpacity: 0.5 }),
|
|
3302
|
+
/* @__PURE__ */ jsx36(Circle8, { cx: 60, cy: 58, r: 12, fill: `url(#${id}c)` }),
|
|
3303
|
+
/* @__PURE__ */ jsx36(Circle8, { cx: 60, cy: 58, r: 3.5, fill: "#ffffff" }),
|
|
3304
|
+
/* @__PURE__ */ jsx36(Path11, { d: PHOENIX.crest, stroke: p.crest, strokeWidth: 2, strokeLinecap: "round" })
|
|
2263
3305
|
] }) }) });
|
|
2264
3306
|
}
|
|
2265
3307
|
|
|
2266
3308
|
// src/native/YazakiaMark.tsx
|
|
2267
|
-
import
|
|
2268
|
-
import { View as
|
|
2269
|
-
import
|
|
3309
|
+
import React27 from "react";
|
|
3310
|
+
import { View as View32 } from "react-native";
|
|
3311
|
+
import Svg15, { Circle as Circle9, Defs as Defs8, LinearGradient as LinearGradient8, Path as Path12, RadialGradient as RadialGradient5, Stop as Stop8 } from "react-native-svg";
|
|
2270
3312
|
|
|
2271
3313
|
// src/marks/yazakia-geometry.ts
|
|
2272
3314
|
var turquoise = marks.yazakia[marks.yazakia.length - 1][1];
|
|
@@ -2296,54 +3338,54 @@ var YAZAKIA = {
|
|
|
2296
3338
|
};
|
|
2297
3339
|
|
|
2298
3340
|
// src/native/YazakiaMark.tsx
|
|
2299
|
-
import { jsx as
|
|
3341
|
+
import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2300
3342
|
function YazakiaMark({ size = 48, animated = true, title, neutral }) {
|
|
2301
3343
|
const { theme } = useTheme();
|
|
2302
|
-
const { Animated:
|
|
3344
|
+
const { Animated: Animated22, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated);
|
|
2303
3345
|
const id = useSvgId("yzm");
|
|
2304
3346
|
const viewBox = size < 48 ? YAZAKIA.croppedViewBox : YAZAKIA.viewBox;
|
|
2305
3347
|
const stroke = neutral ?? theme.textMuted;
|
|
2306
|
-
const gradient = /* @__PURE__ */
|
|
3348
|
+
const gradient = /* @__PURE__ */ jsx37(LinearGradient8, { id: `${id}a`, gradientUnits: "userSpaceOnUse", x1: YAZAKIA.gradient.x1, y1: YAZAKIA.gradient.y1, x2: YAZAKIA.gradient.x2, y2: YAZAKIA.gradient.y2, children: YAZAKIA.gradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx37(Stop8, { offset, stopColor: color }, offset)) });
|
|
2307
3349
|
const fill = `url(#${id}a)`;
|
|
2308
|
-
return /* @__PURE__ */
|
|
2309
|
-
/* @__PURE__ */
|
|
2310
|
-
/* @__PURE__ */
|
|
2311
|
-
/* @__PURE__ */
|
|
2312
|
-
/* @__PURE__ */
|
|
2313
|
-
/* @__PURE__ */
|
|
3350
|
+
return /* @__PURE__ */ jsxs33(View32, { style: { width: size, height: size }, ...markA11y(title), children: [
|
|
3351
|
+
/* @__PURE__ */ jsxs33(Svg15, { viewBox, style: layer, children: [
|
|
3352
|
+
/* @__PURE__ */ jsxs33(Defs8, { children: [
|
|
3353
|
+
/* @__PURE__ */ jsxs33(RadialGradient5, { id: `${id}g`, cx: "50%", cy: "50%", r: "50%", children: [
|
|
3354
|
+
/* @__PURE__ */ jsx37(Stop8, { offset: "0%", stopColor: YAZAKIA.glow.color, stopOpacity: YAZAKIA.glow.opacity }),
|
|
3355
|
+
/* @__PURE__ */ jsx37(Stop8, { offset: "100%", stopColor: YAZAKIA.glow.color, stopOpacity: 0 })
|
|
2314
3356
|
] }),
|
|
2315
3357
|
gradient
|
|
2316
3358
|
] }),
|
|
2317
|
-
size >= 48 ? /* @__PURE__ */
|
|
2318
|
-
/* @__PURE__ */
|
|
2319
|
-
YAZAKIA.voices.map((v, i) => /* @__PURE__ */
|
|
2320
|
-
/* @__PURE__ */
|
|
2321
|
-
/* @__PURE__ */
|
|
2322
|
-
i === 0 ? /* @__PURE__ */
|
|
3359
|
+
size >= 48 ? /* @__PURE__ */ jsx37(Circle9, { cx: YAZAKIA.center, cy: YAZAKIA.center, r: 190, fill: `url(#${id}g)` }) : null,
|
|
3360
|
+
/* @__PURE__ */ jsx37(Circle9, { cx: YAZAKIA.center, cy: YAZAKIA.center, r: YAZAKIA.ring.r, stroke, strokeWidth: YAZAKIA.ring.width, opacity: 0.35, fill: "none" }),
|
|
3361
|
+
YAZAKIA.voices.map((v, i) => /* @__PURE__ */ jsxs33(React27.Fragment, { children: [
|
|
3362
|
+
/* @__PURE__ */ jsx37(Path12, { d: v.body, fill }),
|
|
3363
|
+
/* @__PURE__ */ jsx37(Path12, { d: v.tail, fill }),
|
|
3364
|
+
i === 0 ? /* @__PURE__ */ jsx37(Path12, { d: `${v.body} ${v.tail}`, fill: YAZAKIA.shade.color, opacity: YAZAKIA.shade.opacity }) : null
|
|
2323
3365
|
] }, v.body))
|
|
2324
3366
|
] }),
|
|
2325
|
-
/* @__PURE__ */
|
|
2326
|
-
/* @__PURE__ */
|
|
2327
|
-
/* @__PURE__ */
|
|
2328
|
-
YAZAKIA.pair.at.map(([cx, cy]) => /* @__PURE__ */
|
|
3367
|
+
/* @__PURE__ */ jsx37(Animated22.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs33(Svg15, { viewBox, style: layer, children: [
|
|
3368
|
+
/* @__PURE__ */ jsx37(Defs8, { children: gradient }),
|
|
3369
|
+
/* @__PURE__ */ jsx37(Circle9, { cx: YAZAKIA.center, cy: YAZAKIA.center, r: YAZAKIA.orbit.r, stroke, strokeWidth: YAZAKIA.orbit.width, strokeDasharray: YAZAKIA.orbit.dash, opacity: 0.6, fill: "none" }),
|
|
3370
|
+
YAZAKIA.pair.at.map(([cx, cy]) => /* @__PURE__ */ jsx37(Circle9, { cx, cy, r: YAZAKIA.pair.r, fill }, cx))
|
|
2329
3371
|
] }) }),
|
|
2330
|
-
/* @__PURE__ */
|
|
2331
|
-
/* @__PURE__ */
|
|
3372
|
+
/* @__PURE__ */ jsx37(Animated22.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs33(Svg15, { viewBox, style: layer, children: [
|
|
3373
|
+
/* @__PURE__ */ jsxs33(Defs8, { children: [
|
|
2332
3374
|
gradient,
|
|
2333
|
-
/* @__PURE__ */
|
|
2334
|
-
/* @__PURE__ */
|
|
2335
|
-
/* @__PURE__ */
|
|
3375
|
+
/* @__PURE__ */ jsxs33(LinearGradient8, { id: `${id}l`, gradientUnits: "userSpaceOnUse", x1: 0, y1: YAZAKIA.lens.y1, x2: 0, y2: YAZAKIA.lens.y2, children: [
|
|
3376
|
+
/* @__PURE__ */ jsx37(Stop8, { offset: "0%", stopColor: YAZAKIA.highlight.color, stopOpacity: YAZAKIA.highlight.from }),
|
|
3377
|
+
/* @__PURE__ */ jsx37(Stop8, { offset: "100%", stopColor: YAZAKIA.highlight.color, stopOpacity: YAZAKIA.highlight.to })
|
|
2336
3378
|
] })
|
|
2337
3379
|
] }),
|
|
2338
|
-
/* @__PURE__ */
|
|
2339
|
-
/* @__PURE__ */
|
|
3380
|
+
/* @__PURE__ */ jsx37(Path12, { d: YAZAKIA.lens.d, fill }),
|
|
3381
|
+
/* @__PURE__ */ jsx37(Path12, { d: YAZAKIA.lens.d, fill: `url(#${id}l)` })
|
|
2340
3382
|
] }) })
|
|
2341
3383
|
] });
|
|
2342
3384
|
}
|
|
2343
3385
|
|
|
2344
3386
|
// src/native/YororisMark.tsx
|
|
2345
|
-
import { View as
|
|
2346
|
-
import
|
|
3387
|
+
import { View as View33 } from "react-native";
|
|
3388
|
+
import Svg16, { Circle as Circle10, Defs as Defs9, LinearGradient as LinearGradient9, Path as Path13, RadialGradient as RadialGradient6, Stop as Stop9 } from "react-native-svg";
|
|
2347
3389
|
|
|
2348
3390
|
// src/marks/yororis-geometry.ts
|
|
2349
3391
|
var sand = marks.yororis[0][1];
|
|
@@ -2379,65 +3421,65 @@ var YORORIS = {
|
|
|
2379
3421
|
};
|
|
2380
3422
|
|
|
2381
3423
|
// src/native/YororisMark.tsx
|
|
2382
|
-
import { jsx as
|
|
3424
|
+
import { jsx as jsx38, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2383
3425
|
function YororisMark({ size = 48, animated = true, title, neutral }) {
|
|
2384
3426
|
const { theme } = useTheme();
|
|
2385
|
-
const { Animated:
|
|
3427
|
+
const { Animated: Animated22, layer, spinStyle, pulseStyle } = useMarkMotion(size, animated, 36e3);
|
|
2386
3428
|
const id = useSvgId("yrm");
|
|
2387
3429
|
const viewBox = size < 48 ? YORORIS.croppedViewBox : YORORIS.viewBox;
|
|
2388
3430
|
const stroke = neutral ?? theme.textMuted;
|
|
2389
|
-
const gradient = /* @__PURE__ */
|
|
3431
|
+
const gradient = /* @__PURE__ */ jsx38(LinearGradient9, { id: `${id}a`, gradientUnits: "userSpaceOnUse", x1: YORORIS.gradient.x1, y1: YORORIS.gradient.y1, x2: YORORIS.gradient.x2, y2: YORORIS.gradient.y2, children: YORORIS.gradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx38(Stop9, { offset, stopColor: color }, offset)) });
|
|
2390
3432
|
const fill = `url(#${id}a)`;
|
|
2391
|
-
return /* @__PURE__ */
|
|
2392
|
-
/* @__PURE__ */
|
|
2393
|
-
/* @__PURE__ */
|
|
2394
|
-
/* @__PURE__ */
|
|
2395
|
-
/* @__PURE__ */
|
|
2396
|
-
/* @__PURE__ */
|
|
3433
|
+
return /* @__PURE__ */ jsxs34(View33, { style: { width: size, height: size }, ...markA11y(title), children: [
|
|
3434
|
+
/* @__PURE__ */ jsxs34(Svg16, { viewBox, style: layer, children: [
|
|
3435
|
+
/* @__PURE__ */ jsxs34(Defs9, { children: [
|
|
3436
|
+
/* @__PURE__ */ jsxs34(RadialGradient6, { id: `${id}g`, cx: "50%", cy: "50%", r: "50%", children: [
|
|
3437
|
+
/* @__PURE__ */ jsx38(Stop9, { offset: "0%", stopColor: YORORIS.glow.color, stopOpacity: YORORIS.glow.opacity }),
|
|
3438
|
+
/* @__PURE__ */ jsx38(Stop9, { offset: "100%", stopColor: YORORIS.glow.color, stopOpacity: 0 })
|
|
2397
3439
|
] }),
|
|
2398
3440
|
gradient
|
|
2399
3441
|
] }),
|
|
2400
|
-
size >= 48 ? /* @__PURE__ */
|
|
2401
|
-
/* @__PURE__ */
|
|
2402
|
-
/* @__PURE__ */
|
|
2403
|
-
YORORIS.leaves.map((d) => /* @__PURE__ */
|
|
2404
|
-
/* @__PURE__ */
|
|
3442
|
+
size >= 48 ? /* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.center, cy: YORORIS.center, r: 190, fill: `url(#${id}g)` }) : null,
|
|
3443
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.center, cy: YORORIS.center, r: YORORIS.ring.r, stroke, strokeWidth: YORORIS.ring.width, opacity: 0.35, fill: "none" }),
|
|
3444
|
+
/* @__PURE__ */ jsx38(Path13, { d: YORORIS.stem, stroke: fill, strokeWidth: YORORIS.stroke, strokeLinecap: "round", fill: "none" }),
|
|
3445
|
+
YORORIS.leaves.map((d) => /* @__PURE__ */ jsx38(Path13, { d, fill }, d)),
|
|
3446
|
+
/* @__PURE__ */ jsx38(Path13, { d: YORORIS.veins, stroke: YORORIS.vein.color, strokeOpacity: YORORIS.vein.opacity, strokeWidth: YORORIS.vein.width, strokeLinecap: "round", strokeDasharray: YORORIS.vein.dash, fill: "none" })
|
|
2405
3447
|
] }),
|
|
2406
|
-
/* @__PURE__ */
|
|
2407
|
-
/* @__PURE__ */
|
|
2408
|
-
/* @__PURE__ */
|
|
2409
|
-
/* @__PURE__ */
|
|
3448
|
+
/* @__PURE__ */ jsx38(Animated22.View, { style: [layer, spinStyle], children: /* @__PURE__ */ jsxs34(Svg16, { viewBox, style: layer, children: [
|
|
3449
|
+
/* @__PURE__ */ jsx38(Defs9, { children: gradient }),
|
|
3450
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.center, cy: YORORIS.center, r: YORORIS.orbit.r, stroke, strokeWidth: YORORIS.orbit.width, strokeDasharray: YORORIS.orbit.dash, opacity: 0.6, fill: "none" }),
|
|
3451
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.moment.at[0], cy: YORORIS.moment.at[1], r: YORORIS.moment.r, fill })
|
|
2410
3452
|
] }) }),
|
|
2411
|
-
/* @__PURE__ */
|
|
2412
|
-
/* @__PURE__ */
|
|
2413
|
-
/* @__PURE__ */
|
|
2414
|
-
/* @__PURE__ */
|
|
3453
|
+
/* @__PURE__ */ jsx38(Animated22.View, { style: [layer, pulseStyle], children: /* @__PURE__ */ jsxs34(Svg16, { viewBox, style: layer, children: [
|
|
3454
|
+
/* @__PURE__ */ jsx38(Defs9, { children: /* @__PURE__ */ jsx38(LinearGradient9, { id: `${id}c`, x1: "50%", y1: "100%", x2: "50%", y2: "0%", children: YORORIS.coreGradient.stops.map(([offset, color]) => /* @__PURE__ */ jsx38(Stop9, { offset, stopColor: color }, offset)) }) }),
|
|
3455
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.core.cx, cy: YORORIS.core.cy, r: YORORIS.core.r, fill: `url(#${id}c)` }),
|
|
3456
|
+
/* @__PURE__ */ jsx38(Circle10, { cx: YORORIS.core.cx, cy: YORORIS.core.cy, r: YORORIS.core.inner, fill: YORORIS.highlight })
|
|
2415
3457
|
] }) })
|
|
2416
3458
|
] });
|
|
2417
3459
|
}
|
|
2418
3460
|
|
|
2419
3461
|
// src/native/ProductMark.tsx
|
|
2420
|
-
import { jsx as
|
|
3462
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
2421
3463
|
function ProductMark({ id, ...props }) {
|
|
2422
|
-
if (id === "krizaka") return /* @__PURE__ */
|
|
2423
|
-
if (id === "orazaka") return /* @__PURE__ */
|
|
2424
|
-
if (id === "yazakia") return /* @__PURE__ */
|
|
2425
|
-
if (id === "yororis") return /* @__PURE__ */
|
|
2426
|
-
return /* @__PURE__ */
|
|
3464
|
+
if (id === "krizaka") return /* @__PURE__ */ jsx39(KrizakaMark, { ...props });
|
|
3465
|
+
if (id === "orazaka") return /* @__PURE__ */ jsx39(OrazakaMark, { ...props });
|
|
3466
|
+
if (id === "yazakia") return /* @__PURE__ */ jsx39(YazakiaMark, { ...props });
|
|
3467
|
+
if (id === "yororis") return /* @__PURE__ */ jsx39(YororisMark, { ...props });
|
|
3468
|
+
return /* @__PURE__ */ jsx39(OrochiaMark, { ...props });
|
|
2427
3469
|
}
|
|
2428
3470
|
|
|
2429
3471
|
// src/native/profile-card.tsx
|
|
2430
|
-
import * as
|
|
2431
|
-
import { Animated as
|
|
2432
|
-
import { jsx as
|
|
3472
|
+
import * as React28 from "react";
|
|
3473
|
+
import { Animated as Animated15, StyleSheet as StyleSheet30, View as View34 } from "react-native";
|
|
3474
|
+
import { jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
2433
3475
|
var ratioOf = (value, max = 100) => Math.min(1, Math.max(0, value / (max || 1)));
|
|
2434
3476
|
function Bar({ label, ratio, words, animated, delay }) {
|
|
2435
3477
|
const { theme } = useTheme();
|
|
2436
3478
|
const t = useEntrance(animated, delay, 900);
|
|
2437
|
-
const [width, setWidth] =
|
|
3479
|
+
const [width, setWidth] = React28.useState(0);
|
|
2438
3480
|
const translateX = t.interpolate({ inputRange: [0, 1], outputRange: [-width * ratio, 0] });
|
|
2439
|
-
return /* @__PURE__ */
|
|
2440
|
-
|
|
3481
|
+
return /* @__PURE__ */ jsx40(
|
|
3482
|
+
View34,
|
|
2441
3483
|
{
|
|
2442
3484
|
accessible: true,
|
|
2443
3485
|
role: "meter",
|
|
@@ -2447,42 +3489,42 @@ function Bar({ label, ratio, words, animated, delay }) {
|
|
|
2447
3489
|
"aria-valuenow": Math.round(ratio * 100),
|
|
2448
3490
|
"aria-valuetext": words,
|
|
2449
3491
|
onLayout: (e) => setWidth(e.nativeEvent.layout.width),
|
|
2450
|
-
style: [
|
|
2451
|
-
children: /* @__PURE__ */
|
|
3492
|
+
style: [styles30.track, { backgroundColor: theme.surface3 }],
|
|
3493
|
+
children: /* @__PURE__ */ jsx40(Animated15.View, { style: [styles30.fill, { width: `${ratio * 100}%`, backgroundColor: theme.accent, transform: [{ translateX }] }] })
|
|
2452
3494
|
}
|
|
2453
3495
|
);
|
|
2454
3496
|
}
|
|
2455
3497
|
function ProfileCard({ visual, name, statLabel, value = 100, valueText, stats, caption, children, animated = true, style, ...props }) {
|
|
2456
3498
|
const { theme, radius: radius3 } = useTheme();
|
|
2457
3499
|
const ratio = ratioOf(value);
|
|
2458
|
-
return /* @__PURE__ */
|
|
2459
|
-
/* @__PURE__ */
|
|
2460
|
-
/* @__PURE__ */
|
|
2461
|
-
/* @__PURE__ */
|
|
2462
|
-
statLabel ? /* @__PURE__ */
|
|
3500
|
+
return /* @__PURE__ */ jsxs35(View34, { ...props, style: [styles30.root, { backgroundColor: theme.surface1, borderColor: theme.borderSubtle, borderRadius: radius3.xl }, style], children: [
|
|
3501
|
+
/* @__PURE__ */ jsx40(View34, { "aria-hidden": true, style: [styles30.disc, { backgroundColor: theme.surface2, borderColor: theme.accentSoft }], children: visual }),
|
|
3502
|
+
/* @__PURE__ */ jsxs35(View34, { style: styles30.head, children: [
|
|
3503
|
+
/* @__PURE__ */ jsx40(Txt, { variant: "title", style: styles30.name, children: name }),
|
|
3504
|
+
statLabel ? /* @__PURE__ */ jsxs35(Txt, { variant: "caption", tone: "secondary", children: [
|
|
2463
3505
|
statLabel,
|
|
2464
3506
|
" ",
|
|
2465
|
-
/* @__PURE__ */
|
|
3507
|
+
/* @__PURE__ */ jsx40(Txt, { variant: "caption", children: valueText ?? `${Math.round(ratio * 100)} %` })
|
|
2466
3508
|
] }) : null
|
|
2467
3509
|
] }),
|
|
2468
|
-
statLabel ? /* @__PURE__ */
|
|
3510
|
+
statLabel ? /* @__PURE__ */ jsx40(Bar, { label: statLabel, ratio, words: valueText ?? `${Math.round(ratio * 100)} %`, animated, delay: 200 }) : null,
|
|
2469
3511
|
stats?.map((s, i) => {
|
|
2470
3512
|
const r = ratioOf(s.value, s.max);
|
|
2471
3513
|
const words = s.valueText ?? `${Math.round(r * 100)} %`;
|
|
2472
|
-
return /* @__PURE__ */
|
|
2473
|
-
/* @__PURE__ */
|
|
2474
|
-
/* @__PURE__ */
|
|
2475
|
-
/* @__PURE__ */
|
|
3514
|
+
return /* @__PURE__ */ jsxs35(View34, { style: styles30.stat, children: [
|
|
3515
|
+
/* @__PURE__ */ jsxs35(View34, { "aria-hidden": true, style: styles30.statHead, children: [
|
|
3516
|
+
/* @__PURE__ */ jsx40(Txt, { variant: "caption", tone: "secondary", children: s.label }),
|
|
3517
|
+
/* @__PURE__ */ jsx40(Txt, { variant: "caption", children: words })
|
|
2476
3518
|
] }),
|
|
2477
|
-
/* @__PURE__ */
|
|
3519
|
+
/* @__PURE__ */ jsx40(Bar, { label: s.label, ratio: r, words, animated, delay: 320 + i * 120 })
|
|
2478
3520
|
] }, s.label);
|
|
2479
3521
|
}),
|
|
2480
|
-
caption ? /* @__PURE__ */
|
|
2481
|
-
children ? /* @__PURE__ */
|
|
3522
|
+
caption ? /* @__PURE__ */ jsx40(Txt, { variant: "caption", tone: "secondary", style: styles30.caption, children: caption }) : null,
|
|
3523
|
+
children ? /* @__PURE__ */ jsx40(View34, { style: styles30.extra, children }) : null
|
|
2482
3524
|
] });
|
|
2483
3525
|
}
|
|
2484
|
-
var
|
|
2485
|
-
root: { alignItems: "center", gap: 12, padding: 20, borderWidth:
|
|
3526
|
+
var styles30 = StyleSheet30.create({
|
|
3527
|
+
root: { alignItems: "center", gap: 12, padding: 20, borderWidth: StyleSheet30.hairlineWidth },
|
|
2486
3528
|
disc: { width: 104, height: 104, borderRadius: 52, borderWidth: 1, alignItems: "center", justifyContent: "center", overflow: "hidden" },
|
|
2487
3529
|
head: { flexDirection: "row", alignSelf: "stretch", alignItems: "center", justifyContent: "space-between", gap: 8 },
|
|
2488
3530
|
name: { flexShrink: 1, fontSize: 17 },
|
|
@@ -2495,13 +3537,13 @@ var styles17 = StyleSheet17.create({
|
|
|
2495
3537
|
});
|
|
2496
3538
|
|
|
2497
3539
|
// src/native/progress.tsx
|
|
2498
|
-
import * as
|
|
2499
|
-
import { Animated as
|
|
2500
|
-
import
|
|
2501
|
-
import { jsx as
|
|
2502
|
-
var AnimatedCircle =
|
|
2503
|
-
var
|
|
2504
|
-
var
|
|
3540
|
+
import * as React29 from "react";
|
|
3541
|
+
import { Animated as Animated16, Easing as Easing9, StyleSheet as StyleSheet31, View as View35 } from "react-native";
|
|
3542
|
+
import Svg17, { Circle as Circle11, Defs as Defs10, LinearGradient as LinearGradient10, Rect as Rect3, Stop as Stop10 } from "react-native-svg";
|
|
3543
|
+
import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3544
|
+
var AnimatedCircle = Animated16.createAnimatedComponent(Circle11);
|
|
3545
|
+
var BAR2 = { sm: 4, md: 8, lg: 12 };
|
|
3546
|
+
var RING2 = { sm: 40, md: 80, lg: 144 };
|
|
2505
3547
|
var STROKE = { sm: 12, md: 9, lg: 7 };
|
|
2506
3548
|
function Progress({ variant = "bar", size = "md", value, max = 100, label, valueText, children, style }) {
|
|
2507
3549
|
const { theme } = useTheme();
|
|
@@ -2510,21 +3552,21 @@ function Progress({ variant = "bar", size = "md", value, max = 100, label, value
|
|
|
2510
3552
|
const known = typeof value === "number" && Number.isFinite(value);
|
|
2511
3553
|
const ratio = known ? Math.min(1, Math.max(0, value / (max || 1))) : 0;
|
|
2512
3554
|
const percent = Math.round(ratio * 100);
|
|
2513
|
-
const [progress] =
|
|
2514
|
-
const [spin] =
|
|
2515
|
-
const [track, setTrack] =
|
|
2516
|
-
|
|
3555
|
+
const [progress] = React29.useState(() => new Animated16.Value(ratio));
|
|
3556
|
+
const [spin] = React29.useState(() => new Animated16.Value(0));
|
|
3557
|
+
const [track, setTrack] = React29.useState(0);
|
|
3558
|
+
React29.useEffect(() => {
|
|
2517
3559
|
if (reduce) {
|
|
2518
3560
|
progress.setValue(ratio);
|
|
2519
3561
|
return;
|
|
2520
3562
|
}
|
|
2521
|
-
const animation =
|
|
3563
|
+
const animation = Animated16.timing(progress, { toValue: ratio, duration: 700, easing: Easing9.out(Easing9.cubic), useNativeDriver: false });
|
|
2522
3564
|
animation.start();
|
|
2523
3565
|
return () => animation.stop();
|
|
2524
3566
|
}, [ratio, reduce, progress]);
|
|
2525
|
-
|
|
3567
|
+
React29.useEffect(() => {
|
|
2526
3568
|
if (known || reduce) return;
|
|
2527
|
-
const loop =
|
|
3569
|
+
const loop = Animated16.loop(Animated16.timing(spin, { toValue: 1, duration: 1200, easing: Easing9.linear, useNativeDriver: true }));
|
|
2528
3570
|
loop.start();
|
|
2529
3571
|
return () => {
|
|
2530
3572
|
loop.stop();
|
|
@@ -2540,22 +3582,22 @@ function Progress({ variant = "bar", size = "md", value, max = 100, label, value
|
|
|
2540
3582
|
"aria-valuenow": known ? Math.min(max, Math.max(0, value)) : void 0,
|
|
2541
3583
|
"aria-valuetext": known ? valueText ?? `${percent}%` : valueText
|
|
2542
3584
|
};
|
|
2543
|
-
const gradient = /* @__PURE__ */
|
|
2544
|
-
/* @__PURE__ */
|
|
2545
|
-
/* @__PURE__ */
|
|
3585
|
+
const gradient = /* @__PURE__ */ jsx41(Defs10, { children: /* @__PURE__ */ jsxs36(LinearGradient10, { id, x1: "0", y1: "0", x2: "1", y2: variant === "ring" ? "1" : "0", children: [
|
|
3586
|
+
/* @__PURE__ */ jsx41(Stop10, { offset: "0", stopColor: theme.accent }),
|
|
3587
|
+
/* @__PURE__ */ jsx41(Stop10, { offset: "1", stopColor: theme.accent2 })
|
|
2546
3588
|
] }) });
|
|
2547
3589
|
if (variant === "ring") {
|
|
2548
|
-
const side =
|
|
3590
|
+
const side = RING2[size];
|
|
2549
3591
|
const stroke = STROKE[size];
|
|
2550
3592
|
const r = 50 - stroke / 2;
|
|
2551
3593
|
const circumference = 2 * Math.PI * r;
|
|
2552
3594
|
const offset = known ? progress.interpolate({ inputRange: [0, 1], outputRange: [circumference, 0] }) : circumference * 0.75;
|
|
2553
3595
|
const rotate = spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] });
|
|
2554
|
-
return /* @__PURE__ */
|
|
2555
|
-
/* @__PURE__ */
|
|
3596
|
+
return /* @__PURE__ */ jsxs36(View35, { ...a11y, style: [styles31.ring, { width: side, height: side }, style], children: [
|
|
3597
|
+
/* @__PURE__ */ jsx41(Animated16.View, { style: [StyleSheet31.absoluteFill, { transform: [{ rotate: known ? "-90deg" : rotate }] }], children: /* @__PURE__ */ jsxs36(Svg17, { width: side, height: side, viewBox: "0 0 100 100", children: [
|
|
2556
3598
|
gradient,
|
|
2557
|
-
/* @__PURE__ */
|
|
2558
|
-
/* @__PURE__ */
|
|
3599
|
+
/* @__PURE__ */ jsx41(Circle11, { cx: 50, cy: 50, r, fill: "none", stroke: theme.borderDefault, strokeWidth: stroke }),
|
|
3600
|
+
/* @__PURE__ */ jsx41(
|
|
2559
3601
|
AnimatedCircle,
|
|
2560
3602
|
{
|
|
2561
3603
|
cx: 50,
|
|
@@ -2575,50 +3617,212 @@ function Progress({ variant = "bar", size = "md", value, max = 100, label, value
|
|
|
2575
3617
|
}
|
|
2576
3618
|
const width = known ? progress.interpolate({ inputRange: [0, 1], outputRange: ["0%", "100%"] }) : "40%";
|
|
2577
3619
|
const translate = spin.interpolate({ inputRange: [0, 1], outputRange: [-0.4 * track, track] });
|
|
2578
|
-
return /* @__PURE__ */
|
|
2579
|
-
|
|
3620
|
+
return /* @__PURE__ */ jsx41(
|
|
3621
|
+
View35,
|
|
2580
3622
|
{
|
|
2581
3623
|
...a11y,
|
|
2582
3624
|
onLayout: known ? void 0 : (event) => setTrack(event.nativeEvent.layout.width),
|
|
2583
|
-
style: [
|
|
2584
|
-
children: /* @__PURE__ */
|
|
3625
|
+
style: [styles31.bar, { height: BAR2[size], backgroundColor: theme.surface3 }, style],
|
|
3626
|
+
children: /* @__PURE__ */ jsx41(Animated16.View, { style: [styles31.fill, { width }, known || reduce ? null : { transform: [{ translateX: translate }] }], children: /* @__PURE__ */ jsxs36(Svg17, { width: "100%", height: "100%", preserveAspectRatio: "none", children: [
|
|
2585
3627
|
gradient,
|
|
2586
|
-
/* @__PURE__ */
|
|
3628
|
+
/* @__PURE__ */ jsx41(Rect3, { x: 0, y: 0, width: "100%", height: "100%", fill: `url(#${id})` })
|
|
2587
3629
|
] }) })
|
|
2588
3630
|
}
|
|
2589
3631
|
);
|
|
2590
3632
|
}
|
|
2591
|
-
var
|
|
3633
|
+
var styles31 = StyleSheet31.create({
|
|
2592
3634
|
ring: { alignItems: "center", justifyContent: "center" },
|
|
2593
3635
|
bar: { width: "100%", overflow: "hidden", borderRadius: 9999 },
|
|
2594
3636
|
fill: { height: "100%", overflow: "hidden", borderRadius: 9999 }
|
|
2595
3637
|
});
|
|
2596
3638
|
|
|
3639
|
+
// src/native/pull-to-refresh.tsx
|
|
3640
|
+
import { RefreshControl } from "react-native";
|
|
3641
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
3642
|
+
function PullToRefresh({ label, ...props }) {
|
|
3643
|
+
const { theme } = useTheme();
|
|
3644
|
+
return /* @__PURE__ */ jsx42(RefreshControl, { ...props, tintColor: theme.accent, colors: [theme.accent], progressBackgroundColor: theme.surface2, title: label, titleColor: theme.textSecondary });
|
|
3645
|
+
}
|
|
3646
|
+
|
|
3647
|
+
// src/native/radio-group.tsx
|
|
3648
|
+
import * as React30 from "react";
|
|
3649
|
+
import { Animated as Animated17, Pressable as Pressable15, StyleSheet as StyleSheet32, Text as Text15, View as View36 } from "react-native";
|
|
3650
|
+
import Svg18, { Path as Path14 } from "react-native-svg";
|
|
3651
|
+
import { jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3652
|
+
function Check({ color }) {
|
|
3653
|
+
return /* @__PURE__ */ jsx43(Svg18, { width: 12, height: 12, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: 3.2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx43(Path14, { d: "M20 6 9 17l-5-5" }) });
|
|
3654
|
+
}
|
|
3655
|
+
function Key({ option, checked, disabled, onPress }) {
|
|
3656
|
+
const { theme, radius: radius3, motion: motion3 } = useTheme();
|
|
3657
|
+
const [held, setHeld] = React30.useState(false);
|
|
3658
|
+
const [sink] = React30.useState(() => new Animated17.Value(checked ? 1 : 0));
|
|
3659
|
+
const down = checked || held;
|
|
3660
|
+
React30.useEffect(() => {
|
|
3661
|
+
Animated17.timing(sink, { toValue: down ? 1 : 0, duration: motion3.duration.fast, useNativeDriver: true }).start();
|
|
3662
|
+
}, [down, sink, motion3.duration.fast]);
|
|
3663
|
+
return /* @__PURE__ */ jsxs37(
|
|
3664
|
+
Pressable15,
|
|
3665
|
+
{
|
|
3666
|
+
role: "radio",
|
|
3667
|
+
"aria-checked": checked,
|
|
3668
|
+
"aria-label": option.hint ? `${option.label}, ${option.hint}` : option.label,
|
|
3669
|
+
"aria-disabled": disabled || void 0,
|
|
3670
|
+
disabled,
|
|
3671
|
+
onPress,
|
|
3672
|
+
onPressIn: () => setHeld(true),
|
|
3673
|
+
onPressOut: () => setHeld(false),
|
|
3674
|
+
style: [styles32.keySlot, disabled ? styles32.disabled : null],
|
|
3675
|
+
children: [
|
|
3676
|
+
/* @__PURE__ */ jsx43(View36, { style: [styles32.ledge, { borderRadius: radius3.lg, backgroundColor: checked ? theme.accentHover : theme.borderStrong }] }),
|
|
3677
|
+
/* @__PURE__ */ jsxs37(
|
|
3678
|
+
Animated17.View,
|
|
3679
|
+
{
|
|
3680
|
+
style: [
|
|
3681
|
+
styles32.key,
|
|
3682
|
+
{
|
|
3683
|
+
borderRadius: radius3.lg,
|
|
3684
|
+
backgroundColor: checked ? theme.accent : theme.surface2,
|
|
3685
|
+
borderColor: checked ? theme.accent : theme.borderDefault,
|
|
3686
|
+
transform: [{ translateY: sink.interpolate({ inputRange: [0, 1], outputRange: [0, 3] }) }]
|
|
3687
|
+
}
|
|
3688
|
+
],
|
|
3689
|
+
children: [
|
|
3690
|
+
/* @__PURE__ */ jsx43(Text15, { style: [styles32.keyLabel, { color: checked ? theme.onAccent : theme.textPrimary }], children: option.label }),
|
|
3691
|
+
option.hint ? /* @__PURE__ */ jsx43(Text15, { style: [styles32.keyHint, { color: checked ? theme.onAccent : theme.textSecondary }], children: option.hint }) : null
|
|
3692
|
+
]
|
|
3693
|
+
}
|
|
3694
|
+
)
|
|
3695
|
+
]
|
|
3696
|
+
}
|
|
3697
|
+
);
|
|
3698
|
+
}
|
|
3699
|
+
function RadioGroup({ label, options, value: valueProp, defaultValue = null, onValueChange, variant = "list", error, disabled, style }) {
|
|
3700
|
+
const { theme, radius: radius3, haptic } = useTheme();
|
|
3701
|
+
const [own, setOwn] = React30.useState(defaultValue);
|
|
3702
|
+
const value = valueProp !== void 0 ? valueProp : own;
|
|
3703
|
+
const pick = (v) => {
|
|
3704
|
+
haptic(variant === "buttons" ? "impact" : "selection");
|
|
3705
|
+
if (valueProp === void 0) setOwn(v);
|
|
3706
|
+
if (v !== value) onValueChange?.(v);
|
|
3707
|
+
};
|
|
3708
|
+
const body = options.map((o) => {
|
|
3709
|
+
const checked = o.value === value;
|
|
3710
|
+
const off = Boolean(disabled || o.disabled);
|
|
3711
|
+
const name = o.description ? `${o.label}, ${o.description}` : o.label;
|
|
3712
|
+
if (variant === "buttons") return /* @__PURE__ */ jsx43(Key, { option: o, checked, disabled: off, onPress: () => pick(o.value) }, o.value);
|
|
3713
|
+
if (variant === "segmented")
|
|
3714
|
+
return /* @__PURE__ */ jsx43(
|
|
3715
|
+
Pressable15,
|
|
3716
|
+
{
|
|
3717
|
+
role: "radio",
|
|
3718
|
+
"aria-checked": checked,
|
|
3719
|
+
"aria-label": o.label,
|
|
3720
|
+
"aria-disabled": off || void 0,
|
|
3721
|
+
disabled: off,
|
|
3722
|
+
onPress: () => pick(o.value),
|
|
3723
|
+
style: [styles32.segment, { borderRadius: radius3.md }, checked ? { backgroundColor: theme.surface0, borderColor: theme.borderDefault } : null, off ? styles32.disabled : null],
|
|
3724
|
+
children: /* @__PURE__ */ jsx43(Text15, { numberOfLines: 1, style: [styles32.segmentLabel, { color: checked ? theme.textPrimary : theme.textSecondary }], children: o.label })
|
|
3725
|
+
},
|
|
3726
|
+
o.value
|
|
3727
|
+
);
|
|
3728
|
+
if (variant === "cards")
|
|
3729
|
+
return /* @__PURE__ */ jsxs37(
|
|
3730
|
+
Pressable15,
|
|
3731
|
+
{
|
|
3732
|
+
role: "radio",
|
|
3733
|
+
"aria-checked": checked,
|
|
3734
|
+
"aria-label": name,
|
|
3735
|
+
"aria-disabled": off || void 0,
|
|
3736
|
+
disabled: off,
|
|
3737
|
+
onPress: () => pick(o.value),
|
|
3738
|
+
style: ({ pressed }) => [
|
|
3739
|
+
styles32.card,
|
|
3740
|
+
{ borderRadius: radius3.xl, backgroundColor: checked ? theme.accentSoft : theme.surface1, borderColor: checked ? theme.accent : theme.borderDefault, transform: [{ scale: pressed ? 0.98 : 1 }] },
|
|
3741
|
+
off ? styles32.disabled : null
|
|
3742
|
+
],
|
|
3743
|
+
children: [
|
|
3744
|
+
/* @__PURE__ */ jsx43(View36, { style: [styles32.cardCheck, { borderColor: checked ? theme.accent : theme.borderStrong, backgroundColor: checked ? theme.accent : theme.surface1 }], children: checked ? /* @__PURE__ */ jsx43(Check, { color: theme.onAccent }) : null }),
|
|
3745
|
+
/* @__PURE__ */ jsx43(Text15, { style: [styles32.cardLabel, { color: theme.textPrimary }], children: o.label }),
|
|
3746
|
+
o.description ? /* @__PURE__ */ jsx43(Text15, { style: [styles32.cardDescription, { color: theme.textSecondary }], children: o.description }) : null
|
|
3747
|
+
]
|
|
3748
|
+
},
|
|
3749
|
+
o.value
|
|
3750
|
+
);
|
|
3751
|
+
return /* @__PURE__ */ jsxs37(Pressable15, { role: "radio", "aria-checked": checked, "aria-label": name, "aria-disabled": off || void 0, disabled: off, onPress: () => pick(o.value), style: [styles32.row, off ? styles32.disabled : null], children: [
|
|
3752
|
+
/* @__PURE__ */ jsx43(View36, { style: [styles32.dot, { borderColor: checked ? theme.accent : theme.borderStrong, backgroundColor: checked ? theme.accent : theme.surface1 }], children: checked ? /* @__PURE__ */ jsx43(View36, { style: [styles32.dotIn, { backgroundColor: theme.onAccent }] }) : null }),
|
|
3753
|
+
/* @__PURE__ */ jsxs37(View36, { style: styles32.rowText, children: [
|
|
3754
|
+
/* @__PURE__ */ jsx43(Text15, { style: [styles32.rowLabel, { color: theme.textPrimary }], children: o.label }),
|
|
3755
|
+
o.description ? /* @__PURE__ */ jsx43(Text15, { style: [styles32.cardDescription, { color: theme.textSecondary }], children: o.description }) : null
|
|
3756
|
+
] })
|
|
3757
|
+
] }, o.value);
|
|
3758
|
+
});
|
|
3759
|
+
return /* @__PURE__ */ jsxs37(View36, { style: [styles32.root, style], children: [
|
|
3760
|
+
/* @__PURE__ */ jsx43(
|
|
3761
|
+
View36,
|
|
3762
|
+
{
|
|
3763
|
+
role: "radiogroup",
|
|
3764
|
+
"aria-label": label,
|
|
3765
|
+
style: variant === "segmented" ? [styles32.track, { borderRadius: radius3.lg, backgroundColor: theme.surface2, borderColor: error ? theme.danger : theme.borderDefault }] : variant === "buttons" ? styles32.keys : variant === "cards" ? styles32.cards : styles32.list,
|
|
3766
|
+
children: body
|
|
3767
|
+
}
|
|
3768
|
+
),
|
|
3769
|
+
error ? /* @__PURE__ */ jsx43(Text15, { role: "alert", "aria-live": "polite", style: [styles32.error, { color: theme.dangerText }], children: error }) : null
|
|
3770
|
+
] });
|
|
3771
|
+
}
|
|
3772
|
+
var styles32 = StyleSheet32.create({
|
|
3773
|
+
root: { gap: 6, alignSelf: "stretch" },
|
|
3774
|
+
list: { gap: 2 },
|
|
3775
|
+
row: { flexDirection: "row", alignItems: "center", gap: 12, minHeight: 44 },
|
|
3776
|
+
rowText: { flex: 1, gap: 1 },
|
|
3777
|
+
rowLabel: { fontSize: 15, lineHeight: 20 },
|
|
3778
|
+
dot: { width: 22, height: 22, borderRadius: 11, borderWidth: 1.5, alignItems: "center", justifyContent: "center" },
|
|
3779
|
+
dotIn: { width: 8, height: 8, borderRadius: 4 },
|
|
3780
|
+
cards: { flexDirection: "row", flexWrap: "wrap", gap: 10 },
|
|
3781
|
+
card: { flexGrow: 1, flexBasis: 140, minHeight: 72, padding: 14, paddingRight: 40, gap: 2, borderWidth: 1 },
|
|
3782
|
+
cardCheck: { position: "absolute", right: 12, top: 12, width: 20, height: 20, borderRadius: 10, borderWidth: 1.5, alignItems: "center", justifyContent: "center" },
|
|
3783
|
+
cardLabel: { fontSize: 16, fontWeight: "700" },
|
|
3784
|
+
cardDescription: { fontSize: 12, lineHeight: 16 },
|
|
3785
|
+
keys: { flexDirection: "row", flexWrap: "wrap", gap: 10, paddingBottom: 4 },
|
|
3786
|
+
keySlot: { minWidth: 64, minHeight: 52 },
|
|
3787
|
+
ledge: { position: "absolute", left: 0, right: 0, top: 4, bottom: -4 },
|
|
3788
|
+
key: { minHeight: 48, paddingHorizontal: 16, paddingVertical: 8, alignItems: "center", justifyContent: "center", gap: 1, borderWidth: 1 },
|
|
3789
|
+
keyLabel: { fontSize: 15, fontWeight: "700" },
|
|
3790
|
+
keyHint: { fontSize: 11, fontWeight: "500" },
|
|
3791
|
+
track: { flexDirection: "row", padding: 3, gap: 3, borderWidth: StyleSheet32.hairlineWidth, height: 42 },
|
|
3792
|
+
segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth: StyleSheet32.hairlineWidth, borderColor: "transparent" },
|
|
3793
|
+
segmentLabel: { fontSize: 13, fontWeight: "600" },
|
|
3794
|
+
error: { fontSize: 12, lineHeight: 16 },
|
|
3795
|
+
disabled: { opacity: 0.4 }
|
|
3796
|
+
});
|
|
3797
|
+
|
|
2597
3798
|
// src/native/search-field.tsx
|
|
2598
|
-
import * as
|
|
2599
|
-
import { Pressable as
|
|
2600
|
-
import
|
|
2601
|
-
import { jsx as
|
|
2602
|
-
function SearchField({ label, value, defaultValue = "", onValueChange, onSearch, debounce = 300, onSubmit, clearLabel, style, placeholder, ...props }) {
|
|
3799
|
+
import * as React31 from "react";
|
|
3800
|
+
import { Pressable as Pressable16, StyleSheet as StyleSheet33, TextInput as TextInput5, View as View37 } from "react-native";
|
|
3801
|
+
import Svg19, { Circle as Circle12, Path as Path15 } from "react-native-svg";
|
|
3802
|
+
import { jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3803
|
+
function SearchField({ label, value, defaultValue = "", onValueChange, onSearch, debounce = 300, onSubmit, clearLabel, cancelLabel, onCancel, style, placeholder, onFocus, onBlur, ...props }) {
|
|
3804
|
+
const [focused, setFocused] = React31.useState(false);
|
|
3805
|
+
const input = React31.useRef(null);
|
|
2603
3806
|
const { theme, radius: radius3 } = useTheme();
|
|
2604
|
-
const [own, setOwn] =
|
|
3807
|
+
const [own, setOwn] = React31.useState(defaultValue);
|
|
2605
3808
|
const query = value ?? own;
|
|
2606
|
-
const timer2 =
|
|
2607
|
-
|
|
3809
|
+
const timer2 = React31.useRef(void 0);
|
|
3810
|
+
React31.useEffect(() => () => clearTimeout(timer2.current), []);
|
|
2608
3811
|
const change = (next) => {
|
|
2609
3812
|
if (value === void 0) setOwn(next);
|
|
2610
3813
|
onValueChange?.(next);
|
|
2611
3814
|
clearTimeout(timer2.current);
|
|
2612
3815
|
if (onSearch) timer2.current = setTimeout(() => onSearch(next), debounce);
|
|
2613
3816
|
};
|
|
2614
|
-
|
|
2615
|
-
/* @__PURE__ */
|
|
2616
|
-
/* @__PURE__ */
|
|
2617
|
-
/* @__PURE__ */
|
|
3817
|
+
const field = /* @__PURE__ */ jsxs38(View37, { style: [styles33.frame, { borderRadius: radius3.md, borderColor: theme.borderDefault, backgroundColor: theme.surface2 }, style], children: [
|
|
3818
|
+
/* @__PURE__ */ jsxs38(Svg19, { width: 18, height: 18, viewBox: "0 0 24 24", fill: "none", stroke: theme.textSecondary, strokeWidth: 2, strokeLinecap: "round", "aria-hidden": true, children: [
|
|
3819
|
+
/* @__PURE__ */ jsx44(Circle12, { cx: 11, cy: 11, r: 7 }),
|
|
3820
|
+
/* @__PURE__ */ jsx44(Path15, { d: "m20 20-3.5-3.5" })
|
|
2618
3821
|
] }),
|
|
2619
|
-
/* @__PURE__ */
|
|
2620
|
-
|
|
3822
|
+
/* @__PURE__ */ jsx44(
|
|
3823
|
+
TextInput5,
|
|
2621
3824
|
{
|
|
3825
|
+
ref: input,
|
|
2622
3826
|
role: "searchbox",
|
|
2623
3827
|
"aria-label": label,
|
|
2624
3828
|
value: query,
|
|
@@ -2634,34 +3838,63 @@ function SearchField({ label, value, defaultValue = "", onValueChange, onSearch,
|
|
|
2634
3838
|
onSearch?.(query);
|
|
2635
3839
|
onSubmit?.(query);
|
|
2636
3840
|
},
|
|
2637
|
-
style: [
|
|
3841
|
+
style: [styles33.input, { color: theme.textPrimary }],
|
|
3842
|
+
onFocus: (e) => {
|
|
3843
|
+
setFocused(true);
|
|
3844
|
+
onFocus?.(e);
|
|
3845
|
+
},
|
|
3846
|
+
onBlur: (e) => {
|
|
3847
|
+
setFocused(false);
|
|
3848
|
+
onBlur?.(e);
|
|
3849
|
+
},
|
|
2638
3850
|
...props
|
|
2639
3851
|
}
|
|
2640
3852
|
),
|
|
2641
|
-
query ? /* @__PURE__ */
|
|
3853
|
+
query ? /* @__PURE__ */ jsx44(Pressable16, { role: "button", "aria-label": clearLabel, hitSlop: 10, onPress: () => change(""), style: styles33.clear, children: /* @__PURE__ */ jsx44(Svg19, { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: theme.textSecondary, strokeWidth: 2.4, strokeLinecap: "round", "aria-hidden": true, children: /* @__PURE__ */ jsx44(Path15, { d: "M18 6 6 18M6 6l12 12" }) }) }) : null
|
|
3854
|
+
] });
|
|
3855
|
+
if (!cancelLabel || !onCancel) return field;
|
|
3856
|
+
return /* @__PURE__ */ jsxs38(View37, { style: styles33.bar, children: [
|
|
3857
|
+
/* @__PURE__ */ jsx44(View37, { style: styles33.grow, children: field }),
|
|
3858
|
+
focused || query ? /* @__PURE__ */ jsx44(
|
|
3859
|
+
Pressable16,
|
|
3860
|
+
{
|
|
3861
|
+
role: "button",
|
|
3862
|
+
onPress: () => {
|
|
3863
|
+
change("");
|
|
3864
|
+
input.current?.blur();
|
|
3865
|
+
onCancel();
|
|
3866
|
+
},
|
|
3867
|
+
hitSlop: 8,
|
|
3868
|
+
style: styles33.cancel,
|
|
3869
|
+
children: /* @__PURE__ */ jsx44(Txt, { variant: "label", tone: "accent", children: cancelLabel })
|
|
3870
|
+
}
|
|
3871
|
+
) : null
|
|
2642
3872
|
] });
|
|
2643
3873
|
}
|
|
2644
|
-
var
|
|
2645
|
-
frame: { flexDirection: "row", alignItems: "center", gap: 8, height: 44, paddingLeft: 12, paddingRight: 6, borderWidth:
|
|
3874
|
+
var styles33 = StyleSheet33.create({
|
|
3875
|
+
frame: { flexDirection: "row", alignItems: "center", gap: 8, height: 44, paddingLeft: 12, paddingRight: 6, borderWidth: StyleSheet33.hairlineWidth },
|
|
2646
3876
|
input: { flex: 1, height: "100%", fontSize: 15, paddingVertical: 0 },
|
|
3877
|
+
bar: { flexDirection: "row", alignItems: "center", gap: 10 },
|
|
3878
|
+
grow: { flex: 1 },
|
|
3879
|
+
cancel: { minHeight: 44, justifyContent: "center" },
|
|
2647
3880
|
clear: { width: 32, height: 32, alignItems: "center", justifyContent: "center" }
|
|
2648
3881
|
});
|
|
2649
3882
|
|
|
2650
3883
|
// src/native/segmented.tsx
|
|
2651
|
-
import { Pressable as
|
|
2652
|
-
import { jsx as
|
|
3884
|
+
import { Pressable as Pressable17, StyleSheet as StyleSheet34, Text as Text16, View as View38 } from "react-native";
|
|
3885
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
2653
3886
|
function Segmented({ options, value, onValueChange, size = "md", "aria-label": label, style }) {
|
|
2654
3887
|
const { theme, radius: radius3 } = useTheme();
|
|
2655
|
-
return /* @__PURE__ */
|
|
2656
|
-
|
|
3888
|
+
return /* @__PURE__ */ jsx45(
|
|
3889
|
+
View38,
|
|
2657
3890
|
{
|
|
2658
3891
|
role: "tablist",
|
|
2659
3892
|
"aria-label": label,
|
|
2660
|
-
style: [
|
|
3893
|
+
style: [styles34.track, { backgroundColor: theme.surface2, borderColor: theme.borderSubtle, borderRadius: radius3.md, height: size === "sm" ? 32 : 40 }, style],
|
|
2661
3894
|
children: options.map((option) => {
|
|
2662
3895
|
const selected = option.value === value;
|
|
2663
|
-
return /* @__PURE__ */
|
|
2664
|
-
|
|
3896
|
+
return /* @__PURE__ */ jsx45(
|
|
3897
|
+
Pressable17,
|
|
2665
3898
|
{
|
|
2666
3899
|
role: "tab",
|
|
2667
3900
|
"aria-selected": selected,
|
|
@@ -2671,12 +3904,12 @@ function Segmented({ options, value, onValueChange, size = "md", "aria-label": l
|
|
|
2671
3904
|
if (!selected) onValueChange(option.value);
|
|
2672
3905
|
},
|
|
2673
3906
|
style: [
|
|
2674
|
-
|
|
3907
|
+
styles34.segment,
|
|
2675
3908
|
{ borderRadius: radius3.sm },
|
|
2676
3909
|
selected ? { backgroundColor: theme.surface0, borderColor: theme.borderDefault } : null,
|
|
2677
|
-
option.disabled ?
|
|
3910
|
+
option.disabled ? styles34.disabled : null
|
|
2678
3911
|
],
|
|
2679
|
-
children: /* @__PURE__ */
|
|
3912
|
+
children: /* @__PURE__ */ jsx45(Text16, { numberOfLines: 1, style: [styles34.label, { color: selected ? theme.textPrimary : theme.textSecondary, fontSize: size === "sm" ? 12 : 13 }], children: option.label })
|
|
2680
3913
|
},
|
|
2681
3914
|
option.value
|
|
2682
3915
|
);
|
|
@@ -2684,17 +3917,17 @@ function Segmented({ options, value, onValueChange, size = "md", "aria-label": l
|
|
|
2684
3917
|
}
|
|
2685
3918
|
);
|
|
2686
3919
|
}
|
|
2687
|
-
var
|
|
2688
|
-
track: { flexDirection: "row", padding: 3, gap: 3, borderWidth:
|
|
2689
|
-
segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth:
|
|
3920
|
+
var styles34 = StyleSheet34.create({
|
|
3921
|
+
track: { flexDirection: "row", padding: 3, gap: 3, borderWidth: StyleSheet34.hairlineWidth },
|
|
3922
|
+
segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth: StyleSheet34.hairlineWidth, borderColor: "transparent" },
|
|
2690
3923
|
label: { fontWeight: "600" },
|
|
2691
3924
|
disabled: { opacity: 0.4 }
|
|
2692
3925
|
});
|
|
2693
3926
|
|
|
2694
3927
|
// src/native/skeleton.tsx
|
|
2695
|
-
import * as
|
|
2696
|
-
import { Animated as
|
|
2697
|
-
import { jsx as
|
|
3928
|
+
import * as React32 from "react";
|
|
3929
|
+
import { Animated as Animated18 } from "react-native";
|
|
3930
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
2698
3931
|
var SHAPE = {
|
|
2699
3932
|
text: { width: "100%", height: 12, radius: 4 },
|
|
2700
3933
|
circle: { width: 40, height: 40, radius: 9999 },
|
|
@@ -2703,13 +3936,13 @@ var SHAPE = {
|
|
|
2703
3936
|
function Skeleton({ shape = "text", width, height, style, testID }) {
|
|
2704
3937
|
const { theme } = useTheme();
|
|
2705
3938
|
const reduce = useReducedMotion();
|
|
2706
|
-
const [opacity] =
|
|
2707
|
-
|
|
3939
|
+
const [opacity] = React32.useState(() => new Animated18.Value(1));
|
|
3940
|
+
React32.useEffect(() => {
|
|
2708
3941
|
if (reduce) return;
|
|
2709
|
-
const loop =
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
3942
|
+
const loop = Animated18.loop(
|
|
3943
|
+
Animated18.sequence([
|
|
3944
|
+
Animated18.timing(opacity, { toValue: 0.5, duration: 900, useNativeDriver: true }),
|
|
3945
|
+
Animated18.timing(opacity, { toValue: 1, duration: 900, useNativeDriver: true })
|
|
2713
3946
|
])
|
|
2714
3947
|
);
|
|
2715
3948
|
loop.start();
|
|
@@ -2720,8 +3953,8 @@ function Skeleton({ shape = "text", width, height, style, testID }) {
|
|
|
2720
3953
|
}, [reduce, opacity]);
|
|
2721
3954
|
const s = SHAPE[shape];
|
|
2722
3955
|
const side = shape === "circle" ? width ?? height ?? s.width : void 0;
|
|
2723
|
-
return /* @__PURE__ */
|
|
2724
|
-
|
|
3956
|
+
return /* @__PURE__ */ jsx46(
|
|
3957
|
+
Animated18.View,
|
|
2725
3958
|
{
|
|
2726
3959
|
testID,
|
|
2727
3960
|
"aria-hidden": true,
|
|
@@ -2733,12 +3966,187 @@ function Skeleton({ shape = "text", width, height, style, testID }) {
|
|
|
2733
3966
|
);
|
|
2734
3967
|
}
|
|
2735
3968
|
|
|
3969
|
+
// src/native/slider.tsx
|
|
3970
|
+
import * as React33 from "react";
|
|
3971
|
+
import { PanResponder as PanResponder2, StyleSheet as StyleSheet35, Text as Text17, View as View39 } from "react-native";
|
|
3972
|
+
import Svg20, { Defs as Defs11, LinearGradient as LinearGradient11, Rect as Rect4, Stop as Stop11 } from "react-native-svg";
|
|
3973
|
+
import { jsx as jsx47, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3974
|
+
var THUMB = 26;
|
|
3975
|
+
var toArray = (v) => v === void 0 ? void 0 : typeof v === "number" ? [v] : [...v];
|
|
3976
|
+
function Slider({
|
|
3977
|
+
label,
|
|
3978
|
+
thumbLabels,
|
|
3979
|
+
value,
|
|
3980
|
+
defaultValue,
|
|
3981
|
+
onValueChange,
|
|
3982
|
+
onValueCommit,
|
|
3983
|
+
min = 0,
|
|
3984
|
+
max = 100,
|
|
3985
|
+
step = 1,
|
|
3986
|
+
formatValue = String,
|
|
3987
|
+
showLabel,
|
|
3988
|
+
floatingValue,
|
|
3989
|
+
ticks,
|
|
3990
|
+
marks: marks2,
|
|
3991
|
+
tone: tone3 = "gradient",
|
|
3992
|
+
orientation = "horizontal",
|
|
3993
|
+
disabled,
|
|
3994
|
+
style
|
|
3995
|
+
}) {
|
|
3996
|
+
const { theme, radius: radius3, haptic } = useTheme();
|
|
3997
|
+
const range = Array.isArray(value ?? defaultValue);
|
|
3998
|
+
const vertical = orientation === "vertical";
|
|
3999
|
+
const [inner, setInner] = React33.useState(() => toArray(defaultValue) ?? [min]);
|
|
4000
|
+
const current = toArray(value) ?? inner;
|
|
4001
|
+
const [length, setLength] = React33.useState(0);
|
|
4002
|
+
const [dragging, setDragging] = React33.useState(null);
|
|
4003
|
+
const gradientId = useSvgId("kzs");
|
|
4004
|
+
const out = (next) => range ? [next[0], next[1]] : next[0];
|
|
4005
|
+
const snap = (v) => Math.min(max, Math.max(min, Math.round((v - min) / step) * step + min));
|
|
4006
|
+
const pct = (v) => (v - min) / (max - min || 1);
|
|
4007
|
+
const live = React33.useRef({ current, length, vertical, disabled });
|
|
4008
|
+
React33.useLayoutEffect(() => {
|
|
4009
|
+
live.current = { current, length, vertical, disabled };
|
|
4010
|
+
});
|
|
4011
|
+
const active = React33.useRef(0);
|
|
4012
|
+
const start = React33.useRef(0);
|
|
4013
|
+
const set = (next) => {
|
|
4014
|
+
if (value === void 0) setInner(next);
|
|
4015
|
+
onValueChange?.(out(next));
|
|
4016
|
+
};
|
|
4017
|
+
const move = (thumb, to) => {
|
|
4018
|
+
const now = live.current.current;
|
|
4019
|
+
let v = snap(to);
|
|
4020
|
+
if (now.length === 2) v = thumb === 0 ? Math.min(v, now[1]) : Math.max(v, now[0]);
|
|
4021
|
+
if (v === now[thumb]) return;
|
|
4022
|
+
haptic("selection");
|
|
4023
|
+
const next = [...now];
|
|
4024
|
+
next[thumb] = v;
|
|
4025
|
+
set(next);
|
|
4026
|
+
};
|
|
4027
|
+
const at = (position) => {
|
|
4028
|
+
const { length: l, vertical: vert } = live.current;
|
|
4029
|
+
const p = Math.min(1, Math.max(0, (vert ? l + THUMB / 2 - position : position - THUMB / 2) / (l || 1)));
|
|
4030
|
+
return min + p * (max - min);
|
|
4031
|
+
};
|
|
4032
|
+
const commit = () => onValueCommit?.(out(live.current.current));
|
|
4033
|
+
const handlers = React33.useRef({ move, at, commit });
|
|
4034
|
+
React33.useLayoutEffect(() => {
|
|
4035
|
+
handlers.current = { move, at, commit };
|
|
4036
|
+
});
|
|
4037
|
+
const [responder] = React33.useState(
|
|
4038
|
+
() => PanResponder2.create({
|
|
4039
|
+
onStartShouldSetPanResponder: () => !live.current.disabled,
|
|
4040
|
+
onMoveShouldSetPanResponder: () => !live.current.disabled,
|
|
4041
|
+
onPanResponderTerminationRequest: () => false,
|
|
4042
|
+
onPanResponderGrant: (e) => {
|
|
4043
|
+
const pos = live.current.vertical ? e.nativeEvent.locationY : e.nativeEvent.locationX;
|
|
4044
|
+
start.current = pos;
|
|
4045
|
+
const target = handlers.current.at(pos);
|
|
4046
|
+
const now = live.current.current;
|
|
4047
|
+
active.current = now.length === 2 && Math.abs(target - now[1]) < Math.abs(target - now[0]) ? 1 : 0;
|
|
4048
|
+
setDragging(active.current);
|
|
4049
|
+
handlers.current.move(active.current, target);
|
|
4050
|
+
},
|
|
4051
|
+
onPanResponderMove: (_, g) => handlers.current.move(active.current, handlers.current.at(start.current + (live.current.vertical ? g.dy : g.dx))),
|
|
4052
|
+
onPanResponderRelease: () => {
|
|
4053
|
+
setDragging(null);
|
|
4054
|
+
handlers.current.commit();
|
|
4055
|
+
},
|
|
4056
|
+
onPanResponderTerminate: () => setDragging(null)
|
|
4057
|
+
})
|
|
4058
|
+
);
|
|
4059
|
+
const lo = range ? Math.min(...current) : min;
|
|
4060
|
+
const hi = range ? Math.max(...current) : current[0];
|
|
4061
|
+
const tickValues = ticks === true ? (max - min) / step <= 40 ? Array.from({ length: Math.round((max - min) / step) + 1 }, (_, i) => min + i * step) : [] : ticks ? [...ticks] : [];
|
|
4062
|
+
const along = (p) => vertical ? { bottom: p * length } : { left: p * length };
|
|
4063
|
+
const onLayout = (e) => setLength(vertical ? e.nativeEvent.layout.height : e.nativeEvent.layout.width);
|
|
4064
|
+
const fill = vertical ? { bottom: pct(lo) * length, height: (pct(hi) - pct(lo)) * length, left: 0, right: 0 } : { left: pct(lo) * length, width: (pct(hi) - pct(lo)) * length, top: 0, bottom: 0 };
|
|
4065
|
+
return /* @__PURE__ */ jsxs39(View39, { style: [styles35.root, vertical ? styles35.rootVertical : null, disabled ? styles35.disabled : null, style], children: [
|
|
4066
|
+
showLabel ? /* @__PURE__ */ jsxs39(View39, { style: styles35.header, children: [
|
|
4067
|
+
/* @__PURE__ */ jsx47(Text17, { style: [styles35.label, { color: theme.textSecondary }], children: label }),
|
|
4068
|
+
/* @__PURE__ */ jsx47(Text17, { "aria-hidden": true, style: [styles35.value, { color: theme.textSecondary }], children: current.map(formatValue).join(" \u2013 ") })
|
|
4069
|
+
] }) : null,
|
|
4070
|
+
/* @__PURE__ */ jsxs39(View39, { ...responder.panHandlers, style: vertical ? styles35.controlVertical : styles35.control, children: [
|
|
4071
|
+
/* @__PURE__ */ jsxs39(View39, { onLayout, pointerEvents: "none", style: [vertical ? styles35.trackVertical : styles35.track, { borderRadius: radius3.full, backgroundColor: theme.surface3 }], children: [
|
|
4072
|
+
/* @__PURE__ */ jsx47(View39, { style: [styles35.fill, fill, { borderRadius: radius3.full, overflow: "hidden", backgroundColor: theme.accent }], children: tone3 === "gradient" ? /* @__PURE__ */ jsxs39(Svg20, { width: "100%", height: "100%", "aria-hidden": true, children: [
|
|
4073
|
+
/* @__PURE__ */ jsx47(Defs11, { children: /* @__PURE__ */ jsxs39(LinearGradient11, { id: gradientId, x1: "0", y1: vertical ? "1" : "0", x2: vertical ? "0" : "1", y2: "0", children: [
|
|
4074
|
+
/* @__PURE__ */ jsx47(Stop11, { offset: "0", stopColor: theme.accent }),
|
|
4075
|
+
/* @__PURE__ */ jsx47(Stop11, { offset: "1", stopColor: theme.accent2 })
|
|
4076
|
+
] }) }),
|
|
4077
|
+
/* @__PURE__ */ jsx47(Rect4, { width: "100%", height: "100%", fill: `url(#${gradientId})` })
|
|
4078
|
+
] }) : null }),
|
|
4079
|
+
tickValues.map((t) => /* @__PURE__ */ jsx47(View39, { style: [vertical ? styles35.tickVertical : styles35.tick, along(pct(t)), { backgroundColor: t > lo && t < hi ? theme.onAccent : theme.borderStrong }] }, t))
|
|
4080
|
+
] }),
|
|
4081
|
+
current.map((v, i) => /* @__PURE__ */ jsx47(
|
|
4082
|
+
View39,
|
|
4083
|
+
{
|
|
4084
|
+
accessible: true,
|
|
4085
|
+
role: "slider",
|
|
4086
|
+
"aria-label": range ? thumbLabels?.[i] ?? label : label,
|
|
4087
|
+
"aria-valuenow": v,
|
|
4088
|
+
"aria-valuemin": min,
|
|
4089
|
+
"aria-valuemax": max,
|
|
4090
|
+
"aria-valuetext": formatValue(v),
|
|
4091
|
+
"aria-disabled": disabled || void 0,
|
|
4092
|
+
accessibilityActions: [{ name: "increment" }, { name: "decrement" }],
|
|
4093
|
+
onAccessibilityAction: (e) => {
|
|
4094
|
+
const next = snap(v + (e.nativeEvent.actionName === "increment" ? step : -step));
|
|
4095
|
+
move(i, next);
|
|
4096
|
+
const values = [...current];
|
|
4097
|
+
values[i] = next;
|
|
4098
|
+
onValueCommit?.(out(values));
|
|
4099
|
+
},
|
|
4100
|
+
pointerEvents: "none",
|
|
4101
|
+
style: [styles35.thumb, vertical ? { bottom: pct(v) * length, left: (44 - THUMB) / 2, marginLeft: 0, marginTop: 0 } : { left: pct(v) * length - THUMB / 2, top: 0 }, { borderColor: theme.accent, backgroundColor: theme.textOnMedia, shadowColor: theme.scrimStrong }],
|
|
4102
|
+
children: floatingValue === "always" || floatingValue && dragging === i ? /* @__PURE__ */ jsx47(View39, { "aria-hidden": true, style: [vertical ? styles35.bubbleVertical : styles35.bubble, { backgroundColor: theme.textPrimary, borderRadius: radius3.md }], children: /* @__PURE__ */ jsx47(Text17, { style: [styles35.bubbleText, { color: theme.surface0 }], children: formatValue(v) }) }) : null
|
|
4103
|
+
},
|
|
4104
|
+
i
|
|
4105
|
+
))
|
|
4106
|
+
] }),
|
|
4107
|
+
marks2?.length && !vertical ? /* @__PURE__ */ jsx47(View39, { "aria-hidden": true, style: styles35.marks, children: marks2.map((m) => /* @__PURE__ */ jsx47(Text17, { style: [styles35.mark, { left: pct(m.value) * length, color: theme.textSecondary, transform: [{ translateX: m.value === min ? 0 : m.value === max ? -40 : -20 }], textAlign: m.value === min ? "left" : m.value === max ? "right" : "center" }], children: m.label }, m.value)) }) : null
|
|
4108
|
+
] });
|
|
4109
|
+
}
|
|
4110
|
+
var styles35 = StyleSheet35.create({
|
|
4111
|
+
root: { gap: 8, alignSelf: "stretch" },
|
|
4112
|
+
rootVertical: { alignSelf: "flex-start", alignItems: "center" },
|
|
4113
|
+
header: { flexDirection: "row", justifyContent: "space-between", alignItems: "baseline", gap: 12 },
|
|
4114
|
+
label: { fontSize: 12, fontWeight: "600" },
|
|
4115
|
+
value: { fontSize: 12, fontVariant: ["tabular-nums"] },
|
|
4116
|
+
control: { height: 44, justifyContent: "center", paddingHorizontal: THUMB / 2 },
|
|
4117
|
+
controlVertical: { flex: 1, minHeight: 160, width: 44, alignItems: "center", paddingVertical: THUMB / 2 },
|
|
4118
|
+
track: { height: 6 },
|
|
4119
|
+
trackVertical: { width: 6, flex: 1 },
|
|
4120
|
+
fill: { position: "absolute" },
|
|
4121
|
+
tick: { position: "absolute", top: 1, width: 1, height: 4, marginLeft: -0.5 },
|
|
4122
|
+
tickVertical: { position: "absolute", left: 1, height: 1, width: 4, marginBottom: -0.5 },
|
|
4123
|
+
thumb: {
|
|
4124
|
+
position: "absolute",
|
|
4125
|
+
width: THUMB,
|
|
4126
|
+
height: THUMB,
|
|
4127
|
+
borderRadius: THUMB / 2,
|
|
4128
|
+
borderWidth: 2.5,
|
|
4129
|
+
marginLeft: THUMB / 2,
|
|
4130
|
+
marginTop: (44 - THUMB) / 2,
|
|
4131
|
+
shadowOpacity: 0.3,
|
|
4132
|
+
shadowRadius: 4,
|
|
4133
|
+
shadowOffset: { width: 0, height: 2 },
|
|
4134
|
+
elevation: 3
|
|
4135
|
+
},
|
|
4136
|
+
bubble: { position: "absolute", bottom: THUMB + 6, left: -17, minWidth: 56, paddingHorizontal: 8, paddingVertical: 4, alignItems: "center" },
|
|
4137
|
+
bubbleVertical: { position: "absolute", left: THUMB + 8, top: -2, minWidth: 48, paddingHorizontal: 8, paddingVertical: 4, alignItems: "center" },
|
|
4138
|
+
bubbleText: { fontSize: 12, fontWeight: "700", fontVariant: ["tabular-nums"] },
|
|
4139
|
+
marks: { height: 16, marginHorizontal: THUMB / 2 },
|
|
4140
|
+
mark: { position: "absolute", width: 40, fontSize: 11, fontWeight: "500" },
|
|
4141
|
+
disabled: { opacity: 0.4 }
|
|
4142
|
+
});
|
|
4143
|
+
|
|
2736
4144
|
// src/native/spinner.tsx
|
|
2737
4145
|
import { ActivityIndicator as ActivityIndicator2 } from "react-native";
|
|
2738
|
-
import { jsx as
|
|
4146
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
2739
4147
|
function Spinner({ label, size = "md", ...props }) {
|
|
2740
4148
|
const { theme } = useTheme();
|
|
2741
|
-
return /* @__PURE__ */
|
|
4149
|
+
return /* @__PURE__ */ jsx48(
|
|
2742
4150
|
ActivityIndicator2,
|
|
2743
4151
|
{
|
|
2744
4152
|
accessible: true,
|
|
@@ -2752,10 +4160,309 @@ function Spinner({ label, size = "md", ...props }) {
|
|
|
2752
4160
|
);
|
|
2753
4161
|
}
|
|
2754
4162
|
|
|
4163
|
+
// src/native/stepper.tsx
|
|
4164
|
+
import { StyleSheet as StyleSheet36, View as View40 } from "react-native";
|
|
4165
|
+
import Svg21, { Circle as Circle13, Path as Path16 } from "react-native-svg";
|
|
4166
|
+
import { jsx as jsx49, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
4167
|
+
var WORDS = { done: "done", current: "in progress", upcoming: "to come", error: "failed" };
|
|
4168
|
+
function Stepper({ steps, current = 0, orientation = "vertical", statusLabels, "aria-label": label, style }) {
|
|
4169
|
+
const { theme } = useTheme();
|
|
4170
|
+
const words = { ...WORDS, ...statusLabels };
|
|
4171
|
+
const vertical = orientation === "vertical";
|
|
4172
|
+
return /* @__PURE__ */ jsx49(View40, { role: "list", "aria-label": label, style: [vertical ? styles36.column : styles36.row, style], children: steps.map((step, i) => {
|
|
4173
|
+
const status = step.status ?? (i < current ? "done" : i === current ? "current" : "upcoming");
|
|
4174
|
+
const last = i === steps.length - 1;
|
|
4175
|
+
const node = status === "current" ? /* @__PURE__ */ jsx49(LoaderGlyph, { value: step.value ?? null, size: 24 }) : status === "error" ? /* @__PURE__ */ jsx49(LoaderGlyph, { state: "error", size: 24 }) : /* @__PURE__ */ jsxs40(Svg21, { width: 24, height: 24, viewBox: "0 0 24 24", "aria-hidden": true, children: [
|
|
4176
|
+
/* @__PURE__ */ jsx49(Circle13, { cx: 12, cy: 12, r: 10, fill: status === "done" ? theme.accent : "none", stroke: status === "done" ? theme.accent : theme.borderStrong, strokeWidth: 2 }),
|
|
4177
|
+
status === "done" ? /* @__PURE__ */ jsx49(Path16, { d: "M7.5 12.3l3 3 6-6.3", stroke: theme.onAccent, strokeWidth: 2.2, fill: "none", strokeLinecap: "round", strokeLinejoin: "round" }) : null
|
|
4178
|
+
] });
|
|
4179
|
+
const connector = !last ? /* @__PURE__ */ jsx49(View40, { "aria-hidden": true, style: [vertical ? styles36.vLine : styles36.hLine, { backgroundColor: status === "done" ? theme.accent : theme.borderDefault }] }) : null;
|
|
4180
|
+
return /* @__PURE__ */ jsxs40(View40, { role: "listitem", accessible: true, "aria-label": `${step.title}, ${words[status]}`, style: vertical ? styles36.vStep : styles36.hStep, children: [
|
|
4181
|
+
/* @__PURE__ */ jsxs40(View40, { style: vertical ? styles36.vRail : styles36.hRail, children: [
|
|
4182
|
+
node,
|
|
4183
|
+
connector
|
|
4184
|
+
] }),
|
|
4185
|
+
/* @__PURE__ */ jsxs40(View40, { style: [styles36.body, vertical && !last ? { paddingBottom: 20 } : null], children: [
|
|
4186
|
+
/* @__PURE__ */ jsx49(Txt, { variant: "label", tone: status === "upcoming" ? "secondary" : "text", numberOfLines: vertical ? void 0 : 2, children: step.title }),
|
|
4187
|
+
step.description ? /* @__PURE__ */ jsx49(Txt, { variant: "caption", tone: "secondary", children: step.description }) : null,
|
|
4188
|
+
step.content && (status === "current" || status === "error") ? /* @__PURE__ */ jsx49(View40, { style: styles36.content, children: step.content }) : null
|
|
4189
|
+
] })
|
|
4190
|
+
] }, i);
|
|
4191
|
+
}) });
|
|
4192
|
+
}
|
|
4193
|
+
var styles36 = StyleSheet36.create({
|
|
4194
|
+
column: { gap: 0 },
|
|
4195
|
+
row: { flexDirection: "row" },
|
|
4196
|
+
vStep: { flexDirection: "row", gap: 12 },
|
|
4197
|
+
hStep: { flex: 1, gap: 8 },
|
|
4198
|
+
vRail: { alignItems: "center", width: 24 },
|
|
4199
|
+
hRail: { flexDirection: "row", alignItems: "center" },
|
|
4200
|
+
vLine: { width: 2, flex: 1, marginVertical: 4, borderRadius: 1 },
|
|
4201
|
+
hLine: { height: 2, flex: 1, marginHorizontal: 6, borderRadius: 1 },
|
|
4202
|
+
body: { flex: 1, gap: 2, paddingTop: 2 },
|
|
4203
|
+
content: { marginTop: 8 }
|
|
4204
|
+
});
|
|
4205
|
+
|
|
4206
|
+
// src/native/swipeable-row.tsx
|
|
4207
|
+
import * as React34 from "react";
|
|
4208
|
+
import { Animated as Animated19, PanResponder as PanResponder3, Pressable as Pressable18, StyleSheet as StyleSheet37, View as View41 } from "react-native";
|
|
4209
|
+
import { jsx as jsx50, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
4210
|
+
var toneColor = (t, tone3) => ({ neutral: t.surface3, accent: t.accent, success: t.success, warning: t.warning, danger: t.danger })[tone3 ?? "neutral"];
|
|
4211
|
+
var toneText = (tone3) => tone3 === "neutral" || tone3 === void 0 ? "text" : "onAccent";
|
|
4212
|
+
function SwipeableRow({ children, trailing = [], leading = [], fullSwipe = 0.6, actionWidth = 80, onActivate, testID, style }) {
|
|
4213
|
+
const { theme, haptic } = useTheme();
|
|
4214
|
+
const reduce = useReducedMotion();
|
|
4215
|
+
const [x] = React34.useState(() => new Animated19.Value(0));
|
|
4216
|
+
const [width, setWidth] = React34.useState(0);
|
|
4217
|
+
const rest = React34.useRef(0);
|
|
4218
|
+
const armed = React34.useRef(false);
|
|
4219
|
+
const settle = (to) => {
|
|
4220
|
+
rest.current = to;
|
|
4221
|
+
if (reduce) x.setValue(to);
|
|
4222
|
+
else Animated19.spring(x, { toValue: to, useNativeDriver: true, damping: 22, stiffness: 240 }).start();
|
|
4223
|
+
};
|
|
4224
|
+
const run = (action) => {
|
|
4225
|
+
settle(0);
|
|
4226
|
+
action.onPress();
|
|
4227
|
+
};
|
|
4228
|
+
const pan = React34.useMemo(
|
|
4229
|
+
() => PanResponder3.create({
|
|
4230
|
+
onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 8 && Math.abs(g.dx) > Math.abs(g.dy) * 1.5,
|
|
4231
|
+
onPanResponderMove: (_, g) => {
|
|
4232
|
+
let next = rest.current + g.dx;
|
|
4233
|
+
if (next < 0 && trailing.length === 0) next = 0;
|
|
4234
|
+
if (next > 0 && leading.length === 0) next = 0;
|
|
4235
|
+
x.setValue(next);
|
|
4236
|
+
const past = fullSwipe !== false && width > 0 && Math.abs(next) > width * fullSwipe;
|
|
4237
|
+
if (past !== armed.current) {
|
|
4238
|
+
armed.current = past;
|
|
4239
|
+
if (past) haptic("impact");
|
|
4240
|
+
}
|
|
4241
|
+
},
|
|
4242
|
+
onPanResponderRelease: (_, g) => {
|
|
4243
|
+
const at = rest.current + g.dx;
|
|
4244
|
+
if (armed.current) {
|
|
4245
|
+
armed.current = false;
|
|
4246
|
+
const action = at < 0 ? trailing[0] : leading[0];
|
|
4247
|
+
if (action) return run(action);
|
|
4248
|
+
}
|
|
4249
|
+
const open = at < 0 ? -trailing.length * actionWidth : leading.length * actionWidth;
|
|
4250
|
+
settle(Math.abs(at) > actionWidth / 2 ? open : 0);
|
|
4251
|
+
},
|
|
4252
|
+
onPanResponderTerminate: () => settle(0)
|
|
4253
|
+
}),
|
|
4254
|
+
[trailing, leading, fullSwipe, width, actionWidth]
|
|
4255
|
+
// eslint-disable-line react-hooks/exhaustive-deps -- run/settle are stable in effect
|
|
4256
|
+
);
|
|
4257
|
+
const side = (actions, edge) => /* @__PURE__ */ jsx50(View41, { "aria-hidden": true, style: [styles37.side, edge === "left" ? { left: 0 } : { right: 0, flexDirection: "row-reverse" }], children: actions.map((action, i) => (
|
|
4258
|
+
// eslint-disable-next-line react-hooks/refs -- runs on a press, never during render
|
|
4259
|
+
/* @__PURE__ */ jsxs41(Pressable18, { focusable: false, tabIndex: -1, onPress: () => run(action), style: [styles37.action, { width: actionWidth, backgroundColor: toneColor(theme, action.tone) }], children: [
|
|
4260
|
+
action.icon,
|
|
4261
|
+
/* @__PURE__ */ jsx50(Txt, { variant: "caption", tone: toneText(action.tone), style: styles37.actionText, numberOfLines: 1, children: action.label })
|
|
4262
|
+
] }, i)
|
|
4263
|
+
)) });
|
|
4264
|
+
const all = [...leading, ...trailing];
|
|
4265
|
+
return /* @__PURE__ */ jsxs41(View41, { style: [styles37.root, style], onLayout: (e) => setWidth(e.nativeEvent.layout.width), children: [
|
|
4266
|
+
leading.length > 0 ? side(leading, "left") : null,
|
|
4267
|
+
trailing.length > 0 ? side(trailing, "right") : null,
|
|
4268
|
+
/* @__PURE__ */ jsx50(
|
|
4269
|
+
Animated19.View,
|
|
4270
|
+
{
|
|
4271
|
+
...pan.panHandlers,
|
|
4272
|
+
accessible: true,
|
|
4273
|
+
testID,
|
|
4274
|
+
accessibilityActions: [...onActivate ? [{ name: "activate" }] : [], ...all.map((a) => ({ name: a.label, label: a.label }))],
|
|
4275
|
+
onAccessibilityAction: (e) => {
|
|
4276
|
+
if (e.nativeEvent.actionName === "activate") return onActivate?.();
|
|
4277
|
+
const action = all.find((a) => a.label === e.nativeEvent.actionName);
|
|
4278
|
+
if (action) action.onPress();
|
|
4279
|
+
},
|
|
4280
|
+
style: [styles37.front, { backgroundColor: theme.surface0, transform: [{ translateX: x }] }],
|
|
4281
|
+
children
|
|
4282
|
+
}
|
|
4283
|
+
)
|
|
4284
|
+
] });
|
|
4285
|
+
}
|
|
4286
|
+
var styles37 = StyleSheet37.create({
|
|
4287
|
+
root: { overflow: "hidden" },
|
|
4288
|
+
side: { position: "absolute", top: 0, bottom: 0, flexDirection: "row" },
|
|
4289
|
+
action: { alignItems: "center", justifyContent: "center", gap: 4, paddingHorizontal: 6 },
|
|
4290
|
+
actionText: { fontWeight: "700" },
|
|
4291
|
+
front: {}
|
|
4292
|
+
});
|
|
4293
|
+
|
|
4294
|
+
// src/native/switch.tsx
|
|
4295
|
+
import * as React35 from "react";
|
|
4296
|
+
import { Animated as Animated20, Pressable as Pressable19, StyleSheet as StyleSheet38, Text as Text18, View as View42 } from "react-native";
|
|
4297
|
+
import { jsx as jsx51, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
4298
|
+
var SIZES = { sm: { w: 40, h: 24, knob: 18 }, md: { w: 52, h: 32, knob: 26 } };
|
|
4299
|
+
function Switch({ label, checked, defaultChecked = false, onCheckedChange, description, showLabel, size = "md", error, disabled, style }) {
|
|
4300
|
+
const { theme, motion: motion3, haptic } = useTheme();
|
|
4301
|
+
const [own, setOwn] = React35.useState(defaultChecked);
|
|
4302
|
+
const on = checked ?? own;
|
|
4303
|
+
const d = SIZES[size];
|
|
4304
|
+
const travel = d.w - d.knob - (d.h - d.knob);
|
|
4305
|
+
const [x] = React35.useState(() => new Animated20.Value(on ? 1 : 0));
|
|
4306
|
+
React35.useEffect(() => {
|
|
4307
|
+
Animated20.timing(x, { toValue: on ? 1 : 0, duration: motion3.duration.base, useNativeDriver: true }).start();
|
|
4308
|
+
}, [on, x, motion3.duration.base]);
|
|
4309
|
+
const toggle = () => {
|
|
4310
|
+
haptic("selection");
|
|
4311
|
+
if (checked === void 0) setOwn(!on);
|
|
4312
|
+
onCheckedChange?.(!on);
|
|
4313
|
+
};
|
|
4314
|
+
const track = /* @__PURE__ */ jsx51(View42, { style: [styles38.track, { width: d.w, height: d.h, borderRadius: d.h / 2, backgroundColor: on ? theme.accent : theme.surface3, borderColor: error ? theme.danger : on ? theme.accent : theme.borderDefault }], children: /* @__PURE__ */ jsx51(
|
|
4315
|
+
Animated20.View,
|
|
4316
|
+
{
|
|
4317
|
+
style: [
|
|
4318
|
+
styles38.knob,
|
|
4319
|
+
{
|
|
4320
|
+
width: d.knob,
|
|
4321
|
+
height: d.knob,
|
|
4322
|
+
borderRadius: d.knob / 2,
|
|
4323
|
+
backgroundColor: theme.textOnMedia,
|
|
4324
|
+
shadowColor: theme.scrimStrong,
|
|
4325
|
+
transform: [{ translateX: x.interpolate({ inputRange: [0, 1], outputRange: [0, travel] }) }]
|
|
4326
|
+
}
|
|
4327
|
+
]
|
|
4328
|
+
}
|
|
4329
|
+
) });
|
|
4330
|
+
const a11y = {
|
|
4331
|
+
role: "switch",
|
|
4332
|
+
"aria-checked": on,
|
|
4333
|
+
"aria-label": label,
|
|
4334
|
+
"aria-disabled": disabled || void 0,
|
|
4335
|
+
accessibilityHint: error ?? description,
|
|
4336
|
+
disabled,
|
|
4337
|
+
onPress: toggle
|
|
4338
|
+
};
|
|
4339
|
+
if (!showLabel)
|
|
4340
|
+
return /* @__PURE__ */ jsx51(Pressable19, { ...a11y, hitSlop: { top: (44 - d.h) / 2, bottom: (44 - d.h) / 2, left: Math.max(0, (44 - d.w) / 2), right: Math.max(0, (44 - d.w) / 2) }, style: [disabled ? styles38.disabled : null, style], children: track });
|
|
4341
|
+
return /* @__PURE__ */ jsxs42(View42, { style: [styles38.root, style], children: [
|
|
4342
|
+
/* @__PURE__ */ jsxs42(Pressable19, { ...a11y, style: [styles38.row, disabled ? styles38.disabled : null], children: [
|
|
4343
|
+
/* @__PURE__ */ jsxs42(View42, { style: styles38.text, children: [
|
|
4344
|
+
/* @__PURE__ */ jsx51(Text18, { style: [styles38.label, { color: theme.textPrimary }], children: label }),
|
|
4345
|
+
description ? /* @__PURE__ */ jsx51(Text18, { style: [styles38.description, { color: theme.textSecondary }], children: description }) : null
|
|
4346
|
+
] }),
|
|
4347
|
+
track
|
|
4348
|
+
] }),
|
|
4349
|
+
error ? /* @__PURE__ */ jsx51(Text18, { role: "alert", "aria-live": "polite", style: [styles38.description, { color: theme.dangerText }], children: error }) : null
|
|
4350
|
+
] });
|
|
4351
|
+
}
|
|
4352
|
+
var styles38 = StyleSheet38.create({
|
|
4353
|
+
root: { gap: 2, alignSelf: "stretch" },
|
|
4354
|
+
row: { flexDirection: "row", alignItems: "center", gap: 16, minHeight: 48 },
|
|
4355
|
+
text: { flex: 1, gap: 2 },
|
|
4356
|
+
label: { fontSize: 15, lineHeight: 20, fontWeight: "500" },
|
|
4357
|
+
description: { fontSize: 12, lineHeight: 16 },
|
|
4358
|
+
track: { justifyContent: "center", paddingHorizontal: 2, borderWidth: 1 },
|
|
4359
|
+
knob: { shadowOpacity: 0.25, shadowRadius: 3, shadowOffset: { width: 0, height: 1 }, elevation: 2 },
|
|
4360
|
+
disabled: { opacity: 0.4 }
|
|
4361
|
+
});
|
|
4362
|
+
|
|
4363
|
+
// src/native/tab-bar.tsx
|
|
4364
|
+
import { Pressable as Pressable20, StyleSheet as StyleSheet39, Text as Text19, View as View43 } from "react-native";
|
|
4365
|
+
import { jsx as jsx52, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
4366
|
+
function TabBar({ items: items2, value, onValueChange, onReselect, "aria-label": label, style }) {
|
|
4367
|
+
const { theme, insets, haptic } = useTheme();
|
|
4368
|
+
return /* @__PURE__ */ jsx52(View43, { role: "tablist", "aria-label": label, style: [styles39.bar, { backgroundColor: theme.glassBg, borderTopColor: theme.glassBorder, paddingBottom: Math.max(6, insets.bottom) }, style], children: items2.map((item) => {
|
|
4369
|
+
const selected = item.value === value;
|
|
4370
|
+
const color = selected ? theme.accentText : theme.textSecondary;
|
|
4371
|
+
const badge = item.badge === true ? "" : typeof item.badge === "number" && item.badge > 0 ? item.badge > 99 ? "99+" : String(item.badge) : null;
|
|
4372
|
+
return /* @__PURE__ */ jsxs43(
|
|
4373
|
+
Pressable20,
|
|
4374
|
+
{
|
|
4375
|
+
role: "tab",
|
|
4376
|
+
"aria-selected": selected,
|
|
4377
|
+
onPress: () => {
|
|
4378
|
+
haptic("selection");
|
|
4379
|
+
if (selected) onReselect?.(item.value);
|
|
4380
|
+
else onValueChange(item.value);
|
|
4381
|
+
},
|
|
4382
|
+
style: ({ pressed }) => [styles39.item, { opacity: pressed ? 0.7 : 1 }],
|
|
4383
|
+
children: [
|
|
4384
|
+
/* @__PURE__ */ jsxs43(View43, { "aria-hidden": true, style: styles39.icon, children: [
|
|
4385
|
+
item.icon(selected, color),
|
|
4386
|
+
badge !== null ? /* @__PURE__ */ jsx52(View43, { style: [badge ? styles39.count : styles39.dot, { backgroundColor: theme.danger, borderColor: theme.surface1 }], children: badge ? /* @__PURE__ */ jsx52(Text19, { style: [styles39.countText, { color: theme.onAccent }], children: badge }) : null }) : null
|
|
4387
|
+
] }),
|
|
4388
|
+
/* @__PURE__ */ jsx52(Text19, { numberOfLines: 1, style: [styles39.label, { color, fontWeight: selected ? "700" : "500" }], children: item.label }),
|
|
4389
|
+
badge !== null && item.badgeLabel ? /* @__PURE__ */ jsx52(Text19, { style: styles39.unseen, children: `, ${item.badgeLabel}` }) : null
|
|
4390
|
+
]
|
|
4391
|
+
},
|
|
4392
|
+
item.value
|
|
4393
|
+
);
|
|
4394
|
+
}) });
|
|
4395
|
+
}
|
|
4396
|
+
var styles39 = StyleSheet39.create({
|
|
4397
|
+
bar: { flexDirection: "row", borderTopWidth: StyleSheet39.hairlineWidth, paddingTop: 6 },
|
|
4398
|
+
item: { flex: 1, alignItems: "center", gap: 2, minHeight: 48, justifyContent: "center" },
|
|
4399
|
+
icon: { width: 28, height: 26, alignItems: "center", justifyContent: "center" },
|
|
4400
|
+
label: { fontSize: 11, lineHeight: 14 },
|
|
4401
|
+
unseen: { position: "absolute", width: 1, height: 1, overflow: "hidden", opacity: 0 },
|
|
4402
|
+
count: { position: "absolute", top: -4, left: 16, minWidth: 18, height: 18, borderRadius: 9, paddingHorizontal: 4, alignItems: "center", justifyContent: "center", borderWidth: 2 },
|
|
4403
|
+
countText: { fontSize: 10, fontWeight: "800", lineHeight: 12 },
|
|
4404
|
+
dot: { position: "absolute", top: 0, right: 0, width: 10, height: 10, borderRadius: 5, borderWidth: 2 }
|
|
4405
|
+
});
|
|
4406
|
+
|
|
4407
|
+
// src/native/tabs.tsx
|
|
4408
|
+
import * as React36 from "react";
|
|
4409
|
+
import { Pressable as Pressable21, ScrollView as ScrollView6, StyleSheet as StyleSheet40, View as View44 } from "react-native";
|
|
4410
|
+
import { jsx as jsx53, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
4411
|
+
function Tabs({ items: items2, value, defaultValue, onValueChange, "aria-label": label, variant = "underline", style }) {
|
|
4412
|
+
const { theme, radius: radius3, haptic } = useTheme();
|
|
4413
|
+
const [own, setOwn] = React36.useState(defaultValue ?? items2[0]?.value);
|
|
4414
|
+
const current = value ?? own;
|
|
4415
|
+
const select = (next) => {
|
|
4416
|
+
if (next === current) return;
|
|
4417
|
+
haptic("selection");
|
|
4418
|
+
if (value === void 0) setOwn(next);
|
|
4419
|
+
onValueChange?.(next);
|
|
4420
|
+
};
|
|
4421
|
+
const segmented = variant === "segmented";
|
|
4422
|
+
const tabs = items2.map((item) => {
|
|
4423
|
+
const selected = item.value === current;
|
|
4424
|
+
return /* @__PURE__ */ jsx53(
|
|
4425
|
+
Pressable21,
|
|
4426
|
+
{
|
|
4427
|
+
role: "tab",
|
|
4428
|
+
"aria-selected": selected,
|
|
4429
|
+
"aria-disabled": item.disabled,
|
|
4430
|
+
disabled: item.disabled,
|
|
4431
|
+
onPress: () => select(item.value),
|
|
4432
|
+
style: [
|
|
4433
|
+
segmented ? styles40.segment : styles40.tab,
|
|
4434
|
+
segmented && selected ? { backgroundColor: theme.surface0, borderColor: theme.borderDefault, borderRadius: radius3.sm } : null,
|
|
4435
|
+
!segmented ? { borderBottomColor: selected ? theme.accent : "transparent" } : null,
|
|
4436
|
+
item.disabled ? styles40.disabled : null
|
|
4437
|
+
],
|
|
4438
|
+
children: /* @__PURE__ */ jsxs44(Txt, { variant: "label", tone: selected ? "text" : "secondary", numberOfLines: 1, children: [
|
|
4439
|
+
item.label,
|
|
4440
|
+
item.count !== void 0 ? /* @__PURE__ */ jsx53(Txt, { variant: "caption", tone: "secondary", children: ` ${item.count}` }) : null
|
|
4441
|
+
] })
|
|
4442
|
+
},
|
|
4443
|
+
item.value
|
|
4444
|
+
);
|
|
4445
|
+
});
|
|
4446
|
+
const panel = items2.find((i) => i.value === current)?.content;
|
|
4447
|
+
return /* @__PURE__ */ jsxs44(View44, { style: [styles40.root, style], children: [
|
|
4448
|
+
segmented ? /* @__PURE__ */ jsx53(View44, { role: "tablist", "aria-label": label, style: [styles40.track, { backgroundColor: theme.surface2, borderColor: theme.borderSubtle, borderRadius: radius3.md }], children: tabs }) : /* @__PURE__ */ jsx53(View44, { style: [styles40.underline, { borderBottomColor: theme.borderSubtle }], children: /* @__PURE__ */ jsx53(ScrollView6, { horizontal: true, showsHorizontalScrollIndicator: false, role: "tablist", "aria-label": label, contentContainerStyle: styles40.scroll, children: tabs }) }),
|
|
4449
|
+
panel !== void 0 ? /* @__PURE__ */ jsx53(View44, { role: "tabpanel", children: panel }) : null
|
|
4450
|
+
] });
|
|
4451
|
+
}
|
|
4452
|
+
var styles40 = StyleSheet40.create({
|
|
4453
|
+
root: { gap: 12 },
|
|
4454
|
+
underline: { borderBottomWidth: StyleSheet40.hairlineWidth },
|
|
4455
|
+
scroll: { gap: 4, paddingHorizontal: 4 },
|
|
4456
|
+
tab: { minHeight: 44, justifyContent: "center", paddingHorizontal: 12, borderBottomWidth: 2 },
|
|
4457
|
+
track: { flexDirection: "row", padding: 3, gap: 3, borderWidth: StyleSheet40.hairlineWidth, height: 40 },
|
|
4458
|
+
segment: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 8, borderWidth: StyleSheet40.hairlineWidth, borderColor: "transparent" },
|
|
4459
|
+
disabled: { opacity: 0.4 }
|
|
4460
|
+
});
|
|
4461
|
+
|
|
2755
4462
|
// src/native/toast.tsx
|
|
2756
|
-
import * as
|
|
2757
|
-
import { AccessibilityInfo as
|
|
2758
|
-
import { Fragment as
|
|
4463
|
+
import * as React37 from "react";
|
|
4464
|
+
import { AccessibilityInfo as AccessibilityInfo12, Animated as Animated21, PanResponder as PanResponder4, Pressable as Pressable22, StyleSheet as StyleSheet41, Text as Text20, View as View45 } from "react-native";
|
|
4465
|
+
import { Fragment as Fragment6, jsx as jsx54, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
2759
4466
|
var items = [];
|
|
2760
4467
|
var listeners2 = /* @__PURE__ */ new Set();
|
|
2761
4468
|
var counter = 0;
|
|
@@ -2779,87 +4486,104 @@ function dismiss(id) {
|
|
|
2779
4486
|
emit();
|
|
2780
4487
|
gone.forEach((t) => t.onDismiss?.());
|
|
2781
4488
|
}
|
|
2782
|
-
var
|
|
4489
|
+
var tone2 = (name) => (title, options) => show(title, { ...options, tone: name });
|
|
2783
4490
|
var toast = Object.assign(show, {
|
|
2784
|
-
success:
|
|
2785
|
-
warning:
|
|
2786
|
-
error:
|
|
2787
|
-
info:
|
|
4491
|
+
success: tone2("success"),
|
|
4492
|
+
warning: tone2("warning"),
|
|
4493
|
+
error: tone2("error"),
|
|
4494
|
+
info: tone2("info"),
|
|
2788
4495
|
dismiss
|
|
2789
4496
|
});
|
|
2790
4497
|
function ToastView({ item, closeLabel, duration }) {
|
|
2791
|
-
const { theme, radius: radius3 } = useTheme();
|
|
4498
|
+
const { theme, radius: radius3, haptic } = useTheme();
|
|
2792
4499
|
const reduce = useReducedMotion();
|
|
2793
|
-
const [
|
|
2794
|
-
|
|
4500
|
+
const [swipe] = React37.useState(() => new Animated21.Value(0));
|
|
4501
|
+
const drag = React37.useMemo(
|
|
4502
|
+
() => PanResponder4.create({
|
|
4503
|
+
onMoveShouldSetPanResponder: (_, g) => Math.abs(g.dx) > 8 && Math.abs(g.dx) > Math.abs(g.dy),
|
|
4504
|
+
onPanResponderMove: (_, g) => swipe.setValue(g.dx),
|
|
4505
|
+
onPanResponderRelease: (_, g) => {
|
|
4506
|
+
if (Math.abs(g.dx) > 96 || Math.abs(g.vx) > 0.9) {
|
|
4507
|
+
Animated21.timing(swipe, { toValue: Math.sign(g.dx) * 480, duration: 160, useNativeDriver: true }).start(() => dismiss(item.id));
|
|
4508
|
+
} else Animated21.spring(swipe, { toValue: 0, useNativeDriver: true }).start();
|
|
4509
|
+
}
|
|
4510
|
+
}),
|
|
4511
|
+
[swipe, item.id]
|
|
4512
|
+
);
|
|
4513
|
+
React37.useEffect(() => {
|
|
4514
|
+
if (item.tone === "success" || item.tone === "warning") haptic(item.tone);
|
|
4515
|
+
if (item.tone === "error") haptic("warning");
|
|
4516
|
+
}, [item.id]);
|
|
4517
|
+
const [enter] = React37.useState(() => new Animated21.Value(reduce ? 1 : 0));
|
|
4518
|
+
React37.useEffect(() => {
|
|
2795
4519
|
if (reduce) enter.setValue(1);
|
|
2796
|
-
else
|
|
4520
|
+
else Animated21.timing(enter, { toValue: 1, duration: 220, useNativeDriver: true }).start();
|
|
2797
4521
|
}, [enter, reduce]);
|
|
2798
|
-
|
|
2799
|
-
|
|
4522
|
+
React37.useEffect(() => {
|
|
4523
|
+
AccessibilityInfo12.announceForAccessibility(item.description ? `${item.title}. ${item.description}` : item.title);
|
|
2800
4524
|
}, [item.title, item.description]);
|
|
2801
4525
|
const ms = item.duration ?? duration;
|
|
2802
|
-
|
|
4526
|
+
React37.useEffect(() => {
|
|
2803
4527
|
if (!Number.isFinite(ms)) return;
|
|
2804
4528
|
const timer2 = setTimeout(() => dismiss(item.id), ms);
|
|
2805
4529
|
return () => clearTimeout(timer2);
|
|
2806
4530
|
}, [item.id, ms]);
|
|
2807
4531
|
const edge = { success: theme.success, warning: theme.warning, error: theme.danger, info: theme.info, default: theme.borderDefault }[item.tone ?? "default"];
|
|
2808
|
-
const text = /* @__PURE__ */
|
|
2809
|
-
item.icon ? /* @__PURE__ */
|
|
2810
|
-
/* @__PURE__ */
|
|
2811
|
-
/* @__PURE__ */
|
|
2812
|
-
item.description ? /* @__PURE__ */
|
|
4532
|
+
const text = /* @__PURE__ */ jsxs45(Fragment6, { children: [
|
|
4533
|
+
item.icon ? /* @__PURE__ */ jsx54(View45, { "aria-hidden": true, children: item.icon }) : null,
|
|
4534
|
+
/* @__PURE__ */ jsxs45(View45, { style: styles41.content, children: [
|
|
4535
|
+
/* @__PURE__ */ jsx54(Txt, { variant: "label", numberOfLines: 2, children: item.title }),
|
|
4536
|
+
item.description ? /* @__PURE__ */ jsx54(Txt, { variant: "caption", tone: "secondary", numberOfLines: 3, children: item.description }) : null
|
|
2813
4537
|
] })
|
|
2814
4538
|
] });
|
|
2815
|
-
const body = /* @__PURE__ */
|
|
2816
|
-
item.onPress ? /* @__PURE__ */
|
|
2817
|
-
|
|
4539
|
+
const body = /* @__PURE__ */ jsxs45(Fragment6, { children: [
|
|
4540
|
+
item.onPress ? /* @__PURE__ */ jsx54(
|
|
4541
|
+
Pressable22,
|
|
2818
4542
|
{
|
|
2819
4543
|
role: "button",
|
|
2820
4544
|
onPress: () => {
|
|
2821
4545
|
item.onPress?.();
|
|
2822
4546
|
dismiss(item.id);
|
|
2823
4547
|
},
|
|
2824
|
-
style: ({ pressed }) => [
|
|
4548
|
+
style: ({ pressed }) => [styles41.main, { opacity: pressed ? 0.8 : 1 }],
|
|
2825
4549
|
children: text
|
|
2826
4550
|
}
|
|
2827
|
-
) : /* @__PURE__ */
|
|
2828
|
-
item.action ? /* @__PURE__ */
|
|
2829
|
-
|
|
4551
|
+
) : /* @__PURE__ */ jsx54(View45, { style: styles41.main, children: text }),
|
|
4552
|
+
item.action ? /* @__PURE__ */ jsx54(
|
|
4553
|
+
Pressable22,
|
|
2830
4554
|
{
|
|
2831
4555
|
role: "button",
|
|
2832
4556
|
onPress: () => {
|
|
2833
4557
|
item.action?.onPress();
|
|
2834
4558
|
dismiss(item.id);
|
|
2835
4559
|
},
|
|
2836
|
-
style: [
|
|
2837
|
-
children: /* @__PURE__ */
|
|
4560
|
+
style: [styles41.action, { backgroundColor: theme.accent, borderRadius: radius3.sm }],
|
|
4561
|
+
children: /* @__PURE__ */ jsx54(Text20, { style: [styles41.actionLabel, { color: theme.onAccent }], children: item.action.label })
|
|
2838
4562
|
}
|
|
2839
4563
|
) : null,
|
|
2840
|
-
/* @__PURE__ */
|
|
4564
|
+
/* @__PURE__ */ jsx54(Pressable22, { role: "button", "aria-label": closeLabel, hitSlop: 10, onPress: () => dismiss(item.id), style: styles41.close, children: /* @__PURE__ */ jsx54(Text20, { style: [styles41.cross, { color: theme.textSecondary }], children: "\xD7" }) })
|
|
2841
4565
|
] });
|
|
2842
4566
|
const frame = [
|
|
2843
|
-
|
|
4567
|
+
styles41.toast,
|
|
2844
4568
|
{ backgroundColor: theme.surface2, borderColor: theme.borderDefault, borderLeftColor: edge, borderRadius: radius3.lg, shadowColor: theme.scrimStrong }
|
|
2845
4569
|
];
|
|
2846
|
-
const motion3 = { transform: [{ translateY: enter.interpolate({ inputRange: [0, 1], outputRange: [-8, 0] }) }] };
|
|
2847
|
-
return /* @__PURE__ */
|
|
4570
|
+
const motion3 = { transform: [{ translateY: enter.interpolate({ inputRange: [0, 1], outputRange: [-8, 0] }) }, { translateX: swipe }] };
|
|
4571
|
+
return /* @__PURE__ */ jsx54(Animated21.View, { "aria-live": "polite", style: motion3, ...drag.panHandlers, children: /* @__PURE__ */ jsx54(View45, { style: frame, children: body }) });
|
|
2848
4572
|
}
|
|
2849
4573
|
function Toaster({ closeLabel, position = "top", offset = 12, duration = 6e3, max = 3 }) {
|
|
2850
|
-
const all =
|
|
4574
|
+
const all = React37.useSyncExternalStore(subscribe2, snapshot, snapshot);
|
|
2851
4575
|
const shown = all.slice(-max);
|
|
2852
4576
|
if (shown.length === 0) return null;
|
|
2853
|
-
return /* @__PURE__ */
|
|
4577
|
+
return /* @__PURE__ */ jsx54(View45, { pointerEvents: "box-none", style: [styles41.stack, position === "top" ? { top: offset } : { bottom: offset }], children: (position === "top" ? shown : [...shown].reverse()).map((item) => /* @__PURE__ */ jsx54(ToastView, { item, closeLabel, duration }, item.id)) });
|
|
2854
4578
|
}
|
|
2855
|
-
var
|
|
4579
|
+
var styles41 = StyleSheet41.create({
|
|
2856
4580
|
stack: { position: "absolute", left: 12, right: 12, gap: 8, zIndex: 100 },
|
|
2857
4581
|
toast: {
|
|
2858
4582
|
flexDirection: "row",
|
|
2859
4583
|
alignItems: "center",
|
|
2860
4584
|
gap: 10,
|
|
2861
4585
|
padding: 12,
|
|
2862
|
-
borderWidth:
|
|
4586
|
+
borderWidth: StyleSheet41.hairlineWidth,
|
|
2863
4587
|
borderLeftWidth: 4,
|
|
2864
4588
|
shadowOpacity: 0.3,
|
|
2865
4589
|
shadowRadius: 16,
|
|
@@ -2874,6 +4598,8 @@ var styles21 = StyleSheet21.create({
|
|
|
2874
4598
|
cross: { fontSize: 18, lineHeight: 20, fontWeight: "700" }
|
|
2875
4599
|
});
|
|
2876
4600
|
export {
|
|
4601
|
+
ActionSheet,
|
|
4602
|
+
ActivityFeed,
|
|
2877
4603
|
Avatar,
|
|
2878
4604
|
AvatarGroup,
|
|
2879
4605
|
AvatarRoot,
|
|
@@ -2891,31 +4617,53 @@ export {
|
|
|
2891
4617
|
CardTitle,
|
|
2892
4618
|
Checkbox,
|
|
2893
4619
|
Chip,
|
|
4620
|
+
Combobox,
|
|
2894
4621
|
Countdown,
|
|
2895
4622
|
DateField,
|
|
2896
4623
|
DateWheel,
|
|
2897
4624
|
DayStrip,
|
|
4625
|
+
DescriptionList,
|
|
2898
4626
|
EmptyState,
|
|
2899
4627
|
ErrorState,
|
|
4628
|
+
Fab,
|
|
2900
4629
|
GoalGauge,
|
|
4630
|
+
Header,
|
|
2901
4631
|
IconButton,
|
|
4632
|
+
ImageViewer,
|
|
2902
4633
|
KrizakaMark,
|
|
4634
|
+
Loader,
|
|
4635
|
+
LoaderGlyph,
|
|
2903
4636
|
LoadingState,
|
|
2904
4637
|
Mascot,
|
|
2905
4638
|
MascotState,
|
|
4639
|
+
Meter,
|
|
2906
4640
|
MonthPicker,
|
|
4641
|
+
NumberTicker,
|
|
4642
|
+
Onboarding,
|
|
2907
4643
|
OrazakaMark,
|
|
2908
4644
|
OrochiaMark,
|
|
4645
|
+
OtpInput,
|
|
2909
4646
|
Pagination,
|
|
4647
|
+
PermissionPrompt,
|
|
2910
4648
|
Phoenix,
|
|
2911
4649
|
ProductMark,
|
|
2912
4650
|
ProfileCard,
|
|
2913
4651
|
Progress,
|
|
4652
|
+
PullToRefresh,
|
|
4653
|
+
RadioGroup,
|
|
2914
4654
|
SearchField,
|
|
2915
4655
|
Segmented,
|
|
4656
|
+
Select,
|
|
4657
|
+
Sheet,
|
|
2916
4658
|
Skeleton,
|
|
4659
|
+
Slider,
|
|
2917
4660
|
Spinner,
|
|
4661
|
+
Stepper,
|
|
2918
4662
|
SuccessState,
|
|
4663
|
+
SwipeableRow,
|
|
4664
|
+
Switch,
|
|
4665
|
+
TabBar,
|
|
4666
|
+
Tabs,
|
|
2919
4667
|
TextField,
|
|
2920
4668
|
ThemeProvider,
|
|
2921
4669
|
TimePicker,
|
|
@@ -2932,6 +4680,7 @@ export {
|
|
|
2932
4680
|
ageOn,
|
|
2933
4681
|
alpha,
|
|
2934
4682
|
calendarLabels,
|
|
4683
|
+
comboboxLabels,
|
|
2935
4684
|
composeDate,
|
|
2936
4685
|
dateFieldLabels,
|
|
2937
4686
|
datePartsOrder,
|
|
@@ -2940,13 +4689,16 @@ export {
|
|
|
2940
4689
|
isRealDate,
|
|
2941
4690
|
latestBirthDate,
|
|
2942
4691
|
monthNames,
|
|
4692
|
+
prefetchNeighbours,
|
|
2943
4693
|
splitDuration,
|
|
2944
4694
|
textStyles,
|
|
2945
4695
|
timeSlots,
|
|
2946
4696
|
timeToMinutes,
|
|
2947
4697
|
toast,
|
|
2948
4698
|
todayIso,
|
|
4699
|
+
useCollapsingHeader,
|
|
2949
4700
|
useCountdown,
|
|
4701
|
+
useDelayedWait,
|
|
2950
4702
|
useReducedMotion,
|
|
2951
4703
|
useTheme,
|
|
2952
4704
|
uses12Hours
|