ui: the drafts go chrome-less; serif titles name sessions, always (owner round 11)
Both /chat/new drafts lose their TopBar — home's register now: drag mask first in the DOM, floating sidebar-reopen toggle as the only pointer-events-auto spot, the empty state carrying the orientation. The chain picker's own bar then sits at the very top of the column, exactly like the graph view — no stacked bars, no special-casing. The chain table drops its 'Chains' title with it: the serif title register is RESERVED — it always names a session; the table names nothing, so its bar carries counts + search + close only.
This commit is contained in:
@@ -237,13 +237,15 @@ export function ChainTableBody({
|
||||
|
||||
return (
|
||||
<div data-testid="chain-table" className="relative flex h-full min-h-0 flex-col">
|
||||
{/* THE shared top bar (standardization ruling): title at the standard
|
||||
size, drag mechanics, sidebar reopen, traffic-light gutter — the
|
||||
same element as every chat surface. Search + close
|
||||
carve out with lh-no-drag (the mask law: later in the DOM). */}
|
||||
{/* THE shared top bar (standardization ruling): drag mechanics,
|
||||
sidebar reopen, traffic-light gutter — the same element as every
|
||||
chat surface. NO TITLE (owner round 11, 2026-10-05): the serif
|
||||
title register is RESERVED — it always names a session; the
|
||||
chain table names nothing, so its bar carries counts + search +
|
||||
close only. Search + close carve out with lh-no-drag (the mask
|
||||
law: later in the DOM). */}
|
||||
<TopBar>
|
||||
<span className="min-w-0 flex-1 truncate font-title text-3xl tracking-tight">Chains</span>
|
||||
<span className="shrink-0 text-xs text-muted-foreground">
|
||||
<span className="min-w-0 flex-1 truncate text-xs text-muted-foreground">
|
||||
{chains.length} {chains.length === 1 ? "chain" : "chains"} · {nodes.length} {nodes.length === 1 ? "node" : "nodes"}
|
||||
</span>
|
||||
<div className="relative shrink-0">
|
||||
|
||||
+21
-11
@@ -5,7 +5,7 @@ import { useRouter } from "next/navigation";
|
||||
import { Conversation, ConversationContent, ConversationEmptyState } from "@/components/ai-elements/conversation";
|
||||
import { Composer } from "@/components/composer";
|
||||
import { DictationBar, joinDictation, useDictation } from "@/components/dictation";
|
||||
import { TopBar } from "@/components/top-bar";
|
||||
import { SidebarToggle } from "@/components/sidebar";
|
||||
import { SetupDialog } from "@/components/setup-dialog";
|
||||
import { useStrongKeyless, useZeroKeys, ZeroKeysPill } from "@/components/setup-cta";
|
||||
import { StatsBar } from "@/components/stats-bar";
|
||||
@@ -144,17 +144,19 @@ export function DraftShell({
|
||||
}
|
||||
}, [dictation.active]);
|
||||
return (
|
||||
<div className="flex h-dvh">
|
||||
/* CHROME-LESS CREATION SURFACE (owner round 11, 2026-10-05): the
|
||||
* drafts join home's register — no TopBar, no title (the serif title
|
||||
* always names a session; a draft has none). Home's proven pattern
|
||||
* verbatim: a drag mask first in the DOM, a floating reopen toggle
|
||||
* (the only pointer-events-auto spot), the empty state carrying the
|
||||
* orientation. The chain picker then owns the column top exactly
|
||||
* like the graph view's — no stacked bars. */
|
||||
<div className="relative flex h-dvh">
|
||||
{/* Window-drag strip — deliberately FIRST in the DOM (the mask
|
||||
law: no-drag subtraction resolves by DOM order, so every
|
||||
carved control later in the tree subtracts correctly). */}
|
||||
<div className="lh-drag absolute inset-x-0 top-0 h-13" aria-hidden="true" />
|
||||
<div className="flex min-w-0 flex-1 flex-col">
|
||||
{/* The shared top bar (standardization ruling, 2026-09-29): one
|
||||
element, every surface — h-15, drag, sidebar reopen, lights
|
||||
gutter. h-15 (60px) matches the sidebar's wordmark band. */}
|
||||
<TopBar>
|
||||
<div className="min-w-0 flex-1 truncate font-title text-3xl tracking-tight">
|
||||
{mode === "practice" ? "New practice session" : "New session"}
|
||||
</div>
|
||||
</TopBar>
|
||||
|
||||
<div className="relative flex min-h-0 flex-1">
|
||||
{/* The pointer-events pattern (953b22b): the sticky wrapper is
|
||||
pointer-events-none so nothing here blocks the empty-state
|
||||
@@ -237,6 +239,14 @@ export function DraftShell({
|
||||
{overlay}
|
||||
</div>
|
||||
</div>
|
||||
{/* The floating reopen toggle — pointer-events-none except the
|
||||
toggle itself (home's pattern), painted AFTER the overlay's
|
||||
column so nothing of it blocks the canvas area. */}
|
||||
<header className="pointer-events-none absolute inset-x-0 top-0 flex items-center gap-2 px-3 py-2">
|
||||
<div className="pointer-events-auto">
|
||||
<SidebarToggle />
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,10 @@
|
||||
* - border-b border-border px-3, gap-3 rhythm.
|
||||
*
|
||||
* The consumer brings the title (font-title text-3xl tracking-tight) and
|
||||
* any right-side controls. `drag={false}` is the one escape hatch —
|
||||
* any right-side controls. THE TITLE LAW (owner round 11, 2026-10-05):
|
||||
* the serif title ALWAYS names a session — chrome-less creation surfaces
|
||||
* (home, both /chat/new drafts) and the chain table render NO title.
|
||||
* `drag={false}` is the one escape hatch —
|
||||
* chat's rename mode (app-region:drag would eat the mousedown that
|
||||
* exits the input; owner ask).
|
||||
*
|
||||
|
||||
@@ -125,12 +125,13 @@ describe("ChainTableBody — clusters (the outermost layer)", () => {
|
||||
});
|
||||
|
||||
describe("ChainTableBody — THE shared TopBar + the lines law (owner, round 2)", () => {
|
||||
it("the body renders the standardized top bar: h-15, lh-drag, select-none, standard title size, close X", () => {
|
||||
it("the body renders the standardized top bar: h-15, lh-drag, select-none, NO title (serif = session name, always), close X", () => {
|
||||
const html = render();
|
||||
assert.ok(html.includes("lh-drag"), "the window-drag band");
|
||||
assert.ok(html.includes("select-none"), "dragging never highlights the title");
|
||||
assert.ok(html.includes("select-none"), "dragging never highlights the bar");
|
||||
assert.ok(html.includes("h-15"), "the standard height");
|
||||
assert.ok(html.includes('font-title text-3xl tracking-tight">Chains<'), "the standard title size");
|
||||
assert.ok(!html.includes(">Chains<"), "NO title (owner round 11): the serif register always names a session");
|
||||
assert.ok(html.includes("chain"), "the counts remain");
|
||||
assert.ok(html.includes('data-testid="chain-table-close"'), "the close X");
|
||||
assert.ok(html.includes('data-testid="chain-table-search"'), "the search input");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user