717 lines
23 KiB
Plaintext
717 lines
23 KiB
Plaintext
import { variantGetParameter, variantGetBracket, variantMatcher, variantParentMatcher, getBracket, getStringComponent } from '@unocss/rule-utils';
|
|
import { h, r as resolveBreakpoints, C as CONTROL_MINI_NO_NEGATIVE } from './shared/preset-mini.Stl9mkMB.mjs';
|
|
import { warnOnce, escapeRegExp, escapeSelector } from '@unocss/core';
|
|
|
|
const variantAria = {
|
|
name: "aria",
|
|
match(matcher, ctx) {
|
|
const variant = variantGetParameter("aria-", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest] = variant;
|
|
const aria = h.bracket(match) ?? ctx.theme.aria?.[match] ?? "";
|
|
if (aria) {
|
|
return {
|
|
matcher: rest,
|
|
selector: (s) => `${s}[aria-${aria}]`
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
function calcMaxWidthBySize(size) {
|
|
const value = size.match(/^-?[0-9]+\.?[0-9]*/)?.[0] || "";
|
|
const unit = size.slice(value.length);
|
|
if (unit === "px") {
|
|
const maxWidth = Number.parseFloat(value) - 0.1;
|
|
return Number.isNaN(maxWidth) ? size : `${maxWidth}${unit}`;
|
|
}
|
|
return `calc(${size} - 0.1px)`;
|
|
}
|
|
function variantBreakpoints() {
|
|
const regexCache = {};
|
|
return {
|
|
name: "breakpoints",
|
|
match(matcher, context) {
|
|
const variantEntries = (resolveBreakpoints(context) ?? []).map(({ point, size }, idx) => [point, size, idx]);
|
|
for (const [point, size, idx] of variantEntries) {
|
|
if (!regexCache[point])
|
|
regexCache[point] = new RegExp(`^((?:([al]t-|[<~]|max-))?${point}(?:${context.generator.config.separators.join("|")}))`);
|
|
const match = matcher.match(regexCache[point]);
|
|
if (!match)
|
|
continue;
|
|
const [, pre] = match;
|
|
const m = matcher.slice(pre.length);
|
|
if (m === "container")
|
|
continue;
|
|
const isLtPrefix = pre.startsWith("lt-") || pre.startsWith("<") || pre.startsWith("max-");
|
|
const isAtPrefix = pre.startsWith("at-") || pre.startsWith("~");
|
|
let order = 1e3;
|
|
if (isLtPrefix) {
|
|
order -= idx + 1;
|
|
return {
|
|
matcher: m,
|
|
handle: (input, next) => next({
|
|
...input,
|
|
parent: `${input.parent ? `${input.parent} $$ ` : ""}@media (max-width: ${calcMaxWidthBySize(size)})`,
|
|
parentOrder: order
|
|
})
|
|
};
|
|
}
|
|
order += idx + 1;
|
|
if (isAtPrefix && idx < variantEntries.length - 1) {
|
|
return {
|
|
matcher: m,
|
|
handle: (input, next) => next({
|
|
...input,
|
|
parent: `${input.parent ? `${input.parent} $$ ` : ""}@media (min-width: ${size}) and (max-width: ${calcMaxWidthBySize(variantEntries[idx + 1][1])})`,
|
|
parentOrder: order
|
|
})
|
|
};
|
|
}
|
|
return {
|
|
matcher: m,
|
|
handle: (input, next) => next({
|
|
...input,
|
|
parent: `${input.parent ? `${input.parent} $$ ` : ""}@media (min-width: ${size})`,
|
|
parentOrder: order
|
|
})
|
|
};
|
|
}
|
|
},
|
|
multiPass: true,
|
|
autocomplete: "(at-|lt-|max-|)$breakpoints:"
|
|
};
|
|
}
|
|
|
|
function scopeMatcher(name, combinator) {
|
|
return {
|
|
name: `combinator:${name}`,
|
|
match(matcher, ctx) {
|
|
if (!matcher.startsWith(name))
|
|
return;
|
|
const separators = ctx.generator.config.separators;
|
|
let body = variantGetBracket(`${name}-`, matcher, separators);
|
|
if (!body) {
|
|
for (const separator of separators) {
|
|
if (matcher.startsWith(`${name}${separator}`)) {
|
|
body = ["", matcher.slice(name.length + separator.length)];
|
|
break;
|
|
}
|
|
}
|
|
if (!body)
|
|
return;
|
|
}
|
|
let bracketValue = h.bracket(body[0]) ?? "";
|
|
if (bracketValue === "")
|
|
bracketValue = "*";
|
|
return {
|
|
matcher: body[1],
|
|
selector: (s) => `${s}${combinator}${bracketValue}`
|
|
};
|
|
},
|
|
multiPass: true
|
|
};
|
|
}
|
|
const variantCombinators = [
|
|
scopeMatcher("all", " "),
|
|
scopeMatcher("children", ">"),
|
|
scopeMatcher("next", "+"),
|
|
scopeMatcher("sibling", "+"),
|
|
scopeMatcher("siblings", "~")
|
|
];
|
|
|
|
const variantContainerQuery = {
|
|
name: "@",
|
|
match(matcher, ctx) {
|
|
if (matcher.startsWith("@container"))
|
|
return;
|
|
const variant = variantGetParameter("@", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest, label] = variant;
|
|
const unbracket = h.bracket(match);
|
|
let container;
|
|
if (unbracket) {
|
|
const minWidth = h.numberWithUnit(unbracket);
|
|
if (minWidth)
|
|
container = `(min-width: ${minWidth})`;
|
|
} else {
|
|
container = ctx.theme.containers?.[match] ?? "";
|
|
}
|
|
if (container) {
|
|
warnOnce("The container query variant is experimental and may not follow semver.");
|
|
return {
|
|
matcher: rest,
|
|
handle: (input, next) => next({
|
|
...input,
|
|
parent: `${input.parent ? `${input.parent} $$ ` : ""}@container${label ? ` ${label} ` : " "}${container}`
|
|
})
|
|
};
|
|
}
|
|
}
|
|
},
|
|
multiPass: true
|
|
};
|
|
|
|
function variantColorsMediaOrClass(options = {}) {
|
|
if (options?.dark === "class" || typeof options.dark === "object") {
|
|
const { dark = ".dark", light = ".light" } = typeof options.dark === "string" ? {} : options.dark;
|
|
return [
|
|
variantMatcher("dark", (input) => ({ prefix: `${dark} $$ ${input.prefix}` })),
|
|
variantMatcher("light", (input) => ({ prefix: `${light} $$ ${input.prefix}` }))
|
|
];
|
|
}
|
|
return [
|
|
variantParentMatcher("dark", "@media (prefers-color-scheme: dark)"),
|
|
variantParentMatcher("light", "@media (prefers-color-scheme: light)")
|
|
];
|
|
}
|
|
|
|
const variantDataAttribute = {
|
|
name: "data",
|
|
match(matcher, ctx) {
|
|
const variant = variantGetParameter("data-", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest] = variant;
|
|
const dataAttribute = h.bracket(match) ?? ctx.theme.data?.[match] ?? "";
|
|
if (dataAttribute) {
|
|
return {
|
|
matcher: rest,
|
|
selector: (s) => `${s}[data-${dataAttribute}]`
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const variantGroupDataAttribute = {
|
|
name: "group-data",
|
|
match(matcher, ctx) {
|
|
const variant = variantGetParameter("group-data-", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest] = variant;
|
|
const dataAttribute = h.bracket(match) ?? ctx.theme.data?.[match] ?? "";
|
|
if (dataAttribute) {
|
|
return {
|
|
matcher: `group-[[data-${dataAttribute}]]:${rest}`
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
const variantLanguageDirections = [
|
|
variantMatcher("rtl", (input) => ({ prefix: `[dir="rtl"] $$ ${input.prefix}` })),
|
|
variantMatcher("ltr", (input) => ({ prefix: `[dir="ltr"] $$ ${input.prefix}` }))
|
|
];
|
|
|
|
const variantSelector = {
|
|
name: "selector",
|
|
match(matcher, ctx) {
|
|
const variant = variantGetBracket("selector-", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest] = variant;
|
|
const selector = h.bracket(match);
|
|
if (selector) {
|
|
return {
|
|
matcher: rest,
|
|
selector: () => selector
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const variantCssLayer = {
|
|
name: "layer",
|
|
match(matcher, ctx) {
|
|
const variant = variantGetParameter("layer-", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest] = variant;
|
|
const layer = h.bracket(match) ?? match;
|
|
if (layer) {
|
|
return {
|
|
matcher: rest,
|
|
handle: (input, next) => next({
|
|
...input,
|
|
parent: `${input.parent ? `${input.parent} $$ ` : ""}@layer ${layer}`
|
|
})
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const variantInternalLayer = {
|
|
name: "uno-layer",
|
|
match(matcher, ctx) {
|
|
const variant = variantGetParameter("uno-layer-", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest] = variant;
|
|
const layer = h.bracket(match) ?? match;
|
|
if (layer) {
|
|
return {
|
|
matcher: rest,
|
|
layer
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const variantScope = {
|
|
name: "scope",
|
|
match(matcher, ctx) {
|
|
const variant = variantGetBracket("scope-", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest] = variant;
|
|
const scope = h.bracket(match);
|
|
if (scope) {
|
|
return {
|
|
matcher: rest,
|
|
selector: (s) => `${scope} $$ ${s}`
|
|
};
|
|
}
|
|
}
|
|
}
|
|
};
|
|
const variantVariables = {
|
|
name: "variables",
|
|
match(matcher, ctx) {
|
|
if (!matcher.startsWith("["))
|
|
return;
|
|
const [match, rest] = getBracket(matcher, "[", "]") ?? [];
|
|
if (!(match && rest))
|
|
return;
|
|
let newMatcher;
|
|
for (const separator of ctx.generator.config.separators) {
|
|
if (rest.startsWith(separator)) {
|
|
newMatcher = rest.slice(separator.length);
|
|
break;
|
|
}
|
|
}
|
|
if (newMatcher == null)
|
|
return;
|
|
const variant = h.bracket(match) ?? "";
|
|
const useParent = variant.startsWith("@");
|
|
if (!(useParent || variant.includes("&")))
|
|
return;
|
|
return {
|
|
matcher: newMatcher,
|
|
handle(input, next) {
|
|
const updates = useParent ? {
|
|
parent: `${input.parent ? `${input.parent} $$ ` : ""}${variant}`
|
|
} : {
|
|
selector: variant.replace(/&/g, input.selector)
|
|
};
|
|
return next({
|
|
...input,
|
|
...updates
|
|
});
|
|
}
|
|
};
|
|
},
|
|
multiPass: true
|
|
};
|
|
|
|
const numberRE = /[0-9.]+(?:[a-z]+|%)?/;
|
|
const ignoreProps = [
|
|
/opacity|color|flex/
|
|
];
|
|
function negateFunctions(value) {
|
|
const match = value.match(/^(calc|clamp|max|min)\s*(\(.*)/);
|
|
if (match) {
|
|
const [fnBody, rest] = getStringComponent(match[2], "(", ")", " ") ?? [];
|
|
if (fnBody)
|
|
return `calc(${match[1]}${fnBody} * -1)${rest ? ` ${rest}` : ""}`;
|
|
}
|
|
}
|
|
const variantNegative = {
|
|
name: "negative",
|
|
match(matcher) {
|
|
if (!matcher.startsWith("-"))
|
|
return;
|
|
return {
|
|
matcher: matcher.slice(1),
|
|
body: (body) => {
|
|
if (body.find((v) => v[0] === CONTROL_MINI_NO_NEGATIVE))
|
|
return;
|
|
let changed = false;
|
|
body.forEach((v) => {
|
|
const value = v[1]?.toString();
|
|
if (!value || value === "0")
|
|
return;
|
|
if (ignoreProps.some((i) => v[0].match(i)))
|
|
return;
|
|
const negated = negateFunctions(value);
|
|
if (negated) {
|
|
v[1] = negated;
|
|
changed = true;
|
|
} else if (numberRE.test(value)) {
|
|
v[1] = value.replace(numberRE, (i) => `-${i}`);
|
|
changed = true;
|
|
}
|
|
});
|
|
if (changed)
|
|
return body;
|
|
return [];
|
|
}
|
|
};
|
|
}
|
|
};
|
|
|
|
function variantImportant() {
|
|
let re;
|
|
return {
|
|
name: "important",
|
|
match(matcher, ctx) {
|
|
if (!re)
|
|
re = new RegExp(`^(important(?:${ctx.generator.config.separators.join("|")})|!)`);
|
|
let base;
|
|
const match = matcher.match(re);
|
|
if (match)
|
|
base = matcher.slice(match[0].length);
|
|
else if (matcher.endsWith("!"))
|
|
base = matcher.slice(0, -1);
|
|
if (base) {
|
|
return {
|
|
matcher: base,
|
|
body: (body) => {
|
|
body.forEach((v) => {
|
|
if (v[1])
|
|
v[1] += " !important";
|
|
});
|
|
return body;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
const variantPrint = variantParentMatcher("print", "@media print");
|
|
const variantCustomMedia = {
|
|
name: "media",
|
|
match(matcher, ctx) {
|
|
const variant = variantGetParameter("media-", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest] = variant;
|
|
let media = h.bracket(match) ?? "";
|
|
if (media === "")
|
|
media = ctx.theme.media?.[match] ?? "";
|
|
if (media) {
|
|
return {
|
|
matcher: rest,
|
|
handle: (input, next) => next({
|
|
...input,
|
|
parent: `${input.parent ? `${input.parent} $$ ` : ""}@media ${media}`
|
|
})
|
|
};
|
|
}
|
|
}
|
|
},
|
|
multiPass: true
|
|
};
|
|
|
|
const variantSupports = {
|
|
name: "supports",
|
|
match(matcher, ctx) {
|
|
const variant = variantGetParameter("supports-", matcher, ctx.generator.config.separators);
|
|
if (variant) {
|
|
const [match, rest] = variant;
|
|
let supports = h.bracket(match) ?? "";
|
|
if (supports === "")
|
|
supports = ctx.theme.supports?.[match] ?? "";
|
|
if (supports) {
|
|
return {
|
|
matcher: rest,
|
|
handle: (input, next) => next({
|
|
...input,
|
|
parent: `${input.parent ? `${input.parent} $$ ` : ""}@supports ${supports}`
|
|
})
|
|
};
|
|
}
|
|
}
|
|
},
|
|
multiPass: true
|
|
};
|
|
|
|
const PseudoClasses = Object.fromEntries([
|
|
// pseudo elements part 1
|
|
["first-letter", "::first-letter"],
|
|
["first-line", "::first-line"],
|
|
// location
|
|
"any-link",
|
|
"link",
|
|
"visited",
|
|
"target",
|
|
["open", "[open]"],
|
|
// forms
|
|
"default",
|
|
"checked",
|
|
"indeterminate",
|
|
"placeholder-shown",
|
|
"autofill",
|
|
"optional",
|
|
"required",
|
|
"valid",
|
|
"invalid",
|
|
"user-valid",
|
|
"user-invalid",
|
|
"in-range",
|
|
"out-of-range",
|
|
"read-only",
|
|
"read-write",
|
|
// content
|
|
"empty",
|
|
// interactions
|
|
"focus-within",
|
|
"hover",
|
|
"focus",
|
|
"focus-visible",
|
|
"active",
|
|
"enabled",
|
|
"disabled",
|
|
// tree-structural
|
|
"root",
|
|
"empty",
|
|
["even-of-type", ":nth-of-type(even)"],
|
|
["even", ":nth-child(even)"],
|
|
["odd-of-type", ":nth-of-type(odd)"],
|
|
["odd", ":nth-child(odd)"],
|
|
"first-of-type",
|
|
["first", ":first-child"],
|
|
"last-of-type",
|
|
["last", ":last-child"],
|
|
"only-child",
|
|
"only-of-type",
|
|
// pseudo elements part 2
|
|
["backdrop-element", "::backdrop"],
|
|
["placeholder", "::placeholder"],
|
|
["before", "::before"],
|
|
["after", "::after"],
|
|
["selection", "::selection"],
|
|
["marker", "::marker"],
|
|
["file", "::file-selector-button"]
|
|
].map((key) => Array.isArray(key) ? key : [key, `:${key}`]));
|
|
const PseudoClassesKeys = Object.keys(PseudoClasses);
|
|
const PseudoClassesColon = Object.fromEntries([
|
|
["backdrop", "::backdrop"]
|
|
].map((key) => Array.isArray(key) ? key : [key, `:${key}`]));
|
|
const PseudoClassesColonKeys = Object.keys(PseudoClassesColon);
|
|
const PseudoClassFunctions = [
|
|
"not",
|
|
"is",
|
|
"where",
|
|
"has"
|
|
];
|
|
const PseudoClassesStr = Object.entries(PseudoClasses).filter(([, pseudo]) => !pseudo.startsWith("::")).map(([key]) => key).sort((a, b) => b.length - a.length).join("|");
|
|
const PseudoClassesColonStr = Object.entries(PseudoClassesColon).filter(([, pseudo]) => !pseudo.startsWith("::")).map(([key]) => key).sort((a, b) => b.length - a.length).join("|");
|
|
const PseudoClassFunctionsStr = PseudoClassFunctions.join("|");
|
|
function taggedPseudoClassMatcher(tag, parent, combinator) {
|
|
const rawRE = new RegExp(`^(${escapeRegExp(parent)}:)(\\S+)${escapeRegExp(combinator)}\\1`);
|
|
let splitRE;
|
|
let pseudoRE;
|
|
let pseudoColonRE;
|
|
let pseudoVarRE;
|
|
const matchBracket = (input) => {
|
|
const body = variantGetBracket(`${tag}-`, input, []);
|
|
if (!body)
|
|
return;
|
|
const [match, rest] = body;
|
|
const bracketValue = h.bracket(match);
|
|
if (bracketValue == null)
|
|
return;
|
|
const label = rest.split(splitRE, 1)?.[0] ?? "";
|
|
const prefix = `${parent}${escapeSelector(label)}`;
|
|
return [
|
|
label,
|
|
input.slice(input.length - (rest.length - label.length - 1)),
|
|
bracketValue.includes("&") ? bracketValue.replace(/&/g, prefix) : `${prefix}${bracketValue}`
|
|
];
|
|
};
|
|
const matchPseudo = (input) => {
|
|
const match = input.match(pseudoRE) || input.match(pseudoColonRE);
|
|
if (!match)
|
|
return;
|
|
const [original, fn, pseudoKey] = match;
|
|
const label = match[3] ?? "";
|
|
let pseudo = PseudoClasses[pseudoKey] || PseudoClassesColon[pseudoKey] || `:${pseudoKey}`;
|
|
if (fn)
|
|
pseudo = `:${fn}(${pseudo})`;
|
|
return [
|
|
label,
|
|
input.slice(original.length),
|
|
`${parent}${escapeSelector(label)}${pseudo}`,
|
|
pseudoKey
|
|
];
|
|
};
|
|
const matchPseudoVar = (input) => {
|
|
const match = input.match(pseudoVarRE);
|
|
if (!match)
|
|
return;
|
|
const [original, fn, pseudoValue] = match;
|
|
const label = match[3] ?? "";
|
|
const pseudo = `:${fn}(${pseudoValue})`;
|
|
return [
|
|
label,
|
|
input.slice(original.length),
|
|
`${parent}${escapeSelector(label)}${pseudo}`
|
|
];
|
|
};
|
|
return {
|
|
name: `pseudo:${tag}`,
|
|
match(input, ctx) {
|
|
if (!(splitRE && pseudoRE && pseudoColonRE)) {
|
|
splitRE = new RegExp(`(?:${ctx.generator.config.separators.join("|")})`);
|
|
pseudoRE = new RegExp(`^${tag}-(?:(?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesStr}))(?:(/\\w+))?(?:${ctx.generator.config.separators.join("|")})`);
|
|
pseudoColonRE = new RegExp(`^${tag}-(?:(?:(${PseudoClassFunctionsStr})-)?(${PseudoClassesColonStr}))(?:(/\\w+))?(?:${ctx.generator.config.separators.filter((x) => x !== "-").join("|")})`);
|
|
pseudoVarRE = new RegExp(`^${tag}-(?:(${PseudoClassFunctionsStr})-)?\\[(.+)\\](?:(/\\w+))?(?:${ctx.generator.config.separators.filter((x) => x !== "-").join("|")})`);
|
|
}
|
|
if (!input.startsWith(tag))
|
|
return;
|
|
const result = matchBracket(input) || matchPseudo(input) || matchPseudoVar(input);
|
|
if (!result)
|
|
return;
|
|
const [label, matcher, prefix, pseudoName = ""] = result;
|
|
if (label !== "")
|
|
warnOnce("The labeled variant is experimental and may not follow semver.");
|
|
return {
|
|
matcher,
|
|
handle: (input2, next) => next({
|
|
...input2,
|
|
prefix: `${prefix}${combinator}${input2.prefix}`.replace(rawRE, "$1$2:"),
|
|
sort: PseudoClassesKeys.indexOf(pseudoName) ?? PseudoClassesColonKeys.indexOf(pseudoName)
|
|
})
|
|
};
|
|
},
|
|
multiPass: true
|
|
};
|
|
}
|
|
const excludedPseudo = [
|
|
"::-webkit-resizer",
|
|
"::-webkit-scrollbar",
|
|
"::-webkit-scrollbar-button",
|
|
"::-webkit-scrollbar-corner",
|
|
"::-webkit-scrollbar-thumb",
|
|
"::-webkit-scrollbar-track",
|
|
"::-webkit-scrollbar-track-piece",
|
|
"::file-selector-button"
|
|
];
|
|
const PseudoClassesAndElementsStr = Object.entries(PseudoClasses).map(([key]) => key).sort((a, b) => b.length - a.length).join("|");
|
|
const PseudoClassesAndElementsColonStr = Object.entries(PseudoClassesColon).map(([key]) => key).sort((a, b) => b.length - a.length).join("|");
|
|
function variantPseudoClassesAndElements() {
|
|
let PseudoClassesAndElementsRE;
|
|
let PseudoClassesAndElementsColonRE;
|
|
return {
|
|
name: "pseudo",
|
|
match(input, ctx) {
|
|
if (!(PseudoClassesAndElementsRE && PseudoClassesAndElementsRE)) {
|
|
PseudoClassesAndElementsRE = new RegExp(`^(${PseudoClassesAndElementsStr})(?:${ctx.generator.config.separators.join("|")})`);
|
|
PseudoClassesAndElementsColonRE = new RegExp(`^(${PseudoClassesAndElementsColonStr})(?:${ctx.generator.config.separators.filter((x) => x !== "-").join("|")})`);
|
|
}
|
|
const match = input.match(PseudoClassesAndElementsRE) || input.match(PseudoClassesAndElementsColonRE);
|
|
if (match) {
|
|
const pseudo = PseudoClasses[match[1]] || PseudoClassesColon[match[1]] || `:${match[1]}`;
|
|
let index = PseudoClassesKeys.indexOf(match[1]);
|
|
if (index === -1)
|
|
index = PseudoClassesColonKeys.indexOf(match[1]);
|
|
if (index === -1)
|
|
index = void 0;
|
|
return {
|
|
matcher: input.slice(match[0].length),
|
|
handle: (input2, next) => {
|
|
const selectors = pseudo.startsWith("::") && !excludedPseudo.includes(pseudo) ? {
|
|
pseudo: `${input2.pseudo}${pseudo}`
|
|
} : {
|
|
selector: `${input2.selector}${pseudo}`
|
|
};
|
|
return next({
|
|
...input2,
|
|
...selectors,
|
|
sort: index,
|
|
noMerge: true
|
|
});
|
|
}
|
|
};
|
|
}
|
|
},
|
|
multiPass: true,
|
|
autocomplete: `(${PseudoClassesAndElementsStr}|${PseudoClassesAndElementsColonStr}):`
|
|
};
|
|
}
|
|
function variantPseudoClassFunctions() {
|
|
let PseudoClassFunctionsRE;
|
|
let PseudoClassColonFunctionsRE;
|
|
let PseudoClassVarFunctionRE;
|
|
return {
|
|
match(input, ctx) {
|
|
if (!(PseudoClassFunctionsRE && PseudoClassColonFunctionsRE)) {
|
|
PseudoClassFunctionsRE = new RegExp(`^(${PseudoClassFunctionsStr})-(${PseudoClassesStr})(?:${ctx.generator.config.separators.join("|")})`);
|
|
PseudoClassColonFunctionsRE = new RegExp(`^(${PseudoClassFunctionsStr})-(${PseudoClassesColonStr})(?:${ctx.generator.config.separators.filter((x) => x !== "-").join("|")})`);
|
|
PseudoClassVarFunctionRE = new RegExp(`^(${PseudoClassFunctionsStr})-(\\[.+\\])(?:${ctx.generator.config.separators.filter((x) => x !== "-").join("|")})`);
|
|
}
|
|
const match = input.match(PseudoClassFunctionsRE) || input.match(PseudoClassColonFunctionsRE) || input.match(PseudoClassVarFunctionRE);
|
|
if (match) {
|
|
const fn = match[1];
|
|
const fnVal = getBracket(match[2], "[", "]");
|
|
const pseudo = fnVal ? h.bracket(match[2]) : PseudoClasses[match[2]] || PseudoClassesColon[match[2]] || `:${match[2]}`;
|
|
return {
|
|
matcher: input.slice(match[0].length),
|
|
selector: (s) => `${s}:${fn}(${pseudo})`
|
|
};
|
|
}
|
|
},
|
|
multiPass: true,
|
|
autocomplete: `(${PseudoClassFunctionsStr})-(${PseudoClassesStr}|${PseudoClassesColonStr}):`
|
|
};
|
|
}
|
|
function variantTaggedPseudoClasses(options = {}) {
|
|
const attributify = !!options?.attributifyPseudo;
|
|
return [
|
|
taggedPseudoClassMatcher("group", attributify ? '[group=""]' : ".group", " "),
|
|
taggedPseudoClassMatcher("peer", attributify ? '[peer=""]' : ".peer", "~"),
|
|
taggedPseudoClassMatcher("parent", attributify ? '[parent=""]' : ".parent", ">"),
|
|
taggedPseudoClassMatcher("previous", attributify ? '[previous=""]' : ".previous", "+")
|
|
];
|
|
}
|
|
const PartClassesRE = /(part-\[(.+)]:)(.+)/;
|
|
const variantPartClasses = {
|
|
match(input) {
|
|
const match = input.match(PartClassesRE);
|
|
if (match) {
|
|
const part = `part(${match[2]})`;
|
|
return {
|
|
matcher: input.slice(match[1].length),
|
|
selector: (s) => `${s}::${part}`
|
|
};
|
|
}
|
|
},
|
|
multiPass: true
|
|
};
|
|
|
|
function variants(options) {
|
|
return [
|
|
variantAria,
|
|
variantDataAttribute,
|
|
variantCssLayer,
|
|
variantSelector,
|
|
variantInternalLayer,
|
|
variantNegative,
|
|
variantImportant(),
|
|
variantSupports,
|
|
variantPrint,
|
|
variantCustomMedia,
|
|
variantBreakpoints(),
|
|
...variantCombinators,
|
|
variantPseudoClassesAndElements(),
|
|
variantPseudoClassFunctions(),
|
|
...variantTaggedPseudoClasses(options),
|
|
variantPartClasses,
|
|
...variantColorsMediaOrClass(options),
|
|
...variantLanguageDirections,
|
|
variantScope,
|
|
variantContainerQuery,
|
|
variantVariables,
|
|
variantGroupDataAttribute
|
|
];
|
|
}
|
|
|
|
export { calcMaxWidthBySize, variantAria, variantBreakpoints, variantColorsMediaOrClass, variantCombinators, variantContainerQuery, variantCssLayer, variantCustomMedia, variantDataAttribute, variantGroupDataAttribute, variantImportant, variantInternalLayer, variantLanguageDirections, variantNegative, variantPartClasses, variantPrint, variantPseudoClassFunctions, variantPseudoClassesAndElements, variantScope, variantSelector, variantSupports, variantTaggedPseudoClasses, variantVariables, variants };
|