@latty-ds/tokens 0.8.0 → 0.9.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/README.md +11 -11
- package/dist/configure.d.ts +53 -31
- package/dist/configure.js +21 -16
- package/dist/tokens.css +1 -1
- package/dist/tokens.js +1 -1
- package/dist/tokens.json +1 -1
- package/dist/types/public-types.d.ts +39 -13
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -116,17 +116,17 @@ console.log(tokens.elevation['2']); // "0 4px 6px -1px rgb(…)"
|
|
|
116
116
|
|
|
117
117
|
### Primitive tokens (`tokens.css`)
|
|
118
118
|
|
|
119
|
-
| Prefix | Example | Description
|
|
120
|
-
| --------------------------------------- | ------------------------------ |
|
|
121
|
-
| `--lt-color-[name]-[step]` | `--lt-color-primary-500` | Color palette steps 50–900
|
|
122
|
-
| `--lt-color-[name]-muted-[step]` | `--lt-color-primary-muted-300` | Desaturated variant of each color
|
|
123
|
-
| `--lt-color-neutral-[step]` | `--lt-color-neutral-100` | Greyscale scale
|
|
124
|
-
| `--lt-color-white` / `--lt-color-black` | | System colors
|
|
125
|
-
| `--lt-spacing-[n]` | `--lt-spacing-4` → `1rem` | Spacing scale (rem), n = 0–24
|
|
126
|
-
| `--lt-spacing-px-[n]` | `--lt-spacing-px-4` → `16px` | Spacing scale (px)
|
|
127
|
-
| `--lt-border-radius` | `0.5rem` | Global border radius
|
|
128
|
-
| `--lt-elevation-[n]` | `--lt-elevation-2` | Box shadows, n = 0–5
|
|
129
|
-
| `--lt-typography-
|
|
119
|
+
| Prefix | Example | Description |
|
|
120
|
+
| --------------------------------------- | ------------------------------ | -------------------------------------------------------------------------- |
|
|
121
|
+
| `--lt-color-[name]-[step]` | `--lt-color-primary-500` | Color palette steps 50–900 |
|
|
122
|
+
| `--lt-color-[name]-muted-[step]` | `--lt-color-primary-muted-300` | Desaturated variant of each color |
|
|
123
|
+
| `--lt-color-neutral-[step]` | `--lt-color-neutral-100` | Greyscale scale |
|
|
124
|
+
| `--lt-color-white` / `--lt-color-black` | | System colors |
|
|
125
|
+
| `--lt-spacing-[n]` | `--lt-spacing-4` → `1rem` | Spacing scale (rem), n = 0–24 |
|
|
126
|
+
| `--lt-spacing-px-[n]` | `--lt-spacing-px-4` → `16px` | Spacing scale (px) |
|
|
127
|
+
| `--lt-border-radius` | `0.5rem` | Global border radius |
|
|
128
|
+
| `--lt-elevation-[n]` | `--lt-elevation-2` | Box shadows, n = 0–5 |
|
|
129
|
+
| `--lt-typography-fontFamilyPrimary` | `"Hanken Grotesk", sans-serif` | Base font family (additional `...Secondary`/`...Tertiary` when configured) |
|
|
130
130
|
|
|
131
131
|
Color names: `primary`, `secondary`, `success`, `warning`, `error`, `info` (each with a `-muted` variant).
|
|
132
132
|
|
package/dist/configure.d.ts
CHANGED
|
@@ -4,22 +4,48 @@
|
|
|
4
4
|
* Any other CSS length (e.g. `'1.5px'`) passes through unchanged.
|
|
5
5
|
*/
|
|
6
6
|
type BorderWidth = 'thin' | 'medium' | 'thick' | (string & {});
|
|
7
|
+
/** Generic CSS font-family keyword used as the safety-net fallback if a CDN font fails to load. */
|
|
8
|
+
type FontFallback = 'sans-serif' | 'serif' | 'monospace' | 'cursive' | 'fantasy' | 'system-ui';
|
|
9
|
+
/**
|
|
10
|
+
* A single `font.family` entry: a plain CSS value, a Google Fonts CSS2 URL, or
|
|
11
|
+
* a URL paired with a custom generic fallback (default `'sans-serif'`) for
|
|
12
|
+
* when the derived family isn't sans-serif — e.g. a serif display font.
|
|
13
|
+
*/
|
|
14
|
+
type FontFamilyEntry = string | {
|
|
15
|
+
url: string;
|
|
16
|
+
fallback?: FontFallback;
|
|
17
|
+
};
|
|
7
18
|
interface LattyConfig {
|
|
8
19
|
/** Built-in names: primary, secondary, success, warning, error, info. Any additional name generates a new palette. */
|
|
9
20
|
colors?: Record<string, string>;
|
|
10
21
|
font?: {
|
|
11
22
|
/**
|
|
12
|
-
* A CSS `font-family` value (e.g. `'Inter, sans-serif'`),
|
|
13
|
-
*
|
|
14
|
-
* `'https://fonts.googleapis.com/css2?family=Hanken+Grotesk:ital,wght@0,100..900&display=swap'`)
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
23
|
+
* A CSS `font-family` value (e.g. `'Inter, sans-serif'`), a Google Fonts
|
|
24
|
+
* CSS2 stylesheet URL (e.g.
|
|
25
|
+
* `'https://fonts.googleapis.com/css2?family=Hanken+Grotesk:ital,wght@0,100..900&display=swap'`),
|
|
26
|
+
* a `{ url, fallback }` object, or an array of any of these. URLs get
|
|
27
|
+
* `@import`ed automatically and the family name is derived from the
|
|
28
|
+
* `family=` query param — no separate `<link>` tag needed. Stylesheet
|
|
29
|
+
* URLs from providers other than `fonts.googleapis.com` are still
|
|
30
|
+
* loaded, but since there's no reliable way to guess the family name
|
|
31
|
+
* from an arbitrary CDN, pass the resulting name as a plain value
|
|
32
|
+
* instead (or open an issue if there's a provider worth special-casing).
|
|
33
|
+
*
|
|
34
|
+
* A bare URL string always falls back to the generic `sans-serif` family
|
|
35
|
+
* if the font itself fails to load. Use the `{ url, fallback }` object
|
|
36
|
+
* form to pick a different generic fallback (e.g. `'serif'` for a serif
|
|
37
|
+
* display font):
|
|
38
|
+
* ```ts
|
|
39
|
+
* family: { url: 'https://fonts.googleapis.com/css2?family=Playfair+Display', fallback: 'serif' }
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* When an array is passed, each entry maps to its own token in order —
|
|
43
|
+
* `--lt-typography-fontFamilyPrimary`, `...Secondary`, `...Tertiary`,
|
|
44
|
+
* etc. — rather than being combined into a single CSS fallback stack, so
|
|
45
|
+
* multiple fonts (e.g. a heading font and a body font) can each be
|
|
46
|
+
* referenced independently in your own CSS.
|
|
21
47
|
*/
|
|
22
|
-
family?:
|
|
48
|
+
family?: FontFamilyEntry | FontFamilyEntry[];
|
|
23
49
|
};
|
|
24
50
|
border?: {
|
|
25
51
|
radius?: string;
|
|
@@ -45,30 +71,26 @@ declare const createStyleSheet: (userConfig?: LattyConfig) => string;
|
|
|
45
71
|
* Injects design tokens into the document as a `<style>` element.
|
|
46
72
|
* Call once at your app's entry point — before any components render.
|
|
47
73
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* `<
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* both `@import`s it and derives the font-family name for you, so no separate
|
|
55
|
-
* `<link>` tag is needed.
|
|
74
|
+
* `font.family` accepts a single value or an array. Each entry is either a
|
|
75
|
+
* plain CSS `font-family` value or a Google Fonts CSS2 stylesheet URL (which
|
|
76
|
+
* configure() `@import`s and derives the family name from automatically — no
|
|
77
|
+
* separate `<link>` tag needed). Array entries map to their own token in
|
|
78
|
+
* order — `--lt-typography-fontFamilyPrimary`, `...Secondary`, `...Tertiary`,
|
|
79
|
+
* etc. — so each font can be referenced independently in your own CSS.
|
|
56
80
|
*
|
|
57
81
|
* @example
|
|
58
82
|
* ```html
|
|
59
|
-
* <
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* </head>
|
|
71
|
-
* </html>
|
|
83
|
+
* <script type="module">
|
|
84
|
+
* import { configure } from '@latty-ds/tokens/configure';
|
|
85
|
+
* configure({
|
|
86
|
+
* colors: { primary: '#6366f1', secondary: '#f59e0b' },
|
|
87
|
+
* font: { family: [
|
|
88
|
+
* 'https://fonts.googleapis.com/css2?family=Hanken+Grotesk:ital,wght@0,100..900;1,100..900&display=swap',
|
|
89
|
+
* 'Georgia, serif',
|
|
90
|
+
* ] },
|
|
91
|
+
* border: { radius: '0.375rem', width: 'medium' },
|
|
92
|
+
* });
|
|
93
|
+
* </script>
|
|
72
94
|
* ```
|
|
73
95
|
*/
|
|
74
96
|
declare const configure: (userConfig?: LattyConfig) => void;
|
package/dist/configure.js
CHANGED
|
@@ -172,7 +172,7 @@ var buildTokens = (cfg) => {
|
|
|
172
172
|
color = addSystemColors(color);
|
|
173
173
|
const spacing = buildSpacing();
|
|
174
174
|
const border = { radius: DEFAULT_BORDER_RADIUS, width: DEFAULT_BORDER_WIDTH };
|
|
175
|
-
const typography = {
|
|
175
|
+
const typography = { fontFamilyPrimary: DEFAULT_FONT_FAMILY };
|
|
176
176
|
const elevation = buildElevation(color.neutral);
|
|
177
177
|
return { color, spacing, border, typography, elevation };
|
|
178
178
|
};
|
|
@@ -320,6 +320,8 @@ var buildDarkSemanticTokens = (opts = {}) => {
|
|
|
320
320
|
var buildSemanticTokens = (mode = "light", opts = {}) => mode === "dark" ? buildDarkSemanticTokens(opts) : buildLightSemanticTokens(opts);
|
|
321
321
|
|
|
322
322
|
// src/configure/font.ts
|
|
323
|
+
var FONT_FAMILY_SLOT_NAMES = ["Primary", "Secondary", "Tertiary", "Quaternary"];
|
|
324
|
+
var fontFamilySlot = (index) => `fontFamily${FONT_FAMILY_SLOT_NAMES[index] ?? String(index + 1)}`;
|
|
323
325
|
var unwrapQuotes = (value) => {
|
|
324
326
|
const trimmed = value.trim();
|
|
325
327
|
const first = trimmed[0];
|
|
@@ -331,8 +333,10 @@ var unwrapQuotes = (value) => {
|
|
|
331
333
|
var isUrl = (value) => /^https?:\/\//i.test(value);
|
|
332
334
|
var namesFromFamilyParam = (raw) => raw.split("|").map((part) => part.split(":")[0].trim()).filter(Boolean);
|
|
333
335
|
var quoteIfNeeded = (name) => /\s/.test(name) ? `"${name}"` : name;
|
|
334
|
-
var
|
|
335
|
-
const
|
|
336
|
+
var resolveSingleFont = (entry) => {
|
|
337
|
+
const rawValue = typeof entry === "string" ? entry : entry.url;
|
|
338
|
+
const fallback = typeof entry === "string" ? "sans-serif" : entry.fallback ?? "sans-serif";
|
|
339
|
+
const unwrapped = unwrapQuotes(rawValue);
|
|
336
340
|
if (!isUrl(unwrapped)) return { family: unwrapped, importUrl: null };
|
|
337
341
|
let parsed;
|
|
338
342
|
try {
|
|
@@ -343,11 +347,12 @@ var resolveFontFamily = (value) => {
|
|
|
343
347
|
if (parsed.hostname.toLowerCase() === "fonts.googleapis.com") {
|
|
344
348
|
const names = [...new Set(parsed.searchParams.getAll("family").flatMap(namesFromFamilyParam))];
|
|
345
349
|
if (names.length > 0) {
|
|
346
|
-
return { family: `${names.map(quoteIfNeeded).join(", ")},
|
|
350
|
+
return { family: `${names.map(quoteIfNeeded).join(", ")}, ${fallback}`, importUrl: unwrapped };
|
|
347
351
|
}
|
|
348
352
|
}
|
|
349
353
|
return { family: "", importUrl: unwrapped };
|
|
350
354
|
};
|
|
355
|
+
var resolveFontFamilies = (value) => (Array.isArray(value) ? value : [value]).map(resolveSingleFont);
|
|
351
356
|
|
|
352
357
|
// tokens.config.json
|
|
353
358
|
var tokens_config_default = {
|
|
@@ -377,12 +382,16 @@ var resolveBorderWidth = (width) => BORDER_WIDTH_PRESETS[width] ?? width;
|
|
|
377
382
|
var createStyleSheet = (userConfig = {}) => {
|
|
378
383
|
const cfg = toInternalConfig(userConfig);
|
|
379
384
|
let tokens = buildTokens(cfg);
|
|
380
|
-
|
|
385
|
+
const importUrls = [];
|
|
381
386
|
if (userConfig.font?.family) {
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
387
|
+
const resolvedFonts = resolveFontFamilies(userConfig.font.family);
|
|
388
|
+
const typographyOverrides = {};
|
|
389
|
+
resolvedFonts.forEach((font, i) => {
|
|
390
|
+
if (font.importUrl) importUrls.push(font.importUrl);
|
|
391
|
+
if (font.family) typographyOverrides[fontFamilySlot(i)] = font.family;
|
|
392
|
+
});
|
|
393
|
+
if (Object.keys(typographyOverrides).length > 0) {
|
|
394
|
+
tokens = { ...tokens, typography: { ...tokens.typography, ...typographyOverrides } };
|
|
386
395
|
}
|
|
387
396
|
}
|
|
388
397
|
if (userConfig.border?.radius) {
|
|
@@ -403,22 +412,18 @@ var createStyleSheet = (userConfig = {}) => {
|
|
|
403
412
|
} else {
|
|
404
413
|
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"]');
|
|
405
414
|
}
|
|
406
|
-
|
|
415
|
+
const importLines = importUrls.map((url) => `@import url("${url}");`).join("\n");
|
|
416
|
+
return importLines ? `${importLines}
|
|
407
417
|
${body}` : body;
|
|
408
418
|
};
|
|
409
419
|
var configure = (userConfig = {}) => {
|
|
410
|
-
const root = document.documentElement;
|
|
411
|
-
root.removeAttribute("data-lt-ready");
|
|
412
420
|
let style = document.getElementById("lt-tokens");
|
|
413
421
|
if (!style) {
|
|
414
422
|
style = document.createElement("style");
|
|
415
423
|
style.id = "lt-tokens";
|
|
416
424
|
document.head.prepend(style);
|
|
417
425
|
}
|
|
418
|
-
|
|
419
|
-
const css = createStyleSheet(userConfig);
|
|
420
|
-
style.textContent = css.startsWith("@import") ? css.replace(/^(@import[^\n]*\n)/, `$1${guard}`) : guard + css;
|
|
421
|
-
requestAnimationFrame(() => root.setAttribute("data-lt-ready", ""));
|
|
426
|
+
style.textContent = createStyleSheet(userConfig);
|
|
422
427
|
};
|
|
423
428
|
export {
|
|
424
429
|
configure,
|
package/dist/tokens.css
CHANGED
package/dist/tokens.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const tokens = {"color":{"primary":{"50":"#f0e5df","100":"#ffd4b5","200":"#ffbb87","300":"#ffa860","400":"#ff9539","500":"#ff8200","600":"#d56400","700":"#963b00","800":"#5e3c25","900":"#3c1d05"},"primary-muted":{"50":"#e9e7e6","100":"#e8dfda","200":"#dfd1c8","300":"#dac8bd","400":"#d2beb2","500":"#c6b1a5","600":"#a08e82","700":"#6b5c53","800":"#50453e","900":"#2b2521"},"secondary":{"50":"#e5e7f1","100":"#cbd2ff","200":"#a3acf7","300":"#8a93f4","400":"#7076e5","500":"#5252c5","600":"#4544ad","700":"#333187","800":"#2e3254","900":"#202343"},"secondary-muted":{"50":"#e7e8e9","100":"#d5d7df","200":"#b4b7c4","300":"#a0a3b3","400":"#898c9e","500":"#6c6f81","600":"#5a5d6d","700":"#414351","800":"#363742","900":"#25262c"},"success":{"50":"#e1ebe2","100":"#beedc6","200":"#94e4a4","300":"#70df8b","400":"#4bd573","500":"#22c55e","600":"#00a244","700":"#006f22","800":"#2b4d32","900":"#0c2e16"},"success-muted":{"50":"#e7e8e7","100":"#dbe3dc","200":"#cad7cc","300":"#bfcfc1","400":"#b3c5b6","500":"#a5b8a8","600":"#839586","700":"#546256","800":"#404a41","900":"#222823"},"warning":{"50":"#ece7de","100":"#f5e0b5","200":"#f6d289","300":"#f9c962","400":"#f7bf3a","500":"#eeb308","600":"#c38e00","700":"#845a00","800":"#584720","900":"#332400"},"warning-muted":{"50":"#e8e8e6","100":"#e7e4dc","200":"#e2dcd0","300":"#ded7c8","400":"#dad1c0","500":"#d2c9b8","600":"#a9a090","700":"#6d6659","800":"#504c42","900":"#292621"},"error":{"50":"#f3e4e2","100":"#ffc8c1","200":"#ffa198","300":"#ff847b","400":"#ff6560","500":"#ef4444","600":"#cb2d31","700":"#950e18","800":"#5a312e","900":"#3f1917"},"error-muted":{"50":"#e9e7e7","100":"#e6dad8","200":"#d6c3c1","300":"#cdb4b2","400":"#bfa4a1","500":"#ab908d","600":"#8d7572","700":"#624e4c","800":"#4c3d3b","900":"#2d2423"},"info":{"50":"#e1e9ef","100":"#bce4fe","200":"#8fd2fd","300":"#6ac7ff","400":"#43b9fa","500":"#0ea5e9","600":"#0087c4","700":"#005c8d","800":"#1e465d","900":"#082a3c"},"info-muted":{"50":"#e7e8e9","100":"#d9e0e5","200":"#c5d0d7","300":"#b8c6cf","400":"#aab9c4","500":"#99a9b3","600":"#7a8993","700":"#4f5b63","800":"#3d464c","900":"#22272a"},"neutral":{"50":"#fafafa","100":"#f3f3f3","200":"#e4e4e4","300":"#cacaca","400":"#ababab","500":"#868686","600":"#696969","700":"#4d4d4d","800":"#333333","900":"#1b1b1b"},"white":"#FFFFFF","black":"#000000"},"spacing":{"px":{"0":"0px","1":"4px","2":"8px","3":"12px","4":"16px","5":"20px","6":"24px","7":"28px","8":"32px","9":"36px","10":"40px","11":"44px","12":"48px","13":"52px","14":"56px","15":"60px","16":"64px","17":"68px","18":"72px","19":"76px","20":"80px","21":"84px","22":"88px","23":"92px","24":"96px"},"rem":{"0":"0rem","1":"0.25rem","2":"0.5rem","3":"0.75rem","4":"1rem","5":"1.25rem","6":"1.5rem","7":"1.75rem","8":"2rem","9":"2.25rem","10":"2.5rem","11":"2.75rem","12":"3rem","13":"3.25rem","14":"3.5rem","15":"3.75rem","16":"4rem","17":"4.25rem","18":"4.5rem","19":"4.75rem","20":"5rem","21":"5.25rem","22":"5.5rem","23":"5.75rem","24":"6rem"}},"border":{"radius":"0.5rem","width":"1px"},"typography":{"
|
|
1
|
+
export const tokens = {"color":{"primary":{"50":"#f0e5df","100":"#ffd4b5","200":"#ffbb87","300":"#ffa860","400":"#ff9539","500":"#ff8200","600":"#d56400","700":"#963b00","800":"#5e3c25","900":"#3c1d05"},"primary-muted":{"50":"#e9e7e6","100":"#e8dfda","200":"#dfd1c8","300":"#dac8bd","400":"#d2beb2","500":"#c6b1a5","600":"#a08e82","700":"#6b5c53","800":"#50453e","900":"#2b2521"},"secondary":{"50":"#e5e7f1","100":"#cbd2ff","200":"#a3acf7","300":"#8a93f4","400":"#7076e5","500":"#5252c5","600":"#4544ad","700":"#333187","800":"#2e3254","900":"#202343"},"secondary-muted":{"50":"#e7e8e9","100":"#d5d7df","200":"#b4b7c4","300":"#a0a3b3","400":"#898c9e","500":"#6c6f81","600":"#5a5d6d","700":"#414351","800":"#363742","900":"#25262c"},"success":{"50":"#e1ebe2","100":"#beedc6","200":"#94e4a4","300":"#70df8b","400":"#4bd573","500":"#22c55e","600":"#00a244","700":"#006f22","800":"#2b4d32","900":"#0c2e16"},"success-muted":{"50":"#e7e8e7","100":"#dbe3dc","200":"#cad7cc","300":"#bfcfc1","400":"#b3c5b6","500":"#a5b8a8","600":"#839586","700":"#546256","800":"#404a41","900":"#222823"},"warning":{"50":"#ece7de","100":"#f5e0b5","200":"#f6d289","300":"#f9c962","400":"#f7bf3a","500":"#eeb308","600":"#c38e00","700":"#845a00","800":"#584720","900":"#332400"},"warning-muted":{"50":"#e8e8e6","100":"#e7e4dc","200":"#e2dcd0","300":"#ded7c8","400":"#dad1c0","500":"#d2c9b8","600":"#a9a090","700":"#6d6659","800":"#504c42","900":"#292621"},"error":{"50":"#f3e4e2","100":"#ffc8c1","200":"#ffa198","300":"#ff847b","400":"#ff6560","500":"#ef4444","600":"#cb2d31","700":"#950e18","800":"#5a312e","900":"#3f1917"},"error-muted":{"50":"#e9e7e7","100":"#e6dad8","200":"#d6c3c1","300":"#cdb4b2","400":"#bfa4a1","500":"#ab908d","600":"#8d7572","700":"#624e4c","800":"#4c3d3b","900":"#2d2423"},"info":{"50":"#e1e9ef","100":"#bce4fe","200":"#8fd2fd","300":"#6ac7ff","400":"#43b9fa","500":"#0ea5e9","600":"#0087c4","700":"#005c8d","800":"#1e465d","900":"#082a3c"},"info-muted":{"50":"#e7e8e9","100":"#d9e0e5","200":"#c5d0d7","300":"#b8c6cf","400":"#aab9c4","500":"#99a9b3","600":"#7a8993","700":"#4f5b63","800":"#3d464c","900":"#22272a"},"neutral":{"50":"#fafafa","100":"#f3f3f3","200":"#e4e4e4","300":"#cacaca","400":"#ababab","500":"#868686","600":"#696969","700":"#4d4d4d","800":"#333333","900":"#1b1b1b"},"white":"#FFFFFF","black":"#000000"},"spacing":{"px":{"0":"0px","1":"4px","2":"8px","3":"12px","4":"16px","5":"20px","6":"24px","7":"28px","8":"32px","9":"36px","10":"40px","11":"44px","12":"48px","13":"52px","14":"56px","15":"60px","16":"64px","17":"68px","18":"72px","19":"76px","20":"80px","21":"84px","22":"88px","23":"92px","24":"96px"},"rem":{"0":"0rem","1":"0.25rem","2":"0.5rem","3":"0.75rem","4":"1rem","5":"1.25rem","6":"1.5rem","7":"1.75rem","8":"2rem","9":"2.25rem","10":"2.5rem","11":"2.75rem","12":"3rem","13":"3.25rem","14":"3.5rem","15":"3.75rem","16":"4rem","17":"4.25rem","18":"4.5rem","19":"4.75rem","20":"5rem","21":"5.25rem","22":"5.5rem","23":"5.75rem","24":"6rem"}},"border":{"radius":"0.5rem","width":"1px"},"typography":{"fontFamilyPrimary":"\"Hanken Grotesk\", sans-serif"},"elevation":{"0":"none","1":"0 1px 3px 0 rgb(27 27 27 / 0.1), 0 1px 2px 0 rgb(27 27 27 / 0.06)","2":"0 4px 6px -1px rgb(27 27 27 / 0.1), 0 2px 4px -1px rgb(27 27 27 / 0.06)","3":"0 10px 15px -3px rgb(27 27 27 / 0.1), 0 4px 6px -2px rgb(27 27 27 / 0.05)","4":"0 20px 25px -5px rgb(27 27 27 / 0.1), 0 10px 10px -5px rgb(27 27 27 / 0.04)","5":"0 25px 50px -12px rgb(27 27 27 / 0.25)"},"semantic":{"text-default":"color-neutral-900","text-subtle":"color-neutral-600","text-muted":"color-neutral-400","text-disabled":"color-neutral-400","text-inverse":"color-white","text-neutral":"color-neutral-700","text-primary":"color-primary-700","text-on-primary":"color-neutral-900","text-secondary":"color-secondary-700","text-on-secondary":"color-white","text-success":"color-success-700","text-on-success":"color-white","text-warning":"color-warning-700","text-on-warning":"color-warning-800","text-error":"color-error-700","text-on-error":"color-white","text-info":"color-info-700","text-on-info":"color-white","bg-default":"color-white","bg-subtle":"color-neutral-50","bg-surface":"color-neutral-100","bg-overlay":"color-neutral-200","bg-inverse":"color-neutral-900","bg-neutral-subtle":"color-neutral-100","bg-primary":"color-primary-500","bg-primary-subtle":"color-primary-100","bg-secondary":"color-secondary-500","bg-secondary-subtle":"color-secondary-100","bg-success":"color-success-500","bg-success-subtle":"color-success-100","bg-warning":"color-warning-500","bg-warning-subtle":"color-warning-100","bg-error":"color-error-500","bg-error-subtle":"color-error-100","bg-info":"color-info-500","bg-info-subtle":"color-info-100","border-default":"color-neutral-200","border-strong":"color-neutral-400","border-subtle":"color-neutral-100","border-focus":"color-primary-200","border-primary":"color-primary-200","border-primary-strong":"color-primary-500","border-secondary":"color-secondary-200","border-secondary-strong":"color-secondary-500","border-success":"color-success-200","border-success-strong":"color-success-500","border-warning":"color-warning-200","border-warning-strong":"color-warning-500","border-error":"color-error-200","border-error-strong":"color-error-500","border-info":"color-info-200","border-info-strong":"color-info-500","interactive-primary-bg":"color-primary-500","interactive-primary-bg-hover":"color-primary-600","interactive-primary-bg-active":"color-primary-700","interactive-secondary-bg":"color-secondary-500","interactive-secondary-bg-hover":"color-secondary-600","interactive-secondary-bg-active":"color-secondary-700","interactive-success-bg":"color-success-500","interactive-success-bg-hover":"color-success-600","interactive-success-bg-active":"color-success-700","interactive-warning-bg":"color-warning-500","interactive-warning-bg-hover":"color-warning-600","interactive-warning-bg-active":"color-warning-700","interactive-error-bg":"color-error-500","interactive-error-bg-hover":"color-error-600","interactive-error-bg-active":"color-error-700","interactive-info-bg":"color-info-500","interactive-info-bg-hover":"color-info-600","interactive-info-bg-active":"color-info-700"},"semanticDark":{"text-default":"color-neutral-100","text-subtle":"color-neutral-300","text-muted":"color-neutral-500","text-disabled":"color-neutral-600","text-inverse":"color-neutral-900","text-neutral":"color-neutral-200","text-primary":"color-primary-300","text-on-primary":"color-neutral-900","text-secondary":"color-secondary-300","text-on-secondary":"color-white","text-success":"color-success-300","text-on-success":"color-white","text-warning":"color-warning-300","text-on-warning":"color-warning-800","text-error":"color-error-300","text-on-error":"color-white","text-info":"color-info-300","text-on-info":"color-white","bg-default":"color-neutral-900","bg-subtle":"color-neutral-800","bg-surface":"color-neutral-800","bg-overlay":"color-neutral-700","bg-inverse":"color-neutral-50","bg-neutral-subtle":"color-neutral-800","bg-primary":"color-primary-500","bg-primary-subtle":"color-primary-900","bg-secondary":"color-secondary-500","bg-secondary-subtle":"color-secondary-900","bg-success":"color-success-500","bg-success-subtle":"color-success-900","bg-warning":"color-warning-500","bg-warning-subtle":"color-warning-900","bg-error":"color-error-500","bg-error-subtle":"color-error-900","bg-info":"color-info-500","bg-info-subtle":"color-info-900","border-default":"color-neutral-700","border-strong":"color-neutral-500","border-subtle":"color-neutral-800","border-focus":"color-primary-400","border-primary":"color-primary-700","border-primary-strong":"color-primary-500","border-secondary":"color-secondary-700","border-secondary-strong":"color-secondary-500","border-success":"color-success-700","border-success-strong":"color-success-500","border-warning":"color-warning-700","border-warning-strong":"color-warning-500","border-error":"color-error-700","border-error-strong":"color-error-500","border-info":"color-info-700","border-info-strong":"color-info-500","interactive-primary-bg":"color-primary-400","interactive-primary-bg-hover":"color-primary-300","interactive-primary-bg-active":"color-primary-500","interactive-secondary-bg":"color-secondary-400","interactive-secondary-bg-hover":"color-secondary-300","interactive-secondary-bg-active":"color-secondary-500","interactive-success-bg":"color-success-400","interactive-success-bg-hover":"color-success-300","interactive-success-bg-active":"color-success-500","interactive-warning-bg":"color-warning-400","interactive-warning-bg-hover":"color-warning-300","interactive-warning-bg-active":"color-warning-500","interactive-error-bg":"color-error-400","interactive-error-bg-hover":"color-error-300","interactive-error-bg-active":"color-error-500","interactive-info-bg":"color-info-400","interactive-info-bg-hover":"color-info-300","interactive-info-bg-active":"color-info-500"}};
|
package/dist/tokens.json
CHANGED
|
@@ -24,7 +24,7 @@ import type { ElevationTokens } from '../elevation/';
|
|
|
24
24
|
* radius: "0.375rem"
|
|
25
25
|
* },
|
|
26
26
|
* typography: {
|
|
27
|
-
*
|
|
27
|
+
* fontFamilyPrimary: "Hanken Grotesk, sans-serif"
|
|
28
28
|
* },
|
|
29
29
|
* elevation: {
|
|
30
30
|
* "0": "none",
|
|
@@ -42,8 +42,8 @@ export type Tokens = {
|
|
|
42
42
|
width: string;
|
|
43
43
|
};
|
|
44
44
|
typography: {
|
|
45
|
-
|
|
46
|
-
}
|
|
45
|
+
fontFamilyPrimary: string;
|
|
46
|
+
} & Record<string, string>;
|
|
47
47
|
elevation: ElevationTokens;
|
|
48
48
|
};
|
|
49
49
|
export type { Config, TokenColorName } from './';
|
|
@@ -53,22 +53,48 @@ export type { Config, TokenColorName } from './';
|
|
|
53
53
|
* Any other CSS length (e.g. `'1.5px'`) passes through unchanged.
|
|
54
54
|
*/
|
|
55
55
|
export type BorderWidth = 'thin' | 'medium' | 'thick' | (string & {});
|
|
56
|
+
/** Generic CSS font-family keyword used as the safety-net fallback if a CDN font fails to load. */
|
|
57
|
+
export type FontFallback = 'sans-serif' | 'serif' | 'monospace' | 'cursive' | 'fantasy' | 'system-ui';
|
|
58
|
+
/**
|
|
59
|
+
* A single `font.family` entry: a plain CSS value, a Google Fonts CSS2 URL, or
|
|
60
|
+
* a URL paired with a custom generic fallback (default `'sans-serif'`) for
|
|
61
|
+
* when the derived family isn't sans-serif — e.g. a serif display font.
|
|
62
|
+
*/
|
|
63
|
+
export type FontFamilyEntry = string | {
|
|
64
|
+
url: string;
|
|
65
|
+
fallback?: FontFallback;
|
|
66
|
+
};
|
|
56
67
|
export interface LattyConfig {
|
|
57
68
|
/** Built-in names: primary, secondary, success, warning, error, info. Any additional name generates a new palette. */
|
|
58
69
|
colors?: Record<string, string>;
|
|
59
70
|
font?: {
|
|
60
71
|
/**
|
|
61
|
-
* A CSS `font-family` value (e.g. `'Inter, sans-serif'`),
|
|
62
|
-
*
|
|
63
|
-
* `'https://fonts.googleapis.com/css2?family=Hanken+Grotesk:ital,wght@0,100..900&display=swap'`)
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
72
|
+
* A CSS `font-family` value (e.g. `'Inter, sans-serif'`), a Google Fonts
|
|
73
|
+
* CSS2 stylesheet URL (e.g.
|
|
74
|
+
* `'https://fonts.googleapis.com/css2?family=Hanken+Grotesk:ital,wght@0,100..900&display=swap'`),
|
|
75
|
+
* a `{ url, fallback }` object, or an array of any of these. URLs get
|
|
76
|
+
* `@import`ed automatically and the family name is derived from the
|
|
77
|
+
* `family=` query param — no separate `<link>` tag needed. Stylesheet
|
|
78
|
+
* URLs from providers other than `fonts.googleapis.com` are still
|
|
79
|
+
* loaded, but since there's no reliable way to guess the family name
|
|
80
|
+
* from an arbitrary CDN, pass the resulting name as a plain value
|
|
81
|
+
* instead (or open an issue if there's a provider worth special-casing).
|
|
82
|
+
*
|
|
83
|
+
* A bare URL string always falls back to the generic `sans-serif` family
|
|
84
|
+
* if the font itself fails to load. Use the `{ url, fallback }` object
|
|
85
|
+
* form to pick a different generic fallback (e.g. `'serif'` for a serif
|
|
86
|
+
* display font):
|
|
87
|
+
* ```ts
|
|
88
|
+
* family: { url: 'https://fonts.googleapis.com/css2?family=Playfair+Display', fallback: 'serif' }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* When an array is passed, each entry maps to its own token in order —
|
|
92
|
+
* `--lt-typography-fontFamilyPrimary`, `...Secondary`, `...Tertiary`,
|
|
93
|
+
* etc. — rather than being combined into a single CSS fallback stack, so
|
|
94
|
+
* multiple fonts (e.g. a heading font and a body font) can each be
|
|
95
|
+
* referenced independently in your own CSS.
|
|
70
96
|
*/
|
|
71
|
-
family?:
|
|
97
|
+
family?: FontFamilyEntry | FontFamilyEntry[];
|
|
72
98
|
};
|
|
73
99
|
border?: {
|
|
74
100
|
radius?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@latty-ds/tokens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.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": "
|
|
63
|
+
"gitHead": "8d5627a4a71bb4c7efdf3b754198c6450ce5467f"
|
|
64
64
|
}
|