@tutti-os/workspace-file-manager 0.0.92 → 0.0.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,6 +24,10 @@ needed to drive those flows so different hosts can integrate primarily by
24
24
  implementing `WorkspaceFileManagerHost` instead of rebuilding workflow around
25
25
  the shared UI.
26
26
 
27
+ The optional React surface persists the adjustable locations-sidebar and
28
+ details-panel widths on the current device. Restored widths are clamped to the
29
+ available surface so the central file list keeps its minimum usable width.
30
+
27
31
  Hosts now provide one app-level i18n runtime and scope it into the file-manager
28
32
  namespace, rather than hand-assembling package-local message objects.
29
33
 
@@ -80,6 +80,8 @@ var workspaceFileManagerEn = {
80
80
  renameLabel: "Rename",
81
81
  renamePlaceholder: "New name",
82
82
  refreshLabel: "Refresh",
83
+ resizeLocationsSidebar: "Resize locations sidebar",
84
+ resizePreviewPanel: "Resize file details panel",
83
85
  retryLabel: "Retry",
84
86
  searchPlaceholder: "Search files",
85
87
  searchResultsLabel: "Search results",
@@ -174,6 +176,8 @@ var workspaceFileManagerZhCN = {
174
176
  renameLabel: "\u91CD\u547D\u540D",
175
177
  renamePlaceholder: "\u65B0\u540D\u79F0",
176
178
  refreshLabel: "\u5237\u65B0",
179
+ resizeLocationsSidebar: "\u8C03\u6574\u4F4D\u7F6E\u4FA7\u680F\u5BBD\u5EA6",
180
+ resizePreviewPanel: "\u8C03\u6574\u6587\u4EF6\u8BE6\u60C5\u9762\u677F\u5BBD\u5EA6",
177
181
  retryLabel: "\u91CD\u8BD5",
178
182
  searchPlaceholder: "\u641C\u7D22\u6587\u4EF6",
179
183
  searchResultsLabel: "\u641C\u7D22\u7ED3\u679C",
@@ -235,4 +239,4 @@ export {
235
239
  createWorkspaceFileManagerI18nRuntime,
236
240
  resolveRevealInFolderLabel
237
241
  };
238
- //# sourceMappingURL=chunk-HIYT2WOT.js.map
242
+ //# sourceMappingURL=chunk-KKKQGRC5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/i18n/workspaceFileManagerI18n.ts"],"sourcesContent":["import {\n createScopedLocaleObjectsI18nModuleManifest,\n createScopedI18nRuntime,\n type I18nDictionary,\n type I18nRuntime\n} from \"@tutti-os/ui-i18n-runtime\";\n\ntype WorkspaceFileManagerI18nLocale = \"en\" | \"zh-CN\";\nexport const workspaceFileManagerI18nNamespace = \"workspaceFileManager\";\nexport const tuttiI18nModule = createScopedLocaleObjectsI18nModuleManifest({\n localeObjectByLocale: {\n en: \"workspaceFileManagerEn\",\n \"zh-CN\": \"workspaceFileManagerZhCN\"\n },\n name: \"workspace-file-manager\",\n namespace: \"workspaceFileManager\",\n sourceRoot: \"packages/workspace/file-manager/src\"\n});\n\nconst workspaceFileManagerEn = {\n backLabel: \"Back\",\n arrangeApplicationLabel: \"Application\",\n arrangeCreatedLabel: \"Created\",\n arrangeDateAddedLabel: \"Date Added\",\n arrangeKindLabel: \"Kind\",\n arrangeLastOpenedLabel: \"Last Opened\",\n arrangeMenuLabel: \"Arrange\",\n arrangeNoneLabel: \"None\",\n breadcrumbRootLabel: \"workspace\",\n cancelLabel: \"Cancel\",\n closeLabel: \"Close\",\n copyLabel: \"Copy\",\n copyPathLabel: \"Copy path\",\n copyPathSuccessTitle: \"Path copied\",\n copySuccessTitle: \"Copied to clipboard\",\n createActionLabel: \"Create\",\n createDirectoryLabel: \"New folder\",\n createDirectoryPlaceholder: \"Folder name\",\n createFileLabel: \"New file\",\n createFilePlaceholder: \"File name\",\n createNameInvalid: \"Use a valid name without path separators\",\n createNameRequired: \"Enter a name to continue\",\n clearSearchLabel: \"Clear search\",\n deleteConfirmDescription: \"Delete {{name}} from this workspace?\",\n deleteLabel: \"Delete\",\n deletingLabel: \"Deleting...\",\n downloadFailedTitle: \"Download failed\",\n downloadLabel: \"Download\",\n dropToImportLabel: \"Drop files here to import to the current folder\",\n emptyDirectory: \"No visible files in this folder\",\n collapseFolderLabel: \"Collapse folder\",\n expandFolderLabel: \"Expand folder\",\n forwardLabel: \"Forward\",\n loading: \"Loading\",\n modifiedLabel: \"Modified\",\n nameLabel: \"Name\",\n noSearchResults: \"No files matched your search\",\n openFailedTitle: \"Open failed\",\n openLabel: \"Open\",\n openInAppBrowserLabel: \"Tutti built-in browser\",\n openInDefaultBrowserLabel: \"Default Browser\",\n openInFileViewerLabel: \"File viewer\",\n openWithLabel: \"Open With\",\n openWithLoadingLabel: \"Loading apps...\",\n openWithOtherLabel: \"Other...\",\n openWithOtherPickerPrompt: \"Choose an application to open this file:\",\n revealInFileExplorerLabel: \"Reveal in File Explorer\",\n revealInFileManagerLabel: \"Reveal in File Manager\",\n revealInFinderLabel: \"Reveal in Finder\",\n unknownErrorMessage: \"Something went wrong. Please try again.\",\n previewBinary:\n \"This file looks binary, so the preview stays read-only for now.\",\n previewDecodeFailed:\n \"We couldn't decode this file as UTF-8 text for preview.\",\n previewDirectoryLabel: \"Folder\",\n previewEmptyLabel: \"Select a file or folder to view details\",\n previewFileTooLarge:\n \"This file is larger than {{maxSize}}, so inline preview is disabled.\",\n previewLoadingLabel: \"Loading preview...\",\n previewTooLarge:\n \"This text file is larger than {{maxSize}}, so inline preview is disabled.\",\n previewUnavailableDownloadBody:\n \"Download {{name}} to open it in another environment.\",\n previewUnavailableOpenBody: \"Open {{name}} in your local app instead.\",\n previewUnavailableTitle: \"Can't preview this file\",\n previewUnsupported: \"Inline preview isn't available for this file type yet.\",\n revealFailedTitle: \"Could not reveal in file manager\",\n renameActionLabel: \"Rename\",\n renameLabel: \"Rename\",\n renamePlaceholder: \"New name\",\n refreshLabel: \"Refresh\",\n resizeLocationsSidebar: \"Resize locations sidebar\",\n resizePreviewPanel: \"Resize file details panel\",\n retryLabel: \"Retry\",\n searchPlaceholder: \"Search files\",\n searchResultsLabel: \"Search results\",\n sizeLabel: \"Size\",\n unsupportedImportBody:\n \"Importing local files into the workspace is not wired up in this desktop build yet.\",\n unsupportedImportTitle: \"Import not available yet\",\n unsupportedViewBody:\n \"Opening {{name}} from the file manager is not supported in this desktop build yet.\",\n unsupportedViewTitle: \"Open not available yet\",\n importConflictDescription:\n \"{{count}} file from this import already exists in this folder tree. Replace it?\",\n importConflictReplaceLabel: \"Replace files\",\n importConflictReviewLabel: \"Existing path\",\n importConflictSummaryFiltered: \"Filtered: {{count}}\",\n importConflictSummaryIgnored: \"Ignored: {{count}}\",\n importConflictSummaryReasonIgnored: \"Ignored by rules: {{count}}\",\n importConflictSummaryReasonSymlink: \"Skipped symlinks: {{count}}\",\n importConflictSummaryReasonSystemMetadata:\n \"Skipped system metadata: {{count}}\",\n importConflictSummarySelected: \"Selected: {{count}}\",\n importConflictTitle: \"Replace existing file?\",\n importFailedTitle: \"Import failed\",\n importLabel: \"Import\",\n importTypeConflictDescription:\n \"{{count}} import path conflicts with an existing file or folder using an incompatible type. Resolve it before retrying.\",\n importTypeConflictTitle: \"Import path conflict\",\n layoutIconViewLabel: \"Icon view\",\n layoutIconViewTooltipLabel: \"Icon mode\",\n layoutListViewLabel: \"List view\",\n layoutListViewTooltipLabel: \"List mode\"\n} as const satisfies I18nDictionary;\n\nconst workspaceFileManagerZhCN = {\n backLabel: \"后退\",\n arrangeApplicationLabel: \"应用程序\",\n arrangeCreatedLabel: \"创建日期\",\n arrangeDateAddedLabel: \"添加日期\",\n arrangeKindLabel: \"种类\",\n arrangeLastOpenedLabel: \"上次打开日期\",\n arrangeMenuLabel: \"排列方式\",\n arrangeNoneLabel: \"无\",\n breadcrumbRootLabel: \"工作区\",\n cancelLabel: \"取消\",\n closeLabel: \"关闭\",\n copyLabel: \"复制\",\n copyPathLabel: \"复制路径\",\n copyPathSuccessTitle: \"复制成功\",\n copySuccessTitle: \"已复制到剪贴板\",\n createActionLabel: \"创建\",\n createDirectoryLabel: \"新建文件夹\",\n createDirectoryPlaceholder: \"文件夹名称\",\n createFileLabel: \"新建文件\",\n createFilePlaceholder: \"文件名称\",\n createNameInvalid: \"请输入有效名称,且不要包含路径分隔符\",\n createNameRequired: \"请输入名称后再继续\",\n clearSearchLabel: \"清空搜索\",\n deleteConfirmDescription: \"要从这个工作区删除 {{name}} 吗?\",\n deleteLabel: \"删除\",\n deletingLabel: \"删除中...\",\n downloadFailedTitle: \"下载失败\",\n downloadLabel: \"下载\",\n dropToImportLabel: \"将文件拖到这里以导入到当前文件夹\",\n emptyDirectory: \"这个文件夹里没有可见文件\",\n collapseFolderLabel: \"收起文件夹\",\n expandFolderLabel: \"展开文件夹\",\n forwardLabel: \"前进\",\n loading: \"加载中\",\n modifiedLabel: \"修改时间\",\n nameLabel: \"名称\",\n noSearchResults: \"没有匹配的文件\",\n openFailedTitle: \"打开失败\",\n openLabel: \"打开\",\n openInAppBrowserLabel: \"Tutti 内置的浏览器\",\n openInDefaultBrowserLabel: \"默认浏览器\",\n openInFileViewerLabel: \"文件查看器\",\n openWithLabel: \"打开方式\",\n openWithLoadingLabel: \"正在加载应用...\",\n openWithOtherLabel: \"其他...\",\n openWithOtherPickerPrompt: \"选择用来打开此文件的应用程序:\",\n revealInFileExplorerLabel: \"在文件资源管理器中显示\",\n revealInFileManagerLabel: \"在文件管理器中显示\",\n revealInFinderLabel: \"在 Finder 中显示\",\n unknownErrorMessage: \"出了点问题,请稍后再试。\",\n previewBinary: \"这个文件更像二进制内容,当前先保持只读占位。\",\n previewDecodeFailed: \"暂时无法按 UTF-8 文本解码这个文件。\",\n previewDirectoryLabel: \"文件夹\",\n previewEmptyLabel: \"选择文件或文件夹查看详情\",\n previewFileTooLarge: \"这个文件超过了 {{maxSize}},暂时不做内联预览。\",\n previewLoadingLabel: \"正在加载预览...\",\n previewTooLarge: \"这个文本文件超过了 {{maxSize}},暂时不做内联预览。\",\n previewUnavailableDownloadBody: \"下载 {{name}} 后再在其他环境中打开。\",\n previewUnavailableOpenBody: \"改为在本地应用中打开 {{name}}。\",\n previewUnavailableTitle: \"这个文件暂时无法预览\",\n previewUnsupported: \"这种文件类型暂时还不支持内联预览。\",\n revealFailedTitle: \"无法在文件管理器中显示\",\n renameActionLabel: \"重命名\",\n renameLabel: \"重命名\",\n renamePlaceholder: \"新名称\",\n refreshLabel: \"刷新\",\n resizeLocationsSidebar: \"调整位置侧栏宽度\",\n resizePreviewPanel: \"调整文件详情面板宽度\",\n retryLabel: \"重试\",\n searchPlaceholder: \"搜索文件\",\n searchResultsLabel: \"搜索结果\",\n sizeLabel: \"大小\",\n unsupportedImportBody:\n \"这个桌面版本暂时还没有把本地文件导入到工作区的链路接通。\",\n unsupportedImportTitle: \"暂不支持导入\",\n unsupportedViewBody:\n \"这个桌面版本暂时还不支持直接从文件管理器打开 {{name}}。\",\n unsupportedViewTitle: \"暂不支持打开\",\n importConflictDescription:\n \"这次导入里有 {{count}} 个文件在当前目录树中已经存在。要替换吗?\",\n importConflictReplaceLabel: \"替换文件\",\n importConflictReviewLabel: \"现有路径\",\n importConflictSummaryFiltered: \"已过滤:{{count}}\",\n importConflictSummaryIgnored: \"已忽略:{{count}}\",\n importConflictSummaryReasonIgnored: \"规则忽略:{{count}}\",\n importConflictSummaryReasonSymlink: \"已跳过符号链接:{{count}}\",\n importConflictSummaryReasonSystemMetadata: \"已跳过系统元数据:{{count}}\",\n importConflictSummarySelected: \"已选择:{{count}}\",\n importConflictTitle: \"替换已有文件?\",\n importFailedTitle: \"导入失败\",\n importLabel: \"导入\",\n importTypeConflictDescription:\n \"这次导入里有 {{count}} 个路径与现有文件或文件夹的类型不兼容。请先处理后再重试。\",\n importTypeConflictTitle: \"导入路径冲突\",\n layoutIconViewLabel: \"图标\",\n layoutIconViewTooltipLabel: \"图标模式\",\n layoutListViewLabel: \"列表\",\n layoutListViewTooltipLabel: \"列表模式\"\n} as const satisfies I18nDictionary;\n\nexport type WorkspaceFileManagerI18nKey = keyof typeof workspaceFileManagerEn;\n\nexport type WorkspaceFileManagerI18nRuntime =\n I18nRuntime<WorkspaceFileManagerI18nKey>;\n\nconst workspaceFileManagerDefaults: Record<\n WorkspaceFileManagerI18nLocale,\n I18nDictionary\n> = {\n en: workspaceFileManagerEn,\n \"zh-CN\": workspaceFileManagerZhCN\n};\n\nexport const workspaceFileManagerI18nResources: Record<\n WorkspaceFileManagerI18nLocale,\n I18nDictionary\n> = {\n en: {\n [workspaceFileManagerI18nNamespace]: workspaceFileManagerDefaults.en\n },\n \"zh-CN\": {\n [workspaceFileManagerI18nNamespace]: workspaceFileManagerDefaults[\"zh-CN\"]\n }\n};\n\nexport function createWorkspaceFileManagerI18nRuntime(\n runtime: I18nRuntime<string>\n): WorkspaceFileManagerI18nRuntime {\n return createScopedI18nRuntime<WorkspaceFileManagerI18nKey>(\n runtime,\n workspaceFileManagerI18nNamespace\n );\n}\n\nexport function resolveRevealInFolderLabel(\n copy: WorkspaceFileManagerI18nRuntime,\n platform: NodeJS.Platform\n): string {\n if (platform === \"darwin\") {\n return copy.t(\"revealInFinderLabel\");\n }\n if (platform === \"win32\") {\n return copy.t(\"revealInFileExplorerLabel\");\n }\n return copy.t(\"revealInFileManagerLabel\");\n}\n"],"mappings":"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","names":[]}
@@ -1,2 +1,2 @@
1
- export { W as WorkspaceFileManagerI18nKey, a as WorkspaceFileManagerI18nRuntime, c as createWorkspaceFileManagerI18nRuntime, w as workspaceFileManagerI18nNamespace, b as workspaceFileManagerI18nResources } from '../index-D23bxzS8.js';
1
+ export { W as WorkspaceFileManagerI18nKey, a as WorkspaceFileManagerI18nRuntime, c as createWorkspaceFileManagerI18nRuntime, w as workspaceFileManagerI18nNamespace, b as workspaceFileManagerI18nResources } from '../index-C3AgiOLN.js';
2
2
  import '@tutti-os/ui-i18n-runtime';
@@ -2,7 +2,7 @@ import {
2
2
  createWorkspaceFileManagerI18nRuntime,
3
3
  workspaceFileManagerI18nNamespace,
4
4
  workspaceFileManagerI18nResources
5
- } from "../chunk-HIYT2WOT.js";
5
+ } from "../chunk-KKKQGRC5.js";
6
6
  export {
7
7
  createWorkspaceFileManagerI18nRuntime,
8
8
  workspaceFileManagerI18nNamespace,
@@ -69,6 +69,8 @@ declare const workspaceFileManagerEn: {
69
69
  readonly renameLabel: "Rename";
70
70
  readonly renamePlaceholder: "New name";
71
71
  readonly refreshLabel: "Refresh";
72
+ readonly resizeLocationsSidebar: "Resize locations sidebar";
73
+ readonly resizePreviewPanel: "Resize file details panel";
72
74
  readonly retryLabel: "Retry";
73
75
  readonly searchPlaceholder: "Search files";
74
76
  readonly searchResultsLabel: "Search results";
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { F as WorkspaceFileOpenWithApplication, c as WorkspaceFileEntry, j as WorkspaceFileLocation, D as WorkspaceFileManagerSession } from './workspaceFileManagerLocations-D9EY8vxl.js';
2
- export { C as CreateWorkspaceFileManagerSessionInput, W as WorkspaceFileActivationTarget, a as WorkspaceFileDirectoryListing, b as WorkspaceFileDirectoryLocation, d as WorkspaceFileEntryKind, e as WorkspaceFileExternalLocation, f as WorkspaceFileImportConflict, g as WorkspaceFileImportSummary, h as WorkspaceFileImportSummaryReason, i as WorkspaceFileImportSummaryReasonCount, k as WorkspaceFileLocationKind, l as WorkspaceFileLocationSection, m as WorkspaceFileManagerCapabilities, n as WorkspaceFileManagerFileActivationRequest, p as WorkspaceFileManagerHost, q as WorkspaceFileManagerHostActionMessage, r as WorkspaceFileManagerHostActionMessageStatus, s as WorkspaceFileManagerHostActionResult, t as WorkspaceFileManagerHostExportResult, u as WorkspaceFileManagerHostFallbackAction, v as WorkspaceFileManagerHostFallbackActionKind, w as WorkspaceFileManagerHostFileActivationResult, x as WorkspaceFileManagerHostImportConflict, y as WorkspaceFileManagerHostImportResult, z as WorkspaceFileManagerMutationErrorMessage, A as WorkspaceFileManagerPersistedState, B as WorkspaceFileManagerService, E as WorkspaceFileManagerState, G as WorkspaceFilePreviewKind, H as WorkspaceFilePreviewState, I as WorkspaceFileRecentLocation, J as WorkspaceFileSearchEntry, K as WorkspaceFileSearchResult, L as classifyWorkspaceFilePreviewKind, M as createWorkspaceFileManagerService, N as findWorkspaceFileLocationById, O as flattenWorkspaceFileLocations, P as isWorkspaceFileExternalLocation, Q as isWorkspaceFileRecentLocation, R as resolveWorkspaceFileActivationTarget, S as resolveWorkspaceFileLocationDefaultId } from './workspaceFileManagerLocations-D9EY8vxl.js';
3
- import { a as WorkspaceFileManagerI18nRuntime } from './index-D23bxzS8.js';
4
- export { W as WorkspaceFileManagerI18nKey, c as createWorkspaceFileManagerI18nRuntime, r as resolveRevealInFolderLabel, w as workspaceFileManagerI18nNamespace, b as workspaceFileManagerI18nResources } from './index-D23bxzS8.js';
1
+ import { F as WorkspaceFileOpenWithApplication, c as WorkspaceFileEntry, j as WorkspaceFileLocation, D as WorkspaceFileManagerSession } from './workspaceFileManagerLocations-mW7kL37e.js';
2
+ export { C as CreateWorkspaceFileManagerSessionInput, W as WorkspaceFileActivationTarget, a as WorkspaceFileDirectoryListing, b as WorkspaceFileDirectoryLocation, d as WorkspaceFileEntryKind, e as WorkspaceFileExternalLocation, f as WorkspaceFileImportConflict, g as WorkspaceFileImportSummary, h as WorkspaceFileImportSummaryReason, i as WorkspaceFileImportSummaryReasonCount, k as WorkspaceFileLocationKind, l as WorkspaceFileLocationSection, m as WorkspaceFileManagerCapabilities, n as WorkspaceFileManagerFileActivationRequest, p as WorkspaceFileManagerHost, q as WorkspaceFileManagerHostActionMessage, r as WorkspaceFileManagerHostActionMessageStatus, s as WorkspaceFileManagerHostActionResult, t as WorkspaceFileManagerHostExportResult, u as WorkspaceFileManagerHostFallbackAction, v as WorkspaceFileManagerHostFallbackActionKind, w as WorkspaceFileManagerHostFileActivationResult, x as WorkspaceFileManagerHostImportConflict, y as WorkspaceFileManagerHostImportResult, z as WorkspaceFileManagerMutationErrorMessage, A as WorkspaceFileManagerPersistedState, B as WorkspaceFileManagerService, E as WorkspaceFileManagerState, G as WorkspaceFilePreviewKind, H as WorkspaceFilePreviewState, I as WorkspaceFileRecentLocation, J as WorkspaceFileSearchEntry, K as WorkspaceFileSearchResult, L as classifyWorkspaceFilePreviewKind, M as createWorkspaceFileManagerService, N as findWorkspaceFileLocationById, O as flattenWorkspaceFileLocations, P as isWorkspaceFileExternalLocation, Q as isWorkspaceFileRecentLocation, R as resolveWorkspaceFileActivationTarget, S as resolveWorkspaceFileLocationDefaultId } from './workspaceFileManagerLocations-mW7kL37e.js';
3
+ import { a as WorkspaceFileManagerI18nRuntime } from './index-C3AgiOLN.js';
4
+ export { W as WorkspaceFileManagerI18nKey, c as createWorkspaceFileManagerI18nRuntime, r as resolveRevealInFolderLabel, w as workspaceFileManagerI18nNamespace, b as workspaceFileManagerI18nResources } from './index-C3AgiOLN.js';
5
5
  import { ReactElement, RefObject } from 'react';
6
6
  import { TuttiDateLocale } from '@tutti-os/ui-system/date-format';
7
7
  export { decodeWorkspaceTextFile, isWorkspaceTextFileTooLarge, looksLikeBinaryText, resolveWorkspaceFileExtension, resolveWorkspaceImageMimeType, resolveWorkspaceVideoMimeType, workspaceFilePreviewMaxBytes, workspaceFileTextMaxBytes } from '@tutti-os/workspace-file-preview';
package/dist/index.js CHANGED
@@ -39,10 +39,17 @@ import {
39
39
  resolveRevealInFolderLabel,
40
40
  workspaceFileManagerI18nNamespace,
41
41
  workspaceFileManagerI18nResources
42
- } from "./chunk-HIYT2WOT.js";
42
+ } from "./chunk-KKKQGRC5.js";
43
43
 
44
44
  // src/ui/WorkspaceFileManager.tsx
45
- import { useCallback as useCallback6, useEffect as useEffect7, useMemo as useMemo3, useRef as useRef7, useState as useState8 } from "react";
45
+ import {
46
+ useCallback as useCallback6,
47
+ useEffect as useEffect7,
48
+ useLayoutEffect as useLayoutEffect4,
49
+ useMemo as useMemo3,
50
+ useRef as useRef7,
51
+ useState as useState8
52
+ } from "react";
46
53
  import { cn as cn7 } from "@tutti-os/ui-system";
47
54
 
48
55
  // src/ui/WorkspaceFileManagerContextMenuContainer.tsx
@@ -1982,6 +1989,72 @@ function IconTileRenameInput({
1982
1989
  ] });
1983
1990
  }
