@talend/react-components
Version:
Set of react components.
179 lines (174 loc) • 5.18 kB
JavaScript
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { withTranslation } from 'react-i18next';
import { randomUUID } from '@talend/utils';
import theme from './Breadcrumbs.module.scss';
import { Action, ActionDropdown } from '../Actions';
import Skeleton from '../Skeleton/Skeleton.component';
import I18N_DOMAIN_COMPONENTS from '../constants';
import getDefaultT from '../translate';
/**
* Default max items to display
* @type {number}
*/
import { jsx as _jsx } from "react/jsx-runtime";
const DEFAULT_MAX_ITEMS = 4;
/**
* Default number of items before adding an ellipsis
* @type {number}
*/
const DEFAULT_NB_ITEMS_BEFORE_ELLIPSIS = 1;
const BREADCRUMB_SKELETON = [{
type: Skeleton.TYPES.text,
size: Skeleton.SIZES.large
}, {
type: Skeleton.TYPES.circle,
size: Skeleton.SIZES.small
}, {
type: Skeleton.TYPES.text,
size: Skeleton.SIZES.large
}];
/**
* Indicate the current page location within a navigational hierarchy.
* @param {object} props react props
* @example
<Breadcrumbs
maxItems={4}
items={items}
/>
*/
export function BreadcrumbsComponent({
loading,
id,
items,
maxItems,
t
}) {
if (loading) {
return /*#__PURE__*/_jsx("div", {
className: classNames(theme['tc-breadcrumb'], theme.loading, 'tc-breadcrumb', 'tc-breadcrumb--loading'),
children: BREADCRUMB_SKELETON.map(({
size,
type
}, index) => /*#__PURE__*/_jsx(Skeleton, {
size: size,
type: type
}, index))
});
}
const nbItems = items.length;
const maxItemsReached = nbItems > maxItems;
const ellipsisIndex = nbItems - maxItems + DEFAULT_NB_ITEMS_BEFORE_ELLIPSIS;
const hiddenItems = items.slice(DEFAULT_NB_ITEMS_BEFORE_ELLIPSIS, ellipsisIndex + 1).map((hiddenItem, index) => ({
id: `${id}-item-${index + DEFAULT_NB_ITEMS_BEFORE_ELLIPSIS}`,
label: hiddenItem.text,
title: hiddenItem.title,
onClick: event => hiddenItem.onClick(event, hiddenItem)
}));
/**
* Render breadcrumb item
* @param item Plain object representative of breadcrumb item
* @param index Item position
* @returns {*} Breadcrumb item rendering depending of its position
*/
function renderBreadcrumbItem(item, index) {
const {
text,
title,
onClick
} = item;
const isActive = index === nbItems - 1;
const itemId = `${id}-item-${index}`;
/**
* Wrapper for onClick in order to return item
* @param args Arguments of default onClick callback
* @returns {Function} New callback with the item
*/
let wrappedOnClick;
if (onClick) {
wrappedOnClick = event => onClick(event, item);
}
function getItemContent() {
if (!isActive && onClick) {
return /*#__PURE__*/_jsx(Action, {
id: itemId,
bsStyle: "link",
role: "link",
title: title || text,
"aria-label": title,
label: text,
onClick: wrappedOnClick
});
}
const ariaCurrent = isActive ? 'page' : undefined;
return (
/*#__PURE__*/
// bug in eslint a11y plugin, fixed in version 6.
// But to upgrade we need to upgrade the whole package (eslint, airbnb, a11y, react)
// eslint-disable-next-line jsx-a11y/aria-props
_jsx("span", {
id: itemId,
title: title,
"aria-current": ariaCurrent,
children: text
})
);
}
if (maxItemsReached && index > 0 && index < ellipsisIndex) {
return undefined;
}
if (maxItemsReached && index === ellipsisIndex) {
return /*#__PURE__*/_jsx("li", {
className: "tc-breadcrumb-menu",
children: /*#__PURE__*/_jsx(ActionDropdown, {
id: `${id}-ellipsis`,
items: hiddenItems,
"aria-label": t('BREADCRUMB_OPEN_FIRST_LINKS_MENU', {
defaultValue: 'Show breadcrumb links'
}),
label: "\u2026",
link: true,
noCaret: true
})
}, index + 0.1);
}
return /*#__PURE__*/_jsx("li", {
className: classNames('tc-breadcrumb-item', {
active: isActive
}),
children: getItemContent()
}, index);
}
return /*#__PURE__*/_jsx("nav", {
"aria-label": t('BREADCRUMB', {
defaultValue: 'breadcrumb'
}),
children: /*#__PURE__*/_jsx("ul", {
id: id,
className: classNames('breadcrumb', theme['tc-breadcrumb'], 'tc-breadcrumb'),
children: items.map(renderBreadcrumbItem)
})
});
}
BreadcrumbsComponent.displayName = 'Breadcrumbs';
if (process.env.NODE_ENV !== 'production') {
BreadcrumbsComponent.propTypes = {
id: PropTypes.string,
loading: PropTypes.bool,
items: PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string.isRequired,
title: PropTypes.string,
onClick: PropTypes.func
})),
maxItems: PropTypes.number,
t: PropTypes.func
};
}
BreadcrumbsComponent.defaultProps = {
id: randomUUID(),
items: [],
maxItems: DEFAULT_MAX_ITEMS,
t: getDefaultT()
};
export default withTranslation(I18N_DOMAIN_COMPONENTS)(BreadcrumbsComponent);
//# sourceMappingURL=Breadcrumbs.component.js.map