New Changes with table Classes and Modification

This commit is contained in:
2025-11-06 13:49:12 +05:30
parent 8b354b0889
commit 6cfb3b7750
4 changed files with 130 additions and 14 deletions
+75 -14
View File
@@ -12,6 +12,8 @@ const {
pageSize = 10,
fetchData,
columnsRendererKey,
classInfos = "",
tableClassNames = "",
} = Astro.props as TableProps<any>;
const id = `table-${Math.random().toString(36).slice(2, 9)}`;
@@ -36,7 +38,13 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
class="wr:overflow-x-auto wr:rounded-xl wr:border wr:border-gray-300 wr:dark:border-neutral-700 wr:hidden wr:md:block"
>
<table
class={`wr:w-full wr:text-sm ${striped ? "wr:divide-y wr:divide-gray-200 wr:dark:divide-neutral-700" : ""}`}
class={cn(
`wr:w-full wr:text-sm`,
striped
? "wr:divide-y wr:divide-gray-200 wr:dark:divide-neutral-700"
: "",
tableClassNames,
)}
>
<thead
class="wr:bg-gray-100 wr:dark:bg-neutral-700 wr:text-gray-600 wr:dark:text-gray-300"
@@ -52,7 +60,9 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
{
columns.map((col) => (
<th
class={`wr:py-3 wr:px-4 ${col.align ? `wr:text-${col.align}` : "wr:text-left"} ${col.sortable ? "wr:cursor-pointer" : ""}`}
class={cn(
`wr:py-3 wr:px-4 ${col.align ? `wr:text-${col.align}` : "wr:text-left"} ${col.sortable ? "wr:cursor-pointer" : ""}`,
)}
style={col.width ? `width:${col.width}` : ""}
data-sort-key={
col.sortable ? col.key : undefined
@@ -128,6 +138,7 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
columns,
data,
columnsRendererKey,
classInfos,
}}
>
const start = () => {
@@ -161,6 +172,20 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
</svg>`;
const fetchDataFn = fetchData ? window[fetchData] : null;
const classNames = classInfos ? window[classInfos] : {};
const resolveClasses = (input, ...ctx) => {
if (!input) return "";
const val = typeof input === "function" ? input(...ctx) : input;
if (typeof val === "string") return val;
if (val && typeof val === "object") {
return Object.entries(val)
.filter(([, on]) => !!on)
.map(([cls]) => cls)
.join(" ");
}
return "";
};
/** 🧱 Render rows */
function renderRows(dataset) {
@@ -168,9 +193,19 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
mobileBody.innerHTML = "";
dataset.forEach((row, i) => {
const rowCls = resolveClasses(classNames?.row, row, i);
// 🖥️ Desktop
let tr = `<tr class="wr:transition wr:bg-white wr:dark:bg-neutral-900 wr:hover:bg-gray-100 wr:dark:hover:bg-neutral-700 ${dataset.length - 1 != i && "wr:border-b"} wr:border-gray-300 wr:dark:border-neutral-800">`;
columns.forEach((col) => {
let tr = `<tr class="${[
"wr:transition wr:bg-white wr:dark:bg-neutral-900 wr:hover:bg-gray-100 wr:dark:hover:bg-neutral-700",
dataset.length - 1 != i ? "wr:border-b" : "",
"wr:border-gray-300 wr:dark:border-neutral-800",
rowCls,
]
.filter(Boolean)
.join(" ")}">`;
columns.forEach((col, colIndex) => {
let value = row[col.key] ?? "";
const renderers = columnsRendererKey
@@ -183,30 +218,56 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
if (col.render) {
value = col.render(value, row);
}
tr += `<td class="wr:px-4 wr:py-3">${value}</td>`;
const columnCls = resolveClasses(
classNames?.column,
col,
colIndex,
);
const cellCls = resolveClasses(classNames?.cell, {
row,
value,
col,
i,
colIndex,
});
tr += `<td class="wr:px-4 wr:py-3 ${columnCls} ${cellCls}">${value}</td>`;
});
tr += `</tr>`;
tbody.insertAdjacentHTML("beforeend", tr);
// 📱 Mobile
let card = `<div class="wr:rounded-lg wr:border wr:border-gray-300 wr:dark:border-neutral-700 wr:p-4 wr:space-y-2 wr:bg-white wr:dark:bg-neutral-800">`;
columns.forEach((col) => {
columns.forEach((col, colIndex) => {
let value = row[col.key] ?? "";
const renderers = columnsRendererKey
? window[columnsRendererKey]
: {};
columns.forEach((col) => {
if (renderers[col.key]) col.render = renderers[col.key];
columns.forEach((c) => {
if (renderers[c.key]) c.render = renderers[c.key];
});
if (col.render) value = col.render(value, row);
const columnCls = resolveClasses(
classNames?.column,
col,
colIndex,
);
const cellCls = resolveClasses(classNames?.cell, {
row,
value,
col,
i,
colIndex,
});
if (col.render) {
value = col.render(value, row);
}
card += `
<div class="wr:flex wr:justify-between wr:items-start wr:gap-4">
<div class="wr:text-sm wr:font-medium wr:text-gray-600 wr:dark:text-gray-300">${col.label}</div>
<div class="wr:text-sm wr:text-gray-800 wr:dark:text-gray-100 wr:text-right wr:max-w-[60%] wr:break-words">${value}</div>
<div class="wr:flex wr:justify-between wr:items-start wr:gap-4 ${columnCls} ${cellCls}">
<div class="wr:text-sm wr:font-medium wr:text-gray-600 wr:dark:text-gray-300">${col.label}</div>
<div class="wr:text-sm wr:text-gray-800 wr:dark:text-gray-100 wr:text-right wr:max-w-[60%] wr:break-words">${value}</div>
</div>`;
});
card += `</div>`;
+1
View File
@@ -12,6 +12,7 @@ declare global {
myModal_close: any;
hls: typeof Hls,
flvjs: typeof FlvJs
classNames: any;
}
}
+39
View File
@@ -239,6 +239,18 @@ const data = [
avatar: "https://i.pravatar.cc/40?img=25",
},
];
const studentData = [
{ id: 1, name: "Alice", age: 24, role: "Engineer" },
{ id: 2, name: "Bob", age: 29, role: "Designer" },
{ id: 3, name: "Carol", age: 35, role: "Manager" },
];
const studentColumns = [
{ key: "name", label: "Name", sortable: true },
{ key: "age", label: "Age", sortable: true, align: "right" },
{ key: "role", label: "Role" },
];
---
<ComponentLayout>
@@ -256,6 +268,17 @@ const data = [
fetchData="fetchData"
columnsRendererKey="columnsRenderer"
/>
<br />
<Table
data={studentData}
columns={studentColumns}
search
pagignations
classInfos="classNames"
tableClassNames="wr:rounded-2xl wr:border-2 wr:border-red-500"
/>
</div>
</ComponentLayout>
@@ -396,4 +419,20 @@ const data = [
total,
};
};
window.classNames = {
row: (_row: any, idx: number) => ({
"wr:!bg-gray-50 wr:text-black": _row.role === "Engineer",
}),
column: (col: any) =>
col.key === "age"
? "wr:text-right wr:font-bold wr:bg-yellow-100 wr:text-black"
: "",
cell: ({ value, col }: { value: any; col: any }) =>
typeof value === "number" && col.key === "age" && value > 30
? "wr:text-green-600"
: "",
};
</script>
+15
View File
@@ -1,3 +1,16 @@
export type ClassValue =
| string
| Record<string, boolean>
| ((...args: any[]) => string | Record<string, boolean>);
export type ClassNames = {
table?: ClassValue;
row?: ClassValue;
column?: ClassValue;
cell?: ClassValue;
};
export interface Column<T> {
key: keyof T | string;
label: string;
@@ -18,4 +31,6 @@ export interface TableProps<T> {
pagignations?: boolean;
pageSize?: number
columnsRendererKey?: string
classInfos?: string;
tableClassNames?: string;
}