m3-svelte 5.10.0 → 5.12.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.
@@ -11,6 +11,7 @@
11
11
  variant?: "elevated" | "filled" | "tonal" | "outlined" | "text";
12
12
  square?: boolean;
13
13
  iconType?: "none" | "left" | "full";
14
+ size?: "xs" | "s" | "m" | "l" | "xl";
14
15
  children: Snippet;
15
16
  } & ActionProps;
16
17
 
@@ -18,35 +19,32 @@
18
19
  variant = "filled",
19
20
  square = false,
20
21
  iconType = "none",
22
+ size = "s",
21
23
  children,
22
24
  ...props
23
25
  }: Props = $props();
24
26
  </script>
25
27
 
26
28
  {#if "for" in props}
27
- <label class="m3-container m3-font-label-large {variant} icon-{iconType}" class:square {...props}>
29
+ <label class="m3-container {variant} {size} icon-{iconType}" class:square {...props}>
28
30
  <Layer />
29
31
  {@render children()}
30
32
  </label>
31
33
  {:else if "href" in props}
32
- <a class="m3-container m3-font-label-large {variant} icon-{iconType}" class:square {...props}>
34
+ <a class="m3-container {variant} {size} icon-{iconType}" class:square {...props}>
33
35
  <Layer />
34
36
  {@render children()}
35
37
  </a>
36
38
  {:else if "summary" in props}
37
39
  {@const { summary: _, ...extra } = props}
38
- <summary
39
- class="m3-container m3-font-label-large {variant} icon-{iconType}"
40
- class:square
41
- {...extra}
42
- >
40
+ <summary class="m3-container {variant} {size} icon-{iconType}" class:square {...extra}>
43
41
  <Layer />
44
42
  {@render children()}
45
43
  </summary>
46
44
  {:else}
47
45
  <button
48
46
  type={"onclick" in props ? "button" : "submit"}
49
- class="m3-container m3-font-label-large {variant} icon-{iconType}"
47
+ class="m3-container {variant} {size} icon-{iconType}"
50
48
  class:square
51
49
  {...props}
52
50
  >
@@ -56,16 +54,79 @@
56
54
  {/if}
57
55
 
58
56
  <style>
59
- :root {
57
+ .m3-container.xs {
58
+ height: calc(2rem + var(--m3-util-density-term));
59
+ padding: 0 0.75rem;
60
+ gap: 0.5rem;
61
+ --m3-button-shape: 1rem;
62
+ --m3-button-square-shape: var(--m3-util-rounding-medium);
63
+ --m3-button-pressed-shape: var(--m3-util-rounding-small);
64
+ font-family: var(--m3-font-label, var(--m3-font));
65
+ font-size: var(--m3-font-label-large-size, 0.875rem);
66
+ line-height: var(--m3-font-label-large-height, 1.429);
67
+ letter-spacing: var(--m3-font-label-large-tracking, 0.006rem);
68
+ font-weight: var(--m3-font-label-large-weight, 500);
69
+ }
70
+
71
+ .m3-container.s {
72
+ height: calc(2.5rem + var(--m3-util-density-term));
73
+ padding: 0 1rem;
74
+ gap: 0.5rem;
60
75
  --m3-button-shape: 1.25rem;
76
+ --m3-button-square-shape: var(--m3-util-rounding-medium);
77
+ --m3-button-pressed-shape: var(--m3-util-rounding-small);
78
+ font-family: var(--m3-font-label, var(--m3-font));
79
+ font-size: var(--m3-font-label-large-size, 0.875rem);
80
+ line-height: var(--m3-font-label-large-height, 1.429);
81
+ letter-spacing: var(--m3-font-label-large-tracking, 0.006rem);
82
+ font-weight: var(--m3-font-label-large-weight, 500);
83
+ }
84
+
85
+ .m3-container.m {
86
+ height: calc(3.5rem + var(--m3-util-density-term));
87
+ padding: 0 1.5rem;
88
+ gap: 0.5rem;
89
+ --m3-button-shape: 1.75rem;
90
+ --m3-button-square-shape: var(--m3-util-rounding-large);
91
+ --m3-button-pressed-shape: var(--m3-util-rounding-medium);
92
+ font-family: var(--m3-font-title, var(--m3-font));
93
+ font-size: var(--m3-font-title-medium-size, 1rem);
94
+ line-height: var(--m3-font-title-medium-height, 1.5);
95
+ letter-spacing: var(--m3-font-title-medium-tracking, 0);
96
+ font-weight: var(--m3-font-title-medium-weight, 500);
97
+ }
98
+
99
+ .m3-container.l {
100
+ height: calc(6rem + var(--m3-util-density-term));
101
+ padding: 0 3rem;
102
+ gap: 0.75rem;
103
+ --m3-button-shape: 3rem;
104
+ --m3-button-square-shape: var(--m3-util-rounding-extra-large);
105
+ --m3-button-pressed-shape: var(--m3-util-rounding-large);
106
+ font-family: var(--m3-font-headline, var(--m3-font));
107
+ font-size: var(--m3-font-headline-small-size, 1.5rem);
108
+ line-height: var(--m3-font-headline-small-height, 1.333);
109
+ letter-spacing: var(--m3-font-headline-small-tracking, 0);
110
+ font-weight: var(--m3-font-headline-small-weight, 400);
111
+ }
112
+
113
+ .m3-container.xl {
114
+ height: calc(8.5rem + var(--m3-util-density-term));
115
+ padding: 0 4rem;
116
+ gap: 1rem;
117
+ --m3-button-shape: 4.25rem;
118
+ --m3-button-square-shape: var(--m3-util-rounding-extra-large);
119
+ --m3-button-pressed-shape: var(--m3-util-rounding-large);
120
+ font-family: var(--m3-font-headline, var(--m3-font));
121
+ font-size: var(--m3-font-headline-large-size, 2rem);
122
+ line-height: var(--m3-font-headline-large-height, 1.25);
123
+ letter-spacing: var(--m3-font-headline-large-tracking, 0);
124
+ font-weight: var(--m3-font-headline-large-weight, 400);
61
125
  }
62
126
 
63
127
  .m3-container {
64
128
  display: inline-flex;
65
129
  border: none;
66
- height: calc(2.5rem + var(--m3-util-density-term));
67
- gap: 0.5rem;
68
- padding: 0 1rem;
69
130
  border-radius: var(--m3-button-shape);
70
131
  transition:
71
132
  border-radius var(--m3-util-easing-fast-spatial),
@@ -121,6 +182,14 @@
121
182
  outline: 1px solid rgb(var(--m3-scheme-outline-variant));
122
183
  outline-offset: -1px;
123
184
  }
185
+ &.outlined.l {
186
+ outline-width: 2px;
187
+ outline-offset: -2px;
188
+ }
189
+ &.outlined.xl {
190
+ outline-width: 3px;
191
+ outline-offset: -3px;
192
+ }
124
193
  &.outlined:not(:disabled, :global(input:disabled) + label) {
125
194
  outline-color: rgb(var(--m3-scheme-outline-variant));
126
195
  color: rgb(var(--m3-scheme-on-surface-variant));
@@ -145,28 +214,73 @@
145
214
 
146
215
  &.square:not(:is(:global(input:checked) + label, :global(:open) > summary)),
147
216
  &:is(:global(input:checked) + label, :global(:open) > summary):not(.square) {
148
- border-radius: var(--m3-util-rounding-medium);
217
+ border-radius: var(--m3-button-square-shape);
149
218
  }
150
219
  &:active:not(:disabled, :global(input:disabled) + label) {
151
- border-radius: var(--m3-util-rounding-small) !important;
220
+ border-radius: var(--m3-button-pressed-shape) !important;
152
221
  }
153
222
  }
154
223
 
155
224
  .m3-container > :global(*) {
156
225
  flex-shrink: 0;
157
226
  }
158
- .icon-left > :global(svg) {
159
- width: 1.125rem;
160
- height: 1.125rem;
227
+
228
+ .xs.icon-left > :global(svg),
229
+ .s.icon-left > :global(svg) {
230
+ width: 1.25rem;
231
+ height: 1.25rem;
161
232
  }
162
- .icon-full {
233
+ .m.icon-left > :global(svg) {
234
+ width: 1.5rem;
235
+ height: 1.5rem;
236
+ }
237
+ .l.icon-left > :global(svg) {
238
+ width: 2rem;
239
+ height: 2rem;
240
+ }
241
+ .xl.icon-left > :global(svg) {
242
+ width: 2.5rem;
243
+ height: 2.5rem;
244
+ }
245
+
246
+ .xs.icon-full {
247
+ width: 2rem;
248
+ padding: 0;
249
+ }
250
+ .s.icon-full {
163
251
  width: 2.5rem;
164
252
  padding: 0;
165
253
  }
166
- .icon-full > :global(svg) {
254
+ .m.icon-full {
255
+ width: 3.5rem;
256
+ padding: 0;
257
+ }
258
+ .l.icon-full {
259
+ width: 6rem;
260
+ padding: 0;
261
+ }
262
+ .xl.icon-full {
263
+ width: 8.5rem;
264
+ padding: 0;
265
+ }
266
+
267
+ .xs.icon-full > :global(svg),
268
+ .s.icon-full > :global(svg) {
269
+ width: 1.25rem;
270
+ height: 1.25rem;
271
+ }
272
+ .m.icon-full > :global(svg) {
167
273
  width: 1.5rem;
168
274
  height: 1.5rem;
169
275
  }
276
+ .l.icon-full > :global(svg) {
277
+ width: 2rem;
278
+ height: 2rem;
279
+ }
280
+ .xl.icon-full > :global(svg) {
281
+ width: 2.5rem;
282
+ height: 2.5rem;
283
+ }
170
284
 
171
285
  .m3-container {
172
286
  print-color-adjust: exact;
@@ -9,6 +9,7 @@ type Props = {
9
9
  variant?: "elevated" | "filled" | "tonal" | "outlined" | "text";
10
10
  square?: boolean;
11
11
  iconType?: "none" | "left" | "full";
12
+ size?: "xs" | "s" | "m" | "l" | "xl";
12
13
  children: Snippet;
13
14
  } & ActionProps;
14
15
  declare const Button: import("svelte").Component<Props, {}, "">;
@@ -6,15 +6,17 @@
6
6
  toggle = $bindable(),
7
7
  variant,
8
8
  round = false,
9
+ size,
9
10
  children,
10
11
  }: {
11
12
  toggle: boolean;
12
13
  variant?: "filled" | "tonal";
13
14
  round?: boolean;
15
+ size?: "xs" | "s" | "m" | "l" | "xl";
14
16
  children: Snippet;
15
17
  } = $props();
16
18
  const id = $props.id();
17
19
  </script>
18
20
 
19
21
  <input type="checkbox" {id} bind:checked={toggle} />
20
- <Button for={id} {variant} square={!round} {children} />
22
+ <Button for={id} {variant} square={!round} {size} {children} />
@@ -3,6 +3,7 @@ type $$ComponentProps = {
3
3
  toggle: boolean;
4
4
  variant?: "filled" | "tonal";
5
5
  round?: boolean;
6
+ size?: "xs" | "s" | "m" | "l" | "xl";
6
7
  children: Snippet;
7
8
  };
8
9
  declare const TogglePrimitive: import("svelte").Component<$$ComponentProps, {}, "toggle">;
@@ -0,0 +1,113 @@
1
+ <script module lang="ts">
2
+ export const snackbar = (
3
+ message: string,
4
+ actions?: Record<string, () => void>,
5
+ closable?: boolean,
6
+ /*
7
+ undefined/unset -> 4s timeout
8
+ 2000 -> 2s timeout
9
+ -1 -> no timeout
10
+ */
11
+ timeout?: number,
12
+ ) => {
13
+ _show(message, actions, closable, timeout);
14
+ };
15
+ let _show: typeof snackbar;
16
+ </script>
17
+
18
+ <script lang="ts">
19
+ import { fade } from "svelte/transition";
20
+ import iconX from "@ktibow/iconset-material-symbols/close";
21
+ import Icon from "../misc/Icon.svelte";
22
+ import SnackbarItem from "./SnackbarItem.svelte";
23
+ import Layer from "../misc/Layer.svelte";
24
+
25
+ let { closeTitle = "Close" }: { closeTitle?: string } = $props();
26
+ let shown:
27
+ | { message: string; actions: Record<string, () => void>; closable: boolean }
28
+ | undefined = $state();
29
+ let timeoutId: number;
30
+ _show = (message, actions = {}, closable = false, timeout = 4000) => {
31
+ shown = { message, actions, closable };
32
+ clearTimeout(timeoutId);
33
+ if (timeout && timeout > 0)
34
+ timeoutId = setTimeout(() => {
35
+ shown = undefined;
36
+ }, timeout);
37
+ };
38
+ </script>
39
+
40
+ {#if shown}
41
+ <div class="holder" out:fade={{ duration: 200 }}>
42
+ {#key shown}
43
+ <SnackbarItem>
44
+ <p class="m3-font-body-medium">{shown.message}</p>
45
+ {#each Object.entries(shown.actions) as [key, action]}
46
+ <button
47
+ type="button"
48
+ class="action m3-font-label-large"
49
+ onclick={() => {
50
+ shown = undefined;
51
+ action();
52
+ }}
53
+ >
54
+ {key}
55
+ </button>
56
+ {/each}
57
+ {#if shown.closable}
58
+ <button
59
+ type="button"
60
+ class="close"
61
+ title={closeTitle}
62
+ onclick={() => {
63
+ shown = undefined;
64
+ }}
65
+ >
66
+ <Layer />
67
+ <Icon icon={iconX} />
68
+ </button>
69
+ {/if}
70
+ </SnackbarItem>
71
+ {/key}
72
+ </div>
73
+ {/if}
74
+
75
+ <style>
76
+ .holder {
77
+ position: fixed;
78
+ padding-bottom: 1rem;
79
+ bottom: var(--m3-util-bottom-offset);
80
+ left: 50%;
81
+ transform: translate(-50%, 0);
82
+ z-index: 3;
83
+ }
84
+ p {
85
+ margin-right: auto;
86
+ }
87
+ button {
88
+ display: flex;
89
+ align-self: stretch;
90
+ align-items: center;
91
+ margin: 0;
92
+ padding: 0;
93
+ border: none;
94
+
95
+ background-color: transparent;
96
+ color: unset;
97
+ cursor: pointer;
98
+ position: relative;
99
+ }
100
+ button :global(svg) {
101
+ width: 1.5rem;
102
+ height: 1.5rem;
103
+ }
104
+
105
+ .action {
106
+ color: rgb(var(--m3-scheme-inverse-primary));
107
+ padding: 0 0.5rem;
108
+ }
109
+ .close {
110
+ padding: 0 0.75rem;
111
+ margin-right: -1rem;
112
+ }
113
+ </style>
@@ -0,0 +1,7 @@
1
+ export declare const snackbar: (message: string, actions?: Record<string, () => void>, closable?: boolean, timeout?: number) => void;
2
+ type $$ComponentProps = {
3
+ closeTitle?: string;
4
+ };
5
+ declare const NewSnackbar: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type NewSnackbar = ReturnType<typeof NewSnackbar>;
7
+ export default NewSnackbar;
@@ -1,3 +1,7 @@
1
+ <!--
2
+ @component
3
+ @deprecated use NewSnackbar instead
4
+ -->
1
5
  <script module lang="ts">
2
6
  export type SnackbarIn = {
3
7
  message: string;
@@ -12,6 +12,7 @@ type $$ComponentProps = {
12
12
  config?: SnackbarConfig;
13
13
  closeButtonTitle?: string;
14
14
  } & DivAttrs;
15
+ /** @deprecated use NewSnackbar instead */
15
16
  declare const Snackbar: import("svelte").Component<$$ComponentProps, {
16
17
  show: ({ message, actions, closable, timeout }: SnackbarIn) => void;
17
18
  }, "">;
@@ -18,6 +18,7 @@ export { default as MenuItem } from "./containers/MenuItem.svelte";
18
18
  export { default as Snackbar } from "./containers/Snackbar.svelte";
19
19
  export type { SnackbarIn } from "./containers/Snackbar.svelte";
20
20
  export { default as SnackbarItem } from "./containers/SnackbarItem.svelte";
21
+ export { default as NewSnackbar, snackbar } from "./containers/NewSnackbar.svelte";
21
22
  export { default as Checkbox } from "./forms/Checkbox.svelte";
22
23
  export { default as Chip } from "./forms/Chip.svelte";
23
24
  export { default as CircularProgress } from "./forms/CircularProgress.svelte";
package/package/index.js CHANGED
@@ -17,6 +17,7 @@ export { default as Menu } from "./containers/Menu.svelte";
17
17
  export { default as MenuItem } from "./containers/MenuItem.svelte";
18
18
  export { default as Snackbar } from "./containers/Snackbar.svelte";
19
19
  export { default as SnackbarItem } from "./containers/SnackbarItem.svelte";
20
+ export { default as NewSnackbar, snackbar } from "./containers/NewSnackbar.svelte";
20
21
  export { default as Checkbox } from "./forms/Checkbox.svelte";
21
22
  export { default as Chip } from "./forms/Chip.svelte";
22
23
  export { default as CircularProgress } from "./forms/CircularProgress.svelte";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "m3-svelte",
3
- "version": "5.10.0",
3
+ "version": "5.12.0",
4
4
  "license": "Apache-2.0 OR GPL-3.0-only",
5
5
  "repository": "KTibow/m3-svelte",
6
6
  "author": {
@@ -35,18 +35,18 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@iconify/types": "^2.0.0",
38
- "@ktibow/iconset-material-symbols": "~0.0.1760073587",
39
- "@ktibow/material-color-utilities-nightly": "^0.3.11760125264000",
40
- "svelte": "^5.39.11"
38
+ "@ktibow/iconset-material-symbols": "~0.0.1760591837",
39
+ "@ktibow/material-color-utilities-nightly": "^0.3.11760728781000",
40
+ "svelte": "^5.41.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@eslint/compat": "^1.4.0",
44
- "@eslint/js": "^9.37.0",
44
+ "@eslint/js": "^9.38.0",
45
45
  "@sveltejs/adapter-static": "^3.0.10",
46
- "@sveltejs/kit": "^2.46.4",
46
+ "@sveltejs/kit": "^2.47.1",
47
47
  "@sveltejs/package": "^2.5.4",
48
48
  "@sveltejs/vite-plugin-svelte": "^6.2.1",
49
- "eslint": "^9.37.0",
49
+ "eslint": "^9.38.0",
50
50
  "eslint-config-prettier": "^10.1.8",
51
51
  "eslint-plugin-svelte": "^3.12.4",
52
52
  "fast-glob": "^3.3.3",
@@ -58,7 +58,7 @@
58
58
  "svelte-highlight": "^7.8.4",
59
59
  "typescript": "^5.9.3",
60
60
  "typescript-eslint": "^8.46.1",
61
- "vite": "^7.1.9"
61
+ "vite": "^7.1.10"
62
62
  },
63
63
  "keywords": [
64
64
  "svelte",