@parallelworks/ui 0.18.0 → 0.19.1

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 (349) hide show
  1. package/README.md +86 -6
  2. package/dist/ai/adapter/memoryStore.d.ts +8 -0
  3. package/dist/ai/adapter/memoryStore.js +152 -0
  4. package/dist/ai/adapter/mock/index.d.ts +2 -0
  5. package/dist/ai/adapter/mock/index.js +3 -0
  6. package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
  7. package/dist/ai/adapter/mock/mockAdapter.js +81 -0
  8. package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
  9. package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
  10. package/dist/ai/adapter/openai/errors.d.ts +3 -0
  11. package/dist/ai/adapter/openai/errors.js +37 -0
  12. package/dist/ai/adapter/openai/index.d.ts +6 -0
  13. package/dist/ai/adapter/openai/index.js +6 -0
  14. package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
  15. package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
  16. package/dist/ai/adapter/openai/responses.d.ts +4 -0
  17. package/dist/ai/adapter/openai/responses.js +108 -0
  18. package/dist/ai/adapter/openai/sse.d.ts +24 -0
  19. package/dist/ai/adapter/openai/sse.js +112 -0
  20. package/dist/ai/adapter/openai/wire.d.ts +40 -0
  21. package/dist/ai/adapter/types.d.ts +131 -0
  22. package/dist/ai/adapter/types.js +11 -0
  23. package/dist/ai/agent/classifier.d.ts +2 -0
  24. package/dist/ai/agent/classifier.js +12 -0
  25. package/dist/ai/agent/diff.d.ts +35 -0
  26. package/dist/ai/agent/diff.js +223 -0
  27. package/dist/ai/agent/diffHighlight.d.ts +6 -0
  28. package/dist/ai/agent/diffHighlight.js +101 -0
  29. package/dist/ai/agent/index.d.ts +6 -0
  30. package/dist/ai/agent/permissions.d.ts +11 -0
  31. package/dist/ai/agent/permissions.js +29 -0
  32. package/dist/ai/agent/toolfmt.d.ts +18 -0
  33. package/dist/ai/agent/toolfmt.js +383 -0
  34. package/dist/ai/agent/transcript.d.ts +38 -0
  35. package/dist/ai/agent/transcript.js +127 -0
  36. package/dist/ai/ai.css +325 -0
  37. package/dist/ai/components/AllocationSelector.d.ts +4 -0
  38. package/dist/ai/components/AllocationSelector.js +56 -0
  39. package/dist/ai/components/AttachmentManager.d.ts +1 -0
  40. package/dist/ai/components/AttachmentManager.js +144 -0
  41. package/dist/ai/components/AttachmentUpload.d.ts +24 -0
  42. package/dist/ai/components/AttachmentUpload.js +179 -0
  43. package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
  44. package/dist/ai/components/BlockedGroupBanner.js +29 -0
  45. package/dist/ai/components/BranchNavigator.d.ts +8 -0
  46. package/dist/ai/components/BranchNavigator.js +57 -0
  47. package/dist/ai/components/ChatEmptyState.d.ts +3 -0
  48. package/dist/ai/components/ChatEmptyState.js +171 -0
  49. package/dist/ai/components/ChatInput.d.ts +45 -0
  50. package/dist/ai/components/ChatInput.js +265 -0
  51. package/dist/ai/components/ChatLayout.d.ts +5 -0
  52. package/dist/ai/components/ChatLayout.js +15 -0
  53. package/dist/ai/components/ChatMessage.d.ts +24 -0
  54. package/dist/ai/components/ChatMessage.js +338 -0
  55. package/dist/ai/components/ChatMessageList.d.ts +35 -0
  56. package/dist/ai/components/ChatMessageList.js +301 -0
  57. package/dist/ai/components/ChatSidebar.d.ts +5 -0
  58. package/dist/ai/components/ChatSidebar.js +345 -0
  59. package/dist/ai/components/ChatThread.d.ts +3 -0
  60. package/dist/ai/components/ChatThread.js +198 -0
  61. package/dist/ai/components/ComposerChrome.d.ts +18 -0
  62. package/dist/ai/components/ComposerChrome.js +50 -0
  63. package/dist/ai/components/ComposerFrame.d.ts +16 -0
  64. package/dist/ai/components/ComposerFrame.js +33 -0
  65. package/dist/ai/components/DragOverlay.d.ts +5 -0
  66. package/dist/ai/components/DragOverlay.js +20 -0
  67. package/dist/ai/components/ModelSelector.d.ts +6 -0
  68. package/dist/ai/components/ModelSelector.js +343 -0
  69. package/dist/ai/components/ShareDialog.d.ts +11 -0
  70. package/dist/ai/components/ShareDialog.js +260 -0
  71. package/dist/ai/components/SlashMenu.d.ts +28 -0
  72. package/dist/ai/components/SlashMenu.js +91 -0
  73. package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
  74. package/dist/ai/components/agent/ActivityLine.js +151 -0
  75. package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
  76. package/dist/ai/components/agent/AgentMessageParts.js +721 -0
  77. package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
  78. package/dist/ai/components/agent/PermissionPicker.js +38 -0
  79. package/dist/ai/components/attachmentKeys.d.ts +4 -0
  80. package/dist/ai/components/attachmentKeys.js +10 -0
  81. package/dist/ai/core/ChatProvider.d.ts +66 -0
  82. package/dist/ai/core/ChatProvider.js +848 -0
  83. package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
  84. package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
  85. package/dist/ai/core/chatReducer.d.ts +114 -0
  86. package/dist/ai/core/chatReducer.js +223 -0
  87. package/dist/ai/core/config.d.ts +47 -0
  88. package/dist/ai/core/config.js +45 -0
  89. package/dist/ai/core/events.d.ts +1 -0
  90. package/dist/ai/core/events.js +4 -0
  91. package/dist/ai/core/exportConversation.d.ts +4 -0
  92. package/dist/ai/core/exportConversation.js +42 -0
  93. package/dist/ai/core/greeting.d.ts +3 -0
  94. package/dist/ai/core/greeting.js +38 -0
  95. package/dist/ai/core/parts.d.ts +11 -0
  96. package/dist/ai/core/parts.js +84 -0
  97. package/dist/ai/core/useDragDrop.d.ts +14 -0
  98. package/dist/ai/core/useDragDrop.js +36 -0
  99. package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
  100. package/dist/ai/core/useKeyboardShortcuts.js +77 -0
  101. package/dist/ai/core/useSSEStream.d.ts +34 -0
  102. package/dist/ai/core/useSSEStream.js +98 -0
  103. package/dist/ai/index.d.ts +40 -0
  104. package/dist/ai/index.js +44 -0
  105. package/dist/ai/strings.d.ts +167 -0
  106. package/dist/ai/strings.js +175 -0
  107. package/dist/ai/types.d.ts +236 -0
  108. package/dist/ai/ui/Avatar.d.ts +8 -0
  109. package/dist/ai/ui/Avatar.js +35 -0
  110. package/dist/ai/ui/Dropdown.d.ts +31 -0
  111. package/dist/ai/ui/Dropdown.js +110 -0
  112. package/dist/ai/ui/Markdown.d.ts +8 -0
  113. package/dist/ai/ui/Markdown.js +79 -0
  114. package/dist/ai/ui/Notice.d.ts +21 -0
  115. package/dist/ai/ui/Notice.js +77 -0
  116. package/dist/ai/ui/buttons.d.ts +1 -0
  117. package/dist/ai/ui/codeBreaks.d.ts +16 -0
  118. package/dist/ai/ui/codeBreaks.js +36 -0
  119. package/dist/ai/ui/prose.d.ts +1 -0
  120. package/dist/ai/ui/prose.js +13 -0
  121. package/dist/ai/ui/sidebar.d.ts +81 -0
  122. package/dist/ai/ui/sidebar.js +148 -0
  123. package/dist/ai/utils.d.ts +4 -0
  124. package/dist/ai/utils.js +23 -0
  125. package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
  126. package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
  127. package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
  128. package/dist/components/AddMenu.js +46 -0
  129. package/dist/components/Avatar.d.ts +1 -1
  130. package/dist/components/Avatar.js +46 -0
  131. package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
  132. package/dist/components/Breadcrumbs.d.ts +1 -1
  133. package/dist/components/Breadcrumbs.js +83 -0
  134. package/dist/components/Button.js +83 -0
  135. package/dist/components/Callout.js +23 -0
  136. package/dist/components/Card.js +31 -0
  137. package/dist/components/CollapsiblePanel.js +77 -0
  138. package/dist/components/ConfirmModal.js +74 -0
  139. package/dist/components/CopyToClipboard.js +81 -0
  140. package/dist/{chunks/CreateModal-BY6DLmur.js → components/CreateModal.js} +10 -189
  141. package/dist/components/DescriptionList.js +42 -0
  142. package/dist/components/Dropdown.d.ts +1 -1
  143. package/dist/components/Dropdown.js +349 -0
  144. package/dist/components/EmptyState.d.ts +1 -1
  145. package/dist/components/EmptyState.js +27 -0
  146. package/dist/components/Filter.js +32 -0
  147. package/dist/components/FilterPill.js +13 -0
  148. package/dist/components/IconButton.js +34 -0
  149. package/dist/components/Indicator.d.ts +2 -2
  150. package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
  151. package/dist/components/Input.d.ts +1 -1
  152. package/dist/components/Input.js +88 -0
  153. package/dist/components/LetterBadge.d.ts +1 -1
  154. package/dist/components/LetterBadge.js +13 -0
  155. package/dist/components/Listbox.js +123 -0
  156. package/dist/{chunks/Loader-BXoXTZGc.js → components/Loader.js} +1 -1
  157. package/dist/components/Markdown.js +15 -0
  158. package/dist/components/MarkdownImpl.d.ts +1 -1
  159. package/dist/components/MultiSelect.js +171 -0
  160. package/dist/components/Overview.js +39 -0
  161. package/dist/components/PageHeader.js +194 -0
  162. package/dist/components/Pagination.js +35 -0
  163. package/dist/components/Provider.d.ts +16 -65
  164. package/dist/{chunks/Provider-Ghua9PkN.js → components/Provider.js} +54 -20
  165. package/dist/{chunks/RequiredMark-DfLdYbYZ.js → components/RequiredMark.js} +1 -1
  166. package/dist/components/SectionHeader.js +11 -0
  167. package/dist/components/SettingModeOption.js +30 -0
  168. package/dist/components/SettingRow.d.ts +1 -1
  169. package/dist/components/SettingRow.js +35 -0
  170. package/dist/components/SettingsCard.js +31 -0
  171. package/dist/components/SettingsGroup.d.ts +1 -1
  172. package/dist/components/SettingsGroup.js +17 -0
  173. package/dist/components/Sort.js +42 -0
  174. package/dist/components/StatusBadge.js +63 -0
  175. package/dist/components/SwitchToggle.js +59 -0
  176. package/dist/{chunks/SwitchToggleSmall-FcsaYSTs.js → components/SwitchToggleSmall.js} +1 -1
  177. package/dist/{chunks/Table-4OHjdKdO.js → components/Table.js} +7 -5
  178. package/dist/components/Toggle.js +20 -0
  179. package/dist/{chunks/Tooltip-Crxo_eU_.js → components/Tooltip.js} +6 -4
  180. package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
  181. package/dist/components/focus.d.ts +2 -0
  182. package/dist/components/focus.js +7 -0
  183. package/dist/components/ghostButton.js +7 -0
  184. package/dist/components/inputClasses.js +4 -0
  185. package/dist/components/keys.d.ts +12 -0
  186. package/dist/components/keys.js +27 -0
  187. package/dist/components/relativeTime.js +32 -0
  188. package/dist/{chunks/useCssIsDark-DHr05dG2.js → components/useCssIsDark.js} +1 -1
  189. package/dist/duration.d.ts +3 -0
  190. package/dist/duration.js +17 -0
  191. package/dist/editor/Editor.js +13 -0
  192. package/dist/editor/EditorField.js +53 -0
  193. package/dist/editor/FormCodePanel.js +173 -0
  194. package/dist/editor/Monaco.d.ts +1 -20
  195. package/dist/editor/Monaco.js +112 -0
  196. package/dist/editor/index.d.ts +2 -1
  197. package/dist/editor/index.js +7 -2
  198. package/dist/editor/themes.js +91 -0
  199. package/dist/editor/workers.js +29 -0
  200. package/dist/editor/yaml.d.ts +5 -0
  201. package/dist/editor/yaml.js +15 -0
  202. package/dist/engine.d.ts +98 -0
  203. package/dist/file-explorer/FileExplorer.d.ts +11 -2
  204. package/dist/file-explorer/FileExplorer.js +1402 -0
  205. package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
  206. package/dist/file-explorer/FileExplorerContext.js +370 -0
  207. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
  208. package/dist/{chunks/CodePreviewEditor-4lx3kE-w.js → file-explorer/FilePreview/CodePreviewEditor.js} +3 -2
  209. package/dist/file-explorer/FilePreview/Inline.js +45 -0
  210. package/dist/file-explorer/FilePreview/StreamedBadge.js +16 -0
  211. package/dist/file-explorer/FilePreview/Viewer.js +526 -0
  212. package/dist/file-explorer/FilePreview/index.js +266 -0
  213. package/dist/file-explorer/FilePreview/parse.js +63 -0
  214. package/dist/file-explorer/FilePreview/previewCache.js +98 -0
  215. package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
  216. package/dist/file-explorer/FilePreview/previewType.js +151 -0
  217. package/dist/file-explorer/FilePreview/readCappedBytes.js +196 -0
  218. package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +95 -0
  219. package/dist/file-explorer/FilePreview/useObjectText.js +109 -0
  220. package/dist/file-explorer/FilePreview/usePresignedUrl.js +73 -0
  221. package/dist/file-explorer/FileRow.d.ts +1 -1
  222. package/dist/file-explorer/FileRow.js +165 -0
  223. package/dist/file-explorer/FileRowsWindow.js +92 -0
  224. package/dist/file-explorer/FileTable.js +172 -0
  225. package/dist/file-explorer/FileTableHeaders.js +49 -0
  226. package/dist/file-explorer/LoadMoreRow.js +46 -0
  227. package/dist/file-explorer/TreeView.js +376 -0
  228. package/dist/file-explorer/helpers.d.ts +4 -4
  229. package/dist/file-explorer/helpers.js +537 -0
  230. package/dist/file-explorer/index.d.ts +3 -3
  231. package/dist/file-explorer/index.js +7 -5705
  232. package/dist/file-explorer/lib/batch.js +39 -0
  233. package/dist/file-explorer/lib/errors.js +9 -0
  234. package/dist/file-explorer/lib/paging.js +124 -0
  235. package/dist/file-explorer/lib/types.d.ts +6 -1
  236. package/dist/file-explorer/lib/utils.d.ts +1 -3
  237. package/dist/file-explorer/lib/utils.js +322 -0
  238. package/dist/file-explorer/toasts.js +400 -0
  239. package/dist/file-explorer/treeRows.js +73 -0
  240. package/dist/file-explorer/useNearEnd.d.ts +1 -1
  241. package/dist/file-explorer/useNearEnd.js +27 -0
  242. package/dist/form/FieldWrapper.d.ts +2 -2
  243. package/dist/form/FieldWrapper.js +54 -0
  244. package/dist/form/Fields/BooleanField.js +51 -0
  245. package/dist/form/Fields/CheckboxGroupField.js +72 -0
  246. package/dist/form/Fields/ColorField.js +33 -0
  247. package/dist/form/Fields/DropdownField.js +49 -0
  248. package/dist/form/Fields/DurationField.js +130 -0
  249. package/dist/form/Fields/LabelField.js +19 -0
  250. package/dist/form/Fields/MultiDropdownField.js +40 -0
  251. package/dist/form/Fields/NumberField.js +51 -0
  252. package/dist/form/Fields/ObjectField.js +54 -0
  253. package/dist/form/Fields/RadioField.js +49 -0
  254. package/dist/form/Fields/RangeField.js +58 -0
  255. package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
  256. package/dist/form/Fields/ResourceOptionIcon.js +21 -0
  257. package/dist/form/Fields/StepField.js +6 -0
  258. package/dist/form/Fields/StringField.js +37 -0
  259. package/dist/form/Fields/TextAreaField.js +31 -0
  260. package/dist/form/Fields/durationValidity.js +11 -0
  261. package/dist/form/Form.d.ts +4 -21
  262. package/dist/form/Form.js +643 -0
  263. package/dist/form/SpecialTypes/DropdownWrapper.js +30 -0
  264. package/dist/form/SpecialTypes/FormikCustomDropdown.js +122 -0
  265. package/dist/form/SpecialTypes/FormikCustomInput.js +111 -0
  266. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +31 -0
  267. package/dist/form/SpecialTypes/FormikNumericInput.js +60 -0
  268. package/dist/form/Wizard/WizardContainer.js +138 -0
  269. package/dist/form/Wizard/WizardNavigation.js +92 -0
  270. package/dist/form/Wizard/WizardStepContent.js +35 -0
  271. package/dist/form/Wizard/WizardStepIndicator.js +108 -0
  272. package/dist/form/Wizard/useWizardState.js +118 -0
  273. package/dist/form/Wizard/utils.js +34 -0
  274. package/dist/form/fieldContext.js +26 -0
  275. package/dist/form/fieldRegistry.js +50 -0
  276. package/dist/form/index.d.ts +11 -12
  277. package/dist/form/index.js +18 -2445
  278. package/dist/form/lib.d.ts +6 -1
  279. package/dist/{chunks/FieldWrapper-Bef01EWO.js → form/lib.js} +5 -104
  280. package/dist/form/types/fieldComponentTypes.d.ts +3 -2
  281. package/dist/form/types/fieldTypes.d.ts +6 -20
  282. package/dist/form/useParsedOpts.d.ts +1 -1
  283. package/dist/form/useParsedOpts.js +62 -0
  284. package/dist/form/usePrevious.js +11 -0
  285. package/dist/form/utils/checkShowIfObject.js +14 -0
  286. package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
  287. package/dist/form/utils/duration.js +69 -0
  288. package/dist/form/utils/getParentValue.js +23 -0
  289. package/dist/form/utils/getPlaceholder.js +9 -0
  290. package/dist/form/utils/getValueUsingPath.js +23 -0
  291. package/dist/form/utils/secondaryField.js +22 -0
  292. package/dist/graph/AnnotationBanner.js +141 -0
  293. package/dist/graph/Collapse.js +41 -0
  294. package/dist/{workflow/index.js → graph/DependencyGraph.js} +76 -1163
  295. package/dist/graph/JobSummary.js +104 -0
  296. package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
  297. package/dist/graph/MatrixGroup.js +107 -0
  298. package/dist/graph/Reveal.js +57 -0
  299. package/dist/graph/TreeView.js +711 -0
  300. package/dist/{workflow → graph}/index.d.ts +1 -1
  301. package/dist/graph/index.js +2 -0
  302. package/dist/{workflow → graph}/types.d.ts +3 -3
  303. package/dist/graph/types.js +6 -0
  304. package/dist/icons.d.ts +20 -21
  305. package/dist/index.d.ts +38 -40
  306. package/dist/index.js +47 -599
  307. package/dist/list/ActionToolbar.js +184 -0
  308. package/dist/list/HoverCard.js +73 -0
  309. package/dist/list/ListPage.js +145 -0
  310. package/dist/list/ListPager.js +59 -0
  311. package/dist/list/ListTable.d.ts +1 -1
  312. package/dist/list/ListTable.js +163 -0
  313. package/dist/list/ListViewControls.d.ts +2 -2
  314. package/dist/list/ListViewControls.js +372 -0
  315. package/dist/list/RowContextMenu.js +350 -0
  316. package/dist/list/UserHoverCard.js +117 -0
  317. package/dist/list/index.d.ts +9 -9
  318. package/dist/list/index.js +11 -2
  319. package/dist/list/listSearch.js +137 -0
  320. package/dist/list/listView.js +210 -0
  321. package/dist/list/textEntry.js +10 -0
  322. package/dist/logviewer/LogViewer.d.ts +1 -1
  323. package/dist/logviewer/LogViewer.js +750 -0
  324. package/dist/logviewer/index.d.ts +1 -0
  325. package/dist/logviewer/index.js +3 -742
  326. package/dist/logviewer/segments.d.ts +9 -0
  327. package/dist/logviewer/segments.js +80 -0
  328. package/dist/styles/fonts.css +4 -4
  329. package/dist/styles/theme.css +6 -4
  330. package/dist/styles.css +1 -1
  331. package/dist/theme/index.js +2 -2
  332. package/package.json +38 -14
  333. package/LICENSE +0 -202
  334. package/dist/chunks/Monaco-C1POOdVv.js +0 -1046
  335. package/dist/chunks/PageHeader-l49p1nM9.js +0 -690
  336. package/dist/chunks/SwitchToggle-CHPP8uZQ.js +0 -755
  337. package/dist/chunks/editor-9_uVtUyy.js +0 -347
  338. package/dist/chunks/list-qrojZZNv.js +0 -1411
  339. package/dist/editor/usesGitlab.d.ts +0 -97
  340. package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
  341. package/dist/form/types/workflow-schema.d.ts +0 -1145
  342. package/dist/form/utils/pwResolver.d.ts +0 -18
  343. package/dist/{chunks/MarkdownImpl-Bq4QhrtA.js → components/MarkdownImpl.js} +1 -1
  344. /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
  345. /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
  346. /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
  347. /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
  348. /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
  349. /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
