@parallelworks/ui 0.51.0 → 0.52.0

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.
Files changed (227) hide show
  1. package/README.md +155 -14
  2. package/dist/ai/agent/toolStrings.d.ts +2 -0
  3. package/dist/ai/agent/toolStrings.js +20 -18
  4. package/dist/ai/ai.css +12 -0
  5. package/dist/ai/components/AllocationSelector.js +5 -1
  6. package/dist/ai/components/AttachmentManager.js +51 -42
  7. package/dist/ai/components/AttachmentUpload.d.ts +4 -2
  8. package/dist/ai/components/AttachmentUpload.js +9 -9
  9. package/dist/ai/components/BlockedGroupBanner.js +8 -14
  10. package/dist/ai/components/BranchNavigator.js +11 -12
  11. package/dist/ai/components/ChatEmptyState.js +12 -19
  12. package/dist/ai/components/ChatInput.d.ts +4 -3
  13. package/dist/ai/components/ChatInput.js +27 -13
  14. package/dist/ai/components/ChatMessage.js +45 -121
  15. package/dist/ai/components/ChatMessageList.d.ts +5 -2
  16. package/dist/ai/components/ChatMessageList.js +89 -51
  17. package/dist/ai/components/ChatSidebar.js +11 -7
  18. package/dist/ai/components/ChatThread.js +1 -13
  19. package/dist/ai/components/DragOverlay.js +3 -3
  20. package/dist/ai/components/MessageAttachments.d.ts +10 -0
  21. package/dist/ai/components/MessageAttachments.js +78 -0
  22. package/dist/ai/components/ModelSelector.js +3 -3
  23. package/dist/ai/components/PastedText.js +2 -2
  24. package/dist/ai/components/ProviderIssueBanner.js +19 -23
  25. package/dist/ai/components/ShareDialog.js +2 -2
  26. package/dist/ai/components/agent/ActivityLine.d.ts +0 -2
  27. package/dist/ai/components/agent/ActivityLine.js +8 -51
  28. package/dist/ai/components/agent/AgentMessageParts.js +114 -53
  29. package/dist/ai/core/ChatProvider.d.ts +16 -5
  30. package/dist/ai/core/ChatProvider.js +41 -8
  31. package/dist/ai/core/config.js +4 -3
  32. package/dist/ai/index.d.ts +1 -1
  33. package/dist/ai/index.js +3 -3
  34. package/dist/ai/strings.d.ts +29 -3
  35. package/dist/ai/strings.js +81 -26
  36. package/dist/ai/types.d.ts +4 -0
  37. package/dist/ai/ui/Notice.d.ts +2 -2
  38. package/dist/ai/ui/Notice.js +29 -62
  39. package/dist/ai/ui/sidebar.d.ts +5 -3
  40. package/dist/ai/ui/sidebar.js +21 -9
  41. package/dist/components/ActionMenu.d.ts +1 -0
  42. package/dist/components/ActionMenu.js +6 -1
  43. package/dist/components/AppLink.d.ts +26 -0
  44. package/dist/components/AppLink.js +51 -0
  45. package/dist/components/Avatar.d.ts +2 -1
  46. package/dist/components/Avatar.js +4 -2
  47. package/dist/components/Button.d.ts +15 -5
  48. package/dist/components/Button.js +47 -40
  49. package/dist/components/Callout.d.ts +31 -7
  50. package/dist/components/Callout.js +50 -19
  51. package/dist/components/Card.d.ts +11 -6
  52. package/dist/components/Card.js +14 -8
  53. package/dist/components/Checkbox.js +2 -1
  54. package/dist/components/ColorInput.js +5 -3
  55. package/dist/components/Combobox.js +49 -19
  56. package/dist/components/ConfirmModal.d.ts +19 -8
  57. package/dist/components/ConfirmModal.js +31 -53
  58. package/dist/components/CopyButton.d.ts +38 -0
  59. package/dist/components/CopyButton.js +68 -0
  60. package/dist/components/CreateModal.js +118 -111
  61. package/dist/components/DatePicker.js +12 -8
  62. package/dist/components/DescriptionList.d.ts +25 -5
  63. package/dist/components/DescriptionList.js +56 -22
  64. package/dist/components/Disclosure.js +1 -1
  65. package/dist/components/Drawer.js +10 -16
  66. package/dist/components/Field.d.ts +15 -5
  67. package/dist/components/Field.js +40 -8
  68. package/dist/components/IconButton.d.ts +14 -5
  69. package/dist/components/IconButton.js +25 -14
  70. package/dist/components/InfoTip.d.ts +4 -1
  71. package/dist/components/InfoTip.js +2 -1
  72. package/dist/components/Input.d.ts +14 -8
  73. package/dist/components/Input.js +46 -31
  74. package/dist/components/Loader.js +1 -1
  75. package/dist/components/MenuEntries.d.ts +4 -0
  76. package/dist/components/MenuEntries.js +11 -12
  77. package/dist/components/Meter.js +5 -4
  78. package/dist/components/Modal.d.ts +28 -4
  79. package/dist/components/Modal.js +37 -14
  80. package/dist/components/Overview.d.ts +20 -12
  81. package/dist/components/Overview.js +14 -9
  82. package/dist/components/PageHeader.d.ts +47 -65
  83. package/dist/components/PageHeader.js +275 -153
  84. package/dist/components/PageHeaderAction.d.ts +67 -0
  85. package/dist/components/PageHeaderAction.js +107 -0
  86. package/dist/components/Pagination.js +6 -16
  87. package/dist/components/Popover.js +3 -2
  88. package/dist/components/Provider.d.ts +77 -19
  89. package/dist/components/Provider.js +139 -130
  90. package/dist/components/Radio.js +2 -1
  91. package/dist/components/RefreshButton.js +7 -8
  92. package/dist/components/RequiredMark.js +1 -1
  93. package/dist/components/Section.js +1 -1
  94. package/dist/components/Select.d.ts +4 -9
  95. package/dist/components/Select.js +24 -11
  96. package/dist/components/SettingModeOption.d.ts +1 -1
  97. package/dist/components/SettingModeOption.js +7 -1
  98. package/dist/components/SettingsCard.d.ts +5 -3
  99. package/dist/components/SettingsCard.js +27 -20
  100. package/dist/components/Slider.js +1 -1
  101. package/dist/components/StatusBadge.js +2 -2
  102. package/dist/components/Switch.js +5 -4
  103. package/dist/components/Table.d.ts +30 -20
  104. package/dist/components/Table.js +50 -73
  105. package/dist/components/Tabs.d.ts +3 -7
  106. package/dist/components/Tabs.js +6 -10
  107. package/dist/components/ThemeEditor.js +18 -8
  108. package/dist/components/Toast.d.ts +11 -3
  109. package/dist/components/Toast.js +45 -20
  110. package/dist/components/buttonClasses.js +1 -1
  111. package/dist/components/comboboxItems.d.ts +4 -0
  112. package/dist/components/comboboxItems.js +6 -1
  113. package/dist/components/dismiss.d.ts +12 -0
  114. package/dist/components/dismiss.js +19 -0
  115. package/dist/components/fieldBox.d.ts +4 -0
  116. package/dist/components/fieldBox.js +7 -3
  117. package/dist/components/floating.d.ts +3 -3
  118. package/dist/components/floating.js +1 -1
  119. package/dist/components/markdownCodeBreaks.js +3 -4
  120. package/dist/components/pageHeaderStore.d.ts +41 -0
  121. package/dist/components/pageHeaderStore.js +67 -0
  122. package/dist/components/pathBreaks.d.ts +8 -0
  123. package/dist/components/pathBreaks.js +28 -0
  124. package/dist/components/segmented.js +1 -1
  125. package/dist/components/shortcutKey.d.ts +2 -1
  126. package/dist/components/shortcutKey.js +19 -2
  127. package/dist/components/splitter.js +1 -1
  128. package/dist/components/useCssIsDark.js +40 -18
  129. package/dist/components/useTheme.js +9 -10
  130. package/dist/dev.d.ts +9 -0
  131. package/dist/dev.js +14 -0
  132. package/dist/editor/Editor.d.ts +3 -2
  133. package/dist/editor/Editor.js +11 -2
  134. package/dist/editor/EditorField.d.ts +2 -1
  135. package/dist/editor/EditorField.js +11 -29
  136. package/dist/editor/FormCodePanel.d.ts +7 -3
  137. package/dist/editor/FormCodePanel.js +14 -7
  138. package/dist/editor/Monaco.d.ts +14 -5
  139. package/dist/editor/Monaco.js +163 -112
  140. package/dist/editor/index.d.ts +5 -5
  141. package/dist/editor/index.js +3 -3
  142. package/dist/editor/themes.d.ts +8 -5
  143. package/dist/editor/themes.js +58 -30
  144. package/dist/editor/yaml.d.ts +6 -2
  145. package/dist/editor/yaml.js +11 -2
  146. package/dist/file-explorer/FileExplorer.js +143 -124
  147. package/dist/file-explorer/FileExplorerContext.js +1 -1
  148. package/dist/file-explorer/FilePreview/StreamedBadge.js +3 -1
  149. package/dist/file-explorer/FilePreview/Viewer.js +2 -2
  150. package/dist/file-explorer/FilePreview/index.js +4 -4
  151. package/dist/file-explorer/FileRow.js +1 -1
  152. package/dist/file-explorer/FileRowsWindow.js +34 -3
  153. package/dist/file-explorer/FileTable.js +3 -1
  154. package/dist/file-explorer/TreeView.js +37 -14
  155. package/dist/file-explorer/helpers.d.ts +2 -1
  156. package/dist/file-explorer/helpers.js +21 -20
  157. package/dist/file-explorer/toasts.js +27 -19
  158. package/dist/file-explorer/treeRows.d.ts +6 -0
  159. package/dist/file-explorer/treeRows.js +19 -1
  160. package/dist/file-explorer/useNearEnd.js +3 -6
  161. package/dist/form/Fields/CheckboxGroupField.js +12 -5
  162. package/dist/form/Fields/DurationField.js +1 -1
  163. package/dist/form/Fields/LabelField.js +1 -1
  164. package/dist/form/Fields/ObjectField.d.ts +1 -1
  165. package/dist/form/Fields/ObjectField.js +3 -2
  166. package/dist/form/Fields/StringField.js +16 -29
  167. package/dist/form/Fields/TextAreaField.js +3 -4
  168. package/dist/form/Form.js +3 -8
  169. package/dist/form/Wizard/WizardNavigation.js +0 -3
  170. package/dist/form/Wizard/utils.js +1 -1
  171. package/dist/form/fieldFrame.d.ts +1 -1
  172. package/dist/form/fieldFrame.js +2 -2
  173. package/dist/form/types/fieldComponentTypes.d.ts +2 -1
  174. package/dist/graph/AnnotationBanner.d.ts +1 -2
  175. package/dist/graph/AnnotationBanner.js +30 -32
  176. package/dist/graph/Connectors.js +4 -1
  177. package/dist/graph/DependencyGraph.js +2 -2
  178. package/dist/graph/GraphEditor.js +11 -9
  179. package/dist/graph/GraphEditorDialogs.js +1 -1
  180. package/dist/graph/GraphNode.js +7 -4
  181. package/dist/graph/InputDialog.js +1 -1
  182. package/dist/graph/InputsEditor.js +14 -11
  183. package/dist/graph/MatrixGroup.js +9 -3
  184. package/dist/graph/Reveal.js +18 -10
  185. package/dist/graph/ShortcutsButton.d.ts +11 -2
  186. package/dist/graph/ShortcutsButton.js +14 -3
  187. package/dist/graph/TreeView.js +35 -18
  188. package/dist/graph/WorkflowSettingsDialog.js +1 -1
  189. package/dist/graph/editorFields.js +1 -1
  190. package/dist/graph/editorRows.js +16 -10
  191. package/dist/graph/editorStrings.d.ts +7 -0
  192. package/dist/graph/editorStrings.js +8 -1
  193. package/dist/graph/inputRefs.js +1 -1
  194. package/dist/graph/settingsViews.js +11 -18
  195. package/dist/graph/stepWith.js +1 -1
  196. package/dist/icons.d.ts +2 -0
  197. package/dist/icons.js +4 -2
  198. package/dist/index.d.ts +12 -12
  199. package/dist/index.js +16 -16
  200. package/dist/list/ActionToolbar.d.ts +42 -6
  201. package/dist/list/ActionToolbar.js +297 -101
  202. package/dist/list/ListPage.d.ts +15 -23
  203. package/dist/list/ListPage.js +42 -43
  204. package/dist/list/ListTable.d.ts +32 -7
  205. package/dist/list/ListTable.js +48 -12
  206. package/dist/list/ListViewControls.js +1 -1
  207. package/dist/list/UserHoverCard.js +7 -15
  208. package/dist/list/index.d.ts +2 -2
  209. package/dist/list/index.js +2 -2
  210. package/dist/list/listSearch.js +12 -10
  211. package/dist/list/listView.d.ts +10 -1
  212. package/dist/list/listView.js +15 -1
  213. package/dist/logviewer/LogViewer.d.ts +4 -2
  214. package/dist/logviewer/LogViewer.js +87 -69
  215. package/dist/logviewer/logviewer.css +3 -2
  216. package/dist/reducedMotion.d.ts +5 -0
  217. package/dist/reducedMotion.js +20 -0
  218. package/dist/safeUrl.d.ts +1 -1
  219. package/dist/safeUrl.js +4 -2
  220. package/dist/styles.css +1 -1
  221. package/package.json +1 -1
  222. package/dist/components/Breadcrumbs.d.ts +0 -37
  223. package/dist/components/Breadcrumbs.js +0 -90
  224. package/dist/components/CopyToClipboard.d.ts +0 -17
  225. package/dist/components/CopyToClipboard.js +0 -66
  226. package/dist/components/Sort.d.ts +0 -9
  227. package/dist/components/Sort.js +0 -42