1984
1991
 
1992
+ // src/ui/workspaceFileManagerPaneSizing.ts
1993
+ var workspaceFileManagerSidebarDefaultWidth = 460;
1994
+ var workspaceFileManagerSidebarMinWidth = 180;
1995
+ var workspaceFileManagerContentMinWidth = 580;
1996
+ var workspaceFileManagerPaneResizeStep = 24;
1997
+ var workspaceFileManagerPreviewDefaultWidth = 348;
1998
+ var workspaceFileManagerSidebarWidthStorageKey = "tutti.workspace-file-manager.sidebar-width";
1999
+ var workspaceFileManagerPreviewWidthStorageKey = "tutti.workspace-file-manager.preview-width";
2000
+ function readWorkspaceFileManagerSidebarWidth() {
2001
+ return readWorkspaceFileManagerPaneWidth(
2002
+ workspaceFileManagerSidebarWidthStorageKey,
2003
+ workspaceFileManagerSidebarDefaultWidth
2004
+ );
2005
+ }
2006
+ function writeWorkspaceFileManagerSidebarWidth(width) {
2007
+ writeWorkspaceFileManagerPaneWidth(
2008
+ workspaceFileManagerSidebarWidthStorageKey,
2009
+ width
2010
+ );
2011
+ }
2012
+ function readWorkspaceFileManagerPreviewWidth() {
2013
+ return readWorkspaceFileManagerPaneWidth(
2014
+ workspaceFileManagerPreviewWidthStorageKey,
2015
+ workspaceFileManagerPreviewDefaultWidth
2016
+ );
2017
+ }
2018
+ function writeWorkspaceFileManagerPreviewWidth(width) {
2019
+ writeWorkspaceFileManagerPaneWidth(
2020
+ workspaceFileManagerPreviewWidthStorageKey,
2021
+ width
2022
+ );
2023
+ }
2024
+ function clampWorkspaceFileManagerSidebarWidth(input) {
2025
+ const containerWidth = Number.isFinite(input.containerWidth) ? input.containerWidth : workspaceFileManagerSidebarMinWidth + workspaceFileManagerContentMinWidth;
2026
+ const maxWidth = Math.max(
2027
+ workspaceFileManagerSidebarMinWidth,
2028
+ containerWidth - workspaceFileManagerContentMinWidth
2029
+ );
2030
+ const width = Number.isFinite(input.width) ? input.width : workspaceFileManagerSidebarDefaultWidth;
2031
+ return Math.round(
2032
+ Math.min(maxWidth, Math.max(workspaceFileManagerSidebarMinWidth, width))
2033
+ );
2034
+ }
2035
+ function resolveWorkspaceFileManagerSidebarMaxWidth(containerWidth) {
2036
+ const resolvedContainerWidth = Number.isFinite(containerWidth) ? containerWidth : workspaceFileManagerSidebarMinWidth + workspaceFileManagerContentMinWidth;
2037
+ return Math.round(
2038
+ Math.max(
2039
+ workspaceFileManagerSidebarMinWidth,
2040
+ resolvedContainerWidth - workspaceFileManagerContentMinWidth
2041
+ )
2042
+ );
2043
+ }
2044
+ function readWorkspaceFileManagerPaneWidth(storageKey, defaultWidth) {
2045
+ if (typeof window === "undefined") {
2046
+ return defaultWidth;
2047
+ }
2048
+ const storedWidth = Number(window.localStorage.getItem(storageKey));
2049
+ return Number.isFinite(storedWidth) && storedWidth > 0 ? storedWidth : defaultWidth;
2050
+ }
2051
+ function writeWorkspaceFileManagerPaneWidth(storageKey, width) {
2052
+ if (typeof window === "undefined" || !Number.isFinite(width) || width <= 0) {
2053
+ return;
2054
+ }
2055
+ window.localStorage.setItem(storageKey, String(width));
2056
+ }
2057
+
1985
2058
  // src/ui/WorkspaceFileManagerPanels.tsx