@@ -0,0 +1,376 @@
1
+ import { useStrings } from "../components/Provider.js";
2
+ import { AngleRightIcon, FolderIcon, FolderOpenIcon } from "../icons.js";
3
+ import { positionKeys } from "../components/keys.js";
4
+ import { getParentPath } from "./lib/utils.js";
5
+ import { canPreview } from "./FilePreview/previewType.js";
6
+ import { getNodeIcon } from "./helpers.js";
7
+ import { findRowIndex, flattenTreeRows, nextFileLimit, stepRow } from "./treeRows.js";
8
+ import cx from "classnames";
9
+ import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
10
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
+ import Skeleton from "react-loading-skeleton";
12
+ import { useVirtualizer } from "@tanstack/react-virtual";
13
+ //#region src/file-explorer/TreeView.tsx
14
+ /** 9px margin + 12px padding, per level. */
15
+ var INDENT_PER_LEVEL = 21;
16
+ var GUIDE_OFFSET = 9;
17
+ var ROW_PAD_DIRECTORY = 8;
18
+ var ROW_PAD_FILE = 28;
19
+ function rowHeight(row) {
20
+ return row.kind === "skeleton" ? 64 : 30;
21
+ }
22
+ /** The sidebar tree, flattened and windowed. The flat array is the single source
23
+ * of truth for rendering, arrow keys and ARIA. */
24
+ function TreeView({ rootNodes, parentToChildrenMap, expandedPaths, selectedPath, loadingPaths, onToggleExpand, onSelect, onDropToFolder, onContextMenu, onPreviewFile, paging }) {
25
+ const [scrollEl, setScrollEl] = useState(null);
26
+ const [fileLimits, setFileLimits] = useState(() => /* @__PURE__ */ new Map());
27
+ const incompletePaths = paging?.incompletePaths;
28
+ const rows = useMemo(() => flattenTreeRows(rootNodes, parentToChildrenMap, expandedPaths, {
29
+ loadingPaths,
30
+ ...incompletePaths && { incompletePaths },
31
+ fileLimits
32
+ }), [
33
+ rootNodes,
34
+ parentToChildrenMap,
35
+ expandedPaths,
36
+ loadingPaths,
37
+ incompletePaths,
38
+ fileLimits
39
+ ]);
40
+ const revealMore = useCallback((row) => {
41
+ const path = row.node.path;
42
+ if ((row.hiddenFiles ?? 0) > 0) {
43
+ setFileLimits((prev) => new Map(prev).set(path, nextFileLimit(prev.get(path))));
44
+ return;
45
+ }
46
+ paging?.onLoadMore(row.node);
47
+ }, [paging]);
48
+ const offsets = useMemo(() => {
49
+ const out = new Array(rows.length);
50
+ let running = 0;
51
+ rows.forEach((row, i) => {
52
+ out[i] = running;
53
+ running += rowHeight(row);
54
+ });
55
+ return out;
56
+ }, [rows]);
57
+ const cursorRef = useRef(null);
58
+ const wantsFocusRef = useRef(false);
59
+ const pendingNavRef = useRef(/* @__PURE__ */ new Set());
60
+ useEffect(() => {
61
+ if (pendingNavRef.current.delete(selectedPath)) return;
62
+ cursorRef.current = selectedPath;
63
+ }, [selectedPath]);
64
+ const getRowKey = useCallback((index) => rows[index]?.key ?? index, [rows]);
65
+ const virtualizer = useVirtualizer({
66
+ count: rows.length,
67
+ getScrollElement: () => scrollEl,
68
+ estimateSize: (index) => {
69
+ const row = rows[index];
70
+ return row ? rowHeight(row) : 30;
71
+ },
72
+ getItemKey: getRowKey,
73
+ overscan: 10
74
+ });
75
+ const move = useCallback((from, direction) => {
76
+ const cursorIndex = findRowIndex(rows, cursorRef.current ?? "");
77
+ const index = cursorIndex >= 0 ? cursorIndex : findRowIndex(rows, from.path);
78
+ if (index === -1) return;
79
+ const target = stepRow(rows, index, direction);
80
+ if (!target) return;
81
+ cursorRef.current = target.node.path;
82
+ pendingNavRef.current.add(target.node.path);
83
+ virtualizer.scrollToIndex(findRowIndex(rows, target.node.path));
84
+ wantsFocusRef.current = true;
85
+ onSelect(target.node.path, target.node);
86
+ }, [
87
+ rows,
88
+ virtualizer,
89
+ onSelect
90
+ ]);
91
+ useEffect(() => {
92
+ if (!wantsFocusRef.current) return;
93
+ const index = findRowIndex(rows, cursorRef.current ?? "");
94
+ const row = index < 0 ? null : scrollEl?.querySelector(`[data-index="${index}"] [role="treeitem"]`);
95
+ if (row instanceof HTMLElement) {
96
+ wantsFocusRef.current = false;
97
+ row.focus();
98
+ return;
99
+ }
100
+ if (selectedPath === cursorRef.current) wantsFocusRef.current = false;
101
+ }, [
102
+ selectedPath,
103
+ rows,
104
+ scrollEl
105
+ ]);
106
+ const handleKeyDown = useCallback((e, node) => {
107
+ if (e.key === " " && node.type === "file" && canPreview(node)) {
108
+ e.preventDefault();
109
+ onPreviewFile(node);
110
+ return;
111
+ }
112
+ if (e.key === "ArrowDown") {
113
+ e.preventDefault();
114
+ move(node, 1);
115
+ } else if (e.key === "ArrowUp") {
116
+ e.preventDefault();
117
+ move(node, -1);
118
+ }
119
+ }, [move, onPreviewFile]);
120
+ const items = virtualizer.getVirtualItems();
121
+ useTreePitchAudit(scrollEl, rows, items);
122
+ const renderRow = (index, top, height) => {
123
+ const row = rows[index];
124
+ if (!row) return null;
125
+ return /* @__PURE__ */ jsx("div", {
126
+ "data-index": index,
127
+ className: "absolute inset-x-0",
128
+ style: {
129
+ top,
130
+ height
131
+ },
132
+ children: row.kind === "skeleton" ? /* @__PURE__ */ jsx(TreeSkeletonRow, { depth: row.depth }) : row.kind === "more" ? /* @__PURE__ */ jsx(TreeMoreRow, {
133
+ depth: row.depth,
134
+ hiddenFiles: row.hiddenFiles ?? 0,
135
+ partial: incompletePaths?.has(row.node.path) ?? false,
136
+ loading: paging?.isLoading(row.node.path) ?? false,
137
+ failed: paging?.hasFailed(row.node.path) ?? false,
138
+ onReveal: () => revealMore(row)
139
+ }) : /* @__PURE__ */ jsx(TreeRowItem, {
140
+ row,
141
+ isSelected: row.node.path === selectedPath,
142
+ onToggleExpand,
143
+ onSelect,
144
+ onDropToFolder,
145
+ onContextMenu,
146
+ onKeyDown: handleKeyDown
147
+ })
148
+ }, row.key);
149
+ };
150
+ const cursorIndex = findRowIndex(rows, cursorRef.current ?? selectedPath);
151
+ const cursorOutsideWindow = cursorIndex >= 0 && !items.some((item) => item.index === cursorIndex);
152
+ const slots = items.map((item) => ({
153
+ index: item.index,
154
+ top: item.start,
155
+ height: item.size
156
+ }));
157
+ if (cursorOutsideWindow) {
158
+ slots.push({
159
+ index: cursorIndex,
160
+ top: offsets[cursorIndex] ?? 0,
161
+ height: rowHeight(rows[cursorIndex])
162
+ });
163
+ slots.sort((a, b) => a.index - b.index);
164
+ }
165
+ return /* @__PURE__ */ jsx("div", {
166
+ ref: setScrollEl,
167
+ className: "overflow-auto flex-1 px-2 py-2",
168
+ role: "tree",
169
+ onDragOver: (e) => e.preventDefault(),
170
+ onDrop: (e) => e.preventDefault(),
171
+ children: /* @__PURE__ */ jsx("div", {
172
+ className: "relative w-full",
173
+ style: { height: virtualizer.getTotalSize() },
174
+ children: slots.map((slot) => renderRow(slot.index, slot.top, slot.height))
175
+ })
176
+ });
177
+ }
178
+ function indentStyle(depth, isDirectory) {
179
+ return { paddingLeft: depth * INDENT_PER_LEVEL + (isDirectory ? ROW_PAD_DIRECTORY : ROW_PAD_FILE) };
180
+ }
181
+ function IndentGuides({ depth }) {
182
+ if (depth === 0) return null;
183
+ return /* @__PURE__ */ jsx(Fragment$1, { children: positionKeys(depth, "indent").map((key, level) => /* @__PURE__ */ jsx("span", {
184
+ "aria-hidden": "true",
185
+ className: "pointer-events-none absolute inset-y-0 w-px bg-(--theme-border)/60",
186
+ style: { left: GUIDE_OFFSET + level * INDENT_PER_LEVEL }
187
+ }, key)) });
188
+ }
189
+ function RowIcons({ isDirectory, isExpanded, customIcon }) {
190
+ if (!isDirectory) return /* @__PURE__ */ jsx("div", {
191
+ className: "shrink-0",
192
+ children: customIcon
193
+ });
194
+ const folder = isExpanded ? /* @__PURE__ */ jsx(FolderOpenIcon, { className: "h-4 w-4 mr-1 text-sky-500" }) : /* @__PURE__ */ jsx(FolderIcon, { className: "h-4 w-4 mr-1 text-sky-500/80" });
195
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(AngleRightIcon, { className: cx("h-3.5 w-3.5 shrink-0 theme-muted-text transition-transform duration-150", isExpanded && "rotate-90") }), customIcon ?? folder] });
196
+ }
197
+ /** Sized by the slot, not by its contents: react-loading-skeleton wraps each bar
198
+ * in an inline span, so a bar occupies a line box taller than its `height` and
199
+ * the overflow would sit on top of the absolutely positioned row below. */
200
+ /** Click-only, unlike the table's sentinel: the tree is a navigation aid, and
201
+ * growing it automatically as the user scrolls is what the cap exists to prevent. */
202
+ function TreeMoreRow({ depth, hiddenFiles, partial, loading, failed, onReveal }) {
203
+ const t = useStrings().fileExplorer;
204
+ const label = () => {
205
+ if (failed) return t.retry;
206
+ if (hiddenFiles === 0) return t.loadMore;
207
+ return partial ? t.treeMoreCountPartial(hiddenFiles) : t.treeMoreCount(hiddenFiles);
208
+ };
209
+ return /* @__PURE__ */ jsxs("div", {
210
+ className: "relative h-full overflow-hidden",
211
+ children: [/* @__PURE__ */ jsx(IndentGuides, { depth }), /* @__PURE__ */ jsx("div", {
212
+ className: "flex h-full items-center pr-2 text-xs theme-muted-text",
213
+ style: { paddingLeft: depth * INDENT_PER_LEVEL + ROW_PAD_FILE },
214
+ children: loading ? /* @__PURE__ */ jsx("span", { children: t.loadingMore }) : /* @__PURE__ */ jsx("button", {
215
+ type: "button",
216
+ className: cx("cursor-pointer underline", failed ? "text-red-500" : "theme-link"),
217
+ onClick: onReveal,
218
+ children: label()
219
+ })
220
+ })]
221
+ });
222
+ }
223
+ function TreeSkeletonRow({ depth }) {
224
+ return /* @__PURE__ */ jsxs("div", {
225
+ className: "relative h-full overflow-hidden",
226
+ children: [/* @__PURE__ */ jsx(IndentGuides, { depth }), /* @__PURE__ */ jsx("div", {
227
+ className: "flex h-full flex-col justify-center gap-1.5 py-1 pr-2",
228
+ style: { paddingLeft: depth * INDENT_PER_LEVEL + ROW_PAD_FILE },
229
+ children: [
230
+ 0,
231
+ 1,
232
+ 2
233
+ ].map((i) => /* @__PURE__ */ jsx(Skeleton, {
234
+ height: 12,
235
+ containerClassName: "block leading-none"
236
+ }, i))
237
+ })]
238
+ });
239
+ }
240
+ /** Hovering a dragged file over a collapsed folder expands it after 400ms. */
241
+ function useSpringLoadedDrop({ node, dropPath, isDirectory, isExpanded, onToggleExpand, onDropToFolder }) {
242
+ const hoverCount = useRef(0);
243
+ const timer = useRef(null);
244
+ const [dragActive, setDragActive] = useState(false);
245
+ const clear = () => {
246
+ if (timer.current) {
247
+ clearTimeout(timer.current);
248
+ timer.current = null;
249
+ }
250
+ };
251
+ useEffect(() => () => {
252
+ if (timer.current) {
253
+ clearTimeout(timer.current);
254
+ timer.current = null;
255
+ }
256
+ }, []);
257
+ return {
258
+ dragActive,
259
+ dragHandlers: {
260
+ onDragEnter: (e) => {
261
+ e.preventDefault();
262
+ e.stopPropagation();
263
+ hoverCount.current += 1;
264
+ setDragActive(true);
265
+ if (isDirectory && !isExpanded && !timer.current) timer.current = setTimeout(() => {
266
+ onToggleExpand(node.path);
267
+ timer.current = null;
268
+ }, 400);
269
+ },
270
+ onDragOver: (e) => e.preventDefault(),
271
+ onDragLeave: (e) => {
272
+ e.preventDefault();
273
+ e.stopPropagation();
274
+ hoverCount.current -= 1;
275
+ if (hoverCount.current > 0) return;
276
+ setDragActive(false);
277
+ clear();
278
+ },
279
+ onDrop: (e) => {
280
+ e.stopPropagation();
281
+ e.preventDefault();
282
+ hoverCount.current = 0;
283
+ setDragActive(false);
284
+ clear();
285
+ onDropToFolder(dropPath, e.dataTransfer.items.length ? e.dataTransfer.items : e.dataTransfer.files);
286
+ }
287
+ }
288
+ };
289
+ }
290
+ /** Keys a row handles itself; the arrows that move between rows delegate upward,
291
+ * where the flat array is. The set is deliberately narrow:
292
+ * no Home/End, no typeahead, and ArrowLeft/Right only toggle a directory. */
293
+ function dispatchRowKey(e, { node, isDirectory, isExpanded, onSelect, onToggleExpand, onDelegate }) {
294
+ if (e.key === "Enter") {
295
+ e.preventDefault();
296
+ onSelect(e);
297
+ return;
298
+ }
299
+ if (e.key === " ") {
300
+ e.preventDefault();
301
+ if (!isDirectory && canPreview(node)) onDelegate(e, node);
302
+ else onSelect(e);
303
+ return;
304
+ }
305
+ if (e.key === "ArrowRight" && isDirectory && !isExpanded || e.key === "ArrowLeft" && isDirectory && isExpanded) {
306
+ e.preventDefault();
307
+ onToggleExpand(node.path);
308
+ return;
309
+ }
310
+ onDelegate(e, node);
311
+ }
312
+ var TreeRowItem = memo(function TreeRowItem({ row, isSelected, onToggleExpand, onSelect, onDropToFolder, onContextMenu, onKeyDown }) {
313
+ const { node, depth, isExpanded } = row;
314
+ const isDirectory = node.type === "directory";
315
+ const isStorageNode = !!node.displayName && node.storageId;
316
+ const { dragActive, dragHandlers } = useSpringLoadedDrop({
317
+ node,
318
+ dropPath: isDirectory ? node.path : getParentPath(node.path),
319
+ isDirectory,
320
+ isExpanded,
321
+ onToggleExpand,
322
+ onDropToFolder
323
+ });
324
+ const handleSelect = (e) => {
325
+ if (e.type === "click") e.preventDefault();
326
+ onSelect(node.path, node);
327
+ if (isDirectory) onToggleExpand(node.path);
328
+ };
329
+ const handleKeyDown = (e) => dispatchRowKey(e, {
330
+ node,
331
+ isDirectory,
332
+ isExpanded,
333
+ onSelect: handleSelect,
334
+ onToggleExpand,
335
+ onDelegate: onKeyDown
336
+ });
337
+ const customIcon = getNodeIcon(node);
338
+ const label = isDirectory && isStorageNode && node.displayName ? node.displayName : node.name;
339
+ return /* @__PURE__ */ jsxs("div", {
340
+ className: cx("relative h-full rounded-md transition-[box-shadow,background-color] duration-150", dragActive && "ring-1 ring-(--theme-link)/60"),
341
+ ...dragHandlers,
342
+ children: [/* @__PURE__ */ jsx(IndentGuides, { depth }), /* @__PURE__ */ jsxs("div", {
343
+ 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"),
344
+ style: indentStyle(depth, isDirectory),
345
+ onClick: handleSelect,
346
+ onKeyDown: handleKeyDown,
347
+ onContextMenu: (e) => onContextMenu(e, node),
348
+ role: "treeitem",
349
+ "aria-level": depth + 1,
350
+ "aria-posinset": row.posInSet,
351
+ "aria-setsize": row.setSize,
352
+ "aria-selected": isSelected,
353
+ ...isDirectory && { "aria-expanded": isExpanded },
354
+ tabIndex: isSelected ? 0 : -1,
355
+ children: [/* @__PURE__ */ jsx(RowIcons, {
356
+ isDirectory,
357
+ isExpanded,
358
+ customIcon
359
+ }), /* @__PURE__ */ jsx("span", {
360
+ className: "text-sm truncate",
361
+ children: label
362
+ })]
363
+ })]
364
+ });
365
+ });
366
+ /** The height constants must equal the rendered pitch, or the scrollbar
367
+ * drifts from the content. Reports the measured value to use. */
368
+ function useTreePitchAudit(scrollEl, rows, items) {
369
+ useEffect(() => {}, [
370
+ scrollEl,
371
+ rows,
372
+ items
373
+ ]);
374
+ }
375
+ //#endregion
376
+ export { TreeView };
@@ -1,5 +1,5 @@
1
- import type { TreeNode, TStorage, UploadNode } from './lib/types.js';
2
1
  import { type JSX } from 'react';
