fix(app): align activity panel with capsule

This commit is contained in:
Dax Raad
2026-10-18 21:17:53 -04:00
Unverified
parent d25bf1f0ec
commit 6113f2cef1
3 changed files with 70 additions and 8 deletions
@@ -63,3 +63,55 @@
opacity: 0.16;
}
}
/*
* The open panel grows out of the capsule, which stays as its bottom row. Everything sits on the capsule's grid:
* 1px border + 8px padding puts glyphs at x=9; a 15px glyph + 6px gap puts text at x=30.
*/
[data-component="menu-v2-content"][data-slot="session-activity-panel"] {
width: max-content;
min-width: max(var(--kb-popper-anchor-width, 0px), 240px);
max-width: min(360px, calc(100vw - 24px));
padding: 4px 4px 32px;
border: 1px solid var(--v2-border-border-base);
border-radius: 14px;
background: var(--v2-background-bg-base);
/* Past the 6px gutter and the 28px capsule, so the panel's bottom edge is the capsule's. */
translate: 0 34px;
[data-component="menu-v2-item"] {
padding-inline: 4px 8px;
border-radius: 10px;
}
[data-slot="menu-v2-item-content"] {
gap: 6px;
}
[data-slot="menu-v2-item-content"] > svg:first-child {
flex: none;
width: 15px;
height: 15px;
}
[data-slot="menu-v2-group-label"] {
height: 24px;
padding-inline: 4px;
}
[data-slot="menu-v2-separator"] {
width: calc(100% + 8px);
margin: 4px -4px;
}
@media (prefers-reduced-motion: reduce) {
animation: none;
}
}
/* While open, the capsule is the panel's bottom row rather than a pill of its own. */
[data-slot="session-activity-chip"][data-expanded] {
border-color: transparent;
background: transparent;
box-shadow: none;
}
@@ -17,8 +17,8 @@ import type { SessionActivityItem } from "./activity-chips"
const timelineDetail = timelinePresets[2].value
const subagents = [
{ id: "ses_child_scroll", agent: "general", description: "Investigate Linux scroll jacking" },
{ id: "ses_child_audit", agent: "explore", description: "Audit the timeline projection" },
{ id: "ses_child_review", agent: "general", description: "Review the composer dock" },
{ id: "ses_child_search", agent: "explore", description: "Search for shell metadata" },
]
@@ -233,7 +233,7 @@ export const TwoSubagents = { render: preview(2, 2, 0) }
export const OneShell = { render: preview(7, 0, 1) }
export const SubagentsAndShells = { render: preview(3, 2, 1) }
export const SubagentsAndShells = { render: preview(4, 2, 2) }
export const ManySubagents = { render: preview(4, 12, 2) }
@@ -21,6 +21,9 @@ export function SessionActivityChips(props: {
}) {
const language = useLanguage()
// With one kind running, the capsule row already names it.
const both = () => props.subagents.length > 0 && props.shells.length > 0
const label = () => language.activitySummary({ subagents: props.subagents.length, shells: props.shells.length })
return (
@@ -31,16 +34,18 @@ export function SessionActivityChips(props: {
as="button"
type="button"
data-slot="session-activity-chip"
class="flex h-7 min-w-0 max-w-full items-center gap-1.5 rounded-full border border-v2-border-border-base bg-v2-background-bg-base ps-2 pe-2.5 text-[13px] font-[530] leading-text-compact tracking-[-0.04px] whitespace-nowrap tabular-nums text-v2-text-text-base shadow-[var(--v2-elevation-raised)] outline-none duration-150 ease-out animate-in fade-in motion-reduce:animate-none hover:bg-v2-background-bg-layer-01 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-v2-border-border-focus data-[expanded]:bg-v2-background-bg-layer-01"
class="flex h-7 min-w-0 max-w-full items-center gap-1.5 rounded-full border border-v2-border-border-base bg-v2-background-bg-base ps-2 pe-2.5 text-[13px] font-[530] leading-text-compact tracking-[-0.04px] whitespace-nowrap tabular-nums text-v2-text-text-base shadow-[var(--v2-elevation-raised)] outline-none duration-150 ease-out animate-in fade-in motion-reduce:animate-none hover:bg-v2-background-bg-layer-01 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-v2-border-border-focus"
>
<SessionActivityGlyph />
<span class="truncate">{label()}</span>
</Menu.Trigger>
<Menu.Portal>
<Menu.Content class="w-72 max-w-[calc(100vw-24px)]" aria-label={label()}>
<Menu.Content data-slot="session-activity-panel" aria-label={label()}>
<Show when={props.subagents.length > 0}>
<Menu.Group>
<Menu.GroupLabel>{language.t("session.activity.section.subagents")}</Menu.GroupLabel>
<Show when={both()}>
<Menu.GroupLabel>{language.t("session.activity.section.subagents")}</Menu.GroupLabel>
</Show>
<For each={props.subagents}>
{(item) => (
<Menu.Item onSelect={() => props.onOpen(item)}>
@@ -58,17 +63,22 @@ export function SessionActivityChips(props: {
</For>
</Menu.Group>
</Show>
<Show when={props.subagents.length > 0 && props.shells.length > 0}>
<Show when={both()}>
<Menu.Separator />
</Show>
<Show when={props.shells.length > 0}>
<Menu.Group>
<Menu.GroupLabel>{language.t("session.activity.section.shells")}</Menu.GroupLabel>
<Show when={both()}>
<Menu.GroupLabel>{language.t("session.activity.section.shells")}</Menu.GroupLabel>
</Show>
<For each={props.shells}>
{(item) => (
<Menu.Item onSelect={() => props.onOpen(item)}>
<Icon name="console" class="shrink-0 text-v2-icon-icon-muted" />
<span dir="ltr" class="me-1.5 min-w-0 flex-1 truncate font-mono text-v2-text-text-base">
<span
dir="ltr"
class="me-1.5 min-w-0 flex-1 truncate font-mono text-[12px] text-v2-text-text-base"
>
{item.label}
</span>
</Menu.Item>