noph-ui 0.34.3 → 0.35.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.
Files changed (44) hide show
  1. package/dist/badge/Badge.svelte +4 -2
  2. package/dist/badge/Badge.svelte.d.ts +1 -0
  3. package/dist/button/Button.svelte +3 -5
  4. package/dist/button/IconButton.svelte +7 -7
  5. package/dist/button/SegmentedButton.svelte +22 -25
  6. package/dist/card/Card.svelte +11 -35
  7. package/dist/checkbox/Checkbox.svelte +68 -32
  8. package/dist/checkbox/types.d.ts +1 -0
  9. package/dist/chip/ChipSet.svelte +10 -2
  10. package/dist/chip/FilterChip.svelte +48 -52
  11. package/dist/chip/InputChip.svelte +32 -31
  12. package/dist/chip/InputChip.svelte.d.ts +1 -1
  13. package/dist/chip/types.d.ts +3 -1
  14. package/dist/dialog/Dialog.svelte +53 -10
  15. package/dist/index.d.ts +1 -0
  16. package/dist/index.js +1 -0
  17. package/dist/keyboard-nav.js +12 -4
  18. package/dist/list/Item.svelte +39 -66
  19. package/dist/menu/Menu.svelte +10 -1
  20. package/dist/menu/MenuItem.svelte +4 -4
  21. package/dist/navigation-drawer/NavigationDrawer.svelte +35 -1
  22. package/dist/navigation-rail/NavigationRailItem.svelte +2 -2
  23. package/dist/progress/CircularProgress.svelte +214 -117
  24. package/dist/progress/LinearProgress.svelte +382 -102
  25. package/dist/progress/types.d.ts +2 -0
  26. package/dist/ripple/Ripple.svelte +6 -7
  27. package/dist/select/Select.svelte +41 -20
  28. package/dist/slider/Slider.svelte +555 -0
  29. package/dist/slider/Slider.svelte.d.ts +4 -0
  30. package/dist/slider/index.d.ts +1 -0
  31. package/dist/slider/index.js +1 -0
  32. package/dist/slider/types.d.ts +23 -0
  33. package/dist/slider/types.js +1 -0
  34. package/dist/snackbar/Snackbar.svelte +21 -10
  35. package/dist/switch/Switch.svelte +1 -1
  36. package/dist/tabs/Tab.svelte +18 -16
  37. package/dist/tabs/Tabs.svelte +4 -2
  38. package/dist/tabs/types.d.ts +2 -0
  39. package/dist/text-field/TextField.svelte +3 -1
  40. package/dist/themes/defaultTheme.css +3 -9
  41. package/dist/tooltip/Tooltip.svelte +53 -10
  42. package/dist/types.d.ts +1 -0
  43. package/dist/types.js +1 -0
  44. package/package.json +11 -11
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { MediaQuery } from 'svelte/reactivity'
2
3
  import type { LinearProgressProps } from './types.ts'
3
4
 
4
5
  let {
@@ -7,45 +8,201 @@
7
8
  indeterminate = false,
8
9
  fourColor = false,
9
10
  buffer = 0,
11
+ wavy = false,
12
+ track = true,
10
13
  ...attributes
11
14
  }: LinearProgressProps = $props()
12
15
 
