Files
simple-react-app-kit/packages/lexical/src/actions/font-size.tsx
T
Maofeng 0d817537be feat(lexical): add declarative rich text editor
Introduce @workspace/lexical with composable actions, toolbars, embeds, rich-text nodes, media uploads, selection utilities, HTML serialization, and theme styling.\n\nLocalize built-in controls through MessageDescriptor catalogs for English and Simplified Chinese, while providing an English I18nProvider fallback for standalone editor use. Include focused unit coverage for actions, controls, serialization, plugins, public API, and catalogs.
2026-07-31 15:07:09 +08:00

86 lines
2.4 KiB
TypeScript

import {
$getSelectionStyleValueForProperty,
$patchStyleText,
} from "@lexical/selection"
import { ALargeSmall, ChevronDown } from "lucide-react"
import { $getSelection, $isRangeSelection } from "lexical"
import { Button } from "@workspace/ui/components/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "@workspace/ui/components/dropdown-menu"
import type {
LexicalActionDefaultControlProps,
LexicalActionDefinition,
} from "../types"
import { lexicalMessages } from "../messages"
const fontSizes = ["12px", "14px", "16px", "18px", "24px", "32px"] as const
function FontSizeControl({ context, label }: LexicalActionDefaultControlProps) {
const fontSize = context.editor.getEditorState().read(() => {
const selection = $getSelection()
return $isRangeSelection(selection)
? $getSelectionStyleValueForProperty(selection, "font-size", "16px")
: "16px"
})
return (
<DropdownMenu>
<DropdownMenuTrigger
render={
<Button
type="button"
size="sm"
variant="ghost"
aria-label={label}
className="w-fit justify-between px-2 font-normal"
onMouseDown={(event) => event.preventDefault()}
/>
}
>
<span>{fontSize}</span>
<ChevronDown className="opacity-60" />
</DropdownMenuTrigger>
<DropdownMenuContent
align="center"
className="w-fit min-w-auto"
showArrow
>
<DropdownMenuRadioGroup
value={fontSize}
onValueChange={(value) => fontSizeAction.execute(context, value)}
>
{fontSizes.map((size) => (
<DropdownMenuRadioItem
key={size}
value={size}
onMouseDown={(event) => event.preventDefault()}
>
{size}
</DropdownMenuRadioItem>
))}
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
)
}
export const fontSizeAction: LexicalActionDefinition = {
name: "fontSize",
label: lexicalMessages.fontSize,
icon: ALargeSmall,
control: FontSizeControl,
execute: ({ editor }, value = "16px") => {
editor.update(() => {
const selection = $getSelection()
if ($isRangeSelection(selection)) {
$patchStyleText(selection, { "font-size": value })
}
})
},
}