@latty-ds/tokens 0.7.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 +63 -19
- package/dist/configure.js +70 -11
- package/dist/constants/tokens.constants.d.ts +10 -0
- package/dist/tokens.css +2 -1
- package/dist/tokens.js +1 -1
- package/dist/tokens.json +3 -2
- package/dist/types/public-types.d.ts +49 -4
- 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
|
@@ -1,11 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Border width applied to control chrome (outlined buttons, inputs, chips, surfaces).
|
|
3
|
+
* Named presets: `thin` = 1px (default), `medium` = 2px, `thick` = 4px.
|
|
4
|
+
* Any other CSS length (e.g. `'1.5px'`) passes through unchanged.
|
|
5
|
+
*/
|
|
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
|
+
};
|
|
1
18
|
interface LattyConfig {
|
|
2
19
|
/** Built-in names: primary, secondary, success, warning, error, info. Any additional name generates a new palette. */
|
|
3
20
|
colors?: Record<string, string>;
|
|
4
21
|
font?: {
|
|
5
|
-
|
|
22
|
+
/**
|
|
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.
|
|
47
|
+
*/
|
|
48
|
+
family?: FontFamilyEntry | FontFamilyEntry[];
|
|
6
49
|
};
|
|
7
50
|
border?: {
|
|
8
51
|
radius?: string;
|
|
52
|
+
width?: BorderWidth;
|
|
9
53
|
};
|
|
10
54
|
/**
|
|
11
55
|
* Controls which semantic token layer is emitted.
|
|
@@ -27,28 +71,28 @@ declare const createStyleSheet: (userConfig?: LattyConfig) => string;
|
|
|
27
71
|
* Injects design tokens into the document as a `<style>` element.
|
|
28
72
|
* Call once at your app's entry point — before any components render.
|
|
29
73
|
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* `<
|
|
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.
|
|
34
80
|
*
|
|
35
81
|
* @example
|
|
36
82
|
* ```html
|
|
37
|
-
* <
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* </head>
|
|
49
|
-
* </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>
|
|
50
94
|
* ```
|
|
51
95
|
*/
|
|
52
96
|
declare const configure: (userConfig?: LattyConfig) => void;
|
|
53
97
|
|
|
54
|
-
export { type LattyConfig, configure, createStyleSheet };
|
|
98
|
+
export { type BorderWidth, type LattyConfig, configure, createStyleSheet };
|
package/dist/configure.js
CHANGED
|
@@ -32,6 +32,12 @@ var REM_BASE_PX = 16;
|
|
|
32
32
|
|
|
33
33
|
// src/constants/tokens.constants.ts
|
|
34
34
|
var DEFAULT_BORDER_RADIUS = "0.5rem";
|
|
35
|
+
var DEFAULT_BORDER_WIDTH = "1px";
|
|
36
|
+
var BORDER_WIDTH_PRESETS = {
|
|
37
|
+
thin: "1px",
|
|
38
|
+
medium: "2px",
|
|
39
|
+
thick: "4px"
|
|
40
|
+
};
|
|
35
41
|
var DEFAULT_FONT_FAMILY = '"Hanken Grotesk", sans-serif';
|
|
36
42
|
|
|
37
43
|
// src/spacing/spacing.ts
|
|
@@ -165,8 +171,8 @@ var buildTokens = (cfg) => {
|
|
|
165
171
|
let color = buildColorTokens(cfg);
|
|
166
172
|
color = addSystemColors(color);
|
|
167
173
|
const spacing = buildSpacing();
|
|
168
|
-
const border = { radius: DEFAULT_BORDER_RADIUS };
|
|
169
|
-
const typography = {
|
|
174
|
+
const border = { radius: DEFAULT_BORDER_RADIUS, width: DEFAULT_BORDER_WIDTH };
|
|
175
|
+
const typography = { fontFamilyPrimary: DEFAULT_FONT_FAMILY };
|
|
170
176
|
const elevation = buildElevation(color.neutral);
|
|
171
177
|
return { color, spacing, border, typography, elevation };
|
|
172
178
|
};
|
|
@@ -313,6 +319,41 @@ var buildDarkSemanticTokens = (opts = {}) => {
|
|
|
313
319
|
};
|
|
314
320
|
var buildSemanticTokens = (mode = "light", opts = {}) => mode === "dark" ? buildDarkSemanticTokens(opts) : buildLightSemanticTokens(opts);
|
|
315
321
|
|
|
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)}`;
|
|
325
|
+
var unwrapQuotes = (value) => {
|
|
326
|
+
const trimmed = value.trim();
|
|
327
|
+
const first = trimmed[0];
|
|
328
|
+
if (trimmed.length > 1 && (first === '"' || first === "'") && trimmed[trimmed.length - 1] === first) {
|
|
329
|
+
return trimmed.slice(1, -1).trim();
|
|
330
|
+
}
|
|
331
|
+
return trimmed;
|
|
332
|
+
};
|
|
333
|
+
var isUrl = (value) => /^https?:\/\//i.test(value);
|
|
334
|
+
var namesFromFamilyParam = (raw) => raw.split("|").map((part) => part.split(":")[0].trim()).filter(Boolean);
|
|
335
|
+
var quoteIfNeeded = (name) => /\s/.test(name) ? `"${name}"` : name;
|
|
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);
|
|
340
|
+
if (!isUrl(unwrapped)) return { family: unwrapped, importUrl: null };
|
|
341
|
+
let parsed;
|
|
342
|
+
try {
|
|
343
|
+
parsed = new URL(unwrapped);
|
|
344
|
+
} catch {
|
|
345
|
+
return { family: unwrapped, importUrl: null };
|
|
346
|
+
}
|
|
347
|
+
if (parsed.hostname.toLowerCase() === "fonts.googleapis.com") {
|
|
348
|
+
const names = [...new Set(parsed.searchParams.getAll("family").flatMap(namesFromFamilyParam))];
|
|
349
|
+
if (names.length > 0) {
|
|
350
|
+
return { family: `${names.map(quoteIfNeeded).join(", ")}, ${fallback}`, importUrl: unwrapped };
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return { family: "", importUrl: unwrapped };
|
|
354
|
+
};
|
|
355
|
+
var resolveFontFamilies = (value) => (Array.isArray(value) ? value : [value]).map(resolveSingleFont);
|
|
356
|
+
|
|
316
357
|
// tokens.config.json
|
|
317
358
|
var tokens_config_default = {
|
|
318
359
|
color: {
|
|
@@ -332,39 +373,57 @@ var tokens_config_default = {
|
|
|
332
373
|
var DEFAULTS = {
|
|
333
374
|
colors: tokens_config_default.color,
|
|
334
375
|
font: { family: DEFAULT_FONT_FAMILY },
|
|
335
|
-
border: { radius: DEFAULT_BORDER_RADIUS }
|
|
376
|
+
border: { radius: DEFAULT_BORDER_RADIUS, width: DEFAULT_BORDER_WIDTH }
|
|
336
377
|
};
|
|
337
378
|
var toInternalConfig = (userConfig) => ({
|
|
338
379
|
color: { ...DEFAULTS.colors, ...userConfig.colors }
|
|
339
380
|
});
|
|
381
|
+
var resolveBorderWidth = (width) => BORDER_WIDTH_PRESETS[width] ?? width;
|
|
340
382
|
var createStyleSheet = (userConfig = {}) => {
|
|
341
383
|
const cfg = toInternalConfig(userConfig);
|
|
342
384
|
let tokens = buildTokens(cfg);
|
|
385
|
+
const importUrls = [];
|
|
343
386
|
if (userConfig.font?.family) {
|
|
344
|
-
|
|
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 } };
|
|
395
|
+
}
|
|
345
396
|
}
|
|
346
397
|
if (userConfig.border?.radius) {
|
|
347
398
|
tokens = { ...tokens, border: { ...tokens.border, radius: userConfig.border.radius } };
|
|
348
399
|
}
|
|
400
|
+
if (userConfig.border?.width) {
|
|
401
|
+
tokens = { ...tokens, border: { ...tokens.border, width: resolveBorderWidth(userConfig.border.width) } };
|
|
402
|
+
}
|
|
349
403
|
const primitives = tokensToCss(tokens);
|
|
350
404
|
const theme = userConfig.theme ?? "light";
|
|
351
405
|
const primary = tokens.color.primary;
|
|
352
406
|
const semanticOpts = { primary500: primary["500"], primary400: primary["400"] };
|
|
353
|
-
|
|
354
|
-
if (theme === "
|
|
355
|
-
|
|
407
|
+
let body;
|
|
408
|
+
if (theme === "dark") {
|
|
409
|
+
body = primitives + "\n" + semanticTokensToCss(buildSemanticTokens("dark", semanticOpts));
|
|
410
|
+
} else if (theme === "light") {
|
|
411
|
+
body = primitives + "\n" + semanticTokensToCss(buildSemanticTokens("light", semanticOpts));
|
|
412
|
+
} else {
|
|
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"]');
|
|
414
|
+
}
|
|
415
|
+
const importLines = importUrls.map((url) => `@import url("${url}");`).join("\n");
|
|
416
|
+
return importLines ? `${importLines}
|
|
417
|
+
${body}` : body;
|
|
356
418
|
};
|
|
357
419
|
var configure = (userConfig = {}) => {
|
|
358
|
-
const root = document.documentElement;
|
|
359
|
-
root.removeAttribute("data-lt-ready");
|
|
360
420
|
let style = document.getElementById("lt-tokens");
|
|
361
421
|
if (!style) {
|
|
362
422
|
style = document.createElement("style");
|
|
363
423
|
style.id = "lt-tokens";
|
|
364
424
|
document.head.prepend(style);
|
|
365
425
|
}
|
|
366
|
-
style.textContent =
|
|
367
|
-
requestAnimationFrame(() => root.setAttribute("data-lt-ready", ""));
|
|
426
|
+
style.textContent = createStyleSheet(userConfig);
|
|
368
427
|
};
|
|
369
428
|
export {
|
|
370
429
|
configure,
|
|
@@ -1,2 +1,12 @@
|
|
|
1
1
|
export declare const DEFAULT_BORDER_RADIUS: "0.5rem";
|
|
2
|
+
export declare const DEFAULT_BORDER_WIDTH: "1px";
|
|
3
|
+
/**
|
|
4
|
+
* Named presets accepted by `border.width` in `LattyConfig`.
|
|
5
|
+
* Any other CSS length passes through unchanged.
|
|
6
|
+
*/
|
|
7
|
+
export declare const BORDER_WIDTH_PRESETS: {
|
|
8
|
+
readonly thin: "1px";
|
|
9
|
+
readonly medium: "2px";
|
|
10
|
+
readonly thick: "4px";
|
|
11
|
+
};
|
|
2
12
|
export declare const DEFAULT_FONT_FAMILY: "\"Hanken Grotesk\", sans-serif";
|
package/dist/tokens.css
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
:root{
|
|
2
2
|
--lt-border-radius: 0.5rem;
|
|
3
|
+
--lt-border-width: 1px;
|
|
3
4
|
--lt-color-black: #000000;
|
|
4
5
|
--lt-color-error-100: #ffc8c1;
|
|
5
6
|
--lt-color-error-200: #ffa198;
|
|
@@ -188,5 +189,5 @@
|
|
|
188
189
|
--lt-spacing-7: 1.75rem;
|
|
189
190
|
--lt-spacing-8: 2rem;
|
|
190
191
|
--lt-spacing-9: 2.25rem;
|
|
191
|
-
--lt-typography-
|
|
192
|
+
--lt-typography-fontFamilyPrimary: "Hanken Grotesk", sans-serif;
|
|
192
193
|
}
|
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"},"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
|
@@ -216,10 +216,11 @@
|
|
|
216
216
|
}
|
|
217
217
|
},
|
|
218
218
|
"border": {
|
|
219
|
-
"radius": "0.5rem"
|
|
219
|
+
"radius": "0.5rem",
|
|
220
|
+
"width": "1px"
|
|
220
221
|
},
|
|
221
222
|
"typography": {
|
|
222
|
-
"
|
|
223
|
+
"fontFamilyPrimary": "\"Hanken Grotesk\", sans-serif"
|
|
223
224
|
},
|
|
224
225
|
"elevation": {
|
|
225
226
|
"0": "none",
|
|
@@ -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",
|
|
@@ -39,21 +39,66 @@ export type Tokens = {
|
|
|
39
39
|
spacing: SpacingTokens;
|
|
40
40
|
border: {
|
|
41
41
|
radius: string;
|
|
42
|
+
width: string;
|
|
42
43
|
};
|
|
43
44
|
typography: {
|
|
44
|
-
|
|
45
|
-
}
|
|
45
|
+
fontFamilyPrimary: string;
|
|
46
|
+
} & Record<string, string>;
|
|
46
47
|
elevation: ElevationTokens;
|
|
47
48
|
};
|
|
48
49
|
export type { Config, TokenColorName } from './';
|
|
50
|
+
/**
|
|
51
|
+
* Border width applied to control chrome (outlined buttons, inputs, chips, surfaces).
|
|
52
|
+
* Named presets: `thin` = 1px (default), `medium` = 2px, `thick` = 4px.
|
|
53
|
+
* Any other CSS length (e.g. `'1.5px'`) passes through unchanged.
|
|
54
|
+
*/
|
|
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
|
+
};
|
|
49
67
|
export interface LattyConfig {
|
|
50
68
|
/** Built-in names: primary, secondary, success, warning, error, info. Any additional name generates a new palette. */
|
|
51
69
|
colors?: Record<string, string>;
|
|
52
70
|
font?: {
|
|
53
|
-
|
|
71
|
+
/**
|
|
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.
|
|
96
|
+
*/
|
|
97
|
+
family?: FontFamilyEntry | FontFamilyEntry[];
|
|
54
98
|
};
|
|
55
99
|
border?: {
|
|
56
100
|
radius?: string;
|
|
101
|
+
width?: BorderWidth;
|
|
57
102
|
};
|
|
58
103
|
/**
|
|
59
104
|
* Controls which semantic token layer is emitted.
|
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
|
}
|