@parallelworks/ui 0.40.1 → 0.42.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 (289) hide show
  1. package/README.md +25 -0
  2. package/dist/ai/adapter/memoryStore.js +7 -0
  3. package/dist/ai/adapter/mock/mockAdapter.js +52 -17
  4. package/dist/ai/adapter/openai/createOpenAIStream.js +1 -1
  5. package/dist/ai/adapter/openai/index.d.ts +1 -1
  6. package/dist/ai/adapter/openai/sse.d.ts +8 -2
  7. package/dist/ai/adapter/openai/sse.js +40 -4
  8. package/dist/ai/adapter/openai/wire.d.ts +6 -0
  9. package/dist/ai/components/AllocationSelector.d.ts +3 -4
  10. package/dist/ai/components/AllocationSelector.js +37 -33
  11. package/dist/ai/components/AttachmentManager.js +7 -7
  12. package/dist/ai/components/AttachmentUpload.js +5 -5
  13. package/dist/ai/components/BranchNavigator.js +1 -1
  14. package/dist/ai/components/ChatEmptyState.js +2 -2
  15. package/dist/ai/components/ChatInput.js +10 -8
  16. package/dist/ai/components/ChatLayout.js +4 -5
  17. package/dist/ai/components/ChatMessage.js +12 -12
  18. package/dist/ai/components/ChatMessageList.js +9 -9
  19. package/dist/ai/components/ChatSidebar.js +8 -9
  20. package/dist/ai/components/ChatThread.js +4 -4
  21. package/dist/ai/components/ComposerChrome.d.ts +2 -2
  22. package/dist/ai/components/ComposerChrome.js +3 -6
  23. package/dist/ai/components/DragOverlay.js +2 -2
  24. package/dist/ai/components/ModelSelector.d.ts +5 -3
  25. package/dist/ai/components/ModelSelector.js +102 -339
  26. package/dist/ai/components/PastedText.js +11 -11
  27. package/dist/ai/components/ProviderIssueBanner.d.ts +2 -0
  28. package/dist/ai/components/ProviderIssueBanner.js +34 -16
  29. package/dist/ai/components/Reasoning.js +4 -4
  30. package/dist/ai/components/ShareDialog.js +43 -35
  31. package/dist/ai/components/SlashMenu.d.ts +12 -2
  32. package/dist/ai/components/SlashMenu.js +29 -13
  33. package/dist/ai/components/agent/ActivityLine.js +3 -3
  34. package/dist/ai/components/agent/AgentMessageParts.js +20 -20
  35. package/dist/ai/components/agent/PermissionPicker.js +13 -11
  36. package/dist/ai/components/conversationActions.d.ts +4 -6
  37. package/dist/ai/components/conversationActions.js +9 -13
  38. package/dist/ai/core/ChatProvider.js +4 -4
  39. package/dist/ai/core/config.js +1 -1
  40. package/dist/ai/core/parts.d.ts +5 -0
  41. package/dist/ai/core/parts.js +28 -1
  42. package/dist/ai/core/providerIssues.d.ts +7 -0
  43. package/dist/ai/core/providerIssues.js +9 -1
  44. package/dist/ai/core/useKeyboardShortcuts.d.ts +4 -0
  45. package/dist/ai/core/useKeyboardShortcuts.js +8 -2
  46. package/dist/ai/index.d.ts +0 -1
  47. package/dist/ai/index.js +1 -2
  48. package/dist/ai/strings.d.ts +19 -0
  49. package/dist/ai/strings.js +18 -1
  50. package/dist/ai/ui/Avatar.js +5 -5
  51. package/dist/ai/ui/ConversationSidebar.d.ts +0 -1
  52. package/dist/ai/ui/ConversationSidebar.js +6 -7
  53. package/dist/ai/ui/Markdown.js +3 -3
  54. package/dist/ai/ui/Notice.js +6 -6
  55. package/dist/ai/ui/chip.d.ts +4 -0
  56. package/dist/ai/ui/chip.js +8 -0
  57. package/dist/ai/ui/sidebar.d.ts +6 -5
  58. package/dist/ai/ui/sidebar.js +39 -43
  59. package/dist/components/ActionMenu.d.ts +13 -0
  60. package/dist/components/ActionMenu.js +30 -0
  61. package/dist/components/Avatar.js +6 -6
  62. package/dist/components/Breadcrumbs.js +1 -1
  63. package/dist/components/Button.js +10 -10
  64. package/dist/components/Callout.js +2 -2
  65. package/dist/components/Card.js +3 -3
  66. package/dist/components/Combobox.d.ts +66 -0
  67. package/dist/components/Combobox.js +393 -0
  68. package/dist/components/ConfirmModal.js +11 -11
  69. package/dist/components/ContextMenu.d.ts +23 -0
  70. package/dist/components/ContextMenu.js +89 -0
  71. package/dist/components/CopyToClipboard.js +2 -2
  72. package/dist/components/CreateModal.d.ts +17 -36
  73. package/dist/components/CreateModal.js +97 -259
  74. package/dist/components/DescriptionList.js +8 -8
  75. package/dist/components/Filter.js +2 -2
  76. package/dist/components/FilterPill.js +2 -2
  77. package/dist/components/HoverCard.d.ts +14 -0
  78. package/dist/components/HoverCard.js +33 -0
  79. package/dist/components/IconButton.d.ts +5 -5
  80. package/dist/components/IconButton.js +18 -22
  81. package/dist/components/InfoTip.d.ts +15 -0
  82. package/dist/components/InfoTip.js +60 -0
  83. package/dist/components/Input.js +5 -5
  84. package/dist/components/LetterBadge.js +2 -2
  85. package/dist/components/Loader.js +3 -3
  86. package/dist/components/Markdown.js +1 -1
  87. package/dist/components/MarkdownImpl.js +2 -2
  88. package/dist/components/Menu.d.ts +33 -0
  89. package/dist/components/Menu.js +86 -0
  90. package/dist/components/MenuEntries.d.ts +56 -0
  91. package/dist/components/MenuEntries.js +123 -0
  92. package/dist/components/Modal.d.ts +29 -0
  93. package/dist/components/Modal.js +47 -0
  94. package/dist/components/Overview.js +11 -10
  95. package/dist/components/PageHeader.d.ts +10 -16
  96. package/dist/components/PageHeader.js +69 -95
  97. package/dist/components/Pagination.js +5 -5
  98. package/dist/components/Provider.d.ts +5 -11
  99. package/dist/components/Provider.js +11 -14
  100. package/dist/components/Radio.d.ts +8 -0
  101. package/dist/components/Radio.js +16 -0
  102. package/dist/components/SectionHeader.js +2 -2
  103. package/dist/components/SegmentedControl.d.ts +6 -5
  104. package/dist/components/SegmentedControl.js +34 -30
  105. package/dist/components/Select.d.ts +27 -0
  106. package/dist/components/Select.js +78 -0
  107. package/dist/components/SettingModeOption.d.ts +5 -8
  108. package/dist/components/SettingModeOption.js +10 -12
  109. package/dist/components/SettingRow.js +4 -4
  110. package/dist/components/SettingsCard.js +4 -4
  111. package/dist/components/SettingsGroup.js +2 -2
  112. package/dist/components/Sort.js +1 -1
  113. package/dist/components/StatusBadge.js +7 -7
  114. package/dist/components/StatusIcons.js +4 -4
  115. package/dist/components/Switch.d.ts +22 -0
  116. package/dist/components/Switch.js +28 -0
  117. package/dist/components/Table.js +11 -11
  118. package/dist/components/Tooltip.d.ts +24 -20
  119. package/dist/components/Tooltip.js +58 -76
  120. package/dist/components/floating.d.ts +14 -0
  121. package/dist/components/floating.js +21 -0
  122. package/dist/components/search.d.ts +2 -0
  123. package/dist/components/search.js +14 -0
  124. package/dist/editor/Editor.js +1 -1
  125. package/dist/editor/EditorField.js +16 -21
  126. package/dist/editor/FormCodePanel.js +19 -19
  127. package/dist/editor/Monaco.js +3 -3
  128. package/dist/file-explorer/FileExplorer.js +77 -81
  129. package/dist/file-explorer/FileExplorerContext.js +2 -2
  130. package/dist/file-explorer/FilePreview/CodePreviewEditor.js +1 -1
  131. package/dist/file-explorer/FilePreview/Inline.js +1 -1
  132. package/dist/file-explorer/FilePreview/StreamedBadge.js +5 -6
  133. package/dist/file-explorer/FilePreview/Viewer.js +8 -8
  134. package/dist/file-explorer/FilePreview/index.d.ts +1 -1
  135. package/dist/file-explorer/FilePreview/index.js +49 -83
  136. package/dist/file-explorer/FileRow.d.ts +4 -3
  137. package/dist/file-explorer/FileRow.js +32 -38
  138. package/dist/file-explorer/FileRowsWindow.d.ts +3 -2
  139. package/dist/file-explorer/FileRowsWindow.js +4 -4
  140. package/dist/file-explorer/FileTable.d.ts +3 -2
  141. package/dist/file-explorer/FileTable.js +3 -3
  142. package/dist/file-explorer/LoadMoreRow.js +1 -1
  143. package/dist/file-explorer/TreeView.js +11 -16
  144. package/dist/file-explorer/helpers.js +11 -12
  145. package/dist/file-explorer/toasts.js +11 -11
  146. package/dist/form/FieldGroup.d.ts +11 -0
  147. package/dist/form/FieldGroup.js +36 -0
  148. package/dist/form/FieldWrapper.js +4 -4
  149. package/dist/form/Fields/BooleanField.js +23 -33
  150. package/dist/form/Fields/CheckboxGroupField.d.ts +1 -1
  151. package/dist/form/Fields/CheckboxGroupField.js +9 -13
  152. package/dist/form/Fields/ColorField.d.ts +1 -2
  153. package/dist/form/Fields/ColorField.js +6 -11
  154. package/dist/form/Fields/DropdownField.d.ts +3 -13
  155. package/dist/form/Fields/DropdownField.js +40 -27
  156. package/dist/form/Fields/DurationField.d.ts +1 -2
  157. package/dist/form/Fields/DurationField.js +25 -32
  158. package/dist/form/Fields/LabelField.js +2 -2
  159. package/dist/form/Fields/MultiDropdownField.d.ts +6 -12
  160. package/dist/form/Fields/MultiDropdownField.js +31 -22
  161. package/dist/form/Fields/NumberField.d.ts +1 -1
  162. package/dist/form/Fields/NumberField.js +65 -35
  163. package/dist/form/Fields/ObjectField.d.ts +1 -1
  164. package/dist/form/Fields/ObjectField.js +12 -43
  165. package/dist/form/Fields/RadioField.d.ts +1 -1
  166. package/dist/form/Fields/RadioField.js +30 -41
  167. package/dist/form/Fields/RangeField.d.ts +1 -2
  168. package/dist/form/Fields/RangeField.js +23 -16
  169. package/dist/form/Fields/StringField.d.ts +1 -2
  170. package/dist/form/Fields/StringField.js +58 -26
  171. package/dist/form/Fields/TextAreaField.js +12 -10
  172. package/dist/form/Form.d.ts +30 -48
  173. package/dist/form/Form.js +306 -412
  174. package/dist/form/FormLayout.js +9 -9
  175. package/dist/form/Wizard/WizardContainer.d.ts +1 -4
  176. package/dist/form/Wizard/WizardContainer.js +40 -56
  177. package/dist/form/Wizard/WizardNavigation.js +1 -1
  178. package/dist/form/Wizard/WizardStepContent.d.ts +1 -5
  179. package/dist/form/Wizard/WizardStepContent.js +11 -16
  180. package/dist/form/Wizard/WizardStepIndicator.js +6 -6
  181. package/dist/form/Wizard/types.d.ts +0 -14
  182. package/dist/form/fieldRegistry.d.ts +1 -1
  183. package/dist/form/fieldRegistry.js +6 -6
  184. package/dist/form/formEditing.js +1 -1
  185. package/dist/form/index.d.ts +5 -4
  186. package/dist/form/index.js +6 -7
  187. package/dist/form/types/fieldComponentTypes.d.ts +8 -10
  188. package/dist/form/useChoiceField.d.ts +20 -0
  189. package/dist/form/useChoiceField.js +49 -0
  190. package/dist/form/useFieldValue.d.ts +7 -0
  191. package/dist/form/useFieldValue.js +20 -0
  192. package/dist/form/useParsedOpts.d.ts +3 -1
  193. package/dist/form/useParsedOpts.js +12 -17
  194. package/dist/form/utils/dependentOptions.d.ts +8 -4
  195. package/dist/form/utils/dependentOptions.js +25 -17
  196. package/dist/form/utils/fieldItems.d.ts +10 -0
  197. package/dist/form/utils/fieldItems.js +11 -0
  198. package/dist/form/utils/fieldPath.d.ts +10 -0
  199. package/dist/form/utils/fieldPath.js +20 -0
  200. package/dist/form/utils/shareEqual.d.ts +6 -0
  201. package/dist/form/utils/shareEqual.js +38 -0
  202. package/dist/graph/AnnotationBanner.js +8 -8
  203. package/dist/graph/Collapse.d.ts +1 -0
  204. package/dist/graph/Collapse.js +6 -27
  205. package/dist/graph/Connectors.js +5 -5
  206. package/dist/graph/DependencyGraph.js +20 -19
  207. package/dist/graph/GraphEditor.js +30 -41
  208. package/dist/graph/GraphEditorDialogs.js +17 -17
  209. package/dist/graph/GraphNode.js +1 -1
  210. package/dist/graph/InputDialog.js +19 -22
  211. package/dist/graph/InputsEditor.js +58 -66
  212. package/dist/graph/JobSummary.js +42 -39
  213. package/dist/graph/MatrixGroup.js +1 -1
  214. package/dist/graph/ProblemsButton.js +18 -19
  215. package/dist/graph/Reveal.js +1 -1
  216. package/dist/graph/ShortcutsButton.js +15 -18
  217. package/dist/graph/SuggestionInput.d.ts +5 -10
  218. package/dist/graph/SuggestionInput.js +14 -18
  219. package/dist/graph/ToolbarPopover.d.ts +11 -6
  220. package/dist/graph/ToolbarPopover.js +35 -67
  221. package/dist/graph/TreeView.js +24 -37
  222. package/dist/graph/WorkflowSettingsDialog.js +4 -4
  223. package/dist/graph/editorChrome.js +13 -12
  224. package/dist/graph/editorFields.js +29 -29
  225. package/dist/graph/editorPrimitives.d.ts +1 -1
  226. package/dist/graph/editorPrimitives.js +10 -7
  227. package/dist/graph/editorRows.js +103 -97
  228. package/dist/graph/fieldProblems.js +2 -2
  229. package/dist/graph/graphEditorState.d.ts +4 -3
  230. package/dist/graph/inputRefs.js +9 -9
  231. package/dist/graph/settingsViews.js +6 -7
  232. package/dist/graph/stepWith.js +6 -6
  233. package/dist/index.d.ts +14 -15
  234. package/dist/index.js +15 -14
  235. package/dist/list/ActionToolbar.d.ts +6 -14
  236. package/dist/list/ActionToolbar.js +48 -96
  237. package/dist/list/ListPage.d.ts +6 -12
  238. package/dist/list/ListPage.js +46 -29
  239. package/dist/list/ListPager.js +4 -4
  240. package/dist/list/ListTable.js +5 -5
  241. package/dist/list/ListViewControls.d.ts +5 -4
  242. package/dist/list/ListViewControls.js +177 -267
  243. package/dist/list/UserHoverCard.d.ts +3 -17
  244. package/dist/list/UserHoverCard.js +21 -45
  245. package/dist/list/index.d.ts +3 -4
  246. package/dist/list/index.js +3 -4
  247. package/dist/list/listSearch.js +12 -11
  248. package/dist/list/rowMenu.d.ts +63 -0
  249. package/dist/list/rowMenu.js +134 -0
  250. package/dist/logviewer/LogViewer.js +26 -26
  251. package/dist/styles.css +1 -1
  252. package/package.json +7 -13
  253. package/dist/ai/ui/Dropdown.d.ts +0 -31
  254. package/dist/ai/ui/Dropdown.js +0 -110
  255. package/dist/components/AddMenu.d.ts +0 -18
  256. package/dist/components/AddMenu.js +0 -46
  257. package/dist/components/BareModal.d.ts +0 -17
  258. package/dist/components/BareModal.js +0 -77
  259. package/dist/components/CollapsiblePanel.d.ts +0 -27
  260. package/dist/components/CollapsiblePanel.js +0 -77
  261. package/dist/components/Dropdown.d.ts +0 -28
  262. package/dist/components/Dropdown.js +0 -355
  263. package/dist/components/Listbox.d.ts +0 -21
  264. package/dist/components/Listbox.js +0 -119
  265. package/dist/components/MultiSelect.d.ts +0 -22
  266. package/dist/components/MultiSelect.js +0 -168
  267. package/dist/components/SwitchToggle.d.ts +0 -15
  268. package/dist/components/SwitchToggle.js +0 -57
  269. package/dist/components/SwitchToggleSmall.d.ts +0 -6
  270. package/dist/components/SwitchToggleSmall.js +0 -14
  271. package/dist/components/Toggle.d.ts +0 -6
  272. package/dist/components/Toggle.js +0 -20
  273. package/dist/components/dropdownUtils.d.ts +0 -37
  274. package/dist/components/dropdownUtils.js +0 -99
  275. package/dist/form/SpecialTypes/DropdownWrapper.d.ts +0 -25
  276. package/dist/form/SpecialTypes/DropdownWrapper.js +0 -28
  277. package/dist/form/SpecialTypes/FormikCustomDropdown.d.ts +0 -51
  278. package/dist/form/SpecialTypes/FormikCustomDropdown.js +0 -119
  279. package/dist/form/SpecialTypes/FormikCustomInput.d.ts +0 -19
  280. package/dist/form/SpecialTypes/FormikCustomInput.js +0 -121
  281. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.d.ts +0 -13
  282. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +0 -31
  283. package/dist/form/SpecialTypes/FormikNumericInput.d.ts +0 -9
  284. package/dist/form/SpecialTypes/FormikNumericInput.js +0 -60
  285. package/dist/form/SpecialTypes/index.d.ts +0 -3
  286. package/dist/list/HoverCard.d.ts +0 -24
  287. package/dist/list/HoverCard.js +0 -73
  288. package/dist/list/RowContextMenu.d.ts +0 -127
  289. package/dist/list/RowContextMenu.js +0 -515
