fix(core): update outline viewer style (#7641)

## What changes
- Update responsive style and fix some bug of outline viewer (https://github.com/toeverything/blocksuite/pull/7759)
- Change left and right padding of full-width editor from `15px` to `72px`
- Hide outline viewer when side outline panel is opened ([BS-987](https://linear.app/affine-design/issue/BS-987/逻辑-bug-toc-入口和-toc-侧边栏共存))
- Add entries of outline panel and frame panel in more menu of detail page header ( [BS-996](https://linear.app/affine-design/issue/BS-996/page-mode-下的-page-option-缺少-view-table-of-contents-的入口) , [BS-1006](https://linear.app/affine-design/issue/BS-1006/edgeless-mode-的-page-options-里缺少-view-all-frames))
- Add outline viewer to dock peek preview ( [BS-995](https://linear.app/affine-design/issue/BS-995/center-peek-里缺少-quick-toc-的入口) )
- Add more e2e tests for outline viewer
This commit is contained in:
L-Sun
2024-08-05 03:57:48 +00:00
parent 545bd032a7
commit bd31c8388c
18 changed files with 264 additions and 81 deletions
@@ -20,6 +20,7 @@ import { useTrashModalHelper } from '@affine/core/hooks/affine/use-trash-modal-h
import { useAsyncCallback } from '@affine/core/hooks/affine-async-hooks';
import { mixpanel } from '@affine/core/mixpanel';
import { WorkbenchService } from '@affine/core/modules/workbench';
import { ViewService } from '@affine/core/modules/workbench/services/view';
import { useDetailPageHeaderResponsive } from '@affine/core/pages/workspace/detail-page/use-header-responsive';
import { WorkspaceFlavour } from '@affine/env/workspace';
import { useI18n } from '@affine/i18n';
@@ -29,6 +30,7 @@ import {
EditIcon,
FavoritedIcon,
FavoriteIcon,
FrameIcon,
HistoryIcon,
ImportIcon,
InformationIcon,
@@ -36,6 +38,7 @@ import {
PageIcon,
ShareIcon,
SplitViewIcon,
TocIcon,
} from '@blocksuite/icons/rc';
import type { Doc } from '@blocksuite/store';
import {
@@ -84,6 +87,24 @@ export const PageHeaderMenuButton = ({
const { importFile } = usePageHelper(docCollection);
const { setTrashModal } = useTrashModalHelper(docCollection);
const view = useService(ViewService).view;
const openSidePanel = useCallback(
(id: string) => {
workbench.openSidebar();
view.activeSidebarTab(id);
},
[workbench, view]
);
const openAllFrames = useCallback(() => {
openSidePanel('frame');
}, [openSidePanel]);
const openOutlinePanel = useCallback(() => {
openSidePanel('outline');
}, [openSidePanel]);
const [historyModalOpen, setHistoryModalOpen] = useState(false);
const setOpenHistoryTipsModal = useSetAtom(openHistoryTipsModalAtom);
@@ -297,6 +318,33 @@ export const PageHeaderMenuButton = ({
{t['com.affine.page-properties.page-info.view']()}
</MenuItem>
)}
{currentMode === 'page' ? (
<MenuItem
preFix={
<MenuIcon>
<TocIcon />
</MenuIcon>
}
data-testid="editor-option-toc"
onSelect={openOutlinePanel}
style={menuItemStyle}
>
{t['com.affine.header.option.view-toc']()}
</MenuItem>
) : (
<MenuItem
preFix={
<MenuIcon>
<FrameIcon />
</MenuIcon>
}
data-testid="editor-option-frame"
onSelect={openAllFrames}
style={menuItemStyle}
>
{t['com.affine.header.option.view-frame']()}
</MenuItem>
)}
<MenuItem
preFix={
<MenuIcon>
@@ -0,0 +1,42 @@
import type { AffineEditorContainer } from '@blocksuite/presets';
import { OutlineViewer } from '@blocksuite/presets';
import { useCallback, useRef } from 'react';
import * as styles from './outline-viewer.css';
export const EditorOutlineViewer = ({
editor,
show,
openOutlinePanel,
}: {
editor: AffineEditorContainer | null;
show: boolean;
openOutlinePanel: () => void;
}) => {
const outlineViewerRef = useRef<OutlineViewer | null>(null);
const onRefChange = useCallback((container: HTMLDivElement | null) => {
if (container) {
if (outlineViewerRef.current === null) {
console.error('outline viewer should be initialized');
return;
}
container.append(outlineViewerRef.current);
}
}, []);
if (!editor || !show) return;
if (!outlineViewerRef.current) {
outlineViewerRef.current = new OutlineViewer();
}
if (outlineViewerRef.current.editor !== editor) {
outlineViewerRef.current.editor = editor;
}
if (outlineViewerRef.current.toggleOutlinePanel !== openOutlinePanel) {
outlineViewerRef.current.toggleOutlinePanel = openOutlinePanel;
}
return <div className={styles.root} ref={onRefChange} />;
};
@@ -0,0 +1,17 @@
import { style } from '@vanilla-extract/css';
const top = 256 - 52; // 52 is the height of the header
const bottom = 76;
export const root = style({
position: 'absolute',
top,
right: 22,
maxHeight: `calc(100% - ${top}px - ${bottom}px)`,
display: 'flex',
'@container': {
'(width <= 640px)': {
display: 'none',
},
},
});
@@ -5,7 +5,7 @@ export const editor = style({
'&.full-screen': {
vars: {
'--affine-editor-width': '100%',
'--affine-editor-side-padding': '15px',
'--affine-editor-side-padding': '72px',
},
},
},