diff --git a/.github/workflows/add-new-issues-to-project.yml b/.github/workflows/add-new-issues-to-project.yml index de588d0c795..fb7b6f2f3fc 100644 --- a/.github/workflows/add-new-issues-to-project.yml +++ b/.github/workflows/add-new-issues-to-project.yml @@ -13,4 +13,4 @@ jobs: - uses: actions/add-to-project@v0.3.0 with: project-url: https://github.com/orgs/patternfly/projects/7 - github-token: ${{ secrets.PF_ISSUES_PROJECT_SECRET }} + github-token: ${{ secrets.GH_PROJECTS }} diff --git a/.github/workflows/extensions.yml b/.github/workflows/extensions.yml new file mode 100644 index 00000000000..3a436d5cf22 --- /dev/null +++ b/.github/workflows/extensions.yml @@ -0,0 +1,17 @@ +name: Add relevant issues to extensions project board + +on: + issues: + types: + - labeled + +jobs: + add-to-extensions: + if: github.event.label.name == 'extension' + name: Add issue to extensions board + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@v0.3.0 + with: + project-url: https://github.com/orgs/patternfly/projects/12 + github-token: ${{ secrets.GH_PROJECTS }} diff --git a/packages/react-catalog-view-extension/CHANGELOG.md b/packages/react-catalog-view-extension/CHANGELOG.md index 659370e5cc1..16c88669d75 100644 --- a/packages/react-catalog-view-extension/CHANGELOG.md +++ b/packages/react-catalog-view-extension/CHANGELOG.md @@ -3,6 +3,174 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 4.92.56 (2022-11-01) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.55](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.54...@patternfly/react-catalog-view-extension@4.92.55) (2022-10-27) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.54](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.53...@patternfly/react-catalog-view-extension@4.92.54) (2022-10-26) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.53](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.52...@patternfly/react-catalog-view-extension@4.92.53) (2022-10-26) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## 4.92.52 (2022-10-25) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.51](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.50...@patternfly/react-catalog-view-extension@4.92.51) (2022-10-24) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.50](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.49...@patternfly/react-catalog-view-extension@4.92.50) (2022-10-24) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.49](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.48...@patternfly/react-catalog-view-extension@4.92.49) (2022-10-24) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.48](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.47...@patternfly/react-catalog-view-extension@4.92.48) (2022-10-24) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.47](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.46...@patternfly/react-catalog-view-extension@4.92.47) (2022-10-22) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.46](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.45...@patternfly/react-catalog-view-extension@4.92.46) (2022-10-21) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.45](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.44...@patternfly/react-catalog-view-extension@4.92.45) (2022-10-21) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.44](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.43...@patternfly/react-catalog-view-extension@4.92.44) (2022-10-21) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.43](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.42...@patternfly/react-catalog-view-extension@4.92.43) (2022-10-20) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.42](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.41...@patternfly/react-catalog-view-extension@4.92.42) (2022-10-19) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.41](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.40...@patternfly/react-catalog-view-extension@4.92.41) (2022-10-18) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.40](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.39...@patternfly/react-catalog-view-extension@4.92.40) (2022-10-18) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.39](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.38...@patternfly/react-catalog-view-extension@4.92.39) (2022-10-17) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.38](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.37...@patternfly/react-catalog-view-extension@4.92.38) (2022-10-14) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.37](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.36...@patternfly/react-catalog-view-extension@4.92.37) (2022-10-14) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.36](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.35...@patternfly/react-catalog-view-extension@4.92.36) (2022-10-14) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + ## [4.92.35](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.34...@patternfly/react-catalog-view-extension@4.92.35) (2022-10-13) **Note:** Version bump only for package @patternfly/react-catalog-view-extension diff --git a/packages/react-catalog-view-extension/package.json b/packages/react-catalog-view-extension/package.json index 7a38d791014..7ff0dcf5d8e 100644 --- a/packages/react-catalog-view-extension/package.json +++ b/packages/react-catalog-view-extension/package.json @@ -1,6 +1,6 @@ { "name": "@patternfly/react-catalog-view-extension", - "version": "4.92.35", + "version": "4.92.56", "description": "This library provides catalog view extensions for PatternFly 4 React.", "main": "dist/js/index.js", "module": "dist/esm/index.js", @@ -35,9 +35,9 @@ "clean": "rimraf dist" }, "dependencies": { - "@patternfly/patternfly": "4.217.1", - "@patternfly/react-core": "^4.251.1", - "@patternfly/react-styles": "^4.91.6" + "@patternfly/patternfly": "4.219.2", + "@patternfly/react-core": "^4.258.4", + "@patternfly/react-styles": "^4.91.10" }, "devDependencies": { "rimraf": "^2.6.2", diff --git a/packages/react-charts/CHANGELOG.md b/packages/react-charts/CHANGELOG.md index 6056c8ed7e7..584406ded7a 100644 --- a/packages/react-charts/CHANGELOG.md +++ b/packages/react-charts/CHANGELOG.md @@ -3,6 +3,38 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 6.94.11 (2022-10-27) + +**Note:** Version bump only for package @patternfly/react-charts + + + + + +## 6.94.10 (2022-10-26) + +**Note:** Version bump only for package @patternfly/react-charts + + + + + +## [6.94.9](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-charts@6.94.8...@patternfly/react-charts@6.94.9) (2022-10-17) + +**Note:** Version bump only for package @patternfly/react-charts + + + + + +## 6.94.8 (2022-10-14) + +**Note:** Version bump only for package @patternfly/react-charts + + + + + ## 6.94.7 (2022-10-05) **Note:** Version bump only for package @patternfly/react-charts diff --git a/packages/react-charts/package.json b/packages/react-charts/package.json index c44d2e38341..3774b5b7b6e 100644 --- a/packages/react-charts/package.json +++ b/packages/react-charts/package.json @@ -1,6 +1,6 @@ { "name": "@patternfly/react-charts", - "version": "6.94.7", + "version": "6.94.11", "description": "This library provides a set of React chart components for use with the PatternFly reference implementation.", "main": "dist/js/index.js", "module": "dist/esm/index.js", @@ -29,8 +29,8 @@ }, "homepage": "https://github.com/patternfly/patternfly-react#readme", "dependencies": { - "@patternfly/react-styles": "^4.91.6", - "@patternfly/react-tokens": "^4.93.6", + "@patternfly/react-styles": "^4.91.10", + "@patternfly/react-tokens": "^4.93.10", "hoist-non-react-statics": "^3.3.0", "lodash": "^4.17.19", "tslib": "^2.0.0", diff --git a/packages/react-code-editor/CHANGELOG.md b/packages/react-code-editor/CHANGELOG.md index cdc28b695e2..be86cf43e69 100644 --- a/packages/react-code-editor/CHANGELOG.md +++ b/packages/react-code-editor/CHANGELOG.md @@ -3,6 +3,177 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 4.82.56 (2022-11-01) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.55](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.54...@patternfly/react-code-editor@4.82.55) (2022-10-27) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.54](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.53...@patternfly/react-code-editor@4.82.54) (2022-10-26) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.53](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.52...@patternfly/react-code-editor@4.82.53) (2022-10-26) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## 4.82.52 (2022-10-25) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.51](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.50...@patternfly/react-code-editor@4.82.51) (2022-10-24) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.50](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.49...@patternfly/react-code-editor@4.82.50) (2022-10-24) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.49](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.48...@patternfly/react-code-editor@4.82.49) (2022-10-24) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.48](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.47...@patternfly/react-code-editor@4.82.48) (2022-10-24) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.47](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.46...@patternfly/react-code-editor@4.82.47) (2022-10-22) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.46](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.45...@patternfly/react-code-editor@4.82.46) (2022-10-21) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.45](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.44...@patternfly/react-code-editor@4.82.45) (2022-10-21) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.44](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.43...@patternfly/react-code-editor@4.82.44) (2022-10-21) + + +### Bug Fixes + +* **CodeEditor:** use codeEditorControls and clean up overall ([#7931](https://github.com/patternfly/patternfly-react/issues/7931)) ([69d5937](https://github.com/patternfly/patternfly-react/commit/69d5937fd5fa56ace7543a740ba253bdc851009e)) + + + + + +## [4.82.43](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.42...@patternfly/react-code-editor@4.82.43) (2022-10-20) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.42](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.41...@patternfly/react-code-editor@4.82.42) (2022-10-19) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.41](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.40...@patternfly/react-code-editor@4.82.41) (2022-10-18) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.40](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.39...@patternfly/react-code-editor@4.82.40) (2022-10-18) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.39](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.38...@patternfly/react-code-editor@4.82.39) (2022-10-17) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.38](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.37...@patternfly/react-code-editor@4.82.38) (2022-10-14) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.37](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.36...@patternfly/react-code-editor@4.82.37) (2022-10-14) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.36](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.35...@patternfly/react-code-editor@4.82.36) (2022-10-14) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + ## [4.82.35](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.34...@patternfly/react-code-editor@4.82.35) (2022-10-13) **Note:** Version bump only for package @patternfly/react-code-editor diff --git a/packages/react-code-editor/package.json b/packages/react-code-editor/package.json index 38fca4a225e..d33482b9fa3 100644 --- a/packages/react-code-editor/package.json +++ b/packages/react-code-editor/package.json @@ -1,6 +1,6 @@ { "name": "@patternfly/react-code-editor", - "version": "4.82.35", + "version": "4.82.56", "description": "This package provides a PatternFly wrapper for the Monaco code editor\n", "main": "dist/js/index.js", "module": "dist/esm/index.js", @@ -30,10 +30,10 @@ "clean": "rimraf dist" }, "dependencies": { - "@patternfly/react-core": "^4.251.1", - "@patternfly/react-icons": "^4.92.6", - "@patternfly/react-styles": "^4.91.6", - "react-dropzone": "^14.2.3", + "@patternfly/react-core": "^4.258.4", + "@patternfly/react-icons": "^4.92.10", + "@patternfly/react-styles": "^4.91.10", + "react-dropzone": "14.2.3", "tslib": "^2.0.0" }, "peerDependencies": { diff --git a/packages/react-code-editor/src/components/CodeEditor/CodeEditor.tsx b/packages/react-code-editor/src/components/CodeEditor/CodeEditor.tsx index cbfddd49d49..945fe899122 100644 --- a/packages/react-code-editor/src/components/CodeEditor/CodeEditor.tsx +++ b/packages/react-code-editor/src/components/CodeEditor/CodeEditor.tsx @@ -13,7 +13,6 @@ import { Popover, PopoverProps, Title, - Tooltip, TooltipPosition } from '@patternfly/react-core'; import MonacoEditor, { ChangeHandler, EditorDidMount } from 'react-monaco-editor'; @@ -25,6 +24,7 @@ import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon'; import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; import Dropzone, { FileRejection } from 'react-dropzone'; import { CodeEditorContext } from './CodeEditorUtils'; +import { CodeEditorControl } from './CodeEditorControl'; export interface Shortcut { description: string; @@ -440,18 +440,8 @@ export class CodeEditor extends React.Component { - if (this.timer) { - window.clearTimeout(this.timer); - this.setState({ copied: false }); - } - this.editor?.focus(); - document.execCommand('copy'); - this.setState({ copied: true }, () => { - this.timer = window.setTimeout(() => { - this.setState({ copied: false }); - this.timer = null; - }, 2500); - }); + navigator.clipboard.writeText(this.state.value); + this.setState({ copied: true }); }; download = () => { @@ -555,55 +545,51 @@ export class CodeEditor extends React.Component )); + const tooltipProps = { + position: toolTipPosition, + exitDelay: toolTipDelay, + entryDelay: toolTipDelay, + maxWidth: toolTipMaxWidth, + trigger: 'mouseenter focus' + }; + const editorHeader = (
{
- {isCopyEnabled && (!showEmptyState || !!value) && ( - {copied ? copyButtonSuccessTooltipText : copyButtonToolTipText}
} - exitDelay={copied ? toolTipCopyExitDelay : toolTipDelay} - entryDelay={toolTipDelay} - maxWidth={toolTipMaxWidth} - position={toolTipPosition} - > - - - )} - {isUploadEnabled && ( - {uploadButtonToolTipText}
} - entryDelay={toolTipDelay} - exitDelay={toolTipDelay} - maxWidth={toolTipMaxWidth} - position={toolTipPosition} - > - - - )} - {isDownloadEnabled && (!showEmptyState || !!value) && ( - {downloadButtonToolTipText}} - entryDelay={toolTipDelay} - exitDelay={toolTipDelay} - maxWidth={toolTipMaxWidth} - position={toolTipPosition} - > - - - )} - {customControls && ( - {customControls} - )} + + {isCopyEnabled && (!showEmptyState || !!value) && ( + } + aria-label={copyButtonAriaLabel} + tooltipProps={{ + ...tooltipProps, + 'aria-live': 'polite', + content:
{copied ? copyButtonSuccessTooltipText : copyButtonToolTipText}
, + exitDelay: copied ? toolTipCopyExitDelay : toolTipDelay, + onTooltipHidden: () => this.setState({ copied: false }) + }} + onClick={this.copyCode} + /> + )} + {isUploadEnabled && ( + } + aria-label={uploadButtonAriaLabel} + tooltipProps={{ content:
{uploadButtonToolTipText}
, ...tooltipProps }} + onClick={open} + /> + )} + {isDownloadEnabled && (!showEmptyState || !!value) && ( + } + aria-label={downloadButtonAriaLabel} + tooltipProps={{ content:
{downloadButtonToolTipText}
, ...tooltipProps }} + onClick={this.download} + /> + )} + {customControls && customControls} +
} {
{headerMainContent}
} diff --git a/packages/react-code-editor/src/components/CodeEditor/CodeEditorControl.tsx b/packages/react-code-editor/src/components/CodeEditor/CodeEditorControl.tsx index 5b8298a3416..751cf7c1c4f 100644 --- a/packages/react-code-editor/src/components/CodeEditor/CodeEditorControl.tsx +++ b/packages/react-code-editor/src/components/CodeEditor/CodeEditorControl.tsx @@ -7,19 +7,19 @@ import { CodeEditorContext } from './CodeEditorUtils'; */ export interface CodeEditorControlProps extends Omit { - /** Accessible label for the code editor control. */ + /** Accessible label for the code editor control */ 'aria-label'?: string; /** Additional classes added to the code editor control. */ className?: string; - /** Delay in ms before the tooltip appears. */ + /** @deprecated Delay in ms before the tooltip appears. */ entryDelay?: number; - /** Delay in ms before the tooltip disappears. */ + /** @deprecated Delay in ms before the tooltip disappears. */ exitDelay?: number; /** Icon rendered inside the code editor control. */ icon: React.ReactNode; - /** Maximum width of the tooltip (default 150px). */ + /** @deprecated Maximum width of the tooltip (default 150px). */ maxWidth?: string; - /** Copy button popover position. */ + /** @deprecated Copy button popover position. */ position?: | PopoverPosition | 'auto' @@ -35,12 +35,14 @@ export interface CodeEditorControlProps extends Omit { | 'left-end' | 'right-start' | 'right-end'; - /** Text to display in the tooltip. */ - toolTipText: React.ReactNode; - /** Event handler for the click of the button. */ + /** @deprecated Text to display in the tooltip*/ + toolTipText?: React.ReactNode; + /** Event handler for the click of the button */ onClick: (code: string, event?: any) => void; /** Flag indicating that the button is visible above the code editor. */ isVisible?: boolean; + /** Additional tooltip props forwarded to the Tooltip component */ + tooltipProps?: any; } export const CodeEditorControl: React.FunctionComponent = ({ @@ -48,28 +50,67 @@ export const CodeEditorControl: React.FunctionComponent className, 'aria-label': ariaLabel, toolTipText, - exitDelay = 0, - entryDelay = 300, - maxWidth = '100px', - position = 'top', + exitDelay, + entryDelay, + maxWidth, + position, onClick = () => {}, isVisible = true, + tooltipProps = {}, ...props }: CodeEditorControlProps) => { const context = React.useContext(CodeEditorContext); + if (entryDelay !== undefined) { + // eslint-disable-next-line no-console + console.warn( + 'CodeEditorControl: entryDelay prop has been deprecated. ' + + 'Pass the entryDelay via the tooltipProps prop instead.' + ); + } + + if (exitDelay !== undefined) { + // eslint-disable-next-line no-console + console.warn( + 'CodeEditorControl: exitDelay prop has been deprecated. ' + + 'Pass the exitDelay via the tooltipProps prop instead.' + ); + } + + if (maxWidth !== undefined) { + // eslint-disable-next-line no-console + console.warn( + 'CodeEditorControl: maxWidth prop has been deprecated. ' + 'Pass the maxWidth via the tooltipProps prop instead.' + ); + } + + if (position !== undefined) { + // eslint-disable-next-line no-console + console.warn( + 'CodeEditorControl: position prop has been deprecated. ' + 'Pass the position via the tooltipProps prop instead.' + ); + } + + if (toolTipText !== undefined) { + // eslint-disable-next-line no-console + console.warn( + 'CodeEditorControl: toolTipText prop has been deprecated. ' + + 'Pass the toolTipText by setting the content field in tooltipProps prop instead.' + ); + } + const onCustomClick = (event: React.MouseEvent) => { onClick(context.code, event); }; return isVisible ? ( {toolTipText}} + {...tooltipProps} > + ); + expect(asFragment()).toMatchSnapshot(); + }); + + test('isLoading icon only', () => { + const { asFragment } = render( + ); @@ -130,11 +146,4 @@ describe('Button', () => { render(); expect(screen.getByRole('button')).toHaveAttribute('tabindex', '0'); }); - - test('isLoading icon only', () => { - const { asFragment } = render( - + +`; + exports[`Button link button 1`] = ` {' '} {' '} +
+
{' '} ); }; diff --git a/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx b/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx index 82186d297d9..de0e55165c9 100644 --- a/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx +++ b/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx @@ -8,6 +8,7 @@ import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-i import { css } from '@patternfly/react-styles'; import styles from '@patternfly/react-styles/css/components/CalendarMonth/calendar-month'; import { getUniqueId } from '../../helpers/util'; +import { isValidDate } from '../../helpers/datetimeUtils'; export enum Weekday { Sunday = 0, @@ -109,8 +110,6 @@ const buildCalendar = (year: number, month: number, weekStart: number, validator const isSameDate = (d1: Date, d2: Date) => d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate(); -export const isValidDate = (date: Date) => Boolean(date && !isNaN(date as any)); - const today = new Date(); /** The main calendar month component. */ diff --git a/packages/react-core/src/components/CalendarMonth/examples/CalendarMonth.md b/packages/react-core/src/components/CalendarMonth/examples/CalendarMonth.md index 377c9422f54..993a87a1501 100644 --- a/packages/react-core/src/components/CalendarMonth/examples/CalendarMonth.md +++ b/packages/react-core/src/components/CalendarMonth/examples/CalendarMonth.md @@ -3,7 +3,6 @@ id: Calendar month section: components cssPrefix: pf-c-calendar-month propComponents: ['CalendarMonth', 'CalendarFormat'] -beta: true --- ## Examples diff --git a/packages/react-core/src/components/Card/Card.tsx b/packages/react-core/src/components/Card/Card.tsx index 36746cb75ce..c0203a42a9e 100644 --- a/packages/react-core/src/components/Card/Card.tsx +++ b/packages/react-core/src/components/Card/Card.tsx @@ -16,11 +16,11 @@ export interface CardProps extends React.HTMLProps, OUIAProps { isCompact?: boolean; /** Modifies the card to include selectable styling */ isSelectable?: boolean; - /** @beta Specifies the card is selectable, and applies the new raised styling on hover and select */ + /** Specifies the card is selectable, and applies the new raised styling on hover and select */ isSelectableRaised?: boolean; /** Modifies the card to include selected styling */ isSelected?: boolean; - /** @beta Modifies a raised selectable card to have disabled styling */ + /** Modifies a raised selectable card to have disabled styling */ isDisabledRaised?: boolean; /** Modifies the card to include flat styling */ isFlat?: boolean; diff --git a/packages/react-core/src/components/ClipboardCopy/ClipboardCopy.tsx b/packages/react-core/src/components/ClipboardCopy/ClipboardCopy.tsx index b53ac9c18fc..0e89a54e14d 100644 --- a/packages/react-core/src/components/ClipboardCopy/ClipboardCopy.tsx +++ b/packages/react-core/src/components/ClipboardCopy/ClipboardCopy.tsx @@ -8,15 +8,10 @@ import { GenerateId } from '../../helpers/GenerateId/GenerateId'; import { ClipboardCopyButton } from './ClipboardCopyButton'; import { ClipboardCopyToggle } from './ClipboardCopyToggle'; import { ClipboardCopyExpanded } from './ClipboardCopyExpanded'; +import { getOUIAProps, OUIAProps } from '../../helpers'; export const clipboardCopyFunc = (event: React.ClipboardEvent, text?: React.ReactNode) => { - const clipboard = event.currentTarget.parentElement; - const el = document.createElement('textarea'); - el.value = text.toString(); - clipboard.appendChild(el); - el.select(); - document.execCommand('copy'); - clipboard.removeChild(el); + navigator.clipboard.writeText(text.toString()); }; export enum ClipboardCopyVariant { @@ -31,7 +26,7 @@ export interface ClipboardCopyState { copied: boolean; } -export interface ClipboardCopyProps extends Omit, 'onChange'> { +export interface ClipboardCopyProps extends Omit, 'onChange'>, OUIAProps { /** Additional classes added to the clipboard copy container. */ className?: string; /** Tooltip message to display when hover the copy button */ @@ -74,7 +69,7 @@ export interface ClipboardCopyProps extends Omit exitDelay?: number; /** Delay in ms before the tooltip appears. */ entryDelay?: number; - /** Delay in ms before the tooltip message switch to hover tip. */ + /** @deprecated Delay in ms before the tooltip message switch to hover tip. */ switchDelay?: number; /** A function that is triggered on clicking the copy button. */ onCopy?: (event: React.ClipboardEvent, text?: React.ReactNode) => void; @@ -84,6 +79,10 @@ export interface ClipboardCopyProps extends Omit children: React.ReactNode; /** Additional actions for inline clipboard copy. Should be wrapped with ClipboardCopyAction. */ additionalActions?: React.ReactNode; + /** Value to overwrite the randomly generated data-ouia-component-id.*/ + ouiaId?: number | string; + /** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ + ouiaSafe?: boolean; } export class ClipboardCopy extends React.Component { @@ -98,6 +97,14 @@ export class ClipboardCopy extends React.Component = { @@ -109,14 +116,14 @@ export class ClipboardCopy extends React.Component undefined, textAriaLabel: 'Copyable input', toggleAriaLabel: 'Show content', - additionalActions: null + additionalActions: null, + ouiaSafe: true }; // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -149,6 +156,7 @@ export class ClipboardCopy extends React.Component + switchDelay, /* eslint-enable @typescript-eslint/no-unused-vars */ isReadOnly, isCode, @@ -156,7 +164,6 @@ export class ClipboardCopy extends React.Component {variant === 'inline-compact' && ( @@ -208,18 +218,10 @@ export class ClipboardCopy extends React.Component { - if (this.timer) { - window.clearTimeout(this.timer); - this.setState({ copied: false }); - } onCopy(event, this.state.text); - this.setState({ copied: true }, () => { - this.timer = window.setTimeout(() => { - this.setState({ copied: false }); - this.timer = null; - }, switchDelay); - }); + this.setState({ copied: true }); }} + onTooltipHidden={() => this.setState({ copied: false })} > {this.state.copied ? clickTip : hoverTip} @@ -261,18 +263,10 @@ export class ClipboardCopy extends React.Component { - if (this.timer) { - window.clearTimeout(this.timer); - this.setState({ copied: false }); - } onCopy(event, this.state.text); - this.setState({ copied: true }, () => { - this.timer = window.setTimeout(() => { - this.setState({ copied: false }); - this.timer = null; - }, switchDelay); - }); + this.setState({ copied: true }); }} + onTooltipHidden={() => this.setState({ copied: false })} > {this.state.copied ? clickTip : hoverTip} diff --git a/packages/react-core/src/components/ClipboardCopy/ClipboardCopyButton.tsx b/packages/react-core/src/components/ClipboardCopy/ClipboardCopyButton.tsx index 8fe22538bea..17845e409e6 100644 --- a/packages/react-core/src/components/ClipboardCopy/ClipboardCopyButton.tsx +++ b/packages/react-core/src/components/ClipboardCopy/ClipboardCopyButton.tsx @@ -41,6 +41,8 @@ export interface ClipboardCopyButtonProps 'aria-label'?: string; /** Variant of the copy button */ variant?: 'control' | 'plain'; + /** Callback when tooltip's hide transition has finished executing */ + onTooltipHidden?: () => void; } export const ClipboardCopyButton: React.FunctionComponent = ({ @@ -54,6 +56,7 @@ export const ClipboardCopyButton: React.FunctionComponent {}, ...props }: ClipboardCopyButtonProps) => ( {children}} + onTooltipHidden={onTooltipHidden} > + + +
+`; + exports[`MultipleFileUploadStatusItem renders custom progress value/variant when passed 1`] = `
  • +
    + Progress value is 42%. +
    +
    + Progress value is 0%. +
    +
    + Progress value is 0%. +
    `; + +exports[`MultipleFileUploadStatusItem rendersdefault progressAriaLiveMessage when nothing is passed 1`] = ` + +
  • +
    + +
    +
    +
    + Progress value is 0%. +
    +
    + + +
    +
    + +
    +
    +
    +
    +
    + +
    +
  • +
    +`; diff --git a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md index f938c357399..c6c9474aa45 100644 --- a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md +++ b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md @@ -4,7 +4,6 @@ section: components cssPrefix: pf-c-multiple-file-upload propComponents: ['MultipleFileUpload', 'MultipleFileUploadMain', 'MultipleFileUploadStatus', 'MultipleFileUploadStatusItem'] -beta: true --- import UploadIcon from '@patternfly/react-icons/dist/esm/icons/upload-icon'; diff --git a/packages/react-core/src/components/NotificationDrawer/examples/NotificationDrawer.md b/packages/react-core/src/components/NotificationDrawer/examples/NotificationDrawer.md index a454feb4d77..ce8eba76fe5 100644 --- a/packages/react-core/src/components/NotificationDrawer/examples/NotificationDrawer.md +++ b/packages/react-core/src/components/NotificationDrawer/examples/NotificationDrawer.md @@ -14,7 +14,6 @@ propComponents: 'NotificationDrawerListItemBody', 'NotificationDrawerListItemHeader', ] -beta: true --- import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; diff --git a/packages/react-core/src/components/Pagination/OptionsToggle.tsx b/packages/react-core/src/components/Pagination/OptionsToggle.tsx index b95ea24c9cc..fdb923bc254 100644 --- a/packages/react-core/src/components/Pagination/OptionsToggle.tsx +++ b/packages/react-core/src/components/Pagination/OptionsToggle.tsx @@ -44,7 +44,6 @@ export interface OptionsToggleProps extends React.HTMLProps { widgetId?: string; } -let toggleId = 0; export const OptionsToggle: React.FunctionComponent = ({ itemsTitle = 'items', optionsToggle, @@ -95,7 +94,7 @@ export const OptionsToggle: React.FunctionComponent = ({ onToggle={onToggle} isDisabled={isDisabled || (itemCount && itemCount <= 0)} isOpen={isOpen} - id={`${widgetId}-toggle-${toggleId++}`} + {...(widgetId && { id: `${widgetId}-toggle` })} className={isDiv ? styles.optionsMenuToggleButton : toggleClasses} parentRef={parentRef} aria-haspopup="listbox" diff --git a/packages/react-core/src/components/Pagination/Pagination.tsx b/packages/react-core/src/components/Pagination/Pagination.tsx index 9aec19883ad..5596eece018 100644 --- a/packages/react-core/src/components/Pagination/Pagination.tsx +++ b/packages/react-core/src/components/Pagination/Pagination.tsx @@ -177,7 +177,6 @@ const handleInputWidth = (lastPage: number, node: HTMLDivElement) => { } }; -let paginationId = 0; export class Pagination extends React.Component { static displayName = 'Pagination'; paginationRef = React.createRef(); @@ -211,7 +210,7 @@ export class Pagination extends React.Component undefined, onPerPageSelect: () => undefined, onFirstClick: () => undefined, @@ -325,7 +324,7 @@ export class Pagination extends React.Component @@ -366,7 +365,7 @@ export class Pagination extends React.Component { const { asFragment } = render(); expect(asFragment()).toMatchSnapshot(); }); + + test('should not update generated options menu id on rerenders', () => { + const { rerender } = render(); + const id = screen.getByLabelText("test label").getAttribute("id"); + rerender(); + expect(screen.getByLabelText("test label")).toHaveAttribute("id", id); + }); }); describe('API', () => { diff --git a/packages/react-core/src/components/Pagination/__tests__/__snapshots__/Pagination.test.tsx.snap b/packages/react-core/src/components/Pagination/__tests__/__snapshots__/Pagination.test.tsx.snap index a89f6ec9472..cab728b9004 100644 --- a/packages/react-core/src/components/Pagination/__tests__/__snapshots__/Pagination.test.tsx.snap +++ b/packages/react-core/src/components/Pagination/__tests__/__snapshots__/Pagination.test.tsx.snap @@ -7,7 +7,7 @@ exports[`Pagination component render custom pagination toggle 1`] = ` data-ouia-component-id="OUIA-Generated-Pagination-top-12" data-ouia-component-type="PF4/Pagination" data-ouia-safe="true" - id="pagination-options-menu-13" + id="options-menu-top-pagination" style="--pf-c-pagination__nav-page-select--c-form-control--width-chars: 2;" >
    { { perPage={perPage} page={page} onSetPage={onSetPage} - widgetId="pagination-options-menu-top" + widgetId="compact-example" onPerPageSelect={onPerPageSelect} isCompact /> diff --git a/packages/react-core/src/components/Pagination/examples/PaginationDisabled.tsx b/packages/react-core/src/components/Pagination/examples/PaginationDisabled.tsx index a105a8d2d98..4073a9c2d8a 100644 --- a/packages/react-core/src/components/Pagination/examples/PaginationDisabled.tsx +++ b/packages/react-core/src/components/Pagination/examples/PaginationDisabled.tsx @@ -25,7 +25,7 @@ export const PaginationDisabled: React.FunctionComponent = () => { perPage={perPage} page={page} onSetPage={onSetPage} - widgetId="pagination-options-menu-top" + widgetId="disabled-example" onPerPageSelect={onPerPageSelect} isDisabled /> diff --git a/packages/react-core/src/components/Pagination/examples/PaginationIndeterminate.tsx b/packages/react-core/src/components/Pagination/examples/PaginationIndeterminate.tsx index 6b26fd0ac0d..e12a96aae61 100644 --- a/packages/react-core/src/components/Pagination/examples/PaginationIndeterminate.tsx +++ b/packages/react-core/src/components/Pagination/examples/PaginationIndeterminate.tsx @@ -30,7 +30,7 @@ export const PaginationIndeterminate: React.FunctionComponent = () => { many )} - widgetId="pagination-indeterminate" + widgetId="indeterminate-example" perPage={perPage} page={page} onSetPage={onSetPage} diff --git a/packages/react-core/src/components/Pagination/examples/PaginationNoItems.tsx b/packages/react-core/src/components/Pagination/examples/PaginationNoItems.tsx index 0b4fa6f94c8..d2a6157fb8b 100644 --- a/packages/react-core/src/components/Pagination/examples/PaginationNoItems.tsx +++ b/packages/react-core/src/components/Pagination/examples/PaginationNoItems.tsx @@ -25,7 +25,7 @@ export const PaginationNoItems: React.FunctionComponent = () => { perPage={perPage} page={page} onSetPage={onSetPage} - widgetId="pagination-options-menu-top" + widgetId="no-items-example" onPerPageSelect={onPerPageSelect} /> ); diff --git a/packages/react-core/src/components/Pagination/examples/PaginationOnePage.tsx b/packages/react-core/src/components/Pagination/examples/PaginationOnePage.tsx index ed8d11569e8..b1a7c94e903 100644 --- a/packages/react-core/src/components/Pagination/examples/PaginationOnePage.tsx +++ b/packages/react-core/src/components/Pagination/examples/PaginationOnePage.tsx @@ -25,7 +25,7 @@ export const PaginationOnePage: React.FunctionComponent = () => { perPage={perPage} page={page} onSetPage={onSetPage} - widgetId="pagination-options-menu-top" + widgetId="one-page-example" onPerPageSelect={onPerPageSelect} /> ); diff --git a/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx b/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx index 45affd06b1d..b5b32552647 100644 --- a/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx +++ b/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx @@ -33,7 +33,7 @@ export const PaginationSticky: React.FunctionComponent = () => { perPage={perPage} page={page} onSetPage={onSetPage} - widgetId="pagination-options-menu-top" + widgetId="sticky-example" onPerPageSelect={onPerPageSelect} isSticky > diff --git a/packages/react-core/src/components/Pagination/examples/PaginationTop.tsx b/packages/react-core/src/components/Pagination/examples/PaginationTop.tsx index fdd3c7891d3..3ff580ece15 100644 --- a/packages/react-core/src/components/Pagination/examples/PaginationTop.tsx +++ b/packages/react-core/src/components/Pagination/examples/PaginationTop.tsx @@ -25,7 +25,7 @@ export const PaginationTop: React.FunctionComponent = () => { perPage={perPage} page={page} onSetPage={onSetPage} - widgetId="pagination-options-menu-top" + widgetId="top-example" onPerPageSelect={onPerPageSelect} /> ); diff --git a/packages/react-core/src/components/Panel/examples/Panel.md b/packages/react-core/src/components/Panel/examples/Panel.md index 37b5c02ee03..a29324c00cc 100644 --- a/packages/react-core/src/components/Panel/examples/Panel.md +++ b/packages/react-core/src/components/Panel/examples/Panel.md @@ -3,7 +3,6 @@ id: Panel section: components cssPrefix: pf-c-panel propComponents: [Panel, PanelMain, PanelMainBody, PanelHeader, PanelFooter] -beta: true --- ## Examples diff --git a/packages/react-core/src/components/Popover/Popover.tsx b/packages/react-core/src/components/Popover/Popover.tsx index 12a8dfd91f4..4ee492261e2 100644 --- a/packages/react-core/src/components/Popover/Popover.tsx +++ b/packages/react-core/src/components/Popover/Popover.tsx @@ -38,11 +38,11 @@ export enum PopoverPosition { */ export interface PopoverProps { - /** @beta Text announced by screen reader when alert severity variant is set to indicate + /** Text announced by screen reader when alert severity variant is set to indicate * severity level. */ alertSeverityScreenReaderText?: string; - /** @beta Severity variants for an alert popover. This modifies the color of the header to + /** Severity variants for an alert popover. This modifies the color of the header to * match the severity. */ alertSeverityVariant?: 'default' | 'info' | 'warning' | 'success' | 'danger'; @@ -123,7 +123,7 @@ export interface PopoverProps { * popover, i.e. headerContent={hide => } */ headerContent?: React.ReactNode | ((hide: () => void) => React.ReactNode); - /** @beta Icon to be displayed in the popover header. **/ + /** Icon to be displayed in the popover header. **/ headerIcon?: React.ReactNode; /** Hides the popover when a click occurs outside (only works if isVisible is not controlled * by the user). @@ -247,8 +247,20 @@ export const Popover: React.FunctionComponent = ({ closeBtnAriaLabel = 'Close', showClose = true, distance = 25, - // For every initial starting position, there are 3 escape positions - flipBehavior = ['top', 'right', 'bottom', 'left', 'top', 'right', 'bottom'], + flipBehavior = [ + 'top', + 'bottom', + 'left', + 'right', + 'top-start', + 'top-end', + 'bottom-start', + 'bottom-end', + 'left-start', + 'left-end', + 'right-start', + 'right-end' + ], animationDuration = 300, id, withFocusTrap: propWithFocusTrap, diff --git a/packages/react-core/src/components/Popover/examples/Popover.md b/packages/react-core/src/components/Popover/examples/Popover.md index 11867adcf1d..ce89207bed0 100644 --- a/packages/react-core/src/components/Popover/examples/Popover.md +++ b/packages/react-core/src/components/Popover/examples/Popover.md @@ -58,10 +58,10 @@ Note: If you use the isVisible prop, either refer to the example above or if you ### Popover with icon in the title -```ts file="./PopoverWithIconInTheTitle.tsx" isBeta +```ts file="./PopoverWithIconInTheTitle.tsx" ``` ### Alert popover -```ts file="./PopoverAlert.tsx" isBeta +```ts file="./PopoverAlert.tsx" ``` diff --git a/packages/react-core/src/components/Select/Select.tsx b/packages/react-core/src/components/Select/Select.tsx index 4f9ad2d52e7..fc8393ac1db 100644 --- a/packages/react-core/src/components/Select/Select.tsx +++ b/packages/react-core/src/components/Select/Select.tsx @@ -265,7 +265,7 @@ export class Select extends React.Component - List item 1 - , - - List item 2 - , - List item 3 - ]; - - return ( - - {items} - - ); - } -} +```ts file="SimpleListBasic.tsx" ``` ### Grouped list -```js -import React from 'react'; -import { SimpleList, SimpleListItem, SimpleListGroup } from '@patternfly/react-core'; - -class SimpleListGroupDemo extends React.Component { - onSelect(selectedItem, selectedItemProps) { - console.log('new selection SimpleListGroupDemo', selectedItem, selectedItemProps); - } - - render() { - const group1Items = [ - - List item 1 - , - - List item 2 - , - List item 3, - List item 4 - ]; - - const group2Items = [ - List item 1, - - List item 2 - , - - List item 3 - , - List item 4 - ]; - - return ( - - - {group1Items} - - - {group2Items} - - - ); - } -} +```ts file="SimpleListGrouped.tsx" ``` ### Uncontrolled simple list -```js -import React from 'react'; -import { SimpleList, SimpleListItem } from '@patternfly/react-core'; - -class SimpleListUncontrolledDemo extends React.Component { - constructor(props) { - super(props); - this.state = { - activeItem: 0 - }; - this.onSelect = (selectedItem, selectedItemProps) => { - console.log('new selection SimpleListUncontrolledDemo', selectedItem, selectedItemProps); - this.setState({ activeItem: selectedItemProps.itemId }); - }; - } - - render() { - const { activeItem } = this.state; - const items = [ - - List item 1 - , - - List item 2 - , - - List item 3 - - ]; - - return ( - - {items} - - ); - } -} +```ts file="SimpleListUncontrolled.tsx" ``` + diff --git a/packages/react-core/src/components/SimpleList/examples/SimpleListBasic.tsx b/packages/react-core/src/components/SimpleList/examples/SimpleListBasic.tsx new file mode 100644 index 00000000000..130782a6d5d --- /dev/null +++ b/packages/react-core/src/components/SimpleList/examples/SimpleListBasic.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { SimpleList, SimpleListItem } from '@patternfly/react-core'; + +export const SimpleListBasic: React.FunctionComponent = () => { + const items = [ + + List item 1 + , + + List item 2 + , + List item 3 + ]; + + return {items}; +}; diff --git a/packages/react-core/src/components/SimpleList/examples/SimpleListGrouped.tsx b/packages/react-core/src/components/SimpleList/examples/SimpleListGrouped.tsx new file mode 100644 index 00000000000..25e5f35d594 --- /dev/null +++ b/packages/react-core/src/components/SimpleList/examples/SimpleListGrouped.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { SimpleList, SimpleListItem, SimpleListGroup } from '@patternfly/react-core'; + +export const SimpleListGrouped: React.FunctionComponent = () => { + const group1Items = [ + + List item 1 + , + List item 2, + List item 3, + List item 4 + ]; + + const group2Items = [ + List item 1, + + List item 2 + , + + List item 3 + , + List item 4 + ]; + + return ( + + + {group1Items} + + + {group2Items} + + + ); +}; diff --git a/packages/react-core/src/components/SimpleList/examples/SimpleListUncontrolled.tsx b/packages/react-core/src/components/SimpleList/examples/SimpleListUncontrolled.tsx new file mode 100644 index 00000000000..63ed0cc6dac --- /dev/null +++ b/packages/react-core/src/components/SimpleList/examples/SimpleListUncontrolled.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { SimpleList, SimpleListItem, SimpleListItemProps } from '@patternfly/react-core'; + +export const SimpleListUncontrolled: React.FunctionComponent = () => { + const [activeItem, setActiveItem] = React.useState(0); + + const onSelect = ( + selectedItem: React.RefObject | React.RefObject, + selectedItemProps: SimpleListItemProps + ) => { + setActiveItem(selectedItemProps.itemId as number); + }; + + const items = [ + + List item 1 + , + + List item 2 + , + + List item 3 + + ]; + + return ( + + {items} + + ); +}; diff --git a/packages/react-core/src/components/Slider/examples/Slider.md b/packages/react-core/src/components/Slider/examples/Slider.md index 357f33f1802..d99a2c82038 100644 --- a/packages/react-core/src/components/Slider/examples/Slider.md +++ b/packages/react-core/src/components/Slider/examples/Slider.md @@ -3,7 +3,6 @@ id: Slider section: components cssPrefix: pf-c-slider propComponents: ['Slider', 'SliderStepObject'] -beta: true --- import { Slider, Button, Text, TextVariants } from '@patternfly/react-core'; diff --git a/packages/react-core/src/components/TextArea/__tests__/TextArea.test.tsx b/packages/react-core/src/components/TextArea/__tests__/TextArea.test.tsx index b8d4e2fe54c..eea71ff8ff3 100644 --- a/packages/react-core/src/components/TextArea/__tests__/TextArea.test.tsx +++ b/packages/react-core/src/components/TextArea/__tests__/TextArea.test.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { TextArea, TextAreaBase } from '../TextArea'; +import { TextArea } from '../TextArea'; import { ValidatedOptions } from '../../../helpers/constants'; const props = { @@ -11,116 +11,132 @@ const props = { value: 'test textarea' }; -describe('TextArea', () => { - test('textarea passes value and event to onChange handler', async () => { - const user = userEvent.setup(); - - render(); - - await user.type(screen.getByLabelText('test textarea'), 'a'); - expect(props.onChange).toHaveBeenCalledWith('a', expect.any(Object)); - }); - - test('simple text area', () => { - const { asFragment } = render( - -`; - -exports[`TextArea disabled text area using isDisabled 1`] = ` - - - -`; - -exports[`TextArea horizontally resizable text area 1`] = ` - - - -`; - -exports[`TextArea read only text area using default readOnlyVariant 1`] = ` - - - -`; - -exports[`TextArea read only text area using isReadOnly 1`] = ` - - - -`; - -exports[`TextArea read only text area using plain readOnlyVariant 1`] = ` - - - -`; - -exports[`TextArea read only text area using readOnly 1`] = ` - - - -`; - -exports[`TextArea simple text area 1`] = ` - - - -`; - -exports[`TextArea validated text area error 1`] = ` - - - -`; - -exports[`TextArea vertically resizable text area 1`] = ` - - + style="--pf-c-form-control--textarea--Height: 6px;" + /> `; diff --git a/packages/react-core/src/components/TextArea/examples/TextArea.md b/packages/react-core/src/components/TextArea/examples/TextArea.md index d520d8b9050..235dfc24d63 100644 --- a/packages/react-core/src/components/TextArea/examples/TextArea.md +++ b/packages/react-core/src/components/TextArea/examples/TextArea.md @@ -266,7 +266,7 @@ import { TextArea } from '@patternfly/react-core'; **Note:** The icons for the success, invalid, calendar, etc. variations in form control elements are applied as background images to the form element. By default, the image URLs for these icons are data URIs. However, there may be cases where data URIs are not ideal, such as in an application with a content security policy that disallows data URIs for security reasons. The `isIconSprite` variation changes the icon source to an external SVG file that serves as a sprite for all of the supported icons. -```js isBeta +```js import React from 'react'; import { TextArea } from '@patternfly/react-core'; diff --git a/packages/react-core/src/components/TextInput/examples/TextInput.md b/packages/react-core/src/components/TextInput/examples/TextInput.md index 6702d09ce38..74c5a1fb85e 100644 --- a/packages/react-core/src/components/TextInput/examples/TextInput.md +++ b/packages/react-core/src/components/TextInput/examples/TextInput.md @@ -46,5 +46,5 @@ propComponents: ['TextInput'] **Note:** The icons for the success, invalid, calendar, etc. variations in form control elements are applied as background images to the form element. By default, the image URLs for these icons are data URIs. However, there may be cases where data URIs are not ideal, such as in an application with a content security policy that disallows data URIs for security reasons. The `isIconSprite` variation changes the icon source to an external SVG file that serves as a sprite for all of the supported icons. -```ts isBeta file="./TextInputIconSprite.tsx" +```ts file="./TextInputIconSprite.tsx" ``` diff --git a/packages/react-core/src/components/Timestamp/Timestamp.tsx b/packages/react-core/src/components/Timestamp/Timestamp.tsx index da10ddb2483..b1e6a8c0366 100644 --- a/packages/react-core/src/components/Timestamp/Timestamp.tsx +++ b/packages/react-core/src/components/Timestamp/Timestamp.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import styles from '@patternfly/react-styles/css/components/Timestamp/timestamp'; import { css } from '@patternfly/react-styles'; import { Tooltip } from '../Tooltip'; +import { isValidDate } from '../../helpers/datetimeUtils'; export enum TimestampFormat { full = 'full', @@ -78,7 +79,7 @@ export const Timestamp: React.FunctionComponent = ({ children, className, customFormat, - date: dateProp = new Date(), + date: dateProp, dateFormat, displaySuffix = '', is12Hour, @@ -87,6 +88,24 @@ export const Timestamp: React.FunctionComponent = ({ tooltip, ...props }: TimestampProps) => { + const [date, setDate] = React.useState(() => { + const initDate = new Date(dateProp); + if (isValidDate(initDate)) { + return initDate; + } + + return new Date(); + }); + + React.useEffect(() => { + const dateFromProp = new Date(dateProp); + if (isValidDate(dateFromProp) && dateFromProp.toString() !== new Date(date).toString()) { + setDate(dateFromProp); + } else if (!dateProp) { + setDate(new Date()); + } + }, [dateProp]); + const hasTimeFormat = timeFormat && !customFormat; const formatOptions = { ...(dateFormat && !customFormat && { dateStyle: dateFormat }), @@ -94,7 +113,7 @@ export const Timestamp: React.FunctionComponent = ({ ...(is12Hour !== undefined && { hour12: is12Hour }) }; - const dateAsLocaleString = new Date(dateProp).toLocaleString(locale, { + const dateAsLocaleString = new Date(date).toLocaleString(locale, { ...formatOptions, ...(hasTimeFormat && { timeStyle: timeFormat }) }); @@ -102,19 +121,21 @@ export const Timestamp: React.FunctionComponent = ({ const utcTimeFormat = timeFormat !== 'short' ? 'medium' : 'short'; const convertToUTCString = (date: Date) => new Date(date).toUTCString().slice(0, -3); - const utcDateString = new Date(convertToUTCString(dateProp)).toLocaleString(locale, { + const utcDateString = new Date(convertToUTCString(date)).toLocaleString(locale, { ...formatOptions, ...(hasTimeFormat && { timeStyle: utcTimeFormat }) }); const defaultTooltipContent = `${utcDateString}${tooltip?.suffix ? ' ' + tooltip.suffix : ' UTC'}`; + const { dateTime, ...propsWithoutDateTime } = props; + const timestamp = ( - diff --git a/packages/react-core/src/components/Timestamp/__tests__/Timestamp.test.tsx b/packages/react-core/src/components/Timestamp/__tests__/Timestamp.test.tsx index def82f4a8fe..482378b2420 100644 --- a/packages/react-core/src/components/Timestamp/__tests__/Timestamp.test.tsx +++ b/packages/react-core/src/components/Timestamp/__tests__/Timestamp.test.tsx @@ -36,12 +36,31 @@ test('Renders with current date by default with default formatting', () => { expect(screen.getByText(new Date().toLocaleString())).toBeInTheDocument(); }); +test('Renders with correct datetime attribute with current date by default', () => { + render(); + // Because there could be a .001 ms difference in the expected and received datetime value, + // we want an ISO value without the ms to expect as the datetime value. + const isoDateWithoutMS = new Date().toISOString().split('.')[0]; + + expect(screen.getByText(new Date().toLocaleString())).toHaveAttribute( + 'datetime', + expect.stringMatching(isoDateWithoutMS) + ); +}); + test('Renders passed in date with default formatting', () => { render(); expect(screen.getByText('1/1/2022, 12:00:00 AM')).toBeInTheDocument(); }); +test('Renders with correct datetime attribute when date is passed in', () => { + const passedDate = new Date(2022, 0, 1); + render(); + + expect(screen.getByText('1/1/2022, 12:00:00 AM')).toHaveAttribute('datetime', passedDate.toISOString()); +}); + test('Renders with custom formatting when dateFormat and timeFormat are passed in', () => { render( @@ -51,7 +70,7 @@ test('Renders with custom formatting when dateFormat and timeFormat are passed i }); test('Renders with only date when dateFormat is passed in', () => { - render(); + render(); expect(screen.getByText('Saturday, January 1, 2022')).toBeInTheDocument(); }); @@ -152,9 +171,7 @@ test('Renders with pf-m-help-text class when tooltip is passed in with custom va }); test('Renders with default tooltip content for default variant', () => { - render( - - ); + render(); expect(screen.getByText('1/1/2022, 5:00:00 AM UTC')).toBeInTheDocument(); }); @@ -162,7 +179,7 @@ test('Renders with default tooltip content for default variant', () => { test('Renders with custom tooltip suffix for default variant', () => { render( ); diff --git a/packages/react-core/src/components/Timestamp/__tests__/__snapshots__/Timestamp.test.tsx.snap b/packages/react-core/src/components/Timestamp/__tests__/__snapshots__/Timestamp.test.tsx.snap index 57b1ddd0047..6eaa5d032d2 100644 --- a/packages/react-core/src/components/Timestamp/__tests__/__snapshots__/Timestamp.test.tsx.snap +++ b/packages/react-core/src/components/Timestamp/__tests__/__snapshots__/Timestamp.test.tsx.snap @@ -4,7 +4,6 @@ exports[`Matches snapshot 1`] = `