refactor: DataTable 컴포넌트 반응형 개선

- 툴바 모바일 세로 스택 레이아웃 전환
- 검색창 w-full sm:w-64 반응형 너비
- 테이블 overflow-x-auto 가로 스크롤 지원
- 페이지네이션 모바일 레이아웃 개선
- 하드코딩 색상(slate-*) → CSS 변수 기반 색상으로 교체

Made-with: Cursor
This commit is contained in:
DDD1542 2026-03-07 03:34:27 +09:00
parent 542fab2140
commit e29c7163ed
1 changed files with 20 additions and 19 deletions

View File

@ -65,17 +65,17 @@ export function DataTable<TData, TValue>({
return (
<div className={cn("space-y-4", className)}>
{/* 테이블 상단 툴바 */}
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2">
{/* 테이블 상단 툴바 - 모바일: 세로 스택, sm 이상: 가로 배치 */}
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:space-x-2">
{searchable && (
<div className="relative">
<Search className="absolute top-2.5 left-2.5 h-4 w-4 text-slate-500" />
<Search className="absolute top-2.5 left-2.5 h-4 w-4 text-muted-foreground" />
<Input
placeholder={searchPlaceholder}
value={globalFilter ?? ""}
onChange={(event) => setGlobalFilter(event.target.value)}
className="w-64 pl-8"
className="w-full pl-8 sm:w-64"
/>
</div>
)}
@ -98,15 +98,15 @@ export function DataTable<TData, TValue>({
</div>
</div>
{/* 테이블 */}
<div className="rounded-md border">
{/* 테이블 - 가로 스크롤 지원 */}
<div className="overflow-x-auto rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id} className="bg-slate-50">
<TableHead key={header.id} className="bg-muted/50">
{header.isPlaceholder ? null : (
<div
className={cn(
@ -143,7 +143,7 @@ export function DataTable<TData, TValue>({
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
className={cn(onRowClick ? "cursor-pointer hover:bg-slate-50" : "")}
className={cn(onRowClick ? "cursor-pointer hover:bg-muted/50" : "")}
onClick={() => onRowClick?.(row.original)}
>
{row.getVisibleCells().map((cell) => (
@ -162,16 +162,17 @@ export function DataTable<TData, TValue>({
</Table>
</div>
{/* 페이지네이션 */}
<div className="flex items-center justify-between px-2">
<div className="flex-1 text-sm text-slate-600">
{/* 페이지네이션 - 모바일: 세로 스택, sm 이상: 가로 배치 */}
<div className="flex flex-col gap-3 px-2 sm:flex-row sm:items-center sm:justify-between">
<div className="text-center text-sm text-muted-foreground sm:text-left">
{table.getFilteredSelectedRowModel().rows.length} {table.getFilteredRowModel().rows.length}
</div>
<div className="flex items-center space-x-6 lg:space-x-8">
<div className="flex flex-col items-center gap-3 sm:flex-row sm:gap-6 lg:gap-8">
<div className="flex items-center space-x-2">
<p className="text-sm font-medium"> </p>
{/* 모바일에서 "페이지당 행 수" 텍스트 숨김 */}
<p className="hidden text-sm font-medium sm:block"> </p>
<select
className="h-8 w-16 rounded border border-slate-300 text-sm"
className="h-8 w-16 rounded border border-input text-sm"
value={table.getState().pagination.pageSize}
onChange={(e) => {
table.setPageSize(Number(e.target.value));
@ -184,10 +185,10 @@ export function DataTable<TData, TValue>({
))}
</select>
</div>
<div className="flex w-24 items-center justify-center text-sm font-medium">
{table.getState().pagination.pageIndex + 1} / {table.getPageCount()}
</div>
<div className="flex items-center space-x-2">
<div className="flex items-center gap-1">
<div className="flex w-24 items-center justify-center text-sm font-medium">
{table.getState().pagination.pageIndex + 1} / {table.getPageCount()}
</div>
<Button
variant="outline"
className="h-8 w-8 p-0"