@parallelworks/ui 0.50.0 → 0.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +50 -5
  2. package/dist/ai/components/ModelSelector.js +1 -1
  3. package/dist/ai/components/agent/AgentMessageParts.js +3 -3
  4. package/dist/components/Callout.js +3 -7
  5. package/dist/components/CreateModal.js +1 -1
  6. package/dist/components/DescriptionList.d.ts +31 -17
  7. package/dist/components/DescriptionList.js +83 -31
  8. package/dist/components/Field.js +1 -1
  9. package/dist/components/MenuEntries.d.ts +39 -12
  10. package/dist/components/MenuEntries.js +24 -8
  11. package/dist/components/Meter.js +3 -3
  12. package/dist/components/PageHeader.js +1 -1
  13. package/dist/components/Provider.d.ts +2 -0
  14. package/dist/components/Provider.js +1 -0
  15. package/dist/components/RequiredMark.js +1 -1
  16. package/dist/components/RunStatusIcon.js +2 -2
  17. package/dist/components/StatusIcons.js +2 -2
  18. package/dist/components/ThemeEditor.js +6 -6
  19. package/dist/components/Toast.js +2 -2
  20. package/dist/components/buttonClasses.js +1 -1
  21. package/dist/components/tone.d.ts +5 -2
  22. package/dist/components/tone.js +15 -6
  23. package/dist/form/Wizard/WizardNavigation.js +1 -1
  24. package/dist/form/Wizard/WizardStepIndicator.js +1 -1
  25. package/dist/graph/DependencyGraph.js +1 -1
  26. package/dist/graph/GraphEditor.js +1 -1
  27. package/dist/graph/GraphEditorDialogs.js +1 -1
  28. package/dist/graph/ProblemsButton.js +2 -2
  29. package/dist/graph/ShortcutsButton.js +1 -1
  30. package/dist/graph/editorChrome.js +1 -1
  31. package/dist/graph/fieldProblems.js +1 -1
  32. package/dist/graph/stepWith.js +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.js +2 -2
  35. package/dist/list/ActionToolbar.d.ts +2 -2
  36. package/dist/list/ActionToolbar.js +6 -3
  37. package/dist/list/ListPage.js +4 -2
  38. package/dist/list/ListViewControls.js +1 -1
  39. package/dist/list/rowMenu.d.ts +2 -2
  40. package/dist/logviewer/LogViewer.js +1 -1
  41. package/dist/styles/theme.css +24 -10
  42. package/dist/styles.css +1 -1
  43. package/dist/theme/derive.d.ts +1 -1
  44. package/dist/theme/derive.js +46 -21
  45. package/dist/theme/fit.js +10 -4
  46. package/package.json +1 -1
@@ -1,6 +1,15 @@
1
1
  //#region src/components/tone.ts
2
2
  /** Text in the tone, for a status line beside a dot or icon. */
