Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { FunctionComponent } from 'react';
import { DataViewTable, DataViewTr, DataViewTh, ExpandableContent } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
import { ExclamationCircleIcon } from '@patternfly/react-icons';
import { Button } from '@patternfly/react-core';
import { ActionsColumn } from '@patternfly/react-table';

interface Repository {
id: number;
name: string;
branches: string | null;
prs: string | null;
workspaces: string;
lastCommit: string;
}

const expandableContents: ExpandableContent[] = [
// Row 1 - Repository one
{ rowId: 1, columnId: 3, content: <div><strong>PR Details:</strong> 3 open PRs, 45 merged this month, avg review time: 2 days</div> },
{ rowId: 1, columnId: 5, content: <div><strong>Commit Info:</strong> Author: John Doe, Message: "Fix critical authentication bug", SHA: a1b2c3d</div> },

// Row 2 - Repository two
{ rowId: 2, columnId: 2, content: <div><strong>Branch Details:</strong> 8 active branches, main, staging, feature/api-v2, feature/dashboard</div> },
{ rowId: 2, columnId: 3, content: <div><strong>PR Details:</strong> 5 open PRs, 120 merged this month, avg review time: 1.5 days</div> },
{ rowId: 2, columnId: 4, content: <div><strong>Workspace Info:</strong> Development env, 3 active deployments, last updated 30 mins ago</div> },
{ rowId: 2, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Jane Smith, Message: "Add new API endpoints", SHA: x9y8z7w</div> },

// Row 3 - Repository three
{ rowId: 3, columnId: 2, content: <div><strong>Branch Details:</strong> 12 active branches including main, develop, multiple feature branches</div> },
{ rowId: 3, columnId: 3, content: <div><strong>PR Details:</strong> 8 open PRs, 200 merged this month, avg review time: 3 days</div> },
{ rowId: 3, columnId: 4, content: <div><strong>Workspace Info:</strong> Staging env, 10 active deployments, last updated 1 day ago</div> },
{ rowId: 3, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Bob Johnson, Message: "Refactor core modules", SHA: p0o9i8u</div> },

// Row 4 - Repository four
{ rowId: 4, columnId: 2, content: <div><strong>Branch Details:</strong> 6 active branches, focusing on microservices architecture</div> },
{ rowId: 4, columnId: 3, content: <div><strong>PR Details:</strong> 2 open PRs, 90 merged this month, avg review time: 2.5 days</div> },
{ rowId: 4, columnId: 4, content: <div><strong>Workspace Info:</strong> QA env, 7 active deployments, automated testing enabled</div> },
{ rowId: 4, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Alice Williams, Message: "Update dependencies", SHA: m5n4b3v</div> },

// Row 5 - Repository five
{ rowId: 5, columnId: 2, content: <div><strong>Branch Details:</strong> 4 active branches, clean branch strategy</div> },
{ rowId: 5, columnId: 3, content: <div><strong>PR Details:</strong> 6 open PRs, 75 merged this month, avg review time: 1 day</div> },
{ rowId: 5, columnId: 4, content: <div><strong>Workspace Info:</strong> Pre-production env, CI/CD pipeline configured</div> },
{ rowId: 5, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Charlie Brown, Message: "Implement dark mode", SHA: q2w3e4r</div> },

// Row 6 - Repository six
{ rowId: 6, columnId: 2, content: <div><strong>Branch Details:</strong> 15 active branches, complex branching model</div> },
{ rowId: 6, columnId: 3, content: <div><strong>PR Details:</strong> 10 open PRs, 250 merged this month, avg review time: 4 days</div> },
{ rowId: 6, columnId: 4, content: <div><strong>Workspace Info:</strong> Multi-region deployment, high availability setup</div> },
{ rowId: 6, columnId: 5, content: <div><strong>Commit Info:</strong> Author: David Lee, Message: "Security patches applied", SHA: t6y7u8i</div> },
];

const repositories: Repository[] = [
{ id: 1, name: 'Repository one', branches: 'Branch one', prs: 'Pull request one', workspaces: 'Workspace one', lastCommit: 'Timestamp one' },
{ id: 2, name: 'Repository two', branches: 'Branch two', prs: 'Pull request two', workspaces: 'Workspace two', lastCommit: 'Timestamp two' },
{ id: 3, name: 'Repository three', branches: 'Branch three', prs: 'Pull request three', workspaces: 'Workspace three', lastCommit: 'Timestamp three' },
{ id: 4, name: 'Repository four', branches: 'Branch four', prs: 'Pull request four', workspaces: 'Workspace four', lastCommit: 'Timestamp four' },
{ id: 5, name: 'Repository five', branches: 'Branch five', prs: 'Pull request five', workspaces: 'Workspace five', lastCommit: 'Timestamp five' },
{ id: 6, name: 'Repository six', branches: 'Branch six', prs: 'Pull request six', workspaces: 'Workspace six', lastCommit: 'Timestamp six' }
];

