react-native-css 3.0.0-nightly.27bd5e2 → 3.0.0-nightly.4af17f5

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.
Files changed (221) hide show
  1. package/dist/commonjs/compiler/atRules.js +6 -2
  2. package/dist/commonjs/compiler/atRules.js.map +1 -1
  3. package/dist/commonjs/compiler/attributes.test.js +1 -1
  4. package/dist/commonjs/compiler/attributes.test.js.map +1 -1
  5. package/dist/commonjs/compiler/compiler.js +57 -18
  6. package/dist/commonjs/compiler/compiler.js.map +1 -1
  7. package/dist/commonjs/compiler/declarations.js +177 -74
  8. package/dist/commonjs/compiler/declarations.js.map +1 -1
  9. package/dist/commonjs/compiler/inheritance.test.js +7 -7
  10. package/dist/commonjs/compiler/inheritance.test.js.map +1 -1
  11. package/dist/commonjs/compiler/selector-builder.js +457 -0
  12. package/dist/commonjs/compiler/selector-builder.js.map +1 -0
  13. package/dist/commonjs/compiler/selectors.js +10 -6
  14. package/dist/commonjs/compiler/selectors.js.map +1 -1
  15. package/dist/commonjs/compiler/stylesheet.js +125 -40
  16. package/dist/commonjs/compiler/stylesheet.js.map +1 -1
  17. package/dist/commonjs/jest/index.js +24 -25
  18. package/dist/commonjs/jest/index.js.map +1 -1
  19. package/dist/commonjs/metro/index.js +7 -5
  20. package/dist/commonjs/metro/index.js.map +1 -1
  21. package/dist/commonjs/poison.pill.js +4 -1
  22. package/dist/commonjs/poison.pill.js.map +1 -1
  23. package/dist/commonjs/runtime/native/conditions/attributes.js +42 -0
  24. package/dist/commonjs/runtime/native/conditions/attributes.js.map +1 -0
  25. package/dist/commonjs/runtime/native/conditions/container-query.js +28 -21
  26. package/dist/commonjs/runtime/native/conditions/container-query.js.map +1 -1
  27. package/dist/commonjs/runtime/native/conditions/guards.js.map +1 -1
  28. package/dist/commonjs/runtime/native/conditions/index.js +10 -46
  29. package/dist/commonjs/runtime/native/conditions/index.js.map +1 -1
  30. package/dist/commonjs/runtime/native/conditions/media-query.js +17 -17
  31. package/dist/commonjs/runtime/native/conditions/media-query.js.map +1 -1
  32. package/dist/commonjs/runtime/native/injection.js +3 -2
  33. package/dist/commonjs/runtime/native/injection.js.map +1 -1
  34. package/dist/commonjs/runtime/native/react/interaction.js +10 -10
  35. package/dist/commonjs/runtime/native/react/interaction.js.map +1 -1
  36. package/dist/commonjs/runtime/native/react/rules.js +9 -9
  37. package/dist/commonjs/runtime/native/react/rules.js.map +1 -1
  38. package/dist/commonjs/runtime/native/react/useNativeCss.js +1 -0
  39. package/dist/commonjs/runtime/native/react/useNativeCss.js.map +1 -1
  40. package/dist/commonjs/runtime/native/reactivity.js +1 -12
  41. package/dist/commonjs/runtime/native/reactivity.js.map +1 -1
  42. package/dist/commonjs/runtime/native/root.js +28 -0
  43. package/dist/commonjs/runtime/native/root.js.map +1 -0
  44. package/dist/commonjs/runtime/native/styles/calculate-props.js +53 -48
  45. package/dist/commonjs/runtime/native/styles/calculate-props.js.map +1 -1
  46. package/dist/commonjs/runtime/native/styles/index.js +12 -12
  47. package/dist/commonjs/runtime/native/styles/index.js.map +1 -1
  48. package/dist/commonjs/runtime/native/styles/units.js +6 -3
  49. package/dist/commonjs/runtime/native/styles/units.js.map +1 -1
  50. package/dist/commonjs/runtime/native/styles/variables.js +3 -2
  51. package/dist/commonjs/runtime/native/styles/variables.js.map +1 -1
  52. package/dist/commonjs/runtime/utils/specificity.js +2 -1
  53. package/dist/commonjs/runtime/utils/specificity.js.map +1 -1
  54. package/dist/module/compiler/atRules.js +6 -2
  55. package/dist/module/compiler/atRules.js.map +1 -1
  56. package/dist/module/compiler/attributes.test.js +1 -1
  57. package/dist/module/compiler/attributes.test.js.map +1 -1
  58. package/dist/module/compiler/compiler.js +57 -18
  59. package/dist/module/compiler/compiler.js.map +1 -1
  60. package/dist/module/compiler/compiler.types.js.map +1 -1
  61. package/dist/module/compiler/declarations.js +172 -70
  62. package/dist/module/compiler/declarations.js.map +1 -1
  63. package/dist/module/compiler/inheritance.test.js +7 -7
  64. package/dist/module/compiler/inheritance.test.js.map +1 -1
  65. package/dist/module/compiler/selector-builder.js +452 -0
  66. package/dist/module/compiler/selector-builder.js.map +1 -0
  67. package/dist/module/compiler/selectors.js +10 -6
  68. package/dist/module/compiler/selectors.js.map +1 -1
  69. package/dist/module/compiler/stylesheet.js +124 -39
  70. package/dist/module/compiler/stylesheet.js.map +1 -1
  71. package/dist/module/jest/index.js +25 -10
  72. package/dist/module/jest/index.js.map +1 -1
  73. package/dist/module/metro/index.js +7 -5
  74. package/dist/module/metro/index.js.map +1 -1
  75. package/dist/module/poison.pill.js +4 -1
  76. package/dist/module/poison.pill.js.map +1 -1
  77. package/dist/module/runtime/native/conditions/attributes.js +38 -0
  78. package/dist/module/runtime/native/conditions/attributes.js.map +1 -0
  79. package/dist/module/runtime/native/conditions/container-query.js +28 -21
  80. package/dist/module/runtime/native/conditions/container-query.js.map +1 -1
  81. package/dist/module/runtime/native/conditions/guards.js.map +1 -1
  82. package/dist/module/runtime/native/conditions/index.js +10 -46
  83. package/dist/module/runtime/native/conditions/index.js.map +1 -1
  84. package/dist/module/runtime/native/conditions/media-query.js +17 -17
  85. package/dist/module/runtime/native/conditions/media-query.js.map +1 -1
  86. package/dist/module/runtime/native/injection.js +2 -1
  87. package/dist/module/runtime/native/injection.js.map +1 -1
  88. package/dist/module/runtime/native/react/interaction.js +10 -10
  89. package/dist/module/runtime/native/react/interaction.js.map +1 -1
  90. package/dist/module/runtime/native/react/rules.js +9 -9
  91. package/dist/module/runtime/native/react/rules.js.map +1 -1
  92. package/dist/module/runtime/native/react/useNativeCss.js +1 -0
  93. package/dist/module/runtime/native/react/useNativeCss.js.map +1 -1
  94. package/dist/module/runtime/native/reactivity.js +0 -11
  95. package/dist/module/runtime/native/reactivity.js.map +1 -1
  96. package/dist/module/runtime/native/root.js +24 -0
  97. package/dist/module/runtime/native/root.js.map +1 -0
  98. package/dist/module/runtime/native/styles/calculate-props.js +53 -48
  99. package/dist/module/runtime/native/styles/calculate-props.js.map +1 -1
  100. package/dist/module/runtime/native/styles/index.js +12 -12
  101. package/dist/module/runtime/native/styles/index.js.map +1 -1
  102. package/dist/module/runtime/native/styles/units.js +6 -3
  103. package/dist/module/runtime/native/styles/units.js.map +1 -1
  104. package/dist/module/runtime/native/styles/variables.js +2 -1
  105. package/dist/module/runtime/native/styles/variables.js.map +1 -1
  106. package/dist/module/runtime/utils/specificity.js +2 -1
  107. package/dist/module/runtime/utils/specificity.js.map +1 -1
  108. package/dist/typescript/commonjs/example/app.config.d.ts +4 -0
  109. package/dist/typescript/commonjs/example/app.config.d.ts.map +1 -0
  110. package/dist/typescript/commonjs/src/compiler/compiler.d.ts +9 -2
  111. package/dist/typescript/commonjs/src/compiler/compiler.d.ts.map +1 -1
  112. package/dist/typescript/commonjs/src/compiler/compiler.types.d.ts +5 -4
  113. package/dist/typescript/commonjs/src/compiler/compiler.types.d.ts.map +1 -1
  114. package/dist/typescript/commonjs/src/compiler/declarations.d.ts +16 -19
  115. package/dist/typescript/commonjs/src/compiler/declarations.d.ts.map +1 -1
  116. package/dist/typescript/commonjs/src/compiler/selector-builder.d.ts +23 -0
  117. package/dist/typescript/commonjs/src/compiler/selector-builder.d.ts.map +1 -0
  118. package/dist/typescript/commonjs/src/compiler/selectors.d.ts +3 -2
  119. package/dist/typescript/commonjs/src/compiler/selectors.d.ts.map +1 -1
  120. package/dist/typescript/commonjs/src/compiler/stylesheet.d.ts +23 -5
  121. package/dist/typescript/commonjs/src/compiler/stylesheet.d.ts.map +1 -1
  122. package/dist/typescript/commonjs/src/jest/index.d.ts +11 -5
  123. package/dist/typescript/commonjs/src/jest/index.d.ts.map +1 -1
  124. package/dist/typescript/commonjs/src/metro/index.d.ts.map +1 -1
  125. package/dist/typescript/commonjs/src/poison.pill.d.ts.map +1 -1
  126. package/dist/typescript/commonjs/src/runtime/native/conditions/attributes.d.ts +5 -0
  127. package/dist/typescript/commonjs/src/runtime/native/conditions/attributes.d.ts.map +1 -0
  128. package/dist/typescript/commonjs/src/runtime/native/conditions/container-query.d.ts +3 -3
  129. package/dist/typescript/commonjs/src/runtime/native/conditions/container-query.d.ts.map +1 -1
  130. package/dist/typescript/commonjs/src/runtime/native/conditions/guards.d.ts +2 -2
  131. package/dist/typescript/commonjs/src/runtime/native/conditions/guards.d.ts.map +1 -1
  132. package/dist/typescript/commonjs/src/runtime/native/conditions/index.d.ts +2 -2
  133. package/dist/typescript/commonjs/src/runtime/native/conditions/index.d.ts.map +1 -1
  134. package/dist/typescript/commonjs/src/runtime/native/conditions/media-query.d.ts +2 -2
  135. package/dist/typescript/commonjs/src/runtime/native/conditions/media-query.d.ts.map +1 -1
  136. package/dist/typescript/commonjs/src/runtime/native/injection.d.ts.map +1 -1
  137. package/dist/typescript/commonjs/src/runtime/native/react/interaction.d.ts +2 -2
  138. package/dist/typescript/commonjs/src/runtime/native/react/interaction.d.ts.map +1 -1
  139. package/dist/typescript/commonjs/src/runtime/native/react/useNativeCss.d.ts +2 -1
  140. package/dist/typescript/commonjs/src/runtime/native/react/useNativeCss.d.ts.map +1 -1
  141. package/dist/typescript/commonjs/src/runtime/native/reactivity.d.ts +2 -10
  142. package/dist/typescript/commonjs/src/runtime/native/reactivity.d.ts.map +1 -1
  143. package/dist/typescript/commonjs/src/runtime/native/root.d.ts +11 -0
  144. package/dist/typescript/commonjs/src/runtime/native/root.d.ts.map +1 -0
  145. package/dist/typescript/commonjs/src/runtime/native/styles/calculate-props.d.ts.map +1 -1
  146. package/dist/typescript/commonjs/src/runtime/native/styles/units.d.ts.map +1 -1
  147. package/dist/typescript/commonjs/src/runtime/native/styles/variables.d.ts.map +1 -1
  148. package/dist/typescript/commonjs/src/runtime/utils/specificity.d.ts +1 -0
  149. package/dist/typescript/commonjs/src/runtime/utils/specificity.d.ts.map +1 -1
  150. package/dist/typescript/module/example/app.config.d.ts +4 -0
  151. package/dist/typescript/module/example/app.config.d.ts.map +1 -0
  152. package/dist/typescript/module/src/compiler/compiler.d.ts +9 -2
  153. package/dist/typescript/module/src/compiler/compiler.d.ts.map +1 -1
  154. package/dist/typescript/module/src/compiler/compiler.types.d.ts +5 -4
  155. package/dist/typescript/module/src/compiler/compiler.types.d.ts.map +1 -1
  156. package/dist/typescript/module/src/compiler/declarations.d.ts +16 -19
  157. package/dist/typescript/module/src/compiler/declarations.d.ts.map +1 -1
  158. package/dist/typescript/module/src/compiler/selector-builder.d.ts +23 -0
  159. package/dist/typescript/module/src/compiler/selector-builder.d.ts.map +1 -0
  160. package/dist/typescript/module/src/compiler/selectors.d.ts +3 -2
  161. package/dist/typescript/module/src/compiler/selectors.d.ts.map +1 -1
  162. package/dist/typescript/module/src/compiler/stylesheet.d.ts +23 -5
  163. package/dist/typescript/module/src/compiler/stylesheet.d.ts.map +1 -1
  164. package/dist/typescript/module/src/jest/index.d.ts +11 -5
  165. package/dist/typescript/module/src/jest/index.d.ts.map +1 -1
  166. package/dist/typescript/module/src/metro/index.d.ts.map +1 -1
  167. package/dist/typescript/module/src/poison.pill.d.ts.map +1 -1
  168. package/dist/typescript/module/src/runtime/native/conditions/attributes.d.ts +5 -0
  169. package/dist/typescript/module/src/runtime/native/conditions/attributes.d.ts.map +1 -0
  170. package/dist/typescript/module/src/runtime/native/conditions/container-query.d.ts +3 -3
  171. package/dist/typescript/module/src/runtime/native/conditions/container-query.d.ts.map +1 -1
  172. package/dist/typescript/module/src/runtime/native/conditions/guards.d.ts +2 -2
  173. package/dist/typescript/module/src/runtime/native/conditions/guards.d.ts.map +1 -1
  174. package/dist/typescript/module/src/runtime/native/conditions/index.d.ts +2 -2
  175. package/dist/typescript/module/src/runtime/native/conditions/index.d.ts.map +1 -1
  176. package/dist/typescript/module/src/runtime/native/conditions/media-query.d.ts +2 -2
  177. package/dist/typescript/module/src/runtime/native/conditions/media-query.d.ts.map +1 -1
  178. package/dist/typescript/module/src/runtime/native/injection.d.ts.map +1 -1
  179. package/dist/typescript/module/src/runtime/native/react/interaction.d.ts +2 -2
  180. package/dist/typescript/module/src/runtime/native/react/interaction.d.ts.map +1 -1
  181. package/dist/typescript/module/src/runtime/native/react/useNativeCss.d.ts +2 -1
  182. package/dist/typescript/module/src/runtime/native/react/useNativeCss.d.ts.map +1 -1
  183. package/dist/typescript/module/src/runtime/native/reactivity.d.ts +2 -10
  184. package/dist/typescript/module/src/runtime/native/reactivity.d.ts.map +1 -1
  185. package/dist/typescript/module/src/runtime/native/root.d.ts +11 -0
  186. package/dist/typescript/module/src/runtime/native/root.d.ts.map +1 -0
  187. package/dist/typescript/module/src/runtime/native/styles/calculate-props.d.ts.map +1 -1
  188. package/dist/typescript/module/src/runtime/native/styles/units.d.ts.map +1 -1
  189. package/dist/typescript/module/src/runtime/native/styles/variables.d.ts.map +1 -1
  190. package/dist/typescript/module/src/runtime/utils/specificity.d.ts +1 -0
  191. package/dist/typescript/module/src/runtime/utils/specificity.d.ts.map +1 -1
  192. package/package.json +28 -4
  193. package/src/compiler/atRules.ts +7 -2
  194. package/src/compiler/attributes.test.ts +1 -1
  195. package/src/compiler/compiler.ts +63 -33
  196. package/src/compiler/compiler.types.ts +7 -5
  197. package/src/compiler/declarations.ts +300 -69
  198. package/src/compiler/inheritance.test.ts +6 -6
  199. package/src/compiler/selector-builder.ts +531 -0
  200. package/src/compiler/selectors.ts +20 -6
  201. package/src/compiler/stylesheet.ts +168 -38
  202. package/src/jest/index.ts +34 -11
  203. package/src/metro/index.ts +12 -6
  204. package/src/poison.pill.ts +5 -1
  205. package/src/runtime/native/conditions/attributes.ts +52 -0
  206. package/src/runtime/native/conditions/container-query.ts +27 -22
  207. package/src/runtime/native/conditions/guards.ts +1 -2
  208. package/src/runtime/native/conditions/index.ts +12 -66
  209. package/src/runtime/native/conditions/media-query.ts +18 -20
  210. package/src/runtime/native/injection.ts +1 -1
  211. package/src/runtime/native/react/interaction.ts +12 -12
  212. package/src/runtime/native/react/rules.ts +9 -9
  213. package/src/runtime/native/react/useNativeCss.ts +3 -0
  214. package/src/runtime/native/reactivity.ts +2 -21
  215. package/src/runtime/native/root.ts +31 -0
  216. package/src/runtime/native/styles/calculate-props.ts +59 -49
  217. package/src/runtime/native/styles/index.ts +12 -12
  218. package/src/runtime/native/styles/units.ts +7 -3
  219. package/src/runtime/native/styles/variables.ts +2 -6
  220. package/src/runtime/utils/specificity.ts +1 -0
  221. package/types.d.ts +70 -0
