refactor: move outline fragment to separate package (#10331)

### TL;DR

Moved outline functionality into a dedicated fragment package and updated vanilla-extract CSS dependency.

### What changed?

- Created new `@blocksuite/affine-fragment-outline` package
- Relocated outline-related code from presets to the new fragment package
- Updated imports across affected files to reference the new package location
- Upgraded `@vanilla-extract/css` dependency from 1.14.0/1.16.1 to 1.17.0
- Added necessary package configuration and TypeScript setup for the new fragment

### How to test?

1. Verify outline functionality works as expected in both desktop and mobile views
2. Check that outline panel, viewer, and mobile menu components render correctly
3. Ensure outline navigation and interactions continue to work
4. Confirm no regressions in outline-related features

### Why make this change?

This change improves code organization by isolating outline functionality into a dedicated package, following the modular architecture pattern. This makes the codebase more maintainable and allows for better separation of concerns. The vanilla-extract CSS upgrade ensures consistency across packages and provides access to the latest features and fixes.
This commit is contained in:
Saul-Mirone
2025-02-20 15:59:13 +00:00
parent 5ac15f12e6
commit b8dcb85007
41 changed files with 217 additions and 134 deletions

View File

@@ -24,7 +24,7 @@
"@blocksuite/store": "workspace:*", "@blocksuite/store": "workspace:*",
"@floating-ui/dom": "^1.6.10", "@floating-ui/dom": "^1.6.10",
"@preact/signals-core": "^1.8.0", "@preact/signals-core": "^1.8.0",
"@vanilla-extract/css": "^1.14.0", "@vanilla-extract/css": "^1.17.0",
"lit": "^3.2.0", "lit": "^3.2.0",
"yjs": "^13.6.21", "yjs": "^13.6.21",
"zod": "^3.24.1" "zod": "^3.24.1"

View File

@@ -0,0 +1,45 @@
{
"name": "@blocksuite/affine-fragment-outline",
"description": "Outline fragment for BlockSuite.",
"type": "module",
"scripts": {
"build": "tsc",
"test:unit": "nx vite:test --run --passWithNoTests",
"test:unit:coverage": "nx vite:test --run --coverage",
"test:e2e": "playwright test"
},
"sideEffects": false,
"keywords": [],
"author": "toeverything",
"license": "MIT",
"dependencies": {
"@blocksuite/affine-block-note": "workspace:*",
"@blocksuite/affine-components": "workspace:*",
"@blocksuite/affine-model": "workspace:*",
"@blocksuite/affine-shared": "workspace:*",
"@blocksuite/block-std": "workspace:*",
"@blocksuite/global": "workspace:*",
"@blocksuite/icons": "^2.2.1",
"@blocksuite/inline": "workspace:*",
"@blocksuite/store": "workspace:*",
"@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.11",
"@vanilla-extract/css": "^1.17.0",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"zod": "^3.23.8"
},
"exports": {
".": "./src/index.ts",
"./effects": "./src/effects.ts"
},
"files": [
"src",
"dist",
"!src/__tests__",
"!dist/__tests__"
],
"version": "0.19.0"
}

View File

@@ -1,18 +1,10 @@
import { effects } from '@blocksuite/affine-block-note/effects'; import { changeNoteDisplayMode } from '@blocksuite/affine-block-note';
import { NoteBlockModel, NoteDisplayMode } from '@blocksuite/affine-model';
import { DocModeProvider } from '@blocksuite/affine-shared/services';
import { matchModels } from '@blocksuite/affine-shared/utils';
import { ShadowlessElement, SurfaceSelection } from '@blocksuite/block-std'; import { ShadowlessElement, SurfaceSelection } from '@blocksuite/block-std';
import { import { GfxControllerIdentifier } from '@blocksuite/block-std/gfx';
changeNoteDisplayMode, import { Bound, SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
DocModeProvider,
matchModels,
NoteBlockModel,
NoteDisplayMode,
} from '@blocksuite/blocks';
import {
Bound,
noop,
SignalWatcher,
WithDisposable,
} from '@blocksuite/global/utils';
import type { BlockModel } from '@blocksuite/store'; import type { BlockModel } from '@blocksuite/store';
import { consume } from '@lit/context'; import { consume } from '@lit/context';
import { effect, signal } from '@preact/signals-core'; import { effect, signal } from '@preact/signals-core';
@@ -22,8 +14,6 @@ import { classMap } from 'lit/directives/class-map.js';
import { repeat } from 'lit/directives/repeat.js'; import { repeat } from 'lit/directives/repeat.js';
import { when } from 'lit/directives/when.js'; import { when } from 'lit/directives/when.js';
noop(effects);
import { type TocContext, tocContext } from '../config'; import { type TocContext, tocContext } from '../config';
import type { import type {
ClickBlockEvent, ClickBlockEvent,
@@ -79,10 +69,6 @@ export class OutlinePanelBody extends SignalWatcher(
return this.editor.doc; return this.editor.doc;
} }
private get edgeless() {
return this.editor.querySelector('affine-edgeless-root');
}
get viewportPadding(): [number, number, number, number] { get viewportPadding(): [number, number, number, number] {
const fitPadding = this._context.fitPadding$.value; const fitPadding = this._context.fitPadding$.value;
return fitPadding.length === 4 return fitPadding.length === 4
@@ -93,9 +79,9 @@ export class OutlinePanelBody extends SignalWatcher(
} }
private _deSelectNoteInEdgelessMode(note: NoteBlockModel) { private _deSelectNoteInEdgelessMode(note: NoteBlockModel) {
if (!this.edgeless) return; const gfx = this.editor.std.get(GfxControllerIdentifier);
const selection = gfx.selection;
const { selection } = this.edgeless.service;
if (!selection.has(note.id)) return; if (!selection.has(note.id)) return;
const selectedIds = selection.selectedIds.filter(id => id !== note.id); const selectedIds = selection.selectedIds.filter(id => id !== note.id);
selection.set({ selection.set({
@@ -116,18 +102,12 @@ export class OutlinePanelBody extends SignalWatcher(
} }
private _fitToElement(e: FitViewEvent) { private _fitToElement(e: FitViewEvent) {
const edgeless = this.edgeless; const gfx = this.editor.std.get(GfxControllerIdentifier);
if (!edgeless) return;
const { block } = e.detail; const { block } = e.detail;
const bound = Bound.deserialize(block.xywh); const bound = Bound.deserialize(block.xywh);
edgeless.service.viewport.setViewportByBound( gfx.viewport.setViewportByBound(bound, this.viewportPadding, true);
bound,
this.viewportPadding,
true
);
} }
// when display mode change to page only, we should de-select the note if it is selected in edgeless mode // when display mode change to page only, we should de-select the note if it is selected in edgeless mode
@@ -200,6 +180,8 @@ export class OutlinePanelBody extends SignalWatcher(
private _selectNote(e: SelectEvent) { private _selectNote(e: SelectEvent) {
const { selected, id, multiselect } = e.detail; const { selected, id, multiselect } = e.detail;
const gfx = this.editor.std.get(GfxControllerIdentifier);
const editorMode = this.editor.std.get(DocModeProvider).getEditorMode();
const note = this.doc.getBlock(id)?.model; const note = this.doc.getBlock(id)?.model;
if (!note || !matchModels(note, [NoteBlockModel])) return; if (!note || !matchModels(note, [NoteBlockModel])) return;
@@ -213,8 +195,8 @@ export class OutlinePanelBody extends SignalWatcher(
selectedNotes = [note]; selectedNotes = [note];
} }
if (this.edgeless) { if (editorMode === 'edgeless') {
this.edgeless?.service.selection.set({ gfx.selection.set({
elements: selectedNotes.map(({ id }) => id), elements: selectedNotes.map(({ id }) => id),
editing: false, editing: false,
}); });

View File

@@ -1,9 +1,6 @@
import { type NoteBlockModel, NoteDisplayMode } from '@blocksuite/affine-model';
import { createButtonPopper } from '@blocksuite/affine-shared/utils';
import { ShadowlessElement } from '@blocksuite/block-std'; import { ShadowlessElement } from '@blocksuite/block-std';
import {
createButtonPopper,
type NoteBlockModel,
NoteDisplayMode,
} from '@blocksuite/blocks';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
import { ArrowDownSmallIcon, InvisibleIcon } from '@blocksuite/icons/lit'; import { ArrowDownSmallIcon, InvisibleIcon } from '@blocksuite/icons/lit';
import type { BlockModel } from '@blocksuite/store'; import type { BlockModel } from '@blocksuite/store';

View File

@@ -1,16 +1,16 @@
import type {
AttachmentBlockModel,
BookmarkBlockModel,
CodeBlockModel,
DatabaseBlockModel,
ImageBlockModel,
ListBlockModel,
ParagraphBlockModel,
RootBlockModel,
} from '@blocksuite/affine-model';
import { DocDisplayMetaProvider } from '@blocksuite/affine-shared/services';
import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; import type { AffineTextAttributes } from '@blocksuite/affine-shared/types';
import { ShadowlessElement } from '@blocksuite/block-std'; import { ShadowlessElement } from '@blocksuite/block-std';
import {
type AttachmentBlockModel,
type BookmarkBlockModel,
type CodeBlockModel,
type DatabaseBlockModel,
DocDisplayMetaProvider,
type ImageBlockModel,
type ListBlockModel,
type ParagraphBlockModel,
type RootBlockModel,
} from '@blocksuite/blocks';
import { noop, SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { noop, SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
import { LinkedPageIcon } from '@blocksuite/icons/lit'; import { LinkedPageIcon } from '@blocksuite/icons/lit';
import type { DeltaInsert } from '@blocksuite/inline'; import type { DeltaInsert } from '@blocksuite/inline';

View File

@@ -1,5 +1,5 @@
import type { ParagraphBlockModel } from '@blocksuite/affine-model';
import type { EditorHost } from '@blocksuite/block-std'; import type { EditorHost } from '@blocksuite/block-std';
import type { ParagraphBlockModel, Signal } from '@blocksuite/blocks';
import { import {
AttachmentIcon, AttachmentIcon,
BlockIcon, BlockIcon,
@@ -21,6 +21,7 @@ import {
TextIcon, TextIcon,
} from '@blocksuite/icons/lit'; } from '@blocksuite/icons/lit';
import { createContext } from '@lit/context'; import { createContext } from '@lit/context';
import type { Signal } from '@preact/signals-core';
import type { TemplateResult } from 'lit'; import type { TemplateResult } from 'lit';
const _16px = { width: '16px', height: '16px' }; const _16px = { width: '16px', height: '16px' };

View File

@@ -0,0 +1,39 @@
import { AFFINE_OUTLINE_NOTICE, OutlineNotice } from './body/outline-notice';
import {
AFFINE_OUTLINE_PANEL_BODY,
OutlinePanelBody,
} from './body/outline-panel-body';
import { AFFINE_OUTLINE_NOTE_CARD, OutlineNoteCard } from './card/outline-card';
import {
AFFINE_OUTLINE_BLOCK_PREVIEW,
OutlineBlockPreview,
} from './card/outline-preview';
import {
AFFINE_OUTLINE_PANEL_HEADER,
OutlinePanelHeader,
} from './header/outline-panel-header';
import {
AFFINE_OUTLINE_NOTE_PREVIEW_SETTING_MENU,
OutlineNotePreviewSettingMenu,
} from './header/outline-setting-menu';
import {
AFFINE_MOBILE_OUTLINE_MENU,
MobileOutlineMenu,
} from './mobile-outline-panel';
import { AFFINE_OUTLINE_PANEL, OutlinePanel } from './outline-panel';
import { AFFINE_OUTLINE_VIEWER, OutlineViewer } from './outline-viewer';
export function effects() {
customElements.define(
AFFINE_OUTLINE_NOTE_PREVIEW_SETTING_MENU,
OutlineNotePreviewSettingMenu
);
customElements.define(AFFINE_OUTLINE_NOTICE, OutlineNotice);
customElements.define(AFFINE_OUTLINE_PANEL, OutlinePanel);
customElements.define(AFFINE_OUTLINE_PANEL_HEADER, OutlinePanelHeader);
customElements.define(AFFINE_OUTLINE_NOTE_CARD, OutlineNoteCard);
customElements.define(AFFINE_OUTLINE_VIEWER, OutlineViewer);
customElements.define(AFFINE_MOBILE_OUTLINE_MENU, MobileOutlineMenu);
customElements.define(AFFINE_OUTLINE_BLOCK_PREVIEW, OutlineBlockPreview);
customElements.define(AFFINE_OUTLINE_PANEL_BODY, OutlinePanelBody);
}

View File

@@ -1,5 +1,5 @@
import { createButtonPopper } from '@blocksuite/affine-shared/utils';
import { ShadowlessElement } from '@blocksuite/block-std'; import { ShadowlessElement } from '@blocksuite/block-std';
import { createButtonPopper } from '@blocksuite/blocks';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
import { SettingsIcon, SortIcon } from '@blocksuite/icons/lit'; import { SettingsIcon, SortIcon } from '@blocksuite/icons/lit';
import { consume } from '@lit/context'; import { consume } from '@lit/context';

View File

@@ -1,16 +1,16 @@
import {
NoteDisplayMode,
ParagraphBlockModel,
RootBlockModel,
} from '@blocksuite/affine-model';
import { DocModeProvider } from '@blocksuite/affine-shared/services';
import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme'; import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme';
import { matchModels } from '@blocksuite/affine-shared/utils';
import { import {
type EditorHost, type EditorHost,
PropTypes, PropTypes,
requiredProperties, requiredProperties,
} from '@blocksuite/block-std'; } from '@blocksuite/block-std';
import {
DocModeProvider,
matchModels,
NoteDisplayMode,
ParagraphBlockModel,
RootBlockModel,
} from '@blocksuite/blocks';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
import type { BlockModel } from '@blocksuite/store'; import type { BlockModel } from '@blocksuite/store';
import { signal } from '@preact/signals-core'; import { signal } from '@preact/signals-core';

View File

@@ -1,10 +1,10 @@
import { DocModeProvider } from '@blocksuite/affine-shared/services';
import { import {
type EditorHost, type EditorHost,
PropTypes, PropTypes,
requiredProperties, requiredProperties,
ShadowlessElement, ShadowlessElement,
} from '@blocksuite/block-std'; } from '@blocksuite/block-std';
import { DocModeProvider } from '@blocksuite/blocks';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
import { provide } from '@lit/context'; import { provide } from '@lit/context';
import { effect, signal } from '@preact/signals-core'; import { effect, signal } from '@preact/signals-core';

View File

@@ -1,14 +1,12 @@
import { NoteDisplayMode } from '@blocksuite/affine-model';
import { DocModeProvider } from '@blocksuite/affine-shared/services';
import { scrollbarStyle } from '@blocksuite/affine-shared/styles';
import { import {
type EditorHost, type EditorHost,
PropTypes, PropTypes,
requiredProperties, requiredProperties,
ShadowlessElement, ShadowlessElement,
} from '@blocksuite/block-std'; } from '@blocksuite/block-std';
import {
DocModeProvider,
NoteDisplayMode,
scrollbarStyle,
} from '@blocksuite/blocks';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
import { TocIcon } from '@blocksuite/icons/lit'; import { TocIcon } from '@blocksuite/icons/lit';
import { provide } from '@lit/context'; import { provide } from '@lit/context';

View File

@@ -1,4 +1,4 @@
import type { NoteBlockModel, NoteDisplayMode } from '@blocksuite/blocks'; import type { NoteBlockModel, NoteDisplayMode } from '@blocksuite/affine-model';
export type ReorderEvent = CustomEvent<{ export type ReorderEvent = CustomEvent<{
currentNumber: number; currentNumber: number;

View File

@@ -1,11 +1,10 @@
import { import {
BlocksUtils,
matchModels,
NoteBlockModel, NoteBlockModel,
NoteDisplayMode, NoteDisplayMode,
ParagraphBlockModel, ParagraphBlockModel,
RootBlockModel, RootBlockModel,
} from '@blocksuite/blocks'; } from '@blocksuite/affine-model';
import { matchModels } from '@blocksuite/affine-shared/utils';
import type { BlockModel, Store } from '@blocksuite/store'; import type { BlockModel, Store } from '@blocksuite/store';
import { headingKeys } from '../config.js'; import { headingKeys } from '../config.js';
@@ -35,14 +34,14 @@ export function getNotesFromDoc(
} }
export function isRootBlock(block: BlockModel): block is RootBlockModel { export function isRootBlock(block: BlockModel): block is RootBlockModel {
return BlocksUtils.matchModels(block, [RootBlockModel]); return matchModels(block, [RootBlockModel]);
} }
export function isHeadingBlock( export function isHeadingBlock(
block: BlockModel block: BlockModel
): block is ParagraphBlockModel { ): block is ParagraphBlockModel {
return ( return (
BlocksUtils.matchModels(block, [ParagraphBlockModel]) && matchModels(block, [ParagraphBlockModel]) &&
headingKeys.has(block.type$.value) headingKeys.has(block.type$.value)
); );
} }

View File

@@ -1,9 +1,8 @@
import { getDocTitleByEditorHost } from '@blocksuite/affine-components/doc-title';
import { NoteDisplayMode } from '@blocksuite/affine-model';
import { DocModeProvider } from '@blocksuite/affine-shared/services';
import type { Viewport } from '@blocksuite/affine-shared/types';
import type { EditorHost } from '@blocksuite/block-std'; import type { EditorHost } from '@blocksuite/block-std';
import {
DocModeProvider,
getDocTitleByEditorHost,
NoteDisplayMode,
} from '@blocksuite/blocks';
import { clamp, DisposableGroup } from '@blocksuite/global/utils'; import { clamp, DisposableGroup } from '@blocksuite/global/utils';
import { getHeadingBlocksFromDoc } from './query.js'; import { getHeadingBlocksFromDoc } from './query.js';
@@ -13,7 +12,7 @@ export function scrollToBlock(host: EditorHost, blockId: string) {
const mode = docModeService.getEditorMode(); const mode = docModeService.getEditorMode();
if (mode === 'edgeless') return; if (mode === 'edgeless') return;
if (editor.doc.root?.id === blockId) { if (host.doc.root?.id === blockId) {
const docTitle = getDocTitleByEditorHost(host); const docTitle = getDocTitleByEditorHost(host);
if (!docTitle) return; if (!docTitle) return;
@@ -89,7 +88,9 @@ function highlightBlock(host: EditorHost, blockId: string) {
if (host.doc.root?.id === blockId) return emptyClear; if (host.doc.root?.id === blockId) return emptyClear;
const rootComponent = host.querySelector('affine-page-root'); const rootComponent = host.querySelector<
HTMLElement & { viewport: Viewport }
>('affine-page-root');
if (!rootComponent) return emptyClear; if (!rootComponent) return emptyClear;
if (!rootComponent.viewport) { if (!rootComponent.viewport) {

View File

@@ -0,0 +1,19 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"tsBuildInfoFile": "./dist/tsconfig.tsbuildinfo"
},
"include": ["./src"],
"references": [
{ "path": "../block-note" },
{ "path": "../components" },
{ "path": "../model" },
{ "path": "../shared" },
{ "path": "../../framework/block-std" },
{ "path": "../../framework/global" },
{ "path": "../../framework/inline" },
{ "path": "../../framework/store" }
]
}

View File

@@ -33,6 +33,7 @@
"@blocksuite/affine-block-table": "workspace:*", "@blocksuite/affine-block-table": "workspace:*",
"@blocksuite/affine-components": "workspace:*", "@blocksuite/affine-components": "workspace:*",
"@blocksuite/affine-fragment-frame-panel": "workspace:*", "@blocksuite/affine-fragment-frame-panel": "workspace:*",
"@blocksuite/affine-fragment-outline": "workspace:*",
"@blocksuite/affine-model": "workspace:*", "@blocksuite/affine-model": "workspace:*",
"@blocksuite/affine-shared": "workspace:*", "@blocksuite/affine-shared": "workspace:*",
"@blocksuite/affine-widget-drag-handle": "workspace:*", "@blocksuite/affine-widget-drag-handle": "workspace:*",

View File

@@ -34,6 +34,7 @@ import { effects as componentToggleButtonEffects } from '@blocksuite/affine-comp
import { ToggleSwitch } from '@blocksuite/affine-components/toggle-switch'; import { ToggleSwitch } from '@blocksuite/affine-components/toggle-switch';
import { effects as componentToolbarEffects } from '@blocksuite/affine-components/toolbar'; import { effects as componentToolbarEffects } from '@blocksuite/affine-components/toolbar';
import { effects as fragmentFramePanelEffects } from '@blocksuite/affine-fragment-frame-panel/effects'; import { effects as fragmentFramePanelEffects } from '@blocksuite/affine-fragment-frame-panel/effects';
import { effects as fragmentOutlineEffects } from '@blocksuite/affine-fragment-outline/effects';
import { effects as widgetDragHandleEffects } from '@blocksuite/affine-widget-drag-handle/effects'; import { effects as widgetDragHandleEffects } from '@blocksuite/affine-widget-drag-handle/effects';
import { effects as widgetEdgelessAutoConnectEffects } from '@blocksuite/affine-widget-edgeless-auto-connect/effects'; import { effects as widgetEdgelessAutoConnectEffects } from '@blocksuite/affine-widget-edgeless-auto-connect/effects';
import { effects as widgetFrameTitleEffects } from '@blocksuite/affine-widget-frame-title/effects'; import { effects as widgetFrameTitleEffects } from '@blocksuite/affine-widget-frame-title/effects';
@@ -229,6 +230,7 @@ export function effects() {
widgetEdgelessAutoConnectEffects(); widgetEdgelessAutoConnectEffects();
fragmentFramePanelEffects(); fragmentFramePanelEffects();
fragmentOutlineEffects();
customElements.define('affine-page-root', PageRootBlockComponent); customElements.define('affine-page-root', PageRootBlockComponent);
customElements.define('affine-preview-root', PreviewRootBlockComponent); customElements.define('affine-preview-root', PreviewRootBlockComponent);

View File

@@ -91,6 +91,7 @@ export {
Tooltip, Tooltip,
} from '@blocksuite/affine-components/toolbar'; } from '@blocksuite/affine-components/toolbar';
export * from '@blocksuite/affine-fragment-frame-panel'; export * from '@blocksuite/affine-fragment-frame-panel';
export * from '@blocksuite/affine-fragment-outline';
export * from '@blocksuite/affine-model'; export * from '@blocksuite/affine-model';
export { export {
AttachmentAdapter, AttachmentAdapter,

View File

@@ -26,6 +26,7 @@
{ "path": "../affine/block-table" }, { "path": "../affine/block-table" },
{ "path": "../affine/components" }, { "path": "../affine/components" },
{ "path": "../affine/fragment-frame-panel" }, { "path": "../affine/fragment-frame-panel" },
{ "path": "../affine/fragment-outline" },
{ "path": "../affine/model" }, { "path": "../affine/model" },
{ "path": "../affine/shared" }, { "path": "../affine/shared" },
{ "path": "../affine/widget-drag-handle" }, { "path": "../affine/widget-drag-handle" },

View File

@@ -7,56 +7,12 @@ import {
PageEditor, PageEditor,
} from './editors/index.js'; } from './editors/index.js';
import { CommentInput } from './fragments/comment/comment-input.js'; import { CommentInput } from './fragments/comment/comment-input.js';
import { import { CommentPanel } from './fragments/index.js';
AFFINE_MOBILE_OUTLINE_MENU,
AFFINE_OUTLINE_PANEL,
AFFINE_OUTLINE_VIEWER,
CommentPanel,
MobileOutlineMenu,
OutlinePanel,
OutlineViewer,
} from './fragments/index.js';
import {
AFFINE_OUTLINE_NOTICE,
OutlineNotice,
} from './fragments/outline/body/outline-notice.js';
import {
AFFINE_OUTLINE_PANEL_BODY,
OutlinePanelBody,
} from './fragments/outline/body/outline-panel-body.js';
import {
AFFINE_OUTLINE_NOTE_CARD,
OutlineNoteCard,
} from './fragments/outline/card/outline-card.js';
import {
AFFINE_OUTLINE_BLOCK_PREVIEW,
OutlineBlockPreview,
} from './fragments/outline/card/outline-preview.js';
import {
AFFINE_OUTLINE_PANEL_HEADER,
OutlinePanelHeader,
} from './fragments/outline/header/outline-panel-header.js';
import {
AFFINE_OUTLINE_NOTE_PREVIEW_SETTING_MENU,
OutlineNotePreviewSettingMenu,
} from './fragments/outline/header/outline-setting-menu.js';
export function effects() { export function effects() {
customElements.define('page-editor', PageEditor); customElements.define('page-editor', PageEditor);
customElements.define('comment-input', CommentInput); customElements.define('comment-input', CommentInput);
customElements.define(
AFFINE_OUTLINE_NOTE_PREVIEW_SETTING_MENU,
OutlineNotePreviewSettingMenu
);
customElements.define(AFFINE_OUTLINE_NOTICE, OutlineNotice);
customElements.define('comment-panel', CommentPanel); customElements.define('comment-panel', CommentPanel);
customElements.define(AFFINE_OUTLINE_PANEL, OutlinePanel);
customElements.define(AFFINE_OUTLINE_PANEL_HEADER, OutlinePanelHeader);
customElements.define('affine-editor-container', AffineEditorContainer); customElements.define('affine-editor-container', AffineEditorContainer);
customElements.define(AFFINE_OUTLINE_NOTE_CARD, OutlineNoteCard);
customElements.define('edgeless-editor', EdgelessEditor); customElements.define('edgeless-editor', EdgelessEditor);
customElements.define(AFFINE_OUTLINE_VIEWER, OutlineViewer);
customElements.define(AFFINE_MOBILE_OUTLINE_MENU, MobileOutlineMenu);
customElements.define(AFFINE_OUTLINE_BLOCK_PREVIEW, OutlineBlockPreview);
customElements.define(AFFINE_OUTLINE_PANEL_BODY, OutlinePanelBody);
} }

View File

@@ -1,2 +1 @@
export * from './comment/index.js'; export * from './comment/index.js';
export * from './outline/index.js';

View File

@@ -17,7 +17,7 @@
"@sentry/react": "^8.44.0", "@sentry/react": "^8.44.0",
"@toeverything/infra": "workspace:*", "@toeverything/infra": "workspace:*",
"@toeverything/theme": "^1.1.11", "@toeverything/theme": "^1.1.11",
"@vanilla-extract/css": "^1.16.1", "@vanilla-extract/css": "^1.17.0",
"async-call-rpc": "^6.4.2", "async-call-rpc": "^6.4.2",
"next-themes": "^0.4.4", "next-themes": "^0.4.4",
"react": "^19.0.0", "react": "^19.0.0",

View File

@@ -79,7 +79,7 @@
"@testing-library/react": "^16.1.0", "@testing-library/react": "^16.1.0",
"@types/react": "^19.0.1", "@types/react": "^19.0.1",
"@types/react-dom": "^19.0.2", "@types/react-dom": "^19.0.2",
"@vanilla-extract/css": "^1.16.1", "@vanilla-extract/css": "^1.17.0",
"storybook": "^8.4.7", "storybook": "^8.4.7",
"typescript": "^5.7.2", "typescript": "^5.7.2",
"unplugin-swc": "^1.5.1", "unplugin-swc": "^1.5.1",

View File

@@ -88,7 +88,7 @@
"@types/bytes": "^3.1.5", "@types/bytes": "^3.1.5",
"@types/image-blob-reduce": "^4.1.4", "@types/image-blob-reduce": "^4.1.4",
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",
"@vanilla-extract/css": "^1.16.1", "@vanilla-extract/css": "^1.17.0",
"fake-indexeddb": "^6.0.0", "fake-indexeddb": "^6.0.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"vitest": "3.0.6" "vitest": "3.0.6"

View File

@@ -1,5 +1,5 @@
import type { EditorHost } from '@blocksuite/affine/block-std'; import type { EditorHost } from '@blocksuite/affine/block-std';
import { OutlineViewer } from '@blocksuite/affine/presets'; import { OutlineViewer } from '@blocksuite/affine/blocks';
import { useCallback, useRef } from 'react'; import { useCallback, useRef } from 'react';
import * as styles from './outline-viewer.css'; import * as styles from './outline-viewer.css';

View File

@@ -1,5 +1,5 @@
import type { EditorHost } from '@blocksuite/affine/block-std'; import type { EditorHost } from '@blocksuite/affine/block-std';
import { OutlinePanel } from '@blocksuite/affine/presets'; import { OutlinePanel } from '@blocksuite/affine/blocks';
import { useCallback, useEffect, useRef } from 'react'; import { useCallback, useEffect, useRef } from 'react';
import * as styles from './outline.css'; import * as styles from './outline.css';

View File

@@ -1,5 +1,5 @@
import type { EditorHost } from '@blocksuite/affine/block-std'; import type { EditorHost } from '@blocksuite/affine/block-std';
import { MobileOutlineMenu } from '@blocksuite/affine/presets'; import { MobileOutlineMenu } from '@blocksuite/affine/blocks';
import { useCallback, useRef } from 'react'; import { useCallback, useRef } from 'react';
export const MobileTocMenu = ({ editor }: { editor: EditorHost | null }) => { export const MobileTocMenu = ({ editor }: { editor: EditorHost | null }) => {

View File

@@ -289,6 +289,20 @@ export const PackageList = [
'blocksuite/framework/store', 'blocksuite/framework/store',
], ],
}, },
{
location: 'blocksuite/affine/fragment-outline',
name: '@blocksuite/affine-fragment-outline',
workspaceDependencies: [
'blocksuite/affine/block-note',
'blocksuite/affine/components',
'blocksuite/affine/model',
'blocksuite/affine/shared',
'blocksuite/framework/block-std',
'blocksuite/framework/global',
'blocksuite/framework/inline',
'blocksuite/framework/store',
],
},
{ {
location: 'blocksuite/affine/model', location: 'blocksuite/affine/model',
name: '@blocksuite/affine-model', name: '@blocksuite/affine-model',
@@ -396,6 +410,7 @@ export const PackageList = [
'blocksuite/affine/block-table', 'blocksuite/affine/block-table',
'blocksuite/affine/components', 'blocksuite/affine/components',
'blocksuite/affine/fragment-frame-panel', 'blocksuite/affine/fragment-frame-panel',
'blocksuite/affine/fragment-outline',
'blocksuite/affine/model', 'blocksuite/affine/model',
'blocksuite/affine/shared', 'blocksuite/affine/shared',
'blocksuite/affine/widget-drag-handle', 'blocksuite/affine/widget-drag-handle',
@@ -780,6 +795,7 @@ export type PackageName =
| '@blocksuite/affine-components' | '@blocksuite/affine-components'
| '@blocksuite/data-view' | '@blocksuite/data-view'
| '@blocksuite/affine-fragment-frame-panel' | '@blocksuite/affine-fragment-frame-panel'
| '@blocksuite/affine-fragment-outline'
| '@blocksuite/affine-model' | '@blocksuite/affine-model'
| '@blocksuite/affine-shared' | '@blocksuite/affine-shared'
| '@blocksuite/affine-widget-drag-handle' | '@blocksuite/affine-widget-drag-handle'

View File

@@ -71,6 +71,7 @@
{ "path": "./blocksuite/affine/components" }, { "path": "./blocksuite/affine/components" },
{ "path": "./blocksuite/affine/data-view" }, { "path": "./blocksuite/affine/data-view" },
{ "path": "./blocksuite/affine/fragment-frame-panel" }, { "path": "./blocksuite/affine/fragment-frame-panel" },
{ "path": "./blocksuite/affine/fragment-outline" },
{ "path": "./blocksuite/affine/model" }, { "path": "./blocksuite/affine/model" },
{ "path": "./blocksuite/affine/shared" }, { "path": "./blocksuite/affine/shared" },
{ "path": "./blocksuite/affine/widget-drag-handle" }, { "path": "./blocksuite/affine/widget-drag-handle" },

View File

@@ -311,7 +311,7 @@ __metadata:
"@toeverything/theme": "npm:^1.1.11" "@toeverything/theme": "npm:^1.1.11"
"@types/react": "npm:^19.0.1" "@types/react": "npm:^19.0.1"
"@types/react-dom": "npm:^19.0.2" "@types/react-dom": "npm:^19.0.2"
"@vanilla-extract/css": "npm:^1.16.1" "@vanilla-extract/css": "npm:^1.17.0"
"@vanilla-extract/dynamic": "npm:^2.1.2" "@vanilla-extract/dynamic": "npm:^2.1.2"
check-password-strength: "npm:^3.0.0" check-password-strength: "npm:^3.0.0"
clsx: "npm:^2.1.1" clsx: "npm:^2.1.1"
@@ -396,7 +396,7 @@ __metadata:
"@types/bytes": "npm:^3.1.5" "@types/bytes": "npm:^3.1.5"
"@types/image-blob-reduce": "npm:^4.1.4" "@types/image-blob-reduce": "npm:^4.1.4"
"@types/lodash-es": "npm:^4.17.12" "@types/lodash-es": "npm:^4.17.12"
"@vanilla-extract/css": "npm:^1.16.1" "@vanilla-extract/css": "npm:^1.17.0"
"@vanilla-extract/dynamic": "npm:^2.1.2" "@vanilla-extract/dynamic": "npm:^2.1.2"
animejs: "npm:^3.2.2" animejs: "npm:^3.2.2"
bytes: "npm:^3.1.2" bytes: "npm:^3.1.2"
@@ -488,7 +488,7 @@ __metadata:
"@toeverything/theme": "npm:^1.1.11" "@toeverything/theme": "npm:^1.1.11"
"@types/react": "npm:^19.0.1" "@types/react": "npm:^19.0.1"
"@types/react-dom": "npm:^19.0.2" "@types/react-dom": "npm:^19.0.2"
"@vanilla-extract/css": "npm:^1.16.1" "@vanilla-extract/css": "npm:^1.17.0"
async-call-rpc: "npm:^6.4.2" async-call-rpc: "npm:^6.4.2"
cross-env: "npm:^7.0.3" cross-env: "npm:^7.0.3"
next-themes: "npm:^0.4.4" next-themes: "npm:^0.4.4"
@@ -3680,7 +3680,7 @@ __metadata:
"@blocksuite/store": "workspace:*" "@blocksuite/store": "workspace:*"
"@floating-ui/dom": "npm:^1.6.10" "@floating-ui/dom": "npm:^1.6.10"
"@preact/signals-core": "npm:^1.8.0" "@preact/signals-core": "npm:^1.8.0"
"@vanilla-extract/css": "npm:^1.14.0" "@vanilla-extract/css": "npm:^1.17.0"
lit: "npm:^3.2.0" lit: "npm:^3.2.0"
yjs: "npm:^13.6.21" yjs: "npm:^13.6.21"
zod: "npm:^3.24.1" zod: "npm:^3.24.1"
@@ -3744,6 +3744,30 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"@blocksuite/affine-fragment-outline@workspace:*, @blocksuite/affine-fragment-outline@workspace:blocksuite/affine/fragment-outline":
version: 0.0.0-use.local
resolution: "@blocksuite/affine-fragment-outline@workspace:blocksuite/affine/fragment-outline"
dependencies:
"@blocksuite/affine-block-note": "workspace:*"
"@blocksuite/affine-components": "workspace:*"
"@blocksuite/affine-model": "workspace:*"
"@blocksuite/affine-shared": "workspace:*"
"@blocksuite/block-std": "workspace:*"
"@blocksuite/global": "workspace:*"
"@blocksuite/icons": "npm:^2.2.1"
"@blocksuite/inline": "workspace:*"
"@blocksuite/store": "workspace:*"
"@floating-ui/dom": "npm:^1.6.10"
"@lit/context": "npm:^1.1.2"
"@preact/signals-core": "npm:^1.8.0"
"@toeverything/theme": "npm:^1.1.11"
"@vanilla-extract/css": "npm:^1.17.0"
lit: "npm:^3.2.0"
minimatch: "npm:^10.0.1"
zod: "npm:^3.23.8"
languageName: unknown
linkType: soft
"@blocksuite/affine-model@workspace:*, @blocksuite/affine-model@workspace:blocksuite/affine/model": "@blocksuite/affine-model@workspace:*, @blocksuite/affine-model@workspace:blocksuite/affine/model":
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "@blocksuite/affine-model@workspace:blocksuite/affine/model" resolution: "@blocksuite/affine-model@workspace:blocksuite/affine/model"
@@ -3962,6 +3986,7 @@ __metadata:
"@blocksuite/affine-block-table": "workspace:*" "@blocksuite/affine-block-table": "workspace:*"
"@blocksuite/affine-components": "workspace:*" "@blocksuite/affine-components": "workspace:*"
"@blocksuite/affine-fragment-frame-panel": "workspace:*" "@blocksuite/affine-fragment-frame-panel": "workspace:*"
"@blocksuite/affine-fragment-outline": "workspace:*"
"@blocksuite/affine-model": "workspace:*" "@blocksuite/affine-model": "workspace:*"
"@blocksuite/affine-shared": "workspace:*" "@blocksuite/affine-shared": "workspace:*"
"@blocksuite/affine-widget-drag-handle": "workspace:*" "@blocksuite/affine-widget-drag-handle": "workspace:*"
@@ -15886,7 +15911,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@vanilla-extract/css@npm:^1.14.0, @vanilla-extract/css@npm:^1.16.1, @vanilla-extract/css@npm:^1.17.0, @vanilla-extract/css@npm:^1.17.1": "@vanilla-extract/css@npm:^1.17.0, @vanilla-extract/css@npm:^1.17.1":
version: 1.17.1 version: 1.17.1
resolution: "@vanilla-extract/css@npm:1.17.1" resolution: "@vanilla-extract/css@npm:1.17.1"
dependencies: dependencies: