Files
AFFiNE-Mirror/blocksuite/affine/inlines/preset/src/command/text-style.ts
T
L-Sun bcd6a70b59 refactor(editor): narrow text format parameter (#12946)
#### PR Dependency Tree


* **PR #12946** 👈
  * **PR #12947**
    * **PR #12948**

This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Refactor**
* Updated terminology and types from "text style" to "text attributes"
throughout the text formatting features for improved clarity and
consistency.
* Separated style-specific attributes (like bold, italic, color, and
background) from other text metadata.
* Renamed relevant commands and updated menu and toolbar configurations
to use the new attribute structure.

* **New Features**
* Added support for color and background properties in text style
attributes.

* **Bug Fixes**
* Improved consistency and reliability in text formatting and
highlighting behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-07-02 06:55:14 +00:00

111 lines
2.7 KiB
TypeScript

import {
getBlockSelectionsCommand,
getTextSelectionCommand,
} from '@blocksuite/affine-shared/commands';
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 { getCombinedTextAttributes } from './utils.js';
export const toggleTextStyleCommand: Command<{
key: Extract<
keyof AffineTextStyleAttributes,
'bold' | 'italic' | 'underline' | 'strike' | 'code'
>;
}> = (ctx, next) => {
const { std, key } = ctx;
const [active] = std.command
.chain()
.pipe(isTextAttributeActive, { key })
.run();
const payload: {
styles: AffineTextStyleAttributes;
mode?: 'replace' | 'merge';
} = {
styles: {
[key]: active ? null : true,
},
};
const [result] = std.command
.chain()
.try(chain => [
chain.pipe(getTextSelectionCommand).pipe(formatTextCommand, payload),
chain.pipe(getBlockSelectionsCommand).pipe(formatBlockCommand, payload),
chain.pipe(formatNativeCommand, payload),
])
.run();
if (result) {
return next();
}
return false;
};
const toggleTextStyleCommandWrapper = (
key: Extract<
keyof AffineTextStyleAttributes,
'bold' | 'italic' | 'underline' | 'strike' | 'code'
>
): Command => {
return (ctx, next) => {
const [success] = ctx.std.command
.chain()
.pipe(toggleTextStyleCommand, { key })
.run();
if (success) next();
return false;
};
};
export const toggleBold = toggleTextStyleCommandWrapper('bold');
export const toggleItalic = toggleTextStyleCommandWrapper('italic');
export const toggleUnderline = toggleTextStyleCommandWrapper('underline');
export const toggleStrike = toggleTextStyleCommandWrapper('strike');
export const toggleCode = toggleTextStyleCommandWrapper('code');
export const getTextAttributes: Command<
{},
{ textAttributes: AffineTextAttributes }
> = (ctx, next) => {
const [result, innerCtx] = getCombinedTextAttributes(
ctx.std.command.chain()
).run();
if (!result) {
return false;
}
return next({ textAttributes: innerCtx.textAttributes });
};
export const isTextAttributeActive: Command<{
key: keyof AffineTextAttributes;
}> = (ctx, next) => {
const key = ctx.key;
const [result] = getCombinedTextAttributes(ctx.std.command.chain())
.pipe((ctx, next) => {
const { textAttributes } = ctx;
if (textAttributes && key in textAttributes) {
return next();
}
return false;
})
.run();
if (!result) {
return false;
}
return next();
};