@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.
- 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/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 +2 -2
- 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/internal/field.js
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
* an Input and a NumberInput placed side by side did not line up. Changing a
|
|
8
8
|
* control's appearance now means changing one of these constants.
|
|
9
9
|
*
|
|
10
|
-
* Not exported from the package entry point
|
|
10
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
11
11
|
*/
|
|
12
|
-
/** Vertical rhythm inside a
|
|
12
|
+
/** Vertical rhythm inside a labeled field: label, control, hint/error. */
|
|
13
13
|
export const FIELD_WRAP = 'flex flex-col gap-1.5';
|
|
14
14
|
/**
|
|
15
|
-
* The marker every
|
|
15
|
+
* The marker every labeled field carries on its outermost element, and the
|
|
16
16
|
* only way a surface can ask how much form it is holding.
|
|
17
17
|
*
|
|
18
18
|
* A class would not do: FIELD_WRAP is three utilities a caller may legitimately
|
|
@@ -41,20 +41,20 @@ export const FIELD_HINT = 'text-xs text-faint';
|
|
|
41
41
|
/** Error text below a control. Replaces the hint rather than stacking with it. */
|
|
42
42
|
export const FIELD_ERROR = 'text-xs text-danger';
|
|
43
43
|
/**
|
|
44
|
-
* Everything a single-line control needs except its border
|
|
44
|
+
* Everything a single-line control needs except its border color.
|
|
45
45
|
*
|
|
46
46
|
* `h-control` is a theme token (2.375rem / 38px), not a literal, so the height
|
|
47
|
-
* is stated once. Controls that grow with their content
|
|
48
|
-
* MultiSelect chip well
|
|
47
|
+
* is stated once. Controls that grow with their content: Textarea, the
|
|
48
|
+
* MultiSelect chip well: use `CONTROL_MULTILINE` instead and keep the token as
|
|
49
49
|
* a minimum.
|
|
50
50
|
*/
|
|
51
51
|
/**
|
|
52
52
|
* outline-none must be paired with a replacement. It was not here: theme.css
|
|
53
53
|
* declares a global :focus-visible outline of 2px solid brand, chosen for its
|
|
54
|
-
* contrast, and a utility beats the base layer, so these two
|
|
54
|
+
* contrast, and a utility beats the base layer, so these two canceled the
|
|
55
55
|
* kit's own focus indicator for every text input, textarea, number and select.
|
|
56
|
-
* Focus was left as a 1px border-
|
|
57
|
-
* CONTROL_SEGMENT already pair the two correctly
|
|
56
|
+
* Focus was left as a 1px border-color change. SidebarNav's buttons and
|
|
57
|
+
* CONTROL_SEGMENT already pair the two correctly. These did half of it.
|
|
58
58
|
*/
|
|
59
59
|
export const CONTROL_BASE = 'w-full h-control rounded-lg bg-surface-2 border px-3 text-sm text-fg ' +
|
|
60
60
|
'placeholder:text-faint transition-colors outline-none ' +
|
|
@@ -76,7 +76,7 @@ export const CONTROL_MULTILINE = 'w-full min-h-control rounded-lg bg-surface-2 b
|
|
|
76
76
|
export function controlBorder(error) {
|
|
77
77
|
// line-strong, not line: at 1.25:1 against the page the resting border was
|
|
78
78
|
// the only thing marking the control and it failed SC 1.4.11. line stays the
|
|
79
|
-
// divider
|
|
79
|
+
// divider color, where there is no control to identify.
|
|
80
80
|
return error ? 'border-danger focus:border-danger' : 'border-line-strong focus:border-brand';
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
@@ -84,7 +84,7 @@ export function controlBorder(error) {
|
|
|
84
84
|
*
|
|
85
85
|
* Returns undefined when neither is present, so the attribute is omitted rather
|
|
86
86
|
* than pointing at an element that was never rendered. Only Input carried
|
|
87
|
-
* `aria-invalid` before this
|
|
87
|
+
* `aria-invalid` before this. Nothing carried `aria-describedby`, so a screen
|
|
88
88
|
* reader announced the control and never the reason it was rejected.
|
|
89
89
|
*/
|
|
90
90
|
export function describedBy(id, error, hint) {
|
|
@@ -123,7 +123,7 @@ export function segmentedBorder(error) {
|
|
|
123
123
|
*
|
|
124
124
|
* It carries no width. A two-digit segment needs a fixed one so the control
|
|
125
125
|
* does not resize as the user types, and an AM/PM select needs to size to its
|
|
126
|
-
* own text
|
|
126
|
+
* own text. Stating a width here would mean one of the two overriding it, and
|
|
127
127
|
* two width utilities on one element resolve by the order Tailwind emits them
|
|
128
128
|
* rather than the order they were written.
|
|
129
129
|
*
|
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
*
|
|
9
9
|
* It reads the label and nothing else, so an option a user knows by its value,
|
|
10
10
|
* its airport code or a synonym could not be found. It compares raw code
|
|
11
|
-
* points, so a query of "cafe" missed an option
|
|
11
|
+
* points, so a query of "cafe" missed an option labeled with an acute accent.
|
|
12
12
|
* It trims and lowercases the query once per option instead of once per
|
|
13
13
|
* keystroke. And it is not a prop, so a consumer whose list arrives already
|
|
14
14
|
* narrowed by a server query had no way to switch local filtering off or to say
|
|
15
15
|
* what a match means for their data. Both controls now call applyFilter, which
|
|
16
16
|
* takes a matcher the call site can replace or disable.
|
|
17
17
|
*
|
|
18
|
-
* Not exported from the package entry point
|
|
18
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
19
19
|
*/
|
|
20
20
|
/** What a matcher is told about the query, computed once per keystroke rather than per option. */
|
|
21
21
|
export interface FilterContext {
|
|
@@ -52,7 +52,7 @@ export declare function normalize(value: string): string;
|
|
|
52
52
|
/**
|
|
53
53
|
* The default matcher: case- and accent-insensitive substring over the label,
|
|
54
54
|
* plus any keywords the option carries. Label-only matching is what ships
|
|
55
|
-
* today
|
|
55
|
+
* today. Keywords are additive and absent on every existing option, so adopting
|
|
56
56
|
* this changes no current list.
|
|
57
57
|
*
|
|
58
58
|
* An empty needle keeps every option. applyFilter answers an empty query before
|
package/dist/internal/filter.js
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
*
|
|
9
9
|
* It reads the label and nothing else, so an option a user knows by its value,
|
|
10
10
|
* its airport code or a synonym could not be found. It compares raw code
|
|
11
|
-
* points, so a query of "cafe" missed an option
|
|
11
|
+
* points, so a query of "cafe" missed an option labeled with an acute accent.
|
|
12
12
|
* It trims and lowercases the query once per option instead of once per
|
|
13
13
|
* keystroke. And it is not a prop, so a consumer whose list arrives already
|
|
14
14
|
* narrowed by a server query had no way to switch local filtering off or to say
|
|
15
15
|
* what a match means for their data. Both controls now call applyFilter, which
|
|
16
16
|
* takes a matcher the call site can replace or disable.
|
|
17
17
|
*
|
|
18
|
-
* Not exported from the package entry point
|
|
18
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
19
19
|
*/
|
|
20
20
|
/**
|
|
21
21
|
* Trim, lowercase, and fold diacritics through NFD so that a query of "e"
|
|
@@ -34,7 +34,7 @@ export function normalize(value) {
|
|
|
34
34
|
/**
|
|
35
35
|
* The default matcher: case- and accent-insensitive substring over the label,
|
|
36
36
|
* plus any keywords the option carries. Label-only matching is what ships
|
|
37
|
-
* today
|
|
37
|
+
* today. Keywords are additive and absent on every existing option, so adopting
|
|
38
38
|
* this changes no current list.
|
|
39
39
|
*
|
|
40
40
|
* An empty needle keeps every option. applyFilter answers an empty query before
|
package/dist/internal/href.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* from a caller supplied function, and a rule kept in two places is a rule that
|
|
8
8
|
* gets fixed in one of them.
|
|
9
9
|
*
|
|
10
|
-
* Not exported from the package entry point
|
|
10
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
11
11
|
*/
|
|
12
12
|
/** The href as given, or nothing when its scheme is one no component will emit. */
|
|
13
13
|
export declare function safeHref(href: string | undefined | null): string | undefined;
|
package/dist/internal/href.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* from a caller supplied function, and a rule kept in two places is a rule that
|
|
8
8
|
* gets fixed in one of them.
|
|
9
9
|
*
|
|
10
|
-
* Not exported from the package entry point
|
|
10
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
11
11
|
*/
|
|
12
12
|
/**
|
|
13
13
|
* The characters a browser drops before it reads the scheme.
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* theme declares, `--spacing-control` was the one with any uses, and it had
|
|
16
16
|
* them because the field contract composes from it.
|
|
17
17
|
*
|
|
18
|
-
* Not exported from the package entry point
|
|
18
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
19
19
|
*/
|
|
20
20
|
/** The treatment a section heading takes, independent of its level. */
|
|
21
21
|
export type SectionVariant = 'default' | 'eyebrow';
|
|
@@ -60,7 +60,7 @@ export type OverlaySize = 'sm' | 'md' | 'lg' | 'xl' | 'full';
|
|
|
60
60
|
*/
|
|
61
61
|
export declare const OVERLAY_WIDTH: Record<OverlaySize, string>;
|
|
62
62
|
/**
|
|
63
|
-
* The rung a body of this many
|
|
63
|
+
* The rung a body of this many labeled fields needs.
|
|
64
64
|
*
|
|
65
65
|
* A panel is sized by its caller today, and the caller is guessing: all 18
|
|
66
66
|
* drawers measured across three consuming applications ask for the widest rung
|
|
@@ -113,7 +113,7 @@ export declare const CARD_HEADER = "px-card py-card-sm border-b border-line";
|
|
|
113
113
|
/** The band below a card's content. CARD_HEADER's inset, with the rule on top. */
|
|
114
114
|
export declare const CARD_FOOTER = "px-card py-card-sm border-t border-line bg-surface-2/40";
|
|
115
115
|
/**
|
|
116
|
-
* A placeholder inside a card, where three spellings of the same
|
|
116
|
+
* A placeholder inside a card, where three spellings of the same centered muted
|
|
117
117
|
* line currently ship.
|
|
118
118
|
*
|
|
119
119
|
* An empty list is not an error, so it reads as muted body copy and not as a
|
|
@@ -132,7 +132,7 @@ export declare const CARD_EMPTY = "py-section text-center text-sm text-muted";
|
|
|
132
132
|
* near equal numbers, and 8px is the one the token scale names.
|
|
133
133
|
*/
|
|
134
134
|
export declare const TABLE_CELL_HEAD = "px-card-sm py-input-y text-xs font-medium uppercase tracking-wider whitespace-nowrap text-faint";
|
|
135
|
-
/** The body cell of a table. TABLE_CELL_HEAD's padding, at body weight and
|
|
135
|
+
/** The body cell of a table. TABLE_CELL_HEAD's padding, at body weight and color. */
|
|
136
136
|
export declare const TABLE_CELL_BODY = "px-card-sm py-input-y text-fg align-middle";
|
|
137
137
|
/**
|
|
138
138
|
* The gutter every modal surface uses. Modal paints 20px and Dialog paints
|
|
@@ -157,7 +157,7 @@ export declare const MODAL_PAD = "px-card py-card-sm";
|
|
|
157
157
|
* element is a decision about document structure and the treatment is not: an
|
|
158
158
|
* eyebrow appears at both levels. It went unnamed here while thirty of them
|
|
159
159
|
* shipped hand rolled across two apps in four different bottom margins, and a
|
|
160
|
-
* margin is exactly what this function must not carry
|
|
160
|
+
* margin is exactly what this function must not carry: the stack around the
|
|
161
161
|
* heading owns the distance to what follows.
|
|
162
162
|
*/
|
|
163
163
|
export declare function sectionHeading(level: 2 | 3, variant?: SectionVariant): string;
|
|
@@ -166,7 +166,7 @@ export declare function sectionHeading(level: 2 | 3, variant?: SectionVariant):
|
|
|
166
166
|
*
|
|
167
167
|
* Three apps hand rolled this and none of the three agreed. The sidebar was
|
|
168
168
|
* `w-56` in the admin and `w-60` in the other two, `bg-surface` in two and
|
|
169
|
-
* `bg-surface/30` in the third
|
|
169
|
+
* `bg-surface/30` in the third. The header existed in one and not in the other
|
|
170
170
|
* two. None of that was visible from inside any one app, which is why it went
|
|
171
171
|
* on being three shells for as long as it did.
|
|
172
172
|
*
|
|
@@ -178,7 +178,7 @@ export declare const APP_SIDEBAR = "h-full shrink-0 flex-col border-e border-lin
|
|
|
178
178
|
* The sidebar's two widths. Expanded is the 224px column every authed screen
|
|
179
179
|
* had. The rail is the 56px icon column the theme had named and nothing used:
|
|
180
180
|
* at 768px the expanded column left 496px for the page, and a flow editor with
|
|
181
|
-
* two docked panes had no canvas at all. The shell picks between them
|
|
181
|
+
* two docked panes had no canvas at all. The shell picks between them. The
|
|
182
182
|
* width is not part of APP_SIDEBAR so the aside cannot carry both.
|
|
183
183
|
*
|
|
184
184
|
* The travel between them is on APP_SIDEBAR, which is the one class both
|
package/dist/internal/layout.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* theme declares, `--spacing-control` was the one with any uses, and it had
|
|
16
16
|
* them because the field contract composes from it.
|
|
17
17
|
*
|
|
18
|
-
* Not exported from the package entry point
|
|
18
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
19
19
|
*/
|
|
20
20
|
/**
|
|
21
21
|
* The gutter a page sits in, stated once.
|
|
@@ -65,7 +65,7 @@ export const OVERLAY_WIDTH = {
|
|
|
65
65
|
full: 'max-w-overlay-full',
|
|
66
66
|
};
|
|
67
67
|
/**
|
|
68
|
-
* The rung a body of this many
|
|
68
|
+
* The rung a body of this many labeled fields needs.
|
|
69
69
|
*
|
|
70
70
|
* A panel is sized by its caller today, and the caller is guessing: all 18
|
|
71
71
|
* drawers measured across three consuming applications ask for the widest rung
|
|
@@ -129,7 +129,7 @@ export const CARD_HEADER = 'px-card py-card-sm border-b border-line';
|
|
|
129
129
|
/** The band below a card's content. CARD_HEADER's inset, with the rule on top. */
|
|
130
130
|
export const CARD_FOOTER = 'px-card py-card-sm border-t border-line bg-surface-2/40';
|
|
131
131
|
/**
|
|
132
|
-
* A placeholder inside a card, where three spellings of the same
|
|
132
|
+
* A placeholder inside a card, where three spellings of the same centered muted
|
|
133
133
|
* line currently ship.
|
|
134
134
|
*
|
|
135
135
|
* An empty list is not an error, so it reads as muted body copy and not as a
|
|
@@ -148,7 +148,7 @@ export const CARD_EMPTY = 'py-section text-center text-sm text-muted';
|
|
|
148
148
|
* near equal numbers, and 8px is the one the token scale names.
|
|
149
149
|
*/
|
|
150
150
|
export const TABLE_CELL_HEAD = 'px-card-sm py-input-y text-xs font-medium uppercase tracking-wider whitespace-nowrap text-faint';
|
|
151
|
-
/** The body cell of a table. TABLE_CELL_HEAD's padding, at body weight and
|
|
151
|
+
/** The body cell of a table. TABLE_CELL_HEAD's padding, at body weight and color. */
|
|
152
152
|
export const TABLE_CELL_BODY = 'px-card-sm py-input-y text-fg align-middle';
|
|
153
153
|
/**
|
|
154
154
|
* The gutter every modal surface uses. Modal paints 20px and Dialog paints
|
|
@@ -173,7 +173,7 @@ export const MODAL_PAD = 'px-card py-card-sm';
|
|
|
173
173
|
* element is a decision about document structure and the treatment is not: an
|
|
174
174
|
* eyebrow appears at both levels. It went unnamed here while thirty of them
|
|
175
175
|
* shipped hand rolled across two apps in four different bottom margins, and a
|
|
176
|
-
* margin is exactly what this function must not carry
|
|
176
|
+
* margin is exactly what this function must not carry: the stack around the
|
|
177
177
|
* heading owns the distance to what follows.
|
|
178
178
|
*/
|
|
179
179
|
export function sectionHeading(level, variant = 'default') {
|
|
@@ -200,7 +200,7 @@ export function sectionHeading(level, variant = 'default') {
|
|
|
200
200
|
*
|
|
201
201
|
* Three apps hand rolled this and none of the three agreed. The sidebar was
|
|
202
202
|
* `w-56` in the admin and `w-60` in the other two, `bg-surface` in two and
|
|
203
|
-
* `bg-surface/30` in the third
|
|
203
|
+
* `bg-surface/30` in the third. The header existed in one and not in the other
|
|
204
204
|
* two. None of that was visible from inside any one app, which is why it went
|
|
205
205
|
* on being three shells for as long as it did.
|
|
206
206
|
*
|
|
@@ -212,7 +212,7 @@ export const APP_SIDEBAR = 'h-full shrink-0 flex-col border-e border-line bg-sur
|
|
|
212
212
|
* The sidebar's two widths. Expanded is the 224px column every authed screen
|
|
213
213
|
* had. The rail is the 56px icon column the theme had named and nothing used:
|
|
214
214
|
* at 768px the expanded column left 496px for the page, and a flow editor with
|
|
215
|
-
* two docked panes had no canvas at all. The shell picks between them
|
|
215
|
+
* two docked panes had no canvas at all. The shell picks between them. The
|
|
216
216
|
* width is not part of APP_SIDEBAR so the aside cannot carry both.
|
|
217
217
|
*
|
|
218
218
|
* The travel between them is on APP_SIDEBAR, which is the one class both
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* it. A single-value control calls close('select') from its own onSelect, which
|
|
25
25
|
* is why that reason exists.
|
|
26
26
|
*
|
|
27
|
-
* Not exported from the package entry point
|
|
27
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
28
28
|
*/
|
|
29
29
|
/** The least a row has to be for the keyboard model to work on it. */
|
|
30
30
|
export interface ListboxItem {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* it. A single-value control calls close('select') from its own onSelect, which
|
|
25
25
|
* is why that reason exists.
|
|
26
26
|
*
|
|
27
|
-
* Not exported from the package entry point
|
|
27
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
28
28
|
*/
|
|
29
29
|
import { normalize } from './filter.js';
|
|
30
30
|
/**
|
|
@@ -251,7 +251,7 @@ export function createListbox(config) {
|
|
|
251
251
|
if (event.key === ' ' && typed === '')
|
|
252
252
|
return false;
|
|
253
253
|
// Date.now is a timestamp, not a timer: nothing is scheduled and nothing
|
|
254
|
-
// has to be
|
|
254
|
+
// has to be canceled when the control unmounts mid-run.
|
|
255
255
|
const now = Date.now();
|
|
256
256
|
typed = now - typedAt > TYPEAHEAD_WINDOW_MS ? event.key : typed + event.key;
|
|
257
257
|
typedAt = now;
|
|
@@ -307,7 +307,7 @@ export function createListbox(config) {
|
|
|
307
307
|
return true;
|
|
308
308
|
case 'Escape':
|
|
309
309
|
// Only an open list consumes Escape. Unstopped, one press closed both
|
|
310
|
-
// a listbox and the Modal holding it
|
|
310
|
+
// a listbox and the Modal holding it. Consumed while closed, Escape
|
|
311
311
|
// never reached the Modal at all.
|
|
312
312
|
if (!open)
|
|
313
313
|
return false;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* the tree and the path underneath them. A reader decision always wins, and
|
|
15
15
|
* until there is one the group follows the page.
|
|
16
16
|
*
|
|
17
|
-
* Not exported from the package entry point
|
|
17
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
18
18
|
*/
|
|
19
19
|
import { type NavTree } from './nav-tree.js';
|
|
20
20
|
export interface NavExpansionOptions {
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
* the tree and the path underneath them. A reader decision always wins, and
|
|
15
15
|
* until there is one the group follows the page.
|
|
16
16
|
*
|
|
17
|
-
* Not exported from the package entry point
|
|
17
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
18
18
|
*/
|
|
19
19
|
import { activeTrail, flattenNav } from './nav-tree.js';
|
|
20
20
|
/**
|
|
21
21
|
* localStorage is absent on the server and throws on access in a private
|
|
22
22
|
* window and wherever the reader has blocked site data, so it is reached for
|
|
23
|
-
* behind both a typeof guard and a catch. Expansion is a convenience
|
|
23
|
+
* behind both a typeof guard and a catch. Expansion is a convenience. Nothing
|
|
24
24
|
* here may be the reason a sidebar fails to render.
|
|
25
25
|
*/
|
|
26
26
|
function storage() {
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
* they are siblings and only one of them can be open.
|
|
15
15
|
*
|
|
16
16
|
* The fix is that prefix matching is a property of a node that owns a section,
|
|
17
|
-
* not of every node. A leaf answers for its own path and nothing below it
|
|
17
|
+
* not of every node. A leaf answers for its own path and nothing below it. A
|
|
18
18
|
* node with children answers for its whole subtree, because that is what makes
|
|
19
19
|
* an ancestor able to say "you are somewhere in here" while its child says
|
|
20
20
|
* "you are here". Either default is overridable per node, and 'none' opts a
|
|
21
21
|
* node out of path matching entirely.
|
|
22
22
|
*
|
|
23
|
-
* Not exported from the package entry point
|
|
23
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
24
24
|
*/
|
|
25
25
|
import type { Component } from 'svelte';
|
|
26
26
|
import type { AccentTone } from './tone.js';
|
|
@@ -47,7 +47,7 @@ export type NavTree = NavNode[];
|
|
|
47
47
|
/**
|
|
48
48
|
* True when this node is the current page.
|
|
49
49
|
*
|
|
50
|
-
* Path only. A disabled node still reports the truth about its href
|
|
50
|
+
* Path only. A disabled node still reports the truth about its href. Whether
|
|
51
51
|
* it is rendered as a link is a separate decision the component makes.
|
|
52
52
|
*/
|
|
53
53
|
export declare function isActive(node: NavNode, activePath: string): boolean;
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
* they are siblings and only one of them can be open.
|
|
15
15
|
*
|
|
16
16
|
* The fix is that prefix matching is a property of a node that owns a section,
|
|
17
|
-
* not of every node. A leaf answers for its own path and nothing below it
|
|
17
|
+
* not of every node. A leaf answers for its own path and nothing below it. A
|
|
18
18
|
* node with children answers for its whole subtree, because that is what makes
|
|
19
19
|
* an ancestor able to say "you are somewhere in here" while its child says
|
|
20
20
|
* "you are here". Either default is overridable per node, and 'none' opts a
|
|
21
21
|
* node out of path matching entirely.
|
|
22
22
|
*
|
|
23
|
-
* Not exported from the package entry point
|
|
23
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
24
24
|
*/
|
|
25
25
|
/**
|
|
26
26
|
* Trailing slashes are noise: a router hands over /settings on one route and
|
|
@@ -46,7 +46,7 @@ function matchMode(node) {
|
|
|
46
46
|
/**
|
|
47
47
|
* True when this node is the current page.
|
|
48
48
|
*
|
|
49
|
-
* Path only. A disabled node still reports the truth about its href
|
|
49
|
+
* Path only. A disabled node still reports the truth about its href. Whether
|
|
50
50
|
* it is rendered as a link is a separate decision the component makes.
|
|
51
51
|
*/
|
|
52
52
|
export function isActive(node, activePath) {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* and an English sentence carrying a German separator is the worse of the two
|
|
15
15
|
* inconsistencies.
|
|
16
16
|
*
|
|
17
|
-
* Not exported from the package entry point
|
|
17
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
18
18
|
*/
|
|
19
19
|
/**
|
|
20
20
|
* A count, grouped in threes.
|
package/dist/internal/number.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* and an English sentence carrying a German separator is the worse of the two
|
|
15
15
|
* inconsistencies.
|
|
16
16
|
*
|
|
17
|
-
* Not exported from the package entry point
|
|
17
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
18
18
|
*/
|
|
19
19
|
/**
|
|
20
20
|
* Built at module load, not per call.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The behavior every modal surface owes a keyboard and screen reader user.
|
|
3
3
|
*
|
|
4
4
|
* Dialog carried a correct implementation and Modal and Drawer carried none:
|
|
5
5
|
* both declared `aria-modal="true"` while leaving focus behind them in the
|
|
6
6
|
* page, so a screen reader user was told a modal had opened and then went on
|
|
7
7
|
* reading the document underneath it, and a keyboard user tabbed straight out
|
|
8
|
-
* of the panel with no way back. The
|
|
8
|
+
* of the panel with no way back. The behavior lives here now so a fourth
|
|
9
9
|
* overlay cannot ship without it.
|
|
10
10
|
*
|
|
11
|
-
* Not exported from the package entry point
|
|
11
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
12
12
|
*/
|
|
13
13
|
export declare function lockBodyScroll(): void;
|
|
14
14
|
export declare function unlockBodyScroll(): void;
|
package/dist/internal/overlay.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The behavior every modal surface owes a keyboard and screen reader user.
|
|
3
3
|
*
|
|
4
4
|
* Dialog carried a correct implementation and Modal and Drawer carried none:
|
|
5
5
|
* both declared `aria-modal="true"` while leaving focus behind them in the
|
|
6
6
|
* page, so a screen reader user was told a modal had opened and then went on
|
|
7
7
|
* reading the document underneath it, and a keyboard user tabbed straight out
|
|
8
|
-
* of the panel with no way back. The
|
|
8
|
+
* of the panel with no way back. The behavior lives here now so a fourth
|
|
9
9
|
* overlay cannot ship without it.
|
|
10
10
|
*
|
|
11
|
-
* Not exported from the package entry point
|
|
11
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
12
12
|
*/
|
|
13
13
|
/**
|
|
14
14
|
* Elements that can hold focus. `[tabindex="-1"]` is excluded because it is
|
package/dist/internal/panel.d.ts
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* sized to seven columns are different requirements. Everything else is here.
|
|
28
28
|
*
|
|
29
29
|
* Two rules hold these together. No row carries two utilities for the same
|
|
30
|
-
* property.
|
|
30
|
+
* property. Color and background sit on the surface, and a row states only
|
|
31
31
|
* the override its state earns, because two utilities for one property resolve
|
|
32
32
|
* in the order Tailwind emits them and not in the order they were written.
|
|
33
33
|
* And a row is inset and rounded, never square and full width: the surface is
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
* rounded-lg, so what a row paints stays inside the frame with corners of its
|
|
37
37
|
* own.
|
|
38
38
|
*
|
|
39
|
-
* Not exported from the package entry point
|
|
39
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
40
40
|
*/
|
|
41
41
|
/**
|
|
42
42
|
* The floating surface every popover paints.
|
|
43
43
|
*
|
|
44
44
|
* border-line-strong, not border-line: a panel floating over arbitrary content
|
|
45
45
|
* needs a boundary that clears 3:1, which line does not. It carries the
|
|
46
|
-
* resting text
|
|
46
|
+
* resting text color so a row can override it with a single utility.
|
|
47
47
|
*
|
|
48
48
|
* overflow-hidden is a backstop, not the shape: the rows sit inset with
|
|
49
49
|
* corners of their own, so nothing they paint reaches the rounded frame. It
|
|
@@ -67,7 +67,7 @@ export declare const PANEL_LIST = "max-h-panel-max overflow-y-auto overscroll-co
|
|
|
67
67
|
/**
|
|
68
68
|
* One row at rest.
|
|
69
69
|
*
|
|
70
|
-
* No background and no text
|
|
70
|
+
* No background and no text color of its own: it inherits both from the
|
|
71
71
|
* surface, which leaves each state below a single utility to override.
|
|
72
72
|
* rounded-lg, one step inside the surface's rounded-xl, so the hover tint and
|
|
73
73
|
* the active ring follow the row's own corners.
|
|
@@ -146,7 +146,7 @@ export declare const PANEL_ABOVE = "bottom-full mb-1 origin-bottom";
|
|
|
146
146
|
* <div class={PANEL_LIST} data-panel-list>
|
|
147
147
|
*
|
|
148
148
|
* The anchor is the surface's offset parent, the relative wrapper every
|
|
149
|
-
* control puts around its trigger
|
|
149
|
+
* control puts around its trigger. A DOM without layout has no offset parent,
|
|
150
150
|
* so the parent element stands in. Below is the default, because a list under
|
|
151
151
|
* its field is where a native select puts one. The panel goes above only when
|
|
152
152
|
* its natural height does not fit below and there is more room above, so a
|
package/dist/internal/panel.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* sized to seven columns are different requirements. Everything else is here.
|
|
28
28
|
*
|
|
29
29
|
* Two rules hold these together. No row carries two utilities for the same
|
|
30
|
-
* property.
|
|
30
|
+
* property. Color and background sit on the surface, and a row states only
|
|
31
31
|
* the override its state earns, because two utilities for one property resolve
|
|
32
32
|
* in the order Tailwind emits them and not in the order they were written.
|
|
33
33
|
* And a row is inset and rounded, never square and full width: the surface is
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
* rounded-lg, so what a row paints stays inside the frame with corners of its
|
|
37
37
|
* own.
|
|
38
38
|
*
|
|
39
|
-
* Not exported from the package entry point
|
|
39
|
+
* Not exported from the package entry point: this is an implementation detail.
|
|
40
40
|
*/
|
|
41
41
|
/**
|
|
42
42
|
* The floating surface every popover paints.
|
|
43
43
|
*
|
|
44
44
|
* border-line-strong, not border-line: a panel floating over arbitrary content
|
|
45
45
|
* needs a boundary that clears 3:1, which line does not. It carries the
|
|
46
|
-
* resting text
|
|
46
|
+
* resting text color so a row can override it with a single utility.
|
|
47
47
|
*
|
|
48
48
|
* overflow-hidden is a backstop, not the shape: the rows sit inset with
|
|
49
49
|
* corners of their own, so nothing they paint reaches the rounded frame. It
|
|
@@ -67,7 +67,7 @@ export const PANEL_LIST = 'max-h-panel-max overflow-y-auto overscroll-contain px
|
|
|
67
67
|
/**
|
|
68
68
|
* One row at rest.
|
|
69
69
|
*
|
|
70
|
-
* No background and no text
|
|
70
|
+
* No background and no text color of its own: it inherits both from the
|
|
71
71
|
* surface, which leaves each state below a single utility to override.
|
|
72
72
|
* rounded-lg, one step inside the surface's rounded-xl, so the hover tint and
|
|
73
73
|
* the active ring follow the row's own corners.
|
|
@@ -184,7 +184,7 @@ function swap(node, remove, add) {
|
|
|
184
184
|
* <div class={PANEL_LIST} data-panel-list>
|
|
185
185
|
*
|
|
186
186
|
* The anchor is the surface's offset parent, the relative wrapper every
|
|
187
|
-
* control puts around its trigger
|
|
187
|
+
* control puts around its trigger. A DOM without layout has no offset parent,
|
|
188
188
|
* so the parent element stands in. Below is the default, because a list under
|
|
189
189
|
* its field is where a native select puts one. The panel goes above only when
|
|
190
190
|
* its natural height does not fit below and there is more room above, so a
|
|
@@ -0,0 +1,110 @@
|
|
|
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
|
+
/** One sellable capability, as the catalog endpoint reports it. */
|
|
19
|
+
export interface CartPlugin {
|
|
20
|
+
sku: string;
|
|
21
|
+
name: string;
|
|
22
|
+
/** Integer cents, always. No float ever holds money here. */
|
|
23
|
+
price_cents: number;
|
|
24
|
+
category?: string;
|
|
25
|
+
blurb?: string;
|
|
26
|
+
/** `soon` is shown and cannot be bought. Anything else sells. */
|
|
27
|
+
status?: string;
|
|
28
|
+
}
|
|
29
|
+
/** One rung of the volume ladder. */
|
|
30
|
+
export interface DiscountBracket {
|
|
31
|
+
plugins: number;
|
|
32
|
+
discount_pct: number;
|
|
33
|
+
}
|
|
34
|
+
/** The catalog endpoint's whole answer. */
|
|
35
|
+
export interface CartCatalog {
|
|
36
|
+
plugins: CartPlugin[];
|
|
37
|
+
discount_brackets: DiscountBracket[];
|
|
38
|
+
}
|
|
39
|
+
/** One line of a priced cart. */
|
|
40
|
+
export interface CartQuoteItem {
|
|
41
|
+
sku: string;
|
|
42
|
+
name: string;
|
|
43
|
+
unit_cents: number;
|
|
44
|
+
discounted_cents: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The server's price for one selection. Rendered, never recomputed.
|
|
48
|
+
*
|
|
49
|
+
* `count` and `items` are here so a consumer can tell whether the quote it
|
|
50
|
+
* holds still describes what the reader has selected. A stale total beside a
|
|
51
|
+
* changed cart is the one failure this component cannot show its way out of.
|
|
52
|
+
*/
|
|
53
|
+
export interface CartQuote {
|
|
54
|
+
items: CartQuoteItem[];
|
|
55
|
+
count: number;
|
|
56
|
+
subtotal_cents: number;
|
|
57
|
+
volume_discount_pct: number;
|
|
58
|
+
volume_discount_cents: number;
|
|
59
|
+
community_discount_pct: number;
|
|
60
|
+
community_discount_cents: number;
|
|
61
|
+
total_cents: number;
|
|
62
|
+
/** A year at ten months' price. Zero on a monthly quote. */
|
|
63
|
+
annual_total_cents?: number;
|
|
64
|
+
}
|
|
65
|
+
export type BillingPeriod = 'monthly' | 'annual';
|
|
66
|
+
/** Where a selection stands on the ladder, and what the next rung is worth. */
|
|
67
|
+
export interface LadderState {
|
|
68
|
+
/** The plugin count the ladder was read at. */
|
|
69
|
+
count: number;
|
|
70
|
+
/** The discount that count has reached. */
|
|
71
|
+
reachedPct: number;
|
|
72
|
+
/** The first rung above the count worth more than the one reached. */
|
|
73
|
+
next: {
|
|
74
|
+
plugins: number;
|
|
75
|
+
discount_pct: number;
|
|
76
|
+
more: number;
|
|
77
|
+
} | null;
|
|
78
|
+
/** Index of the rung the count stands on, ascending, or -1 below the first. */
|
|
79
|
+
active: number;
|
|
80
|
+
}
|
|
81
|
+
export declare function ladderState(brackets: DiscountBracket[], count: number): LadderState;
|
|
82
|
+
/**
|
|
83
|
+
* How many capabilities the bill will carry.
|
|
84
|
+
*
|
|
85
|
+
* For a new cart that is what is selected. For a change to a live
|
|
86
|
+
* subscription it is what is held as well, because that is the count the
|
|
87
|
+
* server prices the change at. Reading the cart alone put a subscriber on the
|
|
88
|
+
* list-price rung beside a total that had already taken the discount.
|
|
89
|
+
*/
|
|
90
|
+
export declare function billedCount(opts: {
|
|
91
|
+
selected: Iterable<string>;
|
|
92
|
+
held?: Iterable<string>;
|
|
93
|
+
change?: boolean;
|
|
94
|
+
pricedSkus?: string[] | null;
|
|
95
|
+
}): number;
|
|
96
|
+
/** One row per rung, labeled by the range it covers. */
|
|
97
|
+
export declare function ladderRows(brackets: DiscountBracket[]): {
|
|
98
|
+
from: number;
|
|
99
|
+
to: number | null;
|
|
100
|
+
discount_pct: number;
|
|
101
|
+
}[];
|
|
102
|
+
/**
|
|
103
|
+
* Money, for display.
|
|
104
|
+
*
|
|
105
|
+
* The locale is fixed for the reason `number.ts` states: a server and the
|
|
106
|
+
* browser that hydrates its output do not have to report the same one, and a
|
|
107
|
+
* figure that changes under the reader is worse than one that is not local to
|
|
108
|
+
* them.
|
|
109
|
+
*/
|
|
110
|
+
export declare function formatCents(cents: number, currency?: string): string;
|