@carbon/ibm-products
Version:
Carbon for IBM Products
159 lines (147 loc) • 4.71 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.
*/
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
import React__default, { useState, useRef, useEffect } from 'react';
import PropTypes from '../../_virtual/index.js';
import cx from 'classnames';
import { NavList, blockClass as blockClass$1 } from './NavList.js';
import { NavItem, blockClass as blockClass$2 } from './NavItem.js';
import { getDevtoolsProps } from '../../global/js/utils/devtools.js';
import { pkg } from '../../settings.js';
const componentName = 'Nav';
const blockClass = `${pkg.prefix}--nav`;
/**
* @deprecated This component is deprecated
*/
let Nav = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
let {
activeHref,
className,
children,
heading,
label,
...rest
} = _ref;
const [_activeHref, setActiveHref] = useState(activeHref);
const navigationLists = useRef({});
useEffect(() => {
if (!_activeHref && window.location) {
const {
hash,
pathname
} = window.location;
setActiveHref(pathname + hash);
}
}, [_activeHref]);
/**
* Creates a new child list item.
* @param {NavItem} child The child list item to create.
* @param {number} index The index of the child list item.
* @returns {NavItem} The new child list item.
*/
const buildNewItemChild = (child, index) => {
const key = `${blockClass$2}--${index}`;
return /*#__PURE__*/React__default.createElement(NavItem, _extends({}, child.props, {
activeHref: _activeHref,
key: key,
onClick: (event, href) => handleItemClick(event, href, child.props.onClick)
}));
};
/**
* Creates a new child list.
* @param {NavList} child The child list to create.
* @param {number} index The index of the child list.
* @returns {NavList} The new child list.
*/
const buildNewListChild = (child, index) => {
const key = `${blockClass$1}--${index}`;
return /*#__PURE__*/React__default.createElement(NavList, _extends({}, child.props, {
activeHref: _activeHref,
id: key,
key: key,
onListClick: handleListClick,
onItemClick: handleItemClick,
ref: el => navigationLists.current[key] = el
}));
};
/**
* Handles toggling the list item.
* @param {SyntheticEvent} event The event fired when the list item is toggled.
* @param {string} href The URL of the list item.
*/
const handleItemClick = (event, href, onClick) => {
event.stopPropagation();
const {
type,
which
} = event;
// Enter (13) and spacebar (32).
const acceptableEvent = which === 13 || which === 32 || type === 'click';
const diffHref = href !== _activeHref;
if (acceptableEvent && diffHref) {
setActiveHref(href);
}
if (onClick) {
onClick(event);
}
};
/**
* Handles when a list has been selected.
* @param {number} id The index of the list.
*/
const handleListClick = id => {
Object.keys(navigationLists.current).forEach(key => {
if (key !== id && !navigationLists.current[key].isExpandedOnPageLoad) {
navigationLists.current[key].close();
}
});
};
return /*#__PURE__*/React__default.createElement("nav", _extends({
className: cx(blockClass, className),
"aria-label": label,
ref: ref
}, getDevtoolsProps(componentName), rest), heading && /*#__PURE__*/React__default.createElement("h1", {
className: `${blockClass}__heading`
}, heading), /*#__PURE__*/React__default.createElement("ul", {
className: `${blockClass}__wrapper`,
role: "menubar"
}, React__default.Children.map(children, (child, index) => {
return child?.type?.displayName === NavList.displayName ? buildNewListChild(child, index) : buildNewItemChild(child, index);
})));
});
Nav.deprecated = {
level: 'warn',
details: `This component is deprecated`
};
Nav.propTypes = {
/**
* Hypertext reference for active page.
*/
activeHref: PropTypes.string,
/**
* Child elements.
*/
children: PropTypes.node,
/**
* Extra classes to add.
*/
className: PropTypes.string,
/**
* Heading.
*/
heading: PropTypes.string,
/**
* Aria-label on the rendered `nav` element.
*/
label: PropTypes.string.isRequired
};
// Return a placeholder if not released and not enabled by feature flag
Nav = pkg.checkComponentEnabled(Nav, componentName);
// The display name of the component, used by React. Note that displayName
// is used in preference to relying on function.name.
Nav.displayName = componentName;
export { Nav };