UNPKG

@carbon/ibm-products

Version:

Carbon for IBM Products

231 lines (225 loc) 7.22 kB
/** * Copyright IBM Corp. 2020, 2025 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js'; import React__default, { useRef, useEffect, useCallback } from 'react'; import { Layer, MultiSelect, Dropdown, Button } from '@carbon/react'; import { ChevronRight, View } from '@carbon/react/icons'; import PropTypes from '../../_virtual/index.js'; import cx from 'classnames'; import { pkg } from '../../settings.js'; import { AddSelectFormControl } from './AddSelectFormControl.js'; const blockClass = `${pkg.prefix}--add-select__selections`; const componentName = 'AddSelectList'; let AddSelectRow = _ref => { let { appliedModifiers, displayMetalPanel, index, focus, item, metaIconDescription, modifiers, multi, multiSelection, navIconDescription, parentId, parentSelected, setAppliedModifiers, setDisplayMetaPanel, setFocus, setMultiSelection, setParentSelected, setSingleSelection, setSize, singleSelection } = _ref; const ref = useRef(null); useEffect(() => { if (focus === index) { ref.current.focus(); } }, [focus, index]); const isSelected = () => { if (multi) { return multiSelection.includes(item.id); } return item.id === singleSelection; }; const getTabIndex = () => { // on initial load make the first item tabbable if (index === 0 && focus === '') { return 0; } // make it so only the last focused item is tabbable if (focus === index && focus !== '') { return 0; } // make unfocused items un-tabbable return -1; }; const focusHandler = useCallback(reset => { setFocus(reset ? '' : index); }, [setFocus, index]); const handleSingleSelection = () => { setSingleSelection(item.id); }; const onSelectKeyDown = _ref2 => { let { key } = _ref2; if (key === 'Enter' || key === ' ') { if (multi) { handleMultiSelection(); } else { handleSingleSelection(); } } else if (key === 'ArrowRight' && item.children) { onNavigateItem(); } }; const handleMultiSelection = () => { const checked = isSelected(); if (!checked) { const newValues = [...multiSelection, item.id]; setMultiSelection(newValues); } else { const newValues = multiSelection.filter(v => v !== item.id); setMultiSelection(newValues); } }; const onNavigateItem = () => { focusHandler(true); setParentSelected(item.id, item.title, parentId); }; const modifierHandler = (id, selectedItem) => { const modifiersClone = [...appliedModifiers]; const modifierIdx = modifiersClone.findIndex(item => item.id === id); modifiersClone[modifierIdx] = { id, [modifiers.id]: selectedItem }; setAppliedModifiers(modifiersClone); }; const metaPanelHandler = () => { if (item.meta) { setDisplayMetaPanel(item); } }; const isInMetaPanel = id => id === displayMetalPanel?.id; const hasModifiers = modifiers?.options?.length > 0; const tabIndex = getTabIndex(); const selected = isSelected(); const expanded = parentSelected === item.id; const sharedSelectProps = { id: `add-select-modifier-${item.id}`, titleText: modifiers?.title, type: 'inline', disabled: !isSelected(), label: modifiers?.label, items: modifiers?.options }; return /*#__PURE__*/React__default.createElement("div", { className: cx(`${blockClass}-row`, { [`${blockClass}-row--selected`]: isSelected(), [`${blockClass}-row-meta--selected`]: isInMetaPanel(item.id), [`${blockClass}-row--active`]: expanded, [`${blockClass}-row--focused`]: focus === index }), onKeyDown: onSelectKeyDown, tabIndex: tabIndex, ref: ref, role: "row", "aria-selected": selected, "aria-posinset": index + 1 // a11y aria-posinset must be >= 1, index is zero based , "aria-setsize": setSize, "aria-expanded": expanded }, /*#__PURE__*/React__default.createElement("div", { className: `${blockClass}-cell`, role: "gridcell" }, /*#__PURE__*/React__default.createElement("div", { className: `${blockClass}-cell-wrapper` }, multi ? /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(AddSelectFormControl, { type: "checkbox", item: item, selected: selected, onClick: handleMultiSelection }), hasModifiers && /*#__PURE__*/React__default.createElement(Layer, null, modifiers?.multiSelect ? /*#__PURE__*/React__default.createElement(MultiSelect, _extends({}, sharedSelectProps, { initialSelectedItems: item[modifiers.id], onChange: _ref3 => { let { selectedItems } = _ref3; return modifierHandler(item.id, selectedItems); } })) : /*#__PURE__*/React__default.createElement(Dropdown, _extends({}, sharedSelectProps, { className: `${blockClass}-dropdown`, initialSelectedItem: item[modifiers.id], onChange: _ref4 => { let { selectedItem } = _ref4; return modifierHandler(item.id, selectedItem); } })))) : /*#__PURE__*/React__default.createElement(AddSelectFormControl, { type: "radio", item: item, selected: selected, onClick: handleSingleSelection }), item.children && /*#__PURE__*/React__default.createElement(Button, { className: `${blockClass}-view-children`, renderIcon: props => /*#__PURE__*/React__default.createElement(ChevronRight, _extends({ size: 16 }, props)), iconDescription: navIconDescription, tooltipPosition: "left", tooltipAlignment: "center", hasIconOnly: true, onClick: onNavigateItem, kind: "ghost", size: "sm", tabIndex: -1, "aria-hidden": true }), item.meta && /*#__PURE__*/React__default.createElement(Button, { className: `${blockClass}-view-meta`, renderIcon: props => /*#__PURE__*/React__default.createElement(View, _extends({ size: 16 }, props)), iconDescription: metaIconDescription, tooltipPosition: "left", tooltipAlignment: "center", hasIconOnly: true, kind: "ghost", size: "sm", onClick: metaPanelHandler })))); }; AddSelectRow.propTypes = { appliedModifiers: PropTypes.array, displayMetalPanel: PropTypes.object, filteredItems: PropTypes.array, focus: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), index: PropTypes.number, item: PropTypes.object, metaIconDescription: PropTypes.string, modifiers: PropTypes.object, multi: PropTypes.bool, multiSelection: PropTypes.array, navIconDescription: PropTypes.string, parentId: PropTypes.string, parentSelected: PropTypes.string, setAppliedModifiers: PropTypes.func, setDisplayMetaPanel: PropTypes.func, setFocus: PropTypes.func, setMultiSelection: PropTypes.func, setParentSelected: PropTypes.func, setSingleSelection: PropTypes.func, setSize: PropTypes.number, singleSelection: PropTypes.string }; AddSelectRow.displayName = componentName; export { AddSelectRow };