@passui/react 0.1.16 → 0.1.19
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 +102 -1
- 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/ambient/ambient.d.ts +12 -0
- package/dist/types/src/components/ambient/index.d.ts +1 -0
- package/dist/types/src/components/button/button-styles.d.ts +12 -0
- package/dist/types/src/components/button/button.d.ts +30 -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/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-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 +22 -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 +21 -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 +13 -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/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/picker/picker-trigger.d.ts +2 -0
- package/dist/types/src/components/picker/picker.d.ts +37 -0
- package/dist/types/src/components/popover/popover-fit.d.ts +21 -0
- package/dist/types/src/components/popover/popover.d.ts +14 -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/search-field/search-field.d.ts +2 -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 +18 -0
- package/dist/types/src/components/slider/slider.d.ts +14 -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/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 +18 -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/hooks/scroll/minimize-decision.d.ts +2 -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 +58 -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 +192 -40
- package/src/appearance/platform.tsx +10 -47
- package/src/appearance/theme.tsx +42 -142
- package/src/components/ambient/ambient.tsx +2 -10
- package/src/components/button/button-styles.ts +13 -31
- package/src/components/button/button.tsx +19 -14
- 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/compact-date-picker/calendar-month.ts +13 -57
- package/src/components/compact-date-picker/compact-date-picker.tsx +44 -123
- package/src/components/compact-time-picker/compact-time-picker.tsx +46 -130
- package/src/components/compact-time-picker/time-value.ts +4 -16
- 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 +125 -195
- package/src/components/context-menu/context-menu-store.ts +3 -11
- 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 +13 -54
- 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 +31 -76
- package/src/components/dialog/dialog-store.ts +1 -3
- package/src/components/dialog/dialog.tsx +23 -80
- package/src/components/disclosure-group/disclosure-group.tsx +70 -0
- package/src/components/divider/divider.tsx +31 -0
- package/src/components/inline-disclosure/inline-disclosure.tsx +49 -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/picker/picker-trigger.ts +10 -0
- package/src/components/picker/picker.tsx +72 -203
- package/src/components/popover/popover-fit.ts +69 -0
- package/src/components/popover/popover.tsx +94 -77
- package/src/components/profile-image/profile-image.tsx +6 -28
- package/src/components/progress-view/progress-view.tsx +65 -0
- package/src/components/search-field/search-field.tsx +27 -25
- package/src/components/search-list/search-list.tsx +43 -69
- 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 +27 -30
- package/src/components/slider/slider.tsx +76 -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/stepper.tsx +80 -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 +11 -40
- package/src/components/toast/toast-store.ts +9 -30
- package/src/components/toast/toaster.tsx +90 -104
- package/src/components/toggle/toggle.tsx +28 -24
- package/src/components/tooltip/tooltip-host.tsx +71 -69
- package/src/components/view-controller/view-controller.tsx +4 -21
- package/src/hooks/scroll/minimize-decision.ts +1 -5
- package/src/hooks/use-anchored-placement.ts +4 -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 +167 -121
- package/src/index.ts +9 -1
- package/src/lib/anchored-placement.ts +5 -15
- 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/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
|
@@ -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,70 @@
|
|
|
1
|
+
import { type ReactNode, useId } from "react"
|
|
2
|
+
import { ChevronDownIcon } from "../../icons/icons"
|
|
3
|
+
import { cn } from "../../lib/class-names"
|
|
4
|
+
import { InlineDisclosure } from "../inline-disclosure/inline-disclosure"
|
|
5
|
+
|
|
6
|
+
export interface DisclosureGroupProps {
|
|
7
|
+
label: string
|
|
8
|
+
open: boolean
|
|
9
|
+
onOpenChange: (open: boolean) => void
|
|
10
|
+
children: ReactNode
|
|
11
|
+
disabled?: boolean
|
|
12
|
+
className?: string
|
|
13
|
+
/** Supporting text beneath the title. */
|
|
14
|
+
description?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A controlled, accessible disclosure row with the shared inline reveal. */
|
|
18
|
+
export function DisclosureGroup({
|
|
19
|
+
label,
|
|
20
|
+
open,
|
|
21
|
+
onOpenChange,
|
|
22
|
+
children,
|
|
23
|
+
disabled = false,
|
|
24
|
+
className,
|
|
25
|
+
description,
|
|
26
|
+
}: DisclosureGroupProps) {
|
|
27
|
+
const id = useId()
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<div className={cn("min-w-0", className)}>
|
|
31
|
+
<h3 className="m-0">
|
|
32
|
+
<button
|
|
33
|
+
type="button"
|
|
34
|
+
id={`${id}-trigger`}
|
|
35
|
+
aria-expanded={open}
|
|
36
|
+
aria-controls={id}
|
|
37
|
+
disabled={disabled}
|
|
38
|
+
onClick={() => onOpenChange(!open)}
|
|
39
|
+
className={cn(
|
|
40
|
+
"flex min-h-11 w-full items-center justify-between gap-3 rounded-xl px-3 py-2 text-start",
|
|
41
|
+
"text-subheadline text-label hover:bg-fill/60 focus-visible:outline-2 focus-visible:outline-offset-2",
|
|
42
|
+
"focus-visible:outline-accent-text disabled:cursor-not-allowed disabled:opacity-40"
|
|
43
|
+
)}
|
|
44
|
+
>
|
|
45
|
+
<span className="flex min-w-0 flex-col gap-0.5">
|
|
46
|
+
<span className="font-semibold">{label}</span>
|
|
47
|
+
{description && (
|
|
48
|
+
<span className="text-footnote font-normal text-label-secondary">
|
|
49
|
+
{description}
|
|
50
|
+
</span>
|
|
51
|
+
)}
|
|
52
|
+
</span>
|
|
53
|
+
<ChevronDownIcon
|
|
54
|
+
size={17}
|
|
55
|
+
aria-hidden="true"
|
|
56
|
+
className={cn(
|
|
57
|
+
"shrink-0 text-label-tertiary transition-transform duration-normal motion-reduce:transition-none",
|
|
58
|
+
open && "rotate-180"
|
|
59
|
+
)}
|
|
60
|
+
/>
|
|
61
|
+
</button>
|
|
62
|
+
</h3>
|
|
63
|
+
<section id={id} aria-labelledby={`${id}-trigger`}>
|
|
64
|
+
<InlineDisclosure open={open}>
|
|
65
|
+
<div className="px-3 pb-3">{children}</div>
|
|
66
|
+
</InlineDisclosure>
|
|
67
|
+
</section>
|
|
68
|
+
</div>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -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}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { forwardRef, type ReactNode, useRef, useSyncExternalStore } from "react"
|
|
2
|
+
import { Button, type ButtonProps } from "../button/button"
|
|
3
|
+
import {
|
|
4
|
+
closeContextMenu,
|
|
5
|
+
getContextMenu,
|
|
6
|
+
openMenu,
|
|
7
|
+
subscribeContextMenu,
|
|
8
|
+
type ContextMenuEdge,
|
|
9
|
+
type ContextMenuItem,
|
|
10
|
+
} from "../context-menu/context-menu-store"
|
|
11
|
+
|
|
12
|
+
export interface MenuProps extends Omit<ButtonProps, "onClick" | "children"> {
|
|
13
|
+
/** Accessible name for the menu trigger. */
|
|
14
|
+
label: string
|
|
15
|
+
/** Items are rendered by the app's existing ContextMenuHost. */
|
|
16
|
+
items: readonly ContextMenuItem[]
|
|
17
|
+
children: ReactNode
|
|
18
|
+
/** Logical edge used to align the menu, including RTL. @default "leading" */
|
|
19
|
+
edge?: ContextMenuEdge
|
|
20
|
+
/** Open above the trigger instead of below it. @default false */
|
|
21
|
+
above?: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** A declarative menu button using the same native host as context menus. */
|
|
25
|
+
export const Menu = forwardRef<HTMLButtonElement, MenuProps>(function Menu(
|
|
26
|
+
{ label, items, children, edge = "leading", above = false, disabled, ...props },
|
|
27
|
+
forwardedRef
|
|
28
|
+
) {
|
|
29
|
+
const trigger = useRef<HTMLButtonElement>(null)
|
|
30
|
+
const current = useSyncExternalStore(subscribeContextMenu, getContextMenu, () => null)
|
|
31
|
+
const expanded = Boolean(current && current.anchor === trigger.current)
|
|
32
|
+
|
|
33
|
+
const toggle = () => {
|
|
34
|
+
if (!trigger.current || disabled) return
|
|
35
|
+
if (expanded) closeContextMenu(false)
|
|
36
|
+
else openMenu(trigger.current, [...items], { edge, above })
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Button
|
|
41
|
+
{...props}
|
|
42
|
+
ref={(node) => {
|
|
43
|
+
trigger.current = node
|
|
44
|
+
if (typeof forwardedRef === "function") forwardedRef(node)
|
|
45
|
+
else if (forwardedRef) forwardedRef.current = node
|
|
46
|
+
}}
|
|
47
|
+
type="button"
|
|
48
|
+
aria-label={label}
|
|
49
|
+
aria-haspopup="menu"
|
|
50
|
+
aria-expanded={expanded}
|
|
51
|
+
disabled={disabled}
|
|
52
|
+
onClick={toggle}
|
|
53
|
+
onKeyDown={(event) => {
|
|
54
|
+
props.onKeyDown?.(event)
|
|
55
|
+
if (event.defaultPrevented) return
|
|
56
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
57
|
+
event.preventDefault()
|
|
58
|
+
if (!expanded) toggle()
|
|
59
|
+
} else if (event.key === "Escape" && expanded) {
|
|
60
|
+
event.preventDefault()
|
|
61
|
+
closeContextMenu()
|
|
62
|
+
}
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
{children}
|
|
66
|
+
</Button>
|
|
67
|
+
)
|
|
68
|
+
})
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { cn } from "../../lib/class-names"
|
|
2
|
+
|
|
3
|
+
/** Shared field treatment for the popup-based Picker, date and time controls. */
|
|
4
|
+
export function pickerTriggerStyle(className?: string) {
|
|
5
|
+
return cn(
|
|
6
|
+
"flex w-full min-w-0 items-center gap-2 rounded-lg control-field px-3 py-2 text-start text-subheadline text-label",
|
|
7
|
+
"disabled:cursor-not-allowed disabled:opacity-40",
|
|
8
|
+
className
|
|
9
|
+
)
|
|
10
|
+
}
|