Skip to content

Commit

Permalink
feat(postprocess): createFilter for add important
Browse files Browse the repository at this point in the history
  • Loading branch information
zyyv committed Dec 26, 2024
1 parent 343a5cc commit 81b7c47
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 61 deletions.
32 changes: 32 additions & 0 deletions packages/core/src/core/postprocess/important.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { Postprocessor } from '@unocss/core'
import type { FilterPattern, ImportantOptions } from '../../types'
import { toArray } from '@unocss/core'

function createFilter(
include: FilterPattern,
exclude: FilterPattern,
): (id: string) => boolean {
const includePattern = toArray(include || [])
const excludePattern = toArray(exclude || [])
return (id: string) => {
if (excludePattern.some(p => id.match(p)))
return false
return includePattern.some(p => id.match(p))
}
}

export function importantProcess(importantOptions: ImportantOptions): Postprocessor {
console.log(importantOptions)

Check failure on line 19 in packages/core/src/core/postprocess/important.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement

const keyFilter = createFilter(importantOptions.includes || [], importantOptions.excludes || [])

return (util) => {
for (const item of util.entries) {
console.log(item[0], keyFilter(item[0]))

Check failure on line 25 in packages/core/src/core/postprocess/important.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement

if (keyFilter(item[0]) && item[1] != null && !String(item[1]).includes('!important')) {
item[1] += ' !important'
}
}
}
}
13 changes: 13 additions & 0 deletions packages/core/src/core/postprocess/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Postprocessor } from '@unocss/core'
import type { ImportantOptions, ResolvedOptions } from '../../types'
import { importantProcess } from './important'
import { postprocessWithUnColor } from './uncolor'

export function postprocess(options: ResolvedOptions): Postprocessor[] {
const { unColor, important } = options

return [
unColor ? postprocessWithUnColor(unColor as string) : undefined,
important ? importantProcess(important as ImportantOptions) : undefined,
].filter(Boolean) as Postprocessor[]
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { Postprocessor } from '@unocss/core'
const rgbRE = /rgb\(([\d\s]+?)\s*\/\s*([^)]+)\)/
const rgbaRE = /rgba\(([\d\s,]+),\s*([^)]+)\)/

// IN-README-START
// https://github.com/unocss/unocss/discussions/2816
// Extract rgba color in css variable.
export function postprocessWithUnColor(unColor: string): Postprocessor {
Expand All @@ -27,13 +26,3 @@ export function postprocessWithUnColor(unColor: string): Postprocessor {
})
}
}

export function importantProcess(): Postprocessor {
return (util) => {
util.entries.forEach((i) => {
if (i[1] != null && !String(i[1]).includes('!important'))
i[1] += ' !important'
})
}
}
// IN-README-END
12 changes: 4 additions & 8 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { Postprocessor, Shortcut, UserConfig } from '@unocss/core'
import type { Shortcut, UserConfig } from '@unocss/core'
import type { UsefulOptions, UsefulTheme } from './types'
import { definePreset, mergeConfigs } from '@unocss/core'
import { extractors, preflights, rules, shortcuts, variants } from './core'
import { importantProcess, postprocessWithUnColor } from './core/postprocess'
import { extractors, postprocess, preflights, rules, shortcuts, variants } from './core'
import { PRESET_NAME } from './meta'
import { resolveOptions } from './resolve'

Expand All @@ -12,7 +11,7 @@ export type { UsefulOptions, UsefulTheme }

