From 0e0caaae606ea16086d8cbf66a293644f231d61d Mon Sep 17 00:00:00 2001 From: Cahllagerfeld <43843195+Cahllagerfeld@users.noreply.github.com> Date: Tue, 2 Apr 2024 07:44:44 +0000 Subject: [PATCH 1/2] feat: add table components --- package.json | 1 + pnpm-lock.yaml | 20 +++++ src/components/Table/DataTable.stories.tsx | 82 ++++++++++++++++++ src/components/Table/DataTable.tsx | 76 +++++++++++++++++ src/components/Table/Table.stories.tsx | 71 ++++++++++++++++ src/components/Table/Table.tsx | 97 ++++++++++++++++++++++ src/components/Table/index.tsx | 2 + src/components/index.ts | 1 + 8 files changed, 350 insertions(+) create mode 100644 src/components/Table/DataTable.stories.tsx create mode 100644 src/components/Table/DataTable.tsx create mode 100644 src/components/Table/Table.stories.tsx create mode 100644 src/components/Table/Table.tsx create mode 100644 src/components/Table/index.tsx diff --git a/package.json b/package.json index 5babf75..79503e4 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-slot": "^1.0.2", + "@tanstack/react-table": "^8.15.3", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "tailwind-merge": "^2.2.2" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2d574d..507d6ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ dependencies: '@radix-ui/react-slot': specifier: ^1.0.2 version: 1.0.2(@types/react@18.2.28)(react@18.2.0) + '@tanstack/react-table': + specifier: ^8.15.3 + version: 8.15.3(react-dom@18.2.0)(react@18.2.0) '@types/react': specifier: ^18.0.0 version: 18.2.28 @@ -3527,6 +3530,23 @@ packages: file-system-cache: 2.3.0 dev: true + /@tanstack/react-table@8.15.3(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-aocQ4WpWiAh7R+yxNp+DGQYXeVACh5lv2kk96DjYgFiHDCB0cOFoYMT/pM6eDOzeMXR9AvPoLeumTgq8/0qX+w==} + engines: {node: '>=12'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + dependencies: + '@tanstack/table-core': 8.15.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + + /@tanstack/table-core@8.15.3: + resolution: {integrity: sha512-wOgV0HfEvuMOv8RlqdR9MdNNqq0uyvQtP39QOvGlggHvIObOE4exS+D5LGO8LZ3LUXxId2IlUKcHDHaGujWhUg==} + engines: {node: '>=12'} + dev: false + /@testing-library/dom@9.3.3: resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} engines: {node: '>=14'} diff --git a/src/components/Table/DataTable.stories.tsx b/src/components/Table/DataTable.stories.tsx new file mode 100644 index 0000000..399cbb0 --- /dev/null +++ b/src/components/Table/DataTable.stories.tsx @@ -0,0 +1,82 @@ +import { Meta } from "@storybook/react"; +import { StoryObj } from "@storybook/react"; +import React from "react"; +import { DataTable } from "./index"; +import { ColumnDef } from "@tanstack/react-table"; + +type DummyData = { + id: number; + name: string; + age: number; +}; + +const cols: ColumnDef[] = [ + { + id: "id", + header: "ID", + accessorKey: "id" + }, + { + id: "name", + header: "Name", + accessorKey: "name" + }, + { + id: "age", + header: "Age", + accessorKey: "age" + } +]; + +const data: DummyData[] = [ + { + id: 1, + name: "John Doe", + age: 25 + }, + { + id: 2, + name: "Jane Doe", + age: 24 + }, + { + id: 3, + name: "John Smith", + age: 26 + }, + { + id: 4, + name: "Jane Smith", + age: 27 + } +]; + +const meta = { + title: "Elements/Table/DataTable", + component: DataTable, + + parameters: { + layout: "centered" + }, + decorators: [ + (Story) => ( +
+ +
+ ) + ], + tags: ["autodocs"] +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const DefaultVariant: Story = { + name: "Default", + args: { + // @ts-expect-error Something with the type seems off here, it renders correctly though + columns: cols, + data: data + } +}; diff --git a/src/components/Table/DataTable.tsx b/src/components/Table/DataTable.tsx new file mode 100644 index 0000000..a2fd6d0 --- /dev/null +++ b/src/components/Table/DataTable.tsx @@ -0,0 +1,76 @@ +"use client"; + +import { ColumnDef, flexRender, getCoreRowModel, useReactTable } from "@tanstack/react-table"; +import React, { useState } from "react"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "./Table"; + +interface DataTableProps { + columns: ColumnDef[]; + data: TData[]; +} + +export function DataTable({ columns, data }: DataTableProps) { + const [rowSelection, setRowSelection] = useState({}); + const table = useReactTable({ + data, + columns, + onRowSelectionChange: setRowSelection, + getCoreRowModel: getCoreRowModel(), + state: { + rowSelection + } + }); + + return ( +
+ + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder + ? null + : flexRender(header.column.columnDef.header, header.getContext())} + + ); + })} + + ))} + + + {table.getRowModel().rows?.length ? ( + table.getRowModel().rows.map((row) => ( + + {row.getVisibleCells().map((cell) => ( + + {flexRender(cell.column.columnDef.cell, cell.getContext())} + + ))} + + )) + ) : ( + + + No results. + + + )} + +
+
+ ); +} diff --git a/src/components/Table/Table.stories.tsx b/src/components/Table/Table.stories.tsx new file mode 100644 index 0000000..c86a827 --- /dev/null +++ b/src/components/Table/Table.stories.tsx @@ -0,0 +1,71 @@ +import { Meta } from "@storybook/react"; +import { StoryObj } from "@storybook/react"; +import React from "react"; +import { Table, TableHeader, TableBody, TableHead, TableRow, TableCell } from "./index"; + +const rows = ["ID", "Name", "Age"]; +const values = [ + ["1", "John Doe", "25"], + ["2", "Jane Doe", "24"], + ["3", "John Smith", "26"], + ["4", "Jane Smith", "27"] +]; + +const meta = { + title: "Elements/Table/Table", + component: Table, + + parameters: { + layout: "centered" + }, + decorators: [ + (Story) => ( +
+ +
+ ) + ], + tags: ["autodocs"] +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const DefaultVariant: Story = { + name: "Default", + render() { + return ( +
+ + + + {rows.map((rows, index) => { + return ( + + {rows} + + ); + })} + + + + {values.map((value, index) => { + return ( + + {value.map((val, i) => { + return ( + + {val} + + ); + })} + + ); + })} + +
+
+ ); + } +}; diff --git a/src/components/Table/Table.tsx b/src/components/Table/Table.tsx new file mode 100644 index 0000000..f9eb7f3 --- /dev/null +++ b/src/components/Table/Table.tsx @@ -0,0 +1,97 @@ +import * as React from "react"; +import { cn } from "../../utilities"; + +const Table = React.forwardRef>( + ({ className, ...props }, ref) => ( +
+ + + ) +); +Table.displayName = "Table"; + +const TableHeader = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)); +TableHeader.displayName = "TableHeader"; + +const TableBody = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)); +TableBody.displayName = "TableBody"; + +const TableFooter = React.forwardRef< + HTMLTableSectionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( + +)); +TableFooter.displayName = "TableFooter"; + +const TableRow = React.forwardRef>( + ({ className, ...props }, ref) => ( + + ) +); +TableRow.displayName = "TableRow"; + +const TableHead = React.forwardRef< + HTMLTableCellElement, + React.ThHTMLAttributes +>(({ className, ...props }, ref) => ( +
[role=checkbox]]:translate-y-[2px]", + className + )} + {...props} + /> +)); +TableHead.displayName = "TableHead"; + +const TableCell = React.forwardRef< + HTMLTableCellElement, + React.TdHTMLAttributes +>(({ className, ...props }, ref) => ( + [role=checkbox]]:translate-y-[2px]", + className + )} + {...props} + /> +)); +TableCell.displayName = "TableCell"; + +const TableCaption = React.forwardRef< + HTMLTableCaptionElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)); +TableCaption.displayName = "TableCaption"; + +export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption }; diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx new file mode 100644 index 0000000..3d55021 --- /dev/null +++ b/src/components/Table/index.tsx @@ -0,0 +1,2 @@ +export * from "./Table"; +export * from "./DataTable"; diff --git a/src/components/index.ts b/src/components/index.ts index 557fa5c..bbfadeb 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -5,3 +5,4 @@ export * from "./Box"; export * from "./Avatar"; export * from "./Skeleton"; export * from "./Dropdown"; +export * from "./Table"; From 909f4594515e9191c27edef76caffffd3addbd2c Mon Sep 17 00:00:00 2001 From: Cahllagerfeld <43843195+Cahllagerfeld@users.noreply.github.com> Date: Tue, 2 Apr 2024 07:45:15 +0000 Subject: [PATCH 2/2] chore: add changeset --- .changeset/fluffy-hairs-trade.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fluffy-hairs-trade.md diff --git a/.changeset/fluffy-hairs-trade.md b/.changeset/fluffy-hairs-trade.md new file mode 100644 index 0000000..c62ceb2 --- /dev/null +++ b/.changeset/fluffy-hairs-trade.md @@ -0,0 +1,5 @@ +--- +"@zenml-io/react-component-library": minor +--- + +add table components