@parallelworks/ui 0.19.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 (217) hide show
  1. package/dist/{chunks/memoryStore-CC91S5LP.js → ai/adapter/memoryStore.js} +2 -2
  2. package/dist/ai/adapter/mock/index.js +2 -80
  3. package/dist/ai/adapter/mock/mockAdapter.js +81 -0
  4. package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
  5. package/dist/ai/adapter/openai/errors.js +37 -0
  6. package/dist/ai/adapter/openai/index.js +5 -333
  7. package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
  8. package/dist/ai/adapter/openai/responses.js +108 -0
  9. package/dist/ai/adapter/openai/sse.js +112 -0
  10. package/dist/{chunks/types-Yy0NrerF.js → ai/adapter/types.js} +1 -1
  11. package/dist/ai/agent/classifier.js +12 -0
  12. package/dist/ai/agent/diff.js +223 -0
  13. package/dist/ai/agent/diffHighlight.js +101 -0
  14. package/dist/ai/agent/permissions.js +29 -0
  15. package/dist/ai/agent/toolfmt.js +383 -0
  16. package/dist/ai/agent/transcript.js +127 -0
  17. package/dist/ai/components/AllocationSelector.js +56 -0
  18. package/dist/ai/components/AttachmentManager.js +144 -0
  19. package/dist/ai/components/AttachmentUpload.js +179 -0
  20. package/dist/ai/components/BlockedGroupBanner.js +29 -0
  21. package/dist/ai/components/BranchNavigator.js +57 -0
  22. package/dist/ai/components/ChatEmptyState.js +171 -0
  23. package/dist/ai/components/ChatInput.js +265 -0
  24. package/dist/ai/components/ChatLayout.js +15 -0
  25. package/dist/ai/components/ChatMessage.js +338 -0
  26. package/dist/ai/components/ChatMessageList.js +301 -0
  27. package/dist/ai/components/ChatSidebar.js +345 -0
  28. package/dist/ai/components/ChatThread.js +198 -0
  29. package/dist/ai/components/ComposerChrome.js +50 -0
  30. package/dist/ai/components/ComposerFrame.js +33 -0
  31. package/dist/ai/components/DragOverlay.js +20 -0
  32. package/dist/ai/components/ModelSelector.js +343 -0
  33. package/dist/ai/components/ShareDialog.js +260 -0
  34. package/dist/ai/components/SlashMenu.js +91 -0
  35. package/dist/ai/components/agent/ActivityLine.js +151 -0
  36. package/dist/ai/components/agent/AgentMessageParts.js +721 -0
  37. package/dist/ai/components/agent/PermissionPicker.js +38 -0
  38. package/dist/ai/components/attachmentKeys.js +10 -0
  39. package/dist/ai/core/ChatProvider.js +848 -0
  40. package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
  41. package/dist/ai/core/chatReducer.js +223 -0
  42. package/dist/ai/core/config.js +45 -0
  43. package/dist/ai/core/events.js +4 -0
  44. package/dist/ai/core/exportConversation.js +42 -0
  45. package/dist/ai/core/greeting.js +38 -0
  46. package/dist/ai/core/parts.js +84 -0
  47. package/dist/ai/core/useDragDrop.js +36 -0
  48. package/dist/ai/core/useKeyboardShortcuts.js +77 -0
  49. package/dist/ai/core/useSSEStream.js +98 -0
  50. package/dist/ai/index.js +43 -6644
  51. package/dist/ai/strings.js +175 -0
  52. package/dist/ai/ui/Avatar.js +35 -0
  53. package/dist/ai/ui/Dropdown.js +110 -0
  54. package/dist/ai/ui/Markdown.js +79 -0
  55. package/dist/ai/ui/Notice.js +77 -0
  56. package/dist/ai/ui/codeBreaks.js +36 -0
  57. package/dist/ai/ui/prose.js +13 -0
  58. package/dist/ai/ui/sidebar.js +148 -0
  59. package/dist/ai/utils.js +23 -0
  60. package/dist/components/AddMenu.js +46 -0
  61. package/dist/components/Avatar.js +46 -0
  62. package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
  63. package/dist/components/Breadcrumbs.js +83 -0
  64. package/dist/components/Button.js +83 -0
  65. package/dist/components/Callout.js +23 -0
  66. package/dist/components/Card.js +31 -0
  67. package/dist/components/CollapsiblePanel.js +77 -0
  68. package/dist/{chunks/ConfirmModal-aOR4O1QE.js → components/ConfirmModal.js} +4 -9
  69. package/dist/components/CopyToClipboard.js +81 -0
  70. package/dist/{chunks/Markdown-CM-FenNE.js → components/CreateModal.js} +9 -116
  71. package/dist/components/DescriptionList.js +42 -0
  72. package/dist/components/Dropdown.js +349 -0
  73. package/dist/components/EmptyState.js +27 -0
  74. package/dist/components/Filter.js +32 -0
  75. package/dist/components/FilterPill.js +13 -0
  76. package/dist/components/IconButton.js +34 -0
  77. package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
  78. package/dist/components/Input.js +88 -0
  79. package/dist/components/LetterBadge.js +13 -0
  80. package/dist/components/Listbox.js +123 -0
  81. package/dist/{chunks/Loader-BXoXTZGc.js → components/Loader.js} +1 -1
  82. package/dist/components/Markdown.js +15 -0
  83. package/dist/components/MultiSelect.js +171 -0
  84. package/dist/components/Overview.js +39 -0
  85. package/dist/components/PageHeader.js +194 -0
  86. package/dist/components/Pagination.js +35 -0
  87. package/dist/{chunks/Provider-CDYurraE.js → components/Provider.js} +1 -1
  88. package/dist/{chunks/RequiredMark-DfLdYbYZ.js → components/RequiredMark.js} +1 -1
  89. package/dist/components/SectionHeader.js +11 -0
  90. package/dist/components/SettingModeOption.js +30 -0
  91. package/dist/components/SettingRow.js +35 -0
  92. package/dist/components/SettingsCard.js +31 -0
  93. package/dist/components/SettingsGroup.js +17 -0
  94. package/dist/components/Sort.js +42 -0
  95. package/dist/components/StatusBadge.js +63 -0
  96. package/dist/components/SwitchToggle.js +59 -0
  97. package/dist/{chunks/SwitchToggleSmall-FcsaYSTs.js → components/SwitchToggleSmall.js} +1 -1
  98. package/dist/{chunks/Table-DU2MW8xz.js → components/Table.js} +3 -3
  99. package/dist/components/Toggle.js +20 -0
  100. package/dist/{chunks/Tooltip-K5HJr4_p.js → components/Tooltip.js} +2 -27
  101. package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
  102. package/dist/{chunks/focus-D_iZJTW1.js → components/focus.js} +1 -1
  103. package/dist/components/ghostButton.js +7 -0
  104. package/dist/components/inputClasses.js +4 -0
  105. package/dist/components/keys.js +27 -0
  106. package/dist/components/relativeTime.js +32 -0
  107. package/dist/{chunks/useCssIsDark-DHr05dG2.js → components/useCssIsDark.js} +1 -1
  108. package/dist/{chunks/duration-BOv8Phl8.js → duration.js} +1 -1
  109. package/dist/editor/Editor.js +13 -0
  110. package/dist/editor/EditorField.js +53 -0
  111. package/dist/editor/FormCodePanel.js +173 -0
  112. package/dist/{chunks/Monaco-DJ8MW-Dq.js → editor/Monaco.js} +4 -2
  113. package/dist/editor/index.js +6 -1
  114. package/dist/editor/themes.js +91 -0
  115. package/dist/editor/workers.js +29 -0
  116. package/dist/editor/yaml.js +15 -0
  117. package/dist/file-explorer/FileExplorer.js +1402 -0
  118. package/dist/file-explorer/FileExplorerContext.js +370 -0
  119. package/dist/{chunks/CodePreviewEditor-YqQBz1YL.js → file-explorer/FilePreview/CodePreviewEditor.js} +3 -2
  120. package/dist/file-explorer/FilePreview/Inline.js +45 -0
  121. package/dist/file-explorer/FilePreview/StreamedBadge.js +16 -0
  122. package/dist/file-explorer/FilePreview/Viewer.js +526 -0
  123. package/dist/file-explorer/FilePreview/index.js +266 -0
  124. package/dist/file-explorer/FilePreview/parse.js +63 -0
  125. package/dist/file-explorer/FilePreview/previewCache.js +98 -0
  126. package/dist/file-explorer/FilePreview/previewType.js +151 -0
  127. package/dist/file-explorer/FilePreview/readCappedBytes.js +196 -0
  128. package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +95 -0
  129. package/dist/file-explorer/FilePreview/useObjectText.js +109 -0
  130. package/dist/file-explorer/FilePreview/usePresignedUrl.js +73 -0
  131. package/dist/file-explorer/FileRow.js +165 -0
  132. package/dist/file-explorer/FileRowsWindow.js +92 -0
  133. package/dist/file-explorer/FileTable.js +172 -0
  134. package/dist/file-explorer/FileTableHeaders.js +49 -0
  135. package/dist/file-explorer/LoadMoreRow.js +46 -0
  136. package/dist/file-explorer/TreeView.js +376 -0
  137. package/dist/file-explorer/helpers.js +537 -0
  138. package/dist/file-explorer/index.js +7 -5671
  139. package/dist/file-explorer/lib/batch.js +39 -0
  140. package/dist/file-explorer/lib/errors.js +9 -0
  141. package/dist/file-explorer/lib/paging.js +124 -0
  142. package/dist/file-explorer/lib/utils.js +322 -0
  143. package/dist/file-explorer/toasts.js +400 -0
  144. package/dist/file-explorer/treeRows.js +73 -0
  145. package/dist/file-explorer/useNearEnd.js +27 -0
  146. package/dist/form/FieldWrapper.js +54 -0
  147. package/dist/form/Fields/BooleanField.js +51 -0
  148. package/dist/form/Fields/CheckboxGroupField.js +72 -0
  149. package/dist/form/Fields/ColorField.js +33 -0
  150. package/dist/form/Fields/DropdownField.js +49 -0
  151. package/dist/form/Fields/DurationField.js +130 -0
  152. package/dist/form/Fields/LabelField.js +19 -0
  153. package/dist/form/Fields/MultiDropdownField.js +40 -0
  154. package/dist/form/Fields/NumberField.js +51 -0
  155. package/dist/form/Fields/ObjectField.js +54 -0
  156. package/dist/form/Fields/RadioField.js +49 -0
  157. package/dist/form/Fields/RangeField.js +58 -0
  158. package/dist/form/Fields/ResourceOptionIcon.js +21 -0
  159. package/dist/form/Fields/StepField.js +6 -0
  160. package/dist/form/Fields/StringField.js +37 -0
  161. package/dist/form/Fields/TextAreaField.js +31 -0
  162. package/dist/form/Fields/durationValidity.js +11 -0
  163. package/dist/form/Form.js +643 -0
  164. package/dist/form/SpecialTypes/DropdownWrapper.js +30 -0
  165. package/dist/form/SpecialTypes/FormikCustomDropdown.js +122 -0
  166. package/dist/form/SpecialTypes/FormikCustomInput.js +111 -0
  167. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +31 -0
  168. package/dist/form/SpecialTypes/FormikNumericInput.js +60 -0
  169. package/dist/form/Wizard/WizardContainer.js +138 -0
  170. package/dist/form/Wizard/WizardNavigation.js +92 -0
  171. package/dist/form/Wizard/WizardStepContent.js +35 -0
  172. package/dist/form/Wizard/WizardStepIndicator.js +108 -0
  173. package/dist/form/Wizard/useWizardState.js +118 -0
  174. package/dist/form/Wizard/utils.js +34 -0
  175. package/dist/form/fieldContext.js +26 -0
  176. package/dist/form/fieldRegistry.js +50 -0
  177. package/dist/form/index.js +17 -2321
  178. package/dist/{chunks/FieldWrapper-Cszwg-4B.js → form/lib.js} +2 -97
  179. package/dist/form/useParsedOpts.js +62 -0
  180. package/dist/form/usePrevious.js +11 -0
  181. package/dist/form/utils/checkShowIfObject.js +14 -0
  182. package/dist/form/utils/duration.js +69 -0
  183. package/dist/form/utils/getParentValue.js +23 -0
  184. package/dist/form/utils/getPlaceholder.js +9 -0
  185. package/dist/form/utils/getValueUsingPath.js +23 -0
  186. package/dist/form/utils/secondaryField.js +22 -0
  187. package/dist/graph/AnnotationBanner.js +141 -0
  188. package/dist/graph/Collapse.js +41 -0
  189. package/dist/graph/DependencyGraph.js +1398 -0
  190. package/dist/graph/JobSummary.js +104 -0
  191. package/dist/graph/MatrixGroup.js +107 -0
  192. package/dist/graph/Reveal.js +57 -0
  193. package/dist/graph/TreeView.js +711 -0
  194. package/dist/graph/index.js +1 -2519
  195. package/dist/graph/types.js +6 -0
  196. package/dist/index.js +46 -599
  197. package/dist/list/ActionToolbar.js +184 -0
  198. package/dist/list/HoverCard.js +73 -0
  199. package/dist/list/ListPage.js +145 -0
  200. package/dist/list/ListPager.js +59 -0
  201. package/dist/list/ListTable.js +163 -0
  202. package/dist/list/ListViewControls.js +372 -0
  203. package/dist/list/RowContextMenu.js +350 -0
  204. package/dist/list/UserHoverCard.js +117 -0
  205. package/dist/list/index.js +11 -2
  206. package/dist/list/listSearch.js +137 -0
  207. package/dist/list/listView.js +210 -0
  208. package/dist/list/textEntry.js +10 -0
  209. package/dist/{chunks/logviewer-BTKuQWzw.js → logviewer/LogViewer.js} +4 -82
  210. package/dist/logviewer/index.js +2 -1
  211. package/dist/logviewer/segments.js +80 -0
  212. package/package.json +1 -1
  213. package/dist/chunks/PageHeader-0kG_iypP.js +0 -692
  214. package/dist/chunks/SwitchToggle-DShNdcao.js +0 -758
  215. package/dist/chunks/editor-Dk1rbV75.js +0 -361
  216. package/dist/chunks/list-CJm875m7.js +0 -1418
  217. /package/dist/{chunks/MarkdownImpl-CyeTVvSt.js → components/MarkdownImpl.js} +0 -0
