diff --git a/package-lock.json b/package-lock.json index f0480dd..bcc2a82 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,13 +36,13 @@ "eslint": "^8.57.0", "eslint-config-prettier": "9.1.0", "eslint-config-standard-with-typescript": "^23.0.0", - "eslint-plugin-import": "^2.29.1", + "eslint-plugin-import": "^2.31.0", "eslint-plugin-markdown": "^1.0.2", "eslint-plugin-n": "^15.7.0", "eslint-plugin-prettier": "^5.1.3", "eslint-plugin-promise": "^6.2.0", "eslint-plugin-react": "^7.34.3", - "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-hooks": "^5.0.0", "fs-extra": "^11.2.0", "glob": "^10.4.1", "identity-obj-proxy": "^3.0.0", @@ -4300,7 +4300,8 @@ "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-6.0.0-prerelease.15.tgz", "integrity": "sha512-7/tRjaWBMX9bvMhIexdAONgxKiVbOCuFffLEKq+p+Q4t8Qq8fqGM7eAznzOx3YbLKIzqVtmbRrgTAIkpsSe1aw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@patternfly/patternfly-a11y": { "version": "4.3.1", @@ -4564,14 +4565,13 @@ } }, "node_modules/@patternfly/react-component-groups": { - "version": "6.0.0-prerelease.7", - "resolved": "https://registry.npmjs.org/@patternfly/react-component-groups/-/react-component-groups-6.0.0-prerelease.7.tgz", - "integrity": "sha512-+JYabo0L8ASWSiYHA6mzDrAdPABdcmaEk2Ts06PuGb/nrZdOLvdAHRFpzcnjFva9+tkeItHvAXAT7bK5WVAEEg==", - "license": "MIT", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-component-groups/-/react-component-groups-6.0.0.tgz", + "integrity": "sha512-q4dQj4b/Yf8fW3ZXWZhXrX8xE73JpRAFF5wydDx6OZe3oZXucUgldghupavbyhY/oYM2V89/P67w24poH6iOqA==", "dependencies": { - "@patternfly/react-core": "^6.0.0-prerelease.21", - "@patternfly/react-icons": "^6.0.0-prerelease.7", - "@patternfly/react-table": "^6.0.0-prerelease.22", + "@patternfly/react-core": "^6.0.0", + "@patternfly/react-icons": "^6.0.0", + "@patternfly/react-table": "^6.0.0", "clsx": "^2.1.1", "react-jss": "^10.10.0" }, @@ -4580,11 +4580,47 @@ "react-dom": "^17 || ^18" } }, + "node_modules/@patternfly/react-component-groups/node_modules/@patternfly/react-core": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-6.0.0.tgz", + "integrity": "sha512-UKFj9+YzBY+FfEDsLONgOM4N0e8SPV/27/UzNRiJ0gpgqbw2POuXwLpjGSRTTIUuCaLaGGM5PeTSj7mMB73ykw==", + "dependencies": { + "@patternfly/react-icons": "^6.0.0", + "@patternfly/react-styles": "^6.0.0", + "@patternfly/react-tokens": "^6.0.0", + "focus-trap": "7.6.0", + "react-dropzone": "^14.2.3", + "tslib": "^2.7.0" + }, + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" + } + }, + "node_modules/@patternfly/react-component-groups/node_modules/@patternfly/react-table": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-6.0.0.tgz", + "integrity": "sha512-LvWMzjcQZHdFUpK8fjj5EAFrNxqB8/MFd7gUUZu7AgYt6rmS2im4xk6yb7h0K7cAhY085oPeRF9lkYSCgzlRDg==", + "dependencies": { + "@patternfly/react-core": "^6.0.0", + "@patternfly/react-icons": "^6.0.0", + "@patternfly/react-styles": "^6.0.0", + "@patternfly/react-tokens": "^6.0.0", + "lodash": "^4.17.21", + "tslib": "^2.7.0" + }, + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" + } + }, "node_modules/@patternfly/react-core": { "version": "6.0.0-prerelease.21", "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-6.0.0-prerelease.21.tgz", "integrity": "sha512-EaGcKUPeeR253vY4N0Ahm9oOVtltoI6JycfclwmzjevOzpYvuLj1jcsVwL8wqgWYQVpURoBm1yxIdx34fo5UHA==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@patternfly/react-icons": "^6.0.0-prerelease.7", "@patternfly/react-styles": "^6.0.0-prerelease.6", @@ -4603,26 +4639,26 @@ "link": true }, "node_modules/@patternfly/react-icons": { - "version": "6.0.0-prerelease.7", - "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-6.0.0-prerelease.7.tgz", - "integrity": "sha512-DQmecVgXRIiD3ww4KUuJ0qO76TmYMDEJ1ao1+DYuTSP+FzeJLJKuE9QxvL8qn3anyKtuORBuHdTIjM52mVq5Vg==", - "license": "MIT", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-6.0.0.tgz", + "integrity": "sha512-ZFrsBVKrAp0DZrPOss98OA/EVUL4F0frXhR1uBId9+3ZrRArdKTgYgmQUCeSzMbxnSlxpmm3a2L05XQ36VUVbw==", "peerDependencies": { "react": "^17 || ^18", "react-dom": "^17 || ^18" } }, "node_modules/@patternfly/react-styles": { - "version": "6.0.0-prerelease.6", - "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-6.0.0-prerelease.6.tgz", - "integrity": "sha512-tI28gIJFgbgVQs7Xj705csfl6T92dr5Bh7ynR5gN4+QdTWCUWmSctp46G2ZewXdrIN+C+2zUPE86o77aFp4CWw==", - "license": "MIT" + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-6.0.0.tgz", + "integrity": "sha512-fJFMB89sTRGlZTzTLmpRmthgOXqcN078scHMFJ3ttfi2D2btnem5oZrxmQ/gPZkZOxR+9MqwKDB6l3F5x1SqLQ==" }, "node_modules/@patternfly/react-table": { "version": "6.0.0-prerelease.22", "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-6.0.0-prerelease.22.tgz", "integrity": "sha512-vGDWr14YATIY9RnxaOpyjkPlw4aKBM7dhHJRPXY0cwCFehSGwwzQpialZyi+92I2WfBF1Cb75doDAtxTSi8UZQ==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@patternfly/react-core": "^6.0.0-prerelease.21", "@patternfly/react-icons": "^6.0.0-prerelease.7", @@ -4637,10 +4673,9 @@ } }, "node_modules/@patternfly/react-tokens": { - "version": "6.0.0-prerelease.7", - "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-6.0.0-prerelease.7.tgz", - "integrity": "sha512-SLgVwbIgVx26LCjaXkpNlPIZYqWpHJkw3QX/n3URLmIcRlCw536/rKO1PzXaeuCCqhuSq66J6R125zM2eJjM6A==", - "license": "MIT" + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-6.0.0.tgz", + "integrity": "sha512-xd0ynDkiIW2rp8jz4TNvR4Dyaw9kSMkZdsuYcLlFXCVmvX//Mnl4rhBnid/2j2TaqK0NbkyTTPnPY/BU7SfLVQ==" }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -11871,16 +11906,15 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", - "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0.tgz", + "integrity": "sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10" }, "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "node_modules/eslint-plugin-react/node_modules/doctrine": { @@ -28038,16 +28072,16 @@ "version": "1.0.0-prerelease.0", "license": "MIT", "dependencies": { - "@patternfly/react-component-groups": "6.0.0-prerelease.7", - "@patternfly/react-core": "6.0.0-prerelease.21", - "@patternfly/react-icons": "6.0.0-prerelease.7", - "@patternfly/react-table": "6.0.0-prerelease.22", + "@patternfly/react-component-groups": "6.0.0", + "@patternfly/react-core": "6.0.0", + "@patternfly/react-icons": "6.0.0", + "@patternfly/react-table": "6.0.0", "clsx": "^2.1.1", "react-jss": "^10.10.0" }, "devDependencies": { "@patternfly/documentation-framework": "6.0.0-alpha.117", - "@patternfly/patternfly": "6.0.0-prerelease.15", + "@patternfly/patternfly": "6.0.0", "@patternfly/patternfly-a11y": "^4.3.1", "@types/react": "^18.3.1", "@types/react-dom": "^18.3.0", @@ -28063,6 +28097,46 @@ "react": "^17 || ^18", "react-dom": "^17 || ^18" } + }, + "packages/module/node_modules/@patternfly/patternfly": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-6.0.0.tgz", + "integrity": "sha512-Mn92Tt/4okSj1COGCJrgUgh390OOaFCWf0tL0WmigDNUecSHNn1D6Vhpd1hxHQBXvre9eWorzxV2b9yhSEl79Q==", + "dev": true + }, + "packages/module/node_modules/@patternfly/react-core": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-6.0.0.tgz", + "integrity": "sha512-UKFj9+YzBY+FfEDsLONgOM4N0e8SPV/27/UzNRiJ0gpgqbw2POuXwLpjGSRTTIUuCaLaGGM5PeTSj7mMB73ykw==", + "dependencies": { + "@patternfly/react-icons": "^6.0.0", + "@patternfly/react-styles": "^6.0.0", + "@patternfly/react-tokens": "^6.0.0", + "focus-trap": "7.6.0", + "react-dropzone": "^14.2.3", + "tslib": "^2.7.0" + }, + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" + } + }, + "packages/module/node_modules/@patternfly/react-table": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-6.0.0.tgz", + "integrity": "sha512-LvWMzjcQZHdFUpK8fjj5EAFrNxqB8/MFd7gUUZu7AgYt6rmS2im4xk6yb7h0K7cAhY085oPeRF9lkYSCgzlRDg==", + "dependencies": { + "@patternfly/react-core": "^6.0.0", + "@patternfly/react-icons": "^6.0.0", + "@patternfly/react-styles": "^6.0.0", + "@patternfly/react-tokens": "^6.0.0", + "lodash": "^4.17.21", + "tslib": "^2.7.0" + }, + "peerDependencies": { + "react": "^17 || ^18", + "react-dom": "^17 || ^18" + } } } } diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/AbstractLayoutExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/AbstractLayoutExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/AbstractLayoutExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/AbstractLayoutExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableEmptyExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/DataViewTableEmptyExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableEmptyExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/DataViewTableEmptyExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableErrorExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/DataViewTableErrorExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableErrorExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/DataViewTableErrorExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/DataViewTableExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/DataViewTableExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableLoadingExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/DataViewTableLoadingExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableLoadingExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/DataViewTableLoadingExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableTreeExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/DataViewTableTreeExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewTableTreeExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/DataViewTableTreeExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarActionsExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/DataViewToolbarActionsExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarActionsExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/DataViewToolbarActionsExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/DataViewToolbarExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Components/DataViewToolbarExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/DataViewToolbarExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/EventsContext/EventsExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/EventsExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/EventsContext/EventsExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/EventsExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/PaginationExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/PaginationExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/PaginationExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/PaginationExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/PredefinedLayoutExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/PredefinedLayoutExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/PredefinedLayoutExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/PredefinedLayoutExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/SelectionExample.tsx b/packages/module/patternfly-docs/content/extensions/data-view/SelectionExample.tsx similarity index 100% rename from packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/SelectionExample.tsx rename to packages/module/patternfly-docs/content/extensions/data-view/SelectionExample.tsx diff --git a/packages/module/patternfly-docs/content/extensions/data-view/about-data-view.md b/packages/module/patternfly-docs/content/extensions/data-view/about-data-view.md index 0fd1b95..0c1013d 100644 --- a/packages/module/patternfly-docs/content/extensions/data-view/about-data-view.md +++ b/packages/module/patternfly-docs/content/extensions/data-view/about-data-view.md @@ -1,14 +1,200 @@ --- section: extensions subsection: Data view -id: About data view -sortValue: 1 ---- +id: Data view +propComponents: ['DataViewToolbar', 'DataViewTableBasic', 'DataViewTableTree','DataView', 'DataViewState'] +sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md +--- +import { useState, useEffect, useRef, useMemo } from 'react'; +import { BrowserRouter, useSearchParams } from 'react-router-dom'; +import { Button, Drawer, DrawerContent, DrawerContentBody, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter } from '@patternfly/react-core'; +import { CubesIcon, FolderIcon, FolderOpenIcon, LeafIcon, ExclamationCircleIcon } from '@patternfly/react-icons'; +import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table'; +import { BulkSelect, BulkSelectValue, ErrorState, ResponsiveAction, ResponsiveActions, SkeletonTableHead, SkeletonTableBody } from '@patternfly/react-component-groups'; +import { useDataViewPagination, useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks'; +import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar'; +import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable'; +import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynamic/DataView'; +import { useDataViewEventsContext, DataViewEventsContext, DataViewEventsProvider, EventTypes } from '@patternfly/react-data-view/dist/dynamic/DataViewEventsContext'; + +**Note:** Data view lives in its own package [`@patternfly/react-data-view`](https://www.npmjs.com/package/@patternfly/react-data-view) + +If you notice a bug, or if you have a suggestion for improving the data view extension or its documentation, file an issue in [the react-data-view repository](https://github.com/patternfly/react-data-view/issues)! Before creating a new issue, make sure there is not already a pre-existing issue. + +## Basic data view + +The **data view** extension helps you display datasets in organized layouts. + +A basic data view places data in a [PatternFly table](/components/table), with [toolbars](/components/toolbar) above and below the table that support interactions like selection and pagination. + +These table and toolbar components are combined and passed as `children` to the `` component. + +```js file="./PredefinedLayoutExample.tsx" + +``` + +## Basic toolbar + +A basic data view toolbar typically supports bulk selection, to allow users to select data, and pagination, to help users navigate large datasets that span multiple pages. + +To enable selection and pagination, pass `bulkSelect` or `pagination` to the [toolbar item component](/components/toolbar#toolbar-items). + +You can further customize these actions by referring to the additional documentation: +- [Selection](#selection) +- [Pagination](#pagination) + +```js file="./DataViewToolbarExample.tsx" + +``` + +### Toolbar actions + +To support additional user needs, you can pass relevant actions to the toolbar via `actions`. Add standard PatternFly actions (like buttons) or choose a predefined [responsive action component group](/component-groups/controls/responsive-actions). + +```js file="./DataViewToolbarActionsExample.tsx" + +``` + +### Selection + +To allow users to select data records inside the data view, add support for [bulk selection](/patterns/bulk-selection). + +To enable selection, pass a predefined [bulk select component group](/component-groups/controls/bulk-select) to the `bulkSelect` property of the ``. + +This example includes the following: + +- The `useDataViewSelection` hook, which manages the selection state of the data view. + +- Initial values, before selection: + - An optional `initialSelected` array of a record's identifiers, selected by default + - A `matchOption` function that checks if a record is selected + - When no `matchOption` is passed, the `Array.prototype.includes()` operation is performed on the `selected` array. + +- Return values, after selection: + - A `selected` array of currently selected records + - An `isSelected` function that returns the selection state of a record + - An `onSelect` callback that modifies the selection state + - This callback accepts the `isSelecting` flag, which dictates when records are selected or deselected, and `items`, which contains affected records. + +```js file="./SelectionExample.tsx" + +``` + +### Pagination + +To help users navigate data records that span multiple pages, enable [pagination](/components/pagination/design-guidelines). + +To support pagination, pass a [pagination component](/components/pagination) to `pagination` in the ``. For testing purposes, you can also pass a custom `ouiaId`. + +This example includes the following: + +- The `useDataViewPagination` hook, which manages the pagination state of the data view. + +- Initial values: + - A `perPage` initial value + - An optional `page` initial value + - An optional `searchParams` object + - An optional `setSearchParams` function + + - While the hook works seamlessly with the React Router library, you do not need to use it to take advantage of URL persistence. The `searchParams` and `setSearchParams` props can be managed using native browser APIs (`URLSearchParams` and `window.history.pushState`) or any other routing library of your choice. If you don't pass these two props, the pagination state will be stored internally without the URL usage. + + You can also pass custom `pageParam` or `perPageParam` names, renaming the pagination parameters in the URL. + + The retrieved values are named to match the PatternFly [pagination](/components/pagination) component props, so you can easily spread them to the component. + +- Return values: + - A current `page` number + - An `onSetPage` function to modify the current page + - An items `perPage` value + - An `onPerPageSelect` function to modify per page value + +```js file="./PaginationExample.tsx" + +``` + +## Basic table + +A basic data view table supports various customizations of the table head and body. + +The `` component accepts the following props: + +- `columns`: Defines the columns of the table. Each item in the array can be a `ReactNode` (for simple heads) or an object with the following properties: + - `cell` (`ReactNode`): Content to display in the column head + - Optional `props` (`ThProps`) to pass to the `` component, such as `width`, `sort`, and other table head cell properties. + +- `rows`: Defines the rows in the table. Each item in the array can be either an array of `DataViewTd` (for simple rows) or an object with the following properties: + - `row` (`DataViewTd[]`): Content for each cell in the row + - Optional `id` (`string`) for the row, which can be used to match items in selection. + - Optional `props` (`TrProps`) to pass to the `` component, such as `isHoverable`, `isRowSelected`, and other table row properties. + +- Optional `ouiaId` + +- Optional `props` (`TableProps`) that are passed down to the `` component, except for `onSelect`, which is managed internally. + +```js file="./DataViewTableExample.tsx" + +``` + +### Tree table + +Instead of a basic table, your data view can use a tree table variant, with expandable rows and custom icons for leaf and parent nodes. + +To enable a tree table, pass the `isTreeTable` flag to the `` component. + +Pass `collapsedIcon`, `expandedIcon`, and `leafIcon` to ``, to align a row's icon to its state. + +Tree table rows have to be defined as an object with the following keys: + - A `row` (`DataViewTd[]`) that defines the content for each cell in the row + - An `id` (`string`) for the row, which is used to identify selected items and expand the row + - Optional `children` (`DataViewTrTree[]`) that define the children rows + +You can disable row selection by passing the `isSelectDisabled` function to the wrapping ``. + +```js file="./DataViewTableTreeExample.tsx" + +``` + +### Empty state + +When there is no data to render in the data view, you can instead display a customizable empty state. + +You can customize your `` component within `empty` by using [PatternFly empty state options](/components/empty-state). To load the empty state, pass the `empty` key to `headStates` or `bodyStates`. + +```js file="./DataViewTableEmptyExample.tsx" + +``` + +### Error state + +When there is a data connection or retrieval error, you can display an error state. + +You can customize your `` component within `error` by using the [error state component group](/component-groups/error-communication/error-state). To load the empty state, pass the `error` key to `headStates` or `bodyStates`. + +The error state will be displayed when the data view `state` value is `error`. + +```js file="./DataViewTableErrorExample.tsx" + +``` + +### Loading state + +To indicate that data is still loading, you can display a [skeleton table](/component-groups/status-and-state-indicators/skeleton-table). + +You can pass `` to the `loading` key of `headStates` and `` to the `loading` key of `bodyStates`. + +The loading state will be displayed when the data view `state` value is `loading`. + +```js file="./DataViewTableLoadingExample.tsx" + +``` + +### Events context hook + +You can use the `DataViewEventsContext` hook to manage a shared state and handle events from outside of the data view component. The `DataViewEventsProvider` hook wraps components that need access to the shared context. -Data view lives in its own package [`@patternfly/react-data-view`](https://www.npmjs.com/package/@patternfly/react-data-view) +This example illustrates how to set up a layout that listens for row click events and displays detailed information about the selected row in a [drawer component](/components/drawer). -# Data view -The data view extension contains implementation of the data view component allowing to display record data in a configured layout. +```js file="./EventsExample.tsx" -If you notice a bug or have a suggestion for the data view, feel free to file an issue in our [GitHub repository](https://github.com/patternfly/react-data-view/issues)! Please make sure to check if there is already a pre-existing issue before creating a new issue. +``` \ No newline at end of file diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md b/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md deleted file mode 100644 index a7efd40..0000000 --- a/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -# Sidenav top-level section -# should be the same for all markdown files -section: extensions -subsection: Data view -# Sidenav secondary level section -# should be the same for all markdown files -id: Components -# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility) -source: react -# If you use typescript, the name of the interface to display props for -# These are found through the sourceProps function provided in patternfly-docs.source.js -sortValue: 4 -propComponents: ['DataViewToolbar', 'DataViewTableBasic', 'DataViewTableTree'] -sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md ---- -import { Button, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter } from '@patternfly/react-core'; -import { CubesIcon, FolderIcon, FolderOpenIcon, LeafIcon, ExclamationCircleIcon } from '@patternfly/react-icons'; -import { BulkSelect, ErrorState, ResponsiveAction, ResponsiveActions, SkeletonTableHead, SkeletonTableBody } from '@patternfly/react-component-groups'; -import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar'; -import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable'; -import { useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks'; -import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynamic/DataView'; - -## Data view toolbar - -The **data view toolbar** component renders a default opinionated data view toolbar above or below the data section. - -Data view toolbar can contain a `pagination`, `bulkSelect`, `actions` or other children content passed. The preffered way of passing children toolbar items is using the [toolbar item](/components/toolbar#toolbar-items) component. - -### Basic toolbar example - -```js file="./DataViewToolbarExample.tsx" - -``` - -# Toolbar actions -Data view toolbar can display actions using the `actions` property accepting a React node. You can make use of a predefined [responsive actions](/extensions/component-groups/responsive-actions) component from the [component groups](/extensions/component-groups/about-component-groups) extension. - -### Actions configuration - -### Actions example - -```js file="./DataViewToolbarActionsExample.tsx" - -``` - -## Data view table - -The **data view table** component renders your columns and rows definition into a [table](/components/table) component. - -### Rows and columns customization - -This example shows possible formats of `rows` and `columns` passed to the `DataViewTable` which allow you various customizations of the table head and body. - -```js file="./DataViewTableExample.tsx" - -``` - -The `DataViewTable` component accepts the following props: - -- `columns` defining the column heads of the table. Each item in the array can be a `ReactNode` (for simple heads) or an object with the following properties: - - `cell` (`ReactNode`) content to display in the column head. - - optional `props` (`ThProps`) to pass to the `` component, such as `isHoverable`, `isRowSelected`, and other table row properties. - -- optional `ouiaId` - -- optional `props` (`TableProps`) that are passed down to the `
` component, such as `width`, `sort`, and other table head cell properties. - -- `rows` defining the rows to be displayed in the table. Each item in the array can be either an array of `DataViewTd` (for simple rows) or an object with the following properties: - - `row` (`DataViewTd[]`) defining the content for each cell in the row. - - optional `id` (`string`) for the row (can be used to match items in selection). - - optional `props` (`TrProps`) to pass to the `
` component, except for `onSelect`, which is managed internally. - -### Tree table example -This example shows the tree table variant with expandable rows, custom icons for leaf and parent nodes. Tree table is turned on by passing `isTreeTable` flag to the `DataViewTable` component. You can pass `collapsedIcon`, `expandedIcon` or `leafIcon` to be displayen rows with given status. The tree table rows have to be defined in a format of object with following keys: - - `row` (`DataViewTd[]`) defining the content for each cell in the row. - - `id` (`string`) for the row (used to match items in selection end expand the rows). - - optional `children` (`DataViewTrTree[]`) defining the children rows. - -It is also possible to disable row selection using the `isSelectDisabled` function passed to the wrapping data view component. - -```js file="./DataViewTableTreeExample.tsx" - -``` - -### Empty state example -The data view table supports displaying a custom empty state. You can pass it using the the `headStates` and `bodyStates` properties and their `empty` key. It will be automatically displayed in case there are no rows to be rendered. - -```js file="./DataViewTableEmptyExample.tsx" - -``` - -### Error state example -The data view table also supports displaying an error state. You can pass it using the the `headStates` and `bodyStates` properties and their `error` key. It will be displayed in case the data view recieves its `state` property set to `error`. - -```js file="./DataViewTableErrorExample.tsx" - -``` - -### Loading state example -The data view table also supports displaying a custom loading state. You can pass it using the `headStates` and `bodyStates` properties and their `loading` key. Your state will be displayed in case the data view recieves its `state` property set to `loading`. - -```js file="./DataViewTableLoadingExample.tsx" - -``` diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/EventsContext/EventsContext.md b/packages/module/patternfly-docs/content/extensions/data-view/examples/EventsContext/EventsContext.md deleted file mode 100644 index 2c0cfe4..0000000 --- a/packages/module/patternfly-docs/content/extensions/data-view/examples/EventsContext/EventsContext.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -# Sidenav top-level section -# should be the same for all markdown files -section: extensions -subsection: Data view -# Sidenav secondary level section -# should be the same for all markdown files -id: Events context -# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility) -source: react -# If you use typescript, the name of the interface to display props for -# These are found through the sourceProps function provided in patternfly-docs.source.js -sortValue: 3 -sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/EventsContext/EventsContext.md ---- -import { useState, useEffect, useRef, useMemo } from 'react'; -import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table'; -import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView'; -import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable'; -import { useDataViewEventsContext, DataViewEventsContext, DataViewEventsProvider, EventTypes } from '@patternfly/react-data-view/dist/dynamic/DataViewEventsContext'; -import { Drawer, DrawerContent, DrawerContentBody } from '@patternfly/react-core'; - -The **data view events context** provides a way of listening to the data view events from the outside of the component. - -### Row click subscription example -The following example demonstrates how to use the `DataViewEventsContext` to manage shared state and handle events. The `DataViewEventsProvider` is used to wrap components that need access to the shared context. This example illustrates how to set up a layout that listens for data view row click events and displays detailed information about the selected row in a [drawer component](/components/drawer). - - -```js file="./EventsExample.tsx" - -``` - diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md b/packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md deleted file mode 100644 index c788309..0000000 --- a/packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -# Sidenav top-level section -# should be the same for all markdown files -section: extensions -subsection: Data view -# Sidenav secondary level section -# should be the same for all markdown files -id: Functionality -# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility) -source: react -# If you use typescript, the name of the interface to display props for -# These are found through the sourceProps function provided in patternfly-docs.source.js -sortValue: 3 -sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Functionality/Functionality.md ---- -import { useMemo } from 'react'; -import { BrowserRouter, useSearchParams } from 'react-router-dom'; -import { useDataViewPagination, useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks'; -import { DataView } from '@patternfly/react-data-view/dist/dynamic/DataView'; -import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect'; -import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar'; -import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable'; - - -This is a list of functionality you can use to manage data displayed in the **data view**. - -# Pagination -Allows to display data records on multiple pages and display the pagination state. - -### Toolbar usage -Data view toolbar can display a pagination using the `pagination` property accepting a React node. You can also pass a custom `ouiaId` for testing purposes. - -### Pagination state - -The `useDataViewPagination` hook manages the pagination state of the data view. - -**Initial values:** -- `perPage` initial value -- optional `page` initial value -- optional `searchParams` object -- optional `setSearchParams` function - -While the hook works seamlessly with React Router library, you do not need to use it to take advantage of URL persistence. The `searchParams` and `setSearchParams` props can be managed using native browser APIs (`URLSearchParams` and `window.history.pushState`) or any other routing library of your choice. If you don't pass these two props, the pagination state will be stored internally without the URL usage. - -You can also pass custom `pageParam` or `perPageParam` names, renaming the pagination parameters in the URL. - -The retrieved values are named to match the PatternFly [pagination](/components/pagination) component props, so you can easily spread them to the component. - -**Return values:** -- current `page` number -- `onSetPage` to modify current page -- items `perPage` value -- `onPerPageSelect` to modify per page value - -### Pagination example -```js file="./PaginationExample.tsx" - -``` - -# Selection -Allows to select data records inside the data view and show the selection state. - -### Toolbar usage -Data view toolbar can display a bulk selection component using the `bulkSelect` property accepting a React node. You can make use of a predefined [bulk select](/extensions/component-groups/bulk-select) component from the [component groups](/extensions/component-groups/about-component-groups) extension. - -### Selection state - -The `useDataViewSelection` hook manages the selection state of the data view. - -**Initial values:** -- optional `initialSelected` array of record's identifiers selected by default -- `matchOption` function to check if given record is selected - -*When no `matchOption` is passed, the `Array.prototype.includes()` operation is performed on the `selected` array.* - -**Return values:** -- `selected` array of currently selected records -- `isSelected` function returning the selection state for given record -- `onSelect` callback to modify the selection state and accepting `isSelecting` flag indicating if records are changing to selected or deselected and `items` containing affected records - -### Selection example - -```js file="./SelectionExample.tsx" - -``` diff --git a/packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/Layout.md b/packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/Layout.md deleted file mode 100644 index 13c892d..0000000 --- a/packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/Layout.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -# Sidenav top-level section -# should be the same for all markdown files -section: extensions -subsection: Data view -# Sidenav secondary level section -# should be the same for all markdown files -id: Layout -# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility) -source: react -# If you use typescript, the name of the interface to display props for -# These are found through the sourceProps function provided in patternfly-docs.source.js -sortValue: 2 -propComponents: ['DataView', 'DataViewState'] -sourceLink: https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Layout/Layout.md ---- -import { useMemo } from 'react'; -import { useDataViewPagination, useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks'; -import { BulkSelect, BulkSelectValue } from '@patternfly/react-component-groups/dist/dynamic/BulkSelect'; -import DataView from '@patternfly/react-data-view/dist/dynamic/DataView'; -import DataViewToolbar from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar'; -import DataViewTable from '@patternfly/react-data-view/dist/dynamic/DataViewTable'; - -The **data view** component renders record data in a configured layout. - -### Layout example - -Data view is expected to consist of header, data part and footer stacked below each other and passed as `children`. - -```js file="./AbstractLayoutExample.tsx" - -``` - -### Predefined layout components - -You can make use of the predefined layout components to display a default header and footer. See [data view toolbar](/extensions/data-view/components#dataviewtoolbar) for more information - -```js file="./PredefinedLayoutExample.tsx" - -``` diff --git a/packages/module/patternfly-docs/generated/extensions/data-view/about-data-view/extensions.js b/packages/module/patternfly-docs/generated/extensions/data-view/about-data-view/extensions.js index 66137eb..873e16c 100644 --- a/packages/module/patternfly-docs/generated/extensions/data-view/about-data-view/extensions.js +++ b/packages/module/patternfly-docs/generated/extensions/data-view/about-data-view/extensions.js @@ -1,6 +1,16 @@ import React from 'react'; import { AutoLinkHeader, Example, Link as PatternflyThemeLink } from '@patternfly/documentation-framework/components'; - +import { useState, useEffect, useRef, useMemo } from 'react'; +import { BrowserRouter, useSearchParams } from 'react-router-dom'; +import { Button, Drawer, DrawerContent, DrawerContentBody, EmptyState, EmptyStateActions, EmptyStateBody, EmptyStateFooter } from '@patternfly/react-core'; +import { CubesIcon, FolderIcon, FolderOpenIcon, LeafIcon, ExclamationCircleIcon } from '@patternfly/react-icons'; +import { Table, Tbody, Th, Thead, Tr, Td } from '@patternfly/react-table'; +import { BulkSelect, BulkSelectValue, ErrorState, ResponsiveAction, ResponsiveActions, SkeletonTableHead, SkeletonTableBody } from '@patternfly/react-component-groups'; +import { useDataViewPagination, useDataViewSelection } from '@patternfly/react-data-view/dist/dynamic/Hooks'; +import { DataViewToolbar } from '@patternfly/react-data-view/dist/dynamic/DataViewToolbar'; +import { DataViewTable } from '@patternfly/react-data-view/dist/dynamic/DataViewTable'; +import { DataView, DataViewState } from '@patternfly/react-data-view/dist/dynamic/DataView'; +import { useDataViewEventsContext, DataViewEventsContext, DataViewEventsProvider, EventTypes } from '@patternfly/react-data-view/dist/dynamic/DataViewEventsContext'; const pageData = { "id": "About data view", "section": "extensions", @@ -13,37 +23,976 @@ const pageData = { "source": "extensions", "tabName": null, "slug": "/extensions/data-view/about-data-view/extensions", - "sourceLink": "https://github.com/patternfly/patternfly-org/blob/main/packages/module/patternfly-docs/content/extensions/data-view/about-data-view.md", + "sourceLink": "https://github.com/patternfly/react-data-view/blob/main/packages/module/patternfly-docs/content/extensions/data-view/examples/Components/Components.md", "relPath": "packages/module/patternfly-docs/content/extensions/data-view/about-data-view.md", - "sortValue": 1 + "propComponents": [ + { + "name": "DataViewToolbar", + "description": "", + "props": [ + { + "name": "actions", + "type": "React.ReactNode", + "description": "React component to display actions" + }, + { + "name": "bulkSelect", + "type": "React.ReactNode", + "description": "React component to display bulk select" + }, + { + "name": "className", + "type": "string", + "description": "Toolbar className" + }, + { + "name": "ouiaId", + "type": "string", + "description": "Custom OUIA ID", + "defaultValue": "'DataViewToolbar'" + }, + { + "name": "pagination", + "type": "React.ReactNode", + "description": "React component to display pagination" + } + ] + }, + { + "name": "DataViewTableBasic", + "description": "", + "props": [ + { + "name": "bodyStates", + "type": "Partial>", + "description": "Table body states to be displayed when active" + }, + { + "name": "columns", + "type": "DataViewTh[]", + "description": "Columns definition", + "required": true + }, + { + "name": "headStates", + "type": "Partial>", + "description": "Table head states to be displayed when active" + }, + { + "name": "ouiaId", + "type": "string", + "description": "Custom OUIA ID", + "defaultValue": "'DataViewTableBasic'" + }, + { + "name": "rows", + "type": "DataViewTr[]", + "description": "Current page rows", + "required": true + } + ] + }, + { + "name": "DataViewTableTree", + "description": "", + "props": [ + { + "name": "bodyStates", + "type": "Partial>", + "description": "Table body states to be displayed when active" + }, + { + "name": "collapsedIcon", + "type": "React.ReactNode", + "description": "Optional icon for the collapsed parent rows", + "defaultValue": "null" + }, + { + "name": "columns", + "type": "DataViewTh[]", + "description": "Columns definition", + "required": true + }, + { + "name": "expandedIcon", + "type": "React.ReactNode", + "description": "Optional icon for the expanded parent rows", + "defaultValue": "null" + }, + { + "name": "headStates", + "type": "Partial>", + "description": "Table head states to be displayed when active" + }, + { + "name": "leafIcon", + "type": "React.ReactNode", + "description": "Optional icon for the leaf rows", + "defaultValue": "null" + }, + { + "name": "ouiaId", + "type": "string", + "description": "Custom OUIA ID", + "defaultValue": "'DataViewTableTree'" + }, + { + "name": "rows", + "type": "DataViewTrTree[]", + "description": "Current page rows", + "required": true + } + ] + }, + { + "name": "DataView", + "description": "", + "props": [ + { + "name": "activeState", + "type": "DataViewState | string", + "description": "Currently active state" + }, + { + "name": "children", + "type": "React.ReactNode", + "description": "Content rendered inside the data view", + "required": true + }, + { + "name": "ouiaId", + "type": "string", + "description": "Custom OUIA ID" + }, + { + "name": "selection", + "type": "DataViewSelection", + "description": "Selection context configuration" + } + ] + }, + { + "name": "DataViewState", + "description": "", + "props": [] + } + ], + "sortValue": 1, + "examples": [ + "Basic toolbar example", + "Actions example", + "Rows and columns customization", + "Tree table example", + "Empty state example", + "Error state example", + "Loading state example", + "Layout example", + "Predefined layout components", + "Row click subscription example", + "Pagination example", + "Selection example" + ] +}; +pageData.liveContext = { + useState, + useEffect, + useRef, + useMemo, + BrowserRouter, + useSearchParams, + Button, + Drawer, + DrawerContent, + DrawerContentBody, + EmptyState, + EmptyStateActions, + EmptyStateBody, + EmptyStateFooter, + CubesIcon, + FolderIcon, + FolderOpenIcon, + LeafIcon, + ExclamationCircleIcon, + Table, + Tbody, + Th, + Thead, + Tr, + Td, + BulkSelect, + BulkSelectValue, + ErrorState, + ResponsiveAction, + ResponsiveActions, + SkeletonTableHead, + SkeletonTableBody, + useDataViewPagination, + useDataViewSelection, + DataViewToolbar, + DataViewTable, + DataView, + DataViewState, + useDataViewEventsContext, + DataViewEventsContext, + DataViewEventsProvider, + EventTypes }; pageData.examples = { - + 'Basic toolbar example': props => + (\n null}\n /> \n }\n pagination={\n \n }\n />\n)\n","title":"Basic toolbar example","lang":"js","className":""}}> + + , + 'Actions example': props => + (\n null}\n /> \n }\n actions={\n \n Persistent\n Pinned\n Action three\n Action four\n \n }\n pagination={\n \n }\n />\n)\n","title":"Actions example","lang":"js","className":""}}> + + , + 'Rows and columns customization': props => + console.log('clicked on Some action') // eslint-disable-line no-console\n },\n {\n title:
Another action
,\n onClick: () => console.log('clicked on Another action') // eslint-disable-line no-console\n },\n {\n isSeparator: true\n },\n {\n title: 'Third action',\n onClick: () => console.log('clicked on Third action') // eslint-disable-line no-console\n }\n];\n\n// you can also pass props to Tr by returning { row: DataViewTd[], props: TrProps } }\nconst rows: DataViewTr[] = repositories.map(({ id, name, branches, prs, workspaces, lastCommit }) => [\n { id, cell: workspaces, props: { favorites: { isFavorited: true } } },\n { cell: },\n branches,\n prs,\n workspaces,\n lastCommit,\n { cell: , props: { isActionCell: true } },\n]);\n\nconst columns: DataViewTh[] = [\n null,\n 'Repositories', \n { cell: <>Branches }, \n 'Pull requests', \n { cell: 'Workspaces', props: { info: { tooltip: 'More information' } } }, \n { cell: 'Last commit', props: { sort: { sortBy: {}, columnIndex: 4 } } },\n];\n\nconst ouiaId = 'TableExample';\n\nexport const BasicExample: React.FunctionComponent = () => (\n \n);\n","title":"Rows and columns customization","lang":"js","className":""}}> + +

+ {`This example shows possible formats of `} + + + {`rows`} + + {` and `} + + + {`columns`} + + {` passed to the `} + + + {`DataViewTable`} + + {` which allow you various customizations of the table head and body.`} +

+
, + 'Tree table example': props => + repositories.map((repo) => ({\n row: [ repo.name, repo.branches, repo.prs, repo.workspaces, repo.lastCommit ],\n id: repo.name, // unique ID for each row\n ...(repo.children\n ? { \n children: buildRows(repo.children) // build rows for children\n } \n : {})\n}));\n\nconst rows: DataViewTrTree[] = buildRows(repositories);\n\nconst columns: DataViewTh[] = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];\n\nconst ouiaId = 'TreeTableExample';\n\nexport const BasicExample: React.FunctionComponent = () => {\n const selection = useDataViewSelection({ matchOption: (a, b) => a.id === b.id });\n\n return (\n \n }\n expandedIcon={}\n collapsedIcon={} \n />\n \n );\n}\n","title":"Tree table example","lang":"js","className":""}}> + +

+ {`This example shows the tree table variant with expandable rows, custom icons for leaf and parent nodes. Tree table is turned on by passing `} + + + {`isTreeTable`} + + {` flag to the `} + + + {`DataViewTable`} + + {` component. You can pass `} + + + {`collapsedIcon`} + + {`, `} + + + {`expandedIcon`} + + {` or `} + + + {`leafIcon`} + + {` to be displayen rows with given status. The tree table rows have to be defined in a format of object with following keys:`} +

+ +
    + + + +
  • + + + {`row`} + + {` (`} + + + {`DataViewTd[]`} + + {`) defining the content for each cell in the row.`} +
  • + + + +
  • + + + {`id`} + + {` (`} + + + {`string`} + + {`) for the row (used to match items in selection end expand the rows).`} +
  • + + + +
  • + {`optional `} + + + {`children`} + + {` (`} + + + {`DataViewTrTree[]`} + + {`) defining the children rows.`} +
  • + + +
+ +

+ {`It is also possible to disable row selection using the `} + + + {`isSelectDisabled`} + + {` function passed to the wrapping data view component.`} +

+
, + 'Empty state example': props => + Object.values(repository));\n\nconst columns: DataViewTh[] = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];\n\nconst ouiaId = 'TableExample';\n\nconst empty = (\n
\n \n \n \n \n);\n\nexport const BasicExample: React.FunctionComponent = () => (\n \n \n \n);\n","title":"Empty state example","lang":"js","className":""}}> + +

+ {`The data view table supports displaying a custom empty state. You can pass it using the the `} + + + {`headStates`} + + {` and `} + + + {`bodyStates`} + + {` properties and their `} + + + {`empty`} + + {` key. It will be automatically displayed in case there are no rows to be rendered.`} +

+ , + 'Error state example': props => + Object.values(repository));\n\nconst columns: DataViewTh[] = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];\n\nconst ouiaId = 'TableErrorExample';\n\nconst error = (\n \n \n \n \n \n);\n\nexport const BasicExample: React.FunctionComponent = () => (\n \n \n \n);\n","title":"Error state example","lang":"js","className":""}}> + +

+ {`The data view table also supports displaying an error state. You can pass it using the the `} + + + {`headStates`} + + {` and `} + + + {`bodyStates`} + + {` properties and their `} + + + {`error`} + + {` key. It will be displayed in case the data view recieves its `} + + + {`state`} + + {` property set to `} + + + {`error`} + + {`.`} +

+ , + 'Loading state example': props => + \nconst bodyLoading = ;\n\nexport const BasicExample: React.FunctionComponent = () => (\n \n \n \n);\n","title":"Loading state example","lang":"js","className":""}}> + +

+ {`The data view table also supports displaying a custom loading state. You can pass it using the `} + + + {`headStates`} + + {` and `} + + + {`bodyStates`} + + {` properties and their `} + + + {`loading`} + + {` key. Your state will be displayed in case the data view recieves its `} + + + {`state`} + + {` property set to `} + + + {`loading`} + + {`.`} +

+
, + 'Layout example': props => + (\n \n
Header
\n
Data representation
\n
Footer
\n
\n)\n","title":"Layout example","lang":"js","className":""}}> + +

+ {`Data view is expected to consist of header, data part and footer stacked below each other and passed as `} + + + {`children`} + + {`.`} +

+
, + 'Predefined layout components': props => + Object.values(item));\n\nconst columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];\n\nconst ouiaId = 'LayoutExample';\n\nexport const BasicExample: React.FunctionComponent = () => { \n const pagination = useDataViewPagination({ perPage: 5 });\n const { page, perPage } = pagination;\n const selection = useDataViewSelection({ matchOption: (a, b) => a[0] === b[0] });\n const { selected, onSelect, isSelected } = selection;\n\n const pageRows = useMemo(() => rows.slice((page - 1) * perPage, ((page - 1) * perPage) + perPage), [ page, perPage ]);\n\n const handleBulkSelect = (value: BulkSelectValue) => {\n value === BulkSelectValue.none && onSelect(false);\n value === BulkSelectValue.all && onSelect(true, rows);\n value === BulkSelectValue.nonePage && onSelect(false, pageRows);\n value === BulkSelectValue.page && onSelect(true, pageRows);\n };\n\n return (\n \n isSelected(item))}\n pagePartiallySelected={pageRows.some(item => isSelected(item)) && !pageRows.every(item => isSelected(item))}\n onSelect={handleBulkSelect}\n />\n } \n pagination={\n \n } \n />\n \n \n } \n />\n \n );\n}","title":"Predefined layout components","lang":"js","className":""}}> + +

+ {`You can make use of the predefined layout components to display a default header and footer. See `} + + + {`data view toolbar`} + + {` for more information`} +

+
, + 'Row click subscription example': props => + >;\n}\n\nconst RepositoryDetail: React.FunctionComponent = ({ selectedRepo, setSelectedRepo }) => {\n const context = useDataViewEventsContext();\n\n useEffect(() => {\n const unsubscribe = context.subscribe(EventTypes.rowClick, (repo: Repository) => {\n setSelectedRepo(repo);\n });\n\n return () => unsubscribe();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n \n \n \n Detail of {selectedRepo?.name}\n \n Branches: {selectedRepo?.branches}\n Pull requests: {selectedRepo?.prs}\n Workspaces: {selectedRepo?.workspaces}\n Last commit: {selectedRepo?.lastCommit}\n \n setSelectedRepo(undefined)} data-ouia-component-id=\"detail-drawer-close-btn\"/>\n \n \n \n );\n};\n\ninterface RepositoriesTableProps {\n selectedRepo?: Repository;\n}\n\nconst RepositoriesTable: React.FunctionComponent = ({ selectedRepo = undefined }) => {\n const { trigger } = useDataViewEventsContext();\n const rows = useMemo(() => {\n const handleRowClick = (repo: Repository | undefined) => {\n trigger(EventTypes.rowClick, repo);\n };\n\n return repositories.map(repo => ({\n row: Object.values(repo),\n props: {\n isClickable: true,\n onRowClick: () => handleRowClick(selectedRepo?.name === repo.name ? undefined : repo),\n isRowSelected: selectedRepo?.name === repo.name\n }\n }));\n }, [ selectedRepo?.name, trigger ]);\n\n return (\n \n \n \n );\n};\n\nexport const BasicExample: React.FunctionComponent = () => {\n const [ selectedRepo, setSelectedRepo ] = useState();\n const drawerRef = useRef(null);\n\n return (\n \n drawerRef.current?.focus()} data-ouia-component-id=\"detail-drawer\" >\n }\n >\n \n \n \n \n \n \n );\n};\n","title":"Row click subscription example","lang":"js","className":""}}> + +

+ {`The following example demonstrates how to use the `} + + + {`DataViewEventsContext`} + + {` to manage shared state and handle events. The `} + + + {`DataViewEventsProvider`} + + {` is used to wrap components that need access to the shared context. This example illustrates how to set up a layout that listens for data view row click events and displays detailed information about the selected row in a `} + + + {`drawer component`} + + {`.`} +

+
, + 'Pagination example': props => + Object.values(item));\n\nconst columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];\n\nconst ouiaId = 'LayoutExample';\n\nconst MyTable: React.FunctionComponent = () => {\n const [ searchParams, setSearchParams ] = useSearchParams()\n const pagination = useDataViewPagination({ perPage: 5, searchParams, setSearchParams });\n const { page, perPage } = pagination;\n\n const pageRows = useMemo(() => rows.slice((page - 1) * perPage, ((page - 1) * perPage) + perPage), [ page, perPage ]);\n return (\n \n } />\n \n } />\n \n );\n};\n\nexport const BasicExample: React.FunctionComponent = () => (\n \n \n \n);\n","title":"Pagination example","lang":"js","className":""}}> + + , + 'Selection example': props => + Object.values(item));\n\nconst columns = [ 'Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last commit' ];\n\nconst ouiaId = 'LayoutExample';\n\nexport const BasicExample: React.FunctionComponent = () => { \n const selection = useDataViewSelection({ matchOption: (a, b) => a[0] === b[0] });\n const { selected, onSelect } = selection;\n\n const handleBulkSelect = (value: BulkSelectValue) => {\n value === BulkSelectValue.none && onSelect(false);\n value === BulkSelectValue.all && onSelect(true, rows);\n };\n\n return (\n \n \n } \n />\n \n \n );\n}","title":"Selection example","lang":"js","className":""}}> + + }; const Component = () => ( -

- {`Data view lives in its own package `} +

+ + {`Note:`} + + {` Data view lives in its own package `} {`@patternfly/react-data-view`}

- - {`Data view`} - -

- {`The data view extension contains implementation of the data view component allowing to display record data in a configured layout.`} +

+ {`The `} + + {`data view`} + + {` extension contains enables you to display record data in a configured layout.`}

-

- {`If you notice a bug or have a suggestion for the data view, feel free to file an issue in our `} +

+ {`If you notice a bug in the data view extension, or if have a suggestion for improving the extension or documentation, file an issue in `} - {`GitHub repository`} + {`the react-data-view repository`} {`! Please make sure to check if there is already a pre-existing issue before creating a new issue.`}

+ + {`Data view toolbar`} + +

+ {`The `} + + {`data view toolbar`} + + {` component renders a default opinionated data view toolbar above or below the data section.`} +

+

+ {`Data view toolbar can contain a `} + + {`pagination`} + + {`, `} + + {`bulkSelect`} + + {`, `} + + {`actions`} + + {` or other children content passed. The preffered way of passing children toolbar items is using the `} + + {`toolbar item`} + + {` component.`} +

+ {React.createElement(pageData.examples["Basic toolbar example"])} + + {`Toolbar actions`} + +

+ {`Data view toolbar can display actions using the `} + + {`actions`} + + {` property accepting a React node. You can make use of a predefined `} + + {`responsive actions`} + + {` component from the `} + + {`component groups`} + + {` extension.`} +

+ + {`Actions configuration`} + + {React.createElement(pageData.examples["Actions example"])} + + {`Data view table`} + +

+ {`The `} + + {`data view table`} + + {` component renders your columns and rows definition into a `} + + {`table`} + + {` component.`} +

+ {React.createElement(pageData.examples["Rows and columns customization"])} +

+ {`The `} + + {`DataViewTable`} + + {` component accepts the following props:`} +

+
    +
  • +

    + + {`columns`} + + {` defining the column heads of the table. Each item in the array can be a `} + + {`ReactNode`} + + {` (for simple heads) or an object with the following properties:`} +

    +
      +
    • + + {`cell`} + + {` (`} + + {`ReactNode`} + + {`) content to display in the column head.`} +
    • +
    • + {`optional `} + + {`props`} + + {` (`} + + {`ThProps`} + + {`) to pass to the `} + + {`
