Skip to content

Commit 15e86a3

Browse files
committed
feat(VTable): add caption slot and pass aria-* to <table>
resolves #21805
1 parent e20fe22 commit 15e86a3

6 files changed

Lines changed: 34 additions & 2 deletions

File tree

packages/api-generator/src/locale/en/VTable.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
{
22
"description": "Replacement for native `<table>` HTML element. Lightweight alternative to `v-data-table`.",
33
"props": {
4+
"ariaLabel": "Sets the accessible name of the underlying `<table>` element. Use when the table has no visible heading.",
5+
"ariaLabelledby": "References the `id` of an element whose text labels the underlying `<table>` element.",
46
"fixedFooter": "Use the fixed-footer prop together with the height prop to fix the footer to the bottom of the table.",
57
"fixedHeader": "Use the fixed-header prop together with the height prop to fix the header to the top of the table.",
68
"gridlines": "Controls cell borders\n- **horizontal** draws lines between rows\n- **vertical** between columns (keeps horizontal lines of header and footer rows)\n- **all** / `true` draws both vertical and horizontal lines\n- `false` removes all lines.",
@@ -10,6 +12,7 @@
1012
},
1113
"slots": {
1214
"bottom": "Slot to add content below the table.",
15+
"caption": "First slot inside `<table>` element epected to hold `<caption>` element within.",
1316
"top": "Slot to add content above the table.",
1417
"wrapper": "Slots for custom rendering of the table wrapper."
1518
}

packages/docs/src/data/new-in.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,8 @@
167167
},
168168
"VDataTable": {
169169
"props": {
170+
"ariaLabel": "4.1.0",
171+
"ariaLabelledby": "4.1.0",
170172
"collapseIcon": "3.10.0",
171173
"expandIcon": "3.10.0",
172174
"expandStrategy": "4.1.0",
@@ -187,6 +189,7 @@
187189
"update:opened": "4.1.0"
188190
},
189191
"slots": {
192+
"caption": "4.1.0",
190193
"expanded": "4.1.0",
191194
"group-summary": "3.10.0"
192195
},
@@ -199,6 +202,8 @@
199202
},
200203
"VDataTableServer": {
201204
"props": {
205+
"ariaLabel": "4.1.0",
206+
"ariaLabelledby": "4.1.0",
202207
"collapseIcon": "3.10.0",
203208
"expandIcon": "3.10.0",
204209
"expandStrategy": "4.1.0",
@@ -218,12 +223,15 @@
218223
"update:opened": "4.1.0"
219224
},
220225
"slots": {
226+
"caption": "4.1.0",
221227
"expanded": "4.1.0",
222228
"group-summary": "3.10.0"
223229
}
224230
},
225231
"VDataTableVirtual": {
226232
"props": {
233+
"ariaLabel": "4.1.0",
234+
"ariaLabelledby": "4.1.0",
227235
"collapseIcon": "3.10.0",
228236
"expandIcon": "3.10.0",
229237
"expandStrategy": "4.1.0",
@@ -241,6 +249,7 @@
241249
"update:opened": "4.1.0"
242250
},
243251
"slots": {
252+
"caption": "4.1.0",
244253
"expanded": "4.1.0",
245254
"group-summary": "3.10.0"
246255
}
@@ -534,7 +543,12 @@
534543
},
535544
"VTable": {
536545
"props": {
546+
"ariaLabel": "4.1.0",
547+
"ariaLabelledby": "4.1.0",
537548
"gridlines": "4.1.0"
549+
},
550+
"slots": {
551+
"caption": "4.1.0"
538552
}
539553
},
540554
"VTabs": {

packages/vuetify/src/components/VDataTable/VDataTable.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export type VDataTableSlotProps<T> = {
7070

7171
export type VDataTableSlots<T> = VDataTableRowsSlots<T> & VDataTableHeadersSlots & {
7272
default: VDataTableSlotProps<T>
73+
caption: never
7374
colgroup: VDataTableSlotProps<T>
7475
top: VDataTableSlotProps<T>
7576
body: VDataTableSlotProps<T>
@@ -291,6 +292,7 @@ export const VDataTable = genericComponent<new <T extends readonly any[], V>(
291292
>
292293
{{
293294
top: () => slots.top?.(slotProps.value),
295+
caption: slots.caption,
294296
default: () => slots.default ? slots.default(slotProps.value) : (
295297
<>
296298
{ slots.colgroup?.(slotProps.value) }

packages/vuetify/src/components/VDataTable/VDataTableServer.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ export const VDataTableServer = genericComponent<new <T extends readonly any[],
177177
>
178178
{{
179179
top: () => slots.top?.(slotProps.value),
180+
caption: slots.caption,
180181
default: () => slots.default ? slots.default(slotProps.value) : (
181182
<>
182183
{ slots.colgroup?.(slotProps.value) }

packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ type VDataTableVirtualSlotProps<T> = Omit<
4242
>
4343

4444
export type VDataTableVirtualSlots<T> = VDataTableRowsSlots<T> & VDataTableHeadersSlots & {
45+
caption: never
4546
colgroup: VDataTableVirtualSlotProps<T>
4647
top: VDataTableVirtualSlotProps<T>
4748
headers: VDataTableHeadersSlots['headers']
@@ -229,7 +230,11 @@ export const VDataTableVirtual = genericComponent<new <T extends readonly any[],
229230
height: convertToUnit(props.height),
230231
}}
231232
>
232-
<table>
233+
<table
234+
aria-label={ props.ariaLabel }
235+
aria-labelledby={ props.ariaLabelledby }
236+
>
237+
{ slots.caption && <caption>{ slots.caption() }</caption> }
233238
{ slots.colgroup?.(slotProps.value) }
234239
{ !props.hideDefaultHeader && (
235240
<thead key="thead">

packages/vuetify/src/components/VTable/VTable.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@ export type VTableSlots = {
1919
top: never
2020
bottom: never
2121
wrapper: never
22+
caption: never
2223
}
2324

2425
export type Striped = null | 'odd' | 'even'
2526
export type Gridlines = 'horizontal' | 'vertical' | 'all'
2627

2728
export const makeVTableProps = propsFactory({
29+
ariaLabel: String,
30+
ariaLabelledby: String,
2831
gridlines: {
2932
type: [Boolean, String] as PropType<boolean | Gridlines>,
3033
default: 'horizontal',
@@ -89,7 +92,11 @@ export const VTable = genericComponent<VTableSlots>()({
8992
class="v-table__wrapper"
9093
style={{ height: convertToUnit(props.height) }}
9194
>
92-
<table>
95+
<table
96+
aria-label={ props.ariaLabel }
97+
aria-labelledby={ props.ariaLabelledby }
98+
>
99+
{ slots.caption?.() }
93100
{ slots.default() }
94101
</table>
95102
</div>

0 commit comments

Comments
 (0)