@noxlovette/material 0.4.8 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation/Shapes.stories.svelte +56 -0
- package/dist/animation/Shapes.stories.svelte.d.ts +3 -0
- package/dist/animation/TransitionPatterns.stories.svelte +359 -0
- package/dist/animation/TransitionPatterns.stories.svelte.d.ts +3 -0
- package/dist/animation/containerTransform.d.ts +35 -12
- package/dist/animation/containerTransform.js +31 -138
- package/dist/animation/enterExit.d.ts +30 -3
- package/dist/animation/enterExit.js +69 -22
- package/dist/animation/index.d.ts +2 -1
- package/dist/animation/index.js +2 -1
- package/dist/animation/presence.svelte.d.ts +47 -0
- package/dist/animation/presence.svelte.js +84 -0
- package/dist/animation/shapeMorph.svelte.d.ts +52 -0
- package/dist/animation/shapeMorph.svelte.js +112 -0
- package/dist/animation/shapesAnimatableSmall.d.ts +28 -22
- package/dist/animation/shapesAnimatableSmall.js +32 -23
- package/dist/animation/sharedAxisTransition.d.ts +57 -37
- package/dist/animation/sharedAxisTransition.js +74 -22
- package/dist/animation/skeleton.d.ts +16 -0
- package/dist/animation/skeleton.js +28 -0
- package/dist/animation/spring.d.ts +61 -0
- package/dist/animation/spring.js +53 -0
- package/dist/animation/springValue.svelte.d.ts +22 -0
- package/dist/animation/springValue.svelte.js +42 -0
- package/dist/animation/transition.d.ts +3 -1
- package/dist/animation/transition.js +3 -1
- package/dist/attachments/clickOutside.d.ts +13 -0
- package/dist/attachments/clickOutside.js +18 -0
- package/dist/attachments/index.d.ts +1 -0
- package/dist/attachments/index.js +1 -0
- package/dist/components/buttons/FAB.svelte +23 -16
- package/dist/components/buttons/FABMenu.svelte +24 -29
- package/dist/components/buttons/FABMenu.svelte.d.ts +2 -1
- package/dist/components/buttons/FABMenuItem.svelte +23 -20
- package/dist/components/buttons/FABMenuItem.svelte.d.ts +5 -1
- package/dist/components/buttons/split-button/SplitButton.svelte +10 -17
- package/dist/components/buttons/split-button/theme.js +1 -1
- package/dist/components/buttons/types.d.ts +3 -3
- package/dist/components/cards/theme.js +1 -1
- package/dist/components/containers/bottom-sheet/BottomSheet.stories.svelte +8 -12
- package/dist/components/containers/bottom-sheet/BottomSheet.svelte +67 -55
- package/dist/components/containers/bottom-sheet/BottomSheet.svelte.d.ts +1 -1
- package/dist/components/containers/bottom-sheet/types.d.ts +8 -2
- package/dist/components/containers/context-menu/ContextMenu.svelte +23 -36
- package/dist/components/containers/context-menu/theme.js +2 -2
- package/dist/components/containers/dialogue/Dialogue.svelte +49 -65
- package/dist/components/containers/link-preview/LinkPreview.svelte +12 -23
- package/dist/components/containers/link-preview/theme.d.ts +3 -3
- package/dist/components/containers/menu/Menu.svelte +14 -21
- package/dist/components/containers/menu/MenuSub.svelte +10 -17
- package/dist/components/containers/pane/DraggablePane.svelte +90 -5
- package/dist/components/containers/pane/DraggablePane.svelte.d.ts +1 -1
- package/dist/components/containers/pane/theme.js +2 -2
- package/dist/components/containers/popover/Popover.svelte +31 -42
- package/dist/components/containers/popover/theme.d.ts +3 -3
- package/dist/components/containers/scroll-area/theme.js +2 -2
- package/dist/components/containers/side-sheet/SideSheet.stories.svelte +10 -15
- package/dist/components/containers/side-sheet/SideSheet.svelte +44 -44
- package/dist/components/containers/side-sheet/SideSheet.svelte.d.ts +4 -3
- package/dist/components/containers/side-sheet/types.d.ts +8 -2
- package/dist/components/date/DateField.svelte +99 -92
- package/dist/components/date/DateField.svelte.d.ts +4 -5
- package/dist/components/date/DateRangeField.svelte +127 -155
- package/dist/components/date/DateRangeField.svelte.d.ts +4 -5
- package/dist/components/date/calendarMotion.d.ts +9 -0
- package/dist/components/date/calendarMotion.js +23 -0
- package/dist/components/date/theme.d.ts +95 -0
- package/dist/components/date/theme.js +103 -14
- package/dist/components/date/types.d.ts +13 -0
- package/dist/components/forms/checkbox/theme.js +2 -2
- package/dist/components/forms/command/theme.d.ts +3 -3
- package/dist/components/forms/command/theme.js +1 -1
- package/dist/components/forms/pin/theme.js +2 -2
- package/dist/components/forms/radio-group/theme.js +2 -2
- package/dist/components/forms/select/Select.svelte +42 -54
- package/dist/components/forms/select/theme.js +4 -4
- package/dist/components/forms/slider/Slider.svelte +144 -126
- package/dist/components/forms/slider/Slider.svelte.d.ts +3 -0
- package/dist/components/forms/slider/theme.d.ts +154 -48
- package/dist/components/forms/slider/theme.js +60 -20
- package/dist/components/forms/slider/types.d.ts +1 -1
- package/dist/components/forms/switch/theme.js +4 -4
- package/dist/components/forms/textfield/Textfield.svelte +1 -1
- package/dist/components/forms/textfield/theme.d.ts +12 -0
- package/dist/components/forms/textfield/theme.js +30 -10
- package/dist/components/forms/toggle-group/theme.js +1 -1
- package/dist/components/forms/tooltip/Tooltip.svelte +24 -35
- package/dist/components/nav/breadcrumb/theme.js +1 -1
- package/dist/components/nav/navbar/theme.js +2 -2
- package/dist/components/nav/rail/Rail.svelte +4 -5
- package/dist/components/nav/rail/theme.js +7 -7
- package/dist/components/nav/tabs/TabHolder.svelte +29 -3
- package/dist/components/nav/tabs/TabHolder.svelte.d.ts +3 -1
- package/dist/components/nav/tabs/theme.js +1 -1
- package/dist/components/progress/CircularProgress.svelte +78 -4
- package/dist/components/progress/CircularProgress.svelte.d.ts +5 -0
- package/dist/components/progress/LinearProgress.svelte +70 -7
- package/dist/components/progress/LinearProgress.svelte.d.ts +5 -0
- package/dist/components/progress/WavyLinearProgress.svelte +27 -3
- package/dist/components/progress/WavyLinearProgress.svelte.d.ts +3 -0
- package/dist/components/progress/_wavy.d.ts +2 -0
- package/dist/components/progress/_wavy.js +3 -1
- package/dist/components/snackbar/Snackbar.svelte +13 -17
- package/dist/components/table/TableBody.svelte +3 -16
- package/dist/components/table/TableBody.svelte.d.ts +1 -5
- package/dist/components/table/TableHeader.svelte +1 -1
- package/dist/components/table/theme.js +1 -1
- package/dist/components/table/types.d.ts +0 -7
- package/dist/components/time/TimeField.stories.svelte +41 -0
- package/dist/components/time/TimeField.stories.svelte.d.ts +19 -0
- package/dist/components/time/TimeField.svelte +69 -62
- package/dist/components/time/TimeField.svelte.d.ts +6 -0
- package/dist/components/time/TimepickerInput.svelte +8 -4
- package/dist/components/time/types.d.ts +11 -1
- package/dist/components/toolbar/theme.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/styles/component.css +21 -22
- package/dist/styles/motion.css +317 -38
- package/dist/utils/Layer.svelte +16 -29
- package/dist/utils/icon/LoadingIndicator.svelte +61 -22
- package/dist/utils/icon/loadingShapes.d.ts +1 -0
- package/dist/utils/icon/loadingShapes.js +16 -0
- package/package.json +5 -2
- package/dist/actions/clickOutside.d.ts +0 -3
- package/dist/actions/clickOutside.js +0 -13
- package/dist/actions/floating.d.ts +0 -20
- package/dist/actions/floating.js +0 -87
- package/dist/actions/index.d.ts +0 -6
- package/dist/actions/index.js +0 -6
- package/dist/actions/keyboard.d.ts +0 -3
- package/dist/actions/keyboard.js +0 -14
- package/dist/actions/portal.d.ts +0 -3
- package/dist/actions/portal.js +0 -8
- package/dist/actions/positionFloating.d.ts +0 -10
- package/dist/actions/positionFloating.js +0 -59
- package/dist/actions/rovingFocusGroup.d.ts +0 -20
- package/dist/actions/rovingFocusGroup.js +0 -82
- package/dist/animation/easing.d.ts +0 -6
- package/dist/animation/easing.js +0 -78
- package/dist/animation/outroClass.d.ts +0 -3
- package/dist/animation/outroClass.js +0 -20
- package/dist/animation/transitionTypes.d.ts +0 -8
- package/dist/animation/transitionTypes.js +0 -1
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
-
An individual action within a FAB menu.
|
|
3
|
+
An individual action within a FAB menu. Wraps bits-ui's `DropdownMenu.Item`, so it gets the
|
|
4
|
+
`menuitem` role, arrow-key navigation, and closes the menu when selected. Must be rendered
|
|
5
|
+
inside a `FAB` with `withMenu`.
|
|
4
6
|
-->
|
|
5
7
|
<script lang="ts">
|
|
6
8
|
import clsx from 'clsx';
|
|
7
9
|
import { fabMenuItem } from './theme.js';
|
|
8
10
|
import type { FABMenuItemProps } from './types.js';
|
|
9
11
|
import { Icon, LoadingIndicator, Layer } from '../../utils/index.js';
|
|
10
|
-
import { Button, type
|
|
12
|
+
import { Button, DropdownMenu, type DropdownMenuItemProps } from 'bits-ui';
|
|
11
13
|
|
|
12
14
|
let {
|
|
13
15
|
class: className,
|
|
@@ -16,6 +18,7 @@ An individual action within a FAB menu.
|
|
|
16
18
|
children,
|
|
17
19
|
iconProps,
|
|
18
20
|
formaction,
|
|
21
|
+
disabled,
|
|
19
22
|
...restProps
|
|
20
23
|
}: FABMenuItemProps = $props();
|
|
21
24
|
|
|
@@ -23,21 +26,21 @@ An individual action within a FAB menu.
|
|
|
23
26
|
const btnCls = $derived(base({ class: clsx(className) }));
|
|
24
27
|
</script>
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
</
|
|
29
|
+
<!-- Spread onto the Item, not the button: bits-ui merges (and chains handlers of) these into `props`. -->
|
|
30
|
+
<DropdownMenu.Item {disabled} {...restProps as DropdownMenuItemProps}>
|
|
31
|
+
{#snippet child({ props })}
|
|
32
|
+
<Button.Root {formaction} {disabled} data-cy="m3-fab-menu-item" {...props} class={btnCls}>
|
|
33
|
+
{#if iconProps}
|
|
34
|
+
{#if loading}
|
|
35
|
+
<LoadingIndicator />
|
|
36
|
+
{:else}
|
|
37
|
+
<Icon class={icon()} {...iconProps} />
|
|
38
|
+
{/if}
|
|
39
|
+
{:else if loading}
|
|
40
|
+
<LoadingIndicator />
|
|
41
|
+
{/if}
|
|
42
|
+
{@render children?.()}
|
|
43
|
+
<Layer />
|
|
44
|
+
</Button.Root>
|
|
45
|
+
{/snippet}
|
|
46
|
+
</DropdownMenu.Item>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { FABMenuItemProps } from './types.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* An individual action within a FAB menu. Wraps bits-ui's `DropdownMenu.Item`, so it gets the
|
|
4
|
+
* `menuitem` role, arrow-key navigation, and closes the menu when selected. Must be rendered
|
|
5
|
+
* inside a `FAB` with `withMenu`.
|
|
6
|
+
*/
|
|
3
7
|
declare const FABMenuItem: import("svelte").Component<FABMenuItemProps, {}, "">;
|
|
4
8
|
type FABMenuItem = ReturnType<typeof FABMenuItem>;
|
|
5
9
|
export default FABMenuItem;
|
|
@@ -15,10 +15,9 @@ selectable items, no menu).
|
|
|
15
15
|
@see https://m3.material.io/components/buttons/guidelines#834f5f31-e363-4d0f-bc4d-abac128f5f0e
|
|
16
16
|
-->
|
|
17
17
|
<script lang="ts">
|
|
18
|
+
import { enterExit, presence } from '../../../animation/index.js';
|
|
18
19
|
import { DropdownMenu } from 'bits-ui';
|
|
19
20
|
import clsx from 'clsx';
|
|
20
|
-
import { easeEmphasizedDecel } from '../../../animation/easing.js';
|
|
21
|
-
import { enterExit } from '../../../animation/enterExit.js';
|
|
22
21
|
import Button from '../Button.svelte';
|
|
23
22
|
import ButtonIcon from '../ButtonIcon.svelte';
|
|
24
23
|
import { buttonIcon } from '../theme.js';
|
|
@@ -80,23 +79,17 @@ selectable items, no menu).
|
|
|
80
79
|
</DropdownMenu.Trigger>
|
|
81
80
|
|
|
82
81
|
<DropdownMenu.Portal>
|
|
83
|
-
<DropdownMenu.Content
|
|
82
|
+
<DropdownMenu.Content {align} sideOffset={4} class="z-100">
|
|
84
83
|
{#snippet child({ wrapperProps, props, open: isOpen })}
|
|
85
|
-
{
|
|
86
|
-
<div
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
easing: easeEmphasizedDecel,
|
|
93
|
-
mode: 'scale'
|
|
94
|
-
}}
|
|
95
|
-
>
|
|
96
|
-
{@render menuChildren()}
|
|
97
|
-
</div>
|
|
84
|
+
<div {...wrapperProps} class={wrapperProps.class as any}>
|
|
85
|
+
<div
|
|
86
|
+
{...props}
|
|
87
|
+
class="bg-md-sys-color-surface-container-high shadow-elevation-3 ring-md-sys-color-outline/10 max-w-sm min-w-48 gap-1 overflow-y-auto rounded-lg px-2 py-1"
|
|
88
|
+
{@attach presence(() => isOpen, enterExit.scale)}
|
|
89
|
+
>
|
|
90
|
+
{@render menuChildren()}
|
|
98
91
|
</div>
|
|
99
|
-
|
|
92
|
+
</div>
|
|
100
93
|
{/snippet}
|
|
101
94
|
</DropdownMenu.Content>
|
|
102
95
|
</DropdownMenu.Portal>
|
|
@@ -12,7 +12,7 @@ export const SPLIT_BUTTON_INNER_RADIUS = {
|
|
|
12
12
|
export const splitButton = tv({
|
|
13
13
|
slots: {
|
|
14
14
|
root: 'inline-flex items-center gap-0.5',
|
|
15
|
-
icon: 'transition-transform
|
|
15
|
+
icon: 'transition-transform md-sys-motion-fast-spatial'
|
|
16
16
|
},
|
|
17
17
|
variants: {
|
|
18
18
|
open: {
|
|
@@ -146,9 +146,7 @@ export type FABProps = FABVariants & AnchorButtonAttributes & {
|
|
|
146
146
|
*/
|
|
147
147
|
children?: Snippet;
|
|
148
148
|
};
|
|
149
|
-
export type FABMenuProps = HTMLAttributes<
|
|
150
|
-
/** The FAB button element to position the menu relative to. */
|
|
151
|
-
anchorEl: HTMLElement;
|
|
149
|
+
export type FABMenuProps = HTMLAttributes<HTMLDivElement> & {
|
|
152
150
|
/**
|
|
153
151
|
* The menu items. Use `FABMenuItem` components.
|
|
154
152
|
*/
|
|
@@ -159,6 +157,8 @@ export type FABMenuItemProps = FABMenuItemVariants & AnchorButtonAttributes & {
|
|
|
159
157
|
* The visual variant of the menu item.
|
|
160
158
|
*/
|
|
161
159
|
variant?: FABMenuItemVariants['variant'];
|
|
160
|
+
/** Whether the menu item is disabled (skipped by keyboard navigation). */
|
|
161
|
+
disabled?: boolean;
|
|
162
162
|
/** Whether the menu item is in a loading state. */
|
|
163
163
|
loading?: boolean;
|
|
164
164
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { tv } from 'tailwind-variants';
|
|
2
2
|
export const card = tv({
|
|
3
3
|
slots: {
|
|
4
|
-
base: 'relative flex flex-col rounded-lg disabled:opacity-[0.38] disabled:bg-md-sys-color-surface-variant state-layer before:rounded-lg
|
|
4
|
+
base: 'relative flex flex-col rounded-lg disabled:opacity-[0.38] disabled:bg-md-sys-color-surface-variant state-layer before:rounded-lg transition-shadow md-sys-motion-effects',
|
|
5
5
|
icon: 'size-6 text-[24px] text-md-sys-color-primary'
|
|
6
6
|
},
|
|
7
7
|
variants: {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
BottomSheet
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
backdrop click, or dragging the handle down below a minimum height ('esc' | 'click' | 'low') —
|
|
6
|
-
the consumer is expected to flip its own `open` flag to false in response.
|
|
2
|
+
BottomSheet is controlled with `bind:open`: it dismisses itself on Esc, backdrop click, or
|
|
3
|
+
dragging the handle below a minimum height, and stays mounted until its exit animation
|
|
4
|
+
finishes. The optional `close` callback reports why ('esc' | 'click' | 'low').
|
|
7
5
|
-->
|
|
8
6
|
<script module lang="ts">
|
|
9
7
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
@@ -24,12 +22,10 @@
|
|
|
24
22
|
<Story name="Playground" asChild>
|
|
25
23
|
<div class="p-6">
|
|
26
24
|
<Button onclick={() => (playgroundOpen = true)}>Open bottom sheet</Button>
|
|
27
|
-
{
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
</BottomSheet>
|
|
33
|
-
{/if}
|
|
25
|
+
<BottomSheet bind:open={playgroundOpen}>
|
|
26
|
+
<MenuItem iconProps={{ name: 'share' }}>Share</MenuItem>
|
|
27
|
+
<MenuItem iconProps={{ name: 'link' }}>Copy link</MenuItem>
|
|
28
|
+
<MenuItem iconProps={{ name: 'download' }}>Download</MenuItem>
|
|
29
|
+
</BottomSheet>
|
|
34
30
|
</div>
|
|
35
31
|
</Story>
|
|
@@ -9,31 +9,37 @@ while keeping the main screen content visible.
|
|
|
9
9
|
-->
|
|
10
10
|
<script lang="ts">
|
|
11
11
|
import type { BottomSheetProps } from './types.js';
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import { outroClass } from '../../../animation/outroClass.js';
|
|
12
|
+
import { untrack } from 'svelte';
|
|
13
|
+
import { enterExit, Presence } from '../../../animation/index.js';
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
const DEFAULT_HEIGHT = 480;
|
|
16
|
+
const DISMISS_HEIGHT = 48;
|
|
17
17
|
|
|
18
|
-
let
|
|
18
|
+
let { children, open = $bindable(true), close }: BottomSheetProps = $props();
|
|
19
|
+
|
|
20
|
+
let height = $state(DEFAULT_HEIGHT);
|
|
19
21
|
let container: HTMLDivElement | undefined = $state();
|
|
20
22
|
let isDragging = $state(false);
|
|
21
23
|
let startY = $state(0);
|
|
22
24
|
|
|
23
|
-
const
|
|
25
|
+
const sheet = new Presence(() => open);
|
|
26
|
+
|
|
27
|
+
// untrack: re-running this attachment on every drag would call showModal() on an open dialog.
|
|
28
|
+
const showModal = (node: HTMLDialogElement) => {
|
|
29
|
+
untrack(() => node.clientHeight < height && (height = node.clientHeight));
|
|
30
|
+
node.showModal();
|
|
31
|
+
};
|
|
24
32
|
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
): TransitionConfig => {
|
|
29
|
-
if (node.clientHeight < height) height = node.clientHeight;
|
|
30
|
-
return {
|
|
31
|
-
duration: options.duration,
|
|
32
|
-
easing: options.easing,
|
|
33
|
-
css: (t) => `max-height: ${t * height}px`
|
|
34
|
-
};
|
|
33
|
+
const dismiss = (reason: 'esc' | 'click' | 'low') => {
|
|
34
|
+
open = false;
|
|
35
|
+
close?.(reason);
|
|
35
36
|
};
|
|
36
37
|
|
|
38
|
+
// A sheet dragged shut keeps its collapsed height through the exit; restore it on reopen.
|
|
39
|
+
$effect.pre(() => {
|
|
40
|
+
if (open) untrack(() => height < DISMISS_HEIGHT && (height = DEFAULT_HEIGHT));
|
|
41
|
+
});
|
|
42
|
+
|
|
37
43
|
const moveWheel = (e: WheelEvent) => {
|
|
38
44
|
e.preventDefault();
|
|
39
45
|
height += e.deltaY;
|
|
@@ -49,7 +55,7 @@ while keeping the main screen content visible.
|
|
|
49
55
|
};
|
|
50
56
|
|
|
51
57
|
$effect(() => {
|
|
52
|
-
if (height <
|
|
58
|
+
if (height < DISMISS_HEIGHT && untrack(() => open)) dismiss('low');
|
|
53
59
|
});
|
|
54
60
|
</script>
|
|
55
61
|
|
|
@@ -60,51 +66,57 @@ while keeping the main screen content visible.
|
|
|
60
66
|
ontouchend={() => (isDragging = false)}
|
|
61
67
|
/>
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
>
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
69
|
+
{#if sheet.mounted}
|
|
70
|
+
<dialog
|
|
71
|
+
class="bg-md-sys-color-surface-container-low text-md-sys-color-on-surface mx-auto mt-auto w-full max-w-2xl overflow-hidden rounded-t-md"
|
|
72
|
+
style:max-height="{height}px"
|
|
73
|
+
data-state={open ? 'open' : 'closed'}
|
|
74
|
+
{@attach showModal}
|
|
75
|
+
{@attach sheet.attach(enterExit.bottomSheet)}
|
|
76
|
+
oncancel={(e) => {
|
|
77
|
+
e.preventDefault();
|
|
78
|
+
dismiss('esc');
|
|
79
|
+
}}
|
|
80
|
+
onmousedown={(e) => {
|
|
81
|
+
if (e.target != e.currentTarget) return;
|
|
82
|
+
dismiss('click');
|
|
83
|
+
}}
|
|
84
|
+
onwheel={moveWheel}
|
|
85
|
+
>
|
|
86
|
+
<div class="px-4" bind:this={container}>
|
|
87
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
88
|
+
<div
|
|
89
|
+
class="flex h-12 w-full cursor-grab items-center justify-center"
|
|
90
|
+
onmousedown={(e) => {
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
isDragging = true;
|
|
93
|
+
startY = e.clientY;
|
|
94
|
+
}}
|
|
95
|
+
ontouchstart={(e) => {
|
|
96
|
+
isDragging = true;
|
|
97
|
+
startY = e.touches[0].clientY;
|
|
98
|
+
}}
|
|
99
|
+
>
|
|
100
|
+
<div class="bg-md-sys-color-on-surface-variant/40 h-1 w-8 rounded-full"></div>
|
|
101
|
+
</div>
|
|
102
|
+
{@render children()}
|
|
95
103
|
</div>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
</dialog>
|
|
104
|
+
</dialog>
|
|
105
|
+
{/if}
|
|
99
106
|
|
|
100
107
|
<style>
|
|
101
108
|
dialog::backdrop {
|
|
102
109
|
background-color: rgba(0, 0, 0, 0.5);
|
|
103
|
-
animation: backdrop
|
|
110
|
+
animation: backdrop var(--md-sys-motion-duration-effects-spring)
|
|
111
|
+
var(--md-sys-motion-timing-function-effects-spring);
|
|
112
|
+
}
|
|
113
|
+
dialog[data-state='closed'] {
|
|
114
|
+
pointer-events: none;
|
|
104
115
|
}
|
|
105
|
-
dialog
|
|
116
|
+
dialog[data-state='closed']::backdrop {
|
|
106
117
|
background-color: transparent;
|
|
107
|
-
animation: backdropReverse
|
|
118
|
+
animation: backdropReverse var(--md-sys-motion-duration-fast-effects-spring)
|
|
119
|
+
var(--md-sys-motion-timing-function-fast-effects-spring);
|
|
108
120
|
}
|
|
109
121
|
@keyframes backdrop {
|
|
110
122
|
from {
|
|
@@ -7,6 +7,6 @@ import type { BottomSheetProps } from './types.js';
|
|
|
7
7
|
*
|
|
8
8
|
* @see https://m3.material.io/components/bottom-sheets/overview
|
|
9
9
|
*/
|
|
10
|
-
declare const BottomSheet: import("svelte").Component<BottomSheetProps, {}, "">;
|
|
10
|
+
declare const BottomSheet: import("svelte").Component<BottomSheetProps, {}, "open">;
|
|
11
11
|
type BottomSheet = ReturnType<typeof BottomSheet>;
|
|
12
12
|
export default BottomSheet;
|
|
@@ -9,8 +9,14 @@ export interface BottomSheetProps {
|
|
|
9
9
|
*/
|
|
10
10
|
children: Snippet;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Whether the sheet is shown. Bind it (`bind:open`) so the sheet can play its exit animation
|
|
13
|
+
* before unmounting.
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
open?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Called when the user dismisses the sheet.
|
|
13
19
|
* @param reason The reason for closing ('esc' key, 'click' outside, or 'low' drag height).
|
|
14
20
|
*/
|
|
15
|
-
close
|
|
21
|
+
close?: (reason: 'esc' | 'click' | 'low') => void;
|
|
16
22
|
}
|
|
@@ -30,13 +30,12 @@ you need it (e.g. a table row):
|
|
|
30
30
|
@see https://m3.material.io/components/menus/guidelines
|
|
31
31
|
-->
|
|
32
32
|
<script lang="ts">
|
|
33
|
+
import { enterExit, presence } from '../../../animation/index.js';
|
|
33
34
|
import { ContextMenu as BitsContextMenu } from 'bits-ui';
|
|
34
35
|
import { contextMenu } from './theme.js';
|
|
35
36
|
import type { ContextMenuProps, ContextMenuDataItem } from './types.js';
|
|
36
37
|
import Icon from '../../../utils/icon/Icon.svelte';
|
|
37
38
|
import Divider from '../divider/Divider.svelte';
|
|
38
|
-
import { enterExit } from '../../../animation/enterExit.js';
|
|
39
|
-
import { easeEmphasizedDecel } from '../../../animation/easing.js';
|
|
40
39
|
|
|
41
40
|
let {
|
|
42
41
|
items = [],
|
|
@@ -75,25 +74,19 @@ you need it (e.g. a table row):
|
|
|
75
74
|
<Icon name="chevron_right" class={theme.rightSlot()} />
|
|
76
75
|
</BitsContextMenu.SubTrigger>
|
|
77
76
|
<BitsContextMenu.Portal>
|
|
78
|
-
<BitsContextMenu.SubContent
|
|
77
|
+
<BitsContextMenu.SubContent class={theme.content()}>
|
|
79
78
|
{#snippet child({ wrapperProps, props, open })}
|
|
80
|
-
{
|
|
81
|
-
<div
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}}
|
|
90
|
-
>
|
|
91
|
-
{#each item.items as subItem (subItem)}
|
|
92
|
-
{@render MenuItem(subItem)}
|
|
93
|
-
{/each}
|
|
94
|
-
</div>
|
|
79
|
+
<div {...wrapperProps} class={wrapperProps.class as any}>
|
|
80
|
+
<div
|
|
81
|
+
{...props}
|
|
82
|
+
class={props.class as any}
|
|
83
|
+
{@attach presence(() => open, enterExit.scale)}
|
|
84
|
+
>
|
|
85
|
+
{#each item.items as subItem (subItem)}
|
|
86
|
+
{@render MenuItem(subItem)}
|
|
87
|
+
{/each}
|
|
95
88
|
</div>
|
|
96
|
-
|
|
89
|
+
</div>
|
|
97
90
|
{/snippet}
|
|
98
91
|
</BitsContextMenu.SubContent>
|
|
99
92
|
</BitsContextMenu.Portal>
|
|
@@ -142,25 +135,19 @@ you need it (e.g. a table row):
|
|
|
142
135
|
</BitsContextMenu.Trigger>
|
|
143
136
|
|
|
144
137
|
<BitsContextMenu.Portal>
|
|
145
|
-
<BitsContextMenu.Content
|
|
138
|
+
<BitsContextMenu.Content class={theme.content()}>
|
|
146
139
|
{#snippet child({ wrapperProps, props, open })}
|
|
147
|
-
{
|
|
148
|
-
<div
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}}
|
|
157
|
-
>
|
|
158
|
-
{#each items as item (item)}
|
|
159
|
-
{@render MenuItem(item)}
|
|
160
|
-
{/each}
|
|
161
|
-
</div>
|
|
140
|
+
<div {...wrapperProps} class={wrapperProps.class as any}>
|
|
141
|
+
<div
|
|
142
|
+
{...props}
|
|
143
|
+
class={props.class as any}
|
|
144
|
+
{@attach presence(() => open, enterExit.scale)}
|
|
145
|
+
>
|
|
146
|
+
{#each items as item (item)}
|
|
147
|
+
{@render MenuItem(item)}
|
|
148
|
+
{/each}
|
|
162
149
|
</div>
|
|
163
|
-
|
|
150
|
+
</div>
|
|
164
151
|
{/snippet}
|
|
165
152
|
</BitsContextMenu.Content>
|
|
166
153
|
</BitsContextMenu.Portal>
|
|
@@ -9,14 +9,14 @@ export const contextMenu = tv({
|
|
|
9
9
|
item: `
|
|
10
10
|
rounded-sm relative flex w-full cursor-pointer select-none items-center gap-2
|
|
11
11
|
px-3 py-2 text-left md-sys-typescale-body-large text-md-sys-color-on-surface
|
|
12
|
-
outline-none transition-colors
|
|
12
|
+
outline-none transition-colors md-sys-motion-fast-effects
|
|
13
13
|
hover:bg-md-sys-color-on-surface/8 data-[highlighted]:bg-md-sys-color-on-surface/8
|
|
14
14
|
data-[disabled]:cursor-not-allowed data-[disabled]:opacity-38
|
|
15
15
|
`,
|
|
16
16
|
subTrigger: `
|
|
17
17
|
rounded-sm relative flex w-full cursor-pointer select-none items-center gap-2
|
|
18
18
|
px-3 py-2 text-left md-sys-typescale-body-large text-md-sys-color-on-surface
|
|
19
|
-
outline-none transition-colors
|
|
19
|
+
outline-none transition-colors md-sys-motion-fast-effects
|
|
20
20
|
hover:bg-md-sys-color-on-surface/8 data-[state=open]:bg-md-sys-color-on-surface/8
|
|
21
21
|
data-[highlighted]:bg-md-sys-color-on-surface/8
|
|
22
22
|
data-[disabled]:cursor-not-allowed data-[disabled]:opacity-38
|
|
@@ -13,8 +13,7 @@ on screen until confirmed, dismissed, or a required action has been taken.
|
|
|
13
13
|
import { dialogue } from './theme.js';
|
|
14
14
|
import type { DialogueProps } from './types.js';
|
|
15
15
|
import { Dialog } from 'bits-ui';
|
|
16
|
-
import { enterExit } from '../../../animation/
|
|
17
|
-
import { easeEmphasized, easeEmphasizedDecel } from '../../../animation/easing.js';
|
|
16
|
+
import { enterExit, presence } from '../../../animation/index.js';
|
|
18
17
|
import { Button } from '../../buttons/index.js';
|
|
19
18
|
|
|
20
19
|
let {
|
|
@@ -44,79 +43,64 @@ on screen until confirmed, dismissed, or a required action has been taken.
|
|
|
44
43
|
|
|
45
44
|
<Dialog.Root bind:open {...rootRest}>
|
|
46
45
|
<Dialog.Portal disabled={portalDisabled}>
|
|
47
|
-
<Dialog.Overlay
|
|
46
|
+
<Dialog.Overlay>
|
|
48
47
|
{#snippet child({ props, open })}
|
|
49
|
-
{
|
|
50
|
-
<div
|
|
51
|
-
{...props}
|
|
52
|
-
class={base()}
|
|
53
|
-
transition:enterExit={{
|
|
54
|
-
duration: 500,
|
|
55
|
-
easing: easeEmphasizedDecel
|
|
56
|
-
}}
|
|
57
|
-
></div>
|
|
58
|
-
{/if}
|
|
48
|
+
<div {...props} class={base()} {@attach presence(() => open, enterExit.fade)}></div>
|
|
59
49
|
{/snippet}
|
|
60
50
|
</Dialog.Overlay>
|
|
61
|
-
<Dialog.Content
|
|
51
|
+
<Dialog.Content>
|
|
62
52
|
{#snippet child({ props, open: isOpen })}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
{#if supportingText}
|
|
85
|
-
<Dialog.Description class={supportingTextContainer()}>
|
|
86
|
-
{supportingText}
|
|
87
|
-
</Dialog.Description>
|
|
88
|
-
{/if}
|
|
53
|
+
<form
|
|
54
|
+
method="POST"
|
|
55
|
+
action={confirmAction}
|
|
56
|
+
use:enhance
|
|
57
|
+
{...props}
|
|
58
|
+
{...formProps}
|
|
59
|
+
class={inner({ class: className })}
|
|
60
|
+
style:min-width={minWidth}
|
|
61
|
+
style:max-width={maxWidth}
|
|
62
|
+
{@attach presence(() => isOpen, enterExit.dialog)}
|
|
63
|
+
>
|
|
64
|
+
{#if headline}
|
|
65
|
+
<Dialog.Title class={headlineContainer()}>
|
|
66
|
+
{headline}
|
|
67
|
+
</Dialog.Title>
|
|
68
|
+
{/if}
|
|
69
|
+
{#if supportingText}
|
|
70
|
+
<Dialog.Description class={supportingTextContainer()}>
|
|
71
|
+
{supportingText}
|
|
72
|
+
</Dialog.Description>
|
|
73
|
+
{/if}
|
|
89
74
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
75
|
+
{#if children}
|
|
76
|
+
<div class="flex w-full flex-col gap-4">
|
|
77
|
+
{@render children()}
|
|
78
|
+
</div>
|
|
79
|
+
{/if}
|
|
95
80
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
81
|
+
<div class={buttonContainer()}>
|
|
82
|
+
<Button
|
|
83
|
+
type="button"
|
|
84
|
+
variant="text"
|
|
85
|
+
data-cy="dialogue-cancel"
|
|
86
|
+
onclick={() => (open = false)}
|
|
87
|
+
>
|
|
88
|
+
{cancelText}
|
|
89
|
+
</Button>
|
|
105
90
|
|
|
106
|
-
|
|
91
|
+
{#if delegateClose}
|
|
92
|
+
<Button type="submit" {disabled} {loading} data-cy="dialogue-confirm">
|
|
93
|
+
{confirmText}
|
|
94
|
+
</Button>
|
|
95
|
+
{:else}
|
|
96
|
+
<Dialog.Close>
|
|
107
97
|
<Button type="submit" {disabled} {loading} data-cy="dialogue-confirm">
|
|
108
98
|
{confirmText}
|
|
109
99
|
</Button>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
</Button>
|
|
115
|
-
</Dialog.Close>
|
|
116
|
-
{/if}
|
|
117
|
-
</div>
|
|
118
|
-
</form>
|
|
119
|
-
{/if}
|
|
100
|
+
</Dialog.Close>
|
|
101
|
+
{/if}
|
|
102
|
+
</div>
|
|
103
|
+
</form>
|
|
120
104
|
{/snippet}
|
|
121
105
|
</Dialog.Content>
|
|
122
106
|
</Dialog.Portal>
|