Skip to content

Commit

Permalink
Merge pull request #3922 from udecode/toolbar/improve
Browse files Browse the repository at this point in the history
Toolbar/improve
  • Loading branch information
felixfeng33 authored Dec 28, 2024
2 parents 9c72530 + d7f360c commit 846d57e
Show file tree
Hide file tree
Showing 31 changed files with 628 additions and 100 deletions.
6 changes: 6 additions & 0 deletions .changeset/great-starfishes-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@udecode/plate-font': patch
---

Add api `api.fontSize.setMark`.
Add utils `toUnitLess`.
7 changes: 7 additions & 0 deletions apps/www/content/docs/cn/components/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ toc: true

## 2024年12月 #17

### 12月27日 #17.7

- `fixed-toolbar-buttons`: 添加 `font-size-toolbar-button`
- `floating-toolbar`: 添加 `inline-equation-toolbar-button`
- `turn-into-dropdown-menu`: 修复:转换为其他块后,编辑器应重新获得焦点
- `insert-dropdown-menu`: 添加 `行内公式``公式` 并修复焦点问题
- `slash-input-element`: 添加 `公式``行内公式`

### 12月25日 #17.6

Expand Down
30 changes: 30 additions & 0 deletions apps/www/content/docs/cn/font.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,36 @@ const plugins = [

### FontSizePlugin

#### API

##### editor.api.fontSize.setMark

设置字体大小标记。

<APIParameters>
<APIItem name="fontSize" type="string">
要设置的字体大小值。
</APIItem>
</APIParameters>

#### Utils

##### toUnitLess

将字体大小值转换为无单位的值。

<APIParameters>
<APIItem name="fontSize" type="string">
要转换的字体大小值。
</APIItem>
</APIParameters>

<APIReturns>
<APIItem name="unitLess" type="string">
无单位字体大小值。
</APIItem>
</APIReturns>

### FontWeightPlugin

## API Components
Expand Down
1 change: 1 addition & 0 deletions apps/www/content/docs/en/components/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Use the [CLI](https://platejs.org/docs/components/cli) to install the latest ver

### December 27 #17.7

- `fixed-toolbar-buttons`: add `font-size-toolbar-button`
- `floating-toolbar`: add `inline-equation-toolbar-button`
- `turn-into-dropdown-menu`: Fix: after turn into other block, the editor should regain focus.
- `insert-dropdown-menu`: add `inline equation` and `equation` & fix the focus issue
Expand Down
30 changes: 30 additions & 0 deletions apps/www/content/docs/en/font.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,36 @@ const plugins = [

### FontSizePlugin

#### API

##### editor.api.fontSize.setMark

Set the font size mark.

<APIParameters>
<APIItem name="fontSize" type="string">
The font size value to set.
</APIItem>
</APIParameters>

#### Utils

##### toUnitLess

Convert a font size value to a unitless value.

<APIParameters>
<APIItem name="fontSize" type="string">
The font size value to convert.
</APIItem>
</APIParameters>

<APIReturns>
<APIItem name="unitLess" type="string">
The font size value without units.
</APIItem>
</APIReturns>

### FontWeightPlugin

## API Components
Expand Down
28 changes: 28 additions & 0 deletions apps/www/public/r/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,33 @@
],
"type": "registry:ui"
},
{
"dependencies": [
"@udecode/plate-font"
],
"doc": {
"description": "A toolbar control for adjusting font size.",
"docs": [
{
"route": "/docs/font"
}
],
"examples": [
"list-demo"
]
},
"files": [
{
"path": "plate-ui/font-size-toolbar-button.tsx",
"type": "registry:ui"
}
],
"name": "font-size-toolbar-button",
"registryDependencies": [
"toolbar"
],
"type": "registry:ui"
},
{
"dependencies": [],
"doc": {
Expand Down Expand Up @@ -2259,6 +2286,7 @@
"color-dropdown-menu",
"comment-toolbar-button",
"emoji-dropdown-menu",
"font-size-toolbar-button",
"history-toolbar-button",
"indent-list-toolbar-button",
"indent-todo-toolbar-button",
Expand Down
3 changes: 2 additions & 1 deletion apps/www/public/r/styles/default/fixed-toolbar-buttons.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"files": [
{
"content": "'use client';\n\nimport React from 'react';\n\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { useEditorReadOnly } from '@udecode/plate-common/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n ArrowUpToLineIcon,\n BaselineIcon,\n BoldIcon,\n Code2Icon,\n HighlighterIcon,\n ItalicIcon,\n PaintBucketIcon,\n StrikethroughIcon,\n UnderlineIcon,\n WandSparklesIcon,\n} from 'lucide-react';\n\nimport { MoreDropdownMenu } from '@/components/plate-ui/more-dropdown-menu';\n\nimport { AIToolbarButton } from './ai-toolbar-button';\nimport { AlignDropdownMenu } from './align-dropdown-menu';\nimport { ColorDropdownMenu } from './color-dropdown-menu';\nimport { CommentToolbarButton } from './comment-toolbar-button';\nimport { EmojiDropdownMenu } from './emoji-dropdown-menu';\nimport { ExportToolbarButton } from './export-toolbar-button';\nimport { RedoToolbarButton, UndoToolbarButton } from './history-toolbar-button';\nimport {\n BulletedIndentListToolbarButton,\n NumberedIndentListToolbarButton,\n} from './indent-list-toolbar-button';\nimport { IndentTodoToolbarButton } from './indent-todo-toolbar-button';\nimport { IndentToolbarButton } from './indent-toolbar-button';\nimport { InsertDropdownMenu } from './insert-dropdown-menu';\nimport { LineHeightDropdownMenu } from './line-height-dropdown-menu';\nimport { LinkToolbarButton } from './link-toolbar-button';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { MediaToolbarButton } from './media-toolbar-button';\nimport { ModeDropdownMenu } from './mode-dropdown-menu';\nimport { OutdentToolbarButton } from './outdent-toolbar-button';\nimport { TableDropdownMenu } from './table-dropdown-menu';\nimport { ToggleToolbarButton } from './toggle-toolbar-button';\nimport { ToolbarGroup } from './toolbar';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FixedToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n <div className=\"flex w-full\">\n {!readOnly && (\n <>\n <ToolbarGroup>\n <UndoToolbarButton />\n <RedoToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <AIToolbarButton tooltip=\"AI commands\">\n <WandSparklesIcon />\n </AIToolbarButton>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <ExportToolbarButton>\n <ArrowUpToLineIcon />\n </ExportToolbarButton>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <InsertDropdownMenu />\n <TurnIntoDropdownMenu />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MarkToolbarButton nodeType={BoldPlugin.key} tooltip=\"Bold (⌘+B)\">\n <BoldIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={ItalicPlugin.key}\n tooltip=\"Italic (⌘+I)\"\n >\n <ItalicIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={UnderlinePlugin.key}\n tooltip=\"Underline (⌘+U)\"\n >\n <UnderlineIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={StrikethroughPlugin.key}\n tooltip=\"Strikethrough (⌘+⇧+M)\"\n >\n <StrikethroughIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton nodeType={CodePlugin.key} tooltip=\"Code (⌘+E)\">\n <Code2Icon />\n </MarkToolbarButton>\n\n <ColorDropdownMenu\n nodeType={FontColorPlugin.key}\n tooltip=\"Text color\"\n >\n <BaselineIcon />\n </ColorDropdownMenu>\n\n <ColorDropdownMenu\n nodeType={FontBackgroundColorPlugin.key}\n tooltip=\"Background color\"\n >\n <PaintBucketIcon />\n </ColorDropdownMenu>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <AlignDropdownMenu />\n\n <NumberedIndentListToolbarButton />\n <BulletedIndentListToolbarButton />\n <IndentTodoToolbarButton />\n <ToggleToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <LinkToolbarButton />\n <TableDropdownMenu />\n <EmojiDropdownMenu />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MediaToolbarButton nodeType={ImagePlugin.key} />\n <MediaToolbarButton nodeType={VideoPlugin.key} />\n <MediaToolbarButton nodeType={AudioPlugin.key} />\n <MediaToolbarButton nodeType={FilePlugin.key} />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <LineHeightDropdownMenu />\n <OutdentToolbarButton />\n <IndentToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MoreDropdownMenu />\n </ToolbarGroup>\n </>\n )}\n\n <div className=\"grow\" />\n\n <ToolbarGroup>\n <MarkToolbarButton nodeType={HighlightPlugin.key} tooltip=\"Highlight\">\n <HighlighterIcon />\n </MarkToolbarButton>\n <CommentToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <ModeDropdownMenu />\n </ToolbarGroup>\n </div>\n );\n}\n",
"content": "'use client';\n\nimport React from 'react';\n\nimport {\n BoldPlugin,\n CodePlugin,\n ItalicPlugin,\n StrikethroughPlugin,\n UnderlinePlugin,\n} from '@udecode/plate-basic-marks/react';\nimport { useEditorReadOnly } from '@udecode/plate-common/react';\nimport {\n FontBackgroundColorPlugin,\n FontColorPlugin,\n} from '@udecode/plate-font/react';\nimport { HighlightPlugin } from '@udecode/plate-highlight/react';\nimport {\n AudioPlugin,\n FilePlugin,\n ImagePlugin,\n VideoPlugin,\n} from '@udecode/plate-media/react';\nimport {\n ArrowUpToLineIcon,\n BaselineIcon,\n BoldIcon,\n Code2Icon,\n HighlighterIcon,\n ItalicIcon,\n PaintBucketIcon,\n StrikethroughIcon,\n UnderlineIcon,\n WandSparklesIcon,\n} from 'lucide-react';\n\nimport { MoreDropdownMenu } from '@/components/plate-ui/more-dropdown-menu';\n\nimport { AIToolbarButton } from './ai-toolbar-button';\nimport { AlignDropdownMenu } from './align-dropdown-menu';\nimport { ColorDropdownMenu } from './color-dropdown-menu';\nimport { CommentToolbarButton } from './comment-toolbar-button';\nimport { EmojiDropdownMenu } from './emoji-dropdown-menu';\nimport { ExportToolbarButton } from './export-toolbar-button';\nimport { FontSizeToolbarButton } from './font-size-toolbar-button';\nimport { RedoToolbarButton, UndoToolbarButton } from './history-toolbar-button';\nimport {\n BulletedIndentListToolbarButton,\n NumberedIndentListToolbarButton,\n} from './indent-list-toolbar-button';\nimport { IndentTodoToolbarButton } from './indent-todo-toolbar-button';\nimport { IndentToolbarButton } from './indent-toolbar-button';\nimport { InsertDropdownMenu } from './insert-dropdown-menu';\nimport { LineHeightDropdownMenu } from './line-height-dropdown-menu';\nimport { LinkToolbarButton } from './link-toolbar-button';\nimport { MarkToolbarButton } from './mark-toolbar-button';\nimport { MediaToolbarButton } from './media-toolbar-button';\nimport { ModeDropdownMenu } from './mode-dropdown-menu';\nimport { OutdentToolbarButton } from './outdent-toolbar-button';\nimport { TableDropdownMenu } from './table-dropdown-menu';\nimport { ToggleToolbarButton } from './toggle-toolbar-button';\nimport { ToolbarGroup } from './toolbar';\nimport { TurnIntoDropdownMenu } from './turn-into-dropdown-menu';\n\nexport function FixedToolbarButtons() {\n const readOnly = useEditorReadOnly();\n\n return (\n <div className=\"flex w-full\">\n {!readOnly && (\n <>\n <ToolbarGroup>\n <UndoToolbarButton />\n <RedoToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <AIToolbarButton tooltip=\"AI commands\">\n <WandSparklesIcon />\n </AIToolbarButton>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <ExportToolbarButton>\n <ArrowUpToLineIcon />\n </ExportToolbarButton>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <InsertDropdownMenu />\n <TurnIntoDropdownMenu />\n <FontSizeToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MarkToolbarButton nodeType={BoldPlugin.key} tooltip=\"Bold (⌘+B)\">\n <BoldIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={ItalicPlugin.key}\n tooltip=\"Italic (⌘+I)\"\n >\n <ItalicIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={UnderlinePlugin.key}\n tooltip=\"Underline (⌘+U)\"\n >\n <UnderlineIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton\n nodeType={StrikethroughPlugin.key}\n tooltip=\"Strikethrough (⌘+⇧+M)\"\n >\n <StrikethroughIcon />\n </MarkToolbarButton>\n\n <MarkToolbarButton nodeType={CodePlugin.key} tooltip=\"Code (⌘+E)\">\n <Code2Icon />\n </MarkToolbarButton>\n\n <ColorDropdownMenu\n nodeType={FontColorPlugin.key}\n tooltip=\"Text color\"\n >\n <BaselineIcon />\n </ColorDropdownMenu>\n\n <ColorDropdownMenu\n nodeType={FontBackgroundColorPlugin.key}\n tooltip=\"Background color\"\n >\n <PaintBucketIcon />\n </ColorDropdownMenu>\n </ToolbarGroup>\n\n <ToolbarGroup>\n <AlignDropdownMenu />\n\n <NumberedIndentListToolbarButton />\n <BulletedIndentListToolbarButton />\n <IndentTodoToolbarButton />\n <ToggleToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <LinkToolbarButton />\n <TableDropdownMenu />\n <EmojiDropdownMenu />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MediaToolbarButton nodeType={ImagePlugin.key} />\n <MediaToolbarButton nodeType={VideoPlugin.key} />\n <MediaToolbarButton nodeType={AudioPlugin.key} />\n <MediaToolbarButton nodeType={FilePlugin.key} />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <LineHeightDropdownMenu />\n <OutdentToolbarButton />\n <IndentToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <MoreDropdownMenu />\n </ToolbarGroup>\n </>\n )}\n\n <div className=\"grow\" />\n\n <ToolbarGroup>\n <MarkToolbarButton nodeType={HighlightPlugin.key} tooltip=\"Highlight\">\n <HighlighterIcon />\n </MarkToolbarButton>\n <CommentToolbarButton />\n </ToolbarGroup>\n\n <ToolbarGroup>\n <ModeDropdownMenu />\n </ToolbarGroup>\n </div>\n );\n}\n",
"path": "plate-ui/fixed-toolbar-buttons.tsx",
"target": "components/plate-ui/fixed-toolbar-buttons.tsx",
"type": "registry:ui"
Expand All @@ -28,6 +28,7 @@
"color-dropdown-menu",
"comment-toolbar-button",
"emoji-dropdown-menu",
"font-size-toolbar-button",
"history-toolbar-button",
"indent-list-toolbar-button",
"indent-todo-toolbar-button",
Expand Down
29 changes: 29 additions & 0 deletions apps/www/public/r/styles/default/font-size-toolbar-button.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"dependencies": [
"@udecode/plate-font"
],
"doc": {
"description": "A toolbar control for adjusting font size.",
"docs": [
{
"route": "/docs/font"
}
],
"examples": [
"list-demo"
]
},
"files": [
{
"content": "'use client';\nimport { useState } from 'react';\n\nimport { cn } from '@udecode/cn';\nimport { type TElement, getAboveNode, getMarks } from '@udecode/plate-common';\nimport {\n focusEditor,\n useEditorPlugin,\n useEditorSelector,\n} from '@udecode/plate-common/react';\nimport { BaseFontSizePlugin, toUnitLess } from '@udecode/plate-font';\nimport { FontSizePlugin } from '@udecode/plate-font/react';\nimport { HEADING_KEYS } from '@udecode/plate-heading';\nimport { Minus, Plus } from 'lucide-react';\n\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\nimport { ToolbarButton } from './toolbar';\n\nconst DEFAULT_FONT_SIZE = '16';\n\nconst FONT_SIZE_MAP = {\n [HEADING_KEYS.h1]: '36',\n [HEADING_KEYS.h2]: '24',\n [HEADING_KEYS.h3]: '20',\n} as const;\n\nconst FONT_SIZES = [\n '8',\n '9',\n '10',\n '12',\n '14',\n '16',\n '18',\n '24',\n '30',\n '36',\n '48',\n '60',\n '72',\n '96',\n] as const;\n\nexport function FontSizeToolbarButton() {\n const [inputValue, setInputValue] = useState(DEFAULT_FONT_SIZE);\n const [isFocused, setIsFocused] = useState(false);\n const { api, editor } = useEditorPlugin(BaseFontSizePlugin);\n\n const cursorFontSize = useEditorSelector((editor) => {\n const marks = getMarks(editor);\n const fontSize = marks?.[FontSizePlugin.key];\n\n if (fontSize) {\n return toUnitLess(fontSize as string);\n }\n\n const [node] =\n getAboveNode<TElement>(editor, {\n at: editor.selection?.focus,\n }) || [];\n\n return node?.type && node.type in FONT_SIZE_MAP\n ? FONT_SIZE_MAP[node.type as keyof typeof FONT_SIZE_MAP]\n : DEFAULT_FONT_SIZE;\n }, []);\n\n const handleInputChange = () => {\n const newSize = toUnitLess(inputValue);\n\n if (Number.parseInt(newSize) < 1 || Number.parseInt(newSize) > 100) {\n focusEditor(editor);\n\n return;\n }\n if (newSize !== toUnitLess(cursorFontSize)) {\n api.fontSize.setMark(`${newSize}px`);\n }\n\n focusEditor(editor);\n };\n\n const handleFontSizeChange = (delta: number) => {\n const newSize = Number(displayValue) + delta;\n api.fontSize.setMark(`${newSize}px`);\n focusEditor(editor);\n };\n\n const displayValue = isFocused ? inputValue : cursorFontSize;\n\n return (\n <div className=\"flex h-7 items-center gap-1 rounded-md bg-muted/60 p-0 \">\n <ToolbarButton onClick={() => handleFontSizeChange(-1)}>\n <Minus />\n </ToolbarButton>\n\n <Popover open={isFocused} modal={false}>\n <PopoverTrigger asChild>\n <input\n className={cn(\n 'h-full w-10 shrink-0 bg-transparent px-1 text-center text-sm hover:bg-muted'\n )}\n value={displayValue}\n onBlur={() => {\n setIsFocused(false);\n handleInputChange();\n }}\n onChange={(e) => setInputValue(e.target.value)}\n onFocus={() => {\n setIsFocused(true);\n setInputValue(toUnitLess(cursorFontSize));\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n handleInputChange();\n }\n }}\n data-plate-focus=\"true\"\n type=\"text\"\n />\n </PopoverTrigger>\n <PopoverContent\n className=\"w-10 px-px py-1\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n {FONT_SIZES.map((size) => (\n <button\n key={size}\n className={cn(\n 'flex h-8 w-full items-center justify-center text-sm hover:bg-accent data-[highlighted=true]:bg-accent'\n )}\n onClick={() => {\n api.fontSize.setMark(`${size}px`);\n setIsFocused(false);\n }}\n data-highlighted={size === displayValue}\n type=\"button\"\n >\n {size}\n </button>\n ))}\n </PopoverContent>\n </Popover>\n\n <ToolbarButton onClick={() => handleFontSizeChange(1)}>\n <Plus />\n </ToolbarButton>\n </div>\n );\n}\n",
"path": "plate-ui/font-size-toolbar-button.tsx",
"target": "components/plate-ui/font-size-toolbar-button.tsx",
"type": "registry:ui"
}
],
"name": "font-size-toolbar-button",
"registryDependencies": [
"toolbar"
],
"type": "registry:ui"
}
Loading

0 comments on commit 846d57e

Please sign in to comment.