@@ -1,109 +1,14 @@
1
- import { i as useNotify, u as useStrings } from "./Provider-CDYurraE.js";
2
- import { AlertIcon, CheckIcon, ChevronDownIcon, ChevronRightIcon, ClipboardIcon, CopyIcon, FavoriteIcon, FavoriteOutlineIcon, HiddenFalseIcon, HiddenTrueIcon, InfoIcon, TooltipIcon } from "../icons.js";
3
- import { n as TOOLTIP_ID } from "./Tooltip-K5HJr4_p.js";
4
- import { E as AddMenu } from "./PageHeader-0kG_iypP.js";
5
- import { n as modalPanelClasses, t as BareModal } from "./BareModal-BtRiQezg.js";
6
- import { r as ghostButtonClasses } from "./ConfirmModal-aOR4O1QE.js";
7
- import { a as filterOption, u as toggleSetMember } from "./StatusBadge-C1Blx_cW.js";
1
+ import { useStrings } from "./Provider.js";
2
+ import { ChevronDownIcon, ChevronRightIcon, FavoriteIcon, FavoriteOutlineIcon, TooltipIcon } from "../icons.js";
3
+ import { TOOLTIP_ID } from "./Tooltip.js";
4
+ import { AddMenu } from "./AddMenu.js";
5
+ import { BareModal, modalPanelClasses } from "./BareModal.js";
6
+ import { ghostButtonClasses } from "./ghostButton.js";
7
+ import { filterOption, toggleSetMember } from "./dropdownUtils.js";
8
8
  import { Combobox, ComboboxInput, ComboboxOption, ComboboxOptions, Menu, MenuButton, MenuItem, MenuItems } from "@headlessui/react";
