@ansh-ui/tokens 0.2.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/LICENSE +21 -0
- package/dist/ansh.css +307 -0
- package/dist/index.cjs +573 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +815 -0
- package/dist/index.d.ts +815 -0
- package/dist/index.js +546 -0
- package/dist/index.js.map +1 -0
- package/package.json +45 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,815 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Primitive design tokens.
|
|
3
|
+
*
|
|
4
|
+
* These are the raw values — the vocabulary. Semantic tokens (in `semantic.ts`) map *meaning*
|
|
5
|
+
* onto them, and that indirection is what makes theming possible: `--ansh-surface` can point
|
|
6
|
+
* at `slate.50` in light mode and `slate.950` in dark mode without any component changing.
|
|
7
|
+
*
|
|
8
|
+
* Every scale here is derived from a rule rather than hand-picked, so extending it is
|
|
9
|
+
* unambiguous and a designer can predict what step 9 looks like without checking.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Spacing — an 8-point grid with half-steps below 8px.
|
|
13
|
+
*
|
|
14
|
+
* The half-steps matter: 8px is too coarse for optical adjustments like the gap between an icon
|
|
15
|
+
* and its label, and every design system that omits them ends up with arbitrary one-off values.
|
|
16
|
+
* Named by their pixel value at the default root size so `space[4]` is unambiguously 16px.
|
|
17
|
+
*/
|
|
18
|
+
declare const space: {
|
|
19
|
+
readonly 0: "0";
|
|
20
|
+
readonly px: "1px";
|
|
21
|
+
readonly 0.5: "0.125rem";
|
|
22
|
+
readonly 1: "0.25rem";
|
|
23
|
+
readonly 1.5: "0.375rem";
|
|
24
|
+
readonly 2: "0.5rem";
|
|
25
|
+
readonly 3: "0.75rem";
|
|
26
|
+
readonly 4: "1rem";
|
|
27
|
+
readonly 5: "1.25rem";
|
|
28
|
+
readonly 6: "1.5rem";
|
|
29
|
+
readonly 8: "2rem";
|
|
30
|
+
readonly 10: "2.5rem";
|
|
31
|
+
readonly 12: "3rem";
|
|
32
|
+
readonly 16: "4rem";
|
|
33
|
+
readonly 20: "5rem";
|
|
34
|
+
readonly 24: "6rem";
|
|
35
|
+
readonly 32: "8rem";
|
|
36
|
+
readonly 40: "10rem";
|
|
37
|
+
readonly 48: "12rem";
|
|
38
|
+
readonly 56: "14rem";
|
|
39
|
+
readonly 64: "16rem";
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Typography — a modular scale at ratio 1.2 (minor third), rounded to sensible pixel values.
|
|
43
|
+
*
|
|
44
|
+
* 1.2 rather than the more common 1.25 or golden ratio: on the wide viewports these components
|
|
45
|
+
* target, a steeper ratio makes display sizes enormous before the body sizes have room to
|
|
46
|
+
* differentiate. 1.2 gives eight useful steps between 12px and 60px.
|
|
47
|
+
*
|
|
48
|
+
* Each step pairs a size with a line height, because a size without its leading is not a
|
|
49
|
+
* typographic decision — and line height must *decrease* proportionally as size increases.
|
|
50
|
+
*/
|
|
51
|
+
declare const fontSize: {
|
|
52
|
+
readonly xs: readonly ["0.75rem", {
|
|
53
|
+
readonly lineHeight: "1.125rem";
|
|
54
|
+
readonly letterSpacing: "0.01em";
|
|
55
|
+
}];
|
|
56
|
+
readonly sm: readonly ["0.875rem", {
|
|
57
|
+
readonly lineHeight: "1.375rem";
|
|
58
|
+
readonly letterSpacing: "0.005em";
|
|
59
|
+
}];
|
|
60
|
+
readonly base: readonly ["1rem", {
|
|
61
|
+
readonly lineHeight: "1.625rem";
|
|
62
|
+
readonly letterSpacing: "0";
|
|
63
|
+
}];
|
|
64
|
+
readonly lg: readonly ["1.125rem", {
|
|
65
|
+
readonly lineHeight: "1.75rem";
|
|
66
|
+
readonly letterSpacing: "-0.005em";
|
|
67
|
+
}];
|
|
68
|
+
readonly xl: readonly ["1.25rem", {
|
|
69
|
+
readonly lineHeight: "1.875rem";
|
|
70
|
+
readonly letterSpacing: "-0.01em";
|
|
71
|
+
}];
|
|
72
|
+
readonly '2xl': readonly ["1.5rem", {
|
|
73
|
+
readonly lineHeight: "2rem";
|
|
74
|
+
readonly letterSpacing: "-0.015em";
|
|
75
|
+
}];
|
|
76
|
+
readonly '3xl': readonly ["1.875rem", {
|
|
77
|
+
readonly lineHeight: "2.375rem";
|
|
78
|
+
readonly letterSpacing: "-0.02em";
|
|
79
|
+
}];
|
|
80
|
+
readonly '4xl': readonly ["2.25rem", {
|
|
81
|
+
readonly lineHeight: "2.625rem";
|
|
82
|
+
readonly letterSpacing: "-0.025em";
|
|
83
|
+
}];
|
|
84
|
+
readonly '5xl': readonly ["3rem", {
|
|
85
|
+
readonly lineHeight: "3.25rem";
|
|
86
|
+
readonly letterSpacing: "-0.03em";
|
|
87
|
+
}];
|
|
88
|
+
readonly '6xl': readonly ["3.75rem", {
|
|
89
|
+
readonly lineHeight: "3.9rem";
|
|
90
|
+
readonly letterSpacing: "-0.035em";
|
|
91
|
+
}];
|
|
92
|
+
readonly '7xl': readonly ["4.5rem", {
|
|
93
|
+
readonly lineHeight: "4.6rem";
|
|
94
|
+
readonly letterSpacing: "-0.04em";
|
|
95
|
+
}];
|
|
96
|
+
};
|
|
97
|
+
declare const fontWeight: {
|
|
98
|
+
readonly normal: "400";
|
|
99
|
+
readonly medium: "500";
|
|
100
|
+
readonly semibold: "600";
|
|
101
|
+
readonly bold: "700";
|
|
102
|
+
};
|
|
103
|
+
declare const fontFamily: {
|
|
104
|
+
/**
|
|
105
|
+
* The system UI stack. Deliberately not a webfont: the fastest, most legible text on any
|
|
106
|
+
* platform is the font the user's OS already has loaded, and a design system should not force
|
|
107
|
+
* a font decision on its consumers.
|
|
108
|
+
*/
|
|
109
|
+
readonly sans: string;
|
|
110
|
+
readonly mono: string;
|
|
111
|
+
};
|
|
112
|
+
/** Corner radii. `full` is a large fixed value rather than 50%, so pills stay pill-shaped. */
|
|
113
|
+
declare const radius: {
|
|
114
|
+
readonly none: "0";
|
|
115
|
+
readonly xs: "0.25rem";
|
|
116
|
+
readonly sm: "0.375rem";
|
|
117
|
+
readonly md: "0.5rem";
|
|
118
|
+
readonly lg: "0.75rem";
|
|
119
|
+
readonly xl: "1rem";
|
|
120
|
+
readonly '2xl': "1.5rem";
|
|
121
|
+
readonly '3xl': "2rem";
|
|
122
|
+
readonly full: "9999px";
|
|
123
|
+
};
|
|
124
|
+
/**
|
|
125
|
+
* Elevation — layered shadows, not single ones.
|
|
126
|
+
*
|
|
127
|
+
* A single `box-shadow` cannot describe real light: an object casts both a tight contact shadow
|
|
128
|
+
* directly beneath it and a broader ambient shadow further out. Every step here composes both,
|
|
129
|
+
* which is the difference between a card that sits on the page and one that looks pasted onto it.
|
|
130
|
+
*
|
|
131
|
+
* Shadow colour is a token so it can shift with the theme — a pure-black shadow on a dark
|
|
132
|
+
* surface is invisible, so the dark theme uses a deeper, more spread variant.
|
|
133
|
+
*/
|
|
134
|
+
declare const shadow: {
|
|
135
|
+
readonly none: "none";
|
|
136
|
+
readonly xs: "0 1px 2px 0 var(--ansh-shadow-color, rgb(15 23 42 / 0.05))";
|
|
137
|
+
readonly sm: string;
|
|
138
|
+
readonly md: string;
|
|
139
|
+
readonly lg: string;
|
|
140
|
+
readonly xl: string;
|
|
141
|
+
readonly '2xl': "0 25px 50px -12px var(--ansh-shadow-color, rgb(15 23 42 / 0.2))";
|
|
142
|
+
/** Inset — for pressed states and inputs. */
|
|
143
|
+
readonly inner: "inset 0 2px 4px 0 var(--ansh-shadow-color, rgb(15 23 42 / 0.06))";
|
|
144
|
+
/**
|
|
145
|
+
* Glow. Uses `currentColor` so a button's glow automatically matches its own accent without
|
|
146
|
+
* the author repeating the colour.
|
|
147
|
+
*/
|
|
148
|
+
readonly glow: "0 0 24px -4px currentColor";
|
|
149
|
+
readonly glowLg: "0 0 48px -8px currentColor";
|
|
150
|
+
};
|
|
151
|
+
/** Backdrop blur steps, for glass surfaces. */
|
|
152
|
+
declare const blur: {
|
|
153
|
+
readonly none: "0";
|
|
154
|
+
readonly xs: "2px";
|
|
155
|
+
readonly sm: "4px";
|
|
156
|
+
readonly md: "8px";
|
|
157
|
+
readonly lg: "16px";
|
|
158
|
+
readonly xl: "24px";
|
|
159
|
+
readonly '2xl': "40px";
|
|
160
|
+
readonly '3xl': "64px";
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Motion durations in seconds.
|
|
164
|
+
*
|
|
165
|
+
* Named by intent rather than by number. The values follow a rule of thumb that holds up well:
|
|
166
|
+
* the distance travelled should determine the duration, so a tooltip appearing in place is
|
|
167
|
+
* `instant`, a dropdown is `fast`, and a full-screen sheet is `slow`.
|
|
168
|
+
*/
|
|
169
|
+
declare const duration: {
|
|
170
|
+
readonly instant: "0.1s";
|
|
171
|
+
readonly fast: "0.2s";
|
|
172
|
+
readonly normal: "0.3s";
|
|
173
|
+
readonly moderate: "0.45s";
|
|
174
|
+
readonly slow: "0.6s";
|
|
175
|
+
readonly slower: "0.9s";
|
|
176
|
+
readonly deliberate: "1.2s";
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* CSS timing functions matching the engine's `signature` easings exactly.
|
|
180
|
+
*
|
|
181
|
+
* Keeping these in lockstep means a CSS transition and a JS animation on the same element move
|
|
182
|
+
* identically — which matters more than it sounds, because mismatched curves on adjacent
|
|
183
|
+
* elements is one of those things that reads as "cheap" without the viewer knowing why.
|
|
184
|
+
*/
|
|
185
|
+
declare const easing: {
|
|
186
|
+
readonly linear: "linear";
|
|
187
|
+
readonly standard: "cubic-bezier(0.4, 0, 0.2, 1)";
|
|
188
|
+
readonly emphasized: "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
189
|
+
readonly enter: "cubic-bezier(0, 0, 0.2, 1)";
|
|
190
|
+
readonly exit: "cubic-bezier(0.4, 0, 1, 1)";
|
|
191
|
+
readonly overshoot: "cubic-bezier(0.34, 1.56, 0.64, 1)";
|
|
192
|
+
readonly cinematic: "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
193
|
+
};
|
|
194
|
+
/**
|
|
195
|
+
* Z-index scale.
|
|
196
|
+
*
|
|
197
|
+
* Sparse, deliberate values with names. The alternative — `z-index: 9999` scattered through a
|
|
198
|
+
* codebase — is the single most common source of stacking bugs in a component library.
|
|
199
|
+
*/
|
|
200
|
+
declare const zIndex: {
|
|
201
|
+
readonly hide: "-1";
|
|
202
|
+
readonly base: "0";
|
|
203
|
+
readonly raised: "10";
|
|
204
|
+
readonly dropdown: "1000";
|
|
205
|
+
readonly sticky: "1100";
|
|
206
|
+
readonly overlay: "1200";
|
|
207
|
+
readonly modal: "1300";
|
|
208
|
+
readonly popover: "1400";
|
|
209
|
+
readonly toast: "1500";
|
|
210
|
+
readonly tooltip: "1600";
|
|
211
|
+
/** Reserved for skip links and focus traps, which must beat everything. */
|
|
212
|
+
readonly max: "2147483647";
|
|
213
|
+
};
|
|
214
|
+
/** Breakpoints, matching the widths where real layout decisions occur. */
|
|
215
|
+
declare const breakpoint: {
|
|
216
|
+
readonly sm: "640px";
|
|
217
|
+
readonly md: "768px";
|
|
218
|
+
readonly lg: "1024px";
|
|
219
|
+
readonly xl: "1280px";
|
|
220
|
+
readonly '2xl': "1536px";
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Neutral ramp, defined in OKLCH.
|
|
224
|
+
*
|
|
225
|
+
* Lightness steps are perceptually even, which a hex-defined grey ramp never is — the usual
|
|
226
|
+
* result is a scale that looks well-spaced at the light end and bunched at the dark end. A slight
|
|
227
|
+
* blue chroma (hue 264) keeps it from reading as muddy against saturated accents.
|
|
228
|
+
*/
|
|
229
|
+
declare const neutral: {
|
|
230
|
+
readonly 50: "oklch(98.5% 0.002 264)";
|
|
231
|
+
readonly 100: "oklch(96.8% 0.004 264)";
|
|
232
|
+
readonly 200: "oklch(92.9% 0.007 264)";
|
|
233
|
+
readonly 300: "oklch(86.9% 0.011 264)";
|
|
234
|
+
readonly 400: "oklch(70.7% 0.018 264)";
|
|
235
|
+
readonly 500: "oklch(55.4% 0.022 264)";
|
|
236
|
+
readonly 600: "oklch(44.6% 0.021 264)";
|
|
237
|
+
readonly 700: "oklch(37.2% 0.019 264)";
|
|
238
|
+
readonly 800: "oklch(27.9% 0.017 264)";
|
|
239
|
+
readonly 900: "oklch(20.8% 0.015 264)";
|
|
240
|
+
readonly 950: "oklch(13.8% 0.014 264)";
|
|
241
|
+
readonly 1000: "oklch(8.5% 0.012 264)";
|
|
242
|
+
};
|
|
243
|
+
/** The Ansh brand ramp — the blue the library ships with. */
|
|
244
|
+
declare const brand: {
|
|
245
|
+
readonly 50: "oklch(97% 0.017 253)";
|
|
246
|
+
readonly 100: "oklch(93.8% 0.036 253)";
|
|
247
|
+
readonly 200: "oklch(88.5% 0.069 253)";
|
|
248
|
+
readonly 300: "oklch(80.9% 0.111 253)";
|
|
249
|
+
readonly 400: "oklch(71.4% 0.153 253)";
|
|
250
|
+
readonly 500: "oklch(62.3% 0.188 253)";
|
|
251
|
+
readonly 600: "oklch(54.6% 0.208 253)";
|
|
252
|
+
readonly 700: "oklch(46.4% 0.192 253)";
|
|
253
|
+
readonly 800: "oklch(39.1% 0.16 253)";
|
|
254
|
+
readonly 900: "oklch(33.5% 0.129 253)";
|
|
255
|
+
readonly 950: "oklch(23.2% 0.093 253)";
|
|
256
|
+
};
|
|
257
|
+
/** Status ramps. Only the steps that get used are defined, rather than a full 11 for each. */
|
|
258
|
+
declare const status: {
|
|
259
|
+
readonly success: {
|
|
260
|
+
readonly subtle: "oklch(95.5% 0.035 155)";
|
|
261
|
+
readonly default: "oklch(58% 0.15 155)";
|
|
262
|
+
readonly strong: "oklch(44% 0.12 155)";
|
|
263
|
+
};
|
|
264
|
+
readonly warning: {
|
|
265
|
+
readonly subtle: "oklch(96.5% 0.045 85)";
|
|
266
|
+
readonly default: "oklch(72% 0.16 75)";
|
|
267
|
+
readonly strong: "oklch(52% 0.13 65)";
|
|
268
|
+
};
|
|
269
|
+
readonly danger: {
|
|
270
|
+
readonly subtle: "oklch(95.5% 0.03 25)";
|
|
271
|
+
readonly default: "oklch(58% 0.21 25)";
|
|
272
|
+
readonly strong: "oklch(46% 0.18 25)";
|
|
273
|
+
};
|
|
274
|
+
readonly info: {
|
|
275
|
+
readonly subtle: "oklch(96% 0.025 240)";
|
|
276
|
+
readonly default: "oklch(62% 0.17 245)";
|
|
277
|
+
readonly strong: "oklch(48% 0.15 250)";
|
|
278
|
+
};
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Semantic tokens — meaning mapped onto primitives.
|
|
283
|
+
*
|
|
284
|
+
* This layer is why theming works. A component references `surface.raised`, never `neutral.100`.
|
|
285
|
+
* Switching to dark mode remaps `surface.raised` to `neutral.900`, and every component follows
|
|
286
|
+
* without a single change. A component that reaches past this layer to a primitive is a bug: it
|
|
287
|
+
* will look wrong in one theme and nobody will notice until a user reports it.
|
|
288
|
+
*
|
|
289
|
+
* The naming follows a consistent pattern:
|
|
290
|
+
*
|
|
291
|
+
* - `surface.*` — backgrounds, ordered by elevation
|
|
292
|
+
* - `content.*` — text and icons, ordered by prominence
|
|
293
|
+
* - `border.*` — dividers and outlines, ordered by strength
|
|
294
|
+
* - `accent.*` — the interactive brand colour and its states
|
|
295
|
+
* - `state.*` — success/warning/danger/info
|
|
296
|
+
*/
|
|
297
|
+
interface SemanticTokens {
|
|
298
|
+
surface: {
|
|
299
|
+
/** The page background. */
|
|
300
|
+
canvas: string;
|
|
301
|
+
/** Cards and panels sitting on the canvas. */
|
|
302
|
+
raised: string;
|
|
303
|
+
/** Menus, popovers and anything floating above `raised`. */
|
|
304
|
+
overlay: string;
|
|
305
|
+
/** Subtly recessed areas — code blocks, well insets. */
|
|
306
|
+
sunken: string;
|
|
307
|
+
/** Translucent glass surface, for use with `backdrop-filter`. */
|
|
308
|
+
glass: string;
|
|
309
|
+
/** The scrim behind a modal. */
|
|
310
|
+
scrim: string;
|
|
311
|
+
};
|
|
312
|
+
content: {
|
|
313
|
+
/** Body text and headings. Must reach 7:1 against `surface.canvas`. */
|
|
314
|
+
primary: string;
|
|
315
|
+
/** Supporting text. Must reach 4.5:1. */
|
|
316
|
+
secondary: string;
|
|
317
|
+
/** De-emphasised text — timestamps, captions. Must reach 4.5:1 at ≥14px. */
|
|
318
|
+
tertiary: string;
|
|
319
|
+
/** Placeholder and disabled text. Exempt from contrast minimums by WCAG. */
|
|
320
|
+
disabled: string;
|
|
321
|
+
/** Text placed on top of `accent.default`. */
|
|
322
|
+
onAccent: string;
|
|
323
|
+
/** Inverted text, for use on `content.primary` as a background. */
|
|
324
|
+
inverse: string;
|
|
325
|
+
};
|
|
326
|
+
border: {
|
|
327
|
+
/** Hairline dividers. */
|
|
328
|
+
subtle: string;
|
|
329
|
+
/** Input and card outlines. */
|
|
330
|
+
default: string;
|
|
331
|
+
/** Hovered or emphasised outlines. */
|
|
332
|
+
strong: string;
|
|
333
|
+
/** The focus ring. Must reach 3:1 against both adjacent surfaces. */
|
|
334
|
+
focus: string;
|
|
335
|
+
};
|
|
336
|
+
accent: {
|
|
337
|
+
subtle: string;
|
|
338
|
+
muted: string;
|
|
339
|
+
default: string;
|
|
340
|
+
hover: string;
|
|
341
|
+
active: string;
|
|
342
|
+
/** For text and icons rendered in the accent colour on a neutral surface. */
|
|
343
|
+
text: string;
|
|
344
|
+
};
|
|
345
|
+
state: {
|
|
346
|
+
successSubtle: string;
|
|
347
|
+
success: string;
|
|
348
|
+
warningSubtle: string;
|
|
349
|
+
warning: string;
|
|
350
|
+
dangerSubtle: string;
|
|
351
|
+
danger: string;
|
|
352
|
+
infoSubtle: string;
|
|
353
|
+
info: string;
|
|
354
|
+
};
|
|
355
|
+
/** The shadow colour the elevation scale multiplies through. */
|
|
356
|
+
shadowColor: string;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Light theme.
|
|
360
|
+
*
|
|
361
|
+
* Contrast ratios against `surface.canvas` (`neutral.50`):
|
|
362
|
+
* `content.primary` → 15.8:1 (AAA)
|
|
363
|
+
* `content.secondary` → 7.4:1 (AAA)
|
|
364
|
+
* `content.tertiary` → 4.7:1 (AA)
|
|
365
|
+
* `border.focus` → 3.4:1 (AA non-text)
|
|
366
|
+
*/
|
|
367
|
+
declare const light: SemanticTokens;
|
|
368
|
+
/**
|
|
369
|
+
* Dark theme.
|
|
370
|
+
*
|
|
371
|
+
* Not an inversion of `light`. Three adjustments that a mechanical inversion misses:
|
|
372
|
+
*
|
|
373
|
+
* 1. **Surfaces get lighter as they rise, not darker.** In light mode, elevation is signalled by
|
|
374
|
+
* shadow. On a dark background shadow is invisible, so elevation must be signalled by the
|
|
375
|
+
* surface itself becoming lighter.
|
|
376
|
+
* 2. **Chroma is raised.** Saturated colours read as less vivid against dark backgrounds
|
|
377
|
+
* (Helmholtz–Kohlrausch), so accents step *lighter* rather than mirroring their light-mode step.
|
|
378
|
+
* 3. **Body text is not pure white.** `#fff` on a near-black background causes halation — the
|
|
379
|
+
* text appears to bleed. `neutral.100` reads as white while staying comfortable.
|
|
380
|
+
*/
|
|
381
|
+
declare const dark: SemanticTokens;
|
|
382
|
+
declare const themes: {
|
|
383
|
+
readonly light: SemanticTokens;
|
|
384
|
+
readonly dark: SemanticTokens;
|
|
385
|
+
};
|
|
386
|
+
type ThemeName = keyof typeof themes;
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* CSS custom property generation.
|
|
390
|
+
*
|
|
391
|
+
* Tokens exist twice on purpose — as TypeScript values and as CSS variables — because the two
|
|
392
|
+
* are consumed differently and neither can serve both jobs:
|
|
393
|
+
*
|
|
394
|
+
* - **TypeScript** values are needed where JavaScript computes with them: passing colours into
|
|
395
|
+
* canvas effects, deriving palettes, computing contrast.
|
|
396
|
+
* - **CSS variables** are needed for everything the cascade should own: theming a subtree,
|
|
397
|
+
* respecting `prefers-color-scheme`, and letting a consumer override a token in their own
|
|
398
|
+
* stylesheet without touching a build step.
|
|
399
|
+
*
|
|
400
|
+
* This module is the bridge, and it is generated from the same source of truth so the two can't
|
|
401
|
+
* drift.
|
|
402
|
+
*/
|
|
403
|
+
declare const CSS_PREFIX = "ansh";
|
|
404
|
+
/** Structural tokens — identical in every theme. */
|
|
405
|
+
declare function structuralVariables(): Map<string, string>;
|
|
406
|
+
/** Theme-dependent tokens for one theme. */
|
|
407
|
+
declare function themeVariables(tokens: SemanticTokens): Map<string, string>;
|
|
408
|
+
/**
|
|
409
|
+
* Emit the complete stylesheet.
|
|
410
|
+
*
|
|
411
|
+
* The theming strategy is deliberately layered so it works for every consumer:
|
|
412
|
+
*
|
|
413
|
+
* 1. `:root` carries the light theme, so the default works with no configuration.
|
|
414
|
+
* 2. `@media (prefers-color-scheme: dark)` applies dark automatically — but *only* when the
|
|
415
|
+
* document has not opted into manual control, guarded by `:root:not([data-theme])`. Without
|
|
416
|
+
* that guard, a user who explicitly chose light mode in an app whose OS is dark would get dark
|
|
417
|
+
* anyway, which is the single most common theming bug in the wild.
|
|
418
|
+
* 3. `[data-theme='dark']` and `[data-theme='light']` allow explicit control at any level of the
|
|
419
|
+
* tree, so a single dark card on a light page works with no extra plumbing.
|
|
420
|
+
*/
|
|
421
|
+
declare function generateCss(): string;
|
|
422
|
+
/**
|
|
423
|
+
* Apply a theme imperatively.
|
|
424
|
+
*
|
|
425
|
+
* Sets `data-theme` on the target, which the stylesheet above already understands. Prefer this
|
|
426
|
+
* over injecting inline styles: it keeps every token in one cascade layer and lets the browser
|
|
427
|
+
* do the work.
|
|
428
|
+
*
|
|
429
|
+
* @param theme `'light'`, `'dark'`, or `'system'` to hand control back to `prefers-color-scheme`.
|
|
430
|
+
* @param target Defaults to `document.documentElement`. Pass an element to theme a subtree.
|
|
431
|
+
*/
|
|
432
|
+
declare function applyTheme(theme: 'light' | 'dark' | 'system', target?: HTMLElement): void;
|
|
433
|
+
/**
|
|
434
|
+
* Read the currently applied theme.
|
|
435
|
+
*
|
|
436
|
+
* Resolves `'system'` to whichever theme is actually in effect, because callers generally want to
|
|
437
|
+
* know what the user is *seeing*, not how it was configured.
|
|
438
|
+
*/
|
|
439
|
+
declare function resolveTheme(target?: HTMLElement): 'light' | 'dark';
|
|
440
|
+
/**
|
|
441
|
+
* Build an inline `style` object for a subtree override.
|
|
442
|
+
*
|
|
443
|
+
* Used by framework `<ThemeProvider>` components that need to apply a theme before the stylesheet
|
|
444
|
+
* has necessarily loaded — during SSR, most importantly, where a flash of the wrong theme is
|
|
445
|
+
* otherwise unavoidable.
|
|
446
|
+
*/
|
|
447
|
+
declare function themeStyle(theme: 'light' | 'dark'): Record<string, string>;
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* @ansh-ui/tokens — the Ansh design language.
|
|
451
|
+
*
|
|
452
|
+
* Tokens are exported both as TypeScript values (for code that computes with them) and as CSS
|
|
453
|
+
* custom properties (for everything the cascade should own). Both are generated from the same
|
|
454
|
+
* source, so they cannot drift.
|
|
455
|
+
*
|
|
456
|
+
* ```ts
|
|
457
|
+
* import '@ansh-ui/tokens/ansh.css'
|
|
458
|
+
* import { space, applyTheme } from '@ansh-ui/tokens'
|
|
459
|
+
* ```
|
|
460
|
+
*/
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Every structural token in one object.
|
|
464
|
+
*
|
|
465
|
+
* Convenient for a Tailwind preset or a styled-components theme, where the consumer wants the
|
|
466
|
+
* whole scale rather than individual imports.
|
|
467
|
+
*/
|
|
468
|
+
declare const tokens: {
|
|
469
|
+
readonly space: {
|
|
470
|
+
readonly 0: "0";
|
|
471
|
+
readonly px: "1px";
|
|
472
|
+
readonly 0.5: "0.125rem";
|
|
473
|
+
readonly 1: "0.25rem";
|
|
474
|
+
readonly 1.5: "0.375rem";
|
|
475
|
+
readonly 2: "0.5rem";
|
|
476
|
+
readonly 3: "0.75rem";
|
|
477
|
+
readonly 4: "1rem";
|
|
478
|
+
readonly 5: "1.25rem";
|
|
479
|
+
readonly 6: "1.5rem";
|
|
480
|
+
readonly 8: "2rem";
|
|
481
|
+
readonly 10: "2.5rem";
|
|
482
|
+
readonly 12: "3rem";
|
|
483
|
+
readonly 16: "4rem";
|
|
484
|
+
readonly 20: "5rem";
|
|
485
|
+
readonly 24: "6rem";
|
|
486
|
+
readonly 32: "8rem";
|
|
487
|
+
readonly 40: "10rem";
|
|
488
|
+
readonly 48: "12rem";
|
|
489
|
+
readonly 56: "14rem";
|
|
490
|
+
readonly 64: "16rem";
|
|
491
|
+
};
|
|
492
|
+
readonly radius: {
|
|
493
|
+
readonly none: "0";
|
|
494
|
+
readonly xs: "0.25rem";
|
|
495
|
+
readonly sm: "0.375rem";
|
|
496
|
+
readonly md: "0.5rem";
|
|
497
|
+
readonly lg: "0.75rem";
|
|
498
|
+
readonly xl: "1rem";
|
|
499
|
+
readonly '2xl': "1.5rem";
|
|
500
|
+
readonly '3xl': "2rem";
|
|
501
|
+
readonly full: "9999px";
|
|
502
|
+
};
|
|
503
|
+
readonly shadow: {
|
|
504
|
+
readonly none: "none";
|
|
505
|
+
readonly xs: "0 1px 2px 0 var(--ansh-shadow-color, rgb(15 23 42 / 0.05))";
|
|
506
|
+
readonly sm: string;
|
|
507
|
+
readonly md: string;
|
|
508
|
+
readonly lg: string;
|
|
509
|
+
readonly xl: string;
|
|
510
|
+
readonly '2xl': "0 25px 50px -12px var(--ansh-shadow-color, rgb(15 23 42 / 0.2))";
|
|
511
|
+
readonly inner: "inset 0 2px 4px 0 var(--ansh-shadow-color, rgb(15 23 42 / 0.06))";
|
|
512
|
+
readonly glow: "0 0 24px -4px currentColor";
|
|
513
|
+
readonly glowLg: "0 0 48px -8px currentColor";
|
|
514
|
+
};
|
|
515
|
+
readonly blur: {
|
|
516
|
+
readonly none: "0";
|
|
517
|
+
readonly xs: "2px";
|
|
518
|
+
readonly sm: "4px";
|
|
519
|
+
readonly md: "8px";
|
|
520
|
+
readonly lg: "16px";
|
|
521
|
+
readonly xl: "24px";
|
|
522
|
+
readonly '2xl': "40px";
|
|
523
|
+
readonly '3xl': "64px";
|
|
524
|
+
};
|
|
525
|
+
readonly duration: {
|
|
526
|
+
readonly instant: "0.1s";
|
|
527
|
+
readonly fast: "0.2s";
|
|
528
|
+
readonly normal: "0.3s";
|
|
529
|
+
readonly moderate: "0.45s";
|
|
530
|
+
readonly slow: "0.6s";
|
|
531
|
+
readonly slower: "0.9s";
|
|
532
|
+
readonly deliberate: "1.2s";
|
|
533
|
+
};
|
|
534
|
+
readonly easing: {
|
|
535
|
+
readonly linear: "linear";
|
|
536
|
+
readonly standard: "cubic-bezier(0.4, 0, 0.2, 1)";
|
|
537
|
+
readonly emphasized: "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
538
|
+
readonly enter: "cubic-bezier(0, 0, 0.2, 1)";
|
|
539
|
+
readonly exit: "cubic-bezier(0.4, 0, 1, 1)";
|
|
540
|
+
readonly overshoot: "cubic-bezier(0.34, 1.56, 0.64, 1)";
|
|
541
|
+
readonly cinematic: "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
542
|
+
};
|
|
543
|
+
readonly zIndex: {
|
|
544
|
+
readonly hide: "-1";
|
|
545
|
+
readonly base: "0";
|
|
546
|
+
readonly raised: "10";
|
|
547
|
+
readonly dropdown: "1000";
|
|
548
|
+
readonly sticky: "1100";
|
|
549
|
+
readonly overlay: "1200";
|
|
550
|
+
readonly modal: "1300";
|
|
551
|
+
readonly popover: "1400";
|
|
552
|
+
readonly toast: "1500";
|
|
553
|
+
readonly tooltip: "1600";
|
|
554
|
+
readonly max: "2147483647";
|
|
555
|
+
};
|
|
556
|
+
readonly fontSize: {
|
|
557
|
+
readonly xs: readonly ["0.75rem", {
|
|
558
|
+
readonly lineHeight: "1.125rem";
|
|
559
|
+
readonly letterSpacing: "0.01em";
|
|
560
|
+
}];
|
|
561
|
+
readonly sm: readonly ["0.875rem", {
|
|
562
|
+
readonly lineHeight: "1.375rem";
|
|
563
|
+
readonly letterSpacing: "0.005em";
|
|
564
|
+
}];
|
|
565
|
+
readonly base: readonly ["1rem", {
|
|
566
|
+
readonly lineHeight: "1.625rem";
|
|
567
|
+
readonly letterSpacing: "0";
|
|
568
|
+
}];
|
|
569
|
+
readonly lg: readonly ["1.125rem", {
|
|
570
|
+
readonly lineHeight: "1.75rem";
|
|
571
|
+
readonly letterSpacing: "-0.005em";
|
|
572
|
+
}];
|
|
573
|
+
readonly xl: readonly ["1.25rem", {
|
|
574
|
+
readonly lineHeight: "1.875rem";
|
|
575
|
+
readonly letterSpacing: "-0.01em";
|
|
576
|
+
}];
|
|
577
|
+
readonly '2xl': readonly ["1.5rem", {
|
|
578
|
+
readonly lineHeight: "2rem";
|
|
579
|
+
readonly letterSpacing: "-0.015em";
|
|
580
|
+
}];
|
|
581
|
+
readonly '3xl': readonly ["1.875rem", {
|
|
582
|
+
readonly lineHeight: "2.375rem";
|
|
583
|
+
readonly letterSpacing: "-0.02em";
|
|
584
|
+
}];
|
|
585
|
+
readonly '4xl': readonly ["2.25rem", {
|
|
586
|
+
readonly lineHeight: "2.625rem";
|
|
587
|
+
readonly letterSpacing: "-0.025em";
|
|
588
|
+
}];
|
|
589
|
+
readonly '5xl': readonly ["3rem", {
|
|
590
|
+
readonly lineHeight: "3.25rem";
|
|
591
|
+
readonly letterSpacing: "-0.03em";
|
|
592
|
+
}];
|
|
593
|
+
readonly '6xl': readonly ["3.75rem", {
|
|
594
|
+
readonly lineHeight: "3.9rem";
|
|
595
|
+
readonly letterSpacing: "-0.035em";
|
|
596
|
+
}];
|
|
597
|
+
readonly '7xl': readonly ["4.5rem", {
|
|
598
|
+
readonly lineHeight: "4.6rem";
|
|
599
|
+
readonly letterSpacing: "-0.04em";
|
|
600
|
+
}];
|
|
601
|
+
};
|
|
602
|
+
readonly fontWeight: {
|
|
603
|
+
readonly normal: "400";
|
|
604
|
+
readonly medium: "500";
|
|
605
|
+
readonly semibold: "600";
|
|
606
|
+
readonly bold: "700";
|
|
607
|
+
};
|
|
608
|
+
readonly fontFamily: {
|
|
609
|
+
readonly sans: string;
|
|
610
|
+
readonly mono: string;
|
|
611
|
+
};
|
|
612
|
+
readonly breakpoint: {
|
|
613
|
+
readonly sm: "640px";
|
|
614
|
+
readonly md: "768px";
|
|
615
|
+
readonly lg: "1024px";
|
|
616
|
+
readonly xl: "1280px";
|
|
617
|
+
readonly '2xl': "1536px";
|
|
618
|
+
};
|
|
619
|
+
};
|
|
620
|
+
type Tokens = typeof tokens;
|
|
621
|
+
/**
|
|
622
|
+
* A Tailwind CSS preset that maps Ansh tokens onto Tailwind's theme keys.
|
|
623
|
+
*
|
|
624
|
+
* Returned as a plain object rather than importing Tailwind types, so this package stays free of a
|
|
625
|
+
* Tailwind dependency for the majority of consumers who don't use it.
|
|
626
|
+
*
|
|
627
|
+
* ```js
|
|
628
|
+
* // tailwind.config.js
|
|
629
|
+
* import { tailwindPreset } from '@ansh-ui/tokens'
|
|
630
|
+
* export default { presets: [tailwindPreset()] }
|
|
631
|
+
* ```
|
|
632
|
+
*/
|
|
633
|
+
declare function tailwindPreset(): {
|
|
634
|
+
theme: {
|
|
635
|
+
extend: {
|
|
636
|
+
spacing: {
|
|
637
|
+
readonly 0: "0";
|
|
638
|
+
readonly px: "1px";
|
|
639
|
+
readonly 0.5: "0.125rem";
|
|
640
|
+
readonly 1: "0.25rem";
|
|
641
|
+
readonly 1.5: "0.375rem";
|
|
642
|
+
readonly 2: "0.5rem";
|
|
643
|
+
readonly 3: "0.75rem";
|
|
644
|
+
readonly 4: "1rem";
|
|
645
|
+
readonly 5: "1.25rem";
|
|
646
|
+
readonly 6: "1.5rem";
|
|
647
|
+
readonly 8: "2rem";
|
|
648
|
+
readonly 10: "2.5rem";
|
|
649
|
+
readonly 12: "3rem";
|
|
650
|
+
readonly 16: "4rem";
|
|
651
|
+
readonly 20: "5rem";
|
|
652
|
+
readonly 24: "6rem";
|
|
653
|
+
readonly 32: "8rem";
|
|
654
|
+
readonly 40: "10rem";
|
|
655
|
+
readonly 48: "12rem";
|
|
656
|
+
readonly 56: "14rem";
|
|
657
|
+
readonly 64: "16rem";
|
|
658
|
+
};
|
|
659
|
+
borderRadius: {
|
|
660
|
+
readonly none: "0";
|
|
661
|
+
readonly xs: "0.25rem";
|
|
662
|
+
readonly sm: "0.375rem";
|
|
663
|
+
readonly md: "0.5rem";
|
|
664
|
+
readonly lg: "0.75rem";
|
|
665
|
+
readonly xl: "1rem";
|
|
666
|
+
readonly '2xl': "1.5rem";
|
|
667
|
+
readonly '3xl': "2rem";
|
|
668
|
+
readonly full: "9999px";
|
|
669
|
+
};
|
|
670
|
+
boxShadow: {
|
|
671
|
+
readonly none: "none";
|
|
672
|
+
readonly xs: "0 1px 2px 0 var(--ansh-shadow-color, rgb(15 23 42 / 0.05))";
|
|
673
|
+
readonly sm: string;
|
|
674
|
+
readonly md: string;
|
|
675
|
+
readonly lg: string;
|
|
676
|
+
readonly xl: string;
|
|
677
|
+
readonly '2xl': "0 25px 50px -12px var(--ansh-shadow-color, rgb(15 23 42 / 0.2))";
|
|
678
|
+
readonly inner: "inset 0 2px 4px 0 var(--ansh-shadow-color, rgb(15 23 42 / 0.06))";
|
|
679
|
+
readonly glow: "0 0 24px -4px currentColor";
|
|
680
|
+
readonly glowLg: "0 0 48px -8px currentColor";
|
|
681
|
+
};
|
|
682
|
+
blur: {
|
|
683
|
+
readonly none: "0";
|
|
684
|
+
readonly xs: "2px";
|
|
685
|
+
readonly sm: "4px";
|
|
686
|
+
readonly md: "8px";
|
|
687
|
+
readonly lg: "16px";
|
|
688
|
+
readonly xl: "24px";
|
|
689
|
+
readonly '2xl': "40px";
|
|
690
|
+
readonly '3xl': "64px";
|
|
691
|
+
};
|
|
692
|
+
fontFamily: {
|
|
693
|
+
sans: string[];
|
|
694
|
+
mono: string[];
|
|
695
|
+
};
|
|
696
|
+
fontSize: {
|
|
697
|
+
readonly xs: readonly ["0.75rem", {
|
|
698
|
+
readonly lineHeight: "1.125rem";
|
|
699
|
+
readonly letterSpacing: "0.01em";
|
|
700
|
+
}];
|
|
701
|
+
readonly sm: readonly ["0.875rem", {
|
|
702
|
+
readonly lineHeight: "1.375rem";
|
|
703
|
+
readonly letterSpacing: "0.005em";
|
|
704
|
+
}];
|
|
705
|
+
readonly base: readonly ["1rem", {
|
|
706
|
+
readonly lineHeight: "1.625rem";
|
|
707
|
+
readonly letterSpacing: "0";
|
|
708
|
+
}];
|
|
709
|
+
readonly lg: readonly ["1.125rem", {
|
|
710
|
+
readonly lineHeight: "1.75rem";
|
|
711
|
+
readonly letterSpacing: "-0.005em";
|
|
712
|
+
}];
|
|
713
|
+
readonly xl: readonly ["1.25rem", {
|
|
714
|
+
readonly lineHeight: "1.875rem";
|
|
715
|
+
readonly letterSpacing: "-0.01em";
|
|
716
|
+
}];
|
|
717
|
+
readonly '2xl': readonly ["1.5rem", {
|
|
718
|
+
readonly lineHeight: "2rem";
|
|
719
|
+
readonly letterSpacing: "-0.015em";
|
|
720
|
+
}];
|
|
721
|
+
readonly '3xl': readonly ["1.875rem", {
|
|
722
|
+
readonly lineHeight: "2.375rem";
|
|
723
|
+
readonly letterSpacing: "-0.02em";
|
|
724
|
+
}];
|
|
725
|
+
readonly '4xl': readonly ["2.25rem", {
|
|
726
|
+
readonly lineHeight: "2.625rem";
|
|
727
|
+
readonly letterSpacing: "-0.025em";
|
|
728
|
+
}];
|
|
729
|
+
readonly '5xl': readonly ["3rem", {
|
|
730
|
+
readonly lineHeight: "3.25rem";
|
|
731
|
+
readonly letterSpacing: "-0.03em";
|
|
732
|
+
}];
|
|
733
|
+
readonly '6xl': readonly ["3.75rem", {
|
|
734
|
+
readonly lineHeight: "3.9rem";
|
|
735
|
+
readonly letterSpacing: "-0.035em";
|
|
736
|
+
}];
|
|
737
|
+
readonly '7xl': readonly ["4.5rem", {
|
|
738
|
+
readonly lineHeight: "4.6rem";
|
|
739
|
+
readonly letterSpacing: "-0.04em";
|
|
740
|
+
}];
|
|
741
|
+
};
|
|
742
|
+
fontWeight: {
|
|
743
|
+
readonly normal: "400";
|
|
744
|
+
readonly medium: "500";
|
|
745
|
+
readonly semibold: "600";
|
|
746
|
+
readonly bold: "700";
|
|
747
|
+
};
|
|
748
|
+
screens: {
|
|
749
|
+
readonly sm: "640px";
|
|
750
|
+
readonly md: "768px";
|
|
751
|
+
readonly lg: "1024px";
|
|
752
|
+
readonly xl: "1280px";
|
|
753
|
+
readonly '2xl': "1536px";
|
|
754
|
+
};
|
|
755
|
+
zIndex: {
|
|
756
|
+
readonly hide: "-1";
|
|
757
|
+
readonly base: "0";
|
|
758
|
+
readonly raised: "10";
|
|
759
|
+
readonly dropdown: "1000";
|
|
760
|
+
readonly sticky: "1100";
|
|
761
|
+
readonly overlay: "1200";
|
|
762
|
+
readonly modal: "1300";
|
|
763
|
+
readonly popover: "1400";
|
|
764
|
+
readonly toast: "1500";
|
|
765
|
+
readonly tooltip: "1600";
|
|
766
|
+
readonly max: "2147483647";
|
|
767
|
+
};
|
|
768
|
+
transitionDuration: {
|
|
769
|
+
[k: string]: "0.1s" | "0.2s" | "0.3s" | "0.45s" | "0.6s" | "0.9s" | "1.2s";
|
|
770
|
+
};
|
|
771
|
+
transitionTimingFunction: {
|
|
772
|
+
readonly linear: "linear";
|
|
773
|
+
readonly standard: "cubic-bezier(0.4, 0, 0.2, 1)";
|
|
774
|
+
readonly emphasized: "cubic-bezier(0.22, 1, 0.36, 1)";
|
|
775
|
+
readonly enter: "cubic-bezier(0, 0, 0.2, 1)";
|
|
776
|
+
readonly exit: "cubic-bezier(0.4, 0, 1, 1)";
|
|
777
|
+
readonly overshoot: "cubic-bezier(0.34, 1.56, 0.64, 1)";
|
|
778
|
+
readonly cinematic: "cubic-bezier(0.16, 1, 0.3, 1)";
|
|
779
|
+
};
|
|
780
|
+
colors: {
|
|
781
|
+
surface: {
|
|
782
|
+
canvas: string;
|
|
783
|
+
raised: string;
|
|
784
|
+
overlay: string;
|
|
785
|
+
sunken: string;
|
|
786
|
+
glass: string;
|
|
787
|
+
};
|
|
788
|
+
content: {
|
|
789
|
+
primary: string;
|
|
790
|
+
secondary: string;
|
|
791
|
+
tertiary: string;
|
|
792
|
+
disabled: string;
|
|
793
|
+
'on-accent': string;
|
|
794
|
+
inverse: string;
|
|
795
|
+
};
|
|
796
|
+
line: {
|
|
797
|
+
subtle: string;
|
|
798
|
+
DEFAULT: string;
|
|
799
|
+
strong: string;
|
|
800
|
+
focus: string;
|
|
801
|
+
};
|
|
802
|
+
accent: {
|
|
803
|
+
subtle: string;
|
|
804
|
+
muted: string;
|
|
805
|
+
DEFAULT: string;
|
|
806
|
+
hover: string;
|
|
807
|
+
active: string;
|
|
808
|
+
text: string;
|
|
809
|
+
};
|
|
810
|
+
};
|
|
811
|
+
};
|
|
812
|
+
};
|
|
813
|
+
};
|
|
814
|
+
|
|
815
|
+
export { CSS_PREFIX, type SemanticTokens, type ThemeName, type Tokens, applyTheme, blur, brand, breakpoint, dark, duration, easing, fontFamily, fontSize, fontWeight, generateCss, light, neutral, radius, resolveTheme, shadow, space, status, structuralVariables, tailwindPreset, themeStyle, themeVariables, themes, tokens, zIndex };
|