1986
2059
  import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1987
2060
  var workspaceFileManagerTableGridClassName = "grid-cols-[minmax(0,_1fr)_148px_96px]";
@@ -1996,7 +2069,6 @@ var workspaceFileManagerPreviewDetailGridStyle = {
1996
2069
  gridTemplateColumns: "minmax(82px, 0.8fr) minmax(0, 1.2fr)"
1997
2070
  };
1998
2071
  var workspaceFileManagerStackedBreakpoint = 600;
1999
- var workspaceFileManagerPreviewDefaultWidth = 280;
2000
2072
  var workspaceFileManagerPreviewMinWidth = 220;
2001
2073
  var workspaceFileManagerTableMinWidth = 360;
2002
2074
  var workspaceFileManagerMoveDragThreshold = 4;
@@ -2043,6 +2115,9 @@ function WorkspaceFileManagerPanels({
2043
2115
  );
2044
2116
  const previewResizeRef = useRef5(null);
2045
2117
  const [previewPaneWidth, setPreviewPaneWidth] = useState3(
2118
+ readWorkspaceFileManagerPreviewWidth
2119
+ );
2120
+ const [previewPaneMaxWidth, setPreviewPaneMaxWidth] = useState3(
2046
2121
  workspaceFileManagerPreviewDefaultWidth
2047
2122
  );
2048
2123
  const [moveDragPreview, setMoveDragPreview] = useState3(null);
@@ -2266,17 +2341,21 @@ function WorkspaceFileManagerPanels({
2266
2341
  },
2267
2342
  []
2268
2343
  );
2344
+ const resolvePreviewPaneMaxWidth = useCallback2(() => {
2345
+ const containerWidth = rootRef.current?.getBoundingClientRect().width ?? workspaceFileManagerTableMinWidth + workspaceFileManagerPreviewMinWidth;
2346
+ return Math.max(
2347
+ workspaceFileManagerPreviewMinWidth,
2348
+ containerWidth - workspaceFileManagerTableMinWidth
2349
+ );
2350
+ }, [rootRef]);
2269
2351
  useLayoutEffect3(() => {
2270
2352
  const element = rootRef.current;
2271
2353
  if (!element || useStackedPreview || !showPreviewPanel) {
2272
2354
  return;
2273
2355
  }
2274
2356
  const publishLayout = () => {
2275
- const containerWidth = Math.round(element.getBoundingClientRect().width);
2276
- const maxWidth = Math.max(
2277
- workspaceFileManagerPreviewMinWidth,
2278
- containerWidth - workspaceFileManagerTableMinWidth
2279
- );
2357
+ const maxWidth = resolvePreviewPaneMaxWidth();
2358
+ setPreviewPaneMaxWidth(maxWidth);
2280
2359
  setPreviewPaneWidth(
2281
2360
  (currentWidth) => clampPreviewPaneWidth(currentWidth, maxWidth)
2282
2361
  );
@@ -2293,28 +2372,31 @@ function WorkspaceFileManagerPanels({
2293
2372
  return () => {
2294
2373
  observer.disconnect();
2295
2374
  };
2296
- }, [clampPreviewPaneWidth, rootRef, showPreviewPanel, useStackedPreview]);
2375
+ }, [
2376
+ clampPreviewPaneWidth,
2377
+ resolvePreviewPaneMaxWidth,
2378
+ rootRef,
2379
+ showPreviewPanel,
2380
+ useStackedPreview
2381
+ ]);
2297
2382
  const handlePreviewResizePointerDown = useCallback2(
2298
2383
  (event) => {
2299
2384
  if (event.button !== 0) {
2300
2385
  return;
2301
2386
  }
2302
- const containerWidth = rootRef.current?.getBoundingClientRect().width ?? 0;
2303
- const maxWidth = Math.max(
2304
- workspaceFileManagerPreviewMinWidth,
2305
- containerWidth - workspaceFileManagerTableMinWidth
2306
- );
2387
+ const maxWidth = resolvePreviewPaneMaxWidth();
2307
2388
  event.preventDefault();
2308
2389
  event.stopPropagation();
2309
2390
  event.currentTarget.setPointerCapture(event.pointerId);
2310
2391
  previewResizeRef.current = {
2392
+ currentWidth: previewPaneWidth,
2311
2393
  pointerId: event.pointerId,
2312
2394
  startX: event.clientX,
2313
2395
  startWidth: previewPaneWidth,
2314
2396
  maxWidth
2315
2397
  };
2316
2398
  },
2317
- [previewPaneWidth, rootRef]
2399
+ [previewPaneWidth, resolvePreviewPaneMaxWidth]
2318
2400
  );
2319
2401
  const handlePreviewResizePointerMove = useCallback2(
2320
2402
  (event) => {
@@ -2323,9 +2405,11 @@ function WorkspaceFileManagerPanels({
2323
2405
  return;
2324
2406
  }
2325
2407
  const deltaX = event.clientX - resize.startX;
2326
- setPreviewPaneWidth(
2327
- clampPreviewPaneWidth(resize.startWidth - deltaX, resize.maxWidth)
2408
+ resize.currentWidth = clampPreviewPaneWidth(
2409
+ resize.startWidth - deltaX,
2410
+ resize.maxWidth
2328
2411
  );
2412
+ setPreviewPaneWidth(resize.currentWidth);
2329
2413
  },
2330
2414
  [clampPreviewPaneWidth]
2331
2415
  );
@@ -2336,10 +2420,34 @@ function WorkspaceFileManagerPanels({
2336
2420
  return;
2337
2421
  }
2338
2422
  previewResizeRef.current = null;
2423
+ writeWorkspaceFileManagerPreviewWidth(resize.currentWidth);
2339
2424
  event.currentTarget.releasePointerCapture(event.pointerId);
2340
2425
  },
2341
2426
  []
2342
2427
  );
2428
+ const handlePreviewResizeKeyDown = useCallback2(
2429
+ (event) => {
2430
+ let nextWidth = null;
2431
+ if (event.key === "Home") {
2432
+ event.preventDefault();
2433
+ nextWidth = workspaceFileManagerPreviewMinWidth;
2434
+ } else if (event.key === "End") {
2435
+ event.preventDefault();
2436
+ nextWidth = previewPaneMaxWidth;
2437
+ } else if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
2438
+ event.preventDefault();
2439
+ nextWidth = clampPreviewPaneWidth(
2440
+ previewPaneWidth + (event.key === "ArrowLeft" ? workspaceFileManagerPaneResizeStep : -workspaceFileManagerPaneResizeStep),
2441
+ previewPaneMaxWidth
2442
+ );
2443
+ }
2444
+ if (nextWidth !== null) {
2445
+ setPreviewPaneWidth(nextWidth);
2446
+ writeWorkspaceFileManagerPreviewWidth(nextWidth);
2447
+ }
2448
+ },
2449
+ [clampPreviewPaneWidth, previewPaneMaxWidth, previewPaneWidth]
2450
+ );
2343
2451
  const tablePanel = /* @__PURE__ */ jsx6(
2344
2452
  "div",
2345
2453
  {
@@ -2504,16 +2612,22 @@ function WorkspaceFileManagerPanels({
2504
2612
  showPreviewPanel && !useStackedPreview ? /* @__PURE__ */ jsx6(
2505
2613
  "div",
2506
2614
  {
2615
+ "aria-label": copy.t("resizePreviewPanel"),
2507
2616
  "aria-orientation": "vertical",
2617
+ "aria-valuemax": previewPaneMaxWidth,
2618
+ "aria-valuemin": workspaceFileManagerPreviewMinWidth,
2619
+ "aria-valuenow": previewPaneWidth,
2508
2620
  className: "nodrag absolute top-0 bottom-0 z-[1] w-2 cursor-col-resize touch-none",
2509
2621
  role: "separator",
2622
+ tabIndex: 0,
2510
2623
  style: {
2511
2624
  right: previewPaneWidth - 4
2512
2625
  },
2513
2626
  onPointerCancel: handlePreviewResizePointerEnd,
2514
2627
  onPointerDown: handlePreviewResizePointerDown,
2515
2628
  onPointerMove: handlePreviewResizePointerMove,
2516
- onPointerUp: handlePreviewResizePointerEnd
2629
+ onPointerUp: handlePreviewResizePointerEnd,
2630
+ onKeyDown: handlePreviewResizeKeyDown
2517
2631
  }
2518
2632
  ) : null,
2519
2633
  previewPanel
@@ -3634,6 +3748,7 @@ function WorkspaceFileManagerSidebar({
3634
3748
  disabled,
3635
3749
  locationSections,
3636
3750
  selectedLocationId,
3751
+ width,
3637
3752
  onSelectLocation
3638
3753
  }) {
3639
3754
  const visibleSections = locationSections.filter(
@@ -3642,19 +3757,26 @@ function WorkspaceFileManagerSidebar({
3642
3757
  if (visibleSections.length === 0) {
3643
3758
  return null;
3644
3759
  }
3645
- return /* @__PURE__ */ jsx8("aside", { className: "@max-[600px]/workspace-file-manager:hidden flex w-[188px] min-w-[188px] flex-col border-r border-[var(--border-1)] bg-[var(--background-panel)]", children: /* @__PURE__ */ jsx8(ScrollArea2, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx8(TooltipProvider2, { delayDuration: 350, children: /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-3 px-2 py-3", children: visibleSections.map((section) => /* @__PURE__ */ jsxs7("section", { className: "min-w-0", children: [
3646
- /* @__PURE__ */ jsx8("h2", { className: "mb-1 px-2 text-[11px] font-medium uppercase tracking-normal text-[var(--text-tertiary)]", children: section.label }),
3647
- /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-0.5", children: section.locations.map((location) => /* @__PURE__ */ jsx8(
3648
- WorkspaceFileManagerSidebarLocation,
3649
- {
3650
- active: location.id === selectedLocationId,
3651
- disabled,
3652
- location,
3653
- onSelectLocation
3654
- },
3655
- location.id
3656
- )) })
3657
- ] }, section.id)) }) }) }) });
3760
+ return /* @__PURE__ */ jsx8(
3761
+ "aside",
3762
+ {
3763
+ className: "@max-[600px]/workspace-file-manager:hidden flex shrink-0 flex-col border-r border-[var(--border-1)] bg-[var(--background-panel)]",
3764
+ style: { minWidth: width, width },
3765
+ children: /* @__PURE__ */ jsx8(ScrollArea2, { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx8(TooltipProvider2, { delayDuration: 350, children: /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-3 px-2 py-3", children: visibleSections.map((section) => /* @__PURE__ */ jsxs7("section", { className: "min-w-0", children: [
3766
+ /* @__PURE__ */ jsx8("h2", { className: "mb-1 px-2 text-[11px] font-medium uppercase tracking-normal text-[var(--text-tertiary)]", children: section.label }),
3767
+ /* @__PURE__ */ jsx8("div", { className: "flex flex-col gap-0.5", children: section.locations.map((location) => /* @__PURE__ */ jsx8(
3768
+ WorkspaceFileManagerSidebarLocation,
3769
+ {
3770
+ active: location.id === selectedLocationId,
3771
+ disabled,
3772
+ location,
3773
+ onSelectLocation
3774
+ },
3775
+ location.id
3776
+ )) })
3777
+ ] }, section.id)) }) }) })
3778
+ }
3779
+ );
3658
3780
  }
