From 69d5937fd5fa56ace7543a740ba253bdc851009e Mon Sep 17 00:00:00 2001 From: Nicole Thoen Date: Fri, 21 Oct 2022 08:55:40 -0400 Subject: [PATCH] fix(CodeEditor): use codeEditorControls and clean up overall (#7931) * fix(CodeEditor): use codeEditorControls and clean up overall * fix lint errors * use better variable names * clean up per PR comments * add back useCallback * clean up * clean up * fix lint errors * add console warnings when using deprecated props * fix lint errors * update warning messages * fix lint again --- .../src/components/CodeEditor/CodeEditor.tsx | 102 ++++++++---------- .../CodeEditor/CodeEditorControl.tsx | 67 +++++++++--- .../examples/CodeEditorCustomControl.tsx | 2 +- .../examples/CodeEditorShortcutMainHeader.tsx | 19 ++-- .../ClipboardCopy/ClipboardCopy.tsx | 47 +++----- .../ClipboardCopy/ClipboardCopyButton.tsx | 4 + .../CodeBlock/examples/CodeBlockBasic.tsx | 11 +- .../examples/CodeBlockExpandable.tsx | 11 +- .../src/components/Tooltip/Tooltip.tsx | 25 ++++- 9 files changed, 158 insertions(+), 130 deletions(-) diff --git a/packages/react-code-editor/src/components/CodeEditor/CodeEditor.tsx b/packages/react-code-editor/src/components/CodeEditor/CodeEditor.tsx index ff4dbeb36ef..ed455032582 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 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} >