@noxlovette/material 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/cards/theme.js +1 -1
- package/dist/components/containers/context-menu/ContextMenu.stories.svelte +71 -0
- package/dist/components/containers/context-menu/ContextMenu.stories.svelte.d.ts +19 -0
- package/dist/components/containers/context-menu/ContextMenu.svelte +2 -2
- package/dist/components/containers/divider/Divider.stories.svelte +62 -0
- package/dist/components/containers/divider/Divider.stories.svelte.d.ts +19 -0
- package/dist/components/containers/divider/Divider.svelte +12 -11
- package/dist/components/containers/divider/types.d.ts +7 -2
- package/dist/components/containers/list/ListItem.stories.svelte +100 -0
- package/dist/components/containers/list/ListItem.stories.svelte.d.ts +19 -0
- package/dist/components/containers/list/theme.js +2 -2
- package/dist/components/containers/merger/InputMerger.svelte +2 -7
- package/dist/components/containers/merger/index.d.ts +1 -0
- package/dist/components/containers/merger/index.js +2 -0
- package/dist/components/containers/merger/theme.d.ts +1 -0
- package/dist/components/containers/merger/theme.js +4 -0
- package/dist/components/containers/panes/SupportingPane.svelte +0 -2
- package/dist/components/forms/command/Command.stories.svelte +86 -0
- package/dist/components/forms/command/Command.stories.svelte.d.ts +19 -0
- package/dist/components/forms/command/theme.js +4 -4
- package/dist/components/forms/tooltip/Tooltip.stories.svelte +90 -0
- package/dist/components/forms/tooltip/Tooltip.stories.svelte.d.ts +19 -0
- package/dist/components/forms/tooltip/Tooltip.svelte +4 -3
- package/dist/components/forms/tooltip/theme.d.ts +3 -0
- package/dist/components/forms/tooltip/theme.js +6 -5
- package/dist/components/misc/Avatar.stories.svelte +55 -0
- package/dist/components/misc/Avatar.stories.svelte.d.ts +19 -0
- package/dist/components/misc/ThemeSettings.svelte +1 -1
- package/dist/components/misc/theme.js +2 -2
- package/dist/components/nav/rail/RailItem.svelte +1 -0
- package/dist/components/nav/tabs/TabHolder.svelte +1 -1
- package/dist/components/nav/tabs/Tabs.stories.svelte +5 -4
- package/dist/components/time/TimepickerInput.svelte +1 -0
- package/dist/components/time/theme.js +2 -2
- package/dist/components/typography/kbd/Kbd.stories.svelte +41 -0
- package/dist/components/typography/kbd/Kbd.stories.svelte.d.ts +19 -0
- package/dist/components/typography/kbd/theme.d.ts +2 -2
- package/dist/components/typography/kbd/theme.js +2 -2
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { tv } from 'tailwind-variants';
|
|
2
2
|
export const card = tv({
|
|
3
3
|
slots: {
|
|
4
|
-
base: 'relative flex flex-col rounded-lg disabled:opacity-[0.38] disabled:bg-sys-color-surface-variant state-layer before:rounded-lg focus:outline-3 focus:outline-md-sys-color-secondary [transition:box-shadow_var(--md-sys-motion-duration,200ms)_var(--md-sys-motion-timing-function,cubic-bezier(0.34,0.8,0.34,1))]',
|
|
4
|
+
base: 'relative flex flex-col rounded-lg disabled:opacity-[0.38] disabled:bg-md-sys-color-surface-variant state-layer before:rounded-lg focus:outline-3 focus:outline-md-sys-color-secondary [transition:box-shadow_var(--md-sys-motion-duration,200ms)_var(--md-sys-motion-timing-function,cubic-bezier(0.34,0.8,0.34,1))]',
|
|
5
5
|
icon: 'size-6 text-[24px] text-md-sys-color-primary'
|
|
6
6
|
},
|
|
7
7
|
variants: {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import ContextMenu from './ContextMenu.svelte';
|
|
4
|
+
|
|
5
|
+
const { Story } = defineMeta({
|
|
6
|
+
title: 'Containers/Context Menu',
|
|
7
|
+
component: ContextMenu
|
|
8
|
+
});
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<Story name="Playground" asChild>
|
|
12
|
+
<ContextMenu
|
|
13
|
+
items={[
|
|
14
|
+
{ label: 'Edit', value: 'edit', iconProps: { name: 'edit' } },
|
|
15
|
+
{ label: 'Duplicate', value: 'duplicate', iconProps: { name: 'content_copy' } },
|
|
16
|
+
{ separator: true },
|
|
17
|
+
{ label: 'Delete', value: 'delete', iconProps: { name: 'delete' } }
|
|
18
|
+
]}
|
|
19
|
+
onselect={(value) => console.log('selected', value)}
|
|
20
|
+
>
|
|
21
|
+
<div
|
|
22
|
+
class="border-md-sys-color-outline text-md-sys-color-on-surface-variant flex size-40 items-center justify-center rounded-lg border border-dashed"
|
|
23
|
+
>
|
|
24
|
+
Right click me
|
|
25
|
+
</div>
|
|
26
|
+
</ContextMenu>
|
|
27
|
+
</Story>
|
|
28
|
+
|
|
29
|
+
<Story name="With Submenu" asChild>
|
|
30
|
+
<ContextMenu
|
|
31
|
+
items={[
|
|
32
|
+
{ label: 'Edit', value: 'edit', iconProps: { name: 'edit' } },
|
|
33
|
+
{ separator: true },
|
|
34
|
+
{
|
|
35
|
+
label: 'Share',
|
|
36
|
+
value: 'share',
|
|
37
|
+
iconProps: { name: 'share' },
|
|
38
|
+
items: [
|
|
39
|
+
{ label: 'Email', value: 'email' },
|
|
40
|
+
{ label: 'Link', value: 'link' }
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{ separator: true },
|
|
44
|
+
{ label: 'Delete', value: 'delete', iconProps: { name: 'delete' } }
|
|
45
|
+
]}
|
|
46
|
+
onselect={(value) => console.log('selected', value)}
|
|
47
|
+
>
|
|
48
|
+
<div
|
|
49
|
+
class="border-md-sys-color-outline text-md-sys-color-on-surface-variant flex size-40 items-center justify-center rounded-lg border border-dashed"
|
|
50
|
+
>
|
|
51
|
+
Right click me
|
|
52
|
+
</div>
|
|
53
|
+
</ContextMenu>
|
|
54
|
+
</Story>
|
|
55
|
+
|
|
56
|
+
<Story name="With Selected Item" asChild>
|
|
57
|
+
<ContextMenu
|
|
58
|
+
selected="name"
|
|
59
|
+
items={[
|
|
60
|
+
{ label: 'Name', value: 'name' },
|
|
61
|
+
{ label: 'Date modified', value: 'date' },
|
|
62
|
+
{ label: 'Size', value: 'size' }
|
|
63
|
+
]}
|
|
64
|
+
>
|
|
65
|
+
<div
|
|
66
|
+
class="border-md-sys-color-outline text-md-sys-color-on-surface-variant flex size-40 items-center justify-center rounded-lg border border-dashed"
|
|
67
|
+
>
|
|
68
|
+
Right click me
|
|
69
|
+
</div>
|
|
70
|
+
</ContextMenu>
|
|
71
|
+
</Story>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import ContextMenu from './ContextMenu.svelte';
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const ContextMenu: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type ContextMenu = InstanceType<typeof ContextMenu>;
|
|
19
|
+
export default ContextMenu;
|
|
@@ -76,7 +76,7 @@ Context menus appear on right-click and provide actions related to the clicked e
|
|
|
76
76
|
mode: 'scale'
|
|
77
77
|
}}
|
|
78
78
|
>
|
|
79
|
-
{#each item.items as subItem}
|
|
79
|
+
{#each item.items as subItem (subItem)}
|
|
80
80
|
{@render MenuItem(subItem)}
|
|
81
81
|
{/each}
|
|
82
82
|
</div>
|
|
@@ -139,7 +139,7 @@ Context menus appear on right-click and provide actions related to the clicked e
|
|
|
139
139
|
mode: 'scale'
|
|
140
140
|
}}
|
|
141
141
|
>
|
|
142
|
-
{#each items as item}
|
|
142
|
+
{#each items as item (item)}
|
|
143
143
|
{@render MenuItem(item)}
|
|
144
144
|
{/each}
|
|
145
145
|
</div>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import Divider from './Divider.svelte';
|
|
4
|
+
import { Body } from '../../../index.js';
|
|
5
|
+
|
|
6
|
+
const { Story } = defineMeta({
|
|
7
|
+
title: 'Containers/Divider',
|
|
8
|
+
component: Divider,
|
|
9
|
+
argTypes: {
|
|
10
|
+
variant: { control: 'select', options: ['full', 'inset', 'wavy'] },
|
|
11
|
+
orientation: { control: 'select', options: ['horizontal', 'vertical'] }
|
|
12
|
+
},
|
|
13
|
+
args: {
|
|
14
|
+
variant: 'full',
|
|
15
|
+
orientation: 'horizontal'
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<Story name="Playground">
|
|
21
|
+
{#snippet template(args)}
|
|
22
|
+
<div class="w-96">
|
|
23
|
+
<Divider variant={args.variant} orientation={args.orientation} />
|
|
24
|
+
</div>
|
|
25
|
+
{/snippet}
|
|
26
|
+
</Story>
|
|
27
|
+
|
|
28
|
+
<Story name="Full" asChild>
|
|
29
|
+
<div class="w-96">
|
|
30
|
+
<Divider variant="full" />
|
|
31
|
+
</div>
|
|
32
|
+
</Story>
|
|
33
|
+
|
|
34
|
+
<Story name="Inset" asChild>
|
|
35
|
+
<div class="w-96">
|
|
36
|
+
<Divider variant="inset" />
|
|
37
|
+
</div>
|
|
38
|
+
</Story>
|
|
39
|
+
|
|
40
|
+
<Story name="Wavy" asChild>
|
|
41
|
+
<div class="w-96">
|
|
42
|
+
<Divider variant="wavy" />
|
|
43
|
+
</div>
|
|
44
|
+
</Story>
|
|
45
|
+
|
|
46
|
+
<Story name="With Label" asChild>
|
|
47
|
+
<div class="w-96">
|
|
48
|
+
<Divider>
|
|
49
|
+
{#snippet children()}
|
|
50
|
+
OR
|
|
51
|
+
{/snippet}
|
|
52
|
+
</Divider>
|
|
53
|
+
</div>
|
|
54
|
+
</Story>
|
|
55
|
+
|
|
56
|
+
<Story name="Vertical" asChild>
|
|
57
|
+
<div class="flex h-24 items-center gap-4">
|
|
58
|
+
<Body>Left</Body>
|
|
59
|
+
<Divider orientation="vertical" />
|
|
60
|
+
<Body>Right</Body>
|
|
61
|
+
</div>
|
|
62
|
+
</Story>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Divider from './Divider.svelte';
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const Divider: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type Divider = InstanceType<typeof Divider>;
|
|
19
|
+
export default Divider;
|
|
@@ -9,7 +9,7 @@ Powered by bits-ui for accessibility.
|
|
|
9
9
|
@see https://m3.material.io/components/divider/overview
|
|
10
10
|
-->
|
|
11
11
|
<script lang="ts">
|
|
12
|
-
import { Separator } from 'bits-ui';
|
|
12
|
+
import { Separator, type SeparatorRootProps } from 'bits-ui';
|
|
13
13
|
import clsx from 'clsx';
|
|
14
14
|
import { hr } from './theme.js';
|
|
15
15
|
import type { HrProps } from './types.js';
|
|
@@ -33,7 +33,6 @@ Powered by bits-ui for accessibility.
|
|
|
33
33
|
);
|
|
34
34
|
let insetClass = $derived(variant === 'inset' ? 'mr-2 ml-4' : '');
|
|
35
35
|
|
|
36
|
-
let host = $state<HTMLDivElement | null>(null);
|
|
37
36
|
let width = $state(0);
|
|
38
37
|
let waveHeight = 12;
|
|
39
38
|
let waveThickness = 1;
|
|
@@ -43,23 +42,20 @@ Powered by bits-ui for accessibility.
|
|
|
43
42
|
let right = $derived(Math.max(left, width - waveThickness * 0.5));
|
|
44
43
|
let wavePath = $derived(width > 0 ? linear(waveAmp, waveCenter, left, right, 0) : '');
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
if (variant !== 'wavy' || !host || typeof window === 'undefined') return;
|
|
45
|
+
function trackWidth(node: HTMLElement) {
|
|
48
46
|
const observer = new ResizeObserver((entries) => {
|
|
49
47
|
const entry = entries[0];
|
|
50
48
|
width = Math.max(0, entry?.contentRect.width ?? 0);
|
|
51
49
|
});
|
|
52
|
-
observer.observe(
|
|
53
|
-
return () =>
|
|
54
|
-
|
|
55
|
-
};
|
|
56
|
-
});
|
|
50
|
+
observer.observe(node);
|
|
51
|
+
return () => observer.disconnect();
|
|
52
|
+
}
|
|
57
53
|
</script>
|
|
58
54
|
|
|
59
55
|
{#if variant === 'wavy'}
|
|
60
56
|
<div
|
|
61
57
|
{...restProps}
|
|
62
|
-
|
|
58
|
+
{@attach trackWidth}
|
|
63
59
|
class={clsx('w-full', insetClass, className)}
|
|
64
60
|
role={decorative ? 'none' : 'separator'}
|
|
65
61
|
aria-orientation={orientation}
|
|
@@ -96,5 +92,10 @@ Powered by bits-ui for accessibility.
|
|
|
96
92
|
<div class={lineClass}></div>
|
|
97
93
|
</div>
|
|
98
94
|
{:else}
|
|
99
|
-
<Separator.Root
|
|
95
|
+
<Separator.Root
|
|
96
|
+
{...restProps as SeparatorRootProps}
|
|
97
|
+
{orientation}
|
|
98
|
+
{decorative}
|
|
99
|
+
class={clsx(styling, className)}
|
|
100
|
+
/>
|
|
100
101
|
{/if}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DivAttrs } from '../../../utils/types.js';
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { HrVariants } from './theme.js';
|
|
4
4
|
/**
|
|
5
5
|
* Props for the Divider component.
|
|
6
6
|
* Dividers are thin lines that group content in lists and layouts.
|
|
7
7
|
*/
|
|
8
|
-
export interface HrProps extends HrVariants,
|
|
8
|
+
export interface HrProps extends HrVariants, DivAttrs {
|
|
9
9
|
/**
|
|
10
10
|
* Optional content to be rendered within the divider (horizontal only).
|
|
11
11
|
* If provided, the divider will show the content centered between two lines.
|
|
@@ -24,4 +24,9 @@ export interface HrProps extends HrVariants, Omit<SeparatorRootProps, 'children'
|
|
|
24
24
|
* @default 'full'
|
|
25
25
|
*/
|
|
26
26
|
variant?: HrVariants['variant'];
|
|
27
|
+
/**
|
|
28
|
+
* Whether the separator is decorative and should be hidden from assistive technologies.
|
|
29
|
+
* @default true
|
|
30
|
+
*/
|
|
31
|
+
decorative?: boolean;
|
|
27
32
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import ListItem from './ListItem.svelte';
|
|
4
|
+
import Icon from '../../../utils/icon/Icon.svelte';
|
|
5
|
+
|
|
6
|
+
const { Story } = defineMeta({
|
|
7
|
+
title: 'Containers/List Item',
|
|
8
|
+
component: ListItem,
|
|
9
|
+
argTypes: {
|
|
10
|
+
headline: { control: 'text' },
|
|
11
|
+
overline: { control: 'text' },
|
|
12
|
+
supporting: { control: 'text' },
|
|
13
|
+
selected: { control: 'boolean' }
|
|
14
|
+
},
|
|
15
|
+
args: {
|
|
16
|
+
headline: 'Headline',
|
|
17
|
+
overline: '',
|
|
18
|
+
supporting: '',
|
|
19
|
+
selected: false
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<Story name="Playground">
|
|
25
|
+
{#snippet template(args)}
|
|
26
|
+
<ul class="w-80">
|
|
27
|
+
<ListItem
|
|
28
|
+
headline={args.headline}
|
|
29
|
+
overline={args.overline}
|
|
30
|
+
supporting={args.supporting}
|
|
31
|
+
selected={args.selected}
|
|
32
|
+
/>
|
|
33
|
+
</ul>
|
|
34
|
+
{/snippet}
|
|
35
|
+
</Story>
|
|
36
|
+
|
|
37
|
+
<Story name="One Line" asChild>
|
|
38
|
+
<ul class="w-80">
|
|
39
|
+
<ListItem headline="Headline" />
|
|
40
|
+
</ul>
|
|
41
|
+
</Story>
|
|
42
|
+
|
|
43
|
+
<Story name="Two Line" asChild>
|
|
44
|
+
<ul class="w-80">
|
|
45
|
+
<ListItem headline="Headline" supporting="Supporting text that describes the item" />
|
|
46
|
+
</ul>
|
|
47
|
+
</Story>
|
|
48
|
+
|
|
49
|
+
<Story name="Three Line" asChild>
|
|
50
|
+
<ul class="w-80">
|
|
51
|
+
<ListItem
|
|
52
|
+
overline="Overline"
|
|
53
|
+
headline="Headline"
|
|
54
|
+
supporting="Supporting text that spans up to two lines before it gets clipped"
|
|
55
|
+
/>
|
|
56
|
+
</ul>
|
|
57
|
+
</Story>
|
|
58
|
+
|
|
59
|
+
<Story name="With Leading Icon" asChild>
|
|
60
|
+
<ul class="w-80">
|
|
61
|
+
<ListItem headline="Headline" supporting="Supporting text">
|
|
62
|
+
{#snippet leading()}
|
|
63
|
+
<Icon name="folder" />
|
|
64
|
+
{/snippet}
|
|
65
|
+
</ListItem>
|
|
66
|
+
</ul>
|
|
67
|
+
</Story>
|
|
68
|
+
|
|
69
|
+
<Story name="With Trailing and Badge" asChild>
|
|
70
|
+
<ul class="w-80">
|
|
71
|
+
<ListItem headline="Headline" supporting="Supporting text" badge={3}>
|
|
72
|
+
{#snippet leading()}
|
|
73
|
+
<Icon name="inbox" />
|
|
74
|
+
{/snippet}
|
|
75
|
+
{#snippet trailing()}
|
|
76
|
+
<Icon name="chevron_right" />
|
|
77
|
+
{/snippet}
|
|
78
|
+
</ListItem>
|
|
79
|
+
</ul>
|
|
80
|
+
</Story>
|
|
81
|
+
|
|
82
|
+
<Story name="Selected" asChild>
|
|
83
|
+
<ul class="w-80">
|
|
84
|
+
<ListItem headline="Headline" supporting="Supporting text" selected>
|
|
85
|
+
{#snippet leading()}
|
|
86
|
+
<Icon name="check_circle" />
|
|
87
|
+
{/snippet}
|
|
88
|
+
</ListItem>
|
|
89
|
+
</ul>
|
|
90
|
+
</Story>
|
|
91
|
+
|
|
92
|
+
<Story name="As Link" asChild>
|
|
93
|
+
<ul class="w-80">
|
|
94
|
+
<ListItem headline="Headline" supporting="Navigates on click" href="#">
|
|
95
|
+
{#snippet leading()}
|
|
96
|
+
<Icon name="link" />
|
|
97
|
+
{/snippet}
|
|
98
|
+
</ListItem>
|
|
99
|
+
</ul>
|
|
100
|
+
</Story>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import ListItem from './ListItem.svelte';
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const ListItem: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type ListItem = InstanceType<typeof ListItem>;
|
|
19
|
+
export default ListItem;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { tv } from 'tailwind-variants';
|
|
2
2
|
export const listiem = tv({
|
|
3
3
|
slots: {
|
|
4
|
-
base: 'bg-md-sys-color-surface text-sys-color-on-surface-variant state-layer disabled:before:bg-md-sys-color-on-surface/10 md-sys-state-focus-indicator px-4 py-2 gap-4 items-center relative flex rounded-lg before:rounded-lg w-full',
|
|
4
|
+
base: 'bg-md-sys-color-surface text-md-sys-color-on-surface-variant state-layer disabled:before:bg-md-sys-color-on-surface/10 md-sys-state-focus-indicator px-4 py-2 gap-4 items-center relative flex rounded-lg before:rounded-lg w-full',
|
|
5
5
|
leading: 'inline-flex items-start',
|
|
6
6
|
body: 'min-w-0',
|
|
7
7
|
overline: 'md-sys-typescale-label-small line-clamp-1',
|
|
8
8
|
headline: 'text-md-sys-color-on-surface md-sys-typescale-body-large line-clamp-1',
|
|
9
|
-
supporting: 'md-sys-typescale-
|
|
9
|
+
supporting: 'md-sys-typescale-body-medium line-clamp-2',
|
|
10
10
|
trailing: 'size-6 text-[24px] inline-flex items-start ml-auto'
|
|
11
11
|
},
|
|
12
12
|
variants: {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
InputMerger is a container that groups multiple input components together visually.
|
|
4
4
|
-->
|
|
5
5
|
<script lang="ts">
|
|
6
|
-
import
|
|
6
|
+
import { inputMerger } from './theme.js';
|
|
7
7
|
|
|
8
8
|
interface Props {
|
|
9
9
|
/**
|
|
@@ -19,11 +19,6 @@ InputMerger is a container that groups multiple input components together visual
|
|
|
19
19
|
let { children, class: className = '' }: Props = $props();
|
|
20
20
|
</script>
|
|
21
21
|
|
|
22
|
-
<div
|
|
23
|
-
class={clsx(
|
|
24
|
-
className,
|
|
25
|
-
'border-primary padding-default gap-narrow grid max-h-max w-full shrink rounded-none border-x-0 px-0 md:rounded-2xl md:border-x-2 md:px-2.5'
|
|
26
|
-
)}
|
|
27
|
-
>
|
|
22
|
+
<div class={inputMerger({ class: className })}>
|
|
28
23
|
{@render children()}
|
|
29
24
|
</div>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
// THIS FILE IS AUTO-GENERATED BY scripts/generate-components-index.ts - DO NOT EDIT MANUALLY
|
|
2
|
+
// re-export TS/JS modules from this folder
|
|
3
|
+
export * from './theme.js';
|
|
2
4
|
// default exports for components in this folder
|
|
3
5
|
export { default as InputMerger } from './InputMerger.svelte';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const inputMerger: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "grid max-h-max w-full shrink gap-2 rounded-none border-x-0 border-md-sys-color-outline-variant px-0 py-2 md:rounded-2xl md:border-x-2 md:px-2.5", {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "grid max-h-max w-full shrink gap-2 rounded-none border-x-0 border-md-sys-color-outline-variant px-0 py-2 md:rounded-2xl md:border-x-2 md:px-2.5", unknown, unknown, undefined>>;
|
|
@@ -62,7 +62,6 @@ SupportingPane provides a layout with a main content area and a supporting side
|
|
|
62
62
|
mobileTriggerClass
|
|
63
63
|
}: SupportingPaneProps = $props();
|
|
64
64
|
|
|
65
|
-
let entered = $state(false);
|
|
66
65
|
let supportingVisible = $state(true);
|
|
67
66
|
let mobileSheetOpen = $state(false);
|
|
68
67
|
let isLargeScreen = $state(false);
|
|
@@ -140,7 +139,6 @@ SupportingPane provides a layout with a main content area and a supporting side
|
|
|
140
139
|
class={supportingCls({
|
|
141
140
|
class: clsx(supportingClass, inlineSupportingClass)
|
|
142
141
|
})}
|
|
143
|
-
data-entered={entered}
|
|
144
142
|
data-position={position}
|
|
145
143
|
>
|
|
146
144
|
{@render supporting()}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import Command from './Command.svelte';
|
|
4
|
+
import CommandInput from './CommandInput.svelte';
|
|
5
|
+
import CommandList from './CommandList.svelte';
|
|
6
|
+
import CommandEmpty from './CommandEmpty.svelte';
|
|
7
|
+
import CommandGroup from './CommandGroup.svelte';
|
|
8
|
+
import CommandItem from './CommandItem.svelte';
|
|
9
|
+
import CommandSeparator from './CommandSeparator.svelte';
|
|
10
|
+
import Icon from '../../../utils/icon/Icon.svelte';
|
|
11
|
+
import { command } from './theme.js';
|
|
12
|
+
|
|
13
|
+
const { itemIcon } = command();
|
|
14
|
+
|
|
15
|
+
const { Story } = defineMeta({
|
|
16
|
+
title: 'Forms/Command',
|
|
17
|
+
component: Command
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<Story name="Playground" asChild>
|
|
22
|
+
<div class="w-96">
|
|
23
|
+
<Command>
|
|
24
|
+
<CommandInput placeholder="Type a command or search..." />
|
|
25
|
+
<CommandList>
|
|
26
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
27
|
+
<CommandGroup heading="Suggestions">
|
|
28
|
+
<CommandItem value="calendar">
|
|
29
|
+
<Icon name="calendar_today" class={itemIcon()} />
|
|
30
|
+
Calendar
|
|
31
|
+
</CommandItem>
|
|
32
|
+
<CommandItem value="search-emoji">
|
|
33
|
+
<Icon name="mood" class={itemIcon()} />
|
|
34
|
+
Search Emoji
|
|
35
|
+
</CommandItem>
|
|
36
|
+
<CommandItem value="calculator">
|
|
37
|
+
<Icon name="calculate" class={itemIcon()} />
|
|
38
|
+
Calculator
|
|
39
|
+
</CommandItem>
|
|
40
|
+
</CommandGroup>
|
|
41
|
+
<CommandSeparator />
|
|
42
|
+
<CommandGroup heading="Settings">
|
|
43
|
+
<CommandItem value="profile">
|
|
44
|
+
<Icon name="person" class={itemIcon()} />
|
|
45
|
+
Profile
|
|
46
|
+
</CommandItem>
|
|
47
|
+
<CommandItem value="billing">
|
|
48
|
+
<Icon name="credit_card" class={itemIcon()} />
|
|
49
|
+
Billing
|
|
50
|
+
</CommandItem>
|
|
51
|
+
<CommandItem value="settings">
|
|
52
|
+
<Icon name="settings" class={itemIcon()} />
|
|
53
|
+
Settings
|
|
54
|
+
</CommandItem>
|
|
55
|
+
</CommandGroup>
|
|
56
|
+
</CommandList>
|
|
57
|
+
</Command>
|
|
58
|
+
</div>
|
|
59
|
+
</Story>
|
|
60
|
+
|
|
61
|
+
<Story name="Empty State" asChild>
|
|
62
|
+
<div class="w-96">
|
|
63
|
+
<Command>
|
|
64
|
+
<CommandInput placeholder="Search for nothing..." />
|
|
65
|
+
<CommandList>
|
|
66
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
67
|
+
</CommandList>
|
|
68
|
+
</Command>
|
|
69
|
+
</div>
|
|
70
|
+
</Story>
|
|
71
|
+
|
|
72
|
+
<Story name="No Icons" asChild>
|
|
73
|
+
<div class="w-96">
|
|
74
|
+
<Command>
|
|
75
|
+
<CommandInput placeholder="Search..." />
|
|
76
|
+
<CommandList>
|
|
77
|
+
<CommandEmpty>No results found.</CommandEmpty>
|
|
78
|
+
<CommandGroup heading="Recent">
|
|
79
|
+
<CommandItem value="apple">Apple</CommandItem>
|
|
80
|
+
<CommandItem value="banana">Banana</CommandItem>
|
|
81
|
+
<CommandItem value="cherry">Cherry</CommandItem>
|
|
82
|
+
</CommandGroup>
|
|
83
|
+
</CommandList>
|
|
84
|
+
</Command>
|
|
85
|
+
</div>
|
|
86
|
+
</Story>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Command from './Command.svelte';
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const Command: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type Command = InstanceType<typeof Command>;
|
|
19
|
+
export default Command;
|
|
@@ -4,12 +4,12 @@ export const command = tv({
|
|
|
4
4
|
base: 'flex h-full w-full flex-col overflow-hidden rounded-2xl bg-md-sys-color-surface-container-high text-md-sys-color-on-surface shadow-elevation-3 ring-1 ring-md-sys-color-outline/20',
|
|
5
5
|
inputWrapper: 'flex items-center border-b border-md-sys-color-outline-variant px-4',
|
|
6
6
|
inputIcon: 'mr-3 h-5 w-5 shrink-0 text-md-sys-color-on-surface-variant',
|
|
7
|
-
input: 'flex h-12 w-full rounded-md bg-transparent py-3
|
|
7
|
+
input: 'flex h-12 w-full rounded-md bg-transparent py-3 md-sys-typescale-body-large outline-none placeholder:text-md-sys-color-on-surface-variant disabled:cursor-not-allowed disabled:opacity-50',
|
|
8
8
|
list: 'max-h-[300px] overflow-y-auto overflow-x-hidden p-2 scrollbar-thin scrollbar-thumb-md-sys-color-outline-variant scrollbar-track-transparent',
|
|
9
|
-
empty: 'py-6 text-center
|
|
10
|
-
group: 'overflow-hidden p-1 text-md-sys-color-on-surface-variant [&_[data-command-group-heading]]:px-3 [&_[data-command-group-heading]]:py-2 [&_[data-command-group-heading]]:
|
|
9
|
+
empty: 'py-6 text-center md-sys-typescale-body-medium text-md-sys-color-on-surface-variant',
|
|
10
|
+
group: 'overflow-hidden p-1 text-md-sys-color-on-surface-variant [&_[data-command-group-heading]]:px-3 [&_[data-command-group-heading]]:py-2 [&_[data-command-group-heading]]:md-sys-typescale-label-medium [&_[data-command-group-heading]]:text-md-sys-color-on-surface-variant',
|
|
11
11
|
separator: '-mx-1 h-px bg-md-sys-color-outline-variant',
|
|
12
|
-
item: 'relative flex cursor-default select-none items-center rounded-lg px-3 py-3
|
|
12
|
+
item: 'relative flex cursor-default select-none items-center rounded-lg px-3 py-3 md-sys-typescale-body-medium outline-none data-[selected=true]:bg-md-sys-color-secondary-container data-[selected=true]:text-md-sys-color-on-secondary-container data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-50 transition-colors',
|
|
13
13
|
itemIcon: 'mr-3 h-5 w-5 shrink-0'
|
|
14
14
|
}
|
|
15
15
|
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Tooltip only renders its content while open, and opening normally requires a real hover/focus
|
|
3
|
+
interaction on the trigger. Each story below passes `isOpen={true}` so the tooltip renders open
|
|
4
|
+
by default for visual review, without needing to hover in Storybook.
|
|
5
|
+
-->
|
|
6
|
+
<script module lang="ts">
|
|
7
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
8
|
+
import Tooltip from './Tooltip.svelte';
|
|
9
|
+
import Button from '../../buttons/Button.svelte';
|
|
10
|
+
|
|
11
|
+
const { Story } = defineMeta({
|
|
12
|
+
title: 'Forms/Tooltip',
|
|
13
|
+
component: Tooltip
|
|
14
|
+
});
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<Story name="Snack (Default)" asChild>
|
|
18
|
+
<div class="p-24">
|
|
19
|
+
<Tooltip supportingText="Add to library" isOpen={true}>
|
|
20
|
+
{#snippet trigger(props)}
|
|
21
|
+
<Button {...props} variant="filled" iconProps={{ name: 'add' }}>Add</Button>
|
|
22
|
+
{/snippet}
|
|
23
|
+
</Tooltip>
|
|
24
|
+
</div>
|
|
25
|
+
</Story>
|
|
26
|
+
|
|
27
|
+
<Story name="Rich" asChild>
|
|
28
|
+
<div class="p-24">
|
|
29
|
+
<Tooltip
|
|
30
|
+
variant="rich"
|
|
31
|
+
style="container"
|
|
32
|
+
subhead="Accessibility settings"
|
|
33
|
+
supportingText="Adjust text size, contrast, and motion preferences."
|
|
34
|
+
isOpen={true}
|
|
35
|
+
>
|
|
36
|
+
{#snippet trigger(props)}
|
|
37
|
+
<Button {...props} variant="outlined">Settings</Button>
|
|
38
|
+
{/snippet}
|
|
39
|
+
</Tooltip>
|
|
40
|
+
</div>
|
|
41
|
+
</Story>
|
|
42
|
+
|
|
43
|
+
<Story name="Rich — All Styles" asChild>
|
|
44
|
+
<div class="flex flex-wrap gap-24 p-24">
|
|
45
|
+
<Tooltip
|
|
46
|
+
variant="rich"
|
|
47
|
+
style="container"
|
|
48
|
+
subhead="Container"
|
|
49
|
+
supportingText="bg-surface-container"
|
|
50
|
+
isOpen={true}
|
|
51
|
+
>
|
|
52
|
+
{#snippet trigger(props)}
|
|
53
|
+
<Button {...props} variant="outlined">Container</Button>
|
|
54
|
+
{/snippet}
|
|
55
|
+
</Tooltip>
|
|
56
|
+
<Tooltip
|
|
57
|
+
variant="rich"
|
|
58
|
+
style="primary"
|
|
59
|
+
subhead="Primary"
|
|
60
|
+
supportingText="bg-primary-container"
|
|
61
|
+
isOpen={true}
|
|
62
|
+
>
|
|
63
|
+
{#snippet trigger(props)}
|
|
64
|
+
<Button {...props} variant="outlined">Primary</Button>
|
|
65
|
+
{/snippet}
|
|
66
|
+
</Tooltip>
|
|
67
|
+
<Tooltip
|
|
68
|
+
variant="rich"
|
|
69
|
+
style="secondary"
|
|
70
|
+
subhead="Secondary"
|
|
71
|
+
supportingText="bg-secondary-container"
|
|
72
|
+
isOpen={true}
|
|
73
|
+
>
|
|
74
|
+
{#snippet trigger(props)}
|
|
75
|
+
<Button {...props} variant="outlined">Secondary</Button>
|
|
76
|
+
{/snippet}
|
|
77
|
+
</Tooltip>
|
|
78
|
+
<Tooltip
|
|
79
|
+
variant="rich"
|
|
80
|
+
style="tertiary"
|
|
81
|
+
subhead="Tertiary"
|
|
82
|
+
supportingText="bg-tertiary-container"
|
|
83
|
+
isOpen={true}
|
|
84
|
+
>
|
|
85
|
+
{#snippet trigger(props)}
|
|
86
|
+
<Button {...props} variant="outlined">Tertiary</Button>
|
|
87
|
+
{/snippet}
|
|
88
|
+
</Tooltip>
|
|
89
|
+
</div>
|
|
90
|
+
</Story>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Tooltip from './Tooltip.svelte';
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const Tooltip: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type Tooltip = InstanceType<typeof Tooltip>;
|
|
19
|
+
export default Tooltip;
|
|
@@ -36,10 +36,11 @@ Plain tooltips are used for simple labels, while rich tooltips can contain forma
|
|
|
36
36
|
subhead: subheadCls,
|
|
37
37
|
base,
|
|
38
38
|
trigger: triggerCls,
|
|
39
|
-
supportingText: supportingTextCls
|
|
39
|
+
supportingText: supportingTextCls,
|
|
40
|
+
textContainer: textContainerCls
|
|
40
41
|
} = $derived(tooltip({ variant, style }));
|
|
41
42
|
|
|
42
|
-
const baseCls = $derived(base({ class: clsx(className) }));
|
|
43
|
+
const baseCls = $derived(base({ class: clsx(className, textContainerCls()) }));
|
|
43
44
|
|
|
44
45
|
/**
|
|
45
46
|
* ButtonIcons always have tooltips on, but not always with text
|
|
@@ -86,7 +87,7 @@ Plain tooltips are used for simple labels, while rich tooltips can contain forma
|
|
|
86
87
|
{#if variant === 'rich'}
|
|
87
88
|
<Layer />
|
|
88
89
|
{#if subhead}
|
|
89
|
-
<Title class={subheadCls()}>
|
|
90
|
+
<Title size="small" class={subheadCls()}>
|
|
90
91
|
{subhead}
|
|
91
92
|
</Title>
|
|
92
93
|
{/if}
|
|
@@ -33,6 +33,7 @@ export declare const tooltip: import("tailwind-variants").TVReturnType<{
|
|
|
33
33
|
base: string;
|
|
34
34
|
subhead: string;
|
|
35
35
|
supportingText: string;
|
|
36
|
+
textContainer: string;
|
|
36
37
|
trigger: string;
|
|
37
38
|
}, undefined, {
|
|
38
39
|
variant: {
|
|
@@ -67,6 +68,7 @@ export declare const tooltip: import("tailwind-variants").TVReturnType<{
|
|
|
67
68
|
base: string;
|
|
68
69
|
subhead: string;
|
|
69
70
|
supportingText: string;
|
|
71
|
+
textContainer: string;
|
|
70
72
|
trigger: string;
|
|
71
73
|
}, import("tailwind-variants").TVReturnType<{
|
|
72
74
|
variant: {
|
|
@@ -101,5 +103,6 @@ export declare const tooltip: import("tailwind-variants").TVReturnType<{
|
|
|
101
103
|
base: string;
|
|
102
104
|
subhead: string;
|
|
103
105
|
supportingText: string;
|
|
106
|
+
textContainer: string;
|
|
104
107
|
trigger: string;
|
|
105
108
|
}, undefined, unknown, unknown, undefined>>;
|
|
@@ -4,6 +4,7 @@ export const tooltip = tv({
|
|
|
4
4
|
base: 'min-w-60 py-3 px-4 shadow-elevation-2 rounded-md relative z-[100] pointer-events-auto',
|
|
5
5
|
subhead: '',
|
|
6
6
|
supportingText: '',
|
|
7
|
+
textContainer: '',
|
|
7
8
|
trigger: 'relative inline-flex'
|
|
8
9
|
},
|
|
9
10
|
variants: {
|
|
@@ -12,7 +13,7 @@ export const tooltip = tv({
|
|
|
12
13
|
base: 'flex flex-col gap-3'
|
|
13
14
|
},
|
|
14
15
|
snack: {
|
|
15
|
-
base: '
|
|
16
|
+
base: 'inline-flex min-w-0 max-w-50 bg-md-sys-color-inverse-surface text-md-sys-color-inverse-on-surface md-sys-typescale-body-small px-3 py-2 shadow-elevation-3 before:rounded-md',
|
|
16
17
|
supportingText: 'text-md-sys-color-inverse-on-surface md-sys-typescale-body-small',
|
|
17
18
|
textContainer: ''
|
|
18
19
|
}
|
|
@@ -20,19 +21,19 @@ export const tooltip = tv({
|
|
|
20
21
|
style: {
|
|
21
22
|
container: {
|
|
22
23
|
base: 'bg-md-sys-color-surface-container',
|
|
23
|
-
textContainer: 'text-md-sys-on-surface-variant'
|
|
24
|
+
textContainer: 'text-md-sys-color-on-surface-variant'
|
|
24
25
|
},
|
|
25
26
|
primary: {
|
|
26
27
|
base: 'bg-md-sys-color-primary-container',
|
|
27
|
-
textContainer: 'text-md-sys-on-primary-container'
|
|
28
|
+
textContainer: 'text-md-sys-color-on-primary-container'
|
|
28
29
|
},
|
|
29
30
|
secondary: {
|
|
30
31
|
base: 'bg-md-sys-color-secondary-container',
|
|
31
|
-
textContainer: 'text-md-sys-on-secondary-container'
|
|
32
|
+
textContainer: 'text-md-sys-color-on-secondary-container'
|
|
32
33
|
},
|
|
33
34
|
tertiary: {
|
|
34
35
|
base: 'bg-md-sys-color-tertiary-container',
|
|
35
|
-
textContainer: 'text-md-sys-on-tertiary-container'
|
|
36
|
+
textContainer: 'text-md-sys-color-on-tertiary-container'
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
39
|
},
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script module lang="ts">
|
|
2
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
3
|
+
import Avatar from './Avatar.svelte';
|
|
4
|
+
|
|
5
|
+
const { Story } = defineMeta({
|
|
6
|
+
title: 'Misc/Avatar',
|
|
7
|
+
component: Avatar,
|
|
8
|
+
argTypes: {
|
|
9
|
+
size: { control: 'select', options: ['sm', 'md', 'lg'] },
|
|
10
|
+
seed: { control: 'text' },
|
|
11
|
+
dicebearStyle: { control: 'text' }
|
|
12
|
+
},
|
|
13
|
+
args: {
|
|
14
|
+
size: 'lg',
|
|
15
|
+
seed: 'ogonek'
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<Story name="Playground">
|
|
21
|
+
{#snippet template(args)}
|
|
22
|
+
<Avatar size={args.size} seed={args.seed} dicebearStyle={args.dicebearStyle} />
|
|
23
|
+
{/snippet}
|
|
24
|
+
</Story>
|
|
25
|
+
|
|
26
|
+
<Story name="Sizes" asChild>
|
|
27
|
+
<div class="flex items-end gap-4">
|
|
28
|
+
<Avatar size="sm" seed="small" />
|
|
29
|
+
<Avatar size="md" seed="medium" />
|
|
30
|
+
<Avatar size="lg" seed="large" />
|
|
31
|
+
</div>
|
|
32
|
+
</Story>
|
|
33
|
+
|
|
34
|
+
<Story name="Generated Fallback" asChild>
|
|
35
|
+
<div class="flex items-end gap-4">
|
|
36
|
+
<Avatar seed="alice" />
|
|
37
|
+
<Avatar seed="bob" />
|
|
38
|
+
<Avatar seed="carol" />
|
|
39
|
+
</div>
|
|
40
|
+
</Story>
|
|
41
|
+
|
|
42
|
+
<Story name="With Image" asChild>
|
|
43
|
+
<div class="flex items-end gap-4">
|
|
44
|
+
<Avatar src="https://picsum.photos/seed/ogonek-1/200" alt="Sample user" />
|
|
45
|
+
<Avatar
|
|
46
|
+
src="https://this-url-does-not-resolve.example/broken.jpg"
|
|
47
|
+
alt="Broken image"
|
|
48
|
+
seed="fallback"
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
51
|
+
</Story>
|
|
52
|
+
|
|
53
|
+
<Story name="Clickable" asChild>
|
|
54
|
+
<Avatar seed="clickable" onclick={() => console.log('Avatar clicked')} />
|
|
55
|
+
</Story>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Avatar from './Avatar.svelte';
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const Avatar: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type Avatar = InstanceType<typeof Avatar>;
|
|
19
|
+
export default Avatar;
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
type="file"
|
|
56
56
|
accept="image/*"
|
|
57
57
|
onchange={handleImageUpload}
|
|
58
|
-
class="file:bg-md-sys-color-primary-container file:text-md-sys-color-on-primary-container hover:file:bg-md-sys-color-primary-container/80
|
|
58
|
+
class="file:bg-md-sys-color-primary-container file:text-md-sys-color-on-primary-container hover:file:bg-md-sys-color-primary-container/80 md-sys-typescale-body-medium file:mr-4 file:rounded-full file:border-0 file:px-4 file:py-2 file:md-sys-typescale-label-large"
|
|
59
59
|
/>
|
|
60
60
|
</div>
|
|
61
61
|
</div>
|
|
@@ -3,8 +3,8 @@ export const avatar = tv({
|
|
|
3
3
|
slots: {
|
|
4
4
|
root: 'relative flex aspect-square shrink-0 items-center justify-center overflow-hidden rounded-full',
|
|
5
5
|
image: 'h-full w-full object-cover',
|
|
6
|
-
fallback: 'flex h-full w-full items-center justify-center rounded-full bg-surface-container-highest',
|
|
7
|
-
button: 'relative rounded-full focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary'
|
|
6
|
+
fallback: 'flex h-full w-full items-center justify-center rounded-full bg-md-sys-color-surface-container-highest',
|
|
7
|
+
button: 'relative rounded-full focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-md-sys-color-primary'
|
|
8
8
|
},
|
|
9
9
|
variants: {
|
|
10
10
|
size: {
|
|
@@ -30,7 +30,7 @@ Use TabContent for content-panel tabs; omit it for navigation (href) tabs.
|
|
|
30
30
|
|
|
31
31
|
<Tabs.Root bind:value {onValueChange} {activationMode}>
|
|
32
32
|
<Tabs.List class={base()}>
|
|
33
|
-
{#each items as item}
|
|
33
|
+
{#each items as item (item)}
|
|
34
34
|
<Tab {...item} {variant} />
|
|
35
35
|
{/each}
|
|
36
36
|
|
|
@@ -33,10 +33,11 @@
|
|
|
33
33
|
<Story name="Playground">
|
|
34
34
|
{#snippet template(args)}
|
|
35
35
|
<div class="flex flex-col gap-4">
|
|
36
|
-
<TabHolder {...args} {items}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
<TabHolder {...args} {items}>
|
|
37
|
+
<TabContent value="flights"><Body>Flights panel content.</Body></TabContent>
|
|
38
|
+
<TabContent value="trips"><Body>Trips panel content.</Body></TabContent>
|
|
39
|
+
<TabContent value="explore"><Body>Explore panel content.</Body></TabContent>
|
|
40
|
+
</TabHolder>
|
|
40
41
|
</div>
|
|
41
42
|
{/snippet}
|
|
42
43
|
</Story>
|
|
@@ -24,6 +24,7 @@ It follows the Material 3 design for time input pickers.
|
|
|
24
24
|
|
|
25
25
|
const cls = timepicker();
|
|
26
26
|
|
|
27
|
+
// svelte-ignore state_referenced_locally (timeValue is a one-time editable seed from `time`, then mutated locally via bind:value)
|
|
27
28
|
let timeValue = $state<Time>(parseTime(time?.includes(':') ? time : '00:00'));
|
|
28
29
|
|
|
29
30
|
const output = $derived(
|
|
@@ -7,7 +7,7 @@ export const timepicker = tv({
|
|
|
7
7
|
headline: 'text-md-sys-color-on-surface-variant md-sys-typescale-label-medium',
|
|
8
8
|
inputWrapper: 'space-y-2',
|
|
9
9
|
fieldSeparator: 'text-md-sys-color-on-surface md-sys-typescale-display-large ',
|
|
10
|
-
timeInput: 'bg-md-sys-color-surface-container-highest rounded-sm outline outline-md-sys-color-outline w-24 h-18 md-sys-typescale-display-medium text-md-sys-color-on-surface hover:text-sys-color-on-surface state-layer before:bg-md-sys-color-on-surface/8 md-sys-state-focus-indicator inline-flex items-center justify-center cursor-text focus:text-md-sys-color-on-primary-container focus:outline-md-sys-color-primary focus:bg-md-sys-color-primary-container relative',
|
|
11
|
-
timeInputSupportingText: 'text-md-color-on-surface-variant md-sys-typescale-body-small'
|
|
10
|
+
timeInput: 'bg-md-sys-color-surface-container-highest rounded-sm outline outline-md-sys-color-outline w-24 h-18 md-sys-typescale-display-medium text-md-sys-color-on-surface hover:text-md-sys-color-on-surface state-layer before:bg-md-sys-color-on-surface/8 md-sys-state-focus-indicator inline-flex items-center justify-center cursor-text focus:text-md-sys-color-on-primary-container focus:outline-md-sys-color-primary focus:bg-md-sys-color-primary-container relative',
|
|
11
|
+
timeInputSupportingText: 'text-md-sys-color-on-surface-variant md-sys-typescale-body-small'
|
|
12
12
|
}
|
|
13
13
|
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
`position="absolute"` anchors Kbd to the bottom-right corner of a `relative` ancestor (and is
|
|
3
|
+
hidden below the `md` breakpoint) — typically used to show a keyboard shortcut hint inside a
|
|
4
|
+
search/command input. `position="relative"` renders it inline instead.
|
|
5
|
+
-->
|
|
6
|
+
<script module lang="ts">
|
|
7
|
+
import { defineMeta } from '@storybook/addon-svelte-csf';
|
|
8
|
+
import Kbd from './Kbd.svelte';
|
|
9
|
+
|
|
10
|
+
const { Story } = defineMeta({
|
|
11
|
+
title: 'Typography/Kbd',
|
|
12
|
+
component: Kbd,
|
|
13
|
+
argTypes: {
|
|
14
|
+
position: { control: 'select', options: ['relative', 'absolute'] }
|
|
15
|
+
},
|
|
16
|
+
args: {
|
|
17
|
+
position: 'relative'
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<Story name="Playground">
|
|
23
|
+
{#snippet template(args)}
|
|
24
|
+
<Kbd position={args.position}>⌘K</Kbd>
|
|
25
|
+
{/snippet}
|
|
26
|
+
</Story>
|
|
27
|
+
|
|
28
|
+
<Story name="Inline Shortcut" asChild>
|
|
29
|
+
<p class="md-sys-typescale-body-medium text-md-sys-color-on-surface">
|
|
30
|
+
Press <Kbd position="relative">⌘K</Kbd> to open the command palette.
|
|
31
|
+
</p>
|
|
32
|
+
</Story>
|
|
33
|
+
|
|
34
|
+
<Story name="Anchored in a Search Field" asChild>
|
|
35
|
+
<div
|
|
36
|
+
class="relative flex h-12 w-80 items-center rounded-full bg-md-sys-color-surface-container-high px-4 md-sys-typescale-body-large text-md-sys-color-on-surface-variant"
|
|
37
|
+
>
|
|
38
|
+
Search...
|
|
39
|
+
<Kbd position="absolute">⌘K</Kbd>
|
|
40
|
+
</div>
|
|
41
|
+
</Story>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Kbd from './Kbd.svelte';
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const Kbd: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
16
|
+
[evt: string]: CustomEvent<any>;
|
|
17
|
+
}, {}, {}, string>;
|
|
18
|
+
type Kbd = InstanceType<typeof Kbd>;
|
|
19
|
+
export default Kbd;
|
|
@@ -5,7 +5,7 @@ export declare const kbd: import("tailwind-variants").TVReturnType<{
|
|
|
5
5
|
absolute: string;
|
|
6
6
|
relative: string;
|
|
7
7
|
};
|
|
8
|
-
}, undefined, "
|
|
8
|
+
}, undefined, "md-sys-typescale-label-small font-semibold text-md-sys-color-on-surface-variant", {
|
|
9
9
|
position: {
|
|
10
10
|
absolute: string;
|
|
11
11
|
relative: string;
|
|
@@ -15,4 +15,4 @@ export declare const kbd: import("tailwind-variants").TVReturnType<{
|
|
|
15
15
|
absolute: string;
|
|
16
16
|
relative: string;
|
|
17
17
|
};
|
|
18
|
-
}, undefined, "
|
|
18
|
+
}, undefined, "md-sys-typescale-label-small font-semibold text-md-sys-color-on-surface-variant", unknown, unknown, undefined>>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { tv } from 'tailwind-variants';
|
|
2
2
|
export const kbd = tv({
|
|
3
|
-
base: '
|
|
3
|
+
base: 'md-sys-typescale-label-small font-semibold text-md-sys-color-on-surface-variant',
|
|
4
4
|
variants: {
|
|
5
5
|
position: {
|
|
6
|
-
absolute: 'right-1.5 bottom-1.5 hidden md:absolute md:right-2 md:bottom-2',
|
|
6
|
+
absolute: 'right-1.5 bottom-1.5 hidden md:absolute md:right-2 md:bottom-2 md:inline-flex',
|
|
7
7
|
relative: ''
|
|
8
8
|
}
|
|
9
9
|
}
|