16
+ const WAVE_AMPLITUDE = 3
17
+ const WAVE_THICKNESS = 4
18
+ const DETERMINATE_WAVELENGTH = 40
19
+ const INDETERMINATE_WAVELENGTH = 20
20
+
21
+ const reducedMotion = new MediaQuery('(prefers-reduced-motion: reduce)', false)
22
+ let wave = $derived(wavy && !reducedMotion.current)
23
+
24
+ let wavelength = $derived(indeterminate ? INDETERMINATE_WAVELENGTH : DETERMINATE_WAVELENGTH)
25
+ let amplitude = $derived(
26
+ !wave ? 0 : indeterminate || (value / max > 0.1 && value / max < 0.95) ? 1 : 0,
27
+ )
28
+
29
+ const cubicBezier = (x1: number, y1: number, x2: number, y2: number) => {
30
+ const A = (a: number, b: number) => 1 - 3 * b + 3 * a
31
+ const B = (a: number, b: number) => 3 * b - 6 * a
32
+ const bez = (t: number, a: number, b: number) => ((A(a, b) * t + B(a, b)) * t + 3 * a) * t
33
+ const slope = (t: number) => (3 * A(x1, x2) * t + 2 * B(x1, x2)) * t + 3 * x1
34
+ return (x: number) => {
35
+ if (x <= 0) return 0
36
+ if (x >= 1) return 1
37
+ let t = x
38
+ for (let i = 0; i < 8; i++) {
39
+ const err = bez(t, x1, x2) - x
40
+ if (Math.abs(err) < 1e-6) break
41
+ const d = slope(t)
42
+ if (Math.abs(d) < 1e-6) break
43
+ t -= err / d
44
+ }
45
+ return bez(t, y1, y2)
46
+ }
47
+ }
48
+ const accelerate = cubicBezier(0.3, 0, 0.8, 0.15)
49
+ const CYCLE = 1750
50
+ const RAMPS = [
51
+ [0, 1000],
52
+ [250, 1000],
53
+ [650, 850],
54
+ [900, 850],
55
+ ] as const
56
+ const rampAt = (t: number, delay: number, duration: number) =>
57
+ t <= delay ? 0 : t >= delay + duration ? 1 : accelerate((t - delay) / duration)
58
+
59
+ const WAVE_STEPS = 12
60
+ let containerWidth = $state(0)
61
+ let wavePathA = $state<SVGPathElement>()
62
+ let wavePathB = $state<SVGPathElement>()
63
+ let renderedAmplitude = 0
64
+
65
+ const buildWave = (width: number, len: number, amp: number, phase: number) => {
66
+ const height = WAVE_THICKNESS + 2 * WAVE_AMPLITUDE
67
+ const mid = height / 2
68
+ const step = len / WAVE_STEPS
69
+ const xs: number[] = []
70
+ const ys: number[] = []
71
+ for (let x = 0; x <= width + step; x += step) {
72
+ xs.push(x)
73
+ ys.push(mid - amp * WAVE_AMPLITUDE * Math.cos(((x + phase) / len) * Math.PI * 2))
74
+ }
75
+ let d = `M${xs[0].toFixed(2)},${ys[0].toFixed(2)}`
76
+ const cum = [0]
77
+ for (let i = 1; i < xs.length; i++) {
78
+ d += `L${xs[i].toFixed(2)},${ys[i].toFixed(2)}`
79
+ cum.push(cum[i - 1] + Math.hypot(xs[i] - xs[i - 1], ys[i] - ys[i - 1]))
80
+ }
81
+ return { d, xs, cum, step, total: cum[cum.length - 1] }
82
+ }
83
+
84
+ type Wave = ReturnType<typeof buildWave>
85
+ const lengthAt = (wave: Wave, x: number) => {
86
+ if (x <= 0) return 0
87
+ const i = Math.min(wave.xs.length - 2, Math.max(0, Math.floor(x / wave.step)))
88
+ const span = wave.xs[i + 1] - wave.xs[i]
89
+ const f = span > 0 ? Math.min(1, Math.max(0, (x - wave.xs[i]) / span)) : 0
90
+ return wave.cum[i] + (wave.cum[i + 1] - wave.cum[i]) * f
91
+ }
92
+
93
+ const trim = (path: SVGPathElement | undefined, wave: Wave, x0: number, x1: number) => {
94
+ if (!path) return
95
+ const cap = WAVE_THICKNESS / 2
96
+ const from = x0 + cap
97
+ const to = x1 - cap
98
+ if (to <= from) {
99
+ path.style.visibility = 'hidden'
100
+ return
101
+ }
102
+ path.style.visibility = ''
103
+ const a = lengthAt(wave, from)
104
+ const b = lengthAt(wave, to)
105
+ path.setAttribute('d', wave.d)
106
+ path.style.strokeDasharray = `${b - a} ${wave.total}`
107
+ path.style.strokeDashoffset = `${-a}`
108
+ }
109
+
110
+ $effect(() => {
111
+ if (!wave || !containerWidth) return
112
+ const len = wavelength
113
+ const width = containerWidth
114
+ const host = wavePathA?.closest('.progress') as HTMLElement | null
115
+ let raf = 0
116
+ let last = 0
117
+ const frame = (now: number) => {
118
+ raf = requestAnimationFrame(frame)
119
+ const dt = last ? Math.min(64, now - last) : 16
120
+ last = now
121
+ const phase = ((now / 1000) % 1) * len
122
+ renderedAmplitude += (amplitude - renderedAmplitude) * Math.min(1, dt / 500)
123
+ const wave = buildWave(width, len, renderedAmplitude, phase)
124
+ if (indeterminate) {
125
+ const t = now % CYCLE
126
+ const [h1, t1, h2, t2] = RAMPS.map(([d, u]) => rampAt(t, d, u))
127
+ host?.style.setProperty('--np-lp-h1', `${h1 * 100}%`)
128
+ host?.style.setProperty('--np-lp-t1', `${t1 * 100}%`)
129
+ host?.style.setProperty('--np-lp-h2', `${h2 * 100}%`)
130
+ host?.style.setProperty('--np-lp-t2', `${t2 * 100}%`)
131
+ trim(wavePathA, wave, t1 * width, h1 * width)
132
+ trim(wavePathB, wave, t2 * width, h2 * width)
133
+ } else {
134
+ trim(wavePathA, wave, 0, (percent / 100) * width)
135
+ }
136
+ }
137
+ raf = requestAnimationFrame(frame)
138
+ return () => cancelAnimationFrame(raf)
139
+ })
140
+
13
141
  let bufferValue = $derived(buffer ?? 0)
