@ecoma-io/loom 0.1.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/LICENSE +202 -0
- package/README.md +180 -0
- package/dist/a11y.d.ts +2 -0
- package/dist/a11y.d.ts.map +1 -0
- package/dist/a11y.js +2 -0
- package/dist/blocks/AppHeader/AppHeader.js +7 -0
- package/dist/blocks/AppHeader/AppHeader.js.map +1 -0
- package/dist/blocks/AppHeader/AppHeader.vue.d.ts +83 -0
- package/dist/blocks/AppHeader/AppHeader.vue.d.ts.map +1 -0
- package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js +96 -0
- package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/DashboardGrid/DashboardGrid.js +7 -0
- package/dist/blocks/DashboardGrid/DashboardGrid.js.map +1 -0
- package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts +42 -0
- package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts.map +1 -0
- package/dist/blocks/DashboardGrid/DashboardGrid.vue_vue_type_script_setup_true_lang.js +45 -0
- package/dist/blocks/DashboardGrid/DashboardGrid.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/EmptyState/EmptyState.js +7 -0
- package/dist/blocks/EmptyState/EmptyState.js.map +1 -0
- package/dist/blocks/EmptyState/EmptyState.vue.d.ts +50 -0
- package/dist/blocks/EmptyState/EmptyState.vue.d.ts.map +1 -0
- package/dist/blocks/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +71 -0
- package/dist/blocks/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/PageHeader/PageHeader.js +7 -0
- package/dist/blocks/PageHeader/PageHeader.js.map +1 -0
- package/dist/blocks/PageHeader/PageHeader.vue.d.ts +54 -0
- package/dist/blocks/PageHeader/PageHeader.vue.d.ts.map +1 -0
- package/dist/blocks/PageHeader/PageHeader.vue_vue_type_script_setup_true_lang.js +68 -0
- package/dist/blocks/PageHeader/PageHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/RowActions/RowActions.js +7 -0
- package/dist/blocks/RowActions/RowActions.js.map +1 -0
- package/dist/blocks/RowActions/RowActions.vue.d.ts +14 -0
- package/dist/blocks/RowActions/RowActions.vue.d.ts.map +1 -0
- package/dist/blocks/RowActions/RowActions.vue_vue_type_script_setup_true_lang.js +47 -0
- package/dist/blocks/RowActions/RowActions.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/SidebarNav/SidebarNav.js +7 -0
- package/dist/blocks/SidebarNav/SidebarNav.js.map +1 -0
- package/dist/blocks/SidebarNav/SidebarNav.vue.d.ts +40 -0
- package/dist/blocks/SidebarNav/SidebarNav.vue.d.ts.map +1 -0
- package/dist/blocks/SidebarNav/SidebarNav.vue_vue_type_script_setup_true_lang.js +125 -0
- package/dist/blocks/SidebarNav/SidebarNav.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/TitleBar/TitleBar.js +7 -0
- package/dist/blocks/TitleBar/TitleBar.js.map +1 -0
- package/dist/blocks/TitleBar/TitleBar.vue.d.ts +49 -0
- package/dist/blocks/TitleBar/TitleBar.vue.d.ts.map +1 -0
- package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js +66 -0
- package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/blocks/ToastStack/ToastStack.js +7 -0
- package/dist/blocks/ToastStack/ToastStack.js.map +1 -0
- package/dist/blocks/ToastStack/ToastStack.vue.d.ts +24 -0
- package/dist/blocks/ToastStack/ToastStack.vue.d.ts.map +1 -0
- package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js +38 -0
- package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/icons/BrandMark.d.ts +18 -0
- package/dist/icons/BrandMark.d.ts.map +1 -0
- package/dist/icons/BrandMark.js +47 -0
- package/dist/icons/BrandMark.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/lib/a11y-scope.d.ts +19 -0
- package/dist/lib/a11y-scope.d.ts.map +1 -0
- package/dist/lib/a11y-scope.js +28 -0
- package/dist/lib/a11y-scope.js.map +1 -0
- package/dist/lib/attrs.d.ts +18 -0
- package/dist/lib/attrs.d.ts.map +1 -0
- package/dist/lib/attrs.js +28 -0
- package/dist/lib/attrs.js.map +1 -0
- package/dist/lib/cn.d.ts +9 -0
- package/dist/lib/cn.d.ts.map +1 -0
- package/dist/lib/cn.js +16 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/lib/icon-defaults.d.ts +22 -0
- package/dist/lib/icon-defaults.d.ts.map +1 -0
- package/dist/lib/icon-defaults.js +32 -0
- package/dist/lib/icon-defaults.js.map +1 -0
- package/dist/lib/motion.d.ts +14 -0
- package/dist/lib/motion.d.ts.map +1 -0
- package/dist/lib/motion.js +20 -0
- package/dist/lib/motion.js.map +1 -0
- package/dist/lib/props.d.ts +31 -0
- package/dist/lib/props.d.ts.map +1 -0
- package/dist/lib/props.js +37 -0
- package/dist/lib/props.js.map +1 -0
- package/dist/primitives/Avatar/Avatar.js +7 -0
- package/dist/primitives/Avatar/Avatar.js.map +1 -0
- package/dist/primitives/Avatar/Avatar.vue.d.ts +27 -0
- package/dist/primitives/Avatar/Avatar.vue.d.ts.map +1 -0
- package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +33 -0
- package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Badge/Badge.js +7 -0
- package/dist/primitives/Badge/Badge.js.map +1 -0
- package/dist/primitives/Badge/Badge.vue.d.ts +27 -0
- package/dist/primitives/Badge/Badge.vue.d.ts.map +1 -0
- package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js +30 -0
- package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Button/Button.js +7 -0
- package/dist/primitives/Button/Button.js.map +1 -0
- package/dist/primitives/Button/Button.vue.d.ts +70 -0
- package/dist/primitives/Button/Button.vue.d.ts.map +1 -0
- package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js +122 -0
- package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Checkbox/Checkbox.js +7 -0
- package/dist/primitives/Checkbox/Checkbox.js.map +1 -0
- package/dist/primitives/Checkbox/Checkbox.vue.d.ts +34 -0
- package/dist/primitives/Checkbox/Checkbox.vue.d.ts.map +1 -0
- package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js +94 -0
- package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Dialog/Dialog.js +7 -0
- package/dist/primitives/Dialog/Dialog.js.map +1 -0
- package/dist/primitives/Dialog/Dialog.vue.d.ts +58 -0
- package/dist/primitives/Dialog/Dialog.vue.d.ts.map +1 -0
- package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +88 -0
- package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/DropdownMenu/DropdownMenu.js +7 -0
- package/dist/primitives/DropdownMenu/DropdownMenu.js.map +1 -0
- package/dist/primitives/DropdownMenu/DropdownMenu.vue.d.ts +55 -0
- package/dist/primitives/DropdownMenu/DropdownMenu.vue.d.ts.map +1 -0
- package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +82 -0
- package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Field/Field.js +7 -0
- package/dist/primitives/Field/Field.js.map +1 -0
- package/dist/primitives/Field/Field.vue.d.ts +53 -0
- package/dist/primitives/Field/Field.vue.d.ts.map +1 -0
- package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js +84 -0
- package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/InlineError/InlineError.js +7 -0
- package/dist/primitives/InlineError/InlineError.js.map +1 -0
- package/dist/primitives/InlineError/InlineError.vue.d.ts +32 -0
- package/dist/primitives/InlineError/InlineError.vue.d.ts.map +1 -0
- package/dist/primitives/InlineError/InlineError.vue_vue_type_script_setup_true_lang.js +44 -0
- package/dist/primitives/InlineError/InlineError.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Menubar/Menubar.js +7 -0
- package/dist/primitives/Menubar/Menubar.js.map +1 -0
- package/dist/primitives/Menubar/Menubar.vue.d.ts +41 -0
- package/dist/primitives/Menubar/Menubar.vue.d.ts.map +1 -0
- package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js +184 -0
- package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/NumberField/NumberField.js +7 -0
- package/dist/primitives/NumberField/NumberField.js.map +1 -0
- package/dist/primitives/NumberField/NumberField.vue.d.ts +47 -0
- package/dist/primitives/NumberField/NumberField.vue.d.ts.map +1 -0
- package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js +204 -0
- package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Popover/Popover.js +7 -0
- package/dist/primitives/Popover/Popover.js.map +1 -0
- package/dist/primitives/Popover/Popover.vue.d.ts +61 -0
- package/dist/primitives/Popover/Popover.vue.d.ts.map +1 -0
- package/dist/primitives/Popover/Popover.vue_vue_type_script_setup_true_lang.js +59 -0
- package/dist/primitives/Popover/Popover.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Progress/Progress.js +7 -0
- package/dist/primitives/Progress/Progress.js.map +1 -0
- package/dist/primitives/Progress/Progress.vue.d.ts +30 -0
- package/dist/primitives/Progress/Progress.vue.d.ts.map +1 -0
- package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js +67 -0
- package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/RadioGroup/RadioGroup.js +7 -0
- package/dist/primitives/RadioGroup/RadioGroup.js.map +1 -0
- package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts +39 -0
- package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts.map +1 -0
- package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js +63 -0
- package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/SegmentedControl/SegmentedControl.js +7 -0
- package/dist/primitives/SegmentedControl/SegmentedControl.js.map +1 -0
- package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts +40 -0
- package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts.map +1 -0
- package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +89 -0
- package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Select/Select.js +7 -0
- package/dist/primitives/Select/Select.js.map +1 -0
- package/dist/primitives/Select/Select.vue.d.ts +56 -0
- package/dist/primitives/Select/Select.vue.d.ts.map +1 -0
- package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js +122 -0
- package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Separator/Separator.js +7 -0
- package/dist/primitives/Separator/Separator.js.map +1 -0
- package/dist/primitives/Separator/Separator.vue.d.ts +19 -0
- package/dist/primitives/Separator/Separator.vue.d.ts.map +1 -0
- package/dist/primitives/Separator/Separator.vue_vue_type_script_setup_true_lang.js +31 -0
- package/dist/primitives/Separator/Separator.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Skeleton/Skeleton.js +7 -0
- package/dist/primitives/Skeleton/Skeleton.js.map +1 -0
- package/dist/primitives/Skeleton/Skeleton.vue.d.ts +16 -0
- package/dist/primitives/Skeleton/Skeleton.vue.d.ts.map +1 -0
- package/dist/primitives/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js +37 -0
- package/dist/primitives/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Slider/Slider.js +7 -0
- package/dist/primitives/Slider/Slider.js.map +1 -0
- package/dist/primitives/Slider/Slider.vue.d.ts +58 -0
- package/dist/primitives/Slider/Slider.vue.d.ts.map +1 -0
- package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js +137 -0
- package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Spinner/Spinner.js +7 -0
- package/dist/primitives/Spinner/Spinner.js.map +1 -0
- package/dist/primitives/Spinner/Spinner.vue.d.ts +21 -0
- package/dist/primitives/Spinner/Spinner.vue.d.ts.map +1 -0
- package/dist/primitives/Spinner/Spinner.vue_vue_type_script_setup_true_lang.js +63 -0
- package/dist/primitives/Spinner/Spinner.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Surface/Surface.js +7 -0
- package/dist/primitives/Surface/Surface.js.map +1 -0
- package/dist/primitives/Surface/Surface.vue.d.ts +42 -0
- package/dist/primitives/Surface/Surface.vue.d.ts.map +1 -0
- package/dist/primitives/Surface/Surface.vue_vue_type_script_setup_true_lang.js +48 -0
- package/dist/primitives/Surface/Surface.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Switch/Switch.js +7 -0
- package/dist/primitives/Switch/Switch.js.map +1 -0
- package/dist/primitives/Switch/Switch.vue.d.ts +24 -0
- package/dist/primitives/Switch/Switch.vue.d.ts.map +1 -0
- package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js +44 -0
- package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Tabs/Tabs.js +7 -0
- package/dist/primitives/Tabs/Tabs.js.map +1 -0
- package/dist/primitives/Tabs/Tabs.vue.d.ts +33 -0
- package/dist/primitives/Tabs/Tabs.vue.d.ts.map +1 -0
- package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js +54 -0
- package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/TextField/TextField.js +7 -0
- package/dist/primitives/TextField/TextField.js.map +1 -0
- package/dist/primitives/TextField/TextField.vue.d.ts +58 -0
- package/dist/primitives/TextField/TextField.vue.d.ts.map +1 -0
- package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js +71 -0
- package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Textarea/Textarea.js +7 -0
- package/dist/primitives/Textarea/Textarea.js.map +1 -0
- package/dist/primitives/Textarea/Textarea.vue.d.ts +48 -0
- package/dist/primitives/Textarea/Textarea.vue.d.ts.map +1 -0
- package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js +54 -0
- package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Toast/Toast.js +7 -0
- package/dist/primitives/Toast/Toast.js.map +1 -0
- package/dist/primitives/Toast/Toast.vue.d.ts +46 -0
- package/dist/primitives/Toast/Toast.vue.d.ts.map +1 -0
- package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js +52 -0
- package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Toast/ToastItem.js +7 -0
- package/dist/primitives/Toast/ToastItem.js.map +1 -0
- package/dist/primitives/Toast/ToastItem.vue.d.ts +38 -0
- package/dist/primitives/Toast/ToastItem.vue.d.ts.map +1 -0
- package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js +114 -0
- package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.js +7 -0
- package/dist/primitives/Tooltip/Tooltip.js.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.vue.d.ts +52 -0
- package/dist/primitives/Tooltip/Tooltip.vue.d.ts.map +1 -0
- package/dist/primitives/Tooltip/Tooltip.vue_vue_type_script_setup_true_lang.js +56 -0
- package/dist/primitives/Tooltip/Tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/primitives/WindowControls/WindowControls.js +7 -0
- package/dist/primitives/WindowControls/WindowControls.js.map +1 -0
- package/dist/primitives/WindowControls/WindowControls.vue.d.ts +41 -0
- package/dist/primitives/WindowControls/WindowControls.vue.d.ts.map +1 -0
- package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js +111 -0
- package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/styles/fonts/Geist-Variable.woff2 +0 -0
- package/dist/styles/fonts/GeistMono-Variable.woff2 +0 -0
- package/dist/styles/fonts/OFL.txt +92 -0
- package/dist/styles/fonts.css +30 -0
- package/dist/styles/global.css +181 -0
- package/dist/styles/theme.css +212 -0
- package/package.json +123 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The six weights, and the choice between them is about emphasis rather than
|
|
3
|
+
* colour: `primary` is the one action a screen is asking for, `destructive` is
|
|
4
|
+
* the one it is warning about, and the four between them step down.
|
|
5
|
+
*/
|
|
6
|
+
export type ButtonVariant = "primary" | "secondary" | "subtle" | "outline" | "ghost" | "destructive";
|
|
7
|
+
export type ButtonSize = "sm" | "md" | "lg" | "icon" | "icon-sm";
|
|
8
|
+
/**
|
|
9
|
+
* Button — the workhorse, and the primitive that encodes Loom's press
|
|
10
|
+
* language:
|
|
11
|
+
*
|
|
12
|
+
* • hover lifts by fill, not by shadow
|
|
13
|
+
* • active presses down (scale 0.97) — physical, causal feedback
|
|
14
|
+
* • focus blooms the warp ring
|
|
15
|
+
* • loading plays a kinetic swap under a shimmer sweep: the label rolls up
|
|
16
|
+
* and out, a progress arc springs in, the loading text rises last — and
|
|
17
|
+
* both layers share one grid cell, so the width never jumps mid-film
|
|
18
|
+
*
|
|
19
|
+
* The 50% dim belongs to a *disabled* button only. It is applied off the
|
|
20
|
+
* `disabled` prop rather than off the DOM disabled state, because a loading
|
|
21
|
+
* button is also DOM-disabled yet has to read as "working", not
|
|
22
|
+
* "unavailable".
|
|
23
|
+
*/
|
|
24
|
+
export declare const buttonVariants: (props?: ({
|
|
25
|
+
variant?: "outline" | "primary" | "destructive" | "secondary" | "subtle" | "ghost" | null | undefined;
|
|
26
|
+
size?: "sm" | "md" | "lg" | "icon" | "icon-sm" | null | undefined;
|
|
27
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
28
|
+
declare const _default: typeof __VLS_export;
|
|
29
|
+
export default _default;
|
|
30
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
31
|
+
/** How much emphasis the action carries. */
|
|
32
|
+
variant?: ButtonVariant;
|
|
33
|
+
/** Control height. `icon` and `icon-sm` are square, for a glyph alone. */
|
|
34
|
+
size?: ButtonSize;
|
|
35
|
+
/** Locks the button and plays the kinetic swap (label → arc + loadingText). */
|
|
36
|
+
loading?: boolean;
|
|
37
|
+
/** Text shown beside the progress arc while loading, e.g. "Saving…". */
|
|
38
|
+
loadingText?: string;
|
|
39
|
+
/** Unavailable rather than busy — dims to 50% and blocks pointer events. */
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
/** The native button type. Defaults to `button`, never an accidental submit. */
|
|
42
|
+
type?: "button" | "submit" | "reset";
|
|
43
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
|
|
44
|
+
/** How much emphasis the action carries. */
|
|
45
|
+
variant?: ButtonVariant;
|
|
46
|
+
/** Control height. `icon` and `icon-sm` are square, for a glyph alone. */
|
|
47
|
+
size?: ButtonSize;
|
|
48
|
+
/** Locks the button and plays the kinetic swap (label → arc + loadingText). */
|
|
49
|
+
loading?: boolean;
|
|
50
|
+
/** Text shown beside the progress arc while loading, e.g. "Saving…". */
|
|
51
|
+
loadingText?: string;
|
|
52
|
+
/** Unavailable rather than busy — dims to 50% and blocks pointer events. */
|
|
53
|
+
disabled?: boolean;
|
|
54
|
+
/** The native button type. Defaults to `button`, never an accidental submit. */
|
|
55
|
+
type?: "button" | "submit" | "reset";
|
|
56
|
+
}> & Readonly<{}>, {
|
|
57
|
+
size: ButtonSize;
|
|
58
|
+
type: "button" | "submit" | "reset";
|
|
59
|
+
variant: ButtonVariant;
|
|
60
|
+
loading: boolean;
|
|
61
|
+
disabled: boolean;
|
|
62
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
|
|
63
|
+
default?: (props: {}) => any;
|
|
64
|
+
}>;
|
|
65
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
66
|
+
new (): {
|
|
67
|
+
$slots: S;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=Button.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Button/Button.vue"],"names":[],"mappings":"AAoKA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACvB,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc;;;8EAuC1B,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEd,4CAA4C;cAClC,aAAa;IACvB,0EAA0E;WACnE,UAAU;IACjB,+EAA+E;cACrE,OAAO;IACjB,wEAAwE;kBAC1D,MAAM;IACpB,4EAA4E;eACjE,OAAO;IAClB,gFAAgF;WACzE,QAAQ,GAAG,QAAQ,GAAG,OAAO;;IAXpC,4CAA4C;cAClC,aAAa;IACvB,0EAA0E;WACnE,UAAU;IACjB,+EAA+E;cACrE,OAAO;IACjB,wEAAwE;kBAC1D,MAAM;IACpB,4EAA4E;eACjE,OAAO;IAClB,gFAAgF;WACzE,QAAQ,GAAG,QAAQ,GAAG,OAAO;;UAR7B,UAAU;UAQV,QAAQ,GAAG,QAAQ,GAAG,OAAO;aAV1B,aAAa;aAIb,OAAO;cAIN,OAAO;;cAmIR,CAAC,KAAK,IAAgB,KAAK,GAAG;EAUxC,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { cn } from "../../lib/cn.js";
|
|
2
|
+
import { createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, openBlock, renderSlot, toDisplayString, unref } from "vue";
|
|
3
|
+
import { cva } from "class-variance-authority";
|
|
4
|
+
//#region src/primitives/Button/Button.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
+
var _hoisted_1 = [
|
|
6
|
+
"type",
|
|
7
|
+
"disabled",
|
|
8
|
+
"data-loading",
|
|
9
|
+
"aria-busy"
|
|
10
|
+
];
|
|
11
|
+
var _hoisted_2 = {
|
|
12
|
+
key: 0,
|
|
13
|
+
"aria-hidden": "true",
|
|
14
|
+
class: "pointer-events-none absolute inset-0 rounded-md bg-[linear-gradient(110deg,transparent_35%,--alpha(var(--color-primary)/25%)_50%,transparent_65%)] bg-[length:220%_100%] animate-shimmer"
|
|
15
|
+
};
|
|
16
|
+
var _hoisted_3 = { class: "inline-grid place-items-center" };
|
|
17
|
+
var _hoisted_4 = ["aria-hidden"];
|
|
18
|
+
var _hoisted_5 = ["aria-hidden"];
|
|
19
|
+
var _hoisted_6 = {
|
|
20
|
+
key: 0,
|
|
21
|
+
class: "transition-[opacity,transform] duration-100 ease-out opacity-0 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:opacity-100 group-data-[loading]:delay-75 motion-reduce:group-data-[loading]:delay-0"
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Button — the workhorse, and the primitive that encodes Loom's press
|
|
25
|
+
* language:
|
|
26
|
+
*
|
|
27
|
+
* • hover lifts by fill, not by shadow
|
|
28
|
+
* • active presses down (scale 0.97) — physical, causal feedback
|
|
29
|
+
* • focus blooms the warp ring
|
|
30
|
+
* • loading plays a kinetic swap under a shimmer sweep: the label rolls up
|
|
31
|
+
* and out, a progress arc springs in, the loading text rises last — and
|
|
32
|
+
* both layers share one grid cell, so the width never jumps mid-film
|
|
33
|
+
*
|
|
34
|
+
* The 50% dim belongs to a *disabled* button only. It is applied off the
|
|
35
|
+
* `disabled` prop rather than off the DOM disabled state, because a loading
|
|
36
|
+
* button is also DOM-disabled yet has to read as "working", not
|
|
37
|
+
* "unavailable".
|
|
38
|
+
*/
|
|
39
|
+
var buttonVariants = cva([
|
|
40
|
+
"relative inline-flex items-center justify-center gap-2 whitespace-nowrap select-none",
|
|
41
|
+
"rounded-md text-sm font-medium",
|
|
42
|
+
"[transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out),color_var(--duration-fast)_var(--ease-out),box-shadow_var(--duration-fast)_var(--ease-out)]",
|
|
43
|
+
"active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo",
|
|
44
|
+
"disabled:pointer-events-none"
|
|
45
|
+
], {
|
|
46
|
+
variants: {
|
|
47
|
+
variant: {
|
|
48
|
+
primary: "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm",
|
|
49
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/70",
|
|
50
|
+
subtle: "bg-transparent text-foreground hover:bg-subtle",
|
|
51
|
+
outline: "border border-input bg-transparent text-foreground hover:bg-subtle",
|
|
52
|
+
ghost: "bg-transparent text-muted-foreground hover:bg-subtle hover:text-foreground",
|
|
53
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm"
|
|
54
|
+
},
|
|
55
|
+
size: {
|
|
56
|
+
sm: "h-8 px-3 text-xs",
|
|
57
|
+
md: "h-9 px-4",
|
|
58
|
+
lg: "h-11 px-6 text-base",
|
|
59
|
+
icon: "h-9 w-9 p-0",
|
|
60
|
+
"icon-sm": "h-8 w-8 p-0"
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
defaultVariants: {
|
|
64
|
+
variant: "primary",
|
|
65
|
+
size: "md"
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
var Button_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
69
|
+
__name: "Button",
|
|
70
|
+
props: {
|
|
71
|
+
variant: { default: "primary" },
|
|
72
|
+
size: { default: "md" },
|
|
73
|
+
loading: {
|
|
74
|
+
type: Boolean,
|
|
75
|
+
default: false
|
|
76
|
+
},
|
|
77
|
+
loadingText: {},
|
|
78
|
+
disabled: {
|
|
79
|
+
type: Boolean,
|
|
80
|
+
default: false
|
|
81
|
+
},
|
|
82
|
+
type: { default: "button" }
|
|
83
|
+
},
|
|
84
|
+
setup(__props) {
|
|
85
|
+
return (_ctx, _cache) => {
|
|
86
|
+
return openBlock(), createElementBlock("button", {
|
|
87
|
+
type: __props.type,
|
|
88
|
+
disabled: __props.disabled || __props.loading,
|
|
89
|
+
"data-loading": __props.loading || void 0,
|
|
90
|
+
"aria-busy": __props.loading || void 0,
|
|
91
|
+
class: normalizeClass(unref(cn)(unref(buttonVariants)({
|
|
92
|
+
variant: __props.variant,
|
|
93
|
+
size: __props.size
|
|
94
|
+
}), "group", __props.disabled && "opacity-50"))
|
|
95
|
+
}, [__props.loading ? (openBlock(), createElementBlock("span", _hoisted_2)) : createCommentVNode("", true), createElementVNode("span", _hoisted_3, [createElementVNode("span", {
|
|
96
|
+
"aria-hidden": __props.loading || void 0,
|
|
97
|
+
class: "[grid-area:1/1] inline-flex items-center gap-2 transition-[opacity,transform] duration-fast ease-out group-data-[loading]:-translate-y-1 group-data-[loading]:opacity-0"
|
|
98
|
+
}, [renderSlot(_ctx.$slots, "default")], 8, _hoisted_4), createElementVNode("span", {
|
|
99
|
+
"aria-hidden": !__props.loading || void 0,
|
|
100
|
+
class: "pointer-events-none [grid-area:1/1] inline-flex items-center gap-2"
|
|
101
|
+
}, [_cache[0] || (_cache[0] = createElementVNode("span", { class: "transition-[opacity,transform] duration-fast ease-spring opacity-0 scale-50 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:scale-100 group-data-[loading]:opacity-100" }, [createElementVNode("svg", {
|
|
102
|
+
class: "h-4 w-4 animate-spin",
|
|
103
|
+
viewBox: "0 0 24 24",
|
|
104
|
+
fill: "none",
|
|
105
|
+
"aria-hidden": "true"
|
|
106
|
+
}, [createElementVNode("circle", {
|
|
107
|
+
class: "stroke-current opacity-25",
|
|
108
|
+
cx: "12",
|
|
109
|
+
cy: "12",
|
|
110
|
+
r: "10",
|
|
111
|
+
"stroke-width": "4"
|
|
112
|
+
}), createElementVNode("path", {
|
|
113
|
+
class: "fill-current opacity-75",
|
|
114
|
+
d: "M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12h4z"
|
|
115
|
+
})])], -1)), __props.loadingText ? (openBlock(), createElementBlock("span", _hoisted_6, toDisplayString(__props.loadingText), 1)) : createCommentVNode("", true)], 8, _hoisted_5)])], 10, _hoisted_1);
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
//#endregion
|
|
120
|
+
export { buttonVariants, Button_vue_vue_type_script_setup_true_lang_default as default };
|
|
121
|
+
|
|
122
|
+
//# sourceMappingURL=Button.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/primitives/Button/Button.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/**\n * The six weights, and the choice between them is about emphasis rather than\n * colour: `primary` is the one action a screen is asking for, `destructive` is\n * the one it is warning about, and the four between them step down.\n */\nexport type ButtonVariant =\n \"primary\" | \"secondary\" | \"subtle\" | \"outline\" | \"ghost\" | \"destructive\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\" | \"icon-sm\";\n\n/**\n * Button — the workhorse, and the primitive that encodes Loom's press\n * language:\n *\n * • hover lifts by fill, not by shadow\n * • active presses down (scale 0.97) — physical, causal feedback\n * • focus blooms the warp ring\n * • loading plays a kinetic swap under a shimmer sweep: the label rolls up\n * and out, a progress arc springs in, the loading text rises last — and\n * both layers share one grid cell, so the width never jumps mid-film\n *\n * The 50% dim belongs to a *disabled* button only. It is applied off the\n * `disabled` prop rather than off the DOM disabled state, because a loading\n * button is also DOM-disabled yet has to read as \"working\", not\n * \"unavailable\".\n */\nexport const buttonVariants = cva(\n [\n \"relative inline-flex items-center justify-center gap-2 whitespace-nowrap select-none\",\n \"rounded-md text-sm font-medium\",\n \"[transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out),color_var(--duration-fast)_var(--ease-out),box-shadow_var(--duration-fast)_var(--ease-out)]\",\n \"active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:pointer-events-none\",\n ],\n {\n // `satisfies` is what keeps the two halves honest. The union above is the\n // name a consumer imports and the documentation prints; the map below is\n // the classes. Adding a member to one and not the other stops compiling,\n // so neither can be the stale copy of the other.\n variants: {\n variant: {\n primary: \"bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/70\",\n subtle: \"bg-transparent text-foreground hover:bg-subtle\",\n outline: \"border border-input bg-transparent text-foreground hover:bg-subtle\",\n ghost: \"bg-transparent text-muted-foreground hover:bg-subtle hover:text-foreground\",\n destructive: \"bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm\",\n } satisfies Record<ButtonVariant, string>,\n size: {\n sm: \"h-8 px-3 text-xs\",\n md: \"h-9 px-4\",\n lg: \"h-11 px-6 text-base\",\n icon: \"h-9 w-9 p-0\",\n // A square icon button for dense rows, matching `sm`'s height so a row\n // action lines up with that row's text controls. Still 32px — well\n // over the 24px minimum target size (WCAG 2.2 SC 2.5.8) — so density\n // here costs no reachability. It exists because consumers were\n // reaching for `size=\"icon\"` and then hand-overriding `class=\"h-8 w-8\"`,\n // which silently re-litigates the target-size question at every call\n // site.\n \"icon-sm\": \"h-8 w-8 p-0\",\n } satisfies Record<ButtonSize, string>,\n },\n defaultVariants: { variant: \"primary\", size: \"md\" },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\n\nwithDefaults(\n defineProps<{\n /** How much emphasis the action carries. */\n variant?: ButtonVariant;\n /** Control height. `icon` and `icon-sm` are square, for a glyph alone. */\n size?: ButtonSize;\n /** Locks the button and plays the kinetic swap (label → arc + loadingText). */\n loading?: boolean;\n /** Text shown beside the progress arc while loading, e.g. \"Saving…\". */\n loadingText?: string;\n /** Unavailable rather than busy — dims to 50% and blocks pointer events. */\n disabled?: boolean;\n /** The native button type. Defaults to `button`, never an accidental submit. */\n type?: \"button\" | \"submit\" | \"reset\";\n }>(),\n { variant: \"primary\", size: \"md\", loading: false, disabled: false, type: \"button\" },\n);\n</script>\n\n<template>\n <button\n :type=\"type\"\n :disabled=\"disabled || loading\"\n :data-loading=\"loading || undefined\"\n :aria-busy=\"loading || undefined\"\n :class=\"cn(buttonVariants({ variant, size }), 'group', disabled && 'opacity-50')\"\n >\n <!-- The shimmer sweep, while loading. -->\n <span\n v-if=\"loading\"\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute inset-0 rounded-md bg-[linear-gradient(110deg,transparent_35%,--alpha(var(--color-primary)/25%)_50%,transparent_65%)] bg-[length:220%_100%] animate-shimmer\"\n />\n <!-- The kinetic swap. Both layers live in the same grid cell, so the\n button keeps the width of the wider one and nothing jumps mid-swap.\n Only the layer for the current state is exposed to assistive\n technology; the other is aria-hidden, because opacity alone does not\n hide anything from a screen reader. -->\n <span class=\"inline-grid place-items-center\">\n <!-- Beat 1 — the label rolls up and out. -->\n <span\n :aria-hidden=\"loading || undefined\"\n class=\"[grid-area:1/1] inline-flex items-center gap-2 transition-[opacity,transform] duration-fast ease-out group-data-[loading]:-translate-y-1 group-data-[loading]:opacity-0\"\n >\n <slot />\n </span>\n <span\n :aria-hidden=\"!loading || undefined\"\n class=\"pointer-events-none [grid-area:1/1] inline-flex items-center gap-2\"\n >\n <!-- Beat 2 — the progress arc springs in from below. The spinning svg\n sits inside a wrapper because `animate-spin` owns `transform`: the\n entry scale and translate have to live on a separate element, or\n the spin keyframe would overwrite them. It is the same arc the\n standalone Spinner draws, inlined and aria-hidden — Spinner's\n role=\"status\" contract is wrong inside an aria-busy button, where\n it would announce the state twice. -->\n <span\n class=\"transition-[opacity,transform] duration-fast ease-spring opacity-0 scale-50 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:scale-100 group-data-[loading]:opacity-100\"\n >\n <svg class=\"h-4 w-4 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle class=\"stroke-current opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke-width=\"4\" />\n <path\n class=\"fill-current opacity-75\"\n d=\"M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n </span>\n <!-- Beat 3 — the loading text rises last. The stagger delay applies on\n entry only (exit keeps delay 0, so the film cuts out clean), and\n it is cancelled under reduced motion so the instant swap is not\n lagged by a delay nobody asked for. -->\n <span\n v-if=\"loadingText\"\n class=\"transition-[opacity,transform] duration-100 ease-out opacity-0 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:opacity-100 group-data-[loading]:delay-75 motion-reduce:group-data-[loading]:delay-0\"\n >\n {{ loadingText }}\n </span>\n </span>\n </span>\n </button>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,IAAa,iBAAiB,IAC5B;CACE;CACA;CACA;CACA;CACA;AACF,GACA;CAKE,UAAU;EACR,SAAS;GACP,SAAS;GACT,WAAW;GACX,QAAQ;GACR,SAAS;GACT,OAAO;GACP,aAAa;EACf;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GAQN,WAAW;EACb;CACF;CACA,iBAAiB;EAAE,SAAS;EAAW,MAAM;CAAK;AACpD,CACF;;;;;;;;;;;;;;;;;;;GA0BE,OAAA,UAAA,GAAA,mBA4DS,UAAA;IA3DN,MAAM,QAAA;IACN,UAAU,QAAA,YAAY,QAAA;IACtB,gBAAc,QAAA,WAAW,KAAA;IACzB,aAAW,QAAA,WAAW,KAAA;IACtB,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,MAAA,cAAA,CAAc,CAAA;KAAA,SAAG,QAAA;KAAO,MAAE,QAAA;IAAI,CAAA,GAAA,SAAc,QAAA,YAAQ,YAAA,CAAA;GAIvD,GAAA,CAAA,QAAA,WADR,UAAA,GAAA,mBAIE,QAJF,UAIE,KAAA,mBAAA,IAAA,IAAA,GAMF,mBAyCO,QAzCP,YAyCO,CAvCL,mBAKO,QAAA;IAJJ,eAAa,QAAA,WAAW,KAAA;IACzB,OAAM;GAEN,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,GAAA,UAAA,GAEV,mBAgCO,QAAA;IA/BJ,eAAW,CAAG,QAAA,WAAW,KAAA;IAC1B,OAAM;GASN,GAAA,CAAA,OAAA,OAAA,OAAA,KAAA,mBAUO,QAAA,EATL,OAAM,+LAA8L,GAAA,CAEpM,mBAMM,OAAA;IAND,OAAM;IAAuB,SAAQ;IAAY,MAAK;IAAO,eAAY;GAC5E,GAAA,CAAA,mBAAoF,UAAA;IAA5E,OAAM;IAA4B,IAAG;IAAK,IAAG;IAAK,GAAE;IAAK,gBAAa;GAC9E,CAAA,GAAA,mBAGE,QAAA;IAFA,OAAM;IACN,GAAE;GASA,CAAA,CAAA,CAAA,CAAA,GAAA,EAAA,IAAA,QAAA,eADR,UAAA,GAAA,mBAKO,QALP,YAKO,gBADF,QAAA,WAAW,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,GAAA,UAAA,CAAA,CAAA,CAAA,GAAA,IAAA,UAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import Checkbox_vue_vue_type_script_setup_true_lang_default from "./Checkbox.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/primitives/Checkbox/Checkbox.vue
|
|
3
|
+
var Checkbox_default = Checkbox_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { Checkbox_default as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=Checkbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.js","names":[],"sources":["../../../src/primitives/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckboxIndicator, CheckboxRoot } from \"reka-ui\";\nimport { Check, Minus } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\n\n/**\n * Checkbox — a single boolean choice inside a form (as opposed to Switch,\n * which flips a setting immediately, no form/\"Save\" involved). Built on Reka\n * UI's Checkbox (role=\"checkbox\" + aria-checked, Space toggles); also\n * supports the third \"indeterminate\" state for a parent checkbox over a\n * partially-selected group — shown as a dash instead of a check.\n *\n * An inline `label` wraps the control in a real `<label>` (a11y name comes\n * free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the\n * visible label lives elsewhere (e.g. a table header cell).\n */\nconst props = withDefaults(\n defineProps<{\n /** `true`/`false` for a plain toggle, `\"indeterminate\"` for a parent over a partially-selected group. Omit to let the box own its own state. */\n modelValue?: boolean | \"indeterminate\" | undefined;\n /** Blocks both click and keyboard input, and dims the box. */\n disabled?: boolean;\n /** Visible text, rendered inside the wrapping `<label>`. Omit and use `ariaLabel`/`ariaLabelledby` when the label lives elsewhere. */\n label?: string;\n /** Accessible name when no visible `label` is rendered by this component. */\n ariaLabel?: string;\n /** Accessible name sourced from another element's id, when no visible `label` is rendered by this component. */\n ariaLabelledby?: string;\n }>(),\n {\n // Not `false`. A concrete value here would mean \"the host owns this\", and\n // a host that passes nothing would get a box that emits its update event\n // and never moves — a control that looks broken rather than one that\n // reports an error. `undefined` is what leaves it self-managing, and the\n // explicit default is what survives Vue's absent-Boolean-casts-to-false\n // rule.\n modelValue: undefined,\n disabled: false,\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: boolean | \"indeterminate\"] }>();\n\nconst boxClass = cn(\n \"flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-input bg-background\",\n // Transform (the press squish) rides --ease-spring for a restrained release,\n // while fill/border stay on the instant --ease-out — the \"springy transform,\n // steady color\" split (boxStyle below), same language as Button/Switch.\n \"active:scale-90\",\n // Checked = a human decision (Loom law): the box fills flat warp.\n \"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground\",\n \"data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground\",\n // Focus draws the weave tight: the brand ring blooms.\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:cursor-not-allowed\",\n);\n\nconst boxStyle =\n \"transition: transform var(--duration-fast) var(--ease-spring), background-color var(--duration-instant) var(--ease-out), border-color var(--duration-instant) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);\";\n</script>\n\n<template>\n <!-- CheckboxRoot is a labelable <button role=\"checkbox\">, so wrapping it in\n <label> names it exactly like a native control; the rule's nesting/id\n heuristic just doesn't recognize reka-ui's custom element as a\n \"control\". -->\n <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->\n <label\n v-if=\"label\"\n :class=\"\n cn(\n 'inline-flex items-center gap-2 text-sm text-foreground',\n // Disabled text stays readable (AA on the light ground) — only the box dims.\n props.disabled ? 'cursor-not-allowed text-muted-foreground' : 'cursor-pointer',\n )\n \"\n >\n <CheckboxRoot\n v-bind=\"optional({ modelValue })\"\n :disabled=\"disabled\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <!-- The tick pops in with scale-in — a small causal \"it's checked now\".\n stroke-width 2.5 is the ≤12px iconography rule, not a local taste:\n the inherited 1.5 renders 0.75 device px at 12px and reads washed\n out inside the filled box. Both branches carry it identically. -->\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n {{ label }}\n </label>\n <!-- The control always dims itself when disabled; label text stays\n readable muted — same stance in both branches. -->\n <CheckboxRoot\n v-else\n v-bind=\"optional({ modelValue })\"\n :disabled=\"disabled\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkbox — a single boolean choice inside a form (as opposed to Switch,
|
|
3
|
+
* which flips a setting immediately, no form/"Save" involved). Built on Reka
|
|
4
|
+
* UI's Checkbox (role="checkbox" + aria-checked, Space toggles); also
|
|
5
|
+
* supports the third "indeterminate" state for a parent checkbox over a
|
|
6
|
+
* partially-selected group — shown as a dash instead of a check.
|
|
7
|
+
*
|
|
8
|
+
* An inline `label` wraps the control in a real `<label>` (a11y name comes
|
|
9
|
+
* free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the
|
|
10
|
+
* visible label lives elsewhere (e.g. a table header cell).
|
|
11
|
+
*/
|
|
12
|
+
type __VLS_Props = {
|
|
13
|
+
/** `true`/`false` for a plain toggle, `"indeterminate"` for a parent over a partially-selected group. Omit to let the box own its own state. */
|
|
14
|
+
modelValue?: boolean | "indeterminate" | undefined;
|
|
15
|
+
/** Blocks both click and keyboard input, and dims the box. */
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
/** Visible text, rendered inside the wrapping `<label>`. Omit and use `ariaLabel`/`ariaLabelledby` when the label lives elsewhere. */
|
|
18
|
+
label?: string;
|
|
19
|
+
/** Accessible name when no visible `label` is rendered by this component. */
|
|
20
|
+
ariaLabel?: string;
|
|
21
|
+
/** Accessible name sourced from another element's id, when no visible `label` is rendered by this component. */
|
|
22
|
+
ariaLabelledby?: string;
|
|
23
|
+
};
|
|
24
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
25
|
+
"update:modelValue": (value: boolean | "indeterminate") => any;
|
|
26
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
27
|
+
"onUpdate:modelValue"?: (value: boolean | "indeterminate") => any;
|
|
28
|
+
}>, {
|
|
29
|
+
disabled: boolean;
|
|
30
|
+
modelValue: boolean | "indeterminate" | undefined;
|
|
31
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
32
|
+
declare const _default: typeof __VLS_export;
|
|
33
|
+
export default _default;
|
|
34
|
+
//# sourceMappingURL=Checkbox.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Checkbox/Checkbox.vue"],"names":[],"mappings":"AA8HA;;;;;;;;;;GAUG;AACH,KAAK,WAAW,GAAG;IACf,gJAAgJ;IAChJ,UAAU,CAAC,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAAC;IACnD,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sIAAsI;IACtI,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gHAAgH;IAChH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAmRJ,QAAA,MAAM,YAAY;;;;;cA1RH,OAAO;gBAFL,OAAO,GAAG,eAAe,GAAG,SAAS;6EAgSpD,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { cn } from "../../lib/cn.js";
|
|
2
|
+
import { optional } from "../../lib/props.js";
|
|
3
|
+
import { Check, Minus } from "@lucide/vue";
|
|
4
|
+
import { createBlock, createElementBlock, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, openBlock, toDisplayString, unref, withCtx } from "vue";
|
|
5
|
+
import { CheckboxIndicator, CheckboxRoot } from "reka-ui";
|
|
6
|
+
//#region src/primitives/Checkbox/Checkbox.vue?vue&type=script&setup=true&lang.ts
|
|
7
|
+
/**
|
|
8
|
+
* Checkbox — a single boolean choice inside a form (as opposed to Switch,
|
|
9
|
+
* which flips a setting immediately, no form/"Save" involved). Built on Reka
|
|
10
|
+
* UI's Checkbox (role="checkbox" + aria-checked, Space toggles); also
|
|
11
|
+
* supports the third "indeterminate" state for a parent checkbox over a
|
|
12
|
+
* partially-selected group — shown as a dash instead of a check.
|
|
13
|
+
*
|
|
14
|
+
* An inline `label` wraps the control in a real `<label>` (a11y name comes
|
|
15
|
+
* free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the
|
|
16
|
+
* visible label lives elsewhere (e.g. a table header cell).
|
|
17
|
+
*/
|
|
18
|
+
var boxStyle = "transition: transform var(--duration-fast) var(--ease-spring), background-color var(--duration-instant) var(--ease-out), border-color var(--duration-instant) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);";
|
|
19
|
+
var Checkbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
20
|
+
__name: "Checkbox",
|
|
21
|
+
props: {
|
|
22
|
+
modelValue: {
|
|
23
|
+
type: [Boolean, String],
|
|
24
|
+
default: void 0
|
|
25
|
+
},
|
|
26
|
+
disabled: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: false
|
|
29
|
+
},
|
|
30
|
+
label: {},
|
|
31
|
+
ariaLabel: {},
|
|
32
|
+
ariaLabelledby: {}
|
|
33
|
+
},
|
|
34
|
+
emits: ["update:modelValue"],
|
|
35
|
+
setup(__props) {
|
|
36
|
+
const props = __props;
|
|
37
|
+
const boxClass = cn("flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-input bg-background", "active:scale-90", "data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground", "data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo", "disabled:cursor-not-allowed");
|
|
38
|
+
return (_ctx, _cache) => {
|
|
39
|
+
return __props.label ? (openBlock(), createElementBlock("label", {
|
|
40
|
+
key: 0,
|
|
41
|
+
class: normalizeClass(unref(cn)("inline-flex items-center gap-2 text-sm text-foreground", props.disabled ? "cursor-not-allowed text-muted-foreground" : "cursor-pointer"))
|
|
42
|
+
}, [createVNode(unref(CheckboxRoot), mergeProps(unref(optional)({ modelValue: __props.modelValue }), {
|
|
43
|
+
disabled: __props.disabled,
|
|
44
|
+
class: unref(cn)(unref(boxClass), "disabled:opacity-50"),
|
|
45
|
+
style: boxStyle,
|
|
46
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:modelValue", $event))
|
|
47
|
+
}), {
|
|
48
|
+
default: withCtx(({ state }) => [createVNode(unref(CheckboxIndicator), { class: "flex animate-scale-in items-center justify-center text-current" }, {
|
|
49
|
+
default: withCtx(() => [state === "indeterminate" ? (openBlock(), createBlock(unref(Minus), {
|
|
50
|
+
key: 0,
|
|
51
|
+
class: "h-3 w-3",
|
|
52
|
+
"stroke-width": 2.5
|
|
53
|
+
})) : (openBlock(), createBlock(unref(Check), {
|
|
54
|
+
key: 1,
|
|
55
|
+
class: "h-3 w-3",
|
|
56
|
+
"stroke-width": 2.5
|
|
57
|
+
}))]),
|
|
58
|
+
_: 2
|
|
59
|
+
}, 1024)]),
|
|
60
|
+
_: 1
|
|
61
|
+
}, 16, ["disabled", "class"]), createTextVNode(" " + toDisplayString(__props.label), 1)], 2)) : (openBlock(), createBlock(unref(CheckboxRoot), mergeProps({ key: 1 }, unref(optional)({ modelValue: __props.modelValue }), {
|
|
62
|
+
disabled: __props.disabled,
|
|
63
|
+
"aria-label": __props.ariaLabel,
|
|
64
|
+
"aria-labelledby": __props.ariaLabelledby,
|
|
65
|
+
class: unref(cn)(unref(boxClass), "disabled:opacity-50"),
|
|
66
|
+
style: boxStyle,
|
|
67
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.$emit("update:modelValue", $event))
|
|
68
|
+
}), {
|
|
69
|
+
default: withCtx(({ state }) => [createVNode(unref(CheckboxIndicator), { class: "flex animate-scale-in items-center justify-center text-current" }, {
|
|
70
|
+
default: withCtx(() => [state === "indeterminate" ? (openBlock(), createBlock(unref(Minus), {
|
|
71
|
+
key: 0,
|
|
72
|
+
class: "h-3 w-3",
|
|
73
|
+
"stroke-width": 2.5
|
|
74
|
+
})) : (openBlock(), createBlock(unref(Check), {
|
|
75
|
+
key: 1,
|
|
76
|
+
class: "h-3 w-3",
|
|
77
|
+
"stroke-width": 2.5
|
|
78
|
+
}))]),
|
|
79
|
+
_: 2
|
|
80
|
+
}, 1024)]),
|
|
81
|
+
_: 1
|
|
82
|
+
}, 16, [
|
|
83
|
+
"disabled",
|
|
84
|
+
"aria-label",
|
|
85
|
+
"aria-labelledby",
|
|
86
|
+
"class"
|
|
87
|
+
]));
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
//#endregion
|
|
92
|
+
export { Checkbox_vue_vue_type_script_setup_true_lang_default as default };
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=Checkbox.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../src/primitives/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckboxIndicator, CheckboxRoot } from \"reka-ui\";\nimport { Check, Minus } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\n\n/**\n * Checkbox — a single boolean choice inside a form (as opposed to Switch,\n * which flips a setting immediately, no form/\"Save\" involved). Built on Reka\n * UI's Checkbox (role=\"checkbox\" + aria-checked, Space toggles); also\n * supports the third \"indeterminate\" state for a parent checkbox over a\n * partially-selected group — shown as a dash instead of a check.\n *\n * An inline `label` wraps the control in a real `<label>` (a11y name comes\n * free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the\n * visible label lives elsewhere (e.g. a table header cell).\n */\nconst props = withDefaults(\n defineProps<{\n /** `true`/`false` for a plain toggle, `\"indeterminate\"` for a parent over a partially-selected group. Omit to let the box own its own state. */\n modelValue?: boolean | \"indeterminate\" | undefined;\n /** Blocks both click and keyboard input, and dims the box. */\n disabled?: boolean;\n /** Visible text, rendered inside the wrapping `<label>`. Omit and use `ariaLabel`/`ariaLabelledby` when the label lives elsewhere. */\n label?: string;\n /** Accessible name when no visible `label` is rendered by this component. */\n ariaLabel?: string;\n /** Accessible name sourced from another element's id, when no visible `label` is rendered by this component. */\n ariaLabelledby?: string;\n }>(),\n {\n // Not `false`. A concrete value here would mean \"the host owns this\", and\n // a host that passes nothing would get a box that emits its update event\n // and never moves — a control that looks broken rather than one that\n // reports an error. `undefined` is what leaves it self-managing, and the\n // explicit default is what survives Vue's absent-Boolean-casts-to-false\n // rule.\n modelValue: undefined,\n disabled: false,\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: boolean | \"indeterminate\"] }>();\n\nconst boxClass = cn(\n \"flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-input bg-background\",\n // Transform (the press squish) rides --ease-spring for a restrained release,\n // while fill/border stay on the instant --ease-out — the \"springy transform,\n // steady color\" split (boxStyle below), same language as Button/Switch.\n \"active:scale-90\",\n // Checked = a human decision (Loom law): the box fills flat warp.\n \"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground\",\n \"data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground\",\n // Focus draws the weave tight: the brand ring blooms.\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:cursor-not-allowed\",\n);\n\nconst boxStyle =\n \"transition: transform var(--duration-fast) var(--ease-spring), background-color var(--duration-instant) var(--ease-out), border-color var(--duration-instant) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);\";\n</script>\n\n<template>\n <!-- CheckboxRoot is a labelable <button role=\"checkbox\">, so wrapping it in\n <label> names it exactly like a native control; the rule's nesting/id\n heuristic just doesn't recognize reka-ui's custom element as a\n \"control\". -->\n <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->\n <label\n v-if=\"label\"\n :class=\"\n cn(\n 'inline-flex items-center gap-2 text-sm text-foreground',\n // Disabled text stays readable (AA on the light ground) — only the box dims.\n props.disabled ? 'cursor-not-allowed text-muted-foreground' : 'cursor-pointer',\n )\n \"\n >\n <CheckboxRoot\n v-bind=\"optional({ modelValue })\"\n :disabled=\"disabled\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <!-- The tick pops in with scale-in — a small causal \"it's checked now\".\n stroke-width 2.5 is the ≤12px iconography rule, not a local taste:\n the inherited 1.5 renders 0.75 device px at 12px and reads washed\n out inside the filled box. Both branches carry it identically. -->\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n {{ label }}\n </label>\n <!-- The control always dims itself when disabled; label text stays\n readable muted — same stance in both branches. -->\n <CheckboxRoot\n v-else\n v-bind=\"optional({ modelValue })\"\n :disabled=\"disabled\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;AA0DA,IAAM,WACJ;;;;;;;;;;;;;;;;;;EA1CF,MAAM,QAAQ;EA2Bd,MAAM,WAAW,GACf,kGAIA,mBAEA,oHACA,sIAEA,+GACA,6BACF;;GAaU,OAAA,QAAA,SADR,UAAA,GAAA,mBA6BQ,SAAA;;IA3BL,OAAK,eAAS,MAAA,EAAA,CAAE,CAAA,0DAAkK,MAAM,WAAQ,6CAAA,gBAAA,CAAA;GAQjM,GAAA,CAAA,YAiBe,MAAA,YAAA,GAjBf,WACU,MAgBK,QAAA,CAhBG,CAAA,EAAA,YAAG,QAAA,WAAU,CAAA,GAAA;IAC5B,UAAU,QAAA;IACV,OAAO,MAAA,EAAA,CAAE,CAAC,MAAA,QAAA,GAAQ,qBAAA;IAClB,OAAO;IACP,uBAAkB,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,qBAAsB,MAAM;;IAE3C,SAAO,SAQI,EARA,YAAK,CAKzB,YAGoB,MAAA,iBAAA,GAAA,EAHD,OAAM,iEAAgE,GAAA;KACvF,SAAA,cAA8E,CAAjE,UAAK,mBAAlB,UAAA,GAAA,YAA8E,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc;KACvE,CAAA,MAAA,UAAA,GAAA,YAAoD,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc;;;;;GAGpC,GAAA,IAAA,CAAA,YAAA,OAAA,CAAA,GAAA,gBAAA,MACf,gBAAG,QAAA,KAAK,GAAA,CAAA,CAAA,GAAA,CAAA,MAIV,UAAA,GAAA,YAgBe,MAAA,YAAA,GAhBf,WAgBe,EAAA,KAAA,EAAA,GAdL,MAAA,QAAA,CAAQ,CAAA,EAAA,YAAG,QAAA,WAAU,CAAA,GAAA;IAC5B,UAAU,QAAA;IACV,cAAY,QAAA;IACZ,mBAAiB,QAAA;IACjB,OAAO,MAAA,EAAA,CAAE,CAAC,MAAA,QAAA,GAAQ,qBAAA;IAClB,OAAO;IACP,uBAAkB,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,qBAAsB,MAAM;;IAE3C,SAAO,SAII,EAJA,YAAK,CACzB,YAGoB,MAAA,iBAAA,GAAA,EAHD,OAAM,iEAAgE,GAAA;KACvF,SAAA,cAA8E,CAAjE,UAAK,mBAAlB,UAAA,GAAA,YAA8E,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc;KACvE,CAAA,MAAA,UAAA,GAAA,YAAoD,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import Dialog_vue_vue_type_script_setup_true_lang_default from "./Dialog.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/primitives/Dialog/Dialog.vue
|
|
3
|
+
var Dialog_default = Dialog_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { Dialog_default as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=Dialog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.js","names":[],"sources":["../../../src/primitives/Dialog/Dialog.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * How wide the task surface gets. Width is the primitive's decision rather\n * than a class a caller passes, so three dialogs opened from three screens\n * cannot be three different widths: `md` for a confirm or a short form, `lg`\n * for a form with several sections, `xl` for an authoring surface — an editor\n * living inside a dialog.\n */\nexport type DialogSize = \"md\" | \"lg\" | \"xl\";\n\n/**\n * Each width is capped against the viewport, so the largest sizes stay usable\n * on a laptop instead of running off the screen. `satisfies` is what keeps the\n * map and the union honest: adding a member to one and not the other stops\n * compiling.\n */\nconst SIZE_CLASS = {\n md: \"w-[min(92vw,32rem)]\",\n lg: \"w-[min(92vw,44rem)]\",\n xl: \"w-[min(94vw,64rem)]\",\n} satisfies Record<DialogSize, string>;\n</script>\n\n<script setup lang=\"ts\">\nimport {\n DialogRoot,\n DialogTrigger,\n DialogPortal,\n DialogOverlay,\n DialogContent,\n DialogTitle,\n DialogDescription,\n DialogClose,\n} from \"reka-ui\";\nimport { X } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\n\n/**\n * Dialog — a modal task surface that blocks the rest of the UI until it is\n * resolved: confirming a destructive action, or a form that deserves the\n * user's whole attention.\n *\n * The escape contract, and it is the strictest of the overlays: opening moves\n * focus into the panel and *traps* it there, so Tab cycles the dialog's own\n * controls and never reaches the page behind. Esc, the overlay and the close\n * button all close it; closing returns focus to whatever opened it. The page\n * behind does not scroll while it is open. Everything outside the panel is\n * hidden from assistive technology, which is what makes the block real rather\n * than visual.\n *\n * `title` is a required prop rather than optional chrome: without a rendered\n * title the dialog has no accessible name, and a screen reader announces a\n * modal that says nothing about what it is asking. Pass `hideTitle` to keep it\n * for assistive technology while dropping it from the visual layout.\n *\n * Reach for `Popover` when the panel is non-blocking secondary content, and a\n * transient notification when the user need not act at all.\n */\nwithDefaults(\n defineProps<{\n /** Drive the dialog from the host with `v-model:open`; omit it and the dialog owns its own state. */\n open?: boolean | undefined;\n /** The accessible name, and the question the dialog is asking. State the consequence (\"Delete scene?\"), not \"Are you sure?\". */\n title: string;\n /** Wired as the dialog's accessible description — the consequence line, rather than loose body text. */\n description?: string;\n /** Keep the title as the accessible name but drop it from the visual layout. */\n hideTitle?: boolean;\n /** Show the close affordance in the top corner. Esc and an overlay click close the dialog either way. */\n closable?: boolean;\n /** Panel width. `md` confirms, `lg` multi-section forms, `xl` authoring surfaces. */\n size?: DialogSize;\n }>(),\n // `open: undefined` is load-bearing, not a redundant default — it is what\n // keeps the uncontrolled third state reachable past Vue's absent-Boolean\n // casting. `optional()` in the template is the other half; its docblock\n // carries the reasoning for both. `description` needs no such entry: a\n // string prop is already `undefined` when absent.\n { open: undefined, hideTitle: false, closable: true, size: \"md\" },\n);\n\ndefineEmits<{ \"update:open\": [value: boolean] }>();\n</script>\n\n<template>\n <DialogRoot v-bind=\"optional({ open })\" @update:open=\"$emit('update:open', $event)\">\n <!-- @slot The control that opens the dialog. Optional — omit it and drive\n the dialog entirely from the host with `v-model:open`. -->\n <DialogTrigger v-if=\"$slots.trigger\" as-child>\n <slot name=\"trigger\" />\n </DialogTrigger>\n\n <DialogPortal>\n <!-- The scrim is heavy on purpose: at 70% the page behind reads as\n context, and at 60% it read as competing content. It fades rather\n than moves, so nothing behind the dialog appears to shift. -->\n <DialogOverlay class=\"fixed inset-0 z-50 bg-foreground/70 data-[state=open]:animate-fade\" />\n <DialogContent\n :class=\"\n cn(\n 'fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2',\n SIZE_CLASS[size],\n 'rounded-lg border border-border bg-popover p-6 text-popover-foreground shadow-lg outline-none',\n // Scoped to the open state, never unconditional. Reka's Presence\n // keeps closed content mounted until an animationend arrives, and a\n // mount-only animation never fires a second one — which here would\n // strand a full-screen, input-blocking overlay over a page with no\n // dialog on it. Scoped, the closed element computes\n // `animation-name: none` and Presence unmounts it at once.\n 'data-[state=open]:animate-scale-in',\n )\n \"\n >\n <DialogTitle :class=\"cn('text-base font-semibold', hideTitle && 'sr-only')\">\n {{ title }}\n </DialogTitle>\n <DialogDescription v-if=\"description\" class=\"mt-1 text-sm text-muted-foreground\">\n {{ description }}\n </DialogDescription>\n\n <!-- The gap above the body is dropped when nothing visible precedes\n it, so a dialog with a hidden title and no description does not\n open with an empty band at the top. -->\n <div :class=\"cn((description || !hideTitle) && 'mt-4')\">\n <!-- @slot The dialog body. -->\n <slot />\n </div>\n\n <!-- @slot The action row, aligned to the trailing edge. -->\n <div v-if=\"$slots.footer\" class=\"mt-6 flex items-center justify-end gap-2\">\n <slot name=\"footer\" />\n </div>\n\n <DialogClose\n v-if=\"closable\"\n aria-label=\"Close\"\n class=\"absolute right-4 top-4 inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n >\n <X class=\"h-4 w-4\" />\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n </DialogRoot>\n</template>\n"],"mappings":""}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How wide the task surface gets. Width is the primitive's decision rather
|
|
3
|
+
* than a class a caller passes, so three dialogs opened from three screens
|
|
4
|
+
* cannot be three different widths: `md` for a confirm or a short form, `lg`
|
|
5
|
+
* for a form with several sections, `xl` for an authoring surface — an editor
|
|
6
|
+
* living inside a dialog.
|
|
7
|
+
*/
|
|
8
|
+
export type DialogSize = "md" | "lg" | "xl";
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
11
|
+
declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
|
|
12
|
+
/** Drive the dialog from the host with `v-model:open`; omit it and the dialog owns its own state. */
|
|
13
|
+
open?: boolean | undefined;
|
|
14
|
+
/** The accessible name, and the question the dialog is asking. State the consequence ("Delete scene?"), not "Are you sure?". */
|
|
15
|
+
title: string;
|
|
16
|
+
/** Wired as the dialog's accessible description — the consequence line, rather than loose body text. */
|
|
17
|
+
description?: string;
|
|
18
|
+
/** Keep the title as the accessible name but drop it from the visual layout. */
|
|
19
|
+
hideTitle?: boolean;
|
|
20
|
+
/** Show the close affordance in the top corner. Esc and an overlay click close the dialog either way. */
|
|
21
|
+
closable?: boolean;
|
|
22
|
+
/** Panel width. `md` confirms, `lg` multi-section forms, `xl` authoring surfaces. */
|
|
23
|
+
size?: DialogSize;
|
|
24
|
+
}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
25
|
+
"update:open": (value: boolean) => any;
|
|
26
|
+
}, string, import("vue").PublicProps, Readonly<{
|
|
27
|
+
/** Drive the dialog from the host with `v-model:open`; omit it and the dialog owns its own state. */
|
|
28
|
+
open?: boolean | undefined;
|
|
29
|
+
/** The accessible name, and the question the dialog is asking. State the consequence ("Delete scene?"), not "Are you sure?". */
|
|
30
|
+
title: string;
|
|
31
|
+
/** Wired as the dialog's accessible description — the consequence line, rather than loose body text. */
|
|
32
|
+
description?: string;
|
|
33
|
+
/** Keep the title as the accessible name but drop it from the visual layout. */
|
|
34
|
+
hideTitle?: boolean;
|
|
35
|
+
/** Show the close affordance in the top corner. Esc and an overlay click close the dialog either way. */
|
|
36
|
+
closable?: boolean;
|
|
37
|
+
/** Panel width. `md` confirms, `lg` multi-section forms, `xl` authoring surfaces. */
|
|
38
|
+
size?: DialogSize;
|
|
39
|
+
}> & Readonly<{
|
|
40
|
+
"onUpdate:open"?: (value: boolean) => any;
|
|
41
|
+
}>, {
|
|
42
|
+
size: DialogSize;
|
|
43
|
+
open: boolean | undefined;
|
|
44
|
+
hideTitle: boolean;
|
|
45
|
+
closable: boolean;
|
|
46
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
|
|
47
|
+
trigger?: (props: {}) => any;
|
|
48
|
+
} & {
|
|
49
|
+
default?: (props: {}) => any;
|
|
50
|
+
} & {
|
|
51
|
+
footer?: (props: {}) => any;
|
|
52
|
+
}>;
|
|
53
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
54
|
+
new (): {
|
|
55
|
+
$slots: S;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=Dialog.vue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Dialog/Dialog.vue"],"names":[],"mappings":"AAmKA;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;wBAavB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAuBd,qGAAqG;WAC9F,OAAO,GAAG,SAAS;IAC1B,gIAAgI;WACzH,MAAM;IACb,wGAAwG;kBAC1F,MAAM;IACpB,gFAAgF;gBACpE,OAAO;IACnB,yGAAyG;eAC9F,OAAO;IAClB,qFAAqF;WAC9E,UAAU;;;;IAXjB,qGAAqG;WAC9F,OAAO,GAAG,SAAS;IAC1B,gIAAgI;WACzH,MAAM;IACb,wGAAwG;kBAC1F,MAAM;IACpB,gFAAgF;gBACpE,OAAO;IACnB,yGAAyG;eAC9F,OAAO;IAClB,qFAAqF;WAC9E,UAAU;;;;UAAV,UAAU;UAVV,OAAO,GAAG,SAAS;eAMd,OAAO;cAER,OAAO;;cAuQR,CAAC,KAAK,IAAiB,KAAK,GAAG;;cAC/B,CAAC,KAAK,IAAiB,KAAK,GAAG;;aAChC,CAAC,KAAK,IAAiB,KAAK,GAAG;EAWxC,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { cn } from "../../lib/cn.js";
|
|
2
|
+
import { optional } from "../../lib/props.js";
|
|
3
|
+
import { X } from "@lucide/vue";
|
|
4
|
+
import { createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, openBlock, renderSlot, toDisplayString, unref, withCtx } from "vue";
|
|
5
|
+
import { DialogClose, DialogContent, DialogDescription, DialogOverlay, DialogPortal, DialogRoot, DialogTitle, DialogTrigger } from "reka-ui";
|
|
6
|
+
//#region src/primitives/Dialog/Dialog.vue?vue&type=script&setup=true&lang.ts
|
|
7
|
+
var _hoisted_1 = {
|
|
8
|
+
key: 1,
|
|
9
|
+
class: "mt-6 flex items-center justify-end gap-2"
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Each width is capped against the viewport, so the largest sizes stay usable
|
|
13
|
+
* on a laptop instead of running off the screen. `satisfies` is what keeps the
|
|
14
|
+
* map and the union honest: adding a member to one and not the other stops
|
|
15
|
+
* compiling.
|
|
16
|
+
*/
|
|
17
|
+
var SIZE_CLASS = {
|
|
18
|
+
md: "w-[min(92vw,32rem)]",
|
|
19
|
+
lg: "w-[min(92vw,44rem)]",
|
|
20
|
+
xl: "w-[min(94vw,64rem)]"
|
|
21
|
+
};
|
|
22
|
+
var Dialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
23
|
+
__name: "Dialog",
|
|
24
|
+
props: {
|
|
25
|
+
open: {
|
|
26
|
+
type: Boolean,
|
|
27
|
+
default: void 0
|
|
28
|
+
},
|
|
29
|
+
title: {},
|
|
30
|
+
description: {},
|
|
31
|
+
hideTitle: {
|
|
32
|
+
type: Boolean,
|
|
33
|
+
default: false
|
|
34
|
+
},
|
|
35
|
+
closable: {
|
|
36
|
+
type: Boolean,
|
|
37
|
+
default: true
|
|
38
|
+
},
|
|
39
|
+
size: { default: "md" }
|
|
40
|
+
},
|
|
41
|
+
emits: ["update:open"],
|
|
42
|
+
setup(__props) {
|
|
43
|
+
return (_ctx, _cache) => {
|
|
44
|
+
return openBlock(), createBlock(unref(DialogRoot), mergeProps(unref(optional)({ open: __props.open }), { "onUpdate:open": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:open", $event)) }), {
|
|
45
|
+
default: withCtx(() => [_ctx.$slots.trigger ? (openBlock(), createBlock(unref(DialogTrigger), {
|
|
46
|
+
key: 0,
|
|
47
|
+
"as-child": ""
|
|
48
|
+
}, {
|
|
49
|
+
default: withCtx(() => [renderSlot(_ctx.$slots, "trigger")]),
|
|
50
|
+
_: 3
|
|
51
|
+
})) : createCommentVNode("", true), createVNode(unref(DialogPortal), null, {
|
|
52
|
+
default: withCtx(() => [createVNode(unref(DialogOverlay), { class: "fixed inset-0 z-50 bg-foreground/70 data-[state=open]:animate-fade" }), createVNode(unref(DialogContent), { class: normalizeClass(unref(cn)("fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2", SIZE_CLASS[__props.size], "rounded-lg border border-border bg-popover p-6 text-popover-foreground shadow-lg outline-none", "data-[state=open]:animate-scale-in")) }, {
|
|
53
|
+
default: withCtx(() => [
|
|
54
|
+
createVNode(unref(DialogTitle), { class: normalizeClass(unref(cn)("text-base font-semibold", __props.hideTitle && "sr-only")) }, {
|
|
55
|
+
default: withCtx(() => [createTextVNode(toDisplayString(__props.title), 1)]),
|
|
56
|
+
_: 1
|
|
57
|
+
}, 8, ["class"]),
|
|
58
|
+
__props.description ? (openBlock(), createBlock(unref(DialogDescription), {
|
|
59
|
+
key: 0,
|
|
60
|
+
class: "mt-1 text-sm text-muted-foreground"
|
|
61
|
+
}, {
|
|
62
|
+
default: withCtx(() => [createTextVNode(toDisplayString(__props.description), 1)]),
|
|
63
|
+
_: 1
|
|
64
|
+
})) : createCommentVNode("", true),
|
|
65
|
+
createElementVNode("div", { class: normalizeClass(unref(cn)((__props.description || !__props.hideTitle) && "mt-4")) }, [renderSlot(_ctx.$slots, "default")], 2),
|
|
66
|
+
_ctx.$slots.footer ? (openBlock(), createElementBlock("div", _hoisted_1, [renderSlot(_ctx.$slots, "footer")])) : createCommentVNode("", true),
|
|
67
|
+
__props.closable ? (openBlock(), createBlock(unref(DialogClose), {
|
|
68
|
+
key: 2,
|
|
69
|
+
"aria-label": "Close",
|
|
70
|
+
class: "absolute right-4 top-4 inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring"
|
|
71
|
+
}, {
|
|
72
|
+
default: withCtx(() => [createVNode(unref(X), { class: "h-4 w-4" })]),
|
|
73
|
+
_: 1
|
|
74
|
+
})) : createCommentVNode("", true)
|
|
75
|
+
]),
|
|
76
|
+
_: 3
|
|
77
|
+
}, 8, ["class"])]),
|
|
78
|
+
_: 3
|
|
79
|
+
})]),
|
|
80
|
+
_: 3
|
|
81
|
+
}, 16);
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
//#endregion
|
|
86
|
+
export { Dialog_vue_vue_type_script_setup_true_lang_default as default };
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=Dialog.vue_vue_type_script_setup_true_lang.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dialog.vue_vue_type_script_setup_true_lang.js","names":["$emit","$slots"],"sources":["../../../src/primitives/Dialog/Dialog.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * How wide the task surface gets. Width is the primitive's decision rather\n * than a class a caller passes, so three dialogs opened from three screens\n * cannot be three different widths: `md` for a confirm or a short form, `lg`\n * for a form with several sections, `xl` for an authoring surface — an editor\n * living inside a dialog.\n */\nexport type DialogSize = \"md\" | \"lg\" | \"xl\";\n\n/**\n * Each width is capped against the viewport, so the largest sizes stay usable\n * on a laptop instead of running off the screen. `satisfies` is what keeps the\n * map and the union honest: adding a member to one and not the other stops\n * compiling.\n */\nconst SIZE_CLASS = {\n md: \"w-[min(92vw,32rem)]\",\n lg: \"w-[min(92vw,44rem)]\",\n xl: \"w-[min(94vw,64rem)]\",\n} satisfies Record<DialogSize, string>;\n</script>\n\n<script setup lang=\"ts\">\nimport {\n DialogRoot,\n DialogTrigger,\n DialogPortal,\n DialogOverlay,\n DialogContent,\n DialogTitle,\n DialogDescription,\n DialogClose,\n} from \"reka-ui\";\nimport { X } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\n\n/**\n * Dialog — a modal task surface that blocks the rest of the UI until it is\n * resolved: confirming a destructive action, or a form that deserves the\n * user's whole attention.\n *\n * The escape contract, and it is the strictest of the overlays: opening moves\n * focus into the panel and *traps* it there, so Tab cycles the dialog's own\n * controls and never reaches the page behind. Esc, the overlay and the close\n * button all close it; closing returns focus to whatever opened it. The page\n * behind does not scroll while it is open. Everything outside the panel is\n * hidden from assistive technology, which is what makes the block real rather\n * than visual.\n *\n * `title` is a required prop rather than optional chrome: without a rendered\n * title the dialog has no accessible name, and a screen reader announces a\n * modal that says nothing about what it is asking. Pass `hideTitle` to keep it\n * for assistive technology while dropping it from the visual layout.\n *\n * Reach for `Popover` when the panel is non-blocking secondary content, and a\n * transient notification when the user need not act at all.\n */\nwithDefaults(\n defineProps<{\n /** Drive the dialog from the host with `v-model:open`; omit it and the dialog owns its own state. */\n open?: boolean | undefined;\n /** The accessible name, and the question the dialog is asking. State the consequence (\"Delete scene?\"), not \"Are you sure?\". */\n title: string;\n /** Wired as the dialog's accessible description — the consequence line, rather than loose body text. */\n description?: string;\n /** Keep the title as the accessible name but drop it from the visual layout. */\n hideTitle?: boolean;\n /** Show the close affordance in the top corner. Esc and an overlay click close the dialog either way. */\n closable?: boolean;\n /** Panel width. `md` confirms, `lg` multi-section forms, `xl` authoring surfaces. */\n size?: DialogSize;\n }>(),\n // `open: undefined` is load-bearing, not a redundant default — it is what\n // keeps the uncontrolled third state reachable past Vue's absent-Boolean\n // casting. `optional()` in the template is the other half; its docblock\n // carries the reasoning for both. `description` needs no such entry: a\n // string prop is already `undefined` when absent.\n { open: undefined, hideTitle: false, closable: true, size: \"md\" },\n);\n\ndefineEmits<{ \"update:open\": [value: boolean] }>();\n</script>\n\n<template>\n <DialogRoot v-bind=\"optional({ open })\" @update:open=\"$emit('update:open', $event)\">\n <!-- @slot The control that opens the dialog. Optional — omit it and drive\n the dialog entirely from the host with `v-model:open`. -->\n <DialogTrigger v-if=\"$slots.trigger\" as-child>\n <slot name=\"trigger\" />\n </DialogTrigger>\n\n <DialogPortal>\n <!-- The scrim is heavy on purpose: at 70% the page behind reads as\n context, and at 60% it read as competing content. It fades rather\n than moves, so nothing behind the dialog appears to shift. -->\n <DialogOverlay class=\"fixed inset-0 z-50 bg-foreground/70 data-[state=open]:animate-fade\" />\n <DialogContent\n :class=\"\n cn(\n 'fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2',\n SIZE_CLASS[size],\n 'rounded-lg border border-border bg-popover p-6 text-popover-foreground shadow-lg outline-none',\n // Scoped to the open state, never unconditional. Reka's Presence\n // keeps closed content mounted until an animationend arrives, and a\n // mount-only animation never fires a second one — which here would\n // strand a full-screen, input-blocking overlay over a page with no\n // dialog on it. Scoped, the closed element computes\n // `animation-name: none` and Presence unmounts it at once.\n 'data-[state=open]:animate-scale-in',\n )\n \"\n >\n <DialogTitle :class=\"cn('text-base font-semibold', hideTitle && 'sr-only')\">\n {{ title }}\n </DialogTitle>\n <DialogDescription v-if=\"description\" class=\"mt-1 text-sm text-muted-foreground\">\n {{ description }}\n </DialogDescription>\n\n <!-- The gap above the body is dropped when nothing visible precedes\n it, so a dialog with a hidden title and no description does not\n open with an empty band at the top. -->\n <div :class=\"cn((description || !hideTitle) && 'mt-4')\">\n <!-- @slot The dialog body. -->\n <slot />\n </div>\n\n <!-- @slot The action row, aligned to the trailing edge. -->\n <div v-if=\"$slots.footer\" class=\"mt-6 flex items-center justify-end gap-2\">\n <slot name=\"footer\" />\n </div>\n\n <DialogClose\n v-if=\"closable\"\n aria-label=\"Close\"\n class=\"absolute right-4 top-4 inline-flex h-7 w-7 items-center justify-center rounded-md text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n >\n <X class=\"h-4 w-4\" />\n </DialogClose>\n </DialogContent>\n </DialogPortal>\n </DialogRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAM,aAAa;CACjB,IAAI;CACJ,IAAI;CACJ,IAAI;AACN;;;;;;;;;;;;;;;;;;;;;;;GAkEE,OAAA,UAAA,GAAA,YAyDa,MAAA,UAAA,GAzDb,WAAoB,MAyDP,QAAA,CAzDe,CAAA,EAAA,MAAG,QAAA,KAAI,CAAA,GAAA,EAAM,iBAAW,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,eAAgB,MAAM,GAAA,CAAA,GAAA;IAG/E,SAAA,cAEgB,CAFKC,KAAAA,OAAO,WAA5B,UAAA,GAAA,YAEgB,MAAA,aAAA,GAAA;;KAFqB,YAAA;;KACnC,SAAA,cAAuB,CAAvB,WAAuB,KAAA,QAAA,SAAA,CAAA,CAAA;;IAGzB,CAAA,KAAA,mBAAA,IAAA,IAAA,GAAA,YAiDe,MAAA,YAAA,GAAA,MAAA;KA7Cb,SAAA,cAA4F,CAA5F,YAA4F,MAAA,aAAA,GAAA,EAA7E,OAAM,qEAAoE,CAAA,GACzF,YA2CgB,MAAA,aAAA,GAAA,EA1Cb,OAAK,eAAa,MAAA,EAAA,CAAE,CAAA,iEAA2F,WAAW,QAAA,OAAA,iGAAA,oCAAA,CAAA,EAAA,GAAA;MAe3H,SAAA,cAEc;OAFd,YAEc,MAAA,WAAA,GAAA,EAFA,OAAK,eAAE,MAAA,EAAA,CAAE,CAAA,2BAA4B,QAAA,aAAS,SAAA,CAAA,EAAA,GAAA;QAC1D,SAAA,cAAW,CAAR,gBAAA,gBAAA,QAAA,KAAK,GAAA,CAAA,CAAA,CAAA;;;OAEe,QAAA,eAAzB,UAAA,GAAA,YAEoB,MAAA,iBAAA,GAAA;;QAFkB,OAAM;;QAC1C,SAAA,cAAiB,CAAd,gBAAA,gBAAA,QAAA,WAAW,GAAA,CAAA,CAAA,CAAA;;;OAMhB,mBAGM,OAAA,EAHA,OAAK,eAAE,MAAA,EAAA,CAAE,EAAE,QAAA,eAAW,CAAK,QAAA,cAAS,MAAA,CAAA,EAAA,GAAA,CAExC,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA;OAICA,KAAAA,OAAO,UAAlB,UAAA,GAAA,mBAEM,OAFN,YAEM,CADJ,WAAsB,KAAA,QAAA,QAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;OAIhB,QAAA,YADR,UAAA,GAAA,YAMc,MAAA,WAAA,GAAA;;QAJZ,cAAW;QACX,OAAM;;QAEN,SAAA,cAAqB,CAArB,YAAqB,MAAA,CAAA,GAAA,EAAlB,OAAM,UAAS,CAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import DropdownMenu_vue_vue_type_script_setup_true_lang_default from "./DropdownMenu.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region src/primitives/DropdownMenu/DropdownMenu.vue
|
|
3
|
+
var DropdownMenu_default = DropdownMenu_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { DropdownMenu_default as default };
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=DropdownMenu.js.map
|