fix(creator-studio): 沉浸式布局与公众号式写作体验
首轮实机体验暴露的问题: - 投稿页仍在渲染主题头部的 all_top_fluid 挂件区、页脚与浮动入口, 与工作台顶栏重复。header.php / footer.php 新增 jio_render_header、 jio_render_footer、jio_render_fluid_widgets 过滤器,工作台模式下全部关闭 - 区块 Inspector 被写在 BlockList 之后,作为正文流的一部分渲染出 一个巨大的「未选择区块」白框;移除内联 Inspector(区块设置改由 行内工具栏的区块菜单提供) - 中文正文被 wordcount 的 'words' 口径算成「字数:1」;改用 characters_excluding_spaces,与前台 TinyMCE 字数一致 - 行宽 820px、标题 34px 偏松散;收窄到 720px / 27px,正文 16px/1.85, 段落间距与选区描边收敛,行内工具栏改为深色圆角悬浮条 新增本地视觉验收脚本(不参与运行时): - scripts/preview.cjs:用模拟 bootstrap 生成离线预览页 - scripts/shoot.cjs:桌面/移动端截图与控制台错误采集 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
2c7262770b
commit
d07cffe99e
10 files changed
+272
-39
No files matched your search
@@ -12,7 +12,7 @@ import { createRoot, useCallback, useEffect, useMemo, useRef, useState } from '@
|
||||
import { parse, serialize } from '@wordpress/blocks';
|
||||
import { registerCoreBlocks } from '@wordpress/block-library';
|
||||
import { useSelect } from '@wordpress/data';
|
||||
import { BlockEditorProvider, BlockList, BlockTools, BlockInspector } from '@wordpress/block-editor';
|
||||
import { BlockEditorProvider, BlockList, BlockTools } from '@wordpress/block-editor';
|
||||
import { count as countWords } from '@wordpress/wordcount';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
|
||||
@@ -133,7 +133,13 @@ function Studio(): JSX.Element {
|
||||
}, []);
|
||||
|
||||
const serialized = useMemo(() => serialize(blocks), [blocks]);
|
||||
const words = useMemo(() => countWords(serialized.replace(/<[^>]*>/g, ' '), 'words', {}), [serialized]);
|
||||
|
||||
// 中文没有空格分词,wordcount 的 'words' 会把整段算成 1。
|
||||
// 'characters_excluding_spaces' 才是中文场景该用的口径(与前台 TinyMCE 字数一致)。
|
||||
const charCount = useMemo(() => {
|
||||
const text = serialized.replace(/<[^>]*>/g, ' ');
|
||||
return countWords(text, 'characters_excluding_spaces', {});
|
||||
}, [serialized]);
|
||||
|
||||
const buildPayload = useCallback(
|
||||
(extra: Record<string, any> = {}) => ({
|
||||
@@ -400,16 +406,13 @@ function Studio(): JSX.Element {
|
||||
<BlockTools>
|
||||
<BlockList />
|
||||
</BlockTools>
|
||||
<aside className="jio-creator__inspector" aria-label={__('区块设置', 'jio')}>
|
||||
<BlockInspector />
|
||||
</aside>
|
||||
</BlockEditorProvider>
|
||||
</div>
|
||||
|
||||
<footer className="jio-creator__footer">
|
||||
<span>{__('字数', 'jio')}:{words}</span>
|
||||
<span>{__('字数', 'jio')}:{charCount}</span>
|
||||
<span>
|
||||
{__('约', 'jio')} {Math.max(1, Math.round(words / 400))} {__('分钟阅读', 'jio')}
|
||||
{__('约', 'jio')} {Math.max(1, Math.round(charCount / 400))} {__('分钟阅读', 'jio')}
|
||||
</span>
|
||||
</footer>
|
||||
</main>
|
||||
|
||||
@@ -218,26 +218,28 @@ $warn: #b4573f;
|
||||
}
|
||||
|
||||
.jio-creator__canvas {
|
||||
width: min(820px, 100%);
|
||||
/* 公众号式阅读宽度:正文行宽控制在约 40 个汉字,留白优先。 */
|
||||
width: min(720px, 100%);
|
||||
margin: 0 auto;
|
||||
padding: clamp(24px, 5vw, 56px) clamp(16px, 4vw, 40px) 120px;
|
||||
padding: clamp(20px, 4vw, 44px) clamp(20px, 5vw, 52px) 140px;
|
||||
}
|
||||
|
||||
.jio-creator__title {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 6px;
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
min-height: 56px;
|
||||
min-height: 50px;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: var(--jc-ink);
|
||||
font-family: "Songti SC", "Noto Serif SC", "Source Han Serif SC", serif;
|
||||
font-size: clamp(26px, 3.4vw, 34px);
|
||||
font-weight: 600;
|
||||
line-height: 1.35;
|
||||
font-size: clamp(23px, 2.6vw, 27px);
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.01em;
|
||||
line-height: 1.4;
|
||||
resize: none;
|
||||
|
||||
&:focus {
|
||||
@@ -252,29 +254,28 @@ $warn: #b4573f;
|
||||
|
||||
.jio-creator__excerpt {
|
||||
display: block;
|
||||
margin-bottom: 28px;
|
||||
margin-bottom: 22px;
|
||||
|
||||
> span {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
color: var(--jc-ink-soft);
|
||||
margin-bottom: 4px;
|
||||
color: #9aa8a2;
|
||||
font-size: 12px;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 8px 0;
|
||||
padding: 6px 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid var(--jc-line);
|
||||
background: transparent;
|
||||
color: var(--jc-ink-soft);
|
||||
font-family: inherit;
|
||||
font-size: 15px;
|
||||
font-size: 14px;
|
||||
line-height: 1.7;
|
||||
resize: none;
|
||||
|
||||
&:focus {
|
||||
border-color: var(--jc-accent);
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
@@ -282,10 +283,13 @@ $warn: #b4573f;
|
||||
|
||||
.jio-creator__editor {
|
||||
position: relative;
|
||||
/* 行内浮动工具栏相对书写区定位,而不是相对整个页面。 */
|
||||
min-height: 40vh;
|
||||
|
||||
.block-editor-writing-flow {
|
||||
font-size: 17px;
|
||||
font-size: 16px;
|
||||
line-height: 1.85;
|
||||
letter-spacing: 0.01em;
|
||||
}
|
||||
|
||||
.block-editor-default-block-appender textarea.block-editor-default-block-appender__content {
|
||||
@@ -293,28 +297,61 @@ $warn: #b4573f;
|
||||
}
|
||||
|
||||
.block-editor-block-list__layout {
|
||||
padding-bottom: 80px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.wp-block {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
.jio-creator__inspector {
|
||||
margin-top: 24px;
|
||||
|
||||
.block-editor-block-inspector {
|
||||
border-top: 1px solid var(--jc-line);
|
||||
padding-top: 16px;
|
||||
/* 段落之间留出公众号式的呼吸感,标题上方多留一档。 */
|
||||
.block-editor-block-list__block {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1.1em;
|
||||
}
|
||||
|
||||
.block-editor-block-inspector:empty {
|
||||
display: none;
|
||||
.block-editor-block-list__block[data-type='core/heading'] {
|
||||
margin-top: 1.6em;
|
||||
}
|
||||
|
||||
.components-panel__body {
|
||||
/* 选中时的虚线框收敛成低对比描边,贴近公众号的“轻选中”。 */
|
||||
.block-editor-block-list__block.is-selected::after,
|
||||
.block-editor-block-list__block.is-hovered::after {
|
||||
box-shadow: 0 0 0 1.5px rgba(38, 118, 101, 0.35);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
/* 行内工具栏:圆角悬浮条,深色底更接近公众号的选中工具条。 */
|
||||
.block-editor-block-contextual-toolbar {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.block-editor-block-contextual-toolbar .block-editor-block-toolbar {
|
||||
border: 0;
|
||||
border-radius: 8px;
|
||||
background: #2b3733;
|
||||
box-shadow: 0 6px 20px rgba(20, 32, 28, 0.22);
|
||||
|
||||
.components-toolbar-group,
|
||||
.components-toolbar {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.components-button {
|
||||
color: rgba(255, 255, 255, 0.86);
|
||||
|
||||
&:hover:not(:disabled),
|
||||
&:focus:not(:disabled) {
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.is-pressed,
|
||||
&[aria-pressed='true'] {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user