@niibase/uniwind 1.5.1 โ 1.6.1
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/CHANGELOG.md +45 -0
- package/dist/common/components/web/generateDataSet.js +2 -1
- package/dist/common/core/config/config.common.js +6 -3
- package/dist/common/core/web/getWebStyles.js +12 -1
- package/dist/common/hoc/withUniwind.js +7 -4
- package/dist/common/hoc/withUniwind.native.js +4 -4
- package/dist/common/hooks/useResolveClassNames.js +1 -1
- package/dist/metro/metro-transformer.cjs +42 -7
- package/dist/metro/metro-transformer.mjs +42 -7
- package/dist/module/components/web/generateDataSet.d.ts +1 -1
- package/dist/module/components/web/generateDataSet.js +2 -1
- package/dist/module/core/config/config.common.d.ts +2 -1
- package/dist/module/core/config/config.common.js +6 -3
- package/dist/module/core/web/getWebStyles.d.ts +1 -1
- package/dist/module/core/web/getWebStyles.js +12 -1
- package/dist/module/hoc/withUniwind.js +7 -4
- package/dist/module/hoc/withUniwind.native.js +4 -4
- package/dist/module/hooks/useResolveClassNames.js +2 -2
- package/dist/module/hooks/useUniwind.d.ts +2 -1
- package/dist/module/index.d.ts +1 -0
- package/package.json +3 -2
- package/src/components/web/generateDataSet.ts +4 -2
- package/src/components/web/rnw.ts +1 -1
- package/src/core/config/config.common.ts +7 -3
- package/src/core/web/getWebStyles.ts +20 -1
- package/src/hoc/withUniwind.native.tsx +4 -4
- package/src/hoc/withUniwind.tsx +5 -2
- package/src/hooks/useResolveClassNames.ts +2 -2
- package/src/hooks/useUniwind.ts +2 -2
- package/src/index.ts +1 -0
- package/src/metro/processor/color.ts +2 -1
- package/src/metro/processor/css.ts +35 -0
- package/src/metro/utils/serialize.ts +13 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,48 @@
|
|
|
1
|
+
## What's Changed in 1.6.1
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### ๐ Bug Fixes
|
|
6
|
+
|
|
7
|
+
* pass data attributes to withUniwind (#477) by @Brentlok
|
|
8
|
+
* p3 color parsing (#476) by @Brentlok
|
|
9
|
+
|
|
10
|
+
### ๐งช Testing
|
|
11
|
+
|
|
12
|
+
* advanced type check for ThemeName (#465) by @Brentlok
|
|
13
|
+
|
|
14
|
+
### ๐ฆ Other
|
|
15
|
+
|
|
16
|
+
* Merge branch 'prepare-release' by @divineniiquaye
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
**Full Changelog**: https://github.com/divineniiquaye/uniwind/compare/v1.6.0...v1.6.1
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## What's Changed in 1.6.0
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### ๐ Features
|
|
27
|
+
|
|
28
|
+
* export ThemeName and make themes public in Uniwind class (#460) by @Brentlok
|
|
29
|
+
|
|
30
|
+
### ๐ Bug Fixes
|
|
31
|
+
|
|
32
|
+
* parsing multiple transforms tokens in single class (#451) by @Brentlok
|
|
33
|
+
|
|
34
|
+
### ๐ Chores
|
|
35
|
+
|
|
36
|
+
* validate each entry in serialization instead of whole object (#456) by @Brentlok
|
|
37
|
+
|
|
38
|
+
### ๐ฆ Other
|
|
39
|
+
|
|
40
|
+
* Merge branch 'orig' by @divineniiquaye
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
**Full Changelog**: https://github.com/divineniiquaye/uniwind/compare/v1.5.1...v1.6.0
|
|
44
|
+
|
|
45
|
+
|
|
1
46
|
## What's Changed in 1.5.1
|
|
2
47
|
|
|
3
48
|
|
|
@@ -4,13 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.generateDataSet = void 0;
|
|
7
|
+
const toCamelCase = str => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
7
8
|
const generateDataSet = props => {
|
|
8
9
|
const dataSet = props.dataSet !== void 0 ? {
|
|
9
10
|
...props.dataSet
|
|
10
11
|
} : {};
|
|
11
12
|
Object.entries(props).forEach(([key, value]) => {
|
|
12
13
|
if (key.startsWith("data-")) {
|
|
13
|
-
dataSet[key.slice(5)] = value;
|
|
14
|
+
dataSet[toCamelCase(key.slice(5))] = value;
|
|
14
15
|
}
|
|
15
16
|
});
|
|
16
17
|
return dataSet;
|
|
@@ -13,7 +13,7 @@ const SYSTEM_THEME = "system";
|
|
|
13
13
|
const RN_VERSION = _reactNative.Platform.constants?.reactNativeVersion?.minor ?? 0;
|
|
14
14
|
const UNSPECIFIED_THEME = RN_VERSION >= 82 ? "unspecified" : void 0;
|
|
15
15
|
class UniwindConfigBuilder {
|
|
16
|
-
|
|
16
|
+
_themes = ["light", "dark"];
|
|
17
17
|
#hasAdaptiveThemes = true;
|
|
18
18
|
#currentTheme = this.colorScheme;
|
|
19
19
|
constructor() {
|
|
@@ -27,6 +27,9 @@ class UniwindConfigBuilder {
|
|
|
27
27
|
}
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
|
+
get themes() {
|
|
31
|
+
return this._themes;
|
|
32
|
+
}
|
|
30
33
|
get hasAdaptiveThemes() {
|
|
31
34
|
return this.#hasAdaptiveThemes;
|
|
32
35
|
}
|
|
@@ -61,7 +64,7 @@ class UniwindConfigBuilder {
|
|
|
61
64
|
}
|
|
62
65
|
return;
|
|
63
66
|
}
|
|
64
|
-
if (!this.
|
|
67
|
+
if (!this._themes.includes(theme)) {
|
|
65
68
|
throw new Error(`Uniwind: You're trying to setTheme to '${theme}', but it was not registered.`);
|
|
66
69
|
}
|
|
67
70
|
this.#hasAdaptiveThemes = false;
|
|
@@ -89,7 +92,7 @@ class UniwindConfigBuilder {
|
|
|
89
92
|
insets;
|
|
90
93
|
}
|
|
91
94
|
__reinit(_, themes) {
|
|
92
|
-
this.
|
|
95
|
+
this._themes = themes;
|
|
93
96
|
}
|
|
94
97
|
onThemeChange() {}
|
|
95
98
|
}
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getWebVariable = exports.getWebStyles = void 0;
|
|
7
|
+
var _generateDataSet = require("../../components/web/generateDataSet");
|
|
7
8
|
var _cssListener = require("./cssListener");
|
|
8
9
|
var _parseCSSValue = require("./parseCSSValue");
|
|
9
10
|
const dummyParent = typeof document !== "undefined" ? Object.assign(document.createElement("div"), {
|
|
@@ -38,7 +39,7 @@ const getActiveStylesForClass = className => {
|
|
|
38
39
|
});
|
|
39
40
|
return extractedStyles;
|
|
40
41
|
};
|
|
41
|
-
const getWebStyles = (className, uniwindContext) => {
|
|
42
|
+
const getWebStyles = (className, componentProps, uniwindContext) => {
|
|
42
43
|
if (className === void 0) {
|
|
43
44
|
return {};
|
|
44
45
|
}
|
|
@@ -51,7 +52,17 @@ const getWebStyles = (className, uniwindContext) => {
|
|
|
51
52
|
dummyParent?.removeAttribute("class");
|
|
52
53
|
}
|
|
53
54
|
dummy.className = className;
|
|
55
|
+
const dataSet = (0, _generateDataSet.generateDataSet)(componentProps ?? {});
|
|
56
|
+
Object.entries(dataSet).forEach(([key, value]) => {
|
|
57
|
+
if (value === false || value === void 0) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
dummy.dataset[key] = String(value);
|
|
61
|
+
});
|
|
54
62
|
const computedStyles = getActiveStylesForClass(className);
|
|
63
|
+
Object.keys(dataSet).forEach(key => {
|
|
64
|
+
delete dummy.dataset[key];
|
|
65
|
+
});
|
|
55
66
|
return Object.fromEntries(Object.entries(computedStyles).map(([key, value]) => {
|
|
56
67
|
const parsedKey = key[0] === "-" ? key : key.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
57
68
|
return [parsedKey, (0, _parseCSSValue.parseCSSValue)(value)];
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.withUniwind = void 0;
|
|
7
7
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
8
8
|
var _react = require("react");
|
|
9
|
+
var _generateDataSet = require("../components/web/generateDataSet");
|
|
9
10
|
var _context = require("../core/context");
|
|
10
11
|
var _web = require("../core/web");
|
|
11
12
|
var _withUniwindUtils = require("./withUniwindUtils");
|
|
@@ -23,7 +24,7 @@ const withAutoUniwind = Component2 => props => {
|
|
|
23
24
|
return acc;
|
|
24
25
|
}
|
|
25
26
|
const className = propValue;
|
|
26
|
-
const color = (0, _web.getWebStyles)(className, uniwindContext).accentColor;
|
|
27
|
+
const color = (0, _web.getWebStyles)(className, props, uniwindContext).accentColor;
|
|
27
28
|
acc.generatedProps[colorProp] = color !== void 0 ? (0, _web.formatColor)(color) : void 0;
|
|
28
29
|
acc.classNames += `${className} `;
|
|
29
30
|
return acc;
|
|
@@ -54,7 +55,8 @@ const withAutoUniwind = Component2 => props => {
|
|
|
54
55
|
}, [classNames]);
|
|
55
56
|
return /* @__PURE__ */(0, _jsxRuntime.jsx)(Component2, {
|
|
56
57
|
...props,
|
|
57
|
-
...generatedProps
|
|
58
|
+
...generatedProps,
|
|
59
|
+
dataSet: (0, _generateDataSet.generateDataSet)(props)
|
|
58
60
|
});
|
|
59
61
|
};
|
|
60
62
|
const withManualUniwind = (Component2, options) => props => {
|
|
@@ -71,7 +73,7 @@ const withManualUniwind = (Component2, options) => props => {
|
|
|
71
73
|
if (props[propName] !== void 0) {
|
|
72
74
|
return acc;
|
|
73
75
|
}
|
|
74
|
-
const value = (0, _web.getWebStyles)(className, uniwindContext)[option.styleProperty];
|
|
76
|
+
const value = (0, _web.getWebStyles)(className, props, uniwindContext)[option.styleProperty];
|
|
75
77
|
const transformedValue = value !== void 0 && option.styleProperty.toLowerCase().includes("color") ? (0, _web.formatColor)(value) : value;
|
|
76
78
|
acc.classNames += `${className} `;
|
|
77
79
|
acc.generatedProps[propName] = transformedValue;
|
|
@@ -93,6 +95,7 @@ const withManualUniwind = (Component2, options) => props => {
|
|
|
93
95
|
}, [classNames]);
|
|
94
96
|
return /* @__PURE__ */(0, _jsxRuntime.jsx)(Component2, {
|
|
95
97
|
...props,
|
|
96
|
-
...generatedProps
|
|
98
|
+
...generatedProps,
|
|
99
|
+
dataSet: (0, _generateDataSet.generateDataSet)(props)
|
|
97
100
|
});
|
|
98
101
|
};
|
|
@@ -26,7 +26,7 @@ const withAutoUniwind = Component2 => props => {
|
|
|
26
26
|
const {
|
|
27
27
|
styles,
|
|
28
28
|
dependencies: dependencies2
|
|
29
|
-
} = _native.UniwindStore.getStyles(propValue,
|
|
29
|
+
} = _native.UniwindStore.getStyles(propValue, props, void 0, uniwindContext);
|
|
30
30
|
acc.dependencies.push(...dependencies2);
|
|
31
31
|
acc.generatedProps[colorProp] = styles.accentColor;
|
|
32
32
|
return acc;
|
|
@@ -36,7 +36,7 @@ const withAutoUniwind = Component2 => props => {
|
|
|
36
36
|
const {
|
|
37
37
|
styles,
|
|
38
38
|
dependencies: dependencies2
|
|
39
|
-
} = _native.UniwindStore.getStyles(propValue,
|
|
39
|
+
} = _native.UniwindStore.getStyles(propValue, props, void 0, uniwindContext);
|
|
40
40
|
acc.dependencies.push(...dependencies2);
|
|
41
41
|
acc.generatedProps[styleProp] ??= [];
|
|
42
42
|
acc.generatedProps[styleProp][0] = styles;
|
|
@@ -83,7 +83,7 @@ const withManualUniwind = (Component2, options) => props => {
|
|
|
83
83
|
const {
|
|
84
84
|
styles: styles2,
|
|
85
85
|
dependencies: dependencies3
|
|
86
|
-
} = _native.UniwindStore.getStyles(className,
|
|
86
|
+
} = _native.UniwindStore.getStyles(className, props, void 0, uniwindContext);
|
|
87
87
|
acc.generatedProps[propName] = styles2[option.styleProperty];
|
|
88
88
|
acc.dependencies.push(...dependencies3);
|
|
89
89
|
return acc;
|
|
@@ -91,7 +91,7 @@ const withManualUniwind = (Component2, options) => props => {
|
|
|
91
91
|
const {
|
|
92
92
|
styles,
|
|
93
93
|
dependencies: dependencies2
|
|
94
|
-
} = _native.UniwindStore.getStyles(className,
|
|
94
|
+
} = _native.UniwindStore.getStyles(className, props, void 0, uniwindContext);
|
|
95
95
|
acc.dependencies.push(...dependencies2);
|
|
96
96
|
if (!(0, _withUniwindUtils.isStyleProperty)(propName)) {
|
|
97
97
|
acc.generatedProps[propName] = styles;
|
|
@@ -10,7 +10,7 @@ var _web = require("../core/web");
|
|
|
10
10
|
const emptyState = {};
|
|
11
11
|
const useResolveClassNames = className => {
|
|
12
12
|
const uniwindContext = (0, _context.useUniwindContext)();
|
|
13
|
-
const [styles, recreate] = (0, _react.useReducer)(() => className !== "" ? (0, _web.getWebStyles)(className, uniwindContext) : emptyState, void 0, () => className !== "" ? (0, _web.getWebStyles)(className, uniwindContext) : emptyState);
|
|
13
|
+
const [styles, recreate] = (0, _react.useReducer)(() => className !== "" ? (0, _web.getWebStyles)(className, void 0, uniwindContext) : emptyState, void 0, () => className !== "" ? (0, _web.getWebStyles)(className, void 0, uniwindContext) : emptyState);
|
|
14
14
|
(0, _react.useLayoutEffect)(() => {
|
|
15
15
|
if (className === "") {
|
|
16
16
|
return;
|
|
@@ -94,6 +94,15 @@ const serializeJSObject = (obj, serializer) => {
|
|
|
94
94
|
const serializedObject = common.pipe(obj)(
|
|
95
95
|
Object.entries,
|
|
96
96
|
(entries) => entries.map(([key, value]) => serializer(key, serialize(value))),
|
|
97
|
+
(serializedValues) => serializedValues.filter((serializedValue) => {
|
|
98
|
+
try {
|
|
99
|
+
new Function(`function validateJS() { const obj = ({ ${serializedValue} }) }`);
|
|
100
|
+
return true;
|
|
101
|
+
} catch {
|
|
102
|
+
stringifyThemes.Logger.error(`Failed to serialize ${serializedValue} as a valid JS object entry. Skipping.`);
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}),
|
|
97
106
|
(entries) => entries.join(","),
|
|
98
107
|
(result) => {
|
|
99
108
|
if (result === "") {
|
|
@@ -102,12 +111,6 @@ const serializeJSObject = (obj, serializer) => {
|
|
|
102
111
|
return `${result},`;
|
|
103
112
|
}
|
|
104
113
|
);
|
|
105
|
-
try {
|
|
106
|
-
new Function(`function validateJS() { const obj = ({ ${serializedObject} }) }`);
|
|
107
|
-
} catch {
|
|
108
|
-
stringifyThemes.Logger.error("Failed to serialize javascript object");
|
|
109
|
-
return "";
|
|
110
|
-
}
|
|
111
114
|
return serializedObject;
|
|
112
115
|
};
|
|
113
116
|
|
|
@@ -337,8 +340,9 @@ class Color {
|
|
|
337
340
|
mode: "rgb"
|
|
338
341
|
});
|
|
339
342
|
}
|
|
343
|
+
const colorType = color.type === "display-p3" ? "p3" : color.type;
|
|
340
344
|
const result = this.toRgb({
|
|
341
|
-
mode:
|
|
345
|
+
mode: colorType,
|
|
342
346
|
...color
|
|
343
347
|
});
|
|
344
348
|
return this.format(result);
|
|
@@ -842,6 +846,12 @@ class CSS {
|
|
|
842
846
|
if (declarationValue.length === 1) {
|
|
843
847
|
return this.processValue(declarationValue[0]);
|
|
844
848
|
}
|
|
849
|
+
if (this.isTransformArray(declarationValue)) {
|
|
850
|
+
return declarationValue.flatMap((value) => {
|
|
851
|
+
const result = this.processValue(value);
|
|
852
|
+
return Array.isArray(result) ? result : [result];
|
|
853
|
+
});
|
|
854
|
+
}
|
|
845
855
|
return this.addComaBetweenTokens(declarationValue).reduce((acc, value, index, array) => {
|
|
846
856
|
if (typeof value === "object") {
|
|
847
857
|
const nextValue = array.at(index + 1);
|
|
@@ -949,6 +959,31 @@ class CSS {
|
|
|
949
959
|
this.logUnsupported(`Unsupported value - ${JSON.stringify(declarationValue)}`);
|
|
950
960
|
return void 0;
|
|
951
961
|
}
|
|
962
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
963
|
+
static TRANSFORM_TYPES = /* @__PURE__ */ new Set([
|
|
964
|
+
"translate",
|
|
965
|
+
"translateX",
|
|
966
|
+
"translateY",
|
|
967
|
+
"translateZ",
|
|
968
|
+
"rotate",
|
|
969
|
+
"rotateX",
|
|
970
|
+
"rotateY",
|
|
971
|
+
"rotateZ",
|
|
972
|
+
"scale",
|
|
973
|
+
"scaleX",
|
|
974
|
+
"scaleY",
|
|
975
|
+
"scaleZ",
|
|
976
|
+
"skew",
|
|
977
|
+
"skewX",
|
|
978
|
+
"skewY",
|
|
979
|
+
"matrix",
|
|
980
|
+
"perspective"
|
|
981
|
+
]);
|
|
982
|
+
isTransformArray(values) {
|
|
983
|
+
return values.every(
|
|
984
|
+
(value) => typeof value === "object" && value !== null && "type" in value && CSS.TRANSFORM_TYPES.has(value.type)
|
|
985
|
+
);
|
|
986
|
+
}
|
|
952
987
|
isOverflow(value) {
|
|
953
988
|
return typeof value === "object" && "x" in value && ["hidden", "visible"].includes(value.x);
|
|
954
989
|
}
|
|
@@ -87,6 +87,15 @@ const serializeJSObject = (obj, serializer) => {
|
|
|
87
87
|
const serializedObject = pipe(obj)(
|
|
88
88
|
Object.entries,
|
|
89
89
|
(entries) => entries.map(([key, value]) => serializer(key, serialize(value))),
|
|
90
|
+
(serializedValues) => serializedValues.filter((serializedValue) => {
|
|
91
|
+
try {
|
|
92
|
+
new Function(`function validateJS() { const obj = ({ ${serializedValue} }) }`);
|
|
93
|
+
return true;
|
|
94
|
+
} catch {
|
|
95
|
+
Logger.error(`Failed to serialize ${serializedValue} as a valid JS object entry. Skipping.`);
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}),
|
|
90
99
|
(entries) => entries.join(","),
|
|
91
100
|
(result) => {
|
|
92
101
|
if (result === "") {
|
|
@@ -95,12 +104,6 @@ const serializeJSObject = (obj, serializer) => {
|
|
|
95
104
|
return `${result},`;
|
|
96
105
|
}
|
|
97
106
|
);
|
|
98
|
-
try {
|
|
99
|
-
new Function(`function validateJS() { const obj = ({ ${serializedObject} }) }`);
|
|
100
|
-
} catch {
|
|
101
|
-
Logger.error("Failed to serialize javascript object");
|
|
102
|
-
return "";
|
|
103
|
-
}
|
|
104
107
|
return serializedObject;
|
|
105
108
|
};
|
|
106
109
|
|
|
@@ -330,8 +333,9 @@ class Color {
|
|
|
330
333
|
mode: "rgb"
|
|
331
334
|
});
|
|
332
335
|
}
|
|
336
|
+
const colorType = color.type === "display-p3" ? "p3" : color.type;
|
|
333
337
|
const result = this.toRgb({
|
|
334
|
-
mode:
|
|
338
|
+
mode: colorType,
|
|
335
339
|
...color
|
|
336
340
|
});
|
|
337
341
|
return this.format(result);
|
|
@@ -835,6 +839,12 @@ class CSS {
|
|
|
835
839
|
if (declarationValue.length === 1) {
|
|
836
840
|
return this.processValue(declarationValue[0]);
|
|
837
841
|
}
|
|
842
|
+
if (this.isTransformArray(declarationValue)) {
|
|
843
|
+
return declarationValue.flatMap((value) => {
|
|
844
|
+
const result = this.processValue(value);
|
|
845
|
+
return Array.isArray(result) ? result : [result];
|
|
846
|
+
});
|
|
847
|
+
}
|
|
838
848
|
return this.addComaBetweenTokens(declarationValue).reduce((acc, value, index, array) => {
|
|
839
849
|
if (typeof value === "object") {
|
|
840
850
|
const nextValue = array.at(index + 1);
|
|
@@ -942,6 +952,31 @@ class CSS {
|
|
|
942
952
|
this.logUnsupported(`Unsupported value - ${JSON.stringify(declarationValue)}`);
|
|
943
953
|
return void 0;
|
|
944
954
|
}
|
|
955
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
956
|
+
static TRANSFORM_TYPES = /* @__PURE__ */ new Set([
|
|
957
|
+
"translate",
|
|
958
|
+
"translateX",
|
|
959
|
+
"translateY",
|
|
960
|
+
"translateZ",
|
|
961
|
+
"rotate",
|
|
962
|
+
"rotateX",
|
|
963
|
+
"rotateY",
|
|
964
|
+
"rotateZ",
|
|
965
|
+
"scale",
|
|
966
|
+
"scaleX",
|
|
967
|
+
"scaleY",
|
|
968
|
+
"scaleZ",
|
|
969
|
+
"skew",
|
|
970
|
+
"skewX",
|
|
971
|
+
"skewY",
|
|
972
|
+
"matrix",
|
|
973
|
+
"perspective"
|
|
974
|
+
]);
|
|
975
|
+
isTransformArray(values) {
|
|
976
|
+
return values.every(
|
|
977
|
+
(value) => typeof value === "object" && value !== null && "type" in value && CSS.TRANSFORM_TYPES.has(value.type)
|
|
978
|
+
);
|
|
979
|
+
}
|
|
945
980
|
isOverflow(value) {
|
|
946
981
|
return typeof value === "object" && "x" in value && ["hidden", "visible"].includes(value.x);
|
|
947
982
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const generateDataSet: (props: Record<PropertyKey, any>) => DataSet;
|
|
2
|
-
type DataSet = Record<string, string | boolean>;
|
|
2
|
+
type DataSet = Record<string, string | boolean | undefined>;
|
|
3
3
|
declare module 'react-native' {
|
|
4
4
|
interface SwitchProps {
|
|
5
5
|
dataSet?: DataSet;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
const toCamelCase = (str) => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
1
2
|
export const generateDataSet = (props) => {
|
|
2
3
|
const dataSet = props.dataSet !== void 0 ? { ...props.dataSet } : {};
|
|
3
4
|
Object.entries(props).forEach(([key, value]) => {
|
|
4
5
|
if (key.startsWith("data-")) {
|
|
5
|
-
dataSet[key.slice(5)] = value;
|
|
6
|
+
dataSet[toCamelCase(key.slice(5))] = value;
|
|
6
7
|
}
|
|
7
8
|
});
|
|
8
9
|
return dataSet;
|
|
@@ -5,8 +5,9 @@ import { CSSVariables, GenerateStyleSheetsCallback, ThemeName } from '../types';
|
|
|
5
5
|
declare const SYSTEM_THEME: "system";
|
|
6
6
|
export declare class UniwindConfigBuilder {
|
|
7
7
|
#private;
|
|
8
|
-
protected
|
|
8
|
+
protected _themes: string[];
|
|
9
9
|
constructor();
|
|
10
|
+
get themes(): Array<ThemeName>;
|
|
10
11
|
get hasAdaptiveThemes(): boolean;
|
|
11
12
|
get currentTheme(): ThemeName;
|
|
12
13
|
private get colorScheme();
|
|
@@ -7,7 +7,7 @@ const SYSTEM_THEME = "system";
|
|
|
7
7
|
const RN_VERSION = Platform.constants?.reactNativeVersion?.minor ?? 0;
|
|
8
8
|
const UNSPECIFIED_THEME = RN_VERSION >= 82 ? "unspecified" : void 0;
|
|
9
9
|
export class UniwindConfigBuilder {
|
|
10
|
-
|
|
10
|
+
_themes = ["light", "dark"];
|
|
11
11
|
#hasAdaptiveThemes = true;
|
|
12
12
|
#currentTheme = this.colorScheme;
|
|
13
13
|
constructor() {
|
|
@@ -21,6 +21,9 @@ export class UniwindConfigBuilder {
|
|
|
21
21
|
}
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
+
get themes() {
|
|
25
|
+
return this._themes;
|
|
26
|
+
}
|
|
24
27
|
get hasAdaptiveThemes() {
|
|
25
28
|
return this.#hasAdaptiveThemes;
|
|
26
29
|
}
|
|
@@ -52,7 +55,7 @@ export class UniwindConfigBuilder {
|
|
|
52
55
|
}
|
|
53
56
|
return;
|
|
54
57
|
}
|
|
55
|
-
if (!this.
|
|
58
|
+
if (!this._themes.includes(theme)) {
|
|
56
59
|
throw new Error(`Uniwind: You're trying to setTheme to '${theme}', but it was not registered.`);
|
|
57
60
|
}
|
|
58
61
|
this.#hasAdaptiveThemes = false;
|
|
@@ -81,7 +84,7 @@ export class UniwindConfigBuilder {
|
|
|
81
84
|
insets;
|
|
82
85
|
}
|
|
83
86
|
__reinit(_, themes) {
|
|
84
|
-
this.
|
|
87
|
+
this._themes = themes;
|
|
85
88
|
}
|
|
86
89
|
onThemeChange() {
|
|
87
90
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { RNStyle, UniwindContextType } from '../types';
|
|
2
|
-
export declare const getWebStyles: (className: string | undefined, uniwindContext: UniwindContextType) => RNStyle;
|
|
2
|
+
export declare const getWebStyles: (className: string | undefined, componentProps: Record<string, unknown> | undefined, uniwindContext: UniwindContextType) => RNStyle;
|
|
3
3
|
export declare const getWebVariable: (name: string, uniwindContext: UniwindContextType) => string | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { generateDataSet } from "../../components/web/generateDataSet.js";
|
|
1
2
|
import { CSSListener } from "./cssListener.js";
|
|
2
3
|
import { parseCSSValue } from "./parseCSSValue.js";
|
|
3
4
|
const dummyParent = typeof document !== "undefined" ? Object.assign(document.createElement("div"), {
|
|
@@ -33,7 +34,7 @@ const getActiveStylesForClass = (className) => {
|
|
|
33
34
|
});
|
|
34
35
|
return extractedStyles;
|
|
35
36
|
};
|
|
36
|
-
export const getWebStyles = (className, uniwindContext) => {
|
|
37
|
+
export const getWebStyles = (className, componentProps, uniwindContext) => {
|
|
37
38
|
if (className === void 0) {
|
|
38
39
|
return {};
|
|
39
40
|
}
|
|
@@ -46,7 +47,17 @@ export const getWebStyles = (className, uniwindContext) => {
|
|
|
46
47
|
dummyParent?.removeAttribute("class");
|
|
47
48
|
}
|
|
48
49
|
dummy.className = className;
|
|
50
|
+
const dataSet = generateDataSet(componentProps ?? {});
|
|
51
|
+
Object.entries(dataSet).forEach(([key, value]) => {
|
|
52
|
+
if (value === false || value === void 0) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
dummy.dataset[key] = String(value);
|
|
56
|
+
});
|
|
49
57
|
const computedStyles = getActiveStylesForClass(className);
|
|
58
|
+
Object.keys(dataSet).forEach((key) => {
|
|
59
|
+
delete dummy.dataset[key];
|
|
60
|
+
});
|
|
50
61
|
return Object.fromEntries(
|
|
51
62
|
Object.entries(computedStyles).map(([key, value]) => {
|
|
52
63
|
const parsedKey = key[0] === "-" ? key : key.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useLayoutEffect, useReducer } from "react";
|
|
3
|
+
import { generateDataSet } from "../components/web/generateDataSet.js";
|
|
3
4
|
import { useUniwindContext } from "../core/context.js";
|
|
4
5
|
import { CSSListener, formatColor, getWebStyles } from "../core/web/index.js";
|
|
5
6
|
import { classToColor, classToStyle, isClassProperty, isColorClassProperty, isStyleProperty } from "./withUniwindUtils.js";
|
|
@@ -13,7 +14,7 @@ const withAutoUniwind = (Component2) => (props) => {
|
|
|
13
14
|
return acc;
|
|
14
15
|
}
|
|
15
16
|
const className = propValue;
|
|
16
|
-
const color = getWebStyles(className, uniwindContext).accentColor;
|
|
17
|
+
const color = getWebStyles(className, props, uniwindContext).accentColor;
|
|
17
18
|
acc.generatedProps[colorProp] = color !== void 0 ? formatColor(color) : void 0;
|
|
18
19
|
acc.classNames += `${className} `;
|
|
19
20
|
return acc;
|
|
@@ -40,7 +41,8 @@ const withAutoUniwind = (Component2) => (props) => {
|
|
|
40
41
|
Component2,
|
|
41
42
|
{
|
|
42
43
|
...props,
|
|
43
|
-
...generatedProps
|
|
44
|
+
...generatedProps,
|
|
45
|
+
dataSet: generateDataSet(props)
|
|
44
46
|
}
|
|
45
47
|
);
|
|
46
48
|
};
|
|
@@ -55,7 +57,7 @@ const withManualUniwind = (Component2, options) => (props) => {
|
|
|
55
57
|
if (props[propName] !== void 0) {
|
|
56
58
|
return acc;
|
|
57
59
|
}
|
|
58
|
-
const value = getWebStyles(className, uniwindContext)[option.styleProperty];
|
|
60
|
+
const value = getWebStyles(className, props, uniwindContext)[option.styleProperty];
|
|
59
61
|
const transformedValue = value !== void 0 && option.styleProperty.toLowerCase().includes("color") ? formatColor(value) : value;
|
|
60
62
|
acc.classNames += `${className} `;
|
|
61
63
|
acc.generatedProps[propName] = transformedValue;
|
|
@@ -73,7 +75,8 @@ const withManualUniwind = (Component2, options) => (props) => {
|
|
|
73
75
|
Component2,
|
|
74
76
|
{
|
|
75
77
|
...props,
|
|
76
|
-
...generatedProps
|
|
78
|
+
...generatedProps,
|
|
79
|
+
dataSet: generateDataSet(props)
|
|
77
80
|
}
|
|
78
81
|
);
|
|
79
82
|
};
|
|
@@ -13,14 +13,14 @@ const withAutoUniwind = (Component2) => (props) => {
|
|
|
13
13
|
if (props[colorProp] !== void 0) {
|
|
14
14
|
return acc;
|
|
15
15
|
}
|
|
16
|
-
const { styles, dependencies: dependencies2 } = UniwindStore.getStyles(propValue,
|
|
16
|
+
const { styles, dependencies: dependencies2 } = UniwindStore.getStyles(propValue, props, void 0, uniwindContext);
|
|
17
17
|
acc.dependencies.push(...dependencies2);
|
|
18
18
|
acc.generatedProps[colorProp] = styles.accentColor;
|
|
19
19
|
return acc;
|
|
20
20
|
}
|
|
21
21
|
if (isClassProperty(propName)) {
|
|
22
22
|
const styleProp = classToStyle(propName);
|
|
23
|
-
const { styles, dependencies: dependencies2 } = UniwindStore.getStyles(propValue,
|
|
23
|
+
const { styles, dependencies: dependencies2 } = UniwindStore.getStyles(propValue, props, void 0, uniwindContext);
|
|
24
24
|
acc.dependencies.push(...dependencies2);
|
|
25
25
|
acc.generatedProps[styleProp] ??= [];
|
|
26
26
|
acc.generatedProps[styleProp][0] = styles;
|
|
@@ -61,12 +61,12 @@ const withManualUniwind = (Component2, options) => (props) => {
|
|
|
61
61
|
if (props[propName] !== void 0) {
|
|
62
62
|
return acc;
|
|
63
63
|
}
|
|
64
|
-
const { styles: styles2, dependencies: dependencies3 } = UniwindStore.getStyles(className,
|
|
64
|
+
const { styles: styles2, dependencies: dependencies3 } = UniwindStore.getStyles(className, props, void 0, uniwindContext);
|
|
65
65
|
acc.generatedProps[propName] = styles2[option.styleProperty];
|
|
66
66
|
acc.dependencies.push(...dependencies3);
|
|
67
67
|
return acc;
|
|
68
68
|
}
|
|
69
|
-
const { styles, dependencies: dependencies2 } = UniwindStore.getStyles(className,
|
|
69
|
+
const { styles, dependencies: dependencies2 } = UniwindStore.getStyles(className, props, void 0, uniwindContext);
|
|
70
70
|
acc.dependencies.push(...dependencies2);
|
|
71
71
|
if (!isStyleProperty(propName)) {
|
|
72
72
|
acc.generatedProps[propName] = styles;
|
|
@@ -5,9 +5,9 @@ const emptyState = {};
|
|
|
5
5
|
export const useResolveClassNames = (className) => {
|
|
6
6
|
const uniwindContext = useUniwindContext();
|
|
7
7
|
const [styles, recreate] = useReducer(
|
|
8
|
-
() => className !== "" ? getWebStyles(className, uniwindContext) : emptyState,
|
|
8
|
+
() => className !== "" ? getWebStyles(className, void 0, uniwindContext) : emptyState,
|
|
9
9
|
void 0,
|
|
10
|
-
() => className !== "" ? getWebStyles(className, uniwindContext) : emptyState
|
|
10
|
+
() => className !== "" ? getWebStyles(className, void 0, uniwindContext) : emptyState
|
|
11
11
|
);
|
|
12
12
|
useLayoutEffect(() => {
|
|
13
13
|
if (className === "") {
|
package/dist/module/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './components/ScopedTheme';
|
|
2
2
|
export { Uniwind } from './core';
|
|
3
|
+
export type { ThemeName } from './core/types';
|
|
3
4
|
export { withUniwind } from './hoc';
|
|
4
5
|
export type { ApplyUniwind, ApplyUniwindOptions } from './hoc/types';
|
|
5
6
|
export { useCSSVariable, useResolveClassNames, useUniwind } from './hooks';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@niibase/uniwind",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.6.1",
|
|
5
5
|
"description": "A fork of Uniwind with Reanimated 4 support",
|
|
6
6
|
"homepage": "https://uniwind.dev",
|
|
7
7
|
"author": "Unistack",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"postinstall": "node scripts/postinstall.mjs",
|
|
22
22
|
"test:native": "jest --config jest.config.native.js",
|
|
23
23
|
"test:web": "jest --config jest.config.web.js",
|
|
24
|
+
"test:types": "tsc --project tests/type-test/tsconfig.json",
|
|
24
25
|
"test:e2e": "playwright test",
|
|
25
26
|
"release": "release-it"
|
|
26
27
|
},
|
|
@@ -121,7 +122,7 @@
|
|
|
121
122
|
"ts-jest": "29.4.6",
|
|
122
123
|
"typescript": "catalog:",
|
|
123
124
|
"unbuild": "3.6.1",
|
|
124
|
-
"vite": "
|
|
125
|
+
"vite": "catalog:",
|
|
125
126
|
"esbuild": "0.27.3"
|
|
126
127
|
}
|
|
127
128
|
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
+
const toCamelCase = (str: string) => str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())
|
|
2
|
+
|
|
1
3
|
export const generateDataSet = (props: Record<PropertyKey, any>) => {
|
|
2
4
|
const dataSet: DataSet = props.dataSet !== undefined ? { ...props.dataSet } : {}
|
|
3
5
|
|
|
4
6
|
Object.entries(props).forEach(([key, value]) => {
|
|
5
7
|
if (key.startsWith('data-')) {
|
|
6
8
|
// Remove data- prefix
|
|
7
|
-
dataSet[key.slice(5)] = value
|
|
9
|
+
dataSet[toCamelCase(key.slice(5))] = value
|
|
8
10
|
}
|
|
9
11
|
})
|
|
10
12
|
|
|
11
13
|
return dataSet
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
type DataSet = Record<string, string | boolean>
|
|
16
|
+
type DataSet = Record<string, string | boolean | undefined>
|
|
15
17
|
|
|
16
18
|
declare module 'react-native' {
|
|
17
19
|
interface SwitchProps {
|
|
@@ -13,7 +13,7 @@ const RN_VERSION = Platform.constants?.reactNativeVersion?.minor ?? 0
|
|
|
13
13
|
const UNSPECIFIED_THEME = RN_VERSION >= 82 ? 'unspecified' : undefined
|
|
14
14
|
|
|
15
15
|
export class UniwindConfigBuilder {
|
|
16
|
-
protected
|
|
16
|
+
protected _themes = ['light', 'dark']
|
|
17
17
|
#hasAdaptiveThemes = true
|
|
18
18
|
#currentTheme = this.colorScheme as ThemeName
|
|
19
19
|
|
|
@@ -33,6 +33,10 @@ export class UniwindConfigBuilder {
|
|
|
33
33
|
})
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
get themes() {
|
|
37
|
+
return this._themes as Array<ThemeName>
|
|
38
|
+
}
|
|
39
|
+
|
|
36
40
|
get hasAdaptiveThemes() {
|
|
37
41
|
return this.#hasAdaptiveThemes
|
|
38
42
|
}
|
|
@@ -77,7 +81,7 @@ export class UniwindConfigBuilder {
|
|
|
77
81
|
return
|
|
78
82
|
}
|
|
79
83
|
|
|
80
|
-
if (!this.
|
|
84
|
+
if (!this._themes.includes(theme)) {
|
|
81
85
|
throw new Error(`Uniwind: You're trying to setTheme to '${theme}', but it was not registered.`)
|
|
82
86
|
}
|
|
83
87
|
|
|
@@ -116,7 +120,7 @@ export class UniwindConfigBuilder {
|
|
|
116
120
|
}
|
|
117
121
|
|
|
118
122
|
protected __reinit(_: GenerateStyleSheetsCallback, themes: Array<string>) {
|
|
119
|
-
this.
|
|
123
|
+
this._themes = themes
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
protected onThemeChange() {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { generateDataSet } from '../../components/web/generateDataSet'
|
|
1
2
|
import { RNStyle, UniwindContextType } from '../types'
|
|
2
3
|
import { CSSListener } from './cssListener'
|
|
3
4
|
import { parseCSSValue } from './parseCSSValue'
|
|
@@ -52,7 +53,11 @@ const getActiveStylesForClass = (className: string) => {
|
|
|
52
53
|
return extractedStyles
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
export const getWebStyles = (
|
|
56
|
+
export const getWebStyles = (
|
|
57
|
+
className: string | undefined,
|
|
58
|
+
componentProps: Record<string, unknown> | undefined,
|
|
59
|
+
uniwindContext: UniwindContextType,
|
|
60
|
+
): RNStyle => {
|
|
56
61
|
if (className === undefined) {
|
|
57
62
|
return {}
|
|
58
63
|
}
|
|
@@ -69,8 +74,22 @@ export const getWebStyles = (className: string | undefined, uniwindContext: Uniw
|
|
|
69
74
|
|
|
70
75
|
dummy.className = className
|
|
71
76
|
|
|
77
|
+
const dataSet = generateDataSet(componentProps ?? {})
|
|
78
|
+
|
|
79
|
+
Object.entries(dataSet).forEach(([key, value]) => {
|
|
80
|
+
if (value === false || value === undefined) {
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
dummy.dataset[key] = String(value)
|
|
85
|
+
})
|
|
86
|
+
|
|
72
87
|
const computedStyles = getActiveStylesForClass(className)
|
|
73
88
|
|
|
89
|
+
Object.keys(dataSet).forEach(key => {
|
|
90
|
+
delete dummy.dataset[key]
|
|
91
|
+
})
|
|
92
|
+
|
|
74
93
|
return Object.fromEntries(
|
|
75
94
|
Object.entries(computedStyles)
|
|
76
95
|
.map(([key, value]) => {
|
|
@@ -26,7 +26,7 @@ const withAutoUniwind = (Component: Component<AnyObject>) => (props: AnyObject)
|
|
|
26
26
|
return acc
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
const { styles, dependencies } = UniwindStore.getStyles(propValue,
|
|
29
|
+
const { styles, dependencies } = UniwindStore.getStyles(propValue, props, undefined, uniwindContext)
|
|
30
30
|
|
|
31
31
|
acc.dependencies.push(...dependencies)
|
|
32
32
|
acc.generatedProps[colorProp] = styles.accentColor
|
|
@@ -36,7 +36,7 @@ const withAutoUniwind = (Component: Component<AnyObject>) => (props: AnyObject)
|
|
|
36
36
|
|
|
37
37
|
if (isClassProperty(propName)) {
|
|
38
38
|
const styleProp = classToStyle(propName)
|
|
39
|
-
const { styles, dependencies } = UniwindStore.getStyles(propValue,
|
|
39
|
+
const { styles, dependencies } = UniwindStore.getStyles(propValue, props, undefined, uniwindContext)
|
|
40
40
|
|
|
41
41
|
acc.dependencies.push(...dependencies)
|
|
42
42
|
acc.generatedProps[styleProp] ??= []
|
|
@@ -90,7 +90,7 @@ const withManualUniwind = (Component: Component<AnyObject>, options: Record<Prop
|
|
|
90
90
|
return acc
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
const { styles, dependencies } = UniwindStore.getStyles(className,
|
|
93
|
+
const { styles, dependencies } = UniwindStore.getStyles(className, props, undefined, uniwindContext)
|
|
94
94
|
|
|
95
95
|
acc.generatedProps[propName] = styles[option.styleProperty]
|
|
96
96
|
acc.dependencies.push(...dependencies)
|
|
@@ -98,7 +98,7 @@ const withManualUniwind = (Component: Component<AnyObject>, options: Record<Prop
|
|
|
98
98
|
return acc
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
const { styles, dependencies } = UniwindStore.getStyles(className,
|
|
101
|
+
const { styles, dependencies } = UniwindStore.getStyles(className, props, undefined, uniwindContext)
|
|
102
102
|
acc.dependencies.push(...dependencies)
|
|
103
103
|
|
|
104
104
|
if (!isStyleProperty(propName)) {
|
package/src/hoc/withUniwind.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ComponentProps, useLayoutEffect, useReducer } from 'react'
|
|
2
|
+
import { generateDataSet } from '../components/web/generateDataSet'
|
|
2
3
|
import { useUniwindContext } from '../core/context'
|
|
3
4
|
import { CSSListener, formatColor, getWebStyles } from '../core/web'
|
|
4
5
|
import { AnyObject, Component, OptionMapping, WithUniwind } from './types'
|
|
@@ -26,7 +27,7 @@ const withAutoUniwind = (Component: Component<AnyObject>) => (props: AnyObject)
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
const className = propValue
|
|
29
|
-
const color = getWebStyles(className, uniwindContext).accentColor
|
|
30
|
+
const color = getWebStyles(className, props, uniwindContext).accentColor
|
|
30
31
|
|
|
31
32
|
acc.generatedProps[colorProp] = color !== undefined
|
|
32
33
|
? formatColor(color)
|
|
@@ -67,6 +68,7 @@ const withAutoUniwind = (Component: Component<AnyObject>) => (props: AnyObject)
|
|
|
67
68
|
<Component
|
|
68
69
|
{...props}
|
|
69
70
|
{...generatedProps}
|
|
71
|
+
dataSet={generateDataSet(props)}
|
|
70
72
|
/>
|
|
71
73
|
)
|
|
72
74
|
}
|
|
@@ -87,7 +89,7 @@ const withManualUniwind = (Component: Component<AnyObject>, options: Record<Prop
|
|
|
87
89
|
return acc
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
const value = getWebStyles(className, uniwindContext)[option.styleProperty]
|
|
92
|
+
const value = getWebStyles(className, props, uniwindContext)[option.styleProperty]
|
|
91
93
|
const transformedValue = value !== undefined && option.styleProperty.toLowerCase().includes('color')
|
|
92
94
|
? formatColor(value as string)
|
|
93
95
|
: value
|
|
@@ -115,6 +117,7 @@ const withManualUniwind = (Component: Component<AnyObject>, options: Record<Prop
|
|
|
115
117
|
<Component
|
|
116
118
|
{...props}
|
|
117
119
|
{...generatedProps}
|
|
120
|
+
dataSet={generateDataSet(props)}
|
|
118
121
|
/>
|
|
119
122
|
)
|
|
120
123
|
}
|
|
@@ -8,9 +8,9 @@ const emptyState = {} as RNStyle
|
|
|
8
8
|
export const useResolveClassNames = (className: string) => {
|
|
9
9
|
const uniwindContext = useUniwindContext()
|
|
10
10
|
const [styles, recreate] = useReducer(
|
|
11
|
-
() => className !== '' ? getWebStyles(className, uniwindContext) : emptyState,
|
|
11
|
+
() => className !== '' ? getWebStyles(className, undefined, uniwindContext) : emptyState,
|
|
12
12
|
undefined,
|
|
13
|
-
() => className !== '' ? getWebStyles(className, uniwindContext) : emptyState,
|
|
13
|
+
() => className !== '' ? getWebStyles(className, undefined, uniwindContext) : emptyState,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
useLayoutEffect(() => {
|
package/src/hooks/useUniwind.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { UniwindListener } from '../core/listener'
|
|
|
5
5
|
import { ThemeName } from '../core/types'
|
|
6
6
|
import { StyleDependency } from '../types'
|
|
7
7
|
|
|
8
|
-
export const useUniwind = () => {
|
|
8
|
+
export const useUniwind = (): { theme: ThemeName; hasAdaptiveThemes: boolean } => {
|
|
9
9
|
const uniwindContext = useUniwindContext()
|
|
10
10
|
const [theme, setTheme] = useState(Uniwind.currentTheme)
|
|
11
11
|
const [hasAdaptiveThemes, setHasAdaptiveThemes] = useState(Uniwind.hasAdaptiveThemes)
|
|
@@ -26,7 +26,7 @@ export const useUniwind = () => {
|
|
|
26
26
|
}, [uniwindContext])
|
|
27
27
|
|
|
28
28
|
return {
|
|
29
|
-
theme: uniwindContext.scopedTheme ?? theme
|
|
29
|
+
theme: uniwindContext.scopedTheme ?? theme,
|
|
30
30
|
hasAdaptiveThemes: uniwindContext.scopedTheme !== null ? false : hasAdaptiveThemes,
|
|
31
31
|
}
|
|
32
32
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './components/ScopedTheme'
|
|
2
2
|
export { Uniwind } from './core'
|
|
3
|
+
export type { ThemeName } from './core/types'
|
|
3
4
|
export { withUniwind } from './hoc'
|
|
4
5
|
export type { ApplyUniwind, ApplyUniwindOptions } from './hoc/types'
|
|
5
6
|
export { useCSSVariable, useResolveClassNames, useUniwind } from './hooks'
|
|
@@ -434,6 +434,14 @@ export class CSS {
|
|
|
434
434
|
return this.processValue(declarationValue[0]!)
|
|
435
435
|
}
|
|
436
436
|
|
|
437
|
+
if (this.isTransformArray(declarationValue)) {
|
|
438
|
+
return declarationValue.flatMap(value => {
|
|
439
|
+
const result = this.processValue(value)
|
|
440
|
+
|
|
441
|
+
return Array.isArray(result) ? result : [result]
|
|
442
|
+
})
|
|
443
|
+
}
|
|
444
|
+
|
|
437
445
|
return this.addComaBetweenTokens(declarationValue).reduce<string | number>((acc, value, index, array) => {
|
|
438
446
|
if (typeof value === 'object') {
|
|
439
447
|
const nextValue = array.at(index + 1)
|
|
@@ -580,6 +588,33 @@ export class CSS {
|
|
|
580
588
|
return undefined
|
|
581
589
|
}
|
|
582
590
|
|
|
591
|
+
// eslint-disable-next-line @typescript-eslint/member-ordering
|
|
592
|
+
private static readonly TRANSFORM_TYPES = new Set([
|
|
593
|
+
'translate',
|
|
594
|
+
'translateX',
|
|
595
|
+
'translateY',
|
|
596
|
+
'translateZ',
|
|
597
|
+
'rotate',
|
|
598
|
+
'rotateX',
|
|
599
|
+
'rotateY',
|
|
600
|
+
'rotateZ',
|
|
601
|
+
'scale',
|
|
602
|
+
'scaleX',
|
|
603
|
+
'scaleY',
|
|
604
|
+
'scaleZ',
|
|
605
|
+
'skew',
|
|
606
|
+
'skewX',
|
|
607
|
+
'skewY',
|
|
608
|
+
'matrix',
|
|
609
|
+
'perspective',
|
|
610
|
+
])
|
|
611
|
+
|
|
612
|
+
private isTransformArray(values: Array<any>) {
|
|
613
|
+
return values.every(
|
|
614
|
+
value => typeof value === 'object' && value !== null && 'type' in value && CSS.TRANSFORM_TYPES.has(value.type),
|
|
615
|
+
)
|
|
616
|
+
}
|
|
617
|
+
|
|
583
618
|
private isOverflow(value: any): value is { x: OverflowKeyword; y: OverflowKeyword } {
|
|
584
619
|
return typeof value === 'object' && 'x' in value && ['hidden', 'visible'].includes(value.x)
|
|
585
620
|
}
|
|
@@ -100,6 +100,19 @@ export const serializeJSObject = (obj: Record<string, any>, serializer: (key: st
|
|
|
100
100
|
const serializedObject = pipe(obj)(
|
|
101
101
|
Object.entries,
|
|
102
102
|
entries => entries.map(([key, value]) => serializer(key, serialize(value))),
|
|
103
|
+
serializedValues =>
|
|
104
|
+
serializedValues.filter(serializedValue => {
|
|
105
|
+
try {
|
|
106
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func
|
|
107
|
+
new Function(`function validateJS() { const obj = ({ ${serializedValue} }) }`)
|
|
108
|
+
|
|
109
|
+
return true
|
|
110
|
+
} catch {
|
|
111
|
+
Logger.error(`Failed to serialize ${serializedValue} as a valid JS object entry. Skipping.`)
|
|
112
|
+
|
|
113
|
+
return false
|
|
114
|
+
}
|
|
115
|
+
}),
|
|
103
116
|
entries => entries.join(','),
|
|
104
117
|
result => {
|
|
105
118
|
if (result === '') {
|
|
@@ -110,13 +123,5 @@ export const serializeJSObject = (obj: Record<string, any>, serializer: (key: st
|
|
|
110
123
|
},
|
|
111
124
|
)
|
|
112
125
|
|
|
113
|
-
try {
|
|
114
|
-
// eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func
|
|
115
|
-
new Function(`function validateJS() { const obj = ({ ${serializedObject} }) }`)
|
|
116
|
-
} catch {
|
|
117
|
-
Logger.error('Failed to serialize javascript object')
|
|
118
|
-
return ''
|
|
119
|
-
}
|
|
120
|
-
|
|
121
126
|
return serializedObject
|
|
122
127
|
}
|