41 lines
1.2 KiB
JavaScript
41 lines
1.2 KiB
JavaScript
import * as React from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
|
|
|
|
/**
|
|
* IconButton — a square Button carrying only an icon.
|
|
*
|
|
* It delegates entirely to Button so the two can never diverge, and requires a
|
|
* `label`: an icon-only control with no accessible name is a bug, so the API
|
|
* makes it impossible to omit. The label doubles as the tooltip.
|
|
*/
|
|
/** @type {React.ForwardRefExoticComponent<any>} */
|
|
export const IconButton = React.forwardRef(
|
|
({ icon: Icon, label, tooltip = true, size = 'default', side = 'top', ...props }, ref) => {
|
|
const sizeMap = {
|
|
xs: 'icon-xs',
|
|
sm: 'icon-sm',
|
|
default: 'icon',
|
|
lg: 'icon-lg',
|
|
};
|
|
|
|
const button = (
|
|
<Button ref={ref} size={sizeMap[size] || 'icon'} aria-label={label} {...props}>
|
|
<Icon aria-hidden="true" />
|
|
</Button>
|
|
);
|
|
|
|
if (!tooltip) return button;
|
|
|
|
return (
|
|
<TooltipProvider delayDuration={300}>
|
|
<Tooltip>
|
|
<TooltipTrigger asChild>{button}</TooltipTrigger>
|
|
<TooltipContent side={side}>{label}</TooltipContent>
|
|
</Tooltip>
|
|
</TooltipProvider>
|
|
);
|
|
}
|
|
);
|
|
IconButton.displayName = 'IconButton';
|