@revikornmann/muka-ui 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -60
- package/cli/bin/muka-ui.js +12 -5
- package/cli/commands/brand.js +33 -14
- package/cli/commands/init.js +21 -17
- package/cli/commands/install-skill.js +84 -26
- package/cli/templates/AGENTS.md +128 -0
- package/cli/templates/CLAUDE.md +8 -88
- package/cli/templates/muka-ui-guidelines.md +50 -14
- package/dist/cjs/components/ActionSheet/ActionSheet.css +4 -4
- package/dist/cjs/components/BottomBar/BottomBar.css +0 -3
- package/dist/cjs/components/Breadcrumb/Breadcrumb.css +26 -2
- package/dist/cjs/components/Combobox/Combobox.css +116 -132
- package/dist/cjs/components/Combobox/Combobox.js +175 -52
- package/dist/cjs/components/Combobox/Combobox.js.map +1 -1
- package/dist/cjs/components/Combobox/index.js.map +1 -1
- package/dist/cjs/components/ContextSelect/ContextSelect.css +4 -4
- package/dist/cjs/components/DocumentViewer/DocumentViewer.css +2 -2
- package/dist/cjs/components/DropdownSelect/DropdownSelect.css +225 -0
- package/dist/cjs/components/DropdownSelect/DropdownSelect.js +106 -0
- package/dist/cjs/components/DropdownSelect/DropdownSelect.js.map +1 -0
- package/dist/cjs/components/DropdownSelect/index.js +6 -0
- package/dist/cjs/components/DropdownSelect/index.js.map +1 -0
- package/dist/cjs/components/EmptyState/EmptyState.css +8 -8
- package/dist/cjs/components/FAB/FAB.css +1 -1
- package/dist/cjs/components/FileUpload/FileUpload.css +10 -10
- package/dist/cjs/components/Icon/custom/ArrowReturnIcon.js +11 -0
- package/dist/cjs/components/Icon/custom/ArrowReturnIcon.js.map +1 -0
- package/dist/cjs/components/Icon/iconRegistry.js +14 -1
- package/dist/cjs/components/Icon/iconRegistry.js.map +1 -1
- package/dist/cjs/components/Input/Input.css +47 -10
- package/dist/cjs/components/Input/Input.js +14 -3
- package/dist/cjs/components/Input/Input.js.map +1 -1
- package/dist/cjs/components/Label/Label.css +1 -1
- package/dist/cjs/components/LicensePlateInput/LicensePlateInput.css +1 -1
- package/dist/cjs/components/Menu/Menu.css +124 -38
- package/dist/cjs/components/Menu/Menu.js +283 -25
- package/dist/cjs/components/Menu/Menu.js.map +1 -1
- package/dist/cjs/components/Pagination/Pagination.css +15 -15
- package/dist/cjs/components/PhotoUploader/PhotoUploader.css +4 -4
- package/dist/cjs/components/ProgressAccordeon/ProgressAccordeon.css +10 -6
- package/dist/cjs/components/ProgressAccordeon/ProgressAccordeon.js +27 -16
- package/dist/cjs/components/ProgressAccordeon/ProgressAccordeon.js.map +1 -1
- package/dist/cjs/components/ProgressTracker/ProgressTracker.css +273 -22
- package/dist/cjs/components/ProgressTracker/ProgressTracker.js +109 -9
- package/dist/cjs/components/ProgressTracker/ProgressTracker.js.map +1 -1
- package/dist/cjs/components/Scrollbar/Scrollbar.css +7 -6
- package/dist/cjs/components/SearchInput/SearchInput.css +4 -4
- package/dist/cjs/components/Select/Select.css +2 -2
- package/dist/cjs/components/SmsOtpField/SmsOtpField.css +2 -2
- package/dist/cjs/components/SpecList/SpecList.css +8 -8
- package/dist/cjs/components/Spinner/Spinner.css +1 -1
- package/dist/cjs/components/SwipeActions/SwipeActions.css +6 -6
- package/dist/cjs/components/Table/Table.css +3 -3
- package/dist/cjs/components/Table/TablePagination.css +1 -1
- package/dist/cjs/components/Tabs/Tabs.css +6 -6
- package/dist/cjs/components/Textarea/Textarea.css +2 -2
- package/dist/cjs/components/Waveform/Waveform.css +1 -1
- package/dist/cjs/components/index.js +5 -3
- package/dist/cjs/components/index.js.map +1 -1
- package/dist/esm/components/ActionSheet/ActionSheet.css +4 -4
- package/dist/esm/components/BottomBar/BottomBar.css +0 -3
- package/dist/esm/components/Breadcrumb/Breadcrumb.css +26 -2
- package/dist/esm/components/Combobox/Combobox.css +116 -132
- package/dist/esm/components/Combobox/Combobox.js +177 -54
- package/dist/esm/components/Combobox/Combobox.js.map +1 -1
- package/dist/esm/components/Combobox/index.js +1 -1
- package/dist/esm/components/Combobox/index.js.map +1 -1
- package/dist/esm/components/ContextSelect/ContextSelect.css +4 -4
- package/dist/esm/components/DocumentViewer/DocumentViewer.css +2 -2
- package/dist/esm/components/DropdownSelect/DropdownSelect.css +225 -0
- package/dist/esm/components/DropdownSelect/DropdownSelect.js +102 -0
- package/dist/esm/components/DropdownSelect/DropdownSelect.js.map +1 -0
- package/dist/esm/components/DropdownSelect/index.js +2 -0
- package/dist/esm/components/DropdownSelect/index.js.map +1 -0
- package/dist/esm/components/EmptyState/EmptyState.css +8 -8
- package/dist/esm/components/FAB/FAB.css +1 -1
- package/dist/esm/components/FileUpload/FileUpload.css +10 -10
- package/dist/esm/components/Icon/custom/ArrowReturnIcon.js +7 -0
- package/dist/esm/components/Icon/custom/ArrowReturnIcon.js.map +1 -0
- package/dist/esm/components/Icon/iconRegistry.js +14 -1
- package/dist/esm/components/Icon/iconRegistry.js.map +1 -1
- package/dist/esm/components/Input/Input.css +47 -10
- package/dist/esm/components/Input/Input.js +14 -3
- package/dist/esm/components/Input/Input.js.map +1 -1
- package/dist/esm/components/Label/Label.css +1 -1
- package/dist/esm/components/LicensePlateInput/LicensePlateInput.css +1 -1
- package/dist/esm/components/Menu/Menu.css +124 -38
- package/dist/esm/components/Menu/Menu.js +284 -26
- package/dist/esm/components/Menu/Menu.js.map +1 -1
- package/dist/esm/components/Pagination/Pagination.css +15 -15
- package/dist/esm/components/PhotoUploader/PhotoUploader.css +4 -4
- package/dist/esm/components/ProgressAccordeon/ProgressAccordeon.css +10 -6
- package/dist/esm/components/ProgressAccordeon/ProgressAccordeon.js +27 -16
- package/dist/esm/components/ProgressAccordeon/ProgressAccordeon.js.map +1 -1
- package/dist/esm/components/ProgressTracker/ProgressTracker.css +273 -22
- package/dist/esm/components/ProgressTracker/ProgressTracker.js +110 -10
- package/dist/esm/components/ProgressTracker/ProgressTracker.js.map +1 -1
- package/dist/esm/components/Scrollbar/Scrollbar.css +7 -6
- package/dist/esm/components/SearchInput/SearchInput.css +4 -4
- package/dist/esm/components/Select/Select.css +2 -2
- package/dist/esm/components/SmsOtpField/SmsOtpField.css +2 -2
- package/dist/esm/components/SpecList/SpecList.css +8 -8
- package/dist/esm/components/Spinner/Spinner.css +1 -1
- package/dist/esm/components/SwipeActions/SwipeActions.css +6 -6
- package/dist/esm/components/Table/Table.css +3 -3
- package/dist/esm/components/Table/TablePagination.css +1 -1
- package/dist/esm/components/Tabs/Tabs.css +6 -6
- package/dist/esm/components/Textarea/Textarea.css +2 -2
- package/dist/esm/components/Waveform/Waveform.css +1 -1
- package/dist/esm/components/index.js +1 -0
- package/dist/esm/components/index.js.map +1 -1
- package/dist/styles/components/ActionSheet.css +4 -4
- package/dist/styles/components/BottomBar.css +0 -3
- package/dist/styles/components/Breadcrumb.css +26 -2
- package/dist/styles/components/Combobox.css +116 -132
- package/dist/styles/components/ContextSelect.css +4 -4
- package/dist/styles/components/DocumentViewer.css +2 -2
- package/dist/styles/components/DropdownSelect.css +225 -0
- package/dist/styles/components/EmptyState.css +8 -8
- package/dist/styles/components/FAB.css +1 -1
- package/dist/styles/components/FileUpload.css +10 -10
- package/dist/styles/components/Input.css +47 -10
- package/dist/styles/components/Label.css +1 -1
- package/dist/styles/components/LicensePlateInput.css +1 -1
- package/dist/styles/components/Menu.css +124 -38
- package/dist/styles/components/Pagination.css +15 -15
- package/dist/styles/components/PhotoUploader.css +4 -4
- package/dist/styles/components/ProgressAccordeon.css +10 -6
- package/dist/styles/components/ProgressTracker.css +273 -22
- package/dist/styles/components/Scrollbar.css +7 -6
- package/dist/styles/components/SearchInput.css +4 -4
- package/dist/styles/components/Select.css +2 -2
- package/dist/styles/components/SmsOtpField.css +2 -2
- package/dist/styles/components/SpecList.css +8 -8
- package/dist/styles/components/Spinner.css +1 -1
- package/dist/styles/components/SwipeActions.css +6 -6
- package/dist/styles/components/Table.css +3 -3
- package/dist/styles/components/Tabs.css +6 -6
- package/dist/styles/components/Textarea.css +2 -2
- package/dist/styles/components/Typography.css +89 -0
- package/dist/styles/components/Waveform.css +1 -1
- package/dist/styles/index.css +1167 -462
- package/dist/styles/muka-dark.css +1167 -462
- package/dist/styles/muka-light.css +1167 -462
- package/dist/styles/tokens-bouwplan-dark.css +5 -4
- package/dist/styles/tokens-bouwplan-light.css +5 -4
- package/dist/styles/tokens-fscl-dark.css +25 -24
- package/dist/styles/tokens-fscl-light.css +25 -24
- package/dist/styles/tokens-grip-dark.css +4 -3
- package/dist/styles/tokens-grip-light.css +4 -3
- package/dist/styles/tokens-muka-dark.css +4 -3
- package/dist/styles/tokens-muka-light.css +4 -3
- package/dist/styles/tokens-wireframe-dark.css +49 -48
- package/dist/styles/tokens-wireframe-light.css +49 -48
- package/dist/styles/wireframe-dark.css +1212 -507
- package/dist/styles/wireframe-light.css +1212 -507
- package/dist/types/components/Combobox/Combobox.d.ts +38 -38
- package/dist/types/components/Combobox/Combobox.d.ts.map +1 -1
- package/dist/types/components/Combobox/index.d.ts +1 -1
- package/dist/types/components/Combobox/index.d.ts.map +1 -1
- package/dist/types/components/DropdownSelect/DropdownSelect.d.ts +71 -0
- package/dist/types/components/DropdownSelect/DropdownSelect.d.ts.map +1 -0
- package/dist/types/components/DropdownSelect/index.d.ts +2 -0
- package/dist/types/components/DropdownSelect/index.d.ts.map +1 -0
- package/dist/types/components/Icon/custom/ArrowReturnIcon.d.ts +9 -0
- package/dist/types/components/Icon/custom/ArrowReturnIcon.d.ts.map +1 -0
- package/dist/types/components/Icon/iconRegistry.d.ts.map +1 -1
- package/dist/types/components/Input/Input.d.ts +5 -0
- package/dist/types/components/Input/Input.d.ts.map +1 -1
- package/dist/types/components/Menu/Menu.d.ts +42 -2
- package/dist/types/components/Menu/Menu.d.ts.map +1 -1
- package/dist/types/components/ProgressAccordeon/ProgressAccordeon.d.ts +17 -12
- package/dist/types/components/ProgressAccordeon/ProgressAccordeon.d.ts.map +1 -1
- package/dist/types/components/ProgressTracker/ProgressTracker.d.ts +29 -8
- package/dist/types/components/ProgressTracker/ProgressTracker.d.ts.map +1 -1
- package/dist/types/components/index.d.ts +1 -0
- package/dist/types/components/index.d.ts.map +1 -1
- package/docs/consumers/README.md +116 -37
- package/docs/consumers/brand.md +261 -0
- package/docs/consumers/figma-console-mcp.md +116 -0
- package/docs/consumers/setup-instructions.md +98 -12
- package/docs/consumers/skills.md +79 -0
- package/package.json +5 -6
- package/scripts/postinstall-nudge.js +8 -4
- package/skills/add-brand/SKILL.md +204 -0
- package/skills/add-brand/reference.md +160 -0
- package/skills/figma-to-code/SKILL.md +127 -0
- package/skills/pull-from-figma/SKILL.md +123 -0
- package/skills/push-to-figma/SKILL.md +172 -0
- package/skills/setup-muka/SKILL.md +73 -13
- package/tokens/README.md +39 -17
- package/tokens/t2-alias/brand/bouwplan/fonts.json +1 -1
- package/tokens/t2-alias/brand/fscl/fonts.json +3 -3
- package/tokens/t2-alias/brand/wireframe/fonts.json +2 -2
- package/tokens/t4-components/menu.json +8 -3
|
@@ -16,11 +16,14 @@ import './ProgressAccordeon.css';
|
|
|
16
16
|
* - **past** — dark check indicator, heading, edit + chevron controls; the
|
|
17
17
|
* content slot collapses/expands via `collapsed` + `onToggle`
|
|
18
18
|
* - **current** — accent numbered indicator, heading, content slot, actions
|
|
19
|
-
* - **upcoming** — muted numbered indicator, heading
|
|
19
|
+
* - **upcoming** — muted numbered indicator, heading; optional collapsible
|
|
20
|
+
* content slot (same `collapsed` + `onToggle` as past) for empty-state
|
|
21
|
+
* instructions or picking up a step out of order
|
|
20
22
|
*
|
|
21
23
|
* Content is passed as `children` (an optional slot) and rendered as-is — supply
|
|
22
|
-
* your own `Card` when you want
|
|
23
|
-
* Divider primitives and is fully themed through the Muka
|
|
24
|
+
* your own `Card` or `EmptyState` when you want those surfaces. Composes the
|
|
25
|
+
* Button, Icon and Divider primitives and is fully themed through the Muka
|
|
26
|
+
* design token system.
|
|
24
27
|
*
|
|
25
28
|
* Tokens used:
|
|
26
29
|
* - alias.color.accent.{default|contrast} — step indicator fills
|
|
@@ -39,18 +42,25 @@ import './ProgressAccordeon.css';
|
|
|
39
42
|
export const ProgressAccordeon = ({ state, stepNumber, heading, description, children, divider = true, collapsed = false, onToggle, editLabel = 'Edit', onEdit, primaryAction, secondaryAction, className = '', }) => {
|
|
40
43
|
const isPast = state === 'past';
|
|
41
44
|
const isCurrent = state === 'current';
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
45
|
+
const isUpcoming = state === 'upcoming';
|
|
46
|
+
// Past and upcoming share the collapsible slot pattern so consumers can show
|
|
47
|
+
// empty-state instructions on future steps and pick steps up independently.
|
|
48
|
+
const isCollapsible = isPast || isUpcoming;
|
|
49
|
+
const showToggle = isCollapsible && Boolean(onToggle);
|
|
50
|
+
const showEdit = isPast && !collapsed && Boolean(onEdit);
|
|
51
|
+
const showDescription = Boolean(description) && !(isCollapsible && collapsed);
|
|
52
|
+
// Collapsible steps keep their content mounted regardless of `collapsed` so
|
|
53
|
+
// the collapse/expand can be CSS-animated (you can't animate an unmounted node).
|
|
54
|
+
const hasSlot = (isCollapsible || isCurrent) && Boolean(children);
|
|
49
55
|
const hasActions = isCurrent && Boolean(primaryAction || secondaryAction);
|
|
56
|
+
// Collapse modifiers only when the step can actually collapse — keeps
|
|
57
|
+
// header-only upcoming spacing on the base `--upcoming` gap rule.
|
|
58
|
+
const showCollapseModifiers = isPast || (isUpcoming && (Boolean(children) || Boolean(onToggle)));
|
|
50
59
|
const rootClasses = [
|
|
51
60
|
'muka-progress-accordeon',
|
|
52
61
|
`muka-progress-accordeon--${state}`,
|
|
53
|
-
|
|
62
|
+
showCollapseModifiers &&
|
|
63
|
+
`muka-progress-accordeon--${collapsed ? 'collapsed' : 'expanded'}`,
|
|
54
64
|
className,
|
|
55
65
|
].filter(Boolean).join(' ');
|
|
56
66
|
const indicatorClasses = [
|
|
@@ -59,9 +69,10 @@ export const ProgressAccordeon = ({ state, stepNumber, heading, description, chi
|
|
|
59
69
|
].join(' ');
|
|
60
70
|
const header = (_jsxs("div", { className: "muka-progress-accordeon__header", children: [_jsxs("div", { className: "muka-progress-accordeon__header-row", children: [_jsxs("div", { className: "muka-progress-accordeon__heading-group", children: [_jsx("div", { className: indicatorClasses, "aria-hidden": "true", children: isPast ? (_jsx(Icon, { name: "check", variant: "fill", size: "sm", className: "muka-progress-accordeon__check-icon" })) : (_jsx("span", { className: "muka-progress-accordeon__number", children: stepNumber })) }), _jsx("h3", { className: "muka-progress-accordeon__heading", children: heading })] }), (showEdit || showToggle) && (_jsxs("div", { className: "muka-progress-accordeon__controls", children: [showEdit && (_jsxs(_Fragment, { children: [_jsx(Button, { variant: "tertiary", size: "md", onClick: onEdit, iconLeft: _jsx(Icon, { name: "pencil", variant: "line", size: "md" }), className: "muka-progress-accordeon__edit muka-progress-accordeon__edit--wide", children: editLabel }), _jsx(Button, { variant: "tertiary", size: "md", iconOnly: true, onClick: onEdit, className: "muka-progress-accordeon__edit muka-progress-accordeon__edit--narrow", "aria-label": editLabel, children: _jsx(Icon, { name: "pencil", variant: "line", size: "md" }) })] })), showToggle && (_jsx(Button, { variant: "tertiary", size: "md", iconOnly: true, onClick: onToggle, className: "muka-progress-accordeon__toggle", "aria-label": collapsed ? 'Expand' : 'Collapse', "aria-expanded": !collapsed, children: _jsx(Icon, { name: collapsed ? 'arrow-down-s' : 'arrow-up-s', variant: "line", size: "md" }) }))] }))] }), showDescription && (_jsx("div", { className: "muka-progress-accordeon__description", children: description }))] }));
|
|
61
71
|
const slot = hasSlot ? (_jsx("div", { className: "muka-progress-accordeon__slot", children: children })) : null;
|
|
62
|
-
//
|
|
63
|
-
// collapses its height to zero. Marked inert + aria-hidden while
|
|
64
|
-
// the still-mounted content is skipped by keyboard focus and
|
|
72
|
+
// Collapsible steps wrap the (always-mounted) slot in a grid animation
|
|
73
|
+
// container that collapses its height to zero. Marked inert + aria-hidden while
|
|
74
|
+
// collapsed so the still-mounted content is skipped by keyboard focus and
|
|
75
|
+
// assistive tech.
|
|
65
76
|
// `inert` is set imperatively on the DOM node rather than via a React prop:
|
|
66
77
|
// React 18 drops a boolean `inert` prop, while React 19 warns on the string
|
|
67
78
|
// form — toggling the attribute directly works correctly under both.
|
|
@@ -77,8 +88,8 @@ export const ProgressAccordeon = ({ state, stepNumber, heading, description, chi
|
|
|
77
88
|
node.removeAttribute('inert');
|
|
78
89
|
}
|
|
79
90
|
}, [collapsed]);
|
|
80
|
-
const
|
|
81
|
-
return (_jsxs("div", { className: rootClasses, role: "group", "aria-label": `Step ${stepNumber}: ${heading}`, "aria-current": isCurrent ? 'step' : undefined, children: [
|
|
91
|
+
const collapsibleSlot = hasSlot ? (_jsx("div", { ref: slotWrapperRef, className: `muka-progress-accordeon__slot-wrapper${collapsed ? ' muka-progress-accordeon__slot-wrapper--collapsed' : ''}`, "aria-hidden": collapsed || undefined, children: _jsx("div", { className: "muka-progress-accordeon__slot-clip", children: slot }) })) : null;
|
|
92
|
+
return (_jsxs("div", { className: rootClasses, role: "group", "aria-label": `Step ${stepNumber}: ${heading}`, "aria-current": isCurrent ? 'step' : undefined, children: [isCollapsible ? (_jsxs("div", { className: "muka-progress-accordeon__body", children: [header, collapsibleSlot] })) : (_jsxs(_Fragment, { children: [header, slot] })), hasActions && (_jsxs("div", { className: "muka-progress-accordeon__actions", children: [secondaryAction && (_jsx(Button, { variant: "secondary", size: "md", onClick: secondaryAction.onClick, disabled: secondaryAction.disabled, className: "muka-progress-accordeon__action", children: secondaryAction.label })), primaryAction && (_jsx(Button, { variant: "primary", size: "md", onClick: primaryAction.onClick, disabled: primaryAction.disabled, className: "muka-progress-accordeon__action", children: primaryAction.label }))] })), divider && _jsx(Divider, { className: "muka-progress-accordeon__divider" })] }));
|
|
82
93
|
};
|
|
83
94
|
export default ProgressAccordeon;
|
|
84
95
|
//# sourceMappingURL=ProgressAccordeon.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressAccordeon.js","sourceRoot":"","sources":["../../../../components/ProgressAccordeon/ProgressAccordeon.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"ProgressAccordeon.js","sourceRoot":"","sources":["../../../../components/ProgressAccordeon/ProgressAccordeon.tsx"],"names":[],"mappings":"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"}
|
|
@@ -3,19 +3,22 @@
|
|
|
3
3
|
/* ─── Root ──────────────────────────────────────────────── */
|
|
4
4
|
.muka-progress-tracker {
|
|
5
5
|
width: 100%;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.muka-progress-tracker--horizontal {
|
|
6
9
|
padding-bottom: var(--spacing-7);
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
/* ─── Track (layered container) ─────────────────────────── */
|
|
10
|
-
.muka-progress-tracker__track {
|
|
13
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__track {
|
|
11
14
|
position: relative;
|
|
12
15
|
/* Vertical padding = (indicator size - connector height) / 2 = (32 - 4) / 2 = 14px */
|
|
13
16
|
padding-top: 14px;
|
|
14
17
|
padding-bottom: 14px;
|
|
15
18
|
}
|
|
16
19
|
|
|
17
|
-
/* ─── Steps layer (on top)
|
|
18
|
-
.muka-progress-tracker__steps {
|
|
20
|
+
/* ─── Steps layer (on top) — horizontal ─────────────────── */
|
|
21
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__steps {
|
|
19
22
|
position: absolute;
|
|
20
23
|
inset: 0;
|
|
21
24
|
display: flex;
|
|
@@ -24,13 +27,16 @@
|
|
|
24
27
|
z-index: 2;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
/* ─── Individual step
|
|
28
|
-
.muka-progress-tracker__step {
|
|
30
|
+
/* ─── Individual step — horizontal ──────────────────────── */
|
|
31
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__step {
|
|
29
32
|
display: flex;
|
|
30
33
|
flex-direction: column;
|
|
31
34
|
align-items: center;
|
|
32
|
-
gap: 7px;
|
|
33
35
|
position: relative;
|
|
36
|
+
/* Labels are absolutely positioned so the step stays 32px and
|
|
37
|
+
circle centers line up with the connector padding. */
|
|
38
|
+
width: 32px;
|
|
39
|
+
flex: 0 0 32px;
|
|
34
40
|
}
|
|
35
41
|
|
|
36
42
|
/* ─── Step indicator (circle) ───────────────────────────── */
|
|
@@ -43,20 +49,24 @@
|
|
|
43
49
|
justify-content: center;
|
|
44
50
|
flex-shrink: 0;
|
|
45
51
|
position: relative;
|
|
52
|
+
z-index: 1;
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
/* Past: dark accent contrast circle with white checkmark */
|
|
49
56
|
.muka-progress-tracker__indicator--past {
|
|
50
57
|
background-color: var(--alias-color-accent-contrast);
|
|
51
58
|
color: var(--color-text-default-inverse);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__indicator--past {
|
|
52
62
|
cursor: pointer;
|
|
53
63
|
}
|
|
54
64
|
|
|
55
|
-
.muka-progress-tracker__indicator--past:hover {
|
|
65
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__indicator--past:hover {
|
|
56
66
|
background-color: var(--alias-color-accent-pressed);
|
|
57
67
|
}
|
|
58
68
|
|
|
59
|
-
.muka-progress-tracker__indicator--past:focus-visible {
|
|
69
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__indicator--past:focus-visible {
|
|
60
70
|
outline: 2px solid var(--color-border-focus);
|
|
61
71
|
outline-offset: 2px;
|
|
62
72
|
}
|
|
@@ -83,6 +93,18 @@
|
|
|
83
93
|
user-select: none;
|
|
84
94
|
}
|
|
85
95
|
|
|
96
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__indicator--upcoming .muka-progress-tracker__number {
|
|
97
|
+
font-family: var(--text-label-md-bold-fontFamily);
|
|
98
|
+
font-weight: var(--text-label-md-bold-fontWeight);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__indicator--upcoming .muka-progress-tracker__number {
|
|
102
|
+
font-family: var(--text-label-md-semibold-fontFamily);
|
|
103
|
+
font-weight: var(--text-label-md-semibold-fontWeight);
|
|
104
|
+
font-size: var(--text-label-md-semibold-fontSize);
|
|
105
|
+
line-height: var(--text-label-md-semibold-lineHeight);
|
|
106
|
+
}
|
|
107
|
+
|
|
86
108
|
/* ─── Checkmark icon ────────────────────────────────────── */
|
|
87
109
|
.muka-progress-tracker__check-icon {
|
|
88
110
|
width: 20px;
|
|
@@ -95,8 +117,12 @@
|
|
|
95
117
|
color: var(--color-text-default-inverse);
|
|
96
118
|
}
|
|
97
119
|
|
|
98
|
-
/* ─── Step label
|
|
99
|
-
.muka-progress-tracker__label {
|
|
120
|
+
/* ─── Step label — horizontal ───────────────────────────── */
|
|
121
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__label {
|
|
122
|
+
position: absolute;
|
|
123
|
+
top: 39px;
|
|
124
|
+
left: 50%;
|
|
125
|
+
transform: translateX(-50%);
|
|
100
126
|
font-family: var(--text-label-sm-regular-fontFamily);
|
|
101
127
|
font-weight: var(--text-label-sm-regular-fontWeight);
|
|
102
128
|
font-size: var(--text-label-sm-regular-fontSize);
|
|
@@ -109,14 +135,14 @@
|
|
|
109
135
|
text-overflow: ellipsis;
|
|
110
136
|
}
|
|
111
137
|
|
|
112
|
-
/* Current step label is bold */
|
|
113
|
-
.muka-progress-tracker__label--current {
|
|
138
|
+
/* Current step label is bold (horizontal only) */
|
|
139
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__label--current {
|
|
114
140
|
font-family: var(--text-label-sm-bold-fontFamily);
|
|
115
141
|
font-weight: var(--text-label-sm-bold-fontWeight);
|
|
116
142
|
}
|
|
117
143
|
|
|
118
|
-
/* ─── Connectors layer (behind indicators)
|
|
119
|
-
.muka-progress-tracker__connectors {
|
|
144
|
+
/* ─── Connectors layer (behind indicators) — horizontal ─── */
|
|
145
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__connectors {
|
|
120
146
|
display: flex;
|
|
121
147
|
align-items: center;
|
|
122
148
|
/* Horizontal padding = indicator radius (32/2 = 16px) so lines meet circle centers */
|
|
@@ -126,20 +152,31 @@
|
|
|
126
152
|
z-index: 1;
|
|
127
153
|
}
|
|
128
154
|
|
|
129
|
-
/*
|
|
130
|
-
.
|
|
155
|
+
/* Rounder, bar, rounder in a row. Chromium treats a negative gap as invalid,
|
|
156
|
+
so the overlap is margins: the bar runs 2px under each circle. */
|
|
157
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__connector {
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-direction: row;
|
|
160
|
+
align-items: center;
|
|
131
161
|
flex: 1 0 0;
|
|
132
162
|
height: 4px;
|
|
133
163
|
min-width: 1px;
|
|
164
|
+
position: relative;
|
|
165
|
+
overflow: visible;
|
|
166
|
+
background: none;
|
|
134
167
|
}
|
|
135
168
|
|
|
136
|
-
|
|
137
|
-
|
|
169
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__connector-line {
|
|
170
|
+
flex: 1 1 auto;
|
|
171
|
+
height: 4px;
|
|
172
|
+
min-width: 1px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__connector--past .muka-progress-tracker__connector-line {
|
|
138
176
|
background-color: var(--alias-color-accent-contrast);
|
|
139
177
|
}
|
|
140
178
|
|
|
141
|
-
|
|
142
|
-
.muka-progress-tracker__connector--current {
|
|
179
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__connector--current .muka-progress-tracker__connector-line {
|
|
143
180
|
background: linear-gradient(
|
|
144
181
|
to right,
|
|
145
182
|
var(--alias-color-accent-contrast) 0%,
|
|
@@ -147,8 +184,7 @@
|
|
|
147
184
|
);
|
|
148
185
|
}
|
|
149
186
|
|
|
150
|
-
|
|
151
|
-
.muka-progress-tracker__connector--current-right {
|
|
187
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__connector--current-right .muka-progress-tracker__connector-line {
|
|
152
188
|
background: linear-gradient(
|
|
153
189
|
to right,
|
|
154
190
|
var(--alias-color-accent-default) 0%,
|
|
@@ -157,7 +193,222 @@
|
|
|
157
193
|
);
|
|
158
194
|
}
|
|
159
195
|
|
|
196
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__connector--upcoming .muka-progress-tracker__connector-line {
|
|
197
|
+
background-color: var(--color-surface-sunken);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/* Past: solid dark line (vertical; horizontal uses the inner line) */
|
|
201
|
+
.muka-progress-tracker__connector--past {
|
|
202
|
+
background-color: var(--alias-color-accent-contrast);
|
|
203
|
+
}
|
|
204
|
+
|
|
160
205
|
/* Upcoming: solid gray line */
|
|
161
206
|
.muka-progress-tracker__connector--upcoming {
|
|
162
207
|
background-color: var(--color-surface-sunken);
|
|
163
208
|
}
|
|
209
|
+
|
|
210
|
+
/* ═══════════════════════════════════════════════════════════
|
|
211
|
+
Vertical orientation
|
|
212
|
+
═══════════════════════════════════════════════════════════ */
|
|
213
|
+
|
|
214
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__track {
|
|
215
|
+
display: flex;
|
|
216
|
+
flex-direction: column;
|
|
217
|
+
align-items: stretch;
|
|
218
|
+
gap: var(--spacing-6);
|
|
219
|
+
width: 100%;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step {
|
|
223
|
+
display: flex;
|
|
224
|
+
flex-direction: row;
|
|
225
|
+
align-items: flex-start;
|
|
226
|
+
gap: var(--spacing-3);
|
|
227
|
+
padding-right: var(--spacing-1);
|
|
228
|
+
position: relative;
|
|
229
|
+
width: 100%;
|
|
230
|
+
min-height: 32px;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step--interactive {
|
|
234
|
+
cursor: pointer;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step--interactive:focus-visible {
|
|
238
|
+
outline: 2px solid var(--color-border-focus);
|
|
239
|
+
outline-offset: 4px;
|
|
240
|
+
border-radius: 20px;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/* Indicator column: circle only; connector is absolutely positioned on the step */
|
|
244
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__indicator-col {
|
|
245
|
+
display: flex;
|
|
246
|
+
flex-direction: column;
|
|
247
|
+
align-items: center;
|
|
248
|
+
flex-shrink: 0;
|
|
249
|
+
position: relative;
|
|
250
|
+
width: 32px;
|
|
251
|
+
z-index: 1;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/* Vertical connector: from mid-indicator through gap to next mid-indicator */
|
|
255
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__connector {
|
|
256
|
+
position: absolute;
|
|
257
|
+
left: 14px; /* (32px indicator - 4px line) / 2 */
|
|
258
|
+
top: 16px;
|
|
259
|
+
/* Through track gap (spacing-6) into the next indicator's top half */
|
|
260
|
+
bottom: calc(-1 * var(--spacing-6) - 16px);
|
|
261
|
+
width: 4px;
|
|
262
|
+
z-index: 0;
|
|
263
|
+
overflow: visible;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* Divider rounders: circle bleeds into the connector (Figma Divider Rounder) */
|
|
267
|
+
.muka-progress-tracker__rounder {
|
|
268
|
+
position: absolute;
|
|
269
|
+
display: block;
|
|
270
|
+
pointer-events: none;
|
|
271
|
+
overflow: visible;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.muka-progress-tracker__rounder--past {
|
|
275
|
+
color: var(--alias-color-accent-contrast);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
.muka-progress-tracker__rounder--current {
|
|
279
|
+
color: var(--alias-color-accent-default);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.muka-progress-tracker__rounder--upcoming {
|
|
283
|
+
color: var(--color-surface-sunken);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__rounder {
|
|
287
|
+
position: relative;
|
|
288
|
+
z-index: 1;
|
|
289
|
+
flex-shrink: 0;
|
|
290
|
+
top: auto;
|
|
291
|
+
right: auto;
|
|
292
|
+
bottom: auto;
|
|
293
|
+
left: auto;
|
|
294
|
+
transform: none;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__rounder--start {
|
|
298
|
+
margin-left: 14px;
|
|
299
|
+
/* Rounder overhangs the circle by 3px; -5px tucks the bar 2px under the circle. */
|
|
300
|
+
margin-right: -5px;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.muka-progress-tracker--horizontal .muka-progress-tracker__rounder--end {
|
|
304
|
+
margin-left: -5px;
|
|
305
|
+
margin-right: 14px;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__rounder--start {
|
|
309
|
+
left: 50%;
|
|
310
|
+
top: 14px;
|
|
311
|
+
transform: translateX(-50%);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__rounder--end {
|
|
315
|
+
left: 50%;
|
|
316
|
+
bottom: 14px;
|
|
317
|
+
transform: translateX(-50%);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__connector--current {
|
|
321
|
+
background: linear-gradient(
|
|
322
|
+
to bottom,
|
|
323
|
+
var(--alias-color-accent-contrast) 0%,
|
|
324
|
+
var(--alias-color-accent-default) 100%
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__connector--current-right {
|
|
329
|
+
background: linear-gradient(
|
|
330
|
+
to bottom,
|
|
331
|
+
var(--alias-color-accent-default) 0%,
|
|
332
|
+
var(--alias-color-accent-default) 15%,
|
|
333
|
+
var(--color-surface-sunken) 50%
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/* Vertical label: body/base/regular, wraps, not bold for current */
|
|
338
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__label {
|
|
339
|
+
font-family: var(--text-body-base-regular-fontFamily);
|
|
340
|
+
font-weight: var(--text-body-base-regular-fontWeight);
|
|
341
|
+
font-size: var(--text-body-base-regular-fontSize);
|
|
342
|
+
line-height: var(--text-body-base-regular-lineHeight);
|
|
343
|
+
color: var(--color-text-default-default);
|
|
344
|
+
text-align: left;
|
|
345
|
+
flex: 1 0 0;
|
|
346
|
+
min-width: 0;
|
|
347
|
+
padding-top: var(--spacing-1);
|
|
348
|
+
padding-bottom: var(--spacing-1);
|
|
349
|
+
word-break: break-word;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/* Current label stays regular weight in vertical layout */
|
|
353
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__label--current {
|
|
354
|
+
font-family: var(--text-body-base-regular-fontFamily);
|
|
355
|
+
font-weight: var(--text-body-base-regular-fontWeight);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/* Ensure step content paints above hover/selected backgrounds */
|
|
359
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__indicator-col,
|
|
360
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__label {
|
|
361
|
+
position: relative;
|
|
362
|
+
z-index: 1;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/* ─── Hover halo (vertical interactive only) ────────────── */
|
|
366
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step--interactive:hover::before,
|
|
367
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step--interactive:active::before,
|
|
368
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step[data-selected='true']::before {
|
|
369
|
+
content: '';
|
|
370
|
+
position: absolute;
|
|
371
|
+
background-color: var(--color-surface-level1);
|
|
372
|
+
pointer-events: none;
|
|
373
|
+
z-index: 0;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/* Hover: 40px circle behind indicator only */
|
|
377
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step--interactive:hover::before {
|
|
378
|
+
left: -4px;
|
|
379
|
+
top: -4px;
|
|
380
|
+
width: 40px;
|
|
381
|
+
height: 40px;
|
|
382
|
+
border-radius: 20px;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* Selected / :active: pill behind full step row — wins over hover */
|
|
386
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step--interactive:active::before,
|
|
387
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step[data-selected='true']::before {
|
|
388
|
+
left: -4px;
|
|
389
|
+
right: -8px;
|
|
390
|
+
top: -4px;
|
|
391
|
+
bottom: -4px;
|
|
392
|
+
width: auto;
|
|
393
|
+
height: auto;
|
|
394
|
+
border-radius: 20px;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/* Selected steps without interactive class still show the pill */
|
|
398
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__step[data-selected='true']:not(.muka-progress-tracker__step--interactive)::before {
|
|
399
|
+
content: '';
|
|
400
|
+
position: absolute;
|
|
401
|
+
left: -4px;
|
|
402
|
+
right: -8px;
|
|
403
|
+
top: -4px;
|
|
404
|
+
bottom: -4px;
|
|
405
|
+
background-color: var(--color-surface-level1);
|
|
406
|
+
border-radius: 20px;
|
|
407
|
+
pointer-events: none;
|
|
408
|
+
z-index: 0;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/* Connector stays behind indicators (indicator-col is z-index 1) */
|
|
412
|
+
.muka-progress-tracker--vertical .muka-progress-tracker__connector {
|
|
413
|
+
z-index: 0;
|
|
414
|
+
}
|
|
@@ -1,6 +1,44 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import './ProgressTracker.css';
|
|
3
3
|
import { Icon } from '../Icon';
|
|
4
|
+
/** Figma Divider Rounder paths — circle bleeds into the 4px connector. */
|
|
5
|
+
const DIVIDER_ROUNDERS = {
|
|
6
|
+
horizontal: {
|
|
7
|
+
start: {
|
|
8
|
+
width: 5,
|
|
9
|
+
height: 15.4893,
|
|
10
|
+
viewBox: '0 0 5 15.4893',
|
|
11
|
+
d: 'M0 0C0.549963 0.992174 1.00009 2.04813 1.33105 3.15527C1.7646 4.60497 3.01126 5.74512 4.52441 5.74512H5V9.74512H4.52441C3.01126 9.74512 1.7646 10.8853 1.33105 12.335C1.00017 13.4418 0.549773 14.4973 0 15.4893V0Z',
|
|
12
|
+
},
|
|
13
|
+
end: {
|
|
14
|
+
width: 5,
|
|
15
|
+
height: 15.4893,
|
|
16
|
+
viewBox: '0 0 5 15.4893',
|
|
17
|
+
d: 'M5 0C4.45004 0.992174 3.99991 2.04813 3.66895 3.15527C3.2354 4.60497 1.98874 5.74512 0.475586 5.74512H0V9.74512H0.475586C1.98874 9.74512 3.2354 10.8853 3.66895 12.335C3.99983 13.4418 4.45023 14.4973 5 15.4893V0Z',
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
vertical: {
|
|
21
|
+
start: {
|
|
22
|
+
width: 16,
|
|
23
|
+
height: 5,
|
|
24
|
+
viewBox: '0 0 16 5',
|
|
25
|
+
d: 'M16 0C14.9751 0.549963 13.8843 1.00009 12.7407 1.33105C11.2432 1.7646 10 3.01126 10 4.52441V5H6V4.52441C6 3.01126 4.75581 1.7646 3.25831 1.33105C2.11494 1.00017 1.02467 0.549773 0 0H16Z',
|
|
26
|
+
},
|
|
27
|
+
end: {
|
|
28
|
+
width: 16,
|
|
29
|
+
height: 5,
|
|
30
|
+
viewBox: '0 0 16 5',
|
|
31
|
+
d: 'M16 5C14.9751 4.45004 13.8843 3.99991 12.7407 3.66895C11.2432 3.2354 10 1.98874 10 0.475586V0H6V0.475586C6 1.98874 4.75581 3.2354 3.25831 3.66895C2.11494 3.99983 1.02467 4.45023 0 5H16Z',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
function DividerRounder({ orientation, edge, status, }) {
|
|
36
|
+
const spec = DIVIDER_ROUNDERS[orientation][edge];
|
|
37
|
+
return (_jsx("svg", { className: `muka-progress-tracker__rounder muka-progress-tracker__rounder--${edge} muka-progress-tracker__rounder--${status}`, width: spec.width, height: spec.height, viewBox: spec.viewBox, fill: "none", "aria-hidden": "true", children: _jsx("path", { d: spec.d, fill: "currentColor" }) }));
|
|
38
|
+
}
|
|
39
|
+
function DividerRounders({ orientation, startStatus, endStatus, }) {
|
|
40
|
+
return (_jsxs(_Fragment, { children: [_jsx(DividerRounder, { orientation: orientation, edge: "start", status: startStatus }), _jsx(DividerRounder, { orientation: orientation, edge: "end", status: endStatus })] }));
|
|
41
|
+
}
|
|
4
42
|
function getStepStatus(stepIndex, currentStep, totalSteps) {
|
|
5
43
|
if (currentStep <= 0)
|
|
6
44
|
return 'upcoming';
|
|
@@ -31,12 +69,15 @@ function getConnectorStatus(connectorIndex, currentStep, totalSteps) {
|
|
|
31
69
|
/**
|
|
32
70
|
* ProgressTracker Component
|
|
33
71
|
*
|
|
34
|
-
* A
|
|
72
|
+
* A stepper/progress indicator for multi-step forms.
|
|
73
|
+
* Supports horizontal (default) and vertical orientations.
|
|
35
74
|
* Shows numbered step indicators connected by progress lines.
|
|
36
|
-
* Supports 2–
|
|
75
|
+
* Supports 2–10 steps with past, current, and upcoming states.
|
|
76
|
+
*
|
|
77
|
+
* Vertical orientation also supports hover and selected interaction states.
|
|
37
78
|
*
|
|
38
79
|
* Built using the Muka design token system with support for:
|
|
39
|
-
* - Dynamic step counts (2–
|
|
80
|
+
* - Dynamic step counts (2–10)
|
|
40
81
|
* - Step states: past (checkmark), current (number), upcoming (number)
|
|
41
82
|
* - Animated connector lines showing progress
|
|
42
83
|
* - Multi-brand theming through design tokens
|
|
@@ -44,14 +85,73 @@ function getConnectorStatus(connectorIndex, currentStep, totalSteps) {
|
|
|
44
85
|
* Tokens used:
|
|
45
86
|
* - alias.color.accent.{default|contrast|pressed} — step indicator backgrounds
|
|
46
87
|
* - color.surface.sunken — upcoming indicator/connector background
|
|
88
|
+
* - color.surface.level1 — vertical hover/selected backgrounds
|
|
47
89
|
* - color.text.default.{default|inverse} — indicator/label text
|
|
48
|
-
* - text.label.{sm|md}.{regular|bold} — typography
|
|
49
|
-
* -
|
|
90
|
+
* - text.label.{sm|md}.{regular|bold|semibold} — horizontal typography
|
|
91
|
+
* - text.body.base.regular — vertical label typography
|
|
92
|
+
* - spacing.1, spacing.3, spacing.4, spacing.6, spacing.7 — layout spacing
|
|
50
93
|
* - border.radius.full — circular indicators
|
|
51
94
|
*/
|
|
52
|
-
export const ProgressTracker = ({ steps, currentStep, onStepClick, className = '', }) => {
|
|
95
|
+
export const ProgressTracker = ({ steps, currentStep, orientation = 'horizontal', selectedStep, onStepClick, className = '', }) => {
|
|
53
96
|
const totalSteps = steps.length;
|
|
54
|
-
const
|
|
97
|
+
const isVertical = orientation === 'vertical';
|
|
98
|
+
const rootClasses = [
|
|
99
|
+
'muka-progress-tracker',
|
|
100
|
+
`muka-progress-tracker--${orientation}`,
|
|
101
|
+
className,
|
|
102
|
+
].filter(Boolean).join(' ');
|
|
103
|
+
const renderIndicatorContent = (status, stepNumber) => {
|
|
104
|
+
if (status === 'past') {
|
|
105
|
+
return (_jsx(Icon, { name: "check", variant: "fill", size: "sm", className: "muka-progress-tracker__check-icon" }));
|
|
106
|
+
}
|
|
107
|
+
return _jsx("span", { className: "muka-progress-tracker__number", children: stepNumber });
|
|
108
|
+
};
|
|
109
|
+
if (isVertical) {
|
|
110
|
+
return (_jsx("div", { className: rootClasses, role: "group", "aria-label": "Form progress", children: _jsx("div", { className: "muka-progress-tracker__track", children: steps.map((step, index) => {
|
|
111
|
+
const status = getStepStatus(index, currentStep, totalSteps);
|
|
112
|
+
const stepNumber = index + 1;
|
|
113
|
+
const isPast = status === 'past';
|
|
114
|
+
const isCurrent = status === 'current';
|
|
115
|
+
const isLast = index === totalSteps - 1;
|
|
116
|
+
const isSelected = selectedStep === stepNumber;
|
|
117
|
+
const isInteractive = Boolean(onStepClick);
|
|
118
|
+
const stepClasses = [
|
|
119
|
+
'muka-progress-tracker__step',
|
|
120
|
+
`muka-progress-tracker__step--${status}`,
|
|
121
|
+
isInteractive && 'muka-progress-tracker__step--interactive',
|
|
122
|
+
].filter(Boolean).join(' ');
|
|
123
|
+
const indicatorClasses = [
|
|
124
|
+
'muka-progress-tracker__indicator',
|
|
125
|
+
`muka-progress-tracker__indicator--${status}`,
|
|
126
|
+
].join(' ');
|
|
127
|
+
const labelClasses = [
|
|
128
|
+
'muka-progress-tracker__label',
|
|
129
|
+
isCurrent && 'muka-progress-tracker__label--current',
|
|
130
|
+
].filter(Boolean).join(' ');
|
|
131
|
+
const handleClick = isInteractive
|
|
132
|
+
? () => onStepClick(index)
|
|
133
|
+
: undefined;
|
|
134
|
+
const connectorStatus = !isLast
|
|
135
|
+
? getConnectorStatus(index, currentStep, totalSteps)
|
|
136
|
+
: null;
|
|
137
|
+
return (_jsxs("div", { className: stepClasses, "data-selected": isSelected ? 'true' : undefined, "aria-current": isCurrent ? 'step' : undefined, onClick: handleClick, role: handleClick ? 'button' : undefined, tabIndex: handleClick ? 0 : undefined, onKeyDown: handleClick
|
|
138
|
+
? (e) => {
|
|
139
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
140
|
+
e.preventDefault();
|
|
141
|
+
handleClick();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
: undefined, "aria-label": isPast
|
|
145
|
+
? `Step ${stepNumber}: ${step.label} (completed)`
|
|
146
|
+
: isCurrent
|
|
147
|
+
? `Step ${stepNumber}: ${step.label} (current)`
|
|
148
|
+
: `Step ${stepNumber}: ${step.label}`, children: [connectorStatus && (_jsx("div", { className: [
|
|
149
|
+
'muka-progress-tracker__connector',
|
|
150
|
+
`muka-progress-tracker__connector--${connectorStatus}`,
|
|
151
|
+
].join(' '), "aria-hidden": "true", children: _jsx(DividerRounders, { orientation: "vertical", startStatus: status, endStatus: getStepStatus(index + 1, currentStep, totalSteps) }) })), _jsx("div", { className: "muka-progress-tracker__indicator-col", children: _jsx("div", { className: indicatorClasses, children: renderIndicatorContent(status, stepNumber) }) }), _jsx("span", { className: labelClasses, children: step.label })] }, index));
|
|
152
|
+
}) }) }));
|
|
153
|
+
}
|
|
154
|
+
// Horizontal layout (default)
|
|
55
155
|
return (_jsx("div", { className: rootClasses, role: "group", "aria-label": "Form progress", children: _jsxs("div", { className: "muka-progress-tracker__track", children: [_jsx("div", { className: "muka-progress-tracker__steps", children: steps.map((step, index) => {
|
|
56
156
|
const status = getStepStatus(index, currentStep, totalSteps);
|
|
57
157
|
const stepNumber = index + 1;
|
|
@@ -83,14 +183,14 @@ export const ProgressTracker = ({ steps, currentStep, onStepClick, className = '
|
|
|
83
183
|
? `Step ${stepNumber}: ${step.label} (completed)`
|
|
84
184
|
: isCurrent
|
|
85
185
|
? `Step ${stepNumber}: ${step.label} (current)`
|
|
86
|
-
: `Step ${stepNumber}: ${step.label}`, children:
|
|
186
|
+
: `Step ${stepNumber}: ${step.label}`, children: renderIndicatorContent(status, stepNumber) }), _jsx("span", { className: labelClasses, children: step.label })] }, index));
|
|
87
187
|
}) }), _jsx("div", { className: "muka-progress-tracker__connectors", children: Array.from({ length: totalSteps - 1 }, (_, index) => {
|
|
88
188
|
const status = getConnectorStatus(index, currentStep, totalSteps);
|
|
89
189
|
const connectorClasses = [
|
|
90
190
|
'muka-progress-tracker__connector',
|
|
91
191
|
`muka-progress-tracker__connector--${status}`,
|
|
92
192
|
].join(' ');
|
|
93
|
-
return
|
|
193
|
+
return (_jsxs("div", { className: connectorClasses, "aria-hidden": "true", children: [_jsx(DividerRounder, { orientation: "horizontal", edge: "start", status: getStepStatus(index, currentStep, totalSteps) }), _jsx("span", { className: "muka-progress-tracker__connector-line" }), _jsx(DividerRounder, { orientation: "horizontal", edge: "end", status: getStepStatus(index + 1, currentStep, totalSteps) })] }, index));
|
|
94
194
|
}) })] }) }));
|
|
95
195
|
};
|
|
96
196
|
export default ProgressTracker;
|