@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.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +30 -3
  3. package/dist/doc/VJoyAdminBanner/guideline.md +284 -0
  4. package/dist/doc/VJoyAvailability/guideline.md +352 -0
  5. package/dist/doc/VJoyAvatar/guideline.md +192 -0
  6. package/dist/doc/VJoyAvatarsList/guideline.md +328 -0
  7. package/dist/doc/VJoyBadge/guideline.md +169 -0
  8. package/dist/doc/VJoyBadgeLevel/guideline.md +166 -0
  9. package/dist/doc/VJoyBlockSkeleton/guideline.md +150 -0
  10. package/dist/doc/VJoyBottomSheet/guideline.md +345 -0
  11. package/dist/doc/VJoyBottomSheetTrigger/guideline.md +156 -0
  12. package/dist/doc/VJoyButton/guideline.md +371 -0
  13. package/dist/doc/VJoyButton/metadata.json +0 -16
  14. package/dist/doc/VJoyButtonCard/guideline.md +384 -0
  15. package/dist/doc/VJoyCheckbox/guideline.md +317 -0
  16. package/dist/doc/VJoyCheckboxCard/guideline.md +381 -0
  17. package/dist/doc/VJoyCheckboxGroup/guideline.md +363 -0
  18. package/dist/doc/VJoyCheckboxGroup/metadata.json +7 -7
  19. package/dist/doc/VJoyCollapse/guideline.md +362 -0
  20. package/dist/doc/VJoyCollapseItem/guideline.md +394 -0
  21. package/dist/doc/VJoyCompanyAvatar/guideline.md +162 -0
  22. package/dist/doc/VJoyDialog/guideline.md +425 -0
  23. package/dist/doc/VJoyDialogTrigger/guideline.md +186 -0
  24. package/dist/doc/VJoyDot/guideline.md +177 -0
  25. package/dist/doc/VJoyDrawer/guideline.md +392 -0
  26. package/dist/doc/VJoyDrawerTrigger/guideline.md +145 -0
  27. package/dist/doc/VJoyDropdown/guideline.md +393 -0
  28. package/dist/doc/VJoyDropdown/metadata.json +6 -6
  29. package/dist/doc/VJoyDropdownList/guideline.md +396 -0
  30. package/dist/doc/VJoyDropdownList/metadata.json +7 -7
  31. package/dist/doc/VJoyDropzone/guideline.md +390 -0
  32. package/dist/doc/VJoyDropzone/metadata.json +36 -1
  33. package/dist/doc/VJoyFilterBar/guideline.md +419 -0
  34. package/dist/doc/VJoyFilterBarButton/guideline.md +359 -0
  35. package/dist/doc/VJoyFloatingActionsBar/guideline.md +372 -0
  36. package/dist/doc/VJoyFormError/guideline.md +325 -0
  37. package/dist/doc/VJoyFormError/metadata.json +0 -14
  38. package/dist/doc/VJoyFormFieldSkeleton/guideline.md +159 -0
  39. package/dist/doc/VJoyFormGroup/guideline.md +285 -0
  40. package/dist/doc/VJoyFunnel/guideline.md +349 -0
  41. package/dist/doc/VJoyFunnelFooter/guideline.md +178 -0
  42. package/dist/doc/VJoyFunnelHeader/guideline.md +204 -0
  43. package/dist/doc/VJoyHighlight/guideline.md +169 -0
  44. package/dist/doc/VJoyIcon/JoyIcon.types.ts +1 -1
  45. package/dist/doc/VJoyIcon/guideline.md +168 -0
  46. package/dist/doc/VJoyIcon/metadata.json +0 -1
  47. package/dist/doc/VJoyIconButton/guideline.md +169 -0
  48. package/dist/doc/VJoyIconButton/metadata.json +1 -1
  49. package/dist/doc/VJoyIndicator/guideline.md +168 -0
  50. package/dist/doc/VJoyIndicators/guideline.md +183 -0
  51. package/dist/doc/VJoyInput/JoyInput.types.ts +1 -6
  52. package/dist/doc/VJoyInput/guideline.md +401 -0
  53. package/dist/doc/VJoyInput/metadata.json +5 -14
  54. package/dist/doc/VJoyInputDigit/guideline.md +381 -0
  55. package/dist/doc/VJoyInputNumber/guideline.md +414 -0
  56. package/dist/doc/VJoyInputNumber/metadata.json +22 -17
  57. package/dist/doc/VJoyInputPassword/guideline.md +379 -0
  58. package/dist/doc/VJoyInputPassword/metadata.json +0 -14
  59. package/dist/doc/VJoyLabel/guideline.md +200 -0
  60. package/dist/doc/VJoyLink/guideline.md +360 -0
  61. package/dist/doc/VJoyListItem/guideline.md +335 -0
  62. package/dist/doc/VJoyMenu/guideline.md +304 -0
  63. package/dist/doc/VJoyMenu/metadata.json +21 -21
  64. package/dist/doc/VJoyMenuItem/guideline.md +352 -0
  65. package/dist/doc/VJoyPagination/guideline.md +355 -0
  66. package/dist/doc/VJoyPanel/guideline.md +238 -0
  67. package/dist/doc/VJoyPanelSection/guideline.md +160 -0
  68. package/dist/doc/VJoyPasswordRequirement/guideline.md +336 -0
  69. package/dist/doc/VJoyPasswordRequirement/metadata.json +1 -1
  70. package/dist/doc/VJoyProductTour/JoyProductTour.types.ts +0 -1
  71. package/dist/doc/VJoyProductTour/guideline.md +455 -0
  72. package/dist/doc/VJoyProductTour/metadata.json +1 -1
  73. package/dist/doc/VJoyProductTourTrigger/guideline.md +167 -0
  74. package/dist/doc/VJoyProgressBar/guideline.md +348 -0
  75. package/dist/doc/VJoyRadio/guideline.md +346 -0
  76. package/dist/doc/VJoyRadioGroup/guideline.md +331 -0
  77. package/dist/doc/VJoyRatingStars/guideline.md +306 -0
  78. package/dist/doc/VJoyScreenLoader/guideline.md +172 -0
  79. package/dist/doc/VJoySelect/guideline.md +396 -0
  80. package/dist/doc/VJoySelectableItem/guideline.md +351 -0
  81. package/dist/doc/VJoySelectableItemGroup/guideline.md +370 -0
  82. package/dist/doc/VJoySeparator/guideline.md +161 -0
  83. package/dist/doc/VJoySnackbar/guideline.md +402 -0
  84. package/dist/doc/VJoySpinner/guideline.md +168 -0
  85. package/dist/doc/VJoyStep/guideline.md +182 -0
  86. package/dist/doc/VJoyStepper/guideline.md +390 -0
  87. package/dist/doc/VJoyTab/guideline.md +298 -0
  88. package/dist/doc/VJoyTabs/guideline.md +353 -0
  89. package/dist/doc/VJoyTag/guideline.md +226 -0
  90. package/dist/doc/VJoyTagsInput/guideline.md +387 -0
  91. package/dist/doc/VJoyTagsList/guideline.md +311 -0
  92. package/dist/doc/VJoyTagsList/metadata.json +27 -27
  93. package/dist/doc/VJoyTemplate/guideline.md +366 -0
  94. package/dist/doc/VJoyText/guideline.md +175 -0
  95. package/dist/doc/VJoyText/metadata.json +1 -1
  96. package/dist/doc/VJoyTextarea/guideline.md +378 -0
  97. package/dist/doc/VJoyTitleBrand/guideline.md +155 -0
  98. package/dist/doc/VJoyToggle/guideline.md +327 -0
  99. package/dist/doc/VJoyTooltip/guideline.md +322 -0
  100. package/dist/doc/VJoyUserCard/guideline.md +268 -0
  101. package/dist/doc/VJoyUserCard/metadata.json +3 -17
  102. package/dist/doc/VJoyWalkthrough/guideline.md +351 -0
  103. package/dist/doc/VJoyWalkthroughTrigger/guideline.md +171 -0
  104. package/dist/doc/VJoyWrapper/guideline.md +173 -0
  105. package/dist/doc/css-classes.json +1 -15
  106. package/dist/doc/design-tokens.json +1 -0
  107. package/dist/doc/index.json +20 -30
  108. package/dist/index.js +22 -2
  109. package/dist/index.js.map +1 -1
  110. package/dist/tools/get-component-guideline.d.ts +30 -0
  111. package/dist/tools/get-component-guideline.d.ts.map +1 -0
  112. package/dist/tools/get-component-guideline.js +51 -0
  113. package/dist/tools/get-component-guideline.js.map +1 -0
  114. package/dist/tools/get-documentation-page.d.ts +22 -0
  115. package/dist/tools/get-documentation-page.d.ts.map +1 -0
  116. package/dist/tools/get-documentation-page.js +21 -0
  117. package/dist/tools/get-documentation-page.js.map +1 -0
  118. package/dist/tools/list-documentation-pages.d.ts +22 -0
  119. package/dist/tools/list-documentation-pages.d.ts.map +1 -0
  120. package/dist/tools/list-documentation-pages.js +17 -0
  121. package/dist/tools/list-documentation-pages.js.map +1 -0
  122. package/dist/tools/search-documentation.d.ts +41 -0
  123. package/dist/tools/search-documentation.d.ts.map +1 -0
  124. package/dist/tools/search-documentation.js +25 -0
  125. package/dist/tools/search-documentation.js.map +1 -0
  126. package/dist/zeroheight-parser.d.ts +27 -0
  127. package/dist/zeroheight-parser.d.ts.map +1 -0
  128. package/dist/zeroheight-parser.js +77 -0
  129. package/dist/zeroheight-parser.js.map +1 -0
  130. package/package.json +10 -10
  131. package/dist/doc/VJoyMultiCheckbox/metadata.json +0 -332
