@tamagui/to-tailwind 0.0.0-bootstrap.0 → 3.0.0-beta.643.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +30 -0
- package/dist/cjs/index.native.cjs +32 -0
- package/dist/cjs/index.native.js +34 -0
- package/dist/cjs/index.native.js.map +1 -0
- package/dist/cjs/maps/componentToTag.cjs +42 -0
- package/dist/cjs/maps/componentToTag.native.cjs +44 -0
- package/dist/cjs/maps/componentToTag.native.js +46 -0
- package/dist/cjs/maps/componentToTag.native.js.map +1 -0
- package/dist/cjs/transform.cjs +706 -0
- package/dist/cjs/transform.native.cjs +933 -0
- package/dist/cjs/transform.native.js +935 -0
- package/dist/cjs/transform.native.js.map +1 -0
- package/dist/esm/index.mjs +4 -0
- package/dist/esm/index.native.js +4 -0
- package/dist/esm/maps/componentToTag.mjs +21 -0
- package/dist/esm/maps/componentToTag.mjs.map +1 -0
- package/dist/esm/maps/componentToTag.native.js +21 -0
- package/dist/esm/maps/componentToTag.native.js.map +1 -0
- package/dist/esm/transform.mjs +677 -0
- package/dist/esm/transform.mjs.map +1 -0
- package/dist/esm/transform.native.js +902 -0
- package/dist/esm/transform.native.js.map +1 -0
- package/package.json +44 -7
- package/src/index.ts +2 -0
- package/src/maps/componentToTag.ts +18 -0
- package/src/transform.ts +889 -0
- package/README.md +0 -1
|
@@ -0,0 +1,677 @@
|
|
|
1
|
+
import { parse } from "@babel/parser";
|
|
2
|
+
import _traverse from "@babel/traverse";
|
|
3
|
+
import _generate from "@babel/generator";
|
|
4
|
+
import * as t from "@babel/types";
|
|
5
|
+
import { createModifierRegistry, defaultMediaKeys, fontWeightNames, formatCandidate, getTokenCategory, parseValue, propToTailwindPrefix, standaloneValueProps, v6RemovedThemeNames, v6ThemeNameReplacements } from "@tamagui/style-grammar/tooling";
|
|
6
|
+
import { componentToTag } from "./maps/componentToTag.mjs";
|
|
7
|
+
import { shorthands } from "@tamagui/shorthands/v4";
|
|
8
|
+
|
|
9
|
+
const traverse = _traverse.default ?? _traverse;
|
|
10
|
+
const generate = _generate.default ?? _generate;
|
|
11
|
+
const defaultShorthands = shorthands;
|
|
12
|
+
const removedV6ThemeNames = new Set(v6RemovedThemeNames);
|
|
13
|
+
function getV6ThemeName(name) {
|
|
14
|
+
const opacityIndex = name.indexOf("/");
|
|
15
|
+
const baseName = opacityIndex === -1 ? name : name.slice(0, opacityIndex);
|
|
16
|
+
if (removedV6ThemeNames.has(baseName)) return null;
|
|
17
|
+
const mapped = v6ThemeNameReplacements[baseName] ?? baseName;
|
|
18
|
+
return opacityIndex === -1 ? mapped : `${mapped}${name.slice(opacityIndex)}`;
|
|
19
|
+
}
|
|
20
|
+
function namesToSet(names) {
|
|
21
|
+
if (!names) return /* @__PURE__ */ new Set();
|
|
22
|
+
if (Array.isArray(names)) return new Set(names);
|
|
23
|
+
if (names instanceof Set) return new Set(names);
|
|
24
|
+
return new Set(Object.keys(names));
|
|
25
|
+
}
|
|
26
|
+
function addConfigNames(target, source) {
|
|
27
|
+
if (!source) return;
|
|
28
|
+
for (const key in source) target.add(key);
|
|
29
|
+
}
|
|
30
|
+
function createTransformGrammarConfig(options, mediaKeys, shorthands) {
|
|
31
|
+
if (options.grammarConfig) {
|
|
32
|
+
return {
|
|
33
|
+
...options.grammarConfig,
|
|
34
|
+
shorthands,
|
|
35
|
+
mediaNames: mediaKeys
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const tokenNames = {};
|
|
39
|
+
const tokenCategories = [
|
|
40
|
+
"space",
|
|
41
|
+
"size",
|
|
42
|
+
"radius",
|
|
43
|
+
"zIndex",
|
|
44
|
+
"color"
|
|
45
|
+
];
|
|
46
|
+
const fontCategories = [
|
|
47
|
+
"fontFamily",
|
|
48
|
+
"fontSize",
|
|
49
|
+
"fontWeight",
|
|
50
|
+
"lineHeight",
|
|
51
|
+
"letterSpacing"
|
|
52
|
+
];
|
|
53
|
+
const authoritative = [
|
|
54
|
+
"tokens",
|
|
55
|
+
"fonts",
|
|
56
|
+
"themes",
|
|
57
|
+
"media",
|
|
58
|
+
"shorthands"
|
|
59
|
+
].some((key) => Object.prototype.hasOwnProperty.call(options, key));
|
|
60
|
+
if (authoritative) {
|
|
61
|
+
for (const category of [...tokenCategories, ...fontCategories]) {
|
|
62
|
+
tokenNames[category] = /* @__PURE__ */ new Set();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
for (const category of tokenCategories) {
|
|
66
|
+
if (options.tokens?.[category]) {
|
|
67
|
+
const names = tokenNames[category] || /* @__PURE__ */ new Set();
|
|
68
|
+
addConfigNames(names, options.tokens[category]);
|
|
69
|
+
tokenNames[category] = names;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (options.fonts) {
|
|
73
|
+
tokenNames.fontFamily ||= /* @__PURE__ */ new Set();
|
|
74
|
+
tokenNames.fontSize ||= /* @__PURE__ */ new Set();
|
|
75
|
+
tokenNames.fontWeight ||= /* @__PURE__ */ new Set();
|
|
76
|
+
tokenNames.lineHeight ||= /* @__PURE__ */ new Set();
|
|
77
|
+
tokenNames.letterSpacing ||= /* @__PURE__ */ new Set();
|
|
78
|
+
for (const familyName in options.fonts) {
|
|
79
|
+
tokenNames.fontFamily.add(familyName);
|
|
80
|
+
const font = options.fonts[familyName];
|
|
81
|
+
addConfigNames(tokenNames.fontSize, font?.size);
|
|
82
|
+
addConfigNames(tokenNames.fontWeight, font?.weight);
|
|
83
|
+
addConfigNames(tokenNames.lineHeight, font?.lineHeight);
|
|
84
|
+
addConfigNames(tokenNames.letterSpacing, font?.letterSpacing);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const themeNames = /* @__PURE__ */ new Set();
|
|
88
|
+
if (options.themes) {
|
|
89
|
+
tokenNames.color ||= /* @__PURE__ */ new Set();
|
|
90
|
+
for (const themeName in options.themes) {
|
|
91
|
+
themeNames.add(themeName);
|
|
92
|
+
for (const name in options.themes[themeName]) {
|
|
93
|
+
const mapped = getV6ThemeName(name);
|
|
94
|
+
if (mapped) tokenNames.color.add(mapped);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
shorthands,
|
|
100
|
+
mediaNames: mediaKeys,
|
|
101
|
+
themeNames,
|
|
102
|
+
tokenNames
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function findParseError(source) {
|
|
106
|
+
try {
|
|
107
|
+
const ast = parse(source, {
|
|
108
|
+
sourceType: "module",
|
|
109
|
+
plugins: ["jsx", "typescript"],
|
|
110
|
+
errorRecovery: true
|
|
111
|
+
});
|
|
112
|
+
const errs = ast.errors;
|
|
113
|
+
if (errs && errs.length > 0) {
|
|
114
|
+
const e = errs[0];
|
|
115
|
+
const loc = e?.loc ? `${e.loc.line}:${e.loc.column}` : "?";
|
|
116
|
+
return `${e?.reasonCode || e?.message || "parse error"} at ${loc}`;
|
|
117
|
+
}
|
|
118
|
+
return null;
|
|
119
|
+
} catch (e) {
|
|
120
|
+
return e.message || "parse error";
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function tamaguiToTailwind(source, options = {}) {
|
|
124
|
+
const { renameComponents = true } = options;
|
|
125
|
+
const mediaKeys = options.grammarConfig?.mediaNames ? namesToSet(options.grammarConfig.mediaNames) : options.media ? new Set(Array.isArray(options.media) ? options.media : Object.keys(options.media)) : new Set(defaultMediaKeys);
|
|
126
|
+
const shorthands = options.grammarConfig?.shorthands ?? options.shorthands ?? defaultShorthands;
|
|
127
|
+
const grammarConfig = createTransformGrammarConfig(options, mediaKeys, shorthands);
|
|
128
|
+
const ctx = {
|
|
129
|
+
mediaKeys,
|
|
130
|
+
componentAllow: new Set(options.components ?? []),
|
|
131
|
+
shorthands,
|
|
132
|
+
grammarConfig,
|
|
133
|
+
modifierRegistry: createModifierRegistry(grammarConfig).registry
|
|
134
|
+
};
|
|
135
|
+
let ast;
|
|
136
|
+
try {
|
|
137
|
+
ast = parse(source, {
|
|
138
|
+
sourceType: "module",
|
|
139
|
+
plugins: ["jsx", "typescript"],
|
|
140
|
+
errorRecovery: true
|
|
141
|
+
});
|
|
142
|
+
} catch {
|
|
143
|
+
return source;
|
|
144
|
+
}
|
|
145
|
+
if (ast.errors && ast.errors.length > 0) {
|
|
146
|
+
return source;
|
|
147
|
+
}
|
|
148
|
+
let didTransform = false;
|
|
149
|
+
traverse(ast, { JSXOpeningElement(path) {
|
|
150
|
+
const node = path.node;
|
|
151
|
+
const resolved = resolveTamaguiComponent(path, ctx);
|
|
152
|
+
if (resolved === null) return;
|
|
153
|
+
const { name: componentName, isSimpleKnown, isPlainIdentifier } = resolved;
|
|
154
|
+
if (node.attributes.some((a) => t.isJSXSpreadAttribute(a))) return;
|
|
155
|
+
const hasDynamicClassName = node.attributes.some((attr) => t.isJSXAttribute(attr) && attr.name.name === "className" && getStringValue(attr.value) === null);
|
|
156
|
+
if (hasDynamicClassName) return;
|
|
157
|
+
const hasClassName = node.attributes.some((attr) => t.isJSXAttribute(attr) && attr.name.name === "className");
|
|
158
|
+
const hasNeighboringStyleProp = node.attributes.some((attr) => {
|
|
159
|
+
if (!t.isJSXAttribute(attr) || attr.name.name === "className") return false;
|
|
160
|
+
const name = attr.name.name;
|
|
161
|
+
return isConvertibleStyleProp(resolveShorthand(ctx, name));
|
|
162
|
+
});
|
|
163
|
+
if (hasClassName && hasNeighboringStyleProp) return;
|
|
164
|
+
const classes = [];
|
|
165
|
+
const keptAttrs = [];
|
|
166
|
+
let existingClassName = null;
|
|
167
|
+
const blockedLeafKeys = /* @__PURE__ */ new Set();
|
|
168
|
+
for (const a of node.attributes) {
|
|
169
|
+
if (t.isJSXAttribute(a) && a.name.name === "className") {
|
|
170
|
+
const v = getStringValue(a.value);
|
|
171
|
+
if (v) {
|
|
172
|
+
for (const tok of v.split(/\s+/)) {
|
|
173
|
+
if (tok) for (const k of leafKeysOfClassToken(tok)) blockedLeafKeys.add(k);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const implicitClasses = [];
|
|
179
|
+
if (componentName === "XStack") implicitClasses.push("flex", "flex-row");
|
|
180
|
+
else if (componentName === "YStack") implicitClasses.push("flex", "flex-col");
|
|
181
|
+
else if (componentName === "ZStack") implicitClasses.push("relative");
|
|
182
|
+
const styleEntries = [];
|
|
183
|
+
for (const attr of node.attributes) {
|
|
184
|
+
if (!t.isJSXAttribute(attr)) {
|
|
185
|
+
keptAttrs.push(attr);
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const name = attr.name.name;
|
|
189
|
+
if (name === "className") {
|
|
190
|
+
existingClassName = attr;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
styleEntries.push({
|
|
194
|
+
attr,
|
|
195
|
+
fullProp: resolveShorthand(ctx, name),
|
|
196
|
+
cls: propValueToClass(ctx, name, attr.value)
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
const retainedLeafKeys = new Set(blockedLeafKeys);
|
|
200
|
+
for (const e of styleEntries) {
|
|
201
|
+
if (e.cls === null && isConvertibleStyleProp(e.fullProp)) {
|
|
202
|
+
for (const k of leafKeysOfProp(e.fullProp)) retainedLeafKeys.add(k);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
for (const c of implicitClasses) {
|
|
206
|
+
if (!overlapsSet(leafKeysOfClassToken(c), retainedLeafKeys)) classes.push(c);
|
|
207
|
+
}
|
|
208
|
+
for (const e of styleEntries) {
|
|
209
|
+
if (e.cls !== null && !overlapsSet(leafKeysOfProp(e.fullProp), retainedLeafKeys)) {
|
|
210
|
+
classes.push(e.cls);
|
|
211
|
+
} else {
|
|
212
|
+
keptAttrs.push(e.attr);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
if (classes.length > 0) {
|
|
216
|
+
const classStr = classes.join(" ");
|
|
217
|
+
if (existingClassName) {
|
|
218
|
+
const existingVal = getStringValue(existingClassName.value);
|
|
219
|
+
if (existingVal !== null) {
|
|
220
|
+
existingClassName.value = t.stringLiteral(existingVal ? `${classStr} ${existingVal}` : classStr);
|
|
221
|
+
keptAttrs.unshift(existingClassName);
|
|
222
|
+
} else if (t.isJSXExpressionContainer(existingClassName.value) && !t.isJSXEmptyExpression(existingClassName.value.expression)) {
|
|
223
|
+
const expr = existingClassName.value.expression;
|
|
224
|
+
existingClassName.value = t.jsxExpressionContainer(t.templateLiteral([t.templateElement({
|
|
225
|
+
raw: `${classStr} `,
|
|
226
|
+
cooked: `${classStr} `
|
|
227
|
+
}, false), t.templateElement({
|
|
228
|
+
raw: "",
|
|
229
|
+
cooked: ""
|
|
230
|
+
}, true)], [expr]));
|
|
231
|
+
keptAttrs.unshift(existingClassName);
|
|
232
|
+
} else {
|
|
233
|
+
keptAttrs.unshift(t.jsxAttribute(t.jsxIdentifier("className"), t.stringLiteral(classStr)));
|
|
234
|
+
}
|
|
235
|
+
} else {
|
|
236
|
+
keptAttrs.unshift(t.jsxAttribute(t.jsxIdentifier("className"), t.stringLiteral(classStr)));
|
|
237
|
+
}
|
|
238
|
+
} else if (existingClassName) {
|
|
239
|
+
keptAttrs.unshift(existingClassName);
|
|
240
|
+
}
|
|
241
|
+
node.attributes = keptAttrs;
|
|
242
|
+
if (classes.length > 0) didTransform = true;
|
|
243
|
+
if (renameComponents && isSimpleKnown && isPlainIdentifier) {
|
|
244
|
+
const tag = componentToTag[componentName];
|
|
245
|
+
node.name = t.jsxIdentifier(tag);
|
|
246
|
+
const parent = path.parent;
|
|
247
|
+
if (t.isJSXElement(parent) && parent.closingElement) {
|
|
248
|
+
parent.closingElement.name = t.jsxIdentifier(tag);
|
|
249
|
+
}
|
|
250
|
+
didTransform = true;
|
|
251
|
+
}
|
|
252
|
+
} });
|
|
253
|
+
if (!didTransform) return source;
|
|
254
|
+
const output = generate(ast, {
|
|
255
|
+
retainLines: true,
|
|
256
|
+
concise: false
|
|
257
|
+
});
|
|
258
|
+
return output.code;
|
|
259
|
+
}
|
|
260
|
+
const knownCompoundComponents = /* @__PURE__ */ new Set([
|
|
261
|
+
"Sheet.Frame",
|
|
262
|
+
"Sheet.Overlay",
|
|
263
|
+
"Sheet.Handle",
|
|
264
|
+
"Sheet.ScrollView",
|
|
265
|
+
"Sheet.Container",
|
|
266
|
+
"Dialog.Content",
|
|
267
|
+
"Dialog.Overlay",
|
|
268
|
+
"Popover.Content",
|
|
269
|
+
"Tabs.Tab"
|
|
270
|
+
]);
|
|
271
|
+
function isTamaguiSource(source) {
|
|
272
|
+
return source === "tamagui" || source.startsWith("@tamagui/");
|
|
273
|
+
}
|
|
274
|
+
function resolveTamaguiComponent(path, ctx) {
|
|
275
|
+
const nameNode = path.node.name;
|
|
276
|
+
let baseName;
|
|
277
|
+
let memberChain = [];
|
|
278
|
+
const isPlainIdentifier = t.isJSXIdentifier(nameNode);
|
|
279
|
+
if (t.isJSXIdentifier(nameNode)) {
|
|
280
|
+
baseName = nameNode.name;
|
|
281
|
+
} else if (t.isJSXMemberExpression(nameNode)) {
|
|
282
|
+
const parts = [];
|
|
283
|
+
let cur = nameNode;
|
|
284
|
+
while (t.isJSXMemberExpression(cur)) {
|
|
285
|
+
parts.unshift(cur.property.name);
|
|
286
|
+
cur = cur.object;
|
|
287
|
+
}
|
|
288
|
+
if (!t.isJSXIdentifier(cur)) return null;
|
|
289
|
+
baseName = cur.name;
|
|
290
|
+
memberChain = parts;
|
|
291
|
+
} else {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
const binding = path.scope?.getBinding?.(baseName);
|
|
295
|
+
let tamaguiBase;
|
|
296
|
+
if (binding) {
|
|
297
|
+
const bnode = binding.path.node;
|
|
298
|
+
if (t.isImportSpecifier(bnode) || t.isImportDefaultSpecifier(bnode) || t.isImportNamespaceSpecifier(bnode)) {
|
|
299
|
+
const decl = binding.path.parent;
|
|
300
|
+
const source = t.isImportDeclaration(decl) ? String(decl.source.value) : "";
|
|
301
|
+
if (!isTamaguiSource(source)) return null;
|
|
302
|
+
if (t.isImportNamespaceSpecifier(bnode)) {
|
|
303
|
+
if (memberChain.length === 0) return null;
|
|
304
|
+
tamaguiBase = memberChain[0];
|
|
305
|
+
memberChain = memberChain.slice(1);
|
|
306
|
+
} else if (t.isImportSpecifier(bnode)) {
|
|
307
|
+
const imported = bnode.imported;
|
|
308
|
+
tamaguiBase = t.isIdentifier(imported) ? imported.name : String(imported.value);
|
|
309
|
+
} else {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
} else {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
} else {
|
|
316
|
+
tamaguiBase = baseName;
|
|
317
|
+
}
|
|
318
|
+
const name = memberChain.length ? [tamaguiBase, ...memberChain].join(".") : tamaguiBase;
|
|
319
|
+
const isSimpleKnown = memberChain.length === 0 && name in componentToTag;
|
|
320
|
+
if (!isSimpleKnown && !knownCompoundComponents.has(name) && !ctx.componentAllow.has(name)) {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
name,
|
|
325
|
+
isSimpleKnown,
|
|
326
|
+
isPlainIdentifier
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function classPrefixOf(token) {
|
|
330
|
+
const noMod = token.slice(token.lastIndexOf(":") + 1);
|
|
331
|
+
const core = noMod[0] === "-" ? noMod.slice(1) : noMod;
|
|
332
|
+
const dash = core.indexOf("-");
|
|
333
|
+
return dash === -1 ? core : core.slice(0, dash);
|
|
334
|
+
}
|
|
335
|
+
const leafExpansion = {
|
|
336
|
+
padding: [
|
|
337
|
+
"paddingTop",
|
|
338
|
+
"paddingRight",
|
|
339
|
+
"paddingBottom",
|
|
340
|
+
"paddingLeft"
|
|
341
|
+
],
|
|
342
|
+
paddingHorizontal: ["paddingLeft", "paddingRight"],
|
|
343
|
+
paddingVertical: ["paddingTop", "paddingBottom"],
|
|
344
|
+
margin: [
|
|
345
|
+
"marginTop",
|
|
346
|
+
"marginRight",
|
|
347
|
+
"marginBottom",
|
|
348
|
+
"marginLeft"
|
|
349
|
+
],
|
|
350
|
+
marginHorizontal: ["marginLeft", "marginRight"],
|
|
351
|
+
marginVertical: ["marginTop", "marginBottom"],
|
|
352
|
+
inset: [
|
|
353
|
+
"top",
|
|
354
|
+
"right",
|
|
355
|
+
"bottom",
|
|
356
|
+
"left"
|
|
357
|
+
],
|
|
358
|
+
gap: [
|
|
359
|
+
"gap",
|
|
360
|
+
"rowGap",
|
|
361
|
+
"columnGap"
|
|
362
|
+
],
|
|
363
|
+
borderWidth: [
|
|
364
|
+
"borderTopWidth",
|
|
365
|
+
"borderRightWidth",
|
|
366
|
+
"borderBottomWidth",
|
|
367
|
+
"borderLeftWidth"
|
|
368
|
+
],
|
|
369
|
+
borderColor: [
|
|
370
|
+
"borderTopColor",
|
|
371
|
+
"borderRightColor",
|
|
372
|
+
"borderBottomColor",
|
|
373
|
+
"borderLeftColor"
|
|
374
|
+
],
|
|
375
|
+
borderRadius: [
|
|
376
|
+
"borderTopLeftRadius",
|
|
377
|
+
"borderTopRightRadius",
|
|
378
|
+
"borderBottomLeftRadius",
|
|
379
|
+
"borderBottomRightRadius"
|
|
380
|
+
]
|
|
381
|
+
};
|
|
382
|
+
function leafKeysOfProp(fullProp) {
|
|
383
|
+
return leafExpansion[fullProp] ?? [fullProp];
|
|
384
|
+
}
|
|
385
|
+
const prefixToProp = (() => {
|
|
386
|
+
const m = {};
|
|
387
|
+
for (const [prop, prefix] of Object.entries(propToTailwindPrefix)) {
|
|
388
|
+
if (prefix && !(prefix in m)) m[prefix] = prop;
|
|
389
|
+
}
|
|
390
|
+
return m;
|
|
391
|
+
})();
|
|
392
|
+
function leafKeysOfClassToken(token) {
|
|
393
|
+
const prefix = classPrefixOf(token);
|
|
394
|
+
return leafKeysOfProp(prefixToProp[prefix] ?? prefix);
|
|
395
|
+
}
|
|
396
|
+
function overlapsSet(keys, set) {
|
|
397
|
+
return keys.some((k) => set.has(k));
|
|
398
|
+
}
|
|
399
|
+
function isConvertibleStyleProp(fullProp) {
|
|
400
|
+
return propToTailwindPrefix[fullProp] !== void 0 || fullProp in standaloneValueProps;
|
|
401
|
+
}
|
|
402
|
+
function propValueToClass(ctx, propName, value) {
|
|
403
|
+
const fullProp = resolveShorthand(ctx, propName);
|
|
404
|
+
if (propToTailwindPrefix[fullProp] === void 0) return null;
|
|
405
|
+
const strVal = getStringValue(value);
|
|
406
|
+
const numVal = getNumericValue(value);
|
|
407
|
+
if (strVal !== null) {
|
|
408
|
+
const parsed = parseValue(strVal, ctx.modifierRegistry);
|
|
409
|
+
if (!parsed.ok) return null;
|
|
410
|
+
const classes = [];
|
|
411
|
+
if (parsed.value.base !== null) {
|
|
412
|
+
const base = payloadToClass(ctx, fullProp, parsed.value.base, []);
|
|
413
|
+
if (base === null) return null;
|
|
414
|
+
classes.push(base);
|
|
415
|
+
}
|
|
416
|
+
for (const clause of parsed.value.clauses) {
|
|
417
|
+
const conditional = payloadToClass(ctx, fullProp, clause.payload, clause.modifiers);
|
|
418
|
+
if (conditional === null) return null;
|
|
419
|
+
classes.push(conditional);
|
|
420
|
+
}
|
|
421
|
+
return classes.length ? classes.join(" ") : null;
|
|
422
|
+
}
|
|
423
|
+
if (numVal === null) return null;
|
|
424
|
+
const formatted = formatNumericValue(fullProp, numVal);
|
|
425
|
+
if (formatted === null) return null;
|
|
426
|
+
return formatCandidate({
|
|
427
|
+
prop: fullProp,
|
|
428
|
+
value: formatted.value,
|
|
429
|
+
valueKind: formatted.valueKind,
|
|
430
|
+
modifiers: void 0
|
|
431
|
+
}, ctx.grammarConfig);
|
|
432
|
+
}
|
|
433
|
+
function payloadToClass(ctx, fullProp, payload, modifiers) {
|
|
434
|
+
let formatted;
|
|
435
|
+
if (standaloneValueProps[fullProp]?.[payload]) {
|
|
436
|
+
formatted = {
|
|
437
|
+
value: payload,
|
|
438
|
+
valueKind: "enum"
|
|
439
|
+
};
|
|
440
|
+
} else {
|
|
441
|
+
formatted = formatStringValue(ctx, fullProp, payload);
|
|
442
|
+
if (formatted === null && /^-?\d+(?:\.\d+)?$/.test(payload)) {
|
|
443
|
+
const category = getTokenCategory(fullProp);
|
|
444
|
+
if (!category || ctx.grammarConfig.tokenNames?.[category] !== void 0) {
|
|
445
|
+
formatted = formatNumericValue(fullProp, Number(payload));
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
if (formatted === null) return null;
|
|
450
|
+
return formatCandidate({
|
|
451
|
+
prop: fullProp,
|
|
452
|
+
value: formatted.value,
|
|
453
|
+
valueKind: formatted.valueKind,
|
|
454
|
+
modifiers: modifiers.length ? modifiers : void 0
|
|
455
|
+
}, ctx.grammarConfig);
|
|
456
|
+
}
|
|
457
|
+
function getStringValue(value) {
|
|
458
|
+
if (!value) return null;
|
|
459
|
+
if (t.isStringLiteral(value)) return value.value;
|
|
460
|
+
if (t.isJSXExpressionContainer(value) && t.isStringLiteral(value.expression)) {
|
|
461
|
+
return value.expression.value;
|
|
462
|
+
}
|
|
463
|
+
if (t.isJSXExpressionContainer(value) && t.isTemplateLiteral(value.expression)) {
|
|
464
|
+
if (value.expression.expressions.length === 0 && value.expression.quasis.length === 1) {
|
|
465
|
+
return value.expression.quasis[0].value.raw;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
function getNumericValue(value) {
|
|
471
|
+
if (!value) return null;
|
|
472
|
+
if (t.isJSXExpressionContainer(value)) {
|
|
473
|
+
if (t.isNumericLiteral(value.expression)) return value.expression.value;
|
|
474
|
+
if (t.isUnaryExpression(value.expression) && value.expression.operator === "-" && t.isNumericLiteral(value.expression.argument)) {
|
|
475
|
+
return -value.expression.argument.value;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return null;
|
|
479
|
+
}
|
|
480
|
+
function resolveShorthand(ctx, name) {
|
|
481
|
+
return ctx.shorthands[name] || name;
|
|
482
|
+
}
|
|
483
|
+
function hasConfiguredName(names, value) {
|
|
484
|
+
if (!names) return false;
|
|
485
|
+
if (Array.isArray(names)) return names.includes(value);
|
|
486
|
+
if (names instanceof Set) return names.has(value);
|
|
487
|
+
return Object.prototype.hasOwnProperty.call(names, value);
|
|
488
|
+
}
|
|
489
|
+
function formatStringValue(ctx, prop, value) {
|
|
490
|
+
const category = getTokenCategory(prop);
|
|
491
|
+
if (prop !== "fontWeight" && category && hasConfiguredName(ctx.grammarConfig.tokenNames?.[category], value)) {
|
|
492
|
+
if (category === "color") {
|
|
493
|
+
const mapped = getV6ThemeName(value);
|
|
494
|
+
return mapped ? {
|
|
495
|
+
value: mapped,
|
|
496
|
+
valueKind: "token"
|
|
497
|
+
} : null;
|
|
498
|
+
}
|
|
499
|
+
return {
|
|
500
|
+
value,
|
|
501
|
+
valueKind: "token"
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
if (prop === "fontWeight") {
|
|
505
|
+
return fontWeightNames[value] ? {
|
|
506
|
+
value,
|
|
507
|
+
valueKind: "enum"
|
|
508
|
+
} : null;
|
|
509
|
+
}
|
|
510
|
+
if (prop === "zIndex" && /^\d+$/.test(value)) {
|
|
511
|
+
return {
|
|
512
|
+
value,
|
|
513
|
+
valueKind: "convenience"
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
if (/^-?\d+(\.\d+)?$/.test(value)) return null;
|
|
517
|
+
if (value.endsWith("%")) {
|
|
518
|
+
const exact = {
|
|
519
|
+
"100%": "full",
|
|
520
|
+
"50%": "1/2",
|
|
521
|
+
"25%": "1/4",
|
|
522
|
+
"75%": "3/4"
|
|
523
|
+
};
|
|
524
|
+
if (getTokenCategory(prop) === "size" && exact[value]) {
|
|
525
|
+
return {
|
|
526
|
+
value: exact[value],
|
|
527
|
+
valueKind: "convenience"
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
value,
|
|
532
|
+
valueKind: "arbitrary"
|
|
533
|
+
};
|
|
534
|
+
}
|
|
535
|
+
if (value === "auto" && getTokenCategory(prop) === "size") {
|
|
536
|
+
return {
|
|
537
|
+
value,
|
|
538
|
+
valueKind: "convenience"
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
if (prop === "fontFamily") return {
|
|
542
|
+
value,
|
|
543
|
+
valueKind: "arbitrary"
|
|
544
|
+
};
|
|
545
|
+
if (value.includes("(") || value.includes(" ") || value.includes("_") || value.startsWith("#") || value.startsWith("-") || /^[\d.]+[a-z%]/i.test(value)) {
|
|
546
|
+
return {
|
|
547
|
+
value,
|
|
548
|
+
valueKind: "arbitrary"
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
return {
|
|
552
|
+
value,
|
|
553
|
+
valueKind: "arbitrary"
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
const pxLengthProps = /* @__PURE__ */ new Set([
|
|
557
|
+
"width",
|
|
558
|
+
"height",
|
|
559
|
+
"minWidth",
|
|
560
|
+
"maxWidth",
|
|
561
|
+
"minHeight",
|
|
562
|
+
"maxHeight",
|
|
563
|
+
"flexBasis",
|
|
564
|
+
"padding",
|
|
565
|
+
"paddingTop",
|
|
566
|
+
"paddingRight",
|
|
567
|
+
"paddingBottom",
|
|
568
|
+
"paddingLeft",
|
|
569
|
+
"paddingHorizontal",
|
|
570
|
+
"paddingVertical",
|
|
571
|
+
"margin",
|
|
572
|
+
"marginTop",
|
|
573
|
+
"marginRight",
|
|
574
|
+
"marginBottom",
|
|
575
|
+
"marginLeft",
|
|
576
|
+
"marginHorizontal",
|
|
577
|
+
"marginVertical",
|
|
578
|
+
"gap",
|
|
579
|
+
"rowGap",
|
|
580
|
+
"columnGap",
|
|
581
|
+
"top",
|
|
582
|
+
"right",
|
|
583
|
+
"bottom",
|
|
584
|
+
"left",
|
|
585
|
+
"inset",
|
|
586
|
+
"borderRadius",
|
|
587
|
+
"borderTopLeftRadius",
|
|
588
|
+
"borderTopRightRadius",
|
|
589
|
+
"borderBottomLeftRadius",
|
|
590
|
+
"borderBottomRightRadius",
|
|
591
|
+
"fontSize",
|
|
592
|
+
"letterSpacing",
|
|
593
|
+
"lineHeight"
|
|
594
|
+
]);
|
|
595
|
+
function formatNumericValue(prop, value) {
|
|
596
|
+
if (prop === "opacity") {
|
|
597
|
+
const pct = value * 100;
|
|
598
|
+
return Number.isInteger(pct) ? {
|
|
599
|
+
value: String(pct),
|
|
600
|
+
valueKind: "convenience"
|
|
601
|
+
} : {
|
|
602
|
+
value: String(value),
|
|
603
|
+
valueKind: "arbitrary"
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
if (prop === "aspectRatio") return {
|
|
607
|
+
value: String(value),
|
|
608
|
+
valueKind: "arbitrary"
|
|
609
|
+
};
|
|
610
|
+
if (prop === "scale" || prop === "scaleX" || prop === "scaleY") {
|
|
611
|
+
if (value === 0) return {
|
|
612
|
+
value: "0",
|
|
613
|
+
valueKind: "convenience"
|
|
614
|
+
};
|
|
615
|
+
if (value === 1) return {
|
|
616
|
+
value: "100",
|
|
617
|
+
valueKind: "convenience"
|
|
618
|
+
};
|
|
619
|
+
return {
|
|
620
|
+
value: String(value),
|
|
621
|
+
valueKind: "arbitrary"
|
|
622
|
+
};
|
|
623
|
+
}
|
|
624
|
+
if (prop === "flex") {
|
|
625
|
+
return value === 1 ? {
|
|
626
|
+
value: "1",
|
|
627
|
+
valueKind: "convenience"
|
|
628
|
+
} : {
|
|
629
|
+
value: String(value),
|
|
630
|
+
valueKind: "arbitrary"
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
if (prop === "flexGrow" || prop === "flexShrink") {
|
|
634
|
+
return {
|
|
635
|
+
value: String(value),
|
|
636
|
+
valueKind: "arbitrary"
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
if (prop === "zIndex") {
|
|
640
|
+
return Number.isInteger(value) && value >= 0 ? {
|
|
641
|
+
value: String(value),
|
|
642
|
+
valueKind: "convenience"
|
|
643
|
+
} : {
|
|
644
|
+
value: String(value),
|
|
645
|
+
valueKind: "arbitrary"
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
if (prop === "fontWeight") {
|
|
649
|
+
return fontWeightNames[String(value)] ? {
|
|
650
|
+
value: String(value),
|
|
651
|
+
valueKind: "enum"
|
|
652
|
+
} : null;
|
|
653
|
+
}
|
|
654
|
+
if (prop === "rotate") return null;
|
|
655
|
+
if (prop === "x" || prop === "y") {
|
|
656
|
+
return {
|
|
657
|
+
value: `${value}px`,
|
|
658
|
+
valueKind: "arbitrary"
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
if (prop.includes("Width") && prop.startsWith("border")) {
|
|
662
|
+
return {
|
|
663
|
+
value: `${value}px`,
|
|
664
|
+
valueKind: "arbitrary"
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
if (pxLengthProps.has(prop)) {
|
|
668
|
+
return {
|
|
669
|
+
value: `${value}px`,
|
|
670
|
+
valueKind: "arbitrary"
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
return null;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
export { findParseError, tamaguiToTailwind };
|
|
677
|
+
//# sourceMappingURL=transform.mjs.map
|