ツールチップ
:LiTarget: 用途
ホバー/フォーカスでツールチップ表示。位置自動調整(top/bottom/left/right)。
:LiSparkle: 特徴
- ホバー表示
- フォーカス表示
- 位置自動調整
- a11y 対応
:LiCode: コード(コピペ用)
'use client';
import { useState, useRef, ReactNode, ReactElement, cloneElement } from 'react';
export function Tooltip({ children, content, side = 'top' }: {
children: ReactElement;
content: ReactNode;
side?: 'top' | 'bottom' | 'left' | 'right';
}) {
const [show, setShow] = useState(false);
const ref = useRef<HTMLSpanElement>(null);
const positions: Record<string, any> = {
top: { bottom: '100%', left: '50%', transform: 'translateX(-50%) translateY(-6px)' },
bottom: { top: '100%', left: '50%', transform: 'translateX(-50%) translateY(6px)' },
left: { right: '100%', top: '50%', transform: 'translateY(-50%) translateX(-6px)' },
right: { left: '100%', top: '50%', transform: 'translateY(-50%) translateX(6px)' },
};
return (
<span ref={ref} style={{ position: 'relative', display: 'inline-block' }}
onMouseEnter={() => setShow(true)} onMouseLeave={() => setShow(false)}
onFocus={() => setShow(true)} onBlur={() => setShow(false)}>
{children}
{show && (
<span role="tooltip" style={{
position: 'absolute', ...positions[side],
background: 'rgba(8,8,10,.94)', border: '1px solid rgba(255,255,255,.07)',
color: '#fff', fontSize: '.7rem', padding: '.4rem .65rem', borderRadius: 4,
whiteSpace: 'nowrap', zIndex: 50, pointerEvents: 'none',
}}>
{content}
</span>
)}
</span>
);
}
:LiHandPointer: 使い方
対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。
:LiAlertCircle: 注意事項
- 依存パッケージを忘れず追加