-
-
Notifications
You must be signed in to change notification settings - Fork 804
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(preset-mini): support for defining css property with the `theme(…
…)` function (#3204) Co-authored-by: chris <hizyyv@gmail.com> Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com> Co-authored-by: Chris <1633711653@qq.com>
- Loading branch information
1 parent
c15a29d
commit da5ec25
Showing
13 changed files
with
88 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,9 @@ | ||
import type { UnoGenerator } from '@unocss/core' | ||
import { colorToString, parseCssColor } from '@unocss/rule-utils' | ||
import { transformThemeFn } from '@unocss/rule-utils' | ||
import type { Root } from 'postcss' | ||
import MagicString from 'magic-string' | ||
|
||
export function themeFnRE(directiveName: string) { | ||
return new RegExp(`${directiveName}\\((.*?)\\)`, 'g') | ||
} | ||
export async function parseTheme(root: Root, uno: UnoGenerator, directiveName: string) { | ||
export async function parseTheme(root: Root, uno: UnoGenerator) { | ||
root.walkDecls((decl) => { | ||
const matches = Array.from(decl.value.matchAll(themeFnRE(directiveName))) | ||
|
||
if (!matches.length) | ||
return | ||
|
||
for (const match of matches) { | ||
const rawArg = match[1].trim() | ||
if (!rawArg) | ||
throw new Error(`${directiveName}() expect exact one argument, but got 0`) | ||
|
||
const [rawKey, alpha] = rawArg.slice(1, -1).split('/') as [string, string?] | ||
let value: any = uno.config.theme | ||
const keys = rawKey.trim().split('.') | ||
|
||
keys.every((key) => { | ||
if (value[key] != null) | ||
value = value[key] | ||
else if (value[+key] != null) | ||
value = value[+key] | ||
else | ||
return false | ||
return true | ||
}) | ||
|
||
if (typeof value === 'string') { | ||
if (alpha) { | ||
const color = parseCssColor(value) | ||
if (color) | ||
value = colorToString(color, alpha) | ||
} | ||
const code = new MagicString(decl.value) | ||
code.overwrite( | ||
match.index!, | ||
match.index! + match[0].length, | ||
value, | ||
) | ||
decl.value = code.toString() | ||
} | ||
} | ||
decl.value = transformThemeFn(decl.value, uno.config.theme) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import MagicString from 'magic-string' | ||
import { colorToString, parseCssColor } from './colors' | ||
|
||
export const themeFnRE = /theme\(\s*['"]?(.*?)['"]?\s*\)/g | ||
|
||
export function hasThemeFn(str: string) { | ||
return str.includes('theme(') && str.includes(')') | ||
} | ||
|
||
export function transformThemeFn(code: string, theme: Record<string, any>, throwOnMissing = true) { | ||
const matches = Array.from(code.toString().matchAll(themeFnRE)) | ||
|
||
if (!matches.length) | ||
return code | ||
|
||
const s = new MagicString(code) | ||
|
||
for (const match of matches) { | ||
const rawArg = match[1] | ||
if (!rawArg) | ||
throw new Error('theme() expect exact one argument, but got 0') | ||
|
||
const [rawKey, alpha] = rawArg.split('/') as [string, string?] | ||
const keys = rawKey.trim().split('.') | ||
let value = keys.reduce((t, k) => t?.[k], theme) as unknown as string | undefined | ||
|
||
if (typeof value === 'string') { | ||
if (alpha) { | ||
const color = parseCssColor(value) | ||
if (color) | ||
value = colorToString(color, alpha) | ||
} | ||
|
||
s.overwrite( | ||
match.index!, | ||
match.index! + match[0].length, | ||
value, | ||
) | ||
} | ||
else if (throwOnMissing) { | ||
throw new Error(`theme of "${rawArg}" did not found`) | ||
} | ||
} | ||
|
||
return s.toString() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,12 @@ | ||
import type { Declaration } from 'css-tree' | ||
import { colorToString, parseCssColor } from '@unocss/rule-utils' | ||
import { transformThemeFn } from '@unocss/rule-utils' | ||
import type { TransformerDirectivesContext } from '.' | ||
|
||
export const themeFnRE = /theme\((.*?)\)/g | ||
|
||
export function handleThemeFn({ code, uno, options }: TransformerDirectivesContext, node: Declaration) { | ||
const { throwOnMissing = true } = options | ||
|
||
const offset = node.value.loc!.start.offset | ||
const str = code.original.slice(offset, node.value.loc!.end.offset) | ||
const matches = Array.from(str.matchAll(themeFnRE)) | ||
|
||
if (!matches.length) | ||
return | ||
|
||
for (const match of matches) { | ||
const rawArg = match[1].trim() | ||
if (!rawArg) | ||
throw new Error('theme() expect exact one argument, but got 0') | ||
|
||
const [rawKey, alpha] = rawArg.slice(1, -1).split('/') as [string, string?] | ||
let value: any = uno.config.theme | ||
const keys = rawKey.trim().split('.') | ||
|
||
keys.every((key) => { | ||
if (value[key] != null) | ||
value = value[key] | ||
else if (value[+key] != null) | ||
value = value[+key] | ||
else | ||
return false | ||
return true | ||
}) | ||
|
||
if (typeof value === 'string') { | ||
if (alpha) { | ||
const color = parseCssColor(value) | ||
if (color) | ||
value = colorToString(color, alpha) | ||
} | ||
|
||
code.overwrite( | ||
offset + match.index!, | ||
offset + match.index! + match[0].length, | ||
value, | ||
) | ||
} | ||
else if (throwOnMissing) { | ||
throw new Error(`theme of "${rawArg.slice(1, -1)}" did not found`) | ||
} | ||
} | ||
code.overwrite(offset, node.value.loc!.end.offset, transformThemeFn(str, uno.config.theme, throwOnMissing)) | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters