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
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Badge from "./Badge.svelte";
|
|
3
|
+
import type { ExtendedSemanticVariant } from "../types/variants.js";
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
title: string;
|
|
7
|
+
description: string;
|
|
8
|
+
href?: string;
|
|
9
|
+
onclick?: (event: MouseEvent) => void | Promise<void>;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
loading?: boolean;
|
|
12
|
+
badgeText?: string;
|
|
13
|
+
badgeVariant?: ExtendedSemanticVariant;
|
|
14
|
+
/** Overrides the default accessible name for the clickable region. */
|
|
15
|
+
ariaLabel?: string;
|
|
16
|
+
className?: string;
|
|
17
|
+
target?: HTMLAnchorElement["target"];
|
|
18
|
+
rel?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let {
|
|
22
|
+
title,
|
|
23
|
+
description,
|
|
24
|
+
href,
|
|
25
|
+
onclick,
|
|
26
|
+
disabled = false,
|
|
27
|
+
loading = false,
|
|
28
|
+
badgeText,
|
|
29
|
+
badgeVariant = "neutral",
|
|
30
|
+
ariaLabel,
|
|
31
|
+
className = "",
|
|
32
|
+
target,
|
|
33
|
+
rel,
|
|
34
|
+
...restProps
|
|
35
|
+
}: Props = $props();
|
|
36
|
+
|
|
37
|
+
const isDisabled = $derived(disabled || loading);
|
|
38
|
+
|
|
39
|
+
const computedAriaLabel = $derived(
|
|
40
|
+
ariaLabel ?? (href ? `Open ${title}` : title),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
const baseClasses =
|
|
44
|
+
"group focus-ring focus-ring--muted block rounded-2xl border border-base-200 bg-base-0 p-6 text-left transition-all duration-200 hover:border-headline/30 hover:bg-base-50 active:scale-[0.99] active:bg-base-100";
|
|
45
|
+
|
|
46
|
+
const disabledClasses =
|
|
47
|
+
"opacity-50 cursor-not-allowed pointer-events-none hover:border-base-200 hover:bg-base-0 active:scale-100";
|
|
48
|
+
|
|
49
|
+
const panelClasses = $derived(
|
|
50
|
+
[baseClasses, isDisabled ? disabledClasses : "", className]
|
|
51
|
+
.filter(Boolean)
|
|
52
|
+
.join(" ")
|
|
53
|
+
.trim(),
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
function handleKeydown(event: KeyboardEvent) {
|
|
57
|
+
if (isDisabled) return;
|
|
58
|
+
if (!href && onclick && (event.key === "Enter" || event.key === " ")) {
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
onclick(event as unknown as MouseEvent);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
{#snippet body()}
|
|
66
|
+
<div class="flex items-start justify-between gap-4">
|
|
67
|
+
<div class="min-w-0">
|
|
68
|
+
<h3
|
|
69
|
+
class="truncate text-lg font-semibold text-headline transition-colors group-hover:text-headline/90"
|
|
70
|
+
>
|
|
71
|
+
{title}
|
|
72
|
+
</h3>
|
|
73
|
+
<p class="mt-3 line-clamp-2 text-description">{description}</p>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="flex shrink-0 items-center gap-3">
|
|
76
|
+
{#if badgeText}
|
|
77
|
+
<Badge variant={badgeVariant} text={badgeText} />
|
|
78
|
+
{/if}
|
|
79
|
+
{#if loading}
|
|
80
|
+
<span
|
|
81
|
+
class="inline-block size-5 shrink-0 animate-spin rounded-full border-2 border-description border-t-transparent opacity-70"
|
|
82
|
+
aria-hidden="true"
|
|
83
|
+
></span>
|
|
84
|
+
{/if}
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
{/snippet}
|
|
88
|
+
|
|
89
|
+
{#if href}
|
|
90
|
+
<a
|
|
91
|
+
class={panelClasses}
|
|
92
|
+
href={isDisabled ? undefined : href}
|
|
93
|
+
aria-label={computedAriaLabel}
|
|
94
|
+
aria-disabled={isDisabled ? "true" : undefined}
|
|
95
|
+
aria-busy={loading ? "true" : undefined}
|
|
96
|
+
tabindex={isDisabled ? -1 : undefined}
|
|
97
|
+
target={target}
|
|
98
|
+
rel={rel}
|
|
99
|
+
{...restProps}
|
|
100
|
+
>
|
|
101
|
+
{@render body()}
|
|
102
|
+
</a>
|
|
103
|
+
{:else}
|
|
104
|
+
<button
|
|
105
|
+
type="button"
|
|
106
|
+
class={panelClasses}
|
|
107
|
+
aria-label={computedAriaLabel}
|
|
108
|
+
aria-busy={loading ? "true" : undefined}
|
|
109
|
+
disabled={isDisabled}
|
|
110
|
+
onclick={onclick}
|
|
111
|
+
onkeydown={handleKeydown}
|
|
112
|
+
{...restProps}
|
|
113
|
+
>
|
|
114
|
+
{@render body()}
|
|
115
|
+
</button>
|
|
116
|
+
{/if}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ExtendedSemanticVariant } from "../types/variants.js";
|
|
2
|
+
interface Props {
|
|
3
|
+
title: string;
|
|
4
|
+
description: string;
|
|
5
|
+
href?: string;
|
|
6
|
+
onclick?: (event: MouseEvent) => void | Promise<void>;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
loading?: boolean;
|
|
9
|
+
badgeText?: string;
|
|
10
|
+
badgeVariant?: ExtendedSemanticVariant;
|
|
11
|
+
/** Overrides the default accessible name for the clickable region. */
|
|
12
|
+
ariaLabel?: string;
|
|
13
|
+
className?: string;
|
|
14
|
+
target?: HTMLAnchorElement["target"];
|
|
15
|
+
rel?: string;
|
|
16
|
+
}
|
|
17
|
+
declare const ActionPanel: import("svelte").Component<Props, {}, "">;
|
|
18
|
+
type ActionPanel = ReturnType<typeof ActionPanel>;
|
|
19
|
+
export default ActionPanel;
|
package/dist/atoms/Badge.svelte
CHANGED
package/dist/atoms/Button.svelte
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
|
-
import type { ButtonVariant, SizeVariant } from "
|
|
3
|
+
import type { ButtonVariant, SizeVariant } from "../types/variants.js";
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
6
6
|
variant?: ButtonVariant;
|
|
7
7
|
size?: SizeVariant;
|
|
8
8
|
disabled?: boolean;
|
|
9
|
+
loading?: boolean;
|
|
9
10
|
type?: "button" | "submit" | "reset";
|
|
10
11
|
text?: string;
|
|
11
12
|
isFullWidth?: boolean;
|
|
13
|
+
class?: string;
|
|
12
14
|
onclick?: (event: MouseEvent) => void;
|
|
13
15
|
children?: Snippet;
|
|
14
16
|
}
|
|
@@ -17,15 +19,19 @@
|
|
|
17
19
|
variant = "primary",
|
|
18
20
|
size = "md",
|
|
19
21
|
disabled = false,
|
|
22
|
+
loading = false,
|
|
20
23
|
type = "button",
|
|
21
24
|
text = "",
|
|
22
25
|
isFullWidth = false,
|
|
26
|
+
class: className = "",
|
|
23
27
|
onclick,
|
|
24
28
|
children,
|
|
25
29
|
...restProps
|
|
26
30
|
}: Props = $props();
|
|
27
31
|
|
|
28
|
-
const
|
|
32
|
+
const isDisabled = $derived(disabled || loading);
|
|
33
|
+
|
|
34
|
+
const sizeClass = $derived.by(() => {
|
|
29
35
|
if (size === "sm") {
|
|
30
36
|
return {
|
|
31
37
|
padding: "px-4 py-2.5",
|
|
@@ -59,33 +65,46 @@
|
|
|
59
65
|
}
|
|
60
66
|
});
|
|
61
67
|
|
|
62
|
-
const variantClass = $derived(() => {
|
|
68
|
+
const variantClass = $derived.by(() => {
|
|
63
69
|
return variant === "primary"
|
|
64
|
-
? "bg-action-primary text-action-primary hover:bg-action-primary-hover active:bg-action-primary-active
|
|
70
|
+
? "bg-action-primary text-action-primary hover:bg-action-primary-hover active:bg-action-primary-active active:scale-[0.98]"
|
|
65
71
|
: variant === "secondary"
|
|
66
|
-
? "bg-action-secondary text-headline hover:bg-action-secondary-hover active:bg-action-secondary-active
|
|
72
|
+
? "bg-action-secondary text-headline hover:bg-action-secondary-hover active:bg-action-secondary-active active:scale-[0.98]"
|
|
67
73
|
: variant === "danger"
|
|
68
|
-
? "bg-action-danger text-inverse hover:bg-action-danger-hover active:bg-action-danger-active
|
|
74
|
+
? "bg-action-danger text-inverse hover:bg-action-danger-hover active:bg-action-danger-active active:scale-[0.98] focus-ring--danger"
|
|
69
75
|
: variant === "ghost"
|
|
70
|
-
? "bg-transparent text-headline hover:bg-base-100 active:bg-base-200
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
? "bg-transparent text-headline hover:bg-base-100 active:bg-base-200 active:scale-[0.98] focus-ring--muted disabled:text-disabled"
|
|
77
|
+
: variant === "outline"
|
|
78
|
+
? "bg-transparent border border-border text-headline hover:bg-action-secondary hover:border-border-medium hover:text-action-primary active:bg-action-primary-active active:text-action-primary active:scale-[0.98] disabled:border-disabled disabled:text-disabled"
|
|
73
79
|
: variant === "link"
|
|
74
|
-
? "text-brand-700 active:text-brand-700 underline-offset-4 hover:underline
|
|
75
|
-
: "bg-action-primary text-action-primary hover:bg-action-primary-hover active:bg-action-primary-active
|
|
80
|
+
? "text-brand-700 active:text-brand-700 underline-offset-4 hover:underline disabled:text-disabled disabled:no-underline"
|
|
81
|
+
: "bg-action-primary text-action-primary hover:bg-action-primary-hover active:bg-action-primary-active active:scale-[0.98]";
|
|
76
82
|
});
|
|
77
83
|
|
|
78
|
-
const buttonClasses = $derived(() => {
|
|
79
|
-
const sizeStyles = sizeClass
|
|
84
|
+
const buttonClasses = $derived.by(() => {
|
|
85
|
+
const sizeStyles = sizeClass;
|
|
80
86
|
const flexClass = isFullWidth ? "flex" : "inline-flex";
|
|
81
87
|
const widthClass = isFullWidth ? "w-full" : "";
|
|
82
|
-
const baseClasses = `${flexClass} items-center justify-center transition-all duration-200 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed
|
|
88
|
+
const baseClasses = `${flexClass} focus-ring items-center justify-center transition-all duration-200 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:active:scale-100`;
|
|
83
89
|
|
|
84
|
-
return `${baseClasses} ${widthClass} ${sizeStyles.padding} ${sizeStyles.text} ${sizeStyles.font} ${sizeStyles.leading} ${sizeStyles.tracking} ${sizeStyles.radius} ${sizeStyles.gap} ${variantClass
|
|
90
|
+
return `${baseClasses} ${widthClass} ${sizeStyles.padding} ${sizeStyles.text} ${sizeStyles.font} ${sizeStyles.leading} ${sizeStyles.tracking} ${sizeStyles.radius} ${sizeStyles.gap} ${variantClass} ${className}`.trim();
|
|
85
91
|
});
|
|
86
92
|
</script>
|
|
87
93
|
|
|
88
|
-
<button
|
|
94
|
+
<button
|
|
95
|
+
{type}
|
|
96
|
+
class={buttonClasses}
|
|
97
|
+
disabled={isDisabled}
|
|
98
|
+
aria-busy={loading ? "true" : undefined}
|
|
99
|
+
{onclick}
|
|
100
|
+
{...restProps}
|
|
101
|
+
>
|
|
102
|
+
{#if loading}
|
|
103
|
+
<span
|
|
104
|
+
class="inline-block size-4 shrink-0 animate-spin rounded-full border-2 border-current border-t-transparent opacity-80"
|
|
105
|
+
aria-hidden="true"
|
|
106
|
+
></span>
|
|
107
|
+
{/if}
|
|
89
108
|
{#if text}
|
|
90
109
|
{text}
|
|
91
110
|
{:else if children}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { Snippet } from "svelte";
|
|
2
|
-
import type { ButtonVariant, SizeVariant } from "
|
|
2
|
+
import type { ButtonVariant, SizeVariant } from "../types/variants.js";
|
|
3
3
|
interface Props {
|
|
4
4
|
variant?: ButtonVariant;
|
|
5
5
|
size?: SizeVariant;
|
|
6
6
|
disabled?: boolean;
|
|
7
|
+
loading?: boolean;
|
|
7
8
|
type?: "button" | "submit" | "reset";
|
|
8
9
|
text?: string;
|
|
9
10
|
isFullWidth?: boolean;
|
|
11
|
+
class?: string;
|
|
10
12
|
onclick?: (event: MouseEvent) => void;
|
|
11
13
|
children?: Snippet;
|
|
12
14
|
}
|
package/dist/atoms/Card.svelte
CHANGED
|
@@ -1,70 +1,73 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
|
-
import type { CardVariant, SizeVariant } from "
|
|
4
|
-
import CardHeader from "./CardHeader.svelte";
|
|
5
|
-
import CardContent from "./CardContent.svelte";
|
|
3
|
+
import type { CardVariant, SizeVariant } from "../types/variants.js";
|
|
6
4
|
|
|
7
5
|
interface Props {
|
|
8
|
-
title?: string;
|
|
9
|
-
description?: string;
|
|
10
|
-
image?: string;
|
|
11
6
|
onclick?: (event: MouseEvent) => void | Promise<void>;
|
|
12
7
|
size?: SizeVariant;
|
|
13
8
|
variant?: CardVariant;
|
|
14
9
|
fullWidth?: boolean;
|
|
10
|
+
className?: string;
|
|
11
|
+
/** Required when `onclick` is set (no visible label). */
|
|
12
|
+
ariaLabel?: string;
|
|
15
13
|
children?: Snippet;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
let {
|
|
19
|
-
title = "",
|
|
20
|
-
description = "",
|
|
21
|
-
image = "",
|
|
22
17
|
onclick,
|
|
23
18
|
size = "md",
|
|
24
19
|
variant = "default",
|
|
25
20
|
fullWidth = true,
|
|
21
|
+
className = "",
|
|
22
|
+
ariaLabel,
|
|
26
23
|
children,
|
|
27
24
|
...restProps
|
|
28
25
|
}: Props = $props();
|
|
29
26
|
|
|
30
|
-
const sizeClass = $derived(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const variantClasses = $derived(() => {
|
|
35
|
-
switch (variant) {
|
|
36
|
-
case "elevated":
|
|
37
|
-
return "bg-card shadow-lg";
|
|
38
|
-
case "outlined":
|
|
39
|
-
return "bg-card border-2 border-base-200 shadow-none";
|
|
40
|
-
case "flat":
|
|
41
|
-
return "bg-card shadow-none border-none";
|
|
42
|
-
default:
|
|
43
|
-
return "bg-card shadow-sm";
|
|
44
|
-
}
|
|
45
|
-
});
|
|
27
|
+
const sizeClass = $derived(
|
|
28
|
+
size === "sm" ? "p-4" : size === "lg" ? "p-8" : "p-6",
|
|
29
|
+
);
|
|
46
30
|
|
|
47
|
-
const
|
|
48
|
-
|
|
31
|
+
const radiusClass = $derived(
|
|
32
|
+
size === "sm"
|
|
33
|
+
? "rounded-xl"
|
|
34
|
+
: size === "lg"
|
|
35
|
+
? "rounded-3xl"
|
|
36
|
+
: "rounded-2xl",
|
|
49
37
|
);
|
|
50
38
|
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
: "cursor-pointer hover:shadow-lg hover:bg-card-hover"
|
|
61
|
-
: "";
|
|
62
|
-
const widthClasses = fullWidth ? "w-full" : "";
|
|
63
|
-
const minWidthClass = useOldAPI ? "min-w-64" : "";
|
|
64
|
-
const paddingClass = useOldAPI ? sizeClass() : "";
|
|
39
|
+
const variantClasses = $derived(
|
|
40
|
+
variant === "elevated"
|
|
41
|
+
? "bg-card shadow-lg"
|
|
42
|
+
: variant === "outlined"
|
|
43
|
+
? "bg-card border-2 border-base-200 shadow-none"
|
|
44
|
+
: variant === "flat"
|
|
45
|
+
? "bg-card shadow-none border-none"
|
|
46
|
+
: "bg-card shadow-sm",
|
|
47
|
+
);
|
|
65
48
|
|
|
66
|
-
|
|
67
|
-
|
|
49
|
+
const cardClasses = $derived(
|
|
50
|
+
[
|
|
51
|
+
radiusClass,
|
|
52
|
+
"transition-all duration-200",
|
|
53
|
+
variantClasses,
|
|
54
|
+
onclick
|
|
55
|
+
? variant === "elevated"
|
|
56
|
+
? "cursor-pointer hover:shadow-xl hover:bg-card-hover"
|
|
57
|
+
: variant === "outlined"
|
|
58
|
+
? "cursor-pointer hover:border-brand-500 hover:bg-card-hover"
|
|
59
|
+
: variant === "flat"
|
|
60
|
+
? "cursor-pointer hover:bg-card-hover"
|
|
61
|
+
: "cursor-pointer hover:shadow-lg hover:bg-card-hover"
|
|
62
|
+
: "",
|
|
63
|
+
fullWidth ? "w-full" : "",
|
|
64
|
+
sizeClass,
|
|
65
|
+
className,
|
|
66
|
+
]
|
|
67
|
+
.filter(Boolean)
|
|
68
|
+
.join(" ")
|
|
69
|
+
.trim(),
|
|
70
|
+
);
|
|
68
71
|
|
|
69
72
|
function handleKeydown(event: KeyboardEvent) {
|
|
70
73
|
if (onclick && (event.key === "Enter" || event.key === " ")) {
|
|
@@ -74,37 +77,16 @@
|
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
const cardRole = $derived(onclick ? "button" : undefined);
|
|
77
|
-
const cardAriaLabel = $derived(onclick && title ? title : undefined);
|
|
78
80
|
</script>
|
|
79
81
|
|
|
80
82
|
<div
|
|
81
|
-
class={cardClasses
|
|
83
|
+
class={cardClasses}
|
|
82
84
|
{onclick}
|
|
83
85
|
role={cardRole}
|
|
84
86
|
{...onclick ? { tabindex: 0 } : {}}
|
|
85
|
-
aria-label={
|
|
87
|
+
aria-label={ariaLabel}
|
|
86
88
|
onkeydown={onclick ? handleKeydown : undefined}
|
|
87
89
|
{...restProps}
|
|
88
90
|
>
|
|
89
|
-
{
|
|
90
|
-
<!-- Old API: Using title/description/image props -->
|
|
91
|
-
{#if title || description}
|
|
92
|
-
<CardHeader {title} {description} />
|
|
93
|
-
{/if}
|
|
94
|
-
|
|
95
|
-
{#if image || children}
|
|
96
|
-
<CardContent {image} imageAlt={title}>
|
|
97
|
-
{#if children}
|
|
98
|
-
{@render children()}
|
|
99
|
-
{/if}
|
|
100
|
-
</CardContent>
|
|
101
|
-
{/if}
|
|
102
|
-
{:else}
|
|
103
|
-
<!-- New API: Using compound components (CardHeader, CardContent, CardFooter) -->
|
|
104
|
-
{#if children}
|
|
105
|
-
<CardContent className="pt-6">
|
|
106
|
-
{@render children()}
|
|
107
|
-
</CardContent>
|
|
108
|
-
{/if}
|
|
109
|
-
{/if}
|
|
91
|
+
{@render children?.()}
|
|
110
92
|
</div>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { Snippet } from "svelte";
|
|
2
|
-
import type { CardVariant, SizeVariant } from "
|
|
2
|
+
import type { CardVariant, SizeVariant } from "../types/variants.js";
|
|
3
3
|
interface Props {
|
|
4
|
-
title?: string;
|
|
5
|
-
description?: string;
|
|
6
|
-
image?: string;
|
|
7
4
|
onclick?: (event: MouseEvent) => void | Promise<void>;
|
|
8
5
|
size?: SizeVariant;
|
|
9
6
|
variant?: CardVariant;
|
|
10
7
|
fullWidth?: boolean;
|
|
8
|
+
className?: string;
|
|
9
|
+
/** Required when `onclick` is set (no visible label). */
|
|
10
|
+
ariaLabel?: string;
|
|
11
11
|
children?: Snippet;
|
|
12
12
|
}
|
|
13
13
|
declare const Card: import("svelte").Component<Props, {}, "">;
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
5
|
title?: string;
|
|
6
|
+
subtitle?: string;
|
|
6
7
|
description?: string;
|
|
8
|
+
/** `id` on the subtitle `<p>` (e.g. `aria-describedby` on the title). */
|
|
9
|
+
subtitleId?: string;
|
|
10
|
+
/** `id` on the description `<p>`. */
|
|
11
|
+
descriptionId?: string;
|
|
7
12
|
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
8
13
|
className?: string;
|
|
9
14
|
children?: Snippet;
|
|
@@ -11,7 +16,10 @@
|
|
|
11
16
|
|
|
12
17
|
let {
|
|
13
18
|
title = "",
|
|
19
|
+
subtitle = "",
|
|
14
20
|
description = "",
|
|
21
|
+
subtitleId,
|
|
22
|
+
descriptionId,
|
|
15
23
|
level = 3,
|
|
16
24
|
className = "",
|
|
17
25
|
children,
|
|
@@ -24,7 +32,7 @@
|
|
|
24
32
|
});
|
|
25
33
|
</script>
|
|
26
34
|
|
|
27
|
-
<header class=
|
|
35
|
+
<header class={`flex flex-col space-y-1.5 pb-4 ${className}`.trim()} {...restProps}>
|
|
28
36
|
{#if title}
|
|
29
37
|
<svelte:element this={headingTag} class={headingClasses()}>
|
|
30
38
|
{title}
|
|
@@ -33,8 +41,13 @@
|
|
|
33
41
|
{#if children}
|
|
34
42
|
{@render children()}
|
|
35
43
|
{/if}
|
|
44
|
+
{#if subtitle}
|
|
45
|
+
<p id={subtitleId} class="text-sm text-description">
|
|
46
|
+
{subtitle}
|
|
47
|
+
</p>
|
|
48
|
+
{/if}
|
|
36
49
|
{#if description}
|
|
37
|
-
<p class="text-sm text-description">
|
|
50
|
+
<p id={descriptionId} class="text-sm text-description">
|
|
38
51
|
{description}
|
|
39
52
|
</p>
|
|
40
53
|
{/if}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import type { Snippet } from "svelte";
|
|
2
2
|
interface Props {
|
|
3
3
|
title?: string;
|
|
4
|
+
subtitle?: string;
|
|
4
5
|
description?: string;
|
|
6
|
+
/** `id` on the subtitle `<p>` (e.g. `aria-describedby` on the title). */
|
|
7
|
+
subtitleId?: string;
|
|
8
|
+
/** `id` on the description `<p>`. */
|
|
9
|
+
descriptionId?: string;
|
|
5
10
|
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
6
11
|
className?: string;
|
|
7
12
|
children?: Snippet;
|
|
@@ -1,95 +1,69 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import
|
|
2
|
+
import SelectionControl from "./SelectionControl.svelte";
|
|
3
|
+
import type { SelectionControlMarkProps } from "./SelectionControl.svelte";
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
|
-
|
|
6
|
+
id?: string;
|
|
6
7
|
name?: string;
|
|
8
|
+
value?: string;
|
|
7
9
|
disabled?: boolean;
|
|
10
|
+
loading?: boolean;
|
|
8
11
|
label?: string;
|
|
12
|
+
defaultChecked?: boolean;
|
|
13
|
+
checked?: boolean;
|
|
14
|
+
onChange?: (event: Event) => void;
|
|
9
15
|
onchange?: (event: Event) => void;
|
|
10
16
|
}
|
|
11
17
|
|
|
12
18
|
let {
|
|
13
|
-
|
|
19
|
+
id,
|
|
20
|
+
value = "",
|
|
14
21
|
name = "",
|
|
15
22
|
disabled = false,
|
|
23
|
+
loading = false,
|
|
16
24
|
label = "",
|
|
25
|
+
defaultChecked = false,
|
|
26
|
+
checked = $bindable(defaultChecked),
|
|
27
|
+
onChange,
|
|
17
28
|
onchange,
|
|
18
29
|
...restProps
|
|
19
30
|
}: Props = $props();
|
|
20
|
-
|
|
21
|
-
const checkboxId = generateId("checkbox");
|
|
22
|
-
|
|
23
|
-
const checkboxContainerClasses = $derived(() => {
|
|
24
|
-
const baseClasses =
|
|
25
|
-
"relative inline-flex items-center justify-center w-5 h-5 rounded transition-all duration-200";
|
|
26
|
-
|
|
27
|
-
if (disabled) {
|
|
28
|
-
return `${baseClasses} opacity-50 cursor-not-allowed`;
|
|
29
|
-
}
|
|
30
|
-
return `${baseClasses} cursor-pointer`;
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const checkboxBoxClasses = $derived(() => {
|
|
34
|
-
if (checked) {
|
|
35
|
-
return disabled
|
|
36
|
-
? "border-0 opacity-50 bg-brand-500"
|
|
37
|
-
: "border-0 bg-brand-500";
|
|
38
|
-
}
|
|
39
|
-
return disabled
|
|
40
|
-
? "border-2 border-base-400 bg-transparent"
|
|
41
|
-
: "border-2 border-base-400 bg-transparent";
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
function handleChange(event: Event) {
|
|
45
|
-
if (disabled) return;
|
|
46
|
-
const target = event.target as HTMLInputElement;
|
|
47
|
-
checked = target.checked;
|
|
48
|
-
if (onchange) {
|
|
49
|
-
onchange(event);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
31
|
</script>
|
|
53
32
|
|
|
54
|
-
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
33
|
+
{#snippet mark(props: SelectionControlMarkProps)}
|
|
34
|
+
<span
|
|
35
|
+
class="pointer-events-none absolute inline-block size-3 shrink-0 animate-spin rounded-full border-2 border-brand-500 border-t-transparent z-10 opacity-0 group-has-[aria-busy=true]/control:opacity-100 group-has-checked/control:border-base-50"
|
|
36
|
+
aria-hidden="true"
|
|
37
|
+
></span>
|
|
38
|
+
<svg
|
|
39
|
+
class="absolute w-3 h-3 text-base-50 pointer-events-none z-10 opacity-0 group-has-checked/control:opacity-100"
|
|
40
|
+
fill="none"
|
|
41
|
+
stroke="currentColor"
|
|
42
|
+
viewBox="0 0 24 24"
|
|
43
|
+
aria-hidden="true"
|
|
60
44
|
>
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
</svg>
|
|
87
|
-
{/if}
|
|
88
|
-
</div>
|
|
89
|
-
{#if label}
|
|
90
|
-
<span class="text-sm font-medium text-label">
|
|
91
|
-
{label}
|
|
92
|
-
</span>
|
|
93
|
-
{/if}
|
|
94
|
-
</label>
|
|
95
|
-
</div>
|
|
45
|
+
<path
|
|
46
|
+
stroke-linecap="round"
|
|
47
|
+
stroke-linejoin="round"
|
|
48
|
+
stroke-width="2.5"
|
|
49
|
+
d="M5 13l4 4L19 7"
|
|
50
|
+
/>
|
|
51
|
+
</svg>
|
|
52
|
+
{/snippet}
|
|
53
|
+
|
|
54
|
+
<SelectionControl
|
|
55
|
+
type="checkbox"
|
|
56
|
+
shape="square"
|
|
57
|
+
{id}
|
|
58
|
+
{name}
|
|
59
|
+
{value}
|
|
60
|
+
{label}
|
|
61
|
+
{disabled}
|
|
62
|
+
{loading}
|
|
63
|
+
bind:checked
|
|
64
|
+
{defaultChecked}
|
|
65
|
+
{onChange}
|
|
66
|
+
{onchange}
|
|
67
|
+
{mark}
|
|
68
|
+
{...restProps}
|
|
69
|
+
/>
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
interface Props {
|
|
2
|
-
|
|
2
|
+
id?: string;
|
|
3
3
|
name?: string;
|
|
4
|
+
value?: string;
|
|
4
5
|
disabled?: boolean;
|
|
6
|
+
loading?: boolean;
|
|
5
7
|
label?: string;
|
|
8
|
+
defaultChecked?: boolean;
|
|
9
|
+
checked?: boolean;
|
|
10
|
+
onChange?: (event: Event) => void;
|
|
6
11
|
onchange?: (event: Event) => void;
|
|
7
12
|
}
|
|
8
|
-
declare const Checkbox: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
declare const Checkbox: import("svelte").Component<Props, {}, "checked">;
|
|
9
14
|
type Checkbox = ReturnType<typeof Checkbox>;
|
|
10
15
|
export default Checkbox;
|