From 65355361832c38ef6d8d8bcdac0585fbf7d2adbb Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Thu, 1 Dec 2022 18:04:46 +0800 Subject: [PATCH] feat(directives): support `applyVariable`, deprecated `varStyle` --- packages/transformer-directives/README.md | 27 ++++----- packages/transformer-directives/src/apply.ts | 5 +- packages/transformer-directives/src/index.ts | 58 ++++++++++++++------ test/fixtures/vite/src/main.css | 2 +- test/transformer-directives.test.ts | 4 +- 5 files changed, 61 insertions(+), 35 deletions(-) diff --git a/packages/transformer-directives/README.md b/packages/transformer-directives/README.md index e3149d9b58..aaf80347b8 100644 --- a/packages/transformer-directives/README.md +++ b/packages/transformer-directives/README.md @@ -62,13 +62,14 @@ To use rules with `:`, you will need to quote the value } ``` -This feature is enabled by default (with prefix `--at-`), you can configure it or disable it via: +This feature is enabled by default with a few alias, you can configure or disable it via: ```js transformerDirectives({ - varStyle: '--my-at-', + // the defaults + applyVariable: ['--at-apply', '--uno-apply', '--uno'], // or disable with: - // varStyle: false + // applyVariable: false }) ``` @@ -78,16 +79,16 @@ The `@screen` directive allows you to create media queries that reference your b ```css .grid { - @apply grid grid-cols-2; + --uno: grid grid-cols-2; } @screen xs { .grid { - @apply grid-cols-1; + --uno: grid-cols-1; } } @screen sm { .grid { - @apply grid-cols-3; + --uno: grid-cols-3; } } /* ... */ @@ -121,16 +122,16 @@ Will be transformed to: ```css .grid { - @apply grid grid-cols-2; + --uno: grid grid-cols-2; } @screen lt-xs { .grid { - @apply grid-cols-1; + --uno: grid-cols-1; } } @screen lt-sm { .grid { - @apply grid-cols-3; + --uno: grid-cols-3; } } /* ... */ @@ -160,21 +161,21 @@ Will be transformed to: ```css .grid { - @apply grid grid-cols-2; + --uno: grid grid-cols-2; } @screen at-xs { .grid { - @apply grid-cols-1; + --uno: grid-cols-1; } } @screen at-xl { .grid { - @apply grid-cols-3; + --uno: grid-cols-3; } } @screen at-xxl { .grid { - @apply grid-cols-4; + --uno: grid-cols-4; } } /* ... */ diff --git a/packages/transformer-directives/src/apply.ts b/packages/transformer-directives/src/apply.ts index d5ca525c6b..69c19a6c0e 100644 --- a/packages/transformer-directives/src/apply.ts +++ b/packages/transformer-directives/src/apply.ts @@ -20,15 +20,14 @@ export async function handleApply(ctx: TransformerDirectivesContext, node: Rule) ) } -export async function parseApply({ code, uno, options, offset }: TransformerDirectivesContext, node: Rule, childNode: CssNode) { - const { varStyle = '--at-' } = options +export async function parseApply({ code, uno, offset, applyVariable }: TransformerDirectivesContext, node: Rule, childNode: CssNode) { const calcOffset = (pos: number) => offset ? pos + offset : pos let body: string | undefined if (childNode.type === 'Atrule' && childNode.name === 'apply' && childNode.prelude && childNode.prelude.type === 'Raw') { body = childNode.prelude.value.trim() } - else if (varStyle !== false && childNode!.type === 'Declaration' && childNode.property === `${varStyle}apply` && childNode.value.type === 'Raw') { + else if (childNode!.type === 'Declaration' && applyVariable.includes(childNode.property) && childNode.value.type === 'Raw') { body = childNode.value.value.trim() // remove quotes if (body.match(/^(['"]).*\1$/)) diff --git a/packages/transformer-directives/src/index.ts b/packages/transformer-directives/src/index.ts index 0185d1d93e..5da9af777c 100644 --- a/packages/transformer-directives/src/index.ts +++ b/packages/transformer-directives/src/index.ts @@ -1,4 +1,4 @@ -import { cssIdRE } from '@unocss/core' +import { cssIdRE, toArray } from '@unocss/core' import type { SourceCodeTransformer, UnoGenerator } from '@unocss/core' import type { CssNode, List, ListItem } from 'css-tree' import { parse, walk } from 'css-tree' @@ -9,27 +9,39 @@ import { handleApply } from './apply' export interface TransformerDirectivesOptions { enforce?: SourceCodeTransformer['enforce'] + /** - * Treat CSS variables as directives for CSS syntax compatible. + * Throw an error if utils or themes are not found. * - * Pass `false` to disable, or a string to use as a prefix. + * @default true + */ + throwOnMissing?: boolean + + /** + * Treat CSS variables as @apply directives for CSS syntax compatible. * - * @default '--at-' + * Pass `false` to disable. + * + * @default ['--at-apply', '--uno-apply', '--uno'] */ - varStyle?: false | string + applyVariable?: false | string | string[] /** - * Throw an error if utils or themes are not found. + * Treat CSS variables as directives for CSS syntax compatible. * - * @default true + * Pass `false` to disable, or a string to use as a prefix. + * + * @deprecated use `applyVariable` to specify the full var name instead. + * @default '--at-' */ - throwOnMissing?: boolean + varStyle?: false | string } export interface TransformerDirectivesContext { code: MagicString uno: UnoGenerator options: TransformerDirectivesOptions + applyVariable: string[] offset?: number filename?: string } @@ -53,13 +65,20 @@ export async function transformDirectives( originalCode?: string, offset?: number, ) { - const { varStyle = '--at-' } = options + let { applyVariable } = options + const varStyle = options.varStyle + if (applyVariable === undefined) { + if (varStyle !== undefined) + applyVariable = varStyle ? [`${varStyle}apply`] : [] + applyVariable = ['--at-apply', '--uno-apply', '--uno'] + } + applyVariable = toArray(applyVariable || []) - const isApply = code.original.includes('@apply') || (varStyle !== false && code.original.includes(varStyle)) - const isScreen = code.original.includes('@screen') + const hasApply = code.original.includes('@apply') || applyVariable.some(s => code.original.includes(s)) + const hasScreen = code.original.includes('@screen') const hasThemeFn = code.original.match(themeFnRE) - if (!isApply && !hasThemeFn && !isScreen) + if (!hasApply && !hasThemeFn && !hasScreen) return const ast = parse(originalCode || code.original, { @@ -73,16 +92,23 @@ export async function transformDirectives( const stack: Promise[] = [] - const processNode = async (node: CssNode, _item: ListItem, _list: List) => { - const ctx: TransformerDirectivesContext = { options, uno, code, filename, offset } + const ctx: TransformerDirectivesContext = { + options, + applyVariable, + uno, + code, + filename, + offset, + } - if (isScreen && node.type === 'Atrule') + const processNode = async (node: CssNode, _item: ListItem, _list: List) => { + if (hasScreen && node.type === 'Atrule') handleScreen(ctx, node) if (hasThemeFn && node.type === 'Declaration') handleThemeFn(ctx, node) - if (isApply && node.type === 'Rule') + if (hasApply && node.type === 'Rule') await handleApply(ctx, node) } diff --git a/test/fixtures/vite/src/main.css b/test/fixtures/vite/src/main.css index a12547aa62..c702888113 100644 --- a/test/fixtures/vite/src/main.css +++ b/test/fixtures/vite/src/main.css @@ -1,6 +1,6 @@ .foo { @apply flex; - @apply gap-1; + --uno: gap-1; } .bar { diff --git a/test/transformer-directives.test.ts b/test/transformer-directives.test.ts index 9eb15f6a67..b9ea8e0ee3 100644 --- a/test/transformer-directives.test.ts +++ b/test/transformer-directives.test.ts @@ -354,12 +354,12 @@ describe('transformer-directives', () => { ul { li { - --at-apply: border; + --uno-apply: border; } } a { --at-apply: px-2; - --at-apply: "hover:underline"; + --uno: "hover:underline"; } }`, )