Skip to content

Commit 9823d09

Browse files
committed
refactor(components): route aria labels through locale.t()
Replace six hardcoded English aria-label / aria-valuetext strings with locale.t() calls so consumers can localise them. v0 ships no default strings — locale.t() returns the key when no translation is registered. Keys: Dialog.close, AlertDialog.close, Snackbar.close, NumberField.increment, NumberField.decrement, Rating.valueText. Tests switch to toBeDefined() per testing.md §Locale string assertions. Codifies PHILOSOPHY §5.5 / WCAG 4.1.2. Triage row B07.
1 parent 010cd2d commit 9823d09

11 files changed

Lines changed: 37 additions & 19 deletions

File tree

packages/0/src/components/AlertDialog/AlertDialogClose.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
/** Attributes to bind to the close button element */
2424
attrs: {
2525
'type': 'button' | undefined
26-
'aria-label': 'Close'
26+
'aria-label': string
2727
}
2828
}
2929
</script>
@@ -33,6 +33,9 @@
3333
import { Atom } from '#v0/components/Atom'
3434
import { useAlertDialogContext } from './AlertDialogRoot.vue'
3535
36+
// Composables
37+
import { useLocale } from '#v0/composables/useLocale'
38+
3639
// Utilities
3740
import { toRef } from 'vue'
3841
@@ -48,6 +51,7 @@
4851
} = defineProps<AlertDialogCloseProps>()
4952
5053
const context = useAlertDialogContext(namespace)
54+
const locale = useLocale()
5155
5256
function onClick () {
5357
context.close()
@@ -57,7 +61,7 @@
5761
isOpen: context.isOpen.value,
5862
attrs: {
5963
'type': as === 'button' ? 'button' : undefined,
60-
'aria-label': 'Close',
64+
'aria-label': locale.t('AlertDialog.close'),
6165
},
6266
}))
6367
</script>

packages/0/src/components/AlertDialog/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ describe('alert-dialog', () => {
537537
})
538538

539539
const close = wrapper.findComponent(AlertDialog.Close as any)
540-
expect(close.attributes('aria-label')).toBe('Close')
540+
expect(close.attributes('aria-label')).toBeDefined()
541541
})
542542

543543
it('should close dialog on click', async () => {

packages/0/src/components/Dialog/DialogClose.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
/** Attributes to bind to the close button element */
2424
attrs: {
2525
'type': 'button' | undefined
26-
'aria-label': 'Close'
26+
'aria-label': string
2727
}
2828
}
2929
</script>
@@ -33,6 +33,9 @@
3333
import { Atom } from '#v0/components/Atom'
3434
import { useDialogContext } from './DialogRoot.vue'
3535
36+
// Composables
37+
import { useLocale } from '#v0/composables/useLocale'
38+
3639
// Utilities
3740
import { toRef } from 'vue'
3841
@@ -48,6 +51,7 @@
4851
} = defineProps<DialogCloseProps>()
4952
5053
const context = useDialogContext(namespace)
54+
const locale = useLocale()
5155
5256
function onClick () {
5357
context.close()
@@ -57,7 +61,7 @@
5761
isOpen: context.isOpen.value,
5862
attrs: {
5963
'type': as === 'button' ? 'button' : undefined,
60-
'aria-label': 'Close',
64+
'aria-label': locale.t('Dialog.close'),
6165
},
6266
}))
6367
</script>

packages/0/src/components/Dialog/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ describe('dialog', () => {
609609
})
610610

611611
const close = wrapper.findComponent(Dialog.Close as any)
612-
expect(close.attributes('aria-label')).toBe('Close')
612+
expect(close.attributes('aria-label')).toBeDefined()
613613
})
614614
})
615615

