Files
ersatztv/design-system/components/forms/IconButton.jsx
T
2026-07-02 07:37:00 +02:00

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>
);
}