@parallelworks/ui 0.2.0 → 0.3.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 (62) hide show
  1. package/README.md +5 -0
  2. package/dist/chunks/CodePreviewEditor-CSPRILMp.js +61 -0
  3. package/dist/chunks/Indicator-hBSIxOPK.js +39 -0
  4. package/dist/chunks/Markdown-C5Re2ezs.js +101 -0
  5. package/dist/chunks/{Indicator-fF8AVbjQ.js → Modal-sOUEwebV.js} +1 -38
  6. package/dist/chunks/{Monaco-CP_cL9gp.js → Monaco-CC4ak1JG.js} +3 -31
  7. package/dist/chunks/Provider-DvVvScTQ.js +391 -0
  8. package/dist/chunks/StatusBadge-DXp4zkSd.js +46 -0
  9. package/dist/chunks/{Table-DWuRINhu.js → SwitchToggle-2uRw8ZeJ.js} +2 -132
  10. package/dist/chunks/Table-C5z6qWjM.js +91 -0
  11. package/dist/chunks/editor-D55tumuZ.js +372 -0
  12. package/dist/chunks/list-7PyDF1tz.js +465 -0
  13. package/dist/components/Provider.d.ts +293 -0
  14. package/dist/editor/index.d.ts +1 -0
  15. package/dist/editor/index.js +2 -219
  16. package/dist/editor/useCssIsDark.d.ts +6 -0
  17. package/dist/file-explorer/FileExplorer.d.ts +23 -0
  18. package/dist/file-explorer/FileExplorerContext.d.ts +17 -0
  19. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +6 -0
  20. package/dist/file-explorer/FilePreview/Inline.d.ts +13 -0
  21. package/dist/file-explorer/FilePreview/StreamedBadge.d.ts +1 -0
  22. package/dist/file-explorer/FilePreview/Viewer.d.ts +15 -0
  23. package/dist/file-explorer/FilePreview/index.d.ts +15 -0
  24. package/dist/file-explorer/FilePreview/parse.d.ts +24 -0
  25. package/dist/file-explorer/FilePreview/previewCache.d.ts +26 -0
  26. package/dist/file-explorer/FilePreview/previewType.d.ts +21 -0
  27. package/dist/file-explorer/FilePreview/readCappedBytes.d.ts +37 -0
  28. package/dist/file-explorer/FilePreview/useObjectBlobUrl.d.ts +16 -0
  29. package/dist/file-explorer/FilePreview/useObjectText.d.ts +23 -0
  30. package/dist/file-explorer/FilePreview/usePresignedUrl.d.ts +12 -0
  31. package/dist/file-explorer/FileRow.d.ts +35 -0
  32. package/dist/file-explorer/FileRowsWindow.d.ts +43 -0
  33. package/dist/file-explorer/FileTable.d.ts +26 -0
  34. package/dist/file-explorer/FileTableHeaders.d.ts +13 -0
  35. package/dist/file-explorer/LoadMoreRow.d.ts +15 -0
  36. package/dist/file-explorer/TreeView.d.ts +28 -0
  37. package/dist/file-explorer/helpers.d.ts +47 -0
  38. package/dist/file-explorer/index.d.ts +10 -0
  39. package/dist/file-explorer/index.js +5646 -0
  40. package/dist/file-explorer/lib/batch.d.ts +3 -0
  41. package/dist/file-explorer/lib/errors.d.ts +3 -0
  42. package/dist/file-explorer/lib/fileExplorer.d.ts +32 -0
  43. package/dist/file-explorer/lib/paging.d.ts +93 -0
  44. package/dist/file-explorer/lib/types.d.ts +92 -0
  45. package/dist/file-explorer/lib/utils.d.ts +37 -0
  46. package/dist/file-explorer/toasts.d.ts +9 -0
  47. package/dist/file-explorer/treeRows.d.ts +35 -0
  48. package/dist/file-explorer/useNearEnd.d.ts +7 -0
  49. package/dist/form/index.js +4 -2
  50. package/dist/index.d.ts +1 -1
  51. package/dist/index.js +9 -101
  52. package/dist/list/ListTable.d.ts +63 -0
  53. package/dist/list/RowContextMenu.d.ts +113 -0
  54. package/dist/list/index.d.ts +2 -0
  55. package/dist/list/index.js +2 -0
  56. package/dist/logviewer/index.js +1 -1
  57. package/dist/styles/theme.css +30 -0
  58. package/dist/styles.css +1 -1
  59. package/dist/workflow/index.js +3 -2
  60. package/package.json +20 -3
  61. package/dist/chunks/Provider-C2VtPnh5.js +0 -151
  62. package/dist/chunks/workers-Cjfjb8E7.js +0 -119
