UNPKG

@gravity-ui/uikit

Version:

Gravity UI base styling and components

115 lines (114 loc) 5.66 kB
'use client'; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { createElement as _createElement } from "react"; import * as React from 'react'; import { useCollapseChildren, useForkRef, useResizeObserver } from "../../hooks/index.js"; import { useDefaultProps } from "../theme/useDefaultProps.js"; import { filterDOMProps } from "../utils/filterDOMProps.js"; import { BreadcrumbsDropdownMenu } from "./BreadcrumbsDropdownMenu.js"; import { BreadcrumbsItem } from "./BreadcrumbsItem.js"; import { BreadcrumbsSeparator } from "./BreadcrumbsSeparator.js"; import { b, getReactNodeHash } from "./utils.js"; import "./Breadcrumbs.css"; export const Breadcrumbs = React.forwardRef(function Breadcrumbs(rawProps, ref) { const props = useDefaultProps('Breadcrumbs', rawProps); const listRef = React.useRef(null); const containerRef = useForkRef(ref, listRef); const menuRef = React.useRef(null); const endContentRef = React.useRef(null); const items = []; React.Children.forEach(props.children, (child, index) => { if (React.isValidElement(child)) { if (child.key === undefined || child.key === null) { child = React.cloneElement(child, { key: index }); } items.push(child); } }); const { calculated, recalculate, visibleCount: visibleItemsCount, } = useCollapseChildren({ containerRef: listRef, preservedRefs: [menuRef, endContentRef], direction: 'start', minCount: 1, maxCount: typeof props.maxItems === 'number' && props.maxItems < items.length ? props.maxItems - 1 : undefined, childSelector: `.${b('item')}`, getChildWidth: (child) => { const width = child.getBoundingClientRect().width; const maxWidth = child.dataset.current ? 200 : Infinity; return Math.min(maxWidth, width); }, }); useResizeObserver({ ref: endContentRef, onResize: recalculate, }); const childrenHash = getReactNodeHash(props.children); const separatorHash = getReactNodeHash(props.separator); React.useEffect(() => { recalculate(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [childrenHash, separatorHash, props.itemComponent]); let contents = items; if (items.length > visibleItemsCount) { contents = []; const breadcrumbs = [...items]; let endItems = visibleItemsCount; if (props.showRoot && visibleItemsCount > 1) { const rootItem = breadcrumbs.shift(); if (rootItem) { contents.push(rootItem); } endItems--; } const hiddenItems = breadcrumbs.slice(0, -endItems); const menuItem = (_jsx(BreadcrumbsDropdownMenu, { disabled: props.disabled, popupPlacement: props.popupPlacement, popupStyle: props.popupStyle, "data-breadcrumbs-menu-item": true, children: hiddenItems.map((child, index) => { const Component = props.itemComponent ?? BreadcrumbsItem; const key = child.key ?? index; const handleAction = () => { if (typeof props.onAction === 'function') { props.onAction(key); } }; const innerProps = { __index: index, __disabled: props.disabled || child.props.disabled, __onAction: handleAction, }; return (_createElement(Component, { ...child.props, key: key, ...innerProps }, child.props.children)); }) })); contents.push(menuItem); contents.push(...breadcrumbs.slice(-endItems)); } return (_jsxs("ol", { ref: containerRef, ...filterDOMProps(props, { labelable: true }), "data-qa": props.qa, className: b(null, props.className), style: props.style, children: [contents.map((child, index) => { const key = child.key ?? index; const isCurrent = index === contents.length - 1; const { 'data-breadcrumbs-menu-item': isMenu, ...childProps } = child.props; let item; if (isMenu) { item = child; } else { const Component = props.itemComponent ?? BreadcrumbsItem; const handleAction = () => { if (typeof props.onAction === 'function') { props.onAction(key); } }; const innerProps = { __current: isCurrent, __disabled: props.disabled || childProps.disabled, __onAction: handleAction, }; item = (_createElement(Component, { ...childProps, key: key, ...innerProps }, childProps.children)); } return (_jsxs("li", { ref: isMenu ? menuRef : undefined, className: b('item', { calculating: isCurrent && !calculated, current: isCurrent, }), "data-current": isCurrent ? isCurrent : undefined, children: [item, isCurrent ? null : _jsx(BreadcrumbsSeparator, { separator: props.separator })] }, isMenu ? 'menu' : `item-${key}`)); }), props.endContent && (_jsx("li", { ref: endContentRef, className: b('item'), children: props.endContent }))] })); }); Breadcrumbs.Item = BreadcrumbsItem; Breadcrumbs.displayName = 'Breadcrumbs'; //# sourceMappingURL=Breadcrumbs.js.map