@zeyos/zx 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +51 -0
- package/README.md +15 -0
- package/dist/types/compat/base.d.ts +156 -0
- package/dist/types/compat/globals.d.ts +20 -0
- package/dist/types/compat/index.d.ts +128 -0
- package/dist/types/compat/map/basic.d.ts +175 -0
- package/dist/types/compat/map/data.d.ts +102 -0
- package/dist/types/compat/map/date-time.d.ts +80 -0
- package/dist/types/compat/map/factory.d.ts +9 -0
- package/dist/types/compat/map/form.d.ts +98 -0
- package/dist/types/compat/map/helpers.d.ts +12 -0
- package/dist/types/compat/map/http.d.ts +36 -0
- package/dist/types/compat/map/layout.d.ts +106 -0
- package/dist/types/compat/map/options.d.ts +80 -0
- package/dist/types/compat/map/select.d.ts +95 -0
- package/dist/types/compat/map/stubs.d.ts +32 -0
- package/dist/types/compat/map/utilities.d.ts +37 -0
- package/dist/types/compat-entry.d.ts +5 -0
- package/dist/types/components/badge/badge.d.ts +46 -0
- package/dist/types/components/breadcrumb/breadcrumb.d.ts +200 -0
- package/dist/types/components/button/button.d.ts +42 -0
- package/dist/types/components/check-button/check-button.d.ts +98 -0
- package/dist/types/components/checklist/checklist.d.ts +143 -0
- package/dist/types/components/checklist/field-adapter.d.ts +5 -0
- package/dist/types/components/context-menu/context-menu.d.ts +130 -0
- package/dist/types/components/copy/copy-button.d.ts +48 -0
- package/dist/types/components/copy/copy-input.d.ts +91 -0
- package/dist/types/components/data-filter/data-filter.d.ts +250 -0
- package/dist/types/components/data-filter/filter-core.d.ts +52 -0
- package/dist/types/components/date-picker/date-picker.d.ts +137 -0
- package/dist/types/components/date-picker/date-range-picker.d.ts +350 -0
- package/dist/types/components/date-picker/field-adapter.d.ts +6 -0
- package/dist/types/components/date-picker/month-picker.d.ts +75 -0
- package/dist/types/components/date-picker/range-field-adapter.d.ts +7 -0
- package/dist/types/components/date-picker/time-picker.d.ts +127 -0
- package/dist/types/components/datebox/date-range-box.d.ts +218 -0
- package/dist/types/components/datebox/datebox.d.ts +160 -0
- package/dist/types/components/datebox/field-adapter.d.ts +5 -0
- package/dist/types/components/dialog/dialog.d.ts +284 -0
- package/dist/types/components/dropdown/dropdown.d.ts +118 -0
- package/dist/types/components/empty-state/empty-state.d.ts +38 -0
- package/dist/types/components/field/field.d.ts +231 -0
- package/dist/types/components/field-upload/field-adapter.d.ts +5 -0
- package/dist/types/components/field-upload/field-upload.d.ts +213 -0
- package/dist/types/components/fieldset/fieldset.d.ts +125 -0
- package/dist/types/components/finder/finder.d.ts +252 -0
- package/dist/types/components/form/form.d.ts +194 -0
- package/dist/types/components/groupbox/groupbox.d.ts +89 -0
- package/dist/types/components/layout/layout.d.ts +132 -0
- package/dist/types/components/loading/inline-loading.d.ts +86 -0
- package/dist/types/components/loading/progress-bar.d.ts +168 -0
- package/dist/types/components/loading/spinner.d.ts +34 -0
- package/dist/types/components/master-panel/master-panel.d.ts +112 -0
- package/dist/types/components/menu-button/menu-button.d.ts +142 -0
- package/dist/types/components/message/message.d.ts +212 -0
- package/dist/types/components/modal/modal.d.ts +105 -0
- package/dist/types/components/multi-value-editor/field-adapter.d.ts +5 -0
- package/dist/types/components/multi-value-editor/multi-value-editor.d.ts +66 -0
- package/dist/types/components/navigation-bar/navigation-bar.d.ts +229 -0
- package/dist/types/components/number-field/field-adapter.d.ts +5 -0
- package/dist/types/components/number-field/number-field.d.ts +292 -0
- package/dist/types/components/pagination/pagination.d.ts +267 -0
- package/dist/types/components/panel/panel.d.ts +194 -0
- package/dist/types/components/permission/permission.d.ts +93 -0
- package/dist/types/components/rating/field-adapter.d.ts +5 -0
- package/dist/types/components/rating/rating.d.ts +213 -0
- package/dist/types/components/search/search.d.ts +98 -0
- package/dist/types/components/select/field-adapter.d.ts +5 -0
- package/dist/types/components/select/filter.d.ts +11 -0
- package/dist/types/components/select/select.d.ts +235 -0
- package/dist/types/components/skeleton/skeleton.d.ts +97 -0
- package/dist/types/components/slider/field-adapter.d.ts +5 -0
- package/dist/types/components/slider/slider.d.ts +216 -0
- package/dist/types/components/split-view/split-view.d.ts +335 -0
- package/dist/types/components/stepper/stepper.d.ts +314 -0
- package/dist/types/components/stepper/steps.d.ts +131 -0
- package/dist/types/components/tabbox/tabbox.d.ts +230 -0
- package/dist/types/components/table/sort.d.ts +49 -0
- package/dist/types/components/table/table.d.ts +872 -0
- package/dist/types/components/tag-picker/field-adapter.d.ts +5 -0
- package/dist/types/components/tag-picker/tag-picker.d.ts +375 -0
- package/dist/types/components/timebox/field-adapter.d.ts +5 -0
- package/dist/types/components/timebox/timebox.d.ts +121 -0
- package/dist/types/components/toggle/field-adapter.d.ts +5 -0
- package/dist/types/components/toggle/toggle.d.ts +94 -0
- package/dist/types/components/toolbar/toolbar.d.ts +230 -0
- package/dist/types/components/tooltip/tooltip.d.ts +183 -0
- package/dist/types/components/tree/hierarchy.d.ts +113 -0
- package/dist/types/components/tree/tree.d.ts +383 -0
- package/dist/types/components/truncate/truncate.d.ts +61 -0
- package/dist/types/components/value-list/field-adapter.d.ts +5 -0
- package/dist/types/components/value-list/value-list.d.ts +143 -0
- package/dist/types/core/breakpoint.d.ts +68 -0
- package/dist/types/core/component.d.ts +115 -0
- package/dist/types/core/date.d.ts +50 -0
- package/dist/types/core/dom.d.ts +86 -0
- package/dist/types/core/export.d.ts +70 -0
- package/dist/types/core/fontawesome.d.ts +107 -0
- package/dist/types/core/format.d.ts +107 -0
- package/dist/types/core/http.d.ts +122 -0
- package/dist/types/core/i18n.d.ts +35 -0
- package/dist/types/core/icons.d.ts +137 -0
- package/dist/types/core/keyboard.d.ts +72 -0
- package/dist/types/core/position.d.ts +45 -0
- package/dist/types/core/storage.d.ts +46 -0
- package/dist/types/core/util.d.ts +117 -0
- package/dist/types/elements/define.d.ts +73 -0
- package/dist/types/elements/reflect.d.ts +27 -0
- package/dist/types/index.d.ts +79 -0
- package/dist/types/zeyos/connect.d.ts +65 -0
- package/dist/types/zeyos/form.d.ts +140 -0
- package/dist/types/zeyos/icons.d.ts +104 -0
- package/dist/types/zeyos/index.d.ts +12 -0
- package/dist/types/zeyos/modules.d.ts +110 -0
- package/dist/types/zeyos/query.d.ts +157 -0
- package/dist/types/zeyos/schema.d.ts +79 -0
- package/dist/types/zeyos/select.d.ts +167 -0
- package/dist/types/zeyos/table.d.ts +205 -0
- package/dist/zx-compat.esm.js +375 -39
- package/dist/zx-compat.esm.min.js +1 -1
- package/dist/zx-compat.global.js +372 -73
- package/dist/zx-compat.global.min.js +3 -3
- package/dist/zx-zeyos.esm.js +355 -49
- package/dist/zx-zeyos.esm.min.js +1 -1
- package/dist/zx.css +68 -6
- package/dist/zx.esm.js +359 -73
- package/dist/zx.esm.min.js +3 -3
- package/dist/zx.global.js +359 -73
- package/dist/zx.global.min.js +3 -3
- package/dist/zx.min.css +1 -1
- package/docs/api.json +48 -2
- package/docs/llms.md +31 -0
- package/package.json +37 -9
- package/src/compat/base.js +291 -0
- package/src/compat/globals.js +165 -0
- package/src/compat/index.js +84 -0
- package/src/compat/map/basic.js +464 -0
- package/src/compat/map/data.js +232 -0
- package/src/compat/map/date-time.js +177 -0
- package/src/compat/map/factory.js +45 -0
- package/src/compat/map/form.js +330 -0
- package/src/compat/map/helpers.js +46 -0
- package/src/compat/map/http.js +117 -0
- package/src/compat/map/layout.js +256 -0
- package/src/compat/map/options.js +267 -0
- package/src/compat/map/select.js +198 -0
- package/src/compat/map/stubs.js +26 -0
- package/src/compat/map/utilities.js +113 -0
- package/src/compat-entry.js +11 -0
- package/src/components/badge/badge.css +147 -0
- package/src/components/badge/badge.js +92 -0
- package/src/components/breadcrumb/breadcrumb.css +105 -0
- package/src/components/breadcrumb/breadcrumb.js +331 -0
- package/src/components/button/button.css +104 -0
- package/src/components/button/button.js +76 -0
- package/src/components/check-button/check-button.css +66 -0
- package/src/components/check-button/check-button.js +167 -0
- package/src/components/checklist/checklist.css +65 -0
- package/src/components/checklist/checklist.js +282 -0
- package/src/components/checklist/field-adapter.js +46 -0
- package/src/components/context-menu/context-menu.css +54 -0
- package/src/components/context-menu/context-menu.js +334 -0
- package/src/components/copy/copy-button.css +27 -0
- package/src/components/copy/copy-button.js +78 -0
- package/src/components/copy/copy-input.css +59 -0
- package/src/components/copy/copy-input.js +123 -0
- package/src/components/data-filter/data-filter.css +53 -0
- package/src/components/data-filter/data-filter.js +400 -0
- package/src/components/data-filter/filter-core.js +128 -0
- package/src/components/date-picker/date-picker.css +181 -0
- package/src/components/date-picker/date-picker.js +500 -0
- package/src/components/date-picker/date-range-picker.css +264 -0
- package/src/components/date-picker/date-range-picker.js +990 -0
- package/src/components/date-picker/field-adapter.js +36 -0
- package/src/components/date-picker/month-picker.js +223 -0
- package/src/components/date-picker/range-field-adapter.js +31 -0
- package/src/components/date-picker/time-picker.css +191 -0
- package/src/components/date-picker/time-picker.js +406 -0
- package/src/components/datebox/date-range-box.css +128 -0
- package/src/components/datebox/date-range-box.js +492 -0
- package/src/components/datebox/datebox.css +108 -0
- package/src/components/datebox/datebox.js +358 -0
- package/src/components/datebox/field-adapter.js +34 -0
- package/src/components/dialog/dialog.css +74 -0
- package/src/components/dialog/dialog.js +450 -0
- package/src/components/dropdown/dropdown.css +24 -0
- package/src/components/dropdown/dropdown.js +288 -0
- package/src/components/empty-state/empty-state.css +80 -0
- package/src/components/empty-state/empty-state.js +92 -0
- package/src/components/field/field.css +127 -0
- package/src/components/field/field.js +605 -0
- package/src/components/field-upload/field-adapter.js +21 -0
- package/src/components/field-upload/field-upload.css +108 -0
- package/src/components/field-upload/field-upload.js +475 -0
- package/src/components/fieldset/fieldset.css +37 -0
- package/src/components/fieldset/fieldset.js +307 -0
- package/src/components/finder/finder.css +98 -0
- package/src/components/finder/finder.js +509 -0
- package/src/components/form/form.css +32 -0
- package/src/components/form/form.js +302 -0
- package/src/components/groupbox/groupbox.css +51 -0
- package/src/components/groupbox/groupbox.js +199 -0
- package/src/components/layout/layout.css +117 -0
- package/src/components/layout/layout.js +136 -0
- package/src/components/loading/inline-loading.css +34 -0
- package/src/components/loading/inline-loading.js +140 -0
- package/src/components/loading/progress-bar.css +115 -0
- package/src/components/loading/progress-bar.js +259 -0
- package/src/components/loading/spinner.css +58 -0
- package/src/components/loading/spinner.js +57 -0
- package/src/components/master-panel/master-panel.css +51 -0
- package/src/components/master-panel/master-panel.js +203 -0
- package/src/components/menu-button/menu-button.css +49 -0
- package/src/components/menu-button/menu-button.js +294 -0
- package/src/components/message/message.css +122 -0
- package/src/components/message/message.js +499 -0
- package/src/components/modal/modal.css +47 -0
- package/src/components/modal/modal.js +203 -0
- package/src/components/multi-value-editor/field-adapter.js +44 -0
- package/src/components/multi-value-editor/multi-value-editor.css +56 -0
- package/src/components/multi-value-editor/multi-value-editor.js +170 -0
- package/src/components/navigation-bar/navigation-bar.css +130 -0
- package/src/components/navigation-bar/navigation-bar.js +450 -0
- package/src/components/number-field/field-adapter.js +40 -0
- package/src/components/number-field/number-field.css +77 -0
- package/src/components/number-field/number-field.js +545 -0
- package/src/components/pagination/pagination.css +95 -0
- package/src/components/pagination/pagination.js +481 -0
- package/src/components/panel/panel.css +123 -0
- package/src/components/panel/panel.js +336 -0
- package/src/components/permission/permission.css +47 -0
- package/src/components/permission/permission.js +198 -0
- package/src/components/rating/field-adapter.js +34 -0
- package/src/components/rating/rating.css +97 -0
- package/src/components/rating/rating.js +395 -0
- package/src/components/search/search.css +70 -0
- package/src/components/search/search.js +193 -0
- package/src/components/select/field-adapter.js +24 -0
- package/src/components/select/filter.js +39 -0
- package/src/components/select/select.css +180 -0
- package/src/components/select/select.js +663 -0
- package/src/components/skeleton/skeleton.css +76 -0
- package/src/components/skeleton/skeleton.js +139 -0
- package/src/components/slider/field-adapter.js +36 -0
- package/src/components/slider/slider.css +181 -0
- package/src/components/slider/slider.js +399 -0
- package/src/components/split-view/split-view.css +139 -0
- package/src/components/split-view/split-view.js +806 -0
- package/src/components/stepper/stepper.css +234 -0
- package/src/components/stepper/stepper.js +459 -0
- package/src/components/stepper/steps.js +131 -0
- package/src/components/tabbox/tabbox.css +281 -0
- package/src/components/tabbox/tabbox.js +484 -0
- package/src/components/table/sort.js +85 -0
- package/src/components/table/table.css +364 -0
- package/src/components/table/table.js +1711 -0
- package/src/components/tag-picker/field-adapter.js +35 -0
- package/src/components/tag-picker/tag-picker.css +169 -0
- package/src/components/tag-picker/tag-picker.js +837 -0
- package/src/components/timebox/field-adapter.js +24 -0
- package/src/components/timebox/timebox.css +51 -0
- package/src/components/timebox/timebox.js +276 -0
- package/src/components/toggle/field-adapter.js +24 -0
- package/src/components/toggle/toggle.css +66 -0
- package/src/components/toggle/toggle.js +150 -0
- package/src/components/toolbar/toolbar.css +81 -0
- package/src/components/toolbar/toolbar.js +511 -0
- package/src/components/tooltip/tooltip.css +36 -0
- package/src/components/tooltip/tooltip.js +420 -0
- package/src/components/tree/hierarchy.js +151 -0
- package/src/components/tree/tree.css +99 -0
- package/src/components/tree/tree.js +784 -0
- package/src/components/truncate/truncate.css +20 -0
- package/src/components/truncate/truncate.js +92 -0
- package/src/components/value-list/field-adapter.js +24 -0
- package/src/components/value-list/value-list.css +108 -0
- package/src/components/value-list/value-list.js +336 -0
- package/src/core/breakpoint.js +150 -0
- package/src/core/component.js +292 -0
- package/src/core/date.js +216 -0
- package/src/core/dom.js +260 -0
- package/src/core/export.js +204 -0
- package/src/core/fontawesome.js +177 -0
- package/src/core/format.js +283 -0
- package/src/core/http.js +246 -0
- package/src/core/i18n.js +83 -0
- package/src/core/icons.js +283 -0
- package/src/core/keyboard.js +240 -0
- package/src/core/position.js +177 -0
- package/src/core/storage.js +175 -0
- package/src/core/util.js +336 -0
- package/src/elements/define.js +715 -0
- package/src/elements/reflect.js +79 -0
- package/src/index.js +131 -0
- package/src/zeyos/connect.js +142 -0
- package/src/zeyos/form.js +254 -0
- package/src/zeyos/icons.js +92 -0
- package/src/zeyos/index.js +21 -0
- package/src/zeyos/modules.js +269 -0
- package/src/zeyos/query.js +199 -0
- package/src/zeyos/schema.js +474 -0
- package/src/zeyos/select.js +175 -0
- package/src/zeyos/table.js +272 -0
- package/styles/base.css +124 -0
- package/styles/icons.css +34 -0
- package/styles/tokens/dark.css +84 -0
- package/styles/tokens/density.css +9 -0
- package/styles/tokens/global.css +80 -0
- package/styles/tokens/modules.css +109 -0
- package/styles/tokens/semantic.css +49 -0
- package/styles/zx.css +61 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM-free step-list logic shared by {@link Stepper}: validation, normalization, and the
|
|
3
|
+
* index arithmetic behind `next()` / `previous()`.
|
|
4
|
+
* @module components/stepper/steps
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {Object} StepDefinition
|
|
9
|
+
* @property {string} name Stable step name, unique within the stepper.
|
|
10
|
+
* @property {string} title Visible step title.
|
|
11
|
+
* @property {string} [description] Secondary line rendered under the title.
|
|
12
|
+
* @property {boolean} [optional=false] Marks the step as skippable.
|
|
13
|
+
* @property {boolean} [disabled=false] Whether the step can be activated.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {Object} NormalizedStep
|
|
18
|
+
* @property {string} name Stable step name.
|
|
19
|
+
* @property {string} title Visible step title.
|
|
20
|
+
* @property {string|null} description Secondary line, or null.
|
|
21
|
+
* @property {boolean} optional Whether the step is skippable.
|
|
22
|
+
* @property {boolean} disabled Whether the step can be activated.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Validates and normalizes a step list. Every step needs a unique non-empty name; every other
|
|
27
|
+
* property is coerced to its documented type.
|
|
28
|
+
* @param {StepDefinition[]} list Step definitions.
|
|
29
|
+
* @returns {NormalizedStep[]} Normalized copies — the input objects are never mutated.
|
|
30
|
+
* @throws {TypeError} When the list or a step is malformed.
|
|
31
|
+
* @throws {RangeError} When two steps share a name.
|
|
32
|
+
*/
|
|
33
|
+
export function normalizeSteps(list) {
|
|
34
|
+
if (!Array.isArray(list)) throw new TypeError('Stepper steps must be an array');
|
|
35
|
+
const names = new Set();
|
|
36
|
+
return list.map((step) => {
|
|
37
|
+
if (!step || typeof step !== 'object' || Array.isArray(step)) {
|
|
38
|
+
throw new TypeError('Step definition must be an object');
|
|
39
|
+
}
|
|
40
|
+
if (typeof step.name !== 'string' || step.name === '') {
|
|
41
|
+
throw new TypeError('Step name must be a non-empty string');
|
|
42
|
+
}
|
|
43
|
+
if (names.has(step.name)) throw new RangeError(`Step already exists: ${step.name}`);
|
|
44
|
+
names.add(step.name);
|
|
45
|
+
return {
|
|
46
|
+
name: step.name,
|
|
47
|
+
title: String(step.title ?? ''),
|
|
48
|
+
description: step.description == null ? null : String(step.description),
|
|
49
|
+
optional: Boolean(step.optional),
|
|
50
|
+
disabled: Boolean(step.disabled)
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns the index of a step by name.
|
|
57
|
+
* @param {NormalizedStep[]} steps Normalized steps.
|
|
58
|
+
* @param {string|null} name Step name.
|
|
59
|
+
* @returns {number} Zero-based index, or -1 when the name is unknown or null.
|
|
60
|
+
*/
|
|
61
|
+
export function stepIndex(steps, name) {
|
|
62
|
+
if (name === null) return -1;
|
|
63
|
+
return steps.findIndex((step) => step.name === name);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Resolves the next enabled step in a direction, skipping disabled steps. Starting from -1 walks
|
|
68
|
+
* in from the matching end, so `resolveStepIndex(steps, -1, 1)` is the first enabled step.
|
|
69
|
+
* @param {NormalizedStep[]} steps Normalized steps.
|
|
70
|
+
* @param {number} from Zero-based index to start from, or -1 for "outside the list".
|
|
71
|
+
* @param {number} direction Positive to move forward, negative to move backward.
|
|
72
|
+
* @returns {number} Zero-based index, or -1 when no enabled step lies that way.
|
|
73
|
+
*/
|
|
74
|
+
export function resolveStepIndex(steps, from, direction) {
|
|
75
|
+
const step = direction < 0 ? -1 : 1;
|
|
76
|
+
let cursor = from < 0 ? (step > 0 ? 0 : steps.length - 1) : from + step;
|
|
77
|
+
while (cursor >= 0 && cursor < steps.length) {
|
|
78
|
+
if (!steps[cursor].disabled) return cursor;
|
|
79
|
+
cursor += step;
|
|
80
|
+
}
|
|
81
|
+
return -1;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Names of the steps a move marks complete. Advancing past a step completes it — including every
|
|
86
|
+
* step skipped over by a jump — while moving backwards completes nothing, so a user can walk back
|
|
87
|
+
* through a wizard without erasing their progress.
|
|
88
|
+
* @param {NormalizedStep[]} steps Normalized steps.
|
|
89
|
+
* @param {number} from Zero-based index being left, or -1 when nothing was active.
|
|
90
|
+
* @param {number} to Zero-based index being activated.
|
|
91
|
+
* @returns {string[]} Names to add to the completed set, in step order.
|
|
92
|
+
*/
|
|
93
|
+
export function completedByAdvance(steps, from, to) {
|
|
94
|
+
if (from < 0 || to <= from) return [];
|
|
95
|
+
return steps.slice(from, to).map((step) => step.name);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @typedef {Object} StepStateContext
|
|
100
|
+
* @property {number} [activeIndex=-1] Zero-based active index, or -1 when nothing is active.
|
|
101
|
+
* @property {Set<string>|string[]} [completed] Completed step names.
|
|
102
|
+
* @property {Set<string>|string[]} [errored] Errored step names.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Resolves the rendered state of one step. Errors win over everything, so a step the user has to
|
|
107
|
+
* come back and fix stays visible as a problem even while it is the active one; being active in
|
|
108
|
+
* turn wins over being complete, because where the user stands matters more than where they have
|
|
109
|
+
* already been.
|
|
110
|
+
* @param {NormalizedStep} step Normalized step.
|
|
111
|
+
* @param {number} index Zero-based index of the step.
|
|
112
|
+
* @param {StepStateContext} [context={}] Rail state.
|
|
113
|
+
* @returns {'upcoming'|'active'|'complete'|'error'}
|
|
114
|
+
*/
|
|
115
|
+
export function stepState(step, index, context = {}) {
|
|
116
|
+
const { activeIndex = -1, completed, errored } = context;
|
|
117
|
+
if (contains(errored, step.name)) return 'error';
|
|
118
|
+
if (index === activeIndex) return 'active';
|
|
119
|
+
if (contains(completed, step.name)) return 'complete';
|
|
120
|
+
return 'upcoming';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @param {Set<string>|string[]|undefined|null} source Set or array of names.
|
|
125
|
+
* @param {string} name Name to look for.
|
|
126
|
+
* @returns {boolean}
|
|
127
|
+
*/
|
|
128
|
+
function contains(source, name) {
|
|
129
|
+
if (!source) return false;
|
|
130
|
+
return source instanceof Set ? source.has(name) : source.includes(name);
|
|
131
|
+
}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Four tab appearances, all square-cornered by default:
|
|
3
|
+
*
|
|
4
|
+
* divided (default) flat blocks on a muted track, split by hairline dividers, the active
|
|
5
|
+
* block lifted onto the panel surface under an accent rule — the workhorse for a
|
|
6
|
+
* record page or a panel that owns its content box.
|
|
7
|
+
* bracket folder tabs that outline and fuse into the panel below, the active tab bridging
|
|
8
|
+
* the seam — for document-like views where the tabs belong to the sheet.
|
|
9
|
+
* segmented a compact group on a muted fill, the active tab raised onto a control surface —
|
|
10
|
+
* for switching a view inside a toolbar or card header, where the row reads as one
|
|
11
|
+
* control rather than as navigation.
|
|
12
|
+
* line a full-width rule with the active tab underlined — for page- and section-level
|
|
13
|
+
* navigation, where the row spans the content it switches.
|
|
14
|
+
*
|
|
15
|
+
* `divided` and `bracket` draw the panel box themselves; `line` and `segmented` leave the panel
|
|
16
|
+
* bare so the surrounding layout supplies the chrome.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
.zx-tabbox {
|
|
20
|
+
/* Corner rounding for the boxed variants. 0 keeps every corner square; set it to
|
|
21
|
+
`var(--zx-radius-lg)` on the root for the rounded pill group Zx shipped previously. */
|
|
22
|
+
--zx-tabbox-radius: 0px;
|
|
23
|
+
min-inline-size: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.zx-tabbox__tablist {
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: stretch;
|
|
29
|
+
/* Horizontal-only scroll for overflowing tab rows. Setting overflow-x alone would
|
|
30
|
+
compute overflow-y to auto and reveal a phantom vertical scrollbar, so pin it. */
|
|
31
|
+
overflow-x: auto;
|
|
32
|
+
overflow-y: hidden;
|
|
33
|
+
scrollbar-width: none;
|
|
34
|
+
scrollbar-gutter: auto;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.zx-tabbox__tablist::-webkit-scrollbar {
|
|
38
|
+
display: none;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.zx-tabbox__tab {
|
|
42
|
+
position: relative;
|
|
43
|
+
display: inline-flex;
|
|
44
|
+
flex: 0 0 auto;
|
|
45
|
+
align-items: center;
|
|
46
|
+
justify-content: center;
|
|
47
|
+
gap: var(--zx-space-2);
|
|
48
|
+
/* `styles/base.css` gives every bare button the control height as a minimum and the control
|
|
49
|
+
radius as its corners. Both have to be cleared here: the tab sets its own height per variant —
|
|
50
|
+
and segmented asks for 100% of a track shorter than that — while the corners belong to
|
|
51
|
+
`--zx-tabbox-radius`, which is square by default. Left in place, `divided` and `line` would
|
|
52
|
+
keep a rounded fill inside a squared row. The variants that want corners set them below. */
|
|
53
|
+
min-block-size: 0;
|
|
54
|
+
border: 0;
|
|
55
|
+
border-radius: 0;
|
|
56
|
+
background: none;
|
|
57
|
+
color: var(--zx-color-text-muted);
|
|
58
|
+
font: inherit;
|
|
59
|
+
font-size: var(--zx-control-font-size);
|
|
60
|
+
font-weight: 500;
|
|
61
|
+
white-space: nowrap;
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.zx-tabbox__tab:hover:not([aria-disabled="true"]) {
|
|
66
|
+
color: var(--zx-color-text);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.zx-tabbox__tab[aria-selected="true"] {
|
|
70
|
+
color: var(--zx-color-text);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.zx-tabbox__tab[aria-disabled="true"] {
|
|
74
|
+
color: var(--zx-color-text-placeholder);
|
|
75
|
+
cursor: not-allowed;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.zx-tabbox__icon {
|
|
79
|
+
display: inline-grid;
|
|
80
|
+
flex: none;
|
|
81
|
+
place-items: center;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/* ------------------------------------------------------------- divided variant -- */
|
|
85
|
+
|
|
86
|
+
.zx-tabbox[data-variant="divided"] .zx-tabbox__tablist {
|
|
87
|
+
border-block-end: 1px solid var(--zx-color-border);
|
|
88
|
+
background: var(--zx-color-bg-muted);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.zx-tabbox[data-variant="divided"] .zx-tabbox__tab {
|
|
92
|
+
block-size: calc(var(--zx-control-height) + 8px);
|
|
93
|
+
/* The top rule is the selected marker; transparent here keeps every block the same height. */
|
|
94
|
+
border-block-start: 2px solid transparent;
|
|
95
|
+
border-inline-end: 1px solid var(--zx-color-border);
|
|
96
|
+
padding-inline: var(--zx-space-4);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.zx-tabbox[data-variant="divided"] .zx-tabbox__tab:last-child {
|
|
100
|
+
border-inline-end: 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.zx-tabbox[data-variant="divided"] .zx-tabbox__tab:hover:not([aria-disabled="true"]):not([aria-selected="true"]) {
|
|
104
|
+
background: var(--zx-color-bg-hover);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.zx-tabbox[data-variant="divided"] .zx-tabbox__tab[aria-selected="true"] {
|
|
108
|
+
border-block-start-color: var(--zx-color-accent);
|
|
109
|
+
background: var(--zx-color-bg-surface);
|
|
110
|
+
font-weight: 650;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.zx-tabbox[data-variant="divided"] .zx-tabbox__tab:focus-visible {
|
|
114
|
+
z-index: 1;
|
|
115
|
+
outline: 0;
|
|
116
|
+
box-shadow: inset var(--zx-focus-ring);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* ------------------------------------------------------------- bracket variant -- */
|
|
120
|
+
|
|
121
|
+
.zx-tabbox[data-variant="bracket"] .zx-tabbox__tablist {
|
|
122
|
+
border-block-end: 1px solid var(--zx-color-border);
|
|
123
|
+
padding-inline-start: var(--zx-space-2);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.zx-tabbox[data-variant="bracket"] .zx-tabbox__tab {
|
|
127
|
+
block-size: calc(var(--zx-control-height) + 8px);
|
|
128
|
+
/* Pulled down over the tablist rule so the active tab's own fill erases the seam below it. */
|
|
129
|
+
margin-block-end: -1px;
|
|
130
|
+
border: 1px solid transparent;
|
|
131
|
+
border-block-end: 0;
|
|
132
|
+
border-start-start-radius: var(--zx-tabbox-radius);
|
|
133
|
+
border-start-end-radius: var(--zx-tabbox-radius);
|
|
134
|
+
padding-inline: var(--zx-space-4);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.zx-tabbox[data-variant="bracket"] .zx-tabbox__tab:hover:not([aria-disabled="true"]):not([aria-selected="true"]) {
|
|
138
|
+
background: var(--zx-color-bg-hover);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.zx-tabbox[data-variant="bracket"] .zx-tabbox__tab[aria-selected="true"] {
|
|
142
|
+
border-color: var(--zx-color-border);
|
|
143
|
+
background: var(--zx-color-bg-surface);
|
|
144
|
+
font-weight: 650;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.zx-tabbox[data-variant="bracket"] .zx-tabbox__tab[aria-selected="true"]::after {
|
|
148
|
+
content: "";
|
|
149
|
+
position: absolute;
|
|
150
|
+
inset-inline: -1px;
|
|
151
|
+
inset-block-end: -1px;
|
|
152
|
+
block-size: 1px;
|
|
153
|
+
background: var(--zx-color-bg-surface);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.zx-tabbox[data-variant="bracket"] .zx-tabbox__tab:focus-visible {
|
|
157
|
+
z-index: 1;
|
|
158
|
+
outline: 0;
|
|
159
|
+
box-shadow: inset var(--zx-focus-ring);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* ----------------------------------------------------------------- line variant -- */
|
|
163
|
+
|
|
164
|
+
.zx-tabbox[data-variant="line"] .zx-tabbox__tablist {
|
|
165
|
+
border-block-end: 1px solid var(--zx-color-border);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.zx-tabbox[data-variant="line"] .zx-tabbox__tab {
|
|
169
|
+
block-size: calc(var(--zx-control-height) + 8px);
|
|
170
|
+
border-block-end: 2px solid transparent;
|
|
171
|
+
padding-inline: var(--zx-space-4);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.zx-tabbox[data-variant="line"] .zx-tabbox__tab:hover:not([aria-disabled="true"]) {
|
|
175
|
+
border-block-end-color: var(--zx-color-border-strong);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
.zx-tabbox[data-variant="line"] .zx-tabbox__tab[aria-selected="true"] {
|
|
179
|
+
border-block-end-color: var(--zx-color-accent);
|
|
180
|
+
font-weight: 600;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.zx-tabbox[data-variant="line"] .zx-tabbox__tab:focus-visible {
|
|
184
|
+
z-index: 1;
|
|
185
|
+
outline: 0;
|
|
186
|
+
box-shadow: inset var(--zx-focus-ring);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* ------------------------------------------------------------- segmented variant -- */
|
|
190
|
+
|
|
191
|
+
.zx-tabbox[data-variant="segmented"] .zx-tabbox__tablist {
|
|
192
|
+
inline-size: fit-content;
|
|
193
|
+
max-inline-size: 100%;
|
|
194
|
+
align-items: center;
|
|
195
|
+
gap: 2px;
|
|
196
|
+
block-size: var(--zx-control-height);
|
|
197
|
+
border-radius: var(--zx-tabbox-radius);
|
|
198
|
+
background: var(--zx-color-bg-muted);
|
|
199
|
+
padding: 3px;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.zx-tabbox[data-variant="segmented"] .zx-tabbox__tab {
|
|
203
|
+
block-size: 100%;
|
|
204
|
+
/* A transparent border keeps the active and inactive boxes the same size. */
|
|
205
|
+
border: 1px solid transparent;
|
|
206
|
+
/* Nested inside the track's 3px padding, so the inner corner is one step tighter. */
|
|
207
|
+
border-radius: max(0px, calc(var(--zx-tabbox-radius) - 2px));
|
|
208
|
+
padding-inline: var(--zx-space-3);
|
|
209
|
+
font-size: var(--zx-text-sm);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.zx-tabbox[data-variant="segmented"] .zx-tabbox__tab:hover:not([aria-disabled="true"]):not([aria-selected="true"]) {
|
|
213
|
+
background: var(--zx-color-bg-hover);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.zx-tabbox[data-variant="segmented"] .zx-tabbox__tab[aria-selected="true"] {
|
|
217
|
+
border-color: var(--zx-color-border-control);
|
|
218
|
+
background: var(--zx-color-bg-control);
|
|
219
|
+
box-shadow: var(--zx-shadow-2);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.zx-tabbox[data-variant="segmented"] .zx-tabbox__tab:focus-visible {
|
|
223
|
+
z-index: 1;
|
|
224
|
+
outline: 0;
|
|
225
|
+
border-color: var(--zx-color-ring);
|
|
226
|
+
box-shadow: var(--zx-focus-ring);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
230
|
+
.zx-tabbox__tab {
|
|
231
|
+
transition: color var(--zx-dur-fast) var(--zx-ease),
|
|
232
|
+
background-color var(--zx-dur-fast) var(--zx-ease),
|
|
233
|
+
border-color var(--zx-dur-fast) var(--zx-ease),
|
|
234
|
+
box-shadow var(--zx-dur-fast) var(--zx-ease);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* ---------------------------------------------------------------- badge & close -- */
|
|
239
|
+
|
|
240
|
+
.zx-tabbox__badge {
|
|
241
|
+
min-inline-size: 1.25rem;
|
|
242
|
+
border-radius: var(--zx-radius-full);
|
|
243
|
+
background: var(--zx-color-accent);
|
|
244
|
+
padding-inline: var(--zx-space-1);
|
|
245
|
+
color: var(--zx-color-on-accent);
|
|
246
|
+
font-size: var(--zx-text-xs);
|
|
247
|
+
font-weight: 700;
|
|
248
|
+
line-height: 1.25rem;
|
|
249
|
+
text-align: center;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.zx-tabbox__close {
|
|
253
|
+
margin-inline-start: calc(-1 * var(--zx-space-1));
|
|
254
|
+
color: var(--zx-color-text-muted);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/* ----------------------------------------------------------------------- panels -- */
|
|
258
|
+
|
|
259
|
+
.zx-tabbox__panel {
|
|
260
|
+
padding-block-start: var(--zx-space-4);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* The boxed variants own their panel chrome, so the tabs read as attached to the sheet. */
|
|
264
|
+
.zx-tabbox[data-variant="divided"] .zx-tabbox__panels,
|
|
265
|
+
.zx-tabbox[data-variant="bracket"] .zx-tabbox__panels {
|
|
266
|
+
border: 1px solid var(--zx-color-border);
|
|
267
|
+
border-block-start: 0;
|
|
268
|
+
border-end-start-radius: var(--zx-tabbox-radius);
|
|
269
|
+
border-end-end-radius: var(--zx-tabbox-radius);
|
|
270
|
+
background: var(--zx-color-bg-surface);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.zx-tabbox[data-variant="divided"] .zx-tabbox__panel,
|
|
274
|
+
.zx-tabbox[data-variant="bracket"] .zx-tabbox__panel {
|
|
275
|
+
padding: var(--zx-space-4);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.zx-tabbox__panel:focus-visible {
|
|
279
|
+
outline: 0;
|
|
280
|
+
box-shadow: inset var(--zx-focus-ring);
|
|
281
|
+
}
|