export const presetUseful = definePreset<UsefulOptions, UsefulTheme>(async (options) => {
const resolvedOptions = await resolveOptions(options ?? {})
const { enableDefaultShortcuts, unColor, theme, meta, important } = resolvedOptions
const { enableDefaultShortcuts, theme, meta } = resolvedOptions

return {
name: `unocss-preset-${PRESET_NAME}`,
Expand All @@ -24,10 +23,7 @@ export const presetUseful = definePreset<UsefulOptions, UsefulTheme>(async (opti
variants: variants(resolvedOptions),
shortcuts: [...enableDefaultShortcuts ? shortcuts : [], ...meta.shortcuts] as Shortcut[],
extractors,
postprocess: [
unColor ? postprocessWithUnColor(unColor as string) : undefined,
important ? importantProcess() : undefined,
].filter(Boolean) as Postprocessor[],
postprocess: postprocess(resolvedOptions),
presets: meta.presets,
transformers: meta.transformers,
preflights: preflights(resolvedOptions),
Expand Down
90 changes: 52 additions & 38 deletions packages/core/src/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,44 +48,10 @@ export async function resolveOptions(options: UsefulOptions) {
? optionsWithDefault.unColor
: optionsWithDefault.unColor ? '--un-color' : false

const presets = []
const transformers = []
const presetMap = {
uno: import('@unocss/preset-uno').then(m => m.presetUno),
attributify: import('@unocss/preset-attributify').then(m => m.presetAttributify),
icons: import('@unocss/preset-icons').then(m => m.presetIcons),
webFonts: import('@unocss/preset-web-fonts').then(m => m.presetWebFonts),
typography: import('@unocss/preset-typography').then(m => m.presetTypography),
tagify: import('@unocss/preset-tagify').then(m => m.presetTagify),
remToPx: import('@unocss/preset-rem-to-px').then(m => m.default),
scrollbar: import('unocss-preset-scrollbar').then(m => m.presetScrollbar),
magicss: import('unocss-preset-magicss').then(m => m.presetMagicss),
}
const transformerMap = {
directives: import('unocss').then(m => m.transformerDirectives),
variantGroup: import('unocss').then(m => m.transformerVariantGroup),
compileClass: import('unocss').then(m => m.transformerCompileClass),
}

for (const [key, preset] of Object.entries(presetMap)) {
const option = optionsWithDefault[key as keyof typeof presetMap]
if (option) {
const p = await preset as any
const presetOptions = defaultPresetOptions[key as keyof typeof defaultPresetOptions]
if (typeof option === 'object')
presets.push(p({ ...presetOptions, ...option }))
else
presets.push(p(presetOptions ?? {}))
}
}
for (const [key, transformer] of Object.entries(transformerMap)) {
const option = optionsWithDefault[key as keyof typeof transformerMap]
if (option) {
const t = await transformer as any
transformers.push(t(typeof option === 'boolean' ? {} as any : option))
}
}
optionsWithDefault.important = optionsWithDefault.important === true ? { excludes: [] } : optionsWithDefault.important

const presets = await resolvePresets(optionsWithDefault)
const transformers = await resolveTransformers(optionsWithDefault)
const { theme: t_theme, shortcuts } = resolveExtend(optionsWithDefault.theme.extend ?? {})
const _theme = deepMerge(optionsWithDefault.theme, t_theme)

Expand All @@ -100,7 +66,7 @@ export async function resolveOptions(options: UsefulOptions) {
} as ResolvedOptions
}

export function resolveExtend(extend: UsefulTheme['extend']) {
function resolveExtend(extend: UsefulTheme['extend']) {
const _shortcuts: CustomStaticShortcuts = []
const { animation, keyframes } = extend!

Expand All @@ -118,3 +84,51 @@ export function resolveExtend(extend: UsefulTheme['extend']) {
shortcuts: _shortcuts,
}
}

async function resolvePresets(options: Required<UsefulOptions>) {
const presets = []
const presetMap = {
uno: import('@unocss/preset-uno').then(m => m.presetUno),
attributify: import('@unocss/preset-attributify').then(m => m.presetAttributify),
icons: import('@unocss/preset-icons').then(m => m.presetIcons),
webFonts: import('@unocss/preset-web-fonts').then(m => m.presetWebFonts),
typography: import('@unocss/preset-typography').then(m => m.presetTypography),
tagify: import('@unocss/preset-tagify').then(m => m.presetTagify),
remToPx: import('@unocss/preset-rem-to-px').then(m => m.default),
scrollbar: import('unocss-preset-scrollbar').then(m => m.presetScrollbar),
magicss: import('unocss-preset-magicss').then(m => m.presetMagicss),
}

for (const [key, preset] of Object.entries(presetMap)) {
const option = options[key as keyof typeof presetMap]
if (option) {
const p = await preset as any
const presetOptions = defaultPresetOptions[key as keyof typeof defaultPresetOptions]
if (typeof option === 'object')
presets.push(p({ ...presetOptions, ...option }))
else
presets.push(p(presetOptions ?? {}))
}
}

return presets
}

async function resolveTransformers(options: Required<UsefulOptions>) {
const transformers = []
const transformerMap = {
directives: import('unocss').then(m => m.transformerDirectives),
variantGroup: import('unocss').then(m => m.transformerVariantGroup),
compileClass: import('unocss').then(m => m.transformerCompileClass),
}

for (const [key, transformer] of Object.entries(transformerMap)) {
const option = options[key as keyof typeof transformerMap]
if (option) {
const t = await transformer as any
transformers.push(t(typeof option === 'boolean' ? {} as any : option))
}
}

return transformers
}
18 changes: 17 additions & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,29 @@ interface PreflightOptions {
reset?: boolean
}

export type FilterPattern = Array<string | RegExp> | string | RegExp | null

export interface ImportantOptions {
/**
* Make all unitilities important.
*
*/
includes?: FilterPattern

/**
* Make all unitilities important.
*
*/
excludes?: FilterPattern
}

export interface UsefulOptions {
/**
* Make all unitilities important.
*
* @default false
*/
important?: boolean
important?: boolean | ImportantOptions

/**
* Enable default shortcuts
Expand Down
5 changes: 2 additions & 3 deletions test/postprocess.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,15 @@ describe('presetUseful postprocess with unColor', () => {
})

describe('presetUseful postprocess with important', () => {
const withOutImport = ['bg-red', 'text-blue']
const withInImport = ['!text-xl', 'sm:text-sm!', 'important-ma']
const tokens = ['bg-red', 'text-blue', '!text-xl', 'sm:text-sm!', 'important-ma']

it('base', async () => {
const uno = await generateUno({
important: true,
preflights: false,
})

const { css } = await uno.generate([...withInImport, ...withOutImport])
const { css } = await uno.generate(tokens)

expect(css).toMatchInlineSnapshot(`
"/* layer: default */
Expand Down

0 comments on commit 81b7c47

Please sign in to comment.