Skip to content

Commit

Permalink
fix(tooltip): review fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
revolunet committed Oct 7, 2024
1 parent a921417 commit 9f9ef21
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 61 deletions.
88 changes: 33 additions & 55 deletions src/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
import React, { forwardRef, memo, ReactElement } from "react";
import React, { forwardRef, memo } from "react";
import type { ReactNode, CSSProperties } from "react";
import type { Equals } from "tsafe";
import { assert } from "tsafe/assert";
import { symToStr } from "tsafe/symToStr";
import { useAnalyticsId } from "./tools/useAnalyticsId";
import { createComponentI18nApi } from "./i18n";
import { fr } from "./fr";
import { cx } from "./tools/cx";

export type TooltipProps = TooltipProps.WithClickAction | TooltipProps.WithHoverAction;

export namespace TooltipProps {
export type Common = {
description: string;
title: ReactNode;
id?: string;
className?: string;
style?: CSSProperties;
};

export type WithClickAction = Common & {
kind: "click";
children?: ReactElement | string;
children?: undefined;
};

export type WithHoverAction = Common & {
kind?: "hover";
children: ReactElement | string;
children: ReactNode;
};
}

/** @see <https://components.react-dsfr.codegouv.studio/?path=/docs/components-tooltip> */
export const Tooltip = memo(
forwardRef<HTMLSpanElement, TooltipProps>((props, ref) => {
const { id: id_prop, className, description, kind, children, ...rest } = props;
const { id: id_prop, className, title, kind, style, children, ...rest } = props;
assert<Equals<keyof typeof rest, never>>();

const { t } = useTranslation();
Expand All @@ -38,61 +42,35 @@ export const Tooltip = memo(
"explicitlyProvidedId": id_prop
});

const displayChildren = (
children: ReactElement | string | undefined,
id: string
): ReactElement => {
if (children === undefined) return <></>;
return typeof children === "string" ? (
<span aria-describedby={id} id={`tooltip-owner-${id}`}>
{children}
</span>
) : (
children &&
React.cloneElement(children, {
"aria-describedby": id,
"id": `tooltip-owner-${id}`
})
);
};
const TooltipSpan = () => (
<span
className={cx(fr.cx("fr-tooltip", "fr-placement"), className)}
id={id}
ref={ref}
style={style}
role="tooltip"
aria-hidden="true"
>
{title}
</span>
);

return (
<>
{props.kind === "click" ? (
<span ref={ref}>
{children === undefined ? (
<button
className="fr-btn--tooltip fr-btn"
aria-describedby={id}
id={`tooltip-owner-${id}`}
>
{t("tooltip-button-text")}
</button>
) : (
displayChildren(children, id)
)}
<span
className={`fr-tooltip fr-placement ${props.className}`}
id={id}
role="tooltip"
aria-hidden="true"
>
{props.description}
</span>
</span>
) : (
<span ref={ref}>
{displayChildren(children, id)}
<span
className={`fr-tooltip fr-placement ${props.className}`}
id={id}
role="tooltip"
aria-hidden="true"
>
{props.description}
</span>
{(kind === "click" && (
<button
className={fr.cx("fr-btn--tooltip", "fr-btn")}
aria-describedby={id}
id={`tooltip-owner-${id}`}
>
{t("tooltip-button-text")}
</button>
)) || (
<span aria-describedby={id} id={`tooltip-owner-${id}`}>
{children}
</span>
)}
<TooltipSpan />
</>
);
})
Expand Down
17 changes: 11 additions & 6 deletions stories/Tooltip.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from "react";
import { Tooltip, type TooltipProps } from "../dist/Tooltip";
import { sectionName } from "./sectionName";
import { getStoryFactory } from "./getStory";
Expand Down Expand Up @@ -30,28 +31,32 @@ const { meta, getStory } = getStoryFactory({
})(),
"description": "Optional."
},
"description": {
"title": {
"control": { "type": "text" }
},
"children": {
"control": { "type": "text" }
}
},
"disabledProps": ["lang"]
}
});

export default meta;

const defaultOnHoverProps: TooltipProps.WithHoverAction = {
"description": "lorem ipsum",
"children": "Exemple"
"title": "lorem ipsum",
"children": "Hover example"
};

export const Default = getStory(defaultOnHoverProps);

export const TooltipOnHover = getStory(defaultOnHoverProps);

export const TooltipOnHoverLink = getStory({
...defaultOnHoverProps,
children: <a href="#">Some link</a>
});

export const TooltipOnClick = getStory({
"kind": "click",
"description": "lorem ipsum"
"title": "lorem ipsum"
});

0 comments on commit 9f9ef21

Please sign in to comment.