@maltjoy/mcp-server 0.4.0 → 0.6.0-beta.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/LICENSE +21 -0
- package/README.md +30 -3
- package/dist/doc/VJoyAdminBanner/guideline.md +284 -0
- package/dist/doc/VJoyAvailability/guideline.md +352 -0
- package/dist/doc/VJoyAvatar/guideline.md +192 -0
- package/dist/doc/VJoyAvatarsList/guideline.md +328 -0
- package/dist/doc/VJoyBadge/guideline.md +169 -0
- package/dist/doc/VJoyBadgeLevel/guideline.md +166 -0
- package/dist/doc/VJoyBlockSkeleton/guideline.md +150 -0
- package/dist/doc/VJoyBottomSheet/guideline.md +345 -0
- package/dist/doc/VJoyBottomSheetTrigger/guideline.md +156 -0
- package/dist/doc/VJoyButton/guideline.md +371 -0
- package/dist/doc/VJoyButton/metadata.json +0 -16
- package/dist/doc/VJoyButtonCard/guideline.md +384 -0
- package/dist/doc/VJoyCheckbox/guideline.md +317 -0
- package/dist/doc/VJoyCheckboxCard/guideline.md +381 -0
- package/dist/doc/VJoyCheckboxGroup/guideline.md +363 -0
- package/dist/doc/VJoyCheckboxGroup/metadata.json +7 -7
- package/dist/doc/VJoyCollapse/guideline.md +362 -0
- package/dist/doc/VJoyCollapseItem/guideline.md +394 -0
- package/dist/doc/VJoyCompanyAvatar/guideline.md +162 -0
- package/dist/doc/VJoyDialog/guideline.md +425 -0
- package/dist/doc/VJoyDialogTrigger/guideline.md +186 -0
- package/dist/doc/VJoyDot/guideline.md +177 -0
- package/dist/doc/VJoyDrawer/guideline.md +392 -0
- package/dist/doc/VJoyDrawerTrigger/guideline.md +145 -0
- package/dist/doc/VJoyDropdown/guideline.md +393 -0
- package/dist/doc/VJoyDropdown/metadata.json +6 -6
- package/dist/doc/VJoyDropdownList/guideline.md +396 -0
- package/dist/doc/VJoyDropdownList/metadata.json +7 -7
- package/dist/doc/VJoyDropzone/guideline.md +390 -0
- package/dist/doc/VJoyDropzone/metadata.json +36 -1
- package/dist/doc/VJoyFilterBar/guideline.md +419 -0
- package/dist/doc/VJoyFilterBarButton/guideline.md +359 -0
- package/dist/doc/VJoyFloatingActionsBar/guideline.md +372 -0
- package/dist/doc/VJoyFormError/guideline.md +325 -0
- package/dist/doc/VJoyFormError/metadata.json +0 -14
- package/dist/doc/VJoyFormFieldSkeleton/guideline.md +159 -0
- package/dist/doc/VJoyFormGroup/guideline.md +285 -0
- package/dist/doc/VJoyFunnel/guideline.md +349 -0
- package/dist/doc/VJoyFunnelFooter/guideline.md +178 -0
- package/dist/doc/VJoyFunnelHeader/guideline.md +204 -0
- package/dist/doc/VJoyHighlight/guideline.md +169 -0
- package/dist/doc/VJoyIcon/JoyIcon.types.ts +1 -1
- package/dist/doc/VJoyIcon/guideline.md +168 -0
- package/dist/doc/VJoyIcon/metadata.json +0 -1
- package/dist/doc/VJoyIconButton/guideline.md +169 -0
- package/dist/doc/VJoyIconButton/metadata.json +1 -1
- package/dist/doc/VJoyIndicator/guideline.md +168 -0
- package/dist/doc/VJoyIndicators/guideline.md +183 -0
- package/dist/doc/VJoyInput/JoyInput.types.ts +1 -6
- package/dist/doc/VJoyInput/guideline.md +401 -0
- package/dist/doc/VJoyInput/metadata.json +5 -14
- package/dist/doc/VJoyInputDigit/guideline.md +381 -0
- package/dist/doc/VJoyInputNumber/guideline.md +414 -0
- package/dist/doc/VJoyInputNumber/metadata.json +22 -17
- package/dist/doc/VJoyInputPassword/guideline.md +379 -0
- package/dist/doc/VJoyInputPassword/metadata.json +0 -14
- package/dist/doc/VJoyLabel/guideline.md +200 -0
- package/dist/doc/VJoyLink/guideline.md +360 -0
- package/dist/doc/VJoyListItem/guideline.md +335 -0
- package/dist/doc/VJoyMenu/guideline.md +304 -0
- package/dist/doc/VJoyMenu/metadata.json +21 -21
- package/dist/doc/VJoyMenuItem/guideline.md +352 -0
- package/dist/doc/VJoyPagination/guideline.md +355 -0
- package/dist/doc/VJoyPanel/guideline.md +238 -0
- package/dist/doc/VJoyPanelSection/guideline.md +160 -0
- package/dist/doc/VJoyPasswordRequirement/guideline.md +336 -0
- package/dist/doc/VJoyPasswordRequirement/metadata.json +1 -1
- package/dist/doc/VJoyProductTour/JoyProductTour.types.ts +0 -1
- package/dist/doc/VJoyProductTour/guideline.md +455 -0
- package/dist/doc/VJoyProductTour/metadata.json +1 -1
- package/dist/doc/VJoyProductTourTrigger/guideline.md +167 -0
- package/dist/doc/VJoyProgressBar/guideline.md +348 -0
- package/dist/doc/VJoyRadio/guideline.md +346 -0
- package/dist/doc/VJoyRadioGroup/guideline.md +331 -0
- package/dist/doc/VJoyRatingStars/guideline.md +306 -0
- package/dist/doc/VJoyScreenLoader/guideline.md +172 -0
- package/dist/doc/VJoySelect/guideline.md +396 -0
- package/dist/doc/VJoySelectableItem/guideline.md +351 -0
- package/dist/doc/VJoySelectableItemGroup/guideline.md +370 -0
- package/dist/doc/VJoySeparator/guideline.md +161 -0
- package/dist/doc/VJoySnackbar/guideline.md +402 -0
- package/dist/doc/VJoySpinner/guideline.md +168 -0
- package/dist/doc/VJoyStep/guideline.md +182 -0
- package/dist/doc/VJoyStepper/guideline.md +390 -0
- package/dist/doc/VJoyTab/guideline.md +298 -0
- package/dist/doc/VJoyTabs/guideline.md +353 -0
- package/dist/doc/VJoyTag/guideline.md +226 -0
- package/dist/doc/VJoyTagsInput/guideline.md +387 -0
- package/dist/doc/VJoyTagsList/guideline.md +311 -0
- package/dist/doc/VJoyTagsList/metadata.json +27 -27
- package/dist/doc/VJoyTemplate/guideline.md +366 -0
- package/dist/doc/VJoyText/guideline.md +175 -0
- package/dist/doc/VJoyText/metadata.json +1 -1
- package/dist/doc/VJoyTextarea/guideline.md +378 -0
- package/dist/doc/VJoyTitleBrand/guideline.md +155 -0
- package/dist/doc/VJoyToggle/guideline.md +327 -0
- package/dist/doc/VJoyTooltip/guideline.md +322 -0
- package/dist/doc/VJoyUserCard/guideline.md +268 -0
- package/dist/doc/VJoyUserCard/metadata.json +3 -17
- package/dist/doc/VJoyWalkthrough/guideline.md +351 -0
- package/dist/doc/VJoyWalkthroughTrigger/guideline.md +171 -0
- package/dist/doc/VJoyWrapper/guideline.md +173 -0
- package/dist/doc/css-classes.json +1 -15
- package/dist/doc/design-tokens.json +1 -0
- package/dist/doc/index.json +20 -30
- package/dist/index.js +22 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/get-component-guideline.d.ts +30 -0
- package/dist/tools/get-component-guideline.d.ts.map +1 -0
- package/dist/tools/get-component-guideline.js +51 -0
- package/dist/tools/get-component-guideline.js.map +1 -0
- package/dist/tools/get-documentation-page.d.ts +22 -0
- package/dist/tools/get-documentation-page.d.ts.map +1 -0
- package/dist/tools/get-documentation-page.js +21 -0
- package/dist/tools/get-documentation-page.js.map +1 -0
- package/dist/tools/list-documentation-pages.d.ts +22 -0
- package/dist/tools/list-documentation-pages.d.ts.map +1 -0
- package/dist/tools/list-documentation-pages.js +17 -0
- package/dist/tools/list-documentation-pages.js.map +1 -0
- package/dist/tools/search-documentation.d.ts +41 -0
- package/dist/tools/search-documentation.d.ts.map +1 -0
- package/dist/tools/search-documentation.js +25 -0
- package/dist/tools/search-documentation.js.map +1 -0
- package/dist/zeroheight-parser.d.ts +27 -0
- package/dist/zeroheight-parser.d.ts.map +1 -0
- package/dist/zeroheight-parser.js +77 -0
- package/dist/zeroheight-parser.js.map +1 -0
- package/package.json +10 -10
- package/dist/doc/VJoyMultiCheckbox/metadata.json +0 -332
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: VJoyStep
|
|
3
|
+
status: draft
|
|
4
|
+
language: en
|
|
5
|
+
dsds: JoyStep.dsds.json
|
|
6
|
+
dsdsVersion: "0.15.2"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Step
|
|
10
|
+
|
|
11
|
+
Use **`VJoyStep`** as one segment in a multi-step progress indicator — a horizontal bar with an optional text label.
|
|
12
|
+
|
|
13
|
+
Each step shows fill progress for **completed**, **current**, or **upcoming** states. Compose several `VJoyStep` children inside **`VJoyStepper`**, which drives `completed` and `currentSubStep` from its `step` and `subStep` props. Use `subSteps` on a step when that main step has internal sub-progress.
|
|
14
|
+
|
|
15
|
+
| | |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **Code** | `VJoyStep` from `@maltjoy/core-vue` |
|
|
18
|
+
| **Design** | [ZeroHeight — Stepper](https://joy.malt.com/6bf479565/p/83eba5-stepper) |
|
|
19
|
+
| **Storybook** | [VJoyStepper docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-view-vjoystepper--docs) (includes `VJoyStep` children) |
|
|
20
|
+
| **DSDS (machine)** | [`JoyStep.dsds.json`](./JoyStep.dsds.json) |
|
|
21
|
+
| **Live API** | `joy_get_component_info("VJoyStep")` |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## When to use this component
|
|
26
|
+
|
|
27
|
+
Use a step segment when a workflow has **named stages** the user should track — onboarding funnels, multi-page forms, checkout, or any linear process with 2–6 main steps.
|
|
28
|
+
|
|
29
|
+
Typical pattern: render one `VJoyStep` per stage as children of `VJoyStepper`, put the step name in the default slot, and bind `VJoyStepper` `step` (and optionally `subStep`) to your flow state. Set `subSteps` on a step when that stage itself has substages and you want finer fill animation on the bar.
|
|
30
|
+
|
|
31
|
+
### When not to use this component
|
|
32
|
+
|
|
33
|
+
| Need | Use instead |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| Managing the full stepper row and current index | `VJoyStepper` (parent of `VJoyStep` children) |
|
|
36
|
+
| A single percentage or completion bar (no named steps) | `VJoyProgressBar` |
|
|
37
|
+
| Full-page guided flow shell (header, footer, scroll) | `VJoyFunnel` + `VJoyStepper` in `#funnel-stepper` |
|
|
38
|
+
| Carousel / page dot indicators | `VJoyIndicators` |
|
|
39
|
+
| Custom progress bars with ad-hoc CSS | Still use `VJoyStep` + Joy tokens — don’t reinvent step chrome |
|
|
40
|
+
|
|
41
|
+
> **Composition:** `VJoyStep` is a **child** of `VJoyStepper` in almost all product code. Using it standalone is valid for Storybook or tests, but apps should drive state through the stepper.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## How it works
|
|
46
|
+
|
|
47
|
+
### Anatomy
|
|
48
|
+
|
|
49
|
+
| Part | Required? | What it is |
|
|
50
|
+
| --- | --- | --- |
|
|
51
|
+
| Root container | Yes | `.joy-step` with size and state modifier classes |
|
|
52
|
+
| Stroke track | Yes | `.joy-step__stroke` — full-width neutral bar (8px height) |
|
|
53
|
+
| Stroke fill | Yes | `.joy-step__stroke--filled` — colored segment; width driven by internal `progress` |
|
|
54
|
+
| Label | No* | Default slot in `.joy-step__label`; animated in/out when `showLabel` is true |
|
|
55
|
+
|
|
56
|
+
\*Label slot is optional, but each step in a stepper **should** have a short name for clarity. Labels are **hidden below 480px viewport width** via component CSS.
|
|
57
|
+
|
|
58
|
+
### Default values
|
|
59
|
+
|
|
60
|
+
- `completed` defaults to **`false`**
|
|
61
|
+
- `currentSubStep` defaults to **`0`** (upcoming — no fill)
|
|
62
|
+
- `subSteps` defaults to **`1`** (no sub-progress granularity)
|
|
63
|
+
- `size` defaults to **`default`** (`small` only reduces label typography — not bar height)
|
|
64
|
+
- `showLabel` defaults to **`true`**
|
|
65
|
+
- `id` defaults to a generated `joy-step-value--{random}` string
|
|
66
|
+
|
|
67
|
+
Props, events, and slots: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
|
|
68
|
+
|
|
69
|
+
### Progress logic
|
|
70
|
+
|
|
71
|
+
`VJoyStep` computes bar fill from props (exposed as `progress`):
|
|
72
|
+
|
|
73
|
+
| Condition | Fill |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| `completed` is `true` | `100%` |
|
|
76
|
+
| `currentSubStep` is `0` | `0%` (upcoming) |
|
|
77
|
+
| Current, `subSteps` ≤ 1 or `currentSubStep` is `1` | `10%` (started) |
|
|
78
|
+
| Current with `subSteps` > 1 | Scales between ~10% and ~90% from `currentSubStep / subSteps` |
|
|
79
|
+
|
|
80
|
+
`VJoyStepper` sets `completed` on steps before the active index and passes `currentSubStep` only to the active step. When using `VJoyStep` without a stepper, wire these props yourself.
|
|
81
|
+
|
|
82
|
+
`subSteps` must be **≥ 1**; values ≤ 0 log a console warning and emit `update:subSteps`.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Best practices
|
|
87
|
+
|
|
88
|
+
Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
|
|
89
|
+
|
|
90
|
+
### Composition
|
|
91
|
+
|
|
92
|
+
- **MUST** compose `VJoyStep` children inside `VJoyStepper` for multi-step flows — let the stepper own `step` / `subStep` state.
|
|
93
|
+
- **SHOULD** provide a short default-slot label per step (noun or short phrase).
|
|
94
|
+
- **SHOULD** use `subSteps` only on steps that genuinely have internal substages — keep most steps at the default `1`.
|
|
95
|
+
- **SHOULD** place the stepper in `VJoyFunnel`’s `#funnel-stepper` slot for full-page funnels.
|
|
96
|
+
- **MUST NOT** use `VJoyStep` alone when the UI needs step navigation — that belongs in page logic + `VJoyStepper`.
|
|
97
|
+
|
|
98
|
+
### Implementation
|
|
99
|
+
|
|
100
|
+
- **MUST** use only documented props from MCP or `TJoyStep.types.ts`.
|
|
101
|
+
- **MUST** use Joy tokens — no custom `.joy-step` bar or label overrides.
|
|
102
|
+
- **MUST NOT** invent props (`variant`, `color`, `active`, …).
|
|
103
|
+
- **MUST NOT** hardcode bar height or fill colors — they come from CSS variables (`--stepper-border-color`, `--stepper-border-color-filled`, etc.).
|
|
104
|
+
- **SHOULD** treat `size="small"` as a **label density** choice only; bar dimensions stay the same.
|
|
105
|
+
|
|
106
|
+
### Do / don’t
|
|
107
|
+
|
|
108
|
+
| Do | Don’t |
|
|
109
|
+
| --- | --- |
|
|
110
|
+
| `VJoyStepper` + one `VJoyStep` per stage | Manual flex row of custom progress divs |
|
|
111
|
+
| Short labels in the default slot | Long descriptions in the step label |
|
|
112
|
+
| `subSteps` on steps with real substages | `subSteps` > 1 on every step by default |
|
|
113
|
+
| `VJoyFunnel` `#funnel-stepper` for funnels | Stepper floating without layout context |
|
|
114
|
+
| `VJoyProgressBar` for a single % | `VJoyStep` for non-stepped progress |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Accessibility
|
|
119
|
+
|
|
120
|
+
Behaviors (what must happen), not slogans.
|
|
121
|
+
|
|
122
|
+
| Behavior | Expectation |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| Role | Presentational segments — not interactive controls |
|
|
125
|
+
| Name | Step meaning comes from the visible default-slot label when `showLabel` is true |
|
|
126
|
+
| Mobile | Labels are not shown below 480px — ensure step context is clear from page title or heading |
|
|
127
|
+
| Progress | Bar fill is decorative; don’t rely on color alone — labels (or page headings) name each stage |
|
|
128
|
+
| Grouping | Multiple steps in `VJoyStepper` form one progress indicator; keep DOM order matching visual order |
|
|
129
|
+
| Funnel | `VJoyFunnel` collapses stepper labels on scroll — primary step context should remain in the page heading |
|
|
130
|
+
|
|
131
|
+
Target: **WCAG 2.2 AA** where the product requires it.
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Examples
|
|
136
|
+
|
|
137
|
+
```vue
|
|
138
|
+
<script setup lang="ts">
|
|
139
|
+
import { ref } from 'vue'
|
|
140
|
+
import { VJoyStepper, VJoyStep } from '@maltjoy/core-vue'
|
|
141
|
+
|
|
142
|
+
const currentStep = ref(2)
|
|
143
|
+
const currentSubStep = ref(3)
|
|
144
|
+
</script>
|
|
145
|
+
|
|
146
|
+
<template>
|
|
147
|
+
<!-- Typical: stepper owns state -->
|
|
148
|
+
<VJoyStepper :step="currentStep" :sub-step="currentSubStep">
|
|
149
|
+
<VJoyStep>Introduction</VJoyStep>
|
|
150
|
+
<VJoyStep :sub-steps="4">Profile</VJoyStep>
|
|
151
|
+
<VJoyStep>Review</VJoyStep>
|
|
152
|
+
<VJoyStep>Confirmation</VJoyStep>
|
|
153
|
+
</VJoyStepper>
|
|
154
|
+
|
|
155
|
+
<!-- Standalone (tests / edge cases) — wire props manually -->
|
|
156
|
+
<VJoyStep completed>Done</VJoyStep>
|
|
157
|
+
<VJoyStep :current-sub-step="2" :sub-steps="3">In progress</VJoyStep>
|
|
158
|
+
<VJoyStep>Upcoming</VJoyStep>
|
|
159
|
+
|
|
160
|
+
<!-- Smaller label typography -->
|
|
161
|
+
<VJoyStep size="small" :current-sub-step="1">Compact label</VJoyStep>
|
|
162
|
+
|
|
163
|
+
<!-- Hide label (bar only) -->
|
|
164
|
+
<VJoyStep :show-label="false" :current-sub-step="1" />
|
|
165
|
+
</template>
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
In Nuxt (or apps with auto-import), omit the import if `VJoyStep` and `VJoyStepper` are already global.
|
|
169
|
+
|
|
170
|
+
For funnel layouts, see `VJoyFunnel` docs — place `VJoyStepper` in `#funnel-stepper`.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Related
|
|
175
|
+
|
|
176
|
+
| Component | Use when |
|
|
177
|
+
| --- | --- |
|
|
178
|
+
| `VJoyStepper` | Parent that manages current step, sub-step, and child `VJoyStep` state |
|
|
179
|
+
| `VJoyFunnel` | Full-page multi-step shell with optional stepper slot |
|
|
180
|
+
| `VJoyProgressBar` | Single completion percentage without named steps |
|
|
181
|
+
| `VJoyIndicators` | Dot-style page or carousel indicators |
|
|
182
|
+
| `VJoyFunnelHeader` / `VJoyFunnelFooter` | Navigation chrome inside a funnel |
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: VJoyStepper
|
|
3
|
+
status: draft
|
|
4
|
+
language: en
|
|
5
|
+
dsds: JoyStepper.dsds.json
|
|
6
|
+
dsdsVersion: "0.15.2"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Stepper
|
|
10
|
+
|
|
11
|
+
Use **`VJoyStepper`** with **`VJoyStep`** children when the user is moving through a **linear, multi-step process** — onboarding funnels, registration wizards, or guided workflows — and needs a visual sense of where they are and how much remains.
|
|
12
|
+
|
|
13
|
+
The parent manages which step is current (`step`, 1-based), optional sub-step progress within the active step (`subStep`), and automatically marks earlier steps as completed. Each child renders a progress stroke and an optional text label.
|
|
14
|
+
|
|
15
|
+
| | |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **Code** | `VJoyStepper` + `VJoyStep` from `@maltjoy/core-vue` |
|
|
18
|
+
| **Design** | [ZeroHeight — Stepper](https://zeroheight.com/6bf479565/p/2411991-stepper) |
|
|
19
|
+
| **Storybook** | [VJoyStepper docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-view-vjoystepper--docs) |
|
|
20
|
+
| **DSDS (machine)** | [`JoyStepper.dsds.json`](./JoyStepper.dsds.json) |
|
|
21
|
+
| **Live API** | `joy_get_component_info("VJoyStepper")` · `joy_get_component_info("VJoyStep")` |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## When to use this component
|
|
26
|
+
|
|
27
|
+
Use a stepper when progress through a **fixed sequence** matters — the user should see how many stages exist, which ones are done, and where they are now. Typical jobs: signup funnels, project-creation flows, and multi-screen forms inside `VJoyFunnel`.
|
|
28
|
+
|
|
29
|
+
Place one `VJoyStep` per main stage in the default slot. Drive `step` from your route, wizard state, or page logic when the user moves forward or back. Use `subStep` together with `sub-steps` on the active `VJoyStep` when a single stage has internal milestones (e.g. several screens before advancing to the next main step).
|
|
30
|
+
|
|
31
|
+
### When not to use this component
|
|
32
|
+
|
|
33
|
+
| Need | Use instead |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| Peer sections on one surface (switch panels, not a sequence) | `VJoyTabs` |
|
|
36
|
+
| Expand/collapse optional blocks on the same page | `VJoyCollapse` |
|
|
37
|
+
| A single percentage or task completion bar | `VJoyProgressBar` |
|
|
38
|
+
| Carousel / dot pagination | `VJoyIndicators` |
|
|
39
|
+
| Primary app or site navigation | App shell patterns (`VJoyMenu`, sidebar, header nav) |
|
|
40
|
+
| Clickable steps that jump to arbitrary stages | Not supported — keep linear navigation via footer CTAs |
|
|
41
|
+
| Custom progress markup / ad-hoc bars | Still use `VJoyStepper` + `VJoyStep` + Joy tokens |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## How it works
|
|
46
|
+
|
|
47
|
+
`VJoyStepper` reads **`VJoyStep`** children from its default slot (including via `v-for`), computes completed vs. current vs. upcoming states, and passes progress into each child.
|
|
48
|
+
|
|
49
|
+
### Anatomy
|
|
50
|
+
|
|
51
|
+
| Part | Required? | What it is |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| Stepper container | Yes | Root `.joy-stepper` — horizontal flex row of steps |
|
|
54
|
+
| Step (`VJoyStep`) | Yes (≥1) | One segment per main stage; flexes to share width |
|
|
55
|
+
| Progress stroke | Yes | 8px bar (`joy-step__stroke`); neutral track + secondary fill |
|
|
56
|
+
| Filled portion | Yes | `joy-step__stroke--filled` — width reflects completion / sub-step progress |
|
|
57
|
+
| Step label | No | Text from each `VJoyStep` default slot; can be hidden (see States) |
|
|
58
|
+
|
|
59
|
+
### Default values
|
|
60
|
+
|
|
61
|
+
**`VJoyStepper`**
|
|
62
|
+
|
|
63
|
+
- `step` is **required** — **1-based** index of the active main step
|
|
64
|
+
- `subStep` defaults to **`1`** — position within the active step’s sub-steps
|
|
65
|
+
|
|
66
|
+
**`VJoyStep`** (set on each child; see `VJoyStep` Storybook for detail)
|
|
67
|
+
|
|
68
|
+
- `subSteps` defaults to **`1`**
|
|
69
|
+
- `size` defaults to **`default`** (label typography only — does not change bar height)
|
|
70
|
+
- `showLabel` defaults to **`true`** (overridden when inside `VJoyFunnel` on scroll — see States)
|
|
71
|
+
|
|
72
|
+
Props, events, and slots: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
|
|
73
|
+
|
|
74
|
+
### Composition
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<VJoyStepper :step="currentStep" :sub-step="currentSubStep">
|
|
78
|
+
<VJoyStep>Introduction</VJoyStep>
|
|
79
|
+
<VJoyStep :sub-steps="4">Project details</VJoyStep>
|
|
80
|
+
<VJoyStep>Confirmation</VJoyStep>
|
|
81
|
+
</VJoyStepper>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- **`VJoyStep`** children go in the `VJoyStepper` default slot (static list or `v-for`).
|
|
85
|
+
- Bind **`step`** to your wizard state; increment when the user completes a stage.
|
|
86
|
+
- Set **`sub-steps`** on a child when that stage has multiple internal screens; bind **`sub-step`** on the parent while that stage is active.
|
|
87
|
+
- In funnels, place the stepper in **`VJoyFunnel`**’s `funnel-stepper` slot so label visibility follows scroll behavior.
|
|
88
|
+
|
|
89
|
+
### Sub-step validation
|
|
90
|
+
|
|
91
|
+
If `subStep` is **≤ 0** or **greater than** the active step’s `sub-steps`, the component treats the value as invalid and falls back to the maximum sub-step for that step (`invalidSubStepValue` on the exposed instance). **MUST** keep `subStep` within `1 … subSteps` in product code — do not rely on the fallback.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Variants
|
|
96
|
+
|
|
97
|
+
`VJoyStepper` has **no variant or emphasis prop**. Visual meaning comes from **step state** (completed, ongoing, upcoming) and Joy tokens on each `VJoyStep` stroke and label.
|
|
98
|
+
|
|
99
|
+
Do not simulate alternate color themes with custom CSS — use the component as shipped.
|
|
100
|
+
|
|
101
|
+
### Not in the API: clickable steps
|
|
102
|
+
|
|
103
|
+
The stepper is **presentational**. Users advance via funnel footer CTAs, form submit, or routing — not by clicking step segments. Do not add `@click` handlers or link styling to steps.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Sizes
|
|
108
|
+
|
|
109
|
+
Bar height is fixed at **8px** via Joy stepper tokens — there is no size prop on `VJoyStepper`.
|
|
110
|
+
|
|
111
|
+
Label density is controlled per child with **`size`** on `VJoyStep`:
|
|
112
|
+
|
|
113
|
+
| Size | Use when |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| `default` | Standard funnel headers and desktop layouts |
|
|
116
|
+
| `small` | Dense funnels or when labels must stay compact (bar height unchanged) |
|
|
117
|
+
|
|
118
|
+
**Do not hardcode stroke height or label font sizes** in apps — use `size` and `--joy-font-size-primary-*` tokens.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## States
|
|
123
|
+
|
|
124
|
+
| State | What the user sees |
|
|
125
|
+
| --- | --- |
|
|
126
|
+
| Completed | Earlier steps (`index < step - 1`): fill at 100%; muted label color |
|
|
127
|
+
| Ongoing (current) | Active step: secondary fill animates with `subStep` / `sub-steps`; bold label |
|
|
128
|
+
| Upcoming | Later steps: empty track; neutral label |
|
|
129
|
+
| Sub-step progress | On the current step only — fill grows from ~10% at sub-step 1 toward 100% as `subStep` approaches `sub-steps` |
|
|
130
|
+
| Labels visible | Default — each `VJoyStep` shows its slot text below the bar |
|
|
131
|
+
| Labels hidden (mobile) | Viewports **≤ 479px** — labels are hidden in CSS; progress bars remain |
|
|
132
|
+
| Labels hidden (funnel scroll) | Inside `VJoyFunnel`, labels hide when the user scrolls the content (`VJoyStepperShowLabels` inject) — strokes stay visible |
|
|
133
|
+
|
|
134
|
+
There is **no disabled, error, or loading state** on the stepper itself. Reflect validation or blocking in the funnel footer (`VJoyFunnelFooter` + `VJoyButton`), not on the progress bar.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Best practices
|
|
139
|
+
|
|
140
|
+
Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
|
|
141
|
+
|
|
142
|
+
### Structure / flow
|
|
143
|
+
|
|
144
|
+
- **MUST** keep the flow **linear** — one active `step` at a time; update `step` when the user legitimately advances or goes back.
|
|
145
|
+
- **SHOULD** limit main steps to **about 3** per design guidance — split very long flows across routes or sessions instead of many equal segments.
|
|
146
|
+
- **SHOULD** limit sub-steps to **≤ 10** per main step when using `sub-steps` / `subStep`.
|
|
147
|
+
- **SHOULD** place the stepper in `VJoyFunnel`’s `funnel-stepper` slot for full-page funnels so sticky header + scroll label behavior applies.
|
|
148
|
+
- **MUST NOT** use the stepper as navigation — no jumping to arbitrary steps by clicking bars.
|
|
149
|
+
|
|
150
|
+
### Implementation
|
|
151
|
+
|
|
152
|
+
- **MUST** compose `VJoyStepper` with **`VJoyStep`** children — not hand-rolled divs.
|
|
153
|
+
- **MUST** use only documented props (Joy MCP / Storybook). No `variant`, `disabled`, or `href` props exist.
|
|
154
|
+
- **MUST** treat `step` as **1-based** (first step = `1`, not `0`).
|
|
155
|
+
- **MUST** keep `subStep` within `1 … subSteps` for the active step.
|
|
156
|
+
- **MUST** style with Joy tokens — no custom `.joy-stepper` / `.joy-step__stroke` chrome overrides.
|
|
157
|
+
- **MUST NOT** invent props on `VJoyStepper` or `VJoyStep`.
|
|
158
|
+
- **SHOULD** use `v-for` on `VJoyStep` when steps are data-driven — `VJoyStepper` unwraps a single fragment child.
|
|
159
|
+
|
|
160
|
+
### Intermediate / untitled steps
|
|
161
|
+
|
|
162
|
+
Design allows **intermediate** segments that show progress without a title — leave the `VJoyStep` default slot empty when only the bar should communicate position. Prefer titled steps when the user benefits from named stages.
|
|
163
|
+
|
|
164
|
+
### Do / don’t
|
|
165
|
+
|
|
166
|
+
| Do | Don’t |
|
|
167
|
+
| --- | --- |
|
|
168
|
+
| `step` + `sub-step` driven by wizard state | Hardcoded step index with no back-navigation sync |
|
|
169
|
+
| Short noun labels per step | Long sentences or verb-only imperatives in labels |
|
|
170
|
+
| `sub-steps` only on steps that need internal progress | `sub-steps="10"` on every step “just in case” |
|
|
171
|
+
| `VJoyFunnel` + `VJoyFunnelFooter` for funnel CTAs | Clickable step bars as the only navigation |
|
|
172
|
+
| `size="small"` for dense funnels | Custom 4px / 12px bar heights |
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Content
|
|
177
|
+
|
|
178
|
+
Step labels name **stages**, not actions. They appear under the bar on larger viewports and may hide on small screens or when the funnel content scrolls.
|
|
179
|
+
|
|
180
|
+
### Label formula
|
|
181
|
+
|
|
182
|
+
**Short noun or noun phrase** naming the stage:
|
|
183
|
+
|
|
184
|
+
- ✅ Introduction · Project details · Confirmation
|
|
185
|
+
- ✅ Profile · Billing · Review
|
|
186
|
+
|
|
187
|
+
Use **parallel structure** across steps (all nouns, similar length). Per Malt conjugation guidance, prefer **nouns** over infinitives or imperatives in stepper labels.
|
|
188
|
+
|
|
189
|
+
### Writing rules
|
|
190
|
+
|
|
191
|
+
| Strength | Rule |
|
|
192
|
+
| --- | --- |
|
|
193
|
+
| **MUST** | Keep labels **short** — aim for **≤ 3–4 words**; the bar is the primary progress cue on mobile |
|
|
194
|
+
| **MUST** | Use **sentence case** (or product locale rules) consistently across the set |
|
|
195
|
+
| **MUST** | Make each label **distinct** — no two steps that differ only by punctuation |
|
|
196
|
+
| **MUST NOT** | Use button-style imperatives as labels — ❌ `Continue`, `Submit` (save verbs for footer CTAs) |
|
|
197
|
+
| **MUST NOT** | Repeat the funnel page title in every step — ❌ `Create project — Details` → ✅ `Details` |
|
|
198
|
+
| **SHOULD** | Name the **stage**, not the UI — ✅ `Verification` · ❌ `Step 2` |
|
|
199
|
+
| **SHOULD** | Omit labels only when intermediate nameless segments are intentional |
|
|
200
|
+
| **SHOULD** (FR) | Prefer nouns (`Introduction`, `Description du besoin`) over infinitives; avoid imperative `-ez` in labels |
|
|
201
|
+
|
|
202
|
+
### Patterns
|
|
203
|
+
|
|
204
|
+
**Three-step funnel** — `Introduction` → `Details` → `Confirmation`. Default tab: step 1; footer `Next` advances `step`.
|
|
205
|
+
|
|
206
|
+
**Stage with internal screens** — set `:sub-steps="4"` on the active `VJoyStep` and bump `:sub-step` as the user moves through substeps before incrementing `step`.
|
|
207
|
+
|
|
208
|
+
**Funnel with scroll** — rely on `VJoyFunnel` to collapse labels while scrolling; ensure stage names are still clear from page headings in the main content.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Accessibility
|
|
213
|
+
|
|
214
|
+
The stepper is **presentational progress feedback**, not an interactive control.
|
|
215
|
+
|
|
216
|
+
| Behavior | Expectation |
|
|
217
|
+
| --- | --- |
|
|
218
|
+
| Role | No tablist / button semantics — decorative progress segments |
|
|
219
|
+
| Interaction | Users do not activate steps directly; navigation happens via footer CTAs or form actions |
|
|
220
|
+
| Name | Step labels are visible text when shown; on mobile or collapsed funnel scroll, **page title / heading** must convey the current stage |
|
|
221
|
+
| Progress | Completed vs. ongoing vs. upcoming is communicated visually (fill + color); do not rely on color alone for critical status — pair with heading copy |
|
|
222
|
+
| Motion | Fill width animates on the ongoing step — respect `prefers-reduced-motion` at the app level if you add custom wrappers |
|
|
223
|
+
| Focus | No focusable elements inside the stepper — keyboard users tab to footer actions |
|
|
224
|
+
|
|
225
|
+
Target: **WCAG 2.2 AA** where the product requires it. For audit trails, expose current position in the document (`<h1>`, `aria-current="step"` on the active section) outside the stepper component.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Examples
|
|
230
|
+
|
|
231
|
+
```vue
|
|
232
|
+
<script setup lang="ts">
|
|
233
|
+
import { ref } from 'vue'
|
|
234
|
+
import {
|
|
235
|
+
VJoyStepper,
|
|
236
|
+
VJoyStep,
|
|
237
|
+
VJoyFunnel,
|
|
238
|
+
VJoyFunnelFooter,
|
|
239
|
+
VJoyButton,
|
|
240
|
+
} from '@maltjoy/core-vue'
|
|
241
|
+
|
|
242
|
+
const currentStep = ref(1)
|
|
243
|
+
const currentSubStep = ref(1)
|
|
244
|
+
|
|
245
|
+
const stages = [
|
|
246
|
+
{ id: 'intro', label: 'Introduction', subSteps: 1, dense: false },
|
|
247
|
+
{ id: 'details', label: 'Project details', subSteps: 4, dense: true },
|
|
248
|
+
{ id: 'confirm', label: 'Confirmation', subSteps: 1, dense: false },
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
function next() {
|
|
252
|
+
if (currentSubStep.value < 4) {
|
|
253
|
+
currentSubStep.value += 1
|
|
254
|
+
return
|
|
255
|
+
}
|
|
256
|
+
currentSubStep.value = 1
|
|
257
|
+
currentStep.value += 1
|
|
258
|
+
}
|
|
259
|
+
</script>
|
|
260
|
+
|
|
261
|
+
<template>
|
|
262
|
+
<!-- Basic wizard -->
|
|
263
|
+
<VJoyStepper :step="currentStep">
|
|
264
|
+
<VJoyStep>Introduction</VJoyStep>
|
|
265
|
+
<VJoyStep>Details</VJoyStep>
|
|
266
|
+
<VJoyStep>Confirmation</VJoyStep>
|
|
267
|
+
</VJoyStepper>
|
|
268
|
+
|
|
269
|
+
<!-- Sub-steps on the active stage -->
|
|
270
|
+
<VJoyStepper :step="2" :sub-step="4">
|
|
271
|
+
<VJoyStep>Introduction</VJoyStep>
|
|
272
|
+
<VJoyStep :sub-steps="4">Project details</VJoyStep>
|
|
273
|
+
<VJoyStep :sub-steps="4">Review</VJoyStep>
|
|
274
|
+
<VJoyStep>Done</VJoyStep>
|
|
275
|
+
</VJoyStepper>
|
|
276
|
+
|
|
277
|
+
<!-- Data-driven steps -->
|
|
278
|
+
<VJoyStepper :step="currentStep" :sub-step="currentSubStep">
|
|
279
|
+
<VJoyStep
|
|
280
|
+
v-for="stage in stages"
|
|
281
|
+
:key="stage.id"
|
|
282
|
+
:sub-steps="stage.subSteps"
|
|
283
|
+
:size="stage.dense ? 'small' : 'default'"
|
|
284
|
+
>
|
|
285
|
+
{{ stage.label }}
|
|
286
|
+
</VJoyStep>
|
|
287
|
+
</VJoyStepper>
|
|
288
|
+
|
|
289
|
+
<!-- Inside a funnel -->
|
|
290
|
+
<VJoyFunnel>
|
|
291
|
+
<template #funnel-stepper>
|
|
292
|
+
<VJoyStepper :step="currentStep" :sub-step="currentSubStep">
|
|
293
|
+
<VJoyStep>Profile</VJoyStep>
|
|
294
|
+
<VJoyStep :sub-steps="4">Project</VJoyStep>
|
|
295
|
+
<VJoyStep>Confirm</VJoyStep>
|
|
296
|
+
</VJoyStepper>
|
|
297
|
+
</template>
|
|
298
|
+
|
|
299
|
+
<!-- …main funnel content… -->
|
|
300
|
+
|
|
301
|
+
<VJoyFunnelFooter>
|
|
302
|
+
<template #footer-right>
|
|
303
|
+
<VJoyButton label="Next" variant="main" size="small" @click="next" />
|
|
304
|
+
</template>
|
|
305
|
+
</VJoyFunnelFooter>
|
|
306
|
+
</VJoyFunnel>
|
|
307
|
+
</template>
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
In Nuxt (or apps with auto-import), omit the import if `VJoyStepper` and `VJoyStep` are already global.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Related
|
|
315
|
+
|
|
316
|
+
| Component | Use when |
|
|
317
|
+
| --- | --- |
|
|
318
|
+
| `VJoyStep` | Required child — one segment per main stage (label, `sub-steps`, `size`) |
|
|
319
|
+
| `VJoyFunnel` | Full-page funnel layout; provides `funnel-stepper` slot and scroll label behavior |
|
|
320
|
+
| `VJoyFunnelFooter` / `VJoyFunnelHeader` | Sticky funnel chrome and primary navigation CTAs |
|
|
321
|
+
| `VJoyButton` | Next, Back, Skip actions in the funnel footer |
|
|
322
|
+
| `VJoyTabs` | Peer sections on one surface, not a sequential flow |
|
|
323
|
+
| `VJoyProgressBar` | Single continuous completion percentage, not discrete stages |
|
|
324
|
+
| `VJoyTemplate` | Page layout inside funnel content |
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## For agents
|
|
329
|
+
|
|
330
|
+
Optional for readers; **required** for vibe-coding quality. Maps to `agentDocumentBlocks` in [`JoyStepper.dsds.json`](./JoyStepper.dsds.json).
|
|
331
|
+
|
|
332
|
+
### Pick the right component
|
|
333
|
+
|
|
334
|
+
| If the intent is… | Emit… | Do not emit… |
|
|
335
|
+
| --- | --- | --- |
|
|
336
|
+
| Linear multi-step funnel / wizard | `VJoyStepper` + `VJoyStep` children | `VJoyTabs` for sequential onboarding |
|
|
337
|
+
| Peer panels on one page | `VJoyTabs` | `VJoyStepper` |
|
|
338
|
+
| One percentage bar | `VJoyProgressBar` | Multiple `VJoyStep` with fake labels |
|
|
339
|
+
| Accordion FAQ on same page | `VJoyCollapse` | `VJoyStepper` |
|
|
340
|
+
| Full-page guided flow | `VJoyFunnel` + `VJoyStepper` in `funnel-stepper` | Bare stepper floating without funnel layout |
|
|
341
|
+
|
|
342
|
+
### Hard rules
|
|
343
|
+
|
|
344
|
+
1. **MUST** call `joy_get_component_info("VJoyStepper")` and `joy_get_component_info("VJoyStep")` (or read Storybook) before generating props.
|
|
345
|
+
2. **MUST** always emit **`VJoyStep`** inside **`VJoyStepper`** default slot — one child per main stage.
|
|
346
|
+
3. **MUST** bind **`step`** (required, **1-based**) to wizard state.
|
|
347
|
+
4. **MUST** use **`sub-step`** on `VJoyStepper` and **`sub-steps`** on the active `VJoyStep` together when a stage has internal progress.
|
|
348
|
+
5. **MUST** keep `subStep` in range `1 … subSteps` for the active step.
|
|
349
|
+
6. **MUST NOT** invent `variant`, `disabled`, `clickable`, or navigation props.
|
|
350
|
+
7. **MUST NOT** override `.joy-stepper`, `.joy-step__stroke`, or bar height with custom CSS.
|
|
351
|
+
8. **MUST NOT** make steps clickable or use the stepper as the sole navigation mechanism.
|
|
352
|
+
9. **SHOULD** use ~**3** main steps and ≤ **10** sub-steps per design guidance.
|
|
353
|
+
10. **SHOULD** use `size="small"` on `VJoyStep` only for label density — bar stays 8px.
|
|
354
|
+
|
|
355
|
+
### Valid enums (from MCP / types)
|
|
356
|
+
|
|
357
|
+
| Component | Prop | Values |
|
|
358
|
+
| --- | --- | --- |
|
|
359
|
+
| `VJoyStep` | `size` | `default`, `small` |
|
|
360
|
+
|
|
361
|
+
### Checklist
|
|
362
|
+
|
|
363
|
+
- [ ] `VJoyStepper` + one `VJoyStep` per main stage (not standalone `VJoyStep` for wizards)
|
|
364
|
+
- [ ] `step` is 1-based and synced with footer / route navigation
|
|
365
|
+
- [ ] `sub-step` / `sub-steps` aligned and in valid range
|
|
366
|
+
- [ ] Props from MCP / Storybook only — no invented enums
|
|
367
|
+
- [ ] No custom stepper chrome CSS
|
|
368
|
+
- [ ] Labels are short nouns; verbs live on footer `VJoyButton`s
|
|
369
|
+
- [ ] Funnel flows use `VJoyFunnel` `funnel-stepper` slot when appropriate
|
|
370
|
+
- [ ] Current stage named in page heading when labels may be hidden (mobile / scroll)
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## DSDS mapping
|
|
375
|
+
|
|
376
|
+
This Markdown mirrors [`JoyStepper.dsds.json`](./JoyStepper.dsds.json) (DSDS **0.15.2**).
|
|
377
|
+
|
|
378
|
+
| Section here | DSDS block |
|
|
379
|
+
| --- | --- |
|
|
380
|
+
| When to use / not | `use-cases` |
|
|
381
|
+
| Anatomy | `anatomy` |
|
|
382
|
+
| Variants / sizes | `variants` |
|
|
383
|
+
| States | `states` |
|
|
384
|
+
| Best practices / content rules | `guidelines` (+ `content`) |
|
|
385
|
+
| Accessibility | `accessibility` |
|
|
386
|
+
| Examples | `sections` |
|
|
387
|
+
| For agents | `agentDocumentBlocks` |
|
|
388
|
+
| Props detail | `api` in JSON + Joy MCP |
|
|
389
|
+
| Imports | `imports` in JSON |
|
|
390
|
+
| Stroke / typography tokens | `design-specifications` in JSON (`--stepper-border-color-*`, `--joy-font-size-primary-*`) |
|