New Changes with table Classes and Modification
This commit is contained in:
+75
-14
@@ -12,6 +12,8 @@ const {
|
|||||||
pageSize = 10,
|
pageSize = 10,
|
||||||
fetchData,
|
fetchData,
|
||||||
columnsRendererKey,
|
columnsRendererKey,
|
||||||
|
classInfos = "",
|
||||||
|
tableClassNames = "",
|
||||||
} = Astro.props as TableProps<any>;
|
} = Astro.props as TableProps<any>;
|
||||||
|
|
||||||
const id = `table-${Math.random().toString(36).slice(2, 9)}`;
|
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"
|
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
|
<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
|
<thead
|
||||||
class="wr:bg-gray-100 wr:dark:bg-neutral-700 wr:text-gray-600 wr:dark:text-gray-300"
|
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) => (
|
columns.map((col) => (
|
||||||
<th
|
<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}` : ""}
|
style={col.width ? `width:${col.width}` : ""}
|
||||||
data-sort-key={
|
data-sort-key={
|
||||||
col.sortable ? col.key : undefined
|
col.sortable ? col.key : undefined
|
||||||
@@ -128,6 +138,7 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
|
|||||||
columns,
|
columns,
|
||||||
data,
|
data,
|
||||||
columnsRendererKey,
|
columnsRendererKey,
|
||||||
|
classInfos,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
const start = () => {
|
const start = () => {
|
||||||
@@ -161,6 +172,20 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
|
|||||||
</svg>`;
|
</svg>`;
|
||||||
|
|
||||||
const fetchDataFn = fetchData ? window[fetchData] : null;
|
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 */
|
/** 🧱 Render rows */
|
||||||
function renderRows(dataset) {
|
function renderRows(dataset) {
|
||||||
@@ -168,9 +193,19 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
|
|||||||
mobileBody.innerHTML = "";
|
mobileBody.innerHTML = "";
|
||||||
|
|
||||||
dataset.forEach((row, i) => {
|
dataset.forEach((row, i) => {
|
||||||
|
const rowCls = resolveClasses(classNames?.row, row, i);
|
||||||
|
|
||||||
// 🖥️ Desktop
|
// 🖥️ 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">`;
|
let tr = `<tr class="${[
|
||||||
columns.forEach((col) => {
|
"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] ?? "";
|
let value = row[col.key] ?? "";
|
||||||
|
|
||||||
const renderers = columnsRendererKey
|
const renderers = columnsRendererKey
|
||||||
@@ -183,30 +218,56 @@ const id = `table-${Math.random().toString(36).slice(2, 9)}`;
|
|||||||
if (col.render) {
|
if (col.render) {
|
||||||
value = col.render(value, row);
|
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>`;
|
tr += `</tr>`;
|
||||||
tbody.insertAdjacentHTML("beforeend", tr);
|
tbody.insertAdjacentHTML("beforeend", tr);
|
||||||
|
|
||||||
// 📱 Mobile
|
// 📱 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">`;
|
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] ?? "";
|
let value = row[col.key] ?? "";
|
||||||
|
|
||||||
const renderers = columnsRendererKey
|
const renderers = columnsRendererKey
|
||||||
? window[columnsRendererKey]
|
? window[columnsRendererKey]
|
||||||
: {};
|
: {};
|
||||||
columns.forEach((col) => {
|
columns.forEach((c) => {
|
||||||
if (renderers[col.key]) col.render = renderers[col.key];
|
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 += `
|
card += `
|
||||||
<div class="wr:flex wr:justify-between wr:items-start wr:gap-4">
|
<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: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:text-sm wr:text-gray-800 wr:dark:text-gray-100 wr:text-right wr:max-w-[60%] wr:break-words">${value}</div>
|
||||||
</div>`;
|
</div>`;
|
||||||
});
|
});
|
||||||
card += `</div>`;
|
card += `</div>`;
|
||||||
|
|||||||
Vendored
+1
@@ -12,6 +12,7 @@ declare global {
|
|||||||
myModal_close: any;
|
myModal_close: any;
|
||||||
hls: typeof Hls,
|
hls: typeof Hls,
|
||||||
flvjs: typeof FlvJs
|
flvjs: typeof FlvJs
|
||||||
|
classNames: any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -239,6 +239,18 @@ const data = [
|
|||||||
avatar: "https://i.pravatar.cc/40?img=25",
|
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>
|
<ComponentLayout>
|
||||||
@@ -256,6 +268,17 @@ const data = [
|
|||||||
fetchData="fetchData"
|
fetchData="fetchData"
|
||||||
columnsRendererKey="columnsRenderer"
|
columnsRendererKey="columnsRenderer"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<Table
|
||||||
|
data={studentData}
|
||||||
|
columns={studentColumns}
|
||||||
|
search
|
||||||
|
pagignations
|
||||||
|
classInfos="classNames"
|
||||||
|
tableClassNames="wr:rounded-2xl wr:border-2 wr:border-red-500"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</ComponentLayout>
|
</ComponentLayout>
|
||||||
|
|
||||||
@@ -396,4 +419,20 @@ const data = [
|
|||||||
total,
|
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>
|
</script>
|
||||||
|
|||||||
@@ -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> {
|
export interface Column<T> {
|
||||||
key: keyof T | string;
|
key: keyof T | string;
|
||||||
label: string;
|
label: string;
|
||||||
@@ -18,4 +31,6 @@ export interface TableProps<T> {
|
|||||||
pagignations?: boolean;
|
pagignations?: boolean;
|
||||||
pageSize?: number
|
pageSize?: number
|
||||||
columnsRendererKey?: string
|
columnsRendererKey?: string
|
||||||
|
classInfos?: string;
|
||||||
|
tableClassNames?: string;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user