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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +355 -81
  3. package/dist/atoms/Button.svelte +1 -1
  4. package/dist/atoms/CardContent.svelte +1 -1
  5. package/dist/atoms/CardHeader.svelte +1 -1
  6. package/dist/atoms/Checkbox.svelte +1 -7
  7. package/dist/atoms/CodeBlock.svelte +6 -6
  8. package/dist/atoms/ColorPicker.svelte +80 -72
  9. package/dist/atoms/IconButton.svelte +88 -0
  10. package/dist/atoms/IconButton.svelte.d.ts +21 -0
  11. package/dist/atoms/Input.svelte +14 -10
  12. package/dist/atoms/Input.svelte.d.ts +2 -0
  13. package/dist/atoms/List.svelte +47 -0
  14. package/dist/atoms/List.svelte.d.ts +19 -0
  15. package/dist/atoms/ListItem.svelte +148 -0
  16. package/dist/atoms/ListItem.svelte.d.ts +35 -0
  17. package/dist/atoms/Progress.svelte +3 -5
  18. package/dist/atoms/Select.svelte +152 -19
  19. package/dist/atoms/Select.svelte.d.ts +23 -1
  20. package/dist/atoms/Textarea.svelte +11 -9
  21. package/dist/atoms/Textarea.svelte.d.ts +1 -0
  22. package/dist/atoms/Toggle.svelte +1 -7
  23. package/dist/atoms/Tooltip.svelte +8 -15
  24. package/dist/atoms/index.d.ts +3 -0
  25. package/dist/atoms/index.js +3 -0
  26. package/dist/components/atoms/index.d.ts +3 -0
  27. package/dist/components/atoms/index.d.ts.map +1 -1
  28. package/dist/components/index.d.ts +4 -0
  29. package/dist/components/index.d.ts.map +1 -1
  30. package/dist/components/molecules/index.d.ts +1 -1
  31. package/dist/components/molecules/navigation-menu-context.d.ts +7 -0
  32. package/dist/components/molecules/navigation-menu-context.d.ts.map +1 -0
  33. package/dist/components/organisms/index.d.ts +2 -0
  34. package/dist/components/organisms/index.d.ts.map +1 -1
  35. package/dist/index.d.ts +4 -0
  36. package/dist/index.js +5 -8
  37. package/dist/molecules/Alert.svelte +8 -3
  38. package/dist/molecules/ContactForm.svelte +63 -31
  39. package/dist/molecules/ContactForm.svelte.d.ts +1 -4
  40. package/dist/molecules/Dropdown.svelte +2 -1
  41. package/dist/molecules/ImageUpload.svelte +26 -3
  42. package/dist/molecules/ImageUpload.svelte.d.ts +1 -0
  43. package/dist/molecules/Modal.svelte +44 -43
  44. package/dist/molecules/NavigationMenu.svelte +7 -10
  45. package/dist/molecules/NavigationMenuContent.svelte +8 -8
  46. package/dist/molecules/NavigationMenuItem.svelte +7 -6
  47. package/dist/molecules/NavigationMenuLink.svelte +7 -5
  48. package/dist/molecules/NavigationMenuList.svelte +0 -7
  49. package/dist/molecules/NavigationMenuTrigger.svelte +7 -7
  50. package/dist/molecules/Section.svelte +158 -0
  51. package/dist/molecules/Section.svelte.d.ts +27 -0
  52. package/dist/molecules/SlideUp.svelte +30 -0
  53. package/dist/molecules/Tabs.svelte +71 -4
  54. package/dist/molecules/index.d.ts +1 -1
  55. package/dist/molecules/index.js +1 -1
  56. package/dist/molecules/navigation-menu-context.d.ts +6 -0
  57. package/dist/molecules/navigation-menu-context.js +1 -0
  58. package/dist/organisms/Navigation.svelte +9 -6
  59. package/dist/organisms/Navigation.svelte.d.ts +1 -0
  60. package/dist/organisms/SidebarNavigation.svelte +420 -0
  61. package/dist/organisms/SidebarNavigation.svelte.d.ts +44 -0
  62. package/dist/organisms/SidebarProjectPanel.svelte +174 -0
  63. package/dist/organisms/SidebarProjectPanel.svelte.d.ts +32 -0
  64. package/dist/organisms/index.d.ts +2 -0
  65. package/dist/organisms/index.js +2 -0
  66. package/dist/zabi-components.css +412 -0
  67. package/package.json +7 -8
  68. package/dist/molecules/Sidebar.svelte +0 -324
  69. 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;AAEtE,eAAO,MAAM,QAAQ,GAAI,SAAQ,MAAa,KAAG,MAMhD,CAAC;AAEF,eAAO,MAAM,EAAE,GAAI,GAAG,SAAS,CAAC,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,KAAK,CAAC,EAAE,KAAG,MAClC,CAAC;AAEtC,eAAO,MAAM,WAAW,GAAI,MAAM,eAAe,KAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAGrE,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,OAG7C,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,OAAO,GAAG,KAAG,OAE7C,CAAC;AAEF,eAAO,MAAM,SAAS,QAAO,OAE5B,CAAC;AAEF,eAAO,MAAM,UAAU,QAAO,MAAM,GAAG,SAEtC,CAAC;AAEF,eAAO,MAAM,YAAY,QAAO,QAAQ,GAAG,SAE1C,CAAC;AAEF,eAAO,MAAM,gBAAgB,QAAO,OAAO,GAAG,SAE7C,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,SAAQ,MAAa,KAAG,MAKlD,CAAC;AAEF,OAAO,EACH,GAAG,EACH,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,WAAW,EACX,YAAY,EACZ,GAAG,EACH,SAAS,EACT,SAAS,EACT,QAAQ,EACX,MAAM,gBAAgB,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 Sidebar } from './Sidebar.svelte';
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 const createId = (prefix = 'id') => {
23
- if (typeof window !== 'undefined') {
24
- return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;
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
- variant
72
+ visualVariant
68
73
  ]} transition-all duration-200 motion-reduce:transition-none {className}"
