diff --git a/polaris-react/src/components/Tooltip/Tooltip.stories.tsx b/polaris-react/src/components/Tooltip/Tooltip.stories.tsx
index 173bf0a2fc3..99fd3bee3f1 100644
--- a/polaris-react/src/components/Tooltip/Tooltip.stories.tsx
+++ b/polaris-react/src/components/Tooltip/Tooltip.stories.tsx
@@ -1,5 +1,9 @@
import React, {useState} from 'react';
-import {QuestionCircleIcon} from '@shopify/polaris-icons';
+import {
+ CheckIcon,
+ ClipboardIcon,
+ QuestionCircleIcon,
+} from '@shopify/polaris-icons';
import type {ComponentMeta} from '@storybook/react';
import {
Button,
@@ -13,6 +17,7 @@ import {
BlockStack,
Popover,
Card,
+ Link,
} from '@shopify/polaris';
import type {TooltipProps} from '@shopify/polaris';
@@ -566,3 +571,74 @@ export function OneCharacter() {
);
}
+
+export function CopyToClipboard() {
+ const [copy, status] = useCopyToClipboard({
+ defaultValue: 'hello@example.com',
+ });
+
+ return (
+
+
+
+ hello@example.com
+
+
+
+
+
+
+ );
+}
+
+type Status = 'inactive' | 'copied' | 'failed';
+
+interface UseCopyToClipboardOptions {
+ defaultValue?: string;
+ timeout?: number;
+}
+
+/**
+ * Copy text to the native clipboard using the `navigator.clipboard` API
+ * Adapted from https://www.benmvp.com/blog/copy-to-clipboard-react-custom-hook
+ */
+function useCopyToClipboard(options: UseCopyToClipboardOptions = {}) {
+ const {defaultValue = '', timeout = 1500} = options;
+
+ const [status, setStatus] = React.useState('inactive');
+
+ const copy = React.useCallback(
+ (value?: string) => {
+ navigator.clipboard
+ .writeText(typeof value === 'string' ? value : defaultValue)
+ .then(
+ () => setStatus('copied'),
+ () => setStatus('failed'),
+ )
+ .catch((error) => {
+ throw error;
+ });
+ },
+ [defaultValue],
+ );
+
+ React.useEffect(() => {
+ if (status === 'inactive') return;
+
+ const timeoutId = setTimeout(() => setStatus('inactive'), timeout);
+
+ return () => clearTimeout(timeoutId);
+ }, [status, timeout]);
+
+ return [copy, status] as const;
+}
diff --git a/polaris-react/src/components/Tooltip/Tooltip.tsx b/polaris-react/src/components/Tooltip/Tooltip.tsx
index 635e3977fed..937ba1bbedc 100644
--- a/polaris-react/src/components/Tooltip/Tooltip.tsx
+++ b/polaris-react/src/components/Tooltip/Tooltip.tsx
@@ -158,7 +158,13 @@ export function Tooltip({
const handleKeyUp = useCallback(
(event: React.KeyboardEvent) => {
- if (event.key !== 'Escape') return;
+ if (
+ event.key !== 'Escape' &&
+ event.key !== 'Enter' &&
+ event.key !== ' '
+ ) {
+ return;
+ }
handleClose?.();
handleBlur();
persistOnClick && togglePersisting();
@@ -206,6 +212,11 @@ export function Tooltip({
handleFocus();
}}
onBlur={() => {
+ if (hoverDelayTimeout.current) {
+ clearTimeout(hoverDelayTimeout.current);
+ hoverDelayTimeout.current = null;
+ }
+
handleClose();
handleBlur();