zabi-components 5.0.15 → 5.0.18

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 (66) hide show
  1. package/README.md +175 -23
  2. package/dist/SSRSafe.svelte +0 -3
  3. package/dist/atoms/Badge.svelte +32 -47
  4. package/dist/atoms/Badge.svelte.d.ts +6 -5
  5. package/dist/atoms/Button.svelte +18 -17
  6. package/dist/atoms/Button.svelte.d.ts +3 -2
  7. package/dist/atoms/Card.svelte +74 -23
  8. package/dist/atoms/Card.svelte.d.ts +3 -1
  9. package/dist/atoms/CardContent.svelte +24 -0
  10. package/dist/atoms/CardContent.svelte.d.ts +8 -0
  11. package/dist/atoms/CardDescription.svelte +24 -0
  12. package/dist/atoms/CardDescription.svelte.d.ts +8 -0
  13. package/dist/atoms/CardFooter.svelte +24 -0
  14. package/dist/atoms/CardFooter.svelte.d.ts +8 -0
  15. package/dist/atoms/CardHeader.svelte +24 -0
  16. package/dist/atoms/CardHeader.svelte.d.ts +8 -0
  17. package/dist/atoms/CardTitle.svelte +33 -0
  18. package/dist/atoms/CardTitle.svelte.d.ts +9 -0
  19. package/dist/atoms/Checkbox.svelte +19 -20
  20. package/dist/atoms/CodeBlock.svelte +4 -7
  21. package/dist/atoms/ColorPicker.svelte +33 -65
  22. package/dist/atoms/FeatureCard.svelte +2 -12
  23. package/dist/atoms/FeatureCard.svelte.d.ts +0 -8
  24. package/dist/atoms/Heading.svelte +0 -2
  25. package/dist/atoms/Input.svelte +8 -17
  26. package/dist/atoms/Input.svelte.d.ts +3 -2
  27. package/dist/atoms/Progress.svelte +1 -4
  28. package/dist/atoms/Select.svelte +37 -28
  29. package/dist/atoms/Skeleton.svelte +1 -1
  30. package/dist/atoms/Textarea.svelte +5 -11
  31. package/dist/atoms/Textarea.svelte.d.ts +3 -1
  32. package/dist/atoms/ThemeToggle.svelte +5 -12
  33. package/dist/atoms/Toast.svelte +1 -2
  34. package/dist/atoms/Toggle.svelte +2 -10
  35. package/dist/atoms/Tooltip.svelte +123 -26
  36. package/dist/atoms/index.d.ts +5 -0
  37. package/dist/atoms/index.js +5 -1
  38. package/dist/components/atoms/index.d.ts +5 -0
  39. package/dist/components/atoms/index.d.ts.map +1 -1
  40. package/dist/components/index.d.ts.map +1 -1
  41. package/dist/components/molecules/index.d.ts.map +1 -1
  42. package/dist/components/organisms/index.d.ts.map +1 -1
  43. package/dist/index.js +0 -23
  44. package/dist/molecules/Alert.svelte +9 -13
  45. package/dist/molecules/Alert.svelte.d.ts +2 -1
  46. package/dist/molecules/ComponentDemo.svelte +55 -64
  47. package/dist/molecules/ContactForm.svelte +21 -12
  48. package/dist/molecules/Dropdown.svelte +104 -8
  49. package/dist/molecules/Dropdown.svelte.d.ts +1 -0
  50. package/dist/molecules/Form.svelte +0 -1
  51. package/dist/molecules/ImageUpload.svelte +2 -6
  52. package/dist/molecules/Modal.svelte +30 -6
  53. package/dist/molecules/SlideUp.svelte +2 -4
  54. package/dist/molecules/Tabs.svelte +2 -4
  55. package/dist/molecules/index.js +0 -1
  56. package/dist/organisms/Navbar.svelte +1 -8
  57. package/dist/organisms/Navigation.svelte +0 -6
  58. package/dist/organisms/index.js +0 -1
  59. package/dist/routes/lib/variant-utils.ts +7 -5
  60. package/dist/zabi-components-colors.css +287 -211
  61. package/dist/zabi-components-theme-dark-only.css +158 -0
  62. package/dist/zabi-components-theme-dark.css +160 -0
  63. package/dist/zabi-components-theme-only.css +235 -0
  64. package/dist/zabi-components-theme.css +237 -0
  65. package/dist/zabi-components.css +575 -360
  66. package/package.json +15 -5
