react-mcu 1.0.1 → 1.0.2

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
@@ -1,43 +1,58 @@
1
- # react-mcu
2
-
3
1
  [![npm version](https://img.shields.io/npm/v/react-mcu.svg)](https://www.npmjs.com/package/react-mcu)
2
+ [![](https://img.shields.io/badge/chromatic-171c23.svg?logo=chromatic)](https://www.chromatic.com/library?appId=695eb517cb602e59b4cc045c&branch=main)
4
3
 
5
- A React component library.
6
-
7
- ## Installation
8
-
9
- ```bash
10
- npm install react-mcu
11
- ```
12
-
13
- ## Usage
4
+ Usage:
14
5
 
15
6
  ```tsx
16
7
  import { Mcu } from "react-mcu";
17
8
 
18
- function App() {
19
- return <Mcu />;
20
- }
9
+ <Mcu
10
+ source="#0e1216"
11
+ scheme="vibrant"
12
+ contrast={0.5}
13
+ customColors=[]
14
+ >
15
+ <div style={{
16
+ backgroundColor: "var(--mcu-surface)",
17
+ color: "var(--mcu-on-surface)",
18
+ }}>
19
+ Hello, MCU colors!
20
+ </div>
21
+ </Mcu>
21
22
  ```
22
23
 
23
- ## Components
24
-
25
- ### Mcu
26
-
27
- A simple component that renders "Hello World".
28
-
29
- ```tsx
30
- <Mcu />
24
+ # Dev
25
+
26
+ ## INSTALL
27
+
28
+ Pre-requisites:
29
+
30
+ - Install [nvm](https://github.com/nvm-sh/nvm), then:
31
+ ```sh
32
+ $ nvm install
33
+ $ nvm use
34
+ $ node -v # make sure your version satisfies package.json#engines.node
35
+ ```
36
+ nb: if you want this node version to be your default nvm's one:
37
+ `nvm alias default node`
38
+ - Install pnpm, with:
39
+ ```sh
40
+ $ corepack enable
41
+ $ corepack prepare --activate # it reads "packageManager"
42
+ $ pnpm -v # make sure your version satisfies package.json#engines.pnpm
43
+ ```
44
+
45
+ ```sh
46
+ $ pnpm i
31
47
  ```
32
48
 
33
- ## Contributing
49
+ ## CONTRIBUTING
34
50
 
35
- When submitting a pull request, please include a changeset to document your changes:
51
+ When submitting a pull request, please include a changeset to document your
52
+ changes:
36
53
 
37
54
  ```bash
38
- pnpm dlx changeset
55
+ pnpm exec changeset
39
56
  ```
40
57
 
41
58
  This helps us maintain the changelog and version the package appropriately.
42
-
43
- bump02
package/dist/index.d.ts CHANGED
@@ -1,5 +1,28 @@
1
- interface McuProps {
2
- }
3
- declare const Mcu: React.FC<McuProps>;
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SchemeTonalSpot, SchemeMonochrome, SchemeNeutral, SchemeVibrant, SchemeExpressive, SchemeFidelity, SchemeContent, CustomColor } from '@material/material-color-utilities';
4
3
 
5
- export { Mcu, type McuProps };
4
+ type HexCustomColor = Omit<CustomColor, "value"> & {
5
+ hex: string;
6
+ };
7
+ type McuConfig = {
8
+ source: string;
9
+ scheme: SchemeName;
10
+ contrast: number;
11
+ customColors: HexCustomColor[];
12
+ };
13
+ declare const schemesMap: {
14
+ readonly tonalSpot: typeof SchemeTonalSpot;
15
+ readonly monochrome: typeof SchemeMonochrome;
16
+ readonly neutral: typeof SchemeNeutral;
17
+ readonly vibrant: typeof SchemeVibrant;
18
+ readonly expressive: typeof SchemeExpressive;
19
+ readonly fidelity: typeof SchemeFidelity;
20
+ readonly content: typeof SchemeContent;
21
+ };
22
+ declare const schemeNames: (keyof typeof schemesMap)[];
23
+ type SchemeName = (typeof schemeNames)[number];
24
+ declare function Mcu({ source, scheme, contrast, customColors, children, }: McuConfig & {
25
+ children: React.ReactNode;
26
+ }): react_jsx_runtime.JSX.Element;
27
+
28
+ export { Mcu };
package/dist/index.js CHANGED
@@ -1,8 +1,248 @@
1
1
  // src/Mcu.tsx
2
+ import {
3
+ argbFromHex,
4
+ Hct,
5
+ hexFromArgb as hexFromArgb2,
6
+ MaterialDynamicColors,
7
+ SchemeContent,
8
+ SchemeExpressive,
9
+ SchemeFidelity,
10
+ SchemeMonochrome,
11
+ SchemeNeutral,
12
+ SchemeTonalSpot,
13
+ SchemeVibrant
14
+ } from "@material/material-color-utilities";
15
+ import { kebabCase } from "lodash-es";
16
+ import { useMemo as useMemo2 } from "react";
17
+
18
+ // src/Mcu.context.tsx
19
+ import { hexFromArgb } from "@material/material-color-utilities";
20
+ import {
21
+ useCallback,
22
+ useInsertionEffect,
23
+ useMemo,
24
+ useState
25
+ } from "react";
26
+
27
+ // src/lib/createRequiredContext.ts
28
+ import { createContext, useContext } from "react";
29
+ var createRequiredContext = () => {
30
+ const Ctx = createContext(null);
31
+ const useCtx = () => {
32
+ const contextValue = useContext(Ctx);
33
+ if (contextValue === null) {
34
+ throw new Error("Context value is null");
35
+ }
36
+ return contextValue;
37
+ };
38
+ return [useCtx, Ctx.Provider, Ctx];
39
+ };
40
+
41
+ // src/Mcu.context.tsx
2
42
  import { jsx } from "react/jsx-runtime";
3
- var Mcu = () => {
4
- return /* @__PURE__ */ jsx("div", { children: "hello react-mcu" });
43
+ var [useMcu, Provider, McuContext] = createRequiredContext();
44
+ var McuProvider = ({
45
+ source: initialSource,
46
+ scheme: initialScheme,
47
+ contrast: initialContrast,
48
+ customColors: initialCustomColors,
49
+ styleId,
50
+ children
51
+ }) => {
52
+ const [initials] = useState(() => ({
53
+ source: initialSource,
54
+ scheme: initialScheme,
55
+ contrast: initialContrast,
56
+ customColors: initialCustomColors
57
+ }));
58
+ const [mcuConfig, setMcuConfig] = useState(initials);
59
+ const { css, mergedColorsLight, mergedColorsDark } = useMemo(
60
+ () => generateCss(mcuConfig),
61
+ [mcuConfig]
62
+ );
63
+ useInsertionEffect(() => {
64
+ let tag = document.getElementById(styleId);
65
+ if (!tag) {
66
+ tag = document.createElement("style");
67
+ tag.id = styleId;
68
+ document.head.appendChild(tag);
69
+ }
70
+ tag.textContent = css;
71
+ }, [css, styleId]);
72
+ const getMcuColor = useCallback(
73
+ (colorName, theme) => {
74
+ return hexFromArgb(
75
+ (theme === "light" ? mergedColorsLight : mergedColorsDark)[colorName]
76
+ );
77
+ },
78
+ [mergedColorsDark, mergedColorsLight]
79
+ );
80
+ const value = useMemo(
81
+ () => ({
82
+ initials,
83
+ setMcuConfig,
84
+ getMcuColor
85
+ }),
86
+ [getMcuColor, initials]
87
+ );
88
+ return /* @__PURE__ */ jsx(Provider, { value, children });
89
+ };
90
+
91
+ // src/Mcu.tsx
92
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
93
+ var schemesMap = {
94
+ tonalSpot: SchemeTonalSpot,
95
+ monochrome: SchemeMonochrome,
96
+ neutral: SchemeNeutral,
97
+ vibrant: SchemeVibrant,
98
+ expressive: SchemeExpressive,
99
+ fidelity: SchemeFidelity,
100
+ content: SchemeContent
101
+ };
102
+ var schemeNames = Object.keys(
103
+ schemesMap
104
+ );
105
+ var mcuStyleId = "mcu-styles";
106
+ function Mcu({
107
+ source,
108
+ scheme,
109
+ contrast,
110
+ customColors,
111
+ children
112
+ }) {
113
+ const config = useMemo2(
114
+ () => ({
115
+ source,
116
+ scheme,
117
+ contrast,
118
+ customColors
119
+ }),
120
+ [contrast, customColors, scheme, source]
121
+ );
122
+ const { css } = useMemo2(() => generateCss(config), [config]);
123
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
124
+ /* @__PURE__ */ jsx2("style", { id: mcuStyleId, children: css }),
125
+ /* @__PURE__ */ jsx2(McuProvider, { ...config, styleId: mcuStyleId, children })
126
+ ] });
127
+ }
128
+ var tokenNames = [
129
+ "background",
130
+ "onBackground",
131
+ "surface",
132
+ "surfaceDim",
133
+ "surfaceBright",
134
+ "surfaceContainerLowest",
135
+ "surfaceContainerLow",
136
+ "surfaceContainer",
137
+ "surfaceContainerHigh",
138
+ "surfaceContainerHighest",
139
+ "onSurface",
140
+ "onSurfaceVariant",
141
+ "outline",
142
+ "outlineVariant",
143
+ "inverseSurface",
144
+ "inverseOnSurface",
145
+ "primary",
146
+ // "primaryDim",
147
+ "onPrimary",
148
+ "primaryContainer",
149
+ "onPrimaryContainer",
150
+ "primaryFixed",
151
+ "primaryFixedDim",
152
+ "onPrimaryFixed",
153
+ "onPrimaryFixedVariant",
154
+ "inversePrimary",
155
+ "primaryFixed",
156
+ "primaryFixedDim",
157
+ "onPrimaryFixed",
158
+ "onPrimaryFixedVariant",
159
+ "secondary",
160
+ // "secondaryDim",
161
+ "onSecondary",
162
+ "secondaryContainer",
163
+ "onSecondaryContainer",
164
+ "secondaryFixed",
165
+ "secondaryFixedDim",
166
+ "onSecondaryFixed",
167
+ "onSecondaryFixedVariant",
168
+ "tertiary",
169
+ // "tertiaryDim",
170
+ "onTertiary",
171
+ "tertiaryContainer",
172
+ "onTertiaryContainer",
173
+ "tertiaryFixed",
174
+ "tertiaryFixedDim",
175
+ "onTertiaryFixed",
176
+ "onTertiaryFixedVariant",
177
+ "error",
178
+ // "errorDim",
179
+ "onError",
180
+ "errorContainer",
181
+ "onErrorContainer",
182
+ "scrim",
183
+ // added manually, was missing
184
+ "shadow"
185
+ // added manually, was missing
186
+ ];
187
+ function toRecord(arr, getEntry) {
188
+ return arr.reduce(
189
+ (acc, item) => {
190
+ const [key, value] = getEntry(item);
191
+ acc[key] = value;
192
+ return acc;
193
+ },
194
+ {}
195
+ );
196
+ }
197
+ function mergeBaseAndCustomColors(scheme, customColors) {
198
+ const baseVars = toRecord(tokenNames, (tokenName) => {
199
+ const dynamicColor = MaterialDynamicColors[tokenName];
200
+ const argb = dynamicColor.getArgb(scheme);
201
+ return [tokenName, argb];
202
+ });
203
+ const customVars = toRecord(customColors, (color) => [
204
+ color.name,
205
+ color.value
206
+ ]);
207
+ return { ...baseVars, ...customVars };
208
+ }
209
+ var cssVar = (colorName, colorValue) => {
210
+ const name = `--mcu-${kebabCase(colorName)}`;
211
+ const value = hexFromArgb2(colorValue);
212
+ return `${name}:${value};`;
213
+ };
214
+ var toCssVars = (mergedColors) => {
215
+ return Object.entries(mergedColors).map(([name, value]) => cssVar(name, value)).join(" ");
5
216
  };
217
+ function generateCss({
218
+ source: hexSource,
219
+ customColors: hexCustomColors,
220
+ scheme,
221
+ contrast
222
+ }) {
223
+ console.log("MCU generateCss");
224
+ const sourceArgb = argbFromHex(hexSource);
225
+ const hct = Hct.fromInt(sourceArgb);
226
+ const SchemeClass = schemesMap[scheme];
227
+ const lightScheme = new SchemeClass(hct, false, contrast);
228
+ const darkScheme = new SchemeClass(hct, true, contrast);
229
+ const customColors = hexCustomColors.map(({ hex, ...rest }) => ({
230
+ ...rest,
231
+ value: argbFromHex(hex)
232
+ }));
233
+ const mergedColorsLight = mergeBaseAndCustomColors(lightScheme, customColors);
234
+ const mergedColorsDark = mergeBaseAndCustomColors(darkScheme, customColors);
235
+ const lightVars = toCssVars(mergedColorsLight);
236
+ const darkVars = toCssVars(mergedColorsDark);
237
+ return {
238
+ css: `
239
+ :root { ${lightVars} }
240
+ .dark { ${darkVars} }
241
+ `,
242
+ mergedColorsLight,
243
+ mergedColorsDark
244
+ };
245
+ }
6
246
  export {
7
247
  Mcu
8
248
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-mcu",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "A React component library",
5
5
  "keywords": [
6
6
  "react",
@@ -28,25 +28,35 @@
28
28
  ],
29
29
  "type": "module",
30
30
  "devDependencies": {
31
- "@arethetypeswrong/cli": "^0.15.4",
31
+ "@arethetypeswrong/cli": "^0.18.2",
32
32
  "@changesets/cli": "^2.27.7",
33
+ "@storybook/react-vite": "^10.1.11",
33
34
  "@testing-library/dom": "^10.4.1",
34
35
  "@testing-library/react": "^16.3.1",
36
+ "@types/lodash-es": "^4.17.12",
35
37
  "@types/react": "^19.2.7",
36
38
  "@types/react-dom": "^19.2.3",
37
39
  "@vitejs/plugin-react": "^5.1.2",
40
+ "chromatic": "^13.3.5",
41
+ "husky": "^9.1.7",
38
42
  "jsdom": "^27.4.0",
43
+ "lint-staged": "^16.2.7",
39
44
  "prettier": "^3.3.3",
40
45
  "react": "^19.2.3",
41
46
  "react-dom": "^19.2.3",
47
+ "storybook": "^10.1.11",
42
48
  "tsup": "^8.2.4",
43
49
  "typescript": "^5.5.4",
44
- "vitest": "^2.0.5"
50
+ "vitest": "^4.0.16"
45
51
  },
46
52
  "peerDependencies": {
47
53
  "react": "^19.2.3",
48
54
  "react-dom": "^19.2.3"
49
55
  },
56
+ "dependencies": {
57
+ "@material/material-color-utilities": "^0.3.0",
58
+ "lodash-es": "^4.17.22"
59
+ },
50
60
  "scripts": {
51
61
  "build": "tsup",
52
62
  "ci": "pnpm run build && pnpm run check-format && pnpm run check-exports && pnpm run lint && pnpm run test",
@@ -56,6 +66,9 @@
56
66
  "check-format": "prettier --check .",
57
67
  "check-exports": "attw --pack . --ignore-rules cjs-resolves-to-esm no-resolution",
58
68
  "release": "pnpm run build && changeset publish",
59
- "local-release": "pnpm run ci && changeset version && changeset publish"
69
+ "local-release": "pnpm run ci && changeset version && changeset publish",
70
+ "storybook": "storybook dev -p 6006",
71
+ "build-storybook": "storybook build",
72
+ "chromatic": "chromatic --project-token $CHROMATIC_PROJECT_TOKEN"
60
73
  }
61
74
  }