@syncfusion/react-buttons
Version:
Syncfusion React Buttons package is a feature-rich collection of UI components including Button, CheckBox, RadioButton, Switch, Chip, and more for building modern, interactive React applications.
127 lines (126 loc) • 6.17 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, memo, useCallback, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { preRender, useProviderContext, useRippleEffect, Size } from '@syncfusion/react-base';
import { CheckTickIcon, CloseIcon } from '@syncfusion/react-icons';
export { Size };
/**
* The Chip component represents information in a compact form, such as entity attribute, text, or action.
*
* ```typescript
* import { Chip } from "@syncfusion/react-buttons";
*
* <Chip color="Primary" removable={true}>Anne</Chip>
* ```
*/
export const Chip = memo(forwardRef((props, ref) => {
const { value, text, avatar, leadingIcon, trailingIcon, className, disabled = false, leadingIconUrl, trailingIconUrl, children, removable, variant = 'Filled', color, size = Size.Medium, onDelete, onClick, selectIcon = _jsx(CheckTickIcon, {}), removeIcon = _jsx(CloseIcon, {}), ...otherProps } = props;
const publicAPI = {
value,
text,
avatar,
leadingIcon,
trailingIcon,
disabled,
leadingIconUrl,
trailingIconUrl,
removable,
variant,
color,
size,
selectIcon,
removeIcon
};
const chipRef = useRef(null);
const [isFocused, setIsFocused] = useState(false);
const { dir, ripple } = useProviderContext();
const IconClasses = 'sf-content-center sf-overflow-hidden';
const { rippleMouseDown, Ripple } = useRippleEffect(ripple);
useLayoutEffect(() => {
preRender('chip');
}, []);
useImperativeHandle(ref, () => ({
...publicAPI,
element: chipRef.current
}));
const handleDelete = useCallback((e) => {
if (!removable) {
return;
}
e.stopPropagation();
const eventArgs = {
event: e,
data: props
};
if (onDelete) {
onDelete(eventArgs);
}
}, [onDelete, text, props]);
const handleSpanDelete = useCallback((e) => {
if (removable) {
handleDelete(e);
}
}, [removable, handleDelete]);
const handleClick = useCallback((e) => {
if (onClick) {
onClick(e);
}
}, [onClick, text, props]);
const handleKeyDown = useCallback((e) => {
switch (e.key) {
case 'Enter':
case ' ':
e.preventDefault();
handleClick(e);
break;
case 'Delete':
case 'Backspace':
if (removable) {
e.preventDefault();
handleDelete(e);
}
break;
}
}, [removable, handleClick, handleDelete]);
const handleFocus = useCallback(() => {
setIsFocused(true);
}, []);
const handleBlur = useCallback(() => {
setIsFocused(false);
}, []);
const chipClassName = useMemo(() => {
if (className?.includes('sf-chip')) {
return className;
}
return [
'sf-chip sf-control sf-chip-list',
className,
disabled ? `sf-disabled sf-chip-${color ? 'variant' : 'invariant'}-disabled` : '',
dir === 'rtl' ? 'sf-rtl' : '',
avatar ? 'sf-chip-avatar-wrap' :
leadingIcon ? 'sf-chip-icon-wrap' : '',
isFocused ? 'sf-focused' : '',
variant === 'Outlined' ? 'sf-outline' : '',
color ? `sf-${color.toLowerCase()}` : '',
avatar || leadingIcon || leadingIconUrl ? 'sf-chip-has-icon' : '',
size ? `sf-chip-${size.toLowerCase()}` : ''
].filter(Boolean).join(' ');
}, [className, disabled, dir, avatar, leadingIcon, isFocused, variant, color, size]);
const avatarClasses = useMemo(() => {
return [
'sf-chip-avatar',
IconClasses,
typeof avatar === 'string' ? avatar : ''
].filter(Boolean).join(' ');
}, [avatar]);
const trailingIconClasses = useMemo(() => {
return [
trailingIconUrl && !removable ? 'sf-chip-trailing-url' : 'sf-chip-delete',
IconClasses,
removable ? 'sf-dlt-btn' : (typeof trailingIcon === 'string' ? trailingIcon : '')
].filter(Boolean).join(' ');
}, [trailingIconUrl, removable, trailingIcon]);
return (_jsxs("div", { ref: chipRef, className: chipClassName, tabIndex: disabled ? -1 : 0, role: "button", "aria-disabled": disabled ? 'true' : 'false', "aria-label": text ? text : undefined, "data-value": value ? value.toString() : undefined, onClick: handleClick, onFocus: handleFocus, onBlur: handleBlur, onKeyDown: handleKeyDown, onMouseDown: rippleMouseDown, ...otherProps, children: [chipClassName.includes('sf-selectable') && (_jsx("span", { className: 'sf-chip-selectable-icon sf-content-center', children: selectIcon })), (avatar) && (_jsx("span", { className: avatarClasses, children: typeof avatar !== 'string' && avatar })), (leadingIcon && !avatar) && (typeof leadingIcon === 'string' ?
_jsx("span", { className: `sf-chip-icon ${leadingIcon} ${IconClasses}` }) :
_jsx("span", { className: `sf-chip-icon ${IconClasses}`, children: leadingIcon })), (leadingIconUrl && !leadingIcon && !avatar) && (_jsx("span", { className: `sf-chip-avatar sf-chip-image ${IconClasses}`, children: leadingIconUrl && (_jsx("img", { className: 'sf-chip-leading-image', src: leadingIconUrl, alt: "leading image" })) })), children ? (_jsx("div", { className: "sf-chip-template sf-display-inline-flex", children: children })) : text ? (_jsx("span", { className: "sf-chip-text sf-ellipsis", children: text })) : null, (trailingIcon || trailingIconUrl || removable) && (_jsxs("span", { className: trailingIconClasses, onClick: handleSpanDelete, children: [removable && (removeIcon), !removable && typeof trailingIcon !== 'string' && trailingIcon, !removable && trailingIconUrl && (_jsx("img", { className: 'sf-chip-trailing-image', src: trailingIconUrl, alt: "trailing image" }))] })), ripple && _jsx(Ripple, {})] }));
}));
export default Chip;