zabi-components 8.1.0 → 9.0.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/CHANGELOG.md +1011 -0
- package/README.md +1 -1
- package/THEME.md +18 -5
- package/THEMING.md +308 -74
- package/dist/atoms/ActionPanel.svelte +1 -1
- package/dist/atoms/Avatar.svelte +19 -3
- package/dist/atoms/Avatar.svelte.d.ts +12 -0
- package/dist/atoms/Badge.svelte +37 -8
- package/dist/atoms/Badge.svelte.d.ts +6 -0
- package/dist/atoms/Block.svelte +74 -0
- package/dist/atoms/Block.svelte.d.ts +29 -0
- package/dist/atoms/Button.svelte +52 -15
- package/dist/atoms/Button.svelte.d.ts +3 -2
- package/dist/atoms/Card.svelte +181 -25
- package/dist/atoms/Card.svelte.d.ts +55 -3
- package/dist/atoms/Checkbox.svelte +33 -0
- package/dist/atoms/Checkbox.svelte.d.ts +27 -0
- package/dist/atoms/Chip.svelte +351 -0
- package/dist/atoms/Chip.svelte.d.ts +57 -0
- package/dist/atoms/CodeField.svelte +385 -0
- package/dist/atoms/CodeField.svelte.d.ts +61 -0
- package/dist/atoms/ColorPicker.svelte +1 -0
- package/dist/atoms/DateField.svelte +41 -3
- package/dist/atoms/DateField.svelte.d.ts +31 -3
- package/dist/atoms/FloatingActionButton.svelte +5 -3
- package/dist/atoms/FloatingActionButton.svelte.d.ts +1 -1
- package/dist/atoms/Heading.svelte +27 -1
- package/dist/atoms/Heading.svelte.d.ts +7 -0
- package/dist/atoms/IconButton.svelte +81 -9
- package/dist/atoms/IconButton.svelte.d.ts +13 -0
- package/dist/atoms/Input.svelte +10 -5
- package/dist/atoms/Input.svelte.d.ts +3 -2
- package/dist/atoms/List.svelte +3 -2
- package/dist/atoms/ListItem.svelte +31 -7
- package/dist/atoms/ListItem.svelte.d.ts +6 -0
- package/dist/atoms/PickerField.svelte +239 -0
- package/dist/atoms/PickerField.svelte.d.ts +67 -0
- package/dist/atoms/Progress.svelte +78 -17
- package/dist/atoms/Progress.svelte.d.ts +11 -1
- package/dist/atoms/Radio.svelte +32 -0
- package/dist/atoms/Radio.svelte.d.ts +26 -0
- package/dist/atoms/Rating.svelte +132 -6
- package/dist/atoms/Rating.svelte.d.ts +24 -3
- package/dist/atoms/Select.svelte +24 -26
- package/dist/atoms/Select.svelte.d.ts +12 -0
- package/dist/atoms/SelectionControl.svelte +99 -6
- package/dist/atoms/SelectionControl.svelte.d.ts +25 -0
- package/dist/atoms/Skeleton.svelte +114 -18
- package/dist/atoms/Skeleton.svelte.d.ts +30 -3
- package/dist/atoms/SkeletonGroup.svelte +43 -0
- package/dist/atoms/SkeletonGroup.svelte.d.ts +20 -0
- package/dist/atoms/Slider.svelte +35 -0
- package/dist/atoms/Sparkline.svelte +109 -0
- package/dist/atoms/Sparkline.svelte.d.ts +27 -0
- package/dist/atoms/SpeechBubble.svelte +187 -0
- package/dist/atoms/SpeechBubble.svelte.d.ts +33 -0
- package/dist/atoms/Stat.svelte +72 -0
- package/dist/atoms/Stat.svelte.d.ts +19 -0
- package/dist/atoms/TemporalField.svelte +342 -10
- package/dist/atoms/TemporalField.svelte.d.ts +20 -4
- package/dist/atoms/Textarea.svelte +100 -5
- package/dist/atoms/Textarea.svelte.d.ts +21 -0
- package/dist/atoms/TimeColumn.svelte +150 -0
- package/dist/atoms/TimeColumn.svelte.d.ts +25 -0
- package/dist/atoms/TimeField.svelte +46 -3
- package/dist/atoms/TimeField.svelte.d.ts +34 -3
- package/dist/atoms/Toast.svelte +6 -5
- package/dist/atoms/Toggle.svelte +61 -10
- package/dist/atoms/Toggle.svelte.d.ts +15 -0
- package/dist/atoms/Tooltip.svelte +20 -1
- package/dist/atoms/Tooltip.svelte.d.ts +7 -0
- package/dist/atoms/index.d.ts +21 -0
- package/dist/atoms/index.js +17 -0
- package/dist/atoms/selection-control.styles.d.ts +15 -4
- package/dist/atoms/selection-control.styles.js +16 -5
- package/dist/components/atoms/index.d.ts +21 -0
- package/dist/components/atoms/index.d.ts.map +1 -1
- package/dist/components/atoms/selection-control.styles.d.ts +15 -4
- package/dist/components/atoms/selection-control.styles.d.ts.map +1 -1
- package/dist/components/index.d.ts +27 -3
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/map.d.ts +11 -0
- package/dist/components/map.d.ts.map +1 -0
- package/dist/components/molecules/index.d.ts +7 -2
- package/dist/components/molecules/index.d.ts.map +1 -1
- package/dist/components/molecules/toast-store.d.ts +30 -0
- package/dist/components/molecules/toast-store.d.ts.map +1 -1
- package/dist/components/organisms/index.d.ts +6 -1
- package/dist/components/organisms/index.d.ts.map +1 -1
- package/dist/components/types/variants.d.ts +12 -3
- package/dist/components/types/variants.d.ts.map +1 -1
- package/dist/components/util/app-shell.d.ts +55 -4
- package/dist/components/util/app-shell.d.ts.map +1 -1
- package/dist/components/util/avatar.d.ts +3 -0
- package/dist/components/util/avatar.d.ts.map +1 -1
- package/dist/components/util/bottom-tab-bar.d.ts +6 -0
- package/dist/components/util/bottom-tab-bar.d.ts.map +1 -1
- package/dist/components/util/chart.d.ts +140 -0
- package/dist/components/util/chart.d.ts.map +1 -0
- package/dist/components/util/chip.d.ts +66 -0
- package/dist/components/util/chip.d.ts.map +1 -0
- package/dist/components/util/cn.d.ts.map +1 -1
- package/dist/components/util/code-field.d.ts +63 -0
- package/dist/components/util/code-field.d.ts.map +1 -0
- package/dist/components/util/collapsible.d.ts +6 -0
- package/dist/components/util/collapsible.d.ts.map +1 -1
- package/dist/components/util/display-voice.d.ts +10 -0
- package/dist/components/util/display-voice.d.ts.map +1 -0
- package/dist/components/util/field-control.d.ts +30 -0
- package/dist/components/util/field-control.d.ts.map +1 -0
- package/dist/components/util/field.d.ts +6 -0
- package/dist/components/util/field.d.ts.map +1 -1
- package/dist/components/util/focus-utils.d.ts +2 -0
- package/dist/components/util/focus-utils.d.ts.map +1 -1
- package/dist/components/util/map-view.d.ts +144 -0
- package/dist/components/util/map-view.d.ts.map +1 -0
- package/dist/components/util/photo.d.ts +19 -0
- package/dist/components/util/photo.d.ts.map +1 -1
- package/dist/components/util/progress.d.ts +19 -0
- package/dist/components/util/progress.d.ts.map +1 -0
- package/dist/components/util/scroll-edge.d.ts +33 -0
- package/dist/components/util/scroll-edge.d.ts.map +1 -0
- package/dist/components/util/sheet-drag.d.ts +25 -1
- package/dist/components/util/sheet-drag.d.ts.map +1 -1
- package/dist/components/util/skeleton.d.ts +15 -0
- package/dist/components/util/skeleton.d.ts.map +1 -0
- package/dist/components/util/sliding-indicator.d.ts +25 -0
- package/dist/components/util/sliding-indicator.d.ts.map +1 -0
- package/dist/components/util/temporal-field.d.ts +89 -0
- package/dist/components/util/temporal-field.d.ts.map +1 -0
- package/dist/components/util/toaster.d.ts +40 -0
- package/dist/components/util/toaster.d.ts.map +1 -1
- package/dist/components/util/tone-surface.d.ts +34 -0
- package/dist/components/util/tone-surface.d.ts.map +1 -0
- package/dist/components/util/top-navbar.d.ts +26 -2
- package/dist/components/util/top-navbar.d.ts.map +1 -1
- package/dist/components/util/zabi-strings.d.ts +9 -0
- package/dist/components/util/zabi-strings.d.ts.map +1 -1
- package/dist/create-theme/cli.js +6 -2
- package/dist/create-theme/index.d.ts +17 -3
- package/dist/create-theme/index.js +252 -35
- package/dist/create-theme/lib/resolve.js +97 -0
- package/dist/create-theme/theme-data.js +1618 -90
- package/dist/index.d.ts +27 -3
- package/dist/index.js +18 -0
- package/dist/map.d.ts +10 -0
- package/dist/map.js +9 -0
- package/dist/molecules/Alert.svelte +31 -12
- package/dist/molecules/Alert.svelte.d.ts +12 -1
- package/dist/molecules/AppBar.svelte +287 -28
- package/dist/molecules/AppBar.svelte.d.ts +62 -0
- package/dist/molecules/AvatarGroup.svelte +1 -1
- package/dist/molecules/BarChart.svelte +381 -0
- package/dist/molecules/BarChart.svelte.d.ts +45 -0
- package/dist/molecules/BottomSheet.svelte +88 -20
- package/dist/molecules/BottomSheet.svelte.d.ts +17 -1
- package/dist/molecules/BottomTabBar.svelte +134 -28
- package/dist/molecules/BottomTabBar.svelte.d.ts +36 -2
- package/dist/molecules/Calendar.svelte.d.ts +1 -1
- package/dist/molecules/ChipGroup.svelte +325 -0
- package/dist/molecules/ChipGroup.svelte.d.ts +41 -0
- package/dist/molecules/Collapsible.svelte +158 -54
- package/dist/molecules/Collapsible.svelte.d.ts +23 -6
- package/dist/molecules/CollapsibleGroup.svelte +16 -6
- package/dist/molecules/ConfirmDialog.svelte +5 -1
- package/dist/molecules/ConfirmDialog.svelte.d.ts +3 -0
- package/dist/molecules/Drawer.svelte +33 -12
- package/dist/molecules/Dropdown.svelte +9 -1
- package/dist/molecules/Dropdown.svelte.d.ts +2 -0
- package/dist/molecules/DropdownItem.svelte +1 -1
- package/dist/molecules/ImageUpload.svelte +230 -120
- package/dist/molecules/ImageUpload.svelte.d.ts +38 -3
- package/dist/molecules/LineChart.svelte +459 -0
- package/dist/molecules/LineChart.svelte.d.ts +53 -0
- package/dist/molecules/MapView.svelte +565 -0
- package/dist/molecules/MapView.svelte.d.ts +88 -0
- package/dist/molecules/Modal.svelte +11 -6
- package/dist/molecules/PhotoGrid.svelte +100 -10
- package/dist/molecules/PhotoGrid.svelte.d.ts +11 -0
- package/dist/molecules/PhotoViewer.svelte +121 -24
- package/dist/molecules/PhotoViewer.svelte.d.ts +18 -0
- package/dist/molecules/PieChart.svelte +421 -0
- package/dist/molecules/PieChart.svelte.d.ts +51 -0
- package/dist/molecules/RadioGroup.svelte +20 -4
- package/dist/molecules/RadioGroup.svelte.d.ts +5 -0
- package/dist/molecules/SegmentedControl.svelte +136 -3
- package/dist/molecules/SegmentedControl.svelte.d.ts +6 -0
- package/dist/molecules/SidebarFooter.svelte +1 -1
- package/dist/molecules/SidebarNavSection.svelte +1 -1
- package/dist/molecules/SortableList.svelte +1 -0
- package/dist/molecules/Stepper.svelte +21 -7
- package/dist/molecules/StickyActionBar.svelte +67 -8
- package/dist/molecules/StickyActionBar.svelte.d.ts +14 -1
- package/dist/molecules/Tabs.svelte +79 -2
- package/dist/molecules/Toaster.svelte +171 -7
- package/dist/molecules/Toaster.svelte.d.ts +60 -2
- package/dist/molecules/ToasterToast.svelte +292 -60
- package/dist/molecules/ToasterToast.svelte.d.ts +6 -0
- package/dist/molecules/UnsavedChangesBar.svelte +13 -2
- package/dist/molecules/index.d.ts +7 -2
- package/dist/molecules/index.js +4 -0
- package/dist/molecules/toast-store.d.ts +30 -0
- package/dist/molecules/toast-store.js +4 -1
- package/dist/organisms/AppNavigation.svelte +440 -0
- package/dist/organisms/AppNavigation.svelte.d.ts +72 -0
- package/dist/organisms/AppShell.svelte +539 -39
- package/dist/organisms/AppShell.svelte.d.ts +102 -6
- package/dist/organisms/AppShellHeaderPart.svelte +163 -0
- package/dist/organisms/AppShellHeaderPart.svelte.d.ts +57 -0
- package/dist/organisms/SidebarNavigation.svelte +23 -36
- package/dist/organisms/SidebarPanel.svelte +10 -14
- package/dist/organisms/SidebarPanel.svelte.d.ts +1 -0
- package/dist/organisms/SidebarShell.svelte +2 -3
- package/dist/organisms/TopNavbar.svelte +117 -28
- package/dist/organisms/TopNavbar.svelte.d.ts +22 -1
- package/dist/organisms/TopNavbarSheetContent.svelte +145 -0
- package/dist/organisms/TopNavbarSheetContent.svelte.d.ts +24 -0
- package/dist/organisms/index.d.ts +6 -1
- package/dist/organisms/index.js +4 -0
- package/dist/types/components.d.ts +17 -1
- package/dist/types/components.d.ts.map +1 -1
- package/dist/types/index.d.ts +497 -10
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/variants.ts +14 -3
- package/dist/util/app-shell.d.ts +55 -4
- package/dist/util/app-shell.js +32 -7
- package/dist/util/avatar.d.ts +3 -0
- package/dist/util/bottom-tab-bar.d.ts +6 -0
- package/dist/util/chart.d.ts +139 -0
- package/dist/util/chart.js +305 -0
- package/dist/util/chip.d.ts +65 -0
- package/dist/util/chip.js +58 -0
- package/dist/util/cn.js +28 -2
- package/dist/util/code-field.d.ts +62 -0
- package/dist/util/code-field.js +112 -0
- package/dist/util/collapsible.d.ts +6 -0
- package/dist/util/display-voice.d.ts +9 -0
- package/dist/util/display-voice.js +9 -0
- package/dist/util/field-control.d.ts +29 -0
- package/dist/util/field-control.js +32 -0
- package/dist/util/field.d.ts +6 -0
- package/dist/util/focus-utils.d.ts +2 -0
- package/dist/util/focus-utils.js +4 -0
- package/dist/util/map-view.d.ts +143 -0
- package/dist/util/map-view.js +121 -0
- package/dist/util/photo.d.ts +19 -0
- package/dist/util/photo.js +3 -0
- package/dist/util/progress.d.ts +18 -0
- package/dist/util/progress.js +17 -0
- package/dist/util/scroll-edge.d.ts +32 -0
- package/dist/util/scroll-edge.js +87 -0
- package/dist/util/sheet-drag.d.ts +25 -1
- package/dist/util/sheet-drag.js +71 -1
- package/dist/util/skeleton.d.ts +14 -0
- package/dist/util/skeleton.js +22 -0
- package/dist/util/sliding-indicator.d.ts +24 -0
- package/dist/util/sliding-indicator.js +44 -0
- package/dist/util/temporal-field.d.ts +88 -0
- package/dist/util/temporal-field.js +136 -0
- package/dist/util/toaster.d.ts +40 -0
- package/dist/util/toaster.js +55 -0
- package/dist/util/tone-surface.d.ts +33 -0
- package/dist/util/tone-surface.js +35 -0
- package/dist/util/top-navbar.d.ts +26 -2
- package/dist/util/top-navbar.js +23 -0
- package/dist/util/zabi-strings.d.ts +9 -0
- package/dist/zabi-components-colors.css +9 -3
- package/dist/zabi-components-theme-dark-only.css +474 -164
- package/dist/zabi-components-theme-dark.css +474 -164
- package/dist/zabi-components-theme-only.css +933 -99
- package/dist/zabi-components-theme.css +933 -99
- package/dist/zabi-components.css +2275 -321
- package/package.json +11 -1
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
import { type Snippet } from "svelte";
|
|
2
2
|
import type { HTMLAttributes } from "svelte/elements";
|
|
3
3
|
import { type CollapsibleHeadingLevel, type CollapsibleTriggerProps, type CollapsibleTriggerState } from "../util/collapsible.js";
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* A trigger, then a panel of its own that it opens. It is not for a "show
|
|
6
|
+
* all" under a list: there the control comes after the content, and what
|
|
7
|
+
* it shows is more items of a list that is already on the screen. For
|
|
8
|
+
* that, put a `Button` with `aria-expanded` and `aria-controls` under the
|
|
9
|
+
* list and let the list draw the rest (Z-127).
|
|
10
|
+
*
|
|
11
|
+
* Other attributes (`id`, `data-*`, ...) land on the host `<div>`.
|
|
12
|
+
*/
|
|
5
13
|
type Props = Omit<HTMLAttributes<HTMLDivElement>, "class" | "title"> & {
|
|
6
14
|
/** Extra classes for the host element. */
|
|
7
15
|
class?: string;
|
|
8
|
-
/** Extra classes for the default trigger
|
|
16
|
+
/** Extra classes for the default trigger (a `<summary>`). */
|
|
9
17
|
triggerClass?: string;
|
|
10
18
|
/** Extra classes for the panel. */
|
|
11
19
|
panelClass?: string;
|
|
@@ -18,18 +26,27 @@ type Props = Omit<HTMLAttributes<HTMLDivElement>, "class" | "title"> & {
|
|
|
18
26
|
* a group does not close a disabled panel either.
|
|
19
27
|
*/
|
|
20
28
|
disabled?: boolean;
|
|
21
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* Text of the default trigger, a full-width header with a chevron. It is
|
|
31
|
+
* a native `<details>` / `<summary>`, so it opens and closes without
|
|
32
|
+
* scripts: before hydration, and for a visitor who has none.
|
|
33
|
+
*/
|
|
22
34
|
title?: string;
|
|
23
35
|
/**
|
|
24
36
|
* Your own header, in place of the default trigger. Spread the first
|
|
25
|
-
* argument on a `<button>`; the second carries the open state.
|
|
37
|
+
* argument on a `<button>`; the second carries the open state. This
|
|
38
|
+
* path needs scripts: the button and the `hidden` panel are yours to
|
|
39
|
+
* wire, and nothing opens until the page has hydrated. Use `title` for
|
|
40
|
+
* content that must open without scripts.
|
|
26
41
|
*/
|
|
27
42
|
trigger?: Snippet<[CollapsibleTriggerProps, CollapsibleTriggerState]>;
|
|
28
43
|
/** Wraps the default trigger in `<h1>`–`<h6>`. No heading when omitted. */
|
|
29
44
|
headingLevel?: CollapsibleHeadingLevel;
|
|
30
45
|
/**
|
|
31
|
-
* Closed content
|
|
32
|
-
* keeps its values
|
|
46
|
+
* Closed content stays in the DOM, inside the closed `<details>`, so a
|
|
47
|
+
* form inside it keeps its values and still submits them: closed
|
|
48
|
+
* details content is part of the form. Set this to remove the content
|
|
49
|
+
* while closed instead.
|
|
33
50
|
*/
|
|
34
51
|
unmountOnClose?: boolean;
|
|
35
52
|
/**
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { setContext, untrack, type Snippet } from "svelte";
|
|
3
3
|
import type { HTMLAttributes } from "svelte/elements";
|
|
4
4
|
import { cn } from "../util/cn.js";
|
|
5
|
+
import { generateId } from "../util/ssr-safe.js";
|
|
5
6
|
import {
|
|
6
7
|
COLLAPSIBLE_GROUP,
|
|
7
8
|
nextTriggerIndex,
|
|
@@ -29,6 +30,9 @@
|
|
|
29
30
|
|
|
30
31
|
let hostElement: HTMLDivElement | undefined = $state();
|
|
31
32
|
|
|
33
|
+
/** Names the native exclusive accordion of a single-open group. */
|
|
34
|
+
const exclusiveName = generateId("collapsible-group");
|
|
35
|
+
|
|
32
36
|
/** In the order the Collapsibles were created. */
|
|
33
37
|
const members = new Set<CollapsibleGroupMember>();
|
|
34
38
|
|
|
@@ -47,6 +51,9 @@
|
|
|
47
51
|
get multiple() {
|
|
48
52
|
return multiple;
|
|
49
53
|
},
|
|
54
|
+
get exclusiveName() {
|
|
55
|
+
return multiple ? undefined : exclusiveName;
|
|
56
|
+
},
|
|
50
57
|
register(member) {
|
|
51
58
|
// Settled here, while the members initialise, so the first render
|
|
52
59
|
// (the server's included) already shows one open panel.
|
|
@@ -91,16 +98,19 @@
|
|
|
91
98
|
if (!ids.has(target.id)) return;
|
|
92
99
|
|
|
93
100
|
// Read from the DOM so the order is the visual one. A disabled button
|
|
94
|
-
// cannot take focus, so it is skipped.
|
|
101
|
+
// (or a summary marked `aria-disabled`) cannot take focus, so it is skipped.
|
|
95
102
|
const triggers = Array.from(
|
|
96
|
-
hostElement.querySelectorAll<
|
|
97
|
-
|
|
98
|
-
)
|
|
99
|
-
|
|
103
|
+
hostElement.querySelectorAll<HTMLElement>("[data-collapsible-trigger]"),
|
|
104
|
+
).filter(
|
|
105
|
+
(element) =>
|
|
106
|
+
ids.has(element.id) &&
|
|
107
|
+
!(element as HTMLButtonElement).disabled &&
|
|
108
|
+
element.getAttribute("aria-disabled") !== "true",
|
|
109
|
+
);
|
|
100
110
|
|
|
101
111
|
const next = nextTriggerIndex(
|
|
102
112
|
event.key,
|
|
103
|
-
triggers.indexOf(target
|
|
113
|
+
triggers.indexOf(target),
|
|
104
114
|
triggers.length,
|
|
105
115
|
);
|
|
106
116
|
if (next === null) return;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
ConfirmDialogResult,
|
|
14
14
|
ConfirmDialogVariant,
|
|
15
15
|
} from "../util/confirm-dialog.js";
|
|
16
|
+
import type { ButtonVariant } from "../types/variants.js";
|
|
16
17
|
|
|
17
18
|
interface Props {
|
|
18
19
|
/** Whether the dialog is shown; supports `bind:open`. */
|
|
@@ -25,6 +26,8 @@
|
|
|
25
26
|
variant?: ConfirmDialogVariant;
|
|
26
27
|
confirmLabel?: string;
|
|
27
28
|
cancelLabel?: string;
|
|
29
|
+
/** The `Button` variant of the cancel button: `tonal` or `ghost` for an app that has no outline button. */
|
|
30
|
+
cancelVariant?: ButtonVariant;
|
|
28
31
|
/**
|
|
29
32
|
* The confirm button shows its loading state, cancel is disabled and
|
|
30
33
|
* the dialog cannot be dismissed. Set by the dialog itself while a
|
|
@@ -70,6 +73,7 @@
|
|
|
70
73
|
variant = "info",
|
|
71
74
|
confirmLabel: confirmLabelGiven,
|
|
72
75
|
cancelLabel: cancelLabelGiven,
|
|
76
|
+
cancelVariant = "outline",
|
|
73
77
|
loading = false,
|
|
74
78
|
loadingLabel = "Working…",
|
|
75
79
|
onconfirm,
|
|
@@ -234,7 +238,7 @@
|
|
|
234
238
|
|
|
235
239
|
{#snippet footer()}
|
|
236
240
|
<Button
|
|
237
|
-
variant=
|
|
241
|
+
variant={cancelVariant}
|
|
238
242
|
disabled={busy}
|
|
239
243
|
onclick={() => cancel("cancel-button")}
|
|
240
244
|
data-confirm-dialog-cancel=""
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Snippet } from "svelte";
|
|
2
2
|
import type { ConfirmDialogCancelReason, ConfirmDialogResult, ConfirmDialogVariant } from "../util/confirm-dialog.js";
|
|
3
|
+
import type { ButtonVariant } from "../types/variants.js";
|
|
3
4
|
interface Props {
|
|
4
5
|
/** Whether the dialog is shown; supports `bind:open`. */
|
|
5
6
|
open?: boolean;
|
|
@@ -11,6 +12,8 @@ interface Props {
|
|
|
11
12
|
variant?: ConfirmDialogVariant;
|
|
12
13
|
confirmLabel?: string;
|
|
13
14
|
cancelLabel?: string;
|
|
15
|
+
/** The `Button` variant of the cancel button: `tonal` or `ghost` for an app that has no outline button. */
|
|
16
|
+
cancelVariant?: ButtonVariant;
|
|
14
17
|
/**
|
|
15
18
|
* The confirm button shows its loading state, cancel is disabled and
|
|
16
19
|
* the dialog cannot be dismissed. Set by the dialog itself while a
|
|
@@ -121,6 +121,7 @@
|
|
|
121
121
|
applyDefaults();
|
|
122
122
|
$effect.pre(applyDefaults);
|
|
123
123
|
|
|
124
|
+
// Used only where --duration-moderate cannot be read.
|
|
124
125
|
const SLIDE_MS = 200;
|
|
125
126
|
|
|
126
127
|
const titleId = generateId("drawer-title");
|
|
@@ -159,14 +160,14 @@
|
|
|
159
160
|
}[size] ?? "w-[min(100%,28rem)]",
|
|
160
161
|
);
|
|
161
162
|
|
|
162
|
-
/** The
|
|
163
|
+
/** The edge the panel is attached to. The rim comes from the material. */
|
|
163
164
|
const sideClasses = $derived(
|
|
164
165
|
{
|
|
165
|
-
"left": "left-0
|
|
166
|
-
"right": "right-0
|
|
167
|
-
"start": "start-0
|
|
168
|
-
"end": "end-0
|
|
169
|
-
}[side] ?? "right-0
|
|
166
|
+
"left": "left-0",
|
|
167
|
+
"right": "right-0",
|
|
168
|
+
"start": "start-0",
|
|
169
|
+
"end": "end-0",
|
|
170
|
+
}[side] ?? "right-0",
|
|
170
171
|
);
|
|
171
172
|
|
|
172
173
|
function close(reason: DrawerCloseReason) {
|
|
@@ -179,6 +180,14 @@
|
|
|
179
180
|
onclose?.({ reason });
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
/** `200ms`, `0.2s` or `0s` to milliseconds; the fallback when it is not a time. */
|
|
184
|
+
function parseDuration(value: string): number {
|
|
185
|
+
const match = /^\s*(-?\d*\.?\d+)(ms|s)\s*$/.exec(value);
|
|
186
|
+
if (!match) return SLIDE_MS;
|
|
187
|
+
const ms = parseFloat(match[1]) * (match[2] === "s" ? 1000 : 1);
|
|
188
|
+
return ms >= 0 ? ms : SLIDE_MS;
|
|
189
|
+
}
|
|
190
|
+
|
|
182
191
|
/** Slides the panel in from its edge. Skipped where motion is unwanted or unsupported. */
|
|
183
192
|
function slideIn(container: HTMLElement) {
|
|
184
193
|
if (typeof container.animate !== "function") return;
|
|
@@ -190,10 +199,16 @@
|
|
|
190
199
|
}
|
|
191
200
|
const rtl = getComputedStyle(container).direction === "rtl";
|
|
192
201
|
const from = resolveDrawerEdge(side, rtl) === "left" ? "-100%" : "100%";
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
);
|
|
202
|
+
// Read from the element so a theme that overrides the tokens is followed.
|
|
203
|
+
const style = getComputedStyle(container);
|
|
204
|
+
const duration = parseDuration(style.getPropertyValue("--duration-moderate"));
|
|
205
|
+
const easing = style.getPropertyValue("--ease-out").trim() || "ease-out";
|
|
206
|
+
const frames = [{ transform: `translateX(${from})` }, { transform: "translateX(0)" }];
|
|
207
|
+
try {
|
|
208
|
+
container.animate(frames, { duration, easing });
|
|
209
|
+
} catch {
|
|
210
|
+
container.animate(frames, { duration, easing: "ease-out" });
|
|
211
|
+
}
|
|
197
212
|
}
|
|
198
213
|
|
|
199
214
|
$effect(() => {
|
|
@@ -296,8 +311,11 @@
|
|
|
296
311
|
|
|
297
312
|
{#if isOpen}
|
|
298
313
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
314
|
+
<!-- `overflow-clip`, not `hidden` (as in BottomSheet): a clipped box is a
|
|
315
|
+
scroll container nobody can scroll, and WebKit scrolls one to a focused
|
|
316
|
+
element while the panel is still off screen. -->
|
|
299
317
|
<div
|
|
300
|
-
class="group/overlay fixed inset-0 z-modal overflow-
|
|
318
|
+
class="group/overlay fixed inset-0 z-modal overflow-clip {dismissible ? 'cursor-pointer' : 'cursor-default'} bg-overlay"
|
|
301
319
|
style:z-index={depth > 0 ? `calc(var(--z-modal) + ${depth})` : undefined}
|
|
302
320
|
data-overlay-depth={depth}
|
|
303
321
|
use:portalTo={portal}
|
|
@@ -308,7 +326,10 @@
|
|
|
308
326
|
<div
|
|
309
327
|
bind:this={panel}
|
|
310
328
|
class={cn(
|
|
311
|
-
|
|
329
|
+
// The glass is a layer behind the content (`::before`), not a filter on
|
|
330
|
+
// the panel: a backdrop-filter would make the panel the containing
|
|
331
|
+
// block of every fixed-position popover inside it.
|
|
332
|
+
"material-layer-thick absolute inset-y-0 flex cursor-default flex-col",
|
|
312
333
|
// Above the home indicator: the last row, or the footer, ends
|
|
313
334
|
// where a finger can reach it. Over a keyboard that is under
|
|
314
335
|
// the keyboard.
|
|
@@ -60,6 +60,8 @@
|
|
|
60
60
|
* to six `options`, all of it for more. The grip moves it either way.
|
|
61
61
|
*/
|
|
62
62
|
sheetSnap?: BottomSheetSnap;
|
|
63
|
+
/** The sheet is as tall as the list, up to half the screen (BottomSheet `fit`); the grip then only drags. Off by default. */
|
|
64
|
+
sheetFit?: boolean;
|
|
63
65
|
/** Accessible name of the sheet's close button. */
|
|
64
66
|
sheetCloseLabel?: string;
|
|
65
67
|
/** Accessible name of the sheet's grip while its button takes the sheet up a step. */
|
|
@@ -93,6 +95,7 @@
|
|
|
93
95
|
fullWidth = false,
|
|
94
96
|
sheetTitle = undefined,
|
|
95
97
|
sheetSnap = undefined,
|
|
98
|
+
sheetFit = false,
|
|
96
99
|
sheetCloseLabel: sheetCloseLabelGiven,
|
|
97
100
|
sheetExpandLabel: sheetExpandLabelGiven,
|
|
98
101
|
sheetCollapseLabel: sheetCollapseLabelGiven,
|
|
@@ -562,7 +565,11 @@
|
|
|
562
565
|
// the corner: within a pixel of concentric.
|
|
563
566
|
// A column, so that the list below can be the part that scrolls
|
|
564
567
|
// when the menu is limited in height.
|
|
565
|
-
|
|
568
|
+
// The layer form of the material: a menu may hold content that
|
|
569
|
+
// places itself with `position: fixed` (a nested Dropdown, a
|
|
570
|
+
// Tooltip), and a backdrop-filter on the menu itself would make it
|
|
571
|
+
// the containing block of that content.
|
|
572
|
+
'material-layer-thick flex flex-col rounded-overlay py-2 transition-[opacity,translate] duration-(--duration-moderate) ease-standard motion-reduce:transition-none',
|
|
566
573
|
transformClasses(),
|
|
567
574
|
]
|
|
568
575
|
.join(' ')
|
|
@@ -590,6 +597,7 @@
|
|
|
590
597
|
<BottomSheet
|
|
591
598
|
bind:isOpen
|
|
592
599
|
snap={sheetSnap ?? (options.length > 6 ? 'full' : 'half')}
|
|
600
|
+
fit={sheetFit}
|
|
593
601
|
title={sheetTitle || ariaLabel}
|
|
594
602
|
closeLabel={sheetCloseLabel}
|
|
595
603
|
expandLabel={sheetExpandLabel}
|
|
@@ -39,6 +39,8 @@ interface Props {
|
|
|
39
39
|
* to six `options`, all of it for more. The grip moves it either way.
|
|
40
40
|
*/
|
|
41
41
|
sheetSnap?: BottomSheetSnap;
|
|
42
|
+
/** The sheet is as tall as the list, up to half the screen (BottomSheet `fit`); the grip then only drags. Off by default. */
|
|
43
|
+
sheetFit?: boolean;
|
|
42
44
|
/** Accessible name of the sheet's close button. */
|
|
43
45
|
sheetCloseLabel?: string;
|
|
44
46
|
/** Accessible name of the sheet's grip while its button takes the sheet up a step. */
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
const itemClasses = $derived(
|
|
70
70
|
cn(
|
|
71
71
|
"focus-ring flex w-full items-start justify-start gap-2 rounded-control px-3 py-2 pointer-coarse:py-3 text-start text-sm transition-colors focus:outline-none",
|
|
72
|
-
tone === "danger" ? "text-error focus-ring--danger" : "text-body",
|
|
72
|
+
tone === "danger" ? "text-error-text focus-ring--danger" : "text-body",
|
|
73
73
|
disabled
|
|
74
74
|
? "cursor-not-allowed"
|
|
75
75
|
: tone === "danger"
|