@@ -2,6 +2,11 @@ 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
4
  export { default as Card } from './Card.svelte';
5
+ export { default as CardHeader } from './CardHeader.svelte';
6
+ export { default as CardContent } from './CardContent.svelte';
7
+ export { default as CardFooter } from './CardFooter.svelte';
8
+ export { default as CardTitle } from './CardTitle.svelte';
9
+ export { default as CardDescription } from './CardDescription.svelte';
5
10
  export { default as Input } from './Input.svelte';
6
11
  export { default as Textarea } from './Textarea.svelte';
7
12
  export { default as Select } from './Select.svelte';
@@ -1,8 +1,12 @@
1
- // Export atom components - All SSR-safe components
2
1
  export { default as Toggle } from './Toggle.svelte';
3
2
  export { default as Badge } from './Badge.svelte';
4
3
  export { default as Button } from './Button.svelte';
5
4
  export { default as Card } from './Card.svelte';
5
+ export { default as CardHeader } from './CardHeader.svelte';
6
+ export { default as CardContent } from './CardContent.svelte';
7
+ export { default as CardFooter } from './CardFooter.svelte';
8
+ export { default as CardTitle } from './CardTitle.svelte';
9
+ export { default as CardDescription } from './CardDescription.svelte';
6
10
  export { default as Input } from './Input.svelte';
7
11
  export { default as Textarea } from './Textarea.svelte';
8
12
  export { default as Select } from './Select.svelte';
@@ -2,6 +2,11 @@ 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
4
  export { default as Card } from './Card.svelte';
5
+ export { default as CardHeader } from './CardHeader.svelte';
6
+ export { default as CardContent } from './CardContent.svelte';
7
+ export { default as CardFooter } from './CardFooter.svelte';
8
+ export { default as CardTitle } from './CardTitle.svelte';
9
+ export { default as CardDescription } from './CardDescription.svelte';
5
10
  export { default as Input } from './Input.svelte';
6
11
  export { default as Textarea } from './Textarea.svelte';
7
12
  export { default as Select } from './Select.svelte';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/atoms/index.ts"],"names":[],"mappings":"AACA,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,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,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,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACtE,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 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC1D,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;AAMpE,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;AAM1D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAOtE,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;AAGtC,eAAO,MAAM,WAAW,GAAI,MAAM,eAAe,KAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAGrE,CAAC;AAGF,eAAO,MAAM,aAAa,GAAI,OAAO,MAAM,KAAG,OAG7C,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,OAAO,GAAG,KAAG,OAE7C,CAAC;AAGF,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;AAGF,eAAO,MAAM,UAAU,GAAI,SAAQ,MAAa,KAAG,MAKlD,CAAC;AAMF,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":"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 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/molecules/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/molecules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/organisms/index.ts"],"names":[],"mappings":"AACA,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"}
package/dist/index.js CHANGED
@@ -1,9 +1,3 @@
1
- // Zabi Components - Clean & Simple Svelte Component Library
2
- // Main library entry point - All components in one place
3
- // ============================================================================
4
- // ATOM COMPONENTS - Basic UI building blocks
5
- // ============================================================================
6
- // Form Controls - All SSR-safe components
7
1
  export { default as Toggle } from './atoms/Toggle.svelte';
8
2
  export { default as Badge } from './atoms/Badge.svelte';
9
3
  export { default as Button } from './atoms/Button.svelte';
