Skip to content

Commit

Permalink
Merge pull request #657 from BabyElias/gsoc-table
Browse files Browse the repository at this point in the history
[KTable] Accessibility for Loading States
  • Loading branch information
MisRob authored Jun 18, 2024
2 parents f843b55 + 37beb3f commit 218205b
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 34 deletions.
123 changes: 99 additions & 24 deletions docs/pages/playground.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,50 @@

<div id="app">
<h1>KTable Component Example</h1>
<h2>Sortable Table with Local Sorting</h2>

<!-- Local Sorting Table Example -->
<h2>Local Sorting Table</h2>
<KTable
:headers="headers"
:rows="localRows"
caption="Sortable Table"
:rows="rows"
caption="Local Sorting Table"
:useLocalSorting="true"
sortable
>
<template #header="{ header, index }">

Check failure on line 15 in docs/pages/playground.vue

View workflow job for this annotation

GitHub Actions / lint

'index' is defined but never used
<span>{{ header.label }} (Local Sort)</span>
<span>{{ header.label }} (Local)</span>
</template>
<template #cell="{ content, rowIndex, colIndex }">

Check failure on line 18 in docs/pages/playground.vue

View workflow job for this annotation

GitHub Actions / lint

'rowIndex' is defined but never used
<span v-if="colIndex === 1">{{ content }} years old</span>
<span v-else>{{ content }}</span>
</template>
</KTable>

<h2>Sortable Table with Backend Sorting</h2>
<!-- Backend Sorting Table Example -->
<h2>Backend Sorting Table</h2>
<div ref="loadingArea" role="status" aria-live="polite" class="sr-only">
{{ loadingMessage }}
</div>
<KTable
:headers="headers"
:rows="backendRows"
caption="Sortable Table"
caption="Backend Sorting Table"
:useLocalSorting="false"
sortable
@changeSort="changeSortHandler"
>
<template #header="{ header, index }">

Check failure on line 37 in docs/pages/playground.vue

View workflow job for this annotation

GitHub Actions / lint

'index' is defined but never used
<span>{{ header.label }} (Backend Sort)</span>
<span>{{ header.label }} (Backend)</span>
</template>
<template #cell="{ content, rowIndex, colIndex }">

Check failure on line 40 in docs/pages/playground.vue

View workflow job for this annotation

GitHub Actions / lint

'rowIndex' is defined but never used
<span v-if="colIndex === 2">{{ content }} (City)</span>
<span v-else>{{ content }}</span>
</template>
</KTable>

<div v-if="isLoading" class="loading-overlay">
Data is loading. Please wait...
</div>
</div>

</template>
Expand All @@ -44,17 +54,39 @@
<script>
/*
Playground is a Vue component too,
so you can also use `data`, `methods`, etc.
as usual if helpful
*/
Playground is a Vue component too,
so you can also use `data`, `methods`, etc.
as usual if helpful
*/
import { ref } from '@vue/composition-api';
import KTable from '../../lib/KTable';
export default {
name: 'Playground',
components: {
KTable,
},
setup() {
const loadingArea = ref(null);
const isLoading = ref(false);
const loadingMessage = ref('');
const updateLoadingMessage = message => {
loadingMessage.value = message;
if (loadingArea.value) {
loadingArea.value.setAttribute('aria-live', 'off'); // Temporarily disable live region
void loadingArea.value.offsetWidth; // Force reflow
loadingArea.value.setAttribute('aria-live', 'polite'); // Re-enable live region
}
};
return {
loadingArea,
isLoading,
loadingMessage,
updateLoadingMessage,
};
},
data() {
return {
headers: [
Expand All @@ -64,33 +96,51 @@
{ label: 'Joined', dataType: 'date' },
{ label: 'Misc', dataType: 'others' },
],
localRows: [
['John Doe', 28, 'New York', '2022-01-15', 'N/A'],
['Jane Smith', 34, 'Los Angeles', '2021-12-22', 'N/A'],
['Samuel Green', 22, 'Chicago', '2023-03-10', 'N/A'],
['Alice Johnson', 30, 'Houston', '2020-07-18', 'N/A'],
rows: [
['John Doe', 28, 'New York', '2022-01-15T00:00:00Z', 'N/A'],
['Jane Smith', 34, 'Los Angeles', '2021-12-22T00:00:00Z', 'N/A'],
['Samuel Green', 22, 'Chicago', '2023-03-10T00:00:00Z', 'N/A'],
['Alice Johnson', 30, 'Houston', '2020-07-18T00:00:00Z', 'N/A'],
],
backendRows: [
['John Doe', 28, 'New York', '2022-01-15', 'N/A'],
['Jane Smith', 34, 'Los Angeles', '2021-12-22', 'N/A'],
['Samuel Green', 22, 'Chicago', '2023-03-10', 'N/A'],
['Alice Johnson', 30, 'Houston', '2020-07-18', 'N/A'],
['John Doe', 28, 'New York', '2022-01-15T00:00:00Z', 'N/A'],
['Jane Smith', 34, 'Los Angeles', '2021-12-22T00:00:00Z', 'N/A'],
['Samuel Green', 22, 'Chicago', '2023-03-10T00:00:00Z', 'N/A'],
['Alice Johnson', 30, 'Houston', '2020-07-18T00:00:00Z', 'N/A'],
],
};
},
methods: {
changeSortHandler(index, sortOrder) {
async changeSortHandler(index, sortOrder) {
this.isLoading = true;
this.updateLoadingMessage('Data is loading. Please wait...');
this.$nextTick(() => {
if (this.$refs.loadingArea) {
this.$refs.loadingArea.focus();
}
});
// Simulate fetching sorted data from backend
console.log('Fetching sorted data from backend for column:', index, 'order:', sortOrder);
// You can replace this with an actual API call
// For demo purposes, we just reverse the rows
this.backendRows = [...this.backendRows].reverse();
setTimeout(() => {
// For demo purposes, we just reverse the rows
this.backendRows = [...this.backendRows].reverse();
this.isLoading = false;
this.updateLoadingMessage('Data loaded successfully.');
setTimeout(() => {
this.updateLoadingMessage('');
}, 5000);
}, 10000); // Simulate a 10 second delay for fetching data
},
},
};
</script>


<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
Expand All @@ -103,4 +153,29 @@
h1, h2 {
margin: 20px 0;
}
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.8);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5em;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
</style>
12 changes: 2 additions & 10 deletions lib/composables/useSorting.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ref, computed } from '@vue/composition-api';
import _ from 'lodash';

export const SORT_ORDER_ASC = 'asc';
export const SORT_ORDER_DESC = 'desc';
Expand All @@ -14,16 +15,7 @@ export default function useSorting(headers, rows, useLocalSorting) {
const sortedRows = computed(() => {
if (!useLocalSorting.value || sortKey.value === null) return rows.value;

return [...rows.value].sort((a, b) => {
const aValue = a[sortKey.value];
const bValue = b[sortKey.value];

if (sortOrder.value === SORT_ORDER_ASC) {
return aValue > bValue ? 1 : aValue < bValue ? -1 : 0;
} else {
return aValue < bValue ? 1 : aValue > bValue ? -1 : 0;
}
});
return _.orderBy(rows.value, [row => row[sortKey.value]], [sortOrder.value]);
});

const handleSort = index => {
Expand Down

0 comments on commit 218205b

Please sign in to comment.