3659
3781
  function WorkspaceFileManagerSidebarLocation({
3660
3782
  active,
@@ -4086,6 +4208,11 @@ function WorkspaceFileManager({
4086
4208
  surface = "card"
4087
4209
  }) {
4088
4210
  const rootRef = useRef7(null);
4211
+ const sidebarResizeRef = useRef7(null);
4212
+ const [sidebarWidth, setSidebarWidth] = useState8(
4213
+ readWorkspaceFileManagerSidebarWidth
4214
+ );
4215
+ const [containerWidth, setContainerWidth] = useState8(0);
4089
4216
  const { arrangeMode, setArrangeMode } = useWorkspaceFileManagerArrangeMode();
4090
4217
  const { layoutMode, setLayoutMode } = useWorkspaceFileManagerLayoutMode();
4091
4218
  const rootView = useWorkspaceFileManagerRootView(session);
@@ -4097,6 +4224,109 @@ function WorkspaceFileManager({
4097
4224
  );
4098
4225
  return location?.kind === "external" ? location : null;
4099
4226
  }, [rootView.locationSections, rootView.selectedLocationId]);
4227
+ const hasLocationSidebar = rootView.locationSections.some(
4228
+ (section) => section.locations.length > 0
4229
+ );
4230
+ const sidebarMaxWidth = containerWidth > 0 ? resolveWorkspaceFileManagerSidebarMaxWidth(containerWidth) : workspaceFileManagerSidebarDefaultWidth;
4231
+ const updateSidebarWidth = useCallback6((width) => {
4232
+ const nextWidth = clampWorkspaceFileManagerSidebarWidth({
4233
+ containerWidth: rootRef.current?.getBoundingClientRect().width ?? 0,
4234
+ width
4235
+ });
4236
+ setSidebarWidth(nextWidth);
4237
+ return nextWidth;
4238
+ }, []);
4239
+ useLayoutEffect4(() => {
4240
+ const element = rootRef.current;
4241
+ if (!element || !hasLocationSidebar) {
4242
+ return;
4243
+ }
4244
+ const publishLayout = () => {
4245
+ const nextContainerWidth = Math.round(
4246
+ element.getBoundingClientRect().width
4247
+ );
4248
+ setContainerWidth(nextContainerWidth);
4249
+ setSidebarWidth(
4250
+ (currentWidth) => clampWorkspaceFileManagerSidebarWidth({
4251
+ containerWidth: nextContainerWidth,
4252
+ width: currentWidth
4253
+ })
4254
+ );
4255
+ };
4256
+ publishLayout();
4257
+ if (typeof ResizeObserver === "undefined") {
4258
+ window.addEventListener("resize", publishLayout);
4259
+ return () => {
4260
+ window.removeEventListener("resize", publishLayout);
4261
+ };
4262
+ }
4263
+ const observer = new ResizeObserver(publishLayout);
4264
+ observer.observe(element);
4265
+ return () => {
4266
+ observer.disconnect();
4267
+ };
4268
+ }, [hasLocationSidebar]);
4269
+ const handleSidebarResizePointerDown = useCallback6(
4270
+ (event) => {
4271
+ if (event.button !== 0) {
4272
+ return;
4273
+ }
4274
+ event.preventDefault();
4275
+ event.currentTarget.setPointerCapture(event.pointerId);
4276
+ sidebarResizeRef.current = {
4277
+ currentWidth: sidebarWidth,
4278
+ pointerId: event.pointerId,
4279
+ startWidth: sidebarWidth,
4280
+ startX: event.clientX
4281
+ };
4282
+ },
4283
+ [sidebarWidth]
4284
+ );
4285
+ const handleSidebarResizePointerMove = useCallback6(
4286
+ (event) => {
4287
+ const resize = sidebarResizeRef.current;
4288
+ if (!resize || resize.pointerId !== event.pointerId) {
4289
+ return;
4290
+ }
4291
+ resize.currentWidth = updateSidebarWidth(
4292
+ resize.startWidth + event.clientX - resize.startX
4293
+ );
4294
+ },
4295
+ [updateSidebarWidth]
4296
+ );
4297
+ const handleSidebarResizePointerEnd = useCallback6(
4298
+ (event) => {
4299
+ const resize = sidebarResizeRef.current;
4300
+ if (!resize || resize.pointerId !== event.pointerId) {
4301
+ return;
4302
+ }
4303
+ sidebarResizeRef.current = null;
4304
+ writeWorkspaceFileManagerSidebarWidth(resize.currentWidth);
4305
+ event.currentTarget.releasePointerCapture(event.pointerId);
4306
+ },
4307
+ []
4308
+ );
4309
+ const handleSidebarResizeKeyDown = useCallback6(
4310
+ (event) => {
4311
+ let nextWidth = null;
4312
+ if (event.key === "Home") {
4313
+ event.preventDefault();
4314
+ nextWidth = updateSidebarWidth(workspaceFileManagerSidebarMinWidth);
4315
+ } else if (event.key === "End") {
4316
+ event.preventDefault();
4317
+ nextWidth = updateSidebarWidth(sidebarMaxWidth);
4318
+ } else if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
4319
+ event.preventDefault();
4320
+ nextWidth = updateSidebarWidth(
4321
+ sidebarWidth + (event.key === "ArrowLeft" ? -workspaceFileManagerPaneResizeStep : workspaceFileManagerPaneResizeStep)
4322
+ );
4323
+ }
4324
+ if (nextWidth !== null) {
4325
+ writeWorkspaceFileManagerSidebarWidth(nextWidth);
4326
+ }
4327
+ },
4328
+ [sidebarMaxWidth, sidebarWidth, updateSidebarWidth]
4329
+ );
4100
4330
  useEffect7(() => {
4101
4331
  function handleCopyShortcut(event) {
4102
4332
  if (!(event.metaKey || event.ctrlKey) || event.key !== "c" || event.shiftKey) {
@@ -4274,6 +4504,7 @@ function WorkspaceFileManager({
4274
4504
  disabled: rootView.isBusy || panelsState.isLoading,
4275
4505
  locationSections: rootView.locationSections,
4276
4506
  selectedLocationId: rootView.selectedLocationId,
4507
+ width: sidebarWidth,
4277
4508
  onSelectLocation: (location) => {
4278
4509
  if (location.kind === "directory") {
4279
4510
  onDirectoryExpanded?.(location.path);
@@ -4282,6 +4513,24 @@ function WorkspaceFileManager({
4282
4513
  }
4283
4514
  }
4284
4515
  ),
4516
+ hasLocationSidebar ? /* @__PURE__ */ jsx9(
4517
+ "div",
4518
+ {
4519
+ "aria-label": i18n.t("resizeLocationsSidebar"),
4520
+ "aria-orientation": "vertical",
4521
+ "aria-valuemax": sidebarMaxWidth,
4522
+ "aria-valuemin": workspaceFileManagerSidebarMinWidth,
4523
+ "aria-valuenow": sidebarWidth,
4524
+ className: "nodrag @max-[600px]/workspace-file-manager:hidden relative z-[1] -ml-1 -mr-1 h-full w-2 shrink-0 cursor-col-resize touch-none outline-none before:absolute before:left-1/2 before:h-full before:w-px before:-translate-x-1/2 before:bg-transparent hover:before:bg-[var(--border-focus)] focus-visible:before:bg-[var(--border-focus)]",
4525
+ role: "separator",
4526
+ tabIndex: 0,
4527
+ onKeyDown: handleSidebarResizeKeyDown,
4528
+ onPointerCancel: handleSidebarResizePointerEnd,
4529
+ onPointerDown: handleSidebarResizePointerDown,
4530
+ onPointerMove: handleSidebarResizePointerMove,
4531
+ onPointerUp: handleSidebarResizePointerEnd
4532
+ }
4533
+ ) : null,
4285
4534
  /* @__PURE__ */ jsx9("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", children: selectedExternalLocation ? renderExternalLocationContent?.(selectedExternalLocation) ?? null : /* @__PURE__ */ jsxs8(Fragment3, { children: [
4286
4535
  /* @__PURE__ */ jsx9(
4287
4536
  WorkspaceFileManagerToolbarContainer,