Skip to content

Commit

Permalink
feat(directives): support applyVariable, deprecated varStyle
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Dec 1, 2022
1 parent 2818d53 commit 6535536
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 35 deletions.
27 changes: 14 additions & 13 deletions packages/transformer-directives/README.md
Expand Up @@ -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
})
```

Expand All @@ -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;
}
}
/* ... */
Expand Down Expand Up @@ -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;
}
}
/* ... */
Expand Down Expand Up @@ -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;
}
}
/* ... */
Expand Down
5 changes: 2 additions & 3 deletions packages/transformer-directives/src/apply.ts
Expand Up @@ -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$/))
Expand Down
58 changes: 42 additions & 16 deletions 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'
Expand All @@ -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
}
Expand All @@ -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, {
Expand All @@ -73,16 +92,23 @@ export async function transformDirectives(

const stack: Promise<void>[] = []

const processNode = async (node: CssNode, _item: ListItem<CssNode>, _list: List<CssNode>) => {
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<CssNode>, _list: List<CssNode>) => {
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)
}

Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/vite/src/main.css
@@ -1,6 +1,6 @@
.foo {
@apply flex;
@apply gap-1;
--uno: gap-1;
}

.bar {
Expand Down
4 changes: 2 additions & 2 deletions test/transformer-directives.test.ts
Expand Up @@ -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";
}
}`,
)
Expand Down

0 comments on commit 6535536

Please sign in to comment.