@@ -1,3 +1,5 @@
1
+ import type { SelectorList } from "lightningcss";
2
+
1
3
  import {
2
4
  isStyleDescriptorArray,
3
5
  Specificity,
@@ -17,8 +19,9 @@ import type {
17
19
  StyleRuleMapping,
18
20
  StyleRuleSet,
19
21
  VariableRecord,
22
+ VariableValue,
20
23
  } from "./compiler.types";
21
- import { toRNProperty, type NormalizeSelector } from "./selectors";
24
+ import { getClassNameSelectors, toRNProperty } from "./selector-builder";
22
25
 
23
26
  type BuilderMode = "style" | "media" | "container" | "keyframes";
24
27
 
@@ -56,22 +59,49 @@ export class StylesheetBuilder {
56
59
  animations?: AnimationRecord;
57
60
  rem: number;
58
61
  ruleOrder: number;
59
- } = { ruleSets: {}, rem: 14, ruleOrder: 0 },
62
+ warningProperty?: string;
63
+ warningProperties: string[];
64
+ warningValues: Record<string, unknown[]>;
65
+ warningFunctions: string[];
66
+ } = {
67
+ ruleSets: {},
68
+ rem: 14,
69
+ ruleOrder: 0,
70
+ warningProperties: [],
71
+ warningValues: {},
72
+ warningFunctions: [],
73
+ },
74
+ private selectors: SelectorList = [],
60
75
  ) {}
