Skip to content

Commit

Permalink
feat(core)!: support string in rule that returns array (#1093)
Browse files Browse the repository at this point in the history
  • Loading branch information
chu121su12 committed Jun 12, 2022
1 parent 0c861eb commit 44313e8
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 70 deletions.
66 changes: 47 additions & 19 deletions packages/core/src/generator/index.ts
@@ -1,5 +1,5 @@
import { createNanoEvents } from '../utils/events'
import type { CSSEntries, CSSObject, ExtractorContext, GenerateOptions, GenerateResult, ParsedUtil, PreflightContext, RawUtil, ResolvedConfig, Rule, RuleContext, RuleMeta, Shortcut, StringifiedUtil, UserConfig, UserConfigDefaults, UtilObject, Variant, VariantContext, VariantHandler, VariantMatchedResult } from '../types'
import type { CSSEntries, CSSObject, ExtractorContext, GenerateOptions, GenerateResult, ParsedUtil, PreflightContext, PreparedRule, RawUtil, ResolvedConfig, Rule, RuleContext, RuleMeta, Shortcut, StringifiedUtil, UserConfig, UserConfigDefaults, UtilObject, Variant, VariantContext, VariantHandler, VariantMatchedResult } from '../types'
import { resolveConfig } from '../config'
import { CONTROL_SHORTCUT_NO_MERGE, TwoKeyMap, e, entriesToCss, expandVariantGroup, isRawUtil, isStaticShortcut, noop, normalizeCSSEntries, normalizeCSSValues, notNull, uniq, warnOnce } from '../utils'
import { version } from '../../package.json'
Expand Down Expand Up @@ -219,28 +219,44 @@ export class UnoGenerator {
.sort((a, b) => ((this.parentOrders.get(a[0]) ?? 0) - (this.parentOrders.get(b[0]) ?? 0)) || a[0]?.localeCompare(b[0] || '') || 0)
.map(([parent, items]) => {
const size = items.length
const sorted = items
const sorted: PreparedRule[] = items
.filter(i => (i[4]?.layer || 'default') === layer)
.sort((a, b) => a[0] - b[0] || (a[4]?.sort || 0) - (b[4]?.sort || 0) || a[1]?.localeCompare(b[1] || '') || 0)
.map(a => [a[1] ? applyScope(a[1], scope) : a[1], a[2], !!a[4]?.noMerge])
.map(a => [a[0] == null ? a[0] : [a[0]], a[1], a[2]]) as [string[] | undefined, string, boolean][]
.sort((a, b) => a[0] - b[0] || (a[4]?.sort || 0) - (b[4]?.sort || 0) || a[1]?.localeCompare(b[1] || '') || a[2]?.localeCompare(b[2] || '') || 0)
.map(([, selector, body,, meta]) => {
const scopedSelector = selector ? applyScope(selector, scope) : selector
return [
[[scopedSelector ?? '', meta?.sort ?? 0]],
body,
!!meta?.noMerge,
]
})
if (!sorted.length)
return undefined
const rules = sorted
.reverse()
.map(([selector, body, noMerge], idx) => {
if (!noMerge && selector && this.config.mergeSelectors) {
.map(([selectorSortPair, body, noMerge], idx) => {
if (!noMerge && this.config.mergeSelectors) {
// search for rules that has exact same body, and merge them
for (let i = idx + 1; i < size; i++) {
const current = sorted[i]
if (current && !current[2] && current[0] && current[1] === body) {
current[0].push(...selector)
if (current && !current[2] && ((selectorSortPair && current[0]) || (selectorSortPair == null && current[0] == null)) && current[1] === body) {
if (selectorSortPair && current[0])
current[0].push(...selectorSortPair)
return null
}
}
}
return selector
? `${[...new Set(selector)].join(`,${nl}`)}{${body}}`

const selectors = selectorSortPair
? [...new Set(selectorSortPair
.sort((a, b) => a[1] - b[1] || a[0]?.localeCompare(b[0] || '') || 0)
.map(pair => pair[0])
.filter(Boolean),
)]
: []

return selectors.length
? `${selectors.join(`,${nl}`)}{${body}}`
: body
})
.filter(Boolean)
Expand Down Expand Up @@ -341,16 +357,18 @@ export class UnoGenerator {
}

constructCustomCSS(context: Readonly<RuleContext>, body: CSSObject | CSSEntries, overrideSelector?: string) {
body = normalizeCSSEntries(body)
const normalizedBody = normalizeCSSEntries(body)
if (typeof normalizedBody === 'string')
return normalizedBody

const { selector, entries, parent } = this.applyVariants([0, overrideSelector || context.rawSelector, body, undefined, context.variantHandlers])
const { selector, entries, parent } = this.applyVariants([0, overrideSelector || context.rawSelector, normalizedBody, undefined, context.variantHandlers])
const cssBody = `${selector}{${entriesToCss(entries)}}`
if (parent)
return `${parent}{${cssBody}}`
return cssBody
}

async parseUtil(input: string | VariantMatchedResult, context: RuleContext, internal = false): Promise<ParsedUtil[] | RawUtil[] | undefined> {
async parseUtil(input: string | VariantMatchedResult, context: RuleContext, internal = false): Promise<(ParsedUtil | RawUtil)[] | undefined> {
const [raw, processed, variantHandlers] = typeof input === 'string'
? this.matchVariants(input)
: input
Expand All @@ -367,7 +385,13 @@ export class UnoGenerator {
if (staticMatch) {
if (staticMatch[1] && (internal || !staticMatch[2]?.internal)) {
recordRule(staticMatch[3])
return [[staticMatch[0], raw, normalizeCSSEntries(staticMatch[1]), staticMatch[2], variantHandlers]]
const index = staticMatch[0]
const entry = normalizeCSSEntries(staticMatch[1])
const meta = staticMatch[2]
if (typeof entry === 'string')
return [[index, entry, meta]]
else
return [[index, raw, entry, meta, variantHandlers]]
}
}

Expand Down Expand Up @@ -399,11 +423,15 @@ export class UnoGenerator {

recordRule(rule)

if (typeof result === 'string')
return [[i, result, meta]]
const entries = normalizeCSSValues(result).filter(i => i.length)
if (entries.length)
return entries.map(e => [i, raw, e, meta, variantHandlers])
if (entries.length) {
return entries.map((e) => {
if (typeof e === 'string')
return [i, e, meta]
else
return [i, raw, e, meta, variantHandlers]
})
}
}
}

Expand Down
11 changes: 9 additions & 2 deletions packages/core/src/types.ts
Expand Up @@ -164,9 +164,10 @@ export interface RuleMeta {
internal?: boolean
}

export type CSSValues = CSSObject | CSSEntries | (CSSObject | CSSEntries)[]
export type CSSValue = CSSObject | CSSEntries
export type CSSValues = CSSValue | CSSValue[]

export type DynamicMatcher<Theme extends {} = {}> = ((match: RegExpMatchArray, context: Readonly<RuleContext<Theme>>) => Awaitable<CSSValues | string | undefined>)
export type DynamicMatcher<Theme extends {} = {}> = ((match: RegExpMatchArray, context: Readonly<RuleContext<Theme>>) => Awaitable<CSSValue | string | (CSSValue | string)[] | undefined>)
export type DynamicRule<Theme extends {} = {}> = [RegExp, DynamicMatcher<Theme>] | [RegExp, DynamicMatcher<Theme>, RuleMeta]
export type StaticRule = [string, CSSObject | CSSEntries] | [string, CSSObject | CSSEntries, RuleMeta]
export type Rule<Theme extends {} = {}> = DynamicRule<Theme> | StaticRule
Expand Down Expand Up @@ -599,6 +600,12 @@ export type StringifiedUtil = readonly [
context: RuleContext | undefined,
]

export type PreparedRule = readonly [
selector: [string, number][],
body: string,
noMerge: boolean,
]

export interface UtilObject {
selector: string
entries: CSSEntries
Expand Down
12 changes: 7 additions & 5 deletions packages/core/src/utils/object.ts
@@ -1,16 +1,18 @@
import type { CSSEntries, CSSObject, CSSValues, DeepPartial, Rule, Shortcut, StaticRule, StaticShortcut } from '../types'
import type { CSSEntries, CSSObject, CSSValue, DeepPartial, Rule, Shortcut, StaticRule, StaticShortcut } from '../types'

export function normalizeCSSEntries(obj: CSSEntries | CSSObject): CSSEntries {
export function normalizeCSSEntries(obj: string | CSSEntries | CSSObject): string | CSSEntries {
if (typeof obj === 'string')
return obj
return (!Array.isArray(obj) ? Object.entries(obj) : obj).filter(i => i[1] != null)
}

export function normalizeCSSValues(obj: CSSValues): CSSEntries[] {
export function normalizeCSSValues(obj: CSSValue | string | (CSSValue | string)[]): (string | CSSEntries)[] {
if (Array.isArray(obj)) {
// @ts-expect-error type cast
if (obj.find(i => !Array.isArray(i) || Array.isArray(i[0])))
return (obj as any).map((i: any) => normalizeCSSEntries(i))
return (obj as (string | CSSValue)[]).map(i => normalizeCSSEntries(i))
else
return [obj as any]
return [obj as CSSEntries]
}
else {
return [normalizeCSSEntries(obj)]
Expand Down
23 changes: 16 additions & 7 deletions packages/preset-wind/src/rules/animation.ts
Expand Up @@ -3,21 +3,30 @@ import { handler as h } from '@unocss/preset-mini/utils'
import type { Theme } from '@unocss/preset-mini'

export const animations: Rule<Theme>[] = [
[/^(?:animate-)?keyframes-(.+)$/, ([, name], { theme, constructCSS }) => {
[/^(?:animate-)?keyframes-(.+)$/, ([, name], { theme }) => {
const kf = theme.animation?.keyframes?.[name]
if (kf)
return `@keyframes ${name}${kf}\n${constructCSS({ animation: `${name}` })}`
if (kf) {
return [
`@keyframes ${name}${kf}`,
{ animation: name },
]
}
}, { autocomplete: ['animate-keyframes-$animation.keyframes', 'keyframes-$animation.keyframes'] }],

[/^animate-(.+)$/, ([, name], { theme, constructCSS }) => {
[/^animate-(.+)$/, ([, name], { theme }) => {
const kf = theme.animation?.keyframes?.[name]
if (kf) {
const duration = theme.animation?.durations?.[name] ?? '1s'
const timing = theme.animation?.timingFns?.[name] ?? 'linear'
const props = theme.animation?.properties?.[name]
const count = theme.animation?.counts?.[name] ?? 1
return `@keyframes ${name}${kf}\n${constructCSS(
Object.assign({ animation: `${name} ${duration} ${timing} ${count}` }, props))}`
const props = theme.animation?.properties?.[name]
return [
`@keyframes ${name}${kf}`,
{
animation: `${name} ${duration} ${timing} ${count}`,
...props,
},
]
}
return { animation: h.bracket.cssvar(name) }
}, { autocomplete: 'animate-$animation.keyframes' }],
Expand Down
2 changes: 1 addition & 1 deletion test/__snapshots__/layer.test.ts.snap
Expand Up @@ -10,8 +10,8 @@ exports[`layers > static 1`] = `
/* layer: c */
.c5{name:5;}
/* layer: d */
/* RAW 4 */
/* RAW 3 */
/* RAW 4 */
/* layer: s */
.abcd{name:bar1;name:bar2;name:2;}"
`;
10 changes: 10 additions & 0 deletions test/__snapshots__/order.test.ts.snap
@@ -1,5 +1,15 @@
// Vitest Snapshot v1

exports[`order > fully controlled rules merged and sorted by body 1`] = `
"/* layer: default */
.uno{--var:uno;}
/* sort: css */ .foo{--foo:0}
/* sort: uno */ .foo{--foo:0}
.bar-css{--bar:css;}
.bar-uno{--bar:uno;}
.css{--var:css;}"
`;

exports[`order > movePseudoElementsEnd 1`] = `".marker\\\\:file\\\\:hover\\\\:selection\\\\:mb-4:hover::marker::file-selector-button::selection"`;

exports[`order > multiple variant sorting 1`] = `
Expand Down
20 changes: 10 additions & 10 deletions test/__snapshots__/preset-attributify.test.ts.snap
Expand Up @@ -41,37 +41,37 @@ exports[`attributify > autocomplete extractor 5`] = `
exports[`attributify > compatible with full controlled rules 1`] = `
"/* layer: default */
[custom~=\\"\\\\31 \\"] {
font-size: 1px;
.custom-2 {
font-size: 2px;
}
/* you can have multiple rules */
[custom~=\\"\\\\31 \\"]::after {
.custom-2::after {
content: 'after';
}
.foo > [custom~=\\"\\\\31 \\"] {
.foo > .custom-2 {
color: red;
}
/* or media queries */
@media (min-width: 680px) {
[custom~=\\"\\\\31 \\"] {
.custom-2 {
font-size: 16px;
}
}
.custom-2 {
font-size: 2px;
[custom~=\\"\\\\31 \\"] {
font-size: 1px;
}
/* you can have multiple rules */
.custom-2::after {
[custom~=\\"\\\\31 \\"]::after {
content: 'after';
}
.foo > .custom-2 {
.foo > [custom~=\\"\\\\31 \\"] {
color: red;
}
/* or media queries */
@media (min-width: 680px) {
.custom-2 {
[custom~=\\"\\\\31 \\"] {
font-size: 16px;
}
}
Expand Down
12 changes: 6 additions & 6 deletions test/__snapshots__/preset-mini.test.ts.snap
Expand Up @@ -409,10 +409,10 @@ div:hover .group-\\\\[div\\\\:hover\\\\]-\\\\[combinator\\\\:test-4\\\\]{combina
.text-rose{--un-text-opacity:1;color:rgba(251,113,133,var(--un-text-opacity));}
.placeholder-color-opacity-60::placeholder{--un-text-opacity:0.6;}
.text-opacity-\\\\[13\\\\.3333333\\\\%\\\\]{--un-text-opacity:13.3333333%;}
.italic,
.font-italic{font-style:italic;}
.oblique,
.font-oblique{font-style:oblique;}
.font-italic,
.italic{font-style:italic;}
.font-oblique,
.oblique{font-style:oblique;}
.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smoothing:grayscale;}
.shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color, rgba(0,0,0,0.1)),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color, rgba(0,0,0,0.1));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}
.shadow-none{--un-shadow:0 0 var(--un-shadow-color, rgba(0,0,0,0));box-shadow:var(--un-ring-offset-shadow, 0 0 #0000), var(--un-ring-shadow, 0 0 #0000), var(--un-shadow);}
Expand Down Expand Up @@ -678,8 +678,8 @@ div:hover .group-\\\\[div\\\\:hover\\\\]-\\\\[combinator\\\\:test-4\\\\]{combina
.float-none{float:none;}
.clear-both{clear:both;}
.clear-none{clear:none;}
.z0,
.z-0{z-index:0;}
.z-0,
.z0{z-index:0;}
.-z-1{z-index:-1;}
.z-\\\\$variable{z-index:var(--variable);}
.z-1{z-index:1;}
Expand Down
20 changes: 8 additions & 12 deletions test/__snapshots__/preset-wind.test.ts.snap
Expand Up @@ -66,23 +66,19 @@ exports[`preset-wind > targets 1`] = `
.table-auto{table-layout:auto;}
.table-empty-cells-visible{empty-cells:show;}
.table-empty-cells-hidden{empty-cells:hide;}
@keyframes pulse-alt{from{transform:scale3d(1,1,1)}50%{transform:scale3d(1.05,1.05,1.05)}to{transform:scale3d(1,1,1)}}
@keyframes pulse{0%, 100% {opacity:1} 50% {opacity:.5}}
.animate-keyframes-pulse,
.keyframes-pulse{animation:pulse;}
@keyframes pulse-alt{from{transform:scale3d(1,1,1)}50%{transform:scale3d(1.05,1.05,1.05)}to{transform:scale3d(1,1,1)}}
.animate-keyframes-pulse-alt,
.keyframes-pulse-alt{animation:pulse-alt;}
@keyframes pulse{0%, 100% {opacity:1} 50% {opacity:.5}}
.animate-keyframes-pulse{animation:pulse;}
@keyframes pulse-alt{from{transform:scale3d(1,1,1)}50%{transform:scale3d(1.05,1.05,1.05)}to{transform:scale3d(1,1,1)}}
.animate-keyframes-pulse-alt{animation:pulse-alt;}
@keyframes pulse{0%, 100% {opacity:1} 50% {opacity:.5}}
.animate-pulse{animation:pulse 2s cubic-bezier(0.4,0,.6,1) infinite;}
@keyframes pulse-alt{from{transform:scale3d(1,1,1)}50%{transform:scale3d(1.05,1.05,1.05)}to{transform:scale3d(1,1,1)}}
.animate-pulse-alt{animation:pulse-alt 1s ease-in-out infinite;}
.animate-\\\\[4s_linear_0s_infinite_alternate_move\\\\\\\\_eye\\\\]{animation:4s linear 0s infinite alternate move\\\\_eye;}
.animate-\\\\$variable{animation:var(--variable);}
@keyframes bounce{0%, 100% {transform:translateY(-25%);animation-timing-function:cubic-bezier(0.8,0,1,1)} 50% {transform:translateY(0);animation-timing-function:cubic-bezier(0,0,0.2,1)}}
@keyframes ping{0%{transform:scale(1);opacity:1}75%,100%{transform:scale(2);opacity:0}}
.\\\\!animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite !important;}
@keyframes bounce{0%, 100% {transform:translateY(-25%);animation-timing-function:cubic-bezier(0.8,0,1,1)} 50% {transform:translateY(0);animation-timing-function:cubic-bezier(0,0,0.2,1)}}
.animate-\\\\[4s_linear_0s_infinite_alternate_move\\\\\\\\_eye\\\\]{animation:4s linear 0s infinite alternate move\\\\_eye;}
.animate-\\\\$variable{animation:var(--variable);}
.animate-pulse{animation:pulse 2s cubic-bezier(0.4,0,.6,1) infinite;}
.animate-pulse-alt{animation:pulse-alt 1s ease-in-out infinite;}
.hover\\\\:animate-bounce:hover{animation:bounce 1s linear infinite;}
.animate-name-move{animation-name:move;}
.animate-duration-\\\\$variable{animation-duration:var(--variable);}
Expand Down
4 changes: 2 additions & 2 deletions test/__snapshots__/selector-no-merge.test.ts.snap
Expand Up @@ -2,8 +2,8 @@

exports[`selector > rules split selector 1`] = `
"/* layer: default */
.to-merge,
.merge-candidate{merged:1;}
.merge-candidate,
.to-merge{merged:1;}
.not-merged{merged:1;}"
`;

Expand Down
11 changes: 5 additions & 6 deletions test/__snapshots__/shortcuts.test.ts.snap
Expand Up @@ -4,10 +4,9 @@ exports[`shortcuts > animate 1`] = `
"/* layer: preflights */
*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x:var(--un-empty,/*!*/ /*!*/);--un-pan-y:var(--un-empty,/*!*/ /*!*/);--un-pinch-zoom:var(--un-empty,/*!*/ /*!*/);--un-scroll-snap-strictness:proximity;--un-ordinal:var(--un-empty,/*!*/ /*!*/);--un-slashed-zero:var(--un-empty,/*!*/ /*!*/);--un-numeric-figure:var(--un-empty,/*!*/ /*!*/);--un-numeric-spacing:var(--un-empty,/*!*/ /*!*/);--un-numeric-fraction:var(--un-empty,/*!*/ /*!*/);--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset:var(--un-empty,/*!*/ /*!*/);--un-shadow:0 0 #0000;--un-ring-inset:var(--un-empty,/*!*/ /*!*/);--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,0.5);--un-blur:var(--un-empty,/*!*/ /*!*/);--un-brightness:var(--un-empty,/*!*/ /*!*/);--un-contrast:var(--un-empty,/*!*/ /*!*/);--un-drop-shadow:var(--un-empty,/*!*/ /*!*/);--un-grayscale:var(--un-empty,/*!*/ /*!*/);--un-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-invert:var(--un-empty,/*!*/ /*!*/);--un-saturate:var(--un-empty,/*!*/ /*!*/);--un-sepia:var(--un-empty,/*!*/ /*!*/);--un-backdrop-blur:var(--un-empty,/*!*/ /*!*/);--un-backdrop-brightness:var(--un-empty,/*!*/ /*!*/);--un-backdrop-contrast:var(--un-empty,/*!*/ /*!*/);--un-backdrop-grayscale:var(--un-empty,/*!*/ /*!*/);--un-backdrop-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-invert:var(--un-empty,/*!*/ /*!*/);--un-backdrop-opacity:var(--un-empty,/*!*/ /*!*/);--un-backdrop-saturate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-sepia:var(--un-empty,/*!*/ /*!*/);}
/* layer: shortcuts */
.loading{transition-duration:1000ms;}
.loading{animation:spin 1s linear infinite;transition-duration:1000ms;}
/* layer: default */
@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
.loading{animation:spin 1s linear infinite;}"
@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}"
`;

exports[`shortcuts > dynamic 1`] = `
Expand Down Expand Up @@ -125,9 +124,9 @@ exports[`shortcuts > no-merge 1`] = `
"/* layer: preflights */
*,::before,::after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x:var(--un-empty,/*!*/ /*!*/);--un-pan-y:var(--un-empty,/*!*/ /*!*/);--un-pinch-zoom:var(--un-empty,/*!*/ /*!*/);--un-scroll-snap-strictness:proximity;--un-ordinal:var(--un-empty,/*!*/ /*!*/);--un-slashed-zero:var(--un-empty,/*!*/ /*!*/);--un-numeric-figure:var(--un-empty,/*!*/ /*!*/);--un-numeric-spacing:var(--un-empty,/*!*/ /*!*/);--un-numeric-fraction:var(--un-empty,/*!*/ /*!*/);--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 #0000;--un-ring-shadow:0 0 #0000;--un-shadow-inset:var(--un-empty,/*!*/ /*!*/);--un-shadow:0 0 #0000;--un-ring-inset:var(--un-empty,/*!*/ /*!*/);--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,0.5);--un-blur:var(--un-empty,/*!*/ /*!*/);--un-brightness:var(--un-empty,/*!*/ /*!*/);--un-contrast:var(--un-empty,/*!*/ /*!*/);--un-drop-shadow:var(--un-empty,/*!*/ /*!*/);--un-grayscale:var(--un-empty,/*!*/ /*!*/);--un-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-invert:var(--un-empty,/*!*/ /*!*/);--un-saturate:var(--un-empty,/*!*/ /*!*/);--un-sepia:var(--un-empty,/*!*/ /*!*/);--un-backdrop-blur:var(--un-empty,/*!*/ /*!*/);--un-backdrop-brightness:var(--un-empty,/*!*/ /*!*/);--un-backdrop-contrast:var(--un-empty,/*!*/ /*!*/);--un-backdrop-grayscale:var(--un-empty,/*!*/ /*!*/);--un-backdrop-hue-rotate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-invert:var(--un-empty,/*!*/ /*!*/);--un-backdrop-opacity:var(--un-empty,/*!*/ /*!*/);--un-backdrop-saturate:var(--un-empty,/*!*/ /*!*/);--un-backdrop-sepia:var(--un-empty,/*!*/ /*!*/);}
/* layer: default */
.with-no-merge{no-merge:1;}
.with-no-merge,
.merge-candidate{merged:1;}"
.merge-candidate,
.with-no-merge{merged:1;}
.with-no-merge{no-merge:1;}"
`;

exports[`shortcuts > static 1`] = `
Expand Down

0 comments on commit 44313e8

Please sign in to comment.