Fix delete workspace dialog overflow (#2634)
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
parent
368abf2e25
commit
8096f236aa
|
|
@ -217,6 +217,15 @@ The pattern in `src/renderer/src/components/settings/SettingsFormControls.tsx` i
|
|||
- **Control:** the shadcn primitive (`<Input>`, `<Select>`, etc.). Errors surface via `aria-invalid`; the input primitive already maps that to a destructive ring — don't paint your own.
|
||||
- **Trailing metadata:** `text-[11px] text-muted-foreground` below the control (e.g., "Current: 14px · Default: 13px"), not next to the label.
|
||||
|
||||
### Overflow containment
|
||||
|
||||
Every modal, card, list row, and nested preview must stay inside its parent when content contains long paths, branch names, command names, URLs, hashes, or unbroken error text.
|
||||
|
||||
- **Flex/grid children that contain text need `min-w-0`.** Put it on the text column and any nested card/list wrapper that must shrink inside the parent.
|
||||
- **Bound framed previews with `max-w-full overflow-hidden`.** If a nested card shows rows of paths or labels, the framed preview itself should clip instead of contributing an intrinsic width wider than the dialog/card.
|
||||
- **Choose the overflow behavior deliberately.** Use `truncate` for one-line labels and paths, `[overflow-wrap:anywhere]` or `break-all` for multiline error/body text, and `overflow-x-auto` only when horizontal scrolling is the intended interaction.
|
||||
- **Test with hostile strings.** Before shipping dialog/card/list changes, check at least one long local path and one long SSH-style path so local-only happy paths don't hide layout bugs.
|
||||
|
||||
### Scrollbars
|
||||
|
||||
Three scrollbar classes are defined globally in `main.css`:
|
||||
|
|
|
|||
|
|
@ -127,4 +127,19 @@ describe('DeleteWorktreeDialog lineage copy', () => {
|
|||
expect(markup).toContain('Delete Parent Only')
|
||||
expect(markup).not.toContain('Don't ask again')
|
||||
})
|
||||
|
||||
it('keeps long child workspace paths constrained inside the lineage notice', async () => {
|
||||
const child = makeWorktree(
|
||||
'docs-file-upload-discovery-with-a-very-long-name',
|
||||
'/Users/jinjingliang/Documents/projects/agent-slack/docs-file-upload-discovery-with-a-very-long-path-segment'
|
||||
)
|
||||
const { DeleteWorktreeLineageNotice } = await import('./DeleteWorktreeLineageNotice')
|
||||
|
||||
const markup = renderToStaticMarkup(<DeleteWorktreeLineageNotice descendants={[child]} />)
|
||||
|
||||
expect(markup).toContain('min-w-0 max-w-full overflow-hidden rounded-md')
|
||||
expect(markup).toContain('mt-2 min-w-0 max-w-full space-y-1 overflow-hidden')
|
||||
expect(markup).toContain('min-w-0 overflow-hidden')
|
||||
expect(markup).toContain('truncate text-muted-foreground')
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export function DeleteWorktreeLineageNotice({
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="rounded-md border border-border/70 bg-muted/35 px-3 py-2 text-xs">
|
||||
<div className="min-w-0 max-w-full overflow-hidden rounded-md border border-border/70 bg-muted/35 px-3 py-2 text-xs">
|
||||
<div className="flex items-start gap-2">
|
||||
<Workflow className="mt-0.5 size-3.5 shrink-0 text-muted-foreground" />
|
||||
<div className="min-w-0 flex-1">
|
||||
|
|
@ -26,9 +26,11 @@ export function DeleteWorktreeLineageNotice({
|
|||
? '1 child workspace will stay in Orca and on disk.'
|
||||
: `${childWorkspaceCount} child workspaces will stay in Orca and on disk.`}
|
||||
</div>
|
||||
<div className="mt-2 space-y-1 rounded-sm border border-border/60 bg-background/60 px-2 py-1.5">
|
||||
{/* Why: long nowrap paths can otherwise give this grid child an
|
||||
intrinsic width wider than the modal. */}
|
||||
<div className="mt-2 min-w-0 max-w-full space-y-1 overflow-hidden rounded-sm border border-border/60 bg-background/60 px-2 py-1.5">
|
||||
{descendants.slice(0, 4).map((child) => (
|
||||
<div key={child.id} className="min-w-0">
|
||||
<div key={child.id} className="min-w-0 overflow-hidden">
|
||||
<div className="truncate font-medium text-foreground">{child.displayName}</div>
|
||||
<div className="truncate text-muted-foreground">{child.path}</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue