Files
defgov/packages/ui/src/lv1-fundamental/Slot/Slot.tsx

51 lines
1.2 KiB
TypeScript

import * as React from "react";
import { cn } from "tailwind-variants";
export interface SlotProps extends React.HTMLAttributes<HTMLElement> {
children: React.ReactNode;
}
export const Slot = React.forwardRef<HTMLElement, SlotProps>(
(
{
children,
onClick: externalOnClick,
style: styleProp,
className: classNameProp,
...props
},
ref,
) => {
if (!React.isValidElement(children)) return null;
const child = children as React.ReactElement<Record<string, unknown>>;
const mergedClassName = cn(child.props.className as string, classNameProp);
const mergedStyle = {
...(child.props.style ?? {}),
...(styleProp ?? {}),
} as React.CSSProperties;
const childOnClick = child.props.onClick as
| ((e: React.MouseEvent<HTMLElement>) => void)
| undefined;
const mergedOnClick = (e: React.MouseEvent<HTMLElement>) => {
childOnClick?.(e);
externalOnClick?.(e);
};
return React.cloneElement(child, {
...child.props,
...props,
ref,
style: mergedStyle,
className: mergedClassName,
onClick: mergedOnClick,
});
},
);
Slot.displayName = "Slot";