Merge pull request #32313 from overleaf/ae-tab-icon

Add icons to file tabs

GitOrigin-RevId: 7b032c694c4f81e868e5811673b465179e10bae7
This commit is contained in:
Mathias Jakobsen
2026-04-14 11:12:33 +01:00
committed by Copybot
parent d1ce54b513
commit 3bf3264cfe
4 changed files with 77 additions and 8 deletions

View File

@@ -9,6 +9,10 @@ import { debugConsole } from '@/utils/debugging'
import { disambiguatePaths } from '../util/disambiguate-paths'
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
import { useUserSettingsContext } from '@/shared/context/user-settings-context'
import {
FileTreeFindResult,
isFileRefResult,
} from '@/features/ide-react/types/file-tree'
type PersistedTabInfo = { id: string; lifetime: Lifetime }
@@ -16,7 +20,9 @@ type Lifetime = 'permanent' | 'temporary'
export type EditorFileTab = {
id: string
name: string
displayPath: string
isLinkedFile: boolean
lifetime: Lifetime
}
@@ -64,19 +70,29 @@ export const TabsProvider: FC<React.PropsWithChildren> = ({ children }) => {
lifetime: tab.lifetime,
result: findInTree(fileTreeData, tab.id),
}))
.filter(x => !!x.result)
.filter(x => !!x.result) as {
lifetime: Lifetime
result: FileTreeFindResult
}[]
const pathLookup = disambiguatePaths(
tabsFileTreeLookup.map(tab => tab.result!),
tabsFileTreeLookup.map(tab => tab.result),
fileTreeData
)
return tabsFileTreeLookup.map(tab => ({
id: tab.result!.entity._id,
displayPath:
pathLookup.get(tab.result!.entity._id) || tab.result!.entity.name,
lifetime: tab.lifetime,
}))
return tabsFileTreeLookup.map(tab => {
const entity = tab.result.entity
return {
id: entity._id,
name: entity.name,
displayPath: pathLookup.get(entity._id) || entity.name,
isLinkedFile:
isFileRefResult(tab.result) &&
!!tab.result.entity.linkedFileData?.provider,
lifetime: tab.lifetime,
}
})
}, [fileTreeData, openTabs, tabsEnabled])
const openTab = useCallback(

View File

@@ -29,3 +29,15 @@ export type FileTreeFindResult =
| FileTreeFolderFindResult
| FileTreeDocumentFindResult
| FileTreeFileRefFindResult
export const isFolderResult = (
result: FileTreeFindResult
): result is FileTreeFolderFindResult => result.type === 'folder'
export const isDocResult = (
result: FileTreeFindResult
): result is FileTreeDocumentFindResult => result.type === 'doc'
export const isFileRefResult = (
result: FileTreeFindResult
): result is FileTreeFileRefFindResult => result.type === 'fileRef'

View File

@@ -2,6 +2,7 @@ import {
EditorFileTab,
TAB_TRANSFER_TYPE,
} from '@/features/ide-react/context/tabs-context'
import FileTreeIcon from '@/features/file-tree/components/file-tree-icon'
import MaterialIcon from '@/shared/components/material-icon'
import { debugConsole } from '@/utils/debugging'
import classNames from 'classnames'
@@ -196,6 +197,9 @@ export const Tab = memo(function Tab({
'tab-temporary': tab.lifetime === 'temporary',
})}
>
<span className="editor-file-tab-icon">
<FileTreeIcon isLinkedFile={tab.isLinkedFile} name={tab.name} />
</span>
<div className="editor-file-tab-path">&lrm;{tab.displayPath}</div>
<div className="editor-file-tab-action">
<button

View File

@@ -41,6 +41,7 @@
.editor-file-tab {
--tab-bg-color: transparent;
--tab-icon-colour: var(--content-secondary-themed);
display: inline-flex;
align-items: center;
@@ -61,6 +62,7 @@
&.tab-selected {
--tab-bg-color: var(--bg-secondary-themed);
--tab-icon-colour: var(--content-primary-themed);
}
.material-symbols {
@@ -68,6 +70,34 @@
font-size: var(--font-size-03);
}
.file-tree-icon,
.linked-file-highlight {
color: var(--tab-icon-colour);
}
.editor-file-tab-icon {
position: relative;
display: inline-flex;
align-items: center;
flex: 0 0 auto;
}
.file-tree-icon {
margin-right: var(--spacing-01);
}
.linked-file-icon {
position: relative;
left: -2px;
}
.linked-file-highlight {
position: absolute;
top: 6px;
left: 6px !important;
font-size: var(--font-size-01);
}
&.tab-drop-right {
border-right-color: var(--border-primary-themed);
}
@@ -80,6 +110,11 @@
font-style: italic;
}
.editor-file-tab-action {
display: flex;
align-items: center;
}
.editor-file-tab-close-action {
background: transparent;
border: none;
@@ -87,6 +122,8 @@
cursor: pointer;
margin: 0;
padding: 0;
display: flex;
align-items: center;
&:hover {
color: var(--content-secondary-themed);