@tamagui/tailwind 3.0.0-beta.924.1 → 3.0.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.
Files changed (56) hide show
  1. package/dist/cjs/candidate.cjs +312 -137
  2. package/dist/cjs/candidate.native.cjs +342 -153
  3. package/dist/cjs/candidate.native.js +342 -153
  4. package/dist/cjs/candidate.native.js.map +1 -1
  5. package/dist/cjs/compose.cjs +383 -0
  6. package/dist/cjs/compose.native.cjs +389 -0
  7. package/dist/cjs/compose.native.js +391 -0
  8. package/dist/cjs/compose.native.js.map +1 -0
  9. package/dist/cjs/composedResolver.cjs +226 -0
  10. package/dist/cjs/composedResolver.native.cjs +255 -0
  11. package/dist/cjs/composedResolver.native.js +257 -0
  12. package/dist/cjs/composedResolver.native.js.map +1 -0
  13. package/dist/cjs/frontend.cjs +4 -11
  14. package/dist/cjs/frontend.native.cjs +5 -16
  15. package/dist/cjs/frontend.native.js +5 -16
  16. package/dist/cjs/frontend.native.js.map +1 -1
  17. package/dist/cjs/index.cjs +2 -0
  18. package/dist/cjs/index.native.cjs +2 -0
  19. package/dist/cjs/index.native.js +2 -0
  20. package/dist/cjs/index.native.js.map +1 -1
  21. package/dist/esm/candidate.mjs +314 -140
  22. package/dist/esm/candidate.mjs.map +1 -1
  23. package/dist/esm/candidate.native.js +344 -156
  24. package/dist/esm/candidate.native.js.map +1 -1
  25. package/dist/esm/compose.mjs +359 -0
  26. package/dist/esm/compose.mjs.map +1 -0
  27. package/dist/esm/compose.native.js +363 -0
  28. package/dist/esm/compose.native.js.map +1 -0
  29. package/dist/esm/composedResolver.mjs +206 -0
  30. package/dist/esm/composedResolver.mjs.map +1 -0
  31. package/dist/esm/composedResolver.native.js +233 -0
  32. package/dist/esm/composedResolver.native.js.map +1 -0
  33. package/dist/esm/frontend.mjs +4 -11
  34. package/dist/esm/frontend.mjs.map +1 -1
  35. package/dist/esm/frontend.native.js +5 -16
  36. package/dist/esm/frontend.native.js.map +1 -1
  37. package/dist/esm/index.mjs +3 -2
  38. package/dist/esm/index.mjs.map +1 -1
  39. package/dist/esm/index.native.js +3 -2
  40. package/dist/esm/index.native.js.map +1 -1
  41. package/package.json +18 -15
  42. package/src/candidate.ts +396 -60
  43. package/src/frontend.ts +3 -16
  44. package/src/index.tsx +14 -2
  45. package/src/types.ts +32 -4
  46. package/types/candidate.d.ts +2 -1
  47. package/types/candidate.d.ts.map +1 -1
  48. package/types/compose.d.ts +19 -0
  49. package/types/compose.d.ts.map +1 -0
  50. package/types/composedResolver.d.ts +19 -0
  51. package/types/composedResolver.d.ts.map +1 -0
  52. package/types/frontend.d.ts.map +1 -1
  53. package/types/index.d.ts +11 -1
  54. package/types/index.d.ts.map +1 -1
  55. package/types/types.d.ts +18 -3
  56. package/types/types.d.ts.map +1 -1
@@ -1,7 +1,10 @@
1
1
  import { isWeb } from "@tamagui/constants";
2
- import { plainValueToPayload } from "@tamagui/core/internal-runtime";
2
+ import { stylePropsUnitless } from "@tamagui/helpers";
3
+ import { mergeFrontendCondition, plainValueToPayload } from "@tamagui/core/internal-runtime";
4
+ import { noteBoxShadow, noteTailwindTransform, tryCompose } from "./compose.mjs";
5
+ import { composedResolver } from "./composedResolver.mjs";
3
6
  import { borderSideSuffix, configRevisionSymbol, createGrammarConfigView, getSafeAreaEdge, getTokenCategory, insetAxisProps, percentUtilityProps, radiusCornerProps, sizeUtilityProps, splitColorOpacitySuffix } from "@tamagui/style-grammar/runtime";
