@tamagui/tailwind 3.0.0-beta.922.1 → 3.0.0

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