2
+ import type { TreeNode, TStorage, UploadNode } from './lib/types.js';
3
3
  declare const SIDEBAR_WIDTH_STORAGE_KEY = "fileExplorerSidebarWidth";
4
4
  declare const SIDEBAR_WIDTH_DEFAULT = 300;
5
5
  type StorageIconUrlResolver = (args: {
@@ -9,7 +9,7 @@ declare function getNodeIcon(node: TreeNode, storageIconUrl?: StorageIconUrlReso
9
9
  declare function renderUploadNodes(uploadNodes: UploadNode[]): JSX.Element[];
10
10
  declare function NoFileSelectedPreview(): JSX.Element;
11
11
  /** Shown instead of a skeleton that has nothing left to wait for. */
12
- declare function NotFoundPreview({ path, onRetry, }: {
12
+ declare function NotFoundPreview({ path, onRetry }: {
13
13
  path: string;
14
14
  onRetry: () => void;
15
15
  }): JSX.Element;
@@ -36,10 +36,10 @@ interface IDragDropZoneProps {
36
36
  children: React.ReactNode;
37
37
  className?: string;
38
38
  }
39
- declare function DragDropZone({ onDropFiles, children, className, }: IDragDropZoneProps): JSX.Element;
39
+ declare function DragDropZone({ onDropFiles, children, className }: IDragDropZoneProps): JSX.Element;
40
40
  interface IShareFileButtonProps {
41
41
  node: TreeNode;
42
42
  onShare: (node: TreeNode) => Promise<void>;
43
43
  }
44
44
  declare function ShareFileButton({ node, onShare }: IShareFileButtonProps): JSX.Element;
45
- export { CorsIssuePreview, DragDropZone, getNodeIcon, NoFileSelectedPreview, NoDataAvailablePreview, NotFoundPreview, renderUploadNodes, ShareFileButton, SIDEBAR_WIDTH_DEFAULT, SIDEBAR_WIDTH_STORAGE_KEY, SkeletonPreview, };
45
+ export { CorsIssuePreview, DragDropZone, getNodeIcon, NoDataAvailablePreview, NoFileSelectedPreview, NotFoundPreview, renderUploadNodes, ShareFileButton, SIDEBAR_WIDTH_DEFAULT, SIDEBAR_WIDTH_STORAGE_KEY, SkeletonPreview, };