import type { Doc } from '@blocksuite/store'; import { BlockStdScope, ShadowlessElement } from '@blocksuite/block-std'; import { EdgelessEditorBlockSpecs, ThemeProvider } from '@blocksuite/blocks'; import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils'; import { css, html, nothing, type TemplateResult } from 'lit'; import { property, state } from 'lit/decorators.js'; import { guard } from 'lit/directives/guard.js'; export class EdgelessEditor extends SignalWatcher( WithDisposable(ShadowlessElement) ) { static override styles = css` edgeless-editor { font-family: var(--affine-font-family); background: var(--affine-background-primary-color); } edgeless-editor * { box-sizing: border-box; } @media print { edgeless-editor { height: auto; } } .affine-edgeless-viewport { display: block; height: 100%; position: relative; overflow: clip; container-name: viewport; container-type: inline-size; } `; get host() { try { return this.std.host; } catch { return null; } } override connectedCallback() { super.connectedCallback(); this._disposables.add( this.doc.slots.rootAdded.on(() => this.requestUpdate()) ); this.std = new BlockStdScope({ doc: this.doc, extensions: this.specs, }); } override async getUpdateComplete(): Promise { const result = await super.getUpdateComplete(); await this.host?.updateComplete; return result; } override render() { if (!this.doc.root) return nothing; const std = this.std; const theme = std.get(ThemeProvider).edgeless$.value; return html`
${guard([std], () => std.render())}
`; } override willUpdate( changedProperties: Map ) { super.willUpdate(changedProperties); if (changedProperties.has('doc')) { this.std = new BlockStdScope({ doc: this.doc, extensions: this.specs, }); } } @property({ attribute: false }) accessor doc!: Doc; @property({ attribute: false }) accessor editor!: TemplateResult; @property({ attribute: false }) accessor specs = EdgelessEditorBlockSpecs; @state() accessor std!: BlockStdScope; } declare global { interface HTMLElementTagNameMap { 'edgeless-editor': EdgelessEditor; } }