Skip to content

Commit

Permalink
Create basic table components
Browse files Browse the repository at this point in the history
  • Loading branch information
arkadiuszbachorski committed Jul 5, 2024
1 parent ef3c11f commit 1f8cd2e
Show file tree
Hide file tree
Showing 12 changed files with 7,044 additions and 2,051 deletions.
8,762 changes: 6,711 additions & 2,051 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"@hookform/resolvers": "^3.6.0",
"@stanfordbdhg/design-system": "file:./packages/design-system",
"@t3-oss/env-nextjs": "^0.10.1",
"@tanstack/react-table": "^8.19.2",
"firebase": "^10.12.2",
"next": "^14",
"next-intl": "^3.14.1",
Expand Down
32 changes: 32 additions & 0 deletions packages/design-system/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/design-system/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tooltip": "^1.1.2",
"@tanstack/react-table": "^8.19.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2",
"lucide-react": "^0.383.0",
Expand Down
14 changes: 14 additions & 0 deletions packages/design-system/src/components/DataTable/DataTable.mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { ColumnDef } from '@tanstack/react-table'

export const peopleData = [
{ name: 'John', age: 52 },
{ name: 'Doe', age: 19 },
{ name: 'Lorem', age: 24 },
]

type Person = (typeof peopleData)[number]

export const peopleColumns: Array<ColumnDef<Person>> = [
{ accessorFn: (item) => item.name, header: 'Name' },
{ accessorFn: (item) => item.age, header: 'Age' },
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// This source file is part of the Stanford Biodesign Digital Health ENGAGE-HF open-source project
//
// SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md)
//
// SPDX-License-Identifier: MIT
//
import { type Meta } from '@storybook/react'
import { DataTable } from './DataTable'
import { peopleColumns, peopleData } from './DataTable.mocks'

const meta: Meta<typeof DataTable> = {
title: 'Components/DataTable',
component: DataTable,
parameters: {
layout: 'fullscreen',
},
}

export default meta

export const Default = () => (
<DataTable columns={peopleColumns} data={peopleData} />
)
26 changes: 26 additions & 0 deletions packages/design-system/src/components/DataTable/DataTable.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// This source file is part of the Stanford Biodesign Digital Health ENGAGE-HF open-source project
//
// SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md)
//
// SPDX-License-Identifier: MIT
//
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
import { peopleColumns, peopleData } from './DataTable.mocks'
import { DataTable } from '.'

describe('DataTable', () => {
it('renders table element with respective columns', () => {
render(<DataTable columns={peopleColumns} data={peopleData} />)

const table = screen.getByRole('table')
expect(table).toBeInTheDocument()

const nameHead = screen.getByRole('columnheader', { name: 'Name' })
expect(nameHead).toBeInTheDocument()

const johnCell = screen.getByRole('cell', { name: 'John' })
expect(johnCell).toBeInTheDocument()
})
})
77 changes: 77 additions & 0 deletions packages/design-system/src/components/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
'use client'

import {
type ColumnDef,
flexRender,
getCoreRowModel,
useReactTable,
} from '@tanstack/react-table'
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '../Table'

interface DataTableProps<TData, TValue> {
columns: Array<ColumnDef<TData, TValue>>
data: TData[]
}

export const DataTable = <TData, TValue>({
columns,
data,
}: DataTableProps<TData, TValue>) => {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
})
const rows = table.getRowModel().rows

return (
<div className="rounded-md border">
<Table>
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<TableHead key={header.id}>
{header.isPlaceholder ? null : (
flexRender(
header.column.columnDef.header,
header.getContext(),
)
)}
</TableHead>
))}
</TableRow>
))}
</TableHeader>
<TableBody>
{!rows.length ?
<TableRow>
<TableCell colSpan={columns.length} className="h-24 text-center">
No results.
</TableCell>
</TableRow>
: rows.map((row) => (
<TableRow
key={row.id}
data-state={row.getIsSelected() && 'selected'}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
))
}
</TableBody>
</Table>
</div>
)
}
1 change: 1 addition & 0 deletions packages/design-system/src/components/DataTable/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './DataTable'
54 changes: 54 additions & 0 deletions packages/design-system/src/components/Table/Table.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// This source file is part of the Stanford Biodesign Digital Health ENGAGE-HF open-source project
//
// SPDX-FileCopyrightText: 2023 Stanford University and the project authors (see CONTRIBUTORS.md)
//
// SPDX-License-Identifier: MIT
//
import { type Meta } from '@storybook/react'
import {
Table,
TableBody,
TableCell,
TableFooter,
TableHead,
TableHeader,
TableRow,
} from './Table'

const meta: Meta<typeof Table> = {
title: 'Components/Table',
component: Table,
parameters: {
layout: 'fullscreen',
},
}

export default meta

export const Default = () => (
<Table>
<TableHeader>
<TableRow>
<TableHead>Name</TableHead>
<TableHead>Age</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>John</TableCell>
<TableCell>17</TableCell>
</TableRow>
<TableRow>
<TableCell>Doe</TableCell>
<TableCell>35</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow>
<TableCell>Sum</TableCell>
<TableCell>52</TableCell>
</TableRow>
</TableFooter>
</Table>
)
102 changes: 102 additions & 0 deletions packages/design-system/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import * as React from 'react'
import {
type TdHTMLAttributes,
forwardRef,
type HTMLAttributes,
type ThHTMLAttributes,
} from 'react'
import { cn } from '../../utils/className'

export const Table = forwardRef<
HTMLTableElement,
HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
<div className="relative w-full overflow-auto">
<table
ref={ref}
className={cn('w-full caption-bottom text-sm', className)}
{...props}
/>
</div>
))
Table.displayName = 'Table'

export const TableHeader = forwardRef<
HTMLTableSectionElement,
HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />
))
TableHeader.displayName = 'TableHeader'

export const TableBody = forwardRef<
HTMLTableSectionElement,
HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tbody
ref={ref}
className={cn('[&_tr:last-child]:border-0', className)}
{...props}
/>
))
TableBody.displayName = 'TableBody'

export const TableFooter = forwardRef<
HTMLTableSectionElement,
HTMLAttributes<HTMLTableSectionElement>
>(({ className, ...props }, ref) => (
<tfoot
ref={ref}
className={cn(
'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
className,
)}
{...props}
/>
))
TableFooter.displayName = 'TableFooter'

export const TableRow = forwardRef<
HTMLTableRowElement,
HTMLAttributes<HTMLTableRowElement>
>(({ className, ...props }, ref) => (
<tr
ref={ref}
className={cn(
'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
className,
)}
{...props}
/>
))
TableRow.displayName = 'TableRow'

export const TableHead = forwardRef<
HTMLTableCellElement,
ThHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<th
ref={ref}
className={cn(
'h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0',
className,
)}
{...props}
/>
))
TableHead.displayName = 'TableHead'

export const TableCell = forwardRef<
HTMLTableCellElement,
TdHTMLAttributes<HTMLTableCellElement>
>(({ className, ...props }, ref) => (
<td
ref={ref}
className={cn(
'p-4 text-left align-middle [&:has([role=checkbox])]:pr-0',
className,
)}
{...props}
/>
))
TableCell.displayName = 'TableCell'
1 change: 1 addition & 0 deletions packages/design-system/src/components/Table/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Table'

0 comments on commit 1f8cd2e

Please sign in to comment.