package/README.md CHANGED
@@ -34,6 +34,11 @@ stylesheet instead:
34
34
  import '@parallelworks/ui/styles.css'
35
35
  ```
36
36
 
37
+ The prebuilt stylesheet nests all of its rules in the `pw-ui` cascade layer,
38
+ so loading it alongside other Parallel Works package stylesheets (for example
39
+ `@parallelworks/ai-chat/styles.css`, which uses the `pw-ai-chat` layer) is
40
+ order-independent.
41
+
37
42
  ## Icons
38
43
 
39
44
  ```tsx
@@ -0,0 +1,61 @@
1
+ import { i as getThemeName, n as setupMonacoWorkers, r as defineEditorThemes, t as useCssIsDark } from "./editor-D55tumuZ.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ import * as monaco from "monaco-editor";
5
+ //#region src/file-explorer/FilePreview/CodePreviewEditor.tsx
6
+ var OPTIONS = {
7
+ readOnly: true,
8
+ domReadOnly: true,
9
+ automaticLayout: true,
10
+ minimap: { enabled: false },
11
+ scrollBeyondLastLine: false,
12
+ renderLineHighlight: "none",
13
+ overviewRulerLanes: 0,
14
+ hideCursorInOverviewRuler: true,
15
+ lineNumbers: "on",
16
+ wordWrap: "off",
17
+ fontSize: 12,
18
+ scrollbar: { alwaysConsumeMouseWheel: false }
19
+ };
20
+ setupMonacoWorkers();
21
+ function CodePreviewEditor({ value, language }) {
22
+ const isDark = useCssIsDark();
23
+ const editorRef = useRef(null);
24
+ useEffect(() => {
25
+ return () => {
26
+ editorRef.current?.getModel()?.dispose();
27
+ editorRef.current?.dispose();
28
+ editorRef.current = null;
29
+ };
30
+ }, []);
31
+ useEffect(() => {
32
+ const model = editorRef.current?.getModel();
33
+ if (model && model.getValue() !== value) model.setValue(value);
34
+ }, [value]);
35
+ useEffect(() => {
36
+ const model = editorRef.current?.getModel();
37
+ if (model) monaco.editor.setModelLanguage(model, language);
38
+ }, [language]);
39
+ useEffect(() => {
40
+ if (editorRef.current) {
41
+ defineEditorThemes(monaco.editor);
42
+ monaco.editor.setTheme(getThemeName(isDark));
43
+ }
44
+ }, [isDark]);
45
+ return /* @__PURE__ */ jsx("div", {
46
+ className: "h-full w-full",
47
+ ref: (container) => {
48
+ if (container && !editorRef.current) {
49
+ defineEditorThemes(monaco.editor);
50
+ const model = monaco.editor.createModel(value, language);
51
+ editorRef.current = monaco.editor.create(container, {
52
+ ...OPTIONS,
53
+ model
54
+ });
55
+ monaco.editor.setTheme(getThemeName(isDark));
56
+ }
57
+ }
58
+ });
59
+ }
60
+ //#endregion
61
+ export { CodePreviewEditor as default };
@@ -0,0 +1,39 @@
1
+ import { CancelIcon, FailIcon, NotRunningIcon, RunningIcon, SkipIcon, SuccessIcon } from "../icons.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/components/Indicator.tsx
4
+ function Indicator({ status }) {
5
+ return /* @__PURE__ */ jsx("div", {
6
+ className: "h-2 flex items-center text-(--theme-panel-bg)",
7
+ children: status === "started" || status === "running" ? /* @__PURE__ */ jsx(RunningIcon, {
8
+ className: "rounded-full text-[#FFCF00] animate-spin",
9
+ "data-testid": "running-indicator"
10
+ }) : status === "completed" ? /* @__PURE__ */ jsx(SuccessIcon, {
11
+ className: "text-[#6FBF5A]",
12
+ style: { transform: "scale(1.25)" },
13
+ "data-testid": "completed-indicator"
14
+ }) : status === "failed" || status === "error" ? /* @__PURE__ */ jsx(FailIcon, {
15
+ className: "text-red-500",
16
+ style: { transform: "scale(1.25)" },
17
+ "data-testid": "failed-indicator"
18
+ }) : status === "skipped" || status === "skipped-failed" ? /* @__PURE__ */ jsx(SkipIcon, {
19
+ className: "text-gray-400",
20
+ style: { transform: "scale(1.25)" },
21
+ "data-testid": "skipped-indicator"
22
+ }) : status === "canceled" ? /* @__PURE__ */ jsx(CancelIcon, {
23
+ className: "text-[#3B82F6]",
24
+ style: { transform: "scale(1.5)" },
25
+ "data-testid": "canceled-indicator"
26
+ }) : status === "faulted" ? /* @__PURE__ */ jsx(RunningIcon, {
27
+ className: "rounded-full text-[#EF4444] animate-spin",
28
+ "data-testid": "faulted-indicator"
29
+ }) : status === "canceling" ? /* @__PURE__ */ jsx(RunningIcon, {
30
+ className: "rounded-full text-[#3B82F6] animate-spin",
31
+ "data-testid": "canceling-indicator"
32
+ }) : /* @__PURE__ */ jsx(NotRunningIcon, {
33
+ className: "rounded-full text-[#AAAAAA]",
34
+ "data-testid": "not-running-indicator"
35
+ })
36
+ });
37
+ }
38
+ //#endregion
39
+ export { Indicator as t };
@@ -0,0 +1,101 @@
1
+ import { AlertIcon, CheckIcon, ClipboardIcon, CopyIcon, HiddenFalseIcon, HiddenTrueIcon, InfoIcon } from "../icons.js";
2
+ import { i as useNotify } from "./Provider-DvVvScTQ.js";
3
+ import cx from "classnames";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { Suspense, lazy, useState } from "react";
6
+ //#region src/components/Callout.tsx
7
+ function CalloutIcon({ type }) {
8
+ if (type === "warning" || type === "error") return /* @__PURE__ */ jsx(AlertIcon, { className: "h-6 w-6 mr-4 text-lg" });
9
+ else return /* @__PURE__ */ jsx(InfoIcon, { className: "h-6 w-6 mr-4 text-lg" });
10
+ }
11
+ function Callout({ type, className = "", children }) {
12
+ return /* @__PURE__ */ jsx("div", {
13
+ 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"),
14
+ role: "alert",
15
+ children: /* @__PURE__ */ jsxs("div", {
16
+ className: "flex",
17
+ children: [/* @__PURE__ */ jsx("div", {
18
+ className: "py-1",
19
+ children: /* @__PURE__ */ jsx(CalloutIcon, { type })
20
+ }), /* @__PURE__ */ jsx("div", { children })]
21
+ })
22
+ });
23
+ }
24
+ //#endregion
25
+ //#region src/components/CopyToClipboard.tsx
26
+ function CopyToClipboard({ as = "div", text, className, children, showIcon = true }) {
27
+ const notify = useNotify();
28
+ const handleCopy = async () => {
29
+ try {
30
+ await navigator.clipboard.writeText(text);
31
+ notify.info("Copied to clipboard");
32
+ } catch {
33
+ notify.error("Failed to copy to clipboard");
34
+ }
35
+ };
36
+ return /* @__PURE__ */ jsxs(as, {
37
+ className,
38
+ onClick: handleCopy,
39
+ ...as === "button" ? { type: "button" } : {},
40
+ children: [showIcon && /* @__PURE__ */ jsx(ClipboardIcon, {}), children]
41
+ });
42
+ }
43
+ function CopyCodeBlock({ textToCopy, children, secret = false, isRevealed = false, onRevealToggle }) {
44
+ const notify = useNotify();
45
+ const [copied, setCopied] = useState(false);
46
+ const handleCopy = async () => {
47
+ if (copied) return;
48
+ try {
49
+ await navigator.clipboard.writeText(textToCopy);
50
+ setCopied(true);
51
+ notify.info("Copied to clipboard");
52
+ setTimeout(() => setCopied(false), 2e3);
53
+ } catch {
54
+ notify.error("Failed to copy to clipboard");
55
+ }
56
+ };
57
+ return /* @__PURE__ */ jsxs("div", {
58
+ className: "group relative",
59
+ onClick: handleCopy,
60
+ children: [/* @__PURE__ */ jsx("pre", {
61
+ className: `p-4 theme-hover border rounded-lg text-left font-mono text-sm overflow-x-auto ${secret ? "pr-24" : "pr-12"}`,
62
+ children
63
+ }), /* @__PURE__ */ jsxs("div", {
64
+ 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",
65
+ children: [secret && /* @__PURE__ */ jsx("button", {
66
+ type: "button",
67
+ onClick: (e) => {
68
+ e.stopPropagation();
69
+ onRevealToggle?.();
70
+ },
71
+ className: "p-2 rounded-md opacity-0 group-hover:opacity-100 transition-all duration-150",
72
+ "aria-label": isRevealed ? "Hide secret" : "Reveal secret",
73
+ title: isRevealed ? "Hide secret" : "Reveal secret",
74
+ children: isRevealed ? /* @__PURE__ */ jsx(HiddenFalseIcon, {}) : /* @__PURE__ */ jsx(HiddenTrueIcon, {})
75
+ }), /* @__PURE__ */ jsx("button", {
76
+ type: "button",
77
+ onClick: (e) => {
78
+ e.stopPropagation();
79
+ handleCopy();
80
+ },
81
+ className: "p-2 rounded-md opacity-0 group-hover:opacity-100 transition-all duration-150",
82
+ "aria-label": copied ? "Copied" : "Copy to clipboard",
83
+ children: copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-green-400" }) : /* @__PURE__ */ jsx(CopyIcon, {})
84
+ })]
85
+ })]
86
+ });
87
+ }
88
+ //#endregion
89
+ //#region src/components/Markdown.tsx
90
+ var MarkdownImpl = lazy(() => import("./MarkdownImpl-Bq4QhrtA.js"));
91
+ function Markdown(props) {
92
+ return /* @__PURE__ */ jsx(Suspense, {
93
+ fallback: /* @__PURE__ */ jsx("div", {
94
+ className: "markdown whitespace-pre-wrap text-start w-full",
95
+ children: props.children
96
+ }),
97
+ children: /* @__PURE__ */ jsx(MarkdownImpl, { ...props })
98
+ });
99
+ }
100
+ //#endregion
101
+ export { Callout as i, CopyCodeBlock as n, CopyToClipboard as r, Markdown as t };
@@ -1,4 +1,3 @@
1
- import { CancelIcon, FailIcon, NotRunningIcon, RunningIcon, SkipIcon, SuccessIcon } from "../icons.js";
2
1
  import cx from "classnames";