61
76
 
62
- fork(mode = this.mode, rule?: Partial<StyleRule>): StylesheetBuilder {
77
+ fork(mode = this.mode, selectors: SelectorList = []): StylesheetBuilder {
63
78
  this.shared.ruleOrder++;
79
+
80
+ /**
81
+ * If we already have selectors and we are added more
82
+ * Then these must be nested selectors.
83
+ *
84
+ * We need to extrapolate out the selectors to their full values
85
+ */
86
+ selectors =
87
+ this.selectors.length && selectors.length
88
+ ? this.selectors.flatMap((selectorA) => {
89
+ return selectors.map((selectorB) => [...selectorA, ...selectorB]);
90
+ })
91
+ : [...this.selectors, ...selectors];
92
+
64
93
  return new StylesheetBuilder(
65
94
  this.options,
66
95
  mode,
67
- this.cloneRule(rule ? { ...this.rule, ...rule } : undefined),
96
+ this.cloneRule(),
68
97
  { ...this.mapping },
69
98
  this.descriptorProperty,
70
99
  this.shared,
100
+ selectors,
71
101
  );
72
102
  }
73
103
 
74
- cloneRule({ ...rule } = this.rule): StyleRule {
104
+ cloneRule({ ...rule } = this.ruleTemplate): StyleRule {
75
105
  rule.s = [...rule.s];
76
106
  rule.aq &&= [...rule.aq];
77
107
  rule.c &&= [...rule.c];
@@ -123,11 +153,17 @@ export class StylesheetBuilder {
123
153
  }
124
154
 
125
155
  if (this.shared.rootVariables) {
126
- stylesheetOptions.vr = Object.entries(this.shared.rootVariables);
156
+ stylesheetOptions.vr = Object.entries(this.shared.rootVariables).map(
157
+ // Reverse these so the most specific variables are first
158
+ ([key, value]) => [key, value.reverse()] as const,
159
+ );
127
160
  }
128
161
 
129
162
  if (this.shared.universalVariables) {
130
- stylesheetOptions.vu = Object.entries(this.shared.universalVariables);
163
+ stylesheetOptions.vu = Object.entries(this.shared.universalVariables).map(
164
+ // Reverse these so the most specific variables are first
165
+ ([key, value]) => [key, value.reverse()] as const,
166
+ );
131
167
  }
132
168
 
133
169
  if (this.shared.animations) {
@@ -150,11 +186,64 @@ export class StylesheetBuilder {
150
186
  );
151
187
  }
152
188
 
189
+ setWarningProperty(property: string) {
190
+ this.shared.warningProperty = property;
191
+ }
192
+
193
+ addWarning(type: "property" | "value", property: string): void;
194
+ addWarning(type: "style", property: string, value: unknown): void;
153
195
  addWarning(
154
- _type: "property" | "value" | "function",
155
- _property: string | number,
196
+ type: "property" | "style" | "value",
197
+ property: string,
198
+ value?: unknown,
156
199
  ): void {
157
- // TODO
200
+ switch (type) {
201
+ case "property":
202
+ this.shared.warningProperties.push(property);
203
+ break;
204
+ case "value": {
205
+ value = property;
206
+ property = this.shared.warningProperty ?? "";
207
+
208
+ if (!property) {
209
+ return;
210
+ }
211
+
212
+ this.shared.warningValues[property] ??= [];
213
+ this.shared.warningValues[property]?.push(value);
214
+ break;
215
+ }
216
+ case "style":
217
+ this.shared.warningValues[property] ??= [];
218
+ this.shared.warningValues[property]?.push(value);
219
+ break;
220
+ }
221
+ }
222
+
223
+ getWarnings() {
224
+ const result: {
225
+ properties?: string[];
226
+ values?: Record<string, unknown[]>;
227
+ functions?: string[];
228
+ } = {};
229
+
230
+ if (this.shared.warningProperties.length) {
231
+ result.properties = this.shared.warningProperties;
232
+ }
233
+
234
+ if (Object.keys(this.shared.warningValues).length) {
235
+ result.values = this.shared.warningValues;
236
+ }
237
+
238
+ if (this.shared.warningFunctions.length) {
239
+ result.functions = this.shared.warningFunctions;
240
+ }
241
+
242
+ return result;
243
+ }
244
+
245
+ addMapping(mapping: StyleRuleMapping) {
246
+ this.mapping = { ...this.mapping, ...mapping };
158
247
  }
159
248
 
160
249
  newRule(mapping = this.mapping, { important = false } = {}) {
@@ -166,6 +255,12 @@ export class StylesheetBuilder {
166
255
  }
167
256
  }
168
257
 
258
+ /** Used by nested declarations (for example @media inside a RuleSet) */
259
+ newNestedRule({ important = false } = {}) {
260
+ this.newRule(this.mapping, { important });
261
+ }
262
+
263
+ /** Hack for light-dark, which requires adding a new rule without changing the current rule */
169
264
  addExtraRule(rule: Partial<StyleRule>) {
170
265
  let extraRuleArray = extraRules.get(this.rule);
171
266
  if (!extraRuleArray) {
@@ -184,8 +279,8 @@ export class StylesheetBuilder {
184
279
  }
185
280
 
186
281
  addMediaQuery(condition: MediaCondition) {
187
- this.rule.m ??= [];
188
- this.rule.m.push(condition);
282
+ this.ruleTemplate.m ??= [];
283
+ this.ruleTemplate.m.push(condition);
189
284
  }
190
285
 
191
286
  addContainer(value: string[] | false) {
@@ -284,30 +379,29 @@ export class StylesheetBuilder {
284
379
  }
285
380
 
286
381
  private pushDescriptor(
287
- property: string,
382
+ rawProperty: string,
288
383
  value: StyleDescriptor,
289
384
  declarations: StyleDeclaration[],
290
385
  forceTuple = false,
291
386
  delayed = false,
292
387
  ) {
293
- property = toRNProperty(property);
388
+ const property = toRNProperty(rawProperty);
294
389
 
295
- let propPath: string | string[] =
296
- this.mapping[property] ?? this.mapping["*"] ?? property;
390
+ let propPath: string | string[] | undefined =
391
+ this.mapping[rawProperty] ?? this.mapping[property] ?? this.mapping["*"];
297
392
 
298
393
  if (Array.isArray(propPath)) {
299
- const first = propPath[0];
300
-
301
- if (!first) {
302
- // This should not happen, but if it does, we skip the property
303
- return;
304
- }
394
+ const [first, second] = propPath;
305
395
 
306
- if (propPath.length === 1) {
307
- propPath = first;
396
+ if (propPath.length === 2 && first === "*" && second) {
397
+ propPath = second;
308
398
  } else {
309
399
  forceTuple = true;
310
400
  }
401
+ } else if (propPath) {
402
+ forceTuple = true;
403
+ } else {
404
+ propPath = property;
311
405
  }
312
406
 
313
407
  if (isStyleFunction(value)) {
@@ -317,7 +411,10 @@ export class StylesheetBuilder {
317
411
  declarations.push([value, propPath]);
318
412
  }
319
413
  } else if (forceTuple || Array.isArray(propPath)) {
320
- declarations.push([value, propPath]);
414
+ declarations.push([
415
+ value,
416
+ Array.isArray(propPath) ? propPath : [propPath],
417
+ ]);
321
418
  } else if (Array.isArray(value) && value.some(isStyleFunction)) {
322
419
  declarations.push([value, propPath]);
323
420
  } else {
@@ -331,13 +428,24 @@ export class StylesheetBuilder {
331
428
  }
332
429
  }
333
430
 
334
- applyRuleToSelectors(selectorList: NormalizeSelector[]): void {
335
- if (!this.rule.d && !this.rule.v) {
431
+ applyRuleToSelectors(selectorList = this.selectors): void {
432
+ if (!selectorList.length) {
433
+ // If there are no selectors, we cannot apply the rule
434
+ return;
435
+ }
436
+
437
+ if (!this.rule.d && !this.rule.v && !this.rule.c) {
336
438
  return;
337
439
  }
338
440
 
339
- for (const selector of selectorList) {
340
- const rule = this.cloneRule();
441
+ const normalizedSelectors = getClassNameSelectors(
442
+ selectorList,
443
+ this.options,
444
+ );
445
+
446
+ for (const selector of normalizedSelectors) {
447
+ // We are going to be apply the current rule to n selectors, so we clone the rule
448
+ const rule = this.cloneRule(this.rule);
341
449
 
342
450
  if (selector.type === "className") {
343
451
  const {
@@ -349,6 +457,10 @@ export class StylesheetBuilder {
349
457
  attributeQuery,
350
458
  } = selector;
351
459
 
460
+ if (!className) {
461
+ continue; // No className, nothing to do
462
+ }
463
+
352
464
  // Combine the specificity of the selector with the rule's specificity
353
465
  for (let i = 0; i < specificity.length; i++) {
354
466
  const spec = specificity[i];
@@ -372,14 +484,29 @@ export class StylesheetBuilder {
372
484
  continue;
373
485
  }
374
486
 
487
+ const [first, ...rest] = name.split(".");
488
+
489
+ if (typeof first !== "string") {
490
+ continue;
491
+ }
492
+
375
493
  const containerRule: StyleRule = {
376
494
  // These are not "real" rules, so they use the lowest specificity
377
495
  s: [0],
378
496
  c: [name],
379
497
  };
380
498
 
499
+ if (rest.length) {
500
+ containerRule.aq = rest.map((attr) => [
501
+ "a",
502
+ "className",
503
+ "*=",
504
+ attr,
505
+ ]);
506
+ }
507
+
381
508
  // Create rules for the parent classes
382
- this.addRuleToRuleSet(name, containerRule);
509
+ this.addRuleToRuleSet(first, containerRule);
383
510
  }
384
511
  }
385
512
 
@@ -408,21 +535,24 @@ export class StylesheetBuilder {
408
535
  if (!this.rule.v) {
409
536
  continue;
410
537
  }
411
-
412
- const { type, subtype } = selector;
413
-
538
+ const { type } = selector;
414
539
  for (const [name, value] of this.rule.v) {
415
540
  this.shared[type] ??= {};
416
- this.shared[type][name] ??= [undefined];
417
- this.shared[type][name][subtype === "light" ? 0 : 1] = value;
541
+ this.shared[type][name] ??= [];
542
+ const mediaQueries = this.rule.m;
543
+ const variableValue: VariableValue = mediaQueries
544
+ ? [value, [...mediaQueries]]
545
+ : [value];
546
+ // Append extra media queries if they exist
547
+ this.shared[type][name].push(variableValue);
418
548
  }
419
549
  }
420
550
  }
421
551
  }
422
552
 
423
553
  addContainerQuery(query: ContainerQuery) {
424
- this.rule.cq ??= [];
425
- this.rule.cq.push(query);
554
+ this.ruleTemplate.cq ??= [];
555
+ this.ruleTemplate.cq.push(query);
426
556
  }
427
557
 
428
558
  newAnimationFrames(name: string) {
@@ -484,7 +614,7 @@ function postProcessStyleFunction(value: StyleDescriptor): [
484
614
  let [shouldDelay, usesVariables] = postProcessStyleFunction(value[2]);
485
615
 
486
616
  usesVariables ||= value[1] === "var";
487
- shouldDelay ||= value[3] === 1;
617
+ shouldDelay ||= value[3] === 1 || usesVariables;
488
618
 
489
619
  if (shouldDelay) {
490
620
  return [true, usesVariables];
package/src/jest/index.ts CHANGED
@@ -1,42 +1,65 @@
1
- /* eslint-disable @typescript-eslint/no-namespace */
2
- import { Dimensions } from "react-native";
1
+ import { Appearance, Dimensions } from "react-native";
2
+
3
+ import { inspect } from "node:util";
3
4
 
4
5
  import { compile, type CompilerOptions } from "../compiler";
5
6
  import { StyleCollection } from "../runtime/native/injection";
6
7
  import { colorScheme, dimensions, rem } from "../runtime/native/reactivity";
7
8
 
8
9
  declare global {
10
+ /* eslint-disable @typescript-eslint/no-namespace */
9
11
  namespace jest {
10
12
  interface Matchers<R> {
11
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
- toHaveAnimatedStyle(style?: any): R;
13
+ toHaveAnimatedStyle(style?: unknown): R;
13
14
  }
14
15
  }
15
16
  }
16
17
 
17
- export * from "@testing-library/react-native";
18
18
  export const testID = "react-native-css";
19
19
 
20
20
  beforeEach(() => {
21
21
  StyleCollection.styles.clear();
22
22
  dimensions.set(Dimensions.get("window"));
23
23
  rem.set(14);
24
+ Appearance.setColorScheme(null);
24
25
  colorScheme.set(null);
25
26
  });
26
27
 
28
+ const debugDefault = Boolean(
29
+ process.env.REACT_NATIVE_CSS_TEST_DEBUG &&
30
+ process.env.NODE_OPTIONS?.includes("--inspect"),
31
+ );
32
+
27
33
  export function registerCSS(
28
34
  css: string,
29
35
  {
30
- debugCompiled = process.env.NODE_OPTIONS?.includes("--inspect"),
36
+ debug = debugDefault,
31
37
  ...options
32
- }: CompilerOptions & { debugCompiled?: boolean } = {},
38
+ }: CompilerOptions & { debug?: boolean } = {},
33
39
  ) {
34
- const compiled = compile(css, options);
35
- if (debugCompiled) {
36
- console.log(`Compiled styles:\n\n${JSON.stringify({ compiled }, null, 2)}`);
40
+ const logger = debug
41
+ ? (text: string) => {
42
+ // Just log the rules
43
+ if (text.startsWith("[")) {
44
+ console.log(`Rules:\n---\n${text}`);
45
+ }
46
+ }
47
+ : undefined;
48
+
49
+ const compiled = compile(css, { ...options, logger });
50
+ if (debug) {
51
+ console.log(
52
+ `Compiled:\n---\n${inspect(
53
+ {
54
+ stylesheet: compiled.stylesheet(),
55
+ warnings: compiled.warnings(),
56
+ },
57
+ { depth: null, colors: true, compact: false },
58
+ )}`,
59
+ );
37
60
  }
38
61
 
39
- StyleCollection.inject(compiled);
62
+ StyleCollection.inject(compiled.stylesheet());
40
63
 
41
64
  return compiled;
42
65
  }
@@ -6,7 +6,7 @@ import connect from "connect";
6
6
  import debug from "debug";
7
7
  import type { MetroConfig } from "metro-config";
8
8
 
9
- import type { CompilerOptions } from "../compiler";
9
+ import type { CompilerOptions, ReactNativeCssStyleSheet_V2 } from "../compiler";
10
10
  import { compile } from "../compiler/compiler";
11
11
  import { getNativeInjectionCode, getWebInjectionCode } from "./injection-code";
12
12
  import { nativeResolver, webResolver } from "./resolver";
@@ -41,8 +41,11 @@ export function withReactNativeCSS<
41
41
  disableTypeScriptGeneration,
42
42
  typescriptEnvPath,
43
43
  globalClassNamePolyfill = false,
44
+ logger = defaultLogger,
44
45
  } = options || {};
45
46
 
47
+ const loggerEnabled = "enabled" in logger ? logger.enabled : true;
48
+
46
49
  if (disableTypeScriptGeneration !== true) {
47
50
  setupTypeScript(typescriptEnvPath);
48
51
  }
@@ -90,7 +93,10 @@ export function withReactNativeCSS<
90
93
  if (!bundler.__react_native_css__patched) {
91
94
  bundler.__react_native_css__patched = true;
92
95
 
93
- const nativeCSSFiles = new Map();
96
+ const nativeCSSFiles = new Map<
97
+ string,
98
+ [string, ReactNativeCssStyleSheet_V2]
99
+ >();
94
100
  const webCSSFiles = new Set<string>();
95
101
 
96
102
  const nativeInjectionPath = require.resolve(
@@ -171,7 +177,7 @@ export function withReactNativeCSS<
171
177
  next,
172
178
  compile(next, {
173
179
  hexColors: options?.hexColors,
174
- }),
180
+ }).stylesheet(),
175
181
  ]);
176
182
 
177
183
  watcher.emit("change", {
@@ -211,9 +217,9 @@ export function withReactNativeCSS<
211
217
  Array.from(nativeCSSFiles.values()).map(([, value]) => value),
212
218
  );
213
219
 
214
- if (defaultLogger.enabled && fileBuffer) {
215
- defaultLogger(`Transformed ${filePath}`);
216
- defaultLogger(fileBuffer?.toString());
220
+ if (loggerEnabled && fileBuffer) {
221
+ logger(`Transformed ${filePath}`);
222
+ logger(fileBuffer?.toString());
217
223
  }
218
224
  }
219
225
 
@@ -1,4 +1,7 @@
1
- throw new Error(`react-native-css has encountered a setup error.
1
+ const canWarn = process.env.NODE_ENV !== "test";
2
+
3
+ if (canWarn) {
4
+ throw new Error(`react-native-css has encountered a setup error.
2
5
 
3
6
  ┌─────-─┐
4
7
  | Metro |
@@ -28,5 +31,6 @@ If you are using NativeWind with the 'withNativeWind' function, follow the Metro
28
31
 
29
32
  If you are using another bundler (Vite, Webpack, etc), or non-Metro framework (Next.js, Remix, etc), please ensure you have included 'react-native-css/babel' as a babel preset.
30
33
  `);
34
+ }
31
35
 
32
36
  export {};
@@ -0,0 +1,52 @@
1
+ import type { AttributeQuery } from "../../../compiler";
2
+ import type { Props } from "../../runtime.types";
3
+ import type { RenderGuard } from "./guards";
4
+
5
+ export function testAttributes(
6
+ queries: AttributeQuery[],
7
+ props: Props,
8
+ guards: RenderGuard[],
9
+ ) {
10
+ return queries.every((query) => testAttribute(query, props, guards));
11
+ }
12
+
13
+ function testAttribute(
14
+ [type, prop, operator, testValue]: AttributeQuery,
15
+ props: Props,
16
+ guards: RenderGuard[],
17
+ ) {
18
+ let value: unknown;
19
+
20
+ if (type === "a") {
21
+ value = props?.[prop];
22
+ } else {
23
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
24
+ value = props?.dataSet?.[prop];
25
+ }
26
+
27
+ guards.push([type, prop, value]);
28
+
29
+ if (!operator) {
30
+ return value !== undefined && value !== null && value !== false;
31
+ }
32
+
33
+ switch (operator) {
34
+ case "!":
35
+ return !value;
36
+ case "=":
37
+ return value == testValue;
38
+ case "~=":
39
+ return testValue && value?.toString().split(" ").includes(testValue);
40
+ case "|=":
41
+ return testValue && value?.toString().startsWith(testValue + "-");
42
+ case "^=":
43
+ return testValue && value?.toString().startsWith(testValue);
44
+ case "$=":
45
+ return testValue && value?.toString().endsWith(testValue);
46
+ case "*=":
47
+ return testValue && value?.toString().includes(testValue);
48
+ default:
49
+ operator satisfies never;
50
+ return false;
51
+ }
52
+ }
@@ -14,8 +14,9 @@ import {
14
14
  focusFamily,
15
15
  hoverFamily,
16
16
  type ContainerContextValue,
17
- type Effect,
17
+ type Getter,
18
18
  } from "../reactivity";
19
+ // import { testAttributes } from "./attributes";
19
20
  import type { RenderGuard } from "./guards";
20
21
 
21
22
  export const DEFAULT_CONTAINER_NAME = "c:___default___";
@@ -24,10 +25,10 @@ export function testContainerQueries(
24
25
  queries: ContainerQuery[],
25
26
  inheritedContainers: ContainerContextValue,
26
27
  guards: RenderGuard[],
27
- effect: Effect,
28
+ get: Getter,
28
29
  ) {
29
30
  return queries.every((query) => {
30
- return testContainerQuery(query, inheritedContainers, guards, effect);
31
+ return testContainerQuery(query, inheritedContainers, guards, get);
31
32
  });
32
33
  }
33
34
 
@@ -35,7 +36,7 @@ export function testContainerQuery(
35
36
  query: ContainerQuery,
36
37
  inheritedContainers: ContainerContextValue,
37
38
  guards: RenderGuard[],
38
- effect?: Effect,
39
+ get: Getter,
39
40
  ): boolean {
40
41
  const name = query.n ?? DEFAULT_CONTAINER_NAME;
41
42
  const container = inheritedContainers[name]!;
@@ -46,11 +47,15 @@ export function testContainerQuery(
46
47
  return false;
47
48
  }
48
49
 
49
- if (query.m && !testContainerMediaCondition(query.m, container, effect)) {
50
+ // if (query.a && !testAttributes(query.a, container.props, guards)) {
51
+ // return false;
52
+ // }
53
+
54
+ if (query.m && !testContainerMediaCondition(query.m, container, get)) {
50
55
  return false;
51
56
  }
52
57
 
53
- if (query.p && !testContainerPseudoCondition(query.p, container, effect)) {
58
+ if (query.p && !testContainerPseudoCondition(query.p, container, get)) {
54
59
  return false;
55
60
  }
56
61
 
@@ -60,15 +65,15 @@ export function testContainerQuery(
60
65
  function testContainerPseudoCondition(
61
66
  query: PseudoClassesQuery,
62
67
  containerKey: WeakKey,
63
- effect?: Effect,
68
+ get: Getter,
64
69
  ): boolean {
65
- if (query.h && !hoverFamily(containerKey).get(effect)) {
70
+ if (query.h && !get(hoverFamily(containerKey))) {
66
71
  return false;
67
72
  }
68
- if (query.a && !activeFamily(containerKey).get(effect)) {
73
+ if (query.a && !get(activeFamily(containerKey))) {
69
74
  return false;
70
75
  }
71
- if (query.f && !focusFamily(containerKey).get(effect)) {
76
+ if (query.f && !get(focusFamily(containerKey))) {
72
77
  return false;
73
78
  }
74
79
  return true;
@@ -77,18 +82,18 @@ function testContainerPseudoCondition(
77
82
  function testContainerMediaCondition(
78
83
  condition: MediaCondition,
79
84
  containerKey: WeakKey,
80
- effect?: Effect,
85
+ get: Getter,
81
86
  ): boolean {
82
87
  switch (condition[0]) {
83
88
  case "!":
84
- return !testContainerMediaCondition(condition[1], containerKey, effect);
89
+ return !testContainerMediaCondition(condition[1], containerKey, get);
85
90
  case "&":
86
91
  return condition[1].every((query) => {
87
- return testContainerMediaCondition(query, containerKey, effect);
92
+ return testContainerMediaCondition(query, containerKey, get);
88
93
  });
89
94
  case "|":
90
95
  return condition[1].some((query) => {
91
- return testContainerMediaCondition(query, containerKey, effect);
96
+ return testContainerMediaCondition(query, containerKey, get);
92
97
  });
93
98
  case "!!":
94
99
  return false;
@@ -99,7 +104,7 @@ function testContainerMediaCondition(
99
104
  case "<":
100
105
  case "<=":
101
106
  case "=": {
102
- const left = getContainerFeatureValue(condition[1], containerKey, effect);
107
+ const left = getContainerFeatureValue(condition[1], containerKey, get);
103
108
  const right = condition[2];
104
109
 
105
110
  if (condition[0] === "=") {
@@ -133,21 +138,21 @@ function testContainerMediaCondition(
133
138
  function getContainerFeatureValue(
134
139
  name: MediaFeatureNameFor_ContainerSizeFeatureId,
135
140
  containerKey: WeakKey,
136
- effect?: Effect,
141
+ get: Getter,
137
142
  ): StyleDescriptor {
138
143
  switch (name) {
139
144
  case "width":
140
- return containerWidthFamily(containerKey).get(effect);
145
+ return get(containerWidthFamily(containerKey));
141
146
  case "height":
142
- return containerHeightFamily(containerKey).get(effect);
147
+ return get(containerHeightFamily(containerKey));
143
148
  case "aspect-ratio": {
144
- const width = containerWidthFamily(containerKey).get(effect);
145
- const height = containerWidthFamily(containerKey).get(effect);
149
+ const width = get(containerWidthFamily(containerKey));
150
+ const height = get(containerHeightFamily(containerKey));
146
151
  return width / height;
147
152
  }
148
153
  case "orientation":
149
- const width = containerWidthFamily(containerKey).get(effect);
150
- const height = containerWidthFamily(containerKey).get(effect);
154
+ const width = get(containerWidthFamily(containerKey));
155
+ const height = get(containerHeightFamily(containerKey));
151
156
  return width > height ? "landscape" : "portrait";
152
157
  case "inline-size":
153
158
  case "block-size":
@@ -2,7 +2,6 @@
2
2
  import type { ComponentState } from "../react/useNativeCss";
3
3
  import type {
4
4
  ContainerContextValue,
5
- Effect,
6
5
  VariableContextValue,
7
6
  } from "../reactivity";
8
7
 
@@ -10,7 +9,7 @@ export type RenderGuard =
10
9
  | ["a", string, any]
11
10
  | ["d", string, any]
12
11
  | ["v", string, any]
13
- | ["c", string, Effect];
12
+ | ["c", string, WeakKey];
14
13
 
15
14
  export function testGuards(
16
15
  state: ComponentState,