@tristan2828/ui-foundation 4.62.0 → 4.63.1
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/conventions/docs/design-language.md +140 -23
- package/dist/components/app/app-shell.js +28 -2
- package/dist/components/app/board.js +1 -1
- package/dist/components/app/data-table.js +1 -1
- package/dist/components/app/foundation-providers.d.ts +14 -1
- package/dist/components/app/foundation-providers.js +4 -3
- package/dist/components/app/module-card.js +1 -1
- package/dist/components/app/palette-provider.d.ts +14 -0
- package/dist/components/app/palette-provider.js +35 -0
- package/dist/components/app/widget-card.js +2 -2
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/badge.js +5 -2
- package/dist/components/ui/button.js +10 -10
- package/dist/components/ui/card.js +3 -3
- package/dist/components/ui/checkbox.js +1 -1
- package/dist/components/ui/combobox.js +1 -1
- package/dist/components/ui/dialog.js +1 -1
- package/dist/components/ui/input-group.js +1 -1
- package/dist/components/ui/input.js +1 -1
- package/dist/components/ui/progress.d.ts +7 -0
- package/dist/components/ui/progress.js +19 -0
- package/dist/components/ui/select.js +1 -1
- package/dist/components/ui/sheet.js +1 -1
- package/dist/components/ui/slider.d.ts +3 -0
- package/dist/components/ui/slider.js +12 -0
- package/dist/components/ui/textarea.js +1 -1
- package/dist/hooks/use-palette.d.ts +14 -0
- package/dist/hooks/use-palette.js +7 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/lib/palettes.d.ts +21 -0
- package/dist/lib/palettes.js +74 -0
- package/dist/testing/index.d.ts +14 -3
- package/dist/testing/index.js +44 -14
- package/package.json +1 -1
- package/styles/index.css +60 -0
- package/styles/theme.css +321 -11
- package/vite/index.d.ts +7 -1
- package/vite/pwa.js +21 -7
package/styles/theme.css
CHANGED
|
@@ -112,7 +112,97 @@
|
|
|
112
112
|
--category-12-400: oklch(0.648 0.232 337);
|
|
113
113
|
--blue-500: oklch(0.488 0.243 264.376);
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
/*
|
|
116
|
+
* Palette primitives (design-language.md "Palettes"). A palette is an
|
|
117
|
+
* app's own dark look: these four were chosen for the shared style
|
|
118
|
+
* guide, and an app names one (FoundationProviders' `palette`). Each is
|
|
119
|
+
* the guide's colours as written, with one change: Violet's text on its
|
|
120
|
+
* accent was #130925 (4.496:1, just under 4.5) and is #110823 (4.54:1).
|
|
121
|
+
* The semantic blocks under `.dark[data-palette]`, at the end of this
|
|
122
|
+
* file, map them onto the tokens components use. Ratios are against the
|
|
123
|
+
* palette's own background (bg), card and raised surfaces (WCAG 2.x,
|
|
124
|
+
* sRGB), listed 1 Indigo and Cyan / 2 Indigo and Rose / 3 Graphite and
|
|
125
|
+
* Periwinkle / 4 Violet:
|
|
126
|
+
*
|
|
127
|
+
* text on bg 15.0 / 15.3 / 15.0 / 15.0, on card 13.4 / 13.9 / 13.4 / 13.4
|
|
128
|
+
* dim on bg 7.47 / 7.42 / 7.54 / 7.47, on raised 5.87 / 6.06 / 5.79 / 5.87
|
|
129
|
+
* accent on bg 5.25 / 4.33 / 4.87 / 4.24, on card 4.68 / 3.94 / 4.32 / 3.78:
|
|
130
|
+
* never small text (2 and 4 fail); the ring and fills only
|
|
131
|
+
* on-accent on accent 5.49 / 4.51 / 5.28 / 4.54
|
|
132
|
+
* accent-light on bg 10.3 / 9.65 / 10.4 / 8.53, on card 9.16 / 8.77 / 9.19 / 7.61: links
|
|
133
|
+
* strong-border on bg 2.79 / 2.53 / 2.89 / 2.79: under 3:1, the guide's
|
|
134
|
+
* lightest grey, kept as designed (axe doesn't check borders)
|
|
135
|
+
* second on card 9.47 / 5.85 / 5.08 / 4.79
|
|
136
|
+
*/
|
|
137
|
+
--palette-indigo-cyan-background: #13161b;
|
|
138
|
+
--palette-indigo-cyan-panel: #1c2129;
|
|
139
|
+
--palette-indigo-cyan-raised: #252b35;
|
|
140
|
+
--palette-indigo-cyan-border: #38414d;
|
|
141
|
+
--palette-indigo-cyan-strong-border: #535f6f;
|
|
142
|
+
--palette-indigo-cyan-text: #e7eaee;
|
|
143
|
+
--palette-indigo-cyan-dim: #a0a7b1;
|
|
144
|
+
--palette-indigo-cyan-accent: #6682f5;
|
|
145
|
+
--palette-indigo-cyan-accent-light: #b2c1fa;
|
|
146
|
+
--palette-indigo-cyan-accent-deep: #224cf1;
|
|
147
|
+
--palette-indigo-cyan-on-accent: #090f25;
|
|
148
|
+
--palette-indigo-cyan-second: #6dd4ee;
|
|
149
|
+
|
|
150
|
+
--palette-indigo-rose-background: #101219;
|
|
151
|
+
--palette-indigo-rose-panel: #181c28;
|
|
152
|
+
--palette-indigo-rose-raised: #202534;
|
|
153
|
+
--palette-indigo-rose-border: #32394e;
|
|
154
|
+
--palette-indigo-rose-strong-border: #4c5570;
|
|
155
|
+
--palette-indigo-rose-text: #e6e8ef;
|
|
156
|
+
--palette-indigo-rose-dim: #9da3b4;
|
|
157
|
+
--palette-indigo-rose-accent: #6868f3;
|
|
158
|
+
--palette-indigo-rose-accent-light: #b4b4f9;
|
|
159
|
+
--palette-indigo-rose-accent-deep: #2626ed;
|
|
160
|
+
--palette-indigo-rose-on-accent: #090925;
|
|
161
|
+
--palette-indigo-rose-second: #ec6f8e;
|
|
162
|
+
|
|
163
|
+
--palette-graphite-periwinkle-background: #171717;
|
|
164
|
+
--palette-graphite-periwinkle-panel: #222222;
|
|
165
|
+
--palette-graphite-periwinkle-raised: #2d2d2d;
|
|
166
|
+
--palette-graphite-periwinkle-border: #424242;
|
|
167
|
+
--palette-graphite-periwinkle-strong-border: #616161;
|
|
168
|
+
--palette-graphite-periwinkle-text: #ebebeb;
|
|
169
|
+
--palette-graphite-periwinkle-dim: #a8a8a8;
|
|
170
|
+
--palette-graphite-periwinkle-accent: #7f75f0;
|
|
171
|
+
--palette-graphite-periwinkle-accent-light: #c3bff8;
|
|
172
|
+
--palette-graphite-periwinkle-accent-deep: #4435e9;
|
|
173
|
+
--palette-graphite-periwinkle-on-accent: #0b0925;
|
|
174
|
+
--palette-graphite-periwinkle-second: #a97bea;
|
|
175
|
+
|
|
176
|
+
--palette-violet-background: #13161b;
|
|
177
|
+
--palette-violet-panel: #1c2129;
|
|
178
|
+
--palette-violet-raised: #252b35;
|
|
179
|
+
--palette-violet-border: #38414d;
|
|
180
|
+
--palette-violet-strong-border: #535f6f;
|
|
181
|
+
--palette-violet-text: #e7eaee;
|
|
182
|
+
--palette-violet-dim: #a0a7b1;
|
|
183
|
+
--palette-violet-accent: #905ceb;
|
|
184
|
+
--palette-violet-accent-light: #c1a4f4;
|
|
185
|
+
--palette-violet-accent-deep: #651ce3;
|
|
186
|
+
--palette-violet-on-accent: #110823;
|
|
187
|
+
--palette-violet-second: #c363e4;
|
|
188
|
+
|
|
189
|
+
/*
|
|
190
|
+
* The status colours every palette shares, as TEXT shades (--*-text):
|
|
191
|
+
* soft badges, icons, coloured words. Never fills: white on the success
|
|
192
|
+
* shade measures 1.80, so solid fills keep the deeper -500/-700 shades
|
|
193
|
+
* above, with white text. On bg / card / raised, the lowest palette:
|
|
194
|
+
* success 9.95 / 8.83 / 7.64, warning 9.03 / 8.02 / 6.94,
|
|
195
|
+
* danger 6.12 / 5.44 / 4.70.
|
|
196
|
+
* Danger is a shade lighter than the guide's #dc726a, which measured
|
|
197
|
+
* 4.37 on Graphite's raised surface and 4.46 on an outline button's fill.
|
|
198
|
+
*/
|
|
199
|
+
--palette-success: #66d69a;
|
|
200
|
+
--palette-warning: #e0b152;
|
|
201
|
+
--palette-danger: #df7a72;
|
|
202
|
+
|
|
203
|
+
/* 9px (the shared style guide): buttons and cards on --radius, fields
|
|
204
|
+
on --radius-md (about 7px). */
|
|
205
|
+
--radius-base: 0.5625rem;
|
|
116
206
|
|
|
117
207
|
/*
|
|
118
208
|
* Typography roles (conventions/docs/design-language.md "Typography").
|
|
@@ -123,14 +213,17 @@
|
|
|
123
213
|
* The values are what the package and template already used, so moving
|
|
124
214
|
* onto a role changes nothing visible.
|
|
125
215
|
*/
|
|
126
|
-
--type-page-title-size: 1.
|
|
127
|
-
--type-page-title-leading: 1.
|
|
216
|
+
--type-page-title-size: 1.75rem; /* 28px, the shared style guide's */
|
|
217
|
+
--type-page-title-leading: 1.2;
|
|
128
218
|
--type-page-title-weight: 600;
|
|
129
219
|
--type-section-title-size: 1rem;
|
|
130
220
|
--type-section-title-leading: 1.5rem;
|
|
131
221
|
--type-section-title-weight: 600;
|
|
222
|
+
/* Headings draw in a little (the page and section titles, and written
|
|
223
|
+
text's # and ##); labels and body keep the font's own spacing. */
|
|
224
|
+
--type-heading-tracking: -0.02em;
|
|
132
225
|
--type-body-size: 0.875rem; /* text-sm: tables, forms, most UI text */
|
|
133
|
-
--type-body-leading: 1.
|
|
226
|
+
--type-body-leading: 1.5;
|
|
134
227
|
--type-body-weight: 400;
|
|
135
228
|
--type-label-size: 0.875rem; /* column headers, field labels */
|
|
136
229
|
--type-label-leading: 1.25rem;
|
|
@@ -166,8 +259,26 @@
|
|
|
166
259
|
* The default is what the table always had.
|
|
167
260
|
*/
|
|
168
261
|
--table-cell-px: 0.5rem;
|
|
169
|
-
|
|
170
|
-
|
|
262
|
+
/* Compact rows by default (the shared style guide, chosen from the
|
|
263
|
+
review screenshots on 2026-11-04): 4px around the line, a 32px
|
|
264
|
+
header. data-density="compact" keeps them so and tightens a hub's
|
|
265
|
+
cards; comfortable opens them up. */
|
|
266
|
+
--table-cell-py: 0.25rem;
|
|
267
|
+
--table-head-height: 2rem;
|
|
268
|
+
/*
|
|
269
|
+
* Glow (the shared style guide), drawn only under a palette (index.css's
|
|
270
|
+
* `palette:` variant and glow-edge): the accent as one soft layer, from
|
|
271
|
+
* --primary, so each palette's glow is its own accent.
|
|
272
|
+
* --primary-glow a primary button on hover, keyboard focus and press:
|
|
273
|
+
* 38px blur, 2px spread, 38%
|
|
274
|
+
* --edge-glow a hovered hub tile, widget or card: a softer halo
|
|
275
|
+
* beside its accent edge
|
|
276
|
+
* --thumb-glow a slider's thumb
|
|
277
|
+
*/
|
|
278
|
+
--primary-glow: 0 0 38px 2px color-mix(in srgb, var(--primary) 38%, transparent);
|
|
279
|
+
--edge-glow: 0 0 18px 0 color-mix(in srgb, var(--primary) 28%, transparent);
|
|
280
|
+
--thumb-glow: 0 0 10px 2px color-mix(in srgb, var(--primary) 50%, transparent);
|
|
281
|
+
|
|
171
282
|
/* The small size of Button and Toggle (and the calendar's weekdays):
|
|
172
283
|
between text-xs and text-sm, so it has a token of its own for the
|
|
173
284
|
large density to scale. */
|
|
@@ -258,6 +369,16 @@
|
|
|
258
369
|
--chart-3: var(--gray-600);
|
|
259
370
|
--chart-4: var(--gray-700);
|
|
260
371
|
--chart-5: var(--gray-900);
|
|
372
|
+
/* A palette's second colour (a neighbouring hue): a chart's fourth
|
|
373
|
+
series, anything that needs a colour beside the accent. Without a
|
|
374
|
+
palette it is a grey, as the charts are. */
|
|
375
|
+
--accent-second: var(--gray-700);
|
|
376
|
+
/* A card (the shared style guide): a soft shadow under its border, and
|
|
377
|
+
its header a tinted bar. The shadow is 30% in dark, where the guide
|
|
378
|
+
set it, and lighter on white. Text on the bar: foreground and muted
|
|
379
|
+
foreground as on --muted. */
|
|
380
|
+
--card-shadow: 0 6px 14px oklch(0 0 0 / 8%);
|
|
381
|
+
--card-header: color-mix(in srgb, var(--muted) 60%, var(--card));
|
|
261
382
|
--radius: var(--radius-base);
|
|
262
383
|
--sidebar: var(--gray-50);
|
|
263
384
|
--sidebar-foreground: var(--black);
|
|
@@ -270,7 +391,7 @@
|
|
|
270
391
|
}
|
|
271
392
|
|
|
272
393
|
[data-density="compact"] {
|
|
273
|
-
--table-cell-py: 0.25rem;
|
|
394
|
+
--table-cell-py: 0.25rem; /* the default's, since the default is compact */
|
|
274
395
|
--table-head-height: 2rem;
|
|
275
396
|
}
|
|
276
397
|
|
|
@@ -307,14 +428,12 @@
|
|
|
307
428
|
--text-xl: 1.5625rem; /* 20 → 25px */
|
|
308
429
|
--text-2xl: 1.875rem; /* 24 → 30px */
|
|
309
430
|
--control-text-sm: 1rem; /* 12.8 → 16px */
|
|
310
|
-
--radius: 0.
|
|
431
|
+
--radius: 0.6875rem; /* 9 → 11px, so larger controls keep their shape */
|
|
311
432
|
|
|
312
|
-
--type-page-title-size:
|
|
313
|
-
--type-page-title-leading: 2.125rem;
|
|
433
|
+
--type-page-title-size: 2.1875rem; /* 28 → 35px */
|
|
314
434
|
--type-section-title-size: 1.25rem;
|
|
315
435
|
--type-section-title-leading: 1.875rem;
|
|
316
436
|
--type-body-size: 1.125rem;
|
|
317
|
-
--type-body-leading: 1.625rem;
|
|
318
437
|
--type-label-size: 1.125rem;
|
|
319
438
|
--type-label-leading: 1.625rem;
|
|
320
439
|
--type-caption-size: 0.9375rem;
|
|
@@ -398,6 +517,9 @@
|
|
|
398
517
|
--chart-3: var(--gray-600);
|
|
399
518
|
--chart-4: var(--gray-700);
|
|
400
519
|
--chart-5: var(--gray-900);
|
|
520
|
+
--accent-second: var(--gray-700);
|
|
521
|
+
--card-shadow: 0 6px 14px oklch(0 0 0 / 30%);
|
|
522
|
+
--card-header: color-mix(in srgb, var(--muted) 60%, var(--card));
|
|
401
523
|
--sidebar: var(--gray-950);
|
|
402
524
|
--sidebar-foreground: var(--gray-50);
|
|
403
525
|
--sidebar-primary: var(--blue-500);
|
|
@@ -407,3 +529,191 @@
|
|
|
407
529
|
--sidebar-border: var(--white-a10);
|
|
408
530
|
--sidebar-ring: var(--gray-500);
|
|
409
531
|
}
|
|
532
|
+
|
|
533
|
+
/*
|
|
534
|
+
* Palettes (design-language.md "Palettes"): an app's own dark look.
|
|
535
|
+
* FoundationProviders' `palette` puts data-palette on <html> and forces
|
|
536
|
+
* the dark theme, so a block below always sits on top of .dark and sets
|
|
537
|
+
* only what differs from it. The solid fills (--destructive, --success,
|
|
538
|
+
* --warning, --info, each with white -foreground), --info-text, the
|
|
539
|
+
* highlight washes and the categorical slots stay .dark's.
|
|
540
|
+
*
|
|
541
|
+
* --ring is the accent (4.24 to 5.25 on the page), not the guide's
|
|
542
|
+
* accent deep (2.30 to 2.91, under the 3:1 a focus ring needs).
|
|
543
|
+
* --link is accent light: the accent fails 4.5 as small text on 2 and 4.
|
|
544
|
+
* --*-text are the shared status shades; the fills are unchanged.
|
|
545
|
+
* --sidebar-accent, the active and hovered item, is a soft accent tint
|
|
546
|
+
* on the panel (16%): text on it 10.8 / 11.6 / 10.9 / 11.2, dim 5.35
|
|
547
|
+
* at the least.
|
|
548
|
+
* Derived in .dark and resolved with these values, since both blocks
|
|
549
|
+
* apply to <html>: --table-stripe (dim on it 6.86 at the
|
|
550
|
+
* least), --table-highlight (dim 6.30), --heading-band (text 7.79).
|
|
551
|
+
* --rule is the strong border (2.53 to 2.89; .dark's was 2.54).
|
|
552
|
+
*
|
|
553
|
+
* Printed notes still print light: index.css's print override is more
|
|
554
|
+
* specific than these blocks (tests: entity-view-print.spec.ts).
|
|
555
|
+
*/
|
|
556
|
+
|
|
557
|
+
.dark[data-palette="indigo-cyan"] {
|
|
558
|
+
--background: var(--palette-indigo-cyan-background);
|
|
559
|
+
--foreground: var(--palette-indigo-cyan-text);
|
|
560
|
+
--card: var(--palette-indigo-cyan-panel);
|
|
561
|
+
--card-foreground: var(--palette-indigo-cyan-text);
|
|
562
|
+
--popover: var(--palette-indigo-cyan-panel);
|
|
563
|
+
--popover-foreground: var(--palette-indigo-cyan-text);
|
|
564
|
+
--primary: var(--palette-indigo-cyan-accent);
|
|
565
|
+
--primary-foreground: var(--palette-indigo-cyan-on-accent);
|
|
566
|
+
--secondary: var(--palette-indigo-cyan-raised);
|
|
567
|
+
--secondary-foreground: var(--palette-indigo-cyan-text);
|
|
568
|
+
--muted: var(--palette-indigo-cyan-raised);
|
|
569
|
+
--muted-foreground: var(--palette-indigo-cyan-dim);
|
|
570
|
+
--accent: var(--palette-indigo-cyan-raised);
|
|
571
|
+
--accent-foreground: var(--palette-indigo-cyan-text);
|
|
572
|
+
--accent-second: var(--palette-indigo-cyan-second);
|
|
573
|
+
--destructive-text: var(--palette-danger);
|
|
574
|
+
--success-text: var(--palette-success);
|
|
575
|
+
--warning-text: var(--palette-warning);
|
|
576
|
+
--link: var(--palette-indigo-cyan-accent-light);
|
|
577
|
+
--heading-bar: var(--palette-indigo-cyan-accent-light);
|
|
578
|
+
--rule: var(--palette-indigo-cyan-strong-border);
|
|
579
|
+
--table-highlight-muted-foreground: var(--palette-indigo-cyan-dim);
|
|
580
|
+
--border: var(--palette-indigo-cyan-border);
|
|
581
|
+
--input: var(--palette-indigo-cyan-strong-border);
|
|
582
|
+
--ring: var(--palette-indigo-cyan-accent);
|
|
583
|
+
--chart-1: var(--palette-indigo-cyan-accent-light);
|
|
584
|
+
--chart-2: var(--palette-indigo-cyan-accent);
|
|
585
|
+
--chart-3: var(--palette-indigo-cyan-accent-deep);
|
|
586
|
+
--chart-4: var(--palette-indigo-cyan-second);
|
|
587
|
+
--chart-5: var(--palette-indigo-cyan-border);
|
|
588
|
+
--sidebar: var(--palette-indigo-cyan-panel);
|
|
589
|
+
--sidebar-foreground: var(--palette-indigo-cyan-text);
|
|
590
|
+
--sidebar-primary: var(--palette-indigo-cyan-accent);
|
|
591
|
+
--sidebar-primary-foreground: var(--palette-indigo-cyan-on-accent);
|
|
592
|
+
--sidebar-accent: color-mix(in srgb, var(--palette-indigo-cyan-accent) 16%, var(--palette-indigo-cyan-panel));
|
|
593
|
+
--sidebar-accent-foreground: var(--palette-indigo-cyan-text);
|
|
594
|
+
--sidebar-border: var(--palette-indigo-cyan-border);
|
|
595
|
+
--sidebar-ring: var(--palette-indigo-cyan-accent);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.dark[data-palette="indigo-rose"] {
|
|
599
|
+
--background: var(--palette-indigo-rose-background);
|
|
600
|
+
--foreground: var(--palette-indigo-rose-text);
|
|
601
|
+
--card: var(--palette-indigo-rose-panel);
|
|
602
|
+
--card-foreground: var(--palette-indigo-rose-text);
|
|
603
|
+
--popover: var(--palette-indigo-rose-panel);
|
|
604
|
+
--popover-foreground: var(--palette-indigo-rose-text);
|
|
605
|
+
--primary: var(--palette-indigo-rose-accent);
|
|
606
|
+
--primary-foreground: var(--palette-indigo-rose-on-accent);
|
|
607
|
+
--secondary: var(--palette-indigo-rose-raised);
|
|
608
|
+
--secondary-foreground: var(--palette-indigo-rose-text);
|
|
609
|
+
--muted: var(--palette-indigo-rose-raised);
|
|
610
|
+
--muted-foreground: var(--palette-indigo-rose-dim);
|
|
611
|
+
--accent: var(--palette-indigo-rose-raised);
|
|
612
|
+
--accent-foreground: var(--palette-indigo-rose-text);
|
|
613
|
+
--accent-second: var(--palette-indigo-rose-second);
|
|
614
|
+
--destructive-text: var(--palette-danger);
|
|
615
|
+
--success-text: var(--palette-success);
|
|
616
|
+
--warning-text: var(--palette-warning);
|
|
617
|
+
--link: var(--palette-indigo-rose-accent-light);
|
|
618
|
+
--heading-bar: var(--palette-indigo-rose-accent-light);
|
|
619
|
+
--rule: var(--palette-indigo-rose-strong-border);
|
|
620
|
+
--table-highlight-muted-foreground: var(--palette-indigo-rose-dim);
|
|
621
|
+
--border: var(--palette-indigo-rose-border);
|
|
622
|
+
--input: var(--palette-indigo-rose-strong-border);
|
|
623
|
+
--ring: var(--palette-indigo-rose-accent);
|
|
624
|
+
--chart-1: var(--palette-indigo-rose-accent-light);
|
|
625
|
+
--chart-2: var(--palette-indigo-rose-accent);
|
|
626
|
+
--chart-3: var(--palette-indigo-rose-accent-deep);
|
|
627
|
+
--chart-4: var(--palette-indigo-rose-second);
|
|
628
|
+
--chart-5: var(--palette-indigo-rose-border);
|
|
629
|
+
--sidebar: var(--palette-indigo-rose-panel);
|
|
630
|
+
--sidebar-foreground: var(--palette-indigo-rose-text);
|
|
631
|
+
--sidebar-primary: var(--palette-indigo-rose-accent);
|
|
632
|
+
--sidebar-primary-foreground: var(--palette-indigo-rose-on-accent);
|
|
633
|
+
--sidebar-accent: color-mix(in srgb, var(--palette-indigo-rose-accent) 16%, var(--palette-indigo-rose-panel));
|
|
634
|
+
--sidebar-accent-foreground: var(--palette-indigo-rose-text);
|
|
635
|
+
--sidebar-border: var(--palette-indigo-rose-border);
|
|
636
|
+
--sidebar-ring: var(--palette-indigo-rose-accent);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.dark[data-palette="graphite-periwinkle"] {
|
|
640
|
+
--background: var(--palette-graphite-periwinkle-background);
|
|
641
|
+
--foreground: var(--palette-graphite-periwinkle-text);
|
|
642
|
+
--card: var(--palette-graphite-periwinkle-panel);
|
|
643
|
+
--card-foreground: var(--palette-graphite-periwinkle-text);
|
|
644
|
+
--popover: var(--palette-graphite-periwinkle-panel);
|
|
645
|
+
--popover-foreground: var(--palette-graphite-periwinkle-text);
|
|
646
|
+
--primary: var(--palette-graphite-periwinkle-accent);
|
|
647
|
+
--primary-foreground: var(--palette-graphite-periwinkle-on-accent);
|
|
648
|
+
--secondary: var(--palette-graphite-periwinkle-raised);
|
|
649
|
+
--secondary-foreground: var(--palette-graphite-periwinkle-text);
|
|
650
|
+
--muted: var(--palette-graphite-periwinkle-raised);
|
|
651
|
+
--muted-foreground: var(--palette-graphite-periwinkle-dim);
|
|
652
|
+
--accent: var(--palette-graphite-periwinkle-raised);
|
|
653
|
+
--accent-foreground: var(--palette-graphite-periwinkle-text);
|
|
654
|
+
--accent-second: var(--palette-graphite-periwinkle-second);
|
|
655
|
+
--destructive-text: var(--palette-danger);
|
|
656
|
+
--success-text: var(--palette-success);
|
|
657
|
+
--warning-text: var(--palette-warning);
|
|
658
|
+
--link: var(--palette-graphite-periwinkle-accent-light);
|
|
659
|
+
--heading-bar: var(--palette-graphite-periwinkle-accent-light);
|
|
660
|
+
--rule: var(--palette-graphite-periwinkle-strong-border);
|
|
661
|
+
--table-highlight-muted-foreground: var(--palette-graphite-periwinkle-dim);
|
|
662
|
+
--border: var(--palette-graphite-periwinkle-border);
|
|
663
|
+
--input: var(--palette-graphite-periwinkle-strong-border);
|
|
664
|
+
--ring: var(--palette-graphite-periwinkle-accent);
|
|
665
|
+
--chart-1: var(--palette-graphite-periwinkle-accent-light);
|
|
666
|
+
--chart-2: var(--palette-graphite-periwinkle-accent);
|
|
667
|
+
--chart-3: var(--palette-graphite-periwinkle-accent-deep);
|
|
668
|
+
--chart-4: var(--palette-graphite-periwinkle-second);
|
|
669
|
+
--chart-5: var(--palette-graphite-periwinkle-border);
|
|
670
|
+
--sidebar: var(--palette-graphite-periwinkle-panel);
|
|
671
|
+
--sidebar-foreground: var(--palette-graphite-periwinkle-text);
|
|
672
|
+
--sidebar-primary: var(--palette-graphite-periwinkle-accent);
|
|
673
|
+
--sidebar-primary-foreground: var(--palette-graphite-periwinkle-on-accent);
|
|
674
|
+
--sidebar-accent: color-mix(in srgb, var(--palette-graphite-periwinkle-accent) 16%, var(--palette-graphite-periwinkle-panel));
|
|
675
|
+
--sidebar-accent-foreground: var(--palette-graphite-periwinkle-text);
|
|
676
|
+
--sidebar-border: var(--palette-graphite-periwinkle-border);
|
|
677
|
+
--sidebar-ring: var(--palette-graphite-periwinkle-accent);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
.dark[data-palette="violet"] {
|
|
681
|
+
--background: var(--palette-violet-background);
|
|
682
|
+
--foreground: var(--palette-violet-text);
|
|
683
|
+
--card: var(--palette-violet-panel);
|
|
684
|
+
--card-foreground: var(--palette-violet-text);
|
|
685
|
+
--popover: var(--palette-violet-panel);
|
|
686
|
+
--popover-foreground: var(--palette-violet-text);
|
|
687
|
+
--primary: var(--palette-violet-accent);
|
|
688
|
+
--primary-foreground: var(--palette-violet-on-accent);
|
|
689
|
+
--secondary: var(--palette-violet-raised);
|
|
690
|
+
--secondary-foreground: var(--palette-violet-text);
|
|
691
|
+
--muted: var(--palette-violet-raised);
|
|
692
|
+
--muted-foreground: var(--palette-violet-dim);
|
|
693
|
+
--accent: var(--palette-violet-raised);
|
|
694
|
+
--accent-foreground: var(--palette-violet-text);
|
|
695
|
+
--accent-second: var(--palette-violet-second);
|
|
696
|
+
--destructive-text: var(--palette-danger);
|
|
697
|
+
--success-text: var(--palette-success);
|
|
698
|
+
--warning-text: var(--palette-warning);
|
|
699
|
+
--link: var(--palette-violet-accent-light);
|
|
700
|
+
--heading-bar: var(--palette-violet-accent-light);
|
|
701
|
+
--rule: var(--palette-violet-strong-border);
|
|
702
|
+
--table-highlight-muted-foreground: var(--palette-violet-dim);
|
|
703
|
+
--border: var(--palette-violet-border);
|
|
704
|
+
--input: var(--palette-violet-strong-border);
|
|
705
|
+
--ring: var(--palette-violet-accent);
|
|
706
|
+
--chart-1: var(--palette-violet-accent-light);
|
|
707
|
+
--chart-2: var(--palette-violet-accent);
|
|
708
|
+
--chart-3: var(--palette-violet-accent-deep);
|
|
709
|
+
--chart-4: var(--palette-violet-second);
|
|
710
|
+
--chart-5: var(--palette-violet-border);
|
|
711
|
+
--sidebar: var(--palette-violet-panel);
|
|
712
|
+
--sidebar-foreground: var(--palette-violet-text);
|
|
713
|
+
--sidebar-primary: var(--palette-violet-accent);
|
|
714
|
+
--sidebar-primary-foreground: var(--palette-violet-on-accent);
|
|
715
|
+
--sidebar-accent: color-mix(in srgb, var(--palette-violet-accent) 16%, var(--palette-violet-panel));
|
|
716
|
+
--sidebar-accent-foreground: var(--palette-violet-text);
|
|
717
|
+
--sidebar-border: var(--palette-violet-border);
|
|
718
|
+
--sidebar-ring: var(--palette-violet-accent);
|
|
719
|
+
}
|
package/vite/index.d.ts
CHANGED
|
@@ -31,7 +31,13 @@ export type PwaOptions = {
|
|
|
31
31
|
/** A shorter one for under the icon. Defaults to `name`; its first letter is the SVG icon's. */
|
|
32
32
|
shortName?: string
|
|
33
33
|
description?: string
|
|
34
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* The app's palette, the same one FoundationProviders names: the colours
|
|
36
|
+
* below default to its accent, its text on the accent and its background
|
|
37
|
+
* instead of the light theme's.
|
|
38
|
+
*/
|
|
39
|
+
palette?: 'indigo-cyan' | 'indigo-rose' | 'graphite-periwinkle' | 'violet'
|
|
40
|
+
/** `#rrggbb`. Defaults to the package's `--primary` token (or the palette's accent). */
|
|
35
41
|
themeColor?: string
|
|
36
42
|
/** The letter's colour on the SVG icon, `#rrggbb`. Defaults to `--primary-foreground`. */
|
|
37
43
|
themeForegroundColor?: string
|
package/vite/pwa.js
CHANGED
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
//
|
|
19
19
|
// Colours default to the package's tokens (styles/theme.css: --primary,
|
|
20
20
|
// --primary-foreground, --background), converted to hex as a manifest
|
|
21
|
-
// needs
|
|
21
|
+
// needs, or to its palette's with `palette` (the one FoundationProviders
|
|
22
|
+
// names). An app that changed its tokens passes its own.
|
|
22
23
|
|
|
23
24
|
import fs from 'node:fs'
|
|
24
25
|
import path from 'node:path'
|
|
@@ -34,7 +35,10 @@ const HEX = /^#[0-9a-f]{6}$/i
|
|
|
34
35
|
|
|
35
36
|
/** The value of `--name` in theme.css's :root block, var() followed. */
|
|
36
37
|
export function themeToken(css, name, seen = new Set()) {
|
|
37
|
-
|
|
38
|
+
// The first :root block, to its closing brace: a comment inside it may
|
|
39
|
+
// name other selectors (.dark, a palette's), so it can't end at one.
|
|
40
|
+
const start = css.indexOf(':root {')
|
|
41
|
+
const root = css.slice(start, css.indexOf('\n}', start))
|
|
38
42
|
const match = new RegExp(`--${name}:\\s*([^;]+);`).exec(root)
|
|
39
43
|
if (!match) throw new Error(`pwa: no --${name} in the theme.`)
|
|
40
44
|
const value = match[1].trim()
|
|
@@ -71,12 +75,22 @@ export function oklchToHex(value) {
|
|
|
71
75
|
return `#${linear.map((x) => toByte(x).toString(16).padStart(2, '0')).join('')}`
|
|
72
76
|
}
|
|
73
77
|
|
|
74
|
-
|
|
78
|
+
// A palette's own colours for each token pwa() reads (styles/theme.css's
|
|
79
|
+
// --palette-<name>-* primitives, already #rrggbb).
|
|
80
|
+
const PALETTE_PARTS = { primary: 'accent', 'primary-foreground': 'on-accent', background: 'background' }
|
|
81
|
+
|
|
82
|
+
function colour(value, token, palette) {
|
|
75
83
|
if (value !== undefined) {
|
|
76
84
|
if (!HEX.test(value)) throw new Error(`pwa: ${token} must be #rrggbb, not ${value}.`)
|
|
77
85
|
return value.toLowerCase()
|
|
78
86
|
}
|
|
79
|
-
|
|
87
|
+
const css = fs.readFileSync(THEME_CSS, 'utf8')
|
|
88
|
+
if (palette !== undefined) {
|
|
89
|
+
const hex = themeToken(css, `palette-${palette}-${PALETTE_PARTS[token]}`)
|
|
90
|
+
if (!HEX.test(hex)) throw new Error(`pwa: no palette "${palette}" in the theme.`)
|
|
91
|
+
return hex.toLowerCase()
|
|
92
|
+
}
|
|
93
|
+
return oklchToHex(themeToken(css, token))
|
|
80
94
|
}
|
|
81
95
|
|
|
82
96
|
// ---------------------------------------------------------------- icons
|
|
@@ -145,9 +159,9 @@ export function pwaFiles(options, base = '/', root = process.cwd()) {
|
|
|
145
159
|
if (!options?.name?.trim()) throw new Error('pwa: `name` is required (the app as the Home Screen names it).')
|
|
146
160
|
const name = options.name.trim()
|
|
147
161
|
const shortName = options.shortName?.trim() || name
|
|
148
|
-
const theme = colour(options.themeColor, 'primary')
|
|
149
|
-
const onTheme = colour(options.themeForegroundColor, 'primary-foreground')
|
|
150
|
-
const background = colour(options.backgroundColor, 'background')
|
|
162
|
+
const theme = colour(options.themeColor, 'primary', options.palette)
|
|
163
|
+
const onTheme = colour(options.themeForegroundColor, 'primary-foreground', options.palette)
|
|
164
|
+
const background = colour(options.backgroundColor, 'background', options.palette)
|
|
151
165
|
const at = (file) => `${base}${file}`
|
|
152
166
|
|
|
153
167
|
/** @type {Map<string, { type: string, source: string | Buffer }>} */
|