okchroma 0.5.1 → 0.6.1
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/README.md +1 -1
- package/dist-lib/index.cjs +239 -1
- package/dist-lib/index.mjs +239 -1
- package/dist-lib/types/engine/interaction.d.ts +35 -0
- package/dist-lib/types/engine/tokensRender.d.ts +51 -0
- package/dist-lib/types/index.d.ts +2 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ const css = brandCss('acme', 'Acme', theme.themed, theme.secondary?.scale ?? nul
|
|
|
41
41
|
// and data-theme="dark" on it for dark mode
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
The Figma tree comes from `themeToFigma`. Signatures, the full input, and an end-to-end example:
|
|
44
|
+
The same values as one object per mode come from `themeTokens`, and the state layer as named rows from `interactionCss` and `interactionTokens` (`docs/agents.md` lists the rows). The Figma tree comes from `themeToFigma`. Signatures, the full input, and an end-to-end example:
|
|
45
45
|
[Install and API](https://egerrity.github.io/okchroma/#/docs/install).
|
|
46
46
|
|
|
47
47
|
## Run from source
|
package/dist-lib/index.cjs
CHANGED
|
@@ -24,7 +24,12 @@ __export(index_exports, {
|
|
|
24
24
|
DEFAULT_LINK_HEX: () => DEFAULT_LINK_HEX,
|
|
25
25
|
DISABLED_OPACITY: () => DISABLED_OPACITY,
|
|
26
26
|
EXT_KEY: () => EXT_KEY,
|
|
27
|
+
INTERACTION_FAMILIES: () => INTERACTION_FAMILIES,
|
|
28
|
+
INTERACTION_LADDER: () => INTERACTION_LADDER,
|
|
29
|
+
INTERACTION_POLE_FAMILY: () => INTERACTION_POLE_FAMILY,
|
|
30
|
+
INTERACTION_ROWS: () => INTERACTION_ROWS,
|
|
27
31
|
INTERACTION_RUNGS: () => INTERACTION_RUNGS,
|
|
32
|
+
INTERACTION_STATES: () => INTERACTION_STATES,
|
|
28
33
|
MODE_SPECS: () => MODE_SPECS,
|
|
29
34
|
OFFSET_ALPHAS: () => OFFSET_ALPHAS,
|
|
30
35
|
OPACITY_RUNGS: () => OPACITY_RUNGS,
|
|
@@ -60,6 +65,11 @@ __export(index_exports, {
|
|
|
60
65
|
generateNeutralScale: () => generateNeutralScale,
|
|
61
66
|
generateScale: () => generateScale,
|
|
62
67
|
generateSubtleSecondary: () => generateSubtleSecondary,
|
|
68
|
+
interactionCss: () => interactionCss,
|
|
69
|
+
interactionRows: () => interactionRows,
|
|
70
|
+
interactionTintName: () => interactionTintName,
|
|
71
|
+
interactionTokens: () => interactionTokens,
|
|
72
|
+
interactionVarName: () => interactionVarName,
|
|
63
73
|
neutralCss: () => neutralCss,
|
|
64
74
|
neutralTintHue: () => neutralTintHue,
|
|
65
75
|
opacityLeafName: () => opacityLeafName,
|
|
@@ -67,19 +77,24 @@ __export(index_exports, {
|
|
|
67
77
|
opacityVarName: () => opacityVarName,
|
|
68
78
|
pageStopFor: () => pageStopFor,
|
|
69
79
|
parseToken: () => parseToken,
|
|
80
|
+
readEmission: () => readEmission,
|
|
70
81
|
resolveBrand: () => resolveBrand,
|
|
71
82
|
resolveDtcgRamp: () => resolveDtcgRamp,
|
|
72
83
|
resolveLinkInverseTrio: () => resolveLinkInverseTrio,
|
|
73
84
|
resolveLinkTrio: () => resolveLinkTrio,
|
|
85
|
+
resolveReferences: () => resolveReferences,
|
|
74
86
|
resolveTheme: () => resolveTheme,
|
|
75
87
|
signalScalesFor: () => signalScalesFor,
|
|
76
88
|
signalsCss: () => signalsCss,
|
|
77
89
|
stopHex: () => stopHex,
|
|
78
90
|
stopTokenName: () => stopTokenName,
|
|
79
91
|
stopsToVars: () => stopsToVars,
|
|
92
|
+
systemCss: () => systemCss,
|
|
80
93
|
themeToFigma: () => themeToFigma,
|
|
94
|
+
themeTokens: () => themeTokens,
|
|
81
95
|
toHex: () => toHex2,
|
|
82
|
-
tokenOrder: () => tokenOrder
|
|
96
|
+
tokenOrder: () => tokenOrder,
|
|
97
|
+
tokensFromEmission: () => tokensFromEmission
|
|
83
98
|
});
|
|
84
99
|
module.exports = __toCommonJS(index_exports);
|
|
85
100
|
|
|
@@ -3828,6 +3843,229 @@ function brandCss(slug, displayName, r, secondary, noteSuffix = "", neutralLevel
|
|
|
3828
3843
|
].join("\n");
|
|
3829
3844
|
}
|
|
3830
3845
|
|
|
3846
|
+
// src/engine/tokensRender.ts
|
|
3847
|
+
var DARK_MARK = '[data-theme="dark"]';
|
|
3848
|
+
function readEmission(css) {
|
|
3849
|
+
const light = /* @__PURE__ */ new Map();
|
|
3850
|
+
const dark = /* @__PURE__ */ new Map();
|
|
3851
|
+
const order = [];
|
|
3852
|
+
let depth = 0;
|
|
3853
|
+
let skipUntilDepth = -1;
|
|
3854
|
+
let inDark = false;
|
|
3855
|
+
let inBlock = false;
|
|
3856
|
+
for (const line of css.split("\n")) {
|
|
3857
|
+
const t = line.trim();
|
|
3858
|
+
if (t.endsWith("{")) {
|
|
3859
|
+
if (t.startsWith("@")) {
|
|
3860
|
+
if (skipUntilDepth < 0) skipUntilDepth = depth;
|
|
3861
|
+
depth++;
|
|
3862
|
+
continue;
|
|
3863
|
+
}
|
|
3864
|
+
depth++;
|
|
3865
|
+
if (skipUntilDepth < 0) {
|
|
3866
|
+
inBlock = true;
|
|
3867
|
+
inDark = t.includes(DARK_MARK);
|
|
3868
|
+
}
|
|
3869
|
+
continue;
|
|
3870
|
+
}
|
|
3871
|
+
if (t === "}") {
|
|
3872
|
+
depth--;
|
|
3873
|
+
if (skipUntilDepth >= 0 && depth === skipUntilDepth) skipUntilDepth = -1;
|
|
3874
|
+
inBlock = false;
|
|
3875
|
+
continue;
|
|
3876
|
+
}
|
|
3877
|
+
if (skipUntilDepth >= 0 || !inBlock || !t.startsWith("--")) continue;
|
|
3878
|
+
const colon = t.indexOf(":");
|
|
3879
|
+
if (colon === -1) continue;
|
|
3880
|
+
const name = t.slice(2, colon).trim();
|
|
3881
|
+
const value = t.slice(colon + 1).replace(/;$/, "").trim();
|
|
3882
|
+
const target = inDark ? dark : light;
|
|
3883
|
+
if (!light.has(name) && !dark.has(name)) order.push(name);
|
|
3884
|
+
target.set(name, value);
|
|
3885
|
+
}
|
|
3886
|
+
return { light, dark, order };
|
|
3887
|
+
}
|
|
3888
|
+
var VAR_REF = /var\(--([a-z0-9-]+)(?:\s*,\s*([^)]*))?\)/g;
|
|
3889
|
+
function resolveReferences(own, shared) {
|
|
3890
|
+
const out = {};
|
|
3891
|
+
const lookup = (name) => own.get(name) ?? shared.get(name);
|
|
3892
|
+
const resolve = (value, depth) => depth > 12 ? value : value.replace(VAR_REF, (_, ref, fallback) => {
|
|
3893
|
+
const target = lookup(ref);
|
|
3894
|
+
if (target !== void 0) return resolve(target, depth + 1);
|
|
3895
|
+
return fallback !== void 0 ? resolve(fallback.trim(), depth + 1) : `var(--${ref})`;
|
|
3896
|
+
});
|
|
3897
|
+
for (const name of /* @__PURE__ */ new Set([...own.keys(), ...shared.keys()])) out[name] = resolve(lookup(name), 0);
|
|
3898
|
+
return out;
|
|
3899
|
+
}
|
|
3900
|
+
function systemCss() {
|
|
3901
|
+
const planeRef = (stop) => stop === PAPER_0 ? `var(--${PAPER_0})` : `var(--${CSS_FAMILY.neutral}-${stop})`;
|
|
3902
|
+
const pad = (r) => String(r).padStart(2, "0");
|
|
3903
|
+
const lines = (mode) => [
|
|
3904
|
+
...Object.entries(SURFACE_PLANE_LAW).map(([leaf, stops]) => ` --surface-${leaf.split("/").pop()}: ${planeRef(stops[mode])};`),
|
|
3905
|
+
...Object.keys(SHADOW_ALPHAS).map(Number).map((r) => ` --shadow-${pad(r)}: rgba(0, 0, 0, ${SHADOW_ALPHAS[r][mode]});`),
|
|
3906
|
+
` --scrim: rgba(0, 0, 0, ${SCRIM_ALPHA});`,
|
|
3907
|
+
` --disabled-opacity: ${DISABLED_OPACITY};`
|
|
3908
|
+
];
|
|
3909
|
+
return [":root {", ...lines("light"), "}", `:root${DARK_MARK}, ${DARK_MARK} {`, ...lines("dark"), "}"].join("\n");
|
|
3910
|
+
}
|
|
3911
|
+
function tokensFromEmission(slug, css) {
|
|
3912
|
+
const { light, dark, order } = readEmission(css);
|
|
3913
|
+
const resolvedLight = resolveReferences(light, /* @__PURE__ */ new Map());
|
|
3914
|
+
const resolvedDark = resolveReferences(dark, light);
|
|
3915
|
+
const invariant = order.filter((n) => !dark.has(n) || light.has(n) && light.get(n) === dark.get(n));
|
|
3916
|
+
const raw = { light: Object.fromEntries(light), dark: Object.fromEntries(dark) };
|
|
3917
|
+
return { slug, names: order, light: resolvedLight, dark: resolvedDark, invariant, raw };
|
|
3918
|
+
}
|
|
3919
|
+
function themeTokens(input) {
|
|
3920
|
+
const css = [
|
|
3921
|
+
signalsCss(input.contrastProfile),
|
|
3922
|
+
systemCss(),
|
|
3923
|
+
brandCss(
|
|
3924
|
+
input.slug,
|
|
3925
|
+
input.displayName ?? input.slug,
|
|
3926
|
+
input.brand,
|
|
3927
|
+
input.secondary ?? null,
|
|
3928
|
+
"",
|
|
3929
|
+
input.neutralLevel ?? "default",
|
|
3930
|
+
input.contrastProfile,
|
|
3931
|
+
input.secondaryStyle,
|
|
3932
|
+
input.ctaEscape,
|
|
3933
|
+
input.linkHex ?? null,
|
|
3934
|
+
input.ctaBorder ?? true,
|
|
3935
|
+
input.neutralH
|
|
3936
|
+
)
|
|
3937
|
+
].join("\n");
|
|
3938
|
+
return tokensFromEmission(input.slug, css);
|
|
3939
|
+
}
|
|
3940
|
+
|
|
3941
|
+
// src/engine/interaction.ts
|
|
3942
|
+
var INTERACTION_POLE_FAMILY = { strong: "neutral-strong", inverse: "neutral-inverse" };
|
|
3943
|
+
var INTERACTION_FAMILIES = [
|
|
3944
|
+
CSS_FAMILY.neutral,
|
|
3945
|
+
CSS_FAMILY.brandPrimary,
|
|
3946
|
+
CSS_FAMILY.brandSecondary,
|
|
3947
|
+
...SIGNALS2.map((s) => s.emitName),
|
|
3948
|
+
INTERACTION_POLE_FAMILY.strong,
|
|
3949
|
+
INTERACTION_POLE_FAMILY.inverse
|
|
3950
|
+
];
|
|
3951
|
+
var INTERACTION_STATES = ["enabled", "hover", "pressed", "selected"];
|
|
3952
|
+
var INTERACTION_LADDER = {
|
|
3953
|
+
subtle: { enabled: 12, hover: 16, pressed: 24, selected: 32 },
|
|
3954
|
+
hint: { enabled: null, hover: 8, pressed: 12, selected: 16 }
|
|
3955
|
+
};
|
|
3956
|
+
var INTERACTION_ROWS = [
|
|
3957
|
+
"fg",
|
|
3958
|
+
"fg-strong",
|
|
3959
|
+
"fg-on-hint",
|
|
3960
|
+
"solid-bg-enabled",
|
|
3961
|
+
"solid-bg-hover",
|
|
3962
|
+
"solid-bg-pressed",
|
|
3963
|
+
"solid-border",
|
|
3964
|
+
"solid-fg",
|
|
3965
|
+
"subtle-bg-enabled",
|
|
3966
|
+
"subtle-bg-hover",
|
|
3967
|
+
"subtle-bg-pressed",
|
|
3968
|
+
"subtle-bg-selected",
|
|
3969
|
+
"hint-bg-enabled",
|
|
3970
|
+
"hint-bg-hover",
|
|
3971
|
+
"hint-bg-pressed",
|
|
3972
|
+
"hint-bg-selected"
|
|
3973
|
+
];
|
|
3974
|
+
var interactionVarName = (family, row) => `--${family}-${row}`;
|
|
3975
|
+
var isPole = (family) => family === INTERACTION_POLE_FAMILY.strong || family === INTERACTION_POLE_FAMILY.inverse;
|
|
3976
|
+
var hexChannels = (hex) => {
|
|
3977
|
+
const m = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex.trim());
|
|
3978
|
+
return m ? [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)] : null;
|
|
3979
|
+
};
|
|
3980
|
+
function interactionTintName(family) {
|
|
3981
|
+
if (family === INTERACTION_POLE_FAMILY.strong) return PEN_100;
|
|
3982
|
+
if (family === INTERACTION_POLE_FAMILY.inverse) return PAPER_0;
|
|
3983
|
+
return `${family}-${stopTokenName(8)}`;
|
|
3984
|
+
}
|
|
3985
|
+
function interactionRows(family, mode, tokens) {
|
|
3986
|
+
const neutral = CSS_FAMILY.neutral;
|
|
3987
|
+
const v2 = (name) => `var(--${name})`;
|
|
3988
|
+
const pen = (stop) => `${family}-${stopTokenName(stop)}`;
|
|
3989
|
+
const tintHex = tokens[mode][interactionTintName(family)];
|
|
3990
|
+
const ch = tintHex ? hexChannels(tintHex) : null;
|
|
3991
|
+
if (!ch) throw new Error(`interactionRows: no sRGB hex for ${interactionTintName(family)} in ${mode}`);
|
|
3992
|
+
const at = (rung) => rung === null ? v2(TRANSPARENT_VAR.slice(2)) : `rgba(${ch[0]}, ${ch[1]}, ${ch[2]}, ${OPACITY_RUNGS[rung]})`;
|
|
3993
|
+
const text = isPole(family) ? [["fg", v2(interactionTintName(family))], ["fg-strong", v2(interactionTintName(family))], ["fg-on-hint", v2(interactionTintName(family))]] : [["fg", v2(pen(10))], ["fg-strong", v2(pen(11))], ["fg-on-hint", v2(pen(9))]];
|
|
3994
|
+
const solid = family === INTERACTION_POLE_FAMILY.strong ? [
|
|
3995
|
+
["solid-bg-enabled", v2(PEN_100)],
|
|
3996
|
+
["solid-bg-hover", v2(`${neutral}-${stopTokenName(11)}`)],
|
|
3997
|
+
["solid-bg-pressed", v2(`${neutral}-${stopTokenName(10)}`)],
|
|
3998
|
+
["solid-border", v2(TRANSPARENT_VAR.slice(2))],
|
|
3999
|
+
["solid-fg", v2(PAPER_0)]
|
|
4000
|
+
] : family === INTERACTION_POLE_FAMILY.inverse ? [
|
|
4001
|
+
["solid-bg-enabled", v2(PAPER_0)],
|
|
4002
|
+
["solid-bg-hover", v2(`${neutral}-${stopTokenName(2)}`)],
|
|
4003
|
+
["solid-bg-pressed", v2(`${neutral}-${stopTokenName(3)}`)],
|
|
4004
|
+
["solid-border", v2(TRANSPARENT_VAR.slice(2))],
|
|
4005
|
+
["solid-fg", v2(PEN_100)]
|
|
4006
|
+
] : [
|
|
4007
|
+
["solid-bg-enabled", v2(`${family}-${STAMP_FILL}`)],
|
|
4008
|
+
["solid-bg-hover", v2(`${family}-${STAMP_FILL_HOVER}`)],
|
|
4009
|
+
["solid-bg-pressed", v2(`${family}-${STAMP_FILL_PRESSED}`)],
|
|
4010
|
+
["solid-border", v2(`${family}-${STAMP_EDGE}`)],
|
|
4011
|
+
["solid-fg", v2(`${family}-${STAMP_ON}`)]
|
|
4012
|
+
];
|
|
4013
|
+
const ladder = (tier) => INTERACTION_STATES.map((state) => [`${tier}-bg-${state}`, at(INTERACTION_LADDER[tier][state])]);
|
|
4014
|
+
return [...text, ...solid, ...ladder("subtle"), ...ladder("hint")];
|
|
4015
|
+
}
|
|
4016
|
+
var rowVariesByMode = (row) => /^(subtle|hint)-bg-/.test(row) && row !== "hint-bg-enabled";
|
|
4017
|
+
function interactionCss(slug, tokens) {
|
|
4018
|
+
const scope = `[data-brand="${slug}"]`;
|
|
4019
|
+
const light = [];
|
|
4020
|
+
const dark = [];
|
|
4021
|
+
for (const family of INTERACTION_FAMILIES) {
|
|
4022
|
+
for (const [row, value] of interactionRows(family, "light", tokens)) light.push(` ${interactionVarName(family, row)}: ${value};`);
|
|
4023
|
+
for (const [row, value] of interactionRows(family, "dark", tokens)) if (rowVariesByMode(row)) dark.push(` ${interactionVarName(family, row)}: ${value};`);
|
|
4024
|
+
}
|
|
4025
|
+
const scoped = INTERACTION_FAMILIES.flatMap((family) => [
|
|
4026
|
+
`${scope} [data-family="${family}"], ${scope}[data-family="${family}"] {`,
|
|
4027
|
+
...INTERACTION_ROWS.map((row) => ` --${row}: var(${interactionVarName(family, row)});`),
|
|
4028
|
+
`}`
|
|
4029
|
+
]);
|
|
4030
|
+
return [
|
|
4031
|
+
`/* Interaction register: solid, subtle and hint tiers per family, the translucent rows at the engine's opacity rungs */`,
|
|
4032
|
+
`${scope} {`,
|
|
4033
|
+
...light,
|
|
4034
|
+
`}`,
|
|
4035
|
+
`${scope}[data-theme="dark"] {`,
|
|
4036
|
+
...dark,
|
|
4037
|
+
`}`,
|
|
4038
|
+
...scoped
|
|
4039
|
+
].join("\n");
|
|
4040
|
+
}
|
|
4041
|
+
function interactionTokens(tokens) {
|
|
4042
|
+
const add = (mode) => {
|
|
4043
|
+
const m = /* @__PURE__ */ new Map();
|
|
4044
|
+
for (const family of INTERACTION_FAMILIES)
|
|
4045
|
+
for (const [row, value] of interactionRows(family, mode, tokens)) m.set(interactionVarName(family, row).slice(2), value);
|
|
4046
|
+
return m;
|
|
4047
|
+
};
|
|
4048
|
+
const rawLight = add("light");
|
|
4049
|
+
const rawDark = add("dark");
|
|
4050
|
+
const baseLight = new Map(Object.entries(tokens.light));
|
|
4051
|
+
const baseDark = new Map(Object.entries(tokens.dark));
|
|
4052
|
+
const light = resolveReferences(rawLight, baseLight);
|
|
4053
|
+
const dark = resolveReferences(rawDark, baseDark);
|
|
4054
|
+
const names = [...tokens.names, ...rawLight.keys()];
|
|
4055
|
+
const invariant = [...tokens.invariant, ...[...rawLight.keys()].filter((n) => rawLight.get(n) === rawDark.get(n))];
|
|
4056
|
+
return {
|
|
4057
|
+
slug: tokens.slug,
|
|
4058
|
+
names,
|
|
4059
|
+
light: { ...tokens.light, ...Object.fromEntries([...rawLight.keys()].map((n) => [n, light[n]])) },
|
|
4060
|
+
dark: { ...tokens.dark, ...Object.fromEntries([...rawDark.keys()].map((n) => [n, dark[n]])) },
|
|
4061
|
+
invariant,
|
|
4062
|
+
raw: {
|
|
4063
|
+
light: { ...tokens.raw.light, ...Object.fromEntries(rawLight) },
|
|
4064
|
+
dark: { ...tokens.raw.dark, ...Object.fromEntries(rawDark) }
|
|
4065
|
+
}
|
|
4066
|
+
};
|
|
4067
|
+
}
|
|
4068
|
+
|
|
3831
4069
|
// src/engine/figmaRender.ts
|
|
3832
4070
|
var clamp01 = (v2) => Math.min(1, Math.max(0, v2));
|
|
3833
4071
|
var TRANSPARENT_TOKEN = {
|
package/dist-lib/index.mjs
CHANGED
|
@@ -3743,6 +3743,229 @@ function brandCss(slug, displayName, r, secondary, noteSuffix = "", neutralLevel
|
|
|
3743
3743
|
].join("\n");
|
|
3744
3744
|
}
|
|
3745
3745
|
|
|
3746
|
+
// src/engine/tokensRender.ts
|
|
3747
|
+
var DARK_MARK = '[data-theme="dark"]';
|
|
3748
|
+
function readEmission(css) {
|
|
3749
|
+
const light = /* @__PURE__ */ new Map();
|
|
3750
|
+
const dark = /* @__PURE__ */ new Map();
|
|
3751
|
+
const order = [];
|
|
3752
|
+
let depth = 0;
|
|
3753
|
+
let skipUntilDepth = -1;
|
|
3754
|
+
let inDark = false;
|
|
3755
|
+
let inBlock = false;
|
|
3756
|
+
for (const line of css.split("\n")) {
|
|
3757
|
+
const t = line.trim();
|
|
3758
|
+
if (t.endsWith("{")) {
|
|
3759
|
+
if (t.startsWith("@")) {
|
|
3760
|
+
if (skipUntilDepth < 0) skipUntilDepth = depth;
|
|
3761
|
+
depth++;
|
|
3762
|
+
continue;
|
|
3763
|
+
}
|
|
3764
|
+
depth++;
|
|
3765
|
+
if (skipUntilDepth < 0) {
|
|
3766
|
+
inBlock = true;
|
|
3767
|
+
inDark = t.includes(DARK_MARK);
|
|
3768
|
+
}
|
|
3769
|
+
continue;
|
|
3770
|
+
}
|
|
3771
|
+
if (t === "}") {
|
|
3772
|
+
depth--;
|
|
3773
|
+
if (skipUntilDepth >= 0 && depth === skipUntilDepth) skipUntilDepth = -1;
|
|
3774
|
+
inBlock = false;
|
|
3775
|
+
continue;
|
|
3776
|
+
}
|
|
3777
|
+
if (skipUntilDepth >= 0 || !inBlock || !t.startsWith("--")) continue;
|
|
3778
|
+
const colon = t.indexOf(":");
|
|
3779
|
+
if (colon === -1) continue;
|
|
3780
|
+
const name = t.slice(2, colon).trim();
|
|
3781
|
+
const value = t.slice(colon + 1).replace(/;$/, "").trim();
|
|
3782
|
+
const target = inDark ? dark : light;
|
|
3783
|
+
if (!light.has(name) && !dark.has(name)) order.push(name);
|
|
3784
|
+
target.set(name, value);
|
|
3785
|
+
}
|
|
3786
|
+
return { light, dark, order };
|
|
3787
|
+
}
|
|
3788
|
+
var VAR_REF = /var\(--([a-z0-9-]+)(?:\s*,\s*([^)]*))?\)/g;
|
|
3789
|
+
function resolveReferences(own, shared) {
|
|
3790
|
+
const out = {};
|
|
3791
|
+
const lookup = (name) => own.get(name) ?? shared.get(name);
|
|
3792
|
+
const resolve = (value, depth) => depth > 12 ? value : value.replace(VAR_REF, (_, ref, fallback) => {
|
|
3793
|
+
const target = lookup(ref);
|
|
3794
|
+
if (target !== void 0) return resolve(target, depth + 1);
|
|
3795
|
+
return fallback !== void 0 ? resolve(fallback.trim(), depth + 1) : `var(--${ref})`;
|
|
3796
|
+
});
|
|
3797
|
+
for (const name of /* @__PURE__ */ new Set([...own.keys(), ...shared.keys()])) out[name] = resolve(lookup(name), 0);
|
|
3798
|
+
return out;
|
|
3799
|
+
}
|
|
3800
|
+
function systemCss() {
|
|
3801
|
+
const planeRef = (stop) => stop === PAPER_0 ? `var(--${PAPER_0})` : `var(--${CSS_FAMILY.neutral}-${stop})`;
|
|
3802
|
+
const pad = (r) => String(r).padStart(2, "0");
|
|
3803
|
+
const lines = (mode) => [
|
|
3804
|
+
...Object.entries(SURFACE_PLANE_LAW).map(([leaf, stops]) => ` --surface-${leaf.split("/").pop()}: ${planeRef(stops[mode])};`),
|
|
3805
|
+
...Object.keys(SHADOW_ALPHAS).map(Number).map((r) => ` --shadow-${pad(r)}: rgba(0, 0, 0, ${SHADOW_ALPHAS[r][mode]});`),
|
|
3806
|
+
` --scrim: rgba(0, 0, 0, ${SCRIM_ALPHA});`,
|
|
3807
|
+
` --disabled-opacity: ${DISABLED_OPACITY};`
|
|
3808
|
+
];
|
|
3809
|
+
return [":root {", ...lines("light"), "}", `:root${DARK_MARK}, ${DARK_MARK} {`, ...lines("dark"), "}"].join("\n");
|
|
3810
|
+
}
|
|
3811
|
+
function tokensFromEmission(slug, css) {
|
|
3812
|
+
const { light, dark, order } = readEmission(css);
|
|
3813
|
+
const resolvedLight = resolveReferences(light, /* @__PURE__ */ new Map());
|
|
3814
|
+
const resolvedDark = resolveReferences(dark, light);
|
|
3815
|
+
const invariant = order.filter((n) => !dark.has(n) || light.has(n) && light.get(n) === dark.get(n));
|
|
3816
|
+
const raw = { light: Object.fromEntries(light), dark: Object.fromEntries(dark) };
|
|
3817
|
+
return { slug, names: order, light: resolvedLight, dark: resolvedDark, invariant, raw };
|
|
3818
|
+
}
|
|
3819
|
+
function themeTokens(input) {
|
|
3820
|
+
const css = [
|
|
3821
|
+
signalsCss(input.contrastProfile),
|
|
3822
|
+
systemCss(),
|
|
3823
|
+
brandCss(
|
|
3824
|
+
input.slug,
|
|
3825
|
+
input.displayName ?? input.slug,
|
|
3826
|
+
input.brand,
|
|
3827
|
+
input.secondary ?? null,
|
|
3828
|
+
"",
|
|
3829
|
+
input.neutralLevel ?? "default",
|
|
3830
|
+
input.contrastProfile,
|
|
3831
|
+
input.secondaryStyle,
|
|
3832
|
+
input.ctaEscape,
|
|
3833
|
+
input.linkHex ?? null,
|
|
3834
|
+
input.ctaBorder ?? true,
|
|
3835
|
+
input.neutralH
|
|
3836
|
+
)
|
|
3837
|
+
].join("\n");
|
|
3838
|
+
return tokensFromEmission(input.slug, css);
|
|
3839
|
+
}
|
|
3840
|
+
|
|
3841
|
+
// src/engine/interaction.ts
|
|
3842
|
+
var INTERACTION_POLE_FAMILY = { strong: "neutral-strong", inverse: "neutral-inverse" };
|
|
3843
|
+
var INTERACTION_FAMILIES = [
|
|
3844
|
+
CSS_FAMILY.neutral,
|
|
3845
|
+
CSS_FAMILY.brandPrimary,
|
|
3846
|
+
CSS_FAMILY.brandSecondary,
|
|
3847
|
+
...SIGNALS2.map((s) => s.emitName),
|
|
3848
|
+
INTERACTION_POLE_FAMILY.strong,
|
|
3849
|
+
INTERACTION_POLE_FAMILY.inverse
|
|
3850
|
+
];
|
|
3851
|
+
var INTERACTION_STATES = ["enabled", "hover", "pressed", "selected"];
|
|
3852
|
+
var INTERACTION_LADDER = {
|
|
3853
|
+
subtle: { enabled: 12, hover: 16, pressed: 24, selected: 32 },
|
|
3854
|
+
hint: { enabled: null, hover: 8, pressed: 12, selected: 16 }
|
|
3855
|
+
};
|
|
3856
|
+
var INTERACTION_ROWS = [
|
|
3857
|
+
"fg",
|
|
3858
|
+
"fg-strong",
|
|
3859
|
+
"fg-on-hint",
|
|
3860
|
+
"solid-bg-enabled",
|
|
3861
|
+
"solid-bg-hover",
|
|
3862
|
+
"solid-bg-pressed",
|
|
3863
|
+
"solid-border",
|
|
3864
|
+
"solid-fg",
|
|
3865
|
+
"subtle-bg-enabled",
|
|
3866
|
+
"subtle-bg-hover",
|
|
3867
|
+
"subtle-bg-pressed",
|
|
3868
|
+
"subtle-bg-selected",
|
|
3869
|
+
"hint-bg-enabled",
|
|
3870
|
+
"hint-bg-hover",
|
|
3871
|
+
"hint-bg-pressed",
|
|
3872
|
+
"hint-bg-selected"
|
|
3873
|
+
];
|
|
3874
|
+
var interactionVarName = (family, row) => `--${family}-${row}`;
|
|
3875
|
+
var isPole = (family) => family === INTERACTION_POLE_FAMILY.strong || family === INTERACTION_POLE_FAMILY.inverse;
|
|
3876
|
+
var hexChannels = (hex) => {
|
|
3877
|
+
const m = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex.trim());
|
|
3878
|
+
return m ? [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)] : null;
|
|
3879
|
+
};
|
|
3880
|
+
function interactionTintName(family) {
|
|
3881
|
+
if (family === INTERACTION_POLE_FAMILY.strong) return PEN_100;
|
|
3882
|
+
if (family === INTERACTION_POLE_FAMILY.inverse) return PAPER_0;
|
|
3883
|
+
return `${family}-${stopTokenName(8)}`;
|
|
3884
|
+
}
|
|
3885
|
+
function interactionRows(family, mode, tokens) {
|
|
3886
|
+
const neutral = CSS_FAMILY.neutral;
|
|
3887
|
+
const v2 = (name) => `var(--${name})`;
|
|
3888
|
+
const pen = (stop) => `${family}-${stopTokenName(stop)}`;
|
|
3889
|
+
const tintHex = tokens[mode][interactionTintName(family)];
|
|
3890
|
+
const ch = tintHex ? hexChannels(tintHex) : null;
|
|
3891
|
+
if (!ch) throw new Error(`interactionRows: no sRGB hex for ${interactionTintName(family)} in ${mode}`);
|
|
3892
|
+
const at = (rung) => rung === null ? v2(TRANSPARENT_VAR.slice(2)) : `rgba(${ch[0]}, ${ch[1]}, ${ch[2]}, ${OPACITY_RUNGS[rung]})`;
|
|
3893
|
+
const text = isPole(family) ? [["fg", v2(interactionTintName(family))], ["fg-strong", v2(interactionTintName(family))], ["fg-on-hint", v2(interactionTintName(family))]] : [["fg", v2(pen(10))], ["fg-strong", v2(pen(11))], ["fg-on-hint", v2(pen(9))]];
|
|
3894
|
+
const solid = family === INTERACTION_POLE_FAMILY.strong ? [
|
|
3895
|
+
["solid-bg-enabled", v2(PEN_100)],
|
|
3896
|
+
["solid-bg-hover", v2(`${neutral}-${stopTokenName(11)}`)],
|
|
3897
|
+
["solid-bg-pressed", v2(`${neutral}-${stopTokenName(10)}`)],
|
|
3898
|
+
["solid-border", v2(TRANSPARENT_VAR.slice(2))],
|
|
3899
|
+
["solid-fg", v2(PAPER_0)]
|
|
3900
|
+
] : family === INTERACTION_POLE_FAMILY.inverse ? [
|
|
3901
|
+
["solid-bg-enabled", v2(PAPER_0)],
|
|
3902
|
+
["solid-bg-hover", v2(`${neutral}-${stopTokenName(2)}`)],
|
|
3903
|
+
["solid-bg-pressed", v2(`${neutral}-${stopTokenName(3)}`)],
|
|
3904
|
+
["solid-border", v2(TRANSPARENT_VAR.slice(2))],
|
|
3905
|
+
["solid-fg", v2(PEN_100)]
|
|
3906
|
+
] : [
|
|
3907
|
+
["solid-bg-enabled", v2(`${family}-${STAMP_FILL}`)],
|
|
3908
|
+
["solid-bg-hover", v2(`${family}-${STAMP_FILL_HOVER}`)],
|
|
3909
|
+
["solid-bg-pressed", v2(`${family}-${STAMP_FILL_PRESSED}`)],
|
|
3910
|
+
["solid-border", v2(`${family}-${STAMP_EDGE}`)],
|
|
3911
|
+
["solid-fg", v2(`${family}-${STAMP_ON}`)]
|
|
3912
|
+
];
|
|
3913
|
+
const ladder = (tier) => INTERACTION_STATES.map((state) => [`${tier}-bg-${state}`, at(INTERACTION_LADDER[tier][state])]);
|
|
3914
|
+
return [...text, ...solid, ...ladder("subtle"), ...ladder("hint")];
|
|
3915
|
+
}
|
|
3916
|
+
var rowVariesByMode = (row) => /^(subtle|hint)-bg-/.test(row) && row !== "hint-bg-enabled";
|
|
3917
|
+
function interactionCss(slug, tokens) {
|
|
3918
|
+
const scope = `[data-brand="${slug}"]`;
|
|
3919
|
+
const light = [];
|
|
3920
|
+
const dark = [];
|
|
3921
|
+
for (const family of INTERACTION_FAMILIES) {
|
|
3922
|
+
for (const [row, value] of interactionRows(family, "light", tokens)) light.push(` ${interactionVarName(family, row)}: ${value};`);
|
|
3923
|
+
for (const [row, value] of interactionRows(family, "dark", tokens)) if (rowVariesByMode(row)) dark.push(` ${interactionVarName(family, row)}: ${value};`);
|
|
3924
|
+
}
|
|
3925
|
+
const scoped = INTERACTION_FAMILIES.flatMap((family) => [
|
|
3926
|
+
`${scope} [data-family="${family}"], ${scope}[data-family="${family}"] {`,
|
|
3927
|
+
...INTERACTION_ROWS.map((row) => ` --${row}: var(${interactionVarName(family, row)});`),
|
|
3928
|
+
`}`
|
|
3929
|
+
]);
|
|
3930
|
+
return [
|
|
3931
|
+
`/* Interaction register: solid, subtle and hint tiers per family, the translucent rows at the engine's opacity rungs */`,
|
|
3932
|
+
`${scope} {`,
|
|
3933
|
+
...light,
|
|
3934
|
+
`}`,
|
|
3935
|
+
`${scope}[data-theme="dark"] {`,
|
|
3936
|
+
...dark,
|
|
3937
|
+
`}`,
|
|
3938
|
+
...scoped
|
|
3939
|
+
].join("\n");
|
|
3940
|
+
}
|
|
3941
|
+
function interactionTokens(tokens) {
|
|
3942
|
+
const add = (mode) => {
|
|
3943
|
+
const m = /* @__PURE__ */ new Map();
|
|
3944
|
+
for (const family of INTERACTION_FAMILIES)
|
|
3945
|
+
for (const [row, value] of interactionRows(family, mode, tokens)) m.set(interactionVarName(family, row).slice(2), value);
|
|
3946
|
+
return m;
|
|
3947
|
+
};
|
|
3948
|
+
const rawLight = add("light");
|
|
3949
|
+
const rawDark = add("dark");
|
|
3950
|
+
const baseLight = new Map(Object.entries(tokens.light));
|
|
3951
|
+
const baseDark = new Map(Object.entries(tokens.dark));
|
|
3952
|
+
const light = resolveReferences(rawLight, baseLight);
|
|
3953
|
+
const dark = resolveReferences(rawDark, baseDark);
|
|
3954
|
+
const names = [...tokens.names, ...rawLight.keys()];
|
|
3955
|
+
const invariant = [...tokens.invariant, ...[...rawLight.keys()].filter((n) => rawLight.get(n) === rawDark.get(n))];
|
|
3956
|
+
return {
|
|
3957
|
+
slug: tokens.slug,
|
|
3958
|
+
names,
|
|
3959
|
+
light: { ...tokens.light, ...Object.fromEntries([...rawLight.keys()].map((n) => [n, light[n]])) },
|
|
3960
|
+
dark: { ...tokens.dark, ...Object.fromEntries([...rawDark.keys()].map((n) => [n, dark[n]])) },
|
|
3961
|
+
invariant,
|
|
3962
|
+
raw: {
|
|
3963
|
+
light: { ...tokens.raw.light, ...Object.fromEntries(rawLight) },
|
|
3964
|
+
dark: { ...tokens.raw.dark, ...Object.fromEntries(rawDark) }
|
|
3965
|
+
}
|
|
3966
|
+
};
|
|
3967
|
+
}
|
|
3968
|
+
|
|
3746
3969
|
// src/engine/figmaRender.ts
|
|
3747
3970
|
var clamp01 = (v2) => Math.min(1, Math.max(0, v2));
|
|
3748
3971
|
var TRANSPARENT_TOKEN = {
|
|
@@ -4000,7 +4223,12 @@ export {
|
|
|
4000
4223
|
DEFAULT_LINK_HEX,
|
|
4001
4224
|
DISABLED_OPACITY,
|
|
4002
4225
|
EXT_KEY,
|
|
4226
|
+
INTERACTION_FAMILIES,
|
|
4227
|
+
INTERACTION_LADDER,
|
|
4228
|
+
INTERACTION_POLE_FAMILY,
|
|
4229
|
+
INTERACTION_ROWS,
|
|
4003
4230
|
INTERACTION_RUNGS,
|
|
4231
|
+
INTERACTION_STATES,
|
|
4004
4232
|
MODE_SPECS,
|
|
4005
4233
|
OFFSET_ALPHAS,
|
|
4006
4234
|
OPACITY_RUNGS,
|
|
@@ -4036,6 +4264,11 @@ export {
|
|
|
4036
4264
|
generateNeutralScale,
|
|
4037
4265
|
generateScale,
|
|
4038
4266
|
generateSubtleSecondary,
|
|
4267
|
+
interactionCss,
|
|
4268
|
+
interactionRows,
|
|
4269
|
+
interactionTintName,
|
|
4270
|
+
interactionTokens,
|
|
4271
|
+
interactionVarName,
|
|
4039
4272
|
neutralCss,
|
|
4040
4273
|
neutralTintHue,
|
|
4041
4274
|
opacityLeafName,
|
|
@@ -4043,17 +4276,22 @@ export {
|
|
|
4043
4276
|
opacityVarName,
|
|
4044
4277
|
pageStopFor,
|
|
4045
4278
|
parseToken,
|
|
4279
|
+
readEmission,
|
|
4046
4280
|
resolveBrand,
|
|
4047
4281
|
resolveDtcgRamp,
|
|
4048
4282
|
resolveLinkInverseTrio,
|
|
4049
4283
|
resolveLinkTrio,
|
|
4284
|
+
resolveReferences,
|
|
4050
4285
|
resolveTheme,
|
|
4051
4286
|
signalScalesFor,
|
|
4052
4287
|
signalsCss,
|
|
4053
4288
|
stopHex,
|
|
4054
4289
|
stopTokenName,
|
|
4055
4290
|
stopsToVars,
|
|
4291
|
+
systemCss,
|
|
4056
4292
|
themeToFigma,
|
|
4293
|
+
themeTokens,
|
|
4057
4294
|
toHex2 as toHex,
|
|
4058
|
-
tokenOrder
|
|
4295
|
+
tokenOrder,
|
|
4296
|
+
tokensFromEmission
|
|
4059
4297
|
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type OpacityRung } from './cssRender';
|
|
2
|
+
import { type ThemeTokens, type TokenMode } from './tokensRender';
|
|
3
|
+
export declare const INTERACTION_POLE_FAMILY: {
|
|
4
|
+
readonly strong: "neutral-strong";
|
|
5
|
+
readonly inverse: "neutral-inverse";
|
|
6
|
+
};
|
|
7
|
+
export type InteractionPoleFamily = (typeof INTERACTION_POLE_FAMILY)[keyof typeof INTERACTION_POLE_FAMILY];
|
|
8
|
+
/** every family the register emits, color families first, the two pole families last */
|
|
9
|
+
export declare const INTERACTION_FAMILIES: readonly string[];
|
|
10
|
+
export type InteractionState = 'enabled' | 'hover' | 'pressed' | 'selected';
|
|
11
|
+
export declare const INTERACTION_STATES: readonly InteractionState[];
|
|
12
|
+
/** the rung each translucent tier takes per state; null is the transparent rest */
|
|
13
|
+
export declare const INTERACTION_LADDER: Record<'subtle' | 'hint', Record<InteractionState, OpacityRung | null>>;
|
|
14
|
+
export declare const INTERACTION_ROWS: readonly ["fg", "fg-strong", "fg-on-hint", "solid-bg-enabled", "solid-bg-hover", "solid-bg-pressed", "solid-border", "solid-fg", "subtle-bg-enabled", "subtle-bg-hover", "subtle-bg-pressed", "subtle-bg-selected", "hint-bg-enabled", "hint-bg-hover", "hint-bg-pressed", "hint-bg-selected"];
|
|
15
|
+
export type InteractionRow = (typeof INTERACTION_ROWS)[number];
|
|
16
|
+
/** the CSS custom property a family's row lives under */
|
|
17
|
+
export declare const interactionVarName: (family: string, row: InteractionRow) => string;
|
|
18
|
+
/**
|
|
19
|
+
* The name whose channels a family's translucent rows ride: the family's
|
|
20
|
+
* highlighter-26, or the pole for the pole families.
|
|
21
|
+
*/
|
|
22
|
+
export declare function interactionTintName(family: string): string;
|
|
23
|
+
/** One family's rows for one mode as [name, value] pairs, aliases as var() and rungs as rgba. */
|
|
24
|
+
export declare function interactionRows(family: string, mode: TokenMode, tokens: ThemeTokens): Array<[InteractionRow, string]>;
|
|
25
|
+
/**
|
|
26
|
+
* The register as CSS for one brand: every family's rows under the brand scope, the
|
|
27
|
+
* rung rows per mode, then one scope block per family that maps the family-agnostic
|
|
28
|
+
* names (`--solid-bg-enabled`, `--fg`) onto that family, so a component reads one set
|
|
29
|
+
* of names and `data-family` picks the family, the way a mode does on a Figma instance.
|
|
30
|
+
*/
|
|
31
|
+
export declare function interactionCss(slug: string, tokens: ThemeTokens): string;
|
|
32
|
+
/** The base tokens plus the register's rows, resolved to literals per mode. */
|
|
33
|
+
export declare function interactionTokens(tokens: ThemeTokens): ThemeTokens;
|
|
34
|
+
/** every rung the register uses is one of the engine's interaction rungs */
|
|
35
|
+
export declare const interactionLadderIsLegal: () => boolean;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { GeneratedScale, NeutralLevel, ContrastProfile } from './colorEngine';
|
|
2
|
+
import type { ResolvedBrand, SecondaryStyle } from './resolve';
|
|
3
|
+
export type TokenMode = 'light' | 'dark';
|
|
4
|
+
export interface ThemeTokens {
|
|
5
|
+
slug: string;
|
|
6
|
+
/** every emitted name, in emission order */
|
|
7
|
+
names: string[];
|
|
8
|
+
/** resolved literal values per mode; mode-invariant names appear in both */
|
|
9
|
+
light: Record<string, string>;
|
|
10
|
+
dark: Record<string, string>;
|
|
11
|
+
/** names whose value does not depend on the mode */
|
|
12
|
+
invariant: string[];
|
|
13
|
+
/** the declarations as emitted, var() references intact, per block */
|
|
14
|
+
raw: {
|
|
15
|
+
light: Record<string, string>;
|
|
16
|
+
dark: Record<string, string>;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface ThemeTokensInput {
|
|
20
|
+
slug: string;
|
|
21
|
+
displayName?: string;
|
|
22
|
+
/** the resolved brand; for a resolved theme pass `theme.themed` */
|
|
23
|
+
brand: ResolvedBrand;
|
|
24
|
+
secondary?: GeneratedScale | null;
|
|
25
|
+
neutralLevel?: NeutralLevel;
|
|
26
|
+
contrastProfile?: ContrastProfile;
|
|
27
|
+
secondaryStyle?: SecondaryStyle;
|
|
28
|
+
ctaEscape?: boolean;
|
|
29
|
+
linkHex?: string | null;
|
|
30
|
+
ctaBorder?: boolean;
|
|
31
|
+
neutralH?: number;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Reads the engine's CSS emission into one declaration map per mode. Only the
|
|
35
|
+
* emitters' own grammar is understood: a line ending in `{` opens a block, a line
|
|
36
|
+
* that is `}` closes one, `--name: value;` lines declare. At-rule groups (the
|
|
37
|
+
* display-p3 re-emission) are skipped whole.
|
|
38
|
+
*/
|
|
39
|
+
export declare function readEmission(css: string): {
|
|
40
|
+
light: Map<string, string>;
|
|
41
|
+
dark: Map<string, string>;
|
|
42
|
+
order: string[];
|
|
43
|
+
};
|
|
44
|
+
/** Resolves var() references against `own`, falling back to `shared` for names declared once. */
|
|
45
|
+
export declare function resolveReferences(own: Map<string, string>, shared: Map<string, string>): Record<string, string>;
|
|
46
|
+
/** The system rows tokens/semantic.css states as static aliases, as engine-table projections. */
|
|
47
|
+
export declare function systemCss(): string;
|
|
48
|
+
/** Builds a ThemeTokens object from an emission's declaration maps. */
|
|
49
|
+
export declare function tokensFromEmission(slug: string, css: string): ThemeTokens;
|
|
50
|
+
/** The whole page's token set for one brand: signals, system rows, and the brand block. */
|
|
51
|
+
export declare function themeTokens(input: ThemeTokensInput): ThemeTokens;
|
|
@@ -2,6 +2,8 @@ export { generateScale, generateNeutralScale, generateSubtleSecondary, neutralTi
|
|
|
2
2
|
export { resolveBrand, resolveTheme, resolveLinkTrio, resolveLinkInverseTrio, DEFAULT_LINK_HEX, SIGNAL_SCALES, signalScalesFor, SECONDARY_DISTINCT_DELTA_E, SUBTLE_TINT_MULT, SUBTLE_PASTEL_K, OUTLINE_HOVER_ALPHA, type ResolvedBrand, type ResolvedTheme, type ResolvedSecondary, type SecondaryLevel, type SecondaryStyle, type SignalOverride, } from './engine/resolve';
|
|
3
3
|
export { brandCss, neutralCss, signalsCss, stopsToVars, toHex, stopHex, OFFSET_ALPHAS, SHADOW_ALPHAS, SCRIM_ALPHA, OPACITY_RUNGS, INTERACTION_RUNGS, opacityLeafName, opacityVarName, opacityTokenPath, type OpacityRung, DISABLED_OPACITY, type ShadowRung, ctaNeedsBorder, ctaBorderRung, pageStopFor, } from './engine/cssRender';
|
|
4
4
|
export { CSS_FAMILY } from './engine/tokenDescriptions';
|
|
5
|
+
export { themeTokens, tokensFromEmission, readEmission, resolveReferences, systemCss, type ThemeTokens, type ThemeTokensInput, type TokenMode, } from './engine/tokensRender';
|
|
6
|
+
export { interactionCss, interactionTokens, interactionRows, interactionVarName, interactionTintName, INTERACTION_FAMILIES, INTERACTION_POLE_FAMILY, INTERACTION_ROWS, INTERACTION_STATES, INTERACTION_LADDER, type InteractionRow, type InteractionState, type InteractionPoleFamily, } from './engine/interaction';
|
|
5
7
|
export { themeToFigma, type FigmaGroup, type FigmaColorToken, type FigmaNumberToken, type FigmaLeaf, type ThemeInput, } from './engine/figmaRender';
|
|
6
8
|
export { emitDtcgRamp, resolveDtcgRamp, parseToken, EXT_KEY, RESOLVER_ID, type DtcgRampGroup, type DtcgRequirementToken, type DtcgSeedToken, type DtcgColorValue, } from './engine/requirements/dtcg';
|
|
7
9
|
export { MODE_SPECS, type ModeSpec } from './engine/requirements/spec';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "okchroma",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Color token engine: one brand hex in, a full WCAG-enforced light+dark token system out (CSS variables, DTCG JSON, Figma variables)",
|
|
6
6
|
"repository": {
|
|
@@ -54,7 +54,8 @@
|
|
|
54
54
|
"name-lint": "esbuild scripts/name-lint.ts --bundle --platform=node --outfile=dist/name-lint.js && node dist/name-lint.js",
|
|
55
55
|
"typecheck": "tsc --noEmit",
|
|
56
56
|
"typecheck:ext": "tsc --noEmit -p plugin-ext",
|
|
57
|
-
"docs:lint": "esbuild scripts/docs-lint.ts --bundle --platform=node --outfile=dist/docs-lint.js && node dist/docs-lint.js"
|
|
57
|
+
"docs:lint": "esbuild scripts/docs-lint.ts --bundle --platform=node --outfile=dist/docs-lint.js && node dist/docs-lint.js",
|
|
58
|
+
"audit:tokens": "esbuild scripts/tokens-audit.ts --bundle --platform=node --outfile=dist/tokens-audit.js && node dist/tokens-audit.js"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
61
|
"@types/node": "^25.9.2",
|