@vectoriox/iox-ui 5.10.0 → 5.11.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/design-core/index.d.ts +8037 -8920
- package/fesm2022/vectoriox-iox-ui-design-core.mjs +9584 -10575
- package/fesm2022/vectoriox-iox-ui-design-core.mjs.map +1 -1
- package/fesm2022/vectoriox-iox-ui.mjs +2 -11315
- package/fesm2022/vectoriox-iox-ui.mjs.map +1 -1
- package/index.d.ts +3 -9343
- package/package.json +1 -1
- package/src/design-core/brand.ts +36 -3
- package/src/design-core/design-token.model.ts +14 -14
- package/src/design-core/flavor-spec.generated.ts +9454 -10524
- package/src/design-core/flavor-tokens.ts +7 -3
- package/src/design-core/fonts.ts +14 -4
- package/src/design-core/spring.ts +21 -9
- package/src/design-core/token-css.ts +81 -31
package/package.json
CHANGED
package/src/design-core/brand.ts
CHANGED
|
@@ -226,13 +226,18 @@ export function deriveBrandTokens(seed: string, pack: Pick<FlavorPack, 'accentHu
|
|
|
226
226
|
/** WCAG 2 AA for body text — the gate every quartet pair is held to. */
|
|
227
227
|
export const WCAG_AA_TEXT = 4.5;
|
|
228
228
|
|
|
229
|
-
export const ACCENT_TOKEN_NAMES = [
|
|
229
|
+
export const ACCENT_TOKEN_NAMES = [
|
|
230
|
+
'accent', 'accent-ink', 'accent-hover', 'accent-text', 'inverse-accent', 'inverse-accent-ink',
|
|
231
|
+
] as const;
|
|
230
232
|
export type AccentTokenName = (typeof ACCENT_TOKEN_NAMES)[number];
|
|
231
233
|
|
|
232
|
-
/** The
|
|
234
|
+
/** The backgrounds the accent must read on, light and (optionally) dark. Without an inverse
|
|
235
|
+
* background the inverse pair is not derived — the pack's own stays. */
|
|
233
236
|
export interface AccentBackgrounds {
|
|
234
237
|
bg: string;
|
|
235
238
|
bgDark?: string;
|
|
239
|
+
inverseBg?: string;
|
|
240
|
+
inverseBgDark?: string;
|
|
236
241
|
}
|
|
237
242
|
|
|
238
243
|
const RAMP_ORDER = RAMP_STEPS.map(s => s.step);
|
|
@@ -252,7 +257,13 @@ const bestInkHex = (bg: string) =>
|
|
|
252
257
|
* - dark: the first of brand-300/200/400 an ink clears 4.5:1 on, the same hover rule, and
|
|
253
258
|
* `accent-text` = the first light step that clears 4.5:1 on `bgDark`
|
|
254
259
|
*
|
|
255
|
-
*
|
|
260
|
+
* - `inverse-accent` = the first step from 500 toward the end that reads on `inverseBg` clearing
|
|
261
|
+
* 4.5:1 on it; `inverse-accent-ink` = the higher-contrast of `brandInk` and the OPPOSITE ramp end
|
|
262
|
+
* (the spec's `brandSeed` rule). A step whose best ink still misses 4.5:1 is passed over, so the
|
|
263
|
+
* pair is a guarantee rather than a hope. Dark: the same against `inverseBgDark`.
|
|
264
|
+
*
|
|
265
|
+
* Every pair (ink/accent, ink/hover, text/bg, inverse ink/inverse accent, inverse accent/inverse
|
|
266
|
+
* bg) is asserted ≥ 4.5:1 across packs and seeds in `flavor-tokens.spec.ts`.
|
|
256
267
|
*/
|
|
257
268
|
export function deriveAccentTokens(
|
|
258
269
|
seed: string,
|
|
@@ -289,6 +300,24 @@ export function deriveAccentTokens(
|
|
|
289
300
|
};
|
|
290
301
|
})() : null;
|
|
291
302
|
|
|
303
|
+
const inverseOn = (inverseBg: string) => {
|
|
304
|
+
const toward = wcagContrastRatio(step(RAMP_ORDER[0]), inverseBg) >= wcagContrastRatio(step(RAMP_ORDER[RAMP_ORDER.length - 1]), inverseBg)
|
|
305
|
+
? -1 : 1;
|
|
306
|
+
const walk = RAMP_ORDER.filter(n => (toward < 0 ? n <= 500 : n >= 500));
|
|
307
|
+
if (toward < 0) walk.reverse();
|
|
308
|
+
const rampEnd = step(toward < 0 ? RAMP_ORDER[RAMP_ORDER.length - 1] : RAMP_ORDER[0]);
|
|
309
|
+
const inkOn = (fill: string) =>
|
|
310
|
+
(wcagContrastRatio(ink, fill) >= wcagContrastRatio(rampEnd, fill) ? ink : rampEnd);
|
|
311
|
+
for (const n of walk) {
|
|
312
|
+
const fill = step(n);
|
|
313
|
+
if (passesText(fill, inverseBg) && passesText(inkOn(fill), fill)) return { accent: fill, ink: inkOn(fill) };
|
|
314
|
+
}
|
|
315
|
+
const fill = step(walk[walk.length - 1]);
|
|
316
|
+
return { accent: fill, ink: passesText(inkOn(fill), fill) ? inkOn(fill) : bestInkHex(fill) };
|
|
317
|
+
};
|
|
318
|
+
const inverse = against.inverseBg ? inverseOn(against.inverseBg) : null;
|
|
319
|
+
const inverseDark = against.inverseBg && against.inverseBgDark ? inverseOn(against.inverseBgDark) : null;
|
|
320
|
+
|
|
292
321
|
const row = (name: AccentTokenName, value: string, darkValue?: string): FlavorTokenDef => ({
|
|
293
322
|
name, value, type: 'color', group: 'colour', tier: 'semantic',
|
|
294
323
|
...(darkValue ? { values: { dark: darkValue } } : {}),
|
|
@@ -298,5 +327,9 @@ export function deriveAccentTokens(
|
|
|
298
327
|
row('accent-ink', light.ink, dark?.ink),
|
|
299
328
|
row('accent-hover', light.hover, dark?.hover),
|
|
300
329
|
row('accent-text', light.text, dark?.text),
|
|
330
|
+
...(inverse ? [
|
|
331
|
+
row('inverse-accent', inverse.accent, inverseDark?.accent),
|
|
332
|
+
row('inverse-accent-ink', inverse.ink, inverseDark?.ink),
|
|
333
|
+
] : []),
|
|
301
334
|
];
|
|
302
335
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
FLAVOR_SPEC_VERSION, SPEC_AXES, SPEC_FLAVOR_PACKS, SPEC_FONT_ROLES, SPEC_SCHEMES, SPEC_TIER_IDS, SPEC_TOKEN_TYPES,
|
|
3
|
+
} from './flavor-spec.generated';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* The design-token vocabulary (design-system plan §3a/§3f). Every list here is READ from the
|
|
5
7
|
* generated spec, so the contract has one source: iox-ai-guidance `flavor-spec.v1.json`.
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
|
-
export type DesignTokenType = (typeof
|
|
9
|
-
export const DESIGN_TOKEN_TYPES: ReadonlyArray<DesignTokenType> =
|
|
10
|
+
export type DesignTokenType = (typeof SPEC_TOKEN_TYPES)[number];
|
|
11
|
+
export const DESIGN_TOKEN_TYPES: ReadonlyArray<DesignTokenType> = SPEC_TOKEN_TYPES;
|
|
10
12
|
|
|
11
|
-
export type DesignTokenTier =
|
|
12
|
-
export const DESIGN_TOKEN_TIERS
|
|
13
|
+
export type DesignTokenTier = (typeof SPEC_TIER_IDS)[number];
|
|
14
|
+
export const DESIGN_TOKEN_TIERS: ReadonlyArray<DesignTokenTier> = SPEC_TIER_IDS;
|
|
13
15
|
|
|
14
16
|
/** The spec carries groups per row, not as a list — `design-token.model.spec` pins this list
|
|
15
17
|
* to exactly the set of groups the spec's rows use. */
|
|
@@ -35,12 +37,12 @@ export interface StoredDesignTokenRow extends DesignTokenRow {
|
|
|
35
37
|
_id?: string;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
export type ShapeId = keyof typeof
|
|
39
|
-
export type DensityId = keyof typeof
|
|
40
|
-
export type MotionId = keyof typeof
|
|
41
|
-
export type DesignMode = (typeof
|
|
42
|
-
export type SchemeId = keyof typeof
|
|
43
|
-
export type FontRoleToken = (typeof
|
|
40
|
+
export type ShapeId = keyof typeof SPEC_AXES.shapes;
|
|
41
|
+
export type DensityId = keyof typeof SPEC_AXES.densities;
|
|
42
|
+
export type MotionId = keyof typeof SPEC_AXES.motions;
|
|
43
|
+
export type DesignMode = (typeof SPEC_AXES.modes)[number];
|
|
44
|
+
export type SchemeId = keyof typeof SPEC_SCHEMES;
|
|
45
|
+
export type FontRoleToken = (typeof SPEC_FONT_ROLES)[number]['token'];
|
|
44
46
|
|
|
45
47
|
/** Everything a studio chose about its look — the `settings.design` row, typed. */
|
|
46
48
|
export interface DesignChoices {
|
|
@@ -97,9 +99,7 @@ export interface FlavorPackV2 {
|
|
|
97
99
|
|
|
98
100
|
/** The spec's flavors, typed. Assignment here is the compile-time proof that the generated
|
|
99
101
|
* data fits `FlavorPackV2`. */
|
|
100
|
-
export const SPEC_FLAVORS: ReadonlyArray<FlavorPackV2> =
|
|
101
|
-
|
|
102
|
-
export const FLAVOR_SPEC_VERSION: number = FLAVOR_SPEC.version;
|
|
102
|
+
export const SPEC_FLAVORS: ReadonlyArray<FlavorPackV2> = SPEC_FLAVOR_PACKS;
|
|
103
103
|
|
|
104
104
|
/** The stamp seeded rows carry, so an upgrade can tell the machine's rows from the author's. */
|
|
105
105
|
export function flavorSourceStamp(flavorId: string, version: number = FLAVOR_SPEC_VERSION): string {
|