UNPKG

@carbon/ibm-products

Version:
114 lines (112 loc) 3.77 kB
/** * 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 { AddSelectContext, blockClass } from "./context.js"; import React, { forwardRef, useContext, useEffect, useRef } from "react"; import PropTypes from "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__ */ __toESM(require_classnames()); const AddSelectContent = forwardRef(({ children, className, layout = "vertical", ...rest }, ref) => { const { multi } = useContext(AddSelectContext); const listRef = useRef(null); const focusedIndexRef = 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(`.${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(); }; useEffect(() => { updateItemFocus(0, false); }, [children]); const listClasses = (0, import_classnames.default)(`${blockClass}-list`, className); const listBodyClasses = (0, import_classnames.default)(`${blockClass}-list-body`, { [`${blockClass}-list-body--horizontal`]: layout === "horizontal" }); return /* @__PURE__ */ React.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.createElement("div", { className: listBodyClasses }, children)); }); AddSelectContent.propTypes = { children: PropTypes.node, className: PropTypes.string, /**@ts-ignore */ layout: PropTypes.oneOf(["vertical", "horizontal"]) }; AddSelectContent.displayName = "AddSelectContent"; //#endregion export { AddSelectContent as default };