Initial commit - Horux Despachos NL
This commit is contained in:
2
packages/shared-ui/src/hooks/index.ts
Normal file
2
packages/shared-ui/src/hooks/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from './use-debounce';
|
||||
export * from './use-table-sort';
|
||||
17
packages/shared-ui/src/hooks/use-debounce.ts
Normal file
17
packages/shared-ui/src/hooks/use-debounce.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
export function useDebounce<T>(value: T, delay: number): T {
|
||||
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedValue(value);
|
||||
}, delay);
|
||||
|
||||
return () => {
|
||||
clearTimeout(handler);
|
||||
};
|
||||
}, [value, delay]);
|
||||
|
||||
return debouncedValue;
|
||||
}
|
||||
56
packages/shared-ui/src/hooks/use-table-sort.ts
Normal file
56
packages/shared-ui/src/hooks/use-table-sort.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
'use client';
|
||||
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
export type SortDir = 'asc' | 'desc';
|
||||
|
||||
/**
|
||||
* Ordenamiento client-side de una tabla.
|
||||
*
|
||||
* Uso:
|
||||
* const { sortedData, sortKey, sortDir, toggleSort, getSortIndicator } = useTableSort(
|
||||
* data,
|
||||
* {
|
||||
* fecha: (row) => new Date(row.fechaEmision).getTime(),
|
||||
* total: (row) => Number(row.totalMxn || 0),
|
||||
* },
|
||||
* 'fecha',
|
||||
* );
|
||||
*/
|
||||
export function useTableSort<T, K extends string>(
|
||||
data: T[] | undefined,
|
||||
accessors: Record<K, (row: T) => number | string>,
|
||||
initialKey: K,
|
||||
initialDir: SortDir = 'desc',
|
||||
) {
|
||||
const [sortKey, setSortKey] = useState<K>(initialKey);
|
||||
const [sortDir, setSortDir] = useState<SortDir>(initialDir);
|
||||
|
||||
const sortedData = useMemo(() => {
|
||||
if (!data) return data;
|
||||
const accessor = accessors[sortKey];
|
||||
const sign = sortDir === 'asc' ? 1 : -1;
|
||||
return [...data].sort((a, b) => {
|
||||
const va = accessor(a);
|
||||
const vb = accessor(b);
|
||||
if (typeof va === 'number' && typeof vb === 'number') {
|
||||
return (va - vb) * sign;
|
||||
}
|
||||
return String(va).localeCompare(String(vb)) * sign;
|
||||
});
|
||||
}, [data, sortKey, sortDir, accessors]);
|
||||
|
||||
const toggleSort = (key: K) => {
|
||||
if (sortKey === key) {
|
||||
setSortDir(sortDir === 'asc' ? 'desc' : 'asc');
|
||||
} else {
|
||||
setSortKey(key);
|
||||
setSortDir('desc');
|
||||
}
|
||||
};
|
||||
|
||||
/** Retorna 'asc' | 'desc' | null según el header sea activo o no */
|
||||
const getSortIndicator = (key: K): SortDir | null => (sortKey === key ? sortDir : null);
|
||||
|
||||
return { sortedData, sortKey, sortDir, toggleSort, getSortIndicator };
|
||||
}
|
||||
Reference in New Issue
Block a user