@@ -14,9 +8,6 @@ export { default as Select } from './atoms/Select.svelte';
14
8
  export { default as ColorPicker } from './atoms/ColorPicker.svelte';
15
9
  export { default as Heading } from './atoms/Heading.svelte';
16
10
  export { default as ThemeToggle } from './atoms/ThemeToggle.svelte';
17
- // ============================================================================
18
- // MOLECULE COMPONENTS - Composite UI elements
19
- // ============================================================================
20
11
  export { default as Alert } from './molecules/Alert.svelte';
21
12
  export { default as ComponentDemo } from './molecules/ComponentDemo.svelte';
22
13
  export { default as ContactForm } from './molecules/ContactForm.svelte';
@@ -26,15 +17,8 @@ export { default as ImageUpload } from './molecules/ImageUpload.svelte';
26
17
  export { default as Modal } from './molecules/Modal.svelte';
27
18
  export { default as SlideUp } from './molecules/SlideUp.svelte';
28
19
  export { default as Tabs } from './molecules/Tabs.svelte';
29
- // ============================================================================
30
- // ORGANISM COMPONENTS - Complex UI sections
31
- // ============================================================================
32
20
  export { default as Navbar } from './organisms/Navbar.svelte';
33
21
  export { default as Navigation } from './organisms/Navigation.svelte';
