@reactberry/system 2.0.0-beta

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 (165) hide show
  1. package/README.md +48 -0
  2. package/package.json +74 -0
  3. package/src/blocks/Accordion/index.tsx +158 -0
  4. package/src/blocks/AnimatedCarousel/index.tsx +188 -0
  5. package/src/blocks/AppleGlow/index.tsx +144 -0
  6. package/src/blocks/Avatar/index.tsx +167 -0
  7. package/src/blocks/Await/index.tsx +45 -0
  8. package/src/blocks/Cards/AnimatedCard/index.tsx +175 -0
  9. package/src/blocks/Cards/FluorescentCard/index.tsx +180 -0
  10. package/src/blocks/Cards/InfoCard/index.tsx +206 -0
  11. package/src/blocks/Cards/TickerCard/index.tsx +125 -0
  12. package/src/blocks/Carousel/index.tsx +216 -0
  13. package/src/blocks/Checkbox/index.tsx +101 -0
  14. package/src/blocks/Collection/index.tsx +59 -0
  15. package/src/blocks/Container/index.tsx +55 -0
  16. package/src/blocks/Controls/Control.tsx +67 -0
  17. package/src/blocks/Controls/index.tsx +11 -0
  18. package/src/blocks/CyclingNumber/index.tsx +78 -0
  19. package/src/blocks/DisplaySet/index.tsx +42 -0
  20. package/src/blocks/Divider/index.tsx +14 -0
  21. package/src/blocks/Draggable/index.tsx +266 -0
  22. package/src/blocks/Drawer/index.tsx +136 -0
  23. package/src/blocks/DynamicIsland/DynamicIsland.tsx +89 -0
  24. package/src/blocks/DynamicIsland/index.tsx +2 -0
  25. package/src/blocks/Fader/index.tsx +145 -0
  26. package/src/blocks/FamilyDrawer/README.md +116 -0
  27. package/src/blocks/FamilyDrawer/example.tsx +108 -0
  28. package/src/blocks/FamilyDrawer/index.tsx +119 -0
  29. package/src/blocks/FamilyDrawer/views/DefaultView.tsx +93 -0
  30. package/src/blocks/FamilyDrawer/views/KeyView.tsx +129 -0
  31. package/src/blocks/FamilyDrawer/views/PhraseView.tsx +129 -0
  32. package/src/blocks/FamilyDrawer/views/RemoveView.tsx +81 -0
  33. package/src/blocks/FieldSet/index.tsx +173 -0
  34. package/src/blocks/Filesystem/index.tsx +198 -0
  35. package/src/blocks/Gallery/Carousel/index.tsx +257 -0
  36. package/src/blocks/Gallery/Modal/index.tsx +83 -0
  37. package/src/blocks/Gallery/index.tsx +57 -0
  38. package/src/blocks/Gallery/utils/animationVariants.ts +18 -0
  39. package/src/blocks/Gallery/utils/aspectRatio.ts +14 -0
  40. package/src/blocks/Gallery/utils/downloadPhoto.ts +24 -0
  41. package/src/blocks/Gallery/utils/range.ts +11 -0
  42. package/src/blocks/GradientMesh/index.tsx +106 -0
  43. package/src/blocks/Group/index.tsx +152 -0
  44. package/src/blocks/Heading/index.tsx +111 -0
  45. package/src/blocks/HorizontalScroller/index.tsx +135 -0
  46. package/src/blocks/Icon/index.tsx +45 -0
  47. package/src/blocks/Indicator/index.tsx +27 -0
  48. package/src/blocks/InlineEditor/index.tsx +216 -0
  49. package/src/blocks/List/index.tsx +657 -0
  50. package/src/blocks/Main/index.tsx +17 -0
  51. package/src/blocks/Marquee/index.tsx +116 -0
  52. package/src/blocks/MaskedField/index.tsx +199 -0
  53. package/src/blocks/Menu/MenuContent.tsx +246 -0
  54. package/src/blocks/Menu/MenuContext.tsx +34 -0
  55. package/src/blocks/Menu/MenuItem.tsx +104 -0
  56. package/src/blocks/Menu/index.tsx +60 -0
  57. package/src/blocks/Modal/index.tsx +268 -0
  58. package/src/blocks/MorphingPopover/index.tsx +294 -0
  59. package/src/blocks/Overlay/Backdrop.tsx +48 -0
  60. package/src/blocks/Overlay/OverscrollGuard.tsx +36 -0
  61. package/src/blocks/Overlay/index.ts +2 -0
  62. package/src/blocks/Parallax/index.tsx +117 -0
  63. package/src/blocks/ParallaxSection/index.tsx +61 -0
  64. package/src/blocks/Placeholder/index.tsx +48 -0
  65. package/src/blocks/Popover/index.tsx +402 -0
  66. package/src/blocks/Progress/getProgressColor.ts +61 -0
  67. package/src/blocks/Progress/index.tsx +179 -0
  68. package/src/blocks/ProgressiveBlur/index.tsx +75 -0
  69. package/src/blocks/README.md +15 -0
  70. package/src/blocks/RenderAsset/index.tsx +18 -0
  71. package/src/blocks/ScrollContainer/index.tsx +93 -0
  72. package/src/blocks/ShinyText/index.tsx +72 -0
  73. package/src/blocks/Skeleton/index.tsx +71 -0
  74. package/src/blocks/Slider/SliderControls.tsx +119 -0
  75. package/src/blocks/Slider/index.tsx +140 -0
  76. package/src/blocks/Slider/useSlider.ts +126 -0
  77. package/src/blocks/Slideshow/index.tsx +177 -0
  78. package/src/blocks/Spotlight/index.tsx +144 -0
  79. package/src/blocks/Steps/StepIndicator.tsx +149 -0
  80. package/src/blocks/Steps/StepProgress.tsx +164 -0
  81. package/src/blocks/Steps/Steps.tsx +197 -0
  82. package/src/blocks/Steps/StepsNav.tsx +30 -0
  83. package/src/blocks/Steps/StepsTracker.tsx +80 -0
  84. package/src/blocks/Steps/hooks.ts +71 -0
  85. package/src/blocks/Steps/index.tsx +16 -0
  86. package/src/blocks/Steps/types.ts +71 -0
  87. package/src/blocks/StickySectionStack/index.tsx +136 -0
  88. package/src/blocks/Switch/index.tsx +85 -0
  89. package/src/blocks/SystemNotice/index.tsx +81 -0
  90. package/src/blocks/Table/README.md +251 -0
  91. package/src/blocks/Table/Table.tsx +207 -0
  92. package/src/blocks/Table/TablePagination.tsx +189 -0
  93. package/src/blocks/Table/index.ts +33 -0
  94. package/src/blocks/Table/useTableControls.ts +331 -0
  95. package/src/blocks/Tag/index.tsx +27 -0
  96. package/src/blocks/TextBreak/index.tsx +96 -0
  97. package/src/blocks/TextReveal/index.tsx +104 -0
  98. package/src/blocks/Thumbnail/index.tsx +26 -0
  99. package/src/blocks/Ticker/index.tsx +112 -0
  100. package/src/blocks/Toast/index.tsx +77 -0
  101. package/src/blocks/Tooltip/index.tsx +174 -0
  102. package/src/blocks/Underlay/index.tsx +104 -0
  103. package/src/blocks/Upload/Dropzone.tsx +92 -0
  104. package/src/blocks/Upload/UploadBtn.tsx +38 -0
  105. package/src/blocks/Upload/index.tsx +61 -0
  106. package/src/blocks/Upload/types.ts +37 -0
  107. package/src/blocks/VideoMarquee/index.tsx +511 -0
  108. package/src/blocks/index.ts +119 -0
  109. package/src/blocks/pagination/Pagination.tsx +148 -0
  110. package/src/blocks/pagination/PaginationList.tsx +41 -0
  111. package/src/blocks/pagination/index.ts +2 -0
  112. package/src/charts/BarChart.tsx +63 -0
  113. package/src/charts/PieChart.tsx +39 -0
  114. package/src/charts/index.ts +3 -0
  115. package/src/charts/utils.ts +103 -0
  116. package/src/docs/README.md +373 -0
  117. package/src/docs/reference/README.md +299 -0
  118. package/src/elements/box.ts +163 -0
  119. package/src/elements/button.ts +49 -0
  120. package/src/elements/field.ts +129 -0
  121. package/src/elements/index.ts +8 -0
  122. package/src/elements/text.ts +47 -0
  123. package/src/elements/utils.js +97 -0
  124. package/src/hooks/use-copy-to-clipboard.tsx +33 -0
  125. package/src/hooks/use-enter-submit.tsx +23 -0
  126. package/src/hooks/use-local-storage.ts +42 -0
  127. package/src/hooks/use-sidebar.tsx +109 -0
  128. package/src/hooks/useAnimatedText.ts +32 -0
  129. package/src/hooks/useAutosizeTextArea.ts +45 -0
  130. package/src/hooks/useBreakpoint.tsx +123 -0
  131. package/src/hooks/useClickOutside.tsx +38 -0
  132. package/src/hooks/useHover.tsx +33 -0
  133. package/src/hooks/useHoverList.tsx +17 -0
  134. package/src/hooks/useKeyboardShortcuts.ts +91 -0
  135. package/src/hooks/useKeypress.ts +27 -0
  136. package/src/hooks/useOverlay.ts +32 -0
  137. package/src/hooks/useReducedMotion.ts +25 -0
  138. package/src/hooks/useStandaloneMode.ts +35 -0
  139. package/src/hooks/useTouchDevice.ts +34 -0
  140. package/src/icons/index.tsx +129 -0
  141. package/src/index.ts +12 -0
  142. package/src/providers/DesignSystemProvider.tsx +35 -0
  143. package/src/providers/StyledComponentsRegistry.tsx +30 -0
  144. package/src/providers/index.ts +2 -0
  145. package/src/themes/README.md +30 -0
  146. package/src/themes/default/assets/badge-avatar.tsx +45 -0
  147. package/src/themes/default/assets/logo.tsx +42 -0
  148. package/src/themes/default/global.ts +138 -0
  149. package/src/themes/default/modes/dark/config.js +49 -0
  150. package/src/themes/default/modes/dark/skins.js +631 -0
  151. package/src/themes/default/modes/dark/theme.js +87 -0
  152. package/src/themes/default/modes/light/config.js +48 -0
  153. package/src/themes/default/modes/light/skins.js +1026 -0
  154. package/src/themes/default/modes/light/theme.js +74 -0
  155. package/src/themes/default/tokens/controls.js +53 -0
  156. package/src/themes/default/tokens/shadows.js +63 -0
  157. package/src/themes/default/tokens/shapes.js +37 -0
  158. package/src/themes/default/tokens/space.js +143 -0
  159. package/src/themes/default/tokens/spectre.js +16 -0
  160. package/src/themes/default/utils.js +523 -0
  161. package/src/themes/index.ts +11 -0
  162. package/src/types.ts +394 -0
  163. package/src/utils/overlayTheme.ts +61 -0
  164. package/src/utils/pickColor.ts +15 -0
  165. package/tsconfig.json +24 -0
@@ -0,0 +1,523 @@
1
+ import chroma from "chroma-js";
2
+ import { spectre } from "./tokens/spectre";
3
+
4
+ // Utility function to generate system colors
5
+ const generateSystemColors = ({
6
+ brandColor,
7
+ accentColor,
8
+ systemColor,
9
+ mixRatio,
10
+ baseSaturation,
11
+ lightPaletteLightness,
12
+ darkPaletteLightness,
13
+ }) => {
14
+ const systemColors = {
15
+ brand: brandColor,
16
+ accent: accentColor,
17
+ neutral: systemColor,
18
+ light: chroma
19
+ .mix("black", brandColor)
20
+ .set("hsl.s", baseSaturation)
21
+ .set("hsl.l", lightPaletteLightness)
22
+ .hex(),
23
+ dark: chroma
24
+ .mix("black", brandColor)
25
+ .set("hsl.s", baseSaturation)
26
+ .set("hsl.l", darkPaletteLightness)
27
+ .hex(),
28
+ };
29
+
30
+ Object.keys(spectre).forEach((key) => {
31
+ systemColors[key] = chroma.mix(spectre[key], brandColor, mixRatio).hex();
32
+ });
33
+
34
+ return systemColors;
35
+ };
36
+
37
+ // Utility function to generate color palette scales
38
+ const generatePaletteScales = (
39
+ colors,
40
+ lightBase,
41
+ palettePadding,
42
+ paletteSize,
43
+ mode
44
+ ) => {
45
+ // Define colors to exclude from palette generation
46
+ const excludedColors = ["white", "black"];
47
+ const specialColors = ["light", "dark"];
48
+
49
+ return Object.keys(colors).reduce((acc, key) => {
50
+ // Skip excluded colors
51
+ if (excludedColors.includes(key)) {
52
+ return acc;
53
+ }
54
+
55
+ // Handle special colors differently
56
+ if (specialColors.includes(key)) {
57
+ if (key === "dark") {
58
+ // For dark palette: scale direction depends on lightBase
59
+ acc[key + "s"] = chroma
60
+ .scale(
61
+ lightBase === "light"
62
+ ? [colors.dark, colors.neutral] // light theme: dark to neutral
63
+ : [colors.dark, colors.neutral] // dark theme: neutral to dark
64
+ )
65
+ .mode(mode)
66
+ .padding(palettePadding)
67
+ .colors(6);
68
+ }
69
+ if (key === "light") {
70
+ // For light palette: scale direction depends on lightBase
71
+ acc[key + "s"] = chroma
72
+ .scale(
73
+ lightBase === "light"
74
+ ? [colors.light, colors.neutral] // light theme: neutral to light
75
+ : [colors.light, colors.neutral] // dark theme: light to neutral
76
+ )
77
+ .mode(mode)
78
+ .padding(palettePadding)
79
+ .colors(6);
80
+ }
81
+ } else {
82
+ // Regular colors
83
+ acc[key + "s"] = chroma
84
+ .scale(
85
+ lightBase === "light"
86
+ ? [
87
+ chroma(colors[key]).brighten(10),
88
+ colors[key],
89
+ chroma(colors[key]).darken(10),
90
+ ]
91
+ : [
92
+ chroma(colors[key]).darken(10),
93
+ colors[key],
94
+ chroma(colors[key]).brighten(10),
95
+ ]
96
+ )
97
+ .domain([0, 50, 100])
98
+ .mode(mode)
99
+ .padding(palettePadding)
100
+ .colors(paletteSize);
101
+ }
102
+ return acc;
103
+ }, {});
104
+ };
105
+
106
+ // Utility function to generate transparent colors
107
+ const generateTransparentColors = (baseColor, steps) => {
108
+ return steps.map((step) => chroma(baseColor).alpha(step).css());
109
+ };
110
+
111
+ // Primary function to generate theme colors
112
+ export const generateThemeColors = (config) => {
113
+ const systemColors = generateSystemColors(config);
114
+ const scales = generatePaletteScales(
115
+ systemColors,
116
+ config.lightBase,
117
+ config.palettePadding,
118
+ config.paletteSize,
119
+ config.mode,
120
+ spectre
121
+ );
122
+ return {
123
+ ...systemColors,
124
+ palette: scales,
125
+ white: spectre.white,
126
+ black: spectre.black,
127
+ transparent: {
128
+ brand: generateTransparentColors(
129
+ systemColors.brand,
130
+ config.transparentSteps
131
+ ),
132
+ neutral: generateTransparentColors(
133
+ systemColors.neutral,
134
+ config.transparentSteps
135
+ ),
136
+ accent: generateTransparentColors(
137
+ systemColors.accent,
138
+ config.transparentSteps
139
+ ),
140
+ light: generateTransparentColors(
141
+ config.lightBase === "light" ? spectre.black : spectre.white,
142
+ config.transparentSteps
143
+ ),
144
+ dark: generateTransparentColors(
145
+ config.lightBase === "light" ? spectre.white : spectre.black,
146
+ config.transparentSteps
147
+ ),
148
+ },
149
+ };
150
+ };
151
+
152
+ // helper function for checking the contrast ratio of two colors
153
+ export function checkContrast(c1, c2) {
154
+ try {
155
+ if (!c1 || !c2) {
156
+ throw new Error("Both colors are required");
157
+ }
158
+
159
+ if (!chroma.valid(c1) || !chroma.valid(c2)) {
160
+ throw new Error("Invalid color format");
161
+ }
162
+
163
+ const contrast = Number(chroma.contrast(c1, c2).toFixed(2));
164
+
165
+ // WCAG 2.1 Grading
166
+ const grade = {
167
+ ratio: contrast,
168
+ AA: {
169
+ large: contrast >= 3, // 18pt+ or 14pt+ bold
170
+ normal: contrast >= 4.5, // All other text
171
+ ui: contrast >= 3, // UI components and graphical objects
172
+ },
173
+ AAA: {
174
+ large: contrast >= 4.5, // 18pt+ or 14pt+ bold
175
+ normal: contrast >= 7, // All other text
176
+ },
177
+ toString() {
178
+ if (contrast >= 7) return "AAA";
179
+ if (contrast >= 4.5) return "AA";
180
+ if (contrast >= 3) return "AA Large";
181
+ return "Fail";
182
+ },
183
+ };
184
+
185
+ return grade;
186
+ } catch (error) {
187
+ console.error(`Contrast check failed: ${error.message}`);
188
+ return {
189
+ ratio: 1,
190
+ AA: { large: false, normal: false, ui: false },
191
+ AAA: { large: false, normal: false },
192
+ toString: () => "Fail",
193
+ };
194
+ }
195
+ }
196
+ // helper function to get a transparent color from input
197
+ export function getTransparent(color, opacity) {
198
+ // let res = colors[color];
199
+ // if (res === undefined) return color;
200
+ // TODO: Add additional logic to handle palette colors
201
+ // if (color.includes("palette") === true) {
202
+ // let trav = color.split(".").slice(1, 3);
203
+ // let res2 = Object.fromEntries(Object.entries(colors.palette[trav[0]]).filter(([key]) => key.includes(trav[1])));
204
+ // return (res = Object.values(res2).toString());
205
+ // }
206
+ return chroma(color).alpha(opacity).css("hsla");
207
+ }
208
+
209
+ export function getTint(color, amount = 0.5) {
210
+ try {
211
+ // Tint = mix with white (lighten)
212
+ // amount: 0 = original color, 1 = white
213
+ return chroma.mix(color, 'white', amount).hex();
214
+ } catch (error) {
215
+ console.error(`Tint failed: ${error.message}`);
216
+ return color;
217
+ }
218
+ }
219
+
220
+ export function getShade(color, amount = 0.5) {
221
+ try {
222
+ // Check if color is undefined, null, or empty string
223
+ if (color === undefined || color === null || color === "") {
224
+ console.error(`getShade received invalid color value:`, color);
225
+ return "#000000"; // Return fallback color
226
+ }
227
+
228
+ // Shade = mix with black (darken)
229
+ // amount: 0 = original color, 1 = black
230
+ return chroma.mix(color, 'black', amount).hex();
231
+ } catch (error) {
232
+ console.error(
233
+ `Shade failed for color "${color}" with amount ${amount}: ${error.message}`
234
+ );
235
+ console.error("Color type:", typeof color, "Color value:", color);
236
+ return color || "#000000"; // Return original color or fallback
237
+ }
238
+ }
239
+
240
+ // Store for the current theme - will be set by the theme provider
241
+ let currentTheme = null;
242
+
243
+ // Function to set the current theme (called by theme provider)
244
+ export function setCurrentTheme(theme) {
245
+ currentTheme = theme;
246
+ }
247
+
248
+ // Helper function to resolve color from theme
249
+ // function resolveThemeColor(colors, colorPath) {
250
+ // try {
251
+ // // Handle direct color references (e.g., "brand", "accent", "neutral")
252
+ // if (typeof colorPath === "string" && colors[colorPath]) {
253
+ // return chroma(colors[colorPath]).hex();
254
+ // }
255
+
256
+ // // Handle palette colors (e.g., "palette.reds.5", "palette.blues.0")
257
+ // if (typeof colorPath === "string" && colorPath.includes("palette.")) {
258
+ // const pathParts = colorPath.split(".");
259
+
260
+ // if (pathParts.length >= 3) {
261
+ // const paletteGroup = pathParts[1]; // e.g., "reds"
262
+ // const paletteIndex = pathParts[2]; // e.g., "5"
263
+
264
+ // if (colors.palette &&
265
+ // colors.palette[paletteGroup] &&
266
+ // colors.palette[paletteGroup][paletteIndex]) {
267
+ // return chroma(colors.palette[paletteGroup][paletteIndex]).hex();
268
+ // }
269
+ // }
270
+ // }
271
+
272
+ // // Handle transparent colors (e.g., "transparent.brand.0")
273
+ // if (typeof colorPath === "string" && colorPath.includes("transparent.")) {
274
+ // const pathParts = colorPath.split(".");
275
+
276
+ // if (pathParts.length >= 3) {
277
+ // const transparentGroup = pathParts[1]; // e.g., "brand"
278
+ // const transparentIndex = pathParts[2]; // e.g., "0"
279
+
280
+ // if (colors.transparent &&
281
+ // colors.transparent[transparentGroup] &&
282
+ // colors.transparent[transparentGroup][transparentIndex]) {
283
+ // // Transparent colors are already in CSS format, convert to hex with alpha
284
+ // return chroma(colors.transparent[transparentGroup][transparentIndex]).hex();
285
+ // }
286
+ // }
287
+ // }
288
+
289
+ // // Handle object notation (e.g., colors.palette.reds[5])
290
+ // if (typeof colorPath === "object") {
291
+ // return chroma(colorPath).hex();
292
+ // }
293
+
294
+ // // If all else fails, try to parse as direct color value
295
+ // return chroma(colorPath).hex();
296
+
297
+ // } catch (error) {
298
+ // console.error(`resolveThemeColor failed: ${error.message}`);
299
+ // console.error(`Color path: ${colorPath}`);
300
+ // return colorPath; // Return original value as fallback
301
+ // }
302
+ // }
303
+
304
+ // Utility function to resolve theme color path to actual color value
305
+ function resolveColorPath(colors, colorPath) {
306
+ if (!colorPath || !colors) return colorPath;
307
+
308
+ const pathParts = colorPath.split(".");
309
+ let current = colors;
310
+
311
+ for (const part of pathParts) {
312
+ if (current && typeof current === "object" && part in current) {
313
+ current = current[part];
314
+ } else {
315
+ return colorPath; // Return original if path doesn't exist
316
+ }
317
+ }
318
+
319
+ return current;
320
+ }
321
+
322
+ // Template string processor that resolves theme colors in CSS functions
323
+ export function withThemeColors(template) {
324
+ return (props) => {
325
+ try {
326
+ // Get colors from props.theme or fallback to currentTheme
327
+ let colors;
328
+ if (props && props.theme && props.theme.colors) {
329
+ colors = props.theme.colors;
330
+ } else if (currentTheme && currentTheme.colors) {
331
+ colors = currentTheme.colors;
332
+ } else {
333
+ console.warn("No theme available, returning template as-is");
334
+ return template;
335
+ }
336
+
337
+ // Replace theme color references in the template
338
+ return template.replace(
339
+ /getThemeColor\("([^"]+)"\)/g,
340
+ (match, colorPath) => {
341
+ const resolvedColor = resolveColorPath(colors, colorPath);
342
+
343
+ // Convert to hex if it's a valid color
344
+ if (resolvedColor && resolvedColor !== colorPath) {
345
+ try {
346
+ return chroma(resolvedColor).hex();
347
+ } catch (colorError) {
348
+ console.error(
349
+ `Failed to convert color: ${resolvedColor}`,
350
+ colorError
351
+ );
352
+ return colorPath;
353
+ }
354
+ }
355
+
356
+ return colorPath;
357
+ }
358
+ );
359
+ } catch (error) {
360
+ console.error(`withThemeColors failed: ${error.message}`);
361
+ return template;
362
+ }
363
+ };
364
+ }
365
+
366
+ // Utility function that accepts colors and returns HEX value directly
367
+ export function getThemeColor(colors, colorPath) {
368
+ try {
369
+ if (!colors || !colorPath) {
370
+ console.error("Both colors and colorPath are required");
371
+ return colorPath;
372
+ }
373
+
374
+ const resolvedColor = resolveColorPath(colors, colorPath);
375
+
376
+ // Convert to hex if it's a valid color
377
+ if (resolvedColor && resolvedColor !== colorPath) {
378
+ const hexValue = chroma(resolvedColor).hex();
379
+ //console.log(`getThemeColor('${colorPath}') -> ${hexValue}`);
380
+ return hexValue;
381
+ }
382
+
383
+ //console.log(`getThemeColor('${colorPath}') -> ${colorPath} (not found)`);
384
+ return colorPath;
385
+ } catch (error) {
386
+ console.error(`getThemeColor failed: ${error.message}`);
387
+ console.error(`Color path: ${colorPath}`);
388
+ return colorPath;
389
+ }
390
+ }
391
+
392
+ // Styled-components helper function for getting theme colors
393
+ export const themeColor = (colorPath) => (props) => {
394
+ try {
395
+ if (!props.theme || !props.theme.colors) {
396
+ console.warn("No theme available in styled-components props");
397
+ return colorPath;
398
+ }
399
+
400
+ const colors = props.theme.colors;
401
+
402
+ // Handle direct color references (e.g., "brand", "accent", "neutral")
403
+ if (typeof colorPath === "string" && colors[colorPath]) {
404
+ return chroma(colors[colorPath]).hex();
405
+ }
406
+
407
+ // Handle palette colors (e.g., "palette.reds.5", "palette.blues.0")
408
+ if (typeof colorPath === "string" && colorPath.includes("palette.")) {
409
+ const pathParts = colorPath.split(".");
410
+
411
+ if (pathParts.length >= 3) {
412
+ const paletteGroup = pathParts[1]; // e.g., "reds"
413
+ const paletteIndex = pathParts[2]; // e.g., "5"
414
+
415
+ if (
416
+ colors.palette &&
417
+ colors.palette[paletteGroup] &&
418
+ colors.palette[paletteGroup][paletteIndex]
419
+ ) {
420
+ return chroma(colors.palette[paletteGroup][paletteIndex]).hex();
421
+ }
422
+ }
423
+ }
424
+
425
+ // Handle transparent colors (e.g., "transparent.brand.0")
426
+ if (typeof colorPath === "string" && colorPath.includes("transparent.")) {
427
+ const pathParts = colorPath.split(".");
428
+
429
+ if (pathParts.length >= 3) {
430
+ const transparentGroup = pathParts[1]; // e.g., "brand"
431
+ const transparentIndex = pathParts[2]; // e.g., "0"
432
+
433
+ if (
434
+ colors.transparent &&
435
+ colors.transparent[transparentGroup] &&
436
+ colors.transparent[transparentGroup][transparentIndex]
437
+ ) {
438
+ // Transparent colors are already in CSS format, convert to hex with alpha
439
+ return chroma(
440
+ colors.transparent[transparentGroup][transparentIndex]
441
+ ).hex();
442
+ }
443
+ }
444
+ }
445
+
446
+ // Handle object notation (e.g., colors.palette.reds[5])
447
+ if (typeof colorPath === "object") {
448
+ return chroma(colorPath).hex();
449
+ }
450
+
451
+ // If all else fails, try to parse as direct color value
452
+ return chroma(colorPath).hex();
453
+ } catch (error) {
454
+ console.error(`themeColor failed: ${error.message}`);
455
+ console.error(`Color path: ${colorPath}`);
456
+ return colorPath; // Return original value as fallback
457
+ }
458
+ };
459
+
460
+ // Legacy function for backward compatibility (two argument version)
461
+ export function getThemeColorLegacy(colors, colorPath) {
462
+ try {
463
+ if (!colors || !colorPath) {
464
+ throw new Error("Colors object and color path are required");
465
+ }
466
+
467
+ // Handle direct color references (e.g., "brand", "accent", "neutral")
468
+ if (typeof colorPath === "string" && colors[colorPath]) {
469
+ return chroma(colors[colorPath]).hex();
470
+ }
471
+
472
+ // Handle palette colors (e.g., "palette.reds.5", "palette.blues.0")
473
+ if (typeof colorPath === "string" && colorPath.includes("palette.")) {
474
+ const pathParts = colorPath.split(".");
475
+
476
+ if (pathParts.length >= 3) {
477
+ const paletteGroup = pathParts[1]; // e.g., "reds"
478
+ const paletteIndex = pathParts[2]; // e.g., "5"
479
+
480
+ if (
481
+ colors.palette &&
482
+ colors.palette[paletteGroup] &&
483
+ colors.palette[paletteGroup][paletteIndex]
484
+ ) {
485
+ return chroma(colors.palette[paletteGroup][paletteIndex]).hex();
486
+ }
487
+ }
488
+ }
489
+
490
+ // Handle transparent colors (e.g., "transparent.brand.0")
491
+ if (typeof colorPath === "string" && colorPath.includes("transparent.")) {
492
+ const pathParts = colorPath.split(".");
493
+
494
+ if (pathParts.length >= 3) {
495
+ const transparentGroup = pathParts[1]; // e.g., "brand"
496
+ const transparentIndex = pathParts[2]; // e.g., "0"
497
+
498
+ if (
499
+ colors.transparent &&
500
+ colors.transparent[transparentGroup] &&
501
+ colors.transparent[transparentGroup][transparentIndex]
502
+ ) {
503
+ // Transparent colors are already in CSS format, convert to hex with alpha
504
+ return chroma(
505
+ colors.transparent[transparentGroup][transparentIndex]
506
+ ).hex();
507
+ }
508
+ }
509
+ }
510
+
511
+ // Handle object notation (e.g., colors.palette.reds[5])
512
+ if (typeof colorPath === "object") {
513
+ return chroma(colorPath).hex();
514
+ }
515
+
516
+ // If all else fails, try to parse as direct color value
517
+ return chroma(colorPath).hex();
518
+ } catch (error) {
519
+ console.error(`getThemeColorLegacy failed: ${error.message}`);
520
+ console.error(`Color path: ${colorPath}`);
521
+ return colorPath; // Return original value as fallback
522
+ }
523
+ }
@@ -0,0 +1,11 @@
1
+ import light from "./default/modes/light/theme";
2
+ import dark from "./default/modes/dark/theme";
3
+
4
+ export const themes = {
5
+ dark,
6
+ light,
7
+ // Other themes can be added here
8
+ };
9
+
10
+ export type ThemeName = keyof typeof themes;
11
+ export type Theme = (typeof themes)[ThemeName];