diff --git a/apps/web/src/components/pure/workspace-slider-bar/favorite/empty-item.tsx b/apps/web/src/components/pure/workspace-slider-bar/favorite/empty-item.tsx new file mode 100644 index 0000000000..eccc4f49e6 --- /dev/null +++ b/apps/web/src/components/pure/workspace-slider-bar/favorite/empty-item.tsx @@ -0,0 +1,10 @@ +import { useTranslation } from '@affine/i18n'; + +import { StyledCollapseItem } from '../shared-styles'; + +export const EmptyItem = () => { + const { t } = useTranslation(); + return {t('No item')}; +}; + +export default EmptyItem; diff --git a/apps/web/src/components/pure/workspace-slider-bar/favorite/favorite-list.tsx b/apps/web/src/components/pure/workspace-slider-bar/favorite/favorite-list.tsx index c9fbeab7b2..7236ee254c 100644 --- a/apps/web/src/components/pure/workspace-slider-bar/favorite/favorite-list.tsx +++ b/apps/web/src/components/pure/workspace-slider-bar/favorite/favorite-list.tsx @@ -1,5 +1,4 @@ import { MuiCollapse } from '@affine/component'; -import { useTranslation } from '@affine/i18n'; import { EdgelessIcon, PageIcon } from '@blocksuite/icons'; import { useAtomValue } from 'jotai'; import { useRouter } from 'next/router'; @@ -8,13 +7,13 @@ import { useMemo } from 'react'; import { workspacePreferredModeAtom } from '../../../../atoms'; import type { FavoriteListProps } from '../index'; import { StyledCollapseItem } from '../shared-styles'; +import EmptyItem from './empty-item'; export const FavoriteList = ({ pageMeta, openPage, showList, }: FavoriteListProps) => { const router = useRouter(); - const { t } = useTranslation(); const record = useAtomValue(workspacePreferredModeAtom); const favoriteList = useMemo( @@ -60,9 +59,7 @@ export const FavoriteList = ({ ); })} - {favoriteList.length === 0 && ( - {t('No item')} - )} + {favoriteList.length === 0 && } ); }; diff --git a/apps/web/src/components/pure/workspace-slider-bar/pivot/OperationButton.tsx b/apps/web/src/components/pure/workspace-slider-bar/pivot/OperationButton.tsx new file mode 100644 index 0000000000..05b175177a --- /dev/null +++ b/apps/web/src/components/pure/workspace-slider-bar/pivot/OperationButton.tsx @@ -0,0 +1,110 @@ +import { + IconButton, + MenuItem, + MuiClickAwayListener, + PureMenu, +} from '@affine/component'; +import { useTranslation } from '@affine/i18n'; +import { + CopyIcon, + DeleteTemporarilyIcon, + MoreVerticalIcon, + MoveToIcon, + PenIcon, + PlusIcon, +} from '@blocksuite/icons'; +import { useRouter } from 'next/router'; +import { useCallback, useState } from 'react'; + +import { toast } from '../../../../utils'; + +export const OperationButton = ({ + onAdd, + onDelete, +}: { + onAdd: () => void; + onDelete: () => void; +}) => { + const { t } = useTranslation(); + const router = useRouter(); + + const [anchorEl, setAnchorEl] = useState(null); + + const [open, setOpen] = useState(false); + const copyUrl = useCallback(() => { + const workspaceId = router.query.workspaceId; + navigator.clipboard.writeText(window.location.href); + toast(t('Copied link to clipboard')); + }, [router.query.workspaceId, t]); + + return ( + { + setOpen(false); + }} + > +
{ + e.stopPropagation(); + }} + onMouseLeave={() => { + setOpen(false); + }} + > + setAnchorEl(ref)} + size="small" + className="operation-button" + onClick={event => { + event.stopPropagation(); + setOpen(!open); + }} + > + + + + } + onClick={() => { + onAdd(); + setOpen(false); + }} + > + {t('Add a subpage inside')} + + } disabled={true}> + {t('Move to')} + + } disabled={true}> + {t('Rename')} + + } + onClick={() => { + onDelete(); + setOpen(false); + }} + > + {t('Move to Trash')} + + } + disabled={true} + // onClick={() => { + // const workspaceId = router.query.workspaceId; + // navigator.clipboard.writeText(window.location.href); + // toast(t('Copied link to clipboard')); + // }} + > + {t('Copy Link')} + + +
+
+ ); +}; diff --git a/apps/web/src/components/pure/workspace-slider-bar/pivot/Pivot.tsx b/apps/web/src/components/pure/workspace-slider-bar/pivot/Pivot.tsx index bfdb121b85..d40b92f5a5 100644 --- a/apps/web/src/components/pure/workspace-slider-bar/pivot/Pivot.tsx +++ b/apps/web/src/components/pure/workspace-slider-bar/pivot/Pivot.tsx @@ -1,7 +1,7 @@ import { MuiCollapse, TreeView } from '@affine/component'; import { DebugLogger } from '@affine/debug'; import { useTranslation } from '@affine/i18n'; -import { ArrowDownSmallIcon, FolderIcon } from '@blocksuite/icons'; +import { ArrowDownSmallIcon, PivotsIcon } from '@blocksuite/icons'; import type { PageMeta } from '@blocksuite/store'; import { nanoid } from '@blocksuite/store'; import { useCallback, useMemo, useState } from 'react'; @@ -9,6 +9,7 @@ import { useCallback, useMemo, useState } from 'react'; import { useBlockSuiteWorkspaceHelper } from '../../../../hooks/use-blocksuite-workspace-helper'; import { usePageMetaHelper } from '../../../../hooks/use-page-meta'; import type { RemWorkspace } from '../../../../shared'; +import EmptyItem from '../favorite/empty-item'; import { StyledCollapseButton, StyledListItem } from '../shared-styles'; import type { TreeNode } from './types'; import { flattenToTree } from './utils'; @@ -197,6 +198,11 @@ export const Pivot = ({ const [showPivot, setShowPivot] = useState(true); + const isPivotEmpty = useMemo( + () => allMetas.filter(meta => !meta.trash).length === 0, + [allMetas] + ); + return ( <> @@ -208,7 +214,7 @@ export const Pivot = ({ > - + {t('Pivots')} @@ -220,11 +226,15 @@ export const Pivot = ({ overflowY: 'auto', }} > - + {isPivotEmpty ? ( + + ) : ( + + )} ); diff --git a/apps/web/src/components/pure/workspace-slider-bar/pivot/TreeNodeRender.tsx b/apps/web/src/components/pure/workspace-slider-bar/pivot/TreeNodeRender.tsx index b33fd74933..68a1271241 100644 --- a/apps/web/src/components/pure/workspace-slider-bar/pivot/TreeNodeRender.tsx +++ b/apps/web/src/components/pure/workspace-slider-bar/pivot/TreeNodeRender.tsx @@ -1,23 +1,16 @@ -import { IconButton } from '@affine/component'; -import { - ArrowDownSmallIcon, - EdgelessIcon, - // DeleteTemporarilyIcon, - // PlusIcon, - MoreVerticalIcon, - PageIcon, -} from '@blocksuite/icons'; +import { ArrowDownSmallIcon, EdgelessIcon, PageIcon } from '@blocksuite/icons'; import type { PageMeta } from '@blocksuite/store'; import { useAtomValue } from 'jotai'; import { useRouter } from 'next/router'; import { workspacePreferredModeAtom } from '../../../../atoms'; import { StyledCollapseButton, StyledCollapseItem } from '../shared-styles'; +import { OperationButton } from './OperationButton'; import type { TreeNode } from './types'; export const TreeNodeRender: TreeNode['render'] = ( node, - { onAdd, onDelete, collapsed, setCollapsed }, + { isOver, onAdd, onDelete, collapsed, setCollapsed }, extendProps ) => { const { openPage, pageMeta } = extendProps as { @@ -37,6 +30,7 @@ export const TreeNodeRender: TreeNode['render'] = ( } openPage(node.id); }} + isOver={isOver} active={active} > {record[pageMeta.id] === 'edgeless' ? : } {node.title || 'Untitled'} - { - e.stopPropagation(); - }} - > - - - - {/* {*/} - {/* e.stopPropagation();*/} - {/* onAdd();*/} - {/* }}*/} - {/* size="small"*/} - {/* className="operation-button"*/} - {/*>*/} - {/* */} - {/**/} - {/* {*/} - {/* e.stopPropagation();*/} - - {/* onDelete();*/} - {/* }}*/} - {/* size="small"*/} - {/* className="operation-button"*/} - {/*>*/} - {/* */} - {/**/} + ); }; diff --git a/apps/web/src/components/pure/workspace-slider-bar/shared-styles.ts b/apps/web/src/components/pure/workspace-slider-bar/shared-styles.ts index 6600d9f17b..4cd939700d 100644 --- a/apps/web/src/components/pure/workspace-slider-bar/shared-styles.ts +++ b/apps/web/src/components/pure/workspace-slider-bar/shared-styles.ts @@ -1,4 +1,4 @@ -import { displayFlex, styled, textEllipsis } from '@affine/component'; +import { alpha, displayFlex, styled, textEllipsis } from '@affine/component'; export const StyledListItem = styled('div')<{ active?: boolean; @@ -53,10 +53,11 @@ export const StyledCollapseButton = styled('button')<{ }; }); -export const StyledCollapseItem = styled('button')<{ +export const StyledCollapseItem = styled('div')<{ disable?: boolean; active?: boolean; -}>(({ disable = false, active = false, theme }) => { + isOver?: boolean; +}>(({ disable = false, active = false, theme, isOver }) => { return { width: '100%', height: '32px', @@ -70,6 +71,7 @@ export const StyledCollapseItem = styled('button')<{ ? theme.colors.primaryColor : theme.colors.textColor, cursor: disable ? 'not-allowed' : 'pointer', + background: isOver ? alpha(theme.colors.primaryColor, 0.06) : '', span: { flexGrow: '1', @@ -83,7 +85,7 @@ export const StyledCollapseItem = styled('button')<{ color: active ? theme.colors.primaryColor : theme.colors.iconColor, }, '.operation-button': { - display: 'none', + visibility: 'hidden', }, ':hover': disable @@ -91,7 +93,7 @@ export const StyledCollapseItem = styled('button')<{ : { backgroundColor: theme.colors.hoverBackground, '.operation-button': { - display: 'flex', + visibility: 'visible', }, }, }; diff --git a/apps/web/src/components/pure/workspace-slider-bar/style.ts b/apps/web/src/components/pure/workspace-slider-bar/style.ts index 3b0226a946..0089610dce 100644 --- a/apps/web/src/components/pure/workspace-slider-bar/style.ts +++ b/apps/web/src/components/pure/workspace-slider-bar/style.ts @@ -16,6 +16,7 @@ export const StyledSliderBar = styled('div')<{ show: boolean }>( flexShrink: 0, display: 'flex', flexDirection: 'column', + overflow: 'hidden', }; } ); diff --git a/packages/component/src/styles/styled.tsx b/packages/component/src/styles/styled.tsx index 9cdcf0371b..94993418d7 100644 --- a/packages/component/src/styles/styled.tsx +++ b/packages/component/src/styles/styled.tsx @@ -1,5 +1,6 @@ import { CssBaseline } from '@mui/material'; import { + alpha, createTheme as createMuiTheme, css, keyframes, @@ -11,7 +12,7 @@ import { useMemo } from 'react'; import type { AffineTheme } from './types'; -export { css, keyframes, styled }; +export { alpha, css, keyframes, styled }; export const ThemeProvider = ({ theme, diff --git a/packages/component/src/ui/menu/MenuItem.tsx b/packages/component/src/ui/menu/MenuItem.tsx index db4b835a99..b23bf60481 100644 --- a/packages/component/src/ui/menu/MenuItem.tsx +++ b/packages/component/src/ui/menu/MenuItem.tsx @@ -6,12 +6,13 @@ export type IconMenuProps = PropsWithChildren<{ isDir?: boolean; icon?: ReactElement; iconSize?: [number, number]; + disabled?: boolean; }> & HTMLAttributes; export const MenuItem = forwardRef( ({ isDir = false, icon, iconSize, children, ...props }, ref) => { - const [iconWidth, iconHeight] = iconSize || [16, 16]; + const [iconWidth, iconHeight] = iconSize || [20, 20]; return ( {icon && @@ -19,7 +20,7 @@ export const MenuItem = forwardRef( width: iconWidth, height: iconHeight, style: { - marginRight: 14, + marginRight: 12, ...icon.props?.style, }, })} diff --git a/packages/component/src/ui/menu/PureMenu.tsx b/packages/component/src/ui/menu/PureMenu.tsx new file mode 100644 index 0000000000..1f21aa932a --- /dev/null +++ b/packages/component/src/ui/menu/PureMenu.tsx @@ -0,0 +1,20 @@ +import type { CSSProperties } from 'react'; + +import type { PurePopperProps } from '../popper'; +import { PurePopper } from '../popper'; +import { StyledMenuWrapper } from './styles'; + +export const PureMenu = ({ + children, + placement, + width, + ...otherProps +}: PurePopperProps & { width?: CSSProperties['width'] }) => { + return ( + + + {children} + + + ); +}; diff --git a/packages/component/src/ui/menu/index.ts b/packages/component/src/ui/menu/index.ts index f6fcdd4d68..ecbe2eee6c 100644 --- a/packages/component/src/ui/menu/index.ts +++ b/packages/component/src/ui/menu/index.ts @@ -1,3 +1,4 @@ export * from './Menu'; // export { StyledMenuItem as MenuItem } from './styles'; export * from './MenuItem'; +export * from './PureMenu'; diff --git a/packages/component/src/ui/menu/styles.ts b/packages/component/src/ui/menu/styles.ts index 7041264c02..48e6336e0f 100644 --- a/packages/component/src/ui/menu/styles.ts +++ b/packages/component/src/ui/menu/styles.ts @@ -28,7 +28,8 @@ export const StyledArrow = styled(ArrowRightSmallIcon)({ export const StyledMenuItem = styled('button')<{ isDir?: boolean; -}>(({ theme, isDir = false }) => { + disabled?: boolean; +}>(({ theme, isDir = false, disabled = false }) => { return { width: '100%', borderRadius: '5px', @@ -39,10 +40,25 @@ export const StyledMenuItem = styled('button')<{ cursor: isDir ? 'pointer' : '', position: 'relative', backgroundColor: 'transparent', - color: theme.colors.textColor, - ':hover': { - color: theme.colors.primaryColor, - backgroundColor: theme.colors.hoverBackground, + color: disabled ? theme.colors.disableColor : theme.colors.textColor, + svg: { + color: disabled ? theme.colors.disableColor : theme.colors.iconColor, }, + ...(disabled + ? { + cursor: 'not-allowed', + pointerEvents: 'none', + } + : {}), + + ':hover': disabled + ? {} + : { + color: theme.colors.primaryColor, + backgroundColor: theme.colors.hoverBackground, + svg: { + color: theme.colors.primaryColor, + }, + }, }; }); diff --git a/packages/component/src/ui/popper/PopoverArrow.tsx b/packages/component/src/ui/popper/PopoverArrow.tsx index 847af75ae9..7b81574520 100644 --- a/packages/component/src/ui/popper/PopoverArrow.tsx +++ b/packages/component/src/ui/popper/PopoverArrow.tsx @@ -11,7 +11,7 @@ export const PopperArrow = forwardRef( ); const getArrowStyle = ( - placement: PopperArrowProps['placement'], + placement: PopperArrowProps['placement'] = 'bottom', backgroundColor: CSSProperties['backgroundColor'] ) => { if (placement.indexOf('bottom') === 0) { @@ -72,7 +72,7 @@ const getArrowStyle = ( }; const StyledArrow = styled('span')<{ - placement: PopperArrowProps['placement']; + placement?: PopperArrowProps['placement']; }>(({ placement, theme }) => { return { position: 'absolute', diff --git a/packages/component/src/ui/popper/Popper.tsx b/packages/component/src/ui/popper/Popper.tsx index e934778d49..d1aa6bd6e8 100644 --- a/packages/component/src/ui/popper/Popper.tsx +++ b/packages/component/src/ui/popper/Popper.tsx @@ -1,6 +1,7 @@ import ClickAwayListener from '@mui/base/ClickAwayListener'; import PopperUnstyled from '@mui/base/PopperUnstyled'; import Grow from '@mui/material/Grow'; +import type { CSSProperties, PointerEvent } from 'react'; import { cloneElement, useEffect, @@ -33,6 +34,8 @@ export const Popper = ({ popperHandlerRef, onClick, onClickAway, + onPointerEnter, + onPointerLeave, ...popperProps }: PopperProps) => { const [anchorEl, setAnchorEl] = useState(); @@ -58,7 +61,8 @@ export const Popper = ({ ); }, [trigger]); - const onPointerEnterHandler = () => { + const onPointerEnterHandler = (e: PointerEvent) => { + onPointerEnter?.(e); if (!hasHoverTrigger || visibleControlledByParent) { return; } @@ -69,7 +73,9 @@ export const Popper = ({ }, pointerEnterDelay); }; - const onPointerLeaveHandler = () => { + const onPointerLeaveHandler = (e: PointerEvent) => { + onPointerLeave?.(e); + if (!hasHoverTrigger || visibleControlledByParent) { return; } @@ -151,7 +157,7 @@ export const Popper = ({ onPointerLeave={onPointerLeaveHandler} style={popoverStyle} className={popoverClassName} - onClick={e => { + onClick={() => { if (hasClickTrigger && !visibleControlledByParent) { setVisible(false); } @@ -178,11 +184,11 @@ const Container = styled('div')({ display: 'contents', }); -const BasicStyledPopper = styled(PopperUnstyled, { +export const BasicStyledPopper = styled(PopperUnstyled, { shouldForwardProp: (propName: string) => !['zIndex'].some(name => name === propName), })<{ - zIndex?: number; + zIndex?: CSSProperties['zIndex']; }>(({ zIndex, theme }) => { return { zIndex: zIndex ?? theme.zIndex.popover, diff --git a/packages/component/src/ui/popper/PurePopper.tsx b/packages/component/src/ui/popper/PurePopper.tsx new file mode 100644 index 0000000000..38be8d0077 --- /dev/null +++ b/packages/component/src/ui/popper/PurePopper.tsx @@ -0,0 +1,67 @@ +import type { PopperUnstyledProps } from '@mui/base/PopperUnstyled'; +import Grow from '@mui/material/Grow'; +import type { CSSProperties, PropsWithChildren } from 'react'; +import { useState } from 'react'; + +import { PopperArrow } from './PopoverArrow'; +import { BasicStyledPopper } from './Popper'; +import { PopperWrapper } from './styles'; + +export type PurePopperProps = { + zIndex?: CSSProperties['zIndex']; + + offset?: [number, number]; + + showArrow?: boolean; +} & PopperUnstyledProps & + PropsWithChildren; + +export const PurePopper = (props: PurePopperProps) => { + const { + children, + zIndex, + offset, + showArrow = false, + modifiers = [], + placement, + ...otherProps + } = props; + const [arrowRef, setArrowRef] = useState(); + + // @ts-ignore + return ( + + {({ TransitionProps }) => ( + + + {showArrow && ( + + )} + {children} + + + )} + + ); +}; diff --git a/packages/component/src/ui/popper/index.ts b/packages/component/src/ui/popper/index.ts index 88fac67073..908fb1627e 100644 --- a/packages/component/src/ui/popper/index.ts +++ b/packages/component/src/ui/popper/index.ts @@ -1,2 +1,3 @@ export * from './interface'; export * from './Popper'; +export * from './PurePopper'; diff --git a/packages/component/src/ui/popper/interface.ts b/packages/component/src/ui/popper/interface.ts index 4de506ca60..7fb200a4ca 100644 --- a/packages/component/src/ui/popper/interface.ts +++ b/packages/component/src/ui/popper/interface.ts @@ -13,7 +13,7 @@ export type PopperHandler = { }; export type PopperArrowProps = { - placement: PopperPlacementType; + placement?: PopperPlacementType; }; export type PopperProps = { diff --git a/packages/component/src/ui/popper/styles.ts b/packages/component/src/ui/popper/styles.ts new file mode 100644 index 0000000000..58fd4c01f9 --- /dev/null +++ b/packages/component/src/ui/popper/styles.ts @@ -0,0 +1,7 @@ +import { styled } from '../../styles'; + +export const PopperWrapper = styled('div')(() => { + return { + position: 'relative', + }; +}); diff --git a/packages/component/src/ui/tree-view/TreeNode.tsx b/packages/component/src/ui/tree-view/TreeNode.tsx index c9c349dfd3..1355acf582 100644 --- a/packages/component/src/ui/tree-view/TreeNode.tsx +++ b/packages/component/src/ui/tree-view/TreeNode.tsx @@ -1,13 +1,18 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useDrag, useDrop } from 'react-dnd'; import { StyledCollapse, StyledNodeLine, StyledTreeNodeContainer, - StyledTreeNodeItem, + StyledTreeNodeWrapper, } from './styles'; -import type { Node, NodeLIneProps, TreeNodeProps } from './types'; +import type { + Node, + NodeLIneProps, + TreeNodeItemProps, + TreeNodeProps, +} from './types'; const NodeLine = ({ node, @@ -39,30 +44,21 @@ const NodeLine = ({ return ; }; - -export const TreeNode = ({ +const TreeNodeItem = ({ node, - index, - allDrop = true, + allowDrop, + collapsed, + setCollapsed, ...otherProps -}: TreeNodeProps) => { - const { onAdd, onDelete, onDrop, indent } = otherProps; - const [collapsed, setCollapsed] = useState(false); - - const [{ isDragging }, drag] = useDrag(() => ({ - type: 'node', - item: node, - collect: monitor => ({ - isDragging: monitor.isDragging(), - }), - })); +}: TreeNodeItemProps) => { + const { onAdd, onDelete, onDrop } = otherProps; const [{ canDrop, isOver }, drop] = useDrop( () => ({ accept: 'node', drop: (item: Node, monitor) => { const didDrop = monitor.didDrop(); - if (didDrop || item.id === node.id || !allDrop) { + if (didDrop || item.id === node.id || !allowDrop) { return; } onDrop?.(item, node, { @@ -73,42 +69,75 @@ export const TreeNode = ({ }, collect: monitor => ({ isOver: monitor.isOver(), - canDrop: monitor.canDrop(), + canDrop: monitor.canDrop() && allowDrop, }), }), - [onDrop, allDrop] + [onDrop, allowDrop] ); + useEffect(() => { + if (isOver && canDrop) { + setCollapsed(false); + } + }, [isOver, canDrop]); + + return ( +
+ {node.render?.(node, { + isOver: !!(isOver && canDrop), + onAdd: () => onAdd?.(node), + onDelete: () => onDelete?.(node), + collapsed, + setCollapsed, + })} +
+ ); +}; + +export const TreeNode = ({ + node, + index, + allowDrop = true, + ...otherProps +}: TreeNodeProps) => { + const { indent } = otherProps; + const [collapsed, setCollapsed] = useState(false); + + const [{ isDragging }, drag] = useDrag(() => ({ + type: 'node', + item: node, + collect: monitor => ({ + isDragging: monitor.isDragging(), + }), + })); + return ( - + {index === 0 && ( )} - {node.render?.(node, { - onAdd: () => onAdd?.(node), - onDelete: () => onDelete?.(node), - collapsed, - setCollapsed, - })} + {(!node.children?.length || collapsed) && ( )} - - + {node.children && node.children.map((childNode, index) => ( @@ -116,7 +145,7 @@ export const TreeNode = ({ key={childNode.id} node={childNode} index={index} - allDrop={isDragging ? false : allDrop} + allowDrop={isDragging ? false : allowDrop} {...otherProps} /> ))} diff --git a/packages/component/src/ui/tree-view/styles.ts b/packages/component/src/ui/tree-view/styles.ts index 1c8502aca5..5255543a95 100644 --- a/packages/component/src/ui/tree-view/styles.ts +++ b/packages/component/src/ui/tree-view/styles.ts @@ -1,7 +1,7 @@ import MuiCollapse from '@mui/material/Collapse'; import type { CSSProperties } from 'react'; -import { styled } from '../../styles'; +import { alpha, styled } from '../../styles'; export const StyledCollapse = styled(MuiCollapse)<{ indent?: CSSProperties['paddingLeft']; @@ -10,12 +10,8 @@ export const StyledCollapse = styled(MuiCollapse)<{ paddingLeft: indent, }; }); -export const StyledTreeNodeItem = styled('div')<{ - isOver?: boolean; - canDrop?: boolean; -}>(({ isOver, canDrop, theme }) => { +export const StyledTreeNodeWrapper = styled('div')(() => { return { - background: isOver && canDrop ? theme.colors.hoverBackground : '', position: 'relative', }; }); @@ -23,6 +19,7 @@ export const StyledTreeNodeContainer = styled('div')<{ isDragging: boolean }>( ({ isDragging, theme }) => { return { background: isDragging ? theme.colors.hoverBackground : '', + // opacity: isDragging ? 0.4 : 1, }; } ); @@ -32,11 +29,14 @@ export const StyledNodeLine = styled('div')<{ show: boolean; isTop?: boolean }>( return { position: 'absolute', left: '0', - ...(isTop ? { top: '0' } : { bottom: '0' }), + ...(isTop ? { top: '-1px' } : { bottom: '-1px' }), width: '100%', - paddingTop: '3px', - borderBottom: '3px solid', + paddingTop: '2x', + borderTop: '2px solid', borderColor: show ? theme.colors.primaryColor : 'transparent', + boxShadow: show + ? `0px 0px 8px ${alpha(theme.colors.primaryColor, 0.35)}` + : 'none', zIndex: 1, }; } diff --git a/packages/component/src/ui/tree-view/types.ts b/packages/component/src/ui/tree-view/types.ts index 80079ccec9..494b481db3 100644 --- a/packages/component/src/ui/tree-view/types.ts +++ b/packages/component/src/ui/tree-view/types.ts @@ -6,6 +6,7 @@ export type Node = { render?: ( node: Node, eventsAndStatus: { + isOver: boolean; onAdd: () => void; onDelete: () => void; collapsed: boolean; @@ -33,9 +34,14 @@ type CommonProps = { export type TreeNodeProps = { node: Node; index: number; - allDrop?: boolean; + allowDrop?: boolean; } & CommonProps; +export type TreeNodeItemProps = { + collapsed: boolean; + setCollapsed: (collapsed: boolean) => void; +} & TreeNodeProps; + export type TreeViewProps = { data: Node[]; } & CommonProps; diff --git a/packages/i18n/src/resources/en.json b/packages/i18n/src/resources/en.json index 7361f4d012..c904129e23 100644 --- a/packages/i18n/src/resources/en.json +++ b/packages/i18n/src/resources/en.json @@ -194,5 +194,8 @@ "Please make sure you are online": "Please make sure you are online", "Workspace Owner": "Workspace Owner", "Members": "Members", - "Pivots": "Pivots" + "Pivots": "Pivots", + "Add a subpage inside": "Add a subpage inside", + "Rename": "Rename", + "Move to": "Move to" }