fix: preserve desktop shell layout with side card
This commit is contained in:
+44
-32
@@ -1,38 +1,42 @@
|
||||
/**
|
||||
* Layout push: when a panel is open it OCCUPIES the layout instead of
|
||||
* floating over it — the app shell (#root, the AppFrame three-column grid)
|
||||
* gives up space. Only the center column is flexible (1fr), so the right
|
||||
* panel's width squeeze (margin-right on #root) lands exactly on the
|
||||
* conversation output and the input bar, like a VSCode sidebar.
|
||||
* Layout push: an open panel occupies layout instead of floating over it.
|
||||
* The right panel reserves padding inside the AppFrame three-column grid,
|
||||
* so the app sidebar, conversation, and details column all remain to its
|
||||
* left while the frame's border-box stays viewport-wide. Harness measures
|
||||
* that border-box to choose desktop versus narrow presentation; preserving
|
||||
* it prevents a desktop window from entering narrow mode merely because the
|
||||
* plugin panel opened.
|
||||
*
|
||||
* The width rides `calc(100% - var(...))` instead of a bare margin on a
|
||||
* full-width box: some desktop shells (DSH Desktop, #208) set #root to
|
||||
* width:100%, where a margin would overflow the viewport additively —
|
||||
* the calc keeps the box at exactly 100% minus the push in every shell.
|
||||
* Width and margin transition in lockstep (same variable, same duration
|
||||
* and easing), so expand/collapse animates the content width exactly as
|
||||
* the bare-margin version did.
|
||||
* AppFrame positions its details drag handle from the measured border-box.
|
||||
* Move that handle left by the same reserved width so it stays on the details
|
||||
* column edge. The ordinary sidebar handle remains at its native coordinate.
|
||||
*
|
||||
* The bottom panel squeezes ONLY the center column — it must not cover the
|
||||
* app's own left sidebar or the right panel. The anchor is the frame's
|
||||
* center grid item via its stable data attribute ([data-pane="conversation"]
|
||||
* on the centerCol inside [data-dsh-frame]), not a positional path: the
|
||||
* frame's child order also contains an overlay layer and drag handles
|
||||
* (verified against a live DSH 0.1.x page), so nth-child is brittle. A
|
||||
* stretched grid item shrinks by its margins, so the conversation content
|
||||
* (output + input bar) lifts without touching the sidebars.
|
||||
* The bottom panel squeezes only the conversation column. The anchor is the
|
||||
* [data-dsh-center-col] tag the Sidebar shell's locator writes on the
|
||||
* frame's measured center grid item (Sidebar.tsx locate — not a positional
|
||||
* path: the frame also contains an overlay layer and drag handles). A
|
||||
* stretched grid item shrinks by its bottom margin, so the conversation
|
||||
* output and composer lift without touching either sidebar.
|
||||
*
|
||||
* The sizes ride CSS variables updated by the Sidebar shell (0 while
|
||||
* collapsed); expand/collapse animates both the margins and the panel
|
||||
* slides on the same theme duration. Drags disable the transition so the
|
||||
* layout tracks the pointer.
|
||||
* Sizes ride CSS variables updated by the Sidebar shell (0 while collapsed).
|
||||
* Expand/collapse uses the host theme duration; drags disable transitions so
|
||||
* every reserved edge tracks the pointer.
|
||||
*/
|
||||
#root {
|
||||
margin-right: var(--dsh-sidebar-width, 0px);
|
||||
width: calc(100% - var(--dsh-sidebar-width, 0px));
|
||||
/* Current shells expose [data-dsh-frame]; rc.8-era shells expose the same
|
||||
AppFrame only as the root slot's direct child. */
|
||||
#root [data-dsh-frame],
|
||||
#root > [data-slot="root"] > div {
|
||||
box-sizing: border-box;
|
||||
padding-right: var(--dsh-sidebar-width, 0px);
|
||||
transition: padding-right var(--ds-transition-duration-slow) var(--ds-ease-in-out);
|
||||
}
|
||||
|
||||
#root [data-dsh-frame] > [data-side="details"],
|
||||
#root > [data-slot="root"] > div > [data-side="details"] {
|
||||
transform: translateX(calc(0px - var(--dsh-sidebar-width, 0px)));
|
||||
transition:
|
||||
margin-right var(--ds-transition-duration-slow) var(--ds-ease-in-out),
|
||||
width var(--ds-transition-duration-slow) var(--ds-ease-in-out);
|
||||
left var(--ds-transition-duration-slow) var(--ds-ease-in-out),
|
||||
transform var(--ds-transition-duration-slow) var(--ds-ease-in-out);
|
||||
}
|
||||
|
||||
/* The AppFrame's center column. The Sidebar shell's locator (Sidebar.tsx
|
||||
@@ -69,8 +73,13 @@ body[data-dsh-sidebar-collapsed] [data-slot="conversation.session.header"] > hea
|
||||
padding-right: 78px;
|
||||
}
|
||||
|
||||
body[data-dsh-sidebar-dragging] #root,
|
||||
body[data-dsh-sidebar-dragging] #root [data-dsh-center-col] {
|
||||
body[data-dsh-sidebar-dragging] #root [data-dsh-frame],
|
||||
body[data-dsh-sidebar-dragging] #root > [data-slot="root"] > div,
|
||||
body[data-dsh-sidebar-dragging] #root [data-dsh-frame] > [data-side="details"],
|
||||
body[data-dsh-sidebar-dragging] #root > [data-slot="root"] > div > [data-side="details"],
|
||||
body[data-dsh-sidebar-dragging] #root [data-dsh-center-col],
|
||||
#root [data-dsh-frame][data-dragging] > [data-side="details"],
|
||||
#root > [data-slot="root"] > div[data-dragging] > [data-side="details"] {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
@@ -94,7 +103,10 @@ body[data-dsh-sidebar-dragging] #root [data-dsh-center-col] {
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
#root,
|
||||
#root [data-dsh-frame],
|
||||
#root > [data-slot="root"] > div,
|
||||
#root [data-dsh-frame] > [data-side="details"],
|
||||
#root > [data-slot="root"] > div > [data-side="details"],
|
||||
#root [data-dsh-center-col] {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user