react-mcu 1.0.0 → 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 +45 -26
- package/dist/index.d.ts +27 -4
- package/dist/index.js +242 -2
- package/package.json +24 -11
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,39 +1,58 @@
|
|
|
1
|
-
|
|
1
|
+
[](https://www.npmjs.com/package/react-mcu)
|
|
2
|
+
[](https://www.chromatic.com/library?appId=695eb517cb602e59b4cc045c&branch=main)
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install react-mcu
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Usage
|
|
4
|
+
Usage:
|
|
12
5
|
|
|
13
6
|
```tsx
|
|
14
|
-
import { Mcu } from
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
import { Mcu } from "react-mcu";
|
|
8
|
+
|
|
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>
|
|
19
22
|
```
|
|
20
23
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
29
47
|
```
|
|
30
48
|
|
|
31
|
-
##
|
|
49
|
+
## CONTRIBUTING
|
|
32
50
|
|
|
33
|
-
When submitting a pull request, please include a changeset to document your
|
|
51
|
+
When submitting a pull request, please include a changeset to document your
|
|
52
|
+
changes:
|
|
34
53
|
|
|
35
54
|
```bash
|
|
36
|
-
|
|
55
|
+
pnpm exec changeset
|
|
37
56
|
```
|
|
38
57
|
|
|
39
58
|
This helps us maintain the changelog and version the package appropriately.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
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
|
|
4
|
-
|
|
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.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A React component library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -28,34 +28,47 @@
|
|
|
28
28
|
],
|
|
29
29
|
"type": "module",
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@arethetypeswrong/cli": "^0.
|
|
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": "^
|
|
50
|
+
"vitest": "^4.0.16"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"react": "^19.2.3",
|
|
54
|
+
"react-dom": "^19.2.3"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@material/material-color-utilities": "^0.3.0",
|
|
58
|
+
"lodash-es": "^4.17.22"
|
|
45
59
|
},
|
|
46
60
|
"scripts": {
|
|
47
61
|
"build": "tsup",
|
|
48
|
-
"ci": "
|
|
62
|
+
"ci": "pnpm run build && pnpm run check-format && pnpm run check-exports && pnpm run lint && pnpm run test",
|
|
49
63
|
"lint": "tsc",
|
|
50
64
|
"test": "vitest run",
|
|
51
65
|
"format": "prettier --write .",
|
|
52
66
|
"check-format": "prettier --check .",
|
|
53
67
|
"check-exports": "attw --pack . --ignore-rules cjs-resolves-to-esm no-resolution",
|
|
54
|
-
"release": "
|
|
55
|
-
"local-release": "
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
"react-dom": "^19.2.3"
|
|
68
|
+
"release": "pnpm run build && 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
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) Matt Pocock 2024
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|