zabi-components 5.0.17 → 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 (65) hide show
  1. package/README.md +124 -23
  2. package/dist/SSRSafe.svelte +0 -3
  3. package/dist/atoms/Badge.svelte +19 -34
  4. package/dist/atoms/Badge.svelte.d.ts +6 -5
  5. package/dist/atoms/Button.svelte +10 -9
  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 +0 -4
  20. package/dist/atoms/CodeBlock.svelte +0 -3
  21. package/dist/atoms/ColorPicker.svelte +33 -65
  22. package/dist/atoms/FeatureCard.svelte +0 -10
  23. package/dist/atoms/FeatureCard.svelte.d.ts +0 -8
  24. package/dist/atoms/Heading.svelte +0 -2
  25. package/dist/atoms/Input.svelte +3 -12
  26. package/dist/atoms/Input.svelte.d.ts +3 -2
  27. package/dist/atoms/Progress.svelte +0 -3
  28. package/dist/atoms/Select.svelte +0 -14
  29. package/dist/atoms/Textarea.svelte +3 -9
  30. package/dist/atoms/Textarea.svelte.d.ts +3 -1
  31. package/dist/atoms/ThemeToggle.svelte +0 -7
  32. package/dist/atoms/Toast.svelte +0 -1
  33. package/dist/atoms/Toggle.svelte +0 -6
  34. package/dist/atoms/Tooltip.svelte +0 -12
  35. package/dist/atoms/index.d.ts +5 -0
  36. package/dist/atoms/index.js +5 -1
  37. package/dist/components/atoms/index.d.ts +5 -0
  38. package/dist/components/atoms/index.d.ts.map +1 -1
  39. package/dist/components/index.d.ts.map +1 -1
  40. package/dist/components/molecules/index.d.ts.map +1 -1
  41. package/dist/components/organisms/index.d.ts.map +1 -1
  42. package/dist/index.js +0 -23
  43. package/dist/molecules/Alert.svelte +3 -13
  44. package/dist/molecules/Alert.svelte.d.ts +2 -1
  45. package/dist/molecules/ComponentDemo.svelte +0 -2
  46. package/dist/molecules/ContactForm.svelte +21 -12
  47. package/dist/molecules/Dropdown.svelte +100 -6
  48. package/dist/molecules/Dropdown.svelte.d.ts +1 -0
  49. package/dist/molecules/Form.svelte +0 -1
  50. package/dist/molecules/ImageUpload.svelte +0 -4
  51. package/dist/molecules/Modal.svelte +29 -5
  52. package/dist/molecules/SlideUp.svelte +0 -2
  53. package/dist/molecules/Tabs.svelte +0 -2
  54. package/dist/molecules/index.js +0 -1
  55. package/dist/organisms/Navbar.svelte +0 -7
  56. package/dist/organisms/Navigation.svelte +0 -6
  57. package/dist/organisms/index.js +0 -1
  58. package/dist/routes/lib/variant-utils.ts +3 -1
  59. package/dist/zabi-components-colors.css +246 -178
  60. package/dist/zabi-components-theme-dark-only.css +11 -2
  61. package/dist/zabi-components-theme-dark.css +11 -2
  62. package/dist/zabi-components-theme-only.css +32 -24
  63. package/dist/zabi-components-theme.css +32 -24
  64. package/dist/zabi-components.css +259 -83
  65. package/package.json +2 -2
@@ -1,5 +1,4 @@
1
1
  <script lang="ts">
2
- // SSR-safe ID generation
3
2
  function generateId(prefix: string = "id"): string {
4
3
  if (typeof window !== "undefined") {
5
4
  return `${prefix}-${Math.random().toString(36).substr(2, 9)}`;
@@ -8,7 +7,6 @@
8
7
  }
9
8
  }
10
9
 
11
- // Props using Svelte 5 runes
12
10
  interface Props {
13
11
  checked?: boolean;
14
12
  disabled?: boolean;
@@ -26,15 +24,12 @@
26
24
  ...restProps
27
25
  }: Props = $props();
28
26
 
29
- // SSR-safe ID generation (call directly, not in onMount)
30
27
  const toggleId = generateId("toggle");
31
28
 
32
- // Handle click
33
29
  function handleClick(event: MouseEvent) {
34
30
  if (disabled) return;
35
31
  checked = !checked;
36
32
 
37
- // Call parent handlers if provided
38
33
  if (onclick) onclick(event);
39
34
  if (onchange) onchange({ checked });
40
35
  }
@@ -57,7 +52,6 @@
57
52
  return `${baseClasses} ${positionClasses}`.trim();
58
53
  });
59
54
 
