From 9cb1e61fbeef0e6a8018ee2fa98094a0b6a3cf61 Mon Sep 17 00:00:00 2001 From: Weronika Olejniczak Date: Fri, 22 Nov 2024 12:37:57 +0100 Subject: [PATCH 1/4] feat(code_block): allow for a custom copy button aria-label closes #8004 --- packages/eui/changelogs/upcoming/8176.md | 3 ++ .../code_block_custom_copy_aria_label.tsx | 13 +++++ .../src-docs/src/views/code/code_example.js | 19 +++++++ .../__snapshots__/code_block.test.tsx.snap | 53 +++++++++++++++++++ .../src/components/code/code_block.test.tsx | 13 +++++ .../eui/src/components/code/code_block.tsx | 7 +++ .../src/components/code/code_block_copy.tsx | 6 ++- .../components/editors_and_syntax/code.mdx | 14 +++++ 8 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 packages/eui/changelogs/upcoming/8176.md create mode 100644 packages/eui/src-docs/src/views/code/code_block_custom_copy_aria_label.tsx diff --git a/packages/eui/changelogs/upcoming/8176.md b/packages/eui/changelogs/upcoming/8176.md new file mode 100644 index 000000000000..1c77567106bc --- /dev/null +++ b/packages/eui/changelogs/upcoming/8176.md @@ -0,0 +1,3 @@ +**Accessibility** + +- Allowed to pass a custom `aria-label` for the Copy button in the EuiCodeBlock component. diff --git a/packages/eui/src-docs/src/views/code/code_block_custom_copy_aria_label.tsx b/packages/eui/src-docs/src/views/code/code_block_custom_copy_aria_label.tsx new file mode 100644 index 000000000000..08fe8f170335 --- /dev/null +++ b/packages/eui/src-docs/src/views/code/code_block_custom_copy_aria_label.tsx @@ -0,0 +1,13 @@ +import React from 'react'; + +import { EuiCodeBlock } from '../../../../src/components'; + +const htmlCode = ` +

Hello world!

+

Lorem ipsum dolor sit amet.