69
74
  role={alertRole}
70
- aria-live={variant === "success" || variant === "info"
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[variant]}
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
- children,
18
- ...restProps
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 formData = new FormData(event.target as HTMLFormElement);
52
+ const submittedFormData = new FormData(event.target as HTMLFormElement);
30
53
  const data: ContactFormData = {
31
- name: (formData.get("name") as string) || "",
32
- email: (formData.get("email") as string) || "",
33
- message: (formData.get("message") as string) || "",
34
- subscribe: formData.get("subscribe") === "on" || false,
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
- console.log("Form submitted with data:", data);
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
- <Card size="md" fullWidth={true} title="Get in Touch">
42
- <Form onsubmit={handleFormSubmit} className="space-y-4">
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
- <Input
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
- </Form>
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
- type $$ComponentProps = Props & {
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
- let dropdownId = `dropdown-${Math.random().toString(36).substr(2, 9)}`;
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
- if (value && typeof URL !== "undefined" && URL.revokeObjectURL) {
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>
@@ -3,6 +3,7 @@ interface Props {
3
3
  disabled?: boolean;
4
4
  accept?: string;
5
5
  placeholder?: string;
6
+ errorMessage?: string;
6
7
  onchange?: (event: Event) => void;
7
8
  onclick?: (event: Event) => void;
8
9
  }
@@ -28,7 +28,7 @@
28
28
  ...restProps
29
29
  }: Props & { children?: any; footer?: any } = $props();
30
30
 
31
- let modalContainer: HTMLDivElement;
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
- if (isOpen && modalContainer) {
56
+ const container = modalContainer;
57
+ if (isOpen && container) {
57
58
  saveFocus();
58
- cleanupFocusTrap = trapFocus(modalContainer);
59
+ cleanupFocusTrap = trapFocus(container);
59
60
  // Small delay to ensure modal is rendered
60
61
  setTimeout(() => {
61
- focusFirstElement(modalContainer);
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
- <Card
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
- {#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}
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
- {#if children}
129
- <CardContent className="flex-1">
130
- {@render children?.()}
131
- </CardContent>
132
- {/if}
128
+ {#if children}
129
+ <CardContent className="flex-1">
130
+ {@render children?.()}
131
+ </CardContent>
132
+ {/if}
133
133
 
134
- {#if footer}
135
- <CardFooter className="flex justify-end gap-3 pt-4">
136
- {@render footer?.()}
137
- </CardFooter>
138
- {/if}
139
- </Card>
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 { getContext, setContext } from "svelte";
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
- interface NavigationMenuContext {
12
- activeItem: string | null;
13
- setActiveItem: (item: string | null) => void;
14
- isMobile: boolean;
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: NavigationMenuContext = {
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(NAVIGATION_MENU_CONTEXT, context);
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, onDestroy } from "svelte";
5
-
6
- const NAVIGATION_MENU_CONTEXT = Symbol("navigation-menu");
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
- activeItem: string | null;
26
- setActiveItem: (item: string | null) => void;
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
- const NAVIGATION_MENU_CONTEXT = Symbol("navigation-menu");
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
- activeItem: string | null;
22
- setActiveItem: (item: string | null) => void;
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>