diff --git a/packages/eui/changelogs/upcoming/8758.md b/packages/eui/changelogs/upcoming/8758.md new file mode 100644 index 00000000000..5c6c8f08e75 --- /dev/null +++ b/packages/eui/changelogs/upcoming/8758.md @@ -0,0 +1,3 @@ +**Breaking changes** + +- Added `tooltipProps` to `EuiCopy` which replaces spreading all props to `EuiToolTip` diff --git a/packages/eui/src/components/copy/copy.test.tsx b/packages/eui/src/components/copy/copy.test.tsx index 3a0c1bc8ae2..bb7af0a1de5 100644 --- a/packages/eui/src/components/copy/copy.test.tsx +++ b/packages/eui/src/components/copy/copy.test.tsx @@ -7,13 +7,33 @@ */ import React from 'react'; -import { shallow } from 'enzyme'; -import { render } from '../../test/rtl'; +import { fireEvent } from '@testing-library/react'; +import { + waitForEuiToolTipVisible, + waitForEuiToolTipHidden, + render, +} from '../../test/rtl'; import { requiredProps } from '../../test'; import { EuiCopy } from './copy'; describe('EuiCopy', () => { + const originalExecCommand = document.execCommand; + + beforeAll(() => { + Object.defineProperty(document, 'execCommand', { + value: jest.fn(() => true), + writable: true, + }); + }); + + afterAll(() => { + Object.defineProperty(document, 'execCommand', { + value: originalExecCommand, + writable: true, + }); + }); + it('renders', () => { const { container } = render( @@ -24,23 +44,76 @@ describe('EuiCopy', () => { }); describe('props', () => { - test('beforeMessage', () => { - const component = shallow( - - {(copy) => } + it('beforeMessage', async () => { + const beforeMessage = 'copy this'; + const { getByRole, getByText } = render( + + {() => ( + + )} + + ); + // Simulate mouse over to show the tooltip + fireEvent.mouseOver(getByRole('button')); + await waitForEuiToolTipVisible(); + // The beforeMessage should be shown in the tooltip + expect(getByText(beforeMessage)).toBeInTheDocument(); + fireEvent.mouseOut(getByRole('button')); + await waitForEuiToolTipHidden(); + }); + + it('afterMessage', async () => { + const afterMessage = 'successfully copied'; + const { getByRole, getByText } = render( + + {(copy) => ( + + )} ); - expect(component.state('tooltipText')).toBe('copy this'); + + // Simulate a click to copy the text + fireEvent.click(getByRole('button')); + fireEvent.mouseOver(getByRole('button')); + await waitForEuiToolTipVisible(); + // The afterMessage should be shown after the copy action + expect(getByText(afterMessage)).toBeInTheDocument(); + fireEvent.mouseOut(getByRole('button')); + await waitForEuiToolTipHidden(); }); - test('afterMessage', () => { - const component = shallow( - - {(copy) => } + it('tooltipProps', async () => { + const tooltipProps = { + 'data-test-subj': 'customTooltip', + className: 'myTooltipClass', + }; + const beforeMessage = 'copy this'; + const { getByRole, getByTestSubject } = render( + + {() => ( + + )} ); - const instance = component.instance(); - expect(instance.props.afterMessage).toBe('successfuly copied'); + // Simulate mouse over to show the tooltip + fireEvent.mouseOver(getByRole('button')); + await waitForEuiToolTipVisible(); + // The tooltip portalled, so search the global document + const tooltip = getByTestSubject('customTooltip'); + expect(tooltip).toBeInTheDocument(); + expect(tooltip?.className).toContain('myTooltipClass'); + fireEvent.mouseOut(getByRole('button')); + await waitForEuiToolTipHidden(); }); }); }); diff --git a/packages/eui/src/components/copy/copy.tsx b/packages/eui/src/components/copy/copy.tsx index a435cf87a5c..a869694a552 100644 --- a/packages/eui/src/components/copy/copy.tsx +++ b/packages/eui/src/components/copy/copy.tsx @@ -11,9 +11,7 @@ import { CommonProps } from '../common'; import { copyToClipboard } from '../../services'; import { EuiToolTip, EuiToolTipProps } from '../tool_tip'; -export interface EuiCopyProps - extends CommonProps, - Partial> { +export interface EuiCopyProps extends CommonProps { /** * Text that will be copied to clipboard when copy function is executed. */ @@ -32,6 +30,12 @@ export interface EuiCopyProps * Use your own logic to create the component that users interact with when triggering copy. */ children(copy: () => void): ReactElement; + /** + * Optional props to pass to the EuiToolTip component. + */ + tooltipProps?: Partial< + Omit + >; } interface EuiCopyState { @@ -67,8 +71,7 @@ export class EuiCopy extends Component { }; render() { - const { children, textToCopy, beforeMessage, afterMessage, ...rest } = - this.props; + const { children, tooltipProps } = this.props; return ( // See `src/components/tool_tip/tool_tip.js` for explanation of below eslint-disable @@ -76,7 +79,7 @@ export class EuiCopy extends Component { {children(this.copy)} diff --git a/packages/website/docs/components/display/icons/index.mdx b/packages/website/docs/components/display/icons/index.mdx index 0e52364152c..93167f21759 100644 --- a/packages/website/docs/components/display/icons/index.mdx +++ b/packages/website/docs/components/display/icons/index.mdx @@ -36,7 +36,7 @@ import { iconSizes, iconSizesText } from './icon_sizes'; {iconSizes.map((size, index) => ( - + {(copy) => (  {' '} @@ -69,7 +69,7 @@ import { iconColors } from './icon_colors.ts' {iconColors.map((color) => ( - + {(copy) => { const panel = ( @@ -107,7 +107,7 @@ import { iconTypes } from './icon_types'; {iconTypes.map((iconType) => ( - + {(copy) => (  {' '} @@ -134,7 +134,7 @@ import { iconTypesEditor } from './icon_types_editor'; {iconTypes.map((iconType) => ( - + {(copy) => (  {' '} @@ -196,7 +196,7 @@ import { iconTypesLogos } from './icon_types_logos'; {iconTypes.map((iconType) => ( - + {(copy) => ( {iconTypes.map((iconType) => ( - + {(copy) => (  {' '} @@ -268,7 +268,7 @@ import { iconTypesML } from './icon_types_ml'; {iconTypes.map((iconType) => ( - + {(copy) => (  {' '} @@ -299,7 +299,7 @@ import { iconTypesTokens } from './icon_types_tokens'; {iconTypes.map((iconType) => ( - + {(copy) => (  {' '} diff --git a/packages/website/docs/components/navigation/buttons/guidelines_context_menu.tsx b/packages/website/docs/components/navigation/buttons/guidelines_context_menu.tsx index 96b2b8c5f6c..1f6d845a8ea 100644 --- a/packages/website/docs/components/navigation/buttons/guidelines_context_menu.tsx +++ b/packages/website/docs/components/navigation/buttons/guidelines_context_menu.tsx @@ -24,7 +24,10 @@ export default () => { }; const items = [ - + {(copy) => ( Copy diff --git a/packages/website/docs/components/navigation/context-menu.mdx b/packages/website/docs/components/navigation/context-menu.mdx index d6f8a005c09..c00e66e2649 100644 --- a/packages/website/docs/components/navigation/context-menu.mdx +++ b/packages/website/docs/components/navigation/context-menu.mdx @@ -199,7 +199,7 @@ export default () => { }; const items = [ - + {(copy) => ( Copy