@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
@@ -1,690 +0,0 @@
1
- import { i as useNotify, l as useSlots, n as useLink, u as useStrings } from "./Provider-Ghua9PkN.js";
2
- import { AddIcon, CheckIcon, ChevronRightIcon, ClipboardIcon, CopyIcon, EditIcon, IdCardIcon, KeyIcon, LinkIcon, MailIcon, MoreIcon, UserIcon } from "../icons.js";
3
- import { n as TOOLTIP_ID } from "./Tooltip-Crxo_eU_.js";
4
- import cx from "classnames";
5
- import React, { Fragment, createContext, useCallback, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
6
- import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
- import { createPortal } from "react-dom";
8
- import { Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
9
- //#region src/components/Avatar.tsx
10
- var SIZE_CLASSES = {
11
- sm: "w-6 h-6 text-xs",
12
- md: "w-8 h-8 text-sm",
13
- lg: "w-10 h-10 text-base",
14
- xl: "w-12 h-12 text-lg",
15
- "2xl": "w-16 h-16 text-xl"
16
- };
17
- var STATUS_CLASSES = {
18
- online: "bg-green-500",
19
- offline: "bg-(--theme-muted-text-color)",
20
- busy: "bg-red-500",
21
- away: "bg-yellow-500"
22
- };
23
- /** Up to two initials: the first and last word of a name split on spaces and dots. */
24
- function avatarInitials(name) {
25
- const parts = (name ?? "").split(/[\s.]+/).filter(Boolean);
26
- if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
27
- return parts[0]?.[0]?.toUpperCase() || "?";
28
- }
29
- function Avatar({ src, name, size = "md", status, className }) {
30
- const strings = useStrings();
31
- const [erroredUrl, setErroredUrl] = useState(null);
32
- const showImage = !!src && erroredUrl !== src;
33
- return /* @__PURE__ */ jsxs("div", {
34
- className: cx("relative inline-flex", className),
35
- children: [showImage ? /* @__PURE__ */ jsx("img", {
36
- src,
37
- alt: name || strings.common.userAvatar,
38
- onError: () => setErroredUrl(src),
39
- className: cx("rounded-full object-cover", SIZE_CLASSES[size])
40
- }) : /* @__PURE__ */ jsx("div", {
41
- className: cx("rounded-full flex items-center justify-center font-medium", "bg-gradient-to-br from-[var(--gradient-start,var(--theme-element))] to-[var(--gradient-mid,var(--theme-link))] text-white", SIZE_CLASSES[size]),
42
- children: avatarInitials(name)
43
- }), status && /* @__PURE__ */ jsx("span", {
44
- "data-testid": "online-indicator",
45
- className: cx("absolute bottom-0 right-0 block rounded-full ring-2 ring-(--theme-app-bg)", STATUS_CLASSES[status], size === "sm" ? "w-1.5 h-1.5" : "w-2.5 h-2.5")
46
- })]
47
- });
48
- }
49
- //#endregion
50
- //#region src/components/AddMenu.tsx
51
- var addMenuItemClasses = "flex w-full items-center gap-2 px-3 py-1.5 text-[13px] text-(--theme-app) data-[focus]:bg-(--theme-muted-panel-bg) cursor-pointer";
52
- function itemButtonProps(item) {
53
- if (!item.disabled) return { onClick: item.onSelect };
54
- return {
55
- "aria-disabled": true,
56
- ...item.hint ? {
57
- "aria-label": `${item.label}. ${item.hint}`,
58
- "data-tooltip-id": TOOLTIP_ID,
59
- "data-tooltip-content": item.hint
60
- } : {}
61
- };
62
- }
63
- function AddMenu({ items, label, buttonClassName, zClassName = "z-50", children }) {
64
- const Link = useLink();
65
- return /* @__PURE__ */ jsxs(Menu, { children: [/* @__PURE__ */ jsx(MenuButton, {
66
- "aria-label": label,
67
- title: label,
68
- className: buttonClassName,
69
- children
70
- }), /* @__PURE__ */ jsx(MenuItems, {
71
- anchor: "bottom start",
72
- className: cx("mt-1 min-w-52 rounded-lg border border-(--theme-border) bg-(--theme-app-bg) py-1 shadow-lg focus:outline-none", zClassName),
73
- children: items.map((item) => /* @__PURE__ */ jsxs(Fragment, { children: [item.separatorAbove && /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-(--theme-border)" }), /* @__PURE__ */ jsx(MenuItem, {
74
- disabled: item.disabled ?? false,
75
- children: item.to && !item.disabled ? /* @__PURE__ */ jsxs(Link, {
76
- to: item.to,
77
- className: addMenuItemClasses,
78
- children: [item.icon, item.label]
79
- }) : /* @__PURE__ */ jsxs("button", {
80
- type: "button",
81
- ...itemButtonProps(item),
82
- className: cx(addMenuItemClasses, item.disabled && "opacity-50 cursor-not-allowed"),
83
- children: [item.icon, item.label]
84
- })
85
- })] }, item.label))
86
- })] });
87
- }
88
- //#endregion
89
- //#region src/components/Breadcrumbs.tsx
90
- var BreadcrumbContext = createContext({
91
- breadcrumbs: [],
92
- setBreadcrumbs: () => {},
93
- rightsideBreadcrumb: null,
94
- setRightsideBreadcrumb: () => {},
95
- hidden: false,
96
- setHidden: () => {},
97
- titleActionSlot: null,
98
- setTitleActionSlot: () => {},
99
- rightActionSlot: null,
100
- setRightActionSlot: () => {},
101
- claimedPath: { current: null }
102
- });
103
- var useBreadcrumb = () => useContext(BreadcrumbContext);
104
- function BreadcrumbProvider({ children }) {
105
- const [breadcrumbs, setBreadcrumbs] = React.useState([]);
106
- const [rightsideBreadcrumb, setRightsideBreadcrumb] = React.useState(null);
107
- const [hidden, setHidden] = React.useState(false);
108
- const [titleActionSlot, setTitleActionSlot] = React.useState(null);
109
- const [rightActionSlot, setRightActionSlot] = React.useState(null);
110
- const claimedPath = React.useRef(null);
111
- return /* @__PURE__ */ jsx(BreadcrumbContext.Provider, {
112
- value: {
113
- breadcrumbs,
114
- setBreadcrumbs,
115
- rightsideBreadcrumb,
116
- setRightsideBreadcrumb,
117
- hidden,
118
- setHidden,
119
- titleActionSlot,
120
- setTitleActionSlot,
121
- rightActionSlot,
122
- setRightActionSlot,
123
- claimedPath
124
- },
125
- children
126
- });
127
- }
128
- function useSetBreadcrumbs(getBreadcrumbs) {
129
- const { setBreadcrumbs, claimedPath } = useBreadcrumb();
130
- useLayoutEffect(() => {
131
- claimedPath.current = window.location.pathname;
132
- setBreadcrumbs(typeof getBreadcrumbs === "function" ? getBreadcrumbs() : getBreadcrumbs);
133
- }, [
134
- getBreadcrumbs,
135
- setBreadcrumbs,
136
- claimedPath
137
- ]);
138
- }
139
- /**
140
- * For layout routes that derive breadcrumbs from the URL: applies them only
141
- * while no page under the layout has set its own for the current path.
142
- * Without this, a layout re-running its effect (for example when the
143
- * organization's display name loads) overwrote the page's breadcrumbs.
144
- */
145
- function useSetDefaultBreadcrumbs(getBreadcrumbs) {
146
- const { setBreadcrumbs, claimedPath } = useBreadcrumb();
147
- useLayoutEffect(() => {
148
- if (claimedPath.current === window.location.pathname) return;
149
- setBreadcrumbs(typeof getBreadcrumbs === "function" ? getBreadcrumbs() : getBreadcrumbs);
150
- }, [
151
- getBreadcrumbs,
152
- setBreadcrumbs,
153
- claimedPath
154
- ]);
155
- }
156
- var EMPTY_BREADCRUMBS = [];
157
- /** For pages that render their own header instead of the breadcrumb strip. */
158
- function useClearBreadcrumbs() {
159
- useSetBreadcrumbs(EMPTY_BREADCRUMBS);
160
- }
161
- function useHideBreadcrumbs(hidden) {
162
- const { setHidden } = useBreadcrumb();
163
- useEffect(() => {
164
- setHidden(hidden);
165
- return () => setHidden(false);
166
- }, [hidden, setHidden]);
167
- }
168
- //#endregion
169
- //#region src/list/RowContextMenu.tsx
170
- /** Converts a single row action to a menu item: a `to` makes it a link, otherwise an action. */
171
- function toRowMenuItem(action) {
172
- if (action.to) return {
173
- kind: "link",
174
- label: action.label,
175
- icon: action.icon,
176
- to: action.to,
177
- destructive: action.destructive
178
- };
179
- return {
180
- kind: "action",
181
- label: action.label,
182
- icon: action.icon,
183
- onSelect: action.onSelect ?? (() => {}),
184
- disabled: action.disabled,
185
- destructive: action.destructive,
186
- tooltip: action.tooltip
187
- };
188
- }
189
- /** Bridges a toolbar action (icon component, `onClick`/`href`) onto the shared
190
- * `RowAction` shape. Typed structurally so any toolbar action shape matching
191
- * these fields is assignable. */
192
- function toolbarActionToRowAction(action) {
193
- const Icon = action.icon;
194
- return {
195
- key: action.key,
196
- label: action.label,
197
- icon: /* @__PURE__ */ jsx(Icon, {}),
198
- onSelect: action.onClick,
199
- to: action.href,
200
- disabled: action.disabled,
201
- destructive: action.key === "delete" || action.key === "destroy",
202
- tooltip: action.disabledTooltip
203
- };
204
- }
205
- /** Assembles a row's context menu in the shared order: leading link(s) → middle
206
- * actions → extra items → Copy submenu → trailing (destructive) actions last. */
207
- function assembleRowMenu({ lead = [], actions, exclude, order, trailing = ["delete"], extra = [], copy }) {
208
- const trailingSet = new Set(trailing);
209
- const excludeSet = new Set(exclude);
210
- let middle = actions.filter((a) => !trailingSet.has(a.key) && !excludeSet.has(a.key));
211
- if (order) {
212
- const byKey = new Map(middle.map((a) => [a.key, a]));
213
- middle = order.map((key) => byKey.get(key)).filter((a) => a !== void 0);
214
- }
215
- const trailingItems = trailing.map((key) => actions.find((a) => a.key === key)).filter((a) => a !== void 0);
216
- return [
217
- ...lead,
218
- ...middle.map(toRowMenuItem),
219
- ...extra,
220
- ...copy ? [copy] : [],
221
- ...trailingItems.map(toRowMenuItem)
222
- ];
223
- }
224
- function useRowMenu(zClassName = "z-50") {
225
- const [menu, setMenu] = useState(null);
226
- const onCloseRef = useRef(void 0);
227
- return {
228
- openMenu: useCallback((x, y, items, onClose) => {
229
- if (items.length > 0) {
230
- onCloseRef.current?.();
231
- onCloseRef.current = onClose;
232
- setMenu({
233
- x,
234
- y,
235
- items
236
- });
237
- }
238
- }, []),
239
- contextMenu: /* @__PURE__ */ jsx(RowContextMenu, {
240
- state: menu,
241
- onClose: useCallback(() => {
242
- onCloseRef.current?.();
243
- onCloseRef.current = void 0;
244
- setMenu(null);
245
- }, []),
246
- zClassName
247
- })
248
- };
249
- }
250
- /** The full-screen menu overlay drops CSS :hover on the triggering row; wrap openMenu here to substitute a JS-driven `active` highlight. */
251
- function useRowMenuActive(openMenu) {
252
- const [active, setActive] = useState(false);
253
- return {
254
- active,
255
- openMenu: useCallback((x, y, items) => {
256
- setActive(true);
257
- openMenu(x, y, items, () => setActive(false));
258
- }, [openMenu])
259
- };
260
- }
261
- function rowContextMenuProps(openMenu, items) {
262
- return { onContextMenu: (e) => {
263
- e.preventDefault();
264
- if (items.length > 0) e.stopPropagation();
265
- openMenu(e.clientX, e.clientY, items);
266
- } };
267
- }
268
- function RowContextMenu({ state, onClose, zClassName }) {
269
- const ref = useRef(null);
270
- const [pos, setPos] = useState(null);
271
- useLayoutEffect(() => {
272
- if (!state || !ref.current) {
273
- setPos(null);
274
- return;
275
- }
276
- const { width, height } = ref.current.getBoundingClientRect();
277
- const pad = 8;
278
- const top = height > window.innerHeight - pad - state.y && state.y - height - pad >= 0 ? state.y - height : Math.min(state.y, window.innerHeight - height - pad);
279
- setPos({
280
- left: Math.max(pad, Math.min(state.x, window.innerWidth - width - pad)),
281
- top: Math.max(pad, top)
282
- });
283
- }, [state]);
284
- useEffect(() => {
285
- if (!state) return;
286
- const close = () => onClose();
287
- const onKey = (e) => {
288
- if (e.key === "Escape") onClose();
289
- };
290
- window.addEventListener("scroll", close, true);
291
- window.addEventListener("resize", close);
292
- window.addEventListener("keydown", onKey);
293
- return () => {
294
- window.removeEventListener("scroll", close, true);
295
- window.removeEventListener("resize", close);
296
- window.removeEventListener("keydown", onKey);
297
- };
298
- }, [state, onClose]);
299
- if (!state) return null;
300
- const side = (pos?.left ?? state.x) > window.innerWidth * .6 ? "left" : "right";
301
- return createPortal(/* @__PURE__ */ jsx("div", {
302
- role: "none",
303
- className: cx("fixed inset-0", zClassName),
304
- onClick: (e) => {
305
- if (e.target === e.currentTarget) onClose();
306
- },
307
- onContextMenu: (e) => {
308
- e.preventDefault();
309
- if (ref.current?.contains(e.target)) {
310
- onClose();
311
- return;
312
- }
313
- const { clientX, clientY } = e;
314
- const overlay = e.currentTarget;
315
- overlay.style.pointerEvents = "none";
316
- const under = document.elementFromPoint(clientX, clientY);
317
- overlay.style.pointerEvents = "";
318
- onClose();
319
- under?.dispatchEvent(new MouseEvent("contextmenu", {
320
- bubbles: true,
321
- cancelable: true,
322
- clientX,
323
- clientY
324
- }));
325
- },
326
- children: /* @__PURE__ */ jsx("div", {
327
- ref,
328
- role: "menu",
329
- className: "absolute min-w-44 rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) py-1 shadow-lg backdrop-blur-xl",
330
- style: {
331
- left: pos?.left ?? state.x,
332
- top: pos?.top ?? state.y,
333
- visibility: pos ? "visible" : "hidden"
334
- },
335
- children: /* @__PURE__ */ jsx(MenuItemList, {
336
- items: state.items,
337
- onClose,
338
- side
339
- })
340
- })
341
- }), document.body);
342
- }
343
- var MENU_ITEM_CLASSES = "flex w-full items-center gap-2.5 px-3 py-1.5 text-left text-[13px] hover:bg-(--theme-muted-panel-bg) transition-colors cursor-pointer [&>svg]:h-4 [&>svg]:w-4 [&>svg]:shrink-0";
344
- function MenuItemList({ items, onClose, side }) {
345
- return items.map((item, i) => item.kind === "divider" ? /* @__PURE__ */ jsx("div", {
346
- "aria-hidden": "true",
347
- className: "my-1 h-px bg-(--theme-border)"
348
- }, `divider-${i}`) : /* @__PURE__ */ jsx(MenuRow, {
349
- item,
350
- onClose,
351
- side
352
- }, `${item.label}-${i}`));
353
- }
354
- function MenuRow({ item, onClose, side }) {
355
- const Link = useLink();
356
- const notify = useNotify();
357
- const { list: t } = useStrings();
358
- const [openSub, setOpenSub] = useState(false);
359
- const closeTimer = useRef(void 0);
360
- if (item.kind === "submenu") {
361
- const open = () => {
362
- clearTimeout(closeTimer.current);
363
- setOpenSub(true);
364
- };
365
- const close = () => {
366
- closeTimer.current = setTimeout(() => setOpenSub(false), 160);
367
- };
368
- return /* @__PURE__ */ jsxs("div", {
369
- className: "relative",
370
- role: "none",
371
- onMouseEnter: open,
372
- onMouseLeave: close,
373
- onFocus: open,
374
- onBlur: close,
375
- children: [/* @__PURE__ */ jsxs("button", {
376
- type: "button",
377
- "aria-expanded": openSub,
378
- "aria-haspopup": "menu",
379
- onClick: open,
380
- className: cx(MENU_ITEM_CLASSES, "justify-between text-(--theme-app)"),
381
- children: [/* @__PURE__ */ jsxs("span", {
382
- className: "flex items-center gap-2.5",
383
- children: [item.icon, item.label]
384
- }), /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 shrink-0 opacity-60" })]
385
- }), openSub && /* @__PURE__ */ jsx("div", {
386
- className: cx("absolute -top-1 z-10 min-w-44 rounded-lg border border-(--theme-border) bg-(--theme-panel-bg) py-1 shadow-lg", side === "left" ? "right-full" : "left-full"),
387
- children: /* @__PURE__ */ jsx(MenuItemList, {
388
- items: item.items,
389
- onClose,
390
- side
391
- })
392
- })]
393
- });
394
- }
395
- if (item.kind === "link") {
396
- const className = cx(MENU_ITEM_CLASSES, item.destructive ? "text-red-500" : "text-(--theme-app)");
397
- if (item.reloadDocument) return /* @__PURE__ */ jsxs("a", {
398
- href: item.to,
399
- onClick: onClose,
400
- className,
401
- children: [item.icon, item.label]
402
- });
403
- return /* @__PURE__ */ jsxs(Link, {
404
- to: item.to,
405
- onClick: onClose,
406
- className,
407
- children: [item.icon, item.label]
408
- });
409
- }
410
- return /* @__PURE__ */ jsxs("button", {
411
- type: "button",
412
- disabled: item.disabled && !item.tooltip,
413
- "aria-disabled": item.disabled,
414
- ...item.disabled && item.tooltip ? {
415
- "data-tooltip-id": TOOLTIP_ID,
416
- "data-tooltip-content": item.tooltip
417
- } : {},
418
- onClick: () => {
419
- if (item.disabled) return;
420
- if (item.copy) {
421
- const { text, label } = item.copy;
422
- navigator.clipboard?.writeText(text).then(() => notify.success(t.copied(label)), () => notify.error(t.couldntCopy(label)));
423
- }
424
- item.onSelect?.();
425
- onClose();
426
- },
427
- className: cx(MENU_ITEM_CLASSES, item.destructive ? "text-red-500" : "text-(--theme-app)", item.disabled && "opacity-40 cursor-not-allowed hover:bg-transparent"),
428
- children: [
429
- item.icon,
430
- item.label,
431
- item.selected && /* @__PURE__ */ jsx(CheckIcon, { className: "ml-auto opacity-80" })
432
- ]
433
- });
434
- }
435
- /** Returns a builder for the Copy submenu, labeled from the provider's strings. */
436
- function useCopySubmenu() {
437
- const { list: t } = useStrings();
438
- return useCallback(({ name, nameLabel, email, username, uid, id, url, extra }) => {
439
- const items = [
440
- {
441
- label: nameLabel ?? t.labelName,
442
- value: name,
443
- icon: /* @__PURE__ */ jsx(CopyIcon, {})
444
- },
445
- {
446
- label: t.labelEmail,
447
- value: email,
448
- icon: /* @__PURE__ */ jsx(MailIcon, {})
449
- },
450
- {
451
- label: t.labelUsername,
452
- value: username,
453
- icon: /* @__PURE__ */ jsx(UserIcon, {})
454
- },
455
- {
456
- label: t.labelUid,
457
- value: uid === null || uid === void 0 ? null : String(uid),
458
- icon: /* @__PURE__ */ jsx(KeyIcon, {})
459
- },
460
- {
461
- label: t.labelId,
462
- value: id,
463
- icon: /* @__PURE__ */ jsx(IdCardIcon, {})
464
- },
465
- {
466
- label: t.labelUrl,
467
- value: url,
468
- icon: /* @__PURE__ */ jsx(LinkIcon, {})
469
- },
470
- ...(extra ?? []).map((e) => ({
471
- label: e.label,
472
- value: e.value,
473
- icon: e.icon ?? /* @__PURE__ */ jsx(CopyIcon, {})
474
- }))
475
- ].filter((f) => f.value).map((f) => ({
476
- kind: "action",
477
- label: t.copy(f.label),
478
- icon: f.icon,
479
- copy: {
480
- text: f.value,
481
- label: f.label
482
- }
483
- }));
484
- return {
485
- kind: "submenu",
486
- label: t.copyMenu,
487
- icon: /* @__PURE__ */ jsx(ClipboardIcon, {}),
488
- items
489
- };
490
- }, [t]);
491
- }
492
- /** Stays visible while active (menu open) so it doesn't vanish behind the overlay. */
493
- function MoreButton({ onOpen, active, className }) {
494
- const { list: t } = useStrings();
495
- return /* @__PURE__ */ jsx("button", {
496
- type: "button",
497
- "aria-label": t.moreActions,
498
- onClick: (e) => {
499
- e.stopPropagation();
500
- const r = e.currentTarget.getBoundingClientRect();
501
- onOpen(r.right, r.bottom);
502
- },
503
- className: cx("rounded p-1 cursor-pointer text-(--theme-muted-text-color) transition-colors hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) focus-visible:opacity-100", active ? "opacity-100" : "opacity-0 group-hover:opacity-100", className),
504
- children: /* @__PURE__ */ jsx(MoreIcon, { className: "h-4 w-4" })
505
- });
506
- }
507
- //#endregion
508
- //#region src/components/PageHeader.tsx
509
- var headerActionButtonClasses = "flex items-center justify-center w-6 h-6 rounded-md shrink-0 cursor-pointer text-(--theme-muted-text-color) hover:text-(--theme-app) hover:bg-(--theme-muted-panel-bg) transition-colors";
510
- var headerAddButtonClasses = "inline-flex h-[26px] shrink-0 items-center gap-1.5 rounded-md border border-(--theme-border) px-2 text-xs font-medium cursor-pointer text-(--theme-muted-text-color) hover:bg-(--theme-muted-panel-bg) hover:text-(--theme-app) transition-colors";
511
- /** With menu, the plus opens a chooser; otherwise navigates to or calls the
512
- * single action. `word` is the visible verb; `label` stays the full action for
513
- * the tooltip and screen readers. */
514
- function HeaderAddButton({ to, onClick, label, word = "add", menu, disabled = false, disabledHint }) {
515
- const { common } = useStrings();
516
- const Link = useLink();
517
- const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(AddIcon, { className: "w-3 h-3" }), /* @__PURE__ */ jsx("span", { children: word === "create" ? common.create : common.add })] });
518
- if (menu) return /* @__PURE__ */ jsx(AddMenu, {
519
- items: menu,
520
- label,
521
- buttonClassName: headerAddButtonClasses,
522
- children: content
523
- });
524
- if (to) return /* @__PURE__ */ jsx(Link, {
525
- to,
526
- "aria-label": label,
527
- title: label,
528
- className: headerAddButtonClasses,
529
- children: content
530
- });
531
- const hint = disabled ? disabledHint : void 0;
532
- return /* @__PURE__ */ jsx("button", {
533
- type: "button",
534
- onClick: disabled ? void 0 : onClick,
535
- "aria-label": hint ? `${label}. ${hint}` : label,
536
- "aria-disabled": disabled || void 0,
537
- ...hint ? {
538
- "data-tooltip-id": TOOLTIP_ID,
539
- "data-tooltip-content": hint
540
- } : { title: label },
541
- className: cx(headerAddButtonClasses, "aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-disabled:hover:bg-transparent aria-disabled:hover:text-(--theme-muted-text-color)"),
542
- children: content
543
- });
544
- }
545
- function HeaderActionMenu({ items, label = "Actions" }) {
546
- if (items.length === 0) return null;
547
- return /* @__PURE__ */ jsx(AddMenu, {
548
- items,
549
- label,
550
- buttonClassName: headerActionButtonClasses,
551
- children: /* @__PURE__ */ jsx(MoreIcon, { className: "w-3.5 h-3.5" })
552
- });
553
- }
554
- /** The header "…" trigger for a RowMenuItem menu — same rendering (submenus,
555
- * destructive styling) as the list pages' right-click context menus. */
556
- function HeaderRowMenu({ items, label = "Actions" }) {
557
- const { openMenu, contextMenu } = useRowMenu();
558
- if (items.length === 0) return null;
559
- return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("button", {
560
- type: "button",
561
- "aria-label": label,
562
- title: label,
563
- className: headerActionButtonClasses,
564
- onClick: (e) => {
565
- const r = e.currentTarget.getBoundingClientRect();
566
- openMenu(r.left, r.bottom + 4, items);
567
- },
568
- children: /* @__PURE__ */ jsx(MoreIcon, { className: "w-3.5 h-3.5" })
569
- }), contextMenu] });
570
- }
571
- function HeaderEditButton({ to, onClick, label = "Edit", disabled, tooltip }) {
572
- const Link = useLink();
573
- const tooltipProps = tooltip ? {
574
- "data-tooltip-id": TOOLTIP_ID,
575
- "data-tooltip-content": tooltip
576
- } : {};
577
- if (to && !disabled) return /* @__PURE__ */ jsx(Link, {
578
- to,
579
- "aria-label": label,
580
- ...tooltip ? {} : { title: label },
581
- className: headerActionButtonClasses,
582
- ...tooltipProps,
583
- children: /* @__PURE__ */ jsx(EditIcon, { className: "w-3 h-3" })
584
- });
585
- return /* @__PURE__ */ jsx("button", {
586
- type: "button",
587
- onClick,
588
- disabled,
589
- "aria-label": label,
590
- title: tooltip ? void 0 : label,
591
- className: cx(headerActionButtonClasses, disabled && "opacity-50 cursor-not-allowed hover:bg-transparent"),
592
- ...tooltipProps,
593
- children: /* @__PURE__ */ jsx(EditIcon, { className: "w-3 h-3" })
594
- });
595
- }
596
- /** Renders nothing when the modern breadcrumb strip isn't mounted (classic chrome or self-headered pages). */
597
- function BreadcrumbsTitleAction({ children }) {
598
- const { titleActionSlot } = useBreadcrumb();
599
- if (!titleActionSlot) return null;
600
- return createPortal(children, titleActionSlot);
601
- }
602
- function BreadcrumbsRightAction({ children }) {
603
- const { rightActionSlot } = useBreadcrumb();
604
- if (!rightActionSlot) return null;
605
- return createPortal(children, rightActionSlot);
606
- }
607
- var breadcrumbsActionClasses = "flex items-center gap-1 link text-xs whitespace-nowrap disabled:opacity-50 disabled:cursor-not-allowed";
608
- function BreadcrumbsActionButton({ icon: Icon, label, ariaLabel, to, onClick, disabled, tooltip }) {
609
- const Link = useLink();
610
- const tip = tooltip ? {
611
- "data-tooltip-id": TOOLTIP_ID,
612
- "data-tooltip-content": tooltip
613
- } : {};
614
- const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Icon, { className: "w-3 h-3" }), label] });
615
- if (to && !disabled) return /* @__PURE__ */ jsx(Link, {
616
- to,
617
- className: breadcrumbsActionClasses,
618
- ...ariaLabel ? { "aria-label": ariaLabel } : {},
619
- ...tip,
620
- children: content
621
- });
622
- return /* @__PURE__ */ jsx("button", {
623
- type: "button",
624
- onClick,
625
- disabled,
626
- className: breadcrumbsActionClasses,
627
- ...ariaLabel ? { "aria-label": ariaLabel } : {},
628
- ...tip,
629
- children: content
630
- });
631
- }
632
- function PageHeader({ breadcrumbs, title, titleAction, actions, toolbar, className, sticky = true, stickyTopClassName = "top-0" }) {
633
- const { setHidden } = useBreadcrumb();
634
- const Link = useLink();
635
- const { breadcrumbPin, navToggle } = useSlots();
636
- useLayoutEffect(() => {
637
- setHidden(true);
638
- return () => setHidden(false);
639
- }, [setHidden]);
640
- const crumbs = [...breadcrumbs ?? []];
641
- const lastLabel = crumbs[crumbs.length - 1]?.label;
642
- if (title !== null && title !== void 0 && title !== lastLabel) crumbs.push({ label: title });
643
- const crumbRow = crumbs.length > 0 && /* @__PURE__ */ jsxs("div", {
644
- className: "flex items-center gap-1.5 min-w-0",
645
- children: [
646
- /* @__PURE__ */ jsx("nav", {
647
- "aria-label": "Breadcrumb",
648
- className: "flex items-center gap-2 min-w-0 text-[13px]",
649
- children: crumbs.map((crumb, idx) => {
650
- if (idx === crumbs.length - 1) return /* @__PURE__ */ jsx("h1", {
651
- className: "m-0 text-[13px] font-medium leading-none text-(--theme-app) truncate",
652
- children: crumb.label
653
- }, `${crumb.label}-${idx}`);
654
- return /* @__PURE__ */ jsxs(Fragment, { children: [crumb.href ? /* @__PURE__ */ jsx(Link, {
655
- to: crumb.href,
656
- className: "text-(--theme-muted-text-color) hover:text-(--theme-app) transition-colors cursor-pointer whitespace-nowrap",
657
- children: crumb.label
658
- }) : /* @__PURE__ */ jsx("span", {
659
- className: "text-(--theme-muted-text-color) whitespace-nowrap",
660
- children: crumb.label
661
- }), /* @__PURE__ */ jsx(ChevronRightIcon, { className: "w-3 h-3 opacity-60 shrink-0 text-(--theme-muted-text-color)" })] }, `${crumb.label}-${idx}`);
662
- })
663
- }),
664
- titleAction,
665
- breadcrumbPin?.({ crumbs })
666
- ]
667
- });
668
- const actionCluster = actions && /* @__PURE__ */ jsx("div", {
669
- className: "flex items-center gap-1.5 shrink-0",
670
- children: actions
671
- });
672
- const toggle = navToggle?.();
673
- const hasLeading = !!crumbRow || !!toggle;
674
- const leading = hasLeading ? /* @__PURE__ */ jsxs("div", {
675
- className: "flex items-center gap-2 min-w-0",
676
- children: [toggle, crumbRow]
677
- }) : /* @__PURE__ */ jsx("div", {});
678
- return /* @__PURE__ */ jsxs("div", {
679
- className: cx(sticky && cx("sticky z-20", stickyTopClassName), "w-full bg-(--theme-app-bg)", className),
680
- children: [/* @__PURE__ */ jsxs("div", {
681
- className: cx("flex items-center justify-between gap-6 px-4 h-11", hasLeading && "border-b border-(--theme-border)"),
682
- children: [leading, actionCluster]
683
- }), toolbar && /* @__PURE__ */ jsx("div", {
684
- className: "px-4",
685
- children: toolbar
686
- })]
687
- });
688
- }
689
- //#endregion
690
- export { useSetDefaultBreadcrumbs as C, avatarInitials as E, useSetBreadcrumbs as S, Avatar as T, useRowMenuActive as _, HeaderAddButton as a, useClearBreadcrumbs as b, PageHeader as c, assembleRowMenu as d, rowContextMenuProps as f, useRowMenu as g, useCopySubmenu as h, HeaderActionMenu as i, headerActionButtonClasses as l, toolbarActionToRowAction as m, BreadcrumbsRightAction as n, HeaderEditButton as o, toRowMenuItem as p, BreadcrumbsTitleAction as r, HeaderRowMenu as s, BreadcrumbsActionButton as t, MoreButton as u, BreadcrumbProvider as v, AddMenu as w, useHideBreadcrumbs as x, useBreadcrumb as y };