14
142
  let hasBuffer = $derived(bufferValue > 0)
15
143
 
16
- let dotStyles = $derived(
17
- `transform: scaleX(${(indeterminate || !hasBuffer ? 1 : bufferValue / max) * 100}%)`,
144
+ const clamp = (n: number) => Math.min(100, Math.max(0, n))
145
+
146
+ let percent = $derived(indeterminate ? 0 : clamp((value / max) * 100))
147
+ let bufferPercent = $derived(indeterminate || !hasBuffer ? 100 : clamp((bufferValue / max) * 100))
148
+ let gapOn = $derived(percent > 0 ? 1 : 0)
149
+
150
+ let trackStyles = $derived(
151
+ `--_percent:${percent}%;--_buffer-percent:${bufferPercent}%;--_gap-on:${gapOn}`,
18
152
  )
19
153
 
20
154
  let hideDots = $derived(indeterminate || !hasBuffer || bufferValue >= max || value >= max)
21
155
  </script>
22
156
 
23
- <div class="np-container">
157
+ <div class={['np-container', wave && 'wavy']} bind:clientWidth={containerWidth}>
24
158
  <div
25
159
  {...attributes}
26
- class={['progress', indeterminate && 'indeterminate', fourColor && 'four-color']}
160
+ style={trackStyles}
161
+ class={[
162
+ 'progress',
163
+ indeterminate && 'indeterminate',
164
+ fourColor && 'four-color',
165
+ wave && 'wavy',
166
+ ]}
27
167
  role="progressbar"
28
168
  aria-valuemin="0"
29
169
  aria-valuemax={max}
30
170
  aria-valuenow={indeterminate ? undefined : value}
31
171
  >
32
- <div class="dots" hidden={hideDots}></div>
33
- <div class="inactive-track" style={dotStyles}></div>
34
- <div
35
- class="bar primary-bar"
36
- style={`transform: scaleX(${(indeterminate ? 1 : value / max) * 100}%)`}
37
- >
38
- <div class="bar-inner"></div>
39
- </div>
40
- <div class="bar secondary-bar">
41
- <div class="bar-inner"></div>
42
- </div>
172
+ {#if track}
173
+ <div class="dots" hidden={hideDots}></div>
174
+ {#if indeterminate}
175
+ <div class="np-lp-track ahead"></div>
176
+ <div class="np-lp-track between"></div>
177
+ <div class="np-lp-track behind"></div>
178
+ {:else}
179
+ <div class="inactive-track"></div>
180
+ {/if}
181
+ {/if}
182
+ {#if wave}
183
+ <svg class="np-lp-wave" aria-hidden="true">
184
+ <path bind:this={wavePathA} class="np-lp-wave-line"></path>
185
+ {#if indeterminate}
186
+ <path bind:this={wavePathB} class="np-lp-wave-line"></path>
187
+ {/if}
188
+ </svg>
189
+ {:else}
190
+ <div class="bar primary-bar">
191
+ <div class="bar-inner"></div>
192
+ </div>
193
+ <div class="bar secondary-bar">
194
+ <div class="bar-inner"></div>
195
+ </div>
196
+ {/if}
197
+ {#if !indeterminate}
198
+ <div class="stop-indicator"></div>
199
+ {/if}
43
200
  </div>
44
201
  </div>
45
202
 
46
203
  <style>
47
204
  .np-container {
48
- border-radius: var(--np-linear-progress-track-shape, 0);
205
+ border-radius: var(--np-linear-progress-track-shape, var(--np-shape-corner-full));
49
206
  display: flex;
50
207
  position: relative;
51
208
  min-width: 80px;
@@ -57,12 +214,12 @@
57
214
  .dots,
58
215
  .inactive-track,
59
216
  .bar,
60
- .bar-inner {
217
+ .bar-inner,
218
+ .stop-indicator {
61
219
  position: absolute;
62
220
  }
63
221
 
64
222
  .progress {
65
- direction: ltr;
66
223
  inset: 0;
67
224
  border-radius: inherit;
68
225
  overflow: hidden;
@@ -70,12 +227,25 @@
70
227
  align-items: center;
71
228
  }
72
229
 
230
+ .progress:dir(rtl) {
231
+ transform: scaleX(-1);
232
+ }
233
+
234
+ .stop-indicator {
235
+ right: 0;
236
+ width: var(--np-linear-progress-active-indicator-height, 0.25rem);
237
+ height: var(--np-linear-progress-active-indicator-height, 0.25rem);
238
+ border-radius: var(--np-shape-corner-full);
239
+ background: var(--np-linear-progress-active-indicator-color, var(--np-color-primary));
240
+ }
241
+
73
242
  .bar {
74
243
  animation: none;
244
+ left: 0;
75
245
  width: 100%;
76
246
  height: var(--np-linear-progress-active-indicator-height, 0.25rem);
77
247
  transform-origin: left center;
78
- transition: transform 250ms cubic-bezier(0.4, 0, 0.6, 1);
248
+ transition: transform var(--np-motion-expressive-default-effects);
79
249
  }
80
250
 
81
251
  .secondary-bar {
@@ -88,21 +258,35 @@
88
258
  background: var(--np-linear-progress-active-indicator-color, var(--np-color-primary));
89
259
  }
90
260
 
261
+ .progress:not(.indeterminate) .primary-bar {
262
+ width: var(--_percent, 0%);
263
+ transform: none;
264
+ transition: width var(--np-motion-expressive-default-effects);
265
+ }
266
+
267
+ .progress:not(.indeterminate) .bar-inner {
268
+ border-radius: var(--np-linear-progress-track-shape, var(--np-shape-corner-full));
269
+ }
270
+
91
271
  .inactive-track {
92
- background: var(--np-linear-progress-track-color, var(--np-color-surface-container-highest));
93
- inset: 0;
94
- transition: transform 250ms cubic-bezier(0.4, 0, 0.6, 1);
95
- transform-origin: left center;
272
+ background: var(--np-linear-progress-track-color, var(--np-color-secondary-container));
273
+ inset-block: 0;
274
+ left: min(
275
+ calc(var(--_percent, 0%) + var(--np-linear-progress-track-gap, 0.25rem) * var(--_gap-on, 0)),
276
+ 100%
277
+ );
278
+ right: calc(100% - var(--_buffer-percent, 100%));
279
+ border-radius: var(--np-linear-progress-track-shape, var(--np-shape-corner-full));
280
+ transition:
281
+ left var(--np-motion-expressive-default-effects),
282
+ right var(--np-motion-expressive-default-effects);
96
283
  }
97
284
 
98
285
  .dots {
99
286
  inset: 0;
100
287
  animation: linear infinite 250ms;
101
288
  animation-name: buffering;
102
- background-color: var(
103
- --np-linear-progress-track-color,
104
- var(--np-color-surface-container-highest)
105
- );
289
+ background-color: var(--np-linear-progress-track-color, var(--np-color-secondary-container));
106
290
  background-repeat: repeat-x;
107
291
  -webkit-mask-image: url("data:image/svg+xml,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5 2' preserveAspectRatio='xMinYMin slice'><circle cx='1' cy='1' r='1'/></svg>");
108
292
  mask-image: url("data:image/svg+xml,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5 2' preserveAspectRatio='xMinYMin slice'><circle cx='1' cy='1' r='1'/></svg>");
@@ -115,134 +299,230 @@
115
299
 
116
300
  .indeterminate .bar {
117
301
  transition: none;
118
- }
119
-
120
- .indeterminate .primary-bar {
121
- inset-inline-start: -145.167%;
302
+ left: 0;
303
+ transform: none;
304
+ animation: none;
122
305
  }
123
306
 
124
307
  .indeterminate .secondary-bar {
125
- inset-inline-start: -54.8889%;
126
308
  display: block;
127
309
  }
128
310
 
129
- .indeterminate .primary-bar {
130
- animation: linear infinite 2s;
131
- animation-name: primary-indeterminate-translate;
311
+ @property --np-lp-h1 {
312
+ syntax: '<percentage>';
313
+ inherits: true;
314
+ initial-value: 0%;
315
+ }
316
+ @property --np-lp-t1 {
317
+ syntax: '<percentage>';
318
+ inherits: true;
319
+ initial-value: 0%;
320
+ }
321
+ @property --np-lp-h2 {
322
+ syntax: '<percentage>';
323
+ inherits: true;
324
+ initial-value: 0%;
325
+ }
326
+ @property --np-lp-t2 {
327
+ syntax: '<percentage>';
328
+ inherits: true;
329
+ initial-value: 0%;
330
+ }
331
+
332
+ .progress.indeterminate {
333
+ animation:
334
+ np-lp-h1 1750ms linear infinite,
335
+ np-lp-t1 1750ms linear infinite,
336
+ np-lp-h2 1750ms linear infinite,
337
+ np-lp-t2 1750ms linear infinite;
338
+ }
339
+
340
+ .indeterminate .bar-inner {
341
+ inset-block: 0;
342
+ transform: none;
343
+ border-radius: var(--np-linear-progress-track-shape, var(--np-shape-corner-full));
132
344
  }
133
345
 
134
346
  .indeterminate .primary-bar > .bar-inner {
135
- animation: linear infinite 2s primary-indeterminate-scale;
347
+ left: var(--np-lp-t1);
348
+ right: calc(100% - var(--np-lp-h1));
136
349
  }
137
350
 
138
- .indeterminate.four-color .primary-bar > .bar-inner {
139
- animation-name: primary-indeterminate-scale, four-color;
140
- animation-duration: 2s, calc(2s * 2);
351
+ .indeterminate .secondary-bar > .bar-inner {
352
+ left: var(--np-lp-t2);
353
+ right: calc(100% - var(--np-lp-h2));
141
354
  }
142
355
 
143
- .indeterminate .secondary-bar {
144
- animation: linear infinite 2s;
145
- animation-name: secondary-indeterminate-translate;
356
+ .indeterminate.four-color .bar-inner {
357
+ animation: four-color calc(1750ms * 4) linear infinite;
146
358
  }
147
359
 
148
- .indeterminate .secondary-bar > .bar-inner {
149
- animation: linear infinite 2s secondary-indeterminate-scale;
360
+ .np-lp-track {
361
+ position: absolute;
362
+ inset-block: 0;
363
+ background: var(--np-linear-progress-track-color, var(--np-color-secondary-container));
364
+ border-radius: var(--np-linear-progress-track-shape, var(--np-shape-corner-full));
365
+ }
366
+
367
+ .np-lp-track.ahead {
368
+ left: min(calc(var(--np-lp-h1) + var(--np-linear-progress-track-gap, 0.25rem)), 100%);
369
+ right: 0;
150
370
  }
151
371
 
152
- .indeterminate.four-color .secondary-bar > .bar-inner {
153
- animation-name: secondary-indeterminate-scale, four-color;
154
- animation-duration: 2s, calc(2s * 2);
372
+ .np-lp-track.between {
373
+ left: min(calc(var(--np-lp-h2) + var(--np-linear-progress-track-gap, 0.25rem)), 100%);
374
+ right: calc(
375
+ 100% - max(calc(var(--np-lp-t1) - var(--np-linear-progress-track-gap, 0.25rem)), 0%)
376
+ );
155
377
  }
156
378
 
157
- :host(:dir(rtl)) {
158
- transform: scale(-1);
379
+ .np-lp-track.behind {
380
+ left: 0;
381
+ right: calc(
382
+ 100% - max(calc(var(--np-lp-t2) - var(--np-linear-progress-track-gap, 0.25rem)), 0%)
383
+ );
159
384
  }
160
385
 
161
- @keyframes primary-indeterminate-scale {
386
+ @keyframes np-lp-h1 {
162
387
  0% {
163
- transform: scaleX(0.08);
388
+ --np-lp-h1: 0%;
389
+ animation-timing-function: linear;
164
390
  }
165
-
166
- 36.65% {
167
- animation-timing-function: cubic-bezier(0.334731, 0.12482, 0.785844, 1);
168
- transform: scaleX(0.08);
391
+ 0% {
392
+ --np-lp-h1: 0%;
393
+ animation-timing-function: cubic-bezier(0.3, 0, 0.8, 0.15);
169
394
  }
170
-
171
- 69.15% {
172
- animation-timing-function: cubic-bezier(0.06, 0.11, 0.6, 1);
173
- transform: scaleX(0.661479);
395
+ 57.143% {
396
+ --np-lp-h1: 100%;
397
+ animation-timing-function: linear;
174
398
  }
175
-
176
399
  100% {
177
- transform: scaleX(0.08);
400
+ --np-lp-h1: 100%;
178
401
  }
179
402
  }
180
403
 
181
- @keyframes secondary-indeterminate-scale {
404
+ @keyframes np-lp-t1 {
182
405
  0% {
183
- animation-timing-function: cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);
184
- transform: scaleX(0.08);
406
+ --np-lp-t1: 0%;
407
+ animation-timing-function: linear;
185
408
  }
186
-
187
- 19.15% {
188
- animation-timing-function: cubic-bezier(0.152313, 0.196432, 0.648374, 1.00432);
189
- transform: scaleX(0.457104);
409
+ 14.286% {
410
+ --np-lp-t1: 0%;
411
+ animation-timing-function: cubic-bezier(0.3, 0, 0.8, 0.15);
190
412
  }
191
-
192
- 44.15% {
193
- animation-timing-function: cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);
194
- transform: scaleX(0.72796);
413
+ 71.429% {
414
+ --np-lp-t1: 100%;
415
+ animation-timing-function: linear;
195
416
  }
196
-
197
417
  100% {
198
- transform: scaleX(0.08);
418
+ --np-lp-t1: 100%;
199
419
  }
200
420
  }
201
421
 
202
- @keyframes buffering {
422
+ @keyframes np-lp-h2 {
203
423
  0% {
204
- transform: translateX(calc(calc(var(--np-linear-progress-track-height, 0.25rem) / 2) * 5));
424
+ --np-lp-h2: 0%;
425
+ animation-timing-function: linear;
426
+ }
427
+ 37.143% {
428
+ --np-lp-h2: 0%;
429
+ animation-timing-function: cubic-bezier(0.3, 0, 0.8, 0.15);
430
+ }
431
+ 85.714% {
432
+ --np-lp-h2: 100%;
433
+ animation-timing-function: linear;
434
+ }
435
+ 100% {
436
+ --np-lp-h2: 100%;
205
437
  }
206
438
  }
207
439
 
208
- @keyframes primary-indeterminate-translate {
440
+ @keyframes np-lp-t2 {
209
441
  0% {
210
- transform: translateX(0px);
442
+ --np-lp-t2: 0%;
443
+ animation-timing-function: linear;
211
444
  }
212
-
213
- 20% {
214
- animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819);
215
- transform: translateX(0px);
445
+ 51.429% {
446
+ --np-lp-t2: 0%;
447
+ animation-timing-function: cubic-bezier(0.3, 0, 0.8, 0.15);
216
448
  }
217
-
218
- 59.15% {
219
- animation-timing-function: cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);
220
- transform: translateX(83.6714%);
449
+ 100% {
450
+ --np-lp-t2: 100%;
451
+ animation-timing-function: linear;
221
452
  }
222
-
223
453
  100% {
224
- transform: translateX(200.611%);
454
+ --np-lp-t2: 100%;
225
455
  }
226
456
  }
227
457
 
228
- @keyframes secondary-indeterminate-translate {
229
- 0% {
230
- animation-timing-function: cubic-bezier(0.15, 0, 0.515058, 0.409685);
231
- transform: translateX(0px);
232
- }
458
+ .np-container.wavy {
459
+ height: var(--np-linear-progress-wave-height, 0.625rem);
460
+ border-radius: 0;
461
+ }
233
462
 
234
- 25% {
235
- animation-timing-function: cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);
236
- transform: translateX(37.6519%);
237
- }
463
+ .wavy .inactive-track,
464
+ .wavy .np-lp-track,
465
+ .wavy .dots {
466
+ inset-block: auto;
467
+ top: 50%;
468
+ height: var(--np-linear-progress-track-height, 0.25rem);
469
+ transform: translateY(-50%);
470
+ }
238
471
 
239
- 48.35% {
240
- animation-timing-function: cubic-bezier(0.4, 0.627035, 0.6, 0.902026);
241
- transform: translateX(84.3862%);
242
- }
472
+ .wavy .stop-indicator {
473
+ top: 50%;
474
+ transform: translateY(-50%);
475
+ }
243
476
 
477
+ .np-lp-wave {
478
+ position: absolute;
479
+ inset: 0;
480
+ width: 100%;
481
+ height: 100%;
482
+ overflow: visible;
483
+ }
484
+
485
+ .np-lp-wave-line {
486
+ fill: none;
487
+ stroke: var(--np-linear-progress-active-indicator-color, var(--np-color-primary));
488
+ stroke-width: var(--np-linear-progress-active-indicator-height, 0.25rem);
489
+ stroke-linecap: round;
490
+ stroke-linejoin: round;
491
+ }
492
+
493
+ .progress.wavy.indeterminate {
494
+ animation: none;
495
+ }
496
+
497
+ .wavy.four-color .np-lp-wave-line {
498
+ animation: four-color-stroke calc(1750ms * 4) linear infinite;
499
+ }
500
+
501
+ @keyframes four-color-stroke {
502
+ 0%,
503
+ 15% {
504
+ stroke: var(--np-color-primary);
505
+ }
506
+ 25%,
507
+ 40% {
508
+ stroke: var(--np-color-primary-container);
509
+ }
510
+ 50%,
511
+ 65% {
512
+ stroke: var(--np-color-tertiary);
513
+ }
514
+ 75%,
515
+ 90% {
516
+ stroke: var(--np-color-tertiary-container);
517
+ }
244
518
  100% {
245
- transform: translateX(160.278%);
519
+ stroke: var(--np-color-primary);
520
+ }
521
+ }
522
+
523
+ @keyframes buffering {
524
+ 0% {
525
+ transform: translateX(calc(calc(var(--np-linear-progress-track-height, 0.25rem) / 2) * 5));
246
526
  }
247
527
  }
248
528
 
@@ -3,6 +3,8 @@ export interface CircularProgressProps {
3
3
  max?: number;
4
4
  indeterminate?: boolean;
5
5
  fourColor?: boolean;
6
+ track?: boolean;
7
+ wavy?: boolean;
6
8
  'aria-label'?: string | undefined | null;
7
9
  }
8
10
  export interface LinearProgressProps extends CircularProgressProps {
@@ -280,12 +280,10 @@
280
280
 
281
281
  $effect(() => {
282
282
  const forcedColors = window?.matchMedia('(forced-colors: active)')
283
- if (!forcedColors.matches && forElement) {
284
- return addEvents(forElement)
285
- } else {
286
- if (!forcedColors.matches && element) {
287
- return addEvents(element)
288
- }
283
+ if (forcedColors.matches) return
284
+ const target = forElement ?? element?.parentElement
285
+ if (target) {
286
+ return addEvents(target)
289
287
  }
290
288
  })
291
289
  </script>
@@ -314,6 +312,7 @@
314
312
  position: absolute;
315
313
  inset: 0;
316
314
  overflow: hidden;
315
+ pointer-events: none;
317
316
  }
318
317
 
319
318
  .np-ripple-surface {
@@ -352,7 +351,7 @@
352
351
  }
353
352
 
354
353
  .np-ripple-pressed::after {
355
- opacity: var(--np-ripple-pressed-opacity, 0.12);
354
+ opacity: var(--np-ripple-pressed-opacity, 0.1);
356
355
  transition-duration: 105ms;
357
356
  }
358
357
  </style>