mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-15 04:55:20 +00:00
fix(app): simplify the session location popover (#60492)
This commit is contained in:
parent
ad2e08225f
commit
eeb3c19e57
3 changed files with 45 additions and 14 deletions
|
|
@ -128,7 +128,6 @@ test("the project menu loads changes on demand and opens review", async ({ page
|
|||
"main",
|
||||
/1 Changed file.*\+7.*-3/,
|
||||
"",
|
||||
"This computer",
|
||||
"C:/OpenCode/ProjectChanges",
|
||||
"",
|
||||
"Edit project",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,29 @@
|
|||
padding-inline-end: 30px;
|
||||
}
|
||||
|
||||
/* The location card takes the browser site popover's spacing. Its submenus render elsewhere and keep the menu's. */
|
||||
[data-component="menu-v2-content"][data-slot="session-location-card"] {
|
||||
gap: 2px;
|
||||
padding: 2px;
|
||||
|
||||
[data-component="menu-v2-item"] {
|
||||
padding-inline: 8px;
|
||||
}
|
||||
|
||||
/* A row whose submenu is open keeps the hover background while the pointer is in the submenu. */
|
||||
[data-component="menu-v2-item"][data-expanded] {
|
||||
background: var(--menu-v2-hover);
|
||||
}
|
||||
|
||||
/* Spans the card edge to edge over its padding; a 1px line scaled to a hairline. */
|
||||
[data-slot="menu-v2-separator"] {
|
||||
width: calc(100% + 4px);
|
||||
margin: 0 -2px;
|
||||
background: var(--v2-border-border-base);
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.session-header-layout {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@ export function SessionLocation(props: {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Menu placement="bottom-start" gutter={4} modal={false} onOpenChange={onOpenChange}>
|
||||
{/* The shift lines the card's icons and labels up with the trigger's: 2px card + 8px row padding vs the trigger's 6px. */}
|
||||
<Menu placement="bottom-start" gutter={4} shift={-4} modal={false} onOpenChange={onOpenChange}>
|
||||
<Tooltip
|
||||
placement="bottom"
|
||||
value={<bdi dir="auto">{label()}</bdi>}
|
||||
|
|
@ -320,7 +321,7 @@ export function SessionLocation(props: {
|
|||
</bdi>
|
||||
</Menu.SubTrigger>
|
||||
<Menu.Portal>
|
||||
<Menu.SubContent class="w-max max-w-[calc(100vw-32px)]" aria-label={name()}>
|
||||
<Menu.SubContent class="w-max min-w-[172px] max-w-[calc(100vw-32px)]" aria-label={name()}>
|
||||
<Menu.Item onSelect={() => void copyText(name())}>
|
||||
<Icon name="outline-copy" class="text-v2-icon-icon-muted" />
|
||||
{language.t("session.location.copyBranch")}
|
||||
|
|
@ -368,23 +369,27 @@ export function SessionLocation(props: {
|
|||
)}
|
||||
</Show>
|
||||
<Menu.Separator />
|
||||
<SessionLocationDetail icon="server">
|
||||
<ServerLabel server={server.conn} hint />
|
||||
</SessionLocationDetail>
|
||||
{/* The only server, on this computer, needs no name. */}
|
||||
<Show when={servers.list.length > 1 || !servers.current(server.conn)}>
|
||||
<SessionLocationDetail icon="server">
|
||||
<ServerLabel server={server.conn} hint />
|
||||
</SessionLocationDetail>
|
||||
</Show>
|
||||
<Show when={props.directory}>
|
||||
{(directory) => (
|
||||
<Menu.Sub gutter={4} overflowPadding={16} overlap>
|
||||
<Menu.SubTrigger
|
||||
data-slot="session-location-path"
|
||||
class="[&_[data-slot=menu-v2-item-chevron]]:text-v2-icon-icon-muted"
|
||||
style={{ height: "auto", "padding-block": "6px" }}
|
||||
// The split spans are flex items, which the accessible name would join with a space.
|
||||
aria-label={directory()}
|
||||
>
|
||||
<span class="flex min-w-0 items-start gap-2 text-[12px] leading-4 text-v2-text-text-muted">
|
||||
<Icon name="folder" class="shrink-0 text-v2-icon-icon-muted" />
|
||||
<bdi dir="ltr" class="min-w-0 select-text break-all">
|
||||
{directory()}
|
||||
</bdi>
|
||||
</span>
|
||||
<Icon name="folder" class="shrink-0 text-v2-icon-icon-muted" />
|
||||
{/* Truncates in the middle: the parent folders shrink, the last folder stays whole. */}
|
||||
<bdi dir="ltr" class="flex min-w-0 select-text whitespace-nowrap">
|
||||
<span class="min-w-0 truncate">{directory().slice(0, lastSeparator(directory()))}</span>
|
||||
<span class="max-w-full shrink-0 truncate">{directory().slice(lastSeparator(directory()))}</span>
|
||||
</bdi>
|
||||
</Menu.SubTrigger>
|
||||
<Menu.Portal>
|
||||
<Menu.SubContent class="w-max max-w-[calc(100vw-32px)]" aria-label={directory()}>
|
||||
|
|
@ -438,13 +443,17 @@ export function SessionLocation(props: {
|
|||
|
||||
function SessionLocationDetail(props: ParentProps<{ icon: ComponentProps<typeof Icon>["name"] }>) {
|
||||
return (
|
||||
<div class="flex h-7 min-w-0 items-center gap-2 px-3 text-[13px] font-[440] leading-[var(--line-height-compact)] tracking-[-0.04px] text-v2-text-text-base">
|
||||
<div class="flex h-7 min-w-0 items-center gap-2 px-2 text-[13px] font-[440] leading-[var(--line-height-compact)] tracking-[-0.04px] text-v2-text-text-base">
|
||||
<Icon name={props.icon} class="shrink-0 text-v2-icon-icon-muted" />
|
||||
<span class="flex min-w-0 truncate">{props.children}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function lastSeparator(path: string) {
|
||||
return Math.max(0, path.lastIndexOf("/"), path.lastIndexOf("\\"))
|
||||
}
|
||||
|
||||
export function SessionAncestorTrail(props: {
|
||||
sessionID: string
|
||||
parentID: string
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue