@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.
- package/README.md +48 -0
- package/package.json +74 -0
- package/src/blocks/Accordion/index.tsx +158 -0
- package/src/blocks/AnimatedCarousel/index.tsx +188 -0
- package/src/blocks/AppleGlow/index.tsx +144 -0
- package/src/blocks/Avatar/index.tsx +167 -0
- package/src/blocks/Await/index.tsx +45 -0
- package/src/blocks/Cards/AnimatedCard/index.tsx +175 -0
- package/src/blocks/Cards/FluorescentCard/index.tsx +180 -0
- package/src/blocks/Cards/InfoCard/index.tsx +206 -0
- package/src/blocks/Cards/TickerCard/index.tsx +125 -0
- package/src/blocks/Carousel/index.tsx +216 -0
- package/src/blocks/Checkbox/index.tsx +101 -0
- package/src/blocks/Collection/index.tsx +59 -0
- package/src/blocks/Container/index.tsx +55 -0
- package/src/blocks/Controls/Control.tsx +67 -0
- package/src/blocks/Controls/index.tsx +11 -0
- package/src/blocks/CyclingNumber/index.tsx +78 -0
- package/src/blocks/DisplaySet/index.tsx +42 -0
- package/src/blocks/Divider/index.tsx +14 -0
- package/src/blocks/Draggable/index.tsx +266 -0
- package/src/blocks/Drawer/index.tsx +136 -0
- package/src/blocks/DynamicIsland/DynamicIsland.tsx +89 -0
- package/src/blocks/DynamicIsland/index.tsx +2 -0
- package/src/blocks/Fader/index.tsx +145 -0
- package/src/blocks/FamilyDrawer/README.md +116 -0
- package/src/blocks/FamilyDrawer/example.tsx +108 -0
- package/src/blocks/FamilyDrawer/index.tsx +119 -0
- package/src/blocks/FamilyDrawer/views/DefaultView.tsx +93 -0
- package/src/blocks/FamilyDrawer/views/KeyView.tsx +129 -0
- package/src/blocks/FamilyDrawer/views/PhraseView.tsx +129 -0
- package/src/blocks/FamilyDrawer/views/RemoveView.tsx +81 -0
- package/src/blocks/FieldSet/index.tsx +173 -0
- package/src/blocks/Filesystem/index.tsx +198 -0
- package/src/blocks/Gallery/Carousel/index.tsx +257 -0
- package/src/blocks/Gallery/Modal/index.tsx +83 -0
- package/src/blocks/Gallery/index.tsx +57 -0
- package/src/blocks/Gallery/utils/animationVariants.ts +18 -0
- package/src/blocks/Gallery/utils/aspectRatio.ts +14 -0
- package/src/blocks/Gallery/utils/downloadPhoto.ts +24 -0
- package/src/blocks/Gallery/utils/range.ts +11 -0
- package/src/blocks/GradientMesh/index.tsx +106 -0
- package/src/blocks/Group/index.tsx +152 -0
- package/src/blocks/Heading/index.tsx +111 -0
- package/src/blocks/HorizontalScroller/index.tsx +135 -0
- package/src/blocks/Icon/index.tsx +45 -0
- package/src/blocks/Indicator/index.tsx +27 -0
- package/src/blocks/InlineEditor/index.tsx +216 -0
- package/src/blocks/List/index.tsx +657 -0
- package/src/blocks/Main/index.tsx +17 -0
- package/src/blocks/Marquee/index.tsx +116 -0
- package/src/blocks/MaskedField/index.tsx +199 -0
- package/src/blocks/Menu/MenuContent.tsx +246 -0
- package/src/blocks/Menu/MenuContext.tsx +34 -0
- package/src/blocks/Menu/MenuItem.tsx +104 -0
- package/src/blocks/Menu/index.tsx +60 -0
- package/src/blocks/Modal/index.tsx +268 -0
- package/src/blocks/MorphingPopover/index.tsx +294 -0
- package/src/blocks/Overlay/Backdrop.tsx +48 -0
- package/src/blocks/Overlay/OverscrollGuard.tsx +36 -0
- package/src/blocks/Overlay/index.ts +2 -0
- package/src/blocks/Parallax/index.tsx +117 -0
- package/src/blocks/ParallaxSection/index.tsx +61 -0
- package/src/blocks/Placeholder/index.tsx +48 -0
- package/src/blocks/Popover/index.tsx +402 -0
- package/src/blocks/Progress/getProgressColor.ts +61 -0
- package/src/blocks/Progress/index.tsx +179 -0
- package/src/blocks/ProgressiveBlur/index.tsx +75 -0
- package/src/blocks/README.md +15 -0
- package/src/blocks/RenderAsset/index.tsx +18 -0
- package/src/blocks/ScrollContainer/index.tsx +93 -0
- package/src/blocks/ShinyText/index.tsx +72 -0
- package/src/blocks/Skeleton/index.tsx +71 -0
- package/src/blocks/Slider/SliderControls.tsx +119 -0
- package/src/blocks/Slider/index.tsx +140 -0
- package/src/blocks/Slider/useSlider.ts +126 -0
- package/src/blocks/Slideshow/index.tsx +177 -0
- package/src/blocks/Spotlight/index.tsx +144 -0
- package/src/blocks/Steps/StepIndicator.tsx +149 -0
- package/src/blocks/Steps/StepProgress.tsx +164 -0
- package/src/blocks/Steps/Steps.tsx +197 -0
- package/src/blocks/Steps/StepsNav.tsx +30 -0
- package/src/blocks/Steps/StepsTracker.tsx +80 -0
- package/src/blocks/Steps/hooks.ts +71 -0
- package/src/blocks/Steps/index.tsx +16 -0
- package/src/blocks/Steps/types.ts +71 -0
- package/src/blocks/StickySectionStack/index.tsx +136 -0
- package/src/blocks/Switch/index.tsx +85 -0
- package/src/blocks/SystemNotice/index.tsx +81 -0
- package/src/blocks/Table/README.md +251 -0
- package/src/blocks/Table/Table.tsx +207 -0
- package/src/blocks/Table/TablePagination.tsx +189 -0
- package/src/blocks/Table/index.ts +33 -0
- package/src/blocks/Table/useTableControls.ts +331 -0
- package/src/blocks/Tag/index.tsx +27 -0
- package/src/blocks/TextBreak/index.tsx +96 -0
- package/src/blocks/TextReveal/index.tsx +104 -0
- package/src/blocks/Thumbnail/index.tsx +26 -0
- package/src/blocks/Ticker/index.tsx +112 -0
- package/src/blocks/Toast/index.tsx +77 -0
- package/src/blocks/Tooltip/index.tsx +174 -0
- package/src/blocks/Underlay/index.tsx +104 -0
- package/src/blocks/Upload/Dropzone.tsx +92 -0
- package/src/blocks/Upload/UploadBtn.tsx +38 -0
- package/src/blocks/Upload/index.tsx +61 -0
- package/src/blocks/Upload/types.ts +37 -0
- package/src/blocks/VideoMarquee/index.tsx +511 -0
- package/src/blocks/index.ts +119 -0
- package/src/blocks/pagination/Pagination.tsx +148 -0
- package/src/blocks/pagination/PaginationList.tsx +41 -0
- package/src/blocks/pagination/index.ts +2 -0
- package/src/charts/BarChart.tsx +63 -0
- package/src/charts/PieChart.tsx +39 -0
- package/src/charts/index.ts +3 -0
- package/src/charts/utils.ts +103 -0
- package/src/docs/README.md +373 -0
- package/src/docs/reference/README.md +299 -0
- package/src/elements/box.ts +163 -0
- package/src/elements/button.ts +49 -0
- package/src/elements/field.ts +129 -0
- package/src/elements/index.ts +8 -0
- package/src/elements/text.ts +47 -0
- package/src/elements/utils.js +97 -0
- package/src/hooks/use-copy-to-clipboard.tsx +33 -0
- package/src/hooks/use-enter-submit.tsx +23 -0
- package/src/hooks/use-local-storage.ts +42 -0
- package/src/hooks/use-sidebar.tsx +109 -0
- package/src/hooks/useAnimatedText.ts +32 -0
- package/src/hooks/useAutosizeTextArea.ts +45 -0
- package/src/hooks/useBreakpoint.tsx +123 -0
- package/src/hooks/useClickOutside.tsx +38 -0
- package/src/hooks/useHover.tsx +33 -0
- package/src/hooks/useHoverList.tsx +17 -0
- package/src/hooks/useKeyboardShortcuts.ts +91 -0
- package/src/hooks/useKeypress.ts +27 -0
- package/src/hooks/useOverlay.ts +32 -0
- package/src/hooks/useReducedMotion.ts +25 -0
- package/src/hooks/useStandaloneMode.ts +35 -0
- package/src/hooks/useTouchDevice.ts +34 -0
- package/src/icons/index.tsx +129 -0
- package/src/index.ts +12 -0
- package/src/providers/DesignSystemProvider.tsx +35 -0
- package/src/providers/StyledComponentsRegistry.tsx +30 -0
- package/src/providers/index.ts +2 -0
- package/src/themes/README.md +30 -0
- package/src/themes/default/assets/badge-avatar.tsx +45 -0
- package/src/themes/default/assets/logo.tsx +42 -0
- package/src/themes/default/global.ts +138 -0
- package/src/themes/default/modes/dark/config.js +49 -0
- package/src/themes/default/modes/dark/skins.js +631 -0
- package/src/themes/default/modes/dark/theme.js +87 -0
- package/src/themes/default/modes/light/config.js +48 -0
- package/src/themes/default/modes/light/skins.js +1026 -0
- package/src/themes/default/modes/light/theme.js +74 -0
- package/src/themes/default/tokens/controls.js +53 -0
- package/src/themes/default/tokens/shadows.js +63 -0
- package/src/themes/default/tokens/shapes.js +37 -0
- package/src/themes/default/tokens/space.js +143 -0
- package/src/themes/default/tokens/spectre.js +16 -0
- package/src/themes/default/utils.js +523 -0
- package/src/themes/index.ts +11 -0
- package/src/types.ts +394 -0
- package/src/utils/overlayTheme.ts +61 -0
- package/src/utils/pickColor.ts +15 -0
- 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];
|