@@ -1,4 +1,3 @@
1
- import { useStrings } from "../../components/Provider.js";
2
1
  import { FaLink } from "../../icons/fa/FaLink.js";
3
2
  import { FiDownload } from "../../icons/fi/FiDownload.js";
4
3
  import { FiFile } from "../../icons/fi/FiFile.js";
@@ -7,16 +6,17 @@ import { LuChevronLeft } from "../../icons/lu/LuChevronLeft.js";
7
6
  import { LuChevronRight } from "../../icons/lu/LuChevronRight.js";
8
7
  import { LuZoomIn } from "../../icons/lu/LuZoomIn.js";
9
8
  import { LuZoomOut } from "../../icons/lu/LuZoomOut.js";
9
+ import { useStrings } from "../../components/Provider.js";
10
+ import { Modal } from "../../components/Modal.js";
10
11
  import { formatFileSize } from "../lib/utils.js";
11
12
  import { getPreviewKind } from "./previewType.js";
12
13
  import { StreamedBadge } from "./StreamedBadge.js";
13
14
  import { usePresignedUrl } from "./usePresignedUrl.js";
14
15
  import { FilePreviewViewer } from "./Viewer.js";
15
- import cx from "classnames";
16
- import { useCallback, useEffect, useState } from "react";
16
+ import { clsx } from "clsx";
17
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
18
+ import { useEffect, useState } from "react";
17
19
  import { useLocalStorage } from "usehooks-ts";
