@adia-ai/web-components 0.0.33 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/index.js +1 -0
- package/components/step-progress/step-progress.a2ui.json +111 -0
- package/components/step-progress/step-progress.css +61 -0
- package/components/step-progress/step-progress.js +88 -0
- package/components/step-progress/step-progress.test.js +118 -0
- package/components/step-progress/step-progress.yaml +93 -0
- package/package.json +2 -2
- package/styles/components.css +1 -0
package/components/index.js
CHANGED
|
@@ -48,6 +48,7 @@ export { UIUpload } from './upload/upload.js';
|
|
|
48
48
|
export { UICard } from './card/card.js';
|
|
49
49
|
export { UIAvatar, UIAvatarGroup } from './avatar/avatar.js';
|
|
50
50
|
export { UIProgress } from './progress/progress.js';
|
|
51
|
+
export { UIStepProgress } from './step-progress/step-progress.js';
|
|
51
52
|
export { UISkeleton } from './skeleton/skeleton.js';
|
|
52
53
|
export { UIAlert } from './alert/alert.js';
|
|
53
54
|
export { UIKbd } from './kbd/kbd.js';
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://adiaui.dev/a2ui/v0_9/components/StepProgress.json",
|
|
4
|
+
"title": "StepProgress",
|
|
5
|
+
"description": "Discrete-dash step-progress indicator. One <span> dash per step in\n[total]; the first [value] dashes are filled with --a-accent. Used\nin multi-step flows (registration, onboarding, wizards). Replaces\nthe bespoke `[data-onb-progress]` + `[data-reg-progress]` markup\nthat lived in onboarding.css + registration.css with a single\nprimitive.\n",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"allOf": [
|
|
8
|
+
{
|
|
9
|
+
"$ref": "common_types.json#/$defs/ComponentCommon"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"$ref": "common_types.json#/$defs/CatalogComponentCommon"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"caption": {
|
|
17
|
+
"description": "Optional caption text rendered above the track (e.g. 'Step 3 of 10', 'Step 3 of 10 · Optional', 'All steps complete'). Hidden when empty.",
|
|
18
|
+
"type": "string",
|
|
19
|
+
"default": ""
|
|
20
|
+
},
|
|
21
|
+
"component": {
|
|
22
|
+
"const": "StepProgress"
|
|
23
|
+
},
|
|
24
|
+
"total": {
|
|
25
|
+
"description": "Total number of steps. The track renders this many dashes.",
|
|
26
|
+
"type": "number",
|
|
27
|
+
"default": 0
|
|
28
|
+
},
|
|
29
|
+
"value": {
|
|
30
|
+
"description": "Number of steps completed (1-indexed). Clamped to [0, total].",
|
|
31
|
+
"type": "number",
|
|
32
|
+
"default": 0
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"required": [
|
|
36
|
+
"component"
|
|
37
|
+
],
|
|
38
|
+
"unevaluatedProperties": false,
|
|
39
|
+
"x-adiaui": {
|
|
40
|
+
"anti_patterns": [],
|
|
41
|
+
"category": "feedback",
|
|
42
|
+
"events": {},
|
|
43
|
+
"examples": [
|
|
44
|
+
{
|
|
45
|
+
"description": "3 of 10 steps complete with caption.",
|
|
46
|
+
"a2ui": "[\n {\n \"id\": \"root\",\n \"component\": \"StepProgress\",\n \"value\": 3,\n \"total\": 10,\n \"caption\": \"Step 3 of 10\"\n }\n]",
|
|
47
|
+
"name": "in-progress"
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"description": "All steps complete.",
|
|
51
|
+
"a2ui": "[\n {\n \"id\": \"root\",\n \"component\": \"StepProgress\",\n \"value\": 10,\n \"total\": 10,\n \"caption\": \"All steps complete\"\n }\n]",
|
|
52
|
+
"name": "complete"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"description": "A 9-of-10 step that's optional.",
|
|
56
|
+
"a2ui": "[\n {\n \"id\": \"root\",\n \"component\": \"StepProgress\",\n \"value\": 9,\n \"total\": 10,\n \"caption\": \"Step 9 of 10 · Optional\"\n }\n]",
|
|
57
|
+
"name": "optional-step"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
"keywords": [
|
|
61
|
+
"progress",
|
|
62
|
+
"step",
|
|
63
|
+
"wizard",
|
|
64
|
+
"onboarding",
|
|
65
|
+
"registration",
|
|
66
|
+
"multi-step",
|
|
67
|
+
"indicator"
|
|
68
|
+
],
|
|
69
|
+
"name": "UIStepProgress",
|
|
70
|
+
"related": [
|
|
71
|
+
"progress-ui",
|
|
72
|
+
"stepper-ui"
|
|
73
|
+
],
|
|
74
|
+
"slots": {
|
|
75
|
+
"caption": {
|
|
76
|
+
"description": "Optional override of the auto-minted caption (use for rich content like icon + text). When present, the [caption] attribute is ignored."
|
|
77
|
+
},
|
|
78
|
+
"track": {
|
|
79
|
+
"description": "Optional override of the auto-minted track (rare — use only when the dash structure needs to differ)."
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"states": [
|
|
83
|
+
{
|
|
84
|
+
"description": "value=0; no dashes filled.",
|
|
85
|
+
"name": "empty"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"description": "0 < value < total; some dashes filled.",
|
|
89
|
+
"name": "in-progress"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"description": "value=total; all dashes filled.",
|
|
93
|
+
"name": "complete"
|
|
94
|
+
}
|
|
95
|
+
],
|
|
96
|
+
"synonyms": {
|
|
97
|
+
"step": [
|
|
98
|
+
"stage",
|
|
99
|
+
"phase"
|
|
100
|
+
],
|
|
101
|
+
"total": [
|
|
102
|
+
"count",
|
|
103
|
+
"length"
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
"tag": "step-progress-ui",
|
|
107
|
+
"tokens": {},
|
|
108
|
+
"traits": [],
|
|
109
|
+
"version": 1
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════
|
|
2
|
+
step-progress-ui — Discrete-dash step progress indicator
|
|
3
|
+
Replaces bespoke `[data-onb-progress]` + `[data-reg-progress]` markup.
|
|
4
|
+
═══════════════════════════════════════════ */
|
|
5
|
+
|
|
6
|
+
@scope (step-progress-ui) {
|
|
7
|
+
:where(:scope) {
|
|
8
|
+
--step-progress-gap: var(--a-space-2);
|
|
9
|
+
--step-progress-track-gap: var(--a-space-1);
|
|
10
|
+
--step-progress-dash-h: 4px;
|
|
11
|
+
--step-progress-dash-radius: var(--a-radius-full);
|
|
12
|
+
--step-progress-dash-bg: var(--a-border-subtle);
|
|
13
|
+
--step-progress-dash-bg-active: var(--a-accent);
|
|
14
|
+
--step-progress-caption-fg: var(--a-fg-muted);
|
|
15
|
+
--step-progress-caption-size: var(--a-ui-sm);
|
|
16
|
+
|
|
17
|
+
/* Sizing — match the bespoke flex shape in registration + onboarding
|
|
18
|
+
(flex:0 1 18rem; min-width:10rem). Consumers can override. */
|
|
19
|
+
--step-progress-flex: 0 1 18rem;
|
|
20
|
+
--step-progress-min-width: 10rem;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
:scope {
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
gap: var(--step-progress-gap);
|
|
27
|
+
flex: var(--step-progress-flex);
|
|
28
|
+
min-width: var(--step-progress-min-width);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/* Caption row — small, muted text. Hidden when no caption provided
|
|
32
|
+
(the [hidden] attribute is set by the JS). */
|
|
33
|
+
[slot="caption"] {
|
|
34
|
+
color: var(--step-progress-caption-fg);
|
|
35
|
+
font-size: var(--step-progress-caption-size);
|
|
36
|
+
line-height: 1.4;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[slot="caption"][hidden] {
|
|
40
|
+
display: none;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Discrete-dash track — one <span> per step. Each dash is a flex
|
|
44
|
+
item so the track scales with the column width. */
|
|
45
|
+
[slot="track"] {
|
|
46
|
+
display: flex;
|
|
47
|
+
gap: var(--step-progress-track-gap);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
[slot="track"] > span {
|
|
51
|
+
flex: 1;
|
|
52
|
+
height: var(--step-progress-dash-h);
|
|
53
|
+
border-radius: var(--step-progress-dash-radius);
|
|
54
|
+
background: var(--step-progress-dash-bg);
|
|
55
|
+
transition: background var(--a-duration-fast, 150ms) var(--a-easing, ease);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
[slot="track"] > span[data-active] {
|
|
59
|
+
background: var(--step-progress-dash-bg-active);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* <step-progress-ui value="3" total="10" caption="Step 3 of 10"></step-progress-ui>
|
|
3
|
+
* <step-progress-ui value="3" total="10"></step-progress-ui> <!-- no caption -->
|
|
4
|
+
* <step-progress-ui value="10" total="10" caption="All steps complete"></step-progress-ui>
|
|
5
|
+
*
|
|
6
|
+
* Discrete-dash step progress indicator. One dash per step in the
|
|
7
|
+
* total; the first `value` dashes carry [data-active] and paint with
|
|
8
|
+
* --a-accent. Used in registration + onboarding flows; replaces the
|
|
9
|
+
* bespoke `[data-onb-progress]` / `[data-reg-progress]` markup.
|
|
10
|
+
*
|
|
11
|
+
* Primitive shape (per ROADMAP § Done):
|
|
12
|
+
* `<step-progress-ui value="N" total="M" caption="...">`
|
|
13
|
+
*
|
|
14
|
+
* Caption is optional; pass via attribute. Free-form text passes
|
|
15
|
+
* straight through; `<text-ui>` styling can be replicated with
|
|
16
|
+
* default-slot HTML if needed (the auto-mint uses plain text).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { UIElement } from '../../core/element.js';
|
|
20
|
+
|
|
21
|
+
class UIStepProgress extends UIElement {
|
|
22
|
+
static properties = {
|
|
23
|
+
value: { type: Number, default: 0, reflect: true },
|
|
24
|
+
total: { type: Number, default: 0, reflect: true },
|
|
25
|
+
caption: { type: String, default: '', reflect: true },
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
static template = () => null;
|
|
29
|
+
|
|
30
|
+
#captionEl = null;
|
|
31
|
+
#trackEl = null;
|
|
32
|
+
|
|
33
|
+
connected() {
|
|
34
|
+
this.setAttribute('role', 'progressbar');
|
|
35
|
+
this.setAttribute('aria-valuemin', '0');
|
|
36
|
+
|
|
37
|
+
// Auto-mint internal structure if the consumer didn't provide custom slots.
|
|
38
|
+
if (!this.querySelector(':scope > [slot="caption"]') && !this.querySelector(':scope > [slot="track"]')) {
|
|
39
|
+
this.#captionEl = document.createElement('span');
|
|
40
|
+
this.#captionEl.setAttribute('slot', 'caption');
|
|
41
|
+
this.appendChild(this.#captionEl);
|
|
42
|
+
|
|
43
|
+
this.#trackEl = document.createElement('div');
|
|
44
|
+
this.#trackEl.setAttribute('slot', 'track');
|
|
45
|
+
this.appendChild(this.#trackEl);
|
|
46
|
+
} else {
|
|
47
|
+
this.#captionEl = this.querySelector(':scope > [slot="caption"]');
|
|
48
|
+
this.#trackEl = this.querySelector(':scope > [slot="track"]');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
render() {
|
|
53
|
+
const total = Math.max(0, this.total | 0);
|
|
54
|
+
const clamped = Math.max(0, Math.min(total, this.value | 0));
|
|
55
|
+
|
|
56
|
+
this.setAttribute('aria-valuemax', String(total));
|
|
57
|
+
this.setAttribute('aria-valuenow', String(clamped));
|
|
58
|
+
|
|
59
|
+
// Caption — text content if attribute set; cleared otherwise.
|
|
60
|
+
// Skip if the consumer passed in a custom caption slot (preserve their content).
|
|
61
|
+
if (this.#captionEl && !this.#captionEl.dataset.custom) {
|
|
62
|
+
this.#captionEl.textContent = this.caption || '';
|
|
63
|
+
this.#captionEl.toggleAttribute('hidden', !this.caption);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Track — sync span count with `total`; mark first `value` as active.
|
|
67
|
+
if (this.#trackEl) {
|
|
68
|
+
const existing = this.#trackEl.children.length;
|
|
69
|
+
while (this.#trackEl.children.length < total) {
|
|
70
|
+
this.#trackEl.appendChild(document.createElement('span'));
|
|
71
|
+
}
|
|
72
|
+
while (this.#trackEl.children.length > total) {
|
|
73
|
+
this.#trackEl.lastElementChild.remove();
|
|
74
|
+
}
|
|
75
|
+
for (let i = 0; i < this.#trackEl.children.length; i++) {
|
|
76
|
+
this.#trackEl.children[i].toggleAttribute('data-active', i < clamped);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
disconnected() {
|
|
82
|
+
this.#captionEl = null;
|
|
83
|
+
this.#trackEl = null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
customElements.define('step-progress-ui', UIStepProgress);
|
|
88
|
+
export { UIStepProgress };
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest';
|
|
2
|
+
import '../../core/element.js';
|
|
3
|
+
import './step-progress.js';
|
|
4
|
+
|
|
5
|
+
const tick = () => new Promise((r) => queueMicrotask(r));
|
|
6
|
+
|
|
7
|
+
function mount(html) {
|
|
8
|
+
const wrap = document.createElement('div');
|
|
9
|
+
wrap.innerHTML = html;
|
|
10
|
+
document.body.appendChild(wrap);
|
|
11
|
+
return wrap.firstElementChild;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
describe('step-progress-ui', () => {
|
|
15
|
+
beforeEach(() => { document.body.innerHTML = ''; });
|
|
16
|
+
|
|
17
|
+
it('registers as a custom element', () => {
|
|
18
|
+
expect(customElements.get('step-progress-ui')).toBeDefined();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('sets role=progressbar + aria-value{min,max,now}', () => {
|
|
22
|
+
const el = mount('<step-progress-ui value="3" total="10"></step-progress-ui>');
|
|
23
|
+
expect(el.getAttribute('role')).toBe('progressbar');
|
|
24
|
+
expect(el.getAttribute('aria-valuemin')).toBe('0');
|
|
25
|
+
expect(el.getAttribute('aria-valuemax')).toBe('10');
|
|
26
|
+
expect(el.getAttribute('aria-valuenow')).toBe('3');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('auto-mints a caption span + track div', () => {
|
|
30
|
+
const el = mount('<step-progress-ui value="2" total="5" caption="Step 2 of 5"></step-progress-ui>');
|
|
31
|
+
expect(el.querySelector(':scope > [slot="caption"]')).not.toBeNull();
|
|
32
|
+
expect(el.querySelector(':scope > [slot="track"]')).not.toBeNull();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('renders one <span> per step in the track', () => {
|
|
36
|
+
const el = mount('<step-progress-ui value="2" total="5"></step-progress-ui>');
|
|
37
|
+
const dashes = el.querySelectorAll(':scope > [slot="track"] > span');
|
|
38
|
+
expect(dashes.length).toBe(5);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('marks the first `value` dashes as [data-active]', () => {
|
|
42
|
+
const el = mount('<step-progress-ui value="3" total="5"></step-progress-ui>');
|
|
43
|
+
const dashes = el.querySelectorAll(':scope > [slot="track"] > span');
|
|
44
|
+
expect(dashes[0].hasAttribute('data-active')).toBe(true);
|
|
45
|
+
expect(dashes[1].hasAttribute('data-active')).toBe(true);
|
|
46
|
+
expect(dashes[2].hasAttribute('data-active')).toBe(true);
|
|
47
|
+
expect(dashes[3].hasAttribute('data-active')).toBe(false);
|
|
48
|
+
expect(dashes[4].hasAttribute('data-active')).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('renders the caption text in the caption slot', () => {
|
|
52
|
+
const el = mount('<step-progress-ui value="3" total="10" caption="Step 3 of 10"></step-progress-ui>');
|
|
53
|
+
expect(el.querySelector('[slot="caption"]').textContent).toBe('Step 3 of 10');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('hides the caption span when caption is empty', () => {
|
|
57
|
+
const el = mount('<step-progress-ui value="2" total="5"></step-progress-ui>');
|
|
58
|
+
expect(el.querySelector('[slot="caption"]').hasAttribute('hidden')).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('updates the dash + aria when value changes', async () => {
|
|
62
|
+
const el = mount('<step-progress-ui value="2" total="5"></step-progress-ui>');
|
|
63
|
+
el.value = 4;
|
|
64
|
+
await tick();
|
|
65
|
+
const dashes = el.querySelectorAll(':scope > [slot="track"] > span');
|
|
66
|
+
expect(el.getAttribute('aria-valuenow')).toBe('4');
|
|
67
|
+
expect(dashes[3].hasAttribute('data-active')).toBe(true);
|
|
68
|
+
expect(dashes[4].hasAttribute('data-active')).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('grows the dash count when total increases', async () => {
|
|
72
|
+
const el = mount('<step-progress-ui value="2" total="5"></step-progress-ui>');
|
|
73
|
+
expect(el.querySelectorAll('[slot="track"] > span').length).toBe(5);
|
|
74
|
+
el.total = 8;
|
|
75
|
+
await tick();
|
|
76
|
+
expect(el.querySelectorAll('[slot="track"] > span').length).toBe(8);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('shrinks the dash count when total decreases', async () => {
|
|
80
|
+
const el = mount('<step-progress-ui value="2" total="8"></step-progress-ui>');
|
|
81
|
+
expect(el.querySelectorAll('[slot="track"] > span').length).toBe(8);
|
|
82
|
+
el.total = 4;
|
|
83
|
+
await tick();
|
|
84
|
+
expect(el.querySelectorAll('[slot="track"] > span').length).toBe(4);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('clamps value to [0, total]', () => {
|
|
88
|
+
const el = mount('<step-progress-ui value="20" total="5"></step-progress-ui>');
|
|
89
|
+
const dashes = el.querySelectorAll(':scope > [slot="track"] > span');
|
|
90
|
+
expect(el.getAttribute('aria-valuenow')).toBe('5');
|
|
91
|
+
for (const dash of dashes) {
|
|
92
|
+
expect(dash.hasAttribute('data-active')).toBe(true);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('handles value=0 (empty state) — no dashes active', () => {
|
|
97
|
+
const el = mount('<step-progress-ui value="0" total="5"></step-progress-ui>');
|
|
98
|
+
const dashes = el.querySelectorAll(':scope > [slot="track"] > span');
|
|
99
|
+
expect(el.getAttribute('aria-valuenow')).toBe('0');
|
|
100
|
+
for (const dash of dashes) {
|
|
101
|
+
expect(dash.hasAttribute('data-active')).toBe(false);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('handles value=total (complete state) — all dashes active', () => {
|
|
106
|
+
const el = mount('<step-progress-ui value="5" total="5" caption="All steps complete"></step-progress-ui>');
|
|
107
|
+
const dashes = el.querySelectorAll(':scope > [slot="track"] > span');
|
|
108
|
+
for (const dash of dashes) {
|
|
109
|
+
expect(dash.hasAttribute('data-active')).toBe(true);
|
|
110
|
+
}
|
|
111
|
+
expect(el.querySelector('[slot="caption"]').textContent).toBe('All steps complete');
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('survives disconnect without throwing', () => {
|
|
115
|
+
const el = mount('<step-progress-ui value="3" total="10"></step-progress-ui>');
|
|
116
|
+
expect(() => el.remove()).not.toThrow();
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
$schema: ../../../../scripts/schemas/component.yaml.schema.json
|
|
2
|
+
name: UIStepProgress
|
|
3
|
+
tag: step-progress-ui
|
|
4
|
+
component: StepProgress
|
|
5
|
+
category: feedback
|
|
6
|
+
version: 1
|
|
7
|
+
description: |
|
|
8
|
+
Discrete-dash step-progress indicator. One <span> dash per step in
|
|
9
|
+
[total]; the first [value] dashes are filled with --a-accent. Used
|
|
10
|
+
in multi-step flows (registration, onboarding, wizards). Replaces
|
|
11
|
+
the bespoke `[data-onb-progress]` + `[data-reg-progress]` markup
|
|
12
|
+
that lived in onboarding.css + registration.css with a single
|
|
13
|
+
primitive.
|
|
14
|
+
|
|
15
|
+
props:
|
|
16
|
+
value:
|
|
17
|
+
type: number
|
|
18
|
+
default: 0
|
|
19
|
+
description: "Number of steps completed (1-indexed). Clamped to [0, total]."
|
|
20
|
+
total:
|
|
21
|
+
type: number
|
|
22
|
+
default: 0
|
|
23
|
+
description: "Total number of steps. The track renders this many dashes."
|
|
24
|
+
caption:
|
|
25
|
+
type: string
|
|
26
|
+
default: ''
|
|
27
|
+
description: "Optional caption text rendered above the track (e.g. 'Step 3 of 10', 'Step 3 of 10 · Optional', 'All steps complete'). Hidden when empty."
|
|
28
|
+
|
|
29
|
+
events: {}
|
|
30
|
+
|
|
31
|
+
slots:
|
|
32
|
+
caption:
|
|
33
|
+
description: "Optional override of the auto-minted caption (use for rich content like icon + text). When present, the [caption] attribute is ignored."
|
|
34
|
+
track:
|
|
35
|
+
description: "Optional override of the auto-minted track (rare — use only when the dash structure needs to differ)."
|
|
36
|
+
|
|
37
|
+
states:
|
|
38
|
+
- name: empty
|
|
39
|
+
description: "value=0; no dashes filled."
|
|
40
|
+
- name: in-progress
|
|
41
|
+
description: "0 < value < total; some dashes filled."
|
|
42
|
+
- name: complete
|
|
43
|
+
description: "value=total; all dashes filled."
|
|
44
|
+
|
|
45
|
+
traits: []
|
|
46
|
+
tokens: {}
|
|
47
|
+
a2ui:
|
|
48
|
+
rules: []
|
|
49
|
+
anti_patterns: []
|
|
50
|
+
|
|
51
|
+
examples:
|
|
52
|
+
- name: in-progress
|
|
53
|
+
description: 3 of 10 steps complete with caption.
|
|
54
|
+
a2ui: >-
|
|
55
|
+
[
|
|
56
|
+
{
|
|
57
|
+
"id": "root",
|
|
58
|
+
"component": "StepProgress",
|
|
59
|
+
"value": 3,
|
|
60
|
+
"total": 10,
|
|
61
|
+
"caption": "Step 3 of 10"
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
- name: complete
|
|
65
|
+
description: All steps complete.
|
|
66
|
+
a2ui: >-
|
|
67
|
+
[
|
|
68
|
+
{
|
|
69
|
+
"id": "root",
|
|
70
|
+
"component": "StepProgress",
|
|
71
|
+
"value": 10,
|
|
72
|
+
"total": 10,
|
|
73
|
+
"caption": "All steps complete"
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
- name: optional-step
|
|
77
|
+
description: A 9-of-10 step that's optional.
|
|
78
|
+
a2ui: >-
|
|
79
|
+
[
|
|
80
|
+
{
|
|
81
|
+
"id": "root",
|
|
82
|
+
"component": "StepProgress",
|
|
83
|
+
"value": 9,
|
|
84
|
+
"total": 10,
|
|
85
|
+
"caption": "Step 9 of 10 · Optional"
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
|
|
89
|
+
keywords: [progress, step, wizard, onboarding, registration, multi-step, indicator]
|
|
90
|
+
synonyms:
|
|
91
|
+
step: [stage, phase]
|
|
92
|
+
total: [count, length]
|
|
93
|
+
related: [progress-ui, stepper-ui]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adia-ai/web-components",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "AdiaUI web components — vanilla custom elements. A2UI runtime (renderer, registry, streams, wiring) lives in @adia-ai/a2ui-utils.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"./core/provider.js"
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@adia-ai/a2ui-utils": "^0.0
|
|
35
|
+
"@adia-ai/a2ui-utils": "^0.2.0"
|
|
36
36
|
},
|
|
37
37
|
"publishConfig": {
|
|
38
38
|
"access": "public",
|
package/styles/components.css
CHANGED
|
@@ -70,6 +70,7 @@
|
|
|
70
70
|
@import "../components/nav/nav.css";
|
|
71
71
|
@import "../components/nav-group/nav-group.css";
|
|
72
72
|
@import "../components/nav-item/nav-item.css";
|
|
73
|
+
@import "../components/step-progress/step-progress.css";
|
|
73
74
|
@import "../components/otp-input/otp-input.css";
|
|
74
75
|
@import "../components/image/image.css";
|
|
75
76
|
@import "../components/search/search.css";
|