From ac84c16a4adaa41a465d1c8bd42f0cd0458344d2 Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Fri, 12 Aug 2022 15:23:11 +0800 Subject: [PATCH 1/6] fix: fix color and text of status pendant --- libs/components/editor-core/src/block-pendant/config.ts | 4 ++-- libs/components/editor-core/src/block-pendant/utils.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/components/editor-core/src/block-pendant/config.ts b/libs/components/editor-core/src/block-pendant/config.ts index 077a795142..74471647d2 100644 --- a/libs/components/editor-core/src/block-pendant/config.ts +++ b/libs/components/editor-core/src/block-pendant/config.ts @@ -98,8 +98,8 @@ export const pendantConfig: { [key: string]: PendantConfig } = { }, [PendantTypes.Status]: { iconName: IconNames.STATUS, - background: ['#C5FBE0', '#FFF5AB', '#FFCECE', '#E3DEFF'], - color: ['#05683D', '#896406', '#AF1212', '#511AAB'], + background: ['#FFCECE', '#FFF5AB', '#C5FBE0', '#E3DEFF'], + color: ['#AF1212', '#896406', '#05683D', '#511AAB'], }, [PendantTypes.Select]: { iconName: IconNames.SINGLE_SELECT, diff --git a/libs/components/editor-core/src/block-pendant/utils.ts b/libs/components/editor-core/src/block-pendant/utils.ts index 63a3344a91..bebdef1925 100644 --- a/libs/components/editor-core/src/block-pendant/utils.ts +++ b/libs/components/editor-core/src/block-pendant/utils.ts @@ -88,7 +88,7 @@ export const generateInitialOptions = ( ) => { if (type === PendantTypes.Status) { return [ - generateBasicOption({ index: 0, iconConfig, name: 'No Started' }), + generateBasicOption({ index: 0, iconConfig, name: 'Not Started' }), generateBasicOption({ index: 1, iconConfig, From 7e3df042ecf0312e89cdf2478ce1bdd46f22eb7f Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Fri, 12 Aug 2022 16:10:05 +0800 Subject: [PATCH 2/6] feat: update pendant add button --- .../src/block-pendant/AddPendantPopover.tsx | 27 ++++++++++++++++--- .../pendant-popover/PendantPopover.tsx | 1 + 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/libs/components/editor-core/src/block-pendant/AddPendantPopover.tsx b/libs/components/editor-core/src/block-pendant/AddPendantPopover.tsx index bbb61be631..015f8a4120 100644 --- a/libs/components/editor-core/src/block-pendant/AddPendantPopover.tsx +++ b/libs/components/editor-core/src/block-pendant/AddPendantPopover.tsx @@ -4,7 +4,10 @@ import { Popover, type PopoverProps, PopperHandler, + Tag, } from '@toeverything/components/ui'; +import { TagsIcon } from '@toeverything/components/icons'; + import { CreatePendantPanel } from './pendant-operation-panel'; import { IconButton } from './StyledComponent'; import { AsyncBlock } from '../editor'; @@ -13,11 +16,13 @@ type Props = { block: AsyncBlock; onSure?: () => void; iconStyle?: CSSProperties; + useAddIcon?: boolean; } & Omit; export const AddPendantPopover = ({ block, onSure, iconStyle, + useAddIcon = true, ...popoverProps }: Props) => { const popoverHandlerRef = useRef(); @@ -38,9 +43,25 @@ export const AddPendantPopover = ({ style={{ padding: 0 }} {...popoverProps} > - - - + {useAddIcon ? ( + + + + ) : ( + + } + > + Tag App + + )} ); }; diff --git a/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx b/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx index d92a2ab8b4..36d785a181 100644 --- a/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx +++ b/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx @@ -33,6 +33,7 @@ export const PendantPopover = ( }} offset={[0, -30]} trigger="click" + useAddIcon={false} /> } onClose={() => { From 82c3d773d6fb782d05a4528ce9ef7605dbfe2ba9 Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Fri, 12 Aug 2022 16:24:51 +0800 Subject: [PATCH 3/6] fix: move the pendant popover to the body layer --- .../src/block-pendant/pendant-popover/PendantPopover.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx b/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx index 36d785a181..09ad317777 100644 --- a/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx +++ b/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx @@ -26,7 +26,6 @@ export const PendantPopover = ( block={block} endElement={ { popoverHandlerRef.current?.setVisible(false); From f16bfecab88f9024d48c3fe2666b27b01da1ad0d Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Fri, 12 Aug 2022 18:49:47 +0800 Subject: [PATCH 4/6] refactor: refactor popper --- .../components/command-panel/CommandPanel.tsx | 4 +- .../PendantHistoryPanel.tsx | 2 +- .../pendant-popover/PendantPopover.tsx | 2 +- .../pendant-render/PandentRender.tsx | 4 +- libs/components/ui/src/popover/Popover.tsx | 12 +- libs/components/ui/src/popper/Popper.tsx | 326 +++++++++--------- libs/components/ui/src/popper/interface.ts | 29 +- libs/components/ui/src/tooltip/Tooltip.tsx | 14 +- 8 files changed, 188 insertions(+), 205 deletions(-) diff --git a/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx b/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx index 6c45bfc4e6..bc22965a71 100644 --- a/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx +++ b/libs/components/board-draw/src/components/command-panel/CommandPanel.tsx @@ -23,7 +23,7 @@ export const CommandPanel = ({ app }: { app: TldrawApp }) => { ? app.getScreenPoint([bounds.minX, bounds.minY]) : undefined; - const anchor = getAnchor({ + const anchorEl = getAnchor({ x: point?.[0] || 0, y: (point?.[1] || 0) + 40, width: bounds?.width ? bounds.width * camera.zoom : 0, @@ -101,7 +101,7 @@ export const CommandPanel = ({ app }: { app: TldrawApp }) => { diff --git a/libs/components/editor-core/src/block-pendant/pendant-history-panel/PendantHistoryPanel.tsx b/libs/components/editor-core/src/block-pendant/pendant-history-panel/PendantHistoryPanel.tsx index ade7ced37d..3efc36721f 100644 --- a/libs/components/editor-core/src/block-pendant/pendant-history-panel/PendantHistoryPanel.tsx +++ b/libs/components/editor-core/src/block-pendant/pendant-history-panel/PendantHistoryPanel.tsx @@ -91,7 +91,7 @@ export const PendantHistoryPanel = ({ return ( { + popperHandlerRef={ref => { popoverHandlerRef.current[item.id] = ref; }} placement="bottom-start" diff --git a/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx b/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx index 09ad317777..63d01064d9 100644 --- a/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx +++ b/libs/components/editor-core/src/block-pendant/pendant-popover/PendantPopover.tsx @@ -17,7 +17,7 @@ export const PendantPopover = ( const popoverHandlerRef = useRef(); return ( { return ( { + popperHandlerRef={ref => { popoverHandlerRef.current[id] = ref; }} container={blockRenderContainerRef.current} @@ -107,7 +107,7 @@ export const PendantRender = ({ block }: { block: AsyncBlock }) => { iconStyle={{ marginTop: 4 }} trigger="click" // trigger={isKanbanView ? 'hover' : 'click'} - container={blockRenderContainerRef.current} + // container={blockRenderContainerRef.current} /> diff --git a/libs/components/ui/src/popover/Popover.tsx b/libs/components/ui/src/popover/Popover.tsx index d03a65f322..c165b45197 100644 --- a/libs/components/ui/src/popover/Popover.tsx +++ b/libs/components/ui/src/popover/Popover.tsx @@ -1,6 +1,6 @@ import type { MuiPopperPlacementType as PopperPlacementType } from '../mui'; -import React, { forwardRef, type PropsWithChildren } from 'react'; -import { type PopperHandler, Popper } from '../popper'; +import React, { type PropsWithChildren } from 'react'; +import { Popper } from '../popper'; import { PopoverContainer } from './Container'; import type { PopoverProps, PopoverDirection } from './interface'; @@ -25,15 +25,11 @@ export const placementToContainerDirection: Record< 'auto-end': 'none', }; -export const Popover = forwardRef< - PopperHandler, - PropsWithChildren ->((props, ref) => { +export const Popover = (props: PropsWithChildren) => { const { popoverDirection, placement, content, children, style } = props; return ( ); -}); +}; diff --git a/libs/components/ui/src/popper/Popper.tsx b/libs/components/ui/src/popper/Popper.tsx index f74cf89980..12a6211015 100644 --- a/libs/components/ui/src/popper/Popper.tsx +++ b/libs/components/ui/src/popper/Popper.tsx @@ -1,184 +1,182 @@ import React, { - forwardRef, + CSSProperties, useEffect, useImperativeHandle, useMemo, useRef, useState, } from 'react'; -import { - MuiPopper, - MuiClickAwayListener as ClickAwayListener, - MuiGrow as Grow, -} from '../mui'; +/* eslint-disable no-restricted-imports */ +import PopperUnstyled from '@mui/base/PopperUnstyled'; +/* eslint-disable no-restricted-imports */ +import ClickAwayListener from '@mui/base/ClickAwayListener'; +/* eslint-disable no-restricted-imports */ +import Grow from '@mui/material/Grow'; + import { styled } from '../styled'; -import { PopperProps, PopperHandler, VirtualElement } from './interface'; +import { PopperProps, VirtualElement } from './interface'; import { useTheme } from '../theme'; import { PopperArrow } from './PopoverArrow'; -export const Popper = forwardRef( - ( - { - children, - content, - anchor: propsAnchor, - placement = 'top-start', - defaultVisible = false, - container, - keepMounted = false, - visible: propsVisible, - trigger = 'hover', - pointerEnterDelay = 100, - pointerLeaveDelay = 100, - onVisibleChange, - popoverStyle, - popoverClassName, - anchorStyle, - anchorClassName, - zIndex, - offset = [0, 5], - showArrow = false, - }, - ref - ) => { - const [anchorEl, setAnchorEl] = useState(null); - const [visible, setVisible] = useState(defaultVisible); - const [arrowRef, setArrowRef] = useState(null); +export const Popper = ({ + children, + content, + anchorEl: propsAnchorEl, + placement = 'top-start', + defaultVisible = false, + visible: propsVisible, + trigger = 'hover', + pointerEnterDelay = 100, + pointerLeaveDelay = 100, + onVisibleChange, + popoverStyle, + popoverClassName, + anchorStyle, + anchorClassName, + zIndex, + offset = [0, 5], + showArrow = false, + popperHandlerRef, + ...popperProps +}: PopperProps) => { + const [anchorEl, setAnchorEl] = useState(null); + const [visible, setVisible] = useState(defaultVisible); + const [arrowRef, setArrowRef] = useState(null); + const popperRef = useRef(); + const pointerLeaveTimer = useRef(); + const pointerEnterTimer = useRef(); - const pointerLeaveTimer = useRef(); - const pointerEnterTimer = useRef(); - - const visibleControlledByParent = typeof propsVisible !== 'undefined'; - const isAnchorCustom = typeof propsAnchor !== 'undefined'; - - const hasHoverTrigger = useMemo(() => { - return ( - trigger === 'hover' || - (Array.isArray(trigger) && trigger.includes('hover')) - ); - }, [trigger]); - - const hasClickTrigger = useMemo(() => { - return ( - trigger === 'click' || - (Array.isArray(trigger) && trigger.includes('click')) - ); - }, [trigger]); - - const theme = useTheme(); - - const onPointerEnterHandler = () => { - if (!hasHoverTrigger || visibleControlledByParent) { - return; - } - window.clearTimeout(pointerLeaveTimer.current); - - pointerEnterTimer.current = window.setTimeout(() => { - setVisible(true); - }, pointerEnterDelay); - }; - - const onPointerLeaveHandler = () => { - if (!hasHoverTrigger || visibleControlledByParent) { - return; - } - window.clearTimeout(pointerEnterTimer.current); - pointerLeaveTimer.current = window.setTimeout(() => { - setVisible(false); - }, pointerLeaveDelay); - }; - - useEffect(() => { - onVisibleChange?.(visible); - }, [visible, onVisibleChange]); - - useImperativeHandle(ref, () => { - return { - setVisible: (visible: boolean) => { - !visibleControlledByParent && setVisible(visible); - }, - }; - }); + const visibleControlledByParent = typeof propsVisible !== 'undefined'; + const isAnchorCustom = typeof propsAnchorEl !== 'undefined'; + const hasHoverTrigger = useMemo(() => { return ( - { - setVisible(false); - }} - > - - {isAnchorCustom ? null : ( -
setAnchorEl(dom)} - onClick={() => { - if ( - !hasClickTrigger || - visibleControlledByParent - ) { - return; - } - setVisible(!visible); - }} - onPointerEnter={onPointerEnterHandler} - onPointerLeave={onPointerLeaveHandler} - style={anchorStyle} - className={anchorClassName} - > - {children} -
- )} - - {({ TransitionProps }) => ( - -
- {showArrow && ( - - )} - {content} -
-
- )} -
-
-
+ trigger === 'hover' || + (Array.isArray(trigger) && trigger.includes('hover')) ); - } -); + }, [trigger]); + + const hasClickTrigger = useMemo(() => { + return ( + trigger === 'click' || + (Array.isArray(trigger) && trigger.includes('click')) + ); + }, [trigger]); + + const onPointerEnterHandler = () => { + if (!hasHoverTrigger || visibleControlledByParent) { + return; + } + window.clearTimeout(pointerLeaveTimer.current); + + pointerEnterTimer.current = window.setTimeout(() => { + setVisible(true); + }, pointerEnterDelay); + }; + + const onPointerLeaveHandler = () => { + if (!hasHoverTrigger || visibleControlledByParent) { + return; + } + window.clearTimeout(pointerEnterTimer.current); + pointerLeaveTimer.current = window.setTimeout(() => { + setVisible(false); + }, pointerLeaveDelay); + }; + + useEffect(() => { + onVisibleChange?.(visible); + }, [visible, onVisibleChange]); + + useImperativeHandle(popperHandlerRef, () => { + return { + setVisible: (visible: boolean) => { + !visibleControlledByParent && setVisible(visible); + }, + }; + }); + + return ( + { + setVisible(false); + }} + > + + {isAnchorCustom ? null : ( +
setAnchorEl(dom)} + onClick={() => { + if (!hasClickTrigger || visibleControlledByParent) { + return; + } + setVisible(!visible); + }} + onPointerEnter={onPointerEnterHandler} + onPointerLeave={onPointerLeaveHandler} + style={anchorStyle} + className={anchorClassName} + > + {children} +
+ )} + + {({ TransitionProps }) => ( + +
+ {showArrow && ( + + )} + {content} +
+
+ )} +
+
+
+ ); +}; // The children of ClickAwayListener must be a DOM Node to judge whether the click is outside, use node.contains const Container = styled('div')({ display: 'contents', }); + +const BasicStyledPopper = styled(PopperUnstyled)<{ + zIndex?: CSSProperties['zIndex']; +}>(({ zIndex, theme }) => { + return { + zIndex: zIndex || theme.affine.zIndex.popover, + }; +}); diff --git a/libs/components/ui/src/popper/interface.ts b/libs/components/ui/src/popper/interface.ts index 9f52cf551f..4930de15f1 100644 --- a/libs/components/ui/src/popper/interface.ts +++ b/libs/components/ui/src/popper/interface.ts @@ -1,6 +1,9 @@ -import type { CSSProperties, ReactNode } from 'react'; -import type { MuiPopperPlacementType as PopperPlacementType } from '../mui'; - +import type { CSSProperties, ReactNode, Ref } from 'react'; +/* eslint-disable no-restricted-imports */ +import { + type PopperUnstyledProps, + type PopperPlacementType, +} from '@mui/base/PopperUnstyled'; export type VirtualElement = { getBoundingClientRect: () => ClientRect | DOMRect; contextElement?: Element; @@ -21,26 +24,12 @@ export type PopperProps = { // Popover trigger children?: ReactNode; - // Position of Popover - placement?: PopperPlacementType; - - // The popover will pop up based on the anchor position - // And if this parameter is passed, children will not be rendered - anchor?: VirtualElement | (() => VirtualElement); - // Whether the default is implicit defaultVisible?: boolean; // Used to manually control the visibility of the Popover visible?: boolean; - // A HTML element or function that returns one. The container will have the portal children appended to it. - // By default, it uses the body of the top-level document object, so it's simply document.body most of the time. - container?: HTMLElement; - - // Always keep the children in the DOM. This prop can be useful in SEO situation or when you want to maximize the responsiveness of the Popper - keepMounted?: boolean; - // TODO: support focus trigger?: 'hover' | 'click' | 'focus' | ('click' | 'hover' | 'focus')[]; @@ -66,9 +55,11 @@ export type PopperProps = { anchorClassName?: string; // Popover z-index - zIndex?: number; + zIndex?: CSSProperties['zIndex']; offset?: [number, number]; showArrow?: boolean; -}; + + popperHandlerRef?: Ref; +} & Omit; diff --git a/libs/components/ui/src/tooltip/Tooltip.tsx b/libs/components/ui/src/tooltip/Tooltip.tsx index 2c896e5c0d..ff0b47262c 100644 --- a/libs/components/ui/src/tooltip/Tooltip.tsx +++ b/libs/components/ui/src/tooltip/Tooltip.tsx @@ -1,5 +1,5 @@ -import { forwardRef, type PropsWithChildren, type CSSProperties } from 'react'; -import { type PopperHandler, type PopperProps, Popper } from '../popper'; +import { type PropsWithChildren, type CSSProperties } from 'react'; +import { type PopperProps, Popper } from '../popper'; import { PopoverContainer, placementToContainerDirection } from '../popover'; import type { TooltipProps } from './interface'; import { useTheme } from '../theme'; @@ -14,17 +14,15 @@ const useTooltipStyle = (): CSSProperties => { }; }; -export const Tooltip = forwardRef< - PopperHandler, - PropsWithChildren ->((props, ref) => { +export const Tooltip = ( + props: PropsWithChildren +) => { const { content, placement = 'top-start' } = props; const style = useTooltipStyle(); // If there is no content, hide forever const visibleProp = content ? {} : { visible: false }; return ( ); -}); +}; From 4944887d4a22237d34e1b8be1e8a63bf69525a9f Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Fri, 12 Aug 2022 18:51:56 +0800 Subject: [PATCH 5/6] fix: fix pendant popover obscured by screen --- .../editor-core/src/block-pendant/AddPendantPopover.tsx | 8 +++++++- .../src/block-pendant/pendant-modify-panel/types.ts | 1 + .../pendant-operation-panel/CreatePendantPanel.tsx | 6 ++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libs/components/editor-core/src/block-pendant/AddPendantPopover.tsx b/libs/components/editor-core/src/block-pendant/AddPendantPopover.tsx index 015f8a4120..ce5dc6cdc9 100644 --- a/libs/components/editor-core/src/block-pendant/AddPendantPopover.tsx +++ b/libs/components/editor-core/src/block-pendant/AddPendantPopover.tsx @@ -5,6 +5,7 @@ import { type PopoverProps, PopperHandler, Tag, + type PopperProps, } from '@toeverything/components/ui'; import { TagsIcon } from '@toeverything/components/icons'; @@ -26,9 +27,11 @@ export const AddPendantPopover = ({ ...popoverProps }: Props) => { const popoverHandlerRef = useRef(); + const popperRef = useRef(); return ( { + popperRef.current?.update?.(); + }} /> } placement="bottom-start" diff --git a/libs/components/editor-core/src/block-pendant/pendant-modify-panel/types.ts b/libs/components/editor-core/src/block-pendant/pendant-modify-panel/types.ts index a7ed9e0198..5afbb29ad5 100644 --- a/libs/components/editor-core/src/block-pendant/pendant-modify-panel/types.ts +++ b/libs/components/editor-core/src/block-pendant/pendant-modify-panel/types.ts @@ -11,6 +11,7 @@ export type ModifyPanelProps = { iconConfig?: PendantConfig; isStatusSelect?: boolean; property?: RecastMetaProperty; + onTypeChange?: (type: PendantTypes) => void; }; export type ModifyPanelContentProps = { diff --git a/libs/components/editor-core/src/block-pendant/pendant-operation-panel/CreatePendantPanel.tsx b/libs/components/editor-core/src/block-pendant/pendant-operation-panel/CreatePendantPanel.tsx index 42e36e063f..88fd5b039f 100644 --- a/libs/components/editor-core/src/block-pendant/pendant-operation-panel/CreatePendantPanel.tsx +++ b/libs/components/editor-core/src/block-pendant/pendant-operation-panel/CreatePendantPanel.tsx @@ -24,9 +24,11 @@ import { useOnCreateSure } from './hooks'; export const CreatePendantPanel = ({ block, onSure, + onTypeChange, }: { block: AsyncBlock; onSure?: () => void; + onTypeChange?: (option: PendantOptions) => void; }) => { const [selectedOption, setSelectedOption] = useState(); const [fieldName, setFieldName] = useState(''); @@ -37,6 +39,10 @@ export const CreatePendantPanel = ({ setFieldName(generateRandomFieldName(selectedOption.type)); }, [selectedOption]); + useEffect(() => { + onTypeChange?.(selectedOption); + }, [selectedOption, onTypeChange]); + return ( Add Field From c9a5fe3d25328fd669ff6a97ffb4431630920e9a Mon Sep 17 00:00:00 2001 From: QiShaoXuan Date: Fri, 12 Aug 2022 19:01:40 +0800 Subject: [PATCH 6/6] fix: Property zIndex does not exist on type CSSProperties --- libs/components/ui/src/popper/Popper.tsx | 4 +--- libs/components/ui/src/popper/interface.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libs/components/ui/src/popper/Popper.tsx b/libs/components/ui/src/popper/Popper.tsx index 12a6211015..4cf9f6a78b 100644 --- a/libs/components/ui/src/popper/Popper.tsx +++ b/libs/components/ui/src/popper/Popper.tsx @@ -1,5 +1,4 @@ import React, { - CSSProperties, useEffect, useImperativeHandle, useMemo, @@ -16,7 +15,6 @@ import Grow from '@mui/material/Grow'; import { styled } from '../styled'; import { PopperProps, VirtualElement } from './interface'; -import { useTheme } from '../theme'; import { PopperArrow } from './PopoverArrow'; export const Popper = ({ children, @@ -174,7 +172,7 @@ const Container = styled('div')({ }); const BasicStyledPopper = styled(PopperUnstyled)<{ - zIndex?: CSSProperties['zIndex']; + zIndex?: number; }>(({ zIndex, theme }) => { return { zIndex: zIndex || theme.affine.zIndex.popover, diff --git a/libs/components/ui/src/popper/interface.ts b/libs/components/ui/src/popper/interface.ts index 4930de15f1..d60fac29f7 100644 --- a/libs/components/ui/src/popper/interface.ts +++ b/libs/components/ui/src/popper/interface.ts @@ -55,7 +55,7 @@ export type PopperProps = { anchorClassName?: string; // Popover z-index - zIndex?: CSSProperties['zIndex']; + zIndex?: number; offset?: [number, number];