import * as React from "react"; import { DropdownSection, DropdownMenuItem } from "../dropdownMenu"; import { Flex, FlexItem } from "../styleUtils/layout"; import { Text } from "../styleUtils/typography"; import { Icon } from "../icon"; import { SystemIcons } from "../icons/dist/system-icons-enum"; import { greyLightLighten1 } from "../design-tokens/build/js/designTokens"; import { mockTableData } from "./mockTableData.json"; import { Table, Sorter, DropdownMenuCell, EmptyCell, TooltipHeaderCell, MutedCell } from "."; /////////////////////////////////////////////////////////////////////////////// // TESTING GEAR // /////////////////////////////////////////////////////////////////////////////// // A low row-count as a default. Some Storybook-addon tries to stringify the whole content of the page, which makes for a slow dev-cycle. turn this up to e.g. 200 if you want to test how the table behaves under load. alternatively you could have a look at how to convince that addon to not serialize stuff... const ROWS = 20; interface User { id: number; name: string; username: string; email: string; phone?: string; website: string; company: { name: string; }; } const { floor, random } = Math; const getRandomInt = (max: number) => floor(random() * floor(max)); const initialData = mockTableData .slice(0, ROWS) .map((card, index) => ({ ...card, id: index })); function update(data: A[], cursor: number) { const indexToReplace = getRandomInt(data.length); const newEntry = mockTableData[cursor]; return data.map(e => e.id === indexToReplace ? { ...newEntry, name: e.name, id: indexToReplace } : e ); } const defaultColumns = [ { id: "name", header: "Name", render: x => x.name }, { id: "username", header: "Username", render: x => x.username }, { id: "email", header: "Email", render: x => x.email }, { id: "phone", header: "Phone", render: x => x.phone }, { id: "website", header: "Website", render: x => x.website }, { id: "company", header: "Company", render: x => x.company.name } ]; export default { title: "Data Listing/Table", component: Table }; export const Default = () => ( el.id.toString()} columns={defaultColumns} /> ); export const WithVariableCols = () => { const [cols, setCols] = React.useState(defaultColumns); // every second we're changing the columns to show. React.useEffect(() => { let i = 0; const intervalId = setInterval(() => { const toRemove = i % 2 ? [] : ["email", "phone"]; setCols(defaultColumns.filter(c => !toRemove.includes(c.id))); i = i + 1; }, 1000); return () => clearInterval(intervalId); }, [setCols]); return (
el.id.toString()} columns={cols} /> ); }; export const WithUpdatingData = () => { const [items, setItems] = React.useState(initialData); const cursor = React.useRef(ROWS); // update data every couple milliseconds React.useEffect(() => { const timeout = setTimeout(() => { if (cursor.current >= mockTableData.length) { clearTimeout(timeout); } else { setItems(update(items, cursor.current)); cursor.current++; } }, 1000); return () => void clearTimeout(timeout); }, [cursor, items, setItems]); return (
el.id.toString()} columns={defaultColumns} /> ); }; export const ColumnsWithCustomWidths = () => (
el.id.toString()} columns={[ { id: "name", header: "200px", render: x => x.name, initialWidth: "200px" }, { id: "username", header: "200px", render: x => x.username, initialWidth: "200px" }, { id: "email", header: "minmax(300px, 1fr)", render: x => x.email, initialWidth: "minmax(300px, 1fr)" }, { id: "phone", header: "minmax(300px, 1fr)", render: x => x.phone, initialWidth: "minmax(300px, 1fr)" }, { id: "website", header: "minmax(200px, 300px)", render: x => x.website, initialWidth: "minmax(200px, 300px)" }, { id: "company", header: "minmax(200px, 300px)", render: x => x.company.name, initialWidth: "minmax(200px, 300px)" } ]} /> ); export const ColumnsWithWrappingContent = () => (
el.id.toString()} columns={[ { id: "name", header: "Name", render: x => x.name, initialWidth: "100px", contentNoWrap: false }, { id: "username", header: "Username", render: x => x.username, contentNoWrap: false }, { id: "email", header: "E-mail", render: x => x.email, contentNoWrap: false }, { id: "phone", header: "Phone", render: x => x.phone, contentNoWrap: false }, { id: "website", header: "Website", render: x => x.website, contentNoWrap: false }, { id: "company", header: "Company (With Longer Title)", render: x => x.company.name, initialWidth: "200px", contentNoWrap: false } ]} /> ); export const SortableColumns = () => (
el.id.toString()} columns={[ { id: "name", header: 'Sorter.string("name")', render: x => x.name, sorter: Sorter.string("name") }, { id: "id", header: 'Sorter.number("id")', render: x => x.id, sorter: Sorter.number("id") }, { id: "email", header: "Custom sort fn", render: x => x.email, sorter: dir => (a, b) => (dir === "asc" ? 1 : -1) * a.email.localeCompare(b.email) }, { id: "phone", header: 'Sorter.string("phone") with nulls', render: x => x.phone, sorter: Sorter.string("phone") }, { id: "website", header: "No sort", render: x => x.website }, { id: "company", header: "No Sort", render: x => x.company.name } ]} initialSorter={{ by: "name", order: "asc" }} /> ); export const ColumnTextAlignment = () => (
el.id.toString()} columns={[ { id: "name", header: "Left", render: x => x.name, textAlign: "left" }, { id: "id", header: "Right", render: x => x.id, textAlign: "right" }, { id: "email", header: "Center", render: x => x.email, textAlign: "center" }, { id: "phone", header: "Phone", render: x => x.phone }, { id: "website", header: "Website", render: x => x.website }, { id: "company", header: "Company", render: x => x.company.name } ]} /> ); export const ColumnHeaderWithTooltip = () => (
el.id.toString()} columns={[ { id: "email", render: x => x.email, sorter: Sorter.string("email"), header: ( Tooltip with Text Component } > Email ) }, { id: "phone", header: "Phone", render: x => x.phone }, { id: "name", header: ( Name ), render: x => x.name, sorter: Sorter.string("name") }, { id: "website", header: ( Website ), render: x => x.website, sorter: Sorter.string("website") }, { id: "company", render: x => x.company.name, header: ( Company ) } ]} /> ); export const ActionMenuOnEachRow = () => (
el.id.toString()} columns={[ { id: "name", header: "Name", render: x => x.name }, { id: "username", header: "Username", render: x => x.username }, { id: "email", header: "Email", render: x => x.email }, { id: "phone", header: "Phone", render: x => x.phone }, { id: "website", header: "Website", render: x => x.website }, { id: "company", header: "Company", render: x => x.company.name }, { id: "dropdown", header: "", render: () => ( Edit Scale Restart Stop ) } ]} /> ); export const EmptyCells = () => (
el.id.toString()} columns={[ { id: "name", header: "Name", render: x => x.name }, { id: "username", header: "Username", render: () => }, { id: "email", header: "Email", render: x => x.email }, { id: "phone", header: "Phone", render: x => x.phone }, { id: "website", header: "Website", render: x => x.website }, { id: "company", header: "Company", render: x => x.company.name } ]} /> ); export const MutedCells = () => (
el.id.toString()} columns={[ { id: "name", header: "Name", render: x => x.name }, { id: "username", header: "Username", render: x => x.username }, { id: "email", header: "Email", render: x => No email provided }, { id: "phone", header: "Phone", render: x => x.phone }, { id: "website", header: "Website", render: x => x.website }, { id: "company", header: "Company", render: x => x.company.name } ]} /> ); export const CellsRenderedWithReactComponents = () => (
el.id.toString()} columns={[ { id: "name", header: "Name", render: x => ( {x.name} ) }, { id: "username", header: "Username", render: x => ( {x.username} ) }, { id: "email", header: "Email", render: x => ( {x.email} ) }, { id: "phone", header: "Phone", render: x => {x.phone} }, { id: "website", header: "Website", render: x => ( {x.website} ) }, { id: "company", header: "Company", render: x => ( {x.company.name} ) } ]} /> ); export const WithoutStickyFirstColumn = () => (
el.id.toString()} columns={[ { id: "name", header: "Name", render: x => x.name, initialWidth: "minmax(400px, 1fr)" }, { id: "username", header: "Username", render: x => x.username, initialWidth: "400px" }, { id: "email", header: "Email", render: x => x.email, initialWidth: "400px" }, { id: "phone", header: "Phone", render: x => x.phone, initialWidth: "400px" }, { id: "website", header: "Website", render: x => x.website, initialWidth: "400px" }, { id: "company", header: "Company", render: x => x.company.name, initialWidth: "400px" } ]} stickyFirstCol={false} /> ); export const UsingOnStateChange = () => ( <>

Resize a column and check the browser console.

el.id.toString()} onStateChange={state => { // TODO: make this work with storybook actions console.log(state); }} columns={defaultColumns} /> );