import * as React from 'react'; import { useIntl } from 'react-intl'; import Breadcrumb from './Breadcrumb'; import BreadcrumbDropdown from './BreadcrumbDropdown'; import BreadcrumbDelimiter from './BreadcrumbDelimiter'; import type { Crumb, Delimiter } from '../../../common/types/core'; import { DELIMITER_CARET, DEFAULT_ROOT, DELIMITER_SLASH } from '../../../constants'; import './Breadcrumbs.scss'; import messages from '../messages'; export interface BreadcrumbsProps { crumbs: Crumb[]; delimiter: Delimiter; isSmall?: boolean; onCrumbClick: (item: string) => void; portalElement?: HTMLElement; rootId: string; } /** * Filters out ancestors to root from the crumbs. * This is useful when the root is not All Files. * * @private * @param {string} rootId the root folder id * @param {Array} crumbs list of crumbs * @return {Array} crumbs */ function filterCrumbs(rootId: string, crumbs: Crumb[]): Crumb[] { const rootIndex = crumbs.findIndex((crumb: Crumb) => crumb.id === rootId); return rootIndex === -1 ? crumbs : crumbs.slice(rootIndex); } /** * Creates an individual breadcrumb * * @private * @param {Object} crumb single crumb data * @param {boolean} isLast is this the last crumb * @return {Element} */ function getBreadcrumb( crumbs: Crumb | Crumb[], isLast: boolean, onCrumbClick: (item: string) => void, delimiter: Delimiter, portalElement?: HTMLElement, ) { if (Array.isArray(crumbs)) { const condensed = delimiter !== DELIMITER_CARET; return ( ); } const { id, name } = crumbs; return onCrumbClick(id)} />; } const Breadcrumbs = ({ crumbs, delimiter, isSmall = false, onCrumbClick, portalElement, rootId }: BreadcrumbsProps) => { const { formatMessage } = useIntl(); if (!rootId || crumbs.length === 0) { return ; } // The crumbs given may have ancestors higher than the root. We need to filter them out. const filteredCrumbs = filterCrumbs(rootId, crumbs); // Make sure "All Files" crumb is localized const defaultRootCrumb = filteredCrumbs.find(({ id }) => id === DEFAULT_ROOT); if (defaultRootCrumb) { defaultRootCrumb.name = formatMessage(messages.rootBreadcrumb); } const { length } = filteredCrumbs; // Always show the last/leaf breadcrumb. const crumb = filteredCrumbs[length - 1]; const onClick = crumb.id ? () => onCrumbClick(crumb.id) : undefined; const lastBreadcrumb = ; // Always show the second last/parent breadcrumb when there are at least 2 crumbs. const secondLastBreadcrumb = length > 1 ? getBreadcrumb(filteredCrumbs[length - 2], false, onCrumbClick, delimiter, portalElement) : null; // Only show the more dropdown when there were at least 4 crumbs. const moreBreadcrumbs = length > 3 ? getBreadcrumb(filteredCrumbs.slice(1, length - 2), false, onCrumbClick, delimiter, portalElement) : null; // Only show the root breadcrumb when there are at least 3 crumbs. const firstBreadcrumb = length > 2 ? getBreadcrumb(filteredCrumbs[0], false, onCrumbClick, delimiter, portalElement) : null; return (
{isSmall ? null : firstBreadcrumb} {isSmall ? null : moreBreadcrumbs} {secondLastBreadcrumb} {lastBreadcrumb}
); }; export default Breadcrumbs;