@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,328 @@
1
+ ---
2
+ component: VJoyAvatarsList
3
+ status: draft
4
+ language: en
5
+ dsds: JoyAvatarsList.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Avatars list
10
+
11
+ Use **`VJoyAvatarsList`** when you need to show **several `VJoyAvatar` instances as a group** — with consistent spacing and alignment, or in a compact overlapping stack.
12
+
13
+ The list is a layout container only: put avatars in the default slot, set `compress` when they should overlap (for example bulk-selection toolbars), and let provide/inject pass compression styling to each child. Overflow counts (`+N`) still belong on the last `VJoyAvatar` via `totalNumber`, not on the list itself.
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyAvatarsList` from `@maltjoy/core-vue` |
18
+ | **Design** | [ZeroHeight — Avatar](https://zeroheight.com/6bf479565/p/52ceb2-avatar) (list patterns) |
19
+ | **Storybook** | [VJoyAvatarsList docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-view-vjoyavatarslist--docs) |
20
+ | **DSDS (machine)** | [`JoyAvatarsList.dsds.json`](./JoyAvatarsList.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyAvatarsList")` *(not indexed in Joy MCP yet — use Storybook or `VJoyAvatarsList.vue`)* |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use an avatars list when multiple people should read as **one visual unit** — team members on a card, participants in a thread, or freelancers in a bulk-action bar. `VJoyAvatarsList` handles flex layout, token-based gaps, and optional overlap so product code does not hand-roll negative margins or borders.
28
+
29
+ Typical jobs:
30
+
31
+ - **Spaced row** — default mode; avatars wrap with Joy spacing when the row is long.
32
+ - **Compressed stack** — `compress` for dense UI (floating action bars, table selection summaries) where avatars overlap left-to-right.
33
+
34
+ Always compose **`VJoyAvatar` children** inside the list. Person-level props (`fullName`, `photoUrl`, `size`, `totalNumber`, …) stay on each avatar.
35
+
36
+ ### When not to use this component
37
+
38
+ | Need | Use instead |
39
+ | --- | --- |
40
+ | A single person | `VJoyAvatar` alone |
41
+ | Avatar + name, role, metadata in a card | `VJoyUserCard` |
42
+ | Overlapping avatars with manual CSS / negative margins | `VJoyAvatarsList` + `compress` |
43
+ | Setting `compress` on individual avatars | `VJoyAvatarsList` with `compress` — compression is injected, not a per-avatar prop |
44
+ | A scrollable roster with row actions | List/table patterns with `VJoySelectableItem` or data tables |
45
+ | Custom flex wrapper / ad-hoc gap CSS for the same job | Still use `VJoyAvatarsList` + Joy tokens |
46
+
47
+ > **Not in the Vue API:** legacy Stencil `joy-avatars-list` and per-avatar `compress` / `is-first-from-list`. In Vue, only **`VJoyAvatarsList`** exposes `compress`; children pick it up via provide/inject.
48
+
49
+ ---
50
+
51
+ ## How it works
52
+
53
+ `VJoyAvatarsList` renders a flex container, applies list-level classes, and **`provide`s** `{ compress }` under the key `VJoyAvatarsList`. Each `VJoyAvatar` **injects** that value and toggles `.joy-avatar__wrapper--compressed` and overlap styles automatically.
54
+
55
+ ### Anatomy
56
+
57
+ | Part | Required? | What it is |
58
+ | --- | --- | --- |
59
+ | Root container | Yes | `<div class="joy-avatars-list">` — flex row, wrap, token gaps |
60
+ | Default slot | Yes* | One or more `VJoyAvatar` instances (*empty list is valid but usually avoided in product UI) |
61
+ | Compressed modifier | No | `.joy-avatars-list--compressed` when `compress` is true — zero gap, overlap margins on children |
62
+
63
+ There are no events, no `v-model`, and no nested subcomponents beyond slot content.
64
+
65
+ ### Default values
66
+
67
+ - `compress` defaults to **`false`**
68
+
69
+ Props and slots: use Storybook or read `VJoyAvatarsList.vue` — Joy MCP may not list this component yet. This page focuses on **when** and **how**, not a full API dump.
70
+
71
+ ### Layout tokens (default mode)
72
+
73
+ - `display: flex`, `flex-wrap: wrap`, `align-items: center`, `justify-content: flex-start`
74
+ - Gap: `var(--joy-core-spacing-3)` (row) and `var(--joy-core-spacing-6)` (column)
75
+
76
+ **Don’t** reimplement these gaps in product CSS when wrapping avatars in a plain `div`.
77
+
78
+ ---
79
+
80
+ ## Variants
81
+
82
+ `VJoyAvatarsList` has **no color or emphasis prop**. Layout is controlled by **`compress`** only.
83
+
84
+ ### Default (spaced)
85
+
86
+ Use when avatars should remain **distinct circles** with breathing room — member grids, color/size showcases, or anywhere overlap would reduce legibility.
87
+
88
+ Avoid when horizontal space is very tight and the design calls for a stacked “pile” of faces.
89
+
90
+ ### Compressed (`compress`)
91
+
92
+ Use when several avatars must fit in a **compact horizontal stack** — bulk selection bars, dense summaries beside a count label, table toolbars.
93
+
94
+ The list sets `gap: 0` and applies per-size negative `margin-left` on each avatar wrapper (one quarter of the avatar diameter). Non-empty avatars get a **white separator border** so faces remain distinguishable. Empty avatars (`isEmpty`) skip the white border in compressed mode.
95
+
96
+ Avoid compress when avatars are large (`large` / `xlarge`) and the stack would obscure identity — prefer fewer visible avatars plus a `totalNumber` overflow chip.
97
+
98
+ ### Not in the API: per-avatar `compress`
99
+
100
+ Legacy Stencil documented `compress` and `is-first-from-list` on `joy-avatar`. **`VJoyAvatar` has no `compress` prop.** Set `compress` only on `VJoyAvatarsList`.
101
+
102
+ ---
103
+
104
+ ## Sizes
105
+
106
+ `VJoyAvatarsList` has **no `size` prop**. Density comes from the **`size` on each `VJoyAvatar`** child.
107
+
108
+ | Practice | Use when |
109
+ | --- | --- |
110
+ | Same `size` on every child in one list | Always — mixed sizes break alignment and compressed overlap math |
111
+ | `small` inside compressed stacks | Bulk actions, table selections (`VJoyFloatingActionsBar` pattern) |
112
+ | `medium` (avatar default) in spaced lists | General member rows and cards |
113
+ | Larger sizes (`large`, `xlarge`) | Hero or profile contexts — usually **without** `compress` |
114
+
115
+ Overlap offset is computed from each child’s size token (`--negative-margin: calc(avatarSize / -4)`). **Don’t** hardcode overlap pixels in app CSS.
116
+
117
+ ---
118
+
119
+ ## States
120
+
121
+ | State | What the user sees |
122
+ | --- | --- |
123
+ | Default (`compress: false`) | Avatars in a wrapped flex row with token gaps |
124
+ | Compressed (`compress: true`) | Overlapping stack; later avatars sit above earlier ones (`z-index`); white ring between faces |
125
+ | Empty list | Container renders with no avatars — valid technically; avoid in product unless loading |
126
+ | Empty avatars in stack | `isEmpty` on `VJoyAvatar` — neutral placeholder circles; compressed borders omitted for empty wrappers |
127
+ | Overflow | Not a list state — last child uses `VJoyAvatar` `totalNumber` (e.g. `+3`) |
128
+
129
+ The list itself is **not interactive**. Clicks and keyboard focus live on individual `VJoyAvatar` instances when `link` is set.
130
+
131
+ ---
132
+
133
+ ## Best practices
134
+
135
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
136
+
137
+ ### Composition
138
+
139
+ - **MUST** place only `VJoyAvatar` (or wrappers that render avatars) in the default slot — the list does not render avatars for you.
140
+ - **MUST** use the same `size` on every avatar in a given list.
141
+ - **SHOULD** use `compress` for selection summaries and floating action bars; use default spacing elsewhere.
142
+ - **SHOULD** show at most **three** person avatars in selection UI, then a **`totalNumber`** overflow avatar for the remainder (see Content).
143
+ - **SHOULD** keep avatars in **selection order** (left-to-right) — do not reorder by name or recency for display alone.
144
+ - **MUST NOT** set `compress` on individual avatars — only on `VJoyAvatarsList`.
145
+ - **MUST NOT** combine `totalNumber` with `fullName` or `photoUrl` on the same avatar (ESLint).
146
+
147
+ ### Implementation
148
+
149
+ - **MUST** use Joy tokens — no custom `.joy-avatars-list` gap, margin, or overlap CSS.
150
+ - **MUST NOT** invent props on `VJoyAvatarsList` (`variant`, `size`, `max`, `gap`, …).
151
+ - **SHOULD** pair compressed lists with a visible text summary (`3 freelancers selected`) when the selection count matters.
152
+ - **SHOULD** pass `fullName` on person avatars for accessible images and tooltips (`title` on the avatar surface).
153
+
154
+ ### Do / don’t
155
+
156
+ | Do | Don’t |
157
+ | --- | --- |
158
+ | `VJoyAvatarsList` + `VJoyAvatar` children | Bare `div` + manual negative margins |
159
+ | `compress` on the list | `compress` on each avatar |
160
+ | Consistent `size` across the set | Mixed `small` + `medium` in one list |
161
+ | `totalNumber` on the last avatar for overflow | Extra fake avatars to imply count |
162
+ | Text label beside compressed stacks | Avatars alone when count is the main message |
163
+
164
+ ---
165
+
166
+ ## Content
167
+
168
+ `VJoyAvatarsList` does not render copy. Content rules apply to **how you compose** the list with labels and overflow chips in selection and summary UI.
169
+
170
+ ### Selection summary pattern
171
+
172
+ When selected items are identifiable people (for example freelancers to contact):
173
+
174
+ - Show up to **three** person avatars, then collapse overflow into a **`+N`** avatar (`totalNumber` on the last `VJoyAvatar`).
175
+ - Place a **count label after the stack**: `6 selected` (follow locale plural rules).
176
+ - For a **single** selection: one avatar + `1 selected` — do not pluralize the label.
177
+ - When selection has **no** associated people, use a plain count — do not show an avatars list.
178
+
179
+ ### Overflow chip
180
+
181
+ - Use `totalNumber` for the **hidden count only** (not total headcount). Example: two visible faces + `totalNumber={4}` → reads as two photos and `+4` for four more.
182
+ - Keep the overflow avatar the **same `size`** as the visible avatars.
183
+
184
+ ### Writing rules
185
+
186
+ | Strength | Rule |
187
+ | --- | --- |
188
+ | **MUST** | Expose the selection count in visible text when the list is the primary selection indicator |
189
+ | **MUST NOT** | Rely on avatars alone when users need an exact count |
190
+ | **SHOULD** | Use sentence case for count labels — `3 freelancers selected` |
191
+ | **SHOULD** | Match count copy to the entity type (freelancers, members, participants) |
192
+
193
+ ---
194
+
195
+ ## Accessibility
196
+
197
+ Behaviors (what must happen), not slogans.
198
+
199
+ | Behavior | Expectation |
200
+ | --- | --- |
201
+ | Role | Presentational group — no interactive role on the list container |
202
+ | Names | Each person avatar should have a meaningful `fullName` (photo `alt` / `title`) or nearby text that identifies the set |
203
+ | Overflow | `+N` text is visible content on the overflow avatar; pair with a textual count for screen-reader context when the number is critical |
204
+ | Keyboard | List does not trap focus; focusable avatars use `link` + `@click` on `VJoyAvatar` only |
205
+ | Selection context | When the list indicates bulk selection, expose the count in **visible text** next to the stack — not only in a tooltip |
206
+
207
+ Target: **WCAG 2.2 AA** where the product requires it.
208
+
209
+ ---
210
+
211
+ ## Examples
212
+
213
+ ```vue
214
+ <script setup lang="ts">
215
+ import { VJoyAvatar, VJoyAvatarsList, VJoyText, VJoyWrapper } from '@maltjoy/core-vue'
216
+ </script>
217
+
218
+ <template>
219
+ <!-- Spaced member row -->
220
+ <VJoyAvatarsList>
221
+ <VJoyAvatar full-name="Alan Grant" photo-url="https://example.com/alan.webp" size="medium" />
222
+ <VJoyAvatar full-name="Ellie Sattler" size="medium" />
223
+ <VJoyAvatar full-name="Ian Malcolm" size="medium" />
224
+ </VJoyAvatarsList>
225
+
226
+ <!-- Compressed stack with overflow (bulk selection) -->
227
+ <VJoyWrapper no-margin column-gap="3" align="center">
228
+ <VJoyAvatarsList compress>
229
+ <VJoyAvatar full-name="Alice Dupont" size="small" />
230
+ <VJoyAvatar full-name="Bob Martin" size="small" />
231
+ <VJoyAvatar :total-number="4" size="small" />
232
+ </VJoyAvatarsList>
233
+ <VJoyText preset="primary-400">6 freelancers selected</VJoyText>
234
+ </VJoyWrapper>
235
+
236
+ <!-- v-for-driven list -->
237
+ <VJoyAvatarsList compress>
238
+ <VJoyAvatar
239
+ v-for="member in members"
240
+ :key="member.id"
241
+ :full-name="member.fullName"
242
+ :photo-url="member.photoUrl"
243
+ size="small"
244
+ />
245
+ </VJoyAvatarsList>
246
+ </template>
247
+ ```
248
+
249
+ In Nuxt (or apps with auto-import), omit the import if `VJoyAvatarsList` is already global.
250
+
251
+ ---
252
+
253
+ ## Related
254
+
255
+ | Component | Use when |
256
+ | --- | --- |
257
+ | `VJoyAvatar` | A single person, overflow `+N` chip, or anonymous placeholder |
258
+ | `VJoyUserCard` | Avatar plus name, subtitle, and actions |
259
+ | `VJoyFloatingActionsBar` | Bulk actions — often pairs `compress` avatars with action buttons |
260
+ | `VJoyWrapper` | Horizontal layout beside the list (avatar stack + count label) |
261
+ | `VJoyText` | Selection count or summary copy next to the list |
262
+
263
+ ---
264
+
265
+ ## For agents
266
+
267
+ Optional for readers; **required** for vibe-coding quality. Maps to `agentDocumentBlocks` in [`JoyAvatarsList.dsds.json`](./JoyAvatarsList.dsds.json).
268
+
269
+ ### Pick the right component
270
+
271
+ | If the intent is… | Emit… | Do not emit… |
272
+ | --- | --- | --- |
273
+ | One person | `VJoyAvatar` | `VJoyAvatarsList` with a single child (unless design explicitly groups it) |
274
+ | Multiple people, spaced | `VJoyAvatarsList` + `VJoyAvatar` children | `div` with flex + gap |
275
+ | Overlapping stack | `VJoyAvatarsList` with `compress` | Per-avatar `compress` or negative margins |
276
+ | Hidden count / +N | Last `VJoyAvatar` with `totalNumber` | Extra avatars or list-level `overflow` prop |
277
+ | Full identity card | `VJoyUserCard` | List + manual name markup |
278
+
279
+ ### Hard rules
280
+
281
+ 1. **MUST** read `VJoyAvatarsList.vue` and Storybook before generating props — `joy_get_component_info("VJoyAvatarsList")` may fail until MCP indexes the component.
282
+ 2. **MUST** use only documented list prop: `compress` (boolean, default `false`).
283
+ 3. **MUST** put avatars in the **default slot** — no `avatars` prop array on the list.
284
+ 4. **MUST NOT** invent list props (`size`, `variant`, `maxVisible`, `gap`, `avatars`, …).
285
+ 5. **MUST NOT** set `compress` on `VJoyAvatar` — compression is provide/inject from the list parent.
286
+ 6. **MUST NOT** override `.joy-avatars-list` gap, overlap, or border styles in product CSS.
287
+ 7. **SHOULD** use `compress` with `size="small"` in dense toolbars; default spacing otherwise.
288
+ 8. **SHOULD** use identical `size` on all children in one list.
289
+ 9. **SHOULD** cap visible person avatars at three in selection UI and use `totalNumber` for overflow.
290
+
291
+ ### Valid API (from source)
292
+
293
+ | Prop | Type | Default |
294
+ | --- | --- | --- |
295
+ | `compress` | `boolean` | `false` |
296
+
297
+ | Slot | Purpose |
298
+ | --- | --- |
299
+ | `default` | `VJoyAvatar` instances |
300
+
301
+ ### Checklist
302
+
303
+ - [ ] `VJoyAvatarsList` wraps multiple `VJoyAvatar` children (not a lone avatar unless required)
304
+ - [ ] `compress` only on the list, never on avatars
305
+ - [ ] Same `size` on every child in the set
306
+ - [ ] Overflow via last child `totalNumber` — not combined with `fullName` / `photoUrl`
307
+ - [ ] Selection UI: ≤ 3 faces + overflow chip + textual count when needed
308
+ - [ ] No custom overlap / gap CSS on `.joy-avatars-list`
309
+
310
+ ---
311
+
312
+ ## DSDS mapping
313
+
314
+ This Markdown mirrors [`JoyAvatarsList.dsds.json`](./JoyAvatarsList.dsds.json) (DSDS **0.15.2**).
315
+
316
+ | Section here | DSDS block |
317
+ | --- | --- |
318
+ | When to use / not | `use-cases` |
319
+ | Anatomy | `anatomy` |
320
+ | Layout modes (`compress`) | `variants` |
321
+ | Child `size` consistency | `design-specifications` |
322
+ | States | `states` |
323
+ | Best practices / composition rules | `guidelines` |
324
+ | Selection copy / overflow | `content` |
325
+ | Accessibility | `accessibility` |
326
+ | Examples | `sections` |
327
+ | For agents | `agentDocumentBlocks` |
328
+ | Props detail | `api` in JSON + Storybook / source |
@@ -0,0 +1,169 @@
1
+ ---
2
+ component: VJoyBadge
3
+ status: draft
4
+ language: en
5
+ dsds: JoyBadge.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Badge
10
+
11
+ Use **`VJoyBadge`** when you need a compact, colored label to communicate status, category, or metadata — for example “Active”, “Draft”, “Premium”, or a row state in a table.
12
+
13
+ The badge renders short text from the `label` prop or default slot, with an optional leading bullet (`bulletpoint`) and a semantic `variant` color. It is presentational and non-interactive.
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyBadge` from `@maltjoy/core-vue` |
18
+ | **Design** | [ZeroHeight — Badge](https://zeroheight.com/6bf479565/p/574c8a) |
19
+ | **Storybook** | [VJoyBadge docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-view-vjoybadge--docs) |
20
+ | **DSDS (machine)** | [`JoyBadge.dsds.json`](./JoyBadge.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyBadge")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use a badge when a short, scannable label should sit beside or inside content — table cells, list rows, card headers, or inline metadata — and color helps users spot status or category at a glance.
28
+
29
+ Enable `bulletpoint` when design calls for a colored pastille before the label (common in data tables and status rows). Omit it for simpler chips where the pill background alone is enough.
30
+
31
+ ### When not to use this component
32
+
33
+ | Need | Use instead |
34
+ | --- | --- |
35
+ | Malt-specific user achievement or program status (SuperMalter, Verified, …) | `VJoyBadgeLevel` |
36
+ | Removable filters, selectable chips, or skill tags | `VJoyTag` / `VJoyTagsList` |
37
+ | Standalone notification count (numeric dot on an icon) | `VJoyDot` with `number` |
38
+ | Clickable or dismissible token | `VJoyTag` (interactive) — `VJoyBadge` has no click or remove API |
39
+ | Long descriptions or multi-sentence copy | `VJoyText` or inline body copy — badges stay short |
40
+ | Custom pill markup with ad-hoc colors | Still use `VJoyBadge` + documented `variant` values |
41
+
42
+ ---
43
+
44
+ ## How it works
45
+
46
+ `VJoyBadge` is a `<span role="status">` with pill styling (`joy-badge`, `joy-badge__{variant}`). When `bulletpoint` is true, a `VJoyDot` shares the same `variant` and sits to the left of the label.
47
+
48
+ ### Anatomy
49
+
50
+ | Part | Required? | What it is |
51
+ | --- | --- | --- |
52
+ | Root container | Yes | `.joy-badge` pill; `role="status"` |
53
+ | Label text | Yes* | `label` prop or default slot content |
54
+ | Bullet (`VJoyDot`) | No | Colored dot when `bulletpoint` is true (`.joy-badge_dot`) |
55
+ | Variant class | Yes | Background from `variant` (`joy-badge__{variant}`) |
56
+
57
+ \*Provide text via `label` or the default slot — empty badges are possible but useless in product UI.
58
+
59
+ ### Variants (`variant`)
60
+
61
+ Allowed values (`TJoyBadgeVariants` / `TJoyDotVariants`): `info`, `gray`, `green`, `orange`, `red`, `teal`, `pink`, `dark-blue`, `yellow`.
62
+
63
+ | `variant` | Typical meaning | Background token |
64
+ | --- | --- | --- |
65
+ | `info` | Informational / default | `--joy-color-information-10` |
66
+ | `gray` | Neutral / inactive | `--joy-color-neutral-20` |
67
+ | `green` | Success / positive | `--joy-color-success-10` |
68
+ | `orange` | Warning / attention | `--joy-color-warning-10` |
69
+ | `red` | Primary emphasis / critical | `--joy-color-primary-10` |
70
+ | `teal` | Secondary accent | `--joy-color-secondary-10` |
71
+ | `pink` | Brand primary | `--joy-color-brand-primary-10` |
72
+ | `dark-blue` | Brand secondary | `--joy-color-brand-secondary-10` |
73
+ | `yellow` | Quaternary highlight | `--joy-color-quaternary-10` |
74
+
75
+ Pick `variant` by **meaning in context**, not by which swatch looks best. The component docs mention `--badge-bg-color` and `--badge-circle-color` overrides — prefer documented variants before custom CSS.
76
+
77
+ ### Default values
78
+
79
+ - `variant` defaults to **`info`**
80
+ - `bulletpoint` defaults to **`false`**
81
+ - `label` defaults to **`""`**
82
+
83
+ Props and slots: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
84
+
85
+ ---
86
+
87
+ ## Best practices
88
+
89
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
90
+
91
+ ### Selection and content
92
+
93
+ - **SHOULD** keep badge copy **short** (one or two words, or a compact count) — badges are not paragraphs.
94
+ - **SHOULD** choose `variant` to match semantic intent (success, warning, neutral) so color reinforces the label.
95
+ - **SHOULD** enable `bulletpoint` when the design system pattern expects a pastille (e.g. table status columns); hide it for plain pills.
96
+ - **MUST NOT** use `VJoyBadge` for Malt profile achievements — use `VJoyBadgeLevel` with the correct `type`.
97
+
98
+ ### Implementation
99
+
100
+ - **MUST** use only documented `variant` values from MCP or `JoyBadge.types.ts`.
101
+ - **MUST** use Joy tokens — no custom `.joy-badge` chrome or hardcoded hex backgrounds in product CSS.
102
+ - **MUST NOT** invent props (`size`, `clickable`, `removable`, …).
103
+ - **SHOULD** use the `label` prop for plain strings; use the default slot when the label needs inline markup (keep it minimal).
104
+
105
+ ### Do / don’t
106
+
107
+ | Do | Don’t |
108
+ | --- | --- |
109
+ | `variant="green"` + label “Paid” for success | Random `red` because it “pops” |
110
+ | `bulletpoint` in table status columns | Recreate pills with `<span>` + custom CSS |
111
+ | `VJoyBadgeLevel` for SuperMalter / Verified | `VJoyBadge` for platform achievement icons |
112
+ | `VJoyTag` for removable filter chips | `VJoyBadge` with click handlers wrapped around it |
113
+
114
+ ---
115
+
116
+ ## Accessibility
117
+
118
+ Presentational status label — not interactive by default.
119
+
120
+ | Behavior | Expectation |
121
+ | --- | --- |
122
+ | Role | `role="status"` on the root — suitable for status text; avoid stacking many live `status` regions that update constantly |
123
+ | Name | Visible label text (`label` prop or default slot) is the accessible name |
124
+ | Bullet | When `bulletpoint` is true, the dot is decorative if the text conveys the same status — don’t rely on color alone |
125
+ | Interaction | No built-in keyboard or pointer handling — if the badge must be clickable, wrap it in a proper link/button with its own name |
126
+ | Contrast | Text uses `--joy-color-neutral-50` on light variant backgrounds — don’t override text color without a design review |
127
+
128
+ Target: **WCAG 2.2 AA** where the product requires it.
129
+
130
+ ---
131
+
132
+ ## Examples
133
+
134
+ ```vue
135
+ <script setup lang="ts">
136
+ import { VJoyBadge } from '@maltjoy/core-vue'
137
+ </script>
138
+
139
+ <template>
140
+ <!-- Default informational badge -->
141
+ <VJoyBadge label="Draft" />
142
+
143
+ <!-- Success status with bullet (table-style) -->
144
+ <VJoyBadge variant="green" bulletpoint label="Approved" />
145
+
146
+ <!-- Slot for short custom content -->
147
+ <VJoyBadge variant="orange" bulletpoint>
148
+ Pending review
149
+ </VJoyBadge>
150
+
151
+ <!-- Neutral metadata -->
152
+ <VJoyBadge variant="gray" label="Archived" />
153
+ </template>
154
+ ```
155
+
156
+ In Nuxt (or apps with auto-import), omit the import if `VJoyBadge` is already global.
157
+
158
+ ---
159
+
160
+ ## Related
161
+
162
+ | Component | Use when |
163
+ | --- | --- |
164
+ | `VJoyBadgeLevel` | Malt-specific user or program recognition badges |
165
+ | `VJoyTag` | Interactive, removable, or selectable chips |
166
+ | `VJoyTagsList` | Horizontal list of tags |
167
+ | `VJoyDot` | Standalone colored dot or numeric notification badge |
168
+ | `VJoyText` | Longer supporting copy beside a badge |
169
+ | `VJoyTooltip` | Optional clarification when icon-only or terse labels need context |
@@ -0,0 +1,166 @@
1
+ ---
2
+ component: VJoyBadgeLevel
3
+ status: draft
4
+ language: en
5
+ dsds: JoyBadgeLevel.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Badge level
10
+
11
+ Use **`VJoyBadgeLevel`** when you need to show a Malt-specific user recognition level or program status — SuperMalter crowns, High Potential, Verified, Malt Linker, New, and related program badges.
12
+
13
+ Each `type` renders a fixed SVG icon (when applicable) and an optional text label. Set `visibleText` to `false` for icon-only display, or use the default slot to override the built-in label.
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyBadgeLevel` from `@maltjoy/core-vue` |
18
+ | **Design** | [Figma — Joy Core Design System](https://www.figma.com/design/jfndp2QBJGS9yeuWbeGuvD/) |
19
+ | **Storybook** | [VJoyBadgeLevel docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-view-vjoybadgelevel--docs) |
20
+ | **DSDS (machine)** | [`JoyBadgeLevel.dsds.json`](./JoyBadgeLevel.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyBadgeLevel")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use a badge level when the UI must communicate a **predefined Malt achievement or program status** tied to a freelancer or profile — for example SuperMalter tier, High Potential program membership, verified identity, Malt Linker designation, or a “New” profile marker.
28
+
29
+ Typical placements: next to a user name in a card or list row, inside `VJoyUserCard`, or inline in profile headers where the recognition is part of the user’s identity rather than a generic tag.
30
+
31
+ ### When not to use this component
32
+
33
+ | Need | Use instead |
34
+ | --- | --- |
35
+ | Generic status, category, or count chips | `VJoyBadge` or `VJoyTag` |
36
+ | Custom achievement graphics not in the Joy badge-level set | Confirm with design — don’t recreate badge SVGs in product CSS |
37
+ | Interactive filters or removable tokens | `VJoyTag` / `VJoyTagsList` |
38
+ | Availability or online status | `VJoyAvailability` |
39
+ | Ad-hoc badge markup with copied SVG paths | Still use `VJoyBadgeLevel` + documented `type` values |
40
+
41
+ > **Deprecated:** `type="highpotential"` (`JoyBadgeLevelEnum.HIGH_POTENTIAL`) — prefer `type="high-potential-auto"` or `type="program_high-potential"` for new work. Rendering matches High Potential today; only the keyword differs for program tracking.
42
+
43
+ ---
44
+
45
+ ## How it works
46
+
47
+ `VJoyBadgeLevel` is a presentational `<span>`: one or more inline SVGs (depending on `type`) plus an optional `.joy-badge-level__tag` label. Label color is derived from `type` (`red`, `blue`, or `turquoise` modifier classes) — not a separate prop.
48
+
49
+ ### Anatomy
50
+
51
+ | Part | Required? | What it is |
52
+ | --- | --- | --- |
53
+ | Root container | Yes | `.joy-badge-level` flex row (icon + label) |
54
+ | SVG icon(s) | No* | Type-specific artwork; SuperMalter repeats 1–3 crown icons |
55
+ | Text tag | No | `.joy-badge-level__tag` with built-in or slotted label |
56
+ | Default slot | No | Overrides the computed label when `visibleText` is true |
57
+
58
+ \*`new` and `verified` are label-only (no icon). Other types render at least one SVG.
59
+
60
+ ### Badge types (`type`)
61
+
62
+ | `type` value | Icon | Default label | Tag color |
63
+ | --- | --- | --- | --- |
64
+ | `supermalter` | 1–3 crowns (`superMalterLevel`) | Supermalter | blue |
65
+ | `highpotential` | Diamond | High Potential | blue |
66
+ | `program_high-potential` | Diamond (program variant) | High Potential | blue |
67
+ | `high-potential-auto` | Flame | High Potential Auto | red |
68
+ | `maltlinker` | Linker mark | Malt Linker | red |
69
+ | `new` | — | New | red |
70
+ | `verified` | — | Verified | turquoise |
71
+
72
+ ### Default values
73
+
74
+ - `type` is **required** — must be a `TJoyBadges` enum string
75
+ - `superMalterLevel` defaults to **`1`** (only applies when `type="supermalter"`; valid range 1–3)
76
+ - `visibleText` defaults to **`true`**
77
+
78
+ Props and slots: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
79
+
80
+ ---
81
+
82
+ ## Best practices
83
+
84
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
85
+
86
+ ### Selection and data
87
+
88
+ - **MUST** pass a documented `type` from `JoyBadgeLevelEnum` / `JoyBadgeProgramEnum` — never invent badge keywords.
89
+ - **MUST** source `type` and `superMalterLevel` from backend/profile data; don’t hardcode achievement levels in the UI layer.
90
+ - **SHOULD** use `:visible-text="false"` in dense layouts (avatars, compact list rows) when the icon alone is recognizable in context.
91
+ - **SHOULD** keep the default English labels unless product copy requires localization — override via the default slot when translations differ.
92
+
93
+ ### Implementation
94
+
95
+ - **MUST** use `VJoyBadgeLevel` as shipped — no custom SVG recreations or `.joy-badge-level__*` color overrides in product CSS.
96
+ - **MUST NOT** invent props (`variant`, `size`, `color`, …).
97
+ - **MUST NOT** use `type="highpotential"` on new features — use `high-potential-auto` or `program_high-potential`.
98
+ - **SHOULD** pair with the user’s name or profile context so the badge meaning is clear without hover tooltips.
99
+
100
+ ### Do / don’t
101
+
102
+ | Do | Don’t |
103
+ | --- | --- |
104
+ | `type="supermalter"` + `superMalterLevel` from API | Always show 3 crowns regardless of level |
105
+ | `:visible-text="false"` in tight headers | Shrink or recolor badge SVGs in app CSS |
106
+ | Default slot for localized label text | Duplicate badge artwork in `<img>` or inline SVG |
107
+ | `VJoyBadge` for generic “Pro” / status chips | `VJoyBadgeLevel` for non-Malt-specific labels |
108
+
109
+ ---
110
+
111
+ ## Accessibility
112
+
113
+ Decorative presentational badge — not interactive by default.
114
+
115
+ | Behavior | Expectation |
116
+ | --- | --- |
117
+ | Role | Plain text/graphics in a `<span>` — no button or link role unless wrapped by the app |
118
+ | Name | When `visibleText` is true, the visible label provides the text alternative; icon-only instances **SHOULD** sit beside a visible user name or have nearby text that conveys the same status |
119
+ | Icon-only | Don’t rely on color or icon shape alone in isolation — ensure context (name, title, or adjacent copy) states the achievement |
120
+ | Motion | Static SVGs — no animation in the component |
121
+ | Links | If the badge is wrapped in a link, the **link** must have an accessible name; don’t make the badge itself the only clickable target without a label |
122
+
123
+ Target: **WCAG 2.2 AA** where the product requires it.
124
+
125
+ ---
126
+
127
+ ## Examples
128
+
129
+ ```vue
130
+ <script setup lang="ts">
131
+ import { VJoyBadgeLevel } from '@maltjoy/core-vue'
132
+
133
+ // Example profile fields from an API
134
+ const superMalterLevel = 2
135
+ </script>
136
+
137
+ <template>
138
+ <!-- SuperMalter with level from backend -->
139
+ <VJoyBadgeLevel type="supermalter" :super-malter-level="superMalterLevel" />
140
+
141
+ <!-- High Potential program badge -->
142
+ <VJoyBadgeLevel type="program_high-potential" />
143
+
144
+ <!-- Icon only in a compact row -->
145
+ <VJoyBadgeLevel type="verified" :visible-text="false" />
146
+
147
+ <!-- Localized label override -->
148
+ <VJoyBadgeLevel type="new">
149
+ Nouveau
150
+ </VJoyBadgeLevel>
151
+ </template>
152
+ ```
153
+
154
+ In Nuxt (or apps with auto-import), omit the import if `VJoyBadgeLevel` is already global.
155
+
156
+ ---
157
+
158
+ ## Related
159
+
160
+ | Component | Use when |
161
+ | --- | --- |
162
+ | `VJoyUserCard` | Profile row that may include badge level beside the user name |
163
+ | `VJoyAvatar` | User photo/initials — badge level is usually adjacent, not inside the avatar |
164
+ | `VJoyBadge` | Generic semantic badges (status, category, counts) |
165
+ | `VJoyTag` | Removable or selectable chips, filters, skills |
166
+ | `VJoyTooltip` | Optional extra explanation when icon-only badges need clarification |