@lyeve-labs/ui-kit 0.31.1 → 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.
Files changed (111) hide show
  1. package/README.md +9 -9
  2. package/dist/components/AccordionItem.svelte +1 -1
  3. package/dist/components/AccountMenu.svelte +2 -2
  4. package/dist/components/AccountMenu.svelte.d.ts +1 -1
  5. package/dist/components/Alert.svelte +2 -2
  6. package/dist/components/Alert.svelte.d.ts +1 -1
  7. package/dist/components/AppShell.svelte +7 -7
  8. package/dist/components/AppShell.svelte.d.ts +2 -2
  9. package/dist/components/AuthShell.svelte +1 -1
  10. package/dist/components/AuthShell.svelte.d.ts +1 -1
  11. package/dist/components/Autocomplete.svelte +1 -1
  12. package/dist/components/Badge.svelte +2 -2
  13. package/dist/components/Banner.svelte +1 -1
  14. package/dist/components/Banner.svelte.d.ts +1 -1
  15. package/dist/components/Button.svelte +5 -5
  16. package/dist/components/Button.svelte.d.ts +1 -1
  17. package/dist/components/Card.svelte +2 -2
  18. package/dist/components/Checkbox.svelte +3 -3
  19. package/dist/components/CheckoutSteps.svelte +54 -0
  20. package/dist/components/CheckoutSteps.svelte.d.ts +12 -0
  21. package/dist/components/Collapsible.svelte +1 -1
  22. package/dist/components/Collapsible.svelte.d.ts +1 -1
  23. package/dist/components/CopyField.svelte +2 -2
  24. package/dist/components/Field.svelte +1 -1
  25. package/dist/components/Field.svelte.d.ts +1 -1
  26. package/dist/components/FileInput.svelte +1 -1
  27. package/dist/components/FormMessage.svelte +4 -4
  28. package/dist/components/Logo.svelte +1 -1
  29. package/dist/components/Logo.svelte.d.ts +1 -1
  30. package/dist/components/MultiSelect.svelte +1 -1
  31. package/dist/components/PageHeader.svelte +2 -2
  32. package/dist/components/PageShell.svelte +4 -4
  33. package/dist/components/PageShell.svelte.d.ts +4 -4
  34. package/dist/components/Pagination.svelte +2 -2
  35. package/dist/components/Panel.svelte +1 -1
  36. package/dist/components/Panel.svelte.d.ts +1 -1
  37. package/dist/components/PluginCart.svelte +339 -0
  38. package/dist/components/PluginCart.svelte.d.ts +45 -0
  39. package/dist/components/Radio.svelte +2 -2
  40. package/dist/components/SearchInput.svelte +2 -2
  41. package/dist/components/SegmentedControl.svelte +4 -4
  42. package/dist/components/SegmentedControl.svelte.d.ts +2 -2
  43. package/dist/components/Select.svelte +5 -5
  44. package/dist/components/Select.svelte.d.ts +4 -4
  45. package/dist/components/SidebarNav.svelte +5 -5
  46. package/dist/components/Stat.svelte +1 -1
  47. package/dist/components/Stat.svelte.d.ts +1 -1
  48. package/dist/components/Table.svelte +4 -4
  49. package/dist/components/Tabs.svelte +2 -2
  50. package/dist/components/ThemeToggle.svelte +1 -1
  51. package/dist/components/TimePicker.svelte +2 -2
  52. package/dist/components/Toggle.svelte +3 -3
  53. package/dist/components/Toolbar.svelte +1 -1
  54. package/dist/components/Toolbar.svelte.d.ts +1 -1
  55. package/dist/components/TreeView.svelte +1 -1
  56. package/dist/components/dialog/Dialog.svelte +1 -1
  57. package/dist/components/dialog/DialogContainer.svelte +1 -1
  58. package/dist/components/dialog/dialog-manager.svelte.d.ts +3 -3
  59. package/dist/components/dialog/dialog-manager.svelte.js +7 -7
  60. package/dist/components/dialog/types.d.ts +3 -3
  61. package/dist/index.d.ts +7 -3
  62. package/dist/index.js +8 -5
  63. package/dist/internal/calendar.d.ts +1 -1
  64. package/dist/internal/calendar.js +2 -2
  65. package/dist/internal/choice.d.ts +6 -6
  66. package/dist/internal/choice.js +6 -6
  67. package/dist/internal/copy.svelte.d.ts +2 -2
  68. package/dist/internal/copy.svelte.js +2 -2
  69. package/dist/internal/field.d.ts +11 -11
  70. package/dist/internal/field.js +12 -12
  71. package/dist/internal/filter.d.ts +3 -3
  72. package/dist/internal/filter.js +3 -3
  73. package/dist/internal/href.d.ts +1 -1
  74. package/dist/internal/href.js +1 -1
  75. package/dist/internal/layout.d.ts +7 -7
  76. package/dist/internal/layout.js +7 -7
  77. package/dist/internal/listbox.svelte.d.ts +1 -1
  78. package/dist/internal/listbox.svelte.js +3 -3
  79. package/dist/internal/nav-expansion.svelte.d.ts +1 -1
  80. package/dist/internal/nav-expansion.svelte.js +2 -2
  81. package/dist/internal/nav-tree.d.ts +3 -3
  82. package/dist/internal/nav-tree.js +3 -3
  83. package/dist/internal/number.d.ts +1 -1
  84. package/dist/internal/number.js +1 -1
  85. package/dist/internal/overlay.d.ts +3 -3
  86. package/dist/internal/overlay.js +3 -3
  87. package/dist/internal/panel.d.ts +5 -5
  88. package/dist/internal/panel.js +5 -5
  89. package/dist/internal/pricing.d.ts +110 -0
  90. package/dist/internal/pricing.js +77 -0
  91. package/dist/internal/rollup.d.ts +3 -3
  92. package/dist/internal/rollup.js +3 -3
  93. package/dist/internal/scroll-edges.d.ts +4 -4
  94. package/dist/internal/scroll-edges.js +5 -5
  95. package/dist/internal/time.d.ts +3 -3
  96. package/dist/internal/time.js +3 -3
  97. package/dist/internal/tone.d.ts +3 -3
  98. package/dist/internal/tone.js +3 -3
  99. package/dist/internal/touch.d.ts +1 -1
  100. package/dist/internal/touch.js +1 -1
  101. package/dist/internal/tree.d.ts +2 -2
  102. package/dist/internal/tree.js +2 -2
  103. package/dist/motion.d.ts +3 -3
  104. package/dist/motion.js +4 -4
  105. package/dist/stores/toast.svelte.d.ts +1 -1
  106. package/dist/styles/theme.css +45 -45
  107. package/dist/utils/cn.d.ts +1 -1
  108. package/dist/utils/theme.d.ts +6 -6
  109. package/dist/utils/theme.js +10 -10
  110. package/package.json +1 -1
  111. package/src/lib/styles/theme.css +45 -45
