@rcarls/rc-progress 0.0.0-next-20260921045401

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/CHANGELOG.md ADDED
@@ -0,0 +1,82 @@
1
+ # @rcarls/rc-progress
2
+
3
+ ## 0.0.0-next-20260921045401
4
+
5
+ ### Minor Changes
6
+
7
+ - 6e548d9: Several components handle `prefers-reduced-motion: reduce` in their own
8
+ shadow styles, outside a theme's reach, and refine it the same way the theme
9
+ layer already does: spatial motion (`translate`, `scale`, `transform`,
10
+ `inline-size`, `block-size`) goes fully to zero, while effects motion (color,
11
+ opacity) shortens instead of disappearing.
12
+
13
+ `rc-app-bar` zeros its host's hide/show `translate` but shortens the
14
+ expanded title's fade-in. `rc-disclosure` keeps its panel's expand/collapse
15
+ zeroed, but its summary/content backstop for a theme-added transition now
16
+ shortens instead of zeroing it outright. `rc-list-item`'s row and
17
+ state-layer transition only color and opacity, so the whole sweep shortens.
18
+ `rc-fab-menu`'s popup mixes `scale` with opacity/overlay/display under one
19
+ shared duration; reduced motion now zeros the scale and shortens the rest.
20
+ `rc-switch`'s thumb mixes background-color with inline-size/block-size/
21
+ transform the same way; the icons and track, which each transition only one
22
+ kind of property, needed only the zero-or-shorten call. `rc-fab`'s
23
+ scroll-reveal is opacity/visibility only with no time-based duration to
24
+ shorten in its scroll-linked path, so reduced motion narrows the scroll
25
+ window instead of collapsing it to zero; its JS-transition fallback path
26
+ shortens the same fade rather than removing it. `rc-progress`'s determinate
27
+ fill transition, previously unguarded under reduced motion, is now zeroed;
28
+ its indeterminate loop, a continuous sweep with no meaningful shortened
29
+ form, stays fully stopped rather than shortened.
30
+
31
+ - 114e38a: `rc-progress`'s determinate fill transition is now themeable through two new
32
+ CSS custom properties, `--rc-progress-fill-transition-duration` (default
33
+ `150ms`) and `--rc-progress-fill-transition-easing` (default `ease-out`),
34
+ replacing a hardcoded `0.15s ease-out` no theme could reach.
35
+
36
+ The indeterminate loop's easing changes from `ease-in-out` to `linear`. A
37
+ loop has no beginning or end to decelerate into or accelerate out of, so an
38
+ eased loop visibly pulses at each cycle boundary; Material 3 specifies linear
39
+ easing for indeterminate loops for the same reason.
40
+
41
+ `rc-theme-material` and `rc-theme-substrate` map the new duration/easing
42
+ properties to their effects-fast motion tokens; `rc-theme-win31` already sets
43
+ `transition: none` on the fill part directly and needs no change.
44
+
45
+ ### Patch Changes
46
+
47
+ - cc7289f: `rc-progress`'s indeterminate sweep now animates `translate` instead of
48
+ `inset-inline-start`, moving the animation onto the compositor instead of
49
+ forcing layout on every frame. `translate`'s percentages resolve against the
50
+ element's own box, not the track, and its direction is physical rather than
51
+ logical, so it does not flip for RTL the way `inset-inline-start` did on its
52
+ own; an internal custom property now carries that sign flip via `:dir(rtl)`,
53
+ verified to still sweep start-to-end in both writing directions.
54
+ - Updated dependencies [50d5610]
55
+ - Updated dependencies [4341311]
56
+ - @rcarls/rc-common@0.0.0-next-20260921045401
57
+
58
+ ## 0.6.0
59
+
60
+ ### Minor Changes
61
+
62
+ - 509ee64: Add `rc-progress`, a native `<progress>` enhancer with a formatted value
63
+ display, a track and fill you can restyle with CSS custom properties, and a
64
+ built-in fix for the indeterminate/undefined-binding footgun.
65
+
66
+ Keep the native element as the uncontrolled source of truth, support releasing
67
+ a controlled value, and react to live native `value`/`max` changes. Preserve a
68
+ native determinate value while `indeterminate` temporarily removes its
69
+ attribute.
70
+
71
+ The bar renders at its intended height with no `display` attribute set,
72
+ matching its own documented default: previously the track/fill/native
73
+ `<progress>` are all absolutely positioned, contributing nothing to the
74
+ control's normal-flow height, so with no value-display text sharing its grid
75
+ row to give it one, the whole bar collapsed to 0px.
76
+
77
+ ### Patch Changes
78
+
79
+ - Updated dependencies [6683eb9]
80
+ - Updated dependencies [ee7ba6c]
81
+ - Updated dependencies [30eb232]
82
+ - @rcarls/rc-common@0.6.0
package/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # @rcarls/rc-progress
2
+
3
+ Native `<progress>` enhancer with a formatted value display, a track and fill
4
+ you can restyle with CSS custom properties, and a built-in fix for the
5
+ indeterminate/undefined-binding footgun.
6
+
7
+ Docs: [https://richardcarls.github.io/rc-webcomponents/components/rc-progress](https://richardcarls.github.io/rc-webcomponents/components/rc-progress).
8
+
9
+ ## Styling Hooks
10
+
11
+ `rc-progress` progressively enhances a direct child `<progress>`. The element
12
+ remains consumer-owned light DOM (so it keeps its native `role="progressbar"`
13
+ and any `id`-based associations), while the component renders its track, fill,
14
+ and value display in shadow DOM.
15
+
16
+ ```html
17
+ <rc-progress display="inline-end" value-text="4 of 10 recipes synced">
18
+ <progress value="4" max="10" aria-label="Sync progress"></progress>
19
+ </rc-progress>
20
+ ```
21
+
22
+ The component exposes `root`, `control`, `track`, `fill`, and `value-display`
23
+ CSS parts.
24
+
25
+ ## Indeterminate
26
+
27
+ Toggle the `indeterminate` attribute instead of binding `undefined` to the
28
+ native element's `value`: the component removes/restores the attribute for
29
+ you, avoiding the well-known `<progress>.value = undefined` throw:
30
+
31
+ ```html
32
+ <rc-progress indeterminate>
33
+ <progress aria-label="Preparing…"></progress>
34
+ </rc-progress>
35
+ ```
@@ -0,0 +1,510 @@
1
+ {
2
+ "schemaVersion": "1.0.0",
3
+ "readme": "",
4
+ "modules": [
5
+ {
6
+ "kind": "javascript-module",
7
+ "path": "src/define.ts",
8
+ "declarations": [],
9
+ "exports": [
10
+ {
11
+ "kind": "custom-element-definition",
12
+ "name": "rc-progress",
13
+ "declaration": {
14
+ "name": "RCProgress",
15
+ "module": "/src/index.js"
16
+ }
17
+ },
18
+ {
19
+ "kind": "js",
20
+ "name": "*",
21
+ "declaration": {
22
+ "name": "*",
23
+ "module": "src/index.js"
24
+ }
25
+ }
26
+ ]
27
+ },
28
+ {
29
+ "kind": "javascript-module",
30
+ "path": "src/index.ts",
31
+ "declarations": [],
32
+ "exports": [
33
+ {
34
+ "kind": "js",
35
+ "name": "*",
36
+ "declaration": {
37
+ "name": "*",
38
+ "module": "src/rc-progress.js"
39
+ }
40
+ }
41
+ ]
42
+ },
43
+ {
44
+ "kind": "javascript-module",
45
+ "path": "src/rc-progress.ts",
46
+ "declarations": [
47
+ {
48
+ "kind": "class",
49
+ "description": "Enhances a native `<progress>` with a custom track/fill and an optional\nformatted value display, following the same progressive-enhancement shape\nas `rc-slider`.\n\nDeliberately does one job: it does not render a dialog, own any phase\nstate, or assume anything about where it's placed. Compose it with\n`rc-dialog`, a card, or an inline status row as needed.\n\nLabel association:\n- Explicit `for`/`id`: `<label for=\"sync\">Sync</label><rc-progress><progress id=\"sync\" …></rc-progress>`\n- Direct `aria-label` on the `<progress>`: `<progress aria-label=\"Sync\" …>`\n\nThese patterns all work without JavaScript. The component does not render\na label itself — the consumer is responsible for accessible naming.",
50
+ "name": "RCProgress",
51
+ "cssProperties": [
52
+ {
53
+ "description": "Track hit-area block size.",
54
+ "name": "--rc-progress-control-size",
55
+ "default": "0.5rem"
56
+ },
57
+ {
58
+ "description": "Track length when `orientation=\"vertical\"`.",
59
+ "name": "--rc-progress-vertical-size",
60
+ "default": "12.5rem"
61
+ },
62
+ {
63
+ "description": "Gap between track and inline value display.",
64
+ "name": "--rc-progress-gap",
65
+ "default": "var(--rc-control-gap)"
66
+ },
67
+ {
68
+ "description": "Unfilled track color.",
69
+ "name": "--rc-progress-track-background",
70
+ "default": "CanvasText"
71
+ },
72
+ {
73
+ "description": "Unfilled track opacity.",
74
+ "name": "--rc-progress-track-opacity",
75
+ "default": "0.25"
76
+ },
77
+ {
78
+ "description": "Track border radius.",
79
+ "name": "--rc-progress-track-radius",
80
+ "default": "var(--rc-control-radius)"
81
+ },
82
+ {
83
+ "description": "Filled track color.",
84
+ "name": "--rc-progress-fill-background",
85
+ "default": "var(--rc-accent)"
86
+ },
87
+ {
88
+ "description": "Determinate fill transition duration.",
89
+ "name": "--rc-progress-fill-transition-duration",
90
+ "default": "150ms"
91
+ },
92
+ {
93
+ "description": "Determinate fill transition easing.",
94
+ "name": "--rc-progress-fill-transition-easing",
95
+ "default": "ease-out"
96
+ },
97
+ {
98
+ "description": "Value display text color.",
99
+ "name": "--rc-progress-value-color",
100
+ "default": "var(--rc-text-disabled)"
101
+ }
102
+ ],
103
+ "cssParts": [
104
+ {
105
+ "description": "Root layout wrapper.",
106
+ "name": "root"
107
+ },
108
+ {
109
+ "description": "Track positioning wrapper.",
110
+ "name": "control"
111
+ },
112
+ {
113
+ "description": "Visual track.",
114
+ "name": "track"
115
+ },
116
+ {
117
+ "description": "Filled progress segment.",
118
+ "name": "fill"
119
+ },
120
+ {
121
+ "description": "Rendered value text.",
122
+ "name": "value-display"
123
+ }
124
+ ],
125
+ "slots": [
126
+ {
127
+ "description": "Place a `<progress>` element here.",
128
+ "name": ""
129
+ },
130
+ {
131
+ "description": "Optional replacement for the rendered value text.",
132
+ "name": "value-display"
133
+ }
134
+ ],
135
+ "members": [
136
+ {
137
+ "kind": "field",
138
+ "name": "_value",
139
+ "type": {
140
+ "text": "number | undefined"
141
+ },
142
+ "privacy": "private"
143
+ },
144
+ {
145
+ "kind": "field",
146
+ "name": "_defaultValue",
147
+ "type": {
148
+ "text": "number | undefined"
149
+ },
150
+ "privacy": "private"
151
+ },
152
+ {
153
+ "kind": "field",
154
+ "name": "_valueInitialized",
155
+ "type": {
156
+ "text": "boolean"
157
+ },
158
+ "privacy": "private",
159
+ "default": "false"
160
+ },
161
+ {
162
+ "kind": "field",
163
+ "name": "value",
164
+ "type": {
165
+ "text": "number"
166
+ },
167
+ "description": "Current progress value.",
168
+ "attribute": "value"
169
+ },
170
+ {
171
+ "kind": "field",
172
+ "name": "defaultValue",
173
+ "type": {
174
+ "text": "number | undefined"
175
+ },
176
+ "description": "Initial uncontrolled value. Has no effect after the first host write.",
177
+ "attribute": "default-value"
178
+ },
179
+ {
180
+ "kind": "field",
181
+ "name": "max",
182
+ "type": {
183
+ "text": "number"
184
+ },
185
+ "description": "Maximum progress value, read directly from the native `<progress>`\nchild's own `max` IDL property (native default `1`) rather than\nduplicated as a separate host attribute — the consumer already owns it\nby setting `max` on the slotted `<progress>` element.",
186
+ "readonly": true
187
+ },
188
+ {
189
+ "kind": "field",
190
+ "name": "indeterminate",
191
+ "type": {
192
+ "text": "boolean"
193
+ },
194
+ "default": "false",
195
+ "description": "When present, the component removes the native `<progress>`'s `value`\nattribute instead of asking the consumer to bind `undefined` to it —\nbinding `undefined` to a live `<progress>.value` throws.",
196
+ "attribute": "indeterminate",
197
+ "reflects": true
198
+ },
199
+ {
200
+ "kind": "field",
201
+ "name": "disabled",
202
+ "type": {
203
+ "text": "boolean"
204
+ },
205
+ "default": "false",
206
+ "description": "Visual-only dimming; native `<progress>` has no functional disabled state.",
207
+ "attribute": "disabled",
208
+ "reflects": true
209
+ },
210
+ {
211
+ "kind": "field",
212
+ "name": "display",
213
+ "type": {
214
+ "text": "DisplayValue"
215
+ },
216
+ "default": "null",
217
+ "description": "Controls the live value display.\n\n- Absent (default) — no value shown.\n- `overlay` (or bare `display`) — centered on the bar.\n- `display=\"inline-start\"` — rendered before the track, inline in the grid.\n- `display=\"inline-end\"` — rendered after the track, inline in the grid.",
218
+ "attribute": "display",
219
+ "reflects": true
220
+ },
221
+ {
222
+ "kind": "field",
223
+ "name": "valueText",
224
+ "type": {
225
+ "text": "string"
226
+ },
227
+ "default": "''",
228
+ "description": "Screen-reader value text. When set, forwarded as `aria-valuetext` on the\nnative `<progress>` and used as the default formatted display text.",
229
+ "attribute": "value-text"
230
+ },
231
+ {
232
+ "kind": "field",
233
+ "name": "orientation",
234
+ "type": {
235
+ "text": "'horizontal' | 'vertical'"
236
+ },
237
+ "default": "'horizontal'",
238
+ "description": "Orientation; reflected as an attribute and forwarded to `aria-orientation`.",
239
+ "attribute": "orientation",
240
+ "reflects": true
241
+ },
242
+ {
243
+ "kind": "field",
244
+ "name": "_$nativeProgress",
245
+ "type": {
246
+ "text": "HTMLProgressElement | null"
247
+ },
248
+ "privacy": "private",
249
+ "default": "null"
250
+ },
251
+ {
252
+ "kind": "field",
253
+ "name": "_completedDispatched",
254
+ "type": {
255
+ "text": "boolean"
256
+ },
257
+ "privacy": "private",
258
+ "default": "false"
259
+ },
260
+ {
261
+ "kind": "field",
262
+ "name": "_nativeValueBeforeIndeterminate",
263
+ "type": {
264
+ "text": "number | undefined"
265
+ },
266
+ "privacy": "private"
267
+ },
268
+ {
269
+ "kind": "field",
270
+ "name": "_progressObserver",
271
+ "type": {
272
+ "text": "MutationObserver | null"
273
+ },
274
+ "privacy": "private",
275
+ "default": "null"
276
+ },
277
+ {
278
+ "kind": "field",
279
+ "name": "_nativeProgressController",
280
+ "privacy": "private",
281
+ "readonly": true,
282
+ "default": "new NativeChildController<HTMLProgressElement>( this, { selector: ':scope > progress', observe: true, onChange: ($progress, $previous) => this._setupProgress($progress, $previous), onMissing: () => { if (import.meta.env.DEV) { warnMissingDirectChild(this, { selector: ':scope > progress', message: '[rc-progress] Requires a child <progress> element.', }); } }, }, )"
283
+ },
284
+ {
285
+ "kind": "field",
286
+ "name": "_displayText",
287
+ "type": {
288
+ "text": "string"
289
+ },
290
+ "privacy": "private",
291
+ "readonly": true
292
+ },
293
+ {
294
+ "kind": "field",
295
+ "name": "_nativeProgressValue",
296
+ "type": {
297
+ "text": "number"
298
+ },
299
+ "privacy": "private",
300
+ "readonly": true
301
+ },
302
+ {
303
+ "kind": "method",
304
+ "name": "_setupProgress",
305
+ "privacy": "private",
306
+ "return": {
307
+ "type": {
308
+ "text": "void"
309
+ }
310
+ },
311
+ "parameters": [
312
+ {
313
+ "name": "$progress",
314
+ "type": {
315
+ "text": "HTMLProgressElement | null"
316
+ }
317
+ },
318
+ {
319
+ "name": "$previous",
320
+ "optional": true,
321
+ "type": {
322
+ "text": "HTMLProgressElement | null"
323
+ }
324
+ }
325
+ ]
326
+ },
327
+ {
328
+ "kind": "field",
329
+ "name": "_onDefaultSlotChange",
330
+ "privacy": "private"
331
+ },
332
+ {
333
+ "kind": "method",
334
+ "name": "_applyInitialValueToNative",
335
+ "privacy": "private",
336
+ "return": {
337
+ "type": {
338
+ "text": "void"
339
+ }
340
+ }
341
+ },
342
+ {
343
+ "kind": "method",
344
+ "name": "_applyValueToNative",
345
+ "privacy": "private",
346
+ "return": {
347
+ "type": {
348
+ "text": "void"
349
+ }
350
+ },
351
+ "parameters": [
352
+ {
353
+ "name": "value",
354
+ "type": {
355
+ "text": "number"
356
+ }
357
+ }
358
+ ]
359
+ },
360
+ {
361
+ "kind": "method",
362
+ "name": "_applyIndeterminate",
363
+ "privacy": "private",
364
+ "return": {
365
+ "type": {
366
+ "text": "void"
367
+ }
368
+ },
369
+ "description": "Adds or removes the native `<progress>`'s `value` attribute/property to\nreflect `indeterminate` — the one piece of state this component owns so\nconsumers never bind `undefined` to a live `<progress>.value` themselves."
370
+ },
371
+ {
372
+ "kind": "method",
373
+ "name": "_syncAriaAttributes",
374
+ "privacy": "private",
375
+ "return": {
376
+ "type": {
377
+ "text": "void"
378
+ }
379
+ },
380
+ "parameters": [
381
+ {
382
+ "name": "$progress",
383
+ "type": {
384
+ "text": "HTMLProgressElement"
385
+ }
386
+ }
387
+ ]
388
+ },
389
+ {
390
+ "kind": "method",
391
+ "name": "_checkComplete",
392
+ "privacy": "private",
393
+ "return": {
394
+ "type": {
395
+ "text": "void"
396
+ }
397
+ }
398
+ },
399
+ {
400
+ "kind": "method",
401
+ "name": "_fillStyle",
402
+ "privacy": "private",
403
+ "return": {
404
+ "type": {
405
+ "text": "string"
406
+ }
407
+ }
408
+ }
409
+ ],
410
+ "events": [
411
+ {
412
+ "name": "rc-progress-complete",
413
+ "type": {
414
+ "text": "CustomEvent"
415
+ },
416
+ "description": "Fires once when `value` reaches `max` while not indeterminate. Does not re-fire on subsequent updates while already at max."
417
+ }
418
+ ],
419
+ "attributes": [
420
+ {
421
+ "description": "Current progress value.",
422
+ "name": "value",
423
+ "type": {
424
+ "text": "number"
425
+ },
426
+ "fieldName": "value"
427
+ },
428
+ {
429
+ "description": "Initial uncontrolled value. Has no effect after the first host write.",
430
+ "name": "default-value",
431
+ "type": {
432
+ "text": "number | undefined"
433
+ },
434
+ "fieldName": "defaultValue"
435
+ },
436
+ {
437
+ "description": "When present, the component removes the native `<progress>`'s `value`\nattribute instead of asking the consumer to bind `undefined` to it —\nbinding `undefined` to a live `<progress>.value` throws.",
438
+ "name": "indeterminate",
439
+ "type": {
440
+ "text": "boolean"
441
+ },
442
+ "default": "false",
443
+ "fieldName": "indeterminate"
444
+ },
445
+ {
446
+ "description": "Controls the live value display.\n\n- Absent (default) — no value shown.\n- `overlay` (or bare `display`) — centered on the bar.\n- `display=\"inline-start\"` — rendered before the track, inline in the grid.\n- `display=\"inline-end\"` — rendered after the track, inline in the grid.",
447
+ "name": "display",
448
+ "type": {
449
+ "text": "DisplayValue"
450
+ },
451
+ "default": "null",
452
+ "fieldName": "display"
453
+ },
454
+ {
455
+ "description": "Screen-reader value text. When set, forwarded as `aria-valuetext` on the\nnative `<progress>` and used as the default formatted display text.",
456
+ "name": "value-text",
457
+ "type": {
458
+ "text": "string"
459
+ },
460
+ "default": "''",
461
+ "fieldName": "valueText"
462
+ },
463
+ {
464
+ "description": "Orientation; reflected as an attribute and forwarded to `aria-orientation`.",
465
+ "name": "orientation",
466
+ "type": {
467
+ "text": "'horizontal' | 'vertical'"
468
+ },
469
+ "default": "'horizontal'",
470
+ "fieldName": "orientation"
471
+ },
472
+ {
473
+ "description": "Visual-only dimming; native `<progress>` has no functional disabled state.",
474
+ "name": "disabled",
475
+ "type": {
476
+ "text": "boolean"
477
+ },
478
+ "default": "false",
479
+ "fieldName": "disabled"
480
+ }
481
+ ],
482
+ "superclass": {
483
+ "name": "LitElement",
484
+ "package": "lit"
485
+ },
486
+ "tagName": "rc-progress",
487
+ "customElement": true
488
+ }
489
+ ],
490
+ "exports": [
491
+ {
492
+ "kind": "js",
493
+ "name": "RCProgress",
494
+ "declaration": {
495
+ "name": "RCProgress",
496
+ "module": "src/rc-progress.ts"
497
+ }
498
+ },
499
+ {
500
+ "kind": "js",
501
+ "name": "default",
502
+ "declaration": {
503
+ "name": "RCProgress",
504
+ "module": "src/rc-progress.ts"
505
+ }
506
+ }
507
+ ]
508
+ }
509
+ ]
510
+ }
@@ -0,0 +1,353 @@
1
+ import { LitElement as d, css as v, nothing as a, html as h } from "lit";
2
+ import { property as n } from "lit/decorators.js";
3
+ import { ifDefined as f } from "lit/directives/if-defined.js";
4
+ import { NativeChildController as g } from "@rcarls/rc-common";
5
+ var m = Object.defineProperty, y = Object.getOwnPropertyDescriptor, o = (i, e, t, l) => {
6
+ for (var s = l > 1 ? void 0 : l ? y(e, t) : e, c = i.length - 1, u; c >= 0; c--)
7
+ (u = i[c]) && (s = (l ? u(e, t, s) : u(s)) || s);
8
+ return l && s && m(e, t, s), s;
9
+ };
10
+ const _ = {
11
+ fromAttribute(i) {
12
+ return i === null ? null : i === "" || i === "overlay" ? "overlay" : i === "inline-start" ? "inline-start" : i === "inline-end" ? "inline-end" : null;
13
+ },
14
+ toAttribute(i) {
15
+ return i;
16
+ }
17
+ }, p = class p extends d {
18
+ constructor() {
19
+ super(...arguments), this._valueInitialized = !1, this.indeterminate = !1, this.disabled = !1, this.display = null, this.valueText = "", this.orientation = "horizontal", this._$nativeProgress = null, this._completedDispatched = !1, this._progressObserver = null, this._nativeProgressController = new g(
20
+ this,
21
+ {
22
+ selector: ":scope > progress",
23
+ observe: !0,
24
+ onChange: (e, t) => this._setupProgress(e, t),
25
+ onMissing: () => {
26
+ }
27
+ }
28
+ ), this._onDefaultSlotChange = () => {
29
+ this._nativeProgressController.sync(), this.requestUpdate();
30
+ };
31
+ }
32
+ get value() {
33
+ return this._value ?? this._defaultValue ?? this._nativeProgressValue;
34
+ }
35
+ set value(e) {
36
+ const t = this.value;
37
+ this._value = e ?? void 0, this._valueInitialized = !0, this._applyValueToNative(this.value), this.requestUpdate("value", t);
38
+ }
39
+ get defaultValue() {
40
+ return this._defaultValue;
41
+ }
42
+ set defaultValue(e) {
43
+ const t = this._defaultValue;
44
+ this._defaultValue = e, !this._valueInitialized && this._value === void 0 && e !== void 0 && (this._applyValueToNative(e), this.requestUpdate("value", void 0)), this.requestUpdate("defaultValue", t);
45
+ }
46
+ /**
47
+ * Maximum progress value, read directly from the native `<progress>`
48
+ * child's own `max` IDL property (native default `1`) rather than
49
+ * duplicated as a separate host attribute — the consumer already owns it
50
+ * by setting `max` on the slotted `<progress>` element.
51
+ */
52
+ get max() {
53
+ return this._$nativeProgress?.max ?? 1;
54
+ }
55
+ disconnectedCallback() {
56
+ this._progressObserver?.disconnect(), super.disconnectedCallback();
57
+ }
58
+ updated(e) {
59
+ const t = this._$nativeProgress;
60
+ t && this._syncAriaAttributes(t), e.has("indeterminate") && this._applyIndeterminate(), (e.has("value") || e.has("indeterminate")) && this._checkComplete();
61
+ }
62
+ render() {
63
+ if (!this._$nativeProgress)
64
+ return a;
65
+ const t = h`
66
+ <span part="value-display" class="rc-progress-value" aria-hidden="true">
67
+ <slot name="value-display">${this._displayText}</slot>
68
+ </span>
69
+ `;
70
+ return h`
71
+ <div
72
+ part="root"
73
+ class="rc-progress-root"
74
+ data-display=${this.display ?? a}
75
+ data-orientation=${this.orientation}
76
+ data-disabled=${this.disabled ? "" : a}
77
+ data-has-value-text=${this.valueText ? "" : a}
78
+ >
79
+ ${this.display === "inline-start" ? t : a}
80
+
81
+ <span part="control" class="rc-progress-control">
82
+ <span part="track" class="rc-progress-track" aria-hidden="true">
83
+ <span
84
+ part="fill"
85
+ class="rc-progress-fill"
86
+ style=${f(this.indeterminate ? void 0 : this._fillStyle())}
87
+ ></span>
88
+ </span>
89
+
90
+ <slot @slotchange=${this._onDefaultSlotChange}></slot>
91
+ ${this.display === "overlay" ? t : a}
92
+ </span>
93
+
94
+ ${this.display === "inline-end" ? t : a}
95
+ </div>
96
+ `;
97
+ }
98
+ get _displayText() {
99
+ if (this.valueText)
100
+ return this.valueText;
101
+ if (this.indeterminate)
102
+ return "";
103
+ const e = this.max > 0 ? this.value / this.max * 100 : 0;
104
+ return `${Math.round(e)}%`;
105
+ }
106
+ get _nativeProgressValue() {
107
+ const e = this._$nativeProgress?.value;
108
+ return e === void 0 || isNaN(e) ? 0 : e;
109
+ }
110
+ _setupProgress(e, t) {
111
+ if (this._progressObserver?.disconnect(), this._progressObserver = null, !e) {
112
+ this._$nativeProgress = null;
113
+ return;
114
+ }
115
+ this._$nativeProgress = e, this._applyInitialValueToNative(), this._applyIndeterminate(), typeof MutationObserver == "function" && (this._progressObserver = new MutationObserver(() => {
116
+ this.indeterminate && this._applyIndeterminate(), this.requestUpdate(), this._checkComplete();
117
+ }), this._progressObserver.observe(e, {
118
+ attributes: !0,
119
+ attributeFilter: ["max", "value"]
120
+ })), this.requestUpdate();
121
+ }
122
+ _applyInitialValueToNative() {
123
+ if (this._value !== void 0) {
124
+ this._applyValueToNative(this._value);
125
+ return;
126
+ }
127
+ if (this._defaultValue !== void 0) {
128
+ this._applyValueToNative(this._defaultValue);
129
+ return;
130
+ }
131
+ }
132
+ _applyValueToNative(e) {
133
+ !this._$nativeProgress || this.indeterminate || (this._$nativeProgress.value = e);
134
+ }
135
+ /**
136
+ * Adds or removes the native `<progress>`'s `value` attribute/property to
137
+ * reflect `indeterminate` — the one piece of state this component owns so
138
+ * consumers never bind `undefined` to a live `<progress>.value` themselves.
139
+ */
140
+ _applyIndeterminate() {
141
+ const e = this._$nativeProgress;
142
+ e && (this.indeterminate ? (e.hasAttribute("value") && (this._nativeValueBeforeIndeterminate = e.value), e.removeAttribute("value")) : (e.value = this._value ?? this._defaultValue ?? this._nativeValueBeforeIndeterminate ?? this._nativeProgressValue, this._nativeValueBeforeIndeterminate = void 0));
143
+ }
144
+ _syncAriaAttributes(e) {
145
+ this.valueText ? e.setAttribute("aria-valuetext", this.valueText) : e.removeAttribute("aria-valuetext"), this.orientation === "vertical" ? e.setAttribute("aria-orientation", "vertical") : e.removeAttribute("aria-orientation");
146
+ }
147
+ _checkComplete() {
148
+ const e = !this.indeterminate && this.max > 0 && this.value >= this.max;
149
+ e && !this._completedDispatched ? (this._completedDispatched = !0, this.dispatchEvent(
150
+ new CustomEvent("rc-progress-complete", { bubbles: !0, composed: !0 })
151
+ )) : e || (this._completedDispatched = !1);
152
+ }
153
+ _fillStyle() {
154
+ const e = this.max > 0 ? Math.min(100, Math.max(0, this.value / this.max * 100)) : 0;
155
+ return this.orientation === "vertical" ? `inset-block-start:${(100 - e).toFixed(3)}%;block-size:${e.toFixed(3)}%` : `inline-size:${e.toFixed(3)}%`;
156
+ }
157
+ };
158
+ p.styles = v`
159
+ :host {
160
+ display: block;
161
+ /*
162
+ * translate() percentages resolve against the element's own box, not
163
+ * the parent's, and its direction is physical, not logical — it does
164
+ * not flip for RTL the way inset-inline-start does on its own. This
165
+ * sign flips the indeterminate sweep's direction so it still travels
166
+ * start-to-end in the document's actual writing direction.
167
+ */
168
+ --_rc-progress-indeterminate-direction: 1;
169
+ }
170
+
171
+ :host(:dir(rtl)) {
172
+ --_rc-progress-indeterminate-direction: -1;
173
+ }
174
+
175
+ .rc-progress-root {
176
+ display: grid;
177
+ gap: var(--rc-progress-gap, var(--rc-control-gap, 0.5rem));
178
+ align-items: center;
179
+ font-family: var(--rc-font-family, inherit);
180
+ font-size: var(--rc-font-size, inherit);
181
+ line-height: var(--rc-line-height, normal);
182
+ }
183
+
184
+ .rc-progress-root[data-display='inline-start'] {
185
+ grid-template-columns: auto minmax(0, 1fr);
186
+ }
187
+
188
+ .rc-progress-root[data-display='inline-end'] {
189
+ grid-template-columns: minmax(0, 1fr) auto;
190
+ }
191
+
192
+ .rc-progress-control {
193
+ position: relative;
194
+ display: block;
195
+ min-width: 0;
196
+ /*
197
+ * Everything this wraps (the track, the fill, the slotted <progress>)
198
+ * is position: absolute, contributing nothing to normal-flow height.
199
+ * Without an explicit block-size here, this collapses to 0px and the
200
+ * whole bar renders invisible whenever no value-display text (the
201
+ * only other thing that could give the shared grid row a height) is
202
+ * shown alongside it — the default, since display is unset unless a
203
+ * consumer opts into inline-start/inline-end/overlay.
204
+ */
205
+ block-size: var(--rc-progress-control-size, 0.5rem);
206
+ }
207
+
208
+ .rc-progress-track,
209
+ .rc-progress-fill {
210
+ position: absolute;
211
+ pointer-events: none;
212
+ }
213
+
214
+ .rc-progress-track {
215
+ inset: 0;
216
+ block-size: var(--rc-progress-control-size, 0.5rem);
217
+ background: var(--rc-progress-track-background, CanvasText);
218
+ opacity: var(--rc-progress-track-opacity, 0.25);
219
+ border-radius: var(--rc-progress-track-radius, var(--rc-control-radius, 0));
220
+ overflow: hidden;
221
+ z-index: 0;
222
+ }
223
+
224
+ ::slotted(progress) {
225
+ position: absolute;
226
+ inset: 0;
227
+ inline-size: 100%;
228
+ block-size: 100%;
229
+ margin: 0;
230
+ opacity: 0;
231
+ z-index: 2;
232
+ }
233
+
234
+ .rc-progress-fill {
235
+ inset-block: 0;
236
+ inset-inline-start: 0;
237
+ background: var(--rc-progress-fill-background, var(--rc-accent, Highlight));
238
+ border-radius: inherit;
239
+ z-index: 1;
240
+ transition: inline-size var(--rc-progress-fill-transition-duration, 150ms)
241
+ var(--rc-progress-fill-transition-easing, ease-out);
242
+ }
243
+
244
+ :host([indeterminate]) .rc-progress-fill {
245
+ inline-size: 40% !important;
246
+ /*
247
+ * A loop has no beginning or end to decelerate into or accelerate out
248
+ * of, so it uses a constant, linear pace; an eased loop visibly pulses
249
+ * at each cycle boundary.
250
+ */
251
+ animation: rc-progress-indeterminate 1.4s linear infinite;
252
+ }
253
+
254
+ /*
255
+ * translate() moves on the compositor; inset-inline-start forces layout
256
+ * on every frame. The fill's own box is 40% of the track (its inline-
257
+ * size), so a translate of N% moves it N% of that 40%, not of the
258
+ * track: -100% (of self) lands at -40% of the track, matching where
259
+ * this keyframe used to start, and 250% (of self) lands at 100%.
260
+ */
261
+ @keyframes rc-progress-indeterminate {
262
+ 0% {
263
+ translate: calc(var(--_rc-progress-indeterminate-direction) * -100%) 0;
264
+ }
265
+ 100% {
266
+ translate: calc(var(--_rc-progress-indeterminate-direction) * 250%) 0;
267
+ }
268
+ }
269
+
270
+ @media (prefers-reduced-motion: reduce) {
271
+ /*
272
+ * The determinate fill's inline-size transition is spatial (a real
273
+ * width change), so it drops to 0ms. The indeterminate loop is an
274
+ * unbounded, continuous translate sweeping most of the track, which
275
+ * has no meaningful "shortened" form, so it stops outright rather
276
+ * than looping faster; the fill still shows a static bar via its
277
+ * existing 40% inline-size.
278
+ */
279
+ :host(:not([indeterminate])) .rc-progress-fill {
280
+ transition-duration: 0ms;
281
+ }
282
+
283
+ :host([indeterminate]) .rc-progress-fill {
284
+ animation: none;
285
+ translate: none;
286
+ }
287
+ }
288
+
289
+ .rc-progress-value {
290
+ font-variant-numeric: tabular-nums;
291
+ white-space: nowrap;
292
+ color: var(--rc-progress-value-color, var(--rc-text-disabled, GrayText));
293
+ }
294
+
295
+ .rc-progress-root[data-display='overlay'] .rc-progress-value {
296
+ position: absolute;
297
+ inset: 0;
298
+ display: flex;
299
+ align-items: center;
300
+ justify-content: center;
301
+ pointer-events: none;
302
+ z-index: 3;
303
+ }
304
+
305
+ :host([orientation='vertical']) {
306
+ display: inline-block;
307
+ }
308
+
309
+ :host([orientation='vertical']) .rc-progress-control {
310
+ inline-size: var(--rc-progress-control-size, 0.5rem);
311
+ block-size: var(--rc-progress-vertical-size, 12.5rem);
312
+ }
313
+
314
+ :host([orientation='vertical']) .rc-progress-track {
315
+ inline-size: var(--rc-progress-control-size, 0.5rem);
316
+ block-size: auto;
317
+ }
318
+
319
+ :host([orientation='vertical']) .rc-progress-fill {
320
+ inset-inline: 0;
321
+ inset-block-start: auto;
322
+ }
323
+
324
+ :host([disabled]) {
325
+ opacity: 0.5;
326
+ }
327
+ `;
328
+ let r = p;
329
+ o([
330
+ n({ type: Number })
331
+ ], r.prototype, "value", 1);
332
+ o([
333
+ n({ type: Number, attribute: "default-value" })
334
+ ], r.prototype, "defaultValue", 1);
335
+ o([
336
+ n({ type: Boolean, reflect: !0 })
337
+ ], r.prototype, "indeterminate", 2);
338
+ o([
339
+ n({ type: Boolean, reflect: !0 })
340
+ ], r.prototype, "disabled", 2);
341
+ o([
342
+ n({ reflect: !0, converter: _ })
343
+ ], r.prototype, "display", 2);
344
+ o([
345
+ n({ attribute: "value-text" })
346
+ ], r.prototype, "valueText", 2);
347
+ o([
348
+ n({ reflect: !0 })
349
+ ], r.prototype, "orientation", 2);
350
+ export {
351
+ r as R
352
+ };
353
+ //# sourceMappingURL=rc-progress-D3BdHeCV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-progress-D3BdHeCV.js","sources":["../src/rc-progress.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport type { ComplexAttributeConverter, PropertyValues } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { NativeChildController, warnMissingDirectChild } from '@rcarls/rc-common';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-progress': RCProgress;\n }\n\n interface HTMLElementEventMap {\n 'rc-progress-complete': CustomEvent<Record<string, never>>;\n }\n}\n\ntype DisplayValue = 'inline-start' | 'inline-end' | 'overlay' | null;\n\n/**\n * Normalises the `display` attribute.\n * A bare boolean attribute (`display` with no value) maps to `'overlay'` so\n * the reflected attribute is always an explicit string, never an empty string.\n */\nconst displayConverter: ComplexAttributeConverter<DisplayValue> = {\n fromAttribute(v: string | null): DisplayValue {\n if (v === null) {\n return null;\n }\n\n if (v === '' || v === 'overlay') {\n return 'overlay';\n }\n\n if (v === 'inline-start') {\n return 'inline-start';\n }\n\n if (v === 'inline-end') {\n return 'inline-end';\n }\n\n return null;\n },\n toAttribute(v: DisplayValue): string | null {\n return v;\n },\n};\n\n/**\n * Enhances a native `<progress>` with a custom track/fill and an optional\n * formatted value display, following the same progressive-enhancement shape\n * as `rc-slider`.\n *\n * Deliberately does one job: it does not render a dialog, own any phase\n * state, or assume anything about where it's placed. Compose it with\n * `rc-dialog`, a card, or an inline status row as needed.\n *\n * Label association:\n * - Explicit `for`/`id`: `<label for=\"sync\">Sync</label><rc-progress><progress id=\"sync\" …></rc-progress>`\n * - Direct `aria-label` on the `<progress>`: `<progress aria-label=\"Sync\" …>`\n *\n * These patterns all work without JavaScript. The component does not render\n * a label itself — the consumer is responsible for accessible naming.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-progress rc-progress docs}\n *\n * @slot - Place a `<progress>` element here.\n * @slot value-display - Optional replacement for the rendered value text.\n *\n * @fires rc-progress-complete - Fires once when `value` reaches `max` while\n * not indeterminate. Does not re-fire on subsequent updates while already\n * at max.\n *\n * @attr value - Current progress value. Host writes are silent.\n * @attr default-value - Initial uncontrolled value. Has no effect after the first\n * host write.\n * @attr indeterminate - When present, the component removes the native `<progress>`'s\n * `value` attribute instead of asking the consumer to bind `undefined` to it.\n * @attr display - Controls the live value display: absent (none), `overlay` (centered on\n * the bar), `inline-start`, or `inline-end`.\n * @attr value-text - Screen-reader value text, forwarded as `aria-valuetext` on the\n * native `<progress>`. Also used as the default formatted display text when set.\n * @attr orientation - Orientation, forwarded to `aria-orientation`: `horizontal` or\n * `vertical`.\n * @attr disabled - Visual-only dimming; native `<progress>` has no functional disabled state.\n *\n * @cssprop [--rc-progress-control-size=0.5rem] - Track hit-area block size.\n * @cssprop [--rc-progress-vertical-size=12.5rem] - Track length when `orientation=\"vertical\"`.\n * @cssprop [--rc-progress-gap=var(--rc-control-gap)] - Gap between track and inline value display.\n * @cssprop [--rc-progress-track-background=CanvasText] - Unfilled track color.\n * @cssprop [--rc-progress-track-opacity=0.25] - Unfilled track opacity.\n * @cssprop [--rc-progress-track-radius=var(--rc-control-radius)] - Track border radius.\n * @cssprop [--rc-progress-fill-background=var(--rc-accent)] - Filled track color.\n * @cssprop [--rc-progress-fill-transition-duration=150ms] - Determinate fill transition duration.\n * @cssprop [--rc-progress-fill-transition-easing=ease-out] - Determinate fill transition easing.\n * @cssprop [--rc-progress-value-color=var(--rc-text-disabled)] - Value display text color.\n *\n * @csspart root - Root layout wrapper.\n * @csspart control - Track positioning wrapper.\n * @csspart track - Visual track.\n * @csspart fill - Filled progress segment.\n * @csspart value-display - Rendered value text.\n */\nexport class RCProgress extends LitElement {\n static override styles = css`\n :host {\n display: block;\n /*\n * translate() percentages resolve against the element's own box, not\n * the parent's, and its direction is physical, not logical — it does\n * not flip for RTL the way inset-inline-start does on its own. This\n * sign flips the indeterminate sweep's direction so it still travels\n * start-to-end in the document's actual writing direction.\n */\n --_rc-progress-indeterminate-direction: 1;\n }\n\n :host(:dir(rtl)) {\n --_rc-progress-indeterminate-direction: -1;\n }\n\n .rc-progress-root {\n display: grid;\n gap: var(--rc-progress-gap, var(--rc-control-gap, 0.5rem));\n align-items: center;\n font-family: var(--rc-font-family, inherit);\n font-size: var(--rc-font-size, inherit);\n line-height: var(--rc-line-height, normal);\n }\n\n .rc-progress-root[data-display='inline-start'] {\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .rc-progress-root[data-display='inline-end'] {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n\n .rc-progress-control {\n position: relative;\n display: block;\n min-width: 0;\n /*\n * Everything this wraps (the track, the fill, the slotted <progress>)\n * is position: absolute, contributing nothing to normal-flow height.\n * Without an explicit block-size here, this collapses to 0px and the\n * whole bar renders invisible whenever no value-display text (the\n * only other thing that could give the shared grid row a height) is\n * shown alongside it — the default, since display is unset unless a\n * consumer opts into inline-start/inline-end/overlay.\n */\n block-size: var(--rc-progress-control-size, 0.5rem);\n }\n\n .rc-progress-track,\n .rc-progress-fill {\n position: absolute;\n pointer-events: none;\n }\n\n .rc-progress-track {\n inset: 0;\n block-size: var(--rc-progress-control-size, 0.5rem);\n background: var(--rc-progress-track-background, CanvasText);\n opacity: var(--rc-progress-track-opacity, 0.25);\n border-radius: var(--rc-progress-track-radius, var(--rc-control-radius, 0));\n overflow: hidden;\n z-index: 0;\n }\n\n ::slotted(progress) {\n position: absolute;\n inset: 0;\n inline-size: 100%;\n block-size: 100%;\n margin: 0;\n opacity: 0;\n z-index: 2;\n }\n\n .rc-progress-fill {\n inset-block: 0;\n inset-inline-start: 0;\n background: var(--rc-progress-fill-background, var(--rc-accent, Highlight));\n border-radius: inherit;\n z-index: 1;\n transition: inline-size var(--rc-progress-fill-transition-duration, 150ms)\n var(--rc-progress-fill-transition-easing, ease-out);\n }\n\n :host([indeterminate]) .rc-progress-fill {\n inline-size: 40% !important;\n /*\n * A loop has no beginning or end to decelerate into or accelerate out\n * of, so it uses a constant, linear pace; an eased loop visibly pulses\n * at each cycle boundary.\n */\n animation: rc-progress-indeterminate 1.4s linear infinite;\n }\n\n /*\n * translate() moves on the compositor; inset-inline-start forces layout\n * on every frame. The fill's own box is 40% of the track (its inline-\n * size), so a translate of N% moves it N% of that 40%, not of the\n * track: -100% (of self) lands at -40% of the track, matching where\n * this keyframe used to start, and 250% (of self) lands at 100%.\n */\n @keyframes rc-progress-indeterminate {\n 0% {\n translate: calc(var(--_rc-progress-indeterminate-direction) * -100%) 0;\n }\n 100% {\n translate: calc(var(--_rc-progress-indeterminate-direction) * 250%) 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n /*\n * The determinate fill's inline-size transition is spatial (a real\n * width change), so it drops to 0ms. The indeterminate loop is an\n * unbounded, continuous translate sweeping most of the track, which\n * has no meaningful \"shortened\" form, so it stops outright rather\n * than looping faster; the fill still shows a static bar via its\n * existing 40% inline-size.\n */\n :host(:not([indeterminate])) .rc-progress-fill {\n transition-duration: 0ms;\n }\n\n :host([indeterminate]) .rc-progress-fill {\n animation: none;\n translate: none;\n }\n }\n\n .rc-progress-value {\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n color: var(--rc-progress-value-color, var(--rc-text-disabled, GrayText));\n }\n\n .rc-progress-root[data-display='overlay'] .rc-progress-value {\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n pointer-events: none;\n z-index: 3;\n }\n\n :host([orientation='vertical']) {\n display: inline-block;\n }\n\n :host([orientation='vertical']) .rc-progress-control {\n inline-size: var(--rc-progress-control-size, 0.5rem);\n block-size: var(--rc-progress-vertical-size, 12.5rem);\n }\n\n :host([orientation='vertical']) .rc-progress-track {\n inline-size: var(--rc-progress-control-size, 0.5rem);\n block-size: auto;\n }\n\n :host([orientation='vertical']) .rc-progress-fill {\n inset-inline: 0;\n inset-block-start: auto;\n }\n\n :host([disabled]) {\n opacity: 0.5;\n }\n `;\n\n private _value: number | undefined;\n private _defaultValue: number | undefined;\n private _valueInitialized = false;\n\n /** Current progress value. */\n @property({ type: Number })\n get value(): number {\n return this._value ?? this._defaultValue ?? this._nativeProgressValue;\n }\n\n set value(value: number | undefined) {\n const oldValue = this.value;\n\n this._value = value ?? undefined;\n this._valueInitialized = true;\n this._applyValueToNative(this.value);\n this.requestUpdate('value', oldValue);\n }\n\n /** Initial uncontrolled value. Has no effect after the first host write. */\n @property({ type: Number, attribute: 'default-value' })\n get defaultValue(): number | undefined {\n return this._defaultValue;\n }\n\n set defaultValue(value: number | undefined) {\n const oldValue = this._defaultValue;\n\n this._defaultValue = value;\n\n if (!this._valueInitialized && this._value === undefined && value !== undefined) {\n this._applyValueToNative(value);\n this.requestUpdate('value', undefined);\n }\n\n this.requestUpdate('defaultValue', oldValue);\n }\n\n /**\n * Maximum progress value, read directly from the native `<progress>`\n * child's own `max` IDL property (native default `1`) rather than\n * duplicated as a separate host attribute — the consumer already owns it\n * by setting `max` on the slotted `<progress>` element.\n */\n get max(): number {\n return this._$nativeProgress?.max ?? 1;\n }\n\n /**\n * When present, the component removes the native `<progress>`'s `value`\n * attribute instead of asking the consumer to bind `undefined` to it —\n * binding `undefined` to a live `<progress>.value` throws.\n */\n @property({ type: Boolean, reflect: true }) indeterminate = false;\n\n /** Visual-only dimming; native `<progress>` has no functional disabled state. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /**\n * Controls the live value display.\n *\n * - Absent (default) — no value shown.\n * - `overlay` (or bare `display`) — centered on the bar.\n * - `display=\"inline-start\"` — rendered before the track, inline in the grid.\n * - `display=\"inline-end\"` — rendered after the track, inline in the grid.\n */\n @property({ reflect: true, converter: displayConverter })\n display: DisplayValue = null;\n\n /**\n * Screen-reader value text. When set, forwarded as `aria-valuetext` on the\n * native `<progress>` and used as the default formatted display text.\n */\n @property({ attribute: 'value-text' }) valueText = '';\n\n /** Orientation; reflected as an attribute and forwarded to `aria-orientation`. */\n @property({ reflect: true }) orientation: 'horizontal' | 'vertical' = 'horizontal';\n\n private _$nativeProgress: HTMLProgressElement | null = null;\n private _completedDispatched = false;\n private _nativeValueBeforeIndeterminate: number | undefined;\n private _progressObserver: MutationObserver | null = null;\n\n private readonly _nativeProgressController = new NativeChildController<HTMLProgressElement>(\n this,\n {\n selector: ':scope > progress',\n observe: true,\n onChange: ($progress, $previous) => this._setupProgress($progress, $previous),\n onMissing: () => {\n if (import.meta.env.DEV) {\n warnMissingDirectChild(this, {\n selector: ':scope > progress',\n message: '[rc-progress] Requires a child <progress> element.',\n });\n }\n },\n },\n );\n\n override disconnectedCallback(): void {\n this._progressObserver?.disconnect();\n\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n const $progress = this._$nativeProgress;\n\n if ($progress) {\n this._syncAriaAttributes($progress);\n }\n\n if (changed.has('indeterminate')) {\n this._applyIndeterminate();\n }\n\n if (changed.has('value') || changed.has('indeterminate')) {\n this._checkComplete();\n }\n }\n\n override render() {\n const $progress = this._$nativeProgress;\n\n if (!$progress) {\n return nothing;\n }\n\n const valueDisplay = html`\n <span part=\"value-display\" class=\"rc-progress-value\" aria-hidden=\"true\">\n <slot name=\"value-display\">${this._displayText}</slot>\n </span>\n `;\n\n return html`\n <div\n part=\"root\"\n class=\"rc-progress-root\"\n data-display=${this.display ?? nothing}\n data-orientation=${this.orientation}\n data-disabled=${this.disabled ? '' : nothing}\n data-has-value-text=${this.valueText ? '' : nothing}\n >\n ${this.display === 'inline-start' ? valueDisplay : nothing}\n\n <span part=\"control\" class=\"rc-progress-control\">\n <span part=\"track\" class=\"rc-progress-track\" aria-hidden=\"true\">\n <span\n part=\"fill\"\n class=\"rc-progress-fill\"\n style=${ifDefined(this.indeterminate ? undefined : this._fillStyle())}\n ></span>\n </span>\n\n <slot @slotchange=${this._onDefaultSlotChange}></slot>\n ${this.display === 'overlay' ? valueDisplay : nothing}\n </span>\n\n ${this.display === 'inline-end' ? valueDisplay : nothing}\n </div>\n `;\n }\n\n private get _displayText(): string {\n if (this.valueText) {\n return this.valueText;\n }\n\n if (this.indeterminate) {\n return '';\n }\n\n const percent = this.max > 0 ? (this.value / this.max) * 100 : 0;\n\n return `${Math.round(percent)}%`;\n }\n\n private get _nativeProgressValue(): number {\n const value = this._$nativeProgress?.value;\n\n return value === undefined || isNaN(value) ? 0 : value;\n }\n\n private _setupProgress(\n $progress: HTMLProgressElement | null,\n $previous?: HTMLProgressElement | null,\n ): void {\n void $previous;\n\n this._progressObserver?.disconnect();\n this._progressObserver = null;\n\n if (!$progress) {\n this._$nativeProgress = null;\n\n return;\n }\n\n this._$nativeProgress = $progress;\n this._applyInitialValueToNative();\n this._applyIndeterminate();\n\n if (typeof MutationObserver === 'function') {\n this._progressObserver = new MutationObserver(() => {\n if (this.indeterminate) {\n this._applyIndeterminate();\n }\n\n this.requestUpdate();\n this._checkComplete();\n });\n\n this._progressObserver.observe($progress, {\n attributes: true,\n attributeFilter: ['max', 'value'],\n });\n }\n\n this.requestUpdate();\n }\n\n private _onDefaultSlotChange = (): void => {\n this._nativeProgressController.sync();\n this.requestUpdate();\n };\n\n private _applyInitialValueToNative(): void {\n if (this._value !== undefined) {\n this._applyValueToNative(this._value);\n\n return;\n }\n\n if (this._defaultValue !== undefined) {\n this._applyValueToNative(this._defaultValue);\n\n return;\n }\n\n // With no host-owned value, keep reading the live native control rather\n // than copying its initial value into component state. This preserves the\n // native element as the uncontrolled source of truth.\n }\n\n private _applyValueToNative(value: number): void {\n if (!this._$nativeProgress || this.indeterminate) {\n return;\n }\n\n this._$nativeProgress.value = value;\n }\n\n /**\n * Adds or removes the native `<progress>`'s `value` attribute/property to\n * reflect `indeterminate` — the one piece of state this component owns so\n * consumers never bind `undefined` to a live `<progress>.value` themselves.\n */\n private _applyIndeterminate(): void {\n const $progress = this._$nativeProgress;\n\n if (!$progress) {\n return;\n }\n\n if (this.indeterminate) {\n if ($progress.hasAttribute('value')) {\n this._nativeValueBeforeIndeterminate = $progress.value;\n }\n\n $progress.removeAttribute('value');\n } else {\n $progress.value =\n this._value ??\n this._defaultValue ??\n this._nativeValueBeforeIndeterminate ??\n this._nativeProgressValue;\n\n this._nativeValueBeforeIndeterminate = undefined;\n }\n }\n\n private _syncAriaAttributes($progress: HTMLProgressElement): void {\n if (this.valueText) {\n $progress.setAttribute('aria-valuetext', this.valueText);\n } else {\n $progress.removeAttribute('aria-valuetext');\n }\n\n if (this.orientation === 'vertical') {\n $progress.setAttribute('aria-orientation', 'vertical');\n } else {\n $progress.removeAttribute('aria-orientation');\n }\n }\n\n private _checkComplete(): void {\n const isComplete = !this.indeterminate && this.max > 0 && this.value >= this.max;\n\n if (isComplete && !this._completedDispatched) {\n this._completedDispatched = true;\n\n this.dispatchEvent(\n new CustomEvent('rc-progress-complete', { bubbles: true, composed: true }),\n );\n } else if (!isComplete) {\n this._completedDispatched = false;\n }\n }\n\n private _fillStyle(): string {\n const percent = this.max > 0 ? Math.min(100, Math.max(0, (this.value / this.max) * 100)) : 0;\n\n if (this.orientation === 'vertical') {\n return `inset-block-start:${(100 - percent).toFixed(3)}%;block-size:${percent.toFixed(3)}%`;\n }\n\n return `inline-size:${percent.toFixed(3)}%`;\n }\n}\n\nexport default RCProgress;\n"],"names":["displayConverter","v","_RCProgress","LitElement","NativeChildController","$progress","$previous","value","oldValue","changed","nothing","valueDisplay","html","ifDefined","percent","isComplete","css","RCProgress","__decorateClass","property"],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { R as e } from "./rc-progress-D3BdHeCV.js";
2
+ customElements.get("rc-progress") || customElements.define("rc-progress", e);
3
+ export {
4
+ e as RCProgress
5
+ };
6
+ //# sourceMappingURL=rc-progress-define.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-progress-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCProgress } from './index.js';\n\ncustomElements.get('rc-progress') || customElements.define('rc-progress', RCProgress);\n\nexport * from './index.js';\n"],"names":["RCProgress"],"mappings":";AAEA,eAAe,IAAI,aAAa,KAAK,eAAe,OAAO,eAAeA,CAAU;"}
@@ -0,0 +1,5 @@
1
+ import { R as s } from "./rc-progress-D3BdHeCV.js";
2
+ export {
3
+ s as RCProgress
4
+ };
5
+ //# sourceMappingURL=rc-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rc-progress.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1 @@
1
+ export * from './index.js';
@@ -0,0 +1 @@
1
+ export * from './rc-progress.js';
@@ -0,0 +1,132 @@
1
+ import { LitElement, nothing, PropertyValues } from 'lit';
2
+ declare global {
3
+ interface HTMLElementTagNameMap {
4
+ 'rc-progress': RCProgress;
5
+ }
6
+ interface HTMLElementEventMap {
7
+ 'rc-progress-complete': CustomEvent<Record<string, never>>;
8
+ }
9
+ }
10
+ type DisplayValue = 'inline-start' | 'inline-end' | 'overlay' | null;
11
+ /**
12
+ * Enhances a native `<progress>` with a custom track/fill and an optional
13
+ * formatted value display, following the same progressive-enhancement shape
14
+ * as `rc-slider`.
15
+ *
16
+ * Deliberately does one job: it does not render a dialog, own any phase
17
+ * state, or assume anything about where it's placed. Compose it with
18
+ * `rc-dialog`, a card, or an inline status row as needed.
19
+ *
20
+ * Label association:
21
+ * - Explicit `for`/`id`: `<label for="sync">Sync</label><rc-progress><progress id="sync" …></rc-progress>`
22
+ * - Direct `aria-label` on the `<progress>`: `<progress aria-label="Sync" …>`
23
+ *
24
+ * These patterns all work without JavaScript. The component does not render
25
+ * a label itself — the consumer is responsible for accessible naming.
26
+ *
27
+ * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-progress rc-progress docs}
28
+ *
29
+ * @slot - Place a `<progress>` element here.
30
+ * @slot value-display - Optional replacement for the rendered value text.
31
+ *
32
+ * @fires rc-progress-complete - Fires once when `value` reaches `max` while
33
+ * not indeterminate. Does not re-fire on subsequent updates while already
34
+ * at max.
35
+ *
36
+ * @attr value - Current progress value. Host writes are silent.
37
+ * @attr default-value - Initial uncontrolled value. Has no effect after the first
38
+ * host write.
39
+ * @attr indeterminate - When present, the component removes the native `<progress>`'s
40
+ * `value` attribute instead of asking the consumer to bind `undefined` to it.
41
+ * @attr display - Controls the live value display: absent (none), `overlay` (centered on
42
+ * the bar), `inline-start`, or `inline-end`.
43
+ * @attr value-text - Screen-reader value text, forwarded as `aria-valuetext` on the
44
+ * native `<progress>`. Also used as the default formatted display text when set.
45
+ * @attr orientation - Orientation, forwarded to `aria-orientation`: `horizontal` or
46
+ * `vertical`.
47
+ * @attr disabled - Visual-only dimming; native `<progress>` has no functional disabled state.
48
+ *
49
+ * @cssprop [--rc-progress-control-size=0.5rem] - Track hit-area block size.
50
+ * @cssprop [--rc-progress-vertical-size=12.5rem] - Track length when `orientation="vertical"`.
51
+ * @cssprop [--rc-progress-gap=var(--rc-control-gap)] - Gap between track and inline value display.
52
+ * @cssprop [--rc-progress-track-background=CanvasText] - Unfilled track color.
53
+ * @cssprop [--rc-progress-track-opacity=0.25] - Unfilled track opacity.
54
+ * @cssprop [--rc-progress-track-radius=var(--rc-control-radius)] - Track border radius.
55
+ * @cssprop [--rc-progress-fill-background=var(--rc-accent)] - Filled track color.
56
+ * @cssprop [--rc-progress-fill-transition-duration=150ms] - Determinate fill transition duration.
57
+ * @cssprop [--rc-progress-fill-transition-easing=ease-out] - Determinate fill transition easing.
58
+ * @cssprop [--rc-progress-value-color=var(--rc-text-disabled)] - Value display text color.
59
+ *
60
+ * @csspart root - Root layout wrapper.
61
+ * @csspart control - Track positioning wrapper.
62
+ * @csspart track - Visual track.
63
+ * @csspart fill - Filled progress segment.
64
+ * @csspart value-display - Rendered value text.
65
+ */
66
+ export declare class RCProgress extends LitElement {
67
+ static styles: import('lit').CSSResult;
68
+ private _value;
69
+ private _defaultValue;
70
+ private _valueInitialized;
71
+ /** Current progress value. */
72
+ get value(): number;
73
+ set value(value: number | undefined);
74
+ /** Initial uncontrolled value. Has no effect after the first host write. */
75
+ get defaultValue(): number | undefined;
76
+ set defaultValue(value: number | undefined);
77
+ /**
78
+ * Maximum progress value, read directly from the native `<progress>`
79
+ * child's own `max` IDL property (native default `1`) rather than
80
+ * duplicated as a separate host attribute — the consumer already owns it
81
+ * by setting `max` on the slotted `<progress>` element.
82
+ */
83
+ get max(): number;
84
+ /**
85
+ * When present, the component removes the native `<progress>`'s `value`
86
+ * attribute instead of asking the consumer to bind `undefined` to it —
87
+ * binding `undefined` to a live `<progress>.value` throws.
88
+ */
89
+ indeterminate: boolean;
90
+ /** Visual-only dimming; native `<progress>` has no functional disabled state. */
91
+ disabled: boolean;
92
+ /**
93
+ * Controls the live value display.
94
+ *
95
+ * - Absent (default) — no value shown.
96
+ * - `overlay` (or bare `display`) — centered on the bar.
97
+ * - `display="inline-start"` — rendered before the track, inline in the grid.
98
+ * - `display="inline-end"` — rendered after the track, inline in the grid.
99
+ */
100
+ display: DisplayValue;
101
+ /**
102
+ * Screen-reader value text. When set, forwarded as `aria-valuetext` on the
103
+ * native `<progress>` and used as the default formatted display text.
104
+ */
105
+ valueText: string;
106
+ /** Orientation; reflected as an attribute and forwarded to `aria-orientation`. */
107
+ orientation: 'horizontal' | 'vertical';
108
+ private _$nativeProgress;
109
+ private _completedDispatched;
110
+ private _nativeValueBeforeIndeterminate;
111
+ private _progressObserver;
112
+ private readonly _nativeProgressController;
113
+ disconnectedCallback(): void;
114
+ updated(changed: PropertyValues): void;
115
+ render(): typeof nothing | import('lit').TemplateResult<1>;
116
+ private get _displayText();
117
+ private get _nativeProgressValue();
118
+ private _setupProgress;
119
+ private _onDefaultSlotChange;
120
+ private _applyInitialValueToNative;
121
+ private _applyValueToNative;
122
+ /**
123
+ * Adds or removes the native `<progress>`'s `value` attribute/property to
124
+ * reflect `indeterminate` — the one piece of state this component owns so
125
+ * consumers never bind `undefined` to a live `<progress>.value` themselves.
126
+ */
127
+ private _applyIndeterminate;
128
+ private _syncAriaAttributes;
129
+ private _checkComplete;
130
+ private _fillStyle;
131
+ }
132
+ export default RCProgress;
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@rcarls/rc-progress",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "version": "0.0.0-next-20260921045401",
7
+ "description": "Native <progress> enhancer with a formatted value display, restyleable track/fill, and a built-in fix for the indeterminate/undefined-binding footgun.",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/richardcarls/rc-webcomponents.git",
11
+ "directory": "packages/rc-progress"
12
+ },
13
+ "homepage": "https://richardcarls.github.io/rc-webcomponents/components/rc-progress",
14
+ "license": "MIT",
15
+ "type": "module",
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "module": "./dist/rc-progress.js",
20
+ "exports": {
21
+ ".": {
22
+ "import": {
23
+ "types": "./dist/types/packages/rc-progress/src/index.d.ts",
24
+ "default": "./dist/rc-progress.js"
25
+ }
26
+ },
27
+ "./define": {
28
+ "import": {
29
+ "types": "./dist/types/packages/rc-progress/src/define.d.ts",
30
+ "default": "./dist/rc-progress-define.js"
31
+ }
32
+ }
33
+ },
34
+ "types": "./dist/types/packages/rc-progress/src/index.d.ts",
35
+ "sideEffects": [
36
+ "./dist/rc-progress-define.js"
37
+ ],
38
+ "customElements": "dist/custom-elements.json",
39
+ "scripts": {
40
+ "build": "tsc && vite build && cem analyze",
41
+ "cem:analyze": "cem analyze",
42
+ "preview": "vite preview",
43
+ "test:browser": "vitest --run",
44
+ "test:browser:chrome": "vitest --run --project=chromium",
45
+ "test:browser:firefox": "vitest --run --project=firefox"
46
+ },
47
+ "devDependencies": {
48
+ "@custom-elements-manifest/analyzer": "0.11.0",
49
+ "@vitest/browser-playwright": "4.1.5",
50
+ "lit": "^3.0.0",
51
+ "playwright": "^1.56.0",
52
+ "rollup": "^4.60.2",
53
+ "typescript": "~5.9.3",
54
+ "vite": "^7.1.7",
55
+ "vite-plugin-dts": "^4.5.4",
56
+ "vitest": "^4.0.6",
57
+ "vitest-browser-lit": "^1.0.1"
58
+ },
59
+ "dependencies": {
60
+ "@rcarls/rc-common": "0.0.0-next-20260921045401"
61
+ },
62
+ "peerDependencies": {
63
+ "lit": "^3.0.0"
64
+ }
65
+ }