@@ -0,0 +1,349 @@
1
+ ---
2
+ component: VJoyFunnel
3
+ status: draft
4
+ language: en
5
+ dsds: JoyFunnel.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Funnel
10
+
11
+ Use **`VJoyFunnel`** when the user must complete a **multi-step, full-page guided flow** — onboarding, registration, checkout, or any linear workflow that takes over the viewport.
12
+
13
+ It provides a fixed full-screen shell with a sticky header, optional progress stepper, scrollable main area, and decorative background shapes. Compose page content with **`VJoyTemplate`** in the default slot, navigation chrome with **`VJoyFunnelHeader`** and **`VJoyFunnelFooter`**, and progress with **`VJoyStepper`**.
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyFunnel` from `@maltjoy/core-vue` |
18
+ | **Design** | [Figma — Joy Core Design System](https://www.figma.com/design/jfndp2QBJGS9yeuWbeGuvD/) |
19
+ | **Storybook** | [VJoyFunnel docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-layout-vjoyfunnel--docs) |
20
+ | **DSDS (machine)** | [`JoyFunnel.dsds.json`](./JoyFunnel.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyFunnel")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use a funnel when the product needs a **dedicated, distraction-free surface** for a sequence of steps the user completes before returning to the main app. Typical jobs: signup, project creation wizards, strategy onboarding, or any flow where each step has a title, body content, and Previous / Next actions.
28
+
29
+ The layout is optimized for **mobile and desktop**: content scrolls inside the funnel while the header (and stepper, when present) stays visible. Pair it with `VJoyStepper` when users need progress feedback across main steps and sub-steps.
30
+
31
+ ### When not to use this component
32
+
33
+ | Need | Use instead |
34
+ | --- | --- |
35
+ | A modal interrupt on the current page | `VJoyDialog` |
36
+ | A slide-in panel for filters or details | `VJoyDrawer` |
37
+ | A standard app page with global navigation | `VJoyTemplate` alone (no full-screen takeover) |
38
+ | A single form on a regular page | `VJoyTemplate` + `VJoyPanel` inside the app shell |
39
+ | Custom full-screen layout with ad-hoc CSS | Still use `VJoyFunnel` + Joy tokens — don’t reinvent the shell |
40
+
41
+ > **Deprecated:** do not use the `funnel-footer` slot on new work. Place **`VJoyFunnelFooter`** inside the default slot (typically in `VJoyTemplate`’s `template-main`), not in a dedicated funnel footer slot.
42
+
43
+ > **Renamed:** `VJoyHeader` inside funnels is now **`VJoyFunnelHeader`**. MCP slot docs may still mention `VJoyHeader`; emit `VJoyFunnelHeader` in the `funnel-header` slot.
44
+
45
+ ---
46
+
47
+ ## How it works
48
+
49
+ ### Anatomy
50
+
51
+ | Part | Required? | What it is |
52
+ | --- | --- | --- |
53
+ | Root shell (`joy-funnel`) | Yes | Fixed full-viewport container (`position: fixed`, funnel z-index, neutral background) |
54
+ | Header area (`funnel-header` slot) | No | Sticky top bar — typically `VJoyFunnelHeader` (logo left, close / help right) |
55
+ | Stepper area (`funnel-stepper` slot) | No | Progress row — typically `VJoyStepper` + `VJoyStep` children; hidden when slot is empty |
56
+ | Scrollable region | Yes | Main scroll container; drives stepper label visibility |
57
+ | Content area (default slot) | Yes | Page body — typically `VJoyTemplate` with title, subtitle, main, optional sidebar |
58
+ | Decorative shapes | No* | Bottom-right brand shapes (*shown unless `hideShapes` is true; hidden below 1420px viewport width) |
59
+ | Footer actions | No | Not a funnel slot — use `VJoyFunnelFooter` inside `template-main` |
60
+
61
+ ### Composition pattern
62
+
63
+ ```text
64
+ VJoyFunnel
65
+ ├── #funnel-header → VJoyFunnelHeader (logo, close)
66
+ ├── #funnel-stepper → VJoyStepper (optional)
67
+ └── default → VJoyTemplate
68
+ ├── #template-title / #template-subtitle
69
+ └── #template-main → VJoyPanel + VJoyFunnelFooter (Previous / Next)
70
+ ```
71
+
72
+ `VJoyFunnel` resets `--template-inner-spacing` on nested `.joy-template` to `0` so funnel content aligns with funnel padding tokens.
73
+
74
+ ### Default values
75
+
76
+ - `layoutWidth` defaults to **`large`** (max content width ~1024px + lateral padding)
77
+ - `profile` defaults to **`default`** (primary-tinted decorative shapes)
78
+ - `hideShapes` defaults to **`false`**
79
+
80
+ Props and slots: use Joy MCP (`joy_get_component_info`, `joy_get_component_types`) or Storybook — this page focuses on **when** and **how**, not a full API dump.
81
+
82
+ ### Scroll and stepper labels
83
+
84
+ `VJoyFunnel` provides `VJoyStepperShowLabels` to child `VJoyStepper` instances. When a stepper is present and the user scrolls the content **away from the top**, step labels collapse to save vertical space; scrolling back to the top restores labels. This is automatic — do not reimplement it in product code.
85
+
86
+ ### Exposed members
87
+
88
+ - `scrollOnTop` — whether the scrollable region is at the top
89
+ - `hasStepperSlot` — whether `funnel-stepper` is filled
90
+ - `hasFooterSlot` — whether the deprecated `funnel-footer` slot has content (affects shape vertical offset)
91
+
92
+ ---
93
+
94
+ ## Variants
95
+
96
+ Funnels don’t have button-style color variants. Choose **`profile`** by product context — it only affects decorative shape colors.
97
+
98
+ ### Default (`profile="default"`)
99
+
100
+ Primary palette shapes (`--joy-color-primary-10` through `-70`). Use for standard product onboarding and general multi-step flows.
101
+
102
+ Avoid when design has explicitly approved the strategy palette for this surface.
103
+
104
+ ### Strategy (`profile="strategy"`)
105
+
106
+ Tertiary palette shapes (`--joy-color-tertiary-10` through `-70`). Use for strategy-specific onboarding or flows approved by design for that brand moment.
107
+
108
+ Avoid on generic product funnels without design sign-off.
109
+
110
+ ---
111
+
112
+ ## Sizes
113
+
114
+ Choose **`layoutWidth`** for content density — widths come from funnel CSS variables, not hardcoded pixel max-widths in apps.
115
+
116
+ | `layoutWidth` | Use when |
117
+ | --- | --- |
118
+ | `large` (default) | Standard funnels with panels, forms, or optional sidebar (`~1024px` content + lateral padding) |
119
+ | `medium` | Narrower copy-heavy or single-column steps (`~672px` content + lateral padding) |
120
+
121
+ The stepper row follows the same width constraint as the content (`joy-funnel__stepper--medium` when `layoutWidth="medium"`).
122
+
123
+ **MUST NOT** override `--funnel-content-width-large`, `--funnel-content-width-medium`, or `--funnel-content-lateral-padding` in product CSS unless design approves a new layout token.
124
+
125
+ ---
126
+
127
+ ## States
128
+
129
+ | State | What the user sees / can do |
130
+ | --- | --- |
131
+ | Default (scroll at top) | Full stepper labels (when stepper present); header visible with elevation |
132
+ | Scrolled | Content scrolls inside the funnel; stepper labels hide when stepper is present |
133
+ | No stepper | `joy-funnel--no-stepper` — stepper region not rendered |
134
+ | Shapes hidden (`hideShapes`) | No decorative shapes (e.g. dense mobile, admin previews, Storybook demos) |
135
+ | Shapes visible | Decorative shapes bottom-right; auto-hidden on viewports ≤ 1420px |
136
+ | With footer in main | `VJoyFunnelFooter` at bottom of scrollable content; stacks vertically on narrow screens (≤ 479px) |
137
+
138
+ `VJoyFunnel` is a layout shell — loading, validation, and disabled states belong on child components (`VJoyTemplate` `loading`, form fields, `VJoyButton` `loading`, etc.).
139
+
140
+ ---
141
+
142
+ ## Best practices
143
+
144
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
145
+
146
+ ### Structure
147
+
148
+ - **MUST** put step content in the **default slot** via `VJoyTemplate` — don’t bypass the template for arbitrary div layouts.
149
+ - **MUST** place **`VJoyFunnelFooter`** inside `template-main` (after main panels), not in the deprecated `funnel-footer` slot.
150
+ - **SHOULD** use **`VJoyFunnelHeader`** in `funnel-header` for logo and dismiss / help actions.
151
+ - **SHOULD** add **`VJoyStepper`** in `funnel-stepper` when the flow has three or more named steps users must track.
152
+ - **SHOULD** use `layoutWidth="medium"` for short copy-only steps; `large` when forms, panels, or sidebars need room.
153
+
154
+ ### Implementation
155
+
156
+ - **MUST** use only `profile` and `layoutWidth` values from MCP or `JoyFunnel.types.ts` (`default` | `strategy`; `medium` | `large`).
157
+ - **MUST** style with Joy tokens — no custom `.joy-funnel` chrome (background, z-index, fixed positioning).
158
+ - **MUST NOT** invent props (`variant`, `size`, custom width props, etc.).
159
+ - **MUST NOT** nest another full-screen fixed layout inside the funnel content.
160
+ - **SHOULD** set `hideShapes` when decorative shapes would clash with dense illustrations or brand-specific art direction.
161
+
162
+ ### Navigation
163
+
164
+ - **SHOULD** wire Previous / Next in `VJoyFunnelFooter` with `VJoyButton` (`secondary` + `main`, `size="small"` per Storybook).
165
+ - **SHOULD** provide a labeled close control in the header (`VJoyIconButton` with `label`, e.g. `"Close funnel"`) when users can exit without finishing.
166
+ - **MUST** follow `VJoyButton` content rules for footer labels — see Button guidelines for funnel-specific `Next` / `Previous` vs destination naming.
167
+
168
+ ### Do / don’t
169
+
170
+ | Do | Don’t |
171
+ | --- | --- |
172
+ | `VJoyTemplate` + `VJoyFunnelFooter` in `template-main` | Deprecated `funnel-footer` slot |
173
+ | `VJoyFunnelHeader` in `funnel-header` | Legacy `VJoyHeader` in new funnels |
174
+ | `hideShapes` for shape-free surfaces | Custom shape markup in app code |
175
+ | `layoutWidth` for density | Hardcoded `max-width: 1024px` on wrappers |
176
+ | Let funnel handle stepper label collapse on scroll | Manual show/hide of step labels |
177
+
178
+ ---
179
+
180
+ ## Accessibility
181
+
182
+ Behaviors (what must happen), not slogans.
183
+
184
+ | Behavior | Expectation |
185
+ | --- | --- |
186
+ | Landmark structure | Header content in `funnel-header` should use semantic `<header>` (`VJoyFunnelHeader` provides this); main content in `VJoyTemplate` should use proper headings (`h1` for step title) |
187
+ | Focus order | Tab order follows visual order: header actions → stepper (if interactive) → main content → footer buttons |
188
+ | Page takeover | Funnel covers the viewport — ensure route change or close action returns focus sensibly (e.g. to the element that opened the funnel) |
189
+ | Close / exit | Icon-only close **MUST** have an accessible name (`label` on `VJoyIconButton`) |
190
+ | Stepper | Progress is visual; pair with clear step titles and don’t rely on color alone for current step — `VJoyStepper` manages step states |
191
+ | Scrolling | Main content scrolls inside the funnel; don’t trap keyboard users — interactive elements in the scroll region remain reachable |
192
+ | Decorative shapes | Purely decorative — no information conveyed by shapes alone |
193
+
194
+ Target: **WCAG 2.2 AA** where the product requires it.
195
+
196
+ ---
197
+
198
+ ## Examples
199
+
200
+ ```vue
201
+ <script setup lang="ts">
202
+ import {
203
+ VJoyFunnel,
204
+ VJoyFunnelHeader,
205
+ VJoyFunnelFooter,
206
+ VJoyTemplate,
207
+ VJoyPanel,
208
+ VJoyStepper,
209
+ VJoyStep,
210
+ VJoyButton,
211
+ VJoyIconButton,
212
+ } from '@maltjoy/core-vue'
213
+ </script>
214
+
215
+ <template>
216
+ <VJoyFunnel layout-width="large" profile="default">
217
+ <template #funnel-header>
218
+ <VJoyFunnelHeader>
219
+ <template #funnel-header-left>
220
+ <img src="/logo.svg" alt="Malt" height="36" />
221
+ </template>
222
+ <template #funnel-header-right>
223
+ <VJoyIconButton label="Close funnel" icon="cross" size="small" variant="ghost" />
224
+ </template>
225
+ </VJoyFunnelHeader>
226
+ </template>
227
+
228
+ <template #funnel-stepper>
229
+ <VJoyStepper :step="2" :sub-step="1">
230
+ <VJoyStep>Account</VJoyStep>
231
+ <VJoyStep>Profile</VJoyStep>
232
+ <VJoyStep>Review</VJoyStep>
233
+ </VJoyStepper>
234
+ </template>
235
+
236
+ <VJoyTemplate>
237
+ <template #template-title>
238
+ <h1>Complete your profile</h1>
239
+ </template>
240
+ <template #template-subtitle>
241
+ Tell clients who you are and what you do.
242
+ </template>
243
+ <template #template-main>
244
+ <VJoyPanel>
245
+ <template #panel-body>
246
+ <!-- Step form fields -->
247
+ </template>
248
+ </VJoyPanel>
249
+
250
+ <VJoyFunnelFooter>
251
+ <template #footer-left>
252
+ <VJoyButton label="Previous" size="small" variant="secondary" />
253
+ </template>
254
+ <template #footer-right>
255
+ <VJoyButton label="Next" size="small" variant="main" />
256
+ </template>
257
+ </VJoyFunnelFooter>
258
+ </template>
259
+ </VJoyTemplate>
260
+ </VJoyFunnel>
261
+ </template>
262
+ ```
263
+
264
+ Narrower step without stepper:
265
+
266
+ ```vue
267
+ <VJoyFunnel layout-width="medium" hide-shapes>
268
+ <VJoyTemplate>
269
+ <template #template-title><h1>Welcome</h1></template>
270
+ <template #template-main>
271
+ <!-- … -->
272
+ </template>
273
+ </VJoyTemplate>
274
+ </VJoyFunnel>
275
+ ```
276
+
277
+ In Nuxt (or apps with auto-import), omit the import if components are already global.
278
+
279
+ ---
280
+
281
+ ## Related
282
+
283
+ | Component | Use when |
284
+ | --- | --- |
285
+ | `VJoyFunnelHeader` | Branded bar in `funnel-header` (logo, close, help) |
286
+ | `VJoyFunnelFooter` | Previous / Next (or other) actions at the bottom of a step |
287
+ | `VJoyTemplate` | Structured title, subtitle, main, optional sidebar inside the funnel |
288
+ | `VJoyStepper` / `VJoyStep` | Progress across steps in `funnel-stepper` |
289
+ | `VJoyPanel` | Card-style body content for a step |
290
+ | `VJoyButton` | Footer navigation and header actions |
291
+ | `VJoyDialog` | Confirm exit or destructive actions without leaving the funnel shell |
292
+
293
+ ---
294
+
295
+ ## For agents
296
+
297
+ Optional for readers; **required** for vibe-coding quality. Maps to `agentDocumentBlocks` in [`JoyFunnel.dsds.json`](./JoyFunnel.dsds.json).
298
+
299
+ ### Pick the right component
300
+
301
+ | If the intent is… | Emit… | Do not emit… |
302
+ | --- | --- | --- |
303
+ | Full-page multi-step flow | `VJoyFunnel` + `VJoyTemplate` | `VJoyTemplate` alone with custom `position: fixed` |
304
+ | Modal confirm on current page | `VJoyDialog` | `VJoyFunnel` for a single question |
305
+ | Progress across steps | `VJoyStepper` in `#funnel-stepper` | Custom progress dots |
306
+ | Step footer actions | `VJoyFunnelFooter` in `template-main` | `#funnel-footer` slot |
307
+ | Funnel top bar | `VJoyFunnelHeader` in `#funnel-header` | `VJoyHeader` or raw `<header>` |
308
+ | Strategy-branded onboarding | `profile="strategy"` | Custom tertiary shape CSS |
309
+
310
+ ### Hard rules
311
+
312
+ 1. **MUST** call `joy_get_component_info("VJoyFunnel")` or read `JoyFunnel.types.ts` before generating props.
313
+ 2. **MUST** compose default slot with `VJoyTemplate`; put `VJoyFunnelFooter` inside `template-main`.
314
+ 3. **MUST** use `profile` values `default` | `strategy` and `layoutWidth` values `medium` | `large` only.
315
+ 4. **MUST NOT** use the `funnel-footer` slot — deprecated.
316
+ 5. **MUST NOT** emit `VJoyHeader` — use `VJoyFunnelHeader`.
317
+ 6. **MUST NOT** override `.joy-funnel` positioning, z-index, background, or content width tokens.
318
+ 7. **SHOULD** set `hideShapes` when shapes are not wanted; don’t delete shape markup in apps.
319
+ 8. **SHOULD** use `VJoyButton` `size="small"` in funnel footers (Storybook convention).
320
+
321
+ ### Checklist
322
+
323
+ - [ ] Correct shell (`VJoyFunnel` vs dialog / drawer / plain template)
324
+ - [ ] `VJoyTemplate` in default slot
325
+ - [ ] `VJoyFunnelFooter` in `template-main` (not `funnel-footer` slot)
326
+ - [ ] `VJoyFunnelHeader` in `funnel-header` when a header is needed
327
+ - [ ] Props / enums from MCP or types only
328
+ - [ ] No invented props / no custom funnel chrome CSS
329
+ - [ ] Close control has accessible `label`
330
+ - [ ] Stepper in `funnel-stepper` when flow has multiple tracked steps
331
+
332
+ ---
333
+
334
+ ## DSDS mapping
335
+
336
+ This Markdown mirrors [`JoyFunnel.dsds.json`](./JoyFunnel.dsds.json) (DSDS **0.15.2**).
337
+
338
+ | Section here | DSDS block |
339
+ | --- | --- |
340
+ | When to use / not | `use-cases` |
341
+ | Anatomy / composition | `anatomy` |
342
+ | Profiles / layout widths | `variants` |
343
+ | Scroll / layout states | `states` |
344
+ | Best practices | `guidelines` |
345
+ | Accessibility | `accessibility` |
346
+ | Examples | `sections` |
347
+ | For agents | `agentDocumentBlocks` |
348
+ | Props detail | `api` in JSON + Joy MCP |
349
+ | Content widths / tokens | `design-specifications` in JSON (`--funnel-content-width-*`, `--funnel-content-lateral-padding`) |
@@ -0,0 +1,178 @@
1
+ ---
2
+ component: VJoyFunnelFooter
3
+ status: draft
4
+ language: en
5
+ dsds: JoyFunnelFooter.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Funnel footer
10
+
11
+ Use **`VJoyFunnelFooter`** at the bottom of a funnel step to lay out **back / secondary actions on the left** and **forward / primary actions on the right** — typically Previous and Next buttons in a multi-step onboarding or wizard flow.
12
+
13
+ It is a presentational layout shell: no props, two named slots, responsive stacking on narrow viewports, and a semantic `<footer>` landmark. Place it inside `VJoyTemplate`’s `#template-main`, after step content (for example a `VJoyPanel`).
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyFunnelFooter` from `@maltjoy/core-vue` |
18
+ | **Design** | [Figma — Joy Core Design System](https://www.figma.com/design/jfndp2QBJGS9yeuWbeGuvD/) |
19
+ | **Storybook** | [VJoyFunnel docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-layout-vjoyfunnel--docs) (footer shown in funnel examples) |
20
+ | **DSDS (machine)** | [`JoyFunnelFooter.dsds.json`](./JoyFunnelFooter.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyFunnelFooter")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use a funnel footer when a **`VJoyFunnel`** step needs persistent navigation actions at the bottom of the main content area — for example **Previous** / **Next** in an onboarding flow, or a secondary escape action paired with a primary continue button.
28
+
29
+ The component handles horizontal alignment on desktop (left vs right groups) and stacks actions full-width on mobile (`≤ 479px`). Put step body content above it in the same `#template-main` block.
30
+
31
+ ### When not to use this component
32
+
33
+ | Need | Use instead |
34
+ | --- | --- |
35
+ | Actions tied to a single card or panel only | `VJoyPanel` `#panel-action` footer slot |
36
+ | Sticky actions visible while scrolling any long page | `VJoyFloatingActionsBar` |
37
+ | Full funnel page chrome (header, stepper, shapes) | `VJoyFunnel` + `VJoyFunnelHeader` — not this component alone |
38
+ | A generic page footer outside a funnel | App shell / page layout patterns |
39
+ | Custom flex footer with ad-hoc CSS | Still use `VJoyFunnelFooter` + Joy tokens |
40
+
41
+ > **Deprecated:** do not use the `#funnel-footer` slot on `VJoyFunnel` or the legacy `VJoyFooter` sub-component. Render `VJoyFunnelFooter` directly in `#template-main` (Joy v4+).
42
+
43
+ ---
44
+
45
+ ## How it works
46
+
47
+ `VJoyFunnelFooter` renders a `<footer>` with two flex regions. Slot content is entirely yours — usually `VJoyButton` instances. Spacing and responsive layout are built in; there are **no props or events**.
48
+
49
+ ### Anatomy
50
+
51
+ | Part | Required? | What it is |
52
+ | --- | --- | --- |
53
+ | Root `<footer>` | Yes | `.joy-funnel-footer` — full-width flex row with top margin |
54
+ | Left region | No | `#footer-left` — start-aligned group (often back / secondary) |
55
+ | Right region | No | `#footer-right` — end-aligned flex row with gap between children (often primary / next) |
56
+
57
+ ### Default values
58
+
59
+ - **No props** — layout is fixed; customize only via slot content.
60
+ - **Slots:** `footer-left`, `footer-right` (both optional, but at least one should carry the step actions).
61
+ - **Top margin:** `var(--joy-core-spacing-8)` — may collapse with bottom margin on a preceding `VJoyPanel`.
62
+ - **Right group gap:** `var(--joy-core-spacing-8)` between direct children.
63
+ - **Mobile (`≤ 479px`):** column layout, `row-gap: var(--joy-core-spacing-2)`, children stretched to **100% width**.
64
+
65
+ Props, events, and slots: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
66
+
67
+ ---
68
+
69
+ ## Best practices
70
+
71
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
72
+
73
+ ### Placement / composition
74
+
75
+ - **MUST** place `VJoyFunnelFooter` inside **`VJoyTemplate` `#template-main`**, at the **bottom** of the step content, within a `VJoyFunnel` flow.
76
+ - **MUST NOT** use the deprecated **`#funnel-footer`** slot on `VJoyFunnel`.
77
+ - **SHOULD** put **back / secondary** actions in `#footer-left` and **forward / primary** actions in `#footer-right` (matches Storybook and product funnels).
78
+ - **SHOULD** use **`VJoyButton`** with `size="small"` for funnel navigation unless design specifies otherwise.
79
+ - **MAY** put multiple buttons in `#footer-right`; the built-in gap handles spacing.
80
+ - **SHOULD** leave `#footer-left` empty when there is no back action on the first step — do not add a disabled placeholder button.
81
+
82
+ ### Implementation
83
+
84
+ - **MUST NOT** invent props — the component exposes **none**.
85
+ - **MUST** use Joy tokens — **no** custom `.joy-funnel-footer` layout overrides in product CSS.
86
+ - **MUST NOT** rely on this component for sticky viewport positioning; it flows with page content inside the funnel.
87
+
88
+ ### Do / don’t
89
+
90
+ | Do | Don’t |
91
+ | --- | --- |
92
+ | Previous in `footer-left`, Next in `footer-right` | Both primary actions crammed into one slot without reason |
93
+ | Place after `VJoyPanel` (or step body) in `#template-main` | Use `#funnel-footer` on `VJoyFunnel` |
94
+ | Empty `footer-left` on the first step | Disabled “Previous” as filler |
95
+ | `VJoyButton` with clear labels | Icon-only buttons without accessible names |
96
+ | Let mobile full-width stacking handle narrow screens | Custom media queries duplicating the footer layout |
97
+
98
+ ---
99
+
100
+ ## Accessibility
101
+
102
+ Behaviors (what must happen), not slogans.
103
+
104
+ | Behavior | Expectation |
105
+ | --- | --- |
106
+ | Landmark | Renders a native **`<footer>`** — useful for structure inside the funnel main area |
107
+ | Interactive controls | **No built-in buttons** — every control in slots **must** have an accessible name (`label` on `VJoyButton`, etc.) |
108
+ | Order | On mobile, **`footer-left` renders above `footer-right`** — keep logical tab order (e.g. Previous before Next) |
109
+ | Keyboard | Focus order follows DOM order in the slots; use real buttons/links, not `div` click handlers |
110
+ | Disabled steps | Disable or omit the control — don’t rely on color alone to show unavailable actions |
111
+
112
+ Target: **WCAG 2.2 AA** where the product requires it.
113
+
114
+ ---
115
+
116
+ ## Examples
117
+
118
+ ```vue
119
+ <script setup lang="ts">
120
+ import {
121
+ VJoyFunnel,
122
+ VJoyTemplate,
123
+ VJoyPanel,
124
+ VJoyFunnelFooter,
125
+ VJoyButton,
126
+ } from '@maltjoy/core-vue'
127
+ </script>
128
+
129
+ <template>
130
+ <VJoyFunnel>
131
+ <VJoyTemplate>
132
+ <template #template-main>
133
+ <VJoyPanel>
134
+ <template #panel-body>
135
+ <!-- Step content -->
136
+ </template>
137
+ </VJoyPanel>
138
+
139
+ <VJoyFunnelFooter>
140
+ <template #footer-left>
141
+ <VJoyButton label="Previous" size="small" variant="secondary" />
142
+ </template>
143
+ <template #footer-right>
144
+ <VJoyButton label="Next" size="small" variant="main" />
145
+ </template>
146
+ </VJoyFunnelFooter>
147
+ </template>
148
+ </VJoyTemplate>
149
+ </VJoyFunnel>
150
+ </template>
151
+ ```
152
+
153
+ First step (no back action):
154
+
155
+ ```vue
156
+ <VJoyFunnelFooter>
157
+ <template #footer-right>
158
+ <VJoyButton label="Get started" size="small" variant="main" />
159
+ </template>
160
+ </VJoyFunnelFooter>
161
+ ```
162
+
163
+ In Nuxt (or apps with auto-import), omit the import if `VJoyFunnelFooter` is already global.
164
+
165
+ ---
166
+
167
+ ## Related
168
+
169
+ | Component | Use when |
170
+ | --- | --- |
171
+ | `VJoyFunnel` | Full-page funnel layout (header, stepper, main area) |
172
+ | `VJoyFunnelHeader` | Funnel top bar (logo, close, etc.) |
173
+ | `VJoyTemplate` | Title, subtitle, and `#template-main` where the footer lives |
174
+ | `VJoyPanel` | Card-style body content above the footer |
175
+ | `VJoyButton` | Typical Previous / Next / Submit actions in footer slots |
176
+ | `VJoyStepper` | Multi-step progress in `#funnel-stepper` |
177
+ | `VJoyPanel` `#panel-action` | Footer actions scoped to one panel, not the whole funnel step |
178
+ | `VJoyFloatingActionsBar` | Viewport-sticky bulk or primary actions on long scrollable pages |