From 1d6b90254fe5c6e07e7ab0831fcd23e35143d66f Mon Sep 17 00:00:00 2001 From: Florent Mathieu Date: Mon, 12 May 2025 12:56:43 -1000 Subject: [PATCH 1/3] feat(modals): add fallbackPlacements support to TooltipDialog --- .../elements/TooltipDialog/TooltipDialog.tsx | 23 +++++++++++++++---- packages/modals/src/types/index.ts | 12 ++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/packages/modals/src/elements/TooltipDialog/TooltipDialog.tsx b/packages/modals/src/elements/TooltipDialog/TooltipDialog.tsx index 75798817d67..f0c4cd8869a 100644 --- a/packages/modals/src/elements/TooltipDialog/TooltipDialog.tsx +++ b/packages/modals/src/elements/TooltipDialog/TooltipDialog.tsx @@ -9,7 +9,14 @@ import React, { HTMLAttributes, useState, useContext, useEffect, useRef } from ' import PropTypes from 'prop-types'; import { ThemeContext } from 'styled-components'; import { CSSTransition } from 'react-transition-group'; -import { autoPlacement, autoUpdate, offset, platform, useFloating } from '@floating-ui/react-dom'; +import { + autoPlacement, + autoUpdate, + flip, + offset, + platform, + useFloating +} from '@floating-ui/react-dom'; import { useModal } from '@zendeskgarden/container-modal'; import { mergeRefs } from 'react-merge-refs'; import { TooltipDialogContext } from '../../utils/useTooltipDialogContext'; @@ -18,7 +25,7 @@ import { StyledTooltipDialog, StyledTooltipDialogBackdrop } from '../../styled'; -import { ITooltipDialogProps } from '../../types'; +import { ITooltipDialogProps, PLACEMENT } from '../../types'; import { Title } from './Title'; import { Body } from './Body'; import { Close } from './Close'; @@ -35,6 +42,7 @@ const TooltipDialogComponent = React.forwardRef placement !== 'auto')) + ), isAnimated: PropTypes.bool, hasArrow: PropTypes.bool, zIndex: PropTypes.number, diff --git a/packages/modals/src/types/index.ts b/packages/modals/src/types/index.ts index 1a8aff71326..71583390b6b 100644 --- a/packages/modals/src/types/index.ts +++ b/packages/modals/src/types/index.ts @@ -76,9 +76,13 @@ export interface IDrawerHeaderProps extends HTMLAttributes { export interface ITooltipDialogProps extends Omit { /** - * Positions the modal relative to the provided `HTMLElement` + * Provides a list of acceptable fallback placements */ - referenceElement?: HTMLElement | null; + fallbackPlacements?: Exclude[]; + /** + * Adds an arrow to the tooltop + */ + hasArrow?: boolean; /** @ignore Modifies the placement offset from the reference element (internal only) */ offset?: number; /** @@ -86,9 +90,9 @@ export interface ITooltipDialogProps extends Omit Date: Mon, 12 May 2025 12:58:26 -1000 Subject: [PATCH 2/3] feat(tooltips): add fallbackPlacements support to Tooltips --- packages/tooltips/src/elements/Tooltip.tsx | 13 +++++++++---- packages/tooltips/src/types/index.ts | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/tooltips/src/elements/Tooltip.tsx b/packages/tooltips/src/elements/Tooltip.tsx index 55c166ac843..c7aef5d92d2 100644 --- a/packages/tooltips/src/elements/Tooltip.tsx +++ b/packages/tooltips/src/elements/Tooltip.tsx @@ -14,7 +14,7 @@ import { useTooltip } from '@zendeskgarden/container-tooltip'; import { composeEventHandlers, getControlledValue } from '@zendeskgarden/container-utilities'; import { StyledTooltipWrapper, StyledTooltip } from '../styled'; import { ITooltipProps, PLACEMENT, SIZE, TYPE } from '../types'; -import { autoPlacement, autoUpdate, platform, useFloating } from '@floating-ui/react-dom'; +import { autoPlacement, autoUpdate, flip, platform, useFloating } from '@floating-ui/react-dom'; import { DEFAULT_THEME, getFloatingPlacements } from '@zendeskgarden/react-theming'; import { toSize } from './utils'; import { Paragraph } from './Paragraph'; @@ -29,6 +29,7 @@ export const TooltipComponent = ({ content, refKey, placement: _placement, + fallbackPlacements: _fallbackPlacements, children, hasArrow, size, @@ -51,9 +52,10 @@ export const TooltipComponent = ({ }); const controlledIsVisible = getControlledValue(externalIsVisible, isVisible); - const [floatingPlacement] = getFloatingPlacements( + const [floatingPlacement, fallbackPlacements] = getFloatingPlacements( theme, - _placement === 'auto' ? PLACEMENT_DEFAULT : _placement! + _placement === 'auto' ? PLACEMENT_DEFAULT : _placement!, + _fallbackPlacements ); const { @@ -68,7 +70,7 @@ export const TooltipComponent = ({ }, elements: { reference: triggerRef?.current, floating: floatingRef?.current }, placement: floatingPlacement, - middleware: _placement === 'auto' ? [autoPlacement()] : undefined + middleware: _placement === 'auto' ? [autoPlacement()] : [flip({ fallbackPlacements })] }); useEffect(() => { @@ -135,6 +137,9 @@ TooltipComponent.propTypes = { id: PropTypes.string, content: PropTypes.node.isRequired, placement: PropTypes.oneOf(PLACEMENT), + fallbackPlacements: PropTypes.arrayOf( + PropTypes.oneOf(PLACEMENT.filter(placement => placement !== 'auto')) + ), size: PropTypes.oneOf(SIZE), type: PropTypes.oneOf(TYPE), zIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), diff --git a/packages/tooltips/src/types/index.ts b/packages/tooltips/src/types/index.ts index 37c733674b6..71fbc1c8397 100644 --- a/packages/tooltips/src/types/index.ts +++ b/packages/tooltips/src/types/index.ts @@ -25,6 +25,8 @@ export interface ITooltipProps extends Omit, 'con delayMS?: number; /** Defines the content of the tooltip */ content: ReactNode; + /** Provides a list of acceptable fallback placements */ + fallbackPlacements?: Exclude[]; /** Adjusts the placement of the tooltip */ placement?: GardenPlacement; /** Adjusts the padding and font size */ From dcaee9b3bd651f885836c99db054b9daebd2cd90 Mon Sep 17 00:00:00 2001 From: Florent Mathieu Date: Mon, 12 May 2025 14:59:20 -1000 Subject: [PATCH 3/3] docs: update Tooltip + TooltipModal story with fallbackPlacements --- packages/modals/demo/stories/TooltipDialogStory.tsx | 2 +- packages/modals/demo/tooltipDialog.stories.mdx | 2 ++ packages/tooltips/demo/stories/TooltipStory.tsx | 2 +- packages/tooltips/demo/tooltip.stories.mdx | 4 +++- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/modals/demo/stories/TooltipDialogStory.tsx b/packages/modals/demo/stories/TooltipDialogStory.tsx index 40ebcce065f..e511d7fa8ea 100644 --- a/packages/modals/demo/stories/TooltipDialogStory.tsx +++ b/packages/modals/demo/stories/TooltipDialogStory.tsx @@ -90,7 +90,7 @@ export const TooltipDialogStory: Story = ({ {!!hasClose && } - + {[...Array(count)].map((_, index) => ( p !== 'auto') }, hasBody: { name: 'TooltipDialog.Body', table: { category: 'Story' } }, hasClose: { name: 'TooltipDialog.Close', table: { category: 'Story' } }, hasFooter: { name: 'TooltipDialog.Footer', table: { category: 'Story' } }, diff --git a/packages/tooltips/demo/stories/TooltipStory.tsx b/packages/tooltips/demo/stories/TooltipStory.tsx index da635587d06..2d0b3eeafa4 100644 --- a/packages/tooltips/demo/stories/TooltipStory.tsx +++ b/packages/tooltips/demo/stories/TooltipStory.tsx @@ -18,7 +18,7 @@ interface IArgs extends Omit { export const TooltipStory: StoryFn = ({ content, ...args }: IArgs) => ( - + p !== 'auto') } }} parameters={{ design: {