diff --git a/blocksuite/affine/blocks/root/src/configs/toolbar.ts b/blocksuite/affine/blocks/root/src/configs/toolbar.ts index 6945c1f16a..5ffda5dd59 100644 --- a/blocksuite/affine/blocks/root/src/configs/toolbar.ts +++ b/blocksuite/affine/blocks/root/src/configs/toolbar.ts @@ -9,6 +9,7 @@ import { promptDocTitle, } from '@blocksuite/affine-block-embed'; import { updateBlockType } from '@blocksuite/affine-block-note'; +import type { HighlightType } from '@blocksuite/affine-components/highlight-dropdown-menu'; import { toast } from '@blocksuite/affine-components/toast'; import { EditorChevronDown } from '@blocksuite/affine-components/toolbar'; import { @@ -38,7 +39,6 @@ import type { ToolbarModuleConfig, } from '@blocksuite/affine-shared/services'; import { ActionPlacement } from '@blocksuite/affine-shared/services'; -import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; import { tableViewMeta } from '@blocksuite/data-view/view-presets'; import { CopyIcon, @@ -140,7 +140,7 @@ const highlightActionGroup = { id: 'c.highlight', when: ({ chain }) => isFormatSupported(chain).run()[0], content({ chain }) { - const updateHighlight = (styles: AffineTextAttributes) => { + const updateHighlight = (styles: HighlightType) => { const payload = { styles }; chain .try(chain => [ diff --git a/blocksuite/affine/components/src/highlight-dropdown-menu/dropdown-menu.ts b/blocksuite/affine/components/src/highlight-dropdown-menu/dropdown-menu.ts index 1f1c47bb37..2c23f4bc94 100644 --- a/blocksuite/affine/components/src/highlight-dropdown-menu/dropdown-menu.ts +++ b/blocksuite/affine/components/src/highlight-dropdown-menu/dropdown-menu.ts @@ -1,4 +1,4 @@ -import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; +import type { AffineTextStyleAttributes } from '@blocksuite/affine-shared/types'; import { PropTypes, requiredProperties } from '@blocksuite/std'; import { LitElement } from 'lit'; import { property } from 'lit/decorators.js'; @@ -20,7 +20,10 @@ const colors = [ 'grey', ] as const; -type HighlightType = 'color' | 'background'; +export type HighlightType = Pick< + AffineTextStyleAttributes, + 'color' | 'background' +>; // TODO(@fundon): these recent settings should be added to the dropdown menu // tests/blocksutie/e2e/format-bar.spec.ts#253 @@ -33,13 +36,13 @@ type HighlightType = 'color' | 'background'; }) export class HighlightDropdownMenu extends LitElement { @property({ attribute: false }) - accessor updateHighlight!: (styles: AffineTextAttributes) => void; + accessor updateHighlight!: (styles: HighlightType) => void; - private readonly _update = (value: string | null, type: HighlightType) => { + private readonly _update = (style: HighlightType) => { // latestHighlightColor = value; // latestHighlightType = type; - this.updateHighlight({ [`${type}`]: value }); + this.updateHighlight(style); }; override render() { @@ -71,7 +74,7 @@ export class HighlightDropdownMenu extends LitElement { return html` this._update(value, 'color')} + @click=${() => this._update({ color: value })} > this._update(value, 'background')} + @click=${() => this._update({ background: value })} > { const [result] = host.std.command .chain() - .pipe(isTextStyleActive, { key: 'bold' }) + .pipe(isTextAttributeActive, { key: 'bold' }) .run(); return result; }, @@ -54,7 +54,7 @@ export const textFormatConfigs: TextFormatConfig[] = [ activeWhen: host => { const [result] = host.std.command .chain() - .pipe(isTextStyleActive, { key: 'italic' }) + .pipe(isTextAttributeActive, { key: 'italic' }) .run(); return result; }, @@ -70,7 +70,7 @@ export const textFormatConfigs: TextFormatConfig[] = [ activeWhen: host => { const [result] = host.std.command .chain() - .pipe(isTextStyleActive, { key: 'underline' }) + .pipe(isTextAttributeActive, { key: 'underline' }) .run(); return result; }, @@ -86,7 +86,7 @@ export const textFormatConfigs: TextFormatConfig[] = [ activeWhen: host => { const [result] = host.std.command .chain() - .pipe(isTextStyleActive, { key: 'strike' }) + .pipe(isTextAttributeActive, { key: 'strike' }) .run(); return result; }, @@ -102,7 +102,7 @@ export const textFormatConfigs: TextFormatConfig[] = [ activeWhen: host => { const [result] = host.std.command .chain() - .pipe(isTextStyleActive, { key: 'code' }) + .pipe(isTextAttributeActive, { key: 'code' }) .run(); return result; }, @@ -118,7 +118,7 @@ export const textFormatConfigs: TextFormatConfig[] = [ activeWhen: host => { const [result] = host.std.command .chain() - .pipe(isTextStyleActive, { key: 'link' }) + .pipe(isTextAttributeActive, { key: 'link' }) .run(); return result; }, diff --git a/blocksuite/affine/inlines/preset/src/command/format-text.ts b/blocksuite/affine/inlines/preset/src/command/format-text.ts index 728f2df0b7..64f9fa7f21 100644 --- a/blocksuite/affine/inlines/preset/src/command/format-text.ts +++ b/blocksuite/affine/inlines/preset/src/command/format-text.ts @@ -1,6 +1,9 @@ import { clearMarksOnDiscontinuousInput } from '@blocksuite/affine-rich-text'; import { getSelectedBlocksCommand } from '@blocksuite/affine-shared/commands'; -import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; +import type { + AffineTextAttributes, + AffineTextStyleAttributes, +} from '@blocksuite/affine-shared/types'; import type { Command, TextSelection } from '@blocksuite/std'; import { INLINE_ROOT_ATTR, @@ -13,7 +16,7 @@ import { FORMAT_TEXT_SUPPORT_FLAVOURS } from './consts.js'; export const formatTextCommand: Command<{ currentTextSelection?: TextSelection; textSelection?: TextSelection; - styles: AffineTextAttributes; + styles: AffineTextStyleAttributes; mode?: 'replace' | 'merge'; }> = (ctx, next) => { const { styles, mode = 'merge' } = ctx; diff --git a/blocksuite/affine/inlines/preset/src/command/index.ts b/blocksuite/affine/inlines/preset/src/command/index.ts index 51550bfdc2..54286ae1f0 100644 --- a/blocksuite/affine/inlines/preset/src/command/index.ts +++ b/blocksuite/affine/inlines/preset/src/command/index.ts @@ -10,8 +10,8 @@ export { formatBlockCommand } from './format-block.js'; export { formatNativeCommand } from './format-native.js'; export { formatTextCommand } from './format-text.js'; export { - getTextStyle, - isTextStyleActive, + getTextAttributes, + isTextAttributeActive, toggleBold, toggleCode, toggleItalic, diff --git a/blocksuite/affine/inlines/preset/src/command/text-style.ts b/blocksuite/affine/inlines/preset/src/command/text-style.ts index 6fcec20515..0b74eb0913 100644 --- a/blocksuite/affine/inlines/preset/src/command/text-style.ts +++ b/blocksuite/affine/inlines/preset/src/command/text-style.ts @@ -2,25 +2,31 @@ import { getBlockSelectionsCommand, getTextSelectionCommand, } from '@blocksuite/affine-shared/commands'; -import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; +import type { + AffineTextAttributes, + AffineTextStyleAttributes, +} from '@blocksuite/affine-shared/types'; import type { Command } from '@blocksuite/std'; import { formatBlockCommand } from './format-block.js'; import { formatNativeCommand } from './format-native.js'; import { formatTextCommand } from './format-text.js'; -import { getCombinedTextStyle } from './utils.js'; +import { getCombinedTextAttributes } from './utils.js'; export const toggleTextStyleCommand: Command<{ key: Extract< - keyof AffineTextAttributes, + keyof AffineTextStyleAttributes, 'bold' | 'italic' | 'underline' | 'strike' | 'code' >; }> = (ctx, next) => { const { std, key } = ctx; - const [active] = std.command.chain().pipe(isTextStyleActive, { key }).run(); + const [active] = std.command + .chain() + .pipe(isTextAttributeActive, { key }) + .run(); const payload: { - styles: AffineTextAttributes; + styles: AffineTextStyleAttributes; mode?: 'replace' | 'merge'; } = { styles: { @@ -46,7 +52,7 @@ export const toggleTextStyleCommand: Command<{ const toggleTextStyleCommandWrapper = ( key: Extract< - keyof AffineTextAttributes, + keyof AffineTextStyleAttributes, 'bold' | 'italic' | 'underline' | 'strike' | 'code' > ): Command => { @@ -66,30 +72,29 @@ export const toggleUnderline = toggleTextStyleCommandWrapper('underline'); export const toggleStrike = toggleTextStyleCommandWrapper('strike'); export const toggleCode = toggleTextStyleCommandWrapper('code'); -export const getTextStyle: Command<{}, { textStyle: AffineTextAttributes }> = ( - ctx, - next -) => { - const [result, innerCtx] = getCombinedTextStyle( +export const getTextAttributes: Command< + {}, + { textAttributes: AffineTextAttributes } +> = (ctx, next) => { + const [result, innerCtx] = getCombinedTextAttributes( ctx.std.command.chain() ).run(); if (!result) { return false; } - return next({ textStyle: innerCtx.textStyle }); + return next({ textAttributes: innerCtx.textAttributes }); }; -export const isTextStyleActive: Command<{ key: keyof AffineTextAttributes }> = ( - ctx, - next -) => { +export const isTextAttributeActive: Command<{ + key: keyof AffineTextAttributes; +}> = (ctx, next) => { const key = ctx.key; - const [result] = getCombinedTextStyle(ctx.std.command.chain()) + const [result] = getCombinedTextAttributes(ctx.std.command.chain()) .pipe((ctx, next) => { - const { textStyle } = ctx; + const { textAttributes } = ctx; - if (textStyle && key in textStyle) { + if (textAttributes && key in textAttributes) { return next(); } diff --git a/blocksuite/affine/inlines/preset/src/command/utils.ts b/blocksuite/affine/inlines/preset/src/command/utils.ts index 3552909d49..2056f4931d 100644 --- a/blocksuite/affine/inlines/preset/src/command/utils.ts +++ b/blocksuite/affine/inlines/preset/src/command/utils.ts @@ -77,8 +77,8 @@ function handleCurrentSelection( handler: ( type: 'text' | 'block' | 'native', inlineEditors: InlineEditor[] - ) => { textStyle: AffineTextAttributes } | boolean | void -): Chain { + ) => { textAttributes: AffineTextAttributes } | boolean | void +): Chain { return chain.try(chain => [ // text selection, corresponding to `formatText` command chain @@ -174,25 +174,25 @@ function handleCurrentSelection( ]); } -export function getCombinedTextStyle(chain: Chain) { +export function getCombinedTextAttributes(chain: Chain) { return handleCurrentSelection(chain, (type, inlineEditors) => { if (type === 'text') { return { - textStyle: getCombinedFormatFromInlineEditors( + textAttributes: getCombinedFormatFromInlineEditors( inlineEditors.map(e => [e, e.getInlineRange()]) ), }; } if (type === 'block') { return { - textStyle: getCombinedFormatFromInlineEditors( + textAttributes: getCombinedFormatFromInlineEditors( inlineEditors.map(e => [e, { index: 0, length: e.yTextLength }]) ), }; } if (type === 'native') { return { - textStyle: getCombinedFormatFromInlineEditors( + textAttributes: getCombinedFormatFromInlineEditors( inlineEditors.map(e => [e, e.getInlineRange()]) ), }; diff --git a/blocksuite/affine/shared/src/types/index.ts b/blocksuite/affine/shared/src/types/index.ts index 3502bcee1a..cfa71eab17 100644 --- a/blocksuite/affine/shared/src/types/index.ts +++ b/blocksuite/affine/shared/src/types/index.ts @@ -35,27 +35,30 @@ export type IndentContext = { type: 'indent' | 'dedent'; }; -export interface AffineTextAttributes { +export type AffineTextStyleAttributes = { bold?: true | null; italic?: true | null; underline?: true | null; strike?: true | null; code?: true | null; + color?: string | null; + background?: string | null; +}; + +export type AffineTextAttributes = AffineTextStyleAttributes & { link?: string | null; reference?: | ({ type: 'Subpage' | 'LinkedPage'; } & ReferenceInfo) | null; - background?: string | null; - color?: string | null; latex?: string | null; footnote?: FootNote | null; mention?: { member: string; notification?: string; } | null; -} +}; export type AffineInlineEditor = InlineEditor; diff --git a/blocksuite/affine/widgets/keyboard-toolbar/src/config.ts b/blocksuite/affine/widgets/keyboard-toolbar/src/config.ts index 9c1bbe3eef..b8c0552b8a 100644 --- a/blocksuite/affine/widgets/keyboard-toolbar/src/config.ts +++ b/blocksuite/affine/widgets/keyboard-toolbar/src/config.ts @@ -26,7 +26,7 @@ import { formatBlockCommand, formatNativeCommand, formatTextCommand, - getTextStyle, + getTextAttributes, toggleBold, toggleCode, toggleItalic, @@ -45,7 +45,7 @@ import { getTextSelectionCommand, } from '@blocksuite/affine-shared/commands'; import { REFERENCE_NODE } from '@blocksuite/affine-shared/consts'; -import type { AffineTextAttributes } from '@blocksuite/affine-shared/types'; +import type { AffineTextStyleAttributes } from '@blocksuite/affine-shared/types'; import { createDefaultDoc, openSingleFileWith, @@ -817,8 +817,8 @@ const textStyleToolItems: KeyboardToolbarItem[] = [ name: 'Bold', icon: BoldIcon(), background: ({ std }) => { - const [_, { textStyle }] = std.command.exec(getTextStyle); - return textStyle?.bold ? '#00000012' : ''; + const [_, { textAttributes }] = std.command.exec(getTextAttributes); + return textAttributes?.bold ? '#00000012' : ''; }, action: ({ std }) => { std.command.exec(toggleBold); @@ -828,8 +828,8 @@ const textStyleToolItems: KeyboardToolbarItem[] = [ name: 'Italic', icon: ItalicIcon(), background: ({ std }) => { - const [_, { textStyle }] = std.command.exec(getTextStyle); - return textStyle?.italic ? '#00000012' : ''; + const [_, { textAttributes }] = std.command.exec(getTextAttributes); + return textAttributes?.italic ? '#00000012' : ''; }, action: ({ std }) => { std.command.exec(toggleItalic); @@ -839,8 +839,8 @@ const textStyleToolItems: KeyboardToolbarItem[] = [ name: 'UnderLine', icon: UnderLineIcon(), background: ({ std }) => { - const [_, { textStyle }] = std.command.exec(getTextStyle); - return textStyle?.underline ? '#00000012' : ''; + const [_, { textAttributes }] = std.command.exec(getTextAttributes); + return textAttributes?.underline ? '#00000012' : ''; }, action: ({ std }) => { std.command.exec(toggleUnderline); @@ -850,8 +850,8 @@ const textStyleToolItems: KeyboardToolbarItem[] = [ name: 'StrikeThrough', icon: StrikeThroughIcon(), background: ({ std }) => { - const [_, { textStyle }] = std.command.exec(getTextStyle); - return textStyle?.strike ? '#00000012' : ''; + const [_, { textAttributes }] = std.command.exec(getTextAttributes); + return textAttributes?.strike ? '#00000012' : ''; }, action: ({ std }) => { std.command.exec(toggleStrike); @@ -861,8 +861,8 @@ const textStyleToolItems: KeyboardToolbarItem[] = [ name: 'Code', icon: CodeIcon(), background: ({ std }) => { - const [_, { textStyle }] = std.command.exec(getTextStyle); - return textStyle?.code ? '#00000012' : ''; + const [_, { textAttributes }] = std.command.exec(getTextAttributes); + return textAttributes?.code ? '#00000012' : ''; }, action: ({ std }) => { std.command.exec(toggleCode); @@ -872,8 +872,8 @@ const textStyleToolItems: KeyboardToolbarItem[] = [ name: 'Link', icon: LinkIcon(), background: ({ std }) => { - const [_, { textStyle }] = std.command.exec(getTextStyle); - return textStyle?.link ? '#00000012' : ''; + const [_, { textAttributes }] = std.command.exec(getTextAttributes); + return textAttributes?.link ? '#00000012' : ''; }, action: ({ std }) => { std.command.exec(toggleLink); @@ -883,9 +883,9 @@ const textStyleToolItems: KeyboardToolbarItem[] = [ const highlightToolPanel: KeyboardToolPanelConfig = { icon: ({ std }) => { - const [_, { textStyle }] = std.command.exec(getTextStyle); - if (textStyle?.color) { - return HighLightDuotoneIcon(textStyle.color); + const [_, { textAttributes }] = std.command.exec(getTextAttributes); + if (textAttributes?.color) { + return HighLightDuotoneIcon(textAttributes.color); } else { return HighLightDuotoneIcon(cssVarV2('icon/primary')); } @@ -916,7 +916,7 @@ const highlightToolPanel: KeyboardToolPanelConfig = { const payload = { styles: { color: cssVarV2(`text/highlight/fg/${color}`), - } satisfies AffineTextAttributes, + } satisfies AffineTextStyleAttributes, }; std.command .chain() @@ -961,7 +961,7 @@ const highlightToolPanel: KeyboardToolPanelConfig = { const payload = { styles: { background: cssVarV2(`text/highlight/bg/${color}`), - } satisfies AffineTextAttributes, + } satisfies AffineTextStyleAttributes, }; std.command .chain()