UNPKG

@carbon/ibm-products

Version:
172 lines (170 loc) 7.33 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 { useResizeObserver } from "../../../global/js/hooks/useResizeObserver.js"; import { blockClass } from "../PageHeaderUtils.js"; import { PageHeaderContext } from "./context.js"; import { getHeaderOffset } from "./utils.js"; import { PageHeaderBreadcrumbBar } from "./PageHeaderBreadcrumbBar.js"; import { PageHeaderContent } from "./PageHeaderContent.js"; import { PageHeaderContentPageActions } from "./PageHeaderContentPageActions.js"; import { PageHeaderContentText } from "./PageHeaderContentText.js"; import { PageHeaderHeroImage } from "./PageHeaderHeroImage.js"; import { PageHeaderTabBar } from "./PageHeaderTabBar.js"; import { PageHeaderTagOverflow } from "./PageHeaderTagOverflow.js"; import { PageHeaderScrollButton } from "./PageHeaderScrollButton.js"; import { PageHeaderTitleBreadcrumb } from "./PageHeaderTitleBreadcrumb.js"; import { PageHeaderBreadcrumbOverflow } from "./PageHeaderBreadcrumbOverflow.js"; import { PageHeaderBreadcrumbPageActions } from "./PageHeaderBreadcrumbPageActions.js"; import React, { useEffect, useMemo, useRef, useState } from "react"; //#region src/components/PageHeader/next/PageHeader.tsx /** * Copyright IBM Corp. 2025, 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 PageHeader = React.forwardRef(function PageHeader({ className, children, onContentFullyCollapsed, onTitleClipped, onContentActionsClipped, ...other }, ref) { const [refs, setRefs] = useState({}); const [pageActionsInstance, setPageActionsInstance] = useState(null); const [disableStickyTabBar, setDisableStickyTabBar] = useState(false); const tempRef = useRef(null); const componentRef = ref ?? tempRef; const classNames = (0, import_classnames.default)({ [`${blockClass}`]: true, [`${blockClass}__next`]: true, [`${blockClass}--disable-sticky-tab-bar`]: disableStickyTabBar }, className); useResizeObserver(componentRef, () => { if (componentRef?.current) { const pageHeaderContentHeight = refs?.contentRef?.current?.offsetHeight ?? 0; const totalHeaderOffset = getHeaderOffset(componentRef?.current); componentRef?.current.style.setProperty(`--${pkg.prefix}-page-header-header-top`, `${(Math.round(pageHeaderContentHeight) - totalHeaderOffset) * -1}px`); componentRef?.current.style.setProperty(`--${pkg.prefix}-page-header-breadcrumb-top`, `${totalHeaderOffset}px`); } }); const [fullyCollapsed, setFullyCollapsed] = useState(false); const [titleClipped, setTitleClipped] = useState(false); const [contentActionsClipped, setContentActionsClipped] = useState(false); useEffect(() => { if (!componentRef?.current) return; const totalHeaderOffset = getHeaderOffset(componentRef?.current); const predefinedContentPadding = 24; const contentObserver = refs?.contentRef?.current ? new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.target === refs?.contentRef.current) { const collapsed = !entry.isIntersecting; setFullyCollapsed(collapsed); onContentFullyCollapsed?.(collapsed); } }); }, { root: null, rootMargin: `${(predefinedContentPadding + (refs?.contentRef?.current?.offsetHeight || 0) + totalHeaderOffset + 24) * -1}px 0px 0px 0px`, threshold: .1 }) : null; const titleObserver = refs?.titleRef?.current ? new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.target === refs?.titleRef.current) { const clipped = !entry.isIntersecting; setTitleClipped(clipped); onTitleClipped?.(clipped); } }); }, { root: null, rootMargin: `${(predefinedContentPadding + (refs?.titleRef.current.offsetHeight || 0) + totalHeaderOffset + 24) * -1}px 0px 0px 0px`, threshold: .1 }) : null; const contentActionsObserver = refs?.contentActions?.current ? new IntersectionObserver((entries) => { entries.forEach((entry) => { if (entry.target === refs?.contentActions.current) { const clipped = !entry.isIntersecting; setContentActionsClipped(clipped); onContentActionsClipped?.(clipped); } }); }, { root: null, rootMargin: `${(predefinedContentPadding + (refs?.contentActions?.current?.offsetHeight || 0) + totalHeaderOffset + 24) * -1}px 0px 0px 0px`, threshold: .1 }) : null; if (refs?.contentRef?.current && contentObserver) contentObserver.observe(refs.contentRef.current); if (refs?.titleRef?.current && titleObserver) titleObserver.observe(refs.titleRef.current); if (refs?.contentActions?.current && contentActionsObserver) contentActionsObserver.observe(refs.contentActions.current); return () => { contentObserver?.disconnect(); titleObserver?.disconnect(); contentActionsObserver?.disconnect(); }; }, [ refs?.contentRef, refs?.titleRef, refs?.contentActions, componentRef, onContentFullyCollapsed, onTitleClipped, onContentActionsClipped ]); const observerState = useMemo(() => ({ fullyCollapsed, titleClipped, contentActionsClipped }), [ fullyCollapsed, titleClipped, contentActionsClipped ]); return /* @__PURE__ */ React.createElement(PageHeaderContext.Provider, { value: { refs, setRefs, pageActionsInstance, setPageActionsInstance, observerState, disableStickyTabBar, setDisableStickyTabBar } }, /* @__PURE__ */ React.createElement("div", { className: classNames, ref: componentRef, ...other }, children)); }); PageHeader.displayName = "PageHeader"; /** * ------- * 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"; const TagOverflow = PageHeaderTagOverflow; TagOverflow.displayName = "PageHeaderTagOverflow"; const BreadcrumbPageActions = PageHeaderBreadcrumbPageActions; BreadcrumbPageActions.displayName = "PageHeaderBreadcrumbPageActions"; //#endregion export { BreadcrumbBar, BreadcrumbOverflow, BreadcrumbPageActions, Content, ContentPageActions, ContentText, HeroImage, PageHeader, Root, ScrollButton, TabBar, TagOverflow, TitleBreadcrumb };