mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-18 18:46:19 +08:00
feat(core): add actions to editor settings (#8030)
# What Changed? - Add actions of following edgeless-elements editor settings: - note - connector - edgeless text - pen
This commit is contained in:
-183
@@ -1,183 +0,0 @@
|
||||
import {
|
||||
Menu,
|
||||
MenuItem,
|
||||
MenuTrigger,
|
||||
RadioGroup,
|
||||
type RadioItem,
|
||||
Slider,
|
||||
} from '@affine/component';
|
||||
import { SettingRow } from '@affine/component/setting-components';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useMemo, useState } from 'react';
|
||||
|
||||
import { menuTrigger, settingWrapper } from '../style.css';
|
||||
import { EdgelessSnapshot } from './snapshot';
|
||||
|
||||
export const ConnecterSettings = () => {
|
||||
const t = useI18n();
|
||||
|
||||
const [connecterStyle, setConnecterStyle] = useState<'general' | 'scribbled'>(
|
||||
'general'
|
||||
);
|
||||
const [connectorShape, setConnectorShape] = useState<
|
||||
'elbowed' | 'curve' | 'straight'
|
||||
>('elbowed');
|
||||
const [borderStyle, setBorderStyle] = useState<'solid' | 'dash'>('solid');
|
||||
const [borderThickness, setBorderThickness] = useState<number[]>([3]);
|
||||
|
||||
const connecterStyleItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: 'general',
|
||||
label: t['com.affine.settings.editorSettings.edgeless.style.general'](),
|
||||
},
|
||||
{
|
||||
value: 'scribbled',
|
||||
label:
|
||||
t['com.affine.settings.editorSettings.edgeless.style.scribbled'](),
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
const connecterShapeItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: 'elbowed',
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.connector-shape.elbowed'
|
||||
](),
|
||||
},
|
||||
{
|
||||
value: 'curve',
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.connector-shape.curve'
|
||||
](),
|
||||
},
|
||||
{
|
||||
value: 'straight',
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.connector-shape.straight'
|
||||
](),
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
const borderStyleItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: 'solid',
|
||||
label:
|
||||
t['com.affine.settings.editorSettings.edgeless.note.border.solid'](),
|
||||
},
|
||||
{
|
||||
value: 'dash',
|
||||
label:
|
||||
t['com.affine.settings.editorSettings.edgeless.note.border.dash'](),
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<EdgelessSnapshot
|
||||
title={t['com.affine.settings.editorSettings.edgeless.connecter']()}
|
||||
option={['mock-option']}
|
||||
type="mock-type"
|
||||
/>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.color'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>Grey</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
Grey
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t['com.affine.settings.editorSettings.edgeless.style']()}
|
||||
desc={''}
|
||||
>
|
||||
<RadioGroup
|
||||
items={connecterStyleItems}
|
||||
value={connecterStyle}
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
onChange={setConnecterStyle}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.connector-shape'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<RadioGroup
|
||||
items={connecterShapeItems}
|
||||
value={connectorShape}
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
onChange={setConnectorShape}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.border-style'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<RadioGroup
|
||||
items={borderStyleItems}
|
||||
value={borderStyle}
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
onChange={setBorderStyle}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.border-thickness'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Slider
|
||||
value={borderThickness}
|
||||
onValueChange={setBorderThickness}
|
||||
min={1}
|
||||
max={5}
|
||||
step={1}
|
||||
nodes={[1, 2, 3, 4, 5]}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.start-endpoint'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>None</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
None
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.end-endpoint'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>Arrow</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
Arrow
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
import {
|
||||
Menu,
|
||||
MenuItem,
|
||||
MenuTrigger,
|
||||
RadioGroup,
|
||||
type RadioItem,
|
||||
Slider,
|
||||
} from '@affine/component';
|
||||
import { SettingRow } from '@affine/component/setting-components';
|
||||
import { EditorSettingService } from '@affine/core/modules/editor-settting';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import {
|
||||
ConnectorMode,
|
||||
LineColor,
|
||||
PointStyle,
|
||||
StrokeStyle,
|
||||
} from '@blocksuite/blocks';
|
||||
import { useFramework, useLiveData } from '@toeverything/infra';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { menuTrigger, settingWrapper } from '../style.css';
|
||||
import { EdgelessSnapshot } from './snapshot';
|
||||
|
||||
enum ConnecterStyle {
|
||||
General = 'general',
|
||||
Scribbled = 'scribbled',
|
||||
}
|
||||
|
||||
export const ConnectorSettings = () => {
|
||||
const t = useI18n();
|
||||
const framework = useFramework();
|
||||
const { editorSetting } = framework.get(EditorSettingService);
|
||||
const settings = useLiveData(editorSetting.settings$);
|
||||
|
||||
const connecterStyleItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: ConnecterStyle.General,
|
||||
label: t['com.affine.settings.editorSettings.edgeless.style.general'](),
|
||||
},
|
||||
{
|
||||
value: ConnecterStyle.Scribbled,
|
||||
label:
|
||||
t['com.affine.settings.editorSettings.edgeless.style.scribbled'](),
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
const connecterStyle: ConnecterStyle = settings.connector.rough
|
||||
? ConnecterStyle.Scribbled
|
||||
: ConnecterStyle.General;
|
||||
const setConnecterStyle = useCallback(
|
||||
(value: ConnecterStyle) => {
|
||||
const isRough = value === ConnecterStyle.Scribbled;
|
||||
editorSetting.set('connector', {
|
||||
rough: isRough,
|
||||
});
|
||||
},
|
||||
[editorSetting]
|
||||
);
|
||||
|
||||
const connectorShapeItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: ConnectorMode.Orthogonal as any,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.connector-shape.elbowed'
|
||||
](),
|
||||
},
|
||||
{
|
||||
value: ConnectorMode.Curve as any,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.connector-shape.curve'
|
||||
](),
|
||||
},
|
||||
{
|
||||
value: ConnectorMode.Straight as any,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.connector-shape.straight'
|
||||
](),
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
const connectorShape: ConnectorMode = settings.connector.mode;
|
||||
const setConnectorShape = useCallback(
|
||||
(value: ConnectorMode) => {
|
||||
editorSetting.set('connector', {
|
||||
mode: value,
|
||||
});
|
||||
},
|
||||
[editorSetting]
|
||||
);
|
||||
|
||||
const borderStyleItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: StrokeStyle.Solid,
|
||||
label:
|
||||
t['com.affine.settings.editorSettings.edgeless.note.border.solid'](),
|
||||
},
|
||||
{
|
||||
value: StrokeStyle.Dash,
|
||||
label:
|
||||
t['com.affine.settings.editorSettings.edgeless.note.border.dash'](),
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
const borderStyle: StrokeStyle = settings.connector.strokeStyle;
|
||||
const setBorderStyle = useCallback(
|
||||
(value: StrokeStyle) => {
|
||||
editorSetting.set('connector', {
|
||||
strokeStyle: value,
|
||||
});
|
||||
},
|
||||
[editorSetting]
|
||||
);
|
||||
|
||||
const borderThickness = settings.connector.strokeWidth;
|
||||
const setBorderThickness = useCallback(
|
||||
(value: number[]) => {
|
||||
editorSetting.set('connector', {
|
||||
strokeWidth: value[0],
|
||||
});
|
||||
},
|
||||
[editorSetting]
|
||||
);
|
||||
|
||||
const colorItems = useMemo(() => {
|
||||
const { stroke } = settings.connector;
|
||||
return Object.entries(LineColor).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('connector', { stroke: value });
|
||||
};
|
||||
const isSelected = stroke === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
const startEndPointItems = useMemo(() => {
|
||||
const { frontEndpointStyle } = settings.connector;
|
||||
return Object.entries(PointStyle).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('connector', { frontEndpointStyle: value });
|
||||
};
|
||||
const isSelected = frontEndpointStyle === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
const endEndPointItems = useMemo(() => {
|
||||
const { rearEndpointStyle } = settings.connector;
|
||||
return Object.entries(PointStyle).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('connector', { rearEndpointStyle: value });
|
||||
};
|
||||
const isSelected = rearEndpointStyle === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EdgelessSnapshot
|
||||
title={t['com.affine.settings.editorSettings.edgeless.connecter']()}
|
||||
option={['mock-option']}
|
||||
type="mock-type"
|
||||
/>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.color'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={colorItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{String(settings.connector.stroke)}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t['com.affine.settings.editorSettings.edgeless.style']()}
|
||||
desc={''}
|
||||
>
|
||||
<RadioGroup
|
||||
items={connecterStyleItems}
|
||||
value={connecterStyle}
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
onChange={setConnecterStyle}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.connector-shape'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<RadioGroup
|
||||
items={connectorShapeItems}
|
||||
value={connectorShape}
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
onChange={setConnectorShape}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.border-style'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<RadioGroup
|
||||
items={borderStyleItems}
|
||||
value={borderStyle}
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
onChange={setBorderStyle}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.border-thickness'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Slider
|
||||
value={[borderThickness]}
|
||||
onValueChange={setBorderThickness}
|
||||
min={2}
|
||||
max={12}
|
||||
step={2}
|
||||
nodes={[2, 4, 6, 8, 10, 12]}
|
||||
/>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.start-endpoint'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={startEndPointItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{String(settings.connector.frontEndpointStyle)}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.connecter.end-endpoint'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={endEndPointItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{String(settings.connector.rearEndpointStyle)}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { SettingWrapper } from '@affine/component/setting-components';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
|
||||
import { ConnecterSettings } from './connecter';
|
||||
import { ConnectorSettings } from './connector';
|
||||
import { MindMapSettings } from './mind-map';
|
||||
import { NoteSettings } from './note';
|
||||
import { PenSettings } from './pen';
|
||||
@@ -15,7 +15,7 @@ export const Edgeless = () => {
|
||||
<NoteSettings />
|
||||
<TextSettings />
|
||||
<ShapeSettings />
|
||||
<ConnecterSettings />
|
||||
<ConnectorSettings />
|
||||
<PenSettings />
|
||||
<MindMapSettings />
|
||||
</SettingWrapper>
|
||||
|
||||
+123
-23
@@ -7,39 +7,139 @@ import {
|
||||
Slider,
|
||||
} from '@affine/component';
|
||||
import { SettingRow } from '@affine/component/setting-components';
|
||||
import { EditorSettingService } from '@affine/core/modules/editor-settting';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useMemo, useState } from 'react';
|
||||
import {
|
||||
NoteBackgroundColor,
|
||||
NoteShadow,
|
||||
StrokeStyle,
|
||||
} from '@blocksuite/blocks';
|
||||
import { useFramework, useLiveData } from '@toeverything/infra';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { menuTrigger, settingWrapper } from '../style.css';
|
||||
import { EdgelessSnapshot } from './snapshot';
|
||||
|
||||
const CORNER_SIZE = [
|
||||
{ name: 'None', value: 0 },
|
||||
{ name: 'Small', value: 8 },
|
||||
{ name: 'Medium', value: 16 },
|
||||
{ name: 'Large', value: 24 },
|
||||
{ name: 'Huge', value: 32 },
|
||||
] as const;
|
||||
|
||||
export const NoteSettings = () => {
|
||||
const t = useI18n();
|
||||
const [borderStyle, setBorderStyle] = useState<'solid' | 'dash' | 'none'>(
|
||||
'solid'
|
||||
);
|
||||
const [borderThickness, setBorderThickness] = useState<number[]>([3]);
|
||||
const framework = useFramework();
|
||||
const { editorSetting } = framework.get(EditorSettingService);
|
||||
const settings = useLiveData(editorSetting.settings$);
|
||||
|
||||
const borderStyleItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: 'solid',
|
||||
value: StrokeStyle.Solid,
|
||||
label:
|
||||
t['com.affine.settings.editorSettings.edgeless.note.border.solid'](),
|
||||
},
|
||||
{
|
||||
value: 'dash',
|
||||
value: StrokeStyle.Dash,
|
||||
label:
|
||||
t['com.affine.settings.editorSettings.edgeless.note.border.dash'](),
|
||||
},
|
||||
{
|
||||
value: 'none',
|
||||
value: StrokeStyle.None,
|
||||
label:
|
||||
t['com.affine.settings.editorSettings.edgeless.note.border.none'](),
|
||||
},
|
||||
],
|
||||
[t]
|
||||
);
|
||||
|
||||
const { borderStyle } = settings['affine:note'].edgeless.style;
|
||||
const setBorderStyle = useCallback(
|
||||
(value: StrokeStyle) => {
|
||||
editorSetting.set('affine:note', {
|
||||
edgeless: {
|
||||
style: {
|
||||
borderStyle: value,
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
[editorSetting]
|
||||
);
|
||||
|
||||
const { borderSize } = settings['affine:note'].edgeless.style;
|
||||
const setBorderSize = useCallback(
|
||||
(value: number[]) => {
|
||||
editorSetting.set('affine:note', {
|
||||
edgeless: {
|
||||
style: {
|
||||
borderSize: value[0],
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
[editorSetting]
|
||||
);
|
||||
|
||||
const backgroundItems = useMemo(() => {
|
||||
const { background } = settings['affine:note'];
|
||||
return Object.entries(NoteBackgroundColor).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('affine:note', { background: value });
|
||||
};
|
||||
const isSelected = background === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
const cornerItems = useMemo(() => {
|
||||
const { borderRadius } = settings['affine:note'].edgeless.style;
|
||||
return CORNER_SIZE.map(({ name, value }) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('affine:note', {
|
||||
edgeless: {
|
||||
style: {
|
||||
borderRadius: value,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
const isSelected = borderRadius === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
const shadowItems = useMemo(() => {
|
||||
const { shadowType } = settings['affine:note'].edgeless.style;
|
||||
return Object.entries(NoteShadow).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('affine:note', {
|
||||
edgeless: {
|
||||
style: {
|
||||
shadowType: value,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
const isSelected = shadowType === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EdgelessSnapshot
|
||||
@@ -53,9 +153,9 @@ export const NoteSettings = () => {
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>Yellow</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
Yellow
|
||||
<Menu items={backgroundItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{String(settings['affine:note'].background)}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
@@ -63,9 +163,9 @@ export const NoteSettings = () => {
|
||||
name={t['com.affine.settings.editorSettings.edgeless.note.corners']()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>Small</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
Small
|
||||
<Menu items={cornerItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{String(settings['affine:note'].edgeless.style.borderRadius)}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
@@ -73,9 +173,9 @@ export const NoteSettings = () => {
|
||||
name={t['com.affine.settings.editorSettings.edgeless.note.shadow']()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>Box shadow</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
Box shadow
|
||||
<Menu items={shadowItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{String(settings['affine:note'].edgeless.style.shadowType)}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
@@ -98,12 +198,12 @@ export const NoteSettings = () => {
|
||||
desc={''}
|
||||
>
|
||||
<Slider
|
||||
value={borderThickness}
|
||||
onValueChange={setBorderThickness}
|
||||
min={1}
|
||||
max={5}
|
||||
step={1}
|
||||
nodes={[1, 2, 3, 4, 5]}
|
||||
value={[borderSize]}
|
||||
onValueChange={setBorderSize}
|
||||
min={2}
|
||||
max={12}
|
||||
step={2}
|
||||
nodes={[2, 4, 6, 8, 10, 12]}
|
||||
/>
|
||||
</SettingRow>
|
||||
</>
|
||||
|
||||
+41
-10
@@ -1,14 +1,45 @@
|
||||
import { Menu, MenuItem, MenuTrigger, Slider } from '@affine/component';
|
||||
import { SettingRow } from '@affine/component/setting-components';
|
||||
import { EditorSettingService } from '@affine/core/modules/editor-settting';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useState } from 'react';
|
||||
import { LineColor } from '@blocksuite/blocks';
|
||||
import { useFramework, useLiveData } from '@toeverything/infra';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { menuTrigger } from '../style.css';
|
||||
import { EdgelessSnapshot } from './snapshot';
|
||||
|
||||
export const PenSettings = () => {
|
||||
const t = useI18n();
|
||||
const [borderThickness, setBorderThickness] = useState<number[]>([3]);
|
||||
const framework = useFramework();
|
||||
const { editorSetting } = framework.get(EditorSettingService);
|
||||
const settings = useLiveData(editorSetting.settings$);
|
||||
|
||||
const colorItems = useMemo(() => {
|
||||
const { color } = settings.brush;
|
||||
return Object.entries(LineColor).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('brush', { color: value });
|
||||
};
|
||||
const isSelected = color === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
const borderThickness = settings.brush.lineWidth;
|
||||
const setBorderThickness = useCallback(
|
||||
(value: number[]) => {
|
||||
editorSetting.set('brush', {
|
||||
lineWidth: value[0],
|
||||
});
|
||||
},
|
||||
[editorSetting]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EdgelessSnapshot
|
||||
@@ -20,9 +51,9 @@ export const PenSettings = () => {
|
||||
name={t['com.affine.settings.editorSettings.edgeless.pen.color']()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>Yellow</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
Yellow
|
||||
<Menu items={colorItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{String(settings.brush.color)}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
@@ -31,12 +62,12 @@ export const PenSettings = () => {
|
||||
desc={''}
|
||||
>
|
||||
<Slider
|
||||
value={borderThickness}
|
||||
value={[borderThickness]}
|
||||
onValueChange={setBorderThickness}
|
||||
min={1}
|
||||
max={5}
|
||||
step={1}
|
||||
nodes={[1, 2, 3, 4, 5]}
|
||||
min={2}
|
||||
max={12}
|
||||
step={2}
|
||||
nodes={[2, 4, 6, 8, 10, 12]}
|
||||
/>
|
||||
</SettingRow>
|
||||
</>
|
||||
|
||||
+107
-24
@@ -6,37 +6,46 @@ import {
|
||||
type RadioItem,
|
||||
} from '@affine/component';
|
||||
import { SettingRow } from '@affine/component/setting-components';
|
||||
import { EditorSettingService } from '@affine/core/modules/editor-settting';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { useMemo, useState } from 'react';
|
||||
import {
|
||||
FontFamily,
|
||||
FontFamilyMap,
|
||||
FontStyle,
|
||||
FontWeight,
|
||||
LineColor,
|
||||
TextAlign,
|
||||
} from '@blocksuite/blocks';
|
||||
import { useFramework, useLiveData } from '@toeverything/infra';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
|
||||
import { menuTrigger, settingWrapper } from '../style.css';
|
||||
import { EdgelessSnapshot } from './snapshot';
|
||||
|
||||
export const TextSettings = () => {
|
||||
const t = useI18n();
|
||||
|
||||
const [textAlignment, setTextAlignment] = useState<
|
||||
'left' | 'center' | 'right'
|
||||
>('left');
|
||||
const framework = useFramework();
|
||||
const { editorSetting } = framework.get(EditorSettingService);
|
||||
const settings = useLiveData(editorSetting.settings$);
|
||||
|
||||
const alignItems = useMemo<RadioItem[]>(
|
||||
() => [
|
||||
{
|
||||
value: 'left',
|
||||
value: TextAlign.Left,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.edgeless.text.alignment.left'
|
||||
](),
|
||||
},
|
||||
{
|
||||
value: 'center',
|
||||
value: TextAlign.Center,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.edgeless.text.alignment.center'
|
||||
](),
|
||||
},
|
||||
{
|
||||
value: 'right',
|
||||
value: TextAlign.Right,
|
||||
label:
|
||||
t[
|
||||
'com.affine.settings.editorSettings.edgeless.text.alignment.right'
|
||||
@@ -46,6 +55,76 @@ export const TextSettings = () => {
|
||||
[t]
|
||||
);
|
||||
|
||||
const { textAlign } = settings['affine:edgeless-text'];
|
||||
const setTextAlign = useCallback(
|
||||
(value: TextAlign) => {
|
||||
editorSetting.set('affine:edgeless-text', {
|
||||
textAlign: value,
|
||||
});
|
||||
},
|
||||
[editorSetting]
|
||||
);
|
||||
|
||||
const colorItems = useMemo(() => {
|
||||
const { color } = settings['affine:edgeless-text'];
|
||||
return Object.entries(LineColor).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('affine:edgeless-text', { color: value });
|
||||
};
|
||||
const isSelected = color === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
const fontFamilyItems = useMemo(() => {
|
||||
const { fontFamily } = settings['affine:edgeless-text'];
|
||||
return Object.entries(FontFamily).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('affine:edgeless-text', { fontFamily: value });
|
||||
};
|
||||
const isSelected = fontFamily === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
const fontStyleItems = useMemo(() => {
|
||||
const { fontStyle } = settings['affine:edgeless-text'];
|
||||
return Object.entries(FontStyle).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('affine:edgeless-text', { fontStyle: value });
|
||||
};
|
||||
const isSelected = fontStyle === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
const fontWeightItems = useMemo(() => {
|
||||
const { fontWeight } = settings['affine:edgeless-text'];
|
||||
return Object.entries(FontWeight).map(([name, value]) => {
|
||||
const handler = () => {
|
||||
editorSetting.set('affine:edgeless-text', { fontWeight: value });
|
||||
};
|
||||
const isSelected = fontWeight === value;
|
||||
return (
|
||||
<MenuItem key={name} onSelect={handler} selected={isSelected}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
);
|
||||
});
|
||||
}, [editorSetting, settings]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<EdgelessSnapshot
|
||||
@@ -57,29 +136,33 @@ export const TextSettings = () => {
|
||||
name={t['com.affine.settings.editorSettings.edgeless.text.color']()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>Blue</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
Blue
|
||||
<Menu items={colorItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{String(settings['affine:edgeless-text'].color)}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t['com.affine.settings.editorSettings.edgeless.text.font']()}
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.text.font-family'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>Inter</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
Inter
|
||||
<Menu items={fontFamilyItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{FontFamilyMap[settings['affine:edgeless-text'].fontFamily]}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
<SettingRow
|
||||
name={t['com.affine.settings.editorSettings.edgeless.text.font-size']()}
|
||||
name={t[
|
||||
'com.affine.settings.editorSettings.edgeless.text.font-style'
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>15px</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
15px
|
||||
<Menu items={fontStyleItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{String(settings['affine:edgeless-text'].fontStyle)}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
@@ -89,9 +172,9 @@ export const TextSettings = () => {
|
||||
]()}
|
||||
desc={''}
|
||||
>
|
||||
<Menu items={<MenuItem>Regular</MenuItem>}>
|
||||
<MenuTrigger className={menuTrigger} disabled>
|
||||
Regular
|
||||
<Menu items={fontWeightItems}>
|
||||
<MenuTrigger className={menuTrigger}>
|
||||
{settings['affine:edgeless-text'].fontWeight}
|
||||
</MenuTrigger>
|
||||
</Menu>
|
||||
</SettingRow>
|
||||
@@ -101,10 +184,10 @@ export const TextSettings = () => {
|
||||
>
|
||||
<RadioGroup
|
||||
items={alignItems}
|
||||
value={textAlignment}
|
||||
value={textAlign}
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
onChange={setTextAlignment}
|
||||
onChange={setTextAlign}
|
||||
/>
|
||||
</SettingRow>
|
||||
</>
|
||||
|
||||
+5
@@ -3,6 +3,7 @@ import {
|
||||
AIPageRootBlockSpec,
|
||||
} from '@affine/core/blocksuite/presets/ai';
|
||||
import { mixpanel } from '@affine/core/mixpanel';
|
||||
import { EditorSettingService } from '@affine/core/modules/editor-settting';
|
||||
import {
|
||||
BlockFlavourIdentifier,
|
||||
BlockServiceIdentifier,
|
||||
@@ -54,6 +55,7 @@ function withAffineRootService(Service: typeof PageRootService) {
|
||||
export function createPageRootBlockSpec(
|
||||
framework: FrameworkProvider
|
||||
): ExtensionType[] {
|
||||
const editorSettingService = framework.get(EditorSettingService);
|
||||
return [
|
||||
...AIPageRootBlockSpec,
|
||||
{
|
||||
@@ -67,6 +69,7 @@ export function createPageRootBlockSpec(
|
||||
},
|
||||
ConfigExtension('affine:page', {
|
||||
linkedWidget: createLinkedWidgetConfig(framework),
|
||||
editorSetting: editorSettingService.editorSetting.settingSignal,
|
||||
}),
|
||||
];
|
||||
}
|
||||
@@ -74,6 +77,7 @@ export function createPageRootBlockSpec(
|
||||
export function createEdgelessRootBlockSpec(
|
||||
framework: FrameworkProvider
|
||||
): ExtensionType[] {
|
||||
const editorSettingService = framework.get(EditorSettingService);
|
||||
return [
|
||||
...AIEdgelessRootBlockSpec,
|
||||
{
|
||||
@@ -87,6 +91,7 @@ export function createEdgelessRootBlockSpec(
|
||||
},
|
||||
ConfigExtension('affine:page', {
|
||||
linkedWidget: createLinkedWidgetConfig(framework),
|
||||
editorSetting: editorSettingService.editorSetting.settingSignal,
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user