const rowActions = [
{
title: 'Some action',
onClick: () => console.log('clicked on Some action') // eslint-disable-line no-console
},
{
title: <div>Another action</div>,
onClick: () => console.log('clicked on Another action') // eslint-disable-line no-console
},
{
isSeparator: true
},
{
title: 'Third action',
onClick: () => console.log('clicked on Third action') // eslint-disable-line no-console
}
];

const rows: DataViewTr[] = repositories.map(({ id, name, branches, prs, workspaces, lastCommit }) => [
{
id,
cell: workspaces,
props: {
favorites: { isFavorited: true }
}
},
{ cell: <Button href='#' variant='link' isInline>{name}</Button> },
branches,
prs,
workspaces,
lastCommit,
{ cell: <ActionsColumn items={rowActions}/>, props: { isActionCell: true } },
]);

const columns: DataViewTh[] = [
null,
'Repositories',
{ cell: <>Branches<ExclamationCircleIcon className='pf-v6-u-ml-sm' color="var(--pf-t--global--color--status--danger--default)"/></> },
'Pull requests',
{ cell: 'Workspaces', props: { info: { tooltip: 'More information' }, isStickyColumn: true } },
{ cell: 'Last commit', props: { sort: { sortBy: {}, columnIndex: 4 } } },
];

const ouiaId = 'CompoundExpandableTableExample';

export const CompoundExpandableExample: FunctionComponent = () => (
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} expandedRows={expandableContents} isExpandable={true}/>
);
Original file line number Diff line number Diff line change
@@ -1,54 +1,15 @@
import { FunctionComponent } from 'react';
import { DataViewTable, DataViewTr, DataViewTh, ExpandableContent } from '@patternfly/react-data-view/dist/dynamic/DataViewTable';
import { ExclamationCircleIcon } from '@patternfly/react-icons';
import { Button } from '@patternfly/react-core';
import { ActionsColumn } from '@patternfly/react-table';

interface Repository {
id: number;
name: string;
branches: string | null;
prs: string | null;
branches: string;
prs: string;
workspaces: string;
lastCommit: string;
}

const expandableContents: ExpandableContent[] = [
// Row 1 - Repository one
{ rowId: 1, columnId: 3, content: <div><strong>PR Details:</strong> 3 open PRs, 45 merged this month, avg review time: 2 days</div> },
{ rowId: 1, columnId: 5, content: <div><strong>Commit Info:</strong> Author: John Doe, Message: "Fix critical authentication bug", SHA: a1b2c3d</div> },

// Row 2 - Repository two
{ rowId: 2, columnId: 2, content: <div><strong>Branch Details:</strong> 8 active branches, main, staging, feature/api-v2, feature/dashboard</div> },
{ rowId: 2, columnId: 3, content: <div><strong>PR Details:</strong> 5 open PRs, 120 merged this month, avg review time: 1.5 days</div> },
{ rowId: 2, columnId: 4, content: <div><strong>Workspace Info:</strong> Development env, 3 active deployments, last updated 30 mins ago</div> },
{ rowId: 2, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Jane Smith, Message: "Add new API endpoints", SHA: x9y8z7w</div> },

// Row 3 - Repository three
{ rowId: 3, columnId: 2, content: <div><strong>Branch Details:</strong> 12 active branches including main, develop, multiple feature branches</div> },
{ rowId: 3, columnId: 3, content: <div><strong>PR Details:</strong> 8 open PRs, 200 merged this month, avg review time: 3 days</div> },
{ rowId: 3, columnId: 4, content: <div><strong>Workspace Info:</strong> Staging env, 10 active deployments, last updated 1 day ago</div> },
{ rowId: 3, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Bob Johnson, Message: "Refactor core modules", SHA: p0o9i8u</div> },

// Row 4 - Repository four
{ rowId: 4, columnId: 2, content: <div><strong>Branch Details:</strong> 6 active branches, focusing on microservices architecture</div> },
{ rowId: 4, columnId: 3, content: <div><strong>PR Details:</strong> 2 open PRs, 90 merged this month, avg review time: 2.5 days</div> },
{ rowId: 4, columnId: 4, content: <div><strong>Workspace Info:</strong> QA env, 7 active deployments, automated testing enabled</div> },
{ rowId: 4, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Alice Williams, Message: "Update dependencies", SHA: m5n4b3v</div> },

// Row 5 - Repository five
{ rowId: 5, columnId: 2, content: <div><strong>Branch Details:</strong> 4 active branches, clean branch strategy</div> },
{ rowId: 5, columnId: 3, content: <div><strong>PR Details:</strong> 6 open PRs, 75 merged this month, avg review time: 1 day</div> },
{ rowId: 5, columnId: 4, content: <div><strong>Workspace Info:</strong> Pre-production env, CI/CD pipeline configured</div> },
{ rowId: 5, columnId: 5, content: <div><strong>Commit Info:</strong> Author: Charlie Brown, Message: "Implement dark mode", SHA: q2w3e4r</div> },

// Row 6 - Repository six
{ rowId: 6, columnId: 2, content: <div><strong>Branch Details:</strong> 15 active branches, complex branching model</div> },
{ rowId: 6, columnId: 3, content: <div><strong>PR Details:</strong> 10 open PRs, 250 merged this month, avg review time: 4 days</div> },
{ rowId: 6, columnId: 4, content: <div><strong>Workspace Info:</strong> Multi-region deployment, high availability setup</div> },
{ rowId: 6, columnId: 5, content: <div><strong>Commit Info:</strong> Author: David Lee, Message: "Security patches applied", SHA: t6y7u8i</div> },
];