@@ -0,0 +1,77 @@
1
+ /**
2
+ * The cart's shape and the volume ladder, shared by every surface that sells.
3
+ *
4
+ * Two sites sold the same catalog from two components. One posted the
5
+ * selection to the server and rendered the price that came back, the other
6
+ * computed a total in the browser from a catalog it had fetched, with a
7
+ * hardcoded list behind it for when the fetch failed. They agreed by
8
+ * coincidence, and the second carried a comment recording how thin the
9
+ * coincidence was: the discount has to be truncated rather than rounded, or
10
+ * the quote is a cent deeper than the charge.
11
+ *
12
+ * So nothing here computes a price. The types describe what the sales API
13
+ * returns, and the functions are presentation over the ladder: which rung a
14
+ * selection stands on and how far the next one is. The total always comes
15
+ * from the server, on both sites, because a price computed twice is a price
16
+ * that will disagree once.
17
+ */
18
+ export function ladderState(brackets, count) {
19
+ const sorted = [...brackets].sort((a, b) => a.plugins - b.plugins);
20
+ const reachedPct = sorted
21
+ .filter((b) => b.plugins <= count)
22
+ .reduce((m, b) => Math.max(m, b.discount_pct), 0);
23
+ const step = sorted.find((b) => b.plugins > count && b.discount_pct > reachedPct);
24
+ let active = -1;
25
+ sorted.forEach((b, i) => {
26
+ if (count >= b.plugins)
27
+ active = i;
28
+ });
29
+ return {
30
+ count,
31
+ reachedPct,
32
+ next: step
33
+ ? { plugins: step.plugins, discount_pct: step.discount_pct, more: step.plugins - count }
34
+ : null,
35
+ active,
36
+ };
37
+ }
38
+ /**
39
+ * How many capabilities the bill will carry.
40
+ *
41
+ * For a new cart that is what is selected. For a change to a live
42
+ * subscription it is what is held as well, because that is the count the
43
+ * server prices the change at. Reading the cart alone put a subscriber on the
44
+ * list-price rung beside a total that had already taken the discount.
45
+ */
46
+ export function billedCount(opts) {
47
+ const added = new Set(opts.selected);
48
+ if (!opts.change)
49
+ return added.size;
50
+ if (opts.pricedSkus)
51
+ return new Set(opts.pricedSkus).size;
52
+ return new Set([...(opts.held ?? []), ...added]).size;
53
+ }
54
+ /** One row per rung, labeled by the range it covers. */
55
+ export function ladderRows(brackets) {
56
+ const sorted = [...brackets].sort((a, b) => a.plugins - b.plugins);
57
+ return sorted.map((b, i) => {
58
+ const next = sorted[i + 1];
59
+ return { from: b.plugins, to: next ? next.plugins - 1 : null, discount_pct: b.discount_pct };
60
+ });
61
+ }
62
+ /**
63
+ * Money, for display.
64
+ *
65
+ * The locale is fixed for the reason `number.ts` states: a server and the
66
+ * browser that hydrates its output do not have to report the same one, and a
67
+ * figure that changes under the reader is worse than one that is not local to
68
+ * them.
69
+ */
70
+ export function formatCents(cents, currency = 'USD') {
71
+ return new Intl.NumberFormat('en-US', {
72
+ style: 'currency',
73
+ currency,
74
+ minimumFractionDigits: 2,
75
+ maximumFractionDigits: 2,
76
+ }).format(cents / 100);
77
+ }
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * The tri-state contract behind a permissions matrix and a checkable tree.
3
3
  *
