mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-23 04:51:49 +08:00
b8dcb85007
### 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.
119 lines
3.3 KiB
TypeScript
119 lines
3.3 KiB
TypeScript
import { DocModeProvider } from '@blocksuite/affine-shared/services';
|
|
import {
|
|
type EditorHost,
|
|
PropTypes,
|
|
requiredProperties,
|
|
ShadowlessElement,
|
|
} from '@blocksuite/block-std';
|
|
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
|
|
import { provide } from '@lit/context';
|
|
import { effect, signal } from '@preact/signals-core';
|
|
import { html, type PropertyValues } from 'lit';
|
|
import { property } from 'lit/decorators.js';
|
|
|
|
import { outlineSettingsKey, type TocContext, tocContext } from './config.js';
|
|
import * as styles from './outline-panel.css';
|
|
|
|
export const AFFINE_OUTLINE_PANEL = 'affine-outline-panel';
|
|
|
|
@requiredProperties({
|
|
editor: PropTypes.object,
|
|
})
|
|
export class OutlinePanel extends SignalWatcher(
|
|
WithDisposable(ShadowlessElement)
|
|
) {
|
|
private _getEditorMode(host: EditorHost) {
|
|
const docModeService = host.std.get(DocModeProvider);
|
|
const mode = docModeService.getEditorMode();
|
|
return mode;
|
|
}
|
|
|
|
private _setContext() {
|
|
this._context = {
|
|
editor$: signal(this.editor),
|
|
showIcons$: signal<boolean>(false),
|
|
enableSorting$: signal<boolean>(false),
|
|
fitPadding$: signal<number[]>(this.fitPadding),
|
|
};
|
|
|
|
this.disposables.add(
|
|
effect(() => {
|
|
const settingsString = localStorage.getItem(outlineSettingsKey);
|
|
const settings = settingsString ? JSON.parse(settingsString) : null;
|
|
|
|
if (settings) {
|
|
this._context.showIcons$.value = settings.showIcons;
|
|
}
|
|
|
|
const editor = this._context.editor$.value;
|
|
if (this._getEditorMode(editor) === 'edgeless') {
|
|
this._context.enableSorting$.value = true;
|
|
} else if (settings) {
|
|
this._context.enableSorting$.value = settings.enableSorting;
|
|
}
|
|
})
|
|
);
|
|
}
|
|
|
|
private _watchSettingsChange() {
|
|
this.disposables.add(
|
|
effect(() => {
|
|
if (this._getEditorMode(this._context.editor$.value) === 'edgeless')
|
|
return;
|
|
|
|
const showPreviewIcon = this._context.showIcons$.value;
|
|
const enableNotesSorting = this._context.enableSorting$.value;
|
|
localStorage.setItem(
|
|
outlineSettingsKey,
|
|
JSON.stringify({
|
|
showIcons: showPreviewIcon,
|
|
enableSorting: enableNotesSorting,
|
|
})
|
|
);
|
|
})
|
|
);
|
|
}
|
|
|
|
override connectedCallback() {
|
|
super.connectedCallback();
|
|
this.classList.add(styles.outlinePanel);
|
|
|
|
this._setContext();
|
|
this._watchSettingsChange();
|
|
}
|
|
|
|
override willUpdate(changedProperties: PropertyValues<this>): void {
|
|
if (changedProperties.has('editor')) {
|
|
this._context.editor$.value = this.editor;
|
|
}
|
|
if (changedProperties.has('fitPadding')) {
|
|
this._context.fitPadding$.value = this.fitPadding;
|
|
}
|
|
}
|
|
|
|
override render() {
|
|
if (!this.editor) return;
|
|
|
|
return html`
|
|
<affine-outline-panel-header></affine-outline-panel-header>
|
|
<affine-outline-panel-body> </affine-outline-panel-body>
|
|
<affine-outline-notice></affine-outline-notice>
|
|
`;
|
|
}
|
|
|
|
@provide({ context: tocContext })
|
|
private accessor _context!: TocContext;
|
|
|
|
@property({ attribute: false })
|
|
accessor editor!: EditorHost;
|
|
|
|
@property({ attribute: false })
|
|
accessor fitPadding!: number[];
|
|
}
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
[AFFINE_OUTLINE_PANEL]: OutlinePanel;
|
|
}
|
|
}
|