@carbon/ibm-products
Version:
Carbon for IBM Products
116 lines (114 loc) • 4 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.
*/
const require_runtime = require("../../../_virtual/_rolldown/runtime.js");
const require_index = require("../../../node_modules/classnames/index.js");
const require_context = require("./context.js");
let react = require("react");
react = require_runtime.__toESM(react);
let prop_types = require("prop-types");
prop_types = require_runtime.__toESM(prop_types);
//#region src/components/AddSelect/next/AddSelectContent.tsx
/**
* Copyright IBM Corp. 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.
*/
var import_classnames = /* @__PURE__ */ require_runtime.__toESM(require_index.default);
const AddSelectContent = (0, react.forwardRef)(({ children, className, layout = "vertical", ...rest }, ref) => {
const { multi } = (0, react.useContext)(require_context.AddSelectContext);
const listRef = (0, react.useRef)(null);
const focusedIndexRef = (0, react.useRef)(0);
const getItems = () => {
if (!listRef.current) return [];
return Array.from(listRef.current.querySelectorAll("[role=\"row\"]"));
};
const updateItemFocus = (focusIndex, shouldFocus = true) => {
const items = getItems();
if (items.length === 0) return;
focusedIndexRef.current = Math.max(0, Math.min(focusIndex, items.length - 1));
items.forEach((item, index) => {
if (index === focusedIndexRef.current) {
item.setAttribute("tabindex", "0");
if (shouldFocus) item.focus();
} else item.setAttribute("tabindex", "-1");
});
};
const handleKeyDown = (event) => {
const items = getItems();
if (items.length === 0) return;
const currentItem = items[focusedIndexRef.current];
let handled = false;
switch (event.key) {
case "ArrowDown":
event.preventDefault();
updateItemFocus(focusedIndexRef.current + 1);
handled = true;
break;
case "ArrowUp":
event.preventDefault();
updateItemFocus(focusedIndexRef.current - 1);
handled = true;
break;
case "ArrowRight":
if (currentItem && currentItem.hasAttribute("data-has-children")) {
event.preventDefault();
currentItem.querySelector(`.${require_context.blockClass}-row__nav-indicator`)?.click();
handled = true;
}
break;
case "Enter":
case " ":
event.preventDefault();
if (currentItem) currentItem.querySelector("input[type=\"checkbox\"], input[type=\"radio\"]")?.click();
handled = true;
break;
case "Home":
if (event.ctrlKey) {
event.preventDefault();
updateItemFocus(0);
handled = true;
}
break;
case "End":
if (event.ctrlKey) {
event.preventDefault();
updateItemFocus(items.length - 1);
handled = true;
}
break;
}
if (handled) event.stopPropagation();
};
(0, react.useEffect)(() => {
updateItemFocus(0, false);
}, [children]);
const listClasses = (0, import_classnames.default)(`${require_context.blockClass}-list`, className);
const listBodyClasses = (0, import_classnames.default)(`${require_context.blockClass}-list-body`, { [`${require_context.blockClass}-list-body--horizontal`]: layout === "horizontal" });
return /* @__PURE__ */ react.default.createElement("div", {
className: listClasses,
ref: (node) => {
listRef.current = node;
if (typeof ref === "function") ref(node);
else if (ref) ref.current = node;
},
role: "grid",
"aria-multiselectable": multi,
tabIndex: 0,
onKeyDown: handleKeyDown,
...rest
}, /* @__PURE__ */ react.default.createElement("div", { className: listBodyClasses }, children));
});
AddSelectContent.propTypes = {
children: prop_types.default.node,
className: prop_types.default.string,
/**@ts-ignore */
layout: prop_types.default.oneOf(["vertical", "horizontal"])
};
AddSelectContent.displayName = "AddSelectContent";
//#endregion
exports.default = AddSelectContent;