UNPKG

@carbon/react

Version:

React components for the Carbon Design System

505 lines (480 loc) 18.4 kB
/** * Copyright IBM Corp. 2016, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js'); var React = require('react'); var PropTypes = require('prop-types'); var cx = require('classnames'); var usePrefix = require('../../internal/usePrefix.js'); var layout = require('@carbon/layout'); var useMatchMedia = require('../../internal/useMatchMedia.js'); require('../Text/index.js'); var index = require('../MenuButton/index.js'); require('../Menu/Menu.js'); var MenuItem = require('../Menu/MenuItem.js'); var DefinitionTooltip = require('../Tooltip/DefinitionTooltip.js'); require('../Tooltip/Tooltip.js'); var AspectRatio = require('../AspectRatio/AspectRatio.js'); var utilities = require('@carbon/utilities'); var Tag = require('../Tag/Tag.js'); require('../Tag/DismissibleTag.js'); var OperationalTag = require('../Tag/OperationalTag.js'); require('../Tag/SelectableTag.js'); require('../Tag/Tag.Skeleton.js'); var useOverflowItems = require('../../internal/useOverflowItems.js'); var index$1 = require('../Popover/index.js'); var useId = require('../../internal/useId.js'); require('../Grid/FlexGrid.js'); var Grid = require('../Grid/Grid.js'); require('../Grid/Row.js'); var Column = require('../Grid/Column.js'); require('../Grid/ColumnHang.js'); require('../Grid/GridContext.js'); var Text = require('../Text/Text.js'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var React__default = /*#__PURE__*/_interopDefaultLegacy(React); var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes); var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx); /** * ---------- * PageHeader * ---------- */ const PageHeader = /*#__PURE__*/React__default["default"].forwardRef(function PageHeader({ className, children, ...other }, ref) { const prefix = usePrefix.usePrefix(); const classNames = cx__default["default"]({ [`${prefix}--page-header`]: true }, className); return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ className: classNames, ref: ref }, other), children); }); PageHeader.displayName = 'PageHeader'; /** * ----------------------- * PageHeaderBreadcrumbBar * ----------------------- */ const PageHeaderBreadcrumbBar = /*#__PURE__*/React__default["default"].forwardRef(function PageHeaderBreadcrumbBar({ border = true, className, children, renderIcon: IconElement, contentActions, contentActionsFlush, pageActions, pageActionsFlush, ...other }, ref) { const prefix = usePrefix.usePrefix(); const classNames = cx__default["default"]({ [`${prefix}--page-header__breadcrumb-bar`]: true, [`${prefix}--page-header__breadcrumb-bar-border`]: border, [`${prefix}--page-header__breadcrumb__actions-flush`]: pageActionsFlush }, className); const contentActionsClasses = cx__default["default"]({ [`${prefix}--page-header__breadcrumb__content-actions`]: !contentActionsFlush }); return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ className: classNames, ref: ref }, other), /*#__PURE__*/React__default["default"].createElement(Grid.Grid, null, /*#__PURE__*/React__default["default"].createElement(Column["default"], { lg: 16, md: 8, sm: 4 }, /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__breadcrumb-container` }, /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__breadcrumb-wrapper` }, IconElement && /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__breadcrumb__icon` }, /*#__PURE__*/React__default["default"].createElement(IconElement, null)), children), /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__breadcrumb__actions` }, /*#__PURE__*/React__default["default"].createElement("div", { className: contentActionsClasses }, contentActions), pageActions))))); }); PageHeaderBreadcrumbBar.displayName = 'PageHeaderBreadcrumbBar'; /** * ----------------- * PageHeaderContent * ----------------- */ const PageHeaderContent = /*#__PURE__*/React__default["default"].forwardRef(function PageHeaderContent({ className, children, title, renderIcon: IconElement, contextualActions, pageActions, ...other }, ref) { const prefix = usePrefix.usePrefix(); const classNames = cx__default["default"]({ [`${prefix}--page-header__content`]: true }, className); const titleRef = React.useRef(null); const [isEllipsisApplied, setIsEllipsisApplied] = React.useState(false); const isEllipsisActive = element => { setIsEllipsisApplied(element.offsetHeight < element.scrollHeight); return element.offsetHeight < element.scrollHeight; }; React.useLayoutEffect(() => { titleRef.current && isEllipsisActive(titleRef.current); }, [title]); return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ className: classNames, ref: ref }, other), /*#__PURE__*/React__default["default"].createElement(Grid.Grid, null, /*#__PURE__*/React__default["default"].createElement(Column["default"], { lg: 16, md: 8, sm: 4 }, /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__content__title-wrapper` }, /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__content__start` }, /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__content__title-container` }, IconElement && /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__content__icon` }, /*#__PURE__*/React__default["default"].createElement(IconElement, null)), isEllipsisApplied ? /*#__PURE__*/React__default["default"].createElement(DefinitionTooltip.DefinitionTooltip, { definition: title }, /*#__PURE__*/React__default["default"].createElement(Text.Text, { ref: titleRef, as: "h4", className: `${prefix}--page-header__content__title` }, title)) : /*#__PURE__*/React__default["default"].createElement(Text.Text, { ref: titleRef, as: "h4", className: `${prefix}--page-header__content__title` }, title)), contextualActions && /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__content__contextual-actions` }, contextualActions)), pageActions), children))); }); PageHeaderContent.displayName = 'PageHeaderContent'; PageHeaderContent.propTypes = { /** * Provide child elements to be rendered inside PageHeaderContent. */ children: PropTypes__default["default"].node, /** * Specify an optional className to be added to your PageHeaderContent */ className: PropTypes__default["default"].string, /** * Provide an optional icon to render in front of the PageHeaderContent's title. */ renderIcon: PropTypes__default["default"].oneOfType([PropTypes__default["default"].func, PropTypes__default["default"].object]), /** * The PageHeaderContent's title */ title: PropTypes__default["default"].string.isRequired, /** * The PageHeaderContent's subtitle */ subtitle: PropTypes__default["default"].string, /** * The PageHeaderContent's contextual actions */ contextualActions: PropTypes__default["default"].node, /** * The PageHeaderContent's page actions */ pageActions: PropTypes__default["default"].node }; /** * ---------------- * PageHeaderContentPageActions * ---------------- */ const PageHeaderContentPageActions = ({ className, children, menuButtonLabel = 'Actions', actions, ...other }) => { const prefix = usePrefix.usePrefix(); const classNames = cx__default["default"]({ [`${prefix}--page-header__content__page-actions`]: true }, className); const containerRef = React.useRef(null); const offsetRef = React.useRef(null); const [menuButtonVisibility, setMenuButtonVisibility] = React.useState(false); const [hiddenItems, setHiddenItems] = React.useState([]); // need to set the grid columns width based on the menu button's width // to avoid overlapping when resizing React.useLayoutEffect(() => { if (menuButtonVisibility && offsetRef.current) { const width = offsetRef.current.offsetWidth; document.documentElement.style.setProperty('--pageheader-title-grid-width', `${width}px`); } }, [menuButtonVisibility]); React.useEffect(() => { if (!containerRef.current || !Array.isArray(actions)) return; utilities.createOverflowHandler({ container: containerRef.current, // exclude the hidden menu button from children maxVisibleItems: containerRef.current.children.length - 1, onChange: (visible, hidden) => { setHiddenItems(actions?.slice(visible.length)); if (hidden.length > 0) { setMenuButtonVisibility(true); } } }); }, []); return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ className: classNames, ref: containerRef }, other), actions && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, Array.isArray(actions) && /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, actions.map(action => /*#__PURE__*/React__default["default"].createElement("div", { key: action.id }, /*#__PURE__*/React__default["default"].cloneElement(action.body, { ...action.body.props, onClick: action.onClick }))), /*#__PURE__*/React__default["default"].createElement("span", { "data-offset": true, "data-hidden": true, ref: offsetRef }, /*#__PURE__*/React__default["default"].createElement(index.MenuButton, { menuAlignment: "bottom-end", label: menuButtonLabel, size: "md" }, [...hiddenItems].reverse().map(item => /*#__PURE__*/React__default["default"].createElement(MenuItem.MenuItem, _rollupPluginBabelHelpers["extends"]({ key: item.id, onClick: item.onClick }, item.menuItem)))))))); }; PageHeaderContentPageActions.displayName = 'PageHeaderContentPageActions'; PageHeaderContentPageActions.propTypes = { /** * Provide child elements to be rendered inside PageHeaderContentPageActions. */ children: PropTypes__default["default"].node, /** * Specify an optional className to be added to your PageHeaderContentPageActions */ className: PropTypes__default["default"].string, /** * The PageHeaderContent's collapsible Menu button label */ menuButtonLabel: PropTypes__default["default"].string, /** * The PageHeaderContent's page actions */ actions: PropTypes__default["default"].oneOfType([PropTypes__default["default"].node, PropTypes__default["default"].array]) }; /** * ---------------- * PageHeaderContentText * ---------------- */ const PageHeaderContentText = ({ className, children, subtitle, ...other }) => { const prefix = usePrefix.usePrefix(); const classNames = cx__default["default"]({ [`${prefix}--page-header__content__body`]: true }, className); return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ className: classNames }, other), subtitle && /*#__PURE__*/React__default["default"].createElement(Text.Text, { as: "h3", className: `${prefix}--page-header__content__subtitle` }, subtitle), children); }; PageHeaderContentText.displayName = 'PageHeaderContentText'; PageHeaderContentText.propTypes = { /** * Provide child elements to be rendered inside PageHeaderContentText. */ children: PropTypes__default["default"].node, /** * Specify an optional className to be added to your PageHeaderContentText */ className: PropTypes__default["default"].string, /** * The PageHeaderContent's subtitle */ subtitle: PropTypes__default["default"].string }; /** * ---------------- * PageHeaderHeroImage * ---------------- */ const PageHeaderHeroImage = ({ className, children, ...other }) => { const prefix = usePrefix.usePrefix(); const classNames = cx__default["default"]({ [`${prefix}--page-header__hero-image`]: true }, className); const lgMediaQuery = `(min-width: ${layout.breakpoints.lg.width})`; const isLg = useMatchMedia.useMatchMedia(lgMediaQuery); return /*#__PURE__*/React__default["default"].createElement(AspectRatio["default"], _rollupPluginBabelHelpers["extends"]({ className: classNames }, other, { ratio: isLg ? '2x1' : '3x2' }), children); }; PageHeaderHeroImage.displayName = 'PageHeaderHeroImage'; PageHeaderHeroImage.propTypes = { /** * Provide child elements to be rendered inside PageHeaderHeroImage. */ children: PropTypes__default["default"].node, /** * Specify an optional className to be added to your PageHeaderHeroImage */ className: PropTypes__default["default"].string }; /** * ---------------- * PageHeaderTabBar * ---------------- */ const PageHeaderTabBar = /*#__PURE__*/React__default["default"].forwardRef(function PageHeaderTabBar({ className, children, tags = [], ...other }, ref) { const prefix = usePrefix.usePrefix(); const classNames = cx__default["default"]({ [`${prefix}--page-header__tab-bar`]: true }, className); // Early return if no tags are provided if (!tags.length) { return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ className: classNames, ref: ref }, other), /*#__PURE__*/React__default["default"].createElement(Grid.Grid, null, /*#__PURE__*/React__default["default"].createElement(Column["default"], { lg: 16, md: 8, sm: 4 }, children))); } const [openPopover, setOpenPopover] = React.useState(false); const tagSize = tags[0]?.size || 'md'; const instanceId = useId.useId('PageHeaderTabBar'); const tagsWithIds = React.useMemo(() => { return tags.map((tag, index) => ({ ...tag, id: tag.id || `tag-${index}-${instanceId}` })); }, [tags]); const tagsContainerRef = React.useRef(null); const offsetRef = React.useRef(null); // To close popover when window resizes React.useEffect(() => { const handleResize = () => { // Close the popover when window resizes to prevent unwanted opens setOpenPopover(false); }; window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, []); // overflow items hook const { visibleItems = [], hiddenItems = [], itemRefHandler = () => {} } = useOverflowItems["default"](tagsWithIds, tagsContainerRef, offsetRef) || { visibleItems: [], hiddenItems: [], itemRefHandler: () => {} }; const handleOverflowClick = React.useCallback(event => { event.stopPropagation(); setOpenPopover(prev => !prev); }, []); // Function to render tags const renderTags = () => /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__tags`, ref: tagsContainerRef }, visibleItems.map(tag => /*#__PURE__*/React__default["default"].createElement(Tag["default"], { key: tag.id, ref: node => itemRefHandler(tag.id, node), type: tag.type, size: tag.size, className: `${prefix}--page-header__tag-item` }, tag.text)), hiddenItems.length > 0 && /*#__PURE__*/React__default["default"].createElement(index$1.Popover, { open: openPopover, onRequestClose: () => setOpenPopover(false) }, /*#__PURE__*/React__default["default"].createElement(OperationalTag["default"], { onClick: handleOverflowClick, "aria-expanded": openPopover, text: `+${hiddenItems.length}`, size: tagSize }), /*#__PURE__*/React__default["default"].createElement(index$1.PopoverContent, { className: "tag-popover-content" }, /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__tags-popover-list` }, hiddenItems.map(tag => /*#__PURE__*/React__default["default"].createElement(Tag["default"], { key: tag.id, type: tag.type, size: tag.size }, tag.text)))))); return /*#__PURE__*/React__default["default"].createElement("div", _rollupPluginBabelHelpers["extends"]({ className: classNames, ref: ref }, other), /*#__PURE__*/React__default["default"].createElement(Grid.Grid, null, /*#__PURE__*/React__default["default"].createElement(Column["default"], { lg: 16, md: 8, sm: 4 }, /*#__PURE__*/React__default["default"].createElement("div", { className: `${prefix}--page-header__tab-bar--tablist` }, children, tags.length > 0 && renderTags())))); }); PageHeaderTabBar.displayName = 'PageHeaderTabBar'; /** * ------- * Exports * ------- */ const Root = PageHeader; Root.displayName = 'PageHeader.Root'; const BreadcrumbBar = PageHeaderBreadcrumbBar; BreadcrumbBar.displayName = 'PageHeaderBreadcrumbBar'; const Content = PageHeaderContent; Content.displayName = 'PageHeaderContent'; const ContentPageActions = PageHeaderContentPageActions; ContentPageActions.displayName = 'PageHeaderContentPageActions'; const ContentText = PageHeaderContentText; ContentText.displayName = 'PageHeaderContentText'; const HeroImage = PageHeaderHeroImage; HeroImage.displayName = 'PageHeaderHeroImage'; const TabBar = PageHeaderTabBar; TabBar.displayName = 'PageHeaderTabBar'; exports.BreadcrumbBar = BreadcrumbBar; exports.Content = Content; exports.ContentPageActions = ContentPageActions; exports.ContentText = ContentText; exports.HeroImage = HeroImage; exports.PageHeader = PageHeader; exports.PageHeaderBreadcrumbBar = PageHeaderBreadcrumbBar; exports.PageHeaderContent = PageHeaderContent; exports.PageHeaderContentPageActions = PageHeaderContentPageActions; exports.PageHeaderContentText = PageHeaderContentText; exports.PageHeaderHeroImage = PageHeaderHeroImage; exports.PageHeaderTabBar = PageHeaderTabBar; exports.Root = Root; exports.TabBar = TabBar;