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