diff --git a/src/Table/README.md b/src/Table/README.md index 31ba60a6c..d009d6b52 100644 --- a/src/Table/README.md +++ b/src/Table/README.md @@ -11,6 +11,18 @@ You can render a simple use-case of the table by specifying a list of records an /> ``` +### With Fixed Layout + +Tables perform better with a forced fixed layout, since the browser doesn't have to recalculate positions depending on the contents of the table. Here's what the same table looks like with a fixed layout. + +```js + +``` + ### Simple Usage without Header ```js @@ -78,6 +90,63 @@ const data = [ /> ``` +### With custom widths per column + +We can customize the look of the table by specifying a `width` property on certain columns. + +```jsx +const data = [ + { + name: "Mega Deal Dev", + lastUpdated: "2018-06-06", + tags: ["agent-view", "production"], + collaborators: [ + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + ], + }, + { + name: "Mega Deal Dev", + lastUpdated: "2018-06-06", + tags: ["agent-view", "production"], + collaborators: [ + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + ], + }, + { + name: "Toy Bundle", + lastUpdated: "2018-06-06", + tags: ["agent-view", "production"], + collaborators: [ + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + { photo: "https://graph.facebook.com/775278331/picture", name: "Tejas Kumar" }, + ], + }, +] +;
}, + { heading: "Name", width: 600, cell: dataEntry => dataEntry.name }, + { heading: "Last updated", cell: dataEntry => dataEntry.lastUpdated }, + { + heading: "Tags", + width: 100, + cell: dataEntry => dataEntry.tags.map((tag, tagIndex) => {tag}), + }, + { heading: "Collaborators", cell: dataEntry => }, + ]} + onRowClick={(dataEntry, i) => console.log({ dataEntry, i })} +/> +``` + ### With icons ```jsx diff --git a/src/Table/Table.tsx b/src/Table/Table.tsx index a9898f311..aed11414d 100644 --- a/src/Table/Table.tsx +++ b/src/Table/Table.tsx @@ -23,6 +23,8 @@ export interface TableProps extends DefaultProps { iconColor?: (dataEntry: T) => string /** Remove the header? */ headless?: boolean + /** Fixed Layout for performance */ + fixedLayout?: boolean } export interface Column { @@ -30,15 +32,17 @@ export interface Column { cell: (dataEntry: T, index: number) => React.ReactNode sortOrder?: "asc" | "desc" onSortClick?: (order: "asc" | "desc") => void + width?: number } -const Container = styled("table")(({ theme }) => ({ +const Container = styled("table")<{ fixedLayout: TableProps["fixedLayout"] }>(({ theme, fixedLayout }) => ({ width: "100%", backgroundColor: theme.color.white, textAlign: "left", borderCollapse: "collapse", fontSize: theme.font.size.small, fontFamily: theme.font.family.main, + tableLayout: fixedLayout ? "fixed" : "initial", })) const Tr = styled("tr")<{ hover?: boolean; clickable?: boolean }>(({ hover, theme, clickable }) => ({ @@ -88,13 +92,21 @@ const ThContent = styled("span")<{ sorted?: boolean }>` ${props => props.sorted && `color: ${props.theme.color.text.light};`}; ` -const Td = styled("td")(({ theme }) => ({ +const Td = styled("td")<{ cellWidth?: Column["width"] }>(({ theme, cellWidth }) => ({ verticalAlign: "middle", borderBottom: `1px solid ${theme.color.separators.default}`, color: theme.color.text.default, + hyphens: "auto", "&:first-child": { paddingLeft: theme.space.small, }, + ...(cellWidth + ? { + width: cellWidth, + wordBreak: "break-all", + wordWrap: "break-word", + } + : {}), })) const Actions = styled(Td)(({ theme }) => ({ @@ -148,6 +160,7 @@ function Table({ icon, iconColor, headless, + fixedLayout, ...props }: TableProps) { const standardizedColumns: Array> = columns.map(column => { @@ -164,7 +177,7 @@ function Table({ const hasIcons: boolean = Boolean(data[0]) && Boolean(icon) && Boolean(icon!(data[0])) return ( - + {!headless && ( @@ -234,7 +247,9 @@ function Table({ )} {standardizedColumns.map((column, columnIndex) => ( - + ))} {rowAction} {onRowClick && diff --git a/src/Table/__tests__/__snapshots__/Table.test.tsx.snap b/src/Table/__tests__/__snapshots__/Table.test.tsx.snap index d712a3aff..b09dcdeeb 100644 --- a/src/Table/__tests__/__snapshots__/Table.test.tsx.snap +++ b/src/Table/__tests__/__snapshots__/Table.test.tsx.snap @@ -8,7 +8,7 @@ exports[`Table Component Should render 1`] = ` class="css-ar73w8-Messages" />
{column.cell(dataEntry, dataEntryIndex)} + {column.cell(dataEntry, dataEntryIndex)} +
There are no records available