mirror of
https://github.com/Xevion/rdap.git
synced 2025-12-06 01:16:00 -06:00
refactor: improve icon handling with component-based approach
Replace ReactNode icon props with IconComponent type for better type safety and consistency. Add configurable iconSize prop to control icon dimensions. Update ShareButton to pass icon components instead of JSX elements.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { FunctionComponent, ReactNode } from "react";
|
||||
import type { FunctionComponent, ComponentType } from "react";
|
||||
import { useState, useCallback, useEffect, useRef } from "react";
|
||||
import { CheckIcon, ClipboardIcon } from "@radix-ui/react-icons";
|
||||
import type { IconButtonProps } from "@radix-ui/themes";
|
||||
@@ -15,6 +15,9 @@ export type ButtonSize = IconButtonProps["size"];
|
||||
export type ButtonVariant = IconButtonProps["variant"];
|
||||
export type ButtonColor = IconButtonProps["color"];
|
||||
|
||||
// Type for icon components that accept width/height props (e.g., Radix UI icons)
|
||||
export type IconComponent = ComponentType<{ width?: string | number; height?: string | number }>;
|
||||
|
||||
export type CopyButtonProps = {
|
||||
/**
|
||||
* The value to copy to clipboard when the button is clicked
|
||||
@@ -35,9 +38,14 @@ export type CopyButtonProps = {
|
||||
*/
|
||||
color?: ButtonColor | null;
|
||||
/**
|
||||
* Optional custom icon to show when not copied (defaults to ClipboardIcon)
|
||||
* Optional custom icon component to show when not copied (defaults to ClipboardIcon)
|
||||
*/
|
||||
icon?: ReactNode;
|
||||
icon?: IconComponent;
|
||||
/**
|
||||
* Size for both the custom icon and checkmark icon
|
||||
* @default 16
|
||||
*/
|
||||
iconSize?: number;
|
||||
/**
|
||||
* Tooltip text to show when not copied (defaults to "Copy to Clipboard")
|
||||
*/
|
||||
@@ -49,7 +57,8 @@ const CopyButton: FunctionComponent<CopyButtonProps> = ({
|
||||
size = "1",
|
||||
variant = "ghost",
|
||||
color = "gray",
|
||||
icon,
|
||||
icon: IconComp,
|
||||
iconSize = 16,
|
||||
tooltipText = "Copy to Clipboard",
|
||||
}) => {
|
||||
const [copied, setCopied] = useState(false);
|
||||
@@ -91,6 +100,9 @@ const CopyButton: FunctionComponent<CopyButtonProps> = ({
|
||||
setTooltipOpen(open);
|
||||
}, []);
|
||||
|
||||
// Determine which icon component to render
|
||||
const ActiveIcon = copied ? CheckIcon : (IconComp ?? ClipboardIcon);
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
content={copied ? "Copied!" : tooltipText}
|
||||
@@ -104,7 +116,7 @@ const CopyButton: FunctionComponent<CopyButtonProps> = ({
|
||||
aria-label={copied ? "Copied!" : tooltipText}
|
||||
onClick={handleCopy}
|
||||
>
|
||||
{copied ? <CheckIcon /> : (icon ?? <ClipboardIcon />)}
|
||||
<ActiveIcon width={iconSize} height={iconSize} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
@@ -11,7 +11,8 @@ export type ShareButtonProps = Omit<CopyButtonProps, "value"> & {
|
||||
|
||||
const ShareButton: FunctionComponent<ShareButtonProps> = ({
|
||||
url,
|
||||
icon = <Link2Icon />,
|
||||
icon = Link2Icon,
|
||||
iconSize = 18,
|
||||
tooltipText = "Copy shareable link",
|
||||
...copyButtonProps
|
||||
}) => {
|
||||
@@ -24,7 +25,15 @@ const ShareButton: FunctionComponent<ShareButtonProps> = ({
|
||||
}
|
||||
}
|
||||
|
||||
return <CopyButton {...copyButtonProps} value={url} icon={icon} tooltipText={tooltipText} />;
|
||||
return (
|
||||
<CopyButton
|
||||
{...copyButtonProps}
|
||||
value={url}
|
||||
icon={icon}
|
||||
iconSize={iconSize}
|
||||
tooltipText={tooltipText}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ShareButton;
|
||||
|
||||
Reference in New Issue
Block a user