@maltjoy/mcp-server 0.4.0 → 0.6.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +30 -3
- package/dist/doc/VJoyAdminBanner/guideline.md +284 -0
- package/dist/doc/VJoyAvailability/guideline.md +352 -0
- package/dist/doc/VJoyAvatar/guideline.md +192 -0
- package/dist/doc/VJoyAvatarsList/guideline.md +328 -0
- package/dist/doc/VJoyBadge/guideline.md +169 -0
- package/dist/doc/VJoyBadgeLevel/guideline.md +166 -0
- package/dist/doc/VJoyBlockSkeleton/guideline.md +150 -0
- package/dist/doc/VJoyBottomSheet/guideline.md +345 -0
- package/dist/doc/VJoyBottomSheetTrigger/guideline.md +156 -0
- package/dist/doc/VJoyButton/guideline.md +371 -0
- package/dist/doc/VJoyButton/metadata.json +0 -16
- package/dist/doc/VJoyButtonCard/guideline.md +384 -0
- package/dist/doc/VJoyCheckbox/guideline.md +317 -0
- package/dist/doc/VJoyCheckboxCard/guideline.md +381 -0
- package/dist/doc/VJoyCheckboxGroup/guideline.md +363 -0
- package/dist/doc/VJoyCheckboxGroup/metadata.json +7 -7
- package/dist/doc/VJoyCollapse/guideline.md +362 -0
- package/dist/doc/VJoyCollapseItem/guideline.md +394 -0
- package/dist/doc/VJoyCompanyAvatar/guideline.md +162 -0
- package/dist/doc/VJoyDialog/guideline.md +425 -0
- package/dist/doc/VJoyDialogTrigger/guideline.md +186 -0
- package/dist/doc/VJoyDot/guideline.md +177 -0
- package/dist/doc/VJoyDrawer/guideline.md +392 -0
- package/dist/doc/VJoyDrawerTrigger/guideline.md +145 -0
- package/dist/doc/VJoyDropdown/guideline.md +393 -0
- package/dist/doc/VJoyDropdown/metadata.json +6 -6
- package/dist/doc/VJoyDropdownList/guideline.md +396 -0
- package/dist/doc/VJoyDropdownList/metadata.json +7 -7
- package/dist/doc/VJoyDropzone/guideline.md +390 -0
- package/dist/doc/VJoyDropzone/metadata.json +36 -1
- package/dist/doc/VJoyFilterBar/guideline.md +419 -0
- package/dist/doc/VJoyFilterBarButton/guideline.md +359 -0
- package/dist/doc/VJoyFloatingActionsBar/guideline.md +372 -0
- package/dist/doc/VJoyFormError/guideline.md +325 -0
- package/dist/doc/VJoyFormError/metadata.json +0 -14
- package/dist/doc/VJoyFormFieldSkeleton/guideline.md +159 -0
- package/dist/doc/VJoyFormGroup/guideline.md +285 -0
- package/dist/doc/VJoyFunnel/guideline.md +349 -0
- package/dist/doc/VJoyFunnelFooter/guideline.md +178 -0
- package/dist/doc/VJoyFunnelHeader/guideline.md +204 -0
- package/dist/doc/VJoyHighlight/guideline.md +169 -0
- package/dist/doc/VJoyIcon/JoyIcon.types.ts +1 -1
- package/dist/doc/VJoyIcon/guideline.md +168 -0
- package/dist/doc/VJoyIcon/metadata.json +0 -1
- package/dist/doc/VJoyIconButton/guideline.md +169 -0
- package/dist/doc/VJoyIconButton/metadata.json +1 -1
- package/dist/doc/VJoyIndicator/guideline.md +168 -0
- package/dist/doc/VJoyIndicators/guideline.md +183 -0
- package/dist/doc/VJoyInput/JoyInput.types.ts +1 -6
- package/dist/doc/VJoyInput/guideline.md +401 -0
- package/dist/doc/VJoyInput/metadata.json +5 -14
- package/dist/doc/VJoyInputDigit/guideline.md +381 -0
- package/dist/doc/VJoyInputNumber/guideline.md +414 -0
- package/dist/doc/VJoyInputNumber/metadata.json +22 -17
- package/dist/doc/VJoyInputPassword/guideline.md +379 -0
- package/dist/doc/VJoyInputPassword/metadata.json +0 -14
- package/dist/doc/VJoyLabel/guideline.md +200 -0
- package/dist/doc/VJoyLink/guideline.md +360 -0
- package/dist/doc/VJoyListItem/guideline.md +335 -0
- package/dist/doc/VJoyMenu/guideline.md +304 -0
- package/dist/doc/VJoyMenu/metadata.json +21 -21
- package/dist/doc/VJoyMenuItem/guideline.md +352 -0
- package/dist/doc/VJoyPagination/guideline.md +355 -0
- package/dist/doc/VJoyPanel/guideline.md +238 -0
- package/dist/doc/VJoyPanelSection/guideline.md +160 -0
- package/dist/doc/VJoyPasswordRequirement/guideline.md +336 -0
- package/dist/doc/VJoyPasswordRequirement/metadata.json +1 -1
- package/dist/doc/VJoyProductTour/JoyProductTour.types.ts +0 -1
- package/dist/doc/VJoyProductTour/guideline.md +455 -0
- package/dist/doc/VJoyProductTour/metadata.json +1 -1
- package/dist/doc/VJoyProductTourTrigger/guideline.md +167 -0
- package/dist/doc/VJoyProgressBar/guideline.md +348 -0
- package/dist/doc/VJoyRadio/guideline.md +346 -0
- package/dist/doc/VJoyRadioGroup/guideline.md +331 -0
- package/dist/doc/VJoyRatingStars/guideline.md +306 -0
- package/dist/doc/VJoyScreenLoader/guideline.md +172 -0
- package/dist/doc/VJoySelect/guideline.md +396 -0
- package/dist/doc/VJoySelectableItem/guideline.md +351 -0
- package/dist/doc/VJoySelectableItemGroup/guideline.md +370 -0
- package/dist/doc/VJoySeparator/guideline.md +161 -0
- package/dist/doc/VJoySnackbar/guideline.md +402 -0
- package/dist/doc/VJoySpinner/guideline.md +168 -0
- package/dist/doc/VJoyStep/guideline.md +182 -0
- package/dist/doc/VJoyStepper/guideline.md +390 -0
- package/dist/doc/VJoyTab/guideline.md +298 -0
- package/dist/doc/VJoyTabs/guideline.md +353 -0
- package/dist/doc/VJoyTag/guideline.md +226 -0
- package/dist/doc/VJoyTagsInput/guideline.md +387 -0
- package/dist/doc/VJoyTagsList/guideline.md +311 -0
- package/dist/doc/VJoyTagsList/metadata.json +27 -27
- package/dist/doc/VJoyTemplate/guideline.md +366 -0
- package/dist/doc/VJoyText/guideline.md +175 -0
- package/dist/doc/VJoyText/metadata.json +1 -1
- package/dist/doc/VJoyTextarea/guideline.md +378 -0
- package/dist/doc/VJoyTitleBrand/guideline.md +155 -0
- package/dist/doc/VJoyToggle/guideline.md +327 -0
- package/dist/doc/VJoyTooltip/guideline.md +322 -0
- package/dist/doc/VJoyUserCard/guideline.md +268 -0
- package/dist/doc/VJoyUserCard/metadata.json +3 -17
- package/dist/doc/VJoyWalkthrough/guideline.md +351 -0
- package/dist/doc/VJoyWalkthroughTrigger/guideline.md +171 -0
- package/dist/doc/VJoyWrapper/guideline.md +173 -0
- package/dist/doc/css-classes.json +1 -15
- package/dist/doc/design-tokens.json +1 -0
- package/dist/doc/index.json +20 -30
- package/dist/index.js +22 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/get-component-guideline.d.ts +30 -0
- package/dist/tools/get-component-guideline.d.ts.map +1 -0
- package/dist/tools/get-component-guideline.js +51 -0
- package/dist/tools/get-component-guideline.js.map +1 -0
- package/dist/tools/get-documentation-page.d.ts +22 -0
- package/dist/tools/get-documentation-page.d.ts.map +1 -0
- package/dist/tools/get-documentation-page.js +21 -0
- package/dist/tools/get-documentation-page.js.map +1 -0
- package/dist/tools/list-documentation-pages.d.ts +22 -0
- package/dist/tools/list-documentation-pages.d.ts.map +1 -0
- package/dist/tools/list-documentation-pages.js +17 -0
- package/dist/tools/list-documentation-pages.js.map +1 -0
- package/dist/tools/search-documentation.d.ts +41 -0
- package/dist/tools/search-documentation.d.ts.map +1 -0
- package/dist/tools/search-documentation.js +25 -0
- package/dist/tools/search-documentation.js.map +1 -0
- package/dist/zeroheight-parser.d.ts +27 -0
- package/dist/zeroheight-parser.d.ts.map +1 -0
- package/dist/zeroheight-parser.js +77 -0
- package/dist/zeroheight-parser.js.map +1 -0
- package/package.json +10 -10
- package/dist/doc/VJoyMultiCheckbox/metadata.json +0 -332
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
---
|
|
2
|
+
component: VJoyFilterBarButton
|
|
3
|
+
status: draft
|
|
4
|
+
language: en
|
|
5
|
+
dsds: JoyFilterBarButton.dsds.json
|
|
6
|
+
dsdsVersion: "0.15.2"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Filter bar button
|
|
10
|
+
|
|
11
|
+
Use **`VJoyFilterBarButton`** when the user needs a segmented control inside a filter bar — a compact button that represents one filter dimension (status, location, category) and can open a panel or toggle filter state.
|
|
12
|
+
|
|
13
|
+
It renders a native `<button>` with Joy filter-bar styling, an optional `label`, a required `value` identifier, and an `active` state you control from the parent. Inside `VJoyDropdown`, it automatically shows a chevron-down icon. Use the default slot for extras such as a `VJoyTag` with the number of applied filters.
|
|
14
|
+
|
|
15
|
+
| | |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **Code** | `VJoyFilterBarButton` from `@maltjoy/core-vue` |
|
|
18
|
+
| **Design** | [Joy — Filter Bar](https://zeroheight.com/6bf479565/) (page id `4675975`) |
|
|
19
|
+
| **Storybook** | [VJoyFilterBar docs](https://doc.malt.tech/joy-storybook/?path=/docs/components-forms-vjoyfilterbar--docs) (subcomponent) |
|
|
20
|
+
| **DSDS (machine)** | [`JoyFilterBarButton.dsds.json`](./JoyFilterBarButton.dsds.json) |
|
|
21
|
+
| **Live API** | `joy_get_component_info("VJoyFilterBarButton")` |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## When to use this component
|
|
26
|
+
|
|
27
|
+
Use a filter bar button when building **grouped filter UIs** — typically inside `VJoyFilterBar` — where each segment represents a filter category the user can interact with. Common jobs: opening a dropdown of checkboxes (`VJoyDropdown` + `VJoyCheckboxGroup`), showing how many values are applied via a tag, or switching which filter panel is active in a simple segmented control.
|
|
28
|
+
|
|
29
|
+
The parent owns filter state. Set `active` when that dimension has applied values or should read as selected; listen to `@filter` when you need the `value` identifier on click (for example toggling panels in a custom filter bar).
|
|
30
|
+
|
|
31
|
+
### When not to use this component
|
|
32
|
+
|
|
33
|
+
| Need | Use instead |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| A general-purpose action (Save, Cancel, Submit) | `VJoyButton` |
|
|
36
|
+
| Icon-only control with no filter label | `VJoyIconButton` |
|
|
37
|
+
| Single labeled form field with native select semantics | `VJoySelect` |
|
|
38
|
+
| Standalone toggle on/off for one setting | `VJoyToggle` |
|
|
39
|
+
| Filter chips outside a connected filter-bar group | `VJoyTag` (selectable) or confirm with design |
|
|
40
|
+
| Custom segmented `<button>` styling in a filter row | Still use `VJoyFilterBarButton` inside `VJoyFilterBar` + Joy tokens |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## How it works
|
|
45
|
+
|
|
46
|
+
### Anatomy
|
|
47
|
+
|
|
48
|
+
| Part | Required? | What it is |
|
|
49
|
+
| --- | --- | --- |
|
|
50
|
+
| Root `<button>` | Yes | `type="button"`, class `joy-filter-bar-button`, `data-joy-form-field` |
|
|
51
|
+
| Label text | Yes* | `label` prop (*or meaningful content in the default slot) |
|
|
52
|
+
| `value` identifier | Yes | Stable string sent with the `filter` event — identifies this filter dimension |
|
|
53
|
+
| Default slot | No | Extra inline content (e.g. `VJoyTag` with selection count) |
|
|
54
|
+
| Chevron icon | No | `VJoyIcon` (`chevron-down`) when the button is rendered inside `VJoyDropdown` |
|
|
55
|
+
| Focus / hover chrome | Yes | Border and background from Joy tokens — do not remove in product CSS |
|
|
56
|
+
|
|
57
|
+
`VJoyFilterBar` wraps siblings and applies connected border radius and overlap (`margin-left: -1px`) so segments read as one control. Place each button (or `VJoyDropdown` wrapping a button) as a direct child of `VJoyFilterBar`.
|
|
58
|
+
|
|
59
|
+
### Default values
|
|
60
|
+
|
|
61
|
+
- `active` defaults to **`false`**
|
|
62
|
+
- `label` is optional (string) — prefer setting it for an accessible name
|
|
63
|
+
- `value` is **required** (string)
|
|
64
|
+
|
|
65
|
+
Props, events, and slots: use Joy MCP or Storybook — this page focuses on **when** and **how**, not a full API dump.
|
|
66
|
+
|
|
67
|
+
### Visual treatment
|
|
68
|
+
|
|
69
|
+
There is **no `variant` or `size` prop**. Height, border, padding, and colors come from component CSS (`--button-height: 40px`, Joy neutral/secondary tokens) — **don’t hardcode filter-button height or border colors** in apps.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## States
|
|
74
|
+
|
|
75
|
+
| State | What the user sees / can do |
|
|
76
|
+
| --- | --- |
|
|
77
|
+
| Default (`active={false}`) | Neutral border and white background; label in neutral text color |
|
|
78
|
+
| Hover | Secondary border; pointer cursor |
|
|
79
|
+
| Focus | Secondary border, secondary-tinted background, elevated `z-index` — keep visible for keyboard users |
|
|
80
|
+
| Active (`active={true}`) | Same as focus styling — use when this filter has applied values or should read as selected |
|
|
81
|
+
| With dropdown chevron | Chevron appears automatically when the button is a child of `VJoyDropdown` (via `VJoyDropdownContext`) |
|
|
82
|
+
| With selection tag | Default slot content (e.g. `VJoyTag` with count) appears inline after the label |
|
|
83
|
+
|
|
84
|
+
`active` is **controlled by the parent** — the component does not compute applied filters. Typical pattern: `:active="Boolean(selectedValues.length)"` or `:active="selectedValues.length > 0"`.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Best practices
|
|
89
|
+
|
|
90
|
+
Rules use RFC 2119 strength (**MUST** / **SHOULD** / **MUST NOT** / **SHOULD NOT**).
|
|
91
|
+
|
|
92
|
+
### Composition
|
|
93
|
+
|
|
94
|
+
- **MUST** place filter bar buttons inside `VJoyFilterBar` so connected borders and corner radius apply correctly.
|
|
95
|
+
- **SHOULD** wrap a button in `VJoyDropdown` when the filter opens a panel of options (checkboxes, custom list).
|
|
96
|
+
- **SHOULD** set `aria-label` on the parent `VJoyFilterBar` when the group purpose isn’t obvious from page context.
|
|
97
|
+
- **MUST NOT** use `VJoyFilterBarButton` for non-filter primary actions — use `VJoyButton`.
|
|
98
|
+
|
|
99
|
+
### Implementation
|
|
100
|
+
|
|
101
|
+
- **MUST** pass a stable, unique `value` per filter dimension (e.g. `"continents"`, `"countries"`).
|
|
102
|
+
- **MUST** use only documented props from MCP or the component source.
|
|
103
|
+
- **MUST** style with Joy tokens — no custom `.joy-filter-bar-button` chrome (border, height, padding, radius).
|
|
104
|
+
- **MUST NOT** invent props (`variant`, `size`, `disabled` as a documented API, `icon`, …).
|
|
105
|
+
- **SHOULD** drive `active` from real filter state (applied selections), not from dropdown open/close alone unless that matches the design intent.
|
|
106
|
+
- **SHOULD** show applied count in the default slot with `VJoyTag` (`size="xsmall"`) when multiple values can be selected.
|
|
107
|
+
|
|
108
|
+
### Interaction
|
|
109
|
+
|
|
110
|
+
- **SHOULD** listen to `@filter` when the parent needs the clicked `value` (simple segmented bars without dropdown).
|
|
111
|
+
- **SHOULD** pair dropdown filters with `VJoyDropdown` reset behavior when users need to clear one dimension.
|
|
112
|
+
- **MUST** keep filter state in the parent (`v-model` on checkbox groups, reactive objects, etc.) — this button does not store selections.
|
|
113
|
+
|
|
114
|
+
### Do / don’t
|
|
115
|
+
|
|
116
|
+
| Do | Don’t |
|
|
117
|
+
| --- | --- |
|
|
118
|
+
| `VJoyFilterBar` + `VJoyFilterBarButton` | Lone custom-styled buttons pretending to be a filter bar |
|
|
119
|
+
| `:active` tied to applied filter values | Hard-coded `active` that never reflects state |
|
|
120
|
+
| `VJoyTag` in default slot for counts | Long text or paragraphs inside the button |
|
|
121
|
+
| `VJoyDropdown` for multi-select filter panels | `VJoySelect` disguised as a filter chip |
|
|
122
|
+
| Joy token styling | Hardcoded `40px` height or custom border colors |
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Content
|
|
127
|
+
|
|
128
|
+
Filter bar button labels name the **filter dimension** — what will be refined when the user opens or activates this segment. Keep labels short; put counts in a `VJoyTag`, not in the label string.
|
|
129
|
+
|
|
130
|
+
### Label formula
|
|
131
|
+
|
|
132
|
+
**Noun or short noun phrase** naming the dimension (English):
|
|
133
|
+
|
|
134
|
+
- ✅ Continents
|
|
135
|
+
- ✅ Countries
|
|
136
|
+
- ✅ Status
|
|
137
|
+
- ✅ Date range
|
|
138
|
+
|
|
139
|
+
Avoid action verbs on the chip itself — the control’s job is implied by the filter bar pattern.
|
|
140
|
+
|
|
141
|
+
### Writing rules
|
|
142
|
+
|
|
143
|
+
| Strength | Rule |
|
|
144
|
+
| --- | --- |
|
|
145
|
+
| **MUST** | Every button has a discernible name — `label` prop and/or slot content that screen readers can read |
|
|
146
|
+
| **MUST** | Label names the dimension, not the action — ✅ `Countries` · ❌ `Filter countries` |
|
|
147
|
+
| **MUST NOT** | Duplicate the count in the label when a `VJoyTag` already shows it — ✅ `Countries` + tag `3` · ❌ `Countries (3)` + tag `3` |
|
|
148
|
+
| **MUST NOT** | Use generic labels (`Filter`, `Options`, `More`) when a specific dimension exists |
|
|
149
|
+
| **SHOULD** | ≤ 20 characters for the primary label; abbreviate only when space is tight and meaning stays clear |
|
|
150
|
+
| **SHOULD** | Use parallel grammar across segments in the same bar (all nouns: `Status`, `Region`, `Owner`) |
|
|
151
|
+
| **SHOULD** | Match terminology with column headers or facet names elsewhere on the page |
|
|
152
|
+
| **SHOULD** (FR) | Use French grammar for labels and tags when the UI is localized |
|
|
153
|
+
|
|
154
|
+
### Patterns
|
|
155
|
+
|
|
156
|
+
**Simple segmented bar** — Several `VJoyFilterBarButton` siblings with distinct `value`s; parent sets `:active` on the current segment and handles `@filter`.
|
|
157
|
+
|
|
158
|
+
**Dropdown with multi-select** — `VJoyDropdown` → `dropdown-button` slot → `VJoyFilterBarButton` with `:active="selections.length > 0"` and optional `VJoyTag` showing `selections.length`. Options live in `dropdown-items` (e.g. `VJoyCheckboxGroup`).
|
|
159
|
+
|
|
160
|
+
**Toolbar row** — Compose `VJoyFilterBar` with `VJoyWrapper` alongside search (`VJoyInput`) and a global reset (`VJoyButton` `variant="ghost"`). See `VJoyFilterBar` Storybook **Advanced usage**.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Accessibility
|
|
165
|
+
|
|
166
|
+
Behaviors (what must happen), not slogans.
|
|
167
|
+
|
|
168
|
+
| Behavior | Expectation |
|
|
169
|
+
| --- | --- |
|
|
170
|
+
| Role | Native `<button type="button">` |
|
|
171
|
+
| Name | From `label` prop and/or default slot text; tag counts should not be the only name |
|
|
172
|
+
| Grouping | Parent `VJoyFilterBar` exposes `role="group"` with `aria-label` (default `"Filter bar"` — override with `ariaLabel` when needed) |
|
|
173
|
+
| Keyboard | **Enter** and **Space** activate the button; **Tab** moves between segments |
|
|
174
|
+
| Focus | Visible focus styling (secondary border + background) — do not remove in product CSS |
|
|
175
|
+
| Dropdown trigger | When inside `VJoyDropdown`, ensure the dropdown trigger remains focusable; set `aria-label` on icon-only or ambiguous triggers per `VJoyDropdown` guidance |
|
|
176
|
+
| State | `active` is visual only — expose applied filters in page content or live region if results change |
|
|
177
|
+
|
|
178
|
+
Target: **WCAG 2.2 AA** where the product requires it.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Examples
|
|
183
|
+
|
|
184
|
+
```vue
|
|
185
|
+
<script setup lang="ts">
|
|
186
|
+
import { reactive } from 'vue'
|
|
187
|
+
import {
|
|
188
|
+
VJoyFilterBar,
|
|
189
|
+
VJoyFilterBarButton,
|
|
190
|
+
VJoyDropdown,
|
|
191
|
+
VJoyCheckboxGroup,
|
|
192
|
+
VJoyTag,
|
|
193
|
+
VJoyButton,
|
|
194
|
+
VJoyInput,
|
|
195
|
+
VJoyWrapper,
|
|
196
|
+
} from '@maltjoy/core-vue'
|
|
197
|
+
|
|
198
|
+
const filters = reactive({
|
|
199
|
+
continents: [] as string[],
|
|
200
|
+
countries: [] as string[],
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
const continents = [
|
|
204
|
+
{ value: 'europe', label: 'Europe', id: 'europe' },
|
|
205
|
+
{ value: 'asia', label: 'Asia', id: 'asia' },
|
|
206
|
+
]
|
|
207
|
+
|
|
208
|
+
const countries = [
|
|
209
|
+
{ value: 'france', label: 'France', id: 'france' },
|
|
210
|
+
{ value: 'spain', label: 'Spain', id: 'spain' },
|
|
211
|
+
]
|
|
212
|
+
|
|
213
|
+
function resetAll() {
|
|
214
|
+
filters.continents = []
|
|
215
|
+
filters.countries = []
|
|
216
|
+
}
|
|
217
|
+
</script>
|
|
218
|
+
|
|
219
|
+
<template>
|
|
220
|
+
<!-- Simple segmented filters -->
|
|
221
|
+
<VJoyFilterBar aria-label="Project filters">
|
|
222
|
+
<VJoyFilterBarButton
|
|
223
|
+
value="open"
|
|
224
|
+
label="Open"
|
|
225
|
+
:active="true"
|
|
226
|
+
@filter="(id) => console.log('filter', id)"
|
|
227
|
+
/>
|
|
228
|
+
<VJoyFilterBarButton value="closed" label="Closed" />
|
|
229
|
+
<VJoyFilterBarButton value="archived" label="Archived" />
|
|
230
|
+
</VJoyFilterBar>
|
|
231
|
+
|
|
232
|
+
<!-- Dropdown filters with selection counts -->
|
|
233
|
+
<VJoyWrapper row-gap="4">
|
|
234
|
+
<VJoyFilterBar aria-label="Location filters">
|
|
235
|
+
<VJoyDropdown :reset="true" reset-label="Reset filter">
|
|
236
|
+
<template #dropdown-button>
|
|
237
|
+
<VJoyFilterBarButton
|
|
238
|
+
value="continents"
|
|
239
|
+
label="Continents"
|
|
240
|
+
:active="filters.continents.length > 0"
|
|
241
|
+
>
|
|
242
|
+
<VJoyTag
|
|
243
|
+
v-if="filters.continents.length"
|
|
244
|
+
size="xsmall"
|
|
245
|
+
value="continent-count"
|
|
246
|
+
:label="String(filters.continents.length)"
|
|
247
|
+
/>
|
|
248
|
+
</VJoyFilterBarButton>
|
|
249
|
+
</template>
|
|
250
|
+
<template #dropdown-items>
|
|
251
|
+
<VJoyCheckboxGroup v-model:value="filters.continents" :options="continents" />
|
|
252
|
+
</template>
|
|
253
|
+
</VJoyDropdown>
|
|
254
|
+
|
|
255
|
+
<VJoyDropdown :reset="true" reset-label="Reset filter">
|
|
256
|
+
<template #dropdown-button>
|
|
257
|
+
<VJoyFilterBarButton
|
|
258
|
+
value="countries"
|
|
259
|
+
label="Countries"
|
|
260
|
+
:active="filters.countries.length > 0"
|
|
261
|
+
>
|
|
262
|
+
<VJoyTag
|
|
263
|
+
v-if="filters.countries.length"
|
|
264
|
+
size="xsmall"
|
|
265
|
+
value="country-count"
|
|
266
|
+
:label="String(filters.countries.length)"
|
|
267
|
+
/>
|
|
268
|
+
</VJoyFilterBarButton>
|
|
269
|
+
</template>
|
|
270
|
+
<template #dropdown-items>
|
|
271
|
+
<VJoyCheckboxGroup v-model:value="filters.countries" :options="countries" />
|
|
272
|
+
</template>
|
|
273
|
+
</VJoyDropdown>
|
|
274
|
+
</VJoyFilterBar>
|
|
275
|
+
|
|
276
|
+
<VJoyButton variant="ghost" size="xsmall" label="Reset all filters" @click="resetAll" />
|
|
277
|
+
<VJoyInput
|
|
278
|
+
name="search"
|
|
279
|
+
size="small"
|
|
280
|
+
icon="search"
|
|
281
|
+
placeholder="Search locations…"
|
|
282
|
+
/>
|
|
283
|
+
</VJoyWrapper>
|
|
284
|
+
</template>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
In Nuxt (or apps with auto-import), omit the import if components are already global.
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Related
|
|
292
|
+
|
|
293
|
+
| Component | Use when |
|
|
294
|
+
| --- | --- |
|
|
295
|
+
| `VJoyFilterBar` | Container that connects segments with shared border radius |
|
|
296
|
+
| `VJoyDropdown` | Filter opens a panel of options; provides chevron on the button |
|
|
297
|
+
| `VJoyCheckboxGroup` | Multi-select values inside a filter dropdown |
|
|
298
|
+
| `VJoyTag` | Inline count of applied filters in the default slot |
|
|
299
|
+
| `VJoyInput` | Search field beside the filter bar in a toolbar |
|
|
300
|
+
| `VJoyButton` | Global reset or actions adjacent to filters (`ghost`, `xsmall`) |
|
|
301
|
+
| `VJoyWrapper` | Layout spacing for filter bar + search + actions |
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## For agents
|
|
306
|
+
|
|
307
|
+
Optional for readers; **required** for vibe-coding quality. Maps to `agentDocumentBlocks` in [`JoyFilterBarButton.dsds.json`](./JoyFilterBarButton.dsds.json).
|
|
308
|
+
|
|
309
|
+
### Pick the right component
|
|
310
|
+
|
|
311
|
+
| If the intent is… | Emit… | Do not emit… |
|
|
312
|
+
| --- | --- | --- |
|
|
313
|
+
| Segmented filter control in a filter bar | `VJoyFilterBarButton` inside `VJoyFilterBar` | `VJoyButton` with custom filter CSS |
|
|
314
|
+
| Filter opens checkbox / custom panel | `VJoyDropdown` + `VJoyFilterBarButton` in `dropdown-button` | Raw `VJoyButton` as dropdown trigger in a filter bar |
|
|
315
|
+
| Show count of applied filters | `VJoyTag` in default slot | Long label like `Countries (3)` |
|
|
316
|
+
| Primary page CTA | `VJoyButton` | `VJoyFilterBarButton` |
|
|
317
|
+
| Single form select field | `VJoySelect` | Filter bar button |
|
|
318
|
+
| Icon-only filter | `VJoyIconButton` + tooltip (rare) | Unlabeled `VJoyFilterBarButton` |
|
|
319
|
+
|
|
320
|
+
### Hard rules
|
|
321
|
+
|
|
322
|
+
1. **MUST** call `joy_get_component_info("VJoyFilterBarButton")` before generating props.
|
|
323
|
+
2. **MUST** set `value` on every instance (required prop).
|
|
324
|
+
3. **MUST** wrap segments in `VJoyFilterBar` for correct grouped styling.
|
|
325
|
+
4. **MUST NOT** invent props — there is no `variant`, `size`, or `icon` prop.
|
|
326
|
+
5. **MUST NOT** override `.joy-filter-bar-button` height, border, padding, or radius.
|
|
327
|
+
6. **MUST** control `active` from parent filter state.
|
|
328
|
+
7. **SHOULD** use `VJoyDropdown` when the filter reveals a list of options.
|
|
329
|
+
8. **SHOULD** use `VJoyTag` (`size="xsmall"`) for selection counts in the default slot.
|
|
330
|
+
|
|
331
|
+
### Checklist
|
|
332
|
+
|
|
333
|
+
- [ ] Correct component (`VJoyFilterBarButton` or named alternative)
|
|
334
|
+
- [ ] Inside `VJoyFilterBar` (unless design explicitly documents an exception)
|
|
335
|
+
- [ ] `value` set; `label` or meaningful slot content for accessible name
|
|
336
|
+
- [ ] `active` reflects applied filters (parent-controlled)
|
|
337
|
+
- [ ] Dropdown filters use `VJoyDropdown` + checkbox group or documented slot content
|
|
338
|
+
- [ ] No invented props / no custom filter-button chrome CSS
|
|
339
|
+
- [ ] `VJoyFilterBar` `aria-label` set when default is insufficient
|
|
340
|
+
- [ ] Counts in `VJoyTag`, not duplicated in `label`
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## DSDS mapping
|
|
345
|
+
|
|
346
|
+
This Markdown mirrors [`JoyFilterBarButton.dsds.json`](./JoyFilterBarButton.dsds.json) (DSDS **0.15.2**).
|
|
347
|
+
|
|
348
|
+
| Section here | DSDS block |
|
|
349
|
+
| --- | --- |
|
|
350
|
+
| When to use / not | `use-cases` |
|
|
351
|
+
| Anatomy | `anatomy` |
|
|
352
|
+
| States | `states` |
|
|
353
|
+
| Best practices / content rules | `guidelines` (+ `content`) |
|
|
354
|
+
| Accessibility | `accessibility` |
|
|
355
|
+
| Examples | `sections` |
|
|
356
|
+
| For agents | `agentDocumentBlocks` |
|
|
357
|
+
| Props detail | `api` in JSON + Joy MCP |
|
|
358
|
+
| Imports | `imports` in JSON |
|
|
359
|
+
| Token sizing | `design-specifications` in JSON (`--button-height`, Joy neutral/secondary colors) |
|