summaryrefslogtreecommitdiff
path: root/components/data-table
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-07-07 01:43:36 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-07-07 01:43:36 +0000
commitfbb3b7f05737f9571b04b0a8f4f15c0928de8545 (patch)
tree343247117a7587b8ef5c418c9528d1cf2e0b6f1c /components/data-table
parent9945ad119686a4c3a66f7b57782750f78a366cfb (diff)
(대표님) 변경사항 20250707 10시 43분
Diffstat (limited to 'components/data-table')
-rw-r--r--components/data-table/data-table-grobal-filter.tsx1
-rw-r--r--components/data-table/data-table-sort-list.tsx45
-rw-r--r--components/data-table/data-table.tsx40
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,