asma-ui-core 3.78.4 → 3.78.6

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.
@@ -0,0 +1,110 @@
1
+ /**
2
+ * The colour pairs this library actually puts on screen, as a data table.
3
+ *
4
+ * Every row cites the component file that pairs the two tokens, so a reviewer can check the claim
5
+ * without trusting the table. Tokens are cited by NAME, never by line number — `src/styles/**` is
6
+ * ASMA-8133's area and its line numbers move.
7
+ *
8
+ * Rows with a `finding` are measured failures against master. They are quarantined, not fixed:
9
+ * changing a token value is a visual (potentially breaking) change to a brand theme and needs
10
+ * design sign-off, so each one is written up in `docs/a11y-contrast.md` and escalated instead.
11
+ *
12
+ * @see docs/a11y-contrast.md — findings register, exemption rationale, measured ratios
13
+ * @see docs/a11y-allowlist.md — the axe (SC 1.4.3 only) story baseline this cross-references
14
+ */
15
+ /**
16
+ * The surface the library composites onto when a token is `transparent`, and the surface an
17
+ * unparented control is assumed to sit on. The library ships no page-background token; every
18
+ * component that sets its own opaque surface (input, tooltip, chip) uses white or a delta tint.
19
+ */
20
+ export declare const APP_SURFACE = "#ffffff";
21
+ export declare const REQUIREMENT_RATIO: {
22
+ /** SC 1.4.3, body text below 18.66px bold / 24px regular. */
23
+ readonly text: 4.5;
24
+ /** SC 1.4.3, large text at or above that size. */
25
+ readonly largeText: 3;
26
+ /** SC 1.4.11, UI component boundaries, state indicators and focus rings. */
27
+ readonly nonText: 3;
28
+ };
29
+ export type ContrastRequirement = keyof typeof REQUIREMENT_RATIO;
30
+ export interface ContrastPair {
31
+ /** Stable id. Quarantined rows use it to join to `docs/a11y-contrast.md`. */
32
+ readonly id: string;
33
+ /** Custom-property name, or a literal colour for a hard-coded component value. */
34
+ readonly foreground: string;
35
+ readonly background: string;
36
+ readonly requirement: ContrastRequirement;
37
+ /** Repo-relative path of the component that pairs these two. */
38
+ readonly usedBy: string;
39
+ /** Findings id in docs/a11y-contrast.md. Present means "measured failing, quarantined". */
40
+ readonly finding?: string;
41
+ }
42
+ /**
43
+ * Hand-curated pairs. The button token family is generated instead — see `buildButtonPairs`.
44
+ */
45
+ export declare const COMPONENT_PAIRS: readonly ContrastPair[];
46
+ /**
47
+ * `StyledButton.module.scss` builds every button from a single mixin over
48
+ * `--colors-button-{type}-{color}-{state}-{text|bg|border}-color`, so the button pairs are
49
+ * generated from the token names rather than transcribed. A new variant or state added to the
50
+ * token files is contrast-checked the moment it lands, with no edit here.
51
+ */
52
+ export declare const BUTTON_TYPES: readonly ["contained", "outlined", "text", "textGray", "textWhite"];
53
+ export declare const BUTTON_COLORS: readonly ["common", "error"];
54
+ /**
55
+ * `disabled` is deliberately absent. SC 1.4.3 exempts "text ... that is part of an inactive user
56
+ * interface component", and 1.4.11 exempts inactive components in the same words. See the
57
+ * exemptions section of docs/a11y-contrast.md.
58
+ */
59
+ export declare const BUTTON_STATES: readonly ["base", "hover", "active", "focused"];
60
+ export type ButtonType = (typeof BUTTON_TYPES)[number];
61
+ export type ButtonState = (typeof BUTTON_STATES)[number];
62
+ export interface ButtonTokenNames {
63
+ readonly text: string;
64
+ readonly background: string;
65
+ readonly border: string;
66
+ }
67
+ export declare const buttonTokenNames: (type: ButtonType, color: (typeof BUTTON_COLORS)[number], state: ButtonState) => ButtonTokenNames;
68
+ /**
69
+ * Types whose boundary is a designed, always-present edge. `text` / `textGray` are borderless by
70
+ * design — the label carries the affordance and is held to 4.5:1, which is what SC 1.4.11's
71
+ * "visual information required to identify user interface components" asks for. `textWhite` is
72
+ * excluded from contrast assertions entirely: it is white-on-transparent, meant to be placed on a
73
+ * consumer-supplied dark surface this package never sees. Documented in docs/a11y-contrast.md.
74
+ */
75
+ export declare const BUTTON_TYPES_WITH_BOUNDARY: readonly ButtonType[];
76
+ export declare const BUTTON_TYPES_WITHOUT_KNOWN_SURFACE: readonly ButtonType[];
77
+ /**
78
+ * Button pairs that fail against master, keyed `{type}/{color}/{state}/{aspect}`.
79
+ *
80
+ * `text-on-tinted-hover` (F-12): outlined/text/textGray put gama-500 on a gama-50 or gama-100 tint
81
+ * at hover and active, which drops the label under 4.5:1 in every theme.
82
+ * `boundary-focus` (F-07): the focus border is gama-400 everywhere, which is under 3:1 on white in
83
+ * default and fretex.
84
+ * `boundary-outlined-hover` (F-13): outlined's hover/active border is gama-300, under 3:1 in all
85
+ * three themes.
86
+ * `outlined/error/focused/text` (F-16): white label on a beta-100 tint, 1.27:1 in every theme.
87
+ * The error/focused boundary rows (F-15): the border points at `--colors-beta-400`, which no theme
88
+ * defines, so `default` and `greenish` render no focus border at all; `fretex` overrides it to
89
+ * gama-400 and lands at 2.24:1, which is F-07's root cause again.
90
+ */
91
+ export declare const BUTTON_FINDINGS: Readonly<Record<string, string>>;
92
+ /**
93
+ * Regression floors for the quarantined pairs: the ratio each one measures on master, per theme.
94
+ *
95
+ * A quarantined pair is asserted against its floor rather than against the WCAG threshold, so the
96
+ * suite still detects *decay* on an already-failing pair while staying green if ASMA-8133 or a
97
+ * design fix legitimately *improves* the number. This is a characterization test — the floor is a
98
+ * record of the status quo, not a standard. The real target stays in docs/a11y-contrast.md against
99
+ * the finding id, and lifting a quarantine means deleting the pair's `finding` key so the live SC
100
+ * assertion takes over.
101
+ *
102
+ * `null` means the pair has no computed value at all — see F-15, where the `var()` chain is
103
+ * dangling so the browser drops the declaration outright. A floor is meaningless there, so those
104
+ * stay skipped.
105
+ *
106
+ * Values are produced by `contrastRatio`, which already truncates to two decimals, so the floor and
107
+ * the measurement are byte-identical and the comparison needs no epsilon. Regenerate after
108
+ * ASMA-8133 lands.
109
+ */
110
+ export declare const REGRESSION_FLOORS: Readonly<Record<string, Readonly<Record<string, number | null>>>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ /** The theme every other theme layers on top of; selected by `:root`, not by a `data-theme` value. */
2
+ export declare const DEFAULT_THEME = "default";
3
+ export type ThemeName = string;
4
+ /**
5
+ * Every theme the stylesheets define, discovered rather than listed, so adding a fourth theme file
6
+ * automatically brings it into the contrast matrix instead of silently going unchecked.
7
+ */
8
+ export declare const discoverThemeNames: () => ThemeName[];
9
+ export declare class TokenResolutionError extends Error {
10
+ }
11
+ /**
12
+ * Follows a `var()` chain to a literal. `var(--a, fallback)` uses the fallback only when `--a` is
13
+ * undefined, matching CSS. A cycle or a missing terminal value throws rather than resolving to
14
+ * something plausible — a contrast suite that silently treats an unresolvable token as black would
15
+ * report passes it has not earned.
16
+ */
17
+ export declare const resolveDeclaration: (declarations: ReadonlyMap<string, string>, value: string, seen?: ReadonlySet<string>) => string;
18
+ export interface UnresolvableToken {
19
+ readonly property: string;
20
+ readonly reason: string;
21
+ }
22
+ export interface ThemeResolution {
23
+ readonly resolved: Map<string, string>;
24
+ /**
25
+ * Properties whose `var()` chain never reaches a literal. At runtime the browser treats these
26
+ * as invalid at computed-value time, so the declaration is dropped entirely and the element
27
+ * falls back to the inherited or initial value — i.e. the styling the token file *says* it
28
+ * applies is silently not applied. Worth a test of its own.
29
+ */
30
+ readonly unresolvable: UnresolvableToken[];
31
+ }
32
+ export declare const resolveTheme: (theme: ThemeName) => ThemeResolution;
33
+ /** Every custom property that applies to `theme`, resolved to a literal value. */
34
+ export declare const resolveThemeTokens: (theme: ThemeName) => Map<string, string>;
35
+ /** `resolveThemeTokens` for every discovered theme, keyed by theme name. */
36
+ export declare const resolveAllThemes: () => Map<ThemeName, Map<string, string>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ /**
2
+ * WCAG 2.2 contrast maths, kept dependency-free and side-effect-free so it can be exercised from a
3
+ * plain node-environment vitest run (the `unit` project in vite.config.ts) with no DOM.
4
+ *
5
+ * Only the colour notations the theme CSS actually uses are supported — `#rgb` / `#rgba` /
6
+ * `#rrggbb` / `#rrggbbaa`, `rgb()` / `rgba()` (comma or space separated), and the `white` / `black`
7
+ * / `transparent` keywords. Anything else returns `null` rather than guessing, so an unparsed value
8
+ * surfaces as a loud failure instead of a silently-skipped assertion.
9
+ *
10
+ * @see https://www.w3.org/TR/WCAG22/#dfn-relative-luminance
11
+ * @see https://www.w3.org/TR/WCAG22/#dfn-contrast-ratio
12
+ */
13
+ export interface Rgba {
14
+ readonly r: number;
15
+ readonly g: number;
16
+ readonly b: number;
17
+ /** 0–1. */
18
+ readonly a: number;
19
+ }
20
+ export declare const parseCssColor: (value: string) => Rgba | null;
21
+ /** Source-over compositing. `backdrop` must be opaque; the result always is. */
22
+ export declare const compositeOver: (source: Rgba, backdrop: Rgba) => Rgba;
23
+ export declare const relativeLuminance: ({ r, g, b }: Rgba) => number;
24
+ /**
25
+ * Contrast ratio of two opaque colours, truncated to two decimals.
26
+ *
27
+ * Truncated rather than rounded, for two reasons. It is conservative at the threshold — rounding
28
+ * would report a true 4.4951:1 as "4.5" and let a failing pair through — and it is what axe-core
29
+ * reports, so a ratio quoted in docs/a11y-contrast.md is digit-for-digit the same number as the
30
+ * one in the axe baseline in docs/a11y-allowlist.md.
31
+ */
32
+ export declare const contrastRatio: (first: Rgba, second: Rgba) => number;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "3.78.4",
6
+ "version": "3.78.6",
7
7
  "type": "module",
8
8
  "sideEffects": [
9
9
  "**/*.css",
@@ -66,6 +66,7 @@
66
66
  "vrt:accept": "bash scripts/vrt.sh accept",
67
67
  "vrt:report": "playwright show-report",
68
68
  "test-storybook": "npx vitest --project=storybook",
69
+ "test:interaction": "vitest --project=interaction --run",
69
70
  "changeset:pre-beta": "changeset pre enter beta",
70
71
  "changeset:pre-exit": "changeset pre exit",
71
72
  "changeset:version": "changeset version",