Skip to content

Commit

Permalink
Support postcss-import
Browse files Browse the repository at this point in the history
  • Loading branch information
philipp-spiess committed Nov 29, 2024
1 parent 8aa1825 commit e46c009
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 54 deletions.
28 changes: 4 additions & 24 deletions packages/tailwindcss/src/at-import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@ export async function substituteAtImports(
) {
let promises: Promise<void>[] = []

walk(ast, (node, { replaceWith, context: { reference } }) => {
walk(ast, (node, { replaceWith }) => {
if (node.kind === 'at-rule' && node.name === '@import') {
let parsed = parseImportParams(ValueParser.parse(node.params))
if (parsed === null) return

let { uri, layer, media, supports } = parsed
reference ||= parsed.reference ?? false

// Skip importing data or remote URIs
if (uri.startsWith('data:')) return
Expand All @@ -40,22 +39,14 @@ export async function substituteAtImports(

let loaded = await loadStylesheet(uri, base)
let ast = CSS.parse(loaded.content)
await substituteAtImports(ast, loaded.base, loadStylesheet, recurseCount + 1)

// if (reference) {
// ast = stripStyleRules(ast)
// }

ast = buildImportNodes(
contextNode.nodes = buildImportNodes(
[context({ base: loaded.base }, ast)],
layer,
media,
supports,
!!reference,
)

await substituteAtImports(ast, loaded.base, loadStylesheet, recurseCount + 1)

contextNode.nodes = ast
})(),
)

Expand All @@ -79,7 +70,6 @@ export function parseImportParams(params: ValueParser.ValueAstNode[]) {
let layer: string | null = null
let media: string | null = null
let supports: string | null = null
let reference: true | null = null

for (let i = 0; i < params.length; i++) {
let node = params[i]
Expand Down Expand Up @@ -129,26 +119,20 @@ export function parseImportParams(params: ValueParser.ValueAstNode[]) {
continue
}

if (node.kind === 'word' && node.value.toLocaleLowerCase() === 'reference') {
reference = true
continue
}

media = ValueParser.toCss(params.slice(i))
break
}

if (!uri) return null

return { uri, layer, media, supports, reference }
return { uri, layer, media, supports }
}

function buildImportNodes(
importedAst: AstNode[],
layer: string | null,
media: string | null,
supports: string | null,
reference: boolean | null,
): AstNode[] {
let root = importedAst

Expand All @@ -164,9 +148,5 @@ function buildImportNodes(
root = [atRule('@supports', supports[0] === '(' ? supports : `(${supports})`, root)]
}

if (reference !== null) {
root = [context({ reference }, root)]
}

return root
}
22 changes: 12 additions & 10 deletions packages/tailwindcss/src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3138,23 +3138,23 @@ describe('`@import "…" reference`', () => {
`)
})

test.only('removes styles when the import resolver was handled outside of Tailwind CSS', async () => {
test('removes styles when the import resolver was handled outside of Tailwind CSS', async () => {
await expect(
compileCss(
`
@media reference {
@media print {
.foo {
color: red;
@layer theme {
@theme {
--breakpoint-md: 48rem;
}
@utility foo {
.foo {
color: red;
}
@theme {
--breakpoint-md: 768px;
}
@variant hocus (&:hover, &:focus);
}
@utility foo {
color: red;
}
@variant hocus (&:hover, &:focus);
}
.bar {
Expand All @@ -3164,7 +3164,9 @@ describe('`@import "…" reference`', () => {
[],
),
).resolves.toMatchInlineSnapshot(`
"@media (width >= 768px) {
"@layer theme;
@media (width >= 48rem) {
.bar:hover, .bar:focus {
color: red;
}
Expand Down
36 changes: 16 additions & 20 deletions packages/tailwindcss/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,32 +339,34 @@ async function parseCss(

// Handle `@import "…" reference`
else if (param === 'reference') {
let newAst = []
for (let node of ast) {
if (node.kind !== 'at-rule') {
continue
walk(node.nodes, (child, { replaceWith }) => {
if (child.kind !== 'at-rule') {
replaceWith([])
return WalkAction.Skip
}
switch (node.name) {
switch (child.name) {
case '@theme': {
let themeParams = segment(node.params, ' ')
let themeParams = segment(child.params, ' ')
if (!themeParams.includes('reference')) {
node.params += ' reference'
child.params = (child.params === '' ? '' : ' ') + 'reference'
}
newAst.push(node)
continue
return WalkAction.Skip
}
case '@import':
case '@config':
case '@plugin':
case '@variant':
case '@utility': {
newAst.push(node)
continue
return WalkAction.Skip
}
}
}

node.nodes = [contextNode({ reference: true }, newAst)]
// Other at-rules, like `@media`, `@supports`, or `@layer` should
// be recursively traversed as these might be inserted by the
// `@import` resolution.
}
})
console.dir(node.nodes, { depth: null })
node.nodes = [contextNode({ reference: true }, node.nodes)]
}

//
Expand Down Expand Up @@ -604,9 +606,3 @@ export default function postcssPluginWarning() {
`It looks like you're trying to use \`tailwindcss\` directly as a PostCSS plugin. The PostCSS plugin has moved to a separate package, so to continue using Tailwind CSS with PostCSS you'll need to install \`@tailwindcss/postcss\` and update your PostCSS configuration.`,
)
}

function stripStyleRules(ast: AstNode[]) {
let newAst = []

return newAst
}

0 comments on commit e46c009

Please sign in to comment.