diff --git a/packages/react-components/react-breadcrumb/etc/react-breadcrumb.api.md b/packages/react-components/react-breadcrumb/etc/react-breadcrumb.api.md index 0fd42469bdb0c0..f086c9f11c0f35 100644 --- a/packages/react-components/react-breadcrumb/etc/react-breadcrumb.api.md +++ b/packages/react-components/react-breadcrumb/etc/react-breadcrumb.api.md @@ -120,6 +120,9 @@ export type BreadcrumbSlots = { // @public export type BreadcrumbState = ComponentState & Required>; +// @public (undocumented) +export const isTruncatableBreadcrumbContent: (content: string, maxLength: number) => boolean; + // @public (undocumented) export type PartitionBreadcrumbItems = { startDisplayedItems: readonly T[]; diff --git a/packages/react-components/react-breadcrumb/src/components/BreadcrumbButton/useBreadcrumbButtonStyles.styles.ts b/packages/react-components/react-breadcrumb/src/components/BreadcrumbButton/useBreadcrumbButtonStyles.styles.ts index 1b158967a2e4b0..886b626216a7eb 100644 --- a/packages/react-components/react-breadcrumb/src/components/BreadcrumbButton/useBreadcrumbButtonStyles.styles.ts +++ b/packages/react-components/react-breadcrumb/src/components/BreadcrumbButton/useBreadcrumbButtonStyles.styles.ts @@ -49,6 +49,9 @@ const useStyles = makeStyles({ ':hover:active': { ...defaultButtonStyles, }, + ':disabled': { + ...defaultButtonStyles, + }, }, currentSmall: { ...typographyStyles.caption1Strong, diff --git a/packages/react-components/react-breadcrumb/src/components/BreadcrumbDivider/BreadcrumbDivider.tsx b/packages/react-components/react-breadcrumb/src/components/BreadcrumbDivider/BreadcrumbDivider.tsx index de51ae013fd53e..93f3cebcbb4467 100644 --- a/packages/react-components/react-breadcrumb/src/components/BreadcrumbDivider/BreadcrumbDivider.tsx +++ b/packages/react-components/react-breadcrumb/src/components/BreadcrumbDivider/BreadcrumbDivider.tsx @@ -6,7 +6,7 @@ import type { BreadcrumbDividerProps } from './BreadcrumbDivider.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; /** - * BreadcrumbDivider component - TODO: add more docs + * A divider component which is used inside the Breadcrumb */ export const BreadcrumbDivider: ForwardRefComponent = React.forwardRef((props, ref) => { const state = useBreadcrumbDivider_unstable(props, ref); diff --git a/packages/react-components/react-breadcrumb/src/components/BreadcrumbItem/BreadcrumbItem.tsx b/packages/react-components/react-breadcrumb/src/components/BreadcrumbItem/BreadcrumbItem.tsx index 3909738690525b..2eab38ba6b73d2 100644 --- a/packages/react-components/react-breadcrumb/src/components/BreadcrumbItem/BreadcrumbItem.tsx +++ b/packages/react-components/react-breadcrumb/src/components/BreadcrumbItem/BreadcrumbItem.tsx @@ -6,7 +6,8 @@ import type { BreadcrumbItemProps } from './BreadcrumbItem.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; /** - * BreadcrumbItem component - TODO: add more docs + * BreadcrumbItem component is a wrapper for BreadcrumbLink and BreadcrumbButton. + * It can be used as a non-interactive item. */ export const BreadcrumbItem: ForwardRefComponent = React.forwardRef((props, ref) => { const state = useBreadcrumbItem_unstable(props, ref); diff --git a/packages/react-components/react-breadcrumb/src/components/BreadcrumbLink/BreadcrumbLink.tsx b/packages/react-components/react-breadcrumb/src/components/BreadcrumbLink/BreadcrumbLink.tsx index 4d8458785af5b8..c9100402b1b7a6 100644 --- a/packages/react-components/react-breadcrumb/src/components/BreadcrumbLink/BreadcrumbLink.tsx +++ b/packages/react-components/react-breadcrumb/src/components/BreadcrumbLink/BreadcrumbLink.tsx @@ -6,7 +6,7 @@ import type { BreadcrumbLinkProps } from './BreadcrumbLink.types'; import type { ForwardRefComponent } from '@fluentui/react-utilities'; /** - * BreadcrumbLink component - TODO: add more docs + * A link component which is used inside the Breadcrumb. */ export const BreadcrumbLink: ForwardRefComponent = React.forwardRef((props, ref) => { const state = useBreadcrumbLink_unstable(props, ref); diff --git a/packages/react-components/react-breadcrumb/src/index.ts b/packages/react-components/react-breadcrumb/src/index.ts index 0cf53cf84aa0c6..9cc50472923a63 100644 --- a/packages/react-components/react-breadcrumb/src/index.ts +++ b/packages/react-components/react-breadcrumb/src/index.ts @@ -22,7 +22,12 @@ export { useBreadcrumbItem_unstable, } from './BreadcrumbItem'; export type { BreadcrumbItemProps, BreadcrumbItemSlots, BreadcrumbItemState } from './BreadcrumbItem'; -export { partitionBreadcrumbItems, truncateBreadcrumbLongName, truncateBreadcrumLongTooltip } from './utils/index'; +export { + partitionBreadcrumbItems, + truncateBreadcrumbLongName, + truncateBreadcrumLongTooltip, + isTruncatableBreadcrumbContent, +} from './utils/index'; export type { PartitionBreadcrumbItemsOptions, PartitionBreadcrumbItems } from './utils/index'; export { BreadcrumbButton, diff --git a/packages/react-components/react-breadcrumb/src/utils/index.ts b/packages/react-components/react-breadcrumb/src/utils/index.ts index 6cb6ccdd99efe7..782641164e23cf 100644 --- a/packages/react-components/react-breadcrumb/src/utils/index.ts +++ b/packages/react-components/react-breadcrumb/src/utils/index.ts @@ -1,3 +1,7 @@ export { partitionBreadcrumbItems } from './partitionBreadcrumbItems'; export type { PartitionBreadcrumbItems, PartitionBreadcrumbItemsOptions } from './partitionBreadcrumbItems'; -export { truncateBreadcrumbLongName, truncateBreadcrumLongTooltip } from './truncateBreadcrumb'; +export { + truncateBreadcrumbLongName, + truncateBreadcrumLongTooltip, + isTruncatableBreadcrumbContent, +} from './truncateBreadcrumb'; diff --git a/packages/react-components/react-breadcrumb/src/utils/truncateBreadcrumb.ts b/packages/react-components/react-breadcrumb/src/utils/truncateBreadcrumb.ts index 6e8e065eb91e43..ac710a7ad592aa 100644 --- a/packages/react-components/react-breadcrumb/src/utils/truncateBreadcrumb.ts +++ b/packages/react-components/react-breadcrumb/src/utils/truncateBreadcrumb.ts @@ -2,7 +2,13 @@ const MAX_NAME_LENGTH = 30; const MAX_TOOLTIP_LENGTH = 80; const truncateBreadcrumb = (content: string, maxLength: number): string => { - return content.length > maxLength ? content.trim().slice(0, maxLength).concat('...') : content; + return isTruncatableBreadcrumbContent(content, maxLength) + ? content.trim().slice(0, maxLength).concat('...') + : content; +}; + +export const isTruncatableBreadcrumbContent = (content: string, maxLength: number) => { + return content.length > maxLength; }; export const truncateBreadcrumbLongName = (content: string, maxLength?: number): string => { diff --git a/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbBestPractices.md b/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbBestPractices.md index 6d8ca953452675..a6a18d0f727250 100644 --- a/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbBestPractices.md +++ b/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbBestPractices.md @@ -14,5 +14,6 @@ - Don't use Breadcrumbs as a primary way to navigate an app or site. - Avoid using custom dividers. +- Do not wrap breadcrumb items. diff --git a/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx b/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx index 8775694e3482a3..4fdf007031afd7 100644 --- a/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx +++ b/packages/react-components/react-breadcrumb/stories/Breadcrumb/BreadcrumbWithOverflow.stories.tsx @@ -277,3 +277,15 @@ export const BreadcrumbWithOverflow = () => { ); }; + +BreadcrumbWithOverflow.parameters = { + docs: { + description: { + story: [ + 'The maximum number of items in a breadcrumb can be customized. We recommend a maximum of 6 items or fewer.', + 'When the maximum number is exceeded, items in the middle auto-collapse into an overflow menu.', + '\nThe first and last items should always appear in the breadcrumb. Breadcrumbs should never wrap.', + ].join('\n'), + }, + }, +}; diff --git a/packages/react-components/react-breadcrumb/stories/BreadcrumbDivider/BreadcrumbDividerBestPractices.md b/packages/react-components/react-breadcrumb/stories/BreadcrumbDivider/BreadcrumbDividerBestPractices.md index b9df3ffd50cc30..704a13c542f282 100644 --- a/packages/react-components/react-breadcrumb/stories/BreadcrumbDivider/BreadcrumbDividerBestPractices.md +++ b/packages/react-components/react-breadcrumb/stories/BreadcrumbDivider/BreadcrumbDividerBestPractices.md @@ -5,7 +5,7 @@ ### Do -- Use `slash` dividers only for small and non-interactive breadcrums. +- Use `slash` dividers only for small and non-interactive breadcrums. Use it to describe file paths. ### Don't diff --git a/packages/react-components/react-breadcrumb/stories/BreadcrumbItem/BreadcrumbItemDefault.stories.tsx b/packages/react-components/react-breadcrumb/stories/BreadcrumbItem/BreadcrumbItemDefault.stories.tsx index 1345e6ccbd3c06..06927b5d308835 100644 --- a/packages/react-components/react-breadcrumb/stories/BreadcrumbItem/BreadcrumbItemDefault.stories.tsx +++ b/packages/react-components/react-breadcrumb/stories/BreadcrumbItem/BreadcrumbItemDefault.stories.tsx @@ -8,6 +8,7 @@ import { BreadcrumbButton, truncateBreadcrumbLongName, truncateBreadcrumLongTooltip, + isTruncatableBreadcrumbContent, } from '@fluentui/react-breadcrumb'; import type { PartitionBreadcrumbItems } from '@fluentui/react-breadcrumb'; import { ArrowRight16Filled, MoreHorizontalRegular, MoreHorizontalFilled, bundleIcon } from '@fluentui/react-icons'; @@ -50,9 +51,14 @@ function renderItem(item: Item, size: BreadcrumbProps['size']) { const isLastItem = items.length - 1 === item.key; return ( - - {truncateBreadcrumbLongName(item.value)} - + {isTruncatableBreadcrumbContent(item.value, 30) ? ( + + {truncateBreadcrumbLongName(item.value)} + + ) : ( + {item.value} + )} + {!isLastItem && } );