From d3635208f6923d2c311f10201a79ce83a7d7bddf Mon Sep 17 00:00:00 2001 From: JimmFly Date: Sat, 16 Sep 2023 08:55:56 +0800 Subject: [PATCH] refactor: delete page style (#4347) Co-authored-by: Alex Yang --- .../pure/trash-button-group/index.tsx | 164 +++++++++++++----- .../pure/trash-button-group/styles.css.ts | 44 ++++- apps/core/src/layouts/workspace-layout.tsx | 9 +- .../sidebar-header/sidebar-switch.css.ts | 1 + .../src/components/workspace/index.css.ts | 22 +++ .../src/components/workspace/index.tsx | 14 +- packages/hooks/src/use-is-tiny-screen.ts | 2 +- plugins/outline/src/app.tsx | 5 + 8 files changed, 201 insertions(+), 60 deletions(-) diff --git a/apps/core/src/components/pure/trash-button-group/index.tsx b/apps/core/src/components/pure/trash-button-group/index.tsx index df679644f7..b86b1ccb0b 100644 --- a/apps/core/src/components/pure/trash-button-group/index.tsx +++ b/apps/core/src/components/pure/trash-button-group/index.tsx @@ -1,18 +1,21 @@ import { WorkspaceSubPath } from '@affine/env/workspace'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; import { assertExists } from '@blocksuite/global/utils'; +import { DeleteIcon, ResetIcon } from '@blocksuite/icons'; import { Button } from '@toeverything/components/button'; import { ConfirmModal } from '@toeverything/components/modal'; +import { Tooltip } from '@toeverything/components/tooltip'; import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta'; import { currentPageIdAtom } from '@toeverything/infra/atom'; import { useAtomValue } from 'jotai'; -import { useCallback, useState } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import { useAppSetting } from '../../../atoms/settings'; import { useBlockSuiteMetaHelper } from '../../../hooks/affine/use-block-suite-meta-helper'; import { useCurrentWorkspace } from '../../../hooks/current/use-current-workspace'; import { useNavigateHelper } from '../../../hooks/use-navigate-helper'; import { toast } from '../../../utils'; -import { buttonContainer, group } from './styles.css'; +import * as styles from './styles.css'; export const TrashButtonGroup = () => { // fixme(himself65): remove these hooks ASAP @@ -26,57 +29,124 @@ export const TrashButtonGroup = () => { ); assertExists(pageMeta); const t = useAFFiNEI18N(); + const [appSettings] = useAppSetting(); const { jumpToSubPath } = useNavigateHelper(); const { restoreFromTrash } = useBlockSuiteMetaHelper(blockSuiteWorkspace); - + const restoreRef = useRef(null); + const deleteRef = useRef(null); + const hintTextRef = useRef(null); + const wrapperRef = useRef(null); const [open, setOpen] = useState(false); + const [width, setWidth] = useState(0); + const hintText = + 'This page has been moved to the trash, you can either restore or permanently delete it.'; + useEffect(() => { + const currentRef = wrapperRef.current; + + if (!currentRef) { + return; + } + + const handleResize = () => { + if (!currentRef) { + return; + } + + const wrapperWidth = currentRef?.offsetWidth || 0; + setWidth(wrapperWidth); + }; + + const resizeObserver = new ResizeObserver(handleResize); + resizeObserver.observe(currentRef); + + return () => { + resizeObserver.unobserve(currentRef); + }; + }, []); return ( -
-
- -
-
- -
- +
{ - jumpToSubPath(workspace.id, WorkspaceSubPath.ALL); - blockSuiteWorkspace.removePage(pageId); - toast(t['com.affine.toastMessage.permanentlyDeleted']()); - }, [blockSuiteWorkspace, jumpToSubPath, pageId, workspace.id, t])} - onOpenChange={setOpen} - /> + data-has-background={!appSettings.clientBorder} + > + +
+ {hintText} +
+
+ +
+ + + + + + +
+ { + jumpToSubPath(workspace.id, WorkspaceSubPath.ALL); + blockSuiteWorkspace.removePage(pageId); + toast(t['com.affine.toastMessage.permanentlyDeleted']()); + }, [blockSuiteWorkspace, jumpToSubPath, pageId, workspace.id, t])} + onOpenChange={setOpen} + /> +
); }; diff --git a/apps/core/src/components/pure/trash-button-group/styles.css.ts b/apps/core/src/components/pure/trash-button-group/styles.css.ts index 75ad377019..71b07c64f0 100644 --- a/apps/core/src/components/pure/trash-button-group/styles.css.ts +++ b/apps/core/src/components/pure/trash-button-group/styles.css.ts @@ -1,16 +1,46 @@ import { style } from '@vanilla-extract/css'; export const group = style({ - width: '100%', - position: 'absolute', - bottom: '100px', - left: '0', display: 'flex', - gap: '24px', + gap: '16px', justifyContent: 'center', +}); +export const deleteHintContainer = style({ + position: 'fixed', zIndex: 2, + padding: '14px 20px', + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + bottom: '0', + gap: '16px', + backgroundColor: 'var(--affine-background-primary-color)', + borderTop: '1px solid var(--affine-border-color)', + selectors: { + '&[data-has-background="false"]': { + backgroundColor: 'transparent', + borderTop: 'none', + padding: '14px 0', + }, + }, +}); +export const deleteHintText = style({ + fontSize: '15px', + fontWeight: '500', + lineHeight: '24px', + color: 'var(--affine-text-secondary-color)', + whiteSpace: 'nowrap', + textOverflow: 'ellipsis', + overflow: 'hidden', + cursor: 'pointer', }); export const buttonContainer = style({ - boxShadow: 'var(--affine-float-button-shadow-2)', - borderRadius: '8px', + color: 'var(--affine-pure-white)', + padding: '8px 18px', + fontSize: '20px', + height: '36px', +}); +export const icon = style({ + display: 'flex', + alignContent: 'center', }); diff --git a/apps/core/src/layouts/workspace-layout.tsx b/apps/core/src/layouts/workspace-layout.tsx index b54fad9885..c05bbc8c54 100644 --- a/apps/core/src/layouts/workspace-layout.tsx +++ b/apps/core/src/layouts/workspace-layout.tsx @@ -28,6 +28,7 @@ import { useSensor, useSensors, } from '@dnd-kit/core'; +import { useBlockSuitePageMeta } from '@toeverything/hooks/use-block-suite-page-meta'; import { usePassiveWorkspaceEffect } from '@toeverything/infra/__internal__/react'; import { currentWorkspaceIdAtom } from '@toeverything/infra/atom'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; @@ -228,7 +229,10 @@ export const WorkspaceLayoutInner = ({ const [appSetting] = useAppSetting(); const location = useLocation(); const { pageId } = useParams(); - + const pageMeta = useBlockSuitePageMeta( + currentWorkspace.blockSuiteWorkspace + ).find(meta => meta.id === pageId); + const inTrashPage = pageMeta?.trash ?? false; const setMainContainer = useSetAtom(mainContainerAtom); return ( @@ -262,9 +266,10 @@ export const WorkspaceLayoutInner = ({ {incompatible ? : children} - + diff --git a/packages/component/src/components/app-sidebar/sidebar-header/sidebar-switch.css.ts b/packages/component/src/components/app-sidebar/sidebar-header/sidebar-switch.css.ts index 0a41ec7c7c..d7fea8ef4f 100644 --- a/packages/component/src/components/app-sidebar/sidebar-header/sidebar-switch.css.ts +++ b/packages/component/src/components/app-sidebar/sidebar-header/sidebar-switch.css.ts @@ -11,6 +11,7 @@ export const sidebarSwitch = style({ opacity: 1, width: '32px', flexShrink: 0, + fontSize: '24px', pointerEvents: 'auto', }, }, diff --git a/packages/component/src/components/workspace/index.css.ts b/packages/component/src/components/workspace/index.css.ts index 79a8634758..ec816b3f1e 100644 --- a/packages/component/src/components/workspace/index.css.ts +++ b/packages/component/src/components/workspace/index.css.ts @@ -86,6 +86,12 @@ export const mainContainerStyle = style({ '&[data-show-padding="true"][data-is-macos="true"]': { borderRadius: '6px', }, + '&[data-in-trash-page="true"]': { + marginBottom: '66px', + }, + '&[data-in-trash-page="true"][data-show-padding="true"]': { + marginBottom: '66px', + }, '&[data-show-padding="true"]:before': { content: '""', position: 'absolute', @@ -151,4 +157,20 @@ export const toolStyle = style({ display: 'none', }, }, + selectors: { + '&[data-in-trash-page="true"]': { + bottom: '70px', + '@media': { + [breakpoints.down('md', true)]: { + bottom: '80px', + }, + [breakpoints.down('sm', true)]: { + bottom: '85px', + }, + print: { + display: 'none', + }, + }, + }, + }, }); diff --git a/packages/component/src/components/workspace/index.tsx b/packages/component/src/components/workspace/index.tsx index 157df78619..3472660124 100644 --- a/packages/component/src/components/workspace/index.tsx +++ b/packages/component/src/components/workspace/index.tsx @@ -35,13 +35,14 @@ export const AppContainer = ({ export interface MainContainerProps extends HTMLAttributes { className?: string; padding?: boolean; + inTrashPage?: boolean; } export const MainContainer = forwardRef< HTMLDivElement, PropsWithChildren >(function MainContainer( - { className, padding, children, ...props }, + { className, padding, inTrashPage, children, ...props }, ref ): ReactElement { return ( @@ -50,6 +51,7 @@ export const MainContainer = forwardRef< className={clsx(mainContainerStyle, className)} data-is-macos={environment.isDesktop && environment.isMacOs} data-show-padding={!!padding} + data-in-trash-page={!!inTrashPage} ref={ref} > {children} @@ -59,8 +61,14 @@ export const MainContainer = forwardRef< MainContainer.displayName = 'MainContainer'; -export const ToolContainer = (props: PropsWithChildren): ReactElement => { - return
{props.children}
; +export const ToolContainer = ( + props: PropsWithChildren & { inTrashPage: boolean } +): ReactElement => { + return ( +
+ {props.children} +
+ ); }; export const WorkspaceFallback = (): ReactElement => { diff --git a/packages/hooks/src/use-is-tiny-screen.ts b/packages/hooks/src/use-is-tiny-screen.ts index 185d5fb8b4..506416a983 100644 --- a/packages/hooks/src/use-is-tiny-screen.ts +++ b/packages/hooks/src/use-is-tiny-screen.ts @@ -70,7 +70,7 @@ export function useIsTinyScreen({ resizeObserver.observe(mainContainer); return () => { - resizeObserver.disconnect(); + resizeObserver.unobserve(mainContainer); }; }, [ centerDom, diff --git a/plugins/outline/src/app.tsx b/plugins/outline/src/app.tsx index 328352df5c..1c117d37a8 100644 --- a/plugins/outline/src/app.tsx +++ b/plugins/outline/src/app.tsx @@ -60,7 +60,12 @@ export const HeaderItem = ({ }} > { if (!open) { setOpen(true);