zabi-components 5.0.5 → 5.0.7
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/dist/atoms/Badge.svelte +5 -5
- package/dist/atoms/Button.svelte +9 -19
- package/dist/atoms/Button.svelte.d.ts +1 -1
- package/dist/atoms/Card.svelte +2 -2
- package/dist/atoms/ColorPicker.svelte +35 -92
- package/dist/atoms/ColorPicker.svelte.d.ts +2 -1
- package/dist/atoms/FeatureCard.svelte +1 -1
- package/dist/atoms/Heading.svelte +37 -2
- package/dist/atoms/Heading.svelte.d.ts +3 -3
- package/dist/atoms/Input.svelte +6 -6
- package/dist/atoms/Select.svelte +7 -4
- package/dist/atoms/Textarea.svelte +6 -23
- package/dist/atoms/ThemeToggle.svelte +6 -5
- package/dist/molecules/ComponentDemo.svelte +3 -3
- package/dist/molecules/ImageUpload.svelte +9 -6
- package/dist/molecules/Modal.svelte +15 -3
- package/dist/molecules/Modal.svelte.d.ts +2 -0
- package/dist/organisms/Navbar.svelte +2 -2
- package/dist/organisms/Navigation.svelte +35 -23
- package/dist/organisms/Navigation.svelte.d.ts +1 -0
- package/dist/zabi-components.css +222 -118
- package/package.json +4 -5
package/dist/atoms/Badge.svelte
CHANGED
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
// Variant classes - using semantic color system
|
|
36
36
|
const variantClass =
|
|
37
37
|
variant === "success"
|
|
38
|
-
? "bg-surface-
|
|
38
|
+
? "bg-surface-level-1 border-secondary text-success"
|
|
39
39
|
: variant === "warning"
|
|
40
|
-
? "bg-surface-
|
|
40
|
+
? "bg-surface-level-1 border-secondary text-warning"
|
|
41
41
|
: variant === "error"
|
|
42
|
-
? "bg-surface-
|
|
42
|
+
? "bg-surface-level-1 border-secondary text-error"
|
|
43
43
|
: variant === "info"
|
|
44
|
-
? "bg-surface-
|
|
45
|
-
: "bg-surface-
|
|
44
|
+
? "bg-surface-level-1 border-secondary text-body"
|
|
45
|
+
: "bg-surface-level-1 border-secondary text-body"; // default
|
|
46
46
|
|
|
47
47
|
return `${baseClasses} ${sizeClass} ${variantClass}`.trim();
|
|
48
48
|
});
|
package/dist/atoms/Button.svelte
CHANGED
|
@@ -2,13 +2,7 @@
|
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
|
-
variant?:
|
|
6
|
-
| "primary"
|
|
7
|
-
| "secondary"
|
|
8
|
-
| "danger"
|
|
9
|
-
| "success"
|
|
10
|
-
| "ghost"
|
|
11
|
-
| "brand";
|
|
5
|
+
variant?: "primary" | "secondary" | "danger" | "ghost";
|
|
12
6
|
size?: "sm" | "md" | "lg";
|
|
13
7
|
disabled?: boolean;
|
|
14
8
|
type?: "button" | "submit" | "reset";
|
|
@@ -37,27 +31,23 @@
|
|
|
37
31
|
: "px-4 py-2 text-sm font-medium"; // default md
|
|
38
32
|
});
|
|
39
33
|
|
|
40
|
-
// Variant classes using
|
|
34
|
+
// Variant classes using semantic action colors
|
|
41
35
|
const variantClass = $derived(() => {
|
|
42
36
|
return variant === "primary"
|
|
43
|
-
? "bg-
|
|
37
|
+
? "bg-action-primary text-inverse focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
|
|
44
38
|
: variant === "secondary"
|
|
45
|
-
? "
|
|
39
|
+
? "border border-secondary text-description hover:border-secondary-hover focus:ring-2 focus:ring-stone-500 focus:ring-offset-2"
|
|
46
40
|
: variant === "danger"
|
|
47
|
-
? "bg-
|
|
48
|
-
: variant === "
|
|
49
|
-
? "bg-
|
|
50
|
-
:
|
|
51
|
-
? "bg-transparent text-gray-700 hover:bg-gray-100 active:bg-gray-200 focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 disabled:text-gray-400"
|
|
52
|
-
: variant === "brand"
|
|
53
|
-
? "bg-purple-600 text-white hover:bg-purple-700 active:bg-purple-800 focus:ring-2 focus:ring-purple-500 focus:ring-offset-2 disabled:bg-purple-400"
|
|
54
|
-
: "bg-blue-600 text-white hover:bg-blue-700 active:bg-blue-800 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:bg-blue-400"; // default primary
|
|
41
|
+
? "bg-action-danger text-inverse focus:ring-2 focus:ring-red-500 focus:ring-offset-2"
|
|
42
|
+
: variant === "ghost"
|
|
43
|
+
? "bg-transparent text-headline hover:bg-surface-hover active:bg-surface-active focus:ring-2 focus:ring-stone-500 focus:ring-offset-2 disabled:text-disabled"
|
|
44
|
+
: "bg-action-primary text-inverse focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"; // default primary
|
|
55
45
|
});
|
|
56
46
|
|
|
57
47
|
// Button classes using Badge pattern
|
|
58
48
|
const buttonClasses = $derived(() => {
|
|
59
49
|
const baseClasses =
|
|
60
|
-
"inline-flex items-center justify-center rounded-md transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none focus:outline-none focus:ring-2 focus:ring-offset-2 active:scale-95 transform-gpu
|
|
50
|
+
"inline-flex items-center justify-center rounded-md transition-all duration-200 cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none focus:outline-none focus:ring-2 focus:ring-offset-2 active:scale-95 transform-gpu";
|
|
61
51
|
|
|
62
52
|
return `${baseClasses} ${sizeClass()} ${variantClass()}`.trim();
|
|
63
53
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from "svelte";
|
|
2
2
|
interface Props {
|
|
3
|
-
variant?: "primary" | "secondary" | "danger" | "
|
|
3
|
+
variant?: "primary" | "secondary" | "danger" | "ghost";
|
|
4
4
|
size?: "sm" | "md" | "lg";
|
|
5
5
|
disabled?: boolean;
|
|
6
6
|
type?: "button" | "submit" | "reset";
|
package/dist/atoms/Card.svelte
CHANGED
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
|
|
27
27
|
const cardClasses = $derived(() => {
|
|
28
28
|
const baseClasses =
|
|
29
|
-
"
|
|
29
|
+
"rounded-lg transition-all duration-200 min-w-64 bg-surface-level-0";
|
|
30
30
|
const interactiveClasses = onclick
|
|
31
|
-
? "cursor-pointer hover:bg-surface-hover hover:border-focus"
|
|
31
|
+
? "cursor-pointer hover:shadow-adaptive-md hover:bg-surface-hover hover:border-focus"
|
|
32
32
|
: "";
|
|
33
33
|
const widthClasses = fullWidth ? "w-full" : "";
|
|
34
34
|
|
|
@@ -12,31 +12,21 @@
|
|
|
12
12
|
value?: string;
|
|
13
13
|
label?: string;
|
|
14
14
|
disabled?: boolean;
|
|
15
|
-
|
|
15
|
+
placeholder?: string;
|
|
16
|
+
onchange?: (event: Event) => void;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
let {
|
|
19
20
|
value = "",
|
|
20
21
|
label = "",
|
|
21
22
|
disabled = false,
|
|
22
|
-
|
|
23
|
+
placeholder = "#000000",
|
|
24
|
+
onchange,
|
|
23
25
|
...restProps
|
|
24
26
|
}: Props = $props();
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
{ label: "Blue", value: "#3b82f6" },
|
|
29
|
-
{ label: "Green", value: "#10b981" },
|
|
30
|
-
{ label: "Yellow", value: "#f59e0b" },
|
|
31
|
-
{ label: "Purple", value: "#8b5cf6" },
|
|
32
|
-
{ label: "Pink", value: "#ec4899" },
|
|
33
|
-
{ label: "Gray", value: "#6b7280" },
|
|
34
|
-
{ label: "Black", value: "#000000" },
|
|
35
|
-
];
|
|
36
|
-
|
|
37
|
-
// Generate unique IDs - SSR safe (call directly, not in onMount)
|
|
38
|
-
const groupId = generateId("color-picker");
|
|
39
|
-
const inputId = generateId("color-input");
|
|
28
|
+
// Generate unique ID - SSR safe
|
|
29
|
+
const inputId = generateId("color-picker");
|
|
40
30
|
|
|
41
31
|
// Hex color validation
|
|
42
32
|
function isValidHex(hex: string): boolean {
|
|
@@ -51,7 +41,7 @@
|
|
|
51
41
|
|
|
52
42
|
if (hexValue === "" || isValidHex(hexValue)) {
|
|
53
43
|
value = hexValue;
|
|
54
|
-
if (
|
|
44
|
+
if (onchange) onchange(event);
|
|
55
45
|
}
|
|
56
46
|
}
|
|
57
47
|
|
|
@@ -75,20 +65,6 @@
|
|
|
75
65
|
}
|
|
76
66
|
}
|
|
77
67
|
|
|
78
|
-
// Color button classes using full class names
|
|
79
|
-
const colorButtonClasses = $derived(() => {
|
|
80
|
-
return (colorValue: string) => {
|
|
81
|
-
const baseClasses =
|
|
82
|
-
"w-10 h-10 sm:w-12 sm:h-12 rounded-lg border-2 transition-all";
|
|
83
|
-
const stateClasses =
|
|
84
|
-
value === colorValue
|
|
85
|
-
? "border-blue-500 ring-2 ring-blue-200"
|
|
86
|
-
: "border-gray-300 hover:border-gray-400";
|
|
87
|
-
|
|
88
|
-
return `${baseClasses} ${stateClasses}`.trim();
|
|
89
|
-
};
|
|
90
|
-
});
|
|
91
|
-
|
|
92
68
|
// Input classes
|
|
93
69
|
const inputClasses = $derived(() => {
|
|
94
70
|
const baseClasses =
|
|
@@ -102,70 +78,37 @@
|
|
|
102
78
|
});
|
|
103
79
|
</script>
|
|
104
80
|
|
|
105
|
-
<div class="space-y-
|
|
81
|
+
<div class="space-y-2" {...restProps}>
|
|
106
82
|
{#if label}
|
|
107
|
-
<label for={
|
|
108
|
-
|
|
109
|
-
>
|
|
83
|
+
<label for={inputId} class="block text-sm font-medium text-label">
|
|
84
|
+
{label}
|
|
85
|
+
</label>
|
|
110
86
|
{/if}
|
|
111
87
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
aria-checked={value === color.value}
|
|
131
|
-
aria-label={color.label}
|
|
132
|
-
>
|
|
133
|
-
{#if value === color.value}
|
|
134
|
-
<span class="text-white text-lg">✓</span>
|
|
135
|
-
{/if}
|
|
136
|
-
</button>
|
|
137
|
-
{/each}
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
|
-
<!-- Custom Hex Input -->
|
|
141
|
-
<div class="space-y-1">
|
|
142
|
-
<label for={inputId} class="block text-xs font-medium text-label">
|
|
143
|
-
Or enter custom color
|
|
144
|
-
</label>
|
|
145
|
-
<div class="flex items-center space-x-2">
|
|
146
|
-
<input
|
|
147
|
-
id={inputId}
|
|
148
|
-
type="text"
|
|
149
|
-
placeholder="#000000"
|
|
150
|
-
{value}
|
|
151
|
-
oninput={handleHexInput}
|
|
152
|
-
onblur={handleHexBlur}
|
|
153
|
-
{disabled}
|
|
154
|
-
class={inputClasses()}
|
|
155
|
-
aria-label="Custom hex color input"
|
|
156
|
-
/>
|
|
157
|
-
{#if value && isValidHex(value)}
|
|
158
|
-
<div
|
|
159
|
-
class="w-6 h-6 sm:w-8 sm:h-8 rounded border-2 border-gray-300 shrink-0"
|
|
160
|
-
style="background-color: {value};"
|
|
161
|
-
aria-label="Color preview"
|
|
162
|
-
></div>
|
|
163
|
-
{/if}
|
|
164
|
-
</div>
|
|
165
|
-
{#if value && !isValidHex(value)}
|
|
166
|
-
<p class="text-xs text-red-500">
|
|
167
|
-
Please enter a valid hex color (e.g., #ff0000)
|
|
168
|
-
</p>
|
|
88
|
+
<div class="flex items-center space-x-2">
|
|
89
|
+
<input
|
|
90
|
+
id={inputId}
|
|
91
|
+
type="text"
|
|
92
|
+
{placeholder}
|
|
93
|
+
{value}
|
|
94
|
+
oninput={handleHexInput}
|
|
95
|
+
onblur={handleHexBlur}
|
|
96
|
+
{disabled}
|
|
97
|
+
class={inputClasses()}
|
|
98
|
+
aria-label="Hex color input"
|
|
99
|
+
/>
|
|
100
|
+
{#if value && isValidHex(value)}
|
|
101
|
+
<div
|
|
102
|
+
class="w-8 h-8 rounded border-2 border-gray-300 shrink-0"
|
|
103
|
+
style="background-color: {value};"
|
|
104
|
+
aria-label="Color preview"
|
|
105
|
+
></div>
|
|
169
106
|
{/if}
|
|
170
107
|
</div>
|
|
108
|
+
|
|
109
|
+
{#if value && !isValidHex(value)}
|
|
110
|
+
<p class="text-xs text-red-500">
|
|
111
|
+
Please enter a valid hex color (e.g., #ff0000 or #f00)
|
|
112
|
+
</p>
|
|
113
|
+
{/if}
|
|
171
114
|
</div>
|
|
@@ -2,7 +2,8 @@ interface Props {
|
|
|
2
2
|
value?: string;
|
|
3
3
|
label?: string;
|
|
4
4
|
disabled?: boolean;
|
|
5
|
-
|
|
5
|
+
placeholder?: string;
|
|
6
|
+
onchange?: (event: Event) => void;
|
|
6
7
|
}
|
|
7
8
|
declare const ColorPicker: import("svelte").Component<Props, {}, "">;
|
|
8
9
|
type ColorPicker = ReturnType<typeof ColorPicker>;
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
|
|
35
35
|
{#if mounted}
|
|
36
36
|
<div
|
|
37
|
-
class="p-6 rounded-lg bg-surface border border-border hover:border-primary/20 hover:shadow-sm transition-colors duration-200 {className}"
|
|
37
|
+
class="p-6 rounded-lg bg-surface-level-0 border border-border hover:border-primary/20 hover:shadow-sm transition-colors duration-200 {className}"
|
|
38
38
|
{...restProps}
|
|
39
39
|
>
|
|
40
40
|
<div class="flex items-start gap-4">
|
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
2
|
+
interface Props {
|
|
3
|
+
level?: number;
|
|
4
|
+
text: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
let { level = 1, text }: Props = $props();
|
|
8
|
+
|
|
9
|
+
// Automatic weight and size based on heading level
|
|
10
|
+
const fontWeight = $derived(level <= 2 ? "700" : "500");
|
|
11
|
+
const Tag = $derived(`h${level}`);
|
|
12
|
+
|
|
13
|
+
// Size classes for different heading levels
|
|
14
|
+
const sizeClasses = {
|
|
15
|
+
1: "text-4xl",
|
|
16
|
+
2: "text-3xl",
|
|
17
|
+
3: "text-2xl",
|
|
18
|
+
4: "text-xl",
|
|
19
|
+
5: "text-lg",
|
|
20
|
+
6: "text-base",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const sizeClass = $derived(
|
|
24
|
+
sizeClasses[level as keyof typeof sizeClasses] || "text-base",
|
|
25
|
+
);
|
|
3
26
|
</script>
|
|
4
27
|
|
|
5
|
-
<
|
|
28
|
+
<svelte:element
|
|
29
|
+
this={Tag}
|
|
30
|
+
class="text-headline font-nunito {sizeClass}"
|
|
31
|
+
style="font-weight: {fontWeight};"
|
|
32
|
+
>
|
|
33
|
+
{text}
|
|
34
|
+
</svelte:element>
|
|
35
|
+
|
|
36
|
+
<style>
|
|
37
|
+
.font-nunito {
|
|
38
|
+
font-family: "Nunito Sans", ui-sans-serif, system-ui, sans-serif;
|
|
39
|
+
}
|
|
40
|
+
</style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
interface Props {
|
|
2
2
|
level?: number;
|
|
3
3
|
text: string;
|
|
4
|
-
}
|
|
5
|
-
declare const Heading: import("svelte").Component
|
|
4
|
+
}
|
|
5
|
+
declare const Heading: import("svelte").Component<Props, {}, "">;
|
|
6
6
|
type Heading = ReturnType<typeof Heading>;
|
|
7
7
|
export default Heading;
|
package/dist/atoms/Input.svelte
CHANGED
|
@@ -45,21 +45,21 @@
|
|
|
45
45
|
: "px-4 py-2 text-sm"; // default md
|
|
46
46
|
});
|
|
47
47
|
|
|
48
|
-
// Variant classes using
|
|
48
|
+
// Variant classes using semantic colors
|
|
49
49
|
const variantClass = $derived(() => {
|
|
50
50
|
return variant === "success"
|
|
51
|
-
? "border-
|
|
51
|
+
? "border-success focus:border-success focus:ring-success"
|
|
52
52
|
: variant === "warning"
|
|
53
|
-
? "border-
|
|
53
|
+
? "border-warning focus:border-warning focus:ring-warning"
|
|
54
54
|
: variant === "error"
|
|
55
|
-
? "border-
|
|
56
|
-
: "border-
|
|
55
|
+
? "border-error focus:border-error focus:ring-error"
|
|
56
|
+
: "border-border focus:border-focus focus:ring-focus"; // default
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
// Input classes using Badge pattern
|
|
60
60
|
const inputClasses = $derived(() => {
|
|
61
61
|
const baseClasses =
|
|
62
|
-
"w-full rounded-md transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-surface disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-surface-disabled";
|
|
62
|
+
"w-full border rounded-md transition-colors duration-200 placeholder:text-input-placeholder focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-surface disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-surface-disabled";
|
|
63
63
|
|
|
64
64
|
return `${baseClasses} ${sizeClass()} ${variantClass()}`.trim();
|
|
65
65
|
});
|
package/dist/atoms/Select.svelte
CHANGED
|
@@ -47,11 +47,16 @@
|
|
|
47
47
|
// Select classes using Badge pattern
|
|
48
48
|
const selectClasses = $derived(() => {
|
|
49
49
|
const baseClasses =
|
|
50
|
-
"w-full border border-
|
|
50
|
+
"w-full border border-border rounded-md transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-surface focus:ring-focus focus:border-focus disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-surface-disabled";
|
|
51
51
|
|
|
52
52
|
return `${baseClasses} ${sizeClass()}`.trim();
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
+
// Label classes using semantic text colors
|
|
56
|
+
const labelClasses = $derived(
|
|
57
|
+
() => "block text-sm font-medium text-label mb-1",
|
|
58
|
+
);
|
|
59
|
+
|
|
55
60
|
function handleChange(event: Event) {
|
|
56
61
|
const target = event.target as HTMLSelectElement;
|
|
57
62
|
value = target.value;
|
|
@@ -60,9 +65,7 @@
|
|
|
60
65
|
|
|
61
66
|
<div>
|
|
62
67
|
{#if label}
|
|
63
|
-
<label for={selectId} class=
|
|
64
|
-
>{label}</label
|
|
65
|
-
>
|
|
68
|
+
<label for={selectId} class={labelClasses()}>{label}</label>
|
|
66
69
|
{/if}
|
|
67
70
|
|
|
68
71
|
<select
|
|
@@ -8,23 +8,6 @@
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
// Input variant classes
|
|
12
|
-
function getInputVariantClasses(
|
|
13
|
-
variant: "default" | "success" | "warning" | "error" | "info",
|
|
14
|
-
): string {
|
|
15
|
-
const variantMap = {
|
|
16
|
-
default:
|
|
17
|
-
"border-gray-300 focus:border-blue-500 focus:ring-blue-500",
|
|
18
|
-
success:
|
|
19
|
-
"border-green-300 focus:border-green-500 focus:ring-green-500",
|
|
20
|
-
warning:
|
|
21
|
-
"border-yellow-300 focus:border-yellow-500 focus:ring-yellow-500",
|
|
22
|
-
error: "border-red-300 focus:border-red-500 focus:ring-red-500",
|
|
23
|
-
info: "border-blue-300 focus:border-blue-500 focus:ring-blue-500",
|
|
24
|
-
};
|
|
25
|
-
return variantMap[variant] || variantMap.default;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
11
|
interface Props {
|
|
29
12
|
value?: string;
|
|
30
13
|
name?: string;
|
|
@@ -62,21 +45,21 @@
|
|
|
62
45
|
: "px-4 py-2 text-sm"; // default md
|
|
63
46
|
});
|
|
64
47
|
|
|
65
|
-
// Variant classes using
|
|
48
|
+
// Variant classes using semantic colors
|
|
66
49
|
const variantClass = $derived(() => {
|
|
67
50
|
return variant === "success"
|
|
68
|
-
? "border-
|
|
51
|
+
? "border-success focus:border-success focus:ring-success"
|
|
69
52
|
: variant === "warning"
|
|
70
|
-
? "border-
|
|
53
|
+
? "border-warning focus:border-warning focus:ring-warning"
|
|
71
54
|
: variant === "error"
|
|
72
|
-
? "border-
|
|
73
|
-
: "border-
|
|
55
|
+
? "border-error focus:border-error focus:ring-error"
|
|
56
|
+
: "border-border focus:border-focus focus:ring-focus"; // default
|
|
74
57
|
});
|
|
75
58
|
|
|
76
59
|
// Textarea classes using Badge pattern
|
|
77
60
|
const textareaClasses = $derived(() => {
|
|
78
61
|
const baseClasses =
|
|
79
|
-
"w-full rounded-md transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-surface disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-surface-disabled resize-y";
|
|
62
|
+
"w-full border rounded-md transition-colors duration-200 placeholder:text-input-placeholder focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-surface disabled:opacity-50 disabled:cursor-not-allowed disabled:bg-surface-disabled resize-y";
|
|
80
63
|
|
|
81
64
|
return `${baseClasses} ${sizeClass()} ${variantClass()}`.trim();
|
|
82
65
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { onMount } from "svelte";
|
|
3
|
+
import { Sun, Moon } from "@lucide/svelte";
|
|
3
4
|
// SSR-safe utilities
|
|
4
5
|
function safeLocalStorage(): Storage | undefined {
|
|
5
6
|
return typeof window !== "undefined" ? localStorage : undefined;
|
|
@@ -67,23 +68,23 @@
|
|
|
67
68
|
{#if mounted}
|
|
68
69
|
<button
|
|
69
70
|
onclick={toggleTheme}
|
|
70
|
-
class="w-10 h-10 bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded-lg flex items-center justify-center text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
71
|
+
class="w-10 h-10 bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded-lg flex items-center justify-center text-gray-700 cursor-pointer focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
71
72
|
aria-label={isDark ? "Switch to light mode" : "Switch to dark mode"}
|
|
72
73
|
{...restProps}
|
|
73
74
|
>
|
|
74
75
|
{#if isDark}
|
|
75
|
-
<
|
|
76
|
+
<Moon size={20} class="text-label" />
|
|
76
77
|
{:else}
|
|
77
|
-
<
|
|
78
|
+
<Sun size={20} class="text-label" />
|
|
78
79
|
{/if}
|
|
79
80
|
</button>
|
|
80
81
|
{:else}
|
|
81
82
|
<!-- SSR fallback -->
|
|
82
83
|
<button
|
|
83
|
-
class="w-10 h-10 bg-gray-100 border border-gray-300 rounded-lg flex items-center justify-center text-gray-700"
|
|
84
|
+
class="w-10 h-10 bg-gray-100 border border-gray-300 rounded-lg flex items-center justify-center text-gray-700 cursor-pointer"
|
|
84
85
|
aria-label="Theme toggle"
|
|
85
86
|
{...restProps}
|
|
86
87
|
>
|
|
87
|
-
<
|
|
88
|
+
<Sun size={20} class="text-label" />
|
|
88
89
|
</button>
|
|
89
90
|
{/if}
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
</script>
|
|
24
24
|
|
|
25
25
|
<div
|
|
26
|
-
class="component-demo bg-surface border border-border rounded-lg overflow-hidden {className}"
|
|
26
|
+
class="component-demo bg-surface-level-0 border border-border rounded-lg overflow-hidden {className}"
|
|
27
27
|
{...restProps}
|
|
28
28
|
>
|
|
29
29
|
<!-- Header -->
|
|
30
|
-
<div class="px-6 py-4 border-b border-border bg-surface-
|
|
30
|
+
<div class="px-6 py-4 border-b border-border bg-surface-level-1">
|
|
31
31
|
<div class="flex items-center justify-between">
|
|
32
32
|
<div>
|
|
33
33
|
<h3 class="text-lg font-semibold text-text">{title}</h3>
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
</div>
|
|
40
40
|
<button
|
|
41
41
|
onclick={() => (showCode = !showCode)}
|
|
42
|
-
class="flex items-center gap-2 px-3 py-1.5 text-sm text-text-secondary hover:text-text hover:bg-surface rounded-md transition-colors duration-200"
|
|
42
|
+
class="flex items-center gap-2 px-3 py-1.5 text-sm text-text-secondary hover:text-text hover:bg-surface-level-0 rounded-md transition-colors duration-200"
|
|
43
43
|
aria-label={showCode ? "Show preview" : "Show code"}
|
|
44
44
|
>
|
|
45
45
|
{#if showCode}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Button from "../atoms/Button.svelte";
|
|
3
|
+
import { Image } from "@lucide/svelte";
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
value?: string | null;
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
<img
|
|
54
55
|
src={value}
|
|
55
56
|
alt=""
|
|
56
|
-
class="w-full h-32 object-cover rounded-lg border border-
|
|
57
|
+
class="w-full h-32 object-cover rounded-lg border border-border"
|
|
57
58
|
/>
|
|
58
59
|
<div
|
|
59
60
|
class="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity rounded-lg flex items-center justify-center"
|
|
@@ -81,7 +82,7 @@
|
|
|
81
82
|
{:else}
|
|
82
83
|
<!-- Empty State -->
|
|
83
84
|
<div
|
|
84
|
-
class="border-2 border-dashed border-
|
|
85
|
+
class="border-2 border-dashed border-border rounded-lg p-6 text-center hover:border-border-strong transition-colors cursor-pointer"
|
|
85
86
|
onclick={triggerFileSelect}
|
|
86
87
|
role="button"
|
|
87
88
|
tabindex="0"
|
|
@@ -89,13 +90,15 @@
|
|
|
89
90
|
>
|
|
90
91
|
<div class="space-y-3">
|
|
91
92
|
<div
|
|
92
|
-
class="w-12 h-12 mx-auto bg-
|
|
93
|
+
class="w-12 h-12 mx-auto bg-surface-level-1 rounded-lg flex items-center justify-center"
|
|
93
94
|
>
|
|
94
|
-
<
|
|
95
|
+
<Image size={24} class="text-description" />
|
|
95
96
|
</div>
|
|
96
97
|
<div>
|
|
97
|
-
<p class="font-medium text-
|
|
98
|
-
<p class="text-sm text-
|
|
98
|
+
<p class="font-medium text-headline">{placeholder}</p>
|
|
99
|
+
<p class="text-sm text-description">
|
|
100
|
+
Click to choose a file
|
|
101
|
+
</p>
|
|
99
102
|
</div>
|
|
100
103
|
</div>
|
|
101
104
|
</div>
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
type Size = "sm" | "md" | "lg";
|
|
3
|
+
|
|
2
4
|
interface Props {
|
|
3
5
|
isOpen?: boolean;
|
|
4
6
|
title?: string;
|
|
7
|
+
size?: Size;
|
|
5
8
|
onclick?: (event: Event) => void;
|
|
6
9
|
onkeydown?: (event: Event) => void;
|
|
7
10
|
}
|
|
@@ -9,6 +12,7 @@
|
|
|
9
12
|
let {
|
|
10
13
|
isOpen = false,
|
|
11
14
|
title = "",
|
|
15
|
+
size = "md",
|
|
12
16
|
onclick,
|
|
13
17
|
onkeydown,
|
|
14
18
|
children,
|
|
@@ -16,6 +20,14 @@
|
|
|
16
20
|
...restProps
|
|
17
21
|
}: Props & { children?: any; footer?: any } = $props();
|
|
18
22
|
|
|
23
|
+
const sizeClasses = $derived(
|
|
24
|
+
{
|
|
25
|
+
sm: "w-full md:w-[24rem]",
|
|
26
|
+
md: "w-full md:w-[28rem]",
|
|
27
|
+
lg: "w-full md:w-[42rem]",
|
|
28
|
+
}[size] || "w-full md:w-[28rem]",
|
|
29
|
+
);
|
|
30
|
+
|
|
19
31
|
function closeModal(event?: Event) {
|
|
20
32
|
isOpen = false;
|
|
21
33
|
if (onclick && event) {
|
|
@@ -42,7 +54,7 @@
|
|
|
42
54
|
|
|
43
55
|
{#if isOpen}
|
|
44
56
|
<div
|
|
45
|
-
class="fixed inset-0 bg-black/50 flex items-center justify-center p-4 z-50"
|
|
57
|
+
class="fixed inset-0 bg-black/50 flex items-end md:items-center justify-center p-0 md:p-4 z-50"
|
|
46
58
|
onclick={handleBackdropClick}
|
|
47
59
|
onkeydown={handleKeydown}
|
|
48
60
|
role="dialog"
|
|
@@ -50,7 +62,7 @@
|
|
|
50
62
|
tabindex="-1"
|
|
51
63
|
>
|
|
52
64
|
<div
|
|
53
|
-
class="bg-white rounded-lg shadow-xl
|
|
65
|
+
class="bg-white rounded-t-2xl md:rounded-lg shadow-xl min-w-[320px] {sizeClasses} max-h-[90vh] overflow-y-auto animate-[slideUp_0.3s_ease-out] md:animate-none"
|
|
54
66
|
>
|
|
55
67
|
<!-- Header -->
|
|
56
68
|
<div
|
|
@@ -60,7 +72,7 @@
|
|
|
60
72
|
<button
|
|
61
73
|
type="button"
|
|
62
74
|
onclick={closeModal}
|
|
63
|
-
class="text-gray-400 hover:text-gray-600 text-2xl"
|
|
75
|
+
class="text-gray-400 hover:text-gray-600 text-2xl cursor-pointer"
|
|
64
76
|
aria-label="Close"
|
|
65
77
|
>
|
|
66
78
|
×
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
</script>
|
|
32
32
|
|
|
33
33
|
<nav
|
|
34
|
-
class="bg-
|
|
34
|
+
class="bg-surface-elevated border-b border-border sticky top-0 z-50 {className}"
|
|
35
35
|
{...restProps}
|
|
36
36
|
>
|
|
37
37
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
{#if isMenuOpen}
|
|
82
82
|
<div class="md:hidden">
|
|
83
83
|
<div
|
|
84
|
-
class="px-2 pt-2 pb-3 space-y-1 sm:px-3 border-t border-
|
|
84
|
+
class="px-2 pt-2 pb-3 space-y-1 sm:px-3 border-t border-border"
|
|
85
85
|
>
|
|
86
86
|
{@render nav?.()}
|
|
87
87
|
<div class="pt-4">
|
|
@@ -7,13 +7,15 @@
|
|
|
7
7
|
}>;
|
|
8
8
|
currentPath?: string;
|
|
9
9
|
onclick?: (event: Event) => void;
|
|
10
|
+
className?: string;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
let {
|
|
13
14
|
variant = "header",
|
|
14
15
|
items = [],
|
|
15
16
|
currentPath = "",
|
|
16
|
-
|
|
17
|
+
onclick,
|
|
18
|
+
className = "",
|
|
17
19
|
...restProps
|
|
18
20
|
}: Props & { children?: any } = $props();
|
|
19
21
|
|
|
@@ -22,27 +24,37 @@
|
|
|
22
24
|
// Navigation is now handled by the parent component
|
|
23
25
|
// through event forwarding
|
|
24
26
|
}
|
|
27
|
+
|
|
28
|
+
// Derived class for ul container based on variant
|
|
29
|
+
const ulClasses = $derived(() => {
|
|
30
|
+
return variant === "sidebar"
|
|
31
|
+
? "flex flex-col space-y-2"
|
|
32
|
+
: "flex space-x-6";
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Function to get link classes based on active state
|
|
36
|
+
function getLinkClasses(itemHref: string): string {
|
|
37
|
+
const isActive = currentPath === itemHref;
|
|
38
|
+
const baseClasses = "px-3 py-2 text-sm font-medium rounded-md";
|
|
39
|
+
|
|
40
|
+
if (isActive) {
|
|
41
|
+
return `${baseClasses} text-body font-semibold`;
|
|
42
|
+
}
|
|
43
|
+
return `${baseClasses} text-description hover:text-body`;
|
|
44
|
+
}
|
|
25
45
|
</script>
|
|
26
46
|
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
onclick={(e) => handleClick(item, e)}
|
|
42
|
-
>
|
|
43
|
-
{item.label}
|
|
44
|
-
</a>
|
|
45
|
-
</li>
|
|
46
|
-
{/each}
|
|
47
|
-
</ul>
|
|
48
|
-
</nav>
|
|
47
|
+
<ul class="{ulClasses()} {className}" {...restProps}>
|
|
48
|
+
{#each items as item}
|
|
49
|
+
{@const linkClasses = getLinkClasses(item.href)}
|
|
50
|
+
<li>
|
|
51
|
+
<a
|
|
52
|
+
href={item.href}
|
|
53
|
+
class={linkClasses}
|
|
54
|
+
onclick={(e) => handleClick(item, e)}
|
|
55
|
+
>
|
|
56
|
+
{item.label}
|
|
57
|
+
</a>
|
|
58
|
+
</li>
|
|
59
|
+
{/each}
|
|
60
|
+
</ul>
|
package/dist/zabi-components.css
CHANGED
|
@@ -6,11 +6,18 @@
|
|
|
6
6
|
======================================== */
|
|
7
7
|
|
|
8
8
|
@theme {
|
|
9
|
-
/*
|
|
10
|
-
--
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
/* Typography - Nunito Sans font family */
|
|
10
|
+
--font-family-sans: 'Nunito Sans', ui-sans-serif, system-ui, sans-serif;
|
|
11
|
+
|
|
12
|
+
/* Surface Colors - Level-based naming with stone palette */
|
|
13
|
+
--color-surface-level-0: theme(colors.stone.50);
|
|
14
|
+
--color-surface-level-0-hover: theme(colors.stone.100);
|
|
15
|
+
--color-surface-level-1: theme(colors.stone.100);
|
|
16
|
+
--color-surface-level-1-hover: theme(colors.stone.200);
|
|
17
|
+
--color-surface-level-2: theme(colors.stone.200);
|
|
18
|
+
--color-surface-level-2-hover: theme(colors.stone.300);
|
|
13
19
|
--color-surface-elevated: theme(colors.white);
|
|
20
|
+
--color-surface-elevated-hover: theme(colors.stone.50);
|
|
14
21
|
--color-surface-hover: theme(colors.stone.100);
|
|
15
22
|
--color-surface-active: theme(colors.stone.200);
|
|
16
23
|
--color-surface-inverse: theme(colors.stone.900);
|
|
@@ -22,12 +29,12 @@
|
|
|
22
29
|
--color-background-tertiary: theme(colors.stone.100);
|
|
23
30
|
|
|
24
31
|
/* Page Colors */
|
|
25
|
-
--color-page: theme(colors.
|
|
26
|
-
--color-page-secondary: theme(colors.stone.
|
|
32
|
+
--color-page: theme(colors.stone.100);
|
|
33
|
+
--color-page-secondary: theme(colors.stone.200);
|
|
27
34
|
|
|
28
35
|
/* Card Colors */
|
|
29
36
|
--color-card: theme(colors.white);
|
|
30
|
-
--color-card-hover: theme(colors.stone.
|
|
37
|
+
--color-card-hover: theme(colors.stone.100);
|
|
31
38
|
--color-card-active: theme(colors.stone.100);
|
|
32
39
|
--color-card-elevated: theme(colors.white);
|
|
33
40
|
|
|
@@ -48,78 +55,76 @@
|
|
|
48
55
|
|
|
49
56
|
/* Border Colors */
|
|
50
57
|
--color-border: theme(colors.stone.200);
|
|
51
|
-
--color-border-
|
|
52
|
-
--color-border-
|
|
53
|
-
--color-border-
|
|
54
|
-
--color-border-disabled: theme(colors.stone.200);
|
|
58
|
+
--color-border-weak: theme(colors.stone.300);
|
|
59
|
+
--color-border-medium: theme(colors.stone.400);
|
|
60
|
+
--color-border-strong: theme(colors.stone.500);
|
|
55
61
|
|
|
56
62
|
/* Focus Colors */
|
|
57
63
|
--color-focus: theme(colors.blue.500);
|
|
58
|
-
--color-focus-
|
|
59
|
-
--color-focus-
|
|
60
|
-
--color-focus-
|
|
61
|
-
--color-focus-light: theme(colors.blue.50);
|
|
62
|
-
--color-focus-dark: theme(colors.blue.700);
|
|
63
|
-
--color-focus-surface: theme(colors.blue.50);
|
|
64
|
-
--color-focus-text: theme(colors.blue.700);
|
|
65
|
-
--color-focus-ring: theme(colors.blue.500);
|
|
66
|
-
--color-focus-ring-offset: theme(colors.white);
|
|
64
|
+
--color-focus-weak: theme(colors.blue.600);
|
|
65
|
+
--color-focus-medium: theme(colors.blue.700);
|
|
66
|
+
--color-focus-strong: theme(colors.blue.800);
|
|
67
67
|
|
|
68
68
|
/* Primary Colors */
|
|
69
69
|
--color-primary: theme(colors.blue.600);
|
|
70
|
-
--color-primary-
|
|
71
|
-
--color-primary-
|
|
72
|
-
--color-primary-
|
|
73
|
-
--color-primary-light: theme(colors.blue.100);
|
|
74
|
-
--color-primary-dark: theme(colors.blue.800);
|
|
70
|
+
--color-primary-weak: theme(colors.blue.700);
|
|
71
|
+
--color-primary-medium: theme(colors.blue.800);
|
|
72
|
+
--color-primary-strong: theme(colors.blue.900);
|
|
75
73
|
|
|
76
74
|
/* Secondary Colors */
|
|
77
75
|
--color-secondary: theme(colors.stone.600);
|
|
78
|
-
--color-secondary-
|
|
79
|
-
--color-secondary-
|
|
80
|
-
--color-secondary-
|
|
81
|
-
--color-secondary-light: theme(colors.stone.100);
|
|
82
|
-
--color-secondary-dark: theme(colors.stone.800);
|
|
76
|
+
--color-secondary-weak: theme(colors.stone.700);
|
|
77
|
+
--color-secondary-medium: theme(colors.stone.800);
|
|
78
|
+
--color-secondary-strong: theme(colors.stone.900);
|
|
83
79
|
|
|
84
80
|
/* Success Colors */
|
|
85
81
|
--color-success: theme(colors.green.600);
|
|
86
|
-
--color-success-
|
|
87
|
-
--color-success-
|
|
88
|
-
--color-success-
|
|
89
|
-
--color-success-light: theme(colors.green.100);
|
|
90
|
-
--color-success-dark: theme(colors.green.800);
|
|
91
|
-
--color-success-surface: theme(colors.green.100);
|
|
92
|
-
--color-success-text: theme(colors.green.800);
|
|
82
|
+
--color-success-weak: theme(colors.green.700);
|
|
83
|
+
--color-success-medium: theme(colors.green.800);
|
|
84
|
+
--color-success-strong: theme(colors.green.900);
|
|
93
85
|
|
|
94
86
|
/* Warning Colors */
|
|
95
87
|
--color-warning: theme(colors.yellow.600);
|
|
96
|
-
--color-warning-
|
|
97
|
-
--color-warning-
|
|
98
|
-
--color-warning-
|
|
99
|
-
--color-warning-light: theme(colors.yellow.100);
|
|
100
|
-
--color-warning-dark: theme(colors.yellow.800);
|
|
101
|
-
--color-warning-surface: theme(colors.yellow.100);
|
|
102
|
-
--color-warning-text: theme(colors.yellow.800);
|
|
88
|
+
--color-warning-weak: theme(colors.yellow.700);
|
|
89
|
+
--color-warning-medium: theme(colors.yellow.800);
|
|
90
|
+
--color-warning-strong: theme(colors.yellow.900);
|
|
103
91
|
|
|
104
92
|
/* Error Colors */
|
|
105
93
|
--color-error: theme(colors.red.600);
|
|
106
|
-
--color-error-
|
|
107
|
-
--color-error-
|
|
108
|
-
--color-error-
|
|
109
|
-
--color-error-light: theme(colors.red.100);
|
|
110
|
-
--color-error-dark: theme(colors.red.800);
|
|
111
|
-
--color-error-surface: theme(colors.red.100);
|
|
112
|
-
--color-error-text: theme(colors.red.800);
|
|
94
|
+
--color-error-weak: theme(colors.red.700);
|
|
95
|
+
--color-error-medium: theme(colors.red.800);
|
|
96
|
+
--color-error-strong: theme(colors.red.900);
|
|
113
97
|
|
|
114
98
|
/* Info Colors */
|
|
115
99
|
--color-info: theme(colors.blue.600);
|
|
116
|
-
--color-info-
|
|
117
|
-
--color-info-
|
|
118
|
-
--color-info-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
--color-
|
|
100
|
+
--color-info-weak: theme(colors.blue.700);
|
|
101
|
+
--color-info-medium: theme(colors.blue.800);
|
|
102
|
+
--color-info-strong: theme(colors.blue.900);
|
|
103
|
+
|
|
104
|
+
/* Action Colors - For interactive elements like buttons */
|
|
105
|
+
/* Primary Actions */
|
|
106
|
+
--color-action-primary: theme(colors.blue.600);
|
|
107
|
+
--color-action-primary-hover: theme(colors.blue.700);
|
|
108
|
+
--color-action-primary-active: theme(colors.blue.800);
|
|
109
|
+
--color-action-primary-disabled: theme(colors.blue.300);
|
|
110
|
+
--color-action-primary-subtle: theme(colors.blue.50);
|
|
111
|
+
--color-action-primary-subtle-hover: theme(colors.blue.100);
|
|
112
|
+
|
|
113
|
+
/* Secondary Actions */
|
|
114
|
+
--color-action-secondary: theme(colors.stone.600);
|
|
115
|
+
--color-action-secondary-hover: theme(colors.stone.700);
|
|
116
|
+
--color-action-secondary-active: theme(colors.stone.800);
|
|
117
|
+
--color-action-secondary-disabled: theme(colors.stone.300);
|
|
118
|
+
--color-action-secondary-subtle: theme(colors.stone.100);
|
|
119
|
+
--color-action-secondary-subtle-hover: theme(colors.stone.200);
|
|
120
|
+
|
|
121
|
+
/* Danger Actions */
|
|
122
|
+
--color-action-danger: theme(colors.red.600);
|
|
123
|
+
--color-action-danger-hover: theme(colors.red.700);
|
|
124
|
+
--color-action-danger-active: theme(colors.red.800);
|
|
125
|
+
--color-action-danger-disabled: theme(colors.red.300);
|
|
126
|
+
--color-action-danger-subtle: theme(colors.red.50);
|
|
127
|
+
--color-action-danger-subtle-hover: theme(colors.red.100);
|
|
123
128
|
|
|
124
129
|
/* Shadow Colors */
|
|
125
130
|
--shadow-color: 0 0 0;
|
|
@@ -154,15 +159,26 @@
|
|
|
154
159
|
--z-toast: 1080;
|
|
155
160
|
}
|
|
156
161
|
|
|
162
|
+
/* ========================================
|
|
163
|
+
BASE TYPOGRAPHY
|
|
164
|
+
======================================== */
|
|
165
|
+
body {
|
|
166
|
+
font-family: var(--font-family-sans);
|
|
167
|
+
}
|
|
168
|
+
|
|
157
169
|
/* ========================================
|
|
158
170
|
DARK MODE THEME
|
|
159
171
|
======================================== */
|
|
160
172
|
.dark {
|
|
161
173
|
/* Surface Colors - Dark mode variants */
|
|
162
|
-
--color-surface: theme(colors.stone.800);
|
|
163
|
-
--color-surface-
|
|
164
|
-
--color-surface-
|
|
174
|
+
--color-surface-level-0: theme(colors.stone.800);
|
|
175
|
+
--color-surface-level-0-hover: theme(colors.stone.700);
|
|
176
|
+
--color-surface-level-1: theme(colors.stone.700);
|
|
177
|
+
--color-surface-level-1-hover: theme(colors.stone.600);
|
|
178
|
+
--color-surface-level-2: theme(colors.stone.600);
|
|
179
|
+
--color-surface-level-2-hover: theme(colors.stone.500);
|
|
165
180
|
--color-surface-elevated: theme(colors.stone.800);
|
|
181
|
+
--color-surface-elevated-hover: theme(colors.stone.700);
|
|
166
182
|
--color-surface-hover: theme(colors.stone.700);
|
|
167
183
|
--color-surface-active: theme(colors.stone.600);
|
|
168
184
|
--color-surface-inverse: theme(colors.stone.100);
|
|
@@ -200,78 +216,78 @@
|
|
|
200
216
|
|
|
201
217
|
/* Border Colors */
|
|
202
218
|
--color-border: theme(colors.stone.600);
|
|
203
|
-
--color-border-
|
|
204
|
-
--color-border-
|
|
205
|
-
--color-border-
|
|
206
|
-
--color-border-disabled: theme(colors.stone.600);
|
|
219
|
+
--color-border-weak: theme(colors.stone.500);
|
|
220
|
+
--color-border-medium: theme(colors.stone.400);
|
|
221
|
+
--color-border-strong: theme(colors.stone.300);
|
|
207
222
|
|
|
208
223
|
/* Focus Colors */
|
|
209
224
|
--color-focus: theme(colors.blue.400);
|
|
210
|
-
--color-focus-
|
|
211
|
-
--color-focus-
|
|
225
|
+
--color-focus-weak: theme(colors.blue.500);
|
|
226
|
+
--color-focus-medium: theme(colors.blue.600);
|
|
227
|
+
--color-focus-strong: theme(colors.blue.700);
|
|
212
228
|
--color-focus-disabled: theme(colors.blue.600);
|
|
213
|
-
--color-focus-light: theme(colors.blue.900);
|
|
214
|
-
--color-focus-dark: theme(colors.blue.400);
|
|
215
|
-
--color-focus-surface: theme(colors.blue.900);
|
|
216
|
-
--color-focus-text: theme(colors.blue.400);
|
|
217
|
-
--color-focus-ring: theme(colors.blue.400);
|
|
218
|
-
--color-focus-ring-offset: theme(colors.stone.700);
|
|
219
229
|
|
|
220
230
|
/* Primary Colors */
|
|
221
231
|
--color-primary: theme(colors.blue.600);
|
|
222
|
-
--color-primary-
|
|
223
|
-
--color-primary-
|
|
224
|
-
--color-primary-
|
|
225
|
-
--color-primary-light: theme(colors.blue.100);
|
|
226
|
-
--color-primary-dark: theme(colors.blue.800);
|
|
232
|
+
--color-primary-weak: theme(colors.blue.700);
|
|
233
|
+
--color-primary-medium: theme(colors.blue.800);
|
|
234
|
+
--color-primary-strong: theme(colors.blue.900);
|
|
227
235
|
|
|
228
236
|
/* Secondary Colors */
|
|
229
237
|
--color-secondary: theme(colors.stone.600);
|
|
230
|
-
--color-secondary-
|
|
231
|
-
--color-secondary-
|
|
232
|
-
--color-secondary-
|
|
233
|
-
--color-secondary-light: theme(colors.stone.100);
|
|
234
|
-
--color-secondary-dark: theme(colors.stone.800);
|
|
238
|
+
--color-secondary-weak: theme(colors.stone.700);
|
|
239
|
+
--color-secondary-medium: theme(colors.stone.800);
|
|
240
|
+
--color-secondary-strong: theme(colors.stone.900);
|
|
235
241
|
|
|
236
242
|
/* Success Colors */
|
|
237
243
|
--color-success: theme(colors.green.600);
|
|
238
|
-
--color-success-
|
|
239
|
-
--color-success-
|
|
240
|
-
--color-success-
|
|
241
|
-
--color-success-light: theme(colors.green.100);
|
|
242
|
-
--color-success-dark: theme(colors.green.800);
|
|
243
|
-
--color-success-surface: theme(colors.green.100);
|
|
244
|
-
--color-success-text: theme(colors.green.800);
|
|
244
|
+
--color-success-weak: theme(colors.green.700);
|
|
245
|
+
--color-success-medium: theme(colors.green.800);
|
|
246
|
+
--color-success-strong: theme(colors.green.900);
|
|
245
247
|
|
|
246
248
|
/* Warning Colors */
|
|
247
249
|
--color-warning: theme(colors.yellow.600);
|
|
248
|
-
--color-warning-
|
|
249
|
-
--color-warning-
|
|
250
|
-
--color-warning-
|
|
251
|
-
--color-warning-light: theme(colors.yellow.100);
|
|
252
|
-
--color-warning-dark: theme(colors.yellow.800);
|
|
253
|
-
--color-warning-surface: theme(colors.yellow.100);
|
|
254
|
-
--color-warning-text: theme(colors.yellow.800);
|
|
250
|
+
--color-warning-weak: theme(colors.yellow.700);
|
|
251
|
+
--color-warning-medium: theme(colors.yellow.800);
|
|
252
|
+
--color-warning-strong: theme(colors.yellow.900);
|
|
255
253
|
|
|
256
254
|
/* Error Colors */
|
|
257
255
|
--color-error: theme(colors.red.600);
|
|
258
|
-
--color-error-
|
|
259
|
-
--color-error-
|
|
260
|
-
--color-error-
|
|
261
|
-
--color-error-light: theme(colors.red.100);
|
|
262
|
-
--color-error-dark: theme(colors.red.800);
|
|
263
|
-
--color-error-surface: theme(colors.red.100);
|
|
264
|
-
--color-error-text: theme(colors.red.800);
|
|
256
|
+
--color-error-weak: theme(colors.red.700);
|
|
257
|
+
--color-error-medium: theme(colors.red.800);
|
|
258
|
+
--color-error-strong: theme(colors.red.900);
|
|
265
259
|
|
|
266
260
|
/* Info Colors */
|
|
267
261
|
--color-info: theme(colors.blue.600);
|
|
268
|
-
--color-info-
|
|
262
|
+
--color-info-weak: theme(colors.blue.700);
|
|
269
263
|
--color-info-active: theme(colors.blue.800);
|
|
270
|
-
--color-info-
|
|
271
|
-
--color-info-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
264
|
+
--color-info-medium: theme(colors.blue.800);
|
|
265
|
+
--color-info-strong: theme(colors.blue.900);
|
|
266
|
+
|
|
267
|
+
/* Action Colors - Dark mode variants */
|
|
268
|
+
/* Primary Actions */
|
|
269
|
+
--color-action-primary: theme(colors.blue.500);
|
|
270
|
+
--color-action-primary-hover: theme(colors.blue.600);
|
|
271
|
+
--color-action-primary-active: theme(colors.blue.700);
|
|
272
|
+
--color-action-primary-disabled: theme(colors.blue.700);
|
|
273
|
+
--color-action-primary-subtle: theme(colors.blue.950);
|
|
274
|
+
--color-action-primary-subtle-hover: theme(colors.blue.900);
|
|
275
|
+
|
|
276
|
+
/* Secondary Actions */
|
|
277
|
+
--color-action-secondary: theme(colors.stone.500);
|
|
278
|
+
--color-action-secondary-hover: theme(colors.stone.600);
|
|
279
|
+
--color-action-secondary-active: theme(colors.stone.700);
|
|
280
|
+
--color-action-secondary-disabled: theme(colors.stone.700);
|
|
281
|
+
--color-action-secondary-subtle: theme(colors.stone.800);
|
|
282
|
+
--color-action-secondary-subtle-hover: theme(colors.stone.700);
|
|
283
|
+
|
|
284
|
+
/* Danger Actions */
|
|
285
|
+
--color-action-danger: theme(colors.red.500);
|
|
286
|
+
--color-action-danger-hover: theme(colors.red.600);
|
|
287
|
+
--color-action-danger-active: theme(colors.red.700);
|
|
288
|
+
--color-action-danger-disabled: theme(colors.red.700);
|
|
289
|
+
--color-action-danger-subtle: theme(colors.red.950);
|
|
290
|
+
--color-action-danger-subtle-hover: theme(colors.red.900);
|
|
275
291
|
|
|
276
292
|
/* Shadow Colors */
|
|
277
293
|
--shadow-opacity: 0.3;
|
|
@@ -286,27 +302,29 @@
|
|
|
286
302
|
======================================== */
|
|
287
303
|
|
|
288
304
|
/* Surface utilities */
|
|
289
|
-
.bg-surface {
|
|
290
|
-
background-color: var(--color-surface);
|
|
305
|
+
.bg-surface-level-0 {
|
|
306
|
+
background-color: var(--color-surface-level-0);
|
|
291
307
|
}
|
|
292
308
|
|
|
293
|
-
.bg-surface-
|
|
294
|
-
background-color: var(--color-surface-
|
|
309
|
+
.bg-surface-level-1 {
|
|
310
|
+
background-color: var(--color-surface-level-1);
|
|
295
311
|
}
|
|
296
312
|
|
|
297
|
-
.bg-surface-
|
|
298
|
-
background-color: var(--color-surface-
|
|
313
|
+
.bg-surface-level-2 {
|
|
314
|
+
background-color: var(--color-surface-level-2);
|
|
299
315
|
}
|
|
300
316
|
|
|
301
317
|
.bg-surface-elevated {
|
|
302
318
|
background-color: var(--color-surface-elevated);
|
|
303
319
|
}
|
|
304
320
|
|
|
305
|
-
|
|
321
|
+
/* Global hover effects removed - components should define their own hover states */
|
|
322
|
+
|
|
323
|
+
.bg-surface-hover {
|
|
306
324
|
background-color: var(--color-surface-hover);
|
|
307
325
|
}
|
|
308
326
|
|
|
309
|
-
.bg-surface-active
|
|
327
|
+
.bg-surface-active {
|
|
310
328
|
background-color: var(--color-surface-active);
|
|
311
329
|
}
|
|
312
330
|
|
|
@@ -396,4 +414,90 @@
|
|
|
396
414
|
.focus-outline {
|
|
397
415
|
outline: 2px solid var(--color-focus-ring);
|
|
398
416
|
outline-offset: 2px;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/* Action utilities - For interactive elements like buttons */
|
|
420
|
+
/* Primary Actions */
|
|
421
|
+
.bg-action-primary {
|
|
422
|
+
background-color: var(--color-action-primary);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.bg-action-primary:hover {
|
|
426
|
+
background-color: var(--color-action-primary-hover);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.bg-action-primary:active {
|
|
430
|
+
background-color: var(--color-action-primary-active);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.bg-action-primary:disabled {
|
|
434
|
+
background-color: var(--color-action-primary-disabled);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.bg-action-primary-subtle {
|
|
438
|
+
background-color: var(--color-action-primary-subtle);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.bg-action-primary-subtle:hover {
|
|
442
|
+
background-color: var(--color-action-primary-subtle-hover);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/* Secondary Actions */
|
|
446
|
+
.bg-action-secondary {
|
|
447
|
+
background-color: var(--color-action-secondary);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.bg-action-secondary:hover {
|
|
451
|
+
background-color: var(--color-action-secondary-hover);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.bg-action-secondary:active {
|
|
455
|
+
background-color: var(--color-action-secondary-active);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.bg-action-secondary:disabled {
|
|
459
|
+
background-color: var(--color-action-secondary-disabled);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.bg-action-secondary-subtle {
|
|
463
|
+
background-color: var(--color-action-secondary-subtle);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.bg-action-secondary-subtle:hover {
|
|
467
|
+
background-color: var(--color-action-secondary-subtle-hover);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/* Danger Actions */
|
|
471
|
+
.bg-action-danger {
|
|
472
|
+
background-color: var(--color-action-danger);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.bg-action-danger:hover {
|
|
476
|
+
background-color: var(--color-action-danger-hover);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.bg-action-danger:active {
|
|
480
|
+
background-color: var(--color-action-danger-active);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
.bg-action-danger:disabled {
|
|
484
|
+
background-color: var(--color-action-danger-disabled);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.bg-action-danger-subtle {
|
|
488
|
+
background-color: var(--color-action-danger-subtle);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.bg-action-danger-subtle:hover {
|
|
492
|
+
background-color: var(--color-action-danger-subtle-hover);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/* Modal Animation */
|
|
496
|
+
@keyframes slideUp {
|
|
497
|
+
from {
|
|
498
|
+
transform: translateY(100%);
|
|
499
|
+
}
|
|
500
|
+
to {
|
|
501
|
+
transform: translateY(0);
|
|
502
|
+
}
|
|
399
503
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zabi-components",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.7",
|
|
4
4
|
"description": "A modern Svelte 5 component library with TypeScript, Tailwind CSS v4, and 100% SSR-safe components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -80,19 +80,18 @@
|
|
|
80
80
|
"prepublishOnly": "npm run build:lib"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@storybook/
|
|
84
|
-
"@storybook/sveltekit": "^9.1.7",
|
|
83
|
+
"@storybook/sveltekit": "^9.1.15",
|
|
85
84
|
"@sveltejs/adapter-auto": "^7.0.0",
|
|
86
85
|
"@sveltejs/kit": "^2.47.2",
|
|
87
86
|
"@sveltejs/package": "^2.5.4",
|
|
88
87
|
"@sveltejs/vite-plugin-svelte": "^6.2.0",
|
|
88
|
+
"@tailwindcss/postcss": "^4.1.13",
|
|
89
89
|
"@tsconfig/svelte": "^5.0.5",
|
|
90
90
|
"@types/node": "^24.5.2",
|
|
91
91
|
"@types/react": "^19.2.2",
|
|
92
|
-
"@tailwindcss/postcss": "^4.1.13",
|
|
93
92
|
"autoprefixer": "^10.4.17",
|
|
94
93
|
"postcss": "^8.4.35",
|
|
95
|
-
"storybook": "^9.1.
|
|
94
|
+
"storybook": "^9.1.15",
|
|
96
95
|
"svelte": "^5.38.10",
|
|
97
96
|
"svelte-check": "^4.3.1",
|
|
98
97
|
"tailwindcss": "^4.1.13",
|