const repositories: Repository[] = [
{ id: 1, name: 'Repository one', branches: 'Branch one', prs: 'Pull request one', workspaces: 'Workspace one', lastCommit: 'Timestamp one' },
{ id: 2, name: 'Repository two', branches: 'Branch two', prs: 'Pull request two', workspaces: 'Workspace two', lastCommit: 'Timestamp two' },
Expand All @@ -58,50 +19,26 @@ const repositories: Repository[] = [
{ id: 6, name: 'Repository six', branches: 'Branch six', prs: 'Pull request six', workspaces: 'Workspace six', lastCommit: 'Timestamp six' }
];

const rowActions = [
{
title: 'Some action',
onClick: () => console.log('clicked on Some action') // eslint-disable-line no-console
},
{
title: <div>Another action</div>,
onClick: () => console.log('clicked on Another action') // eslint-disable-line no-console
},
{
isSeparator: true
},
{
title: 'Third action',
onClick: () => console.log('clicked on Third action') // eslint-disable-line no-console
}
const expandableContents: ExpandableContent[] = [
{ rowId: 1, content: <div>Detailed information for Repository one</div> },
{ rowId: 2, content: <div>Detailed information for Repository two</div> },
{ rowId: 3, content: <div>Detailed information for Repository three</div> },
{ rowId: 4, content: <div>Detailed information for Repository four</div> },
{ rowId: 5, content: <div>Detailed information for Repository five</div> },
{ rowId: 6, content: <div>Detailed information for Repository six</div> },
];

const rows: DataViewTr[] = repositories.map(({ id, name, branches, prs, workspaces, lastCommit }) => [
{
id,
cell: workspaces,
props: {
favorites: { isFavorited: true }
}
},
{ cell: <Button href='#' variant='link' isInline>{name}</Button> },
{ id, cell: name },
branches,
prs,
workspaces,
lastCommit,
{ cell: <ActionsColumn items={rowActions}/>, props: { isActionCell: true } },
lastCommit
]);

const columns: DataViewTh[] = [
null,
'Repositories',
{ cell: <>Branches<ExclamationCircleIcon className='pf-v6-u-ml-sm' color="var(--pf-t--global--color--status--danger--default)"/></> },
'Pull requests',
{ cell: 'Workspaces', props: { info: { tooltip: 'More information' }, isStickyColumn: true } },
{ cell: 'Last commit', props: { sort: { sortBy: {}, columnIndex: 4 } } },
];
const columns: DataViewTh[] = [ null, 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];

const ouiaId = 'TableExample';
const ouiaId = 'ExpandableTableExample';

export const ExpandableExample: FunctionComponent = () => (
<DataViewTable aria-label='Repositories table' ouiaId={ouiaId} columns={columns} rows={rows} expandedRows={expandableContents} isExpandable={true}/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ export const InteractiveExample: FunctionComponent = () => {
<ToolbarContent>
<ToolbarItem>
<Switch
id="expandable-switch"
label="Expandable"
id="compound-expandable-switch"
label="Compound expandable"
isChecked={isExpandable}
onChange={(_event, checked) => setIsExpandable(checked)}
aria-label="Toggle expandable rows"
aria-label="Toggle compound expandable rows"
/>
</ToolbarItem>
<ToolbarItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,35 +58,45 @@ If you want to have all expandable nodes open on initial load pass the `expandAl

```

## Expandable rows
## Adding expandable content to rows

To add expandable content to table cells, pass an array of `ExpandableContent` objects to the `expandedRows` prop of the `<DataViewTable>` component. Each expandable content object defines which cell can be expanded and what content to display when expanded.
To add expandable content to table rows, pass an array of `ExpandableContent` objects to the `expandedRows` prop of the `<DataViewTable>` component and set `isExpandable` to `true`.

The `ExpandableContent` interface is defined as:

```typescript
interface ExpandableContent {
/** The ID of the row containing the expandable cell (must match the id property in the row data) */
rowId: number;
/** The column index (0-based) that should be expandable */
columnId: number;
/** The content to display when the cell is expanded */
rowId: string | number;
columnId?: number;
content: ReactNode;
}
```
The `columnId` property is optional. Omit it for [expandable rows](#expandable-rows-example), which add an expand toggle as the first column. Provide it on all entries for [compound expandable rows](#compound-expandable-rows), where individual cells act as expand toggles.

## Expandable rows

When a cell has expandable content:
- A compound expand toggle button appears in the cell
- Clicking the toggle expands the row to show the additional content below
- Only one expanded cell is shown per row at a time
- Clicking another expandable cell in the same row switches the expanded content
To make a parent/child row pair expandable, omit `columnId` from the expandable content entries:
- A toggle is added as the first column (no column header)
- Rows without matching expandable content display an empty toggle cell

### Expandable rows example

```js file="./DataViewTableExpandableExample.tsx"

```

## Compound expandable rows

To make a parent/child row pair compound expandable, provide `columnId` on all expandable content entries:
- Individual cells with expandable content act as expand toggles
- Only one cell can be expanded per row at a time

### Compound expandable rows example

```js file="./DataViewTableCompoundExpandableExample.tsx"

```

## Sticky header and columns

To enable sticky headers and columns, set the `isSticky` prop to `true` on the `<DataViewTable>` component. This keeps the table header and designated columns visible when scrolling.
Expand All @@ -112,8 +122,8 @@ When sticky headers and columns are enabled:
```

### Interactive example
- Interactive example show how the different composable options work together.
- By toggling the toggles you can switch between them and observe the behaviour
- This interactive example shows how the different composable options work together
- By toggling the toggles, you can switch between them and observe the behaviour

```js file="./DataViewTableInteractiveExample.tsx"

Expand Down
4 changes: 2 additions & 2 deletions packages/module/patternfly-docs/generated/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ module.exports = {
'/extensions/data-view/table/react': {
id: "Table",
title: "Data view table",
toc: [{"text":"Configuring rows and columns"},[{"text":"Table example"}],{"text":"Expandable rows"},[{"text":"Expandable rows example"}],{"text":"Sticky header and columns"},[{"text":"Sticky header and columns example"},{"text":"Interactive example"},{"text":"Resizable columns"}],{"text":"Tree table"},[{"text":"Tree table example"}],{"text":"Sorting"},[{"text":"Sorting example"},{"text":"Sorting state"}],{"text":"States"},[{"text":"Empty"},{"text":"Error"},{"text":"Loading"}]],
examples: ["Table example","Expandable rows example","Sticky header and columns example","Interactive example","Resizable columns","Tree table example","Sorting example","Empty","Error","Loading"],
toc: [{"text":"Configuring rows and columns"},[{"text":"Table example"}],{"text":"Adding expandable content to rows"},{"text":"Expandable rows"},[{"text":"Expandable rows example"}],{"text":"Compound expandable rows"},[{"text":"Compound expandable rows example"}],{"text":"Sticky header and columns"},[{"text":"Sticky header and columns example"},{"text":"Interactive example"},{"text":"Resizable columns"}],{"text":"Tree table"},[{"text":"Tree table example"}],{"text":"Sorting"},[{"text":"Sorting example"},{"text":"Sorting state"}],{"text":"States"},[{"text":"Empty"},{"text":"Error"},{"text":"Loading"}]],
examples: ["Table example","Expandable rows example","Compound expandable rows example","Sticky header and columns example","Interactive example","Resizable columns","Tree table example","Sorting example","Empty","Error","Loading"],
section: "extensions",
subsection: "Data view",
source: "react",
Expand Down
Loading