base
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export * from "./table";
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import React from "react";
|
||||
import { Table } from "./table";
|
||||
|
||||
const meta: Meta<typeof Table> = {
|
||||
title: "Table",
|
||||
component: Table,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
// types
|
||||
type TTableData = {
|
||||
id: string;
|
||||
name: string;
|
||||
age: number;
|
||||
};
|
||||
|
||||
type Story = StoryObj<typeof Table<TTableData>>;
|
||||
|
||||
// data
|
||||
const tableData: TTableData[] = [
|
||||
{ id: "1", name: "Ernest", age: 25 },
|
||||
{ id: "2", name: "Ann", age: 30 },
|
||||
{ id: "3", name: "Russell", age: 35 },
|
||||
{ id: "4", name: "Verna", age: 40 },
|
||||
];
|
||||
|
||||
const tableColumns = [
|
||||
{
|
||||
key: "id",
|
||||
content: "Id",
|
||||
tdRender: (rowData: TTableData) => <span>{rowData.id}</span>,
|
||||
},
|
||||
{
|
||||
key: "name",
|
||||
content: "Name",
|
||||
tdRender: (rowData: TTableData) => <span>{rowData.name}</span>,
|
||||
},
|
||||
{
|
||||
key: "age",
|
||||
content: "Age",
|
||||
tdRender: (rowData: TTableData) => <span>{rowData.age}</span>,
|
||||
},
|
||||
];
|
||||
|
||||
// stories
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
data: tableData,
|
||||
columns: tableColumns,
|
||||
keyExtractor: (rowData) => rowData.id,
|
||||
tableClassName: "bg-gray-100",
|
||||
tHeadClassName: "bg-gray-200",
|
||||
tHeadTrClassName: "text-gray-600 text-left text-13 font-medium",
|
||||
thClassName: "font-medium",
|
||||
tBodyClassName: "bg-gray-100",
|
||||
tBodyTrClassName: "text-gray-600",
|
||||
tdClassName: "font-medium",
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
import React from "react";
|
||||
// helpers
|
||||
import { cn } from "../utils";
|
||||
// types
|
||||
import type { TTableData } from "./types";
|
||||
|
||||
export function Table<T>(props: TTableData<T>) {
|
||||
const {
|
||||
data,
|
||||
columns,
|
||||
keyExtractor,
|
||||
tableClassName = "",
|
||||
tHeadClassName = "",
|
||||
tHeadTrClassName = "",
|
||||
thClassName = "",
|
||||
tBodyClassName = "",
|
||||
tBodyTrClassName = "",
|
||||
tdClassName = "",
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<table className={cn("w-full table-auto overflow-hidden whitespace-nowrap", tableClassName)}>
|
||||
<thead className={cn("divide-y divide-subtle", tHeadClassName)}>
|
||||
<tr className={cn("divide-x divide-subtle text-13 text-primary", tHeadTrClassName)}>
|
||||
{columns.map((column) => (
|
||||
<th key={column.key} className={cn("px-2.5 py-2", thClassName)}>
|
||||
{(column?.thRender && column?.thRender()) || column.content}
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className={cn("divide-y divide-subtle", tBodyClassName)}>
|
||||
{data.map((item) => (
|
||||
<tr
|
||||
key={keyExtractor(item)}
|
||||
className={cn("divide-x divide-subtle text-13 text-secondary", tBodyTrClassName)}
|
||||
>
|
||||
{columns.map((column) => (
|
||||
<td key={`${column.key}-${keyExtractor(item)}`} className={cn("px-2.5 py-2", tdClassName)}>
|
||||
{column.tdRender(item)}
|
||||
</td>
|
||||
))}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
export type TTableColumn<T> = {
|
||||
key: string;
|
||||
content: string;
|
||||
thRender?: () => React.ReactNode;
|
||||
tdRender: (rowData: T) => React.ReactNode;
|
||||
};
|
||||
|
||||
export type TTableData<T> = {
|
||||
data: T[];
|
||||
columns: TTableColumn<T>[];
|
||||
keyExtractor: (rowData: T) => string;
|
||||
// classNames
|
||||
tableClassName?: string;
|
||||
tHeadClassName?: string;
|
||||
tHeadTrClassName?: string;
|
||||
thClassName?: string;
|
||||
tBodyClassName?: string;
|
||||
tBodyTrClassName?: string;
|
||||
tdClassName?: string;
|
||||
};
|
||||
Reference in New Issue
Block a user