You signed in with another tab or window.Reload to refresh your session.You signed out in another tab or window.Reload to refresh your session.You switched accounts on another tab or window.Reload to refresh your session.Dismiss alert
fix(BToggle)! Remove redundant attribute cleanup & update docs for accessibility attributes on show/hide components (#2918)
* refactor(BToggle)!: delegate aria-expanded cleanup to composable* docs: document how we handle accessibility attributes wrt visibility* docs: create an architecture doc covering the work in this PR and update Copilot instructions---------Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: .github/copilot-instructions.md
+98-12Lines changed: 98 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,64 +5,73 @@ Always reference these instructions first and fallback to search or bash command
5
5
##Working Effectively
6
6
7
7
###Required Setup
8
+
8
9
- Install Node.js 20.x or 22.x (engine requires >=22.0.0 but 20.x works with warnings)
9
10
- Install pnpm globally:`npm install -g pnpm@10.13.1` (ONLY pnpm is allowed as package manager) Use the version specified in the packageManager field of the package.json file
10
11
- Clone repository and open the**root** directory (not subdirectories like packages/bootstrap-vue-next)
-`ARIA_VISIBILITY.md` - ARIA accessibility system for show/hide components
94
+
80
95
##Documentation Requirements
81
96
82
97
###Component Documentation (.data.ts files)
98
+
83
99
-**CRITICAL**: When adding/modifying component props, events, or slots, ALWAYS update the corresponding`.data.ts` file in`apps/docs/src/data/components/`
84
100
- Each component has a`.data.ts` file that defines:
85
101
-`props`: All component properties with types, defaults, and descriptions
-`pnpm --filter bootstrap-vue-next run build`:~27 seconds
148
+
-`pnpm --filter bootstrap-vue-next run build`:~27 seconds
128
149
-`pnpm --filter bootstrap-vue-next run test:unit:ci`:~40 seconds (1567 tests)
129
150
-`pnpm --filter bootstrap-vue-next run test:lint`:~12 seconds
130
151
-`pnpm --filter playground run build`:~8 seconds
131
152
-`pnpm --filter @bootstrap-vue-next/nuxt run build`:~25 seconds
132
153
133
154
###CRITICAL TIMEOUT WARNINGS
155
+
134
156
-**NEVER CANCEL** any build or test command
135
-
- Set timeouts to 60+ minutes for builds
157
+
- Set timeouts to 60+ minutes for builds
136
158
- Set timeouts to 60+ minutes for test suites
137
159
- Builds may take longer in CI environments
138
160
- Test suites run 1500+ tests and require time
139
161
140
162
##Known Issues and Workarounds
141
163
142
164
###Network-Related Build Failures
165
+
143
166
- Docs build fails due to OpenCollective API calls:**EXPECTED**
144
167
- Use`pnpm install --ignore-scripts` to skip problematic prepare scripts
145
168
- Filter builds to specific packages to avoid docs:`pnpm --filter bootstrap-vue-next run build`
146
169
147
170
###Engine Version Warnings
171
+
148
172
- Repository requires Node.js >=22.0.0 but works with 20.x (shows warnings)
149
173
- Warnings are safe to ignore during development
150
174
151
175
###Generated Files
176
+
152
177
-`*.timestamp-*` files are generated and should be ignored (already in .gitignore)
153
178
- VitePress generates temporary data files during build
154
179
155
180
##Package Manager Rules
181
+
156
182
-**ONLY pnpm is allowed** - npm and yarn will cause errors
157
183
- Use exact version`pnpm@10.13.1` for consistency
158
184
- Always use`--frozen-lockfile` for reproducible installs
159
185
- Use workspace filters:`--filter <package-name>` for targeted operations
160
186
161
187
##Conventional Commits
188
+
162
189
- Use conventional commit format:`feat:`,`fix:`,`docs:`, etc.
163
190
- Required for automated changelog and releases
164
191
- Examples:`feat: add new button variant`,`fix: resolve modal focus issue`
165
192
166
193
##Testing Architecture
194
+
167
195
- Vitest for unit testing with Vue Test Utils
168
196
- 1567+ tests across components
169
197
- Coverage reports available via`pnpm --filter bootstrap-vue-next run test:coverage`
170
-
- Tests use Happy DOM environment for performance
198
+
- Tests use Happy DOM environment for performance
199
+
200
+
##Documentation Examples
201
+
202
+
###Demo File Format
203
+
204
+
All demo files in`apps/docs/src/docs/*/demo/` must follow this structure:
205
+
206
+
1.**Order**: Template first, then script, then style (if applicable)
207
+
2.**Template-Only Examples**: For simple template-only examples wrap example code in`<!-- #region template -->` and`<!-- #endregion template -->` comments
208
+
3.**Complex Examples**: Include script setup after template, using TypeScript
209
+
210
+
**Template-only example:**
211
+
212
+
```vue
213
+
<template>
214
+
<!-- #region template -->
215
+
<BButton v-b-toggle.my-collapse>Toggle</BButton>
216
+
<BCollapse id="my-collapse">
217
+
<BCard>Content</BCard>
218
+
</BCollapse>
219
+
<!-- #endregion template -->
220
+
</template>
221
+
```
222
+
223
+
**Example with script:**
224
+
225
+
```vue
226
+
<template>
227
+
<BButton @click="toggle">Toggle</BButton>
228
+
<BCollapse v-model="visible">
229
+
<BCard>Content</BCard>
230
+
</BCollapse>
231
+
</template>
232
+
233
+
<script setup lang="ts">
234
+
import {ref} from 'vue'
235
+
236
+
const visible = ref(false)
237
+
const toggle = () => {
238
+
visible.value = !visible.value
239
+
}
240
+
</script>
241
+
```
242
+
243
+
###Demo References in Markdown
244
+
245
+
Use the`<<< DEMO` syntax to reference demo files:
246
+
247
+
-**Show full file**:`<<< DEMO ./demo/MyComponent.vue{vue}`
248
+
-**Show specific section**: Use`#region name` markers in the demo file and reference with`#name` in the markdown (e.g.,`#region template` is referenced as`#template`)
249
+
250
+
###Demo File Guidelines
251
+
252
+
- Place demo files in`apps/docs/src/docs/[category]/demo/` directory
253
+
- Name files descriptively:`ComponentFeature.vue` (e.g.,`AccordionOverview.vue`,`AlertDismissible.vue`)
254
+
- Use unique IDs for all components to avoid conflicts when multiple demos render on same page
255
+
- Keep examples focused on demonstrating one feature or pattern
256
+
- Include comments for clarity when showing complex patterns
Copy file name to clipboardExpand all lines: apps/docs/src/docs/components/alert.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -68,6 +68,10 @@ The BAlert exposes four functions to manipulate the state of an active timer: `p
68
68
69
69
<<< DEMO ./demo/AlertFunctions.vue
70
70
71
+
##Accessibility
72
+
73
+
For information on managing ARIA attributes for alert triggers (when using dismissible alerts), see the[ARIA Trigger Registration for Component Visibility](/docs/reference/accessibility#aria-trigger-registration-for-component-visibility) section in the Accessibility reference.
74
+
71
75
##Timer Props
72
76
73
77
-`Immediate`: Setting this property to`false` will cause a timer to not start immediately upon render. A timer that is not started is not rendered. It must manually be started with`resume()` or`restart()`. Default is`true`.
Copy file name to clipboardExpand all lines: apps/docs/src/docs/components/collapse.md
+5-9Lines changed: 5 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,8 +49,6 @@ You can also pass multiple target Ids via the directive _value_ in BootstrapVueN
49
49
The`header` and`footer` slots can be used to create custom toggles for your collapsible content. The default slot is
50
50
used for the content to be hidden or shown.
51
51
52
-
Using the`v-b-toggle` directive to toggle the`BCollapse` will still work but the`collapsed` CSS class will no longer be applied to the element with the directive.
53
-
54
52
The following properties are available for the`header` and`footer` and`default` slots:
55
53
56
54
| Property| Type| Description|
@@ -81,14 +79,12 @@ These are accessed through the [template ref](https://vuejs.org/guide/essentials
81
79
82
80
##Accessibility
83
81
84
-
The`v-b-toggle` directive will automatically add the ARIAattributes`aria-controls`and
85
-
`aria-expanded` to the component that thedirective appears on (as well as add the class`collapsed`
86
-
when not expanded).`aria-expanded`will reflect the state of thetarget`BCollapse` component,
87
-
while`aria-controls` will be set to the Id(s) of the target`BCollapse` component(s).
82
+
The`v-b-toggle` directive will automatically add the ARIAattribute`aria-controls`to the trigger
83
+
element and register it with thetarget`BCollapse` component. The collapse component will then
84
+
automatically manage the`aria-expanded`attribute and`collapsed` class on thetrigger element to
85
+
reflect its visibility state.
88
86
89
-
If using`v-model` to set the visible state instead of the directive`v-b-toggle`, you will be
90
-
required to, on the toggle element, add the`aria-controls` and other appropriate attributes and
91
-
classes yourself.
87
+
For detailed information on managing ARIA attributes for triggers, including examples of using`v-b-toggle` with`v-model` and manual ARIA management, see the[ARIA Trigger Registration for Component Visibility](/docs/reference/accessibility#aria-trigger-registration-for-component-visibility) section in the Accessibility reference.
92
88
93
89
While the`v-b-toggle` directive can be placed on almost any HTML element or Vue component, it is
94
90
recommended to use a button or link (or similar component) to act as your toggler; otherwise your
Copy file name to clipboardExpand all lines: apps/docs/src/docs/components/dropdown.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -287,6 +287,8 @@ The default ARIA role is set to `menu`, but you can change this default to anoth
287
287
288
288
When a menu item does not trigger navigation, it is recommended to use the`BDropdownItemButton` sub-component (which is not announced as a link) instead of`BDropdownItem` (which is presented as a link to the user).
289
289
290
+
For information on managing ARIA attributes for dropdown triggers, see the[ARIA Trigger Registration for Component Visibility](/docs/reference/accessibility#aria-trigger-registration-for-component-visibility) section in the Accessibility reference.
291
+
290
292
###Headers and accessibility
291
293
292
294
When using`BDropdownHeader` components in the dropdown menu, it is recommended to add an`id` attribute to each of the headers, and then set the`aria-describedby` attribute (set to the`id` value of the associated header) on each following dropdown items under that header. This will provide users of assistive technologies (i.e. sight-impaired users) additional context about the dropdown item:
Copy file name to clipboardExpand all lines: apps/docs/src/docs/components/modal.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -297,6 +297,8 @@ If you're looking for replacements for `$bvModal.msgBoxOk` and `$bvModal.msgBoxC
297
297
`<BModal>` provides several accessibility features, including auto focus, return focus, keyboard
298
298
(tab)_focus containment_, and automated`aria-*` attributes.
299
299
300
+
For information on managing ARIA attributes for modal triggers, see the[ARIA Trigger Registration for Component Visibility](/docs/reference/accessibility#aria-trigger-registration-for-component-visibility) section in the Accessibility reference.
301
+
300
302
**Note:** The animation effect of this component is dependent on the`prefers-reduced-motion` media
301
303
query. See the
302
304
[reduced motion section of our accessibility documentation](/docs/reference/accessibility) for
Copy file name to clipboardExpand all lines: apps/docs/src/docs/components/offcanvas.md
+5-8Lines changed: 5 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -150,22 +150,19 @@ elements outside of the offcanvas.
150
150
###`v-b-toggle` directive
151
151
152
152
Using the[`v-b-toggle` directive](/docs/directives/BToggle) is the preferred method for_opening_
153
-
the offcanvas, as it automatically handles applying the`aria-controls` and`aria-expanded`
154
-
accessibility attributes on the trigger element.
153
+
the offcanvas, as it automatically handles applying the`aria-controls` attribute and registering
154
+
the trigger with the offcanvas. The offcanvas will then manage the`aria-expanded` attribute and
155
+
visual state classes on the trigger element to reflect its open/closed state.
155
156
156
157
The majority of examples on this page use the`v-b-toggle` directive.
157
158
158
159
###`v-model`
159
160
160
161
The`v-model` reflects the current visibility state of the offcanvas. While it can be used to control
161
162
the visibility state of the offcanvas, it is recommended to use the
162
-
[`v-b-toggle` directive](#v-b-toggle-directive) to_show_ the offcanvas for accessibility reasons. If
163
-
you do use the`v-model` to show the offcanvas, you should:
163
+
[`v-b-toggle` directive](#v-b-toggle-directive) to_show_ the offcanvas for accessibility reasons.
164
164
165
-
- Provide an`id` prop on the`<BOffcanvas>` component
166
-
- Place the`aria-controls="id"` attribute (where`id` is the ID of the offcanvas) on the trigger element
167
-
- Set the`aria-expanded` attribute (also on the trigger element) to either the string`'true'` (if the offcanvas is open) or`'false'` (if the offcanvas is closed)
168
-
- Provide either a`title` prop or`aria-label` attribute on the`<BOffcanvas>` component for screen readers
165
+
For detailed information on managing ARIA attributes when using`v-model`, including examples of programmatic trigger registration and manual ARIA management, see the[ARIA Trigger Registration for Component Visibility](/docs/reference/accessibility#aria-trigger-registration-for-component-visibility) section in the Accessibility reference.
Copy file name to clipboardExpand all lines: apps/docs/src/docs/components/popover.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -132,3 +132,7 @@ props can be used to control what's considered clipping.
132
132
These are accessed through the[template ref](https://vuejs.org/guide/essentials/template-refs.html#template-refs)
133
133
134
134
<<< DEMO ./demo/PopoverExposed.vue
135
+
136
+
##Accessibility
137
+
138
+
For information on managing ARIA attributes for popover triggers, see the[ARIA Trigger Registration for Component Visibility](/docs/reference/accessibility#aria-trigger-registration-for-component-visibility) section in the Accessibility reference.
Copy file name to clipboardExpand all lines: apps/docs/src/docs/components/toast.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -79,6 +79,8 @@ Toasts are intended to be **small interruptions** to your visitors or users, so
79
79
80
80
If you just need a single simple message to appear along the bottom or top of the user's window, use a fixed position`BAlert` instead.
81
81
82
+
For information on managing ARIA attributes for toast triggers, see the[ARIA Trigger Registration for Component Visibility](/docs/reference/accessibility#aria-trigger-registration-for-component-visibility) section in the Accessibility reference.
83
+
82
84
###Accessibility tips
83
85
84
86
Typically, toast messages should display one or two-line non-critical messages that**do not**
Copy file name to clipboardExpand all lines: apps/docs/src/docs/components/tooltip.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -150,3 +150,7 @@ props can be used to control what's considered clipping.
150
150
These are accessed through the[template ref](https://vuejs.org/guide/essentials/template-refs.html#template-refs)
151
151
152
152
<<< DEMO ./demo/TooltipExposed.vue
153
+
154
+
##Accessibility
155
+
156
+
For information on managing ARIA attributes for tooltip triggers, see the[ARIA Trigger Registration for Component Visibility](/docs/reference/accessibility#aria-trigger-registration-for-component-visibility) section in the Accessibility reference.
description:'A light-weight directive for toggling visibility state for collapses and sidebars by ID. It automaticallyhandles theaccessibility attributes onthe triggerelement'
2
+
description:'A light-weight directive for toggling visibility state for collapses and sidebars by ID. It automaticallysets thearia-controls attribute and registersthe triggerwith the target component, which then manages aria-expanded and visual state'
3
3
---
4
+
5
+
#v-b-toggle Directive
6
+
7
+
The`v-b-toggle` directive provides an easy way to toggle visibility of components like`BCollapse`,`BOffcanvas`, and`BModal`.
8
+
9
+
##Accessibility
10
+
11
+
The directive automatically handles accessibility by:
12
+
13
+
1. Setting the`aria-controls` attribute to the ID(s) of the target component(s)
14
+
2. Registering the trigger element with the target component
15
+
3. The target component then manages:
16
+
- The`aria-expanded` attribute (set to`'true'` or`'false'` based on visibility)
17
+
- The`collapsed` and`not-collapsed` CSS classes
18
+
- Event handlers for the click event
19
+
20
+
This separation ensures that the directive handles the initial connection while each component manages its own state attributes, providing consistent behavior across all show/hide components.