@passui/react 0.1.46 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -109
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/dist/accordion.d.ts +15 -0
- package/dist/accordion.js +93 -0
- package/dist/alert-dialog.d.ts +26 -0
- package/dist/alert-dialog.js +142 -0
- package/dist/alert.d.ts +10 -0
- package/dist/alert.js +28 -0
- package/dist/{types/src/components/ambient/ambient.d.ts → ambient.d.ts} +4 -4
- package/dist/ambient.js +22 -0
- package/dist/{types/src/appearance → appearance}/platform.d.ts +3 -3
- package/dist/appearance/platform.js +43 -0
- package/dist/appearance/theme.d.ts +71 -0
- package/dist/appearance/theme.js +236 -0
- package/dist/appearance.d.ts +3 -0
- package/dist/appearance.js +3 -0
- package/dist/{types/src/components/aspect-ratio/aspect-ratio.d.ts → aspect-ratio.d.ts} +4 -4
- package/dist/aspect-ratio.js +17 -0
- package/dist/avatar.d.ts +5 -0
- package/dist/avatar.js +43 -0
- package/dist/badge.d.ts +8 -0
- package/dist/badge.js +21 -0
- package/dist/breadcrumb.d.ts +13 -0
- package/dist/breadcrumb.js +63 -0
- package/dist/button-group.d.ts +5 -0
- package/dist/button-group.js +14 -0
- package/dist/button.d.ts +21 -0
- package/dist/button.js +58 -0
- package/dist/calendar.d.ts +35 -0
- package/dist/calendar.js +225 -0
- package/dist/card.d.ts +9 -0
- package/dist/card.js +54 -0
- package/dist/chart.d.ts +30 -0
- package/dist/chart.js +226 -0
- package/dist/checkbox.d.ts +13 -0
- package/dist/checkbox.js +53 -0
- package/dist/{types/src/lib/clipboard.d.ts → clipboard.d.ts} +1 -1
- package/dist/clipboard.js +16 -0
- package/dist/cn.d.ts +2 -0
- package/dist/cn.js +10 -0
- package/dist/code-block.d.ts +34 -0
- package/dist/code-block.js +87 -0
- package/dist/collapsible.d.ts +13 -0
- package/dist/collapsible.js +49 -0
- package/dist/combobox.d.ts +25 -0
- package/dist/combobox.js +112 -0
- package/dist/command.d.ts +22 -0
- package/dist/command.js +129 -0
- package/dist/components/toast/toast-store.d.ts +60 -0
- package/dist/components/toast/toast-store.js +96 -0
- package/dist/{types/src/components → components}/toast/toaster.d.ts +4 -4
- package/dist/components/toast/toaster.js +345 -0
- package/dist/context-menu.d.ts +2 -0
- package/dist/context-menu.js +2 -0
- package/dist/conversation.d.ts +48 -0
- package/dist/conversation.js +202 -0
- package/dist/date-time-picker.d.ts +50 -0
- package/dist/date-time-picker.js +235 -0
- package/dist/date.d.ts +50 -0
- package/dist/date.js +77 -0
- package/dist/dialog.d.ts +21 -0
- package/dist/dialog.js +113 -0
- package/dist/drawer.d.ts +30 -0
- package/dist/drawer.js +140 -0
- package/dist/dropdown-menu.d.ts +56 -0
- package/dist/dropdown-menu.js +295 -0
- package/dist/empty.d.ts +11 -0
- package/dist/empty.js +51 -0
- package/dist/field.d.ts +16 -0
- package/dist/field.js +47 -0
- package/{src/hooks/scroll/minimize-decision.ts → dist/hooks/scroll/minimize-decision.js} +3 -5
- package/dist/{types/src/hooks → hooks}/use-anchored-placement.d.ts +2 -2
- package/dist/hooks/use-anchored-placement.js +33 -0
- package/dist/{types/src/hooks → hooks}/use-minimize-on-scroll.d.ts +1 -1
- package/dist/hooks/use-minimize-on-scroll.js +59 -0
- package/dist/{types/src/hooks → hooks}/use-visual-viewport.d.ts +2 -2
- package/{src/hooks/use-visual-viewport.ts → dist/hooks/use-visual-viewport.js} +20 -35
- package/dist/hooks/viewport/types.d.ts +7 -0
- package/dist/hooks/viewport/viewport-metrics.js +13 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.js +80 -0
- package/dist/input-group.d.ts +17 -0
- package/dist/input-group.js +55 -0
- package/dist/input-otp.d.ts +13 -0
- package/dist/input-otp.js +36 -0
- package/dist/input.d.ts +4 -0
- package/dist/input.js +14 -0
- package/dist/item.d.ts +49 -0
- package/dist/item.js +142 -0
- package/dist/kbd.d.ts +4 -0
- package/dist/kbd.js +86 -0
- package/dist/label.d.ts +3 -0
- package/dist/label.js +12 -0
- package/dist/labeled-content.d.ts +24 -0
- package/dist/labeled-content.js +41 -0
- package/dist/{types/src/lib/language.d.ts → language.d.ts} +1 -1
- package/dist/language.js +11 -0
- package/dist/layout.d.ts +24 -0
- package/dist/layout.js +36 -0
- package/dist/{types/src/lib → lib}/anchored-placement.d.ts +27 -27
- package/dist/lib/anchored-placement.js +42 -0
- package/dist/lib/calendar-month.js +90 -0
- package/dist/lib/cx.js +6 -0
- package/dist/lib/drawer.math.js +29 -0
- package/dist/lib/floating-layers.d.ts +3 -0
- package/dist/lib/floating-layers.js +25 -0
- package/dist/{types/src/lib → lib}/haptics.d.ts +1 -1
- package/dist/lib/haptics.js +13 -0
- package/dist/lib/liquid-step.js +33 -0
- package/dist/lib/page-scale.js +58 -0
- package/dist/lib/portal.js +12 -0
- package/dist/lib/presence.js +53 -0
- package/dist/lib/range-value.js +25 -0
- package/dist/lib/render.d.ts +8 -0
- package/dist/lib/render.js +42 -0
- package/dist/lib/rolling-digit.js +83 -0
- package/dist/{types/src/lib → lib}/screen-edges.d.ts +5 -5
- package/dist/lib/screen-edges.js +30 -0
- package/dist/lib/swipe-touch-action.js +34 -0
- package/dist/lib/visual-viewport.js +27 -0
- package/dist/lib/water-drop.js +412 -0
- package/dist/lib/wheel.js +125 -0
- package/dist/list.d.ts +26 -0
- package/dist/list.js +80 -0
- package/dist/locales.d.ts +18 -0
- package/dist/locales.js +36 -0
- package/dist/marker.d.ts +13 -0
- package/dist/marker.js +33 -0
- package/dist/motion/transitions.d.ts +170 -0
- package/dist/motion/transitions.js +156 -0
- package/dist/pagination.d.ts +30 -0
- package/dist/pagination.js +117 -0
- package/dist/popover.d.ts +26 -0
- package/dist/popover.js +101 -0
- package/dist/progress.d.ts +9 -0
- package/dist/progress.js +24 -0
- package/dist/questionnaire.d.ts +46 -0
- package/dist/questionnaire.js +133 -0
- package/dist/radio-group.d.ts +21 -0
- package/dist/radio-group.js +67 -0
- package/dist/search-field.d.ts +18 -0
- package/dist/search-field.js +45 -0
- package/dist/segmented-control.d.ts +16 -0
- package/dist/segmented-control.js +25 -0
- package/dist/select.d.ts +24 -0
- package/dist/select.js +107 -0
- package/dist/separator.d.ts +9 -0
- package/dist/separator.js +17 -0
- package/dist/{types/src/lib/shapes.d.ts → shapes.d.ts} +2 -2
- package/dist/shapes.js +65 -0
- package/dist/sheet.d.ts +24 -0
- package/dist/sheet.js +141 -0
- package/dist/sidebar.d.ts +32 -0
- package/dist/sidebar.js +85 -0
- package/dist/skeleton.d.ts +3 -0
- package/dist/skeleton.js +13 -0
- package/dist/slider.d.ts +9 -0
- package/dist/slider.js +42 -0
- package/dist/slosh-slider.d.ts +21 -0
- package/dist/slosh-slider.js +205 -0
- package/dist/spinner.d.ts +3 -0
- package/dist/spinner.js +20 -0
- package/dist/stat-tile.d.ts +20 -0
- package/dist/stat-tile.js +53 -0
- package/dist/stepper.d.ts +22 -0
- package/dist/stepper.js +98 -0
- package/dist/swatch-picker.d.ts +22 -0
- package/dist/swatch-picker.js +70 -0
- package/dist/switch.d.ts +10 -0
- package/dist/switch.js +44 -0
- package/dist/tab-bar.d.ts +15 -0
- package/dist/tab-bar.js +34 -0
- package/dist/{types/src/components/table/table.d.ts → table.d.ts} +3 -3
- package/dist/table.js +93 -0
- package/dist/tabs.d.ts +32 -0
- package/dist/tabs.js +131 -0
- package/dist/text.d.ts +25 -0
- package/dist/text.js +44 -0
- package/dist/textarea.d.ts +3 -0
- package/dist/textarea.js +13 -0
- package/dist/toast.d.ts +3 -0
- package/dist/toast.js +3 -0
- package/dist/toggle-group.d.ts +20 -0
- package/dist/toggle-group.js +68 -0
- package/dist/toggle.d.ts +24 -0
- package/dist/toggle.js +37 -0
- package/dist/tokens.d.ts +1 -0
- package/dist/tooltip.d.ts +21 -0
- package/dist/tooltip.js +61 -0
- package/dist/trace.d.ts +14 -0
- package/dist/trace.js +54 -0
- package/dist/{types/src/hooks/use-dismiss.d.ts → use-dismiss.d.ts} +3 -3
- package/dist/use-dismiss.js +38 -0
- package/dist/{types/src/hooks/use-media-query.d.ts → use-media-query.d.ts} +12 -12
- package/dist/use-media-query.js +56 -0
- package/dist/use-os.d.ts +12 -0
- package/dist/use-os.js +17 -0
- package/dist/wake-slider.d.ts +15 -0
- package/dist/wake-slider.js +174 -0
- package/package.json +122 -253
- package/src/styles/code-block.css +4 -0
- package/src/styles/globals.css +5 -0
- package/src/styles/motion-controls.css +10 -0
- package/src/styles/page-scale.css +27 -0
- package/src/styles/styles.css +4 -2
- package/dist/types/src/appearance/index.d.ts +0 -2
- package/dist/types/src/appearance/theme.d.ts +0 -71
- package/dist/types/src/components/accordion/accordion.d.ts +0 -23
- package/dist/types/src/components/ambient/index.d.ts +0 -1
- package/dist/types/src/components/breadcrumb/breadcrumb.d.ts +0 -19
- package/dist/types/src/components/button/button-styles.d.ts +0 -12
- package/dist/types/src/components/button/button.d.ts +0 -32
- package/dist/types/src/components/button/icon-button.d.ts +0 -10
- package/dist/types/src/components/button/pending-spinner.d.ts +0 -5
- package/dist/types/src/components/button/use-pending-indicator.d.ts +0 -2
- package/dist/types/src/components/chip/chip.d.ts +0 -10
- package/dist/types/src/components/code-block/code-block.d.ts +0 -13
- package/dist/types/src/components/combo-box/combo-box.d.ts +0 -9
- package/dist/types/src/components/command/command.d.ts +0 -18
- package/dist/types/src/components/compact-date-picker/calendar-month.d.ts +0 -25
- package/dist/types/src/components/compact-date-picker/compact-date-picker.d.ts +0 -30
- package/dist/types/src/components/compact-time-picker/compact-time-picker.d.ts +0 -29
- package/dist/types/src/components/compact-time-picker/time-value.d.ts +0 -18
- package/dist/types/src/components/content-unavailable-view/content-unavailable-view.d.ts +0 -12
- package/dist/types/src/components/content-view/content-view.d.ts +0 -51
- package/dist/types/src/components/content-view/index.d.ts +0 -1
- package/dist/types/src/components/context-menu/conceal-menu-source.d.ts +0 -2
- package/dist/types/src/components/context-menu/context-menu-host.d.ts +0 -2
- package/dist/types/src/components/context-menu/context-menu-store.d.ts +0 -62
- package/dist/types/src/components/context-menu/menu-navigation.d.ts +0 -6
- package/dist/types/src/components/context-menu/menu-position.d.ts +0 -21
- package/dist/types/src/components/context-menu/menu-reveal.d.ts +0 -26
- package/dist/types/src/components/context-menu/use-context-menu.d.ts +0 -14
- package/dist/types/src/components/conversation/conversation.d.ts +0 -48
- package/dist/types/src/components/conversation/index.d.ts +0 -1
- package/dist/types/src/components/date-picker/date-picker.d.ts +0 -19
- package/dist/types/src/components/date-picker/date-value.d.ts +0 -2
- package/dist/types/src/components/dialog/dialog-host.d.ts +0 -6
- package/dist/types/src/components/dialog/dialog-store.d.ts +0 -23
- package/dist/types/src/components/dialog/dialog.d.ts +0 -33
- package/dist/types/src/components/dialog/index.d.ts +0 -1
- package/dist/types/src/components/disclosure-group/disclosure-group.d.ts +0 -18
- package/dist/types/src/components/divider/divider.d.ts +0 -9
- package/dist/types/src/components/inline-disclosure/inline-disclosure.d.ts +0 -15
- package/dist/types/src/components/keyboard-shortcut/keyboard-shortcut.d.ts +0 -8
- package/dist/types/src/components/labeled-content/labeled-content.d.ts +0 -22
- package/dist/types/src/components/locale-switcher/index.d.ts +0 -1
- package/dist/types/src/components/locale-switcher/locale-switcher.d.ts +0 -13
- package/dist/types/src/components/menu/menu.d.ts +0 -16
- package/dist/types/src/components/morph/index.d.ts +0 -2
- package/dist/types/src/components/morph/morph.d.ts +0 -32
- package/dist/types/src/components/morph/use-morph-disclosure.d.ts +0 -13
- package/dist/types/src/components/one-time-code/one-time-code.d.ts +0 -26
- package/dist/types/src/components/picker/picker-trigger.d.ts +0 -3
- package/dist/types/src/components/picker/picker.d.ts +0 -46
- package/dist/types/src/components/popover/anchored-surface.d.ts +0 -17
- package/dist/types/src/components/popover/index.d.ts +0 -41
- package/dist/types/src/components/popover/popover-content.d.ts +0 -32
- package/dist/types/src/components/popover/popover-fit.d.ts +0 -21
- package/dist/types/src/components/popover/popover-root.d.ts +0 -22
- package/dist/types/src/components/popover/popover-trigger.d.ts +0 -23
- package/dist/types/src/components/profile-image/profile-image.d.ts +0 -9
- package/dist/types/src/components/progress-view/progress-view.d.ts +0 -13
- package/dist/types/src/components/progress-view/use-liquid-progress.d.ts +0 -3
- package/dist/types/src/components/radio-group/radio-group.d.ts +0 -20
- package/dist/types/src/components/search-field/expanding-search-field.d.ts +0 -5
- package/dist/types/src/components/search-field/search-field.d.ts +0 -9
- package/dist/types/src/components/search-list/search-list.d.ts +0 -22
- package/dist/types/src/components/section/section.d.ts +0 -18
- package/dist/types/src/components/secure-field/secure-field.d.ts +0 -4
- package/dist/types/src/components/segmented-control/segmented-control.d.ts +0 -25
- package/dist/types/src/components/sheet/modal-environment.d.ts +0 -2
- package/dist/types/src/components/sheet/sheet-portal.d.ts +0 -5
- package/dist/types/src/components/sheet/sheet.d.ts +0 -26
- package/dist/types/src/components/sheet/use-sheet-focus.d.ts +0 -3
- package/dist/types/src/components/sidebar/sidebar.d.ts +0 -24
- package/dist/types/src/components/skeleton/skeleton.d.ts +0 -9
- package/dist/types/src/components/slider/slider.d.ts +0 -17
- package/dist/types/src/components/slosh-slider/liquid-step.d.ts +0 -6
- package/dist/types/src/components/slosh-slider/slosh-slider.d.ts +0 -21
- package/dist/types/src/components/stat-tile/index.d.ts +0 -1
- package/dist/types/src/components/stat-tile/stat-tile.d.ts +0 -20
- package/dist/types/src/components/status-indicator/status-indicator.d.ts +0 -17
- package/dist/types/src/components/stepper/rolling-digit.d.ts +0 -11
- package/dist/types/src/components/stepper/stepper.d.ts +0 -22
- package/dist/types/src/components/swatch-picker/swatch-picker.d.ts +0 -22
- package/dist/types/src/components/tab-bar/tab-bar.d.ts +0 -43
- package/dist/types/src/components/tab-view/tab-view.d.ts +0 -27
- package/dist/types/src/components/text-editor/text-editor.d.ts +0 -9
- package/dist/types/src/components/text-field/text-field.d.ts +0 -33
- package/dist/types/src/components/toast/toast-store.d.ts +0 -52
- package/dist/types/src/components/toggle/toggle.d.ts +0 -22
- package/dist/types/src/components/tooltip/tooltip-host.d.ts +0 -7
- package/dist/types/src/components/view-controller/index.d.ts +0 -1
- package/dist/types/src/components/view-controller/view-controller.d.ts +0 -21
- package/dist/types/src/components/wake-slider/wake-slider.d.ts +0 -15
- package/dist/types/src/hooks/scroll/minimize-decision.d.ts +0 -2
- package/dist/types/src/hooks/use-anchored-disclosure.d.ts +0 -9
- package/dist/types/src/hooks/use-floating-dismiss.d.ts +0 -3
- package/dist/types/src/hooks/viewport/types.d.ts +0 -19
- package/dist/types/src/hooks/viewport/viewport-metrics.d.ts +0 -3
- package/dist/types/src/icons/icons.d.ts +0 -616
- package/dist/types/src/index.d.ts +0 -73
- package/dist/types/src/lib/class-names.d.ts +0 -2
- package/dist/types/src/lib/date.d.ts +0 -50
- package/dist/types/src/lib/floating-layers.d.ts +0 -8
- package/dist/types/src/lib/range-value.d.ts +0 -4
- package/dist/types/src/machines/popover.machine.d.ts +0 -30
- package/dist/types/src/motion/transitions.d.ts +0 -170
- package/src/appearance/index.ts +0 -2
- package/src/appearance/platform.tsx +0 -102
- package/src/appearance/theme.tsx +0 -467
- package/src/components/accordion/accordion.tsx +0 -70
- package/src/components/ambient/ambient.tsx +0 -35
- package/src/components/ambient/index.ts +0 -1
- package/src/components/aspect-ratio/aspect-ratio.tsx +0 -27
- package/src/components/breadcrumb/breadcrumb.tsx +0 -73
- package/src/components/button/button-styles.ts +0 -49
- package/src/components/button/button.tsx +0 -107
- package/src/components/button/icon-button.tsx +0 -33
- package/src/components/button/pending-spinner.tsx +0 -14
- package/src/components/button/use-pending-indicator.ts +0 -22
- package/src/components/chip/chip.tsx +0 -45
- package/src/components/code-block/code-block.tsx +0 -48
- package/src/components/combo-box/combo-box.tsx +0 -13
- package/src/components/command/command.tsx +0 -149
- package/src/components/compact-date-picker/calendar-month.ts +0 -109
- package/src/components/compact-date-picker/compact-date-picker.tsx +0 -337
- package/src/components/compact-time-picker/compact-time-picker.tsx +0 -321
- package/src/components/compact-time-picker/time-value.ts +0 -58
- package/src/components/content-unavailable-view/content-unavailable-view.tsx +0 -78
- package/src/components/content-view/content-view.tsx +0 -215
- package/src/components/content-view/index.ts +0 -1
- package/src/components/context-menu/conceal-menu-source.ts +0 -30
- package/src/components/context-menu/context-menu-host.tsx +0 -459
- package/src/components/context-menu/context-menu-store.ts +0 -167
- package/src/components/context-menu/menu-navigation.ts +0 -36
- package/src/components/context-menu/menu-position.ts +0 -38
- package/src/components/context-menu/menu-reveal.ts +0 -42
- package/src/components/context-menu/use-context-menu.ts +0 -73
- package/src/components/conversation/conversation.tsx +0 -309
- package/src/components/conversation/index.ts +0 -1
- package/src/components/date-picker/date-picker.tsx +0 -106
- package/src/components/date-picker/date-value.ts +0 -22
- package/src/components/dialog/dialog-host.tsx +0 -119
- package/src/components/dialog/dialog-store.ts +0 -66
- package/src/components/dialog/dialog.tsx +0 -211
- package/src/components/dialog/index.ts +0 -1
- package/src/components/disclosure-group/disclosure-group.tsx +0 -108
- package/src/components/divider/divider.tsx +0 -33
- package/src/components/inline-disclosure/inline-disclosure.tsx +0 -53
- package/src/components/keyboard-shortcut/keyboard-shortcut.tsx +0 -32
- package/src/components/labeled-content/labeled-content.tsx +0 -84
- package/src/components/locale-switcher/index.ts +0 -1
- package/src/components/locale-switcher/locale-switcher.tsx +0 -311
- package/src/components/menu/menu.tsx +0 -85
- package/src/components/morph/index.ts +0 -2
- package/src/components/morph/morph.tsx +0 -258
- package/src/components/morph/use-morph-disclosure.ts +0 -27
- package/src/components/one-time-code/one-time-code.tsx +0 -234
- package/src/components/picker/picker-trigger.ts +0 -22
- package/src/components/picker/picker.tsx +0 -404
- package/src/components/popover/anchored-surface.tsx +0 -264
- package/src/components/popover/index.ts +0 -50
- package/src/components/popover/popover-content.tsx +0 -334
- package/src/components/popover/popover-fit.ts +0 -74
- package/src/components/popover/popover-root.tsx +0 -97
- package/src/components/popover/popover-trigger.tsx +0 -71
- package/src/components/profile-image/profile-image.tsx +0 -96
- package/src/components/progress-view/progress-view.tsx +0 -72
- package/src/components/progress-view/use-liquid-progress.ts +0 -43
- package/src/components/radio-group/radio-group.tsx +0 -86
- package/src/components/search-field/expanding-search-field.tsx +0 -197
- package/src/components/search-field/search-field.tsx +0 -66
- package/src/components/search-list/search-list.tsx +0 -276
- package/src/components/section/section.tsx +0 -75
- package/src/components/secure-field/secure-field.tsx +0 -8
- package/src/components/segmented-control/segmented-control.tsx +0 -157
- package/src/components/sheet/modal-environment.ts +0 -82
- package/src/components/sheet/sheet-portal.tsx +0 -62
- package/src/components/sheet/sheet.tsx +0 -165
- package/src/components/sheet/use-sheet-focus.ts +0 -109
- package/src/components/sidebar/sidebar.tsx +0 -102
- package/src/components/skeleton/skeleton.tsx +0 -38
- package/src/components/slider/slider.tsx +0 -134
- package/src/components/slosh-slider/liquid-step.ts +0 -43
- package/src/components/slosh-slider/slosh-slider.tsx +0 -294
- package/src/components/stat-tile/index.ts +0 -1
- package/src/components/stat-tile/stat-tile.tsx +0 -90
- package/src/components/status-indicator/status-indicator.tsx +0 -54
- package/src/components/stepper/rolling-digit.tsx +0 -91
- package/src/components/stepper/stepper.tsx +0 -136
- package/src/components/swatch-picker/swatch-picker.tsx +0 -138
- package/src/components/tab-bar/tab-bar.tsx +0 -182
- package/src/components/tab-view/tab-view.tsx +0 -155
- package/src/components/table/table.tsx +0 -151
- package/src/components/text-editor/text-editor.tsx +0 -42
- package/src/components/text-field/text-field.tsx +0 -200
- package/src/components/toast/toast-store.ts +0 -164
- package/src/components/toast/toaster.tsx +0 -407
- package/src/components/toggle/toggle.tsx +0 -320
- package/src/components/tooltip/tooltip-host.tsx +0 -178
- package/src/components/view-controller/index.ts +0 -1
- package/src/components/view-controller/view-controller.tsx +0 -75
- package/src/components/wake-slider/wake-slider.tsx +0 -260
- package/src/hooks/use-anchored-disclosure.ts +0 -23
- package/src/hooks/use-anchored-placement.ts +0 -40
- package/src/hooks/use-dismiss.ts +0 -44
- package/src/hooks/use-floating-dismiss.ts +0 -30
- package/src/hooks/use-media-query.ts +0 -94
- package/src/hooks/use-minimize-on-scroll.ts +0 -77
- package/src/hooks/viewport/types.ts +0 -19
- package/src/hooks/viewport/viewport-metrics.ts +0 -19
- package/src/icons/icons.tsx +0 -458
- package/src/index.ts +0 -107
- package/src/lib/anchored-placement.ts +0 -91
- package/src/lib/class-names.ts +0 -21
- package/src/lib/clipboard.ts +0 -15
- package/src/lib/date.ts +0 -86
- package/src/lib/floating-layers.ts +0 -53
- package/src/lib/haptics.ts +0 -23
- package/src/lib/language.ts +0 -16
- package/src/lib/range-value.ts +0 -38
- package/src/lib/screen-edges.ts +0 -44
- package/src/lib/shapes.ts +0 -59
- package/src/machines/popover.machine.ts +0 -51
- package/src/motion/transitions.ts +0 -97
- package/src/tokens.ts +0 -1
- /package/dist/{types/src/tokens.d.ts → tokens.js} +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface QuestionOption {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
interface QuestionBase {
|
|
7
|
+
id: string;
|
|
8
|
+
title: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
/** Lets the person move on without answering. @default false */
|
|
11
|
+
optional?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export type Question = (QuestionBase & {
|
|
14
|
+
type: "single";
|
|
15
|
+
options: QuestionOption[];
|
|
16
|
+
}) | (QuestionBase & {
|
|
17
|
+
type: "multiple";
|
|
18
|
+
options: QuestionOption[];
|
|
19
|
+
}) | (QuestionBase & {
|
|
20
|
+
type: "text";
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
});
|
|
23
|
+
/** A single choice is a string, many choices an array, freeform text a string. */
|
|
24
|
+
export type Answers = Record<string, string | string[]>;
|
|
25
|
+
export interface QuestionnaireProps {
|
|
26
|
+
questions: Question[];
|
|
27
|
+
/** Called with every answer after the last step. */
|
|
28
|
+
onComplete: (answers: Answers) => void;
|
|
29
|
+
/** Every string the questionnaire shows, so apps translate them. */
|
|
30
|
+
labels: {
|
|
31
|
+
next: string;
|
|
32
|
+
back: string;
|
|
33
|
+
skip: string;
|
|
34
|
+
finish: string;
|
|
35
|
+
/** Names the step, for example "Question 2 of 5". */
|
|
36
|
+
step: (current: number, total: number) => string;
|
|
37
|
+
};
|
|
38
|
+
className?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A multi-step questionnaire: one question at a time, with single choice,
|
|
42
|
+
* multiple choice, freeform and skippable questions, a way back, and a
|
|
43
|
+
* progress bar. Answers are plain values, collected on the last step.
|
|
44
|
+
*/
|
|
45
|
+
export declare function Questionnaire({ questions, onComplete, labels, className }: QuestionnaireProps): import("react").JSX.Element | null;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "./lib/cx.js";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
|
+
import { useId, useState } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
// src/components/questionnaire.tsx
|
|
7
|
+
const card = "has-[:checked]:bg-accent-soft has-[:checked]:shadow-[inset_0_0_0_1.5px_var(--color-accent)] has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-accent/70 flex cursor-pointer items-start gap-3 rounded-2xl bg-fill/60 p-3 text-footnote transition spring-snappy active:scale-[0.99] motion-reduce:transition-none";
|
|
8
|
+
/**
|
|
9
|
+
* A multi-step questionnaire: one question at a time, with single choice,
|
|
10
|
+
* multiple choice, freeform and skippable questions, a way back, and a
|
|
11
|
+
* progress bar. Answers are plain values, collected on the last step.
|
|
12
|
+
*/
|
|
13
|
+
function Questionnaire({ questions, onComplete, labels, className }) {
|
|
14
|
+
const [index, setIndex] = useState(0);
|
|
15
|
+
const [answers, setAnswers] = useState({});
|
|
16
|
+
const name = useId();
|
|
17
|
+
const question = questions[index];
|
|
18
|
+
if (!question) return null;
|
|
19
|
+
const last = index === questions.length - 1;
|
|
20
|
+
const value = answers[question.id];
|
|
21
|
+
const answered = Array.isArray(value) ? value.length > 0 : !!value?.trim();
|
|
22
|
+
const set = (next) => setAnswers((current) => ({
|
|
23
|
+
...current,
|
|
24
|
+
[question.id]: next
|
|
25
|
+
}));
|
|
26
|
+
const advance = (final) => {
|
|
27
|
+
if (last) onComplete(final);
|
|
28
|
+
else setIndex(index + 1);
|
|
29
|
+
};
|
|
30
|
+
const submit = (event) => {
|
|
31
|
+
event.preventDefault();
|
|
32
|
+
advance(answers);
|
|
33
|
+
};
|
|
34
|
+
const skip = () => {
|
|
35
|
+
const { [question.id]: _skipped, ...rest } = answers;
|
|
36
|
+
setAnswers(rest);
|
|
37
|
+
advance(rest);
|
|
38
|
+
};
|
|
39
|
+
return /* @__PURE__ */ jsxs("form", {
|
|
40
|
+
onSubmit: submit,
|
|
41
|
+
"data-slot": "questionnaire",
|
|
42
|
+
className: cx("flex w-full max-w-md flex-col gap-5", className),
|
|
43
|
+
children: [
|
|
44
|
+
/* @__PURE__ */ jsxs("div", {
|
|
45
|
+
className: "flex flex-col gap-2",
|
|
46
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
47
|
+
role: "progressbar",
|
|
48
|
+
"aria-label": labels.step(index + 1, questions.length),
|
|
49
|
+
"aria-valuemin": 1,
|
|
50
|
+
"aria-valuemax": questions.length,
|
|
51
|
+
"aria-valuenow": index + 1,
|
|
52
|
+
className: "bg-fill h-1.5 w-full overflow-hidden rounded-full",
|
|
53
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
54
|
+
className: "bg-accent spring-smooth h-full rounded-full transition-[width] motion-reduce:transition-none",
|
|
55
|
+
style: { width: `${(index + 1) / questions.length * 100}%` }
|
|
56
|
+
})
|
|
57
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
58
|
+
className: "text-caption text-label-tertiary m-0",
|
|
59
|
+
children: labels.step(index + 1, questions.length)
|
|
60
|
+
})]
|
|
61
|
+
}),
|
|
62
|
+
/* @__PURE__ */ jsxs("fieldset", {
|
|
63
|
+
className: "m-0 flex min-w-0 animate-[passui-step-in_var(--spring-smooth-duration)_var(--spring-smooth)] flex-col gap-3 border-0 p-0 motion-reduce:animate-none",
|
|
64
|
+
children: [
|
|
65
|
+
/* @__PURE__ */ jsx("legend", {
|
|
66
|
+
className: "text-headline text-label p-0 font-semibold",
|
|
67
|
+
children: question.title
|
|
68
|
+
}),
|
|
69
|
+
question.description ? /* @__PURE__ */ jsx("p", {
|
|
70
|
+
className: "text-footnote text-label-secondary m-0",
|
|
71
|
+
children: question.description
|
|
72
|
+
}) : null,
|
|
73
|
+
question.type === "text" ? /* @__PURE__ */ jsx("textarea", {
|
|
74
|
+
"aria-label": question.title,
|
|
75
|
+
placeholder: question.placeholder,
|
|
76
|
+
value: typeof value === "string" ? value : "",
|
|
77
|
+
onChange: (event) => set(event.target.value),
|
|
78
|
+
className: "control-field text-footnote text-label field-sizing-content min-h-20 w-full resize-none rounded-xl px-3 py-2 outline-none"
|
|
79
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
80
|
+
className: "flex flex-col gap-2",
|
|
81
|
+
children: question.options.map((option) => {
|
|
82
|
+
const multiple = question.type === "multiple";
|
|
83
|
+
const picked = Array.isArray(value) ? value : [];
|
|
84
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
85
|
+
className: card,
|
|
86
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
87
|
+
type: multiple ? "checkbox" : "radio",
|
|
88
|
+
name: `${name}-${question.id}`,
|
|
89
|
+
value: option.value,
|
|
90
|
+
checked: multiple ? picked.includes(option.value) : value === option.value,
|
|
91
|
+
onChange: () => set(multiple ? picked.includes(option.value) ? picked.filter((item) => item !== option.value) : [...picked, option.value] : option.value),
|
|
92
|
+
className: "accent-accent mt-0.5 size-4 shrink-0"
|
|
93
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
94
|
+
className: "flex min-w-0 flex-col",
|
|
95
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
96
|
+
className: "text-label font-medium",
|
|
97
|
+
children: option.label
|
|
98
|
+
}), option.description ? /* @__PURE__ */ jsx("span", {
|
|
99
|
+
className: "text-caption text-label-secondary",
|
|
100
|
+
children: option.description
|
|
101
|
+
}) : null]
|
|
102
|
+
})]
|
|
103
|
+
}, option.value);
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
]
|
|
107
|
+
}, question.id),
|
|
108
|
+
/* @__PURE__ */ jsxs("div", {
|
|
109
|
+
className: "flex items-center justify-between gap-2",
|
|
110
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
111
|
+
type: "button",
|
|
112
|
+
variant: "ghost",
|
|
113
|
+
disabled: index === 0,
|
|
114
|
+
onClick: () => setIndex(index - 1),
|
|
115
|
+
children: labels.back
|
|
116
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
117
|
+
className: "flex items-center gap-2",
|
|
118
|
+
children: [question.optional ? /* @__PURE__ */ jsx(Button, {
|
|
119
|
+
type: "button",
|
|
120
|
+
variant: "ghost",
|
|
121
|
+
onClick: skip,
|
|
122
|
+
children: labels.skip
|
|
123
|
+
}) : null, /* @__PURE__ */ jsx(Button, {
|
|
124
|
+
type: "submit",
|
|
125
|
+
disabled: !answered && !question.optional,
|
|
126
|
+
children: last ? labels.finish : labels.next
|
|
127
|
+
})]
|
|
128
|
+
})]
|
|
129
|
+
})
|
|
130
|
+
]
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
export { Questionnaire };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ComponentProps, ReactNode } from "react";
|
|
2
|
+
import * as radio from "@zag-js/radio-group";
|
|
3
|
+
export interface RadioGroupProps extends Omit<radio.Props, "id" | "ids" | "onValueChange"> {
|
|
4
|
+
onValueChange?: (value: string | null) => void;
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
/** Names the group when there is no visible label. */
|
|
8
|
+
"aria-label"?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function RadioGroup({ onValueChange, children, className, "aria-label": ariaLabel, ...props }: RadioGroupProps): import("react").JSX.Element;
|
|
11
|
+
export type RadioGroupItemProps = Omit<ComponentProps<"label">, "value"> & {
|
|
12
|
+
value: string;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Draws no radio dot: the children are the whole control, such as a color
|
|
16
|
+
* swatch. Style them with `group-data-[state=checked]:`.
|
|
17
|
+
*/
|
|
18
|
+
bare?: boolean;
|
|
19
|
+
};
|
|
20
|
+
/** One choice. Children are its label. */
|
|
21
|
+
export declare function RadioGroupItem({ value, disabled, bare, children, className, ...props }: RadioGroupItemProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "./lib/cx.js";
|
|
3
|
+
import { normalizeProps, useMachine } from "@zag-js/react";
|
|
4
|
+
import { createContext, useContext, useId } from "react";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import * as radio from "@zag-js/radio-group";
|
|
7
|
+
// src/components/radio-group.tsx
|
|
8
|
+
const Context = createContext(null);
|
|
9
|
+
function useRadio() {
|
|
10
|
+
const api = useContext(Context);
|
|
11
|
+
if (!api) throw new Error("RadioGroupItem must be used inside <RadioGroup>.");
|
|
12
|
+
return api;
|
|
13
|
+
}
|
|
14
|
+
function RadioGroup({ onValueChange, children, className, "aria-label": ariaLabel, ...props }) {
|
|
15
|
+
const id = useId();
|
|
16
|
+
const service = useMachine(radio.machine, {
|
|
17
|
+
id,
|
|
18
|
+
onValueChange: ({ value }) => onValueChange?.(value),
|
|
19
|
+
...props
|
|
20
|
+
});
|
|
21
|
+
const api = radio.connect(service, normalizeProps);
|
|
22
|
+
return /* @__PURE__ */ jsx(Context.Provider, {
|
|
23
|
+
value: api,
|
|
24
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
25
|
+
...api.getRootProps(),
|
|
26
|
+
role: "radiogroup",
|
|
27
|
+
"aria-label": ariaLabel,
|
|
28
|
+
"data-slot": "radio-group",
|
|
29
|
+
className: cx("grid gap-3", className),
|
|
30
|
+
children
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/** One choice. Children are its label. */
|
|
35
|
+
function RadioGroupItem({ value, disabled, bare, children, className, ...props }) {
|
|
36
|
+
const api = useRadio();
|
|
37
|
+
const item = {
|
|
38
|
+
value,
|
|
39
|
+
disabled
|
|
40
|
+
};
|
|
41
|
+
if (bare) return /* @__PURE__ */ jsxs("label", {
|
|
42
|
+
...api.getItemProps(item),
|
|
43
|
+
"data-slot": "radio-group-item",
|
|
44
|
+
className: cx("group cursor-pointer data-disabled:cursor-not-allowed data-disabled:opacity-40", className),
|
|
45
|
+
...props,
|
|
46
|
+
children: [/* @__PURE__ */ jsx("input", { ...api.getItemHiddenInputProps(item) }), children]
|
|
47
|
+
});
|
|
48
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
49
|
+
...api.getItemProps(item),
|
|
50
|
+
"data-slot": "radio-group-item",
|
|
51
|
+
className: cx("group inline-flex cursor-pointer items-center gap-2.5 text-footnote data-disabled:cursor-not-allowed data-disabled:opacity-40", className),
|
|
52
|
+
...props,
|
|
53
|
+
children: [
|
|
54
|
+
/* @__PURE__ */ jsx("input", { ...api.getItemHiddenInputProps(item) }),
|
|
55
|
+
/* @__PURE__ */ jsx("span", {
|
|
56
|
+
...api.getItemControlProps(item),
|
|
57
|
+
className: "bg-fill spring-snappy group-focus-within:ring-accent/70 data-[state=checked]:bg-accent inline-flex size-5.5 shrink-0 items-center justify-center rounded-full shadow-[inset_0_0_0_0.5px_var(--color-separator)] transition group-focus-within:ring-2 group-active:scale-90 motion-reduce:transition-none motion-reduce:group-active:scale-100",
|
|
58
|
+
children: /* @__PURE__ */ jsx("span", { className: "bg-on-accent spring-bouncy size-2 scale-0 rounded-full transition-transform group-data-[state=checked]:scale-100" })
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ jsx("span", {
|
|
61
|
+
...api.getItemTextProps(item),
|
|
62
|
+
children
|
|
63
|
+
})
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export { RadioGroup, RadioGroupItem };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ComponentProps } from "react";
|
|
2
|
+
export type SearchFieldSize = "sm" | "md" | "lg";
|
|
3
|
+
export type SearchFieldProps = Omit<ComponentProps<"input">, "size"> & {
|
|
4
|
+
/** Height, icon and text, from the shared control scale. @default "md" */
|
|
5
|
+
size?: SearchFieldSize;
|
|
6
|
+
/**
|
|
7
|
+
* Rests as a round search button and opens into the field when focused or
|
|
8
|
+
* when it holds text. Needs a `width` class on the field to open to.
|
|
9
|
+
* @default false
|
|
10
|
+
*/
|
|
11
|
+
collapsible?: boolean;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* A search input in a full pill. Native `type="search"`, so the clear button,
|
|
15
|
+
* Escape and mobile search keyboards come with it. It can rest as a round
|
|
16
|
+
* button and open on focus, in CSS only.
|
|
17
|
+
*/
|
|
18
|
+
export declare function SearchField({ size, collapsible, placeholder, className, ...props }: SearchFieldProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "./lib/cx.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { SearchIcon } from "@passui/icons/search";
|
|
5
|
+
// src/components/search-field.tsx
|
|
6
|
+
const pill = {
|
|
7
|
+
sm: "h-7.5 gap-1.5 px-3 text-footnote",
|
|
8
|
+
md: "h-8.5 gap-2 px-3.5 text-footnote",
|
|
9
|
+
lg: "h-9.5 gap-2.5 px-4 text-subheadline"
|
|
10
|
+
};
|
|
11
|
+
/** The width a collapsed field keeps: a round button the size of the control. */
|
|
12
|
+
const collapsed = {
|
|
13
|
+
sm: "w-7.5",
|
|
14
|
+
md: "w-8.5",
|
|
15
|
+
lg: "w-9.5"
|
|
16
|
+
};
|
|
17
|
+
const icons = {
|
|
18
|
+
sm: 13,
|
|
19
|
+
md: 14,
|
|
20
|
+
lg: 16
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* A search input in a full pill. Native `type="search"`, so the clear button,
|
|
24
|
+
* Escape and mobile search keyboards come with it. It can rest as a round
|
|
25
|
+
* button and open on focus, in CSS only.
|
|
26
|
+
*/
|
|
27
|
+
function SearchField({ size = "md", collapsible = false, placeholder = "Search", className, ...props }) {
|
|
28
|
+
return /* @__PURE__ */ jsxs("label", {
|
|
29
|
+
"data-slot": "search-field",
|
|
30
|
+
"data-collapsible": collapsible || void 0,
|
|
31
|
+
className: cx("control-field group flex max-w-full items-center rounded-full text-label-tertiary focus-within:ring-2 focus-within:ring-accent/70", pill[size], !collapsible && "w-full", collapsible && cx("spring-smooth justify-start overflow-hidden transition-[width] motion-reduce:transition-none", collapsed[size], "focus-within:w-full has-[input:not(:placeholder-shown)]:w-full"), className),
|
|
32
|
+
children: [/* @__PURE__ */ jsx(SearchIcon, {
|
|
33
|
+
size: icons[size],
|
|
34
|
+
"aria-hidden": "true",
|
|
35
|
+
className: "shrink-0"
|
|
36
|
+
}), /* @__PURE__ */ jsx("input", {
|
|
37
|
+
type: "search",
|
|
38
|
+
placeholder,
|
|
39
|
+
"aria-label": props["aria-labelledby"] ? void 0 : placeholder,
|
|
40
|
+
className: cx("min-w-0 grow bg-transparent text-label outline-none placeholder:text-label-tertiary", collapsible && "opacity-0 transition-opacity group-focus-within:opacity-100 group-has-[input:not(:placeholder-shown)]:opacity-100"),
|
|
41
|
+
...props
|
|
42
|
+
})]
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export { SearchField };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
export interface SegmentedOption {
|
|
3
|
+
value: string;
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface SegmentedControlProps {
|
|
8
|
+
options: SegmentedOption[];
|
|
9
|
+
value?: string;
|
|
10
|
+
defaultValue?: string;
|
|
11
|
+
onValueChange?: (value: string) => void;
|
|
12
|
+
"aria-label"?: string;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Mutually exclusive choices in one pill. A single select `ToggleGroup`. */
|
|
16
|
+
export declare function SegmentedControl({ options, value, defaultValue, onValueChange, "aria-label": ariaLabel, className }: SegmentedControlProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "./lib/cx.js";
|
|
3
|
+
import { ToggleGroup, ToggleGroupItem } from "./toggle-group.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
// src/components/segmented-control.tsx
|
|
6
|
+
/** Mutually exclusive choices in one pill. A single select `ToggleGroup`. */
|
|
7
|
+
function SegmentedControl({ options, value, defaultValue, onValueChange, "aria-label": ariaLabel, className }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(ToggleGroup, {
|
|
9
|
+
"aria-label": ariaLabel,
|
|
10
|
+
className: cx("w-fit", className),
|
|
11
|
+
size: "sm",
|
|
12
|
+
value: value === void 0 ? void 0 : [value],
|
|
13
|
+
defaultValue: defaultValue === void 0 ? void 0 : [defaultValue],
|
|
14
|
+
deselectable: false,
|
|
15
|
+
onValueChange: (next) => {
|
|
16
|
+
if (next[0]) onValueChange?.(next[0]);
|
|
17
|
+
},
|
|
18
|
+
children: options.map((o) => /* @__PURE__ */ jsx(ToggleGroupItem, {
|
|
19
|
+
value: o.value,
|
|
20
|
+
disabled: o.disabled,
|
|
21
|
+
children: o.label
|
|
22
|
+
}, o.value))
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export { SegmentedControl };
|
package/dist/select.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import * as zagSelect from "@zag-js/select";
|
|
3
|
+
export interface SelectItem {
|
|
4
|
+
value: string;
|
|
5
|
+
label: string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface SelectProps extends Omit<zagSelect.Props<SelectItem>, "id" | "ids" | "collection" | "value" | "defaultValue" | "onValueChange"> {
|
|
9
|
+
items: SelectItem[];
|
|
10
|
+
value?: string | null;
|
|
11
|
+
defaultValue?: string | null;
|
|
12
|
+
onValueChange?: (value: string | null) => void;
|
|
13
|
+
placeholder?: ReactNode;
|
|
14
|
+
/** Shown before the value inside the trigger, such as a globe for a language list. */
|
|
15
|
+
icon?: ReactNode;
|
|
16
|
+
"aria-label"?: string;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A single choice from a list. Renders a native hidden `select`, so it submits
|
|
21
|
+
* with its form, and a listbox that opens over the trigger with the selected
|
|
22
|
+
* option on the trigger's value.
|
|
23
|
+
*/
|
|
24
|
+
export declare function Select({ items, value, defaultValue, onValueChange, placeholder, icon, "aria-label": ariaLabel, className, ...props }: SelectProps): import("react").JSX.Element;
|
package/dist/select.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cx } from "./lib/cx.js";
|
|
3
|
+
import { Portal } from "./lib/portal.js";
|
|
4
|
+
import { usePresence } from "./lib/presence.js";
|
|
5
|
+
import { alignSelectedOption, positionerSide, useAnchorFollow, useTriggerAnchor, useWaterDrop } from "./lib/water-drop.js";
|
|
6
|
+
import { normalizeProps, useMachine } from "@zag-js/react";
|
|
7
|
+
import { useId, useMemo } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
import * as zagSelect from "@zag-js/select";
|
|
10
|
+
// src/components/select.tsx
|
|
11
|
+
/**
|
|
12
|
+
* A single choice from a list. Renders a native hidden `select`, so it submits
|
|
13
|
+
* with its form, and a listbox that opens over the trigger with the selected
|
|
14
|
+
* option on the trigger's value.
|
|
15
|
+
*/
|
|
16
|
+
function Select({ items, value, defaultValue, onValueChange, placeholder = "Select", icon, "aria-label": ariaLabel, className, ...props }) {
|
|
17
|
+
const id = useId();
|
|
18
|
+
const collection = useMemo(() => zagSelect.collection({
|
|
19
|
+
items,
|
|
20
|
+
itemToValue: (i) => i.value,
|
|
21
|
+
itemToString: (i) => i.label,
|
|
22
|
+
isItemDisabled: (i) => !!i.disabled
|
|
23
|
+
}), [items]);
|
|
24
|
+
const one = (v) => v === void 0 ? void 0 : v ? [v] : [];
|
|
25
|
+
const anchor = useTriggerAnchor("bottom-start", 6);
|
|
26
|
+
const service = useMachine(zagSelect.machine, {
|
|
27
|
+
id,
|
|
28
|
+
collection,
|
|
29
|
+
value: one(value),
|
|
30
|
+
defaultValue: one(defaultValue),
|
|
31
|
+
onValueChange: ({ value: next }) => onValueChange?.(next[0] ?? null),
|
|
32
|
+
positioning: {
|
|
33
|
+
fitViewport: true,
|
|
34
|
+
placement: "bottom-start",
|
|
35
|
+
offset: { mainAxis: 6 },
|
|
36
|
+
getAnchorRect: anchor.getAnchorRect
|
|
37
|
+
},
|
|
38
|
+
...props
|
|
39
|
+
});
|
|
40
|
+
const api = zagSelect.connect(service, normalizeProps);
|
|
41
|
+
anchor.state.shift = () => alignSelectedOption(document.getElementById(api.getTriggerProps().id ?? ""), document.getElementById(api.getContentProps().id ?? ""));
|
|
42
|
+
useAnchorFollow(anchor, api.open, positionerSide(api.getPositionerProps()), api.reposition);
|
|
43
|
+
const drop = useWaterDrop({
|
|
44
|
+
sourceId: api.getTriggerProps().id,
|
|
45
|
+
material: "liquid-glass-dense squircle [--squircle-radius:1.25rem]"
|
|
46
|
+
});
|
|
47
|
+
const { ref, mounted, attrs } = usePresence(api.open, drop);
|
|
48
|
+
const selected = api.selectedItems[0];
|
|
49
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
50
|
+
...api.getRootProps(),
|
|
51
|
+
"data-slot": "select",
|
|
52
|
+
className: cx("w-full", className),
|
|
53
|
+
children: [
|
|
54
|
+
/* @__PURE__ */ jsx("select", { ...api.getHiddenSelectProps() }),
|
|
55
|
+
/* @__PURE__ */ jsx("div", {
|
|
56
|
+
...api.getControlProps(),
|
|
57
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
58
|
+
...api.getTriggerProps(),
|
|
59
|
+
"aria-label": ariaLabel,
|
|
60
|
+
"data-slot": "select-trigger",
|
|
61
|
+
className: "group bg-fill/60 text-footnote text-label focus-visible:ring-accent/70 aria-invalid:ring-danger/70 spring-snappy flex h-8.5 w-full items-center justify-between gap-2 rounded-xl px-3 text-left transition outline-none focus-visible:ring-2 active:scale-[0.98] disabled:opacity-40 aria-invalid:ring-2 motion-reduce:transition-none motion-reduce:active:scale-100",
|
|
62
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
63
|
+
...api.getValueTextProps(),
|
|
64
|
+
className: selected ? "" : "text-label-tertiary",
|
|
65
|
+
children: selected?.label ?? placeholder
|
|
66
|
+
}), /* @__PURE__ */ jsx("svg", {
|
|
67
|
+
viewBox: "0 0 16 16",
|
|
68
|
+
className: "text-label-secondary size-3.5 shrink-0 transition-transform duration-(--duration-fast) group-data-[state=open]:rotate-180 motion-reduce:transition-none",
|
|
69
|
+
fill: "none",
|
|
70
|
+
stroke: "currentColor",
|
|
71
|
+
strokeWidth: "2",
|
|
72
|
+
strokeLinecap: "round",
|
|
73
|
+
strokeLinejoin: "round",
|
|
74
|
+
"aria-hidden": "true",
|
|
75
|
+
children: /* @__PURE__ */ jsx("path", { d: "m4 6 4 4 4-4" })
|
|
76
|
+
})]
|
|
77
|
+
})
|
|
78
|
+
}),
|
|
79
|
+
mounted ? /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx("div", {
|
|
80
|
+
...api.getPositionerProps(),
|
|
81
|
+
className: "z-[70]",
|
|
82
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
83
|
+
...api.getContentProps(),
|
|
84
|
+
...attrs,
|
|
85
|
+
ref,
|
|
86
|
+
hidden: false,
|
|
87
|
+
"data-slot": "select-content",
|
|
88
|
+
className: "liquid-glass-dense squircle morph-reset spring-smooth max-h-[min(18rem,var(--available-height,18rem))] w-max max-w-(--available-width,100vw) min-w-(--reference-width) origin-(--transform-origin,center) overflow-y-auto p-1.5 transition outline-none [--squircle-radius:1.25rem] data-ending-style:scale-[0.88] data-ending-style:opacity-0 data-starting-style:scale-[0.88] data-starting-style:opacity-0 motion-reduce:transition-none",
|
|
89
|
+
children: items.map((item) => /* @__PURE__ */ jsxs("div", {
|
|
90
|
+
...api.getItemProps({ item }),
|
|
91
|
+
"data-slot": "select-item",
|
|
92
|
+
className: "text-footnote text-label data-highlighted:bg-accent/15 flex cursor-pointer items-center justify-between gap-3 rounded-xl px-3 py-2 data-disabled:opacity-40",
|
|
93
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
94
|
+
...api.getItemTextProps({ item }),
|
|
95
|
+
children: item.label
|
|
96
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
97
|
+
...api.getItemIndicatorProps({ item }),
|
|
98
|
+
className: "text-accent-text",
|
|
99
|
+
children: "✓"
|
|
100
|
+
})]
|
|
101
|
+
}, item.value))
|
|
102
|
+
})
|
|
103
|
+
}) }) : null
|
|
104
|
+
]
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
export { Select };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ComponentProps } from "react";
|
|
2
|
+
export type SeparatorProps = ComponentProps<"div"> & {
|
|
3
|
+
/** @default "horizontal" */
|
|
4
|
+
orientation?: "horizontal" | "vertical";
|
|
5
|
+
/** Purely visual separators are hidden from assistive technology. @default true */
|
|
6
|
+
decorative?: boolean;
|
|
7
|
+
};
|
|
8
|
+
/** A hairline rule between groups. */
|
|
9
|
+
export declare function Separator({ orientation, decorative, className, ...props }: SeparatorProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cx } from "./lib/cx.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
// src/components/separator.tsx
|
|
4
|
+
/** A hairline rule between groups. */
|
|
5
|
+
function Separator({ orientation = "horizontal", decorative = true, className, ...props }) {
|
|
6
|
+
return /* @__PURE__ */ jsx("div", {
|
|
7
|
+
"data-slot": "separator",
|
|
8
|
+
"data-orientation": orientation,
|
|
9
|
+
...decorative ? { role: "none" } : {
|
|
10
|
+
role: "separator",
|
|
11
|
+
"aria-orientation": orientation
|
|
12
|
+
},
|
|
13
|
+
className: cx("shrink-0 bg-separator data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px", className),
|
|
14
|
+
...props
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
export { Separator };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Material 3 expressive outlines: a circle and the scalloped "cookie", "clover", and "sunny" shapes. */
|
|
2
|
-
export declare const shapes: readonly ["circle", "cookie4", "cookie6", "cookie9", "clover", "sunny",
|
|
2
|
+
export declare const shapes: readonly ["circle", "cookie4", "cookie6", "cookie9", "clover", "sunny",
|
|
3
3
|
/** Reserved for the Pherus mark itself, so it never matches a project's icon. */
|
|
4
4
|
"cookie12"];
|
|
5
5
|
export type Shape = (typeof shapes)[number];
|
|
@@ -14,4 +14,4 @@ export declare function shapePath(shape: Shape, cx: number, cy: number, r: numbe
|
|
|
14
14
|
* The app wide `dualTone` rule dims every svg path for two tone icons; a
|
|
15
15
|
* drawn shape or illustration opts out with this so its colors stay true.
|
|
16
16
|
*/
|
|
17
|
-
export declare const plainSvg = "cursor-[inherit] [&_path]:opacity-100 [&_path]:transform-none";
|
|
17
|
+
export declare const plainSvg = "cursor-[inherit] [&_path]:opacity-100 [&_path]:transform-none";
|
package/dist/shapes.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// src/lib/shapes.ts
|
|
2
|
+
/** Material 3 expressive outlines: a circle and the scalloped "cookie", "clover", and "sunny" shapes. */
|
|
3
|
+
const shapes = [
|
|
4
|
+
"circle",
|
|
5
|
+
"cookie4",
|
|
6
|
+
"cookie6",
|
|
7
|
+
"cookie9",
|
|
8
|
+
"clover",
|
|
9
|
+
"sunny",
|
|
10
|
+
"cookie12"
|
|
11
|
+
];
|
|
12
|
+
/** Lobe count and wave depth (as a fraction of the radius) for each wavy shape. */
|
|
13
|
+
const waves = {
|
|
14
|
+
cookie4: {
|
|
15
|
+
lobes: 4,
|
|
16
|
+
depth: .08
|
|
17
|
+
},
|
|
18
|
+
cookie6: {
|
|
19
|
+
lobes: 6,
|
|
20
|
+
depth: .07
|
|
21
|
+
},
|
|
22
|
+
cookie9: {
|
|
23
|
+
lobes: 9,
|
|
24
|
+
depth: .055
|
|
25
|
+
},
|
|
26
|
+
clover: {
|
|
27
|
+
lobes: 4,
|
|
28
|
+
depth: .16
|
|
29
|
+
},
|
|
30
|
+
sunny: {
|
|
31
|
+
lobes: 8,
|
|
32
|
+
depth: .045
|
|
33
|
+
},
|
|
34
|
+
cookie12: {
|
|
35
|
+
lobes: 12,
|
|
36
|
+
depth: .04
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const STEPS = 144;
|
|
40
|
+
/**
|
|
41
|
+
* An SVG path for a Material 3 expressive shape centred on (cx, cy): a circle
|
|
42
|
+
* whose radius rides a cosine wave, which gives the soft scalloped "cookie",
|
|
43
|
+
* "clover", and "sunny" outlines. The wave is normalised so every shape fills
|
|
44
|
+
* the same `r`, keeping icons optically the same size.
|
|
45
|
+
*/
|
|
46
|
+
function shapePath(shape, cx, cy, r) {
|
|
47
|
+
if (shape === "circle") return `M ${cx - r} ${cy} a ${r} ${r} 0 1 0 ${r * 2} 0 a ${r} ${r} 0 1 0 ${-r * 2} 0 Z`;
|
|
48
|
+
const { lobes, depth } = waves[shape];
|
|
49
|
+
const base = r / (1 + depth);
|
|
50
|
+
const points = [];
|
|
51
|
+
for (let i = 0; i < STEPS; i++) {
|
|
52
|
+
const theta = i / STEPS * Math.PI * 2 - Math.PI / 2;
|
|
53
|
+
const radius = base * (1 + depth * Math.cos(lobes * (theta + Math.PI / 2)));
|
|
54
|
+
const x = cx + radius * Math.cos(theta);
|
|
55
|
+
const y = cy + radius * Math.sin(theta);
|
|
56
|
+
points.push(`${i === 0 ? "M" : "L"} ${x.toFixed(2)} ${y.toFixed(2)}`);
|
|
57
|
+
}
|
|
58
|
+
return `${points.join(" ")} Z`;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The app wide `dualTone` rule dims every svg path for two tone icons; a
|
|
62
|
+
* drawn shape or illustration opts out with this so its colors stay true.
|
|
63
|
+
*/
|
|
64
|
+
const plainSvg = "cursor-[inherit] [&_path]:opacity-100 [&_path]:transform-none";
|
|
65
|
+
export { plainSvg, shapePath, shapes };
|
package/dist/sheet.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RenderProp } from "./lib/render.js";
|
|
2
|
+
import { ComponentProps, ReactNode } from "react";
|
|
3
|
+
import * as drawer from "@zag-js/drawer";
|
|
4
|
+
export type SheetSide = "top" | "right" | "bottom" | "left";
|
|
5
|
+
export interface SheetProps extends Omit<drawer.Props, "id" | "ids" | "role" | "stack" | "swipeDirection" | "snapPoint" | "snapPoints" | "defaultSnapPoint"> {
|
|
6
|
+
/** Which edge the sheet slides from. */
|
|
7
|
+
side?: SheetSide;
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/** A panel that slides in from any edge and swipes away. Renders no element of its own. */
|
|
11
|
+
export declare function Sheet({ children, side, ...props }: SheetProps): import("react").JSX.Element;
|
|
12
|
+
type PartProps<T extends "button" | "div" | "h2" | "p"> = ComponentProps<T> & {
|
|
13
|
+
/** Render your own element instead of the default one. */
|
|
14
|
+
render?: RenderProp;
|
|
15
|
+
};
|
|
16
|
+
export declare function SheetTrigger({ render, ...props }: PartProps<"button">): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
17
|
+
export declare function SheetClose({ render, ...props }: PartProps<"button">): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
18
|
+
/** Backdrop, panel and focus trap. Mounts only while open or leaving. */
|
|
19
|
+
export declare function SheetContent({ className, render, ...props }: PartProps<"div">): import("react").JSX.Element | null;
|
|
20
|
+
export declare function SheetHeader({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
21
|
+
export declare function SheetFooter({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
22
|
+
export declare function SheetTitle({ className, ...props }: ComponentProps<"h2">): import("react").JSX.Element;
|
|
23
|
+
export declare function SheetDescription({ className, ...props }: ComponentProps<"p">): import("react").JSX.Element;
|
|
24
|
+
export {};
|