@noxlovette/material 0.9.3 → 0.10.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/dist/components/buttons/connected/theme.d.ts +15 -15
- package/dist/components/buttons/connected/theme.js +20 -5
- package/dist/components/buttons/split-button/theme.d.ts +15 -15
- package/dist/components/buttons/split-button/theme.js +21 -15
- package/dist/components/buttons/theme.d.ts +40 -40
- package/dist/components/buttons/theme.js +29 -29
- package/dist/components/cards/theme.js +1 -1
- package/dist/components/chips/Chip.svelte +1 -1
- package/dist/components/chips/theme.js +1 -1
- package/dist/components/containers/bottom-sheet/theme.js +1 -1
- package/dist/components/containers/carousel/theme.js +1 -1
- package/dist/components/containers/context-menu/theme.js +2 -2
- package/dist/components/containers/dialogue/theme.js +1 -1
- package/dist/components/containers/list/theme.d.ts +3 -3
- package/dist/components/containers/list/theme.js +8 -8
- package/dist/components/containers/menu/theme.js +3 -3
- package/dist/components/date/theme.js +2 -2
- package/dist/components/forms/checkbox/theme.js +1 -1
- package/dist/components/forms/command/theme.js +1 -1
- package/dist/components/forms/index.d.ts +1 -0
- package/dist/components/forms/index.js +1 -0
- package/dist/components/forms/search/theme.js +1 -1
- package/dist/components/forms/select/theme.js +2 -2
- package/dist/components/forms/slider/Slider.svelte +8 -0
- package/dist/components/forms/slider/theme.js +7 -7
- package/dist/components/forms/slider/types.d.ts +13 -0
- package/dist/components/forms/textarea/Textarea.mdx +63 -0
- package/dist/components/forms/textarea/Textarea.stories.svelte +99 -0
- package/dist/components/forms/textarea/Textarea.stories.svelte.d.ts +19 -0
- package/dist/components/forms/textarea/Textarea.svelte +142 -0
- package/dist/components/forms/textarea/Textarea.svelte.d.ts +13 -0
- package/dist/components/forms/textarea/index.d.ts +3 -0
- package/dist/components/forms/textarea/index.js +6 -0
- package/dist/components/forms/textarea/theme.d.ts +150 -0
- package/dist/components/forms/textarea/theme.js +155 -0
- package/dist/components/forms/textarea/types.d.ts +59 -0
- package/dist/components/forms/textarea/types.js +1 -0
- package/dist/components/forms/textfield/theme.js +4 -4
- package/dist/components/forms/toggle-group/theme.js +2 -2
- package/dist/components/misc/ThemeSettings.svelte +1 -1
- package/dist/components/misc/materialAvatarPalette.js +1 -1
- package/dist/components/nav/appbar/theme.js +22 -6
- package/dist/components/nav/navbar/theme.js +1 -1
- package/dist/components/nav/tabs/theme.js +1 -1
- package/dist/components/progress/CircularProgress.svelte +5 -3
- package/dist/components/progress/CircularProgress.svelte.d.ts +2 -1
- package/dist/components/progress/LinearProgress.svelte +5 -2
- package/dist/components/progress/LinearProgress.svelte.d.ts +2 -1
- package/dist/components/progress/WavyLinearProgress.svelte +5 -3
- package/dist/components/progress/WavyLinearProgress.svelte.d.ts +2 -1
- package/dist/components/progress/index.d.ts +1 -0
- package/dist/components/progress/index.js +1 -0
- package/dist/components/progress/types.d.ts +16 -0
- package/dist/components/progress/types.js +1 -0
- package/dist/components/snackbar/theme.js +1 -1
- package/dist/components/table/TableHeader.svelte +1 -1
- package/dist/components/toolbar/theme.js +2 -2
- package/dist/styles/components.css +7 -2
- package/dist/styles/icon.css +19 -0
- package/dist/styles/rounding.css +4 -0
- package/dist/utils/Theme.svelte +1 -1
- package/dist/utils/ThemeScript.svelte +1 -1
- package/dist/utils/icon/Icon.svelte +5 -5
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js +1 -1
- package/package.json +1 -1
- /package/dist/utils/{theme.svelte.d.ts → themeState.svelte.d.ts} +0 -0
- /package/dist/utils/{theme.svelte.js → themeState.svelte.js} +0 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { type VariantProps } from '../../../utils/tv.js';
|
|
2
|
+
export type TextareaVariants = VariantProps<typeof textarea>;
|
|
3
|
+
/**
|
|
4
|
+
* M3 defines a multi-line text field but no separate textarea spec. This keeps the text field's
|
|
5
|
+
* containers, label, notch and indicator, and changes only what a growing field has to:
|
|
6
|
+
* the container has a 56dp minimum instead of a fixed height, and the label and icons line up
|
|
7
|
+
* with the first line instead of the vertical center.
|
|
8
|
+
*/
|
|
9
|
+
export declare const textarea: import("tailwind-variants").TVReturnType<{
|
|
10
|
+
variant: {
|
|
11
|
+
filled: {
|
|
12
|
+
base: string;
|
|
13
|
+
inputWrapper: string;
|
|
14
|
+
leadingIcon: string;
|
|
15
|
+
trailingIcon: string;
|
|
16
|
+
label: string;
|
|
17
|
+
};
|
|
18
|
+
outlined: {
|
|
19
|
+
inputWrapper: string;
|
|
20
|
+
label: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
error: {
|
|
24
|
+
true: {
|
|
25
|
+
base: string;
|
|
26
|
+
label: string;
|
|
27
|
+
supportingText: string;
|
|
28
|
+
leadingIcon: string;
|
|
29
|
+
trailingIcon: string;
|
|
30
|
+
fieldset: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
leadingIcon: {
|
|
34
|
+
true: {};
|
|
35
|
+
};
|
|
36
|
+
disabled: {
|
|
37
|
+
true: {
|
|
38
|
+
base: string;
|
|
39
|
+
inputWrapper: string;
|
|
40
|
+
fieldset: string;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
}, {
|
|
44
|
+
base: string;
|
|
45
|
+
inputWrapper: string;
|
|
46
|
+
input: string;
|
|
47
|
+
label: string;
|
|
48
|
+
requiredAsterisk: string;
|
|
49
|
+
leadingIcon: string;
|
|
50
|
+
trailingIcon: string;
|
|
51
|
+
supportingText: string;
|
|
52
|
+
counter: string;
|
|
53
|
+
fieldset: string;
|
|
54
|
+
legend: string;
|
|
55
|
+
legendLabel: string;
|
|
56
|
+
}, undefined, {
|
|
57
|
+
variant: {
|
|
58
|
+
filled: {
|
|
59
|
+
base: string;
|
|
60
|
+
inputWrapper: string;
|
|
61
|
+
leadingIcon: string;
|
|
62
|
+
trailingIcon: string;
|
|
63
|
+
label: string;
|
|
64
|
+
};
|
|
65
|
+
outlined: {
|
|
66
|
+
inputWrapper: string;
|
|
67
|
+
label: string;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
error: {
|
|
71
|
+
true: {
|
|
72
|
+
base: string;
|
|
73
|
+
label: string;
|
|
74
|
+
supportingText: string;
|
|
75
|
+
leadingIcon: string;
|
|
76
|
+
trailingIcon: string;
|
|
77
|
+
fieldset: string;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
leadingIcon: {
|
|
81
|
+
true: {};
|
|
82
|
+
};
|
|
83
|
+
disabled: {
|
|
84
|
+
true: {
|
|
85
|
+
base: string;
|
|
86
|
+
inputWrapper: string;
|
|
87
|
+
fieldset: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
}, {
|
|
91
|
+
base: string;
|
|
92
|
+
inputWrapper: string;
|
|
93
|
+
input: string;
|
|
94
|
+
label: string;
|
|
95
|
+
requiredAsterisk: string;
|
|
96
|
+
leadingIcon: string;
|
|
97
|
+
trailingIcon: string;
|
|
98
|
+
supportingText: string;
|
|
99
|
+
counter: string;
|
|
100
|
+
fieldset: string;
|
|
101
|
+
legend: string;
|
|
102
|
+
legendLabel: string;
|
|
103
|
+
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
104
|
+
variant: {
|
|
105
|
+
filled: {
|
|
106
|
+
base: string;
|
|
107
|
+
inputWrapper: string;
|
|
108
|
+
leadingIcon: string;
|
|
109
|
+
trailingIcon: string;
|
|
110
|
+
label: string;
|
|
111
|
+
};
|
|
112
|
+
outlined: {
|
|
113
|
+
inputWrapper: string;
|
|
114
|
+
label: string;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
error: {
|
|
118
|
+
true: {
|
|
119
|
+
base: string;
|
|
120
|
+
label: string;
|
|
121
|
+
supportingText: string;
|
|
122
|
+
leadingIcon: string;
|
|
123
|
+
trailingIcon: string;
|
|
124
|
+
fieldset: string;
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
leadingIcon: {
|
|
128
|
+
true: {};
|
|
129
|
+
};
|
|
130
|
+
disabled: {
|
|
131
|
+
true: {
|
|
132
|
+
base: string;
|
|
133
|
+
inputWrapper: string;
|
|
134
|
+
fieldset: string;
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
}, {
|
|
138
|
+
base: string;
|
|
139
|
+
inputWrapper: string;
|
|
140
|
+
input: string;
|
|
141
|
+
label: string;
|
|
142
|
+
requiredAsterisk: string;
|
|
143
|
+
leadingIcon: string;
|
|
144
|
+
trailingIcon: string;
|
|
145
|
+
supportingText: string;
|
|
146
|
+
counter: string;
|
|
147
|
+
fieldset: string;
|
|
148
|
+
legend: string;
|
|
149
|
+
legendLabel: string;
|
|
150
|
+
}>>;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { tv } from '../../../utils/tv.js';
|
|
2
|
+
/**
|
|
3
|
+
* M3 defines a multi-line text field but no separate textarea spec. This keeps the text field's
|
|
4
|
+
* containers, label, notch and indicator, and changes only what a growing field has to:
|
|
5
|
+
* the container has a 56dp minimum instead of a fixed height, and the label and icons line up
|
|
6
|
+
* with the first line instead of the vertical center.
|
|
7
|
+
*/
|
|
8
|
+
export const textarea = tv({
|
|
9
|
+
slots: {
|
|
10
|
+
base: `
|
|
11
|
+
group relative w-full min-h-spacing-700 flex items-start
|
|
12
|
+
`,
|
|
13
|
+
/* The wrapper holds the vertical padding, not the textarea, so text scrolled past `maxRows`
|
|
14
|
+
is clipped at the textarea's edge instead of sliding under the floated label. */
|
|
15
|
+
inputWrapper: `
|
|
16
|
+
relative flex-1 self-stretch px-spacing-200 cursor-text
|
|
17
|
+
`,
|
|
18
|
+
input: `
|
|
19
|
+
peer block w-full bg-transparent outline-none resize-none field-sizing-content
|
|
20
|
+
md-sys-typescale-body-large text-md-sys-color-on-surface
|
|
21
|
+
disabled:text-md-sys-color-on-surface/38 disabled:cursor-not-allowed
|
|
22
|
+
`,
|
|
23
|
+
label: `
|
|
24
|
+
absolute left-spacing-200 top-spacing-200
|
|
25
|
+
md-sys-typescale-body-large
|
|
26
|
+
text-md-sys-color-on-surface-variant
|
|
27
|
+
pointer-events-none
|
|
28
|
+
transition-[top,left,font-size,line-height,color,transform] md-sys-motion-fast-spatial
|
|
29
|
+
|
|
30
|
+
peer-focus:text-md-sys-color-primary
|
|
31
|
+
`,
|
|
32
|
+
requiredAsterisk: `
|
|
33
|
+
ml-spacing-25
|
|
34
|
+
text-md-sys-color-error
|
|
35
|
+
group-focus-within:text-md-sys-color-primary
|
|
36
|
+
transition-colors md-sys-motion-effects
|
|
37
|
+
`,
|
|
38
|
+
/* On the first line of text: 16dp from the top when outlined, 24dp when filled. */
|
|
39
|
+
leadingIcon: `
|
|
40
|
+
text-md-sys-color-on-surface-variant size-(--text-icon-24)
|
|
41
|
+
group-focus-within:text-md-sys-color-primary
|
|
42
|
+
ml-spacing-150 mt-spacing-200 text-icon-24
|
|
43
|
+
`,
|
|
44
|
+
/* Sized to the 24dp glyph like Textfield's, so it takes the same offset as the leading icon. */
|
|
45
|
+
trailingIcon: `
|
|
46
|
+
mr-spacing-150 mt-spacing-200 text-md-sys-color-on-surface-variant size-(--text-icon-24)
|
|
47
|
+
group-focus-within:text-md-sys-color-primary
|
|
48
|
+
z-20 text-icon-24
|
|
49
|
+
`,
|
|
50
|
+
supportingText: `
|
|
51
|
+
px-spacing-200 pt-spacing-50 flex justify-between gap-spacing-200
|
|
52
|
+
md-sys-typescale-body-small
|
|
53
|
+
text-md-sys-color-on-surface-variant
|
|
54
|
+
`,
|
|
55
|
+
counter: `
|
|
56
|
+
ms-auto shrink-0
|
|
57
|
+
`,
|
|
58
|
+
fieldset: `
|
|
59
|
+
absolute -top-spacing-100 left-spacing-0 right-spacing-0 bottom-spacing-0 m-spacing-0 px-spacing-150
|
|
60
|
+
pointer-events-none rounded-xs border border-md-sys-color-outline
|
|
61
|
+
transition-colors md-sys-motion-fast-effects
|
|
62
|
+
|
|
63
|
+
group-hover:border-md-sys-color-on-surface
|
|
64
|
+
group-focus-within:border-2 group-focus-within:border-md-sys-color-primary
|
|
65
|
+
`,
|
|
66
|
+
legend: `
|
|
67
|
+
invisible float-none block h-auto max-w-[0.01px] overflow-hidden
|
|
68
|
+
whitespace-nowrap md-sys-typescale-body-small
|
|
69
|
+
transition-[max-width] md-sys-motion-fast-spatial
|
|
70
|
+
|
|
71
|
+
group-focus-within:max-w-full
|
|
72
|
+
group-has-[textarea:not(:placeholder-shown)]:max-w-full
|
|
73
|
+
`,
|
|
74
|
+
legendLabel: `
|
|
75
|
+
px-spacing-50
|
|
76
|
+
`
|
|
77
|
+
},
|
|
78
|
+
variants: {
|
|
79
|
+
variant: {
|
|
80
|
+
filled: {
|
|
81
|
+
base: `
|
|
82
|
+
px-spacing-0 bg-md-sys-color-surface-container-highest
|
|
83
|
+
rounded-t-xs state-layer before:rounded-xs hover:before:bg-md-sys-color-on-surface/8
|
|
84
|
+
after:absolute after:bottom-spacing-0 after:left-spacing-0 after:right-spacing-0 after:h-px after:bg-md-sys-color-on-surface-variant
|
|
85
|
+
after:transition-[height,background-color] after:md-sys-motion-fast-spatial
|
|
86
|
+
hover:after:bg-md-sys-color-on-surface
|
|
87
|
+
focus-within:after:bg-md-sys-color-primary
|
|
88
|
+
focus-within:after:h-[2px]
|
|
89
|
+
`,
|
|
90
|
+
/* 24dp above the first line leaves room for the label floated inside the container;
|
|
91
|
+
24 + 24 + 8 = the 56dp single-line field. The resting label and the icons sit on that
|
|
92
|
+
first line too, so the icons stay beside the text once the label floats to 8dp. */
|
|
93
|
+
inputWrapper: 'pt-spacing-300 pb-spacing-100',
|
|
94
|
+
leadingIcon: 'mt-spacing-300',
|
|
95
|
+
trailingIcon: 'mt-spacing-300',
|
|
96
|
+
label: `
|
|
97
|
+
top-spacing-300
|
|
98
|
+
peer-focus:top-spacing-100 peer-focus:md-sys-typescale-body-small
|
|
99
|
+
peer-not-placeholder-shown:top-spacing-100 peer-not-placeholder-shown:md-sys-typescale-body-small
|
|
100
|
+
`
|
|
101
|
+
},
|
|
102
|
+
outlined: {
|
|
103
|
+
inputWrapper: 'py-spacing-200',
|
|
104
|
+
label: `
|
|
105
|
+
peer-focus:top-spacing-0 peer-focus:md-sys-typescale-body-small peer-focus:-translate-y-1/2
|
|
106
|
+
peer-not-placeholder-shown:top-spacing-0 peer-not-placeholder-shown:md-sys-typescale-body-small peer-not-placeholder-shown:-translate-y-1/2
|
|
107
|
+
`
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
error: {
|
|
111
|
+
true: {
|
|
112
|
+
base: 'after:bg-md-sys-color-error focus-within:after:bg-md-sys-color-error',
|
|
113
|
+
label: 'text-md-sys-color-error peer-focus:text-md-sys-color-error',
|
|
114
|
+
supportingText: 'text-md-sys-color-error',
|
|
115
|
+
leadingIcon: 'text-md-sys-color-error',
|
|
116
|
+
trailingIcon: 'text-md-sys-color-error',
|
|
117
|
+
fieldset: `
|
|
118
|
+
border-md-sys-color-error
|
|
119
|
+
group-hover:border-md-sys-color-error
|
|
120
|
+
group-focus-within:border-md-sys-color-error
|
|
121
|
+
`
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
leadingIcon: {
|
|
125
|
+
true: {}
|
|
126
|
+
},
|
|
127
|
+
disabled: {
|
|
128
|
+
true: {
|
|
129
|
+
base: 'cursor-not-allowed opacity-60',
|
|
130
|
+
inputWrapper: 'cursor-not-allowed',
|
|
131
|
+
fieldset: 'border-md-sys-color-on-surface/12 group-hover:border-md-sys-color-on-surface/12'
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
compoundVariants: [
|
|
136
|
+
{
|
|
137
|
+
/* Same as Textfield: the outlined label floats back over the leading icon into the notch. */
|
|
138
|
+
variant: 'outlined',
|
|
139
|
+
leadingIcon: true,
|
|
140
|
+
class: {
|
|
141
|
+
label: 'peer-focus:-left-spacing-250 peer-not-placeholder-shown:-left-spacing-250'
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
variant: 'filled',
|
|
146
|
+
disabled: true,
|
|
147
|
+
class: {
|
|
148
|
+
base: 'bg-md-sys-color-on-surface/4 after:bg-md-sys-color-on-surface/12'
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
],
|
|
152
|
+
defaultVariants: {
|
|
153
|
+
variant: 'outlined'
|
|
154
|
+
}
|
|
155
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { IconProps } from '../../../utils/index.js';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLTextareaAttributes } from 'svelte/elements';
|
|
4
|
+
import type { TextareaVariants } from './theme.js';
|
|
5
|
+
/**
|
|
6
|
+
* Props for the Textarea component.
|
|
7
|
+
*/
|
|
8
|
+
export type TextareaProps = TextareaVariants & Omit<HTMLTextareaAttributes, 'children' | 'value' | 'rows'> & {
|
|
9
|
+
/**
|
|
10
|
+
* The current value of the textarea.
|
|
11
|
+
*/
|
|
12
|
+
value?: string | null;
|
|
13
|
+
/**
|
|
14
|
+
* The label text for the textarea.
|
|
15
|
+
*/
|
|
16
|
+
label: string;
|
|
17
|
+
/**
|
|
18
|
+
* The ID for the textarea element. Auto-generated but can be replaced.
|
|
19
|
+
*/
|
|
20
|
+
id?: string;
|
|
21
|
+
/**
|
|
22
|
+
* The placeholder text. Not used in M3: the label takes its place.
|
|
23
|
+
*/
|
|
24
|
+
placeholder?: '';
|
|
25
|
+
/**
|
|
26
|
+
* Minimum height, in lines. The field grows with its content from here. Defaults to 3.
|
|
27
|
+
*/
|
|
28
|
+
rows?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Maximum height, in lines, before the content scrolls. Omit to grow without limit; set it
|
|
31
|
+
* to `rows` for a fixed-height field.
|
|
32
|
+
*/
|
|
33
|
+
maxRows?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Snippet for supporting text (helper or error text) displayed below the field.
|
|
36
|
+
*/
|
|
37
|
+
supportingText?: Snippet;
|
|
38
|
+
/**
|
|
39
|
+
* Props for the leading icon, aligned with the first line.
|
|
40
|
+
*/
|
|
41
|
+
leadingIconProps?: IconProps;
|
|
42
|
+
/**
|
|
43
|
+
* Props for the trailing icon button, aligned with the first line.
|
|
44
|
+
*/
|
|
45
|
+
trailingIconProps?: IconProps;
|
|
46
|
+
/**
|
|
47
|
+
* Shows a character counter below the field. Going over it shows the error state; it does
|
|
48
|
+
* not stop typing (pass `maxlength` for a hard limit).
|
|
49
|
+
*/
|
|
50
|
+
characterLimit?: number;
|
|
51
|
+
/**
|
|
52
|
+
* Callback function when the trailing icon is clicked.
|
|
53
|
+
*/
|
|
54
|
+
trailingOnClick?: () => void;
|
|
55
|
+
/**
|
|
56
|
+
* Optional snippet for trailing icon override.
|
|
57
|
+
*/
|
|
58
|
+
trailingIcon?: Snippet;
|
|
59
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -30,14 +30,14 @@ export const textfield = tv({
|
|
|
30
30
|
transition-colors md-sys-motion-effects
|
|
31
31
|
`,
|
|
32
32
|
leadingIcon: `
|
|
33
|
-
text-md-sys-color-on-surface-variant size-
|
|
33
|
+
text-md-sys-color-on-surface-variant size-(--text-icon-24)
|
|
34
34
|
group-focus-within:text-md-sys-color-primary
|
|
35
|
-
ml-spacing-150 text-
|
|
35
|
+
ml-spacing-150 text-icon-24
|
|
36
36
|
`,
|
|
37
37
|
trailingIcon: `
|
|
38
|
-
mr-spacing-150 text-md-sys-color-on-surface-variant size-
|
|
38
|
+
mr-spacing-150 text-md-sys-color-on-surface-variant size-(--text-icon-24)
|
|
39
39
|
group-focus-within:text-md-sys-color-primary
|
|
40
|
-
z-20 text-
|
|
40
|
+
z-20 text-icon-24
|
|
41
41
|
`,
|
|
42
42
|
supportingText: `
|
|
43
43
|
px-spacing-200 pt-spacing-50 flex justify-between
|
|
@@ -14,7 +14,7 @@ export const toggleGroup = tv({
|
|
|
14
14
|
export const toggleGroupItem = tv({
|
|
15
15
|
slots: {
|
|
16
16
|
base: 'layer-container state-layer relative inline-flex min-w-spacing-600 flex-1 items-center justify-center gap-spacing-100 px-spacing-200 md-sys-typescale-label-large text-md-sys-color-on-surface outline-none transition-colors md-sys-motion-fast-effects disabled:cursor-not-allowed disabled:opacity-38 [&:not(:last-child)]:border-r [&:not(:last-child)]:border-md-sys-color-outline data-[state=on]:bg-md-sys-color-secondary-container data-[state=on]:text-md-sys-color-on-secondary-container',
|
|
17
|
-
checkIcon: 'size-
|
|
18
|
-
icon: 'size-
|
|
17
|
+
checkIcon: 'size-(--text-icon-18) text-icon-18',
|
|
18
|
+
icon: 'size-(--text-icon-18) text-icon-18'
|
|
19
19
|
}
|
|
20
20
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { RadioGroup } from '../forms/radio-group/index.js';
|
|
3
|
-
import { themeState, extractColorFromImage } from '../../utils/
|
|
3
|
+
import { themeState, extractColorFromImage } from '../../utils/themeState.svelte.js';
|
|
4
4
|
import { Title } from '../typography/title/index.js';
|
|
5
5
|
import { Body } from '../typography/body/index.js';
|
|
6
6
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Container-tier M3 color roles (see `styles/theme/*.css`) used as a generated avatar's
|
|
3
3
|
* background. Deliberately NOT a fixed hex list: every consuming app picks its own source
|
|
4
|
-
* color (`ThemeConfig.sourceColor` in `
|
|
4
|
+
* color (`ThemeConfig.sourceColor` in `themeState.svelte.ts`), which the M3 dynamic color
|
|
5
5
|
* algorithm expands into these tokens as real `--color-md-sys-color-*` custom properties on
|
|
6
6
|
* `:root` — reading them live is what makes the avatar match that app's actual palette
|
|
7
7
|
* instead of this library's own hardcoded pastel.
|
|
@@ -126,7 +126,7 @@ export const appbar = tv({
|
|
|
126
126
|
row: 'grid w-full items-center px-spacing-50',
|
|
127
127
|
childrenRow: 'w-full px-spacing-100 pb-spacing-100',
|
|
128
128
|
ghost: 'w-full shrink-0 pointer-events-none',
|
|
129
|
-
textContainer: 'flex min-w-spacing-0 flex-col gap-spacing-25 [--lead:
|
|
129
|
+
textContainer: 'flex min-w-spacing-0 flex-col gap-spacing-25 [--lead:var(--spacing-spacing-50)] [--trail:var(--spacing-spacing-50)]',
|
|
130
130
|
title: 'text-md-sys-color-on-surface',
|
|
131
131
|
subtitle: 'text-md-sys-color-on-surface-variant',
|
|
132
132
|
leading: 'text-md-sys-color-on-surface col-start-1 row-start-1 flex shrink-0 items-center justify-self-start',
|
|
@@ -163,7 +163,7 @@ export const appbar = tv({
|
|
|
163
163
|
searchContainer: {
|
|
164
164
|
true: {
|
|
165
165
|
row: 'grid-cols-[auto_1fr_auto]',
|
|
166
|
-
textContainer: '[--lead:
|
|
166
|
+
textContainer: '[--lead:var(--spacing-spacing-100)] [--trail:var(--spacing-spacing-100)]'
|
|
167
167
|
},
|
|
168
168
|
false: ''
|
|
169
169
|
},
|
|
@@ -173,10 +173,26 @@ export const appbar = tv({
|
|
|
173
173
|
},
|
|
174
174
|
compoundVariants: [
|
|
175
175
|
// A title with no button beside it sits at the 16dp inset.
|
|
176
|
-
{
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
176
|
+
{
|
|
177
|
+
align: 'start',
|
|
178
|
+
noLeading: true,
|
|
179
|
+
class: { textContainer: '[--lead:var(--spacing-spacing-200)]' }
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
align: 'start',
|
|
183
|
+
noTrailing: true,
|
|
184
|
+
class: { textContainer: '[--trail:var(--spacing-spacing-200)]' }
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
searchContainer: true,
|
|
188
|
+
noLeading: true,
|
|
189
|
+
class: { textContainer: '[--lead:var(--spacing-spacing-150)]' }
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
searchContainer: true,
|
|
193
|
+
noTrailing: true,
|
|
194
|
+
class: { textContainer: '[--trail:var(--spacing-spacing-150)]' }
|
|
195
|
+
}
|
|
180
196
|
],
|
|
181
197
|
defaultVariants: {
|
|
182
198
|
align: 'start',
|
|
@@ -12,7 +12,7 @@ export const navitem = tv({
|
|
|
12
12
|
base: 'group relative flex flex-1 flex-col items-center justify-center min-w-spacing-0 max-w-[168px] h-full transition-colors md-sys-motion-fast-effects',
|
|
13
13
|
content: 'flex flex-col items-center justify-center gap-spacing-50 w-full',
|
|
14
14
|
iconContainer: 'relative flex items-center justify-center h-spacing-400 w-spacing-800 rounded-full transition-colors md-sys-motion-effects',
|
|
15
|
-
icon: 'text-
|
|
15
|
+
icon: 'text-icon-24 size-(--text-icon-24)',
|
|
16
16
|
label: 'md-sys-typescale-label-medium truncate w-full text-center'
|
|
17
17
|
},
|
|
18
18
|
variants: {
|
|
@@ -19,7 +19,7 @@ export const tab = tv({
|
|
|
19
19
|
'data-[state=inactive]:text-md-sys-color-on-surface-variant'
|
|
20
20
|
].join(' '),
|
|
21
21
|
label: 'md-sys-typescale-title-small',
|
|
22
|
-
icon: 'size-
|
|
22
|
+
icon: 'size-(--text-icon-24) text-icon-24'
|
|
23
23
|
},
|
|
24
24
|
variants: {
|
|
25
25
|
variant: {
|
|
@@ -14,12 +14,14 @@ travels around the circle.
|
|
|
14
14
|
import { animate, type AnimationPlaybackControls } from 'motion';
|
|
15
15
|
import { springTokens, springTransition } from '../../animation/spring.js';
|
|
16
16
|
import { SpringValue } from '../../animation/springValue.svelte.js';
|
|
17
|
+
import type { ProgressA11yProps } from './types.js';
|
|
17
18
|
|
|
18
19
|
let {
|
|
19
20
|
percent,
|
|
20
21
|
size = 48,
|
|
21
|
-
thickness = 4
|
|
22
|
-
|
|
22
|
+
thickness = 4,
|
|
23
|
+
...a11y
|
|
24
|
+
}: ProgressA11yProps & {
|
|
23
25
|
/** The current progress percentage (0–100). Omit or pass null for indeterminate. */
|
|
24
26
|
percent?: number | null;
|
|
25
27
|
/** Diameter of the indicator in pixels. Defaults to 48. */
|
|
@@ -93,7 +95,7 @@ travels around the circle.
|
|
|
93
95
|
);
|
|
94
96
|
</script>
|
|
95
97
|
|
|
96
|
-
<Progress.Root value={percent ?? null} max={100} data-cy="m3-circular-progress">
|
|
98
|
+
<Progress.Root {...a11y} value={percent ?? null} max={100} data-cy="m3-circular-progress">
|
|
97
99
|
{#snippet child({ props })}
|
|
98
100
|
<svg
|
|
99
101
|
{...props}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
type
|
|
1
|
+
import type { ProgressA11yProps } from './types.js';
|
|
2
|
+
type $$ComponentProps = ProgressA11yProps & {
|
|
2
3
|
/** The current progress percentage (0–100). Omit or pass null for indeterminate. */
|
|
3
4
|
percent?: number | null;
|
|
4
5
|
/** Diameter of the indicator in pixels. Defaults to 48. */
|
|
@@ -16,12 +16,14 @@ The track always keeps a gap either side of the bar.
|
|
|
16
16
|
import { animate, type AnimationPlaybackControls } from 'motion';
|
|
17
17
|
import { springTokens, springTransition } from '../../animation/spring.js';
|
|
18
18
|
import { SpringValue } from '../../animation/springValue.svelte.js';
|
|
19
|
+
import type { ProgressA11yProps } from './types.js';
|
|
19
20
|
|
|
20
21
|
let {
|
|
21
22
|
percent,
|
|
22
23
|
height = 4,
|
|
23
|
-
class: className
|
|
24
|
-
|
|
24
|
+
class: className,
|
|
25
|
+
...a11y
|
|
26
|
+
}: ProgressA11yProps & {
|
|
25
27
|
/** The current progress percentage (0–100). Omit or pass null for indeterminate. */
|
|
26
28
|
percent?: number | null;
|
|
27
29
|
/** Height of the bar in pixels. Defaults to 4. */
|
|
@@ -84,6 +86,7 @@ The track always keeps a gap either side of the bar.
|
|
|
84
86
|
</script>
|
|
85
87
|
|
|
86
88
|
<Progress.Root
|
|
89
|
+
{...a11y}
|
|
87
90
|
value={percent ?? null}
|
|
88
91
|
max={100}
|
|
89
92
|
class={container({ class: clsx(className) })}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
type
|
|
1
|
+
import type { ProgressA11yProps } from './types.js';
|
|
2
|
+
type $$ComponentProps = ProgressA11yProps & {
|
|
2
3
|
/** The current progress percentage (0–100). Omit or pass null for indeterminate. */
|
|
3
4
|
percent?: number | null;
|
|
4
5
|
/** Height of the bar in pixels. Defaults to 4. */
|
|
@@ -13,14 +13,16 @@ effects spring (critically damped, so progress never visibly runs backwards).
|
|
|
13
13
|
import { springTokens } from '../../animation/spring.js';
|
|
14
14
|
import { SpringValue } from '../../animation/springValue.svelte.js';
|
|
15
15
|
import { linear, trackOpacity, WAVE_PERIOD_MS } from './_wavy.js';
|
|
16
|
+
import type { ProgressA11yProps } from './types.js';
|
|
16
17
|
|
|
17
18
|
let {
|
|
18
19
|
width = 600,
|
|
19
20
|
height = 10,
|
|
20
21
|
thickness = 4,
|
|
21
22
|
percent,
|
|
22
|
-
class: className
|
|
23
|
-
|
|
23
|
+
class: className,
|
|
24
|
+
...a11y
|
|
25
|
+
}: ProgressA11yProps & {
|
|
24
26
|
/** Width of the SVG viewBox. */
|
|
25
27
|
width?: number;
|
|
26
28
|
/** Height of the SVG viewBox. */
|
|
@@ -56,7 +58,7 @@ effects spring (critically damped, so progress never visibly runs backwards).
|
|
|
56
58
|
let wavePath = $derived(linear(height / 2 - thickness / 2, height / 2, left, percentX, time));
|
|
57
59
|
</script>
|
|
58
60
|
|
|
59
|
-
<Progress.Root value={percent ?? null} max={100}>
|
|
61
|
+
<Progress.Root {...a11y} value={percent ?? null} max={100}>
|
|
60
62
|
{#snippet child({ props })}
|
|
61
63
|
<svg {...props} viewBox="0 0 {width} {height}" class={className}>
|
|
62
64
|
<path
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './_wavy.js';
|
|
2
|
+
export * from './types.js';
|
|
2
3
|
export { default as CircularProgress } from './CircularProgress.svelte';
|
|
3
4
|
export { default as LinearProgress } from './LinearProgress.svelte';
|
|
4
5
|
export { default as WavyLinearProgress } from './WavyLinearProgress.svelte';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// THIS FILE IS AUTO-GENERATED BY scripts/generate-components-index.ts - DO NOT EDIT MANUALLY
|
|
2
2
|
// re-export TS/JS modules from this folder
|
|
3
3
|
export * from './_wavy.js';
|
|
4
|
+
export * from './types.js';
|
|
4
5
|
// default exports for components in this folder
|
|
5
6
|
export { default as CircularProgress } from './CircularProgress.svelte';
|
|
6
7
|
export { default as LinearProgress } from './LinearProgress.svelte';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Accessible-name attributes shared by every progress indicator, forwarded to the element with
|
|
3
|
+
* `role="progressbar"`. Give each indicator a name when more than one is on screen, or when the
|
|
4
|
+
* visible label is not already associated with it.
|
|
5
|
+
*/
|
|
6
|
+
export type ProgressA11yProps = {
|
|
7
|
+
id?: string;
|
|
8
|
+
/** Accessible name, e.g. `"Reading comprehension"`. */
|
|
9
|
+
'aria-label'?: string;
|
|
10
|
+
/** Id of the element whose text names the indicator. */
|
|
11
|
+
'aria-labelledby'?: string;
|
|
12
|
+
/** Id of the element that describes the indicator. */
|
|
13
|
+
'aria-describedby'?: string;
|
|
14
|
+
/** Human-readable value, e.g. `"3 of 5 lessons"`. Defaults to the percentage. */
|
|
15
|
+
'aria-valuetext'?: string;
|
|
16
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -5,7 +5,7 @@ export const snackbar = tv({
|
|
|
5
5
|
label: 'text-md-sys-color-inverse-primary md-sys-typescale-label-large px-spacing-150 cursor-pointer ',
|
|
6
6
|
actionWrapper: 'flex items-center z-40',
|
|
7
7
|
supportingText: 'text-md-sys-color-inverse-on-surface md-sys-typescale-body-medium max-w-[60ch] ',
|
|
8
|
-
icon: 'size-
|
|
8
|
+
icon: 'size-(--text-icon-24) text-icon-24 text-md-sys-color-inverse-on-surface mr-spacing-50 ml-spacing-150'
|
|
9
9
|
},
|
|
10
10
|
variants: {
|
|
11
11
|
fixed: {
|
|
@@ -36,7 +36,7 @@ and `sortDirection` props. Defaults to `scope="col"`.
|
|
|
36
36
|
].join(' ')}
|
|
37
37
|
aria-hidden="true"
|
|
38
38
|
>
|
|
39
|
-
<Icon name="arrow_upward" class="size-
|
|
39
|
+
<Icon name="arrow_upward" class="text-icon-18 size-(--text-icon-18)" />
|
|
40
40
|
</span>
|
|
41
41
|
{/if}
|
|
42
42
|
</span>
|
|
@@ -52,7 +52,7 @@ export const toolbar = tv({
|
|
|
52
52
|
export const toolbarButton = tv({
|
|
53
53
|
slots: {
|
|
54
54
|
base: 'layer-container state-layer before:rounded-full relative inline-flex size-spacing-500 items-center justify-center rounded-full outline-none transition-colors md-sys-motion-fast-effects disabled:cursor-not-allowed disabled:opacity-38',
|
|
55
|
-
icon: 'size-
|
|
55
|
+
icon: 'size-(--text-icon-20) text-icon-20'
|
|
56
56
|
},
|
|
57
57
|
variants: {
|
|
58
58
|
color: {
|
|
@@ -65,7 +65,7 @@ export const toolbarButton = tv({
|
|
|
65
65
|
export const toolbarGroupItem = tv({
|
|
66
66
|
slots: {
|
|
67
67
|
base: 'layer-container state-layer before:rounded-full relative inline-flex size-spacing-500 items-center justify-center rounded-full outline-none transition-colors md-sys-motion-fast-effects disabled:cursor-not-allowed disabled:opacity-38',
|
|
68
|
-
icon: 'size-
|
|
68
|
+
icon: 'size-(--text-icon-20) text-icon-20'
|
|
69
69
|
},
|
|
70
70
|
variants: {
|
|
71
71
|
color: {
|