m3-svelte 6.0.1 → 6.0.2

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/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # m3-svelte
1
+ # M3 Svelte
2
2
 
3
3
  M3 Svelte implements the Material 3 design system in Svelte. See the [website](https://ktibow.github.io/m3-svelte/) for demos and usage instructions.
@@ -241,8 +241,8 @@
241
241
  }
242
242
  }
243
243
 
244
- &.square:not(:is(:global(input:checked) + label, :global(:open) > summary)),
245
- &:is(:global(input:checked) + label, :global(:open) > summary):not(.square) {
244
+ &.square:not(:global(input:checked) + label, :global(:open) > summary),
245
+ &:not(.square):is(:global(input:checked) + label, :global(:open) > summary) {
246
246
  border-radius: var(--square-shape);
247
247
  }
248
248
  &:active:not(:disabled, :global(input:disabled) + label) {
@@ -260,7 +260,6 @@
260
260
 
261
261
  .m3-container {
262
262
  print-color-adjust: exact;
263
- -webkit-print-color-adjust: exact;
264
263
  }
265
264
  @media screen and (forced-colors: active) {
266
265
  .m3-container:is(.elevated, .filled, .tonal) {
@@ -141,7 +141,6 @@
141
141
 
142
142
  .m3-container {
143
143
  print-color-adjust: exact;
144
- -webkit-print-color-adjust: exact;
145
144
  }
146
145
  @media screen and (forced-colors: active) {
147
146
  button {
@@ -181,6 +181,5 @@
181
181
 
182
182
  .m3-container {
183
183
  print-color-adjust: exact;
184
- -webkit-print-color-adjust: exact;
185
184
  }
186
185
  </style>
@@ -27,7 +27,7 @@
27
27
  let shown:
28
28
  | { message: string; actions: Record<string, () => void>; closable: boolean }
29
29
  | undefined = $state();
30
- let timeoutId: number;
30
+ let timeoutId: ReturnType<typeof setTimeout>;
31
31
  _show = (message, actions = {}, closable = false, timeout = 4000) => {
32
32
  clearTimeout(timeoutId);
33
33
  shown = { message, actions, closable };
@@ -110,7 +110,6 @@
110
110
 
111
111
  .m3-container {
112
112
  print-color-adjust: exact;
113
- -webkit-print-color-adjust: exact;
114
113
  }
115
114
  @media screen and (forced-colors: active) {
116
115
  :global(input:checked) + .layer-container .checkbox-box {
@@ -156,7 +156,6 @@
156
156
 
157
157
  .m3-container {
158
158
  print-color-adjust: exact;
159
- -webkit-print-color-adjust: exact;
160
159
  }
161
160
  @media screen and (forced-colors: active) {
162
161
  .selected {
@@ -55,39 +55,7 @@
55
55
  }
56
56
 
57
57
  .percent {
58
- animation: grow
59
- linear(
60
- 0,
61
- 0.08 1.5%,
62
- 0.15 2.93%,
63
- 0.22 4.48%,
64
- 0.29 6.18%,
65
- 0.35 7.77%,
66
- 0.41 9.52%,
67
- 0.47 11.45%,
68
- 0.52 13.24%,
69
- 0.57 15.22%,
70
- 0.61 16.98%,
71
- 0.65 18.93%,
72
- 0.69 21.12%,
73
- 0.73 23.61%,
74
- 0.76 25.74%,
75
- 0.79 28.14%,
76
- 0.82 30.92%,
77
- 0.84 33.05%,
78
- 0.86 35.46%,
79
- 0.88 38.24%,
80
- 0.9 41.52%,
81
- 0.92 45.55%,
82
- 0.93 47.96%,
83
- 0.95 54.02%,
84
- 0.96 58.05%,
85
- 0.97 63.24%,
86
- 0.98 70.55%,
87
- 0.99 83.05%,
88
- 1
89
- )
90
- var(--speed) both;
58
+ animation: grow var(--m3-timing-function-zeno) var(--speed) both;
91
59
  }
92
60
 
93
61
  @keyframes grow {
@@ -1,70 +1,5 @@
1
1
  <script lang="ts">
2
2
  let { sToHalfway = 1, height = 4 }: { sToHalfway?: number; height?: number } = $props();
3
- /*
4
- Easing calculated with
5
- // 1) define the original mapping f(y)=time-%, capped at 100% for y=1
6
- const whenReached = (y) => Math.log(1 - y) / Math.log(0.5);
7
- const makePoints = () => {
8
- const pts = [];
9
- for (let i = 0; i < 100; i++) {
10
- const v = i / 100;
11
- const t = (whenReached(v) * 100) / 8;
12
- pts.push([v, t]);
13
- }
14
- // add the final point (1, 100)
15
- pts.push([1, 100]);
16
- return pts;
17
- };
18
-
19
- // 2) helper: compute perpendicular distance from pt to line (p0→p1)
20
- const perpDist = (pt, p0, p1) => {
21
- const [x, y] = pt;
22
- const [x1, y1] = p0;
23
- const [x2, y2] = p1;
24
- const num = Math.abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1);
25
- const den = Math.hypot(y2 - y1, x2 - x1);
26
- return den === 0 ? 0 : num / den;
27
- };
28
-
29
- // 3) RDP (recursive)
30
- function rdp(points, eps) {
31
- if (points.length < 3) return points;
32
- let maxD = 0,
33
- idx = 0;
34
- for (let i = 1; i < points.length - 1; i++) {
35
- const d = perpDist(points[i], points[0], points[points.length - 1]);
36
- if (d > maxD) {
37
- maxD = d;
38
- idx = i;
39
- }
40
- }
41
- if (maxD > eps) {
42
- const left = rdp(points.slice(0, idx + 1), eps);
43
- const right = rdp(points.slice(idx), eps);
44
- return left.slice(0, -1).concat(right);
45
- }
46
- return [points[0], points[points.length - 1]];
47
- }
48
-
49
- // 4) round x to 2 decimals (keep trailing zeros); round y to 2 decimals (cap tiny negatives to 0)
50
- const fmt = (v, t) => {
51
- const xv = v.toFixed(2);
52
- let tv = Math.round(t * 100) / 100; // round to 2 decimals
53
- if (Math.abs(tv) < 1e-8) tv = 0; // avoid "-0.00"
54
- return `${xv} ${tv.toFixed(2)}%`;
55
- };
56
-
57
- // 5) put it all together
58
- function buildCompressedLinear(tolerance) {
59
- const raw = makePoints();
60
- const reduced = rdp(raw, tolerance);
61
- return `linear(${reduced.map(([v, t]) => fmt(v, t)).join(", ")})`;
62
- }
63
-
64
- // 6) example result
65
- const compressed = buildCompressedLinear(0.001);
66
- console.log(compressed);
67
- */
68
3
  </script>
69
4
 
70
5
  <div
@@ -86,39 +21,7 @@
86
21
  background-color: var(--m3c-primary);
87
22
  border-radius: var(--m3-shape-full);
88
23
  flex-shrink: 0;
89
- animation: grow
90
- linear(
91
- 0,
92
- 0.08 1.5%,
93
- 0.15 2.93%,
94
- 0.22 4.48%,
95
- 0.29 6.18%,
96
- 0.35 7.77%,
97
- 0.41 9.52%,
98
- 0.47 11.45%,
99
- 0.52 13.24%,
100
- 0.57 15.22%,
101
- 0.61 16.98%,
102
- 0.65 18.93%,
103
- 0.69 21.12%,
104
- 0.73 23.61%,
105
- 0.76 25.74%,
106
- 0.79 28.14%,
107
- 0.82 30.92%,
108
- 0.84 33.05%,
109
- 0.86 35.46%,
110
- 0.88 38.24%,
111
- 0.9 41.52%,
112
- 0.92 45.55%,
113
- 0.93 47.96%,
114
- 0.95 54.02%,
115
- 0.96 58.05%,
116
- 0.97 63.24%,
117
- 0.98 70.55%,
118
- 0.99 83.05%,
119
- 1
120
- )
121
- var(--speed) both;
24
+ animation: grow var(--m3-timing-function-zeno) var(--speed) both;
122
25
  }
123
26
  @keyframes grow {
124
27
  0% {
@@ -85,7 +85,6 @@
85
85
 
86
86
  .m3-container {
87
87
  print-color-adjust: exact;
88
- -webkit-print-color-adjust: exact;
89
88
  }
90
89
 
91
90
  @media screen and (forced-colors: active) {
@@ -85,7 +85,6 @@
85
85
 
86
86
  .m3-container {
87
87
  print-color-adjust: exact;
88
- -webkit-print-color-adjust: exact;
89
88
  }
90
89
 
91
90
  @media screen and (forced-colors: active) {
@@ -85,7 +85,6 @@
85
85
 
86
86
  .m3-container {
87
87
  print-color-adjust: exact;
88
- -webkit-print-color-adjust: exact;
89
88
  }
90
89
 
91
90
  @media screen and (forced-colors: active) {
@@ -127,7 +127,6 @@
127
127
  block-size: var(--handle-height);
128
128
  min-inline-size: 10rem;
129
129
  print-color-adjust: exact;
130
- -webkit-print-color-adjust: exact;
131
130
 
132
131
  --functional-width: calc(100% - 2 * (0.25rem + 0.125rem));
133
132
  --handle-left: calc(50% + var(--functional-width) * var(--handle) - 0.125rem - 0.375rem);
@@ -381,6 +380,7 @@
381
380
 
382
381
  opacity: 0;
383
382
  pointer-events: none;
383
+ user-select: none;
384
384
  transition: opacity var(--m3-easing);
385
385
  z-index: 1;
386
386
  @media screen and (forced-colors: active) {
@@ -213,7 +213,6 @@
213
213
 
214
214
  .m3-container {
215
215
  print-color-adjust: exact;
216
- -webkit-print-color-adjust: exact;
217
216
  }
218
217
  @media screen and (forced-colors: active) {
219
218
  input:checked {
@@ -197,7 +197,6 @@
197
197
 
198
198
  .m3-container {
199
199
  print-color-adjust: exact;
200
- -webkit-print-color-adjust: exact;
201
200
  }
202
201
  @media screen and (forced-colors: active) {
203
202
  input {
@@ -37,14 +37,7 @@
37
37
  </script>
38
38
 
39
39
  <div class="m3-container" class:leading-icon={leadingIcon} class:error use:resize>
40
- <textarea
41
- class="focus-none"
42
- placeholder=" "
43
- bind:value
44
- {id}
45
- {disabled}
46
- {required}
47
- {...extra}
40
+ <textarea class="focus-none" placeholder=" " bind:value {id} {disabled} {required} {...extra}
48
41
  ></textarea>
49
42
  <label for={id}>{label}</label>
50
43
  <div class="layer"></div>
@@ -171,7 +164,6 @@
171
164
 
172
165
  .m3-container {
173
166
  print-color-adjust: exact;
174
- -webkit-print-color-adjust: exact;
175
167
  }
176
168
  @media screen and (forced-colors: active) {
177
169
  textarea {
@@ -190,6 +190,5 @@
190
190
 
191
191
  .m3-container {
192
192
  print-color-adjust: exact;
193
- -webkit-print-color-adjust: exact;
194
193
  }
195
194
  </style>
@@ -37,14 +37,7 @@
37
37
  </script>
38
38
 
39
39
  <div class="m3-container" class:leading-icon={leadingIcon} class:error use:resize>
40
- <textarea
41
- class="focus-none"
42
- placeholder=" "
43
- bind:value
44
- {id}
45
- {disabled}
46
- {required}
47
- {...extra}
40
+ <textarea class="focus-none" placeholder=" " bind:value {id} {disabled} {required} {...extra}
48
41
  ></textarea>
49
42
  <div class="layer"></div>
50
43
  <label for={id}>{label}</label>
@@ -165,6 +158,5 @@
165
158
 
166
159
  .m3-container {
167
160
  print-color-adjust: exact;
168
- -webkit-print-color-adjust: exact;
169
161
  }
170
162
  </style>
@@ -63,15 +63,15 @@
63
63
  circle.appendChild(expand);
64
64
 
65
65
  const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
66
- svg.style.cssText = `
67
- position: absolute;
68
- left: ${x - size / 2}px;
69
- top: ${y - size / 2}px;
70
- width: ${size}px;
71
- height: ${size}px;
72
- pointer-events: none;
73
- overflow: visible;
74
- `;
66
+ svg.style.cssText = [
67
+ "position: absolute",
68
+ `left: ${x - size / 2}px`,
69
+ `top: ${y - size / 2}px`,
70
+ `width: ${size}px`,
71
+ `height: ${size}px`,
72
+ "pointer-events: none",
73
+ "overflow: visible",
74
+ ].join(";");
75
75
  svg.appendChild(gradient);
76
76
  svg.appendChild(circle);
77
77
 
@@ -192,18 +192,20 @@
192
192
  transition: opacity var(--m3-easing-fast);
193
193
 
194
194
  &:not(
195
- :global(input:disabled + label) > .tint,
196
- :global(input:disabled + .layer-container) > .tint,
197
- :global(:disabled) > .tint
195
+ :global(input:disabled + label) > *,
196
+ :global(input:disabled + .layer-container) > *,
197
+ :global(:disabled) > *
198
198
  ) {
199
199
  @media (hover: hover) {
200
- &:is(:global(:hover) > .tint, :global(:active) > .tint) {
200
+ &:is(:global(:hover) > *, :global(:active) > *) {
201
201
  opacity: 0.08;
202
202
  }
203
203
  }
204
- &:is(:global(input:focus-visible + label) > .tint),
205
- &:is(:global(:focus-visible) > .tint),
206
- &:is(.ripple-container.broken + .tint):is(:global(:active) > .tint) {
204
+ &:is(
205
+ :global(input:focus-visible + label) > *,
206
+ :global(:focus-visible) > *,
207
+ :global(:active) > .ripple-container.broken + *
208
+ ) {
207
209
  opacity: 0.12;
208
210
  }
209
211
  }
@@ -1,8 +1,10 @@
1
1
  @function --translucent(--color, --opacity) {
2
2
  result: oklab(from var(--color) l a b / var(--opacity));
3
3
  }
4
+ /* DEPRECATED: This default --m3-density function will be removed in a future version.
5
+ For new themes, pick which option you actually want. */
4
6
  @function --m3-density(--size) {
5
- result: calc(var(--size) + (var(--m3v-density) * 0.25rem));
7
+ result: calc(var(--size) + (var(--m3v-density, 0) * 0.25rem));
6
8
  }
7
9
 
8
10
  @layer tokens {
@@ -84,6 +86,38 @@
84
86
  );
85
87
  --m3-timing-function-emphasized-accel: cubic-bezier(0.3, 0, 0.8, 0.15);
86
88
  --m3-timing-function-emphasized-decel: cubic-bezier(0.05, 0.7, 0.1, 1);
89
+
90
+ --m3-timing-function-zeno: linear(
91
+ 0,
92
+ 0.08 1.5%,
93
+ 0.15 2.93%,
94
+ 0.22 4.48%,
95
+ 0.29 6.18%,
96
+ 0.35 7.77%,
97
+ 0.41 9.52%,
98
+ 0.47 11.45%,
99
+ 0.52 13.24%,
100
+ 0.57 15.22%,
101
+ 0.61 16.98%,
102
+ 0.65 18.93%,
103
+ 0.69 21.12%,
104
+ 0.73 23.61%,
105
+ 0.76 25.74%,
106
+ 0.79 28.14%,
107
+ 0.82 30.92%,
108
+ 0.84 33.05%,
109
+ 0.86 35.46%,
110
+ 0.88 38.24%,
111
+ 0.9 41.52%,
112
+ 0.92 45.55%,
113
+ 0.93 47.96%,
114
+ 0.95 54.02%,
115
+ 0.96 58.05%,
116
+ 0.97 63.24%,
117
+ 0.98 70.55%,
118
+ 0.99 83.05%,
119
+ 1
120
+ );
87
121
  }
88
122
  }
89
123
  /* Not tokens because they may be dynamically get/set and aren't generally constant */
@@ -92,11 +126,6 @@
92
126
  inherits: true;
93
127
  initial-value: 0;
94
128
  }
95
- @property --m3v-density {
96
- syntax: "<number>";
97
- inherits: true;
98
- initial-value: 0;
99
- }
100
129
  :root {
101
130
  --m3v-background: var(--m3c-surface);
102
131
  }
@@ -346,3 +375,67 @@ const optimizedSmallResult = createCSSEaseOptimized(testInput, 0.01);
346
375
  console.log("Optimized result (relaxed threshold 0.01):");
347
376
  console.log(optimizedSmallResult);
348
377
  */
378
+ /* Zeno timing function derived from this code:
379
+ // 1) define the original mapping f(y)=time-%, capped at 100% for y=1
380
+ const whenReached = (y) => Math.log(1 - y) / Math.log(0.5);
381
+ const makePoints = () => {
382
+ const pts = [];
383
+ for (let i = 0; i < 100; i++) {
384
+ const v = i / 100;
385
+ const t = (whenReached(v) * 100) / 8;
386
+ pts.push([v, t]);
387
+ }
388
+ // add the final point (1, 100)
389
+ pts.push([1, 100]);
390
+ return pts;
391
+ };
392
+
393
+ // 2) helper: compute perpendicular distance from pt to line (p0→p1)
394
+ const perpDist = (pt, p0, p1) => {
395
+ const [x, y] = pt;
396
+ const [x1, y1] = p0;
397
+ const [x2, y2] = p1;
398
+ const num = Math.abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1);
399
+ const den = Math.hypot(y2 - y1, x2 - x1);
400
+ return den === 0 ? 0 : num / den;
401
+ };
402
+
403
+ // 3) RDP (recursive)
404
+ function rdp(points, eps) {
405
+ if (points.length < 3) return points;
406
+ let maxD = 0,
407
+ idx = 0;
408
+ for (let i = 1; i < points.length - 1; i++) {
409
+ const d = perpDist(points[i], points[0], points[points.length - 1]);
410
+ if (d > maxD) {
411
+ maxD = d;
412
+ idx = i;
413
+ }
414
+ }
415
+ if (maxD > eps) {
416
+ const left = rdp(points.slice(0, idx + 1), eps);
417
+ const right = rdp(points.slice(idx), eps);
418
+ return left.slice(0, -1).concat(right);
419
+ }
420
+ return [points[0], points[points.length - 1]];
421
+ }
422
+
423
+ // 4) round x to 2 decimals (keep trailing zeros); round y to 2 decimals (cap tiny negatives to 0)
424
+ const fmt = (v, t) => {
425
+ const xv = v.toFixed(2);
426
+ let tv = Math.round(t * 100) / 100; // round to 2 decimals
427
+ if (Math.abs(tv) < 1e-8) tv = 0; // avoid "-0.00"
428
+ return `${xv} ${tv.toFixed(2)}%`;
429
+ };
430
+
431
+ // 5) put it all together
432
+ function buildCompressedLinear(tolerance) {
433
+ const raw = makePoints();
434
+ const reduced = rdp(raw, tolerance);
435
+ return `linear(${reduced.map(([v, t]) => fmt(v, t)).join(", ")})`;
436
+ }
437
+
438
+ // 6) example result
439
+ const compressed = buildCompressedLinear(0.001);
440
+ console.log(compressed);
441
+ */
@@ -60,6 +60,7 @@
60
60
  }
61
61
 
62
62
  @mixin --cmlxi-vertical {
63
+ flex-direction: column;
63
64
  .content {
64
65
  flex-direction: column;
65
66
  text-align: center;
@@ -132,6 +133,7 @@
132
133
  &:is(button) {
133
134
  background: none;
134
135
  border: none;
136
+ padding: 0;
135
137
  cursor: pointer;
136
138
  }
137
139
 
@@ -146,7 +146,6 @@
146
146
 
147
147
  .bar {
148
148
  print-color-adjust: exact;
149
- -webkit-print-color-adjust: exact;
150
149
  }
151
150
  @media screen and (forced-colors: active) {
152
151
  .bar {
@@ -124,7 +124,6 @@
124
124
 
125
125
  .bar {
126
126
  print-color-adjust: exact;
127
- -webkit-print-color-adjust: exact;
128
127
  }
129
128
  @media screen and (forced-colors: active) {
130
129
  .bar {
@@ -217,7 +217,6 @@
217
217
 
218
218
  .bar {
219
219
  print-color-adjust: exact;
220
- -webkit-print-color-adjust: exact;
221
220
  }
222
221
  @media screen and (forced-colors: active) {
223
222
  .bar {
@@ -185,7 +185,6 @@
185
185
 
186
186
  .bar {
187
187
  print-color-adjust: exact;
188
- -webkit-print-color-adjust: exact;
189
188
  }
190
189
  @media screen and (forced-colors: active) {
191
190
  .bar {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "m3-svelte",
3
- "version": "6.0.1",
3
+ "version": "6.0.2",
4
4
  "license": "Apache-2.0 OR GPL-3.0-only",
5
5
  "repository": "KTibow/m3-svelte",
6
6
  "author": {
@@ -44,22 +44,24 @@
44
44
  "@sveltejs/package": "^2.5.7",
45
45
  "@sveltejs/vite-plugin-svelte": "^6.2.1",
46
46
  "@types/flubber": "^0.4.0",
47
+ "@types/node": "^24.10.1",
47
48
  "eslint": "^9.39.1",
48
49
  "eslint-config-prettier": "^10.1.8",
49
50
  "eslint-plugin-svelte": "^3.13.1",
50
- "fast-glob": "^3.3.3",
51
51
  "flubber": "^0.4.2",
52
52
  "globals": "^16.5.0",
53
+ "m3-svelte": "link:",
53
54
  "prettier": "^3.7.4",
54
55
  "prettier-plugin-svelte": "^3.4.0",
55
56
  "publint": "^0.3.15",
56
57
  "svelte": "^5.45.6",
57
58
  "svelte-check": "^4.3.4",
58
59
  "svelte-highlight": "^7.9.0",
60
+ "tinyglobby": "^0.2.15",
59
61
  "typescript": "^5.9.3",
60
- "typescript-eslint": "^8.48.1",
61
- "vite": "^7.2.6",
62
- "vite-plugin-functions-mixins": "^0.1.1",
62
+ "typescript-eslint": "^8.49.0",
63
+ "vite": "^7.2.7",
64
+ "vite-plugin-functions-mixins": "^0.4.0",
63
65
  "vite-plugin-token-shaker": "^0.0.3"
64
66
  },
65
67
  "peerDependencies": {