-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* initial sort working * sort working * make sortable table not stack * address pr comments * tweak sort order check * fix sort bug * switch span to button * fix tests * remove obsolete attr * add tests for sort utils --------- Co-authored-by: Kerry Powell <[email protected]>
- Loading branch information
1 parent
ad2c161
commit 266e660
Showing
11 changed files
with
841 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
packages/web-components/src/components/va-table/sort/alpha.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { CompareFuncReturn } from "./utils"; | ||
|
||
// this function returns a function that sorts strings alphabetically and which can be passed to Array.sort | ||
// the "sordir" argument controls whether the function that is returned sorts ascending or descending | ||
// strings will be sorted alphabetically using local language if "lang" attribute added to the va-table element, otherwise defaults to en-us | ||
export function alphaSort(sortdir: string): CompareFuncReturn { | ||
let locale = this?.el?.getAttribute('lang'); | ||
locale = !!locale ? locale : 'en-US'; | ||
return function alphabeticalSort(a: string, b: string): number { | ||
const isAsc = sortdir === 'ascending'; | ||
const _a = isAsc ? a : b; | ||
const _b = isAsc ? b : a; | ||
return new Intl.Collator(locale, { sensitivity: 'base' }).compare(_a, _b); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
packages/web-components/src/components/va-table/sort/date.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { months } from '../../../utils/constants'; | ||
import { CompareFuncReturn, difference } from "./utils"; | ||
|
||
// conventional date representation or month only will be valid | ||
export function isValidDate(string: string): boolean { | ||
const date = new Date(string); | ||
return !isNaN(date.getTime()) || !!months[string.toLowerCase()]; | ||
} | ||
|
||
// get a numerical representation for a date | ||
function getDateValue(string: string): number { | ||
// treat empty string as earliest date | ||
if (string === '') { | ||
return -Infinity; | ||
} | ||
const month = months[string.toLowerCase()]; | ||
return month ? month : new Date(string).getTime(); | ||
} | ||
|
||
// this function returns a function that sorts date strings and which can be passed to Array.sort | ||
// the "sordir" argument controls whether the function that is returned sorts ascending or descending | ||
export function dateSort(sortdir: string): CompareFuncReturn { | ||
return function datesSort(a: string, b: string): number { | ||
const aTime = getDateValue(a); | ||
const bTime = getDateValue(b); | ||
return difference(aTime, bTime, sortdir); | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
packages/web-components/src/components/va-table/sort/numerical.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { isNumeric } from '../../../utils/utils' | ||
import { CompareFuncReturn, difference } from "./utils"; | ||
import { ordinals } from '../../../utils/constants'; | ||
|
||
const dateRegex = /^(\d{1,2}\/){1,2}(\d{2}|\d{4})$/; | ||
|
||
// check if a string is numeric | ||
export function _isNumeric(string: string): boolean { | ||
const value = cleanString(string); | ||
// isNumeric will return true for a string like 04/02/2024 but we want to treat it like a date | ||
if (dateRegex.test(string)) { | ||
return false | ||
} | ||
if (typeof value === 'number') { | ||
return true; | ||
} | ||
return isNumeric(value); | ||
} | ||
|
||
// make sure that strings with commas/$ (e.g. $2,400) or percent signs | ||
// (e.g. 87 %) or ordinals are treated like numbers | ||
function cleanString(string: string): string | number { | ||
// treat empty string as smallest | ||
if (string === '') { | ||
return -Infinity; | ||
} | ||
const _string = string.toLowerCase(); | ||
if (_string in ordinals) { | ||
return ordinals[_string]; | ||
} | ||
return string.replace(/[$%,]|(th)|(st)|(rd)|(nd)/g, ''); | ||
} | ||
|
||
// this function returns a function that sorts numbers and which can be passed to Array.sort | ||
// the "sordir" argument controls whether the function that is returned sorts ascending or descending | ||
export function numSort(sortdir: string): CompareFuncReturn { | ||
return function numberSort(a: string, b: string): number { | ||
return difference(+cleanString(a), +cleanString(b), sortdir); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
packages/web-components/src/components/va-table/sort/utils.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { numSort, _isNumeric as isNumeric } from './numerical'; | ||
import { dateSort, isValidDate } from './date'; | ||
import { alphaSort } from './alpha'; | ||
|
||
export type CompareFuncReturn = (a: string, b: string) => number; | ||
|
||
// used in numerical or date sorts | ||
export function difference(a: number, b: number, sortdir: string): number { | ||
return sortdir === 'ascending' ? a - b : b - a; | ||
} | ||
|
||
// return the sort function for the data type of the sort | ||
export function _getCompareFunc(a: string, sortdir: string) { | ||
let func: CompareFuncReturn; | ||
if (isNumeric(a)) { | ||
func = numSort(sortdir); | ||
} else if (isValidDate(a)) { | ||
func = dateSort(sortdir); | ||
} else { | ||
func = alphaSort.bind(this)(sortdir); | ||
} | ||
return func; | ||
} | ||
|
||
// for the first non empty piece of data in a column, find the appropriate sort function | ||
// if all values are empty strings, return null to signify do not sort | ||
export function getCompareFunc(rows: Element[], index: number, sortdir: string): CompareFuncReturn | null { | ||
for (const row of rows) { | ||
const cellContents = row.children[index].innerHTML.trim(); | ||
if (cellContents !== '') { | ||
return _getCompareFunc.bind(this)(cellContents, sortdir); | ||
} | ||
} | ||
return null; | ||
} |
Oops, something went wrong.