@stacksjs/components 0.2.92 → 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 (188) hide show
  1. package/dist/{Sidebar-yb115a2w.stx → Sidebar-4hn7vw4n.stx} +18 -0
  2. package/dist/index.js +5 -5
  3. package/package.json +5 -6
  4. package/src/components/CodeBlock.stx +0 -54
  5. package/src/components/Footer.stx +0 -66
  6. package/src/components/Hero.stx +0 -25
  7. package/src/components/Installation.stx +0 -37
  8. package/src/components/index.ts +0 -4
  9. package/src/composables/index.ts +0 -4
  10. package/src/composables/useCopyCode.ts +0 -73
  11. package/src/composables/useDarkMode.ts +0 -100
  12. package/src/composables/useSEO.ts +0 -230
  13. package/src/composables/utilities/index.ts +0 -7
  14. package/src/composables/utilities/useClickOutside.ts +0 -72
  15. package/src/composables/utilities/useFocusTrap.ts +0 -159
  16. package/src/composables/utilities/useKeyboard.ts +0 -124
  17. package/src/composables/utilities/useLocalStorage.ts +0 -132
  18. package/src/composables/utilities/useMediaQuery.ts +0 -118
  19. package/src/index.ts +0 -99
  20. package/src/stx.d.ts +0 -4
  21. package/src/ui/accordion/Accordion.stx +0 -146
  22. package/src/ui/accordion/AccordionItem.stx +0 -37
  23. package/src/ui/accordion/index.ts +0 -47
  24. package/src/ui/audio/Audio.stx +0 -50
  25. package/src/ui/audio/README.md +0 -41
  26. package/src/ui/audio/index.ts +0 -13
  27. package/src/ui/auth/Login.stx +0 -161
  28. package/src/ui/auth/README.md +0 -142
  29. package/src/ui/auth/Signup.stx +0 -159
  30. package/src/ui/auth/TwoFactorChallenge.stx +0 -111
  31. package/src/ui/auth/index.ts +0 -32
  32. package/src/ui/avatar/Avatar.stx +0 -77
  33. package/src/ui/avatar/index.ts +0 -12
  34. package/src/ui/badge/Badge.stx +0 -62
  35. package/src/ui/badge/index.ts +0 -10
  36. package/src/ui/breadcrumb/Breadcrumb.stx +0 -79
  37. package/src/ui/breadcrumb/index.ts +0 -15
  38. package/src/ui/button/Button.stx +0 -74
  39. package/src/ui/button/README.md +0 -80
  40. package/src/ui/button/index.ts +0 -85
  41. package/src/ui/calendar/Calendar.stx +0 -189
  42. package/src/ui/calendar/README.md +0 -254
  43. package/src/ui/calendar/index.ts +0 -14
  44. package/src/ui/card/Card.stx +0 -68
  45. package/src/ui/card/index.ts +0 -13
  46. package/src/ui/checkbox/Checkbox.stx +0 -86
  47. package/src/ui/checkbox/index.ts +0 -16
  48. package/src/ui/combobox/Combobox.stx +0 -96
  49. package/src/ui/combobox/ComboboxButton.stx +0 -25
  50. package/src/ui/combobox/ComboboxInput.stx +0 -32
  51. package/src/ui/combobox/ComboboxOption.stx +0 -49
  52. package/src/ui/combobox/ComboboxOptions.stx +0 -16
  53. package/src/ui/combobox/README.md +0 -150
  54. package/src/ui/combobox/index.ts +0 -40
  55. package/src/ui/command-palette/CommandPalette.stx +0 -81
  56. package/src/ui/command-palette/CommandPaletteItem.stx +0 -27
  57. package/src/ui/command-palette/README.md +0 -42
  58. package/src/ui/command-palette/index.ts +0 -15
  59. package/src/ui/dialog/Dialog.stx +0 -41
  60. package/src/ui/dialog/DialogBackdrop.stx +0 -9
  61. package/src/ui/dialog/DialogDescription.stx +0 -11
  62. package/src/ui/dialog/DialogPanel.stx +0 -16
  63. package/src/ui/dialog/DialogTitle.stx +0 -11
  64. package/src/ui/dialog/README.md +0 -121
  65. package/src/ui/dialog/index.ts +0 -32
  66. package/src/ui/drawer/Drawer.stx +0 -120
  67. package/src/ui/drawer/README.md +0 -90
  68. package/src/ui/drawer/index.ts +0 -9
  69. package/src/ui/dropdown/Dropdown.stx +0 -82
  70. package/src/ui/dropdown/DropdownButton.stx +0 -29
  71. package/src/ui/dropdown/DropdownItem.stx +0 -35
  72. package/src/ui/dropdown/DropdownItems.stx +0 -18
  73. package/src/ui/dropdown/README.md +0 -114
  74. package/src/ui/dropdown/index.ts +0 -29
  75. package/src/ui/form/Form.stx +0 -95
  76. package/src/ui/form/index.ts +0 -67
  77. package/src/ui/heatmap/Heatmap.stx +0 -294
  78. package/src/ui/image/Image.stx +0 -165
  79. package/src/ui/image/README.md +0 -164
  80. package/src/ui/image/index.ts +0 -22
  81. package/src/ui/input/EmailInput.stx +0 -30
  82. package/src/ui/input/NumberInput.stx +0 -126
  83. package/src/ui/input/PasswordInput.stx +0 -143
  84. package/src/ui/input/SearchInput.stx +0 -44
  85. package/src/ui/input/TextInput.stx +0 -132
  86. package/src/ui/input/index.ts +0 -180
  87. package/src/ui/listbox/Listbox.stx +0 -101
  88. package/src/ui/listbox/ListboxButton.stx +0 -28
  89. package/src/ui/listbox/ListboxLabel.stx +0 -11
  90. package/src/ui/listbox/ListboxOption.stx +0 -49
  91. package/src/ui/listbox/ListboxOptions.stx +0 -16
  92. package/src/ui/listbox/README.md +0 -135
  93. package/src/ui/listbox/index.ts +0 -39
  94. package/src/ui/navigator/Navigator.stx +0 -113
  95. package/src/ui/navigator/README.md +0 -352
  96. package/src/ui/navigator/index.ts +0 -20
  97. package/src/ui/notification/Notification.stx +0 -117
  98. package/src/ui/notification/README.md +0 -114
  99. package/src/ui/notification/index.ts +0 -12
  100. package/src/ui/pagination/Pagination.stx +0 -150
  101. package/src/ui/pagination/index.ts +0 -11
  102. package/src/ui/payment/Checkout.stx +0 -31
  103. package/src/ui/payment/DefaultPaymentMethod.stx +0 -62
  104. package/src/ui/payment/PaymentMethods.stx +0 -104
  105. package/src/ui/payment/README.md +0 -345
  106. package/src/ui/payment/SubscriptionCheckout.stx +0 -323
  107. package/src/ui/payment/index.ts +0 -59
  108. package/src/ui/popover/Popover.stx +0 -60
  109. package/src/ui/popover/PopoverButton.stx +0 -29
  110. package/src/ui/popover/PopoverPanel.stx +0 -23
  111. package/src/ui/popover/README.md +0 -91
  112. package/src/ui/popover/index.ts +0 -22
  113. package/src/ui/portal/Portal.stx +0 -57
  114. package/src/ui/portal/index.ts +0 -6
  115. package/src/ui/progress/Progress.stx +0 -131
  116. package/src/ui/progress/index.ts +0 -12
  117. package/src/ui/radio/Radio.stx +0 -77
  118. package/src/ui/radio/index.ts +0 -15
  119. package/src/ui/radio-group/README.md +0 -139
  120. package/src/ui/radio-group/RadioGroup.stx +0 -60
  121. package/src/ui/radio-group/RadioGroupDescription.stx +0 -11
  122. package/src/ui/radio-group/RadioGroupLabel.stx +0 -11
  123. package/src/ui/radio-group/RadioGroupOption.stx +0 -58
  124. package/src/ui/radio-group/index.ts +0 -30
  125. package/src/ui/select/README.md +0 -180
  126. package/src/ui/select/Select.stx +0 -82
  127. package/src/ui/select/index.ts +0 -21
  128. package/src/ui/sidebar/Sidebar.stx +0 -458
  129. package/src/ui/sidebar/SidebarFooter.stx +0 -71
  130. package/src/ui/sidebar/SidebarHeader.stx +0 -103
  131. package/src/ui/sidebar/SidebarItem.stx +0 -86
  132. package/src/ui/sidebar/SidebarSection.stx +0 -83
  133. package/src/ui/sidebar/index.ts +0 -153
  134. package/src/ui/sidebar/themes.ts +0 -240
  135. package/src/ui/skeleton/Skeleton.stx +0 -48
  136. package/src/ui/skeleton/index.ts +0 -11
  137. package/src/ui/spinner/Spinner.stx +0 -109
  138. package/src/ui/spinner/index.ts +0 -9
  139. package/src/ui/stepper/README.md +0 -36
  140. package/src/ui/stepper/Stepper.stx +0 -17
  141. package/src/ui/stepper/StepperStep.stx +0 -57
  142. package/src/ui/stepper/index.ts +0 -19
  143. package/src/ui/storage/README.md +0 -193
  144. package/src/ui/storage/index.ts +0 -347
  145. package/src/ui/switch/README.md +0 -114
  146. package/src/ui/switch/Switch.stx +0 -72
  147. package/src/ui/switch/index.ts +0 -10
  148. package/src/ui/table/README.md +0 -39
  149. package/src/ui/table/Table.stx +0 -14
  150. package/src/ui/table/TableBody.stx +0 -10
  151. package/src/ui/table/TableCell.stx +0 -10
  152. package/src/ui/table/TableHead.stx +0 -10
  153. package/src/ui/table/TableHeader.stx +0 -20
  154. package/src/ui/table/TableRow.stx +0 -11
  155. package/src/ui/table/index.ts +0 -35
  156. package/src/ui/tabs/TabPanel.stx +0 -25
  157. package/src/ui/tabs/Tabs.stx +0 -202
  158. package/src/ui/tabs/index.ts +0 -50
  159. package/src/ui/teleport/Teleport.stx +0 -65
  160. package/src/ui/teleport/index.ts +0 -7
  161. package/src/ui/textarea/Textarea.stx +0 -108
  162. package/src/ui/textarea/index.ts +0 -20
  163. package/src/ui/tooltip/Tooltip.stx +0 -71
  164. package/src/ui/tooltip/index.ts +0 -10
  165. package/src/ui/transition/README.md +0 -30
  166. package/src/ui/transition/Transition.stx +0 -102
  167. package/src/ui/transition/index.ts +0 -25
  168. package/src/ui/video/README.md +0 -47
  169. package/src/ui/video/Video.stx +0 -45
  170. package/src/ui/video/index.ts +0 -16
  171. package/src/ui/virtual-list/VirtualList.stx +0 -67
  172. package/src/ui/virtual-list/index.ts +0 -10
  173. package/src/ui/virtual-table/VirtualTable.stx +0 -103
  174. package/src/ui/virtual-table/index.ts +0 -21
  175. package/src/utils/PROP_VALIDATION.md +0 -458
  176. package/src/utils/THEME_SYSTEM.md +0 -702
  177. package/src/utils/accessibility.ts +0 -841
  178. package/src/utils/animation/easing.ts +0 -368
  179. package/src/utils/animation/helpers.ts +0 -223
  180. package/src/utils/animation/index.ts +0 -5
  181. package/src/utils/animation/keyframes.ts +0 -230
  182. package/src/utils/error-handling.ts +0 -475
  183. package/src/utils/highlighter.ts +0 -93
  184. package/src/utils/i18n.ts +0 -634
  185. package/src/utils/keep-alive.ts +0 -819
  186. package/src/utils/lazy-loading.ts +0 -530
  187. package/src/utils/prop-validation.ts +0 -478
  188. 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
- }