import { Fragment, useState } from 'react'; import { Table, Thead, Tr, Th, Tbody, Td, ExpandableRowContent } from '@patternfly/react-table'; import { Checkbox } from '@patternfly/react-core'; interface Repository { name: string; branches: string; prs: string; workspaces: string; lastCommit: string; details?: { detail1?: string; detail2?: string; detail3?: string; detailFormat: 0 | 1 | 2 | 3; }; } export const TableStripedExpandable: React.FunctionComponent = () => { // In real usage, this data would come from some external source like an API via props. const repositories: Repository[] = [ { name: 'one', branches: 'two', prs: 'a', workspaces: 'four', lastCommit: 'five' }, { name: 'parent 1', branches: 'two', prs: 'k', workspaces: 'four', lastCommit: 'five', // This `details` structure is just for this example. You can drive expanded content from any kind of data. details: { detailFormat: 0, detail1: 'single cell' } }, { name: 'parent 2', branches: 'two', prs: 'b', workspaces: 'four', lastCommit: 'five', details: { detailFormat: 1, detail1: 'single cell - fullWidth' } }, { name: 'parent 3', branches: '2', prs: 'b', workspaces: 'four', lastCommit: 'five', details: { detailFormat: 2, detail1: 'single cell - noPadding' } }, { name: 'parent 4', branches: '2', prs: 'b', workspaces: 'four', lastCommit: 'five', details: { detailFormat: 3, detail1: 'single cell - fullWidth & noPadding' } }, { name: 'parent 5', branches: '2', prs: 'b', workspaces: 'four', lastCommit: 'five', details: { detailFormat: 0, detail1: "spans 'Repositories and 'Branches'", detail2: "spans 'Pull requests' and 'Workspaces', and 'Last commit'" } }, { name: 'parent 6', branches: '2', prs: 'b', workspaces: 'four', lastCommit: 'five', details: { detailFormat: 1, detail1: "fullWidth, spans the collapsible column and 'Repositories'", detail2: "fullWidth, spans 'Branches' and 'Pull requests'", detail3: "fullWidth, spans 'Workspaces' and 'Last commit'" } } ]; const columnNames = { name: 'Repositories', branches: 'Branches', prs: 'Pull requests', workspaces: 'Workspaces', lastCommit: 'Last commit' }; // In this example, expanded rows are tracked by the repo names from each row. This could be any unique identifier. // This is to prevent state from being based on row order index in case we later add sorting. // Note that this behavior is very similar to selection state. const initialExpandedRepoNames = repositories.filter((repo) => !!repo.details).map((repo) => repo.name); // Default to all expanded const [expandedRepoNames, setExpandedRepoNames] = useState(initialExpandedRepoNames); const setRepoExpanded = (repo: Repository, isExpanding = true) => setExpandedRepoNames((prevExpanded) => { const otherExpandedRepoNames = prevExpanded.filter((r) => r !== repo.name); return isExpanding ? [...otherExpandedRepoNames, repo.name] : otherExpandedRepoNames; }); const isRepoExpanded = (repo: Repository) => expandedRepoNames.includes(repo.name); const [isExampleCompact, setIsExampleCompact] = useState(true); return ( setIsExampleCompact(checked)} aria-label="toggle striped compact variation" id="toggle-compact-striped" name="toggle-compact-striped" /> {repositories.map((repo, rowIndex) => { // Some arbitrary examples of how you could customize the child row based on your needs let childIsFullWidth = false; let childHasNoPadding = false; let detail1Colspan = 1; let detail2Colspan = 1; let detail3Colspan = 1; if (repo.details) { const { detail1, detail2, detail3, detailFormat } = repo.details; const numColumns = 5; childIsFullWidth = [1, 3].includes(detailFormat); childHasNoPadding = [2, 3].includes(detailFormat); if (detail1 && !detail2 && !detail3) { detail1Colspan = childIsFullWidth ? numColumns : numColumns + 1; // Account for toggle column } else if (detail1 && detail2 && !detail3) { detail1Colspan = 2; detail2Colspan = childIsFullWidth ? 3 : 4; } else if (detail1 && detail2 && detail3) { detail1Colspan = 2; detail2Colspan = 2; detail3Colspan = childIsFullWidth ? 1 : 2; } } return ( {repo.details ? ( {!childIsFullWidth ? ) : null} {repo.details.detail2 ? ( ) : null} {repo.details.detail3 ? ( ) : null} ) : null} ); })}
{columnNames.name} {columnNames.branches} {columnNames.prs} {columnNames.workspaces} {columnNames.lastCommit}
setRepoExpanded(repo, !isRepoExpanded(repo)) } : undefined } /> {repo.name} {repo.branches} {repo.prs} {repo.workspaces} {repo.lastCommit}
: null} {repo.details.detail1 ? ( {repo.details.detail1} {repo.details.detail2} {repo.details.detail3}
); };