zabi-components 5.0.22 → 7.0.0

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 (207) hide show
  1. package/README.md +139 -1478
  2. package/THEME.md +473 -0
  3. package/THEMING.md +248 -0
  4. package/dist/atoms/ActionPanel.svelte +116 -0
  5. package/dist/atoms/ActionPanel.svelte.d.ts +19 -0
  6. package/dist/atoms/Badge.svelte +1 -1
  7. package/dist/atoms/Badge.svelte.d.ts +1 -1
  8. package/dist/atoms/Button.svelte +35 -16
  9. package/dist/atoms/Button.svelte.d.ts +3 -1
  10. package/dist/atoms/Card.svelte +49 -67
  11. package/dist/atoms/Card.svelte.d.ts +4 -4
  12. package/dist/atoms/CardHeader.svelte +15 -2
  13. package/dist/atoms/CardHeader.svelte.d.ts +5 -0
  14. package/dist/atoms/Checkbox.svelte +50 -76
  15. package/dist/atoms/Checkbox.svelte.d.ts +7 -2
  16. package/dist/atoms/CodeBlock.svelte +20 -34
  17. package/dist/atoms/CodeBlock.svelte.d.ts +1 -0
  18. package/dist/atoms/ColorPicker.svelte +3 -7
  19. package/dist/atoms/Container.svelte +41 -0
  20. package/dist/atoms/Container.svelte.d.ts +12 -0
  21. package/dist/atoms/Divider.svelte +68 -0
  22. package/dist/atoms/Divider.svelte.d.ts +13 -0
  23. package/dist/atoms/FeatureCard.svelte +35 -50
  24. package/dist/atoms/FeatureCard.svelte.d.ts +9 -4
  25. package/dist/atoms/IconButton.svelte +33 -24
  26. package/dist/atoms/IconButton.svelte.d.ts +4 -8
  27. package/dist/atoms/Input.svelte +58 -26
  28. package/dist/atoms/Input.svelte.d.ts +6 -1
  29. package/dist/atoms/List.svelte +2 -7
  30. package/dist/atoms/List.svelte.d.ts +1 -6
  31. package/dist/atoms/ListItem.svelte +54 -65
  32. package/dist/atoms/ListItem.svelte.d.ts +7 -13
  33. package/dist/atoms/ListItemLeading.svelte +19 -0
  34. package/dist/atoms/ListItemLeading.svelte.d.ts +9 -0
  35. package/dist/atoms/Progress.svelte +2 -2
  36. package/dist/atoms/Radio.svelte +51 -0
  37. package/dist/atoms/Radio.svelte.d.ts +14 -0
  38. package/dist/atoms/Select.svelte +28 -33
  39. package/dist/atoms/Select.svelte.d.ts +0 -10
  40. package/dist/atoms/SelectionControl.svelte +98 -0
  41. package/dist/atoms/SelectionControl.svelte.d.ts +26 -0
  42. package/dist/atoms/Skeleton.svelte +39 -15
  43. package/dist/atoms/Skeleton.svelte.d.ts +7 -3
  44. package/dist/atoms/Table.svelte +27 -0
  45. package/dist/atoms/Table.svelte.d.ts +10 -0
  46. package/dist/atoms/Text.svelte +46 -0
  47. package/dist/atoms/Text.svelte.d.ts +13 -0
  48. package/dist/atoms/Textarea.svelte +74 -53
  49. package/dist/atoms/Textarea.svelte.d.ts +6 -2
  50. package/dist/atoms/ThemeToggle.svelte +35 -24
  51. package/dist/atoms/ThemeToggle.svelte.d.ts +1 -0
  52. package/dist/atoms/Toast.svelte +55 -31
  53. package/dist/atoms/Toast.svelte.d.ts +4 -1
  54. package/dist/atoms/Toggle.svelte +37 -22
  55. package/dist/atoms/Toggle.svelte.d.ts +2 -1
  56. package/dist/atoms/Tooltip.svelte +90 -11
  57. package/dist/atoms/index.d.ts +6 -0
  58. package/dist/atoms/index.js +6 -0
  59. package/dist/atoms/selection-control.styles.d.ts +25 -0
  60. package/dist/atoms/selection-control.styles.js +30 -0
  61. package/dist/components/atoms/index.d.ts +6 -0
  62. package/dist/components/atoms/index.d.ts.map +1 -1
  63. package/dist/components/atoms/selection-control.styles.d.ts +26 -0
  64. package/dist/components/atoms/selection-control.styles.d.ts.map +1 -0
  65. package/dist/components/index.d.ts +42 -7
  66. package/dist/components/index.d.ts.map +1 -1
  67. package/dist/components/molecules/index.d.ts +10 -0
  68. package/dist/components/molecules/index.d.ts.map +1 -1
  69. package/dist/components/molecules/navigation-menu-context.d.ts +11 -0
  70. package/dist/components/molecules/navigation-menu-context.d.ts.map +1 -1
  71. package/dist/components/molecules/toast-store.d.ts +39 -0
  72. package/dist/components/molecules/toast-store.d.ts.map +1 -0
  73. package/dist/components/organisms/index.d.ts +3 -3
  74. package/dist/components/organisms/index.d.ts.map +1 -1
  75. package/dist/components/types/page.types.d.ts +69 -0
  76. package/dist/components/types/page.types.d.ts.map +1 -0
  77. package/dist/components/types/page.types.js +1 -0
  78. package/dist/components/types/variants.d.ts +64 -0
  79. package/dist/components/types/variants.d.ts.map +1 -0
  80. package/dist/components/types/variants.js +44 -0
  81. package/dist/components/util/fixed-sidebar-flyout.d.ts +23 -0
  82. package/dist/components/util/fixed-sidebar-flyout.d.ts.map +1 -0
  83. package/dist/components/util/focus-utils.d.ts +12 -0
  84. package/dist/components/util/focus-utils.d.ts.map +1 -0
  85. package/dist/components/util/ssr-safe.d.ts +17 -0
  86. package/dist/components/util/ssr-safe.d.ts.map +1 -0
  87. package/dist/index.d.ts +42 -7
  88. package/dist/index.js +45 -10
  89. package/dist/lib/layout-width-tokens.d.ts +17 -0
  90. package/dist/lib/layout-width-tokens.d.ts.map +1 -0
  91. package/dist/lib/showcase/component-docs/Button.d.ts +3 -0
  92. package/dist/lib/showcase/component-docs/Button.d.ts.map +1 -0
  93. package/dist/lib/showcase/component-docs/Input.d.ts +3 -0
  94. package/dist/lib/showcase/component-docs/Input.d.ts.map +1 -0
  95. package/dist/lib/showcase/component-docs/List.d.ts +3 -0
  96. package/dist/lib/showcase/component-docs/List.d.ts.map +1 -0
  97. package/dist/lib/showcase/component-docs/Modal.d.ts +3 -0
  98. package/dist/lib/showcase/component-docs/Modal.d.ts.map +1 -0
  99. package/dist/lib/showcase/component-docs/Radio.d.ts +3 -0
  100. package/dist/lib/showcase/component-docs/Radio.d.ts.map +1 -0
  101. package/dist/lib/showcase/component-docs/SidebarNavigation.d.ts +3 -0
  102. package/dist/lib/showcase/component-docs/SidebarNavigation.d.ts.map +1 -0
  103. package/dist/lib/showcase/component-docs/Skeleton.d.ts +3 -0
  104. package/dist/lib/showcase/component-docs/Skeleton.d.ts.map +1 -0
  105. package/dist/lib/showcase/component-docs/_shared.d.ts +12 -0
  106. package/dist/lib/showcase/component-docs/_shared.d.ts.map +1 -0
  107. package/dist/lib/showcase/component-docs/index.d.ts +4 -0
  108. package/dist/lib/showcase/component-docs/index.d.ts.map +1 -0
  109. package/dist/lib/showcase/components-catalog.d.ts +3 -0
  110. package/dist/lib/showcase/components-catalog.d.ts.map +1 -0
  111. package/dist/lib/showcase/components-showcase-constants.d.ts +89 -0
  112. package/dist/lib/showcase/components-showcase-constants.d.ts.map +1 -0
  113. package/dist/lib/showcase/docs-sidebar-helpers.d.ts +15 -0
  114. package/dist/lib/showcase/docs-sidebar-helpers.d.ts.map +1 -0
  115. package/dist/molecules/Alert.svelte +50 -23
  116. package/dist/molecules/Alert.svelte.d.ts +1 -1
  117. package/dist/molecules/ComponentDemo.svelte +54 -51
  118. package/dist/molecules/ContactForm.svelte +70 -65
  119. package/dist/molecules/Dropdown.svelte +99 -108
  120. package/dist/molecules/Dropdown.svelte.d.ts +12 -6
  121. package/dist/molecules/EmptyState.svelte +44 -0
  122. package/dist/molecules/EmptyState.svelte.d.ts +11 -0
  123. package/dist/molecules/FormField.svelte +89 -0
  124. package/dist/molecules/FormField.svelte.d.ts +23 -0
  125. package/dist/molecules/Header.svelte +41 -0
  126. package/dist/molecules/Header.svelte.d.ts +10 -0
  127. package/dist/molecules/ImageUpload.svelte +1 -1
  128. package/dist/molecules/Modal.svelte +39 -26
  129. package/dist/molecules/Modal.svelte.d.ts +4 -2
  130. package/dist/molecules/NavigationMenu.svelte +16 -0
  131. package/dist/molecules/NavigationMenu.svelte.d.ts +2 -0
  132. package/dist/molecules/NavigationMenuContent.svelte +9 -1
  133. package/dist/molecules/NavigationMenuLink.svelte +1 -1
  134. package/dist/molecules/NavigationMenuTrigger.svelte +9 -4
  135. package/dist/molecules/Page.svelte +16 -0
  136. package/dist/molecules/Page.svelte.d.ts +8 -0
  137. package/dist/molecules/PropsTable.svelte +61 -0
  138. package/dist/molecules/PropsTable.svelte.d.ts +8 -0
  139. package/dist/molecules/RadioGroup.svelte +197 -0
  140. package/dist/molecules/RadioGroup.svelte.d.ts +20 -0
  141. package/dist/molecules/Section.svelte +14 -23
  142. package/dist/molecules/Section.svelte.d.ts +2 -11
  143. package/dist/molecules/SidebarBrandHeader.svelte +68 -0
  144. package/dist/molecules/SidebarBrandHeader.svelte.d.ts +10 -0
  145. package/dist/molecules/SidebarFooter.svelte +119 -0
  146. package/dist/molecules/SidebarFooter.svelte.d.ts +23 -0
  147. package/dist/molecules/SidebarNavSection.svelte +49 -0
  148. package/dist/molecules/SidebarNavSection.svelte.d.ts +14 -0
  149. package/dist/molecules/SlideUp.svelte +21 -16
  150. package/dist/molecules/SlideUp.svelte.d.ts +1 -1
  151. package/dist/molecules/Tabs.svelte +6 -11
  152. package/dist/molecules/Toaster.svelte +21 -0
  153. package/dist/molecules/Toaster.svelte.d.ts +6 -0
  154. package/dist/molecules/ToasterToast.svelte +217 -0
  155. package/dist/molecules/ToasterToast.svelte.d.ts +7 -0
  156. package/dist/molecules/index.d.ts +10 -0
  157. package/dist/molecules/index.js +10 -0
  158. package/dist/molecules/navigation-menu-context.d.ts +11 -0
  159. package/dist/molecules/navigation-menu-context.js +18 -0
  160. package/dist/molecules/toast-store.d.ts +38 -0
  161. package/dist/molecules/toast-store.js +34 -0
  162. package/dist/organisms/SidebarAccountPanel.svelte +118 -0
  163. package/dist/organisms/SidebarAccountPanel.svelte.d.ts +20 -0
  164. package/dist/organisms/SidebarNavigation.svelte +286 -212
  165. package/dist/organisms/SidebarNavigation.svelte.d.ts +22 -1
  166. package/dist/organisms/{SidebarProjectPanel.svelte → SidebarPanel.svelte} +67 -34
  167. package/dist/organisms/{SidebarProjectPanel.svelte.d.ts → SidebarPanel.svelte.d.ts} +9 -6
  168. package/dist/organisms/TopNavbar.svelte +214 -0
  169. package/dist/organisms/TopNavbar.svelte.d.ts +35 -0
  170. package/dist/organisms/index.d.ts +3 -3
  171. package/dist/organisms/index.js +3 -3
  172. package/dist/routes/lib/focus-utils.d.ts +7 -18
  173. package/dist/routes/lib/focus-utils.ts +32 -34
  174. package/dist/routes/lib/ssr-safe.ts +5 -4
  175. package/dist/routes/lib/variant-utils.ts +48 -39
  176. package/dist/types/components.d.ts +187 -0
  177. package/dist/types/components.d.ts.map +1 -0
  178. package/dist/types/events.d.ts +200 -0
  179. package/dist/types/events.d.ts.map +1 -0
  180. package/dist/types/index.d.ts +171 -0
  181. package/dist/types/index.d.ts.map +1 -0
  182. package/dist/types/page.types.d.ts +3 -0
  183. package/dist/types/page.types.d.ts.map +1 -0
  184. package/dist/types/page.types.js +1 -0
  185. package/dist/types/page.types.ts +79 -0
  186. package/dist/types/variants.d.ts +3 -0
  187. package/dist/types/variants.d.ts.map +1 -0
  188. package/dist/types/variants.js +1 -0
  189. package/dist/types/variants.ts +75 -0
  190. package/dist/util/fixed-sidebar-flyout.d.ts +22 -0
  191. package/dist/util/fixed-sidebar-flyout.js +148 -0
  192. package/dist/util/focus-utils.d.ts +11 -0
  193. package/dist/util/focus-utils.js +94 -0
  194. package/dist/util/ssr-safe.d.ts +16 -0
  195. package/dist/util/ssr-safe.js +48 -0
  196. package/dist/zabi-components-colors.css +360 -324
  197. package/dist/zabi-components-theme-dark-only.css +164 -151
  198. package/dist/zabi-components-theme-dark.css +164 -151
  199. package/dist/zabi-components-theme-only.css +253 -230
  200. package/dist/zabi-components-theme.css +253 -230
  201. package/dist/zabi-components.css +1262 -241
  202. package/docs/theme-imports.md +112 -0
  203. package/package.json +32 -10
  204. package/dist/organisms/Navbar.svelte +0 -92
  205. package/dist/organisms/Navbar.svelte.d.ts +0 -14
  206. package/dist/organisms/Navigation.svelte +0 -119
  207. package/dist/organisms/Navigation.svelte.d.ts +0 -21
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import type { ExtendedSemanticVariant } from "../../types/variants.js";
2
+ import type { ExtendedSemanticVariant } from "../types/variants.js";
3
3
  type AlertVisualVariant = Exclude<ExtendedSemanticVariant, "default">;
