Skip to content

Instantly share code, notes, and snippets.

@manabuyasuda
Last active April 19, 2024 10:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save manabuyasuda/0d6816ef085528078e0ad0c886382ea2 to your computer and use it in GitHub Desktop.
Save manabuyasuda/0d6816ef085528078e0ad0c886382ea2 to your computer and use it in GitHub Desktop.
@radix-ui/react-tooltip
@use '@root/common/styles/index.scss' as *;
.tooltip_content {
z-index: 1;
width: 510px;
max-width: 100%;
padding: 8px;
border-radius: 8px;
animation-duration: 0.2s;
animation-timing-function: ease-in-out;
background: #ededed;
color: var(--Secondary, #595959);
font-size: 12px;
font-weight: 400;
line-height: 150%;
pointer-events: visible;
will-change: transform, opacity;
@media (max-width: $break-point) {
width: 100vw;
}
&[data-state='delayed-open'] {
animation-name: fade;
}
}
@keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.tooltip_button {
all: unset;
display: flex;
width: 12px;
height: 12px;
align-items: center;
@media (max-width: $break-point) {
width: 16px;
height: 16px;
}
& svg {
width: 100%;
height: auto;
}
}
'use client';
import React, { useState } from 'react';
import { Provider, Root, Trigger, Content } from '@radix-ui/react-tooltip';
import styles from './index.module.scss';
type Props = {
content: React.ReactNode;
icon?: React.ReactNode;
[key: string]: any;
};
/**
* ツールチップを表示するコンポーネントです。
* @param {React.ReactNode} content - ツールチップに表示する内容(HTML利用可能)
* @param {React.ReactNode} icon - トリガーになるアイコンを変更する場合に指定します
* @param {object} [props] - `Content`のpropsを必要に応じて指定します
* @returns {React.Component} ツールチップコンポーネント
* @see {@link https://www.radix-ui.com/primitives/docs/components/tooltip#content}
*
* @example
* import Tooltip from '@root/common/components/article/article-items/tooltip';
* <Tooltip content="ここに説明を表示" />
* @example
* // コンテンツにHTMLを使用する場合
* <Tooltip content={<>ここに<br />説明を表示</br>} />
* @example
* // コンテンツの位置を変更する場合
* <Tooltip
* align="start"
* alignOffset="0"
* side="top"
* content="ここに説明を表示"
* />
* @example
* // トリガーになるアイコンを変更する場合
* <Tooltip content="ここに説明を表示" icon={<svg></svg>} />
*/
export default function Tooltip({ content, icon, ...props }: Props) {
const [open, setOpen] = useState(false);
return (
<Provider delayDuration={0}>
<Root open={open} onOpenChange={setOpen} delayDuration={0}>
<Trigger asChild>
<button
className={styles.tooltip_button}
onClick={(event) => {
setOpen((prevOpen) => !prevOpen);
event.stopPropagation(); // イベントの伝播を停止
}} // クリック時にツールチップの表示状態を切り替える
onFocus={() => setTimeout(() => setOpen(true), 0)} // フォーカス時にツールチップを表示する(setTimeoutを使用してイベント順序問題を解決)
onBlur={() => setOpen(false)} // フォーカスが外れた時にツールチップを非表示にする
>
{icon ? (
icon
) : (
<svg
xmlns="http://www.w3.org/2000/svg"
width="12"
height="13"
viewBox="0 0 12 13"
fill="none"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6 0.5C2.688 0.5 0 3.188 0 6.5C0 9.812 2.688 12.5 6 12.5C9.312 12.5 12 9.812 12 6.5C12 3.188 9.312 0.5 6 0.5ZM5.99974 3.5C5.66837 3.5 5.39974 3.76863 5.39974 4.1C5.39974 4.43137 5.66837 4.7 5.99974 4.7C6.33111 4.7 6.59974 4.43137 6.59974 4.1C6.59974 3.76863 6.33111 3.5 5.99974 3.5ZM5.99974 5.90006C5.66837 5.90006 5.39974 6.16869 5.39974 6.50007V8.90007C5.39974 9.23144 5.66837 9.50007 5.99974 9.50007C6.33111 9.50007 6.59974 9.23144 6.59974 8.90007V6.50007C6.59974 6.16869 6.33111 5.90006 5.99974 5.90006ZM1.20002 6.49991C1.20002 9.14591 3.35402 11.2999 6.00002 11.2999C8.64602 11.2999 10.8 9.14591 10.8 6.49991C10.8 3.85391 8.64602 1.69991 6.00002 1.69991C3.35402 1.69991 1.20002 3.85391 1.20002 6.49991Z"
fill="#B2B2B2"
/>
</svg>
)}
</button>
</Trigger>
<Content
alignOffset={8}
sideOffset={8}
{...props}
className={styles.tooltip_content}
>
{content}
</Content>
</Root>
</Provider>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment