diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-07 01:43:36 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-07 01:43:36 +0000 |
| commit | fbb3b7f05737f9571b04b0a8f4f15c0928de8545 (patch) | |
| tree | 343247117a7587b8ef5c418c9528d1cf2e0b6f1c /components/data-table | |
| parent | 9945ad119686a4c3a66f7b57782750f78a366cfb (diff) | |
(대표님) 변경사항 20250707 10시 43분
Diffstat (limited to 'components/data-table')
| -rw-r--r-- | components/data-table/data-table-grobal-filter.tsx | 1 | ||||
| -rw-r--r-- | components/data-table/data-table-sort-list.tsx | 45 | ||||
| -rw-r--r-- | components/data-table/data-table.tsx | 40 |
3 files changed, 58 insertions, 28 deletions
diff --git a/components/data-table/data-table-grobal-filter.tsx b/components/data-table/data-table-grobal-filter.tsx index 240e9fa7..a1f0a6f3 100644 --- a/components/data-table/data-table-grobal-filter.tsx +++ b/components/data-table/data-table-grobal-filter.tsx @@ -17,7 +17,6 @@ export function DataTableGlobalFilter() { eq: (a, b) => a === b, clearOnDefault: true, shallow: false, - history: "replace" }) // Local tempValue to update instantly on user keystroke diff --git a/components/data-table/data-table-sort-list.tsx b/components/data-table/data-table-sort-list.tsx index c3c537ac..c752f2f4 100644 --- a/components/data-table/data-table-sort-list.tsx +++ b/components/data-table/data-table-sort-list.tsx @@ -54,19 +54,30 @@ interface DataTableSortListProps<TData> { shallow?: boolean } +let renderCount = 0; + export function DataTableSortList<TData>({ table, debounceMs, shallow, }: DataTableSortListProps<TData>) { + renderCount++; + const id = React.useId() const initialSorting = (table.initialState.sorting ?? []) as ExtendedSortingState<TData> + // ✅ 파서를 안정화 - 한 번만 생성되도록 수정 + const sortingParser = React.useMemo(() => { + // 첫 번째 행의 데이터를 안정적으로 가져오기 + const sampleData = table.getRowModel().rows[0]?.original; + return getSortingStateParser(sampleData); + }, []); // ✅ 빈 dependency - 한 번만 생성 + const [sorting, setSorting] = useQueryState( "sort", - getSortingStateParser(table.getRowModel().rows[0]?.original) + sortingParser .withDefault(initialSorting) .withOptions({ clearOnDefault: true, @@ -74,6 +85,10 @@ export function DataTableSortList<TData>({ }) ) + // ✅ debouncedSetSorting - 컴포넌트 최상위로 이동 + const debouncedSetSorting = useDebouncedCallback(setSorting, debounceMs); + + // ✅ uniqueSorting 메모이제이션 const uniqueSorting = React.useMemo( () => sorting.filter( @@ -82,8 +97,7 @@ export function DataTableSortList<TData>({ [sorting] ) - const debouncedSetSorting = useDebouncedCallback(setSorting, debounceMs) - + // ✅ sortableColumns 메모이제이션 const sortableColumns = React.useMemo( () => table @@ -100,7 +114,8 @@ export function DataTableSortList<TData>({ [sorting, table] ) - function addSort() { + // ✅ 함수들을 useCallback으로 메모이제이션 + const addSort = React.useCallback(() => { const firstAvailableColumn = sortableColumns.find( (column) => !sorting.some((s) => s.id === column.id) ) @@ -113,9 +128,9 @@ export function DataTableSortList<TData>({ desc: false, }, ]) - } + }, [sortableColumns, sorting, setSorting]); - function updateSort({ + const updateSort = React.useCallback(({ id, field, debounced = false, @@ -123,7 +138,7 @@ export function DataTableSortList<TData>({ id: string field: Partial<ExtendedColumnSort<TData>> debounced?: boolean - }) { + }) => { const updateFunction = debounced ? debouncedSetSorting : setSorting updateFunction((prevSorting) => { @@ -134,13 +149,17 @@ export function DataTableSortList<TData>({ ) return updatedSorting }) - } + }, [debouncedSetSorting, setSorting]); - function removeSort(id: string) { + const removeSort = React.useCallback((id: string) => { void setSorting((prevSorting) => prevSorting.filter((item) => item.id !== id) ) - } + }, [setSorting]); + + const resetSorting = React.useCallback(() => { + setSorting(null); + }, [setSorting]); return ( <Sortable @@ -167,7 +186,7 @@ export function DataTableSortList<TData>({ <ArrowDownUp className="size-3" aria-hidden="true" /> <span className="hidden sm:inline"> - 정렬 + 정렬 </span> {uniqueSorting.length > 0 && ( @@ -357,7 +376,7 @@ export function DataTableSortList<TData>({ size="sm" variant="outline" className="rounded" - onClick={() => setSorting(null)} + onClick={resetSorting} > Reset sorting </Button> @@ -367,4 +386,4 @@ export function DataTableSortList<TData>({ </Popover> </Sortable> ) -} +}
\ No newline at end of file diff --git a/components/data-table/data-table.tsx b/components/data-table/data-table.tsx index 64afcb7e..33fca5b8 100644 --- a/components/data-table/data-table.tsx +++ b/components/data-table/data-table.tsx @@ -25,6 +25,25 @@ interface DataTableProps<TData> extends React.HTMLAttributes<HTMLDivElement> { compact?: boolean // 컴팩트 모드 옵션 추가 } +// ✅ compactStyles를 정적으로 정의 (매번 새로 생성 방지) +const COMPACT_STYLES = { + row: "h-7", // 행 높이 축소 + cell: "py-1 px-2 text-sm", // 셀 패딩 축소 및 폰트 크기 조정 + groupRow: "py-1 bg-muted/20 text-sm", // 그룹 행 패딩 축소 + emptyRow: "h-16", // 데이터 없을 때 행 높이 조정 + header: "py-1 px-2 text-sm", // 헤더 패딩 축소 + headerHeight: "h-8", // 헤더 높이 축소 +}; + +const NORMAL_STYLES = { + row: "", + cell: "", + groupRow: "bg-muted/20", + emptyRow: "h-24", + header: "", + headerHeight: "", +}; + /** * 멀티 그룹핑 + 그룹 토글 + 그룹 컬럼/헤더 숨김 + Indent + 리사이징 + 컴팩트 모드 */ @@ -41,18 +60,11 @@ export function DataTable<TData>({ useAutoSizeColumns(table, autoSizeColumns) - // 컴팩트 모드를 위한 클래스 정의 - const compactStyles = compact ? { - row: "h-7", // 행 높이 축소 - cell: "py-1 px-2 text-sm", // 셀 패딩 축소 및 폰트 크기 조정 - groupRow: "py-1 bg-muted/20 text-sm", // 그룹 행 패딩 축소 - emptyRow: "h-16", // 데이터 없을 때 행 높이 조정 - } : { - row: "", - cell: "", - groupRow: "bg-muted/20", - emptyRow: "h-24", - } + // ✅ compactStyles를 useMemo로 메모이제이션 + const compactStyles = React.useMemo(() => + compact ? COMPACT_STYLES : NORMAL_STYLES, + [compact] + ); return ( <div className={cn("w-full space-y-2.5 overflow-auto", className)} {...props}> @@ -62,7 +74,7 @@ export function DataTable<TData>({ {/* 테이블 헤더 */} <TableHeader> {table.getHeaderGroups().map((headerGroup) => ( - <TableRow key={headerGroup.id} className={compact ? "h-8" : ""}> + <TableRow key={headerGroup.id} className={compactStyles.headerHeight}> {headerGroup.headers.map((header) => { if (header.column.getIsGrouped()) { return null @@ -73,7 +85,7 @@ export function DataTable<TData>({ key={header.id} colSpan={header.colSpan} data-column-id={header.column.id} - className={compact ? "py-1 px-2 text-sm" : ""} + className={compactStyles.header} style={{ ...getCommonPinningStylesWithBorder({ column: header.column, |