9
9
  import cx from "classnames";
10
- import { Suspense, lazy, useCallback, useEffect, useRef, useState } from "react";
10
+ import { useCallback, useEffect, useRef, useState } from "react";
11
11
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
12
- //#region src/components/Callout.tsx
13
- function CalloutIcon({ type }) {
14
- if (type === "warning" || type === "error") return /* @__PURE__ */ jsx(AlertIcon, { className: "h-6 w-6 mr-4 text-lg" });
15
- else return /* @__PURE__ */ jsx(InfoIcon, { className: "h-6 w-6 mr-4 text-lg" });
16
- }
17
- function Callout({ type, className = "", children }) {
18
- return /* @__PURE__ */ jsx("div", {
19
- className: cx(className, type === "warning" && "bg-orange-100 border-orange-500 text-orange-700", type === "error" && "bg-red-100 border-red-500 text-red-700", type === "info" && "bg-blue-100 border-blue-500 text-blue-700", "border-t-4 rounded-b px-4 py-3 shadow-md my-4"),
20
- role: "alert",
21
- children: /* @__PURE__ */ jsxs("div", {
22
- className: "flex",
23
- children: [/* @__PURE__ */ jsx("div", {
24
- className: "py-1",
25
- children: /* @__PURE__ */ jsx(CalloutIcon, { type })
26
- }), /* @__PURE__ */ jsx("div", { children })]
27
- })
28
- });
29
- }
30
- //#endregion
31
- //#region src/components/CopyToClipboard.tsx
32
- function CopyToClipboard({ as = "div", text, className, children, showIcon = true }) {
33
- const notify = useNotify();
34
- const strings = useStrings();
35
- const handleCopy = async () => {
36
- try {
37
- await navigator.clipboard.writeText(text);
38
- notify.info("Copied to clipboard");
39
- } catch {
40
- notify.error("Failed to copy to clipboard");
41
- }
42
- };
43
- return /* @__PURE__ */ jsxs(as, {
44
- className,
45
- onClick: handleCopy,
46
- ...as === "button" ? { type: "button" } : {
47
- role: "button",
48
- "aria-label": strings.common.copy,
49
- tabIndex: 0,
50
- onKeyDown: (e) => {
51
- if (e.key === "Enter" || e.key === " ") {
52
- e.preventDefault();
53
- handleCopy();
54
- }
55
- }
56
- },
57
- children: [showIcon && /* @__PURE__ */ jsx(ClipboardIcon, {}), children]
58
- });
59
- }
60
- function CopyCodeBlock({ textToCopy, children, secret = false, isRevealed = false, onRevealToggle }) {
61
- const notify = useNotify();
62
- const [copied, setCopied] = useState(false);
63
- const handleCopy = async () => {
64
- if (copied) return;
65
- try {
66
- await navigator.clipboard.writeText(textToCopy);
67
- setCopied(true);
68
- notify.info("Copied to clipboard");
69
- setTimeout(() => setCopied(false), 2e3);
70
- } catch {
71
- notify.error("Failed to copy to clipboard");
72
- }
73
- };
74
- return /* @__PURE__ */ jsxs("div", {
75
- className: "group relative",
76
- role: "none",
77
- onClick: handleCopy,
78
- children: [/* @__PURE__ */ jsx("pre", {
79
- className: `p-4 theme-hover border rounded-lg text-left font-mono text-sm overflow-x-auto ${secret ? "pr-24" : "pr-12"}`,
80
- children
81
- }), /* @__PURE__ */ jsxs("div", {
82
- className: "absolute top-0 right-0 bottom-0 flex items-center gap-1 pl-8 pr-2 bg-gradient-to-l from-[var(--color-panel)] from-70% to-transparent rounded-r-lg",
83
- children: [secret && /* @__PURE__ */ jsx("button", {
84
- type: "button",
85
- onClick: (e) => {
86
- e.stopPropagation();
87
- onRevealToggle?.();
88
- },
89
- className: "p-2 rounded-md opacity-0 group-hover:opacity-100 transition-all duration-150",
90
- "aria-label": isRevealed ? "Hide secret" : "Reveal secret",
91
- title: isRevealed ? "Hide secret" : "Reveal secret",
92
- children: isRevealed ? /* @__PURE__ */ jsx(HiddenFalseIcon, {}) : /* @__PURE__ */ jsx(HiddenTrueIcon, {})
93
- }), /* @__PURE__ */ jsx("button", {
94
- type: "button",
95
- onClick: (e) => {
96
- e.stopPropagation();
97
- handleCopy();
98
- },
99
- className: "p-2 rounded-md opacity-0 group-hover:opacity-100 transition-all duration-150",
100
- "aria-label": copied ? "Copied" : "Copy to clipboard",
101
- children: copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-green-400" }) : /* @__PURE__ */ jsx(CopyIcon, {})
102
- })]
103
- })]
104
- });
105
- }
106
- //#endregion
107
12
  //#region src/components/CreateModal.tsx
