Fix issue
This commit is contained in:
parent
2c4b75aa6c
commit
1f5e7fa049
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@aet/tailwind",
|
||||
"version": "1.0.20",
|
||||
"version": "1.0.23",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
27
src/__tests__/__snapshots__/emit.test.ts.snap
Normal file
27
src/__tests__/__snapshots__/emit.test.ts.snap
Normal file
@ -0,0 +1,27 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`emit > supports emitting as CSS module 1`] = `
|
||||
"// babel-tailwind:/Users/aet/Documents/Git/babel-tailwind/src/.temp-attr/index.module.css
|
||||
var index_default = {
|
||||
"tw-gqn2k6": "index_tw-gqn2k6",
|
||||
"tw-1qtvvjy": "index_tw-1qtvvjy"
|
||||
};
|
||||
|
||||
import { cx as _cx } from "@emotion/css";
|
||||
import { jsx } from "react/jsx-runtime";
|
||||
function Hello() {
|
||||
return /* @__PURE__ */ jsx("div", { className: _cx([index_default["tw-gqn2k6"], index_default["tw-1qtvvjy"]]), children: "Hello, world!" });
|
||||
}
|
||||
export {
|
||||
Hello
|
||||
};"
|
||||
`;
|
||||
|
||||
exports[`emit > supports emitting as CSS module 2`] = `
|
||||
".index_tw-gqn2k6 {
|
||||
text-align: center;
|
||||
}
|
||||
.index_tw-1qtvvjy:hover {
|
||||
font-weight: 600;
|
||||
}"
|
||||
`;
|
@ -1,4 +1,5 @@
|
||||
import { describe, it } from "vitest";
|
||||
|
||||
import { getBuild, matchSnapshot } from "./utils";
|
||||
|
||||
describe("attr", () => {
|
||||
@ -61,7 +62,7 @@ describe("attr", () => {
|
||||
matchSnapshot(files);
|
||||
});
|
||||
|
||||
it.only("fails", async () => {
|
||||
it("fails", async () => {
|
||||
const { files } = await compileESBuild({
|
||||
clsx: "emotion",
|
||||
expectFiles: 2,
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { createPostCSS } from "../index";
|
||||
|
||||
import { getBuild, minCSS, name } from "./utils";
|
||||
|
||||
describe("babel-tailwind", () => {
|
||||
|
26
src/__tests__/emit.test.ts
Normal file
26
src/__tests__/emit.test.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { describe, it } from "vitest";
|
||||
|
||||
import { getBuild, matchSnapshot } from "./utils";
|
||||
|
||||
describe("emit", () => {
|
||||
const compileESBuild = getBuild("attr");
|
||||
|
||||
it("supports emitting as CSS module", async () => {
|
||||
const { files } = await compileESBuild({
|
||||
clsx: "emotion",
|
||||
expectFiles: 2,
|
||||
cssModules: true,
|
||||
javascript: /* tsx */ `
|
||||
export function Hello() {
|
||||
return (
|
||||
<div css={["text-center", { hover: "font-semibold" }]}>
|
||||
Hello, world!
|
||||
</div>
|
||||
);
|
||||
}
|
||||
`,
|
||||
});
|
||||
|
||||
matchSnapshot(files);
|
||||
});
|
||||
});
|
@ -1,6 +1,8 @@
|
||||
/* eslint-disable unicorn/string-content */
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { getClassName } from "../index";
|
||||
|
||||
import { getBuild } from "./utils";
|
||||
|
||||
describe("merges with existing className attribute", () => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { getBuild, matchSnapshot } from "./utils";
|
||||
|
||||
describe("options", () => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { describe, it } from "vitest";
|
||||
|
||||
import { getBuild, matchSnapshot } from "./utils";
|
||||
|
||||
describe("babel-tailwind", () => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { describe, it } from "vitest";
|
||||
|
||||
import { getBuild, matchSnapshot } from "./utils";
|
||||
|
||||
describe("babel-tailwind", () => {
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { promises as fs } from "node:fs";
|
||||
import { join, resolve } from "node:path";
|
||||
import { afterEach, beforeEach, expect } from "vitest";
|
||||
import * as esbuild from "esbuild";
|
||||
|
||||
import dedent from "dedent";
|
||||
import * as esbuild from "esbuild";
|
||||
import { afterEach, beforeEach, expect } from "vitest";
|
||||
|
||||
import { type TailwindPluginOptions, babelPlugin, getTailwindPlugins } from "../index";
|
||||
|
||||
export { name } from "../../package.json" with { type: "json" };
|
||||
|
@ -35,12 +35,14 @@ function getUtils({
|
||||
clsx,
|
||||
getClassName: getClass = getClassName,
|
||||
vite: bustCache,
|
||||
cssModules,
|
||||
} = options;
|
||||
|
||||
let cx: t.Identifier;
|
||||
let tslibImport: t.Identifier;
|
||||
let styleImport: t.Identifier;
|
||||
let classedImport: t.Identifier;
|
||||
let cssModuleImport: t.Identifier;
|
||||
|
||||
const cssMap = new Map<string, StyleMapEntry>();
|
||||
const jsMap = new Map<string, StyleMapEntry>();
|
||||
@ -50,6 +52,13 @@ function getUtils({
|
||||
return t.cloneNode(styleImport);
|
||||
}
|
||||
|
||||
const getCssModuleImport = () => {
|
||||
if (cssModuleImport == null) {
|
||||
cssModuleImport = path.scope.generateUidIdentifier("cssModule");
|
||||
}
|
||||
return t.cloneNode(cssModuleImport);
|
||||
};
|
||||
|
||||
return {
|
||||
getClass(type: Type, value: string) {
|
||||
return type === "css" ? getClass(value) : "tw_" + hash(value);
|
||||
@ -65,7 +74,7 @@ function getUtils({
|
||||
.join("\n"),
|
||||
}),
|
||||
|
||||
recordIfAbsent(type: Type, entry: StyleMapEntry) {
|
||||
recordIfAbsent(type: "css", entry: StyleMapEntry) {
|
||||
const map = type === "css" ? cssMap : jsMap;
|
||||
if (!map.has(entry.key)) {
|
||||
map.set(entry.key, entry);
|
||||
@ -125,18 +134,44 @@ function getUtils({
|
||||
return t.cloneNode(classedImport);
|
||||
},
|
||||
|
||||
getCssModuleImport,
|
||||
|
||||
getClassNameValue: (className: string) => {
|
||||
const validId = t.isValidIdentifier(className);
|
||||
return cssModules
|
||||
? t.memberExpression(
|
||||
getCssModuleImport(),
|
||||
validId ? t.identifier(className) : t.stringLiteral(className),
|
||||
!validId
|
||||
)
|
||||
: t.stringLiteral(className);
|
||||
},
|
||||
|
||||
finish(node: t.Program) {
|
||||
const { filename } = state;
|
||||
if (!cssMap.size && !jsMap.size) return;
|
||||
invariant(filename, "babel: missing state.filename");
|
||||
|
||||
if (cssMap.size) {
|
||||
const cssName = basename(filename, extname(filename)) + ".css";
|
||||
const cssName =
|
||||
basename(filename, extname(filename)) +
|
||||
(cssModuleImport ? ".module" : "") +
|
||||
".css";
|
||||
const path = join(dirname(filename), cssName);
|
||||
const value = Array.from(cssMap.values());
|
||||
const importee = `tailwind:./${cssName}` + getSuffix(bustCache, value);
|
||||
|
||||
node.body.unshift(t.importDeclaration([], t.stringLiteral(importee)));
|
||||
if (cssModuleImport) {
|
||||
const importee = `tailwind:./${cssName}` + getSuffix(bustCache, value);
|
||||
node.body.unshift(
|
||||
t.importDeclaration(
|
||||
[t.importDefaultSpecifier(cssModuleImport)],
|
||||
t.stringLiteral(importee)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
const importee = `tailwind:./${cssName}` + getSuffix(bustCache, value);
|
||||
node.body.unshift(t.importDeclaration([], t.stringLiteral(importee)));
|
||||
}
|
||||
|
||||
styleMap.set(path, value);
|
||||
onCollect?.(path, value);
|
||||
@ -212,7 +247,7 @@ export function babelTailwind(
|
||||
classNames: trimmed,
|
||||
location: _.sliceText(node),
|
||||
});
|
||||
path.replaceWith(t.stringLiteral(className));
|
||||
path.replaceWith(_.getClassNameValue(className));
|
||||
}
|
||||
},
|
||||
ArrayExpression(path) {
|
||||
@ -228,7 +263,7 @@ export function babelTailwind(
|
||||
classNames: trimmed,
|
||||
location: _.sliceText(path.node),
|
||||
});
|
||||
path.replaceWith(t.stringLiteral(className));
|
||||
path.replaceWith(_.getClassNameValue(className));
|
||||
},
|
||||
JSXExpressionContainer(path) {
|
||||
go(path.get("expression"));
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { extname } from "node:path";
|
||||
import { once } from "lodash-es";
|
||||
|
||||
import type babel from "@babel/core";
|
||||
import type * as esbuild from "esbuild";
|
||||
import { transformSync } from "@babel/core";
|
||||
import type * as esbuild from "esbuild";
|
||||
import { once } from "lodash-es";
|
||||
|
||||
/**
|
||||
* An esbuild plugin that processes files with Babel if `plugins` is not empty.
|
||||
|
21
src/index.ts
21
src/index.ts
@ -19,7 +19,7 @@ export { createPostCSS } from "./shared";
|
||||
type GetClassName = (className: string) => string;
|
||||
export type BuildStyleFile = (
|
||||
path: string
|
||||
) => Promise<readonly ["css", string] | readonly ["js", string]>;
|
||||
) => Promise<readonly ["css" | "local-css", string] | readonly ["js", string]>;
|
||||
|
||||
export interface TailwindPluginOptions {
|
||||
/**
|
||||
@ -86,6 +86,17 @@ export interface TailwindPluginOptions {
|
||||
* Keep the original classnames in the CSS output
|
||||
*/
|
||||
addSourceAsComment?: boolean;
|
||||
|
||||
/**
|
||||
* Emit as CSS modules
|
||||
*/
|
||||
cssModules?: boolean;
|
||||
|
||||
/**
|
||||
* Emit type. `css-import` for plain CSS import,
|
||||
* `css-module` for CSS modules, `css-in-js` for JS.
|
||||
*/
|
||||
// emitType: "css-import" | "css-module" | "css-in-js";
|
||||
}
|
||||
|
||||
export type ResolveTailwindOptions = SetRequired<
|
||||
@ -121,7 +132,7 @@ export const getClassName: GetClassName = cls => "tw-" + hash(cls);
|
||||
* });
|
||||
*/
|
||||
export function getTailwindPlugins(options: TailwindPluginOptions) {
|
||||
const { addSourceAsComment, compile: _compile } = options;
|
||||
const { addSourceAsComment, compile: _compile, cssModules } = options;
|
||||
const resolvedOptions: ResolveTailwindOptions = {
|
||||
getClassName,
|
||||
jsxAttributeAction: "delete",
|
||||
@ -155,7 +166,10 @@ export function getTailwindPlugins(options: TailwindPluginOptions) {
|
||||
.join("\n")
|
||||
);
|
||||
if (path.endsWith(".css")) {
|
||||
return ["css", transformSync(compiled, { loader: "css" }).code] as const;
|
||||
return [
|
||||
cssModules ? "local-css" : "css",
|
||||
transformSync(compiled, { loader: "css" }).code,
|
||||
] as const;
|
||||
} else if (path.endsWith(".js")) {
|
||||
const js = toJSCode(compiled, x => x.slice(1));
|
||||
return ["js", js] as const;
|
||||
@ -176,6 +190,7 @@ export function getTailwindPlugins(options: TailwindPluginOptions) {
|
||||
styleMap,
|
||||
options,
|
||||
getCompiler,
|
||||
buildStyleFile,
|
||||
[Symbol.dispose]() {
|
||||
styleMap.clear();
|
||||
},
|
||||
|
13
src/vendor/animate.ts
vendored
13
src/vendor/animate.ts
vendored
@ -1,4 +1,5 @@
|
||||
// https://github.com/jamiebuilds/tailwindcss-animate/commit/ac0dd3a3c81681b78f1d8ea5e7478044213995e1
|
||||
// https://github.com/tailwindlabs/tailwindcss/discussions/11164#discussioncomment-5819097
|
||||
import plugin from "tailwindcss/plugin.js";
|
||||
import type { PluginAPI } from "tailwindcss/types/config";
|
||||
|
||||
@ -11,11 +12,7 @@ function filterDefault<T extends object>(values: T) {
|
||||
export default plugin(
|
||||
({ addUtilities, matchUtilities, theme }) => {
|
||||
addUtilities({
|
||||
"@keyframes enter": theme("keyframes.enter"),
|
||||
"@keyframes exit": theme("keyframes.exit"),
|
||||
".animate-in": {
|
||||
animationName: "enter",
|
||||
animationDuration: theme("animationDuration.DEFAULT"),
|
||||
"--tw-enter-opacity": "initial",
|
||||
"--tw-enter-scale": "initial",
|
||||
"--tw-enter-rotate": "initial",
|
||||
@ -23,8 +20,6 @@ export default plugin(
|
||||
"--tw-enter-translate-y": "initial",
|
||||
},
|
||||
".animate-out": {
|
||||
animationName: "exit",
|
||||
animationDuration: theme("animationDuration.DEFAULT"),
|
||||
"--tw-exit-opacity": "initial",
|
||||
"--tw-exit-scale": "initial",
|
||||
"--tw-exit-rotate": "initial",
|
||||
@ -168,6 +163,10 @@ export default plugin(
|
||||
1: "1",
|
||||
infinite: "infinite",
|
||||
},
|
||||
animation: ({ theme }) => ({
|
||||
out: `leave ${theme("animationDuration.DEFAULT")}`,
|
||||
in: `enter ${theme("animationDuration.DEFAULT")}`,
|
||||
}),
|
||||
keyframes: {
|
||||
enter: {
|
||||
from: {
|
||||
@ -176,7 +175,7 @@ export default plugin(
|
||||
"translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0) scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))",
|
||||
},
|
||||
},
|
||||
exit: {
|
||||
leave: {
|
||||
to: {
|
||||
opacity: "var(--tw-exit-opacity, 1)",
|
||||
transform:
|
||||
|
Loading…
x
Reference in New Issue
Block a user