mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-22 04:05:48 +00:00
feat(cli): add support for custom Tailwind prefix transformer (#770)
* feat(cli): add support for custom Tailwind prefix * fix(cli): add tw prefix on classes applied in the css file * feat(cli): add support for custom tailwind prefix * chore: add changeset * style(shadcn-ui): code format --------- Co-authored-by: shadcn <m@shadcn.com>
This commit is contained in:
5
.changeset/plenty-mugs-applaud.md
Normal file
5
.changeset/plenty-mugs-applaud.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"shadcn-ui": minor
|
||||
---
|
||||
|
||||
add support for custom tailwind prefix
|
||||
@@ -27,6 +27,8 @@ import ora from "ora"
|
||||
import prompts from "prompts"
|
||||
import * as z from "zod"
|
||||
|
||||
import { applyPrefixesCss } from "../utils/transformers/transform-tw-prefix"
|
||||
|
||||
const PROJECT_DEPENDENCIES = [
|
||||
"tailwindcss-animate",
|
||||
"class-variance-authority",
|
||||
@@ -132,6 +134,14 @@ export async function promptForConfig(
|
||||
active: "yes",
|
||||
inactive: "no",
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
name: "tailwindPrefix",
|
||||
message: `Are you using a custom ${highlight(
|
||||
"tailwind prefix eg. tw-"
|
||||
)}? (Leave blank if not)`,
|
||||
initial: "",
|
||||
},
|
||||
{
|
||||
type: "text",
|
||||
name: "tailwindConfig",
|
||||
@@ -168,6 +178,7 @@ export async function promptForConfig(
|
||||
css: options.tailwindCss,
|
||||
baseColor: options.tailwindBaseColor,
|
||||
cssVariables: options.tailwindCssVariables,
|
||||
prefix: options.tailwindPrefix,
|
||||
},
|
||||
rsc: options.rsc,
|
||||
tsx: options.typescript,
|
||||
@@ -246,7 +257,10 @@ export async function runInit(cwd: string, config: Config) {
|
||||
// Write tailwind config.
|
||||
await fs.writeFile(
|
||||
config.resolvedPaths.tailwindConfig,
|
||||
template(tailwindConfigTemplate)({ extension }),
|
||||
template(tailwindConfigTemplate)({
|
||||
extension,
|
||||
prefix: config.tailwind.prefix,
|
||||
}),
|
||||
"utf8"
|
||||
)
|
||||
|
||||
@@ -256,7 +270,9 @@ export async function runInit(cwd: string, config: Config) {
|
||||
await fs.writeFile(
|
||||
config.resolvedPaths.tailwindCss,
|
||||
config.tailwind.cssVariables
|
||||
? baseColor.cssVarsTemplate
|
||||
? config.tailwind.prefix
|
||||
? applyPrefixesCss(baseColor.cssVarsTemplate, config.tailwind.prefix)
|
||||
: baseColor.cssVarsTemplate
|
||||
: baseColor.inlineColorsTemplate,
|
||||
"utf8"
|
||||
)
|
||||
|
||||
@@ -28,6 +28,7 @@ export const rawConfigSchema = z
|
||||
css: z.string(),
|
||||
baseColor: z.string(),
|
||||
cssVariables: z.boolean().default(true),
|
||||
prefix: z.string().default("").optional(),
|
||||
}),
|
||||
aliases: z.object({
|
||||
components: z.string(),
|
||||
|
||||
@@ -23,6 +23,7 @@ module.exports = {
|
||||
'./app/**/*.{<%- extension %>,<%- extension %>x}',
|
||||
'./src/**/*.{<%- extension %>,<%- extension %>x}',
|
||||
],
|
||||
prefix: "<%- prefix %>",
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
@@ -60,6 +61,7 @@ module.exports = {
|
||||
'./app/**/*.{<%- extension %>,<%- extension %>x}',
|
||||
'./src/**/*.{<%- extension %>,<%- extension %>x}',
|
||||
],
|
||||
prefix: "<%- prefix %>",
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
@@ -138,6 +140,7 @@ const config = {
|
||||
'./app/**/*.{<%- extension %>,<%- extension %>x}',
|
||||
'./src/**/*.{<%- extension %>,<%- extension %>x}',
|
||||
],
|
||||
prefix: "<%- prefix %>",
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
@@ -178,6 +181,7 @@ const config = {
|
||||
'./app/**/*.{<%- extension %>,<%- extension %>x}',
|
||||
'./src/**/*.{<%- extension %>,<%- extension %>x}',
|
||||
],
|
||||
prefix: "<%- prefix %>",
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
|
||||
@@ -10,6 +10,8 @@ import { transformRsc } from "@/src/utils/transformers/transform-rsc"
|
||||
import { Project, ScriptKind, type SourceFile } from "ts-morph"
|
||||
import * as z from "zod"
|
||||
|
||||
import { transformTwPrefixes } from "./transform-tw-prefix"
|
||||
|
||||
export type TransformOpts = {
|
||||
filename: string
|
||||
raw: string
|
||||
@@ -27,6 +29,7 @@ const transformers: Transformer[] = [
|
||||
transformImport,
|
||||
transformRsc,
|
||||
transformCssVars,
|
||||
transformTwPrefixes,
|
||||
]
|
||||
|
||||
const project = new Project({
|
||||
|
||||
201
packages/cli/src/utils/transformers/transform-tw-prefix.ts
Normal file
201
packages/cli/src/utils/transformers/transform-tw-prefix.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
import { Transformer } from "@/src/utils/transformers"
|
||||
import { SyntaxKind } from "ts-morph"
|
||||
|
||||
import { splitClassName } from "./transform-css-vars"
|
||||
|
||||
export const transformTwPrefixes: Transformer = async ({
|
||||
sourceFile,
|
||||
config,
|
||||
}) => {
|
||||
if (!config.tailwind?.prefix) {
|
||||
return sourceFile
|
||||
}
|
||||
|
||||
// Find the cva function calls.
|
||||
sourceFile
|
||||
.getDescendantsOfKind(SyntaxKind.CallExpression)
|
||||
.filter((node) => node.getExpression().getText() === "cva")
|
||||
.forEach((node) => {
|
||||
// cva(base, ...)
|
||||
if (node.getArguments()[0]?.isKind(SyntaxKind.StringLiteral)) {
|
||||
const defaultClassNames = node.getArguments()[0]
|
||||
if (defaultClassNames) {
|
||||
defaultClassNames.replaceWithText(
|
||||
`"${applyPrefix(
|
||||
defaultClassNames.getText()?.replace(/"/g, ""),
|
||||
config.tailwind.prefix
|
||||
)}"`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// cva(..., { variants: { ... } })
|
||||
if (node.getArguments()[1]?.isKind(SyntaxKind.ObjectLiteralExpression)) {
|
||||
node
|
||||
.getArguments()[1]
|
||||
?.getDescendantsOfKind(SyntaxKind.PropertyAssignment)
|
||||
.find((node) => node.getName() === "variants")
|
||||
?.getDescendantsOfKind(SyntaxKind.PropertyAssignment)
|
||||
.forEach((node) => {
|
||||
node
|
||||
.getDescendantsOfKind(SyntaxKind.PropertyAssignment)
|
||||
.forEach((node) => {
|
||||
const classNames = node.getInitializerIfKind(
|
||||
SyntaxKind.StringLiteral
|
||||
)
|
||||
if (classNames) {
|
||||
classNames?.replaceWithText(
|
||||
`"${applyPrefix(
|
||||
classNames.getText()?.replace(/"/g, ""),
|
||||
config.tailwind.prefix
|
||||
)}"`
|
||||
)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// Find all jsx attributes with the name className.
|
||||
sourceFile.getDescendantsOfKind(SyntaxKind.JsxAttribute).forEach((node) => {
|
||||
if (node.getName() === "className") {
|
||||
// className="..."
|
||||
if (node.getInitializer()?.isKind(SyntaxKind.StringLiteral)) {
|
||||
const value = node.getInitializer()
|
||||
if (value) {
|
||||
value.replaceWithText(
|
||||
`"${applyPrefix(
|
||||
value.getText()?.replace(/"/g, ""),
|
||||
config.tailwind.prefix
|
||||
)}"`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// className={...}
|
||||
if (node.getInitializer()?.isKind(SyntaxKind.JsxExpression)) {
|
||||
// Check if it's a call to cn().
|
||||
const callExpression = node
|
||||
.getInitializer()
|
||||
?.getDescendantsOfKind(SyntaxKind.CallExpression)
|
||||
.find((node) => node.getExpression().getText() === "cn")
|
||||
if (callExpression) {
|
||||
// Loop through the arguments.
|
||||
callExpression.getArguments().forEach((node) => {
|
||||
if (
|
||||
node.isKind(SyntaxKind.ConditionalExpression) ||
|
||||
node.isKind(SyntaxKind.BinaryExpression)
|
||||
) {
|
||||
node
|
||||
.getChildrenOfKind(SyntaxKind.StringLiteral)
|
||||
.forEach((node) => {
|
||||
node.replaceWithText(
|
||||
`"${applyPrefix(
|
||||
node.getText()?.replace(/"/g, ""),
|
||||
config.tailwind.prefix
|
||||
)}"`
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
if (node.isKind(SyntaxKind.StringLiteral)) {
|
||||
node.replaceWithText(
|
||||
`"${applyPrefix(
|
||||
node.getText()?.replace(/"/g, ""),
|
||||
config.tailwind.prefix
|
||||
)}"`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// classNames={...}
|
||||
if (node.getName() === "classNames") {
|
||||
if (node.getInitializer()?.isKind(SyntaxKind.JsxExpression)) {
|
||||
node
|
||||
.getDescendantsOfKind(SyntaxKind.PropertyAssignment)
|
||||
.forEach((node) => {
|
||||
if (node.getInitializer()?.isKind(SyntaxKind.CallExpression)) {
|
||||
const callExpression = node.getInitializerIfKind(
|
||||
SyntaxKind.CallExpression
|
||||
)
|
||||
if (callExpression) {
|
||||
// Loop through the arguments.
|
||||
callExpression.getArguments().forEach((arg) => {
|
||||
if (arg.isKind(SyntaxKind.ConditionalExpression)) {
|
||||
arg
|
||||
.getChildrenOfKind(SyntaxKind.StringLiteral)
|
||||
.forEach((node) => {
|
||||
node.replaceWithText(
|
||||
`"${applyPrefix(
|
||||
node.getText()?.replace(/"/g, ""),
|
||||
config.tailwind.prefix
|
||||
)}"`
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
if (arg.isKind(SyntaxKind.StringLiteral)) {
|
||||
arg.replaceWithText(
|
||||
`"${applyPrefix(
|
||||
arg.getText()?.replace(/"/g, ""),
|
||||
config.tailwind.prefix
|
||||
)}"`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (node.getInitializer()?.isKind(SyntaxKind.StringLiteral)) {
|
||||
if (node.getName() !== "variant") {
|
||||
const classNames = node.getInitializer()
|
||||
if (classNames) {
|
||||
classNames.replaceWithText(
|
||||
`"${applyPrefix(
|
||||
classNames.getText()?.replace(/"/g, ""),
|
||||
config.tailwind.prefix
|
||||
)}"`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return sourceFile
|
||||
}
|
||||
|
||||
export function applyPrefix(input: string, prefix: string = "") {
|
||||
const classNames = input.split(" ")
|
||||
const prefixed: string[] = []
|
||||
for (let className of classNames) {
|
||||
const [variant, value, modifier] = splitClassName(className)
|
||||
if (variant) {
|
||||
modifier
|
||||
? prefixed.push(`${variant}:${prefix}${value}/${modifier}`)
|
||||
: prefixed.push(`${variant}:${prefix}${value}`)
|
||||
} else {
|
||||
modifier
|
||||
? prefixed.push(`${prefix}${value}/${modifier}`)
|
||||
: prefixed.push(`${prefix}${value}`)
|
||||
}
|
||||
}
|
||||
return prefixed.join(" ")
|
||||
}
|
||||
|
||||
export function applyPrefixesCss(css: string, prefix: string) {
|
||||
const lines = css.split("\n")
|
||||
for (let line of lines) {
|
||||
if (line.includes("@apply")) {
|
||||
const originalTWCls = line.replace("@apply", "").trim()
|
||||
const prefixedTwCls = applyPrefix(originalTWCls, prefix)
|
||||
css = css.replace(originalTWCls, prefixedTwCls)
|
||||
}
|
||||
}
|
||||
return css
|
||||
}
|
||||
@@ -4,7 +4,8 @@
|
||||
"config": "tailwind.config.ts",
|
||||
"css": "src/app/globals.css",
|
||||
"baseColor": "zinc",
|
||||
"cssVariables": true
|
||||
"cssVariables": true,
|
||||
"prefix": "tw-"
|
||||
},
|
||||
"rsc": false,
|
||||
"aliases": {
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`transform tailwind prefix 1`] = `
|
||||
"import * as React from \\"react\\"
|
||||
export function Foo() {
|
||||
return (
|
||||
<div
|
||||
className=\\"tw-bg-background hover:tw-bg-muted tw-text-primary-foreground sm:focus:tw-text-accent-foreground\\">foo</div>
|
||||
);
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`transform tailwind prefix 2`] = `
|
||||
"import * as React from \\"react\\"
|
||||
export function Foo() {
|
||||
return (
|
||||
<div
|
||||
className=\\"tw-bg-white hover:tw-bg-stone-100 tw-text-stone-50 sm:focus:tw-text-stone-900 dark:tw-bg-stone-950 dark:hover:tw-bg-stone-800 dark:tw-text-stone-900 dark:sm:focus:tw-text-stone-50\\">foo</div>
|
||||
);
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`transform tailwind prefix 3`] = `
|
||||
"import * as React from \\"react\\"
|
||||
export function Foo() {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
\\"tw-bg-white hover:tw-bg-stone-100 dark:tw-bg-stone-950 dark:hover:tw-bg-stone-800\\",
|
||||
true && \\"tw-text-stone-50 sm:focus:tw-text-stone-900 dark:tw-text-stone-900 dark:sm:focus:tw-text-stone-50\\"
|
||||
)}>foo</div>
|
||||
);
|
||||
}
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`transform tailwind prefix 4`] = `
|
||||
"@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 224 71.4% 4.1%;
|
||||
|
||||
--muted: 220 14.3% 95.9%;
|
||||
--muted-foreground: 220 8.9% 46.1%;
|
||||
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 224 71.4% 4.1%;
|
||||
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 224 71.4% 4.1%;
|
||||
|
||||
--border: 220 13% 91%;
|
||||
--input: 220 13% 91%;
|
||||
|
||||
--primary: 220.9 39.3% 11%;
|
||||
--primary-foreground: 210 20% 98%;
|
||||
|
||||
--secondary: 220 14.3% 95.9%;
|
||||
--secondary-foreground: 220.9 39.3% 11%;
|
||||
|
||||
--accent: 220 14.3% 95.9%;
|
||||
--accent-foreground: 220.9 39.3% 11%;
|
||||
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 210 20% 98%;
|
||||
|
||||
--ring: 217.9 10.6% 64.9%;
|
||||
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 224 71.4% 4.1%;
|
||||
--foreground: 210 20% 98%;
|
||||
|
||||
--muted: 215 27.9% 16.9%;
|
||||
--muted-foreground: 217.9 10.6% 64.9%;
|
||||
|
||||
--popover: 224 71.4% 4.1%;
|
||||
--popover-foreground: 210 20% 98%;
|
||||
|
||||
--card: 224 71.4% 4.1%;
|
||||
--card-foreground: 210 20% 98%;
|
||||
|
||||
--border: 215 27.9% 16.9%;
|
||||
--input: 215 27.9% 16.9%;
|
||||
|
||||
--primary: 210 20% 98%;
|
||||
--primary-foreground: 220.9 39.3% 11%;
|
||||
|
||||
--secondary: 215 27.9% 16.9%;
|
||||
--secondary-foreground: 210 20% 98%;
|
||||
|
||||
--accent: 215 27.9% 16.9%;
|
||||
--accent-foreground: 210 20% 98%;
|
||||
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 85.7% 97.3%;
|
||||
|
||||
--ring: 215 27.9% 16.9%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply tw-border-border;
|
||||
}
|
||||
body {
|
||||
@apply tw-bg-background tw-text-foreground;
|
||||
}
|
||||
}"
|
||||
`;
|
||||
42
packages/cli/test/utils/apply-prefix.test.ts
Normal file
42
packages/cli/test/utils/apply-prefix.test.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { describe, expect, test } from "vitest"
|
||||
|
||||
import { applyPrefix } from "../../src/utils/transformers/transform-tw-prefix"
|
||||
|
||||
describe("apply tailwind prefix", () => {
|
||||
test.each([
|
||||
{
|
||||
input: "bg-slate-800 text-gray-500",
|
||||
output: "tw-bg-slate-800 tw-text-gray-500",
|
||||
},
|
||||
{
|
||||
input: "hover:dark:bg-background dark:text-foreground",
|
||||
output: "hover:dark:tw-bg-background dark:tw-text-foreground",
|
||||
},
|
||||
{
|
||||
input:
|
||||
"rounded-lg border border-slate-200 bg-white text-slate-950 shadow-sm dark:border-slate-800 dark:bg-slate-950 dark:text-slate-50",
|
||||
output:
|
||||
"tw-rounded-lg tw-border tw-border-slate-200 tw-bg-white tw-text-slate-950 tw-shadow-sm dark:tw-border-slate-800 dark:tw-bg-slate-950 dark:tw-text-slate-50",
|
||||
},
|
||||
{
|
||||
input:
|
||||
"text-red-500 border-red-500/50 dark:border-red-500 [&>svg]:text-red-500 text-red-500 dark:text-red-900 dark:border-red-900/50 dark:dark:border-red-900 dark:[&>svg]:text-red-900 dark:text-red-900",
|
||||
output:
|
||||
"tw-text-red-500 tw-border-red-500/50 dark:tw-border-red-500 [&>svg]:tw-text-red-500 tw-text-red-500 dark:tw-text-red-900 dark:tw-border-red-900/50 dark:dark:tw-border-red-900 dark:[&>svg]:tw-text-red-900 dark:tw-text-red-900",
|
||||
},
|
||||
{
|
||||
input:
|
||||
"flex h-full w-full items-center justify-center rounded-full bg-muted",
|
||||
output:
|
||||
"tw-flex tw-h-full tw-w-full tw-items-center tw-justify-center tw-rounded-full tw-bg-muted",
|
||||
},
|
||||
{
|
||||
input:
|
||||
"absolute right-4 top-4 bg-primary rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary",
|
||||
output:
|
||||
"tw-absolute tw-right-4 tw-top-4 tw-bg-primary tw-rounded-sm tw-opacity-70 tw-ring-offset-background tw-transition-opacity hover:tw-opacity-100 focus:tw-outline-none focus:tw-ring-2 focus:tw-ring-ring focus:tw-ring-offset-2 disabled:tw-pointer-events-none data-[state=open]:tw-bg-secondary",
|
||||
},
|
||||
])(`applyTwPrefix($input) -> $output`, ({ input, output }) => {
|
||||
expect(applyPrefix(input, "tw-")).toBe(output)
|
||||
})
|
||||
})
|
||||
@@ -91,6 +91,7 @@ test("get config", async () => {
|
||||
baseColor: "zinc",
|
||||
css: "src/app/globals.css",
|
||||
cssVariables: true,
|
||||
prefix: "tw-"
|
||||
},
|
||||
aliases: {
|
||||
components: "~/components",
|
||||
|
||||
82
packages/cli/test/utils/transform-tw-prefix.test.ts
Normal file
82
packages/cli/test/utils/transform-tw-prefix.test.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { expect, test } from "vitest"
|
||||
|
||||
import { transform } from "../../src/utils/transformers"
|
||||
import { applyPrefixesCss } from "../../src/utils/transformers/transform-tw-prefix"
|
||||
import stone from "../fixtures/colors/stone.json"
|
||||
|
||||
test("transform tailwind prefix", async () => {
|
||||
expect(
|
||||
await transform({
|
||||
filename: "test.ts",
|
||||
raw: `import * as React from "react"
|
||||
export function Foo() {
|
||||
return <div className="bg-background hover:bg-muted text-primary-foreground sm:focus:text-accent-foreground">foo</div>
|
||||
}
|
||||
`,
|
||||
config: {
|
||||
tailwind: {
|
||||
baseColor: "stone",
|
||||
prefix: "tw-",
|
||||
},
|
||||
aliases: {
|
||||
components: "@/components",
|
||||
utils: "@/lib/utils",
|
||||
},
|
||||
},
|
||||
baseColor: "stone",
|
||||
})
|
||||
).toMatchSnapshot()
|
||||
|
||||
expect(
|
||||
await transform({
|
||||
filename: "test.ts",
|
||||
raw: `import * as React from "react"
|
||||
export function Foo() {
|
||||
return <div className="bg-background hover:bg-muted text-primary-foreground sm:focus:text-accent-foreground">foo</div>
|
||||
}
|
||||
`,
|
||||
config: {
|
||||
tailwind: {
|
||||
baseColor: "stone",
|
||||
cssVariables: false,
|
||||
prefix: "tw-",
|
||||
},
|
||||
aliases: {
|
||||
components: "@/components",
|
||||
utils: "@/lib/utils",
|
||||
},
|
||||
},
|
||||
baseColor: stone,
|
||||
})
|
||||
).toMatchSnapshot()
|
||||
|
||||
expect(
|
||||
await transform({
|
||||
filename: "test.ts",
|
||||
raw: `import * as React from "react"
|
||||
export function Foo() {
|
||||
return <div className={cn("bg-background hover:bg-muted", true && "text-primary-foreground sm:focus:text-accent-foreground")}>foo</div>
|
||||
}
|
||||
`,
|
||||
config: {
|
||||
tailwind: {
|
||||
baseColor: "stone",
|
||||
cssVariables: false,
|
||||
prefix: "tw-",
|
||||
},
|
||||
aliases: {
|
||||
components: "@/components",
|
||||
utils: "@/lib/utils",
|
||||
},
|
||||
},
|
||||
baseColor: stone,
|
||||
})
|
||||
).toMatchSnapshot()
|
||||
|
||||
expect(
|
||||
applyPrefixesCss(
|
||||
"@tailwind base;\n@tailwind components;\n@tailwind utilities;\n \n@layer base {\n :root {\n --background: 0 0% 100%;\n --foreground: 224 71.4% 4.1%;\n \n --muted: 220 14.3% 95.9%;\n --muted-foreground: 220 8.9% 46.1%;\n \n --popover: 0 0% 100%;\n --popover-foreground: 224 71.4% 4.1%;\n \n --card: 0 0% 100%;\n --card-foreground: 224 71.4% 4.1%;\n \n --border: 220 13% 91%;\n --input: 220 13% 91%;\n \n --primary: 220.9 39.3% 11%;\n --primary-foreground: 210 20% 98%;\n \n --secondary: 220 14.3% 95.9%;\n --secondary-foreground: 220.9 39.3% 11%;\n \n --accent: 220 14.3% 95.9%;\n --accent-foreground: 220.9 39.3% 11%;\n \n --destructive: 0 84.2% 60.2%;\n --destructive-foreground: 210 20% 98%;\n \n --ring: 217.9 10.6% 64.9%;\n \n --radius: 0.5rem;\n }\n \n .dark {\n --background: 224 71.4% 4.1%;\n --foreground: 210 20% 98%;\n \n --muted: 215 27.9% 16.9%;\n --muted-foreground: 217.9 10.6% 64.9%;\n \n --popover: 224 71.4% 4.1%;\n --popover-foreground: 210 20% 98%;\n \n --card: 224 71.4% 4.1%;\n --card-foreground: 210 20% 98%;\n \n --border: 215 27.9% 16.9%;\n --input: 215 27.9% 16.9%;\n \n --primary: 210 20% 98%;\n --primary-foreground: 220.9 39.3% 11%;\n \n --secondary: 215 27.9% 16.9%;\n --secondary-foreground: 210 20% 98%;\n \n --accent: 215 27.9% 16.9%;\n --accent-foreground: 210 20% 98%;\n \n --destructive: 0 62.8% 30.6%;\n --destructive-foreground: 0 85.7% 97.3%;\n \n --ring: 215 27.9% 16.9%;\n }\n}\n \n@layer base {\n * {\n @apply border-border;\n }\n body {\n @apply bg-background text-foreground;\n }\n}",
|
||||
"tw-"
|
||||
)
|
||||
).toMatchSnapshot()
|
||||
})
|
||||
Reference in New Issue
Block a user