@stacksjs/components 0.2.93 → 0.2.94

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 (187) hide show
  1. package/dist/index.js +4 -4
  2. package/package.json +5 -6
  3. package/src/components/CodeBlock.stx +0 -54
  4. package/src/components/Footer.stx +0 -66
  5. package/src/components/Hero.stx +0 -25
  6. package/src/components/Installation.stx +0 -37
  7. package/src/components/index.ts +0 -4
  8. package/src/composables/index.ts +0 -4
  9. package/src/composables/useCopyCode.ts +0 -73
  10. package/src/composables/useDarkMode.ts +0 -100
  11. package/src/composables/useSEO.ts +0 -230
  12. package/src/composables/utilities/index.ts +0 -7
  13. package/src/composables/utilities/useClickOutside.ts +0 -72
  14. package/src/composables/utilities/useFocusTrap.ts +0 -159
  15. package/src/composables/utilities/useKeyboard.ts +0 -124
  16. package/src/composables/utilities/useLocalStorage.ts +0 -132
  17. package/src/composables/utilities/useMediaQuery.ts +0 -118
  18. package/src/index.ts +0 -99
  19. package/src/stx.d.ts +0 -4
  20. package/src/ui/accordion/Accordion.stx +0 -146
  21. package/src/ui/accordion/AccordionItem.stx +0 -37
  22. package/src/ui/accordion/index.ts +0 -47
  23. package/src/ui/audio/Audio.stx +0 -50
  24. package/src/ui/audio/README.md +0 -41
  25. package/src/ui/audio/index.ts +0 -13
  26. package/src/ui/auth/Login.stx +0 -161
  27. package/src/ui/auth/README.md +0 -142
  28. package/src/ui/auth/Signup.stx +0 -159
  29. package/src/ui/auth/TwoFactorChallenge.stx +0 -111
  30. package/src/ui/auth/index.ts +0 -32
  31. package/src/ui/avatar/Avatar.stx +0 -77
  32. package/src/ui/avatar/index.ts +0 -12
  33. package/src/ui/badge/Badge.stx +0 -62
  34. package/src/ui/badge/index.ts +0 -10
  35. package/src/ui/breadcrumb/Breadcrumb.stx +0 -79
  36. package/src/ui/breadcrumb/index.ts +0 -15
  37. package/src/ui/button/Button.stx +0 -74
  38. package/src/ui/button/README.md +0 -80
  39. package/src/ui/button/index.ts +0 -85
  40. package/src/ui/calendar/Calendar.stx +0 -189
  41. package/src/ui/calendar/README.md +0 -254
  42. package/src/ui/calendar/index.ts +0 -14
  43. package/src/ui/card/Card.stx +0 -68
  44. package/src/ui/card/index.ts +0 -13
  45. package/src/ui/checkbox/Checkbox.stx +0 -86
  46. package/src/ui/checkbox/index.ts +0 -16
  47. package/src/ui/combobox/Combobox.stx +0 -96
  48. package/src/ui/combobox/ComboboxButton.stx +0 -25
  49. package/src/ui/combobox/ComboboxInput.stx +0 -32
  50. package/src/ui/combobox/ComboboxOption.stx +0 -49
  51. package/src/ui/combobox/ComboboxOptions.stx +0 -16
  52. package/src/ui/combobox/README.md +0 -150
  53. package/src/ui/combobox/index.ts +0 -40
  54. package/src/ui/command-palette/CommandPalette.stx +0 -81
  55. package/src/ui/command-palette/CommandPaletteItem.stx +0 -27
  56. package/src/ui/command-palette/README.md +0 -42
  57. package/src/ui/command-palette/index.ts +0 -15
  58. package/src/ui/dialog/Dialog.stx +0 -41
  59. package/src/ui/dialog/DialogBackdrop.stx +0 -9
  60. package/src/ui/dialog/DialogDescription.stx +0 -11
  61. package/src/ui/dialog/DialogPanel.stx +0 -16
  62. package/src/ui/dialog/DialogTitle.stx +0 -11
  63. package/src/ui/dialog/README.md +0 -121
  64. package/src/ui/dialog/index.ts +0 -32
  65. package/src/ui/drawer/Drawer.stx +0 -120
  66. package/src/ui/drawer/README.md +0 -90
  67. package/src/ui/drawer/index.ts +0 -9
  68. package/src/ui/dropdown/Dropdown.stx +0 -82
  69. package/src/ui/dropdown/DropdownButton.stx +0 -29
  70. package/src/ui/dropdown/DropdownItem.stx +0 -35
  71. package/src/ui/dropdown/DropdownItems.stx +0 -18
  72. package/src/ui/dropdown/README.md +0 -114
  73. package/src/ui/dropdown/index.ts +0 -29
  74. package/src/ui/form/Form.stx +0 -95
  75. package/src/ui/form/index.ts +0 -67
  76. package/src/ui/heatmap/Heatmap.stx +0 -294
  77. package/src/ui/image/Image.stx +0 -165
  78. package/src/ui/image/README.md +0 -164
  79. package/src/ui/image/index.ts +0 -22
  80. package/src/ui/input/EmailInput.stx +0 -30
  81. package/src/ui/input/NumberInput.stx +0 -126
  82. package/src/ui/input/PasswordInput.stx +0 -143
  83. package/src/ui/input/SearchInput.stx +0 -44
  84. package/src/ui/input/TextInput.stx +0 -132
  85. package/src/ui/input/index.ts +0 -180
  86. package/src/ui/listbox/Listbox.stx +0 -101
  87. package/src/ui/listbox/ListboxButton.stx +0 -28
  88. package/src/ui/listbox/ListboxLabel.stx +0 -11
  89. package/src/ui/listbox/ListboxOption.stx +0 -49
  90. package/src/ui/listbox/ListboxOptions.stx +0 -16
  91. package/src/ui/listbox/README.md +0 -135
  92. package/src/ui/listbox/index.ts +0 -39
  93. package/src/ui/navigator/Navigator.stx +0 -113
  94. package/src/ui/navigator/README.md +0 -352
  95. package/src/ui/navigator/index.ts +0 -20
  96. package/src/ui/notification/Notification.stx +0 -117
  97. package/src/ui/notification/README.md +0 -114
  98. package/src/ui/notification/index.ts +0 -12
  99. package/src/ui/pagination/Pagination.stx +0 -150
  100. package/src/ui/pagination/index.ts +0 -11
  101. package/src/ui/payment/Checkout.stx +0 -31
  102. package/src/ui/payment/DefaultPaymentMethod.stx +0 -62
  103. package/src/ui/payment/PaymentMethods.stx +0 -104
  104. package/src/ui/payment/README.md +0 -345
  105. package/src/ui/payment/SubscriptionCheckout.stx +0 -323
  106. package/src/ui/payment/index.ts +0 -59
  107. package/src/ui/popover/Popover.stx +0 -60
  108. package/src/ui/popover/PopoverButton.stx +0 -29
  109. package/src/ui/popover/PopoverPanel.stx +0 -23
  110. package/src/ui/popover/README.md +0 -91
  111. package/src/ui/popover/index.ts +0 -22
  112. package/src/ui/portal/Portal.stx +0 -57
  113. package/src/ui/portal/index.ts +0 -6
  114. package/src/ui/progress/Progress.stx +0 -131
  115. package/src/ui/progress/index.ts +0 -12
  116. package/src/ui/radio/Radio.stx +0 -77
  117. package/src/ui/radio/index.ts +0 -15
  118. package/src/ui/radio-group/README.md +0 -139
  119. package/src/ui/radio-group/RadioGroup.stx +0 -60
  120. package/src/ui/radio-group/RadioGroupDescription.stx +0 -11
  121. package/src/ui/radio-group/RadioGroupLabel.stx +0 -11
  122. package/src/ui/radio-group/RadioGroupOption.stx +0 -58
  123. package/src/ui/radio-group/index.ts +0 -30
  124. package/src/ui/select/README.md +0 -180
  125. package/src/ui/select/Select.stx +0 -82
  126. package/src/ui/select/index.ts +0 -21
  127. package/src/ui/sidebar/Sidebar.stx +0 -476
  128. package/src/ui/sidebar/SidebarFooter.stx +0 -71
  129. package/src/ui/sidebar/SidebarHeader.stx +0 -103
  130. package/src/ui/sidebar/SidebarItem.stx +0 -86
  131. package/src/ui/sidebar/SidebarSection.stx +0 -83
  132. package/src/ui/sidebar/index.ts +0 -153
  133. package/src/ui/sidebar/themes.ts +0 -240
  134. package/src/ui/skeleton/Skeleton.stx +0 -48
  135. package/src/ui/skeleton/index.ts +0 -11
  136. package/src/ui/spinner/Spinner.stx +0 -109
  137. package/src/ui/spinner/index.ts +0 -9
  138. package/src/ui/stepper/README.md +0 -36
  139. package/src/ui/stepper/Stepper.stx +0 -17
  140. package/src/ui/stepper/StepperStep.stx +0 -57
  141. package/src/ui/stepper/index.ts +0 -19
  142. package/src/ui/storage/README.md +0 -193
  143. package/src/ui/storage/index.ts +0 -347
  144. package/src/ui/switch/README.md +0 -114
  145. package/src/ui/switch/Switch.stx +0 -72
  146. package/src/ui/switch/index.ts +0 -10
  147. package/src/ui/table/README.md +0 -39
  148. package/src/ui/table/Table.stx +0 -14
  149. package/src/ui/table/TableBody.stx +0 -10
  150. package/src/ui/table/TableCell.stx +0 -10
  151. package/src/ui/table/TableHead.stx +0 -10
  152. package/src/ui/table/TableHeader.stx +0 -20
  153. package/src/ui/table/TableRow.stx +0 -11
  154. package/src/ui/table/index.ts +0 -35
  155. package/src/ui/tabs/TabPanel.stx +0 -25
  156. package/src/ui/tabs/Tabs.stx +0 -202
  157. package/src/ui/tabs/index.ts +0 -50
  158. package/src/ui/teleport/Teleport.stx +0 -65
  159. package/src/ui/teleport/index.ts +0 -7
  160. package/src/ui/textarea/Textarea.stx +0 -108
  161. package/src/ui/textarea/index.ts +0 -20
  162. package/src/ui/tooltip/Tooltip.stx +0 -71
  163. package/src/ui/tooltip/index.ts +0 -10
  164. package/src/ui/transition/README.md +0 -30
  165. package/src/ui/transition/Transition.stx +0 -102
  166. package/src/ui/transition/index.ts +0 -25
  167. package/src/ui/video/README.md +0 -47
  168. package/src/ui/video/Video.stx +0 -45
  169. package/src/ui/video/index.ts +0 -16
  170. package/src/ui/virtual-list/VirtualList.stx +0 -67
  171. package/src/ui/virtual-list/index.ts +0 -10
  172. package/src/ui/virtual-table/VirtualTable.stx +0 -103
  173. package/src/ui/virtual-table/index.ts +0 -21
  174. package/src/utils/PROP_VALIDATION.md +0 -458
  175. package/src/utils/THEME_SYSTEM.md +0 -702
  176. package/src/utils/accessibility.ts +0 -841
  177. package/src/utils/animation/easing.ts +0 -368
  178. package/src/utils/animation/helpers.ts +0 -223
  179. package/src/utils/animation/index.ts +0 -5
  180. package/src/utils/animation/keyframes.ts +0 -230
  181. package/src/utils/error-handling.ts +0 -475
  182. package/src/utils/highlighter.ts +0 -93
  183. package/src/utils/i18n.ts +0 -634
  184. package/src/utils/keep-alive.ts +0 -819
  185. package/src/utils/lazy-loading.ts +0 -530
  186. package/src/utils/prop-validation.ts +0 -478
  187. package/src/utils/theme.ts +0 -626
