@latty-ds/tokens 0.9.0 → 0.10.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.
@@ -46,11 +46,32 @@ interface LattyConfig {
46
46
  * referenced independently in your own CSS.
47
47
  */
48
48
  family?: FontFamilyEntry | FontFamilyEntry[];
49
+ /**
50
+ * A single dedicated heading font, resolved to `--lt-typography-fontFamilyHeading`.
51
+ * `lt-text`'s heading/display variants (`h1`–`h6`, `display-*`) read this
52
+ * token automatically, falling back to `fontFamilyPrimary` when unset —
53
+ * the built-in way to do a two-typeface identity without manually
54
+ * rerouting `--lt-typography-fontFamilySecondary` via hand-written CSS.
55
+ */
56
+ heading?: FontFamilyEntry;
49
57
  };
50
58
  border?: {
51
59
  radius?: string;
52
60
  width?: BorderWidth;
61
+ /**
62
+ * Shifts which neutral palette step `--lt-border-default`/`--lt-border-strong`/
63
+ * `--lt-border-subtle` resolve to. `'high'` moves them toward a bolder,
64
+ * higher-contrast step (darker in light mode, lighter in dark mode) without
65
+ * touching theme-switching machinery.
66
+ * @default 'default'
67
+ */
68
+ contrast?: 'default' | 'high';
53
69
  };
70
+ /**
71
+ * Set to `'none'` to flatten every `--lt-elevation-N` token (box-shadow) to
72
+ * `none` in one call, instead of overriding each level individually.
73
+ */
74
+ elevation?: 'none';
54
75
  /**
55
76
  * Controls which semantic token layer is emitted.
56
77
  * - `'light'` (default) — light tokens only; ignores OS preference
package/dist/configure.js CHANGED
@@ -239,6 +239,16 @@ var accessibleTextOn = (bgHex) => {
239
239
  const darkContrast = (L + 0.05) / 0.059;
240
240
  return whiteContrast >= darkContrast ? "color-white" : "color-neutral-900";
241
241
  };
242
+ var BORDER_STEPS = {
243
+ light: {
244
+ default: { default: "200", strong: "400", subtle: "100" },
245
+ high: { default: "400", strong: "600", subtle: "300" }
246
+ },
247
+ dark: {
248
+ default: { default: "700", strong: "500", subtle: "800" },
249
+ high: { default: "500", strong: "300", subtle: "600" }
250
+ }
251
+ };
242
252
  var buildLightSemanticTokens = (opts = {}) => {
243
253
  const map = {};
244
254
  map["text-default"] = "color-neutral-900";
@@ -263,9 +273,10 @@ var buildLightSemanticTokens = (opts = {}) => {
263
273
  map[`bg-${v}`] = `color-${v}-500`;
264
274
  map[`bg-${v}-subtle`] = `color-${v}-100`;
265
275
  }
266
- map["border-default"] = "color-neutral-200";
267
- map["border-strong"] = "color-neutral-400";
268
- map["border-subtle"] = "color-neutral-100";
276
+ const lightBorderSteps = BORDER_STEPS.light[opts.borderContrast ?? "default"];
277
+ map["border-default"] = `color-neutral-${lightBorderSteps.default}`;
278
+ map["border-strong"] = `color-neutral-${lightBorderSteps.strong}`;
279
+ map["border-subtle"] = `color-neutral-${lightBorderSteps.subtle}`;
269
280
  map["border-focus"] = "color-primary-200";
270
281
  for (const v of VARIANTS) {
271
282
  map[`border-${v}`] = `color-${v}-200`;
@@ -302,9 +313,10 @@ var buildDarkSemanticTokens = (opts = {}) => {
302
313
  map[`bg-${v}`] = `color-${v}-500`;
303
314
  map[`bg-${v}-subtle`] = `color-${v}-900`;
304
315
  }
305
- map["border-default"] = "color-neutral-700";
306
- map["border-strong"] = "color-neutral-500";
307
- map["border-subtle"] = "color-neutral-800";
316
+ const darkBorderSteps = BORDER_STEPS.dark[opts.borderContrast ?? "default"];
317
+ map["border-default"] = `color-neutral-${darkBorderSteps.default}`;
318
+ map["border-strong"] = `color-neutral-${darkBorderSteps.strong}`;
319
+ map["border-subtle"] = `color-neutral-${darkBorderSteps.subtle}`;
308
320
  map["border-focus"] = "color-primary-400";
309
321
  for (const v of VARIANTS) {
310
322
  map[`border-${v}`] = `color-${v}-700`;
@@ -394,16 +406,33 @@ var createStyleSheet = (userConfig = {}) => {
394
406
  tokens = { ...tokens, typography: { ...tokens.typography, ...typographyOverrides } };
395
407
  }
396
408
  }
409
+ if (userConfig.font?.heading) {
410
+ const [resolvedHeading] = resolveFontFamilies(userConfig.font.heading);
411
+ if (resolvedHeading.importUrl) importUrls.push(resolvedHeading.importUrl);
412
+ if (resolvedHeading.family) {
413
+ tokens = { ...tokens, typography: { ...tokens.typography, fontFamilyHeading: resolvedHeading.family } };
414
+ }
415
+ }
397
416
  if (userConfig.border?.radius) {
398
417
  tokens = { ...tokens, border: { ...tokens.border, radius: userConfig.border.radius } };
399
418
  }
400
419
  if (userConfig.border?.width) {
401
420
  tokens = { ...tokens, border: { ...tokens.border, width: resolveBorderWidth(userConfig.border.width) } };
402
421
  }
422
+ if (userConfig.elevation === "none") {
423
+ const flatElevation = Object.fromEntries(
424
+ Object.keys(tokens.elevation).map((level) => [level, "none"])
425
+ );
426
+ tokens = { ...tokens, elevation: flatElevation };
427
+ }
403
428
  const primitives = tokensToCss(tokens);
404
429
  const theme = userConfig.theme ?? "light";
405
430
  const primary = tokens.color.primary;
406
- const semanticOpts = { primary500: primary["500"], primary400: primary["400"] };
431
+ const semanticOpts = {
432
+ primary500: primary["500"],
433
+ primary400: primary["400"],
434
+ borderContrast: userConfig.border?.contrast
435
+ };
407
436
  let body;
408
437
  if (theme === "dark") {
409
438
  body = primitives + "\n" + semanticTokensToCss(buildSemanticTokens("dark", semanticOpts));
@@ -412,6 +441,7 @@ var createStyleSheet = (userConfig = {}) => {
412
441
  } else {
413
442
  body = primitives + "\n" + semanticTokensToCss(buildSemanticTokens("light", semanticOpts)) + "\n" + semanticTokensToCss(buildSemanticTokens("dark", semanticOpts), "@media (prefers-color-scheme: dark)") + "\n" + semanticTokensToCss(buildSemanticTokens("dark", semanticOpts), '[data-theme="dark"]') + "\n" + semanticTokensToCss(buildSemanticTokens("light", semanticOpts), '[data-theme="light"]');
414
443
  }
444
+ body += "\nbody { font-family: var(--lt-typography-fontFamilyPrimary); }\n";
415
445
  const importLines = importUrls.map((url) => `@import url("${url}");`).join("\n");
416
446
  return importLines ? `${importLines}
417
447
  ${body}` : body;
@@ -95,11 +95,32 @@ export interface LattyConfig {
95
95
  * referenced independently in your own CSS.
96
96
  */