packages/0/src/components/NumberField/NumberFieldDecrement.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import { useNumberFieldRoot } from './NumberFieldRoot.vue'
1515
1616
// Composables
17+
import { useLocale } from '#v0/composables/useLocale'
1718
import { useTimer } from '#v0/composables/useTimer'
1819
1920
// Utilities
@@ -51,6 +52,7 @@
5152
} = defineProps<NumberFieldDecrementProps>()
5253
5354
const root = useNumberFieldRoot(namespace)
55+
const locale = useLocale()
5456
5557
const isDisabled = toRef(() => {
5658
return root.isDisabled.value || root.isReadonly.value || !root.canDecrement.value
@@ -91,7 +93,7 @@
9193
return {
9294
'type': 'button',
9395
'tabindex': -1,
94-
'aria-label': 'Decrement',
96+
'aria-label': locale.t('NumberField.decrement'),
9597
'disabled': disabled || undefined,
9698
'data-disabled': disabled ? true : undefined,
9799
onBlur,

packages/0/src/components/NumberField/NumberFieldIncrement.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import { useNumberFieldRoot } from './NumberFieldRoot.vue'
1515
1616
// Composables
17+
import { useLocale } from '#v0/composables/useLocale'
1718
import { useTimer } from '#v0/composables/useTimer'
1819
1920
// Utilities
@@ -51,6 +52,7 @@
5152
} = defineProps<NumberFieldIncrementProps>()
5253
5354
const root = useNumberFieldRoot(namespace)
55+
const locale = useLocale()
5456
5557
const isDisabled = toRef(() => {
5658
return root.isDisabled.value || root.isReadonly.value || !root.canIncrement.value
@@ -91,7 +93,7 @@
9193
return {
9294
'type': 'button',
9395
'tabindex': -1,
94-
'aria-label': 'Increment',
96+
'aria-label': locale.t('NumberField.increment'),
9597
'disabled': disabled || undefined,
9698
'data-disabled': disabled ? true : undefined,
9799
onBlur,

packages/0/src/components/NumberField/index.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ function mountNumberField (options: {
8686
wrapper,
8787
rootProps: () => capturedRootProps,
8888
controlEl: () => wrapper.find('[role="spinbutton"]'),
89-
incrementEl: () => wrapper.find('[aria-label="Increment"]'),
90-
decrementEl: () => wrapper.find('[aria-label="Decrement"]'),
89+
incrementEl: () => wrapper.find('[aria-label="NumberField.increment"]'),
90+
decrementEl: () => wrapper.find('[aria-label="NumberField.decrement"]'),
9191
wait: () => nextTick(),
9292
}
9393
}
@@ -631,14 +631,14 @@ describe('number-field', () => {
631631
const model = ref<number | null>(5)
632632
const { incrementEl, wait } = mountNumberField({ model })
633633
await wait()
634-
expect(incrementEl().attributes('aria-label')).toBe('Increment')
634+
expect(incrementEl().attributes('aria-label')).toBeDefined()
635635
})
636636

637637
it('should set decrement button aria-label', async () => {
638638
const model = ref<number | null>(5)
639639
const { decrementEl, wait } = mountNumberField({ model })
640640
await wait()
641-
expect(decrementEl().attributes('aria-label')).toBe('Decrement')
641+
expect(decrementEl().attributes('aria-label')).toBeDefined()
642642
})
643643

644644
it('should set increment button tabindex=-1', async () => {

packages/0/src/components/Rating/RatingRoot.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// Composables
1818
import { createContext } from '#v0/composables/createContext'
1919
import { createRating } from '#v0/composables/createRating'
20+
import { useLocale } from '#v0/composables/useLocale'
2021
2122
// Utilities
2223
import { isNull } from '#v0/utilities'
@@ -162,6 +163,8 @@
162163
isReadonly,
163164
}
164165
166+
const locale = useLocale()
167+
165168
provideRatingRoot(namespace, context)
166169
167170
const slotProps = toRef((): RatingRootSlotProps => ({
@@ -176,7 +179,7 @@
176179
'aria-valuenow': rating.value.value,
177180
'aria-valuemin': 0,
178181
'aria-valuemax': rating.size,
179-
'aria-valuetext': `${rating.value.value} out of ${rating.size}`,
182+
'aria-valuetext': locale.t('Rating.valueText', { value: rating.value.value, size: rating.size }),
180183
'aria-disabled': isDisabled.value ? true : undefined,
181184
'aria-readonly': isReadonly.value ? true : undefined,
182185
'data-disabled': isDisabled.value ? true : undefined,

packages/0/src/components/Rating/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ describe('rating', () => {
290290
const { rootProps, wait } = mountRating({ model })
291291
await wait()
292292

293-
expect(rootProps().attrs['aria-valuetext']).toBe('3 out of 5')
293+
expect(rootProps().attrs['aria-valuetext']).toBeDefined()
294294
})
295295

296296
it('should not set aria-disabled when not disabled', async () => {

packages/0/src/components/Snackbar/SnackbarClose.vue

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
<script lang="ts">
1313
// Components
1414
import { Atom } from '#v0/components/Atom'
15-
// Composables
1615
import { useSnackbarRootContext } from './SnackbarRoot.vue'
1716
17+
// Composables
18+
import { useLocale } from '#v0/composables/useLocale'
19+
1820
// Utilities
1921
import { toRef } from 'vue'
2022
@@ -30,7 +32,7 @@
3032
/** Attributes to bind to the close button element */
3133
attrs: {
3234
'type': 'button' | undefined
33-
'aria-label': 'Close'
35+
'aria-label': string
3436
'onClick': () => void
3537
}
3638
}
@@ -46,6 +48,7 @@
4648
const { as = 'button', namespace = 'v0:notifications' } = defineProps<SnackbarCloseProps>()
4749
4850
const context = useSnackbarRootContext(namespace)
51+
const locale = useLocale()
4952
5053
function onClick () {
5154
context.onDismiss()
@@ -54,7 +57,7 @@
5457
const slotProps = toRef((): SnackbarCloseSlotProps => ({
5558
attrs: {
5659
'type': as === 'button' ? 'button' : undefined,
57-
'aria-label': 'Close',
60+
'aria-label': locale.t('Snackbar.close'),
5861
'onClick': onClick,
5962
},
6063
}))

0 commit comments

Comments
 (0)