From b9535e071df334e31d12d0bbe15ede3fed36e9ac Mon Sep 17 00:00:00 2001 From: tianma-if Date: Wed, 30 Sep 2026 18:55:00 +0800 Subject: [PATCH] fix(web): keep note titles visible on compact desktop windows Notebook and tag controls no longer refuse to shrink, so a scaled desktop window cannot collapse the title field to a couple of characters. --- .../src/components/DiagramEditorPane.test.mjs | 2 +- apps/web/src/components/DiagramEditorPane.tsx | 4 +-- apps/web/src/components/EditorPane.tsx | 4 +-- apps/web/src/components/EditorTagPicker.tsx | 4 +-- .../src/components/InfographicEditorPane.tsx | 5 ++-- .../MemoEditorChromeDensity.test.mjs | 25 ++++++++++++++++++- .../src/components/MemoEditorChromeDensity.ts | 7 ++++++ .../src/components/MemoEditorMetadataRow.tsx | 4 +-- .../components/MemoEditorTopRowLeading.tsx | 2 +- apps/web/src/components/MemoTitleInput.tsx | 2 +- 10 files changed, 44 insertions(+), 15 deletions(-) diff --git a/apps/web/src/components/DiagramEditorPane.test.mjs b/apps/web/src/components/DiagramEditorPane.test.mjs index ee309f3a..bbaa5102 100644 --- a/apps/web/src/components/DiagramEditorPane.test.mjs +++ b/apps/web/src/components/DiagramEditorPane.test.mjs @@ -444,7 +444,7 @@ describe("diagram editor canvas surface", () => { expect(status).toBeGreaterThan(metadata); expect(headerEnd).toBeGreaterThan(status); expect(toolbar).toBeGreaterThan(headerEnd); - expect(source).toContain('rowClassName="shrink-0 flex-nowrap"'); + expect(source).toContain("rowClassName={MEMO_EDITOR_METADATA_ROW_CLASS_NAME}"); expect(source).toContain("nextTitleStatusClearance"); expect(source).toContain('cn(MEMO_EDITOR_TOP_ROW_CLASS_NAME, "border-b-0")'); expect(source).not.toContain("MEMO_EDITOR_TITLE_REGION_CLASS_NAME"); diff --git a/apps/web/src/components/DiagramEditorPane.tsx b/apps/web/src/components/DiagramEditorPane.tsx index 7b242d34..5d651006 100644 --- a/apps/web/src/components/DiagramEditorPane.tsx +++ b/apps/web/src/components/DiagramEditorPane.tsx @@ -154,6 +154,7 @@ import { MemoEditorMetadataRow } from "@/components/MemoEditorMetadataRow"; import { MemoEditorFocusModeButton, MemoEditorTopRowLeading, MemoEditorUpdatedLabel } from "@/components/MemoEditorTopRowLeading"; import { MemoEditorToolbarDivider } from "@/components/MemoEditorToolbarChrome"; import { + MEMO_EDITOR_METADATA_ROW_CLASS_NAME, MEMO_EDITOR_TOP_ROW_CLASS_NAME, nextTitleStatusClearance, } from "@/components/MemoEditorChromeDensity"; @@ -3089,7 +3090,6 @@ export const DiagramEditorPane = ({ className="flex min-w-0 flex-wrap items-center gap-x-2 gap-y-1 px-4 sm:flex-nowrap" > @@ -3123,7 +3123,7 @@ export const DiagramEditorPane = ({ )} /> -
+
@@ -561,7 +560,7 @@ export default function InfographicEditorPane({ )} /> { test("pads the title until it clears the status cluster", () => { @@ -16,3 +17,25 @@ describe("title status clearance", () => { expect(nextTitleStatusClearance(480, 2000, 1000)).toBe(480); }); }); + +describe("title row width", () => { + test("keeps the title field ahead of notebook and tags on a compact desktop row", () => { + expect(MEMO_EDITOR_METADATA_ROW_CLASS_NAME).toContain("min-w-0"); + expect(MEMO_EDITOR_METADATA_ROW_CLASS_NAME).toContain("shrink"); + expect(MEMO_EDITOR_METADATA_ROW_CLASS_NAME).not.toContain("shrink-0"); + expect(MEMO_EDITOR_METADATA_ROW_CLASS_NAME).not.toContain("max-w-[40%]"); + const leading = readFileSync(new URL("./MemoEditorTopRowLeading.tsx", import.meta.url), "utf8"); + expect(leading).toContain("basis-full"); + expect(leading).toContain("sm:min-w-[min(12rem,45%)]"); + expect(leading).toContain("sm:flex-1"); + const metadata = readFileSync(new URL("./MemoEditorMetadataRow.tsx", import.meta.url), "utf8"); + expect(metadata).toContain("min-w-0 max-w-[18rem] shrink"); + expect(metadata).toContain("[&>span]:truncate"); + expect(metadata).not.toContain("min-w-[9rem]"); + for (const file of ["EditorPane.tsx", "DiagramEditorPane.tsx", "InfographicEditorPane.tsx"]) { + const source = readFileSync(new URL(`./${file}`, import.meta.url), "utf8"); + expect(source).toContain("rowClassName={MEMO_EDITOR_METADATA_ROW_CLASS_NAME}"); + expect(source).not.toContain('className="min-w-0 flex-1"'); + } + }); +}); diff --git a/apps/web/src/components/MemoEditorChromeDensity.ts b/apps/web/src/components/MemoEditorChromeDensity.ts index 441c4d31..4e82cc17 100644 --- a/apps/web/src/components/MemoEditorChromeDensity.ts +++ b/apps/web/src/components/MemoEditorChromeDensity.ts @@ -7,6 +7,13 @@ export const MEMO_EDITOR_READING_GUTTER_CLASS_NAME = export const MEMO_EDITOR_TOP_ROW_CLASS_NAME = "relative flex min-h-12 items-center justify-between gap-2 border-b border-slate-100 py-2 sm:min-h-9 sm:py-0.5"; +/** + * Notebook and tags share the title row and shrink before the title field. + * The title's own minimum width is what keeps typed text visible. + */ +export const MEMO_EDITOR_METADATA_ROW_CLASS_NAME = + "min-w-0 max-w-full shrink overflow-hidden flex-nowrap"; + export const MEMO_EDITOR_TOOLBAR_PADDING_CLASS_NAME = "px-3 py-2 sm:px-4 sm:py-0.5"; diff --git a/apps/web/src/components/MemoEditorMetadataRow.tsx b/apps/web/src/components/MemoEditorMetadataRow.tsx index 3bf13262..6c2c81f3 100644 --- a/apps/web/src/components/MemoEditorMetadataRow.tsx +++ b/apps/web/src/components/MemoEditorMetadataRow.tsx @@ -60,13 +60,13 @@ export const MemoEditorMetadataRow = ({ {currentNotebookLabel} -
+