3
3
  var toneText = {
4
+ default: "text-(--theme-app)",
5
+ success: "text-(--theme-success-text)",
6
+ warning: "text-(--theme-warning-text)",
7
+ error: "text-(--theme-error-text)",
8
+ info: "text-(--theme-info-text)",
9
+ muted: "text-(--theme-muted-text-color)"
10
+ };
11
+ /** An icon in the tone, through `currentColor`. */
12
+ var toneIcon = {
4
13
  default: "text-(--theme-app)",
5
14
  success: "text-(--theme-success)",
6
15
  warning: "text-(--theme-warning)",
@@ -11,13 +20,13 @@ var toneText = {
11
20
  /** A tinted surface with a border and text in the tone, for a badge or a callout. */
12
21
  var toneSurface = {
13
22
  default: "bg-(--theme-muted-panel-bg) text-(--theme-app) border-(--theme-border)",
14
- success: "bg-(--theme-success-muted) text-(--theme-success) border-(--theme-success)/25",
15
- warning: "bg-(--theme-warning-muted) text-(--theme-warning) border-(--theme-warning)/25",
16
- error: "bg-(--theme-error-muted) text-(--theme-error) border-(--theme-error)/25",
17
- info: "bg-(--theme-info-muted) text-(--theme-info) border-(--theme-info)/25",
23
+ success: "bg-(--theme-success-muted) text-(--theme-success-text) border-(--theme-success)/25",
24
+ warning: "bg-(--theme-warning-muted) text-(--theme-warning-text) border-(--theme-warning)/25",
25
+ error: "bg-(--theme-error-muted) text-(--theme-error-text) border-(--theme-error)/25",
26
+ info: "bg-(--theme-info-muted) text-(--theme-info-text) border-(--theme-info)/25",
18
27
  muted: "bg-(--theme-muted-panel-bg)/50 text-(--theme-muted-text-color) border-(--theme-border)"
19
28
  };
20
- /** A solid fill in the tone, for a dot. */
29
+ /** A solid fill in the tone, for a dot or a bar. */
21
30
  var toneFill = {
22
31
  default: "bg-(--theme-app)",
23
32
  success: "bg-(--theme-success)",
@@ -27,4 +36,4 @@ var toneFill = {
27
36
  muted: "bg-(--theme-muted-text-color)"
28
37
  };
29
38
  //#endregion
30
- export { toneFill, toneSurface, toneText };
39
+ export { toneFill, toneIcon, toneSurface, toneText };
@@ -33,7 +33,7 @@ function WizardNavigation({ isLastStep, canGoBack, isCurrentStepValid, nextLabel
33
33
  };
34
34
  return /* @__PURE__ */ jsxs("div", { children: [error && /* @__PURE__ */ jsxs("p", {
35
35
  role: "alert",
36
- className: "mb-3 flex items-center gap-1.5 text-sm text-(--theme-error)",
36
+ className: "mb-3 flex items-center gap-1.5 text-sm text-(--theme-error-text)",
37
37
  children: [/* @__PURE__ */ jsx(WarningIcon, {
38
38
  "aria-hidden": "true",
39
39
  className: "size-4 shrink-0"
@@ -80,7 +80,7 @@ function StepItem({ number, title, description, status, onJump }) {
80
80
  children: strings.stepDone
81
81
  }),
82
82
  status === "invalid" && /* @__PURE__ */ jsx("span", {
83
- className: "text-xs text-(--theme-error)",
83
+ className: "text-xs text-(--theme-error-text)",
84
84
  children: strings.stepNeedsAttention
85
85
  }),
86
86
  description && /* @__PURE__ */ jsx("span", {
@@ -5,8 +5,8 @@ import { useRunFile, useSlots, useStrings, useWorkflowEngine } from "../componen
5
5
  import { Button } from "../components/Button.js";
6
6
  import { Modal } from "../components/Modal.js";
7
7
  import { DisclosurePanel } from "../components/Disclosure.js";
8
- import { InfoTip } from "../components/InfoTip.js";
9
8
  import { IconButton } from "../components/IconButton.js";
9
+ import { InfoTip } from "../components/InfoTip.js";
10
10
  import { formatDateTime } from "../format.js";
11
11
  import { Elapsed } from "../components/relativeTime.js";
12
12
  import { RunStatusIcon } from "../components/RunStatusIcon.js";
@@ -1461,7 +1461,7 @@ function DragOverlays({ api, container, trashRef }) {
1461
1461
  const problem = drag.target?.kind === "steps" ? drag.target.problem : void 0;
1462
1462
  return /* @__PURE__ */ jsxs(Fragment, { children: [drag.payload.kind === "jobs" && /* @__PURE__ */ jsxs("div", {
1463
1463
  ref: trashRef,
1464
- className: cx("absolute bottom-2 left-1/2 z-20 flex -translate-x-1/2 items-center gap-2 rounded-lg border-2 border-dashed px-4 py-2 text-sm", overTrash ? "border-(--theme-error) bg-(--theme-error-muted) text-(--theme-error)" : "theme-border bg-(--theme-panel-bg) theme-muted-text"),
1464
+ className: cx("absolute bottom-2 left-1/2 z-20 flex -translate-x-1/2 items-center gap-2 rounded-lg border-2 border-dashed px-4 py-2 text-sm", overTrash ? "border-(--theme-error) bg-(--theme-error-muted) text-(--theme-error-text)" : "theme-border bg-(--theme-panel-bg) theme-muted-text"),
1465
1465
  children: [/* @__PURE__ */ jsx(TrashIcon, { className: "h-4 w-4" }), t.dropToDelete]
1466
1466
  }), drag.payload.kind !== "connect" && /* @__PURE__ */ jsx(DragLabel, {
1467
1467
  at: {
@@ -722,7 +722,7 @@ function JobForm({ job, jobs, inputs, workflow, onEdit, onClose, renderShell, on
722
722
  children: other
723
723
  }),
724
724
  !Object.hasOwn(jobs, other) && /* @__PURE__ */ jsx("span", {
725
- className: "text-xs text-(--theme-error)",
725
+ className: "text-xs text-(--theme-error-text)",
726
726
  children: t.missingJob
727
727
  })
728
728
  ]
@@ -24,7 +24,7 @@ function ProblemsButton({ problems }) {
24
24
  children: /* @__PURE__ */ jsxs("button", {
25
25
  type: "button",
26
26
  "aria-label": label,
27
- className: "flex h-7 cursor-pointer items-center gap-1 rounded px-2 text-xs font-medium text-(--theme-error) theme-hover",
27
+ className: "flex h-7 cursor-pointer items-center gap-1 rounded px-2 text-xs font-medium text-(--theme-error-text) theme-hover",
28
28
  children: [/* @__PURE__ */ jsx(WarningIcon, { className: "h-3.5 w-3.5" }), problems.length]
29
29
  })
30
30
  }),
@@ -36,7 +36,7 @@ function ProblemsButton({ problems }) {
36
36
  className: "mr-1.5 theme-muted-text",
37
37
  children: t.problemLine(problem.line)
38
38
  }), /* @__PURE__ */ jsx("span", {
39
- className: "text-(--theme-error)",
39
+ className: "text-(--theme-error-text)",
40
40
  children: problem.message
41
41
  })] });
42
42
  return /* @__PURE__ */ jsx("li", { children: pick ? /* @__PURE__ */ jsx("button", {
@@ -1,6 +1,6 @@
1
1
  import { KeyboardIcon } from "../icons.js";
2
- import { Popover } from "../components/Popover.js";
3
2
  import { IconButton } from "../components/IconButton.js";
3
+ import { Popover } from "../components/Popover.js";
4
4
  import { useGraphEditorStrings } from "./editorStrings.js";
5
5
  import { toolbarPanel } from "./toolbarPanel.js";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -10,7 +10,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
10
  /** What a drag carries, beside the pointer at `at` in its layer's coordinates. */
11
11
  function DragLabel({ at, text, refused = false }) {
12
12
  return /* @__PURE__ */ jsx("div", {
13
- className: cx("pointer-events-none absolute z-30 rounded-md border bg-(--theme-panel-bg) px-2 py-1 text-xs shadow", refused ? "border-(--theme-error) text-(--theme-error)" : "theme-border"),
13
+ className: cx("pointer-events-none absolute z-30 rounded-md border bg-(--theme-panel-bg) px-2 py-1 text-xs shadow", refused ? "border-(--theme-error) text-(--theme-error-text)" : "theme-border"),
14
14
  style: {
15
15
  left: at.x + 12,
16
16
  top: at.y + 12
@@ -92,7 +92,7 @@ function ProblemList({ problems }) {
92
92
  if (problems.length === 0) return null;
93
93
  const fieldOf = (problem) => [...fields ?? []].filter(([key]) => within(problem, key)).sort(([a], [b]) => b.length - a.length)[0]?.[1];
94
94
  return /* @__PURE__ */ jsx("ul", {
95
- className: "flex flex-col gap-1 text-sm text-(--theme-error)",
95
+ className: "flex flex-col gap-1 text-sm text-(--theme-error-text)",
96
96
  children: keyedByContent(problems, (problem) => `${problem.at.join(".")}:${problem.message}`).map(({ key, item: problem }) => {
97
97
  const field = fieldOf(problem);
98
98
  return /* @__PURE__ */ jsxs("li", {
@@ -515,7 +515,7 @@ function ExtraKey({ name, uses, draft, original, onChange }) {
515
515
  children: name
516
516
  }),
517
517
  /* @__PURE__ */ jsx("span", {
518
- className: "text-xs text-(--theme-error)",
518
+ className: "text-xs text-(--theme-error-text)",
519
519
  children: t.notActionInput
520
520
  }),
521
521
  /* @__PURE__ */ jsx(IconButton, {
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export { type OpenMenu, type OpenMenuOptions, useContextMenu, } from './componen
13
13
  export { CopyCodeBlock, default as CopyToClipboard } from './components/CopyToClipboard.js';
14
14
  export { CreateModal, CreateModalSelect, CreateModalSwitch, } from './components/CreateModal.js';
15
15
  export { DatePicker, type DatePickerProps } from './components/DatePicker.js';
16
- export { DescriptionListItem, default as DescriptionList } from './components/DescriptionList.js';
16
+ export { DescriptionListItem, type DescriptionListItemProps, type DescriptionListProps, type DescriptionListVariant, default as DescriptionList, } from './components/DescriptionList.js';
17
17
  export { Disclosure, DisclosurePanel, type DisclosureProps } from './components/Disclosure.js';
18
18
  export { Drawer, type DrawerProps } from './components/Drawer.js';
19
19
  export { EmptyState, type EmptyStateProps } from './components/EmptyState.js';
package/dist/index.js CHANGED
@@ -35,14 +35,14 @@ import { Disclosure, DisclosurePanel } from "./components/Disclosure.js";
35
35
  import { Switch } from "./components/Switch.js";
36
36
  import { CreateModal, CreateModalSelect, CreateModalSwitch } from "./components/CreateModal.js";
37
37
  import { DatePicker } from "./components/DatePicker.js";
38
+ import { isTextEntryContext, useShortcutKey } from "./components/shortcutKey.js";
39
+ import { IconButton } from "./components/IconButton.js";
38
40
  import { ExternalLink } from "./components/ExternalLink.js";
39
41
  import { Popover, PopoverClose, useClosePopover } from "./components/Popover.js";
40
42
  import { InfoTip, formatInfoTipContent } from "./components/InfoTip.js";
41
43
  import DescriptionList, { DescriptionListItem } from "./components/DescriptionList.js";
42
44
  import { Drawer } from "./components/Drawer.js";
43
45
  import { HoverCard } from "./components/HoverCard.js";
44
- import { isTextEntryContext, useShortcutKey } from "./components/shortcutKey.js";
45
- import { IconButton } from "./components/IconButton.js";
46
46
  import { LetterBadge } from "./components/LetterBadge.js";
47
47
  import Markdown from "./components/Markdown.js";
48
48
  import { Meter, ProgressBar, levelTone } from "./components/Meter.js";
@@ -1,10 +1,10 @@
1
1
  import type { RowAction } from './rowMenu.js';
2
2
  /** A toolbar button, which moves into the `…` menu as a row when the toolbar runs out of room. */
3
- export interface ToolbarAction extends RowAction {
3
+ export type ToolbarAction = RowAction & {
4
4
  /** A hint on the enabled button. */
5
5
  tooltip?: string | undefined;
6
6
  hidden?: boolean;
7
- }
7
+ };
8
8
  /** A pre-rendered element (e.g. a button component that owns its modal). */
9
9
  interface ToolbarElement {
10
10
  key: string;
@@ -4,7 +4,7 @@ import { MenuPopup } from "../components/Menu.js";
4
4
  import { buttonClasses } from "../components/buttonClasses.js";
5
5
  import { Tooltip } from "../components/Tooltip.js";
6
6
  import { useLink, useStrings } from "../components/Provider.js";
7
- import { MenuEntries } from "../components/MenuEntries.js";
7
+ import { MenuEntries, useRunAction, warnIfInert } from "../components/MenuEntries.js";
8
8
  import { Button } from "../components/Button.js";
9
9
  import { Menu } from "@base-ui/react/menu";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -20,12 +20,15 @@ function ToolbarItemView({ item }) {
20
20
  function ToolbarButton({ action }) {
21
21
  const inOverflowMenu = useContext(OverflowMenuContext);
22
22
  const Link = useLink();
23
+ const runAction = useRunAction();
23
24
  if (inOverflowMenu) return /* @__PURE__ */ jsx(MenuEntries, { entries: [action] });
24
25
  const className = buttonClasses({
25
26
  variant: action.checked === false ? "outline" : "primary",
26
27
  size: "md"
27
28
  });
28
29
  const content = /* @__PURE__ */ jsxs(Fragment, { children: [action.icon, action.label] });
30
+ warnIfInert(action, "ActionToolbar");
31
+ const run = () => runAction(action);
29
32
  let control;
30
33
  if (action.href && !action.disabled) control = /* @__PURE__ */ jsx(Link, {
31
34
  href: action.href,
@@ -34,7 +37,7 @@ function ToolbarButton({ action }) {
34
37
  });
35
38
  else if (action.checked !== void 0) control = /* @__PURE__ */ jsx(Toggle, {
36
39
  pressed: action.checked,
37
- onPressedChange: () => action.onClick?.(),
40
+ onPressedChange: run,
38
41
  disabled: action.disabled,
39
42
  className,
40
43
  children: content
@@ -42,7 +45,7 @@ function ToolbarButton({ action }) {
42
45
  else control = /* @__PURE__ */ jsx(Button, {
43
46
  variant: "primary",
44
47
  size: "md",
45
- onClick: action.onClick,
48
+ onClick: run,
46
49
  disabled: action.disabled,
47
50
  focusableWhenDisabled: true,
48
51
  children: content
@@ -1,7 +1,7 @@
1
1
  import { cx } from "../cx.js";
2
2
  import { Tooltip } from "../components/Tooltip.js";
3
3
  import { useLink, useNavigation } from "../components/Provider.js";
4
- import { isMenuDivider, isMenuSubmenu } from "../components/MenuEntries.js";
4
+ import { isMenuDivider, isMenuSubmenu, useRunAction, warnIfInert } from "../components/MenuEntries.js";
5
5
  import { PageHeader } from "../components/PageHeader.js";
6
6
  import { Table } from "../components/Table.js";
7
7
  import { ListActionsHeader } from "./ListTable.js";
@@ -136,7 +136,9 @@ function ListRow({ href, onActivate, items, goTo, openMenu, pinnedActions, selec
136
136
  });
137
137
  }
138
138
  function PinnedActionButton({ action, visible }) {
139
+ warnIfInert(action, "ListPage pinned action");
139
140
  const Link = useLink();
141
+ const runAction = useRunAction();
140
142
  const reason = action.disabled ? action.disabledReason : void 0;
141
143
  const props = {
142
144
  "aria-label": reason ? `${action.label}. ${reason}` : action.label,
@@ -154,7 +156,7 @@ function PinnedActionButton({ action, visible }) {
154
156
  "aria-disabled": action.disabled,
155
157
  onClick: (e) => {
156
158
  e.stopPropagation();
157
- if (!action.disabled) action.onClick?.();
159
+ if (!action.disabled) runAction(action);
158
160
  },
159
161
  ...props,
160
162
  children: action.icon
@@ -5,9 +5,9 @@ import { Tooltip } from "../components/Tooltip.js";
5
5
  import { useStrings } from "../components/Provider.js";
6
6
  import { useQueryMatch } from "../components/search.js";
7
7
  import { Switch } from "../components/Switch.js";
8
+ import { IconButton } from "../components/IconButton.js";
8
9
  import { Popover } from "../components/Popover.js";
9
10
  import { InfoTip } from "../components/InfoTip.js";
10
- import { IconButton } from "../components/IconButton.js";
11
11
  import { Select } from "../components/Select.js";
12
12
  import { Menu } from "@base-ui/react/menu";
13
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -2,9 +2,9 @@ import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react';
2
2
  import type { OpenMenu } from '../components/ContextMenu.js';
3
3
  import type { MenuAction, MenuEntry, MenuSubmenu } from '../components/MenuEntries.js';
4
4
  /** An action on a row, which its menu lists and its pinned buttons show, named by `key`. */
5
- export interface RowAction extends MenuAction {
5
+ export type RowAction = MenuAction & {
6
6
  key: string;
7
- }
7
+ };
8
8
  /** Assembles a row's context menu in the shared order: leading link(s) → middle
9
9
  * actions → extra items → Copy submenu → trailing (destructive) actions last. */
10
10
  export declare function assembleRowMenu({ lead, actions, exclude, order, trailing, extra, copy, }: {
@@ -6,9 +6,9 @@ import { useOptionalWorkflowEngine, useStrings } from "../components/Provider.js
6
6
  import { useCopy } from "../components/useCopy.js";
7
7
  import { Button } from "../components/Button.js";
8
8
  import { DatePicker } from "../components/DatePicker.js";
9
+ import { IconButton } from "../components/IconButton.js";
9
10
  import { Popover } from "../components/Popover.js";
10
11
  import { InfoTip } from "../components/InfoTip.js";
11
- import { IconButton } from "../components/IconButton.js";
12
12
  import { SearchInput } from "../components/SearchInput.js";
13
13
  import { highlightSegments, parseAnsiSegments, plainSegments } from "./segments.js";
14
14
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -29,16 +29,26 @@
29
29
  --theme-accent-subtle: #d3ebfc;
30
30
  --theme-focus: #06354f;
31
31
  --theme-focus-ring: rgba(6, 53, 79, 0.25);
32
- --theme-success: #005f23;
33
- --theme-success-muted: rgba(0, 95, 35, 0.1);
34
- --theme-error: #95050f;
35
- --theme-error-muted: rgba(149, 5, 15, 0.1);
36
- --theme-warning: #794800;
37
- --theme-warning-muted: rgba(121, 72, 0, 0.1);
38
- --theme-info: #004caa;
39
- --theme-info-muted: rgba(0, 76, 170, 0.1);
40
- --theme-favorite: #920242;
41
- --theme-favorite-muted: rgba(146, 2, 66, 0.1);
32
+ --theme-success: #00973d;
33
+ --theme-success-text: #006226;
34
+ --theme-success-solid: #00873c;
35
+ --theme-success-muted: rgba(0, 151, 61, 0.1);
36
+ --theme-error: #ea4841;
37
+ --theme-error-text: #a11a1b;
38
+ --theme-error-solid: #db3934;
39
+ --theme-error-muted: rgba(234, 72, 65, 0.1);
40
+ --theme-warning: #bd7100;
41
+ --theme-warning-text: #7b4a00;
42
+ --theme-warning-solid: #a76900;
43
+ --theme-warning-muted: rgba(189, 113, 0, 0.1);
44
+ --theme-info: #0681f8;
45
+ --theme-info-text: #0050af;
46
+ --theme-info-solid: #0073e8;
47
+ --theme-info-muted: rgba(6, 129, 248, 0.1);
48
+ --theme-favorite: #e7457a;
49
+ --theme-favorite-text: #9e174b;
50
+ --theme-favorite-solid: #d7366e;
51
+ --theme-favorite-muted: rgba(231, 69, 122, 0.1);
42
52
  --theme-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.07);
43
53
  --theme-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.07);
44
54
  --theme-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.07), 0 4px 6px -4px rgba(0, 0, 0, 0.07);
@@ -64,6 +74,10 @@
64
74
 
65
75
  @media (color-gamut: p3) {
66
76
  :root {
77
+ --theme-success: color(display-p3 0.1559 0.5942 0.2459);
78
+ --theme-success-solid: color(display-p3 0.0738 0.5422 0.1959);
79
+ --theme-success-muted: color(display-p3 0.1559 0.5942 0.2459 / 0.1);
80
+ --theme-warning-solid: color(display-p3 0.6474 0.4089 0);
67
81
  --theme-ansi-cyan: color(display-p3 0 0.4024 0.4329);
68
82
  }
69
83
  }