@lyeve-labs/ui-kit 0.31.0 → 0.32.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 +9 -9
- package/dist/components/AccordionItem.svelte +1 -1
- package/dist/components/AccountMenu.svelte +2 -2
- package/dist/components/AccountMenu.svelte.d.ts +1 -1
- package/dist/components/Alert.svelte +2 -2
- package/dist/components/Alert.svelte.d.ts +1 -1
- package/dist/components/AppShell.svelte +7 -7
- package/dist/components/AppShell.svelte.d.ts +2 -2
- package/dist/components/AuthShell.svelte +1 -1
- package/dist/components/AuthShell.svelte.d.ts +1 -1
- package/dist/components/Autocomplete.svelte +1 -1
- package/dist/components/Badge.svelte +2 -2
- package/dist/components/Banner.svelte +1 -1
- package/dist/components/Banner.svelte.d.ts +1 -1
- package/dist/components/Button.svelte +5 -5
- package/dist/components/Button.svelte.d.ts +1 -1
- package/dist/components/Card.svelte +2 -2
- package/dist/components/Checkbox.svelte +3 -3
- package/dist/components/CheckoutSteps.svelte +54 -0
- package/dist/components/CheckoutSteps.svelte.d.ts +12 -0
- package/dist/components/Collapsible.svelte +1 -1
- package/dist/components/Collapsible.svelte.d.ts +1 -1
- package/dist/components/CopyField.svelte +2 -2
- package/dist/components/Field.svelte +1 -1
- package/dist/components/Field.svelte.d.ts +1 -1
- package/dist/components/FileInput.svelte +1 -1
- package/dist/components/FormMessage.svelte +4 -4
- package/dist/components/Logo.svelte +1 -1
- package/dist/components/Logo.svelte.d.ts +1 -1
- package/dist/components/MultiSelect.svelte +1 -1
- package/dist/components/PageHeader.svelte +2 -2
- package/dist/components/PageShell.svelte +4 -4
- package/dist/components/PageShell.svelte.d.ts +4 -4
- package/dist/components/Pagination.svelte +2 -2
- package/dist/components/Panel.svelte +1 -1
- package/dist/components/Panel.svelte.d.ts +1 -1
- package/dist/components/PasswordInput.svelte +5 -2
- package/dist/components/PluginCart.svelte +339 -0
- package/dist/components/PluginCart.svelte.d.ts +45 -0
- package/dist/components/Radio.svelte +2 -2
- package/dist/components/SearchInput.svelte +5 -4
- package/dist/components/SegmentedControl.svelte +4 -4
- package/dist/components/SegmentedControl.svelte.d.ts +2 -2
- package/dist/components/Select.svelte +5 -5
- package/dist/components/Select.svelte.d.ts +4 -4
- package/dist/components/SidebarNav.svelte +5 -5
- package/dist/components/Stat.svelte +1 -1
- package/dist/components/Stat.svelte.d.ts +1 -1
- package/dist/components/Table.svelte +4 -4
- package/dist/components/Tabs.svelte +2 -2
- package/dist/components/ThemeToggle.svelte +1 -1
- package/dist/components/TimePicker.svelte +2 -2
- package/dist/components/Toggle.svelte +3 -3
- package/dist/components/Toolbar.svelte +1 -1
- package/dist/components/Toolbar.svelte.d.ts +1 -1
- package/dist/components/TreeView.svelte +1 -1
- package/dist/components/dialog/Dialog.svelte +1 -1
- package/dist/components/dialog/DialogContainer.svelte +1 -1
- package/dist/components/dialog/dialog-manager.svelte.d.ts +3 -3
- package/dist/components/dialog/dialog-manager.svelte.js +7 -7
- package/dist/components/dialog/types.d.ts +3 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +8 -5
- package/dist/internal/calendar.d.ts +1 -1
- package/dist/internal/calendar.js +2 -2
- package/dist/internal/choice.d.ts +6 -6
- package/dist/internal/choice.js +6 -6
- package/dist/internal/copy.svelte.d.ts +2 -2
- package/dist/internal/copy.svelte.js +2 -2
- package/dist/internal/field.d.ts +11 -11
- package/dist/internal/field.js +12 -12
- package/dist/internal/filter.d.ts +3 -3
- package/dist/internal/filter.js +3 -3
- package/dist/internal/href.d.ts +1 -1
- package/dist/internal/href.js +1 -1
- package/dist/internal/layout.d.ts +7 -7
- package/dist/internal/layout.js +7 -7
- package/dist/internal/listbox.svelte.d.ts +1 -1
- package/dist/internal/listbox.svelte.js +3 -3
- package/dist/internal/nav-expansion.svelte.d.ts +1 -1
- package/dist/internal/nav-expansion.svelte.js +2 -2
- package/dist/internal/nav-tree.d.ts +3 -3
- package/dist/internal/nav-tree.js +3 -3
- package/dist/internal/number.d.ts +1 -1
- package/dist/internal/number.js +1 -1
- package/dist/internal/overlay.d.ts +3 -3
- package/dist/internal/overlay.js +3 -3
- package/dist/internal/panel.d.ts +5 -5
- package/dist/internal/panel.js +5 -5
- package/dist/internal/pricing.d.ts +110 -0
- package/dist/internal/pricing.js +77 -0
- package/dist/internal/rollup.d.ts +3 -3
- package/dist/internal/rollup.js +3 -3
- package/dist/internal/scroll-edges.d.ts +4 -4
- package/dist/internal/scroll-edges.js +5 -5
- package/dist/internal/time.d.ts +3 -3
- package/dist/internal/time.js +3 -3
- package/dist/internal/tone.d.ts +3 -3
- package/dist/internal/tone.js +3 -3
- package/dist/internal/touch.d.ts +1 -1
- package/dist/internal/touch.js +1 -1
- package/dist/internal/tree.d.ts +2 -2
- package/dist/internal/tree.js +2 -2
- package/dist/motion.d.ts +3 -3
- package/dist/motion.js +4 -4
- package/dist/stores/toast.svelte.d.ts +1 -1
- package/dist/styles/theme.css +45 -45
- package/dist/utils/cn.d.ts +1 -1
- package/dist/utils/theme.d.ts +6 -6
- package/dist/utils/theme.js +10 -10
- package/package.json +1 -1
- package/src/lib/styles/theme.css +45 -45
package/dist/styles/theme.css
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* @lyeve-labs/ui-kit
|
|
2
|
+
* @lyeve-labs/ui-kit: theme tokens
|
|
3
3
|
*
|
|
4
4
|
* A single CSS file imported once at the top of your app's root stylesheet.
|
|
5
|
-
* Declares two palettes
|
|
5
|
+
* Declares two palettes, Soft Dark (default) and Soft Light, built from
|
|
6
6
|
* the LyEve brand guideline (Ink #0B1422 + Cyan #00D4FF) and exposes them
|
|
7
7
|
* as Tailwind v4 `@theme` tokens.
|
|
8
8
|
*
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
--color-line-strong: #616d80;
|
|
45
45
|
--color-fg: #e6e8ee;
|
|
46
46
|
--color-muted: #9aa1ad;
|
|
47
|
-
/* #525866 failed WCAG AA against surface/ink (~2.5:1)
|
|
47
|
+
/* #525866 failed WCAG AA against surface/ink (~2.5:1). Every caption and
|
|
48
48
|
* metadata label uses faint, so one token fix clears the systemic
|
|
49
49
|
* violation. #8b94a7 sits at ~5.6:1 on surface and ~5.9:1 on ink. */
|
|
50
50
|
--color-faint: #8b94a7;
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
* tokens because the brand ramp above is tuned for text contrast: in the
|
|
62
62
|
* light theme it darkens to #005a77 and brand-light sits below brand, so a
|
|
63
63
|
* mark painted from it inverts its lighting. A logotype is exempt from the
|
|
64
|
-
* contrast floor, so these keep the published
|
|
64
|
+
* contrast floor, so these keep the published colors instead. */
|
|
65
65
|
--color-mark-ink: #ffffff;
|
|
66
66
|
--color-mark-foot: #9aa1ad;
|
|
67
67
|
--color-mark-step: #c5cad3;
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
* cannot work as a foreground on a dark surface.
|
|
80
80
|
*
|
|
81
81
|
* One token serves both roles because it inverts with `ink`. As text on a
|
|
82
|
-
* dark surface #f87171 reads 6.30:1
|
|
82
|
+
* dark surface #f87171 reads 6.30:1. As the fill behind a `text-ink` label
|
|
83
83
|
* on a filled destructive button it reads 6.67:1. The light palette does
|
|
84
84
|
* the same in reverse with a dark red and a near-white ink. */
|
|
85
85
|
--color-danger: #f87171;
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
--radius-xl: 16px;
|
|
93
93
|
--radius-2xl: 24px;
|
|
94
94
|
|
|
95
|
-
/* -- Elevation
|
|
95
|
+
/* -- Elevation: the stacking order of everything that floats --- *
|
|
96
96
|
* Every floating surface in the kit carried a bare z-50, so which
|
|
97
97
|
* one won was decided by document order: a Dropdown opened after a
|
|
98
98
|
* Modal painted over it, and the same two in the other order did
|
|
@@ -123,16 +123,16 @@
|
|
|
123
123
|
--z-index-dropdown: 100; /* a panel anchored to its trigger */
|
|
124
124
|
--z-index-overlay: 200; /* the scrim behind a drawer or modal */
|
|
125
125
|
--z-index-drawer: 300; /* a panel docked to a viewport edge */
|
|
126
|
-
--z-index-modal: 400; /* a
|
|
126
|
+
--z-index-modal: 400; /* a centered dialog, and the stack */
|
|
127
127
|
--z-index-tooltip: 500; /* a label attached to a control */
|
|
128
128
|
--z-index-toast: 600; /* transient status */
|
|
129
129
|
--z-index-skip-link: 700; /* the first tab stop in the document */
|
|
130
130
|
|
|
131
|
-
/* -- Motion
|
|
131
|
+
/* -- Motion: four durations, three curves, one rule for exits -- *
|
|
132
132
|
* Named for what they are used for, so the choice is made by
|
|
133
133
|
* reading the name:
|
|
134
134
|
*
|
|
135
|
-
* fast a state change in place:
|
|
135
|
+
* fast a state change in place: color, opacity, border,
|
|
136
136
|
* shadow, focus
|
|
137
137
|
* base movement in place (a knob, a chevron, a collapse, a
|
|
138
138
|
* tab indicator) and a small surface arriving (menu,
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
* move changing in place
|
|
146
146
|
*
|
|
147
147
|
* An exit runs one rung faster than its entrance and on exit:
|
|
148
|
-
* slow in, base out
|
|
148
|
+
* slow in, base out. Base in, fast out. Entrances and exits move
|
|
149
149
|
* only opacity and transform.
|
|
150
150
|
*
|
|
151
151
|
* Tailwind builds no utility from a --duration-* token: there is
|
|
@@ -161,8 +161,8 @@
|
|
|
161
161
|
* wrote `duration-150` fifty times to say the same thing.
|
|
162
162
|
*
|
|
163
163
|
* The reduced-motion block at the foot of this file overrides
|
|
164
|
-
* every one of them and stays the authority on whether they run
|
|
165
|
-
*
|
|
164
|
+
* every one of them and stays the authority on whether they run.
|
|
165
|
+
* The Svelte presets in motion.ts honor the same preference for
|
|
166
166
|
* the entrances and exits that run outside CSS. */
|
|
167
167
|
--duration-fast: 120ms;
|
|
168
168
|
--duration-base: 200ms;
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
|
|
179
179
|
/* The one entrance that is a CSS animation. A panel inside <details> is
|
|
180
180
|
* shown and removed by the browser, so a Svelte transition never sees it
|
|
181
|
-
* leave
|
|
181
|
+
* leave. It plays this on the way in and nothing on the way out. Every
|
|
182
182
|
* other surface enters and leaves through the presets in motion.ts. */
|
|
183
183
|
--animate-popover-in: popover-in var(--duration-base) var(--ease-enter);
|
|
184
184
|
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
--tracking-h2: -0.02em;
|
|
224
224
|
--tracking-h3: -0.015em;
|
|
225
225
|
|
|
226
|
-
/* -- Typography
|
|
226
|
+
/* -- Typography: console type scale --------------------------- *
|
|
227
227
|
* Token Size Line Where it renders *
|
|
228
228
|
* text-xs 12px 16px labels, table heads, metadata, hints*
|
|
229
229
|
* text-sm 14px 20px body copy and every control *
|
|
@@ -259,7 +259,7 @@
|
|
|
259
259
|
*
|
|
260
260
|
* A step is declared with its leading, because a --text-* token
|
|
261
261
|
* sets font-size and nothing else. Only the six steps the kit
|
|
262
|
-
* actually renders are declared
|
|
262
|
+
* actually renders are declared. The larger ones a marketing
|
|
263
263
|
* page reaches for stay as Tailwind ships them. */
|
|
264
264
|
--text-xs: 0.75rem; /* 12px */
|
|
265
265
|
--text-xs--line-height: calc(1 / 0.75); /* 16px */
|
|
@@ -277,32 +277,32 @@
|
|
|
277
277
|
/* ── Spacing grid · 4px base (semantic shortcuts) ────────────── *
|
|
278
278
|
* Tailwind's default 0.25rem (4px) grid is unchanged. *
|
|
279
279
|
* These tokens add named slots for common component spacing. */
|
|
280
|
-
--spacing-page-x: 1.5rem; /* 24px
|
|
281
|
-
--spacing-page-y: 1.5rem; /* 24px
|
|
282
|
-
* measured renders an asymmetric gutter
|
|
280
|
+
--spacing-page-x: 1.5rem; /* 24px: page horizontal gutter */
|
|
281
|
+
--spacing-page-y: 1.5rem; /* 24px: page vertical gutter. Equal to page-x because no page
|
|
282
|
+
* measured renders an asymmetric gutter. The two names stay
|
|
283
283
|
* separate so one axis can move without dragging the other. */
|
|
284
|
-
--spacing-card: 1.25rem; /* 20px
|
|
285
|
-
* surfaces in use
|
|
286
|
-
--spacing-card-sm: 1rem; /* 16px
|
|
287
|
-
--spacing-section: 2rem; /* 32px
|
|
284
|
+
--spacing-card: 1.25rem; /* 20px: card inner padding. 24px matched none of the card
|
|
285
|
+
* surfaces in use. 20px is their measured mode and Card's own md. */
|
|
286
|
+
--spacing-card-sm: 1rem; /* 16px: compact card padding */
|
|
287
|
+
--spacing-section: 2rem; /* 32px: section gap. 48px matched nothing anywhere. 32px is the
|
|
288
288
|
* gap the pages that set one already use, and PageHeader's own. */
|
|
289
|
-
--spacing-input-x: 0.75rem; /* 12px
|
|
289
|
+
--spacing-input-x: 0.75rem; /* 12px: input horizontal padding */
|
|
290
290
|
--spacing-input-y: 0.5rem; /* 8px - input vertical padding */
|
|
291
|
-
/* 38px
|
|
291
|
+
/* 38px: the height of every single-line control. Stated once so an Input,
|
|
292
292
|
* a Select and a NumberInput sitting in the same row line up. Derived from
|
|
293
293
|
* the 13px/1.25 control text plus input-y padding and a 1px border. Under a
|
|
294
|
-
* coarse pointer it is 44px
|
|
294
|
+
* coarse pointer it is 44px. See the touch-target block below the palette. */
|
|
295
295
|
--spacing-control: 2.375rem;
|
|
296
|
-
--spacing-panel-max: 15rem; /* 240px
|
|
297
|
-
/* 56px
|
|
296
|
+
--spacing-panel-max: 15rem; /* 240px: the scroll cap on a floating option list */
|
|
297
|
+
/* 56px: the app header bar, and the sidebar's brand row above the nav.
|
|
298
298
|
* One token, because the two sit side by side across the top of every
|
|
299
299
|
* authed screen and a 4px disagreement between them reads as a broken
|
|
300
300
|
* seam. Three apps each picked their own height before this existed. */
|
|
301
301
|
--spacing-header: 3.5rem;
|
|
302
|
-
--spacing-nav-indent: 0.875rem; /* 14px
|
|
303
|
-
--spacing-nav-rail: 3.5rem; /* 56px
|
|
304
|
-
--spacing-sidebar: 14rem; /* 224px
|
|
305
|
-
--spacing-stack: 1rem; /* 16px
|
|
302
|
+
--spacing-nav-indent: 0.875rem; /* 14px: one level of sidebar nesting */
|
|
303
|
+
--spacing-nav-rail: 3.5rem; /* 56px: the collapsed icon rail */
|
|
304
|
+
--spacing-sidebar: 14rem; /* 224px: the expanded sidebar */
|
|
305
|
+
--spacing-stack: 1rem; /* 16px: default vertical stack gap */
|
|
306
306
|
--spacing-inline: 0.5rem; /* 8px - default inline gap */
|
|
307
307
|
|
|
308
308
|
/* ── Widths · how much room a surface is allowed to take ───── *
|
|
@@ -317,8 +317,8 @@
|
|
|
317
317
|
* drawers asked for the widest rung there was, which is what a *
|
|
318
318
|
* ladder that stops too early looks like from the outside. */
|
|
319
319
|
--container-page-narrow: 56rem; /* 896px - one column: a form, a settings pane */
|
|
320
|
-
--container-page-default: 72rem; /* 1152px
|
|
321
|
-
--container-page-wide: 96rem; /* 1536px
|
|
320
|
+
--container-page-default: 72rem; /* 1152px: a page of stacked cards */
|
|
321
|
+
--container-page-wide: 96rem; /* 1536px: a data page whose table needs the room */
|
|
322
322
|
|
|
323
323
|
/* One ladder for every surface lifted off the page, so a drawer and
|
|
324
324
|
* a modal opened from the same screen are the same size. Each rung
|
|
@@ -328,7 +328,7 @@
|
|
|
328
328
|
--container-overlay-md: 36rem; /* 576px - up to four fields */
|
|
329
329
|
--container-overlay-lg: 44rem; /* 704px - a form with paired fields */
|
|
330
330
|
--container-overlay-xl: 56rem; /* 896px - a form beside a preview */
|
|
331
|
-
--container-overlay-full: 68rem; /* 1088px
|
|
331
|
+
--container-overlay-full: 68rem; /* 1088px: a table inside a dialog */
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
/*
|
|
@@ -350,13 +350,13 @@
|
|
|
350
350
|
*
|
|
351
351
|
* `hit-area` does not move the visual. A switch, a checkbox, a breadcrumb, a
|
|
352
352
|
* pager button, a close cross and an icon inside an input are drawn small on
|
|
353
|
-
* purpose and grown to 44px would push their
|
|
354
|
-
* draws an invisible box
|
|
353
|
+
* purpose and grown to 44px would push their neighbors around. Each one
|
|
354
|
+
* draws an invisible box centered on itself that is never smaller than the
|
|
355
355
|
* control size, and a tap on the box lands on the control. The element must
|
|
356
356
|
* be positioned (`relative`, or `absolute` where it already is) for the box
|
|
357
|
-
* to
|
|
357
|
+
* to center on it. The utility does not set position itself, because a
|
|
358
358
|
* position it set would fight the `absolute` an input's clear button relies
|
|
359
|
-
* on. Two
|
|
359
|
+
* on. Two neighbors' boxes may overlap. The later one in document order
|
|
360
360
|
* wins the overlap, which is the spacing exception SC 2.5.8 allows for.
|
|
361
361
|
*/
|
|
362
362
|
@custom-variant coarse (@media (pointer: coarse));
|
|
@@ -392,7 +392,7 @@ html[data-theme='light'] {
|
|
|
392
392
|
--color-line-strong: #767d8e;
|
|
393
393
|
--color-fg: #111827;
|
|
394
394
|
--color-muted: #525866;
|
|
395
|
-
/* Every value below is the lightest
|
|
395
|
+
/* Every value below is the lightest color on its own hue that clears
|
|
396
396
|
* 4.5:1 against the worst background the kit actually paints it on. That
|
|
397
397
|
* worst case is rarely the bare canvas: status text and brand chips sit
|
|
398
398
|
* inside a tint of their own token (bg-warn/10 text-warn), and the tint
|
|
@@ -425,7 +425,7 @@ html[data-theme='light'] {
|
|
|
425
425
|
/*
|
|
426
426
|
* A forced-colors scheme repaints the page but not a fill named in hex, so the
|
|
427
427
|
* mark's white column vanished on a white high-contrast canvas. Its neutral
|
|
428
|
-
* faces take the system
|
|
428
|
+
* faces take the system colors there. The cyan faces keep their shape.
|
|
429
429
|
*/
|
|
430
430
|
@media (forced-colors: active) {
|
|
431
431
|
:root,
|
|
@@ -515,8 +515,8 @@ html[data-theme='light'] {
|
|
|
515
515
|
/*
|
|
516
516
|
* Every animation in the kit ran regardless of what the reader asked for:
|
|
517
517
|
* the drawer slid, the toast flew in, the pulse and ping looped forever.
|
|
518
|
-
*
|
|
519
|
-
* added later, which is the only way it stays
|
|
518
|
+
* Honoring the preference once here covers every component, including any
|
|
519
|
+
* added later, which is the only way it stays honored.
|
|
520
520
|
*
|
|
521
521
|
* Durations are not zeroed. An animation that finishes in 1ms still fires its
|
|
522
522
|
* animationend, so components that wait on one keep working.
|
|
@@ -565,12 +565,12 @@ html[data-theme='light'] {
|
|
|
565
565
|
* Every kit component paints from these tokens, so redefining them here
|
|
566
566
|
* turns the whole library monochrome without a single component knowing
|
|
567
567
|
* about paper. Browsers drop backgrounds when printing by default, which
|
|
568
|
-
* left light text on the white the printer supplies
|
|
568
|
+
* left light text on the white the printer supplies. Naming white here means
|
|
569
569
|
* the two agree either way.
|
|
570
570
|
*
|
|
571
571
|
* The status hues collapse to black rather than to a print-safe tint. A
|
|
572
|
-
*
|
|
573
|
-
* and a legible black label beats an unreadable
|
|
572
|
+
* color that carries meaning on screen carries none through a mono printer,
|
|
573
|
+
* and a legible black label beats an unreadable colored one.
|
|
574
574
|
*/
|
|
575
575
|
html,
|
|
576
576
|
html[data-theme='light'] {
|
package/dist/utils/cn.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* cn('btn', isPrimary && 'btn-primary', { 'is-disabled': disabled })
|
|
8
8
|
*
|
|
9
9
|
* Object entries are treated as `{ className: boolean }` maps, matching the
|
|
10
|
-
*
|
|
10
|
+
* behavior of `clsx` so existing muscle memory carries over.
|
|
11
11
|
*/
|
|
12
12
|
export type ClassValue = string | number | null | false | undefined | Record<string, boolean | null | undefined> | ClassValue[];
|
|
13
13
|
export declare function cn(...inputs: ClassValue[]): string;
|
package/dist/utils/theme.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Theme utilities
|
|
2
|
+
* Theme utilities: small, framework-agnostic helpers for managing the
|
|
3
3
|
* `data-theme` attribute on `<html>` and persisting the user's choice.
|
|
4
4
|
*
|
|
5
|
-
* The `<ThemeToggle />` component uses these under the hood
|
|
5
|
+
* The `<ThemeToggle />` component uses these under the hood. You can also
|
|
6
6
|
* call them directly when you need to set the theme from a layout, route
|
|
7
7
|
* loader, or an inline `<script>` that runs before paint.
|
|
8
8
|
*
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* `data-theme` holds and what every palette rule keys off.
|
|
13
13
|
* ThemePreference what the reader asked for. `dark`, `light`, or `system`,
|
|
14
14
|
* which is a standing instruction to follow the operating
|
|
15
|
-
* system rather than a
|
|
15
|
+
* system rather than a color.
|
|
16
16
|
*
|
|
17
17
|
* The kit resolved a preference in exactly one place, the pre-paint script,
|
|
18
18
|
* and nothing else could read it back. A control could therefore offer two
|
|
@@ -56,7 +56,7 @@ export declare function resolveTheme(preference: ThemePreference): Theme;
|
|
|
56
56
|
* because the reader already answered it there.
|
|
57
57
|
*/
|
|
58
58
|
export declare function getThemePreference(): ThemePreference;
|
|
59
|
-
/** Read the current theme. SSR-safe
|
|
59
|
+
/** Read the current theme. SSR-safe. Returns `'dark'` on the server. */
|
|
60
60
|
export declare function getTheme(): Theme;
|
|
61
61
|
/**
|
|
62
62
|
* Record a preference, apply what it resolves to, and return the applied theme.
|
|
@@ -64,7 +64,7 @@ export declare function getTheme(): Theme;
|
|
|
64
64
|
* `system` is stored under its own name rather than by clearing the key. The
|
|
65
65
|
* two are indistinguishable on the next read otherwise, and they are not the
|
|
66
66
|
* same thing: one reader chose to follow the OS and the other has not chosen
|
|
67
|
-
* anything yet. Both resolve identically today
|
|
67
|
+
* anything yet. Both resolve identically today. Only one of them is a decision
|
|
68
68
|
* a later default may not override.
|
|
69
69
|
*/
|
|
70
70
|
export declare function setThemePreference(preference: ThemePreference): Theme;
|
|
@@ -85,7 +85,7 @@ export declare function toggleTheme(): Theme;
|
|
|
85
85
|
* unsubscribe function, and a no-op one where there is no `matchMedia`.
|
|
86
86
|
*
|
|
87
87
|
* A page resolving `system` has to repaint when the OS flips at dusk. Without
|
|
88
|
-
* this the preference is
|
|
88
|
+
* this the preference is honored once, at load, and reads as ignored for the
|
|
89
89
|
* rest of the session.
|
|
90
90
|
*/
|
|
91
91
|
export declare function watchSystemTheme(onChange: (theme: Theme) => void): () => void;
|
package/dist/utils/theme.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Theme utilities
|
|
2
|
+
* Theme utilities: small, framework-agnostic helpers for managing the
|
|
3
3
|
* `data-theme` attribute on `<html>` and persisting the user's choice.
|
|
4
4
|
*
|
|
5
|
-
* The `<ThemeToggle />` component uses these under the hood
|
|
5
|
+
* The `<ThemeToggle />` component uses these under the hood. You can also
|
|
6
6
|
* call them directly when you need to set the theme from a layout, route
|
|
7
7
|
* loader, or an inline `<script>` that runs before paint.
|
|
8
8
|
*
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* `data-theme` holds and what every palette rule keys off.
|
|
13
13
|
* ThemePreference what the reader asked for. `dark`, `light`, or `system`,
|
|
14
14
|
* which is a standing instruction to follow the operating
|
|
15
|
-
* system rather than a
|
|
15
|
+
* system rather than a color.
|
|
16
16
|
*
|
|
17
17
|
* The kit resolved a preference in exactly one place, the pre-paint script,
|
|
18
18
|
* and nothing else could read it back. A control could therefore offer two
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* The one key every surface of every consuming application reads and writes.
|
|
26
26
|
*
|
|
27
27
|
* Not exported. A surface that needs the name has `getThemePreference` and
|
|
28
|
-
* `setThemePreference
|
|
28
|
+
* `setThemePreference`. A surface that spells the key itself is how two of
|
|
29
29
|
* them ended up on different keys, with the control writing one and the
|
|
30
30
|
* pre-paint script reading the other.
|
|
31
31
|
*/
|
|
@@ -106,7 +106,7 @@ export function getThemePreference() {
|
|
|
106
106
|
return 'system';
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
/** Read the current theme. SSR-safe
|
|
109
|
+
/** Read the current theme. SSR-safe. Returns `'dark'` on the server. */
|
|
110
110
|
export function getTheme() {
|
|
111
111
|
if (typeof document === 'undefined')
|
|
112
112
|
return 'dark';
|
|
@@ -118,7 +118,7 @@ export function getTheme() {
|
|
|
118
118
|
* `system` is stored under its own name rather than by clearing the key. The
|
|
119
119
|
* two are indistinguishable on the next read otherwise, and they are not the
|
|
120
120
|
* same thing: one reader chose to follow the OS and the other has not chosen
|
|
121
|
-
* anything yet. Both resolve identically today
|
|
121
|
+
* anything yet. Both resolve identically today. Only one of them is a decision
|
|
122
122
|
* a later default may not override.
|
|
123
123
|
*/
|
|
124
124
|
export function setThemePreference(preference) {
|
|
@@ -130,8 +130,8 @@ export function setThemePreference(preference) {
|
|
|
130
130
|
localStorage.setItem(STORAGE_KEY, preference);
|
|
131
131
|
}
|
|
132
132
|
catch {
|
|
133
|
-
// Storage may be disabled (private mode, quota)
|
|
134
|
-
// either way, so the session the reader is in still
|
|
133
|
+
// Storage may be disabled (private mode, quota). The attribute is applied
|
|
134
|
+
// either way, so the session the reader is in still honors the choice.
|
|
135
135
|
}
|
|
136
136
|
announce(preference);
|
|
137
137
|
return theme;
|
|
@@ -145,7 +145,7 @@ export function setTheme(theme) {
|
|
|
145
145
|
localStorage.setItem(STORAGE_KEY, theme);
|
|
146
146
|
}
|
|
147
147
|
catch {
|
|
148
|
-
// Storage may be disabled (private mode, quota)
|
|
148
|
+
// Storage may be disabled (private mode, quota). Fall through silently.
|
|
149
149
|
}
|
|
150
150
|
announce(theme);
|
|
151
151
|
}
|
|
@@ -173,7 +173,7 @@ export function toggleTheme() {
|
|
|
173
173
|
* unsubscribe function, and a no-op one where there is no `matchMedia`.
|
|
174
174
|
*
|
|
175
175
|
* A page resolving `system` has to repaint when the OS flips at dusk. Without
|
|
176
|
-
* this the preference is
|
|
176
|
+
* this the preference is honored once, at load, and reads as ignored for the
|
|
177
177
|
* rest of the session.
|
|
178
178
|
*/
|
|
179
179
|
export function watchSystemTheme(onChange) {
|
package/package.json
CHANGED
package/src/lib/styles/theme.css
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* @lyeve-labs/ui-kit
|
|
2
|
+
* @lyeve-labs/ui-kit: theme tokens
|
|
3
3
|
*
|
|
4
4
|
* A single CSS file imported once at the top of your app's root stylesheet.
|
|
5
|
-
* Declares two palettes
|
|
5
|
+
* Declares two palettes, Soft Dark (default) and Soft Light, built from
|
|
6
6
|
* the LyEve brand guideline (Ink #0B1422 + Cyan #00D4FF) and exposes them
|
|
7
7
|
* as Tailwind v4 `@theme` tokens.
|
|
8
8
|
*
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
--color-line-strong: #616d80;
|
|
45
45
|
--color-fg: #e6e8ee;
|
|
46
46
|
--color-muted: #9aa1ad;
|
|
47
|
-
/* #525866 failed WCAG AA against surface/ink (~2.5:1)
|
|
47
|
+
/* #525866 failed WCAG AA against surface/ink (~2.5:1). Every caption and
|
|
48
48
|
* metadata label uses faint, so one token fix clears the systemic
|
|
49
49
|
* violation. #8b94a7 sits at ~5.6:1 on surface and ~5.9:1 on ink. */
|
|
50
50
|
--color-faint: #8b94a7;
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
* tokens because the brand ramp above is tuned for text contrast: in the
|
|
62
62
|
* light theme it darkens to #005a77 and brand-light sits below brand, so a
|
|
63
63
|
* mark painted from it inverts its lighting. A logotype is exempt from the
|
|
64
|
-
* contrast floor, so these keep the published
|
|
64
|
+
* contrast floor, so these keep the published colors instead. */
|
|
65
65
|
--color-mark-ink: #ffffff;
|
|
66
66
|
--color-mark-foot: #9aa1ad;
|
|
67
67
|
--color-mark-step: #c5cad3;
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
* cannot work as a foreground on a dark surface.
|
|
80
80
|
*
|
|
81
81
|
* One token serves both roles because it inverts with `ink`. As text on a
|
|
82
|
-
* dark surface #f87171 reads 6.30:1
|
|
82
|
+
* dark surface #f87171 reads 6.30:1. As the fill behind a `text-ink` label
|
|
83
83
|
* on a filled destructive button it reads 6.67:1. The light palette does
|
|
84
84
|
* the same in reverse with a dark red and a near-white ink. */
|
|
85
85
|
--color-danger: #f87171;
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
--radius-xl: 16px;
|
|
93
93
|
--radius-2xl: 24px;
|
|
94
94
|
|
|
95
|
-
/* -- Elevation
|
|
95
|
+
/* -- Elevation: the stacking order of everything that floats --- *
|
|
96
96
|
* Every floating surface in the kit carried a bare z-50, so which
|
|
97
97
|
* one won was decided by document order: a Dropdown opened after a
|
|
98
98
|
* Modal painted over it, and the same two in the other order did
|
|
@@ -123,16 +123,16 @@
|
|
|
123
123
|
--z-index-dropdown: 100; /* a panel anchored to its trigger */
|
|
124
124
|
--z-index-overlay: 200; /* the scrim behind a drawer or modal */
|
|
125
125
|
--z-index-drawer: 300; /* a panel docked to a viewport edge */
|
|
126
|
-
--z-index-modal: 400; /* a
|
|
126
|
+
--z-index-modal: 400; /* a centered dialog, and the stack */
|
|
127
127
|
--z-index-tooltip: 500; /* a label attached to a control */
|
|
128
128
|
--z-index-toast: 600; /* transient status */
|
|
129
129
|
--z-index-skip-link: 700; /* the first tab stop in the document */
|
|
130
130
|
|
|
131
|
-
/* -- Motion
|
|
131
|
+
/* -- Motion: four durations, three curves, one rule for exits -- *
|
|
132
132
|
* Named for what they are used for, so the choice is made by
|
|
133
133
|
* reading the name:
|
|
134
134
|
*
|
|
135
|
-
* fast a state change in place:
|
|
135
|
+
* fast a state change in place: color, opacity, border,
|
|
136
136
|
* shadow, focus
|
|
137
137
|
* base movement in place (a knob, a chevron, a collapse, a
|
|
138
138
|
* tab indicator) and a small surface arriving (menu,
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
* move changing in place
|
|
146
146
|
*
|
|
147
147
|
* An exit runs one rung faster than its entrance and on exit:
|
|
148
|
-
* slow in, base out
|
|
148
|
+
* slow in, base out. Base in, fast out. Entrances and exits move
|
|
149
149
|
* only opacity and transform.
|
|
150
150
|
*
|
|
151
151
|
* Tailwind builds no utility from a --duration-* token: there is
|
|
@@ -161,8 +161,8 @@
|
|
|
161
161
|
* wrote `duration-150` fifty times to say the same thing.
|
|
162
162
|
*
|
|
163
163
|
* The reduced-motion block at the foot of this file overrides
|
|
164
|
-
* every one of them and stays the authority on whether they run
|
|
165
|
-
*
|
|
164
|
+
* every one of them and stays the authority on whether they run.
|
|
165
|
+
* The Svelte presets in motion.ts honor the same preference for
|
|
166
166
|
* the entrances and exits that run outside CSS. */
|
|
167
167
|
--duration-fast: 120ms;
|
|
168
168
|
--duration-base: 200ms;
|
|
@@ -178,7 +178,7 @@
|
|
|
178
178
|
|
|
179
179
|
/* The one entrance that is a CSS animation. A panel inside <details> is
|
|
180
180
|
* shown and removed by the browser, so a Svelte transition never sees it
|
|
181
|
-
* leave
|
|
181
|
+
* leave. It plays this on the way in and nothing on the way out. Every
|
|
182
182
|
* other surface enters and leaves through the presets in motion.ts. */
|
|
183
183
|
--animate-popover-in: popover-in var(--duration-base) var(--ease-enter);
|
|
184
184
|
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
--tracking-h2: -0.02em;
|
|
224
224
|
--tracking-h3: -0.015em;
|
|
225
225
|
|
|
226
|
-
/* -- Typography
|
|
226
|
+
/* -- Typography: console type scale --------------------------- *
|
|
227
227
|
* Token Size Line Where it renders *
|
|
228
228
|
* text-xs 12px 16px labels, table heads, metadata, hints*
|
|
229
229
|
* text-sm 14px 20px body copy and every control *
|
|
@@ -259,7 +259,7 @@
|
|
|
259
259
|
*
|
|
260
260
|
* A step is declared with its leading, because a --text-* token
|
|
261
261
|
* sets font-size and nothing else. Only the six steps the kit
|
|
262
|
-
* actually renders are declared
|
|
262
|
+
* actually renders are declared. The larger ones a marketing
|
|
263
263
|
* page reaches for stay as Tailwind ships them. */
|
|
264
264
|
--text-xs: 0.75rem; /* 12px */
|
|
265
265
|
--text-xs--line-height: calc(1 / 0.75); /* 16px */
|
|
@@ -277,32 +277,32 @@
|
|
|
277
277
|
/* ── Spacing grid · 4px base (semantic shortcuts) ────────────── *
|
|
278
278
|
* Tailwind's default 0.25rem (4px) grid is unchanged. *
|
|
279
279
|
* These tokens add named slots for common component spacing. */
|
|
280
|
-
--spacing-page-x: 1.5rem; /* 24px
|
|
281
|
-
--spacing-page-y: 1.5rem; /* 24px
|
|
282
|
-
* measured renders an asymmetric gutter
|
|
280
|
+
--spacing-page-x: 1.5rem; /* 24px: page horizontal gutter */
|
|
281
|
+
--spacing-page-y: 1.5rem; /* 24px: page vertical gutter. Equal to page-x because no page
|
|
282
|
+
* measured renders an asymmetric gutter. The two names stay
|
|
283
283
|
* separate so one axis can move without dragging the other. */
|
|
284
|
-
--spacing-card: 1.25rem; /* 20px
|
|
285
|
-
* surfaces in use
|
|
286
|
-
--spacing-card-sm: 1rem; /* 16px
|
|
287
|
-
--spacing-section: 2rem; /* 32px
|
|
284
|
+
--spacing-card: 1.25rem; /* 20px: card inner padding. 24px matched none of the card
|
|
285
|
+
* surfaces in use. 20px is their measured mode and Card's own md. */
|
|
286
|
+
--spacing-card-sm: 1rem; /* 16px: compact card padding */
|
|
287
|
+
--spacing-section: 2rem; /* 32px: section gap. 48px matched nothing anywhere. 32px is the
|
|
288
288
|
* gap the pages that set one already use, and PageHeader's own. */
|
|
289
|
-
--spacing-input-x: 0.75rem; /* 12px
|
|
289
|
+
--spacing-input-x: 0.75rem; /* 12px: input horizontal padding */
|
|
290
290
|
--spacing-input-y: 0.5rem; /* 8px - input vertical padding */
|
|
291
|
-
/* 38px
|
|
291
|
+
/* 38px: the height of every single-line control. Stated once so an Input,
|
|
292
292
|
* a Select and a NumberInput sitting in the same row line up. Derived from
|
|
293
293
|
* the 13px/1.25 control text plus input-y padding and a 1px border. Under a
|
|
294
|
-
* coarse pointer it is 44px
|
|
294
|
+
* coarse pointer it is 44px. See the touch-target block below the palette. */
|
|
295
295
|
--spacing-control: 2.375rem;
|
|
296
|
-
--spacing-panel-max: 15rem; /* 240px
|
|
297
|
-
/* 56px
|
|
296
|
+
--spacing-panel-max: 15rem; /* 240px: the scroll cap on a floating option list */
|
|
297
|
+
/* 56px: the app header bar, and the sidebar's brand row above the nav.
|
|
298
298
|
* One token, because the two sit side by side across the top of every
|
|
299
299
|
* authed screen and a 4px disagreement between them reads as a broken
|
|
300
300
|
* seam. Three apps each picked their own height before this existed. */
|
|
301
301
|
--spacing-header: 3.5rem;
|
|
302
|
-
--spacing-nav-indent: 0.875rem; /* 14px
|
|
303
|
-
--spacing-nav-rail: 3.5rem; /* 56px
|
|
304
|
-
--spacing-sidebar: 14rem; /* 224px
|
|
305
|
-
--spacing-stack: 1rem; /* 16px
|
|
302
|
+
--spacing-nav-indent: 0.875rem; /* 14px: one level of sidebar nesting */
|
|
303
|
+
--spacing-nav-rail: 3.5rem; /* 56px: the collapsed icon rail */
|
|
304
|
+
--spacing-sidebar: 14rem; /* 224px: the expanded sidebar */
|
|
305
|
+
--spacing-stack: 1rem; /* 16px: default vertical stack gap */
|
|
306
306
|
--spacing-inline: 0.5rem; /* 8px - default inline gap */
|
|
307
307
|
|
|
308
308
|
/* ── Widths · how much room a surface is allowed to take ───── *
|
|
@@ -317,8 +317,8 @@
|
|
|
317
317
|
* drawers asked for the widest rung there was, which is what a *
|
|
318
318
|
* ladder that stops too early looks like from the outside. */
|
|
319
319
|
--container-page-narrow: 56rem; /* 896px - one column: a form, a settings pane */
|
|
320
|
-
--container-page-default: 72rem; /* 1152px
|
|
321
|
-
--container-page-wide: 96rem; /* 1536px
|
|
320
|
+
--container-page-default: 72rem; /* 1152px: a page of stacked cards */
|
|
321
|
+
--container-page-wide: 96rem; /* 1536px: a data page whose table needs the room */
|
|
322
322
|
|
|
323
323
|
/* One ladder for every surface lifted off the page, so a drawer and
|
|
324
324
|
* a modal opened from the same screen are the same size. Each rung
|
|
@@ -328,7 +328,7 @@
|
|
|
328
328
|
--container-overlay-md: 36rem; /* 576px - up to four fields */
|
|
329
329
|
--container-overlay-lg: 44rem; /* 704px - a form with paired fields */
|
|
330
330
|
--container-overlay-xl: 56rem; /* 896px - a form beside a preview */
|
|
331
|
-
--container-overlay-full: 68rem; /* 1088px
|
|
331
|
+
--container-overlay-full: 68rem; /* 1088px: a table inside a dialog */
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
/*
|
|
@@ -350,13 +350,13 @@
|
|
|
350
350
|
*
|
|
351
351
|
* `hit-area` does not move the visual. A switch, a checkbox, a breadcrumb, a
|
|
352
352
|
* pager button, a close cross and an icon inside an input are drawn small on
|
|
353
|
-
* purpose and grown to 44px would push their
|
|
354
|
-
* draws an invisible box
|
|
353
|
+
* purpose and grown to 44px would push their neighbors around. Each one
|
|
354
|
+
* draws an invisible box centered on itself that is never smaller than the
|
|
355
355
|
* control size, and a tap on the box lands on the control. The element must
|
|
356
356
|
* be positioned (`relative`, or `absolute` where it already is) for the box
|
|
357
|
-
* to
|
|
357
|
+
* to center on it. The utility does not set position itself, because a
|
|
358
358
|
* position it set would fight the `absolute` an input's clear button relies
|
|
359
|
-
* on. Two
|
|
359
|
+
* on. Two neighbors' boxes may overlap. The later one in document order
|
|
360
360
|
* wins the overlap, which is the spacing exception SC 2.5.8 allows for.
|
|
361
361
|
*/
|
|
362
362
|
@custom-variant coarse (@media (pointer: coarse));
|
|
@@ -392,7 +392,7 @@ html[data-theme='light'] {
|
|
|
392
392
|
--color-line-strong: #767d8e;
|
|
393
393
|
--color-fg: #111827;
|
|
394
394
|
--color-muted: #525866;
|
|
395
|
-
/* Every value below is the lightest
|
|
395
|
+
/* Every value below is the lightest color on its own hue that clears
|
|
396
396
|
* 4.5:1 against the worst background the kit actually paints it on. That
|
|
397
397
|
* worst case is rarely the bare canvas: status text and brand chips sit
|
|
398
398
|
* inside a tint of their own token (bg-warn/10 text-warn), and the tint
|
|
@@ -425,7 +425,7 @@ html[data-theme='light'] {
|
|
|
425
425
|
/*
|
|
426
426
|
* A forced-colors scheme repaints the page but not a fill named in hex, so the
|
|
427
427
|
* mark's white column vanished on a white high-contrast canvas. Its neutral
|
|
428
|
-
* faces take the system
|
|
428
|
+
* faces take the system colors there. The cyan faces keep their shape.
|
|
429
429
|
*/
|
|
430
430
|
@media (forced-colors: active) {
|
|
431
431
|
:root,
|
|
@@ -515,8 +515,8 @@ html[data-theme='light'] {
|
|
|
515
515
|
/*
|
|
516
516
|
* Every animation in the kit ran regardless of what the reader asked for:
|
|
517
517
|
* the drawer slid, the toast flew in, the pulse and ping looped forever.
|
|
518
|
-
*
|
|
519
|
-
* added later, which is the only way it stays
|
|
518
|
+
* Honoring the preference once here covers every component, including any
|
|
519
|
+
* added later, which is the only way it stays honored.
|
|
520
520
|
*
|
|
521
521
|
* Durations are not zeroed. An animation that finishes in 1ms still fires its
|
|
522
522
|
* animationend, so components that wait on one keep working.
|
|
@@ -565,12 +565,12 @@ html[data-theme='light'] {
|
|
|
565
565
|
* Every kit component paints from these tokens, so redefining them here
|
|
566
566
|
* turns the whole library monochrome without a single component knowing
|
|
567
567
|
* about paper. Browsers drop backgrounds when printing by default, which
|
|
568
|
-
* left light text on the white the printer supplies
|
|
568
|
+
* left light text on the white the printer supplies. Naming white here means
|
|
569
569
|
* the two agree either way.
|
|
570
570
|
*
|
|
571
571
|
* The status hues collapse to black rather than to a print-safe tint. A
|
|
572
|
-
*
|
|
573
|
-
* and a legible black label beats an unreadable
|
|
572
|
+
* color that carries meaning on screen carries none through a mono printer,
|
|
573
|
+
* and a legible black label beats an unreadable colored one.
|
|
574
574
|
*/
|
|
575
575
|
html,
|
|
576
576
|
html[data-theme='light'] {
|