fix(write): 元数据行移至封面上方 + 编辑器撑满修复

布局调整:
- 元数据行(Slug/标签)从封面图下方移到上方,顺序变为
  标题 → 摘要 → 元数据行 → 封面图 → 编辑器

- 滚动主体容器补 flex flex-col:此前 overflow-y-auto 容器内
  子项的 flex-1 失效,导致编辑器只剩 min-h 不撑满。
  加 flex flex-col 后,flex-1 编辑器在窗口够高时正常填充剩余空间。
This commit is contained in:
xfy 2026-06-24 15:35:52 +08:00
parent 198a9b292a
commit 66d29eaa62

View File

@ -17,10 +17,10 @@ use crate::api::posts::{
#[cfg(target_arch = "wasm32")]
use crate::tiptap_bridge::{consume_upload_event, upload_image_file, EditorHandle};
// 共享上传状态类型两端都编译rsx 在 server SSR 时也要渲染这些结构)。
use crate::tiptap_bridge::{UploadErrorEntry, UploadsInFlight};
use crate::components::write_skeleton::WriteSkeleton;
use crate::models::post::Post;
use crate::router::Route;
use crate::tiptap_bridge::{UploadErrorEntry, UploadsInFlight};
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::closure::Closure;
// 封面图上传:从 Dioxus 事件拿底层 web_sys::File以及 paste 事件的原始 web 事件。
@ -197,13 +197,8 @@ fn write_editor(post_id: Option<i32>) -> Element {
}
editor_content_set.set(true);
}
let handle = EditorHandle::new(
inst,
on_update,
on_image_upload,
on_ready,
on_upload_event,
);
let handle =
EditorHandle::new(inst, on_update, on_image_upload, on_ready, on_upload_event);
editor.set(Some(handle));
}
Ok(None) => {
@ -259,9 +254,15 @@ fn write_editor(post_id: Option<i32>) -> Element {
let in_flight = uploads_in_flight.read();
if in_flight.uploading > 0 || in_flight.error > 0 {
let msg = if in_flight.uploading > 0 {
format!("{} 张图片正在上传,请等待完成后再保存", in_flight.uploading)
format!(
"有 {} 张图片正在上传,请等待完成后再保存",
in_flight.uploading
)
} else {
format!("{} 张图片上传失败,请移除或重试后再保存", in_flight.error)
format!(
"有 {} 张图片上传失败,请移除或重试后再保存",
in_flight.error
)
};
error.set(Some(msg));
return;
@ -429,7 +430,9 @@ fn write_editor(post_id: Option<i32>) -> Element {
// 可滚动主体:元信息 + 编辑器 + 内联错误提示。
// 底部操作栏留在此容器外(固定吸底),保证保存/状态按钮始终可见。
div { class: "flex-1 min-h-0 overflow-y-auto",
// flex flex-col让内部 flex-1 编辑器能撑满剩余高度;
// overflow-y-auto内容超出时滚动min-h-0 允许 flex 子项收缩触发滚动)。
div { class: "flex-1 min-h-0 overflow-y-auto flex flex-col",
// 顶部元信息区域 - 固定高度,不滚动
div { class: "flex-shrink-0 space-y-5 pt-8",
// 标题区域 - 大字号无框输入
@ -444,13 +447,39 @@ fn write_editor(post_id: Option<i32>) -> Element {
// 摘要
textarea {
class: "w-full text-base bg-transparent text-[var(--color-paper-secondary)] placeholder-[var(--color-paper-tertiary)] focus:outline-none resize-none leading-relaxed",
class: "w-full text-base bg-transparent text-[var(--color-paper-secondary)] placeholder-[var(--color-paper-tertiary)] focus:outline-none resize-none leading-relaxed mb-0",
placeholder: "摘要(留空则自动生成)",
rows: "2",
value: "{summary}",
oninput: move |evt| summary.set(evt.value()),
}
// 元数据行 - 紧凑精致
div { class: "flex flex-wrap items-end gap-x-8 gap-y-4 text-sm",
div { class: "flex-1 min-w-[140px]",
label { class: "{META_LABEL_CLASS}",
"Slug"
}
input {
class: "{META_INPUT_CLASS}",
placeholder: "自动生成",
value: "{slug}",
oninput: move |evt| slug.set(evt.value()),
}
}
div { class: "flex-1 min-w-[140px]",
label { class: "{META_LABEL_CLASS}",
"标签"
}
input {
class: "{META_INPUT_CLASS}",
placeholder: "逗号分隔",
value: "{tags}",
oninput: move |evt| tags.set(evt.value()),
}
}
}
// 封面图上传区:空态矮横条(不挤压编辑器),有图时展开 16:9 预览。
// 容器统一绑定拖拽与粘贴事件;内部按 cover_image / cover_uploading 切换空态、上传中、预览。
div {
@ -691,32 +720,6 @@ fn write_editor(post_id: Option<i32>) -> Element {
}
}
}
// 元数据行 - 紧凑精致
div { class: "flex flex-wrap items-end gap-x-8 gap-y-4 text-sm",
div { class: "flex-1 min-w-[140px]",
label { class: "{META_LABEL_CLASS}",
"Slug"
}
input {
class: "{META_INPUT_CLASS}",
placeholder: "自动生成",
value: "{slug}",
oninput: move |evt| slug.set(evt.value()),
}
}
div { class: "flex-1 min-w-[140px]",
label { class: "{META_LABEL_CLASS}",
"标签"
}
input {
class: "{META_INPUT_CLASS}",
placeholder: "逗号分隔",
value: "{tags}",
oninput: move |evt| tags.set(evt.value()),
}
}
}
}
// 编辑器区域 - 沾满剩余高度,但保证最小编辑空间。