Skip to content

Commit ecbe9d4

Browse files
committed
feat(DataTable): added dynamic sorting, clean up and updated props name
1 parent e0d5ac6 commit ecbe9d4

16 files changed

Lines changed: 2085 additions & 141 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ test/skills/*
3131
# Oobee a11y scan results
3232
results/
3333
a11y-failures.log
34-
**/.pnpm/*
34+
**/.pnpm*

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
"@tailwindcss/cli": "^4.1.18",
101101
"@tailwindcss/postcss": "^4.1.18",
102102
"@tailwindcss/vite": "^4.1.18",
103+
"@types/jest": "^30.0.0",
103104
"@types/mocha": "^10.0.6",
104105
"@typescript-eslint/eslint-plugin": "^5.59.0",
105106
"@typescript-eslint/parser": "^5.59.0",

playground/DataTable.html

Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,19 @@ <h3>Basic</h3>
170170
</sgds-data-table>
171171
</div>
172172

173+
<!-- No rows -->
174+
<div class="container">
175+
<h3>No rows</h3>
176+
<sgds-data-table>
177+
<sgds-data-table-row>
178+
<sgds-data-table-head>#</sgds-data-table-head>
179+
<sgds-data-table-head>First name</sgds-data-table-head>
180+
<sgds-data-table-head>Last name</sgds-data-table-head>
181+
<sgds-data-table-head>Username</sgds-data-table-head>
182+
</sgds-data-table-row>
183+
</sgds-data-table>
184+
</div>
185+
173186
<!-- Multi-select -->
174187
<div class="container">
175188
<h3>Multi-select</h3>
@@ -212,20 +225,20 @@ <h3>Expandable rows</h3>
212225
<sgds-data-table-head>Username</sgds-data-table-head>
213226
</sgds-data-table-row>
214227

215-
<sgds-data-table-row expandable>
228+
<sgds-data-table-row expand open>
216229
<sgds-data-table-cell>1</sgds-data-table-cell>
217230
<sgds-data-table-cell>John</sgds-data-table-cell>
218231
<sgds-data-table-cell>Doe</sgds-data-table-cell>
219232
<sgds-data-table-cell>@johndoe</sgds-data-table-cell>
220-
<div slot="expandable-content">Department: Engineering · Join date: 01 Jan 2022 · Status: Active</div>
233+
<div slot="content">Department: Engineering · Join date: 01 Jan 2022 · Status: Active</div>
221234
</sgds-data-table-row>
222235

223-
<sgds-data-table-row expandable>
236+
<sgds-data-table-row expand>
224237
<sgds-data-table-cell>2</sgds-data-table-cell>
225238
<sgds-data-table-cell>Jane</sgds-data-table-cell>
226239
<sgds-data-table-cell>Doe</sgds-data-table-cell>
227240
<sgds-data-table-cell>@janedoe</sgds-data-table-cell>
228-
<div slot="expandable-content">Department: Design · Join date: 15 Mar 2023 · Status: Active</div>
241+
<div slot="content">Department: Design · Join date: 15 Mar 2023 · Status: Active</div>
229242
</sgds-data-table-row>
230243

231244
<sgds-data-table-row>
@@ -248,12 +261,12 @@ <h3>Expandable + Multi-select</h3>
248261
<sgds-data-table-head>Username</sgds-data-table-head>
249262
</sgds-data-table-row>
250263

251-
<sgds-data-table-row id="ems-row-1" expandable>
264+
<sgds-data-table-row id="ems-row-1" expand>
252265
<sgds-data-table-cell>1</sgds-data-table-cell>
253266
<sgds-data-table-cell>John</sgds-data-table-cell>
254267
<sgds-data-table-cell>Doe</sgds-data-table-cell>
255268
<sgds-data-table-cell>@johndoe</sgds-data-table-cell>
256-
<div slot="expandable-content">Department: Engineering</div>
269+
<div slot="content">Department: Engineering</div>
257270
</sgds-data-table-row>
258271

259272
<sgds-data-table-row id="ems-row-2">
@@ -327,27 +340,27 @@ <h3>Hide Footer (hideFooter)</h3>
327340
<h3>Server Mode (mode="server")</h3>
328341
<sgds-data-table id="server-table" currentPage="1" dataLength="50" itemsPerPage="10" mode="server" isLoading>
329342
<sgds-data-table-row>
330-
<sgds-data-table-head>ID</sgds-data-table-head>
331-
<sgds-data-table-head>Name</sgds-data-table-head>
332-
<sgds-data-table-head>Region</sgds-data-table-head>
343+
<sgds-data-table-head sorting sortKey="id">ID</sgds-data-table-head>
344+
<sgds-data-table-head sorting sortKey="name">Name</sgds-data-table-head>
345+
<sgds-data-table-head sorting sortKey="region">Region</sgds-data-table-head>
333346
</sgds-data-table-row>
334347
</sgds-data-table>
335348
</div>
336349

