diff --git a/packages/ui-breadcrumb/src/Breadcrumb/BreadcrumbLink/index.tsx b/packages/ui-breadcrumb/src/Breadcrumb/BreadcrumbLink/index.tsx index 54fb5aa866..8fdc561a37 100644 --- a/packages/ui-breadcrumb/src/Breadcrumb/BreadcrumbLink/index.tsx +++ b/packages/ui-breadcrumb/src/Breadcrumb/BreadcrumbLink/index.tsx @@ -28,9 +28,10 @@ import { TruncateText } from '@instructure/ui-truncate-text' import { Link } from '@instructure/ui-link' import { omitProps } from '@instructure/ui-react-utils' import { testable } from '@instructure/ui-testable' +import { Tooltip } from '@instructure/ui-tooltip' import { propTypes, allowedProps } from './props' -import type { BreadcrumbLinkProps } from './props' +import type { BreadcrumbLinkProps, BreadcrumbLinkState } from './props' /** --- @@ -40,7 +41,10 @@ id: Breadcrumb.Link **/ @testable() -class BreadcrumbLink extends Component { +class BreadcrumbLink extends Component< + BreadcrumbLinkProps, + BreadcrumbLinkState +> { static readonly componentId = 'Breadcrumb.Link' static propTypes = propTypes @@ -52,26 +56,43 @@ class BreadcrumbLink extends Component { handleRef = (el: Element | null) => { this.ref = el } + constructor(props: BreadcrumbLinkProps) { + super(props) + this.state = { + isTruncated: false + } + } + handleTruncation(isTruncated: boolean) { + if (isTruncated !== this.state.isTruncated) { + this.setState({ isTruncated }) + } + } render() { const { children, href, renderIcon, iconPlacement, onClick, onMouseEnter } = this.props - + const { isTruncated } = this.state const props = omitProps(this.props, BreadcrumbLink.allowedProps) return ( - - {children} - + + + this.handleTruncation(isTruncated)} + > + {children} + + + ) } } diff --git a/packages/ui-breadcrumb/src/Breadcrumb/BreadcrumbLink/props.ts b/packages/ui-breadcrumb/src/Breadcrumb/BreadcrumbLink/props.ts index cca8fd0e45..f9c4f656ea 100644 --- a/packages/ui-breadcrumb/src/Breadcrumb/BreadcrumbLink/props.ts +++ b/packages/ui-breadcrumb/src/Breadcrumb/BreadcrumbLink/props.ts @@ -102,5 +102,9 @@ const allowedProps: AllowedPropKeys = [ 'size' ] -export type { BreadcrumbLinkProps } +type BreadcrumbLinkState = { + isTruncated: boolean +} + +export type { BreadcrumbLinkProps, BreadcrumbLinkState } export { propTypes, allowedProps } diff --git a/packages/ui-tooltip/src/Tooltip/index.tsx b/packages/ui-tooltip/src/Tooltip/index.tsx index f3a3c44a17..3152e54e54 100644 --- a/packages/ui-tooltip/src/Tooltip/index.tsx +++ b/packages/ui-tooltip/src/Tooltip/index.tsx @@ -64,7 +64,8 @@ class Tooltip extends Component { placement: 'top', constrain: 'window', offsetX: 0, - offsetY: 0 + offsetY: 0, + preventTooltip: false } as const private readonly _id: string @@ -148,6 +149,7 @@ class Tooltip extends Component { positionTarget, onShowContent, onHideContent, + preventTooltip, styles, ...rest } = this.props @@ -155,8 +157,8 @@ class Tooltip extends Component { return ( { shouldCloseOnDocumentClick={false} shouldCloseOnEscape > - - {/* TODO: figure out how to add a ref to this */} - {callRenderProp(renderTip)} - + {!preventTooltip ? ( + + {/* TODO: figure out how to add a ref to this */} + {callRenderProp(renderTip)} + + ) : null} ) } diff --git a/packages/ui-tooltip/src/Tooltip/props.ts b/packages/ui-tooltip/src/Tooltip/props.ts index 4d9c10daa0..4133aba8cb 100644 --- a/packages/ui-tooltip/src/Tooltip/props.ts +++ b/packages/ui-tooltip/src/Tooltip/props.ts @@ -148,6 +148,12 @@ type TooltipOwnProps = { event: React.UIEvent | React.FocusEvent, args: { documentClick: boolean } ) => void + + /** + * If true, it won't display the tooltip. This is useful in cases when tooltip is conditionally needed + * but in an uncontrolled way + */ + preventTooltip?: boolean } type PropKeys = keyof TooltipOwnProps @@ -177,6 +183,7 @@ type PropsPassableToPopover = Omit< | 'onFocus' | 'onBlur' | 'elementRef' + | 'preventTooltip' > type TooltipProps = PropsPassableToPopover & @@ -211,7 +218,8 @@ const propTypes: PropValidators = { offsetY: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), positionTarget: PropTypes.oneOfType([element, PropTypes.func]), onShowContent: PropTypes.func, - onHideContent: PropTypes.func + onHideContent: PropTypes.func, + preventTooltip: PropTypes.bool } const allowedProps: AllowedPropKeys = [ @@ -230,7 +238,8 @@ const allowedProps: AllowedPropKeys = [ 'offsetY', 'positionTarget', 'onShowContent', - 'onHideContent' + 'onHideContent', + 'preventTooltip' ] export type { diff --git a/packages/ui-top-nav-bar/src/TopNavBar/TopNavBarLayout/DesktopLayout/__new-tests__/TopNavBarDesktopLayout.test.tsx b/packages/ui-top-nav-bar/src/TopNavBar/TopNavBarLayout/DesktopLayout/__new-tests__/TopNavBarDesktopLayout.test.tsx index 881d7c8748..5565b30ca6 100644 --- a/packages/ui-top-nav-bar/src/TopNavBar/TopNavBarLayout/DesktopLayout/__new-tests__/TopNavBarDesktopLayout.test.tsx +++ b/packages/ui-top-nav-bar/src/TopNavBar/TopNavBarLayout/DesktopLayout/__new-tests__/TopNavBarDesktopLayout.test.tsx @@ -72,7 +72,7 @@ describe('', () => { describe('renderBreadcrumb', () => { it('should render breadcrumb container', () => { - const { getByLabelText, getByText } = render( + const { getByLabelText, getAllByText } = render( ', () => { ) const breadCrumbContainer = getByLabelText('You are here') - const crumb1 = getByText('Course page 1') - const crumb2 = getByText('Course page 2') - const crumb3 = getByText('Course page 3') + const crumb1 = getAllByText('Course page 1')[0] + const crumb2 = getAllByText('Course page 2')[0] + const crumb3 = getAllByText('Course page 3')[0] expect(breadCrumbContainer).toBeInTheDocument() expect(crumb1).toBeVisible()