@noxlovette/material 0.5.1 → 0.6.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/bin/material-claude-skill.js +31 -0
- package/claude-skill/material-design/SKILL.md +68 -0
- package/claude-skill/material-design/references/accessibility-checklist.md +29 -0
- package/claude-skill/material-design/references/component-patterns.md +55 -0
- package/claude-skill/material-design/references/motion-guide.md +163 -0
- package/claude-skill/material-design/references/tokens-and-styles.md +68 -0
- package/dist/animation/Shapes.stories.svelte +10 -6
- package/dist/animation/TransitionPatterns.stories.svelte +30 -20
- package/dist/animation/containerTransform.d.ts +4 -2
- package/dist/animation/containerTransform.js +4 -2
- package/dist/animation/enterExit.js +5 -2
- package/dist/animation/skeleton.d.ts +1 -1
- package/dist/animation/skeleton.js +1 -1
- package/dist/components/badge/Badge.mdx +70 -0
- package/dist/components/badge/Badge.stories.svelte +38 -20
- package/dist/components/badge/Badge.svelte +12 -5
- package/dist/components/badge/theme.d.ts +30 -7
- package/dist/components/badge/theme.js +24 -4
- package/dist/components/badge/types.d.ts +18 -4
- package/dist/components/buttons/Button.mdx +85 -0
- package/dist/components/buttons/Button.stories.svelte +62 -27
- package/dist/components/buttons/Button.svelte +29 -25
- package/dist/components/buttons/Button.svelte.d.ts +11 -9
- package/dist/components/buttons/ButtonIcon.mdx +52 -0
- package/dist/components/buttons/ButtonIcon.stories.svelte +72 -48
- package/dist/components/buttons/ButtonIcon.svelte +58 -36
- package/dist/components/buttons/ButtonIcon.svelte.d.ts +9 -7
- package/dist/components/buttons/FAB.mdx +84 -0
- package/dist/components/buttons/FAB.stories.svelte +103 -24
- package/dist/components/buttons/FAB.stories.svelte.d.ts +2 -17
- package/dist/components/buttons/FAB.svelte +353 -29
- package/dist/components/buttons/FAB.svelte.d.ts +11 -6
- package/dist/components/buttons/FABMenu.svelte +27 -8
- package/dist/components/buttons/FABMenu.svelte.d.ts +7 -3
- package/dist/components/buttons/FABMenuItem.svelte +20 -16
- package/dist/components/buttons/FABMenuItem.svelte.d.ts +3 -3
- package/dist/components/buttons/Toggle.stories.svelte +31 -23
- package/dist/components/buttons/Toggle.stories.svelte.d.ts +2 -17
- package/dist/components/buttons/Toggle.svelte +28 -25
- package/dist/components/buttons/Toggle.svelte.d.ts +5 -5
- package/dist/components/buttons/button-group/ButtonGroup.mdx +39 -0
- package/dist/components/buttons/button-group/ButtonGroup.stories.svelte +62 -43
- package/dist/components/buttons/button-group/ButtonGroup.stories.svelte.d.ts +2 -17
- package/dist/components/buttons/button-group/ButtonGroup.svelte +102 -8
- package/dist/components/buttons/button-group/ButtonGroup.svelte.d.ts +6 -7
- package/dist/components/buttons/button-group/theme.d.ts +45 -15
- package/dist/components/buttons/button-group/theme.js +13 -8
- package/dist/components/buttons/button-group/types.d.ts +13 -7
- package/dist/components/buttons/connected/ConnectedButtonGroup.mdx +43 -0
- package/dist/components/buttons/connected/ConnectedButtonGroup.stories.svelte +56 -74
- package/dist/components/buttons/connected/ConnectedButtonGroup.stories.svelte.d.ts +2 -17
- package/dist/components/buttons/connected/ConnectedButtonGroup.svelte +16 -4
- package/dist/components/buttons/connected/ConnectedButtonGroup.svelte.d.ts +4 -4
- package/dist/components/buttons/connected/ConnectedButtonGroupItem.svelte +35 -8
- package/dist/components/buttons/connected/ConnectedButtonGroupItem.svelte.d.ts +2 -3
- package/dist/components/buttons/connected/theme.d.ts +33 -18
- package/dist/components/buttons/connected/theme.js +32 -9
- package/dist/components/buttons/connected/types.d.ts +36 -9
- package/dist/components/buttons/shapeMorph.d.ts +26 -0
- package/dist/components/buttons/shapeMorph.js +142 -0
- package/dist/components/buttons/split-button/SplitButton.mdx +48 -0
- package/dist/components/buttons/split-button/SplitButton.stories.svelte +9 -14
- package/dist/components/buttons/split-button/SplitButton.svelte +65 -48
- package/dist/components/buttons/split-button/SplitButton.svelte.d.ts +6 -11
- package/dist/components/buttons/split-button/theme.d.ts +110 -17
- package/dist/components/buttons/split-button/theme.js +74 -16
- package/dist/components/buttons/split-button/types.d.ts +24 -18
- package/dist/components/buttons/theme.d.ts +422 -230
- package/dist/components/buttons/theme.js +286 -380
- package/dist/components/buttons/types.d.ts +130 -125
- package/dist/components/cards/Card.mdx +44 -0
- package/dist/components/cards/Card.stories.svelte +11 -11
- package/dist/components/cards/theme.js +5 -5
- package/dist/components/chips/Chip.mdx +68 -0
- package/dist/components/chips/Chip.stories.svelte +4 -4
- package/dist/components/chips/theme.js +3 -3
- package/dist/components/containers/action-rail/ActionRail.stories.svelte +1 -0
- package/dist/components/containers/action-rail/theme.js +1 -1
- package/dist/components/containers/bottom-sheet/BottomSheet.mdx +64 -0
- package/dist/components/containers/bottom-sheet/BottomSheet.stories.svelte +108 -12
- package/dist/components/containers/bottom-sheet/BottomSheet.svelte +179 -109
- package/dist/components/containers/bottom-sheet/BottomSheet.svelte.d.ts +10 -5
- package/dist/components/containers/bottom-sheet/index.d.ts +1 -0
- package/dist/components/containers/bottom-sheet/index.js +1 -0
- package/dist/components/containers/bottom-sheet/theme.d.ts +45 -0
- package/dist/components/containers/bottom-sheet/theme.js +42 -0
- package/dist/components/containers/bottom-sheet/types.d.ts +37 -5
- package/dist/components/containers/carousel/Carousel.mdx +80 -0
- package/dist/components/containers/carousel/Carousel.stories.svelte +131 -0
- package/dist/components/containers/carousel/Carousel.stories.svelte.d.ts +4 -0
- package/dist/components/containers/carousel/Carousel.svelte +194 -0
- package/dist/components/containers/carousel/Carousel.svelte.d.ts +25 -0
- package/dist/components/containers/carousel/index.d.ts +3 -0
- package/dist/components/containers/{stack → carousel}/index.js +1 -2
- package/dist/components/containers/carousel/keylines.d.ts +32 -0
- package/dist/components/containers/carousel/keylines.js +88 -0
- package/dist/components/containers/carousel/theme.d.ts +162 -0
- package/dist/components/containers/carousel/theme.js +67 -0
- package/dist/components/containers/carousel/types.d.ts +52 -0
- package/dist/components/containers/context-menu/ContextMenu.stories.svelte +1 -0
- package/dist/components/containers/context-menu/ContextMenu.svelte +2 -2
- package/dist/components/containers/context-menu/ContextMenu.svelte.d.ts +1 -1
- package/dist/components/containers/context-menu/theme.js +10 -10
- package/dist/components/containers/dialogue/Dialogue.mdx +65 -0
- package/dist/components/containers/dialogue/Dialogue.stories.svelte +4 -4
- package/dist/components/containers/dialogue/Dialogue.svelte +1 -1
- package/dist/components/containers/dialogue/theme.js +3 -3
- package/dist/components/containers/divider/Divider.stories.svelte +2 -1
- package/dist/components/containers/divider/Divider.svelte +2 -2
- package/dist/components/containers/divider/theme.d.ts +6 -6
- package/dist/components/containers/divider/theme.js +2 -2
- package/dist/components/containers/index.d.ts +1 -1
- package/dist/components/containers/index.js +1 -1
- package/dist/components/containers/link-preview/theme.js +2 -2
- package/dist/components/containers/list/List.svelte +18 -0
- package/dist/components/containers/list/List.svelte.d.ts +4 -0
- package/dist/components/containers/list/ListItem.mdx +100 -0
- package/dist/components/containers/list/ListItem.stories.svelte +177 -42
- package/dist/components/containers/list/ListItem.stories.svelte.d.ts +2 -17
- package/dist/components/containers/list/ListItem.svelte +92 -37
- package/dist/components/containers/list/ListItem.svelte.d.ts +1 -1
- package/dist/components/containers/list/context.d.ts +6 -0
- package/dist/components/containers/list/context.js +4 -0
- package/dist/components/containers/list/index.d.ts +1 -0
- package/dist/components/containers/list/index.js +1 -0
- package/dist/components/containers/list/theme.d.ts +487 -12
- package/dist/components/containers/list/theme.js +140 -13
- package/dist/components/containers/list/types.d.ts +39 -5
- package/dist/components/containers/menu/Menu.mdx +52 -0
- package/dist/components/containers/menu/Menu.stories.svelte +14 -14
- package/dist/components/containers/menu/Menu.svelte +1 -1
- package/dist/components/containers/menu/MenuGroup.svelte +1 -1
- package/dist/components/containers/menu/MenuGroup.svelte.d.ts +1 -1
- package/dist/components/containers/menu/menu-item/MenuItem.svelte +1 -1
- package/dist/components/containers/menu/theme.js +8 -8
- package/dist/components/containers/pane/DraggablePane.stories.svelte +4 -3
- package/dist/components/containers/pane/DraggablePane.svelte +2 -2
- package/dist/components/containers/pane/Pane.stories.svelte +11 -10
- package/dist/components/containers/pane/Pane.svelte +24 -2
- package/dist/components/containers/pane/PaneGrid.stories.svelte +19 -18
- package/dist/components/containers/pane/PaneGrid.svelte +3 -2
- package/dist/components/containers/pane/PaneGrid.svelte.d.ts +2 -1
- package/dist/components/containers/pane/PaneHandle.svelte +48 -2
- package/dist/components/containers/pane/PaneHandle.svelte.d.ts +4 -0
- package/dist/components/containers/pane/resizeStore.svelte.d.ts +10 -1
- package/dist/components/containers/pane/resizeStore.svelte.js +13 -2
- package/dist/components/containers/pane/theme.js +129 -45
- package/dist/components/containers/pane/types.d.ts +3 -2
- package/dist/components/containers/popover/Popover.mdx +45 -0
- package/dist/components/containers/popover/Popover.stories.svelte +1 -1
- package/dist/components/containers/popover/Popover.svelte +1 -1
- package/dist/components/containers/popover/theme.js +3 -3
- package/dist/components/containers/scroll-area/theme.js +2 -2
- package/dist/components/containers/side-sheet/SideSheet.mdx +71 -0
- package/dist/components/containers/side-sheet/SideSheet.stories.svelte +113 -17
- package/dist/components/containers/side-sheet/SideSheet.svelte +113 -66
- package/dist/components/containers/side-sheet/SideSheet.svelte.d.ts +8 -7
- package/dist/components/containers/side-sheet/index.d.ts +1 -0
- package/dist/components/containers/side-sheet/index.js +1 -0
- package/dist/components/containers/side-sheet/theme.d.ts +108 -0
- package/dist/components/containers/side-sheet/theme.js +72 -0
- package/dist/components/containers/side-sheet/types.d.ts +35 -7
- package/dist/components/date/DateField.stories.svelte +4 -3
- package/dist/components/date/DateField.svelte +11 -2
- package/dist/components/date/DateRangeField.stories.svelte +4 -3
- package/dist/components/date/DateRangeField.svelte +12 -3
- package/dist/components/date/theme.d.ts +7 -7
- package/dist/components/date/theme.js +31 -31
- package/dist/components/forms/checkbox/Checkbox.mdx +35 -0
- package/dist/components/forms/checkbox/Checkbox.stories.svelte +2 -2
- package/dist/components/forms/checkbox/Checkbox.svelte +1 -1
- package/dist/components/forms/checkbox/theme.js +3 -3
- package/dist/components/forms/command/Command.stories.svelte +1 -0
- package/dist/components/forms/command/theme.js +9 -9
- package/dist/components/forms/pin/theme.js +4 -4
- package/dist/components/forms/radio-group/RadioGroup.svelte +1 -1
- package/dist/components/forms/radio-group/theme.js +5 -5
- package/dist/components/forms/search/Search.mdx +38 -0
- package/dist/components/forms/search/Search.stories.svelte +19 -9
- package/dist/components/forms/search/Search.svelte +40 -17
- package/dist/components/forms/search/Search.svelte.d.ts +2 -2
- package/dist/components/forms/search/theme.d.ts +45 -12
- package/dist/components/forms/search/theme.js +13 -8
- package/dist/components/forms/search/types.d.ts +18 -12
- package/dist/components/forms/select/Select.mdx +53 -0
- package/dist/components/forms/select/Select.stories.svelte +4 -4
- package/dist/components/forms/select/Select.svelte +10 -2
- package/dist/components/forms/select/SelectItem.svelte +1 -1
- package/dist/components/forms/select/theme.js +12 -12
- package/dist/components/forms/slider/Slider.mdx +85 -0
- package/dist/components/forms/slider/Slider.stories.svelte +7 -7
- package/dist/components/forms/slider/Slider.svelte +46 -28
- package/dist/components/forms/slider/theme.d.ts +14 -0
- package/dist/components/forms/slider/theme.js +28 -17
- package/dist/components/forms/slider/types.d.ts +3 -2
- package/dist/components/forms/switch/Switch.mdx +38 -0
- package/dist/components/forms/switch/Switch.stories.svelte +3 -3
- package/dist/components/forms/switch/theme.js +6 -6
- package/dist/components/forms/textfield/Textfield.mdx +53 -0
- package/dist/components/forms/textfield/Textfield.stories.svelte +6 -6
- package/dist/components/forms/textfield/Textfield.svelte +1 -0
- package/dist/components/forms/textfield/theme.js +19 -19
- package/dist/components/forms/toggle-group/theme.js +2 -2
- package/dist/components/forms/tooltip/Tooltip.stories.svelte +1 -0
- package/dist/components/forms/tooltip/theme.js +3 -3
- package/dist/components/misc/Avatar.stories.svelte +5 -4
- package/dist/components/misc/ThemeSettings.svelte +9 -9
- package/dist/components/misc/ThemeSwitcher.svelte +3 -3
- package/dist/components/misc/theme.js +4 -4
- package/dist/components/nav/appbar/AppBar.mdx +71 -0
- package/dist/components/nav/appbar/AppBar.stories.svelte +93 -3
- package/dist/components/nav/appbar/AppBar.stories.svelte.d.ts +2 -17
- package/dist/components/nav/appbar/AppBar.svelte +90 -37
- package/dist/components/nav/appbar/AppBar.svelte.d.ts +9 -2
- package/dist/components/nav/appbar/theme.d.ts +85 -18
- package/dist/components/nav/appbar/theme.js +159 -23
- package/dist/components/nav/appbar/types.d.ts +46 -9
- package/dist/components/nav/breadcrumb/Breadcrumb.stories.svelte +1 -0
- package/dist/components/nav/breadcrumb/theme.js +5 -5
- package/dist/components/nav/navbar/Navbar.mdx +38 -0
- package/dist/components/nav/navbar/Navbar.svelte +1 -1
- package/dist/components/nav/navbar/NavbarItem.svelte +12 -9
- package/dist/components/nav/navbar/theme.js +6 -6
- package/dist/components/nav/rail/Rail.mdx +73 -0
- package/dist/components/nav/rail/Rail.stories.svelte +3 -7
- package/dist/components/nav/rail/Rail.svelte +1 -0
- package/dist/components/nav/rail/RailItem.svelte +12 -9
- package/dist/components/nav/rail/theme.js +13 -13
- package/dist/components/nav/rail/types.d.ts +4 -1
- package/dist/components/nav/tabs/Tabs.mdx +62 -0
- package/dist/components/nav/tabs/Tabs.stories.svelte +1 -1
- package/dist/components/nav/tabs/theme.js +4 -4
- package/dist/components/pill/Pill.mdx +32 -0
- package/dist/components/pill/Pill.stories.svelte +1 -1
- package/dist/components/pill/theme.d.ts +1 -1
- package/dist/components/pill/theme.js +1 -1
- package/dist/components/progress/LinearProgress.svelte +1 -1
- package/dist/components/progress/Progress.mdx +50 -0
- package/dist/components/progress/Progress.stories.svelte +6 -6
- package/dist/components/snackbar/Snackbar.mdx +52 -0
- package/dist/components/snackbar/Snackbar.stories.svelte +5 -5
- package/dist/components/snackbar/Snackbar.svelte +1 -1
- package/dist/components/snackbar/theme.d.ts +3 -3
- package/dist/components/snackbar/theme.js +4 -4
- package/dist/components/table/Table.stories.svelte +1 -0
- package/dist/components/table/TableHeader.svelte +1 -1
- package/dist/components/table/theme.js +3 -3
- package/dist/components/time/TimeField.stories.svelte +3 -2
- package/dist/components/time/TimeField.svelte +1 -1
- package/dist/components/time/TimepickerInput.svelte +1 -1
- package/dist/components/time/theme.js +5 -5
- package/dist/components/toolbar/Toolbar.stories.svelte +1 -0
- package/dist/components/toolbar/Toolbar.svelte +1 -1
- package/dist/components/toolbar/Toolbar.svelte.d.ts +1 -1
- package/dist/components/toolbar/theme.js +14 -14
- package/dist/components/typography/Typography.mdx +67 -0
- package/dist/components/typography/body/Body.stories.svelte +2 -1
- package/dist/components/typography/body/theme.d.ts +15 -12
- package/dist/components/typography/body/theme.js +19 -4
- package/dist/components/typography/body/types.d.ts +2 -1
- package/dist/components/typography/display/Display.stories.svelte +2 -1
- package/dist/components/typography/display/theme.d.ts +15 -12
- package/dist/components/typography/display/theme.js +19 -4
- package/dist/components/typography/display/types.d.ts +2 -1
- package/dist/components/typography/headline/Headline.stories.svelte +2 -1
- package/dist/components/typography/headline/theme.d.ts +15 -12
- package/dist/components/typography/headline/theme.js +19 -4
- package/dist/components/typography/headline/types.d.ts +2 -1
- package/dist/components/typography/kbd/Kbd.stories.svelte +2 -1
- package/dist/components/typography/kbd/theme.d.ts +4 -4
- package/dist/components/typography/kbd/theme.js +2 -2
- package/dist/components/typography/label/Label.stories.svelte +2 -1
- package/dist/components/typography/label/theme.d.ts +15 -12
- package/dist/components/typography/label/theme.js +19 -4
- package/dist/components/typography/label/types.d.ts +2 -1
- package/dist/components/typography/title/Title.stories.svelte +2 -1
- package/dist/components/typography/title/theme.d.ts +15 -12
- package/dist/components/typography/title/theme.js +19 -4
- package/dist/components/typography/title/types.d.ts +2 -1
- package/dist/index.css +1 -0
- package/dist/styles/component.css +78 -175
- package/dist/styles/elevation.css +9 -0
- package/dist/styles/spacing.css +29 -0
- package/dist/styles/typescale.css +635 -20
- package/dist/utils/Layer.svelte +1 -1
- package/dist/utils/icon/Icon.svelte +8 -6
- package/package.json +19 -15
- package/dist/components/containers/stack/HStack.svelte +0 -23
- package/dist/components/containers/stack/HStack.svelte.d.ts +0 -5
- package/dist/components/containers/stack/VStack.svelte +0 -23
- package/dist/components/containers/stack/VStack.svelte.d.ts +0 -5
- package/dist/components/containers/stack/index.d.ts +0 -4
- package/dist/components/containers/stack/theme.d.ts +0 -66
- package/dist/components/containers/stack/theme.js +0 -26
- package/dist/components/containers/stack/types.d.ts +0 -12
- /package/dist/components/containers/{stack → carousel}/types.js +0 -0
|
@@ -1,33 +1,60 @@
|
|
|
1
1
|
import type { IconProps } from '../../../utils/index.js';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { ButtonSize } from '../theme.js';
|
|
3
4
|
import type { ConnectedButtonGroupVariants } from './theme.js';
|
|
5
|
+
export type ConnectedButtonGroupVariant = 'elevated' | 'filled' | 'tonal' | 'outlined';
|
|
4
6
|
export type ConnectedButtonGroupCtx = {
|
|
5
|
-
size:
|
|
7
|
+
size: ButtonSize;
|
|
6
8
|
shape: 'round' | 'square';
|
|
9
|
+
variant: ConnectedButtonGroupVariant;
|
|
10
|
+
type: 'single' | 'multiple';
|
|
11
|
+
value: any;
|
|
7
12
|
};
|
|
8
13
|
export type ConnectedButtonGroupProps = ConnectedButtonGroupVariants & {
|
|
9
|
-
/**
|
|
14
|
+
/** One selected item at a time, or several. */
|
|
10
15
|
type: 'single' | 'multiple';
|
|
11
|
-
/**
|
|
16
|
+
/** The selected value (`single`) or values (`multiple`). Bindable. */
|
|
12
17
|
value?: any;
|
|
18
|
+
/** Called when the selection changes. */
|
|
13
19
|
onValueChange?: (value: any) => void;
|
|
20
|
+
/** Disables every item. */
|
|
14
21
|
disabled?: boolean;
|
|
22
|
+
/** Whether arrow keys wrap from the last item to the first. @default true */
|
|
15
23
|
loop?: boolean;
|
|
24
|
+
/** @default 'horizontal' */
|
|
16
25
|
orientation?: 'horizontal' | 'vertical';
|
|
17
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Toggle button colour style of the items: unselected and selected colours as for `Toggle`.
|
|
28
|
+
* @default 'filled'
|
|
29
|
+
*/
|
|
30
|
+
variant?: ConnectedButtonGroupVariant;
|
|
31
|
+
/**
|
|
32
|
+
* Outer corners: fully round, or square (the inner corner size). Inner corners are the same
|
|
33
|
+
* for both.
|
|
34
|
+
* @default 'round'
|
|
35
|
+
*/
|
|
18
36
|
shape?: ConnectedButtonGroupCtx['shape'];
|
|
19
|
-
/**
|
|
20
|
-
|
|
37
|
+
/**
|
|
38
|
+
* Height, padding and type of the items, as for `Button`: 32, 40, 56, 96 or 136dp.
|
|
39
|
+
* @default 'sm'
|
|
40
|
+
*/
|
|
41
|
+
size?: ButtonSize;
|
|
42
|
+
/** `ConnectedButtonGroupItem`s. */
|
|
21
43
|
children?: Snippet;
|
|
44
|
+
/** Accessible name of the group. */
|
|
45
|
+
'aria-label'?: string;
|
|
22
46
|
class?: string;
|
|
23
47
|
};
|
|
24
48
|
export type ConnectedButtonGroupItemProps = {
|
|
25
|
-
/** The value this item
|
|
49
|
+
/** The value this item selects. */
|
|
26
50
|
value: string;
|
|
27
|
-
/**
|
|
51
|
+
/** The label. */
|
|
28
52
|
label?: string;
|
|
29
|
-
/**
|
|
53
|
+
/** A leading icon. It fills while the item is selected. */
|
|
30
54
|
iconProps?: IconProps;
|
|
55
|
+
/** Accessible name, for an item with only an icon. */
|
|
56
|
+
'aria-label'?: string;
|
|
57
|
+
/** Disables the item. */
|
|
31
58
|
disabled?: boolean;
|
|
32
59
|
class?: string;
|
|
33
60
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type ButtonState = {
|
|
2
|
+
pressed: boolean;
|
|
3
|
+
/** A mouse or pen over the button (never touch, where hover sticks after a tap). */
|
|
4
|
+
hovered: boolean;
|
|
5
|
+
focusVisible: boolean;
|
|
6
|
+
};
|
|
7
|
+
/** Corner radii in px, in logical order: start-start, start-end, end-end, end-start. */
|
|
8
|
+
export type Corners = [number, number, number, number];
|
|
9
|
+
type CornerResolver = (el: HTMLElement, state: ButtonState, px: (prop: string) => number) => Corners;
|
|
10
|
+
/** Springs `el`'s four corners to whatever `corners` resolves for its current state. */
|
|
11
|
+
export declare function shapeMorph(el: HTMLElement, corners: CornerResolver): () => void;
|
|
12
|
+
/** Button, Toggle, ButtonIcon: --btn-shape at rest, --btn-pressed while pressed. */
|
|
13
|
+
export declare const buttonCorners: CornerResolver;
|
|
14
|
+
/**
|
|
15
|
+
* Split button halves. Outer corners stay round; inner corners are --split-inner at rest,
|
|
16
|
+
* --split-active while hovered, focused or pressed, and fully round on the trailing button while
|
|
17
|
+
* its menu is open.
|
|
18
|
+
*/
|
|
19
|
+
export declare const splitCorners: (side: "leading" | "trailing") => CornerResolver;
|
|
20
|
+
/**
|
|
21
|
+
* Connected button group items. Inner corners (facing a neighbour) are --cbg-inner, then
|
|
22
|
+
* --cbg-pressed while pressed and fully round while selected; outer corners (the group's ends)
|
|
23
|
+
* are --cbg-outer.
|
|
24
|
+
*/
|
|
25
|
+
export declare const connectedCorners: CornerResolver;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { springTokens, springTransition } from '../../animation/spring.js';
|
|
2
|
+
import { animate, motionValue } from 'motion';
|
|
3
|
+
const CORNER_PROPS = [
|
|
4
|
+
'borderStartStartRadius',
|
|
5
|
+
'borderStartEndRadius',
|
|
6
|
+
'borderEndEndRadius',
|
|
7
|
+
'borderEndStartRadius'
|
|
8
|
+
];
|
|
9
|
+
/** A length custom property in px. Handles the px, rem and em values the button classes use. */
|
|
10
|
+
const lengthVar = (el, style, prop) => {
|
|
11
|
+
const value = style.getPropertyValue(prop).trim();
|
|
12
|
+
const n = parseFloat(value);
|
|
13
|
+
if (Number.isNaN(n))
|
|
14
|
+
return 0;
|
|
15
|
+
if (value.endsWith('rem'))
|
|
16
|
+
return n * parseFloat(getComputedStyle(document.documentElement).fontSize);
|
|
17
|
+
if (value.endsWith('em'))
|
|
18
|
+
return n * parseFloat(style.fontSize);
|
|
19
|
+
if (value.endsWith('%'))
|
|
20
|
+
return (n / 100) * Math.min(el.offsetWidth, el.offsetHeight);
|
|
21
|
+
return n;
|
|
22
|
+
};
|
|
23
|
+
const isDisabled = (el) => el.matches(':disabled, [aria-disabled="true"], [data-disabled]');
|
|
24
|
+
/** Springs `el`'s four corners to whatever `corners` resolves for its current state. */
|
|
25
|
+
export function shapeMorph(el, corners) {
|
|
26
|
+
const reduced = matchMedia('(prefers-reduced-motion: reduce)');
|
|
27
|
+
const spring = springTransition(springTokens.fastSpatial);
|
|
28
|
+
const state = { pressed: false, hovered: false, focusVisible: false };
|
|
29
|
+
const resolve = () => {
|
|
30
|
+
const style = getComputedStyle(el);
|
|
31
|
+
return corners(el, state, (prop) => lengthVar(el, style, prop));
|
|
32
|
+
};
|
|
33
|
+
const initial = resolve();
|
|
34
|
+
const values = initial.map((r) => motionValue(r));
|
|
35
|
+
const controls = [];
|
|
36
|
+
const unsubscribe = values.map((v, i) => v.on('change', (r) => (el.style[CORNER_PROPS[i]] = `${r}px`)));
|
|
37
|
+
values.forEach((v, i) => (el.style[CORNER_PROPS[i]] = `${v.get()}px`));
|
|
38
|
+
// Each spring restarts only when its target changes; a retarget mid-flight inherits velocity.
|
|
39
|
+
const targets = [...initial];
|
|
40
|
+
const retarget = () => {
|
|
41
|
+
resolve().forEach((to, i) => {
|
|
42
|
+
if (to === targets[i])
|
|
43
|
+
return;
|
|
44
|
+
targets[i] = to;
|
|
45
|
+
controls[i]?.stop();
|
|
46
|
+
if (reduced.matches)
|
|
47
|
+
values[i].jump(to);
|
|
48
|
+
else
|
|
49
|
+
controls[i] = animate(values[i], to, spring);
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
const set = (key, on) => {
|
|
53
|
+
if (state[key] === on)
|
|
54
|
+
return;
|
|
55
|
+
state[key] = on;
|
|
56
|
+
retarget();
|
|
57
|
+
};
|
|
58
|
+
const onPointerDown = (e) => {
|
|
59
|
+
if (e.button === 0 && !isDisabled(el))
|
|
60
|
+
set('pressed', true);
|
|
61
|
+
};
|
|
62
|
+
const onKeyDown = (e) => {
|
|
63
|
+
if (!e.repeat && (e.key === ' ' || e.key === 'Enter') && !isDisabled(el))
|
|
64
|
+
set('pressed', true);
|
|
65
|
+
};
|
|
66
|
+
const release = () => set('pressed', false);
|
|
67
|
+
const onEnter = (e) => {
|
|
68
|
+
if (e.pointerType !== 'touch')
|
|
69
|
+
set('hovered', true);
|
|
70
|
+
};
|
|
71
|
+
const onLeave = () => set('hovered', false);
|
|
72
|
+
const onFocus = () => set('focusVisible', el.matches(':focus-visible'));
|
|
73
|
+
const onBlur = () => {
|
|
74
|
+
state.pressed = false;
|
|
75
|
+
set('focusVisible', false);
|
|
76
|
+
};
|
|
77
|
+
// Selection, open state, size and shape arrive as attribute changes. Not `style`: the springs
|
|
78
|
+
// write the corners there every frame.
|
|
79
|
+
const observer = new MutationObserver(retarget);
|
|
80
|
+
observer.observe(el, {
|
|
81
|
+
attributes: true,
|
|
82
|
+
attributeFilter: ['class', 'data-state', 'aria-pressed', 'aria-expanded']
|
|
83
|
+
});
|
|
84
|
+
el.addEventListener('pointerdown', onPointerDown);
|
|
85
|
+
el.addEventListener('pointerenter', onEnter);
|
|
86
|
+
el.addEventListener('pointerleave', onLeave);
|
|
87
|
+
el.addEventListener('keydown', onKeyDown);
|
|
88
|
+
el.addEventListener('keyup', release);
|
|
89
|
+
el.addEventListener('focus', onFocus);
|
|
90
|
+
el.addEventListener('blur', onBlur);
|
|
91
|
+
window.addEventListener('pointerup', release);
|
|
92
|
+
window.addEventListener('pointercancel', release);
|
|
93
|
+
return () => {
|
|
94
|
+
observer.disconnect();
|
|
95
|
+
controls.forEach((c) => c?.stop());
|
|
96
|
+
unsubscribe.forEach((u) => u());
|
|
97
|
+
el.removeEventListener('pointerdown', onPointerDown);
|
|
98
|
+
el.removeEventListener('pointerenter', onEnter);
|
|
99
|
+
el.removeEventListener('pointerleave', onLeave);
|
|
100
|
+
el.removeEventListener('keydown', onKeyDown);
|
|
101
|
+
el.removeEventListener('keyup', release);
|
|
102
|
+
el.removeEventListener('focus', onFocus);
|
|
103
|
+
el.removeEventListener('blur', onBlur);
|
|
104
|
+
window.removeEventListener('pointerup', release);
|
|
105
|
+
window.removeEventListener('pointercancel', release);
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const all = (r) => [r, r, r, r];
|
|
109
|
+
/** Button, Toggle, ButtonIcon: --btn-shape at rest, --btn-pressed while pressed. */
|
|
110
|
+
export const buttonCorners = (_el, { pressed }, px) => all(pressed ? px('--btn-pressed') || px('--btn-shape') : px('--btn-shape'));
|
|
111
|
+
/**
|
|
112
|
+
* Split button halves. Outer corners stay round; inner corners are --split-inner at rest,
|
|
113
|
+
* --split-active while hovered, focused or pressed, and fully round on the trailing button while
|
|
114
|
+
* its menu is open.
|
|
115
|
+
*/
|
|
116
|
+
export const splitCorners = (side) => (el, { pressed, hovered, focusVisible }, px) => {
|
|
117
|
+
const outer = px('--btn-round');
|
|
118
|
+
const open = side === 'trailing' && el.dataset.state === 'open';
|
|
119
|
+
const active = (pressed || hovered || focusVisible) && !isDisabled(el);
|
|
120
|
+
const inner = open ? outer : active ? px('--split-active') : px('--split-inner');
|
|
121
|
+
return side === 'leading' ? [outer, inner, inner, outer] : [inner, outer, outer, inner];
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Connected button group items. Inner corners (facing a neighbour) are --cbg-inner, then
|
|
125
|
+
* --cbg-pressed while pressed and fully round while selected; outer corners (the group's ends)
|
|
126
|
+
* are --cbg-outer.
|
|
127
|
+
*/
|
|
128
|
+
export const connectedCorners = (el, { pressed }, px) => {
|
|
129
|
+
const selected = el.dataset.state === 'on';
|
|
130
|
+
const inner = pressed && !isDisabled(el)
|
|
131
|
+
? px('--cbg-pressed')
|
|
132
|
+
: selected
|
|
133
|
+
? px('--btn-round')
|
|
134
|
+
: px('--cbg-inner');
|
|
135
|
+
const outer = px('--cbg-outer');
|
|
136
|
+
const first = el.parentElement?.firstElementChild === el;
|
|
137
|
+
const last = el.parentElement?.lastElementChild === el;
|
|
138
|
+
const s = first ? outer : inner;
|
|
139
|
+
const e = last ? outer : inner;
|
|
140
|
+
// Horizontal: the start corners face the previous item. Vertical: the top corners do.
|
|
141
|
+
return el.dataset.orientation === 'vertical' ? [s, s, e, e] : [s, e, e, s];
|
|
142
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Meta, Title, Subtitle, Canvas, Controls } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as SplitStories from './SplitButton.stories.svelte';
|
|
3
|
+
|
|
4
|
+
<Meta of={SplitStories} />
|
|
5
|
+
|
|
6
|
+
<Title />
|
|
7
|
+
|
|
8
|
+
<Subtitle>Split buttons open a menu of options related to their main action.</Subtitle>
|
|
9
|
+
|
|
10
|
+
[M3 spec](https://m3.material.io/components/split-button/specs) ·
|
|
11
|
+
`import { SplitButton } from '@noxlovette/material';`
|
|
12
|
+
|
|
13
|
+
<Canvas of={SplitStories.Playground} />
|
|
14
|
+
|
|
15
|
+
<Controls of={SplitStories.Playground} />
|
|
16
|
+
|
|
17
|
+
## Anatomy
|
|
18
|
+
|
|
19
|
+
- **Leading button:** the main action, with a label, an icon, or both. An icon-only leading
|
|
20
|
+
button needs an `aria-label`.
|
|
21
|
+
- **Trailing button:** always a menu icon. It opens the menu (`menuLabel` names it) and flips the
|
|
22
|
+
icon while open.
|
|
23
|
+
|
|
24
|
+
The two share one colour style (elevated, filled, tonal or outlined; there is no text split
|
|
25
|
+
button), and opening the menu doesn't change their colours.
|
|
26
|
+
|
|
27
|
+
<Canvas of={SplitStories.WithLeadingIcon} />
|
|
28
|
+
|
|
29
|
+
## Shape and size
|
|
30
|
+
|
|
31
|
+
The buttons sit 2dp apart. Their outer corners are fully round; the inner corners are small at
|
|
32
|
+
rest and round out while hovered, focused or pressed. While the menu is open, the trailing
|
|
33
|
+
button becomes fully round and centres its icon, which sits slightly toward the leading button
|
|
34
|
+
otherwise.
|
|
35
|
+
|
|
36
|
+
| `size` | Height | Inner corner | Hovered/pressed | Trailing width | Menu icon |
|
|
37
|
+
| ------ | ------ | ------------ | --------------- | -------------- | --------- |
|
|
38
|
+
| `xs` | 32dp | 4dp | 8dp | 48dp | 22dp |
|
|
39
|
+
| `sm` | 40dp | 4dp | 12dp | 48dp | 22dp |
|
|
40
|
+
| `md` | 56dp | 4dp | 12dp | 56dp | 26dp |
|
|
41
|
+
| `lg` | 96dp | 8dp | 20dp | 96dp | 38dp |
|
|
42
|
+
| `xl` | 136dp | 12dp | 20dp | 136dp | 50dp |
|
|
43
|
+
|
|
44
|
+
<Canvas of={SplitStories.Sizes} />
|
|
45
|
+
|
|
46
|
+
## Migrating
|
|
47
|
+
|
|
48
|
+
`color` and the `text` variant are gone, and the default size is now `sm`.
|
|
@@ -9,11 +9,7 @@
|
|
|
9
9
|
argTypes: {
|
|
10
10
|
variant: {
|
|
11
11
|
control: 'select',
|
|
12
|
-
options: ['elevated', 'filled', 'tonal', 'outlined'
|
|
13
|
-
},
|
|
14
|
-
color: {
|
|
15
|
-
control: 'select',
|
|
16
|
-
options: ['default', 'primary', 'secondary', 'tertiary', 'error']
|
|
12
|
+
options: ['elevated', 'filled', 'tonal', 'outlined']
|
|
17
13
|
},
|
|
18
14
|
size: {
|
|
19
15
|
control: 'select',
|
|
@@ -22,15 +18,14 @@
|
|
|
22
18
|
},
|
|
23
19
|
args: {
|
|
24
20
|
variant: 'filled',
|
|
25
|
-
|
|
26
|
-
size: 'md'
|
|
21
|
+
size: 'sm'
|
|
27
22
|
}
|
|
28
23
|
});
|
|
29
24
|
</script>
|
|
30
25
|
|
|
31
26
|
<Story name="Playground">
|
|
32
27
|
{#snippet template(args)}
|
|
33
|
-
<SplitButton variant={args.variant}
|
|
28
|
+
<SplitButton variant={args.variant} size={args.size}>
|
|
34
29
|
{#snippet children()}
|
|
35
30
|
Reply
|
|
36
31
|
{/snippet}
|
|
@@ -42,8 +37,8 @@
|
|
|
42
37
|
{/snippet}
|
|
43
38
|
</Story>
|
|
44
39
|
|
|
45
|
-
<Story name="
|
|
46
|
-
<div class="p-
|
|
40
|
+
<Story name="With leading icon" asChild>
|
|
41
|
+
<div class="p-spacing-300">
|
|
47
42
|
<SplitButton iconProps={{ name: 'send' }}>
|
|
48
43
|
{#snippet children()}
|
|
49
44
|
Send
|
|
@@ -57,8 +52,8 @@
|
|
|
57
52
|
</Story>
|
|
58
53
|
|
|
59
54
|
<Story name="Variants" asChild>
|
|
60
|
-
<div class="flex flex-wrap items-center
|
|
61
|
-
{#each ['elevated', 'filled', 'tonal', 'outlined'
|
|
55
|
+
<div class="gap-spacing-300 p-spacing-300 flex flex-wrap items-center">
|
|
56
|
+
{#each ['elevated', 'filled', 'tonal', 'outlined'] as const as variant (variant)}
|
|
62
57
|
<SplitButton {variant}>
|
|
63
58
|
{#snippet children()}
|
|
64
59
|
Reply
|
|
@@ -73,7 +68,7 @@
|
|
|
73
68
|
</Story>
|
|
74
69
|
|
|
75
70
|
<Story name="Sizes" asChild>
|
|
76
|
-
<div class="flex flex-
|
|
71
|
+
<div class="gap-spacing-300 p-spacing-300 flex flex-col items-start">
|
|
77
72
|
{#each ['xs', 'sm', 'md', 'lg', 'xl'] as const as size (size)}
|
|
78
73
|
<SplitButton {size}>
|
|
79
74
|
{#snippet children()}
|
|
@@ -89,7 +84,7 @@
|
|
|
89
84
|
</Story>
|
|
90
85
|
|
|
91
86
|
<Story name="Disabled" asChild>
|
|
92
|
-
<div class="p-
|
|
87
|
+
<div class="p-spacing-300">
|
|
93
88
|
<SplitButton disabled>
|
|
94
89
|
{#snippet children()}
|
|
95
90
|
Reply
|
|
@@ -1,27 +1,25 @@
|
|
|
1
1
|
<!--
|
|
2
2
|
@component
|
|
3
|
-
A leading
|
|
4
|
-
|
|
3
|
+
A split button: a leading button for the main action and a trailing button that opens a menu of
|
|
4
|
+
related ones, such as Send with Schedule send. The two share one colour style and sit 2dp apart;
|
|
5
|
+
their inner corners tighten at rest and round out while hovered, pressed or open.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Compose the dropdown from `MenuItem` (and `Divider`, headings, etc.), the
|
|
9
|
-
same way you would with `Menu`.
|
|
7
|
+
Compose the menu from `MenuItem`s (and `Divider`, headings), as with `Menu`. For one trigger that
|
|
8
|
+
only opens a menu, use `Menu`; for selectable options, `ConnectedButtonGroup`.
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
separate primary action) and `ConnectedButtonGroup` (multiple equal,
|
|
13
|
-
selectable items, no menu).
|
|
14
|
-
|
|
15
|
-
@see https://m3.material.io/components/buttons/guidelines#834f5f31-e363-4d0f-bc4d-abac128f5f0e
|
|
10
|
+
@see https://m3.material.io/components/split-button/specs
|
|
16
11
|
-->
|
|
17
12
|
<script lang="ts">
|
|
18
13
|
import { enterExit, presence } from '../../../animation/index.js';
|
|
19
|
-
import {
|
|
14
|
+
import { Icon, Layer } from '../../../utils/index.js';
|
|
15
|
+
import { Button, DropdownMenu } from 'bits-ui';
|
|
20
16
|
import clsx from 'clsx';
|
|
21
|
-
import
|
|
22
|
-
import
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
17
|
+
import { buttonColor, buttonElevation } from '../theme.js';
|
|
18
|
+
import { menu } from '../../containers/menu/theme.js';
|
|
19
|
+
import { SPLIT_CHEVRON_OFFSET, splitButton } from './theme.js';
|
|
20
|
+
import { animate } from 'motion';
|
|
21
|
+
import { springTokens, springTransition } from '../../../animation/spring.js';
|
|
22
|
+
import { shapeMorph, splitCorners } from '../shapeMorph.js';
|
|
25
23
|
import type { SplitButtonProps } from './types.js';
|
|
26
24
|
|
|
27
25
|
let {
|
|
@@ -30,61 +28,80 @@ selectable items, no menu).
|
|
|
30
28
|
onclick,
|
|
31
29
|
iconProps,
|
|
32
30
|
variant = 'filled',
|
|
33
|
-
|
|
34
|
-
size = 'md',
|
|
31
|
+
size = 'sm',
|
|
35
32
|
disabled = false,
|
|
36
33
|
open = $bindable(false),
|
|
37
34
|
align = 'end',
|
|
38
35
|
menuLabel = 'More options',
|
|
36
|
+
'aria-label': ariaLabel,
|
|
39
37
|
class: className
|
|
40
38
|
}: SplitButtonProps = $props();
|
|
41
39
|
|
|
42
|
-
const cls = $derived(splitButton({
|
|
43
|
-
// Reuse ButtonIcon's own icon-size classes so the chevron matches exactly
|
|
44
|
-
// what ButtonIcon would render — `iconProps.class` fully replaces its
|
|
45
|
-
// internal size classes (see ButtonIcon.svelte), so we recompute them here.
|
|
46
|
-
const chevronCls = $derived(
|
|
47
|
-
clsx(buttonIcon({ variant, color, size, width: 'narrow' }).icon(), cls.icon())
|
|
48
|
-
);
|
|
40
|
+
const cls = $derived(splitButton({ size }));
|
|
49
41
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
|
|
42
|
+
let leadingEl = $state<HTMLElement | null>(null);
|
|
43
|
+
let trailingEl = $state<HTMLElement | null>(null);
|
|
44
|
+
$effect(() => (leadingEl ? shapeMorph(leadingEl, splitCorners('leading')) : undefined));
|
|
45
|
+
$effect(() => (trailingEl ? shapeMorph(trailingEl, splitCorners('trailing')) : undefined));
|
|
46
|
+
|
|
47
|
+
// Open: the menu icon springs to centre (cancelling its resting offset) and flips.
|
|
48
|
+
let chevronEl = $state<HTMLElement | null>(null);
|
|
49
|
+
$effect(() => {
|
|
50
|
+
const el = chevronEl;
|
|
51
|
+
if (!el) return;
|
|
52
|
+
const target = { x: open ? SPLIT_CHEVRON_OFFSET[size] : 0, rotate: open ? 180 : 0 };
|
|
53
|
+
const controls = matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
54
|
+
? animate(el, target, { duration: 0 })
|
|
55
|
+
: animate(el, target, springTransition(springTokens.fastSpatial));
|
|
56
|
+
return () => controls.stop();
|
|
57
|
+
});
|
|
58
|
+
const colorCls = $derived(
|
|
59
|
+
clsx(buttonColor({ variant, state: 'default' }), buttonElevation[variant])
|
|
56
60
|
);
|
|
57
61
|
</script>
|
|
58
62
|
|
|
59
63
|
<div class={cls.root({ class: clsx(className) })}>
|
|
60
|
-
<Button
|
|
61
|
-
{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
<Button.Root
|
|
65
|
+
bind:ref={leadingEl}
|
|
66
|
+
type="button"
|
|
67
|
+
{disabled}
|
|
68
|
+
{onclick}
|
|
69
|
+
aria-label={ariaLabel}
|
|
70
|
+
class={cls.leading({ class: colorCls })}
|
|
71
|
+
data-cy="m3-split-button"
|
|
72
|
+
>
|
|
73
|
+
{#if iconProps}
|
|
74
|
+
<Icon {...iconProps} class={cls.leadingIcon({ class: clsx(iconProps.class) })} />
|
|
75
|
+
{/if}
|
|
76
|
+
{@render children?.()}
|
|
77
|
+
<Layer />
|
|
78
|
+
</Button.Root>
|
|
64
79
|
<DropdownMenu.Root bind:open>
|
|
65
80
|
<DropdownMenu.Trigger {disabled}>
|
|
66
81
|
{#snippet child({ props })}
|
|
67
|
-
<
|
|
68
|
-
{
|
|
69
|
-
|
|
70
|
-
{size}
|
|
71
|
-
{disabled}
|
|
72
|
-
width="narrow"
|
|
73
|
-
style={trailingStyle}
|
|
74
|
-
tooltipContent={menuLabel}
|
|
75
|
-
iconProps={{ name: 'arrow_drop_down', class: chevronCls }}
|
|
82
|
+
<Button.Root
|
|
83
|
+
bind:ref={trailingEl}
|
|
84
|
+
type="button"
|
|
76
85
|
{...props}
|
|
77
|
-
|
|
86
|
+
aria-label={menuLabel}
|
|
87
|
+
class={cls.trailing({ class: colorCls })}
|
|
88
|
+
data-cy="m3-split-button-menu"
|
|
89
|
+
>
|
|
90
|
+
<span bind:this={chevronEl} class="inline-flex">
|
|
91
|
+
<Icon name="keyboard_arrow_down" class={cls.chevron()} />
|
|
92
|
+
</span>
|
|
93
|
+
<Layer />
|
|
94
|
+
</Button.Root>
|
|
78
95
|
{/snippet}
|
|
79
96
|
</DropdownMenu.Trigger>
|
|
80
|
-
|
|
81
97
|
<DropdownMenu.Portal>
|
|
82
98
|
<DropdownMenu.Content {align} sideOffset={4} class="z-100">
|
|
83
99
|
{#snippet child({ wrapperProps, props, open: isOpen })}
|
|
84
|
-
<div {...wrapperProps}
|
|
100
|
+
<div {...wrapperProps}>
|
|
101
|
+
<!-- Menu's own panel, so MenuItem rows look the same here. -->
|
|
85
102
|
<div
|
|
86
103
|
{...props}
|
|
87
|
-
class=
|
|
104
|
+
class={menu().content()}
|
|
88
105
|
{@attach presence(() => isOpen, enterExit.scale)}
|
|
89
106
|
>
|
|
90
107
|
{@render menuChildren()}
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import type { SplitButtonProps } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* A leading
|
|
4
|
-
*
|
|
3
|
+
* A split button: a leading button for the main action and a trailing button that opens a menu of
|
|
4
|
+
* related ones, such as Send with Schedule send. The two share one colour style and sit 2dp apart;
|
|
5
|
+
* their inner corners tighten at rest and round out while hovered, pressed or open.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Compose the dropdown from `MenuItem` (and `Divider`, headings, etc.), the
|
|
9
|
-
* same way you would with `Menu`.
|
|
7
|
+
* Compose the menu from `MenuItem`s (and `Divider`, headings), as with `Menu`. For one trigger that
|
|
8
|
+
* only opens a menu, use `Menu`; for selectable options, `ConnectedButtonGroup`.
|
|
10
9
|
*
|
|
11
|
-
*
|
|
12
|
-
* separate primary action) and `ConnectedButtonGroup` (multiple equal,
|
|
13
|
-
* selectable items, no menu).
|
|
14
|
-
*
|
|
15
|
-
* @see https://m3.material.io/components/buttons/guidelines#834f5f31-e363-4d0f-bc4d-abac128f5f0e
|
|
10
|
+
* @see https://m3.material.io/components/split-button/specs
|
|
16
11
|
*/
|
|
17
12
|
declare const SplitButton: import("svelte").Component<SplitButtonProps, {}, "open">;
|
|
18
13
|
type SplitButton = ReturnType<typeof SplitButton>;
|