@carbon/ibm-products
Version:
Carbon for IBM Products
171 lines (169 loc) • 6.3 kB
JavaScript
/**
* Copyright IBM Corp. 2020, 2026
*
* 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 { __toESM } from "../../_virtual/_rolldown/runtime.js";
import { require_classnames } from "../../node_modules/classnames/index.js";
import { pkg } from "../../settings.js";
import { AddSelectFormControl } from "./AddSelectFormControl.js";
import React, { useCallback, useEffect, useRef } from "react";
import PropTypes from "prop-types";
import { Button, Dropdown, Layer, MultiSelect } from "@carbon/react";
import { ChevronRight, View } from "@carbon/react/icons";
//#region src/components/AddSelect/AddSelectRow.jsx
var import_classnames = /* @__PURE__ */ __toESM(require_classnames());
const blockClass = `${pkg.prefix}--add-select__selections`;
const componentName = "AddSelectList";
let AddSelectRow = ({ appliedModifiers, displayMetalPanel, index, focus, item, metaIconDescription, modifiers, multi, multiSelection, navIconDescription, parentId, parentSelected, setAppliedModifiers, setDisplayMetaPanel, setFocus, setMultiSelection, setParentSelected, setSingleSelection, setSize, singleSelection }) => {
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 = () => {
if (index === 0 && focus === "") return 0;
if (focus === index && focus !== "") return 0;
return -1;
};
const focusHandler = useCallback((reset) => {
setFocus(reset ? "" : index);
}, [setFocus, index]);
const handleSingleSelection = () => {
setSingleSelection(item.id);
};
const onSelectKeyDown = ({ key }) => {
if (key === "Enter" || key === " ") if (multi) handleMultiSelection();
else handleSingleSelection();
else if (key === "ArrowRight" && item.children) onNavigateItem();
};
const handleMultiSelection = () => {
if (!isSelected()) setMultiSelection([...multiSelection, item.id]);
else setMultiSelection(multiSelection.filter((v) => v !== item.id));
};
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: (0, import_classnames.default)(`${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,
ref,
role: "row",
"aria-selected": selected,
"aria-posinset": index + 1,
"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, {
type: "checkbox",
item,
selected,
onClick: handleMultiSelection
}), hasModifiers && /* @__PURE__ */ React.createElement(Layer, null, modifiers?.multiSelect ? /* @__PURE__ */ React.createElement(MultiSelect, {
...sharedSelectProps,
initialSelectedItems: item[modifiers.id],
onChange: ({ selectedItems }) => modifierHandler(item.id, selectedItems)
}) : /* @__PURE__ */ React.createElement(Dropdown, {
...sharedSelectProps,
className: `${blockClass}-dropdown`,
initialSelectedItem: item[modifiers.id],
onChange: ({ selectedItem }) => modifierHandler(item.id, selectedItem)
}))) : /* @__PURE__ */ React.createElement(AddSelectFormControl, {
type: "radio",
item,
selected,
onClick: handleSingleSelection
}), item.children && /* @__PURE__ */ React.createElement(Button, {
className: `${blockClass}-view-children`,
renderIcon: (props) => /* @__PURE__ */ React.createElement(ChevronRight, {
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(Button, {
className: `${blockClass}-view-meta`,
renderIcon: (props) => /* @__PURE__ */ React.createElement(View, {
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;
//#endregion
export { AddSelectRow };