3
2
  import { jsx, jsxs } from "react/jsx-runtime";
4
3
  import { useCallback, useEffect, useId, useRef, useState } from "react";
@@ -119,40 +118,4 @@ function Modal({ isOpen, close, cancelAction = noop, children, title = "", text
119
118
  }), document.body);
120
119
  }
121
120
  //#endregion
122
- //#region src/components/Indicator.tsx
123
- function Indicator({ status }) {
124
- return /* @__PURE__ */ jsx("div", {
125
- className: "h-2 flex items-center text-(--theme-panel-bg)",
126
- children: status === "started" || status === "running" ? /* @__PURE__ */ jsx(RunningIcon, {
127
- className: "rounded-full text-[#FFCF00] animate-spin",
128
- "data-testid": "running-indicator"
129
- }) : status === "completed" ? /* @__PURE__ */ jsx(SuccessIcon, {
130
- className: "text-[#6FBF5A]",
131
- style: { transform: "scale(1.25)" },
132
- "data-testid": "completed-indicator"
133
- }) : status === "failed" || status === "error" ? /* @__PURE__ */ jsx(FailIcon, {
134
- className: "text-red-500",
135
- style: { transform: "scale(1.25)" },
136
- "data-testid": "failed-indicator"
137
- }) : status === "skipped" || status === "skipped-failed" ? /* @__PURE__ */ jsx(SkipIcon, {
138
- className: "text-gray-400",
139
- style: { transform: "scale(1.25)" },
140
- "data-testid": "skipped-indicator"
141
- }) : status === "canceled" ? /* @__PURE__ */ jsx(CancelIcon, {
142
- className: "text-[#3B82F6]",
143
- style: { transform: "scale(1.5)" },
144
- "data-testid": "canceled-indicator"
145
- }) : status === "faulted" ? /* @__PURE__ */ jsx(RunningIcon, {
146
- className: "rounded-full text-[#EF4444] animate-spin",
147
- "data-testid": "faulted-indicator"
148
- }) : status === "canceling" ? /* @__PURE__ */ jsx(RunningIcon, {
149
- className: "rounded-full text-[#3B82F6] animate-spin",
150
- "data-testid": "canceling-indicator"
151
- }) : /* @__PURE__ */ jsx(NotRunningIcon, {
152
- className: "rounded-full text-[#AAAAAA]",
153
- "data-testid": "not-running-indicator"
154
- })
155
- });
156
- }
157
- //#endregion
158
- export { Modal as n, Indicator as t };
121
+ export { Modal as t };
@@ -1,8 +1,8 @@
1
- import { s as useWorkflowJsonResolver } from "./Provider-C2VtPnh5.js";
2
- import { n as defineEditorThemes, r as getThemeName, t as setupMonacoWorkers } from "./workers-Cjfjb8E7.js";
1
+ import { l as useWorkflowJsonResolver } from "./Provider-DvVvScTQ.js";
2
+ import { i as getThemeName, n as setupMonacoWorkers, r as defineEditorThemes, t as useCssIsDark } from "./editor-D55tumuZ.js";
3
3
  import cx from "classnames";