18
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
19
- import { createPortal } from "react-dom";
20
20
  //#region src/file-explorer/FilePreview/index.tsx
21
21
  /** Document views run their own chrome and text to the edge of the stage, which
22
22
  * full-window bars would float on top of; they get the bars in flow instead. */
@@ -35,50 +35,27 @@ function FilePreview({ open, node, siblings, storage, getPresignedUrl, onNavigat
35
35
  const index = node ? siblings.findIndex((s) => s.path === node.path) : -1;
36
36
  const hasPrev = index > 0;
37
37
  const hasNext = index > -1 && index < siblings.length - 1;
38
- const goPrev = useCallback(() => {
38
+ const goPrev = () => {
39
39
  const prev = index > 0 ? siblings[index - 1] : void 0;
40
40
  if (prev) onNavigate(prev);
41
- }, [
42
- index,
43
- siblings,
44
- onNavigate
45
- ]);
46
- const goNext = useCallback(() => {
41
+ };
42
+ const goNext = () => {
47
43
  const next = index > -1 ? siblings[index + 1] : void 0;
48
44
  if (next) onNavigate(next);
49
- }, [
50
- index,
51
- siblings,
52
- onNavigate
53
- ]);
45
+ };
54
46
  useEffect(() => {
55
47
  setZoom(100);
56
48
  }, [node]);
57
- useEffect(() => {
58
- if (!open) return;
59
- const onKeyDown = (e) => {
60
- if (e.key === "Escape") onClose();
61
- else if (e.key === "ArrowRight") goNext();
62
- else if (e.key === "ArrowLeft") goPrev();
63
- };
64
- document.addEventListener("keydown", onKeyDown);
65
- return () => document.removeEventListener("keydown", onKeyDown);
66
- }, [
67
- open,
68
- onClose,
69
- goNext,
70
- goPrev
71
- ]);
72
- if (!open || !node) return null;
49
+ if (!node) return null;
73
50
  const kind = getPreviewKind(node);
74
51
  const showZoom = kind === "image";
75
52
  const floatingChrome = isOverlay && !isDocumentView(kind);
76
53
  const topBar = /* @__PURE__ */ jsxs("div", {
77
- className: cx("flex items-center justify-between gap-3 px-4 py-3", floatingChrome ? "absolute inset-x-0 top-0 z-10 bg-linear-to-b from-black/80 to-transparent text-white" : "shrink-0 border-b theme-border"),
54
+ className: clsx("flex items-center justify-between gap-3 px-4 py-3", floatingChrome ? "absolute inset-x-0 top-0 z-10 bg-linear-to-b from-black/80 to-transparent text-white" : "shrink-0 border-b theme-border"),
78
55
  children: [/* @__PURE__ */ jsxs("div", {
79
56
  className: "flex min-w-0 items-center gap-2.5",
80
57
  children: [
81
- /* @__PURE__ */ jsx(FiFile, { className: cx("h-4 w-4 shrink-0", !floatingChrome && "theme-muted-text") }),
58
+ /* @__PURE__ */ jsx(FiFile, { className: clsx("h-4 w-4 shrink-0", !floatingChrome && "theme-muted-text") }),
82
59
  /* @__PURE__ */ jsx("span", {
83
60
  className: "truncate font-semibold",
84
61
  children: node.name
@@ -89,7 +66,7 @@ function FilePreview({ open, node, siblings, storage, getPresignedUrl, onNavigat
89
66
  className: "flex shrink-0 items-center gap-1.5",
90
67
  children: [
91
68
  /* @__PURE__ */ jsxs("div", {
92
- className: cx("mr-1 flex items-center rounded-lg p-0.5", floatingChrome ? "bg-white/10" : "theme-muted-panel"),
69
+ className: clsx("mr-1 flex items-center rounded-lg p-0.5", floatingChrome ? "bg-white/10" : "theme-muted-panel"),
93
70
  children: [/* @__PURE__ */ jsx(SegButton, {
94
71
  active: !isOverlay,
95
72
  overlayChrome: floatingChrome,
@@ -124,14 +101,14 @@ function FilePreview({ open, node, siblings, storage, getPresignedUrl, onNavigat
124
101
  })]
125
102
  });
126
103
  const footer = /* @__PURE__ */ jsxs("div", {
127
- className: cx("flex items-center justify-between gap-4 px-4 py-2.5", floatingChrome ? "absolute inset-x-0 bottom-0 z-10 bg-linear-to-t from-black/80 to-transparent text-white" : "shrink-0 border-t theme-border"),
104
+ className: clsx("flex items-center justify-between gap-4 px-4 py-2.5", floatingChrome ? "absolute inset-x-0 bottom-0 z-10 bg-linear-to-t from-black/80 to-transparent text-white" : "shrink-0 border-t theme-border"),
128
105
  children: [/* @__PURE__ */ jsxs("span", {
129
- className: cx("text-xs", !floatingChrome && "theme-muted-text"),
106
+ className: clsx("text-xs", !floatingChrome && "theme-muted-text"),
130
107
  children: [typeof node.size === "number" && formatFileSize(node.size), node.contentType && ` · ${node.contentType}`]
131
108
  }), /* @__PURE__ */ jsxs("div", {
132
109
  className: "flex items-center gap-3",
133
110
  children: [showZoom && /* @__PURE__ */ jsxs("div", {
134
- className: cx("flex items-center gap-1 rounded-lg p-0.5", floatingChrome ? "bg-white/10" : "theme-muted-panel"),
111
+ className: clsx("flex items-center gap-1 rounded-lg p-0.5", floatingChrome ? "bg-white/10" : "theme-muted-panel"),
135
112
  children: [
136
113
  /* @__PURE__ */ jsx(MiniButton, {
137
114
  overlay: floatingChrome,
@@ -188,49 +165,41 @@ function FilePreview({ open, node, siblings, storage, getPresignedUrl, onNavigat
188
165
  onDownload: () => onDownload(node)
189
166
  }, node.path)
190
167
  });
191
- return createPortal(/* @__PURE__ */ jsxs("div", {
192
- role: "none",
193
- className: "fixed inset-0 z-9995 flex items-center justify-center",
194
- style: {
195
- backgroundColor: isOverlay ? "rgba(1,4,9,.94)" : "rgba(1,4,9,.62)",
196
- backdropFilter: isOverlay ? void 0 : "blur(3px)",
197
- WebkitBackdropFilter: isOverlay ? void 0 : "blur(3px)"
198
- },
199
- onClick: (e) => {
200
- if (e.target === e.currentTarget) onClose();
168
+ return /* @__PURE__ */ jsxs(Modal, {
169
+ open,
170
+ onClose,
171
+ align: "center",
172
+ panel: false,
173
+ "aria-label": node.name,
174
+ backdropClassName: isOverlay ? "bg-[rgba(1,4,9,.94)]" : "bg-[rgba(1,4,9,.62)] backdrop-blur-[3px]",
175
+ className: clsx("flex flex-col", isOverlay ? "fixed inset-0" : "relative h-[min(780px,90vh)] w-[min(1120px,94vw)] overflow-hidden rounded-2xl border theme-border shadow-2xl", floatingChrome ? "bg-transparent" : "bg-(--theme-panel-bg)"),
176
+ onKeyDown: (e) => {
177
+ if (e.key === "ArrowRight") goNext();
178
+ else if (e.key === "ArrowLeft") goPrev();
201
179
  },
202
- children: [isOverlay && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(EdgeButton, {
203
- side: "left",
204
- label: t.preview.previousFile,
205
- disabled: !hasPrev,
206
- onClick: goPrev
207
- }), /* @__PURE__ */ jsx(EdgeButton, {
208
- side: "right",
209
- label: t.preview.nextFile,
210
- disabled: !hasNext,
211
- onClick: goNext
212
- })] }), /* @__PURE__ */ jsxs("div", {
213
- role: "dialog",
214
- "aria-modal": "true",
215
- "aria-label": node.name,
216
- className: cx("relative flex flex-col", isOverlay ? "h-screen w-screen" : "overflow-hidden rounded-2xl border theme-border shadow-2xl", floatingChrome ? "bg-transparent" : "bg-(--theme-panel-bg)"),
217
- style: isOverlay ? void 0 : {
218
- width: "min(1120px, 94vw)",
219
- height: "min(780px, 90vh)"
220
- },
221
- children: [
222
- topBar,
223
- stage,
224
- footer
225
- ]
226
- })]
227
- }), document.body);
180
+ children: [
181
+ isOverlay && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(EdgeButton, {
182
+ side: "left",
183
+ label: t.preview.previousFile,
184
+ disabled: !hasPrev,
185
+ onClick: goPrev
186
+ }), /* @__PURE__ */ jsx(EdgeButton, {
187
+ side: "right",
188
+ label: t.preview.nextFile,
189
+ disabled: !hasNext,
190
+ onClick: goNext
191
+ })] }),
192
+ topBar,
193
+ stage,
194
+ footer
195
+ ]
196
+ });
228
197
  }
229
198
  function SegButton({ active, overlayChrome, onClick, children }) {
230
199
  return /* @__PURE__ */ jsx("button", {
231
200
  type: "button",
232
201
  onClick,
233
- className: cx("cursor-pointer whitespace-nowrap rounded-md px-2.5 py-1 text-[11.5px] font-medium transition-colors", active ? "bg-(--theme-element) text-(--theme-element-text)" : overlayChrome ? "text-white/70 hover:text-white" : "theme-muted-text hover:theme-text"),
202
+ className: clsx("cursor-pointer whitespace-nowrap rounded-md px-2.5 py-1 text-[11.5px] font-medium transition-colors", active ? "bg-(--theme-element) text-(--theme-element-text)" : overlayChrome ? "text-white/70 hover:text-white" : "theme-muted-text hover:theme-text"),
234
203
  children
235
204
  });
236
205
  }
@@ -240,7 +209,7 @@ function ChromeButton({ overlay, label, onClick, children }) {
240
209
  "aria-label": label,
241
210
  title: label,
242
211
  onClick,
243
- className: cx("flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg transition-colors", overlay ? "text-white/90 hover:bg-white/15" : "theme-muted-text hover:theme-hover hover:theme-text"),
212
+ className: clsx("flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg transition-colors", overlay ? "text-white/90 hover:bg-white/15" : "theme-muted-text hover:theme-hover hover:theme-text"),
244
213
  children
245
214
  });
246
215
  }
@@ -251,7 +220,7 @@ function MiniButton({ overlay, label, onClick, disabled, children }) {
251
220
  title: label,
252
221
  onClick,
253
222
  disabled,
254
- className: cx("flex h-6 w-7 items-center justify-center rounded-md transition-colors", disabled ? "cursor-not-allowed opacity-40" : cx("cursor-pointer", overlay ? "hover:bg-white/15" : "hover:theme-hover")),
223
+ className: clsx("flex h-6 w-7 items-center justify-center rounded-md transition-colors", disabled ? "cursor-not-allowed opacity-40" : clsx("cursor-pointer", overlay ? "hover:bg-white/15" : "hover:theme-hover")),
255
224
  children
256
225
  });
257
226
  }
@@ -260,11 +229,8 @@ function EdgeButton({ side, label, disabled, onClick }) {
260
229
  type: "button",
261
230
  "aria-label": label,
262
231
  disabled,
263
- onClick: (e) => {
264
- e.stopPropagation();
265
- onClick();
266
- },
267
- className: cx("absolute top-1/2 z-20 flex h-13 w-13 -translate-y-1/2 items-center justify-center rounded-full text-white backdrop-blur", side === "left" ? "left-5" : "right-5", disabled ? "cursor-not-allowed opacity-30" : "cursor-pointer hover:bg-white/20"),
232
+ onClick,
233
+ className: clsx("absolute top-1/2 z-20 flex h-13 w-13 -translate-y-1/2 items-center justify-center rounded-full text-white backdrop-blur", side === "left" ? "left-5" : "right-5", disabled ? "cursor-not-allowed opacity-30" : "cursor-pointer hover:bg-white/20"),
268
234
  style: { backgroundColor: "rgba(22,27,34,.7)" },
269
235
  children: side === "left" ? /* @__PURE__ */ jsx(LuChevronLeft, { className: "h-6 w-6" }) : /* @__PURE__ */ jsx(LuChevronRight, { className: "h-6 w-6" })
270
236
  });
@@ -1,5 +1,6 @@
1
1
  import type { ReactNode } from 'react';
2
- import { type OpenMenu, type RowMenuItem } from '../list/index.js';
2
+ import type { OpenMenu } from '../components/ContextMenu.js';
3
+ import type { MenuEntry } from '../components/MenuEntries.js';
3
4
  import type { TreeNode } from './lib/types.js';
4
5
  export declare const ROW_HEIGHT_SHORT = 45;
5
6
  export declare const ROW_HEIGHT_TALL = 52.25;
@@ -17,7 +18,7 @@ interface FileRowProps {
17
18
  active: boolean;
18
19
  checked: boolean;
19
20
  canPreview: boolean;
20
- getItems: () => RowMenuItem[];
21
+ getItems: () => MenuEntry[];
21
22
  openMenu: OpenMenu;
22
23
  onOpen: (node: TreeNode) => void;
23
24
  onToggleCheck: (node: TreeNode, checked: boolean) => void;
@@ -27,7 +28,7 @@ export declare function UserRow({ node, icon, storageCount, getItems, openMenu,
27
28
  node: TreeNode;
28
29
  icon: ReactNode;
29
30
  storageCount: number;
30
- getItems: () => RowMenuItem[];
31
+ getItems: () => MenuEntry[];
31
32
  openMenu: OpenMenu;
32
33
  onOpen: (node: TreeNode) => void;
33
34
  }): import("react").JSX.Element;
@@ -1,11 +1,11 @@
1
- import { useStrings } from "../components/Provider.js";
2
1
  import { LuEye } from "../icons/lu/LuEye.js";
3
- import { TOOLTIP_ID } from "../components/Tooltip.js";
4
- import { MoreButton, useRowMenuActive } from "../list/RowContextMenu.js";
2
+ import { Tooltip } from "../components/Tooltip.js";
3
+ import { useStrings } from "../components/Provider.js";
5
4
  import { Table } from "../components/Table.js";
6
5
  import { RowSelectCheckbox } from "../list/ListTable.js";
6
+ import { MoreButton, rowContextMenuProps, useRowMenuActive } from "../list/rowMenu.js";
7
7
  import { formatFileSize } from "./lib/utils.js";
8
- import cx from "classnames";
8
+ import { clsx } from "clsx";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
  import { DateTime } from "luxon";
11
11
  var ROW_HEIGHT_TALL = 52.25;
@@ -19,14 +19,6 @@ function fileRowHeight(node) {
19
19
  function isInteractiveTarget(e) {
20
20
  return !!e.target.closest("a,button,input,label");
21
21
  }
22
- function lazyContextMenuProps(openMenu, getItems) {
23
- return { onContextMenu: (e) => {
24
- const items = getItems();
25
- e.preventDefault();
26
- if (items.length > 0) e.stopPropagation();
27
- openMenu(e.clientX, e.clientY, items);
28
- } };
29
- }
30
22
  function UserRow({ node, icon, storageCount, getItems, openMenu, onOpen }) {
31
23
  const t = useStrings().fileExplorer;
32
24
  const { active: menuActive, openMenu: openRowMenu } = useRowMenuActive(openMenu);
@@ -35,9 +27,9 @@ function UserRow({ node, icon, storageCount, getItems, openMenu, onOpen }) {
35
27
  onOpen(node);
36
28
  };
37
29
  return /* @__PURE__ */ jsxs("tr", {
38
- className: cx("group cursor-pointer", menuActive ? "theme-hover" : "hover:theme-hover"),
30
+ className: clsx("group cursor-pointer", menuActive ? "theme-hover" : "hover:theme-hover"),
39
31
  onClick: handleRowClick,
40
- ...lazyContextMenuProps(openRowMenu, getItems),
32
+ ...rowContextMenuProps(openRowMenu, getItems),
41
33
  children: [
42
34
  /* @__PURE__ */ jsx(Table.Item, {
43
35
  className: "py-2.5",
@@ -65,8 +57,8 @@ function UserRow({ node, icon, storageCount, getItems, openMenu, onOpen }) {
65
57
  children: /* @__PURE__ */ jsx("div", {
66
58
  className: "absolute inset-y-0 right-0 flex items-center pr-4",
67
59
  children: /* @__PURE__ */ jsx(MoreButton, {
68
- active: menuActive,
69
- onOpen: (x, y) => openRowMenu(x, y, getItems())
60
+ open: menuActive,
61
+ onOpen: (button) => openRowMenu(button, getItems())
70
62
  })
71
63
  })
72
64
  })
@@ -87,10 +79,10 @@ function FileRow({ node, icon, rowId, rowIndex, active, checked, canPreview, get
87
79
  id: rowId,
88
80
  "aria-rowindex": rowIndex,
89
81
  "aria-selected": checked,
90
- className: cx("group", checked ? "bg-blue-500/5" : menuActive ? "theme-hover" : "hover:theme-hover", active && "group-focus-visible/grid:ring-1 group-focus-visible/grid:ring-inset group-focus-visible/grid:ring-(--theme-link)", "cursor-pointer"),
82
+ className: clsx("group", checked ? "bg-blue-500/5" : menuActive ? "theme-hover" : "hover:theme-hover", active && "group-focus-visible/grid:ring-1 group-focus-visible/grid:ring-inset group-focus-visible/grid:ring-(--theme-link)", "cursor-pointer"),
91
83
  onClick: handleRowClick,
92
84
  style: { height: fileRowHeight(node) },
93
- ...lazyContextMenuProps(openRowMenu, getItems),
85
+ ...rowContextMenuProps(openRowMenu, getItems),
94
86
  children: [
95
87
  /* @__PURE__ */ jsx(Table.Item, {
96
88
  className: "py-2.5",
@@ -129,32 +121,34 @@ function FileRow({ node, icon, rowId, rowIndex, active, checked, canPreview, get
129
121
  }),
130
122
  /* @__PURE__ */ jsx(Table.Item, {
131
123
  className: "truncate py-2.5 text-sm text-(--theme-muted-text-color)",
132
- children: /* @__PURE__ */ jsx("span", {
133
- "data-tooltip-id": TOOLTIP_ID,
134
- "data-tooltip-content": node.modified ?? "",
135
- "data-tooltip-place": "top",
136
- children: !isDir && modifiedDt?.isValid ? modifiedDt.toRelative() : "—"
137
- })
124
+ children: !isDir && modifiedDt?.isValid ? /* @__PURE__ */ jsx(Tooltip, {
125
+ content: modifiedDt.toLocaleString(DateTime.DATETIME_MED_WITH_SECONDS),
126
+ children: /* @__PURE__ */ jsx("time", {
127
+ dateTime: modifiedDt.toISO() ?? void 0,
128
+ children: modifiedDt.toRelative()
129
+ })
130
+ }) : "—"
138
131
  }),
139
132
  /* @__PURE__ */ jsx(Table.Item, {
140
133
  className: "relative py-2.5",
141
134
  children: /* @__PURE__ */ jsxs("div", {
142
135
  className: "absolute inset-y-0 right-0 flex items-center gap-0.5 pr-4",
143
- children: [!isDir && canPreview && /* @__PURE__ */ jsx("button", {
144
- type: "button",
145
- "aria-label": t.preview.preview,
146
- "data-tooltip-id": "global-tooltip",
147
- "data-tooltip-content": t.preview.preview,
148
- "data-tooltip-place": "bottom",
149
- onClick: (e) => {
150
- e.stopPropagation();
151
- onPreview(node);
152
- },
153
- className: cx("rounded p-1 text-(--theme-muted-text-color) transition-colors hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) [&>svg]:h-4 [&>svg]:w-4", menuActive ? "opacity-100" : "opacity-0 group-hover:opacity-100 focus-visible:opacity-100"),
154
- children: /* @__PURE__ */ jsx(LuEye, {})
136
+ children: [!isDir && canPreview && /* @__PURE__ */ jsx(Tooltip, {
137
+ content: t.preview.preview,
138
+ side: "bottom",
139
+ children: /* @__PURE__ */ jsx("button", {
140
+ type: "button",
141
+ "aria-label": t.preview.preview,
142
+ onClick: (e) => {
143
+ e.stopPropagation();
144
+ onPreview(node);
145
+ },
146
+ className: clsx("rounded p-1 text-(--theme-muted-text-color) transition-colors hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) [&>svg]:h-4 [&>svg]:w-4", menuActive ? "opacity-100" : "opacity-0 group-hover:opacity-100 focus-visible:opacity-100"),
147
+ children: /* @__PURE__ */ jsx(LuEye, {})
148
+ })
155
149
  }), /* @__PURE__ */ jsx(MoreButton, {
156
- active: menuActive,
157
- onOpen: (x, y) => openRowMenu(x, y, getItems())
150
+ open: menuActive,
151
+ onOpen: (button) => openRowMenu(button, getItems())
158
152
  })]
159
153
  })
160
154
  })
@@ -1,4 +1,5 @@
1
- import type { OpenMenu, RowMenuItem } from '../list/index.js';
1
+ import type { OpenMenu } from '../components/ContextMenu.js';
2
+ import type { MenuEntry } from '../components/MenuEntries.js';
2
3
  import { type LoadMoreState } from './LoadMoreRow.js';
3
4
  import type { TreeNode } from './lib/types.js';
4
5
  interface Span {
@@ -24,7 +25,7 @@ interface FileRowsWindowProps {
24
25
  rowIdPrefix: string;
25
26
  scrollEl: HTMLElement | null;
26
27
  loadMore?: LoadMoreState | undefined;
27
- getItems: (node: TreeNode) => RowMenuItem[];
28
+ getItems: (node: TreeNode) => MenuEntry[];
28
29
  openMenu: OpenMenu;
29
30
  onOpen: (node: TreeNode) => void;
30
31
  onToggleCheck: (node: TreeNode, checked: boolean) => void;
@@ -1,12 +1,12 @@
1
- import { useSlots, useStrings } from "../components/Provider.js";
2
1
  import { FaRegFolder } from "../icons/fa/FaRegFolder.js";
3
2
  import { FiFile } from "../icons/fi/FiFile.js";
3
+ import { useSlots, useStrings } from "../components/Provider.js";
4
4
  import { canPreview } from "./FilePreview/previewType.js";
5
5
  import { getNodeIcon } from "./helpers.js";
6
6
  import { FileRow } from "./FileRow.js";
7
7
  import { LoadMoreRow } from "./LoadMoreRow.js";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
8
9
  import { useEffect } from "react";
9
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
10
  //#region src/file-explorer/FileRowsWindow.tsx
11
11
  /** `start`/`end` include scrollMargin but getTotalSize() does not, so the margin
12
12
  * has to come back out of both. */
@@ -29,7 +29,7 @@ function FileRowsWindow({ items, padTop, padBottom, nodes, checkedItems, activeI
29
29
  const storageIconAlt = useStrings().fileExplorer.chrome.storageIconAlt;
30
30
  useNestedScrollerWarning(scrollEl, nodes.length);
31
31
  useRowPitchAudit(scrollEl, nodes, items);
32
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [
32
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
33
33
  padTop > 0 && /* @__PURE__ */ jsx(Spacer, { height: padTop }, "pad-top"),
34
34
  items.map((item) => {
35
35
  const node = nodes[item.index];
@@ -62,7 +62,7 @@ function FileRowsWindow({ items, padTop, padBottom, nodes, checkedItems, activeI
62
62
  ] });
63
63
  }
64
64
  function Spacer({ height }) {
65
- return /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx("tr", {
65
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("tr", {
66
66
  "aria-hidden": "true",
67
67
  className: "border-0",
68
68
  children: /* @__PURE__ */ jsx("td", {
@@ -1,4 +1,5 @@
1
- import { type OpenMenu, type RowMenuItem } from '../list/index.js';
1
+ import type { OpenMenu } from '../components/ContextMenu.js';
2
+ import type { MenuEntry } from '../components/MenuEntries.js';
2
3
  import { type LoadMoreState } from './LoadMoreRow.js';
3
4
  import type { TreeNode } from './lib/types.js';
4
5
  interface FileTableProps {
@@ -7,7 +8,7 @@ interface FileTableProps {
7
8
  allSelected: boolean;
8
9
  someSelected: boolean;
9
10
  onSelectAll: () => void;
10
- getItems: (node: TreeNode) => RowMenuItem[];
11
+ getItems: (node: TreeNode) => MenuEntry[];
11
12
  openMenu: OpenMenu;
12
13
  onOpen: (node: TreeNode) => void;
13
14
  onToggleCheck: (node: TreeNode, checked: boolean) => void;
@@ -3,9 +3,9 @@ import { listTableFixedProps } from "../list/ListTable.js";
3
3
  import { fileRowHeight } from "./FileRow.js";
4
4
  import { FileRowsWindow, spacerHeights } from "./FileRowsWindow.js";
5
5
  import { FileTableHeaders } from "./FileTableHeaders.js";
6
- import cx from "classnames";
7
- import { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
6
+ import { clsx } from "clsx";
8
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
9
9
  import { useVirtualizer } from "@tanstack/react-virtual";
10
10
  //#region src/file-explorer/FileTable.tsx
11
11
  /** The file table. Give it a `key` of the folder path: a folder change must reset
@@ -133,7 +133,7 @@ function FileTable({ nodes, checkedItems, allSelected, someSelected, onSelectAll
133
133
  className: "h-full overflow-auto",
134
134
  children: /* @__PURE__ */ jsxs(Table, {
135
135
  ...listTableFixedProps,
136
- className: cx(listTableFixedProps.className, "group/grid focus:outline-none"),
136
+ className: clsx(listTableFixedProps.className, "group/grid focus:outline-none"),
137
137
  wrapperClassName: "overflow-x-auto",
138
138
  tableProps: {
139
139
  role: "grid",
@@ -1,8 +1,8 @@
1
1
  import { useStrings } from "../components/Provider.js";
2
2
  import Loader from "../components/Loader.js";
3
3
  import { useNearEnd } from "./useNearEnd.js";
4
- import { useRef } from "react";
5
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { useRef } from "react";
6
6
  function LoadMoreRow({ rowId, rowIndex, loading, error, auto, root, onLoadMore }) {
7
7
  const t = useStrings().fileExplorer;
8
8
  const ref = useRef(null);
@@ -1,16 +1,15 @@
1
- import { useStrings } from "../components/Provider.js";
2
1
  import { FaAngleRight } from "../icons/fa/FaAngleRight.js";
3
2
  import { FaRegFolder } from "../icons/fa/FaRegFolder.js";
4
3
  import { FaRegFolderOpen } from "../icons/fa6/FaRegFolderOpen.js";
5
4
  import { positionKeys } from "../components/keys.js";
5
+ import { useStrings } from "../components/Provider.js";
6
6
  import { getParentPath } from "./lib/utils.js";
7
7
  import { canPreview } from "./FilePreview/previewType.js";
8
8
  import { getNodeIcon } from "./helpers.js";
9
9
  import { findRowIndex, flattenTreeRows, nextFileLimit, stepRow } from "./treeRows.js";
10
- import cx from "classnames";
10
+ import { clsx } from "clsx";
11
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
12
  import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
12
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
- import Skeleton from "react-loading-skeleton";
14
13
  import { useVirtualizer } from "@tanstack/react-virtual";
15
14
  //#region src/file-explorer/TreeView.tsx
16
15
  /** 9px margin + 12px padding, per level. */
@@ -183,7 +182,7 @@ function indentStyle(depth, isDirectory) {
183
182
  }
184
183
  function IndentGuides({ depth }) {
185
184
  if (depth === 0) return null;
186
- return /* @__PURE__ */ jsx(Fragment$1, { children: positionKeys(depth, "indent").map((key, level) => /* @__PURE__ */ jsx("span", {
185
+ return /* @__PURE__ */ jsx(Fragment, { children: positionKeys(depth, "indent").map((key, level) => /* @__PURE__ */ jsx("span", {
187
186
  "aria-hidden": "true",
188
187
  className: "pointer-events-none absolute inset-y-0 w-px bg-(--theme-border)/60",
189
188
  style: { left: GUIDE_OFFSET + level * INDENT_PER_LEVEL }
@@ -195,7 +194,7 @@ function RowIcons({ isDirectory, isExpanded, customIcon }) {
195
194
  children: customIcon
196
195
  });
197
196
  const folder = isExpanded ? /* @__PURE__ */ jsx(FaRegFolderOpen, { className: "h-4 w-4 mr-1 text-sky-500" }) : /* @__PURE__ */ jsx(FaRegFolder, { className: "h-4 w-4 mr-1 text-sky-500/80" });
198
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(FaAngleRight, { className: cx("h-3.5 w-3.5 shrink-0 theme-muted-text transition-transform duration-150", isExpanded && "rotate-90") }), customIcon ?? folder] });
197
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(FaAngleRight, { className: clsx("h-3.5 w-3.5 shrink-0 theme-muted-text transition-transform duration-150", isExpanded && "rotate-90") }), customIcon ?? folder] });
199
198
  }
200
199
  /** Click-only, unlike the table's sentinel: the tree is a navigation aid, and
201
200
  * growing it automatically as the user scrolls is what the cap exists to prevent. */
@@ -213,16 +212,15 @@ function TreeMoreRow({ depth, hiddenFiles, partial, loading, failed, onReveal })
213
212
  style: { paddingLeft: depth * INDENT_PER_LEVEL + ROW_PAD_FILE },
214
213
  children: loading ? /* @__PURE__ */ jsx("span", { children: t.loadingMore }) : /* @__PURE__ */ jsx("button", {
215
214
  type: "button",
216
- className: cx("cursor-pointer underline", failed ? "text-red-500" : "theme-link"),
215
+ className: clsx("cursor-pointer underline", failed ? "text-red-500" : "theme-link"),
217
216
  onClick: onReveal,
218
217
  children: label()
219
218
  })
220
219
  })]
221
220
  });
222
221
  }
223
- /** Sized by the slot, not by its contents: react-loading-skeleton wraps each bar
224
- * in an inline span, so a bar occupies a line box taller than its `height` and
225
- * the overflow would sit on top of the absolutely positioned row below. */
222
+ /** Sized by the slot, not by its contents, so the bars never spill onto the
223
+ * absolutely positioned row below. */
226
224
  function TreeSkeletonRow({ depth }) {
227
225
  return /* @__PURE__ */ jsxs("div", {
228
226
  className: "relative h-full overflow-hidden",
@@ -233,10 +231,7 @@ function TreeSkeletonRow({ depth }) {
233
231
  0,
234
232
  1,
235
233
  2
236
- ].map((i) => /* @__PURE__ */ jsx(Skeleton, {
237
- height: 12,
238
- containerClassName: "block leading-none"
239
- }, i))
234
+ ].map((i) => /* @__PURE__ */ jsx("div", { className: "h-3 shrink-0 animate-pulse rounded bg-(--theme-muted-panel-bg)" }, i))
240
235
  })]
241
236
  });
242
237
  }
@@ -339,10 +334,10 @@ var TreeRowItem = memo(function TreeRowItem({ row, isSelected, onToggleExpand, o
339
334
  const customIcon = getNodeIcon(node);
340
335
  const label = isDirectory && node.storageId && node.displayName ? node.displayName : node.name;
341
336
  return /* @__PURE__ */ jsxs("div", {
342
- className: cx("relative h-full rounded-md transition-[box-shadow,background-color] duration-150", dragActive && "ring-1 ring-(--theme-link)/60"),
337
+ className: clsx("relative h-full rounded-md transition-[box-shadow,background-color] duration-150", dragActive && "ring-1 ring-(--theme-link)/60"),
343
338
  ...dragHandlers,
344
339
  children: [/* @__PURE__ */ jsx(IndentGuides, { depth }), /* @__PURE__ */ jsxs("div", {
345
- className: cx("group relative flex items-center gap-1.5 pr-2 py-1 rounded-md cursor-pointer", "transition-colors duration-150", "focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-(--theme-link)", isSelected ? "bg-(--theme-element)/15 font-medium" : dragActive ? "theme-hover" : "hover:theme-hover"),
340
+ className: clsx("group relative flex items-center gap-1.5 pr-2 py-1 rounded-md cursor-pointer", "transition-colors duration-150", "focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-(--theme-link)", isSelected ? "bg-(--theme-element)/15 font-medium" : dragActive ? "theme-hover" : "hover:theme-hover"),
346
341
  style: indentStyle(depth, isDirectory),
347
342
  onClick: handleSelect,
348
343
  onKeyDown: handleKeyDown,