@evinvest/uikit 0.31.0 → 0.33.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 +23 -12
- package/dist/components/{accordion.js → atomic/accordion.js} +5 -4
- package/dist/components/atomic/accordion.js.map +1 -0
- package/dist/components/{alert-dialog.js → atomic/alert-dialog.js} +9 -9
- package/dist/components/atomic/alert-dialog.js.map +1 -0
- package/dist/components/{alert.js → atomic/alert.js} +6 -6
- package/dist/components/atomic/alert.js.map +1 -0
- package/dist/components/{animated-number-columns.js → atomic/animated-number-columns.js} +1 -1
- package/dist/components/atomic/animated-number-columns.js.map +1 -0
- package/dist/components/{avatar.js → atomic/avatar.js} +2 -2
- package/dist/components/atomic/avatar.js.map +1 -0
- package/dist/components/atomic/badge.js +26 -0
- package/dist/components/atomic/badge.js.map +1 -0
- package/dist/components/{band.js → atomic/band.js} +2 -2
- package/dist/components/atomic/band.js.map +1 -0
- package/dist/components/{breadcrumb.js → atomic/breadcrumb.js} +10 -12
- package/dist/components/atomic/breadcrumb.js.map +1 -0
- package/dist/components/{button-group.js → atomic/button-group.js} +3 -3
- package/dist/components/atomic/button-group.js.map +1 -0
- package/dist/components/{button.js → atomic/button.js} +8 -7
- package/dist/components/atomic/button.js.map +1 -0
- package/dist/components/{calendar.js → atomic/calendar.js} +12 -27
- package/dist/components/atomic/calendar.js.map +1 -0
- package/dist/components/{card.js → atomic/card.js} +2 -2
- package/dist/components/atomic/card.js.map +1 -0
- package/dist/components/{checkbox.js → atomic/checkbox.js} +6 -5
- package/dist/components/atomic/checkbox.js.map +1 -0
- package/dist/components/{collapsible.js → atomic/collapsible.js} +1 -1
- package/dist/components/atomic/collapsible.js.map +1 -0
- package/dist/components/{command.js → atomic/command.js} +11 -26
- package/dist/components/atomic/command.js.map +1 -0
- package/dist/components/{container.js → atomic/container.js} +2 -2
- package/dist/components/atomic/container.js.map +1 -0
- package/dist/components/{context-menu.js → atomic/context-menu.js} +15 -22
- package/dist/components/atomic/context-menu.js.map +1 -0
- package/dist/components/{dialog.js → atomic/dialog.js} +13 -11
- package/dist/components/atomic/dialog.js.map +1 -0
- package/dist/components/{drawer.js → atomic/drawer.js} +8 -8
- package/dist/components/atomic/drawer.js.map +1 -0
- package/dist/components/{dropdown-menu.js → atomic/dropdown-menu.js} +16 -24
- package/dist/components/atomic/dropdown-menu.js.map +1 -0
- package/dist/components/{empty.js → atomic/empty.js} +2 -2
- package/dist/components/atomic/empty.js.map +1 -0
- package/dist/components/atomic/field-context.js.map +1 -0
- package/dist/components/{form-row.js → atomic/form-row.js} +2 -2
- package/dist/components/atomic/form-row.js.map +1 -0
- package/dist/components/{hover-card.js → atomic/hover-card.js} +8 -8
- package/dist/components/atomic/hover-card.js.map +1 -0
- package/dist/components/{info-tip.js → atomic/info-tip.js} +18 -19
- package/dist/components/atomic/info-tip.js.map +1 -0
- package/dist/components/{input-otp.js → atomic/input-otp.js} +5 -4
- package/dist/components/atomic/input-otp.js.map +1 -0
- package/dist/components/{input.js → atomic/input.js} +3 -3
- package/dist/components/atomic/input.js.map +1 -0
- package/dist/components/{kbd.js → atomic/kbd.js} +2 -2
- package/dist/components/atomic/kbd.js.map +1 -0
- package/dist/components/{key-value.js → atomic/key-value.js} +8 -7
- package/dist/components/atomic/key-value.js.map +1 -0
- package/dist/components/{label.js → atomic/label.js} +2 -2
- package/dist/components/atomic/label.js.map +1 -0
- package/dist/components/{menubar.js → atomic/menubar.js} +16 -27
- package/dist/components/atomic/menubar.js.map +1 -0
- package/dist/components/{native-select.js → atomic/native-select.js} +5 -5
- package/dist/components/atomic/native-select.js.map +1 -0
- package/dist/components/{navigation-menu.js → atomic/navigation-menu.js} +12 -20
- package/dist/components/atomic/navigation-menu.js.map +1 -0
- package/dist/components/{pagination.js → atomic/pagination.js} +19 -20
- package/dist/components/atomic/pagination.js.map +1 -0
- package/dist/components/{popover.js → atomic/popover.js} +10 -10
- package/dist/components/atomic/popover.js.map +1 -0
- package/dist/components/{progress.js → atomic/progress.js} +2 -2
- package/dist/components/atomic/progress.js.map +1 -0
- package/dist/components/{radio-group.js → atomic/radio-group.js} +8 -7
- package/dist/components/atomic/radio-group.js.map +1 -0
- package/dist/components/{scroll-area.js → atomic/scroll-area.js} +2 -2
- package/dist/components/atomic/scroll-area.js.map +1 -0
- package/dist/components/{section-descriptor.js → atomic/section-descriptor.js} +7 -10
- package/dist/components/atomic/section-descriptor.js.map +1 -0
- package/dist/components/{select-listbox.js → atomic/select-listbox.js} +3 -3
- package/dist/components/atomic/select-listbox.js.map +1 -0
- package/dist/components/{select.js → atomic/select.js} +15 -23
- package/dist/components/atomic/select.js.map +1 -0
- package/dist/components/{separator.js → atomic/separator.js} +2 -2
- package/dist/components/atomic/separator.js.map +1 -0
- package/dist/components/{sheet.js → atomic/sheet.js} +13 -11
- package/dist/components/atomic/sheet.js.map +1 -0
- package/dist/components/{sidebar.js → atomic/sidebar.js} +11 -30
- package/dist/components/atomic/sidebar.js.map +1 -0
- package/dist/components/{skeleton.js → atomic/skeleton.js} +2 -2
- package/dist/components/atomic/skeleton.js.map +1 -0
- package/dist/components/{slider.js → atomic/slider.js} +3 -3
- package/dist/components/atomic/slider.js.map +1 -0
- package/dist/components/{sonner.js → atomic/sonner.js} +22 -20
- package/dist/components/atomic/sonner.js.map +1 -0
- package/dist/components/atomic/spinner.js +26 -0
- package/dist/components/atomic/spinner.js.map +1 -0
- package/dist/components/{status-item.js → atomic/status-item.js} +2 -2
- package/dist/components/atomic/status-item.js.map +1 -0
- package/dist/components/{switch.js → atomic/switch.js} +4 -4
- package/dist/components/atomic/switch.js.map +1 -0
- package/dist/components/{table.js → atomic/table.js} +2 -2
- package/dist/components/atomic/table.js.map +1 -0
- package/dist/components/{tabs.js → atomic/tabs.js} +4 -4
- package/dist/components/atomic/tabs.js.map +1 -0
- package/dist/components/{textarea.js → atomic/textarea.js} +3 -3
- package/dist/components/atomic/textarea.js.map +1 -0
- package/dist/components/{toggle-group.js → atomic/toggle-group.js} +4 -4
- package/dist/components/atomic/toggle-group.js.map +1 -0
- package/dist/components/{toggle.js → atomic/toggle.js} +5 -8
- package/dist/components/atomic/toggle.js.map +1 -0
- package/dist/components/{tooltip.js → atomic/tooltip.js} +8 -8
- package/dist/components/atomic/tooltip.js.map +1 -0
- package/dist/components/{use-count-tween.js → atomic/use-count-tween.js} +1 -1
- package/dist/components/atomic/use-count-tween.js.map +1 -0
- package/dist/components/{animated-number.js → derived/animated-number.js} +5 -5
- package/dist/components/derived/animated-number.js.map +1 -0
- package/dist/components/{carousel.js → derived/carousel.js} +10 -10
- package/dist/components/derived/carousel.js.map +1 -0
- package/dist/components/{command-palette.js → derived/command-palette.js} +14 -13
- package/dist/components/derived/command-palette.js.map +1 -0
- package/dist/components/{confirm-dialog.js → derived/confirm-dialog.js} +15 -20
- package/dist/components/derived/confirm-dialog.js.map +1 -0
- package/dist/components/{date-time-picker.js → derived/date-time-picker.js} +18 -22
- package/dist/components/derived/date-time-picker.js.map +1 -0
- package/dist/components/{field.js → derived/field.js} +6 -6
- package/dist/components/derived/field.js.map +1 -0
- package/dist/components/{form.js → derived/form.js} +4 -5
- package/dist/components/derived/form.js.map +1 -0
- package/dist/components/{icon-button.js → derived/icon-button.js} +4 -4
- package/dist/components/derived/icon-button.js.map +1 -0
- package/dist/components/{input-group.js → derived/input-group.js} +5 -5
- package/dist/components/derived/input-group.js.map +1 -0
- package/dist/components/{item.js → derived/item.js} +4 -5
- package/dist/components/derived/item.js.map +1 -0
- package/dist/components/{popover-form.js → derived/popover-form.js} +9 -8
- package/dist/components/derived/popover-form.js.map +1 -0
- package/dist/components/{settings.js → derived/settings.js} +7 -7
- package/dist/components/derived/settings.js.map +1 -0
- package/dist/components/{account-list.js → shell/account-list.js} +5 -5
- package/dist/components/shell/account-list.js.map +1 -0
- package/dist/components/{account-menu-profile.js → shell/account-menu-profile.js} +7 -7
- package/dist/components/shell/account-menu-profile.js.map +1 -0
- package/dist/components/{account-menu.js → shell/account-menu.js} +4 -4
- package/dist/components/shell/account-menu.js.map +1 -0
- package/dist/components/{account-settings-dialog.js → shell/account-settings-dialog.js} +9 -8
- package/dist/components/shell/account-settings-dialog.js.map +1 -0
- package/dist/components/{app-shell.js → shell/app-shell.js} +1 -1
- package/dist/components/shell/app-shell.js.map +1 -0
- package/dist/components/{aside.js → shell/aside.js} +12 -10
- package/dist/components/shell/aside.js.map +1 -0
- package/dist/components/{auth-wall.js → shell/auth-wall.js} +4 -6
- package/dist/components/shell/auth-wall.js.map +1 -0
- package/dist/components/{bottom-tab-bar.js → shell/bottom-tab-bar.js} +4 -4
- package/dist/components/shell/bottom-tab-bar.js.map +1 -0
- package/dist/components/{chat-composer.js → shell/chat-composer.js} +16 -14
- package/dist/components/shell/chat-composer.js.map +1 -0
- package/dist/components/{chat-message.js → shell/chat-message.js} +4 -4
- package/dist/components/shell/chat-message.js.map +1 -0
- package/dist/components/{chat-panel.js → shell/chat-panel.js} +3 -3
- package/dist/components/shell/chat-panel.js.map +1 -0
- package/dist/components/shell/chat-stream-text.js.map +1 -0
- package/dist/components/{chat-typing.js → shell/chat-typing.js} +4 -3
- package/dist/components/shell/chat-typing.js.map +1 -0
- package/dist/components/{footer.js → shell/footer.js} +27 -25
- package/dist/components/shell/footer.js.map +1 -0
- package/dist/components/{header-controls.js → shell/header-controls.js} +25 -23
- package/dist/components/shell/header-controls.js.map +1 -0
- package/dist/components/shell/hotbar.js +158 -0
- package/dist/components/shell/hotbar.js.map +1 -0
- package/dist/components/{list-rows.js → shell/list-rows.js} +1 -1
- package/dist/components/shell/list-rows.js.map +1 -0
- package/dist/components/{logo.js → shell/logo.js} +4 -3
- package/dist/components/shell/logo.js.map +1 -0
- package/dist/components/{mobile-app-bar.js → shell/mobile-app-bar.js} +5 -5
- package/dist/components/shell/mobile-app-bar.js.map +1 -0
- package/dist/components/{nav-badge.js → shell/nav-badge.js} +1 -1
- package/dist/components/shell/nav-badge.js.map +1 -0
- package/dist/components/{nav-collapse.js → shell/nav-collapse.js} +8 -7
- package/dist/components/shell/nav-collapse.js.map +1 -0
- package/dist/components/shell/nav-link.js.map +1 -0
- package/dist/components/shell/nav-model.js.map +1 -0
- package/dist/components/{page-frame.js → shell/page-frame.js} +2 -2
- package/dist/components/shell/page-frame.js.map +1 -0
- package/dist/components/{resource-error.js → shell/resource-error.js} +5 -5
- package/dist/components/shell/resource-error.js.map +1 -0
- package/dist/components/{section-nav.js → shell/section-nav.js} +4 -4
- package/dist/components/shell/section-nav.js.map +1 -0
- package/dist/components/shell/settled.js.map +1 -0
- package/dist/components/shell/shell-icons.js +42 -0
- package/dist/components/shell/shell-icons.js.map +1 -0
- package/dist/components/{shell-nav.js → shell/shell-nav.js} +5 -5
- package/dist/components/shell/shell-nav.js.map +1 -0
- package/dist/components/{smart-header.js → shell/smart-header.js} +2 -2
- package/dist/components/shell/smart-header.js.map +1 -0
- package/dist/components/shell/status-screen.js +145 -0
- package/dist/components/shell/status-screen.js.map +1 -0
- package/dist/components/{system-banner.js → shell/system-banner.js} +8 -8
- package/dist/components/shell/system-banner.js.map +1 -0
- package/dist/components/{top-bar.js → shell/top-bar.js} +2 -2
- package/dist/components/shell/top-bar.js.map +1 -0
- package/dist/components/shell/use-shell-nav.js.map +1 -0
- package/dist/components/{workspace-tab.js → shell/workspace-tab.js} +6 -5
- package/dist/components/shell/workspace-tab.js.map +1 -0
- package/dist/generated/accent.js +10 -10
- package/dist/generated/accent.js.map +1 -1
- package/dist/generated/accordion.js +6 -2
- package/dist/generated/accordion.js.map +1 -1
- package/dist/generated/account-list.js +4 -4
- package/dist/generated/account-list.js.map +1 -1
- package/dist/generated/account-settings-dialog.js +6 -2
- package/dist/generated/account-settings-dialog.js.map +1 -1
- package/dist/generated/alert-dialog.js +1 -1
- package/dist/generated/alert-dialog.js.map +1 -1
- package/dist/generated/alert.js +3 -10
- package/dist/generated/alert.js.map +1 -1
- package/dist/generated/aside.js +7 -0
- package/dist/generated/aside.js.map +1 -1
- package/dist/generated/badge.js +2 -11
- package/dist/generated/badge.js.map +1 -1
- package/dist/generated/band.js +10 -10
- package/dist/generated/band.js.map +1 -1
- package/dist/generated/breadcrumb.js +1 -1
- package/dist/generated/breadcrumb.js.map +1 -1
- package/dist/generated/button-group.js +3 -3
- package/dist/generated/button-group.js.map +1 -1
- package/dist/generated/button.js +4 -20
- package/dist/generated/button.js.map +1 -1
- package/dist/generated/calendar.js +5 -5
- package/dist/generated/calendar.js.map +1 -1
- package/dist/generated/card.js +1 -1
- package/dist/generated/card.js.map +1 -1
- package/dist/generated/carousel.js +1 -1
- package/dist/generated/carousel.js.map +1 -1
- package/dist/generated/chat-composer.js +9 -2
- package/dist/generated/chat-composer.js.map +1 -1
- package/dist/generated/chat-message.js +25 -19
- package/dist/generated/chat-message.js.map +1 -1
- package/dist/generated/checkbox.js +1 -1
- package/dist/generated/checkbox.js.map +1 -1
- package/dist/generated/command-palette.js +10 -1
- package/dist/generated/command-palette.js.map +1 -1
- package/dist/generated/command.js +8 -6
- package/dist/generated/command.js.map +1 -1
- package/dist/generated/confirm-dialog.js +8 -8
- package/dist/generated/confirm-dialog.js.map +1 -1
- package/dist/generated/context-menu.js +7 -5
- package/dist/generated/context-menu.js.map +1 -1
- package/dist/generated/copy.js +97 -0
- package/dist/generated/copy.js.map +1 -0
- package/dist/generated/date-time-picker.js +10 -0
- package/dist/generated/date-time-picker.js.map +1 -1
- package/dist/generated/dialog.js +2 -2
- package/dist/generated/dialog.js.map +1 -1
- package/dist/generated/drawer.js +6 -6
- package/dist/generated/drawer.js.map +1 -1
- package/dist/generated/dropdown-menu.js +7 -5
- package/dist/generated/dropdown-menu.js.map +1 -1
- package/dist/generated/empty.js +5 -5
- package/dist/generated/empty.js.map +1 -1
- package/dist/generated/field.js +9 -7
- package/dist/generated/field.js.map +1 -1
- package/dist/generated/footer.js +45 -0
- package/dist/generated/footer.js.map +1 -0
- package/dist/generated/header-controls.js +5 -10
- package/dist/generated/header-controls.js.map +1 -1
- package/dist/generated/hover-card.js +1 -1
- package/dist/generated/hover-card.js.map +1 -1
- package/dist/generated/icon-button.js +4 -2
- package/dist/generated/icon-button.js.map +1 -1
- package/dist/generated/icons.js +36 -0
- package/dist/generated/icons.js.map +1 -0
- package/dist/generated/info-tip.js +5 -0
- package/dist/generated/info-tip.js.map +1 -0
- package/dist/generated/input-group.js +10 -10
- package/dist/generated/input-group.js.map +1 -1
- package/dist/generated/input-otp.js +2 -2
- package/dist/generated/input-otp.js.map +1 -1
- package/dist/generated/input.js +4 -4
- package/dist/generated/input.js.map +1 -1
- package/dist/generated/item.js +11 -11
- package/dist/generated/item.js.map +1 -1
- package/dist/generated/kbd.js +1 -1
- package/dist/generated/kbd.js.map +1 -1
- package/dist/generated/key-value.js +7 -1
- package/dist/generated/key-value.js.map +1 -1
- package/dist/generated/label.js +1 -1
- package/dist/generated/label.js.map +1 -1
- package/dist/generated/logo.js +9 -0
- package/dist/generated/logo.js.map +1 -0
- package/dist/generated/menu.js +7 -0
- package/dist/generated/menu.js.map +1 -0
- package/dist/generated/menubar.js +10 -8
- package/dist/generated/menubar.js.map +1 -1
- package/dist/generated/navigation-menu.js +11 -5
- package/dist/generated/navigation-menu.js.map +1 -1
- package/dist/generated/orientation.js +5 -0
- package/dist/generated/orientation.js.map +1 -0
- package/dist/generated/pagination.js +15 -0
- package/dist/generated/pagination.js.map +1 -0
- package/dist/generated/popover-form.js +5 -0
- package/dist/generated/popover-form.js.map +1 -1
- package/dist/generated/popover.js +1 -1
- package/dist/generated/popover.js.map +1 -1
- package/dist/generated/primitives.js +7 -0
- package/dist/generated/primitives.js.map +1 -0
- package/dist/generated/radio-group.js +5 -1
- package/dist/generated/radio-group.js.map +1 -1
- package/dist/generated/section-descriptor.js +7 -0
- package/dist/generated/section-descriptor.js.map +1 -0
- package/dist/generated/select.js +16 -10
- package/dist/generated/select.js.map +1 -1
- package/dist/generated/settings.js +2 -7
- package/dist/generated/settings.js.map +1 -1
- package/dist/generated/sheet.js +1 -1
- package/dist/generated/sheet.js.map +1 -1
- package/dist/generated/sidebar.js +24 -12
- package/dist/generated/sidebar.js.map +1 -1
- package/dist/generated/size.js +12 -0
- package/dist/generated/size.js.map +1 -0
- package/dist/generated/skeleton.js +1 -1
- package/dist/generated/skeleton.js.map +1 -1
- package/dist/generated/slider.js +2 -2
- package/dist/generated/slider.js.map +1 -1
- package/dist/generated/slot.js +5 -0
- package/dist/generated/slot.js.map +1 -0
- package/dist/generated/smart-header.js +2 -0
- package/dist/generated/smart-header.js.map +1 -1
- package/dist/generated/sonner.js +11 -13
- package/dist/generated/sonner.js.map +1 -1
- package/dist/generated/spinner.js +5 -0
- package/dist/generated/spinner.js.map +1 -0
- package/dist/generated/status-screen.js +27 -0
- package/dist/generated/status-screen.js.map +1 -0
- package/dist/generated/switch.js +2 -2
- package/dist/generated/switch.js.map +1 -1
- package/dist/generated/system-banner.js +6 -16
- package/dist/generated/system-banner.js.map +1 -1
- package/dist/generated/table.js +9 -9
- package/dist/generated/table.js.map +1 -1
- package/dist/generated/tabs.js +2 -2
- package/dist/generated/tabs.js.map +1 -1
- package/dist/generated/textarea.js +1 -1
- package/dist/generated/textarea.js.map +1 -1
- package/dist/generated/toggle-group.js +9 -0
- package/dist/generated/toggle-group.js.map +1 -0
- package/dist/generated/toggle.js +1 -9
- package/dist/generated/toggle.js.map +1 -1
- package/dist/generated/tone.js +12 -0
- package/dist/generated/tone.js.map +1 -0
- package/dist/generated/tooltip.js +1 -1
- package/dist/generated/tooltip.js.map +1 -1
- package/dist/generated/workspace-tab.js +3 -3
- package/dist/generated/workspace-tab.js.map +1 -1
- package/dist/icons/icon-shapes.js +10 -0
- package/dist/icons/icon-shapes.js.map +1 -0
- package/dist/{components → icons}/select-chevron.js +2 -1
- package/dist/icons/select-chevron.js.map +1 -0
- package/dist/icons/ui-icons.js +23 -0
- package/dist/icons/ui-icons.js.map +1 -0
- package/dist/index.d.ts +203 -155
- package/dist/index.js +97 -96
- package/dist/lib/cn.js +1 -0
- package/dist/lib/cn.js.map +1 -1
- package/dist/primitives/use-floating.js.map +1 -1
- package/dist/primitives/use-roving-focus.js.map +1 -1
- package/package.json +2 -2
- package/styles/ev.css +13 -76
- package/styles/theme.css +133 -66
- package/styles/tokens.css +157 -149
- package/dist/components/accordion.js.map +0 -1
- package/dist/components/account-list.js.map +0 -1
- package/dist/components/account-menu-profile.js.map +0 -1
- package/dist/components/account-menu.js.map +0 -1
- package/dist/components/account-settings-dialog.js.map +0 -1
- package/dist/components/alert-dialog.js.map +0 -1
- package/dist/components/alert.js.map +0 -1
- package/dist/components/animated-number-columns.js.map +0 -1
- package/dist/components/animated-number.js.map +0 -1
- package/dist/components/app-shell.js.map +0 -1
- package/dist/components/aside.js.map +0 -1
- package/dist/components/auth-wall.js.map +0 -1
- package/dist/components/avatar.js.map +0 -1
- package/dist/components/badge.js +0 -25
- package/dist/components/badge.js.map +0 -1
- package/dist/components/band.js.map +0 -1
- package/dist/components/bottom-tab-bar.js.map +0 -1
- package/dist/components/breadcrumb.js.map +0 -1
- package/dist/components/button-group.js.map +0 -1
- package/dist/components/button.js.map +0 -1
- package/dist/components/calendar.js.map +0 -1
- package/dist/components/card.js.map +0 -1
- package/dist/components/carousel.js.map +0 -1
- package/dist/components/chat-composer.js.map +0 -1
- package/dist/components/chat-message.js.map +0 -1
- package/dist/components/chat-panel.js.map +0 -1
- package/dist/components/chat-stream-text.js.map +0 -1
- package/dist/components/chat-typing.js.map +0 -1
- package/dist/components/checkbox.js.map +0 -1
- package/dist/components/collapsible.js.map +0 -1
- package/dist/components/command-palette.js.map +0 -1
- package/dist/components/command.js.map +0 -1
- package/dist/components/confirm-dialog.js.map +0 -1
- package/dist/components/container.js.map +0 -1
- package/dist/components/context-menu.js.map +0 -1
- package/dist/components/date-time-picker.js.map +0 -1
- package/dist/components/dialog.js.map +0 -1
- package/dist/components/drawer.js.map +0 -1
- package/dist/components/dropdown-menu.js.map +0 -1
- package/dist/components/empty.js.map +0 -1
- package/dist/components/field-context.js.map +0 -1
- package/dist/components/field.js.map +0 -1
- package/dist/components/footer.js.map +0 -1
- package/dist/components/form-row.js.map +0 -1
- package/dist/components/form.js.map +0 -1
- package/dist/components/header-controls.js.map +0 -1
- package/dist/components/hover-card.js.map +0 -1
- package/dist/components/icon-button.js.map +0 -1
- package/dist/components/info-tip.js.map +0 -1
- package/dist/components/input-group.js.map +0 -1
- package/dist/components/input-otp.js.map +0 -1
- package/dist/components/input.js.map +0 -1
- package/dist/components/item.js.map +0 -1
- package/dist/components/kbd.js.map +0 -1
- package/dist/components/key-value.js.map +0 -1
- package/dist/components/label.js.map +0 -1
- package/dist/components/list-rows.js.map +0 -1
- package/dist/components/logo.js.map +0 -1
- package/dist/components/menubar.js.map +0 -1
- package/dist/components/mobile-app-bar.js.map +0 -1
- package/dist/components/native-select.js.map +0 -1
- package/dist/components/nav-badge.js.map +0 -1
- package/dist/components/nav-collapse.js.map +0 -1
- package/dist/components/nav-link.js.map +0 -1
- package/dist/components/nav-model.js.map +0 -1
- package/dist/components/navigation-menu.js.map +0 -1
- package/dist/components/page-frame.js.map +0 -1
- package/dist/components/pagination.js.map +0 -1
- package/dist/components/popover-form.js.map +0 -1
- package/dist/components/popover.js.map +0 -1
- package/dist/components/progress.js.map +0 -1
- package/dist/components/radio-group.js.map +0 -1
- package/dist/components/resource-error.js.map +0 -1
- package/dist/components/scroll-area.js.map +0 -1
- package/dist/components/section-descriptor.js.map +0 -1
- package/dist/components/section-nav.js.map +0 -1
- package/dist/components/select-chevron.js.map +0 -1
- package/dist/components/select-listbox.js.map +0 -1
- package/dist/components/select.js.map +0 -1
- package/dist/components/separator.js.map +0 -1
- package/dist/components/settings.js.map +0 -1
- package/dist/components/settled.js.map +0 -1
- package/dist/components/sheet.js.map +0 -1
- package/dist/components/shell-icons.js +0 -57
- package/dist/components/shell-icons.js.map +0 -1
- package/dist/components/shell-nav.js.map +0 -1
- package/dist/components/sidebar.js.map +0 -1
- package/dist/components/skeleton.js.map +0 -1
- package/dist/components/slider.js.map +0 -1
- package/dist/components/smart-header.js.map +0 -1
- package/dist/components/sonner.js.map +0 -1
- package/dist/components/spinner.js +0 -23
- package/dist/components/spinner.js.map +0 -1
- package/dist/components/status-item.js.map +0 -1
- package/dist/components/status-screen.js +0 -145
- package/dist/components/status-screen.js.map +0 -1
- package/dist/components/switch.js.map +0 -1
- package/dist/components/system-banner.js.map +0 -1
- package/dist/components/table.js.map +0 -1
- package/dist/components/tabs.js.map +0 -1
- package/dist/components/textarea.js.map +0 -1
- package/dist/components/toggle-group.js.map +0 -1
- package/dist/components/toggle.js.map +0 -1
- package/dist/components/tooltip.js.map +0 -1
- package/dist/components/top-bar.js.map +0 -1
- package/dist/components/ui-icons.js +0 -77
- package/dist/components/ui-icons.js.map +0 -1
- package/dist/components/use-count-tween.js.map +0 -1
- package/dist/components/use-shell-nav.js.map +0 -1
- package/dist/components/workspace-tab.js.map +0 -1
- /package/dist/components/{field-context.js → atomic/field-context.js} +0 -0
- /package/dist/components/{chat-stream-text.js → shell/chat-stream-text.js} +0 -0
- /package/dist/components/{nav-link.js → shell/nav-link.js} +0 -0
- /package/dist/components/{nav-model.js → shell/nav-model.js} +0 -0
- /package/dist/components/{settled.js → shell/settled.js} +0 -0
- /package/dist/components/{use-shell-nav.js → shell/use-shell-nav.js} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/context-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport { DismissableLayerScope, useDismissableLayer } from \"../primitives/dismissable-layer\";\nimport { usePresence } from \"../primitives/presence\";\nimport { useRovingFocus } from \"../primitives/use-roving-focus\";\nimport { useHoverIntent } from \"../primitives/use-hover-intent\";\nimport { mergeRefs } from \"../primitives/merge-refs\";\nimport { Portal } from \"../primitives/portal\";\nimport { Slot } from \"../primitives/slot\";\nimport {\n CONTEXT_MENU_CHECK_ITEM,\n CONTEXT_MENU_CONTENT,\n CONTEXT_MENU_ITEM,\n CONTEXT_MENU_LABEL,\n CONTEXT_MENU_SEPARATOR,\n CONTEXT_MENU_SHORTCUT,\n CONTEXT_MENU_SUB_CONTENT,\n CONTEXT_MENU_SUB_TRIGGER,\n} from \"../generated/context-menu\";\n\ninterface ContextMenuContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n point: { x: number; y: number };\n setPoint: (p: { x: number; y: number }) => void;\n}\n\nconst ContextMenuContext = React.createContext<ContextMenuContextValue | null>(null);\n\nfunction useContextMenu(): ContextMenuContextValue {\n const ctx = React.useContext(ContextMenuContext);\n if (!ctx) throw new Error(\"ContextMenu parts must be used within <ContextMenu>\");\n return ctx;\n}\n\nexport interface ContextMenuProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: React.ReactNode;\n}\n\nexport function ContextMenu({ open, defaultOpen = false, onOpenChange, children }: ContextMenuProps) {\n const [isOpen, setOpen] = useControllableState<boolean>({\n ...(open !== undefined ? { value: open } : {}),\n defaultValue: defaultOpen,\n ...(onOpenChange ? { onChange: onOpenChange } : {}),\n });\n const [point, setPoint] = React.useState({ x: 0, y: 0 });\n return (\n <ContextMenuContext.Provider value={{ open: isOpen, setOpen, point, setPoint }}>\n <div data-slot=\"context-menu\">{children}</div>\n </ContextMenuContext.Provider>\n );\n}\n\nexport function ContextMenuPortal({ children }: { children?: React.ReactNode }) {\n return <Portal>{children}</Portal>;\n}\n\nexport interface ContextMenuTriggerProps extends React.ComponentProps<\"div\"> {\n asChild?: boolean;\n}\n\nexport function ContextMenuTrigger({ asChild = false, onContextMenu, ...props }: ContextMenuTriggerProps) {\n const { setOpen, setPoint } = useContextMenu();\n const Comp = asChild ? Slot : \"div\";\n return (\n <Comp\n data-slot=\"context-menu-trigger\"\n onContextMenu={(e: React.MouseEvent<HTMLDivElement>) => {\n onContextMenu?.(e);\n e.preventDefault();\n setPoint({ x: e.clientX, y: e.clientY });\n setOpen(true);\n }}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\nexport function ContextMenuGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div data-slot=\"context-menu-group\" role=\"group\" className={className} {...props} />;\n}\n\nconst ContextMenuCloseContext = React.createContext<() => void>(() => {});\n\nexport function ContextMenuContent({ className, children, ...props }: React.ComponentProps<\"div\">) {\n const { open, setOpen, point } = useContextMenu();\n const { isPresent, ref: presRef } = usePresence(open);\n const dismissRef = useDismissableLayer({\n enabled: open,\n onDismiss: () => setOpen(false),\n });\n const contentRef = React.useRef<HTMLDivElement | null>(null);\n const items = () =>\n Array.from(\n contentRef.current?.querySelectorAll<HTMLElement>(\"[role^='menuitem']\") ?? [],\n ).filter((el) => el.getAttribute(\"data-disabled\") === null);\n const { activeIndex, setActiveIndex, onKeyDown: rovingKeyDown } = useRovingFocus({\n count: () => items().length,\n orientation: \"vertical\",\n loop: true,\n });\n // Reset on close: reopen on the first item, never on an index past the end.\n React.useEffect(() => {\n if (!open) setActiveIndex(0);\n }, [open, setActiveIndex]);\n React.useEffect(() => {\n if (!open) return;\n items()[activeIndex]?.focus();\n }, [open, activeIndex]);\n const close = React.useCallback(() => setOpen(false), [setOpen]);\n if (!isPresent) return null;\n return (\n <Portal>\n <ContextMenuCloseContext.Provider value={close}>\n <div\n data-slot=\"context-menu-content\"\n data-state={open ? \"open\" : \"closed\"}\n data-side=\"bottom\"\n role=\"menu\"\n tabIndex={-1}\n // Escape is the stack's (useDismissableLayer): it closes this menu\n // only while it is the top layer.\n onKeyDown={rovingKeyDown}\n ref={mergeRefs(dismissRef, presRef, contentRef)}\n style={{ position: \"fixed\", top: point.y, left: point.x }}\n className={cn(\n CONTEXT_MENU_CONTENT,\n className,\n )}\n {...(props as Record<string, unknown>)}\n >\n <DismissableLayerScope layer={dismissRef}>{children}</DismissableLayerScope>\n </div>\n </ContextMenuCloseContext.Provider>\n </Portal>\n );\n}\n\nexport interface ContextMenuItemProps extends React.ComponentProps<\"div\"> {\n inset?: boolean;\n variant?: \"neutral\" | \"destructive\";\n disabled?: boolean;\n}\n\nexport function ContextMenuItem({\n className,\n inset,\n variant = \"neutral\",\n disabled,\n onClick,\n onKeyDown,\n ...props\n}: ContextMenuItemProps) {\n const close = React.useContext(ContextMenuCloseContext);\n return (\n <div\n data-slot=\"context-menu-item\"\n data-inset={inset ? \"\" : undefined}\n data-variant={variant}\n data-disabled={disabled ? \"\" : undefined}\n role=\"menuitem\"\n tabIndex={disabled ? undefined : -1}\n className={cn(\n CONTEXT_MENU_ITEM,\n className,\n )}\n onClick={(e) => {\n if (disabled) return;\n onClick?.(e);\n close();\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n (e.currentTarget as HTMLElement).click();\n }\n }}\n {...props}\n />\n );\n}\n\nexport interface ContextMenuCheckboxItemProps extends React.ComponentProps<\"div\"> {\n checked?: boolean;\n disabled?: boolean;\n}\n\nexport function ContextMenuCheckboxItem({\n className,\n children,\n checked,\n disabled,\n onClick,\n onKeyDown,\n ...props\n}: ContextMenuCheckboxItemProps) {\n // No close: several boxes can be toggled in one visit.\n return (\n <div\n data-slot=\"context-menu-checkbox-item\"\n role=\"menuitemcheckbox\"\n aria-checked={checked}\n data-state={checked ? \"checked\" : \"unchecked\"}\n data-disabled={disabled ? \"\" : undefined}\n tabIndex={disabled ? undefined : -1}\n className={cn(\n CONTEXT_MENU_CHECK_ITEM,\n className,\n )}\n onClick={(e) => {\n if (disabled) return;\n onClick?.(e);\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n (e.currentTarget as HTMLElement).click();\n }\n }}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n {checked ? (\n <svg className=\"size-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n ) : null}\n </span>\n {children}\n </div>\n );\n}\n\ninterface ContextMenuRadioGroupContextValue {\n value: string | undefined;\n setValue: (next: string) => void;\n}\n\nconst ContextMenuRadioGroupContext =\n React.createContext<ContextMenuRadioGroupContextValue | null>(null);\n\nexport interface ContextMenuRadioGroupProps extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nexport function ContextMenuRadioGroup({\n className,\n value,\n onValueChange,\n children,\n ...props\n}: ContextMenuRadioGroupProps) {\n const ctx = React.useMemo<ContextMenuRadioGroupContextValue>(\n () => ({ value, setValue: (next) => onValueChange?.(next) }),\n [value, onValueChange],\n );\n return (\n <ContextMenuRadioGroupContext.Provider value={ctx}>\n <div data-slot=\"context-menu-radio-group\" role=\"group\" className={className} {...props}>\n {children}\n </div>\n </ContextMenuRadioGroupContext.Provider>\n );\n}\n\nexport interface ContextMenuRadioItemProps extends React.ComponentProps<\"div\"> {\n value: string;\n disabled?: boolean;\n}\n\nexport function ContextMenuRadioItem({\n className,\n children,\n value,\n disabled,\n onClick,\n ...props\n}: ContextMenuRadioItemProps) {\n const close = React.useContext(ContextMenuCloseContext);\n const group = React.useContext(ContextMenuRadioGroupContext);\n const checked = group?.value === value;\n return (\n <div\n data-slot=\"context-menu-radio-item\"\n role=\"menuitemradio\"\n aria-checked={checked}\n data-state={checked ? \"checked\" : \"unchecked\"}\n data-disabled={disabled ? \"\" : undefined}\n tabIndex={disabled ? undefined : -1}\n className={cn(\n CONTEXT_MENU_CHECK_ITEM,\n className,\n )}\n onClick={(e) => {\n if (disabled) return;\n onClick?.(e);\n group?.setValue(value);\n close();\n }}\n {...props}\n >\n <span className=\"pointer-events-none absolute left-2 flex size-3.5 items-center justify-center\">\n {checked ? (\n <svg className=\"size-2 fill-current\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n </svg>\n ) : null}\n </span>\n {children}\n </div>\n );\n}\n\nexport interface ContextMenuLabelProps extends React.ComponentProps<\"div\"> {\n inset?: boolean;\n}\n\nexport function ContextMenuLabel({ className, inset, ...props }: ContextMenuLabelProps) {\n return (\n <div\n data-slot=\"context-menu-label\"\n data-inset={inset ? \"\" : undefined}\n className={cn(CONTEXT_MENU_LABEL, className)}\n {...props}\n />\n );\n}\n\nexport function ContextMenuSeparator({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"context-menu-separator\"\n role=\"separator\"\n className={cn(CONTEXT_MENU_SEPARATOR, className)}\n {...props}\n />\n );\n}\n\nexport function ContextMenuShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"context-menu-shortcut\"\n className={cn(CONTEXT_MENU_SHORTCUT, className)}\n {...props}\n />\n );\n}\n\n// Sub-menus render inline (nested) rather than in a separate floating layer:\n// the sub-content is revealed in place when its trigger toggles.\ninterface ContextMenuSubContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n triggerRef: React.RefObject<HTMLDivElement | null>;\n /** Set by a keyboard open, so the first item takes focus; a pointer open leaves focus alone. */\n focusFirst: React.RefObject<boolean>;\n}\n\nconst ContextMenuSubContext = React.createContext<ContextMenuSubContextValue | null>(null);\n\nexport interface ContextMenuSubProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: React.ReactNode;\n}\n\nexport function ContextMenuSub({ open, defaultOpen = false, onOpenChange, children }: ContextMenuSubProps) {\n const [isOpen, setOpen] = useControllableState<boolean>({\n ...(open !== undefined ? { value: open } : {}),\n defaultValue: defaultOpen,\n ...(onOpenChange ? { onChange: onOpenChange } : {}),\n });\n const triggerRef = React.useRef<HTMLDivElement | null>(null);\n const focusFirst = React.useRef(false);\n const hover = useHoverIntent({\n onOpen: () => setOpen(true),\n onClose: () => setOpen(false),\n openDelay: 100,\n closeDelay: 150,\n });\n return (\n <ContextMenuSubContext.Provider value={{ open: isOpen, setOpen, triggerRef, focusFirst }}>\n <div data-slot=\"context-menu-sub\" {...hover}>\n {children}\n </div>\n </ContextMenuSubContext.Provider>\n );\n}\n\nexport interface ContextMenuSubTriggerProps extends React.ComponentProps<\"div\"> {\n inset?: boolean;\n}\n\nexport function ContextMenuSubTrigger({\n className,\n inset,\n children,\n onClick,\n onKeyDown,\n ...props\n}: ContextMenuSubTriggerProps) {\n const ctx = React.useContext(ContextMenuSubContext);\n return (\n <div\n ref={ctx?.triggerRef}\n data-slot=\"context-menu-sub-trigger\"\n data-inset={inset ? \"\" : undefined}\n data-state={ctx?.open ? \"open\" : \"closed\"}\n role=\"menuitem\"\n aria-haspopup=\"menu\"\n aria-expanded={ctx?.open}\n tabIndex={-1}\n className={cn(\n CONTEXT_MENU_SUB_TRIGGER,\n className,\n )}\n onClick={(e) => {\n onClick?.(e);\n ctx?.setOpen(!ctx.open);\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (!ctx || (e.key !== \"ArrowRight\" && e.key !== \"Enter\" && e.key !== \" \")) return;\n e.preventDefault();\n e.stopPropagation();\n ctx.focusFirst.current = true;\n ctx.setOpen(true);\n }}\n {...props}\n >\n {children}\n <svg className=\"ml-auto\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </div>\n );\n}\n\nexport function ContextMenuSubContent({ className, children, onKeyDown, ...props }: React.ComponentProps<\"div\">) {\n const ctx = React.useContext(ContextMenuSubContext);\n const ref = React.useRef<HTMLDivElement | null>(null);\n const open = ctx?.open ?? false;\n React.useEffect(() => {\n if (!open || !ctx?.focusFirst.current) return;\n ctx.focusFirst.current = false;\n ref.current?.querySelector<HTMLElement>(\"[role^='menuitem']\")?.focus();\n }, [open, ctx]);\n if (!ctx?.open) return null;\n return (\n <div\n ref={ref}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.key === \"ArrowLeft\" || e.key === \"Escape\") {\n // Closes this flyout only; Escape would otherwise reach the whole menu's dismissal.\n e.preventDefault();\n e.stopPropagation();\n ctx.setOpen(false);\n ctx.triggerRef.current?.focus();\n }\n }}\n data-slot=\"context-menu-sub-content\"\n data-state=\"open\"\n role=\"menu\"\n className={cn(\n CONTEXT_MENU_SUB_CONTENT,\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/date-time-picker.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { focusCandidates } from \"../primitives/focus-scope\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport { buttonVariants } from \"./button\";\nimport { Calendar } from \"./calendar\";\nimport { Input } from \"./input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\nimport {\n DATE_TIME_PICKER_CLEAR,\n DATE_TIME_PICKER_CONTENT,\n DATE_TIME_PICKER_TIME,\n DATE_TIME_PICKER_TIME_INPUT,\n DATE_TIME_PICKER_TIME_SEPARATOR,\n DATE_TIME_PICKER_TRIGGER,\n} from \"../generated/date-time-picker\";\n\n// lucide `calendar`, inlined per the kit's no-icon-dep convention.\nconst CALENDAR_ICON = [\n \"M8 2v4\",\n \"M16 2v4\",\n \"M3 10h18\",\n \"M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z\",\n] as const;\n\nfunction CalendarIcon() {\n return (\n <svg\n className=\"size-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n {CALENDAR_ICON.map(d => (\n <path key={d} d={d} />\n ))}\n </svg>\n );\n}\n\n// lucide `x`, inlined like every other icon in the kit.\nfunction XIcon() {\n return (\n <svg\n className=\"size-4\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n );\n}\n\nconst pad = (n: number): string => String(n).padStart(2, \"0\");\n\n// The value always carries whole minutes: seconds/ms are dropped on every write.\nfunction atMinute(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());\n}\n\n/** Inclusive clamp at minute precision. */\nfunction clampMoment(d: Date, min: Date | undefined, max: Date | undefined): Date {\n const lo = min && atMinute(min);\n const hi = max && atMinute(max);\n if (lo && d.getTime() < lo.getTime()) return lo;\n if (hi && d.getTime() > hi.getTime()) return hi;\n return d;\n}\n\n/**\n * Parses the digits an operator typed into an hours/minutes field. `null`\n * (nothing typed, or no digit at all) keeps the last value.\n *\n * The LAST two digits win: the field is controlled, so what the browser hands\n * over is the old value plus the keystroke (\"01\" + \"5\" = \"015\"), and the\n * freshest digits are the ones the operator meant.\n */\nfunction parseField(raw: string, max: number): number | null {\n const digits = raw.replace(/\\D/g, \"\").slice(-2);\n if (digits === \"\") return null;\n return Math.min(Number(digits), max);\n}\n\n// A focused field is replaced, not appended to: with the whole value selected,\n// \"1\" then \"5\" reads as 15.\nconst selectAll = (e: React.FocusEvent<HTMLInputElement>) => e.currentTarget.select();\n\nfunction isoLabel(d: Date): string {\n return `${d.getFullYear().toString().padStart(4, \"0\")}-${pad(d.getMonth() + 1)}-${pad(\n d.getDate(),\n )} ${pad(d.getHours())}:${pad(d.getMinutes())}`;\n}\n\n/** The picker's own strings; every one defaults to English. */\nexport interface DateTimePickerLabels {\n /** `aria-label` of the calendar's previous-month button; \"Previous month\". */\n previousMonth?: string;\n /** `aria-label` of the calendar's next-month button; \"Next month\". */\n nextMonth?: string;\n /** `aria-label` of the hours input; \"Hours\". */\n hours?: string;\n /** `aria-label` of the minutes input; \"Minutes\". */\n minutes?: string;\n /** Text of the clear button; \"Clear\". */\n clear?: string;\n /** `aria-label` of the popover dialog; \"Choose date and time\". */\n dialog?: string;\n /** `aria-label` of the close button; \"Close\". */\n close?: string;\n}\n\nexport interface DateTimePickerProps\n extends React.AriaAttributes,\n Pick<React.ComponentProps<\"button\">, \"onFocus\" | \"onBlur\"> {\n /** Controlled value; `null` = empty. Local-zone `Date` (seconds/ms are zeroed on every change). */\n value?: Date | null;\n /** Uncontrolled seed; default `null`. */\n defaultValue?: Date | null;\n onChange?: (value: Date | null) => void;\n /** Earliest allowed moment (inclusive, minute precision). */\n min?: Date;\n /** Latest allowed moment (inclusive, minute precision). */\n max?: Date;\n /**\n * BCP-47 tag for the trigger label and calendar captions (`Intl`). Absent →\n * `YYYY-MM-DD HH:MM` and English captions, like the Rust port.\n */\n locale?: string;\n /** Overrides the trigger label entirely (e.g. the cabinet's `formatMoment`). */\n format?: (value: Date) => string;\n /** Shown on the trigger while empty; default \"\". */\n placeholder?: string;\n labels?: DateTimePickerLabels;\n disabled?: boolean;\n /** Renders a hidden `<input name>` carrying unix seconds (\"\" when empty) for plain forms. */\n name?: string;\n /**\n * \"Today\" for the calendar highlight and as the day a typed time lands on\n * while empty; default `new Date()`.\n */\n today?: Date;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n /** `PopoverContent` alignment; default \"start\". */\n align?: \"start\" | \"center\" | \"end\";\n /** Fused onto the trigger. */\n className?: string;\n /** Put on the trigger, so a `FieldLabel`'s `htmlFor` reaches it. */\n id?: string;\n}\n\n/**\n * A date + time field over the kit's own bricks: an outline trigger opening a\n * popover with the `Calendar` and two numeric hours/minutes inputs — no native\n * `datetime-local`, so the browser's locale popup never appears.\n *\n * Every edit reports through `onChange`; the popover stays open after a day\n * click (the operator still sets the time) and closes on clear or on the close\n * button (which keeps the value). Opening moves focus into the hours field;\n * closing hands it back to the trigger unless the operator already focused\n * something else. Any other `aria-*` prop, `onFocus` and `onBlur` land on the\n * trigger.\n */\nexport function DateTimePicker({\n value: valueProp,\n defaultValue = null,\n onChange,\n min,\n max,\n locale,\n format,\n placeholder = \"\",\n labels = {},\n disabled = false,\n name,\n today = new Date(),\n open,\n defaultOpen = false,\n onOpenChange,\n align = \"start\",\n className,\n id,\n ...rest\n}: DateTimePickerProps) {\n const [value, setValue] = useControllableState<Date | null>({\n ...(valueProp !== undefined ? { value: valueProp } : {}),\n defaultValue,\n ...(onChange ? { onChange } : {}),\n });\n const [isOpen, setOpen] = useControllableState<boolean>({\n ...(open !== undefined ? { value: open } : {}),\n defaultValue: defaultOpen,\n ...(onOpenChange ? { onChange: onOpenChange } : {}),\n });\n\n const rootRef = React.useRef<HTMLDivElement | null>(null);\n const hoursRef = React.useRef<HTMLInputElement | null>(null);\n const focusTrigger = () =>\n rootRef.current?.querySelector<HTMLElement>(\"[data-slot=date-time-picker-trigger]\")?.focus();\n // The content lives in a Portal, so the native tab order would skip it.\n React.useEffect(() => {\n if (!isOpen) return;\n hoursRef.current?.focus();\n return () => {\n const active = document.activeElement;\n const content = hoursRef.current?.closest(\"[data-slot=date-time-picker-content]\");\n const lost = !active || active === document.body || !!content?.contains(active);\n if (lost) focusTrigger();\n };\n }, [isOpen]);\n\n const emit = (next: Date) => setValue(clampMoment(atMinute(next), min, max));\n // A fresh copy of the moment a typed time edits: the value, or midnight of\n // `today` while empty — never the consumer's own `Date` instance.\n const base = () =>\n value\n ? new Date(value.getTime())\n : new Date(today.getFullYear(), today.getMonth(), today.getDate());\n\n const onSelect = (day: Date) =>\n emit(\n new Date(\n day.getFullYear(),\n day.getMonth(),\n day.getDate(),\n value?.getHours() ?? 0,\n value?.getMinutes() ?? 0,\n ),\n );\n const onHours = (e: React.ChangeEvent<HTMLInputElement>) => {\n const hour = parseField(e.target.value, 23);\n if (hour === null) return;\n const next = base();\n next.setHours(hour);\n emit(next);\n };\n const onMinutes = (e: React.ChangeEvent<HTMLInputElement>) => {\n const minute = parseField(e.target.value, 59);\n if (minute === null) return;\n const next = base();\n next.setMinutes(minute);\n emit(next);\n };\n const onClear = () => {\n setValue(null);\n setOpen(false);\n };\n // The content is portalled to the end of <body>, so Tab from its last\n // control (and Shift+Tab from its first) has nowhere to go: focus falls out\n // of the document and the dialog stays open over the page. Those two edges\n // close the popover and hand focus back to the trigger — the document's tab\n // order then continues from where the operator started. Middle controls keep\n // the browser's default. Not a trap: the popover is non-modal.\n const onContentKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key !== \"Tab\") return;\n const items = focusCandidates(e.currentTarget);\n const edge = e.shiftKey ? items[0] : items[items.length - 1];\n if (!edge || e.target !== edge) return;\n e.preventDefault();\n setOpen(false);\n focusTrigger();\n };\n // Focus moving elsewhere by pointer or script (the dismissable layer only\n // watches Escape and outside pointerdown). A null `relatedTarget` is the\n // window losing focus (alt-tab), not the operator leaving: keep the popover\n // for their return. Tab-out never reaches here — `onContentKeyDown` closes\n // first.\n const onContentBlur = (e: React.FocusEvent<HTMLDivElement>) => {\n const next = e.relatedTarget;\n if (!(next instanceof Node)) return;\n if (e.currentTarget.contains(next) || rootRef.current?.contains(next)) return;\n setOpen(false);\n };\n\n const label = value\n ? format\n ? format(value)\n : locale\n ? // The fields are 24-hour, so the label is too — even where the locale\n // would default to 12-hour (\"2:05 PM\" over a \"14\" hours field).\n new Intl.DateTimeFormat(locale, {\n dateStyle: \"medium\",\n timeStyle: \"short\",\n hourCycle: \"h23\",\n }).format(value)\n : isoLabel(value)\n : placeholder;\n\n return (\n <div data-slot=\"date-time-picker\" ref={rootRef}>\n <Popover open={isOpen} onOpenChange={setOpen}>\n <PopoverTrigger\n type=\"button\"\n data-slot=\"date-time-picker-trigger\"\n data-placeholder={value ? undefined : \"true\"}\n aria-haspopup=\"dialog\"\n className={cn(\n buttonVariants({ variant: \"outline\", size: \"md\" }),\n DATE_TIME_PICKER_TRIGGER,\n className,\n )}\n disabled={disabled}\n {...(id !== undefined ? { id } : {})}\n {...rest}\n >\n <CalendarIcon />\n <span>{label}</span>\n </PopoverTrigger>\n {name !== undefined && (\n <input\n type=\"hidden\"\n name={name}\n value={value ? String(Math.floor(value.getTime() / 1000)) : \"\"}\n />\n )}\n <PopoverContent\n data-slot=\"date-time-picker-content\"\n role=\"dialog\"\n aria-label={labels.dialog ?? \"Choose date and time\"}\n align={align}\n onBlur={onContentBlur}\n onKeyDown={onContentKeyDown}\n className={DATE_TIME_PICKER_CONTENT}\n >\n <Calendar\n {...(value ? { selected: value } : {})}\n onSelect={onSelect}\n // The content remounts on every open, so this lands on the value's month.\n defaultMonth={value ?? min ?? today}\n today={today}\n disabled={disabled}\n {...(min ? { min } : {})}\n {...(max ? { max } : {})}\n {...(locale !== undefined ? { locale } : {})}\n {...(labels.previousMonth !== undefined\n ? { previousMonthLabel: labels.previousMonth }\n : {})}\n {...(labels.nextMonth !== undefined ? { nextMonthLabel: labels.nextMonth } : {})}\n />\n <div className={DATE_TIME_PICKER_TIME} data-slot=\"date-time-picker-time\">\n <Input\n type=\"text\"\n inputMode=\"numeric\"\n onFocus={selectAll}\n className={DATE_TIME_PICKER_TIME_INPUT}\n ref={hoursRef}\n data-slot=\"date-time-picker-hours\"\n aria-label={labels.hours ?? \"Hours\"}\n value={pad(value?.getHours() ?? 0)}\n disabled={disabled}\n onChange={onHours}\n />\n <span className={DATE_TIME_PICKER_TIME_SEPARATOR} aria-hidden>\n :\n </span>\n <Input\n type=\"text\"\n inputMode=\"numeric\"\n onFocus={selectAll}\n className={DATE_TIME_PICKER_TIME_INPUT}\n data-slot=\"date-time-picker-minutes\"\n aria-label={labels.minutes ?? \"Minutes\"}\n value={pad(value?.getMinutes() ?? 0)}\n disabled={disabled}\n onChange={onMinutes}\n />\n <button\n type=\"button\"\n className={buttonVariants({ variant: \"ghost\", size: \"sm\", className: DATE_TIME_PICKER_CLEAR })}\n data-slot=\"date-time-picker-clear\"\n disabled={disabled}\n onClick={onClear}\n >\n {labels.clear ?? \"Clear\"}\n </button>\n <button\n type=\"button\"\n className={buttonVariants({ variant: \"ghost\", size: \"sm\", icon: true })}\n data-slot=\"date-time-picker-close\"\n aria-label={labels.close ?? \"Close\"}\n disabled={disabled}\n onClick={() => setOpen(false)}\n >\n <XIcon />\n </button>\n </div>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport { DismissableLayerScope, useDismissableLayer, useModalScrimStyle } from \"../primitives/dismissable-layer\";\nimport { type InitialFocus, useFocusScope } from \"../primitives/focus-scope\";\nimport { usePresence } from \"../primitives/presence\";\nimport { mergeRefs } from \"../primitives/merge-refs\";\nimport { Portal } from \"../primitives/portal\";\nimport { Slot } from \"../primitives/slot\";\nimport {\n DIALOG_CLOSE,\n DIALOG_CONTENT,\n DIALOG_DESCRIPTION,\n DIALOG_FOOTER,\n DIALOG_HEADER,\n DIALOG_OVERLAY,\n DIALOG_TITLE,\n} from \"../generated/dialog\";\n\ninterface DialogContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n triggerRef: React.RefObject<HTMLElement | null>;\n /** Ids of the mounted DialogTitle / DialogDescription; unset while none is. */\n titleId: string | undefined;\n descriptionId: string | undefined;\n setTitleId: React.Dispatch<React.SetStateAction<string | undefined>>;\n setDescriptionId: React.Dispatch<React.SetStateAction<string | undefined>>;\n}\n\nconst DialogContext = React.createContext<DialogContextValue | null>(null);\n\nfunction useDialog(): DialogContextValue {\n const ctx = React.useContext(DialogContext);\n if (!ctx) throw new Error(\"Dialog parts must be used within <Dialog>\");\n return ctx;\n}\n\nexport interface DialogProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: React.ReactNode;\n}\n\nexport function Dialog({ open, defaultOpen = false, onOpenChange, children }: DialogProps) {\n const [isOpen, setOpen] = useControllableState<boolean>({\n ...(open !== undefined ? { value: open } : {}),\n defaultValue: defaultOpen,\n ...(onOpenChange ? { onChange: onOpenChange } : {}),\n });\n const triggerRef = React.useRef<HTMLElement | null>(null);\n const [titleId, setTitleId] = React.useState<string | undefined>(undefined);\n const [descriptionId, setDescriptionId] = React.useState<string | undefined>(undefined);\n return (\n <DialogContext.Provider\n value={{ open: isOpen, setOpen, triggerRef, titleId, descriptionId, setTitleId, setDescriptionId }}\n >\n {children}\n </DialogContext.Provider>\n );\n}\n\nexport interface DialogTriggerProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nexport function DialogTrigger({ asChild = false, onClick, ...props }: DialogTriggerProps) {\n const { open, setOpen, triggerRef } = useDialog();\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"dialog-trigger\"\n aria-expanded={open}\n ref={triggerRef as React.Ref<HTMLButtonElement>}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n setOpen(true);\n }}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\nexport type DialogPortalProps = { children?: React.ReactNode };\n\nexport function DialogPortal({ children }: DialogPortalProps) {\n return <>{children}</>;\n}\n\nexport interface DialogOverlayProps extends React.ComponentProps<\"div\"> {}\n\nexport function DialogOverlay({ className, ...props }: DialogOverlayProps) {\n const { open } = useDialog();\n // No onClick: the content's dismissable layer already closes on the\n // pointer-down that lands here, and a second path called onOpenChange(false)\n // twice for one press whenever the overlay was still hit by the click\n // (a host that closes later, CSS without the closed-state pointer-events).\n return (\n <div\n data-slot=\"dialog-overlay\"\n data-state={open ? \"open\" : \"closed\"}\n className={cn(DIALOG_OVERLAY, className)}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\nconst XIcon = (props: React.SVGProps<SVGSVGElement>) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <path d=\"M18 6 6 18M6 6l12 12\" />\n </svg>\n);\n\nexport interface DialogContentProps extends React.ComponentProps<\"div\"> {\n showCloseButton?: boolean;\n /** Where focus lands on open. Default `first` — a dialog is usually a short form. */\n initialFocus?: InitialFocus;\n}\n\nexport function DialogContent({\n className,\n children,\n showCloseButton = true,\n initialFocus = \"first\",\n ...props\n}: DialogContentProps) {\n const { open, setOpen, triggerRef, titleId, descriptionId } = useDialog();\n const { isPresent, ref: presRef } = usePresence(open);\n const focusRef = useFocusScope(open, { initialFocus, returnFocusTo: triggerRef });\n const dismissRef = useDismissableLayer({\n enabled: open,\n onDismiss: () => setOpen(false),\n exclude: [triggerRef],\n modal: true,\n });\n const scrimStyle = useModalScrimStyle(dismissRef);\n React.useEffect(() => {\n if (!open) return;\n const prev = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = prev;\n };\n }, [open]);\n if (!isPresent) return null;\n return (\n <Portal>\n <DialogOverlay style={scrimStyle} />\n <div\n data-slot=\"dialog-content\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={descriptionId}\n data-state={open ? \"open\" : \"closed\"}\n ref={mergeRefs(focusRef, dismissRef, presRef as React.Ref<HTMLDivElement>)}\n className={cn(DIALOG_CONTENT, className)}\n {...(props as Record<string, unknown>)}\n >\n <DismissableLayerScope layer={dismissRef}>{children}</DismissableLayerScope>\n {showCloseButton && (\n <button\n type=\"button\"\n data-slot=\"dialog-close\"\n onClick={() => setOpen(false)}\n className={DIALOG_CLOSE}\n >\n <XIcon />\n <span className=\"sr-only\">Close</span>\n </button>\n )}\n </div>\n </Portal>\n );\n}\n\nexport interface DialogCloseProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nexport function DialogClose({ asChild = false, onClick, ...props }: DialogCloseProps) {\n const { setOpen } = useDialog();\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"dialog-close\"\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n setOpen(false);\n }}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\nexport function DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(DIALOG_HEADER, className)}\n {...props}\n />\n );\n}\n\nexport function DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(DIALOG_FOOTER, className)}\n {...props}\n />\n );\n}\n\n/**\n * Announces `id` as the dialog's title or description while the part is\n * mounted. A layout effect, so the reference is in place before the first\n * paint of an opening dialog and gone with the part — DialogContent never\n * points at an id that is not in the document. Outside a Dialog there is\n * nothing to register with: the part renders as before rather than throwing,\n * since it never needed the context until now.\n */\nfunction useRegisteredId(\n own: string | undefined,\n register: React.Dispatch<React.SetStateAction<string | undefined>> | undefined,\n): string {\n const generated = React.useId();\n const id = own ?? generated;\n React.useLayoutEffect(() => {\n if (!register) return;\n register(id);\n // Clear only our own id: a title mounted after this one has already taken the slot.\n return () => register((current) => (current === id ? undefined : current));\n }, [id, register]);\n return id;\n}\n\nexport function DialogTitle({ className, id, ...props }: React.ComponentProps<\"h2\">) {\n const titleId = useRegisteredId(id, React.useContext(DialogContext)?.setTitleId);\n return (\n <h2\n id={titleId}\n data-slot=\"dialog-title\"\n className={cn(DIALOG_TITLE, className)}\n {...props}\n />\n );\n}\n\nexport function DialogDescription({ className, id, ...props }: React.ComponentProps<\"p\">) {\n const descriptionId = useRegisteredId(id, React.useContext(DialogContext)?.setDescriptionId);\n return (\n <p\n id={descriptionId}\n data-slot=\"dialog-description\"\n className={cn(DIALOG_DESCRIPTION, className)}\n {...props}\n />\n );\n}\n"],"mappings":";AAyDI,SAgCK,UAhCL,KAsHM,YAtHN;AAvDJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,4BAA4B;AACrC,SAAS,uBAAuB,qBAAqB,0BAA0B;AAC/E,SAA4B,qBAAqB;AACjD,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,YAAY;AACrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAaP,MAAM,gBAAgB,MAAM,cAAyC,IAAI;AAEzE,SAAS,YAAgC;AACvC,QAAM,MAAM,MAAM,WAAW,aAAa;AAC1C,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,2CAA2C;AACrE,SAAO;AACT;AASO,SAAS,OAAO,EAAE,MAAM,cAAc,OAAO,cAAc,SAAS,GAAgB;AACzF,QAAM,CAAC,QAAQ,OAAO,IAAI,qBAA8B;AAAA,IACtD,GAAI,SAAS,SAAY,EAAE,OAAO,KAAK,IAAI,CAAC;AAAA,IAC5C,cAAc;AAAA,IACd,GAAI,eAAe,EAAE,UAAU,aAAa,IAAI,CAAC;AAAA,EACnD,CAAC;AACD,QAAM,aAAa,MAAM,OAA2B,IAAI;AACxD,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAA6B,MAAS;AAC1E,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM,SAA6B,MAAS;AACtF,SACE;AAAA,IAAC,cAAc;AAAA,IAAd;AAAA,MACC,OAAO,EAAE,MAAM,QAAQ,SAAS,YAAY,SAAS,eAAe,YAAY,iBAAiB;AAAA,MAEhG;AAAA;AAAA,EACH;AAEJ;AAMO,SAAS,cAAc,EAAE,UAAU,OAAO,SAAS,GAAG,MAAM,GAAuB;AACxF,QAAM,EAAE,MAAM,SAAS,WAAW,IAAI,UAAU;AAChD,QAAM,OAAO,UAAU,OAAO;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,iBAAe;AAAA,MACf,KAAK;AAAA,MACL,SAAS,CAAC,MAA2C;AACnD,kBAAU,CAAC;AACX,gBAAQ,IAAI;AAAA,MACd;AAAA,MACC,GAAI;AAAA;AAAA,EACP;AAEJ;AAIO,SAAS,aAAa,EAAE,SAAS,GAAsB;AAC5D,SAAO,gCAAG,UAAS;AACrB;AAIO,SAAS,cAAc,EAAE,WAAW,GAAG,MAAM,GAAuB;AACzE,QAAM,EAAE,KAAK,IAAI,UAAU;AAK3B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,cAAY,OAAO,SAAS;AAAA,MAC5B,WAAW,GAAG,gBAAgB,SAAS;AAAA,MACtC,GAAI;AAAA;AAAA,EACP;AAEJ;AAEA,MAAM,QAAQ,CAAC,UACb;AAAA,EAAC;AAAA;AAAA,IACC,OAAM;AAAA,IACN,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,QAAO;AAAA,IACP,aAAY;AAAA,IACZ,eAAc;AAAA,IACd,gBAAe;AAAA,IACd,GAAG;AAAA,IAEJ,8BAAC,UAAK,GAAE,wBAAuB;AAAA;AACjC;AASK,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,GAAG;AACL,GAAuB;AACrB,QAAM,EAAE,MAAM,SAAS,YAAY,SAAS,cAAc,IAAI,UAAU;AACxE,QAAM,EAAE,WAAW,KAAK,QAAQ,IAAI,YAAY,IAAI;AACpD,QAAM,WAAW,cAAc,MAAM,EAAE,cAAc,eAAe,WAAW,CAAC;AAChF,QAAM,aAAa,oBAAoB;AAAA,IACrC,SAAS;AAAA,IACT,WAAW,MAAM,QAAQ,KAAK;AAAA,IAC9B,SAAS,CAAC,UAAU;AAAA,IACpB,OAAO;AAAA,EACT,CAAC;AACD,QAAM,aAAa,mBAAmB,UAAU;AAChD,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,SAAS,KAAK,MAAM;AACjC,aAAS,KAAK,MAAM,WAAW;AAC/B,WAAO,MAAM;AACX,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AACT,MAAI,CAAC,UAAW,QAAO;AACvB,SACE,qBAAC,UACC;AAAA,wBAAC,iBAAc,OAAO,YAAY;AAAA,IAClC;AAAA,MAAC;AAAA;AAAA,QACC,aAAU;AAAA,QACV,MAAK;AAAA,QACL,cAAW;AAAA,QACX,mBAAiB;AAAA,QACjB,oBAAkB;AAAA,QAClB,cAAY,OAAO,SAAS;AAAA,QAC5B,KAAK,UAAU,UAAU,YAAY,OAAoC;AAAA,QACzE,WAAW,GAAG,gBAAgB,SAAS;AAAA,QACtC,GAAI;AAAA,QAEL;AAAA,8BAAC,yBAAsB,OAAO,YAAa,UAAS;AAAA,UACnD,mBACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,aAAU;AAAA,cACV,SAAS,MAAM,QAAQ,KAAK;AAAA,cAC5B,WAAW;AAAA,cAEX;AAAA,oCAAC,SAAM;AAAA,gBACP,oBAAC,UAAK,WAAU,WAAU,mBAAK;AAAA;AAAA;AAAA,UACjC;AAAA;AAAA;AAAA,IAEJ;AAAA,KACF;AAEJ;AAMO,SAAS,YAAY,EAAE,UAAU,OAAO,SAAS,GAAG,MAAM,GAAqB;AACpF,QAAM,EAAE,QAAQ,IAAI,UAAU;AAC9B,QAAM,OAAO,UAAU,OAAO;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,SAAS,CAAC,MAA2C;AACnD,kBAAU,CAAC;AACX,gBAAQ,KAAK;AAAA,MACf;AAAA,MACC,GAAI;AAAA;AAAA,EACP;AAEJ;AAEO,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAgC;AACjF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,SAAS;AAAA,MACrC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAgC;AACjF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,SAAS;AAAA,MACrC,GAAG;AAAA;AAAA,EACN;AAEJ;AAUA,SAAS,gBACP,KACA,UACQ;AACR,QAAM,YAAY,MAAM,MAAM;AAC9B,QAAM,KAAK,OAAO;AAClB,QAAM,gBAAgB,MAAM;AAC1B,QAAI,CAAC,SAAU;AACf,aAAS,EAAE;AAEX,WAAO,MAAM,SAAS,CAAC,YAAa,YAAY,KAAK,SAAY,OAAQ;AAAA,EAC3E,GAAG,CAAC,IAAI,QAAQ,CAAC;AACjB,SAAO;AACT;AAEO,SAAS,YAAY,EAAE,WAAW,IAAI,GAAG,MAAM,GAA+B;AACnF,QAAM,UAAU,gBAAgB,IAAI,MAAM,WAAW,aAAa,GAAG,UAAU;AAC/E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,IAAI;AAAA,MACJ,aAAU;AAAA,MACV,WAAW,GAAG,cAAc,SAAS;AAAA,MACpC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,kBAAkB,EAAE,WAAW,IAAI,GAAG,MAAM,GAA8B;AACxF,QAAM,gBAAgB,gBAAgB,IAAI,MAAM,WAAW,aAAa,GAAG,gBAAgB;AAC3F,SACE;AAAA,IAAC;AAAA;AAAA,MACC,IAAI;AAAA,MACJ,aAAU;AAAA,MACV,WAAW,GAAG,oBAAoB,SAAS;AAAA,MAC1C,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/drawer.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport { DismissableLayerScope, useDismissableLayer, useModalScrimStyle } from \"../primitives/dismissable-layer\";\nimport { useFocusScope } from \"../primitives/focus-scope\";\nimport { mergeRefs } from \"../primitives/merge-refs\";\nimport { Portal } from \"../primitives/portal\";\nimport { Slot } from \"../primitives/slot\";\nimport {\n DRAWER_BODY,\n DRAWER_CONTENT_BASE,\n DRAWER_DESCRIPTION,\n DRAWER_FOOTER,\n DRAWER_HANDLE,\n DRAWER_HEADER,\n DRAWER_OVERLAY,\n DRAWER_TITLE,\n drawerDirectionClasses,\n type DrawerDirection,\n} from \"../generated/drawer\";\n\nexport type { DrawerDirection };\n\n// Drag-to-dismiss tuning (pointer physics, TS-only — Rust stays render-only).\n// Values from Vaul: a release past 25% of the panel's size along the drag\n// axis, or a flick faster than 0.4px/ms, closes; anything short snaps back.\n// Drags are refused for the first 500ms after opening so the enter finishes.\nconst CLOSE_THRESHOLD = 0.25;\nconst VELOCITY_THRESHOLD = 0.4;\nconst DRAG_AFTER_OPEN_MS = 500;\n// The closing node is dropped on its exit `transitionend`; this is the safety\n// net for when that never fires (display:none ancestor, tab hidden, a full\n// drag that left the panel exactly at its off-screen transform). Just past\n// the 500ms transition in motion.css.\nconst EXIT_FALLBACK_MS = 600;\n\ninterface DrawerContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n direction: DrawerDirection;\n triggerRef: React.RefObject<HTMLElement | null>;\n}\n\nconst DrawerContext = React.createContext<DrawerContextValue | null>(null);\n\nfunction useDrawer(): DrawerContextValue {\n const ctx = React.useContext(DrawerContext);\n if (!ctx) throw new Error(\"Drawer parts must be used within <Drawer>\");\n return ctx;\n}\n\nexport interface DrawerProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n direction?: DrawerDirection;\n children?: React.ReactNode;\n}\n\nexport function Drawer({\n open,\n defaultOpen = false,\n onOpenChange,\n direction = \"bottom\",\n children,\n}: DrawerProps) {\n const [isOpen, setOpen] = useControllableState<boolean>({\n ...(open !== undefined ? { value: open } : {}),\n defaultValue: defaultOpen,\n ...(onOpenChange ? { onChange: onOpenChange } : {}),\n });\n const triggerRef = React.useRef<HTMLElement | null>(null);\n return (\n <DrawerContext.Provider value={{ open: isOpen, setOpen, direction, triggerRef }}>\n <div data-slot=\"drawer\">{children}</div>\n </DrawerContext.Provider>\n );\n}\n\nexport interface DrawerTriggerProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nexport function DrawerTrigger({ asChild = false, onClick, ...props }: DrawerTriggerProps) {\n const { setOpen, triggerRef } = useDrawer();\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"drawer-trigger\"\n ref={triggerRef as React.Ref<HTMLButtonElement>}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n setOpen(true);\n }}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\nexport interface DrawerCloseProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nexport function DrawerClose({ asChild = false, onClick, ...props }: DrawerCloseProps) {\n const { setOpen } = useDrawer();\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"drawer-close\"\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n setOpen(false);\n }}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\n/**\n * Standalone scrim, redundant with the one {@link DrawerContent} renders (as in\n * shadcn). Mounted only while open; the animated exit lives on the content's\n * own scrim.\n */\nexport function DrawerOverlay({ className, ...props }: React.ComponentProps<\"div\">) {\n const { open, setOpen } = useDrawer();\n if (!open) return null;\n return (\n <div\n data-slot=\"drawer-overlay\"\n data-state=\"open\"\n onClick={() => setOpen(false)}\n className={cn(DRAWER_OVERLAY, className)}\n {...props}\n />\n );\n}\n\n// Positive delta = the finger moved towards the docked edge (bottom: down,\n// top: up, right: right, left: left), i.e. the closing direction.\nconst EDGE_SIGN: Record<DrawerDirection, 1 | -1> = {\n bottom: 1,\n top: -1,\n right: 1,\n left: -1,\n};\n\nfunction isVertical(direction: DrawerDirection): boolean {\n return direction === \"bottom\" || direction === \"top\";\n}\n\nfunction translateAlong(direction: DrawerDirection, px: number): string {\n return isVertical(direction) ? `translate3d(0, ${px}px, 0)` : `translate3d(${px}px, 0, 0)`;\n}\n\n// Vaul's over-drag curve: the panel barely moves past its docked edge. Only\n// starts displacing once the finger has gone ~6px (log(v + 1) > 2); before\n// that the curve is negative, which reads as \"stay home\".\nfunction dampen(px: number): number {\n return Math.max(8 * (Math.log(px + 1) - 2), 0);\n}\n\n// Vaul's `shouldDrag`, minus snap points. `towardsEdge` false = the user is\n// pulling the panel further open, which on a vertical sheet is the scroll\n// gesture — hand it to the scroller. The scroll walk is vertical-only: a\n// horizontal sheet never competes with its body's vertical scroll.\nfunction shouldDrag(\n target: EventTarget | null,\n panel: HTMLElement,\n direction: DrawerDirection,\n towardsEdge: boolean,\n): boolean {\n if (!(target instanceof Element)) return false;\n if (target.tagName === \"SELECT\") return false; // https://github.com/emilkowalski/vaul/issues/483\n if (target.closest(\"[data-vaul-no-drag]\")) return false;\n if (!isVertical(direction)) return true;\n if (!towardsEdge) return false;\n const selection = window.getSelection?.()?.toString();\n if (selection && selection.length > 0) return false;\n // any scroller between the finger and the panel that isn't at its top owns\n // the gesture; the user can scroll up and the next move re-asks\n let el: Element | null = target;\n while (el && el !== panel) {\n if (el.scrollHeight > el.clientHeight && el.scrollTop > 0) return false;\n el = el.parentElement;\n }\n return true;\n}\n\ninterface DragGesture {\n pointerId: number;\n // the element under the finger at pointerdown — once the panel captures the\n // pointer, every later event's `target` is the panel itself, and the scroll\n // walk in `shouldDrag` would never see the scroller it started in\n target: EventTarget | null;\n start: number; // clientX/Y along the axis\n time: number;\n size: number; // panel extent along the axis, for the close threshold + scrim fade\n allowed: boolean | null; // null = undecided; true sticks for the gesture (Vaul's isAllowedToDrag)\n delta: number;\n}\n\n// ── drag-to-dismiss (Vaul pointer physics) ────────────────────────────────\n// No React state on the hot path: the gesture lives in a ref and every move is\n// one inline `transform` write on the panel plus one `opacity` write on the\n// scrim. Not a CSS var: a custom-property change re-resolves inherited values\n// across the whole subtree, per move.\nfunction useDrawerDrag(opts: {\n panelRef: React.RefObject<HTMLDivElement | null>;\n scrimRef: React.RefObject<HTMLDivElement | null>;\n direction: DrawerDirection;\n open: boolean;\n present: boolean;\n openedAtRef: React.RefObject<number>;\n onClose: () => void;\n}) {\n const { panelRef, scrimRef, direction, open, present, openedAtRef, onClose } = opts;\n const dragRef = React.useRef<DragGesture | null>(null);\n\n // Native scroll suppression. Once a gesture is allowed, the browser must not\n // turn the same touch into a scroll/overscroll of a body sitting at its top —\n // that would pointercancel us mid-drag. Pointer events precede the compat\n // touch events, so `allowed` is already decided when this runs. React's\n // onTouchMove is passive, hence the manual listener.\n React.useEffect(() => {\n if (!present) return;\n const panel = panelRef.current;\n if (!panel) return;\n const onTouchMove = (e: TouchEvent) => {\n if (dragRef.current?.allowed) e.preventDefault();\n };\n panel.addEventListener(\"touchmove\", onTouchMove, { passive: false });\n return () => panel.removeEventListener(\"touchmove\", onTouchMove);\n }, [present, panelRef]);\n\n const axisPos = (e: React.PointerEvent) => (isVertical(direction) ? e.clientY : e.clientX);\n\n const onPointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n const panel = panelRef.current;\n // one gesture at a time: a second finger must not reset the first one's\n // state and leave the panel stranded mid-drag\n if (!panel || e.button > 0 || !open || dragRef.current) return;\n const target = e.target as HTMLElement;\n if (target.closest('[data-slot=\"drawer-close\"]')) return;\n // React bubbles portal events (a Select's listbox, a Popover) through the\n // tree; a drag can only start from the panel's own DOM\n if (!panel.contains(target)) return;\n const rect = panel.getBoundingClientRect();\n dragRef.current = {\n pointerId: e.pointerId,\n target,\n start: axisPos(e),\n time: Date.now(),\n size: isVertical(direction) ? rect.height : rect.width,\n allowed: null,\n delta: 0,\n };\n // Capture on the element under the finger, not the panel (Vaul does the\n // same): a click's target is the common ancestor of pointerdown and\n // pointerup, so capturing on the panel would steal every click from the\n // buttons and links inside. No preventDefault either — inputs inside the\n // sheet must still focus on tap.\n try {\n target.setPointerCapture?.(e.pointerId);\n } catch {\n // jsdom / unsupported — capture is a nice-to-have, the drag works without it\n }\n };\n\n const onPointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n const drag = dragRef.current;\n const panel = panelRef.current;\n if (!drag || !panel) return;\n const delta = (axisPos(e) - drag.start) * EDGE_SIGN[direction];\n drag.delta = delta;\n if (!drag.allowed) {\n if (Date.now() - openedAtRef.current < DRAG_AFTER_OPEN_MS) return;\n // refused on this move only — the user may scroll the body to its top\n // and carry on, so the gesture stays alive\n if (!shouldDrag(drag.target, panel, direction, delta > 0)) return;\n drag.allowed = true;\n panel.setAttribute(\"data-dragging\", \"true\"); // CSS drops the transitions for 1:1 tracking\n scrimRef.current?.setAttribute(\"data-dragging\", \"true\");\n }\n const scrim = scrimRef.current;\n if (delta < 0) {\n panel.style.transform = translateAlong(direction, -dampen(-delta) * EDGE_SIGN[direction]);\n if (scrim) scrim.style.opacity = \"1\";\n return;\n }\n panel.style.transform = translateAlong(direction, delta * EDGE_SIGN[direction]);\n if (scrim) {\n scrim.style.opacity = `${Math.min(1, Math.max(0, 1 - delta / drag.size))}`;\n }\n };\n\n // Release hands styling back to the CSS: with the inline transform gone and\n // data-dragging cleared in the same frame, the restored transition carries\n // the panel from wherever the finger left it — home on a snap-back, or (with\n // data-state=closed committed by `onClose` in the same frame) straight off.\n const endGesture = (e: React.PointerEvent<HTMLDivElement>, cancelled: boolean) => {\n const drag = dragRef.current;\n const panel = panelRef.current;\n if (!drag || !panel || e.pointerId !== drag.pointerId) return;\n dragRef.current = null;\n try {\n (drag.target as HTMLElement).releasePointerCapture?.(drag.pointerId);\n } catch {\n // jsdom / unsupported\n }\n if (!drag.allowed) return;\n panel.removeAttribute(\"data-dragging\");\n panel.style.transform = \"\";\n const scrim = scrimRef.current;\n if (scrim) {\n scrim.removeAttribute(\"data-dragging\");\n scrim.style.opacity = \"\";\n }\n if (cancelled || drag.delta <= 0) return;\n const dt = Date.now() - drag.time;\n const velocity = dt > 0 ? drag.delta / dt : 0;\n if (velocity > VELOCITY_THRESHOLD || drag.delta >= drag.size * CLOSE_THRESHOLD) {\n onClose();\n }\n };\n\n return {\n onPointerDown,\n onPointerMove,\n onPointerUp: (e: React.PointerEvent<HTMLDivElement>) => endGesture(e, false),\n onPointerCancel: (e: React.PointerEvent<HTMLDivElement>) => endGesture(e, true),\n };\n}\n\n/**\n * The panel plus its scrim. Presence outlives `open`: once it turns false the\n * panel flips to `data-state=\"closed\"` and is unmounted when its exit\n * `transform` transition ends (or the fallback timer fires). Re-opening\n * mid-exit just flips the state back and the same transition carries the\n * panel home. Drag-to-dismiss is TS-only pointer physics; opt a region out\n * with `data-vaul-no-drag`.\n */\nexport function DrawerContent({ className, children, ...props }: React.ComponentProps<\"div\">) {\n const { open, setOpen, direction, triggerRef } = useDrawer();\n // Derived during render so the panel is in the same commit that opened it —\n // the enter keyframe plays on insertion, no mount flip needed.\n const [present, setPresent] = React.useState(open);\n if (open && !present) setPresent(true);\n const closing = present && !open;\n\n const scopeRef = useFocusScope(open, { returnFocusTo: triggerRef });\n const panelRef = React.useRef<HTMLDivElement | null>(null);\n const scrimRef = React.useRef<HTMLDivElement | null>(null);\n const openedAtRef = React.useRef(0);\n\n React.useEffect(() => {\n if (open) openedAtRef.current = Date.now();\n }, [open]);\n\n React.useEffect(() => {\n if (!open) return;\n const prev = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n return () => {\n document.body.style.overflow = prev;\n };\n }, [open]);\n\n // Safety net for a missed exit transitionend; the cleanup is what cancels it\n // on re-open.\n React.useEffect(() => {\n if (!closing) return;\n const id = setTimeout(() => setPresent(false), EXIT_FALLBACK_MS);\n return () => clearTimeout(id);\n }, [closing]);\n\n const drag = useDrawerDrag({\n panelRef,\n scrimRef,\n direction,\n open,\n present,\n openedAtRef,\n onClose: () => setOpen(false),\n });\n\n // On the stack for Escape, and modal so the layers below ignore every press\n // while it is open — its scrim included. Outside clicks stay with the scrim:\n // it covers everything but the layers above, so a press on a toast or a\n // nested Dialog's backdrop is not a click away from the Drawer.\n const dismissRef = useDismissableLayer({\n enabled: open,\n onDismiss: () => setOpen(false),\n pointerOutside: false,\n modal: true,\n });\n const scrimStyle = useModalScrimStyle(dismissRef);\n\n if (!present) return null;\n const state = closing ? \"closed\" : \"open\";\n return (\n <Portal>\n <div\n ref={scrimRef}\n data-slot=\"drawer-overlay\"\n data-state={state}\n className={DRAWER_OVERLAY}\n style={scrimStyle}\n onClick={() => setOpen(false)}\n />\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n data-slot=\"drawer-content\"\n data-state={state}\n data-vaul-drawer-direction={direction}\n ref={mergeRefs(scopeRef, panelRef, dismissRef)}\n // transitionend bubbles from children (a hover on a button inside),\n // so pin it to the panel's own exit transform\n onTransitionEnd={(e) => {\n if (closing && e.propertyName === \"transform\" && e.target === e.currentTarget) {\n setPresent(false);\n }\n }}\n onPointerDown={drag.onPointerDown}\n onPointerMove={drag.onPointerMove}\n onPointerUp={drag.onPointerUp}\n onPointerCancel={drag.onPointerCancel}\n className={cn(DRAWER_CONTENT_BASE, drawerDirectionClasses[direction], className)}\n {...(props as Record<string, unknown>)}\n >\n {direction === \"bottom\" ? (\n <div\n data-slot=\"drawer-handle\"\n className={DRAWER_HANDLE}\n />\n ) : null}\n <div\n data-slot=\"drawer-body\"\n className={DRAWER_BODY}\n >\n <DismissableLayerScope layer={dismissRef}>{children}</DismissableLayerScope>\n </div>\n </div>\n </Portal>\n );\n}\n\nexport function DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-header\"\n className={cn(DRAWER_HEADER, className)}\n {...props}\n />\n );\n}\n\nexport function DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-footer\"\n className={cn(DRAWER_FOOTER, className)}\n {...props}\n />\n );\n}\n\nexport function DrawerTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-title\"\n className={cn(DRAWER_TITLE, className)}\n {...props}\n />\n );\n}\n\nexport function DrawerDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"drawer-description\"\n className={cn(DRAWER_DESCRIPTION, className)}\n {...props}\n />\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/dropdown-menu.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport { useFloating } from \"../primitives/use-floating\";\nimport { DismissableLayerScope, useDismissableLayer } from \"../primitives/dismissable-layer\";\nimport { usePresence } from \"../primitives/presence\";\nimport { useRovingFocus } from \"../primitives/use-roving-focus\";\nimport { useHoverIntent } from \"../primitives/use-hover-intent\";\nimport { mergeRefs } from \"../primitives/merge-refs\";\nimport { Portal } from \"../primitives/portal\";\nimport { Slot } from \"../primitives/slot\";\nimport {\n DROPDOWN_MENU_CHECK_ITEM,\n DROPDOWN_MENU_CONTENT,\n DROPDOWN_MENU_ITEM,\n DROPDOWN_MENU_ITEM_INDICATOR,\n DROPDOWN_MENU_LABEL,\n DROPDOWN_MENU_SEPARATOR,\n DROPDOWN_MENU_SHORTCUT,\n DROPDOWN_MENU_SUB_CONTENT,\n DROPDOWN_MENU_SUB_TRIGGER,\n} from \"../generated/dropdown-menu\";\n\ninterface DropdownMenuContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n anchorRef: React.RefObject<HTMLElement | null>;\n}\n\nconst DropdownMenuContext = React.createContext<DropdownMenuContextValue | null>(\n null,\n);\n\nfunction useDropdownMenu(): DropdownMenuContextValue {\n const ctx = React.useContext(DropdownMenuContext);\n if (!ctx) throw new Error(\"DropdownMenu parts must be used within <DropdownMenu>\");\n return ctx;\n}\n\nexport interface DropdownMenuProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: React.ReactNode;\n}\n\nexport function DropdownMenu({ open, defaultOpen = false, onOpenChange, children }: DropdownMenuProps) {\n const [isOpen, setOpen] = useControllableState<boolean>({\n ...(open !== undefined ? { value: open } : {}),\n defaultValue: defaultOpen,\n ...(onOpenChange ? { onChange: onOpenChange } : {}),\n });\n const anchorRef = React.useRef<HTMLElement | null>(null);\n return (\n <DropdownMenuContext.Provider value={{ open: isOpen, setOpen, anchorRef }}>\n <div data-slot=\"dropdown-menu\">{children}</div>\n </DropdownMenuContext.Provider>\n );\n}\n\nexport function DropdownMenuPortal({ children }: { children?: React.ReactNode }) {\n return <Portal>{children}</Portal>;\n}\n\nexport interface DropdownMenuTriggerProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n}\n\nexport function DropdownMenuTrigger({ asChild = false, onClick, ...props }: DropdownMenuTriggerProps) {\n const { open, setOpen, anchorRef } = useDropdownMenu();\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"dropdown-menu-trigger\"\n aria-haspopup=\"menu\"\n aria-expanded={open}\n data-state={open ? \"open\" : \"closed\"}\n ref={anchorRef as React.Ref<HTMLButtonElement>}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n setOpen(!open);\n }}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\nexport interface DropdownMenuContentProps extends React.ComponentProps<\"div\"> {\n sideOffset?: number;\n align?: \"start\" | \"center\" | \"end\";\n}\n\nexport function DropdownMenuContent({\n className,\n sideOffset = 4,\n align = \"start\",\n children,\n ...props\n}: DropdownMenuContentProps) {\n const { open, setOpen, anchorRef } = useDropdownMenu();\n const { isPresent, ref: presRef } = usePresence(open);\n const { floatingRef, style, side } = useFloating({\n anchorRef,\n open,\n side: \"bottom\",\n align,\n offset: sideOffset,\n });\n const dismissRef = useDismissableLayer({\n enabled: open,\n onDismiss: () => setOpen(false),\n exclude: [anchorRef],\n });\n const contentRef = React.useRef<HTMLDivElement | null>(null);\n // Roving focus across rendered menu items: ArrowUp/Down move the active item.\n const items = () =>\n Array.from(\n contentRef.current?.querySelectorAll<HTMLElement>(\"[role^='menuitem']\") ?? [],\n ).filter((el) => el.getAttribute(\"data-disabled\") === null);\n const { activeIndex, setActiveIndex, onKeyDown: rovingKeyDown } = useRovingFocus({\n count: () => items().length,\n orientation: \"vertical\",\n loop: true,\n });\n // Reset on close: a menu reopens on its first item, and an index left past\n // the end (items gone while closed) would focus nothing.\n React.useEffect(() => {\n if (!open) setActiveIndex(0);\n }, [open, setActiveIndex]);\n React.useEffect(() => {\n if (!open) return;\n items()[activeIndex]?.focus();\n }, [open, activeIndex]);\n // Give focus back to the trigger on close, as Popover and Dialog do. Skipped when focus already\n // went somewhere real (an item opened a dialog, an outside click landed on an input).\n const wasOpen = React.useRef(false);\n React.useEffect(() => {\n if (open) {\n wasOpen.current = true;\n return;\n }\n if (!wasOpen.current) return;\n wasOpen.current = false;\n const active = document.activeElement;\n if (!active || active === document.body || contentRef.current?.contains(active)) anchorRef.current?.focus();\n }, [open, anchorRef]);\n // Selecting an item closes the menu: items call this through context.\n const close = React.useCallback(() => setOpen(false), [setOpen]);\n if (!isPresent) return null;\n return (\n <Portal>\n <DropdownMenuCloseContext.Provider value={close}>\n <div\n data-slot=\"dropdown-menu-content\"\n data-state={open ? \"open\" : \"closed\"}\n data-side={side}\n role=\"menu\"\n tabIndex={-1}\n // Escape is the stack's (useDismissableLayer): it closes this menu\n // only while it is the top layer.\n onKeyDown={rovingKeyDown}\n ref={mergeRefs(floatingRef, dismissRef, presRef, contentRef)}\n style={style}\n className={cn(\n DROPDOWN_MENU_CONTENT,\n className,\n )}\n {...(props as Record<string, unknown>)}\n >\n <DismissableLayerScope layer={dismissRef}>{children}</DismissableLayerScope>\n </div>\n </DropdownMenuCloseContext.Provider>\n </Portal>\n );\n}\n\nconst DropdownMenuCloseContext = React.createContext<() => void>(() => {});\n\nexport function DropdownMenuGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div data-slot=\"dropdown-menu-group\" role=\"group\" className={className} {...props} />;\n}\n\nexport interface DropdownMenuItemProps extends React.ComponentProps<\"div\"> {\n /** Render the child (a link) as the item. */\n asChild?: boolean;\n inset?: boolean;\n variant?: \"neutral\" | \"destructive\";\n disabled?: boolean;\n}\n\nexport function DropdownMenuItem({\n asChild = false,\n className,\n inset,\n variant = \"neutral\",\n disabled,\n onClick,\n onKeyDown,\n ...props\n}: DropdownMenuItemProps) {\n const close = React.useContext(DropdownMenuCloseContext);\n const Comp = asChild ? Slot : \"div\";\n return (\n <Comp\n data-slot=\"dropdown-menu-item\"\n data-inset={inset ? \"\" : undefined}\n data-variant={variant}\n data-disabled={disabled ? \"\" : undefined}\n role=\"menuitem\"\n tabIndex={disabled ? undefined : -1}\n className={cn(\n DROPDOWN_MENU_ITEM,\n className,\n )}\n onClick={(e) => {\n if (disabled) return;\n onClick?.(e);\n close();\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n (e.currentTarget as HTMLElement).click();\n }\n }}\n {...props}\n />\n );\n}\n\nexport interface DropdownMenuCheckboxItemProps extends React.ComponentProps<\"div\"> {\n checked?: boolean;\n disabled?: boolean;\n}\n\nexport function DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n disabled,\n onClick,\n onKeyDown,\n ...props\n}: DropdownMenuCheckboxItemProps) {\n // No close: several boxes can be toggled in one visit. Escape or an outside click ends it.\n return (\n <div\n data-slot=\"dropdown-menu-checkbox-item\"\n role=\"menuitemcheckbox\"\n aria-checked={checked}\n data-state={checked ? \"checked\" : \"unchecked\"}\n data-disabled={disabled ? \"\" : undefined}\n tabIndex={disabled ? undefined : -1}\n className={cn(\n DROPDOWN_MENU_CHECK_ITEM,\n className,\n )}\n onClick={(e) => {\n if (disabled) return;\n onClick?.(e);\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n (e.currentTarget as HTMLElement).click();\n }\n }}\n {...props}\n >\n <span className={DROPDOWN_MENU_ITEM_INDICATOR}>\n {checked ? (\n <svg className=\"size-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M20 6 9 17l-5-5\" />\n </svg>\n ) : null}\n </span>\n {children}\n </div>\n );\n}\n\ninterface DropdownMenuRadioGroupContextValue {\n value: string | undefined;\n setValue: (next: string) => void;\n}\n\nconst DropdownMenuRadioGroupContext =\n React.createContext<DropdownMenuRadioGroupContextValue | null>(null);\n\nexport interface DropdownMenuRadioGroupProps extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n value?: string;\n onValueChange?: (value: string) => void;\n}\n\nexport function DropdownMenuRadioGroup({\n className,\n value,\n onValueChange,\n children,\n ...props\n}: DropdownMenuRadioGroupProps) {\n const ctx = React.useMemo<DropdownMenuRadioGroupContextValue>(\n () => ({ value, setValue: (next) => onValueChange?.(next) }),\n [value, onValueChange],\n );\n return (\n <DropdownMenuRadioGroupContext.Provider value={ctx}>\n <div data-slot=\"dropdown-menu-radio-group\" role=\"group\" className={className} {...props}>\n {children}\n </div>\n </DropdownMenuRadioGroupContext.Provider>\n );\n}\n\nexport interface DropdownMenuRadioItemProps extends React.ComponentProps<\"div\"> {\n value: string;\n disabled?: boolean;\n}\n\nexport function DropdownMenuRadioItem({\n className,\n children,\n value,\n disabled,\n onClick,\n ...props\n}: DropdownMenuRadioItemProps) {\n const close = React.useContext(DropdownMenuCloseContext);\n const group = React.useContext(DropdownMenuRadioGroupContext);\n const checked = group?.value === value;\n return (\n <div\n data-slot=\"dropdown-menu-radio-item\"\n role=\"menuitemradio\"\n aria-checked={checked}\n data-state={checked ? \"checked\" : \"unchecked\"}\n data-disabled={disabled ? \"\" : undefined}\n tabIndex={disabled ? undefined : -1}\n className={cn(\n DROPDOWN_MENU_CHECK_ITEM,\n className,\n )}\n onClick={(e) => {\n if (disabled) return;\n onClick?.(e);\n group?.setValue(value);\n close();\n }}\n {...props}\n >\n <span className={DROPDOWN_MENU_ITEM_INDICATOR}>\n {checked ? (\n <svg className=\"size-2 fill-current\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n </svg>\n ) : null}\n </span>\n {children}\n </div>\n );\n}\n\nexport interface DropdownMenuLabelProps extends React.ComponentProps<\"div\"> {\n inset?: boolean;\n}\n\nexport function DropdownMenuLabel({ className, inset, ...props }: DropdownMenuLabelProps) {\n return (\n <div\n data-slot=\"dropdown-menu-label\"\n data-inset={inset ? \"\" : undefined}\n className={cn(DROPDOWN_MENU_LABEL, className)}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"dropdown-menu-separator\"\n role=\"separator\"\n className={cn(DROPDOWN_MENU_SEPARATOR, className)}\n {...props}\n />\n );\n}\n\nexport function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(DROPDOWN_MENU_SHORTCUT, className)}\n {...props}\n />\n );\n}\n\n// Sub-menus render inline (nested) rather than in a separate floating layer: the\n// sub-content is revealed in place when its trigger toggles, simplifying the\n// nesting Radix portals each level. data-state still reflects open/closed.\ninterface DropdownMenuSubContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n triggerRef: React.RefObject<HTMLDivElement | null>;\n /** Set by a keyboard open, so the first item takes focus; a pointer open leaves focus alone. */\n focusFirst: React.RefObject<boolean>;\n}\n\nconst DropdownMenuSubContext = React.createContext<DropdownMenuSubContextValue | null>(null);\n\nexport interface DropdownMenuSubProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: React.ReactNode;\n}\n\nexport function DropdownMenuSub({ open, defaultOpen = false, onOpenChange, children }: DropdownMenuSubProps) {\n const [isOpen, setOpen] = useControllableState<boolean>({\n ...(open !== undefined ? { value: open } : {}),\n defaultValue: defaultOpen,\n ...(onOpenChange ? { onChange: onOpenChange } : {}),\n });\n const triggerRef = React.useRef<HTMLDivElement | null>(null);\n const focusFirst = React.useRef(false);\n // On the wrapper, which holds the trigger and the flyout, so crossing from one to the other is not \"leaving\".\n const hover = useHoverIntent({\n onOpen: () => setOpen(true),\n onClose: () => setOpen(false),\n openDelay: 100,\n closeDelay: 150,\n });\n return (\n <DropdownMenuSubContext.Provider value={{ open: isOpen, setOpen, triggerRef, focusFirst }}>\n <div data-slot=\"dropdown-menu-sub\" {...hover}>\n {children}\n </div>\n </DropdownMenuSubContext.Provider>\n );\n}\n\nexport interface DropdownMenuSubTriggerProps extends React.ComponentProps<\"div\"> {\n inset?: boolean;\n}\n\nexport function DropdownMenuSubTrigger({\n className,\n inset,\n children,\n onClick,\n onKeyDown,\n ...props\n}: DropdownMenuSubTriggerProps) {\n const ctx = React.useContext(DropdownMenuSubContext);\n return (\n <div\n ref={ctx?.triggerRef}\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset ? \"\" : undefined}\n data-state={ctx?.open ? \"open\" : \"closed\"}\n role=\"menuitem\"\n aria-haspopup=\"menu\"\n aria-expanded={ctx?.open}\n tabIndex={-1}\n className={cn(\n DROPDOWN_MENU_SUB_TRIGGER,\n className,\n )}\n onClick={(e) => {\n onClick?.(e);\n ctx?.setOpen(!ctx.open);\n }}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (!ctx || (e.key !== \"ArrowRight\" && e.key !== \"Enter\" && e.key !== \" \")) return;\n e.preventDefault();\n // Stops the menu's own handler, which would read Enter as \"select this item\".\n e.stopPropagation();\n ctx.focusFirst.current = true;\n ctx.setOpen(true);\n }}\n {...props}\n >\n {children}\n <svg className=\"ml-auto size-4\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n </div>\n );\n}\n\nexport function DropdownMenuSubContent({ className, children, onKeyDown, ...props }: React.ComponentProps<\"div\">) {\n const ctx = React.useContext(DropdownMenuSubContext);\n const ref = React.useRef<HTMLDivElement | null>(null);\n const open = ctx?.open ?? false;\n React.useEffect(() => {\n if (!open || !ctx?.focusFirst.current) return;\n ctx.focusFirst.current = false;\n ref.current?.querySelector<HTMLElement>(\"[role^='menuitem']\")?.focus();\n }, [open, ctx]);\n if (!ctx?.open) return null;\n return (\n <div\n ref={ref}\n onKeyDown={(e) => {\n onKeyDown?.(e);\n if (e.key === \"ArrowLeft\" || e.key === \"Escape\") {\n // Closes this flyout only; Escape would otherwise reach the whole menu's dismissal.\n e.preventDefault();\n e.stopPropagation();\n ctx.setOpen(false);\n ctx.triggerRef.current?.focus();\n }\n }}\n data-slot=\"dropdown-menu-sub-content\"\n data-state=\"open\"\n role=\"menu\"\n className={cn(\n DROPDOWN_MENU_SUB_CONTENT,\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/empty.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n EMPTY,\n EMPTY_CONTENT,\n EMPTY_DESCRIPTION,\n EMPTY_HEADER,\n EMPTY_MEDIA_BASE,\n EMPTY_TITLE,\n emptyMediaVariants,\n type EmptyMediaVariant,\n} from \"../generated/empty\";\n\nexport type { EmptyMediaVariant };\n\nexport function Empty({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div data-slot=\"empty\" className={cn(EMPTY, className)} {...props} />\n );\n}\n\nexport function EmptyHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-header\"\n className={cn(EMPTY_HEADER, className)}\n {...props}\n />\n );\n}\n\nexport interface EmptyMediaProps extends React.ComponentProps<\"div\"> {\n variant?: EmptyMediaVariant;\n}\n\nexport function EmptyMedia({\n className,\n variant = \"bare\",\n ...props\n}: EmptyMediaProps) {\n return (\n <div\n data-slot=\"empty-icon\"\n data-variant={variant}\n className={cn(EMPTY_MEDIA_BASE, emptyMediaVariants[variant], className)}\n {...props}\n />\n );\n}\n\nexport function EmptyTitle({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-title\"\n className={cn(EMPTY_TITLE, className)}\n {...props}\n />\n );\n}\n\nexport function EmptyDescription({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-description\"\n className={cn(EMPTY_DESCRIPTION, className)}\n {...props}\n />\n );\n}\n\nexport function EmptyContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-content\"\n className={cn(EMPTY_CONTENT, className)}\n {...props}\n />\n );\n}\n"],"mappings":"AAiBI;AAjBJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAIA,SAAS,MAAM,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC1E,SACE,oBAAC,SAAI,aAAU,SAAQ,WAAW,GAAG,OAAO,SAAS,GAAI,GAAG,OAAO;AAEvE;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,cAAc,SAAS;AAAA,MACpC,GAAG;AAAA;AAAA,EACN;AAEJ;AAMO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,UAAU;AAAA,EACV,GAAG;AACL,GAAoB;AAClB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAc;AAAA,MACd,WAAW,GAAG,kBAAkB,mBAAmB,OAAO,GAAG,SAAS;AAAA,MACrE,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,aAAa,SAAS;AAAA,MACnC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,mBAAmB,SAAS;AAAA,MACzC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,eAAe,SAAS;AAAA,MACrC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/field-context.ts"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\n/**\n * The id a `<Field>` hands to the one control it labels. `React.useId` is\n * derived from the position in the tree, so the server render and the hydrating\n * client agree on it — a module counter would not, and the label's `for` would\n * point at nothing after hydration.\n */\nexport interface FieldControl {\n id: string;\n /** Records a control taking the id; returns the release. */\n claim: () => () => void;\n}\n\nexport const FieldControlContext = React.createContext<FieldControl | null>(null);\n\nconst DEV = typeof process !== \"undefined\" && process.env.NODE_ENV !== \"production\";\n\n/** The `claim` of a `Field`: warns in development when a second control takes the id. */\nexport function useFieldClaims(): () => () => void {\n const claims = React.useRef(0);\n return React.useCallback(() => {\n claims.current += 1;\n if (DEV && claims.current === 2) {\n console.warn(\n \"@evinvest/uikit: two controls took the same <Field> id. A Field labels one control; \" +\n \"give the others an `id` of their own.\",\n );\n }\n return () => {\n claims.current -= 1;\n };\n }, []);\n}\n\n/** The caller's `id` when given, else the enclosing `<Field>`'s, else none. */\nexport function useFieldControlId(id: string | undefined): string | undefined {\n const field = React.useContext(FieldControlContext);\n const fromField = id === undefined ? field : null;\n React.useEffect(() => fromField?.claim(), [fromField]);\n return id ?? fromField?.id;\n}\n"],"mappings":";AAEA,YAAY,WAAW;AAchB,MAAM,sBAAsB,MAAM,cAAmC,IAAI;AAEhF,MAAM,MAAM,OAAO,YAAY,eAAe,QAAQ,IAAI,aAAa;AAGhE,SAAS,iBAAmC;AACjD,QAAM,SAAS,MAAM,OAAO,CAAC;AAC7B,SAAO,MAAM,YAAY,MAAM;AAC7B,WAAO,WAAW;AAClB,QAAI,OAAO,OAAO,YAAY,GAAG;AAC/B,cAAQ;AAAA,QACN;AAAA,MAEF;AAAA,IACF;AACA,WAAO,MAAM;AACX,aAAO,WAAW;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,CAAC;AACP;AAGO,SAAS,kBAAkB,IAA4C;AAC5E,QAAM,QAAQ,MAAM,WAAW,mBAAmB;AAClD,QAAM,YAAY,OAAO,SAAY,QAAQ;AAC7C,QAAM,UAAU,MAAM,WAAW,MAAM,GAAG,CAAC,SAAS,CAAC;AACrD,SAAO,MAAM,WAAW;AAC1B;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/field.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { Label } from \"./label\";\nimport { walkElements } from \"../primitives/walk-elements\";\nimport { isLabelable, markLabelable } from \"../primitives/labelable\";\nimport { FieldControlContext, useFieldClaims } from \"./field-context\";\nimport {\n FIELD_BASE,\n FIELD_SET,\n FIELD_LEGEND,\n FIELD_GROUP,\n FIELD_CONTENT,\n FIELD_LABEL,\n FIELD_TITLE,\n FIELD_DESCRIPTION,\n FIELD_SEPARATOR,\n FIELD_SEPARATOR_LINE,\n FIELD_SEPARATOR_CONTENT,\n FIELD_ERROR,\n fieldOrientation,\n type FieldOrientation,\n} from \"../generated/field\";\n\nexport type { FieldOrientation };\n\nexport function FieldSet({ className, ...props }: React.ComponentProps<\"fieldset\">) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(FIELD_SET, className)}\n {...props}\n />\n );\n}\n\nexport function FieldLegend({\n className,\n variant = \"legend\",\n ...props\n}: React.ComponentProps<\"legend\"> & { variant?: \"legend\" | \"label\" }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(FIELD_LEGEND, className)}\n {...props}\n />\n );\n}\n\nexport function FieldGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(FIELD_GROUP, className)}\n {...props}\n />\n );\n}\n\n/**\n * A labelled control. `Field` mints one id and hands it to both ends: its\n * `FieldLabel` takes it as `for`, and the kit's `Input`, `Textarea`,\n * `NativeSelect`, `SelectTrigger`, `Checkbox` and `Switch` take it as `id` —\n * each only when the caller passed none. `controlId` names the id instead of\n * minting one. One control per `Field`: a field that holds two has to name\n * their ids by hand, or both would claim the one id (a development warning\n * says so).\n */\nexport function Field({\n className,\n orientation = \"vertical\",\n controlId,\n ...props\n}: React.ComponentProps<\"div\"> & { orientation?: FieldOrientation; controlId?: string }) {\n const minted = React.useId();\n const claim = useFieldClaims();\n const id = controlId ?? minted;\n const control = React.useMemo(() => ({ id, claim }), [id, claim]);\n return (\n <FieldControlContext.Provider value={control}>\n <div\n role=\"group\"\n data-slot=\"field\"\n data-orientation={orientation}\n className={cn(FIELD_BASE, fieldOrientation[orientation], className)}\n {...props}\n />\n </FieldControlContext.Provider>\n );\n}\n\nmarkLabelable(Field);\n\nexport function FieldContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(FIELD_CONTENT, className)}\n {...props}\n />\n );\n}\n\nexport interface FieldLabelProps extends Omit<React.ComponentProps<typeof Label>, \"htmlFor\"> {\n /** `null` opts out of the `Field`'s id: the label then has no `for` at all. */\n htmlFor?: string | null;\n}\n\n/**\n * Takes its `Field`'s id as `for` unless it wraps a control itself — a label\n * around an `<input>` already labels it, and a `for` pointing elsewhere would\n * steal the click. A control inside a component of yours is invisible to that\n * check; pass `htmlFor={null}` there.\n */\nexport function FieldLabel({ className, htmlFor, children, ...props }: FieldLabelProps) {\n const field = React.useContext(FieldControlContext);\n const target = htmlFor === null ? undefined : (htmlFor ?? (wrapsControl(children) ? undefined : field?.id));\n return (\n <Label\n data-slot=\"field-label\"\n htmlFor={target}\n className={cn(FIELD_LABEL, className)}\n {...props}\n >\n {children}\n </Label>\n );\n}\n\n// The labelable elements (HTML's list, less `output`/`meter`/`progress`, which a\n// field label never wraps) and the kit's controls that render one — plus a\n// nested `Field`, the choice-card shape, whose control is labelled by its own.\n// The kit's controls carry a mark (`primitives/labelable`) rather than sitting\n// in a set here: a set would import every control into every page with a Field.\nconst LABELABLE_TAGS = new Set([\"input\", \"select\", \"textarea\", \"button\"]);\n\nfunction wrapsControl(children: React.ReactNode): boolean {\n let found = false;\n walkElements(children, (element) => {\n if (found) return false;\n const { type } = element;\n const props = element.props as { type?: unknown };\n if (typeof type === \"string\" ? LABELABLE_TAGS.has(type) && props.type !== \"hidden\" : isLabelable(type)) {\n found = true;\n }\n return !found;\n });\n return found;\n}\n\nexport function FieldTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"field-label\"\n className={cn(FIELD_TITLE, className)}\n {...props}\n />\n );\n}\n\nexport function FieldDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n <p\n data-slot=\"field-description\"\n className={cn(FIELD_DESCRIPTION, className)}\n {...props}\n />\n );\n}\n\nexport function FieldSeparator({\n children,\n className,\n ...props\n}: React.ComponentProps<\"div\"> & { children?: React.ReactNode }) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn(FIELD_SEPARATOR, className)}\n {...props}\n >\n <div role=\"separator\" className={FIELD_SEPARATOR_LINE} />\n {children && (\n <span\n className={FIELD_SEPARATOR_CONTENT}\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n );\n}\n\nexport function FieldError({\n className,\n children,\n errors,\n ...props\n}: React.ComponentProps<\"div\"> & {\n errors?: Array<{ message?: string } | undefined>;\n}) {\n const content = React.useMemo(() => {\n if (children) {\n return children;\n }\n\n if (!errors) {\n return null;\n }\n\n if (errors?.length === 1 && errors[0]?.message) {\n return errors[0].message;\n }\n\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {errors.map(\n (error, index) => error?.message && <li key={index}>{error.message}</li>,\n )}\n </ul>\n );\n }, [children, errors]);\n\n if (!content) {\n return null;\n }\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn(FIELD_ERROR, className)}\n {...props}\n >\n {content}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/footer.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { Container } from \"./container\";\n\n/**\n * A 12-col footer grid — brand 3 | sitemap groups 2 each | offices 3 |\n * newsletter 2 — with the legal links and copyright line. On mobile the sitemap\n * columns sit side by side. The kit brings no content of its own: every string,\n * the mark and the lock-up are the caller's, and each column renders only when\n * it has something in it. `children` render right after the `<footer>` tag —\n * the slot for app-side extras like a build-version easter egg.\n *\n * The lock-up is either composed from `mark` + `brand` + `tagline`, or handed\n * over whole as `lockup` when a brand's arrangement is not that one.\n *\n * `linkComponent` lets Next hosts pass `next/link`; everyone else gets `<a>`.\n */\nexport interface FooterLink {\n label: string;\n href: string;\n}\n\nexport interface FooterLinkGroup {\n heading: string;\n links: readonly FooterLink[];\n}\n\nexport interface FooterOffice {\n name: string;\n address: string;\n}\n\nexport interface FooterProps {\n /** The whole lock-up; replaces the one `mark` + `brand` + `tagline` compose. */\n lockup?: React.ReactNode;\n /** The wordmark beside the mark, set in the display family. */\n brand?: string;\n /** The mark beside the brand name. Sized by the caller. */\n mark?: React.ReactNode;\n tagline?: string;\n description?: React.ReactNode;\n copyright?: React.ReactNode;\n nav?: readonly FooterLinkGroup[];\n offices?: readonly FooterOffice[];\n officesHeading?: string;\n legalLinks?: readonly FooterLink[];\n /** The newsletter form; the newsletter column renders only when present. */\n newsletter?: React.ReactNode;\n newsletterHeading?: string;\n newsletterBlurb?: string;\n version?: string;\n commitHref?: string;\n linkComponent?: React.ElementType;\n children?: React.ReactNode;\n}\n\nconst HEADING = \"font-mono text-xs text-ink uppercase tracking-widest mb-6\";\n\nexport function Footer({\n lockup,\n brand,\n mark,\n tagline,\n description,\n copyright,\n nav = [],\n offices = [],\n officesHeading = \"Offices\",\n legalLinks = [],\n newsletter,\n newsletterHeading = \"Newsletter\",\n newsletterBlurb = \"\",\n version,\n commitHref,\n linkComponent,\n children,\n}: FooterProps) {\n const L = linkComponent ?? \"a\";\n const composed = brand !== undefined || mark !== undefined;\n const hasBrandColumn = lockup !== undefined || composed || description !== undefined || legalLinks.length > 0;\n\n return (\n <footer data-slot=\"footer\" className=\"bg-background border-t border-ink/10 py-16\">\n {children}\n <Container>\n <div className=\"grid grid-cols-2 gap-x-8 gap-y-8 lg:grid-cols-12 mb-12\">\n {hasBrandColumn && (\n <div className=\"col-span-2 lg:col-span-3\">\n {lockup !== undefined ? (\n <div data-slot=\"footer-lockup\" className=\"mb-6\">{lockup}</div>\n ) : (\n composed && <FooterLockup brand={brand} mark={mark} tagline={tagline} />\n )}\n {description !== undefined && (\n <p className=\"text-ink/40 text-xs font-light max-w-sm leading-relaxed mb-6\">\n {description}\n </p>\n )}\n {legalLinks.length > 0 && (\n <div className=\"flex gap-4 text-xs font-mono text-primary-ink\">\n {legalLinks.map((link, i) => (\n <React.Fragment key={link.label}>\n {i > 0 && <span className=\"text-ink/20\">|</span>}\n <L href={link.href} className=\"hover:underline\">\n {link.label}\n </L>\n </React.Fragment>\n ))}\n </div>\n )}\n </div>\n )}\n\n {nav.map((group) => (\n <nav key={group.heading} aria-label={`Footer ${group.heading} links`} className=\"lg:col-span-2\">\n <h4 className={HEADING}>{group.heading}</h4>\n <ul className=\"space-y-3\">\n {group.links.map((link) => (\n <li key={link.href}>\n <L\n href={link.href}\n className=\"text-xs font-light text-ink/70 hover:text-primary-ink transition-colors\"\n >\n {link.label}\n </L>\n </li>\n ))}\n </ul>\n </nav>\n ))}\n\n {offices.length > 0 && (\n <div className=\"col-span-2 lg:col-span-3\">\n <h4 className={HEADING}>{officesHeading}</h4>\n <ul className=\"space-y-4 text-xs text-ink/70 font-light leading-relaxed\">\n {offices.map((office) => (\n <li key={office.name}>\n <strong className=\"text-ink block font-mono text-[10px] uppercase tracking-wider mb-1\">\n {office.name}\n </strong>\n {office.address}\n </li>\n ))}\n </ul>\n </div>\n )}\n\n {newsletter && (\n <div className=\"col-span-2 lg:col-span-2\">\n <h4 className={HEADING}>{newsletterHeading}</h4>\n {/* What the source's <Tier tier=\"alt\"><Text> emits: alt body size\n + the info variant, then the mb-4 the caller adds. */}\n <p className=\"text-sm sm:text-xs font-light leading-relaxed text-ink/70 mb-4\">\n {newsletterBlurb}\n </p>\n {newsletter}\n </div>\n )}\n </div>\n\n {(copyright !== undefined || version !== undefined) && (\n <div className=\"border-t border-ink/10 pt-8 text-[10px] font-mono text-ink/40\">\n <p>\n {copyright}\n {version && (\n <>\n {copyright !== undefined && \" \"}\n <a href={commitHref} className=\"text-ink/30\">\n {version}\n </a>\n </>\n )}\n </p>\n </div>\n )}\n </Container>\n </footer>\n );\n}\n\nfunction FooterLockup({\n brand,\n mark,\n tagline,\n}: {\n brand: string | undefined;\n mark: React.ReactNode;\n tagline: string | undefined;\n}) {\n return (\n <div data-slot=\"footer-lockup\" className=\"flex items-center gap-3 mb-6\">\n {mark}\n {(brand !== undefined || tagline !== undefined) && (\n <div className=\"flex flex-col\">\n {brand !== undefined && (\n <span className=\"font-serif font-bold text-base tracking-wider text-ink\">{brand}</span>\n )}\n {tagline !== undefined && (\n <span className=\"text-[8px] font-mono tracking-[0.3em] text-primary-ink uppercase\">\n {tagline}\n </span>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/form-row.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n FORM_ROW_BASE,\n FORM_ROW_CONTROL,\n FORM_ROW_DESCRIPTION,\n FORM_ROW_DIVIDER,\n FORM_ROW_HINT,\n FORM_ROW_LABEL,\n FORM_ROW_LABEL_COLUMN,\n} from \"../generated/form-row\";\n\nexport interface FormRowProps extends Omit<React.ComponentProps<\"div\">, \"title\"> {\n label: React.ReactNode;\n /** The id of the control in `children`; renders the label as a `<label for>`. */\n htmlFor?: string;\n /** A line under the label. */\n description?: React.ReactNode;\n /** A caption under the control, e.g. a format hint. */\n hint?: React.ReactNode;\n /** Hairline under the row. Default true; the last row of a group turns it off. */\n divider?: boolean;\n}\n\n/**\n * Label on the left, the value or its control on the right; they stack on a\n * phone. A plain `div`, not `ListRow`: it is a form field row, not a list item,\n * and its label column has a fixed width so controls line up down the page.\n */\nexport function FormRow({\n label,\n htmlFor,\n description,\n hint,\n divider = true,\n className,\n children,\n ...props\n}: FormRowProps) {\n const Label = htmlFor !== undefined ? \"label\" : \"span\";\n return (\n <div\n data-slot=\"form-row\"\n data-divider={divider}\n className={cn(\n FORM_ROW_BASE,\n divider && FORM_ROW_DIVIDER,\n className,\n )}\n {...props}\n >\n <div data-slot=\"form-row-label\" className={FORM_ROW_LABEL_COLUMN}>\n <Label {...(htmlFor !== undefined ? { htmlFor } : {})} className={FORM_ROW_LABEL}>\n {label}\n </Label>\n {description != null && <span className={FORM_ROW_DESCRIPTION}>{description}</span>}\n </div>\n <div data-slot=\"form-row-control\" className={FORM_ROW_CONTROL}>\n {children}\n {hint != null && <span className={FORM_ROW_HINT}>{hint}</span>}\n </div>\n </div>\n );\n}\n"],"mappings":"AAmDM,SACE,KADF;AAnDN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAmBA,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAiB;AACf,QAAM,QAAQ,YAAY,SAAY,UAAU;AAChD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAc;AAAA,MACd,WAAW;AAAA,QACT;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ;AAAA,6BAAC,SAAI,aAAU,kBAAiB,WAAW,uBACzC;AAAA,8BAAC,SAAO,GAAI,YAAY,SAAY,EAAE,QAAQ,IAAI,CAAC,GAAI,WAAW,gBAC/D,iBACH;AAAA,UACC,eAAe,QAAQ,oBAAC,UAAK,WAAW,sBAAuB,uBAAY;AAAA,WAC9E;AAAA,QACA,qBAAC,SAAI,aAAU,oBAAmB,WAAW,kBAC1C;AAAA;AAAA,UACA,QAAQ,QAAQ,oBAAC,UAAK,WAAW,eAAgB,gBAAK;AAAA,WACzD;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/form.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { Label } from \"./label\";\nimport { Slot } from \"../primitives/slot\";\nimport { FORM_DESCRIPTION, FORM_ITEM, FORM_MESSAGE } from \"../generated/form\";\n\n/**\n * Dep-light, presentational form primitives. We keep the ARIA id-wiring of\n * shadcn's form (label/control/description/message share an id so\n * `aria-describedby`/`id` line up) but drop `react-hook-form`'s state engine:\n * validation and field state are the consumer's job. `FormItem` mints an id via\n * `React.useId` and exposes it through `FormItemContext`.\n */\ntype FormItemContextValue = {\n id: string;\n formItemId: string;\n formDescriptionId: string;\n formMessageId: string;\n};\n\nconst FormItemContext = React.createContext<FormItemContextValue | null>(null);\n\nfunction useFormItem(): FormItemContextValue {\n const ctx = React.useContext(FormItemContext);\n if (!ctx) {\n throw new Error(\"Form parts must be used within <FormItem>\");\n }\n return ctx;\n}\n\nexport function Form({ ...props }: React.ComponentProps<\"form\">) {\n return <form data-slot=\"form\" {...props} />;\n}\n\nexport function FormItem({ className, ...props }: React.ComponentProps<\"div\">) {\n const id = React.useId();\n const value = React.useMemo<FormItemContextValue>(\n () => ({\n id,\n formItemId: `${id}-form-item`,\n formDescriptionId: `${id}-form-item-description`,\n formMessageId: `${id}-form-item-message`,\n }),\n [id],\n );\n\n return (\n <FormItemContext.Provider value={value}>\n <div data-slot=\"form-item\" className={cn(FORM_ITEM, className)} {...props} />\n </FormItemContext.Provider>\n );\n}\n\nexport function FormLabel({\n className,\n error,\n ...props\n}: React.ComponentProps<typeof Label> & { error?: boolean }) {\n const { formItemId } = useFormItem();\n\n return (\n <Label\n data-slot=\"form-label\"\n data-error={!!error}\n className={cn(\"data-[error=true]:text-accent-error\", className)}\n htmlFor={formItemId}\n {...props}\n />\n );\n}\n\nexport function FormControl({\n error,\n ...props\n}: React.ComponentProps<typeof Slot> & { error?: boolean }) {\n const { formItemId, formDescriptionId, formMessageId } = useFormItem();\n\n return (\n <Slot\n data-slot=\"form-control\"\n id={formItemId}\n aria-describedby={\n !error ? `${formDescriptionId}` : `${formDescriptionId} ${formMessageId}`\n }\n aria-invalid={!!error}\n {...props}\n />\n );\n}\n\nexport function FormDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n const { formDescriptionId } = useFormItem();\n\n return (\n <p\n data-slot=\"form-description\"\n id={formDescriptionId}\n className={cn(FORM_DESCRIPTION, className)}\n {...props}\n />\n );\n}\n\nexport function FormMessage({ className, children, ...props }: React.ComponentProps<\"p\">) {\n const { formMessageId } = useFormItem();\n\n if (!children) {\n return null;\n }\n\n return (\n <p\n data-slot=\"form-message\"\n id={formMessageId}\n className={cn(FORM_MESSAGE, className)}\n {...props}\n >\n {children}\n </p>\n );\n}\n"],"mappings":";AAiCS;AA/BT,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,kBAAkB,WAAW,oBAAoB;AAgB1D,MAAM,kBAAkB,MAAM,cAA2C,IAAI;AAE7E,SAAS,cAAoC;AAC3C,QAAM,MAAM,MAAM,WAAW,eAAe;AAC5C,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AACA,SAAO;AACT;AAEO,SAAS,KAAK,EAAE,GAAG,MAAM,GAAiC;AAC/D,SAAO,oBAAC,UAAK,aAAU,QAAQ,GAAG,OAAO;AAC3C;AAEO,SAAS,SAAS,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC7E,QAAM,KAAK,MAAM,MAAM;AACvB,QAAM,QAAQ,MAAM;AAAA,IAClB,OAAO;AAAA,MACL;AAAA,MACA,YAAY,GAAG,EAAE;AAAA,MACjB,mBAAmB,GAAG,EAAE;AAAA,MACxB,eAAe,GAAG,EAAE;AAAA,IACtB;AAAA,IACA,CAAC,EAAE;AAAA,EACL;AAEA,SACE,oBAAC,gBAAgB,UAAhB,EAAyB,OACxB,8BAAC,SAAI,aAAU,aAAY,WAAW,GAAG,WAAW,SAAS,GAAI,GAAG,OAAO,GAC7E;AAEJ;AAEO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA6D;AAC3D,QAAM,EAAE,WAAW,IAAI,YAAY;AAEnC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,cAAY,CAAC,CAAC;AAAA,MACd,WAAW,GAAG,uCAAuC,SAAS;AAAA,MAC9D,SAAS;AAAA,MACR,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,GAAG;AACL,GAA4D;AAC1D,QAAM,EAAE,YAAY,mBAAmB,cAAc,IAAI,YAAY;AAErE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,IAAI;AAAA,MACJ,oBACE,CAAC,QAAQ,GAAG,iBAAiB,KAAK,GAAG,iBAAiB,IAAI,aAAa;AAAA,MAEzE,gBAAc,CAAC,CAAC;AAAA,MACf,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,gBAAgB,EAAE,WAAW,GAAG,MAAM,GAA8B;AAClF,QAAM,EAAE,kBAAkB,IAAI,YAAY;AAE1C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,IAAI;AAAA,MACJ,WAAW,GAAG,kBAAkB,SAAS;AAAA,MACxC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,YAAY,EAAE,WAAW,UAAU,GAAG,MAAM,GAA8B;AACxF,QAAM,EAAE,cAAc,IAAI,YAAY;AAEtC,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,IAAI;AAAA,MACJ,WAAW,GAAG,cAAc,SAAS;AAAA,MACpC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/header-controls.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n HEADER_BALANCE_BASE,\n HEADER_BALANCE_CHEVRON,\n HEADER_BALANCE_FIGURE,\n HEADER_BALANCE_INTERACTIVE,\n HEADER_BALANCE_LABEL,\n HEADER_BALANCE_SETTLED,\n HEADER_BALANCE_SKELETON,\n HEADER_SEARCH_BASE,\n HEADER_SEARCH_PLACEHOLDER,\n NOTIFICATION_BELL_CONTENT,\n NOTIFICATION_BELL_EMPTY,\n NOTIFICATION_BELL_FOOTER,\n NOTIFICATION_BELL_ITEM,\n NOTIFICATION_BELL_ITEM_BODY,\n NOTIFICATION_BELL_ITEM_DESCRIPTION,\n NOTIFICATION_BELL_ITEM_DOT,\n NOTIFICATION_BELL_ITEM_DOT_READ,\n NOTIFICATION_BELL_ITEM_DOT_UNREAD,\n NOTIFICATION_BELL_ITEM_TIME,\n NOTIFICATION_BELL_ITEM_TITLE,\n NOTIFICATION_BELL_ITEM_TITLE_UNREAD,\n NOTIFICATION_BELL_LIST,\n NOTIFICATION_BELL_TRIGGER,\n NOTIFICATION_DOT,\n headerBalanceToneClasses,\n type HeaderBalanceTone,\n} from \"../generated/header-controls\";\nimport { AnimatedNumber } from \"./animated-number\";\nimport { IconButton } from \"./icon-button\";\nimport { Kbd } from \"./kbd\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"./popover\";\nimport { Settled } from \"./settled\";\nimport { Skeleton } from \"./skeleton\";\nimport { UiIcon } from \"./ui-icons\";\n\nexport interface HeaderBalanceProps extends Omit<React.HTMLAttributes<HTMLElement>, \"children\"> {\n /** Only meaningful with `onClick`. */\n disabled?: boolean;\n label?: React.ReactNode;\n /** The figure, already formatted: \"$0.00\". Ignored when `amount` is given. */\n value?: React.ReactNode;\n /** The figure as a number: it rolls to each new amount, formatted by `format` and `locales`. */\n amount?: number;\n /** Formatting for `amount`. Default: USD currency. */\n format?: Intl.NumberFormatOptions;\n locales?: Intl.LocalesArgument;\n /** True until the balance is known; the figure then reveals in place of the skeleton. */\n loading?: boolean;\n /** A glyph before the label. */\n icon?: React.ReactNode;\n /** `warn` colours the figure as a low-funds signal. */\n tone?: HeaderBalanceTone;\n}\n\nconst USD: Intl.NumberFormatOptions = { style: \"currency\", currency: \"USD\" };\n\n/** \"Balance: $0.00\" in the header; a button only when given `onClick`. */\nexport function HeaderBalance({\n label = \"Balance:\",\n value,\n amount,\n format = USD,\n locales,\n loading = false,\n icon,\n tone = \"default\",\n onClick,\n disabled,\n className,\n ...props\n}: HeaderBalanceProps) {\n const face = cn(HEADER_BALANCE_BASE, onClick && HEADER_BALANCE_INTERACTIVE, className);\n const body = (\n <>\n {icon}\n <span className={HEADER_BALANCE_LABEL}>{label}</span>\n <Settled\n loading={loading}\n skeleton={<Skeleton className={HEADER_BALANCE_SKELETON} />}\n className={HEADER_BALANCE_SETTLED}\n >\n <span className={cn(HEADER_BALANCE_FIGURE, headerBalanceToneClasses[tone])}>\n {amount === undefined ? value : <AnimatedNumber value={amount} format={format} locales={locales} />}\n </span>\n </Settled>\n {onClick && <UiIcon name=\"chevron-down\" className={HEADER_BALANCE_CHEVRON} />}\n </>\n );\n if (!onClick) {\n return (\n <div data-slot=\"header-balance\" className={face} {...props}>\n {body}\n </div>\n );\n }\n return (\n <button type=\"button\" data-slot=\"header-balance\" className={face} onClick={onClick} disabled={disabled} {...props}>\n {body}\n </button>\n );\n}\n\nexport interface HeaderNotification {\n id: string;\n title: React.ReactNode;\n description?: React.ReactNode;\n /** Already formatted: \"2m ago\". */\n time?: React.ReactNode;\n unread?: boolean;\n}\n\nexport interface NotificationBellLabels {\n /** The bell's name. Default `\"Notifications\"`. */\n trigger?: string;\n /** Spoken after the name when something is unread; gets the count. Default `\"{n} unread\"`. */\n unread?: (count: number) => string;\n /** Default `\"No notifications\"`. */\n empty?: string;\n}\n\nexport interface NotificationBellProps {\n notifications: readonly HeaderNotification[];\n onSelect?: (id: string) => void;\n labels?: NotificationBellLabels;\n /** Under the list: \"View all\". */\n footer?: React.ReactNode;\n className?: string;\n}\n\n/** The bell with an unread dot; the list opens in a popover. */\nexport function NotificationBell({ notifications, onSelect, labels = {}, footer, className }: NotificationBellProps) {\n const unread = notifications.filter((n) => n.unread).length;\n const name = labels.trigger ?? \"Notifications\";\n const spoken = unread > 0 ? `${name}, ${(labels.unread ?? ((n) => `${n} unread`))(unread)}` : name;\n return (\n <Popover>\n <PopoverTrigger asChild>\n <IconButton aria-label={spoken} variant=\"outline\" className={cn(NOTIFICATION_BELL_TRIGGER, className)}>\n <UiIcon name=\"bell\" />\n {unread > 0 && (\n <span data-slot=\"notification-dot\" aria-hidden className={NOTIFICATION_DOT} />\n )}\n </IconButton>\n </PopoverTrigger>\n <PopoverContent align=\"end\" className={NOTIFICATION_BELL_CONTENT}>\n {notifications.length === 0 ? (\n <p className={NOTIFICATION_BELL_EMPTY}>{labels.empty ?? \"No notifications\"}</p>\n ) : (\n <ul className={NOTIFICATION_BELL_LIST}>\n {notifications.map((n) => (\n <li key={n.id}>\n <button\n type=\"button\"\n onClick={() => onSelect?.(n.id)}\n className={NOTIFICATION_BELL_ITEM}\n >\n <span\n aria-hidden\n className={cn(\n NOTIFICATION_BELL_ITEM_DOT,\n n.unread ? NOTIFICATION_BELL_ITEM_DOT_UNREAD : NOTIFICATION_BELL_ITEM_DOT_READ,\n )}\n />\n <span className={NOTIFICATION_BELL_ITEM_BODY}>\n <span className={cn(NOTIFICATION_BELL_ITEM_TITLE, n.unread && NOTIFICATION_BELL_ITEM_TITLE_UNREAD)}>{n.title}</span>\n {n.description != null && <span className={NOTIFICATION_BELL_ITEM_DESCRIPTION}>{n.description}</span>}\n </span>\n {n.time != null && <span className={NOTIFICATION_BELL_ITEM_TIME}>{n.time}</span>}\n </button>\n </li>\n ))}\n </ul>\n )}\n {footer != null && <div className={NOTIFICATION_BELL_FOOTER}>{footer}</div>}\n </PopoverContent>\n </Popover>\n );\n}\n\nexport interface HeaderSearchProps extends React.ComponentProps<\"button\"> {\n placeholder?: string;\n /** The shortcut hint at the end. Default: `⌘K` on Apple platforms, `Ctrl K` elsewhere. */\n shortcut?: string;\n}\n\nconst APPLE = /Mac|iPhone|iPad|iPod/;\n\n// Read after mount, so the server render and the first client render agree.\nfunction usePlatformShortcut(): string {\n const [shortcut, setShortcut] = React.useState(\"Ctrl K\");\n React.useEffect(() => {\n const nav = navigator as Navigator & { userAgentData?: { platform?: string } };\n if (APPLE.test(nav.userAgentData?.platform ?? nav.platform ?? \"\")) setShortcut(\"⌘K\");\n }, []);\n return shortcut;\n}\n\n/** A button dressed as the search field; it opens the palette rather than taking input. */\nexport function HeaderSearch({\n placeholder = \"Search or jump to…\",\n shortcut,\n className,\n ...props\n}: HeaderSearchProps) {\n const platformShortcut = usePlatformShortcut();\n return (\n <button\n type=\"button\"\n data-slot=\"header-search\"\n className={cn(HEADER_SEARCH_BASE, className)}\n {...props}\n >\n <UiIcon name=\"search\" />\n <span className={HEADER_SEARCH_PLACEHOLDER}>{placeholder}</span>\n <Kbd>{shortcut ?? platformShortcut}</Kbd>\n </button>\n );\n}\n"],"mappings":";AA8EI,mBAEE,KAFF;AA5EJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,WAAW;AACpB,SAAS,SAAS,gBAAgB,sBAAsB;AACxD,SAAS,eAAe;AACxB,SAAS,gBAAgB;AACzB,SAAS,cAAc;AAqBvB,MAAM,MAAgC,EAAE,OAAO,YAAY,UAAU,MAAM;AAGpE,SAAS,cAAc;AAAA,EAC5B,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAuB;AACrB,QAAM,OAAO,GAAG,qBAAqB,WAAW,4BAA4B,SAAS;AACrF,QAAM,OACJ,iCACG;AAAA;AAAA,IACD,oBAAC,UAAK,WAAW,sBAAuB,iBAAM;AAAA,IAC9C;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,UAAU,oBAAC,YAAS,WAAW,yBAAyB;AAAA,QACxD,WAAW;AAAA,QAEX,8BAAC,UAAK,WAAW,GAAG,uBAAuB,yBAAyB,IAAI,CAAC,GACtE,qBAAW,SAAY,QAAQ,oBAAC,kBAAe,OAAO,QAAQ,QAAgB,SAAkB,GACnG;AAAA;AAAA,IACF;AAAA,IACC,WAAW,oBAAC,UAAO,MAAK,gBAAe,WAAW,wBAAwB;AAAA,KAC7E;AAEF,MAAI,CAAC,SAAS;AACZ,WACE,oBAAC,SAAI,aAAU,kBAAiB,WAAW,MAAO,GAAG,OAClD,gBACH;AAAA,EAEJ;AACA,SACE,oBAAC,YAAO,MAAK,UAAS,aAAU,kBAAiB,WAAW,MAAM,SAAkB,UAAqB,GAAG,OACzG,gBACH;AAEJ;AA8BO,SAAS,iBAAiB,EAAE,eAAe,UAAU,SAAS,CAAC,GAAG,QAAQ,UAAU,GAA0B;AACnH,QAAM,SAAS,cAAc,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE;AACrD,QAAM,OAAO,OAAO,WAAW;AAC/B,QAAM,SAAS,SAAS,IAAI,GAAG,IAAI,MAAM,OAAO,WAAW,CAAC,MAAM,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK;AAC9F,SACE,qBAAC,WACC;AAAA,wBAAC,kBAAe,SAAO,MACrB,+BAAC,cAAW,cAAY,QAAQ,SAAQ,WAAU,WAAW,GAAG,2BAA2B,SAAS,GAClG;AAAA,0BAAC,UAAO,MAAK,QAAO;AAAA,MACnB,SAAS,KACR,oBAAC,UAAK,aAAU,oBAAmB,eAAW,MAAC,WAAW,kBAAkB;AAAA,OAEhF,GACF;AAAA,IACA,qBAAC,kBAAe,OAAM,OAAM,WAAW,2BACpC;AAAA,oBAAc,WAAW,IACxB,oBAAC,OAAE,WAAW,yBAA0B,iBAAO,SAAS,oBAAmB,IAE3E,oBAAC,QAAG,WAAW,wBACZ,wBAAc,IAAI,CAAC,MAClB,oBAAC,QACC;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,WAAW,EAAE,EAAE;AAAA,UAC9B,WAAW;AAAA,UAEX;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,eAAW;AAAA,gBACX,WAAW;AAAA,kBACT;AAAA,kBACA,EAAE,SAAS,oCAAoC;AAAA,gBACjD;AAAA;AAAA,YACF;AAAA,YACA,qBAAC,UAAK,WAAW,6BACf;AAAA,kCAAC,UAAK,WAAW,GAAG,8BAA8B,EAAE,UAAU,mCAAmC,GAAI,YAAE,OAAM;AAAA,cAC5G,EAAE,eAAe,QAAQ,oBAAC,UAAK,WAAW,oCAAqC,YAAE,aAAY;AAAA,eAChG;AAAA,YACC,EAAE,QAAQ,QAAQ,oBAAC,UAAK,WAAW,6BAA8B,YAAE,MAAK;AAAA;AAAA;AAAA,MAC3E,KAlBO,EAAE,EAmBX,CACD,GACH;AAAA,MAED,UAAU,QAAQ,oBAAC,SAAI,WAAW,0BAA2B,kBAAO;AAAA,OACvE;AAAA,KACF;AAEJ;AAQA,MAAM,QAAQ;AAGd,SAAS,sBAA8B;AACrC,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAAS,QAAQ;AACvD,QAAM,UAAU,MAAM;AACpB,UAAM,MAAM;AACZ,QAAI,MAAM,KAAK,IAAI,eAAe,YAAY,IAAI,YAAY,EAAE,EAAG,aAAY,SAAI;AAAA,EACrF,GAAG,CAAC,CAAC;AACL,SAAO;AACT;AAGO,SAAS,aAAa;AAAA,EAC3B,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAsB;AACpB,QAAM,mBAAmB,oBAAoB;AAC7C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,WAAW,GAAG,oBAAoB,SAAS;AAAA,MAC1C,GAAG;AAAA,MAEJ;AAAA,4BAAC,UAAO,MAAK,UAAS;AAAA,QACtB,oBAAC,UAAK,WAAW,2BAA4B,uBAAY;AAAA,QACzD,oBAAC,OAAK,sBAAY,kBAAiB;AAAA;AAAA;AAAA,EACrC;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/hover-card.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport { useFloating } from \"../primitives/use-floating\";\nimport { usePresence } from \"../primitives/presence\";\nimport { mergeRefs } from \"../primitives/merge-refs\";\nimport { Portal } from \"../primitives/portal\";\nimport { Slot } from \"../primitives/slot\";\nimport { HOVER_CARD_CONTENT } from \"../generated/hover-card\";\n\ninterface HoverCardContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n anchorRef: React.RefObject<HTMLElement | null>;\n}\n\nconst HoverCardContext = React.createContext<HoverCardContextValue | null>(null);\n\nfunction useHoverCard(): HoverCardContextValue {\n const ctx = React.useContext(HoverCardContext);\n if (!ctx) throw new Error(\"HoverCard parts must be used within <HoverCard>\");\n return ctx;\n}\n\nexport interface HoverCardProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: React.ReactNode;\n}\n\nexport function HoverCard({ open, defaultOpen = false, onOpenChange, children }: HoverCardProps) {\n const [isOpen, setOpen] = useControllableState<boolean>({\n ...(open !== undefined ? { value: open } : {}),\n defaultValue: defaultOpen,\n ...(onOpenChange ? { onChange: onOpenChange } : {}),\n });\n const anchorRef = React.useRef<HTMLElement | null>(null);\n return (\n <HoverCardContext.Provider value={{ open: isOpen, setOpen, anchorRef }}>\n {children}\n </HoverCardContext.Provider>\n );\n}\n\nexport interface HoverCardTriggerProps extends React.ComponentProps<\"a\"> {\n asChild?: boolean;\n}\n\nexport function HoverCardTrigger({\n asChild = false,\n onPointerEnter,\n onPointerLeave,\n ...props\n}: HoverCardTriggerProps) {\n const { setOpen, anchorRef } = useHoverCard();\n const Comp = asChild ? Slot : \"a\";\n return (\n <Comp\n data-slot=\"hover-card-trigger\"\n ref={anchorRef as React.Ref<never>}\n onPointerEnter={(e: React.PointerEvent<HTMLAnchorElement>) => {\n onPointerEnter?.(e);\n setOpen(true);\n }}\n onPointerLeave={(e: React.PointerEvent<HTMLAnchorElement>) => {\n onPointerLeave?.(e);\n setOpen(false);\n }}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\nexport interface HoverCardContentProps extends React.ComponentProps<\"div\"> {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n align?: \"start\" | \"center\" | \"end\";\n sideOffset?: number;\n}\n\nexport function HoverCardContent({\n className,\n side: sideProp = \"bottom\",\n align = \"center\",\n sideOffset = 4,\n children,\n ...props\n}: HoverCardContentProps) {\n const { open, anchorRef } = useHoverCard();\n const { isPresent, ref: presRef } = usePresence(open);\n const { floatingRef, style, side } = useFloating({\n anchorRef,\n open,\n side: sideProp,\n align,\n offset: sideOffset,\n });\n if (!isPresent) return null;\n return (\n <Portal>\n <div\n data-slot=\"hover-card-content\"\n data-state={open ? \"open\" : \"closed\"}\n data-side={side}\n data-align={align}\n ref={mergeRefs(floatingRef, presRef)}\n style={style}\n className={cn(HOVER_CARD_CONTENT, className)}\n {...(props as Record<string, unknown>)}\n >\n {children}\n </div>\n </Portal>\n );\n}\n"],"mappings":";AAyCI;AAvCJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,4BAA4B;AACrC,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,YAAY;AACrB,SAAS,0BAA0B;AAQnC,MAAM,mBAAmB,MAAM,cAA4C,IAAI;AAE/E,SAAS,eAAsC;AAC7C,QAAM,MAAM,MAAM,WAAW,gBAAgB;AAC7C,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,iDAAiD;AAC3E,SAAO;AACT;AASO,SAAS,UAAU,EAAE,MAAM,cAAc,OAAO,cAAc,SAAS,GAAmB;AAC/F,QAAM,CAAC,QAAQ,OAAO,IAAI,qBAA8B;AAAA,IACtD,GAAI,SAAS,SAAY,EAAE,OAAO,KAAK,IAAI,CAAC;AAAA,IAC5C,cAAc;AAAA,IACd,GAAI,eAAe,EAAE,UAAU,aAAa,IAAI,CAAC;AAAA,EACnD,CAAC;AACD,QAAM,YAAY,MAAM,OAA2B,IAAI;AACvD,SACE,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,EAAE,MAAM,QAAQ,SAAS,UAAU,GAClE,UACH;AAEJ;AAMO,SAAS,iBAAiB;AAAA,EAC/B,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,QAAM,EAAE,SAAS,UAAU,IAAI,aAAa;AAC5C,QAAM,OAAO,UAAU,OAAO;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,KAAK;AAAA,MACL,gBAAgB,CAAC,MAA6C;AAC5D,yBAAiB,CAAC;AAClB,gBAAQ,IAAI;AAAA,MACd;AAAA,MACA,gBAAgB,CAAC,MAA6C;AAC5D,yBAAiB,CAAC;AAClB,gBAAQ,KAAK;AAAA,MACf;AAAA,MACC,GAAI;AAAA;AAAA,EACP;AAEJ;AAQO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,MAAM,WAAW;AAAA,EACjB,QAAQ;AAAA,EACR,aAAa;AAAA,EACb;AAAA,EACA,GAAG;AACL,GAA0B;AACxB,QAAM,EAAE,MAAM,UAAU,IAAI,aAAa;AACzC,QAAM,EAAE,WAAW,KAAK,QAAQ,IAAI,YAAY,IAAI;AACpD,QAAM,EAAE,aAAa,OAAO,KAAK,IAAI,YAAY;AAAA,IAC/C;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA,QAAQ;AAAA,EACV,CAAC;AACD,MAAI,CAAC,UAAW,QAAO;AACvB,SACE,oBAAC,UACC;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,cAAY,OAAO,SAAS;AAAA,MAC5B,aAAW;AAAA,MACX,cAAY;AAAA,MACZ,KAAK,UAAU,aAAa,OAAO;AAAA,MACnC;AAAA,MACA,WAAW,GAAG,oBAAoB,SAAS;AAAA,MAC1C,GAAI;AAAA,MAEJ;AAAA;AAAA,EACH,GACF;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/icon-button.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { ICON_BUTTON_BASE, ICON_BUTTON_PRESSED, iconButtonSizeClasses, type IconButtonSize } from \"../generated/icon-button\";\nimport { buttonVariants } from \"./button\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"./tooltip\";\n\nexport type { IconButtonSize };\nexport type IconButtonVariant = \"outline\" | \"ghost\";\n\nexport interface IconButtonProps extends Omit<React.ComponentPropsWithoutRef<\"button\">, \"aria-label\" | \"children\"> {\n /** Required: a glyph alone names nothing. */\n \"aria-label\": string;\n /** The glyph, 16 px. */\n children: React.ReactNode;\n variant?: IconButtonVariant;\n size?: IconButtonSize;\n /** Toggled on: the active fill, and `aria-pressed` for assistive tech. */\n pressed?: boolean;\n /** Shown in a Tooltip on hover and focus. */\n tooltip?: React.ReactNode;\n}\n\n/**\n * A square button holding one glyph. It forwards its ref (also on React 18,\n * where function components drop `ref`) so it can be the child of any\n * `asChild` trigger; with a `tooltip` the same element anchors the tooltip.\n */\nexport const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(function IconButton(\n { variant = \"ghost\", size = \"md\", pressed, tooltip, className, type = \"button\", ...props },\n ref,\n) {\n const button = (\n <button\n ref={ref}\n type={type}\n data-slot=\"icon-button\"\n data-variant={variant}\n aria-pressed={pressed}\n className={cn(\n buttonVariants({ variant, size, icon: true }),\n iconButtonSizeClasses[size],\n ICON_BUTTON_BASE,\n pressed && ICON_BUTTON_PRESSED,\n className,\n )}\n {...props}\n />\n );\n if (tooltip === undefined) return button;\n return (\n <Tooltip>\n <TooltipTrigger asChild>{button}</TooltipTrigger>\n <TooltipContent>{tooltip}</TooltipContent>\n </Tooltip>\n );\n});\n"],"mappings":"AAgCI,cAkBA,YAlBA;AAhCJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,kBAAkB,qBAAqB,6BAAkD;AAClG,SAAS,sBAAsB;AAC/B,SAAS,SAAS,gBAAgB,sBAAsB;AAuBjD,MAAM,aAAa,MAAM,WAA+C,SAASA,YACtF,EAAE,UAAU,SAAS,OAAO,MAAM,SAAS,SAAS,WAAW,OAAO,UAAU,GAAG,MAAM,GACzF,KACA;AACA,QAAM,SACJ;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,aAAU;AAAA,MACV,gBAAc;AAAA,MACd,gBAAc;AAAA,MACd,WAAW;AAAA,QACT,eAAe,EAAE,SAAS,MAAM,MAAM,KAAK,CAAC;AAAA,QAC5C,sBAAsB,IAAI;AAAA,QAC1B;AAAA,QACA,WAAW;AAAA,QACX;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEF,MAAI,YAAY,OAAW,QAAO;AAClC,SACE,qBAAC,WACC;AAAA,wBAAC,kBAAe,SAAO,MAAE,kBAAO;AAAA,IAChC,oBAAC,kBAAgB,mBAAQ;AAAA,KAC3B;AAEJ,CAAC;","names":["IconButton"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/info-tip.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport { useFloating } from \"../primitives/use-floating\";\nimport { DismissableLayerScope, useDismissableLayer } from \"../primitives/dismissable-layer\";\nimport { usePresence } from \"../primitives/presence\";\nimport { useHoverIntent } from \"../primitives/use-hover-intent\";\nimport { mergeRefs } from \"../primitives/merge-refs\";\nimport { Portal } from \"../primitives/portal\";\nimport { Slot } from \"../primitives/slot\";\nimport { POPOVER_CONTENT } from \"../generated/popover\";\n\n/**\n * `InfoTip` — the ⓘ-beside-a-label *toggletip*. It reuses the popover machinery\n * (controllable state + floating + dismissable layer + portal) but deliberately\n * NOT the tooltip ARIA: the trigger is a real `<button aria-expanded aria-controls>`\n * and the bubble is a `role=\"status\"` live region, never `role=\"tooltip\"`. That is\n * the pattern that stays correct across mouse, keyboard and touch (a `role=tooltip`\n * is hover/focus-only and never opens on tap). Hover-with-intent (~0.5s) is layered\n * on as a mouse-only enhancement; click/tap/Enter/Space toggle instantly.\n *\n * The bubble holds plain, non-interactive help text — it does not trap focus and\n * nothing inside it is focusable, so there is no focus to manage or return.\n */\ninterface InfoTipContextValue {\n open: boolean;\n setOpen: (next: boolean) => void;\n anchorRef: React.RefObject<HTMLElement | null>;\n contentId: string;\n}\n\nconst InfoTipContext = React.createContext<InfoTipContextValue | null>(null);\n\nfunction useInfoTip(): InfoTipContextValue {\n const ctx = React.useContext(InfoTipContext);\n if (!ctx) throw new Error(\"InfoTip parts must be used within <InfoTip>\");\n return ctx;\n}\n\nexport interface InfoTipProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n children?: React.ReactNode;\n}\n\nexport function InfoTip({\n open,\n defaultOpen = false,\n onOpenChange,\n children,\n}: InfoTipProps) {\n const [isOpen, setOpen] = useControllableState<boolean>({\n ...(open !== undefined ? { value: open } : {}),\n defaultValue: defaultOpen,\n ...(onOpenChange ? { onChange: onOpenChange } : {}),\n });\n const anchorRef = React.useRef<HTMLElement | null>(null);\n const contentId = React.useId();\n return (\n <InfoTipContext.Provider\n value={{ open: isOpen, setOpen, anchorRef, contentId }}\n >\n {children}\n </InfoTipContext.Provider>\n );\n}\n\n// lucide `info`, inlined per the kit's no-lucide-dep icon convention.\nfunction InfoGlyph({ className }: { className?: string }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n className={cn(\"size-4\", className)}\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M12 16v-4\" />\n <path d=\"M12 8h.01\" />\n </svg>\n );\n}\n\nexport interface InfoTipTriggerProps extends React.ComponentProps<\"button\"> {\n asChild?: boolean;\n /** Accessible name for the icon-only button. */\n label?: string;\n /** Milliseconds the mouse must dwell before the tip opens on hover. */\n hoverDelay?: number;\n}\n\nexport function InfoTipTrigger({\n asChild = false,\n label = \"More information\",\n hoverDelay = 500,\n className,\n onClick,\n onBlur,\n onPointerEnter,\n onPointerLeave,\n children,\n ...props\n}: InfoTipTriggerProps) {\n const { open, setOpen, anchorRef, contentId } = useInfoTip();\n const hover = useHoverIntent({\n onOpen: () => setOpen(true),\n onClose: () => setOpen(false),\n openDelay: hoverDelay,\n });\n const Comp = asChild ? Slot : \"button\";\n return (\n <Comp\n data-slot=\"info-tip-trigger\"\n data-state={open ? \"open\" : \"closed\"}\n type={asChild ? undefined : \"button\"}\n aria-label={label}\n aria-expanded={open}\n aria-controls={contentId}\n ref={anchorRef as React.Ref<never>}\n className={cn(\n \"inline-flex size-4 shrink-0 cursor-help items-center justify-center rounded-full align-middle text-ink-soft outline-none transition-colors hover:text-ink focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:text-accent-debug\",\n className,\n )}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n setOpen(!open);\n }}\n onBlur={(e: React.FocusEvent<HTMLButtonElement>) => {\n onBlur?.(e);\n setOpen(false);\n }}\n onPointerEnter={(e: React.PointerEvent<HTMLButtonElement>) => {\n onPointerEnter?.(e);\n hover.onPointerEnter(e);\n }}\n onPointerLeave={(e: React.PointerEvent<HTMLButtonElement>) => {\n onPointerLeave?.(e);\n hover.onPointerLeave(e);\n }}\n {...(props as Record<string, unknown>)}\n >\n {children ?? <InfoGlyph />}\n </Comp>\n );\n}\n\nexport interface InfoTipContentProps extends React.ComponentProps<\"div\"> {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\";\n align?: \"start\" | \"center\" | \"end\";\n sideOffset?: number;\n}\n\nexport function InfoTipContent({\n className,\n side: sideProp = \"bottom\",\n align = \"center\",\n sideOffset = 6,\n children,\n ...props\n}: InfoTipContentProps) {\n const { open, setOpen, anchorRef, contentId } = useInfoTip();\n const { isPresent, ref: presRef } = usePresence(open);\n const { floatingRef, style, side } = useFloating({\n anchorRef,\n open,\n side: sideProp,\n align,\n offset: sideOffset,\n });\n const dismissRef = useDismissableLayer({\n enabled: open,\n onDismiss: () => setOpen(false),\n exclude: [anchorRef],\n });\n if (!isPresent) return null;\n return (\n <Portal>\n <div\n id={contentId}\n role=\"status\"\n aria-live=\"polite\"\n data-slot=\"info-tip-content\"\n data-state={open ? \"open\" : \"closed\"}\n data-side={side}\n data-align={align}\n ref={mergeRefs(floatingRef, dismissRef, presRef)}\n style={style}\n className={cn(POPOVER_CONTENT, \"w-64 p-3 text-sm\", className)}\n {...(props as Record<string, unknown>)}\n >\n <DismissableLayerScope layer={dismissRef}>{children}</DismissableLayerScope>\n </div>\n </Portal>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/input-group.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { Button, type ButtonProps } from \"./button\";\nimport { Input } from \"./input\";\nimport { Textarea } from \"./textarea\";\nimport {\n INPUT_GROUP_ADDON_BASE,\n INPUT_GROUP_BASE,\n INPUT_GROUP_BUTTON_BASE,\n INPUT_GROUP_INPUT_CONTROL,\n INPUT_GROUP_TEXT,\n INPUT_GROUP_TEXTAREA_CONTROL,\n inputGroupAddonAligns,\n inputGroupButtonSizes,\n type InputGroupAddonAlign,\n type InputGroupButtonSize,\n} from \"../generated/input-group\";\n\nexport type { InputGroupAddonAlign, InputGroupButtonSize };\n\nexport function InputGroup({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"input-group\"\n role=\"group\"\n className={cn(INPUT_GROUP_BASE, className)}\n {...props}\n />\n );\n}\n\nexport interface InputGroupAddonProps extends React.ComponentProps<\"div\"> {\n align?: InputGroupAddonAlign;\n}\n\nexport function InputGroupAddon({\n className,\n align = \"inline-start\",\n ...props\n}: InputGroupAddonProps) {\n return (\n <div\n role=\"group\"\n data-slot=\"input-group-addon\"\n data-align={align}\n className={cn(\n INPUT_GROUP_ADDON_BASE,\n inputGroupAddonAligns[align],\n className,\n )}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) return;\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus();\n }}\n {...props}\n />\n );\n}\n\nexport interface InputGroupButtonProps\n extends Omit<ButtonProps, \"size\"> {\n size?: InputGroupButtonSize;\n}\n\nexport function InputGroupButton({\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"xs\",\n ...props\n}: InputGroupButtonProps) {\n return (\n <Button\n type={type}\n data-size={size}\n variant={variant}\n className={cn(\n INPUT_GROUP_BUTTON_BASE,\n inputGroupButtonSizes[size],\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function InputGroupText({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n className={cn(INPUT_GROUP_TEXT, className)}\n {...props}\n />\n );\n}\n\n// The group, not the control, owns the height, so the control takes neither the\n// kit's `size` nor the native one `Input` gave up for it.\nexport function InputGroupInput({\n className,\n ...props\n}: Omit<React.ComponentProps<\"input\">, \"size\">) {\n return (\n <Input\n data-slot=\"input-group-control\"\n className={cn(INPUT_GROUP_INPUT_CONTROL, className)}\n {...props}\n />\n );\n}\n\nexport function InputGroupTextarea({\n className,\n ...props\n}: React.ComponentProps<\"textarea\">) {\n return (\n <Textarea\n data-slot=\"input-group-control\"\n className={cn(INPUT_GROUP_TEXTAREA_CONTROL, className)}\n {...props}\n />\n );\n}\n"],"mappings":";AA2BI;AAzBJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,cAAgC;AACzC,SAAS,aAAa;AACtB,SAAS,gBAAgB;AACzB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAIA,SAAS,WAAW;AAAA,EACzB;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,MAAK;AAAA,MACL,WAAW,GAAG,kBAAkB,SAAS;AAAA,MACxC,GAAG;AAAA;AAAA,EACN;AAEJ;AAMO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,QAAQ;AAAA,EACR,GAAG;AACL,GAAyB;AACvB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAY;AAAA,MACZ,WAAW;AAAA,QACT;AAAA,QACA,sBAAsB,KAAK;AAAA,QAC3B;AAAA,MACF;AAAA,MACA,SAAS,CAAC,MAAM;AACd,YAAK,EAAE,OAAuB,QAAQ,QAAQ,EAAG;AACjD,UAAE,cAAc,eAAe,cAAc,OAAO,GAAG,MAAM;AAAA,MAC/D;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAOO,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,OAAO;AAAA,EACP,GAAG;AACL,GAA0B;AACxB,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,aAAW;AAAA,MACX;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA,sBAAsB,IAAI;AAAA,QAC1B;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA,GAAG;AACL,GAAiC;AAC/B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,kBAAkB,SAAS;AAAA,MACxC,GAAG;AAAA;AAAA,EACN;AAEJ;AAIO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA,GAAG;AACL,GAAgD;AAC9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,2BAA2B,SAAS;AAAA,MACjD,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,mBAAmB;AAAA,EACjC;AAAA,EACA,GAAG;AACL,GAAqC;AACnC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,8BAA8B,SAAS;AAAA,MACpD,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/input-otp.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { useControllableState } from \"../primitives/use-controllable-state\";\nimport {\n INPUT_OTP_CONTAINER,\n INPUT_OTP_GROUP,\n INPUT_OTP_INPUT,\n INPUT_OTP_SLOT,\n INPUT_OTP_SLOT_CARET,\n INPUT_OTP_SLOT_CARET_WRAPPER,\n} from \"../generated/input-otp\";\n\ntype InputOTPContextValue = {\n value: string;\n maxLength: number;\n activeIndex: number;\n};\n\nconst InputOTPContext = React.createContext<InputOTPContextValue | null>(null);\n\nfunction useInputOTP() {\n const context = React.useContext(InputOTPContext);\n if (!context) {\n throw new Error(\"InputOTP slots must be used within an <InputOTP />\");\n }\n return context;\n}\n\nexport interface InputOTPProps\n extends Omit<React.ComponentProps<\"input\">, \"value\" | \"defaultValue\" | \"onChange\"> {\n maxLength: number;\n value?: string;\n defaultValue?: string;\n onChange?: (value: string) => void;\n containerClassName?: string;\n children?: React.ReactNode;\n}\n\nexport function InputOTP({\n maxLength,\n value: valueProp,\n defaultValue = \"\",\n onChange,\n className,\n containerClassName,\n children,\n disabled,\n ...props\n}: InputOTPProps) {\n const [value, setValue] = useControllableState<string>({\n value: valueProp,\n defaultValue,\n onChange,\n });\n const [focused, setFocused] = React.useState(false);\n\n const activeIndex = focused ? Math.min(value.length, maxLength - 1) : -1;\n\n return (\n <InputOTPContext.Provider value={{ value, maxLength, activeIndex }}>\n <div\n data-slot=\"input-otp\"\n className={cn(INPUT_OTP_CONTAINER, containerClassName)}\n >\n {children}\n <input\n // drag/momentum: n/a — single visually-hidden input tracks the string\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n maxLength={maxLength}\n value={value}\n disabled={disabled}\n onChange={(e) => setValue(e.target.value.slice(0, maxLength))}\n onFocus={() => setFocused(true)}\n onBlur={() => setFocused(false)}\n className={cn(INPUT_OTP_INPUT, className)}\n {...props}\n />\n </div>\n </InputOTPContext.Provider>\n );\n}\n\nexport function InputOTPGroup({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"input-otp-group\"\n className={cn(INPUT_OTP_GROUP, className)}\n {...props}\n />\n );\n}\n\nexport interface InputOTPSlotProps extends React.ComponentProps<\"div\"> {\n index: number;\n}\n\nexport function InputOTPSlot({ index, className, ...props }: InputOTPSlotProps) {\n const { value, activeIndex } = useInputOTP();\n const char = value[index];\n const isActive = activeIndex === index;\n const hasFakeCaret = isActive && char === undefined;\n\n return (\n <div\n data-slot=\"input-otp-slot\"\n data-active={isActive}\n className={cn(INPUT_OTP_SLOT, className)}\n {...props}\n >\n {char}\n {hasFakeCaret && (\n <div className={INPUT_OTP_SLOT_CARET_WRAPPER}>\n <div className={INPUT_OTP_SLOT_CARET} />\n </div>\n )}\n </div>\n );\n}\n\nexport function InputOTPSeparator({ ...props }: React.ComponentProps<\"div\">) {\n return (\n <div data-slot=\"input-otp-separator\" role=\"separator\" {...props}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M5 12h14\" />\n </svg>\n </div>\n );\n}\n"],"mappings":";AA8DM,SAKE,KALF;AA5DN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAQP,MAAM,kBAAkB,MAAM,cAA2C,IAAI;AAE7E,SAAS,cAAc;AACrB,QAAM,UAAU,MAAM,WAAW,eAAe;AAChD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AACA,SAAO;AACT;AAYO,SAAS,SAAS;AAAA,EACvB;AAAA,EACA,OAAO;AAAA,EACP,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkB;AAChB,QAAM,CAAC,OAAO,QAAQ,IAAI,qBAA6B;AAAA,IACrD,OAAO;AAAA,IACP;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,CAAC,SAAS,UAAU,IAAI,MAAM,SAAS,KAAK;AAElD,QAAM,cAAc,UAAU,KAAK,IAAI,MAAM,QAAQ,YAAY,CAAC,IAAI;AAEtE,SACE,oBAAC,gBAAgB,UAAhB,EAAyB,OAAO,EAAE,OAAO,WAAW,YAAY,GAC/D;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,qBAAqB,kBAAkB;AAAA,MAEpD;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YAEC,WAAU;AAAA,YACV,cAAa;AAAA,YACb;AAAA,YACA;AAAA,YACA;AAAA,YACA,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,MAAM,MAAM,GAAG,SAAS,CAAC;AAAA,YAC5D,SAAS,MAAM,WAAW,IAAI;AAAA,YAC9B,QAAQ,MAAM,WAAW,KAAK;AAAA,YAC9B,WAAW,GAAG,iBAAiB,SAAS;AAAA,YACvC,GAAG;AAAA;AAAA,QACN;AAAA;AAAA;AAAA,EACF,GACF;AAEJ;AAEO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,iBAAiB,SAAS;AAAA,MACvC,GAAG;AAAA;AAAA,EACN;AAEJ;AAMO,SAAS,aAAa,EAAE,OAAO,WAAW,GAAG,MAAM,GAAsB;AAC9E,QAAM,EAAE,OAAO,YAAY,IAAI,YAAY;AAC3C,QAAM,OAAO,MAAM,KAAK;AACxB,QAAM,WAAW,gBAAgB;AACjC,QAAM,eAAe,YAAY,SAAS;AAE1C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,eAAa;AAAA,MACb,WAAW,GAAG,gBAAgB,SAAS;AAAA,MACtC,GAAG;AAAA,MAEH;AAAA;AAAA,QACA,gBACC,oBAAC,SAAI,WAAW,8BACd,8BAAC,SAAI,WAAW,sBAAsB,GACxC;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEO,SAAS,kBAAkB,EAAE,GAAG,MAAM,GAAgC;AAC3E,SACE,oBAAC,SAAI,aAAU,uBAAsB,MAAK,aAAa,GAAG,OACxD;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,QAAO;AAAA,MACP,aAAY;AAAA,MACZ,eAAc;AAAA,MACd,gBAAe;AAAA,MACf,eAAY;AAAA,MAEZ,8BAAC,UAAK,GAAE,YAAW;AAAA;AAAA,EACrB,GACF;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/input.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { INPUT_BASE, inputSizeClasses, type InputSize } from \"../generated/input\";\nimport { markLabelable } from \"../primitives/labelable\";\nimport { useFieldControlId } from \"./field-context\";\n\nexport type { InputSize };\n\n// The native `size` attribute (a width in characters) gives way to the kit's\n// scale, as it does on `NativeSelect`; a width belongs in `className`.\nexport interface InputProps extends Omit<React.ComponentPropsWithoutRef<\"input\">, \"size\"> {\n size?: InputSize;\n}\n\n// `forwardRef` rather than a `ref` prop so the handle also reaches the element\n// under React 18, where function components drop `ref`.\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n function Input({ className, type, id, size = \"md\", ...props }, ref) {\n return (\n <input\n ref={ref}\n type={type}\n id={useFieldControlId(id)}\n data-slot=\"input\"\n data-size={size}\n className={cn(INPUT_BASE, inputSizeClasses[size], className)}\n {...props}\n />\n );\n },\n);\n\nmarkLabelable(Input);\n"],"mappings":";AAqBM;AAnBN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,YAAY,wBAAwC;AAC7D,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAY3B,MAAM,QAAQ,MAAM;AAAA,EACzB,SAASA,OAAM,EAAE,WAAW,MAAM,IAAI,OAAO,MAAM,GAAG,MAAM,GAAG,KAAK;AAClE,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,IAAI,kBAAkB,EAAE;AAAA,QACxB,aAAU;AAAA,QACV,aAAW;AAAA,QACX,WAAW,GAAG,YAAY,iBAAiB,IAAI,GAAG,SAAS;AAAA,QAC1D,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AACF;AAEA,cAAc,KAAK;","names":["Input"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/item.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { Slot } from \"../primitives/slot\";\nimport { Separator } from \"./separator\";\nimport {\n ITEM_ACTIONS,\n ITEM_BASE,\n ITEM_CONTENT,\n ITEM_DESCRIPTION,\n ITEM_FOOTER,\n ITEM_GROUP,\n ITEM_HEADER,\n ITEM_MEDIA_BASE,\n ITEM_SEPARATOR,\n ITEM_TITLE,\n itemMediaVariants,\n itemSizes,\n itemVariants,\n type ItemMediaVariant,\n type ItemSize,\n type ItemVariant,\n} from \"../generated/item\";\n\nexport type { ItemMediaVariant, ItemSize, ItemVariant };\n\nexport function ItemGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n role=\"list\"\n data-slot=\"item-group\"\n className={cn(ITEM_GROUP, className)}\n {...props}\n />\n );\n}\n\nexport function ItemSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"item-separator\"\n orientation=\"horizontal\"\n className={cn(ITEM_SEPARATOR, className)}\n {...props}\n />\n );\n}\n\nexport interface ItemProps extends React.ComponentProps<\"div\"> {\n variant?: ItemVariant;\n size?: ItemSize;\n asChild?: boolean;\n}\n\nexport function Item({\n className,\n variant = \"bare\",\n size = \"md\",\n asChild = false,\n ...props\n}: ItemProps) {\n const Comp = asChild ? Slot : \"div\";\n return (\n <Comp\n data-slot=\"item\"\n data-variant={variant}\n data-size={size}\n className={cn(ITEM_BASE, itemVariants[variant], itemSizes[size], className)}\n {...(props as Record<string, unknown>)}\n />\n );\n}\n\nexport interface ItemMediaProps extends React.ComponentProps<\"div\"> {\n variant?: ItemMediaVariant;\n}\n\nexport function ItemMedia({\n className,\n variant = \"bare\",\n ...props\n}: ItemMediaProps) {\n return (\n <div\n data-slot=\"item-media\"\n data-variant={variant}\n className={cn(ITEM_MEDIA_BASE, itemMediaVariants[variant], className)}\n {...props}\n />\n );\n}\n\nexport function ItemContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-content\"\n className={cn(ITEM_CONTENT, className)}\n {...props}\n />\n );\n}\n\nexport function ItemTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-title\"\n className={cn(ITEM_TITLE, className)}\n {...props}\n />\n );\n}\n\nexport function ItemDescription({\n className,\n ...props\n}: React.ComponentProps<\"p\">) {\n return (\n <p\n data-slot=\"item-description\"\n className={cn(ITEM_DESCRIPTION, className)}\n {...props}\n />\n );\n}\n\nexport function ItemActions({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-actions\"\n className={cn(ITEM_ACTIONS, className)}\n {...props}\n />\n );\n}\n\nexport function ItemHeader({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-header\"\n className={cn(ITEM_HEADER, className)}\n {...props}\n />\n );\n}\n\nexport function ItemFooter({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"item-footer\"\n className={cn(ITEM_FOOTER, className)}\n {...props}\n />\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/kbd.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { KBD_BASE, KBD_GROUP_BASE } from \"../generated/kbd\";\n\nexport function Kbd({ className, ...props }: React.ComponentProps<\"kbd\">) {\n return (\n <kbd\n data-slot=\"kbd\"\n className={cn(KBD_BASE, className)}\n {...props}\n />\n );\n}\n\nexport function KbdGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <kbd\n data-slot=\"kbd-group\"\n className={cn(KBD_GROUP_BASE, className)}\n {...props}\n />\n );\n}\n"],"mappings":"AAMI;AANJ,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,UAAU,sBAAsB;AAElC,SAAS,IAAI,EAAE,WAAW,GAAG,MAAM,GAAgC;AACxE,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,UAAU,SAAS;AAAA,MAChC,GAAG;AAAA;AAAA,EACN;AAEJ;AAEO,SAAS,SAAS,EAAE,WAAW,GAAG,MAAM,GAAgC;AAC7E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,gBAAgB,SAAS;AAAA,MACtC,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/key-value.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport {\n KEY_VALUE_BASE,\n KEY_VALUE_COPY,\n KEY_VALUE_LABEL,\n KEY_VALUE_ROW,\n KEY_VALUE_STATUS,\n KEY_VALUE_VALUE,\n} from \"../generated/key-value\";\nimport { UiIcon } from \"./ui-icons\";\n\nexport interface KeyValueLabels {\n /** The copy button. Default `\"Copy {label}\"` (just `\"Copy\"` when the label is not text). */\n copy?: string;\n /** The polite announcement after a copy. Default `\"Copied\"`. */\n copied?: string;\n}\n\nexport interface KeyValueProps extends Omit<React.ComponentProps<\"div\">, \"children\"> {\n label: React.ReactNode;\n value: React.ReactNode;\n /** Adds a copy button for this text. */\n copyText?: string;\n labels?: KeyValueLabels;\n}\n\nconst COPIED_MS = 2000;\n\n// The async clipboard API needs a secure context and a user gesture; an\n// insecure origin or an old webview falls back to a selection + execCommand.\nasync function writeClipboard(text: string): Promise<boolean> {\n try {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(text);\n return true;\n }\n } catch {\n // Denied permission: try the selection route below.\n }\n // Inside a modal the focus scope pulls focus back to the dialog, which would drop a selection\n // made in <body>; the helper has to live inside the dialog the user is in.\n const host = document.activeElement?.closest('[role=\"dialog\"]') ?? document.body;\n const area = document.createElement(\"textarea\");\n area.value = text;\n area.setAttribute(\"readonly\", \"\");\n area.style.position = \"fixed\";\n area.style.opacity = \"0\";\n host.append(area);\n area.select();\n try {\n return document.execCommand(\"copy\");\n } finally {\n area.remove();\n }\n}\n\n/** A small label over its value, with an optional copy button. */\nexport function KeyValue({ label, value, copyText, labels = {}, className, ...props }: KeyValueProps) {\n const [copied, setCopied] = React.useState(false);\n const timer = React.useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n React.useEffect(() => () => clearTimeout(timer.current), []);\n\n const copy = async () => {\n if (copyText === undefined || !(await writeClipboard(copyText))) return;\n setCopied(true);\n clearTimeout(timer.current);\n timer.current = setTimeout(() => setCopied(false), COPIED_MS);\n };\n\n return (\n <div data-slot=\"key-value\" className={cn(KEY_VALUE_BASE, className)} {...props}>\n <span className={KEY_VALUE_LABEL}>{label}</span>\n <div className={KEY_VALUE_ROW}>\n <span className={KEY_VALUE_VALUE}>{value}</span>\n {copyText !== undefined && (\n <button\n type=\"button\"\n aria-label={labels.copy ?? (typeof label === \"string\" ? `Copy ${label}` : \"Copy\")}\n onClick={copy}\n className={KEY_VALUE_COPY}\n >\n <UiIcon name={copied ? \"check\" : \"copy\"} />\n </button>\n )}\n </div>\n <span role=\"status\" aria-live=\"polite\" className={KEY_VALUE_STATUS}>\n {copied ? (labels.copied ?? \"Copied\") : \"\"}\n </span>\n </div>\n );\n}\n"],"mappings":";AA0EM,cACA,YADA;AAxEN,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AAiBvB,MAAM,YAAY;AAIlB,eAAe,eAAe,MAAgC;AAC5D,MAAI;AACF,QAAI,UAAU,WAAW,WAAW;AAClC,YAAM,UAAU,UAAU,UAAU,IAAI;AACxC,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAER;AAGA,QAAM,OAAO,SAAS,eAAe,QAAQ,iBAAiB,KAAK,SAAS;AAC5E,QAAM,OAAO,SAAS,cAAc,UAAU;AAC9C,OAAK,QAAQ;AACb,OAAK,aAAa,YAAY,EAAE;AAChC,OAAK,MAAM,WAAW;AACtB,OAAK,MAAM,UAAU;AACrB,OAAK,OAAO,IAAI;AAChB,OAAK,OAAO;AACZ,MAAI;AACF,WAAO,SAAS,YAAY,MAAM;AAAA,EACpC,UAAE;AACA,SAAK,OAAO;AAAA,EACd;AACF;AAGO,SAAS,SAAS,EAAE,OAAO,OAAO,UAAU,SAAS,CAAC,GAAG,WAAW,GAAG,MAAM,GAAkB;AACpG,QAAM,CAAC,QAAQ,SAAS,IAAI,MAAM,SAAS,KAAK;AAChD,QAAM,QAAQ,MAAM,OAAkD,MAAS;AAC/E,QAAM,UAAU,MAAM,MAAM,aAAa,MAAM,OAAO,GAAG,CAAC,CAAC;AAE3D,QAAM,OAAO,YAAY;AACvB,QAAI,aAAa,UAAa,CAAE,MAAM,eAAe,QAAQ,EAAI;AACjE,cAAU,IAAI;AACd,iBAAa,MAAM,OAAO;AAC1B,UAAM,UAAU,WAAW,MAAM,UAAU,KAAK,GAAG,SAAS;AAAA,EAC9D;AAEA,SACE,qBAAC,SAAI,aAAU,aAAY,WAAW,GAAG,gBAAgB,SAAS,GAAI,GAAG,OACvE;AAAA,wBAAC,UAAK,WAAW,iBAAkB,iBAAM;AAAA,IACzC,qBAAC,SAAI,WAAW,eACd;AAAA,0BAAC,UAAK,WAAW,iBAAkB,iBAAM;AAAA,MACxC,aAAa,UACZ;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,cAAY,OAAO,SAAS,OAAO,UAAU,WAAW,QAAQ,KAAK,KAAK;AAAA,UAC1E,SAAS;AAAA,UACT,WAAW;AAAA,UAEX,8BAAC,UAAO,MAAM,SAAS,UAAU,QAAQ;AAAA;AAAA,MAC3C;AAAA,OAEJ;AAAA,IACA,oBAAC,UAAK,MAAK,UAAS,aAAU,UAAS,WAAW,kBAC/C,mBAAU,OAAO,UAAU,WAAY,IAC1C;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/label.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\nimport { LABEL_BASE } from \"../generated/label\";\n\nexport function Label({ className, ...props }: React.ComponentProps<\"label\">) {\n return <label data-slot=\"label\" className={cn(LABEL_BASE, className)} {...props} />;\n}\n"],"mappings":"AAKS;AALT,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,kBAAkB;AAEpB,SAAS,MAAM,EAAE,WAAW,GAAG,MAAM,GAAkC;AAC5E,SAAO,oBAAC,WAAM,aAAU,SAAQ,WAAW,GAAG,YAAY,SAAS,GAAI,GAAG,OAAO;AACnF;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/list-rows.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\n\n// The phone form of a table: a list of label/value rows split by hairlines.\n// A table scrolled sideways on a phone hides the trailing columns — usually the\n// date and the action, the reason the list was opened. TS-only (README\n// \"Limitations\").\n\nexport type ListRowsVariant = \"plain\" | \"card\";\n\nconst LIST_ROWS = \"flex w-full min-w-0 flex-col divide-y divide-border\";\n\n// `plain` sits in a container that already pads (a padded card, a section);\n// `card` is edge to edge in a `TableCard`, so the rows pad themselves and the\n// hairlines run the card's full width. The inset travels as a custom property,\n// as the table's cell padding does, so a row's own `px-*` still wins.\nconst listRowsVariants: Record<ListRowsVariant, string> = {\n plain: \"\",\n card: \"[--ev-list-row-x:1rem]\",\n};\n\nexport interface ListRowsProps extends React.ComponentProps<\"ul\"> {\n variant?: ListRowsVariant;\n}\n\nexport function ListRows({ variant = \"plain\", className, ...props }: ListRowsProps) {\n return (\n <ul\n data-slot=\"list-rows\"\n data-variant={variant}\n className={cn(LIST_ROWS, listRowsVariants[variant], className)}\n {...props}\n />\n );\n}\n\nconst LIST_ROW = \"flex min-w-0 items-center justify-between gap-3 px-[var(--ev-list-row-x,0px)] py-3\";\n\n// `<li value>` is an ordinal for `<ol>`; in an unordered list of rows the name\n// is far more useful for the trailing figure.\nexport interface ListRowProps extends Omit<React.ComponentProps<\"li\">, \"value\"> {\n /** The row's title. Omit it (and `value`) to lay the row out yourself. */\n label?: React.ReactNode;\n /** A caption a step down under the label. */\n description?: React.ReactNode;\n /** Trailing value, right-aligned and truncated rather than pushing the row wide. */\n value?: React.ReactNode;\n}\n\n/**\n * One row: label (and description) leading, value trailing, then `children`\n * (a badge, an action). With neither `label` nor `value` the children are the\n * whole row.\n */\nexport function ListRow({ label, description, value, className, children, ...props }: ListRowProps) {\n return (\n <li\n data-slot=\"list-row\"\n className={cn(LIST_ROW, className)}\n {...props}\n >\n {(label != null || description != null) && (\n <ListRowLabel description={description}>{label}</ListRowLabel>\n )}\n {value != null && <ListRowValue>{value}</ListRowValue>}\n {children}\n </li>\n );\n}\n\nexport interface ListRowLabelProps extends Omit<React.ComponentProps<\"div\">, \"title\"> {\n description?: React.ReactNode;\n}\n\n/** The leading block on its own, for a row you compose by hand. */\nexport function ListRowLabel({ description, className, children, ...props }: ListRowLabelProps) {\n return (\n <div\n data-slot=\"list-row-label\"\n className={cn(\"flex min-w-0 flex-1 flex-col gap-0.5\", className)}\n {...props}\n >\n <span className=\"text-sm font-medium text-ink\">{children}</span>\n {description != null && (\n <span\n data-slot=\"list-row-description\"\n className=\"text-xs leading-snug text-ink-soft\"\n >\n {description}\n </span>\n )}\n </div>\n );\n}\n\n/**\n * The trailing value. It shares the label's type step, so the muted tone and\n * the lighter weight are what keep the label reading first; digits are tabular\n * so a figure in one row lines up with the next.\n */\nexport function ListRowValue({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"list-row-value\"\n className={cn(\"min-w-0 truncate text-right text-sm tabular-nums text-ink-soft\", className)}\n {...props}\n />\n );\n}\n"],"mappings":"AA2BI,cA6BA,YA7BA;AA3BJ,YAAY,WAAW;AACvB,SAAS,UAAU;AASnB,MAAM,YAAY;AAMlB,MAAM,mBAAoD;AAAA,EACxD,OAAO;AAAA,EACP,MAAM;AACR;AAMO,SAAS,SAAS,EAAE,UAAU,SAAS,WAAW,GAAG,MAAM,GAAkB;AAClF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,gBAAc;AAAA,MACd,WAAW,GAAG,WAAW,iBAAiB,OAAO,GAAG,SAAS;AAAA,MAC5D,GAAG;AAAA;AAAA,EACN;AAEJ;AAEA,MAAM,WAAW;AAkBV,SAAS,QAAQ,EAAE,OAAO,aAAa,OAAO,WAAW,UAAU,GAAG,MAAM,GAAiB;AAClG,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,UAAU,SAAS;AAAA,MAChC,GAAG;AAAA,MAEF;AAAA,kBAAS,QAAQ,eAAe,SAChC,oBAAC,gBAAa,aAA2B,iBAAM;AAAA,QAEhD,SAAS,QAAQ,oBAAC,gBAAc,iBAAM;AAAA,QACtC;AAAA;AAAA;AAAA,EACH;AAEJ;AAOO,SAAS,aAAa,EAAE,aAAa,WAAW,UAAU,GAAG,MAAM,GAAsB;AAC9F,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,wCAAwC,SAAS;AAAA,MAC9D,GAAG;AAAA,MAEJ;AAAA,4BAAC,UAAK,WAAU,gCAAgC,UAAS;AAAA,QACxD,eAAe,QACd;AAAA,UAAC;AAAA;AAAA,YACC,aAAU;AAAA,YACV,WAAU;AAAA,YAET;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAOO,SAAS,aAAa,EAAE,WAAW,GAAG,MAAM,GAAiC;AAClF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,kEAAkE,SAAS;AAAA,MACxF,GAAG;AAAA;AAAA,EACN;AAEJ;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/logo.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../lib/cn\";\n\n/**\n * The consumer's mark, painted as a CSS mask (`backgroundColor: currentColor` +\n * `maskImage`) so a monochrome lockup follows the surrounding text colour\n * instead of the artwork's baked-in fill. `withBackground` seats it on the brand\n * field, keeping a chip consistent with a favicon.\n *\n * The kit ships no artwork. The mark is a design token like every colour: the\n * consumer declares `--brand-mark` — a `url()` at its own asset — and\n * `--brand-aspect` in the same sheet it declares the palette in (see\n * `styles/tokens.css`). Undeclared, `maskImage` is invalid at computed-value time\n * and the span paints as a solid block: loud, and nobody else's logo.\n *\n * Decorative by design (`aria-hidden`): every real call site has the brand name\n * in adjacent text or on the wrapping link, and a mark announced twice is worse\n * than one announced once.\n */\nexport interface LogoProps {\n className?: string;\n withBackground?: boolean;\n}\n\nconst maskStyle: React.CSSProperties = {\n backgroundColor: \"currentColor\",\n maskImage: \"var(--brand-mark)\",\n WebkitMaskImage: \"var(--brand-mark)\",\n maskRepeat: \"no-repeat\",\n WebkitMaskRepeat: \"no-repeat\",\n maskPosition: \"center\",\n WebkitMaskPosition: \"center\",\n maskSize: \"contain\",\n WebkitMaskSize: \"contain\",\n // the ratio's fallback is what makes a missing mark *visible*: a masked span\n // has no intrinsic size, so `h-N w-auto` without it is zero-width\n aspectRatio: \"var(--brand-aspect, 1)\",\n};\n\nexport function Logo({ className, withBackground = false }: LogoProps) {\n const mark = (\n <span\n data-slot=\"logo\"\n aria-hidden\n style={maskStyle}\n className={cn(\"inline-block\", withBackground ? \"w-3/5 h-3/5\" : className)}\n />\n );\n\n if (!withBackground) return mark;\n\n return (\n <span\n data-slot=\"logo-background\"\n className={cn(\"inline-flex items-center justify-center bg-brand\", className)}\n >\n {mark}\n </span>\n );\n}\n"],"mappings":"AAyCI;AAzCJ,YAAY,WAAW;AACvB,SAAS,UAAU;AAuBnB,MAAM,YAAiC;AAAA,EACrC,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,gBAAgB;AAAA;AAAA;AAAA,EAGhB,aAAa;AACf;AAEO,SAAS,KAAK,EAAE,WAAW,iBAAiB,MAAM,GAAc;AACrE,QAAM,OACJ;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,eAAW;AAAA,MACX,OAAO;AAAA,MACP,WAAW,GAAG,gBAAgB,iBAAiB,gBAAgB,SAAS;AAAA;AAAA,EAC1E;AAGF,MAAI,CAAC,eAAgB,QAAO;AAE5B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,aAAU;AAAA,MACV,WAAW,GAAG,oDAAoD,SAAS;AAAA,MAE1E;AAAA;AAAA,EACH;AAEJ;","names":[]}
|