Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | 9x 9x 9x 9x 1x 1x 9x 9x 9x 3x 3x 1x 1x 9x 9x | import {
type FC,
useCallback,
useRef,
type ReactNode,
type MouseEvent as ReactMouseEvent,
type HTMLAttributes,
} from 'react';
import cn from 'classnames';
import RemoveIcon from '../svg/times.svg';
import '../styles/components/chip.scss';
type ChipProps = {
/**
* What is displayed within the chip
*/
children: string | ReactNode;
/**
* Call back which, if present, will display a remove icon and is fired when this is clicked
*/
onRemove?: (event: ReactMouseEvent<SVGElement, MouseEvent>) => void;
/**
* If true will opacify the chip and prevent the remove from being clickable
*/
disabled?: boolean;
/**
* Additional CSS classnames to apply (eg secondary, tertiary)
*/
className?: string;
/**
* Compact styling for chip
*/
compact?: boolean;
/**
* click event listener on the component (except on the close button if present)
*/
onClick?: () => void;
/**
* key press event listener on the component
*/
onKeyPress?: () => void;
innerRef?: (node: HTMLElement | null) => void;
asSpan?: boolean;
};
export const Chip: FC<
ChipProps & HTMLAttributes<HTMLButtonElement | HTMLSpanElement>
> = ({
children,
onRemove,
className = '',
disabled,
compact = false,
onClick,
onKeyPress,
innerRef,
asSpan = false,
...rest
}) => {
const onRemoveRef = useRef(onRemove);
onRemoveRef.current = onRemove;
const handleRemove = useCallback(
(event: ReactMouseEvent<SVGElement, MouseEvent>) => {
event.stopPropagation();
onRemoveRef.current?.(event);
},
[]
);
const props = { ...rest };
let element: 'button' | 'span' = 'button';
if (onRemove || asSpan) {
element = 'span';
if (onClick || onKeyPress) {
props.role = 'button';
props.tabIndex = 0;
}
}
const Element = element;
return (
<Element
ref={innerRef}
className={cn(
'chip',
{ 'chip--disabled': disabled, 'chip--compact': compact },
className
)}
type={element === 'button' ? 'button' : undefined}
onKeyPress={onKeyPress}
onClick={onClick}
{...props}
>
{children}
{onRemove && !disabled && (
<RemoveIcon data-testid="remove-icon" onClick={handleRemove} />
)}
</Element>
);
};
export default Chip;
|