4
- import { classifyCandidate, decodeArbitrary } from "@tamagui/style-grammar/tooling/candidate";
7
+ import { classifyCandidate, decodeArbitrary, hasTokenName, resolveTokenName, tailwindLeadingRatios, tailwindTrackingEms } from "@tamagui/style-grammar/tooling/candidate";
5
8
 
6
9
  const styleGrammarConfigCache = /* @__PURE__ */ new WeakMap();
7
10
  function getStyleGrammarConfig(config) {
@@ -18,44 +21,36 @@ function getStyleGrammarConfig(config) {
18
21
  function isTokenValueProp(prop) {
19
22
  return getTokenCategory(prop) !== null;
20
23
  }
21
- function arbitraryValue(inner) {
24
+ function arbitraryValue(inner, prop) {
22
25
  const px = /^(-?\d*\.?\d+)px$/.exec(inner);
23
- if (px) return Number(px[1]);
26
+ if (px) return prop && stylePropsUnitless[prop] ? inner : Number(px[1]);
24
27
  if (/^-?\d*\.?\d+$/.test(inner)) return Number(inner);
25
28
  return inner;
26
29
  }
30
+ function unwrapArbitraryValue(raw) {
31
+ return arbitraryValue(raw.length > 1 && raw[0] === "[" && raw[raw.length - 1] === "]" ? decodeArbitrary(raw.slice(1, -1)) : raw);
32
+ }
27
33
  function tailwindSizingValue(prop, value) {
28
34
  if (value === "full") return "100%";
29
35
  if (value === "auto") return "auto";
30
- if (value === "screen") return /[Hh]eight/.test(prop) ? "100vh" : "100vw";
36
+ if (value === "screen") return /[Hh]eight|[Bb]lock/.test(prop) ? "100vh" : "100vw";
37
+ if (/^[dls]v[hw]$/.test(value)) return `100${value}`;
31
38
  if (value === "min") return "min-content";
32
39
  if (value === "max") return "max-content";
33
40
  if (value === "fit") return "fit-content";
34
41
  const frac = /^(\d+)\/(\d+)$/.exec(value);
35
- if (frac && Number(frac[2]) !== 0) {
36
- return `${Number(frac[1]) / Number(frac[2]) * 100}%`;
37
- }
42
+ if (frac && Number(frac[2]) !== 0) return `${Number(frac[1]) / Number(frac[2]) * 100}%`;
38
43
  return null;
39
44
  }
40
- function borderDimValue(raw) {
41
- let inner = raw;
42
- if (raw.length > 1 && raw[0] === "[" && raw[raw.length - 1] === "]") {
43
- inner = decodeArbitrary(raw.slice(1, -1));
44
- }
45
- const px = /^(-?\d*\.?\d+)px$/.exec(inner);
46
- if (px) return Number.parseFloat(px[1]);
47
- if (/^-?\d*\.?\d+$/.test(inner)) return Number(inner);
48
- return inner;
49
- }
50
45
  function expansionProps(parsed) {
51
46
  const prefix = parsed.prefix;
52
47
  if (!prefix) return null;
53
48
  if (prefix === "size") return sizeUtilityProps;
54
- if (prefix === "inset-x" || prefix === "inset-y") {
55
- return insetAxisProps[prefix.slice("inset-".length)];
56
- }
49
+ if (prefix === "translate") return ["x", "y"];
50
+ if (prefix === "skew") return ["skewX", "skewY"];
51
+ if (prefix === "inset-x" || prefix === "inset-y") return insetAxisProps[prefix.slice(6)];
57
52
  if (prefix.startsWith("rounded-")) {
58
- const props = radiusCornerProps[prefix.slice("rounded-".length)];
53
+ const props = radiusCornerProps[prefix.slice(8)];
59
54
  if (!props || props.length === 1) return null;
60
55
  return props;
61
56
  }
@@ -65,21 +60,64 @@ function expansionProps(parsed) {
65
60
  const suffix = parsed.entry?.prop.endsWith("Width") ? "Width" : "Color";
66
61
  return sides.map((side) => `border${side}${suffix}`);
67
62
  }
68
- function tailwindClassToFlatProp(parsed) {
69
- if (parsed.kind !== "dynamic" || !parsed.entry || parsed.rawValue === void 0) {
70
- return null;
71
- }
63
+ function tailwindClassToFlatProp(parsed, grammarConfig) {
64
+ if (parsed.kind !== "dynamic" || !parsed.entry || parsed.rawValue === void 0) return null;
72
65
  const prop = parsed.entry.prop;
73
66
  const category = parsed.entry.tokenCategory;
74
67
  let value = parsed.rawValue;
68
+ if (parsed.negative && value === "0" && parsed.convenience !== "angle") return {
69
+ key: prop,
70
+ value: 0
71
+ };
72
+ if (parsed.convenience === "zero") return {
73
+ key: prop,
74
+ value: 0
75
+ };
76
+ if (parsed.convenience === "angle") return {
77
+ key: prop,
78
+ value: `${parsed.negative ? "-" : ""}${value}deg`
79
+ };
80
+ if ((prop === "x" || prop === "y") && parsed.valueKind !== "token") {
81
+ const sized = tailwindSizingValue(prop, value);
82
+ if (sized != null) return {
83
+ key: prop,
84
+ value: parsed.negative && sized[0] !== "-" ? `-${sized}` : sized
85
+ };
86
+ }
87
+ if (parsed.convenience === "leading-keyword") return {
88
+ key: prop,
89
+ value: tailwindLeadingRatios[value]
90
+ };
91
+ if (parsed.convenience === "tracking-keyword") return {
92
+ key: prop,
93
+ value: `${tailwindTrackingEms[value] * (parsed.negative ? -1 : 1)}em`
94
+ };
95
+ if (prop === "lineHeight" && /^\d+(?:\.\d+)?$/.test(value)) return {
96
+ key: prop,
97
+ value: `${Number(value) * 4}px`
98
+ };
99
+ if (prop === "gridTemplateColumns" && /^\d+$/.test(value)) return {
100
+ key: prop,
101
+ value: `repeat(${value}, minmax(0, 1fr))`
102
+ };
103
+ if (prop === "gridColumn" && /^\d+$/.test(value)) return {
104
+ key: prop,
105
+ value: `span ${value} / span ${value}`
106
+ };
107
+ if (prop === "gridRow" && /^\d+$/.test(value)) return {
108
+ key: prop,
109
+ value: `span ${value} / span ${value}`
110
+ };
111
+ if ((prop === "gridColumnStart" || prop === "gridColumnEnd" || prop === "gridRowStart" || prop === "gridRowEnd") && /^\d+$/.test(value)) return {
112
+ key: prop,
113
+ value: Number(value)
114
+ };
75
115
  if (prop.endsWith("Width") && parsed.prefix?.startsWith("border")) {
76
116
  if (parsed.valueKind === "token") {
77
117
  value = `${parsed.negative ? "-" : ""}${value}`;
78
- } else if (parsed.valueKind === "arbitrary") {
79
- value = borderDimValue(value);
80
- } else {
81
- return null;
82
- }
118
+ if (grammarConfig && parsed.entry?.tokenCategory) value = resolveTokenName(grammarConfig, parsed.entry.tokenCategory, value) ?? value;
119
+ } else if (parsed.valueKind === "arbitrary") value = unwrapArbitraryValue(value);
120
+ else return null;
83
121
  return {
84
122
  key: prop,
85
123
  value
@@ -87,16 +125,12 @@ function tailwindClassToFlatProp(parsed) {
87
125
  }
88
126
  if (prop === "fontFamily") {
89
127
  let famValue;
90
- if (value.length > 2 && value[0] === "[" && value[value.length - 1] === "]") {
91
- famValue = decodeArbitrary(value.slice(1, -1));
92
- } else {
93
- const generic = {
94
- sans: "sans-serif",
95
- serif: "serif",
96
- mono: "monospace"
97
- };
98
- famValue = parsed.valueKind === "token" ? value : generic[value] || value;
99
- }
128
+ if (value.length > 2 && value[0] === "[" && value[value.length - 1] === "]") famValue = decodeArbitrary(value.slice(1, -1));
129
+ else famValue = parsed.valueKind === "token" ? value : {
130
+ sans: "sans-serif",
131
+ serif: "serif",
132
+ mono: "monospace"
133
+ }[value] || value;
100
134
  return {
101
135
  key: "fontFamily",
102
136
  value: famValue
@@ -104,11 +138,8 @@ function tailwindClassToFlatProp(parsed) {
104
138
  }
105
139
  if (prop === "fontSize") {
106
140
  let fsValue;
107
- if (value.length > 2 && value[0] === "[" && value[value.length - 1] === "]") {
108
- fsValue = arbitraryValue(decodeArbitrary(value.slice(1, -1)));
109
- } else {
110
- fsValue = value;
111
- }
141
+ if (value.length > 2 && value[0] === "[" && value[value.length - 1] === "]") fsValue = arbitraryValue(decodeArbitrary(value.slice(1, -1)));
142
+ else fsValue = value;
112
143
  return {
113
144
  key: "fontSize",
114
145
  value: fsValue
@@ -116,12 +147,8 @@ function tailwindClassToFlatProp(parsed) {
116
147
  }
117
148
  if (prop === "lineHeight") {
118
149
  let lhValue;
119
- if (value.length > 2 && value[0] === "[" && value[value.length - 1] === "]") {
120
- const inner = decodeArbitrary(value.slice(1, -1));
121
- lhValue = /^-?\d*\.?\d+px$/.test(inner) ? Number.parseFloat(inner) : inner;
122
- } else {
123
- lhValue = value;
124
- }
150
+ if (value.length > 2 && value[0] === "[" && value[value.length - 1] === "]") lhValue = decodeArbitrary(value.slice(1, -1));
151
+ else lhValue = value;
125
152
  return {
126
153
  key: "lineHeight",
127
154
  value: lhValue
@@ -129,71 +156,60 @@ function tailwindClassToFlatProp(parsed) {
129
156
  }
130
157
  if (prop === "letterSpacing") {
131
158
  let lsValue;
132
- if (value.length > 2 && value[0] === "[" && value[value.length - 1] === "]") {
133
- lsValue = arbitraryValue(decodeArbitrary(value.slice(1, -1)));
134
- } else {
135
- lsValue = value;
136
- }
159
+ if (value.length > 2 && value[0] === "[" && value[value.length - 1] === "]") lsValue = arbitraryValue(decodeArbitrary(value.slice(1, -1)));
160
+ else lsValue = value;
137
161
  return {
138
162
  key: "letterSpacing",
139
163
  value: lsValue
140
164
  };
141
165
  }
142
- if (prop === "boxShadow" && value[0] === "[" && value[value.length - 1] === "]") {
143
- return {
144
- key: "boxShadow",
145
- value: decodeArbitrary(value.slice(1, -1))
146
- };
147
- }
166
+ if (prop === "boxShadow" && value[0] === "[" && value[value.length - 1] === "]") return {
167
+ key: "boxShadow",
168
+ value: decodeArbitrary(value.slice(1, -1))
169
+ };
148
170
  if (value.length > 2 && value[0] === "[" && value[value.length - 1] === "]") {
149
171
  const inner = decodeArbitrary(value.slice(1, -1));
150
172
  if (inner === "") return null;
173
+ let resolved = arbitraryValue(inner, prop);
174
+ if ((prop === "rotate" || prop === "rotateX" || prop === "rotateY" || prop === "rotateZ" || prop === "skewX" || prop === "skewY") && typeof resolved === "number") resolved = `${resolved}deg`;
175
+ if (parsed.negative) {
176
+ if (typeof resolved === "number") resolved = -resolved;
177
+ else if (resolved[0] !== "-") resolved = `-${resolved}`;
178
+ }
151
179
  return {
152
180
  key: prop,
153
- value: arbitraryValue(inner)
181
+ value: resolved
154
182
  };
155
183
  }
156
- if (category === "size" && parsed.valueKind !== "token") {
184
+ if (parsed.valueKind !== "token" && (category === "size" || parsed.convenience === "sizing-keyword")) {
157
185
  const sized = tailwindSizingValue(prop, value);
158
- if (sized != null) {
159
- return {
160
- key: prop,
161
- value: sized
162
- };
163
- }
186
+ if (sized != null) return {
187
+ key: prop,
188
+ value: parsed.negative && sized[0] !== "-" ? `-${sized}` : sized
189
+ };
164
190
  }
165
191
  let opacitySuffix = "";
166
192
  if (category === "color" && typeof value === "string") {
167
193
  const suffix = splitColorOpacitySuffix(value);
168
- if (suffix.kind === "invalid") {
169
- return {
170
- key: prop,
171
- value
172
- };
173
- }
194
+ if (suffix.kind === "invalid") return {
195
+ key: prop,
196
+ value
197
+ };
174
198
  if (suffix.kind === "valid") {
175
199
  opacitySuffix = value.slice(suffix.name.length);
176
200
  value = suffix.name;
177
201
  }
178
202
  }
179
- if (percentUtilityProps.has(prop) && /^\d+$/.test(value)) {
180
- value = Number(value) / 100;
181
- } else if (/^\d+(\.\d+)?$/.test(value)) {
182
- if (category === "zIndex" && parsed.valueKind === "convenience") {
183
- value = Number(value);
184
- } else if (category) {
185
- value = `${parsed.negative ? "-" : ""}${value}`;
186
- } else {
187
- value = Number(value);
188
- }
189
- } else if (typeof value === "string") {
190
- if (category && !((category === "space" || category === "size" || category === "radius") && getSafeAreaEdge(value))) {
191
- value = `${parsed.negative ? "-" : ""}${value}`;
192
- }
193
- }
194
- if (opacitySuffix && typeof value === "string") {
195
- value = `${value}${opacitySuffix}`;
203
+ if (percentUtilityProps.has(prop) && /^\d+$/.test(value)) value = Number(value) / 100;
204
+ else if (/^\d+(\.\d+)?$/.test(value)) if (category === "zIndex" && parsed.valueKind === "convenience") value = Number(value) * (parsed.negative ? -1 : 1);
205
+ else if (category) {
206
+ value = `${parsed.negative ? "-" : ""}${value}`;
207
+ if (grammarConfig) value = resolveTokenName(grammarConfig, category, value) ?? value;
208
+ } else value = Number(value);
209
+ else if (typeof value === "string") {
210
+ if (category && !((category === "space" || category === "size" || category === "radius") && getSafeAreaEdge(value))) value = `${parsed.negative ? "-" : ""}${value}`;
196
211
  }
212
+ if (opacitySuffix && typeof value === "string") value = `${value}${opacitySuffix}`;
197
213
  if (parsed.negative && !category) {
198
214
  if (typeof value === "number") value = -value;
199
215
  else if (typeof value === "string" && value[0] !== "-") value = `-${value}`;
@@ -204,6 +220,48 @@ function tailwindClassToFlatProp(parsed) {
204
220
  };
205
221
  }
206
222
  const classPlanCache = /* @__PURE__ */ new WeakMap();
223
+ const nativeTarget = !isWeb || false;
224
+ const cssGridProps = /* @__PURE__ */ new Set([
225
+ "gridTemplateColumns",
226
+ "gridColumn",
227
+ "gridColumnStart",
228
+ "gridColumnEnd",
229
+ "gridRow",
230
+ "gridRowStart",
231
+ "gridRowEnd"
232
+ ]);
233
+ const nativeUnsupportedProps = /* @__PURE__ */ new Set([
234
+ "objectFit",
235
+ "order",
236
+ "overflowX",
237
+ "overflowY",
238
+ "textOverflow",
239
+ "whiteSpace",
240
+ "visibility"
241
+ ]);
242
+ const nativeUnsupportedSizingValues = /* @__PURE__ */ new Set([
243
+ "min",
244
+ "max",
245
+ "fit"
246
+ ]);
247
+ const nativeUnsupportedValues = {
248
+ display: /* @__PURE__ */ new Set([
249
+ "block",
250
+ "inline",
251
+ "inline-flex"
252
+ ]),
253
+ position: /* @__PURE__ */ new Set(["fixed", "sticky"])
254
+ };
255
+ function shouldGateNative(parsed) {
256
+ if (!nativeTarget) return false;
257
+ const properties = parsed.properties || {};
258
+ if (process.env.TAMAGUI_CSS_GRID !== "1" && (parsed.entry && cssGridProps.has(parsed.entry.prop) || properties.display === "grid" || Object.keys(properties).some((prop) => cssGridProps.has(prop)))) return true;
259
+ if (parsed.entry && nativeUnsupportedProps.has(parsed.entry.prop) || Object.keys(properties).some((prop) => nativeUnsupportedProps.has(prop))) return true;
260
+ if (parsed.convenience === "sizing-keyword" && nativeUnsupportedSizingValues.has(parsed.rawValue || "")) return true;
261
+ const entryProp = parsed.entry?.prop;
262
+ if (entryProp && nativeUnsupportedValues[entryProp]?.has(parsed.rawValue || "") || Object.keys(properties).some((prop) => nativeUnsupportedValues[prop]?.has(String(properties[prop])))) return true;
263
+ return properties.overflow === "auto" || properties.cursor !== void 0 && properties.cursor !== "auto" && properties.cursor !== "pointer";
264
+ }
207
265
  function getClassPlanCache(grammarConfig) {
208
266
  let cache = classPlanCache.get(grammarConfig);
209
267
  if (!cache) {
@@ -228,38 +286,123 @@ function createPlanEntry(property, value, modifiers) {
228
286
  modifiers
229
287
  ];
230
288
  }
289
+ const shorthandResets = {
290
+ padding: [
291
+ "paddingTop",
292
+ "paddingRight",
293
+ "paddingBottom",
294
+ "paddingLeft",
295
+ "paddingStart",
296
+ "paddingEnd",
297
+ "paddingInlineStart",
298
+ "paddingInlineEnd",
299
+ "paddingBlockStart",
300
+ "paddingBlockEnd",
301
+ "paddingHorizontal",
302
+ "paddingVertical",
303
+ "paddingInline",
304
+ "paddingBlock"
305
+ ],
306
+ margin: [
307
+ "marginTop",
308
+ "marginRight",
309
+ "marginBottom",
310
+ "marginLeft",
311
+ "marginStart",
312
+ "marginEnd",
313
+ "marginInlineStart",
314
+ "marginInlineEnd",
315
+ "marginBlockStart",
316
+ "marginBlockEnd",
317
+ "marginHorizontal",
318
+ "marginVertical",
319
+ "marginInline",
320
+ "marginBlock"
321
+ ],
322
+ gap: ["rowGap", "columnGap"],
323
+ borderRadius: [
324
+ "borderTopLeftRadius",
325
+ "borderTopRightRadius",
326
+ "borderBottomLeftRadius",
327
+ "borderBottomRightRadius",
328
+ "borderTopStartRadius",
329
+ "borderTopEndRadius",
330
+ "borderBottomStartRadius",
331
+ "borderBottomEndRadius",
332
+ "borderStartStartRadius",
333
+ "borderStartEndRadius",
334
+ "borderEndStartRadius",
335
+ "borderEndEndRadius"
336
+ ],
337
+ borderWidth: [
338
+ "borderTopWidth",
339
+ "borderRightWidth",
340
+ "borderBottomWidth",
341
+ "borderLeftWidth",
342
+ "borderStartWidth",
343
+ "borderEndWidth",
344
+ "borderInlineStartWidth",
345
+ "borderInlineEndWidth",
346
+ "borderBlockStartWidth",
347
+ "borderBlockEndWidth",
348
+ "borderInlineWidth",
349
+ "borderBlockWidth"
350
+ ],
351
+ borderColor: [
352
+ "borderTopColor",
353
+ "borderRightColor",
354
+ "borderBottomColor",
355
+ "borderLeftColor",
356
+ "borderStartColor",
357
+ "borderEndColor",
358
+ "borderInlineStartColor",
359
+ "borderInlineEndColor",
360
+ "borderBlockStartColor",
361
+ "borderBlockEndColor",
362
+ "borderInlineColor",
363
+ "borderBlockColor"
364
+ ]
365
+ };
231
366
  function computeClassPlan(cls, grammarConfig) {
232
367
  const groupMarker = /^group(?:\/([A-Za-z0-9_-]+))?$/.exec(cls);
233
- if (groupMarker) {
234
- return {
235
- entries: [["group", groupMarker[1] || true]],
236
- preserveRawClass: isWeb
237
- };
238
- }
368
+ if (groupMarker) return {
369
+ entries: [["group", groupMarker[1] || true]],
370
+ preserveRawClass: isWeb
371
+ };
239
372
  const containerMarker = /^@container(-size)?(?:\/([A-Za-z0-9_-]+))?$/.exec(cls);
240
373
  if (containerMarker) {
241
374
  const isSize = containerMarker[1] !== void 0;
242
375
  const name = containerMarker[2];
243
376
  const entries = [];
244
377
  entries.push(["container", name || true]);
245
- if (isSize) {
246
- entries.push(["containerType", "size"]);
247
- }
378
+ if (isSize) entries.push(["containerType", "size"]);
248
379
  return {
249
380
  entries,
250
381
  preserveRawClass: isWeb
251
382
  };
252
383
  }
253
384
  const classification = classifyCandidate(cls, grammarConfig);
254
- if (classification.kind === "passthrough") {
255
- return isWeb ? "raw" : null;
256
- }
385
+ if (classification.kind === "passthrough") return isWeb ? "raw" : null;
257
386
  const parsed = classification.parsed;
387
+ if (!nativeTarget && parsed.entry?.prop === "perspective") return "raw";
388
+ if (shouldGateNative(parsed)) return null;
389
+ if (parsed.entry?.prop === "flex" && parsed.rawValue) {
390
+ const fraction = /^(\d+)\/(\d+)$/.exec(parsed.rawValue);
391
+ if (fraction && Number(fraction[2]) !== 0) {
392
+ const basis = `${Number(fraction[1]) / Number(fraction[2]) * 100}%`;
393
+ const entries = [
394
+ createPlanEntry("flexGrow", 1, parsed.modifiers),
395
+ createPlanEntry("flexShrink", 1, parsed.modifiers),
396
+ createPlanEntry("flexBasis", basis, parsed.modifiers)
397
+ ];
398
+ return entries.every(Boolean) ? entries : "raw";
399
+ }
400
+ }
258
401
  const util = parsed.kind === "utility" ? parsed.properties : null;
259
402
  if (util) {
260
403
  const entries = [];
261
404
  for (const p in util) {
262
- const entry = createPlanEntry(p, util[p], parsed.modifiers);
405
+ const entry = createPlanEntry(p, nativeTarget && p === "transform" && util[p] === "none" ? [] : util[p], parsed.modifiers);
263
406
  if (!entry) return "raw";
264
407
  entries.push(entry);
265
408
  }
@@ -275,7 +418,7 @@ function computeClassPlan(cls, grammarConfig) {
275
418
  ...parsed.entry,
276
419
  prop
277
420
  } : parsed.entry
278
- });
421
+ }, grammarConfig);
279
422
  if (!flatProp2) return "raw";
280
423
  const entry = createPlanEntry(flatProp2.key, flatProp2.value, parsed.modifiers);
281
424
  if (!entry) return "raw";
@@ -283,7 +426,7 @@ function computeClassPlan(cls, grammarConfig) {
283
426
  }
284
427
  return entries;
285
428
  }
286
- const flatProp = tailwindClassToFlatProp(parsed);
429
+ const flatProp = tailwindClassToFlatProp(parsed, grammarConfig);
287
430
  if (flatProp) {
288
431
  const entry = createPlanEntry(flatProp.key, flatProp.value, parsed.modifiers);
289
432
  return entry ? [entry] : "raw";
@@ -300,9 +443,61 @@ function getTailwindClassPlan(candidate, config) {
300
443
  }
301
444
  return plan;
302
445
  }
446
+ function resolveTailwindCandidate(candidate, config, sink) {
447
+ const composed = tryCompose(candidate, getStyleGrammarConfig(config), sink);
448
+ if (composed !== void 0) return composed;
449
+ const plan = getTailwindClassPlan(candidate, config);
450
+ if (plan === "raw") return true;
451
+ if (plan === null) return null;
452
+ const parent = Array.isArray(plan) ? null : plan;
453
+ const entries = parent ? parent.entries : plan;
454
+ for (let index = 0; index < entries.length; index++) {
455
+ const entry = entries[index];
456
+ const transformTokenCategory = entry[0] === "x" || entry[0] === "y" ? "space" : entry[0] === "perspective" ? "perspective" : null;
457
+ const transformValue = transformTokenCategory && typeof entry[1] === "string" ? config.tokensParsed?.[transformTokenCategory]?.[entry[1]]?.val ?? entry[1] : entry[1];
458
+ if (noteTailwindTransform(sink, [
459
+ entry[0],
460
+ transformValue,
461
+ entry[2],
462
+ entry[3]
463
+ ])) continue;
464
+ if (entry[0] === "lineHeight") {
465
+ sink([
466
+ "__leading",
467
+ entry[1],
468
+ entry[2],
469
+ entry[3]
470
+ ]);
471
+ continue;
472
+ }
473
+ if (entry[0] === "fontSize" && typeof entry[1] === "string" && hasTokenName(getStyleGrammarConfig(config), "lineHeight", entry[1])) sink([
474
+ "__textLeading",
475
+ entry[1],
476
+ entry[2],
477
+ entry[3]
478
+ ]);
479
+ if (entry[0] === "boxShadow" && typeof entry[1] === "string") noteBoxShadow(sink, config.tokensParsed?.boxShadow?.[entry[1]]?.val ?? entry[1], entry[3] || []);
480
+ sink(entry);
481
+ }
482
+ return parent?.preserveRawClass || false;
483
+ }
303
484
  function resolveTailwindClassName(className, config) {
304
485
  const result = {};
486
+ let composedProps = null;
305
487
  let rawClassName = "";
488
+ const sink = (entry) => {
489
+ const [key, value, condition] = entry;
490
+ if (key.charCodeAt(0) === 95 && key.charCodeAt(1) === 95) {
491
+ composedProps ||= {};
492
+ composedProps[key] = mergeFrontendCondition(composedProps[key], value, condition);
493
+ return;
494
+ }
495
+ if (condition === void 0) {
496
+ const resets = shorthandResets[key];
497
+ if (resets) for (let i = 0; i < resets.length; i++) delete result[resets[i]];
498
+ }
499
+ setInAuthoredOrder(result, key, mergeFrontendCondition(result[key], value, condition));
500
+ };
306
501
  let start = 0;
307
502
  for (let index = 0; index <= className.length; index++) {
308
503
  if (index !== className.length && className.charCodeAt(index) > 32) continue;
@@ -311,45 +506,24 @@ function resolveTailwindClassName(className, config) {
311
506
  continue;
312
507
  }
313
508
  const candidate = className.slice(start, index);
314
- const plan = getTailwindClassPlan(candidate, config);
315
- if (plan === "raw") {
316
- rawClassName = rawClassName ? `${rawClassName} ${candidate}` : candidate;
317
- } else if (plan) {
318
- const parentPlan = plan;
319
- if (!Array.isArray(plan) && parentPlan.preserveRawClass) {
320
- rawClassName = rawClassName ? `${rawClassName} ${candidate}` : candidate;
321
- }
322
- const entries = Array.isArray(plan) ? plan : parentPlan.entries;
323
- for (let entryIndex = 0; entryIndex < entries.length; entryIndex++) {
324
- const [key, value, condition] = entries[entryIndex];
325
- const previous = result[key];
326
- let next = value;
327
- if (condition !== void 0) {
328
- next = previous && typeof previous === "object" && !Array.isArray(previous) ? {
329
- ...previous,
330
- [condition]: value
331
- } : previous === void 0 ? { [condition]: value } : {
332
- default: previous,
333
- [condition]: value
334
- };
335
- } else if (previous && typeof previous === "object" && !Array.isArray(previous)) {
336
- next = {
337
- ...previous,
338
- default: value
339
- };
340
- }
341
- setInAuthoredOrder(result, key, next);
342
- }
343
- }
509
+ if (resolveTailwindCandidate(candidate, config, sink)) rawClassName = rawClassName ? `${rawClassName} ${candidate}` : candidate;
344
510
  start = index + 1;
345
511
  }
512
+ if (composedProps) {
513
+ const composed = composedResolver(composedProps);
514
+ for (const key in composed) setInAuthoredOrder(result, key, composed[key]);
515
+ }
346
516
  if (rawClassName) result.className = rawClassName;
347
517
  return result;
348
518
  }
349
519
  function setInAuthoredOrder(target, key, value) {
520
+ if (value === "unset") {
521
+ delete target[key];
522
+ return;
523
+ }
350
524
  if (key in target) delete target[key];
351
525
  target[key] = value;
352
526
  }
353
527
 
354
- export { getStyleGrammarConfig, getTailwindClassPlan, isTokenValueProp, resolveTailwindClassName, setInAuthoredOrder };
528
+ export { getStyleGrammarConfig, getTailwindClassPlan, isTokenValueProp, resolveTailwindCandidate, resolveTailwindClassName, setInAuthoredOrder };
355
529
  //# sourceMappingURL=candidate.mjs.map