From a659c7e282915389f6dee05469a508f54c6bee51 Mon Sep 17 00:00:00 2001 From: Andres Date: Fri, 4 Aug 2023 14:29:08 +0200 Subject: [PATCH] add table --- src/components/ui/table/table.stories.tsx | 97 ++++++++++++++++++++++- src/components/ui/table/table.tsx | 45 +++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/src/components/ui/table/table.stories.tsx b/src/components/ui/table/table.stories.tsx index b31fb55..6e88ecc 100644 --- a/src/components/ui/table/table.stories.tsx +++ b/src/components/ui/table/table.stories.tsx @@ -1,6 +1,19 @@ +import { useMemo, useState } from 'react' + import { Meta } from '@storybook/react' -import { Table, TableBody, TableCell, TableEmpty, TableHead, TableHeadCell, TableRow } from './' +import { + Column, + Sort, + Table, + TableBody, + TableCell, + TableEmpty, + TableHead, + TableHeadCell, + TableHeader, + TableRow, +} from './' import { Typography } from '@/components' @@ -122,7 +135,89 @@ export const WithMapMethod = { ), }, } +const data2 = [ + { + title: 'Project A', + cardsCount: 10, + updated: '2023-07-07', + createdBy: 'John Doe', + }, + { + title: 'Project B', + cardsCount: 5, + updated: '2023-07-06', + createdBy: 'Jane Smith', + }, + { + title: 'Project C', + cardsCount: 8, + updated: '2023-07-05', + createdBy: 'Alice Johnson', + }, + { + title: 'Project D', + cardsCount: 3, + updated: '2023-07-07', + createdBy: 'Bob Anderson', + }, + { + title: 'Project E', + cardsCount: 12, + updated: '2023-07-04', + createdBy: 'Emma Davis', + }, +] +const columns: Array = [ + { + key: 'name', + title: 'Name', + sortable: true, + }, + { + key: 'cardsCount', + title: 'Cards', + sortable: true, + }, + { + key: 'updated', + title: 'Last Updated', + }, + { + key: 'createdBy', + title: 'Created by', + }, +] + +export const WithSort = { + render: () => { + const [sort, setSort] = useState(null) + const sortedString = useMemo(() => { + if (!sort) return null + + return `${sort.key}-${sort.direction}` + }, [sort]) + + console.log(sortedString) + + return ( + + + + {data2.map(item => ( + + + + + + + + ))} + +
{item.title}{item.cardsCount}{item.updated}{item.createdBy}icons...
+ ) + }, +} export const Empty = { render: () => , } diff --git a/src/components/ui/table/table.tsx b/src/components/ui/table/table.tsx index 603012b..15cafb9 100644 --- a/src/components/ui/table/table.tsx +++ b/src/components/ui/table/table.tsx @@ -20,7 +20,52 @@ export const TableHead = forwardRef, ComponentPropsWithoutRe return } ) +export type Sort = { + key: string + direction: 'asc' | 'desc' +} | null +export type Column = { + key: string + title: string + sortable?: boolean +} +export const TableHeader: FC< + Omit< + ComponentPropsWithoutRef<'thead'> & { + columns: Column[] + sort?: Sort + onSort?: (sort: Sort) => void + }, + 'children' + > +> = ({ columns, sort, onSort, ...restProps }) => { + const handleSort = (key: string, sortable?: boolean) => () => { + if (!onSort || !sortable) return + + if (sort?.key !== key) return onSort({ key, direction: 'asc' }) + + if (sort.direction === 'desc') return onSort(null) + + return onSort({ + key, + direction: sort?.direction === 'asc' ? 'desc' : 'asc', + }) + } + + return ( + + + {columns.map(({ title, key, sortable }) => ( + + {title} + {sort && sort.key === key && {sort.direction === 'asc' ? '▲' : '▼'}} + + ))} + + + ) +} export const TableBody = forwardRef, ComponentPropsWithoutRef<'tbody'>>( ({ ...rest }, ref) => { return