@nexub/tokens 3.1.0 → 3.3.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/js/seed.d.ts CHANGED
@@ -29,6 +29,37 @@ export function createSeedRoles(seed: string, { contrast, target }?: SeedThemeOp
29
29
  export function createSeedThemeCss(seed: string, { selector, ...options }?: SeedThemeOptions & {
30
30
  selector?: string;
31
31
  }): string;
32
+ /**
33
+ * WCAG 2.x contrast ratio between two hex colours, 1–21.
34
+ * @param {string} a `#rrggbb`
35
+ * @param {string} b `#rrggbb`
36
+ * @returns {number}
37
+ */
38
+ export function contrastRatio(a: string, b: string): number;
39
+ /**
40
+ * The full seeded theme as a stylesheet: standard contrast on `selector`, then
41
+ * `data-contrast="medium"` and `"high"`, and high for `prefers-contrast: more`
42
+ * when no `data-contrast` is set. Same layering as the built-in roles.css, so a
43
+ * seeded brand follows the contrast switch like a built-in one.
44
+ * @param {string} seed
45
+ * @param {{ target?: 'primary' | 'tertiary', selector?: string }} [options] `selector` defaults to ':root'.
46
+ * @returns {string}
47
+ */
48
+ export function createSeedStylesheet(seed: string, { target, selector }?: {
49
+ target?: "primary" | "tertiary";
50
+ selector?: string;
51
+ }): string;
52
+ /**
53
+ * The seeded roles as W3C Design Tokens (DTCG) JSON, one document per scheme,
54
+ * for Figma Variables / Tokens Studio / Style Dictionary.
55
+ * @param {string} seed
56
+ * @param {SeedThemeOptions} [options]
57
+ * @returns {{ light: Record<string, unknown>, dark: Record<string, unknown> }}
58
+ */
59
+ export function createSeedTokens(seed: string, options?: SeedThemeOptions): {
60
+ light: Record<string, unknown>;
61
+ dark: Record<string, unknown>;
62
+ };
32
63
  export type SeedThemeOptions = {
33
64
  /**
34
65
  * Contrast level (matches `data-contrast`). Default 'standard'.
package/dist/js/seed.js CHANGED
@@ -65,3 +65,58 @@ export function createSeedThemeCss(seed, { selector = ':root', ...options } = {}
65
65
  const decls = Object.entries(createSeedTheme(seed, options)).map(([k, v]) => ` ${k}: ${v};`);
66
66
  return `${selector} {\n${decls.join('\n')}\n}\n`;
67
67
  }
68
+ /**
69
+ * WCAG 2.x contrast ratio between two hex colours, 1–21.
70
+ * @param {string} a `#rrggbb`
71
+ * @param {string} b `#rrggbb`
72
+ * @returns {number}
73
+ */
74
+ export function contrastRatio(a, b) {
75
+ /** @param {string} hex */
76
+ const lum = (hex) => {
77
+ const c = (/** @type {number} */ i) => {
78
+ const s = parseInt(hex.slice(i, i + 2), 16) / 255;
79
+ return s <= 0.04045 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;
80
+ };
81
+ return 0.2126 * c(1) + 0.7152 * c(3) + 0.0722 * c(5);
82
+ };
83
+ const [x, y] = [lum(a), lum(b)];
84
+ return (Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05);
85
+ }
86
+ /**
87
+ * The full seeded theme as a stylesheet: standard contrast on `selector`, then
88
+ * `data-contrast="medium"` and `"high"`, and high for `prefers-contrast: more`
89
+ * when no `data-contrast` is set. Same layering as the built-in roles.css, so a
90
+ * seeded brand follows the contrast switch like a built-in one.
91
+ * @param {string} seed
92
+ * @param {{ target?: 'primary' | 'tertiary', selector?: string }} [options] `selector` defaults to ':root'.
93
+ * @returns {string}
94
+ */
95
+ export function createSeedStylesheet(seed, { target = 'primary', selector = ':root' } = {}) {
96
+ /** @param {'standard' | 'medium' | 'high'} contrast */
97
+ const decls = (contrast) => Object.entries(createSeedTheme(seed, { contrast, target })).map(([k, v]) => ` ${k}: ${v};`).join('\n');
98
+ /** @param {string} lvl */
99
+ const at = (lvl) => `${selector}[data-contrast='${lvl}'], [data-contrast='${lvl}'] ${selector}`;
100
+ const auto = `${selector}:root:not([data-contrast]), :root:not([data-contrast]) ${selector}`;
101
+ return [
102
+ `${selector} {\n${decls('standard')}\n}`,
103
+ `${at('medium')} {\n${decls('medium')}\n}`,
104
+ `${at('high')} {\n${decls('high')}\n}`,
105
+ `@media (prefers-contrast: more) {\n${auto} {\n${decls('high')}\n}\n}`,
106
+ ].join('\n\n') + '\n';
107
+ }
108
+ /**
109
+ * The seeded roles as W3C Design Tokens (DTCG) JSON, one document per scheme,
110
+ * for Figma Variables / Tokens Studio / Style Dictionary.
111
+ * @param {string} seed
112
+ * @param {SeedThemeOptions} [options]
113
+ * @returns {{ light: Record<string, unknown>, dark: Record<string, unknown> }}
114
+ */
115
+ export function createSeedTokens(seed, options = {}) {
116
+ const { light, dark } = createSeedRoles(seed, options);
117
+ /** @param {Record<string, string>} roles */
118
+ const doc = (roles) => ({
119
+ color: Object.fromEntries(Object.entries(roles).map(([role, hex]) => [role, { $type: 'color', $value: hex }])),
120
+ });
121
+ return { light: doc(light), dark: doc(dark) };
122
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexub/tokens",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "Design tokens for Nexub Design System — colours, typography, spacing, radii, shadows, and motion as CSS variables, Tailwind presets and React Native objects.",
5
5
  "type": "module",
6
6
  "license": "MIT",