Skip to content

Commit b65c1e4

Browse files
hnbenInfiniteGmng
andauthored
feat(BFormTags): added feedbackAriaLive prop (bootstrap-vue-next#2696)
Co-authored-by: Noah Lanctot <135896269+InfiniteGmng@users.noreply.github.com>
1 parent 43ef54d commit b65c1e4

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

apps/docs/src/data/components/formTags.data.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ export default {
9090
description:
9191
'The message when duplicate tags are detected. Set to an empty string to disable the message',
9292
},
93+
feedbackAriaLive: {
94+
type: 'string',
95+
default: "'assertive'",
96+
description: 'Value to use for the `aria-live` attribute on the feedback text',
97+
},
9398
inputAttrs: {
9499
type: 'Readonly<AttrsValue>',
95100
default: undefined,

packages/bootstrap-vue-next/src/components/BFormTags/BFormTags.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@
9797
</div>
9898
</li>
9999
</ul>
100-
<div aria-live="polite" aria-atomic="true">
100+
<div :aria-live="props.feedbackAriaLive" aria-atomic="true">
101101
<div v-if="isInvalid" class="d-block invalid-feedback">
102102
{{ props.invalidTagText }}: {{ inputValue }}
103103
</div>
@@ -140,6 +140,7 @@ const _props = withDefaults(defineProps<Omit<BFormTagsProps, 'modelValue'>>(), {
140140
autofocus: false,
141141
disabled: false,
142142
duplicateTagText: 'Duplicate tag(s)',
143+
feedbackAriaLive: 'assertive',
143144
form: undefined,
144145
inputAttrs: undefined,
145146
inputClass: undefined,

packages/bootstrap-vue-next/src/components/BFormTags/form-tags.spec.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,31 @@ describe('form-tags', () => {
2525
expect($smallElement.text()).toBe('Foo')
2626
})
2727
})
28+
29+
describe('feedbackAriaLive behavior', () => {
30+
it('sets aria-live to assertive by default', () => {
31+
const wrapper = mount(BFormTags)
32+
const feedbackDiv = wrapper.find('.b-form-tags > div[aria-atomic="true"]:last-child')
33+
expect(feedbackDiv.exists()).toBe(true)
34+
expect(feedbackDiv.attributes('aria-live')).toBe('assertive')
35+
})
36+
37+
it('sets aria-live to polite when feedbackAriaLive is polite', () => {
38+
const wrapper = mount(BFormTags, {
39+
props: {feedbackAriaLive: 'polite'},
40+
})
41+
const feedbackDiv = wrapper.find('.b-form-tags > div[aria-atomic="true"]:last-child')
42+
expect(feedbackDiv.exists()).toBe(true)
43+
expect(feedbackDiv.attributes('aria-live')).toBe('polite')
44+
})
45+
46+
it('sets aria-live to off when feedbackAriaLive is off', () => {
47+
const wrapper = mount(BFormTags, {
48+
props: {feedbackAriaLive: 'off'},
49+
})
50+
const feedbackDiv = wrapper.find('.b-form-tags > div[aria-atomic="true"]:last-child')
51+
expect(feedbackDiv.exists()).toBe(true)
52+
expect(feedbackDiv.attributes('aria-live')).toBe('off')
53+
})
54+
})
2855
})

packages/bootstrap-vue-next/src/types/ComponentProps.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import type {
66
RootBoundary,
77
Strategy,
88
} from '@floating-ui/vue'
9-
import type {ComponentPublicInstance, TransitionProps} from 'vue'
9+
import type {AriaAttributes, ComponentPublicInstance, TransitionProps} from 'vue'
1010
import type {RouteLocationRaw} from 'vue-router'
1111
import type {LinkTarget} from './LinkTarget'
1212
import type {
@@ -435,6 +435,7 @@ export interface BFormTagsProps {
435435
autofocus?: boolean
436436
disabled?: boolean
437437
duplicateTagText?: string
438+
feedbackAriaLive?: AriaAttributes['aria-live']
438439
form?: string
439440
inputAttrs?: Readonly<AttrsValue>
440441
inputClass?: ClassValue

0 commit comments

Comments
 (0)