import {
type ComponentProps,
type ComponentType,
isValidElement,
type ReactElement,
type SVGProps,
} from 'react';
import { clsx } from 'clsx';
import { Text, type TextProps } from '#/components/Text';
import { Button, ButtonIcon, ButtonText } from '#/components/web/Button';
import EditIcon from '#/icons/central/EditBig_round_outlined_radius3_stroke1.svg';
import { colors } from '#/styles/colors';
import type { iconSize as iconSizeToken } from '#/styles/tokens.css';
import * as css from './EmptyState.css';
type ButtonColor = NonNullable<ComponentProps<typeof Button>['color']>;
type ButtonSize = NonNullable<ComponentProps<typeof Button>['size']>;
export type EmptyStateButtonProps = {
color?: ButtonColor;
icon?: EmptyStateIcon;
iconPosition?: 'left' | 'right';
label: string;
onPress: () => void;
size?: ButtonSize;
text: string;
};
export type EmptyStateIcon = ComponentType<SVGProps<SVGSVGElement>>;
export function EmptyState({
button,
className,
icon,
iconColor,
iconSize = '_3xl',
message,
messageColor = 'textContrastHigh',
}: {
button?: EmptyStateButtonProps;
className?: string;
icon?: EmptyStateIcon | ReactElement | null;
iconColor?: keyof typeof colors;
iconSize?: keyof typeof iconSizeToken;
message: string;
messageColor?: TextProps['color'];
}) {
const renderIcon = () => {
if (icon === null) {
return null;
}
if (!icon) {
return <EditIcon className={clsx(css.icon._3xl, css.fallbackIcon)} />;
}
if (isValidElement(icon)) {
return icon;
}
const IconComponent = icon;
return (
<IconComponent
className={css.icon[iconSize]}
style={iconColor ? { color: colors[iconColor] } : undefined}
/>
);
};
const renderButton = () => {
if (!button) {
return null;
}
const { color, icon: buttonIcon, iconPosition = 'left', label, onPress, size = 'small', text } = button;
return (
<div className={css.buttonWrap}>
<Button color={color} label={label} onClick={onPress} size={size}>
{buttonIcon && iconPosition === 'left' && <ButtonIcon icon={buttonIcon} />}
<ButtonText>{text}</ButtonText>
{buttonIcon && iconPosition === 'right' && <ButtonIcon icon={buttonIcon} />}
</Button>
</div>
);
};
return (
<div className={clsx(css.root, className)}>
<div className={css.iconBox}>{renderIcon()}</div>
<Text align="center" className={css.message} color={messageColor} size="md" weight="medium">
{message}
</Text>
{renderButton()}
</div>
);
}