UNPKG

@carbon/ibm-products

Version:
83 lines (81 loc) 3.32 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 { pkg } from "../../settings.js"; import { getDevtoolsProps } from "../../global/js/utils/devtools.js"; import { getFocusableElements } from "../../global/js/utils/getFocusableElements.js"; import React, { createContext, forwardRef, useCallback, useEffect, useRef, useState } from "react"; import { bool, node, string } from "prop-types"; //#region src/components/Toolbar/Toolbar.tsx /** * Copyright IBM Corp. 2021, 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. */ var import_classnames = /* @__PURE__ */ __toESM(require_classnames()); const blockClass = `${pkg.prefix}--toolbar`; const ToolbarContext = createContext({}); /** Toolbars are a collection of action items that organize a program’s interaction patterns into a series of closely related commands. */ const Toolbar = forwardRef(({ children, className, vertical, ...rest }, r) => { const focusableElements = useRef(void 0); const getFocusableElements$1 = useCallback(() => focusableElements.current, [focusableElements]); const localRef = useRef(null); const ref = r || localRef; const [focus, setFocus] = useState(-1); useEffect(() => { focusableElements.current = getFocusableElements(ref?.["current"]); if (focus !== -1) getFocusableElements$1()?.forEach((element, index) => { element[index !== focus ? "setAttribute" : "removeAttribute"]("tabindex", "-1"); }); }); useEffect(() => { if (focus !== -1) getFocusableElements$1()?.[focus].focus(); }, [focus, getFocusableElements$1]); const [arrowNext, arrowPrevious] = !vertical ? ["ArrowRight", "ArrowLeft"] : ["ArrowDown", "ArrowUp"]; function onArrowDown(increment) { const nextFocus = focus + increment; if (getFocusableElements$1()?.[nextFocus]) setFocus(nextFocus); } function onFocus({ target }) { const elements = getFocusableElements$1(); if (elements?.includes(target)) setFocus(elements.indexOf(target)); } function onKeyDown({ key, target }) { if (getFocusableElements$1()?.includes(target)) switch (key) { case arrowNext: onArrowDown(1); break; case arrowPrevious: onArrowDown(-1); break; } } return /* @__PURE__ */ React.createElement("div", { ...rest, ref, className: (0, import_classnames.default)(blockClass, className, { [`${blockClass}--vertical`]: vertical }), onFocus, onKeyDown, ...vertical && { "aria-orientation": "vertical" }, ...getDevtoolsProps(componentName), role: "toolbar" }, /* @__PURE__ */ React.createElement(ToolbarContext.Provider, { value: { vertical } }, children)); }); const componentName = "Toolbar"; Toolbar.displayName = componentName; Toolbar.propTypes = { /** Provide the content of the `Toolbar` */ children: node.isRequired, /** Provide an optional class to be applied to the containing node */ className: string, /** Determines whether the `Toolbar` is rendered vertically */ vertical: bool }; //#endregion export { Toolbar, ToolbarContext, blockClass };