diff --git a/.eslintrc.json b/.eslintrc.json index bf7d11e..64cea08 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -94,6 +94,7 @@ "react-hooks/exhaustive-deps": "warn", "react/no-unescaped-entities": ["error", { "forbid": [">", "}"] }], "spaced-comment": "error", - "use-isnan": "error" + "use-isnan": "error", + "react/react-in-jsx-scope": "off" } } diff --git a/.github/workflows/build-lint-test.yml b/.github/workflows/build-lint-test.yml index 806c45b..ca2d66e 100644 --- a/.github/workflows/build-lint-test.yml +++ b/.github/workflows/build-lint-test.yml @@ -7,7 +7,7 @@ jobs: env: GH_PR_NUM: ${{ github.event.number }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: | if [[ ! -z "${GH_PR_NUM}" ]]; then echo "Checking out PR" @@ -17,17 +17,17 @@ jobs: - uses: actions/setup-node@v1 with: node-version: '20' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: yarn-cache name: Cache npm deps with: path: | - node_modules - **/node_modules + node_modules + **/node_modules key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }} - run: yarn install --frozen-lockfile if: steps.yarn-cache.outputs.cache-hit != 'true' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: dist name: Cache dist with: @@ -43,7 +43,7 @@ jobs: GH_PR_NUM: ${{ github.event.number }} needs: build steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: | if [[ ! -z "${GH_PR_NUM}" ]]; then echo "Checking out PR" @@ -53,17 +53,17 @@ jobs: - uses: actions/setup-node@v1 with: node-version: '20' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: yarn-cache name: Cache npm deps with: path: | - node_modules - **/node_modules + node_modules + **/node_modules key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }} - run: yarn install --frozen-lockfile if: steps.yarn-cache.outputs.cache-hit != 'true' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: lint-cache name: Load lint cache with: @@ -79,7 +79,7 @@ jobs: GH_PR_NUM: ${{ github.event.number }} needs: build steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 # Yes, we really want to checkout the PR - run: | if [[ ! -z "${GH_PR_NUM}" ]]; then @@ -90,18 +90,18 @@ jobs: - uses: actions/setup-node@v1 with: node-version: '20' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: yarn-cache name: Cache npm deps with: path: | - node_modules - **/node_modules - ~/.cache/Cypress + node_modules + **/node_modules + ~/.cache/Cypress key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }} - run: yarn install --frozen-lockfile if: steps.yarn-cache.outputs.cache-hit != 'true' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: dist name: Cache dist with: @@ -120,7 +120,7 @@ jobs: GH_PR_NUM: ${{ github.event.number }} needs: build steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 # Yes, we really want to checkout the PR - run: | if [[ ! -z "${GH_PR_NUM}" ]]; then @@ -131,18 +131,18 @@ jobs: - uses: actions/setup-node@v1 with: node-version: '20' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: yarn-cache name: Cache npm deps with: path: | - node_modules - **/node_modules - ~/.cache/Cypress + node_modules + **/node_modules + ~/.cache/Cypress key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }} - run: yarn install --frozen-lockfile if: steps.yarn-cache.outputs.cache-hit != 'true' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: dist name: Cache dist with: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d149512..7712bf4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,14 +7,14 @@ jobs: env: GH_PR_NUM: ${{ github.event.number }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - run: | if [[ ! -z "${GH_PR_NUM}" ]]; then echo "Checking out PR" git fetch origin pull/$GH_PR_NUM/head:tmp git checkout tmp fi - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: setup-cache name: Cache setup with: @@ -33,17 +33,17 @@ jobs: - uses: actions/setup-node@v1 with: node-version: '20' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: yarn-cache name: Cache npm deps with: path: | - node_modules - **/node_modules + node_modules + **/node_modules key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }} - run: yarn install --frozen-lockfile if: steps.yarn-cache.outputs.cache-hit != 'true' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: dist name: Cache dist with: diff --git a/.github/workflows/promote.yml b/.github/workflows/promote.yml index 28fa19e..54026e7 100644 --- a/.github/workflows/promote.yml +++ b/.github/workflows/promote.yml @@ -2,7 +2,7 @@ name: promote on: push: # Sequence of patterns matched against refs/tags - tags: + tags: - v6.* jobs: build-and-promote: @@ -12,7 +12,7 @@ jobs: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Build for promotion run: yarn install --frozen-lockfile && yarn build - uses: actions/setup-node@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d7fb3fa..a029caa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,22 +13,22 @@ jobs: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - uses: actions/setup-node@v1 with: node-version: '20' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: yarn-cache name: Cache npm deps with: path: | - node_modules - **/node_modules - ~/.cache/Cypress + node_modules + **/node_modules + ~/.cache/Cypress key: ${{ runner.os }}-yarn-14-${{ secrets.CACHE_VERSION }}-${{ hashFiles('yarn.lock') }} - run: yarn install --frozen-lockfile if: steps.yarn-cache.outputs.cache-hit != 'true' - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: dist name: Cache dist with: diff --git a/.gitignore b/.gitignore index e61a201..a628326 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ coverage .cache .tmp .eslintcache +generated # package managers yarn-error.log diff --git a/babel.config.js b/babel.config.js index 5aac1c4..52a9841 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,8 +1,13 @@ module.exports = { presets: [ ['@babel/preset-env', { targets: { esmodules: true } }], - '@babel/preset-react', + [ + '@babel/preset-react', + { + runtime: 'automatic' + } + ], '@babel/preset-flow', '@babel/preset-typescript' ] -}; \ No newline at end of file +}; diff --git a/packages/module/package.json b/packages/module/package.json index e57a7b9..b621c20 100644 --- a/packages/module/package.json +++ b/packages/module/package.json @@ -47,8 +47,8 @@ "tslib": "^2.5.2" }, "peerDependencies": { - "react": "^17 || ^18", - "react-dom": "^17 || ^18" + "react": "^17 || ^18 || ^19", + "react-dom": "^17 || ^18 || ^19" }, "devDependencies": { "@patternfly/documentation-framework": "^6.0.0-alpha.109", diff --git a/packages/module/patternfly-docs/content/examples/Actions.tsx b/packages/module/patternfly-docs/content/examples/Actions.tsx index fde443d..a4c7f93 100644 --- a/packages/module/patternfly-docs/content/examples/Actions.tsx +++ b/packages/module/patternfly-docs/content/examples/Actions.tsx @@ -1,5 +1,5 @@ /* eslint-disable no-console */ -import React from 'react'; +import { FunctionComponent } from 'react'; import { ActionsColumn, Caption, @@ -14,7 +14,7 @@ import { import { CellMeasurerCache, CellMeasurer } from 'react-virtualized'; import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension'; -export const ActionsExample: React.FunctionComponent = () => { +export const ActionsExample: FunctionComponent = () => { interface RowType { disableActions: boolean; id: string; diff --git a/packages/module/patternfly-docs/content/examples/Basic.tsx b/packages/module/patternfly-docs/content/examples/Basic.tsx index 5042504..758c622 100644 --- a/packages/module/patternfly-docs/content/examples/Basic.tsx +++ b/packages/module/patternfly-docs/content/examples/Basic.tsx @@ -1,9 +1,9 @@ -import React from 'react'; +import { FunctionComponent } from 'react'; import { Caption, Table, TableGridBreakpoint, Td, Th, Thead, Tr } from '@patternfly/react-table'; import { CellMeasurerCache, CellMeasurer } from 'react-virtualized'; import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension'; -export const VirtualizedExample: React.FunctionComponent = () => { +export const VirtualizedExample: FunctionComponent = () => { // this StringArray type is just needed because something in our documentation framework crashes when it encounters // a string[][] type type StringArray = string[]; diff --git a/packages/module/patternfly-docs/content/examples/FilterableWithWindowScroller.tsx b/packages/module/patternfly-docs/content/examples/FilterableWithWindowScroller.tsx index 9ae4680..a9ff4fd 100644 --- a/packages/module/patternfly-docs/content/examples/FilterableWithWindowScroller.tsx +++ b/packages/module/patternfly-docs/content/examples/FilterableWithWindowScroller.tsx @@ -1,4 +1,3 @@ -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, TableGridBreakpoint, ActionsColumn, Tbody } from '@patternfly/react-table'; @@ -25,10 +24,11 @@ import { Bullseye } from '@patternfly/react-core'; import { FilterIcon, SearchIcon } from '@patternfly/react-icons'; +import { Fragment, useEffect, useState, CSSProperties, Ref, MouseEvent as ReactMouseEvent, SyntheticEvent, KeyboardEvent as ReactKeyboardEvent } from 'react'; export const ComposableTableWindowScroller = () => { - const [scrollableElement, setScrollableElement] = React.useState(); - React.useEffect(() => { + const [scrollableElement, setScrollableElement] = useState(); + useEffect(() => { const scrollableElement = document.getElementById('content-scrollable-2') as HTMLElement; setScrollableElement(scrollableElement); }, []); @@ -86,11 +86,11 @@ export const ComposableTableWindowScroller = () => { const columns = ['Servers', 'Threads', 'Applications', 'Status', 'Location']; const scrollToIndex = -1; // can be used to programmatically set current index - const [isCategoryDropdownOpen, setIsCategoryDropdownOpen] = React.useState(false); - const [isFilterDropdownOpen, setIsFilterDropdownOpen] = React.useState(false); - const [currentCategory, setCurrentCategory] = React.useState('Name'); - const [filters, setFilters] = React.useState>({ location: [], name: [], status: [] }); - const [inputValue, setInputValue] = React.useState(''); + const [isCategoryDropdownOpen, setIsCategoryDropdownOpen] = useState(false); + const [isFilterDropdownOpen, setIsFilterDropdownOpen] = useState(false); + const [currentCategory, setCurrentCategory] = useState('Name'); + const [filters, setFilters] = useState>({ location: [], name: [], status: [] }); + const [inputValue, setInputValue] = useState(''); const onDelete = (type: string | ToolbarLabelGroup, id: string) => { if (type === 'Location') { @@ -130,7 +130,7 @@ export const ComposableTableWindowScroller = () => { setInputValue(newValue); }; - const onStatusSelect = (event: React.MouseEvent | undefined, selection: string | number | undefined) => { + const onStatusSelect = (event: ReactMouseEvent | undefined, selection: string | number | undefined) => { const checked = (event?.target as HTMLInputElement).checked; setFilters({ ...filters, @@ -139,9 +139,9 @@ export const ComposableTableWindowScroller = () => { setIsFilterDropdownOpen(false); }; - const onNameInput = (event: React.SyntheticEvent | React.KeyboardEvent) => { + const onNameInput = (event: SyntheticEvent | ReactKeyboardEvent) => { setIsCategoryDropdownOpen(false); - const pressedKey = (event as React.KeyboardEvent).key; + const pressedKey = (event as ReactKeyboardEvent).key; if (pressedKey && pressedKey !== 'Enter') { return; } @@ -155,7 +155,7 @@ export const ComposableTableWindowScroller = () => { setIsCategoryDropdownOpen(false); }; - const onLocationSelect = (_event: React.MouseEvent | undefined, selection: string | number | undefined) => { + const onLocationSelect = (_event: ReactMouseEvent | undefined, selection: string | number | undefined) => { setFilters({ ...filters, location: [`${selection}`] }); setIsFilterDropdownOpen(false); @@ -180,7 +180,7 @@ export const ComposableTableWindowScroller = () => { - + ); }; diff --git a/packages/module/patternfly-docs/content/examples/Selectable.tsx b/packages/module/patternfly-docs/content/examples/Selectable.tsx index 638be6f..afe1789 100644 --- a/packages/module/patternfly-docs/content/examples/Selectable.tsx +++ b/packages/module/patternfly-docs/content/examples/Selectable.tsx @@ -1,10 +1,10 @@ -import React from 'react'; +import { FunctionComponent, useState } 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 SelectableTableVirtualized: React.FunctionComponent = () => { +export const SelectableTableVirtualized: FunctionComponent = () => { // this StringArray type is just needed because something in our documentation framework crashes when it encounters // a string[][] type type StringArray = string[]; @@ -16,7 +16,7 @@ export const SelectableTableVirtualized: React.FunctionComponent = () => { const selectableRepos = rows; - const [selectedRepoNames, setSelectedRepoNames] = React.useState([]); + const [selectedRepoNames, setSelectedRepoNames] = useState([]); const setRepoSelected = (repo: string, isSelecting = true) => setSelectedRepoNames((prevSelected) => { @@ -31,7 +31,7 @@ export const SelectableTableVirtualized: React.FunctionComponent = () => { const areAllReposSelected = selectedRepoNames.length === selectableRepos.length; const isRepoSelected = (repo: string) => selectedRepoNames.includes(repo); - const [recentSelectedRowIndex, setRecentSelectedRowIndex] = React.useState(null); + const [recentSelectedRowIndex, setRecentSelectedRowIndex] = useState(null); const onSelectRepo = (repo: string, rowIndex: number, isSelecting: boolean) => { if (recentSelectedRowIndex !== null) { diff --git a/packages/module/patternfly-docs/content/examples/Sortable.tsx b/packages/module/patternfly-docs/content/examples/Sortable.tsx index 450b895..7ef3fa4 100644 --- a/packages/module/patternfly-docs/content/examples/Sortable.tsx +++ b/packages/module/patternfly-docs/content/examples/Sortable.tsx @@ -1,9 +1,9 @@ -import React from 'react'; +import { useState, FunctionComponent } from 'react'; import { Caption, Table, Td, Th, Thead, ThProps, Tr } from '@patternfly/react-table'; import { CellMeasurerCache, CellMeasurer } from 'react-virtualized'; import { AutoSizer, VirtualTableBody } from '@patternfly/react-virtualized-extension'; -export const SortableExample: React.FunctionComponent = () => { +export const SortableExample: FunctionComponent = () => { const rows: { id: string; cells: string[] }[] = []; for (let i = 0; i < 100; i++) { rows.push({ @@ -14,10 +14,10 @@ export const SortableExample: React.FunctionComponent = () => { const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit']; - const [activeSortIndex, setActiveSortIndex] = React.useState(-1); + const [activeSortIndex, setActiveSortIndex] = useState(-1); // Sort direction of the currently sorted column - const [activeSortDirection, setActiveSortDirection] = React.useState<'asc' | 'desc' | undefined>(); + const [activeSortDirection, setActiveSortDirection] = useState<'asc' | 'desc' | undefined>(); const getRowIndex = (str: string) => Number(str?.split('-')[1]); diff --git a/packages/module/patternfly-docs/content/examples/VirtualizedTable.md b/packages/module/patternfly-docs/content/examples/VirtualizedTable.md index 524952c..ebcb235 100644 --- a/packages/module/patternfly-docs/content/examples/VirtualizedTable.md +++ b/packages/module/patternfly-docs/content/examples/VirtualizedTable.md @@ -15,30 +15,36 @@ import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-v import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated'; import { Table, Thead, Tr, Th, Td, Caption, TableGridBreakpoint } from '@patternfly/react-table'; import './VirtualGrid.example.css'; +import { useState, useEffect, Fragment } from 'react'; ## Examples ### Basic ```js file="./Basic.tsx" + ``` ### Sortable ```js file="./Sortable.tsx" + ``` ### Selectable ```js file="./Selectable.tsx" + ``` ### Actions ```js file="./Actions.tsx" + ``` ### Filterable with WindowScroller ```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 8e47f9b..5c43e97 100644 --- a/packages/module/patternfly-docs/content/examples/WindowScroller.md +++ b/packages/module/patternfly-docs/content/examples/WindowScroller.md @@ -17,10 +17,12 @@ import { AutoSizer, VirtualTableBody, WindowScroller } from '@patternfly/react-v import { Table as TableDeprecated, TableHeader as TableHeaderDeprecated } from '@patternfly/react-table/deprecated'; import './VirtualGrid.example.css'; import './WindowScroller.example.css'; +import { useState, useEffect } from 'react'; ## Examples ### Window scroller ```js file="WindowScroller.tsx" + ``` diff --git a/packages/module/patternfly-docs/content/examples/WindowScroller.tsx b/packages/module/patternfly-docs/content/examples/WindowScroller.tsx index 363237a..213487f 100644 --- a/packages/module/patternfly-docs/content/examples/WindowScroller.tsx +++ b/packages/module/patternfly-docs/content/examples/WindowScroller.tsx @@ -1,11 +1,11 @@ -import React from 'react'; +import { useState, useEffect } 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 WindowScrollerExample = () => { - const [scrollableElement, setScrollableElement] = React.useState(); - React.useEffect(() => { + const [scrollableElement, setScrollableElement] = useState(); + useEffect(() => { const scrollableElement = document.getElementById('content-scrollable-2') as HTMLElement; setScrollableElement(scrollableElement); }, []); 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 deleted file mode 100644 index 9b06e77..0000000 --- a/packages/module/patternfly-docs/generated/extensions/virtual-scroll-table/react.js +++ /dev/null @@ -1,242 +0,0 @@ -import React from 'react'; -import { AutoLinkHeader, Example, Link as PatternflyThemeLink } from '@patternfly/documentation-framework/components'; -import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; -import FilterIcon from '@patternfly/react-icons/dist/esm/icons/filter-icon'; -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 { Table, Thead, Tr, Th, Td, Caption, TableGridBreakpoint } from '@patternfly/react-table'; -import '../../../content/examples/./VirtualGrid.example.css'; -const pageData = { - "id": "Virtual scroll table", - "section": "extensions", - "subsection": "", - "deprecated": false, - "template": false, - "beta": false, - "demo": false, - "newImplementationLink": false, - "source": "react", - "tabName": null, - "slug": "/extensions/virtual-scroll-table/react", - "sourceLink": "https://github.com/patternfly/react-virtualized-extension", - "relPath": "packages/module/patternfly-docs/content/examples/VirtualizedTable.md", - "propComponents": [ - { - "name": "VirtualTableBody", - "description": "It is inefficient to create and manage a large list of DOM elements within a scrolling container\nif only a few of those elements are visible. The primary purpose of this component is to improve\nperformance by only rendering the DOM nodes that a user is able to see based on their current\nscroll position.\n\nThis component renders a virtualized list of elements with either fixed or dynamic heights.", - "props": [ - { - "name": "aria-label", - "type": "string", - "description": "" - }, - { - "name": "autoHeight", - "type": "boolean", - "description": "Removes fixed height from the scrollingContainer so that the total height\nof rows can stretch the window. Intended for use with WindowScroller", - "defaultValue": "false" - }, - { - "name": "className", - "type": "string", - "description": "Optional CSS class name" - }, - { - "name": "columnCount", - "type": "number", - "description": "" - }, - { - "name": "columns", - "type": "any[]", - "description": "" - }, - { - "name": "estimatedRowSize", - "type": "number", - "description": "Used to estimate the total height of a List before all of its rows have actually been measured.\nThe estimated total height is adjusted as rows are rendered.", - "defaultValue": "30" - }, - { - "name": "height", - "type": "number", - "description": "Height constraint for list (determines how many actual rows are rendered)", - "required": true - }, - { - "name": "innerScrollContainerComponent", - "type": "No type info", - "defaultValue": "'tbody'" - }, - { - "name": "noRowsRenderer", - "type": "NoContentRenderer", - "description": "Optional renderer to be used in place of rows when rowCount is 0", - "defaultValue": "() => null as any" - }, - { - "name": "onRowsRendered", - "type": "(params: any) => void", - "description": "Callback invoked with information about the slice of rows that were just rendered.", - "defaultValue": "() => {}" - }, - { - "name": "onScroll", - "type": "(params: Scroll) => void", - "description": "Callback invoked whenever the scroll offset changes within the inner scrollable region.\nThis callback can be used to sync scrolling between lists, tables, or grids.", - "defaultValue": "() => {}" - }, - { - "name": "overscanIndicesGetter", - "type": "OverscanIndicesGetter", - "description": "See VirtualGrid#overscanIndicesGetter", - "defaultValue": "accessibilityOverscanIndicesGetter" - }, - { - "name": "overscanRowCount", - "type": "number", - "description": "Number of rows to render above/below the visible bounds of the list.\nThese rows can help for smoother scrolling on touch devices.", - "defaultValue": "10" - }, - { - "name": "rowCount", - "type": "number", - "description": "Number of rows in list.", - "required": true - }, - { - "name": "rowHeight", - "type": "CellSize", - "description": "Either a fixed row height (number) or a function that returns the height of a row given its index.", - "required": true - }, - { - "name": "rowRenderer", - "type": "any", - "description": "Responsible for rendering a row given an index; ({ index: number }): node", - "required": true - }, - { - "name": "rows", - "type": "any[]", - "description": "", - "required": true - }, - { - "name": "scrollContainerComponent", - "type": "No type info", - "defaultValue": "'table'" - }, - { - "name": "scrollToAlignment", - "type": "Alignment", - "description": "See VirtualGrid#scrollToAlignment", - "defaultValue": "'auto'" - }, - { - "name": "scrollToIndex", - "type": "number", - "description": "Row index to ensure visible (by forcefully scrolling if necessary)", - "defaultValue": "-1" - }, - { - "name": "scrollTop", - "type": "number", - "description": "Vertical offset." - }, - { - "name": "style", - "type": "Object", - "description": "", - "defaultValue": "{}" - }, - { - "name": "tabIndex", - "type": "number", - "description": "Tab index for focus" - }, - { - "name": "width", - "type": "number", - "description": "Width of list", - "required": true - } - ] - } - ], - "examples": [ - "Basic", - "Sortable", - "Selectable", - "Actions", - "Filterable with WindowScroller" - ] -}; -pageData.liveContext = { - SearchIcon, - FilterIcon, - CellMeasurerCache, - CellMeasurer, - AutoSizer, - VirtualTableBody, - WindowScroller, - TableDeprecated, - TableHeaderDeprecated, - Table, - Thead, - Tr, - Th, - Td, - Caption, - TableGridBreakpoint -}; -pageData.relativeImports = "import 'content/examples/./VirtualGrid.example.css';" -pageData.examples = { - 'Basic': props => - {\n // this StringArray type is just needed because something in our documentation framework crashes when it encounters\n // a string[][] type\n type StringArray = string[];\n const rows: StringArray[] = [];\n for (let i = 0; i < 100; i++) {\n rows.push([`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]);\n }\n\n const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'];\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 {columns.map((col, index) => (\n {rows[rowIndex][index]}\n ))}\n \n \n );\n\n return (\n
\n \n \n \n \n {columns.map((col, index) => (\n \n ))}\n \n \n
Simple Table
{col}
\n \n {({ width }) => (\n \n )}\n \n
\n );\n};\n","title":"Basic","lang":"js","className":""}}> - -
, - 'Sortable': props => - {\n const rows: { id: string; cells: string[] }[] = [];\n for (let i = 0; i < 100; i++) {\n rows.push({\n id: `sortable-row-${i}`,\n cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]\n });\n }\n\n const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'];\n\n const [activeSortIndex, setActiveSortIndex] = React.useState(-1);\n\n // Sort direction of the currently sorted column\n const [activeSortDirection, setActiveSortDirection] = React.useState<'asc' | 'desc' | undefined>();\n\n const getRowIndex = (str: string) => Number(str?.split('-')[1]);\n\n const getSortParams = (columnIndex: number): ThProps['sort'] => ({\n sortBy: {\n index: activeSortIndex,\n direction: activeSortDirection\n },\n onSort: (_event, index, direction) => {\n setActiveSortIndex(index);\n setActiveSortDirection(direction as 'desc' | 'asc');\n },\n columnIndex\n });\n\n if (activeSortIndex !== null) {\n rows.sort((a, b) => {\n const aValue = a.cells[activeSortIndex];\n const bValue = b.cells[activeSortIndex];\n\n const aValueIndex = getRowIndex(aValue);\n const bValueIndex = getRowIndex(bValue);\n\n if (activeSortDirection === 'asc') {\n return aValueIndex - bValueIndex;\n }\n\n return bValueIndex - aValueIndex;\n });\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 {columns.map((col, index) => (\n {rows[rowIndex].cells[index]}\n ))}\n \n \n );\n return (\n
\n \n \n \n \n \n \n \n \n \n \n \n
Sortable Virtualized Table
{columns[0]}{columns[1]}{columns[2]}{columns[3]}{columns[4]}
\n \n {({ width }) => (\n ref}\n className=\"pf-v6-c-table pf-v6-c-virtualized pf-v6-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","className":""}}> - -
, - 'Selectable': props => - {\n // this StringArray type is just needed because something in our documentation framework crashes when it encounters\n // a string[][] type\n type StringArray = string[];\n const rows: StringArray[] = [];\n\n for (let i = 0; i < 100; i++) {\n rows.push([`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]);\n }\n\n const selectableRepos = rows;\n\n const [selectedRepoNames, setSelectedRepoNames] = React.useState([]);\n\n const setRepoSelected = (repo: string, isSelecting = true) =>\n setSelectedRepoNames((prevSelected) => {\n const otherSelectedRepoNames = prevSelected.filter((r) => r !== repo);\n return isSelecting ? [...otherSelectedRepoNames, repo] : otherSelectedRepoNames;\n });\n\n const columns = ['Repositories', 'Branches', 'Pull requests', 'Workspaces', 'Last Commit'];\n\n const selectAllRepos = (isSelecting = true) => setSelectedRepoNames(isSelecting ? rows.map((item) => item[0]) : []);\n\n const areAllReposSelected = selectedRepoNames.length === selectableRepos.length;\n const isRepoSelected = (repo: string) => selectedRepoNames.includes(repo);\n\n const [recentSelectedRowIndex, setRecentSelectedRowIndex] = React.useState(null);\n\n const onSelectRepo = (repo: string, rowIndex: number, isSelecting: boolean) => {\n if (recentSelectedRowIndex !== null) {\n const numberSelected = rowIndex - recentSelectedRowIndex;\n const intermediateIndexes =\n numberSelected > 0\n ? Array.from(new Array(numberSelected + 1), (_x, i) => i + recentSelectedRowIndex)\n : Array.from(new Array(Math.abs(numberSelected) + 1), (_x, i) => i + rowIndex);\n intermediateIndexes.forEach(() => setRepoSelected(repo, isSelecting));\n } else {\n setRepoSelected(repo, isSelecting);\n }\n setRecentSelectedRowIndex(rowIndex);\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 onSelectRepo(rows[rowIndex][0], rowIndex, isSelecting),\n isSelected: isRepoSelected(rows[rowIndex][0])\n }}\n />\n {columns.map((col, index) => (\n {rows[rowIndex][index]}\n ))}\n \n \n );\n\n return (\n
\n \n \n \n \n selectAllRepos(isSelecting),\n isSelected: areAllReposSelected\n }}\n />\n {columns.map((col, index) => (\n \n ))}\n \n \n
Selectable Virtualized Table
{col}
\n \n {({ width }) => (\n \n )}\n \n
\n );\n};\n","title":"Selectable","lang":"js","className":""}}> - -
, - 'Actions': props => - {\n interface RowType {\n disableActions: boolean;\n id: string;\n cells: string[];\n }\n\n const rows: RowType[] = [];\n for (let i = 0; i < 100; i++) {\n rows.push({\n disableActions: i % 3 === 2,\n id: `actions-row-${i}`,\n cells: [`one-${i}`, `two-${i}`, `three-${i}`, `four-${i}`, `five-${i}`]\n });\n }\n\n const columns = ['Name', 'Namespace', 'Labels', 'Status', 'Pod Selector'];\n\n const actions: IActions = [\n {\n title: 'Some action',\n onClick: (_event, rowId, _rowData, _extra) => 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 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 {columns.map((col, index) => (\n {rows[rowIndex].cells[index]}\n ))}\n \n \n \n \n \n );\n\n return (\n
\n \n \n \n \n \n \n \n \n \n \n \n \n
Actions VirtualizedTable
{columns[0]}{columns[1]}{columns[2]}{columns[3]}{columns[4]}
\n \n {({ width }) => (\n \n )}\n \n
\n );\n};\n","title":"Actions","lang":"js","className":""}}> - -
, - 'Filterable with WindowScroller': props => - {\n const [scrollableElement, setScrollableElement] = React.useState();\n React.useEffect(() => {\n const scrollableElement = document.getElementById('content-scrollable-2') as HTMLElement;\n setScrollableElement(scrollableElement);\n }, []);\n\n interface DataType {\n cells: (string | number)[];\n id: string;\n disableActions: boolean;\n }\n\n const rows: DataType[] = [];\n for (let i = 0; i < 100; i++) {\n if (i % 2 === 0) {\n rows.push({\n disableActions: false,\n id: `actions-row-${i}`,\n cells: [`US-Node ${i}`, i, i, 'Down', 'Brno']\n });\n } else if (i % 3 === 0) {\n rows.push({\n disableActions: false,\n id: `actions-row-${i}`,\n cells: [`CN-Node ${i}`, i, i, 'Running', 'Westford']\n });\n } else {\n rows.push({\n disableActions: true,\n id: `actions-row-${i}`,\n cells: [`US-Node ${i}`, i, i, 'Stopped', 'Raleigh']\n });\n }\n }\n\n const actions = [\n {\n title: 'Some action',\n // eslint-disable-next-line no-console\n onClick: (_event, rowId, _rowData, _extra) => console.log('clicked on Some action, on row: ', rowId)\n },\n {\n title:
Another action
,\n // eslint-disable-next-line no-console\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 // eslint-disable-next-line no-console\n onClick: (_event, rowId, _rowData, _extra) => console.log('clicked on Third action, on row: ', rowId)\n }\n ];\n\n const columns = ['Servers', 'Threads', 'Applications', 'Status', 'Location'];\n const scrollToIndex = -1; // can be used to programmatically set current index\n\n const [isCategoryDropdownOpen, setIsCategoryDropdownOpen] = React.useState(false);\n const [isFilterDropdownOpen, setIsFilterDropdownOpen] = React.useState(false);\n const [currentCategory, setCurrentCategory] = React.useState('Name');\n const [filters, setFilters] = React.useState>({ location: [], name: [], status: [] });\n const [inputValue, setInputValue] = React.useState('');\n\n const onDelete = (type: string | ToolbarLabelGroup, id: string) => {\n if (type === 'Location') {\n setFilters({\n ...filters,\n location: filters.location.filter((fil: string) => fil !== id)\n });\n } else if (type === 'Name') {\n setFilters({\n ...filters,\n name: filters.name.filter((fil: string) => fil !== id)\n });\n } else if (type === 'Status') {\n setFilters({\n ...filters,\n status: filters.status.filter((fil: string) => fil !== id)\n });\n } else {\n setFilters({ location: [], name: [], status: [] });\n }\n };\n\n const onCategoryToggle = () => {\n setIsCategoryDropdownOpen(!isCategoryDropdownOpen);\n };\n\n const onCategorySelect = (event) => {\n setCurrentCategory(event.target.innerText);\n setIsCategoryDropdownOpen(!isCategoryDropdownOpen);\n };\n\n const onFilterToggle = () => {\n setIsFilterDropdownOpen(!isFilterDropdownOpen);\n };\n\n const onInputChange = (newValue: string) => {\n setInputValue(newValue);\n };\n\n const onStatusSelect = (event: React.MouseEvent | undefined, selection: string | number | undefined) => {\n const checked = (event?.target as HTMLInputElement).checked;\n setFilters({\n ...filters,\n status: (checked && selection) ? [...filters.status, `${selection}`] : filters.status.filter((value) => value !== selection)\n });\n setIsFilterDropdownOpen(false);\n };\n\n const onNameInput = (event: React.SyntheticEvent | React.KeyboardEvent) => {\n setIsCategoryDropdownOpen(false);\n const pressedKey = (event as React.KeyboardEvent).key;\n if (pressedKey && pressedKey !== 'Enter') {\n return;\n }\n\n const prevFilters = filters.name;\n setFilters({ ...filters, name: prevFilters.includes(inputValue) ? prevFilters : [...prevFilters, inputValue] });\n };\n\n const onFilterSelect = () => {\n setIsFilterDropdownOpen(!isFilterDropdownOpen);\n setIsCategoryDropdownOpen(false);\n };\n\n const onLocationSelect = (_event: React.MouseEvent | undefined, selection: string | number | undefined) => {\n setFilters({ ...filters, location: [`${selection}`] });\n\n setIsFilterDropdownOpen(false);\n onFilterSelect();\n };\n\n const buildCategoryDropdown = () => {\n const categoryMenuItems = [\n \n Location\n ,\n \n Name\n ,\n \n Status\n \n ];\n\n return (\n \n ) => (\n }\n style={\n {\n width: '100%',\n verticalAlign: 'text-bottom'\n } as React.CSSProperties\n }\n >\n {currentCategory}\n \n )}\n isOpen={isCategoryDropdownOpen}\n >\n {categoryMenuItems}\n \n \n );\n };\n\n const buildFilterDropdown = () => {\n const locationMenuItems = [\n \n Raleigh\n ,\n \n Westford\n ,\n \n Boston\n ,\n \n Brno\n ,\n \n Bangalore\n \n ];\n\n const statusMenuItems = [\n \n Running\n ,\n \n Stopped\n ,\n \n Down\n ,\n \n Degraded\n ,\n \n Needs maintenance\n \n ];\n\n return (\n \n onDelete(category, chip as string)}\n categoryName=\"Location\"\n showToolbarItem={currentCategory === 'Location'}\n >\n ) => (\n \n {filters.location[0] || `Any`}\n \n )}\n >\n {locationMenuItems}\n \n \n onDelete(category, chip as string)}\n categoryName=\"Name\"\n showToolbarItem={currentCategory === 'Name'}\n >\n onInputChange(value)}\n value={inputValue}\n onClear={() => {\n onInputChange('');\n }}\n onSearch={onNameInput} // any typing is needed because of what I think is a bug in the SearchInput typing\n />\n \n onDelete(category, chip as string)}\n categoryName=\"Status\"\n showToolbarItem={currentCategory === 'Status'}\n >\n ) => (\n \n Filter by status\n {filters.status.length > 0 && {filters.status.length}}\n \n )}\n >\n {statusMenuItems}\n \n \n \n );\n };\n\n const renderToolbar = () => (\n setFilters({ location: [], name: [], status: [] })}\n collapseListedFiltersBreakpoint=\"xl\"\n >\n \n } breakpoint=\"xl\">\n \n {buildCategoryDropdown()}\n {buildFilterDropdown()}\n \n \n \n \n );\n\n const measurementCache = new CellMeasurerCache({\n fixedWidth: true,\n minHeight: 44,\n keyMapper: (rowIndex) => rowIndex\n });\n\n const filteredRows =\n filters.name.length > 0 || filters.location.length > 0 || filters.status.length > 0\n ? rows.filter(\n (row) =>\n (filters.name.length === 0 ||\n filters.name.some((name) => (row.cells[0] as string).toLowerCase().includes(name.toLowerCase()))) &&\n (filters.location.length === 0 || filters.location.includes(row.cells[4] as string)) &&\n (filters.status.length === 0 || filters.status.includes(row.cells[3] as string))\n )\n : rows;\n\n const emptyState = (\n \n No results match the filter criteria. Clear all filters and try again.\n \n \n {\n setFilters({ location: [], name: [], status: [] });\n }}\n >\n Clear all filters\n \n \n \n \n );\n\n const rowRenderer = ({ index: rowIndex, _isScrolling, key, style, parent }) => (\n \n \n {columns.map((col, index) => (\n {filteredRows[rowIndex].cells[index]}\n ))}\n \n \n \n \n \n );\n\n interface ScrollableContainerStyle {\n height: number;\n overflowX: 'auto';\n overflowY: 'scroll';\n scrollBehavior: 'smooth';\n WebkitOverflowScrolling: 'touch';\n position: 'relative';\n }\n\n const scrollableContainerStyle: 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 {renderToolbar()}\n \n \n \n {columns.map((col, index) => (\n \n ))}\n \n \n \n {filteredRows.length === 0 && (\n \n \n \n \n \n )}\n
{col}
\n {emptyState}\n
\n \n {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (\n \n {({ width }) => (\n
void}>\n \n
\n )}\n
\n )}\n
\n \n );\n};\n","title":"Filterable with WindowScroller","lang":"js","className":""}}> - -
-}; - -const Component = () => ( - -

- {`Note: React Virtualized Extension lives in its own package at `} - - - {`@patternfly/react-virtualized-extension`} - - - {`!`} -

- - {`Examples`} - - {React.createElement(pageData.examples["Basic"])} - {React.createElement(pageData.examples["Sortable"])} - {React.createElement(pageData.examples["Selectable"])} - {React.createElement(pageData.examples["Actions"])} - {React.createElement(pageData.examples["Filterable with WindowScroller"])} -
-); -Component.displayName = 'ExtensionsVirtualScrollTableReactDocs'; -Component.pageData = pageData; - -export default Component; 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 deleted file mode 100644 index 732f925..0000000 --- a/packages/module/patternfly-docs/generated/extensions/virtual-scroll-window-scroller/react.js +++ /dev/null @@ -1,216 +0,0 @@ -import React from 'react'; -import { AutoLinkHeader, Example, Link as PatternflyThemeLink } from '@patternfly/documentation-framework/components'; -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 '../../../content/examples/./VirtualGrid.example.css'; -import '../../../content/examples/./WindowScroller.example.css'; -const pageData = { - "id": "Virtual scroll window scroller", - "section": "extensions", - "subsection": "", - "deprecated": false, - "template": false, - "beta": false, - "demo": false, - "newImplementationLink": false, - "source": "react", - "tabName": null, - "slug": "/extensions/virtual-scroll-window-scroller/react", - "sourceLink": "https://github.com/patternfly/react-virtualized-extension", - "relPath": "packages/module/patternfly-docs/content/examples/WindowScroller.md", - "propComponents": [ - { - "name": "VirtualTableBody", - "description": "It is inefficient to create and manage a large list of DOM elements within a scrolling container\nif only a few of those elements are visible. The primary purpose of this component is to improve\nperformance by only rendering the DOM nodes that a user is able to see based on their current\nscroll position.\n\nThis component renders a virtualized list of elements with either fixed or dynamic heights.", - "props": [ - { - "name": "aria-label", - "type": "string", - "description": "" - }, - { - "name": "autoHeight", - "type": "boolean", - "description": "Removes fixed height from the scrollingContainer so that the total height\nof rows can stretch the window. Intended for use with WindowScroller", - "defaultValue": "false" - }, - { - "name": "className", - "type": "string", - "description": "Optional CSS class name" - }, - { - "name": "columnCount", - "type": "number", - "description": "" - }, - { - "name": "columns", - "type": "any[]", - "description": "" - }, - { - "name": "estimatedRowSize", - "type": "number", - "description": "Used to estimate the total height of a List before all of its rows have actually been measured.\nThe estimated total height is adjusted as rows are rendered.", - "defaultValue": "30" - }, - { - "name": "height", - "type": "number", - "description": "Height constraint for list (determines how many actual rows are rendered)", - "required": true - }, - { - "name": "innerScrollContainerComponent", - "type": "No type info", - "defaultValue": "'tbody'" - }, - { - "name": "noRowsRenderer", - "type": "NoContentRenderer", - "description": "Optional renderer to be used in place of rows when rowCount is 0", - "defaultValue": "() => null as any" - }, - { - "name": "onRowsRendered", - "type": "(params: any) => void", - "description": "Callback invoked with information about the slice of rows that were just rendered.", - "defaultValue": "() => {}" - }, - { - "name": "onScroll", - "type": "(params: Scroll) => void", - "description": "Callback invoked whenever the scroll offset changes within the inner scrollable region.\nThis callback can be used to sync scrolling between lists, tables, or grids.", - "defaultValue": "() => {}" - }, - { - "name": "overscanIndicesGetter", - "type": "OverscanIndicesGetter", - "description": "See VirtualGrid#overscanIndicesGetter", - "defaultValue": "accessibilityOverscanIndicesGetter" - }, - { - "name": "overscanRowCount", - "type": "number", - "description": "Number of rows to render above/below the visible bounds of the list.\nThese rows can help for smoother scrolling on touch devices.", - "defaultValue": "10" - }, - { - "name": "rowCount", - "type": "number", - "description": "Number of rows in list.", - "required": true - }, - { - "name": "rowHeight", - "type": "CellSize", - "description": "Either a fixed row height (number) or a function that returns the height of a row given its index.", - "required": true - }, - { - "name": "rowRenderer", - "type": "any", - "description": "Responsible for rendering a row given an index; ({ index: number }): node", - "required": true - }, - { - "name": "rows", - "type": "any[]", - "description": "", - "required": true - }, - { - "name": "scrollContainerComponent", - "type": "No type info", - "defaultValue": "'table'" - }, - { - "name": "scrollToAlignment", - "type": "Alignment", - "description": "See VirtualGrid#scrollToAlignment", - "defaultValue": "'auto'" - }, - { - "name": "scrollToIndex", - "type": "number", - "description": "Row index to ensure visible (by forcefully scrolling if necessary)", - "defaultValue": "-1" - }, - { - "name": "scrollTop", - "type": "number", - "description": "Vertical offset." - }, - { - "name": "style", - "type": "Object", - "description": "", - "defaultValue": "{}" - }, - { - "name": "tabIndex", - "type": "number", - "description": "Tab index for focus" - }, - { - "name": "width", - "type": "number", - "description": "Width of list", - "required": true - } - ] - } - ], - "examples": [ - "Window scroller" - ] -}; -pageData.liveContext = { - CellMeasurerCache, - CellMeasurer, - AutoSizer, - VirtualTableBody, - WindowScroller, - TableDeprecated, - TableHeaderDeprecated -}; -pageData.relativeImports = "import 'content/examples/./VirtualGrid.example.css';,import 'content/examples/./WindowScroller.example.css';" -pageData.examples = { - 'Window scroller': props => - {\n const [scrollableElement, setScrollableElement] = React.useState();\n React.useEffect(() => {\n const scrollableElement = document.getElementById('content-scrollable-2') as HTMLElement;\n setScrollableElement(scrollableElement);\n }, []);\n\n // this StringArray type is just needed because something in our documentation framework crashes when it encounters\n // a string[][] type\n type StringArray = string[];\n const rows: StringArray[] = [];\n\n for (let i = 0; i < 100000; i++) {\n const cells: string[] = [];\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\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 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 {columns.map((col, index) => (\n {text}\n ))}\n \n \n );\n };\n\n interface ScrollableContainerStyle {\n height: number;\n overflowX: 'auto';\n overflowY: 'scroll';\n scrollBehavior: 'smooth';\n WebkitOverflowScrolling: 'touch';\n position: 'relative';\n }\n\n const scrollableContainerStyle: 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 \n \n \n {columns.map((col, index) => (\n \n ))}\n \n \n
\n WindowScroller allows scrolling of a parent container or the window instead of tbody. It also can be used to\n dynamically size the table to the size of the scroll element.\n
{col}
\n \n {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (\n \n {({ width }) => (\n
void}>\n \n
\n )}\n
\n )}\n
\n \n );\n};\n","title":"Window scroller","lang":"js","className":""}}> - -
-}; - -const Component = () => ( - -

- {`Note: React Virtualized Extension lives in its own package at `} - - - {`@patternfly/react-virtualized-extension`} - - - {`! -`} -
- {` -This package is currently an extension. Extension components do not undergo the same rigorous design or coding review process as core PatternFly components. If enough members of the community find them useful, we will work to move them into our core PatternFly system by starting the design process for the idea. -`} -
- {` -`} -
-

- - {`Examples`} - - {React.createElement(pageData.examples["Window scroller"])} -
-); -Component.displayName = 'ExtensionsVirtualScrollWindowScrollerReactDocs'; -Component.pageData = pageData; - -export default Component; diff --git a/packages/module/patternfly-docs/generated/index.js b/packages/module/patternfly-docs/generated/index.js deleted file mode 100644 index 5b00105..0000000 --- a/packages/module/patternfly-docs/generated/index.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = { - '/extensions/virtual-scroll-window-scroller/react': { - id: "Virtual scroll window scroller", - title: "Virtual scroll window scroller", - toc: [{"text":"Examples"},[{"text":"Window scroller"}]], - examples: ["Window scroller"], - section: "extensions", - subsection: "", - source: "react", - tabName: null, - Component: () => import(/* webpackChunkName: "extensions/virtual-scroll-window-scroller/react/index" */ './extensions/virtual-scroll-window-scroller/react') - }, - '/extensions/virtual-scroll-table/react': { - id: "Virtual scroll table", - title: "Virtual scroll table", - toc: [{"text":"Examples"},[{"text":"Basic"},{"text":"Sortable"},{"text":"Selectable"},{"text":"Actions"},{"text":"Filterable with WindowScroller"}]], - examples: ["Basic","Sortable","Selectable","Actions","Filterable with WindowScroller"], - section: "extensions", - subsection: "", - source: "react", - tabName: null, - Component: () => import(/* webpackChunkName: "extensions/virtual-scroll-table/react/index" */ './extensions/virtual-scroll-table/react') - } -}; \ No newline at end of file diff --git a/packages/module/patternfly-docs/generated/react.js b/packages/module/patternfly-docs/generated/react.js deleted file mode 100644 index c4f2481..0000000 --- a/packages/module/patternfly-docs/generated/react.js +++ /dev/null @@ -1,59 +0,0 @@ -import React from 'react'; -import { AutoLinkHeader, Example, Link as PatternflyThemeLink } from '@patternfly/documentation-framework/components'; -import { ExtendedButton } from "@patternfly/react-virtualized-extension"; -const pageData = { - "id": "React virtualized extension", - "section": "extensions", - "source": "react", - "slug": "/extensions/react-virtualized-extension/react", - "sourceLink": "https://github.com/patternfly/patternfly-react/blob/main/packages/module/patternfly-docs/content/extensions/react-virtualized-extension/examples/basic.md", - "propComponents": [ - { - "name": "ExtendedButton", - "description": "", - "props": [ - { - "name": "children", - "type": "React.ReactNode", - "description": "Content to render inside the extended button component" - } - ] - } - ], - "examples": [ - "Example" - ], - "fullscreenExamples": [ - "Fullscreen example" - ] -}; -pageData.liveContext = { - ExtendedButton -}; -pageData.relativeImports = { - -}; -pageData.examples = { - 'Example': props => - My custom extension button;\n","title":"Example","lang":"js"}}> - - , - 'Fullscreen example': props => - My custom extension button;\n","title":"Fullscreen example","lang":"js","isFullscreen":true}}> - - -}; - -const Component = () => ( - - - {`Basic usage`} - - {React.createElement(pageData.examples["Example"])} - {React.createElement(pageData.examples["Fullscreen example"])} - -); -Component.displayName = 'ExtensionsPatternflyExtensionSeedReactDocs'; -Component.pageData = pageData; - -export default Component; diff --git a/packages/module/patternfly-docs/pages/index.js b/packages/module/patternfly-docs/pages/index.js index 54c2430..a6f0cc7 100644 --- a/packages/module/patternfly-docs/pages/index.js +++ b/packages/module/patternfly-docs/pages/index.js @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-unused-vars import React from 'react'; import { Title, PageSection } from '@patternfly/react-core'; @@ -10,7 +11,7 @@ const centerStyle = { const IndexPage = () => { return ( - +
My extension docs diff --git a/packages/module/src/components/Virtualized/VirtualGrid.ts b/packages/module/src/components/Virtualized/VirtualGrid.ts index 0d9902a..ac93940 100644 --- a/packages/module/src/components/Virtualized/VirtualGrid.ts +++ b/packages/module/src/components/Virtualized/VirtualGrid.ts @@ -1,5 +1,7 @@ /* eslint-disable */ -import * as React from 'react'; +import type { ComponentType, ReactElement } from 'react'; + +import { createElement, Component } from 'react'; import calculateSizeAndPositionDataAndUpdateScrollOffset from './utils/calculateSizeAndPositionDataAndUpdateScrollOffset'; import ScalingCellSizeAndPositionManager from './utils/ScalingCellSizeAndPositionManager'; import createCallbackMemoizer from './utils/createCallbackMemoizer'; @@ -233,10 +235,10 @@ export interface VirtualGridProps { width: number; /** Scroll Container element to render */ - scrollContainerComponent?: string | React.ComponentType<any>; + scrollContainerComponent?: string | ComponentType<any>; /** Inner Scroll Container element to render */ - innerScrollContainerComponent?: string | React.ComponentType<any>; + innerScrollContainerComponent?: string | ComponentType<any>; } interface InstanceProps { @@ -271,7 +273,7 @@ interface VirtualGridState { * Renders tabular data with virtualization along the vertical and horizontal axes. * Row heights and column widths must be known ahead of time and specified as properties. */ -export class VirtualGrid extends React.Component<VirtualGridProps, VirtualGridState> { +export class VirtualGrid extends Component<VirtualGridProps, VirtualGridState> { static defaultProps = { 'aria-label': 'grid', 'aria-readonly': true, @@ -317,7 +319,7 @@ export class VirtualGrid extends React.Component<VirtualGridProps, VirtualGridSt _scrollbarPresenceChanged = false; _scrollingContainer: Element; - _childrenToDisplay: React.ReactElement<any>[]; + _childrenToDisplay: ReactElement<any>[]; _columnStartIndex: number; _columnStopIndex: number; @@ -1020,13 +1022,13 @@ export class VirtualGrid extends React.Component<VirtualGridProps, VirtualGridSt ...containerStyle } }; - innerScrollContainer = React.createElement( + innerScrollContainer = createElement( innerScrollContainerComponent, innerScrollContainerProps, childrenToDisplay ); } - return React.createElement(scrollContainerComponent, scrollContainerProps, [ + return createElement(scrollContainerComponent, scrollContainerProps, [ innerScrollContainer, showNoContentRenderer && noContentRenderer() ]); diff --git a/packages/module/src/components/Virtualized/VirtualTableBody.tsx b/packages/module/src/components/Virtualized/VirtualTableBody.tsx index a3013e2..c2321f1 100644 --- a/packages/module/src/components/Virtualized/VirtualTableBody.tsx +++ b/packages/module/src/components/Virtualized/VirtualTableBody.tsx @@ -1,6 +1,6 @@ /* eslint-disable */ -import * as React from 'react'; +import { Component } from 'react'; import { NoContentRenderer, Alignment, @@ -121,7 +121,7 @@ interface VirtualTableBodyProps rows: any[]; } -export class VirtualTableBody extends React.Component<VirtualTableBodyProps> { +export class VirtualTableBody extends Component<VirtualTableBodyProps> { static defaultProps = { autoHeight: false, estimatedRowSize: 30, @@ -232,7 +232,7 @@ export class VirtualTableBody extends React.Component<VirtualTableBodyProps> { // note: these aria props if rendered will break a11y for role="presentation" // this approach attempts to fix non standard table grids // see: https://www.html5accessibility.com/tests/aria-table-fix.html - <VirtualGrid + (<VirtualGrid {...this.props} style={{ tableLayout: 'fixed', @@ -257,7 +257,7 @@ export class VirtualTableBody extends React.Component<VirtualTableBodyProps> { scrollToRow={scrollToIndex} scrollContainerComponent={scrollContainerComponent} innerScrollContainerComponent={innerScrollContainerComponent} - /> + />) ); } diff --git a/packages/module/src/components/Virtualized/VirtualizedTable.test.tsx b/packages/module/src/components/Virtualized/VirtualizedTable.test.tsx index 67b1a51..8346972 100644 --- a/packages/module/src/components/Virtualized/VirtualizedTable.test.tsx +++ b/packages/module/src/components/Virtualized/VirtualizedTable.test.tsx @@ -1,4 +1,3 @@ -import * as React from 'react'; import { render } from '@testing-library/react'; import { sortable diff --git a/packages/module/src/components/Virtualized/testDataSets.tsx b/packages/module/src/components/Virtualized/testDataSets.tsx index a6334ad..3094a07 100644 --- a/packages/module/src/components/Virtualized/testDataSets.tsx +++ b/packages/module/src/components/Virtualized/testDataSets.tsx @@ -2,7 +2,7 @@ // This file is test data pulled from the @patternfly/react-table package -import * as React from 'react'; +import type { MouseEvent as ReactMouseEvent } from 'react'; import { IRow, ICell, IActions, EditableTextCell } from '@patternfly/react-table'; export const columns: (ICell | string)[] = [ @@ -198,13 +198,13 @@ export const editableRows: IRow[] = [ export const actions: IActions = [ { title: 'Some action', - onClick: (event: React.MouseEvent, rowId: number) => + onClick: (event: ReactMouseEvent, rowId: number) => // tslint:disable-next-line:no-console console.log('clicked on Some action, on row: ', rowId) }, { title: <div>Another action</div>, - onClick: (event: React.MouseEvent, rowId: number) => + onClick: (event: ReactMouseEvent, rowId: number) => // tslint:disable-next-line:no-console console.log('clicked on Another action, on row: ', rowId) }, @@ -214,7 +214,7 @@ export const actions: IActions = [ }, { title: 'Third action', - onClick: (event: React.MouseEvent, rowId: number) => + onClick: (event: ReactMouseEvent, rowId: number) => // tslint:disable-next-line:no-console console.log('clicked on Third action, on row: ', rowId) } diff --git a/packages/module/src/components/Virtualized/types.ts b/packages/module/src/components/Virtualized/types.ts index 36a65cd..e6dbea2 100644 --- a/packages/module/src/components/Virtualized/types.ts +++ b/packages/module/src/components/Virtualized/types.ts @@ -1,4 +1,4 @@ -import * as React from 'react'; +import type { ReactElement } from 'react'; import ScalingCellSizeAndPositionManager from './utils/ScalingCellSizeAndPositionManager'; export interface CellPosition { @@ -16,10 +16,10 @@ export interface CellRendererParams { style: any; } -export type CellRenderer = (props: CellRendererParams) => React.ReactElement<any>; +export type CellRenderer = (props: CellRendererParams) => ReactElement<any>; export interface CellCache { - [key: string]: React.ReactElement<any>; + [key: string]: ReactElement<any>; } export interface StyleCache { [key: string]: any; @@ -47,13 +47,13 @@ export interface CellRangeRendererParams { visibleRowIndices: any; } -export type CellRangeRenderer = (params: CellRangeRendererParams) => React.ReactElement<any>[]; +export type CellRangeRenderer = (params: CellRangeRendererParams) => ReactElement<any>[]; export type CellSizeGetter = (params: { index: number }) => number; export type CellSize = CellSizeGetter | number; -export type NoContentRenderer = () => React.ReactElement<any> | null; +export type NoContentRenderer = () => ReactElement<any> | null; export interface Scroll { clientHeight: number; diff --git a/packages/module/tsconfig.json b/packages/module/tsconfig.json index bd3e41a..f0fa037 100644 --- a/packages/module/tsconfig.json +++ b/packages/module/tsconfig.json @@ -9,7 +9,7 @@ "lib": ["es2015", "dom"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ - "jsx": "react" /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */, + "jsx": "react-jsx" /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */, // "declaration": true /* Generates corresponding '.d.ts' file. */, "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ "sourceMap": true, /* Generates corresponding '.map' file. */ diff --git a/yarn.lock b/yarn.lock index ff4954a..5f937ed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10257,12 +10257,12 @@ react-docgen@5.3.1: strip-indent "^3.0.0" "react-dom@^17.0.0 || ^18.0.0": - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== dependencies: loose-envify "^1.1.0" - scheduler "^0.23.0" + scheduler "^0.23.2" react-dropzone@14.2.3, react-dropzone@^14.2.3: version "14.2.3" @@ -10318,9 +10318,9 @@ react-virtualized@^9.22.5: react-lifecycles-compat "^3.0.4" "react@^17.0.0 || ^18.0.0": - version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== dependencies: loose-envify "^1.1.0" @@ -10821,10 +10821,10 @@ saxes@^6.0.0: dependencies: xmlchars "^2.2.0" -scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== dependencies: loose-envify "^1.1.0"