Skip to content

Commit

Permalink
feat(table): support w3c WAI-ARIA (a11y) pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
mlmoravek committed Nov 27, 2024
1 parent 694f57d commit d0a9938
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 24 deletions.
4 changes: 2 additions & 2 deletions packages/oruga/src/components/loading/Loading.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const props = withDefaults(defineProps<LoadingProps>(), {
iconSpin: () => getDefault("loading.iconSpin", true),
iconSize: () => getDefault("loading.iconSize", "medium"),
scroll: () => getDefault("loading.scroll", "keep"),
ariaRole: () => getDefault("loading.ariaRole", "dialog"),
role: () => getDefault("loading.role", "dialog"),
});
const emits = defineEmits<{
Expand Down Expand Up @@ -128,7 +128,7 @@ defineExpose({ close });
v-if="isActive"
ref="rootElement"
data-oruga="loading"
:role="ariaRole"
:role="role"
:class="rootClasses">
<div
:class="overlayClasses"
Expand Down
2 changes: 1 addition & 1 deletion packages/oruga/src/components/loading/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type LoadingProps = {
*/
scroll?: "keep" | "clip";
/** Role attribute to be passed to the div wrapper for better accessibility */
ariaRole?: string;
role?: string;
} & LoadingClasses;

// class props (will not be displayed in the docs)
Expand Down
31 changes: 19 additions & 12 deletions packages/oruga/src/components/table/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -373,9 +373,10 @@ const tableColumns = computed<TableColumnItem<T>[]>(() => {
);
return {
...column,
value: column,
index: columnItem.index,
identifier: columnItem.identifier,
...column,
thAttrsData: thAttrsData,
tdAttrsData: tdAttrsData,
};
Expand Down Expand Up @@ -933,7 +934,7 @@ function handleColumnDragStart(
): void {
if (!canDragColumn.value) return;
isDraggingColumn.value = true;
emits("columndragstart", column, column.index, event);
emits("columndragstart", column.value, column.index, event);
}
/** emits drag leave event (column) */
Expand All @@ -943,13 +944,13 @@ function handleColumnDragEnd(
): void {
if (!canDragColumn.value) return;
isDraggingColumn.value = false;
emits("columndragend", column, column.index, event);
emits("columndragend", column.value, column.index, event);
}
/** emits drop event (column) */
function handleColumnDrop(column: TableColumnItem<T>, event: DragEvent): void {
if (!canDragColumn.value) return;
emits("columndrop", column, column.index, event);
emits("columndrop", column.value, column.index, event);
}
/** emits drag over event (column) */
Expand All @@ -958,7 +959,7 @@ function handleColumnDragOver(
event: DragEvent,
): void {
if (!canDragColumn.value) return;
emits("columndragover", column, column.index, event);
emits("columndragover", column.value, column.index, event);
}
/** emits drag leave event (column) */
Expand All @@ -967,7 +968,7 @@ function handleColumnDragLeave(
event: DragEvent,
): void {
if (!canDragColumn.value) return;
emits("columndragleave", column, column.index, event);
emits("columndragleave", column.value, column.index, event);
}
// #endregion --- Drag&Drop Feature ---
Expand Down Expand Up @@ -1301,7 +1302,10 @@ defineExpose({ rows: tableRows, sort: sortByField });
:component="column.$el"
name="header"
tag="span"
:props="{ column }" />
:props="{
column: column.value,
index: column.index,
}" />

<span v-else>
{{ column.label }}
Expand Down Expand Up @@ -1379,7 +1383,7 @@ defineExpose({ rows: tableRows, sort: sortByField });
name="searchable"
tag="span"
:props="{
column,
column: column.value,
index: column.index,
filters,
}" />
Expand Down Expand Up @@ -1432,7 +1436,10 @@ defineExpose({ rows: tableRows, sort: sortByField });
:component="column.$el"
name="subheading"
tag="span"
:props="{ column, index: column.index }" />
:props="{
column: column.value,
index: column.index,
}" />
<span v-else>
{{ column.subheading }}
</span>
Expand Down Expand Up @@ -1545,16 +1552,16 @@ defineExpose({ rows: tableRows, sort: sortByField });
:style="isMobileActive ? {} : column.style"
:props="{
row: row.value,
column,
index: row.index,
column: column.value,
colindex: column.index,
toggleDetails: () => toggleDetails(row),
}"
@click="
$emit(
'cell-click',
row.value,
column,
column.value,
row.index,
column.index,
$event,
Expand Down Expand Up @@ -1666,7 +1673,7 @@ defineExpose({ rows: tableRows, sort: sortByField });
:active="loading"
:icon="loadingIcon"
:label="loadingLabel"
aria-role="status" />
role="status" />
</slot>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,114 @@ exports[`OTable tests > render correctly 1`] = `
<!--v-if-->
<!--v-if-->
<div class="o-table__wrapper">
<!--v-if-->
<table class="o-table" aria-rowcount="6" aria-colcount="5">
<!--v-if-->
<thead>
<!--
@slot Define preheader content here
-->
<tr aria-rowindex="1">
<!-- detailed toggle column -->
<!--v-if-->
<!-- checkable column left -->
<!--v-if-->
<!-- row data columns -->
<th class="o-table__th o-table__th--sortable o-table__th--unselectable" style="width: 40px;" draggable="false" aria-colindex="1"><span>ID <span class="o-table__th__sort-icon" aria-hidden="true" style="display: none;"><span class="o-icon o-icon--small" data-oruga="icon"><!-- custom icon component --><!-- native css icon --><i class="mdi mdi-arrow-up"></i></span></span></span></th>
<th class="o-table__th o-table__th--sortable o-table__th--unselectable" draggable="false" aria-colindex="2"><span>First Name <span class="o-table__th__sort-icon" aria-hidden="true" style="display: none;"><span class="o-icon o-icon--small" data-oruga="icon"><!-- custom icon component --><!-- native css icon --><i class="mdi mdi-arrow-up"></i></span></span></span></th>
<th class="o-table__th o-table__th--sortable o-table__th--unselectable" draggable="false" aria-colindex="3"><span>Last Name <span class="o-table__th__sort-icon" aria-hidden="true" style="display: none;"><span class="o-icon o-icon--small" data-oruga="icon"><!-- custom icon component --><!-- native css icon --><i class="mdi mdi-arrow-up"></i></span></span></span></th>
<th class="o-table__th o-table__th--sortable o-table__th--unselectable o-table__th--centered" draggable="false" aria-colindex="4"><span>Date <span class="o-table__th__sort-icon" aria-hidden="true" style="display: none;"><span class="o-icon o-icon--small" data-oruga="icon"><!-- custom icon component --><!-- native css icon --><i class="mdi mdi-arrow-up"></i></span></span></span></th>
<th class="o-table__th o-table__th--sortable o-table__th--unselectable" draggable="false" aria-colindex="5"><span>Gender <span class="o-table__th__sort-icon" aria-hidden="true" style="display: none;"><span class="o-icon o-icon--small" data-oruga="icon"><!-- custom icon component --><!-- native css icon --><i class="mdi mdi-arrow-up"></i></span></span></span></th><!-- checkable column right -->
<!--v-if-->
</tr>
<!--v-if-->
<!--v-if-->
</thead>
<tbody>
<!-- table rows -->
<tr class="" draggable="false" aria-rowindex="2">
<!-- detailed toggle column -->
<!--v-if-->
<!-- checkable column left -->
<!--v-if-->
<!-- row data columns -->
<td class="o-table__td" style="width: 40px;">1</td>
<td class="o-table__td">Jesse</td>
<td class="o-table__td">Simmons</td>
<td class="o-table__td o-table__td--centered">15.10.2016</td>
<td class="o-table__td">Male</td><!-- checkable column right -->
<!--v-if-->
</tr>
<transition-stub name="slide" appear="false" persisted="false" css="true">
<!--v-if-->
</transition-stub>
<tr class="" draggable="false" aria-rowindex="3">
<!-- detailed toggle column -->
<!--v-if-->
<!-- checkable column left -->
<!--v-if-->
<!-- row data columns -->
<td class="o-table__td" style="width: 40px;">2</td>
<td class="o-table__td">John</td>
<td class="o-table__td">Jacobs</td>
<td class="o-table__td o-table__td--centered">15.12.2016</td>
<td class="o-table__td">Male</td><!-- checkable column right -->
<!--v-if-->
</tr>
<transition-stub name="slide" appear="false" persisted="false" css="true">
<!--v-if-->
</transition-stub>
<tr class="" draggable="false" aria-rowindex="4">
<!-- detailed toggle column -->
<!--v-if-->
<!-- checkable column left -->
<!--v-if-->
<!-- row data columns -->
<td class="o-table__td" style="width: 40px;">3</td>
<td class="o-table__td">Tina</td>
<td class="o-table__td">Gilbert</td>
<td class="o-table__td o-table__td--centered">26.4.2016</td>
<td class="o-table__td">Female</td><!-- checkable column right -->
<!--v-if-->
</tr>
<transition-stub name="slide" appear="false" persisted="false" css="true">
<!--v-if-->
</transition-stub>
<tr class="" draggable="false" aria-rowindex="5">
<!-- detailed toggle column -->
<!--v-if-->
<!-- checkable column left -->
<!--v-if-->
<!-- row data columns -->
<td class="o-table__td" style="width: 40px;">4</td>
<td class="o-table__td">Clarence</td>
<td class="o-table__td">Flores</td>
<td class="o-table__td o-table__td--centered">10.4.2016</td>
<td class="o-table__td">Male</td><!-- checkable column right -->
<!--v-if-->
</tr>
<transition-stub name="slide" appear="false" persisted="false" css="true">
<!--v-if-->
</transition-stub>
<tr class="" draggable="false" aria-rowindex="6">
<!-- detailed toggle column -->
<!--v-if-->
<!-- checkable column left -->
<!--v-if-->
<!-- row data columns -->
<td class="o-table__td" style="width: 40px;">5</td>
<td class="o-table__td">Anne</td>
<td class="o-table__td">Lee</td>
<td class="o-table__td o-table__td--centered">6.12.2016</td>
<td class="o-table__td">Female</td><!-- checkable column right -->
<!--v-if-->
</tr>
<transition-stub name="slide" appear="false" persisted="false" css="true">
<!--v-if-->
</transition-stub>
<!--v-if-->
</tbody>
<!--v-if-->
</table>
<!--
@slot Override loading component
@binding {boolean} loading - is loading state enabled
Expand Down
5 changes: 4 additions & 1 deletion packages/oruga/src/components/table/tests/table.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { enableAutoUnmount, mount } from "@vue/test-utils";

import OTable from "@/components/table/Table.vue";
import type { TableColumn } from "../types";
import { nextTick } from "vue";

describe("OTable tests", () => {
enableAutoUnmount(afterEach);
Expand Down Expand Up @@ -77,10 +78,12 @@ describe("OTable tests", () => {
},
];

test("render correctly", () => {
test("render correctly", async () => {
const wrapper = mount<typeof OTable<(typeof data)[number]>>(OTable, {
props: { data, columns },
});
await nextTick(); // await child component rendering

expect(!!wrapper.vm).toBeTruthy();
expect(wrapper.exists()).toBeTruthy();
expect(wrapper.attributes("data-oruga")).toBe("table");
Expand Down
8 changes: 1 addition & 7 deletions packages/oruga/src/components/table/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@ export type TableColumn<
K extends keyof T | string = string,
> = TableColumnProps<T, K>;

export type TableColumns<T = unknown> = (
| {
[K in keyof T]: TableColumn<T, K>;
}[keyof T]
| TableColumn<T, string>
)[];

export type TableColumnComponent<T = unknown> = TableColumn<T> & {
$el: ComponentPublicInstance;
$slots: Slots;
Expand All @@ -35,6 +28,7 @@ export type TableComponent = {

export type TableColumnItem<T = unknown> = Omit<ProviderItem, "data"> &
TableColumnComponent<T> & {
value: TableColumn<T>;
thAttrsData: object;
tdAttrsData: Array<object>;
};

0 comments on commit d0a9938

Please sign in to comment.