feat(creator-studio): icon toolbar with block tools, drop author strip

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Opus 5 committed 2026-11-06 22:30:08 +08:00
1 parent 7bdf7cf018
commit 7c33482be7
19 files changed
+600 -241

No files matched your search

@@ -1,3 +1,12 @@
/**
* 固定顶栏里的正文工具条。
*
* 每个按钮都是「上图标 + 下文字」,与公众号/知乎的单行工具栏一致;
* 只渲染当前账号真正有权限使用的能力,全部动作由父组件转给 TinyMCE。
*
* @package Jio
*/
import { __ } from '@wordpress/i18n';
type Capabilities = Record<string, boolean>;
@@ -12,9 +21,34 @@ type Props = {
onCommand: (name: string, value?: string) => void;
onRememberSelection: () => void;
onOpenLink: () => void;
onOpenMedia: (type: 'image' | 'video') => void;
onOpenMedia: (type: 'image' | 'video' | 'file') => void;
onInsertBlock: (kind: string) => void;
};
type ToolButtonProps = {
label: string;
icon: string;
ready: boolean;
onClick: () => void;
title?: string;
};
function ToolButton({ label, icon, ready, onClick, title }: ToolButtonProps) {
return (
<button
type="button"
className="jio-creator__tool-btn"
disabled={!ready}
onClick={onClick}
title={title || label}
aria-label={title || label}
>
<i className={icon} aria-hidden="true" />
<span className="jio-creator__tool-label">{label}</span>
</button>
);
}
export function EditorToolbar({
ready,
canUndo,
@@ -26,6 +60,7 @@ export function EditorToolbar({
onRememberSelection,
onOpenLink,
onOpenMedia,
onInsertBlock,
}: Props) {
return (
<div
@@ -38,58 +73,65 @@ export function EditorToolbar({
}}
>
<div className="jio-creator__toolbar-group" role="group" aria-label={__('撤销和重做', 'jio')}>
<button type="button" className="jio-creator__tool-btn" disabled={!canUndo} onClick={() => onCommand('undo')} title={__('撤销', 'jio')} aria-label={__('撤销', 'jio')}>
<i className="fa fas fa-undo" aria-hidden="true" />
</button>
<button type="button" className="jio-creator__tool-btn" disabled={!canRedo} onClick={() => onCommand('redo')} title={__('重做', 'jio')} aria-label={__('重做', 'jio')}>
<i className="fa fas fa-redo" aria-hidden="true" />
</button>
<ToolButton label={__('撤销', 'jio')} icon="fa fas fa-undo" ready={canUndo} onClick={() => onCommand('undo')} />
<ToolButton label={__('重做', 'jio')} icon="fa fas fa-redo" ready={canRedo} onClick={() => onCommand('redo')} />
</div>
<span className="jio-creator__toolbar-divider" aria-hidden="true" />
<select
className="jio-creator__format-select"
aria-label={__('段落样式', 'jio')}
value={formatValue}
disabled={!ready}
onFocus={onRememberSelection}
onChange={(event) => {
onFormatChange(event.target.value);
onCommand('format', event.target.value);
}}
>
<option value="p">{__('正文', 'jio')}</option>
<option value="h1">{__('标题 1', 'jio')}</option>
<option value="h2">{__('标题 2', 'jio')}</option>
<option value="h3">{__('标题 3', 'jio')}</option>
<option value="blockquote">{__('引用', 'jio')}</option>
</select>
<div className="jio-creator__toolbar-group" role="group" aria-label={__('段落样式', 'jio')}>
<label className="jio-creator__format-field">
<select
className="jio-creator__format-select"
aria-label={__('标题级别', 'jio')}
value={formatValue === 'blockquote' ? 'p' : formatValue}
disabled={!ready}
onFocus={onRememberSelection}
onChange={(event) => {
onFormatChange(event.target.value);
onCommand('format', event.target.value);
}}
>
<option value="p">{__('正文', 'jio')}</option>
<option value="h1">{__('标题 1', 'jio')}</option>
<option value="h2">{__('标题 2', 'jio')}</option>
<option value="h3">{__('标题 3', 'jio')}</option>
</select>
<i className="fa fas fa-heading" aria-hidden="true" />
<span className="jio-creator__tool-label">{__('标题', 'jio')}</span>
</label>
</div>
<span className="jio-creator__toolbar-divider" aria-hidden="true" />
<div className="jio-creator__toolbar-group" role="group" aria-label={__('文字格式', 'jio')}>
<button type="button" className="jio-creator__tool-btn" disabled={!ready} onClick={() => onCommand('Bold')} title={__('加粗', 'jio')} aria-label={__('加粗', 'jio')}>
<i className="fa fas fa-bold" aria-hidden="true" />
</button>
<button type="button" className="jio-creator__tool-btn" disabled={!ready} onClick={() => onCommand('Italic')} title={__('斜体', 'jio')} aria-label={__('斜体', 'jio')}>
<i className="fa fas fa-italic" aria-hidden="true" />
</button>
<button type="button" className="jio-creator__tool-btn" disabled={!ready} onClick={() => onCommand('Underline')} title={__('下划线', 'jio')} aria-label={__('下划线', 'jio')}>
<i className="fa fas fa-underline" aria-hidden="true" />
</button>
<ToolButton label={__('加粗', 'jio')} icon="fa fas fa-bold" ready={ready} onClick={() => onCommand('Bold')} />
<ToolButton label={__('斜体', 'jio')} icon="fa fas fa-italic" ready={ready} onClick={() => onCommand('Italic')} />
<ToolButton label={__('下划线', 'jio')} icon="fa fas fa-underline" ready={ready} onClick={() => onCommand('Underline')} />
</div>
<span className="jio-creator__toolbar-divider" aria-hidden="true" />
<div className="jio-creator__toolbar-group" role="group" aria-label={__('段落块', 'jio')}>
<ToolButton label={__('列表', 'jio')} icon="fa fas fa-list-ul" ready={ready} onClick={() => onInsertBlock('list')} />
<ToolButton label={__('目录', 'jio')} icon="fa fas fa-list-ol" ready={ready} onClick={() => onInsertBlock('toc')} />
<ToolButton label={__('引用', 'jio')} icon="fa fas fa-quote-left" ready={ready} onClick={() => onCommand('format', 'blockquote')} />
<ToolButton label={__('分割线', 'jio')} icon="fa fas fa-minus" ready={ready} onClick={() => onInsertBlock('divider')} />
<ToolButton label={__('代码块', 'jio')} icon="fa fas fa-code" ready={ready} onClick={() => onInsertBlock('code')} />
<ToolButton label={__('注释', 'jio')} icon="fa fas fa-comment-dots" ready={ready} onClick={() => onInsertBlock('footnote')} />
<ToolButton label={__('公式', 'jio')} icon="fa fas fa-square-root-alt" ready={ready} onClick={() => onInsertBlock('math')} />
<ToolButton label={__('表格', 'jio')} icon="fa fas fa-table" ready={ready} onClick={() => onInsertBlock('table')} />
</div>
<span className="jio-creator__toolbar-divider" aria-hidden="true" />
<div className="jio-creator__toolbar-group" role="group" aria-label={__('媒体和链接', 'jio')}>
{capabilities.canUploadImage && (
<button type="button" className="jio-creator__tool-btn jio-creator__tool-labeled" disabled={!ready} onClick={() => onOpenMedia('image')} title={__('插入图片', 'jio')}>
<i className="fa far fa-image" aria-hidden="true" /><span>{__('图片', 'jio')}</span>
</button>
<ToolButton label={__('图片', 'jio')} icon="fa far fa-image" ready={ready} onClick={() => onOpenMedia('image')} />
)}
{(capabilities.canUploadVideo || capabilities.canEmbed) && (
<button type="button" className="jio-creator__tool-btn jio-creator__tool-labeled" disabled={!ready} onClick={() => onOpenMedia('video')} title={__('插入视频', 'jio')}>
<i className="fa fas fa-video" aria-hidden="true" /><span>{__('视频', 'jio')}</span>
</button>
<ToolButton label={__('视频', 'jio')} icon="fa fas fa-video" ready={ready} onClick={() => onOpenMedia('video')} />
)}
<ToolButton label={__('链接', 'jio')} icon="fa fas fa-link" ready={ready} onClick={onOpenLink} />
{capabilities.canUploadFile && (
<ToolButton label={__('附件', 'jio')} icon="fa fas fa-paperclip" ready={ready} onClick={() => onOpenMedia('file')} />
)}
<button type="button" className="jio-creator__tool-btn jio-creator__tool-labeled" disabled={!ready} onClick={onOpenLink} title={__('插入链接', 'jio')}>
<i className="fa fas fa-link" aria-hidden="true" /><span>{__('链接', 'jio')}</span>
</button>
</div>
</div>
);