@noxlovette/material 0.5.1 → 0.6.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/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 +25 -5
- 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 +46 -16
- package/dist/components/buttons/button-group/theme.js +14 -9
- 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 +34 -19
- package/dist/components/buttons/connected/theme.js +33 -10
- 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 +66 -49
- package/dist/components/buttons/split-button/SplitButton.svelte.d.ts +6 -11
- package/dist/components/buttons/split-button/theme.d.ts +111 -18
- package/dist/components/buttons/split-button/theme.js +75 -17
- package/dist/components/buttons/split-button/types.d.ts +24 -18
- package/dist/components/buttons/theme.d.ts +423 -231
- package/dist/components/buttons/theme.js +287 -381
- 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 +6 -6
- package/dist/components/chips/Chip.mdx +68 -0
- package/dist/components/chips/Chip.stories.svelte +4 -4
- package/dist/components/chips/theme.d.ts +1 -1
- package/dist/components/chips/theme.js +4 -4
- package/dist/components/containers/action-rail/ActionRail.stories.svelte +1 -0
- package/dist/components/containers/action-rail/theme.d.ts +1 -1
- package/dist/components/containers/action-rail/theme.js +2 -2
- package/dist/components/containers/app/theme.d.ts +1 -1
- package/dist/components/containers/app/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.d.ts +1 -1
- package/dist/components/containers/context-menu/theme.js +11 -11
- 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 +2 -2
- package/dist/components/containers/dialogue/theme.d.ts +1 -1
- package/dist/components/containers/dialogue/theme.js +4 -4
- package/dist/components/containers/dialogue/types.d.ts +1 -1
- 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 +7 -7
- package/dist/components/containers/divider/theme.js +3 -3
- package/dist/components/containers/index.d.ts +1 -1
- package/dist/components/containers/index.js +1 -1
- package/dist/components/containers/link-preview/theme.d.ts +1 -1
- package/dist/components/containers/link-preview/theme.js +3 -3
- 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 +141 -14
- 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 +2 -2
- 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/MenuSub.svelte +1 -1
- package/dist/components/containers/menu/menu-item/MenuItem.svelte +1 -1
- package/dist/components/containers/menu/theme.d.ts +1 -1
- package/dist/components/containers/menu/theme.js +9 -9
- 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.d.ts +1 -1
- package/dist/components/containers/pane/theme.js +131 -47
- 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.d.ts +1 -1
- package/dist/components/containers/popover/theme.js +4 -4
- package/dist/components/containers/scroll-area/theme.js +3 -3
- 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 +8 -8
- package/dist/components/date/theme.js +32 -32
- 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.d.ts +1 -1
- package/dist/components/forms/checkbox/theme.js +4 -4
- package/dist/components/forms/command/Command.stories.svelte +1 -0
- package/dist/components/forms/command/theme.d.ts +1 -1
- package/dist/components/forms/command/theme.js +10 -10
- package/dist/components/forms/pin/theme.d.ts +1 -1
- package/dist/components/forms/pin/theme.js +5 -5
- package/dist/components/forms/radio-group/RadioGroup.svelte +1 -1
- package/dist/components/forms/radio-group/theme.d.ts +1 -1
- package/dist/components/forms/radio-group/theme.js +6 -6
- 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 +46 -13
- package/dist/components/forms/search/theme.js +14 -9
- 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 +12 -4
- package/dist/components/forms/select/SelectItem.svelte +1 -1
- package/dist/components/forms/select/theme.d.ts +1 -1
- package/dist/components/forms/select/theme.js +14 -14
- 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 +15 -1
- package/dist/components/forms/slider/theme.js +29 -18
- 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.d.ts +1 -1
- package/dist/components/forms/switch/theme.js +7 -7
- 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.d.ts +1 -1
- package/dist/components/forms/textfield/theme.js +20 -20
- package/dist/components/forms/toggle-group/theme.d.ts +1 -1
- package/dist/components/forms/toggle-group/theme.js +3 -3
- package/dist/components/forms/tooltip/Tooltip.stories.svelte +1 -0
- package/dist/components/forms/tooltip/theme.d.ts +1 -1
- package/dist/components/forms/tooltip/theme.js +4 -4
- 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 +5 -5
- 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 +86 -19
- package/dist/components/nav/appbar/theme.js +160 -24
- 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.d.ts +1 -1
- package/dist/components/nav/breadcrumb/theme.js +6 -6
- 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.d.ts +3 -3
- package/dist/components/nav/navbar/theme.js +7 -7
- 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 +5 -2
- package/dist/components/nav/rail/RailItem.svelte +12 -9
- package/dist/components/nav/rail/theme.d.ts +1 -1
- package/dist/components/nav/rail/theme.js +14 -14
- package/dist/components/nav/rail/types.d.ts +8 -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.d.ts +1 -1
- package/dist/components/nav/tabs/theme.js +5 -5
- package/dist/components/pill/Pill.mdx +32 -0
- package/dist/components/pill/Pill.stories.svelte +1 -1
- package/dist/components/pill/theme.d.ts +2 -2
- package/dist/components/pill/theme.js +2 -2
- package/dist/components/progress/LinearProgress.svelte +2 -2
- 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 +4 -4
- package/dist/components/snackbar/theme.js +5 -5
- package/dist/components/table/Table.stories.svelte +1 -0
- package/dist/components/table/TableHeader.svelte +1 -1
- package/dist/components/table/theme.d.ts +1 -1
- package/dist/components/table/theme.js +4 -4
- package/dist/components/time/TimeField.stories.svelte +3 -2
- package/dist/components/time/TimeField.svelte +2 -2
- package/dist/components/time/TimepickerInput.svelte +1 -1
- package/dist/components/time/theme.d.ts +1 -1
- package/dist/components/time/theme.js +6 -6
- 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.d.ts +1 -1
- package/dist/components/toolbar/theme.js +15 -15
- 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 +16 -13
- package/dist/components/typography/body/theme.js +20 -5
- 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 +16 -13
- package/dist/components/typography/display/theme.js +20 -5
- 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 +16 -13
- package/dist/components/typography/headline/theme.js +20 -5
- 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 +5 -5
- package/dist/components/typography/kbd/theme.js +3 -3
- 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 +20 -5
- 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 +16 -13
- package/dist/components/typography/title/theme.js +20 -5
- package/dist/components/typography/title/types.d.ts +2 -1
- package/dist/index.css +2 -0
- package/dist/styles/component.css +78 -175
- package/dist/styles/elevation.css +9 -0
- package/dist/styles/layers.css +33 -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/dist/utils/icon/theme.d.ts +1 -1
- package/dist/utils/icon/theme.js +1 -1
- package/dist/utils/tv.d.ts +6 -0
- package/dist/utils/tv.js +12 -0
- 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,16 +1,16 @@
|
|
|
1
|
-
import { tv } from '
|
|
1
|
+
import { tv } from '../../../utils/tv.js';
|
|
2
2
|
export const select = tv({
|
|
3
3
|
slots: {
|
|
4
4
|
root: 'relative w-full',
|
|
5
5
|
base: `
|
|
6
|
-
group w-full h-
|
|
6
|
+
group w-full h-spacing-700 px-spacing-0 relative flex items-center
|
|
7
7
|
`,
|
|
8
8
|
trigger: `
|
|
9
9
|
group peer w-full h-full flex items-center justify-between bg-transparent outline-none
|
|
10
10
|
cursor-pointer
|
|
11
11
|
`,
|
|
12
12
|
inputWrapper: `
|
|
13
|
-
relative flex-1 h-full px-
|
|
13
|
+
relative flex-1 h-full px-spacing-200 flex items-center
|
|
14
14
|
`,
|
|
15
15
|
value: `
|
|
16
16
|
w-full bg-transparent outline-none
|
|
@@ -20,25 +20,25 @@ export const select = tv({
|
|
|
20
20
|
truncate text-left
|
|
21
21
|
`,
|
|
22
22
|
leadingIcon: `
|
|
23
|
-
text-md-sys-color-on-surface-variant size-
|
|
23
|
+
text-md-sys-color-on-surface-variant size-spacing-300
|
|
24
24
|
group-has-[[data-state=open]]:text-md-sys-color-primary
|
|
25
|
-
group-data-[invalid]:text-md-sys-color-error ml-
|
|
25
|
+
group-data-[invalid]:text-md-sys-color-error ml-spacing-150 text-[24px]
|
|
26
26
|
`,
|
|
27
27
|
dropdownIcon: `
|
|
28
|
-
mr-
|
|
28
|
+
mr-spacing-150 text-md-sys-color-on-surface-variant size-spacing-300
|
|
29
29
|
group-data-[state=open]:text-md-sys-color-primary
|
|
30
30
|
group-data-[invalid]:text-md-sys-color-error z-20 text-[24px]
|
|
31
31
|
transition-transform md-sys-motion-fast-spatial
|
|
32
32
|
group-data-[state=open]:rotate-180
|
|
33
33
|
`,
|
|
34
34
|
content: `
|
|
35
|
-
z-
|
|
36
|
-
rounded-lg gap-
|
|
37
|
-
shadow-elevation-3 ring-md-sys-color-outline/10 px-
|
|
35
|
+
z-layer-popup min-w-[var(--bits-select-anchor-width)] max-h-96 overflow-y-auto
|
|
36
|
+
rounded-lg gap-spacing-50 bg-md-sys-color-surface-container-high
|
|
37
|
+
shadow-elevation-3 ring-md-sys-color-outline/10 px-spacing-100 py-spacing-50 outline-none
|
|
38
38
|
`,
|
|
39
39
|
item: `
|
|
40
40
|
rounded-sm relative flex w-full cursor-pointer select-none items-center
|
|
41
|
-
px-
|
|
41
|
+
px-spacing-150 py-spacing-100 outline-none
|
|
42
42
|
md-sys-typescale-body-large text-md-sys-color-on-surface
|
|
43
43
|
hover:bg-md-sys-color-on-surface/8
|
|
44
44
|
data-[highlighted]:bg-md-sys-color-on-surface/8
|
|
@@ -48,14 +48,14 @@ export const select = tv({
|
|
|
48
48
|
transition-colors md-sys-motion-fast-effects
|
|
49
49
|
`,
|
|
50
50
|
groupLabel: `
|
|
51
|
-
px-
|
|
51
|
+
px-spacing-150 pt-spacing-100 pb-spacing-50 md-sys-typescale-label-medium
|
|
52
52
|
text-md-sys-color-primary
|
|
53
53
|
`,
|
|
54
54
|
separator: `
|
|
55
|
-
my-
|
|
55
|
+
my-spacing-50 h-px bg-md-sys-color-outline-variant
|
|
56
56
|
`,
|
|
57
57
|
supportingText: `
|
|
58
|
-
px-
|
|
58
|
+
px-spacing-200 pt-spacing-50 flex justify-between
|
|
59
59
|
md-sys-typescale-body-small
|
|
60
60
|
text-md-sys-color-on-surface-variant
|
|
61
61
|
group-data-[invalid]:text-md-sys-color-error
|
|
@@ -67,7 +67,7 @@ export const select = tv({
|
|
|
67
67
|
base: `
|
|
68
68
|
bg-md-sys-color-surface-container-highest
|
|
69
69
|
rounded-t-xs state-layer before:rounded-xs hover:before:bg-md-sys-color-on-surface/8
|
|
70
|
-
after:absolute after:bottom-0 after:left-0 after:right-0 after:h-px after:bg-md-sys-color-on-surface-variant
|
|
70
|
+
after:absolute after:bottom-spacing-0 after:left-spacing-0 after:right-spacing-0 after:h-px after:bg-md-sys-color-on-surface-variant
|
|
71
71
|
after:transition-[height,background-color] after:md-sys-motion-fast-spatial
|
|
72
72
|
hover:after:bg-md-sys-color-on-surface
|
|
73
73
|
has-[[data-state=open]]:after:bg-md-sys-color-primary
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Meta, Title, Subtitle, Canvas, Controls } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as SliderStories from './Slider.stories.svelte';
|
|
3
|
+
|
|
4
|
+
<Meta of={SliderStories} />
|
|
5
|
+
|
|
6
|
+
<Title />
|
|
7
|
+
|
|
8
|
+
<Subtitle>Sliders allow users to make selections from a range of values.</Subtitle>
|
|
9
|
+
|
|
10
|
+
[M3 spec](https://m3.material.io/components/sliders/specs) ·
|
|
11
|
+
`import { Slider } from '@noxlovette/material';`
|
|
12
|
+
|
|
13
|
+
<Canvas of={SliderStories.Playground} />
|
|
14
|
+
|
|
15
|
+
<Controls of={SliderStories.Playground} />
|
|
16
|
+
|
|
17
|
+
This is the M3 Expressive slider. It has two tracks, active and inactive, with a 6dp gap on each
|
|
18
|
+
side of a 4dp bar handle. Bind `value` to read and set it:
|
|
19
|
+
|
|
20
|
+
```svelte
|
|
21
|
+
<script lang="ts">
|
|
22
|
+
let volume = $state(40);
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<Slider bind:value={volume} min={0} max={100} />
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Choosing a size
|
|
29
|
+
|
|
30
|
+
`xs` is the default. Go larger when the slider is the main control on the screen, or when it needs
|
|
31
|
+
inset icons.
|
|
32
|
+
|
|
33
|
+
| Size | Track | Handle | Outer corner | Inset icon |
|
|
34
|
+
| ---- | ----- | ------ | ------------ | ------------ |
|
|
35
|
+
| `xs` | 16dp | 44dp | 8dp | — |
|
|
36
|
+
| `s` | 24dp | 44dp | 8dp | — |
|
|
37
|
+
| `m` | 40dp | 52dp | 12dp | 24dp, 6dp in |
|
|
38
|
+
| `l` | 56dp | 68dp | 16dp | 24dp, 6dp in |
|
|
39
|
+
| `xl` | 96dp | 108dp | 28dp | 32dp, 8dp in |
|
|
40
|
+
|
|
41
|
+
The corners next to the handle are always 2dp.
|
|
42
|
+
|
|
43
|
+
<Canvas of={SliderStories.Sizes} />
|
|
44
|
+
|
|
45
|
+
## Inset icons
|
|
46
|
+
|
|
47
|
+
`leadingIconProps` and `trailingIconProps` put an icon inside the track. M3 defines inset icons
|
|
48
|
+
only for `m`, `l` and `xl`, so they're ignored on `xs` and `s`. When the handle gets too close for
|
|
49
|
+
the icon to fit in its track, the icon moves across the handle into the other track. It also takes
|
|
50
|
+
that track's color.
|
|
51
|
+
|
|
52
|
+
<Canvas of={SliderStories.WithIcons} />
|
|
53
|
+
|
|
54
|
+
## Continuous or discrete
|
|
55
|
+
|
|
56
|
+
Leave `step="any"` for a continuous slider. Set a numeric `step` to make it discrete, and add
|
|
57
|
+
`stops` to show a 4dp stop indicator at each step. With or without `stops`, `endStops` marks the
|
|
58
|
+
end of the track 4dp from its edge. Stops hide within 6dp of the handle, and wherever an inset
|
|
59
|
+
icon covers them.
|
|
60
|
+
|
|
61
|
+
<Canvas of={SliderStories.DiscreteWithStops} />
|
|
62
|
+
|
|
63
|
+
## Value indicator
|
|
64
|
+
|
|
65
|
+
With `showValue`, a 48×44dp indicator shows above the handle while it's dragged or has keyboard
|
|
66
|
+
focus. It sits 12dp above the handle, on inverse-surface. Use `format` to add units or localize
|
|
67
|
+
the number.
|
|
68
|
+
|
|
69
|
+
## States
|
|
70
|
+
|
|
71
|
+
- **Pressed and focused:** the handle narrows from 4dp to 2dp on a fast spatial spring, and the
|
|
72
|
+
6dp gaps follow its edge.
|
|
73
|
+
- **Disabled:** the active track is on-surface at 38% opacity, the inactive track 12%, and the
|
|
74
|
+
handle 38%.
|
|
75
|
+
|
|
76
|
+
<Canvas of={SliderStories.Disabled} />
|
|
77
|
+
|
|
78
|
+
## Accessibility
|
|
79
|
+
|
|
80
|
+
- **Keyboard:** the arrow keys move by one step, and Home/End jump to `min`/`max` (via bits-ui's
|
|
81
|
+
`Slider.Root`).
|
|
82
|
+
- **Focus:** keyboard focus narrows the handle, draws an outline around it, and reveals the value
|
|
83
|
+
indicator.
|
|
84
|
+
- **Labelling:** give the slider an accessible name, such as `aria-label="Volume"`. Inset icons
|
|
85
|
+
are decorative and don't label it.
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
|
|
37
37
|
<Story name="Playground">
|
|
38
38
|
{#snippet template(args)}
|
|
39
|
-
<div class="max-w-sm
|
|
39
|
+
<div class="p-spacing-500 max-w-sm">
|
|
40
40
|
<Slider {...args} />
|
|
41
41
|
</div>
|
|
42
42
|
{/snippet}
|
|
43
43
|
</Story>
|
|
44
44
|
|
|
45
45
|
<Story name="Sizes" asChild>
|
|
46
|
-
<div class="flex max-w-sm flex-col
|
|
46
|
+
<div class="gap-spacing-400 p-spacing-500 flex max-w-sm flex-col">
|
|
47
47
|
<Slider value={30} size="xs" />
|
|
48
48
|
<Slider value={30} size="s" />
|
|
49
49
|
<Slider value={30} size="m" />
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
</div>
|
|
53
53
|
</Story>
|
|
54
54
|
|
|
55
|
-
<Story name="With Icons" asChild>
|
|
56
|
-
<div class="max-w-sm
|
|
55
|
+
<Story name="With Icons" exportName="WithIcons" asChild>
|
|
56
|
+
<div class="p-spacing-500 max-w-sm">
|
|
57
57
|
<Slider
|
|
58
58
|
value={60}
|
|
59
59
|
size="m"
|
|
@@ -63,14 +63,14 @@
|
|
|
63
63
|
</div>
|
|
64
64
|
</Story>
|
|
65
65
|
|
|
66
|
-
<Story name="Discrete With Stops" asChild>
|
|
67
|
-
<div class="max-w-sm
|
|
66
|
+
<Story name="Discrete With Stops" exportName="DiscreteWithStops" asChild>
|
|
67
|
+
<div class="p-spacing-500 max-w-sm">
|
|
68
68
|
<Slider value={40} step={20} stops />
|
|
69
69
|
</div>
|
|
70
70
|
</Story>
|
|
71
71
|
|
|
72
72
|
<Story name="Disabled" asChild>
|
|
73
|
-
<div class="max-w-sm
|
|
73
|
+
<div class="p-spacing-500 max-w-sm">
|
|
74
74
|
<Slider value={40} disabled />
|
|
75
75
|
</div>
|
|
76
76
|
</Story>
|
|
@@ -41,13 +41,18 @@ the track, a new `value` from outside) springs to it on the fast spatial spring.
|
|
|
41
41
|
|
|
42
42
|
/* M3 slider geometry, in px. */
|
|
43
43
|
const HANDLE_PX = 4;
|
|
44
|
+
/* Pressed and focused handles narrow to 2dp. */
|
|
45
|
+
const HANDLE_NARROW_PX = 2;
|
|
44
46
|
const GAP_PX = 6;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const STOP_CLEARANCE_PX = HANDLE_PX / 2 + GAP_PX;
|
|
47
|
+
/* Stop indicators are 4dp with 4dp trailing space, so their centers sit 6dp in from each end. */
|
|
48
|
+
const STOP_INSET_PX = 6;
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
const
|
|
50
|
+
/* Inset icons exist only on M, L and XL: 24dp/6dp padding, 32dp/8dp on XL. */
|
|
51
|
+
const hasIcons = $derived(size === 'm' || size === 'l' || size === 'xl');
|
|
52
|
+
const iconPx = $derived(size === 'xl' ? 32 : 24);
|
|
53
|
+
const iconPaddingPx = $derived(size === 'xl' ? 8 : 6);
|
|
54
|
+
const leadingIcon = $derived(hasIcons ? leadingIconProps : undefined);
|
|
55
|
+
const trailingIcon = $derived(hasIcons ? trailingIconProps : undefined);
|
|
51
56
|
|
|
52
57
|
const stepValue = $derived(typeof step === 'number' ? step : undefined);
|
|
53
58
|
const range = $derived(max - min);
|
|
@@ -60,17 +65,21 @@ the track, a new `value` from outside) springs to it on the fast spatial spring.
|
|
|
60
65
|
pressed, the handle is being dragged and tracks it directly.
|
|
61
66
|
*/
|
|
62
67
|
let dragging = $state(false);
|
|
68
|
+
let pressed = $state(false);
|
|
69
|
+
let focusVisible = $state(false);
|
|
63
70
|
|
|
64
71
|
const trackDrag: Attachment<HTMLElement> = (node) => {
|
|
65
72
|
const move = () => (dragging = true);
|
|
66
73
|
const release = () => {
|
|
67
74
|
dragging = false;
|
|
75
|
+
pressed = false;
|
|
68
76
|
window.removeEventListener('pointermove', move);
|
|
69
77
|
window.removeEventListener('pointerup', release);
|
|
70
78
|
window.removeEventListener('pointercancel', release);
|
|
71
79
|
};
|
|
72
80
|
const press = () => {
|
|
73
81
|
if (disabled) return;
|
|
82
|
+
pressed = true;
|
|
74
83
|
window.addEventListener('pointermove', move);
|
|
75
84
|
window.addEventListener('pointerup', release);
|
|
76
85
|
window.addEventListener('pointercancel', release);
|
|
@@ -92,6 +101,15 @@ the track, a new `value` from outside) springs to it on the fast spatial spring.
|
|
|
92
101
|
/* The spring may overshoot the ends; the track can't. */
|
|
93
102
|
const pos = $derived(Math.min(1, Math.max(0, fraction.current)));
|
|
94
103
|
|
|
104
|
+
/** Handle thickness: 4dp at rest, 2dp while pressed or keyboard-focused. */
|
|
105
|
+
const handleThickness = new SpringValue(
|
|
106
|
+
() => (pressed || focusVisible ? HANDLE_NARROW_PX : HANDLE_PX),
|
|
107
|
+
springTokens.fastSpatial
|
|
108
|
+
);
|
|
109
|
+
const handlePx = $derived(Math.max(1, handleThickness.current));
|
|
110
|
+
/* The gap is measured from the handle's current edge, so it stays 6dp as the handle narrows. */
|
|
111
|
+
const clearPx = $derived(handlePx / 2 + GAP_PX);
|
|
112
|
+
|
|
95
113
|
/* ---- geometry -------------------------------------------------------------------------- */
|
|
96
114
|
|
|
97
115
|
let trackWidth = $state(0);
|
|
@@ -101,21 +119,19 @@ the track, a new `value` from outside) springs to it on the fast spatial spring.
|
|
|
101
119
|
const start = $derived(vertical ? 'bottom' : 'left');
|
|
102
120
|
const extent = $derived(vertical ? 'height' : 'width');
|
|
103
121
|
|
|
104
|
-
/** Handle center: travels the track inset by half a handle so it never overhangs the ends. */
|
|
122
|
+
/** Handle center: travels the track inset by half a resting handle so it never overhangs the ends. */
|
|
105
123
|
const center = (f: number) => `calc(${HANDLE_PX / 2}px + ${f} * (100% - ${HANDLE_PX}px))`;
|
|
106
124
|
const centerPx = $derived(HANDLE_PX / 2 + pos * (length - HANDLE_PX));
|
|
107
125
|
|
|
108
|
-
const activePx = $derived(centerPx -
|
|
109
|
-
const inactivePx = $derived(length - centerPx -
|
|
126
|
+
const activePx = $derived(centerPx - clearPx);
|
|
127
|
+
const inactivePx = $derived(length - centerPx - clearPx);
|
|
110
128
|
|
|
111
|
-
const
|
|
112
|
-
`${extent}: max(0px, calc(${
|
|
113
|
-
);
|
|
114
|
-
const inactiveStyle = $derived(
|
|
115
|
-
`${extent}: max(0px, calc(${1 - pos} * (100% - ${HANDLE_PX}px) - ${GAP_PX}px))`
|
|
116
|
-
);
|
|
129
|
+
const trackStyle = (f: number) =>
|
|
130
|
+
`${extent}: max(0px, calc(${f} * (100% - ${HANDLE_PX}px) + ${HANDLE_PX / 2 - clearPx}px))`;
|
|
131
|
+
const activeStyle = $derived(trackStyle(pos));
|
|
132
|
+
const inactiveStyle = $derived(trackStyle(1 - pos));
|
|
117
133
|
|
|
118
|
-
/* Stops
|
|
134
|
+
/* Stops span the track inset by STOP_INSET_PX, so the end stops keep their 4dp trailing space. */
|
|
119
135
|
const stopList = $derived.by(() => {
|
|
120
136
|
const output: number[] = [];
|
|
121
137
|
if (stops && stepValue && range > 0) {
|
|
@@ -124,24 +140,24 @@ the track, a new `value` from outside) springs to it on the fast spatial spring.
|
|
|
124
140
|
output.push(1);
|
|
125
141
|
}
|
|
126
142
|
return output.filter((s) => {
|
|
127
|
-
if (
|
|
128
|
-
if (
|
|
129
|
-
return !length || Math.abs(s - pos) * length >
|
|
143
|
+
if (leadingIcon && s === 0) return false;
|
|
144
|
+
if (trailingIcon && s === 1) return false;
|
|
145
|
+
return !length || Math.abs(s - pos) * length > clearPx;
|
|
130
146
|
});
|
|
131
147
|
});
|
|
132
148
|
|
|
133
149
|
/* Icons ride inside their track; when it gets too short they hop across the handle. */
|
|
134
|
-
const iconFits = (trackPx: number) => trackPx >= iconPx +
|
|
150
|
+
const iconFits = (trackPx: number) => trackPx >= iconPx + iconPaddingPx * 2;
|
|
135
151
|
const leadingOnActive = $derived(!length || iconFits(activePx));
|
|
136
152
|
const trailingOnInactive = $derived(!length || iconFits(inactivePx));
|
|
137
153
|
|
|
138
154
|
const leadingOffset = $derived(
|
|
139
|
-
leadingOnActive ?
|
|
155
|
+
leadingOnActive ? iconPaddingPx : centerPx + clearPx + iconPaddingPx
|
|
140
156
|
);
|
|
141
157
|
const trailingOffset = $derived(
|
|
142
158
|
trailingOnInactive
|
|
143
|
-
? length -
|
|
144
|
-
: centerPx -
|
|
159
|
+
? length - iconPaddingPx - iconPx
|
|
160
|
+
: centerPx - clearPx - iconPaddingPx - iconPx
|
|
145
161
|
);
|
|
146
162
|
|
|
147
163
|
const sliderDir = $derived(dir === null || dir === 'auto' ? undefined : dir);
|
|
@@ -175,26 +191,26 @@ the track, a new `value` from outside) springs to it on the fast spatial spring.
|
|
|
175
191
|
{#each stopList as s (s)}
|
|
176
192
|
<div
|
|
177
193
|
class={cls.stop({ class: s < pos ? cls.stopOnActive() : cls.stopOnInactive() })}
|
|
178
|
-
style="{start}: calc(
|
|
194
|
+
style="{start}: calc({STOP_INSET_PX}px + {s} * (100% - {STOP_INSET_PX * 2}px))"
|
|
179
195
|
></div>
|
|
180
196
|
{/each}
|
|
181
197
|
|
|
182
|
-
{#if
|
|
198
|
+
{#if leadingIcon}
|
|
183
199
|
<span
|
|
184
200
|
class={cls.icon({ class: leadingOnActive ? cls.iconOnActive() : cls.iconOnInactive() })}
|
|
185
201
|
style="{start}: {leadingOffset}px"
|
|
186
202
|
>
|
|
187
|
-
<Icon
|
|
203
|
+
<Icon {...leadingIcon} class={cls.iconGlyph({ class: clsx(leadingIcon.class) })} />
|
|
188
204
|
</span>
|
|
189
205
|
{/if}
|
|
190
|
-
{#if
|
|
206
|
+
{#if trailingIcon}
|
|
191
207
|
<span
|
|
192
208
|
class={cls.icon({
|
|
193
209
|
class: trailingOnInactive ? cls.iconOnInactive() : cls.iconOnActive()
|
|
194
210
|
})}
|
|
195
211
|
style="{start}: {trailingOffset}px"
|
|
196
212
|
>
|
|
197
|
-
<Icon
|
|
213
|
+
<Icon {...trailingIcon} class={cls.iconGlyph({ class: clsx(trailingIcon.class) })} />
|
|
198
214
|
</span>
|
|
199
215
|
{/if}
|
|
200
216
|
|
|
@@ -204,7 +220,9 @@ the track, a new `value` from outside) springs to it on the fast spatial spring.
|
|
|
204
220
|
{...thumbProps}
|
|
205
221
|
class={cls.handle()}
|
|
206
222
|
data-active={active || undefined}
|
|
207
|
-
style="{start}: {center(pos)}"
|
|
223
|
+
style="{start}: {center(pos)}; {extent}: {handlePx}px"
|
|
224
|
+
onfocus={(e) => (focusVisible = e.currentTarget.matches(':focus-visible'))}
|
|
225
|
+
onblur={() => (focusVisible = false)}
|
|
208
226
|
></div>
|
|
209
227
|
{/snippet}
|
|
210
228
|
</Slider.Thumb>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { type VariantProps } from '
|
|
1
|
+
import { type VariantProps } from '../../../utils/tv.js';
|
|
2
2
|
/**
|
|
3
3
|
* M3 Expressive slider: an active and an inactive track separated from a bar handle by a 6dp gap.
|
|
4
|
+
* Per-size tokens (track / handle / outer corner / inset icon): XS 16/44/8/–, S 24/44/8/–,
|
|
5
|
+
* M 40/52/12/24, L 56/68/16/24, XL 96/108/28/32. The value indicator sits 12dp above the handle.
|
|
4
6
|
* Track/handle positions are set inline by `Slider.svelte` from one animated value; these slots
|
|
5
7
|
* only carry size, shape and color.
|
|
6
8
|
*
|
|
@@ -16,12 +18,15 @@ export declare const slider: import("tailwind-variants").TVReturnType<{
|
|
|
16
18
|
};
|
|
17
19
|
m: {
|
|
18
20
|
root: string;
|
|
21
|
+
iconGlyph: string;
|
|
19
22
|
};
|
|
20
23
|
l: {
|
|
21
24
|
root: string;
|
|
25
|
+
iconGlyph: string;
|
|
22
26
|
};
|
|
23
27
|
xl: {
|
|
24
28
|
root: string;
|
|
29
|
+
iconGlyph: string;
|
|
25
30
|
};
|
|
26
31
|
};
|
|
27
32
|
vertical: {
|
|
@@ -60,6 +65,7 @@ export declare const slider: import("tailwind-variants").TVReturnType<{
|
|
|
60
65
|
stopOnActive: string;
|
|
61
66
|
stopOnInactive: string;
|
|
62
67
|
icon: string;
|
|
68
|
+
iconGlyph: string;
|
|
63
69
|
iconOnActive: string;
|
|
64
70
|
iconOnInactive: string;
|
|
65
71
|
handle: string;
|
|
@@ -74,12 +80,15 @@ export declare const slider: import("tailwind-variants").TVReturnType<{
|
|
|
74
80
|
};
|
|
75
81
|
m: {
|
|
76
82
|
root: string;
|
|
83
|
+
iconGlyph: string;
|
|
77
84
|
};
|
|
78
85
|
l: {
|
|
79
86
|
root: string;
|
|
87
|
+
iconGlyph: string;
|
|
80
88
|
};
|
|
81
89
|
xl: {
|
|
82
90
|
root: string;
|
|
91
|
+
iconGlyph: string;
|
|
83
92
|
};
|
|
84
93
|
};
|
|
85
94
|
vertical: {
|
|
@@ -118,6 +127,7 @@ export declare const slider: import("tailwind-variants").TVReturnType<{
|
|
|
118
127
|
stopOnActive: string;
|
|
119
128
|
stopOnInactive: string;
|
|
120
129
|
icon: string;
|
|
130
|
+
iconGlyph: string;
|
|
121
131
|
iconOnActive: string;
|
|
122
132
|
iconOnInactive: string;
|
|
123
133
|
handle: string;
|
|
@@ -132,12 +142,15 @@ export declare const slider: import("tailwind-variants").TVReturnType<{
|
|
|
132
142
|
};
|
|
133
143
|
m: {
|
|
134
144
|
root: string;
|
|
145
|
+
iconGlyph: string;
|
|
135
146
|
};
|
|
136
147
|
l: {
|
|
137
148
|
root: string;
|
|
149
|
+
iconGlyph: string;
|
|
138
150
|
};
|
|
139
151
|
xl: {
|
|
140
152
|
root: string;
|
|
153
|
+
iconGlyph: string;
|
|
141
154
|
};
|
|
142
155
|
};
|
|
143
156
|
vertical: {
|
|
@@ -176,6 +189,7 @@ export declare const slider: import("tailwind-variants").TVReturnType<{
|
|
|
176
189
|
stopOnActive: string;
|
|
177
190
|
stopOnInactive: string;
|
|
178
191
|
icon: string;
|
|
192
|
+
iconGlyph: string;
|
|
179
193
|
iconOnActive: string;
|
|
180
194
|
iconOnInactive: string;
|
|
181
195
|
handle: string;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { tv } from '
|
|
1
|
+
import { tv } from '../../../utils/tv.js';
|
|
2
2
|
/**
|
|
3
3
|
* M3 Expressive slider: an active and an inactive track separated from a bar handle by a 6dp gap.
|
|
4
|
+
* Per-size tokens (track / handle / outer corner / inset icon): XS 16/44/8/–, S 24/44/8/–,
|
|
5
|
+
* M 40/52/12/24, L 56/68/16/24, XL 96/108/28/32. The value indicator sits 12dp above the handle.
|
|
4
6
|
* Track/handle positions are set inline by `Slider.svelte` from one animated value; these slots
|
|
5
7
|
* only carry size, shape and color.
|
|
6
8
|
*
|
|
@@ -12,22 +14,22 @@ export const slider = tv({
|
|
|
12
14
|
track: 'pointer-events-none absolute',
|
|
13
15
|
activeTrack: 'bg-md-sys-color-primary group-data-[disabled]:bg-md-sys-color-on-surface/38',
|
|
14
16
|
inactiveTrack: 'bg-md-sys-color-secondary-container group-data-[disabled]:bg-md-sys-color-on-surface/12',
|
|
15
|
-
stop: 'pointer-events-none absolute size-
|
|
17
|
+
stop: 'pointer-events-none absolute size-spacing-50 rounded-full',
|
|
16
18
|
stopOnActive: 'bg-md-sys-color-on-primary group-data-[disabled]:bg-md-sys-color-inverse-on-surface',
|
|
17
19
|
stopOnInactive: 'bg-md-sys-color-on-secondary-container group-data-[disabled]:bg-md-sys-color-on-surface/38',
|
|
18
|
-
icon: 'pointer-events-none absolute',
|
|
20
|
+
icon: 'pointer-events-none absolute flex',
|
|
21
|
+
iconGlyph: '',
|
|
19
22
|
iconOnActive: 'text-md-sys-color-on-primary',
|
|
20
23
|
iconOnInactive: 'text-md-sys-color-on-secondary-container',
|
|
21
24
|
handle: `
|
|
22
25
|
absolute rounded-full bg-md-sys-color-primary outline-none
|
|
23
|
-
transition-[width,height] md-sys-motion-fast-spatial
|
|
24
26
|
focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-md-sys-color-secondary
|
|
25
27
|
group-data-[disabled]:bg-md-sys-color-on-surface/38
|
|
26
28
|
`,
|
|
27
29
|
value: `
|
|
28
|
-
pointer-events-none absolute z-10 flex min-w-
|
|
29
|
-
bg-md-sys-color-inverse-surface px-
|
|
30
|
-
md-sys-typescale-
|
|
30
|
+
pointer-events-none absolute z-10 flex min-w-spacing-600 items-center justify-center rounded-full
|
|
31
|
+
bg-md-sys-color-inverse-surface px-spacing-200 py-spacing-150
|
|
32
|
+
md-sys-typescale-body-medium tracking-[0.5px] text-md-sys-color-inverse-on-surface
|
|
31
33
|
opacity-0 transition-opacity md-sys-motion-effects
|
|
32
34
|
group-has-[[data-slider-thumb]:focus-visible]:opacity-100
|
|
33
35
|
`
|
|
@@ -36,30 +38,39 @@ export const slider = tv({
|
|
|
36
38
|
size: {
|
|
37
39
|
xs: { root: '[--track:1rem] [--handle:2.75rem] [--outer:var(--radius-sm)]' },
|
|
38
40
|
s: { root: '[--track:1.5rem] [--handle:2.75rem] [--outer:var(--radius-sm)]' },
|
|
39
|
-
m: {
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
m: {
|
|
42
|
+
root: '[--track:2.5rem] [--handle:3.25rem] [--outer:var(--radius-md)]',
|
|
43
|
+
iconGlyph: 'size-spacing-300 text-[24px]'
|
|
44
|
+
},
|
|
45
|
+
l: {
|
|
46
|
+
root: '[--track:3.5rem] [--handle:4.25rem] [--outer:var(--radius-lg)]',
|
|
47
|
+
iconGlyph: 'size-spacing-300 text-[24px]'
|
|
48
|
+
},
|
|
49
|
+
xl: {
|
|
50
|
+
root: '[--track:6rem] [--handle:6.75rem] [--outer:var(--radius-xl)]',
|
|
51
|
+
iconGlyph: 'size-spacing-400 text-[32px]'
|
|
52
|
+
}
|
|
42
53
|
},
|
|
43
54
|
vertical: {
|
|
44
55
|
false: {
|
|
45
56
|
root: 'h-[var(--handle)] w-full min-w-40',
|
|
46
57
|
track: 'top-1/2 h-[var(--track)] -translate-y-1/2',
|
|
47
|
-
activeTrack: 'left-0 rounded-l-[var(--outer)] rounded-r-[2px]',
|
|
48
|
-
inactiveTrack: 'right-0 rounded-l-[2px] rounded-r-[var(--outer)]',
|
|
58
|
+
activeTrack: 'left-spacing-0 rounded-l-[var(--outer)] rounded-r-[2px]',
|
|
59
|
+
inactiveTrack: 'right-spacing-0 rounded-l-[2px] rounded-r-[var(--outer)]',
|
|
49
60
|
stop: 'top-1/2 -translate-x-1/2 -translate-y-1/2',
|
|
50
61
|
icon: 'top-1/2 -translate-y-1/2',
|
|
51
|
-
handle: 'top-0 h-full
|
|
52
|
-
value: 'bottom-[calc(100%+
|
|
62
|
+
handle: 'top-spacing-0 h-full -translate-x-1/2',
|
|
63
|
+
value: 'bottom-[calc(100%+12px)] -translate-x-1/2'
|
|
53
64
|
},
|
|
54
65
|
true: {
|
|
55
66
|
root: 'h-full min-h-40 w-[var(--handle)]',
|
|
56
67
|
track: 'left-1/2 w-[var(--track)] -translate-x-1/2',
|
|
57
|
-
activeTrack: 'bottom-0 rounded-t-[2px] rounded-b-[var(--outer)]',
|
|
58
|
-
inactiveTrack: 'top-0 rounded-t-[var(--outer)] rounded-b-[2px]',
|
|
68
|
+
activeTrack: 'bottom-spacing-0 rounded-t-[2px] rounded-b-[var(--outer)]',
|
|
69
|
+
inactiveTrack: 'top-spacing-0 rounded-t-[var(--outer)] rounded-b-[2px]',
|
|
59
70
|
stop: 'left-1/2 -translate-x-1/2 translate-y-1/2',
|
|
60
71
|
icon: 'left-1/2 -translate-x-1/2',
|
|
61
|
-
handle: 'left-0
|
|
62
|
-
value: 'left-[calc(100%+
|
|
72
|
+
handle: 'left-spacing-0 w-full translate-y-1/2',
|
|
73
|
+
value: 'left-[calc(100%+12px)] translate-y-1/2'
|
|
63
74
|
}
|
|
64
75
|
},
|
|
65
76
|
active: {
|
|
@@ -30,11 +30,12 @@ export type SliderProps = Omit<SliderVariants, 'active'> & Omit<HTMLAttributes<H
|
|
|
30
30
|
*/
|
|
31
31
|
showValue?: boolean;
|
|
32
32
|
/**
|
|
33
|
-
* Props for the leading icon.
|
|
33
|
+
* Props for the leading inset icon. M3 only defines inset icons for sizes `m`, `l` and `xl`
|
|
34
|
+
* (24dp, or 32dp on XL); it is ignored on `xs` and `s`.
|
|
34
35
|
*/
|
|
35
36
|
leadingIconProps?: IconProps;
|
|
36
37
|
/**
|
|
37
|
-
* Props for the trailing icon.
|
|
38
|
+
* Props for the trailing inset icon. Only rendered on sizes `m`, `l` and `xl`.
|
|
38
39
|
*/
|
|
39
40
|
trailingIconProps?: IconProps;
|
|
40
41
|
/**
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Meta, Title, Subtitle, Canvas, Controls } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as SwitchStories from './Switch.stories.svelte';
|
|
3
|
+
|
|
4
|
+
<Meta of={SwitchStories} />
|
|
5
|
+
|
|
6
|
+
<Title />
|
|
7
|
+
|
|
8
|
+
<Subtitle>Switches toggle a single setting on or off.</Subtitle>
|
|
9
|
+
|
|
10
|
+
[M3 spec](https://m3.material.io/components/switch/specs) ·
|
|
11
|
+
`import { Switch } from '@noxlovette/material';`
|
|
12
|
+
|
|
13
|
+
<Canvas of={SwitchStories.Playground} />
|
|
14
|
+
|
|
15
|
+
<Controls of={SwitchStories.Playground} />
|
|
16
|
+
|
|
17
|
+
## Icons
|
|
18
|
+
|
|
19
|
+
`icons` controls the thumb icon: `checked` (the default) shows a check only when on, `both`
|
|
20
|
+
shows a check when on and a close icon when off, and `none` shows a plain thumb. Showing icons
|
|
21
|
+
gives a signal that doesn't depend on color alone.
|
|
22
|
+
|
|
23
|
+
<Canvas of={SwitchStories.IconModes} />
|
|
24
|
+
|
|
25
|
+
## Dragging
|
|
26
|
+
|
|
27
|
+
Besides click and tap, the thumb can be dragged: moving it more than 16px toward the other side
|
|
28
|
+
flips the state, like a native mobile switch.
|
|
29
|
+
|
|
30
|
+
```svelte
|
|
31
|
+
<Switch bind:checked={notifications} />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Accessibility
|
|
35
|
+
|
|
36
|
+
- **Role.** The control is a `role="switch"` from bits-ui; Space and Enter toggle it.
|
|
37
|
+
- **Label.** The switch has no built-in label. Wrap it in a `<label>` with visible text, or give
|
|
38
|
+
it an `aria-label`.
|
|
@@ -23,14 +23,14 @@
|
|
|
23
23
|
|
|
24
24
|
<Story name="Playground">
|
|
25
25
|
{#snippet template(args)}
|
|
26
|
-
<div class="p-
|
|
26
|
+
<div class="p-spacing-300">
|
|
27
27
|
<Switch {...args} />
|
|
28
28
|
</div>
|
|
29
29
|
{/snippet}
|
|
30
30
|
</Story>
|
|
31
31
|
|
|
32
32
|
<Story name="Icon Modes" asChild>
|
|
33
|
-
<div class="flex flex-col
|
|
33
|
+
<div class="gap-spacing-200 p-spacing-300 flex flex-col">
|
|
34
34
|
<Switch checked icons="checked" />
|
|
35
35
|
<Switch checked icons="both" />
|
|
36
36
|
<Switch checked icons="none" />
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
</Story>
|
|
39
39
|
|
|
40
40
|
<Story name="States" asChild>
|
|
41
|
-
<div class="flex flex-col
|
|
41
|
+
<div class="gap-spacing-200 p-spacing-300 flex flex-col">
|
|
42
42
|
<Switch checked={false} />
|
|
43
43
|
<Switch checked={true} />
|
|
44
44
|
<Switch checked={false} disabled />
|