108
13
  /** Small info icon that surfaces field help via the global tooltip. */
109
14
  function FieldHelp({ tooltip }) {
@@ -571,16 +476,4 @@ function CreateModalSelect({ label, icon, value, options, onChange, disabled = f
571
476
  })] }) });
572
477
  }
573
478
  //#endregion
574
- //#region src/components/Markdown.tsx
575
- var MarkdownImpl = lazy(() => import("./MarkdownImpl-CyeTVvSt.js"));
576
- function Markdown(props) {
577
- return /* @__PURE__ */ jsx(Suspense, {
578
- fallback: /* @__PURE__ */ jsx("div", {
579
- className: "markdown whitespace-pre-wrap text-start w-full",
580
- children: props.children
581
- }),
582
- children: /* @__PURE__ */ jsx(MarkdownImpl, { ...props })
583
- });
584
- }
585
- //#endregion
586
- export { CreateModalField as a, CreateModalTextarea as c, Callout as d, CreateModalAutocompleteField as i, CopyCodeBlock as l, CREATE_MODAL_SELECT_FILTER_THRESHOLD as n, CreateModalSelect as o, CreateModal as r, CreateModalSwitch as s, Markdown as t, CopyToClipboard as u };
479
+ export { CREATE_MODAL_SELECT_FILTER_THRESHOLD, CreateModal, CreateModalAutocompleteField, CreateModalField, CreateModalSelect, CreateModalSwitch, CreateModalTextarea };
@@ -0,0 +1,42 @@
1
+ import { TooltipInfo } from "./Tooltip.js";
2
+ import cx from "classnames";
3
+ import React from "react";
4
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/components/DescriptionList.tsx
6
+ function DescriptionListItem({ label, children, tooltip, className, ...props }) {
7
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("dt", {
8
+ className: cx("text-[13px] leading-6 col-span-1 font-normal flex gap-1", className),
9
+ children: [/* @__PURE__ */ jsx("span", {
10
+ className: "min-w-0 truncate",
11
+ children: label
12
+ }), tooltip && /* @__PURE__ */ jsx(TooltipInfo, {
13
+ className: "pr-2",
14
+ text: tooltip
15
+ })]
16
+ }), /* @__PURE__ */ jsx("dd", {
17
+ ...props,
18
+ className: "flex text-[13px] leading-6 col-span-4 font-light items-center overflow-auto",
19
+ children
20
+ })] });
21
+ }
22
+ function DescriptionList({ children, title, separators = true, subtitle, className, wrapperClassName, vertical = false }) {
23
+ return /* @__PURE__ */ jsxs("div", {
24
+ className: cx("w-full", wrapperClassName),
25
+ children: [
26
+ title && /* @__PURE__ */ jsx("h2", {
27
+ className: "text-sm font-semibold w-full mb-1",
28
+ children: title
29
+ }),
30
+ subtitle && /* @__PURE__ */ jsx("div", {
31
+ className: "max-w-2xl text-sm/6 w-full",
32
+ children: subtitle
33
+ }),
34
+ /* @__PURE__ */ jsx("dl", {
35
+ className: cx("grid", separators && "*:not-last-of-type:border-b-1", vertical ? "grid-cols-1" : "grid-cols-5 gap-x-4 gap-y-0.5 *:pb-0.5", className),
36
+ children: Array.isArray(children) ? React.Children.toArray(children) : children
37
+ })
38
+ ]
39
+ });
40
+ }
41
+ //#endregion
42
+ export { DescriptionListItem, DescriptionList as default };
@@ -0,0 +1,349 @@
1
+ import { useStrings } from "./Provider.js";
2
+ import { CaretDownIcon } from "../icons.js";
3
+ import { truncationTooltipProps } from "./Tooltip.js";
4
+ import { DropdownCaret, flattenDisplayOptions, isCategory, toggleSetMember } from "./dropdownUtils.js";
5
+ import { Combobox, ComboboxButton, ComboboxInput, ComboboxOption, ComboboxOptions } from "@headlessui/react";
6
+ import cx from "classnames";
7
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
8
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
9
+ import { createPortal } from "react-dom";
10
+ import deepEqual from "fast-deep-equal";
11
+ import { usePopper } from "react-popper";
12
+ //#region src/components/Dropdown.tsx
13
+ var defaultCollapsedLabel = (count) => `${count} more`;
14
+ function isNamedValue(value) {
15
+ return typeof value === "object" && value !== null && "name" in value && typeof value.name === "string";
16
+ }
17
+ var checkEquals = (val, opt) => {
18
+ if (typeof val === "object" && !Array.isArray(val)) return deepEqual(val, opt);
19
+ return val === opt;
20
+ };
21
+ function getOptionFromValue(value, options) {
22
+ if (value === void 0) return {
23
+ label: "",
24
+ value: ""
25
+ };
26
+ const found = options?.find((option) => {
27
+ if (typeof option === "string") return checkEquals(value, option);
28
+ else if (isCategory(option)) return option.options.find((opt) => checkEquals(value, opt.value));
29
+ else return checkEquals(value, option.value);
30
+ });
31
+ if (found) {
32
+ if (typeof found === "string") return {
33
+ label: found,
34
+ value: found
35
+ };
36
+ else if (isCategory(found)) return found.options.find((opt) => checkEquals(value, opt.value)) || {
37
+ label: JSON.stringify(value),
38
+ value
39
+ };
40
+ else return found;
41
+ }
42
+ const isNamedObject = isNamedValue(value);
43
+ const fallbackLabel = typeof value === "string" ? value : isNamedObject ? value.name : JSON.stringify(value);
44
+ return {
45
+ label: fallbackLabel,
46
+ value: isNamedObject ? value : fallbackLabel
47
+ };
48
+ }
49
+ function Dropdown(props) {
50
+ const { onChange, value, options = [], ...others } = props;
51
+ const val = useMemo(() => {
52
+ return getOptionFromValue(value, options);
53
+ }, [value, options]);
54
+ const wrapperOnchange = (value) => {
55
+ if (onChange) onChange(value?.value);
56
+ };
57
+ const transformedOptions = useMemo(() => {
58
+ if (!options || options.length === 0) return [];
59
+ return options.map((item) => {
60
+ if (isCategory(item)) return {
61
+ ...item,
62
+ options: item.options.map((opt) => {
63
+ if (typeof opt === "string") return {
64
+ label: opt,
65
+ value: opt
66
+ };
67
+ return opt;
68
+ })
69
+ };
70
+ else if (typeof item === "string") return {
71
+ label: item,
72
+ value: item
73
+ };
74
+ return item;
75
+ });
76
+ }, [options]);
77
+ return /* @__PURE__ */ jsx(DropdownHelper, {
78
+ value: val,
79
+ onChange: wrapperOnchange,
80
+ options: transformedOptions,
81
+ ...others
82
+ });
83
+ }
84
+ function ActiveWatcher({ active, onChange }) {
85
+ const prev = useRef(null);
86
+ useEffect(() => {
87
+ if (prev.current !== active) {
88
+ onChange?.(active?.value);
89
+ prev.current = active;
90
+ }
91
+ }, [active, onChange]);
92
+ return null;
93
+ }
94
+ function OptionContent({ label, description, icon }) {
95
+ return /* @__PURE__ */ jsxs("span", {
96
+ className: cx("flex gap-1.5", description ? "items-start min-w-0" : "items-center truncate"),
97
+ ...truncationTooltipProps(label, (anchor) => anchor.lastElementChild),
98
+ children: [icon, description ? /* @__PURE__ */ jsxs("span", {
99
+ className: "flex flex-col min-w-0",
100
+ children: [/* @__PURE__ */ jsx("span", {
101
+ className: "truncate",
102
+ children: label
103
+ }), /* @__PURE__ */ jsx("span", {
104
+ className: "text-(--theme-muted-text-color) text-xs leading-snug",
105
+ children: description
106
+ })]
107
+ }) : /* @__PURE__ */ jsx("span", {
108
+ className: "truncate",
109
+ children: label
110
+ })]
111
+ });
112
+ }
113
+ function ToggleOption({ option, category, expanded, onToggle, ...virtualRowProps }) {
114
+ return /* @__PURE__ */ jsx(ComboboxOption, {
115
+ ...virtualRowProps,
116
+ "data-testid": "combobox-toggle",
117
+ value: option,
118
+ className: "w-full h-10 flex items-center pl-3",
119
+ children: /* @__PURE__ */ jsxs("button", {
120
+ type: "button",
121
+ "aria-expanded": expanded,
122
+ className: "flex items-center gap-1.5 cursor-pointer text-(--theme-muted-text-color) hover:text-(--theme-app)",
123
+ onMouseDown: (e) => e.preventDefault(),
124
+ onClick: (e) => {
125
+ e.preventDefault();
126
+ e.stopPropagation();
127
+ onToggle(category);
128
+ },
129
+ children: [/* @__PURE__ */ jsx(CaretDownIcon, { className: cx("w-3 h-3", !expanded && "-rotate-90") }), option.label]
130
+ })
131
+ });
132
+ }
133
+ function DropdownHelper({ wrapperClassName = "w-full", className, textBoxClassName = "w-full", options = [], onChange, onActiveChange, value, id, ariaLabel, "aria-describedby": describedBy, required, disabled = false, placeholder = "", loading = false, allowCustomValue = false, customValueLabel = "Use", collapsedLabel = defaultCollapsedLabel, portalEl, compact = false }) {
134
+ const DEBOUNCE_MS = 500;
135
+ const t = useStrings().dropdown;
136
+ const [query, setQuery] = useState("");
137
+ const [selectedIconWidth, setSelectedIconWidth] = useState(0);
138
+ const selectedIconRef = useCallback((node) => {
139
+ setSelectedIconWidth(node?.offsetWidth ?? 0);
140
+ }, []);
141
+ const selectedIcon = query === "" ? value?.icon : void 0;
142
+ const [referenceElement, setReferenceElement] = useState(null);
143
+ const [popperElement, setPopperElement] = useState(null);
144
+ const [boundaryEl, setBoundaryEl] = useState(null);
145
+ useEffect(() => {
146
+ if (!referenceElement) {
147
+ setBoundaryEl(null);
148
+ return;
149
+ }
150
+ const ref = referenceElement;
151
+ const dialog = ref.closest("[role=\"dialog\"]");
152
+ if (!dialog) {
153
+ setBoundaryEl(null);
154
+ return;
155
+ }
156
+ let node = ref.parentElement;
157
+ while (node) {
158
+ const style = getComputedStyle(node);
159
+ if (/(auto|scroll|hidden)/.test(`${style.overflowX} ${style.overflowY}`)) {
160
+ setBoundaryEl(node);
161
+ return;
162
+ }
163
+ if (node === dialog) break;
164
+ node = node.parentElement;
165
+ }
166
+ setBoundaryEl(dialog);
167
+ }, [referenceElement]);
168
+ const sameWidthModifier = useMemo(() => ({
169
+ name: "sameWidth",
170
+ enabled: true,
171
+ phase: "beforeWrite",
172
+ requires: ["computeStyles"],
173
+ fn: ({ state }) => {
174
+ const popperStyles = state.styles["popper"];
175
+ if (popperStyles) popperStyles.width = `${state.rects.reference.width}px`;
176
+ },
177
+ effect: ({ state }) => {
178
+ const { popper, reference } = state.elements;
179
+ if (reference instanceof HTMLElement) popper.style.width = `${reference.offsetWidth}px`;
180
+ }
181
+ }), []);
182
+ const popperModifiers = useMemo(() => boundaryEl ? [
183
+ sameWidthModifier,
184
+ {
185
+ name: "flip",
186
+ options: { boundary: boundaryEl }
187
+ },
188
+ {
189
+ name: "preventOverflow",
190
+ options: { boundary: boundaryEl }
191
+ }
192
+ ] : [sameWidthModifier], [boundaryEl, sameWidthModifier]);
193
+ const { styles, attributes } = usePopper(referenceElement, popperElement, {
194
+ strategy: "fixed",
195
+ modifiers: popperModifiers
196
+ });
197
+ const debounceRef = useRef(null);
198
+ const buttonRef = useRef(null);
199
+ const [expandedCategories, setExpandedCategories] = useState(/* @__PURE__ */ new Set());
200
+ const selectedCategory = useMemo(() => options.find((o) => isCategory(o) && o.options.some((opt) => checkEquals(value.value, opt.value)))?.category, [options, value]);
201
+ const lastAutoExpandedValue = useRef(void 0);
202
+ useEffect(() => {
203
+ if (!selectedCategory || checkEquals(lastAutoExpandedValue.current, value.value)) return;
204
+ lastAutoExpandedValue.current = value.value;
205
+ setExpandedCategories((prev) => prev.size === 1 && prev.has(selectedCategory) ? prev : /* @__PURE__ */ new Set([selectedCategory]));
206
+ }, [selectedCategory, value]);
207
+ const toggleCategory = (category) => setExpandedCategories((prev) => toggleSetMember(prev, category));
208
+ const flushCustomValue = useCallback((val) => {
209
+ onChange({
210
+ label: val,
211
+ value: val
212
+ });
213
+ }, [onChange]);
214
+ const onQueryChange = (val) => {
215
+ setQuery(val);
216
+ if (allowCustomValue) {
217
+ if (debounceRef.current) clearTimeout(debounceRef.current);
218
+ debounceRef.current = setTimeout(() => {
219
+ flushCustomValue(val);
220
+ debounceRef.current = null;
221
+ }, DEBOUNCE_MS);
222
+ }
223
+ };
224
+ const onInputBlur = () => {
225
+ if (allowCustomValue && debounceRef.current) {
226
+ clearTimeout(debounceRef.current);
227
+ debounceRef.current = null;
228
+ flushCustomValue(query);
229
+ }
230
+ setQuery("");
231
+ };
232
+ const onComboboxChange = (val) => {
233
+ if (debounceRef.current) {
234
+ clearTimeout(debounceRef.current);
235
+ debounceRef.current = null;
236
+ }
237
+ onChange(val);
238
+ };
239
+ const flattenedOptions = useMemo(() => flattenDisplayOptions({
240
+ options,
241
+ query,
242
+ expandedCategories,
243
+ collapsedLabel,
244
+ selectedValue: value?.value,
245
+ allowCustomValue,
246
+ customValueLabel
247
+ }), [
248
+ options,
249
+ query,
250
+ expandedCategories,
251
+ collapsedLabel,
252
+ value,
253
+ allowCustomValue,
254
+ customValueLabel
255
+ ]);
256
+ const comboOptions = /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(ComboboxOptions, {
257
+ modal: false,
258
+ ref: setPopperElement,
259
+ style: styles["popper"],
260
+ className: cx("bg-(--theme-input-bg) border-(--theme-border) text-(--theme-app) max-h-60! empty:invisible border overflow-auto rounded-md shadow-lg focus:outline-hidden z-9999 data-[popper-reference-hidden=true]:invisible data-[popper-reference-hidden=true]:pointer-events-none", compact ? "text-xs" : "sm:text-sm"),
261
+ ...attributes["popper"],
262
+ children: ({ option }) => {
263
+ const optionLabel = typeof option === "string" ? option : option.label;
264
+ const optionDescription = typeof option !== "string" ? option.description : void 0;
265
+ const isCategoryRow = typeof option !== "string" && Boolean(option.category);
266
+ const toggleTarget = typeof option !== "string" ? option.toggle : void 0;
267
+ const isPinned = typeof option !== "string" && Boolean(option.pinned);
268
+ if (toggleTarget !== void 0) return /* @__PURE__ */ jsx(ToggleOption, {
269
+ option,
270
+ category: toggleTarget,
271
+ expanded: expandedCategories.has(toggleTarget),
272
+ onToggle: toggleCategory
273
+ });
274
+ return /* @__PURE__ */ jsx(ComboboxOption, {
275
+ "data-testid": "combobox-option",
276
+ value: option,
277
+ className: cx("w-full group relative flex", optionDescription ? "min-h-10 py-2" : compact ? "h-8" : "h-10", isCategoryRow ? "text-[14px] font-bold pl-1 items-center" : "data-disabled:text-(--theme-muted-text-color) data-disabled:bg-(--theme-muted-panel-bg) data-disabled:cursor-not-allowed cursor-pointer items-center pr-9 pl-3 leading-5 data-focus:bg-(--theme-muted-panel-bg) data-focus:text-(--theme-app) data-focus:outline-hidden", "data-selected:border-l-2 data-selected:border-(--theme-link) data-selected:bg-(--theme-muted-panel-bg) data-selected:text-(--theme-app)", isPinned && "border-t border-(--theme-border) font-medium"),
278
+ children: /* @__PURE__ */ jsx(OptionContent, {
279
+ label: optionLabel,
280
+ description: optionDescription,
281
+ icon: typeof option !== "string" && option.icon
282
+ })
283
+ });
284
+ }
285
+ }) });
286
+ return /* @__PURE__ */ jsx("div", {
287
+ className: cx("relative rounded-md flex items-center", wrapperClassName),
288
+ children: /* @__PURE__ */ jsx(Combobox, {
289
+ "data-testid": "combobox",
290
+ className: cx("relative w-full", className),
291
+ as: "div",
292
+ by: checkEquals,
293
+ value,
294
+ onChange: onComboboxChange,
295
+ onClose: () => {
296
+ setQuery("");
297
+ setExpandedCategories(new Set(selectedCategory ? [selectedCategory] : []));
298
+ },
299
+ immediate: true,
300
+ virtual: {
301
+ options: flattenedOptions,
302
+ disabled: (option) => Boolean(option.disabled)
303
+ },
304
+ disabled,
305
+ children: ({ activeOption, open }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
306
+ onActiveChange && /* @__PURE__ */ jsx(ActiveWatcher, {
307
+ active: activeOption,
308
+ onChange: onActiveChange
309
+ }),
310
+ selectedIcon && /* @__PURE__ */ jsx("span", {
311
+ ref: selectedIconRef,
312
+ className: "pointer-events-none absolute inset-y-0 left-3 z-10 flex items-center",
313
+ children: selectedIcon
314
+ }, value.label),
315
+ /* @__PURE__ */ jsx(ComboboxInput, {
316
+ id,
317
+ "aria-label": ariaLabel || void 0,
318
+ "aria-describedby": describedBy,
319
+ "aria-required": required || void 0,
320
+ placeholder: loading ? "Loading..." : placeholder,
321
+ onBlur: onInputBlur,
322
+ ref: setReferenceElement,
323
+ onClick: () => {
324
+ if (!open) buttonRef.current?.click();
325
+ },
326
+ style: selectedIcon && selectedIconWidth > 0 ? { paddingLeft: selectedIconWidth + 18 } : void 0,
327
+ className: cx("placeholder:text-xs bg-(--theme-input-bg) border-(--theme-border) text-(--theme-app) focus:border-(--theme-element) focus:outline-none focus:ring-1 focus:ring-(--theme-element) w-full h-full text-ellipsis pr-8", "disabled:bg-(--theme-input-disabled-bg) disabled:text-(--theme-input-disabled-text) disabled:cursor-not-allowed", textBoxClassName),
328
+ autoComplete: "off",
329
+ onChange: (event) => onQueryChange(event.target.value),
330
+ displayValue: (opt) => {
331
+ return opt?.label?.replaceAll("\"", "") || query || "";
332
+ },
333
+ disabled
334
+ }),
335
+ /* @__PURE__ */ jsx(ComboboxButton, {
336
+ ref: buttonRef,
337
+ "aria-label": t.showOptions,
338
+ className: "absolute inset-y-0 right-0 flex items-center pr-3 disabled:cursor-not-allowed",
339
+ "data-testid": "combobox-button",
340
+ disabled,
341
+ children: /* @__PURE__ */ jsx(DropdownCaret, {})
342
+ }),
343
+ typeof document !== "undefined" && createPortal(comboOptions, portalEl ?? document.querySelector(".ds-root") ?? document.body)
344
+ ] })
345
+ })
346
+ });
347
+ }
348
+ //#endregion
349
+ export { Dropdown as default };
@@ -0,0 +1,27 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ //#region src/components/EmptyState.tsx
3
+ function EmptyState({ title, description, action, icon: Icon }) {
4
+ return /* @__PURE__ */ jsxs("div", {
5
+ className: "border-solid rounded-2xl border border-(--theme-border) theme-panel flex flex-col items-center justify-center py-12 px-6",
6
+ children: [
7
+ Icon && /* @__PURE__ */ jsx("div", {
8
+ className: "w-10 h-10 rounded-full bg-(--theme-muted-panel-bg) flex items-center justify-center mb-3",
9
+ children: /* @__PURE__ */ jsx(Icon, { className: "w-5 h-5 theme-muted-text" })
10
+ }),
11
+ /* @__PURE__ */ jsx("p", {
12
+ className: "text-sm font-medium mb-1",
13
+ children: title
14
+ }),
15
+ description && /* @__PURE__ */ jsx("p", {
16
+ className: "text-xs theme-muted-text text-center max-w-xs",
17
+ children: description
18
+ }),
19
+ action && /* @__PURE__ */ jsx("div", {
20
+ className: "mt-4",
21
+ children: action
22
+ })
23
+ ]
24
+ });
25
+ }
26
+ //#endregion
27
+ export { EmptyState as default };
@@ -0,0 +1,32 @@
1
+ import { FilterIcon } from "../icons.js";
2
+ import cx from "classnames";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/components/Filter.tsx
5
+ function Filter({ filter, setFilter, placeholder = "Filter...", pills, activePill, onPillChange }) {
6
+ return /* @__PURE__ */ jsxs("div", {
7
+ className: "flex items-center gap-2",
8
+ children: [/* @__PURE__ */ jsxs("div", {
9
+ className: "relative flex items-center",
10
+ children: [/* @__PURE__ */ jsx("input", {
11
+ placeholder,
12
+ type: "text",
13
+ value: filter,
14
+ onChange: (e) => setFilter(e.target.value.toLowerCase()),
15
+ className: "shadow-sm focus:ring-1 block w-full pr-3 sm:text-sm theme-border rounded-md py-1.5 pl-8"
16
+ }), /* @__PURE__ */ jsx("div", {
17
+ className: "absolute inset-y-0 left-0 flex py-2.5 pl-2",
18
+ children: /* @__PURE__ */ jsx(FilterIcon, {})
19
+ })]
20
+ }), pills && onPillChange && /* @__PURE__ */ jsx("div", {
21
+ className: "flex gap-1",
22
+ children: pills.map((pill) => /* @__PURE__ */ jsx("button", {
23
+ type: "button",
24
+ onClick: () => onPillChange(pill.value),
25
+ className: cx("px-2.5 py-1 text-xs rounded-full transition-colors border", activePill === pill.value ? "bg-(--theme-element) text-(--theme-element-text) border-transparent" : "theme-border theme-text hover:theme-hover"),
26
+ children: pill.label
27
+ }, pill.value))
28
+ })]
29
+ });
30
+ }
31
+ //#endregion
32
+ export { Filter as default };
@@ -0,0 +1,13 @@
1
+ import cx from "classnames";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/FilterPill.tsx
4
+ function FilterPill({ active, onClick, children }) {
5
+ return /* @__PURE__ */ jsx("button", {
6
+ type: "button",
7
+ onClick,
8
+ className: cx("px-3 py-1.5 text-xs font-medium rounded-full border transition-all duration-200", active ? "bg-[var(--theme-panel-bg)] border-[var(--theme-border)] text-[var(--theme-panel)] shadow-sm" : "bg-transparent border-transparent text-[var(--theme-muted-text-color)] hover:text-[var(--theme-panel)] hover:bg-[var(--theme-hover)]"),
9
+ children
10
+ });
11
+ }
12
+ //#endregion
13
+ export { FilterPill };
@@ -0,0 +1,34 @@
1
+ import { TOOLTIP_ID } from "./Tooltip.js";
2
+ import cx from "classnames";
3
+ import { forwardRef } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/IconButton.tsx
6
+ var IconButton = forwardRef(({ icon, label, variant = "default", size = "md", active = false, showTooltip = true, className, disabled, ...props }, ref) => {
7
+ const sizeClasses = {
8
+ sm: "w-7 h-7 [&_svg]:w-3.5 [&_svg]:h-3.5",
9
+ md: "w-9 h-9 [&_svg]:w-4 [&_svg]:h-4",
10
+ lg: "w-11 h-11 [&_svg]:w-5 [&_svg]:h-5"
11
+ };
12
+ const variantClasses = {
13
+ default: cx("bg-[var(--theme-muted-panel-bg)] text-[var(--theme-muted-text-color)]", "hover:bg-[var(--theme-border)] hover:text-[var(--theme-app)]", active && "bg-[var(--theme-element)]/10 text-[var(--theme-element)]"),
14
+ ghost: cx("bg-transparent text-[var(--theme-muted-text-color)]", "hover:bg-[var(--theme-muted-panel-bg)] hover:text-[var(--theme-app)]", active && "text-[var(--theme-element)]"),
15
+ primary: cx("bg-[var(--theme-element)] text-white", "hover:bg-[var(--theme-element)]/90", active && "ring-2 ring-[var(--theme-element)]/50"),
16
+ success: cx("bg-[#22c55e] text-white", "hover:bg-[#22c55e]/90", active && "ring-2 ring-[#22c55e]/50")
17
+ };
18
+ return /* @__PURE__ */ jsx("button", {
19
+ ref,
20
+ type: "button",
21
+ "aria-label": label,
22
+ disabled,
23
+ ...showTooltip ? { "data-tooltip-id": TOOLTIP_ID } : {},
24
+ "data-tooltip-content": label,
25
+ "data-tooltip-delay-show": 300,
26
+ "data-tooltip-class-name": "!bg-[var(--theme-app)] !text-[var(--theme-app-bg)] !text-xs !py-1 !px-2 !rounded-md",
27
+ className: cx("inline-flex items-center justify-center rounded-lg", "transition-all duration-200 cursor-pointer", "disabled:opacity-50 disabled:cursor-not-allowed", sizeClasses[size], variantClasses[variant], className),
28
+ ...props,
29
+ children: icon
30
+ });
31
+ });
32
+ IconButton.displayName = "IconButton";
33
+ //#endregion
34
+ export { IconButton };
@@ -36,4 +36,4 @@ function Indicator({ status }) {
36
36
  });
37
37
  }
38
38
  //#endregion
39
- export { Indicator as t };
39
+ export { Indicator };