style(web): polish subagent and bash chrome

This commit is contained in:
imccyu
2026-08-01 17:47:34 +08:00
committed by Tianyi Cui
parent ca1d838afc
commit 53ae9abea2
3 changed files with 68 additions and 15 deletions

View File

@@ -55,6 +55,9 @@
position: relative;
min-width: 0;
}
.menu > .node {
margin-left: -8px;
}
.row {
position: relative;
@@ -64,7 +67,7 @@
box-sizing: border-box;
width: 100%;
min-height: 50px;
padding: 7px 8px 7px 3px;
padding: 7px 8px 7px 11px;
border: 0;
border-radius: 8px;
background: transparent;
@@ -76,12 +79,26 @@
outline: none;
}
.row:hover,
.row:focus-visible {
.row:hover > .clickarea,
.row:focus-visible > .clickarea {
background: var(--dsw-alias-interactive-bg-hover);
}
.row > :global([data-state]) {
.clickarea {
box-sizing: border-box;
display: flex;
flex: 1;
align-self: stretch;
align-items: flex-start;
gap: 8px;
min-width: 0;
margin: -7px -8px -7px;
padding: 7px 8px;
border-radius: 8px;
}
.row > :global([data-state]),
.clickarea > :global([data-state]) {
margin-top: 4px;
}
@@ -154,7 +171,7 @@
.children {
position: relative;
margin-left: 10px;
margin-left: 18px;
padding-left: 4px;
}
@@ -171,6 +188,10 @@
height: 26px;
}
.children[aria-busy='true']::before {
content: none;
}
.children > .node::before {
top: 0;
bottom: 0;
@@ -179,15 +200,15 @@
.children > .node:last-child::before {
bottom: auto;
height: 25px;
height: 17px;
}
.children > .node > .row::before {
content: '';
position: absolute;
top: 24px;
top: 16px;
left: -4px;
width: 7px;
width: 14px;
border-top: 1px solid var(--dsw-alias-border-l2);
}

View File

@@ -118,6 +118,7 @@ function CatalogRows({
const childCatalog = catalogs[entry.id]
const isExpanded = expanded.has(entry.id)
const knownLeaf = !entry.hasChildren
const emptyLoading = childCatalog?.state === 'loading' && childCatalog.entries.length === 0
const summary = summaries[entry.id]
const label = entry.label ?? entry.id
const mode = entry.mode === 'one-shot' ? '一次性' : '可继续'
@@ -176,15 +177,21 @@ function CatalogRows({
<IconChevronRightOutline14 />
</button>
)}
<StateDot state={entry.activity === 'running' ? 'ongoing' : 'done'} />
<span className={css.content}>
<span className={css.label}>{label}</span>
<span className={css.summary}>{secondary}</span>
</span>
{time !== undefined && <span className={css.time}>{time}</span>}
<div className={css.clickarea}>
<StateDot state={entry.activity === 'running' ? 'ongoing' : 'done'} />
<span className={css.content}>
<span className={css.label}>{label}</span>
<span className={css.summary}>{secondary}</span>
</span>
{time !== undefined && <span className={css.time}>{time}</span>}
</div>
</div>
{isExpanded && childCatalog !== undefined && !knownLeaf && (
<div role="group" className={css.children}>
<div
role="group"
className={css.children}
aria-busy={emptyLoading || undefined}
>
<CatalogRows
parentSessionId={entry.id}
catalog={childCatalog}

View File

@@ -237,6 +237,31 @@ describe('SubagentCatalogAction', () => {
expect(input.setCatalogOpen).toHaveBeenCalledWith(CHILD, false)
})
it('shows initial descendant loading status without drawing its branch', () => {
const loading = props(catalog(), {
[CHILD]: catalog({ entries: [], state: 'loading' }),
})
const view = render(<SubagentCatalogAction {...loading} />)
fireEvent.click(screen.getByRole('button', { name: /2 个子代理/ }))
fireEvent.click(screen.getByRole('button', { name: '展开 worker 的下级子代理' }))
expect(loading.setCatalogOpen).toHaveBeenCalledWith(CHILD, true)
expect(screen.getByRole('group').getAttribute('aria-busy')).toBe('true')
expect(screen.getByText('正在加载子代理…')).toBeTruthy()
const ready = props(catalog(), {
[CHILD]: catalog({
entries: [{
kind: 'child', id: GRANDCHILD, mode: 'continuable',
label: 'indexer', activity: 'inactive', hasChildren: false,
}],
}),
})
view.rerender(<SubagentCatalogAction {...ready} />)
expect(screen.getByRole('group').getAttribute('aria-busy')).toBeNull()
expect(screen.getByRole('treeitem', { name: /indexer/ })).toBeTruthy()
})
it('uses ArrowRight and ArrowLeft for branch disclosure', async () => {
const input = props(catalog(), {
[CHILD]: catalog({