增加Tooltip组件。

This commit is contained in:
徐涛 2024-12-25 09:28:46 +08:00
parent 8222cfc2e9
commit 4d4192c0f0
2 changed files with 112 additions and 0 deletions

View File

@ -0,0 +1,66 @@
@layer components {
.tooltip_container {
position: relative;
display: inline-block;
}
.tooltip {
position: absolute;
padding-inline: calc(var(--spacing) * 3);
padding-block: calc(var(--spacing) * 1);
border-radius: var(--border-radius-xxs);
color: light-dark(
oklch(from var(--color-neutral) calc(l + (1 - l) * 0.8) c h),
oklch(from var(--color-neutral) calc(l + (1 - l) * 0.7) c h)
);
background-color: light-dark(
oklch(from var(--color-qianbai) calc(l * 0.6) c h),
oklch(from var(--color-qihei) calc(l + (1 - l) * 0.2) c h)
);
font-size: var(--font-size-m);
width: fit-content;
max-width: 40em;
text-wrap: balance;
word-break: keep-all;
box-shadow: 0 4px 6px -1px oklch(from var(--color-black) l c h / 0.1),
0 2px 4px -2px oklch(from var(--color-black) l c h / 0.1);
pointer-events: none;
&.top {
bottom: 100%;
left: 50%;
transform: translateX(-50%);
margin-bottom: calc(var(--spacing) * 4);
}
&.bottom {
top: 100%;
left: 50%;
transform: translateX(-50%);
margin-top: calc(var(--spacing) * 4);
}
&.left {
top: 50%;
right: 100%;
transform: translateY(-50%);
margin-right: calc(var(--spacing) * 4);
}
&.right {
top: 50%;
left: 100%;
transform: translateY(-50%);
margin-left: calc(var(--spacing) * 4);
}
}
.fade_enter {
opacity: 0%;
transition: opacity 200ms ease-in;
}
.fade_enter_active {
opacity: 100%;
}
.fade_exit {
opacity: 100%;
transition: opacity 200ms ease-out;
}
.fade_exit_active {
opacity: 0%;
}
}

View File

@ -0,0 +1,46 @@
import cx from 'clsx';
import { ReactNode, useRef, useState } from 'react';
import { CSSTransition } from 'react-transition-group';
import styles from './Tooltip.module.css';
interface TooltipProps {
content: ReactNode;
position?: 'top' | 'bottom' | 'left' | 'right';
children?: ReactNode;
}
const positionMap = {
top: styles.top,
bottom: styles.bottom,
left: styles.left,
right: styles.right,
};
export function Tooltip({ content, position = 'top', children }: TooltipProps) {
const [show, setShow] = useState(false);
const contentRef = useRef<HTMLDivElement>();
return (
<div
className={styles.tooltip_container}
onMouseEnter={() => setShow(true)}
onMouseLeave={() => setShow(false)}>
{children}
<CSSTransition
nodeRef={contentRef}
in={show}
unmountOnExit
classNames={{
enter: styles.fade_enter,
enterActive: styles.fade_enter_active,
exit: styles.fade_exit,
exitActive: styles.fade_exit_active,
}}
timeout={200}>
<div className={cx(styles.tooltip, positionMap[position])} ref={contentRef}>
{content}
</div>
</CSSTransition>
</div>
);
}