@@ -1,626 +0,0 @@
1
- /**
2
- * Theme system for @stacksjs/components
3
- *
4
- * Provides customizable color palettes, typography, spacing, and component variants
5
- *
6
- * @example
7
- * ```ts
8
- * import { createTheme, applyTheme, useTheme } from '@stacksjs/components'
9
- *
10
- * const myTheme = createTheme({
11
- * colors: {
12
- * primary: '#3b82f6',
13
- * secondary: '#8b5cf6'
14
- * }
15
- * })
16
- *
17
- * applyTheme(myTheme)
18
- * ```
19
- */
20
-
21
- /**
22
- * Color palette definition
23
- */
24
- export interface ColorPalette {
25
- primary?: string
26
- secondary?: string
27
- success?: string
28
- warning?: string
29
- danger?: string
30
- info?: string
31
- gray?: string
32
- white?: string
33
- black?: string
34
- }
35
-
36
- /**
37
- * Typography scale
38
- */
39
- export interface Typography {
40
- fontFamily?: {
41
- sans?: string
42
- serif?: string
43
- mono?: string
44
- }
45
- fontSize?: {
46
- 'xs'?: string
47
- 'sm'?: string
48
- 'base'?: string
49
- 'lg'?: string
50
- 'xl'?: string
51
- '2xl'?: string
52
- '3xl'?: string
53
- '4xl'?: string
54
- }
55
- fontWeight?: {
56
- light?: string
57
- normal?: string
58
- medium?: string
59
- semibold?: string
60
- bold?: string
61
- }
62
- lineHeight?: {
63
- tight?: string
64
- normal?: string
65
- relaxed?: string
66
- }
67
- }
68
-
69
- /**
70
- * Spacing scale
71
- */
72
- export interface Spacing {
73
- 'xs'?: string
74
- 'sm'?: string
75
- 'md'?: string
76
- 'lg'?: string
77
- 'xl'?: string
78
- '2xl'?: string
79
- '3xl'?: string
80
- '4xl'?: string
81
- }
82
-
83
- /**
84
- * Border radius scale
85
- */
86
- export interface BorderRadius {
87
- none?: string
88
- sm?: string
89
- md?: string
90
- lg?: string
91
- full?: string
92
- }
93
-
94
- /**
95
- * Shadow scale
96
- */
97
- export interface Shadows {
98
- 'sm'?: string
99
- 'md'?: string
100
- 'lg'?: string
101
- 'xl'?: string
102
- '2xl'?: string
103
- 'none'?: string
104
- }
105
-
106
- /**
107
- * Component-specific overrides
108
- */
109
- export interface ComponentOverrides {
110
- button?: {
111
- borderRadius?: string
112
- padding?: string
113
- fontSize?: string
114
- fontWeight?: string
115
- }
116
- input?: {
117
- borderRadius?: string
118
- padding?: string
119
- fontSize?: string
120
- borderWidth?: string
121
- }
122
- card?: {
123
- borderRadius?: string
124
- padding?: string
125
- shadow?: string
126
- }
127
- }
128
-
129
- /**
130
- * Complete theme configuration
131
- */
132
- export interface Theme {
133
- colors: ColorPalette
134
- typography: Typography
135
- spacing: Spacing
136
- borderRadius: BorderRadius
137
- shadows: Shadows
138
- components?: ComponentOverrides
139
- }
140
-
141
- /**
142
- * Default theme
143
- */
144
- export const defaultTheme: Theme = {
145
- colors: {
146
- primary: '#3b82f6',
147
- secondary: '#8b5cf6',
148
- success: '#10b981',
149
- warning: '#f59e0b',
150
- danger: '#ef4444',
151
- info: '#06b6d4',
152
- gray: '#6b7280',
153
- white: '#ffffff',
154
- black: '#000000',
155
- },
156
- typography: {
157
- fontFamily: {
158
- sans: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
159
- serif: 'Georgia, Cambria, "Times New Roman", Times, serif',
160
- mono: 'Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
161
- },
162
- fontSize: {
163
- 'xs': '0.75rem',
164
- 'sm': '0.875rem',
165
- 'base': '1rem',
166
- 'lg': '1.125rem',
167
- 'xl': '1.25rem',
168
- '2xl': '1.5rem',
169
- '3xl': '1.875rem',
170
- '4xl': '2.25rem',
171
- },
172
- fontWeight: {
173
- light: '300',
174
- normal: '400',
175
- medium: '500',
176
- semibold: '600',
177
- bold: '700',
178
- },
179
- lineHeight: {
180
- tight: '1.25',
181
- normal: '1.5',
182
- relaxed: '1.75',
183
- },
184
- },
185
- spacing: {
186
- 'xs': '0.25rem',
187
- 'sm': '0.5rem',
188
- 'md': '1rem',
189
- 'lg': '1.5rem',
190
- 'xl': '2rem',
191
- '2xl': '3rem',
192
- '3xl': '4rem',
193
- '4xl': '6rem',
194
- },
195
- borderRadius: {
196
- none: '0',
197
- sm: '0.125rem',
198
- md: '0.375rem',
199
- lg: '0.5rem',
200
- full: '9999px',
201
- },
202
- shadows: {
203
- 'sm': '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
204
- 'md': '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
205
- 'lg': '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
206
- 'xl': '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
207
- '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
208
- 'none': 'none',
209
- },
210
- components: {
211
- button: {
212
- borderRadius: '0.375rem',
213
- padding: '0.5rem 1rem',
214
- fontSize: '0.875rem',
215
- fontWeight: '500',
216
- },
217
- input: {
218
- borderRadius: '0.375rem',
219
- padding: '0.5rem 0.75rem',
220
- fontSize: '0.875rem',
221
- borderWidth: '1px',
222
- },
223
- card: {
224
- borderRadius: '0.5rem',
225
- padding: '1.5rem',
226
- shadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1)',
227
- },
228
- },
229
- }
230
-
231
- /**
232
- * Deep merge two objects
233
- */
234
- function deepMerge<T extends object>(target: T, source: Partial<T>): T {
235
- const output = { ...target }
236
-
237
- for (const key in source) {
238
- if (source[key] instanceof Object && key in target) {
239
- output[key] = deepMerge(target[key] as any, source[key] as any)
240
- }
241
- else {
242
- output[key] = source[key] as any
243
- }
244
- }
245
-
246
- return output
247
- }
248
-
249
- /**
250
- * Create a custom theme by merging with default theme
251
- *
252
- * @param customTheme - Partial theme configuration
253
- * @returns Complete theme object
254
- *
255
- * @example
256
- * ```ts
257
- * const myTheme = createTheme({
258
- * colors: {
259
- * primary: '#3b82f6',
260
- * secondary: '#8b5cf6'
261
- * },
262
- * typography: {
263
- * fontFamily: {
264
- * sans: 'Inter, sans-serif'
265
- * }
266
- * }
267
- * })
268
- * ```
269
- */
270
- export function createTheme(customTheme: Partial<Theme>): Theme {
271
- return deepMerge(defaultTheme, customTheme)
272
- }
273
-
274
- /**
275
- * Current active theme
276
- */
277
- let currentTheme: Theme = defaultTheme
278
-
279
- /**
280
- * Get the current active theme
281
- *
282
- * @returns Current theme object
283
- */
284
- export function getTheme(): Theme {
285
- return currentTheme
286
- }
287
-
288
- /**
289
- * Convert theme to CSS custom properties
290
- *
291
- * @param theme - Theme object
292
- * @returns CSS custom properties string
293
- */
294
- export function themeToCSSProperties(theme: Theme): string {
295
- const cssVars: string[] = []
296
-
297
- // Colors
298
- if (theme.colors) {
299
- Object.entries(theme.colors).forEach(([key, value]) => {
300
- if (value)
301
- cssVars.push(`--color-${key}: ${value};`)
302
- })
303
- }
304
-
305
- // Typography
306
- if (theme.typography?.fontFamily) {
307
- Object.entries(theme.typography.fontFamily).forEach(([key, value]) => {
308
- if (value)
309
- cssVars.push(`--font-${key}: ${value};`)
310
- })
311
- }
312
-
313
- if (theme.typography?.fontSize) {
314
- Object.entries(theme.typography.fontSize).forEach(([key, value]) => {
315
- if (value)
316
- cssVars.push(`--text-${key}: ${value};`)
317
- })
318
- }
319
-
320
- if (theme.typography?.fontWeight) {
321
- Object.entries(theme.typography.fontWeight).forEach(([key, value]) => {
322
- if (value)
323
- cssVars.push(`--font-weight-${key}: ${value};`)
324
- })
325
- }
326
-
327
- if (theme.typography?.lineHeight) {
328
- Object.entries(theme.typography.lineHeight).forEach(([key, value]) => {
329
- if (value)
330
- cssVars.push(`--leading-${key}: ${value};`)
331
- })
332
- }
333
-
334
- // Spacing
335
- if (theme.spacing) {
336
- Object.entries(theme.spacing).forEach(([key, value]) => {
337
- if (value)
338
- cssVars.push(`--spacing-${key}: ${value};`)
339
- })
340
- }
341
-
342
- // Border radius
343
- if (theme.borderRadius) {
344
- Object.entries(theme.borderRadius).forEach(([key, value]) => {
345
- if (value)
346
- cssVars.push(`--radius-${key}: ${value};`)
347
- })
348
- }
349
-
350
- // Shadows
351
- if (theme.shadows) {
352
- Object.entries(theme.shadows).forEach(([key, value]) => {
353
- if (value)
354
- cssVars.push(`--shadow-${key}: ${value};`)
355
- })
356
- }
357
-
358
- // Component overrides
359
- if (theme.components?.button) {
360
- Object.entries(theme.components.button).forEach(([key, value]) => {
361
- if (value)
362
- cssVars.push(`--button-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`)
363
- })
364
- }
365
-
366
- if (theme.components?.input) {
367
- Object.entries(theme.components.input).forEach(([key, value]) => {
368
- if (value)
369
- cssVars.push(`--input-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`)
370
- })
371
- }
372
-
373
- if (theme.components?.card) {
374
- Object.entries(theme.components.card).forEach(([key, value]) => {
375
- if (value)
376
- cssVars.push(`--card-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}: ${value};`)
377
- })
378
- }
379
-
380
- return `:root {\n ${cssVars.join('\n ')}\n}`
381
- }
382
-
383
- /**
384
- * Apply theme to the document
385
- *
386
- * @param theme - Theme object to apply
387
- * @param target - Target element (defaults to document.documentElement)
388
- *
389
- * @example
390
- * ```ts
391
- * const theme = createTheme({ colors: { primary: '#3b82f6' } })
392
- * applyTheme(theme)
393
- * ```
394
- */
395
- export function applyTheme(theme: Theme, target?: HTMLElement): void {
396
- currentTheme = theme
397
-
398
- if (typeof document === 'undefined')
399
- return
400
-
401
- const element = target || document.documentElement
402
-
403
- // Colors
404
- if (theme.colors) {
405
- Object.entries(theme.colors).forEach(([key, value]) => {
406
- if (value)
407
- element.style.setProperty(`--color-${key}`, value)
408
- })
409
- }
410
-
411
- // Typography
412
- if (theme.typography?.fontFamily) {
413
- Object.entries(theme.typography.fontFamily).forEach(([key, value]) => {
414
- if (value)
415
- element.style.setProperty(`--font-${key}`, value)
416
- })
417
- }
418
-
419
- if (theme.typography?.fontSize) {
420
- Object.entries(theme.typography.fontSize).forEach(([key, value]) => {
421
- if (value)
422
- element.style.setProperty(`--text-${key}`, value)
423
- })
424
- }
425
-
426
- if (theme.typography?.fontWeight) {
427
- Object.entries(theme.typography.fontWeight).forEach(([key, value]) => {
428
- if (value)
429
- element.style.setProperty(`--font-weight-${key}`, value)
430
- })
431
- }
432
-
433
- if (theme.typography?.lineHeight) {
434
- Object.entries(theme.typography.lineHeight).forEach(([key, value]) => {
435
- if (value)
436
- element.style.setProperty(`--leading-${key}`, value)
437
- })
438
- }
439
-
440
- // Spacing
441
- if (theme.spacing) {
442
- Object.entries(theme.spacing).forEach(([key, value]) => {
443
- if (value)
444
- element.style.setProperty(`--spacing-${key}`, value)
445
- })
446
- }
447
-
448
- // Border radius
449
- if (theme.borderRadius) {
450
- Object.entries(theme.borderRadius).forEach(([key, value]) => {
451
- if (value)
452
- element.style.setProperty(`--radius-${key}`, value)
453
- })
454
- }
455
-
456
- // Shadows
457
- if (theme.shadows) {
458
- Object.entries(theme.shadows).forEach(([key, value]) => {
459
- if (value)
460
- element.style.setProperty(`--shadow-${key}`, value)
461
- })
462
- }
463
-
464
- // Component overrides
465
- if (theme.components?.button) {
466
- Object.entries(theme.components.button).forEach(([key, value]) => {
467
- if (value)
468
- element.style.setProperty(`--button-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`, value)
469
- })
470
- }
471
-
472
- if (theme.components?.input) {
473
- Object.entries(theme.components.input).forEach(([key, value]) => {
474
- if (value)
475
- element.style.setProperty(`--input-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`, value)
476
- })
477
- }
478
-
479
- if (theme.components?.card) {
480
- Object.entries(theme.components.card).forEach(([key, value]) => {
481
- if (value)
482
- element.style.setProperty(`--card-${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`, value)
483
- })
484
- }
485
- }
486
-
487
- /**
488
- * Hook to use theme in components
489
- *
490
- * @returns Current theme object
491
- *
492
- * @example
493
- * ```ts
494
- * const theme = useTheme()
495
- * const primaryColor = theme.colors.primary
496
- * ```
497
- */
498
- export function useTheme(): Theme {
499
- return currentTheme
500
- }
501
-
502
- /**
503
- * Get a specific theme value by path
504
- *
505
- * @param path - Dot-notation path to theme value
506
- * @returns Theme value or undefined
507
- *
508
- * @example
509
- * ```ts
510
- * const primary = getThemeValue('colors.primary')
511
- * const fontSize = getThemeValue('typography.fontSize.base')
512
- * ```
513
- */
514
- export function getThemeValue(path: string): any {
515
- const keys = path.split('.')
516
- let value: any = currentTheme
517
-
518
- for (const key of keys) {
519
- if (value && typeof value === 'object' && key in value) {
520
- value = value[key]
521
- }
522
- else {
523
- return undefined
524
- }
525
- }
526
-
527
- return value
528
- }
529
-
530
- /**
531
- * Predefined theme presets
532
- */
533
- export const themePresets: {
534
- default: Theme
535
- purple: Theme
536
- green: Theme
537
- orange: Theme
538
- dark: Theme
539
- minimal: Theme
540
- } = {
541
- /**
542
- * Default blue theme
543
- */
544
- default: defaultTheme,
545
-
546
- /**
547
- * Purple theme
548
- */
549
- purple: createTheme({
550
- colors: {
551
- primary: '#8b5cf6',
552
- secondary: '#a78bfa',
553
- },
554
- }),
555
-
556
- /**
557
- * Green theme
558
- */
559
- green: createTheme({
560
- colors: {
561
- primary: '#10b981',
562
- secondary: '#34d399',
563
- },
564
- }),
565
-
566
- /**
567
- * Orange theme
568
- */
569
- orange: createTheme({
570
- colors: {
571
- primary: '#f97316',
572
- secondary: '#fb923c',
573
- },
574
- }),
575
-
576
- /**
577
- * Dark theme
578
- */
579
- dark: createTheme({
580
- colors: {
581
- primary: '#60a5fa',
582
- secondary: '#a78bfa',
583
- gray: '#9ca3af',
584
- white: '#1f2937',
585
- black: '#f9fafb',
586
- },
587
- }),
588
-
589
- /**
590
- * Minimal theme with reduced shadows and border radius
591
- */
592
- minimal: createTheme({
593
- borderRadius: {
594
- none: '0',
595
- sm: '0',
596
- md: '0.125rem',
597
- lg: '0.25rem',
598
- full: '0.25rem',
599
- },
600
- shadows: {
601
- 'sm': 'none',
602
- 'md': '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
603
- 'lg': '0 1px 3px 0 rgba(0, 0, 0, 0.1)',
604
- 'xl': '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
605
- '2xl': '0 10px 15px -3px rgba(0, 0, 0, 0.1)',
606
- 'none': 'none',
607
- },
608
- }),
609
- }
610
-
611
- /**
612
- * Generate CSS file content for a theme
613
- *
614
- * @param theme - Theme object
615
- * @returns CSS file content
616
- *
617
- * @example
618
- * ```ts
619
- * const theme = createTheme({ colors: { primary: '#3b82f6' } })
620
- * const css = generateThemeCSS(theme)
621
- * // Write to file or inject into page
622
- * ```
623
- */
624
- export function generateThemeCSS(theme: Theme): string {
625
- return themeToCSSProperties(theme)
626
- }