diff --git a/packages/module/package.json b/packages/module/package.json
index b28097a..27f0a6d 100644
--- a/packages/module/package.json
+++ b/packages/module/package.json
@@ -39,9 +39,9 @@
"tag": "prerelease"
},
"dependencies": {
- "@patternfly/react-core": "^5.0.0-prerelease.13",
- "@patternfly/react-icons": "^5.0.0-prerelease.7",
- "@patternfly/react-styles": "^5.0.0-prerelease.5",
+ "@patternfly/react-core": "^5.0.0-prerelease.26",
+ "@patternfly/react-icons": "^5.0.0-prerelease.9",
+ "@patternfly/react-styles": "^5.0.0-prerelease.7",
"linear-layout-vector": "0.0.1",
"react-virtualized": "^9.22.5",
"tslib": "^2.5.2"
@@ -51,12 +51,13 @@
"react-dom": "^17 || ^18"
},
"devDependencies": {
- "@patternfly/documentation-framework": "^2.0.0-alpha.69",
- "@patternfly/patternfly": "^5.0.0-prerelease.10",
- "@patternfly/react-table": "^5.0.0-prerelease.13",
- "@patternfly/react-code-editor": "^5.0.0-prerelease.13",
+ "@patternfly/documentation-framework": "^5.0.15",
+ "@patternfly/patternfly": "^5.0.0-prerelease.16",
+ "@patternfly/react-table": "^5.0.0-prerelease.26",
+ "@patternfly/react-code-editor": "^5.0.0-prerelease.26",
"rimraf": "^5.0.1",
"@patternfly/patternfly-a11y": "^4.3.1",
- "react-monaco-editor": "^0.52.0"
+ "react-monaco-editor": "^0.51.0",
+ "monaco-editor": "0.34.1"
}
}
diff --git a/packages/module/patternfly-docs/content/examples/Actions.tsx b/packages/module/patternfly-docs/content/examples/Actions.tsx
new file mode 100644
index 0000000..7441d3a
--- /dev/null
+++ b/packages/module/patternfly-docs/content/examples/Actions.tsx
@@ -0,0 +1,149 @@
+/* eslint-disable no-console */
+import React from 'react';
+import { debounce } from '@patternfly/react-core';
+import { ActionsColumn, TableGridBreakpoint } from '@patternfly/react-table';
+import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
+import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
+import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
+
+export class ActionsExample extends React.Component {
+ constructor(props) {
+ super(props);
+ const rows = [];
+ for (let i = 0; i < 100; i++) {
+ rows.push({
+ disableActions: i % 3 === 2,
+ id: `actions-row-${i}`,
+ cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
+ });
+ }
+
+ this.actionsVirtualBody = null;
+
+ this.state = {
+ columns: [
+ { title: 'Name', props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' } },
+ {
+ title: 'Namespace',
+ props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
+ },
+ {
+ title: 'Labels',
+ props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }
+ },
+ { title: 'Status', props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' } },
+ { title: 'Pod Selector', props: { className: 'pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-xl' } },
+ { title: '', props: { className: 'pf-v5-c-table__action' } }
+ ],
+ rows,
+ actions: [
+ {
+ title: 'Some action',
+ onClick: (_event, rowId, _rowData, _extra) => console.log('clicked on Some action, on row: ', rowId)
+ },
+ {
+ title:
Another action
,
+ onClick: (_event, rowId, _rowData, _extra) => console.log('clicked on Another action, on row: ', rowId)
+ },
+ {
+ isSeparator: true
+ },
+ {
+ title: 'Third action',
+ onClick: (_event, rowId, _rowData, _extra) => console.log('clicked on Third action, on row: ', rowId)
+ }
+ ]
+ };
+
+ this._handleResize = debounce(this._handleResize.bind(this), 100);
+ }
+
+ componentDidMount() {
+ // re-render after resize
+ window.addEventListener('resize', this._handleResize);
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this._handleResize);
+ }
+
+ _handleResize() {
+ this.forceUpdate();
+ }
+
+ render() {
+ const { columns, rows } = this.state;
+
+ const measurementCache = new CellMeasurerCache({
+ fixedWidth: true,
+ minHeight: 44,
+ keyMapper: (rowIndex) => rowIndex
+ });
+
+ const rowRenderer = ({ index, _isScrolling, key, style, parent }) => {
+ const { rows, columns, actions } = this.state;
+
+ return (
+
+
+
+ {rows[index].cells[0]}
+
+
+ {rows[index].cells[1]}
+
+
+ {rows[index].cells[2]}
+
+
+ {rows[index].cells[3]}
+
+
+ {rows[index].cells[4]}
+
+
+
+
+
+
+ );
+ };
+
+ return (
+
+
+
+
+
+ {({ width }) => (
+ (this.actionsVirtualBody = ref)}
+ className="pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller"
+ deferredMeasurementCache={measurementCache}
+ rowHeight={measurementCache.rowHeight}
+ height={400}
+ overscanRowCount={2}
+ columnCount={1}
+ rows={rows}
+ rowCount={rows.length}
+ rowRenderer={rowRenderer}
+ width={width}
+ role="grid"
+ />
+ )}
+
+
+ );
+ }
+}
diff --git a/packages/module/patternfly-docs/content/examples/Basic.tsx b/packages/module/patternfly-docs/content/examples/Basic.tsx
new file mode 100644
index 0000000..fa6a282
--- /dev/null
+++ b/packages/module/patternfly-docs/content/examples/Basic.tsx
@@ -0,0 +1,123 @@
+import React from 'react';
+import { debounce } from '@patternfly/react-core';
+import { TableGridBreakpoint } from '@patternfly/react-table';
+import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
+import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
+import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
+
+export class VirtualizedExample extends React.Component {
+ constructor(props) {
+ super(props);
+ const rows = [];
+ for (let i = 0; i < 100; i++) {
+ rows.push({
+ id: `basic-row-${i}`,
+ cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
+ });
+ }
+
+ this.state = {
+ columns: [
+ {
+ title: 'Repositories',
+ props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
+ },
+ {
+ title: 'Branches',
+ props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
+ },
+ {
+ title: 'Pull requests',
+ props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }
+ },
+ {
+ title: 'Workspaces',
+ props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }
+ },
+ { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }
+ ],
+ rows
+ };
+ this._handleResize = debounce(this._handleResize.bind(this), 100);
+ }
+
+ componentDidMount() {
+ // re-render after resize
+ window.addEventListener('resize', this._handleResize);
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this._handleResize);
+ }
+
+ _handleResize() {
+ this.forceUpdate();
+ }
+
+ render() {
+ const { columns, rows } = this.state;
+
+ const measurementCache = new CellMeasurerCache({
+ fixedWidth: true,
+ minHeight: 44,
+ keyMapper: (rowIndex) => rowIndex
+ });
+
+ const rowRenderer = ({ index, _isScrolling, key, style, parent }) => {
+ const { rows, columns } = this.state;
+
+ return (
+
+
+
+ {rows[index].cells[0]}
+
+
+ {rows[index].cells[1]}
+
+
+ {rows[index].cells[2]}
+
+
+ {rows[index].cells[3]}
+
+
+ {rows[index].cells[4]}
+
+
+
+ );
+ };
+
+ return (
+
+
+
+
+
+ {({ width }) => (
+
+ )}
+
+
+ );
+ }
+}
diff --git a/packages/module/patternfly-docs/content/examples/FilterableWithWindowScroller.tsx b/packages/module/patternfly-docs/content/examples/FilterableWithWindowScroller.tsx
new file mode 100644
index 0000000..5c08f14
--- /dev/null
+++ b/packages/module/patternfly-docs/content/examples/FilterableWithWindowScroller.tsx
@@ -0,0 +1,479 @@
+/* eslint-disable no-console */
+import React from 'react';
+import {
+ Button,
+ ButtonVariant,
+ Toolbar,
+ ToolbarItem,
+ ToolbarContent,
+ ToolbarFilter,
+ ToolbarToggleGroup,
+ ToolbarGroup,
+ InputGroup,
+ InputGroupItem,
+ TextInput
+} from '@patternfly/react-core';
+import { debounce } from '@patternfly/react-core';
+import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
+import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
+import { ActionsColumn } from '@patternfly/react-table';
+import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
+import {
+ Dropdown as DropdownDeprecated,
+ DropdownItem as DropdownItemDeprecated,
+ DropdownPosition as DropdownPositionDeprecated,
+ DropdownToggle as DropdownToggleDeprecated,
+ Select as SelectDeprecated,
+ SelectOption as SelectOptionDeprecated,
+ SelectVariant as SelectVariantDeprecated
+} from '@patternfly/react-core/deprecated';
+import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
+import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-virtualized-extension';
+
+export class FilterExample extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.actionsVirtualBody = null;
+
+ const rows = [];
+ for (let i = 0; i < 100; i++) {
+ const data = {};
+ if (i % 2 === 0) {
+ data.cells = [`US-Node ${i}`, i, i, 'Down', 'Brno'];
+ } else if (i % 3 === 0) {
+ data.cells = [`CN-Node ${i}`, i, i, 'Running', 'Westford'];
+ } else {
+ data.cells = [`US-Node ${i}`, i, i, 'Stopped', 'Raleigh'];
+ }
+ rows.push(data);
+ }
+ this.scrollableElement = React.createRef();
+
+ this.state = {
+ scrollableElement: null,
+
+ filters: {
+ location: [],
+ name: [],
+ status: []
+ },
+ currentCategory: 'Name',
+ isFilterDropdownOpen: false,
+ isCategoryDropdownOpen: false,
+ nameInput: '',
+ columns: [
+ { title: 'Servers' },
+ { title: 'Threads' },
+ { title: 'Applications' },
+ { title: 'Status' },
+ { title: 'Location' }
+ ],
+ rows,
+ inputValue: '',
+ actions: [
+ {
+ title: 'Some action',
+ onClick: (_event, rowId, _rowData, _extra) => console.log('clicked on Some action, on row: ', rowId)
+ },
+ {
+ title: Another action
,
+ onClick: (_event, rowId, _rowData, _extra) => console.log('clicked on Another action, on row: ', rowId)
+ },
+ {
+ isSeparator: true
+ },
+ {
+ title: 'Third action',
+ onClick: (_event, rowId, _rowData, _extra) => console.log('clicked on Third action, on row: ', rowId)
+ }
+ ]
+ };
+
+ this._handleResize = debounce(this._handleResize.bind(this), 100);
+
+ this.onDelete = (type = '', id = '') => {
+ if (type) {
+ this.setState((prevState) => {
+ prevState.filters[type.toLowerCase()] = prevState.filters[type.toLowerCase()].filter((s) => s !== id);
+ return {
+ filters: prevState.filters
+ };
+ });
+ } else {
+ this.setState({
+ filters: {
+ location: [],
+ name: [],
+ status: []
+ },
+ inputValue: ''
+ });
+ }
+ };
+
+ this.onCategoryToggle = (_event, isOpen) => {
+ this.setState({
+ isCategoryDropdownOpen: isOpen
+ });
+ };
+
+ this.onCategorySelect = (event) => {
+ this.setState({
+ currentCategory: event.target.innerText,
+ isCategoryDropdownOpen: !this.state.isCategoryDropdownOpen
+ });
+ };
+
+ this.onFilterToggle = (_event, isOpen) => {
+ this.setState({
+ isFilterDropdownOpen: isOpen
+ });
+ };
+
+ this.onFilterSelect = (_event) => {
+ this.setState({
+ isFilterDropdownOpen: !this.state.isFilterDropdownOpen
+ });
+ };
+
+ this.onInputChange = (_event, newValue) => {
+ // this.setState({ inputValue: newValue });
+ if (newValue === '') {
+ this.onDelete();
+ this.setState({
+ inputValue: newValue
+ });
+ } else {
+ this.setState((prevState) => ({
+ filters: {
+ ...prevState.filters,
+ ['name']: [newValue]
+ },
+ inputValue: newValue
+ }));
+ }
+ };
+
+ this.onRowSelect = (event, isSelected, rowId) => {
+ let rows;
+ if (rowId === -1) {
+ rows = this.state.rows.map((oneRow) => {
+ oneRow.selected = isSelected;
+ return oneRow;
+ });
+ } else {
+ rows = [...this.state.rows];
+ rows[rowId].selected = isSelected;
+ }
+ this.setState({
+ rows
+ });
+ };
+
+ this.onStatusSelect = (event, selection) => {
+ const checked = event.target.checked;
+ this.setState((prevState) => {
+ const prevSelections = prevState.filters.status;
+ return {
+ filters: {
+ ...prevState.filters,
+ status: checked ? [...prevSelections, selection] : prevSelections.filter((value) => value !== selection)
+ }
+ };
+ });
+ };
+
+ this.onNameInput = (event) => {
+ if (event.key && event.key !== 'Enter') {
+ return;
+ }
+
+ const { inputValue } = this.state;
+ this.setState((prevState) => {
+ const prevFilters = prevState.filters.name;
+ return {
+ filters: {
+ ...prevState.filters,
+ ['name']: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue]
+ },
+ inputValue: ''
+ };
+ });
+ };
+
+ this.onLocationSelect = (event, selection) => {
+ this.setState((prevState) => ({
+ filters: {
+ ...prevState.filters,
+ ['location']: [selection]
+ }
+ }));
+ this.onFilterSelect();
+ };
+
+ this._handleResize = debounce(this._handleResize.bind(this), 100);
+ this._bindBodyRef = this._bindBodyRef.bind(this);
+ }
+
+ componentDidMount() {
+ // re-render after resize
+ window.addEventListener('resize', this._handleResize);
+
+ setTimeout(() => {
+ const scollableElement = document.getElementById('content-scrollable-1');
+ this.setState({ scollableElement });
+ });
+
+ // re-render after resize
+ window.addEventListener('resize', this._handleResize);
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this._handleResize);
+ }
+
+ _handleResize() {
+ this._cellMeasurementCache.clearAll();
+ this._bodyRef.recomputeVirtualGridSize();
+ }
+
+ _bindBodyRef(ref) {
+ this._bodyRef = ref;
+ }
+
+ buildCategoryDropdown() {
+ const { isCategoryDropdownOpen, currentCategory } = this.state;
+
+ return (
+
+
+ {currentCategory}
+
+ }
+ isOpen={isCategoryDropdownOpen}
+ dropdownItems={[
+ Location ,
+ Name ,
+ Status
+ ]}
+ style={{ width: '100%' }}
+ >
+
+ );
+ }
+
+ buildFilterDropdown() {
+ const { currentCategory, isFilterDropdownOpen, inputValue, filters } = this.state;
+
+ const locationMenuItems = [
+ ,
+ ,
+ ,
+ ,
+
+ ];
+
+ const statusMenuItems = [
+ ,
+ ,
+ ,
+ ,
+
+ ];
+
+ return (
+
+
+
+ {locationMenuItems}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {statusMenuItems}
+
+
+
+ );
+ }
+
+ renderToolbar() {
+ return (
+
+
+ } breakpoint="xl">
+
+ {this.buildCategoryDropdown()}
+ {this.buildFilterDropdown()}
+
+
+
+
+ );
+ }
+
+ render() {
+ const { loading, rows, columns, actions, filters, scollableElement } = this.state;
+
+ const filteredRows =
+ filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0
+ ? rows.filter((row) => (
+ (filters.name.length === 0 ||
+ filters.name.some((name) => row.cells[0].toLowerCase().includes(name.toLowerCase()))) &&
+ (filters.location.length === 0 || filters.location.includes(row.cells[4])) &&
+ (filters.status.length === 0 || filters.status.includes(row.cells[3]))
+ ))
+ : rows;
+ const measurementCache = new CellMeasurerCache({
+ fixedWidth: true,
+ minHeight: 44,
+ keyMapper: (rowIndex) => rowIndex
+ });
+
+ const rowRenderer = ({ index, _isScrolling, key, style, parent }) => {
+ const { actions } = this.state;
+
+ return (
+
+
+ {filteredRows[index].cells[0]}
+ {filteredRows[index].cells[1]}
+ {filteredRows[index].cells[2]}
+ {filteredRows[index].cells[3]}
+ {filteredRows[index].cells[4]}
+
+
+
+
+
+ );
+ };
+
+ return (
+
+ {this.renderToolbar()}
+
+
+
+ {!loading && filteredRows.length > 0 && (
+
+
+
+
+
+ {({ height, _isScrolling, registerChild, _onChildScroll, scrollTop }) => (
+
+ {({ width }) => (
+
+ (this.actionsVirtualBody = ref)}
+ autoHeight
+ className="pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller"
+ deferredMeasurementCache={measurementCache}
+ rowHeight={measurementCache.rowHeight}
+ height={height || 0}
+ overscanRowCount={10}
+ columnCount={6}
+ rows={filteredRows}
+ rowCount={filteredRows.length}
+ rowRenderer={rowRenderer}
+ scrollTop={scrollTop}
+ width={width}
+ role="grid"
+ />
+
+ )}
+
+ )}
+
+
+ )}
+
+
+
+ );
+ }
+}
diff --git a/packages/module/patternfly-docs/content/examples/Selectable.tsx b/packages/module/patternfly-docs/content/examples/Selectable.tsx
new file mode 100644
index 0000000..3110aac
--- /dev/null
+++ b/packages/module/patternfly-docs/content/examples/Selectable.tsx
@@ -0,0 +1,153 @@
+import React from 'react';
+import { debounce } from '@patternfly/react-core';
+import { headerCol, TableGridBreakpoint } from '@patternfly/react-table';
+import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
+import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
+import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
+
+export class SelectableExample extends React.Component {
+ constructor(props) {
+ super(props);
+ const rows = [];
+ for (let i = 0; i < 100; i++) {
+ rows.push({
+ selected: false,
+ id: `selectable-row-${i}`,
+ cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
+ });
+ }
+
+ this.selectableVirtualBody = null;
+
+ this.state = {
+ columns: [
+ // headerCol transform adds checkbox column with pf-m-2-sm, pf-m-1-md+ column space
+ {
+ title: 'Repositories',
+ cellTransforms: [headerCol()],
+ props: { className: 'pf-m-5-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
+ },
+ {
+ title: 'Pull requests',
+ props: { className: 'pf-m-5-col-on-sm pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl' }
+ },
+ {
+ title: 'Workspaces',
+ props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }
+ },
+ { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }
+ ],
+ rows
+ };
+
+ this.onSelect = this.onSelect.bind(this);
+ this._handleResize = debounce(this._handleResize.bind(this), 100);
+ }
+
+ componentDidMount() {
+ // re-render after resize
+ window.addEventListener('resize', this._handleResize);
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this._handleResize);
+ }
+
+ _handleResize() {
+ this.forceUpdate();
+ }
+
+ onSelect(event, isSelected, virtualRowIndex, rowData) {
+ let rows;
+ if (virtualRowIndex === -1) {
+ rows = this.state.rows.map((oneRow) => {
+ oneRow.selected = isSelected;
+ return oneRow;
+ });
+ } else {
+ rows = [...this.state.rows];
+ const rowIndex = rows.findIndex((r) => r.id === rowData.id);
+ rows[rowIndex] = { ...rows[rowIndex], selected: isSelected };
+ }
+ this.setState({
+ rows
+ });
+ this.selectableVirtualBody.forceUpdateVirtualGrid();
+ }
+
+ render() {
+ const { columns, rows } = this.state;
+
+ const measurementCache = new CellMeasurerCache({
+ fixedWidth: true,
+ minHeight: 44,
+ keyMapper: (rowIndex) => rowIndex
+ });
+
+ const rowRenderer = ({ index, _isScrolling, key, style, parent }) => {
+ const { rows, columns } = this.state;
+
+ return (
+
+
+
+ {
+ this.onSelect(e, e.target.checked, 0, { id: rows[index].id });
+ }}
+ />
+
+
+ {rows[index].cells[0]}
+
+
+ {rows[index].cells[1]}
+
+
+ {rows[index].cells[2]}
+
+
+ {rows[index].cells[3]}
+
+
+
+ );
+ };
+
+ return (
+
+
+
+
+
+ {({ width }) => (
+ (this.selectableVirtualBody = ref)}
+ className="pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller"
+ deferredMeasurementCache={measurementCache}
+ rowHeight={measurementCache.rowHeight}
+ height={400}
+ overscanRowCount={2}
+ columnCount={1}
+ rows={rows}
+ rowCount={rows.length}
+ rowRenderer={rowRenderer}
+ width={width}
+ role="grid"
+ />
+ )}
+
+
+ );
+ }
+}
diff --git a/packages/module/patternfly-docs/content/examples/Sortable.tsx b/packages/module/patternfly-docs/content/examples/Sortable.tsx
new file mode 100644
index 0000000..eb2418d
--- /dev/null
+++ b/packages/module/patternfly-docs/content/examples/Sortable.tsx
@@ -0,0 +1,150 @@
+import React from 'react';
+import { debounce } from '@patternfly/react-core';
+import { sortable, SortByDirection, TableGridBreakpoint } from '@patternfly/react-table';
+import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
+import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
+import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
+
+export class SortableExample extends React.Component {
+ constructor(props) {
+ super(props);
+ const rows = [];
+ for (let i = 0; i < 100; i++) {
+ rows.push({
+ id: `sortable-row-${i}`,
+ cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
+ });
+ }
+
+ this.sortableVirtualBody = null;
+
+ this.state = {
+ columns: [
+ {
+ title: 'Repositories',
+ transforms: [sortable],
+ props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
+ },
+ {
+ title: 'Branches',
+ props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
+ },
+ {
+ title: 'Pull requests',
+ transforms: [sortable],
+ props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }
+ },
+ {
+ title: 'Workspaces',
+ props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }
+ },
+ { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }
+ ],
+ rows,
+ sortBy: {}
+ };
+
+ this.onSort = this.onSort.bind(this);
+ this._handleResize = debounce(this._handleResize.bind(this), 100);
+ }
+
+ componentDidMount() {
+ // re-render after resize
+ window.addEventListener('resize', this._handleResize);
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this._handleResize);
+ }
+
+ _handleResize() {
+ this.forceUpdate();
+ }
+
+ onSort(_event, index, direction) {
+ const sortedRows = this.state.rows.sort((a, b) =>
+ // eslint-disable-next-line no-nested-ternary
+ a.cells[index] < b.cells[index] ? -1 : a.cells[index] > b.cells[index] ? 1 : 0
+ );
+ this.setState({
+ sortBy: {
+ index,
+ direction
+ },
+ rows: direction === SortByDirection.asc ? sortedRows : sortedRows.reverse()
+ });
+
+ this.sortableVirtualBody.forceUpdateVirtualGrid();
+ }
+
+ render() {
+ const { sortBy, columns, rows } = this.state;
+
+ const measurementCache = new CellMeasurerCache({
+ fixedWidth: true,
+ minHeight: 44,
+ keyMapper: (rowIndex) => rowIndex
+ });
+
+ const rowRenderer = ({ index, _isScrolling, key, style, parent }) => {
+ const { rows, columns } = this.state;
+
+ return (
+
+
+
+ {rows[index].cells[0]}
+
+
+ {rows[index].cells[1]}
+
+
+ {rows[index].cells[2]}
+
+
+ {rows[index].cells[3]}
+
+
+ {rows[index].cells[4]}
+
+
+
+ );
+ };
+
+ return (
+
+
+
+
+
+ {({ width }) => (
+ (this.sortableVirtualBody = ref)}
+ className="pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller"
+ deferredMeasurementCache={measurementCache}
+ rowHeight={measurementCache.rowHeight}
+ height={400}
+ overscanRowCount={2}
+ columnCount={1}
+ rows={rows}
+ rowCount={rows.length}
+ rowRenderer={rowRenderer}
+ width={width}
+ role="grid"
+ />
+ )}
+
+
+ );
+ }
+}
diff --git a/packages/module/patternfly-docs/content/examples/UsingComposableTableComponents.tsx b/packages/module/patternfly-docs/content/examples/UsingComposableTableComponents.tsx
new file mode 100644
index 0000000..15933a9
--- /dev/null
+++ b/packages/module/patternfly-docs/content/examples/UsingComposableTableComponents.tsx
@@ -0,0 +1,75 @@
+import React from 'react';
+
+import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
+import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
+import { Table, Thead, Tr, Th, Td, Caption, TableGridBreakpoint } from '@patternfly/react-table';
+
+export const ComposableTableVirtualized = () => {
+ const rows = [];
+ for (let i = 0; i < 100; i++) {
+ rows.push([`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]);
+ }
+ const [selected, setSelected] = React.useState(rows.map((_row) => false));
+ const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'];
+
+ const onSelect = (event, isSelected, rowId) => {
+ setSelected(selected.map((sel, index) => (index === rowId ? isSelected : sel)));
+ };
+
+ const measurementCache = new CellMeasurerCache({
+ fixedWidth: true,
+ minHeight: 44,
+ keyMapper: (rowIndex) => rowIndex
+ });
+
+ const rowRenderer = ({ index: rowIndex, _isScrolling, key, style, parent }) => (
+
+
+
+ {columns.map((col, index) => (
+ {rows[rowIndex][index]}
+ ))}
+
+
+ );
+
+ return (
+
+
+ Virtualized table with composable table components
+
+
+
+ {columns.map((col, index) => (
+ {col}
+ ))}
+
+
+
+
+ {({ width }) => (
+
+ )}
+
+
+ );
+};
diff --git a/packages/module/patternfly-docs/content/examples/UsingComposableTableComponentsDemo.tsx b/packages/module/patternfly-docs/content/examples/UsingComposableTableComponentsDemo.tsx
new file mode 100644
index 0000000..ea411ea
--- /dev/null
+++ b/packages/module/patternfly-docs/content/examples/UsingComposableTableComponentsDemo.tsx
@@ -0,0 +1,116 @@
+import React from 'react';
+import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
+import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-virtualized-extension';
+import { Table, Thead, Tr, Th, Td, Caption, TableGridBreakpoint } from '@patternfly/react-table';
+
+export const ComposableTableWindowScroller = () => {
+ const [scrollableElement, setScrollableElement] = React.useState();
+ React.useEffect(() => {
+ const scrollableElement = document.getElementById('content-scrollable-2');
+ setScrollableElement(scrollableElement);
+ });
+ const rows = [];
+ for (let i = 0; i < 100000; i++) {
+ const cells = [];
+ const num = Math.floor(Math.random() * Math.floor(2)) + 1;
+ for (let j = 0; j < 5; j++) {
+ const cellValue = i.toString() + ' Arma virumque cano Troiae qui primus ab oris. '.repeat(num);
+ cells.push(cellValue);
+ }
+ rows.push(cells);
+ }
+ const [selected, setSelected] = React.useState(rows.map((_row) => false));
+ const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'];
+ const scrollToIndex = -1; // can be used to programmatically set current index
+
+ const onSelect = (event, isSelected, rowId) => {
+ setSelected(selected.map((sel, index) => (index === rowId ? isSelected : sel)));
+ };
+
+ const measurementCache = new CellMeasurerCache({
+ fixedWidth: true,
+ minHeight: 44,
+ keyMapper: (rowIndex) => rowIndex
+ });
+
+ const rowRenderer = ({ index: rowIndex, _isScrolling, key, style, parent }) => {
+ const text = rows[rowIndex][0];
+
+ return (
+
+
+
+ {columns.map((col, index) => (
+ {text}
+ ))}
+
+
+ );
+ };
+
+ const scrollableContainerStyle = {
+ height: 500 /* important note: the scrollable container should have some sort of fixed height, or it should be wrapped in container that is smaller than ReactVirtualized__VirtualGrid container and has overflow visible if using the Window Scroller. See WindowScroller.example.css */,
+ overflowX: 'auto',
+ overflowY: 'scroll',
+ scrollBehavior: 'smooth',
+ WebkitOverflowScrolling: 'touch',
+ position: 'relative'
+ };
+
+ return (
+
+
+ Virtualized table with composable table components
+
+
+
+ {columns.map((col, index) => (
+ {col}
+ ))}
+
+
+
+
+ {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (
+
+ {({ width }) => (
+
+
+
+ )}
+
+ )}
+
+
+ );
+};
diff --git a/packages/module/patternfly-docs/content/examples/VirtualizedTable.md b/packages/module/patternfly-docs/content/examples/VirtualizedTable.md
index 5dfdf03..ff6f736 100644
--- a/packages/module/patternfly-docs/content/examples/VirtualizedTable.md
+++ b/packages/module/patternfly-docs/content/examples/VirtualizedTable.md
@@ -14,13 +14,13 @@ import { CellMeasurerCache, CellMeasurer} from 'react-virtualized';
import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-virtualized-extension';
import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
import {
- Dropdown,
- DropdownItem,
- DropdownPosition,
- DropdownToggle,
- Select,
- SelectOption,
- SelectVariant
+ Dropdown as DropdownDeprecated,
+ DropdownItem as DropdownItemDeprecated,
+ DropdownPosition as DropdownPositionDeprecated,
+ DropdownToggle as DropdownToggleDeprecated,
+ Select as SelectDeprecated,
+ SelectOption as SelectOptionDeprecated,
+ SelectVariant as SelectVariantDeprecated
} from '@patternfly/react-core/deprecated';
import './VirtualGrid.example.css';
@@ -28,1162 +28,30 @@ import './VirtualGrid.example.css';
### Basic
-```js
-import React from 'react';
-import { debounce } from '@patternfly/react-core';
-import { TableGridBreakpoint } from '@patternfly/react-table';
-import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
-import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
-import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
-
-class VirtualizedExample extends React.Component {
- constructor(props) {
- super(props);
- const rows = [];
- for (let i = 0; i < 100; i++) {
- rows.push({
- id: `basic-row-${i}`,
- cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
- });
- }
-
- this.state = {
- columns: [
- {
- title: 'Repositories',
- props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
- },
- {
- title: 'Branches',
- props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
- },
- {
- title: 'Pull requests',
- props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }
- },
- {
- title: 'Workspaces',
- props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }
- },
- { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }
- ],
- rows
- };
- this._handleResize = debounce(this._handleResize.bind(this), 100);
- }
-
- componentDidMount() {
- // re-render after resize
- window.addEventListener('resize', this._handleResize);
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this._handleResize);
- }
-
- _handleResize() {
- this.forceUpdate();
- }
-
- render() {
- const { columns, rows } = this.state;
-
- const measurementCache = new CellMeasurerCache({
- fixedWidth: true,
- minHeight: 44,
- keyMapper: rowIndex => rowIndex
- });
-
- const rowRenderer = ({ index, isScrolling, key, style, parent }) => {
- const { rows, columns } = this.state;
-
- return (
-
-
-
- {rows[index].cells[0]}
-
-
- {rows[index].cells[1]}
-
-
- {rows[index].cells[2]}
-
-
- {rows[index].cells[3]}
-
-
- {rows[index].cells[4]}
-
-
-
- );
- };
-
- return (
-
-
-
-
-
- {({ width }) => (
-
- )}
-
-
- );
- }
-}
+```js file="./Basic.tsx"
```
### Using composable table components
-```js
-import React from 'react';
-import { debounce } from '@patternfly/react-core';
-import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
-import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
-import { Table, Thead, Tr, Th, Td, Caption, TableGridBreakpoint } from '@patternfly/react-table';
-
-ComposableTableVirtualized = () => {
- const rows = [];
- for (let i = 0; i < 100; i++) {
- rows.push([`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]);
- }
- const [selected, setSelected] = React.useState(rows.map(row => false));
- const columns = [
- 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'
- ];
-
- const onSelect = (event, isSelected, rowId) => {
- setSelected(selected.map((sel, index) => (index === rowId ? isSelected : sel)));
- };
-
- const measurementCache = new CellMeasurerCache({
- fixedWidth: true,
- minHeight: 44,
- keyMapper: rowIndex => rowIndex
- });
-
- const rowRenderer = ({ index: rowIndex, isScrolling, key, style, parent }) => (
-
-
-
- {columns.map((col, index) => (
-
- {rows[rowIndex][index]}
-
- ))}
-
-
- );
-
- return (
-
-
- Virtualized table with composable table components
-
-
-
- {columns.map((col, index) => (
-
- {col}
-
- ))}
-
-
-
-
- {({ width }) => (
-
- )}
-
-
- );
-};
+```js file="./UsingComposableTableComponents.tsx"
```
### Sortable
-```js
-import React from 'react';
-import { debounce } from '@patternfly/react-core';
-import { sortable, SortByDirection, TableGridBreakpoint } from '@patternfly/react-table';
-import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
-import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
-import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
-
-class SortableExample extends React.Component {
- constructor(props) {
- super(props);
- const rows = [];
- for (let i = 0; i < 100; i++) {
- rows.push({
- id: `sortable-row-${i}`,
- cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
- });
- }
-
- this.sortableVirtualBody = null;
-
- this.state = {
- columns: [
- {
- title: 'Repositories',
- transforms: [sortable],
- props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
- },
- {
- title: 'Branches',
- props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
- },
- {
- title: 'Pull requests',
- transforms: [sortable],
- props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }
- },
- {
- title: 'Workspaces',
- props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }
- },
- { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }
- ],
- rows,
- sortBy: {}
- };
-
- this.onSort = this.onSort.bind(this);
- this._handleResize = debounce(this._handleResize.bind(this), 100);
- }
-
- componentDidMount() {
- // re-render after resize
- window.addEventListener('resize', this._handleResize);
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this._handleResize);
- }
-
- _handleResize() {
- this.forceUpdate();
- }
-
- onSort(_event, index, direction) {
- const sortedRows = this.state.rows.sort((a, b) =>
- a.cells[index] < b.cells[index] ? -1 : a.cells[index] > b.cells[index] ? 1 : 0
- );
- this.setState({
- sortBy: {
- index,
- direction
- },
- rows: direction === SortByDirection.asc ? sortedRows : sortedRows.reverse()
- });
-
- this.sortableVirtualBody.forceUpdateVirtualGrid();
- }
-
- render() {
- const { sortBy, columns, rows } = this.state;
-
- const measurementCache = new CellMeasurerCache({
- fixedWidth: true,
- minHeight: 44,
- keyMapper: rowIndex => rowIndex
- });
-
- const rowRenderer = ({ index, isScrolling, key, style, parent }) => {
- const { rows, columns } = this.state;
-
- return (
-
-
-
- {rows[index].cells[0]}
-
-
- {rows[index].cells[1]}
-
-
- {rows[index].cells[2]}
-
-
- {rows[index].cells[3]}
-
-
- {rows[index].cells[4]}
-
-
-
- );
- };
-
- return (
-
-
-
-
-
- {({ width }) => (
- (this.sortableVirtualBody = ref)}
- className="pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller"
- deferredMeasurementCache={measurementCache}
- rowHeight={measurementCache.rowHeight}
- height={400}
- overscanRowCount={2}
- columnCount={1}
- rows={rows}
- rowCount={rows.length}
- rowRenderer={rowRenderer}
- width={width}
- role="grid"
- />
- )}
-
-
- );
- }
-}
+```js file="./Sortable.tsx"
```
### Selectable
-```js
-import React from 'react';
-import { debounce } from '@patternfly/react-core';
-import { headerCol, TableGridBreakpoint } from '@patternfly/react-table';
-import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
-import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
-import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
-
-class SelectableExample extends React.Component {
- constructor(props) {
- super(props);
- const rows = [];
- for (let i = 0; i < 100; i++) {
- rows.push({
- selected: false,
- id: `selectable-row-${i}`,
- cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
- });
- }
-
- this.selectableVirtualBody = null;
-
- this.state = {
- columns: [
- // headerCol transform adds checkbox column with pf-m-2-sm, pf-m-1-md+ column space
- {
- title: 'Repositories',
- cellTransforms: [headerCol()],
- props: { className: 'pf-m-5-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
- },
- {
- title: 'Pull requests',
- props: { className: 'pf-m-5-col-on-sm pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl' }
- },
- {
- title: 'Workspaces',
- props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }
- },
- { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }
- ],
- rows
- };
-
- this.onSelect = this.onSelect.bind(this);
- this._handleResize = debounce(this._handleResize.bind(this), 100);
- }
-
- componentDidMount() {
- // re-render after resize
- window.addEventListener('resize', this._handleResize);
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this._handleResize);
- }
-
- _handleResize() {
- this.forceUpdate();
- }
-
- onSelect(event, isSelected, virtualRowIndex, rowData) {
- let rows;
- if (virtualRowIndex === -1) {
- rows = this.state.rows.map(oneRow => {
- oneRow.selected = isSelected;
- return oneRow;
- });
- } else {
- rows = [...this.state.rows];
- const rowIndex = rows.findIndex(r => r.id === rowData.id);
- rows[rowIndex] = { ...rows[rowIndex], selected: isSelected };
- }
- this.setState({
- rows
- });
- this.selectableVirtualBody.forceUpdateVirtualGrid();
- }
-
- render() {
- const { columns, rows } = this.state;
-
- const measurementCache = new CellMeasurerCache({
- fixedWidth: true,
- minHeight: 44,
- keyMapper: rowIndex => rowIndex
- });
-
- const rowRenderer = ({ index, isScrolling, key, style, parent }) => {
- const { rows, columns } = this.state;
-
- return (
-
-
-
- {
- this.onSelect(e, e.target.checked, 0, { id: rows[index].id });
- }}
- />
-
-
- {rows[index].cells[0]}
-
-
- {rows[index].cells[1]}
-
-
- {rows[index].cells[2]}
-
-
- {rows[index].cells[3]}
-
-
-
- );
- };
-
- return (
-
-
-
-
-
- {({ width }) => (
- (this.selectableVirtualBody = ref)}
- className="pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller"
- deferredMeasurementCache={measurementCache}
- rowHeight={measurementCache.rowHeight}
- height={400}
- overscanRowCount={2}
- columnCount={1}
- rows={rows}
- rowCount={rows.length}
- rowRenderer={rowRenderer}
- width={width}
- role="grid"
- />
- )}
-
-
- );
- }
-}
+```js file="./Selectable.tsx"
```
### Actions
-```js
-import React from 'react';
-import { debounce } from '@patternfly/react-core';
-import { ActionsColumn, TableGridBreakpoint } from '@patternfly/react-table';
-import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
-import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
-import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension';
-
-class ActionsExample extends React.Component {
- constructor(props) {
- super(props);
- const rows = [];
- for (let i = 0; i < 100; i++) {
- rows.push({
- disableActions: i % 3 === 2,
- id: `actions-row-${i}`,
- cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]
- });
- }
-
- this.actionsVirtualBody = null;
-
- this.state = {
- columns: [
- { title: 'Name', props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' } },
- {
- title: 'Namespace',
- props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
- },
- {
- title: 'Labels',
- props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }
- },
- { title: 'Status', props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' } },
- { title: 'Pod Selector', props: { className: 'pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-xl' } },
- { title: '', props: { className: 'pf-v5-c-table__action' } }
- ],
- rows,
- actions: [
- {
- title: 'Some action',
- onClick: (event, rowId, rowData, extra) => console.log('clicked on Some action, on row: ', rowId)
- },
- {
- title: Another action
,
- onClick: (event, rowId, rowData, extra) => console.log('clicked on Another action, on row: ', rowId)
- },
- {
- isSeparator: true
- },
- {
- title: 'Third action',
- onClick: (event, rowId, rowData, extra) => console.log('clicked on Third action, on row: ', rowId)
- }
- ]
- };
-
- this._handleResize = debounce(this._handleResize.bind(this), 100);
- }
-
- componentDidMount() {
- // re-render after resize
- window.addEventListener('resize', this._handleResize);
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this._handleResize);
- }
-
- _handleResize() {
- this.forceUpdate();
- }
-
- render() {
- const { columns, rows } = this.state;
-
- const measurementCache = new CellMeasurerCache({
- fixedWidth: true,
- minHeight: 44,
- keyMapper: rowIndex => rowIndex
- });
-
- const rowRenderer = ({ index, isScrolling, key, style, parent }) => {
- const { rows, columns, actions } = this.state;
-
- return (
-
-
-
- {rows[index].cells[0]}
-
-
- {rows[index].cells[1]}
-
-
- {rows[index].cells[2]}
-
-
- {rows[index].cells[3]}
-
-
- {rows[index].cells[4]}
-
-
-
-
-
-
- );
- };
-
- return (
-
-
-
-
-
- {({ width }) => (
- (this.actionsVirtualBody = ref)}
- className="pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller"
- deferredMeasurementCache={measurementCache}
- rowHeight={measurementCache.rowHeight}
- height={400}
- overscanRowCount={2}
- columnCount={1}
- rows={rows}
- rowCount={rows.length}
- rowRenderer={rowRenderer}
- width={width}
- role="grid"
- />
- )}
-
-
- );
- }
-}
+```js file="./Actions.tsx"
```
### Filterable with WindowScroller
-```js
-import React from 'react';
-import {
- Button,
- ButtonVariant,
- Toolbar,
- ToolbarItem,
- ToolbarContent,
- ToolbarFilter,
- ToolbarToggleGroup,
- ToolbarGroup,
- InputGroup,
- TextInput
-} from '@patternfly/react-core';
-import { debounce } from '@patternfly/react-core';
-import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
-import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon';
-import { ActionsColumn } from '@patternfly/react-table';
-import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
-import {
- Dropdown,
- DropdownItem,
- DropdownPosition,
- DropdownToggle,
- Select,
- SelectOption,
- SelectVariant
-} from '@patternfly/react-core/deprecated';
-import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
-import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-virtualized-extension';
-
-class FilterExample extends React.Component {
- constructor(props) {
- super(props);
-
- this.actionsVirtualBody = null;
-
- const rows = [];
- for (let i = 0; i < 100; i++) {
- const data = {};
- if (i % 2 === 0) {
- data.cells = [`US-Node ${i}`, i, i, 'Down', 'Brno'];
- } else if (i % 3 === 0) {
- data.cells = [`CN-Node ${i}`, i, i, 'Running', 'Westford'];
- } else {
- data.cells = [`US-Node ${i}`, i, i, 'Stopped', 'Raleigh'];
- }
- rows.push(data);
- }
- this.scrollableElement = React.createRef();
-
- this.state = {
- scrollableElement: null,
-
- filters: {
- location: [],
- name: [],
- status: []
- },
- currentCategory: 'Name',
- isFilterDropdownOpen: false,
- isCategoryDropdownOpen: false,
- nameInput: '',
- columns: [
- { title: 'Servers' },
- { title: 'Threads' },
- { title: 'Applications' },
- { title: 'Status' },
- { title: 'Location' }
- ],
- rows,
- inputValue: '',
- actions: [
- {
- title: 'Some action',
- onClick: (event, rowId, rowData, extra) => console.log('clicked on Some action, on row: ', rowId)
- },
- {
- title: Another action
,
- onClick: (event, rowId, rowData, extra) => console.log('clicked on Another action, on row: ', rowId)
- },
- {
- isSeparator: true
- },
- {
- title: 'Third action',
- onClick: (event, rowId, rowData, extra) => console.log('clicked on Third action, on row: ', rowId)
- }
- ]
- };
-
- this._handleResize = debounce(this._handleResize.bind(this), 100);
-
- this.onDelete = (type = '', id = '') => {
- if (type) {
- this.setState(prevState => {
- prevState.filters[type.toLowerCase()] = prevState.filters[type.toLowerCase()].filter(s => s !== id);
- return {
- filters: prevState.filters
- };
- });
- } else {
- this.setState({
- filters: {
- location: [],
- name: [],
- status: []
- },
- inputValue: ''
- });
- }
- };
-
- this.onCategoryToggle = isOpen => {
- this.setState({
- isCategoryDropdownOpen: isOpen
- });
- };
-
- this.onCategorySelect = event => {
- this.setState({
- currentCategory: event.target.innerText,
- isCategoryDropdownOpen: !this.state.isCategoryDropdownOpen
- });
- };
-
- this.onFilterToggle = isOpen => {
- this.setState({
- isFilterDropdownOpen: isOpen
- });
- };
-
- this.onFilterSelect = event => {
- this.setState({
- isFilterDropdownOpen: !this.state.isFilterDropdownOpen
- });
- };
-
- this.onInputChange = newValue => {
- // this.setState({ inputValue: newValue });
- if (newValue === '') {
- this.onDelete();
- this.setState({
- inputValue: newValue
- });
- } else {
- this.setState(prevState => {
- return {
- filters: {
- ...prevState.filters,
- ['name']: [newValue]
- },
- inputValue: newValue
- };
- });
- }
- };
-
- this.onRowSelect = (event, isSelected, rowId) => {
- let rows;
- if (rowId === -1) {
- rows = this.state.rows.map(oneRow => {
- oneRow.selected = isSelected;
- return oneRow;
- });
- } else {
- rows = [...this.state.rows];
- rows[rowId].selected = isSelected;
- }
- this.setState({
- rows
- });
- };
-
- this.onStatusSelect = (event, selection) => {
- const checked = event.target.checked;
- this.setState(prevState => {
- const prevSelections = prevState.filters['status'];
- return {
- filters: {
- ...prevState.filters,
- status: checked ? [...prevSelections, selection] : prevSelections.filter(value => value !== selection)
- }
- };
- });
- };
-
- this.onNameInput = event => {
- if (event.key && event.key !== 'Enter') {
- return;
- }
-
- const { inputValue } = this.state;
- this.setState(prevState => {
- const prevFilters = prevState.filters['name'];
- return {
- filters: {
- ...prevState.filters,
- ['name']: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue]
- },
- inputValue: ''
- };
- });
- };
-
- this.onLocationSelect = (event, selection) => {
- this.setState(prevState => {
- return {
- filters: {
- ...prevState.filters,
- ['location']: [selection]
- }
- };
- });
- this.onFilterSelect();
- };
-
- this._handleResize = debounce(this._handleResize.bind(this), 100);
- this._bindBodyRef = this._bindBodyRef.bind(this);
- }
-
- componentDidMount() {
- // re-render after resize
- window.addEventListener('resize', this._handleResize);
-
- setTimeout(() => {
- const scollableElement = document.getElementById('content-scrollable-1');
- this.setState({ scollableElement });
- });
-
- // re-render after resize
- window.addEventListener('resize', this._handleResize);
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this._handleResize);
- }
-
- _handleResize() {
- this._cellMeasurementCache.clearAll();
- this._bodyRef.recomputeVirtualGridSize();
- }
-
- _bindBodyRef(ref) {
- this._bodyRef = ref;
- }
-
- buildCategoryDropdown() {
- const { isCategoryDropdownOpen, currentCategory } = this.state;
-
- return (
-
-
- {currentCategory}
-
- }
- isOpen={isCategoryDropdownOpen}
- dropdownItems={[
- Location ,
- Name ,
- Status
- ]}
- style={{ width: '100%' }}
- >
-
- );
- }
-
- buildFilterDropdown() {
- const { currentCategory, isFilterDropdownOpen, inputValue, filters } = this.state;
-
- const locationMenuItems = [
- ,
- ,
- ,
- ,
-
- ];
-
- const statusMenuItems = [
- ,
- ,
- ,
- ,
-
- ];
-
- return (
-
-
-
- {locationMenuItems}
-
-
-
-
-
-
-
-
-
-
-
-
- {statusMenuItems}
-
-
-
- );
- }
-
- renderToolbar() {
- const { filters } = this.state;
- return (
-
-
- } breakpoint="xl">
-
- {this.buildCategoryDropdown()}
- {this.buildFilterDropdown()}
-
-
-
-
- );
- }
-
- render() {
- const { loading, rows, columns, actions, filters, scollableElement } = this.state;
-
- const filteredRows =
- filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0
- ? rows.filter(row => {
- return (
- (filters.name.length === 0 ||
- filters.name.some(name => row.cells[0].toLowerCase().includes(name.toLowerCase()))) &&
- (filters.location.length === 0 || filters.location.includes(row.cells[4])) &&
- (filters.status.length === 0 || filters.status.includes(row.cells[3]))
- );
- })
- : rows;
- const measurementCache = new CellMeasurerCache({
- fixedWidth: true,
- minHeight: 44,
- keyMapper: rowIndex => rowIndex
- });
-
- const rowRenderer = ({ index, isScrolling, key, style, parent }) => {
- const { columns, actions } = this.state;
-
- return (
-
-
- {filteredRows[index].cells[0]}
- {filteredRows[index].cells[1]}
- {filteredRows[index].cells[2]}
- {filteredRows[index].cells[3]}
- {filteredRows[index].cells[4]}
-
-
-
-
-
- );
- };
-
- return (
-
- {this.renderToolbar()}
-
-
-
- {!loading && filteredRows.length > 0 && (
-
-
-
-
-
- {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (
-
- {({ width }) => (
-
- (this.actionsVirtualBody = ref)}
- autoHeight
- className="pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller"
- deferredMeasurementCache={measurementCache}
- rowHeight={measurementCache.rowHeight}
- height={height || 0}
- overscanRowCount={10}
- columnCount={6}
- rows={filteredRows}
- rowCount={filteredRows.length}
- rowRenderer={rowRenderer}
- scrollTop={scrollTop}
- width={width}
- role="grid"
- />
-
- )}
-
- )}
-
-
- )}
-
-
-
- );
- }
-}
+```js file="./FilterableWithWindowScroller.tsx"
```
diff --git a/packages/module/patternfly-docs/content/examples/WindowScroller.md b/packages/module/patternfly-docs/content/examples/WindowScroller.md
index 605f974..dbfed96 100644
--- a/packages/module/patternfly-docs/content/examples/WindowScroller.md
+++ b/packages/module/patternfly-docs/content/examples/WindowScroller.md
@@ -22,295 +22,10 @@ import './WindowScroller.example.css';
### Window scroller
-```js
-import React from 'react';
-import { debounce } from '@patternfly/react-core';
-import { TableGridBreakpoint } from '@patternfly/react-table';
-import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
-import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
-import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-virtualized-extension';
-
-class WindowScrollerExample extends React.Component {
- constructor(props) {
- super(props);
- const rows = [];
- for (let i = 0; i < 100000; i++) {
- const cells = [];
- const num = Math.floor(Math.random() * Math.floor(2)) + 1;
- for (let j = 0; j < 5; j++) {
- const cellValue = i.toString() + ' Arma virumque cano Troiae qui primus ab oris. '.repeat(num);
- cells.push(cellValue);
- }
- rows.push({
- id: `window-scroller-row-${i}`,
- cells
- });
-
- this._cellMeasurementCache = new CellMeasurerCache({
- fixedWidth: true,
- minHeight: 44,
- keyMapper: rowIndex => rowIndex
- });
- }
-
- this.state = {
- scrollToIndex: -1, // can be used to programmatically set current index
- scrollableElement: null,
- columns: [
- {
- title: 'Repositories',
- props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
- },
- {
- title: 'Branches',
- props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
- },
- {
- title: 'Pull requests',
- props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }
- },
- {
- title: 'Workspaces',
- props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }
- },
- { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }
- ],
- rows
- };
-
- this._handleResize = debounce(this._handleResize.bind(this), 100);
- this._bindBodyRef = this._bindBodyRef.bind(this);
- }
-
- componentDidMount() {
- // re-render after resize
- window.addEventListener('resize', this._handleResize);
-
- this.setState({ scrollableElement: document.getElementById('content-scrollable-1') });
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this._handleResize);
- }
-
- _handleResize() {
- this._cellMeasurementCache.clearAll();
- this._bodyRef.recomputeVirtualGridSize();
- }
-
- _bindBodyRef(ref) {
- this._bodyRef = ref;
- }
-
- render() {
- const { scrollToIndex, columns, rows, scrollableElement } = this.state;
-
- const rowRenderer = ({ index, isScrolling, key, style, parent }) => {
- const { rows, columns } = this.state;
- const text = rows[index].cells[0];
-
- return (
-
-
-
- {text}
-
-
- {text}
-
-
- {text}
-
-
- {text}
-
-
- {text}
-
-
-
- );
- };
-
- return (
-
-
-
-
-
- {scrollableElement &&
- {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (
-
- {({ width }) => (
-
-
-
- )}
-
- )}
- }
-
-
- );
- }
-}
+```js file="./WindowScroller.tsx"
```
### Using composable table components
-```js
-import React from 'react';
-import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
-import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-virtualized-extension';
-import { Table, Thead, Tr, Th, Td, Caption, TableGridBreakpoint } from '@patternfly/react-table';
-
-ComposableTableWindowScroller = () => {
- const [scrollableElement, setScrollableElement] = React.useState();
- React.useEffect(() => {
- const scrollableElement = document.getElementById('content-scrollable-2');
- setScrollableElement(scrollableElement);
- });
- const rows = [];
- for (let i = 0; i < 100000; i++) {
- const cells = [];
- const num = Math.floor(Math.random() * Math.floor(2)) + 1;
- for (let j = 0; j < 5; j++) {
- const cellValue = i.toString() + ' Arma virumque cano Troiae qui primus ab oris. '.repeat(num);
- cells.push(cellValue);
- }
- rows.push(cells);
- }
- const [selected, setSelected] = React.useState(rows.map(row => false));
- const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'];
- const scrollToIndex = -1; // can be used to programmatically set current index
-
- const onSelect = (event, isSelected, rowId) => {
- setSelected(selected.map((sel, index) => (index === rowId ? isSelected : sel)));
- };
-
- const measurementCache = new CellMeasurerCache({
- fixedWidth: true,
- minHeight: 44,
- keyMapper: rowIndex => rowIndex
- });
-
- const rowRenderer = ({ index: rowIndex, isScrolling, key, style, parent }) => {
- const text = rows[rowIndex][0];
-
- return (
-
-
-
- {columns.map((col, index) => (
- {text}
- ))}
-
-
- );
- };
-
- const scrollableContainerStyle = {
- height: 500 /* important note: the scrollable container should have some sort of fixed height, or it should be wrapped in container that is smaller than ReactVirtualized__VirtualGrid container and has overflow visible if using the Window Scroller. See WindowScroller.example.css */,
- overflowX: 'auto',
- overflowY: 'scroll',
- scrollBehavior: 'smooth',
- WebkitOverflowScrolling: 'touch',
- position: 'relative'
- };
-
- return (
-
-
- Virtualized table with composable table components
-
-
-
- {columns.map((col, index) => (
- {col}
- ))}
-
-
-
-
- {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (
-
- {({ width }) => (
-
-
-
- )}
-
- )}
-
-
- );
-};
+```js file="UsingComposableTableComponentsDemo.tsx"
```
diff --git a/packages/module/patternfly-docs/content/examples/WindowScroller.tsx b/packages/module/patternfly-docs/content/examples/WindowScroller.tsx
new file mode 100644
index 0000000..6383e39
--- /dev/null
+++ b/packages/module/patternfly-docs/content/examples/WindowScroller.tsx
@@ -0,0 +1,170 @@
+import React from 'react';
+import { debounce } from '@patternfly/react-core';
+import { TableGridBreakpoint } from '@patternfly/react-table';
+import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
+import { CellMeasurerCache, CellMeasurer } from 'react-virtualized';
+import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-virtualized-extension';
+
+export class WindowScrollerExample extends React.Component {
+ constructor(props) {
+ super(props);
+ const rows = [];
+ for (let i = 0; i < 100000; i++) {
+ const cells = [];
+ const num = Math.floor(Math.random() * Math.floor(2)) + 1;
+ for (let j = 0; j < 5; j++) {
+ const cellValue = i.toString() + ' Arma virumque cano Troiae qui primus ab oris. '.repeat(num);
+ cells.push(cellValue);
+ }
+ rows.push({
+ id: `window-scroller-row-${i}`,
+ cells
+ });
+
+ this._cellMeasurementCache = new CellMeasurerCache({
+ fixedWidth: true,
+ minHeight: 44,
+ keyMapper: (rowIndex) => rowIndex
+ });
+ }
+
+ this.state = {
+ scrollToIndex: -1, // can be used to programmatically set current index
+ scrollableElement: null,
+ columns: [
+ {
+ title: 'Repositories',
+ props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
+ },
+ {
+ title: 'Branches',
+ props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }
+ },
+ {
+ title: 'Pull requests',
+ props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }
+ },
+ {
+ title: 'Workspaces',
+ props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }
+ },
+ { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }
+ ],
+ rows
+ };
+
+ this._handleResize = debounce(this._handleResize.bind(this), 100);
+ this._bindBodyRef = this._bindBodyRef.bind(this);
+ }
+
+ componentDidMount() {
+ // re-render after resize
+ window.addEventListener('resize', this._handleResize);
+
+ this.setState({ scrollableElement: document.getElementById('content-scrollable-1') });
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this._handleResize);
+ }
+
+ _handleResize() {
+ this._cellMeasurementCache.clearAll();
+ this._bodyRef.recomputeVirtualGridSize();
+ }
+
+ _bindBodyRef(ref) {
+ this._bodyRef = ref;
+ }
+
+ render() {
+ const { scrollToIndex, columns, rows, scrollableElement } = this.state;
+
+ const rowRenderer = ({ index, _isScrolling, key, style, parent }) => {
+ const { rows, columns } = this.state;
+ const text = rows[index].cells[0];
+
+ return (
+
+
+
+ {text}
+
+
+ {text}
+
+
+ {text}
+
+
+ {text}
+
+
+ {text}
+
+
+
+ );
+ };
+
+ return (
+
+
+
+
+
+ {scrollableElement && (
+
+ {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (
+
+ {({ width }) => (
+
+
+
+ )}
+
+ )}
+
+ )}
+
+
+ );
+ }
+}
diff --git a/packages/module/patternfly-docs/generated/extensions/virtual-scroll-table/react.js b/packages/module/patternfly-docs/generated/extensions/virtual-scroll-table/react.js
index e00c243..3b6a220 100644
--- a/packages/module/patternfly-docs/generated/extensions/virtual-scroll-table/react.js
+++ b/packages/module/patternfly-docs/generated/extensions/virtual-scroll-table/react.js
@@ -6,13 +6,13 @@ import { CellMeasurerCache, CellMeasurer} from 'react-virtualized';
import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-virtualized-extension';
import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated';
import {
- Dropdown,
- DropdownItem,
- DropdownPosition,
- DropdownToggle,
- Select,
- SelectOption,
- SelectVariant
+ Dropdown as DropdownDeprecated,
+ DropdownItem as DropdownItemDeprecated,
+ DropdownPosition as DropdownPositionDeprecated,
+ DropdownToggle as DropdownToggleDeprecated,
+ Select as SelectDeprecated,
+ SelectOption as SelectOptionDeprecated,
+ SelectVariant as SelectVariantDeprecated
} from '@patternfly/react-core/deprecated';
import '../../../content/examples/./VirtualGrid.example.css';
const pageData = {
@@ -191,40 +191,40 @@ pageData.liveContext = {
WindowScroller,
TableDeprecated,
TableHeaderDeprecated,
- Dropdown,
- DropdownItem,
- DropdownPosition,
- DropdownToggle,
- Select,
- SelectOption,
- SelectVariant
+ DropdownDeprecated,
+ DropdownItemDeprecated,
+ DropdownPositionDeprecated,
+ DropdownToggleDeprecated,
+ SelectDeprecated,
+ SelectOptionDeprecated,
+ SelectVariantDeprecated
};
pageData.relativeImports = {
};
pageData.examples = {
'Basic': props =>
- rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns } = this.state;\n\n return (\n \n \n \n {rows[index].cells[0]}\n \n \n {rows[index].cells[1]}\n \n \n {rows[index].cells[2]}\n \n \n {rows[index].cells[3]}\n \n \n {rows[index].cells[4]}\n \n \n \n );\n };\n\n return (\n \n
\n \n \n
\n {({ width }) => (\n \n )}\n \n
\n );\n }\n}","title":"Basic","lang":"js"}}>
+ rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns } = this.state;\n\n return (\n \n \n \n {rows[index].cells[0]}\n \n \n {rows[index].cells[1]}\n \n \n {rows[index].cells[2]}\n \n \n {rows[index].cells[3]}\n \n \n {rows[index].cells[4]}\n \n \n \n );\n };\n\n return (\n \n
\n \n \n
\n {({ width }) => (\n \n )}\n \n
\n );\n }\n}\n","title":"Basic","lang":"js"}}>
,
'Using composable table components': props =>
- {\n const rows = [];\n for (let i = 0; i < 100; i++) {\n rows.push([`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]);\n }\n const [selected, setSelected] = React.useState(rows.map(row => false));\n const columns = [\n 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'\n ];\n\n const onSelect = (event, isSelected, rowId) => {\n setSelected(selected.map((sel, index) => (index === rowId ? isSelected : sel)));\n };\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: rowIndex => rowIndex\n });\n\n const rowRenderer = ({ index: rowIndex, isScrolling, key, style, parent }) => (\n \n \n \n {columns.map((col, index) => (\n \n {rows[rowIndex][index]}\n \n ))}\n \n \n );\n\n return (\n \n
\n Virtualized table with composable table components \n \n \n \n {columns.map((col, index) => (\n \n {col}\n \n ))}\n \n \n
\n
\n {({ width }) => (\n \n )}\n \n
\n );\n};","title":"Using composable table components","lang":"js"}}>
+ {\n const rows = [];\n for (let i = 0; i < 100; i++) {\n rows.push([`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]);\n }\n const [selected, setSelected] = React.useState(rows.map((row) => false));\n const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'];\n\n const onSelect = (event, isSelected, rowId) => {\n setSelected(selected.map((sel, index) => (index === rowId ? isSelected : sel)));\n };\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: (rowIndex) => rowIndex\n });\n\n const rowRenderer = ({ index: rowIndex, isScrolling, key, style, parent }) => (\n \n \n \n {columns.map((col, index) => (\n {rows[rowIndex][index]} \n ))}\n \n \n );\n\n return (\n \n
\n Virtualized table with composable table components \n \n \n \n {columns.map((col, index) => (\n {col} \n ))}\n \n \n
\n
\n {({ width }) => (\n \n )}\n \n
\n );\n};\n","title":"Using composable table components","lang":"js"}}>
,
'Sortable': props =>
- \n a.cells[index] < b.cells[index] ? -1 : a.cells[index] > b.cells[index] ? 1 : 0\n );\n this.setState({\n sortBy: {\n index,\n direction\n },\n rows: direction === SortByDirection.asc ? sortedRows : sortedRows.reverse()\n });\n\n this.sortableVirtualBody.forceUpdateVirtualGrid();\n }\n\n render() {\n const { sortBy, columns, rows } = this.state;\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: rowIndex => rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns } = this.state;\n\n return (\n \n \n \n {rows[index].cells[0]}\n \n \n {rows[index].cells[1]}\n \n \n {rows[index].cells[2]}\n \n \n {rows[index].cells[3]}\n \n \n {rows[index].cells[4]}\n \n \n \n );\n };\n\n return (\n \n
\n \n \n
\n {({ width }) => (\n (this.sortableVirtualBody = ref)}\n className=\"pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller\"\n deferredMeasurementCache={measurementCache}\n rowHeight={measurementCache.rowHeight}\n height={400}\n overscanRowCount={2}\n columnCount={1}\n rows={rows}\n rowCount={rows.length}\n rowRenderer={rowRenderer}\n width={width}\n role=\"grid\"\n />\n )}\n \n
\n );\n }\n}","title":"Sortable","lang":"js"}}>
+ \n a.cells[index] < b.cells[index] ? -1 : a.cells[index] > b.cells[index] ? 1 : 0\n );\n this.setState({\n sortBy: {\n index,\n direction\n },\n rows: direction === SortByDirection.asc ? sortedRows : sortedRows.reverse()\n });\n\n this.sortableVirtualBody.forceUpdateVirtualGrid();\n }\n\n render() {\n const { sortBy, columns, rows } = this.state;\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: (rowIndex) => rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns } = this.state;\n\n return (\n \n \n \n {rows[index].cells[0]}\n \n \n {rows[index].cells[1]}\n \n \n {rows[index].cells[2]}\n \n \n {rows[index].cells[3]}\n \n \n {rows[index].cells[4]}\n \n \n \n );\n };\n\n return (\n \n
\n \n \n
\n {({ width }) => (\n (this.sortableVirtualBody = ref)}\n className=\"pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller\"\n deferredMeasurementCache={measurementCache}\n rowHeight={measurementCache.rowHeight}\n height={400}\n overscanRowCount={2}\n columnCount={1}\n rows={rows}\n rowCount={rows.length}\n rowRenderer={rowRenderer}\n width={width}\n role=\"grid\"\n />\n )}\n \n
\n );\n }\n}\n","title":"Sortable","lang":"js"}}>
,
'Selectable': props =>
- {\n oneRow.selected = isSelected;\n return oneRow;\n });\n } else {\n rows = [...this.state.rows];\n const rowIndex = rows.findIndex(r => r.id === rowData.id);\n rows[rowIndex] = { ...rows[rowIndex], selected: isSelected };\n }\n this.setState({\n rows\n });\n this.selectableVirtualBody.forceUpdateVirtualGrid();\n }\n\n render() {\n const { columns, rows } = this.state;\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: rowIndex => rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns } = this.state;\n\n return (\n \n \n \n {\n this.onSelect(e, e.target.checked, 0, { id: rows[index].id });\n }}\n />\n \n \n {rows[index].cells[0]}\n \n \n {rows[index].cells[1]}\n \n \n {rows[index].cells[2]}\n \n \n {rows[index].cells[3]}\n \n \n \n );\n };\n\n return (\n \n
\n \n \n
\n {({ width }) => (\n (this.selectableVirtualBody = ref)}\n className=\"pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller\"\n deferredMeasurementCache={measurementCache}\n rowHeight={measurementCache.rowHeight}\n height={400}\n overscanRowCount={2}\n columnCount={1}\n rows={rows}\n rowCount={rows.length}\n rowRenderer={rowRenderer}\n width={width}\n role=\"grid\"\n />\n )}\n \n
\n );\n }\n}","title":"Selectable","lang":"js"}}>
+ {\n oneRow.selected = isSelected;\n return oneRow;\n });\n } else {\n rows = [...this.state.rows];\n const rowIndex = rows.findIndex((r) => r.id === rowData.id);\n rows[rowIndex] = { ...rows[rowIndex], selected: isSelected };\n }\n this.setState({\n rows\n });\n this.selectableVirtualBody.forceUpdateVirtualGrid();\n }\n\n render() {\n const { columns, rows } = this.state;\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: (rowIndex) => rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns } = this.state;\n\n return (\n \n \n \n {\n this.onSelect(e, e.target.checked, 0, { id: rows[index].id });\n }}\n />\n \n \n {rows[index].cells[0]}\n \n \n {rows[index].cells[1]}\n \n \n {rows[index].cells[2]}\n \n \n {rows[index].cells[3]}\n \n \n \n );\n };\n\n return (\n \n
\n \n \n
\n {({ width }) => (\n (this.selectableVirtualBody = ref)}\n className=\"pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller\"\n deferredMeasurementCache={measurementCache}\n rowHeight={measurementCache.rowHeight}\n height={400}\n overscanRowCount={2}\n columnCount={1}\n rows={rows}\n rowCount={rows.length}\n rowRenderer={rowRenderer}\n width={width}\n role=\"grid\"\n />\n )}\n \n
\n );\n }\n}\n","title":"Selectable","lang":"js"}}>
,
'Actions': props =>
- console.log('clicked on Some action, on row: ', rowId)\n },\n {\n title: Another action
,\n onClick: (event, rowId, rowData, extra) => console.log('clicked on Another action, on row: ', rowId)\n },\n {\n isSeparator: true\n },\n {\n title: 'Third action',\n onClick: (event, rowId, rowData, extra) => console.log('clicked on Third action, on row: ', rowId)\n }\n ]\n };\n\n this._handleResize = debounce(this._handleResize.bind(this), 100);\n }\n\n componentDidMount() {\n // re-render after resize\n window.addEventListener('resize', this._handleResize);\n }\n\n componentWillUnmount() {\n window.removeEventListener('resize', this._handleResize);\n }\n\n _handleResize() {\n this.forceUpdate();\n }\n\n render() {\n const { columns, rows } = this.state;\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: rowIndex => rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns, actions } = this.state;\n\n return (\n \n \n \n {rows[index].cells[0]}\n \n \n {rows[index].cells[1]}\n \n \n {rows[index].cells[2]}\n \n \n {rows[index].cells[3]}\n \n \n {rows[index].cells[4]}\n \n \n \n \n \n \n );\n };\n\n return (\n \n
\n \n \n
\n {({ width }) => (\n (this.actionsVirtualBody = ref)}\n className=\"pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller\"\n deferredMeasurementCache={measurementCache}\n rowHeight={measurementCache.rowHeight}\n height={400}\n overscanRowCount={2}\n columnCount={1}\n rows={rows}\n rowCount={rows.length}\n rowRenderer={rowRenderer}\n width={width}\n role=\"grid\"\n />\n )}\n \n
\n );\n }\n}","title":"Actions","lang":"js"}}>
+ console.log('clicked on Some action, on row: ', rowId)\n },\n {\n title: Another action
,\n onClick: (event, rowId, rowData, extra) => console.log('clicked on Another action, on row: ', rowId)\n },\n {\n isSeparator: true\n },\n {\n title: 'Third action',\n onClick: (event, rowId, rowData, extra) => console.log('clicked on Third action, on row: ', rowId)\n }\n ]\n };\n\n this._handleResize = debounce(this._handleResize.bind(this), 100);\n }\n\n componentDidMount() {\n // re-render after resize\n window.addEventListener('resize', this._handleResize);\n }\n\n componentWillUnmount() {\n window.removeEventListener('resize', this._handleResize);\n }\n\n _handleResize() {\n this.forceUpdate();\n }\n\n render() {\n const { columns, rows } = this.state;\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: (rowIndex) => rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns, actions } = this.state;\n\n return (\n \n \n \n {rows[index].cells[0]}\n \n \n {rows[index].cells[1]}\n \n \n {rows[index].cells[2]}\n \n \n {rows[index].cells[3]}\n \n \n {rows[index].cells[4]}\n \n \n \n \n \n \n );\n };\n\n return (\n \n
\n \n \n
\n {({ width }) => (\n (this.actionsVirtualBody = ref)}\n className=\"pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller\"\n deferredMeasurementCache={measurementCache}\n rowHeight={measurementCache.rowHeight}\n height={400}\n overscanRowCount={2}\n columnCount={1}\n rows={rows}\n rowCount={rows.length}\n rowRenderer={rowRenderer}\n width={width}\n role=\"grid\"\n />\n )}\n \n
\n );\n }\n}\n","title":"Actions","lang":"js"}}>
,
'Filterable with WindowScroller': props =>
- console.log('clicked on Some action, on row: ', rowId)\n },\n {\n title: Another action
,\n onClick: (event, rowId, rowData, extra) => console.log('clicked on Another action, on row: ', rowId)\n },\n {\n isSeparator: true\n },\n {\n title: 'Third action',\n onClick: (event, rowId, rowData, extra) => console.log('clicked on Third action, on row: ', rowId)\n }\n ]\n };\n\n this._handleResize = debounce(this._handleResize.bind(this), 100);\n\n this.onDelete = (type = '', id = '') => {\n if (type) {\n this.setState(prevState => {\n prevState.filters[type.toLowerCase()] = prevState.filters[type.toLowerCase()].filter(s => s !== id);\n return {\n filters: prevState.filters\n };\n });\n } else {\n this.setState({\n filters: {\n location: [],\n name: [],\n status: []\n },\n inputValue: ''\n });\n }\n };\n\n this.onCategoryToggle = isOpen => {\n this.setState({\n isCategoryDropdownOpen: isOpen\n });\n };\n\n this.onCategorySelect = event => {\n this.setState({\n currentCategory: event.target.innerText,\n isCategoryDropdownOpen: !this.state.isCategoryDropdownOpen\n });\n };\n\n this.onFilterToggle = isOpen => {\n this.setState({\n isFilterDropdownOpen: isOpen\n });\n };\n\n this.onFilterSelect = event => {\n this.setState({\n isFilterDropdownOpen: !this.state.isFilterDropdownOpen\n });\n };\n\n this.onInputChange = newValue => {\n // this.setState({ inputValue: newValue });\n if (newValue === '') {\n this.onDelete();\n this.setState({\n inputValue: newValue\n });\n } else {\n this.setState(prevState => {\n return {\n filters: {\n ...prevState.filters,\n ['name']: [newValue]\n },\n inputValue: newValue\n };\n });\n }\n };\n\n this.onRowSelect = (event, isSelected, rowId) => {\n let rows;\n if (rowId === -1) {\n rows = this.state.rows.map(oneRow => {\n oneRow.selected = isSelected;\n return oneRow;\n });\n } else {\n rows = [...this.state.rows];\n rows[rowId].selected = isSelected;\n }\n this.setState({\n rows\n });\n };\n\n this.onStatusSelect = (event, selection) => {\n const checked = event.target.checked;\n this.setState(prevState => {\n const prevSelections = prevState.filters['status'];\n return {\n filters: {\n ...prevState.filters,\n status: checked ? [...prevSelections, selection] : prevSelections.filter(value => value !== selection)\n }\n };\n });\n };\n\n this.onNameInput = event => {\n if (event.key && event.key !== 'Enter') {\n return;\n }\n\n const { inputValue } = this.state;\n this.setState(prevState => {\n const prevFilters = prevState.filters['name'];\n return {\n filters: {\n ...prevState.filters,\n ['name']: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue]\n },\n inputValue: ''\n };\n });\n };\n\n this.onLocationSelect = (event, selection) => {\n this.setState(prevState => {\n return {\n filters: {\n ...prevState.filters,\n ['location']: [selection]\n }\n };\n });\n this.onFilterSelect();\n };\n\n this._handleResize = debounce(this._handleResize.bind(this), 100);\n this._bindBodyRef = this._bindBodyRef.bind(this);\n }\n\n componentDidMount() {\n // re-render after resize\n window.addEventListener('resize', this._handleResize);\n\n setTimeout(() => {\n const scollableElement = document.getElementById('content-scrollable-1');\n this.setState({ scollableElement });\n });\n\n // re-render after resize\n window.addEventListener('resize', this._handleResize);\n }\n\n componentWillUnmount() {\n window.removeEventListener('resize', this._handleResize);\n }\n\n _handleResize() {\n this._cellMeasurementCache.clearAll();\n this._bodyRef.recomputeVirtualGridSize();\n }\n\n _bindBodyRef(ref) {\n this._bodyRef = ref;\n }\n\n buildCategoryDropdown() {\n const { isCategoryDropdownOpen, currentCategory } = this.state;\n\n return (\n \n \n {currentCategory}\n \n }\n isOpen={isCategoryDropdownOpen}\n dropdownItems={[\n Location ,\n Name ,\n Status \n ]}\n style={{ width: '100%' }}\n > \n \n );\n }\n\n buildFilterDropdown() {\n const { currentCategory, isFilterDropdownOpen, inputValue, filters } = this.state;\n\n const locationMenuItems = [\n ,\n ,\n ,\n ,\n \n ];\n\n const statusMenuItems = [\n ,\n ,\n ,\n ,\n \n ];\n\n return (\n \n \n \n {locationMenuItems}\n \n \n \n \n \n \n \n \n \n \n \n \n {statusMenuItems}\n \n \n \n );\n }\n\n renderToolbar() {\n const { filters } = this.state;\n return (\n \n \n } breakpoint=\"xl\">\n \n {this.buildCategoryDropdown()}\n {this.buildFilterDropdown()}\n \n \n \n \n );\n }\n\n render() {\n const { loading, rows, columns, actions, filters, scollableElement } = this.state;\n\n const filteredRows =\n filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0\n ? rows.filter(row => {\n return (\n (filters.name.length === 0 ||\n filters.name.some(name => row.cells[0].toLowerCase().includes(name.toLowerCase()))) &&\n (filters.location.length === 0 || filters.location.includes(row.cells[4])) &&\n (filters.status.length === 0 || filters.status.includes(row.cells[3]))\n );\n })\n : rows;\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: rowIndex => rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { columns, actions } = this.state;\n\n return (\n \n \n {filteredRows[index].cells[0]} \n {filteredRows[index].cells[1]} \n {filteredRows[index].cells[2]} \n {filteredRows[index].cells[3]} \n {filteredRows[index].cells[4]} \n \n \n \n \n \n );\n };\n\n return (\n \n {this.renderToolbar()}\n\n \n
\n {!loading && filteredRows.length > 0 && (\n
\n
\n \n \n
\n {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (\n \n {({ width }) => (\n \n (this.actionsVirtualBody = ref)}\n autoHeight\n className=\"pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller\"\n deferredMeasurementCache={measurementCache}\n rowHeight={measurementCache.rowHeight}\n height={height || 0}\n overscanRowCount={10}\n columnCount={6}\n rows={filteredRows}\n rowCount={filteredRows.length}\n rowRenderer={rowRenderer}\n scrollTop={scrollTop}\n width={width}\n role=\"grid\"\n />\n
\n )}\n \n )}\n \n
\n )}\n
\n
\n \n );\n }\n}","title":"Filterable with WindowScroller","lang":"js"}}>
+ console.log('clicked on Some action, on row: ', rowId)\n },\n {\n title: Another action
,\n onClick: (event, rowId, rowData, extra) => console.log('clicked on Another action, on row: ', rowId)\n },\n {\n isSeparator: true\n },\n {\n title: 'Third action',\n onClick: (event, rowId, rowData, extra) => console.log('clicked on Third action, on row: ', rowId)\n }\n ]\n };\n\n this._handleResize = debounce(this._handleResize.bind(this), 100);\n\n this.onDelete = (type = '', id = '') => {\n if (type) {\n this.setState((prevState) => {\n prevState.filters[type.toLowerCase()] = prevState.filters[type.toLowerCase()].filter((s) => s !== id);\n return {\n filters: prevState.filters\n };\n });\n } else {\n this.setState({\n filters: {\n location: [],\n name: [],\n status: []\n },\n inputValue: ''\n });\n }\n };\n\n this.onCategoryToggle = (_event, isOpen) => {\n this.setState({\n isCategoryDropdownOpen: isOpen\n });\n };\n\n this.onCategorySelect = (event) => {\n this.setState({\n currentCategory: event.target.innerText,\n isCategoryDropdownOpen: !this.state.isCategoryDropdownOpen\n });\n };\n\n this.onFilterToggle = (_event, isOpen) => {\n this.setState({\n isFilterDropdownOpen: isOpen\n });\n };\n\n this.onFilterSelect = (event) => {\n this.setState({\n isFilterDropdownOpen: !this.state.isFilterDropdownOpen\n });\n };\n\n this.onInputChange = (_event, newValue) => {\n // this.setState({ inputValue: newValue });\n if (newValue === '') {\n this.onDelete();\n this.setState({\n inputValue: newValue\n });\n } else {\n this.setState((prevState) => {\n return {\n filters: {\n ...prevState.filters,\n ['name']: [newValue]\n },\n inputValue: newValue\n };\n });\n }\n };\n\n this.onRowSelect = (event, isSelected, rowId) => {\n let rows;\n if (rowId === -1) {\n rows = this.state.rows.map((oneRow) => {\n oneRow.selected = isSelected;\n return oneRow;\n });\n } else {\n rows = [...this.state.rows];\n rows[rowId].selected = isSelected;\n }\n this.setState({\n rows\n });\n };\n\n this.onStatusSelect = (event, selection) => {\n const checked = event.target.checked;\n this.setState((prevState) => {\n const prevSelections = prevState.filters['status'];\n return {\n filters: {\n ...prevState.filters,\n status: checked ? [...prevSelections, selection] : prevSelections.filter((value) => value !== selection)\n }\n };\n });\n };\n\n this.onNameInput = (event) => {\n if (event.key && event.key !== 'Enter') {\n return;\n }\n\n const { inputValue } = this.state;\n this.setState((prevState) => {\n const prevFilters = prevState.filters['name'];\n return {\n filters: {\n ...prevState.filters,\n ['name']: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue]\n },\n inputValue: ''\n };\n });\n };\n\n this.onLocationSelect = (event, selection) => {\n this.setState((prevState) => {\n return {\n filters: {\n ...prevState.filters,\n ['location']: [selection]\n }\n };\n });\n this.onFilterSelect();\n };\n\n this._handleResize = debounce(this._handleResize.bind(this), 100);\n this._bindBodyRef = this._bindBodyRef.bind(this);\n }\n\n componentDidMount() {\n // re-render after resize\n window.addEventListener('resize', this._handleResize);\n\n setTimeout(() => {\n const scollableElement = document.getElementById('content-scrollable-1');\n this.setState({ scollableElement });\n });\n\n // re-render after resize\n window.addEventListener('resize', this._handleResize);\n }\n\n componentWillUnmount() {\n window.removeEventListener('resize', this._handleResize);\n }\n\n _handleResize() {\n this._cellMeasurementCache.clearAll();\n this._bodyRef.recomputeVirtualGridSize();\n }\n\n _bindBodyRef(ref) {\n this._bodyRef = ref;\n }\n\n buildCategoryDropdown() {\n const { isCategoryDropdownOpen, currentCategory } = this.state;\n\n return (\n \n \n {currentCategory}\n \n }\n isOpen={isCategoryDropdownOpen}\n dropdownItems={[\n Location ,\n Name ,\n Status \n ]}\n style={{ width: '100%' }}\n > \n \n );\n }\n\n buildFilterDropdown() {\n const { currentCategory, isFilterDropdownOpen, inputValue, filters } = this.state;\n\n const locationMenuItems = [\n ,\n ,\n ,\n ,\n \n ];\n\n const statusMenuItems = [\n ,\n ,\n ,\n ,\n \n ];\n\n return (\n \n \n \n {locationMenuItems}\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n {statusMenuItems}\n \n \n \n );\n }\n\n renderToolbar() {\n const { filters } = this.state;\n return (\n \n \n } breakpoint=\"xl\">\n \n {this.buildCategoryDropdown()}\n {this.buildFilterDropdown()}\n \n \n \n \n );\n }\n\n render() {\n const { loading, rows, columns, actions, filters, scollableElement } = this.state;\n\n const filteredRows =\n filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0\n ? rows.filter((row) => {\n return (\n (filters.name.length === 0 ||\n filters.name.some((name) => row.cells[0].toLowerCase().includes(name.toLowerCase()))) &&\n (filters.location.length === 0 || filters.location.includes(row.cells[4])) &&\n (filters.status.length === 0 || filters.status.includes(row.cells[3]))\n );\n })\n : rows;\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: (rowIndex) => rowIndex\n });\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { columns, actions } = this.state;\n\n return (\n \n \n {filteredRows[index].cells[0]} \n {filteredRows[index].cells[1]} \n {filteredRows[index].cells[2]} \n {filteredRows[index].cells[3]} \n {filteredRows[index].cells[4]} \n \n \n \n \n \n );\n };\n\n return (\n \n {this.renderToolbar()}\n\n \n
\n {!loading && filteredRows.length > 0 && (\n
\n
\n \n \n
\n {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (\n \n {({ width }) => (\n \n (this.actionsVirtualBody = ref)}\n autoHeight\n className=\"pf-v5-c-table pf-v5-c-virtualized pf-v5-c-window-scroller\"\n deferredMeasurementCache={measurementCache}\n rowHeight={measurementCache.rowHeight}\n height={height || 0}\n overscanRowCount={10}\n columnCount={6}\n rows={filteredRows}\n rowCount={filteredRows.length}\n rowRenderer={rowRenderer}\n scrollTop={scrollTop}\n width={width}\n role=\"grid\"\n />\n
\n )}\n \n )}\n \n
\n )}\n
\n
\n \n );\n }\n}\n","title":"Filterable with WindowScroller","lang":"js"}}>
};
diff --git a/packages/module/patternfly-docs/generated/extensions/virtual-scroll-window-scroller/react.js b/packages/module/patternfly-docs/generated/extensions/virtual-scroll-window-scroller/react.js
index d209a36..8b338e7 100644
--- a/packages/module/patternfly-docs/generated/extensions/virtual-scroll-window-scroller/react.js
+++ b/packages/module/patternfly-docs/generated/extensions/virtual-scroll-window-scroller/react.js
@@ -181,11 +181,11 @@ pageData.relativeImports = {
};
pageData.examples = {
'Window scroller': props =>
- rowIndex\n });\n }\n\n this.state = {\n scrollToIndex: -1, // can be used to programmatically set current index\n scrollableElement: null,\n columns: [\n {\n title: 'Repositories',\n props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }\n },\n {\n title: 'Branches',\n props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }\n },\n {\n title: 'Pull requests',\n props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }\n },\n {\n title: 'Workspaces',\n props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }\n },\n { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }\n ],\n rows\n };\n\n this._handleResize = debounce(this._handleResize.bind(this), 100);\n this._bindBodyRef = this._bindBodyRef.bind(this);\n }\n\n componentDidMount() {\n // re-render after resize\n window.addEventListener('resize', this._handleResize);\n\n this.setState({ scrollableElement: document.getElementById('content-scrollable-1') });\n }\n\n componentWillUnmount() {\n window.removeEventListener('resize', this._handleResize);\n }\n\n _handleResize() {\n this._cellMeasurementCache.clearAll();\n this._bodyRef.recomputeVirtualGridSize();\n }\n\n _bindBodyRef(ref) {\n this._bodyRef = ref;\n }\n\n render() {\n const { scrollToIndex, columns, rows, scrollableElement } = this.state;\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns } = this.state;\n const text = rows[index].cells[0];\n\n return (\n \n \n \n {text}\n \n \n {text}\n \n \n {text}\n \n \n {text}\n \n \n {text}\n \n \n \n );\n };\n\n return (\n \n
\n
\n \n \n {scrollableElement &&
\n {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (\n \n {({ width }) => (\n \n \n
\n )}\n \n )}\n }\n
\n
\n );\n }\n}","title":"Window scroller","lang":"js"}}>
+ rowIndex\n });\n }\n\n this.state = {\n scrollToIndex: -1, // can be used to programmatically set current index\n scrollableElement: null,\n columns: [\n {\n title: 'Repositories',\n props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }\n },\n {\n title: 'Branches',\n props: { className: 'pf-m-6-col-on-sm pf-m-4-col-on-md pf-m-3-col-on-lg pf-m-2-col-on-xl' }\n },\n {\n title: 'Pull requests',\n props: { className: 'pf-m-4-col-on-md pf-m-4-col-on-lg pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-md' }\n },\n {\n title: 'Workspaces',\n props: { className: 'pf-m-2-col-on-lg pf-m-2-col-on-xl pf-m-hidden pf-m-visible-on-lg' }\n },\n { title: 'Last Commit', props: { className: 'pf-m-3-col-on-xl pf-m-hidden pf-m-visible-on-xl' } }\n ],\n rows\n };\n\n this._handleResize = debounce(this._handleResize.bind(this), 100);\n this._bindBodyRef = this._bindBodyRef.bind(this);\n }\n\n componentDidMount() {\n // re-render after resize\n window.addEventListener('resize', this._handleResize);\n\n this.setState({ scrollableElement: document.getElementById('content-scrollable-1') });\n }\n\n componentWillUnmount() {\n window.removeEventListener('resize', this._handleResize);\n }\n\n _handleResize() {\n this._cellMeasurementCache.clearAll();\n this._bodyRef.recomputeVirtualGridSize();\n }\n\n _bindBodyRef(ref) {\n this._bodyRef = ref;\n }\n\n render() {\n const { scrollToIndex, columns, rows, scrollableElement } = this.state;\n\n const rowRenderer = ({ index, isScrolling, key, style, parent }) => {\n const { rows, columns } = this.state;\n const text = rows[index].cells[0];\n\n return (\n \n \n \n {text}\n \n \n {text}\n \n \n {text}\n \n \n {text}\n \n \n {text}\n \n \n \n );\n };\n\n return (\n \n
\n
\n \n \n {scrollableElement && (\n
\n {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (\n \n {({ width }) => (\n \n \n
\n )}\n \n )}\n \n )}\n
\n
\n );\n }\n}\n","title":"Window scroller","lang":"js"}}>
,
'Using composable table components': props =>
- {\n const [scrollableElement, setScrollableElement] = React.useState();\n React.useEffect(() => {\n const scrollableElement = document.getElementById('content-scrollable-2');\n setScrollableElement(scrollableElement);\n });\n const rows = [];\n for (let i = 0; i < 100000; i++) {\n const cells = [];\n const num = Math.floor(Math.random() * Math.floor(2)) + 1;\n for (let j = 0; j < 5; j++) {\n const cellValue = i.toString() + ' Arma virumque cano Troiae qui primus ab oris. '.repeat(num);\n cells.push(cellValue);\n }\n rows.push(cells);\n }\n const [selected, setSelected] = React.useState(rows.map(row => false));\n const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'];\n const scrollToIndex = -1; // can be used to programmatically set current index\n\n const onSelect = (event, isSelected, rowId) => {\n setSelected(selected.map((sel, index) => (index === rowId ? isSelected : sel)));\n };\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: rowIndex => rowIndex\n });\n\n const rowRenderer = ({ index: rowIndex, isScrolling, key, style, parent }) => {\n const text = rows[rowIndex][0];\n\n return (\n \n \n \n {columns.map((col, index) => (\n {text} \n ))}\n \n \n );\n };\n\n const scrollableContainerStyle = {\n height: 500 /* important note: the scrollable container should have some sort of fixed height, or it should be wrapped in container that is smaller than ReactVirtualized__VirtualGrid container and has overflow visible if using the Window Scroller. See WindowScroller.example.css */,\n overflowX: 'auto',\n overflowY: 'scroll',\n scrollBehavior: 'smooth',\n WebkitOverflowScrolling: 'touch',\n position: 'relative'\n };\n\n return (\n \n
\n Virtualized table with composable table components \n \n \n \n {columns.map((col, index) => (\n {col} \n ))}\n \n \n
\n
\n {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (\n \n {({ width }) => (\n \n \n
\n )}\n \n )}\n \n
\n );\n};","title":"Using composable table components","lang":"js"}}>
+ {\n const [scrollableElement, setScrollableElement] = React.useState();\n React.useEffect(() => {\n const scrollableElement = document.getElementById('content-scrollable-2');\n setScrollableElement(scrollableElement);\n });\n const rows = [];\n for (let i = 0; i < 100000; i++) {\n const cells = [];\n const num = Math.floor(Math.random() * Math.floor(2)) + 1;\n for (let j = 0; j < 5; j++) {\n const cellValue = i.toString() + ' Arma virumque cano Troiae qui primus ab oris. '.repeat(num);\n cells.push(cellValue);\n }\n rows.push(cells);\n }\n const [selected, setSelected] = React.useState(rows.map((row) => false));\n const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'];\n const scrollToIndex = -1; // can be used to programmatically set current index\n\n const onSelect = (event, isSelected, rowId) => {\n setSelected(selected.map((sel, index) => (index === rowId ? isSelected : sel)));\n };\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: (rowIndex) => rowIndex\n });\n\n const rowRenderer = ({ index: rowIndex, isScrolling, key, style, parent }) => {\n const text = rows[rowIndex][0];\n\n return (\n \n \n \n {columns.map((col, index) => (\n {text} \n ))}\n \n \n );\n };\n\n const scrollableContainerStyle = {\n height: 500 /* important note: the scrollable container should have some sort of fixed height, or it should be wrapped in container that is smaller than ReactVirtualized__VirtualGrid container and has overflow visible if using the Window Scroller. See WindowScroller.example.css */,\n overflowX: 'auto',\n overflowY: 'scroll',\n scrollBehavior: 'smooth',\n WebkitOverflowScrolling: 'touch',\n position: 'relative'\n };\n\n return (\n \n
\n Virtualized table with composable table components \n \n \n \n {columns.map((col, index) => (\n {col} \n ))}\n \n \n
\n
\n {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (\n \n {({ width }) => (\n \n \n
\n )}\n \n )}\n \n
\n );\n};\n","title":"Using composable table components","lang":"js"}}>
};
diff --git a/packages/module/release.config.js b/packages/module/release.config.js
index 1fcafbb..0c2fbff 100644
--- a/packages/module/release.config.js
+++ b/packages/module/release.config.js
@@ -6,7 +6,16 @@ module.exports = {
preset: 'angular'
},
plugins: [
- '@semantic-release/commit-analyzer',
+ [
+ '@semantic-release/commit-analyzer',
+ {
+ preset: 'angular',
+ releaseRules: [
+ { type: 'chore', scope: 'deps', release: 'patch' },
+ { type: 'chore', scope: 'ci-release', release: 'patch' }
+ ]
+ }
+ ],
'@semantic-release/release-notes-generator',
'@semantic-release/github',
'@semantic-release/npm'
diff --git a/yarn.lock b/yarn.lock
index 15545b1..225788b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2081,10 +2081,10 @@
acorn-static-class-features "^1.0.0"
astring "^1.7.5"
-"@patternfly/documentation-framework@^2.0.0-alpha.69":
- version "2.0.0-alpha.69"
- resolved "https://registry.yarnpkg.com/@patternfly/documentation-framework/-/documentation-framework-2.0.0-alpha.69.tgz#be46270b8fa8724457fd5efe8cb689f34939c59e"
- integrity sha512-hwmPsjlnINnYoXbsm7cw+B2l0R2ONIwLBEArDpXia93UjD7Iztnq+fGoKu/RU3wBOhplD+mOO5SeEFG48Z8X+g==
+"@patternfly/documentation-framework@^5.0.15":
+ version "5.0.15"
+ resolved "https://registry.yarnpkg.com/@patternfly/documentation-framework/-/documentation-framework-5.0.15.tgz#56e6608de10a95a92787686e5db1eb3ff7c09b89"
+ integrity sha512-3r9fqPeAKY8GeJM6m7VPyPsiggxhyDbbWTo2/4T4NoNisVPpFXi0AzUaTpvJU2KcBx5pSot1mb84V3f8DHzWXg==
dependencies:
"@babel/core" "7.18.2"
"@babel/plugin-proposal-class-properties" "7.17.12"
@@ -2170,60 +2170,60 @@
puppeteer-cluster "^0.23.0"
xmldoc "^1.1.2"
-"@patternfly/patternfly@^5.0.0-prerelease.10":
- version "5.0.0-prerelease.10"
- resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-5.0.0-prerelease.10.tgz#b5993d04be650f5103edb431436695c7c23c03cc"
- integrity sha512-jVAqCl2UHiB4246fzLBNTcrY6iwllZ5V14KV4kN4/PIPGb3lgM7jpFxWSISsT6yApsVQ8mQngiWhwfqpDZpVaw==
+"@patternfly/patternfly@^5.0.0-prerelease.16":
+ version "5.0.0-prerelease.16"
+ resolved "https://registry.yarnpkg.com/@patternfly/patternfly/-/patternfly-5.0.0-prerelease.16.tgz#63064971002b9b9b2f161bd8c2907cab55bbbebc"
+ integrity sha512-h5vNqRD9UMJO7ABX7vA3YJNMcsJwA+YUOuiEwcvnokHjv0g6kYNlTvYqIRJDab9wKpscbGmRSYyDgHYZvGO6hg==
-"@patternfly/react-code-editor@^5.0.0-prerelease.13":
- version "5.0.0-prerelease.13"
- resolved "https://registry.yarnpkg.com/@patternfly/react-code-editor/-/react-code-editor-5.0.0-prerelease.13.tgz#72db62e6edd6e15014564e9064ff65e1c5fa638f"
- integrity sha512-gbD7R+0oOxG/Af3FW5VILTUnTgSI+9XR2XO0x4RTUPCD4C0fvbU6VyBymdCJo7ukmqIVwJt8KsElL1pT/sClEg==
+"@patternfly/react-code-editor@^5.0.0-prerelease.26":
+ version "5.0.0-prerelease.26"
+ resolved "https://registry.yarnpkg.com/@patternfly/react-code-editor/-/react-code-editor-5.0.0-prerelease.26.tgz#1cb4a73feaec6bf2b3b05697e230d47ab14f896e"
+ integrity sha512-Ml8wvkmdRUUZgfQP5TIyeN87DtW7jhLjuDnAYs9fDY/TGvyf+UjIJ3Bd+QqhVQCfbtZTvoXvy7woiTPMcF4DHg==
dependencies:
- "@patternfly/react-core" "^5.0.0-prerelease.13"
- "@patternfly/react-icons" "^5.0.0-prerelease.7"
- "@patternfly/react-styles" "^5.0.0-prerelease.5"
+ "@patternfly/react-core" "^5.0.0-prerelease.26"
+ "@patternfly/react-icons" "^5.0.0-prerelease.9"
+ "@patternfly/react-styles" "^5.0.0-prerelease.7"
react-dropzone "14.2.3"
tslib "^2.5.0"
-"@patternfly/react-core@^5.0.0-prerelease.13":
- version "5.0.0-prerelease.13"
- resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-5.0.0-prerelease.13.tgz#878b9d27b639bb870e79c6c388fcf617e3793641"
- integrity sha512-NhZmaagCjEDhfOI0VPG5oeYeQkzUAUZB/gDg8VSDvs+2jnwrqRH/Wk+Sot9ix9GaU7Xad3jdkEY9HAqKomVsnw==
+"@patternfly/react-core@^5.0.0-prerelease.26":
+ version "5.0.0-prerelease.26"
+ resolved "https://registry.yarnpkg.com/@patternfly/react-core/-/react-core-5.0.0-prerelease.26.tgz#208c3c95ba033c8a1ce11175216f4ad46d609eb5"
+ integrity sha512-oV8Ev5R0ktMI7gJFZ7XUSsGhjk88l1XSgNvleMwBqclYaqp+PgHsMCvJc9nhOUPmNjtPVZ5KjOgKAIs2UZrTog==
dependencies:
- "@patternfly/react-icons" "^5.0.0-prerelease.7"
- "@patternfly/react-styles" "^5.0.0-prerelease.5"
- "@patternfly/react-tokens" "^5.0.0-prerelease.5"
+ "@patternfly/react-icons" "^5.0.0-prerelease.9"
+ "@patternfly/react-styles" "^5.0.0-prerelease.7"
+ "@patternfly/react-tokens" "^5.0.0-prerelease.9"
focus-trap "7.4.3"
react-dropzone "^14.2.3"
tslib "^2.5.0"
-"@patternfly/react-icons@^ 5.0.0-prerelease.7", "@patternfly/react-icons@^5.0.0-prerelease.7":
+"@patternfly/react-icons@^5.0.0-prerelease.9":
+ version "5.0.0-prerelease.9"
+ resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-5.0.0-prerelease.9.tgz#0ccdffde7ad7c9712bae158d6c09326831a3ebc0"
+ integrity sha512-/+g45rml+GpI9UvIlacPLeZvOf5wRzR3DKaFQz4l1UBq+vgfsZbPG4xZb2zYkuVICQvkkdjCP27gSRYwsIX0gw==
+
+"@patternfly/react-styles@^5.0.0-prerelease.7":
version "5.0.0-prerelease.7"
- resolved "https://registry.yarnpkg.com/@patternfly/react-icons/-/react-icons-5.0.0-prerelease.7.tgz#f98dd22e363324a6174e70fcaaaa8f834316f2fc"
- integrity sha512-nR4kv5pKN9csN6uZ/0HZg55ZM9S2ngpCL8s/pAc1PtwdOpvm5fUEb3HnCKJmf2pjRxPr7FKIF3aAAAGRd1ORIA==
-
-"@patternfly/react-styles@^5.0.0-prerelease.5":
- version "5.0.0-prerelease.5"
- resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-5.0.0-prerelease.5.tgz#cdd20855331fd1fde670c764cb3ec7faf3be93e4"
- integrity sha512-1hMBVpW/LXuDOyfGhI7hhaBnUJn18wh2+Zbfj3Xh4J3jhI1iVr9XIudu/rjwheCKLcELid41IYWF43Pg6FmNSQ==
-
-"@patternfly/react-table@^5.0.0-prerelease.13":
- version "5.0.0-prerelease.13"
- resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-5.0.0-prerelease.13.tgz#01b99204b397f2f1e0da8a02290c050d228cf37a"
- integrity sha512-523SidmitAkXHugkE8NAfcv9+uRUASAYhvNxbZ2wnB8EuO1ICD6GmPHVrbtZJl/43A7cvBJuWQ/EIVTa8bkRxQ==
- dependencies:
- "@patternfly/react-core" "^5.0.0-prerelease.13"
- "@patternfly/react-icons" "^5.0.0-prerelease.7"
- "@patternfly/react-styles" "^5.0.0-prerelease.5"
- "@patternfly/react-tokens" "^5.0.0-prerelease.5"
+ resolved "https://registry.yarnpkg.com/@patternfly/react-styles/-/react-styles-5.0.0-prerelease.7.tgz#c7d4337c6ae5482b69ad9eb9d93bcc9509644874"
+ integrity sha512-TKajHVnE7z9DH+pkSNQwz0olktaAjnOtWQP4V4mzx9RmRBIcU1x+hAIQzi2zdDV1MooWry8Gsk6dRC7UI6gJVQ==
+
+"@patternfly/react-table@^5.0.0-prerelease.26":
+ version "5.0.0-prerelease.26"
+ resolved "https://registry.yarnpkg.com/@patternfly/react-table/-/react-table-5.0.0-prerelease.26.tgz#e4dcf3ba26b7e127df922d1609bf857de6fdb6ee"
+ integrity sha512-Qv0DfAobNJsgCS63+BtX9BU3tRd51DQ4UmzsG9GIpsSCXbxnQXl7hafDwnknq63K87VyzPy5D1pO0LqtaYl6rg==
+ dependencies:
+ "@patternfly/react-core" "^5.0.0-prerelease.26"
+ "@patternfly/react-icons" "^5.0.0-prerelease.9"
+ "@patternfly/react-styles" "^5.0.0-prerelease.7"
+ "@patternfly/react-tokens" "^5.0.0-prerelease.9"
lodash "^4.17.19"
tslib "^2.5.0"
-"@patternfly/react-tokens@^5.0.0-prerelease.5":
- version "5.0.0-prerelease.5"
- resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-5.0.0-prerelease.5.tgz#5b44d55439f020878dde68d13941f2560beabe25"
- integrity sha512-36iQ7CuYh3OKf+TEZNSfU5Mpgi+aLJoFFA2V4YDaOL8+7RC8sFqh/dW3S9ThkjQrtc0fF7OK7mrPJzK+nQB9UQ==
+"@patternfly/react-tokens@^5.0.0-prerelease.9":
+ version "5.0.0-prerelease.9"
+ resolved "https://registry.yarnpkg.com/@patternfly/react-tokens/-/react-tokens-5.0.0-prerelease.9.tgz#c972df627db20f6d5ed20754b16723d6a1b76d3e"
+ integrity sha512-x3kJolPS95LJSiS2n3T9KL6MNjtuM9qKKzbqK1nkiftAytubcoQ9O7ikEjDYiILHpupo5lG5H9Cr50kAwu1rsA==
"@pkgjs/parseargs@^0.11.0":
version "0.11.0"
@@ -9384,13 +9384,6 @@ react-monaco-editor@^0.51.0:
dependencies:
prop-types "^15.8.1"
-react-monaco-editor@^0.52.0:
- version "0.52.0"
- resolved "https://registry.yarnpkg.com/react-monaco-editor/-/react-monaco-editor-0.52.0.tgz#69a7c450a22830064d2fc1b446674b1b7da0f540"
- integrity sha512-jhQSekf2JABbcpN45gKZlWfTS0QcBOZAbAWKGyfqy/KEcMXTwJpCOYGcn2Ur11SUUxWJUzhKjE2fx9BGBc5S8g==
- dependencies:
- prop-types "^15.8.1"
-
react-ssr-prepass@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/react-ssr-prepass/-/react-ssr-prepass-1.5.0.tgz#bc4ca7fcb52365e6aea11cc254a3d1bdcbd030c5"