@adea-ai/ui 0.61.0 → 0.62.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 +44 -6
- package/dist/LICENSE +201 -0
- package/dist/NOTICE +50 -0
- package/dist/components/composites/account-menu/index.js +2 -0
- package/dist/components/composites/list-row/index.js +2 -0
- package/dist/components/composites/settings/index.js +2 -0
- package/dist/components/composites/stat/index.js +2 -0
- package/dist/components/composites/update-dialog/index.js +2 -0
- package/dist/components/composites/workspace-mark/index.js +2 -0
- package/dist/components/conversation/index.js +6 -0
- package/dist/components/layout/app-shell/index.js +2 -0
- package/dist/components/layout/page/index.js +2 -0
- package/dist/components/layout/panel/index.js +2 -0
- package/dist/components/layout/side-rail/index.js +3 -0
- package/dist/components/layout/sidebar-nav/index.js +2 -0
- package/dist/components/layout/status-bar/index.js +2 -0
- package/dist/components/layout/top-bar/index.js +2 -0
- package/dist/components/motion/index.js +2 -2
- package/dist/components/theme/index.js +5 -0
- package/dist/components/ui/accordion/index.js +2 -0
- package/dist/components/ui/alert/index.js +2 -0
- package/dist/components/ui/alert-dialog/index.js +2 -0
- package/dist/components/ui/aspect-ratio/index.js +2 -0
- package/dist/components/ui/avatar/index.js +2 -0
- package/dist/components/ui/badge/index.js +2 -0
- package/dist/components/ui/board/index.js +2 -0
- package/dist/components/ui/breadcrumb/index.js +2 -0
- package/dist/components/ui/button/index.js +2 -0
- package/dist/components/ui/button-group/index.js +2 -0
- package/dist/components/ui/calendar/index.js +2 -0
- package/dist/components/ui/card/index.js +2 -0
- package/dist/components/ui/carousel/index.js +2 -0
- package/dist/components/ui/chart/index.js +2 -0
- package/dist/components/ui/checkbox/index.js +2 -0
- package/dist/components/ui/code-block/index.js +2 -0
- package/dist/components/ui/collapsible/index.js +2 -0
- package/dist/components/ui/combobox/index.js +2 -0
- package/dist/components/ui/command/index.js +2 -0
- package/dist/components/ui/context-menu/index.js +2 -0
- package/dist/components/ui/detail-panel/index.js +2 -0
- package/dist/components/ui/dialog/index.js +2 -0
- package/dist/components/ui/diff-block/index.js +2 -0
- package/dist/components/ui/drawer/index.js +2 -0
- package/dist/components/ui/dropdown-menu/index.js +2 -0
- package/dist/components/ui/empty/index.js +2 -0
- package/dist/components/ui/entity-icon/index.js +2 -0
- package/dist/components/ui/field/index.js +2 -0
- package/dist/components/ui/hover-card/index.js +2 -0
- package/dist/components/ui/input/index.js +2 -0
- package/dist/components/ui/input-group/index.js +2 -0
- package/dist/components/ui/input-otp/index.js +2 -0
- package/dist/components/ui/item/index.js +2 -0
- package/dist/components/ui/kbd/index.js +2 -0
- package/dist/components/ui/label/index.js +2 -0
- package/dist/components/ui/menubar/index.js +2 -0
- package/dist/components/ui/modal-dialog/index.js +2 -0
- package/dist/components/ui/navigation-menu/index.js +2 -0
- package/dist/components/ui/pagination/index.js +2 -0
- package/dist/components/ui/popover/index.js +2 -0
- package/dist/components/ui/progress/index.js +2 -0
- package/dist/components/ui/radio-group/index.js +2 -0
- package/dist/components/ui/resizable/index.js +2 -0
- package/dist/components/ui/scroll-area/index.js +2 -0
- package/dist/components/ui/select/index.js +2 -0
- package/dist/components/ui/separator/index.js +2 -0
- package/dist/components/ui/sheet/index.js +2 -0
- package/dist/components/ui/skeleton/index.js +2 -0
- package/dist/components/ui/slider/index.js +2 -0
- package/dist/components/ui/spinner/index.js +2 -0
- package/dist/components/ui/status-chip/index.js +2 -0
- package/dist/components/ui/switch/index.js +2 -0
- package/dist/components/ui/table/index.js +2 -0
- package/dist/components/ui/tabs/index.js +2 -0
- package/dist/components/ui/textarea/index.js +2 -0
- package/dist/components/ui/toast/index.js +2 -0
- package/dist/components/ui/toggle/index.js +2 -0
- package/dist/components/ui/toggle-group/index.js +2 -0
- package/dist/components/ui/tooltip/index.js +2 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/r/accordion.json +3 -1
- package/dist/r/account-menu.json +2 -1
- package/dist/r/alert-dialog.json +3 -1
- package/dist/r/alert.json +3 -1
- package/dist/r/app-shell.json +3 -1
- package/dist/r/aspect-ratio.json +3 -1
- package/dist/r/avatar.json +3 -1
- package/dist/r/badge.json +3 -1
- package/dist/r/board.json +3 -1
- package/dist/r/breadcrumb.json +3 -1
- package/dist/r/button-group.json +2 -1
- package/dist/r/button.json +3 -1
- package/dist/r/calendar.json +2 -1
- package/dist/r/card.json +3 -1
- package/dist/r/carousel.json +2 -1
- package/dist/r/chart.json +3 -1
- package/dist/r/checkbox.json +3 -1
- package/dist/r/code-block.json +2 -1
- package/dist/r/collapsible.json +3 -1
- package/dist/r/combobox.json +3 -1
- package/dist/r/command.json +3 -1
- package/dist/r/context-menu.json +3 -1
- package/dist/r/conversation.json +2 -1
- package/dist/r/detail-panel.json +2 -1
- package/dist/r/dialog.json +3 -1
- package/dist/r/diff-block.json +3 -1
- package/dist/r/drawer.json +3 -1
- package/dist/r/dropdown-menu.json +3 -1
- package/dist/r/empty.json +3 -1
- package/dist/r/entity-icon.json +3 -1
- package/dist/r/field.json +3 -1
- package/dist/r/hover-card.json +3 -1
- package/dist/r/input-group.json +3 -1
- package/dist/r/input-otp.json +3 -1
- package/dist/r/input.json +3 -1
- package/dist/r/item.json +3 -1
- package/dist/r/kbd.json +3 -1
- package/dist/r/label.json +3 -1
- package/dist/r/lib.json +50 -0
- package/dist/r/list-row.json +3 -1
- package/dist/r/menubar.json +3 -1
- package/dist/r/modal-dialog.json +2 -1
- package/dist/r/motion.json +22 -0
- package/dist/r/navigation-menu.json +3 -1
- package/dist/r/page.json +3 -1
- package/dist/r/pagination.json +3 -1
- package/dist/r/panel.json +3 -1
- package/dist/r/popover.json +3 -1
- package/dist/r/progress.json +3 -1
- package/dist/r/radio-group.json +3 -1
- package/dist/r/registry.json +320 -73
- package/dist/r/resizable.json +3 -1
- package/dist/r/scroll-area.json +3 -1
- package/dist/r/select.json +3 -1
- package/dist/r/separator.json +3 -1
- package/dist/r/settings.json +3 -1
- package/dist/r/sheet.json +2 -1
- package/dist/r/side-rail.json +3 -1
- package/dist/r/sidebar-nav.json +3 -1
- package/dist/r/skeleton.json +3 -1
- package/dist/r/slider.json +3 -1
- package/dist/r/spinner.json +3 -1
- package/dist/r/src/components/composites/account-menu/account-menu.tsx +150 -0
- package/dist/r/src/components/composites/account-menu/index.ts +1 -0
- package/dist/r/src/components/composites/list-row/index.ts +1 -0
- package/dist/r/src/components/composites/list-row/list-row.tsx +116 -0
- package/dist/r/src/components/composites/settings/index.ts +1 -0
- package/dist/r/src/components/composites/settings/settings.tsx +142 -0
- package/dist/r/src/components/composites/stat/index.ts +9 -0
- package/dist/r/src/components/composites/stat/stat.tsx +155 -0
- package/dist/r/src/components/composites/update-dialog/index.ts +7 -0
- package/dist/r/src/components/composites/update-dialog/update-dialog.tsx +529 -0
- package/dist/r/src/components/composites/workspace-mark/index.ts +1 -0
- package/dist/r/src/components/composites/workspace-mark/workspace-mark.tsx +72 -0
- package/dist/r/src/components/conversation/conversation-avatar.tsx +60 -0
- package/dist/r/src/components/conversation/conversation-surface.tsx +107 -0
- package/dist/r/src/components/conversation/index.ts +25 -0
- package/dist/r/src/components/conversation/message-composer.tsx +239 -0
- package/dist/r/src/components/conversation/message-row.tsx +387 -0
- package/dist/r/src/components/conversation/thread-panel.tsx +141 -0
- package/dist/r/src/components/layout/app-shell/app-shell.tsx +92 -0
- package/dist/r/src/components/layout/app-shell/index.ts +1 -0
- package/dist/r/src/components/layout/page/index.ts +9 -0
- package/dist/r/src/components/layout/page/page.tsx +122 -0
- package/dist/r/src/components/layout/panel/index.ts +12 -0
- package/dist/r/src/components/layout/panel/panel.tsx +166 -0
- package/dist/r/src/components/layout/side-rail/index.ts +12 -0
- package/dist/r/src/components/layout/side-rail/side-rail-context.ts +42 -0
- package/dist/r/src/components/layout/side-rail/side-rail.tsx +405 -0
- package/dist/r/src/components/layout/sidebar-nav/index.ts +14 -0
- package/dist/r/src/components/layout/sidebar-nav/sidebar-nav.tsx +244 -0
- package/dist/r/src/components/layout/status-bar/index.ts +1 -0
- package/dist/r/src/components/layout/status-bar/status-bar.tsx +73 -0
- package/dist/r/src/components/layout/top-bar/index.ts +10 -0
- package/dist/r/src/components/layout/top-bar/top-bar.tsx +166 -0
- package/dist/r/src/components/motion/index.ts +2 -0
- package/dist/r/src/components/motion/presence.tsx +32 -0
- package/dist/r/src/components/theme/appearance-panel.tsx +179 -0
- package/dist/r/src/components/theme/index.ts +22 -0
- package/dist/r/src/components/theme/theme-picker.tsx +174 -0
- package/dist/r/src/components/theme/theme-provider.tsx +309 -0
- package/dist/r/src/components/theme/theme-toggle.tsx +64 -0
- package/dist/r/src/components/ui/accordion/accordion.tsx +66 -0
- package/dist/r/src/components/ui/accordion/index.ts +1 -0
- package/dist/r/src/components/ui/alert/alert.tsx +95 -0
- package/dist/r/src/components/ui/alert/index.ts +1 -0
- package/dist/r/src/components/ui/alert-dialog/alert-dialog.tsx +176 -0
- package/dist/r/src/components/ui/alert-dialog/index.ts +13 -0
- package/dist/r/src/components/ui/aspect-ratio/aspect-ratio.tsx +38 -0
- package/dist/r/src/components/ui/aspect-ratio/index.ts +1 -0
- package/dist/r/src/components/ui/avatar/avatar.tsx +114 -0
- package/dist/r/src/components/ui/avatar/index.ts +9 -0
- package/dist/r/src/components/ui/badge/badge.tsx +59 -0
- package/dist/r/src/components/ui/badge/index.ts +1 -0
- package/dist/r/src/components/ui/board/board.tsx +254 -0
- package/dist/r/src/components/ui/board/index.ts +10 -0
- package/dist/r/src/components/ui/breadcrumb/breadcrumb.tsx +117 -0
- package/dist/r/src/components/ui/breadcrumb/index.ts +9 -0
- package/dist/r/src/components/ui/button/button.tsx +89 -0
- package/dist/r/src/components/ui/button/index.ts +1 -0
- package/dist/r/src/components/ui/button-group/button-group.tsx +92 -0
- package/dist/r/src/components/ui/button-group/index.ts +6 -0
- package/dist/r/src/components/ui/calendar/calendar.tsx +277 -0
- package/dist/r/src/components/ui/calendar/index.ts +1 -0
- package/dist/r/src/components/ui/card/card.tsx +82 -0
- package/dist/r/src/components/ui/card/index.ts +10 -0
- package/dist/r/src/components/ui/carousel/carousel.tsx +209 -0
- package/dist/r/src/components/ui/carousel/index.ts +1 -0
- package/dist/r/src/components/ui/chart/chart.tsx +413 -0
- package/dist/r/src/components/ui/chart/index.ts +17 -0
- package/dist/r/src/components/ui/checkbox/checkbox.tsx +99 -0
- package/dist/r/src/components/ui/checkbox/index.ts +1 -0
- package/dist/r/src/components/ui/code-block/code-block.tsx +238 -0
- package/dist/r/src/components/ui/code-block/index.ts +1 -0
- package/dist/r/src/components/ui/collapsible/collapsible.tsx +54 -0
- package/dist/r/src/components/ui/collapsible/index.ts +1 -0
- package/dist/r/src/components/ui/combobox/combobox.tsx +142 -0
- package/dist/r/src/components/ui/combobox/index.ts +10 -0
- package/dist/r/src/components/ui/command/command.tsx +214 -0
- package/dist/r/src/components/ui/command/index.ts +12 -0
- package/dist/r/src/components/ui/context-menu/context-menu.tsx +163 -0
- package/dist/r/src/components/ui/context-menu/index.ts +15 -0
- package/dist/r/src/components/ui/detail-panel/detail-panel.tsx +161 -0
- package/dist/r/src/components/ui/detail-panel/index.ts +9 -0
- package/dist/r/src/components/ui/dialog/dialog.tsx +138 -0
- package/dist/r/src/components/ui/dialog/index.ts +14 -0
- package/dist/r/src/components/ui/diff-block/diff-block.tsx +286 -0
- package/dist/r/src/components/ui/diff-block/index.ts +11 -0
- package/dist/r/src/components/ui/drawer/drawer.tsx +144 -0
- package/dist/r/src/components/ui/drawer/index.ts +13 -0
- package/dist/r/src/components/ui/dropdown-menu/dropdown-menu.tsx +203 -0
- package/dist/r/src/components/ui/dropdown-menu/index.ts +18 -0
- package/dist/r/src/components/ui/empty/empty.tsx +104 -0
- package/dist/r/src/components/ui/empty/index.ts +10 -0
- package/dist/r/src/components/ui/entity-icon/entity-icon.tsx +154 -0
- package/dist/r/src/components/ui/entity-icon/index.ts +1 -0
- package/dist/r/src/components/ui/field/field.tsx +131 -0
- package/dist/r/src/components/ui/field/index.ts +11 -0
- package/dist/r/src/components/ui/hover-card/hover-card.tsx +48 -0
- package/dist/r/src/components/ui/hover-card/index.ts +1 -0
- package/dist/r/src/components/ui/input/index.ts +1 -0
- package/dist/r/src/components/ui/input/input.tsx +41 -0
- package/dist/r/src/components/ui/input-group/index.ts +8 -0
- package/dist/r/src/components/ui/input-group/input-group.tsx +111 -0
- package/dist/r/src/components/ui/input-otp/index.ts +1 -0
- package/dist/r/src/components/ui/input-otp/input-otp.tsx +108 -0
- package/dist/r/src/components/ui/item/index.ts +10 -0
- package/dist/r/src/components/ui/item/item.tsx +146 -0
- package/dist/r/src/components/ui/kbd/index.ts +1 -0
- package/dist/r/src/components/ui/kbd/kbd.tsx +42 -0
- package/dist/r/src/components/ui/label/index.ts +1 -0
- package/dist/r/src/components/ui/label/label.tsx +36 -0
- package/dist/r/src/components/ui/menubar/index.ts +16 -0
- package/dist/r/src/components/ui/menubar/menubar.tsx +190 -0
- package/dist/r/src/components/ui/modal-dialog/index.ts +1 -0
- package/dist/r/src/components/ui/modal-dialog/modal-dialog.tsx +95 -0
- package/dist/r/src/components/ui/navigation-menu/index.ts +13 -0
- package/dist/r/src/components/ui/navigation-menu/navigation-menu.tsx +229 -0
- package/dist/r/src/components/ui/pagination/index.ts +8 -0
- package/dist/r/src/components/ui/pagination/pagination.tsx +144 -0
- package/dist/r/src/components/ui/popover/index.ts +10 -0
- package/dist/r/src/components/ui/popover/popover.tsx +81 -0
- package/dist/r/src/components/ui/progress/index.ts +1 -0
- package/dist/r/src/components/ui/progress/progress.tsx +67 -0
- package/dist/r/src/components/ui/radio-group/index.ts +1 -0
- package/dist/r/src/components/ui/radio-group/radio-group.tsx +78 -0
- package/dist/r/src/components/ui/resizable/index.ts +6 -0
- package/dist/r/src/components/ui/resizable/resizable.tsx +74 -0
- package/dist/r/src/components/ui/scroll-area/index.ts +1 -0
- package/dist/r/src/components/ui/scroll-area/scroll-area.tsx +66 -0
- package/dist/r/src/components/ui/select/index.ts +11 -0
- package/dist/r/src/components/ui/select/select.tsx +188 -0
- package/dist/r/src/components/ui/separator/index.ts +1 -0
- package/dist/r/src/components/ui/separator/separator.tsx +40 -0
- package/dist/r/src/components/ui/sheet/index.ts +13 -0
- package/dist/r/src/components/ui/sheet/sheet.tsx +132 -0
- package/dist/r/src/components/ui/skeleton/index.ts +1 -0
- package/dist/r/src/components/ui/skeleton/skeleton.tsx +28 -0
- package/dist/r/src/components/ui/slider/index.ts +1 -0
- package/dist/r/src/components/ui/slider/slider.tsx +81 -0
- package/dist/r/src/components/ui/spinner/index.ts +1 -0
- package/dist/r/src/components/ui/spinner/spinner.tsx +58 -0
- package/dist/r/src/components/ui/status-chip/index.ts +8 -0
- package/dist/r/src/components/ui/status-chip/status-chip.tsx +142 -0
- package/dist/r/src/components/ui/switch/index.ts +1 -0
- package/dist/r/src/components/ui/switch/switch.tsx +100 -0
- package/dist/r/src/components/ui/table/index.ts +11 -0
- package/dist/r/src/components/ui/table/table.tsx +125 -0
- package/dist/r/src/components/ui/tabs/index.ts +8 -0
- package/dist/r/src/components/ui/tabs/tabs.tsx +77 -0
- package/dist/r/src/components/ui/textarea/index.ts +1 -0
- package/dist/r/src/components/ui/textarea/textarea.tsx +36 -0
- package/dist/r/src/components/ui/toast/index.ts +1 -0
- package/dist/r/src/components/ui/toast/toast.tsx +220 -0
- package/dist/r/src/components/ui/toggle/index.ts +1 -0
- package/dist/r/src/components/ui/toggle/toggle.tsx +60 -0
- package/dist/r/src/components/ui/toggle-group/index.ts +6 -0
- package/dist/r/src/components/ui/toggle-group/toggle-group.tsx +66 -0
- package/dist/r/src/components/ui/tooltip/index.ts +9 -0
- package/dist/r/src/components/ui/tooltip/tooltip.tsx +102 -0
- package/dist/r/src/lib/keyed-rows.ts +68 -0
- package/dist/r/src/lib/overlay.ts +70 -0
- package/dist/r/src/lib/themes.ts +490 -0
- package/dist/r/src/lib/tokens.ts +688 -0
- package/dist/r/src/lib/utils.ts +76 -0
- package/dist/r/src/lib/variants.ts +62 -0
- package/dist/r/src/lib/version-notes.ts +65 -0
- package/dist/r/src/styles/base.css +644 -0
- package/dist/r/src/styles/fonts.css +26 -0
- package/dist/r/src/styles/globals.css +18 -0
- package/dist/r/src/styles/theme.css +864 -0
- package/dist/r/stat.json +3 -1
- package/dist/r/status-bar.json +3 -1
- package/dist/r/status-chip.json +2 -1
- package/dist/r/switch.json +3 -1
- package/dist/r/table.json +3 -1
- package/dist/r/tabs.json +3 -1
- package/dist/r/textarea.json +3 -1
- package/dist/r/theming.json +42 -0
- package/dist/r/toast.json +3 -1
- package/dist/r/toggle-group.json +2 -1
- package/dist/r/toggle.json +3 -1
- package/dist/r/tooltip.json +3 -1
- package/dist/r/top-bar.json +3 -1
- package/dist/r/update-dialog.json +2 -1
- package/dist/r/workspace-mark.json +2 -1
- package/package.json +10 -9
- package/registry.json +320 -73
- package/src/index.ts +2 -4
- package/dist/components/ui/diff-block/diff-block.test.d.ts +0 -2
- package/dist/components/ui/diff-block/diff-block.test.d.ts.map +0 -1
- package/dist/lib/keyed-rows.test.d.ts +0 -2
- package/dist/lib/keyed-rows.test.d.ts.map +0 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { Dialog as KobalteDialog } from '@kobalte/core/dialog'
|
|
2
|
+
import { X } from 'lucide-solid'
|
|
3
|
+
import type { ComponentProps, JSX } from 'solid-js'
|
|
4
|
+
import { Show, splitProps } from 'solid-js'
|
|
5
|
+
import { cva, type VariantProps } from '../../../lib/variants'
|
|
6
|
+
import { cn } from '../../../lib/utils'
|
|
7
|
+
import { DialogOverlay } from '../dialog/dialog'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Sheet.
|
|
11
|
+
*
|
|
12
|
+
* A dialog anchored to an edge of the window rather than centred. Use it when
|
|
13
|
+
* the content is a *panel beside* the work — a details inspector, a filter rail,
|
|
14
|
+
* a settings flyout — so the user keeps the context it belongs to in view.
|
|
15
|
+
* A centred dialog interrupts; a sheet is inspected.
|
|
16
|
+
*
|
|
17
|
+
* `side` decides which edge; the panel is a full-height column for `start` and
|
|
18
|
+
* `end`, and a full-width row for `top` and `bottom`. The slide-in direction
|
|
19
|
+
* follows from the side, so a caller never pairs them by hand.
|
|
20
|
+
*/
|
|
21
|
+
const sheetVariants = cva(
|
|
22
|
+
'bg-popover text-popover-foreground fixed z-(--z-dialog) flex flex-col gap-4 border-border shadow-lg',
|
|
23
|
+
{
|
|
24
|
+
variants: {
|
|
25
|
+
side: {
|
|
26
|
+
top: 'inset-x-0 top-0 h-auto max-h-[85vh] rounded-b-xl border-b data-expanded:slide-in-from-top data-closed:slide-out-to-top',
|
|
27
|
+
bottom:
|
|
28
|
+
'inset-x-0 bottom-0 h-auto max-h-[85vh] rounded-t-xl border-t data-expanded:slide-in-from-bottom data-closed:slide-out-to-bottom',
|
|
29
|
+
start:
|
|
30
|
+
'inset-y-0 start-0 h-full w-80 max-w-[85vw] rounded-e-xl border-e data-expanded:slide-in-from-left data-closed:slide-out-to-left',
|
|
31
|
+
end: 'inset-y-0 end-0 h-full w-80 max-w-[85vw] rounded-s-xl border-s data-expanded:slide-in-from-right data-closed:slide-out-to-right',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: { side: 'end' },
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
export type SheetContentProps = ComponentProps<typeof KobalteDialog.Content> &
|
|
39
|
+
VariantProps<typeof sheetVariants> & {
|
|
40
|
+
closeButton?: JSX.Element | false
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function SheetContent(props: SheetContentProps) {
|
|
44
|
+
const [local, rest] = splitProps(props, ['class', 'side', 'children', 'closeButton'])
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<KobalteDialog.Portal>
|
|
48
|
+
<DialogOverlay />
|
|
49
|
+
<KobalteDialog.Content
|
|
50
|
+
class={cn(
|
|
51
|
+
sheetVariants({ side: local.side }),
|
|
52
|
+
'data-expanded:animate-in data-expanded:fade-in-0 data-expanded:duration-200',
|
|
53
|
+
'data-closed:animate-out data-closed:fade-out-0 data-closed:duration-150',
|
|
54
|
+
local.class
|
|
55
|
+
)}
|
|
56
|
+
{...rest}
|
|
57
|
+
>
|
|
58
|
+
{local.children}
|
|
59
|
+
<Show when={local.closeButton !== false}>
|
|
60
|
+
<KobalteDialog.CloseButton
|
|
61
|
+
aria-label="Close"
|
|
62
|
+
class="absolute top-3.5 end-3.5 rounded-md p-1 text-muted-foreground transition-colors ease-out outline-none hover:bg-surface-hover hover:text-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle"
|
|
63
|
+
>
|
|
64
|
+
{local.closeButton ?? <X class="size-4" />}
|
|
65
|
+
</KobalteDialog.CloseButton>
|
|
66
|
+
</Show>
|
|
67
|
+
</KobalteDialog.Content>
|
|
68
|
+
</KobalteDialog.Portal>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function Sheet(props: ComponentProps<typeof KobalteDialog>) {
|
|
73
|
+
return <KobalteDialog {...props} />
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function SheetTrigger(props: ComponentProps<typeof KobalteDialog.Trigger>) {
|
|
77
|
+
return <KobalteDialog.Trigger {...props} />
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function SheetCloseButton(props: ComponentProps<typeof KobalteDialog.CloseButton>) {
|
|
81
|
+
const [local, rest] = splitProps(props, ['class'])
|
|
82
|
+
return <KobalteDialog.CloseButton class={cn(local.class)} {...rest} />
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function SheetHeader(props: ComponentProps<'div'>) {
|
|
86
|
+
const [local, rest] = splitProps(props, ['class'])
|
|
87
|
+
return (
|
|
88
|
+
<div
|
|
89
|
+
data-slot="sheet-header"
|
|
90
|
+
class={cn('flex flex-col gap-1.5 border-b border-border p-4 pe-12 text-start', local.class)}
|
|
91
|
+
{...rest}
|
|
92
|
+
/>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function SheetBody(props: ComponentProps<'div'>) {
|
|
97
|
+
const [local, rest] = splitProps(props, ['class'])
|
|
98
|
+
return (
|
|
99
|
+
<div
|
|
100
|
+
data-slot="sheet-body"
|
|
101
|
+
class={cn('flex-1 overflow-y-auto px-4 pb-4', local.class)}
|
|
102
|
+
{...rest}
|
|
103
|
+
/>
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function SheetFooter(props: ComponentProps<'div'>) {
|
|
108
|
+
const [local, rest] = splitProps(props, ['class'])
|
|
109
|
+
return (
|
|
110
|
+
<div
|
|
111
|
+
data-slot="sheet-footer"
|
|
112
|
+
class={cn('flex items-center justify-end gap-2 border-t border-border p-4', local.class)}
|
|
113
|
+
{...rest}
|
|
114
|
+
/>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function SheetTitle(props: ComponentProps<typeof KobalteDialog.Title>) {
|
|
119
|
+
const [local, rest] = splitProps(props, ['class'])
|
|
120
|
+
return (
|
|
121
|
+
<KobalteDialog.Title class={cn('text-sm leading-none font-semibold', local.class)} {...rest} />
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function SheetDescription(props: ComponentProps<typeof KobalteDialog.Description>) {
|
|
126
|
+
const [local, rest] = splitProps(props, ['class'])
|
|
127
|
+
return (
|
|
128
|
+
<KobalteDialog.Description class={cn('text-muted-foreground text-sm', local.class)} {...rest} />
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export { sheetVariants }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Skeleton } from './skeleton'
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ComponentProps } from 'solid-js'
|
|
2
|
+
import { splitProps } from 'solid-js'
|
|
3
|
+
import { cn } from '../../../lib/utils'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Skeleton.
|
|
7
|
+
*
|
|
8
|
+
* A placeholder that stands in for content whose shape is already known. It
|
|
9
|
+
* carries `aria-hidden` and no text, because the loading state is announced by
|
|
10
|
+
* the region that owns it — a skeleton that says "loading" would announce it
|
|
11
|
+
* once per bar.
|
|
12
|
+
*
|
|
13
|
+
* The shimmer is a background animation rather than a moving gradient element
|
|
14
|
+
* so it costs one paint and no layout, and it stops under `prefers-reduced-motion`
|
|
15
|
+
* (base.css).
|
|
16
|
+
*/
|
|
17
|
+
export function Skeleton(props: ComponentProps<'div'>) {
|
|
18
|
+
const [local, rest] = splitProps(props, ['class'])
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div
|
|
22
|
+
data-slot="skeleton"
|
|
23
|
+
aria-hidden="true"
|
|
24
|
+
class={cn('bg-muted animate-shimmer rounded-md', local.class)}
|
|
25
|
+
{...rest}
|
|
26
|
+
/>
|
|
27
|
+
)
|
|
28
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Slider, type SliderProps } from './slider'
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Slider as KobalteSlider } from '@kobalte/core/slider'
|
|
2
|
+
import type { ComponentProps } from 'solid-js'
|
|
3
|
+
import { Show, splitProps } from 'solid-js'
|
|
4
|
+
import { cn } from '../../../lib/utils'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Slider.
|
|
8
|
+
*
|
|
9
|
+
* For a value on a continuum where position matters more than precision — a
|
|
10
|
+
* zoom, a volume, a threshold. When the number matters, pass `valueLabel` so
|
|
11
|
+
* the value is both adjustable *and* readable; a bare slider is a control
|
|
12
|
+
* nobody can set exactly.
|
|
13
|
+
*
|
|
14
|
+
* Kobalte handles pointer capture, keyboard stepping and the ARIA value
|
|
15
|
+
* wiring; this paints the track, fill and thumb.
|
|
16
|
+
*/
|
|
17
|
+
export type SliderProps = ComponentProps<typeof KobalteSlider> & {
|
|
18
|
+
trackClass?: string
|
|
19
|
+
rangeClass?: string
|
|
20
|
+
thumbClass?: string
|
|
21
|
+
/** Show the current value beside the thumb while dragging. */
|
|
22
|
+
valueLabel?: boolean
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function Slider(props: SliderProps) {
|
|
26
|
+
const [local, rest] = splitProps(props, [
|
|
27
|
+
'class',
|
|
28
|
+
'trackClass',
|
|
29
|
+
'rangeClass',
|
|
30
|
+
'thumbClass',
|
|
31
|
+
'valueLabel',
|
|
32
|
+
'children',
|
|
33
|
+
'aria-label',
|
|
34
|
+
'aria-labelledby',
|
|
35
|
+
])
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<KobalteSlider
|
|
39
|
+
class={cn(
|
|
40
|
+
'relative flex touch-none flex-col justify-center select-none',
|
|
41
|
+
'data-[orientation=vertical]:h-full data-[orientation=vertical]:w-5 data-[orientation=horizontal]:w-full',
|
|
42
|
+
'data-[disabled]:opacity-50',
|
|
43
|
+
local.class
|
|
44
|
+
)}
|
|
45
|
+
{...rest}
|
|
46
|
+
>
|
|
47
|
+
<KobalteSlider.Track
|
|
48
|
+
class={cn(
|
|
49
|
+
'bg-input relative grow overflow-hidden rounded-full',
|
|
50
|
+
'data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full',
|
|
51
|
+
'data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5',
|
|
52
|
+
local.trackClass
|
|
53
|
+
)}
|
|
54
|
+
>
|
|
55
|
+
<KobalteSlider.Fill
|
|
56
|
+
class={cn(
|
|
57
|
+
'bg-primary absolute rounded-full',
|
|
58
|
+
'data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full',
|
|
59
|
+
local.rangeClass
|
|
60
|
+
)}
|
|
61
|
+
/>
|
|
62
|
+
</KobalteSlider.Track>
|
|
63
|
+
{local.children}
|
|
64
|
+
<KobalteSlider.Thumb
|
|
65
|
+
aria-label={local['aria-label']}
|
|
66
|
+
aria-labelledby={local['aria-labelledby']}
|
|
67
|
+
class={cn(
|
|
68
|
+
'border-primary bg-background block size-4 shrink-0 rounded-full border-2 shadow-xs',
|
|
69
|
+
'transition-[color,box-shadow] ease-out outline-none',
|
|
70
|
+
'hover:ring-4 hover:ring-primary-subtle',
|
|
71
|
+
'focus-visible:ring-4 focus-visible:ring-primary-subtle',
|
|
72
|
+
local.thumbClass
|
|
73
|
+
)}
|
|
74
|
+
>
|
|
75
|
+
<Show when={local.valueLabel}>
|
|
76
|
+
<KobalteSlider.ValueLabel class="bg-popover text-popover-foreground absolute -top-6 left-1/2 -translate-x-1/2 rounded-sm border border-border px-1 text-2xs tabular-nums" />
|
|
77
|
+
</Show>
|
|
78
|
+
</KobalteSlider.Thumb>
|
|
79
|
+
</KobalteSlider>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Spinner, type SpinnerProps } from './spinner'
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { LoaderCircle } from 'lucide-solid'
|
|
2
|
+
import type { ComponentProps } from 'solid-js'
|
|
3
|
+
import { splitProps } from 'solid-js'
|
|
4
|
+
import { cva, type VariantProps } from '../../../lib/variants'
|
|
5
|
+
import { cn } from '../../../lib/utils'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Spinner.
|
|
9
|
+
*
|
|
10
|
+
* A determinate-length activity indicator with no progress to report. When
|
|
11
|
+
* there *is* progress, use Progress instead — a spinner next to a known
|
|
12
|
+
* percentage is a lie about what the app knows.
|
|
13
|
+
*
|
|
14
|
+
* The glyph spins continuously, so it is the one thing in the system that
|
|
15
|
+
* keeps moving under `prefers-reduced-motion`; base.css only shortens
|
|
16
|
+
* `animation-duration` for the *entrance* animations and leaves this loop
|
|
17
|
+
* alone. A frozen spinner reads as a hang, which is worse than motion.
|
|
18
|
+
*/
|
|
19
|
+
const spinnerVariants = cva('animate-spin shrink-0', {
|
|
20
|
+
variants: {
|
|
21
|
+
size: {
|
|
22
|
+
xs: 'size-3',
|
|
23
|
+
sm: 'size-3.5',
|
|
24
|
+
md: 'size-4',
|
|
25
|
+
lg: 'size-5',
|
|
26
|
+
xl: 'size-6',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
defaultVariants: { size: 'md' },
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
type SpinnerVariants = VariantProps<typeof spinnerVariants>
|
|
33
|
+
|
|
34
|
+
export type SpinnerProps = Omit<ComponentProps<'svg'>, 'size'> &
|
|
35
|
+
SpinnerVariants & {
|
|
36
|
+
/** An accessible name. Defaults to "Loading"; pass `false` to hide it. */
|
|
37
|
+
label?: string | false
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function Spinner(props: SpinnerProps) {
|
|
41
|
+
const [local, rest] = splitProps(props, ['class', 'size', 'label'])
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<>
|
|
45
|
+
<LoaderCircle
|
|
46
|
+
data-slot="spinner"
|
|
47
|
+
role="status"
|
|
48
|
+
aria-label={local.label === false ? undefined : (local.label ?? 'Loading')}
|
|
49
|
+
aria-hidden={local.label === false ? 'true' : undefined}
|
|
50
|
+
class={cn(spinnerVariants({ size: local.size }), local.class)}
|
|
51
|
+
{...rest}
|
|
52
|
+
/>
|
|
53
|
+
{local.label === false ? null : (
|
|
54
|
+
<span class="visually-hidden">{local.label ?? 'Loading'}</span>
|
|
55
|
+
)}
|
|
56
|
+
</>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Show, splitProps, type ComponentProps, type JSX } from 'solid-js'
|
|
2
|
+
import { cva } from '../../../lib/variants'
|
|
3
|
+
import { cn } from '../../../lib/utils'
|
|
4
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from '../tooltip'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* StatusChip.
|
|
8
|
+
*
|
|
9
|
+
* A state, said in one word, with the reason available on hover. It exists
|
|
10
|
+
* because a status readout has three parts that are always the same three parts —
|
|
11
|
+
* a tone, a label, and the detail that justifies the label — and rendering them
|
|
12
|
+
* ad hoc produces the two failures this component is here to prevent: a colour
|
|
13
|
+
* with no text (unreadable to anyone who cannot see it) and a bare word with no
|
|
14
|
+
* explanation ("Needs configuration" — of what?).
|
|
15
|
+
*
|
|
16
|
+
* The tones are deliberately not a rainbow. Six cover what a status can actually
|
|
17
|
+
* mean:
|
|
18
|
+
*
|
|
19
|
+
* - `neutral` — fine, and there is nothing to say about it.
|
|
20
|
+
* - `success` — a check passed, a capability is ready, a job finished.
|
|
21
|
+
* - `warning` — degraded, or needs a decision from the user.
|
|
22
|
+
* - `danger` — blocked, failed, unrecoverable without intervention.
|
|
23
|
+
* - `info` — in flight or scheduled; work is happening, nothing is wrong.
|
|
24
|
+
* - `unknown` — the honest absence of information.
|
|
25
|
+
*
|
|
26
|
+
* `unknown` is not the same as `neutral`, and collapsing them is the mistake
|
|
27
|
+
* worth avoiding: "this is idle" and "we have not been told yet" are different
|
|
28
|
+
* facts, and a product that shows the second as the first is lying quietly. The
|
|
29
|
+
* ring is hollow so it also reads as different in greyscale.
|
|
30
|
+
*
|
|
31
|
+
* The dot is `aria-hidden` and the label carries the meaning, so a tone is never
|
|
32
|
+
* the only signal.
|
|
33
|
+
*/
|
|
34
|
+
export const statusDotVariants = cva('size-2 shrink-0 rounded-full', {
|
|
35
|
+
variants: {
|
|
36
|
+
tone: {
|
|
37
|
+
neutral: 'bg-muted-foreground',
|
|
38
|
+
success: 'bg-success',
|
|
39
|
+
warning: 'bg-warning',
|
|
40
|
+
danger: 'bg-destructive',
|
|
41
|
+
info: 'bg-info',
|
|
42
|
+
unknown: 'border border-muted-foreground bg-transparent',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
defaultVariants: { tone: 'neutral' },
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
const labelTone: Record<StatusTone, string> = {
|
|
49
|
+
neutral: 'text-foreground',
|
|
50
|
+
success: 'text-success',
|
|
51
|
+
warning: 'text-warning',
|
|
52
|
+
danger: 'text-destructive',
|
|
53
|
+
info: 'text-info',
|
|
54
|
+
unknown: 'text-muted-foreground',
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type StatusTone = 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'unknown'
|
|
58
|
+
|
|
59
|
+
export type StatusChipProps = Omit<ComponentProps<'span'>, 'children'> & {
|
|
60
|
+
tone?: StatusTone
|
|
61
|
+
label: string
|
|
62
|
+
/** Why the status is what it is. Shown in a tooltip; omit for a self-evident label. */
|
|
63
|
+
detail?: string
|
|
64
|
+
/** A trailing slot: a timestamp, a retry affordance, a count. */
|
|
65
|
+
trailing?: JSX.Element
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function StatusChip(props: StatusChipProps) {
|
|
69
|
+
const [local, rest] = splitProps(props, ['tone', 'label', 'detail', 'trailing', 'class'])
|
|
70
|
+
|
|
71
|
+
const chip = (
|
|
72
|
+
<span
|
|
73
|
+
class={cn(
|
|
74
|
+
'inline-flex w-fit items-center gap-1.5 text-xs font-medium whitespace-nowrap',
|
|
75
|
+
labelTone[local.tone ?? 'neutral'],
|
|
76
|
+
local.class
|
|
77
|
+
)}
|
|
78
|
+
{...rest}
|
|
79
|
+
>
|
|
80
|
+
<span class={statusDotVariants({ tone: local.tone })} aria-hidden="true" />
|
|
81
|
+
{local.label}
|
|
82
|
+
{local.trailing}
|
|
83
|
+
</span>
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
<Show when={local.detail} fallback={chip}>
|
|
88
|
+
{(detail) => (
|
|
89
|
+
<Tooltip>
|
|
90
|
+
<TooltipTrigger as="span" class="inline-flex">
|
|
91
|
+
{chip}
|
|
92
|
+
</TooltipTrigger>
|
|
93
|
+
<TooltipContent>{detail()}</TooltipContent>
|
|
94
|
+
</Tooltip>
|
|
95
|
+
)}
|
|
96
|
+
</Show>
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export type StatusEntry = Readonly<{
|
|
101
|
+
/** A stable key for the row. */
|
|
102
|
+
id: string
|
|
103
|
+
/** What is being reported — "Configuration", "Runtime", "Sync". */
|
|
104
|
+
name: string
|
|
105
|
+
tone: StatusTone
|
|
106
|
+
label: string
|
|
107
|
+
detail?: string
|
|
108
|
+
}>
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* StatusList.
|
|
112
|
+
*
|
|
113
|
+
* The several-facts-about-one-thing shape: an agent with a configuration state, a
|
|
114
|
+
* runtime state and an activity state; a service with a build, a deploy and a
|
|
115
|
+
* health check. It is a definition list rather than a table because there is no
|
|
116
|
+
* column to sort or compare — the rows are facets of a single subject, and a
|
|
117
|
+
* screen reader should hear them as such.
|
|
118
|
+
*
|
|
119
|
+
* Fixed width on the name column is what makes a column of these scannable; the
|
|
120
|
+
* rows line up without a table's semantics.
|
|
121
|
+
*/
|
|
122
|
+
export function StatusList(props: {
|
|
123
|
+
entries: readonly StatusEntry[]
|
|
124
|
+
class?: string
|
|
125
|
+
/** Hide the name column and show only the chips — for a compact badge strip. */
|
|
126
|
+
compact?: boolean
|
|
127
|
+
}) {
|
|
128
|
+
return (
|
|
129
|
+
<dl class={cn('grid gap-2 text-sm', props.class)}>
|
|
130
|
+
{props.entries.map((entry) => (
|
|
131
|
+
<div class="flex items-baseline justify-between gap-4">
|
|
132
|
+
<Show when={!props.compact}>
|
|
133
|
+
<dt class="text-muted-foreground">{entry.name}</dt>
|
|
134
|
+
</Show>
|
|
135
|
+
<dd class={cn(!props.compact && 'shrink-0')}>
|
|
136
|
+
<StatusChip tone={entry.tone} label={entry.label} detail={entry.detail} />
|
|
137
|
+
</dd>
|
|
138
|
+
</div>
|
|
139
|
+
))}
|
|
140
|
+
</dl>
|
|
141
|
+
)
|
|
142
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { Switch, SwitchDescription, SwitchLabel, type SwitchProps } from './switch'
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Switch as KobalteSwitch } from '@kobalte/core/switch'
|
|
2
|
+
import type { ComponentProps, JSX } from 'solid-js'
|
|
3
|
+
import { splitProps } from 'solid-js'
|
|
4
|
+
import { cn } from '../../../lib/utils'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Switch.
|
|
8
|
+
*
|
|
9
|
+
* For a setting that takes effect the moment it is flipped. The distinction
|
|
10
|
+
* from Checkbox is behaviour, not looks: a switch applies immediately and
|
|
11
|
+
* belongs in a settings row, while a checkbox is a value the user is still
|
|
12
|
+
* composing and is applied when a form is submitted. A switch inside an unsaved
|
|
13
|
+
* form is the mistake this split exists to prevent.
|
|
14
|
+
*
|
|
15
|
+
* `Switch.Input` renders a real hidden checkbox, so the control is
|
|
16
|
+
* form-native, keyboard-operable, and its `aria-checked` follows the state the
|
|
17
|
+
* user sees.
|
|
18
|
+
*/
|
|
19
|
+
export type SwitchProps = Omit<ComponentProps<typeof KobalteSwitch>, 'children'> & {
|
|
20
|
+
controlClass?: string
|
|
21
|
+
thumbClass?: string
|
|
22
|
+
labelClass?: string
|
|
23
|
+
descriptionClass?: string
|
|
24
|
+
/**
|
|
25
|
+
* Replaces the control and label. Omit it to get the default control beside
|
|
26
|
+
* `label` and `description`; supply it to compose the parts yourself.
|
|
27
|
+
*/
|
|
28
|
+
children?: JSX.Element
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function Switch(props: SwitchProps) {
|
|
32
|
+
const [local, rest] = splitProps(props, [
|
|
33
|
+
'class',
|
|
34
|
+
'controlClass',
|
|
35
|
+
'thumbClass',
|
|
36
|
+
'labelClass',
|
|
37
|
+
'descriptionClass',
|
|
38
|
+
'children',
|
|
39
|
+
'aria-label',
|
|
40
|
+
'aria-labelledby',
|
|
41
|
+
])
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<KobalteSwitch class={cn('group/switch flex items-center gap-2.5', local.class)} {...rest}>
|
|
45
|
+
{/* The name belongs on the input; see Checkbox for why. */}
|
|
46
|
+
<KobalteSwitch.Input
|
|
47
|
+
aria-label={local['aria-label']}
|
|
48
|
+
aria-labelledby={local['aria-labelledby']}
|
|
49
|
+
/>
|
|
50
|
+
<KobalteSwitch.Control
|
|
51
|
+
class={cn(
|
|
52
|
+
'bg-input inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent',
|
|
53
|
+
'transition-colors ease-out outline-none',
|
|
54
|
+
'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',
|
|
55
|
+
'data-[checked]:bg-primary',
|
|
56
|
+
'data-[invalid]:border-destructive',
|
|
57
|
+
'data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',
|
|
58
|
+
local.controlClass
|
|
59
|
+
)}
|
|
60
|
+
>
|
|
61
|
+
<KobalteSwitch.Thumb
|
|
62
|
+
class={cn(
|
|
63
|
+
'bg-background pointer-events-none block size-4 rounded-full shadow-xs',
|
|
64
|
+
'transition-transform ease-out',
|
|
65
|
+
'data-[checked]:translate-x-4',
|
|
66
|
+
local.thumbClass
|
|
67
|
+
)}
|
|
68
|
+
/>
|
|
69
|
+
</KobalteSwitch.Control>
|
|
70
|
+
{local.children ?? (
|
|
71
|
+
<div class="grid gap-0.5">
|
|
72
|
+
<KobalteSwitch.Label class={cn('text-sm leading-none font-medium', local.labelClass)} />
|
|
73
|
+
<KobalteSwitch.Description
|
|
74
|
+
class={cn('text-muted-foreground text-sm', local.descriptionClass)}
|
|
75
|
+
/>
|
|
76
|
+
</div>
|
|
77
|
+
)}
|
|
78
|
+
</KobalteSwitch>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The switch's own label. Valid only inside a `<Switch>`: it is Kobalte's label
|
|
84
|
+
* for that root's control, and outside one there is nothing to associate with.
|
|
85
|
+
* A label drawn *beside* a switch — a settings row with the control trailing —
|
|
86
|
+
* is plain text, and the switch takes an `aria-label` instead.
|
|
87
|
+
*/
|
|
88
|
+
export function SwitchLabel(props: ComponentProps<typeof KobalteSwitch.Label>) {
|
|
89
|
+
const [local, rest] = splitProps(props, ['class'])
|
|
90
|
+
return (
|
|
91
|
+
<KobalteSwitch.Label class={cn('text-sm leading-none font-medium', local.class)} {...rest} />
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function SwitchDescription(props: ComponentProps<typeof KobalteSwitch.Description>) {
|
|
96
|
+
const [local, rest] = splitProps(props, ['class'])
|
|
97
|
+
return (
|
|
98
|
+
<KobalteSwitch.Description class={cn('text-muted-foreground text-sm', local.class)} {...rest} />
|
|
99
|
+
)
|
|
100
|
+
}
|