@@ -9,9 +9,8 @@ var fallbacks = {};
9
9
  /** A token as Monaco takes it: a 6-digit hex. Monaco can't read display-p3, so
10
10
  * a wide-gamut value is mapped back into sRGB; the default theme fills in for
11
11
  * a host that sets no tokens. */
12
- function token(name, mode) {
13
- const set = typeof window === "undefined" ? "" : getComputedStyle(document.documentElement).getPropertyValue(name).trim();
14
- const color = parseColor(expandShorthandHex(set));
12
+ function token(style, name, mode) {
13
+ const color = parseColor(expandShorthandHex(style?.getPropertyValue(name).trim() ?? ""));
15
14
  if (color) return toHex(color);
16
15
  fallbacks[mode] ??= deriveTheme(schemeFor(DEFAULT_THEME, mode));
17
16
  return fallbacks[mode][name];
@@ -37,27 +36,22 @@ var RULES = [
37
36
  ["delimiter", "--theme-code-text"],
38
37
  ["operators", "--theme-code-text"]
39
38
  ];
40
- function editorTheme(mode, disabled) {
41
- const c = (name) => token(name, mode);
42
- const foreground = disabled ? c("--theme-muted-text-color") : c("--theme-code-text");
43
- const background = disabled ? c("--theme-input-disabled-bg") : c("--theme-panel-bg");
39
+ function editorTheme(style, mode) {
40
+ const c = (name) => token(style, name, mode);
44
41
  return {
45
42
  base: mode === "dark" ? "vs-dark" : "vs",
46
43
  inherit: true,
47
- rules: disabled ? [{
48
- token: "",
49
- foreground: foreground.slice(1)
50
- }] : RULES.map(([name, t, fontStyle]) => ({
44
+ rules: RULES.map(([name, t, fontStyle]) => ({
51
45
  token: name,
52
46
  foreground: c(t).slice(1),
53
47
  ...fontStyle ? { fontStyle } : {}
54
48
  })),
55
49
  colors: {
56
- "editor.foreground": foreground,
57
- "editor.background": background,
50
+ "editor.foreground": c("--theme-code-text"),
51
+ "editor.background": c("--theme-panel-bg"),
58
52
  "editor.border": c("--theme-border"),
59
- "editorCursor.foreground": disabled ? background : c("--theme-app"),
60
- "editor.lineHighlightBackground": disabled ? background : c("--theme-hover"),
53
+ "editorCursor.foreground": c("--theme-app"),
54
+ "editor.lineHighlightBackground": c("--theme-hover"),
61
55
  "editorLineNumber.foreground": c("--theme-placeholder"),
62
56
  "editorLineNumber.activeForeground": c("--theme-muted-text-color"),
63
57
  "editor.selectionBackground": c("--theme-accent-subtle"),
@@ -65,26 +59,60 @@ function editorTheme(mode, disabled) {
65
59
  }
66
60
  };
67
61
  }
68
- /** Monaco themes read from the document's tokens: call again after the host applies another theme. */
62
+ var definedFor = /* @__PURE__ */ new WeakMap();
63
+ /**
64
+ * Defines the light and dark Monaco themes from the document's tokens. Call it again after the
65
+ * host applies other tokens; it returns whether anything changed.
66
+ */
69
67
  function defineEditorThemes(monacoEditor) {
70
- for (const mode of ["light", "dark"]) for (const disabled of [false, true]) monacoEditor.defineTheme(getThemeName(mode === "dark", disabled), editorTheme(mode, disabled));
68
+ const style = typeof window === "undefined" ? void 0 : getComputedStyle(document.documentElement);
69
+ const themes = ["light", "dark"].map((mode) => [mode, editorTheme(style, mode)]);
70
+ const snapshot = JSON.stringify(themes);
71
+ if (definedFor.get(monacoEditor) === snapshot) return false;
72
+ definedFor.set(monacoEditor, snapshot);
73
+ for (const [mode, data] of themes) monacoEditor.defineTheme(getThemeName(mode === "dark"), data);
74
+ return true;
71
75
  }
72
- /** Redefines the editor themes when the host applies other tokens to the document,
73
- * and sets `current()` again, so an open editor follows a theme being edited. */
76
+ var followers = /* @__PURE__ */ new Set();
77
+ var observer;
78
+ var frame = 0;
79
+ function flush() {
80
+ frame = 0;
81
+ for (const follow of followers) follow();
82
+ }
83
+ /** Redefines the editor themes when the host applies other tokens or another scheme to the
84
+ * document, and sets `current()` again, so an open editor follows a theme being edited. */
74
85
  function followThemeTokens(monacoEditor, current) {
75
86
  if (typeof MutationObserver === "undefined") return () => {};
76
- const observer = new MutationObserver(() => {
77
- defineEditorThemes(monacoEditor);
78
- monacoEditor.setTheme(current());
79
- });
80
- observer.observe(document.documentElement, {
81
- attributes: true,
82
- attributeFilter: ["style"]
83
- });
84
- return () => observer.disconnect();
87
+ const follow = () => {
88
+ if (defineEditorThemes(monacoEditor)) monacoEditor.setTheme(current());
89
+ };
90
+ followers.add(follow);
91
+ if (!observer) {
92
+ observer = new MutationObserver(() => {
93
+ frame ||= requestAnimationFrame(flush);
94
+ });
95
+ observer.observe(document.documentElement, {
96
+ attributes: true,
97
+ attributeFilter: [
98
+ "style",
99
+ "class",
100
+ "data-theme"
101
+ ]
102
+ });
103
+ }
104
+ return () => {
105
+ followers.delete(follow);
106
+ if (followers.size === 0) {
107
+ observer?.disconnect();
108
+ observer = void 0;
109
+ cancelAnimationFrame(frame);
110
+ frame = 0;
111
+ }
112
+ };
85
113
  }
86
- function getThemeName(isDark, disabled) {
87
- return `app-${isDark ? "dark" : "light"}${disabled ? "-disabled" : ""}`;
114
+ function getThemeName(isDark) {
115
+ return `app-${isDark ? "dark" : "light"}`;
88
116
  }
89
117
  //#endregion
90
118
  export { defineEditorThemes, expandShorthandHex, followThemeTokens, getThemeName };
@@ -7,7 +7,11 @@ export interface SchemasSettings {
7
7
  /** The schema itself, used instead of fetching `uri`. */
8
8
  schema?: object;
9
9
  }
10
- /** Adds JSON schemas that validate and complete YAML models whose URI matches. */
11
- export declare function configureEditorYaml(added: SchemasSettings[]): void;
10
+ /**
11
+ * Adds JSON schemas that validate and complete YAML models whose URI matches. A schema with the
12
+ * `uri` of one already added replaces it, so calling this again, as a reload or a second mount
13
+ * does, adds nothing twice. Returns a function that removes these schemas.
14
+ */
15
+ export declare function configureEditorYaml(added: SchemasSettings[]): () => void;
12
16
  /** Lets the loaded editor pick up schemas added before or after it loads. */
13
17
  export declare function onYamlSchemas(listener: (schemas: SchemasSettings[]) => void): void;
@@ -1,10 +1,19 @@
1
1
  //#region src/editor/yaml.ts
2
2
  var schemas = [];
3
3
  var apply;
4
- /** Adds JSON schemas that validate and complete YAML models whose URI matches. */
4
+ /**
5
+ * Adds JSON schemas that validate and complete YAML models whose URI matches. A schema with the
6
+ * `uri` of one already added replaces it, so calling this again, as a reload or a second mount
7
+ * does, adds nothing twice. Returns a function that removes these schemas.
8
+ */
5
9
  function configureEditorYaml(added) {
6
- schemas = [...schemas, ...added];
10
+ const uris = new Set(added.map((schema) => schema.uri));
11
+ schemas = [...schemas.filter((schema) => !uris.has(schema.uri)), ...added];
7
12
  apply?.(schemas);
13
+ return () => {
14
+ schemas = schemas.filter((schema) => !added.includes(schema));
15
+ apply?.(schemas);
16
+ };
8
17
  }
9
18
  /** Lets the loaded editor pick up schemas added before or after it loads. */
10
19
  function onYamlSchemas(listener) {
@@ -1,26 +1,28 @@
1
1
  import { cx } from "../cx.js";
2
- import { AccessIcon, ChevronDownIcon, ChevronRightIcon, CollapseIcon, CopyIcon, DownloadIcon, FileIcon, FileTextIcon, FolderIcon, LinkIcon, PreviewIcon, ShareIcon, TrashIcon, UploadIcon, WarningIcon } from "../icons.js";
2
+ import { buttonClasses } from "../components/buttonClasses.js";
3
+ import { AccessIcon, ChevronDownIcon, ChevronRightIcon, CollapseIcon, DownloadIcon, FileIcon, FileTextIcon, FolderIcon, LinkIcon, PreviewIcon, ShareIcon, TrashIcon, UploadIcon } from "../icons.js";
3
4
  import { MenuItem, MenuPopup, MenuSeparator } from "../components/Menu.js";
4
5
  import { safeUrl } from "../safeUrl.js";
5
- import { keyedByContent } from "../components/keys.js";
6
- import { buttonClasses } from "../components/buttonClasses.js";
7
6
  import { Loader } from "../components/Loader.js";
8
7
  import { toast } from "../components/Toast.js";
8
+ import { keyedByContent } from "../components/keys.js";
9
9
  import { Tooltip } from "../components/Tooltip.js";
10
10
  import { usePersistedState, useSlots, useStrings } from "../components/Provider.js";
11
11
  import { useCopy } from "../components/useCopy.js";
12
12
  import { Button } from "../components/Button.js";
13
+ import { Callout } from "../components/Callout.js";
14
+ import { InfoTip } from "../components/InfoTip.js";
13
15
  import { ConfirmModal } from "../components/ConfirmModal.js";
14
16
  import { useContextMenu } from "../components/ContextMenu.js";
15
- import CopyToClipboard, { CopyCodeBlock } from "../components/CopyToClipboard.js";
17
+ import { CopyButton, CopyCodeBlock } from "../components/CopyButton.js";
16
18
  import { CreateModal } from "../components/CreateModal.js";
17
- import { InfoTip } from "../components/InfoTip.js";
18
19
  import { useSplitter } from "../components/splitter.js";
19
20
  import { formatBytes, formatDateTime } from "../format.js";
20
21
  import { RelativeTime } from "../components/relativeTime.js";
21
22
  import { RefreshButton } from "../components/RefreshButton.js";
22
23
  import { StatusBadge } from "../components/StatusBadge.js";
23
24
  import { Table } from "../components/Table.js";
25
+ import { Tabs } from "../components/Tabs.js";
24
26
  import { ListActionsHeader, ListSkeleton, listTableFixedProps, listTableProps } from "../list/ListTable.js";
25
27
  import { assembleRowMenu, useCopySubmenu } from "../list/rowMenu.js";
26
28
  import { calculateUploadNodesTotalSize, createTreeBuilder, getDirectoryNameError, getDirectoryObjectPath, getNodeChildren, getObjectKeyFromNode, getParentPath, getUploadNodesFromDataTransferItems, getUriScheme, pruneNodesInsideSelectedDirectories, removeLeadingAndTrailingSlashes } from "./lib/utils.js";
@@ -42,12 +44,10 @@ import { useCallback, useEffect, useEffectEvent, useLayoutEffect, useMemo, useRe
42
44
  import { DateTime } from "luxon";
43
45
  //#region src/file-explorer/FileExplorer.tsx
44
46
  function UriCard({ value }) {
45
- const { common } = useStrings();
47
+ const { fileExplorer: t } = useStrings();
46
48
  const scheme = getUriScheme(value);
47
- return /* @__PURE__ */ jsxs(CopyToClipboard, {
48
- text: value,
49
- showIcon: false,
50
- className: "group flex items-stretch rounded-lg border theme-border bg-(--theme-input-bg) overflow-hidden cursor-copy hover:border-(--theme-link)/50 transition-colors duration-150",
49
+ return /* @__PURE__ */ jsxs("div", {
50
+ className: "flex items-stretch overflow-hidden rounded-lg border theme-border bg-(--theme-input-bg)",
51
51
  children: [
52
52
  scheme && /* @__PURE__ */ jsx("span", {
53
53
  className: "shrink-0 inline-flex items-center px-3 bg-(--theme-muted-panel-bg) border-r theme-border font-mono text-[11px] font-semibold uppercase tracking-widest theme-muted-text",
@@ -58,9 +58,11 @@ function UriCard({ value }) {
58
58
  children: value
59
59
  }),
60
60
  /* @__PURE__ */ jsx("span", {
61
- className: "shrink-0 inline-flex items-center justify-center px-3 border-l theme-border theme-muted-text group-hover:text-(--theme-link) group-hover:bg-(--theme-link)/5 transition-colors duration-150",
62
- title: common.copyToClipboard,
63
- children: /* @__PURE__ */ jsx(CopyIcon, { className: "h-3.5 w-3.5" })
61
+ className: "shrink-0 inline-flex items-center border-l theme-border px-1.5",
62
+ children: /* @__PURE__ */ jsx(CopyButton, {
63
+ text: value,
64
+ "aria-label": t.preview.copyUri
65
+ })
64
66
  })
65
67
  ]
66
68
  });
@@ -320,10 +322,10 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
320
322
  return { corsError: false };
321
323
  } catch (error) {
322
324
  const isCorsError = error instanceof CorsError;
323
- const errorMessage = isCorsError ? error.message || "CORS error" : error instanceof Error ? error.message : "Unknown error";
325
+ const errorMessage = error instanceof Error && error.message || t.messages.unknownError;
324
326
  if (owns()) {
325
327
  setListings((prev) => recordListingError(options?.replace ? clearListingsUnder(prev, node.path) : prev, node.path, errorMessage));
326
- updateConnectionIssuesMessage((prev) => new Map(prev).set(nodeStorageId, `Failed to load contents for ${node.displayName || node.name}: ${errorMessage}`));
328
+ updateConnectionIssuesMessage((prev) => new Map(prev).set(nodeStorageId, t.messages.loadFailed(node.displayName || node.name, errorMessage)));
327
329
  if (isCorsError) setHasCorsIssue((prev) => new Map(prev).set(nodeStorageId, true));
328
330
  }
329
331
  return { corsError: isCorsError };
@@ -687,22 +689,30 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
687
689
  }
688
690
  if (chain.length === 0) return null;
689
691
  return /* @__PURE__ */ jsx("nav", {
690
- className: "flex min-w-0 flex-1 items-center gap-1 overflow-hidden text-[13px]",
691
- children: chain.map((node, i) => {
692
- const isLast = i === chain.length - 1;
693
- const label = node.displayName || node.name;
694
- return /* @__PURE__ */ jsxs("span", {
695
- className: "flex min-w-0 items-center gap-1",
696
- children: [i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 shrink-0 text-(--theme-muted-text-color)" }), isLast ? /* @__PURE__ */ jsx("span", {
697
- className: "truncate font-semibold text-(--theme-app)",
698
- children: label
699
- }) : /* @__PURE__ */ jsx("button", {
700
- type: "button",
701
- onClick: () => handleSelectTreeItem(node.path, node),
702
- className: "max-w-[16rem] cursor-pointer truncate text-(--theme-muted-text-color) transition-colors hover:text-(--theme-app)",
703
- children: label
704
- })]
705
- }, node.path);
692
+ "aria-label": t.chrome.location,
693
+ className: "flex min-w-0 flex-1 overflow-hidden text-[13px]",
694
+ children: /* @__PURE__ */ jsx("ol", {
695
+ className: "flex min-w-0 items-center gap-1",
696
+ children: chain.map((node, i) => {
697
+ const isLast = i === chain.length - 1;
698
+ const label = node.displayName || node.name;
699
+ return /* @__PURE__ */ jsxs("li", {
700
+ className: "flex min-w-0 items-center gap-1",
701
+ children: [i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, {
702
+ "aria-hidden": "true",
703
+ className: "h-3 w-3 shrink-0 text-(--theme-muted-text-color) rtl:rotate-180"
704
+ }), isLast ? /* @__PURE__ */ jsx("span", {
705
+ "aria-current": "location",
706
+ className: "truncate font-semibold text-(--theme-app)",
707
+ children: label
708
+ }) : /* @__PURE__ */ jsx("button", {
709
+ type: "button",
710
+ onClick: () => handleSelectTreeItem(node.path, node),
711
+ className: "max-w-[16rem] cursor-pointer truncate text-(--theme-muted-text-color) transition-colors hover:text-(--theme-app)",
712
+ children: label
713
+ })]
714
+ }, node.path);
715
+ })
706
716
  })
707
717
  });
708
718
  };
@@ -1056,33 +1066,41 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
1056
1066
  handleUploadInputChange(e.target.files, selectedNode);
1057
1067
  }
1058
1068
  }),
1059
- selectedNodeCanWrite && selectedNodeCanUpload && /* @__PURE__ */ jsx(Button, {
1060
- variant: "primary",
1061
- size: "sm",
1062
- "aria-label": t.createFolder.action,
1063
- icon: /* @__PURE__ */ jsx(FolderIcon, {}),
1064
- disabled: selectedNode.type === "file" || !selectedNode.storageId,
1065
- onClick: () => setCreateFolderTarget(selectedNode),
1066
- children: /* @__PURE__ */ jsx("span", {
1067
- className: "hidden @4xl:inline",
1068
- children: t.createFolder.action
1069
+ selectedNodeCanWrite && selectedNodeCanUpload && /* @__PURE__ */ jsx(Tooltip, {
1070
+ content: t.createFolder.action,
1071
+ side: "bottom",
1072
+ children: /* @__PURE__ */ jsx(Button, {
1073
+ variant: "outline",
1074
+ size: "sm",
1075
+ "aria-label": t.createFolder.action,
1076
+ icon: /* @__PURE__ */ jsx(FolderIcon, {}),
1077
+ disabled: selectedNode.type === "file" || !selectedNode.storageId,
1078
+ onClick: () => setCreateFolderTarget(selectedNode),
1079
+ children: /* @__PURE__ */ jsx("span", {
1080
+ className: "hidden @4xl:inline",
1081
+ children: t.createFolder.action
1082
+ })
1069
1083
  })
1070
1084
  }),
1071
- selectedNodeCanWrite && selectedNodeCanUpload && /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Menu.Trigger, {
1072
- "aria-label": t.chrome.upload,
1073
- className: buttonClasses({
1074
- variant: "primary",
1075
- size: "sm"
1076
- }),
1077
- disabled: selectedNode.type === "file" || !selectedNode.storageId,
1078
- children: [
1079
- /* @__PURE__ */ jsx(UploadIcon, {}),
1080
- /* @__PURE__ */ jsx("span", {
1081
- className: "hidden @4xl:inline",
1082
- children: t.chrome.upload
1085
+ selectedNodeCanWrite && selectedNodeCanUpload && /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsx(Tooltip, {
1086
+ content: t.chrome.upload,
1087
+ side: "bottom",
1088
+ children: /* @__PURE__ */ jsxs(Menu.Trigger, {
1089
+ "aria-label": t.chrome.upload,
1090
+ className: buttonClasses({
1091
+ variant: selectedNode.type === "directory" ? "primary" : "outline",
1092
+ size: "sm"
1083
1093
  }),
1084
- /* @__PURE__ */ jsx(ChevronDownIcon, {})
1085
- ]
1094
+ disabled: selectedNode.type === "file" || !selectedNode.storageId,
1095
+ children: [
1096
+ /* @__PURE__ */ jsx(UploadIcon, {}),
1097
+ /* @__PURE__ */ jsx("span", {
1098
+ className: "hidden @4xl:inline",
1099
+ children: t.chrome.upload
1100
+ }),
1101
+ /* @__PURE__ */ jsx(ChevronDownIcon, {})
1102
+ ]
1103
+ })
1086
1104
  }), /* @__PURE__ */ jsxs(MenuPopup, {
1087
1105
  align: "end",
1088
1106
  className: "w-36",
@@ -1094,21 +1112,25 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
1094
1112
  children: t.chrome.selectFolder
1095
1113
  })]
1096
1114
  })] }),
1097
- /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsxs(Menu.Trigger, {
1098
- "aria-label": common.download,
1099
- className: buttonClasses({
1100
- variant: "primary",
1101
- size: "sm"
1102
- }),
1103
- disabled: checkedItems.size === 0 && selectedNode.type !== "file" || hasFolderSelected() || !selectedNode.storageId,
1104
- children: [
1105
- /* @__PURE__ */ jsx(DownloadIcon, {}),
1106
- /* @__PURE__ */ jsx("span", {
1107
- className: "hidden @4xl:inline",
1108
- children: common.download
1115
+ /* @__PURE__ */ jsxs(Menu.Root, { children: [/* @__PURE__ */ jsx(Tooltip, {
1116
+ content: common.download,
1117
+ side: "bottom",
1118
+ children: /* @__PURE__ */ jsxs(Menu.Trigger, {
1119
+ "aria-label": common.download,
1120
+ className: buttonClasses({
1121
+ variant: selectedNode.type === "file" ? "primary" : "outline",
1122
+ size: "sm"
1109
1123
  }),
1110
- /* @__PURE__ */ jsx(ChevronDownIcon, {})
1111
- ]
1124
+ disabled: checkedItems.size === 0 && selectedNode.type !== "file" || hasFolderSelected() || !selectedNode.storageId,
1125
+ children: [
1126
+ /* @__PURE__ */ jsx(DownloadIcon, {}),
1127
+ /* @__PURE__ */ jsx("span", {
1128
+ className: "hidden @4xl:inline",
1129
+ children: common.download
1130
+ }),
1131
+ /* @__PURE__ */ jsx(ChevronDownIcon, {})
1132
+ ]
1133
+ })
1112
1134
  }), /* @__PURE__ */ jsxs(MenuPopup, {
1113
1135
  align: "end",
1114
1136
  className: "w-72",
@@ -1121,7 +1143,7 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
1121
1143
  className: "text-sm text-center pb-1.5",
1122
1144
  children: downloadCommand.label
1123
1145
  }), /* @__PURE__ */ jsx(CopyCodeBlock, {
1124
- textToCopy: downloadCommandText,
1146
+ text: downloadCommandText,
1125
1147
  children: /* @__PURE__ */ jsx("div", {
1126
1148
  className: "overflow-x-auto text-xs",
1127
1149
  children: keyedByContent(downloadCommandText.split("\n"), (l) => l).map(({ key, item: line }) => /* @__PURE__ */ jsx("div", {
@@ -1132,28 +1154,37 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
1132
1154
  })]
1133
1155
  })] })]
1134
1156
  })] }),
1135
- groups.length > 0 && selectedNodeCanManageAccess && /* @__PURE__ */ jsx(Button, {
1136
- variant: "primary",
1137
- size: "sm",
1138
- "aria-label": t.chrome.access,
1139
- icon: /* @__PURE__ */ jsx(AccessIcon, {}),
1140
- disabled: !selectedNode.storageId,
1141
- onClick: () => setAccessDrawerOpen(true),
1142
- children: /* @__PURE__ */ jsx("span", {
1143
- className: "hidden @4xl:inline",
1144
- children: t.chrome.manageAccess
1157
+ groups.length > 0 && selectedNodeCanManageAccess && /* @__PURE__ */ jsx(Tooltip, {
1158
+ content: t.chrome.manageAccess,
1159
+ side: "bottom",
1160
+ children: /* @__PURE__ */ jsx(Button, {
1161
+ variant: "outline",
1162
+ size: "sm",
1163
+ "aria-label": t.chrome.access,
1164
+ icon: /* @__PURE__ */ jsx(AccessIcon, {}),
1165
+ disabled: !selectedNode.storageId,
1166
+ onClick: () => setAccessDrawerOpen(true),
1167
+ children: /* @__PURE__ */ jsx("span", {
1168
+ className: "hidden @4xl:inline",
1169
+ children: t.chrome.manageAccess
1170
+ })
1145
1171
  })
1146
1172
  }),
1147
- selectedNodeCanDelete && /* @__PURE__ */ jsx(Button, {
1148
- variant: "danger",
1149
- size: "sm",
1150
- "aria-label": common.delete,
1151
- icon: /* @__PURE__ */ jsx(TrashIcon, {}),
1152
- disabled: checkedItems.size === 0 && selectedNode.type !== "file" || !selectedNode.storageId,
1153
- onClick: onDeleteClick,
1154
- children: /* @__PURE__ */ jsx("span", {
1155
- className: "hidden @4xl:inline",
1156
- children: common.delete
1173
+ selectedNodeCanDelete && /* @__PURE__ */ jsx(Tooltip, {
1174
+ content: common.delete,
1175
+ side: "bottom",
1176
+ children: /* @__PURE__ */ jsx(Button, {
1177
+ variant: "outline",
1178
+ size: "sm",
1179
+ "aria-label": common.delete,
1180
+ icon: /* @__PURE__ */ jsx(TrashIcon, {}),
1181
+ className: "*:text-(--theme-error-text)",
1182
+ disabled: checkedItems.size === 0 && selectedNode.type !== "file" || !selectedNode.storageId,
1183
+ onClick: onDeleteClick,
1184
+ children: /* @__PURE__ */ jsx("span", {
1185
+ className: "hidden @4xl:inline",
1186
+ children: common.delete
1187
+ })
1157
1188
  })
1158
1189
  })
1159
1190
  ]
@@ -1202,22 +1233,20 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
1202
1233
  const createdDt = selectedNode.created ? DateTime.fromISO(selectedNode.created) : null;
1203
1234
  const previewable = canPreview(selectedNode);
1204
1235
  const effectiveTab = previewable ? detailTab : "details";
1205
- const tabClass = (active) => cx("mx-2.5 border-b-2 px-1 py-2.5 text-[13px] font-medium cursor-pointer transition-colors", active ? "theme-text border-(--theme-accent)" : "theme-muted-text border-transparent hover:theme-text");
1206
1236
  return /* @__PURE__ */ jsxs("div", {
1207
1237
  className: "flex h-full min-h-0 flex-col",
1208
- children: [/* @__PURE__ */ jsxs("div", {
1209
- className: "flex shrink-0 items-center border-b theme-border px-3",
1210
- children: [/* @__PURE__ */ jsx("button", {
1211
- type: "button",
1212
- className: tabClass(effectiveTab === "details"),
1213
- onClick: () => setDetailTab("details"),
1214
- children: t.preview.detailsTab
1215
- }), previewable && /* @__PURE__ */ jsx("button", {
1216
- type: "button",
1217
- className: tabClass(effectiveTab === "preview"),
1218
- onClick: () => setDetailTab("preview"),
1219
- children: t.preview.previewTab
1220
- })]
1238
+ children: [/* @__PURE__ */ jsx(Tabs, {
1239
+ label: selectedNode.name,
1240
+ items: [{
1241
+ value: "details",
1242
+ label: t.preview.detailsTab
1243
+ }, ...previewable ? [{
1244
+ value: "preview",
1245
+ label: t.preview.previewTab
1246
+ }] : []],
1247
+ value: effectiveTab,
1248
+ onValueChange: setDetailTab,
1249
+ className: "shrink-0 px-3"
1221
1250
  }), effectiveTab === "preview" && previewable ? /* @__PURE__ */ jsx(FilePreviewInline, {
1222
1251
  node: selectedNode,
1223
1252
  storage: selectedStorage ?? null,
@@ -1274,12 +1303,12 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
1274
1303
  node: selectedNode,
1275
1304
  onShare: onShareFileButtonClick
1276
1305
  }), /* @__PURE__ */ jsx(InfoTip, {
1277
- text: "This will generate a pre-signed URL for this file. Anyone with this link can temporarily access and download the file, even if they don't have an account. The link will automatically expire after 12 hours.",
1306
+ text: t.chrome.shareHelp,
1278
1307
  side: "right"
1279
1308
  })]
1280
1309
  }),
1281
1310
  /* @__PURE__ */ jsxs("div", {
1282
- className: "px-6 py-5 mt-5 border-t theme-border",
1311
+ className: cx("px-6 py-5", (uris.length > 0 || selectedNodeCanShare) && "mt-5 border-t theme-border"),
1283
1312
  children: [/* @__PURE__ */ jsx("h3", {
1284
1313
  className: "text-[11px] font-semibold uppercase tracking-widest theme-muted-text mb-3",
1285
1314
  children: t.chrome.details
@@ -1388,8 +1417,8 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
1388
1417
  children: /* @__PURE__ */ jsxs("div", {
1389
1418
  className: "text-sm flex flex-col gap-2 mt-2 text-left",
1390
1419
  children: [
1391
- /* @__PURE__ */ jsx("ul", {
1392
- className: "list-disc pl-5 max-h-40 overflow-auto theme-muted-panel py-1",
1420
+ /* @__PURE__ */ jsx("div", {
1421
+ className: "max-h-40 overflow-auto theme-muted-panel py-1 pl-3",
1393
1422
  children: pendingUpload?.uploadNodes && renderUploadNodes(pendingUpload.uploadNodes)
1394
1423
  }),
1395
1424
  /* @__PURE__ */ jsxs("div", { children: [
@@ -1409,26 +1438,16 @@ function FileExplorer({ storages, onRefresh, refreshKey, onOpenFile, showUserHie
1409
1438
  }),
1410
1439
  " ",
1411
1440
  /* @__PURE__ */ jsx("span", {
1412
- className: cx(isUploadSizeExceeded(pendingUpload?.totalSize ?? 0) && "text-amber-800 font-semibold"),
1441
+ className: cx(isUploadSizeExceeded(pendingUpload?.totalSize ?? 0) && "text-(--theme-warning-text) font-semibold"),
1413
1442
  children: formatBytes(pendingUpload?.totalSize ?? 0)
1414
1443
  })
1415
1444
  ]
1416
1445
  }),
1417
- isUploadSizeExceeded(pendingUpload?.totalSize ?? 0) && /* @__PURE__ */ jsx("div", {
1418
- className: "mt-3 p-3 bg-amber-50 border border-amber-200 rounded-lg",
1419
- children: /* @__PURE__ */ jsxs("div", {
1420
- className: "flex items-start gap-2",
1421
- children: [/* @__PURE__ */ jsx(WarningIcon, { className: "w-4 h-4 text-amber-600 shrink-0 mt-0.5" }), /* @__PURE__ */ jsxs("div", {
1422
- className: "text-amber-800",
1423
- children: [/* @__PURE__ */ jsx("div", {
1424
- className: "font-semibold mb-1",
1425
- children: t.confirmUpload.sizeLimitTitle
1426
- }), /* @__PURE__ */ jsxs("div", {
1427
- className: "text-sm",
1428
- children: [/* @__PURE__ */ jsx("p", { children: t.confirmUpload.sizeLimitBody(formatBytes(pendingUpload?.totalSize ?? 0), formatBytes(MAX_UPLOAD_SIZE)) }), /* @__PURE__ */ jsx("p", { children: t.confirmUpload.sizeLimitHint })]
1429
- })]
1430
- })]
1431
- })
1446
+ isUploadSizeExceeded(pendingUpload?.totalSize ?? 0) && /* @__PURE__ */ jsxs(Callout, {
1447
+ tone: "warning",
1448
+ title: t.confirmUpload.sizeLimitTitle,
1449
+ className: "mt-3",
1450
+ children: [/* @__PURE__ */ jsx("p", { children: t.confirmUpload.sizeLimitBody(formatBytes(pendingUpload?.totalSize ?? 0), formatBytes(MAX_UPLOAD_SIZE)) }), /* @__PURE__ */ jsx("p", { children: t.confirmUpload.sizeLimitHint })]
1432
1451
  })
1433
1452
  ]
1434
1453
  })
@@ -1,5 +1,5 @@
1
- import { keyedByContent } from "../components/keys.js";
2
1
  import { toast } from "../components/Toast.js";
2
+ import { keyedByContent } from "../components/keys.js";
3
3
  import { useStrings } from "../components/Provider.js";
4
4
  import { mapWithConcurrency } from "./lib/batch.js";
5
5
  import { calculateUploadNodesTotalSize, getUploadSessionETA, removeLeadingSlash } from "./lib/utils.js";
@@ -1,4 +1,6 @@
1
+ import { cx } from "../../cx.js";
1
2
  import { LockIcon } from "../../icons.js";
3
+ import { toneSurface } from "../../components/tone.js";
2
4
  import { useStrings } from "../../components/Provider.js";
3
5
  import { InfoTip } from "../../components/InfoTip.js";
4
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -7,7 +9,7 @@ function StreamedBadge() {
7
9
  const t = useStrings().fileExplorer;
8
10
  return /* @__PURE__ */ jsxs(InfoTip, {
9
11
  text: t.preview.streamedTooltip,
10
- className: "shrink-0 gap-1 rounded-full border border-green-500/40 bg-green-500/15 px-2 py-0.5 text-[11px] text-green-600",
12
+ className: cx("shrink-0 gap-1 rounded-full border px-2 py-0.5 text-[11px]", toneSurface.success),
11
13
  children: [/* @__PURE__ */ jsx(LockIcon, { className: "h-2.5 w-2.5" }), t.preview.streamed]
12
14
  });
13
15
  }
@@ -1,7 +1,7 @@
1
1
  import { cx } from "../../cx.js";
2
2
  import { DownloadIcon, FileIcon, LockIcon, MusicIcon, ZipIcon } from "../../icons.js";
3
- import { positionKeys, withPositionKeys } from "../../components/keys.js";
4
3
  import { Loader } from "../../components/Loader.js";
4
+ import { positionKeys, withPositionKeys } from "../../components/keys.js";
5
5
  import { useStrings } from "../../components/Provider.js";
6
6
  import { Button } from "../../components/Button.js";
7
7
  import Markdown from "../../components/Markdown.js";
@@ -439,7 +439,7 @@ function NotebookOutputView({ output }) {
439
439
  children: joinSource(output.text)
440
440
  });
441
441
  if (output.output_type === "error") return /* @__PURE__ */ jsx("pre", {
442
- className: "mt-2 overflow-auto rounded-lg bg-red-500/15 px-3 py-2 font-mono text-[11px] text-red-500",
442
+ className: "mt-2 overflow-auto rounded-lg bg-(--theme-error-muted) px-3 py-2 font-mono text-[11px] text-(--theme-error-text)",
443
443
  children: stripAnsi((output.traceback ?? []).join("\n"))
444
444
  });
445
445
  const plain = output.data?.["text/plain"];
@@ -1,8 +1,8 @@
1
1
  import { cx } from "../../cx.js";
2
2
  import { ChevronLeftIcon, ChevronRightIcon, CloseIcon, DownloadIcon, FileIcon, LinkIcon, ZoomInIcon, ZoomOutIcon } from "../../icons.js";
3
3
  import { usePersistedState, useStrings } from "../../components/Provider.js";
4
- import { Modal } from "../../components/Modal.js";
5
4
  import { IconButton } from "../../components/IconButton.js";
5
+ import { Modal } from "../../components/Modal.js";
6
6
  import { formatBytes } from "../../format.js";
7
7
  import { SegmentedControl } from "../../components/SegmentedControl.js";
8
8
  import { getPreviewKind } from "./previewType.js";
@@ -20,7 +20,7 @@ function isDocumentView(kind) {
20
20
  function FilePreview({ open, node, siblings, storage, getPresignedUrl, onNavigate, onClose, onDownload, onCopyUri }) {
21
21
  const t = useStrings().fileExplorer;
22
22
  const { common } = useStrings();
23
- const [style, setStyle] = usePersistedState("fileExplorer.previewStyle", "quicklook");
23
+ const [style, setStyle] = usePersistedState("fileExplorer.previewStyle", "compact");
24
24
  const [zoom, setZoom] = useState(100);
25
25
  const { url, loading: urlLoading, error: urlError } = usePresignedUrl(node, getPresignedUrl, {
26
26
  enabled: open,
@@ -67,8 +67,8 @@ function FilePreview({ open, node, siblings, storage, getPresignedUrl, onNavigat
67
67
  value: style,
68
68
  onValueChange: setStyle,
69
69
  options: [{
70
- value: "quicklook",
71
- label: t.preview.quickLook
70
+ value: "compact",
71
+ label: t.preview.compact
72
72
  }, {
73
73
  value: "overlay",
74
74
  label: t.preview.fullWindow