4
4
  import { jsx } from "react/jsx-runtime";
5
- import { useEffect, useRef, useState } from "react";
5
+ import { useEffect, useRef } from "react";
6
6
  import { dumpYaml } from "@parallelworks/workflow-parser";
7
7
  import yaml from "js-yaml";
8
8
  import * as monaco from "monaco-editor";
@@ -10,34 +10,6 @@ import { configureMonacoYaml } from "monaco-yaml";
10
10
  //#region src/editor/Monaco.tsx
11
11
  setupMonacoWorkers();
12
12
  var activeWorkflowJsonResolver;
13
- function readIsDark() {
14
- const scheme = getComputedStyle(document.documentElement).colorScheme;
15
- const dark = scheme.includes("dark");
16
- if (dark !== scheme.includes("light")) return dark;
17
- return window.matchMedia("(prefers-color-scheme: dark)").matches;
18
- }
19
- function useCssIsDark() {
20
- const [isDark, setIsDark] = useState(readIsDark);
21
- useEffect(() => {
22
- const update = () => setIsDark(readIsDark());
23
- const media = window.matchMedia("(prefers-color-scheme: dark)");
24
- media.addEventListener("change", update);
25
- const observer = new MutationObserver(update);
26
- observer.observe(document.documentElement, {
27
- attributes: true,
28
- attributeFilter: [
29
- "style",
30
- "class",
31
- "data-theme"
32
- ]
33
- });
34
- return () => {
35
- media.removeEventListener("change", update);
36
- observer.disconnect();
37
- };
38
- }, []);
39
- return isDark;
40
- }
41
13
  var monacoWithWorkerBridge = {
42
14
  ...monaco,
43
15
  editor: {