`} + + {` component, such as `} + + {`isHoverable`} + + {`, `} + + {`isRowSelected`} + + {`, and other table row properties.`} + + + +
  • +

    + {`optional `} + + {`ouiaId`} + +

    +
  • +
  • +

    + {`optional `} + + {`props`} + + {` (`} + + {`TableProps`} + + {`) that are passed down to the `} + + {`

  • \n \n There are no matching data to be displayed.\n \n \n \n \n \n \n \n \n \n \n
    \n \n
    `} + + {` component, such as `} + + {`width`} + + {`, `} + + {`sort`} + + {`, and other table head cell properties.`} + + + +
  • +

    + + {`rows`} + + {` defining the rows to be displayed in the table. Each item in the array can be either an array of `} + + {`DataViewTd`} + + {` (for simple rows) or an object with the following properties:`} +

    +
      +
    • + + {`row`} + + {` (`} + + {`DataViewTd[]`} + + {`) defining the content for each cell in the row.`} +
    • +
    • + {`optional `} + + {`id`} + + {` (`} + + {`string`} + + {`) for the row (can be used to match items in selection).`} +
    • +
    • + {`optional `} + + {`props`} + + {` (`} + + {`TrProps`} + + {`) to pass to the `} + + {`
  • `} + + {` component, except for `} + + {`onSelect`} + + {`, which is managed internally.`} +

    + + + {React.createElement(pageData.examples["Tree table example"])} + {React.createElement(pageData.examples["Empty state example"])} + {React.createElement(pageData.examples["Error state example"])} + {React.createElement(pageData.examples["Loading state example"])} + {React.createElement(pageData.examples["Layout example"])} + {React.createElement(pageData.examples["Predefined layout components"])} +

    + {`The `} + + {`data view events context`} + + {` provides a way of listening to the data view events from the outside of the component.`} +

    + {React.createElement(pageData.examples["Row click subscription example"])} + + {`Pagination`} + +

    + {`Allows to display data records on multiple pages and display the pagination state.`} +

    + + {`Toolbar usage`} + +

    + {`Data view toolbar can display a pagination using the `} + + {`pagination`} + + {` property accepting a React node. You can also pass a custom `} + + {`ouiaId`} + + {` for testing purposes.`} +

    + + {`Pagination state`} + +

    + {`The `} + + {`useDataViewPagination`} + + {` hook manages the pagination state of the data view.`} +

    +

    + + {`Initial values:`} + +

    +
      +
    • + + {`perPage`} + + {` initial value`} +
    • +
    • + {`optional `} + + {`page`} + + {` initial value`} +
    • +
    • + {`optional `} + + {`searchParams`} + + {` object`} +
    • +
    • + {`optional `} + + {`setSearchParams`} + + {` function`} +
    • +
    +

    + {`While the hook works seamlessly with React Router library, you do not need to use it to take advantage of URL persistence. The `} + + {`searchParams`} + + {` and `} + + {`setSearchParams`} + + {` props can be managed using native browser APIs (`} + + {`URLSearchParams`} + + {` and `} + + {`window.history.pushState`} + + {`) or any other routing library of your choice. If you don't pass these two props, the pagination state will be stored internally without the URL usage.`} +

    +

    + {`You can also pass custom `} + + {`pageParam`} + + {` or `} + + {`perPageParam`} + + {` names, renaming the pagination parameters in the URL.`} +

    +

    + {`The retrieved values are named to match the PatternFly `} + + {`pagination`} + + {` component props, so you can easily spread them to the component.`} +

    +

    + + {`Return values:`} + +

    +
      +
    • + {`current `} + + {`page`} + + {` number`} +
    • +
    • + + {`onSetPage`} + + {` to modify current page`} +
    • +
    • + {`items `} + + {`perPage`} + + {` value`} +
    • +
    • + + {`onPerPageSelect`} + + {` to modify per page value`} +
    • +
    + {React.createElement(pageData.examples["Pagination example"])} + + {`Selection`} + +

    + {`Allows to select data records inside the data view and show the selection state.`} +

    + + {`Toolbar usage`} + +

    + {`Data view toolbar can display a bulk selection component using the `} + + {`bulkSelect`} + + {` property accepting a React node. You can make use of a predefined `} + + {`bulk select`} + + {` component from the `} + + {`component groups`} + + {` extension.`} +

    + + {`Selection state`} + +

    + {`The `} + + {`useDataViewSelection`} + + {` hook manages the selection state of the data view.`} +

    +

    + + {`Initial values:`} + +

    +
      +
    • + {`optional `} + + {`initialSelected`} + + {` array of record's identifiers selected by default`} +
    • +
    • + + {`matchOption`} + + {` function to check if given record is selected`} +
    • +
    +

    + + {`When no `} + + {`matchOption`} + + {` is passed, the `} + + {`Array.prototype.includes()`} + + {` operation is performed on the `} + + {`selected`} + + {` array.`} + +

    +

    + + {`Return values:`} + +

    +
      +
    • + + {`selected`} + + {` array of currently selected records`} +
    • +
    • + + {`isSelected`} + + {` function returning the selection state for given record`} +
    • +
    • + + {`onSelect`} + + {` callback to modify the selection state and accepting `} + + {`isSelecting`} + + {` flag indicating if records are changing to selected or deselected and `} + + {`items`} + + {` containing affected records`} +
    • +
    + {React.createElement(pageData.examples["Selection example"])} ); Component.displayName = 'ExtensionsDataViewAboutDataViewExtensionsDocs'; diff --git a/packages/module/patternfly-docs/generated/index.js b/packages/module/patternfly-docs/generated/index.js index 851e24a..eaef037 100644 --- a/packages/module/patternfly-docs/generated/index.js +++ b/packages/module/patternfly-docs/generated/index.js @@ -2,7 +2,8 @@ module.exports = { '/extensions/data-view/about-data-view/extensions': { id: "About data view", title: "About data view", - toc: [], + toc: [{"text":"Data view toolbar"},[{"text":"Basic toolbar example"},{"text":"Actions configuration"},{"text":"Actions example"}],{"text":"Data view table"},[{"text":"Rows and columns customization"},{"text":"Tree table example"},{"text":"Empty state example"},{"text":"Error state example"},{"text":"Loading state example"},{"text":"Layout example"},{"text":"Predefined layout components"},{"text":"Row click subscription example"},{"text":"Toolbar usage"},{"text":"Pagination state"},{"text":"Pagination example"},{"text":"Toolbar usage","id":"toolbar-usage-0"},{"text":"Selection state"},{"text":"Selection example"}]], + examples: ["Basic toolbar example","Actions example","Rows and columns customization","Tree table example","Empty state example","Error state example","Loading state example","Layout example","Predefined layout components","Row click subscription example","Pagination example","Selection example"], section: "extensions", subsection: "Data view", source: "extensions", @@ -10,52 +11,15 @@ module.exports = { sortValue: 1, Component: () => import(/* webpackChunkName: "extensions/data-view/about-data-view/extensions/index" */ './extensions/data-view/about-data-view/extensions') }, - '/extensions/data-view/layout/react': { - id: "Layout", - title: "Layout", - toc: [[{"text":"Layout example"},{"text":"Predefined layout components"}]], - examples: ["Layout example","Predefined layout components"], + '/extensions/data-view/data-view/extensions': { + id: "Data view", + title: "Data view", + toc: [[{"text":"Untitled example"}],{"text":"Basic toolbar"},[{"text":"Toolbar actions"},{"text":"Selection"},{"text":"Pagination"}],{"text":"Basic table"},[{"text":"Tree table"},{"text":"Empty state"},{"text":"Error state"},{"text":"Loading state"},{"text":"Events context hook"}]], + examples: ["Untitled example","Toolbar actions","Selection","Pagination","Tree table","Empty state","Error state","Loading state","Events context hook"], section: "extensions", subsection: "Data view", - source: "react", - tabName: null, - sortValue: 2, - Component: () => import(/* webpackChunkName: "extensions/data-view/layout/react/index" */ './extensions/data-view/layout/react') - }, - '/extensions/data-view/functionality/react': { - id: "Functionality", - title: "Functionality", - toc: [[{"text":"Toolbar usage"},{"text":"Pagination state"},{"text":"Pagination example"},{"text":"Toolbar usage","id":"toolbar-usage-0"},{"text":"Selection state"},{"text":"Selection example"}]], - examples: ["Pagination example","Selection example"], - section: "extensions", - subsection: "Data view", - source: "react", - tabName: null, - sortValue: 3, - Component: () => import(/* webpackChunkName: "extensions/data-view/functionality/react/index" */ './extensions/data-view/functionality/react') - }, - '/extensions/data-view/events-context/react': { - id: "Events context", - title: "Events context", - toc: [[{"text":"Row click subscription example"}]], - examples: ["Row click subscription example"], - section: "extensions", - subsection: "Data view", - source: "react", - tabName: null, - sortValue: 3, - Component: () => import(/* webpackChunkName: "extensions/data-view/events-context/react/index" */ './extensions/data-view/events-context/react') - }, - '/extensions/data-view/components/react': { - id: "Components", - title: "Components", - toc: [{"text":"Data view toolbar"},[{"text":"Basic toolbar example"}],{"text":"Data view table"},[{"text":"Rows and columns customization"},{"text":"Tree table example"},{"text":"Empty state example"}]], - examples: ["Basic toolbar example","Rows and columns customization","Tree table example","Empty state example"], - section: "extensions", - subsection: "Data view", - source: "react", + source: "extensions", tabName: null, - sortValue: 4, - Component: () => import(/* webpackChunkName: "extensions/data-view/components/react/index" */ './extensions/data-view/components/react') + Component: () => import(/* webpackChunkName: "extensions/data-view/data-view/extensions/index" */ './extensions/data-view/data-view/extensions') } }; \ No newline at end of file