diff --git a/packages/trees/src/model/publicTypes.ts b/packages/trees/src/model/publicTypes.ts
index e43cd6fba..33d6029ad 100644
--- a/packages/trees/src/model/publicTypes.ts
+++ b/packages/trees/src/model/publicTypes.ts
@@ -142,17 +142,13 @@ export interface FileTreeDirectoryHandle extends FileTreeItemHandleBase {
export interface FileTreeFileHandle extends FileTreeItemHandleBase {
isDirectory(): false;
}
-
export type FileTreeItemHandle = FileTreeDirectoryHandle | FileTreeFileHandle;
-
export interface FileTreeRenderOptions {
- // Hint how many rows should fit in the first render before the browser can
- // measure the real scroll viewport. Fractional values are allowed when the
- // desired first-render budget is not an exact multiple of itemHeight.
initialVisibleRowCount?: number;
itemHeight?: number;
overscan?: number;
stickyFolders?: boolean;
+ flattenedSegmentsTruncation?: 'per-segment' | 'end';
}
export type FileTreeScrollOffset = 'top' | 'center' | 'nearest';
diff --git a/packages/trees/src/render/FileTree.ts b/packages/trees/src/render/FileTree.ts
index 3948e3c77..9080a8b7e 100644
--- a/packages/trees/src/render/FileTree.ts
+++ b/packages/trees/src/render/FileTree.ts
@@ -190,7 +190,11 @@ export class FileTree
readonly #density: FileTreeDensityPreset;
readonly #viewOptions: Pick<
FileTreeOptions,
- 'initialVisibleRowCount' | 'itemHeight' | 'overscan' | 'stickyFolders'
+ | 'initialVisibleRowCount'
+ | 'itemHeight'
+ | 'overscan'
+ | 'stickyFolders'
+ | 'flattenedSegmentsTruncation'
>;
#fileTreeContainer: HTMLElement | undefined;
#gitStatusState: FileTreeGitStatusState | null;
@@ -230,6 +234,7 @@ export class FileTree
stickyFolders,
unsafeCSS,
initialVisibleRowCount,
+ flattenedSegmentsTruncation,
...controllerOptions
} = options;
this.#composition = composition;
@@ -248,6 +253,7 @@ export class FileTree
itemHeight: this.#density.itemHeight,
overscan,
stickyFolders,
+ flattenedSegmentsTruncation,
initialVisibleRowCount,
};
this.#controller = new FileTreeController({
@@ -561,6 +567,7 @@ export class FileTree
itemHeight?: number;
overscan?: number;
stickyFolders?: boolean;
+ flattenedSegmentsTruncation?: 'per-segment' | 'end';
} {
return {
initialViewportHeight: resolveInitialViewportHeight({
@@ -570,6 +577,8 @@ export class FileTree
itemHeight: this.#viewOptions.itemHeight,
overscan: this.#viewOptions.overscan,
stickyFolders: this.#viewOptions.stickyFolders,
+ flattenedSegmentsTruncation:
+ this.#viewOptions.flattenedSegmentsTruncation,
};
}
@@ -877,6 +886,7 @@ export function preloadFileTree(options: FileTreeOptions): FileTreeSsrPayload {
searchFakeFocus,
stickyFolders,
unsafeCSS,
+ flattenedSegmentsTruncation,
initialVisibleRowCount,
...controllerOptions
} = options;
@@ -925,6 +935,7 @@ export function preloadFileTree(options: FileTreeOptions): FileTreeSsrPayload {
searchEnabled: search === true,
searchFakeFocus: searchFakeFocus === true,
stickyFolders,
+ flattenedSegmentsTruncation,
initialViewportHeight,
})
);
diff --git a/packages/trees/src/render/FileTreeView.tsx b/packages/trees/src/render/FileTreeView.tsx
index 0d3cbab06..ecf68afc7 100644
--- a/packages/trees/src/render/FileTreeView.tsx
+++ b/packages/trees/src/render/FileTreeView.tsx
@@ -78,7 +78,8 @@ import {
function formatFlattenedSegments(
row: FileTreeVisibleRow,
renameInput: JSX.Element | null = null,
- dragTargetFlattenedSegmentPath: string | null = null
+ dragTargetFlattenedSegmentPath: string | null = null,
+ flattenedSegmentsTruncation: 'per-segment' | 'end' = 'per-segment'
): JSX.Element | string {
'use no memo';
const segments = row.flattenedSegments;
@@ -86,7 +87,13 @@ function formatFlattenedSegments(
return renameInput ?? row.name;
}
- return (
+ return flattenedSegmentsTruncation === 'end' ? (
+ (renameInput ?? (
+
+ {segments.map((segment) => segment.name).join(' / ')}
+
+ ))
+ ) : (
{segments.map((segment, index) => {
const isLast = index === segments.length - 1;
@@ -848,6 +855,7 @@ function renderFileTreeRowContent(
gitLaneActive = false,
renameInput = null,
showDecorativeActionAffordance = false,
+ flattenedSegmentsTruncation = 'per-segment',
}: {
actionLaneEnabled?: boolean;
customDecoration?: FileTreeRowDecoration | null;
@@ -857,6 +865,7 @@ function renderFileTreeRowContent(
gitLaneActive?: boolean;
renameInput?: JSX.Element | null;
showDecorativeActionAffordance?: boolean;
+ flattenedSegmentsTruncation?: 'per-segment' | 'end';
} = {}
): JSX.Element {
const targetPath = getFileTreeRowPath(row);
@@ -886,7 +895,8 @@ function renderFileTreeRowContent(
? formatFlattenedSegments(
row,
renameInput,
- dragTargetFlattenedSegmentPath
+ dragTargetFlattenedSegmentPath,
+ flattenedSegmentsTruncation
)
: (renameInput ?? (
@@ -929,6 +939,7 @@ type FileTreeRenderedRowMode = FileTreeRowClickMode;
// with a different `registerButton` target.
type FileTreeRenderRowFrame = {
controller: FileTreeController;
+ flattenedSegmentsTruncation: 'per-segment' | 'end';
renameView: ReturnType;
visualFocusPath: string | null;
contextHoverPath: string | null;
@@ -999,6 +1010,7 @@ function renderStyledRow(
): JSX.Element {
const {
controller,
+ flattenedSegmentsTruncation,
renameView,
visualFocusPath,
contextHoverPath,
@@ -1077,6 +1089,7 @@ function renderStyledRow(
customDecoration,
decorationLaneEnabled,
dragTargetFlattenedSegmentPath: dragTarget?.flattenedSegmentPath ?? null,
+ flattenedSegmentsTruncation,
gitDecoration,
gitLaneActive,
renameInput,
@@ -1239,6 +1252,7 @@ export function FileTreeView({
searchFakeFocus = false,
slotHost,
stickyFolders = false,
+ flattenedSegmentsTruncation = 'per-segment',
initialViewportHeight = FILE_TREE_DEFAULT_VIEWPORT_HEIGHT,
}: FileTreeViewProps): JSX.Element {
'use no memo';
@@ -3636,6 +3650,7 @@ export function FileTreeView({
contextMenuRightClickEnabled,
contextMenuTriggerMode,
controller,
+ flattenedSegmentsTruncation,
directoriesWithGitChanges,
dragAndDropEnabled,
draggedPathSet,