Skip to content

Commit

Permalink
fix: content of tooltips in the Breadcrumb (microsoft#30009)
Browse files Browse the repository at this point in the history
  • Loading branch information
ValentinaKozlova committed Dec 7, 2023
1 parent 841ad6a commit c8cbe2a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 22 deletions.
Expand Up @@ -11,15 +11,16 @@ import {
tokens,
Button,
Menu,
MenuItemLink,
MenuList,
MenuPopover,
MenuTrigger,
useIsOverflowItemVisible,
useOverflowMenu,
Overflow,
OverflowItem,
MenuItemLink,
OverflowDivider,
Tooltip,
} from '@fluentui/react-components';
import {
CalendarMonthFilled,
Expand Down Expand Up @@ -118,6 +119,14 @@ const useExampleStyles = makeStyles({
},
});

const useTooltipStyles = makeStyles({
tooltip: {
whiteSpace: 'nowrap',
...shorthands.overflow('hidden'),
textOverflow: 'ellipsis',
},
});

const MenuItem: React.FC<{ id: string; item: Item }> = props => {
const { item, id } = props;
const isVisible = useIsOverflowItemVisible(id);
Expand Down Expand Up @@ -159,27 +168,54 @@ const renderBreadcrumbItem = (el: Item, isLastItem: boolean = false) => {
);
};

const getTooltipContent = (breadcrumbItems: readonly Item[] | undefined) => {
if (!breadcrumbItems) {
return '';
}
return breadcrumbItems.reduce((acc, initialValue, idx, arr) => {
return (
<>
{acc}
{arr[0].item !== initialValue.item && ' > '}
{initialValue.item}
</>
);
}, <React.Fragment />);
};

const OverflowMenu = (props: PartitionBreadcrumbItems<Item>) => {
const { overflowItems, startDisplayedItems, endDisplayedItems } = props;
const { ref, isOverflowing, overflowCount } = useOverflowMenu<HTMLButtonElement>();

const tooltipStyles = useTooltipStyles();

if (!isOverflowing && overflowItems && overflowItems.length === 0) {
return null;
}

const overflowItemsCount = overflowItems ? overflowItems.length + overflowCount : overflowCount;
const tooltipContent =
overflowItemsCount > 3
? `${overflowItemsCount} items`
: {
children: getTooltipContent(overflowItems),
className: tooltipStyles.tooltip,
};

return (
<BreadcrumbItem>
<Menu hasIcons>
<MenuTrigger disableButtonEnhancement>
<Button
appearance="subtle"
ref={ref}
icon={<MoreHorizontal />}
aria-label={`${overflowItemsCount} more items`}
role="button"
/>
<Tooltip withArrow content={tooltipContent} relationship="label">
<Button
id="menu"
appearance="subtle"
ref={ref}
icon={<MoreHorizontal />}
aria-label={`${overflowCount} more items`}
role="button"
/>
</Tooltip>
</MenuTrigger>
<MenuPopover>
<MenuList>
Expand All @@ -202,7 +238,7 @@ const BreadcrumbOverflowExample = () => {
const { startDisplayedItems, overflowItems, endDisplayedItems }: PartitionBreadcrumbItems<Item> =
partitionBreadcrumbItems({
items,
maxDisplayedItems: 4,
maxDisplayedItems: 5,
});

return (
Expand Down
Expand Up @@ -6,7 +6,6 @@ import {
BreadcrumbDivider,
partitionBreadcrumbItems,
truncateBreadcrumbLongName,
truncateBreadcrumLongTooltip,
isTruncatableBreadcrumbContent,
makeStyles,
shorthands,
Expand Down Expand Up @@ -76,7 +75,7 @@ const itemsWithLongNames: Item[] = [
},
{
key: 2,
item: "Item 3 is long even for tooltip. Don't think about what you want to be, but what you want to do.",
item: "Item 3 is long. Don't think about what you want to be, but what you want to do.",
},
{
key: 3,
Expand All @@ -101,7 +100,7 @@ function renderItem(entry: Item, isLastItem: boolean) {
<React.Fragment key={`item-${entry.key}`}>
{isTruncatableBreadcrumbContent(entry.item, 30) ? (
<BreadcrumbItem>
<Tooltip withArrow content={truncateBreadcrumLongTooltip(entry.item)} relationship="label">
<Tooltip withArrow content={entry.item} relationship="label">
<BreadcrumbButton current={isLastItem}>{truncateBreadcrumbLongName(entry.item)}</BreadcrumbButton>
</Tooltip>
</BreadcrumbItem>
Expand Down Expand Up @@ -134,18 +133,19 @@ const MenuWithTooltip = (props: PartitionBreadcrumbItems<Item>) => {
if (!isOverflowing && overflowItems && overflowItems.length === 0) {
return null;
}
const overflowItemsLength = overflowItems?.length ?? 0;
const tooltipContent =
overflowItemsLength > 3
? `${overflowItemsLength} items`
: {
children: getTooltipContent(overflowItems),
className: tooltipStyles.tooltip,
};

return (
<Menu hasIcons>
<MenuTrigger disableButtonEnhancement>
<Tooltip
withArrow
content={{
children: getTooltipContent(overflowItems),
className: tooltipStyles.tooltip,
}}
relationship="label"
>
<Tooltip withArrow content={tooltipContent} relationship="label">
<Button
id="menu"
appearance="subtle"
Expand Down Expand Up @@ -210,8 +210,8 @@ export const BreadcrumbWithTooltip = () => {
const itemsLength = itemsWithLongNames.length - 1;
return (
<>
<h3>Interactive Breadcrumb with a tooltip</h3>
<BreadcrumbWithTooltipExample aria-label="interactive-breadcrumb-with-tooltip" />
<h3>Breadcrumb with a tooltip</h3>
<BreadcrumbWithTooltipExample aria-label="breadcrumb-with-tooltip" />
<h3>Breadcrumb with long names</h3>
<Breadcrumb aria-label="breadcrumb-with-long-names">
{itemsWithLongNames.map(item => renderItem(item, itemsLength === item.key))}
Expand Down

0 comments on commit c8cbe2a

Please sign in to comment.