mirror of
https://github.com/toeverything/AFFiNE.git
synced 2024-11-27 03:42:08 +03:00
feat: modify popper
This commit is contained in:
parent
d9205bb405
commit
75f05cb399
@ -1,65 +0,0 @@
|
||||
import { useState } from 'react';
|
||||
import type { CSSProperties, PropsWithChildren, ReactNode } from 'react';
|
||||
import Grow from '@mui/material/Grow';
|
||||
import ClickAwayListener from '@mui/base/ClickAwayListener';
|
||||
|
||||
import { styled } from '@/styles';
|
||||
|
||||
type PopoverProps = {
|
||||
popoverContent?: ReactNode;
|
||||
style?: CSSProperties;
|
||||
};
|
||||
|
||||
const StyledPopoverContainer = styled('div')({
|
||||
position: 'relative',
|
||||
cursor: 'pointer',
|
||||
});
|
||||
|
||||
const StyledPopoverWrapper = styled('div')({
|
||||
position: 'absolute',
|
||||
bottom: '0',
|
||||
right: '0',
|
||||
paddingTop: '46px',
|
||||
zIndex: 1000,
|
||||
});
|
||||
const StyledPopover = styled('div')(({ theme }) => {
|
||||
return {
|
||||
width: '248px',
|
||||
background: theme.colors.popoverBackground,
|
||||
boxShadow: theme.shadow.popover,
|
||||
color: theme.colors.popoverColor,
|
||||
borderRadius: '10px 0px 10px 10px',
|
||||
padding: '8px 4px',
|
||||
position: 'absolute',
|
||||
top: '46px',
|
||||
right: '0',
|
||||
};
|
||||
});
|
||||
export const Popover = ({
|
||||
children,
|
||||
popoverContent,
|
||||
style = {},
|
||||
}: PropsWithChildren<PopoverProps>) => {
|
||||
const [show, setShow] = useState(false);
|
||||
return (
|
||||
<ClickAwayListener
|
||||
onClickAway={() => {
|
||||
setShow(false);
|
||||
}}
|
||||
>
|
||||
<StyledPopoverContainer
|
||||
onClick={() => {
|
||||
setShow(!show);
|
||||
}}
|
||||
style={style}
|
||||
>
|
||||
{children}
|
||||
<Grow in={show}>
|
||||
<StyledPopoverWrapper>
|
||||
<StyledPopover>{popoverContent}</StyledPopover>
|
||||
</StyledPopoverWrapper>
|
||||
</Grow>
|
||||
</StyledPopoverContainer>
|
||||
</ClickAwayListener>
|
||||
);
|
||||
};
|
@ -4,6 +4,7 @@ import {
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
cloneElement,
|
||||
} from 'react';
|
||||
import PopperUnstyled from '@mui/base/PopperUnstyled';
|
||||
import ClickAwayListener from '@mui/base/ClickAwayListener';
|
||||
@ -26,7 +27,6 @@ export const Popper = ({
|
||||
onVisibleChange,
|
||||
popoverStyle,
|
||||
popoverClassName,
|
||||
anchorStyle,
|
||||
anchorClassName,
|
||||
zIndex,
|
||||
offset = [0, 5],
|
||||
@ -36,12 +36,9 @@ export const Popper = ({
|
||||
onClickAway,
|
||||
...popperProps
|
||||
}: PopperProps) => {
|
||||
// @ts-ignore
|
||||
const [anchorEl, setAnchorEl] = useState<VirtualElement>(null);
|
||||
const [anchorEl, setAnchorEl] = useState<VirtualElement>();
|
||||
const [visible, setVisible] = useState(defaultVisible);
|
||||
// @ts-ignore
|
||||
const [arrowRef, setArrowRef] = useState<HTMLElement>(null);
|
||||
const popperRef = useRef();
|
||||
const [arrowRef, setArrowRef] = useState<HTMLElement>();
|
||||
const pointerLeaveTimer = useRef<number>();
|
||||
const pointerEnterTimer = useRef<number>();
|
||||
|
||||
@ -95,7 +92,6 @@ export const Popper = ({
|
||||
};
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
return (
|
||||
<ClickAwayListener
|
||||
onClickAway={() => {
|
||||
@ -107,66 +103,63 @@ export const Popper = ({
|
||||
}}
|
||||
>
|
||||
<Container>
|
||||
{isAnchorCustom ? null : (
|
||||
<div
|
||||
ref={(dom: HTMLDivElement) => setAnchorEl(dom)}
|
||||
onClick={e => {
|
||||
if (!hasClickTrigger || visibleControlledByParent) {
|
||||
onClick?.(e);
|
||||
return;
|
||||
}
|
||||
setVisible(!visible);
|
||||
}}
|
||||
onPointerEnter={onPointerEnterHandler}
|
||||
onPointerLeave={onPointerLeaveHandler}
|
||||
style={anchorStyle}
|
||||
className={anchorClassName}
|
||||
{cloneElement(children, {
|
||||
ref: (dom: HTMLDivElement) => setAnchorEl(dom),
|
||||
onClick: (e: MouseEvent) => {
|
||||
if (!hasClickTrigger || visibleControlledByParent) {
|
||||
// @ts-ignore
|
||||
onClick?.(e);
|
||||
return;
|
||||
}
|
||||
setVisible(!visible);
|
||||
},
|
||||
onPointerEnter: onPointerEnterHandler,
|
||||
onPointerLeave: onPointerLeaveHandler,
|
||||
className: anchorClassName,
|
||||
popperVisible: visible,
|
||||
})}
|
||||
{content && (
|
||||
<BasicStyledPopper
|
||||
open={visibleControlledByParent ? propsVisible : visible}
|
||||
zIndex={zIndex}
|
||||
anchorEl={isAnchorCustom ? propsAnchorEl : anchorEl}
|
||||
placement={placement}
|
||||
transition
|
||||
modifiers={[
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'arrow',
|
||||
enabled: showArrow,
|
||||
options: {
|
||||
element: arrowRef,
|
||||
},
|
||||
},
|
||||
]}
|
||||
{...popperProps}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
{({ TransitionProps }) => (
|
||||
<Grow {...TransitionProps}>
|
||||
<div
|
||||
onPointerEnter={onPointerEnterHandler}
|
||||
onPointerLeave={onPointerLeaveHandler}
|
||||
style={popoverStyle}
|
||||
className={popoverClassName}
|
||||
>
|
||||
{showArrow && (
|
||||
// @ts-ignore
|
||||
<PopperArrow placement={placement} ref={setArrowRef} />
|
||||
)}
|
||||
{content}
|
||||
</div>
|
||||
</Grow>
|
||||
)}
|
||||
</BasicStyledPopper>
|
||||
)}
|
||||
<BasicStyledPopper
|
||||
// @ts-ignore
|
||||
popperRef={popperRef}
|
||||
open={visibleControlledByParent ? propsVisible : visible}
|
||||
zIndex={zIndex}
|
||||
anchorEl={isAnchorCustom ? propsAnchorEl : anchorEl}
|
||||
placement={placement}
|
||||
transition
|
||||
modifiers={[
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'arrow',
|
||||
enabled: showArrow,
|
||||
options: {
|
||||
element: arrowRef,
|
||||
},
|
||||
},
|
||||
]}
|
||||
{...popperProps}
|
||||
>
|
||||
{({ TransitionProps }) => (
|
||||
<Grow {...TransitionProps}>
|
||||
<div
|
||||
onPointerEnter={onPointerEnterHandler}
|
||||
onPointerLeave={onPointerLeaveHandler}
|
||||
style={popoverStyle}
|
||||
className={popoverClassName}
|
||||
>
|
||||
{showArrow && (
|
||||
// @ts-ignore
|
||||
<PopperArrow placement={placement} ref={setArrowRef} />
|
||||
)}
|
||||
{content}
|
||||
</div>
|
||||
</Grow>
|
||||
)}
|
||||
</BasicStyledPopper>
|
||||
</Container>
|
||||
</ClickAwayListener>
|
||||
);
|
||||
@ -184,6 +177,6 @@ const BasicStyledPopper = styled(PopperUnstyled, {
|
||||
zIndex?: number;
|
||||
}>(({ zIndex, theme }) => {
|
||||
return {
|
||||
zIndex: zIndex,
|
||||
zIndex: zIndex ?? theme.zIndex.popover,
|
||||
};
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { CSSProperties, ReactNode, Ref } from 'react';
|
||||
import type { CSSProperties, ReactNode, Ref, ReactElement } from 'react';
|
||||
import {
|
||||
type PopperPlacementType,
|
||||
type PopperUnstyledProps,
|
||||
@ -18,10 +18,10 @@ export type PopperArrowProps = {
|
||||
|
||||
export type PopperProps = {
|
||||
// Popover content
|
||||
content: ReactNode;
|
||||
content?: ReactNode;
|
||||
|
||||
// Popover trigger
|
||||
children?: ReactNode;
|
||||
children: ReactElement;
|
||||
|
||||
// Whether the default is implicit
|
||||
defaultVisible?: boolean;
|
||||
@ -47,9 +47,6 @@ export type PopperProps = {
|
||||
// Popover container class name
|
||||
popoverClassName?: string;
|
||||
|
||||
// Anchor style
|
||||
anchorStyle?: CSSProperties;
|
||||
|
||||
// Anchor class name
|
||||
anchorClassName?: string;
|
||||
|
||||
@ -63,4 +60,4 @@ export type PopperProps = {
|
||||
popperHandlerRef?: Ref<PopperHandler>;
|
||||
|
||||
onClickAway?: () => void;
|
||||
} & Omit<PopperUnstyledProps, 'open' | 'ref'>;
|
||||
} & Omit<PopperUnstyledProps, 'open'>;
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { type PropsWithChildren } from 'react';
|
||||
import StyledPopperContainer from '../shared/Container';
|
||||
import { Popper, type PopperProps } from '../popper';
|
||||
import { styled } from '@/styles';
|
||||
@ -14,16 +13,15 @@ const StyledTooltip = styled(StyledPopperContainer)(({ theme }) => {
|
||||
};
|
||||
});
|
||||
|
||||
export const Tooltip = (
|
||||
props: PropsWithChildren<PopperProps & Omit<TooltipProps, 'title'>>
|
||||
) => {
|
||||
const { content, placement = 'top-start' } = props;
|
||||
// If there is no content, hide forever
|
||||
return content ? (
|
||||
export const Tooltip = (props: PopperProps & Omit<TooltipProps, 'title'>) => {
|
||||
const { content, placement = 'top-start', children } = props;
|
||||
return (
|
||||
<Popper
|
||||
{...props}
|
||||
showArrow={false}
|
||||
content={<StyledTooltip placement={placement}>{content}</StyledTooltip>}
|
||||
/>
|
||||
) : null;
|
||||
>
|
||||
{children}
|
||||
</Popper>
|
||||
);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user