@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 +82 -0
- package/README.md +35 -0
- package/dist/custom-elements.json +510 -0
- package/dist/rc-progress-D3BdHeCV.js +353 -0
- package/dist/rc-progress-D3BdHeCV.js.map +1 -0
- package/dist/rc-progress-define.js +6 -0
- package/dist/rc-progress-define.js.map +1 -0
- package/dist/rc-progress.js +5 -0
- package/dist/rc-progress.js.map +1 -0
- package/dist/types/packages/rc-progress/src/define.d.ts +1 -0
- package/dist/types/packages/rc-progress/src/index.d.ts +1 -0
- package/dist/types/packages/rc-progress/src/rc-progress.d.ts +132 -0
- package/package.json +65 -0
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 @@
|
|
|
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 @@
|
|
|
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
|
+
}
|