@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
|
@@ -203,27 +203,30 @@
|
|
|
203
203
|
<button
|
|
204
204
|
type="button"
|
|
205
205
|
data-demo="ct-card"
|
|
206
|
-
class="bg-md-sys-color-primary-container text-md-sys-color-on-primary-container
|
|
206
|
+
class="bg-md-sys-color-primary-container text-md-sys-color-on-primary-container top-spacing-200 left-spacing-200 gap-spacing-150 p-spacing-150 absolute flex items-center rounded-lg"
|
|
207
207
|
onclick={runContainer}
|
|
208
208
|
>
|
|
209
|
-
{@render shape(pathFourSidedCookie, 'size-
|
|
209
|
+
{@render shape(pathFourSidedCookie, 'size-spacing-500 text-md-sys-color-primary')}
|
|
210
210
|
<span class="md-sys-typescale-label-large">Open</span>
|
|
211
211
|
</button>
|
|
212
212
|
{:else}
|
|
213
213
|
<div
|
|
214
214
|
data-demo="ct-detail"
|
|
215
|
-
class="bg-md-sys-color-surface-container-highest text-md-sys-color-on-surface
|
|
215
|
+
class="bg-md-sys-color-surface-container-highest text-md-sys-color-on-surface inset-spacing-150 gap-spacing-150 absolute flex flex-col items-center justify-center rounded-xl"
|
|
216
216
|
>
|
|
217
217
|
{@render shape(pathFourSidedCookie, 'size-24 text-md-sys-color-primary')}
|
|
218
218
|
<span class="md-sys-typescale-title-medium">Detail</span>
|
|
219
219
|
</div>
|
|
220
220
|
{/if}
|
|
221
221
|
{:else if pattern.id === 'axis'}
|
|
222
|
-
<div
|
|
222
|
+
<div
|
|
223
|
+
data-demo="axis"
|
|
224
|
+
class="inset-spacing-0 gap-spacing-150 absolute flex flex-col items-center justify-center"
|
|
225
|
+
>
|
|
223
226
|
{@render shape(
|
|
224
227
|
pathPentagon,
|
|
225
228
|
[
|
|
226
|
-
'size-
|
|
229
|
+
'size-spacing-800 text-md-sys-color-primary',
|
|
227
230
|
'size-20 text-md-sys-color-secondary',
|
|
228
231
|
'size-24 text-md-sys-color-tertiary'
|
|
229
232
|
][level]
|
|
@@ -233,7 +236,9 @@
|
|
|
233
236
|
</span>
|
|
234
237
|
</div>
|
|
235
238
|
{:else if pattern.id === 'lateral'}
|
|
236
|
-
<div
|
|
239
|
+
<div
|
|
240
|
+
class="inset-x-spacing-0 top-spacing-0 gap-spacing-300 pt-spacing-150 absolute flex justify-center"
|
|
241
|
+
>
|
|
237
242
|
{#each tabs as name, i (name)}
|
|
238
243
|
<span
|
|
239
244
|
class={[
|
|
@@ -245,7 +250,7 @@
|
|
|
245
250
|
</div>
|
|
246
251
|
<div
|
|
247
252
|
data-demo="lateral"
|
|
248
|
-
class="bg-md-sys-color-surface-container
|
|
253
|
+
class="bg-md-sys-color-surface-container inset-x-spacing-150 bottom-spacing-150 absolute top-11 flex items-center justify-center rounded-lg"
|
|
249
254
|
>
|
|
250
255
|
{@render shape(pathFourLeafClover, 'size-24 text-md-sys-color-primary')}
|
|
251
256
|
<span
|
|
@@ -257,7 +262,7 @@
|
|
|
257
262
|
<div
|
|
258
263
|
data-demo="top"
|
|
259
264
|
class={[
|
|
260
|
-
'
|
|
265
|
+
'inset-spacing-150 gap-spacing-150 absolute flex flex-col items-center justify-center rounded-lg',
|
|
261
266
|
destinations[destination].color
|
|
262
267
|
]}
|
|
263
268
|
>
|
|
@@ -267,23 +272,25 @@
|
|
|
267
272
|
{:else if pattern.id === 'enter-exit'}
|
|
268
273
|
{#if pop.mounted}
|
|
269
274
|
<div
|
|
270
|
-
class="bg-md-sys-color-surface-container-high shadow-elevation-3
|
|
275
|
+
class="bg-md-sys-color-surface-container-high shadow-elevation-3 inset-x-spacing-400 inset-y-spacing-300 absolute flex items-center justify-center rounded-xl"
|
|
271
276
|
{@attach pop.attach(enterExit.scale)}
|
|
272
277
|
>
|
|
273
278
|
{@render shape(pathSoftBurst, 'size-24 text-md-sys-color-tertiary')}
|
|
274
279
|
</div>
|
|
275
280
|
{/if}
|
|
276
281
|
{:else if pattern.id === 'skeleton'}
|
|
277
|
-
<div class="
|
|
282
|
+
<div class="inset-spacing-150 absolute grid [&>*]:[grid-area:1/1]">
|
|
278
283
|
{#if !loaded}
|
|
279
|
-
<div class="flex flex-col items-center justify-center
|
|
284
|
+
<div class="gap-spacing-150 flex flex-col items-center justify-center" {@attach skeleton}>
|
|
280
285
|
<div class="bg-md-sys-color-surface-container-highest size-24 rounded-full"></div>
|
|
281
|
-
<div
|
|
286
|
+
<div
|
|
287
|
+
class="bg-md-sys-color-surface-container-highest h-spacing-200 w-28 rounded-full"
|
|
288
|
+
></div>
|
|
282
289
|
</div>
|
|
283
290
|
{/if}
|
|
284
291
|
{#if content.mounted}
|
|
285
292
|
<div
|
|
286
|
-
class="flex flex-col items-center justify-center
|
|
293
|
+
class="gap-spacing-150 flex flex-col items-center justify-center"
|
|
287
294
|
{@attach content.attach(enterExit.fade)}
|
|
288
295
|
>
|
|
289
296
|
{@render shape(pathGem, 'size-24 text-md-sys-color-secondary')}
|
|
@@ -296,10 +303,10 @@
|
|
|
296
303
|
|
|
297
304
|
{#snippet demo(pattern: Pattern, tall = false)}
|
|
298
305
|
<section
|
|
299
|
-
class="bg-md-sys-color-surface-container-low text-md-sys-color-on-surface flex flex-col
|
|
306
|
+
class="bg-md-sys-color-surface-container-low text-md-sys-color-on-surface gap-spacing-150 p-spacing-200 flex flex-col rounded-xl"
|
|
300
307
|
>
|
|
301
|
-
<header class="flex items-start justify-between
|
|
302
|
-
<div class="flex flex-col
|
|
308
|
+
<header class="gap-spacing-150 flex items-start justify-between">
|
|
309
|
+
<div class="gap-spacing-50 flex flex-col">
|
|
303
310
|
<Title size="medium">{pattern.title}</Title>
|
|
304
311
|
<Body size="small" class="text-md-sys-color-on-surface-variant">{pattern.summary}</Body>
|
|
305
312
|
</div>
|
|
@@ -320,7 +327,7 @@
|
|
|
320
327
|
{/snippet}
|
|
321
328
|
|
|
322
329
|
{#snippet toolbar()}
|
|
323
|
-
<div class="flex items-center justify-between
|
|
330
|
+
<div class="gap-spacing-200 flex items-center justify-between">
|
|
324
331
|
<Title size="large">M3 transition patterns</Title>
|
|
325
332
|
<Button variant={looping ? 'filled' : 'outlined'} onclick={() => (looping = !looping)}>
|
|
326
333
|
{looping ? 'Pause loop' : 'Loop'}
|
|
@@ -329,9 +336,12 @@
|
|
|
329
336
|
{/snippet}
|
|
330
337
|
|
|
331
338
|
<Story name="Overview" asChild>
|
|
332
|
-
<div
|
|
339
|
+
<div
|
|
340
|
+
class="bg-md-sys-color-surface gap-spacing-300 p-spacing-300 flex min-h-dvh flex-col"
|
|
341
|
+
{@attach roundRobin}
|
|
342
|
+
>
|
|
333
343
|
{@render toolbar()}
|
|
334
|
-
<div class="
|
|
344
|
+
<div class="gap-spacing-200 grid md:grid-cols-2 xl:grid-cols-3">
|
|
335
345
|
{#each all as pattern (pattern.id)}
|
|
336
346
|
{@render demo(pattern)}
|
|
337
347
|
{/each}
|
|
@@ -341,7 +351,7 @@
|
|
|
341
351
|
|
|
342
352
|
{#snippet single(pattern: Pattern)}
|
|
343
353
|
<div
|
|
344
|
-
class="bg-md-sys-color-surface flex min-h-dvh flex-col
|
|
354
|
+
class="bg-md-sys-color-surface gap-spacing-300 p-spacing-300 flex min-h-dvh flex-col"
|
|
345
355
|
{@attach loop(pattern.run)}
|
|
346
356
|
>
|
|
347
357
|
{@render toolbar()}
|
|
@@ -23,8 +23,10 @@ export interface ContainerTransformOptions {
|
|
|
23
23
|
* the DOM at the same time — `update` swaps one for the other. Browsers without the API just run
|
|
24
24
|
* `update`. A second call while one is running is queued, not interrupted.
|
|
25
25
|
*
|
|
26
|
-
* Not built into any component
|
|
27
|
-
*
|
|
26
|
+
* Not built into any component. FAB → sheet is the FAB's own morph (a clip-path on Motion, in
|
|
27
|
+
* `FAB.svelte`), because M3 keeps that container opaque and changes its colour, which a
|
|
28
|
+
* snapshot cross-fade can't. Card → detail is the app's own navigation, and `Search` is a plain
|
|
29
|
+
* field with no search view to expand into.
|
|
28
30
|
*
|
|
29
31
|
* ```ts
|
|
30
32
|
* containerTransform(
|
|
@@ -15,8 +15,10 @@ import { springTokens, springTransition } from './spring.js';
|
|
|
15
15
|
* the DOM at the same time — `update` swaps one for the other. Browsers without the API just run
|
|
16
16
|
* `update`. A second call while one is running is queued, not interrupted.
|
|
17
17
|
*
|
|
18
|
-
* Not built into any component
|
|
19
|
-
*
|
|
18
|
+
* Not built into any component. FAB → sheet is the FAB's own morph (a clip-path on Motion, in
|
|
19
|
+
* `FAB.svelte`), because M3 keeps that container opaque and changes its colour, which a
|
|
20
|
+
* snapshot cross-fade can't. Card → detail is the app's own navigation, and `Search` is a plain
|
|
21
|
+
* field with no search view to expand into.
|
|
20
22
|
*
|
|
21
23
|
* ```ts
|
|
22
24
|
* containerTransform(
|
|
@@ -53,9 +53,12 @@ export const enterExit = {
|
|
|
53
53
|
enter: enterWith(springTokens.spatial),
|
|
54
54
|
exit
|
|
55
55
|
},
|
|
56
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Side sheet anchored to the inline-end edge. Slides only: no opacity (M3: don't fade sheets).
|
|
58
|
+
* The extra 1rem clears a detached sheet's 16dp margin, so no sliver is left at the edge.
|
|
59
|
+
*/
|
|
57
60
|
sideSheet: {
|
|
58
|
-
hidden: { transform: 'translateX(100%)' },
|
|
61
|
+
hidden: { transform: 'translateX(calc(100% + 1rem))' },
|
|
59
62
|
shown: { transform: 'translateX(0%)' },
|
|
60
63
|
enter: springTransition(springTokens.spatial),
|
|
61
64
|
exit: springTransition(springTokens.effects)
|
|
@@ -10,7 +10,7 @@ import type { Attachment } from 'svelte/attachments';
|
|
|
10
10
|
* Not built into any component — none of them load their own data. Apps apply it to placeholders.
|
|
11
11
|
*
|
|
12
12
|
* ```svelte
|
|
13
|
-
* <div class="bg-md-sys-color-surface-container-highest h-
|
|
13
|
+
* <div class="bg-md-sys-color-surface-container-highest h-spacing-200 rounded-sm" {@attach skeleton}></div>
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
export declare const skeleton: Attachment<HTMLElement>;
|
|
@@ -14,7 +14,7 @@ const PULSE_HOLD_S = 0.5;
|
|
|
14
14
|
* Not built into any component — none of them load their own data. Apps apply it to placeholders.
|
|
15
15
|
*
|
|
16
16
|
* ```svelte
|
|
17
|
-
* <div class="bg-md-sys-color-surface-container-highest h-
|
|
17
|
+
* <div class="bg-md-sys-color-surface-container-highest h-spacing-200 rounded-sm" {@attach skeleton}></div>
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
20
20
|
export const skeleton = (node) => {
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Meta, Title, Subtitle, Canvas, Controls } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as BadgeStories from './Badge.stories.svelte';
|
|
3
|
+
|
|
4
|
+
<Meta of={BadgeStories} />
|
|
5
|
+
|
|
6
|
+
<Title />
|
|
7
|
+
|
|
8
|
+
<Subtitle>
|
|
9
|
+
Badges show notifications, counts, or status information on navigation items and icons.
|
|
10
|
+
</Subtitle>
|
|
11
|
+
|
|
12
|
+
[M3 spec](https://m3.material.io/components/badges/specs) ·
|
|
13
|
+
`import { Badge } from '@noxlovette/material';`
|
|
14
|
+
|
|
15
|
+
<Canvas of={BadgeStories.Playground} />
|
|
16
|
+
|
|
17
|
+
<Controls of={BadgeStories.Playground} />
|
|
18
|
+
|
|
19
|
+
## Choosing a size
|
|
20
|
+
|
|
21
|
+
| Size | Looks like | Use for |
|
|
22
|
+
| ---- | --------------------------------- | ------------------------------------------- |
|
|
23
|
+
| `sm` | 6dp dot, no text | A general notification ("something is new") |
|
|
24
|
+
| `lg` | 16dp-tall pill with a label-small | A specific count |
|
|
25
|
+
|
|
26
|
+
A large badge holds at most four characters, "+" included, so counts above `max` (999 by
|
|
27
|
+
default) show as `999+` in a 16×34dp container. A zero or missing `number` hides a large badge.
|
|
28
|
+
|
|
29
|
+
<Canvas of={BadgeStories.DotSmall} />
|
|
30
|
+
|
|
31
|
+
<Canvas of={BadgeStories.MaxCharacterCount} />
|
|
32
|
+
|
|
33
|
+
## Placement
|
|
34
|
+
|
|
35
|
+
`NavbarItem` and `RailItem` take a `badge` prop (a count, or `-1` for the dot) and place it for
|
|
36
|
+
you. Use `Badge` directly only on icons those components don't cover, such as a custom icon
|
|
37
|
+
button.
|
|
38
|
+
|
|
39
|
+
By default the badge is absolutely positioned, with offsets measured from the **icon's**
|
|
40
|
+
top-trailing corner:
|
|
41
|
+
|
|
42
|
+
- **Small:** its bottom-leading corner sits 6dp down and 6dp in, so the dot fills the icon's
|
|
43
|
+
top-trailing corner.
|
|
44
|
+
- **Large:** its bottom-leading corner sits 14dp down and 12dp in. The badge grows away from the
|
|
45
|
+
icon as the count gets wider.
|
|
46
|
+
|
|
47
|
+
So wrap the icon itself in a `relative inline-flex` element. Don't anchor the badge to a larger
|
|
48
|
+
indicator or button container, or the offsets will be measured from the wrong corner.
|
|
49
|
+
|
|
50
|
+
```svelte
|
|
51
|
+
<span class="relative inline-flex">
|
|
52
|
+
<Icon name="mail" />
|
|
53
|
+
<Badge number={5} />
|
|
54
|
+
</span>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
In normal flow, such as a list item's trailing slot, pass `standalone`. `ListItem`'s `badge`
|
|
58
|
+
prop already does this.
|
|
59
|
+
|
|
60
|
+
<Canvas of={BadgeStories.Standalone} />
|
|
61
|
+
|
|
62
|
+
## Accessibility
|
|
63
|
+
|
|
64
|
+
- **Not announced on its own.** `Badge` renders a plain `<span>` with no role or live region.
|
|
65
|
+
Put the count in the anchor's accessible name (e.g. `aria-label="Inbox, 5 new"`), or use an
|
|
66
|
+
`aria-live` region if changes must be announced.
|
|
67
|
+
- **Contrast.** The badge uses the error/on-error pair in every theme, so its label keeps
|
|
68
|
+
contrast against its own container.
|
|
69
|
+
- **Clipping.** An anchored badge overhangs the icon by 2dp at the top and past the trailing edge
|
|
70
|
+
as it widens. Make sure no ancestor with `overflow: hidden` clips it.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
Badge renders `absolute`
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
Badge renders `absolute` by default, offset from its positioned ancestor's top-trailing corner
|
|
3
|
+
per the M3 spec, so that ancestor must hug the 24dp icon (not a larger indicator container).
|
|
4
|
+
NavbarItem/RailItem already wire this up internally via their `badge` prop; the stories below
|
|
5
|
+
reproduce that same `relative inline-flex` wrapper by hand so Badge can be previewed in
|
|
6
|
+
isolation. `standalone` renders it in normal flow instead (e.g. ListItem's trailing slot).
|
|
7
7
|
-->
|
|
8
8
|
<script module lang="ts">
|
|
9
9
|
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
@@ -18,41 +18,59 @@
|
|
|
18
18
|
control: 'select',
|
|
19
19
|
options: ['sm', 'lg']
|
|
20
20
|
},
|
|
21
|
-
number: { control: 'number' }
|
|
21
|
+
number: { control: 'number' },
|
|
22
|
+
max: { control: 'number' },
|
|
23
|
+
standalone: { control: 'boolean' }
|
|
22
24
|
},
|
|
23
25
|
args: {
|
|
24
26
|
size: 'lg',
|
|
25
|
-
number: 5
|
|
27
|
+
number: 5,
|
|
28
|
+
max: 999,
|
|
29
|
+
standalone: false
|
|
26
30
|
}
|
|
27
31
|
});
|
|
28
32
|
</script>
|
|
29
33
|
|
|
30
34
|
<Story name="Playground">
|
|
31
35
|
{#snippet template(args)}
|
|
32
|
-
<
|
|
36
|
+
<span class="relative inline-flex">
|
|
33
37
|
<Icon name="mail" />
|
|
34
|
-
<Badge size={args.size} number={args.number} />
|
|
35
|
-
</
|
|
38
|
+
<Badge size={args.size} number={args.number} max={args.max} standalone={args.standalone} />
|
|
39
|
+
</span>
|
|
36
40
|
{/snippet}
|
|
37
41
|
</Story>
|
|
38
42
|
|
|
39
|
-
<Story name="Dot (Small)" asChild>
|
|
40
|
-
<
|
|
43
|
+
<Story name="Dot (Small)" exportName="DotSmall" asChild>
|
|
44
|
+
<span class="relative inline-flex">
|
|
41
45
|
<Icon name="notifications" />
|
|
42
46
|
<Badge size="sm" />
|
|
43
|
-
</
|
|
47
|
+
</span>
|
|
44
48
|
</Story>
|
|
45
49
|
|
|
46
|
-
<Story name="Numbered (Large)" asChild>
|
|
47
|
-
<
|
|
50
|
+
<Story name="Numbered (Large)" exportName="NumberedLarge" asChild>
|
|
51
|
+
<span class="relative inline-flex">
|
|
48
52
|
<Icon name="mail" />
|
|
49
53
|
<Badge size="lg" number={7} />
|
|
50
|
-
</
|
|
54
|
+
</span>
|
|
51
55
|
</Story>
|
|
52
56
|
|
|
53
|
-
<Story name="
|
|
54
|
-
<
|
|
57
|
+
<Story name="Two digits" asChild>
|
|
58
|
+
<span class="relative inline-flex">
|
|
55
59
|
<Icon name="mail" />
|
|
56
|
-
<Badge size="lg" number={
|
|
57
|
-
</
|
|
60
|
+
<Badge size="lg" number={42} />
|
|
61
|
+
</span>
|
|
62
|
+
</Story>
|
|
63
|
+
|
|
64
|
+
<Story name="Max character count (999+)" exportName="MaxCharacterCount" asChild>
|
|
65
|
+
<span class="relative inline-flex">
|
|
66
|
+
<Icon name="mail" />
|
|
67
|
+
<Badge size="lg" number={1280} />
|
|
68
|
+
</span>
|
|
69
|
+
</Story>
|
|
70
|
+
|
|
71
|
+
<Story name="Standalone" asChild>
|
|
72
|
+
<span class="gap-spacing-100 inline-flex items-center">
|
|
73
|
+
<Badge size="sm" standalone />
|
|
74
|
+
<Badge size="lg" number={3} standalone />
|
|
75
|
+
</span>
|
|
58
76
|
</Story>
|
|
@@ -12,15 +12,22 @@ Large badges are used for specific counts.
|
|
|
12
12
|
import { badge } from './theme.js';
|
|
13
13
|
import type { BadgeProps } from './types.js';
|
|
14
14
|
|
|
15
|
-
const {
|
|
15
|
+
const {
|
|
16
|
+
number,
|
|
17
|
+
size = 'lg',
|
|
18
|
+
max = 999,
|
|
19
|
+
standalone = false,
|
|
20
|
+
class: className,
|
|
21
|
+
...restProps
|
|
22
|
+
}: BadgeProps = $props();
|
|
16
23
|
|
|
17
|
-
const styling = $derived(badge({ size }));
|
|
24
|
+
const styling = $derived(badge({ size, standalone }));
|
|
18
25
|
</script>
|
|
19
26
|
|
|
20
27
|
{#if size === 'sm' || number}
|
|
21
|
-
<
|
|
28
|
+
<span class={clsx(styling, className)} {...restProps}>
|
|
22
29
|
{#if size !== 'sm' && number}
|
|
23
|
-
{number >
|
|
30
|
+
{number > max ? `${max}+` : number}
|
|
24
31
|
{/if}
|
|
25
|
-
</
|
|
32
|
+
</span>
|
|
26
33
|
{/if}
|
|
@@ -1,16 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M3 badge (https://m3.material.io/components/badges/specs).
|
|
3
|
+
*
|
|
4
|
+
* Anchored offsets are measured from the positioned ancestor's top-trailing corner, so that
|
|
5
|
+
* ancestor must hug the icon (24dp box), not the larger active-indicator container:
|
|
6
|
+
* - small: 6dp, its bottom-leading corner 6dp down / 6dp in from the icon's top-trailing corner,
|
|
7
|
+
* i.e. flush with that corner (`top-spacing-0 right-spacing-0`).
|
|
8
|
+
* - large: 16dp tall, bottom-leading corner 14dp down / 12dp in from the icon's top-trailing
|
|
9
|
+
* corner, i.e. top = 14 − 16 = −2dp, left = 100% − 12dp. Anchored by its leading edge so a
|
|
10
|
+
* wider count grows away from the icon.
|
|
11
|
+
*/
|
|
1
12
|
export declare const badge: import("tailwind-variants").TVReturnType<{
|
|
2
13
|
size: {
|
|
3
|
-
sm: "size-
|
|
4
|
-
lg: "h-
|
|
14
|
+
sm: "size-spacing-75";
|
|
15
|
+
lg: "h-spacing-200 min-w-spacing-200 px-spacing-50 md-sys-typescale-label-small whitespace-nowrap tabular-nums";
|
|
5
16
|
};
|
|
6
|
-
|
|
17
|
+
standalone: {
|
|
18
|
+
true: "relative";
|
|
19
|
+
false: "absolute pointer-events-none";
|
|
20
|
+
};
|
|
21
|
+
}, undefined, "bg-md-sys-color-error text-md-sys-color-on-error rounded-full inline-flex shrink-0 items-center justify-center", {
|
|
7
22
|
size: {
|
|
8
|
-
sm: "size-
|
|
9
|
-
lg: "h-
|
|
23
|
+
sm: "size-spacing-75";
|
|
24
|
+
lg: "h-spacing-200 min-w-spacing-200 px-spacing-50 md-sys-typescale-label-small whitespace-nowrap tabular-nums";
|
|
25
|
+
};
|
|
26
|
+
standalone: {
|
|
27
|
+
true: "relative";
|
|
28
|
+
false: "absolute pointer-events-none";
|
|
10
29
|
};
|
|
11
30
|
}, undefined, import("tailwind-variants").TVReturnTypeLike<{
|
|
12
31
|
size: {
|
|
13
|
-
sm: "size-
|
|
14
|
-
lg: "h-
|
|
32
|
+
sm: "size-spacing-75";
|
|
33
|
+
lg: "h-spacing-200 min-w-spacing-200 px-spacing-50 md-sys-typescale-label-small whitespace-nowrap tabular-nums";
|
|
34
|
+
};
|
|
35
|
+
standalone: {
|
|
36
|
+
true: "relative";
|
|
37
|
+
false: "absolute pointer-events-none";
|
|
15
38
|
};
|
|
16
39
|
}, undefined>>;
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
import { tv } from 'tailwind-variants';
|
|
2
|
+
/**
|
|
3
|
+
* M3 badge (https://m3.material.io/components/badges/specs).
|
|
4
|
+
*
|
|
5
|
+
* Anchored offsets are measured from the positioned ancestor's top-trailing corner, so that
|
|
6
|
+
* ancestor must hug the icon (24dp box), not the larger active-indicator container:
|
|
7
|
+
* - small: 6dp, its bottom-leading corner 6dp down / 6dp in from the icon's top-trailing corner,
|
|
8
|
+
* i.e. flush with that corner (`top-spacing-0 right-spacing-0`).
|
|
9
|
+
* - large: 16dp tall, bottom-leading corner 14dp down / 12dp in from the icon's top-trailing
|
|
10
|
+
* corner, i.e. top = 14 − 16 = −2dp, left = 100% − 12dp. Anchored by its leading edge so a
|
|
11
|
+
* wider count grows away from the icon.
|
|
12
|
+
*/
|
|
2
13
|
export const badge = tv({
|
|
3
|
-
base: 'bg-md-sys-color-error text-md-sys-color-on-error
|
|
14
|
+
base: 'bg-md-sys-color-error text-md-sys-color-on-error rounded-full inline-flex shrink-0 items-center justify-center',
|
|
4
15
|
variants: {
|
|
5
16
|
size: {
|
|
6
|
-
sm: 'size-
|
|
7
|
-
lg: 'h-
|
|
17
|
+
sm: 'size-spacing-75',
|
|
18
|
+
lg: 'h-spacing-200 min-w-spacing-200 px-spacing-50 md-sys-typescale-label-small whitespace-nowrap tabular-nums'
|
|
19
|
+
},
|
|
20
|
+
standalone: {
|
|
21
|
+
true: 'relative',
|
|
22
|
+
false: 'absolute pointer-events-none'
|
|
8
23
|
}
|
|
9
|
-
}
|
|
24
|
+
},
|
|
25
|
+
compoundVariants: [
|
|
26
|
+
{ standalone: false, size: 'sm', class: 'top-spacing-0 right-spacing-0' },
|
|
27
|
+
{ standalone: false, size: 'lg', class: '-top-spacing-25 left-[calc(100%-12px)]' }
|
|
28
|
+
],
|
|
29
|
+
defaultVariants: { size: 'lg', standalone: false }
|
|
10
30
|
});
|
|
@@ -2,17 +2,31 @@ import type { HTMLAttributes } from 'svelte/elements';
|
|
|
2
2
|
import type { VariantProps } from 'tailwind-variants';
|
|
3
3
|
import type { badge } from './theme.js';
|
|
4
4
|
export type BadgeVariants = VariantProps<typeof badge>;
|
|
5
|
-
export type BadgeProps = BadgeVariants & HTMLAttributes<
|
|
5
|
+
export type BadgeProps = BadgeVariants & HTMLAttributes<HTMLSpanElement> & {
|
|
6
6
|
/**
|
|
7
7
|
* The size of the badge.
|
|
8
|
-
* - 'sm': Small badge, no number displayed.
|
|
9
|
-
* - 'lg': Large badge, displays number.
|
|
8
|
+
* - 'sm': Small badge (6dp dot), no number displayed.
|
|
9
|
+
* - 'lg': Large badge (16dp tall), displays number.
|
|
10
10
|
*/
|
|
11
11
|
size?: BadgeVariants['size'];
|
|
12
12
|
/**
|
|
13
13
|
* The number to display in the badge.
|
|
14
|
-
* Values greater than
|
|
14
|
+
* Values greater than `max` are displayed as `${max}+`.
|
|
15
15
|
* If size is 'sm', the number is not displayed.
|
|
16
16
|
*/
|
|
17
17
|
number?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Largest count shown before collapsing to `${max}+`. M3 caps a large badge at four
|
|
20
|
+
* characters including the "+" (16×34dp container), so the default is 999 → "999+".
|
|
21
|
+
* @default 999
|
|
22
|
+
*/
|
|
23
|
+
max?: number;
|
|
24
|
+
/**
|
|
25
|
+
* By default the badge is absolutely positioned on its nearest positioned ancestor's
|
|
26
|
+
* top-trailing corner per the M3 offsets — that ancestor should hug the icon (e.g.
|
|
27
|
+
* `<span class="relative inline-flex">` around a 24dp `Icon`). Set `standalone` to render it
|
|
28
|
+
* in normal flow instead, e.g. in a list item's trailing slot.
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
standalone?: boolean;
|
|
18
32
|
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Meta, Title, Subtitle, Canvas, Controls } from '@storybook/addon-docs/blocks';
|
|
2
|
+
import * as ButtonStories from './Button.stories.svelte';
|
|
3
|
+
|
|
4
|
+
<Meta of={ButtonStories} />
|
|
5
|
+
|
|
6
|
+
<Title />
|
|
7
|
+
|
|
8
|
+
<Subtitle>Buttons prompt most actions in a UI.</Subtitle>
|
|
9
|
+
|
|
10
|
+
[M3 spec](https://m3.material.io/components/buttons/specs) ·
|
|
11
|
+
`import { Button, Toggle } from '@noxlovette/material';`
|
|
12
|
+
|
|
13
|
+
<Canvas of={ButtonStories.Playground} />
|
|
14
|
+
|
|
15
|
+
<Controls of={ButtonStories.Playground} />
|
|
16
|
+
|
|
17
|
+
## Choosing a button
|
|
18
|
+
|
|
19
|
+
One high-emphasis button per screen, for its primary action. Show the rest's importance through
|
|
20
|
+
their colour style.
|
|
21
|
+
|
|
22
|
+
| Emphasis | Use | For example |
|
|
23
|
+
| -------- | --------------------------------------------------------------------- | -------------------- |
|
|
24
|
+
| Highest | `FAB` or extended FAB, for the screen's main action | Compose, Create |
|
|
25
|
+
| High | `Button variant="filled"`: final or unblocking actions | Save, Confirm, Done |
|
|
26
|
+
| High | `SplitButton`: a key action with related options | Send + Schedule send |
|
|
27
|
+
| Medium | `variant="tonal"`: important, a step below filled | Save draft |
|
|
28
|
+
| Medium | `variant="elevated"`: only to stand apart from a patterned background | Add to cart |
|
|
29
|
+
| Medium | `variant="outlined"`: attention without being primary; leaving a flow | View all, Cancel |
|
|
30
|
+
| Low | `variant="text"`: optional actions | Learn more |
|
|
31
|
+
| Low | `ButtonIcon`: compact supplementary actions | Favourite, Print |
|
|
32
|
+
|
|
33
|
+
Put buttons side by side rather than stacked when there's room, with the higher-emphasis one
|
|
34
|
+
for the more important action.
|
|
35
|
+
|
|
36
|
+
<Canvas of={ButtonStories.ColourStyles} />
|
|
37
|
+
|
|
38
|
+
## Sizes
|
|
39
|
+
|
|
40
|
+
| `size` | Height | Padding | Icon | Label |
|
|
41
|
+
| ------ | ------ | ------- | ---- | -------------- |
|
|
42
|
+
| `xs` | 32dp | 12dp | 20dp | label large |
|
|
43
|
+
| `sm` | 40dp | 16dp | 20dp | label large |
|
|
44
|
+
| `md` | 56dp | 24dp | 24dp | title medium |
|
|
45
|
+
| `lg` | 96dp | 48dp | 32dp | headline small |
|
|
46
|
+
| `xl` | 136dp | 64dp | 40dp | headline large |
|
|
47
|
+
|
|
48
|
+
`sm` is the default. XS and S buttons keep a 48dp target area around them, so leave room
|
|
49
|
+
between them (a `ButtonGroup` does). The outline thickens to 2dp at L and 3dp at XL.
|
|
50
|
+
|
|
51
|
+
<Canvas of={ButtonStories.Sizes} />
|
|
52
|
+
|
|
53
|
+
## Shape
|
|
54
|
+
|
|
55
|
+
`round` (default) is fully rounded; `square` has 12, 12, 16, 28 and 28dp corners from XS to XL.
|
|
56
|
+
While pressed, both morph to the same tighter corner (8, 8, 12, 16, 16dp) on the fast spatial
|
|
57
|
+
spring, which carries its velocity when you let go mid-morph, so a quick tap still bounces.
|
|
58
|
+
|
|
59
|
+
<Canvas of={ButtonStories.RoundAndSquare} />
|
|
60
|
+
|
|
61
|
+
## Toggle buttons
|
|
62
|
+
|
|
63
|
+
`Toggle` is a button with a selected state (`aria-pressed`). Selecting changes its colours and
|
|
64
|
+
swaps its shape: round becomes square, square becomes round. It comes in the elevated, filled,
|
|
65
|
+
tonal and outlined styles; there is no text toggle. See **Buttons/Toggle**.
|
|
66
|
+
|
|
67
|
+
## States and accessibility
|
|
68
|
+
|
|
69
|
+
- Hover, focus and press tint the container 8%, 10% and 10% in the content colour. Keyboard
|
|
70
|
+
focus draws a 3dp ring 2dp outside the button.
|
|
71
|
+
- Disabled buttons drop to a 10% on-surface container and 38% on-surface content, and lose
|
|
72
|
+
their elevation. A disabled link gets `aria-disabled` and leaves the tab order.
|
|
73
|
+
- `loading` swaps the icon (or the label, with no icon) for a loading indicator and sets
|
|
74
|
+
`aria-busy`.
|
|
75
|
+
|
|
76
|
+
<Canvas of={ButtonStories.Disabled} />
|
|
77
|
+
|
|
78
|
+
## Where this differs from the spec
|
|
79
|
+
|
|
80
|
+
- The text button's disabled state has no container. Its token lists a 10% container, but the
|
|
81
|
+
spec's figures show none.
|
|
82
|
+
- Shape morphs use the library's fast spatial spring (stiffness 800, damping 0.6) instead of
|
|
83
|
+
the button token's 1400 / 0.9, as every motion here uses the Expressive springs.
|
|
84
|
+
- `color` (primary, secondary, tertiary, error) is gone. M3 has one colour mapping per style;
|
|
85
|
+
restyle with a class if you need another role, keeping 3:1 contrast.
|