@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,268 @@
1
+ ---
2
+ component: VJoyUserCard
3
+ status: draft
4
+ language: en
5
+ dsds: JoyUserCard.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # User Card
10
+
11
+ Use **`VJoyUserCard`** when you need a compact, horizontal identity block — avatar, name, subtitle, and optional metadata (rating, badges) — in lists, side panels, activity feeds, or search results.
12
+
13
+ Set `link` to make the whole card navigate as a native `<a>`; pass `target`, `rel`, and other link attributes on the component (they inherit via `$attrs`). Customize avatar, title, subtitle, or trailing content through slots when props are not enough.
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyUserCard` from `@maltjoy/core-vue` |
18
+ | **Design** | [ZeroHeight — User Card](https://zeroheight.com/6bf479565/p/8408347-user-card) |
19
+ | **Storybook** | [VJoyUserCard docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-view-vjoyusercard--docs) |
20
+ | **DSDS (machine)** | [`JoyUserCard.dsds.json`](./JoyUserCard.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyUserCard")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use a user card when someone must **recognize a person or entity at a glance** in a dense layout — for example a freelancer in search results, a participant in a conversation header, a project member row, or a sourcing snippet with rating and level badges.
28
+
29
+ Prefer props (`fullName`, `subTitle`, `photoUrl`) for the default case. Reach for slots when you need a custom avatar size, formatted title, or extra rows (`VJoyRatingStars`, `VJoyBadgeLevel`, availability, tags).
30
+
31
+ ### When not to use this component
32
+
33
+ | Need | Use instead |
34
+ | --- | --- |
35
+ | Only a profile picture / initials | `VJoyAvatar` |
36
+ | A generic interactive list row (icon + title + actions) | `VJoyListItem` |
37
+ | A large profile hero or full profile page layout | Page template / custom layout — not `VJoyUserCard` |
38
+ | A complex clickable card with arbitrary CTA layout | `VJoyButtonCard` |
39
+ | Inline name inside body copy | `VJoyLink` or plain text |
40
+ | Custom markup / ad-hoc flex row for the same job | Still use `VJoyUserCard` + Joy tokens |
41
+
42
+ > **Deprecated:** do not use the `user-card-rating-stars` slot on new work — put `VJoyRatingStars` (and other metadata) in the **default** slot instead. The slot remains for backward compatibility only.
43
+
44
+ > **Not in the Vue API:** legacy Stencil props `ratingValue` and `newTab`, and the `user-card-free-slot` slot name. **`VJoyUserCard` has no `ratingValue` prop** — compose `VJoyRatingStars` in the default slot. For a new tab, set `link` and pass `target="_blank"` (and `rel="noopener noreferrer"` when appropriate) as attributes.
45
+
46
+ > **Not in the API:** ZeroHeight “Profile card” **Portrait** / **Landscape** types are layout patterns in design docs. The component implements a **single horizontal layout** (avatar left, text stack right). Do not invent `variant="portrait"` or `variant="landscape"`.
47
+
48
+ ---
49
+
50
+ ## How it works
51
+
52
+ ### Anatomy
53
+
54
+ | Part | Required? | What it is |
55
+ | --- | --- | --- |
56
+ | Root container | Yes | `<div class="joy-user-card">`, or `<a class="joy-user-card">` when `link` is set |
57
+ | Picture | Yes | `.joy-user-card__picture` — default `VJoyAvatar` or `user-card-avatar` slot |
58
+ | Informations | Yes | `.joy-user-card__informations` — title, subtitle, and optional extra content |
59
+ | Title | Yes* | `.joy-user-card__title` — `fullName` prop or `user-card-title` slot |
60
+ | Subtitle | No | `.joy-user-card__subtitle` — `subTitle` prop or `user-card-subtitle` slot (`joy-font-primary-450`) |
61
+ | Default slot | No | Free content below subtitle (rating, badges, tags, links) |
62
+ | `title` attribute | No | On link roots, set from `fullName` for native tooltip on hover |
63
+
64
+ \*Provide at least a title (prop or slot) so the card is meaningful. Avatar initials also use `fullName` when no photo is available.
65
+
66
+ ### Layout and tokens
67
+
68
+ - **Layout** — `inline-flex`, avatar and text aligned to the start; fixed horizontal pattern (no `size` or `variant` prop on the card).
69
+ - **Typography** — `--user-card-font-size` (default `var(--joy-font-size-primary-400)`); title uses bold weight and `--user-card-title-color`.
70
+ - **Body text** — `--user-card-text-color` (default neutral-60).
71
+ - **Links inside the card** — nested `<a>` elements use `--user-card-links-color` and underline on hover/focus.
72
+ - **Link card** — when the root is `<a>`, the title is underlined and uses link colors; root has opacity transition on hover.
73
+
74
+ Avatar **size** is controlled via `user-card-avatar` (e.g. `VJoyAvatar` `size="small"`) — not a prop on `VJoyUserCard`.
75
+
76
+ ### Default values
77
+
78
+ All props are optional strings with no component defaults — supply the data your surface needs.
79
+
80
+ Props, slots, and attribute inheritance: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
81
+
82
+ ---
83
+
84
+ ## States
85
+
86
+ | State | What the user sees / can do |
87
+ | --- | --- |
88
+ | Default (static) | Root is a `<div>`; informational display only |
89
+ | Default (link) | Root is `<a href="…">`; entire card is one navigation target |
90
+ | Hover (link card) | Root opacity transition; title color shifts to link hover token |
91
+ | Hover / focus (nested links) | Links inside `.joy-user-card__informations` underline and change color |
92
+ | Focus (link card) | Native link focus on the root; title styling follows link focus token |
93
+ | Custom slot content | Rating, badges, or extra lines in the default slot — keep supplementary, not the only way to convey the name |
94
+
95
+ There is no `disabled` or `loading` state on the card itself. If navigation must be blocked, omit `link` or handle it in the parent (and explain why nearby).
96
+
97
+ ---
98
+
99
+ ## Best practices
100
+
101
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
102
+
103
+ ### When to link the whole card
104
+
105
+ - **SHOULD** set `link` when the **primary action** is “open this person’s profile” (or equivalent destination).
106
+ - **SHOULD** pass `target` and `rel` as native attributes when opening externally (`target="_blank"` + `rel="noopener noreferrer"`).
107
+ - **MUST NOT** nest interactive controls that compete with the card link inside a linked card without stopping propagation — prefer static card + explicit button, or link only the title.
108
+ - **SHOULD** use a single clear destination per card — not multiple conflicting click targets.
109
+
110
+ ### Implementation
111
+
112
+ - **MUST** use only documented props: `link`, `photoUrl`, `fullName`, `subTitle`.
113
+ - **MUST** put `VJoyRatingStars`, `VJoyBadgeLevel`, and similar metadata in the **default** slot (not deprecated `user-card-rating-stars`).
114
+ - **MUST** style with Joy tokens / CSS variables (`--user-card-*`) — no custom `.joy-user-card` chrome in product CSS.
115
+ - **MUST NOT** invent props (`ratingValue`, `newTab`, `variant`, `size`, …).
116
+ - **SHOULD** prefer props for plain string title/subtitle; use slots for formatting, components, or i18n wrappers.
117
+ - **SHOULD** wrap multiple default-slot items in `VJoyWrapper` with tight gaps (see Storybook `CustomSlot`).
118
+
119
+ ### Do / don’t
120
+
121
+ | Do | Don’t |
122
+ | --- | --- |
123
+ | `fullName` + `photoUrl` for standard rows | Rebuild avatar + two `<p>` tags with custom CSS |
124
+ | Default slot for rating / badges | Deprecated `user-card-rating-stars` slot |
125
+ | `target="_blank"` as an attribute on the card | `newTab` prop (Stencil only) |
126
+ | `VJoyAvatar` in `user-card-avatar` when size differs | Hardcoded avatar dimensions on `.joy-user-card__picture` |
127
+ | One profile link via `link` | Whole card linked plus unrelated buttons inside |
128
+
129
+ ---
130
+
131
+ ## Accessibility
132
+
133
+ Behaviors (what must happen), not slogans.
134
+
135
+ | Behavior | Expectation |
136
+ | --- | --- |
137
+ | Role | Static card → non-interactive container; with `link` → native `<a href>` (not a clickable `<div>`) |
138
+ | Name | Title text (`fullName` / slot) is the primary visible identifier; avatar image uses `fullName` as `alt` via `VJoyAvatar` |
139
+ | Link card | Root `<a>` must have meaningful link text — the title (and not image alone) should identify the destination |
140
+ | `title` attribute | Set on link root from `fullName` — supplementary only; do not rely on it as the accessible name |
141
+ | Nested links | Allowed in the informations block; avoid duplicate or confusing destinations |
142
+ | Keyboard | Link cards follow native link keyboard behavior (**Enter** activates) |
143
+ | Focus | Preserve visible focus styles on link roots and nested links — do not remove outlines in product CSS |
144
+
145
+ Target: **WCAG 2.2 AA** where the product requires it.
146
+
147
+ ---
148
+
149
+ ## Examples
150
+
151
+ ```vue
152
+ <script setup lang="ts">
153
+ import {
154
+ VJoyUserCard,
155
+ VJoyAvatar,
156
+ VJoyRatingStars,
157
+ VJoyBadgeLevel,
158
+ VJoyWrapper,
159
+ } from '@maltjoy/core-vue'
160
+ </script>
161
+
162
+ <template>
163
+ <!-- Standard identity row -->
164
+ <VJoyUserCard
165
+ full-name="Leslie Nielsen"
166
+ sub-title="Actor"
167
+ photo-url="https://example.com/photo.jpg"
168
+ />
169
+
170
+ <!-- Whole card navigates — attrs pass through to <a> -->
171
+ <VJoyUserCard
172
+ link="https://www.malt.com/profile/123"
173
+ full-name="Leslie Nielsen"
174
+ sub-title="Actor"
175
+ photo-url="https://example.com/photo.jpg"
176
+ target="_blank"
177
+ rel="noopener noreferrer"
178
+ />
179
+
180
+ <!-- Rating + badge in default slot -->
181
+ <VJoyUserCard full-name="Leslie Nielsen" sub-title="Actor">
182
+ <VJoyWrapper :no-margin="true" column-gap="2" row-gap="2">
183
+ <VJoyRatingStars :rating-value="5" />
184
+ <VJoyBadgeLevel level="level-2" type="supermalter" />
185
+ </VJoyWrapper>
186
+ </VJoyUserCard>
187
+
188
+ <!-- Custom avatar size via slot -->
189
+ <VJoyUserCard full-name="Leslie Nielsen" sub-title="Actor">
190
+ <template #user-card-avatar>
191
+ <VJoyAvatar size="small" full-name="Leslie Nielsen" photo-url="https://example.com/photo.jpg" />
192
+ </template>
193
+ </VJoyUserCard>
194
+ </template>
195
+ ```
196
+
197
+ In Nuxt (or apps with auto-import), omit the import if `VJoyUserCard` is already global.
198
+
199
+ ---
200
+
201
+ ## Related
202
+
203
+ | Component | Use when |
204
+ | --- | --- |
205
+ | `VJoyAvatar` | Avatar only, or custom avatar inside `user-card-avatar` |
206
+ | `VJoyRatingStars` | Star rating in the default slot |
207
+ | `VJoyBadgeLevel` | SuperMalter / verification badges below the name |
208
+ | `VJoyWrapper` | Layout and spacing for multiple default-slot children |
209
+ | `VJoyListItem` | Generic list rows with actions, not identity-focused cards |
210
+ | `VJoyLink` | Inline text navigation inside copy |
211
+ | `VJoyAvatarsList` | Stacked/overlapping avatar groups without name stack |
212
+
213
+ ---
214
+
215
+ ## For agents
216
+
217
+ Optional for readers; **required** for vibe-coding quality. Maps to `agentDocumentBlocks` in [`JoyUserCard.dsds.json`](./JoyUserCard.dsds.json).
218
+
219
+ ### Pick the right component
220
+
221
+ | If the intent is… | Emit… | Do not emit… |
222
+ | --- | --- | --- |
223
+ | Avatar + name + subtitle (+ optional metadata) | `VJoyUserCard` | Custom flex row + raw `<img>` |
224
+ | Profile picture only | `VJoyAvatar` | `VJoyUserCard` without text |
225
+ | Clickable profile in search / list | `VJoyUserCard` + `link` | `<div @click>` router navigation |
226
+ | Rating or level under the name | `VJoyRatingStars` / `VJoyBadgeLevel` in **default** slot | `ratingValue` prop or `user-card-rating-stars` |
227
+ | Open profile in new tab | `link` + `target="_blank"` + `rel="noopener noreferrer"` | `newTab` prop |
228
+ | Rich interactive card layout | `VJoyButtonCard` | `VJoyUserCard` with heavy custom CSS |
229
+
230
+ ### Hard rules
231
+
232
+ 1. **MUST** call `joy_get_component_info("VJoyUserCard")` (or read `VJoyUserCard.vue`) before generating props.
233
+ 2. **MUST** use only props: `link`, `photoUrl`, `fullName`, `subTitle`.
234
+ 3. **MUST** pass native link attributes (`target`, `rel`, …) as HTML attributes on `VJoyUserCard`, not as invented props.
235
+ 4. **MUST** place `VJoyRatingStars` and extra metadata in the **default** slot.
236
+ 5. **MUST NOT** use `ratingValue`, `newTab`, `variant`, or `size` on `VJoyUserCard`.
237
+ 6. **MUST NOT** use deprecated `user-card-rating-stars` in new code.
238
+ 7. **MUST NOT** override `.joy-user-card` layout, font-size, or colors with hardcoded app CSS — use `--user-card-*` tokens if needed.
239
+ 8. **SHOULD** set `fullName` whenever `photoUrl` may be missing (initials fallback on avatar).
240
+ 9. **SHOULD** use `user-card-avatar` only when `VJoyAvatar` needs non-default `size` or behavior.
241
+
242
+ ### Checklist
243
+
244
+ - [ ] Correct component (`VJoyUserCard` or named alternative)
245
+ - [ ] Props from MCP / source only (`link`, `photoUrl`, `fullName`, `subTitle`)
246
+ - [ ] Rating / badges in default slot — not `ratingValue` or deprecated rating slot
247
+ - [ ] `target` / `rel` as attributes when `link` opens a new tab
248
+ - [ ] No invented props / no custom `.joy-user-card` chrome CSS
249
+ - [ ] Link card: one clear destination; nested links don’t conflict
250
+ - [ ] Title identifies the person or entity
251
+
252
+ ---
253
+
254
+ ## DSDS mapping
255
+
256
+ This Markdown mirrors [`JoyUserCard.dsds.json`](./JoyUserCard.dsds.json) (DSDS **0.15.2**).
257
+
258
+ | Section here | DSDS block |
259
+ | --- | --- |
260
+ | When to use / not | `use-cases` |
261
+ | Anatomy / layout | `anatomy` |
262
+ | States | `states` |
263
+ | Best practices | `guidelines` |
264
+ | Accessibility | `accessibility` |
265
+ | Examples | `sections` |
266
+ | For agents | `agentDocumentBlocks` |
267
+ | Props detail | `api` in JSON + Joy MCP |
268
+ | Token theming | `design-specifications` in JSON (`--user-card-*`) |
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "JoyUserCard",
3
3
  "displayName": "VJoyUserCard",
4
- "description": "A comprehensive user profile card component for displaying user information in a structured layout.\nFeatures integrated avatar display, name/subtitle presentation, rating stars support, and optional\nlink functionality for navigation. Includes multiple customization slots for avatar, title, subtitle,\nand rating components, with full attribute inheritance for link behavior and accessibility.",
4
+ "description": "A comprehensive user profile card component for displaying user information in a structured layout.\nFeatures integrated avatar display, name/subtitle presentation, rating stars support, and optional\nlink functionality for navigation. Includes multiple customization slots for avatar, title, subtitle,\nand free content through the default slot, with full attribute inheritance for link behavior and\naccessibility. The user-card-rating-stars slot is deprecated; use the default slot for custom\nrating stars or other free content instead.",
5
5
  "category": "View",
6
6
  "props": [
7
7
  {
@@ -31,15 +31,6 @@
31
31
  "string"
32
32
  ]
33
33
  },
34
- {
35
- "name": "ratingValue",
36
- "type": "number | undefined",
37
- "required": false,
38
- "description": "Introduce a VJoyRatingStars component with given rating",
39
- "possibleValues": [
40
- "number"
41
- ]
42
- },
43
34
  {
44
35
  "name": "subTitle",
45
36
  "type": "string | undefined",
@@ -54,7 +45,7 @@
54
45
  "slots": [
55
46
  {
56
47
  "name": "default",
57
- "description": ""
48
+ "description": "Free content displayed below the user information. Use this slot for custom content like VJoyRatingStars."
58
49
  },
59
50
  {
60
51
  "name": "user-card-avatar",
@@ -70,7 +61,7 @@
70
61
  },
71
62
  {
72
63
  "name": "user-card-rating-stars",
73
- "description": "Use your own customized VJoyRatingStars here, if needed"
64
+ "description": ""
74
65
  }
75
66
  ],
76
67
  "exposed": [
@@ -89,11 +80,6 @@
89
80
  "type": "string | undefined",
90
81
  "isMethod": false
91
82
  },
92
- {
93
- "name": "ratingValue",
94
- "type": "number | undefined",
95
- "isMethod": false
96
- },
97
83
  {
98
84
  "name": "subTitle",
99
85
  "type": "string | undefined",
@@ -0,0 +1,351 @@
1
+ ---
2
+ component: VJoyWalkthrough
3
+ status: draft
4
+ language: en
5
+ dsds: JoyWalkthrough.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Walkthrough
10
+
11
+ Use **`VJoyWalkthrough`** when you need a **persistent, collapsible onboarding panel** — for example a “Get started” checklist, profile-completion guidance, or multi-step help that stays available while the user explores the page.
12
+
13
+ It teleports to `body`, anchors to the bottom-right on desktop (full viewport on narrow screens), collapses to a floating trigger pill when closed, and exposes slots for illustration, titles, progress, and body content. Optional footer copy supports permanent dismiss (“don’t show again”).
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyWalkthrough` from `@maltjoy/core-vue` |
18
+ | **Design** | [ZeroHeight — Walkthrough](https://zeroheight.com/6bf479565/p/6305853-walkthrough) |
19
+ | **Storybook** | [VJoyWalkthrough docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-overlays-vjoywalkthrough--docs) |
20
+ | **DSDS (machine)** | [`JoyWalkthrough.dsds.json`](./JoyWalkthrough.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyWalkthrough")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use a walkthrough when onboarding or contextual help should remain **available without blocking the whole page** — the user can collapse the panel, keep working, and reopen it from the trigger.
28
+
29
+ Typical jobs: checklist-style onboarding, profile completion nudges, feature discovery with expandable steps, or resume flows where progress is shown in the trigger subtitle and/or a `walkthrough-progress` slot (often `VJoyProgressBar`).
30
+
31
+ Pair `triggerTitle` / `triggerSubtitle` / `triggerIcon` with slot content so both the collapsed pill and the expanded panel tell a coherent story.
32
+
33
+ ### When not to use this component
34
+
35
+ | Need | Use instead |
36
+ | --- | --- |
37
+ | Spotlight tour anchored to specific page elements | `VJoyProductTour` |
38
+ | Blocking confirmation or focused decision | `VJoyDialog` |
39
+ | Slide-in panel for filters, details, or long forms | `VJoyDrawer` |
40
+ | Brief transient feedback after an action | `pushVJoySnackbar` |
41
+ | Short hover/focus hint on a single control | `VJoyTooltip` |
42
+ | Full-page multi-step funnel | `VJoyFunnel` |
43
+ | Only the collapsed pill, no modal shell | `VJoyWalkthroughTrigger` (uncommon — see its guideline) |
44
+ | Custom fixed corner card with ad-hoc CSS | Still use `VJoyWalkthrough` + Joy tokens |
45
+
46
+ > **Docs only:** `disableTeleport` exists for Storybook previews. **Do not** set it in production — the component should teleport to `body` for correct z-index stacking (`--joy-core-z-index-walkthrough`).
47
+
48
+ ---
49
+
50
+ ## How it works
51
+
52
+ ### Open / collapse lifecycle
53
+
54
+ 1. **Collapsed (default)** — `open` is `false`; `VJoyWalkthroughTrigger` is shown (bottom-right on desktop, bottom-left fixed on mobile). Clicking the trigger opens the modal.
55
+ 2. **Open** — modal panel replaces the trigger. Header click runs a fade-out (~200 ms), then collapses and emits `hide` + `hide:header`.
56
+ 3. **Footer dismiss** — when `footer` is set, clicking the footer link collapses the panel and emits `hide` + `hide:footer` (use this path to persist “don’t show again”).
57
+ 4. **Controlled `open`** — bind `:open` and listen to `hide` / `hide:header` / `hide:footer` to sync app state (for example localStorage). Internal `isOpen` also syncs when `open` changes.
58
+
59
+ Fallthrough attributes (`id`, `data-*`, `aria-*`) on `VJoyWalkthrough` are applied to **`.joy-walkthrough-modal`** while the panel is open. Use **`triggerAttrs`** for attributes on the collapsed trigger button.
60
+
61
+ ### Anatomy
62
+
63
+ | Part | Required? | What it is |
64
+ | --- | --- | --- |
65
+ | Teleport host | Yes | Renders at `body` unless `disableTeleport` (docs only) |
66
+ | Root container | Yes | `.joy-walkthrough` — fixed positioning, z-index walkthrough token |
67
+ | Modal panel | Yes* | `.joy-walkthrough-modal` — white card, elevation-4, fade-in animation |
68
+ | Header | Yes* | Dark bar (`neutral-60`); shows `triggerIcon`, `triggerTitle`, chevron; click collapses |
69
+ | Illustration slot | No | `walkthrough-illustration` — leading visual (often `VJoyIcon`) |
70
+ | Title slot | No* | `walkthrough-title` — primary heading in content area |
71
+ | Subtitle slot | No | `walkthrough-subtitle` — supporting line under title |
72
+ | Progress slot | No | `walkthrough-progress` — e.g. `VJoyProgressBar` with label |
73
+ | Content slot | No | `walkthrough-content` — steps, lists, collapsible sections |
74
+ | Footer | No | Text link (`footer` prop) — permanent dismiss CTA |
75
+ | Trigger | Yes* | `VJoyWalkthroughTrigger` when collapsed |
76
+
77
+ \*Modal and header exist only while open; trigger exists only while collapsed. At least one of title slots or trigger copy should explain the panel’s purpose.
78
+
79
+ ### Default values
80
+
81
+ - `open` defaults to **`false`**
82
+ - `triggerTitle`, `triggerSubtitle`, `triggerIcon`, `footer`, and `triggerAttrs` are **optional**
83
+ - `disableTeleport` is **unset** (teleport enabled)
84
+
85
+ Props, events, slots, and exposed `isOpen`: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
86
+
87
+ ### Layout and tokens
88
+
89
+ - **Desktop** — fixed `bottom: 20px; right: 20px`; modal width `--walkthrough-width` (420px), max content height `--walkthrough-max-height` (420px), scrollable body.
90
+ - **Mobile / short viewport** — full width and height when `max-width: 500px` or `max-height: 600px`; trigger compacts (title hidden on narrow viewports — plan copy accordingly).
91
+ - **Do not** hardcode `420px` or z-index in apps — sizing and stacking come from Joy tokens inside `JoyWalkthrough.scss`.
92
+
93
+ ---
94
+
95
+ ## States
96
+
97
+ | State | What the user sees / can do |
98
+ | --- | --- |
99
+ | Collapsed (default) | Floating trigger pill with icon, title, optional subtitle, chevron-up; page remains fully usable |
100
+ | Opening | Trigger click sets `isOpen` true; modal fades in (~150 ms) |
101
+ | Open | Expanded panel over page; header shows chevron-down; content slots visible |
102
+ | Hiding | Header or footer click adds `joy-walkthrough-modal--hiding`; after ~200 ms panel unmounts and trigger returns |
103
+ | With progress | `walkthrough-progress` slot rendered below title block; often paired with `triggerSubtitle` |
104
+ | With footer | Footer text link below scrollable content; separate dismiss path from header collapse |
105
+ | Controlled `open` | Parent can force open/closed via prop; internal state follows via `watch` |
106
+
107
+ Header collapse and footer dismiss both close the panel but emit **different events** — use `hide:footer` when persisting opt-out.
108
+
109
+ ---
110
+
111
+ ## Best practices
112
+
113
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
114
+
115
+ ### Selection
116
+
117
+ - **SHOULD** use **`VJoyWalkthrough`** for persistent onboarding that can be collapsed and resumed.
118
+ - **SHOULD** use **`VJoyProductTour`** when steps must highlight specific DOM targets with a spotlight.
119
+ - **MUST NOT** stack multiple walkthrough instances on the same viewport without design approval — one corner panel at a time.
120
+
121
+ ### Implementation
122
+
123
+ - **MUST** use only documented props from MCP or `VJoyWalkthrough.vue` (`open`, `triggerTitle`, `triggerSubtitle`, `triggerIcon`, `footer`, `triggerAttrs`, `disableTeleport`).
124
+ - **MUST** style with Joy tokens — no custom `.joy-walkthrough-modal` width, elevation, radius, or z-index overrides.
125
+ - **MUST NOT** invent props (`variant`, `size`, `placement`, `step`, …).
126
+ - **MUST NOT** set `disableTeleport` in production.
127
+ - **SHOULD** pass `triggerAttrs` for `data-testid`, `aria-label`, or analytics hooks on the trigger.
128
+ - **SHOULD** listen to `hide:footer` (or `hide`) to persist permanent dismiss when `footer` is shown.
129
+ - **SHOULD** omit `triggerSubtitle` and `walkthrough-progress` when there is no measurable progress (see Storybook `NoProgress`).
130
+
131
+ ### Content slots
132
+
133
+ - **SHOULD** fill `walkthrough-title` and at least one of `walkthrough-content` or `walkthrough-subtitle` so the open panel is self-explanatory.
134
+ - **SHOULD** keep `walkthrough-illustration` decorative — meaning lives in title/subtitle slots.
135
+ - **MUST NOT** put the only actionable CTA solely in the footer if the user must complete steps in `walkthrough-content` first.
136
+
137
+ ### Do / don’t
138
+
139
+ | Do | Don’t |
140
+ | --- | --- |
141
+ | `VJoyWalkthrough` + slots for onboarding checklists | `VJoyDialog` for non-blocking corner help |
142
+ | `VJoyProductTour` for element-anchored tours | Walkthrough pretending to spotlight page nodes |
143
+ | `triggerAttrs` + `aria-label` when mobile hides title | Icon-only trigger with no accessible name |
144
+ | `hide:footer` + storage for “don’t show again” | Footer copy with no persistence handler |
145
+ | `VJoyProgressBar` in `walkthrough-progress` | Invented progress props on walkthrough |
146
+ | Joy walkthrough z-index token | Arbitrary `z-index: 9999` in product CSS |
147
+
148
+ ---
149
+
150
+ ## Content
151
+
152
+ Walkthrough copy spans the **trigger** (collapsed), **slots** (expanded), and optional **footer** (permanent dismiss). Keep lines short — the panel is narrow on desktop and full-screen on mobile.
153
+
154
+ ### Trigger copy
155
+
156
+ | Prop | Formula | Example |
157
+ | --- | --- | --- |
158
+ | `triggerTitle` | Short action or topic — **2–4 words** | `Get started`, `Complete profile` |
159
+ | `triggerSubtitle` | Progress or status — optional | `80% completed`, `3 steps left` |
160
+ | `triggerIcon` | Reinforces task type — optional | `list`, `trending-up` |
161
+
162
+ Omit `triggerSubtitle` when there is no progress to show. Do not duplicate the same percentage in both subtitle and progress bar label without reason.
163
+
164
+ ### Slot copy
165
+
166
+ | Slot | Formula | Example |
167
+ | --- | --- | --- |
168
+ | `walkthrough-title` | **Benefit or step headline** — sentence case | `Welcome to your dashboard` |
169
+ | `walkthrough-subtitle` | One line of context | `Finish these steps to publish your first project` |
170
+ | `walkthrough-content` | Steps, bullets, or collapsible sections | Checklist items, links to settings |
171
+ | `walkthrough-progress` | Visual meter only — pair with numeric copy nearby | `VJoyProgressBar` + subtitle |
172
+
173
+ ### Footer copy
174
+
175
+ **Opt-out action** — infinitive or imperative, states permanence:
176
+
177
+ - ✅ `Close and don't show again`
178
+ - ✅ `Dismiss setup guide`
179
+ - ❌ `OK` (ambiguous — does not signal persistence)
180
+
181
+ Wire footer clicks to storage or backend preference in the `hide:footer` / `hide` handler.
182
+
183
+ ### Writing rules
184
+
185
+ | Strength | Rule |
186
+ | --- | --- |
187
+ | **MUST** | Trigger `title` (or `aria-label` via `triggerAttrs`) names the walkthrough when collapsed |
188
+ | **MUST** | Footer text reflects permanent dismiss when that is the behavior |
189
+ | **MUST** | Step content in `walkthrough-content` uses scannable lists — one action per line when possible |
190
+ | **MUST NOT** | Use the footer as the only place critical instructions appear |
191
+ | **MUST NOT** | Show conflicting progress (subtitle says 50% while bar shows 80%) |
192
+ | **SHOULD** | Keep `walkthrough-title` ≤ ~60 characters |
193
+ | **SHOULD** | Use joyful / promo tone only for deliberate onboarding — default to neutral, helpful |
194
+ | **SHOULD** | Match terminology with page headings and CTAs elsewhere |
195
+ | **SHOULD** (FR) | Follow French grammar for titles and dismiss lines when the UI is localized |
196
+
197
+ ### Patterns
198
+
199
+ **Checklist onboarding** — `walkthrough-content` lists tasks; completed items move per product rules (see ZeroHeight usage: done items reorder within category). Progress in `walkthrough-progress` + `triggerSubtitle`.
200
+
201
+ **Resume later** — Collapsed trigger shows remaining work (`3 steps left`); open panel expands the full list.
202
+
203
+ **No progress** — Drop `triggerSubtitle` and `walkthrough-progress`; rely on title + content only.
204
+
205
+ ---
206
+
207
+ ## Accessibility
208
+
209
+ Behaviors (what must happen), not slogans.
210
+
211
+ | Behavior | Expectation |
212
+ | --- | --- |
213
+ | Trigger | Native `button` via `VJoyWalkthroughTrigger`; **Enter** / **Space** activate; focus ring on trigger |
214
+ | Trigger name | `triggerTitle` / `triggerSubtitle` supply visible name; add **`aria-label`** via `triggerAttrs` if mobile layout hides title |
215
+ | Modal header | `role="button"` on header wrapper — pointer click collapses; ensure keyboard users can still dismiss via trigger after collapse or provide an equivalent |
216
+ | Footer | Native `button type="button"` with visible text from `footer` prop |
217
+ | Illustration | Treat `walkthrough-illustration` as decorative unless it conveys unique information |
218
+ | Progress | `VJoyProgressBar` needs nearby text (subtitle or label) — bar alone is not sufficient name |
219
+ | Stacking | Teleport to `body` preserves walkthrough z-index token — do not trap focus unless product requires it |
220
+ | Permanent dismiss | Persist opt-out when footer promises it — do not re-show on next visit without user action |
221
+
222
+ Target: **WCAG 2.2 AA** where the product requires it.
223
+
224
+ ---
225
+
226
+ ## Examples
227
+
228
+ ```vue
229
+ <script setup lang="ts">
230
+ import { ref } from 'vue'
231
+ import {
232
+ VJoyWalkthrough,
233
+ VJoyIcon,
234
+ VJoyProgressBar,
235
+ } from '@maltjoy/core-vue'
236
+
237
+ const dismissed = ref(false)
238
+
239
+ function onPermanentDismiss() {
240
+ dismissed.value = true
241
+ localStorage.setItem('onboarding-walkthrough-dismissed', '1')
242
+ }
243
+ </script>
244
+
245
+ <template>
246
+ <VJoyWalkthrough
247
+ v-if="!dismissed"
248
+ :open="true"
249
+ trigger-icon="list"
250
+ trigger-title="Get started"
251
+ trigger-subtitle="80% completed"
252
+ footer="Close and don't show again"
253
+ :trigger-attrs="{ 'data-testid': 'onboarding-walkthrough-trigger' }"
254
+ @hide:footer="onPermanentDismiss"
255
+ >
256
+ <template #walkthrough-illustration>
257
+ <VJoyIcon name="trending-up" size="medium" />
258
+ </template>
259
+ <template #walkthrough-title>Welcome to your dashboard</template>
260
+ <template #walkthrough-subtitle>
261
+ Complete these steps to publish your first project.
262
+ </template>
263
+ <template #walkthrough-progress>
264
+ <VJoyProgressBar :percentage="80" show-label />
265
+ </template>
266
+ <template #walkthrough-content>
267
+ <ul>
268
+ <li>Add your profile photo</li>
269
+ <li>Set your availability</li>
270
+ <li>Publish your first project</li>
271
+ </ul>
272
+ </template>
273
+ </VJoyWalkthrough>
274
+ </template>
275
+ ```
276
+
277
+ In Nuxt (or apps with auto-import), omit the import if `VJoyWalkthrough` is already global.
278
+
279
+ ---
280
+
281
+ ## Related
282
+
283
+ | Component | Use when |
284
+ | --- | --- |
285
+ | `VJoyWalkthroughTrigger` | Collapsed pill only (rare — parent usually owns it) |
286
+ | `VJoyProductTour` | Multi-step tour with element spotlighting |
287
+ | `VJoyProductTourTrigger` | Entry trigger for product tours |
288
+ | `VJoyProgressBar` | Progress meter in `walkthrough-progress` slot |
289
+ | `VJoyIcon` | Illustration slot and `triggerIcon` |
290
+ | `VJoyCollapse` / `VJoyCollapseItem` | Expandable steps inside `walkthrough-content` |
291
+ | `VJoyDialog` | Blocking modal decisions |
292
+ | `VJoyTooltip` | Single-control hints |
293
+
294
+ ---
295
+
296
+ ## For agents
297
+
298
+ Optional for readers; **required** for vibe-coding quality. Maps to `agentDocumentBlocks` in [`JoyWalkthrough.dsds.json`](./JoyWalkthrough.dsds.json).
299
+
300
+ ### Pick the right component
301
+
302
+ | If the intent is… | Emit… | Do not emit… |
303
+ | --- | --- | --- |
304
+ | Persistent collapsible onboarding panel | `VJoyWalkthrough` | Fixed `div` in corner + custom CSS |
305
+ | Highlight specific page elements step-by-step | `VJoyProductTour` | `VJoyWalkthrough` with manual positioning |
306
+ | Blocking confirm / form modal | `VJoyDialog` | Walkthrough for destructive confirm |
307
+ | Toast after save | `pushVJoySnackbar` | Walkthrough for transient feedback |
308
+ | Icon-only corner button without panel | `VJoyWalkthroughTrigger` | `VJoyButton` styled as dark pill |
309
+ | Progress in panel header | `walkthrough-progress` + `VJoyProgressBar` | Invented `percentage` prop on walkthrough |
310
+
311
+ ### Hard rules
312
+
313
+ 1. **MUST** call `joy_get_component_info("VJoyWalkthrough")` before generating props.
314
+ 2. **MUST** use slot names exactly: `walkthrough-illustration`, `walkthrough-title`, `walkthrough-subtitle`, `walkthrough-progress`, `walkthrough-content`.
315
+ 3. **MUST** pass trigger a11y/test attrs via `triggerAttrs`, not on the root when targeting the pill.
316
+ 4. **MUST** listen to `hide`, `hide:header`, or `hide:footer` when syncing `open` or persistence.
317
+ 5. **MUST NOT** emit `disableTeleport` outside Storybook/docs.
318
+ 6. **MUST NOT** invent props (`variant`, `size`, `step`, `placement`, …).
319
+ 7. **MUST NOT** override `.joy-walkthrough` / `.joy-walkthrough-modal` dimensions, z-index, or elevation.
320
+ 8. **SHOULD** omit `triggerSubtitle` and `walkthrough-progress` when there is no progress metric.
321
+ 9. **SHOULD** set `footer` only when implementing permanent dismiss with a handler.
322
+
323
+ ### Checklist
324
+
325
+ - [ ] Correct component (`VJoyWalkthrough` or named alternative)
326
+ - [ ] Props / slots from MCP only
327
+ - [ ] `triggerTitle` or `triggerAttrs['aria-label']` for collapsed state
328
+ - [ ] `walkthrough-title` (+ content) when panel opens
329
+ - [ ] `hide:footer` / storage when footer promises “don’t show again”
330
+ - [ ] No `disableTeleport` in production
331
+ - [ ] No invented props / no custom walkthrough chrome CSS
332
+ - [ ] Product tour with spotlight → `VJoyProductTour`
333
+
334
+ ---
335
+
336
+ ## DSDS mapping
337
+
338
+ This Markdown mirrors [`JoyWalkthrough.dsds.json`](./JoyWalkthrough.dsds.json) (DSDS **0.15.2**).
339
+
340
+ | Section here | DSDS block |
341
+ | --- | --- |
342
+ | When to use / not | `use-cases` |
343
+ | Anatomy / lifecycle | `anatomy` |
344
+ | States | `states` |
345
+ | Best practices / content rules | `guidelines` (+ `content`) |
346
+ | Accessibility | `accessibility` |
347
+ | Examples | `sections` |
348
+ | For agents | `agentDocumentBlocks` |
349
+ | Props detail | `api` in JSON + Joy MCP |
350
+ | Imports | `imports` in JSON |
351
+ | Layout tokens | `design-specifications` in JSON (`--walkthrough-width`, `--joy-core-z-index-walkthrough`) |