feat: implement resizable table headers in TableEditBetter component

This commit is contained in:
faisolavolut 2025-02-21 07:55:28 +07:00
parent 24c57e6896
commit 53f11cb47a
3 changed files with 70 additions and 18 deletions

View File

@ -1,5 +1,5 @@
"use client"; "use client";
import React, { useEffect, useState } from "react"; import React, { FC, useEffect, useState } from "react";
import { Table } from "flowbite-react"; import { Table } from "flowbite-react";
import { HiChevronLeft, HiChevronRight } from "react-icons/hi"; import { HiChevronLeft, HiChevronRight } from "react-icons/hi";
import { useLocal } from "@/lib/utils/use-local"; import { useLocal } from "@/lib/utils/use-local";
@ -8,6 +8,8 @@ import { toast } from "sonner";
import { Loader2, Sticker } from "lucide-react"; import { Loader2, Sticker } from "lucide-react";
import { getNumber } from "@/lib/utils/getNumber"; import { getNumber } from "@/lib/utils/getNumber";
import { formatMoney } from "@/lib/components/form/field/TypeInput"; import { formatMoney } from "@/lib/components/form/field/TypeInput";
import "react-resizable/css/styles.css";
import { Resizable } from "react-resizable";
export const TableEditBetter: React.FC<any> = ({ export const TableEditBetter: React.FC<any> = ({
name, name,
column, column,
@ -144,7 +146,7 @@ export const TableEditBetter: React.FC<any> = ({
? defaultColumns.map((e: any) => { ? defaultColumns.map((e: any) => {
return { return {
...e, ...e,
width: e?.width || "auto", width: e?.width || 150,
}; };
}) })
: ([] as any[]); : ([] as any[]);
@ -241,20 +243,19 @@ export const TableEditBetter: React.FC<any> = ({
<tr className={"table-header-tbl"}> <tr className={"table-header-tbl"}>
{columns.map((col, idx) => { {columns.map((col, idx) => {
return ( return (
<th <HeaderColumn
col={col}
key={`${col?.accessorKey}_${idx}`} key={`${col?.accessorKey}_${idx}`}
className={"table-header-tbl capitalize"} width={col.width}
style={{ height={0}
width: onResize={(e: any, { size }: any) =>
col.width === "auto" handleResize(idx, size.width)
? "auto" }
: `${col.width}px`,
}}
> >
<div className="flex items-center h-full flex-grow p-2"> <div className="flex items-center h-full flex-grow p-2">
<span>{col?.header()}</span> <span>{col?.header()}</span>
</div> </div>
</th> </HeaderColumn>
); );
})} })}
</tr> </tr>
@ -336,7 +337,62 @@ export const TableEditBetter: React.FC<any> = ({
</> </>
); );
}; };
const HeaderColumn: FC<any> = ({ children, width, height, onResize, col }) => {
const [isResizing, setIsResizing] = useState(false);
const handleResizeStart = () => {
setIsResizing(true);
};
const handleResizeStop = () => {
setIsResizing(false);
};
return (
<Resizable
onResizeStart={handleResizeStart}
onResizeStop={handleResizeStop}
width={width}
height={height}
onResize={onResize}
>
<th
className="table-header-tbl capitalize relative"
style={{ width: col.width }}
>
{children}
<div
className={cx(
css`
position: absolute;
right: 0;
top: 0;
height: 100%;
width: 5px;
background: transparent;
cursor: e-resize;
transition: background 0.2s ease;
&:hover {
background: #4a90e2; /* Warna biru saat hover */
}
&:active {
background: #357abd; /* Warna biru lebih gelap saat di-resize */
}
${isResizing &&
css`
background: #357abd; /* Warna biru lebih gelap saat resize aktif */
opacity: 0.8;
`}
`
)}
></div>
</th>
</Resizable>
);
};
export const Pagination: React.FC<any> = ({ export const Pagination: React.FC<any> = ({
onNextPage, onNextPage,
onPrevPage, onPrevPage,

View File

@ -1,11 +1,8 @@
{ {
"name": "julong-flowbite",
"version": "0.1.0",
"private": true,
"dependencies": { "dependencies": {
"@emotion/css": "^11.13.5", "@emotion/css": "^11.13.5",
"@faker-js/faker": "^9.2.0", "@faker-js/faker": "^9.2.0",
"@floating-ui/react": "^0.27.4", "@floating-ui/react": "^0.26.28",
"@radix-ui/react-accordion": "^1.2.2", "@radix-ui/react-accordion": "^1.2.2",
"@radix-ui/react-alert-dialog": "^1.1.2", "@radix-ui/react-alert-dialog": "^1.1.2",
"@radix-ui/react-checkbox": "^1.1.3", "@radix-ui/react-checkbox": "^1.1.3",
@ -50,7 +47,6 @@
"flowbite": "^2.5.2", "flowbite": "^2.5.2",
"flowbite-react": "^0.10.2", "flowbite-react": "^0.10.2",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"julong-flowbite": "file:",
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
"lodash.uniqby": "^4.7.0", "lodash.uniqby": "^4.7.0",
"lucide-react": "^0.462.0", "lucide-react": "^0.462.0",

View File

@ -32,7 +32,7 @@ export const showApprovel = (
column: ["hrd_ho_unit"], column: ["hrd_ho_unit"],
level: ["Level HRD HO"], level: ["Level HRD HO"],
}, },
]; // tiga status yang dapat memunculkan approval ];
const role = { const role = {
head: permision.find((e) => e === "approval-mpr-dept-head"), head: permision.find((e) => e === "approval-mpr-dept-head"),
dir: permision.find((e) => e === "approval-mpr-vp"), dir: permision.find((e) => e === "approval-mpr-vp"),