diff --git a/.husky/pre-commit b/.husky/pre-commit index 0312b76..d0a7784 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - npx lint-staged \ No newline at end of file diff --git a/package.json b/package.json index 28e1196..76bcf89 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "lint": "eslint .", "preview": "vite preview", "postinstall": "node scripts/setup-git-hooks.cjs", - "prepare": "husky && husky install" + "prepare": "husky" }, "lint-staged": { "**/*.{js,jsx}": [ diff --git a/src/components/Table.tsx b/src/components/Table.tsx new file mode 100644 index 0000000..c0d7093 --- /dev/null +++ b/src/components/Table.tsx @@ -0,0 +1,108 @@ +import { + HTMLAttributes, + ReactNode, + TableHTMLAttributes, + TdHTMLAttributes, +} from "react"; + +import { cn } from "@/utils/cn"; + +interface TableProps extends TableHTMLAttributes { + data: T[]; + headRow: () => ReactNode; + bodyRow: (params: T) => ReactNode; + footerRow?: () => ReactNode; +} + +function Table({ + data, + className, + headRow, + bodyRow, + footerRow, + ...props +}: TableProps) { + return ( +
+ {/* ───── 스크롤이 필요한 영역 ───── */} +
+ + {headRow()} + {data.map(bodyRow)} +
+
+ + {/* ──── 스크롤과 무관한 하단 영역 ───── */} + {footerRow && ( + + {footerRow()} +
+ )} +
+ ); +} + +interface TrProps extends HTMLAttributes { + showLastBottomBorder?: boolean; +} + +function Tr({ children, className, showLastBottomBorder, ...props }: TrProps) { + const tableRowClassName = cn( + showLastBottomBorder ? "border-b-[1px]" : "not-last:border-b-[1px]", + "border-gray-20", + className, + ); + + return ( + + {children} + + ); +} + +function Th({ + children, + className, + ...props +}: TdHTMLAttributes) { + const thClassName = cn( + "px-3.5 py-3 text-sm font-normal", + "first:sticky left-0 border-gray-20 z-10 bg-red-50", + className, + ); + + return ( + + {children} + + ); +} + +interface TdProps extends TdHTMLAttributes { + noSticky?: boolean; +} + +function Td({ children, className, noSticky, ...props }: TdProps) { + const tdClassName = cn( + "px-3.5 py-3 break-words whitespace-normal", + noSticky ? "" : "first:sticky left-0 z-10 bg-white first:whitespace-nowrap", + className, + ); + return ( + + {children} + + ); +} + +Table.Tr = Tr; +Table.Th = Th; +Table.Td = Td; + +export default Table;