refactor(editor): extract frame block (#9322)

This commit is contained in:
Saul-Mirone
2024-12-26 04:45:11 +00:00
parent fad0237d94
commit fc5999a482
16 changed files with 130 additions and 14 deletions

View File

@@ -0,0 +1,42 @@
{
"name": "@blocksuite/affine-block-frame",
"description": "Frame block for BlockSuite.",
"type": "module",
"scripts": {
"build": "tsc",
"test:unit": "nx vite:test --run --passWithNoTests",
"test:unit:coverage": "nx vite:test --run --coverage",
"test:e2e": "playwright test"
},
"sideEffects": false,
"keywords": [],
"author": "toeverything",
"license": "MIT",
"dependencies": {
"@blocksuite/affine-components": "workspace:*",
"@blocksuite/affine-model": "workspace:*",
"@blocksuite/affine-shared": "workspace:*",
"@blocksuite/block-std": "workspace:*",
"@blocksuite/global": "workspace:*",
"@blocksuite/inline": "workspace:*",
"@blocksuite/store": "workspace:*",
"@floating-ui/dom": "^1.6.10",
"@lit/context": "^1.1.2",
"@preact/signals-core": "^1.8.0",
"@toeverything/theme": "^1.1.1",
"@types/mdast": "^4.0.4",
"lit": "^3.2.0",
"minimatch": "^10.0.1",
"zod": "^3.23.8"
},
"exports": {
".": "./src/index.ts",
"./effects": "./src/effects.ts"
},
"files": [
"src",
"dist",
"!src/__tests__",
"!dist/__tests__"
]
}

View File

@@ -0,0 +1,5 @@
import { FrameBlockComponent } from './frame-block';
export function effects() {
customElements.define('affine-frame', FrameBlockComponent);
}

View File

@@ -0,0 +1,90 @@
import type { FrameBlockModel } from '@blocksuite/affine-model';
import { ThemeProvider } from '@blocksuite/affine-shared/services';
import { GfxBlockComponent } from '@blocksuite/block-std';
import { Bound } from '@blocksuite/global/utils';
import { cssVarV2 } from '@toeverything/theme/v2';
import { html } from 'lit';
import { state } from 'lit/decorators.js';
import { styleMap } from 'lit/directives/style-map.js';
export class FrameBlockComponent extends GfxBlockComponent<FrameBlockModel> {
override connectedCallback() {
super.connectedCallback();
this._disposables.add(
this.doc.slots.blockUpdated.on(({ type, id }) => {
if (id === this.model.id && type === 'update') {
this.requestUpdate();
}
})
);
this._disposables.add(
this.gfx.viewport.viewportUpdated.on(() => {
this.requestUpdate();
})
);
}
/**
* Due to potentially very large frame sizes, CSS scaling can cause iOS Safari to crash.
* To mitigate this issue, we combine size calculations within the rendering rect.
*/
override getCSSTransform(): string {
return '';
}
override getRenderingRect() {
const viewport = this.gfx.viewport;
const { translateX, translateY, zoom } = viewport;
const { xywh, rotate } = this.model;
const bound = Bound.deserialize(xywh);
const scaledX = bound.x * zoom + translateX;
const scaledY = bound.y * zoom + translateY;
return {
x: scaledX,
y: scaledY,
w: bound.w * zoom,
h: bound.h * zoom,
rotate,
zIndex: this.toZIndex(),
};
}
override renderGfxBlock() {
const { model, showBorder, std } = this;
const backgroundColor = std
.get(ThemeProvider)
.generateColorProperty(model.background, '--affine-platte-transparent');
const _isNavigator =
this.gfx.tool.currentToolName$.value === 'frameNavigator';
const frameIndex = this.gfx.layer.getZIndex(model);
return html`
<div
class="affine-frame-container"
style=${styleMap({
zIndex: `${frameIndex}`,
backgroundColor,
height: '100%',
width: '100%',
borderRadius: '2px',
border:
_isNavigator || !showBorder
? 'none'
: `1px solid ${cssVarV2('edgeless/frame/border/default')}`,
})}
></div>
`;
}
@state()
accessor showBorder = true;
}
declare global {
interface HTMLElementTagNameMap {
'affine-frame': FrameBlockComponent;
}
}

View File

@@ -0,0 +1,6 @@
import { BlockViewExtension, type ExtensionType } from '@blocksuite/block-std';
import { literal } from 'lit/static-html.js';
export const FrameBlockSpec: ExtensionType[] = [
BlockViewExtension('affine:frame', literal`affine-frame`),
];

View File

@@ -0,0 +1,2 @@
export * from './frame-block.js';
export * from './frame-spec.js';

View File

@@ -0,0 +1,32 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src/",
"outDir": "./dist/",
"noEmit": false
},
"include": ["./src"],
"references": [
{
"path": "../../framework/global"
},
{
"path": "../../framework/store"
},
{
"path": "../../framework/block-std"
},
{
"path": "../../framework/inline"
},
{
"path": "../model"
},
{
"path": "../components"
},
{
"path": "../shared"
}
]
}