4
- * A parent control does two jobs at once: it summarises the rows beneath it,
4
+ * A parent control does two jobs at once: it summarizes the rows beneath it,
5
5
  * and a click on it writes every one of them. Both surfaces folded that summary
6
6
  * with `rows.every(has)`, which is true over an empty array, so a group whose
7
7
  * rows were all filtered away or all disabled drew as fully granted and the
8
- * click that followed meant clear rather than fill. Summarising by count rather
8
+ * click that followed meant clear rather than fill. Summarizing by count rather
9
9
  * than by fold, and separating what may be written from what is counted, is the
10
10
  * whole reason this module exists.
11
11
  *
12
- * Not exported from the package entry point - this is an implementation detail.
12
+ * Not exported from the package entry point: this is an implementation detail.
13
13
  */
14
14
  /** What a parent control shows: nothing granted, part granted, all granted. */
15
15
  export type TriState = 'none' | 'some' | 'all';
@@ -1,15 +1,15 @@
1
1
  /**
2
2
  * The tri-state contract behind a permissions matrix and a checkable tree.
3
3
  *
4
- * A parent control does two jobs at once: it summarises the rows beneath it,
4
+ * A parent control does two jobs at once: it summarizes the rows beneath it,
5
5
  * and a click on it writes every one of them. Both surfaces folded that summary
6
6
  * with `rows.every(has)`, which is true over an empty array, so a group whose
7
7
  * rows were all filtered away or all disabled drew as fully granted and the
8
- * click that followed meant clear rather than fill. Summarising by count rather
8
+ * click that followed meant clear rather than fill. Summarizing by count rather
9
9
  * than by fold, and separating what may be written from what is counted, is the
10
10
  * whole reason this module exists.
11
11
  *
12
- * Not exported from the package entry point - this is an implementation detail.
12
+ * Not exported from the package entry point: this is an implementation detail.
13
13
  */
14
14
  /**
15
15
  * Rolls a set of rows up to one state.
@@ -6,13 +6,13 @@
6
6
  * the tab past the edge is otherwise unannounced. The arithmetic is the same
7
7
  * in both and lives here so a third scroller cannot get it subtly different.
8
8
  *
9
- * Not exported from the package entry point - this is an implementation detail.
9
+ * Not exported from the package entry point: this is an implementation detail.
10
10
  */
