mirror of https://github.com/apache/druid.git
add shpitz
This commit is contained in:
parent
4b731c0b0c
commit
93cd91bedf
|
@ -18,6 +18,8 @@
|
|||
|
||||
@import '../../variables';
|
||||
|
||||
$shpitz-size: 10px;
|
||||
|
||||
.portal-bubble {
|
||||
position: absolute;
|
||||
@include card-like;
|
||||
|
@ -38,9 +40,21 @@
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
& > .shpitz {
|
||||
content: '';
|
||||
position: absolute;
|
||||
transform: translate(-50%, 0);
|
||||
bottom: -$shpitz-size;
|
||||
border-top: $shpitz-size solid $dark-gray1;
|
||||
border-right: $shpitz-size solid transparent;
|
||||
border-left: $shpitz-size solid transparent;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
& > .bubble-title-bar {
|
||||
position: relative;
|
||||
padding: 5px 5px 0 5px;
|
||||
white-space: nowrap;
|
||||
font-weight: bold;
|
||||
|
||||
&.with-close {
|
||||
|
|
|
@ -20,7 +20,7 @@ import { Button } from '@blueprintjs/core';
|
|||
import { IconNames } from '@blueprintjs/icons';
|
||||
import classNames from 'classnames';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useRef } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
import { clamp } from '../../utils';
|
||||
|
@ -33,24 +33,28 @@ interface PortalBubbleProps {
|
|||
direction?: 'up' | 'down';
|
||||
onClose?(): void;
|
||||
mute?: boolean;
|
||||
minimal?: boolean;
|
||||
}
|
||||
|
||||
export const PortalBubble = function PortalBubble(props: PortalBubbleProps) {
|
||||
const { className, openOn, direction = 'up', onClose, mute } = props;
|
||||
const ref = useRef<HTMLDivElement | null>(null);
|
||||
const { className, openOn, direction = 'up', onClose, mute, minimal } = props;
|
||||
const [myWidth, setMyWidth] = useState(200);
|
||||
if (!openOn) return null;
|
||||
|
||||
const div: HTMLDivElement | null = ref.current;
|
||||
const myWidth = div ? div.offsetWidth : 200;
|
||||
const halfMyWidth = myWidth / 2;
|
||||
|
||||
const x = clamp(openOn.x, myWidth / 2, window.innerWidth - myWidth / 2);
|
||||
const x = clamp(openOn.x, halfMyWidth, window.innerWidth - halfMyWidth);
|
||||
const offset = clamp(x - openOn.x, -halfMyWidth, halfMyWidth);
|
||||
|
||||
return createPortal(
|
||||
<div
|
||||
className={classNames('portal-bubble', className, direction, {
|
||||
mute: mute && !onClose,
|
||||
})}
|
||||
ref={ref}
|
||||
ref={element => {
|
||||
if (!element) return;
|
||||
setMyWidth(element.offsetWidth);
|
||||
}}
|
||||
style={{ left: x, top: openOn.y }}
|
||||
>
|
||||
{(openOn.title || onClose) && (
|
||||
|
@ -68,6 +72,9 @@ export const PortalBubble = function PortalBubble(props: PortalBubbleProps) {
|
|||
</div>
|
||||
)}
|
||||
<div className="bubble-content">{openOn.text}</div>
|
||||
{!minimal && (
|
||||
<div className="shpitz" style={{ left: offset ? `calc(50% - ${offset}px)` : '50%' }} />
|
||||
)}
|
||||
</div>,
|
||||
document.body,
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue