import { Button, type ButtonProps } from "@ariakit/react"; import { useState, type ReactNode } from "react"; import { useRevertingState } from "../use-reverting-state.ts"; type AriakitButtonProps = Omit< ButtonProps, "children" | "onClick" | "value" | "type" >; export type CopyToClipboardButtonProps = AriakitButtonProps & { value: string | null; children: ReactNode; revertAfterMs: number; }; export function CopyToClipboardButton(props: CopyToClipboardButtonProps) { const { children, value, revertAfterMs, disabled, ...buttonProps } = props; const [copiedTimestamp, setCopiedTimestamp] = useRevertingState< number | null >(null, revertAfterMs); return ( ); } export type WebShareButtonProps = AriakitButtonProps & { children: ReactNode; shareData: ShareData | null; revertAfterMs: number; }; export function WebShareButton(props: WebShareButtonProps) { const { shareData, children, revertAfterMs, disabled, ...buttonProps } = props; // Tracking sharing state to prevent duplicate invocations of // the share dialog. const [sharing, setSharing] = useState(false); const [copiedTimestamp, setCopiedTimestamp] = useRevertingState< number | null >(null, revertAfterMs); return ( ); } export type ShareButtonProps = AriakitButtonProps & { /** * Button label to use when copy to clipboard is used. */ copyLabel: string; /** * Button label to use when web share is used. */ shareLabel: string; /** * Data to be shared by the button. * * If using copy to clipboard, only the URL value will be used. */ shareData: ShareData | null; /** * How long should the confirmation message be shown within the button? * * @default 1500 */ revertAfterMs?: number; /** * Should web share be used instead of copy to clipboard? * * By default, web share will be used if the browser supports it. * * @default !!navigator.share */ webShare?: boolean; }; /** * An unstyled button that is pre-configured to either copy provided share data * to clipboard, or to use web share, depending on which feature is detected * in the browser where the button is running. * * Props that are not consumed by the Share Button itself are passed to the * underlying Ariakit Button component. * * @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share */ export function ShareButton(props: ShareButtonProps) { const { copyLabel, shareLabel, shareData, revertAfterMs = 1500, webShare = !!navigator.share, ...buttonProps } = props; if (webShare) { return ( {shareLabel} ); } return ( {copyLabel} ); }