11
11
  export interface ScrollEdges {
12
12
  before: boolean;
13
13
  after: boolean;
14
14
  }
15
- /** The three metrics the answer is read from; an element has all of them. */
15
+ /** The three metrics the answer is read from. An element has all of them. */
16
16
  export interface ScrollMetrics {
17
17
  scrollWidth: number;
18
18
  clientWidth: number;
@@ -22,8 +22,8 @@ export declare function scrollEdges(el: ScrollMetrics): ScrollEdges;
22
22
  /**
23
23
  * The fade itself: a dark gradient on the edge, outside the scroll box so it
24
24
  * does not scroll away with the content it describes. Dark rather than a
25
- * palette colour, because the box sits on the page in one place and inside
26
- * a card in another and no surface token is the colour to fade to; the
25
+ * palette color, because the box sits on the page in one place and inside
26
+ * a card in another and no surface token is the color to fade to. The
27
27
  * scrims use black at an alpha for the same reason and it reads in both
28
28
  * themes. The direction is logical, so a right-to-left page fades the other
29
29
  * way.
@@ -6,7 +6,7 @@
6
6
  * the tab past the edge is otherwise unannounced. The arithmetic is the same
7
7
  * in both and lives here so a third scroller cannot get it subtly different.
8
8
  *
9
- * Not exported from the package entry point - this is an implementation detail.
9
+ * Not exported from the package entry point: this is an implementation detail.
10
10
  */
11
11
  export function scrollEdges(el) {
12
12
  const slack = el.scrollWidth - el.clientWidth;
@@ -16,14 +16,14 @@ export function scrollEdges(el) {
16
16
  return { before: false, after: false };
17
17
  // A right-to-left box reports the offset as a negative number, and the two
18
18
  // edges are the same two edges either way round.
19
- const travelled = Math.abs(el.scrollLeft);
20
- return { before: travelled > 1, after: travelled < slack - 1 };
19
+ const traveled = Math.abs(el.scrollLeft);
20
+ return { before: traveled > 1, after: traveled < slack - 1 };
21
21
  }
22
22
  /**
23
23
  * The fade itself: a dark gradient on the edge, outside the scroll box so it
24
24
  * does not scroll away with the content it describes. Dark rather than a
25
- * palette colour, because the box sits on the page in one place and inside
26
- * a card in another and no surface token is the colour to fade to; the
25
+ * palette color, because the box sits on the page in one place and inside
26
+ * a card in another and no surface token is the color to fade to. The
27
27
  * scrims use black at an alpha for the same reason and it reads in both
28
28
  * themes. The direction is logical, so a right-to-left page fades the other
29
29
  * way.
@@ -16,7 +16,7 @@
16
16
  * rewrites a legal time, and a modulo that turns midnight into hour zero of a
17
17
  * clock with no hour zero.
18
18
  *
19
- * Not exported from the package entry point - this is an implementation detail.
19
+ * Not exported from the package entry point: this is an implementation detail.
20
20
  */
21
21
  /** One time, already range checked. `mi` rather than `m` so it cannot read as months. */
22
22
  export interface TimeParts {
@@ -47,7 +47,7 @@ export declare function parseISOTime(s: string | undefined | null): TimeParts |
47
47
  */
48
48
  export declare function toISOTime(p: TimeParts, seconds: boolean): string;
49
49
  /**
50
- * Steps one segment without carrying into its neighbour. Stepping the minute
50
+ * Steps one segment without carrying into its neighbor. Stepping the minute
51
51
  * past 59 wraps to 0 and leaves the hour alone, because a spinner that changes
52
52
  * two fields at once is not what the arrow key promised.
53
53
  *
@@ -91,7 +91,7 @@ export declare function to12Hour(h: number): {
91
91
  meridiem: 'AM' | 'PM';
92
92
  };
93
93
  /**
94
- * 12-hour back to 24. 12 AM is hour 0 and 12 PM is hour 12; every other hour is
94
+ * 12-hour back to 24. 12 AM is hour 0 and 12 PM is hour 12. Every other hour is
95
95
  * itself in the morning and itself plus twelve in the afternoon.
96
96
  */
97
97
  export declare function from12Hour(hour: number, meridiem: 'AM' | 'PM'): number;
@@ -16,7 +16,7 @@
16
16
  * rewrites a legal time, and a modulo that turns midnight into hour zero of a
17
17
  * clock with no hour zero.
18
18
  *
19
- * Not exported from the package entry point - this is an implementation detail.
19
+ * Not exported from the package entry point: this is an implementation detail.
20
20
  */
21
21
  /** Highest legal value plus one, per stepped segment. */
22
22
  const SEGMENT_SIZE = {
@@ -67,7 +67,7 @@ export function toISOTime(p, seconds) {
67
67
  return seconds ? `${base}:${pad2(p.s)}` : base;
68
68
  }
69
69
  /**
70
- * Steps one segment without carrying into its neighbour. Stepping the minute
70
+ * Steps one segment without carrying into its neighbor. Stepping the minute
71
71
  * past 59 wraps to 0 and leaves the hour alone, because a spinner that changes
72
72
  * two fields at once is not what the arrow key promised.
73
73
  *
@@ -149,7 +149,7 @@ export function to12Hour(h) {
149
149
  return { hour: wrapped === 0 ? 12 : wrapped, meridiem: h < 12 ? 'AM' : 'PM' };
150
150
  }
151
151
  /**
152
- * 12-hour back to 24. 12 AM is hour 0 and 12 PM is hour 12; every other hour is
152
+ * 12-hour back to 24. 12 AM is hour 0 and 12 PM is hour 12. Every other hour is
153
153
  * itself in the morning and itself plus twelve in the afternoon.
154
154
  */
155
155
  export function from12Hour(hour, meridiem) {
@@ -4,8 +4,8 @@
4
4
  * Alert, Banner and the toast store each named their neutral-informational tone
5
5
  * `info`, while Badge, Tag, Indicator and Progress named the same brand-cyan
6
6
  * tone `brand`. A consumer building a status row had to remember which
7
- * component wanted which word for the same colour. `brand` is canonical because
8
- * it names the token the tone actually resolves to; `info` still works and maps
7
+ * component wanted which word for the same color. `brand` is canonical because
8
+ * it names the token the tone actually resolves to. `info` still works and maps
9
9
  * onto it, so nothing that already ships has to change.
10
10
  */
11
11
  /** Tones a status surface can carry. */
@@ -20,7 +20,7 @@ export declare function statusTone(tone: StatusToneInput): StatusTone;
20
20
  * The glyph each status tone draws, as SVG path data on a 24x24 grid.
21
21
  *
22
22
  * Alert and Toaster drew these as the literal characters ℹ ✓ ! ×, which pick up
23
- * whatever the user's font does with them - the check and the cross landed at
23
+ * whatever the user's font does with them: the check and the cross landed at
24
24
  * different optical weights from every other icon in the library, all of which
25
25
  * are stroked SVG.
26
26
  */
@@ -4,8 +4,8 @@
4
4
  * Alert, Banner and the toast store each named their neutral-informational tone
5
5
  * `info`, while Badge, Tag, Indicator and Progress named the same brand-cyan
6
6
  * tone `brand`. A consumer building a status row had to remember which
7
- * component wanted which word for the same colour. `brand` is canonical because
8
- * it names the token the tone actually resolves to; `info` still works and maps
7
+ * component wanted which word for the same color. `brand` is canonical because
8
+ * it names the token the tone actually resolves to. `info` still works and maps
9
9
  * onto it, so nothing that already ships has to change.
10
10
  */
11
11
  /** Resolves the accepted spelling to the canonical one. */
@@ -16,7 +16,7 @@ export function statusTone(tone) {
16
16
  * The glyph each status tone draws, as SVG path data on a 24x24 grid.
17
17
  *
18
18
  * Alert and Toaster drew these as the literal characters ℹ ✓ ! ×, which pick up
19
- * whatever the user's font does with them - the check and the cross landed at
19
+ * whatever the user's font does with them: the check and the cross landed at
20
20
  * different optical weights from every other icon in the library, all of which
21
21
  * are stroked SVG.
22
22
  */
@@ -7,7 +7,7 @@
7
7
  * value of `--spacing-control` and the `hit-area` utility all live beside the
8
8
  * palette so a consumer's build emits them.
9
9
  *
10
- * Not exported from the package entry point - this is an implementation detail.
10
+ * Not exported from the package entry point: this is an implementation detail.
11
11
  */
12
12
  /**
13
13
  * The control grows. For a control whose visual may take the finger's size:
@@ -7,7 +7,7 @@
7
7
  * value of `--spacing-control` and the `hit-area` utility all live beside the
8
8
  * palette so a consumer's build emits them.
9
9
  *
10
- * Not exported from the package entry point - this is an implementation detail.
10
+ * Not exported from the package entry point: this is an implementation detail.
11
11
  */
12
12
  /**
13
13
  * The control grows. For a control whose visual may take the finger's size:
@@ -2,7 +2,7 @@
2
2
  * The shape of a data tree and the arithmetic a checkable one needs.
3
3
  *
4
4
  * A data tree is not a navigation menu. A menu shows where you can go and one
5
- * item is current; a tree shows a structure, and a branch in it summarises
5
+ * item is current. A tree shows a structure, and a branch in it summarizes
6
6
  * everything beneath it while a click on that branch writes every one of them.
7
7
  * Those two jobs are the reason this module exists: the summary and the write
8
8
  * have to be computed from the same list, or a branch reports a state its own
@@ -12,7 +12,7 @@
12
12
  * here. That module already holds the case a fold gets wrong, and a second
13
13
  * implementation of it would be a second chance to get it wrong.
14
14
  *
15
- * Not exported from the package entry point - this is an implementation detail.
15
+ * Not exported from the package entry point: this is an implementation detail.
16
16
  */
17
17
  import type { Component } from 'svelte';
18
18
  import { type TriState } from './rollup.js';
@@ -2,7 +2,7 @@
2
2
  * The shape of a data tree and the arithmetic a checkable one needs.
3
3
  *
4
4
  * A data tree is not a navigation menu. A menu shows where you can go and one
5
- * item is current; a tree shows a structure, and a branch in it summarises
5
+ * item is current. A tree shows a structure, and a branch in it summarizes
6
6
  * everything beneath it while a click on that branch writes every one of them.
7
7
  * Those two jobs are the reason this module exists: the summary and the write
8
8
  * have to be computed from the same list, or a branch reports a state its own
@@ -12,7 +12,7 @@
12
12
  * here. That module already holds the case a fold gets wrong, and a second
13
13
  * implementation of it would be a second chance to get it wrong.
14
14
  *
15
- * Not exported from the package entry point - this is an implementation detail.
15
+ * Not exported from the package entry point: this is an implementation detail.
16
16
  */
17
17
  import { nextState, rollUp, setSubtree } from './rollup.js';
18
18
  /**
package/dist/motion.d.ts CHANGED
@@ -18,7 +18,7 @@ export declare const FALLBACK: {
18
18
  };
19
19
  /**
20
20
  * What a preset hands Svelte. The function form is resolved once the element
21
- * is in the DOM, with the direction the animation is really playing in; under
21
+ * is in the DOM, with the direction the animation is really playing in. Under
22
22
  * `transition:` the directive itself only ever says `both`, so this is the
23
23
  * one way a single directive can tune its exit apart from its entrance.
24
24
  */
@@ -38,7 +38,7 @@ export declare function bezier(x1: number, y1: number, x2: number, y2: number):
38
38
  export declare function easing(curve: Curve): (x: number) => number;
39
39
  /** True when the document asked for no motion, or cannot play any. */
40
40
  export declare function still(node: Element): boolean;
41
- /** A centred dialog: rises a little and settles to full size. */
41
+ /** A centered dialog: rises a little and settles to full size. */
42
42
  export declare const dialog: (node: Element) => Motion;
43
43
  /** The scrim behind a dialog or drawer, on the same clock as its surface. */
44
44
  export declare const scrim: (node: Element) => Motion;
@@ -55,7 +55,7 @@ export declare const popover: (node: Element) => Motion;
55
55
  export declare const toast: (node: Element) => Motion;
56
56
  /**
57
57
  * Siblings closing the gap a removed item leaves, for `animate:`. Svelte's
58
- * flip measures the move; the kit supplies the clock.
58
+ * flip measures the move. The kit supplies the clock.
59
59
  */
60
60
  export declare function reorder(node: Element, positions: {
61
61
  from: DOMRect;
package/dist/motion.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * <li animate:motion.reorder>
7
7
  *
8
8
  * `|global` is not optional. A Svelte transition is local by default and
9
- * plays only when its own block toggles; a page that wraps a Modal in its own
9
+ * plays only when its own block toggles. A page that wraps a Modal in its own
10
10
  * `{#if}` to reset the form each time removes the whole component, and a
11
11
  * local exit never runs. Global plays it on any ancestor change.
12
12
  *
@@ -22,7 +22,7 @@
22
22
  * and a test holds them equal to the tokens.
23
23
  *
24
24
  * Two cases return no duration at all. A reader who asked for reduced motion
25
- * gets the state change and none of the travel; the reduced-motion block in
25
+ * gets the state change and none of the travel. The reduced-motion block in
26
26
  * theme.css cannot reach these, because Svelte drives them through the Web
27
27
  * Animations API and not through a stylesheet. And a document with no
28
28
  * `Element.animate`, which is every jsdom test, mounts and unmounts at once,
@@ -143,7 +143,7 @@ function surface(rung, css) {
143
143
  };
144
144
  };
145
145
  }
146
- /** A centred dialog: rises a little and settles to full size. */
146
+ /** A centered dialog: rises a little and settles to full size. */
147
147
  export const dialog = surface('slow', (t, u) => `opacity: ${t}; transform: translateY(${8 * u}px) scale(${0.96 + 0.04 * t})`);
148
148
  /** The scrim behind a dialog or drawer, on the same clock as its surface. */
149
149
  export const scrim = surface('slow', (t) => `opacity: ${t}`);
@@ -161,7 +161,7 @@ export const popover = surface('base', (t, u) => `opacity: ${t}; transform: tran
161
161
  export const toast = surface('base', (t, u) => `opacity: ${t}; transform: translateY(${8 * u}px) scale(${0.96 + 0.04 * t})`);
162
162
  /**
163
163
  * Siblings closing the gap a removed item leaves, for `animate:`. Svelte's
164
- * flip measures the move; the kit supplies the clock.
164
+ * flip measures the move. The kit supplies the clock.
165
165
  */
166
166
  export function reorder(node, positions, _params) {
167
167
  if (still(node))
@@ -1,7 +1,7 @@
1
1
  import type { StatusToneInput } from '../internal/tone.js';
2
2
  /**
3
3
  * A toast carries the same tone vocabulary as Alert and Banner. `brand` is the
4
- * canonical name; `info` is kept because `toast.info(...)` already ships.
4
+ * canonical name. `info` is kept because `toast.info(...)` already ships.
5
5
  */
6
6
  export type ToastTone = StatusToneInput;
7
7
  export interface Toast {
@@ -1,8 +1,8 @@
1
1
  /*
2
- * @lyeve-labs/ui-kit - theme tokens
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 - Soft Dark (default) and Soft Light - built from
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); every caption and
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 colours instead. */
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; as the fill behind a `text-ink` label
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 - the stacking order of everything that floats --- *
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 centred dialog, and the stack */
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 - four durations, three curves, one rule for exits -- *
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: colour, opacity, border,
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; base in, fast out. Entrances and exits move
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
- * the Svelte presets in motion.ts honour the same preference for
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; it plays this on the way in and nothing on the way out. Every
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 - console type scale --------------------------- *
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; the larger ones a marketing
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 - 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
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 - 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
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 - input horizontal padding */
289
+ --spacing-input-x: 0.75rem; /* 12px: input horizontal padding */
290
290
  --spacing-input-y: 0.5rem; /* 8px - input vertical padding */
291
- /* 38px - the height of every single-line control. Stated once so an Input,
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; see the touch-target block below the palette. */
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 - the scroll cap on a floating option list */
297
- /* 56px - the app header bar, and the sidebar's brand row above the nav.
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 - 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 */
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 - a page of stacked cards */
321
- --container-page-wide: 96rem; /* 1536px - a data page whose table needs the room */
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 - a table inside a dialog */
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 neighbours around; each one
354
- * draws an invisible box centred on itself that is never smaller than the
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 centre on it; the utility does not set position itself, because a
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 neighbours' boxes may overlap; the later one in document order
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 colour on its own hue that clears
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 colours there; the cyan faces keep their shape.
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
- * Honouring the preference once here covers every component, including any
519
- * added later, which is the only way it stays honoured.
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; naming white here means
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
- * colour that carries meaning on screen carries none through a mono printer,
573
- * and a legible black label beats an unreadable coloured one.
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'] {