60 lines
1.6 KiB
React
60 lines
1.6 KiB
React
import React from "react";
|
|
|
|
/**
|
|
* Compact square icon button — table row actions, toolbars.
|
|
*/
|
|
export function IconButton({
|
|
children,
|
|
size = "md",
|
|
variant = "ghost",
|
|
disabled = false,
|
|
active = false,
|
|
title,
|
|
onClick,
|
|
style = {},
|
|
...rest
|
|
}) {
|
|
const [hover, setHover] = React.useState(false);
|
|
const dim = size === "sm" ? 28 : 32;
|
|
|
|
const base =
|
|
variant === "solid"
|
|
? { background: "var(--action-primary)", color: "var(--text-on-accent)" }
|
|
: { background: active ? "var(--ctv-surface-3)" : "transparent", color: active ? "var(--text-primary)" : "var(--text-secondary)" };
|
|
|
|
const hoverBg =
|
|
variant === "solid" ? "var(--action-primary-hover)" : "var(--ctv-surface-2)";
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
title={title}
|
|
aria-label={title}
|
|
disabled={disabled}
|
|
onClick={onClick}
|
|
onMouseEnter={() => setHover(true)}
|
|
onMouseLeave={() => setHover(false)}
|
|
style={{
|
|
display: "inline-flex",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
width: dim,
|
|
height: dim,
|
|
flex: "0 0 auto",
|
|
borderRadius: "var(--radius-sm)",
|
|
border: "1px solid transparent",
|
|
cursor: disabled ? "not-allowed" : "pointer",
|
|
opacity: disabled ? 0.4 : 1,
|
|
color: base.color,
|
|
background: !disabled && hover ? hoverBg : base.background,
|
|
transition: "background var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard)",
|
|
...(!disabled && hover && variant !== "solid" ? { color: "var(--text-primary)" } : {}),
|
|
...style,
|
|
}}
|
|
{...rest}
|
|
>
|
|
{children}
|
|
</button>
|
|
);
|
|
}
|