Skip to content

Commit

Permalink
[@mantine/core] Tooltip: add middlewares prop
Browse files Browse the repository at this point in the history
  • Loading branch information
jvllmr committed Dec 18, 2024
1 parent 3216b36 commit cdfbde3
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 16 deletions.
35 changes: 26 additions & 9 deletions packages/@mantine/core/src/components/Tooltip/Tooltip.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,32 @@ export const WithArrowRadius = () => (

export function Inline() {
return (
<div style={{ padding: 40, maxWidth: 400 }}>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Vitae ipsam in quos aperiam magni
quas neque{' '}
<Tooltip label="Inline tooltip" inline>
<span style={{ background: 'pink' }}>aliquid laboriosam dolorum</span>
</Tooltip>
, eum voluptate, perferendis placeat repudiandae nesciunt explicabo quibusdam deserunt, animi
dicta.
</div>
<>
<div style={{ padding: 40, maxWidth: 400 }}>
<b>Via inline prop:</b>
<div>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Vitae ipsam in quos aperiam
magni quas neque{' '}
<Tooltip label="Inline tooltip" inline>
<span style={{ background: 'pink' }}>aliquid laboriosam dolorum</span>
</Tooltip>
, eum voluptate, perferendis placeat repudiandae nesciunt explicabo quibusdam deserunt,
animi dicta.
</div>
</div>
<div style={{ padding: 40, maxWidth: 400 }}>
<b>Via middlewares prop:</b>
<div>
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Vitae ipsam in quos aperiam
magni quas neque{' '}
<Tooltip label="Inline tooltip" middlewares={{ inline: true }}>
<span style={{ background: 'pink' }}>aliquid laboriosam dolorum</span>
</Tooltip>
, eum voluptate, perferendis placeat repudiandae nesciunt explicabo quibusdam deserunt,
animi dicta.
</div>
</div>
</>
);
}

Expand Down
3 changes: 3 additions & 0 deletions packages/@mantine/core/src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const defaultProps: Partial<TooltipProps> = {
events: { hover: true, focus: false, touch: false },
zIndex: getDefaultZIndex('popover'),
positionDependencies: [],
middlewares: { flip: true, shift: true, inline: false },
};

const varsResolver = createVarsResolver<TooltipFactory>((theme, { radius, color }) => ({
Expand Down Expand Up @@ -162,6 +163,7 @@ export const Tooltip = factory<TooltipFactory>((_props, ref) => {
portalProps,
mod,
floatingStrategy,
middlewares,
...others
} = useProps('Tooltip', defaultProps, props);

Expand All @@ -181,6 +183,7 @@ export const Tooltip = factory<TooltipFactory>((_props, ref) => {
positionDependencies: [...positionDependencies!, children],
inline,
strategy: floatingStrategy,
middlewares,
});

const getStyles = useStyles<TooltipFactory>({
Expand Down
11 changes: 11 additions & 0 deletions packages/@mantine/core/src/components/Tooltip/Tooltip.types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { FlipOptions, InlineOptions, ShiftOptions, SizeOptions } from '@floating-ui/react';
import { BoxProps, ElementProps, MantineColor, MantineRadius, StylesApiProps } from '../../core';
import { FloatingPosition } from '../Floating';
import { PortalProps } from '../Portal';
Expand All @@ -8,6 +9,13 @@ export type TooltipCssVariables = {
tooltip: '--tooltip-radius' | '--tooltip-bg' | '--tooltip-color';
};

export interface TooltipMiddlewares {
shift?: boolean | ShiftOptions;
flip?: boolean | FlipOptions;
inline?: boolean | InlineOptions;
size?: boolean | SizeOptions;
}

export interface TooltipBaseProps
extends BoxProps,
StylesApiProps<TooltipFactory>,
Expand Down Expand Up @@ -44,4 +52,7 @@ export interface TooltipBaseProps

/** Props to pass down to the portal when withinPortal is true */
portalProps?: Omit<PortalProps, 'children' | 'withinPortal'>;

/** Floating ui middlewares to configure position handling, `{ flip: true, shift: true, inline: false }` by default */
middlewares?: TooltipMiddlewares;
}
61 changes: 54 additions & 7 deletions packages/@mantine/core/src/components/Tooltip/use-tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
useHover,
useInteractions,
useRole,
type Middleware,
} from '@floating-ui/react';
import { useDidUpdate, useId } from '@mantine/hooks';
import {
Expand All @@ -21,6 +22,7 @@ import {
FloatingStrategy,
useFloatingAutoUpdate,
} from '../Floating';
import { type TooltipMiddlewares } from './Tooltip.types';
import { useTooltipGroupContext } from './TooltipGroup/TooltipGroup.context';

interface UseTooltip {
Expand All @@ -37,6 +39,57 @@ interface UseTooltip {
positionDependencies: any[];
inline?: boolean;
strategy?: FloatingStrategy;
middlewares?: TooltipMiddlewares;
}

function getDefaultMiddlewares(middlewares: TooltipMiddlewares | undefined): TooltipMiddlewares {
if (middlewares === undefined) {
return { shift: true, flip: true };
}

const result = { ...middlewares };
if (middlewares.shift === undefined) {
result.shift = true;
}

if (middlewares.flip === undefined) {
result.flip = true;
}

return result;
}

function getTooltipMiddlewares(settings: UseTooltip) {
const middlewaresOptions = getDefaultMiddlewares(settings.middlewares);
const middlewares: Middleware[] = [offset(settings.offset)];

if (middlewaresOptions.shift) {
middlewares.push(
shift(
typeof middlewaresOptions.shift === 'boolean'
? { padding: 8 }
: { padding: 8, ...middlewaresOptions.shift }
)
);
}

if (middlewaresOptions.flip) {
middlewares.push(
typeof middlewaresOptions.flip === 'boolean' ? flip() : flip(middlewaresOptions.flip)
);
}

middlewares.push(arrow({ element: settings.arrowRef!, padding: settings.arrowOffset }));

if (middlewaresOptions.inline) {
middlewares.push(
typeof middlewaresOptions.inline === 'boolean' ? inline() : inline(middlewaresOptions.inline)
);
} else if (settings.inline) {
middlewares.push(inline());
}

return middlewares;
}

export function useTooltip(settings: UseTooltip) {
Expand Down Expand Up @@ -72,13 +125,7 @@ export function useTooltip(settings: UseTooltip) {
placement: settings.position,
open: opened,
onOpenChange: onChange,
middleware: [
offset(settings.offset),
shift({ padding: 8 }),
flip(),
arrow({ element: settings.arrowRef!, padding: settings.arrowOffset }),
...(settings.inline ? [inline()] : []),
],
middleware: getTooltipMiddlewares(settings),
});

useDelayGroup(context, { id: uid });
Expand Down

0 comments on commit cdfbde3

Please sign in to comment.