zabi-components 5.0.20 → 5.0.22
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/LICENSE +21 -0
- package/README.md +355 -81
- package/dist/atoms/Button.svelte +1 -1
- package/dist/atoms/CardContent.svelte +1 -1
- package/dist/atoms/CardHeader.svelte +1 -1
- package/dist/atoms/Checkbox.svelte +1 -7
- package/dist/atoms/CodeBlock.svelte +6 -6
- package/dist/atoms/ColorPicker.svelte +80 -72
- package/dist/atoms/IconButton.svelte +88 -0
- package/dist/atoms/IconButton.svelte.d.ts +21 -0
- package/dist/atoms/Input.svelte +14 -10
- package/dist/atoms/Input.svelte.d.ts +2 -0
- package/dist/atoms/List.svelte +47 -0
- package/dist/atoms/List.svelte.d.ts +19 -0
- package/dist/atoms/ListItem.svelte +148 -0
- package/dist/atoms/ListItem.svelte.d.ts +35 -0
- package/dist/atoms/Progress.svelte +3 -5
- package/dist/atoms/Select.svelte +152 -19
- package/dist/atoms/Select.svelte.d.ts +23 -1
- package/dist/atoms/Textarea.svelte +11 -9
- package/dist/atoms/Textarea.svelte.d.ts +1 -0
- package/dist/atoms/Toggle.svelte +1 -7
- package/dist/atoms/Tooltip.svelte +8 -15
- package/dist/atoms/index.d.ts +3 -0
- package/dist/atoms/index.js +3 -0
- package/dist/components/atoms/index.d.ts +3 -0
- package/dist/components/atoms/index.d.ts.map +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/molecules/index.d.ts +1 -1
- package/dist/components/molecules/navigation-menu-context.d.ts +7 -0
- package/dist/components/molecules/navigation-menu-context.d.ts.map +1 -0
- package/dist/components/organisms/index.d.ts +2 -0
- package/dist/components/organisms/index.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +5 -8
- package/dist/molecules/Alert.svelte +8 -3
- package/dist/molecules/ContactForm.svelte +63 -31
- package/dist/molecules/ContactForm.svelte.d.ts +1 -4
- package/dist/molecules/Dropdown.svelte +2 -1
- package/dist/molecules/ImageUpload.svelte +26 -3
- package/dist/molecules/ImageUpload.svelte.d.ts +1 -0
- package/dist/molecules/Modal.svelte +44 -43
- package/dist/molecules/NavigationMenu.svelte +7 -10
- package/dist/molecules/NavigationMenuContent.svelte +8 -8
- package/dist/molecules/NavigationMenuItem.svelte +7 -6
- package/dist/molecules/NavigationMenuLink.svelte +7 -5
- package/dist/molecules/NavigationMenuList.svelte +0 -7
- package/dist/molecules/NavigationMenuTrigger.svelte +7 -7
- package/dist/molecules/Section.svelte +158 -0
- package/dist/molecules/Section.svelte.d.ts +27 -0
- package/dist/molecules/SlideUp.svelte +30 -0
- package/dist/molecules/Tabs.svelte +71 -4
- package/dist/molecules/index.d.ts +1 -1
- package/dist/molecules/index.js +1 -1
- package/dist/molecules/navigation-menu-context.d.ts +6 -0
- package/dist/molecules/navigation-menu-context.js +1 -0
- package/dist/organisms/Navigation.svelte +9 -6
- package/dist/organisms/Navigation.svelte.d.ts +1 -0
- package/dist/organisms/SidebarNavigation.svelte +420 -0
- package/dist/organisms/SidebarNavigation.svelte.d.ts +44 -0
- package/dist/organisms/SidebarProjectPanel.svelte +174 -0
- package/dist/organisms/SidebarProjectPanel.svelte.d.ts +32 -0
- package/dist/organisms/index.d.ts +2 -0
- package/dist/organisms/index.js +2 -0
- package/dist/zabi-components.css +412 -0
- package/package.json +7 -8
- package/dist/molecules/Sidebar.svelte +0 -324
- package/dist/molecules/Sidebar.svelte.d.ts +0 -30
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { default as Toggle } from './Toggle.svelte';
|
|
2
2
|
export { default as Badge } from './Badge.svelte';
|
|
3
3
|
export { default as Button } from './Button.svelte';
|
|
4
|
+
export { default as IconButton } from './IconButton.svelte';
|
|
4
5
|
export { default as Card } from './Card.svelte';
|
|
5
6
|
export { default as CardHeader } from './CardHeader.svelte';
|
|
6
7
|
export { default as CardContent } from './CardContent.svelte';
|
|
@@ -9,6 +10,8 @@ export { default as Input } from './Input.svelte';
|
|
|
9
10
|
export { default as Textarea } from './Textarea.svelte';
|
|
10
11
|
export { default as Select } from './Select.svelte';
|
|
11
12
|
export { default as ColorPicker } from './ColorPicker.svelte';
|
|
13
|
+
export { default as List } from './List.svelte';
|
|
14
|
+
export { default as ListItem } from './ListItem.svelte';
|
|
12
15
|
export { default as Heading } from './Heading.svelte';
|
|
13
16
|
export { default as ThemeToggle } from './ThemeToggle.svelte';
|
|
14
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/atoms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/atoms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -6,6 +6,8 @@ export { default as Input } from './atoms/Input.svelte';
|
|
|
6
6
|
export { default as Textarea } from './atoms/Textarea.svelte';
|
|
7
7
|
export { default as Select } from './atoms/Select.svelte';
|
|
8
8
|
export { default as ColorPicker } from './atoms/ColorPicker.svelte';
|
|
9
|
+
export { default as List } from './atoms/List.svelte';
|
|
10
|
+
export { default as ListItem } from './atoms/ListItem.svelte';
|
|
9
11
|
export { default as Heading } from './atoms/Heading.svelte';
|
|
10
12
|
export { default as ThemeToggle } from './atoms/ThemeToggle.svelte';
|
|
11
13
|
export { default as Alert } from './molecules/Alert.svelte';
|
|
@@ -19,6 +21,8 @@ export { default as SlideUp } from './molecules/SlideUp.svelte';
|
|
|
19
21
|
export { default as Tabs } from './molecules/Tabs.svelte';
|
|
20
22
|
export { default as Navbar } from './organisms/Navbar.svelte';
|
|
21
23
|
export { default as Navigation } from './organisms/Navigation.svelte';
|
|
24
|
+
export { default as SidebarNavigation } from './organisms/SidebarNavigation.svelte';
|
|
25
|
+
export { default as SidebarProjectPanel } from './organisms/SidebarProjectPanel.svelte';
|
|
22
26
|
export declare const createId: (prefix?: string) => string;
|
|
23
27
|
export declare const cn: (...classes: (string | undefined | null | false)[]) => string;
|
|
24
28
|
export declare const getFormData: (form: HTMLFormElement) => Record<string, any>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEpE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ export { default as NavigationMenuItem } from './NavigationMenuItem.svelte';
|
|
|
11
11
|
export { default as NavigationMenuTrigger } from './NavigationMenuTrigger.svelte';
|
|
12
12
|
export { default as NavigationMenuContent } from './NavigationMenuContent.svelte';
|
|
13
13
|
export { default as NavigationMenuLink } from './NavigationMenuLink.svelte';
|
|
14
|
-
export { default as
|
|
14
|
+
export { default as Section } from './Section.svelte';
|
|
15
15
|
export { default as SlideUp } from './SlideUp.svelte';
|
|
16
16
|
export { default as Tabs } from './Tabs.svelte';
|
|
17
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface NavigationMenuContextValue {
|
|
2
|
+
activeItem: string | null;
|
|
3
|
+
setActiveItem: (item: string | null) => void;
|
|
4
|
+
isMobile: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare const NAVIGATION_MENU_CONTEXT_KEY: unique symbol;
|
|
7
|
+
//# sourceMappingURL=navigation-menu-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-menu-context.d.ts","sourceRoot":"","sources":["../../../src/components/molecules/navigation-menu-context.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,0BAA0B;IACvC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,QAAQ,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,2BAA2B,eAA4B,CAAC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { default as Navbar } from './Navbar.svelte';
|
|
2
2
|
export { default as Navigation } from './Navigation.svelte';
|
|
3
|
+
export { default as SidebarNavigation } from './SidebarNavigation.svelte';
|
|
4
|
+
export { default as SidebarProjectPanel } from './SidebarProjectPanel.svelte';
|
|
3
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/organisms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/organisms/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export { default as Input } from './atoms/Input.svelte';
|
|
|
6
6
|
export { default as Textarea } from './atoms/Textarea.svelte';
|
|
7
7
|
export { default as Select } from './atoms/Select.svelte';
|
|
8
8
|
export { default as ColorPicker } from './atoms/ColorPicker.svelte';
|
|
9
|
+
export { default as List } from './atoms/List.svelte';
|
|
10
|
+
export { default as ListItem } from './atoms/ListItem.svelte';
|
|
9
11
|
export { default as Heading } from './atoms/Heading.svelte';
|
|
10
12
|
export { default as ThemeToggle } from './atoms/ThemeToggle.svelte';
|
|
11
13
|
export { default as Alert } from './molecules/Alert.svelte';
|
|
@@ -19,6 +21,8 @@ export { default as SlideUp } from './molecules/SlideUp.svelte';
|
|
|
19
21
|
export { default as Tabs } from './molecules/Tabs.svelte';
|
|
20
22
|
export { default as Navbar } from './organisms/Navbar.svelte';
|
|
21
23
|
export { default as Navigation } from './organisms/Navigation.svelte';
|
|
24
|
+
export { default as SidebarNavigation } from './organisms/SidebarNavigation.svelte';
|
|
25
|
+
export { default as SidebarProjectPanel } from './organisms/SidebarProjectPanel.svelte';
|
|
22
26
|
export declare const createId: (prefix?: string) => string;
|
|
23
27
|
export declare const cn: (...classes: (string | undefined | null | false)[]) => string;
|
|
24
28
|
export declare const getFormData: (form: HTMLFormElement) => Record<string, any>;
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ export { default as Input } from './atoms/Input.svelte';
|
|
|
6
6
|
export { default as Textarea } from './atoms/Textarea.svelte';
|
|
7
7
|
export { default as Select } from './atoms/Select.svelte';
|
|
8
8
|
export { default as ColorPicker } from './atoms/ColorPicker.svelte';
|
|
9
|
+
export { default as List } from './atoms/List.svelte';
|
|
10
|
+
export { default as ListItem } from './atoms/ListItem.svelte';
|
|
9
11
|
export { default as Heading } from './atoms/Heading.svelte';
|
|
10
12
|
export { default as ThemeToggle } from './atoms/ThemeToggle.svelte';
|
|
11
13
|
export { default as Alert } from './molecules/Alert.svelte';
|
|
@@ -19,14 +21,9 @@ export { default as SlideUp } from './molecules/SlideUp.svelte';
|
|
|
19
21
|
export { default as Tabs } from './molecules/Tabs.svelte';
|
|
20
22
|
export { default as Navbar } from './organisms/Navbar.svelte';
|
|
21
23
|
export { default as Navigation } from './organisms/Navigation.svelte';
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
return `${prefix}-ssr-${Date.now()}`;
|
|
28
|
-
}
|
|
29
|
-
};
|
|
24
|
+
export { default as SidebarNavigation } from './organisms/SidebarNavigation.svelte';
|
|
25
|
+
export { default as SidebarProjectPanel } from './organisms/SidebarProjectPanel.svelte';
|
|
26
|
+
export const createId = (prefix = 'id') => generateId(prefix);
|
|
30
27
|
export const cn = (...classes) => classes.filter(Boolean).join(' ');
|
|
31
28
|
export const getFormData = (form) => {
|
|
32
29
|
const formData = new FormData(form);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { ExtendedSemanticVariant } from "../../types/variants.js";
|
|
3
|
+
type AlertVisualVariant = Exclude<ExtendedSemanticVariant, "default">;
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
variant?: ExtendedSemanticVariant;
|
|
@@ -27,6 +28,10 @@
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
const visualVariant = $derived<AlertVisualVariant>(
|
|
32
|
+
variant === "default" ? "info" : variant,
|
|
33
|
+
);
|
|
34
|
+
|
|
30
35
|
let alertClasses = $derived({
|
|
31
36
|
info: "text-info border border-info",
|
|
32
37
|
success: "text-success border border-success",
|
|
@@ -64,10 +69,10 @@
|
|
|
64
69
|
|
|
65
70
|
<div
|
|
66
71
|
class="relative rounded-md p-4 border {alertClasses[
|
|
67
|
-
|
|
72
|
+
visualVariant
|
|
68
73
|
]} transition-all duration-200 motion-reduce:transition-none {className}"
|
|
69
74
|
role={alertRole}
|
|
70
|
-
aria-live={
|
|
75
|
+
aria-live={visualVariant === "success" || visualVariant === "info"
|
|
71
76
|
? "polite"
|
|
72
77
|
: "assertive"}
|
|
73
78
|
aria-atomic="true"
|
|
@@ -98,7 +103,7 @@
|
|
|
98
103
|
|
|
99
104
|
<div class="flex items-start gap-3 {closable ? 'pr-8' : ''}">
|
|
100
105
|
<div class="shrink-0 mt-0.5">
|
|
101
|
-
{@html iconSvg[
|
|
106
|
+
{@html iconSvg[visualVariant]}
|
|
102
107
|
</div>
|
|
103
108
|
|
|
104
109
|
<div class="flex-1 min-w-0">
|
|
@@ -14,9 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
let {
|
|
16
16
|
className = "",
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
} = $props<Props & { children?: any }>();
|
|
17
|
+
onsubmit,
|
|
18
|
+
}: Props = $props();
|
|
20
19
|
|
|
21
20
|
let formData = $state<ContactFormData>({
|
|
22
21
|
name: "",
|
|
@@ -25,21 +24,65 @@
|
|
|
25
24
|
subscribe: false,
|
|
26
25
|
});
|
|
27
26
|
|
|
27
|
+
let fieldErrors = $state<Partial<Record<keyof ContactFormData, string>>>({});
|
|
28
|
+
let formErrorMessage = $state("");
|
|
29
|
+
|
|
30
|
+
function validate(data: ContactFormData) {
|
|
31
|
+
const nextErrors: Partial<Record<keyof ContactFormData, string>> = {};
|
|
32
|
+
|
|
33
|
+
if (!data.name.trim()) {
|
|
34
|
+
nextErrors.name = "Please enter your name.";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!data.email.trim()) {
|
|
38
|
+
nextErrors.email = "Please enter your email address.";
|
|
39
|
+
} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
|
|
40
|
+
nextErrors.email = "Please enter a valid email address.";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!(data.message || "").trim()) {
|
|
44
|
+
nextErrors.message = "Please enter a message.";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fieldErrors = nextErrors;
|
|
48
|
+
return Object.keys(nextErrors).length === 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
28
51
|
function handleFormSubmit(event: SubmitEvent) {
|
|
29
|
-
const
|
|
52
|
+
const submittedFormData = new FormData(event.target as HTMLFormElement);
|
|
30
53
|
const data: ContactFormData = {
|
|
31
|
-
name: (
|
|
32
|
-
email: (
|
|
33
|
-
message: (
|
|
34
|
-
subscribe:
|
|
54
|
+
name: (submittedFormData.get("name") as string) || "",
|
|
55
|
+
email: (submittedFormData.get("email") as string) || "",
|
|
56
|
+
message: (submittedFormData.get("message") as string) || "",
|
|
57
|
+
subscribe: submittedFormData.get("subscribe") === "on" || false,
|
|
35
58
|
};
|
|
36
59
|
|
|
37
|
-
|
|
60
|
+
if (!validate(data)) {
|
|
61
|
+
formErrorMessage =
|
|
62
|
+
"We could not submit your request. Fix the highlighted fields and try again.";
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
formErrorMessage = "";
|
|
67
|
+
if (onsubmit) {
|
|
68
|
+
onsubmit(event);
|
|
69
|
+
}
|
|
38
70
|
}
|
|
39
71
|
</script>
|
|
40
72
|
|
|
41
|
-
<
|
|
42
|
-
<
|
|
73
|
+
<div class={className}>
|
|
74
|
+
<Card size="md" fullWidth={true} title="Get in Touch">
|
|
75
|
+
<Form onsubmit={handleFormSubmit} className="space-y-4">
|
|
76
|
+
{#if formErrorMessage}
|
|
77
|
+
<div
|
|
78
|
+
class="rounded-lg border border-error px-4 py-3 text-sm text-error"
|
|
79
|
+
role="alert"
|
|
80
|
+
>
|
|
81
|
+
<p class="font-medium">Something went wrong</p>
|
|
82
|
+
<p>{formErrorMessage}</p>
|
|
83
|
+
<p class="mt-1">Recovery action: review your inputs and resubmit.</p>
|
|
84
|
+
</div>
|
|
85
|
+
{/if}
|
|
43
86
|
<div class="space-y-4">
|
|
44
87
|
<Input
|
|
45
88
|
type="text"
|
|
@@ -49,6 +92,8 @@
|
|
|
49
92
|
value={formData.name}
|
|
50
93
|
oninput={(e) =>
|
|
51
94
|
(formData.name = (e.target as HTMLInputElement).value)}
|
|
95
|
+
variant={fieldErrors.name ? "error" : "default"}
|
|
96
|
+
message={fieldErrors.name || ""}
|
|
52
97
|
/>
|
|
53
98
|
<Input
|
|
54
99
|
type="email"
|
|
@@ -58,24 +103,8 @@
|
|
|
58
103
|
value={formData.email}
|
|
59
104
|
oninput={(e) =>
|
|
60
105
|
(formData.email = (e.target as HTMLInputElement).value)}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
type="email"
|
|
64
|
-
name="email"
|
|
65
|
-
label="Email"
|
|
66
|
-
placeholder="Enter your email"
|
|
67
|
-
value={formData.email}
|
|
68
|
-
oninput={(e) =>
|
|
69
|
-
(formData.email = (e.target as HTMLInputElement).value)}
|
|
70
|
-
/>
|
|
71
|
-
<Input
|
|
72
|
-
type="email"
|
|
73
|
-
name="email"
|
|
74
|
-
label="Email"
|
|
75
|
-
placeholder="Enter your email"
|
|
76
|
-
value={formData.email}
|
|
77
|
-
oninput={(e) =>
|
|
78
|
-
(formData.email = (e.target as HTMLInputElement).value)}
|
|
106
|
+
variant={fieldErrors.email ? "error" : "default"}
|
|
107
|
+
message={fieldErrors.email || ""}
|
|
79
108
|
/>
|
|
80
109
|
<Textarea
|
|
81
110
|
name="message"
|
|
@@ -87,6 +116,8 @@
|
|
|
87
116
|
(formData.message = (
|
|
88
117
|
e.target as HTMLTextAreaElement
|
|
89
118
|
).value)}
|
|
119
|
+
variant={fieldErrors.message ? "error" : "default"}
|
|
120
|
+
message={fieldErrors.message || ""}
|
|
90
121
|
/>
|
|
91
122
|
<Checkbox
|
|
92
123
|
name="subscribe"
|
|
@@ -103,5 +134,6 @@
|
|
|
103
134
|
Send Message
|
|
104
135
|
</Button>
|
|
105
136
|
</div>
|
|
106
|
-
|
|
107
|
-
</Card>
|
|
137
|
+
</Form>
|
|
138
|
+
</Card>
|
|
139
|
+
</div>
|
|
@@ -2,9 +2,6 @@ interface Props {
|
|
|
2
2
|
className?: string;
|
|
3
3
|
onsubmit?: (event: SubmitEvent) => void;
|
|
4
4
|
}
|
|
5
|
-
|
|
6
|
-
children?: any;
|
|
7
|
-
};
|
|
8
|
-
declare const ContactForm: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
5
|
+
declare const ContactForm: import("svelte").Component<Props, {}, "">;
|
|
9
6
|
type ContactForm = ReturnType<typeof ContactForm>;
|
|
10
7
|
export default ContactForm;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import Button from "../atoms/Button.svelte";
|
|
3
|
+
import { generateId } from "../../routes/lib/ssr-safe.js";
|
|
3
4
|
|
|
4
5
|
interface Props {
|
|
5
6
|
isOpen?: boolean;
|
|
@@ -26,7 +27,7 @@
|
|
|
26
27
|
...restProps
|
|
27
28
|
}: Props & { children?: any; trigger?: any } = $props();
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
const dropdownId = generateId("dropdown");
|
|
30
31
|
let triggerElement = $state<HTMLElement | null>(null);
|
|
31
32
|
let menuElement = $state<HTMLElement | null>(null);
|
|
32
33
|
let openedViaKeyboard = $state(false);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { onDestroy } from "svelte";
|
|
2
3
|
import Button from "../atoms/Button.svelte";
|
|
3
4
|
import { Image } from "@lucide/svelte";
|
|
4
5
|
|
|
@@ -7,6 +8,7 @@
|
|
|
7
8
|
disabled?: boolean;
|
|
8
9
|
accept?: string;
|
|
9
10
|
placeholder?: string;
|
|
11
|
+
errorMessage?: string;
|
|
10
12
|
onchange?: (event: Event) => void;
|
|
11
13
|
onclick?: (event: Event) => void;
|
|
12
14
|
}
|
|
@@ -16,11 +18,20 @@
|
|
|
16
18
|
disabled = false,
|
|
17
19
|
accept = "image/*",
|
|
18
20
|
placeholder = "No image selected",
|
|
21
|
+
errorMessage = "",
|
|
19
22
|
children,
|
|
20
23
|
...restProps
|
|
21
24
|
} = $props<Props & { children?: any }>();
|
|
22
25
|
|
|
23
26
|
let fileInput = $state<HTMLInputElement>();
|
|
27
|
+
let currentObjectUrl = $state<string | null>(null);
|
|
28
|
+
|
|
29
|
+
function revokeCurrentObjectUrl() {
|
|
30
|
+
if (currentObjectUrl && typeof URL !== "undefined" && URL.revokeObjectURL) {
|
|
31
|
+
URL.revokeObjectURL(currentObjectUrl);
|
|
32
|
+
currentObjectUrl = null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
24
35
|
|
|
25
36
|
function handleFileSelect(event: Event) {
|
|
26
37
|
if (disabled) return;
|
|
@@ -31,17 +42,17 @@
|
|
|
31
42
|
const file = input.files[0];
|
|
32
43
|
|
|
33
44
|
if (typeof URL !== "undefined" && URL.createObjectURL) {
|
|
45
|
+
revokeCurrentObjectUrl();
|
|
34
46
|
const url = URL.createObjectURL(file);
|
|
35
47
|
value = url;
|
|
48
|
+
currentObjectUrl = url;
|
|
36
49
|
}
|
|
37
50
|
}
|
|
38
51
|
|
|
39
52
|
function removeImage() {
|
|
40
53
|
if (disabled) return;
|
|
41
54
|
|
|
42
|
-
|
|
43
|
-
URL.revokeObjectURL(value);
|
|
44
|
-
}
|
|
55
|
+
revokeCurrentObjectUrl();
|
|
45
56
|
value = null;
|
|
46
57
|
}
|
|
47
58
|
|
|
@@ -49,6 +60,10 @@
|
|
|
49
60
|
if (disabled) return;
|
|
50
61
|
fileInput?.click();
|
|
51
62
|
}
|
|
63
|
+
|
|
64
|
+
onDestroy(() => {
|
|
65
|
+
revokeCurrentObjectUrl();
|
|
66
|
+
});
|
|
52
67
|
</script>
|
|
53
68
|
|
|
54
69
|
<div class="space-y-3">
|
|
@@ -118,4 +133,12 @@
|
|
|
118
133
|
{disabled}
|
|
119
134
|
class="hidden"
|
|
120
135
|
/>
|
|
136
|
+
|
|
137
|
+
{#if errorMessage}
|
|
138
|
+
<div class="rounded-lg border border-error px-3 py-2 text-sm text-error" role="alert">
|
|
139
|
+
<p class="font-medium">Image upload failed</p>
|
|
140
|
+
<p>{errorMessage}</p>
|
|
141
|
+
<p class="mt-1">Recovery action: try another file or retry upload.</p>
|
|
142
|
+
</div>
|
|
143
|
+
{/if}
|
|
121
144
|
</div>
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
...restProps
|
|
29
29
|
}: Props & { children?: any; footer?: any } = $props();
|
|
30
30
|
|
|
31
|
-
let modalContainer
|
|
31
|
+
let modalContainer = $state<HTMLDivElement>();
|
|
32
32
|
let cleanupFocusTrap: (() => void) | null = null;
|
|
33
33
|
|
|
34
34
|
const sizeClasses = $derived(
|
|
@@ -53,12 +53,13 @@
|
|
|
53
53
|
|
|
54
54
|
// Handle focus trap when modal opens
|
|
55
55
|
$effect(() => {
|
|
56
|
-
|
|
56
|
+
const container = modalContainer;
|
|
57
|
+
if (isOpen && container) {
|
|
57
58
|
saveFocus();
|
|
58
|
-
cleanupFocusTrap = trapFocus(
|
|
59
|
+
cleanupFocusTrap = trapFocus(container);
|
|
59
60
|
// Small delay to ensure modal is rendered
|
|
60
61
|
setTimeout(() => {
|
|
61
|
-
focusFirstElement(
|
|
62
|
+
focusFirstElement(container);
|
|
62
63
|
}, 0);
|
|
63
64
|
} else if (!isOpen && cleanupFocusTrap) {
|
|
64
65
|
cleanupFocusTrap();
|
|
@@ -93,49 +94,49 @@
|
|
|
93
94
|
aria-labelledby={title ? "modal-title" : undefined}
|
|
94
95
|
tabindex="-1"
|
|
95
96
|
>
|
|
96
|
-
<
|
|
97
|
+
<div
|
|
97
98
|
bind:this={modalContainer}
|
|
98
|
-
variant="default"
|
|
99
|
-
fullWidth={false}
|
|
100
99
|
class="bg-card rounded-t-3xl md:rounded-3xl shadow-xl min-w-[320px] {sizeClasses} max-h-[90vh] overflow-y-auto animate-[slideUp_0.3s_ease-out] md:animate-none flex flex-col p-0"
|
|
101
100
|
>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
<
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
101
|
+
<Card variant="default" fullWidth={false}>
|
|
102
|
+
{#if title || description}
|
|
103
|
+
<CardHeader
|
|
104
|
+
{description}
|
|
105
|
+
className="px-6 pt-6 pb-4"
|
|
106
|
+
>
|
|
107
|
+
{#if title}
|
|
108
|
+
<div class="flex items-center justify-between">
|
|
109
|
+
<h2
|
|
110
|
+
id="modal-title"
|
|
111
|
+
class="text-2xl font-normal leading-8 text-headline tracking-normal"
|
|
112
|
+
>
|
|
113
|
+
{title}
|
|
114
|
+
</h2>
|
|
115
|
+
<button
|
|
116
|
+
type="button"
|
|
117
|
+
onclick={closeModal}
|
|
118
|
+
class="text-description hover:text-headline text-2xl cursor-pointer transition-colors w-8 h-8 flex items-center justify-center rounded-full hover:bg-base-100"
|
|
119
|
+
aria-label="Close"
|
|
120
|
+
>
|
|
121
|
+
×
|
|
122
|
+
</button>
|
|
123
|
+
</div>
|
|
124
|
+
{/if}
|
|
125
|
+
</CardHeader>
|
|
126
|
+
{/if}
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
128
|
+
{#if children}
|
|
129
|
+
<CardContent className="flex-1">
|
|
130
|
+
{@render children?.()}
|
|
131
|
+
</CardContent>
|
|
132
|
+
{/if}
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
134
|
+
{#if footer}
|
|
135
|
+
<CardFooter className="flex justify-end gap-3 pt-4">
|
|
136
|
+
{@render footer?.()}
|
|
137
|
+
</CardFooter>
|
|
138
|
+
{/if}
|
|
139
|
+
</Card>
|
|
140
|
+
</div>
|
|
140
141
|
</div>
|
|
141
142
|
{/if}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
|
-
import {
|
|
3
|
+
import { setContext } from "svelte";
|
|
4
4
|
import { onMount } from "svelte";
|
|
5
5
|
import NavigationMenuList from "./NavigationMenuList.svelte";
|
|
6
6
|
import NavigationMenuItem from "./NavigationMenuItem.svelte";
|
|
@@ -8,13 +8,10 @@
|
|
|
8
8
|
import NavigationMenuContent from "./NavigationMenuContent.svelte";
|
|
9
9
|
import NavigationMenuLink from "./NavigationMenuLink.svelte";
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const NAVIGATION_MENU_CONTEXT = Symbol("navigation-menu");
|
|
11
|
+
import {
|
|
12
|
+
NAVIGATION_MENU_CONTEXT_KEY,
|
|
13
|
+
type NavigationMenuContextValue,
|
|
14
|
+
} from "./navigation-menu-context.js";
|
|
18
15
|
|
|
19
16
|
export interface NavigationMenuItemData {
|
|
20
17
|
value: string;
|
|
@@ -76,7 +73,7 @@
|
|
|
76
73
|
}
|
|
77
74
|
});
|
|
78
75
|
|
|
79
|
-
const context:
|
|
76
|
+
const context: NavigationMenuContextValue = {
|
|
80
77
|
get activeItem() {
|
|
81
78
|
return activeItem;
|
|
82
79
|
},
|
|
@@ -86,7 +83,7 @@
|
|
|
86
83
|
},
|
|
87
84
|
};
|
|
88
85
|
|
|
89
|
-
setContext(
|
|
86
|
+
setContext(NAVIGATION_MENU_CONTEXT_KEY, context);
|
|
90
87
|
</script>
|
|
91
88
|
|
|
92
89
|
<nav
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
3
|
import { getContext } from "svelte";
|
|
4
|
-
import { onMount
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
import { onMount } from "svelte";
|
|
5
|
+
import {
|
|
6
|
+
NAVIGATION_MENU_CONTEXT_KEY,
|
|
7
|
+
type NavigationMenuContextValue,
|
|
8
|
+
} from "./navigation-menu-context.js";
|
|
7
9
|
|
|
8
10
|
interface Props {
|
|
9
11
|
value?: string;
|
|
@@ -21,11 +23,9 @@
|
|
|
21
23
|
let contentElement = $state<HTMLElement | null>(null);
|
|
22
24
|
let parentItem = $state<HTMLElement | null>(null);
|
|
23
25
|
|
|
24
|
-
const context = getContext<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
isMobile: boolean;
|
|
28
|
-
}>(NAVIGATION_MENU_CONTEXT);
|
|
26
|
+
const context = getContext<NavigationMenuContextValue>(
|
|
27
|
+
NAVIGATION_MENU_CONTEXT_KEY,
|
|
28
|
+
);
|
|
29
29
|
|
|
30
30
|
const isActive = $derived(context?.activeItem === value);
|
|
31
31
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from "svelte";
|
|
3
3
|
import { getContext } from "svelte";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
NAVIGATION_MENU_CONTEXT_KEY,
|
|
6
|
+
type NavigationMenuContextValue,
|
|
7
|
+
} from "./navigation-menu-context.js";
|
|
6
8
|
|
|
7
9
|
interface Props {
|
|
8
10
|
value?: string;
|
|
@@ -17,10 +19,9 @@
|
|
|
17
19
|
...restProps
|
|
18
20
|
}: Props = $props();
|
|
19
21
|
|
|
20
|
-
const context = getContext<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}>(NAVIGATION_MENU_CONTEXT);
|
|
22
|
+
const context = getContext<NavigationMenuContextValue>(
|
|
23
|
+
NAVIGATION_MENU_CONTEXT_KEY,
|
|
24
|
+
);
|
|
24
25
|
|
|
25
26
|
const isActive = $derived(context?.activeItem === value);
|
|
26
27
|
</script>
|