@carbon/ibm-products
Version:
Carbon for IBM Products
233 lines (226 loc) • 7.35 kB
JavaScript
/**
* 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.
*/
'use strict';
var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var react = require('@carbon/react');
var icons = require('@carbon/react/icons');
var index = require('../../_virtual/index.js');
var cx = require('classnames');
var settings = require('../../settings.js');
var AddSelectFormControl = require('./AddSelectFormControl.js');
const blockClass = `${settings.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 = React.useRef(null);
React.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 = React.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.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.createElement("div", {
className: `${blockClass}-cell`,
role: "gridcell"
}, /*#__PURE__*/React.createElement("div", {
className: `${blockClass}-cell-wrapper`
}, multi ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(AddSelectFormControl.AddSelectFormControl, {
type: "checkbox",
item: item,
selected: selected,
onClick: handleMultiSelection
}), hasModifiers && /*#__PURE__*/React.createElement(react.Layer, null, modifiers?.multiSelect ? /*#__PURE__*/React.createElement(react.MultiSelect, _rollupPluginBabelHelpers.extends({}, sharedSelectProps, {
initialSelectedItems: item[modifiers.id],
onChange: _ref3 => {
let {
selectedItems
} = _ref3;
return modifierHandler(item.id, selectedItems);
}
})) : /*#__PURE__*/React.createElement(react.Dropdown, _rollupPluginBabelHelpers.extends({}, sharedSelectProps, {
className: `${blockClass}-dropdown`,
initialSelectedItem: item[modifiers.id],
onChange: _ref4 => {
let {
selectedItem
} = _ref4;
return modifierHandler(item.id, selectedItem);
}
})))) : /*#__PURE__*/React.createElement(AddSelectFormControl.AddSelectFormControl, {
type: "radio",
item: item,
selected: selected,
onClick: handleSingleSelection
}), item.children && /*#__PURE__*/React.createElement(react.Button, {
className: `${blockClass}-view-children`,
renderIcon: props => /*#__PURE__*/React.createElement(icons.ChevronRight, _rollupPluginBabelHelpers.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.createElement(react.Button, {
className: `${blockClass}-view-meta`,
renderIcon: props => /*#__PURE__*/React.createElement(icons.View, _rollupPluginBabelHelpers.extends({
size: 16
}, props)),
iconDescription: metaIconDescription,
tooltipPosition: "left",
tooltipAlignment: "center",
hasIconOnly: true,
kind: "ghost",
size: "sm",
onClick: metaPanelHandler
}))));
};
AddSelectRow.propTypes = {
appliedModifiers: index.default.array,
displayMetalPanel: index.default.object,
filteredItems: index.default.array,
focus: index.default.oneOfType([index.default.number, index.default.string]),
index: index.default.number,
item: index.default.object,
metaIconDescription: index.default.string,
modifiers: index.default.object,
multi: index.default.bool,
multiSelection: index.default.array,
navIconDescription: index.default.string,
parentId: index.default.string,
parentSelected: index.default.string,
setAppliedModifiers: index.default.func,
setDisplayMetaPanel: index.default.func,
setFocus: index.default.func,
setMultiSelection: index.default.func,
setParentSelected: index.default.func,
setSingleSelection: index.default.func,
setSize: index.default.number,
singleSelection: index.default.string
};
AddSelectRow.displayName = componentName;
exports.AddSelectRow = AddSelectRow;