337-
<!-- Header props: sortable, sortKey, width, colspan, rowspan, textAlign -->
350+
<!-- Header props: sorting, sortKey, width, colspan, rowspan, textAlign -->
338351
<div class="container">
339-
<h3>Header Props (sortable, sortKey, width, colspan, rowspan, textAlign)</h3>
352+
<h3>Header Props (sorting, sortKey, width, colspan, rowspan, textAlign)</h3>
340353
<sgds-data-table currentPage="1" dataLength="4" itemsPerPage="4">
341354
<sgds-data-table-row>
342355
<sgds-data-table-head rowspan="2" width="88">ID</sgds-data-table-head>
343356
<sgds-data-table-head colspan="2">Profile</sgds-data-table-head>
344-
<sgds-data-table-head rowspan="2" sortable sortKey="score" width="120" textAlign="right"
357+
<sgds-data-table-head rowspan="2" sorting sortKey="score" width="120" textAlign="right"
345358
>Score</sgds-data-table-head
346359
>
347360
</sgds-data-table-row>
348361
<sgds-data-table-row>
349-
<sgds-data-table-head sortable sortKey="name">Name</sgds-data-table-head>
350-
<sgds-data-table-head sortable sortKey="role">Role</sgds-data-table-head>
362+
<sgds-data-table-head sorting sortKey="name">Name</sgds-data-table-head>
363+
<sgds-data-table-head sorting sortKey="role">Role</sgds-data-table-head>
351364
</sgds-data-table-row>
352365

353366
<sgds-data-table-row id="sort-row-1">
@@ -388,7 +401,7 @@ <h3>Header Props (sortable, sortKey, width, colspan, rowspan, textAlign)</h3>
388401
document.getElementById("ems-row-2").rowData = { id: 2, name: "Jane Doe" };
389402
document.getElementById("ems-row-3").rowData = { id: 3, name: "Bob Smith" };
390403

391-
// Set rowData for sortable table head demo (sortKey)
404+
// Set rowData for sorting table head demo (sorting)
392405
document.getElementById("sort-row-1").rowData = { id: 1, name: "Lina", role: "Engineer", score: 82 };
393406
document.getElementById("sort-row-2").rowData = { id: 2, name: "Adam", role: "Designer", score: 90 };
394407
document.getElementById("sort-row-3").rowData = { id: 3, name: "Nora", role: "Manager", score: 75 };
@@ -398,20 +411,49 @@ <h3>Header Props (sortable, sortKey, width, colspan, rowspan, textAlign)</h3>
398411
const serverTable = document.getElementById("server-table");
399412
const totalRows = 50;
400413
const regions = ["North", "South", "East", "West", "Central"];
414+
const serverSort = { key: "", direction: "none" };
401415

402-
const mockApi = ({ page, itemsPerPage }) => {
403-
const start = (page - 1) * itemsPerPage;
404-
const end = Math.min(start + itemsPerPage, totalRows);
416+
const compareServerRows = (left, right, key, direction) => {
417+
if (direction === "none") return 0;
418+
419+
const leftValue = left[key];
420+
const rightValue = right[key];
405421

406-
const rows = Array.from({ length: Math.max(0, end - start) }, (_, index) => {
407-
const id = start + index + 1;
422+
if (leftValue === rightValue) return 0;
423+
424+
const leftNumber = Number(leftValue);
425+
const rightNumber = Number(rightValue);
426+
const bothNumeric = Number.isFinite(leftNumber) && Number.isFinite(rightNumber);
427+
428+
if (bothNumeric) {
429+
return direction === "ascending" ? leftNumber - rightNumber : rightNumber - leftNumber;
430+
}
431+
432+
const cmp = String(leftValue).localeCompare(String(rightValue), undefined, {
433+
numeric: true,
434+
sensitivity: "base"
435+
});
436+
return direction === "ascending" ? cmp : -cmp;
437+
};
438+
439+
const mockApi = ({ page, itemsPerPage, sortKey, sortDirection }) => {
440+
const allRows = Array.from({ length: totalRows }, (_, index) => {
441+
const id = index + 1;
408442
return {
409443
id,
410444
name: `Citizen ${id}`,
411445
region: regions[id % regions.length]
412446
};
413447
});
414448

449+
if (sortKey && sortDirection !== "none") {
450+
allRows.sort((left, right) => compareServerRows(left, right, sortKey, sortDirection));
451+
}
452+
453+
const start = (page - 1) * itemsPerPage;
454+
const end = Math.min(start + itemsPerPage, totalRows);
455+
const rows = allRows.slice(start, end);
456+
415457
return new Promise(resolve => {
416458
setTimeout(() => {
417459
resolve({ total: totalRows, rows });
@@ -442,7 +484,12 @@ <h3>Header Props (sortable, sortKey, width, colspan, rowspan, textAlign)</h3>
442484
serverTable.isLoading = true;
443485

444486
try {
445-
const response = await mockApi({ page, itemsPerPage });
487+
const response = await mockApi({
488+
page,
489+
itemsPerPage,
490+
sortKey: serverSort.key,
491+
sortDirection: serverSort.direction
492+
});
446493
serverTable.dataLength = response.total;
447494
renderServerRows(response.rows);
448495
} finally {
@@ -454,5 +501,11 @@ <h3>Header Props (sortable, sortKey, width, colspan, rowspan, textAlign)</h3>
454501
await loadServerPage(Number(serverTable.currentPage || 1));
455502
});
456503

504+
serverTable.addEventListener("sgds-sort", async event => {
505+
serverSort.key = event.detail.key;
506+
serverSort.direction = event.detail.direction;
507+
await loadServerPage(Number(serverTable.currentPage || 1));
508+
});
509+
457510
loadServerPage(1);
458511
</script>

0 commit comments

Comments
 (0)