Skip to content

Commit

Permalink
Feat(web-react): TooltipModern tooltip hover
Browse files Browse the repository at this point in the history
- Tooltip stay open after mouse hover

Solves #DS-1219
  • Loading branch information
pavelklibani committed Apr 18, 2024
1 parent b857115 commit a7cd369
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/web-react/src/components/Tooltip/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ const [open, setOpen] = React.useState(false);
| `isOpen` | `bool` | - | ✔ | Open state |
| `onToggle` | `() => void` | - | ✔ | Function for toggle open state of dropdown |
| `placement` | [Placement Dictionary][dictionary-placement] | "bottom" | ✕ | Placement of tooltip |
| `isFocusableOnHover` | `bool` | false | ✕ | Allows you to mouse over a tooltip without closing it. We suggest turning off the `click` trigger if you use this feature. |
| `trigger` | ["click" \| "hover" \| "manual"] | ["click", "hover" ] | ✕ | How tooltip is triggered: `click`, `hover`, `manual`. You may pass multiple triggers. If you pass `manual`, there will be no toggle functionality and you should provide your own toggle solution. |
On top of the API options, the components accept [additional attributes][readme-additional-attributes].
Expand Down
2 changes: 2 additions & 0 deletions packages/web-react/src/components/Tooltip/TooltipModern.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const TooltipModern = (props: TooltipModernProps) => {
id,
isDismissible = false,
isOpen = false,
isFocusableOnHover = false,
onToggle,
placement: tooltipPlacement,
trigger = ['click', 'hover'],
Expand Down Expand Up @@ -60,6 +61,7 @@ const TooltipModern = (props: TooltipModernProps) => {
isOpen,
offset: tooltipOffset,
onToggle,
isFocusableOnHover,
shiftProp,
sizeProp,
tooltipArrowWidth,
Expand Down
15 changes: 14 additions & 1 deletion packages/web-react/src/components/Tooltip/useFloating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
inline,
limitShift,
offset,
safePolygon,
shift,
size,
useClick,
Expand All @@ -28,6 +29,7 @@ type UseTooltipUIProps = {
isOpen?: boolean;
offset?: number;
onToggle: (isOpen: boolean) => void;
isFocusableOnHover?: boolean;
shiftProp: boolean;
sizeProp: boolean;
tooltipArrowWidth?: number;
Expand All @@ -51,6 +53,7 @@ export const useFloating = (props: UseTooltipUIProps) => {
isOpen = false,
offset: tooltipOffset = 0,
onToggle,
isFocusableOnHover,
shiftProp,
sizeProp,
tooltipArrowWidth = 0,
Expand All @@ -65,6 +68,13 @@ export const useFloating = (props: UseTooltipUIProps) => {
const isHoverEnabled = trigger?.includes(TOOLTIP_TRIGGER.HOVER);
const isClickEnabled = trigger?.includes(TOOLTIP_TRIGGER.CLICK);

const useSafePolygons = (isClickable: boolean) =>
isClickable
? safePolygon({
requireIntent: false,
})
: undefined;

// Floating UI library settings
const { x, y, refs, context, placement, middlewareData } = useFloatingUI({
open: isOpen,
Expand Down Expand Up @@ -125,7 +135,10 @@ export const useFloating = (props: UseTooltipUIProps) => {

// Floating UI library interaction hooks
const click = useClick(context, { enabled: isClickEnabled });
const hover = useHover(context, { enabled: isHoverEnabled });
const hover = useHover(context, {
enabled: isHoverEnabled,
handleClose: useSafePolygons(!!isFocusableOnHover),
});
const dismiss = useDismiss(context);
const role = useRole(context, { role: 'tooltip' });
const { getReferenceProps, getFloatingProps } = useInteractions([click, hover, dismiss, role]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ const TooltipWithFloatingUI = () => {
flipFallbackPlacements={suggestedFallbackPlacement}
enableShifting={shift}
enableSizing={size}
trigger={['hover']}
isFocusableOnHover
>
<TooltipTrigger elementType={Button}>I have a tooltip 😎</TooltipTrigger>
<TooltipPopover>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ const meta: Meta<typeof TooltipModern> = {
defaultValue: { summary: 'bottom' },
},
},
isFocusableOnHover: {
control: 'boolean',
},
trigger: {
control: 'select',
options: ['click, hover', 'hover', 'click'],
table: {
defaultValue: { summary: 'click, hover' },
},
},
isOpen: {
control: 'boolean',
},
},
args: {
children: (
Expand All @@ -53,14 +66,15 @@ const meta: Meta<typeof TooltipModern> = {
point to the center of the trigger.
</>
),
isOpen: true,
isOpen: false,
id: 'TooltipModernExample',
enableFlipping: true,
enableShifting: true,
enableSizing: true,
enableFlippingCrossAxis: true,
trigger: ['click', 'hover'],
placement: 'bottom',
isFocusableOnHover: false,
flipFallbackPlacements: ['bottom', 'left', 'right', 'top'],
},
};
Expand All @@ -70,7 +84,7 @@ type Story = StoryObj<typeof TooltipModern>;

const TooltipModernWithHooks = (args: SpiritTooltipModernProps) => {
const { children, isOpen } = args;
const [isTooltipOpen, setIsTooltipOpen] = useState(true);
const [isTooltipOpen, setIsTooltipOpen] = useState(isOpen);

const viewportRef = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);
Expand Down
1 change: 1 addition & 0 deletions packages/web-react/src/types/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,6 @@ export interface SpiritTooltipModernProps extends TooltipModernProps, ChildrenPr
enableSizing?: boolean;
flipFallbackAxisSideDirection?: 'none' | 'start' | 'end';
flipFallbackPlacements?: Placement | Placement[];
isFocusableOnHover?: boolean;
trigger?: TooltipTriggerType[];
}

0 comments on commit a7cd369

Please sign in to comment.