fix(ui-trajectory): own composer overlay geometry
This commit is contained in:
@@ -208,6 +208,26 @@
|
||||
);
|
||||
}
|
||||
|
||||
/* Views may opt into a composer overlay while ConversationRoot retains
|
||||
ownership of the seat geometry and its active-phase precedence. */
|
||||
.scrollBody:has([data-conversation-composer-overlay]) {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollBody:has([data-conversation-composer-overlay]) > .viewArea {
|
||||
flex: 1 1 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollBody:has([data-conversation-composer-overlay]) > .composerSeat {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
/* Hero phase: the composer stack (hero chrome + workspace row + card) is
|
||||
flex-centered in the column; composer phase docks it at the bottom. Flex,
|
||||
NOT absolute+transform: a transform would make this box the containing
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
.tablePane {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding-bottom: var(--dsh-trajectory-bottom-clearance, 0px);
|
||||
container: trajectory-table / inline-size;
|
||||
}
|
||||
@@ -28,7 +29,7 @@
|
||||
);
|
||||
|
||||
width: 100%;
|
||||
min-width: 480px;
|
||||
min-width: 0;
|
||||
border-spacing: 0;
|
||||
table-layout: fixed;
|
||||
color: var(--dsw-alias-label-primary);
|
||||
@@ -905,7 +906,8 @@
|
||||
.detailBody {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding-bottom: var(--dsh-trajectory-bottom-clearance, 0px);
|
||||
scrollbar-gutter: stable;
|
||||
}
|
||||
|
||||
@@ -459,7 +459,7 @@ export function TrajectoryView({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={css.root}>
|
||||
<div className={css.root} data-conversation-composer-overlay="">
|
||||
<TrajectoryToolbar
|
||||
actualDuration={actualDuration}
|
||||
onActualDurationChange={(nextActualDuration) => {
|
||||
|
||||
@@ -13,30 +13,6 @@
|
||||
background: var(--dsw-alias-bg-layer-1);
|
||||
}
|
||||
|
||||
/* Trajectory keeps the ledger and details panel inside the remaining
|
||||
* conversation height; only the internal panes scroll. The composer floats
|
||||
* over the ledger like chat's sticky seat — absolute, not sticky, because
|
||||
* this host does not scroll. */
|
||||
:global([data-conversation-scroll]):has(.root) {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:global([data-conversation-scroll]):has(.root) > :first-child {
|
||||
flex: 1 1 0;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* div qualifier outranks ConversationRoot's active-phase sticky rule (equal
|
||||
* specificity otherwise, and cross-module source order is bundler-defined). */
|
||||
:global([data-conversation-scroll]):has(.root) > :global(div[data-composer-seat]) {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.ledger {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
@@ -47,8 +23,6 @@
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
|
||||
/* Internal panes reserve the floating composer's live height plus a 16px
|
||||
* breathing gap so end rows and detail bodies can scroll clear of the
|
||||
* overlay. */
|
||||
/* ConversationRoot publishes the floating composer's live height. */
|
||||
--dsh-trajectory-bottom-clearance: calc(var(--dsh-composer-height, 152px) + 16px);
|
||||
}
|
||||
|
||||
@@ -288,6 +288,7 @@ describe('tab switching in ConversationRoot', () => {
|
||||
expect(screen.queryByRole('columnheader')).toBeNull()
|
||||
expect(screen.getByRole('toolbar', { name: 'Trajectory toolbar' })).toBeTruthy()
|
||||
expect(screen.getByRole('region', { name: 'Trajectory timeline' })).toBeTruthy()
|
||||
expect(view.container.querySelector('[data-conversation-composer-overlay]')).toBeTruthy()
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Collapse turns' }))
|
||||
expect(view.container.querySelector('[data-collapsed-summary="turn"]')).toBeTruthy()
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Expand turns' }))
|
||||
|
||||
Reference in New Issue
Block a user