diff --git a/src/renderer/src/components/browser-pane/workspace-doc/doc-preview-document-chip.tsx b/src/renderer/src/components/browser-pane/workspace-doc/doc-preview-document-chip.tsx index 67efecdbc8b..8fafb551725 100644 --- a/src/renderer/src/components/browser-pane/workspace-doc/doc-preview-document-chip.tsx +++ b/src/renderer/src/components/browser-pane/workspace-doc/doc-preview-document-chip.tsx @@ -35,7 +35,7 @@ export function DocPreviewDocumentChip({ type="button" onClick={() => void copyText()} aria-label={copied ? copiedLabel : copyLabel} - className="flex min-w-0 flex-1 items-center gap-2 overflow-hidden rounded-xl border border-border bg-background px-3 py-1 text-left shadow-sm hover:bg-accent/40 focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none" + className="@container flex min-w-0 flex-1 items-center gap-2 overflow-hidden rounded-xl border border-border bg-background px-3 py-1 text-left shadow-sm hover:bg-accent/40 focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-none" > {copied ? ( @@ -47,19 +47,21 @@ export function DocPreviewDocumentChip({ {identity.directoryPrefix} {identity.fileName} - {/* Why everything here can shrink: a fixed-width child of a squeezed flex row overflows - its parent's layout box even under overflow-hidden, and this row sits beside a path - that can be arbitrarily long in an arbitrarily narrow pane. */} - - + {/* Below 24rem of chip width this row hides whole rather than clipping into slivers — + 384px is what icon + label + a capped badge + a readable path stub need, so visible + implies contained. The tooltip keeps the full identity either way. */} + + {translate( 'auto.components.editor.HtmlDocPreview.workspaceFileChipLabel', 'Workspace file' )} {identity.hostLabel ? ( - - {identity.hostLabel} + + {/* Why the inner span: text directly inside the flex pill clips both ends with no + ellipsis — text-overflow needs a non-flex text box. */} + {identity.hostLabel} ) : null} diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 53aabcd4a00..6e50f18a932 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -14811,7 +14811,11 @@ "openExternallyControl": "Open with default app", "copyDocumentRelativePathControl": "Copy relative path", "openExternallyUnknownHostError": "Can't open '{{value0}}': the host that owns it is no longer known.", - "downloadBlockedNotice": "Downloads are disabled in document previews." + "downloadBlockedNotice": "Downloads are disabled in document previews.", + "directoryAuthorizationFailed": "Could not allow access to this directory.", + "directoryAccessRequest": "This preview wants to read files in {{path}}.", + "dismissAccessRequest": "Dismiss", + "allowDirectory": "Allow folder" } }, "diff": { @@ -16355,6 +16359,13 @@ "description": "Nests this workspace under another in the sidebar. Does not change the base branch.", "searchPlaceholder": "Search workspaces...", "noMatches": "No matches." + }, + "browserPane": { + "workspaceDoc": { + "externalLinkTitle": "Open link to {{host}}?", + "externalLinkConfirm": "Open link", + "externalLinkCancel": "Cancel" + } } }, "i18n": { diff --git a/tests/e2e/paired-remote-html-preview-local-render.spec.ts b/tests/e2e/paired-remote-html-preview-local-render.spec.ts index dbe2794ed78..a86721741dd 100644 --- a/tests/e2e/paired-remote-html-preview-local-render.spec.ts +++ b/tests/e2e/paired-remote-html-preview-local-render.spec.ts @@ -289,16 +289,23 @@ test('renders a paired HTML doc as a document browser tab while the host gains n const pathChip = page.getByRole('button', { name: 'Copy file path', exact: true }) await expect(pathChip).toBeVisible({ timeout: 30_000 }) await expect(pathChip).toContainText(FIXTURE_NAME) + // Below 24rem of chip width the identity row hides whole instead of clipping into slivers; + // when it shows, the badge must sit inside the chip's own layout box. Which arm runs depends + // on how much width this platform's toolbar leaves the chip — both are the contract. const hostBadge = pathChip.locator('[data-slot="badge"]') - const [pathChipBox, hostBadgeBox] = await Promise.all([ - pathChip.boundingBox(), - hostBadge.boundingBox() - ]) + const pathChipBox = await pathChip.boundingBox() expect(pathChipBox).not.toBeNull() - expect(hostBadgeBox).not.toBeNull() - expect((hostBadgeBox?.x ?? 0) + (hostBadgeBox?.width ?? 0)).toBeLessThanOrEqual( - (pathChipBox?.x ?? 0) + (pathChipBox?.width ?? 0) + 0.5 - ) + if (await hostBadge.isVisible()) { + const hostBadgeBox = await hostBadge.boundingBox() + expect(hostBadgeBox).not.toBeNull() + expect((hostBadgeBox?.x ?? 0) + (hostBadgeBox?.width ?? 0)).toBeLessThanOrEqual( + (pathChipBox?.x ?? 0) + (pathChipBox?.width ?? 0) + 0.5 + ) + } else { + // A chip too narrow for the identity row hides it whole; a wide one must show it. 26rem of + // border-box width clears the 24rem content-box container threshold plus padding. + expect(pathChipBox?.width ?? 0).toBeLessThan(416) + } await expect(page.locator(`[data-tab-group-body-id="${sourceGroupId}"]`)).toBeVisible() await expect(page.locator(`[data-tab-group-body-id="${previewRow.groupId}"]`)).toBeVisible()