Support string literal

This commit is contained in:
Alex 2024-06-29 10:56:25 -04:00
parent eaa888e920
commit 7072dc493d
3 changed files with 44 additions and 29 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@aet/tailwind", "name": "@aet/tailwind",
"version": "0.0.1-beta.10", "version": "0.0.1-beta.11",
"main": "dist/index.js", "main": "dist/index.js",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {

View File

@ -35,6 +35,8 @@ interface BabelPluginState {
export type ClassNameCollector = (path: string, entries: StyleMapEntry[]) => void; export type ClassNameCollector = (path: string, entries: StyleMapEntry[]) => void;
const trim = (value: string) => value.replace(/\s+/g, " ").trim();
export function babelTailwind( export function babelTailwind(
{ {
styleMap, styleMap,
@ -137,7 +139,7 @@ export function babelTailwind(
const value = quasis[0].value.cooked; const value = quasis[0].value.cooked;
if (value) { if (value) {
const trimmed = value.replace(/\s+/g, " ").trim(); const trimmed = trim(value);
const className = getClass(trimmed); const className = getClass(trimmed);
recordIfAbsent({ recordIfAbsent({
key: className, key: className,
@ -156,22 +158,23 @@ export function babelTailwind(
const { callee, arguments: args } = node; const { callee, arguments: args } = node;
if (!t.isIdentifier(callee, { name: macroFunction })) return; if (!t.isIdentifier(callee, { name: macroFunction })) return;
if (args.length !== 1) { const trimmed = args
throw new Error(`${macroFunction} should be called with exactly one argument`); .flatMap((arg, i) => {
if (t.isStringLiteral(arg)) {
return trim(arg.value);
} }
const [arg] = args;
if (!t.isObjectExpression(arg)) { if (!t.isObjectExpression(arg)) {
throw new Error(`${macroFunction} should be called with an object literal`); throw new Error(`${macroFunction} should be called with an object literal`);
} }
const ev = path.get("arguments")[0].evaluate(); const ev = path.get("arguments")[i].evaluate();
if (!ev.confident || typeof ev.value !== "object" || ev.value == null) { if (!ev.confident || typeof ev.value !== "object" || ev.value == null) {
throw new Error(`${macroFunction} should be called with a static object literal`); throw new Error(
`${macroFunction} should be called with a static object literal`
);
} }
const trimmed = Object.entries(ev.value) return Object.entries(ev.value).flatMap(([modifier, classes]) => {
.flatMap(([modifier, classes]) => {
if (typeof classes !== "string") { if (typeof classes !== "string") {
throw new Error(`Value for "${modifier}" should be a string`); throw new Error(`Value for "${modifier}" should be a string`);
} }
@ -180,6 +183,7 @@ export function babelTailwind(
.trim() .trim()
.split(" ") .split(" ")
.map(cls => modifier + ":" + cls); .map(cls => modifier + ":" + cls);
});
}) })
.join(" "); .join(" ");

View File

@ -159,22 +159,33 @@ describe("babel-tailwind", () => {
expect(files.css.text).toMatch(`.${clsName} {\n text-align: center;\n}`); expect(files.css.text).toMatch(`.${clsName} {\n text-align: center;\n}`);
}); });
it("supports grouped tw", async () => { it.only("supports grouped tw", async () => {
const { files } = await compileESBuild({ const { files } = await compileESBuild({
clsx: "emotion", clsx: "emotion",
expectFiles: 2, expectFiles: 2,
javascript: /* tsx */ ` javascript: /* tsx */ `
export default tw({ export default tw("text-sm", {
"group-hover": "text-center", "group-hover": "text-center",
"[&>div]": "font-semibold", "[&>div]": "font-semibold",
}) })
`, `,
}); });
const clsName = getClassName("group-hover:text-center [&>div]:font-semibold"); const clsName = getClassName("text-sm group-hover:text-center [&>div]:font-semibold");
expect(files.js.text).toContain(`= "${clsName}"`); expect(files.js.text).toContain(`= "${clsName}"`);
expect(files.css.text).toMatch( expect(files.css.text).toMatch(
`.group:hover .${clsName} {\n text-align: center;\n}\n.${clsName} > div {\n font-weight: 600;\n}` [
`.${clsName} {`,
" font-size: 0.875rem;",
" line-height: 1.25rem;",
"}",
`.group:hover .${clsName} {`,
" text-align: center;",
"}",
`.${clsName} > div {`,
" font-weight: 600;",
"}",
].join("\n")
); );
}); });