import React, { ButtonHTMLAttributes, forwardRef, useState } from "react";
import { CheckmarkIcon, FilesIcon } from "@navikt/aksel-icons";
import type { AkselStatusColorRole } from "@navikt/ds-tokens/types";
import { Button, ButtonProps } from "../button";
import type { AkselColor } from "../types/theme";
import { cl, clipboardCopy, composeEventHandlers } from "../utils/helpers";
import { useTimeout } from "../utils/hooks";
import { useI18n } from "../utils/i18n/i18n.hooks";
export interface CopyButtonProps
extends
Omit, "children">,
Pick {
/**
* @deprecated Use `data-color` attribute instead.
*/
variant?: "action" | "neutral";
/**
* Overrides color.
*
* We recommend only using `accent` and `neutral`. We have disallowed status-colors.
* @default "neutral"
* @see 🏷️ {@link AkselColor}
* @see [📝 Documentation](https://aksel.nav.no/grunnleggende/styling/farger-tokens)
*/
"data-color"?: Exclude;
/**
* Text to copy to clipboard.
*/
copyText: string;
/**
* Optional text in button.
*/
text?: string;
/**
* Text shown when button is clicked.
* Will be used as accessible label (title) if `text`-prop is not set.
* @default "Kopiert!"
*/
activeText?: string;
/**
* Callback that is called when internal copy-state changes.
*
* @param state `true` when copy-state is activated, `false` when copy-state is deactivated.
*/
onActiveChange?: (state: boolean) => void;
/**
* Icon shown when button is not clicked.
* @default
*/
icon?: React.ReactNode;
/**
* Icon shown when active.
* @default
*/
activeIcon?: React.ReactNode;
/**
* Timeout duration in milliseconds.
* @default 2000
*/
activeDuration?: number;
/**
* Accessible label for icon (ignored if text is set).
* @default "Kopier"
*/
title?: string;
}
/**
* A button component that copies text to the clipboard when clicked.
*
* @see [📝 Documentation](https://aksel.nav.no/komponenter/core/copybutton)
* @see 🏷️ {@link CopyButtonProps}
*
* @example
* ```jsx
* ```
*/
export const CopyButton = forwardRef(
(
{
className,
copyText,
text,
activeText,
variant,
"data-color": dataColor = "neutral",
onActiveChange,
icon,
activeIcon,
activeDuration = 2000,
title,
iconPosition = "left",
onClick,
size = "medium",
...rest
},
ref,
) => {
const [active, setActive] = useState(false);
const translate = useI18n("CopyButton");
const timeout = useTimeout();
const handleClick = () => {
clipboardCopy(copyText);
setActive(true);
onActiveChange?.(true);
timeout.start(activeDuration, () => {
setActive(false);
onActiveChange?.(false);
});
};
const activeString = activeText || translate("activeText");
return (
))
: (icon ?? (
))
}
data-active={active}
size={size}
>
{text ? (active ? activeString : text) : null}
);
},
);
function variantToDataColor(
variant: CopyButtonProps["variant"],
): Exclude | undefined {
if (variant === "action") {
return "accent";
}
if (variant === "neutral") {
return "neutral";
}
return undefined;
}
export default CopyButton;