Task #514: Align note composer with folders rail
Original task: On the Notes page the "اكتب ملاحظة" composer sat alone in a full-width row above the content row, while the "المجلدات" FoldersRail started in the row below. Composer appeared high, rail visibly lower with empty space between them. Change: - Switched the folders+content row in `artifacts/tx-os/src/pages/notes.tsx` from flex to CSS grid: `grid md:grid-cols-[14rem_minmax(0,1fr)]`. Composer is placed in col 2 row 1, FoldersRail in col 1 (row-span-2 when composer is shown), content in col 2 row 2. Result: composer's top edge aligns with the rail's top edge on desktop and the empty gap is gone. - On mobile (`grid-cols-1`), `order-1 / order-2 / order-3` give the exact original mobile reading order: composer → rail → content. - Added a `className?: string` prop to `FoldersRail` (`artifacts/tx-os/src/components/notes/folders-rail.tsx`) appended to its root `<aside>`, so the page can pass grid placement classes. - Hidden-composer views (Inbox / Sent / Archived / Shared-with-me) collapse cleanly via conditional `md:row-span-2` on the rail and conditional `md:row-start-1 / md:row-start-2` on the content column — desktop becomes a simple two-cell row and mobile stays rail → content, matching the original behavior. Behavior preserved: - `showTopComposer` gating unchanged. - `data-testid="notes-top-composer"` preserved. - FoldersRail's existing internal classes unchanged; new className prop is purely additive. - Mobile reading order in active/non-shared view: composer → rail → content (same as before this task, when composer was a standalone block above the row). - Mobile reading order in hidden-composer views: rail → content (unchanged). Verification: `pnpm --filter @workspace/tx-os exec tsc --noEmit` passes. No test files reference the composer block by structural selectors that the move would break. No deviations from the plan.
This commit is contained in:
@@ -777,14 +777,32 @@ export default function NotesPage() {
|
||||
The sticky header above keeps the controls pinned. */}
|
||||
<div className="flex-1 flex flex-col">
|
||||
|
||||
{/* Task #514: composer moved INSIDE the main content column so it
|
||||
shares the same row (and same top edge) as the FoldersRail on
|
||||
desktop. On narrow widths the row stacks (`flex-col`); the
|
||||
`order-*` classes keep the composer ABOVE the folders rail in
|
||||
that case so the original mobile reading order is preserved.
|
||||
Hidden conditions (Inbox/Sent/Archived/Shared) are unchanged
|
||||
— see `showTopComposer`. */}
|
||||
<div className="flex-1 px-4 py-6 max-w-6xl w-full mx-auto flex flex-col md:flex-row gap-6">
|
||||
{/* Task #514: switched the folders+content row from flex to CSS
|
||||
grid so the top composer can sit at the SAME vertical
|
||||
position as the FoldersRail on desktop, while still
|
||||
preserving the original mobile reading order
|
||||
(composer → rail → content). Pure flex can't do both: on
|
||||
desktop we need composer + content stacked in the right
|
||||
column, on mobile we need composer above the rail —
|
||||
incompatible with a single flex direction. Grid solves it
|
||||
with explicit `col-start` / `row-start` placement on md+
|
||||
and natural `order-*` flow on mobile. Hidden-composer views
|
||||
(Inbox / Sent / Archived / Shared-with-me) collapse cleanly
|
||||
to the original two-cell layout via conditional row-span
|
||||
/ row-start. */}
|
||||
<div className="flex-1 px-4 py-6 max-w-6xl w-full mx-auto grid gap-4 md:gap-x-6 md:gap-y-4 md:grid-cols-[14rem_minmax(0,1fr)]">
|
||||
{showTopComposer && (
|
||||
<div
|
||||
className="order-1 md:order-none md:col-start-2 md:row-start-1"
|
||||
data-testid="notes-top-composer"
|
||||
>
|
||||
<Composer
|
||||
labels={labels}
|
||||
folderSelection={folderSelection}
|
||||
onSend={(id) => setSendForNoteId(id)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{showFolders && (
|
||||
<FoldersRail
|
||||
folders={folders}
|
||||
@@ -794,19 +812,16 @@ export default function NotesPage() {
|
||||
totalCount={notes.length}
|
||||
onShareFolder={(f) => setFolderShareFor(f)}
|
||||
mode={view === "active" && folderSelection.kind === "all" ? "chips-only" : "rail"}
|
||||
className={showTopComposer ? "order-2 md:order-1" : undefined}
|
||||
className={`order-2 md:order-none md:col-start-1 md:row-start-1${
|
||||
showTopComposer ? " md:row-span-2" : ""
|
||||
}`}
|
||||
/>
|
||||
)}
|
||||
<div className={`flex-1 min-w-0${showTopComposer ? " order-1 md:order-2" : ""}`}>
|
||||
{showTopComposer && (
|
||||
<div className="mb-4" data-testid="notes-top-composer">
|
||||
<Composer
|
||||
labels={labels}
|
||||
folderSelection={folderSelection}
|
||||
onSend={(id) => setSendForNoteId(id)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className={`min-w-0 order-3 md:order-none md:col-start-2 ${
|
||||
showTopComposer ? "md:row-start-2" : "md:row-start-1"
|
||||
}`}
|
||||
>
|
||||
{view === "active" && folderSelection.kind === "shared-folder" && (
|
||||
// Recipient view of a folder shared with the current user. Rendered
|
||||
// before the regular active branch so we never mount the Composer
|
||||
|
||||
Reference in New Issue
Block a user