From ef4c533ebacc2cdc97e518f30e9a9350004fcdfb Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 28 Apr 2025 02:13:30 +0000 Subject: ~20250428 작업사항 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data-table/data-table-advanced-toolbar.tsx | 100 ++++++++- .../data-table/data-table-compact-toggle.tsx | 35 +++ components/data-table/data-table-filter-list.tsx | 2 +- components/data-table/data-table-group-list.tsx | 2 +- components/data-table/data-table-pin-left.tsx | 243 ++++++++++++++++++--- components/data-table/data-table-pin-right.tsx | 150 ++++++++++--- components/data-table/data-table-sort-list.tsx | 2 +- components/data-table/data-table-view-options.tsx | 44 +++- components/data-table/data-table.tsx | 75 ++++--- 9 files changed, 535 insertions(+), 118 deletions(-) create mode 100644 components/data-table/data-table-compact-toggle.tsx (limited to 'components/data-table') diff --git a/components/data-table/data-table-advanced-toolbar.tsx b/components/data-table/data-table-advanced-toolbar.tsx index 7c126c51..256dc125 100644 --- a/components/data-table/data-table-advanced-toolbar.tsx +++ b/components/data-table/data-table-advanced-toolbar.tsx @@ -3,6 +3,8 @@ import * as React from "react" import type { DataTableAdvancedFilterField } from "@/types/table" import { type Table } from "@tanstack/react-table" +import { LayoutGrid, TableIcon } from "lucide-react" +import { Button } from "@/components/ui/button" import { cn } from "@/lib/utils" import { DataTableFilterList } from "@/components/data-table/data-table-filter-list" @@ -14,6 +16,36 @@ import { PinRightButton } from "./data-table-pin-right" import { DataTableGlobalFilter } from "./data-table-grobal-filter" import { DataTableGroupList } from "./data-table-group-list" +// 로컬 스토리지 사용을 위한 훅 +const useLocalStorage = (key: string, initialValue: T): [T, (value: T | ((val: T) => T)) => void] => { + const [storedValue, setStoredValue] = React.useState(() => { + if (typeof window === "undefined") { + return initialValue + } + try { + const item = window.localStorage.getItem(key) + return item ? JSON.parse(item) : initialValue + } catch (error) { + console.error(error) + return initialValue + } + }) + + const setValue = (value: T | ((val: T) => T)) => { + try { + const valueToStore = value instanceof Function ? value(storedValue) : value + setStoredValue(valueToStore) + if (typeof window !== "undefined") { + window.localStorage.setItem(key, JSON.stringify(valueToStore)) + } + } catch (error) { + console.error(error) + } + } + + return [storedValue, setValue] +} + interface DataTableAdvancedToolbarProps extends React.HTMLAttributes { /** @@ -58,6 +90,29 @@ interface DataTableAdvancedToolbarProps * @default true */ shallow?: boolean + + /** + * 컴팩트 모드를 사용할지 여부 (토글 버튼을 숨기려면 null) + * @default true + */ + enableCompactToggle?: boolean | null + + /** + * 초기 컴팩트 모드 상태 + * @default false + */ + initialCompact?: boolean + + /** + * 컴팩트 모드가 변경될 때 호출될 콜백 함수 + */ + onCompactChange?: (isCompact: boolean) => void + + /** + * 컴팩트 모드 상태를 저장할 로컬 스토리지 키 + * @default "dataTableCompact" + */ + compactStorageKey?: string } export function DataTableAdvancedToolbar({ @@ -65,10 +120,30 @@ export function DataTableAdvancedToolbar({ filterFields = [], debounceMs = 300, shallow = true, + enableCompactToggle = true, + initialCompact = false, + onCompactChange, + compactStorageKey = "dataTableCompact", children, className, ...props }: DataTableAdvancedToolbarProps) { + // 컴팩트 모드 상태 관리 + const [isCompact, setIsCompact] = useLocalStorage( + compactStorageKey, + initialCompact + ) + + // 컴팩트 모드 변경 시 콜백 호출 + React.useEffect(() => { + onCompactChange?.(isCompact) + }, [isCompact, onCompactChange]) + + // 컴팩트 모드 토글 핸들러 + const handleToggleCompact = React.useCallback(() => { + setIsCompact(prev => !prev) + }, [setIsCompact]) + return (
({ {...props} >
- + {enableCompactToggle && ( + + )} + ({ debounceMs={debounceMs} shallow={shallow} /> - - - + + +
- {children} + {/* 컴팩트 모드 토글 버튼 */} + {children}
) -} +} \ No newline at end of file diff --git a/components/data-table/data-table-compact-toggle.tsx b/components/data-table/data-table-compact-toggle.tsx new file mode 100644 index 00000000..5c162a03 --- /dev/null +++ b/components/data-table/data-table-compact-toggle.tsx @@ -0,0 +1,35 @@ +"use client" + +import * as React from "react" +import { Button } from "@/components/ui/button" +import { TableIcon, LayoutGrid } from "lucide-react" + +interface DataTableCompactToggleProps { + /** + * 현재 컴팩트 모드 상태 + */ + isCompact: boolean + + /** + * 컴팩트 모드 토글 시 호출될 함수 + */ + onToggleCompact: () => void +} + +export function DataTableCompactToggle({ + isCompact, + onToggleCompact +}: DataTableCompactToggleProps) { + return ( + + ) +} \ No newline at end of file diff --git a/components/data-table/data-table-filter-list.tsx b/components/data-table/data-table-filter-list.tsx index c51d4374..db9f8af9 100644 --- a/components/data-table/data-table-filter-list.tsx +++ b/components/data-table/data-table-filter-list.tsx @@ -82,7 +82,7 @@ export function DataTableFilterList({ }: DataTableFilterListProps) { const params = useParams(); - const lng = params.lng as string; + const lng = params ? (params.lng as string) : 'en'; const { t, i18n } = useTranslation(lng); diff --git a/components/data-table/data-table-group-list.tsx b/components/data-table/data-table-group-list.tsx index cde1cadd..fcae9a79 100644 --- a/components/data-table/data-table-group-list.tsx +++ b/components/data-table/data-table-group-list.tsx @@ -156,7 +156,7 @@ export function DataTableGroupList({ aria-controls={`${id}-group-dialog`} >