ui 테이블 체크박스 사용시 클래스 타입을 사용 체크

This commit is contained in:
leedj312
2025-07-22 15:37:54 +09:00
parent 7d95ddf6a5
commit a028b6ae8b
@@ -1,14 +1,21 @@
"use client"
"use client";
import { Checkbox, Table, TableBody, TableCell, TableHeader, TableRow } from "@common/components";
import {
Checkbox,
Table,
TableBody,
TableCell,
TableHeader,
TableRow,
} from "@common/components";
import { useEffect, useState, useRef } from "react";
import { HeadMakeColSpan } from "./HeadMakeColSpan";
import UiPageNations from "./uiPageNations";
import { Check } from "lucide-react";
export type ChkClass={
chk:boolean
readonly:boolean
}
export type ChkClass = {
chk: boolean;
readonly: boolean;
};
type UiTableProps = {
headName: React.ReactNode | undefined;
tableData: { [key: string]: any }[];
@@ -23,22 +30,35 @@ type UiTableProps = {
boldArray?: number[];
resetSelection?: boolean;
index?: number;
}
};
type UiHeadProps = {
id: string;
title: string;
align?: string;
visible?: boolean;
}
};
export function UiTable({ tableData, headlist, pageSize, total, headName, children, cellClick, onPageChange, className = '', resetPageNo = false, boldArray = [], resetSelection = false, index = -1 }: UiTableProps) {
export function UiTable({
tableData,
headlist,
pageSize,
total,
headName,
children,
cellClick,
onPageChange,
className = "",
resetPageNo = false,
boldArray = [],
resetSelection = false,
index = -1,
}: UiTableProps) {
const [cur, setCur] = useState<number>(1);
const [idx, setIdx] = useState<number>(index);
const [headerHeight, setHeaderHeight] = useState<number>(0);
const headerRef = useRef<HTMLTableSectionElement>(null);
useEffect(() => {
if (resetPageNo) {
setCur(1);
@@ -54,14 +74,14 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr
useEffect(() => {
if (headerRef.current) {
setHeaderHeight(headerRef.current.offsetHeight-5);
setHeaderHeight(headerRef.current.offsetHeight - 5);
}
}, [tableData, headlist]);
const handlePageChange = (page: number) => {
setCur(page);
onPageChange(page);
}
};
const handleCellClick = (index: number, headId: string) => {
if (cellClick) {
@@ -70,91 +90,158 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr
}
};
return (
<>
{headName ? <div className="card-header">
<h3 className="text-2xl font-medium text-label">{headName}</h3>
</div> : <></>}
<div className={`card !m-[1.2rem] !p-0r ${className}`}>
{headName ? (
<div className="card-header">
<h3 className="text-2xl font-medium text-label">{headName}</h3>
</div>
) : (
<></>
)}
<div className={`card !p-0r !m-[1.2rem] ${className}`}>
<Table variant="secondary">
<TableHeader ref={headerRef} className="font-bold">
{children ? children : <HeadMakeColSpan upHeadList={headlist} />}
</TableHeader>
<TableBody className='text-center'>
{tableData.length > 0 ? tableData?.map((el: Record<string, unknown>, index) => (
<TableRow key={`row-${index}`}>
{headlist
.filter((item) => item.visible != false)
.map((head) => (
head.id && head.id.length > 1 && (
boldArray.includes(index)
?
<TableCell
className={`${head.align === 'right' ? 'text-right' : head.align === 'center' ? 'text-center' : 'text-center'} ${cellClick && idx === index ? '!font-[1000] cursor-pointer' :
cellClick ? 'cursor-pointer' : ''
} !font-bold sticky bg-secondary z-40`}
style={{ top: `${headerHeight + (index * 39)}px` }}
onClick={() => handleCellClick(index, head.id)}
key={`cell-${head.id}-${index}`}
>
{typeof el[head.id] !== 'number' ? String(el[head.id] ?? '') : String(el[head.id]).includes('.')
? String(el[head.id]).split('.').map((part, index) =>
index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
).join('.')
: String(el[head.id] ?? '').replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
</TableCell>
:
<TableCell
className={`${head.align === 'right' ? 'text-right' : head.align === 'center' ? 'text-center' : 'text-center'} ${cellClick && idx === index ? '!font-[1000] cursor-pointer' :
cellClick ? 'cursor-pointer' : ''
<TableBody className="text-center">
{tableData.length > 0 ? (
tableData?.map((el: Record<string, unknown>, index) => (
<TableRow key={`row-${index}`}>
{headlist
.filter((item) => item.visible != false)
.map(
(head) =>
head.id &&
head.id.length > 1 &&
(boldArray.includes(index) ? (
<TableCell
className={`${head.align === "right" ? "text-right" : head.align === "center" ? "text-center" : "text-center"} ${
cellClick && idx === index
? "cursor-pointer !font-[1000]"
: cellClick
? "cursor-pointer"
: ""
} sticky z-40 bg-secondary !font-bold`}
style={{ top: `${headerHeight + index * 39}px` }}
onClick={() => handleCellClick(index, head.id)}
key={`cell-${head.id}-${index}`}
>
{typeof el[head.id] !== "number"
? String(el[head.id] ?? "")
: String(el[head.id]).includes(".")
? String(el[head.id])
.split(".")
.map((part, index) =>
index === 0
? part.replace(
/\B(?=(\d{3})+(?!\d))/g,
",",
)
: part,
)
.join(".")
: String(el[head.id] ?? "").replace(
/\B(?=(\d{3})+(?!\d))/g,
",",
)}
</TableCell>
) : (
<TableCell
className={`${head.align === "right" ? "text-right" : head.align === "center" ? "text-center" : "text-center"} ${
cellClick && idx === index
? "cursor-pointer !font-[1000]"
: cellClick
? "cursor-pointer"
: ""
} mt-[${boldArray.length * 40}px]`}
onClick={() => handleCellClick(index, head.id)}
key={`cell-${head.id}-${index}`}
>
{typeof el[head.id] === 'object'
? <Checkbox
checked={(el[head.id] as ChkClass).chk === true}
onCheckedChange={(checked) => {
if((el[head.id] as ChkClass).readonly == true) return
(el[head.id] as ChkClass).chk = Boolean(checked);
}}
>
<Check className="h-6 w-6 text-primary" />
</Checkbox>:
typeof el[head.id] === 'boolean'
? <Checkbox
checked={el[head.id] === true}
onCheckedChange={(checked) => {
el[head.id] = checked;
}}
>
<Check className="h-6 w-6 text-primary" />
</Checkbox>
:
typeof el[head.id] !== 'number' ?
String(el[head.id] ?? '') :
String(el[head.id]).includes('.')
? String(el[head.id]).split('.').map((part, index) =>
index === 0 ? part.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : part
).join('.')
:
String(el[head.id] ?? '').replace(/\B(?=(\d{3})+(?!\d))/g, ",")}
</TableCell>
)
))}
</TableRow>
)) : (
onClick={() => handleCellClick(index, head.id)}
key={`cell-${head.id}-${index}`}
>
{
//체크박스 유형애서 readOnly가 필요한 경우를 위해서 ChkClass 를 사용해서 readOnly 처리함.
typeof el[head.id] === "object" &&
el[head.id] !== null &&
"chk" in (el[head.id] as object) &&
"readonly" in (el[head.id] as object) ? (
<Checkbox
checked={
(el[head.id] as ChkClass)?.chk === true
}
onCheckedChange={(checked) => {
{
console.log(el[head.id]);
}
if (
(el[head.id] as ChkClass).readonly == true
)
return;
(el[head.id] as ChkClass).chk =
Boolean(checked);
}}
>
<Check className="h-6 w-6 text-primary" />
</Checkbox>
) : typeof el[head.id] === "boolean" ? (
<Checkbox
checked={el[head.id] === true}
onCheckedChange={(checked) => {
el[head.id] = checked;
}}
>
<Check className="h-6 w-6 text-primary" />
</Checkbox>
) : typeof el[head.id] !== "number" ? (
String(el[head.id] ?? "")
) : String(el[head.id]).includes(".") ? (
String(el[head.id])
.split(".")
.map((part, index) =>
index === 0
? part.replace(
/\B(?=(\d{3})+(?!\d))/g,
",",
)
: part,
)
.join(".")
) : (
String(el[head.id] ?? "").replace(
/\B(?=(\d{3})+(?!\d))/g,
",",
)
)
}
</TableCell>
)),
)}
</TableRow>
))
) : (
<TableRow>
<TableCell colSpan={headlist.filter((item) => item.visible != false).length} className="h-24 text-center text-gray-500">
<TableCell
colSpan={
headlist.filter((item) => item.visible != false).length
}
className="h-24 text-center text-gray-500"
>
조회된 결과가 없습니다.
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
{total <= 0 ? <></> : <UiPageNations total={total} cur={cur} pageSize={pageSize} onPageChange={handlePageChange} />}
{total <= 0 ? (
<></>
) : (
<UiPageNations
total={total}
cur={cur}
pageSize={pageSize}
onPageChange={handlePageChange}
/>
)}
</div>
</>
);
}
}