4
4
 
5
5
  interface Props {
@@ -44,28 +44,55 @@
44
44
  let alertRole = $derived(
45
45
  variant === "success" || variant === "info" ? "status" : "alert",
46
46
  );
47
+ </script>
47
48
 
48
- let iconSvg = $derived({
49
- info: `<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
50
- <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />
51
- </svg>`,
52
- success: `<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
53
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
54
- </svg>`,
55
- warning: `<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
56
- <path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
57
- </svg>`,
58
- error: `<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
59
- <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
60
- </svg>`,
61
- neutral: `<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
62
- <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zM10 9a1 1 0 100 2 1 1 0 000-2z" clip-rule="evenodd" />
63
- </svg>`,
64
- energetic: `<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
49
+ {#snippet icon()}
50
+ {#if visualVariant === "info"}
51
+ <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
52
+ <path
53
+ fill-rule="evenodd"
54
+ d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
55
+ clip-rule="evenodd"
56
+ />
57
+ </svg>
58
+ {:else if visualVariant === "success"}
59
+ <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
60
+ <path
61
+ fill-rule="evenodd"
62
+ d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
63
+ clip-rule="evenodd"
64
+ />
65
+ </svg>
66
+ {:else if visualVariant === "warning"}
67
+ <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
68
+ <path
69
+ fill-rule="evenodd"
70
+ d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
71
+ clip-rule="evenodd"
72
+ />
73
+ </svg>
74
+ {:else if visualVariant === "error"}
75
+ <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
76
+ <path
77
+ fill-rule="evenodd"
78
+ d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
79
+ clip-rule="evenodd"
80
+ />
81
+ </svg>
82
+ {:else if visualVariant === "neutral"}
83
+ <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
84
+ <path
85
+ fill-rule="evenodd"
86
+ d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zM10 9a1 1 0 100 2 1 1 0 000-2z"
87
+ clip-rule="evenodd"
88
+ />
89
+ </svg>
90
+ {:else}
91
+ <svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
65
92
  <path d="M11 3L4 14h6l-1 7 7-11h-6l1-7z" />
66
- </svg>`,
67
- });
68
- </script>
93
+ </svg>
94
+ {/if}
95
+ {/snippet}
69
96
 
70
97
  <div
71
98
  class="relative rounded-md p-4 border {alertClasses[
@@ -81,7 +108,7 @@
81
108
  {#if closable}
82
109
  <button
83
110
  onclick={handleDismiss}
84
- class="absolute top-2 right-2 z-10 w-6 h-6 flex items-center justify-center rounded-full text-description hover:text-body transition-colors duration-200 motion-reduce:transition-none group focus:outline-none focus:ring-2 focus:ring-focus-ring focus:ring-offset-2"
111
+ class="group absolute right-2 top-2 z-10 flex h-6 w-6 cursor-pointer items-center justify-center rounded-full text-description transition-colors duration-200 hover:text-body motion-reduce:transition-none focus-ring"
85
112
  aria-label="Dismiss alert"
86
113
  type="button"
87
114
  >
@@ -103,7 +130,7 @@
103
130
 
104
131
  <div class="flex items-start gap-3 {closable ? 'pr-8' : ''}">
105
132
  <div class="shrink-0 mt-0.5">
106
- {@html iconSvg[visualVariant]}
133
+ {@render icon()}
107
134
  </div>
108
135
 
109
136
  <div class="flex-1 min-w-0">
@@ -1,4 +1,4 @@
1
- import type { ExtendedSemanticVariant } from "../../types/variants.js";
1
+ import type { ExtendedSemanticVariant } from "../types/variants.js";
2
2
  interface Props {
3
3
  variant?: ExtendedSemanticVariant;
4
4
  title?: string;
@@ -1,6 +1,8 @@
1
1
  <script lang="ts">
2
2
  import CodeBlock from "../atoms/CodeBlock.svelte";
3
3
  import Card from "../atoms/Card.svelte";
4
+ import CardHeader from "../atoms/CardHeader.svelte";
5
+ import CardContent from "../atoms/CardContent.svelte";
4
6
 
5
7
  interface Props {
6
8
  title: string;
@@ -27,61 +29,62 @@
27
29
  <Card
28
30
  size="lg"
29
31
  fullWidth={true}
30
- {title}
31
- {description}
32
- className="overflow-hidden {className}"
32
+ className="overflow-visible {className}"
33
33
  {...restProps}
34
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
- >
35
+ <CardHeader {title} {description} />
36
+ <CardContent>
37
+ <button
38
+ onclick={() => (showCode = !showCode)}
39
+ class="absolute top-8 right-8 z-10 flex cursor-pointer items-center gap-2 rounded-md px-3 py-1.5 text-sm text-description transition-colors duration-200 hover:bg-base-50 hover:text-body"
40
+ aria-label={showCode ? "Show preview" : "Show code"}
41
+ >
42
+ {#if showCode}
43
+ <svg
44
+ class="w-4 h-4"
45
+ fill="none"
46
+ stroke="currentColor"
47
+ viewBox="0 0 24 24"
48
+ >
49
+ <path
50
+ stroke-linecap="round"
51
+ stroke-linejoin="round"
52
+ stroke-width="2"
53
+ d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"
54
+ />
55
+ <path
56
+ stroke-linecap="round"
57
+ stroke-linejoin="round"
58
+ stroke-width="2"
59
+ 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"
60
+ />
61
+ </svg>
62
+ Preview
63
+ {:else}
64
+ <svg
65
+ class="w-4 h-4"
66
+ fill="none"
67
+ stroke="currentColor"
68
+ viewBox="0 0 24 24"
69
+ >
70
+ <path
71
+ stroke-linecap="round"
72
+ stroke-linejoin="round"
73
+ stroke-width="2"
74
+ d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"
75
+ />
76
+ </svg>
77
+ Code
78
+ {/if}
79
+ </button>
80
+
40
81
  {#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
82
+ <CodeBlock {code} {language} />
61
83
  {: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
84
+ <div class="min-h-[100px] w-full min-w-0 py-4">
85
+ {@render children?.()}
86
+ </div>
76
87
  {/if}
77
- </button>
78
-
79
- {#if showCode}
80
- <CodeBlock {code} {language} />
81
- {:else}
82
- <div class="min-h-[100px] flex items-center justify-center w-full">
83
- {@render children?.()}
84
- </div>
85
- {/if}
88
+ </CardContent>
86
89
  </Card>
87
90
  </div>
@@ -5,7 +5,9 @@
5
5
  import Checkbox from "../atoms/Checkbox.svelte";
6
6
  import Button from "../atoms/Button.svelte";
7
7
  import Card from "../atoms/Card.svelte";
8
- import type { ContactFormData } from "../../types/page.types";
8
+ import CardHeader from "../atoms/CardHeader.svelte";
9
+ import CardContent from "../atoms/CardContent.svelte";
10
+ import type { ContactFormData } from "../types/page.types";
9
11
 
10
12
  interface Props {
11
13
  className?: string;
@@ -71,69 +73,72 @@
71
73
  </script>
72
74
 
73
75
  <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}
86
- <div class="space-y-4">
87
- <Input
88
- type="text"
89
- name="name"
90
- label="Name"
91
- placeholder="Enter your name"
92
- value={formData.name}
93
- oninput={(e) =>
94
- (formData.name = (e.target as HTMLInputElement).value)}
95
- variant={fieldErrors.name ? "error" : "default"}
96
- message={fieldErrors.name || ""}
97
- />
98
- <Input
99
- type="email"
100
- name="email"
101
- label="Email"
102
- placeholder="Enter your email"
103
- value={formData.email}
104
- oninput={(e) =>
105
- (formData.email = (e.target as HTMLInputElement).value)}
106
- variant={fieldErrors.email ? "error" : "default"}
107
- message={fieldErrors.email || ""}
108
- />
109
- <Textarea
110
- name="message"
111
- label="Message"
112
- placeholder="Enter your message"
113
- rows={4}
114
- value={formData.message}
115
- oninput={(e) =>
116
- (formData.message = (
117
- e.target as HTMLTextAreaElement
118
- ).value)}
119
- variant={fieldErrors.message ? "error" : "default"}
120
- message={fieldErrors.message || ""}
121
- />
122
- <Checkbox
123
- name="subscribe"
124
- label="Subscribe to updates"
125
- checked={formData.subscribe}
126
- onchange={(e) =>
127
- (formData.subscribe = (
128
- e.target as HTMLInputElement
129
- ).checked)}
130
- />
131
- </div>
132
- <div class="pt-4">
133
- <Button type="submit" variant="primary" size="md">
134
- Send Message
135
- </Button>
136
- </div>
137
- </Form>
76
+ <Card size="md" fullWidth={true}>
77
+ <CardHeader title="Get in Touch" />
78
+ <CardContent>
79
+ <Form onsubmit={handleFormSubmit} className="space-y-4">
80
+ {#if formErrorMessage}
81
+ <div
82
+ class="rounded-lg border border-error px-4 py-3 text-sm text-error"
83
+ role="alert"
84
+ >
85
+ <p class="font-medium">Something went wrong</p>
86
+ <p>{formErrorMessage}</p>
87
+ <p class="mt-1">Recovery action: review your inputs and resubmit.</p>
88
+ </div>
89
+ {/if}
90
+ <div class="space-y-4">
91
+ <Input
92
+ type="text"
93
+ name="name"
94
+ label="Name"
95
+ placeholder="Enter your name"
96
+ value={formData.name}
97
+ oninput={(e) =>
98
+ (formData.name = (e.target as HTMLInputElement).value)}
99
+ variant={fieldErrors.name ? "error" : "default"}
100
+ message={fieldErrors.name || ""}
101
+ />
102
+ <Input
103
+ type="email"
104
+ name="email"
105
+ label="Email"
106
+ placeholder="Enter your email"
107
+ value={formData.email}
108
+ oninput={(e) =>
109
+ (formData.email = (e.target as HTMLInputElement).value)}
110
+ variant={fieldErrors.email ? "error" : "default"}
111
+ message={fieldErrors.email || ""}
112
+ />
113
+ <Textarea
114
+ name="message"
115
+ label="Message"
116
+ placeholder="Enter your message"
117
+ rows={4}
118
+ value={formData.message}
119
+ oninput={(e) =>
120
+ (formData.message = (
121
+ e.target as HTMLTextAreaElement
122
+ ).value)}
123
+ variant={fieldErrors.message ? "error" : "default"}
124
+ message={fieldErrors.message || ""}
125
+ />
126
+ <Checkbox
127
+ name="subscribe"
128
+ label="Subscribe to updates"
129
+ checked={formData.subscribe}
130
+ onchange={(e) =>
131
+ (formData.subscribe = (
132
+ e.target as HTMLInputElement
133
+ ).checked)}
134
+ />
135
+ </div>
136
+ <div class="pt-4">
137
+ <Button type="submit" variant="primary" size="md">
138
+ Send Message
139
+ </Button>
140
+ </div>
141
+ </Form>
142
+ </CardContent>
138
143
  </Card>
139
144
  </div>