feat(core): frame editor settings (#9970)

Co-authored-by: L-Sun <zover.v@gmail.com>
Co-authored-by: Mirone <Saul-Mirone@outlook.com>
This commit is contained in:
Oleg
2025-02-10 08:23:32 +01:00
committed by GitHub
parent 03b806384c
commit d4f0c53a0c
14 changed files with 211 additions and 84 deletions

View File

@@ -0,0 +1,61 @@
{
"type": "page",
"meta": {
"id": "gIUEIHL42k",
"title": "FrameDoc",
"createDate": 1738858597791,
"tags": []
},
"blocks": {
"type": "block",
"id": "MCYCDPz_QH",
"flavour": "affine:page",
"version": 2,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "FrameDoc"
}
]
}
},
"children": [
{
"type": "block",
"id": "I_s0rS2Pbl",
"flavour": "affine:surface",
"version": 5,
"props": {
"elements": {}
},
"children": [
{
"type": "block",
"id": "mHE8GI9UWx",
"flavour": "affine:frame",
"version": 1,
"props": {
"title": {
"$blocksuite:internal:text$": true,
"delta": [
{
"insert": "Frame 1"
}
]
},
"background": "transparent",
"xywh": "[-186.37939453125,-68.03814697265625,375.8616943359375,114.787109375]",
"index": "Zz",
"childElementIds": {},
"presentationIndex": "a00zHdtY37OLhj7JOhCr9ywYQXy1SbAI6kM",
"lockedBySelf": false
},
"children": []
}
]
}
]
}
}

View File

@@ -24,7 +24,8 @@ export type DocName =
| 'flow'
| 'text'
| 'connector'
| 'mindmap';
| 'mindmap'
| 'frame';
const docMap = new Map<DocName, Promise<Store | undefined>>();
@@ -40,6 +41,10 @@ async function loadShape() {
return (await import('./shape.json')).default;
}
async function loadFrame() {
return (await import('./frame.json')).default;
}
async function loadFlow() {
return (await import('./flow.json')).default;
}
@@ -60,6 +65,7 @@ const loaders = {
note: loadNote,
pen: loadPen,
shape: loadShape,
frame: loadFrame,
flow: loadFlow,
text: loadText,
connector: loadConnector,

View File

@@ -2,6 +2,7 @@ import { SettingWrapper } from '@affine/component/setting-components';
import { useI18n } from '@affine/i18n';
import { ConnectorSettings } from './connector';
import { FrameSettings } from './frame';
import { GeneralEdgelessSetting } from './general';
import { MindMapSettings } from './mind-map';
import { NoteSettings } from './note';
@@ -17,6 +18,7 @@ export const Edgeless = () => {
<NoteSettings />
<TextSettings />
<ShapeSettings />
<FrameSettings />
<ConnectorSettings />
<PenSettings />
<MindMapSettings />

View File

@@ -0,0 +1,88 @@
import { MenuItem, MenuTrigger } from '@affine/component';
import { SettingRow } from '@affine/component/setting-components';
import { EditorSettingService } from '@affine/core/modules/editor-setting';
import { useI18n } from '@affine/i18n';
import { DefaultTheme } from '@blocksuite/affine/blocks';
import type { Store } from '@blocksuite/affine/store';
import { useFramework, useLiveData } from '@toeverything/infra';
import { isEqual } from 'lodash-es';
import { useCallback, useMemo } from 'react';
import { DropdownMenu } from '../menu';
import { menuTrigger } from '../style.css';
import { usePalettes } from '../utils';
import { Point } from './point';
import { EdgelessSnapshot } from './snapshot';
export const FrameSettings = () => {
const t = useI18n();
const framework = useFramework();
const { editorSetting } = framework.get(EditorSettingService);
const settings = useLiveData(editorSetting.settings$);
const { palettes, getCurrentColor } = usePalettes(
[
{ key: 'Transparent', value: DefaultTheme.transparent },
...DefaultTheme.FillColorPalettes,
],
DefaultTheme.transparent
);
const { background } = settings['affine:frame'];
const currentColor = useMemo(() => {
return getCurrentColor(background);
}, [getCurrentColor, background]);
const colorItems = useMemo(() => {
return palettes.map(({ key, value, resolvedValue }) => {
const handler = () => {
editorSetting.set('affine:frame', { background: value });
};
const isSelected = isEqual(background, value);
return (
<MenuItem
key={key}
onSelect={handler}
selected={isSelected}
prefix={<Point color={resolvedValue} />}
>
{key}
</MenuItem>
);
});
}, [editorSetting, background, palettes]);
const getElements = useCallback((doc: Store) => {
return doc.getBlocksByFlavour('affine:frame') || [];
}, []);
return (
<>
<EdgelessSnapshot
title={t['com.affine.settings.editorSettings.edgeless.frame']()}
docName="frame"
keyName="affine:frame"
getElements={getElements}
/>
<SettingRow
name={t[
'com.affine.settings.editorSettings.edgeless.frame.background'
]()}
desc={''}
>
{currentColor ? (
<DropdownMenu
items={colorItems}
trigger={
<MenuTrigger
className={menuTrigger}
prefix={<Point color={currentColor.resolvedValue} />}
>
{currentColor.key}
</MenuTrigger>
}
/>
) : null}
</SettingRow>
</>
);
};

View File

@@ -115,7 +115,8 @@ export const EdgelessSnapshot = (props: Props) => {
doc.readonly = false;
edgelessBlock.editorViewportSelector = 'ref-viewport';
const frame = getFrameBlock(doc);
if (frame) {
if (frame && docName !== 'frame') {
// docName with value 'frame' shouldn't be deleted, it is a part of frame settings
boundMap.set(docName, Bound.deserialize(frame.xywh));
doc.deleteBlock(frame);
}