UNPKG

@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
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;