mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-02 01:49:51 +08:00
refactor(editor): move frame toolbar config and components to its package (#11084)
This commit is contained in:
@@ -1,11 +0,0 @@
|
||||
import type { MenuConfig } from '@blocksuite/affine-components/context-menu';
|
||||
import type { BlockComponent } from '@blocksuite/block-std';
|
||||
import type { GfxController } from '@blocksuite/block-std/gfx';
|
||||
|
||||
/**
|
||||
* Helper function to build a menu configuration for a tool in dense mode
|
||||
*/
|
||||
export type DenseMenuBuilder = (
|
||||
edgeless: BlockComponent,
|
||||
gfx: GfxController
|
||||
) => MenuConfig;
|
||||
+1
-2
@@ -1,14 +1,13 @@
|
||||
import { menu } from '@blocksuite/affine-components/context-menu';
|
||||
import { ConnectorMode } from '@blocksuite/affine-model';
|
||||
import { EditPropsStore } from '@blocksuite/affine-shared/services';
|
||||
import type { DenseMenuBuilder } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import {
|
||||
ConnectorCIcon,
|
||||
ConnectorEIcon,
|
||||
ConnectorLIcon,
|
||||
} from '@blocksuite/icons/lit';
|
||||
|
||||
import type { DenseMenuBuilder } from '../common/type.js';
|
||||
|
||||
export const buildConnectorDenseMenu: DenseMenuBuilder = (edgeless, gfx) => {
|
||||
const prevMode =
|
||||
edgeless.std.get(EditPropsStore).lastProps$.value.connector.mode;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
export const FrameConfig: {
|
||||
name: string;
|
||||
wh: [number, number];
|
||||
}[] = [
|
||||
{ name: '1:1', wh: [1200, 1200] },
|
||||
{ name: '4:3', wh: [1600, 1200] },
|
||||
{ name: '16:9', wh: [1600, 900] },
|
||||
{ name: '2:1', wh: [1600, 800] },
|
||||
];
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
import { EdgelessFrameManagerIdentifier } from '@blocksuite/affine-block-frame';
|
||||
import { menu } from '@blocksuite/affine-components/context-menu';
|
||||
import { FrameIcon } from '@blocksuite/icons/lit';
|
||||
|
||||
import type { DenseMenuBuilder } from '../common/type.js';
|
||||
import { FrameConfig } from './config.js';
|
||||
|
||||
export const buildFrameDenseMenu: DenseMenuBuilder = (edgeless, gfx) =>
|
||||
menu.subMenu({
|
||||
name: 'Frame',
|
||||
prefix: FrameIcon({ width: '20px', height: '20px' }),
|
||||
select: () => gfx.tool.setTool({ type: 'frame' }),
|
||||
isSelected: gfx.tool.currentToolName$.peek() === 'frame',
|
||||
options: {
|
||||
items: [
|
||||
menu.action({
|
||||
name: 'Custom',
|
||||
select: () => gfx.tool.setTool({ type: 'frame' }),
|
||||
}),
|
||||
...FrameConfig.map(config =>
|
||||
menu.action({
|
||||
name: `Slide ${config.name}`,
|
||||
select: () => {
|
||||
const frame = edgeless.std.get(EdgelessFrameManagerIdentifier);
|
||||
gfx.tool.setTool('default');
|
||||
frame.createFrameOnViewportCenter(config.wh);
|
||||
},
|
||||
})
|
||||
),
|
||||
],
|
||||
},
|
||||
});
|
||||
-103
@@ -1,103 +0,0 @@
|
||||
import { EdgelessFrameManagerIdentifier } from '@blocksuite/affine-block-frame';
|
||||
import { EdgelessToolbarToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
import { repeat } from 'lit/directives/repeat.js';
|
||||
|
||||
import { FrameConfig } from './config.js';
|
||||
|
||||
export class EdgelessFrameMenu extends EdgelessToolbarToolMixin(LitElement) {
|
||||
static override styles = css`
|
||||
:host {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
z-index: -1;
|
||||
}
|
||||
.menu-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.frame-add-button {
|
||||
width: 40px;
|
||||
height: 24px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--affine-border-color);
|
||||
color: var(--affine-text-primary-color);
|
||||
line-height: 20px;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.frame-add-button::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-radius: 3px;
|
||||
background: transparent;
|
||||
transition: background-color 0.23s ease;
|
||||
pointer-events: none;
|
||||
}
|
||||
.frame-add-button:hover::before {
|
||||
background: var(--affine-hover-color);
|
||||
}
|
||||
|
||||
.custom {
|
||||
width: 60px;
|
||||
background: var(--affine-hover-color);
|
||||
}
|
||||
|
||||
.divider {
|
||||
width: 1px;
|
||||
height: 20px;
|
||||
background: var(--affine-border-color);
|
||||
transform: scaleX(0.5);
|
||||
}
|
||||
`;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'frame';
|
||||
|
||||
get frameManager() {
|
||||
return this.edgeless.std.get(EdgelessFrameManagerIdentifier);
|
||||
}
|
||||
|
||||
override render() {
|
||||
const { gfx, frameManager } = this;
|
||||
return html`
|
||||
<edgeless-slide-menu .showNext=${false}>
|
||||
<div class="menu-content">
|
||||
<div class="frame-add-button custom">Custom</div>
|
||||
<div class="divider"></div>
|
||||
${repeat(
|
||||
FrameConfig,
|
||||
item => item.name,
|
||||
(item, index) => html`
|
||||
<div
|
||||
@click=${() => {
|
||||
gfx.tool.setTool('default');
|
||||
frameManager.createFrameOnViewportCenter(item.wh);
|
||||
}}
|
||||
class="frame-add-button ${index}"
|
||||
data-name="${item.name}"
|
||||
data-w="${item.wh[0]}"
|
||||
data-h="${item.wh[1]}"
|
||||
>
|
||||
${item.name}
|
||||
</div>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
</edgeless-slide-menu>
|
||||
`;
|
||||
}
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
import { QuickToolMixin } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import type { GfxToolsFullOptionValue } from '@blocksuite/block-std/gfx';
|
||||
import { FrameIcon } from '@blocksuite/icons/lit';
|
||||
import { css, html, LitElement } from 'lit';
|
||||
|
||||
export class EdgelessFrameToolButton extends QuickToolMixin(LitElement) {
|
||||
static override styles = css`
|
||||
:host {
|
||||
display: flex;
|
||||
}
|
||||
`;
|
||||
|
||||
override type: GfxToolsFullOptionValue['type'] = 'frame';
|
||||
|
||||
private _toggleFrameMenu() {
|
||||
if (this.tryDisposePopper()) return;
|
||||
|
||||
const menu = this.createPopper('edgeless-frame-menu', this);
|
||||
menu.element.edgeless = this.edgeless;
|
||||
}
|
||||
|
||||
override render() {
|
||||
const type = this.edgelessTool?.type;
|
||||
return html`
|
||||
<edgeless-tool-icon-button
|
||||
class="edgeless-frame-button"
|
||||
.tooltip=${this.popper
|
||||
? ''
|
||||
: html`<affine-tooltip-content-with-shortcut
|
||||
data-tip="${'Frame'}"
|
||||
data-shortcut="${'F'}"
|
||||
></affine-tooltip-content-with-shortcut>`}
|
||||
.tooltipOffset=${17}
|
||||
.iconSize=${'24px'}
|
||||
.active=${type === 'frame'}
|
||||
.iconContainerPadding=${6}
|
||||
@click=${() => {
|
||||
// don't update tool before toggling menu
|
||||
this._toggleFrameMenu();
|
||||
this.setEdgelessTool({ type: 'frame' });
|
||||
}}
|
||||
>
|
||||
${FrameIcon()}
|
||||
<toolbar-arrow-up-icon></toolbar-arrow-up-icon>
|
||||
</edgeless-tool-icon-button>
|
||||
`;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { menu } from '@blocksuite/affine-components/context-menu';
|
||||
import { LassoMode } from '@blocksuite/affine-shared/types';
|
||||
import type { DenseMenuBuilder } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
|
||||
import type { DenseMenuBuilder } from '../common/type.js';
|
||||
import { LassoFreeHandIcon, LassoPolygonalIcon } from './icons.js';
|
||||
|
||||
export const buildLassoDenseMenu: DenseMenuBuilder = (_, gfx) => {
|
||||
|
||||
+1
-2
@@ -2,8 +2,7 @@ import { insertLinkByQuickSearchCommand } from '@blocksuite/affine-block-bookmar
|
||||
import { menu } from '@blocksuite/affine-components/context-menu';
|
||||
import { LinkIcon } from '@blocksuite/affine-components/icons';
|
||||
import { TelemetryProvider } from '@blocksuite/affine-shared/services';
|
||||
|
||||
import type { DenseMenuBuilder } from '../common/type.js';
|
||||
import type { DenseMenuBuilder } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
|
||||
export const buildLinkDenseMenu: DenseMenuBuilder = edgeless =>
|
||||
menu.action({
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { frameQuickTool } from '@blocksuite/affine-block-frame';
|
||||
import { shapeSeniorTool } from '@blocksuite/affine-gfx-shape';
|
||||
import {
|
||||
QuickToolExtension,
|
||||
SeniorToolExtension,
|
||||
} from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
import { html } from 'lit';
|
||||
|
||||
import { buildFrameDenseMenu } from './frame/frame-dense-menu.js';
|
||||
import { buildLinkDenseMenu } from './link/link-dense-menu.js';
|
||||
|
||||
const defaultQuickTool = QuickToolExtension('default', ({ block }) => {
|
||||
@@ -16,17 +17,6 @@ const defaultQuickTool = QuickToolExtension('default', ({ block }) => {
|
||||
};
|
||||
});
|
||||
|
||||
const frameQuickTool = QuickToolExtension('frame', ({ block, gfx }) => {
|
||||
return {
|
||||
type: 'frame',
|
||||
content: html`<edgeless-frame-tool-button
|
||||
.edgeless=${block}
|
||||
></edgeless-frame-tool-button>`,
|
||||
menu: buildFrameDenseMenu(block, gfx),
|
||||
enable: !block.doc.readonly,
|
||||
};
|
||||
});
|
||||
|
||||
const connectorQuickTool = QuickToolExtension('connector', ({ block }) => {
|
||||
return {
|
||||
type: 'connector',
|
||||
@@ -69,19 +59,6 @@ const penSeniorTool = SeniorToolExtension('pen', ({ block }) => {
|
||||
};
|
||||
});
|
||||
|
||||
const shapeSeniorTool = SeniorToolExtension(
|
||||
'shape',
|
||||
({ block, toolbarContainer }) => {
|
||||
return {
|
||||
name: 'Shape',
|
||||
content: html`<edgeless-shape-tool-button
|
||||
.edgeless=${block}
|
||||
.toolbarContainer=${toolbarContainer}
|
||||
></edgeless-shape-tool-button>`,
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
const mindMapSeniorTool = SeniorToolExtension(
|
||||
'mindMap',
|
||||
({ block, toolbarContainer }) => {
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
import { EdgelessTextBlockModel } from '@blocksuite/affine-model';
|
||||
import { type ToolbarModuleConfig } from '@blocksuite/affine-shared/services';
|
||||
import { createTextActions } from '@blocksuite/affine-widget-edgeless-toolbar';
|
||||
|
||||
export const builtinEdgelessTextToolbarConfig = {
|
||||
// No need to adjust element bounds, which updates itself using ResizeObserver
|
||||
actions: createTextActions(EdgelessTextBlockModel, 'edgeless-text'),
|
||||
|
||||
when: ctx => ctx.getSurfaceModelsByType(EdgelessTextBlockModel).length > 0,
|
||||
} as const satisfies ToolbarModuleConfig;
|
||||
@@ -1,3 +1,4 @@
|
||||
import { edgelessTextToolbarConfig } from '@blocksuite/affine-block-edgeless-text';
|
||||
import { frameToolbarExtension } from '@blocksuite/affine-block-frame';
|
||||
import { textToolbarConfig } from '@blocksuite/affine-gfx-text';
|
||||
import { ToolbarModuleExtension } from '@blocksuite/affine-shared/services';
|
||||
@@ -6,7 +7,6 @@ import type { ExtensionType } from '@blocksuite/store';
|
||||
|
||||
import { builtinBrushToolbarConfig } from './brush';
|
||||
import { builtinConnectorToolbarConfig } from './connector';
|
||||
import { builtinEdgelessTextToolbarConfig } from './edgeless-text';
|
||||
import { builtinGroupToolbarConfig } from './group';
|
||||
import { builtinMindmapToolbarConfig } from './mindmap';
|
||||
import { builtinLockedToolbarConfig, builtinMiscToolbarConfig } from './misc';
|
||||
@@ -42,7 +42,7 @@ export const EdgelessElementToolbarExtension: ExtensionType[] = [
|
||||
|
||||
ToolbarModuleExtension({
|
||||
id: BlockFlavourIdentifier('affine:surface:edgeless-text'),
|
||||
config: builtinEdgelessTextToolbarConfig,
|
||||
config: edgelessTextToolbarConfig,
|
||||
}),
|
||||
|
||||
ToolbarModuleExtension({
|
||||
|
||||
@@ -36,8 +36,6 @@ import { EdgelessConnectorMenu } from './edgeless/components/toolbar/connector/c
|
||||
import { EdgelessConnectorToolButton } from './edgeless/components/toolbar/connector/connector-tool-button.js';
|
||||
import { EdgelessDefaultToolButton } from './edgeless/components/toolbar/default/default-tool-button.js';
|
||||
import { EdgelessEraserToolButton } from './edgeless/components/toolbar/eraser/eraser-tool-button.js';
|
||||
import { EdgelessFrameMenu } from './edgeless/components/toolbar/frame/frame-menu.js';
|
||||
import { EdgelessFrameToolButton } from './edgeless/components/toolbar/frame/frame-tool-button.js';
|
||||
import { EdgelessLassoToolButton } from './edgeless/components/toolbar/lasso/lasso-tool-button.js';
|
||||
import { EdgelessLinkToolButton } from './edgeless/components/toolbar/link/link-tool-button.js';
|
||||
import { MindMapPlaceholder } from './edgeless/components/toolbar/mindmap/mindmap-importing-placeholder.js';
|
||||
@@ -157,7 +155,6 @@ function registerEdgelessToolbarComponents() {
|
||||
'edgeless-eraser-tool-button',
|
||||
EdgelessEraserToolButton
|
||||
);
|
||||
customElements.define('edgeless-frame-tool-button', EdgelessFrameToolButton);
|
||||
customElements.define('edgeless-link-tool-button', EdgelessLinkToolButton);
|
||||
customElements.define('edgeless-lasso-tool-button', EdgelessLassoToolButton);
|
||||
customElements.define(
|
||||
@@ -170,7 +167,6 @@ function registerEdgelessToolbarComponents() {
|
||||
// Menus
|
||||
customElements.define('edgeless-brush-menu', EdgelessBrushMenu);
|
||||
customElements.define('edgeless-connector-menu', EdgelessConnectorMenu);
|
||||
customElements.define('edgeless-frame-menu', EdgelessFrameMenu);
|
||||
customElements.define('edgeless-mindmap-menu', EdgelessMindmapMenu);
|
||||
customElements.define('edgeless-note-menu', EdgelessNoteMenu);
|
||||
customElements.define('edgeless-slide-menu', EdgelessSlideMenu);
|
||||
@@ -301,8 +297,6 @@ declare global {
|
||||
'edgeless-connector-tool-button': EdgelessConnectorToolButton;
|
||||
'edgeless-default-tool-button': EdgelessDefaultToolButton;
|
||||
'edgeless-eraser-tool-button': EdgelessEraserToolButton;
|
||||
'edgeless-frame-menu': EdgelessFrameMenu;
|
||||
'edgeless-frame-tool-button': EdgelessFrameToolButton;
|
||||
'edgeless-lasso-tool-button': EdgelessLassoToolButton;
|
||||
'edgeless-link-tool-button': EdgelessLinkToolButton;
|
||||
'mindmap-import-placeholder': MindMapPlaceholder;
|
||||
|
||||
Reference in New Issue
Block a user