34
- // ============================================================================
35
- // UTILITIES - Helper functions and utilities
36
- // ============================================================================
37
- // Simple utility functions
38
22
  export const createId = (prefix = 'id') => {
39
23
  if (typeof window !== 'undefined') {
40
24
  return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;
@@ -44,12 +28,10 @@ export const createId = (prefix = 'id') => {
44
28
  }
45
29
  };
46
30
  export const cn = (...classes) => classes.filter(Boolean).join(' ');
47
- // Form utilities
48
31
  export const getFormData = (form) => {
49
32
  const formData = new FormData(form);
50
33
  return Object.fromEntries(formData.entries());
51
34
  };
52
- // Validation utilities
53
35
  export const validateEmail = (email) => {
54
36
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
55
37
  return emailRegex.test(email);
@@ -57,7 +39,6 @@ export const validateEmail = (email) => {
57
39
  export const validateRequired = (value) => {
58
40
  return value !== null && value !== undefined && value !== '';
59
41
  };
60
- // SSR-safe utilities
61
42
  export const isBrowser = () => {
62
43
  return typeof window !== 'undefined';
63
44
  };
@@ -70,14 +51,10 @@ export const safeDocument = () => {
70
51
  export const safeLocalStorage = () => {
71
52
  return typeof window !== 'undefined' ? localStorage : undefined;
72
53
  };
73
- // Alias for backward compatibility - separate function to avoid initialization issues
74
54
  export const generateId = (prefix = 'id') => {
75
55
  if (typeof window !== 'undefined') {
76
56
  return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;
77
57
  }
78
58
  return `${prefix}-ssr-${Date.now()}`;
79
59
  };
80
- // ============================================================================
81
- // ICONS - Re-export commonly used Lucide icons
82
- // ============================================================================
83
60
  export { Sun, Moon, Monitor, Grip, GripVertical, ChevronUp, ChevronDown, ChevronRight, Zap, Briefcase, Clipboard, Settings } from '@lucide/svelte';
@@ -1,6 +1,8 @@
1
1
  <script lang="ts">
2
+ import type { ExtendedSemanticVariant } from "../../types/variants.js";
3
+
2
4
  interface Props {
3
- variant?: "info" | "success" | "warning" | "error" | "neutral" | "energetic";
5
+ variant?: ExtendedSemanticVariant;
4
6
  title?: string;
5
7
  message?: string;
6
8
  closable?: boolean;
@@ -20,19 +22,18 @@
20
22
  }: Props & { children?: any } = $props();
21
23
 
22
24
  function handleDismiss(event: MouseEvent) {
23
- // Call the parent's onclick handler if provided
24
25
  if (onclick) {
25
26
  onclick(event);
26
27
  }
27
28
  }
28
29
 
29
30
  let alertClasses = $derived({
30
- info: "bg-surface-level-1 text-info border border-info",
31
- success: "bg-surface-level-1 text-success border border-success",
32
- warning: "bg-surface-level-1 text-warning border border-warning",
33
- error: "bg-surface-level-1 text-error border border-error",
34
- neutral: "bg-surface-level-1 text-neutral border border-neutral",
35
- energetic: "bg-surface-level-1 text-energetic border border-energetic",
31
+ info: "text-info border border-info",
32
+ success: "text-success border border-success",
33
+ warning: "text-warning border border-warning",
34
+ error: "text-error border border-error",
35
+ neutral: "text-neutral border border-neutral",
36
+ energetic: "text-energetic border border-energetic",
36
37
  });
37
38
 
38
39
  let alertRole = $derived(
@@ -72,7 +73,6 @@
72
73
  aria-atomic="true"
73
74
  {...restProps}
74
75
  >
75
- <!-- Dismiss button (X in top right) -->
76
76
  {#if closable}
77
77
  <button
78
78
  onclick={handleDismiss}
@@ -96,14 +96,11 @@
96
96
  </button>
97
97
  {/if}
98
98
 
99
- <!-- Content -->
100
99
  <div class="flex items-start gap-3 {closable ? 'pr-8' : ''}">
101
- <!-- Icon -->
102
100
  <div class="shrink-0 mt-0.5">
103
101
  {@html iconSvg[variant]}
104
102
  </div>
105
103
 
106
- <!-- Text content -->
107
104
  <div class="flex-1 min-w-0">
108
105
  {#if title}
109
106
  <h4 class="font-semibold text-sm mb-1 text-headline">
@@ -115,7 +112,6 @@
115
112
  {message}
116
113
  </p>
117
114
  {/if}
118
- <!-- Default slot for custom content -->
119
115
  {@render children?.()}
120
116
  </div>
121
117
  </div>
@@ -1,5 +1,6 @@
1
+ import type { ExtendedSemanticVariant } from "../../types/variants.js";
1
2
  interface Props {
2
- variant?: "info" | "success" | "warning" | "error" | "neutral" | "energetic";
3
+ variant?: ExtendedSemanticVariant;
3
4
  title?: string;
4
5
  message?: string;
5
6
  closable?: boolean;
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import CodeBlock from "../atoms/CodeBlock.svelte";
3
+ import Card from "../atoms/Card.svelte";
3
4
 
4
5
  interface Props {
5
6
  title: string;
@@ -22,75 +23,65 @@
22
23
  let showCode = $state(false);
23
24
  </script>
24
25
 
25
- <div
26
- class="component-demo bg-surface-level-0 border border-border rounded-lg overflow-hidden {className}"
27
- {...restProps}
28
- >
29
- <!-- Header -->
30
- <div class="px-6 py-4 border-b border-border bg-surface-level-1">
31
- <div class="flex items-center justify-between">
32
- <div>
33
- <h3 class="text-lg font-semibold text-text">{title}</h3>
34
- {#if description}
35
- <p class="text-sm text-text-secondary mt-1">
36
- {description}
37
- </p>
38
- {/if}
39
- </div>
40
- <button
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-level-0 rounded-md transition-colors duration-200"
43
- aria-label={showCode ? "Show preview" : "Show code"}
44
- >
45
- {#if showCode}
46
- <svg
47
- class="w-4 h-4"
48
- fill="none"
49
- stroke="currentColor"
50
- viewBox="0 0 24 24"
51
- >
52
- <path
53
- stroke-linecap="round"
54
- stroke-linejoin="round"
55
- stroke-width="2"
56
- d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
57
- />
58
- <path
59
- stroke-linecap="round"
60
- stroke-linejoin="round"
61
- stroke-width="2"
62
- d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
63
- />
64
- </svg>
65
- Preview
66
- {:else}
67
- <svg
68
- class="w-4 h-4"
69
- fill="none"
70
- stroke="currentColor"
71
- viewBox="0 0 24 24"
72
- >
73
- <path
74
- stroke-linecap="round"
75
- stroke-linejoin="round"
76
- stroke-width="2"
77
- d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
78
- />
79
- </svg>
80
- Code
81
- {/if}
82
- </button>
83
- </div>
84
- </div>
26
+ <div class="relative">
27
+ <Card
28
+ size="lg"
29
+ fullWidth={true}
30
+ {title}
31
+ {description}
32
+ className="overflow-hidden {className}"
33
+ {...restProps}
34
+ >
35
+ <button
36
+ onclick={() => (showCode = !showCode)}
37
+ class="absolute top-8 right-8 flex items-center gap-2 px-3 py-1.5 text-sm text-description hover:text-body hover:bg-base-50 rounded-md transition-colors duration-200 z-10"
38
+ aria-label={showCode ? "Show preview" : "Show code"}
39
+ >
40
+ {#if showCode}
41
+ <svg
42
+ class="w-4 h-4"
43
+ fill="none"
44
+ stroke="currentColor"
45
+ viewBox="0 0 24 24"
46
+ >
47
+ <path
48
+ stroke-linecap="round"
49
+ stroke-linejoin="round"
50
+ stroke-width="2"
51
+ d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
52
+ />
53
+ <path
54
+ stroke-linecap="round"
55
+ stroke-linejoin="round"
56
+ stroke-width="2"
57
+ d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"
58
+ />
59
+ </svg>
60
+ Preview
61
+ {:else}
62
+ <svg
63
+ class="w-4 h-4"
64
+ fill="none"
65
+ stroke="currentColor"
66
+ viewBox="0 0 24 24"
67
+ >
68
+ <path
69
+ stroke-linecap="round"
70
+ stroke-linejoin="round"
71
+ stroke-width="2"
72
+ d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
73
+ />
74
+ </svg>
75
+ Code
76
+ {/if}
77
+ </button>
85
78
 
86
- <!-- Content -->
87
- <div class="p-6">
88
79
  {#if showCode}
89
80
  <CodeBlock {code} {language} />
90
81
  {:else}
91
- <div class="min-h-[100px] flex items-center justify-center">
82
+ <div class="min-h-[100px] flex items-center justify-center w-full">
92
83
  {@render children?.()}
93
84
  </div>
94
85
  {/if}
95
- </div>
86
+ </Card>
96
87
  </div>
@@ -4,6 +4,7 @@
4
4
  import Textarea from "../atoms/Textarea.svelte";
5
5
  import Checkbox from "../atoms/Checkbox.svelte";
6
6
  import Button from "../atoms/Button.svelte";
7
+ import Card from "../atoms/Card.svelte";
7
8
  import type { ContactFormData } from "../../types/page.types";
8
9
 
9
10
  interface Props {
@@ -33,21 +34,11 @@
33
34
  subscribe: formData.get("subscribe") === "on" || false,
34
35
  };
35
36
 
36
- // Form submission is now handled by the parent component
37
- // through event forwarding. The data is available for processing.
38
37
  console.log("Form submitted with data:", data);
39
38
  }
40
39
  </script>
41
40
 
42
- <div class="max-w-md mx-auto {className}">
43
- <div class="mb-6">
44
- <h2 class="text-2xl font-bold text-headline mb-2">Get in Touch</h2>
45
- <p class="text-description">
46
- We'd love to hear from you. Send us a message and we'll respond as
47
- soon as possible.
48
- </p>
49
- </div>
50
-
41
+ <Card size="md" fullWidth={true} title="Get in Touch">
51
42
  <Form onsubmit={handleFormSubmit} className="space-y-4">
52
43
  <div class="space-y-4">
53
44
  <Input
@@ -68,6 +59,24 @@
68
59
  oninput={(e) =>
69
60
  (formData.email = (e.target as HTMLInputElement).value)}
70
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)}
79
+ />
71
80
  <Textarea
72
81
  name="message"
73
82
  label="Message"
@@ -95,4 +104,4 @@
95
104
  </Button>
96
105
  </div>
97
106
  </Form>
98
- </div>
107
+ </Card>
@@ -2,17 +2,99 @@
2
2
  interface Props {
3
3
  isOpen?: boolean;
4
4
  placement?: "bottom-start" | "bottom-end" | "top-start" | "top-end";
5
+ ariaLabel?: string;
5
6
  }
6
7
 
7
8
  let {
8
9
  isOpen = false,
9
10
  placement = "bottom-start",
11
+ ariaLabel = "Menu",
10
12
  children,
11
13
  trigger,
12
14
  ...restProps
13
15
  }: Props & { children?: any; trigger?: any } = $props();
14
16
 
15
- // Get positioning classes based on placement
17
+ let dropdownId = `dropdown-${Math.random().toString(36).substr(2, 9)}`;
18
+ let triggerElement: HTMLElement | null = null;
19
+ let menuElement: HTMLElement | null = null;
20
+
21
+ function handleKeydown(event: KeyboardEvent) {
22
+ if (!isOpen) {
23
+ if (event.key === "Enter" || event.key === " " || event.key === "ArrowDown") {
24
+ event.preventDefault();
25
+ isOpen = true;
26
+ }
27
+ return;
28
+ }
29
+
30
+ switch (event.key) {
31
+ case "Escape":
32
+ event.preventDefault();
33
+ isOpen = false;
34
+ triggerElement?.focus();
35
+ break;
36
+ case "ArrowDown":
37
+ event.preventDefault();
38
+ focusNextItem();
39
+ break;
40
+ case "ArrowUp":
41
+ event.preventDefault();
42
+ focusPreviousItem();
43
+ break;
44
+ case "Home":
45
+ event.preventDefault();
46
+ focusFirstItem();
47
+ break;
48
+ case "End":
49
+ event.preventDefault();
50
+ focusLastItem();
51
+ break;
52
+ case "Tab":
53
+ isOpen = false;
54
+ break;
55
+ }
56
+ }
57
+
58
+ function getMenuItems(): HTMLElement[] {
59
+ if (!menuElement) return [];
60
+ return Array.from(
61
+ menuElement.querySelectorAll<HTMLElement>('[role="menuitem"], button, a')
62
+ );
63
+ }
64
+
65
+ function focusNextItem() {
66
+ const items = getMenuItems();
67
+ const currentIndex = items.findIndex((item) => item === document.activeElement);
68
+ const nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;
69
+ items[nextIndex]?.focus();
70
+ }
71
+
72
+ function focusPreviousItem() {
73
+ const items = getMenuItems();
74
+ const currentIndex = items.findIndex((item) => item === document.activeElement);
75
+ const prevIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;
76
+ items[prevIndex]?.focus();
77
+ }
78
+
79
+ function focusFirstItem() {
80
+ const items = getMenuItems();
81
+ items[0]?.focus();
82
+ }
83
+
84
+ function focusLastItem() {
85
+ const items = getMenuItems();
86
+ items[items.length - 1]?.focus();
87
+ }
88
+
89
+ // Focus first item when dropdown opens
90
+ $effect(() => {
91
+ if (isOpen && menuElement) {
92
+ setTimeout(() => {
93
+ focusFirstItem();
94
+ }, 0);
95
+ }
96
+ });
97
+
16
98
  const placementClasses = $derived(() => {
17
99
  const base = "absolute z-dropdown min-w-[12rem]";
18
100
  const positioning = {
@@ -24,7 +106,6 @@
24
106
  return `${base} ${positioning[placement]}`;
25
107
  });
26
108
 
27
- // Get transform classes based on placement and open state
28
109
  const transformClasses = $derived(() => {
29
110
  if (!isOpen) {
30
111
  const hiddenTransform = {
@@ -38,11 +119,10 @@
38
119
  return "opacity-100 visible translate-y-0";
39
120
  });
40
121
 
41
- // Get dropdown content classes
42
122
  const dropdownContentClasses = $derived(() => {
43
123
  return `
44
124
  ${placementClasses()}
45
- bg-brand-100
125
+ bg-input
46
126
  rounded-lg
47
127
  shadow-lg
48
128
  border-0
@@ -51,15 +131,31 @@
51
131
  duration-200
52
132
  ease-in-out
53
133
  ${transformClasses()}
54
- `.trim().replace(/\s+/g, " ");
134
+ `
135
+ .trim()
136
+ .replace(/\s+/g, " ");
55
137
  });
56
138
  </script>
57
139
 
58
- <div class="relative inline-block" data-placement={placement}>
59
- {@render trigger?.()}
140
+ <div
141
+ class="relative inline-block"
142
+ data-placement={placement}
143
+ onkeydown={handleKeydown}
144
+ {...restProps}
145
+ >
146
+ <div bind:this={triggerElement}>
147
+ {@render trigger?.()}
148
+ </div>
60
149
 
61
150
  {#if isOpen}
62
- <div class={dropdownContentClasses()}>
151
+ <div
152
+ bind:this={menuElement}
153
+ id={dropdownId}
154
+ class={dropdownContentClasses()}
155
+ role="menu"
156
+ aria-label={ariaLabel}
157
+ tabindex="-1"
158
+ >
63
159
  {@render children?.()}
64
160
  </div>
65
161
  {/if}
@@ -1,6 +1,7 @@
1
1
  interface Props {
2
2
  isOpen?: boolean;
3
3
  placement?: "bottom-start" | "bottom-end" | "top-start" | "top-end";
4
+ ariaLabel?: string;
4
5
  }
5
6
  type $$ComponentProps = Props & {
6
7
  children?: any;
@@ -19,7 +19,6 @@
19
19
  const formData = new FormData(event.target as HTMLFormElement);
20
20
  const data = Object.fromEntries(formData.entries());
21
21
 
22
- // Call the parent's onsubmit handler if provided
23
22
  if (onsubmit) {
24
23
  onsubmit(event);
25
24
  }
@@ -30,7 +30,6 @@
30
30
 
31
31
  const file = input.files[0];
32
32
 
33
- // SSR-safe URL creation
34
33
  if (typeof URL !== "undefined" && URL.createObjectURL) {
35
34
  const url = URL.createObjectURL(file);
36
35
  value = url;
@@ -54,7 +53,6 @@
54
53
 
55
54
  <div class="space-y-3">
56
55
  {#if value}
57
- <!-- Image Display -->
58
56
  <div class="relative group">
59
57
  <img
60
58
  src={value}
@@ -85,9 +83,8 @@
85
83
  </div>
86
84
  </div>
87
85
  {:else}
88
- <!-- Empty State -->
89
86
  <div
90
- class="border-2 border-dashed border-stone-200 rounded-lg p-6 text-center hover:border-brand-500 transition-colors {disabled
87
+ class="border-2 border-dashed border-base-200 rounded-lg p-6 text-center hover:border-brand-500 transition-colors {disabled
91
88
  ? 'cursor-not-allowed opacity-50'
92
89
  : 'cursor-pointer'}"
93
90
  onclick={triggerFileSelect}
@@ -99,7 +96,7 @@
99
96
  >
100
97
  <div class="space-y-3">
101
98
  <div
102
- class="w-12 h-12 mx-auto bg-surface-level-1 rounded-lg flex items-center justify-center"
99
+ class="w-12 h-12 mx-auto bg-base-100 rounded-lg flex items-center justify-center"
103
100
  >
104
101
  <Image size={24} class="text-description" />
105
102
  </div>
@@ -113,7 +110,6 @@
113
110
  </div>
114
111
  {/if}
115
112
 
116
- <!-- Hidden File Input -->
117
113
  <input
118
114
  bind:this={fileInput}
119
115
  type="file"