PluginProbe
Code Snippets / trunk
Code Snippets vtrunk
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
← All changes | js/components/common/CopyToClipboardButton.tsx +29 -12 3.9.6 → trunk View file →
@@ -20,15 +20,15 @@
20 20
21 21 const StatusIcon: React.FC<StatusIconProps> = ({ status }) => {
22 22 switch (status) {
23 23 case Status.INITIAL:
24 - return <CopyIcon />
24 + return <CopyIcon aria-hidden="true" />
25 25 case Status.PROGRESSING:
26 - return <span className="spinner-wrapper"><Spinner /></span>
26 + return <span className="spinner-wrapper" aria-hidden="true"><Spinner /></span>
27 27 case Status.SUCCESS:
28 - return <span className="dashicons dashicons-yes"></span>
28 + return <span className="dashicons dashicons-yes" aria-hidden="true"></span>
29 29 case Status.ERROR:
30 - return <span className="dashicons dashicons-warning"></span>
30 + return <span className="dashicons dashicons-warning" aria-hidden="true"></span>
31 31 }
32 32 }
33 33
34 34 export interface CopyToClipboardButtonProps extends ButtonProps {
@@ -35,8 +35,15 @@
35 35 text: string
36 36 timeout?: number
37 37 }
38 38
39 +const STATUS_MESSAGES: Record<Status, string> = {
40 + [Status.INITIAL]: '',
41 + [Status.PROGRESSING]: __('Copying to clipboard…', 'code-snippets'),
42 + [Status.SUCCESS]: __('Copied to clipboard.', 'code-snippets'),
43 + [Status.ERROR]: __('Failed to copy to clipboard. Please try again.', 'code-snippets')
44 +}
45 +
39 46 export const CopyToClipboardButton: React.FC<CopyToClipboardButtonProps> = ({
40 47 text,
41 48 timeout = TIMEOUT,
42 49 ...props
@@ -54,18 +61,28 @@
54 61 })
55 62 .catch((error: unknown) => {
56 63 console.error('Failed to copy text to clipboard.', error)
57 64 setStatus(Status.ERROR)
65 + setTimeout(() => setStatus(Status.INITIAL), timeout)
58 66 })
59 67 }
60 68
61 69 return clipboard && window.isSecureContext
62 - ? <Button
63 - className="code-snippets-copy-text"
64 - onClick={handleClick}
65 - {...props}
66 - >
67 - <StatusIcon status={status} />
68 - {__('Copy', 'code-snippets')}
69 - </Button>
70 + ? <>
71 + <Button
72 + className="code-snippets-copy-text"
73 + onClick={handleClick}
74 + {...props}
75 + >
76 + <StatusIcon status={status} />
77 + {__('Copy', 'code-snippets')}
78 + </Button>
79 + <span
80 + className="screen-reader-text"
81 + role={Status.ERROR === status ? 'alert' : 'status'}
82 + aria-live={Status.ERROR === status ? 'assertive' : 'polite'}
83 + >
84 + {STATUS_MESSAGES[status]}
85 + </span>
86 + </>
70 87 : null
71 88 }