Skip to content

Commit

Permalink
feat(playground): add an adpater panel to playground (#8841)
Browse files Browse the repository at this point in the history
  • Loading branch information
donteatfriedrice committed Dec 3, 2024
1 parent bbf0a22 commit 27f7f73
Show file tree
Hide file tree
Showing 2 changed files with 222 additions and 0 deletions.
198 changes: 198 additions & 0 deletions packages/playground/apps/_common/components/adapters-panel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import type { AffineEditorContainer } from '@blocksuite/presets';
import type SlTabPanel from '@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js';

import { ShadowlessElement } from '@blocksuite/block-std';
import '@shoelace-style/shoelace/dist/components/tab-panel/tab-panel.js';
import {
docLinkBaseURLMiddleware,
HtmlAdapter,
MarkdownAdapter,
PlainTextAdapter,
titleMiddleware,
} from '@blocksuite/blocks';
import { WithDisposable } from '@blocksuite/global/utils';
import { type DocSnapshot, Job } from '@blocksuite/store';
import { effect } from '@preact/signals-core';
import { css, html, type PropertyValues } from 'lit';
import { customElement, property, query, state } from 'lit/decorators.js';

@customElement('adapters-panel')
export class AdaptersPanel extends WithDisposable(ShadowlessElement) {
static override styles = css`
adapters-panel {
width: 30vw;
}
.adapters-container {
border: 1px solid var(--affine-border-color, #e3e2e4);
background-color: var(--affine-background-primary-color);
box-sizing: border-box;
position: relative;
}
.adapter-container {
padding: 0px 16px;
width: 100%;
height: calc(100vh - 80px);
white-space: pre-wrap;
color: var(--affine-text-primary-color);
overflow: auto;
}
.update-button {
position: absolute;
top: 8px;
right: 12px;
padding: 8px 12px;
border-radius: 4px;
font-size: 12px;
font-weight: 500;
cursor: pointer;
border: 1px solid var(--affine-border-color);
font-family: var(--affine-font-family);
color: var(--affine-text-primary-color);
background-color: var(--affine-background-primary-color);
}
.update-button:hover {
background-color: var(--affine-hover-color);
}
`;

get doc() {
return this.editor.doc;
}

private _createJob() {
return new Job({
collection: this.doc.collection,
middlewares: [docLinkBaseURLMiddleware, titleMiddleware],
});
}

private async _getDocSnapshot() {
const job = this._createJob();
const result = await job.docToSnapshot(this.doc);
return result;
}

private async _getHtmlContent() {
const job = this._createJob();
const htmlAdapter = new HtmlAdapter(job);
const result = await htmlAdapter.fromDoc(this.doc);
return result?.file;
}

private async _getMarkdownContent() {
const job = this._createJob();
const markdownAdapter = new MarkdownAdapter(job);
const result = await markdownAdapter.fromDoc(this.doc);
return result?.file;
}

private async _getPlainTextContent() {
const job = this._createJob();
const plainTextAdapter = new PlainTextAdapter(job);
const result = await plainTextAdapter.fromDoc(this.doc);
return result?.file;
}

private async _handleTabShow(name: string) {
switch (name) {
case 'markdown':
this._markdownContent = (await this._getMarkdownContent()) || '';
break;
case 'html':
this._htmlContent = (await this._getHtmlContent()) || '';
break;
case 'plaintext':
this._plainTextContent = (await this._getPlainTextContent()) || '';
break;
case 'snapshot':
this._docSnapshot = (await this._getDocSnapshot()) || null;
break;
}
}

private async _updateActiveTabContent() {
if (!this._activeTab) return;
const activeTabName = this._activeTab.name;
await this._handleTabShow(activeTabName);
}

override firstUpdated() {
this.disposables.add(
effect(() => {
const doc = this.doc;
if (doc) {
this._updateActiveTabContent().catch(console.error);
}
})
);
}

override render() {
const snapshotString = this._docSnapshot
? JSON.stringify(this._docSnapshot, null, 4)
: '';
return html`
<div class="adapters-container">
<sl-tab-group
activation="auto"
@sl-tab-show=${(e: CustomEvent) => this._handleTabShow(e.detail.name)}
>
<sl-tab slot="nav" panel="markdown">Markdown</sl-tab>
<sl-tab slot="nav" panel="plaintext">PlainText</sl-tab>
<sl-tab slot="nav" panel="html">HTML</sl-tab>
<sl-tab slot="nav" panel="snapshot">Snapshot</sl-tab>
<sl-tab-panel name="markdown">
<div class="adapter-container">${this._markdownContent}</div>
</sl-tab-panel>
<sl-tab-panel name="html">
<div class="adapter-container">${this._htmlContent}</div>
</sl-tab-panel>
<sl-tab-panel name="plaintext">
<div class="adapter-container">${this._plainTextContent}</div>
</sl-tab-panel>
<sl-tab-panel name="snapshot">
<div class="adapter-container">${snapshotString}</div>
</sl-tab-panel>
</sl-tab-group>
<sl-tooltip content="Update Adapter Content" placement="left" hoist>
<div class="update-button" @click="${this._updateActiveTabContent}">
Update
</div>
</sl-tooltip>
</div>
`;
}

override willUpdate(_changedProperties: PropertyValues) {
if (_changedProperties.has('editor')) {
requestIdleCallback(() => {
this._updateActiveTabContent().catch(console.error);
});
}
}

@query('sl-tab-panel[active]')
private accessor _activeTab!: SlTabPanel;

@state()
private accessor _docSnapshot: DocSnapshot | null = null;

@state()
private accessor _htmlContent = '';

@state()
private accessor _markdownContent = '';

@state()
private accessor _plainTextContent = '';

@property({ attribute: false })
accessor editor!: AffineEditorContainer;
}

declare global {
interface HTMLElementTagNameMap {
'adapters-panel': AdaptersPanel;
}
}
24 changes: 24 additions & 0 deletions packages/playground/apps/_common/components/debug-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import type { SidePanel } from './side-panel.js';
import { mockEdgelessTheme } from '../mock-services.js';
import './left-side-panel.js';
import './side-panel.js';
import { AdaptersPanel } from './adapters-panel.js';

const basePath =
'https://cdn.jsdelivr.net/npm/@shoelace-style/[email protected]/dist';
Expand Down Expand Up @@ -505,6 +506,26 @@ export class DebugMenu extends ShadowlessElement {
this._hasOffset = !this._hasOffset;
}

private _toggleAdaptersPanel() {
const app = document.querySelector('#app');
if (!app) return;

const currentAdaptersPanel = app.querySelector('adapters-panel');
if (currentAdaptersPanel) {
currentAdaptersPanel.remove();
(app as HTMLElement).style.display = 'block';
this.editor.style.width = '100%';
this.editor.style.flex = '';
return;
}

const adaptersPanel = new AdaptersPanel();
adaptersPanel.editor = this.editor;
app.append(adaptersPanel);
this.editor.style.flex = '1';
(app as HTMLElement).style.display = 'flex';
}

private _toggleCommentPanel() {
document.body.append(this.commentPanel);
}
Expand Down Expand Up @@ -796,6 +817,9 @@ export class DebugMenu extends ShadowlessElement {
<sl-menu-item @click="${this._toggleMultipleEditors}">
Toggle Multiple Editors
</sl-menu-item>
<sl-menu-item @click="${this._toggleAdaptersPanel}">
Toggle Adapters Panel
</sl-menu-item>
</sl-menu>
</sl-dropdown>
Expand Down

0 comments on commit 27f7f73

Please sign in to comment.