@passui/react 0.1.17 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -1
- package/THIRD_PARTY_NOTICES.md +25 -0
- package/dist/types/src/appearance/index.d.ts +2 -0
- package/dist/types/src/appearance/platform.d.ts +9 -0
- package/dist/types/src/appearance/theme.d.ts +71 -0
- package/dist/types/src/components/accordion/accordion.d.ts +19 -0
- package/dist/types/src/components/ambient/ambient.d.ts +12 -0
- package/dist/types/src/components/ambient/index.d.ts +1 -0
- package/dist/types/src/components/aspect-ratio/aspect-ratio.d.ts +7 -0
- package/dist/types/src/components/breadcrumb/breadcrumb.d.ts +16 -0
- package/dist/types/src/components/button/button-styles.d.ts +12 -0
- package/dist/types/src/components/button/button.d.ts +32 -0
- package/dist/types/src/components/button/icon-button.d.ts +10 -0
- package/dist/types/src/components/button/pending-spinner.d.ts +5 -0
- package/dist/types/src/components/button/use-pending-indicator.d.ts +2 -0
- package/dist/types/src/components/chip/chip.d.ts +7 -0
- package/dist/types/src/components/code-block/code-block.d.ts +10 -0
- package/dist/types/src/components/combo-box/combo-box.d.ts +9 -0
- package/dist/types/src/components/command/command.d.ts +18 -0
- package/dist/types/src/components/compact-date-picker/calendar-month.d.ts +25 -0
- package/dist/types/src/components/compact-date-picker/compact-date-picker.d.ts +27 -0
- package/dist/types/src/components/compact-time-picker/compact-time-picker.d.ts +26 -0
- package/dist/types/src/components/compact-time-picker/time-value.d.ts +18 -0
- package/dist/types/src/components/content-unavailable-view/content-unavailable-view.d.ts +9 -0
- package/dist/types/src/components/content-view/content-view.d.ts +48 -0
- package/dist/types/src/components/content-view/index.d.ts +1 -0
- package/dist/types/src/components/context-menu/conceal-menu-source.d.ts +2 -0
- package/dist/types/src/components/context-menu/context-menu-host.d.ts +2 -0
- package/dist/types/src/components/context-menu/context-menu-store.d.ts +57 -0
- package/dist/types/src/components/context-menu/menu-navigation.d.ts +6 -0
- package/dist/types/src/components/context-menu/menu-position.d.ts +21 -0
- package/dist/types/src/components/context-menu/menu-reveal.d.ts +17 -0
- package/dist/types/src/components/context-menu/use-context-menu.d.ts +14 -0
- package/dist/types/src/components/conversation/conversation.d.ts +43 -0
- package/dist/types/src/components/conversation/index.d.ts +1 -0
- package/dist/types/src/components/date-picker/date-picker.d.ts +16 -0
- package/dist/types/src/components/date-picker/date-value.d.ts +2 -0
- package/dist/types/src/components/dialog/dialog-host.d.ts +6 -0
- package/dist/types/src/components/dialog/dialog-store.d.ts +23 -0
- package/dist/types/src/components/dialog/dialog.d.ts +30 -0
- package/dist/types/src/components/dialog/index.d.ts +1 -0
- package/dist/types/src/components/disclosure-group/disclosure-group.d.ts +15 -0
- package/dist/types/src/components/divider/divider.d.ts +9 -0
- package/dist/types/src/components/inline-disclosure/inline-disclosure.d.ts +15 -0
- package/dist/types/src/components/keyboard-shortcut/keyboard-shortcut.d.ts +5 -0
- package/dist/types/src/components/labeled-content/labeled-content.d.ts +19 -0
- package/dist/types/src/components/locale-switcher/index.d.ts +1 -0
- package/dist/types/src/components/locale-switcher/locale-switcher.d.ts +10 -0
- package/dist/types/src/components/menu/menu.d.ts +16 -0
- package/dist/types/src/components/one-time-code/one-time-code.d.ts +18 -0
- package/dist/types/src/components/picker/picker-trigger.d.ts +2 -0
- package/dist/types/src/components/picker/picker.d.ts +43 -0
- package/dist/types/src/components/popover/anchored-surface.d.ts +13 -0
- package/dist/types/src/components/popover/popover-fit.d.ts +21 -0
- package/dist/types/src/components/popover/popover.d.ts +18 -0
- package/dist/types/src/components/profile-image/profile-image.d.ts +4 -0
- package/dist/types/src/components/progress-view/progress-view.d.ts +13 -0
- package/dist/types/src/components/progress-view/use-liquid-progress.d.ts +3 -0
- package/dist/types/src/components/radio-group/radio-group.d.ts +17 -0
- package/dist/types/src/components/search-field/expanding-search-field.d.ts +5 -0
- package/dist/types/src/components/search-field/search-field.d.ts +6 -0
- package/dist/types/src/components/search-list/search-list.d.ts +19 -0
- package/dist/types/src/components/section/section.d.ts +15 -0
- package/dist/types/src/components/secure-field/secure-field.d.ts +4 -0
- package/dist/types/src/components/segmented-control/segmented-control.d.ts +20 -0
- package/dist/types/src/components/sheet/modal-environment.d.ts +2 -0
- package/dist/types/src/components/sheet/sheet-portal.d.ts +5 -0
- package/dist/types/src/components/sheet/sheet.d.ts +21 -0
- package/dist/types/src/components/sheet/use-sheet-focus.d.ts +3 -0
- package/dist/types/src/components/sidebar/sidebar.d.ts +19 -0
- package/dist/types/src/components/skeleton/skeleton.d.ts +6 -0
- package/dist/types/src/components/slider/slider.d.ts +14 -0
- package/dist/types/src/components/slosh-slider/liquid-step.d.ts +6 -0
- package/dist/types/src/components/slosh-slider/slosh-slider.d.ts +18 -0
- package/dist/types/src/components/stat-tile/index.d.ts +1 -0
- package/dist/types/src/components/stat-tile/stat-tile.d.ts +15 -0
- package/dist/types/src/components/status-indicator/status-indicator.d.ts +14 -0
- package/dist/types/src/components/stepper/rolling-digit.d.ts +11 -0
- package/dist/types/src/components/stepper/stepper.d.ts +19 -0
- package/dist/types/src/components/swatch-picker/swatch-picker.d.ts +17 -0
- package/dist/types/src/components/tab-bar/tab-bar.d.ts +40 -0
- package/dist/types/src/components/tab-view/tab-view.d.ts +24 -0
- package/dist/types/src/components/table/table.d.ts +10 -0
- package/dist/types/src/components/text-editor/text-editor.d.ts +2 -0
- package/dist/types/src/components/text-field/text-field.d.ts +20 -0
- package/dist/types/src/components/toast/toast-store.d.ts +47 -0
- package/dist/types/src/components/toast/toaster.d.ts +10 -0
- package/dist/types/src/components/toggle/toggle.d.ts +17 -0
- package/dist/types/src/components/tooltip/tooltip-host.d.ts +6 -0
- package/dist/types/src/components/view-controller/index.d.ts +1 -0
- package/dist/types/src/components/view-controller/view-controller.d.ts +21 -0
- package/dist/types/src/components/wake-slider/wake-slider.d.ts +12 -0
- package/dist/types/src/hooks/scroll/minimize-decision.d.ts +2 -0
- package/dist/types/src/hooks/use-anchored-disclosure.d.ts +9 -0
- package/dist/types/src/hooks/use-anchored-placement.d.ts +7 -0
- package/dist/types/src/hooks/use-dismiss.d.ts +9 -0
- package/dist/types/src/hooks/use-floating-dismiss.d.ts +3 -0
- package/dist/types/src/hooks/use-media-query.d.ts +21 -0
- package/dist/types/src/hooks/use-minimize-on-scroll.d.ts +6 -0
- package/dist/types/src/hooks/use-visual-viewport.d.ts +4 -0
- package/dist/types/src/hooks/viewport/types.d.ts +19 -0
- package/dist/types/src/hooks/viewport/viewport-metrics.d.ts +3 -0
- package/dist/types/src/icons/icons.d.ts +612 -0
- package/dist/types/src/index.d.ts +71 -0
- package/dist/types/src/lib/anchored-placement.d.ts +39 -0
- package/dist/types/src/lib/class-names.d.ts +2 -0
- package/dist/types/src/lib/clipboard.d.ts +6 -0
- package/dist/types/src/lib/date.d.ts +50 -0
- package/dist/types/src/lib/floating-layers.d.ts +8 -0
- package/dist/types/src/lib/haptics.d.ts +8 -0
- package/dist/types/src/lib/language.d.ts +4 -0
- package/dist/types/src/lib/range-value.d.ts +4 -0
- package/dist/types/src/lib/screen-edges.d.ts +12 -0
- package/dist/types/src/lib/shapes.d.ts +17 -0
- package/dist/types/src/motion/transitions.d.ts +97 -0
- package/dist/types/src/tokens.d.ts +1 -0
- package/package.json +248 -40
- package/src/appearance/platform.tsx +10 -47
- package/src/appearance/theme.tsx +42 -142
- package/src/components/accordion/accordion.tsx +48 -0
- package/src/components/ambient/ambient.tsx +2 -10
- package/src/components/aspect-ratio/aspect-ratio.tsx +22 -0
- package/src/components/breadcrumb/breadcrumb.tsx +53 -0
- package/src/components/button/button-styles.ts +13 -31
- package/src/components/button/button.tsx +24 -15
- package/src/components/button/icon-button.tsx +14 -56
- package/src/components/button/use-pending-indicator.ts +2 -7
- package/src/components/chip/chip.tsx +8 -13
- package/src/components/code-block/code-block.tsx +41 -0
- package/src/components/combo-box/combo-box.tsx +13 -0
- package/src/components/command/command.tsx +119 -0
- package/src/components/compact-date-picker/calendar-month.ts +13 -57
- package/src/components/compact-date-picker/compact-date-picker.tsx +72 -195
- package/src/components/compact-time-picker/compact-time-picker.tsx +74 -195
- package/src/components/compact-time-picker/time-value.ts +4 -16
- package/src/components/content-unavailable-view/content-unavailable-view.tsx +37 -0
- package/src/components/content-view/content-view.tsx +13 -56
- package/src/components/context-menu/conceal-menu-source.ts +1 -4
- package/src/components/context-menu/context-menu-host.tsx +132 -198
- package/src/components/context-menu/context-menu-store.ts +5 -14
- package/src/components/context-menu/menu-navigation.ts +29 -0
- package/src/components/context-menu/menu-position.ts +6 -27
- package/src/components/context-menu/menu-reveal.ts +14 -52
- package/src/components/context-menu/use-context-menu.ts +6 -30
- package/src/components/conversation/conversation.tsx +26 -72
- package/src/components/date-picker/date-picker.tsx +8 -37
- package/src/components/date-picker/date-value.ts +5 -30
- package/src/components/dialog/dialog-host.tsx +37 -76
- package/src/components/dialog/dialog-store.ts +16 -7
- package/src/components/dialog/dialog.tsx +23 -80
- package/src/components/disclosure-group/disclosure-group.tsx +79 -0
- package/src/components/divider/divider.tsx +31 -0
- package/src/components/inline-disclosure/inline-disclosure.tsx +49 -0
- package/src/components/keyboard-shortcut/keyboard-shortcut.tsx +17 -0
- package/src/components/labeled-content/labeled-content.tsx +24 -18
- package/src/components/locale-switcher/locale-switcher.tsx +20 -70
- package/src/components/menu/menu.tsx +68 -0
- package/src/components/one-time-code/one-time-code.tsx +168 -0
- package/src/components/picker/picker-trigger.ts +10 -0
- package/src/components/picker/picker.tsx +165 -283
- package/src/components/popover/anchored-surface.tsx +223 -0
- package/src/components/popover/popover-fit.ts +69 -0
- package/src/components/popover/popover.tsx +209 -63
- package/src/components/profile-image/profile-image.tsx +6 -28
- package/src/components/progress-view/progress-view.tsx +70 -0
- package/src/components/progress-view/use-liquid-progress.ts +43 -0
- package/src/components/radio-group/radio-group.tsx +63 -0
- package/src/components/search-field/expanding-search-field.tsx +183 -0
- package/src/components/search-field/search-field.tsx +25 -7
- package/src/components/search-list/search-list.tsx +58 -75
- package/src/components/section/section.tsx +18 -17
- package/src/components/secure-field/secure-field.tsx +5 -7
- package/src/components/segmented-control/segmented-control.tsx +20 -29
- package/src/components/sheet/modal-environment.ts +16 -54
- package/src/components/sheet/sheet-portal.tsx +10 -42
- package/src/components/sheet/sheet.tsx +17 -25
- package/src/components/sheet/use-sheet-focus.ts +15 -51
- package/src/components/sidebar/sidebar.tsx +44 -38
- package/src/components/skeleton/skeleton.tsx +19 -0
- package/src/components/slider/slider.tsx +76 -0
- package/src/components/slosh-slider/liquid-step.ts +42 -0
- package/src/components/slosh-slider/slosh-slider.tsx +251 -0
- package/src/components/stat-tile/stat-tile.tsx +9 -30
- package/src/components/status-indicator/status-indicator.tsx +12 -19
- package/src/components/stepper/rolling-digit.tsx +77 -0
- package/src/components/stepper/stepper.tsx +101 -0
- package/src/components/swatch-picker/swatch-picker.tsx +19 -15
- package/src/components/tab-bar/tab-bar.tsx +59 -59
- package/src/components/tab-view/tab-view.tsx +52 -57
- package/src/components/table/table.tsx +14 -62
- package/src/components/text-editor/text-editor.tsx +2 -12
- package/src/components/text-field/text-field.tsx +53 -44
- package/src/components/toast/toast-store.ts +9 -30
- package/src/components/toast/toaster.tsx +90 -104
- package/src/components/toggle/toggle.tsx +165 -44
- package/src/components/tooltip/tooltip-host.tsx +70 -67
- package/src/components/view-controller/view-controller.tsx +4 -21
- package/src/components/wake-slider/wake-slider.tsx +237 -0
- package/src/hooks/scroll/minimize-decision.ts +1 -5
- package/src/hooks/use-anchored-disclosure.ts +23 -0
- package/src/hooks/use-anchored-placement.ts +7 -14
- package/src/hooks/use-dismiss.ts +5 -23
- package/src/hooks/use-floating-dismiss.ts +28 -0
- package/src/hooks/use-media-query.ts +12 -31
- package/src/hooks/use-minimize-on-scroll.ts +10 -34
- package/src/hooks/use-visual-viewport.ts +5 -14
- package/src/hooks/viewport/viewport-metrics.ts +4 -16
- package/src/icons/icons.tsx +229 -183
- package/src/index.ts +27 -1
- package/src/lib/anchored-placement.ts +12 -18
- package/src/lib/class-names.ts +1 -2
- package/src/lib/clipboard.ts +14 -0
- package/src/lib/date.ts +4 -15
- package/src/lib/floating-layers.ts +18 -8
- package/src/lib/haptics.ts +1 -3
- package/src/lib/language.ts +2 -7
- package/src/lib/range-value.ts +32 -0
- package/src/lib/screen-edges.ts +2 -6
- package/src/lib/shapes.ts +5 -20
- package/src/motion/transitions.ts +18 -12
- package/src/styles/code-block.css +33 -0
- package/src/styles/motion-controls.css +189 -0
- package/src/styles/styles.css +3 -0
- package/src/components/ambient/ambient.docs.tsx +0 -68
- package/src/components/ambient/examples/ambient-images.tsx +0 -30
- package/src/components/ambient/examples/ambient-now-playing.tsx +0 -55
- package/src/components/ambient/examples/ambient-showcase.tsx +0 -33
- package/src/components/ambient/examples/ambient-usage.tsx +0 -19
- package/src/components/button/button.docs.tsx +0 -116
- package/src/components/button/examples/button-disabled.tsx +0 -19
- package/src/components/button/examples/button-icon.tsx +0 -39
- package/src/components/button/examples/button-link.tsx +0 -12
- package/src/components/button/examples/button-pending.tsx +0 -27
- package/src/components/button/examples/button-showcase.tsx +0 -115
- package/src/components/button/examples/button-sizes.tsx +0 -12
- package/src/components/button/examples/button-usage.tsx +0 -12
- package/src/components/button/examples/button-variants.tsx +0 -15
- package/src/components/button/examples/button-with-icon.tsx +0 -32
- package/src/components/button/examples/icon-button-player.tsx +0 -38
- package/src/components/button/examples/icon-button-showcase.tsx +0 -83
- package/src/components/button/examples/icon-button-usage.tsx +0 -11
- package/src/components/button/examples/icon-button-variants.tsx +0 -39
- package/src/components/button/icon-button.docs.tsx +0 -68
- package/src/components/chip/chip.docs.tsx +0 -37
- package/src/components/chip/examples/chip-in-rows.tsx +0 -19
- package/src/components/chip/examples/chip-showcase.tsx +0 -51
- package/src/components/chip/examples/chip-tones.tsx +0 -13
- package/src/components/chip/examples/chip-usage.tsx +0 -5
- package/src/components/compact-date-picker/compact-date-picker.docs.tsx +0 -81
- package/src/components/compact-date-picker/examples/compact-date-picker-showcase.tsx +0 -35
- package/src/components/compact-date-picker/examples/compact-date-picker-usage.tsx +0 -22
- package/src/components/compact-time-picker/compact-time-picker.docs.tsx +0 -80
- package/src/components/compact-time-picker/examples/compact-time-picker-showcase.tsx +0 -31
- package/src/components/compact-time-picker/examples/compact-time-picker-usage.tsx +0 -21
- package/src/components/content-view/content-view.docs.tsx +0 -61
- package/src/components/content-view/examples/content-view-header-action.tsx +0 -33
- package/src/components/content-view/examples/content-view-showcase.tsx +0 -65
- package/src/components/content-view/examples/content-view-stats.tsx +0 -35
- package/src/components/content-view/examples/content-view-usage.tsx +0 -14
- package/src/components/context-menu/context-menu.docs.tsx +0 -92
- package/src/components/context-menu/examples/context-menu-checked.tsx +0 -37
- package/src/components/context-menu/examples/context-menu-list.tsx +0 -85
- package/src/components/context-menu/examples/context-menu-showcase.tsx +0 -56
- package/src/components/context-menu/examples/context-menu-toolbar.tsx +0 -63
- package/src/components/context-menu/examples/context-menu-usage.tsx +0 -24
- package/src/components/conversation/conversation.docs.tsx +0 -88
- package/src/components/conversation/examples/conversation-composer.tsx +0 -36
- package/src/components/conversation/examples/conversation-days.tsx +0 -48
- package/src/components/conversation/examples/conversation-showcase.tsx +0 -71
- package/src/components/conversation/examples/conversation-usage.tsx +0 -28
- package/src/components/date-picker/date-picker.docs.tsx +0 -88
- package/src/components/date-picker/examples/date-picker-locales.tsx +0 -41
- package/src/components/date-picker/examples/date-picker-past-only.tsx +0 -29
- package/src/components/date-picker/examples/date-picker-showcase.tsx +0 -49
- package/src/components/date-picker/examples/date-picker-usage.tsx +0 -22
- package/src/components/dialog/dialog.docs.tsx +0 -114
- package/src/components/dialog/examples/dialog-confirm.tsx +0 -24
- package/src/components/dialog/examples/dialog-form.tsx +0 -46
- package/src/components/dialog/examples/dialog-inline.tsx +0 -48
- package/src/components/dialog/examples/dialog-showcase.tsx +0 -53
- package/src/components/dialog/examples/dialog-usage.tsx +0 -31
- package/src/components/labeled-content/examples/labeled-content-descriptions.tsx +0 -37
- package/src/components/labeled-content/examples/labeled-content-showcase.tsx +0 -54
- package/src/components/labeled-content/examples/labeled-content-usage.tsx +0 -22
- package/src/components/labeled-content/examples/labeled-content-values.tsx +0 -26
- package/src/components/labeled-content/examples/labeled-content-wide.tsx +0 -46
- package/src/components/labeled-content/labeled-content.docs.tsx +0 -69
- package/src/components/locale-switcher/examples/locale-switcher-native-names.tsx +0 -30
- package/src/components/locale-switcher/examples/locale-switcher-showcase.tsx +0 -46
- package/src/components/locale-switcher/examples/locale-switcher-translated-page.tsx +0 -35
- package/src/components/locale-switcher/examples/locale-switcher-usage.tsx +0 -20
- package/src/components/locale-switcher/locale-switcher.docs.tsx +0 -91
- package/src/components/picker/examples/picker-details.tsx +0 -44
- package/src/components/picker/examples/picker-searchable.tsx +0 -48
- package/src/components/picker/examples/picker-showcase.tsx +0 -66
- package/src/components/picker/examples/picker-usage.tsx +0 -20
- package/src/components/picker/picker.docs.tsx +0 -68
- package/src/components/popover/examples/popover-help.tsx +0 -57
- package/src/components/popover/examples/popover-menu.tsx +0 -51
- package/src/components/popover/examples/popover-showcase.tsx +0 -61
- package/src/components/popover/examples/popover-usage.tsx +0 -31
- package/src/components/popover/popover.docs.tsx +0 -84
- package/src/components/profile-image/examples/profile-image-fallbacks.tsx +0 -29
- package/src/components/profile-image/examples/profile-image-group.tsx +0 -34
- package/src/components/profile-image/examples/profile-image-showcase.tsx +0 -30
- package/src/components/profile-image/examples/profile-image-usage.tsx +0 -14
- package/src/components/profile-image/profile-image.docs.tsx +0 -81
- package/src/components/search-field/examples/search-field-filter.tsx +0 -53
- package/src/components/search-field/examples/search-field-showcase.tsx +0 -56
- package/src/components/search-field/examples/search-field-toolbar.tsx +0 -27
- package/src/components/search-field/examples/search-field-usage.tsx +0 -18
- package/src/components/search-field/search-field.docs.tsx +0 -58
- package/src/components/search-list/examples/search-list-dropdown.tsx +0 -53
- package/src/components/search-list/examples/search-list-groups.tsx +0 -64
- package/src/components/search-list/examples/search-list-showcase.tsx +0 -67
- package/src/components/search-list/examples/search-list-usage.tsx +0 -27
- package/src/components/search-list/search-list.docs.tsx +0 -87
- package/src/components/section/examples/section-actions.tsx +0 -35
- package/src/components/section/examples/section-groups.tsx +0 -41
- package/src/components/section/examples/section-showcase.tsx +0 -63
- package/src/components/section/examples/section-usage.tsx +0 -19
- package/src/components/section/section.docs.tsx +0 -51
- package/src/components/secure-field/examples/secure-field-new-password.tsx +0 -56
- package/src/components/secure-field/examples/secure-field-reveal.tsx +0 -20
- package/src/components/secure-field/examples/secure-field-showcase.tsx +0 -62
- package/src/components/secure-field/examples/secure-field-usage.tsx +0 -19
- package/src/components/secure-field/secure-field.docs.tsx +0 -72
- package/src/components/segmented-control/examples/segmented-control-overflow.tsx +0 -28
- package/src/components/segmented-control/examples/segmented-control-showcase.tsx +0 -59
- package/src/components/segmented-control/examples/segmented-control-usage.tsx +0 -20
- package/src/components/segmented-control/examples/segmented-control-views.tsx +0 -32
- package/src/components/segmented-control/segmented-control.docs.tsx +0 -61
- package/src/components/sheet/examples/sheet-choices.tsx +0 -58
- package/src/components/sheet/examples/sheet-share.tsx +0 -51
- package/src/components/sheet/examples/sheet-showcase.tsx +0 -74
- package/src/components/sheet/examples/sheet-usage.tsx +0 -32
- package/src/components/sheet/sheet.docs.tsx +0 -75
- package/src/components/sidebar/examples/sidebar-groups.tsx +0 -133
- package/src/components/sidebar/examples/sidebar-showcase.tsx +0 -123
- package/src/components/sidebar/examples/sidebar-unread.tsx +0 -66
- package/src/components/sidebar/examples/sidebar-usage.tsx +0 -52
- package/src/components/sidebar/sidebar.docs.tsx +0 -135
- package/src/components/stat-tile/examples/stat-tile-filters.tsx +0 -32
- package/src/components/stat-tile/examples/stat-tile-grid.tsx +0 -21
- package/src/components/stat-tile/examples/stat-tile-showcase.tsx +0 -52
- package/src/components/stat-tile/examples/stat-tile-usage.tsx +0 -13
- package/src/components/stat-tile/stat-tile.docs.tsx +0 -60
- package/src/components/status-indicator/examples/status-indicator-live.tsx +0 -34
- package/src/components/status-indicator/examples/status-indicator-showcase.tsx +0 -39
- package/src/components/status-indicator/examples/status-indicator-states.tsx +0 -17
- package/src/components/status-indicator/examples/status-indicator-usage.tsx +0 -9
- package/src/components/status-indicator/status-indicator.docs.tsx +0 -43
- package/src/components/swatch-picker/examples/swatch-picker-accents.tsx +0 -42
- package/src/components/swatch-picker/examples/swatch-picker-labels.tsx +0 -45
- package/src/components/swatch-picker/examples/swatch-picker-showcase.tsx +0 -70
- package/src/components/swatch-picker/examples/swatch-picker-usage.tsx +0 -39
- package/src/components/swatch-picker/swatch-picker.docs.tsx +0 -60
- package/src/components/tab-bar/examples/tab-bar-five-tabs.tsx +0 -66
- package/src/components/tab-bar/examples/tab-bar-minimize.tsx +0 -71
- package/src/components/tab-bar/examples/tab-bar-showcase.tsx +0 -82
- package/src/components/tab-bar/examples/tab-bar-usage.tsx +0 -54
- package/src/components/tab-bar/tab-bar.docs.tsx +0 -136
- package/src/components/tab-view/examples/tab-view-keyboard.tsx +0 -39
- package/src/components/tab-view/examples/tab-view-settings.tsx +0 -56
- package/src/components/tab-view/examples/tab-view-showcase.tsx +0 -53
- package/src/components/tab-view/examples/tab-view-usage.tsx +0 -23
- package/src/components/tab-view/tab-view.docs.tsx +0 -77
- package/src/components/table/examples/table-empty.tsx +0 -53
- package/src/components/table/examples/table-invoices.tsx +0 -102
- package/src/components/table/examples/table-selection.tsx +0 -150
- package/src/components/table/examples/table-showcase.tsx +0 -115
- package/src/components/table/examples/table-usage.tsx +0 -67
- package/src/components/table/examples/table-wide.tsx +0 -75
- package/src/components/table/table.docs.tsx +0 -131
- package/src/components/text-editor/examples/text-editor-comment.tsx +0 -48
- package/src/components/text-editor/examples/text-editor-count.tsx +0 -38
- package/src/components/text-editor/examples/text-editor-showcase.tsx +0 -58
- package/src/components/text-editor/examples/text-editor-usage.tsx +0 -25
- package/src/components/text-editor/text-editor.docs.tsx +0 -61
- package/src/components/text-field/examples/text-field-icons.tsx +0 -72
- package/src/components/text-field/examples/text-field-showcase.tsx +0 -50
- package/src/components/text-field/examples/text-field-usage.tsx +0 -18
- package/src/components/text-field/examples/text-field-validation.tsx +0 -27
- package/src/components/text-field/text-field.docs.tsx +0 -118
- package/src/components/toast/examples/toast-action.tsx +0 -32
- package/src/components/toast/examples/toast-promise.tsx +0 -45
- package/src/components/toast/examples/toast-showcase.tsx +0 -49
- package/src/components/toast/examples/toast-usage.tsx +0 -13
- package/src/components/toast/toast.docs.tsx +0 -79
- package/src/components/toggle/examples/toggle-checkboxes.tsx +0 -43
- package/src/components/toggle/examples/toggle-settings.tsx +0 -31
- package/src/components/toggle/examples/toggle-showcase.tsx +0 -59
- package/src/components/toggle/examples/toggle-usage.tsx +0 -13
- package/src/components/toggle/toggle.docs.tsx +0 -69
- package/src/components/tooltip/examples/tooltip-icon-buttons.tsx +0 -27
- package/src/components/tooltip/examples/tooltip-shortcuts.tsx +0 -38
- package/src/components/tooltip/examples/tooltip-showcase.tsx +0 -44
- package/src/components/tooltip/examples/tooltip-usage.tsx +0 -13
- package/src/components/tooltip/tooltip.docs.tsx +0 -56
- package/src/components/view-controller/examples/view-controller-action.tsx +0 -27
- package/src/components/view-controller/examples/view-controller-settings.tsx +0 -31
- package/src/components/view-controller/examples/view-controller-showcase.tsx +0 -45
- package/src/components/view-controller/examples/view-controller-usage.tsx +0 -19
- package/src/components/view-controller/view-controller.docs.tsx +0 -71
- package/src/docs/index.ts +0 -3
- package/src/docs/registry.ts +0 -113
- package/src/docs/snippet.ts +0 -17
- package/src/docs/types.ts +0 -180
|
@@ -20,26 +20,35 @@ export interface PendingDialog extends ConfirmOptions {
|
|
|
20
20
|
let current: PendingDialog | null = null
|
|
21
21
|
let nextId = 1
|
|
22
22
|
const queue: PendingDialog[] = []
|
|
23
|
+
let exitingId: number | null = null
|
|
23
24
|
const listeners = new Set<() => void>()
|
|
24
25
|
|
|
25
26
|
const emit = () => {
|
|
26
27
|
for (const listener of listeners) listener()
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
export function confirmDialog(
|
|
30
|
-
options: ConfirmOptions
|
|
31
|
-
): Promise<boolean> {
|
|
30
|
+
export function confirmDialog(options: ConfirmOptions): Promise<boolean> {
|
|
32
31
|
return new Promise((resolve) => {
|
|
33
32
|
const dialog = { ...options, id: nextId++, resolve }
|
|
34
|
-
if (current) queue.push(dialog)
|
|
33
|
+
if (current || exitingId !== null) queue.push(dialog)
|
|
35
34
|
else current = dialog
|
|
36
35
|
emit()
|
|
37
36
|
})
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
export function settleDialog(confirmed: boolean) {
|
|
41
|
-
if (!current) return
|
|
42
|
-
current
|
|
39
|
+
export function settleDialog(confirmed: boolean, id?: number) {
|
|
40
|
+
if (!current || exitingId !== null || (id !== undefined && current.id !== id)) return
|
|
41
|
+
const settled = current
|
|
42
|
+
exitingId = settled.id
|
|
43
|
+
current = null
|
|
44
|
+
settled.resolve(confirmed)
|
|
45
|
+
emit()
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Advance queued confirmations only after the dismissed card has exited. */
|
|
49
|
+
export function advanceDialogQueue() {
|
|
50
|
+
if (exitingId === null) return
|
|
51
|
+
exitingId = null
|
|
43
52
|
current = queue.shift() ?? null
|
|
44
53
|
emit()
|
|
45
54
|
}
|
|
@@ -1,35 +1,22 @@
|
|
|
1
|
-
import { Sheet } from "
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
useReducedMotion,
|
|
6
|
-
} from "motion/react"
|
|
7
|
-
import { createPortal } from "react-dom"
|
|
8
|
-
import { Button } from "@passui/react/button"
|
|
9
|
-
import { cn } from "@passui/react/cn"
|
|
1
|
+
import { Sheet } from "../sheet/sheet"
|
|
2
|
+
import { AnimatePresence, motion, useReducedMotion } from "motion/react"
|
|
3
|
+
import { Button } from "../button/button"
|
|
4
|
+
import { cn } from "../../lib/class-names"
|
|
10
5
|
import { spring } from "../../motion/transitions"
|
|
11
|
-
import {
|
|
12
|
-
createContext,
|
|
13
|
-
useContext,
|
|
14
|
-
useId,
|
|
15
|
-
type FormEvent,
|
|
16
|
-
type ReactNode,
|
|
17
|
-
} from "react"
|
|
6
|
+
import { createContext, useContext, useId, type FormEvent, type ReactNode } from "react"
|
|
18
7
|
|
|
19
8
|
const CloseContext = createContext<() => void>(() => {})
|
|
20
|
-
export type DialogPresentation =
|
|
21
|
-
| "drawer"
|
|
22
|
-
| "center"
|
|
23
|
-
| "inline"
|
|
9
|
+
export type DialogPresentation = "drawer" | "center" | "inline"
|
|
24
10
|
export type DialogTone = "default" | "destructive"
|
|
25
11
|
|
|
26
|
-
type DialogProps = {
|
|
12
|
+
export type DialogProps = {
|
|
27
13
|
open: boolean
|
|
28
14
|
onOpenChange: (open: boolean) => void
|
|
29
15
|
title: ReactNode
|
|
30
16
|
description?: ReactNode
|
|
31
17
|
children?: ReactNode
|
|
32
18
|
footer?: ReactNode
|
|
19
|
+
/** `drawer` (responsive sheet), `center` (floating panel), or `inline`. @default "drawer" */
|
|
33
20
|
presentation?: DialogPresentation
|
|
34
21
|
className?: string
|
|
35
22
|
onSubmit?: (event: FormEvent<HTMLFormElement>) => void
|
|
@@ -60,28 +47,13 @@ export function Dialog({
|
|
|
60
47
|
const content = (
|
|
61
48
|
<>
|
|
62
49
|
{presentation !== "inline" && (
|
|
63
|
-
<h2
|
|
64
|
-
id={titleId}
|
|
65
|
-
className="text-title3 font-semibold"
|
|
66
|
-
>
|
|
50
|
+
<h2 id={titleId} className="text-title3 font-semibold">
|
|
67
51
|
{title}
|
|
68
52
|
</h2>
|
|
69
53
|
)}
|
|
70
|
-
{description &&
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
</p>
|
|
74
|
-
)}
|
|
75
|
-
{children && (
|
|
76
|
-
<div className="flex flex-col gap-4">
|
|
77
|
-
{children}
|
|
78
|
-
</div>
|
|
79
|
-
)}
|
|
80
|
-
{footer && (
|
|
81
|
-
<div className="flex flex-wrap justify-end gap-2 pt-3">
|
|
82
|
-
{footer}
|
|
83
|
-
</div>
|
|
84
|
-
)}
|
|
54
|
+
{description && <div className="text-footnote text-label-secondary">{description}</div>}
|
|
55
|
+
{children && <div className="flex flex-col gap-4">{children}</div>}
|
|
56
|
+
{footer && <div className="flex flex-wrap justify-end gap-2 pt-3">{footer}</div>}
|
|
85
57
|
</>
|
|
86
58
|
)
|
|
87
59
|
const body = (
|
|
@@ -89,20 +61,12 @@ export function Dialog({
|
|
|
89
61
|
{onSubmit ? (
|
|
90
62
|
<form
|
|
91
63
|
onSubmit={onSubmit}
|
|
92
|
-
className={cn(
|
|
93
|
-
"flex min-h-0 flex-col gap-4 overflow-y-auto p-5",
|
|
94
|
-
className
|
|
95
|
-
)}
|
|
64
|
+
className={cn("flex min-h-0 flex-col gap-4 overflow-y-auto p-5", className)}
|
|
96
65
|
>
|
|
97
66
|
{content}
|
|
98
67
|
</form>
|
|
99
68
|
) : (
|
|
100
|
-
<div
|
|
101
|
-
className={cn(
|
|
102
|
-
"flex min-h-0 flex-col gap-4 overflow-y-auto p-5",
|
|
103
|
-
className
|
|
104
|
-
)}
|
|
105
|
-
>
|
|
69
|
+
<div className={cn("flex min-h-0 flex-col gap-4 overflow-y-auto p-5", className)}>
|
|
106
70
|
{content}
|
|
107
71
|
</div>
|
|
108
72
|
)}
|
|
@@ -115,9 +79,7 @@ export function Dialog({
|
|
|
115
79
|
<motion.div
|
|
116
80
|
key={titleId}
|
|
117
81
|
initial={{
|
|
118
|
-
height: reducedMotion
|
|
119
|
-
? "auto"
|
|
120
|
-
: 0,
|
|
82
|
+
height: reducedMotion ? "auto" : 0,
|
|
121
83
|
opacity: 0,
|
|
122
84
|
}}
|
|
123
85
|
animate={{
|
|
@@ -125,16 +87,10 @@ export function Dialog({
|
|
|
125
87
|
opacity: 1,
|
|
126
88
|
}}
|
|
127
89
|
exit={{
|
|
128
|
-
height: reducedMotion
|
|
129
|
-
? "auto"
|
|
130
|
-
: 0,
|
|
90
|
+
height: reducedMotion ? "auto" : 0,
|
|
131
91
|
opacity: 0,
|
|
132
92
|
}}
|
|
133
|
-
transition={
|
|
134
|
-
reducedMotion
|
|
135
|
-
? { duration: 0 }
|
|
136
|
-
: spring.smooth
|
|
137
|
-
}
|
|
93
|
+
transition={reducedMotion ? { duration: 0 } : spring.smooth}
|
|
138
94
|
className="overflow-hidden"
|
|
139
95
|
>
|
|
140
96
|
{body}
|
|
@@ -142,17 +98,16 @@ export function Dialog({
|
|
|
142
98
|
)}
|
|
143
99
|
</AnimatePresence>
|
|
144
100
|
)
|
|
145
|
-
|
|
146
|
-
return createPortal(
|
|
101
|
+
return (
|
|
147
102
|
<Sheet
|
|
148
103
|
open={open}
|
|
149
104
|
onClose={close}
|
|
150
105
|
label=""
|
|
151
106
|
labelledBy={titleId}
|
|
107
|
+
placement={presentation === "center" ? "center" : "adaptive"}
|
|
152
108
|
>
|
|
153
109
|
{body}
|
|
154
|
-
</Sheet
|
|
155
|
-
document.body
|
|
110
|
+
</Sheet>
|
|
156
111
|
)
|
|
157
112
|
}
|
|
158
113
|
|
|
@@ -170,27 +125,15 @@ function Actions({
|
|
|
170
125
|
<>
|
|
171
126
|
<Button
|
|
172
127
|
type={onConfirm ? "button" : "submit"}
|
|
173
|
-
variant={
|
|
174
|
-
|
|
175
|
-
? "ghost"
|
|
176
|
-
: "default"
|
|
177
|
-
}
|
|
178
|
-
className={
|
|
179
|
-
tone === "destructive"
|
|
180
|
-
? "bg-danger/10 text-danger"
|
|
181
|
-
: undefined
|
|
182
|
-
}
|
|
128
|
+
variant={tone === "destructive" ? "ghost" : "default"}
|
|
129
|
+
className={tone === "destructive" ? "bg-danger/10 text-danger" : undefined}
|
|
183
130
|
isPending={pending}
|
|
184
131
|
disabled={disabled}
|
|
185
132
|
onClick={onConfirm}
|
|
186
133
|
>
|
|
187
134
|
{submitLabel}
|
|
188
135
|
</Button>
|
|
189
|
-
<Button
|
|
190
|
-
type="button"
|
|
191
|
-
variant="secondary"
|
|
192
|
-
onClick={close}
|
|
193
|
-
>
|
|
136
|
+
<Button type="button" variant="secondary" onClick={close}>
|
|
194
137
|
{cancelLabel}
|
|
195
138
|
</Button>
|
|
196
139
|
</>
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Button } from "../button/button"
|
|
2
|
+
import { type ReactNode, useId } from "react"
|
|
3
|
+
import { ChevronDownIcon } from "../../icons/icons"
|
|
4
|
+
import { cn } from "../../lib/class-names"
|
|
5
|
+
import { InlineDisclosure } from "../inline-disclosure/inline-disclosure"
|
|
6
|
+
|
|
7
|
+
export interface DisclosureGroupProps {
|
|
8
|
+
label: string
|
|
9
|
+
open: boolean
|
|
10
|
+
onOpenChange: (open: boolean) => void
|
|
11
|
+
children: ReactNode
|
|
12
|
+
disabled?: boolean
|
|
13
|
+
className?: string
|
|
14
|
+
/** Trigger layout when composed inside a shared surface such as Accordion. */
|
|
15
|
+
triggerClassName?: string
|
|
16
|
+
/** Supporting text beneath the title. */
|
|
17
|
+
description?: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** A controlled, accessible disclosure row with the shared inline reveal. */
|
|
21
|
+
export function DisclosureGroup({
|
|
22
|
+
label,
|
|
23
|
+
open,
|
|
24
|
+
onOpenChange,
|
|
25
|
+
children,
|
|
26
|
+
disabled = false,
|
|
27
|
+
className,
|
|
28
|
+
triggerClassName,
|
|
29
|
+
description,
|
|
30
|
+
}: DisclosureGroupProps) {
|
|
31
|
+
const id = useId()
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div className={cn("w-full min-w-0", className)}>
|
|
35
|
+
<h3 className="m-0">
|
|
36
|
+
<Button
|
|
37
|
+
variant="ghost"
|
|
38
|
+
contentClassName="w-full min-w-0 justify-between gap-3"
|
|
39
|
+
type="button"
|
|
40
|
+
id={`${id}-trigger`}
|
|
41
|
+
aria-expanded={open}
|
|
42
|
+
aria-controls={id}
|
|
43
|
+
disabled={disabled}
|
|
44
|
+
onClick={() => onOpenChange(!open)}
|
|
45
|
+
className={cn(
|
|
46
|
+
"h-auto min-h-11 w-full rounded-xl px-4 py-3 text-start active:scale-100",
|
|
47
|
+
"text-subheadline font-normal text-label hover:bg-fill/60 focus-visible:ring-inset focus-visible:ring-offset-0",
|
|
48
|
+
"focus-visible:outline-accent-text disabled:cursor-not-allowed disabled:opacity-40",
|
|
49
|
+
triggerClassName
|
|
50
|
+
)}
|
|
51
|
+
>
|
|
52
|
+
<span className="flex min-w-0 flex-col gap-0.5">
|
|
53
|
+
<span className="font-medium break-words whitespace-normal">{label}</span>
|
|
54
|
+
{description && (
|
|
55
|
+
<span className="text-footnote leading-footnote font-normal break-words whitespace-normal text-label-secondary">
|
|
56
|
+
{description}
|
|
57
|
+
</span>
|
|
58
|
+
)}
|
|
59
|
+
</span>
|
|
60
|
+
<ChevronDownIcon
|
|
61
|
+
size={17}
|
|
62
|
+
aria-hidden="true"
|
|
63
|
+
className={cn(
|
|
64
|
+
"shrink-0 text-label-tertiary transition-transform duration-normal motion-reduce:transition-none",
|
|
65
|
+
open && "rotate-180"
|
|
66
|
+
)}
|
|
67
|
+
/>
|
|
68
|
+
</Button>
|
|
69
|
+
</h3>
|
|
70
|
+
<section id={id} aria-labelledby={`${id}-trigger`} aria-hidden={!open} inert={!open}>
|
|
71
|
+
<InlineDisclosure open={open}>
|
|
72
|
+
<div className="min-w-0 px-4 pb-4 text-subheadline leading-subheadline text-label-secondary [overflow-wrap:anywhere]">
|
|
73
|
+
{children}
|
|
74
|
+
</div>
|
|
75
|
+
</InlineDisclosure>
|
|
76
|
+
</section>
|
|
77
|
+
</div>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { HTMLAttributes } from "react"
|
|
2
|
+
import { cn } from "../../lib/class-names"
|
|
3
|
+
|
|
4
|
+
export type DividerOrientation = "horizontal" | "vertical"
|
|
5
|
+
|
|
6
|
+
export interface DividerProps extends HTMLAttributes<HTMLHRElement> {
|
|
7
|
+
orientation?: DividerOrientation
|
|
8
|
+
/** Decorative separators are omitted from the accessibility tree. @default true */
|
|
9
|
+
decorative?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** A semantic separator using the shared surface color. */
|
|
13
|
+
export function Divider({
|
|
14
|
+
orientation = "horizontal",
|
|
15
|
+
decorative = true,
|
|
16
|
+
className,
|
|
17
|
+
...props
|
|
18
|
+
}: DividerProps) {
|
|
19
|
+
return (
|
|
20
|
+
<hr
|
|
21
|
+
{...props}
|
|
22
|
+
role={decorative ? "none" : "separator"}
|
|
23
|
+
aria-orientation={decorative ? undefined : orientation}
|
|
24
|
+
className={cn(
|
|
25
|
+
"shrink-0 border-0 bg-separator",
|
|
26
|
+
orientation === "horizontal" ? "h-px w-full" : "h-full w-px self-stretch",
|
|
27
|
+
className
|
|
28
|
+
)}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { AnimatePresence, motion, useReducedMotion } from "motion/react"
|
|
2
|
+
import type { ReactNode } from "react"
|
|
3
|
+
import { cn } from "../../lib/class-names"
|
|
4
|
+
import { spring } from "../../motion/transitions"
|
|
5
|
+
|
|
6
|
+
export interface InlineDisclosureProps {
|
|
7
|
+
/** Whether the content is expanded. */
|
|
8
|
+
open: boolean
|
|
9
|
+
children: ReactNode
|
|
10
|
+
className?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* An inline, spring-driven reveal for settings editors and small details.
|
|
15
|
+
*
|
|
16
|
+
* Height and opacity animate together so following rows move continuously
|
|
17
|
+
* instead of jumping. Motion is disabled when the user requests less motion.
|
|
18
|
+
* The content unmounts after its exit animation completes.
|
|
19
|
+
*/
|
|
20
|
+
export function InlineDisclosure({ open, children, className }: InlineDisclosureProps) {
|
|
21
|
+
const reduceMotion = useReducedMotion()
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<AnimatePresence initial={false}>
|
|
25
|
+
{open && (
|
|
26
|
+
<motion.div
|
|
27
|
+
key="inline-disclosure"
|
|
28
|
+
initial={reduceMotion ? false : { height: 0, opacity: 0 }}
|
|
29
|
+
animate={{ height: "auto", opacity: 1 }}
|
|
30
|
+
exit={reduceMotion ? { opacity: 0 } : { height: 0, opacity: 0 }}
|
|
31
|
+
transition={
|
|
32
|
+
reduceMotion
|
|
33
|
+
? { duration: 0 }
|
|
34
|
+
: {
|
|
35
|
+
height: spring.smooth,
|
|
36
|
+
opacity: {
|
|
37
|
+
duration: 0.18,
|
|
38
|
+
ease: "easeOut",
|
|
39
|
+
},
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
className={cn("overflow-hidden", className)}
|
|
43
|
+
>
|
|
44
|
+
{children}
|
|
45
|
+
</motion.div>
|
|
46
|
+
)}
|
|
47
|
+
</AnimatePresence>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ComponentProps } from "react"
|
|
2
|
+
import { cn } from "../../lib/class-names"
|
|
3
|
+
|
|
4
|
+
export interface KeyboardShortcutProps extends ComponentProps<"kbd"> {}
|
|
5
|
+
|
|
6
|
+
/** A quiet keycap for a shortcut supplied and localized by the application. */
|
|
7
|
+
export function KeyboardShortcut({ className, ...props }: KeyboardShortcutProps) {
|
|
8
|
+
return (
|
|
9
|
+
<kbd
|
|
10
|
+
{...props}
|
|
11
|
+
className={cn(
|
|
12
|
+
"inline-flex shrink-0 items-center rounded-md border border-separator/70 bg-fill/50 px-1.5 py-0.5 font-mono text-caption2 leading-none text-label-secondary",
|
|
13
|
+
className
|
|
14
|
+
)}
|
|
15
|
+
/>
|
|
16
|
+
)
|
|
17
|
+
}
|
|
@@ -1,6 +1,19 @@
|
|
|
1
|
-
import type { ReactNode } from "react"
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from "react"
|
|
2
2
|
import { cn } from "../../lib/class-names"
|
|
3
3
|
|
|
4
|
+
export interface LabeledContentProps extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
/** The visible name of the row. */
|
|
6
|
+
label: string
|
|
7
|
+
/** Supporting text below the label. */
|
|
8
|
+
description?: string
|
|
9
|
+
/** The row's control or value. */
|
|
10
|
+
children: ReactNode
|
|
11
|
+
/** Places the control below the label at every width. @default false */
|
|
12
|
+
stacked?: boolean
|
|
13
|
+
/** Places a wide control below its label on phones. @default false */
|
|
14
|
+
wide?: boolean
|
|
15
|
+
}
|
|
16
|
+
|
|
4
17
|
/**
|
|
5
18
|
* A row: a label, an optional description, and its control at the trailing
|
|
6
19
|
* end, as SwiftUI's `LabeledContent`. Wide controls move under the label
|
|
@@ -12,38 +25,31 @@ export function LabeledContent({
|
|
|
12
25
|
children,
|
|
13
26
|
stacked,
|
|
14
27
|
wide,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
children: ReactNode
|
|
19
|
-
/** Put the control under the label, for wide controls. */
|
|
20
|
-
stacked?: boolean
|
|
21
|
-
/** A wide control (segmented) that moves under the label on phones. */
|
|
22
|
-
wide?: boolean
|
|
23
|
-
}) {
|
|
28
|
+
className,
|
|
29
|
+
...props
|
|
30
|
+
}: LabeledContentProps) {
|
|
24
31
|
return (
|
|
25
32
|
<div
|
|
26
33
|
className={cn(
|
|
27
|
-
"flex flex-wrap gap-x-4 gap-y-2
|
|
34
|
+
"flex flex-wrap gap-x-4 gap-y-2 px-4 py-3",
|
|
28
35
|
stacked
|
|
29
36
|
? "flex-col items-stretch"
|
|
30
37
|
: cn(
|
|
31
38
|
"items-center justify-between",
|
|
32
|
-
wide &&
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
wide && "max-sm:flex-col max-sm:items-stretch max-sm:gap-2"
|
|
40
|
+
),
|
|
41
|
+
className
|
|
35
42
|
)}
|
|
43
|
+
{...props}
|
|
36
44
|
>
|
|
37
45
|
<div
|
|
38
46
|
className={cn(
|
|
39
|
-
"flex min-w-0 flex-1 flex-col break-normal",
|
|
47
|
+
"flex min-w-0 flex-1 flex-col gap-2 break-normal",
|
|
40
48
|
!stacked && "basis-36",
|
|
41
49
|
wide && "max-sm:basis-auto"
|
|
42
50
|
)}
|
|
43
51
|
>
|
|
44
|
-
<span className="text-subheadline text-label">
|
|
45
|
-
{label}
|
|
46
|
-
</span>
|
|
52
|
+
<span className="text-subheadline text-label">{label}</span>
|
|
47
53
|
{description && (
|
|
48
54
|
<span className="text-footnote leading-snug text-label-secondary">
|
|
49
55
|
{description}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
import { getNativeLanguageName } from "../../lib/language"
|
|
2
2
|
import { cn } from "../../lib/class-names"
|
|
3
|
-
import {
|
|
4
|
-
AnimatePresence,
|
|
5
|
-
motion,
|
|
6
|
-
useDragControls,
|
|
7
|
-
useMotionValue,
|
|
8
|
-
} from "motion/react"
|
|
3
|
+
import { AnimatePresence, motion, useDragControls, useMotionValue } from "motion/react"
|
|
9
4
|
import { useEffect, useRef, useState } from "react"
|
|
10
5
|
|
|
11
6
|
type Side = "left" | "right"
|
|
@@ -31,10 +26,8 @@ function loadStoredAnchor(storageKey: string): Anchor | null {
|
|
|
31
26
|
if (!raw) return null
|
|
32
27
|
const parsed = JSON.parse(raw) as Partial<Anchor>
|
|
33
28
|
if (
|
|
34
|
-
(parsed.side === "left" ||
|
|
35
|
-
|
|
36
|
-
(parsed.edge === "top" ||
|
|
37
|
-
parsed.edge === "bottom") &&
|
|
29
|
+
(parsed.side === "left" || parsed.side === "right") &&
|
|
30
|
+
(parsed.edge === "top" || parsed.edge === "bottom") &&
|
|
38
31
|
typeof parsed.x === "number" &&
|
|
39
32
|
typeof parsed.y === "number"
|
|
40
33
|
) {
|
|
@@ -49,15 +42,9 @@ function loadStoredAnchor(storageKey: string): Anchor | null {
|
|
|
49
42
|
return null
|
|
50
43
|
}
|
|
51
44
|
|
|
52
|
-
function saveStoredAnchor(
|
|
53
|
-
storageKey: string,
|
|
54
|
-
anchor: Anchor
|
|
55
|
-
) {
|
|
45
|
+
function saveStoredAnchor(storageKey: string, anchor: Anchor) {
|
|
56
46
|
try {
|
|
57
|
-
localStorage.setItem(
|
|
58
|
-
storageKey,
|
|
59
|
-
JSON.stringify(anchor)
|
|
60
|
-
)
|
|
47
|
+
localStorage.setItem(storageKey, JSON.stringify(anchor))
|
|
61
48
|
} catch {}
|
|
62
49
|
}
|
|
63
50
|
|
|
@@ -98,50 +85,25 @@ export function LocaleSwitcher<L extends string>({
|
|
|
98
85
|
useEffect(() => {
|
|
99
86
|
if (!open) return
|
|
100
87
|
function handlePointerDown(e: PointerEvent) {
|
|
101
|
-
if (
|
|
102
|
-
containerRef.current &&
|
|
103
|
-
!containerRef.current.contains(
|
|
104
|
-
e.target as Node
|
|
105
|
-
)
|
|
106
|
-
) {
|
|
88
|
+
if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
|
|
107
89
|
setOpen(false)
|
|
108
90
|
}
|
|
109
91
|
}
|
|
110
|
-
document.addEventListener(
|
|
111
|
-
|
|
112
|
-
handlePointerDown
|
|
113
|
-
)
|
|
114
|
-
return () =>
|
|
115
|
-
document.removeEventListener(
|
|
116
|
-
"pointerdown",
|
|
117
|
-
handlePointerDown
|
|
118
|
-
)
|
|
92
|
+
document.addEventListener("pointerdown", handlePointerDown)
|
|
93
|
+
return () => document.removeEventListener("pointerdown", handlePointerDown)
|
|
119
94
|
}, [open])
|
|
120
95
|
|
|
121
96
|
function commitDraggedPosition() {
|
|
122
97
|
const el = containerRef.current
|
|
123
98
|
if (!el) return
|
|
124
99
|
const rect = el.getBoundingClientRect()
|
|
125
|
-
const side: Side =
|
|
126
|
-
|
|
127
|
-
? "left"
|
|
128
|
-
: "right"
|
|
129
|
-
const edge: Edge =
|
|
130
|
-
rect.top + rect.height / 2 <
|
|
131
|
-
window.innerHeight / 2
|
|
132
|
-
? "top"
|
|
133
|
-
: "bottom"
|
|
100
|
+
const side: Side = rect.left + rect.width / 2 < window.innerWidth / 2 ? "left" : "right"
|
|
101
|
+
const edge: Edge = rect.top + rect.height / 2 < window.innerHeight / 2 ? "top" : "bottom"
|
|
134
102
|
const next: Anchor = {
|
|
135
103
|
side,
|
|
136
104
|
edge,
|
|
137
|
-
x:
|
|
138
|
-
|
|
139
|
-
? rect.left
|
|
140
|
-
: window.innerWidth - rect.right,
|
|
141
|
-
y:
|
|
142
|
-
edge === "top"
|
|
143
|
-
? rect.top
|
|
144
|
-
: window.innerHeight - rect.bottom,
|
|
105
|
+
x: side === "left" ? rect.left : window.innerWidth - rect.right,
|
|
106
|
+
y: edge === "top" ? rect.top : window.innerHeight - rect.bottom,
|
|
145
107
|
}
|
|
146
108
|
setAnchor(next)
|
|
147
109
|
saveStoredAnchor(storageKey, next)
|
|
@@ -163,12 +125,8 @@ export function LocaleSwitcher<L extends string>({
|
|
|
163
125
|
position: "fixed",
|
|
164
126
|
x,
|
|
165
127
|
y,
|
|
166
|
-
...(anchor.side === "left"
|
|
167
|
-
|
|
168
|
-
: { right: anchor.x }),
|
|
169
|
-
...(anchor.edge === "top"
|
|
170
|
-
? { top: anchor.y }
|
|
171
|
-
: { bottom: anchor.y }),
|
|
128
|
+
...(anchor.side === "left" ? { left: anchor.x } : { right: anchor.x }),
|
|
129
|
+
...(anchor.edge === "top" ? { top: anchor.y } : { bottom: anchor.y }),
|
|
172
130
|
}}
|
|
173
131
|
onDragEnd={commitDraggedPosition}
|
|
174
132
|
onMouseLeave={() => open && setOpen(false)}
|
|
@@ -182,7 +140,7 @@ export function LocaleSwitcher<L extends string>({
|
|
|
182
140
|
stiffness: 380,
|
|
183
141
|
}}
|
|
184
142
|
className={cn(
|
|
185
|
-
"overflow-hidden rounded-2xl border border-
|
|
143
|
+
"overflow-hidden rounded-2xl border border-separator/35 bg-elevated/80 shadow-lg",
|
|
186
144
|
"backdrop-blur-xl backdrop-saturate-150",
|
|
187
145
|
"flex",
|
|
188
146
|
growsUp ? "flex-col-reverse" : "flex-col",
|
|
@@ -193,16 +151,12 @@ export function LocaleSwitcher<L extends string>({
|
|
|
193
151
|
type="button"
|
|
194
152
|
aria-label={label}
|
|
195
153
|
aria-expanded={open}
|
|
196
|
-
onPointerDown={(e) =>
|
|
197
|
-
dragControls.start(e)
|
|
198
|
-
}
|
|
154
|
+
onPointerDown={(e) => dragControls.start(e)}
|
|
199
155
|
onClick={() => setOpen((prev) => !prev)}
|
|
200
156
|
className={cn(
|
|
201
157
|
"flex shrink-0 cursor-grab items-center justify-center",
|
|
202
158
|
"active:cursor-grabbing text-xs font-semibold",
|
|
203
|
-
open
|
|
204
|
-
? "h-9 w-full rounded-lg hover:bg-accent"
|
|
205
|
-
: "size-10 rounded-2xl"
|
|
159
|
+
open ? "h-9 w-full rounded-lg hover:bg-accent" : "size-10 rounded-2xl"
|
|
206
160
|
)}
|
|
207
161
|
>
|
|
208
162
|
{locale.toUpperCase()}
|
|
@@ -218,8 +172,7 @@ export function LocaleSwitcher<L extends string>({
|
|
|
218
172
|
className="flex flex-col gap-px"
|
|
219
173
|
>
|
|
220
174
|
{langs.map((item) => {
|
|
221
|
-
const active =
|
|
222
|
-
item.value === locale
|
|
175
|
+
const active = item.value === locale
|
|
223
176
|
return (
|
|
224
177
|
<button
|
|
225
178
|
key={item.value}
|
|
@@ -227,16 +180,13 @@ export function LocaleSwitcher<L extends string>({
|
|
|
227
180
|
onClick={() => {
|
|
228
181
|
setOpen(false)
|
|
229
182
|
if (!active) {
|
|
230
|
-
onSelect(
|
|
231
|
-
item.value
|
|
232
|
-
)
|
|
183
|
+
onSelect(item.value)
|
|
233
184
|
}
|
|
234
185
|
}}
|
|
235
186
|
className={cn(
|
|
236
187
|
"rounded-sm px-2 py-1.5 text-left text-sm",
|
|
237
188
|
"hover:bg-accent transition-colors",
|
|
238
|
-
active &&
|
|
239
|
-
"text-primary font-medium"
|
|
189
|
+
active && "text-primary font-medium"
|
|
240
190
|
)}
|
|
241
191
|
>
|
|
242
192
|
{item.label}
|