fix(ux): 修水合告警(扩展注入) + 正文编辑器嵌套滚动条/不铺满

- layout: html/body 加 suppressHydrationWarning(浏览器扩展水合前注入 class/attr,非本应用 bug)
- Editor: textarea 高度自适应内容 + overflow-hidden,消除内部嵌套滚动条、正文随内容铺满写作区,外层单一滚动条统管
This commit is contained in:
Yaojia Wang
2026-06-21 17:57:53 +02:00
parent 95b662d85d
commit 10c0d4bead
2 changed files with 20 additions and 3 deletions

View File

@@ -14,9 +14,11 @@ export default function RootLayout({
}: {
children: React.ReactNode;
}) {
// suppressHydrationWarning浏览器扩展如 Dark Reader/翻译插件)常在 html/body
// 注入 class/attr水合前改 DOM → 仅这一层属性的水合告警,非本应用 bug。
return (
<html lang="zh-CN">
<body className="font-sans antialiased">
<html lang="zh-CN" suppressHydrationWarning>
<body className="font-sans antialiased" suppressHydrationWarning>
<ToastProvider>
{children}
<CommandPaletteMount />

View File

@@ -1,5 +1,7 @@
"use client";
import { useEffect, useRef } from "react";
interface EditorProps {
value: string;
onChange: (value: string) => void;
@@ -9,19 +11,32 @@ interface EditorProps {
// 中栏正文编辑器宋体、720px 居中、行高 1.9UX §2.3 / §6.3)。
// 流式中显示朱砂光标提示prefers-reduced-motion 下不闪烁,见 globals.css
export function Editor({ value, onChange, streaming }: EditorProps) {
const ref = useRef<HTMLTextAreaElement>(null);
// 自适应高度textarea 高度=内容高度overflow-hidden 不内部滚动),由外层写作区
// 单一滚动条统管。修复正文出现嵌套滚动条 + 定高 60vh 不铺满展示区的怪象。
// min-h-[60vh] 仍作空稿时的最小可写高度(内容更长时按内容增高、外层滚动)。
useEffect(() => {
const el = ref.current;
if (!el) return;
el.style.height = "auto";
el.style.height = `${el.scrollHeight}px`;
}, [value]);
return (
<div className="mx-auto max-w-prose">
<label htmlFor="chapter-editor" className="sr-only">
</label>
<textarea
ref={ref}
id="chapter-editor"
value={value}
onChange={(e) => onChange(e.target.value)}
readOnly={streaming}
aria-busy={streaming}
placeholder="夜色如墨……点击「写本章」让 AI 起草,或直接在此书写。"
className="min-h-[60vh] w-full resize-none bg-transparent font-serif text-[18px] leading-[1.9] text-ink placeholder:text-ink-soft/50 focus:outline-none"
className="block min-h-[60vh] w-full resize-none overflow-hidden bg-transparent font-serif text-[18px] leading-[1.9] text-ink placeholder:text-ink-soft/50 focus:outline-none"
/>
{streaming ? (
<span