import type { ButtonHTMLAttributes } from 'react';
import { Link, type LinkProps } from 'react-router-dom';
/** The shared class list behind both controls (issue #300): one place decides
* what an icon-only control looks like, so the box, the icon size, the hover
* and the focus ring cannot drift apart between a button and a link. */
function iconClasses(active: boolean | undefined, className: string | undefined): string {
return ['icon-button', active ? 'icon-button--active' : '', className ?? '']
.filter(Boolean)
.join(' ');
}
interface IconButtonProps extends ButtonHTMLAttributes {
/** Localized accessible name; also shown as the hover tooltip. */
label: string;
active?: boolean;
}
/** A compact icon-only button (issue #101): aria-label + title carry the
* localized name, `active` marks toggles that are currently on. */
export function IconButton({
label,
active,
className,
children,
...rest
}: IconButtonProps): React.JSX.Element {
return (
);
}
interface IconLinkProps extends LinkProps {
/** Localized accessible name; also shown as the hover tooltip. */
label: string;
active?: boolean;
}
/**
* The navigating twin of {@link IconButton} (issue #300). An icon-only control
* that goes somewhere is a link, not a button — but it has to look and focus
* exactly like one, which is why both share {@link iconClasses}. Without it the
* three navigating icons (pond settings, graph, trash) stayed the one group
* that had to glue the class on by hand.
*/
export function IconLink({
label,
active,
className,
children,
...rest
}: IconLinkProps): React.JSX.Element {
return (
{children}
);
}