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
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import Check from "@lucide/svelte/icons/check";
|
|
3
|
+
import Copy from "@lucide/svelte/icons/copy";
|
|
4
|
+
import IconButton from "./IconButton.svelte";
|
|
5
|
+
|
|
2
6
|
interface Props {
|
|
7
|
+
/** Raw source; escaped unless `trustHtml` (e.g. highlighter HTML). */
|
|
3
8
|
code: string;
|
|
4
9
|
language?: string;
|
|
5
10
|
className?: string;
|
|
6
11
|
showCopyButton?: boolean;
|
|
12
|
+
/** If true, `{@html code}` — only trusted, sanitized input. */
|
|
13
|
+
trustHtml?: boolean;
|
|
7
14
|
}
|
|
8
15
|
|
|
9
16
|
let {
|
|
@@ -11,6 +18,7 @@
|
|
|
11
18
|
language = "svelte",
|
|
12
19
|
className = "",
|
|
13
20
|
showCopyButton = true,
|
|
21
|
+
trustHtml = false,
|
|
14
22
|
...restProps
|
|
15
23
|
} = $props();
|
|
16
24
|
|
|
@@ -30,11 +38,11 @@
|
|
|
30
38
|
</script>
|
|
31
39
|
|
|
32
40
|
<div
|
|
33
|
-
class="code-block relative bg-
|
|
41
|
+
class="code-block relative bg-surface-1 border border-border rounded-lg overflow-hidden {className}"
|
|
34
42
|
{...restProps}
|
|
35
43
|
>
|
|
36
44
|
<div
|
|
37
|
-
class="flex items-center justify-between px-4 py-2 bg-
|
|
45
|
+
class="flex items-center justify-between px-4 py-2 bg-surface-2 border-b border-border"
|
|
38
46
|
>
|
|
39
47
|
<div class="flex items-center gap-2">
|
|
40
48
|
<div class="w-3 h-3 rounded-full bg-red-500"></div>
|
|
@@ -42,46 +50,24 @@
|
|
|
42
50
|
<div class="w-3 h-3 rounded-full bg-green-500"></div>
|
|
43
51
|
</div>
|
|
44
52
|
{#if showCopyButton}
|
|
45
|
-
<
|
|
53
|
+
<IconButton
|
|
54
|
+
variant="ghost"
|
|
55
|
+
size="sm"
|
|
56
|
+
label={copied ? "Code copied to clipboard" : "Copy code to clipboard"}
|
|
46
57
|
onclick={copyToClipboard}
|
|
47
|
-
class="flex items-center gap-2 px-3 py-1 text-xs text-base-300 hover:text-white hover:bg-base-700 rounded transition-colors duration-200"
|
|
48
|
-
aria-label="Copy code to clipboard"
|
|
49
58
|
>
|
|
50
59
|
{#if copied}
|
|
51
|
-
<
|
|
52
|
-
class="w-4 h-4"
|
|
53
|
-
fill="currentColor"
|
|
54
|
-
viewBox="0 0 20 20"
|
|
55
|
-
>
|
|
56
|
-
<path
|
|
57
|
-
fill-rule="evenodd"
|
|
58
|
-
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
|
59
|
-
clip-rule="evenodd"
|
|
60
|
-
/>
|
|
61
|
-
</svg>
|
|
62
|
-
Copied!
|
|
60
|
+
<Check size={16} class="shrink-0" aria-hidden="true" />
|
|
63
61
|
{:else}
|
|
64
|
-
<
|
|
65
|
-
class="w-4 h-4"
|
|
66
|
-
fill="none"
|
|
67
|
-
stroke="currentColor"
|
|
68
|
-
viewBox="0 0 24 24"
|
|
69
|
-
>
|
|
70
|
-
<path
|
|
71
|
-
stroke-linecap="round"
|
|
72
|
-
stroke-linejoin="round"
|
|
73
|
-
stroke-width="2"
|
|
74
|
-
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
|
|
75
|
-
/>
|
|
76
|
-
</svg>
|
|
77
|
-
Copy
|
|
62
|
+
<Copy size={16} class="shrink-0" aria-hidden="true" />
|
|
78
63
|
{/if}
|
|
79
|
-
</
|
|
64
|
+
</IconButton>
|
|
80
65
|
{/if}
|
|
81
66
|
</div>
|
|
82
67
|
|
|
83
|
-
<pre class="p-4 overflow-x-auto text-sm text-base-
|
|
84
|
-
class="language-{language}"
|
|
68
|
+
<pre class="p-4 overflow-x-auto text-sm text-base-900 leading-relaxed"><code
|
|
69
|
+
class="language-{language}"
|
|
70
|
+
>{#if trustHtml}{@html code}{:else}{code}{/if}</code
|
|
85
71
|
></pre>
|
|
86
72
|
</div>
|
|
87
73
|
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
let colorMap: HTMLCanvasElement | undefined;
|
|
26
26
|
let colorMapContainer: HTMLDivElement | undefined;
|
|
27
27
|
|
|
28
|
-
// HSL
|
|
28
|
+
// Working color in HSL (h: 0–360; s, l: 0–100).
|
|
29
29
|
let hue = $state(0);
|
|
30
30
|
let saturation = $state(100);
|
|
31
31
|
let lightness = $state(50);
|
|
@@ -156,7 +156,6 @@
|
|
|
156
156
|
const width = colorMap.width;
|
|
157
157
|
const height = colorMap.height;
|
|
158
158
|
|
|
159
|
-
// Draw saturation/lightness gradient
|
|
160
159
|
for (let x = 0; x < width; x++) {
|
|
161
160
|
for (let y = 0; y < height; y++) {
|
|
162
161
|
const s = (x / width) * 100;
|
|
@@ -284,7 +283,7 @@
|
|
|
284
283
|
type="button"
|
|
285
284
|
onclick={togglePicker}
|
|
286
285
|
{disabled}
|
|
287
|
-
class="w-11 h-11 rounded-lg border-2 border-card shrink-0 cursor-pointer hover:ring-2 hover:ring-
|
|
286
|
+
class="focus-ring w-11 h-11 rounded-lg border-2 border-card shrink-0 cursor-pointer hover:ring-2 hover:ring-border transition-colors disabled:cursor-not-allowed disabled:opacity-50"
|
|
288
287
|
style="background-color: {displayColor};"
|
|
289
288
|
aria-label="Open color picker"
|
|
290
289
|
aria-expanded={isOpen}
|
|
@@ -293,12 +292,11 @@
|
|
|
293
292
|
{#if isOpen}
|
|
294
293
|
<div
|
|
295
294
|
use:setPickerContainer
|
|
296
|
-
class="absolute top-12 right-0 z-50 bg-input rounded-2xl shadow-lg p-4 w-80"
|
|
295
|
+
class="absolute top-12 right-0 z-50 border border-input-border bg-input rounded-2xl shadow-lg p-4 w-80"
|
|
297
296
|
role="dialog"
|
|
298
297
|
aria-label="Color picker"
|
|
299
298
|
>
|
|
300
299
|
<div class="space-y-4">
|
|
301
|
-
<!-- Color Map -->
|
|
302
300
|
<div
|
|
303
301
|
use:setColorMapContainer
|
|
304
302
|
class="relative w-full h-48 rounded-xl overflow-hidden cursor-crosshair"
|
|
@@ -315,14 +313,12 @@
|
|
|
315
313
|
height={192}
|
|
316
314
|
class="w-full h-full"
|
|
317
315
|
></canvas>
|
|
318
|
-
<!-- Color indicator -->
|
|
319
316
|
<div
|
|
320
317
|
class="absolute w-4 h-4 border-2 border-white rounded-full shadow-lg pointer-events-none transform -translate-x-1/2 -translate-y-1/2"
|
|
321
318
|
style="left: {pickerIndicatorX}; top: {pickerIndicatorY};"
|
|
322
319
|
></div>
|
|
323
320
|
</div>
|
|
324
321
|
|
|
325
|
-
<!-- Hue Slider -->
|
|
326
322
|
<div class="space-y-2">
|
|
327
323
|
<div
|
|
328
324
|
class="relative h-6 rounded-lg overflow-hidden"
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
type MaxWidth = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
as?: 'div' | 'section' | 'main' | 'article';
|
|
8
|
+
maxWidth?: MaxWidth;
|
|
9
|
+
padded?: boolean;
|
|
10
|
+
class?: string;
|
|
11
|
+
children?: Snippet;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
as: Tag = 'div',
|
|
16
|
+
maxWidth = 'xl',
|
|
17
|
+
padded = true,
|
|
18
|
+
class: className = '',
|
|
19
|
+
children,
|
|
20
|
+
}: Props = $props();
|
|
21
|
+
|
|
22
|
+
const maxClass: Record<MaxWidth, string> = {
|
|
23
|
+
sm: 'max-w-screen-sm',
|
|
24
|
+
md: 'max-w-screen-md',
|
|
25
|
+
lg: 'max-w-screen-lg',
|
|
26
|
+
xl: 'max-w-screen-xl',
|
|
27
|
+
'2xl': 'max-w-screen-2xl',
|
|
28
|
+
full: 'max-w-full',
|
|
29
|
+
};
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<svelte:element
|
|
33
|
+
this={Tag}
|
|
34
|
+
class={['mx-auto w-full', maxClass[maxWidth], padded ? 'px-4 sm:px-6' : '', className]
|
|
35
|
+
.filter(Boolean)
|
|
36
|
+
.join(' ')}
|
|
37
|
+
>
|
|
38
|
+
{#if children}
|
|
39
|
+
{@render children()}
|
|
40
|
+
{/if}
|
|
41
|
+
</svelte:element>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
type MaxWidth = 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'full';
|
|
3
|
+
interface Props {
|
|
4
|
+
as?: 'div' | 'section' | 'main' | 'article';
|
|
5
|
+
maxWidth?: MaxWidth;
|
|
6
|
+
padded?: boolean;
|
|
7
|
+
class?: string;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
}
|
|
10
|
+
declare const Container: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type Container = ReturnType<typeof Container>;
|
|
12
|
+
export default Container;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
type Orientation = 'horizontal' | 'vertical';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
orientation?: Orientation;
|
|
6
|
+
label?: string;
|
|
7
|
+
inset?: boolean;
|
|
8
|
+
class?: string;
|
|
9
|
+
labelClass?: string;
|
|
10
|
+
/** Decorative: omit `role="separator"` so SR does not announce a split. */
|
|
11
|
+
decorative?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
orientation = 'horizontal',
|
|
16
|
+
label,
|
|
17
|
+
inset = false,
|
|
18
|
+
class: className = '',
|
|
19
|
+
labelClass = '',
|
|
20
|
+
decorative = true,
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
|
|
23
|
+
const isVertical = $derived(orientation === 'vertical');
|
|
24
|
+
|
|
25
|
+
const lineClasses = $derived(
|
|
26
|
+
[
|
|
27
|
+
'bg-border',
|
|
28
|
+
isVertical ? 'h-full w-px flex-1' : 'h-px w-full flex-1',
|
|
29
|
+
inset ? (isVertical ? 'my-2' : 'mx-2') : undefined,
|
|
30
|
+
]
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.join(' '),
|
|
33
|
+
);
|
|
34
|
+
</script>
|
|
35
|
+
|
|
36
|
+
<div
|
|
37
|
+
class={[
|
|
38
|
+
'flex items-center text-description',
|
|
39
|
+
isVertical ? 'h-full min-h-[1rem] flex-col' : 'w-full flex-row',
|
|
40
|
+
className,
|
|
41
|
+
]
|
|
42
|
+
.filter(Boolean)
|
|
43
|
+
.join(' ')}
|
|
44
|
+
>
|
|
45
|
+
<div
|
|
46
|
+
aria-hidden={decorative ? 'true' : undefined}
|
|
47
|
+
role={decorative ? 'presentation' : 'separator'}
|
|
48
|
+
aria-orientation={decorative ? undefined : orientation}
|
|
49
|
+
class={lineClasses}
|
|
50
|
+
></div>
|
|
51
|
+
|
|
52
|
+
{#if label}
|
|
53
|
+
<span
|
|
54
|
+
class={['shrink-0 px-3 text-xs font-medium text-description', labelClass]
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
.join(' ')}
|
|
57
|
+
>
|
|
58
|
+
{label}
|
|
59
|
+
</span>
|
|
60
|
+
|
|
61
|
+
<div
|
|
62
|
+
aria-hidden={decorative ? 'true' : undefined}
|
|
63
|
+
role={decorative ? 'presentation' : 'separator'}
|
|
64
|
+
aria-orientation={decorative ? undefined : orientation}
|
|
65
|
+
class={lineClasses}
|
|
66
|
+
></div>
|
|
67
|
+
{/if}
|
|
68
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type Orientation = 'horizontal' | 'vertical';
|
|
2
|
+
interface Props {
|
|
3
|
+
orientation?: Orientation;
|
|
4
|
+
label?: string;
|
|
5
|
+
inset?: boolean;
|
|
6
|
+
class?: string;
|
|
7
|
+
labelClass?: string;
|
|
8
|
+
/** Decorative: omit `role="separator"` so SR does not announce a split. */
|
|
9
|
+
decorative?: boolean;
|
|
10
|
+
}
|
|
11
|
+
declare const Divider: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type Divider = ReturnType<typeof Divider>;
|
|
13
|
+
export default Divider;
|
|
@@ -1,64 +1,49 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import type { Component, Snippet } from "svelte";
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
|
-
icon?: string;
|
|
6
5
|
title: string;
|
|
7
|
-
description
|
|
8
|
-
|
|
6
|
+
description?: string;
|
|
7
|
+
icon?: Component<{ size?: number; class?: string }>;
|
|
8
|
+
children?: Snippet;
|
|
9
|
+
class?: string;
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
let {
|
|
12
|
-
icon = "✨",
|
|
13
13
|
title,
|
|
14
14
|
description,
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
icon: Icon,
|
|
16
|
+
children,
|
|
17
|
+
class: className = "",
|
|
17
18
|
}: Props = $props();
|
|
18
|
-
|
|
19
|
-
let mounted = $state(false);
|
|
20
|
-
|
|
21
|
-
onMount(() => {
|
|
22
|
-
mounted = true;
|
|
23
|
-
});
|
|
24
19
|
</script>
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
21
|
+
<article
|
|
22
|
+
class="flex flex-col gap-3 p-6 rounded-2xl bg-surface-1 border border-base-200 transition-colors duration-200 hover:border-base-300 {className}"
|
|
23
|
+
>
|
|
24
|
+
{#if Icon}
|
|
25
|
+
<span
|
|
26
|
+
class="inline-flex items-center justify-center w-10 h-10 rounded-lg bg-brand-50 text-brand-600"
|
|
27
|
+
aria-hidden="true"
|
|
28
|
+
>
|
|
29
|
+
<Icon size={20} />
|
|
30
|
+
</span>
|
|
31
|
+
{/if}
|
|
32
|
+
|
|
33
|
+
<div class="flex flex-col gap-1.5">
|
|
34
|
+
<h3 class="text-base font-semibold leading-snug text-headline">
|
|
35
|
+
{title}
|
|
36
|
+
</h3>
|
|
37
|
+
{#if description}
|
|
38
|
+
<p class="text-sm leading-relaxed text-description">
|
|
39
|
+
{description}
|
|
40
|
+
</p>
|
|
41
|
+
{/if}
|
|
44
42
|
</div>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class="
|
|
48
|
-
|
|
49
|
-
>
|
|
50
|
-
<div class="flex items-start gap-4">
|
|
51
|
-
<div class="shrink-0 text-2xl" aria-hidden="true">
|
|
52
|
-
{icon}
|
|
53
|
-
</div>
|
|
54
|
-
<div class="flex-1 min-w-0">
|
|
55
|
-
<h3 class="text-lg font-semibold text-headline mb-2">
|
|
56
|
-
{title}
|
|
57
|
-
</h3>
|
|
58
|
-
<p class="text-description leading-relaxed">
|
|
59
|
-
{description}
|
|
60
|
-
</p>
|
|
61
|
-
</div>
|
|
43
|
+
|
|
44
|
+
{#if children}
|
|
45
|
+
<div class="mt-2">
|
|
46
|
+
{@render children()}
|
|
62
47
|
</div>
|
|
63
|
-
|
|
64
|
-
|
|
48
|
+
{/if}
|
|
49
|
+
</article>
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import type { Component, Snippet } from "svelte";
|
|
1
2
|
interface Props {
|
|
2
|
-
icon?: string;
|
|
3
3
|
title: string;
|
|
4
|
-
description
|
|
5
|
-
|
|
4
|
+
description?: string;
|
|
5
|
+
icon?: Component<{
|
|
6
|
+
size?: number;
|
|
7
|
+
class?: string;
|
|
8
|
+
}>;
|
|
9
|
+
children?: Snippet;
|
|
10
|
+
class?: string;
|
|
6
11
|
}
|
|
7
|
-
declare const FeatureCard:
|
|
12
|
+
declare const FeatureCard: Component<Props, {}, "">;
|
|
8
13
|
type FeatureCard = ReturnType<typeof FeatureCard>;
|
|
9
14
|
export default FeatureCard;
|
|
@@ -1,21 +1,17 @@
|
|
|
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
|
-
/** Visual style variant. */
|
|
7
6
|
variant?: ButtonVariant;
|
|
8
|
-
/** Size variant controlling padding and radius. */
|
|
9
7
|
size?: SizeVariant;
|
|
10
|
-
/** Whether the button is disabled. */
|
|
11
8
|
disabled?: boolean;
|
|
12
|
-
|
|
9
|
+
loading?: boolean;
|
|
13
10
|
type?: "button" | "submit" | "reset";
|
|
14
|
-
/**
|
|
11
|
+
/** Required for icon-only usage (no visible text). */
|
|
15
12
|
label?: string;
|
|
16
|
-
|
|
13
|
+
class?: string;
|
|
17
14
|
onclick?: (event: MouseEvent) => void;
|
|
18
|
-
/** Icon content. */
|
|
19
15
|
children?: Snippet;
|
|
20
16
|
}
|
|
21
17
|
|
|
@@ -23,66 +19,79 @@
|
|
|
23
19
|
variant = "primary",
|
|
24
20
|
size = "md",
|
|
25
21
|
disabled = false,
|
|
22
|
+
loading = false,
|
|
26
23
|
type = "button",
|
|
27
24
|
label = "",
|
|
25
|
+
class: className = "",
|
|
28
26
|
onclick,
|
|
29
27
|
children,
|
|
30
28
|
...restProps
|
|
31
29
|
}: Props = $props();
|
|
32
30
|
|
|
33
|
-
const
|
|
31
|
+
const isDisabled = $derived(disabled || loading);
|
|
32
|
+
|
|
33
|
+
const sizeClass = $derived.by(() => {
|
|
34
34
|
if (size === "sm") {
|
|
35
35
|
return {
|
|
36
36
|
padding: "p-2",
|
|
37
37
|
radius: "rounded-md",
|
|
38
|
+
spinner: "size-4",
|
|
38
39
|
};
|
|
39
40
|
} else if (size === "lg") {
|
|
40
41
|
return {
|
|
41
42
|
padding: "p-3",
|
|
42
43
|
radius: "rounded-xl",
|
|
44
|
+
spinner: "size-6",
|
|
43
45
|
};
|
|
44
46
|
} else {
|
|
45
47
|
return {
|
|
46
48
|
padding: "p-2.5",
|
|
47
49
|
radius: "rounded-lg",
|
|
50
|
+
spinner: "size-5",
|
|
48
51
|
};
|
|
49
52
|
}
|
|
50
53
|
});
|
|
51
54
|
|
|
52
|
-
const variantClass = $derived(() => {
|
|
55
|
+
const variantClass = $derived.by(() => {
|
|
53
56
|
return variant === "primary"
|
|
54
|
-
? "bg-action-primary text-action-primary hover:bg-action-primary-hover active:bg-action-primary-active
|
|
57
|
+
? "bg-action-primary text-action-primary hover:bg-action-primary-hover active:bg-action-primary-active active:scale-[0.98]"
|
|
55
58
|
: variant === "secondary"
|
|
56
|
-
? "bg-action-secondary text-headline hover:bg-action-secondary-hover active:bg-action-secondary-active
|
|
59
|
+
? "bg-action-secondary text-headline hover:bg-action-secondary-hover active:bg-action-secondary-active active:scale-[0.98]"
|
|
57
60
|
: variant === "danger"
|
|
58
|
-
? "bg-action-danger text-inverse hover:bg-action-danger-hover active:bg-action-danger-active
|
|
61
|
+
? "bg-action-danger text-inverse hover:bg-action-danger-hover active:bg-action-danger-active active:scale-[0.98] focus-ring--danger"
|
|
59
62
|
: variant === "ghost"
|
|
60
|
-
? "bg-transparent text-headline hover:bg-base-100 active:bg-base-200
|
|
63
|
+
? "bg-transparent text-headline hover:bg-base-100 active:bg-base-200 active:scale-[0.98] focus-ring--muted disabled:text-disabled"
|
|
61
64
|
: variant === "outline"
|
|
62
|
-
? "bg-transparent border-2 border-action-primary text-headline hover:bg-action-secondary hover:text-action-primary active:bg-action-primary-active active:text-action-primary
|
|
65
|
+
? "bg-transparent border-2 border-action-primary text-headline hover:bg-action-secondary hover:text-action-primary active:bg-action-primary-active active:text-action-primary active:scale-[0.98] disabled:border-disabled disabled:text-disabled"
|
|
63
66
|
: variant === "link"
|
|
64
|
-
? "text-brand-700 active:text-brand-700
|
|
65
|
-
: "bg-action-primary text-action-primary hover:bg-action-primary-hover active:bg-action-primary-active
|
|
67
|
+
? "text-brand-700 active:text-brand-700 hover:underline disabled:text-disabled disabled:no-underline"
|
|
68
|
+
: "bg-action-primary text-action-primary hover:bg-action-primary-hover active:bg-action-primary-active active:scale-[0.98]";
|
|
66
69
|
});
|
|
67
70
|
|
|
68
|
-
const buttonClasses = $derived(() => {
|
|
69
|
-
const sizeStyles = sizeClass
|
|
71
|
+
const buttonClasses = $derived.by(() => {
|
|
72
|
+
const sizeStyles = sizeClass;
|
|
70
73
|
const baseClasses =
|
|
71
|
-
"inline-flex items-center justify-center transition-all duration-200 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed
|
|
74
|
+
"inline-flex focus-ring items-center justify-center transition-all duration-200 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:active:scale-100";
|
|
72
75
|
|
|
73
|
-
return `${baseClasses} ${sizeStyles.padding} ${sizeStyles.radius} ${variantClass
|
|
76
|
+
return `${baseClasses} ${sizeStyles.padding} ${sizeStyles.radius} ${variantClass} ${className}`.trim();
|
|
74
77
|
});
|
|
75
78
|
</script>
|
|
76
79
|
|
|
77
80
|
<button
|
|
78
81
|
{type}
|
|
79
|
-
class={buttonClasses
|
|
80
|
-
{
|
|
82
|
+
class={buttonClasses}
|
|
83
|
+
disabled={isDisabled}
|
|
84
|
+
aria-busy={loading ? "true" : undefined}
|
|
81
85
|
{onclick}
|
|
82
86
|
aria-label={label || undefined}
|
|
83
87
|
{...restProps}
|
|
84
88
|
>
|
|
85
|
-
{#if
|
|
89
|
+
{#if loading}
|
|
90
|
+
<span
|
|
91
|
+
class="inline-block {sizeClass.spinner} shrink-0 animate-spin rounded-full border-2 border-current border-t-transparent opacity-80"
|
|
92
|
+
aria-hidden="true"
|
|
93
|
+
></span>
|
|
94
|
+
{:else if children}
|
|
86
95
|
{@render children()}
|
|
87
96
|
{/if}
|
|
88
97
|
</button>
|
|
@@ -1,19 +1,15 @@
|
|
|
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
|
-
/** Visual style variant. */
|
|
5
4
|
variant?: ButtonVariant;
|
|
6
|
-
/** Size variant controlling padding and radius. */
|
|
7
5
|
size?: SizeVariant;
|
|
8
|
-
/** Whether the button is disabled. */
|
|
9
6
|
disabled?: boolean;
|
|
10
|
-
|
|
7
|
+
loading?: boolean;
|
|
11
8
|
type?: "button" | "submit" | "reset";
|
|
12
|
-
/**
|
|
9
|
+
/** Required for icon-only usage (no visible text). */
|
|
13
10
|
label?: string;
|
|
14
|
-
|
|
11
|
+
class?: string;
|
|
15
12
|
onclick?: (event: MouseEvent) => void;
|
|
16
|
-
/** Icon content. */
|
|
17
13
|
children?: Snippet;
|
|
18
14
|
}
|
|
19
15
|
declare const IconButton: import("svelte").Component<Props, {}, "">;
|