Skip to content

Commit

Permalink
feat(component): theme support to tooltip (#198)
Browse files Browse the repository at this point in the history
* feat(component): theme support to tooltip

* refactor(component): clean up code
  • Loading branch information
rluders authored Jun 5, 2022
1 parent 3ed4551 commit 957ea45
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 28 deletions.
7 changes: 3 additions & 4 deletions src/lib/components/Dropdown/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import type { ComponentProps, FC, PropsWithChildren, ReactNode } from 'react';
import { useMemo } from 'react';
import { HiOutlineChevronDown, HiOutlineChevronLeft, HiOutlineChevronRight, HiOutlineChevronUp } from 'react-icons/hi';
import classNames from 'classnames';

import type { ButtonComponentProps } from '../Button';
import { Button } from '../Button';
import type { TooltipProps } from '../Tooltip';
import { Tooltip } from '../Tooltip';
import { DropdownItem } from './DropdownItem';
import { DropdownDivider } from './DropdownDivider';
import { DropdownHeader } from './DropdownHeader';
import { excludeClassName } from '../../helpers/exclude';

export type DropdownProps = ButtonComponentProps &
Omit<TooltipProps, 'content' | 'style' | 'animation' | 'arrow'> & {
Expand All @@ -28,7 +27,8 @@ const icons: Record<string, FC<ComponentProps<'svg'>>> = {
};

const DropdownComponent: FC<DropdownProps> = (props) => {
const { children, className, label, inline, tooltipArrow = false, arrowIcon = true, ...restProps } = props;
const theirProps = excludeClassName(props) as DropdownProps;
const { children, label, inline, tooltipArrow = false, arrowIcon = true, ...restProps } = theirProps;
const { placement = inline ? 'bottom-start' : 'bottom', trigger = 'click', ...buttonProps } = restProps;

const Icon = useMemo(() => {
Expand All @@ -43,7 +43,6 @@ const DropdownComponent: FC<DropdownProps> = (props) => {

return (
<Tooltip
className={classNames('w-44 !rounded !p-0', className)}
content={content}
style="auto"
animation="duration-100"
Expand Down
21 changes: 21 additions & 0 deletions src/lib/components/Flowbite/FlowbiteTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,27 @@ export interface FlowbiteTheme {
icon: string;
};
};
tooltip: {
target: string;
base: string;
animation: string;
hidden: string;
style: {
dark: string;
light: string;
auto: string;
};
content: string;
arrow: {
base: string;
style: {
dark: string;
light: string;
auto: string;
};
placement: string;
};
};
}

export interface FlowbiteBoolean {
Expand Down
45 changes: 21 additions & 24 deletions src/lib/components/Tooltip/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { FC, PropsWithChildren, ReactNode, RefObject } from 'react';
import type { ComponentProps, FC, PropsWithChildren, ReactNode, RefObject } from 'react';
import { useEffect, useRef, useState } from 'react';
import classNames from 'classnames';
import type { Placement } from '@floating-ui/core';
Expand All @@ -15,16 +15,17 @@ import {
useInteractions,
useRole,
} from '@floating-ui/react-dom-interactions';
import { useTheme } from '../Flowbite/ThemeContext';
import { excludeClassName } from '../../helpers/exclude';

export type TooltipProps = PropsWithChildren<{
className?: string;
export interface TooltipProps extends PropsWithChildren<Omit<ComponentProps<'div'>, 'className' | 'style'>> {
content: ReactNode;
placement?: 'auto' | Placement;
trigger?: 'hover' | 'click';
style?: 'dark' | 'light' | 'auto';
animation?: false | `duration-${number}`;
arrow?: boolean;
}>;
}

/**
* @see https://floating-ui.com/docs/react-dom-interactions
Expand All @@ -33,13 +34,15 @@ export const Tooltip: FC<TooltipProps> = ({
animation = 'duration-300',
arrow = true,
children,
className,
content,
placement = 'top',
style = 'dark',
trigger = 'hover',
...rest
...props
}) => {
const theme = useTheme().theme.tooltip;
const theirProps = excludeClassName(props);

const arrowRef = useRef<HTMLDivElement>(null);
const [open, setOpen] = useState(false);

Expand Down Expand Up @@ -76,40 +79,34 @@ export const Tooltip: FC<TooltipProps> = ({

return (
<>
<div className="w-fit" {...getReferenceProps({ ref: reference })} data-testid="tooltip-target">
<div className={theme.target} {...getReferenceProps({ ref: reference })} data-testid="tooltip-target">
{children}
</div>
<div
data-testid="tooltip"
{...getFloatingProps({
className: classNames(
'absolute inline-block rounded-lg py-2 px-3 text-sm font-medium shadow-sm',
animation !== false && `transition-opacity ${animation}`,
{
'invisible opacity-0': !open,
'bg-gray-900 text-white dark:bg-gray-700': style === 'dark',
'border border-gray-200 bg-white text-gray-900': style === 'light',
'border border-gray-200 bg-white text-gray-900 dark:border-none dark:bg-gray-700 dark:text-white':
style === 'auto',
},
className,
theme.base,
animation && `${theme.animation} ${animation}`,
!open && theme.hidden,
theme.style[style],
),
ref: floating,
style: {
position: strategy,
top: y ?? ' ',
left: x ?? ' ',
},
...rest,
...theirProps,
})}
>
<div className="relative z-20">{content}</div>
<div className={theme.content}>{content}</div>
{arrow && (
<div
className={classNames('absolute z-10 h-2 w-2 rotate-45', {
'bg-gray-900 dark:bg-gray-700': style === 'dark',
'bg-white': style === 'light',
'bg-white dark:bg-gray-700': style === 'auto',
className={classNames(theme.arrow.base, {
[theme.arrow.style.dark]: style === 'dark',
[theme.arrow.style.light]: style === 'light',
[theme.arrow.style.auto]: style === 'auto',
})}
data-testid="tooltip-arrow"
ref={arrowRef}
Expand All @@ -118,7 +115,7 @@ export const Tooltip: FC<TooltipProps> = ({
left: arrowX ?? ' ',
right: ' ',
bottom: ' ',
[floatingArrowPlacement({ placement: floatingTooltip.placement })]: '-4px',
[floatingArrowPlacement({ placement: floatingTooltip.placement })]: theme.arrow.placement,
}}
>
&nbsp;
Expand Down
21 changes: 21 additions & 0 deletions src/lib/theme/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -411,4 +411,25 @@ export default {
icon: 'h-5 w-5 shrink-0',
},
},
tooltip: {
target: 'w-fit',
base: 'absolute inline-block rounded-lg py-2 px-3 text-sm font-medium shadow-sm',
animation: 'transition-opacity',
hidden: 'invisible opacity-0',
style: {
dark: 'bg-gray-900 text-white dark:bg-gray-700',
light: 'border border-gray-200 bg-white text-gray-900',
auto: 'border border-gray-200 bg-white text-gray-900 dark:border-none dark:bg-gray-700 dark:text-white',
},
content: 'relative z-20',
arrow: {
base: 'absolute z-10 h-2 w-2 rotate-45',
style: {
dark: 'bg-gray-900 dark:bg-gray-700',
light: 'bg-white',
auto: 'bg-white dark:bg-gray-700',
},
placement: '-4px',
},
},
};

0 comments on commit 957ea45

Please sign in to comment.