Files
AFFiNE-Mirror/blocksuite/presets/src/editors/edgeless-editor.ts
T
2025-01-08 13:01:19 +00:00

105 lines
2.4 KiB
TypeScript

import { BlockStdScope, ShadowlessElement } from '@blocksuite/block-std';
import { EdgelessEditorBlockSpecs, ThemeProvider } from '@blocksuite/blocks';
import { SignalWatcher, WithDisposable } from '@blocksuite/global/utils';
import type { Store } from '@blocksuite/store';
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({
store: this.doc,
extensions: this.specs,
});
}
override async getUpdateComplete(): Promise<boolean> {
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`
<div class="affine-edgeless-viewport" data-theme=${theme}>
${guard([std], () => std.render())}
</div>
`;
}
override willUpdate(
changedProperties: Map<string | number | symbol, unknown>
) {
super.willUpdate(changedProperties);
if (changedProperties.has('doc')) {
this.std = new BlockStdScope({
store: this.doc,
extensions: this.specs,
});
}
}
@property({ attribute: false })
accessor doc!: Store;
@property({ attribute: false })
accessor editor!: TemplateResult;
@property({ attribute: false })
accessor specs = EdgelessEditorBlockSpecs;
@state()
accessor std!: BlockStdScope;
}
declare global {
interface HTMLElementTagNameMap {
'edgeless-editor': EdgelessEditor;
}
}