mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-11 15:16:28 +08:00
feat(editor): support preview mode in code block (#11805)
<!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced a preview mode for code blocks, allowing users to toggle between code and rendered previews (e.g., HTML output) directly within the editor. - Added a preview toggle button to the code block toolbar for supported languages. - Enabled dynamic rendering of code block previews using a shared WebContainer, allowing live HTML previews in an embedded iframe. - Added HTML preview support with loading and error states for enhanced user feedback. - Integrated the preview feature as a view extension provider for seamless framework support. - **Bug Fixes** - Improved toolbar layout and button alignment for a cleaner user interface. - **Tests** - Added end-to-end tests to verify the new code block preview functionality and language switching behavior. - **Chores** - Updated development server configuration to include enhanced security headers. - Added a new runtime dependency for WebContainer support. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
@@ -26,11 +26,13 @@ import { computed, effect, type Signal, signal } from '@preact/signals-core';
|
||||
import { html, nothing, type TemplateResult } from 'lit';
|
||||
import { query } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { styleMap } from 'lit/directives/style-map.js';
|
||||
import { bundledLanguagesInfo, type ThemedToken } from 'shiki';
|
||||
|
||||
import { CodeBlockConfigExtension } from './code-block-config.js';
|
||||
import { CodeBlockInlineManagerExtension } from './code-block-inline.js';
|
||||
import { CodeBlockHighlighter } from './code-block-service.js';
|
||||
import { CodeBlockPreviewIdentifier } from './code-preview-extension.js';
|
||||
import { codeBlockStyles } from './styles.js';
|
||||
|
||||
export class CodeBlockComponent extends CaptionedBlockComponent<CodeBlockModel> {
|
||||
@@ -384,6 +386,12 @@ export class CodeBlockComponent extends CaptionedBlockComponent<CodeBlockModel>
|
||||
this.std.getOptional(CodeBlockConfigExtension.identifier)
|
||||
?.showLineNumbers ?? true;
|
||||
|
||||
const preview = !!this.model.props.preview;
|
||||
const previewContext = this.std.getOptional(
|
||||
CodeBlockPreviewIdentifier(this.model.props.language ?? '')
|
||||
);
|
||||
const shouldRenderPreview = preview && previewContext;
|
||||
|
||||
return html`
|
||||
<div
|
||||
class=${classMap({
|
||||
@@ -393,6 +401,9 @@ export class CodeBlockComponent extends CaptionedBlockComponent<CodeBlockModel>
|
||||
})}
|
||||
>
|
||||
<rich-text
|
||||
style=${styleMap({
|
||||
display: shouldRenderPreview ? 'none' : undefined,
|
||||
})}
|
||||
.yText=${this.model.props.text.yText}
|
||||
.inlineEventSource=${this.topContenteditableElement ?? nothing}
|
||||
.undoManager=${this.doc.history}
|
||||
@@ -416,7 +427,15 @@ export class CodeBlockComponent extends CaptionedBlockComponent<CodeBlockModel>
|
||||
: undefined}
|
||||
>
|
||||
</rich-text>
|
||||
|
||||
<div
|
||||
style=${styleMap({
|
||||
display: shouldRenderPreview ? undefined : 'none',
|
||||
})}
|
||||
contenteditable="false"
|
||||
class="affine-code-block-preview"
|
||||
>
|
||||
${previewContext?.renderer(this.model)}
|
||||
</div>
|
||||
${this.renderChildren(this.model)} ${Object.values(this.widgets)}
|
||||
</div>
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user