From 19cc5aee043fd2761da20e1c4df7f2b0cb719d4f Mon Sep 17 00:00:00 2001 From: Tom Moor Date: Sun, 28 Jan 2024 21:46:11 -0500 Subject: [PATCH] Allow ref passthrough on CopyToClipboard component --- app/components/CopyToClipboard.ts | 51 ++++++++++++++++++------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/app/components/CopyToClipboard.ts b/app/components/CopyToClipboard.ts index 3f17db8eb..e106d4823 100644 --- a/app/components/CopyToClipboard.ts +++ b/app/components/CopyToClipboard.ts @@ -1,5 +1,6 @@ import copy from "copy-to-clipboard"; import * as React from "react"; +import { mergeRefs } from "react-merge-refs"; import env from "~/env"; type Props = { @@ -9,32 +10,40 @@ type Props = { onCopy?: () => void; }; -class CopyToClipboard extends React.PureComponent { - onClick = (ev: React.SyntheticEvent) => { - const { text, onCopy, children } = this.props; - const elem = React.Children.only(children); +function CopyToClipboard(props: Props, ref: React.Ref) { + const { text, onCopy, children, ...rest } = props; - copy(text, { - debug: env.ENVIRONMENT !== "production", - format: "text/plain", - }); + const onClick = React.useCallback( + (ev: React.MouseEvent) => { + const elem = React.Children.only(children); - onCopy?.(); + copy(text, { + debug: env.ENVIRONMENT !== "production", + format: "text/plain", + }); - if (elem && elem.props && typeof elem.props.onClick === "function") { - elem.props.onClick(ev); - } - }; + onCopy?.(); - render() { - const { text, onCopy, children, ...rest } = this.props; - const elem = React.Children.only(children); - if (!elem) { - return null; - } + if (elem && elem.props && typeof elem.props.onClick === "function") { + elem.props.onClick(ev); + } + }, + [children, onCopy, text] + ); - return React.cloneElement(elem, { ...rest, onClick: this.onClick }); + const elem = React.Children.only(children); + if (!elem) { + return null; } + + return React.cloneElement(elem, { + ...rest, + ref: + "ref" in elem + ? mergeRefs([elem.ref as React.MutableRefObject, ref]) + : ref, + onClick, + }); } -export default CopyToClipboard; +export default React.forwardRef(CopyToClipboard);