diff --git a/docs/guide/sorting.md b/docs/guide/sorting.md index 9a8c8421e7..b8d9c88e02 100644 --- a/docs/guide/sorting.md +++ b/docs/guide/sorting.md @@ -156,8 +156,12 @@ By default, there are 6 built-in sorting functions to choose from: - `alphanumeric` - Sorts by mixed alphanumeric values without case-sensitivity. Slower, but more accurate if your strings contain numbers that need to be naturally sorted. - `alphanumericCaseSensitive` - Sorts by mixed alphanumeric values with case-sensitivity. Slower, but more accurate if your strings contain numbers that need to be naturally sorted. +- `alphanumericIgnoreDiacritics` - Sorts by mixed alphanumeric values without case-sensitivity and ignoring diacritics/accent marks. Slower, but more accurate if your strings contain numbers that need to be naturally sorted. +- `alphanumericIgnoreDiacriticsCaseSensitive` - Sorts by mixed alphanumeric values with case-sensitivity and ignoring diacritics/accent marks. Slower, but more accurate if your strings contain numbers that need to be naturally sorted. - `text` - Sorts by text/string values without case-sensitivity. Faster, but less accurate if your strings contain numbers that need to be naturally sorted. - `textCaseSensitive` - Sorts by text/string values with case-sensitivity. Faster, but less accurate if your strings contain numbers that need to be naturally sorted. +- `textIgnoreDiacritics` - Sorts by text/string values without case-sensitivity and ignoring diacritics/accent marks. Faster, but less accurate if your strings contain numbers that need to be naturally sorted. +- `textIgnoreDiacriticsCaseSensitive` - Sorts by text/string values with case-sensitivity and ignoring diacritics/accent marks. Faster, but less accurate if your strings contain numbers that need to be naturally sorted. - `datetime` - Sorts by time, use this if your values are `Date` objects. - `basic` - Sorts using a basic/standard `a > b ? 1 : a < b ? -1 : 0` comparison. This is the fastest sorting function, but may not be the most accurate. diff --git a/packages/table-core/src/fns/sortFns.ts b/packages/table-core/src/fns/sortFns.ts index ddc8126791..e2f2cd8aa4 100644 --- a/packages/table-core/src/fns/sortFns.ts +++ b/packages/table-core/src/fns/sortFns.ts @@ -33,6 +33,34 @@ export const sortFn_alphanumericCaseSensitive: SortFn = < ) } +export const sortFn_alphanumericIgnoreDiacritics: SortFn = < + TFeatures extends TableFeatures, + TData extends RowData, +>( + rowA: Row, + rowB: Row, + columnId: string, +) => { + return compareAlphanumeric( + normalizeText(toString(rowA.getValue(columnId)).toLowerCase()), + normalizeText(toString(rowB.getValue(columnId)).toLowerCase()), + ) +} + +export const sortFn_alphanumericIgnoreDiacriticsCaseSensitive: SortFn< + any, + any +> = ( + rowA: Row, + rowB: Row, + columnId: string, +) => { + return compareAlphanumeric( + normalizeText(toString(rowA.getValue(columnId))), + normalizeText(toString(rowB.getValue(columnId))), + ) +} + // The text filter is more basic (less numeric support) // but is much faster export const sortFn_text: SortFn = < @@ -65,6 +93,38 @@ export const sortFn_textCaseSensitive: SortFn = < ) } +// The text filter is more basic (less numeric support) +// but is much faster +export const sortFn_textIgnoreDiacritics: SortFn = < + TFeatures extends TableFeatures, + TData extends RowData, +>( + rowA: Row, + rowB: Row, + columnId: string, +) => { + return compareBasic( + normalizeText(toString(rowA.getValue(columnId)).toLowerCase()), + normalizeText(toString(rowB.getValue(columnId)).toLowerCase()), + ) +} + +// The text filter is more basic (less numeric support) +// but is much faster +export const sortFn_textIgnoreDiacriticsCaseSensitive: SortFn = < + TFeatures extends TableFeatures, + TData extends RowData, +>( + rowA: Row, + rowB: Row, + columnId: string, +) => { + return compareBasic( + normalizeText(toString(rowA.getValue(columnId))), + normalizeText(toString(rowB.getValue(columnId))), + ) +} + export const sortFn_datetime: SortFn = < TFeatures extends TableFeatures, TData extends RowData, @@ -112,6 +172,10 @@ function toString(a: any) { return '' } +function normalizeText(str: string): string { + return str.normalize('NFD').replace(/\p{Diacritic}/gu, '') +} + // Mixed sorting is slow, but very inclusive of many edge cases. // It handles numbers, mixed alphanumeric combinations, and even // null, undefined, and Infinity @@ -164,10 +228,15 @@ function compareAlphanumeric(aStr: string, bStr: string) { export const sortFns = { alphanumeric: sortFn_alphanumeric, alphanumericCaseSensitive: sortFn_alphanumericCaseSensitive, + alphanumericIgnoreDiacritics: sortFn_alphanumericIgnoreDiacritics, + alphanumericIgnoreDiacriticsCaseSensitive: + sortFn_alphanumericIgnoreDiacriticsCaseSensitive, basic: sortFn_basic, datetime: sortFn_datetime, text: sortFn_text, textCaseSensitive: sortFn_textCaseSensitive, + textIgnoreDiacritics: sortFn_textIgnoreDiacritics, + textIgnoreDiacriticsCaseSensitive: sortFn_textIgnoreDiacriticsCaseSensitive, } export type BuiltInSortFn = keyof typeof sortFns