Fix HTML preview: always-visible buttons and multi-pane group selection

- Make preview buttons always visible (not hover-reveal) for touch support
- Fix event propagation so clicking preview doesn't toggle sections
- Use combined-diff tab's group for sourceGroupId in multi-pane layouts
- Add accessibility label to open-section button
- Support untracked, renamed, and uppercase HTML file extensions
This commit is contained in:
Jinjing
2026-08-06 18:45:43 -07:00
parent f3b2498b5c
commit b3d984da40
4 changed files with 53 additions and 9 deletions
@@ -1299,14 +1299,24 @@ export default function CombinedDiffViewer({
) {
return
}
// Why: use this combined-diff tab's group, not worktree activeGroupId —
// in a multi-pane layout the active group may be a different split.
const state = useAppStore.getState()
const sourceGroupId =
(state.unifiedTabsByWorktree[file.worktreeId] ?? []).find(
(tab) =>
tab.entityId === file.id && (tab.contentType === 'diff' || tab.contentType === 'editor')
)?.groupId ??
activeGroupId ??
null
openFilePreviewToSide({
language: detectLanguage(section.path),
filePath: joinPath(file.filePath, section.path),
worktreeId: file.worktreeId,
sourceGroupId: activeGroupId ?? null
sourceGroupId
})
},
[activeGroupId, file.filePath, file.worktreeId, isCommitMode]
[activeGroupId, file.filePath, file.id, file.worktreeId, isCommitMode]
)
const handleSectionSave = useCallback(
@@ -2055,7 +2065,7 @@ export default function CombinedDiffViewer({
status: section.status,
isCommitSurface: isCommitMode
})
? (previewSection) => openSectionPreview(previewSection)
? openSectionPreview
: undefined
}
setSectionHeights={setSectionHeights}
@@ -76,10 +76,14 @@ export function DiffSectionHeader({
{onOpenPreview != null && (
<button
type="button"
// Why: always visible (unlike other hover-reveal section actions) so
// HTML preview matches the single-file editor header affordance.
// Why: always visible (not hover-reveal) so HTML preview matches the
// single-file editor header and stays usable without hover (touch).
className="p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors"
onClick={onOpenPreview}
onClick={(event) => {
// Why: header owns stopPropagation so callers cannot forget and toggle the section.
event.stopPropagation()
onOpenPreview(event)
}}
title={translate(
'auto.components.editor.EditorPanelHeader.fb8331694e',
'Open Preview to the Side'
@@ -96,8 +100,12 @@ export function DiffSectionHeader({
// Why: always visible so open-file matches Eye preview and works without hover (touch).
type="button"
className="p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors"
onClick={onOpenSection}
onClick={(event) => {
event.stopPropagation()
onOpenSection(event)
}}
title={openSectionTitle}
aria-label={openSectionTitle}
>
<ExternalLink className="size-3.5" />
</button>
@@ -346,8 +346,7 @@ export function DiffSectionItem({
openSectionTitle={openSectionTitle}
onOpenPreview={
onOpenPreview
? (event) => {
event.stopPropagation()
? () => {
onOpenPreview(section, index)
}
: undefined
@@ -22,6 +22,33 @@ describe('canOpenDiffSectionPreviewToSide', () => {
).toBe(true)
})
it('enables untracked and renamed HTML files still present on disk', () => {
expect(
canOpenDiffSectionPreviewToSide({
path: 'scratch.html',
status: 'untracked',
isCommitSurface: false
})
).toBe(true)
expect(
canOpenDiffSectionPreviewToSide({
path: 'renamed.html',
status: 'renamed',
isCommitSurface: false
})
).toBe(true)
})
it('enables uppercase HTML extensions', () => {
expect(
canOpenDiffSectionPreviewToSide({
path: 'Docs/DEMO.HTML',
status: 'modified',
isCommitSurface: false
})
).toBe(true)
})
it('disables deleted HTML files', () => {
expect(
canOpenDiffSectionPreviewToSide({