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/Select.svelte
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Dropdown from "../molecules/Dropdown.svelte";
|
|
3
|
-
import
|
|
3
|
+
import Input from "./Input.svelte";
|
|
4
4
|
import {
|
|
5
5
|
ChevronDown,
|
|
6
6
|
CheckCircle,
|
|
7
7
|
AlertTriangle,
|
|
8
8
|
AlertCircle,
|
|
9
9
|
} from "@lucide/svelte";
|
|
10
|
-
import { generateId } from "
|
|
10
|
+
import { generateId } from "../util/ssr-safe.js";
|
|
11
11
|
|
|
12
12
|
interface Props {
|
|
13
13
|
value?: string | number | undefined;
|
|
@@ -16,25 +16,15 @@
|
|
|
16
16
|
label: string;
|
|
17
17
|
disabled?: boolean;
|
|
18
18
|
}>;
|
|
19
|
-
/** Enables the search input inside the dropdown. */
|
|
20
19
|
searchable?: boolean;
|
|
21
|
-
/** Placeholder for the search input. */
|
|
22
20
|
searchPlaceholder?: string;
|
|
23
|
-
/** Max height for the options list (supports any valid CSS length). */
|
|
24
21
|
maxMenuHeight?: string;
|
|
25
|
-
/** Width for the dropdown menu (supports any valid CSS length). */
|
|
26
22
|
menuWidth?: string;
|
|
27
|
-
/** Message shown when no options match the search. */
|
|
28
23
|
noResultsText?: string;
|
|
29
|
-
/** Shows a loading state while options are being fetched. */
|
|
30
24
|
isLoading?: boolean;
|
|
31
|
-
/** Loading text shown in trigger and dropdown body. */
|
|
32
25
|
loadingText?: string;
|
|
33
|
-
/** Empty state title shown when there are no available options. */
|
|
34
26
|
emptyStateTitle?: string;
|
|
35
|
-
/** Empty state description shown when there are no available options. */
|
|
36
27
|
emptyStateDescription?: string;
|
|
37
|
-
/** Optional empty state action label. */
|
|
38
28
|
emptyStateActionLabel?: string;
|
|
39
29
|
placeholder?: string;
|
|
40
30
|
label?: string;
|
|
@@ -100,18 +90,18 @@
|
|
|
100
90
|
|
|
101
91
|
const variantClass = $derived(() => {
|
|
102
92
|
return variant === "success"
|
|
103
|
-
? "border-success focus:border-success
|
|
93
|
+
? "border-success focus-visible:border-success"
|
|
104
94
|
: variant === "warning"
|
|
105
|
-
? "border-warning focus:border-warning
|
|
95
|
+
? "border-warning focus-visible:border-warning"
|
|
106
96
|
: variant === "error"
|
|
107
|
-
? "border-error focus:border-error
|
|
108
|
-
: "border-
|
|
97
|
+
? "border-error focus-visible:border-error"
|
|
98
|
+
: "border-input-border";
|
|
109
99
|
});
|
|
110
100
|
|
|
111
101
|
const triggerClasses = $derived(() => {
|
|
112
102
|
const sizeStyles = sizeClass();
|
|
113
103
|
const baseClasses =
|
|
114
|
-
"w-full bg-input hover:bg-input-hover
|
|
104
|
+
"focus-ring flex w-full cursor-pointer items-center justify-between rounded-lg border bg-input text-body transition-all duration-200 hover:bg-input-hover active:bg-input-focus focus-visible:bg-input-focus focus:outline-none focus-visible:outline-none disabled:cursor-not-allowed disabled:bg-input-disabled disabled:opacity-50";
|
|
115
105
|
|
|
116
106
|
return `${baseClasses} ${sizeStyles.padding} ${sizeStyles.text} ${sizeStyles.leading} ${variantClass()}`.trim();
|
|
117
107
|
});
|
|
@@ -208,7 +198,6 @@
|
|
|
208
198
|
const target = event.target as HTMLElement;
|
|
209
199
|
const clickedSelectContainer = target.closest(".select-container");
|
|
210
200
|
|
|
211
|
-
// Close if clicking outside any select container, or clicking on a different select
|
|
212
201
|
if (
|
|
213
202
|
!clickedSelectContainer ||
|
|
214
203
|
clickedSelectContainer !== selectContainer
|
|
@@ -232,21 +221,21 @@
|
|
|
232
221
|
{/if}
|
|
233
222
|
|
|
234
223
|
<Dropdown
|
|
235
|
-
{isOpen}
|
|
224
|
+
bind:isOpen={isOpen}
|
|
236
225
|
placement="bottom-start"
|
|
237
226
|
selectedValue={value}
|
|
238
227
|
onOptionClick={handleOptionClick}
|
|
239
228
|
ariaLabel="Select options"
|
|
229
|
+
menuRole="listbox"
|
|
240
230
|
>
|
|
241
|
-
{#snippet trigger()}
|
|
231
|
+
{#snippet trigger(aria)}
|
|
242
232
|
<button
|
|
243
233
|
type="button"
|
|
244
234
|
id={selectId}
|
|
245
235
|
class={triggerClasses()}
|
|
246
236
|
{disabled}
|
|
247
237
|
onclick={handleTriggerClick}
|
|
248
|
-
aria
|
|
249
|
-
aria-expanded={isOpen}
|
|
238
|
+
{...aria}
|
|
250
239
|
aria-describedby={message ? `${selectId}-message` : undefined}
|
|
251
240
|
>
|
|
252
241
|
<span
|
|
@@ -277,9 +266,10 @@
|
|
|
277
266
|
<div class="px-2 pb-2 pt-1" style:width={menuWidth}>
|
|
278
267
|
{#if searchable && !isLoading}
|
|
279
268
|
<div class="px-1 pb-2">
|
|
280
|
-
<
|
|
269
|
+
<Input
|
|
281
270
|
type="text"
|
|
282
|
-
|
|
271
|
+
size="sm"
|
|
272
|
+
class="min-w-0"
|
|
283
273
|
placeholder={searchPlaceholder}
|
|
284
274
|
bind:value={searchQuery}
|
|
285
275
|
aria-label={searchPlaceholder}
|
|
@@ -303,18 +293,23 @@
|
|
|
303
293
|
"data-value": String(option.value),
|
|
304
294
|
} as Record<string, string>}
|
|
305
295
|
<div class="w-full my-0.5">
|
|
306
|
-
<
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
296
|
+
<button
|
|
297
|
+
type="button"
|
|
298
|
+
role="option"
|
|
299
|
+
aria-selected={value === option.value
|
|
300
|
+
? true
|
|
301
|
+
: undefined}
|
|
302
|
+
class="focus-ring flex w-full items-center justify-start rounded-md border-2 px-3 py-2 text-left text-sm font-medium transition-colors focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 {value ===
|
|
303
|
+
option.value
|
|
304
|
+
? 'border-action-primary bg-transparent text-headline'
|
|
305
|
+
: 'border-transparent bg-transparent text-body hover:bg-base-100'}"
|
|
312
306
|
disabled={option.disabled}
|
|
313
|
-
onclick={() => handleOptionClick(option.value)}
|
|
314
307
|
{...buttonRestProps}
|
|
308
|
+
onclick={() =>
|
|
309
|
+
handleOptionClick(option.value)}
|
|
315
310
|
>
|
|
316
311
|
{option.label}
|
|
317
|
-
</
|
|
312
|
+
</button>
|
|
318
313
|
</div>
|
|
319
314
|
{/each}
|
|
320
315
|
{:else if hasSearchQuery()}
|
|
@@ -328,7 +323,7 @@
|
|
|
328
323
|
{#if emptyStateActionLabel && onEmptyStateAction}
|
|
329
324
|
<button
|
|
330
325
|
type="button"
|
|
331
|
-
class="mt-3 inline-flex min-h-11 items-center rounded-lg bg-action-primary px-3 py-2 text-sm text-action-primary"
|
|
326
|
+
class="mt-3 inline-flex min-h-11 cursor-pointer items-center rounded-lg bg-action-primary px-3 py-2 text-sm text-action-primary"
|
|
332
327
|
onclick={onEmptyStateAction}
|
|
333
328
|
>
|
|
334
329
|
{emptyStateActionLabel}
|
|
@@ -5,25 +5,15 @@ interface Props {
|
|
|
5
5
|
label: string;
|
|
6
6
|
disabled?: boolean;
|
|
7
7
|
}>;
|
|
8
|
-
/** Enables the search input inside the dropdown. */
|
|
9
8
|
searchable?: boolean;
|
|
10
|
-
/** Placeholder for the search input. */
|
|
11
9
|
searchPlaceholder?: string;
|
|
12
|
-
/** Max height for the options list (supports any valid CSS length). */
|
|
13
10
|
maxMenuHeight?: string;
|
|
14
|
-
/** Width for the dropdown menu (supports any valid CSS length). */
|
|
15
11
|
menuWidth?: string;
|
|
16
|
-
/** Message shown when no options match the search. */
|
|
17
12
|
noResultsText?: string;
|
|
18
|
-
/** Shows a loading state while options are being fetched. */
|
|
19
13
|
isLoading?: boolean;
|
|
20
|
-
/** Loading text shown in trigger and dropdown body. */
|
|
21
14
|
loadingText?: string;
|
|
22
|
-
/** Empty state title shown when there are no available options. */
|
|
23
15
|
emptyStateTitle?: string;
|
|
24
|
-
/** Empty state description shown when there are no available options. */
|
|
25
16
|
emptyStateDescription?: string;
|
|
26
|
-
/** Optional empty state action label. */
|
|
27
17
|
emptyStateActionLabel?: string;
|
|
28
18
|
placeholder?: string;
|
|
29
19
|
label?: string;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from "svelte";
|
|
3
|
+
import { generateId } from "../util/ssr-safe.js";
|
|
4
|
+
import {
|
|
5
|
+
SELECTION_CONTROL_LABEL_ROW,
|
|
6
|
+
selectionControlRingOverlayClasses,
|
|
7
|
+
selectionControlShellClasses,
|
|
8
|
+
type SelectionControlShape,
|
|
9
|
+
} from "./selection-control.styles";
|
|
10
|
+
|
|
11
|
+
type SelectionControlType = "checkbox" | "radio";
|
|
12
|
+
|
|
13
|
+
export type SelectionControlMarkProps = {
|
|
14
|
+
checked: boolean;
|
|
15
|
+
loading: boolean;
|
|
16
|
+
disabled: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface Props {
|
|
20
|
+
id?: string;
|
|
21
|
+
type: SelectionControlType;
|
|
22
|
+
shape: SelectionControlShape;
|
|
23
|
+
name?: string;
|
|
24
|
+
value?: string;
|
|
25
|
+
label?: string;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
loading?: boolean;
|
|
28
|
+
defaultChecked?: boolean;
|
|
29
|
+
checked?: boolean;
|
|
30
|
+
onChange?: (event: Event) => void;
|
|
31
|
+
onchange?: (event: Event) => void;
|
|
32
|
+
mark?: Snippet<[SelectionControlMarkProps]>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let {
|
|
36
|
+
id: idProp,
|
|
37
|
+
type,
|
|
38
|
+
shape,
|
|
39
|
+
name = "",
|
|
40
|
+
value = "",
|
|
41
|
+
label = "",
|
|
42
|
+
disabled = false,
|
|
43
|
+
loading = false,
|
|
44
|
+
defaultChecked = false,
|
|
45
|
+
checked = $bindable(defaultChecked),
|
|
46
|
+
onChange,
|
|
47
|
+
onchange,
|
|
48
|
+
mark,
|
|
49
|
+
...restProps
|
|
50
|
+
}: Props = $props();
|
|
51
|
+
|
|
52
|
+
/** Call once per mount — `generateId()` in `$derived` would churn ids every tick. */
|
|
53
|
+
const fallbackId = generateId("selection-control");
|
|
54
|
+
const controlId = $derived(idProp ?? fallbackId);
|
|
55
|
+
const isDisabled = $derived(disabled || loading);
|
|
56
|
+
|
|
57
|
+
const labelWrapperClasses = SELECTION_CONTROL_LABEL_ROW;
|
|
58
|
+
|
|
59
|
+
const controlContainerClasses = $derived(selectionControlShellClasses(shape));
|
|
60
|
+
|
|
61
|
+
const controlRingClasses = $derived(selectionControlRingOverlayClasses(shape));
|
|
62
|
+
|
|
63
|
+
function handleChange(event: Event) {
|
|
64
|
+
if (isDisabled) return;
|
|
65
|
+
const target = event.target as HTMLInputElement;
|
|
66
|
+
checked = target.checked;
|
|
67
|
+
onChange?.(event);
|
|
68
|
+
onchange?.(event);
|
|
69
|
+
}
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<div class="flex items-center gap-2">
|
|
73
|
+
<label for={controlId} class={labelWrapperClasses}>
|
|
74
|
+
<span class={controlContainerClasses}>
|
|
75
|
+
<input
|
|
76
|
+
{type}
|
|
77
|
+
id={controlId}
|
|
78
|
+
{name}
|
|
79
|
+
{value}
|
|
80
|
+
{checked}
|
|
81
|
+
disabled={isDisabled}
|
|
82
|
+
class="sr-only"
|
|
83
|
+
aria-busy={loading ? "true" : undefined}
|
|
84
|
+
onchange={handleChange}
|
|
85
|
+
{...restProps}
|
|
86
|
+
/>
|
|
87
|
+
<span class={controlRingClasses}></span>
|
|
88
|
+
{#if mark}
|
|
89
|
+
{@render mark({ checked, loading, disabled: isDisabled })}
|
|
90
|
+
{/if}
|
|
91
|
+
</span>
|
|
92
|
+
{#if label}
|
|
93
|
+
<span class="text-sm font-medium text-label">
|
|
94
|
+
{label}
|
|
95
|
+
</span>
|
|
96
|
+
{/if}
|
|
97
|
+
</label>
|
|
98
|
+
</div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Snippet } from "svelte";
|
|
2
|
+
import { type SelectionControlShape } from "./selection-control.styles";
|
|
3
|
+
type SelectionControlType = "checkbox" | "radio";
|
|
4
|
+
export type SelectionControlMarkProps = {
|
|
5
|
+
checked: boolean;
|
|
6
|
+
loading: boolean;
|
|
7
|
+
disabled: boolean;
|
|
8
|
+
};
|
|
9
|
+
interface Props {
|
|
10
|
+
id?: string;
|
|
11
|
+
type: SelectionControlType;
|
|
12
|
+
shape: SelectionControlShape;
|
|
13
|
+
name?: string;
|
|
14
|
+
value?: string;
|
|
15
|
+
label?: string;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
loading?: boolean;
|
|
18
|
+
defaultChecked?: boolean;
|
|
19
|
+
checked?: boolean;
|
|
20
|
+
onChange?: (event: Event) => void;
|
|
21
|
+
onchange?: (event: Event) => void;
|
|
22
|
+
mark?: Snippet<[SelectionControlMarkProps]>;
|
|
23
|
+
}
|
|
24
|
+
declare const SelectionControl: import("svelte").Component<Props, {}, "checked">;
|
|
25
|
+
type SelectionControl = ReturnType<typeof SelectionControl>;
|
|
26
|
+
export default SelectionControl;
|
|
@@ -1,30 +1,54 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
type Variant = "text" | "circle" | "block";
|
|
3
|
+
|
|
2
4
|
interface Props {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
variant?: Variant;
|
|
6
|
+
/** CSS length or px number; omit to use variant default (circle stays square). */
|
|
7
|
+
width?: string | number;
|
|
8
|
+
/** CSS length or px number; omit for variant default height. */
|
|
9
|
+
height?: string | number;
|
|
10
|
+
class?: string;
|
|
6
11
|
"aria-label"?: string;
|
|
7
12
|
}
|
|
8
13
|
|
|
9
14
|
let {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
variant = "text",
|
|
16
|
+
width,
|
|
17
|
+
height,
|
|
18
|
+
class: className = "",
|
|
19
|
+
"aria-label": ariaLabel = "Loading…",
|
|
15
20
|
}: Props = $props();
|
|
16
21
|
|
|
17
|
-
const
|
|
18
|
-
|
|
22
|
+
const radius: Record<Variant, string> = {
|
|
23
|
+
text: "rounded-md",
|
|
24
|
+
circle: "rounded-full",
|
|
25
|
+
block: "rounded-lg",
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const defaultShape: Record<Variant, string> = {
|
|
29
|
+
text: "w-full h-3",
|
|
30
|
+
circle: "w-10 aspect-square",
|
|
31
|
+
block: "w-full h-32",
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function toSize(value: string | number): string {
|
|
35
|
+
return typeof value === "number" ? `${value}px` : value;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const inlineStyle = $derived(
|
|
39
|
+
[
|
|
40
|
+
width !== undefined ? `width: ${toSize(width)}` : null,
|
|
41
|
+
height !== undefined ? `height: ${toSize(height)}` : null,
|
|
42
|
+
]
|
|
43
|
+
.filter(Boolean)
|
|
44
|
+
.join("; "),
|
|
19
45
|
);
|
|
20
|
-
const styles = $derived(`width: ${width}; height: ${height};`);
|
|
21
46
|
</script>
|
|
22
47
|
|
|
23
48
|
<div
|
|
24
|
-
class={
|
|
25
|
-
style={
|
|
49
|
+
class="animate-pulse bg-surface-2 {defaultShape[variant]} {radius[variant]} {className}"
|
|
50
|
+
style={inlineStyle || undefined}
|
|
51
|
+
role="status"
|
|
26
52
|
aria-busy="true"
|
|
27
53
|
aria-label={ariaLabel}
|
|
28
|
-
role="status"
|
|
29
|
-
{...restProps}
|
|
30
54
|
></div>
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
type Variant = "text" | "circle" | "block";
|
|
1
2
|
interface Props {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
variant?: Variant;
|
|
4
|
+
/** CSS length or px number; omit to use variant default (circle stays square). */
|
|
5
|
+
width?: string | number;
|
|
6
|
+
/** CSS length or px number; omit for variant default height. */
|
|
7
|
+
height?: string | number;
|
|
8
|
+
class?: string;
|
|
5
9
|
"aria-label"?: string;
|
|
6
10
|
}
|
|
7
11
|
declare const Skeleton: import("svelte").Component<Props, {}, "">;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
/** Visible `<caption>` when set. */
|
|
6
|
+
caption?: string;
|
|
7
|
+
class?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let { caption, class: className = '', children }: Props = $props();
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<div
|
|
15
|
+
class="overflow-x-auto rounded-lg border border-border shadow-sm {className}"
|
|
16
|
+
>
|
|
17
|
+
<table class="w-full min-w-[20rem] border-collapse text-left text-sm text-body">
|
|
18
|
+
{#if caption}
|
|
19
|
+
<caption class="border-b border-border bg-base-50 px-4 py-3 text-left text-headline">
|
|
20
|
+
{caption}
|
|
21
|
+
</caption>
|
|
22
|
+
{/if}
|
|
23
|
+
{#if children}
|
|
24
|
+
{@render children()}
|
|
25
|
+
{/if}
|
|
26
|
+
</table>
|
|
27
|
+
</div>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Visible `<caption>` when set. */
|
|
4
|
+
caption?: string;
|
|
5
|
+
class?: string;
|
|
6
|
+
children?: Snippet;
|
|
7
|
+
}
|
|
8
|
+
declare const Table: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type Table = ReturnType<typeof Table>;
|
|
10
|
+
export default Table;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
type Tone = 'body' | 'description' | 'caption' | 'headline' | 'label' | 'error';
|
|
5
|
+
type Size = 'sm' | 'md' | 'lg';
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
as?: 'p' | 'span' | 'div';
|
|
9
|
+
tone?: Tone;
|
|
10
|
+
size?: Size;
|
|
11
|
+
class?: string;
|
|
12
|
+
children?: Snippet;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
as: Tag = 'p',
|
|
17
|
+
tone = 'body',
|
|
18
|
+
size = 'md',
|
|
19
|
+
class: className = '',
|
|
20
|
+
children,
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
|
|
23
|
+
const toneClass: Record<Tone, string> = {
|
|
24
|
+
body: 'text-body',
|
|
25
|
+
description: 'text-description',
|
|
26
|
+
caption: 'text-caption',
|
|
27
|
+
headline: 'text-headline',
|
|
28
|
+
label: 'text-label',
|
|
29
|
+
error: 'text-error',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const sizeClass: Record<Size, string> = {
|
|
33
|
+
sm: 'text-sm',
|
|
34
|
+
md: 'text-base',
|
|
35
|
+
lg: 'text-lg',
|
|
36
|
+
};
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<svelte:element
|
|
40
|
+
this={Tag}
|
|
41
|
+
class={[toneClass[tone], sizeClass[size], className].filter(Boolean).join(' ')}
|
|
42
|
+
>
|
|
43
|
+
{#if children}
|
|
44
|
+
{@render children()}
|
|
45
|
+
{/if}
|
|
46
|
+
</svelte:element>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type Tone = 'body' | 'description' | 'caption' | 'headline' | 'label' | 'error';
|
|
3
|
+
type Size = 'sm' | 'md' | 'lg';
|
|
4
|
+
interface Props {
|
|
5
|
+
as?: 'p' | 'span' | 'div';
|
|
6
|
+
tone?: Tone;
|
|
7
|
+
size?: Size;
|
|
8
|
+
class?: string;
|
|
9
|
+
children?: Snippet;
|
|
10
|
+
}
|
|
11
|
+
declare const Text: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type Text = ReturnType<typeof Text>;
|
|
13
|
+
export default Text;
|