1
0
forked from baron/baron-sso

common 정렬 헬퍼 공통화 및 devfront 목록 정렬 추가

This commit is contained in:
2026-05-12 09:43:11 +09:00
parent a0713df85a
commit a2a6938246
6 changed files with 347 additions and 110 deletions

View File

@@ -4,3 +4,5 @@ export function mergeClassNames(
) {
return mergeFn(...classNames);
}
export * from "./sort";

97
common/core/utils/sort.ts Normal file
View File

@@ -0,0 +1,97 @@
export type SortDirection = "asc" | "desc";
export type SortConfig<Key extends string = string> = {
key: Key;
direction: SortDirection;
};
export type SortableValue = string | number | boolean | Date | null | undefined;
export type SortResolver<T> = (item: T) => SortableValue;
export type SortResolverMap<T, Key extends string = string> = Partial<
Record<Key, SortResolver<T>>
>;
function normalizeSortableValue(value: SortableValue) {
if (value instanceof Date) {
return value.getTime();
}
if (typeof value === "string") {
return value.toLocaleLowerCase();
}
if (typeof value === "boolean") {
return value ? 1 : 0;
}
return value;
}
export function compareNullableValues(
left: SortableValue,
right: SortableValue,
direction: SortDirection,
) {
if (left === right) {
return 0;
}
if (left === null || left === undefined) {
return 1;
}
if (right === null || right === undefined) {
return -1;
}
const normalizedLeft = normalizeSortableValue(left);
const normalizedRight = normalizeSortableValue(right);
if (normalizedLeft === normalizedRight) {
return 0;
}
if (normalizedLeft === null || normalizedLeft === undefined) {
return 1;
}
if (normalizedRight === null || normalizedRight === undefined) {
return -1;
}
const comparison = normalizedLeft < normalizedRight ? -1 : 1;
return direction === "asc" ? comparison : -comparison;
}
export function toggleSort<Key extends string>(
current: SortConfig<Key> | null,
key: Key,
): SortConfig<Key> {
if (current?.key === key && current.direction === "asc") {
return { key, direction: "desc" };
}
return { key, direction: "asc" };
}
export function sortItems<T, Key extends string = string>(
items: T[],
sortConfig: SortConfig<Key> | null,
resolverMap: SortResolverMap<T, Key> = {},
) {
if (!sortConfig) {
return [...items];
}
const resolveValue =
resolverMap[sortConfig.key] ??
((item: T) =>
(item as Record<string, SortableValue>)[sortConfig.key] ?? null);
return [...items].sort((left, right) =>
compareNullableValues(
resolveValue(left),
resolveValue(right),
sortConfig.direction,
),
);
}