fix: 适配 DSH 0.1.x 的 [data-slot] DOM 结构,恢复 Session log 挤压与布局
DSH 0.1.x 把 slot 宿主包进 [data-slot] 容器:
#root > div[data-slot=root] > div.frame > div.centerCol
> div[data-slot=conversation] > div.root[data-phase]
> div[data-slot=conversation.session.header] > header
旧选择器 #root > div > div:nth-child(2) 选中的是 data-slot=root 包装
层的第 2 子元素(不存在,其唯一子元素是 frame),导致:
- 折叠态 header 右 padding 挤压失效(Session log 胶囊被按钮簇盖住)
- 底部面板纵向挤压 / 拖动过渡 / 减少动效全部失效
- Sidebar.tsx 中间列定位器(#root > div 的 children[1])失效,
底部面板宽度测量回退为 0
修复:全部改用 [data-slot] 语义锚点——
- 中间列:#root > div[data-slot=root] > div > div:nth-child(2)
- header:body[data-dsh-sidebar-collapsed]
[data-slot=conversation.session.header] > header
- Sidebar.tsx 定位器:#root [data-slot=conversation] 的 parentElement
(= centerCol,探针实测确认)
v0.10.1
This commit is contained in:
+15
-11
@@ -311,8 +311,9 @@ export function Sidebar(props: { ctx: Context; store: SidebarStore }) {
|
||||
// ("squeezes the agent output area") — it starts at the app sidebar's
|
||||
// right edge and ends at the details column's left edge (the details
|
||||
// column sits between the center and the right panel). Measured directly
|
||||
// from the AppFrame's center column DOM (children[1], the layout.css
|
||||
// nth-child(2) column) so the bottom panel tracks the column's real
|
||||
// from the AppFrame's center column DOM (the parent of the
|
||||
// [data-slot="conversation"] wrapper — layout.css's center column) so the
|
||||
// bottom panel tracks the column's real
|
||||
// horizontal edges — including the animated margin-right push while the
|
||||
// right panel opens/closes; a frame that never appears keeps the initial
|
||||
// zero-size fallback (the panel renders at 0 width until measured).
|
||||
@@ -340,17 +341,20 @@ export function Sidebar(props: { ctx: Context; store: SidebarStore }) {
|
||||
useEffect(() => {
|
||||
let disposed = false
|
||||
let observer: ResizeObserver | undefined
|
||||
// Locate the AppFrame's center column (children[1] of the frame div —
|
||||
// layout.css's nth-child(2)). The shell swaps the boot page for the
|
||||
// AppFrame only AFTER boot settles, so the first query may miss it.
|
||||
// Never give up: watch #root's children (the swap mutates them) and
|
||||
// re-run this locator — querying once and bailing would strand the
|
||||
// panel at the zero-size fallback forever (observed: a 1px sliver at
|
||||
// the viewport's left edge).
|
||||
// Locate the AppFrame's center column. DSH 0.1.x wraps slot hosts in
|
||||
// [data-slot] containers: the conversation slot wrapper
|
||||
// ([data-slot="conversation"]) sits directly inside the center column,
|
||||
// so its parent IS that column — no hashed-class or positional
|
||||
// dependency (layout.css uses the same anchor). The shell swaps the
|
||||
// boot page for the AppFrame only AFTER boot settles, so the first
|
||||
// query may miss it. Never give up: watch #root's children (the swap
|
||||
// mutates them) and re-run this locator — querying once and bailing
|
||||
// would strand the panel at the zero-size fallback forever (observed:
|
||||
// a 1px sliver at the viewport's left edge).
|
||||
const locate = (): void => {
|
||||
if (disposed) return
|
||||
const frame = document.querySelector('#root > div')
|
||||
const col = frame?.children[1] as HTMLElement | undefined
|
||||
const col = document.querySelector('#root [data-slot="conversation"]')
|
||||
?.parentElement as HTMLElement | undefined
|
||||
if (col === undefined) {
|
||||
if (centerColRef.current !== null) {
|
||||
centerColRef.current = null
|
||||
|
||||
+19
-14
@@ -6,11 +6,13 @@
|
||||
* conversation output and the input bar, like a VSCode sidebar.
|
||||
*
|
||||
* The bottom panel squeezes ONLY the center column — it must not cover the
|
||||
* app's own left sidebar or the right panel. The AppFrame's grid items are
|
||||
* (#root > div > div:nth-child(2)): sidebarCol, centerCol, detailsCol, so
|
||||
* the vertical push lands on the center column alone. The fixed panels
|
||||
* cover the vacated strips, which looks seamless because #root's background
|
||||
* is the theme base.
|
||||
* app's own left sidebar or the right panel. DSH 0.1.x wraps slot hosts in
|
||||
* [data-slot] containers, so the AppFrame grid lives one level deeper:
|
||||
* #root > div[data-slot="root"] > div (the frame). Its grid items are
|
||||
* (frame > div:nth-child(1..3)): sidebarCol, centerCol, detailsCol, so the
|
||||
* vertical push lands on the center column alone. The fixed panels cover
|
||||
* the vacated strips, which looks seamless because #root's background is
|
||||
* the theme base.
|
||||
*
|
||||
* The sizes ride CSS variables updated by the Sidebar shell (0 while
|
||||
* collapsed); expand/collapse animates both the margins and the panel
|
||||
@@ -23,10 +25,10 @@
|
||||
}
|
||||
|
||||
/* The AppFrame's grid items are sidebarCol, centerCol, detailsCol (children
|
||||
1-3 of #root > div) — nth-child(2) is the center column. A stretched grid
|
||||
item shrinks by its margins, so the conversation content (output + input
|
||||
bar) lifts without touching the sidebars. */
|
||||
#root > div > div:nth-child(2) {
|
||||
1-3 of #root > div[data-slot="root"] > div) — nth-child(2) is the center
|
||||
column. A stretched grid item shrinks by its margins, so the conversation
|
||||
content (output + input bar) lifts without touching the sidebars. */
|
||||
#root > div[data-slot="root"] > div > div:nth-child(2) {
|
||||
margin-bottom: var(--dsh-sidebar-height, 0px);
|
||||
transition: margin-bottom var(--ds-transition-duration-slow) var(--ds-ease-in-out);
|
||||
}
|
||||
@@ -35,20 +37,23 @@
|
||||
corner. Push the DSH session header's right padding out so its right-aligned
|
||||
utilities (the "Session log" download capsule) yield the corner instead of
|
||||
hiding under the cluster. The header default right-pads 28px; the 2-button
|
||||
cluster spans right 10→70px, so 78px clears it with an 8px gap. The
|
||||
Sidebar shell toggles the body attribute with the panel open state. */
|
||||
body[data-dsh-sidebar-collapsed] #root > div > div:nth-child(2) header {
|
||||
cluster spans right 10→70px, so 78px clears it with an 8px gap. Anchor on
|
||||
the header's slot host wrapper ([data-slot="conversation.session.header"])
|
||||
rather than a positional path: DSH 0.1.x nests the header several levels
|
||||
under the center column. The Sidebar shell toggles the body attribute with
|
||||
the panel open state. */
|
||||
body[data-dsh-sidebar-collapsed] [data-slot="conversation.session.header"] > header {
|
||||
padding-right: 78px;
|
||||
}
|
||||
|
||||
body[data-dsh-sidebar-dragging] #root,
|
||||
body[data-dsh-sidebar-dragging] #root > div > div:nth-child(2) {
|
||||
body[data-dsh-sidebar-dragging] #root > div[data-slot="root"] > div > div:nth-child(2) {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
#root,
|
||||
#root > div > div:nth-child(2) {
|
||||
#root > div[data-slot="root"] > div > div:nth-child(2) {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user