`; + +export default () => ( + + {htmlCode} + +); diff --git a/packages/eui/src-docs/src/views/code/code_example.js b/packages/eui/src-docs/src/views/code/code_example.js index 7fbe9103dcf3..81160cc3e044 100644 --- a/packages/eui/src-docs/src/views/code/code_example.js +++ b/packages/eui/src-docs/src/views/code/code_example.js @@ -32,6 +32,12 @@ const codeBlockCopySnippet = ` `; +import CodeBlockCustomCopyAriaLabel from './code_block_custom_copy_aria_label'; +const codeBlockCustomCopyAriaLabelSnippet = ` +{...} + +`; + import CodeBlockOverflow from './code_block_overflow'; const codeBlockOverflowSource = require('!!raw-loader!./code_block_overflow'); const codeBlockOverflowSnippet = ` @@ -177,6 +183,19 @@ export const CodeExample = { props: { EuiCodeBlock }, demo: , }, + { + text: ( +

+ You can specify a custom aria label for the Copy button using the + customCopyAriaLabel prop. It works in conjunction + with the + isCopyable prop. +

+ ), + snippet: codeBlockCustomCopyAriaLabelSnippet, + props: { EuiCodeBlock }, + demo: , + }, { text: (

diff --git a/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap b/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap index b7f00f4ae156..42496fb60b05 100644 --- a/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap +++ b/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap @@ -382,6 +382,59 @@ exports[`EuiCodeBlock line numbers renders line numbers with a start value 1`] = `; +exports[`EuiCodeBlock props customCopyAriaLabel is rendered 1`] = ` +

+
+    
+      
+        var some = 'code';
+
+      
+      
+        console.log(some);
+      
+    
+  
+
+
+ + + +
+
+
+`; + exports[`EuiCodeBlock props fontSize l is rendered 1`] = `
{ }); }); + describe('customCopyAriaLabel', () => { + it('is rendered', () => { + const customLabel = 'Copy this code'; + const { container } = render( + + {code} + + ); + + expect(container.firstChild).toMatchSnapshot(); + }); + }); + describe('overflowHeight', () => { it('is rendered', () => { const { container } = render( diff --git a/packages/eui/src/components/code/code_block.tsx b/packages/eui/src/components/code/code_block.tsx index 145a3031a4b7..aeb49a177b75 100644 --- a/packages/eui/src/components/code/code_block.tsx +++ b/packages/eui/src/components/code/code_block.tsx @@ -87,6 +87,11 @@ export type EuiCodeBlockProps = EuiCodeSharedProps & { */ isCopyable?: boolean; + /** + * Customizes the aria-label for the copy button. + */ + customCopyAriaLabel?: string; + /** * Displays line numbers. * Optionally accepts a configuration object for setting the starting number, @@ -118,6 +123,7 @@ export const EuiCodeBlock: FunctionComponent = ({ paddingSize = 'l', fontSize = 's', isCopyable = false, + customCopyAriaLabel, whiteSpace = 'pre-wrap', children, className, @@ -159,6 +165,7 @@ export const EuiCodeBlock: FunctionComponent = ({ ); const { innerTextRef, copyButton } = useCopy({ + customCopyAriaLabel, isCopyable, isVirtualized, children, diff --git a/packages/eui/src/components/code/code_block_copy.tsx b/packages/eui/src/components/code/code_block_copy.tsx index 6e87d11bd0c4..af9641f0d0db 100644 --- a/packages/eui/src/components/code/code_block_copy.tsx +++ b/packages/eui/src/components/code/code_block_copy.tsx @@ -17,10 +17,12 @@ import { NEW_LINE_REGEX_GLOBAL } from './utils'; * Hook that returns copy-related state/logic/utils */ export const useCopy = ({ + customCopyAriaLabel, isCopyable, isVirtualized, children, }: { + customCopyAriaLabel?: string; isCopyable: boolean; isVirtualized: boolean; children: ReactNode; @@ -52,14 +54,14 @@ export const useCopy = ({ onClick={copy} iconType="copyClipboard" color="text" - aria-label={copyAriaLabel} + aria-label={customCopyAriaLabel || copyAriaLabel} data-test-subj="euiCodeBlockCopy" /> )}
) : null; - }, [showCopyButton, textToCopy, copyAriaLabel]); + }, [copyAriaLabel, customCopyAriaLabel, showCopyButton, textToCopy]); return { innerTextRef, copyButton }; }; diff --git a/packages/website/docs/components/editors_and_syntax/code.mdx b/packages/website/docs/components/editors_and_syntax/code.mdx index da00df04004d..01d9aad2a386 100644 --- a/packages/website/docs/components/editors_and_syntax/code.mdx +++ b/packages/website/docs/components/editors_and_syntax/code.mdx @@ -93,6 +93,20 @@ export default () => ( ``` +You can specify a custom aria label for the Copy button using the `customCopyAriaLabel` prop. It works in conjunction with the `isCopyable` prop. + +```tsx +import React from 'react'; +import { EuiCodeBlock } from '@elastic/eui'; + +export default () => ( + + {...} + +); + +``` + For long content, you can set an `overflowHeight` which will scroll if the text exceeds that height, and allows users to view the code in fullscreen mode. ```tsx interactive From 0ccfd5048c591ca90d68c6710df6e391f9abd127 Mon Sep 17 00:00:00 2001 From: Weronika Olejniczak Date: Fri, 22 Nov 2024 19:13:50 +0100 Subject: [PATCH 2/4] refactor(code_block): rename copyAriaLabel and remove docs --- .../code_block_custom_copy_aria_label.tsx | 13 ------------- .../src-docs/src/views/code/code_example.js | 19 ------------------- .../__snapshots__/code_block.test.tsx.snap | 2 +- .../src/components/code/code_block.test.tsx | 4 ++-- .../eui/src/components/code/code_block.tsx | 8 +++++--- .../src/components/code/code_block_copy.tsx | 10 +++++----- .../components/editors_and_syntax/code.mdx | 14 -------------- 7 files changed, 13 insertions(+), 57 deletions(-) delete mode 100644 packages/eui/src-docs/src/views/code/code_block_custom_copy_aria_label.tsx diff --git a/packages/eui/src-docs/src/views/code/code_block_custom_copy_aria_label.tsx b/packages/eui/src-docs/src/views/code/code_block_custom_copy_aria_label.tsx deleted file mode 100644 index 08fe8f170335..000000000000 --- a/packages/eui/src-docs/src/views/code/code_block_custom_copy_aria_label.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; - -import { EuiCodeBlock } from '../../../../src/components'; - -const htmlCode = ` -

Hello world!

-

Lorem ipsum dolor sit amet.

`; - -export default () => ( - - {htmlCode} - -); diff --git a/packages/eui/src-docs/src/views/code/code_example.js b/packages/eui/src-docs/src/views/code/code_example.js index 81160cc3e044..7fbe9103dcf3 100644 --- a/packages/eui/src-docs/src/views/code/code_example.js +++ b/packages/eui/src-docs/src/views/code/code_example.js @@ -32,12 +32,6 @@ const codeBlockCopySnippet = ` `; -import CodeBlockCustomCopyAriaLabel from './code_block_custom_copy_aria_label'; -const codeBlockCustomCopyAriaLabelSnippet = ` -{...} - -`; - import CodeBlockOverflow from './code_block_overflow'; const codeBlockOverflowSource = require('!!raw-loader!./code_block_overflow'); const codeBlockOverflowSnippet = ` @@ -183,19 +177,6 @@ export const CodeExample = { props: { EuiCodeBlock }, demo: , }, - { - text: ( -

- You can specify a custom aria label for the Copy button using the - customCopyAriaLabel prop. It works in conjunction - with the - isCopyable prop. -

- ), - snippet: codeBlockCustomCopyAriaLabelSnippet, - props: { EuiCodeBlock }, - demo: , - }, { text: (

diff --git a/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap b/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap index 42496fb60b05..d2637f74d987 100644 --- a/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap +++ b/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap @@ -382,7 +382,7 @@ exports[`EuiCodeBlock line numbers renders line numbers with a start value 1`] = `; -exports[`EuiCodeBlock props customCopyAriaLabel is rendered 1`] = ` +exports[`EuiCodeBlock props copyAriaLabel is rendered 1`] = `

diff --git a/packages/eui/src/components/code/code_block.test.tsx b/packages/eui/src/components/code/code_block.test.tsx index 5f0c2e840e4b..a8da5cba2525 100644 --- a/packages/eui/src/components/code/code_block.test.tsx +++ b/packages/eui/src/components/code/code_block.test.tsx @@ -46,11 +46,11 @@ describe('EuiCodeBlock', () => { }); }); - describe('customCopyAriaLabel', () => { + describe('copyAriaLabel', () => { it('is rendered', () => { const customLabel = 'Copy this code'; const { container } = render( - + {code} ); diff --git a/packages/eui/src/components/code/code_block.tsx b/packages/eui/src/components/code/code_block.tsx index aeb49a177b75..2a272a3583e7 100644 --- a/packages/eui/src/components/code/code_block.tsx +++ b/packages/eui/src/components/code/code_block.tsx @@ -89,8 +89,10 @@ export type EuiCodeBlockProps = EuiCodeSharedProps & { /** * Customizes the aria-label for the copy button. + * + * @default 'Copy' */ - customCopyAriaLabel?: string; + copyAriaLabel?: string; /** * Displays line numbers. @@ -123,7 +125,7 @@ export const EuiCodeBlock: FunctionComponent = ({ paddingSize = 'l', fontSize = 's', isCopyable = false, - customCopyAriaLabel, + copyAriaLabel, whiteSpace = 'pre-wrap', children, className, @@ -165,7 +167,7 @@ export const EuiCodeBlock: FunctionComponent = ({ ); const { innerTextRef, copyButton } = useCopy({ - customCopyAriaLabel, + copyAriaLabel, isCopyable, isVirtualized, children, diff --git a/packages/eui/src/components/code/code_block_copy.tsx b/packages/eui/src/components/code/code_block_copy.tsx index af9641f0d0db..bd8cac1f0fa7 100644 --- a/packages/eui/src/components/code/code_block_copy.tsx +++ b/packages/eui/src/components/code/code_block_copy.tsx @@ -17,12 +17,12 @@ import { NEW_LINE_REGEX_GLOBAL } from './utils'; * Hook that returns copy-related state/logic/utils */ export const useCopy = ({ - customCopyAriaLabel, + copyAriaLabel, isCopyable, isVirtualized, children, }: { - customCopyAriaLabel?: string; + copyAriaLabel?: string; isCopyable: boolean; isVirtualized: boolean; children: ReactNode; @@ -43,7 +43,7 @@ export const useCopy = ({ const showCopyButton = isCopyable && textToCopy; - const copyAriaLabel = useEuiI18n('euiCodeBlockCopy.copy', 'Copy'); + const copyDefaultAriaLabel = useEuiI18n('euiCodeBlockCopy.copy', 'Copy'); const copyButton = useMemo(() => { return showCopyButton ? ( @@ -54,14 +54,14 @@ export const useCopy = ({ onClick={copy} iconType="copyClipboard" color="text" - aria-label={customCopyAriaLabel || copyAriaLabel} + aria-label={copyAriaLabel || copyDefaultAriaLabel} data-test-subj="euiCodeBlockCopy" /> )}
) : null; - }, [copyAriaLabel, customCopyAriaLabel, showCopyButton, textToCopy]); + }, [copyAriaLabel, copyDefaultAriaLabel, showCopyButton, textToCopy]); return { innerTextRef, copyButton }; }; diff --git a/packages/website/docs/components/editors_and_syntax/code.mdx b/packages/website/docs/components/editors_and_syntax/code.mdx index 01d9aad2a386..da00df04004d 100644 --- a/packages/website/docs/components/editors_and_syntax/code.mdx +++ b/packages/website/docs/components/editors_and_syntax/code.mdx @@ -93,20 +93,6 @@ export default () => ( ``` -You can specify a custom aria label for the Copy button using the `customCopyAriaLabel` prop. It works in conjunction with the `isCopyable` prop. - -```tsx -import React from 'react'; -import { EuiCodeBlock } from '@elastic/eui'; - -export default () => ( - - {...} - -); - -``` - For long content, you can set an `overflowHeight` which will scroll if the text exceeds that height, and allows users to view the code in fullscreen mode. ```tsx interactive From dbeb3be612d16d9d3209295eecb416fbea88bcc5 Mon Sep 17 00:00:00 2001 From: Weronika Olejniczak Date: Fri, 22 Nov 2024 19:15:37 +0100 Subject: [PATCH 3/4] chore: update the changelog --- packages/eui/changelogs/upcoming/8176.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/eui/changelogs/upcoming/8176.md b/packages/eui/changelogs/upcoming/8176.md index 1c77567106bc..65b0619dcf8c 100644 --- a/packages/eui/changelogs/upcoming/8176.md +++ b/packages/eui/changelogs/upcoming/8176.md @@ -1,3 +1,3 @@ **Accessibility** -- Allowed to pass a custom `aria-label` for the Copy button in the EuiCodeBlock component. +- Updated `EuiCodeBlock` with a new `copyAriaLabel` prop, which allows setting a custom screen reader label on the copy button. From acc44d312bfd3b1dd593ad961c48b76812670bf3 Mon Sep 17 00:00:00 2001 From: Weronika Olejniczak Date: Mon, 25 Nov 2024 12:19:25 +0100 Subject: [PATCH 4/4] refactor(code_block): improve the copyAriaLabel test case - remove the wrapping describe, - update the assertion to toHaveAttribute --- .../__snapshots__/code_block.test.tsx.snap | 53 ------------------- .../src/components/code/code_block.test.tsx | 21 ++++---- 2 files changed, 11 insertions(+), 63 deletions(-) diff --git a/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap b/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap index d2637f74d987..b7f00f4ae156 100644 --- a/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap +++ b/packages/eui/src/components/code/__snapshots__/code_block.test.tsx.snap @@ -382,59 +382,6 @@ exports[`EuiCodeBlock line numbers renders line numbers with a start value 1`] = `; -exports[`EuiCodeBlock props copyAriaLabel is rendered 1`] = ` -
-
-    
-      
-        var some = 'code';
-
-      
-      
-        console.log(some);
-      
-    
-  
-
-
- - - -
-
-
-`; - exports[`EuiCodeBlock props fontSize l is rendered 1`] = `
{ }); }); - describe('copyAriaLabel', () => { - it('is rendered', () => { - const customLabel = 'Copy this code'; - const { container } = render( - - {code} - - ); + it('renders `copyAriaLabel` on the copy button', () => { + const customLabel = 'Copy this code'; + const { getByTestSubject } = render( + + {code} + + ); - expect(container.firstChild).toMatchSnapshot(); - }); + expect(getByTestSubject('euiCodeBlockCopy')).toHaveAttribute( + 'aria-label', + customLabel + ); }); describe('overflowHeight', () => {