@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,204 @@
1
+ ---
2
+ component: VJoyFunnelHeader
3
+ status: draft
4
+ language: en
5
+ dsds: JoyFunnelHeader.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Funnel header
10
+
11
+ Use **`VJoyFunnelHeader`** when a full-page funnel needs a fixed top bar with branding on the left and actions on the right — typically inside **`VJoyFunnel`**’s `funnel-header` slot.
12
+
13
+ It is a slot-only layout primitive: no props, semantic `<header>`, and Joy spacing/background tokens. Compose with a logo or title on the left and a dismiss or utility control on the right.
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyFunnelHeader` 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) (subcomponent) |
20
+ | **DSDS (machine)** | [`JoyFunnelHeader.dsds.json`](./JoyFunnelHeader.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyFunnelHeader")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use a funnel header at the top of a guided, full-page flow — onboarding, registration, or multi-step wizards wrapped in `VJoyFunnel`. The left slot usually carries the product or partner logo; the right slot carries a single utility action such as close or help.
28
+
29
+ Place it in `VJoyFunnel`’s `funnel-header` slot so it sits above the stepper (when present) and scrollable content. Pair with `VJoyTemplate` for the main body and `VJoyFunnelFooter` for step navigation when needed.
30
+
31
+ ### When not to use this component
32
+
33
+ | Need | Use instead |
34
+ | --- | --- |
35
+ | Full funnel shell (shapes, stepper area, scrollable content) | `VJoyFunnel` |
36
+ | Page title, subtitle, and main layout inside the funnel | `VJoyTemplate` |
37
+ | Step navigation (Previous / Next) at the bottom of a step | `VJoyFunnelFooter` |
38
+ | App-wide or dashboard top navigation | App shell patterns — not funnel chrome |
39
+ | Dialog or drawer title bar | `VJoyDialog` / `VJoyDrawer` header slots |
40
+ | Custom `<header>` + manual flex for the same job | Still use `VJoyFunnelHeader` + Joy tokens |
41
+
42
+ > **Renamed:** `VJoyHeader` is now **`VJoyFunnelHeader`**. Slots are prefixed with `funnel-` (`funnel-header-left`, `funnel-header-right`). Update legacy `header-left` / `header-right` slot names.
43
+
44
+ ---
45
+
46
+ ## How it works
47
+
48
+ ### Anatomy
49
+
50
+ | Part | Required? | What it is |
51
+ | --- | --- | --- |
52
+ | Root `<header>` | Yes | `.joy-funnel-header` — full-width flex row, neutral background |
53
+ | Left slot | No* | `funnel-header-left` — logo, wordmark, or back affordance |
54
+ | Right slot | No* | `funnel-header-right` — close, help, or secondary utility |
55
+ | Background | Yes | `--funnel-header-background-color` → `--joy-color-neutral-0` |
56
+ | Horizontal padding | Yes | `--joy-core-spacing-5` left and right |
57
+ | Vertical padding | Yes | `--joy-core-spacing-4` top and bottom |
58
+
59
+ \*At least one slot should carry meaningful content in product flows (typically both).
60
+
61
+ ### Default values
62
+
63
+ `VJoyFunnelHeader` exposes **no props** and **no events**.
64
+
65
+ - Background token: **`--joy-color-neutral-0`**
66
+ - Horizontal padding: **`--joy-core-spacing-5`**
67
+ - Vertical padding: **`--joy-core-spacing-4`**
68
+ - Layout: **`display: flex`**, **`justify-content: space-between`**, **`align-items: center`**, **`width: 100%`**
69
+
70
+ Slots: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
71
+
72
+ ### Composition pattern
73
+
74
+ Nest inside `VJoyFunnel` and fill both slots with focused content — avoid crowding the bar with long titles (those belong in `VJoyTemplate`).
75
+
76
+ ```vue
77
+ <VJoyFunnel>
78
+ <template #funnel-header>
79
+ <VJoyFunnelHeader>
80
+ <template #funnel-header-left>
81
+ <img src="/logo.svg" alt="Malt" height="36" />
82
+ </template>
83
+ <template #funnel-header-right>
84
+ <VJoyIconButton label="Close funnel" icon="cross" size="small" variant="ghost" />
85
+ </template>
86
+ </VJoyFunnelHeader>
87
+ </template>
88
+ <!-- funnel body -->
89
+ </VJoyFunnel>
90
+ ```
91
+
92
+ ---
93
+
94
+ ## Best practices
95
+
96
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
97
+
98
+ ### Structure
99
+
100
+ - **MUST** place `VJoyFunnelHeader` inside `VJoyFunnel`’s **`funnel-header`** slot — not floating outside the funnel shell.
101
+ - **SHOULD** keep the left slot to **one** branding element (logo or compact wordmark).
102
+ - **SHOULD** keep the right slot to **one** primary utility action (usually close).
103
+ - **MUST NOT** put the funnel step title or long copy in the header bar — use `VJoyTemplate` title/subtitle slots.
104
+
105
+ ### Implementation
106
+
107
+ - **MUST** use the documented slot names: **`funnel-header-left`** and **`funnel-header-right`**.
108
+ - **MUST NOT** invent props on `VJoyFunnelHeader` — the API is slot-only.
109
+ - **MUST NOT** override `.joy-funnel-header` padding, background, or flex layout with product CSS.
110
+ - **SHOULD** use `VJoyIconButton` with a clear **`label`** for icon-only header actions (e.g. close).
111
+ - **SHOULD** give logo images a meaningful **`alt`** (or `alt=""` when decorative and redundant with page title).
112
+
113
+ ### Do / don’t
114
+
115
+ | Do | Don’t |
116
+ | --- | --- |
117
+ | Logo left, close right | Multiple competing actions in the right slot |
118
+ | `VJoyIconButton` with `label` for close | Icon-only button without accessible name |
119
+ | Funnel title in `VJoyTemplate` | Long headings inside the header bar |
120
+ | Joy tokens via the component | Custom sticky header markup duplicating funnel chrome |
121
+
122
+ ---
123
+
124
+ ## Accessibility
125
+
126
+ `VJoyFunnelHeader` renders a semantic **`<header>`** but does not supply landmarks beyond that — naming and keyboard behavior come from slot content.
127
+
128
+ | Behavior | Expectation |
129
+ | --- | --- |
130
+ | Landmark | Native `<header>` inside the funnel page structure |
131
+ | Branding | Logo `alt` text or visible text must identify the product when the image conveys branding |
132
+ | Actions | Interactive controls in slots **MUST** have accessible names (`label` on `VJoyIconButton`, visible text on links) |
133
+ | Focus | Tab order follows slot content; close should be reachable early when it exits the flow |
134
+ | Page title | Funnel step title in `VJoyTemplate` provides the main heading — don’t rely on the header bar alone |
135
+
136
+ Target: **WCAG 2.2 AA** where the product requires it — meet requirements through labeled controls and proper heading structure in the funnel body.
137
+
138
+ ---
139
+
140
+ ## Examples
141
+
142
+ ```vue
143
+ <script setup lang="ts">
144
+ import {
145
+ VJoyFunnel,
146
+ VJoyFunnelHeader,
147
+ VJoyFunnelFooter,
148
+ VJoyIconButton,
149
+ VJoyButton,
150
+ VJoyTemplate,
151
+ } from '@maltjoy/core-vue'
152
+ </script>
153
+
154
+ <template>
155
+ <VJoyFunnel>
156
+ <template #funnel-header>
157
+ <VJoyFunnelHeader>
158
+ <template #funnel-header-left>
159
+ <img src="/logo.svg" alt="Malt" height="36" />
160
+ </template>
161
+ <template #funnel-header-right>
162
+ <VJoyIconButton
163
+ label="Close funnel"
164
+ icon="cross"
165
+ size="small"
166
+ variant="ghost"
167
+ />
168
+ </template>
169
+ </VJoyFunnelHeader>
170
+ </template>
171
+
172
+ <VJoyTemplate>
173
+ <template #template-title>Create your account</template>
174
+ <template #template-subtitle>Step 1 of 3</template>
175
+ <template #template-main>
176
+ <!-- step content -->
177
+ <VJoyFunnelFooter>
178
+ <template #footer-left>
179
+ <VJoyButton label="Previous" size="small" variant="secondary" />
180
+ </template>
181
+ <template #footer-right>
182
+ <VJoyButton label="Next" size="small" variant="main" />
183
+ </template>
184
+ </VJoyFunnelFooter>
185
+ </template>
186
+ </VJoyTemplate>
187
+ </VJoyFunnel>
188
+ </template>
189
+ ```
190
+
191
+ In Nuxt (or apps with auto-import), omit the import if `VJoyFunnelHeader` is already global.
192
+
193
+ ---
194
+
195
+ ## Related
196
+
197
+ | Component | Use when |
198
+ | --- | --- |
199
+ | `VJoyFunnel` | Parent shell — provides `funnel-header`, stepper, and scrollable content slots |
200
+ | `VJoyFunnelFooter` | Bottom bar for Previous / Next or secondary actions inside a step |
201
+ | `VJoyTemplate` | Funnel step title, subtitle, main content, and optional sidebar |
202
+ | `VJoyIconButton` | Icon-only close or help control in `funnel-header-right` |
203
+ | `VJoyStepper` | Progress indicator in `VJoyFunnel`’s `funnel-stepper` slot (when used) |
204
+ | `VJoyButton` | Text actions in the footer — not typically in the header bar |
@@ -0,0 +1,169 @@
1
+ ---
2
+ component: VJoyHighlight
3
+ status: draft
4
+ language: en
5
+ dsds: JoyHighlight.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Highlight
10
+
11
+ Use **`VJoyHighlight`** when you need **inline, persistent** contextual messaging on the page — helper text, validation summaries, success confirmations, or warnings the user should read while continuing their task.
12
+
13
+ It supports semantic **levels** (success, info, warning, error, neutral), an optional left accent border, optional status icon, and an optional bold title above the body copy.
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyHighlight` from `@maltjoy/core-vue` |
18
+ | **Design** | [ZeroHeight — Highlight](https://zeroheight.com/6bf479565/) (page id `2432739`) |
19
+ | **Storybook** | [VJoyHighlight docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-view-vjoyhighlight--docs) |
20
+ | **DSDS (machine)** | [`JoyHighlight.dsds.json`](./JoyHighlight.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyHighlight")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use a highlight when information should **stay visible in context** — for example a form section error, a policy reminder above a field group, a success note after a partial save, or a warning that does not block the whole page.
28
+
29
+ Pick the **`level`** to match meaning (not decoration): `error` for blocking issues, `warning` for caution, `success` for positive outcomes, `info` for neutral guidance, `neutral` for low-emphasis notes.
30
+
31
+ Turn on **`accent`** when the message needs extra visual weight (thick left border). Turn on **`displayIcon`** when the status should be scannable at a glance; override with **`icon`** only when the default level icon is misleading.
32
+
33
+ ### When not to use this component
34
+
35
+ | Need | Use instead |
36
+ | --- | --- |
37
+ | Brief feedback after an action (auto-dismiss) | `pushVJoySnackbar` |
38
+ | Blocking confirmation or multi-step decision | `VJoyDialog` |
39
+ | Supplementary hint on hover/click for one control | `VJoyTooltip` |
40
+ | Field-level error tied to a single input | `VJoyFormError` (or highlight + `VJoyFormGroup` for section-level) |
41
+ | Custom banner / callout markup with ad-hoc CSS | Still use `VJoyHighlight` + Joy tokens |
42
+
43
+ > **Experimental:** `variant="ai"` overrides `level` styling for AI-related content. Treat as unstable — confirm with design before shipping to production.
44
+
45
+ > **Not in the API:** `variant="default"` has **no effect** (it only exists as the prop default). Do not rely on it for styling.
46
+
47
+ ---
48
+
49
+ ## How it works
50
+
51
+ ### Anatomy
52
+
53
+ | Part | Required? | What it is |
54
+ | --- | --- | --- |
55
+ | Root container | Yes | Flex row with level/variant classes (`joy-highlight`, `joy-highlight_{level}`) |
56
+ | Decorator | No | `highlight-decorator` slot; defaults to `VJoyIcon` when `displayIcon` is true |
57
+ | Title | No | `highlight-title` slot — rendered in `<strong>` above the body |
58
+ | Body (default slot) | Yes | Main message; may include links (`<a>`) |
59
+ | Accent border | No | 7px left border when `accent` is true |
60
+
61
+ ### Default values
62
+
63
+ - `level` defaults to **`neutral`**
64
+ - `variant` defaults to **`default`** (no visual effect — use `ai` only for the experimental AI theme)
65
+ - `accent` defaults to **`false`**
66
+ - `displayIcon` defaults to **`false`**
67
+ - `icon` has no default — when omitted and `displayIcon` is true, the icon comes from `level` (`success` → `check-circle`, `error` → `warning-triangle`, others → `info-circle`)
68
+
69
+ Props and slots: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
70
+
71
+ ### Levels (semantic emphasis)
72
+
73
+ | `level` | Use when |
74
+ | --- | --- |
75
+ | `error` | Something failed or must be fixed before continuing |
76
+ | `warning` | Non-blocking risk or condition the user should notice |
77
+ | `success` | A positive outcome or completed step |
78
+ | `info` | Neutral guidance or contextual detail |
79
+ | `neutral` | Low-emphasis note without a strong status color |
80
+
81
+ ---
82
+
83
+ ## Best practices
84
+
85
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
86
+
87
+ ### Hierarchy and meaning
88
+
89
+ - **MUST** choose `level` by **meaning**, not by preferred color.
90
+ - **SHOULD** use one highlight per logical section — avoid stacking multiple highlights with the same level.
91
+ - **SHOULD** use `accent` sparingly; reserve it for the primary message in a view.
92
+ - **SHOULD** use `highlight-title` for a short headline and keep detail in the default slot.
93
+
94
+ ### Implementation
95
+
96
+ - **MUST** use only documented props and enums from MCP or `JoyHighlight.types.ts`.
97
+ - **MUST** use Joy tokens — no custom `.joy-highlight` background, border, or typography in product CSS.
98
+ - **MUST NOT** invent props (`size`, `color`, `closable`, …).
99
+ - **MUST** set `displayIcon` to `true` before `icon` has any effect.
100
+ - **SHOULD** use the `highlight-decorator` slot for custom leading UI (e.g. AI tag) instead of hacking margins on the default icon.
101
+
102
+ ### Do / don’t
103
+
104
+ | Do | Don’t |
105
+ | --- | --- |
106
+ | `level="error"` for section-level validation | `pushVJoySnackbar` for errors that block the form |
107
+ | `accent` on the main callout in a panel | Accent on every helper line |
108
+ | Links in the default slot for “learn more” | Essential instructions only inside a snackbar |
109
+ | `variant="ai"` after design sign-off | `variant="ai"` as a generic purple info box |
110
+
111
+ ---
112
+
113
+ ## Accessibility
114
+
115
+ Presentational container — no built-in interactive role. Meaning must come from the **content** you put in slots.
116
+
117
+ | Behavior | Expectation |
118
+ | --- | --- |
119
+ | Structure | Use `highlight-title` for a visible heading; body copy in the default slot |
120
+ | Links | Inline `<a>` elements receive Joy link styling; ensure link text is descriptive |
121
+ | Icons | When `displayIcon` is true, the message text should still convey status — don’t rely on icon color alone |
122
+ | Live regions | Highlights are **not** announced like toasts; for urgent errors, pair with field errors or page-level focus management |
123
+ | Motion | No enter/exit animation — content is always visible |
124
+
125
+ Target: **WCAG 2.2 AA** where the product requires it.
126
+
127
+ ---
128
+
129
+ ## Examples
130
+
131
+ ```vue
132
+ <script setup lang="ts">
133
+ import { VJoyHighlight } from '@maltjoy/core-vue'
134
+ </script>
135
+
136
+ <template>
137
+ <!-- Section helper -->
138
+ <VJoyHighlight level="info">
139
+ Invoices are generated on the 1st of each month.
140
+ </VJoyHighlight>
141
+
142
+ <!-- Error with accent and icon -->
143
+ <VJoyHighlight level="error" accent display-icon>
144
+ <template #highlight-title>We couldn't save your changes</template>
145
+ Check your connection and try again, or
146
+ <a href="/support">contact support</a>.
147
+ </VJoyHighlight>
148
+
149
+ <!-- Success confirmation -->
150
+ <VJoyHighlight level="success" display-icon>
151
+ Your profile was updated.
152
+ </VJoyHighlight>
153
+ </template>
154
+ ```
155
+
156
+ In Nuxt (or apps with auto-import), omit the import if `VJoyHighlight` is already global.
157
+
158
+ ---
159
+
160
+ ## Related
161
+
162
+ | Component | Use when |
163
+ | --- | --- |
164
+ | `pushVJoySnackbar` | Transient feedback after an action |
165
+ | `VJoyFormError` | Single field error message under an input |
166
+ | `VJoyFormGroup` | Group label + control + errors; pair with highlight for section context |
167
+ | `VJoyDialog` | User must confirm, read long content, or choose an action |
168
+ | `VJoyTooltip` | Short supplementary hint on a single trigger |
169
+ | `VJoyTag` | Labels inside `highlight-decorator` (e.g. AI variant in Storybook) |
@@ -3,6 +3,6 @@ import {TSizes, TLevels} from '../../types';
3
3
 
4
4
  export type TJoyIconsColors = TLevels | 'neutral-50' | 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'brand-primary' | 'brand-secondary' | 'white';
5
5
 
6
- export type TJoyIconSizes = Extract<TSizes, 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge'>;
6
+ export type TJoyIconSizes = Extract<TSizes, 'xxsmall' | 'xsmall' | 'small' | 'medium' | 'large'>;
7
7
 
8
8
  export type TJoyIconsNames = JoyIconsId;
@@ -0,0 +1,168 @@
1
+ ---
2
+ component: VJoyIcon
3
+ status: draft
4
+ language: en
5
+ dsds: JoyIcon.dsds.json
6
+ dsdsVersion: "0.15.2"
7
+ ---
8
+
9
+ # Icon
10
+
11
+ Use **`VJoyIcon`** when you need a glyph from the Joy icon library — decorative emphasis beside text, status indicators, or inline affordances inside other components.
12
+
13
+ It supports token-based `color` and `size`, and optional `role="button"` with `ariaLabel` / `title` when the icon itself is interactive (rare — prefer `VJoyIconButton` for icon-only actions).
14
+
15
+ | | |
16
+ | --- | --- |
17
+ | **Code** | `VJoyIcon` from `@maltjoy/core-vue` |
18
+ | **Design** | [Figma — Joy Core Design System](https://www.figma.com/design/jfndp2QBJGS9yeuWbeGuvD/) |
19
+ | **Storybook** | [VJoyIcon docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-icons-vjoyicon--docs) · [Available icons](https://doc.malt.tech/joy-storybook/?path=/docs/components-icons-available-icons--docs) |
20
+ | **DSDS (machine)** | [`JoyIcon.dsds.json`](./JoyIcon.dsds.json) |
21
+ | **Live API** | `joy_get_component_info("VJoyIcon")` |
22
+
23
+ ---
24
+
25
+ ## When to use this component
26
+
27
+ Use an icon when a small visual symbol reinforces meaning — next to a label, inside a list row, as a status glyph, or as the leading/trailing graphic on a `VJoyButton`.
28
+
29
+ `VJoyIcon` is the **primitive** for rendering Joy icons with consistent sizing and color tokens. Parent components (`VJoyButton`, `VJoyMenuItem`, `VJoyInput`, …) compose it internally; use it directly when building custom layouts that still need the Joy icon font.
30
+
31
+ ### When not to use this component
32
+
33
+ | Need | Use instead |
34
+ | --- | --- |
35
+ | Icon-only clickable control (toolbar, dialog close, etc.) | `VJoyIconButton` |
36
+ | Labeled action with optional icon | `VJoyButton` (`icon` prop) |
37
+ | Navigation styled as a link | `VJoyLink` |
38
+ | Brief help on hover for an icon control | `VJoyTooltip` wrapping `VJoyIconButton` |
39
+ | Custom `<i>` / SVG with ad-hoc font-size and color | Still use `VJoyIcon` + Joy tokens — don’t reinvent icon chrome |
40
+
41
+ ---
42
+
43
+ ## How it works
44
+
45
+ ### Anatomy
46
+
47
+ | Part | Required? | What it is |
48
+ | --- | --- | --- |
49
+ | Root `<span>` | Yes | `.joy-icon` with size and color modifier classes |
50
+ | Glyph `<i>` | Yes | `.icon.icon-{name}` from `@maltjoy/icons` (`aria-hidden="true"`) |
51
+ | Accessible name | No* | `aria-label` / `title` on the root when the icon is meaningful or interactive (*required when `role="button"`) |
52
+ | Button affordance | No | `joy-icon--button` when `role="button"` — pointer cursor and hover opacity |
53
+
54
+ The icon font is decorative by default. The inner `<i>` is always hidden from assistive tech; expose meaning via visible text nearby or via `ariaLabel` / `title` on the root when the icon carries information on its own.
55
+
56
+ ### Default values
57
+
58
+ - `name` is **required** — a `TJoyIconsNames` / `JoyIconsId` value (see Storybook “Available icons” or `@maltjoy/icons`)
59
+ - `color` defaults to **`secondary`**
60
+ - `size` defaults to **`xsmall`** (16px)
61
+ - `tabIndex` defaults to **`0`** (applied only when `role="button"`)
62
+ - `role`, `ariaLabel`, and `title` default to **unset**
63
+
64
+ **Sizes** (`TJoyIconSizes`): `xxsmall` (12px), `xsmall` (16px), `small` (24px), `medium` (32px), `large` (46px). Match sibling text or parent component density — don’t hardcode `font-size` in product CSS.
65
+
66
+ **Colors** (`TJoyIconsColors`): `primary`, `secondary`, `tertiary`, `quaternary`, `brand-primary`, `brand-secondary`, `white`, `success`, `error`, `info`, `warning`, `neutral`, `neutral-50`. Pick by semantic meaning (status, emphasis), not decoration alone.
67
+
68
+ Props: 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.
69
+
70
+ > **MCP drift:** some snapshots list `xlarge` as a size value. The current `TJoyIconSizes` and SCSS map only include `xxsmall` through `large`. Do not emit `xlarge`.
71
+
72
+ ---
73
+
74
+ ## Best practices
75
+
76
+ Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
77
+
78
+ ### When to use icons
79
+
80
+ - **SHOULD** pair icons with visible text when the meaning isn’t universally understood.
81
+ - **SHOULD** use semantic `color` for status (`success`, `error`, `warning`, `info`) — not arbitrary brand swatches.
82
+ - **MUST NOT** use a lone `VJoyIcon` as the only way to perform an action — use `VJoyIconButton` or `VJoyButton`.
83
+ - **MUST NOT** rely on `title` alone for critical information (tooltips are supplementary).
84
+
85
+ ### Implementation
86
+
87
+ - **MUST** pass a valid `name` from `TJoyIconsNames` / `JoyIconsId`.
88
+ - **MUST** use only documented `color` and `size` values (MCP / `JoyIcon.types.ts`).
89
+ - **MUST** style with Joy tokens — no custom `.joy-icon` `font-size` or `color` overrides.
90
+ - **MUST NOT** invent props (`variant`, `clickable`, `disabled`, …).
91
+ - **MUST** set `ariaLabel` (or `title`) when `role="button"`; wire keyboard activation in the parent if the icon is interactive.
92
+ - **SHOULD** leave `role` unset for purely decorative icons inside labeled controls.
93
+
94
+ ### Do / don’t
95
+
96
+ | Do | Don’t |
97
+ | --- | --- |
98
+ | `VJoyIcon` beside visible label text | Icon-only action without `VJoyIconButton` |
99
+ | `color="error"` for validation status | Random hex colors on `.icon` |
100
+ | `size="small"` to match `VJoyButton` icon density | Inline `style="font-size: 20px"` |
101
+ | `VJoyIconButton` for toolbar / close controls | `role="button"` on `VJoyIcon` without keyboard handler |
102
+ | Storybook “Available icons” for valid `name` values | Guessing icon slug strings |
103
+
104
+ ---
105
+
106
+ ## Accessibility
107
+
108
+ Behaviors (what must happen), not slogans.
109
+
110
+ | Behavior | Expectation |
111
+ | --- | --- |
112
+ | Role | Decorative by default (`<span>`); set `role="button"` only when the icon is intentionally interactive |
113
+ | Name | Inner glyph is `aria-hidden="true"`. Meaningful icons need `ariaLabel` or `title` on the root, or redundant visible text nearby |
114
+ | Keyboard | When `role="button"`, root receives `tabindex` (default `0`); parent must handle **Enter** / **Space** — the component does not emit click events |
115
+ | Focus | No built-in focus ring — interactive icons should live in `VJoyIconButton` or a proper button/link |
116
+ | Color | Status colors supplement text; don’t convey state by color alone |
117
+ | Tooltip | `title` mirrors `ariaLabel` when one is set; for icon-only controls prefer `VJoyIconButton` + `VJoyTooltip` |
118
+
119
+ Target: **WCAG 2.2 AA** where the product requires it.
120
+
121
+ ---
122
+
123
+ ## Examples
124
+
125
+ ```vue
126
+ <script setup lang="ts">
127
+ import { VJoyIcon } from '@maltjoy/core-vue'
128
+ </script>
129
+
130
+ <template>
131
+ <!-- Decorative — meaning from adjacent text -->
132
+ <span>
133
+ <VJoyIcon name="check-circle" color="success" size="small" />
134
+ Payment confirmed
135
+ </span>
136
+
137
+ <!-- Status glyph inside custom layout -->
138
+ <VJoyIcon name="warning-triangle" color="warning" size="xsmall" />
139
+
140
+ <!-- Inside a button — prefer VJoyButton icon prop when possible -->
141
+ <!-- <VJoyButton icon="add-circle" label="Add item" /> -->
142
+
143
+ <!-- Rare: interactive icon (parent handles @click / keyboard) -->
144
+ <VJoyIcon
145
+ name="close"
146
+ role="button"
147
+ aria-label="Remove filter"
148
+ size="small"
149
+ @click="onRemove"
150
+ />
151
+ </template>
152
+ ```
153
+
154
+ In Nuxt (or apps with auto-import), omit the import if `VJoyIcon` is already global.
155
+
156
+ ---
157
+
158
+ ## Related
159
+
160
+ | Component | Use when |
161
+ | --- | --- |
162
+ | `VJoyIconButton` | Icon-only clickable control with button chrome and focus ring |
163
+ | `VJoyButton` | Labeled action with optional leading/trailing icon |
164
+ | `VJoyTooltip` | Supplementary label on hover/click for icon controls |
165
+ | `VJoyMenuItem` | Navigation row with optional leading icon |
166
+ | `VJoyInput` | Text field with optional leading `icon` prop |
167
+ | `VJoyHighlight` | Status message block — icons are composed internally |
168
+ | `@maltjoy/icons` | Source of truth for icon `name` values (`JoyIconsId`) |
@@ -12,7 +12,6 @@
12
12
  "description": "Use `TJoyIconSizes`",
13
13
  "possibleValues": [
14
14
  "medium",
15
- "xlarge",
16
15
  "large",
17
16
  "small",
18
17
  "xsmall",