@spaced-out/ui-design-system
Version:
Sense UI components library
167 lines (157 loc) • 4.79 kB
Flow
// @flow strict
import * as React from 'react';
import type {ColorTypes} from '../../types/typography';
import {TEXT_COLORS} from '../../types/typography';
import {classify} from '../../utils/classify';
import {ConditionalWrapper} from '../ConditionalWrapper';
import type {IconType} from '../Icon';
import {CloseIcon, Icon, ICON_SIZE, ICON_TYPE} from '../Icon';
import type {BaseTooltipProps} from '../Tooltip';
import {Tooltip} from '../Tooltip';
import css from './PromptChip.module.css';
type ClassNames = $ReadOnly<{
icon?: string,
wrapper?: string,
children?: string,
container?: string,
}>;
export const PROMPT_CHIP_TYPE = Object.freeze({
primary: 'primary',
secondary: 'secondary',
});
export type PromptChipType = $Values<typeof PROMPT_CHIP_TYPE>;
export type PromptChipProps = {
classNames?: ClassNames,
...
| {
onDismiss?: ?(SyntheticEvent<HTMLElement>) => mixed,
dismissable: true,
selfDismiss?: boolean,
}
| {dismissable?: false},
type?: PromptChipType,
onClick?: ?(SyntheticEvent<HTMLElement>) => mixed,
iconName?: string,
iconType?: IconType,
children?: React.Node,
iconColor?: ColorTypes,
rightSlot?: React.Node,
showInfoIcon?: boolean,
infoIconTooltip?: BaseTooltipProps,
};
export const PromptChip: React$AbstractComponent<
PromptChipProps,
HTMLDivElement,
> = React.forwardRef<PromptChipProps, HTMLDivElement>(
(props: PromptChipProps, ref): React.Node => {
const {
type = PROMPT_CHIP_TYPE.primary,
onClick,
iconType = ICON_TYPE.solid,
iconName = 'lightbulb',
children,
iconColor,
rightSlot,
onDismiss,
classNames,
dismissable,
selfDismiss,
showInfoIcon,
infoIconTooltip,
} = props;
const [dismissed, setDismissed] = React.useState(false);
const closeClickHandler = (e) => {
e.stopPropagation();
onDismiss?.(e);
selfDismiss && setDismissed(true);
};
return (
<>
{!dismissed && (
<div
ref={ref}
data-testid="Prompt-Chip"
className={classify(
css.promptChipWrapper,
{
[css.primary]: type === PROMPT_CHIP_TYPE.primary,
[css.secondary]: type === PROMPT_CHIP_TYPE.secondary,
},
classNames?.wrapper,
)}
onClick={(event) => {
onClick?.(event);
}}
tabIndex={onClick ? 0 : undefined}
role="button"
>
<div
className={classify(
css.promptChipContainer,
{
[css.promptChipContainerHover]: !!onClick,
},
classNames?.container,
)}
>
<div className={css.leftSection}>
<Icon
size={ICON_SIZE.small}
name={iconName}
type={iconType}
color={iconColor}
className={classify(
{
[css.chipIconDefaultColor]: !iconColor,
},
classNames?.icon,
)}
/>
{!!children && (
<div
className={classify(
css.childrenWrapper,
classNames?.children,
)}
>
{children}
</div>
)}
</div>
<div className={css.rightSection}>
{rightSlot ? rightSlot : null}
{!!showInfoIcon && (
<ConditionalWrapper
condition={
infoIconTooltip &&
typeof infoIconTooltip === 'object' &&
Object.keys(infoIconTooltip).length > 0
}
wrapper={(children) => (
<Tooltip {...infoIconTooltip}>{children}</Tooltip>
)}
>
<Icon
size={ICON_SIZE.small}
name="info-circle"
color={TEXT_COLORS.primary}
className={classNames?.icon}
/>
</ConditionalWrapper>
)}
{!!dismissable && (
<CloseIcon
size={ICON_SIZE.small}
onClick={closeClickHandler}
ariaLabel="Dismiss"
className={css.dismissIcon}
/>
)}
</div>
</div>
</div>
)}
</>
);
},
);