@carbon/ibm-products
Version:
Carbon for IBM Products
745 lines (718 loc) • 25.9 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.
*/
'use strict';
var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var index = require('../../../_virtual/index.js');
var cx = require('classnames');
var react = require('@carbon/react');
var layout = require('@carbon/layout');
var PageHeaderUtils = require('../PageHeaderUtils.js');
var overflowHandler = require('./overflowHandler.js');
var utilities = require('@carbon/utilities');
var useOverflowItems = require('../../../global/js/hooks/useOverflowItems/useOverflowItems.js');
var useId = require('../../../global/js/utils/useId.js');
var icons = require('@carbon/react/icons');
var context = require('./context.js');
var utils = require('./utils.js');
var settings = require('../../../settings.js');
var useResizeObserver = require('../../../global/js/hooks/useResizeObserver.js');
/**
* ----------
* PageHeader
* ----------
*/
const PageHeader = /*#__PURE__*/React.forwardRef(function PageHeader(_ref, ref) {
let {
className,
children,
...other
} = _ref;
const [refs, setRefs] = React.useState({});
const tempRef = React.useRef(null);
const componentRef = ref ?? tempRef;
const classNames = cx({
[`${PageHeaderUtils.blockClass}`]: true,
[`${PageHeaderUtils.blockClass}__next`]: true
}, className);
// Used to set CSS custom property with PageHeaderContent height to be used
// for sticky positioning
useResizeObserver.useResizeObserver(componentRef, () => {
if (componentRef?.current && refs?.contentRef?.current) {
const pageHeaderContentHeight = refs?.contentRef?.current?.offsetHeight;
const totalHeaderOffset = utils.getHeaderOffset(componentRef?.current);
componentRef?.current.style.setProperty(`--${settings.pkg.prefix}-page-header-header-top`, `${(Math.round(pageHeaderContentHeight) - totalHeaderOffset) * -1}px`);
componentRef?.current.style.setProperty(`--${settings.pkg.prefix}-page-header-breadcrumb-top`, `${totalHeaderOffset}px`);
}
});
const [fullyCollapsed, setFullyCollapsed] = React.useState(false);
const [titleClipped, setTitleClipped] = React.useState(false);
// Intersection Observer setup, tracks if the PageHeaderContent is visible on page.
// If it is not visible, we should set fully collapsed to true so that the
// scroller button will know if it is clicked to expand rather than
// collapse the header.
React.useEffect(() => {
if (!refs?.contentRef || !componentRef?.current) {
return;
}
const totalHeaderOffset = utils.getHeaderOffset(componentRef?.current);
const predefinedContentPadding = 24;
const contentObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.target === refs?.contentRef.current) {
setFullyCollapsed(!entry.isIntersecting);
}
});
}, {
root: null,
rootMargin: `${(predefinedContentPadding + totalHeaderOffset + 40) * -1}px 0px 0px 0px`,
threshold: 0.1
});
if (!refs?.titleRef?.current) {
return;
}
const totalTitleHeight = refs?.titleRef.current.offsetHeight;
const titleObserver = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.target === refs?.titleRef.current) {
setTitleClipped(!entry.isIntersecting);
}
});
}, {
root: null,
rootMargin: `${(predefinedContentPadding + totalTitleHeight + totalHeaderOffset + 24) * -1}px 0px 0px 0px`,
threshold: 0.1
});
if (refs?.contentRef.current) {
contentObserver.observe(refs?.contentRef.current);
}
if (refs?.titleRef.current) {
titleObserver.observe(refs?.titleRef.current);
}
return () => {
if (!refs?.contentRef?.current) {
return;
}
contentObserver.unobserve(refs?.contentRef.current);
if (!refs?.titleRef?.current) {
return;
}
contentObserver.unobserve(refs?.titleRef.current);
};
}, [refs, componentRef]);
return /*#__PURE__*/React.createElement(context.PageHeaderContext.Provider, {
value: {
refs,
setRefs,
fullyCollapsed,
titleClipped
}
}, /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
className: classNames,
ref: componentRef
}, other), children));
});
PageHeader.displayName = 'PageHeader';
/**
* -----------------------
* PageHeaderBreadcrumbBar
* -----------------------
*/
const PageHeaderBreadcrumbBar = /*#__PURE__*/React.forwardRef(function PageHeaderBreadcrumbBar(_ref2, ref) {
let {
border = true,
className,
children,
renderIcon: IconElement,
contentActions,
contentActionsFlush,
pageActions,
pageActionsFlush,
...other
} = _ref2;
const classNames = cx({
[`${PageHeaderUtils.blockClass}__breadcrumb-bar`]: true,
[`${PageHeaderUtils.blockClass}__breadcrumb-bar-border`]: border,
[`${PageHeaderUtils.blockClass}__breadcrumb__actions-flush`]: pageActionsFlush
}, className);
const contentActionsClasses = cx({
[`${PageHeaderUtils.blockClass}__breadcrumb__content-actions`]: !contentActionsFlush
});
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
className: classNames,
ref: ref
}, other), /*#__PURE__*/React.createElement(react.Grid, null, /*#__PURE__*/React.createElement(react.Column, {
lg: 16,
md: 8,
sm: 4
}, /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__breadcrumb-container`
}, /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__breadcrumb-wrapper`
}, IconElement && /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__breadcrumb__icon`
}, /*#__PURE__*/React.createElement(IconElement, null)), children), /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__breadcrumb__actions`
}, /*#__PURE__*/React.createElement("div", {
className: contentActionsClasses
}, contentActions), pageActions)))));
});
PageHeaderBreadcrumbBar.displayName = 'PageHeaderBreadcrumbBar';
/**
* -----------------
* PageHeaderContent
* -----------------
*/
const PageHeaderContent = /*#__PURE__*/React.forwardRef(function PageHeaderContent(_ref3, ref) {
let {
className,
children,
title,
renderIcon: IconElement,
contextualActions,
pageActions,
...other
} = _ref3;
const contentRef = React.useRef(null);
const componentRef = ref ?? contentRef;
const {
setRefs
} = context.usePageHeader();
const classNames = cx({
[`${PageHeaderUtils.blockClass}__content`]: true
}, className);
const titleRef = React.useRef(null);
React.useEffect(() => {
if (componentRef?.current) {
setRefs(prev => ({
...prev,
contentRef: componentRef,
titleRef
}));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
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.createElement("div", _rollupPluginBabelHelpers.extends({
className: classNames,
ref: componentRef
}, other), /*#__PURE__*/React.createElement(react.Grid, null, /*#__PURE__*/React.createElement(react.Column, {
lg: 16,
md: 8,
sm: 4
}, /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__content__title-wrapper`
}, /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__content__start`
}, /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__content__title-container`
}, IconElement && /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__content__icon`
}, /*#__PURE__*/React.createElement(IconElement, null)), isEllipsisApplied ? /*#__PURE__*/React.createElement(react.DefinitionTooltip, {
definition: title
}, /*#__PURE__*/React.createElement(react.unstable_Text, {
ref: titleRef,
as: "h4",
className: `${PageHeaderUtils.blockClass}__content__title`
}, title)) : /*#__PURE__*/React.createElement(react.unstable_Text, {
ref: titleRef,
as: "h4",
className: `${PageHeaderUtils.blockClass}__content__title`
}, title)), contextualActions && /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__content__contextual-actions`
}, contextualActions)), pageActions), children)));
});
PageHeaderContent.displayName = 'PageHeaderContent';
PageHeaderContent.propTypes = {
/**
* Provide child elements to be rendered inside PageHeaderContent.
*/
children: index.default.node,
/**
* Specify an optional className to be added to your PageHeaderContent
*/
className: index.default.string,
/**
* The PageHeaderContent's contextual actions
*/
contextualActions: index.default.node,
/**
* The PageHeaderContent's page actions
*/
pageActions: index.default.node,
/**
* Provide an optional icon to render in front of the PageHeaderContent's title.
*/
renderIcon: index.default.oneOfType([index.default.func, index.default.object]),
/**
* The PageHeaderContent's subtitle
*/
subtitle: index.default.string,
/**
* The PageHeaderContent's title
*/
title: index.default.string.isRequired
};
/**
* ----------------
* PageHeaderContentPageActions
* ----------------
*/
const PageHeaderContentPageActions = _ref4 => {
let {
className,
children,
menuButtonLabel = 'Actions',
actions,
...other
} = _ref4;
const classNames = cx({
[`${PageHeaderUtils.blockClass}__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('--page-header-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);
}
}
});
}, [actions]);
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
className: classNames,
ref: containerRef
}, other), Array.isArray(actions) && /*#__PURE__*/React.createElement(React.Fragment, null, actions.map(action => /*#__PURE__*/React.createElement("div", {
key: action.id
}, /*#__PURE__*/React.cloneElement(action.body, {
...action.body.props,
onClick: action.onClick
}))), /*#__PURE__*/React.createElement("span", {
"data-offset": true,
"data-hidden": true,
ref: offsetRef
}, /*#__PURE__*/React.createElement(react.MenuButton, {
menuAlignment: "bottom-end",
label: menuButtonLabel,
size: "md"
}, [...hiddenItems].reverse().map(item => /*#__PURE__*/React.createElement(react.MenuItem, _rollupPluginBabelHelpers.extends({
key: item.id,
onClick: item.onClick
}, item.menuItem)))))));
};
PageHeaderContentPageActions.displayName = 'PageHeaderContentPageActions';
PageHeaderContentPageActions.propTypes = {
/**
* The PageHeaderContent's page actions
*/
actions: index.default.oneOfType([index.default.node, index.default.array]),
/**
* Provide child elements to be rendered inside PageHeaderContentPageActions.
*/
children: index.default.node,
/**
* Specify an optional className to be added to your PageHeaderContentPageActions
*/
className: index.default.string,
/**
* The PageHeaderContent's collapsible Menu button label
*/
menuButtonLabel: index.default.string
};
/**
* ----------------
* PageHeaderContentText
* ----------------
*/
const PageHeaderContentText = _ref5 => {
let {
className,
children,
subtitle,
...other
} = _ref5;
const classNames = cx({
[`${PageHeaderUtils.blockClass}__content__body`]: true
}, className);
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
className: classNames
}, other), subtitle && /*#__PURE__*/React.createElement(react.unstable_Text, {
as: "h3",
className: `${PageHeaderUtils.blockClass}__content__subtitle`
}, subtitle), children);
};
PageHeaderContentText.displayName = 'PageHeaderContentText';
PageHeaderContentText.propTypes = {
/**
* Provide child elements to be rendered inside PageHeaderContentText.
*/
children: index.default.node,
/**
* Specify an optional className to be added to your PageHeaderContentText
*/
className: index.default.string,
/**
* The PageHeaderContent's subtitle
*/
subtitle: index.default.string
};
/**
* ----------------
* PageHeaderHeroImage
* ----------------
*/
const PageHeaderHeroImage = _ref6 => {
let {
className,
children,
...other
} = _ref6;
const [lgBreakpoint, setLgBreakpoint] = React.useState(false);
const classNames = cx({
[`${PageHeaderUtils.blockClass}__hero-image`]: true
}, className);
const lgMediaQuery = `(min-width: ${layout.breakpoints.lg.width})`;
React.useEffect(() => {
const listener = event => {
setLgBreakpoint(event.matches);
};
const mediaQueryList = window.matchMedia(lgMediaQuery);
mediaQueryList.addEventListener('change', listener);
setLgBreakpoint(mediaQueryList.matches);
return () => {
mediaQueryList.removeEventListener('change', listener);
};
}, [lgMediaQuery]);
return /*#__PURE__*/React.createElement(react.AspectRatio, _rollupPluginBabelHelpers.extends({
className: classNames
}, other, {
ratio: lgBreakpoint ? '2x1' : '3x2'
}), children);
};
PageHeaderHeroImage.displayName = 'PageHeaderHeroImage';
PageHeaderHeroImage.propTypes = {
/**
* Provide child elements to be rendered inside PageHeaderHeroImage.
*/
children: index.default.node,
/**
* Specify an optional className to be added to your PageHeaderHeroImage
*/
className: index.default.string
};
/**
* ----------------
* PageHeaderTabBar
* ----------------
*/
const PageHeaderTabBar = /*#__PURE__*/React.forwardRef(function PageHeaderTabBar(_ref7, ref) {
let {
className,
children,
tags = [],
scroller,
...other
} = _ref7;
const classNames = cx({
[`${PageHeaderUtils.blockClass}__tab-bar`]: true
}, className);
const renderScroller = () => scroller && /*#__PURE__*/React.createElement("div", {
className: `${settings.pkg.prefix}--page-header--scroller-button-container`
}, scroller);
// Early return if no tags are provided
if (!tags.length) {
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
className: classNames,
ref: ref
}, other), /*#__PURE__*/React.createElement(react.Grid, null, /*#__PURE__*/React.createElement(react.Column, {
lg: 16,
md: 8,
sm: 4
}, children, renderScroller())));
}
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}`
}));
}, [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.useOverflowItems(tagsWithIds, tagsContainerRef, offsetRef) || {
visibleItems: [],
hiddenItems: [],
itemRefHandler: () => {}
};
const handleOverflowClick = React.useCallback(event => {
event.stopPropagation();
setOpenPopover(prev => !prev);
}, []);
// Function to render tags
const renderTags = () => /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__tags`,
ref: tagsContainerRef
}, visibleItems.map(tag => /*#__PURE__*/React.createElement(react.Tag, {
key: tag.id,
ref: node => itemRefHandler(tag.id, node),
type: tag.type,
size: tag.size,
className: `${PageHeaderUtils.blockClass}__tag-item`
}, tag.text)), hiddenItems.length > 0 && /*#__PURE__*/React.createElement(react.Popover, {
open: openPopover,
onRequestClose: () => setOpenPopover(false)
}, /*#__PURE__*/React.createElement(react.OperationalTag, {
onClick: handleOverflowClick,
"aria-expanded": openPopover,
text: `+${hiddenItems.length}`,
size: tagSize
}), /*#__PURE__*/React.createElement(react.PopoverContent, {
className: "tag-popover-content"
}, /*#__PURE__*/React.createElement("div", {
className: `${PageHeaderUtils.blockClass}__tags-popover-list`
}, hiddenItems.map(tag => /*#__PURE__*/React.createElement(react.Tag, {
key: tag.id,
type: tag.type,
size: tag.size
}, tag.text))))));
return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({
className: classNames,
ref: ref
}, other), /*#__PURE__*/React.createElement(react.Grid, null, /*#__PURE__*/React.createElement(react.Column, {
lg: 16,
md: 8,
sm: 4
}, /*#__PURE__*/React.createElement("div", {
className: cx(`${PageHeaderUtils.blockClass}__tab-bar--tablist`, {
[`${settings.pkg.prefix}--page-header__tab-bar--with-scroller`]: !!scroller
})
}, children, tags.length > 0 && renderTags(), renderScroller()))));
});
PageHeaderTabBar.displayName = 'PageHeaderTabBar';
const PageHeaderScrollButton = /*#__PURE__*/React.forwardRef(function PageHeaderExpander(_ref8, ref) {
let {
className,
children,
label,
onClick,
collapseText = 'Collapse',
expandText = 'Expand',
...other
} = _ref8;
const {
refs,
fullyCollapsed
} = context.usePageHeader();
const handleScroller = isFullyCollapsed => {
if (!refs?.contentRef?.current) {
return;
}
const scrollableTarget = utils.scrollableAncestor(refs?.contentRef.current);
// Page header content is not fully collapsed
if (!isFullyCollapsed) {
const pageHeaderContentHeight = refs?.contentRef.current.offsetHeight;
scrollableTarget?.scrollTo({
top: pageHeaderContentHeight,
// headerTopValue, check if breadcrumb bar is included
behavior: 'smooth'
});
} else {
// Page header content is fully collapsed
scrollableTarget?.scrollTo({
top: 0,
behavior: 'smooth'
});
}
};
return /*#__PURE__*/React.createElement(react.IconButton, _rollupPluginBabelHelpers.extends({
ref: ref,
label: fullyCollapsed ? expandText : collapseText,
size: "md",
kind: "ghost",
autoAlign: true
}, other, {
onClick: event => {
onClick?.(event);
handleScroller(!!fullyCollapsed);
},
className: cx(className, `${settings.pkg.prefix}--page-header--scroller-button`)
}), /*#__PURE__*/React.createElement(icons.ChevronUp, {
className: cx(`${settings.pkg.prefix}--page-header--scroller-button-icon`, {
[`${settings.pkg.prefix}--page-header--scroller-button-icon-collapsed`]: fullyCollapsed
})
}));
});
const PageHeaderTitleBreadcrumb = /*#__PURE__*/React.forwardRef((_ref9, ref) => {
let {
className,
children,
...other
} = _ref9;
const {
titleClipped,
refs
} = context.usePageHeader();
return /*#__PURE__*/React.createElement(react.BreadcrumbItem, _rollupPluginBabelHelpers.extends({
ref: ref,
isCurrentPage: true
}, other, {
className: cx(className, `${settings.pkg.prefix}--page-header-title-breadcrumb`, {
[`${settings.pkg.prefix}--page-header-title-breadcrumb-show`]: titleClipped && refs?.titleRef
})
}), children);
});
// This component is a wrapper for the Breadcrumb, and renders breadcrumb items as children
// including the overflow breadcrumb item. The overflowHandler determines what elements
// are visible and hidden and passes the hidden elements back to the render prop used
// to display the overflow breadcrumb
const PageHeaderBreadcrumbOverflow = /*#__PURE__*/React.forwardRef((_ref10, ref) => {
let {
renderOverflowBreadcrumb,
className,
children,
...other
} = _ref10;
const [hiddenBreadcrumbs, setHiddenBreadcrumbs] = React.useState([]);
const fallbackRef = React.useRef(null);
const componentRef = ref ?? fallbackRef;
// Initialize overflow resize handler
const carbonPrefix = react.usePrefix();
React.useEffect(() => {
if (!componentRef) {
return;
}
const breadcrumbList = componentRef?.current.querySelector(`.${carbonPrefix}--breadcrumb`);
overflowHandler.createOverflowHandler({
container: breadcrumbList,
onChange: (_, hidden) => {
setHiddenBreadcrumbs(hidden);
}
});
// Don't want ref or carbon prefix in dependency array
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const renderChildren = () => {
// Only BreadcrumbItems and TitleBreadcrumbs are valid children
const filteredBreadcrumbs = React.Children.toArray(children).filter(child => {
if (/*#__PURE__*/React.isValidElement(child)) {
return child.type === react.BreadcrumbItem || PageHeaderTitleBreadcrumb;
}
});
// We need to clone the renderProp for the overflow breadcrumb item
// to place it before the title breadcrumb according to the design
if (filteredBreadcrumbs) {
const overflowBreadcrumb = renderOverflowBreadcrumb?.(hiddenBreadcrumbs);
// If no overflow breadcrumb provided, return here with the rest of the children
if (!overflowBreadcrumb) {
return children;
}
const clonedTitleBreadcrumb = /*#__PURE__*/React.cloneElement(overflowBreadcrumb, {
key: 'cloned overflow breadcrumb item',
'data-fixed': true,
className: cx(`${settings.pkg.prefix}--page-header-breadcrumb-overflow-item`, {
[`${settings.pkg.prefix}--page-header-overflow-breadcrumb-item-with-items`]: hiddenBreadcrumbs.length
})
});
const clonedChildren = [...filteredBreadcrumbs];
clonedChildren.splice(filteredBreadcrumbs.length - 1, 0, clonedTitleBreadcrumb); // second to last position
return clonedChildren;
}
return children;
};
return /*#__PURE__*/React.createElement(react.Breadcrumb, _rollupPluginBabelHelpers.extends({
className: cx(className, `${settings.pkg.prefix}--page-header-breadcrumb-overflow`),
ref: componentRef
}, other), renderChildren());
});
/**
* -------
* 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';
const ScrollButton = PageHeaderScrollButton;
ScrollButton.displayName = 'PageHeaderScrollButton';
const TitleBreadcrumb = PageHeaderTitleBreadcrumb;
TitleBreadcrumb.displayName = 'PageHeaderTitleBreadcrumb';
const BreadcrumbOverflow = PageHeaderBreadcrumbOverflow;
BreadcrumbOverflow.displayName = 'PageHeaderBreadcrumbOverflow';
exports.BreadcrumbBar = BreadcrumbBar;
exports.BreadcrumbOverflow = BreadcrumbOverflow;
exports.Content = Content;
exports.ContentPageActions = ContentPageActions;
exports.ContentText = ContentText;
exports.HeroImage = HeroImage;
exports.PageHeader = PageHeader;
exports.PageHeaderBreadcrumbBar = PageHeaderBreadcrumbBar;
exports.PageHeaderBreadcrumbOverflow = PageHeaderBreadcrumbOverflow;
exports.PageHeaderContent = PageHeaderContent;
exports.PageHeaderContentPageActions = PageHeaderContentPageActions;
exports.PageHeaderContentText = PageHeaderContentText;
exports.PageHeaderHeroImage = PageHeaderHeroImage;
exports.PageHeaderScrollButton = PageHeaderScrollButton;
exports.PageHeaderTabBar = PageHeaderTabBar;
exports.PageHeaderTitleBreadcrumb = PageHeaderTitleBreadcrumb;
exports.Root = Root;
exports.ScrollButton = ScrollButton;
exports.TabBar = TabBar;
exports.TitleBreadcrumb = TitleBreadcrumb;