UNPKG

@coreui/react

Version:

UI Components Library for React.js

179 lines (175 loc) 8.32 kB
'use strict'; var tslib_es6 = require('../../node_modules/tslib/tslib.es6.js'); var React = require('react'); var PropTypes = require('prop-types'); var index = require('../../_virtual/index.js'); var useForkedRef = require('../../hooks/useForkedRef.js'); require('@popperjs/core'); var props = require('../../props.js'); const SELECTOR_FOCUSABLE_ITEMS = '[data-coreui-chip-focusable="true"]:not(.disabled)'; const CChip = React.forwardRef((_a, ref) => { var { active, ariaRemoveLabel = 'Remove', children, as: Component = 'span', className, clickable, color, disabled, onClick, onDeselect, onKeyDown, onRemove, onSelect, onSelectedChange, removable, removeIcon, selectable, selected, size, tabIndex, variant } = _a, rest = tslib_es6.__rest(_a, ["active", "ariaRemoveLabel", "children", "as", "className", "clickable", "color", "disabled", "onClick", "onDeselect", "onKeyDown", "onRemove", "onSelect", "onSelectedChange", "removable", "removeIcon", "selectable", "selected", "size", "tabIndex", "variant"]); const chipRef = React.useRef(null); const forkedRef = useForkedRef.useForkedRef(ref, chipRef); const isSelectedControlled = selected !== undefined; const [_selected, setSelected] = React.useState(Boolean(selected)); const selectedState = isSelectedControlled ? Boolean(selected) : _selected; React.useEffect(() => { if (isSelectedControlled) { setSelected(Boolean(selected)); } }, [isSelectedControlled, selected]); const isFocusable = React.useMemo(() => Boolean(!disabled && (selectable || removable)), [disabled, selectable, removable]); const getFocusableSibling = (shouldGetNext) => { var _a; const currentElement = chipRef.current; if (!(currentElement === null || currentElement === void 0 ? void 0 : currentElement.parentElement)) { return null; } const chips = Array.from(currentElement.parentElement.querySelectorAll(SELECTOR_FOCUSABLE_ITEMS)); const index = chips.indexOf(currentElement); if (index === -1 || chips.length <= 1) { return null; } const targetIndex = shouldGetNext ? index + 1 : index - 1; return (_a = chips[targetIndex]) !== null && _a !== void 0 ? _a : null; }; const navigateToEdge = (targetIndex) => { const currentElement = chipRef.current; if (!(currentElement === null || currentElement === void 0 ? void 0 : currentElement.parentElement)) { return; } const chips = Array.from(currentElement.parentElement.querySelectorAll(SELECTOR_FOCUSABLE_ITEMS)); const edgeChip = targetIndex === -1 ? chips[chips.length - 1] : chips[0]; edgeChip === null || edgeChip === void 0 ? void 0 : edgeChip.focus(); }; const setSelectableState = (nextSelected, event) => { if (!selectable || disabled || nextSelected === selectedState) { return; } if (!isSelectedControlled) { setSelected(nextSelected); } if (nextSelected) { onSelect === null || onSelect === void 0 ? void 0 : onSelect(event); } else { onDeselect === null || onDeselect === void 0 ? void 0 : onDeselect(event); } onSelectedChange === null || onSelectedChange === void 0 ? void 0 : onSelectedChange(nextSelected, event); }; const toggleSelectedState = (event) => { setSelectableState(!selectedState, event); }; const handleRemove = (event) => { onRemove === null || onRemove === void 0 ? void 0 : onRemove(event); }; const handleRemoveClick = (event) => { event.stopPropagation(); handleRemove(event); }; const handleClick = (event) => { if (disabled) { return; } if (event.target.closest('.chip-remove')) { return; } if (selectable) { toggleSelectedState(event); } onClick === null || onClick === void 0 ? void 0 : onClick(event); }; const handleKeyDown = (event) => { if (disabled) { onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event); return; } switch (event.key) { case 'Enter': case ' ': case 'Spacebar': { if (selectable) { event.preventDefault(); toggleSelectedState(event); } break; } case 'Backspace': case 'Delete': { if (removable) { event.preventDefault(); const sibling = getFocusableSibling(false) || getFocusableSibling(true); sibling === null || sibling === void 0 ? void 0 : sibling.focus(); handleRemove(event); } break; } case 'ArrowLeft': { event.preventDefault(); const sibling = getFocusableSibling(false); sibling === null || sibling === void 0 ? void 0 : sibling.focus(); if (selectedState && event.shiftKey) { sibling === null || sibling === void 0 ? void 0 : sibling.dispatchEvent(new CustomEvent('coreui-chip-select')); } break; } case 'ArrowRight': { event.preventDefault(); const sibling = getFocusableSibling(true); sibling === null || sibling === void 0 ? void 0 : sibling.focus(); if (selectedState && event.shiftKey) { sibling === null || sibling === void 0 ? void 0 : sibling.dispatchEvent(new CustomEvent('coreui-chip-select')); } break; } case 'Home': { event.preventDefault(); navigateToEdge(0); break; } case 'End': { event.preventDefault(); navigateToEdge(-1); break; } // No default } onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event); }; return (React.createElement(Component, Object.assign({ className: index.default('chip', { active: selectable ? selectedState : active, disabled, [`chip-${color}`]: color, [`chip-${size}`]: size, 'chip-clickable': clickable || selectable || Boolean(onClick), 'chip-outline': variant === 'outline', }, className), "data-coreui-chip-focusable": isFocusable || undefined }, (disabled && { 'aria-disabled': true }), (selectable && { 'aria-selected': selectedState }), (isFocusable && tabIndex === undefined && { tabIndex: 0 }), { onClick: handleClick, onKeyDown: handleKeyDown }, (Component === 'button' && { disabled }), rest, { ref: forkedRef }), children, removable && (React.createElement("button", { type: "button", className: "chip-remove", "aria-label": ariaRemoveLabel, onClick: handleRemoveClick, tabIndex: -1, disabled: disabled }, removeIcon !== null && removeIcon !== void 0 ? removeIcon : (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }, React.createElement("line", { x1: "4", y1: "4", x2: "12", y2: "12" }), React.createElement("line", { x1: "12", y1: "4", x2: "4", y2: "12" }))))))); }); CChip.propTypes = { active: PropTypes.bool, ariaRemoveLabel: PropTypes.string, as: PropTypes.elementType, children: PropTypes.node, className: PropTypes.string, clickable: PropTypes.bool, color: props.colorPropType, disabled: PropTypes.bool, onDeselect: PropTypes.func, onRemove: PropTypes.func, onSelect: PropTypes.func, onSelectedChange: PropTypes.func, removable: PropTypes.bool, removeIcon: PropTypes.node, selectable: PropTypes.bool, selected: PropTypes.bool, size: PropTypes.oneOf(['sm', 'lg']), variant: PropTypes.oneOf(['outline']), }; CChip.displayName = 'CChip'; exports.CChip = CChip; //# sourceMappingURL=CChip.js.map