zabi-components 5.0.22 → 7.0.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 +139 -1478
- package/THEME.md +473 -0
- package/THEMING.md +248 -0
- package/dist/atoms/ActionPanel.svelte +116 -0
- package/dist/atoms/ActionPanel.svelte.d.ts +19 -0
- package/dist/atoms/Badge.svelte +1 -1
- package/dist/atoms/Badge.svelte.d.ts +1 -1
- package/dist/atoms/Button.svelte +35 -16
- package/dist/atoms/Button.svelte.d.ts +3 -1
- package/dist/atoms/Card.svelte +49 -67
- package/dist/atoms/Card.svelte.d.ts +4 -4
- package/dist/atoms/CardHeader.svelte +15 -2
- package/dist/atoms/CardHeader.svelte.d.ts +5 -0
- package/dist/atoms/Checkbox.svelte +50 -76
- package/dist/atoms/Checkbox.svelte.d.ts +7 -2
- package/dist/atoms/CodeBlock.svelte +20 -34
- package/dist/atoms/CodeBlock.svelte.d.ts +1 -0
- package/dist/atoms/ColorPicker.svelte +3 -7
- package/dist/atoms/Container.svelte +41 -0
- package/dist/atoms/Container.svelte.d.ts +12 -0
- package/dist/atoms/Divider.svelte +68 -0
- package/dist/atoms/Divider.svelte.d.ts +13 -0
- package/dist/atoms/FeatureCard.svelte +35 -50
- package/dist/atoms/FeatureCard.svelte.d.ts +9 -4
- package/dist/atoms/IconButton.svelte +33 -24
- package/dist/atoms/IconButton.svelte.d.ts +4 -8
- package/dist/atoms/Input.svelte +58 -26
- package/dist/atoms/Input.svelte.d.ts +6 -1
- package/dist/atoms/List.svelte +2 -7
- package/dist/atoms/List.svelte.d.ts +1 -6
- package/dist/atoms/ListItem.svelte +54 -65
- package/dist/atoms/ListItem.svelte.d.ts +7 -13
- package/dist/atoms/ListItemLeading.svelte +19 -0
- package/dist/atoms/ListItemLeading.svelte.d.ts +9 -0
- package/dist/atoms/Progress.svelte +2 -2
- package/dist/atoms/Radio.svelte +51 -0
- package/dist/atoms/Radio.svelte.d.ts +14 -0
- package/dist/atoms/Select.svelte +28 -33
- package/dist/atoms/Select.svelte.d.ts +0 -10
- package/dist/atoms/SelectionControl.svelte +98 -0
- package/dist/atoms/SelectionControl.svelte.d.ts +26 -0
- package/dist/atoms/Skeleton.svelte +39 -15
- package/dist/atoms/Skeleton.svelte.d.ts +7 -3
- package/dist/atoms/Table.svelte +27 -0
- package/dist/atoms/Table.svelte.d.ts +10 -0
- package/dist/atoms/Text.svelte +46 -0
- package/dist/atoms/Text.svelte.d.ts +13 -0
- package/dist/atoms/Textarea.svelte +74 -53
- package/dist/atoms/Textarea.svelte.d.ts +6 -2
- package/dist/atoms/ThemeToggle.svelte +35 -24
- package/dist/atoms/ThemeToggle.svelte.d.ts +1 -0
- package/dist/atoms/Toast.svelte +55 -31
- package/dist/atoms/Toast.svelte.d.ts +4 -1
- package/dist/atoms/Toggle.svelte +37 -22
- package/dist/atoms/Toggle.svelte.d.ts +2 -1
- package/dist/atoms/Tooltip.svelte +90 -11
- package/dist/atoms/index.d.ts +6 -0
- package/dist/atoms/index.js +6 -0
- package/dist/atoms/selection-control.styles.d.ts +25 -0
- package/dist/atoms/selection-control.styles.js +30 -0
- package/dist/components/atoms/index.d.ts +6 -0
- package/dist/components/atoms/index.d.ts.map +1 -1
- package/dist/components/atoms/selection-control.styles.d.ts +26 -0
- package/dist/components/atoms/selection-control.styles.d.ts.map +1 -0
- package/dist/components/index.d.ts +42 -7
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/molecules/index.d.ts +10 -0
- package/dist/components/molecules/index.d.ts.map +1 -1
- package/dist/components/molecules/navigation-menu-context.d.ts +11 -0
- package/dist/components/molecules/navigation-menu-context.d.ts.map +1 -1
- package/dist/components/molecules/toast-store.d.ts +39 -0
- package/dist/components/molecules/toast-store.d.ts.map +1 -0
- package/dist/components/organisms/index.d.ts +3 -3
- package/dist/components/organisms/index.d.ts.map +1 -1
- package/dist/components/types/page.types.d.ts +69 -0
- package/dist/components/types/page.types.d.ts.map +1 -0
- package/dist/components/types/page.types.js +1 -0
- package/dist/components/types/variants.d.ts +64 -0
- package/dist/components/types/variants.d.ts.map +1 -0
- package/dist/components/types/variants.js +44 -0
- package/dist/components/util/fixed-sidebar-flyout.d.ts +23 -0
- package/dist/components/util/fixed-sidebar-flyout.d.ts.map +1 -0
- package/dist/components/util/focus-utils.d.ts +12 -0
- package/dist/components/util/focus-utils.d.ts.map +1 -0
- package/dist/components/util/ssr-safe.d.ts +17 -0
- package/dist/components/util/ssr-safe.d.ts.map +1 -0
- package/dist/index.d.ts +42 -7
- package/dist/index.js +45 -10
- package/dist/lib/layout-width-tokens.d.ts +17 -0
- package/dist/lib/layout-width-tokens.d.ts.map +1 -0
- package/dist/lib/showcase/component-docs/Button.d.ts +3 -0
- package/dist/lib/showcase/component-docs/Button.d.ts.map +1 -0
- package/dist/lib/showcase/component-docs/Input.d.ts +3 -0
- package/dist/lib/showcase/component-docs/Input.d.ts.map +1 -0
- package/dist/lib/showcase/component-docs/List.d.ts +3 -0
- package/dist/lib/showcase/component-docs/List.d.ts.map +1 -0
- package/dist/lib/showcase/component-docs/Modal.d.ts +3 -0
- package/dist/lib/showcase/component-docs/Modal.d.ts.map +1 -0
- package/dist/lib/showcase/component-docs/Radio.d.ts +3 -0
- package/dist/lib/showcase/component-docs/Radio.d.ts.map +1 -0
- package/dist/lib/showcase/component-docs/SidebarNavigation.d.ts +3 -0
- package/dist/lib/showcase/component-docs/SidebarNavigation.d.ts.map +1 -0
- package/dist/lib/showcase/component-docs/Skeleton.d.ts +3 -0
- package/dist/lib/showcase/component-docs/Skeleton.d.ts.map +1 -0
- package/dist/lib/showcase/component-docs/_shared.d.ts +12 -0
- package/dist/lib/showcase/component-docs/_shared.d.ts.map +1 -0
- package/dist/lib/showcase/component-docs/index.d.ts +4 -0
- package/dist/lib/showcase/component-docs/index.d.ts.map +1 -0
- package/dist/lib/showcase/components-catalog.d.ts +3 -0
- package/dist/lib/showcase/components-catalog.d.ts.map +1 -0
- package/dist/lib/showcase/components-showcase-constants.d.ts +89 -0
- package/dist/lib/showcase/components-showcase-constants.d.ts.map +1 -0
- package/dist/lib/showcase/docs-sidebar-helpers.d.ts +15 -0
- package/dist/lib/showcase/docs-sidebar-helpers.d.ts.map +1 -0
- package/dist/molecules/Alert.svelte +50 -23
- package/dist/molecules/Alert.svelte.d.ts +1 -1
- package/dist/molecules/ComponentDemo.svelte +54 -51
- package/dist/molecules/ContactForm.svelte +70 -65
- package/dist/molecules/Dropdown.svelte +99 -108
- package/dist/molecules/Dropdown.svelte.d.ts +12 -6
- package/dist/molecules/EmptyState.svelte +44 -0
- package/dist/molecules/EmptyState.svelte.d.ts +11 -0
- package/dist/molecules/FormField.svelte +89 -0
- package/dist/molecules/FormField.svelte.d.ts +23 -0
- package/dist/molecules/Header.svelte +41 -0
- package/dist/molecules/Header.svelte.d.ts +10 -0
- package/dist/molecules/ImageUpload.svelte +1 -1
- package/dist/molecules/Modal.svelte +39 -26
- package/dist/molecules/Modal.svelte.d.ts +4 -2
- package/dist/molecules/NavigationMenu.svelte +16 -0
- package/dist/molecules/NavigationMenu.svelte.d.ts +2 -0
- package/dist/molecules/NavigationMenuContent.svelte +9 -1
- package/dist/molecules/NavigationMenuLink.svelte +1 -1
- package/dist/molecules/NavigationMenuTrigger.svelte +9 -4
- package/dist/molecules/Page.svelte +16 -0
- package/dist/molecules/Page.svelte.d.ts +8 -0
- package/dist/molecules/PropsTable.svelte +61 -0
- package/dist/molecules/PropsTable.svelte.d.ts +8 -0
- package/dist/molecules/RadioGroup.svelte +197 -0
- package/dist/molecules/RadioGroup.svelte.d.ts +20 -0
- package/dist/molecules/Section.svelte +14 -23
- package/dist/molecules/Section.svelte.d.ts +2 -11
- package/dist/molecules/SidebarBrandHeader.svelte +68 -0
- package/dist/molecules/SidebarBrandHeader.svelte.d.ts +10 -0
- package/dist/molecules/SidebarFooter.svelte +119 -0
- package/dist/molecules/SidebarFooter.svelte.d.ts +23 -0
- package/dist/molecules/SidebarNavSection.svelte +49 -0
- package/dist/molecules/SidebarNavSection.svelte.d.ts +14 -0
- package/dist/molecules/SlideUp.svelte +21 -16
- package/dist/molecules/SlideUp.svelte.d.ts +1 -1
- package/dist/molecules/Tabs.svelte +6 -11
- package/dist/molecules/Toaster.svelte +21 -0
- package/dist/molecules/Toaster.svelte.d.ts +6 -0
- package/dist/molecules/ToasterToast.svelte +217 -0
- package/dist/molecules/ToasterToast.svelte.d.ts +7 -0
- package/dist/molecules/index.d.ts +10 -0
- package/dist/molecules/index.js +10 -0
- package/dist/molecules/navigation-menu-context.d.ts +11 -0
- package/dist/molecules/navigation-menu-context.js +18 -0
- package/dist/molecules/toast-store.d.ts +38 -0
- package/dist/molecules/toast-store.js +34 -0
- package/dist/organisms/SidebarAccountPanel.svelte +118 -0
- package/dist/organisms/SidebarAccountPanel.svelte.d.ts +20 -0
- package/dist/organisms/SidebarNavigation.svelte +286 -212
- package/dist/organisms/SidebarNavigation.svelte.d.ts +22 -1
- package/dist/organisms/{SidebarProjectPanel.svelte → SidebarPanel.svelte} +67 -34
- package/dist/organisms/{SidebarProjectPanel.svelte.d.ts → SidebarPanel.svelte.d.ts} +9 -6
- package/dist/organisms/TopNavbar.svelte +214 -0
- package/dist/organisms/TopNavbar.svelte.d.ts +35 -0
- package/dist/organisms/index.d.ts +3 -3
- package/dist/organisms/index.js +3 -3
- package/dist/routes/lib/focus-utils.d.ts +7 -18
- package/dist/routes/lib/focus-utils.ts +32 -34
- package/dist/routes/lib/ssr-safe.ts +5 -4
- package/dist/routes/lib/variant-utils.ts +48 -39
- package/dist/types/components.d.ts +187 -0
- package/dist/types/components.d.ts.map +1 -0
- package/dist/types/events.d.ts +200 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/index.d.ts +171 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/page.types.d.ts +3 -0
- package/dist/types/page.types.d.ts.map +1 -0
- package/dist/types/page.types.js +1 -0
- package/dist/types/page.types.ts +79 -0
- package/dist/types/variants.d.ts +3 -0
- package/dist/types/variants.d.ts.map +1 -0
- package/dist/types/variants.js +1 -0
- package/dist/types/variants.ts +75 -0
- package/dist/util/fixed-sidebar-flyout.d.ts +22 -0
- package/dist/util/fixed-sidebar-flyout.js +148 -0
- package/dist/util/focus-utils.d.ts +11 -0
- package/dist/util/focus-utils.js +94 -0
- package/dist/util/ssr-safe.d.ts +16 -0
- package/dist/util/ssr-safe.js +48 -0
- package/dist/zabi-components-colors.css +360 -324
- package/dist/zabi-components-theme-dark-only.css +164 -151
- package/dist/zabi-components-theme-dark.css +164 -151
- package/dist/zabi-components-theme-only.css +253 -230
- package/dist/zabi-components-theme.css +253 -230
- package/dist/zabi-components.css +1262 -241
- package/docs/theme-imports.md +112 -0
- package/package.json +32 -10
- package/dist/organisms/Navbar.svelte +0 -92
- package/dist/organisms/Navbar.svelte.d.ts +0 -14
- package/dist/organisms/Navigation.svelte +0 -119
- package/dist/organisms/Navigation.svelte.d.ts +0 -21
package/dist/atoms/Input.svelte
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { CheckCircle, AlertTriangle, AlertCircle } from "@lucide/svelte";
|
|
3
|
-
import type { SemanticVariant, SizeVariant } from "
|
|
4
|
-
import { generateId } from "
|
|
3
|
+
import type { SemanticVariant, SizeVariant } from "../types/variants.js";
|
|
4
|
+
import { generateId } from "../util/ssr-safe.js";
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
|
+
/** Omit to auto-generate; pair with FormField `id` when used inside FormField. */
|
|
8
|
+
id?: string;
|
|
7
9
|
value?: string;
|
|
8
10
|
type?: string;
|
|
9
11
|
name?: string;
|
|
10
12
|
class?: string;
|
|
11
13
|
label?: string;
|
|
14
|
+
/** True when FormField supplies the visible `<label>`. */
|
|
15
|
+
hideLabel?: boolean;
|
|
12
16
|
placeholder?: string;
|
|
13
17
|
required?: boolean;
|
|
14
18
|
disabled?: boolean;
|
|
19
|
+
loading?: boolean;
|
|
15
20
|
size?: SizeVariant;
|
|
16
21
|
variant?: SemanticVariant;
|
|
17
22
|
message?: string;
|
|
@@ -21,14 +26,17 @@
|
|
|
21
26
|
}
|
|
22
27
|
|
|
23
28
|
let {
|
|
29
|
+
id: idProp,
|
|
24
30
|
value = $bindable(""),
|
|
25
31
|
type = "text",
|
|
26
32
|
name = "",
|
|
27
33
|
class: className = "",
|
|
28
34
|
label = "",
|
|
35
|
+
hideLabel = false,
|
|
29
36
|
placeholder = "",
|
|
30
37
|
required = false,
|
|
31
38
|
disabled = false,
|
|
39
|
+
loading = false,
|
|
32
40
|
size = "md",
|
|
33
41
|
variant = "default",
|
|
34
42
|
message = "",
|
|
@@ -37,7 +45,9 @@
|
|
|
37
45
|
...restProps
|
|
38
46
|
}: Props = $props();
|
|
39
47
|
|
|
40
|
-
const
|
|
48
|
+
const fallbackId = generateId("input");
|
|
49
|
+
const inputId = $derived(idProp ?? fallbackId);
|
|
50
|
+
const isDisabled = $derived(disabled || loading);
|
|
41
51
|
|
|
42
52
|
const sizeClass = $derived(() => {
|
|
43
53
|
if (size === "sm") {
|
|
@@ -45,38 +55,46 @@
|
|
|
45
55
|
padding: "px-4 py-2",
|
|
46
56
|
text: "text-sm",
|
|
47
57
|
leading: "leading-5",
|
|
58
|
+
spinner: "size-4",
|
|
48
59
|
};
|
|
49
60
|
} else if (size === "lg") {
|
|
50
61
|
return {
|
|
51
62
|
padding: "px-4 py-3",
|
|
52
63
|
text: "text-base",
|
|
53
64
|
leading: "leading-6",
|
|
65
|
+
spinner: "size-5",
|
|
54
66
|
};
|
|
55
67
|
} else {
|
|
56
68
|
return {
|
|
57
69
|
padding: "px-4 py-2.5",
|
|
58
70
|
text: "text-base",
|
|
59
71
|
leading: "leading-6",
|
|
72
|
+
spinner: "size-5",
|
|
60
73
|
};
|
|
61
74
|
}
|
|
62
75
|
});
|
|
63
76
|
|
|
64
77
|
const variantClass = $derived(() => {
|
|
65
78
|
return variant === "success"
|
|
66
|
-
? "border-success focus:border-success
|
|
79
|
+
? "border-success focus-visible:border-success"
|
|
67
80
|
: variant === "warning"
|
|
68
|
-
? "border-warning focus:border-warning
|
|
81
|
+
? "border-warning focus-visible:border-warning"
|
|
69
82
|
: variant === "error"
|
|
70
|
-
? "border-error focus:border-error
|
|
71
|
-
: "border-
|
|
83
|
+
? "border-error focus-visible:border-error"
|
|
84
|
+
: "border-input-border focus-visible:border-input-border";
|
|
72
85
|
});
|
|
73
86
|
|
|
74
87
|
const inputClasses = $derived(() => {
|
|
75
88
|
const sizeStyles = sizeClass();
|
|
89
|
+
const trailingPad = loading
|
|
90
|
+
? size === "sm"
|
|
91
|
+
? "pr-9"
|
|
92
|
+
: "pr-10"
|
|
93
|
+
: "";
|
|
76
94
|
const baseClasses =
|
|
77
|
-
"w-full min-w-48 bg-input hover:bg-input-hover focus:bg-input-focus disabled:bg-input-disabled rounded-lg transition-all duration-200 placeholder:text-description text-body focus:outline-none focus:
|
|
95
|
+
"focus-ring w-full min-w-48 border bg-input hover:bg-input-hover focus-visible:bg-input-focus disabled:bg-input-disabled rounded-lg transition-all duration-200 placeholder:text-description text-body focus:outline-none focus-visible:outline-none disabled:opacity-50 disabled:cursor-not-allowed";
|
|
78
96
|
|
|
79
|
-
return `${baseClasses} ${sizeStyles.padding} ${sizeStyles.text} ${sizeStyles.leading} ${variantClass()} ${className}`.trim();
|
|
97
|
+
return `${baseClasses} ${sizeStyles.padding} ${trailingPad} ${sizeStyles.text} ${sizeStyles.leading} ${variantClass()} ${className}`.trim();
|
|
80
98
|
});
|
|
81
99
|
|
|
82
100
|
const labelClasses = $derived(
|
|
@@ -109,25 +127,39 @@
|
|
|
109
127
|
</script>
|
|
110
128
|
|
|
111
129
|
<div>
|
|
112
|
-
{#if label}
|
|
130
|
+
{#if label && !hideLabel}
|
|
113
131
|
<label for={inputId} class={labelClasses()}>{label}</label>
|
|
114
132
|
{/if}
|
|
115
|
-
<
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
133
|
+
<div class="relative">
|
|
134
|
+
<input
|
|
135
|
+
id={inputId}
|
|
136
|
+
{type}
|
|
137
|
+
{name}
|
|
138
|
+
bind:value
|
|
139
|
+
{placeholder}
|
|
140
|
+
{required}
|
|
141
|
+
disabled={isDisabled}
|
|
142
|
+
class={inputClasses()}
|
|
143
|
+
oninput={handleInput}
|
|
144
|
+
{onblur}
|
|
145
|
+
aria-invalid={variant === "error" ? "true" : undefined}
|
|
146
|
+
aria-required={required ? "true" : undefined}
|
|
147
|
+
aria-busy={loading ? "true" : undefined}
|
|
148
|
+
aria-describedby={message ? `${inputId}-message` : undefined}
|
|
149
|
+
{...restProps}
|
|
150
|
+
/>
|
|
151
|
+
{#if loading}
|
|
152
|
+
<span
|
|
153
|
+
class="pointer-events-none absolute inset-y-0 right-3 flex items-center text-description"
|
|
154
|
+
aria-hidden="true"
|
|
155
|
+
>
|
|
156
|
+
<span
|
|
157
|
+
class="inline-block {sizeClass()
|
|
158
|
+
.spinner} shrink-0 animate-spin rounded-full border-2 border-current border-t-transparent opacity-70"
|
|
159
|
+
></span>
|
|
160
|
+
</span>
|
|
161
|
+
{/if}
|
|
162
|
+
</div>
|
|
131
163
|
{#if message && variant !== "default"}
|
|
132
164
|
<p
|
|
133
165
|
id={`${inputId}-message`}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import type { SemanticVariant, SizeVariant } from "
|
|
1
|
+
import type { SemanticVariant, SizeVariant } from "../types/variants.js";
|
|
2
2
|
interface Props {
|
|
3
|
+
/** Omit to auto-generate; pair with FormField `id` when used inside FormField. */
|
|
4
|
+
id?: string;
|
|
3
5
|
value?: string;
|
|
4
6
|
type?: string;
|
|
5
7
|
name?: string;
|
|
6
8
|
class?: string;
|
|
7
9
|
label?: string;
|
|
10
|
+
/** True when FormField supplies the visible `<label>`. */
|
|
11
|
+
hideLabel?: boolean;
|
|
8
12
|
placeholder?: string;
|
|
9
13
|
required?: boolean;
|
|
10
14
|
disabled?: boolean;
|
|
15
|
+
loading?: boolean;
|
|
11
16
|
size?: SizeVariant;
|
|
12
17
|
variant?: SemanticVariant;
|
|
13
18
|
message?: string;
|
package/dist/atoms/List.svelte
CHANGED
|
@@ -4,17 +4,12 @@
|
|
|
4
4
|
export type ListItem = ListItemData;
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
7
|
-
/** Collection of items rendered in the list. */
|
|
8
7
|
items: ListItemData[];
|
|
9
|
-
/**
|
|
8
|
+
/** `aria-label` on the list region. */
|
|
10
9
|
ariaLabel?: string;
|
|
11
|
-
/** Optional active item id for current state styling. */
|
|
12
10
|
selectedId?: string;
|
|
13
|
-
/** Whether to show the arrow icon for each row. */
|
|
14
11
|
showArrow?: boolean;
|
|
15
|
-
/** Optional custom class names for the list container. */
|
|
16
12
|
className?: string;
|
|
17
|
-
/** Item click callback. */
|
|
18
13
|
onclick?: (item: ListItem, event: MouseEvent) => void;
|
|
19
14
|
}
|
|
20
15
|
|
|
@@ -29,7 +24,7 @@
|
|
|
29
24
|
}: Props = $props();
|
|
30
25
|
|
|
31
26
|
const listClasses = $derived(
|
|
32
|
-
`space-y-1 overflow-hidden rounded-xl
|
|
27
|
+
`space-y-1 overflow-hidden rounded-xl ${className}`.trim(),
|
|
33
28
|
);
|
|
34
29
|
</script>
|
|
35
30
|
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { type ListItemData } from "./ListItem.svelte";
|
|
2
2
|
export type ListItem = ListItemData;
|
|
3
3
|
interface Props {
|
|
4
|
-
/** Collection of items rendered in the list. */
|
|
5
4
|
items: ListItemData[];
|
|
6
|
-
/**
|
|
5
|
+
/** `aria-label` on the list region. */
|
|
7
6
|
ariaLabel?: string;
|
|
8
|
-
/** Optional active item id for current state styling. */
|
|
9
7
|
selectedId?: string;
|
|
10
|
-
/** Whether to show the arrow icon for each row. */
|
|
11
8
|
showArrow?: boolean;
|
|
12
|
-
/** Optional custom class names for the list container. */
|
|
13
9
|
className?: string;
|
|
14
|
-
/** Item click callback. */
|
|
15
10
|
onclick?: (item: ListItem, event: MouseEvent) => void;
|
|
16
11
|
}
|
|
17
12
|
declare const List: import("svelte").Component<Props, {}, "">;
|
|
@@ -1,34 +1,29 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { ArrowRight } from "@lucide/svelte";
|
|
3
|
-
import type { Component } from "svelte";
|
|
3
|
+
import type { Component, Snippet } from "svelte";
|
|
4
|
+
import ListItemLeading from "./ListItemLeading.svelte";
|
|
4
5
|
|
|
5
6
|
export interface ListItemData {
|
|
6
|
-
/** Unique identifier for stable rendering and active-state tracking. */
|
|
7
7
|
id: string;
|
|
8
|
-
/** Primary item label. */
|
|
9
8
|
label: string;
|
|
10
|
-
/** Optional secondary text shown under the label. */
|
|
11
9
|
description?: string;
|
|
12
|
-
/** Optional URL; when set, the item renders as an anchor. */
|
|
13
10
|
href?: string;
|
|
14
|
-
/** Optional leading icon rendered before text. */
|
|
15
11
|
icon?: Component<{ size?: number; class?: string }>;
|
|
16
|
-
/**
|
|
12
|
+
/** Leading image; wins over `icon` when both are set. */
|
|
13
|
+
avatar?: string;
|
|
14
|
+
/** `avatar` alt text; `""` if decorative. */
|
|
15
|
+
avatarAlt?: string;
|
|
17
16
|
target?: "_self" | "_blank" | "_parent" | "_top";
|
|
18
|
-
/** Link rel attribute, only used when href is provided. */
|
|
19
17
|
rel?: string;
|
|
20
|
-
/** Disabled state for the item. */
|
|
21
18
|
disabled?: boolean;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
interface Props {
|
|
25
|
-
/** Item data to render. */
|
|
26
22
|
item: ListItemData;
|
|
27
|
-
/** Active-state styling flag. */
|
|
28
23
|
selected?: boolean;
|
|
29
|
-
/** Whether to show the right-arrow icon. */
|
|
30
24
|
showArrow?: boolean;
|
|
31
|
-
/**
|
|
25
|
+
/** Shown before the chevron when `showArrow` is true. */
|
|
26
|
+
trailing?: Snippet;
|
|
32
27
|
onclick?: (item: ListItemData, event: MouseEvent) => void;
|
|
33
28
|
}
|
|
34
29
|
|
|
@@ -36,16 +31,17 @@
|
|
|
36
31
|
item,
|
|
37
32
|
selected = false,
|
|
38
33
|
showArrow = true,
|
|
34
|
+
trailing,
|
|
39
35
|
onclick,
|
|
40
36
|
...restProps
|
|
41
37
|
}: Props = $props();
|
|
42
38
|
|
|
43
39
|
const itemClasses = $derived.by(() => {
|
|
44
40
|
const baseClasses =
|
|
45
|
-
"group flex w-full items-center gap-3 rounded-xl border border-border px-4 py-3 text-left transition-all duration-150
|
|
41
|
+
"group focus-ring flex w-full items-center gap-3 rounded-xl border border-border px-4 py-3 pr-5 text-left transition-all duration-150";
|
|
46
42
|
const interactiveClasses = item.disabled
|
|
47
43
|
? "cursor-not-allowed opacity-50"
|
|
48
|
-
: "cursor-pointer
|
|
44
|
+
: "cursor-pointer focus-visible:bg-base-100";
|
|
49
45
|
const selectedClasses = selected
|
|
50
46
|
? "bg-action-primary-subtle border-brand-500"
|
|
51
47
|
: "";
|
|
@@ -73,6 +69,47 @@
|
|
|
73
69
|
};
|
|
74
70
|
</script>
|
|
75
71
|
|
|
72
|
+
{#snippet rowContent()}
|
|
73
|
+
{#if item.avatar}
|
|
74
|
+
<ListItemLeading class="rounded-full">
|
|
75
|
+
<img
|
|
76
|
+
src={item.avatar}
|
|
77
|
+
alt={item.avatarAlt ?? ""}
|
|
78
|
+
class="block size-full min-h-0 min-w-0 object-cover"
|
|
79
|
+
loading="lazy"
|
|
80
|
+
decoding="async"
|
|
81
|
+
/>
|
|
82
|
+
</ListItemLeading>
|
|
83
|
+
{:else if item.icon}
|
|
84
|
+
<ListItemLeading>
|
|
85
|
+
<span aria-hidden="true">
|
|
86
|
+
<item.icon size={16} />
|
|
87
|
+
</span>
|
|
88
|
+
</ListItemLeading>
|
|
89
|
+
{/if}
|
|
90
|
+
<span class="min-w-0 flex-1">
|
|
91
|
+
<span class="block text-sm font-medium text-headline">{item.label}</span
|
|
92
|
+
>
|
|
93
|
+
{#if item.description}
|
|
94
|
+
<span class="mt-0.5 block text-sm text-description"
|
|
95
|
+
>{item.description}</span
|
|
96
|
+
>
|
|
97
|
+
{/if}
|
|
98
|
+
</span>
|
|
99
|
+
{#if trailing}
|
|
100
|
+
<span class="flex shrink-0 items-center gap-2 text-sm text-description">
|
|
101
|
+
{@render trailing()}
|
|
102
|
+
</span>
|
|
103
|
+
{/if}
|
|
104
|
+
{#if showArrow}
|
|
105
|
+
<ArrowRight
|
|
106
|
+
size={16}
|
|
107
|
+
class="shrink-0 text-description transition-transform duration-150 group-hover:translate-x-1 group-focus-visible:translate-x-1"
|
|
108
|
+
aria-hidden="true"
|
|
109
|
+
/>
|
|
110
|
+
{/if}
|
|
111
|
+
{/snippet}
|
|
112
|
+
|
|
76
113
|
{#if item.href}
|
|
77
114
|
<a
|
|
78
115
|
href={item.href}
|
|
@@ -85,31 +122,7 @@
|
|
|
85
122
|
onclick={handleItemClick}
|
|
86
123
|
{...restProps}
|
|
87
124
|
>
|
|
88
|
-
{
|
|
89
|
-
<span
|
|
90
|
-
class="flex size-5 shrink-0 items-center justify-center text-description"
|
|
91
|
-
aria-hidden="true"
|
|
92
|
-
>
|
|
93
|
-
<item.icon size={16} />
|
|
94
|
-
</span>
|
|
95
|
-
{/if}
|
|
96
|
-
<span class="min-w-0 flex-1">
|
|
97
|
-
<span class="block text-sm font-medium text-headline"
|
|
98
|
-
>{item.label}</span
|
|
99
|
-
>
|
|
100
|
-
{#if item.description}
|
|
101
|
-
<span class="mt-0.5 block text-sm text-description"
|
|
102
|
-
>{item.description}</span
|
|
103
|
-
>
|
|
104
|
-
{/if}
|
|
105
|
-
</span>
|
|
106
|
-
{#if showArrow}
|
|
107
|
-
<ArrowRight
|
|
108
|
-
size={16}
|
|
109
|
-
class="shrink-0 text-description transition-transform duration-150 group-hover:translate-x-0.5 group-focus-visible:translate-x-0.5"
|
|
110
|
-
aria-hidden="true"
|
|
111
|
-
/>
|
|
112
|
-
{/if}
|
|
125
|
+
{@render rowContent()}
|
|
113
126
|
</a>
|
|
114
127
|
{:else}
|
|
115
128
|
<button
|
|
@@ -119,30 +132,6 @@
|
|
|
119
132
|
onclick={handleItemClick}
|
|
120
133
|
{...restProps}
|
|
121
134
|
>
|
|
122
|
-
{
|
|
123
|
-
<span
|
|
124
|
-
class="flex size-5 shrink-0 items-center justify-center text-description"
|
|
125
|
-
aria-hidden="true"
|
|
126
|
-
>
|
|
127
|
-
<item.icon size={16} />
|
|
128
|
-
</span>
|
|
129
|
-
{/if}
|
|
130
|
-
<span class="min-w-0 flex-1">
|
|
131
|
-
<span class="block text-sm font-medium text-headline"
|
|
132
|
-
>{item.label}</span
|
|
133
|
-
>
|
|
134
|
-
{#if item.description}
|
|
135
|
-
<span class="mt-0.5 block text-sm text-description"
|
|
136
|
-
>{item.description}</span
|
|
137
|
-
>
|
|
138
|
-
{/if}
|
|
139
|
-
</span>
|
|
140
|
-
{#if showArrow}
|
|
141
|
-
<ArrowRight
|
|
142
|
-
size={16}
|
|
143
|
-
class="shrink-0 text-description transition-transform duration-150 group-hover:translate-x-0.5 group-focus-visible:translate-x-0.5"
|
|
144
|
-
aria-hidden="true"
|
|
145
|
-
/>
|
|
146
|
-
{/if}
|
|
135
|
+
{@render rowContent()}
|
|
147
136
|
</button>
|
|
148
137
|
{/if}
|
|
@@ -1,33 +1,27 @@
|
|
|
1
|
-
import type { Component } from "svelte";
|
|
1
|
+
import type { Component, Snippet } from "svelte";
|
|
2
2
|
export interface ListItemData {
|
|
3
|
-
/** Unique identifier for stable rendering and active-state tracking. */
|
|
4
3
|
id: string;
|
|
5
|
-
/** Primary item label. */
|
|
6
4
|
label: string;
|
|
7
|
-
/** Optional secondary text shown under the label. */
|
|
8
5
|
description?: string;
|
|
9
|
-
/** Optional URL; when set, the item renders as an anchor. */
|
|
10
6
|
href?: string;
|
|
11
|
-
/** Optional leading icon rendered before text. */
|
|
12
7
|
icon?: Component<{
|
|
13
8
|
size?: number;
|
|
14
9
|
class?: string;
|
|
15
10
|
}>;
|
|
16
|
-
/**
|
|
11
|
+
/** Leading image; wins over `icon` when both are set. */
|
|
12
|
+
avatar?: string;
|
|
13
|
+
/** `avatar` alt text; `""` if decorative. */
|
|
14
|
+
avatarAlt?: string;
|
|
17
15
|
target?: "_self" | "_blank" | "_parent" | "_top";
|
|
18
|
-
/** Link rel attribute, only used when href is provided. */
|
|
19
16
|
rel?: string;
|
|
20
|
-
/** Disabled state for the item. */
|
|
21
17
|
disabled?: boolean;
|
|
22
18
|
}
|
|
23
19
|
interface Props {
|
|
24
|
-
/** Item data to render. */
|
|
25
20
|
item: ListItemData;
|
|
26
|
-
/** Active-state styling flag. */
|
|
27
21
|
selected?: boolean;
|
|
28
|
-
/** Whether to show the right-arrow icon. */
|
|
29
22
|
showArrow?: boolean;
|
|
30
|
-
/**
|
|
23
|
+
/** Shown before the chevron when `showArrow` is true. */
|
|
24
|
+
trailing?: Snippet;
|
|
31
25
|
onclick?: (item: ListItemData, event: MouseEvent) => void;
|
|
32
26
|
}
|
|
33
27
|
declare const ListItem: Component<Props, {}, "">;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
/** e.g. `rounded-full` for avatars; default is `rounded-md` for icons. */
|
|
6
|
+
class?: string;
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let { class: className = "", children }: Props = $props();
|
|
11
|
+
|
|
12
|
+
const roundingClass = $derived(className.trim() ? className.trim() : "rounded-md");
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<span
|
|
16
|
+
class="flex size-[length:var(--spacing-xl)] shrink-0 select-none items-center justify-center overflow-hidden text-description {roundingClass}"
|
|
17
|
+
>
|
|
18
|
+
{@render children?.()}
|
|
19
|
+
</span>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
interface Props {
|
|
3
|
+
/** e.g. `rounded-full` for avatars; default is `rounded-md` for icons. */
|
|
4
|
+
class?: string;
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
}
|
|
7
|
+
declare const ListItemLeading: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type ListItemLeading = ReturnType<typeof ListItemLeading>;
|
|
9
|
+
export default ListItemLeading;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { generateId } from "
|
|
2
|
+
import { generateId } from "../util/ssr-safe.js";
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
5
|
value?: number;
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
|
|
40
40
|
<div
|
|
41
41
|
id={progressId}
|
|
42
|
-
class="w-full bg-input rounded-full overflow-hidden {sizeClasses[size]}"
|
|
42
|
+
class="w-full border border-input-border bg-input rounded-full overflow-hidden {sizeClasses[size]}"
|
|
43
43
|
role="progressbar"
|
|
44
44
|
aria-valuenow={value}
|
|
45
45
|
aria-valuemin="0"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import SelectionControl from "./SelectionControl.svelte";
|
|
3
|
+
import type { SelectionControlMarkProps } from "./SelectionControl.svelte";
|
|
4
|
+
import { RADIO_CHECKED_DOT_CLASSES } from "./selection-control.styles";
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
id?: string;
|
|
8
|
+
name?: string;
|
|
9
|
+
value?: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
defaultChecked?: boolean;
|
|
13
|
+
checked?: boolean;
|
|
14
|
+
onChange?: (event: Event) => void;
|
|
15
|
+
onchange?: (event: Event) => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
id,
|
|
20
|
+
name = "",
|
|
21
|
+
value = "",
|
|
22
|
+
label = "",
|
|
23
|
+
disabled = false,
|
|
24
|
+
defaultChecked = false,
|
|
25
|
+
checked = $bindable(defaultChecked),
|
|
26
|
+
onChange,
|
|
27
|
+
onchange,
|
|
28
|
+
...restProps
|
|
29
|
+
}: Props = $props();
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
{#snippet mark(_props: SelectionControlMarkProps)}
|
|
33
|
+
<span class={RADIO_CHECKED_DOT_CLASSES} aria-hidden="true"></span>
|
|
34
|
+
{/snippet}
|
|
35
|
+
|
|
36
|
+
<SelectionControl
|
|
37
|
+
type="radio"
|
|
38
|
+
shape="circle"
|
|
39
|
+
{id}
|
|
40
|
+
{name}
|
|
41
|
+
{value}
|
|
42
|
+
{label}
|
|
43
|
+
{disabled}
|
|
44
|
+
bind:checked
|
|
45
|
+
{defaultChecked}
|
|
46
|
+
{onChange}
|
|
47
|
+
{onchange}
|
|
48
|
+
{mark}
|
|
49
|
+
{...restProps}
|
|
50
|
+
/>
|
|
51
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
id?: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
value?: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
defaultChecked?: boolean;
|
|
8
|
+
checked?: boolean;
|
|
9
|
+
onChange?: (event: Event) => void;
|
|
10
|
+
onchange?: (event: Event) => void;
|
|
11
|
+
}
|
|
12
|
+
declare const Radio: import("svelte").Component<Props, {}, "checked">;
|
|
13
|
+
type Radio = ReturnType<typeof Radio>;
|
|
14
|
+
export default Radio;
|