97
97
  family?: FontFamilyEntry | FontFamilyEntry[];
98
+ /**
99
+ * A single dedicated heading font, resolved to `--lt-typography-fontFamilyHeading`.
100
+ * `lt-text`'s heading/display variants (`h1`–`h6`, `display-*`) read this
101
+ * token automatically, falling back to `fontFamilyPrimary` when unset —
102
+ * the built-in way to do a two-typeface identity without manually
103
+ * rerouting `--lt-typography-fontFamilySecondary` via hand-written CSS.
104
+ */
105
+ heading?: FontFamilyEntry;
98
106
  };
99
107
  border?: {
100
108
  radius?: string;
101
109
  width?: BorderWidth;
110
+ /**
111
+ * Shifts which neutral palette step `--lt-border-default`/`--lt-border-strong`/
112
+ * `--lt-border-subtle` resolve to. `'high'` moves them toward a bolder,
113
+ * higher-contrast step (darker in light mode, lighter in dark mode) without
114
+ * touching theme-switching machinery.
115
+ * @default 'default'
116
+ */
117
+ contrast?: 'default' | 'high';
102
118
  };
119
+ /**
120
+ * Set to `'none'` to flatten every `--lt-elevation-N` token (box-shadow) to
121
+ * `none` in one call, instead of overriding each level individually.
122
+ */
123
+ elevation?: 'none';
103
124
  /**
104
125
  * Controls which semantic token layer is emitted.
105
126
  * - `'light'` (default) — light tokens only; ignores OS preference
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@latty-ds/tokens",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Design tokens for the Latty design system — generates CSS custom properties, JSON, and JavaScript exports from a single config file",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -60,5 +60,5 @@
60
60
  "dependencies": {
61
61
  "culori": "^4.0.2"
62
62
  },
63
- "gitHead": "8d5627a4a71bb4c7efdf3b754198c6450ce5467f"
63
+ "gitHead": "7b0b9856be6755a573abf02c0b7cbdb1a6db4fef"
64
64
  }