@getvitops/generator 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +148 -0
- package/README.md +6 -0
- package/assets/css/global.css +10 -0
- package/assets/css/index.css +1 -0
- package/assets/css/patterns/code.css +3 -3
- package/assets/css/patterns/forms.css +31 -0
- package/assets/css/patterns/list.css +12 -32
- package/assets/css/patterns/popover.css +18 -1
- package/assets/css/patterns/theme-editor.css +114 -0
- package/assets/js/editor.js +2 -0
- package/assets/js/elements.js +2 -2
- package/dist/index.d.mts +16 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +152 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -4
- package/schema.json +5 -1
- package/site.schema.json +5 -1
package/dist/index.mjs
CHANGED
|
@@ -62,7 +62,8 @@ const Pattern = desc(z.object({
|
|
|
62
62
|
group: desc(z.optional(z.string()), "Token-cascade group this pattern belongs to (e.g. tag / control / panel); base declarations resolve through `--<prop>-<group>` before `--<prop>-default`."),
|
|
63
63
|
overrides: z.optional(desc(CssDecls, "Per-pattern token overrides, emitted as `--<prop>-<name>-group` values.")),
|
|
64
64
|
element: desc(z.optional(z.string()), "Style at element level via zero-specificity `:where(<element>)` (instead of, or alongside, a class)."),
|
|
65
|
-
class: desc(z.optional(z.string()), "Class name to emit (defaults to the pattern's key)."),
|
|
65
|
+
class: desc(z.optional(z.string()), "Class name to emit (defaults to the pattern's key when no `element` is set). Combined with `element`, the pattern emits one zero-specificity `:where(<element>, .<class>)` rule so the class works on any tag and any explicit class overrides it."),
|
|
66
|
+
fill: desc(z.optional(z.boolean()), "Whether this pattern is colour-filled (states/roles drive `background-color` + `on-solid` text) or text-coloured (they drive `color`). Defaults to true when `base` declares a background."),
|
|
66
67
|
default_role: desc(z.optional(z.string()), "Semantic colour role applied to the bare/default variant."),
|
|
67
68
|
base: z.optional(desc(CssDecls, "Base CSS declarations. Geometry properties (padding, border-radius, border, box-shadow, font-size) are wrapped in per-pattern override hooks (`--p-<name>`, `--br-<name>`, `--b-<name>`, `--ds-<name>`, `--fs-<name>`) so consumers can restyle one pattern by setting one variable.")),
|
|
68
69
|
states: desc(z.optional(z.record(z.string(), z.record(z.string(), z.unknown()))), "Interaction states (hover / active / focus-visible), each a map of shortcuts: `step` (intensify fills/text by n emphasis stops), `scale` (transform scale), `lift` (translateY + shadow), `shadow` (a shadow name → drop-shadow(var(--shadow-<name>)), or true → lift shadow), `ring` (focus ring), or raw `css` declarations. Hover rules are wrapped in `@media (hover: hover)`."),
|
|
@@ -121,13 +122,20 @@ const jsonSchema = {
|
|
|
121
122
|
$id: SCHEMA_URL,
|
|
122
123
|
...z.toJSONSchema(DesignSystemSchema, { target: "draft-2020-12" })
|
|
123
124
|
};
|
|
124
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* Validate an unknown value against the design-system schema.
|
|
127
|
+
*
|
|
128
|
+
* `warnings` are configurations that parse and generate, but produce output that
|
|
129
|
+
* won't behave as authored — currently only the token-namespace collisions the
|
|
130
|
+
* flat `--<prop>-<name>` grammar makes possible.
|
|
131
|
+
*/
|
|
125
132
|
function validate(input) {
|
|
126
133
|
const result = z.safeParse(DesignSystemSchema, input);
|
|
127
134
|
if (!result.success) return {
|
|
128
135
|
ok: false,
|
|
129
136
|
data: void 0,
|
|
130
|
-
errors: result.error.issues
|
|
137
|
+
errors: result.error.issues,
|
|
138
|
+
warnings: []
|
|
131
139
|
};
|
|
132
140
|
const { palette, roles } = result.data.colors;
|
|
133
141
|
for (const [role, hue] of Object.entries(roles)) if (palette[hue] == null) return {
|
|
@@ -141,12 +149,18 @@ function validate(input) {
|
|
|
141
149
|
role
|
|
142
150
|
],
|
|
143
151
|
message: `role "${role}" references unknown palette hue "${hue}"`
|
|
144
|
-
}]
|
|
152
|
+
}],
|
|
153
|
+
warnings: []
|
|
145
154
|
};
|
|
155
|
+
const warnings = [];
|
|
156
|
+
const radii = Object.keys(result.data.patterns?.radii ?? {});
|
|
157
|
+
const items = new Set(Object.keys(result.data.patterns?.items ?? {}));
|
|
158
|
+
for (const name of radii) if (items.has(name)) warnings.push(`patterns.radii.${name} collides with the "${name}" pattern on --br-${name}; the pattern's override hook wins — rename the radius`);
|
|
146
159
|
return {
|
|
147
160
|
ok: true,
|
|
148
161
|
data: result.data,
|
|
149
|
-
errors: []
|
|
162
|
+
errors: [],
|
|
163
|
+
warnings
|
|
150
164
|
};
|
|
151
165
|
}
|
|
152
166
|
|
|
@@ -159,8 +173,9 @@ function validate(input) {
|
|
|
159
173
|
*/
|
|
160
174
|
/**
|
|
161
175
|
* Pattern base geometry props → per-pattern override-hook shorthand. Each hook
|
|
162
|
-
* wraps the authored value (`padding: var(--p-
|
|
163
|
-
* consumer restyles one pattern by setting one variable.
|
|
176
|
+
* wraps the authored value (`padding: var(--p-btn, 0.4em 0.8em)`) so a
|
|
177
|
+
* consumer restyles one pattern by setting one variable. The hook is named after
|
|
178
|
+
* the pattern's key, not its class.
|
|
164
179
|
*/
|
|
165
180
|
const BASE_HOOK = {
|
|
166
181
|
padding: "p",
|
|
@@ -1012,9 +1027,10 @@ pattern CSS is assembled — token cascade, \`--p-<pattern>\`-style override hoo
|
|
|
1012
1027
|
shortcuts — is explained in [/concepts/patterns.md](../concepts/patterns.md).)
|
|
1013
1028
|
|
|
1014
1029
|
- Patterns: ${code(patterns)}.
|
|
1015
|
-
- Roles (for coloured patterns
|
|
1016
|
-
${code(patternRoles)} — e.g. \`badge-success\`, \`
|
|
1017
|
-
|
|
1030
|
+
- Roles (for coloured patterns — \`badge\`, \`tag\`, \`status\`, \`cta\`, \`btn\`, …):
|
|
1031
|
+
${code(patternRoles)} — e.g. \`badge-success\`, \`cta-danger\`. A pattern that also styles an
|
|
1032
|
+
element accepts the bare role class too (\`<button class="danger">\`). The default
|
|
1033
|
+
(unsuffixed) variant uses the pattern's \`default_role\`.
|
|
1018
1034
|
- Shape primitives: \`--br-<name>\` radii — ${code(radii)}.
|
|
1019
1035
|
`;
|
|
1020
1036
|
}
|
|
@@ -1343,16 +1359,25 @@ Shared geometry resolves through a variable chain, most-specific first:
|
|
|
1343
1359
|
|
|
1344
1360
|
## 2 — Base declarations & override hooks
|
|
1345
1361
|
|
|
1346
|
-
Each pattern's \`base\` block is emitted on its selector
|
|
1347
|
-
|
|
1348
|
-
|
|
1362
|
+
Each pattern's \`base\` block is emitted on its selector:
|
|
1363
|
+
|
|
1364
|
+
- \`class\` only → \`.<class ?? name>\`, at normal class specificity.
|
|
1365
|
+
- \`element\` only → a **zero-specificity** \`:where(<element>)\` rule, so author CSS can always
|
|
1366
|
+
override it.
|
|
1367
|
+
- **both** → one \`:where(<element>, .<class>)\` rule (e.g. \`:where(button, .btn)\`). The element
|
|
1368
|
+
gets the styling with no class needed, the class carries it to any other tag, and — because the
|
|
1369
|
+
whole thing sits at zero specificity — any explicit class wins, including a louder pattern
|
|
1370
|
+
(\`.cta\`) or a component's own rule (\`.dialog__close\`).
|
|
1371
|
+
|
|
1372
|
+
Geometry properties are wrapped in a **per-pattern override hook**:
|
|
1349
1373
|
|
|
1350
1374
|
| base property | hook variable |
|
|
1351
1375
|
| --- | --- |
|
|
1352
1376
|
${hookTable}
|
|
1353
1377
|
|
|
1354
|
-
e.g. \`padding: var(--p-
|
|
1355
|
-
\`--p-
|
|
1378
|
+
e.g. \`padding: var(--p-btn, 0.4em 0.8em)\` — a consumer restyles every button by setting
|
|
1379
|
+
\`--p-btn\` on \`:root\`, without touching the pattern. The hook is named after the pattern's
|
|
1380
|
+
**key**, not its class.
|
|
1356
1381
|
|
|
1357
1382
|
## 3 — States
|
|
1358
1383
|
|
|
@@ -1374,7 +1399,10 @@ rules are wrapped in \`@media (hover: hover)\` so touch devices never stick.
|
|
|
1374
1399
|
## 4 — Role variants
|
|
1375
1400
|
|
|
1376
1401
|
\`roles\` lists semantic colour variants: class patterns emit \`.<pattern>-<role>\`
|
|
1377
|
-
(\`.badge-success\`)
|
|
1402
|
+
(\`.badge-success\`). A pattern with an \`element\` emits both the bare role class on the
|
|
1403
|
+
element and the \`-<role>\` form (\`:where(button, .btn).danger, .btn-danger\`), so the same
|
|
1404
|
+
variant works on a non-element host — both at class specificity, so neither outranks a
|
|
1405
|
+
plain class. Fill
|
|
1378
1406
|
patterns set \`background-color: var(--<role>-solid)\` + \`color: var(--<role>-on-solid)\`;
|
|
1379
1407
|
text patterns use the role's \`bold\` emphasis stop. \`default_role\` colours the bare,
|
|
1380
1408
|
unsuffixed pattern. States re-apply per variant with the variant's role.
|
|
@@ -1477,6 +1505,22 @@ function generateDocs(ds, assetsDir) {
|
|
|
1477
1505
|
* and the pre-built JS bundles) live under `assets/` in this package and are read /
|
|
1478
1506
|
* copied from there — they are the same for every consumer.
|
|
1479
1507
|
*/
|
|
1508
|
+
/**
|
|
1509
|
+
* Selector the dark functional-token flip hangs off.
|
|
1510
|
+
*
|
|
1511
|
+
* `data-brx-theme` is Bricks' own attribute — Bricks sets it, so it's what the
|
|
1512
|
+
* WordPress target needs. Nothing sets it anywhere else, which meant the dark
|
|
1513
|
+
* flip was unreachable outside Bricks: the shipped `<color-scheme-toggle>` web
|
|
1514
|
+
* component writes `documentElement.dataset.theme` (i.e. `data-theme`), so
|
|
1515
|
+
* clicking "Dark" changed an attribute no rule matched. Matching both makes the
|
|
1516
|
+
* component work on every target without changing what Bricks already does.
|
|
1517
|
+
*
|
|
1518
|
+
* Note this covers the explicit choice only — there is deliberately no
|
|
1519
|
+
* `prefers-color-scheme` block, so the toggle's "System" position currently
|
|
1520
|
+
* resolves to light. Adding one would flip every existing consumer site dark for
|
|
1521
|
+
* dark-OS users, which is a product decision, not a bug fix.
|
|
1522
|
+
*/
|
|
1523
|
+
const DARK_SEL = ":root[data-brx-theme=\"dark\"], :root[data-theme=\"dark\"]";
|
|
1480
1524
|
const DEFAULT_ASSETS = join(dirname(fileURLToPath(import.meta.url)), "..", "assets");
|
|
1481
1525
|
const UTILITY_PROPS = {
|
|
1482
1526
|
bg: "background-color",
|
|
@@ -1616,7 +1660,7 @@ function build(ds, format, assetsDir) {
|
|
|
1616
1660
|
if (surfaceRole) fb += ` --overlay: color-mix(in oklch, var(--color-${surfaceRole.hue}-950) 60%, transparent);\n`;
|
|
1617
1661
|
if (fb) {
|
|
1618
1662
|
css += `/* Functional role tokens (dark) */\n`;
|
|
1619
|
-
css +=
|
|
1663
|
+
css += `${DARK_SEL} {\n color-scheme: dark;\n${fb}}\n\n`;
|
|
1620
1664
|
}
|
|
1621
1665
|
}
|
|
1622
1666
|
const allTokens = [];
|
|
@@ -1704,6 +1748,7 @@ function build(ds, format, assetsDir) {
|
|
|
1704
1748
|
generated["typography.css"] = typo;
|
|
1705
1749
|
}
|
|
1706
1750
|
const stateRules = (sel, role, states, colorProp = "background-color") => {
|
|
1751
|
+
const sels = Array.isArray(sel) ? sel : [sel];
|
|
1707
1752
|
let out = "";
|
|
1708
1753
|
for (const [state, spec] of Object.entries(states)) {
|
|
1709
1754
|
const body = [];
|
|
@@ -1721,7 +1766,8 @@ function build(ds, format, assetsDir) {
|
|
|
1721
1766
|
}
|
|
1722
1767
|
if (spec.css && typeof spec.css === "object") for (const [k, v] of Object.entries(spec.css)) body.push(`${k}: ${v};`);
|
|
1723
1768
|
if (!body.length) continue;
|
|
1724
|
-
const
|
|
1769
|
+
const pseudo = state === "hover" ? ":hover" : state === "active" ? ":active" : state === "focus-visible" ? ":focus-visible" : `:${state}`;
|
|
1770
|
+
const rule = `${sels.map((s) => `${s}${pseudo}`).join(",\n")} {\n ${body.join("\n ")}\n}\n`;
|
|
1725
1771
|
out += state === "hover" ? `@media (hover: hover) {\n${rule}}\n` : rule;
|
|
1726
1772
|
}
|
|
1727
1773
|
return out;
|
|
@@ -1731,11 +1777,12 @@ function build(ds, format, assetsDir) {
|
|
|
1731
1777
|
for (const [pname, p] of Object.entries(patterns?.items ?? {})) {
|
|
1732
1778
|
if (!p.base) continue;
|
|
1733
1779
|
const states = p.states ?? {};
|
|
1734
|
-
const
|
|
1735
|
-
const
|
|
1780
|
+
const cls = p.class ?? (p.element ? void 0 : pname);
|
|
1781
|
+
const elementSel = (extra = "") => `:where(${[p.element, cls && `.${cls}`].filter(Boolean).join(", ")})${extra}`;
|
|
1782
|
+
const defaultSel = p.element ? elementSel() : `.${cls}`;
|
|
1736
1783
|
const defaultRole = p.default_role ?? null;
|
|
1737
1784
|
const base = { ...p.base };
|
|
1738
|
-
const fills = pname === "button" || pname === "badge" || base["background-color"] != null || base["background"] != null;
|
|
1785
|
+
const fills = p.fill ?? (pname === "button" || pname === "badge" || base["background-color"] != null || base["background"] != null);
|
|
1739
1786
|
const colorProp = fills ? "background-color" : "color";
|
|
1740
1787
|
pat += `${defaultSel} {\n`;
|
|
1741
1788
|
if (Object.keys(states).length > 0) {
|
|
@@ -1753,10 +1800,10 @@ function build(ds, format, assetsDir) {
|
|
|
1753
1800
|
pat += decls(wrappedBase) + "\n}\n";
|
|
1754
1801
|
pat += stateRules(defaultSel, defaultRole, states, colorProp);
|
|
1755
1802
|
for (const role of p.roles ?? []) {
|
|
1756
|
-
const
|
|
1803
|
+
const variantSels = p.element ? [elementSel(`.${role}`), ...cls ? [`.${cls}-${role}`] : []] : [`.${cls}-${role}`];
|
|
1757
1804
|
const variantColorDecl = fills ? `background-color: var(--${role}-solid); color: var(--${role}-on-solid)` : `color: var(--color-${role}-bold)`;
|
|
1758
|
-
pat += `${
|
|
1759
|
-
pat += stateRules(
|
|
1805
|
+
pat += `${variantSels.join(",\n")} { ${variantColorDecl}; }\n`;
|
|
1806
|
+
pat += stateRules(variantSels, role, states, colorProp);
|
|
1760
1807
|
}
|
|
1761
1808
|
pat += "\n";
|
|
1762
1809
|
}
|
|
@@ -1918,11 +1965,25 @@ function build(ds, format, assetsDir) {
|
|
|
1918
1965
|
}, null, 2),
|
|
1919
1966
|
designManifest: (() => {
|
|
1920
1967
|
const reverseIndex = {};
|
|
1921
|
-
for (const [name, hue] of Object.entries(expandedPalette)) for (const n of Object.keys(hue.numeric)) reverseIndex[`--color-${name}-${n}`] = `colors.palette.${name}.
|
|
1968
|
+
for (const [name, hue] of Object.entries(expandedPalette)) for (const n of Object.keys(hue.numeric)) reverseIndex[`--color-${name}-${n}`] = `colors.palette.${name}.anchors.${n}`;
|
|
1922
1969
|
const colorRoles = Object.entries(roleMap).map(([name, ramp]) => ({
|
|
1923
1970
|
name,
|
|
1924
1971
|
ramp
|
|
1925
1972
|
}));
|
|
1973
|
+
const roleTokens = Object.fromEntries(Object.entries(expandedPalette).map(([hueName, hue]) => {
|
|
1974
|
+
const def = functionalRole("_", hueName, hue);
|
|
1975
|
+
const sfc = functionalRole("surface", hueName, hue);
|
|
1976
|
+
return [hueName, {
|
|
1977
|
+
default: {
|
|
1978
|
+
light: def.light,
|
|
1979
|
+
dark: def.dark
|
|
1980
|
+
},
|
|
1981
|
+
surface: {
|
|
1982
|
+
light: sfc.light,
|
|
1983
|
+
dark: sfc.dark
|
|
1984
|
+
}
|
|
1985
|
+
}];
|
|
1986
|
+
}));
|
|
1926
1987
|
const typoRoles = typography?.roles ?? {};
|
|
1927
1988
|
const hooks = {};
|
|
1928
1989
|
for (const [key, [prop, sfx]] of Object.entries(TYPO_KEYMAP)) hooks[sfx] = {
|
|
@@ -1935,7 +1996,6 @@ function build(ds, format, assetsDir) {
|
|
|
1935
1996
|
const pGroups = patterns?.groups ?? {};
|
|
1936
1997
|
const pItems = patterns?.items ?? {};
|
|
1937
1998
|
for (const prop of Object.keys(pDefaults)) reverseIndex[`--${prop}-default`] = `patterns.defaults.${prop}`;
|
|
1938
|
-
for (const name of Object.keys(pRadii)) reverseIndex[`--br-${name}`] = `patterns.radii.${name}`;
|
|
1939
1999
|
for (const [group, props] of Object.entries(pGroups)) for (const prop of Object.keys(props)) reverseIndex[`--${prop}-${group}`] = `patterns.groups.${group}.${prop}`;
|
|
1940
2000
|
const items = Object.entries(pItems).map(([name, p]) => {
|
|
1941
2001
|
const base = p.base ?? {};
|
|
@@ -1952,12 +2012,14 @@ function build(ds, format, assetsDir) {
|
|
|
1952
2012
|
roles: p.roles ?? []
|
|
1953
2013
|
};
|
|
1954
2014
|
});
|
|
2015
|
+
for (const name of Object.keys(pRadii)) if (!(`--br-${name}` in reverseIndex)) reverseIndex[`--br-${name}`] = `patterns.radii.${name}`;
|
|
1955
2016
|
return JSON.stringify({
|
|
1956
2017
|
colors: {
|
|
1957
2018
|
ramps: Object.keys(expandedPalette),
|
|
1958
2019
|
steps: NUMERIC_STEPS,
|
|
1959
2020
|
palette: numericPalette,
|
|
1960
|
-
roles: colorRoles
|
|
2021
|
+
roles: colorRoles,
|
|
2022
|
+
roleTokens
|
|
1961
2023
|
},
|
|
1962
2024
|
typography: {
|
|
1963
2025
|
roles: Object.keys(typoRoles),
|
|
@@ -1985,14 +2047,10 @@ function build(ds, format, assetsDir) {
|
|
|
1985
2047
|
items
|
|
1986
2048
|
},
|
|
1987
2049
|
shadows: shadows ?? {},
|
|
1988
|
-
interaction: {
|
|
1989
|
-
duration: "200ms",
|
|
1990
|
-
easing: "ease"
|
|
1991
|
-
},
|
|
1992
2050
|
reverseIndex
|
|
1993
2051
|
}, null, 2);
|
|
1994
2052
|
})(),
|
|
1995
|
-
tailwind: emitTailwind({
|
|
2053
|
+
tailwind: format !== "tailwind" ? "" : emitTailwind({
|
|
1996
2054
|
ds,
|
|
1997
2055
|
expandedPalette,
|
|
1998
2056
|
scaleRoles,
|
|
@@ -2052,7 +2110,7 @@ function emitTailwind(ctx) {
|
|
|
2052
2110
|
const surface = scaleRoles.find((r) => r.role === "surface");
|
|
2053
2111
|
if (surface) darkBlock += ` --overlay: color-mix(in oklch, var(--color-${surface.hue}-950) 60%, transparent);\n`;
|
|
2054
2112
|
}
|
|
2055
|
-
if (darkBlock) parts.push(`/* Functional role tokens (dark) */\n
|
|
2113
|
+
if (darkBlock) parts.push(`/* Functional role tokens (dark) */\n${DARK_SEL} {\n color-scheme: dark;\n${darkBlock}}\n`);
|
|
2056
2114
|
parts.push("/* State variant for the active flip (hover/focus-visible are built in). */\n@custom-variant is-active (&.is-active, &[data-active]);\n");
|
|
2057
2115
|
const util = [];
|
|
2058
2116
|
if (scaleRoles.length) {
|
|
@@ -2309,6 +2367,7 @@ function loadConfig(input) {
|
|
|
2309
2367
|
const lines = result.errors.slice(0, 12).map((e) => ` • ${e.path.join(".") || "(root)"}: ${e.message}`).join("\n");
|
|
2310
2368
|
throw new Error(`Invalid design-system.json:\n${lines}`);
|
|
2311
2369
|
}
|
|
2370
|
+
for (const w of result.warnings) console.warn(`[vitops] ${w}`);
|
|
2312
2371
|
return result.data;
|
|
2313
2372
|
}
|
|
2314
2373
|
async function generate(options) {
|
|
@@ -3087,21 +3146,73 @@ function defaultConfig() {
|
|
|
3087
3146
|
top: 1e3
|
|
3088
3147
|
},
|
|
3089
3148
|
items: {
|
|
3090
|
-
|
|
3149
|
+
btn: {
|
|
3091
3150
|
group: "control",
|
|
3092
3151
|
element: "button",
|
|
3093
|
-
|
|
3152
|
+
class: "btn",
|
|
3153
|
+
fill: false,
|
|
3154
|
+
overrides: {
|
|
3155
|
+
b: "1px solid transparent",
|
|
3156
|
+
fs: "inherit"
|
|
3157
|
+
},
|
|
3158
|
+
base: {
|
|
3159
|
+
display: "inline-flex",
|
|
3160
|
+
"align-items": "center",
|
|
3161
|
+
"justify-content": "center",
|
|
3162
|
+
gap: "0.4em",
|
|
3163
|
+
padding: "var(--p-btn-group)",
|
|
3164
|
+
"border-radius": "var(--br-btn-group)",
|
|
3165
|
+
border: "var(--b-btn-group)",
|
|
3166
|
+
"box-shadow": "var(--ds-btn-group)",
|
|
3167
|
+
background: "transparent",
|
|
3168
|
+
color: "inherit",
|
|
3169
|
+
"font-family": "inherit",
|
|
3170
|
+
"font-size": "var(--fs-btn-group)",
|
|
3171
|
+
"font-weight": "inherit",
|
|
3172
|
+
"text-decoration": "none",
|
|
3173
|
+
cursor: "pointer"
|
|
3174
|
+
},
|
|
3175
|
+
states: {
|
|
3176
|
+
hover: {
|
|
3177
|
+
step: 1,
|
|
3178
|
+
css: { "background-color": "var(--color-surface-muted)" }
|
|
3179
|
+
},
|
|
3180
|
+
"focus-visible": { ring: true }
|
|
3181
|
+
},
|
|
3182
|
+
roles: []
|
|
3183
|
+
},
|
|
3184
|
+
cta: {
|
|
3185
|
+
group: "control",
|
|
3186
|
+
class: "cta",
|
|
3187
|
+
fill: true,
|
|
3188
|
+
default_role: "ui-primary",
|
|
3189
|
+
overrides: {
|
|
3190
|
+
p: "0.75em 1.5em",
|
|
3191
|
+
b: "none",
|
|
3192
|
+
ds: "var(--shadow-sm)",
|
|
3193
|
+
fs: "inherit"
|
|
3194
|
+
},
|
|
3094
3195
|
base: {
|
|
3095
|
-
|
|
3096
|
-
"
|
|
3097
|
-
|
|
3196
|
+
display: "inline-flex",
|
|
3197
|
+
"align-items": "center",
|
|
3198
|
+
"justify-content": "center",
|
|
3199
|
+
gap: "0.5em",
|
|
3200
|
+
padding: "var(--p-cta-group)",
|
|
3201
|
+
"border-radius": "var(--br-cta-group)",
|
|
3202
|
+
border: "var(--b-cta-group)",
|
|
3203
|
+
"font-family": "inherit",
|
|
3204
|
+
"font-size": "var(--fs-cta-group)",
|
|
3098
3205
|
"font-weight": "600",
|
|
3099
|
-
|
|
3206
|
+
"text-decoration": "none",
|
|
3100
3207
|
cursor: "pointer",
|
|
3101
|
-
|
|
3208
|
+
color: "var(--ui-primary-on-solid)",
|
|
3209
|
+
"box-shadow": "var(--ds-cta-group)"
|
|
3102
3210
|
},
|
|
3103
3211
|
states: {
|
|
3104
|
-
hover: {
|
|
3212
|
+
hover: {
|
|
3213
|
+
step: 1,
|
|
3214
|
+
lift: "1px"
|
|
3215
|
+
},
|
|
3105
3216
|
active: { scale: .97 },
|
|
3106
3217
|
"focus-visible": { ring: true }
|
|
3107
3218
|
},
|