Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/khaki-readers-drop.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
---
'@primer/react': minor
---

Add Table.Divider and Table.Actions components for Table
7 changes: 6 additions & 1 deletion generated/components.json
Original file line numberDiff line numberDiff line change
Expand Up@@ -2428,7 +2428,12 @@
"name": "DataTable",
"status": "draft",
"a11yReviewed": false,
"stories": [],
"stories": [
{
"id": "components-datatable--default",
"code": "() => (\n <Table.Container>\n <Table.Title as=\"h2\" id=\"repositories\">\n Repositories\n </Table.Title>\n <Table.Subtitle as=\"p\" id=\"repositories-subtitle\">\n A subtitle could appear here to give extra context to the data.\n </Table.Subtitle>\n <DataTable\n aria-labelledby=\"repositories\"\n aria-describedby=\"repositories-subtitle\"\n data={data}\n columns={[\n {\n header: 'Repository',\n field: 'name',\n rowHeader: true,\n },\n {\n header: 'Type',\n field: 'type',\n renderCell: (row) => {\n return <Label>{uppercase(row.type)}</Label>\n },\n },\n {\n header: 'Updated',\n field: 'updatedAt',\n renderCell: (row) => {\n return <RelativeTime date={new Date(row.updatedAt)} />\n },\n },\n {\n header: 'Dependabot',\n field: 'securityFeatures.dependabot',\n renderCell: (row) => {\n return row.securityFeatures.dependabot.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.dependabot.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n {\n header: 'Code scanning',\n field: 'securityFeatures.codeScanning',\n renderCell: (row) => {\n return row.securityFeatures.codeScanning.length > 0 ? (\n <LabelGroup>\n {row.securityFeatures.codeScanning.map((feature) => {\n return <Label key={feature}>{uppercase(feature)}</Label>\n })}\n </LabelGroup>\n ) : null\n },\n },\n ]}\n />\n </Table.Container>\n)"
}
],
"props": [
{
"name": "aria-describedby",
Expand Down
250 changes: 227 additions & 23 deletions src/DataTable/DataTable.features.stories.tsx
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
import {DownloadIcon, PlusIcon} from '@primer/octicons-react'
import {Meta} from '@storybook/react'
import React from 'react'
import {Button, IconButton} from '../Button'
import {DataTable, Table} from '../DataTable'
import Heading from '../Heading'
import Label from '../Label'
import LabelGroup from '../LabelGroup'
import RelativeTime from '../RelativeTime'
Expand DownExpand Up@@ -116,7 +119,67 @@ function uppercase(input: string): string {
return input[0].toUpperCase() + input.slice(1)
}

export const Default = () => (
export const WithTitle = () => (
<Table.Container>
<Table.Title as="h2" id="repositories">
Repositories
</Table.Title>
<DataTable
aria-labelledby="repositories"
aria-describedby="repositories-subtitle"
data={data}
columns={[
{
header: 'Repository',
field: 'name',
rowHeader: true,
},
{
header: 'Type',
field: 'type',
renderCell: row => {
return <Label>{uppercase(row.type)}</Label>
},
},
{
header: 'Updated',
field: 'updatedAt',
renderCell: row => {
return <RelativeTime date={new Date(row.updatedAt)} />
},
},
{
header: 'Dependabot',
field: 'securityFeatures.dependabot',
renderCell: row => {
return row.securityFeatures.dependabot.length > 0 ? (
<LabelGroup>
{row.securityFeatures.dependabot.map(feature => {
return <Label key={feature}>{uppercase(feature)}</Label>
})}
</LabelGroup>
) : null
},
},
{
header: 'Code scanning',
field: 'securityFeatures.codeScanning',
renderCell: row => {
return row.securityFeatures.codeScanning.length > 0 ? (
<LabelGroup>
{row.securityFeatures.codeScanning.map(feature => {
return <Label key={feature}>{uppercase(feature)}</Label>
})}
</LabelGroup>
) : null
},
},
]}
/>
</Table.Container>
)

export const WithTitleAndSubtitle = () => (
<Table.Container>
<Table.Title as="h2" id="repositories">
Repositories
Expand DownExpand Up@@ -179,11 +242,90 @@ export const Default = () => (
</Table.Container>
)

export const WithTitle = () => (
export const WithSorting = () => {
const rows = Array.from(data).sort((a, b) => {
return b.updatedAt - a.updatedAt
})
return (
<Table.Container>
<Table.Title as="h2" id="repositories">
Repositories
</Table.Title>
<Table.Subtitle as="p" id="repositories-subtitle">
A subtitle could appear here to give extra context to the data.
</Table.Subtitle>
<DataTable
aria-labelledby="repositories"
aria-describedby="repositories-subtitle"
data={rows}
columns={[
{
header: 'Repository',
field: 'name',
rowHeader: true,
sortBy: true,
},
{
header: 'Type',
field: 'type',
renderCell: row => {
return <Label>{uppercase(row.type)}</Label>
},
},
{
header: 'Updated',
field: 'updatedAt',
sortBy: true,
renderCell: row => {
return <RelativeTime date={new Date(row.updatedAt)} />
},
},
{
header: 'Dependabot',
field: 'securityFeatures.dependabot',
renderCell: row => {
return row.securityFeatures.dependabot.length > 0 ? (
<LabelGroup>
{row.securityFeatures.dependabot.map(feature => {
return <Label key={feature}>{uppercase(feature)}</Label>
})}
</LabelGroup>
) : null
},
},
{
header: 'Code scanning',
field: 'securityFeatures.codeScanning',
renderCell: row => {
return row.securityFeatures.codeScanning.length > 0 ? (
<LabelGroup>
{row.securityFeatures.codeScanning.map(feature => {
return <Label key={feature}>{uppercase(feature)}</Label>
})}
</LabelGroup>
) : null
},
},
]}
initialSortColumn="updatedAt"
initialSortDirection="DESC"
/>
</Table.Container>
)
}

export const WithAction = () => (
<Table.Container>
<Table.Title as="h2" id="repositories">
Repositories
</Table.Title>
<Table.Actions>
<Button>Action</Button>
</Table.Actions>
<Table.Divider />
<Table.Subtitle as="p" id="repositories-subtitle">
A subtitle could appear here to give extra context to the data.
</Table.Subtitle>
<DataTable
aria-labelledby="repositories"
aria-describedby="repositories-subtitle"
Expand DownExpand Up@@ -239,11 +381,80 @@ export const WithTitle = () => (
</Table.Container>
)

export const WithTitleAndSubtitle = () => (
export const WithActionOnly = () => (
<>
<Heading as="h2" id="table-title">
Repositories
</Heading>
<Table.Container>
<Table.Actions>
<Button>Action</Button>
</Table.Actions>
<DataTable
aria-labelledby="table-title"
data={data}
columns={[
{
header: 'Repository',
field: 'name',
rowHeader: true,
},
{
header: 'Type',
field: 'type',
renderCell: row => {
return <Label>{uppercase(row.type)}</Label>
},
},
{
header: 'Updated',
field: 'updatedAt',
renderCell: row => {
return <RelativeTime date={new Date(row.updatedAt)} />
},
},
{
header: 'Dependabot',
field: 'securityFeatures.dependabot',
renderCell: row => {
return row.securityFeatures.dependabot.length > 0 ? (
<LabelGroup>
{row.securityFeatures.dependabot.map(feature => {
return <Label key={feature}>{uppercase(feature)}</Label>
})}
</LabelGroup>
) : null
},
},
{
header: 'Code scanning',
field: 'securityFeatures.codeScanning',
renderCell: row => {
return row.securityFeatures.codeScanning.length > 0 ? (
<LabelGroup>
{row.securityFeatures.codeScanning.map(feature => {
return <Label key={feature}>{uppercase(feature)}</Label>
})}
</LabelGroup>
) : null
},
},
]}
/>
</Table.Container>
</>
)

export const WithActions = () => (
<Table.Container>
<Table.Title as="h2" id="repositories">
Repositories
</Table.Title>
<Table.Actions>
<IconButton aria-label="Download" icon={DownloadIcon} variant="invisible" />
<IconButton aria-label="Add row" icon={PlusIcon} variant="invisible" />
</Table.Actions>
<Table.Divider />
<Table.Subtitle as="p" id="repositories-subtitle">
A subtitle could appear here to give extra context to the data.
</Table.Subtitle>
Expand DownExpand Up@@ -302,28 +513,24 @@ export const WithTitleAndSubtitle = () => (
</Table.Container>
)

export const WithSorting = () => {
const rows = Array.from(data).sort((a, b) => {
return b.updatedAt - a.updatedAt
})
return (
export const WithActionsOnly = () => (
<>
<Heading as="h2" id="table-title">
Repositories
</Heading>
<Table.Container>
<Table.Title as="h2" id="repositories">
Repositories
</Table.Title>
<Table.Subtitle as="p" id="repositories-subtitle">
A subtitle could appear here to give extra context to the data.
</Table.Subtitle>
<Table.Actions>
<IconButton aria-label="Download" icon={DownloadIcon} variant="invisible" />
<IconButton aria-label="Add row" icon={PlusIcon} variant="invisible" />
</Table.Actions>
<DataTable
aria-labelledby="repositories"
aria-describedby="repositories-subtitle"
data={rows}
aria-labelledby="table-title"
data={data}
columns={[
{
header: 'Repository',
field: 'name',
rowHeader: true,
sortBy: true,
},
{
header: 'Type',
Expand All@@ -335,7 +542,6 @@ export const WithSorting = () => {
{
header: 'Updated',
field: 'updatedAt',
sortBy: true,
renderCell: row => {
return <RelativeTime date={new Date(row.updatedAt)} />
},
Expand DownExpand Up@@ -367,9 +573,7 @@ export const WithSorting = () => {
},
},
]}
initialSortColumn="updatedAt"
initialSortDirection="DESC"
/>
</Table.Container>
)
}
</>
)
Loading