@c2n/steps 0.0.10
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/LICENSE +21 -0
- package/README.md +69 -0
- package/dist/step-CsDVe4w8.js +220 -0
- package/dist/step-types.js +0 -0
- package/dist/step.js +2 -0
- package/dist/steps.js +201 -0
- package/package.json +84 -0
- package/react.d.ts +26 -0
- package/react.js +3 -0
- package/types/src/step-icons.d.ts +7 -0
- package/types/src/step-icons.d.ts.map +1 -0
- package/types/src/step-types.d.ts +64 -0
- package/types/src/step-types.d.ts.map +1 -0
- package/types/src/step.d.ts +185 -0
- package/types/src/step.d.ts.map +1 -0
- package/types/src/steps.d.ts +164 -0
- package/types/src/steps.d.ts.map +1 -0
- package/vue.d.ts +40 -0
- package/vue.js +3 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Nguyen Thai Vinh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# @c2n/steps
|
|
2
|
+
|
|
3
|
+
A vertical list of steps: the trace of a task as it runs, or a wizard's progress.
|
|
4
|
+
|
|
5
|
+
A step with sub-steps is a **group**, and a group is a disclosure — its own row is the summary, its sub-steps are
|
|
6
|
+
the detail. Every step is a row and every row is visible: a group starts expanded and nothing folds one away on its
|
|
7
|
+
own. A sub-step is indented until its marker sits under its parent's label, and that is the whole tree — no chevron
|
|
8
|
+
column, no rules, unless you ask for them. `collapsed` in the markup starts a stage folded, and the run only ever
|
|
9
|
+
brings a folded stage back into view when it starts running or something in it fails.
|
|
10
|
+
|
|
11
|
+
A parent that authors no `status` takes the most urgent one under it, so a stage reports that it is running, or
|
|
12
|
+
that something below it failed, on its own.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @c2n/steps
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Markup
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<script type="module">
|
|
22
|
+
import '@c2n/steps'
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<c2-steps aria-label="Pipeline">
|
|
26
|
+
<c2-step label="build" trailing="24 s">
|
|
27
|
+
<c2-step status="success" label="install dependencies" trailing="19 s"></c2-step>
|
|
28
|
+
<c2-step status="success" label="compile" trailing="5 s"></c2-step>
|
|
29
|
+
</c2-step>
|
|
30
|
+
<c2-step label="test">
|
|
31
|
+
<c2-step status="success" label="unit" trailing="8 s"></c2-step>
|
|
32
|
+
<c2-step status="running" label="e2e"></c2-step>
|
|
33
|
+
</c2-step>
|
|
34
|
+
</c2-steps>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Data
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
const trace = document.querySelector('c2-steps')
|
|
41
|
+
|
|
42
|
+
trace.steps = [
|
|
43
|
+
{ id: 'build', label: 'build', children: [{ id: 'install', label: 'install dependencies' }] },
|
|
44
|
+
{ id: 'test', label: 'test', children: [{ id: 'e2e', label: 'e2e' }] },
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
// One step at a time, without rebuilding the array.
|
|
48
|
+
trace.updateStep('install', { status: 'running' })
|
|
49
|
+
trace.updateStep('install', { status: 'success', trailing: '19 s' })
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`collapseAll()` folds every group away and `expandAll()` brings them back; a `step-toggle` event bubbles to the
|
|
53
|
+
list whenever a group is folded or unfolded.
|
|
54
|
+
|
|
55
|
+
A step that arrives while the list is already on screen grows into place, and a marker gives one beat as its
|
|
56
|
+
status settles — both only for things that actually change, so a trace drawn complete sits still.
|
|
57
|
+
`--c2-step--enter-duration: 0s` turns the arrival off and `prefers-reduced-motion` turns both off. Give every node
|
|
58
|
+
a stable `id`, or a step is identified by its position and inserting one recreates every row after it.
|
|
59
|
+
|
|
60
|
+
Everything the markup fills with a slot, the data-driven mode fills with a renderer handed the same node: `marker`
|
|
61
|
+
→ `renderMarker`, `label` → `renderLabel`, `detail` → `renderDetail`, `trailing` → `renderTrailing`, `toggle` →
|
|
62
|
+
`renderToggle`, plus `renderItem` for a row's text all at once. The marker and the disclosure are their own
|
|
63
|
+
columns, so they keep their renderers alongside `renderItem`.
|
|
64
|
+
|
|
65
|
+
Statuses are `pending`, `current`, `running`, `success`, `error`, `warning` and `skipped`. `marker` is `icon`
|
|
66
|
+
(default), `number` — which draws a dotted path, so `3.1` is the first sub-step of the third step — or `none`.
|
|
67
|
+
`current` is the wizard shortcut: the index of the active top-level step.
|
|
68
|
+
|
|
69
|
+
Everything visual is a CSS custom property; the full list is in `custom-elements.json` and on the docs site.
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import { LitElement, html, nothing, unsafeCSS } from "lit";
|
|
2
|
+
import { property, state } from "lit/decorators.js";
|
|
3
|
+
import { customElement } from "@c2n/core/element-helper.js";
|
|
4
|
+
import { classMap } from "lit/directives/class-map.js";
|
|
5
|
+
//#region src/step-icons.ts
|
|
6
|
+
/** What a screen reader reads for each status, since the marker is a glyph. */
|
|
7
|
+
var STATUS_LABELS = {
|
|
8
|
+
pending: "Pending",
|
|
9
|
+
current: "Current",
|
|
10
|
+
running: "Running",
|
|
11
|
+
success: "Completed",
|
|
12
|
+
error: "Failed",
|
|
13
|
+
warning: "Completed with warnings",
|
|
14
|
+
skipped: "Skipped"
|
|
15
|
+
};
|
|
16
|
+
/** The states that draw a glyph. The rest are drawn by the marker's ring alone. */
|
|
17
|
+
var STATUS_ICONS = {
|
|
18
|
+
success: html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
19
|
+
<path d="M20 6 9 17l-5-5"></path>
|
|
20
|
+
</svg>`,
|
|
21
|
+
error: html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
|
|
22
|
+
<path d="M18 6 6 18M6 6l12 12"></path>
|
|
23
|
+
</svg>`,
|
|
24
|
+
warning: html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
|
|
25
|
+
<path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"></path>
|
|
26
|
+
<path d="M12 9v4M12 17h.01"></path>
|
|
27
|
+
</svg>`,
|
|
28
|
+
skipped: html`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round">
|
|
29
|
+
<path d="M5 12h14"></path>
|
|
30
|
+
</svg>`
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The status that stands for a group: the most urgent thing inside it. `skipped` only wins when there is nothing
|
|
34
|
+
* else — a group where one step ran and the rest were skipped still reports that it ran. An empty group is
|
|
35
|
+
* `pending`, because nothing in it has happened.
|
|
36
|
+
*/
|
|
37
|
+
var ROLLUP_ORDER = [
|
|
38
|
+
"error",
|
|
39
|
+
"running",
|
|
40
|
+
"current",
|
|
41
|
+
"warning",
|
|
42
|
+
"pending"
|
|
43
|
+
];
|
|
44
|
+
function rollupStatus(statuses) {
|
|
45
|
+
if (!statuses.length) return "pending";
|
|
46
|
+
for (const status of ROLLUP_ORDER) if (statuses.includes(status)) return status;
|
|
47
|
+
return statuses.every((status) => status === "skipped") ? "skipped" : "success";
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/step.scss?inline
|
|
51
|
+
var step_default = "@charset \"UTF-8\";\n/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n/**\n * A grid of one row rather than a block, so a step arriving in a running trace can grow from `0fr` to `1fr` —\n * the one way to animate to a height nobody knows in advance.\n */\n:host {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: 1fr;\n}\n\n:host([hidden]) {\n display: none;\n}\n\n.c2-step__frame {\n min-width: 0;\n min-height: 0;\n}\n\n:host([entering]) {\n animation: c2-step-enter var(--c2-step--enter-duration,260ms) cubic-bezier(0.2, 0, 0, 1);\n}\n\n:host([entering]) .c2-step__frame {\n overflow: hidden;\n}\n\n@keyframes c2-step-enter {\n from {\n grid-template-rows: 0fr;\n opacity: 0;\n translate: 0 var(--c2-step--enter-translate,-4px);\n }\n to {\n grid-template-rows: 1fr;\n opacity: 1;\n translate: none;\n }\n}\n.c2-step__details {\n display: block;\n}\n\n.c2-step__details:not([open]) .c2-step__children {\n display: none;\n}\n\n.c2-step__row {\n display: flex;\n align-items: flex-start;\n gap: var(--c2-step__row--gap,10px);\n box-sizing: border-box;\n padding: var(--c2-step__row--padding-block,7px) var(--c2-step__row--padding-inline,12px);\n padding-inline-start: calc(var(--c2-step__row--indent,calc(var(--c2-step__marker--size, 16px) + var(--c2-step__row--gap, 10px))) * var(--level, 0) + var(--c2-step__row--padding-inline,12px));\n position: relative;\n background: var(--c2-step__row--background);\n border-radius: var(--c2-step__row--border-radius);\n border-bottom: var(--c2-step__row--border-bottom,1px solid #e4e4e7);\n transition: background-color var(--c2-step--transition-duration,150ms) cubic-bezier(0.2, 0, 0, 1);\n}\n.c2-step__row:hover {\n background: var(--c2-step__row__hover--background,var(--c2-step__row--background));\n}\n\n/**\n * One vertical rule per ancestor level, each sitting where that ancestor's own chevron sits, so the nesting reads\n * as a tree rather than as rows that happen to start further in.\n *\n * The box starts at the first ancestor's chevron centre and is `level * indent` wide, so the repeating tile lands\n * a rule exactly on every ancestor and none anywhere else — offsetting the gradient inside a box that starts at 0\n * repeats in both directions and draws a spurious rule before the first level. `--c2-step__guide--width: 0px`\n * turns them off: a zero-wide colour band paints nothing.\n */\n.c2-step__row::before {\n content: \"\";\n position: absolute;\n inset-block: 0;\n inset-inline-start: calc(var(--c2-step__row--padding-inline,12px) + var(--c2-step__toggle--size,14px) / 2);\n inline-size: calc(var(--c2-step__row--indent,calc(var(--c2-step__marker--size, 16px) + var(--c2-step__row--gap, 10px))) * var(--level, 0));\n pointer-events: none;\n background-image: repeating-linear-gradient(to right, var(--c2-step__guide--color,#e4e4e7) 0 var(--c2-step__guide--width,0px), transparent var(--c2-step__guide--width,0px) var(--c2-step__row--indent,calc(var(--c2-step__marker--size, 16px) + var(--c2-step__row--gap, 10px))));\n}\n\n.c2-step__row:dir(rtl)::before {\n background-image: repeating-linear-gradient(to left, var(--c2-step__guide--color,#e4e4e7) 0 var(--c2-step__guide--width,0px), transparent var(--c2-step__guide--width,0px) var(--c2-step__row--indent,calc(var(--c2-step__marker--size, 16px) + var(--c2-step__row--gap, 10px))));\n}\n\n:host(:not([grouped])) .c2-step__row::before {\n display: none;\n}\n\nsummary.c2-step__row {\n cursor: pointer;\n list-style: none;\n user-select: none;\n}\nsummary.c2-step__row::-webkit-details-marker {\n display: none;\n}\nsummary.c2-step__row:focus-visible {\n outline: var(--c2-step__row--outline,2px solid rgb(2, 101, 220));\n outline-offset: -2px;\n}\n\n:host([last]) .c2-step__row:not(:has(~ .c2-step__children:not([hidden]))) {\n border-bottom: none;\n}\n\n:host([last][has-children]:not([collapsed])) > .c2-step__frame > .c2-step__details > summary.c2-step__row {\n border-bottom: var(--c2-step__row--border-bottom,1px solid #e4e4e7);\n}\n\n/**\n * The disclosure affordance, and there is none by default: a trace is a list of rows, and a column of chevrons\n * down the side of it is noise. The row is a `<summary>`, so it is clickable and focusable with nothing drawn.\n * Fill the `toggle` slot to put a marker of your own there, and it takes a column on every row so they line up.\n */\n.c2-step__toggle {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: var(--c2-step__toggle--size,14px);\n height: calc(var(--c2-step__label--font-size,13px) * 1.5);\n margin-inline-end: calc(var(--c2-step__toggle--gap,4px) - var(--c2-step__row--gap,10px));\n color: var(--c2-step__toggle--color,#a1a1aa);\n transition: transform var(--c2-step--transition-duration,150ms) cubic-bezier(0.2, 0, 0, 1);\n}\n.c2-step__toggle[hidden] {\n display: none;\n}\n.c2-step__toggle svg {\n width: 100%;\n height: 100%;\n}\n.c2-step__toggle ::slotted(*) {\n width: 100%;\n height: 100%;\n}\n\n:host([has-children]:not([collapsed])) .c2-step__toggle {\n transform: rotate(90deg);\n}\n\n.c2-step__gutter {\n display: flex;\n flex-direction: column;\n align-items: center;\n flex: none;\n align-self: stretch;\n gap: var(--c2-step__rail--gap,4px);\n}\n\n.c2-step__marker {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n box-sizing: border-box;\n width: var(--c2-step__marker--size,16px);\n height: var(--c2-step__marker--size,16px);\n margin-top: calc((var(--c2-step__label--font-size,13px) * 1.5 - var(--c2-step__marker--size,16px)) / 2);\n font-size: var(--c2-step__marker--font-size,10px);\n font-weight: var(--c2-step__marker--font-weight,600);\n font-variant-numeric: tabular-nums;\n line-height: 1;\n color: var(--c2-step__marker--color,#71717a);\n background: var(--c2-step__marker--background,transparent);\n border: 1px solid transparent;\n border-radius: var(--c2-step__marker--border-radius,999px);\n transition: color var(--c2-step--transition-duration,150ms) cubic-bezier(0.2, 0, 0, 1), border-color var(--c2-step--transition-duration,150ms) cubic-bezier(0.2, 0, 0, 1), background-color var(--c2-step--transition-duration,150ms) cubic-bezier(0.2, 0, 0, 1);\n}\n.c2-step__marker svg {\n width: 68%;\n height: 68%;\n}\n.c2-step__marker ::slotted(*) {\n width: 100%;\n height: 100%;\n}\n\n.c2-step__rail {\n flex: 1 1 auto;\n width: var(--c2-step__rail--width,0px);\n min-height: 0;\n background: var(--c2-step__rail--color,#e4e4e7);\n border-radius: var(--c2-step__rail--width,0px);\n}\n\n:host([last]:not([has-children])) .c2-step__rail,\n:host([last][has-children][collapsed]) .c2-step__rail {\n visibility: hidden;\n}\n\n:host([marker=none]) .c2-step__gutter {\n display: none;\n}\n\n.c2-step__text {\n display: flex;\n flex-direction: var(--c2-step__text--flex-direction,row);\n align-items: var(--c2-step__text--align-items,baseline);\n flex: 1 1 auto;\n min-width: 0;\n gap: var(--c2-step__detail--row-gap,2px) var(--c2-step__detail--gap,8px);\n}\n\n.c2-step__label {\n transition: color var(--c2-step--transition-duration,150ms) cubic-bezier(0.2, 0, 0, 1);\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--c2-step__label--color,#18181b);\n font-family: var(--c2-step__label--font-family,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);\n font-size: var(--c2-step__label--font-size,13px);\n font-weight: var(--c2-step__label--font-weight,500);\n line-height: 1.5;\n}\n\n.c2-step__detail {\n flex: 0 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--c2-step__detail--color,#71717a);\n font-family: var(--c2-step__label--font-family,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);\n font-size: var(--c2-step__detail--font-size,var(--c2-step__label--font-size,13px));\n font-weight: var(--c2-step__detail--font-weight,400);\n line-height: 1.5;\n}\n.c2-step__detail[hidden] {\n display: none;\n}\n\n.c2-step__trailing {\n flex: none;\n white-space: nowrap;\n color: var(--c2-step__trailing--color,#71717a);\n font-family: var(--c2-step__label--font-family,ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);\n font-size: var(--c2-step__trailing--font-size,var(--c2-step__label--font-size,13px));\n font-weight: var(--c2-step__trailing--font-weight,400);\n font-variant-numeric: tabular-nums;\n line-height: 1.5;\n}\n.c2-step__trailing[hidden] {\n display: none;\n}\n\n.c2-step__status-text {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n\n.c2-step__children[hidden] {\n display: none;\n}\n\n.c2-step__row.is-pending .c2-step__marker {\n border: var(--c2-step__marker--border,1px solid #bcbcc6);\n}\n\n.c2-step__row.is-success .c2-step__marker {\n color: var(--c2-step__success--color,#16a34a);\n}\n\n.c2-step__row.is-error .c2-step__marker {\n color: var(--c2-step__error--color,#dc2626);\n}\n\n.c2-step__row.is-warning .c2-step__marker {\n color: var(--c2-step__warning--color,#d97706);\n}\n\n.c2-step__row.is-running .c2-step__marker {\n color: var(--c2-step__running--color,rgb(2, 101, 220));\n}\n\n.c2-step__row.is-current .c2-step__marker {\n color: var(--c2-step__current--color,rgb(2, 101, 220));\n}\n\n.c2-step__row.is-current .c2-step__marker,\n.c2-step__row.is-running .c2-step__marker {\n border: var(--c2-step__marker--border,1px solid #bcbcc6);\n border-color: currentColor;\n box-shadow: inset 0 0 0 calc(var(--c2-step__marker--size,16px) / 5) currentColor;\n}\n\n/**\n * A number has to sit inside something, whatever the status — but a dotted path is not a glyph, and `2.2.1` in a\n * round box the size of a checkmark spills out over its own border. In number mode the marker keeps its height and\n * grows sideways instead: a single digit is still the circle, a path is a pill.\n */\n:host([marker=number]) .c2-step__marker {\n width: auto;\n min-width: var(--c2-step__marker--size,16px);\n padding-inline: var(--c2-step__marker--padding-inline,3px);\n white-space: nowrap;\n border: var(--c2-step__marker--border,1px solid #bcbcc6);\n}\n\n:host([marker=number]) .c2-step__row.is-success .c2-step__marker,\n:host([marker=number]) .c2-step__row.is-error .c2-step__marker,\n:host([marker=number]) .c2-step__row.is-warning .c2-step__marker,\n:host([marker=number]) .c2-step__row.is-current .c2-step__marker,\n:host([marker=number]) .c2-step__row.is-running .c2-step__marker {\n border-color: currentColor;\n}\n\n:host([marker=number]) .c2-step__row.is-current .c2-step__marker,\n:host([marker=number]) .c2-step__row.is-running .c2-step__marker {\n box-shadow: none;\n}\n\n.c2-step__row.is-skipped .c2-step__marker {\n color: var(--c2-step__skipped--color,#71717a);\n}\n.c2-step__row.is-skipped .c2-step__label {\n color: var(--c2-step__skipped--color,#71717a);\n}\n\n/**\n * A status that settles gives the marker one beat. `settling` is written by the step when its status changes after\n * the first pass and taken off again when the beat ends, so a trace drawn complete sits still and only a step that\n * actually finishes in front of you moves. A step that is still growing into place has enough going on already.\n */\n:host([settling]:not([entering])) .c2-step__row.is-success .c2-step__marker,\n:host([settling]:not([entering])) .c2-step__row.is-error .c2-step__marker,\n:host([settling]:not([entering])) .c2-step__row.is-warning .c2-step__marker,\n:host([settling]:not([entering])) .c2-step__row.is-skipped .c2-step__marker {\n animation: c2-step-settle var(--c2-step--transition-duration,150ms) cubic-bezier(0.2, 0, 0, 1);\n}\n\n@keyframes c2-step-settle {\n from {\n scale: 0.55;\n }\n 60% {\n scale: 1.12;\n }\n to {\n scale: 1;\n }\n}\n.c2-step__row.is-running .c2-step__marker {\n border-style: solid;\n border-top-color: transparent;\n box-shadow: none;\n animation: c2-step-spin 900ms linear infinite;\n}\n\n:host([marker=number]) .c2-step__row.is-running .c2-step__marker {\n animation: none;\n border-top-color: currentColor;\n}\n\n@keyframes c2-step-spin {\n to {\n transform: rotate(360deg);\n }\n}\n@media (prefers-reduced-motion: reduce) {\n .c2-step__row.is-running .c2-step__marker {\n animation: none;\n border-top-color: currentColor;\n }\n :host([entering]),\n :host([settling]) .c2-step__row .c2-step__marker {\n animation: none;\n }\n .c2-step__row,\n .c2-step__marker,\n .c2-step__label,\n .c2-step__toggle {\n transition: none;\n }\n}";
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region \0@oxc-project+runtime@0.148.0/helpers/esm/decorate.js
|
|
54
|
+
function __decorate(decorators, target, key, desc) {
|
|
55
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
56
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
57
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
58
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/step.ts
|
|
62
|
+
/** The statuses that bring a folded-away stage back into view. Nothing ever folds one away on its own. */
|
|
63
|
+
var STATUS_REOPENS = /* @__PURE__ */ new Set([
|
|
64
|
+
"running",
|
|
65
|
+
"current",
|
|
66
|
+
"error",
|
|
67
|
+
"warning"
|
|
68
|
+
]);
|
|
69
|
+
var Step = class Step extends LitElement {
|
|
70
|
+
constructor(..._args) {
|
|
71
|
+
super(..._args);
|
|
72
|
+
this.status = "pending";
|
|
73
|
+
this.label = "";
|
|
74
|
+
this.detail = "";
|
|
75
|
+
this.trailing = "";
|
|
76
|
+
this.collapsed = false;
|
|
77
|
+
this.level = 0;
|
|
78
|
+
this.position = 1;
|
|
79
|
+
this.path = "1";
|
|
80
|
+
this.last = false;
|
|
81
|
+
this.marker = "icon";
|
|
82
|
+
this.grouped = false;
|
|
83
|
+
this.hasChildren = false;
|
|
84
|
+
this.hasDetailSlot = false;
|
|
85
|
+
this.hasTrailingSlot = false;
|
|
86
|
+
this.hasToggleSlot = false;
|
|
87
|
+
this.handleAnimationEnd = (event) => {
|
|
88
|
+
const name = event.animationName;
|
|
89
|
+
if (name.includes("step-enter") && event.target === this) this.removeAttribute("entering");
|
|
90
|
+
if (name.includes("step-settle")) this.removeAttribute("settling");
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
static {
|
|
94
|
+
this.styles = unsafeCSS(step_default);
|
|
95
|
+
}
|
|
96
|
+
connectedCallback() {
|
|
97
|
+
super.connectedCallback();
|
|
98
|
+
this.setAttribute("role", "listitem");
|
|
99
|
+
this.addEventListener("animationend", this.handleAnimationEnd);
|
|
100
|
+
this.renderRoot.addEventListener("animationend", this.handleAnimationEnd);
|
|
101
|
+
}
|
|
102
|
+
disconnectedCallback() {
|
|
103
|
+
this.removeEventListener("animationend", this.handleAnimationEnd);
|
|
104
|
+
this.renderRoot.removeEventListener("animationend", this.handleAnimationEnd);
|
|
105
|
+
super.disconnectedCallback();
|
|
106
|
+
}
|
|
107
|
+
firstUpdated() {
|
|
108
|
+
this.syncHasChildren();
|
|
109
|
+
}
|
|
110
|
+
willUpdate(changed) {
|
|
111
|
+
if (!changed.has("status") || changed.get("status") === void 0) return;
|
|
112
|
+
if (STATUS_REOPENS.has(this.status)) this.collapsed = false;
|
|
113
|
+
}
|
|
114
|
+
updated(changed) {
|
|
115
|
+
if (changed.has("status") && changed.get("status") !== void 0) this.toggleAttribute("settling", true);
|
|
116
|
+
if (changed.has("level")) this.style.setProperty("--level", String(this.level));
|
|
117
|
+
if (changed.has("last")) this.toggleAttribute("last", this.last);
|
|
118
|
+
if (changed.has("marker")) this.setAttribute("marker", this.marker);
|
|
119
|
+
if (changed.has("grouped")) this.toggleAttribute("grouped", this.grouped);
|
|
120
|
+
if (changed.has("hasChildren")) this.toggleAttribute("has-children", this.hasChildren);
|
|
121
|
+
if (changed.has("collapsed") && changed.get("collapsed") !== void 0 && this.hasChildren) this.dispatchEvent(new CustomEvent("step-toggle", {
|
|
122
|
+
detail: {
|
|
123
|
+
collapsed: this.collapsed,
|
|
124
|
+
path: this.path
|
|
125
|
+
},
|
|
126
|
+
bubbles: true
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
/** These three collapse when empty, so their rows have to know whether the slot was filled. */
|
|
130
|
+
handleSlotChange(name, event) {
|
|
131
|
+
const filled = event.target.assignedNodes({ flatten: true }).some((node) => node.nodeType === Node.ELEMENT_NODE || (node.textContent ?? "").trim() !== "");
|
|
132
|
+
if (name === "detail") this.hasDetailSlot = filled;
|
|
133
|
+
else if (name === "trailing") this.hasTrailingSlot = filled;
|
|
134
|
+
else this.hasToggleSlot = filled;
|
|
135
|
+
}
|
|
136
|
+
/** Astro wraps an island in `<astro-island>`, so a sub-step is rarely a literal child — look right through. */
|
|
137
|
+
syncHasChildren() {
|
|
138
|
+
this.hasChildren = !!this.querySelector("c2-step");
|
|
139
|
+
}
|
|
140
|
+
handleToggle(event) {
|
|
141
|
+
this.collapsed = !event.target.open;
|
|
142
|
+
}
|
|
143
|
+
renderMarker() {
|
|
144
|
+
if (this.marker === "none") return nothing;
|
|
145
|
+
const glyph = this.marker === "number" ? html`${this.path}` : STATUS_ICONS[this.status] ?? nothing;
|
|
146
|
+
return html`<span class="c2-step__marker" part="marker" aria-hidden="true"><slot name="marker">${glyph}</slot></span>`;
|
|
147
|
+
}
|
|
148
|
+
/** The row's content, identical whether it is a plain row or a group's summary. */
|
|
149
|
+
renderRowContent() {
|
|
150
|
+
const detail = this.detail || this.hasDetailSlot;
|
|
151
|
+
const trailing = this.trailing || this.hasTrailingSlot;
|
|
152
|
+
return html`
|
|
153
|
+
<span class="c2-step__toggle" part="toggle" aria-hidden="true" ?hidden=${!this.hasToggleSlot}>
|
|
154
|
+
<slot name="toggle" @slotchange=${(event) => this.handleSlotChange("toggle", event)}></slot>
|
|
155
|
+
</span>
|
|
156
|
+
<span class="c2-step__gutter">
|
|
157
|
+
${this.renderMarker()}
|
|
158
|
+
<span class="c2-step__rail" part="rail" aria-hidden="true"></span>
|
|
159
|
+
</span>
|
|
160
|
+
<span class="c2-step__text">
|
|
161
|
+
<span class="c2-step__label" part="label">
|
|
162
|
+
<slot name="label">${this.label}</slot>
|
|
163
|
+
</span>
|
|
164
|
+
<span class="c2-step__detail" part="detail" ?hidden=${!detail}>
|
|
165
|
+
<slot name="detail" @slotchange=${(event) => this.handleSlotChange("detail", event)}>${this.detail}</slot>
|
|
166
|
+
</span>
|
|
167
|
+
</span>
|
|
168
|
+
<span class="c2-step__trailing" part="trailing" ?hidden=${!trailing}>
|
|
169
|
+
<slot name="trailing" @slotchange=${(event) => this.handleSlotChange("trailing", event)}>${this.trailing}</slot>
|
|
170
|
+
</span>
|
|
171
|
+
<!-- The marker is a glyph, so the state is spelled out for assistive technology. -->
|
|
172
|
+
<span class="c2-step__status-text">${STATUS_LABELS[this.status]}</span>
|
|
173
|
+
`;
|
|
174
|
+
}
|
|
175
|
+
renderChildren() {
|
|
176
|
+
return html`
|
|
177
|
+
<div class="c2-step__children" part="children" role="list" ?hidden=${!this.hasChildren}>
|
|
178
|
+
<slot @slotchange=${this.syncHasChildren}></slot>
|
|
179
|
+
</div>
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
render() {
|
|
183
|
+
const rowClass = classMap({
|
|
184
|
+
"c2-step__row": true,
|
|
185
|
+
[`is-${this.status}`]: true
|
|
186
|
+
});
|
|
187
|
+
return html`
|
|
188
|
+
<div class="c2-step__frame" part="frame">
|
|
189
|
+
${this.hasChildren ? html`
|
|
190
|
+
<details class="c2-step__details" ?open=${!this.collapsed} @toggle=${this.handleToggle}>
|
|
191
|
+
<summary class=${rowClass} part="row">${this.renderRowContent()}</summary>
|
|
192
|
+
${this.renderChildren()}
|
|
193
|
+
</details>
|
|
194
|
+
` : html`<div class=${rowClass} part="row">${this.renderRowContent()}</div>
|
|
195
|
+
${this.renderChildren()}`}
|
|
196
|
+
</div>
|
|
197
|
+
`;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
__decorate([property({ reflect: true })], Step.prototype, "status", void 0);
|
|
201
|
+
__decorate([property()], Step.prototype, "label", void 0);
|
|
202
|
+
__decorate([property()], Step.prototype, "detail", void 0);
|
|
203
|
+
__decorate([property()], Step.prototype, "trailing", void 0);
|
|
204
|
+
__decorate([property({
|
|
205
|
+
type: Boolean,
|
|
206
|
+
reflect: true
|
|
207
|
+
})], Step.prototype, "collapsed", void 0);
|
|
208
|
+
__decorate([property({ attribute: false })], Step.prototype, "level", void 0);
|
|
209
|
+
__decorate([property({ attribute: false })], Step.prototype, "position", void 0);
|
|
210
|
+
__decorate([property({ attribute: false })], Step.prototype, "path", void 0);
|
|
211
|
+
__decorate([property({ attribute: false })], Step.prototype, "last", void 0);
|
|
212
|
+
__decorate([property({ attribute: false })], Step.prototype, "marker", void 0);
|
|
213
|
+
__decorate([property({ attribute: false })], Step.prototype, "grouped", void 0);
|
|
214
|
+
__decorate([property({ attribute: false })], Step.prototype, "hasChildren", void 0);
|
|
215
|
+
__decorate([state()], Step.prototype, "hasDetailSlot", void 0);
|
|
216
|
+
__decorate([state()], Step.prototype, "hasTrailingSlot", void 0);
|
|
217
|
+
__decorate([state()], Step.prototype, "hasToggleSlot", void 0);
|
|
218
|
+
Step = __decorate([customElement("c2-step")], Step);
|
|
219
|
+
//#endregion
|
|
220
|
+
export { __decorate as n, rollupStatus as r, Step as t };
|
|
File without changes
|
package/dist/step.js
ADDED
package/dist/steps.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { n as __decorate, r as rollupStatus } from "./step-CsDVe4w8.js";
|
|
2
|
+
import { LitElement, html, nothing, unsafeCSS } from "lit";
|
|
3
|
+
import { property } from "lit/decorators.js";
|
|
4
|
+
import { ifDefined } from "lit/directives/if-defined.js";
|
|
5
|
+
import { repeat } from "lit/directives/repeat.js";
|
|
6
|
+
import { customElement } from "@c2n/core/element-helper.js";
|
|
7
|
+
import { jsonPropertyConverter } from "@c2n/core/lit-helper.js";
|
|
8
|
+
//#region src/steps.scss?inline
|
|
9
|
+
var steps_default = "/* ex : var((width: 24px), width, c2-checkbox) returns var(--c2-checkbox-width, 24px) */\n:host {\n display: flex;\n flex-direction: column;\n gap: var(--c2-steps--gap,0px);\n box-sizing: border-box;\n max-height: var(--c2-steps--max-height,none);\n overflow-y: var(--c2-steps--overflow-y,visible);\n padding: var(--c2-steps--padding-block,0px) var(--c2-steps--padding-inline,0px);\n background: var(--c2-steps--background);\n border: var(--c2-steps--border);\n border-radius: var(--c2-steps--border-radius);\n}\n\n:host([hidden]) {\n display: none;\n}";
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/steps.ts
|
|
12
|
+
var _Steps;
|
|
13
|
+
var Steps = class Steps extends LitElement {
|
|
14
|
+
static {
|
|
15
|
+
_Steps = this;
|
|
16
|
+
}
|
|
17
|
+
constructor(..._args) {
|
|
18
|
+
super(..._args);
|
|
19
|
+
this.marker = "icon";
|
|
20
|
+
this.current = -1;
|
|
21
|
+
this.steps = void 0;
|
|
22
|
+
this.ariaLabel = null;
|
|
23
|
+
this.written = /* @__PURE__ */ new WeakMap();
|
|
24
|
+
this.known = /* @__PURE__ */ new WeakSet();
|
|
25
|
+
this.hasSynced = false;
|
|
26
|
+
}
|
|
27
|
+
static {
|
|
28
|
+
this.styles = unsafeCSS(steps_default);
|
|
29
|
+
}
|
|
30
|
+
connectedCallback() {
|
|
31
|
+
super.connectedCallback();
|
|
32
|
+
this.setAttribute("role", "list");
|
|
33
|
+
this.observer ??= new MutationObserver(() => this.syncSteps());
|
|
34
|
+
this.observer.observe(this, {
|
|
35
|
+
subtree: true,
|
|
36
|
+
childList: true,
|
|
37
|
+
attributes: true,
|
|
38
|
+
attributeFilter: ["status"]
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
disconnectedCallback() {
|
|
42
|
+
this.observer?.disconnect();
|
|
43
|
+
super.disconnectedCallback();
|
|
44
|
+
}
|
|
45
|
+
updated() {
|
|
46
|
+
this.syncSteps();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Changes one step of `steps` in place and redraws, without rebuilding the array — what a task runner wants when
|
|
50
|
+
* it ticks a step over hundreds of times. Returns `false` when no step carries that `id`.
|
|
51
|
+
*/
|
|
52
|
+
updateStep(id, patch) {
|
|
53
|
+
const find = (nodes) => {
|
|
54
|
+
for (const node of nodes) {
|
|
55
|
+
if (node.id === id) return node;
|
|
56
|
+
const hit = node.children?.length ? find(node.children) : void 0;
|
|
57
|
+
if (hit) return hit;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const node = this.steps?.length ? find(this.steps) : void 0;
|
|
61
|
+
if (!node) return false;
|
|
62
|
+
Object.assign(node, patch);
|
|
63
|
+
this.requestUpdate();
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
/** Brings every group back into view. */
|
|
67
|
+
expandAll() {
|
|
68
|
+
this.setCollapsedOfAll(false);
|
|
69
|
+
}
|
|
70
|
+
/** Folds every group away, leaving the top-level stages. */
|
|
71
|
+
collapseAll() {
|
|
72
|
+
this.setCollapsedOfAll(true);
|
|
73
|
+
}
|
|
74
|
+
setCollapsedOfAll(collapsed) {
|
|
75
|
+
for (const step of this.allSteps()) if (step.querySelector("c2-step")) step.collapsed = collapsed;
|
|
76
|
+
}
|
|
77
|
+
/** Every step in the list, wherever it came from. */
|
|
78
|
+
allSteps() {
|
|
79
|
+
return [...(this.steps?.length ? this.renderRoot : this).querySelectorAll("c2-step")];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The nearest `c2-step` descendants of `root`, looking through anything that is not one.
|
|
83
|
+
*
|
|
84
|
+
* A step is rarely a literal child: Astro wraps every island in an `<astro-island>` (which is
|
|
85
|
+
* `display: contents`, so it changes nothing but the tree), and a consumer may wrap rows in a `<div>`. Matching
|
|
86
|
+
* only direct children silently found nothing there, and every step kept its defaults.
|
|
87
|
+
*/
|
|
88
|
+
static collectSteps(root) {
|
|
89
|
+
const found = [];
|
|
90
|
+
for (const child of root.children) if (child.tagName === "C2-STEP") found.push(child);
|
|
91
|
+
else found.push(..._Steps.collectSteps(child));
|
|
92
|
+
return found;
|
|
93
|
+
}
|
|
94
|
+
/** Top-level steps, whether they came from the slot or from `steps`. */
|
|
95
|
+
get rootSteps() {
|
|
96
|
+
const slot = this.renderRoot.querySelector("slot:not([name])");
|
|
97
|
+
if (!slot) return _Steps.collectSteps(this.renderRoot);
|
|
98
|
+
return slot.assignedElements().flatMap((element) => element.tagName === "C2-STEP" ? [element] : _Steps.collectSteps(element));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Writes depth, position and presentation onto every step, and gives a parent that authored no `status` the one
|
|
102
|
+
* rolled up from its children — which is why the walk returns the statuses it settled on.
|
|
103
|
+
*
|
|
104
|
+
* Cheap to repeat: each value is a property assignment Lit will no-op when unchanged.
|
|
105
|
+
*/
|
|
106
|
+
syncSteps() {
|
|
107
|
+
const grouped = !!(this.steps?.length ? this.renderRoot : this).querySelector("c2-step c2-step");
|
|
108
|
+
const walk = (steps, level, parentPath) => {
|
|
109
|
+
return steps.map((step, index) => {
|
|
110
|
+
const element = step;
|
|
111
|
+
element.level = level;
|
|
112
|
+
element.position = index + 1;
|
|
113
|
+
element.path = parentPath ? `${parentPath}.${index + 1}` : String(index + 1);
|
|
114
|
+
element.last = index === steps.length - 1;
|
|
115
|
+
element.marker = this.marker;
|
|
116
|
+
element.grouped = grouped;
|
|
117
|
+
if (!this.known.has(element)) {
|
|
118
|
+
this.known.add(element);
|
|
119
|
+
if (this.hasSynced) element.toggleAttribute("entering", true);
|
|
120
|
+
}
|
|
121
|
+
const children = _Steps.collectSteps(element);
|
|
122
|
+
element.hasChildren = children.length > 0;
|
|
123
|
+
const childStatuses = children.length ? walk(children, level + 1, element.path) : [];
|
|
124
|
+
if (this.mayWrite(element)) {
|
|
125
|
+
const next = this.deriveStatus(childStatuses, level, index);
|
|
126
|
+
element.status = next;
|
|
127
|
+
this.written.set(element, next);
|
|
128
|
+
}
|
|
129
|
+
return element.status;
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
walk(this.rootSteps, 0, "");
|
|
133
|
+
this.hasSynced = true;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Whether this element may still write a step's status. A step it has never written is its to write while the
|
|
137
|
+
* step is `pending` — what "nobody said" looks like, from the markup or from the server. After that it is ours
|
|
138
|
+
* only while it still holds the value we gave it.
|
|
139
|
+
*/
|
|
140
|
+
mayWrite(element) {
|
|
141
|
+
const last = this.written.get(element);
|
|
142
|
+
return last === void 0 ? element.status === "pending" : element.status === last;
|
|
143
|
+
}
|
|
144
|
+
/** A parent takes the most urgent status under it; a leaf takes the wizard's `current`, or nothing happened yet. */
|
|
145
|
+
deriveStatus(childStatuses, level, index) {
|
|
146
|
+
if (childStatuses.length) return rollupStatus(childStatuses);
|
|
147
|
+
if (level === 0 && this.current >= 0) return index < this.current ? "success" : index === this.current ? "current" : "pending";
|
|
148
|
+
return "pending";
|
|
149
|
+
}
|
|
150
|
+
/** The status a data node ends up with, so a renderer is handed what is actually drawn. */
|
|
151
|
+
statusOf(node, level, index) {
|
|
152
|
+
if (node.status) return node.status;
|
|
153
|
+
const children = node.children ?? [];
|
|
154
|
+
if (children.length) return rollupStatus(children.map((child, childIndex) => this.statusOf(child, level + 1, childIndex)));
|
|
155
|
+
if (level === 0 && this.current >= 0) return index < this.current ? "success" : index === this.current ? "current" : "pending";
|
|
156
|
+
return "pending";
|
|
157
|
+
}
|
|
158
|
+
renderNode(node, level, index, parentPath) {
|
|
159
|
+
const position = index + 1;
|
|
160
|
+
const path = parentPath ? `${parentPath}.${position}` : String(position);
|
|
161
|
+
const context = {
|
|
162
|
+
node,
|
|
163
|
+
level,
|
|
164
|
+
position,
|
|
165
|
+
path,
|
|
166
|
+
status: this.statusOf(node, level, index)
|
|
167
|
+
};
|
|
168
|
+
const slot = (name, renderer) => renderer ? html`<span slot=${name}>${renderer(context)}</span>` : nothing;
|
|
169
|
+
const children = node.children ?? [];
|
|
170
|
+
return html`<c2-step
|
|
171
|
+
status=${ifDefined(node.status)}
|
|
172
|
+
?collapsed=${node.collapsed ?? false}
|
|
173
|
+
label=${ifDefined(this.renderItem || this.renderLabel ? void 0 : node.label)}
|
|
174
|
+
detail=${ifDefined(this.renderItem || this.renderDetail ? void 0 : node.detail)}
|
|
175
|
+
trailing=${ifDefined(this.renderItem || this.renderTrailing ? void 0 : node.trailing)}
|
|
176
|
+
>
|
|
177
|
+
${slot("marker", this.renderMarker)}${slot("toggle", this.renderToggle)}
|
|
178
|
+
${this.renderItem ? html`<span slot="label">${this.renderItem(context)}</span>` : html`${slot("label", this.renderLabel)}${slot("detail", this.renderDetail)}${slot("trailing", this.renderTrailing)}`}
|
|
179
|
+
${repeat(children, (child, childIndex) => child.id ?? `${path}.${childIndex + 1}`, (child, childIndex) => this.renderNode(child, level + 1, childIndex, path))}
|
|
180
|
+
</c2-step>`;
|
|
181
|
+
}
|
|
182
|
+
render() {
|
|
183
|
+
return this.steps?.length ? html`${repeat(this.steps, (node, index) => node.id ?? String(index + 1), (node, index) => this.renderNode(node, 0, index, ""))}` : html`<slot @slotchange=${() => this.syncSteps()}></slot>`;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
__decorate([property({ reflect: true })], Steps.prototype, "marker", void 0);
|
|
187
|
+
__decorate([property({
|
|
188
|
+
type: Number,
|
|
189
|
+
reflect: true
|
|
190
|
+
})], Steps.prototype, "current", void 0);
|
|
191
|
+
__decorate([property({ converter: jsonPropertyConverter })], Steps.prototype, "steps", void 0);
|
|
192
|
+
__decorate([property({ attribute: "aria-label" })], Steps.prototype, "ariaLabel", void 0);
|
|
193
|
+
__decorate([property({ attribute: false })], Steps.prototype, "renderItem", void 0);
|
|
194
|
+
__decorate([property({ attribute: false })], Steps.prototype, "renderMarker", void 0);
|
|
195
|
+
__decorate([property({ attribute: false })], Steps.prototype, "renderToggle", void 0);
|
|
196
|
+
__decorate([property({ attribute: false })], Steps.prototype, "renderLabel", void 0);
|
|
197
|
+
__decorate([property({ attribute: false })], Steps.prototype, "renderDetail", void 0);
|
|
198
|
+
__decorate([property({ attribute: false })], Steps.prototype, "renderTrailing", void 0);
|
|
199
|
+
Steps = _Steps = __decorate([customElement("c2-steps")], Steps);
|
|
200
|
+
//#endregion
|
|
201
|
+
export { Steps };
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@c2n/steps",
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/steps.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./types/src/steps.d.ts",
|
|
9
|
+
"default": "./dist/steps.js"
|
|
10
|
+
},
|
|
11
|
+
"./step.js": {
|
|
12
|
+
"types": "./types/src/step.d.ts",
|
|
13
|
+
"default": "./dist/step.js"
|
|
14
|
+
},
|
|
15
|
+
"./step-types.js": {
|
|
16
|
+
"types": "./types/src/step-types.d.ts",
|
|
17
|
+
"default": "./dist/step-types.js"
|
|
18
|
+
},
|
|
19
|
+
"./react": {
|
|
20
|
+
"types": "./react.d.ts",
|
|
21
|
+
"default": "./react.js"
|
|
22
|
+
},
|
|
23
|
+
"./vue": {
|
|
24
|
+
"types": "./vue.d.ts",
|
|
25
|
+
"default": "./vue.js"
|
|
26
|
+
},
|
|
27
|
+
"./custom-elements.json": "./custom-elements.json"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"types",
|
|
32
|
+
"react.d.ts",
|
|
33
|
+
"react.js",
|
|
34
|
+
"vue.d.ts",
|
|
35
|
+
"vue.js"
|
|
36
|
+
],
|
|
37
|
+
"keywords": [
|
|
38
|
+
"steps",
|
|
39
|
+
"stepper",
|
|
40
|
+
"progress",
|
|
41
|
+
"trace",
|
|
42
|
+
"web component",
|
|
43
|
+
"lit"
|
|
44
|
+
],
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"author": "code2nguyen@gmail.com",
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"registry": "https://registry.npmjs.org",
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "https://github.com/code2nguyen/web-components.git"
|
|
54
|
+
},
|
|
55
|
+
"scripts": {
|
|
56
|
+
"dev": "vite",
|
|
57
|
+
"build": "wireit",
|
|
58
|
+
"build:only": "vite build",
|
|
59
|
+
"type-check": "wireit"
|
|
60
|
+
},
|
|
61
|
+
"wireit": {
|
|
62
|
+
"type-check": {
|
|
63
|
+
"dependencies": [
|
|
64
|
+
"../../core:build"
|
|
65
|
+
],
|
|
66
|
+
"command": "tsc -p tsconfig.lib.json --composite false"
|
|
67
|
+
},
|
|
68
|
+
"build": {
|
|
69
|
+
"dependencies": [
|
|
70
|
+
"type-check"
|
|
71
|
+
],
|
|
72
|
+
"command": "vite build"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"@c2n/core": "0.0.10",
|
|
77
|
+
"lit": "3.3.3"
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@c2n/config": "*"
|
|
81
|
+
},
|
|
82
|
+
"customElements": "custom-elements.json",
|
|
83
|
+
"gitHead": "8d57710b3345fcb01cdb4cb15d2d43ba8bf21642"
|
|
84
|
+
}
|
package/react.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// GENERATED by @c2n/framework-types. Do not edit by hand.
|
|
2
|
+
//
|
|
3
|
+
// JSX types for the custom elements of @c2n/steps. Import once, anywhere in the program:
|
|
4
|
+
//
|
|
5
|
+
// import '@c2n/steps/react'
|
|
6
|
+
//
|
|
7
|
+
// Register the elements at module scope before React renders, or React writes an object prop as an
|
|
8
|
+
// attribute and it stringifies.
|
|
9
|
+
|
|
10
|
+
import type { DetailedHTMLProps, HTMLAttributes } from 'react'
|
|
11
|
+
import type { Step } from '@c2n/steps/step.js'
|
|
12
|
+
import type { Steps } from '@c2n/steps'
|
|
13
|
+
|
|
14
|
+
/** Standard React host-element attributes plus the element's own public properties. */
|
|
15
|
+
type C2Props<T> = DetailedHTMLProps<HTMLAttributes<T>, T> & Partial<Omit<T, keyof HTMLElement>>
|
|
16
|
+
|
|
17
|
+
declare module 'react' {
|
|
18
|
+
namespace JSX {
|
|
19
|
+
interface IntrinsicElements {
|
|
20
|
+
'c2-step': C2Props<Step>
|
|
21
|
+
'c2-steps': C2Props<Steps>
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export {}
|
package/react.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { StepStatus } from './step-types.js';
|
|
2
|
+
/** What a screen reader reads for each status, since the marker is a glyph. */
|
|
3
|
+
export declare const STATUS_LABELS: Record<StepStatus, string>;
|
|
4
|
+
/** The states that draw a glyph. The rest are drawn by the marker's ring alone. */
|
|
5
|
+
export declare const STATUS_ICONS: Partial<Record<StepStatus, unknown>>;
|
|
6
|
+
export declare function rollupStatus(statuses: StepStatus[]): StepStatus;
|
|
7
|
+
//# sourceMappingURL=step-icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-icons.d.ts","sourceRoot":"","sources":["../../src/step-icons.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEjD,+EAA+E;AAC/E,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAQpD,CAAA;AAmBD,mFAAmF;AACnF,eAAO,MAAM,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAK7D,CAAA;AASD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,UAAU,CAI/D"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** State of a single step. */
|
|
2
|
+
export type StepStatus =
|
|
3
|
+
/** Not reached yet. */
|
|
4
|
+
'pending'
|
|
5
|
+
/** The step the process is on, but not doing work — a wizard's active page. */
|
|
6
|
+
| 'current'
|
|
7
|
+
/** Under way: the marker spins. */
|
|
8
|
+
| 'running'
|
|
9
|
+
/** Finished successfully. */
|
|
10
|
+
| 'success'
|
|
11
|
+
/** Finished and failed. */
|
|
12
|
+
| 'error'
|
|
13
|
+
/** Finished with something worth reading. */
|
|
14
|
+
| 'warning'
|
|
15
|
+
/** Deliberately not run. */
|
|
16
|
+
| 'skipped';
|
|
17
|
+
/** How the marker is drawn. */
|
|
18
|
+
export type StepsMarker =
|
|
19
|
+
/** A glyph per status: check, cross, triangle, spinner, dot, dash. */
|
|
20
|
+
'icon'
|
|
21
|
+
/** The step's dotted position, coloured by status. */
|
|
22
|
+
| 'number'
|
|
23
|
+
/** No marker column at all. */
|
|
24
|
+
| 'none';
|
|
25
|
+
/** One node of the `steps` property, the data-driven alternative to `c2-step` children. */
|
|
26
|
+
export interface StepNode {
|
|
27
|
+
/**
|
|
28
|
+
* Stable identity. A step keeps its DOM — and so its expanded state — across renders that reuse the same `id`,
|
|
29
|
+
* and `updateStep` addresses a step by it. Without one a step is identified by its position, which is enough for
|
|
30
|
+
* a trace that only ever grows at the end.
|
|
31
|
+
*/
|
|
32
|
+
id?: string;
|
|
33
|
+
/** Primary text. */
|
|
34
|
+
label?: string;
|
|
35
|
+
/** Secondary text beside the label, dimmed — a path, an id, a short note. */
|
|
36
|
+
detail?: string;
|
|
37
|
+
/** Text at the end of the row: a duration, a count, a timestamp. */
|
|
38
|
+
trailing?: string;
|
|
39
|
+
/**
|
|
40
|
+
* State of this step. Left out on a step that has `children`, it is rolled up from them: the most urgent thing
|
|
41
|
+
* inside wins, so a parent reports that it is running, or that something under it failed, on its own.
|
|
42
|
+
*/
|
|
43
|
+
status?: StepStatus;
|
|
44
|
+
/** Sub-steps. A step that has them is a group: its own row is the summary, and these are the detail. */
|
|
45
|
+
children?: StepNode[];
|
|
46
|
+
/** Starts this group folded away. A group is expanded by default: every step in the list is a row you can see. */
|
|
47
|
+
collapsed?: boolean;
|
|
48
|
+
}
|
|
49
|
+
/** What a renderer is handed for one step. */
|
|
50
|
+
export interface StepContext {
|
|
51
|
+
/** The node from the `steps` array. */
|
|
52
|
+
node: StepNode;
|
|
53
|
+
/** Depth of nesting; `0` at the top level. */
|
|
54
|
+
level: number;
|
|
55
|
+
/** 1-based position among its siblings. */
|
|
56
|
+
position: number;
|
|
57
|
+
/** Dotted position through the whole tree — `3.1` is the first child of the third step. */
|
|
58
|
+
path: string;
|
|
59
|
+
/** The status in effect, rolled up and `current`-derived. */
|
|
60
|
+
status: StepStatus;
|
|
61
|
+
}
|
|
62
|
+
/** Replaces part of a row's content. Returns anything Lit can render. */
|
|
63
|
+
export type StepRenderer = (context: StepContext) => unknown;
|
|
64
|
+
//# sourceMappingURL=step-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step-types.d.ts","sourceRoot":"","sources":["../../src/step-types.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,MAAM,MAAM,UAAU;AACpB,uBAAuB;AACrB,SAAS;AACX,+EAA+E;GAC7E,SAAS;AACX,mCAAmC;GACjC,SAAS;AACX,6BAA6B;GAC3B,SAAS;AACX,2BAA2B;GACzB,OAAO;AACT,6CAA6C;GAC3C,SAAS;AACX,4BAA4B;GAC1B,SAAS,CAAA;AAEb,+BAA+B;AAC/B,MAAM,MAAM,WAAW;AACrB,sEAAsE;AACpE,MAAM;AACR,sDAAsD;GACpD,QAAQ;AACV,+BAA+B;GAC7B,MAAM,CAAA;AAEV,2FAA2F;AAC3F,MAAM,WAAW,QAAQ;IACvB;;;;OAIG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,CAAA;IACnB,wGAAwG;IACxG,QAAQ,CAAC,EAAE,QAAQ,EAAE,CAAA;IACrB,kHAAkH;IAClH,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED,8CAA8C;AAC9C,MAAM,WAAW,WAAW;IAC1B,uCAAuC;IACvC,IAAI,EAAE,QAAQ,CAAA;IACd,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAA;IACb,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAA;IAChB,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,MAAM,EAAE,UAAU,CAAA;CACnB;AAED,yEAAyE;AACzE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAA"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { LitElement, type PropertyValues, type TemplateResult } from 'lit';
|
|
2
|
+
import type { TypedAddEventListener, TypedRemoveEventListener } from '@c2n/core/event-helper.js';
|
|
3
|
+
import type { StepStatus, StepsMarker } from './step-types.js';
|
|
4
|
+
export type { StepStatus, StepsMarker } from './step-types.js';
|
|
5
|
+
/** Detail of {@link StepEventMap.step-toggle}. */
|
|
6
|
+
export interface StepToggleEventDetail {
|
|
7
|
+
/** Whether the group is now folded away. */
|
|
8
|
+
collapsed: boolean;
|
|
9
|
+
/** Dotted position of the step through the tree, so a listener on `c2-steps` knows which one moved. */
|
|
10
|
+
path: string;
|
|
11
|
+
}
|
|
12
|
+
export interface StepEventMap {
|
|
13
|
+
/**
|
|
14
|
+
* A group opened or closed — by a click, by the keyboard, or because the run reopened it. Bubbles, so one
|
|
15
|
+
* listener on `c2-steps` hears every group; `event.target` is the step and `detail.path` says where it sits.
|
|
16
|
+
*/
|
|
17
|
+
'step-toggle': CustomEvent<StepToggleEventDetail>;
|
|
18
|
+
}
|
|
19
|
+
export interface Step {
|
|
20
|
+
addEventListener: TypedAddEventListener<Step, StepEventMap>;
|
|
21
|
+
removeEventListener: TypedRemoveEventListener<Step, StepEventMap>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* One row of a {@link Steps} list: a marker, a label with optional dimmed `detail`, and `trailing` text at the end
|
|
25
|
+
* of the row — a duration, a count, a timestamp.
|
|
26
|
+
*
|
|
27
|
+
* **A step with sub-steps is a group.** Nest `c2-step` children and the row becomes the summary of a disclosure
|
|
28
|
+
* and the children its detail, so a long run collapses to the shape of the task rather than to a wall of lines.
|
|
29
|
+
* There is no second element to learn: the same tag is a leaf or a group depending on what is inside it.
|
|
30
|
+
*
|
|
31
|
+
* **Every step is a row, and every row is visible.** A group starts expanded and nothing ever folds one away on
|
|
32
|
+
* its own: the chevron is there for the reader, and `collapsed` in the markup starts a stage folded. The run only
|
|
33
|
+
* ever brings a stage *back* into view — a folded one reopens when it starts running (`running`, `current`) or
|
|
34
|
+
* when something in it goes wrong (`error`, `warning`).
|
|
35
|
+
*
|
|
36
|
+
* **A step is one row.** Label, detail and trailing text sit on a single line and truncate with an ellipsis rather
|
|
37
|
+
* than wrapping, so a hundred-step trace stays scannable, and a sub-step is indented far enough that its marker
|
|
38
|
+
* lands under its parent's label. `--c2-step__text--flex-direction: column` still stacks the detail under the
|
|
39
|
+
* label, which a wizard's descriptions want — that is two lines on purpose, and each of them is still one line.
|
|
40
|
+
*
|
|
41
|
+
* The step never sets its own depth, position or marker mode: the parent `c2-steps` writes them on every pass, so
|
|
42
|
+
* a step used on its own renders as a single root-level row.
|
|
43
|
+
*
|
|
44
|
+
* @tag c2-step
|
|
45
|
+
*
|
|
46
|
+
* @slot - Sub-steps. A step that has them is a group.
|
|
47
|
+
* @slot label - Primary text. Falls back to the `label` attribute.
|
|
48
|
+
* @slot detail - Secondary text beside the label. Falls back to the `detail` attribute.
|
|
49
|
+
* @slot trailing - Content at the end of the row. Falls back to the `trailing` attribute.
|
|
50
|
+
* @slot marker - Replaces the whole marker: a custom icon, an avatar, a number of your own.
|
|
51
|
+
* @slot toggle - A disclosure affordance of your own — a chevron, a caret. Empty by default: a trace is a list of rows, and the row is already clickable. It is filled per step, so give a leaf an empty `<span slot="toggle"></span>` to keep its rows lined up with the groups above them.
|
|
52
|
+
*
|
|
53
|
+
* @event {CustomEvent<StepToggleEventDetail>} step-toggle - A group was folded away or brought back. Bubbles.
|
|
54
|
+
*
|
|
55
|
+
* @csspart frame - The box around the whole step, which is what grows when a new step arrives.
|
|
56
|
+
* @csspart row - The row itself: toggle, marker, text and trailing content. A group's row is its `<summary>`.
|
|
57
|
+
* @csspart toggle - The disclosure chevron of a group.
|
|
58
|
+
* @csspart marker - The round marker at the start of the row.
|
|
59
|
+
* @csspart rail - The connector between this marker and the next.
|
|
60
|
+
* @csspart label - The primary text.
|
|
61
|
+
* @csspart detail - The dimmed secondary text.
|
|
62
|
+
* @csspart trailing - The text at the end of the row.
|
|
63
|
+
* @csspart children - The box holding the sub-steps.
|
|
64
|
+
*
|
|
65
|
+
* @cssproperty {pixel} [--c2-step__row--gap=10px] - Space between the marker, the text and the trailing content.
|
|
66
|
+
* @cssproperty {padding} [--c2-step__row--padding-block=7px]
|
|
67
|
+
* @cssproperty {padding} [--c2-step__row--padding-inline=12px]
|
|
68
|
+
* @cssproperty {pixel} [--c2-step__row--indent=marker size + row gap] - Extra inset per level of nesting. The default puts a sub-step's marker under its parent's label, which is what makes the nesting read without drawing anything.
|
|
69
|
+
* @cssproperty {border-radius} --c2-step__row--border-radius
|
|
70
|
+
* @cssproperty {color} --c2-step__row--background
|
|
71
|
+
* @cssproperty {color} --c2-step__row__hover--background - Set it to make the rows respond to the pointer.
|
|
72
|
+
* @cssproperty {border} [--c2-step__row--border-bottom=1px solid #e4e4e7] - The hairline under each row.
|
|
73
|
+
* @cssproperty {border} [--c2-step__row--outline=2px solid rgb(2, 101, 220)] - Focus ring of a group's row, which is a button.
|
|
74
|
+
*
|
|
75
|
+
* @cssproperty {pixel} [--c2-step__toggle--size=14px] - Width of the `toggle` slot's column, when it is filled.
|
|
76
|
+
* @cssproperty {pixel} [--c2-step__toggle--gap=4px] - Space between that column and the marker.
|
|
77
|
+
* @cssproperty {color} [--c2-step__toggle--color=#a1a1aa]
|
|
78
|
+
*
|
|
79
|
+
* @cssproperty {color} [--c2-step__guide--color=#e4e4e7] - A vertical rule at each ancestor's depth, for a file-tree look. Off by default.
|
|
80
|
+
* @cssproperty {pixel} [--c2-step__guide--width=0px] - Width of that rule. `1px` turns the guides on.
|
|
81
|
+
*
|
|
82
|
+
* @cssproperty {pixel} [--c2-step__marker--size=16px]
|
|
83
|
+
* @cssproperty {font-size} [--c2-step__marker--font-size=10px] - Size of the dotted path in `marker="number"`.
|
|
84
|
+
* @cssproperty {padding} [--c2-step__marker--padding-inline=3px] - Breathing room either side of a dotted path, which is what turns the circle into a pill when the number is long. Only `marker="number"` uses it.
|
|
85
|
+
* @cssproperty {font-weight} [--c2-step__marker--font-weight=600]
|
|
86
|
+
* @cssproperty {border-radius} [--c2-step__marker--border-radius=999px]
|
|
87
|
+
* @cssproperty {border} [--c2-step__marker--border=1px solid #bcbcc6] - The ring, drawn for the states that have no glyph of their own (`pending`, `current`, `running`) and for every `marker="number"` step. A finished step is its glyph, so it has no ring.
|
|
88
|
+
* @cssproperty {color} [--c2-step__marker--background=transparent]
|
|
89
|
+
* @cssproperty {color} [--c2-step__marker--color=#71717a]
|
|
90
|
+
*
|
|
91
|
+
* @cssproperty {pixel} [--c2-step__rail--width=0px] - Width of the connector. `0px` is the trace look; `2px` gives a stepper its rail.
|
|
92
|
+
* @cssproperty {color} [--c2-step__rail--color=#e4e4e7]
|
|
93
|
+
* @cssproperty {pixel} [--c2-step__rail--gap=4px] - Space between the marker and the rail.
|
|
94
|
+
*
|
|
95
|
+
* @cssproperty {color} [--c2-step__label--color=#18181b]
|
|
96
|
+
* @cssproperty {font-size} [--c2-step__label--font-size=13px]
|
|
97
|
+
* @cssproperty {font-weight} [--c2-step__label--font-weight=500]
|
|
98
|
+
* @cssproperty {font-family} [--c2-step__label--font-family=ui-monospace, SFMono-Regular, Menlo, Consolas, monospace]
|
|
99
|
+
* @cssproperty {color} [--c2-step__detail--color=#71717a]
|
|
100
|
+
* @cssproperty {font-size} --c2-step__detail--font-size - Falls back to the label size.
|
|
101
|
+
* @cssproperty {font-weight} [--c2-step__detail--font-weight=400]
|
|
102
|
+
* @cssproperty {pixel} [--c2-step__detail--gap=8px] - Space between the label and the detail when they share a line.
|
|
103
|
+
* @cssproperty {pixel} [--c2-step__detail--row-gap=2px] - Space between them when they are stacked.
|
|
104
|
+
* @cssproperty {flex-direction-row} [--c2-step__text--flex-direction=row] - `column` puts the detail on its own line under the label, which a wizard's descriptions want. It is the only variable that switch needs: the gap and the alignment follow it.
|
|
105
|
+
* @cssproperty {align-items} [--c2-step__text--align-items=baseline] - How the label and the detail line up across the row. Stacked, they are flush left whatever this says.
|
|
106
|
+
* @cssproperty {color} [--c2-step__trailing--color=#71717a]
|
|
107
|
+
* @cssproperty {font-size} --c2-step__trailing--font-size - Falls back to the label size.
|
|
108
|
+
* @cssproperty {font-weight} [--c2-step__trailing--font-weight=400]
|
|
109
|
+
*
|
|
110
|
+
* @cssproperty {color} [--c2-step__success--color=#16a34a] - Marker colour when the step succeeded.
|
|
111
|
+
* @cssproperty {color} [--c2-step__error--color=#dc2626]
|
|
112
|
+
* @cssproperty {color} [--c2-step__warning--color=#d97706]
|
|
113
|
+
* @cssproperty {color} [--c2-step__running--color=rgb(2, 101, 220)]
|
|
114
|
+
* @cssproperty {color} [--c2-step__current--color=rgb(2, 101, 220)]
|
|
115
|
+
* @cssproperty {color} [--c2-step__skipped--color=#71717a] - Marker and label colour when the step was skipped.
|
|
116
|
+
* @cssproperty {time} [--c2-step--transition-duration=150ms] - Colour transitions, and the beat a marker gives when its status settles.
|
|
117
|
+
* @cssproperty {time} [--c2-step--enter-duration=260ms] - How long a step arriving in a running trace takes to grow into place. `0s` turns the animation off.
|
|
118
|
+
* @cssproperty {translate} [--c2-step--enter-translate=-4px] - How far it slides while it does.
|
|
119
|
+
*/
|
|
120
|
+
export declare class Step extends LitElement {
|
|
121
|
+
static styles: import("lit").CSSResult;
|
|
122
|
+
/** State of the step. Drives the marker glyph and the accent colour, and reopens a folded group. */
|
|
123
|
+
status: StepStatus;
|
|
124
|
+
/** Primary text, when the `label` slot is empty. */
|
|
125
|
+
label: string;
|
|
126
|
+
/** Dimmed secondary text beside the label, when the `detail` slot is empty. */
|
|
127
|
+
detail: string;
|
|
128
|
+
/** Text at the end of the row, when the `trailing` slot is empty. */
|
|
129
|
+
trailing: string;
|
|
130
|
+
/**
|
|
131
|
+
* Whether this group is folded away. A group is expanded by default — every step in the list is a row you can
|
|
132
|
+
* see — and only the reader, the markup or a reopening status ever changes that.
|
|
133
|
+
*/
|
|
134
|
+
collapsed: boolean;
|
|
135
|
+
/** Depth of nesting. Written by the parent `c2-steps`; setting it by hand only changes the indent. */
|
|
136
|
+
level: number;
|
|
137
|
+
/** 1-based position among its siblings. Written by the parent. */
|
|
138
|
+
position: number;
|
|
139
|
+
/** Dotted position through the tree — `3.1` for the first child of the third step. Shown by `marker="number"`. */
|
|
140
|
+
path: string;
|
|
141
|
+
/** Whether this is the last step of its group, so the rail stops here. Written by the parent. */
|
|
142
|
+
last: boolean;
|
|
143
|
+
/** Marker mode, written by the parent `c2-steps`. */
|
|
144
|
+
marker: StepsMarker;
|
|
145
|
+
/**
|
|
146
|
+
* Whether the list holds any group at all, written by the parent. A list of plain rows drops the chevron column
|
|
147
|
+
* rather than leaving every row inset by an empty one.
|
|
148
|
+
*/
|
|
149
|
+
grouped: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Whether this step has sub-steps, and so is a group. Written by the parent `c2-steps`, which walks the tree
|
|
152
|
+
* anyway; a step on its own works it out for itself.
|
|
153
|
+
*/
|
|
154
|
+
hasChildren: boolean;
|
|
155
|
+
private hasDetailSlot;
|
|
156
|
+
private hasTrailingSlot;
|
|
157
|
+
private hasToggleSlot;
|
|
158
|
+
connectedCallback(): void;
|
|
159
|
+
disconnectedCallback(): void;
|
|
160
|
+
/**
|
|
161
|
+
* `entering` is written by the parent on a step that arrived after the list was already on screen, and it is
|
|
162
|
+
* the whole of the enter animation. It comes off again the moment that animation is done, so a step is never
|
|
163
|
+
* left in a state that would replay it — the spinner is ignored here because it never ends.
|
|
164
|
+
*/
|
|
165
|
+
private readonly handleAnimationEnd;
|
|
166
|
+
protected firstUpdated(): void;
|
|
167
|
+
protected willUpdate(changed: PropertyValues): void;
|
|
168
|
+
protected updated(changed: PropertyValues): void;
|
|
169
|
+
/** These three collapse when empty, so their rows have to know whether the slot was filled. */
|
|
170
|
+
private handleSlotChange;
|
|
171
|
+
/** Astro wraps an island in `<astro-island>`, so a sub-step is rarely a literal child — look right through. */
|
|
172
|
+
private syncHasChildren;
|
|
173
|
+
private handleToggle;
|
|
174
|
+
private renderMarker;
|
|
175
|
+
/** The row's content, identical whether it is a plain row or a group's summary. */
|
|
176
|
+
private renderRowContent;
|
|
177
|
+
private renderChildren;
|
|
178
|
+
render(): TemplateResult<1>;
|
|
179
|
+
}
|
|
180
|
+
declare global {
|
|
181
|
+
interface HTMLElementTagNameMap {
|
|
182
|
+
'c2-step': Step;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=step.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../../src/step.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAIpG,OAAO,KAAK,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AAChG,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAI9D,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE9D,kDAAkD;AAClD,MAAM,WAAW,qBAAqB;IACpC,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAA;IAClB,uGAAuG;IACvG,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,aAAa,EAAE,WAAW,CAAC,qBAAqB,CAAC,CAAA;CAClD;AAED,MAAM,WAAW,IAAI;IACnB,gBAAgB,EAAE,qBAAqB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;IAC3D,mBAAmB,EAAE,wBAAwB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;CAClE;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgGG;AACH,qBACa,IAAK,SAAQ,UAAU;IAClC,OAAgB,MAAM,0BAAoB;IAE1C,oGAAoG;IACvE,MAAM,EAAE,UAAU,CAAY;IAE3D,oDAAoD;IACxC,KAAK,SAAK;IAEtB,+EAA+E;IACnE,MAAM,SAAK;IAEvB,qEAAqE;IACzD,QAAQ,SAAK;IAEzB;;;OAGG;IACyC,SAAS,UAAQ;IAE7D,sGAAsG;IACtE,KAAK,SAAI;IAEzC,kEAAkE;IAClC,QAAQ,SAAI;IAE5C,kHAAkH;IAClF,IAAI,SAAM;IAE1C,iGAAiG;IACjE,IAAI,UAAQ;IAE5C,qDAAqD;IACrB,MAAM,EAAE,WAAW,CAAS;IAE5D;;;OAGG;IAC6B,OAAO,UAAQ;IAE/C;;;OAGG;IAC6B,WAAW,UAAQ;IAE1C,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,aAAa,CAAQ;IAE7B,iBAAiB;IASjB,oBAAoB;IAM7B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAIlC;cAEkB,YAAY;cAOZ,UAAU,CAAC,OAAO,EAAE,cAAc;cAOlC,OAAO,CAAC,OAAO,EAAE,cAAc;IAclD,+FAA+F;IAC/F,OAAO,CAAC,gBAAgB;IASxB,+GAA+G;IAC/G,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAMpB,mFAAmF;IACnF,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,cAAc;IAQb,MAAM;CAqBhB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,SAAS,EAAE,IAAI,CAAA;KAChB;CACF"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { LitElement, type TemplateResult } from 'lit';
|
|
2
|
+
import type { StepNode, StepRenderer, StepsMarker } from './step-types.js';
|
|
3
|
+
import './step.js';
|
|
4
|
+
export type { StepContext, StepNode, StepRenderer, StepStatus, StepsMarker } from './step-types.js';
|
|
5
|
+
export type { StepToggleEventDetail, StepEventMap } from './step.js';
|
|
6
|
+
/**
|
|
7
|
+
* A vertical list of steps: the trace of a task as it runs, or a wizard's progress. Each row is a marker, a label,
|
|
8
|
+
* an optional dimmed `detail` beside it and `trailing` text at the end — a duration, a count, a timestamp.
|
|
9
|
+
*
|
|
10
|
+
* **A step with sub-steps is a group**, and a group is a disclosure: its own row is the summary and its sub-steps
|
|
11
|
+
* are the detail. **Every step is a row, and every row is visible** — a group starts expanded and nothing ever
|
|
12
|
+
* folds one away on its own. The chevron is there for the reader, `collapsed` in the markup starts a stage folded,
|
|
13
|
+
* and the run only ever brings a folded stage *back* into view when it starts running or something in it fails.
|
|
14
|
+
*
|
|
15
|
+
* Author it either way, and mix them freely:
|
|
16
|
+
*
|
|
17
|
+
* - **Declarative** — slot `c2-step` children and nest them for sub-steps.
|
|
18
|
+
* - **Data-driven** — hand it a `steps` array of `{ id, label, detail, trailing, status, children }` and it renders
|
|
19
|
+
* the tree itself. The array wins when both are present. During a run, `updateStep(id, patch)` changes one step
|
|
20
|
+
* without rebuilding the array.
|
|
21
|
+
*
|
|
22
|
+
* Everything the markup fills with a slot, the data-driven mode fills with a renderer: `renderMarker` for the
|
|
23
|
+
* `marker` slot, `renderToggle` for `toggle`, `renderLabel` / `renderDetail` / `renderTrailing` for the text, and
|
|
24
|
+
* `renderItem` for that text all at once. Each is handed the node, its depth, its position, its dotted path and
|
|
25
|
+
* the status actually in effect.
|
|
26
|
+
*
|
|
27
|
+
* A parent step that does not author a `status` takes one from its children: the most urgent thing inside wins, so
|
|
28
|
+
* a stage reports that it is running, or that something under it failed, without you setting it.
|
|
29
|
+
*
|
|
30
|
+
* `current` is the shortcut a wizard wants: set it to the index of the active step and every top-level step that
|
|
31
|
+
* has neither an explicit `status` nor sub-steps becomes `success` before it, `current` at it and `pending` after.
|
|
32
|
+
*
|
|
33
|
+
* A step that arrives while the list is already on screen grows into place rather than appearing, and a marker
|
|
34
|
+
* gives one beat as its status settles — which is what a trace being written in front of you should look like.
|
|
35
|
+
* `--c2-step--enter-duration: 0s` turns the first off, and `prefers-reduced-motion` turns both off.
|
|
36
|
+
*
|
|
37
|
+
* The connector rail between markers is drawn by CSS and off by default, because a trace does not want one — give
|
|
38
|
+
* `--c2-step__rail--width` a width and a stepper gets its rail.
|
|
39
|
+
*
|
|
40
|
+
* Numbering follows the tree: `marker="number"` draws a dotted path, so the first child of the third step reads
|
|
41
|
+
* `3.1` rather than a second `1`.
|
|
42
|
+
*
|
|
43
|
+
* @tag c2-steps
|
|
44
|
+
*
|
|
45
|
+
* @slot - The `c2-step` children. Ignored when `steps` is set.
|
|
46
|
+
*
|
|
47
|
+
* @slotcomponent c2-step
|
|
48
|
+
*
|
|
49
|
+
* @event {CustomEvent<StepToggleEventDetail>} step-toggle - Fired by a `c2-step` when a group opens or closes, and bubbling to here. `event.target` is the step; `detail.path` says where it sits.
|
|
50
|
+
*
|
|
51
|
+
* @cssproperty {pixel} [--c2-steps--gap=0px] - Space between rows. A stepper usually wants some; a trace does not.
|
|
52
|
+
* @cssproperty {color} --c2-steps--background
|
|
53
|
+
* @cssproperty {border} --c2-steps--border
|
|
54
|
+
* @cssproperty {border-radius} --c2-steps--border-radius
|
|
55
|
+
* @cssproperty {padding} [--c2-steps--padding-block=0px]
|
|
56
|
+
* @cssproperty {padding} [--c2-steps--padding-inline=0px]
|
|
57
|
+
* @cssproperty {overflow} [--c2-steps--overflow-y=visible] - `auto` with a `max-height` keeps a long run in its own scroller.
|
|
58
|
+
* @cssproperty {max-height} [--c2-steps--max-height=none]
|
|
59
|
+
*/
|
|
60
|
+
export declare class Steps extends LitElement {
|
|
61
|
+
static styles: import("lit").CSSResult;
|
|
62
|
+
/** How each marker is drawn: a status glyph, the step's number, or nothing. */
|
|
63
|
+
marker: StepsMarker;
|
|
64
|
+
/**
|
|
65
|
+
* Index of the active step, for a wizard. `-1` (the default) leaves every status alone; otherwise a top-level
|
|
66
|
+
* step with neither an explicit `status` nor sub-steps becomes `success` before this index, `current` at it and
|
|
67
|
+
* `pending` after it.
|
|
68
|
+
*/
|
|
69
|
+
current: number;
|
|
70
|
+
/** The steps as data, instead of `c2-step` children. Takes precedence over the slot. */
|
|
71
|
+
steps: StepNode[] | undefined;
|
|
72
|
+
/** Accessible name for the list. */
|
|
73
|
+
ariaLabel: string | null;
|
|
74
|
+
/**
|
|
75
|
+
* Replaces a row's text when rendering from `steps`, so a step can carry a badge, a link, an avatar — anything
|
|
76
|
+
* Lit renders. It overrides `renderLabel`, `renderDetail` and `renderTrailing`, which are the finer-grained way
|
|
77
|
+
* to do the same thing. The marker and the disclosure are their own columns, not part of the text, so
|
|
78
|
+
* `renderMarker` and `renderToggle` still apply alongside it.
|
|
79
|
+
*/
|
|
80
|
+
renderItem?: StepRenderer;
|
|
81
|
+
/**
|
|
82
|
+
* The step's icon when rendering from `steps` — the data-driven half of the `marker` slot. Return an `<svg>`, an
|
|
83
|
+
* icon element, a letter; anything Lit renders. Without one the marker draws the glyph for the step's status.
|
|
84
|
+
*/
|
|
85
|
+
renderMarker?: StepRenderer;
|
|
86
|
+
/** The step's disclosure affordance when rendering from `steps` — the data-driven half of the `toggle` slot. */
|
|
87
|
+
renderToggle?: StepRenderer;
|
|
88
|
+
/** Replaces the label when rendering from `steps`. */
|
|
89
|
+
renderLabel?: StepRenderer;
|
|
90
|
+
/** Replaces the dimmed detail when rendering from `steps`. */
|
|
91
|
+
renderDetail?: StepRenderer;
|
|
92
|
+
/** Replaces the trailing content when rendering from `steps`. */
|
|
93
|
+
renderTrailing?: StepRenderer;
|
|
94
|
+
/**
|
|
95
|
+
* The status this element last wrote to each step, which is how it knows whether a step is still its to write.
|
|
96
|
+
*
|
|
97
|
+
* `status` reflects, and a server-rendered step arrives with the default already stamped on it, so the presence
|
|
98
|
+
* of the attribute proves nothing about who put it there. A step is ours while it still holds what we last gave
|
|
99
|
+
* it — the moment a run sets something else on it, it is the run's, for good.
|
|
100
|
+
*/
|
|
101
|
+
private readonly written;
|
|
102
|
+
/**
|
|
103
|
+
* Steps this element has already laid out. A step it has not seen before is new — but only once the list itself
|
|
104
|
+
* has been drawn: on the first pass every step is new, and a whole trace fading in at once is not an arrival,
|
|
105
|
+
* it is a page loading.
|
|
106
|
+
*/
|
|
107
|
+
private readonly known;
|
|
108
|
+
private hasSynced;
|
|
109
|
+
/**
|
|
110
|
+
* A run ticks a step over by setting `status` on it, which is nothing this element renders and so nothing Lit
|
|
111
|
+
* would notice. Watching the attribute is what lets a parent roll the change up and a group open on it.
|
|
112
|
+
*/
|
|
113
|
+
private observer?;
|
|
114
|
+
connectedCallback(): void;
|
|
115
|
+
disconnectedCallback(): void;
|
|
116
|
+
protected updated(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Changes one step of `steps` in place and redraws, without rebuilding the array — what a task runner wants when
|
|
119
|
+
* it ticks a step over hundreds of times. Returns `false` when no step carries that `id`.
|
|
120
|
+
*/
|
|
121
|
+
updateStep(id: string, patch: Partial<StepNode>): boolean;
|
|
122
|
+
/** Brings every group back into view. */
|
|
123
|
+
expandAll(): void;
|
|
124
|
+
/** Folds every group away, leaving the top-level stages. */
|
|
125
|
+
collapseAll(): void;
|
|
126
|
+
private setCollapsedOfAll;
|
|
127
|
+
/** Every step in the list, wherever it came from. */
|
|
128
|
+
private allSteps;
|
|
129
|
+
/**
|
|
130
|
+
* The nearest `c2-step` descendants of `root`, looking through anything that is not one.
|
|
131
|
+
*
|
|
132
|
+
* A step is rarely a literal child: Astro wraps every island in an `<astro-island>` (which is
|
|
133
|
+
* `display: contents`, so it changes nothing but the tree), and a consumer may wrap rows in a `<div>`. Matching
|
|
134
|
+
* only direct children silently found nothing there, and every step kept its defaults.
|
|
135
|
+
*/
|
|
136
|
+
private static collectSteps;
|
|
137
|
+
/** Top-level steps, whether they came from the slot or from `steps`. */
|
|
138
|
+
private get rootSteps();
|
|
139
|
+
/**
|
|
140
|
+
* Writes depth, position and presentation onto every step, and gives a parent that authored no `status` the one
|
|
141
|
+
* rolled up from its children — which is why the walk returns the statuses it settled on.
|
|
142
|
+
*
|
|
143
|
+
* Cheap to repeat: each value is a property assignment Lit will no-op when unchanged.
|
|
144
|
+
*/
|
|
145
|
+
private syncSteps;
|
|
146
|
+
/**
|
|
147
|
+
* Whether this element may still write a step's status. A step it has never written is its to write while the
|
|
148
|
+
* step is `pending` — what "nobody said" looks like, from the markup or from the server. After that it is ours
|
|
149
|
+
* only while it still holds the value we gave it.
|
|
150
|
+
*/
|
|
151
|
+
private mayWrite;
|
|
152
|
+
/** A parent takes the most urgent status under it; a leaf takes the wizard's `current`, or nothing happened yet. */
|
|
153
|
+
private deriveStatus;
|
|
154
|
+
/** The status a data node ends up with, so a renderer is handed what is actually drawn. */
|
|
155
|
+
private statusOf;
|
|
156
|
+
private renderNode;
|
|
157
|
+
render(): TemplateResult<1>;
|
|
158
|
+
}
|
|
159
|
+
declare global {
|
|
160
|
+
interface HTMLElementTagNameMap {
|
|
161
|
+
'c2-steps': Steps;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../src/steps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAM/E,OAAO,KAAK,EAAe,QAAQ,EAAE,YAAY,EAAc,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAInG,OAAO,WAAW,CAAA;AAElB,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACnG,YAAY,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAgBpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,qBACa,KAAM,SAAQ,UAAU;IACnC,OAAgB,MAAM,0BAAoB;IAE1C,+EAA+E;IAClD,MAAM,EAAE,WAAW,CAAS;IAEzD;;;;OAIG;IACwC,OAAO,SAAK;IAEvD,wFAAwF;IACxC,KAAK,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAY;IAEzF,oCAAoC;IACY,SAAS,EAAE,MAAM,GAAG,IAAI,CAAO;IAE/E;;;;;OAKG;IAC6B,UAAU,CAAC,EAAE,YAAY,CAAA;IAEzD;;;OAGG;IAC6B,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3D,gHAAgH;IAChF,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3D,sDAAsD;IACtB,WAAW,CAAC,EAAE,YAAY,CAAA;IAE1D,8DAA8D;IAC9B,YAAY,CAAC,EAAE,YAAY,CAAA;IAE3D,iEAAiE;IACjC,cAAc,CAAC,EAAE,YAAY,CAAA;IAE7D;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAE7D;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,SAAS,CAAQ;IAEzB;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,CAAkB;IAE1B,iBAAiB;IAOjB,oBAAoB;cAKV,OAAO;IAI1B;;;OAGG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO;IAgBzD,yCAAyC;IACzC,SAAS;IAIT,4DAA4D;IAC5D,WAAW;IAIX,OAAO,CAAC,iBAAiB;IAIzB,qDAAqD;IACrD,OAAO,CAAC,QAAQ;IAKhB;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;IAS3B,wEAAwE;IACxE,OAAO,KAAK,SAAS,GAIpB;IAED;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAoCjB;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IAKhB,oHAAoH;IACpH,OAAO,CAAC,YAAY;IAMpB,2FAA2F;IAC3F,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,UAAU;IA4BT,MAAM;CAShB;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,UAAU,EAAE,KAAK,CAAA;KAClB;CACF"}
|
package/vue.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// GENERATED by @c2n/framework-types. Do not edit by hand.
|
|
2
|
+
//
|
|
3
|
+
// Vue template types for the custom elements of @c2n/steps. Import once, anywhere in the program:
|
|
4
|
+
//
|
|
5
|
+
// import '@c2n/steps/vue'
|
|
6
|
+
//
|
|
7
|
+
// Tell the compiler about the tags as well, or every c2-* tag is resolved as a Vue component and renders
|
|
8
|
+
// nothing: template.compilerOptions.isCustomElement = (tag) => tag.startsWith('c2-') in vite.config.ts.
|
|
9
|
+
|
|
10
|
+
import type { DefineComponent, HTMLAttributes } from 'vue'
|
|
11
|
+
import type { Step, StepEventMap } from '@c2n/steps/step.js'
|
|
12
|
+
import type { Steps, StepsEventMap } from '@c2n/steps'
|
|
13
|
+
|
|
14
|
+
/** The element's own public properties, plus every attribute Vue understands on a host element. */
|
|
15
|
+
type C2Props<T> = Partial<Omit<T, keyof HTMLElement>> & HTMLAttributes
|
|
16
|
+
|
|
17
|
+
declare module 'vue' {
|
|
18
|
+
interface GlobalComponents {
|
|
19
|
+
'c2-step': DefineComponent<
|
|
20
|
+
C2Props<Step> & {
|
|
21
|
+
onStepToggle?: (event: StepEventMap['step-toggle']) => void
|
|
22
|
+
}
|
|
23
|
+
>
|
|
24
|
+
'c2-steps': DefineComponent<
|
|
25
|
+
C2Props<Steps> & {
|
|
26
|
+
'aria-label'?: unknown
|
|
27
|
+
onStepToggle?: (event: StepsEventMap['step-toggle']) => void
|
|
28
|
+
}
|
|
29
|
+
>
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
declare module '@vue/runtime-dom' {
|
|
34
|
+
interface HTMLAttributes {
|
|
35
|
+
/** Vue's own definition omits it, and slotting a plain element into a component needs it. */
|
|
36
|
+
slot?: string
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export {}
|
package/vue.js
ADDED