60
- // Handle keyboard
61
55
  function handleKeydown(event: KeyboardEvent) {
62
56
  if (disabled) return;
63
57
  if (event.key === " " || event.key === "Enter") {
@@ -22,7 +22,6 @@
22
22
  let isVisible = $state(false);
23
23
  let triggerElement: HTMLElement | null = $state(null);
24
24
 
25
- // Handle keyboard events
26
25
  function handleKeydown(event: KeyboardEvent) {
27
26
  if (event.key === "Escape" && isVisible) {
28
27
  isVisible = false;
@@ -30,7 +29,6 @@
30
29
  }
31
30
  }
32
31
 
33
- // Handle focus events for accessibility
34
32
  function handleFocus() {
35
33
  if (!disabled && content) {
36
34
  isVisible = true;
@@ -38,7 +36,6 @@
38
36
  }
39
37
 
40
38
  function handleBlur() {
41
- // Delay hiding to allow clicking on tooltip content if needed
42
39
  setTimeout(() => {
43
40
  isVisible = false;
44
41
  }, 100);
@@ -136,7 +133,6 @@
136
133
  pointer-events: none;
137
134
  }
138
135
 
139
- /* Simplified positioning using CSS custom properties and logical properties */
140
136
  .tooltip-container[data-placement="top"] .tooltip {
141
137
  inset-block-end: 100%;
142
138
  inset-inline-start: 50%;
@@ -189,7 +185,6 @@
189
185
  transform: translateY(-50%) translateX(0) scale(1);
190
186
  }
191
187
 
192
- /* Modern arrow implementation using CSS clip-path for better performance */
193
188
  .tooltip::before {
194
189
  content: "";
195
190
  position: absolute;
@@ -226,12 +221,10 @@
226
221
  clip-path: polygon(0 50%, 100% 0, 100% 100%);
227
222
  }
228
223
 
229
- /* Delay support using CSS custom properties */
230
224
  .tooltip-container[data-delay] .tooltip {
231
225
  transition-delay: calc(var(--tooltip-delay, 0) * 1ms);
232
226
  }
233
227
 
234
- /* Responsive design with modern CSS */
235
228
  @media (max-width: 640px) {
236
229
  .tooltip {
237
230
  --tooltip-max-width: calc(100vw - 2rem);
@@ -250,19 +243,16 @@
250
243
  }
251
244
  }
252
245
 
253
- /* Dark mode support */
254
246
  @media (prefers-color-scheme: dark) {
255
247
  :root {
256
248
  --tooltip-bg: #374151;
257
249
  }
258
250
  }
259
251
 
260
- /* Use CSS color-scheme for better dark mode support */
261
252
  .dark :root {
262
253
  --tooltip-bg: #374151;
263
254
  }
264
255
 
265
- /* High contrast mode support */
266
256
  @media (prefers-contrast: high) {
267
257
  :root {
268
258
  --tooltip-bg: #000000;
@@ -271,7 +261,6 @@
271
261
  }
272
262
  }
273
263
 
274
- /* Reduced motion support */
275
264
  @media (prefers-reduced-motion: reduce) {
276
265
  .tooltip {
277
266
  transition: opacity 0.1s ease-in-out, visibility 0.1s ease-in-out;
@@ -288,7 +277,6 @@
288
277
  }
289
278
  }
290
279
 
291
- /* Focus-visible for better keyboard navigation */
292
280
  .tooltip-container:focus-visible {
293
281
  outline: 2px solid var(--color-focus, #8fa8ff);
294
282
  outline-offset: 2px;
@@ -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,12 +1,8 @@
1
1
  <script lang="ts">
2
+ import type { ExtendedSemanticVariant } from "../../types/variants.js";
3
+
2
4
  interface Props {
3
- variant?:
4
- | "info"
5
- | "success"
6
- | "warning"
7
- | "error"
8
- | "neutral"
9
- | "energetic";
5
+ variant?: ExtendedSemanticVariant;
10
6
  title?: string;
11
7
  message?: string;
12
8
  closable?: boolean;
@@ -26,7 +22,6 @@
26
22
  }: Props & { children?: any } = $props();
27
23
 
28
24
  function handleDismiss(event: MouseEvent) {
29
- // Call the parent's onclick handler if provided
30
25
  if (onclick) {
31
26
  onclick(event);
32
27
  }
@@ -78,7 +73,6 @@
78
73
  aria-atomic="true"
79
74
  {...restProps}
80
75
  >
81
- <!-- Dismiss button (X in top right) -->
82
76
  {#if closable}
83
77
  <button
84
78
  onclick={handleDismiss}
@@ -102,14 +96,11 @@
102
96
  </button>
103
97
  {/if}
104
98
 
105
- <!-- Content -->
106
99
  <div class="flex items-start gap-3 {closable ? 'pr-8' : ''}">
107
- <!-- Icon -->
108
100
  <div class="shrink-0 mt-0.5">
109
101
  {@html iconSvg[variant]}
110
102
  </div>
111
103
 
112
- <!-- Text content -->
113
104
  <div class="flex-1 min-w-0">
114
105
  {#if title}
115
106
  <h4 class="font-semibold text-sm mb-1 text-headline">
@@ -121,7 +112,6 @@
121
112
  {message}
122
113
  </p>
123
114
  {/if}
124
- <!-- Default slot for custom content -->
125
115
  {@render children?.()}
126
116
  </div>
127
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;
@@ -32,7 +32,6 @@
32
32
  className="overflow-hidden {className}"
33
33
  {...restProps}
34
34
  >
35
- <!-- Toggle Button positioned absolutely -->
36
35
  <button
37
36
  onclick={() => (showCode = !showCode)}
38
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"
@@ -77,7 +76,6 @@
77
76
  {/if}
78
77
  </button>
79
78
 
80
- <!-- Content -->
81
79
  {#if showCode}
82
80
  <CodeBlock {code} {language} />
83
81
  {:else}
@@ -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,7 +119,6 @@
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()}
@@ -57,11 +137,25 @@
57
137
  });
58
138
  </script>
59
139
 
60
- <div class="relative inline-block" data-placement={placement}>
61
- {@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>
62
149
 
63
150
  {#if isOpen}
64
- <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
+ >
65
159
  {@render children?.()}
66
160
  </div>
67
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,7 +83,6 @@
85
83
  </div>
86
84
  </div>
87
85
  {:else}
88
- <!-- Empty State -->
89
86
  <div
90
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'
@@ -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"