mirror of
https://github.com/logto-io/logto.git
synced 2025-03-10 22:22:45 -05:00
fix(console): tooltip style (#1517)
This commit is contained in:
parent
a78427e470
commit
f387652bfd
3 changed files with 58 additions and 16 deletions
|
@ -50,6 +50,7 @@ const CopyToClipboard = ({ value, className, variant = 'contained' }: Props) =>
|
|||
<Tooltip
|
||||
anchorRef={copyIconReference}
|
||||
content={t(copyState)}
|
||||
horizontalAlign="center"
|
||||
className={classNames(copyState === 'copied' && styles.successfulTooltip)}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
box-shadow: var(--shadow-1);
|
||||
padding: _.unit(2) _.unit(3);
|
||||
font: var(--font-body-medium);
|
||||
max-width: 300px;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
|
@ -25,4 +26,21 @@
|
|||
&.arrowUp::after {
|
||||
top: 0%;
|
||||
}
|
||||
|
||||
&.start::after {
|
||||
left: _.unit(10);
|
||||
}
|
||||
|
||||
&.end::after {
|
||||
right: _.unit(10);
|
||||
}
|
||||
|
||||
.content {
|
||||
// https://css-tricks.com/almanac/properties/l/line-clamp/
|
||||
/* stylelint-disable-next-line value-no-vendor-prefix */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 6;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import classNames from 'classnames';
|
|||
import React, { ReactNode, RefObject, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
import usePosition from '@/hooks/use-position';
|
||||
import usePosition, { HorizontalAlignment } from '@/hooks/use-position';
|
||||
|
||||
import * as styles from './index.module.scss';
|
||||
|
||||
|
@ -11,24 +11,42 @@ type Props = {
|
|||
anchorRef: RefObject<Element>;
|
||||
className?: string;
|
||||
isKeepOpen?: boolean;
|
||||
horizontalAlign?: HorizontalAlignment;
|
||||
};
|
||||
|
||||
const Tooltip = ({ content, anchorRef, className, isKeepOpen = false }: Props) => {
|
||||
const getHorizontalOffset = (alignment: HorizontalAlignment): number => {
|
||||
switch (alignment) {
|
||||
case 'start':
|
||||
return -32;
|
||||
case 'end':
|
||||
return 32;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
const Tooltip = ({
|
||||
content,
|
||||
anchorRef,
|
||||
className,
|
||||
isKeepOpen = false,
|
||||
horizontalAlign = 'start',
|
||||
}: Props) => {
|
||||
const [tooltipDom, setTooltipDom] = useState<HTMLDivElement>();
|
||||
const tooltipRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const { position, positionState, mutate } = usePosition({
|
||||
verticalAlign: 'top',
|
||||
horizontalAlign: 'center',
|
||||
offset: { vertical: 20, horizontal: 0 },
|
||||
horizontalAlign,
|
||||
offset: { vertical: 16, horizontal: getHorizontalOffset(horizontalAlign) },
|
||||
anchorRef,
|
||||
overlayRef: tooltipRef,
|
||||
});
|
||||
|
||||
const [showUp, setShowUp] = useState(false);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!showUp) {
|
||||
if (!isVisible) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -39,7 +57,7 @@ const Tooltip = ({ content, anchorRef, className, isKeepOpen = false }: Props) =
|
|||
return () => {
|
||||
cancelAnimationFrame(mutateAnimationFrame);
|
||||
};
|
||||
}, [showUp, mutate]);
|
||||
}, [isVisible, mutate]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!anchorRef.current) {
|
||||
|
@ -47,7 +65,7 @@ const Tooltip = ({ content, anchorRef, className, isKeepOpen = false }: Props) =
|
|||
}
|
||||
|
||||
if (isKeepOpen) {
|
||||
setShowUp(true);
|
||||
setIsVisible(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -55,13 +73,13 @@ const Tooltip = ({ content, anchorRef, className, isKeepOpen = false }: Props) =
|
|||
const dom = anchorRef.current;
|
||||
|
||||
const enterHandler = () => {
|
||||
if (!showUp) {
|
||||
setShowUp(true);
|
||||
if (!isVisible) {
|
||||
setIsVisible(true);
|
||||
}
|
||||
};
|
||||
|
||||
const leaveHandler = () => {
|
||||
setShowUp(false);
|
||||
setIsVisible(false);
|
||||
};
|
||||
|
||||
dom.addEventListener('mouseenter', enterHandler);
|
||||
|
@ -71,10 +89,10 @@ const Tooltip = ({ content, anchorRef, className, isKeepOpen = false }: Props) =
|
|||
dom.removeEventListener('mouseenter', enterHandler);
|
||||
dom.removeEventListener('mouseleave', leaveHandler);
|
||||
};
|
||||
}, [anchorRef, showUp, isKeepOpen]);
|
||||
}, [anchorRef, isVisible, isKeepOpen]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!showUp) {
|
||||
if (!isVisible) {
|
||||
if (tooltipDom) {
|
||||
tooltipDom.remove();
|
||||
setTooltipDom(undefined);
|
||||
|
@ -90,7 +108,7 @@ const Tooltip = ({ content, anchorRef, className, isKeepOpen = false }: Props) =
|
|||
}
|
||||
|
||||
return () => tooltipDom?.remove();
|
||||
}, [showUp, tooltipDom]);
|
||||
}, [isVisible, tooltipDom]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
mutate();
|
||||
|
@ -105,10 +123,15 @@ const Tooltip = ({ content, anchorRef, className, isKeepOpen = false }: Props) =
|
|||
return createPortal(
|
||||
<div
|
||||
ref={tooltipRef}
|
||||
className={classNames(styles.tooltip, isArrowUp && styles.arrowUp, className)}
|
||||
className={classNames(
|
||||
styles.tooltip,
|
||||
isArrowUp && styles.arrowUp,
|
||||
styles[horizontalAlign],
|
||||
className
|
||||
)}
|
||||
style={{ ...position }}
|
||||
>
|
||||
{content}
|
||||
<div className={styles.content}>{content}</div>
|
||||
</div>,
|
||||
tooltipDom
|
||||
);
|
||||
|
|
Loading…
Add table
Reference in a new issue