react-native-css 3.1.0-rc.0 → 3.1.0-rc.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/README.md +24 -0
- package/dist/commonjs/babel/helpers.js +7 -0
- package/dist/commonjs/babel/helpers.js.map +1 -1
- package/dist/commonjs/babel/import-plugin.js +12 -6
- package/dist/commonjs/babel/import-plugin.js.map +1 -1
- package/dist/commonjs/babel/react-native-web.js +2 -2
- package/dist/commonjs/babel/react-native-web.js.map +1 -1
- package/dist/commonjs/babel/react-native.js +2 -2
- package/dist/commonjs/babel/react-native.js.map +1 -1
- package/dist/commonjs/compiler/compiler.js +15 -1
- package/dist/commonjs/compiler/compiler.js.map +1 -1
- package/dist/commonjs/compiler/declarations.js +1 -1
- package/dist/commonjs/compiler/declarations.js.map +1 -1
- package/dist/commonjs/compiler/selector-builder.js +2 -1
- package/dist/commonjs/compiler/selector-builder.js.map +1 -1
- package/dist/commonjs/compiler/stylesheet.js +11 -3
- package/dist/commonjs/compiler/stylesheet.js.map +1 -1
- package/dist/commonjs/metro/index.js.map +1 -1
- package/dist/commonjs/metro/metro-transformer.js +16 -3
- package/dist/commonjs/metro/metro-transformer.js.map +1 -1
- package/dist/commonjs/metro/warnings.js +135 -0
- package/dist/commonjs/metro/warnings.js.map +1 -0
- package/dist/commonjs/native/api.js +1 -1
- package/dist/commonjs/native/api.js.map +1 -1
- package/dist/commonjs/native/react/useNativeCss.js +15 -2
- package/dist/commonjs/native/react/useNativeCss.js.map +1 -1
- package/dist/commonjs/native/reactivity.js +30 -3
- package/dist/commonjs/native/reactivity.js.map +1 -1
- package/dist/commonjs/native-internal/root.js +18 -7
- package/dist/commonjs/native-internal/root.js.map +1 -1
- package/dist/commonjs/native-internal/variables.js +1 -1
- package/dist/commonjs/native-internal/variables.js.map +1 -1
- package/dist/module/babel/helpers.js +6 -0
- package/dist/module/babel/helpers.js.map +1 -1
- package/dist/module/babel/import-plugin.js +12 -6
- package/dist/module/babel/import-plugin.js.map +1 -1
- package/dist/module/babel/react-native-web.js +2 -2
- package/dist/module/babel/react-native-web.js.map +1 -1
- package/dist/module/babel/react-native.js +2 -2
- package/dist/module/babel/react-native.js.map +1 -1
- package/dist/module/compiler/compiler.js +15 -1
- package/dist/module/compiler/compiler.js.map +1 -1
- package/dist/module/compiler/compiler.types.js +2 -0
- package/dist/module/compiler/compiler.types.js.map +1 -1
- package/dist/module/compiler/declarations.js +1 -1
- package/dist/module/compiler/declarations.js.map +1 -1
- package/dist/module/compiler/selector-builder.js +2 -1
- package/dist/module/compiler/selector-builder.js.map +1 -1
- package/dist/module/compiler/stylesheet.js +11 -3
- package/dist/module/compiler/stylesheet.js.map +1 -1
- package/dist/module/metro/index.js.map +1 -1
- package/dist/module/metro/metro-transformer.js +16 -3
- package/dist/module/metro/metro-transformer.js.map +1 -1
- package/dist/module/metro/warnings.js +131 -0
- package/dist/module/metro/warnings.js.map +1 -0
- package/dist/module/native/api.js +2 -2
- package/dist/module/native/api.js.map +1 -1
- package/dist/module/native/react/useNativeCss.js +17 -4
- package/dist/module/native/react/useNativeCss.js.map +1 -1
- package/dist/module/native/reactivity.js +24 -1
- package/dist/module/native/reactivity.js.map +1 -1
- package/dist/module/native-internal/root.js +18 -7
- package/dist/module/native-internal/root.js.map +1 -1
- package/dist/module/native-internal/variables.js +2 -2
- package/dist/module/native-internal/variables.js.map +1 -1
- package/dist/typescript/commonjs/src/babel/helpers.d.ts +2 -1
- package/dist/typescript/commonjs/src/babel/helpers.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/babel/import-plugin.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/babel/react-native-web.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/babel/react-native.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/compiler/compiler.d.ts +1 -5
- package/dist/typescript/commonjs/src/compiler/compiler.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/compiler/compiler.types.d.ts +6 -0
- package/dist/typescript/commonjs/src/compiler/compiler.types.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/compiler/selector-builder.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/compiler/stylesheet.d.ts +6 -8
- package/dist/typescript/commonjs/src/compiler/stylesheet.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/jest/index.d.ts +2 -10
- package/dist/typescript/commonjs/src/jest/index.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/metro/index.d.ts +4 -0
- package/dist/typescript/commonjs/src/metro/index.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/metro/metro-transformer.d.ts +4 -1
- package/dist/typescript/commonjs/src/metro/metro-transformer.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/metro/warnings.d.ts +13 -0
- package/dist/typescript/commonjs/src/metro/warnings.d.ts.map +1 -0
- package/dist/typescript/commonjs/src/native/api.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/native/react/useNativeCss.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/native/reactivity.d.ts +7 -0
- package/dist/typescript/commonjs/src/native/reactivity.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/native-internal/root.d.ts +12 -0
- package/dist/typescript/commonjs/src/native-internal/root.d.ts.map +1 -1
- package/dist/typescript/commonjs/src/native-internal/variables.d.ts.map +1 -1
- package/dist/typescript/module/src/babel/helpers.d.ts +2 -1
- package/dist/typescript/module/src/babel/helpers.d.ts.map +1 -1
- package/dist/typescript/module/src/babel/import-plugin.d.ts.map +1 -1
- package/dist/typescript/module/src/babel/react-native-web.d.ts.map +1 -1
- package/dist/typescript/module/src/babel/react-native.d.ts.map +1 -1
- package/dist/typescript/module/src/compiler/compiler.d.ts +1 -5
- package/dist/typescript/module/src/compiler/compiler.d.ts.map +1 -1
- package/dist/typescript/module/src/compiler/compiler.types.d.ts +6 -0
- package/dist/typescript/module/src/compiler/compiler.types.d.ts.map +1 -1
- package/dist/typescript/module/src/compiler/selector-builder.d.ts.map +1 -1
- package/dist/typescript/module/src/compiler/stylesheet.d.ts +6 -8
- package/dist/typescript/module/src/compiler/stylesheet.d.ts.map +1 -1
- package/dist/typescript/module/src/jest/index.d.ts +2 -10
- package/dist/typescript/module/src/jest/index.d.ts.map +1 -1
- package/dist/typescript/module/src/metro/index.d.ts +4 -0
- package/dist/typescript/module/src/metro/index.d.ts.map +1 -1
- package/dist/typescript/module/src/metro/metro-transformer.d.ts +4 -1
- package/dist/typescript/module/src/metro/metro-transformer.d.ts.map +1 -1
- package/dist/typescript/module/src/metro/warnings.d.ts +13 -0
- package/dist/typescript/module/src/metro/warnings.d.ts.map +1 -0
- package/dist/typescript/module/src/native/api.d.ts.map +1 -1
- package/dist/typescript/module/src/native/react/useNativeCss.d.ts.map +1 -1
- package/dist/typescript/module/src/native/reactivity.d.ts +7 -0
- package/dist/typescript/module/src/native/reactivity.d.ts.map +1 -1
- package/dist/typescript/module/src/native-internal/root.d.ts +12 -0
- package/dist/typescript/module/src/native-internal/root.d.ts.map +1 -1
- package/dist/typescript/module/src/native-internal/variables.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/babel/helpers.ts +8 -1
- package/src/babel/import-plugin.ts +16 -12
- package/src/babel/react-native-web.ts +2 -3
- package/src/babel/react-native.ts +2 -3
- package/src/compiler/compiler.ts +19 -1
- package/src/compiler/compiler.types.ts +9 -0
- package/src/compiler/declarations.ts +1 -1
- package/src/compiler/selector-builder.ts +2 -1
- package/src/compiler/stylesheet.ts +17 -10
- package/src/metro/index.ts +5 -0
- package/src/metro/metro-transformer.ts +19 -4
- package/src/metro/warnings.ts +187 -0
- package/src/native/api.tsx +2 -3
- package/src/native/react/useNativeCss.ts +17 -2
- package/src/native/reactivity.ts +35 -1
- package/src/native-internal/root.ts +40 -13
- package/src/native-internal/variables.tsx +6 -4
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { relative } from "path";
|
|
2
|
+
|
|
3
|
+
import type { CompilerWarnings } from "../compiler/compiler.types";
|
|
4
|
+
|
|
5
|
+
/** "summary" prints one capped block per CSS file, "verbose" lists every entry, "none" prints nothing */
|
|
6
|
+
export type WarningLevel = "none" | "summary" | "verbose";
|
|
7
|
+
|
|
8
|
+
const SUMMARY_ENTRY_LIMIT = 10;
|
|
9
|
+
const SUMMARY_VALUE_LIMIT = 5;
|
|
10
|
+
const SUMMARY_VALUE_LENGTH_LIMIT = 60;
|
|
11
|
+
|
|
12
|
+
const PREFIX = "react-native-css";
|
|
13
|
+
|
|
14
|
+
// Metro re-transforms a CSS file on every rebuild, so a file's block prints again only when its warnings change
|
|
15
|
+
const lastReportedByFile = new Map<string, string>();
|
|
16
|
+
|
|
17
|
+
// Metro forwards each transform worker's stderr to the bundler's terminal, and a warning never fails the build
|
|
18
|
+
export function reportCompilerWarnings(
|
|
19
|
+
warnings: CompilerWarnings,
|
|
20
|
+
options: {
|
|
21
|
+
filename: string;
|
|
22
|
+
projectRoot: string;
|
|
23
|
+
level?: WarningLevel | undefined;
|
|
24
|
+
},
|
|
25
|
+
): void {
|
|
26
|
+
const { filename, projectRoot, level = "summary" } = options;
|
|
27
|
+
|
|
28
|
+
if (level === "none") {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const message = formatCompilerWarnings(warnings, {
|
|
33
|
+
displayPath: toDisplayPath(filename, projectRoot),
|
|
34
|
+
verbose: level === "verbose",
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (message === undefined) {
|
|
38
|
+
lastReportedByFile.delete(filename);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (lastReportedByFile.get(filename) === message) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
lastReportedByFile.set(filename, message);
|
|
47
|
+
|
|
48
|
+
console.warn(message);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Plain text: Metro's transform workers write to a pipe, where colour would never render
|
|
52
|
+
export function formatCompilerWarnings(
|
|
53
|
+
warnings: CompilerWarnings,
|
|
54
|
+
options: { displayPath: string; verbose?: boolean | undefined },
|
|
55
|
+
): string | undefined {
|
|
56
|
+
const { displayPath, verbose = false } = options;
|
|
57
|
+
|
|
58
|
+
const droppedCount =
|
|
59
|
+
(warnings.properties?.length ?? 0) +
|
|
60
|
+
(warnings.functions?.length ?? 0) +
|
|
61
|
+
Object.values(warnings.values ?? {}).reduce(
|
|
62
|
+
(total, entries) => total + entries.length,
|
|
63
|
+
0,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// A syntax warning sends the reader to their stylesheet rather than to what React Native lacks, so it is counted apart
|
|
67
|
+
const syntaxCount = warnings.syntax?.length ?? 0;
|
|
68
|
+
|
|
69
|
+
if (droppedCount === 0 && syntaxCount === 0) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const properties = limit(unique(warnings.properties), verbose);
|
|
74
|
+
const functions = limit(unique(warnings.functions), verbose);
|
|
75
|
+
const rendered = renderValues(warnings.values, verbose);
|
|
76
|
+
const values = limit(rendered.entries, verbose);
|
|
77
|
+
const syntax = limit(unique(warnings.syntax), verbose);
|
|
78
|
+
|
|
79
|
+
const claims: string[] = [];
|
|
80
|
+
if (droppedCount > 0) {
|
|
81
|
+
claims.push(
|
|
82
|
+
`${droppedCount} ${pluralize(droppedCount, "declaration")} dropped, no React Native equivalent`,
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
if (syntaxCount > 0) {
|
|
86
|
+
claims.push(`${syntaxCount} syntax ${pluralize(syntaxCount, "warning")}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const lines = [`${PREFIX}: ${displayPath} - ${claims.join("; ")}`];
|
|
90
|
+
|
|
91
|
+
if (syntax.shown.length > 0) {
|
|
92
|
+
lines.push(` syntax: ${syntax.shown.join("; ")}${suffix(syntax.hidden)}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (properties.shown.length > 0) {
|
|
96
|
+
lines.push(
|
|
97
|
+
` properties: ${properties.shown.join(", ")}${suffix(properties.hidden)}`,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (values.shown.length > 0) {
|
|
102
|
+
lines.push(` values: ${values.shown.join("; ")}${suffix(values.hidden)}`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (functions.shown.length > 0) {
|
|
106
|
+
lines.push(
|
|
107
|
+
` functions: ${functions.shown.join(", ")}${suffix(functions.hidden)}`,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (
|
|
112
|
+
properties.hidden +
|
|
113
|
+
values.hidden +
|
|
114
|
+
functions.hidden +
|
|
115
|
+
rendered.hidden +
|
|
116
|
+
syntax.hidden >
|
|
117
|
+
0
|
|
118
|
+
) {
|
|
119
|
+
lines.push(
|
|
120
|
+
` Set reactNativeCSS.warnings to "verbose" for the full list, or "none" to silence this.`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return lines.join("\n");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function toDisplayPath(filename: string, projectRoot: string): string {
|
|
128
|
+
const relativePath = relative(projectRoot, filename);
|
|
129
|
+
|
|
130
|
+
return relativePath === "" || relativePath.startsWith("..")
|
|
131
|
+
? filename
|
|
132
|
+
: relativePath;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function renderValues(
|
|
136
|
+
values: Record<string, string[]> | undefined,
|
|
137
|
+
verbose: boolean,
|
|
138
|
+
): { entries: string[]; hidden: number } {
|
|
139
|
+
let hidden = 0;
|
|
140
|
+
const entries: string[] = [];
|
|
141
|
+
const recordedByProperty = values ?? {};
|
|
142
|
+
|
|
143
|
+
for (const property of Object.keys(recordedByProperty).sort()) {
|
|
144
|
+
const distinct = unique(recordedByProperty[property]);
|
|
145
|
+
const shown = verbose ? distinct : distinct.slice(0, SUMMARY_VALUE_LIMIT);
|
|
146
|
+
hidden += distinct.length - shown.length;
|
|
147
|
+
|
|
148
|
+
const rendered = shown.map((value) => truncate(value, verbose));
|
|
149
|
+
|
|
150
|
+
entries.push(
|
|
151
|
+
`${property}: ${rendered.join(", ")}${suffix(distinct.length - shown.length)}`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return { entries, hidden };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function limit<T>(entries: T[], verbose: boolean) {
|
|
159
|
+
if (verbose || entries.length <= SUMMARY_ENTRY_LIMIT) {
|
|
160
|
+
return { shown: entries, hidden: 0 };
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
shown: entries.slice(0, SUMMARY_ENTRY_LIMIT),
|
|
165
|
+
hidden: entries.length - SUMMARY_ENTRY_LIMIT,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function suffix(hidden: number): string {
|
|
170
|
+
return hidden > 0 ? ` (+${hidden} more)` : "";
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Code-unit order rather than localeCompare, whose collation varies with the ICU build
|
|
174
|
+
function unique(entries: string[] | undefined): string[] {
|
|
175
|
+
return entries ? [...new Set(entries)].sort() : [];
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// An unresolved calc() is recorded as its whole lightningcss node, hundreds of characters long
|
|
179
|
+
function truncate(value: string, verbose: boolean): string {
|
|
180
|
+
return verbose || value.length <= SUMMARY_VALUE_LENGTH_LIMIT
|
|
181
|
+
? value
|
|
182
|
+
: `${value.slice(0, SUMMARY_VALUE_LENGTH_LIMIT)}...`;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function pluralize(count: number, noun: string): string {
|
|
186
|
+
return count === 1 ? noun : `${noun}s`;
|
|
187
|
+
}
|
package/src/native/api.tsx
CHANGED
|
@@ -18,6 +18,7 @@ import { usePassthrough } from "./react/usePassthrough";
|
|
|
18
18
|
import {
|
|
19
19
|
cleanupEffect,
|
|
20
20
|
colorScheme as colorSchemeObs,
|
|
21
|
+
toVariableRecord,
|
|
21
22
|
VAR_SYMBOL,
|
|
22
23
|
type Effect,
|
|
23
24
|
type Getter,
|
|
@@ -123,8 +124,6 @@ export function useNativeVariable(name: string) {
|
|
|
123
124
|
export function vars(variables: Record<string, StyleDescriptor>): ViewStyle {
|
|
124
125
|
return Object.assign(
|
|
125
126
|
{ [VAR_SYMBOL]: "inline" },
|
|
126
|
-
|
|
127
|
-
Object.entries(variables).map(([k, v]) => [k.replace(/^--/, ""), v]),
|
|
128
|
-
),
|
|
127
|
+
toVariableRecord(variables),
|
|
129
128
|
) as ViewStyle;
|
|
130
129
|
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
Fragment,
|
|
5
5
|
useContext,
|
|
6
6
|
useEffect,
|
|
7
|
+
useRef,
|
|
7
8
|
useState,
|
|
8
9
|
type ComponentType,
|
|
9
10
|
} from "react";
|
|
@@ -16,6 +17,7 @@ import { testGuards, type RenderGuard } from "../conditions/guards";
|
|
|
16
17
|
import {
|
|
17
18
|
cleanupEffect,
|
|
18
19
|
ContainerContext,
|
|
20
|
+
hasChangedDependencies,
|
|
19
21
|
type ContainerContextValue,
|
|
20
22
|
type Effect,
|
|
21
23
|
type Getter,
|
|
@@ -113,12 +115,25 @@ export function useNativeCss(
|
|
|
113
115
|
return initialState;
|
|
114
116
|
});
|
|
115
117
|
|
|
118
|
+
// Distinguishes a fresh mount from an effect replay (Activity, StrictMode)
|
|
119
|
+
const hasCommittedRef = useRef(false);
|
|
120
|
+
|
|
116
121
|
useEffect(() => {
|
|
117
122
|
// Reconnect subscriptions after React replays an effect setup.
|
|
118
123
|
if (state.ruleEffect.observers.size === 0) {
|
|
119
|
-
state.ruleEffect
|
|
120
|
-
|
|
124
|
+
if (hasCommittedRef.current || hasChangedDependencies(state.ruleEffect)) {
|
|
125
|
+
// Replay, or conditions changed since the initializer: recalculate.
|
|
126
|
+
state.ruleEffect.run();
|
|
127
|
+
state.styleEffect.run();
|
|
128
|
+
} else {
|
|
129
|
+
// Fresh mount: resubscribe to the initializer's dependencies.
|
|
130
|
+
// styleEffect resubscribes itself during render.
|
|
131
|
+
for (const observable of state.ruleEffect.dependencies ?? []) {
|
|
132
|
+
observable.get(state.ruleEffect);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
121
135
|
}
|
|
136
|
+
hasCommittedRef.current = true;
|
|
122
137
|
return () => {
|
|
123
138
|
cleanupEffect(state.ruleEffect);
|
|
124
139
|
cleanupEffect(state.styleEffect);
|
package/src/native/reactivity.ts
CHANGED
|
@@ -12,6 +12,10 @@ import type { StyleDescriptor } from "react-native-css/compiler";
|
|
|
12
12
|
export type Effect = {
|
|
13
13
|
observers: Set<Observable<any, any>>;
|
|
14
14
|
run(): void;
|
|
15
|
+
/** Dependencies recorded by the last cleanupEffect() */
|
|
16
|
+
dependencies?: Observable<any, any>[];
|
|
17
|
+
/** Dependency values recorded by the last cleanupEffect() */
|
|
18
|
+
snapshots?: [Observable<any, any>, unknown][];
|
|
15
19
|
};
|
|
16
20
|
|
|
17
21
|
export type Observable<Value, Arg = Value> = {
|
|
@@ -130,13 +134,28 @@ export function observable<Value, Arg = Value>(
|
|
|
130
134
|
|
|
131
135
|
export function cleanupEffect(effect: Effect) {
|
|
132
136
|
if (!effect) return;
|
|
133
|
-
const dependencies = Array.from(effect.observers);
|
|
137
|
+
const dependencies = (effect.dependencies = Array.from(effect.observers));
|
|
138
|
+
// Snapshot before detaching so computed observables return cached values
|
|
139
|
+
effect.snapshots = dependencies.map(
|
|
140
|
+
(observable) =>
|
|
141
|
+
[observable, observable.get()] as [Observable<any, any>, unknown],
|
|
142
|
+
);
|
|
134
143
|
effect.observers.clear();
|
|
135
144
|
for (const dep of dependencies) {
|
|
136
145
|
dep.unsubscribe(effect);
|
|
137
146
|
}
|
|
138
147
|
}
|
|
139
148
|
|
|
149
|
+
/** Whether any of the effect's dependencies changed since cleanupEffect() */
|
|
150
|
+
export function hasChangedDependencies(effect: Effect): boolean {
|
|
151
|
+
const snapshots = effect.snapshots;
|
|
152
|
+
if (!snapshots) return false;
|
|
153
|
+
for (const [observable, value] of snapshots) {
|
|
154
|
+
if (!Object.is(observable.get(), value)) return true;
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
|
|
140
159
|
/** Family Helpers ************************************************************/
|
|
141
160
|
|
|
142
161
|
export function family<Key, Result = Key, Args extends any = void>(
|
|
@@ -198,6 +217,21 @@ export type VariableContextValue = Record<string, StyleDescriptor> & {
|
|
|
198
217
|
[VAR_SYMBOL]: true;
|
|
199
218
|
};
|
|
200
219
|
|
|
220
|
+
// Variable lookup is presence-keyed, so an entry with no value produces no key rather than one that stops the cascade
|
|
221
|
+
export function toVariableRecord(
|
|
222
|
+
variables: Record<string, StyleDescriptor>,
|
|
223
|
+
): Record<string, StyleDescriptor> {
|
|
224
|
+
const record: Record<string, StyleDescriptor> = {};
|
|
225
|
+
|
|
226
|
+
for (const [name, value] of Object.entries(variables)) {
|
|
227
|
+
if (value !== undefined) {
|
|
228
|
+
record[name.replace(/^--/, "")] = value;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return record;
|
|
233
|
+
}
|
|
234
|
+
|
|
201
235
|
/** Pseudo Classes ************************************************************/
|
|
202
236
|
|
|
203
237
|
export const hoverFamily = weakFamily(() => observable(false));
|
|
@@ -29,16 +29,43 @@ const rootVariableFamily = () => {
|
|
|
29
29
|
});
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
32
|
+
interface RootVariableRegistries {
|
|
33
|
+
root: ReturnType<typeof rootVariableFamily>;
|
|
34
|
+
universal: ReturnType<typeof rootVariableFamily>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare global {
|
|
38
|
+
var __react_native_css_root_variable_registries:
|
|
39
|
+
| RootVariableRegistries
|
|
40
|
+
| undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Seeded with the registries, so a copy that loads after the stylesheet inject keeps the project's rem
|
|
44
|
+
function createRootVariableRegistries(): RootVariableRegistries {
|
|
45
|
+
const registries: RootVariableRegistries = {
|
|
46
|
+
root: rootVariableFamily(),
|
|
47
|
+
universal: rootVariableFamily(),
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
registries.root("__rn-css-rem").set([[14]]);
|
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
52
|
+
registries.root("__rn-css-color").set([
|
|
53
|
+
[
|
|
54
|
+
Platform.OS === "ios"
|
|
55
|
+
? PlatformColor("label", "labelColor")
|
|
56
|
+
: PlatformColor("?attr/textColorPrimary", "SystemBaseHighColor"),
|
|
57
|
+
],
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
+
] as any);
|
|
60
|
+
|
|
61
|
+
return registries;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// The exports map gives import and require different builds, and Metro resolves each per requesting module
|
|
65
|
+
globalThis.__react_native_css_root_variable_registries ??=
|
|
66
|
+
createRootVariableRegistries();
|
|
67
|
+
|
|
68
|
+
export const rootVariables =
|
|
69
|
+
globalThis.__react_native_css_root_variable_registries.root;
|
|
70
|
+
export const universalVariables =
|
|
71
|
+
globalThis.__react_native_css_root_variable_registries.universal;
|
|
@@ -7,7 +7,11 @@ import {
|
|
|
7
7
|
|
|
8
8
|
import type { StyleDescriptor } from "react-native-css/compiler";
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
toVariableRecord,
|
|
12
|
+
VAR_SYMBOL,
|
|
13
|
+
type VariableContextValue,
|
|
14
|
+
} from "../native/reactivity";
|
|
11
15
|
|
|
12
16
|
globalThis.__react_native_css_variable_context ??=
|
|
13
17
|
createContext<VariableContextValue>({
|
|
@@ -24,9 +28,7 @@ export function VariableContextProvider(
|
|
|
24
28
|
const value: VariableContextValue = useMemo(
|
|
25
29
|
() => ({
|
|
26
30
|
...inheritedVariables,
|
|
27
|
-
...
|
|
28
|
-
Object.entries(props.value).map(([k, v]) => [k.replace(/^--/, ""), v]),
|
|
29
|
-
),
|
|
31
|
+
...toVariableRecord(props.value),
|
|
30
32
|
[VAR_SYMBOL]: true,
|
|
31
33
|
}),
|
|
32
34
|
[inheritedVariables, props.value],
|