Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tooltip): adds tooltip support for restMs and delay properties #1200

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions content/docs/components/tooltip.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ You can disable the arrow of the tooltip component by passing the `arrow` prop w

<Example name="tooltip.disableArrow" />

## Hover delay

When your tooltip uses the `hover` trigger type, use the `restMs` prop to specify the amount of time (in milliseconds) the user's cursor must be "resting" on the trigger before the tooltip appears.

Use the `delay` prop as a fallback with `restMs` to ensure that the tooltip appears after a certain amount of time even if the user's cursor is still moving.

If you want to specify different behavior delay behavior for `open` and `close`, you can pass an object to `delay` that allows both `open` and `close` properties.

<Example name="tooltip.hoverDelay" />

## Theme

To learn more about how to customize the appearance of components, please see the [Theme docs](/docs/customize/theme).
Expand Down
1 change: 1 addition & 0 deletions examples/tooltip/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { animation } from './tooltip.animation';
export { hoverDelay } from './tooltip.hoverDelay';
export { disableArrow } from './tooltip.disableArrow';
export { placement } from './tooltip.placement';
export { root } from './tooltip.root';
Expand Down
78 changes: 78 additions & 0 deletions examples/tooltip/tooltip.hoverDelay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { type CodeData } from '~/components/code-demo';
import { Button, Tooltip } from '~/src';

const code = `
'use client';

import { Button, Tooltip } from 'flowbite-react';

function Component() {
return (
<div className="flex flex-wrap gap-2">
<Tooltip content="Tooltip content" delay={{ open: 1000, close: 200 }} restMs={100}>
<Button>Delayed tooltip</Button>
</Tooltip>
<Tooltip content="Tooltip content" delay={{ open: 1000, close: 200 }}>
<Button>Delayed tooltip without restMs</Button>
</Tooltip>
<Tooltip content="Tooltip content" restMs={500}>
<Button>Delayed tooltip with restMs only</Button>
</Tooltip>
</div>
);
}
`;

const codeRSC = `
import { Button, Tooltip } from 'flowbite-react';

function Component() {
return (
<div className="flex flex-wrap gap-2">
<Tooltip content="Tooltip content" delay={{ open: 1000, close: 200 }} restMs={100}>
<Button>Delayed tooltip</Button>
</Tooltip>
<Tooltip content="Tooltip content" delay={{ open: 1000, close: 200 }}>
<Button>Delayed tooltip without restMs</Button>
</Tooltip>
<Tooltip content="Tooltip content" restMs={500}>
<Button>Delayed tooltip with restMs only</Button>
</Tooltip>
</div>
);
}
`;

function Component() {
return (
<div className="flex flex-wrap gap-2">
<Tooltip content="Tooltip content" delay={{ open: 1000, close: 200 }} restMs={100}>
<Button>Delayed tooltip</Button>
</Tooltip>
<Tooltip content="Tooltip content" delay={{ open: 1000, close: 200 }}>
<Button>Delayed tooltip without restMs</Button>
</Tooltip>
<Tooltip content="Tooltip content" restMs={500}>
<Button>Delayed tooltip with restMs only</Button>
</Tooltip>
</div>
);
}

export const hoverDelay: CodeData = {
type: 'single',
code: [
{
fileName: 'client',
language: 'tsx',
code,
},
{
fileName: 'server',
language: 'tsx',
code: codeRSC,
},
],
githubSlug: 'tooltip/tooltip.hoverDelay.tsx',
component: <Component />,
};
6 changes: 6 additions & 0 deletions src/components/Floating/Floating.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ export interface FloatingProps extends Omit<ComponentProps<'div'>, 'content' | '
animation?: false | `duration-${number}`;
arrow?: boolean;
content: ReactNode;
delay?: number | Partial<{ open: number; close: number }>;
placement?: 'auto' | Placement;
restMs?: number;
style?: FloatingStyle;
theme: FlowbiteFloatingTheme;
trigger?: 'hover' | 'click';
Expand All @@ -54,6 +56,8 @@ export const Floating: FC<FloatingProps> = ({
children,
className,
content,
delay,
restMs,
placement = 'top',
style = 'dark',
theme,
Expand Down Expand Up @@ -84,6 +88,8 @@ export const Floating: FC<FloatingProps> = ({
const focus = useFocus(context);
const { getFloatingProps, getReferenceProps } = useFloatingInteractions({
context,
delay,
restMs,
role: 'tooltip',
trigger,
interactions: [focus],
Expand Down
13 changes: 13 additions & 0 deletions src/components/Tooltip/Tooltip.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,16 @@ SlowAnimation.args = {
placement: 'bottom',
children: <Button>Tooltip with slow animation</Button>,
};

export const Delay = Template.bind({});
Delay.storyName = 'Delay';
Delay.args = {
delay: {
open: 1000,
close: 200,
},
restMs: 500,
content: 'Tooltip content',
placement: 'bottom',
children: <Button>Tooltip with delay</Button>,
};
6 changes: 6 additions & 0 deletions src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export interface TooltipProps extends Omit<ComponentProps<'div'>, 'content' | 's
animation?: false | `duration-${number}`;
arrow?: boolean;
content: ReactNode;
delay?: number | Partial<{ open: number; close: number }>;
placement?: 'auto' | Placement;
restMs?: number;
style?: 'dark' | 'light' | 'auto';
theme?: DeepPartial<FlowbiteTooltipTheme>;
trigger?: 'hover' | 'click';
Expand All @@ -26,7 +28,9 @@ export const Tooltip: FC<TooltipProps> = ({
children,
className,
content,
delay,
placement = 'top',
restMs,
style = 'dark',
theme: customTheme = {},
trigger = 'hover',
Expand All @@ -39,7 +43,9 @@ export const Tooltip: FC<TooltipProps> = ({
animation={animation}
arrow={arrow}
content={content}
delay={delay}
placement={placement}
restMs={restMs}
style={style}
theme={theme}
trigger={trigger}
Expand Down
6 changes: 6 additions & 0 deletions src/hooks/use-floating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,25 @@ export type UseFloatingInteractionsParams = {
trigger?: 'hover' | 'click';
role?: UseRoleProps['role'];
interactions?: ElementProps[];
delay?: number | Partial<{ open: number; close: number }>;
restMs?: number;
};

export const useFloatingInteractions = ({
context,
trigger,
role = 'tooltip',
interactions = [],
delay,
restMs,
}: UseFloatingInteractionsParams) => {
return useInteractions([
useClick(context, { enabled: trigger === 'click' }),
useHover(context, {
delay,
enabled: trigger === 'hover',
handleClose: safePolygon(),
restMs,
}),
useDismiss(context),
useRole(context, { role }),
Expand Down
Loading