@@ -10,18 +10,23 @@ import { EditorSettingService } from '@affine/core/modules/editor-settting';
1010import { useI18n } from '@affine/i18n' ;
1111import {
1212 ConnectorMode ,
13+ FontFamily ,
14+ FontFamilyMap ,
15+ FontStyle ,
16+ FontWeightMap ,
1317 LineColor ,
1418 LineColorMap ,
1519 PointStyle ,
1620 StrokeStyle ,
21+ TextAlign ,
1722} from '@blocksuite/blocks' ;
1823import type { Doc } from '@blocksuite/store' ;
1924import { useFramework , useLiveData } from '@toeverything/infra' ;
2025import { useCallback , useMemo } from 'react' ;
2126
2227import { DropdownMenu } from '../menu' ;
2328import { menuTrigger , settingWrapper } from '../style.css' ;
24- import { useColor } from '../utils' ;
29+ import { sortedFontWeightEntries , useColor } from '../utils' ;
2530import { Point } from './point' ;
2631import { EdgelessSnapshot } from './snapshot' ;
2732import { getSurfaceBlock } from './utils' ;
@@ -31,6 +36,15 @@ enum ConnecterStyle {
3136 Scribbled = 'scribbled' ,
3237}
3338
39+ enum ConnectorTextFontSize {
40+ '16px' = '16' ,
41+ '20px' = '20' ,
42+ '24px' = '24' ,
43+ '32px' = '32' ,
44+ '40px' = '40' ,
45+ '64px' = '64' ,
46+ }
47+
3448export const ConnectorSettings = ( ) => {
3549 const t = useI18n ( ) ;
3650 const framework = useFramework ( ) ;
@@ -191,6 +205,150 @@ export const ConnectorSettings = () => {
191205 } ) ;
192206 } , [ editorSetting , settings ] ) ;
193207
208+ const alignItems = useMemo < RadioItem [ ] > (
209+ ( ) => [
210+ {
211+ value : TextAlign . Left ,
212+ label :
213+ t [
214+ 'com.affine.settings.editorSettings.edgeless.text.alignment.left'
215+ ] ( ) ,
216+ } ,
217+ {
218+ value : TextAlign . Center ,
219+ label :
220+ t [
221+ 'com.affine.settings.editorSettings.edgeless.text.alignment.center'
222+ ] ( ) ,
223+ } ,
224+ {
225+ value : TextAlign . Right ,
226+ label :
227+ t [
228+ 'com.affine.settings.editorSettings.edgeless.text.alignment.right'
229+ ] ( ) ,
230+ } ,
231+ ] ,
232+ [ t ]
233+ ) ;
234+
235+ const textAlignment = settings . connector . labelStyle . textAlign ;
236+ const setTextAlignment = useCallback (
237+ ( value : TextAlign ) => {
238+ editorSetting . set ( 'connector' , {
239+ labelStyle : {
240+ textAlign : value ,
241+ } ,
242+ } ) ;
243+ } ,
244+ [ editorSetting ]
245+ ) ;
246+
247+ const fontFamilyItems = useMemo ( ( ) => {
248+ const { fontFamily } = settings . connector . labelStyle ;
249+ return Object . entries ( FontFamily ) . map ( ( [ name , value ] ) => {
250+ const handler = ( ) => {
251+ editorSetting . set ( 'connector' , {
252+ labelStyle : {
253+ fontFamily : value ,
254+ } ,
255+ } ) ;
256+ } ;
257+ const isSelected = fontFamily === value ;
258+ return (
259+ < MenuItem key = { name } onSelect = { handler } selected = { isSelected } >
260+ { name }
261+ </ MenuItem >
262+ ) ;
263+ } ) ;
264+ } , [ editorSetting , settings ] ) ;
265+
266+ const fontStyleItems = useMemo ( ( ) => {
267+ const { fontStyle } = settings . connector . labelStyle ;
268+ return Object . entries ( FontStyle ) . map ( ( [ name , value ] ) => {
269+ const handler = ( ) => {
270+ editorSetting . set ( 'connector' , {
271+ labelStyle : {
272+ fontStyle : value ,
273+ } ,
274+ } ) ;
275+ } ;
276+ const isSelected = fontStyle === value ;
277+ return (
278+ < MenuItem key = { name } onSelect = { handler } selected = { isSelected } >
279+ { name }
280+ </ MenuItem >
281+ ) ;
282+ } ) ;
283+ } , [ editorSetting , settings ] ) ;
284+
285+ const fontWeightItems = useMemo ( ( ) => {
286+ const { fontWeight } = settings . connector . labelStyle ;
287+ return sortedFontWeightEntries . map ( ( [ name , value ] ) => {
288+ const handler = ( ) => {
289+ editorSetting . set ( 'connector' , {
290+ labelStyle : {
291+ fontWeight : value ,
292+ } ,
293+ } ) ;
294+ } ;
295+ const isSelected = fontWeight === value ;
296+ return (
297+ < MenuItem key = { name } onSelect = { handler } selected = { isSelected } >
298+ { name }
299+ </ MenuItem >
300+ ) ;
301+ } ) ;
302+ } , [ editorSetting , settings ] ) ;
303+
304+ const fontSizeItems = useMemo ( ( ) => {
305+ const { fontSize } = settings . connector . labelStyle ;
306+ return Object . entries ( ConnectorTextFontSize ) . map ( ( [ name , value ] ) => {
307+ const handler = ( ) => {
308+ editorSetting . set ( 'connector' , {
309+ labelStyle : {
310+ fontSize : Number ( value ) ,
311+ } ,
312+ } ) ;
313+ } ;
314+ const isSelected = fontSize === Number ( value ) ;
315+ return (
316+ < MenuItem key = { name } onSelect = { handler } selected = { isSelected } >
317+ { name }
318+ </ MenuItem >
319+ ) ;
320+ } ) ;
321+ } , [ editorSetting , settings ] ) ;
322+
323+ const textColorItems = useMemo ( ( ) => {
324+ const { color } = settings . connector . labelStyle ;
325+ return Object . entries ( LineColor ) . map ( ( [ name , value ] ) => {
326+ const handler = ( ) => {
327+ editorSetting . set ( 'connector' , {
328+ labelStyle : {
329+ color : value ,
330+ } ,
331+ } ) ;
332+ } ;
333+ const isSelected = color === value ;
334+ return (
335+ < MenuItem
336+ key = { name }
337+ onSelect = { handler }
338+ selected = { isSelected }
339+ prefix = { < Point color = { value } /> }
340+ >
341+ { name }
342+ </ MenuItem >
343+ ) ;
344+ } ) ;
345+ } , [ editorSetting , settings ] ) ;
346+
347+ const textColor = useMemo ( ( ) => {
348+ const { color } = settings . connector . labelStyle ;
349+ return getColorFromMap ( color , LineColorMap ) ;
350+ } , [ getColorFromMap , settings ] ) ;
351+
194352 const getElements = useCallback ( ( doc : Doc ) => {
195353 const surface = getSurfaceBlock ( doc ) ;
196354 return surface ?. getElementsByType ( 'connector' ) || [ ] ;
@@ -309,6 +467,100 @@ export const ConnectorSettings = () => {
309467 }
310468 />
311469 </ SettingRow >
470+ < SettingRow
471+ name = { t [
472+ 'com.affine.settings.editorSettings.edgeless.shape.text-color'
473+ ] ( ) }
474+ desc = { '' }
475+ >
476+ { textColor ? (
477+ < DropdownMenu
478+ items = { textColorItems }
479+ trigger = {
480+ < MenuTrigger
481+ className = { menuTrigger }
482+ prefix = { < Point color = { textColor . value } /> }
483+ >
484+ { textColor . key }
485+ </ MenuTrigger >
486+ }
487+ />
488+ ) : null }
489+ </ SettingRow >
490+ < SettingRow
491+ name = { t [
492+ 'com.affine.settings.editorSettings.edgeless.text.font-family'
493+ ] ( ) }
494+ desc = { '' }
495+ >
496+ < DropdownMenu
497+ items = { fontFamilyItems }
498+ trigger = {
499+ < MenuTrigger className = { menuTrigger } >
500+ { FontFamilyMap [ settings . connector . labelStyle . fontFamily ] }
501+ </ MenuTrigger >
502+ }
503+ />
504+ </ SettingRow >
505+ < SettingRow
506+ name = { t [
507+ 'com.affine.settings.editorSettings.edgeless.shape.font-size'
508+ ] ( ) }
509+ desc = { '' }
510+ >
511+ < DropdownMenu
512+ items = { fontSizeItems }
513+ trigger = {
514+ < MenuTrigger className = { menuTrigger } >
515+ { settings . connector . labelStyle . fontSize + 'px' }
516+ </ MenuTrigger >
517+ }
518+ />
519+ </ SettingRow >
520+ < SettingRow
521+ name = { t [
522+ 'com.affine.settings.editorSettings.edgeless.text.font-style'
523+ ] ( ) }
524+ desc = { '' }
525+ >
526+ < DropdownMenu
527+ items = { fontStyleItems }
528+ trigger = {
529+ < MenuTrigger className = { menuTrigger } >
530+ { settings . connector . labelStyle . fontStyle }
531+ </ MenuTrigger >
532+ }
533+ />
534+ </ SettingRow >
535+ < SettingRow
536+ name = { t [
537+ 'com.affine.settings.editorSettings.edgeless.text.font-weight'
538+ ] ( ) }
539+ desc = { '' }
540+ >
541+ < DropdownMenu
542+ items = { fontWeightItems }
543+ trigger = {
544+ < MenuTrigger className = { menuTrigger } >
545+ { FontWeightMap [ settings . connector . labelStyle . fontWeight ] }
546+ </ MenuTrigger >
547+ }
548+ />
549+ </ SettingRow >
550+ < SettingRow
551+ name = { t [
552+ 'com.affine.settings.editorSettings.edgeless.shape.text-alignment'
553+ ] ( ) }
554+ desc = { '' }
555+ >
556+ < RadioGroup
557+ items = { alignItems }
558+ value = { textAlignment }
559+ width = { 250 }
560+ className = { settingWrapper }
561+ onChange = { setTextAlignment }
562+ />
563+ </ SettingRow >
312564 </ >
313565 ) ;
314566} ;
0 commit comments