@loworbitstudio/visor-theme-engine 0.20.0 → 0.22.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/dist/adapters/index.d.ts +1 -1
- package/dist/adapters/index.js +19 -4
- package/dist/{chunk-JDYLDGUN.js → chunk-L5DQDEZV.js} +348 -6
- package/dist/index.d.ts +135 -4
- package/dist/index.js +66 -4
- package/dist/{types-BG-YT4JW.d.ts → types-Wy5n0W9F.d.ts} +8 -0
- package/package.json +1 -1
- package/src/visor-theme.schema.json +48 -1
package/dist/adapters/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { k as GeneratedPrimitives, s as SemanticTokens, R as ResolvedThemeConfig } from '../types-
|
|
1
|
+
import { k as GeneratedPrimitives, s as SemanticTokens, R as ResolvedThemeConfig } from '../types-Wy5n0W9F.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Adapter types for the Visor theme engine.
|
package/dist/adapters/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
block,
|
|
7
7
|
buildVisorFontUrl,
|
|
8
8
|
collectBrandPassthrough,
|
|
9
|
+
collectDeclaredProperties,
|
|
9
10
|
fontStack,
|
|
10
11
|
generateDarkCss,
|
|
11
12
|
generateFontSizeDecls,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
generateIntentDecls,
|
|
15
16
|
generateLightCss,
|
|
16
17
|
generatePrimitivesCss,
|
|
18
|
+
generateSemanticAliasDecls,
|
|
17
19
|
generateShadeScale,
|
|
18
20
|
generateSpaceAliasDecls,
|
|
19
21
|
generateTextScaleAliasDecls,
|
|
@@ -23,7 +25,7 @@ import {
|
|
|
23
25
|
resolveThemeBrand,
|
|
24
26
|
resolveThemeFonts,
|
|
25
27
|
sectionComment
|
|
26
|
-
} from "../chunk-
|
|
28
|
+
} from "../chunk-L5DQDEZV.js";
|
|
27
29
|
|
|
28
30
|
// src/adapters/brand-passthrough.ts
|
|
29
31
|
var SENTINEL_COLOR = "#ff00ff";
|
|
@@ -301,14 +303,27 @@ ${inner.split("\n").map((l) => ` ${l}`).join("\n")}
|
|
|
301
303
|
}
|
|
302
304
|
semanticLines.push("");
|
|
303
305
|
}
|
|
306
|
+
const lightBody = stripHeader(generateLightCss(input.tokens, { scopePrefix, colorScheme }));
|
|
307
|
+
const darkBody = stripHeader(generateDarkCss(input.tokens, { scopePrefix, colorScheme }));
|
|
308
|
+
const adaptiveBody = [lightBody, darkBody].filter(Boolean).join("\n\n");
|
|
309
|
+
if (scopePrefix) {
|
|
310
|
+
const declared = collectDeclaredProperties(
|
|
311
|
+
[primitivesBody, semanticLines.join("\n"), adaptiveBody].join("\n")
|
|
312
|
+
);
|
|
313
|
+
const aliasDecls = generateSemanticAliasDecls(declared);
|
|
314
|
+
if (aliasDecls.length > 0) {
|
|
315
|
+
semanticLines.push(
|
|
316
|
+
sectionComment("visor-core alias re-substitution at theme scope (VI-648)")
|
|
317
|
+
);
|
|
318
|
+
semanticLines.push(block(hostSelector, aliasDecls));
|
|
319
|
+
semanticLines.push("");
|
|
320
|
+
}
|
|
321
|
+
}
|
|
304
322
|
const semanticLayer = wrapInLayer("visor-semantic", semanticLines.join("\n").trim());
|
|
305
323
|
if (semanticLayer) {
|
|
306
324
|
lines.push(semanticLayer);
|
|
307
325
|
lines.push("");
|
|
308
326
|
}
|
|
309
|
-
const lightBody = stripHeader(generateLightCss(input.tokens, { scopePrefix, colorScheme }));
|
|
310
|
-
const darkBody = stripHeader(generateDarkCss(input.tokens, { scopePrefix, colorScheme }));
|
|
311
|
-
const adaptiveBody = [lightBody, darkBody].filter(Boolean).join("\n\n");
|
|
312
327
|
lines.push(
|
|
313
328
|
wrapInLayer("visor-adaptive", adaptiveBody)
|
|
314
329
|
);
|
|
@@ -1260,9 +1260,23 @@ var TABS = "components/ui/tabs/tabs.module.css";
|
|
|
1260
1260
|
var SKELETON = "components/ui/skeleton/skeleton.module.css";
|
|
1261
1261
|
var SPINNER = "components/ui/spinner/spinner.module.css";
|
|
1262
1262
|
var CHECKBOX = "components/ui/checkbox/checkbox.module.css";
|
|
1263
|
+
var INPUT = "components/ui/input/input.module.css";
|
|
1264
|
+
var TEXTAREA = "components/ui/textarea/textarea.module.css";
|
|
1265
|
+
var SELECT = "components/ui/select/select.module.css";
|
|
1266
|
+
var SWITCH = "components/ui/switch/switch.module.css";
|
|
1267
|
+
var TAG_INPUT = "components/ui/tag-input/tag-input.module.css";
|
|
1268
|
+
var FILE_UPLOAD = "components/ui/file-upload/file-upload.module.css";
|
|
1269
|
+
var BUTTON = "components/ui/button/button.module.css";
|
|
1270
|
+
var FIELD = "components/ui/field/field.module.css";
|
|
1271
|
+
var TEXT = "components/ui/text/text.module.css";
|
|
1272
|
+
var INLINE_EDIT = "components/ui/inline-edit/inline-edit.module.css";
|
|
1273
|
+
var SAVE_STATUS = "components/ui/save-status/save-status.module.css";
|
|
1263
1274
|
function at(file, fallback) {
|
|
1264
1275
|
return [{ file, fallback }];
|
|
1265
1276
|
}
|
|
1277
|
+
function each(files, fallback) {
|
|
1278
|
+
return files.map((file) => ({ file, fallback }));
|
|
1279
|
+
}
|
|
1266
1280
|
var tableFamily = {
|
|
1267
1281
|
family: "table",
|
|
1268
1282
|
prefix: "table",
|
|
@@ -1343,7 +1357,12 @@ var chipFamily = {
|
|
|
1343
1357
|
description: "Chip / filter-pill treatment. The retro found the same mono status chip at 8.5 / 9 / 9.5 / 10 / 11px with tracking .03\u2013.14em across nine implementations; this family is the single dial.",
|
|
1344
1358
|
tokens: [
|
|
1345
1359
|
{ key: "radius", property: "border-radius", description: "Chip corner rounding.", consumers: at(CHIP, "var(--radius-full, 9999px)") },
|
|
1346
|
-
{
|
|
1360
|
+
{
|
|
1361
|
+
key: "border",
|
|
1362
|
+
property: "outline-color (outlined variant, on ::after)",
|
|
1363
|
+
description: "Outlined-chip edge colour. Width and style come from the shared `control` edge, so `control.edge-width: 0` turns it off.",
|
|
1364
|
+
consumers: at(CHIP, "var(--control-edge-color, var(--border-default, #e5e7eb))")
|
|
1365
|
+
},
|
|
1347
1366
|
{ key: "bg", property: "background-color", description: "Resting chip fill.", consumers: at(CHIP, "var(--surface-card, #ffffff)") },
|
|
1348
1367
|
{ key: "text-color", property: "color", description: "Chip label colour.", consumers: at(CHIP, "var(--text-primary, #111827)") },
|
|
1349
1368
|
{ key: "font-family", property: "font-family", description: "Chip label family \u2014 bind a mono face for token/ID chips.", consumers: at(CHIP, "var(--font-body, inherit)") },
|
|
@@ -1360,7 +1379,7 @@ var chipFamily = {
|
|
|
1360
1379
|
{ key: "lg-padding-x", property: "padding", description: "Large chip horizontal padding.", consumers: at(CHIP, "var(--spacing-4, 1rem)") },
|
|
1361
1380
|
{ key: "lg-font-size", property: "font-size", description: "Large chip type size.", consumers: at(CHIP, "var(--font-size-base, 1rem)") },
|
|
1362
1381
|
{ key: "selected-bg", property: "background-color", description: "Selected chip fill.", consumers: at(CHIP, "var(--surface-accent-subtle, #eff6ff)") },
|
|
1363
|
-
{ key: "selected-border-color", property: "
|
|
1382
|
+
{ key: "selected-border-color", property: "outline-color (on ::after)", description: "Selected chip edge colour.", consumers: at(CHIP, "var(--surface-accent-default, #3b82f6)") },
|
|
1364
1383
|
{ key: "selected-text-color", property: "color", description: "Selected chip label colour.", consumers: at(CHIP, "var(--text-link, #2563eb)") }
|
|
1365
1384
|
]
|
|
1366
1385
|
};
|
|
@@ -1458,7 +1477,12 @@ var emptyStateFamily = {
|
|
|
1458
1477
|
{ key: "gap", property: "gap", description: "Placard stack rhythm.", consumers: at(EMPTY_STATE, "var(--spacing-2, 0.5rem)") },
|
|
1459
1478
|
{ key: "padding", property: "padding", description: "Default-size placard inset.", consumers: at(EMPTY_STATE, "var(--spacing-8, 2rem) var(--spacing-5, 1.25rem)") },
|
|
1460
1479
|
{ key: "bg", property: "background-color", description: "Default-tone fill.", consumers: at(EMPTY_STATE, "var(--surface-muted, #f9fafb)") },
|
|
1461
|
-
{
|
|
1480
|
+
{
|
|
1481
|
+
key: "border",
|
|
1482
|
+
property: "outline-color",
|
|
1483
|
+
description: "Default-tone dashed-edge colour. Width and style come from the shared `control` drop edge, so `control.edge-width: 0` turns it off.",
|
|
1484
|
+
consumers: at(EMPTY_STATE, "var(--control-edge-color, var(--border-default, #e5e7eb))")
|
|
1485
|
+
},
|
|
1462
1486
|
{ key: "icon-size", property: "width / height", description: "Icon-chip diameter.", consumers: at(EMPTY_STATE, "72px") },
|
|
1463
1487
|
{ key: "icon-radius", property: "border-radius", description: "Icon-chip rounding.", consumers: at(EMPTY_STATE, "var(--radius-full, 9999px)") },
|
|
1464
1488
|
{ key: "icon-bg", property: "background-color", description: "Icon-chip fill.", consumers: at(EMPTY_STATE, "var(--surface-subtle, #f5f5f6)") },
|
|
@@ -1606,9 +1630,238 @@ var checkboxFamily = {
|
|
|
1606
1630
|
{ key: "size", property: "width / height", description: "Checkbox box size.", consumers: at(CHECKBOX, "1rem") },
|
|
1607
1631
|
{ key: "radius", property: "border-radius", description: "Checkbox corner rounding \u2014 square it for the editorial admin look.", consumers: at(CHECKBOX, "var(--radius-sm, 0.25rem)") },
|
|
1608
1632
|
{ key: "bg", property: "background-color", description: "Unchecked fill.", consumers: at(CHECKBOX, "transparent") },
|
|
1609
|
-
{
|
|
1633
|
+
{
|
|
1634
|
+
key: "border",
|
|
1635
|
+
property: "outline-color",
|
|
1636
|
+
description: "Unchecked edge colour. Width and style come from the shared `control` edge, so `control.edge-width: 0` turns it off.",
|
|
1637
|
+
consumers: at(CHECKBOX, "var(--control-edge-color, var(--border-default, #e5e7eb))")
|
|
1638
|
+
},
|
|
1639
|
+
{
|
|
1640
|
+
key: "edgeless-bg",
|
|
1641
|
+
property: "background-image",
|
|
1642
|
+
description: "Unchecked fill shown only while the shared edge is off (`control.edge-width: 0`), so the box still reads as a control.",
|
|
1643
|
+
consumers: at(CHECKBOX, "var(--control-edge-color, var(--border-default, #e5e7eb))")
|
|
1644
|
+
},
|
|
1610
1645
|
{ key: "bg-checked", property: "background-color", description: "Checked fill.", consumers: at(CHECKBOX, "var(--interactive-primary-bg, var(--primary, #111827))") },
|
|
1611
|
-
{ key: "border-checked", property: "
|
|
1646
|
+
{ key: "border-checked", property: "outline-color", description: "Checked edge colour.", consumers: at(CHECKBOX, "var(--interactive-primary-bg, var(--primary, #111827))") }
|
|
1647
|
+
]
|
|
1648
|
+
};
|
|
1649
|
+
var EDGE_CONTROLS = [INPUT, TEXTAREA, SELECT, CHECKBOX, SWITCH, TAG_INPUT, BUTTON];
|
|
1650
|
+
var controlFamily = {
|
|
1651
|
+
family: "control",
|
|
1652
|
+
prefix: "control",
|
|
1653
|
+
description: "The one switch for form-control edges (VI-655). Every form control draws its resting edge from these, so `edge-width: 0` removes every resting edge at once, dashed edges included, with no layout shift.",
|
|
1654
|
+
tokens: [
|
|
1655
|
+
{
|
|
1656
|
+
key: "edge-width",
|
|
1657
|
+
property: "outline-width",
|
|
1658
|
+
description: "THE switch. Resting-edge weight for every form control; `0` turns every resting edge off.",
|
|
1659
|
+
consumers: [
|
|
1660
|
+
...each(EDGE_CONTROLS, "1px"),
|
|
1661
|
+
{ file: CHIP, fallback: "var(--stroke-width-thin, 1px)" },
|
|
1662
|
+
{ file: FILE_UPLOAD, fallback: "1px" },
|
|
1663
|
+
{ file: EMPTY_STATE, fallback: "1px" }
|
|
1664
|
+
]
|
|
1665
|
+
},
|
|
1666
|
+
{
|
|
1667
|
+
key: "edge-color",
|
|
1668
|
+
property: "outline-color",
|
|
1669
|
+
description: "Resting-edge colour. A component's own `--<component>-border` override still wins over it.",
|
|
1670
|
+
consumers: each([INPUT, TEXTAREA, SELECT, CHECKBOX, TAG_INPUT, CHIP, FILE_UPLOAD, EMPTY_STATE, BUTTON], "var(--border-default, #e5e7eb)")
|
|
1671
|
+
},
|
|
1672
|
+
{
|
|
1673
|
+
key: "edge-style",
|
|
1674
|
+
property: "outline-style",
|
|
1675
|
+
description: "Resting-edge style for solid edges.",
|
|
1676
|
+
consumers: each([...EDGE_CONTROLS, CHIP], "solid")
|
|
1677
|
+
},
|
|
1678
|
+
{
|
|
1679
|
+
key: "drop-edge-width",
|
|
1680
|
+
property: "outline-width",
|
|
1681
|
+
description: "Dashed-edge weight (file-upload draws it at 2\xD7). Follows `edge-width` unless set \u2014 set it alone to keep dashed edges while solid edges are off.",
|
|
1682
|
+
consumers: each([FILE_UPLOAD, EMPTY_STATE], "var(--control-edge-width, 1px)")
|
|
1683
|
+
},
|
|
1684
|
+
{
|
|
1685
|
+
key: "drop-edge-style",
|
|
1686
|
+
property: "outline-style",
|
|
1687
|
+
description: "Dashed-edge style for drop targets and empty states.",
|
|
1688
|
+
consumers: each([FILE_UPLOAD, EMPTY_STATE], "dashed")
|
|
1689
|
+
},
|
|
1690
|
+
{
|
|
1691
|
+
key: "state-edge-width",
|
|
1692
|
+
property: "outline-width",
|
|
1693
|
+
description: "Focus and invalid edge weight. Independent of `edge-width`, so focus and invalid stay visible with edges off.",
|
|
1694
|
+
consumers: each([INPUT, TEXTAREA, SELECT, CHECKBOX, SWITCH, TAG_INPUT], "1px")
|
|
1695
|
+
}
|
|
1696
|
+
]
|
|
1697
|
+
};
|
|
1698
|
+
var fieldFamily = {
|
|
1699
|
+
family: "field",
|
|
1700
|
+
prefix: "field",
|
|
1701
|
+
description: "Field label treatment \u2014 size, case, tracking and colour of `FieldLabel`, in both densities.",
|
|
1702
|
+
tokens: [
|
|
1703
|
+
{
|
|
1704
|
+
key: "label-font-size",
|
|
1705
|
+
property: "font-size",
|
|
1706
|
+
description: "Label type size. Drives both the standard and editorial-density steps.",
|
|
1707
|
+
consumers: [
|
|
1708
|
+
{ file: FIELD, fallback: "var(--font-size-sm, 0.875rem)" },
|
|
1709
|
+
{ file: FIELD, fallback: "13px" }
|
|
1710
|
+
]
|
|
1711
|
+
},
|
|
1712
|
+
{ key: "label-text-transform", property: "text-transform", description: "Label casing.", consumers: at(FIELD, "revert-layer") },
|
|
1713
|
+
{ key: "label-letter-spacing", property: "letter-spacing", description: "Label tracking.", consumers: at(FIELD, "revert-layer") },
|
|
1714
|
+
{
|
|
1715
|
+
key: "label-color",
|
|
1716
|
+
property: "color",
|
|
1717
|
+
description: "Label colour. Drives both the standard and editorial-density steps.",
|
|
1718
|
+
consumers: [
|
|
1719
|
+
{ file: FIELD, fallback: "var(--text-primary, currentColor)" },
|
|
1720
|
+
{ file: FIELD, fallback: "var(--text-secondary)" }
|
|
1721
|
+
]
|
|
1722
|
+
}
|
|
1723
|
+
]
|
|
1724
|
+
};
|
|
1725
|
+
var BUTTON_SIZES = [
|
|
1726
|
+
{ size: "sm", fontSize: ["var(--font-size-xs, 0.75rem)", "0.8125rem"], radius: "var(--radius-md, 0.375rem)" },
|
|
1727
|
+
{ size: "md", fontSize: ["var(--font-size-sm, 0.875rem)"], radius: "var(--radius-md, 0.375rem)" },
|
|
1728
|
+
{ size: "lg", fontSize: ["var(--font-size-base, 1rem)"], radius: "var(--radius-md, 0.375rem)" },
|
|
1729
|
+
{ size: "dlg", fontSize: ["var(--font-size-2xs, 0.6875rem)"], radius: "var(--radius-lg, 0.5rem)" }
|
|
1730
|
+
];
|
|
1731
|
+
var buttonFamily = {
|
|
1732
|
+
family: "button",
|
|
1733
|
+
prefix: "button",
|
|
1734
|
+
description: "Button type treatment and rounding. The unprefixed keys set every size at once; a size key (`dlg-radius`) overrides one size.",
|
|
1735
|
+
tokens: [
|
|
1736
|
+
{
|
|
1737
|
+
key: "text-transform",
|
|
1738
|
+
property: "text-transform",
|
|
1739
|
+
description: "Casing for every size.",
|
|
1740
|
+
consumers: BUTTON_SIZES.map(() => ({ file: BUTTON, fallback: "revert-layer" }))
|
|
1741
|
+
},
|
|
1742
|
+
{
|
|
1743
|
+
key: "letter-spacing",
|
|
1744
|
+
property: "letter-spacing",
|
|
1745
|
+
description: "Tracking for every size.",
|
|
1746
|
+
consumers: BUTTON_SIZES.map(() => ({ file: BUTTON, fallback: "revert-layer" }))
|
|
1747
|
+
},
|
|
1748
|
+
{
|
|
1749
|
+
key: "radius",
|
|
1750
|
+
property: "border-radius",
|
|
1751
|
+
description: "Corner rounding for every size (`999px` for a pill).",
|
|
1752
|
+
consumers: [
|
|
1753
|
+
...BUTTON_SIZES.map(({ radius }) => ({ file: BUTTON, fallback: radius })),
|
|
1754
|
+
{ file: BUTTON, fallback: "var(--radius-md, 0.375rem)" }
|
|
1755
|
+
]
|
|
1756
|
+
},
|
|
1757
|
+
...BUTTON_SIZES.flatMap(({ size, fontSize, radius }) => [
|
|
1758
|
+
{
|
|
1759
|
+
key: `${size}-font-size`,
|
|
1760
|
+
property: "font-size",
|
|
1761
|
+
description: fontSize.length > 1 ? `\`${size}\` type size. Drives both the standard and editorial-density steps.` : `\`${size}\` type size.`,
|
|
1762
|
+
consumers: fontSize.map((fallback) => ({ file: BUTTON, fallback }))
|
|
1763
|
+
},
|
|
1764
|
+
{
|
|
1765
|
+
key: `${size}-text-transform`,
|
|
1766
|
+
property: "text-transform",
|
|
1767
|
+
description: `\`${size}\` casing.`,
|
|
1768
|
+
consumers: at(BUTTON, "var(--button-text-transform, revert-layer)")
|
|
1769
|
+
},
|
|
1770
|
+
{
|
|
1771
|
+
key: `${size}-letter-spacing`,
|
|
1772
|
+
property: "letter-spacing",
|
|
1773
|
+
description: `\`${size}\` tracking.`,
|
|
1774
|
+
consumers: at(BUTTON, "var(--button-letter-spacing, revert-layer)")
|
|
1775
|
+
},
|
|
1776
|
+
{
|
|
1777
|
+
key: `${size}-radius`,
|
|
1778
|
+
property: "border-radius",
|
|
1779
|
+
description: `\`${size}\` corner rounding.`,
|
|
1780
|
+
consumers: at(BUTTON, `var(--button-radius, ${radius})`)
|
|
1781
|
+
}
|
|
1782
|
+
]),
|
|
1783
|
+
// VI-659: the icon-only size. A square box of glyph + 2 × pad.
|
|
1784
|
+
// VI-658: InlineEdit's pencil is the same mark, so it reads the same size,
|
|
1785
|
+
// pad and ink.
|
|
1786
|
+
{
|
|
1787
|
+
key: "icon-size",
|
|
1788
|
+
property: "width / height / font-size",
|
|
1789
|
+
description: 'Icon-only (`size="icon"`) glyph size. The square box is this plus `icon-pad` on every side. Also sizes the InlineEdit pencil and the SaveStatus retry mark.',
|
|
1790
|
+
consumers: [...each(Array(5).fill(BUTTON), "1rem"), ...each(Array(3).fill(INLINE_EDIT), "1rem"), ...each(Array(3).fill(SAVE_STATUS), "1rem")]
|
|
1791
|
+
},
|
|
1792
|
+
{
|
|
1793
|
+
key: "icon-pad",
|
|
1794
|
+
property: "width / height",
|
|
1795
|
+
description: "Icon-only hit-target pad around the glyph, on every side. Also the hit target of the InlineEdit pencil and the SaveStatus retry mark.",
|
|
1796
|
+
consumers: [...each([BUTTON, BUTTON], "var(--spacing-2, 0.5rem)"), ...at(INLINE_EDIT, "var(--spacing-2, 0.5rem)"), ...at(SAVE_STATUS, "var(--spacing-2, 0.5rem)")]
|
|
1797
|
+
},
|
|
1798
|
+
{
|
|
1799
|
+
key: "icon-radius",
|
|
1800
|
+
property: "border-radius",
|
|
1801
|
+
description: "Icon-only corner rounding (`999px` for a round mark).",
|
|
1802
|
+
consumers: at(BUTTON, "var(--button-radius, var(--radius-md, 0.375rem))")
|
|
1803
|
+
},
|
|
1804
|
+
{
|
|
1805
|
+
key: "icon-ghost-color",
|
|
1806
|
+
property: "color",
|
|
1807
|
+
description: "Icon-only ghost ink at rest. Hover comes up to `--text-primary`. Also the ink of the InlineEdit pencil and the SaveStatus retry mark.",
|
|
1808
|
+
consumers: [...at(BUTTON, "var(--text-secondary, #6b7280)"), ...at(INLINE_EDIT, "var(--text-secondary, #6b7280)"), ...at(SAVE_STATUS, "var(--text-secondary, #6b7280)")]
|
|
1809
|
+
}
|
|
1810
|
+
]
|
|
1811
|
+
};
|
|
1812
|
+
var TEXT_SIZES = [
|
|
1813
|
+
{ size: "xs", fontSize: "var(--font-size-xs, 0.75rem)" },
|
|
1814
|
+
{ size: "sm", fontSize: "var(--font-size-sm, 0.875rem)" },
|
|
1815
|
+
{ size: "md", fontSize: "var(--font-size-base, 1rem)" },
|
|
1816
|
+
{ size: "lg", fontSize: "var(--font-size-lg, 1.125rem)" },
|
|
1817
|
+
{ size: "xl", fontSize: "var(--font-size-xl, 1.25rem)" }
|
|
1818
|
+
];
|
|
1819
|
+
var textFamily = {
|
|
1820
|
+
family: "text",
|
|
1821
|
+
prefix: "text",
|
|
1822
|
+
description: "Text type treatment, per size \u2014 set `sm-font-size: 13px` for a 13px step, or caps and tracking on `xs` for a state tag. Every key begins with a size.",
|
|
1823
|
+
tokens: TEXT_SIZES.flatMap(({ size, fontSize }) => [
|
|
1824
|
+
{ key: `${size}-font-size`, property: "font-size", description: `\`${size}\` type size.`, consumers: at(TEXT, fontSize) },
|
|
1825
|
+
{ key: `${size}-text-transform`, property: "text-transform", description: `\`${size}\` casing.`, consumers: at(TEXT, "revert-layer") },
|
|
1826
|
+
{ key: `${size}-letter-spacing`, property: "letter-spacing", description: `\`${size}\` tracking.`, consumers: at(TEXT, "revert-layer") }
|
|
1827
|
+
])
|
|
1828
|
+
};
|
|
1829
|
+
var switchFamily = {
|
|
1830
|
+
family: "switch",
|
|
1831
|
+
prefix: "switch",
|
|
1832
|
+
description: 'Switch track and knob dimensions (default size; `size="sm"` keeps its own). Set `knob-inset` to size the knob from the track: it sits that far from the track\'s outer edge on every side.',
|
|
1833
|
+
tokens: [
|
|
1834
|
+
{ key: "track-width", property: "width", description: "Track width.", consumers: at(SWITCH, "2rem") },
|
|
1835
|
+
{
|
|
1836
|
+
key: "track-height",
|
|
1837
|
+
property: "height",
|
|
1838
|
+
description: "Track height. With `knob-inset` set, the knob is the track height less the inset on both sides.",
|
|
1839
|
+
consumers: at(SWITCH, "1.15rem")
|
|
1840
|
+
},
|
|
1841
|
+
{
|
|
1842
|
+
key: "knob-inset",
|
|
1843
|
+
property: "width / height / transform (knob)",
|
|
1844
|
+
description: "Gap between the knob and the track's outer edge, on every side. Unset, the knob keeps its shipped 1rem size and position.",
|
|
1845
|
+
consumers: at(SWITCH, null)
|
|
1846
|
+
},
|
|
1847
|
+
{ key: "track-bg", property: "background-color", description: "Unchecked track fill.", consumers: at(SWITCH, "var(--border-default, #e5e7eb)") },
|
|
1848
|
+
{
|
|
1849
|
+
key: "edge-color",
|
|
1850
|
+
property: "outline-color",
|
|
1851
|
+
description: "Track edge colour \u2014 transparent by default. Width and style come from the shared `control` edge, so `control.edge-width: 0` turns it off.",
|
|
1852
|
+
consumers: at(SWITCH, "transparent")
|
|
1853
|
+
}
|
|
1854
|
+
]
|
|
1855
|
+
};
|
|
1856
|
+
var saveStatusFamily = {
|
|
1857
|
+
family: "save-status",
|
|
1858
|
+
prefix: "save-status",
|
|
1859
|
+
description: "SaveStatus readout \u2014 the fixed-width slot and its type, so the readout never reflows its row.",
|
|
1860
|
+
tokens: [
|
|
1861
|
+
{ key: "width", property: "width", description: "Slot width. Fixed, so the row never reflows between states.", consumers: at(SAVE_STATUS, "7.5rem") },
|
|
1862
|
+
{ key: "font-family", property: "font-family", description: "Readout family (e.g. the theme's mono).", consumers: at(SAVE_STATUS, "revert-layer") },
|
|
1863
|
+
{ key: "text-transform", property: "text-transform", description: "Readout casing.", consumers: at(SAVE_STATUS, "revert-layer") },
|
|
1864
|
+
{ key: "letter-spacing", property: "letter-spacing", description: "Readout tracking.", consumers: at(SAVE_STATUS, "revert-layer") }
|
|
1612
1865
|
]
|
|
1613
1866
|
};
|
|
1614
1867
|
var adminUiFamily = {
|
|
@@ -1639,6 +1892,12 @@ var COMPONENT_TOKEN_FAMILIES = [
|
|
|
1639
1892
|
skeletonFamily,
|
|
1640
1893
|
spinnerFamily,
|
|
1641
1894
|
checkboxFamily,
|
|
1895
|
+
controlFamily,
|
|
1896
|
+
fieldFamily,
|
|
1897
|
+
buttonFamily,
|
|
1898
|
+
textFamily,
|
|
1899
|
+
switchFamily,
|
|
1900
|
+
saveStatusFamily,
|
|
1642
1901
|
adminUiFamily
|
|
1643
1902
|
];
|
|
1644
1903
|
var COMPONENT_TOKEN_FAMILY_BY_NAME = new Map(
|
|
@@ -2484,6 +2743,86 @@ function generateFullBundleCss(primitives, tokens, config) {
|
|
|
2484
2743
|
return lines.join("\n");
|
|
2485
2744
|
}
|
|
2486
2745
|
|
|
2746
|
+
// src/semantic-aliases.ts
|
|
2747
|
+
var VISOR_CORE_SEMANTIC_ALIASES = {
|
|
2748
|
+
// Border — the one entry the engine's own `SemanticTokens.border` set lacks.
|
|
2749
|
+
"border-input": "color-neutral-200",
|
|
2750
|
+
// Component + layout spacing (4px grid multiples).
|
|
2751
|
+
"component-xs": "spacing-1",
|
|
2752
|
+
"component-sm": "spacing-2",
|
|
2753
|
+
"component-md": "spacing-4",
|
|
2754
|
+
"component-lg": "spacing-6",
|
|
2755
|
+
"component-xl": "spacing-8",
|
|
2756
|
+
"layout-sm": "spacing-4",
|
|
2757
|
+
"layout-md": "spacing-8",
|
|
2758
|
+
"layout-lg": "spacing-12",
|
|
2759
|
+
"layout-xl": "spacing-16",
|
|
2760
|
+
"layout-2xl": "spacing-24",
|
|
2761
|
+
"layout-section-padding": "spacing-24",
|
|
2762
|
+
"layout-section-padding-mobile": "spacing-16",
|
|
2763
|
+
// Typography size roles — track the theme's `typography.scale` ramp.
|
|
2764
|
+
"size-body": "font-size-base",
|
|
2765
|
+
"size-body-sm": "font-size-sm",
|
|
2766
|
+
"size-label": "font-size-sm",
|
|
2767
|
+
"size-caption": "font-size-xs",
|
|
2768
|
+
"size-heading-sm": "font-size-lg",
|
|
2769
|
+
"size-heading-md": "font-size-xl",
|
|
2770
|
+
"size-heading-lg": "font-size-2xl",
|
|
2771
|
+
"size-heading-xl": "font-size-3xl",
|
|
2772
|
+
// Typography weight roles — `--weight-heading` is the token VI-648 was filed on.
|
|
2773
|
+
"weight-body": "font-weight-body",
|
|
2774
|
+
"weight-label": "font-weight-medium",
|
|
2775
|
+
"weight-heading": "font-weight-heading",
|
|
2776
|
+
"weight-strong": "font-weight-bold",
|
|
2777
|
+
// Motion. `--motion-easing-spring` is absent because the engine emits it
|
|
2778
|
+
// under its own name, so it is already correct on the scope.
|
|
2779
|
+
"motion-duration-fast": "motion-duration-100",
|
|
2780
|
+
"motion-duration-normal": "motion-duration-200",
|
|
2781
|
+
"motion-duration-slow": "motion-duration-500",
|
|
2782
|
+
"motion-easing-default": "motion-easing-ease-in-out",
|
|
2783
|
+
"motion-easing-enter": "motion-easing-ease-out",
|
|
2784
|
+
"motion-easing-exit": "motion-easing-ease-in",
|
|
2785
|
+
// Skeleton shimmer. Resolves through *semantic* surfaces, not primitives —
|
|
2786
|
+
// the engine emits those in `visor-adaptive`, a later layer, which does not
|
|
2787
|
+
// affect substitution: `var()` reads the computed value on the element.
|
|
2788
|
+
"skeleton-from": "surface-muted",
|
|
2789
|
+
"skeleton-to": "surface-subtle",
|
|
2790
|
+
// Chart series.
|
|
2791
|
+
"chart-1": "color-primary-500",
|
|
2792
|
+
"chart-2": "color-success-500",
|
|
2793
|
+
"chart-3": "color-warning-500",
|
|
2794
|
+
"chart-4": "color-info-500",
|
|
2795
|
+
"chart-5": "color-error-500",
|
|
2796
|
+
// Sidebar chrome.
|
|
2797
|
+
"sidebar-bg": "color-neutral-50",
|
|
2798
|
+
"sidebar-text": "color-neutral-700",
|
|
2799
|
+
"sidebar-primary-bg": "color-primary-600",
|
|
2800
|
+
"sidebar-primary-text": "color-white",
|
|
2801
|
+
"sidebar-accent-bg": "color-neutral-100",
|
|
2802
|
+
"sidebar-accent-text": "color-neutral-900",
|
|
2803
|
+
"sidebar-border": "color-neutral-200",
|
|
2804
|
+
"sidebar-ring": "color-primary-500",
|
|
2805
|
+
"sidebar-text-muted": "color-neutral-500",
|
|
2806
|
+
// Field-attached floating panels (VI-497).
|
|
2807
|
+
"field-menu-bg": "surface-popover"
|
|
2808
|
+
};
|
|
2809
|
+
function collectDeclaredProperties(css) {
|
|
2810
|
+
const declared = /* @__PURE__ */ new Set();
|
|
2811
|
+
for (const match of css.matchAll(/(^|[{;\s])--([a-zA-Z0-9-]+)\s*:/g)) {
|
|
2812
|
+
declared.add(match[2]);
|
|
2813
|
+
}
|
|
2814
|
+
return declared;
|
|
2815
|
+
}
|
|
2816
|
+
function generateSemanticAliasDecls(declared) {
|
|
2817
|
+
const decls = [];
|
|
2818
|
+
for (const [alias, referent] of Object.entries(VISOR_CORE_SEMANTIC_ALIASES)) {
|
|
2819
|
+
if (declared.has(alias)) continue;
|
|
2820
|
+
if (!declared.has(referent)) continue;
|
|
2821
|
+
decls.push(`--${alias}: var(--${referent});`);
|
|
2822
|
+
}
|
|
2823
|
+
return decls;
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2487
2826
|
// src/types.ts
|
|
2488
2827
|
var MATERIAL_TEXT_SLOTS = [
|
|
2489
2828
|
"displayLarge",
|
|
@@ -2577,5 +2916,8 @@ export {
|
|
|
2577
2916
|
generateHairlineDecls,
|
|
2578
2917
|
generateLightCss,
|
|
2579
2918
|
generateDarkCss,
|
|
2580
|
-
generateFullBundleCss
|
|
2919
|
+
generateFullBundleCss,
|
|
2920
|
+
VISOR_CORE_SEMANTIC_ALIASES,
|
|
2921
|
+
collectDeclaredProperties,
|
|
2922
|
+
generateSemanticAliasDecls
|
|
2581
2923
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FontResolveOptions, a as FontResolution, V as VisorTypography, b as FontDisplayStrategy, T as ThemeFontResult, G as GoogleFontEntry, c as VisorBrand, B as BrandSlot, d as BrandSource, e as BrandResolution, C as ColorScheme, f as ThemeBrandResult, g as BrandStrategy, h as BrandStrategyContext, i as BrandStrategyIssue, j as BrandStrategyValidationResult, S as SerializedBrandStrategy, R as ResolvedThemeConfig, k as GeneratedPrimitives, l as ThemeOutput, m as ThemeData, n as VisorThemeConfig, o as FullShadeScale, p as ColorRole, q as SelectiveShadeScale, r as RGB, P as ParsedColor, O as OKLCH, s as SemanticTokens, t as ShadeStep } from './types-
|
|
2
|
-
export { u as BRAND_VARIANTS, v as BRAND_VISIBILITIES, w as BrandAccessibility, x as BrandArchetype, y as BrandBoilerplate, z as BrandColorPairing, A as BrandColorUsage, D as BrandContrastTarget, E as BrandGoverns, H as BrandLexiconEntry, I as BrandMessaging, J as BrandPersonalityTrait, K as BrandPillar, L as BrandPositioning, M as BrandStrategyIssueSeverity, N as BrandToneEntry, Q as BrandVariant, U as BrandVisibility, W as BrandVoice, X as BrandVoiceTrait, Y as COMPONENT_TOKEN_FAMILIES, Z as COMPONENT_TOKEN_FAMILY_BY_NAME, _ as ColorFormat, $ as ComponentTokenBinding, a0 as ComponentTokenBindings, a1 as ComponentTokenConsumer, a2 as ComponentTokenFamily, a3 as ComponentTokenSpec, a4 as DEFAULT_BRAND_STRATEGY_SURFACES, a5 as DEFAULT_BRAND_STRATEGY_TONE_STATES, a6 as FontSource, a7 as GOVERNS_WILDCARD, a8 as RGBA, a9 as ResolvedComponentTokens, aa as SemanticTokenValue, ab as allComponentTokenNames, ac as componentTokenName, ad as hasComponentBindings, ae as resolveComponentBindings, af as validateComponentBindings } from './types-
|
|
1
|
+
import { F as FontResolveOptions, a as FontResolution, V as VisorTypography, b as FontDisplayStrategy, T as ThemeFontResult, G as GoogleFontEntry, c as VisorBrand, B as BrandSlot, d as BrandSource, e as BrandResolution, C as ColorScheme, f as ThemeBrandResult, g as BrandStrategy, h as BrandStrategyContext, i as BrandStrategyIssue, j as BrandStrategyValidationResult, S as SerializedBrandStrategy, R as ResolvedThemeConfig, k as GeneratedPrimitives, l as ThemeOutput, m as ThemeData, n as VisorThemeConfig, o as FullShadeScale, p as ColorRole, q as SelectiveShadeScale, r as RGB, P as ParsedColor, O as OKLCH, s as SemanticTokens, t as ShadeStep } from './types-Wy5n0W9F.js';
|
|
2
|
+
export { u as BRAND_VARIANTS, v as BRAND_VISIBILITIES, w as BrandAccessibility, x as BrandArchetype, y as BrandBoilerplate, z as BrandColorPairing, A as BrandColorUsage, D as BrandContrastTarget, E as BrandGoverns, H as BrandLexiconEntry, I as BrandMessaging, J as BrandPersonalityTrait, K as BrandPillar, L as BrandPositioning, M as BrandStrategyIssueSeverity, N as BrandToneEntry, Q as BrandVariant, U as BrandVisibility, W as BrandVoice, X as BrandVoiceTrait, Y as COMPONENT_TOKEN_FAMILIES, Z as COMPONENT_TOKEN_FAMILY_BY_NAME, _ as ColorFormat, $ as ComponentTokenBinding, a0 as ComponentTokenBindings, a1 as ComponentTokenConsumer, a2 as ComponentTokenFamily, a3 as ComponentTokenSpec, a4 as DEFAULT_BRAND_STRATEGY_SURFACES, a5 as DEFAULT_BRAND_STRATEGY_TONE_STATES, a6 as FontSource, a7 as GOVERNS_WILDCARD, a8 as RGBA, a9 as ResolvedComponentTokens, aa as SemanticTokenValue, ab as allComponentTokenNames, ac as componentTokenName, ad as hasComponentBindings, ae as resolveComponentBindings, af as validateComponentBindings } from './types-Wy5n0W9F.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Font resolver — maps font family names to loadable font resources.
|
|
@@ -400,6 +400,14 @@ var properties = {
|
|
|
400
400
|
],
|
|
401
401
|
description: "Brand constraint declaring which color modes the theme supports. 'dark-only'/'light-only' lock the brand to a single mode; 'adaptive' supports both. Complements 'default-mode' (the runtime default) — 'color-scheme' is authoritative for the brand-lock. Defaults to 'adaptive' when omitted. Optional."
|
|
402
402
|
},
|
|
403
|
+
edges: {
|
|
404
|
+
type: "string",
|
|
405
|
+
"enum": [
|
|
406
|
+
"on",
|
|
407
|
+
"off"
|
|
408
|
+
],
|
|
409
|
+
description: "The one switch for form-control edges (VI-655). 'off' removes the resting edge of every form control, dashed drop-target and empty-state edges included, with no layout shift; focus and invalid stay visible. Shorthand for components.control.edge-width: \"0\" (an explicit binding there wins). Defaults to 'on'. Optional."
|
|
410
|
+
},
|
|
403
411
|
colors: {
|
|
404
412
|
type: "object",
|
|
405
413
|
description: "Color definitions for light mode. Only primary is required — all others have sensible defaults.",
|
|
@@ -1123,7 +1131,14 @@ var properties = {
|
|
|
1123
1131
|
},
|
|
1124
1132
|
checkbox: {
|
|
1125
1133
|
type: "object",
|
|
1126
|
-
description: "Control sizing — the D3 Tier-2 `--checkbox-size` / `-radius` / `-bg` / `-border` set, promoted from the admin-ui audit to a bindable contract. Keys: size, radius, bg, border, bg-checked, border-checked.",
|
|
1134
|
+
description: "Control sizing — the D3 Tier-2 `--checkbox-size` / `-radius` / `-bg` / `-border` set, promoted from the admin-ui audit to a bindable contract. Keys: size, radius, bg, border, edgeless-bg, bg-checked, border-checked.",
|
|
1135
|
+
additionalProperties: {
|
|
1136
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1137
|
+
}
|
|
1138
|
+
},
|
|
1139
|
+
control: {
|
|
1140
|
+
type: "object",
|
|
1141
|
+
description: "The one switch for form-control edges (VI-655). Every form control draws its resting edge from these, so `edge-width: 0` removes every resting edge at once, dashed edges included, with no layout shift. Keys: edge-width, edge-color, edge-style, drop-edge-width, drop-edge-style, state-edge-width.",
|
|
1127
1142
|
additionalProperties: {
|
|
1128
1143
|
$ref: "#/$defs/componentTokenBinding"
|
|
1129
1144
|
}
|
|
@@ -1135,6 +1150,41 @@ var properties = {
|
|
|
1135
1150
|
$ref: "#/$defs/componentTokenBinding"
|
|
1136
1151
|
}
|
|
1137
1152
|
},
|
|
1153
|
+
field: {
|
|
1154
|
+
type: "object",
|
|
1155
|
+
description: "Field label treatment — size, case, tracking and colour of `FieldLabel`, in both densities. Keys: label-font-size, label-text-transform, label-letter-spacing, label-color.",
|
|
1156
|
+
additionalProperties: {
|
|
1157
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1158
|
+
}
|
|
1159
|
+
},
|
|
1160
|
+
button: {
|
|
1161
|
+
type: "object",
|
|
1162
|
+
description: "Button type treatment and rounding. The unprefixed keys set every size at once; a size key (`dlg-radius`) overrides one size. Keys: text-transform, letter-spacing, radius, sm-font-size, sm-text-transform, sm-letter-spacing, sm-radius, md-font-size, md-text-transform, md-letter-spacing, md-radius, lg-font-size, lg-text-transform, lg-letter-spacing, lg-radius, dlg-font-size, dlg-text-transform, dlg-letter-spacing, dlg-radius, icon-size, icon-pad, icon-radius, icon-ghost-color.",
|
|
1163
|
+
additionalProperties: {
|
|
1164
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1165
|
+
}
|
|
1166
|
+
},
|
|
1167
|
+
text: {
|
|
1168
|
+
type: "object",
|
|
1169
|
+
description: "Text type treatment, per size — set `sm-font-size: 13px` for a 13px step, or caps and tracking on `xs` for a state tag. Every key begins with a size. Keys: xs-font-size, xs-text-transform, xs-letter-spacing, sm-font-size, sm-text-transform, sm-letter-spacing, md-font-size, md-text-transform, md-letter-spacing, lg-font-size, lg-text-transform, lg-letter-spacing, xl-font-size, xl-text-transform, xl-letter-spacing.",
|
|
1170
|
+
additionalProperties: {
|
|
1171
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1172
|
+
}
|
|
1173
|
+
},
|
|
1174
|
+
"switch": {
|
|
1175
|
+
type: "object",
|
|
1176
|
+
description: "Switch track and knob dimensions (default size; `size=\"sm\"` keeps its own). Set `knob-inset` to size the knob from the track: it sits that far from the track's outer edge on every side. Keys: track-width, track-height, knob-inset, track-bg, edge-color.",
|
|
1177
|
+
additionalProperties: {
|
|
1178
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1179
|
+
}
|
|
1180
|
+
},
|
|
1181
|
+
"save-status": {
|
|
1182
|
+
type: "object",
|
|
1183
|
+
description: "SaveStatus readout — the fixed-width slot and its type, so the readout never reflows its row. Keys: width, font-family, text-transform, letter-spacing.",
|
|
1184
|
+
additionalProperties: {
|
|
1185
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1186
|
+
}
|
|
1187
|
+
},
|
|
1138
1188
|
"admin-ui": {
|
|
1139
1189
|
type: "object",
|
|
1140
1190
|
description: "Structural roles the admin-ui pattern owns. `marquee-family` is the display face for KPI hero figures and marquee page titles — the role the admin-ui portability audit named as the one piece of ENTR brand coupling a new theme must rebind. Keys: marquee-family.",
|
|
@@ -1876,6 +1926,87 @@ declare const SEMANTIC_MAP: {
|
|
|
1876
1926
|
*/
|
|
1877
1927
|
declare function getKnownTokenRefs(): Set<string>;
|
|
1878
1928
|
|
|
1929
|
+
/**
|
|
1930
|
+
* visor-core semantic aliases that need re-substituting at a theme scope (VI-648).
|
|
1931
|
+
*
|
|
1932
|
+
* `packages/tokens` emits its semantic layer as indirections — `--chart-1:
|
|
1933
|
+
* var(--color-primary-500)`, `--weight-heading: var(--font-weight-heading)` —
|
|
1934
|
+
* declared on `:root`.
|
|
1935
|
+
*
|
|
1936
|
+
* Custom-property substitution resolves **where the property is declared**. On
|
|
1937
|
+
* a `scopePrefix` theme (the VI-368 body-class repaint pattern that every
|
|
1938
|
+
* Blacklight theme uses) the engine emits the theme's primitives on the scope
|
|
1939
|
+
* selector, e.g. `body.blacklight-pro-theme`. From `:root`, a descendant's
|
|
1940
|
+
* value is invisible, so `var(--color-primary-500)` sees only visor-core's
|
|
1941
|
+
* untuned default. `body` then *inherits* the already-substituted default, and
|
|
1942
|
+
* the alias silently ignores the theme:
|
|
1943
|
+
*
|
|
1944
|
+
* ```
|
|
1945
|
+
* --font-weight-heading : 500 <- correct, emitted by the engine on the scope
|
|
1946
|
+
* --weight-heading : 600 <- visor-core's :root default
|
|
1947
|
+
* --chart-1 : #3b82f6 <- stock blue on a monochrome theme
|
|
1948
|
+
* --skeleton-from : #f3f4f6 <- light gray on a dark theme
|
|
1949
|
+
* ```
|
|
1950
|
+
*
|
|
1951
|
+
* The engine independently resolves 66 of visor-core's 114 aliases to concrete
|
|
1952
|
+
* values (`--text-*`, `--surface-*`, `--border-*`, `--interactive-*`, `--font-*`)
|
|
1953
|
+
* and emits those on the scope already, so they are correct. The 48 below are
|
|
1954
|
+
* the ones only visor-core knows how to derive. Re-declaring them on the scope
|
|
1955
|
+
* selector makes the substitution happen there, against the theme's own
|
|
1956
|
+
* primitives.
|
|
1957
|
+
*
|
|
1958
|
+
* ## Why this table lives in the engine, not in `packages/tokens`
|
|
1959
|
+
*
|
|
1960
|
+
* `packages/tokens` is the natural owner — these are its aliases. But
|
|
1961
|
+
* `packages/tokens` already depends on this package (its build calls
|
|
1962
|
+
* `generateThemeData` + `docsAdapter` to emit `dist/themes/<slug>.css`), so an
|
|
1963
|
+
* engine → tokens import would be a build cycle. The table therefore sits on
|
|
1964
|
+
* the importable side of that edge.
|
|
1965
|
+
*
|
|
1966
|
+
* It is not a hand-maintained copy. `packages/tokens` owns the authoring
|
|
1967
|
+
* tables in `src/tokens/semantic.ts` and this list is asserted against the
|
|
1968
|
+
* *emitted* `tokens.css` by `semantic-alias-coverage` — a stronger check than
|
|
1969
|
+
* comparing two constants, because it compares against what actually ships.
|
|
1970
|
+
* Adding an alias in `packages/tokens` without adding it here fails that test
|
|
1971
|
+
* with the missing names.
|
|
1972
|
+
*/
|
|
1973
|
+
/**
|
|
1974
|
+
* Alias name → the token it resolves through. Both written without the leading
|
|
1975
|
+
* `--`. Order mirrors visor-core's emission order in `tokens.css`, which keeps
|
|
1976
|
+
* a diff against that file readable.
|
|
1977
|
+
*/
|
|
1978
|
+
declare const VISOR_CORE_SEMANTIC_ALIASES: Readonly<Record<string, string>>;
|
|
1979
|
+
/**
|
|
1980
|
+
* Every custom property declared anywhere in `css`, without the leading `--`.
|
|
1981
|
+
*
|
|
1982
|
+
* Read off the generated CSS rather than the token data so the filter in
|
|
1983
|
+
* `generateSemanticAliasDecls` reflects what this theme *actually* emits —
|
|
1984
|
+
* including conditional output such as the `--font-weight-<n>` ladder, which
|
|
1985
|
+
* only appears when a theme declares an explicit `weights` array.
|
|
1986
|
+
*/
|
|
1987
|
+
declare function collectDeclaredProperties(css: string): Set<string>;
|
|
1988
|
+
/**
|
|
1989
|
+
* The `--alias: var(--referent);` declarations to re-emit on a theme's scope
|
|
1990
|
+
* selector, given everything the theme has emitted so far.
|
|
1991
|
+
*
|
|
1992
|
+
* Filtered on both sides, so the table can never make output worse:
|
|
1993
|
+
*
|
|
1994
|
+
* - **Skip an alias the theme already declares.** The theme's own value is
|
|
1995
|
+
* authoritative, and re-declaring it in `visor-semantic` would override a
|
|
1996
|
+
* `visor-primitives` declaration of the same name. `--font-body` is the live
|
|
1997
|
+
* case: the engine emits it as a concrete family, and re-aliasing it to
|
|
1998
|
+
* `var(--font-sans)` would win the layer contest and resolve to nothing.
|
|
1999
|
+
* - **Skip an alias whose referent the theme does not declare.** There is then
|
|
2000
|
+
* nothing to re-resolve against, and inheriting visor-core's `:root` value is
|
|
2001
|
+
* the correct outcome — re-emitting would replace a working value with an
|
|
2002
|
+
* invalid one.
|
|
2003
|
+
*
|
|
2004
|
+
* Returns `[]` for a `:root`-scoped theme's caller, which does not need this at
|
|
2005
|
+
* all: there, visor-core's aliases and the theme's primitives are declared on
|
|
2006
|
+
* the same element, so substitution already sees the theme's values.
|
|
2007
|
+
*/
|
|
2008
|
+
declare function generateSemanticAliasDecls(declared: ReadonlySet<string>): string[];
|
|
2009
|
+
|
|
1879
2010
|
/**
|
|
1880
2011
|
* Per-theme font-family aliasing — substrate fix for VI-354.
|
|
1881
2012
|
*
|
|
@@ -2126,4 +2257,4 @@ declare function cleanFontValue(val: string): string;
|
|
|
2126
2257
|
*/
|
|
2127
2258
|
declare function extractFromCSS(files: CSSFile[], name?: string): ExtractionResult;
|
|
2128
2259
|
|
|
2129
|
-
export { type BrandPassthrough, BrandResolution, BrandSlot, BrandSource, BrandStrategy, BrandStrategyContext, BrandStrategyIssue, BrandStrategyValidationResult, type CSSFile, ColorRole, type Confidence, DEFAULT_VISOR_BRAND, type ExtractedToken, type ExtractionResult, FONT_WEIGHT_ALIASES, type FontCoverageError, type FontCoverageResult, FontDisplayStrategy, type FontFaceDeclaration, FontResolution, FontResolveOptions, FullShadeScale, GeneratedPrimitives, GoogleFontEntry, OKLCH, ParsedColor, RGB, ResolvedThemeConfig, type ResolvedWeightRamp, SEMANTIC_MAP, SelectiveShadeScale, SemanticTokens, SerializedBrandStrategy, ShadeStep, TAILWIND_GRAY, ThemeBrandResult, ThemeData, ThemeFontResult, ThemeOutput, type ThemeValidationResult, VISOR_BRANDS_CDN, VISOR_DEFAULT_BRAND_PATH, VISOR_FONTS_CDN, type ValidateOptions, type ValidationIssue, type ValidationSeverity, VisorBrand, VisorThemeConfig, VisorTypography, WEIGHT_RAMP_TARGETS, applyOverrides, assignSemanticTokens, buildVisorBrandUrl, buildVisorFontUrl, checkBrandStrategyCoherence, checkBrandStrategyStructure, clampToSrgb, cleanFontValue, collectBrandPassthrough, compositeOverBackground, declaresWeights, exportTheme, extractFromCSS, formatFontCoverageError, generateDarkCss, generateFontWeightDecls, generateFullBundleCss, generateLightCss, generatePreloadLinks, generatePrimitives, generatePrimitivesCss, generateSemanticCss, generateShadeScale, generateStylesheetLinks, generateTheme, generateThemeData, generateThemeDataFromConfig, generateThemeFromConfig, getContrastRatio, getKnownTokenRefs, getLuminance, googleFontsCatalog, hasBrandPassthrough, hexToOklch, hexToRgb, isValidColor, isValidHex, isVisorThemeConfig, loadedWeights, lookupFontWeightAlias, lookupGoogleFont, matchLoadedWeight, normalizeHex, oklchToHex, parseCSSDeclarations, parseColor, parseConfig, parseFontFaceDeclarations, parseHex, parseHsla, parseOklch, parseRgba, resolveBrandSlot, resolveBrandSource, resolveConfig, resolveFont, resolveRoleWeight, resolveThemeBrand, resolveThemeFonts, resolveWeightRamp, rgbToHex, serializeBrandStrategy, serializeColor, validate, validateBrandStrategy, validateConfig, validateFontCoverage, visorTheme_schema as visorThemeSchema };
|
|
2260
|
+
export { type BrandPassthrough, BrandResolution, BrandSlot, BrandSource, BrandStrategy, BrandStrategyContext, BrandStrategyIssue, BrandStrategyValidationResult, type CSSFile, ColorRole, type Confidence, DEFAULT_VISOR_BRAND, type ExtractedToken, type ExtractionResult, FONT_WEIGHT_ALIASES, type FontCoverageError, type FontCoverageResult, FontDisplayStrategy, type FontFaceDeclaration, FontResolution, FontResolveOptions, FullShadeScale, GeneratedPrimitives, GoogleFontEntry, OKLCH, ParsedColor, RGB, ResolvedThemeConfig, type ResolvedWeightRamp, SEMANTIC_MAP, SelectiveShadeScale, SemanticTokens, SerializedBrandStrategy, ShadeStep, TAILWIND_GRAY, ThemeBrandResult, ThemeData, ThemeFontResult, ThemeOutput, type ThemeValidationResult, VISOR_BRANDS_CDN, VISOR_CORE_SEMANTIC_ALIASES, VISOR_DEFAULT_BRAND_PATH, VISOR_FONTS_CDN, type ValidateOptions, type ValidationIssue, type ValidationSeverity, VisorBrand, VisorThemeConfig, VisorTypography, WEIGHT_RAMP_TARGETS, applyOverrides, assignSemanticTokens, buildVisorBrandUrl, buildVisorFontUrl, checkBrandStrategyCoherence, checkBrandStrategyStructure, clampToSrgb, cleanFontValue, collectBrandPassthrough, collectDeclaredProperties, compositeOverBackground, declaresWeights, exportTheme, extractFromCSS, formatFontCoverageError, generateDarkCss, generateFontWeightDecls, generateFullBundleCss, generateLightCss, generatePreloadLinks, generatePrimitives, generatePrimitivesCss, generateSemanticAliasDecls, generateSemanticCss, generateShadeScale, generateStylesheetLinks, generateTheme, generateThemeData, generateThemeDataFromConfig, generateThemeFromConfig, getContrastRatio, getKnownTokenRefs, getLuminance, googleFontsCatalog, hasBrandPassthrough, hexToOklch, hexToRgb, isValidColor, isValidHex, isVisorThemeConfig, loadedWeights, lookupFontWeightAlias, lookupGoogleFont, matchLoadedWeight, normalizeHex, oklchToHex, parseCSSDeclarations, parseColor, parseConfig, parseFontFaceDeclarations, parseHex, parseHsla, parseOklch, parseRgba, resolveBrandSlot, resolveBrandSource, resolveConfig, resolveFont, resolveRoleWeight, resolveThemeBrand, resolveThemeFonts, resolveWeightRamp, rgbToHex, serializeBrandStrategy, serializeColor, validate, validateBrandStrategy, validateConfig, validateFontCoverage, visorTheme_schema as visorThemeSchema };
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
MATERIAL_TEXT_SLOTS,
|
|
8
8
|
TAILWIND_GRAY,
|
|
9
9
|
VISOR_BRANDS_CDN,
|
|
10
|
+
VISOR_CORE_SEMANTIC_ALIASES,
|
|
10
11
|
VISOR_DEFAULT_BRAND_PATH,
|
|
11
12
|
VISOR_FONTS_CDN,
|
|
12
13
|
WEIGHT_RAMP_TARGETS,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
buildVisorFontUrl,
|
|
17
18
|
clampToSrgb,
|
|
18
19
|
collectBrandPassthrough,
|
|
20
|
+
collectDeclaredProperties,
|
|
19
21
|
componentTokenName,
|
|
20
22
|
compositeOverBackground,
|
|
21
23
|
declaresWeights,
|
|
@@ -25,6 +27,7 @@ import {
|
|
|
25
27
|
generateLightCss,
|
|
26
28
|
generatePreloadLinks,
|
|
27
29
|
generatePrimitivesCss,
|
|
30
|
+
generateSemanticAliasDecls,
|
|
28
31
|
generateSemanticCss,
|
|
29
32
|
generateShadeScale,
|
|
30
33
|
generateStylesheetLinks,
|
|
@@ -60,7 +63,7 @@ import {
|
|
|
60
63
|
rgbToOklch,
|
|
61
64
|
serializeColor,
|
|
62
65
|
validateComponentBindings
|
|
63
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-L5DQDEZV.js";
|
|
64
67
|
|
|
65
68
|
// src/fonts/validate-coverage.ts
|
|
66
69
|
var FONT_VAR_RE = /--font-(heading|display|body|sans|mono)\s*:\s*([^;]+);/g;
|
|
@@ -647,6 +650,11 @@ var visor_theme_schema_default = {
|
|
|
647
650
|
enum: ["dark-only", "light-only", "adaptive"],
|
|
648
651
|
description: "Brand constraint declaring which color modes the theme supports. 'dark-only'/'light-only' lock the brand to a single mode; 'adaptive' supports both. Complements 'default-mode' (the runtime default) \u2014 'color-scheme' is authoritative for the brand-lock. Defaults to 'adaptive' when omitted. Optional."
|
|
649
652
|
},
|
|
653
|
+
edges: {
|
|
654
|
+
type: "string",
|
|
655
|
+
enum: ["on", "off"],
|
|
656
|
+
description: `The one switch for form-control edges (VI-655). 'off' removes the resting edge of every form control, dashed drop-target and empty-state edges included, with no layout shift; focus and invalid stay visible. Shorthand for components.control.edge-width: "0" (an explicit binding there wins). Defaults to 'on'. Optional.`
|
|
657
|
+
},
|
|
650
658
|
colors: {
|
|
651
659
|
type: "object",
|
|
652
660
|
description: "Color definitions for light mode. Only primary is required \u2014 all others have sensible defaults.",
|
|
@@ -1162,7 +1170,14 @@ var visor_theme_schema_default = {
|
|
|
1162
1170
|
},
|
|
1163
1171
|
checkbox: {
|
|
1164
1172
|
type: "object",
|
|
1165
|
-
description: "Control sizing \u2014 the D3 Tier-2 `--checkbox-size` / `-radius` / `-bg` / `-border` set, promoted from the admin-ui audit to a bindable contract. Keys: size, radius, bg, border, bg-checked, border-checked.",
|
|
1173
|
+
description: "Control sizing \u2014 the D3 Tier-2 `--checkbox-size` / `-radius` / `-bg` / `-border` set, promoted from the admin-ui audit to a bindable contract. Keys: size, radius, bg, border, edgeless-bg, bg-checked, border-checked.",
|
|
1174
|
+
additionalProperties: {
|
|
1175
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1176
|
+
}
|
|
1177
|
+
},
|
|
1178
|
+
control: {
|
|
1179
|
+
type: "object",
|
|
1180
|
+
description: "The one switch for form-control edges (VI-655). Every form control draws its resting edge from these, so `edge-width: 0` removes every resting edge at once, dashed edges included, with no layout shift. Keys: edge-width, edge-color, edge-style, drop-edge-width, drop-edge-style, state-edge-width.",
|
|
1166
1181
|
additionalProperties: {
|
|
1167
1182
|
$ref: "#/$defs/componentTokenBinding"
|
|
1168
1183
|
}
|
|
@@ -1174,6 +1189,41 @@ var visor_theme_schema_default = {
|
|
|
1174
1189
|
$ref: "#/$defs/componentTokenBinding"
|
|
1175
1190
|
}
|
|
1176
1191
|
},
|
|
1192
|
+
field: {
|
|
1193
|
+
type: "object",
|
|
1194
|
+
description: "Field label treatment \u2014 size, case, tracking and colour of `FieldLabel`, in both densities. Keys: label-font-size, label-text-transform, label-letter-spacing, label-color.",
|
|
1195
|
+
additionalProperties: {
|
|
1196
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
button: {
|
|
1200
|
+
type: "object",
|
|
1201
|
+
description: "Button type treatment and rounding. The unprefixed keys set every size at once; a size key (`dlg-radius`) overrides one size. Keys: text-transform, letter-spacing, radius, sm-font-size, sm-text-transform, sm-letter-spacing, sm-radius, md-font-size, md-text-transform, md-letter-spacing, md-radius, lg-font-size, lg-text-transform, lg-letter-spacing, lg-radius, dlg-font-size, dlg-text-transform, dlg-letter-spacing, dlg-radius, icon-size, icon-pad, icon-radius, icon-ghost-color.",
|
|
1202
|
+
additionalProperties: {
|
|
1203
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1206
|
+
text: {
|
|
1207
|
+
type: "object",
|
|
1208
|
+
description: "Text type treatment, per size \u2014 set `sm-font-size: 13px` for a 13px step, or caps and tracking on `xs` for a state tag. Every key begins with a size. Keys: xs-font-size, xs-text-transform, xs-letter-spacing, sm-font-size, sm-text-transform, sm-letter-spacing, md-font-size, md-text-transform, md-letter-spacing, lg-font-size, lg-text-transform, lg-letter-spacing, xl-font-size, xl-text-transform, xl-letter-spacing.",
|
|
1209
|
+
additionalProperties: {
|
|
1210
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1211
|
+
}
|
|
1212
|
+
},
|
|
1213
|
+
switch: {
|
|
1214
|
+
type: "object",
|
|
1215
|
+
description: 'Switch track and knob dimensions (default size; `size="sm"` keeps its own). Set `knob-inset` to size the knob from the track: it sits that far from the track\'s outer edge on every side. Keys: track-width, track-height, knob-inset, track-bg, edge-color.',
|
|
1216
|
+
additionalProperties: {
|
|
1217
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1218
|
+
}
|
|
1219
|
+
},
|
|
1220
|
+
"save-status": {
|
|
1221
|
+
type: "object",
|
|
1222
|
+
description: "SaveStatus readout \u2014 the fixed-width slot and its type, so the readout never reflows its row. Keys: width, font-family, text-transform, letter-spacing.",
|
|
1223
|
+
additionalProperties: {
|
|
1224
|
+
$ref: "#/$defs/componentTokenBinding"
|
|
1225
|
+
}
|
|
1226
|
+
},
|
|
1177
1227
|
"admin-ui": {
|
|
1178
1228
|
type: "object",
|
|
1179
1229
|
description: "Structural roles the admin-ui pattern owns. `marquee-family` is the display face for KPI hero figures and marquee page titles \u2014 the role the admin-ui portability audit named as the one piece of ENTR brand coupling a new theme must rebind. Keys: marquee-family.",
|
|
@@ -1458,7 +1508,8 @@ var KNOWN_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
|
1458
1508
|
"strokeWidths",
|
|
1459
1509
|
"motion",
|
|
1460
1510
|
"overrides",
|
|
1461
|
-
"components"
|
|
1511
|
+
"components",
|
|
1512
|
+
"edges"
|
|
1462
1513
|
]);
|
|
1463
1514
|
var KNOWN_COLOR_KEYS = /* @__PURE__ */ new Set([
|
|
1464
1515
|
"primary",
|
|
@@ -1737,6 +1788,9 @@ function validateConfig(config) {
|
|
|
1737
1788
|
errors.push("'color-scheme' must be one of: dark-only, light-only, adaptive");
|
|
1738
1789
|
}
|
|
1739
1790
|
}
|
|
1791
|
+
if (obj.edges !== void 0 && obj.edges !== "on" && obj.edges !== "off") {
|
|
1792
|
+
errors.push("'edges' must be either 'on' or 'off'");
|
|
1793
|
+
}
|
|
1740
1794
|
if (typeof obj.colors !== "object" || obj.colors === null) {
|
|
1741
1795
|
errors.push("'colors' is required and must be an object");
|
|
1742
1796
|
return { valid: false, errors };
|
|
@@ -2117,7 +2171,12 @@ function resolveConfig(config) {
|
|
|
2117
2171
|
overrides: config.overrides,
|
|
2118
2172
|
// VI-625: component bindings pass through untouched — the contract in
|
|
2119
2173
|
// component-tokens.ts owns their shape, there is nothing to default.
|
|
2120
|
-
|
|
2174
|
+
// VI-655: `edges: off` folds in here as `control.edge-width: 0`, so every
|
|
2175
|
+
// adapter emits the switch through the same component-token path.
|
|
2176
|
+
components: config.edges === "off" ? {
|
|
2177
|
+
...config.components,
|
|
2178
|
+
control: { "edge-width": "0", ...config.components?.control }
|
|
2179
|
+
} : config.components,
|
|
2121
2180
|
originalColors,
|
|
2122
2181
|
colorFormats
|
|
2123
2182
|
};
|
|
@@ -4262,6 +4321,7 @@ export {
|
|
|
4262
4321
|
SEMANTIC_MAP,
|
|
4263
4322
|
TAILWIND_GRAY,
|
|
4264
4323
|
VISOR_BRANDS_CDN,
|
|
4324
|
+
VISOR_CORE_SEMANTIC_ALIASES,
|
|
4265
4325
|
VISOR_DEFAULT_BRAND_PATH,
|
|
4266
4326
|
VISOR_FONTS_CDN,
|
|
4267
4327
|
WEIGHT_RAMP_TARGETS,
|
|
@@ -4275,6 +4335,7 @@ export {
|
|
|
4275
4335
|
clampToSrgb,
|
|
4276
4336
|
cleanFontValue,
|
|
4277
4337
|
collectBrandPassthrough,
|
|
4338
|
+
collectDeclaredProperties,
|
|
4278
4339
|
componentTokenName,
|
|
4279
4340
|
compositeOverBackground,
|
|
4280
4341
|
declaresWeights,
|
|
@@ -4288,6 +4349,7 @@ export {
|
|
|
4288
4349
|
generatePreloadLinks,
|
|
4289
4350
|
generatePrimitives,
|
|
4290
4351
|
generatePrimitivesCss,
|
|
4352
|
+
generateSemanticAliasDecls,
|
|
4291
4353
|
generateSemanticCss,
|
|
4292
4354
|
generateShadeScale,
|
|
4293
4355
|
generateStylesheetLinks,
|
|
@@ -830,6 +830,14 @@ interface VisorThemeConfig {
|
|
|
830
830
|
* did before the contract existed.
|
|
831
831
|
*/
|
|
832
832
|
components?: ComponentTokenBindings;
|
|
833
|
+
/**
|
|
834
|
+
* VI-655: the one switch for form-control edges. `off` removes the resting
|
|
835
|
+
* edge of every form control — dashed drop-target and empty-state edges
|
|
836
|
+
* included — with no layout shift; focus and invalid stay visible. It is
|
|
837
|
+
* shorthand for `components.control.edge-width: "0"`, and an explicit
|
|
838
|
+
* `components.control.edge-width` wins over it. Default: `on`.
|
|
839
|
+
*/
|
|
840
|
+
edges?: "on" | "off";
|
|
833
841
|
/**
|
|
834
842
|
* Migration metadata — optional, additive, consumed by `visor migrate` commands.
|
|
835
843
|
* Does not affect CSS generation or theme application.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loworbitstudio/visor-theme-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Theme engine for the Visor design system — shade generation, token mapping, font resolution, and import/export for .visor.yaml themes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,6 +34,11 @@
|
|
|
34
34
|
"enum": ["dark-only", "light-only", "adaptive"],
|
|
35
35
|
"description": "Brand constraint declaring which color modes the theme supports. 'dark-only'/'light-only' lock the brand to a single mode; 'adaptive' supports both. Complements 'default-mode' (the runtime default) — 'color-scheme' is authoritative for the brand-lock. Defaults to 'adaptive' when omitted. Optional."
|
|
36
36
|
},
|
|
37
|
+
"edges": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"enum": ["on", "off"],
|
|
40
|
+
"description": "The one switch for form-control edges (VI-655). 'off' removes the resting edge of every form control, dashed drop-target and empty-state edges included, with no layout shift; focus and invalid stay visible. Shorthand for components.control.edge-width: \"0\" (an explicit binding there wins). Defaults to 'on'. Optional."
|
|
41
|
+
},
|
|
37
42
|
"colors": {
|
|
38
43
|
"type": "object",
|
|
39
44
|
"description": "Color definitions for light mode. Only primary is required — all others have sensible defaults.",
|
|
@@ -549,7 +554,14 @@
|
|
|
549
554
|
},
|
|
550
555
|
"checkbox": {
|
|
551
556
|
"type": "object",
|
|
552
|
-
"description": "Control sizing — the D3 Tier-2 `--checkbox-size` / `-radius` / `-bg` / `-border` set, promoted from the admin-ui audit to a bindable contract. Keys: size, radius, bg, border, bg-checked, border-checked.",
|
|
557
|
+
"description": "Control sizing — the D3 Tier-2 `--checkbox-size` / `-radius` / `-bg` / `-border` set, promoted from the admin-ui audit to a bindable contract. Keys: size, radius, bg, border, edgeless-bg, bg-checked, border-checked.",
|
|
558
|
+
"additionalProperties": {
|
|
559
|
+
"$ref": "#/$defs/componentTokenBinding"
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
"control": {
|
|
563
|
+
"type": "object",
|
|
564
|
+
"description": "The one switch for form-control edges (VI-655). Every form control draws its resting edge from these, so `edge-width: 0` removes every resting edge at once, dashed edges included, with no layout shift. Keys: edge-width, edge-color, edge-style, drop-edge-width, drop-edge-style, state-edge-width.",
|
|
553
565
|
"additionalProperties": {
|
|
554
566
|
"$ref": "#/$defs/componentTokenBinding"
|
|
555
567
|
}
|
|
@@ -561,6 +573,41 @@
|
|
|
561
573
|
"$ref": "#/$defs/componentTokenBinding"
|
|
562
574
|
}
|
|
563
575
|
},
|
|
576
|
+
"field": {
|
|
577
|
+
"type": "object",
|
|
578
|
+
"description": "Field label treatment — size, case, tracking and colour of `FieldLabel`, in both densities. Keys: label-font-size, label-text-transform, label-letter-spacing, label-color.",
|
|
579
|
+
"additionalProperties": {
|
|
580
|
+
"$ref": "#/$defs/componentTokenBinding"
|
|
581
|
+
}
|
|
582
|
+
},
|
|
583
|
+
"button": {
|
|
584
|
+
"type": "object",
|
|
585
|
+
"description": "Button type treatment and rounding. The unprefixed keys set every size at once; a size key (`dlg-radius`) overrides one size. Keys: text-transform, letter-spacing, radius, sm-font-size, sm-text-transform, sm-letter-spacing, sm-radius, md-font-size, md-text-transform, md-letter-spacing, md-radius, lg-font-size, lg-text-transform, lg-letter-spacing, lg-radius, dlg-font-size, dlg-text-transform, dlg-letter-spacing, dlg-radius, icon-size, icon-pad, icon-radius, icon-ghost-color.",
|
|
586
|
+
"additionalProperties": {
|
|
587
|
+
"$ref": "#/$defs/componentTokenBinding"
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
"text": {
|
|
591
|
+
"type": "object",
|
|
592
|
+
"description": "Text type treatment, per size — set `sm-font-size: 13px` for a 13px step, or caps and tracking on `xs` for a state tag. Every key begins with a size. Keys: xs-font-size, xs-text-transform, xs-letter-spacing, sm-font-size, sm-text-transform, sm-letter-spacing, md-font-size, md-text-transform, md-letter-spacing, lg-font-size, lg-text-transform, lg-letter-spacing, xl-font-size, xl-text-transform, xl-letter-spacing.",
|
|
593
|
+
"additionalProperties": {
|
|
594
|
+
"$ref": "#/$defs/componentTokenBinding"
|
|
595
|
+
}
|
|
596
|
+
},
|
|
597
|
+
"switch": {
|
|
598
|
+
"type": "object",
|
|
599
|
+
"description": "Switch track and knob dimensions (default size; `size=\"sm\"` keeps its own). Set `knob-inset` to size the knob from the track: it sits that far from the track's outer edge on every side. Keys: track-width, track-height, knob-inset, track-bg, edge-color.",
|
|
600
|
+
"additionalProperties": {
|
|
601
|
+
"$ref": "#/$defs/componentTokenBinding"
|
|
602
|
+
}
|
|
603
|
+
},
|
|
604
|
+
"save-status": {
|
|
605
|
+
"type": "object",
|
|
606
|
+
"description": "SaveStatus readout — the fixed-width slot and its type, so the readout never reflows its row. Keys: width, font-family, text-transform, letter-spacing.",
|
|
607
|
+
"additionalProperties": {
|
|
608
|
+
"$ref": "#/$defs/componentTokenBinding"
|
|
609
|
+
}
|
|
610
|
+
},
|
|
564
611
|
"admin-ui": {
|
|
565
612
|
"type": "object",
|
|
566
613
|
"description": "Structural roles the admin-ui pattern owns. `marquee-family` is the display face for KPI hero figures and marquee page titles — the role the admin-ui portability audit named as the one piece of ENTR brand coupling a new theme must rebind. Keys: marquee-family.",
|