react-mcu 1.0.6 → 1.0.7

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 CHANGED
@@ -28,12 +28,16 @@ import { Mcu } from "react-mcu";
28
28
  }}>
29
29
  Hello, MCU <span style={{
30
30
  backgroundColor: "var(--mcu-my-custom-color-1)",
31
- color: "var(--mcu-my-custom-color2)",
31
+ color: "var(--mcu-on-my-custom-color-1)",
32
32
  }}>colors<span>!
33
33
  </p>
34
34
  </Mcu>
35
35
  ```
36
36
 
37
+ > [!NOTE]
38
+ >
39
+ > CSS varnames are always kebab-cased, `myCustomColor1` → `--mcu-my-custom-color-1`
40
+
37
41
  https://github.com/user-attachments/assets/5b67c961-d7a4-4b64-9356-4ada26bc9be4
38
42
 
39
43
  A `useMcu` hook is also provided:
@@ -63,7 +67,9 @@ Or simply:
63
67
  @import "react-mcu/tailwind.css";
64
68
  ```
65
69
 
66
- > [!IMPORTANT] Do not forget to manually add your custom colors, as in:
70
+ > [!IMPORTANT]
71
+ >
72
+ > Do not forget to manually add your custom colors, as in:
67
73
  > https://github.com/abernier/react-mcu/blob/f981087651d77f6b11fc76cb783a5220a1b56e87/src/tailwind.css#L52-L75
68
74
 
69
75
  # Dev
package/dist/index.d.ts CHANGED
@@ -11,6 +11,25 @@ type McuConfig = {
11
11
  scheme?: SchemeName;
12
12
  /** Contrast level from -1.0 (reduced) to 1.0 (increased). Default: 0 (standard) */
13
13
  contrast?: number;
14
+ /** Primary color - the main brand color. Overrides the default palette generation. */
15
+ primary?: string;
16
+ /** Secondary color - accent color. Overrides the default palette generation. */
17
+ secondary?: string;
18
+ /** Tertiary color - additional accent color. Overrides the default palette generation. */
19
+ tertiary?: string;
20
+ /** Neutral color - used for surfaces. Overrides the default palette generation. */
21
+ neutral?: string;
22
+ /** Neutral variant color - used for surfaces with slight tint. Overrides the default palette generation. */
23
+ neutralVariant?: string;
24
+ /** Error color - used for error states. Overrides the default palette generation. */
25
+ error?: string;
26
+ /**
27
+ * Color match mode for core colors.
28
+ * When true, stays true to input colors without harmonization.
29
+ * When false (default), colors may be adjusted for better harmonization.
30
+ * Corresponds to "Color match - Stay true to my color inputs" in Material Theme Builder.
31
+ */
32
+ colorMatch?: boolean;
14
33
  /** Array of custom colors to include in the generated palette */
15
34
  customColors?: HexCustomColor[];
16
35
  };
@@ -25,7 +44,7 @@ declare const schemesMap: {
25
44
  };
26
45
  declare const schemeNames: (keyof typeof schemesMap)[];
27
46
  type SchemeName = (typeof schemeNames)[number];
28
- declare function Mcu({ source, scheme, contrast, customColors, children, }: McuConfig & {
47
+ declare function Mcu({ source, scheme, contrast, primary, secondary, tertiary, neutral, neutralVariant, error, colorMatch, customColors, children, }: McuConfig & {
29
48
  children?: React.ReactNode;
30
49
  }): react_jsx_runtime.JSX.Element;
31
50
  declare const tokenNames: readonly ["background", "onBackground", "surface", "surfaceDim", "surfaceBright", "surfaceContainerLowest", "surfaceContainerLow", "surfaceContainer", "surfaceContainerHigh", "surfaceContainerHighest", "onSurface", "onSurfaceVariant", "outline", "outlineVariant", "inverseSurface", "inverseOnSurface", "primary", "onPrimary", "primaryContainer", "onPrimaryContainer", "primaryFixed", "primaryFixedDim", "onPrimaryFixed", "onPrimaryFixedVariant", "inversePrimary", "primaryFixed", "primaryFixedDim", "onPrimaryFixed", "onPrimaryFixedVariant", "secondary", "onSecondary", "secondaryContainer", "onSecondaryContainer", "secondaryFixed", "secondaryFixedDim", "onSecondaryFixed", "onSecondaryFixedVariant", "tertiary", "onTertiary", "tertiaryContainer", "onTertiaryContainer", "tertiaryFixed", "tertiaryFixedDim", "onTertiaryFixed", "onTertiaryFixedVariant", "error", "onError", "errorContainer", "onErrorContainer", "scrim", "shadow"];
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  // src/Mcu.tsx
2
2
  import {
3
3
  argbFromHex,
4
- Blend,
4
+ CorePalette,
5
+ customColor,
6
+ DynamicScheme,
5
7
  Hct,
6
8
  hexFromArgb as hexFromArgb2,
7
9
  MaterialDynamicColors,
@@ -11,8 +13,7 @@ import {
11
13
  SchemeMonochrome,
12
14
  SchemeNeutral,
13
15
  SchemeTonalSpot,
14
- SchemeVibrant,
15
- TonalPalette
16
+ SchemeVibrant
16
17
  } from "@material/material-color-utilities";
17
18
  import { kebabCase, upperFirst } from "lodash-es";
18
19
  import { useMemo as useMemo2 } from "react";
@@ -106,12 +107,40 @@ var schemeNames = Object.keys(
106
107
  );
107
108
  var DEFAULT_SCHEME = "tonalSpot";
108
109
  var DEFAULT_CONTRAST = 0;
110
+ var DEFAULT_COLOR_MATCH = false;
109
111
  var DEFAULT_CUSTOM_COLORS = [];
112
+ var Variant = {
113
+ MONOCHROME: 0,
114
+ NEUTRAL: 1,
115
+ TONAL_SPOT: 2,
116
+ VIBRANT: 3,
117
+ EXPRESSIVE: 4,
118
+ FIDELITY: 5,
119
+ CONTENT: 6,
120
+ RAINBOW: 7,
121
+ FRUIT_SALAD: 8
122
+ };
123
+ var schemeToVariant = {
124
+ tonalSpot: Variant.TONAL_SPOT,
125
+ monochrome: Variant.MONOCHROME,
126
+ neutral: Variant.NEUTRAL,
127
+ vibrant: Variant.VIBRANT,
128
+ expressive: Variant.EXPRESSIVE,
129
+ fidelity: Variant.FIDELITY,
130
+ content: Variant.CONTENT
131
+ };
110
132
  var mcuStyleId = "mcu-styles";
111
133
  function Mcu({
112
134
  source,
113
135
  scheme = DEFAULT_SCHEME,
114
136
  contrast = DEFAULT_CONTRAST,
137
+ primary,
138
+ secondary,
139
+ tertiary,
140
+ neutral,
141
+ neutralVariant,
142
+ error,
143
+ colorMatch = DEFAULT_COLOR_MATCH,
115
144
  customColors = DEFAULT_CUSTOM_COLORS,
116
145
  children
117
146
  }) {
@@ -120,9 +149,28 @@ function Mcu({
120
149
  source,
121
150
  scheme,
122
151
  contrast,
152
+ primary,
153
+ secondary,
154
+ tertiary,
155
+ neutral,
156
+ neutralVariant,
157
+ error,
158
+ colorMatch,
123
159
  customColors
124
160
  }),
125
- [contrast, customColors, scheme, source]
161
+ [
162
+ contrast,
163
+ customColors,
164
+ scheme,
165
+ source,
166
+ primary,
167
+ secondary,
168
+ tertiary,
169
+ neutral,
170
+ neutralVariant,
171
+ error,
172
+ colorMatch
173
+ ]
126
174
  );
127
175
  const { css } = useMemo2(() => generateCss(config), [config]);
128
176
  return /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -208,15 +256,13 @@ function mergeBaseAndCustomColors(scheme, customColors, sourceArgb) {
208
256
  const customVars = {};
209
257
  const isDark = scheme.isDark;
210
258
  customColors.forEach((color) => {
211
- const colorValue = color.blend ? Blend.harmonize(color.value, sourceArgb) : color.value;
212
- const palette = TonalPalette.fromInt(colorValue);
259
+ const customColorGroup = customColor(sourceArgb, color);
260
+ const colorGroup = isDark ? customColorGroup.dark : customColorGroup.light;
213
261
  const colorname = color.name;
214
- customVars[colorname] = palette.tone(isDark ? 80 : 40);
215
- customVars[`on${upperFirst(colorname)}`] = palette.tone(isDark ? 20 : 100);
216
- customVars[`${colorname}Container`] = palette.tone(isDark ? 30 : 90);
217
- customVars[`on${upperFirst(colorname)}Container`] = palette.tone(
218
- isDark ? 90 : 10
219
- );
262
+ customVars[colorname] = colorGroup.color;
263
+ customVars[`on${upperFirst(colorname)}`] = colorGroup.onColor;
264
+ customVars[`${colorname}Container`] = colorGroup.colorContainer;
265
+ customVars[`on${upperFirst(colorname)}Container`] = colorGroup.onColorContainer;
220
266
  });
221
267
  return { ...baseVars, ...customVars };
222
268
  }
@@ -230,16 +276,53 @@ var toCssVars = (mergedColors) => {
230
276
  };
231
277
  function generateCss({
232
278
  source: hexSource,
233
- customColors: hexCustomColors = DEFAULT_CUSTOM_COLORS,
234
279
  scheme = DEFAULT_SCHEME,
235
- contrast = DEFAULT_CONTRAST
280
+ contrast = DEFAULT_CONTRAST,
281
+ primary,
282
+ secondary,
283
+ tertiary,
284
+ neutral,
285
+ neutralVariant,
286
+ error,
287
+ colorMatch = DEFAULT_COLOR_MATCH,
288
+ customColors: hexCustomColors = DEFAULT_CUSTOM_COLORS
236
289
  }) {
237
- console.log("MCU generateCss");
290
+ const hasCoreColors = primary ?? secondary ?? tertiary ?? neutral ?? neutralVariant ?? error;
291
+ console.log("MCU generateCss", { hasCoreColors });
238
292
  const sourceArgb = argbFromHex(hexSource);
239
- const hct = Hct.fromInt(sourceArgb);
240
- const SchemeClass = schemesMap[scheme];
241
- const lightScheme = new SchemeClass(hct, false, contrast);
242
- const darkScheme = new SchemeClass(hct, true, contrast);
293
+ const createSchemes = (baseConfig) => [
294
+ new DynamicScheme({ ...baseConfig, isDark: false }),
295
+ new DynamicScheme({ ...baseConfig, isDark: true })
296
+ ];
297
+ let lightScheme;
298
+ let darkScheme;
299
+ if (hasCoreColors) {
300
+ const coreColorsArgb = {
301
+ primary: primary ? argbFromHex(primary) : sourceArgb,
302
+ secondary: secondary ? argbFromHex(secondary) : void 0,
303
+ tertiary: tertiary ? argbFromHex(tertiary) : void 0,
304
+ neutral: neutral ? argbFromHex(neutral) : void 0,
305
+ neutralVariant: neutralVariant ? argbFromHex(neutralVariant) : void 0,
306
+ error: error ? argbFromHex(error) : void 0
307
+ };
308
+ const corePalette = colorMatch ? CorePalette.fromColors(coreColorsArgb) : CorePalette.contentFromColors(coreColorsArgb);
309
+ const variant = schemeToVariant[scheme];
310
+ [lightScheme, darkScheme] = createSchemes({
311
+ sourceColorArgb: sourceArgb,
312
+ variant,
313
+ contrastLevel: contrast,
314
+ primaryPalette: corePalette.a1,
315
+ secondaryPalette: corePalette.a2,
316
+ tertiaryPalette: corePalette.a3,
317
+ neutralPalette: corePalette.n1,
318
+ neutralVariantPalette: corePalette.n2
319
+ });
320
+ } else {
321
+ const SchemeClass = schemesMap[scheme];
322
+ const hct = Hct.fromInt(sourceArgb);
323
+ lightScheme = new SchemeClass(hct, false, contrast);
324
+ darkScheme = new SchemeClass(hct, true, contrast);
325
+ }
243
326
  const customColors = hexCustomColors.map(({ hex, ...rest }) => ({
244
327
  ...rest,
245
328
  value: argbFromHex(hex)
@@ -258,9 +341,9 @@ function generateCss({
258
341
  const darkVars = toCssVars(mergedColorsDark);
259
342
  return {
260
343
  css: `
261
- :root { ${lightVars} }
262
- .dark { ${darkVars} }
263
- `,
344
+ :root { ${lightVars} }
345
+ .dark { ${darkVars} }
346
+ `,
264
347
  mergedColorsLight,
265
348
  mergedColorsDark
266
349
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-mcu",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "A React component library",
5
5
  "keywords": [
6
6
  "react",
@@ -32,6 +32,8 @@
32
32
  "devDependencies": {
33
33
  "@arethetypeswrong/cli": "^0.18.2",
34
34
  "@changesets/cli": "^2.27.7",
35
+ "@storybook/addon-docs": "^10.1.11",
36
+ "@storybook/addon-themes": "^10.1.11",
35
37
  "@storybook/react-vite": "^10.1.11",
36
38
  "@tailwindcss/postcss": "^4.1.18",
37
39
  "@testing-library/dom": "^10.4.1",