@camstack/ui-library 1.2.261 → 1.2.263

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.
@@ -45,6 +45,11 @@ interface AddonGlobalSettingsFormProps {
45
45
  */
46
46
  readonly sectionIds?: readonly string[];
47
47
  /**
48
+ * Fields only — no form card, section border or section title. Use when the
49
+ * parent already owns the layout (e.g. Nodes page cluster secret).
50
+ */
51
+ readonly bare?: boolean;
52
+ /**
48
53
  * Render as collapsible. When true, the form body is hidden until
49
54
  * the operator expands the header (click). Defaults to open so
50
55
  * callers that always want the form visible don't have to opt out.
@@ -74,5 +79,5 @@ interface AddonGlobalSettingsFormProps {
74
79
  */
75
80
  readonly onOverrideChange?: (patch: Record<string, unknown>, effective: Record<string, unknown>) => void;
76
81
  }
77
- export declare function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAfterChange, refreshToken, sectionIds, collapsible, defaultOpen, mode, onOverrideChange }: AddonGlobalSettingsFormProps): JSX.Element | null;
82
+ export declare function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAfterChange, refreshToken, sectionIds, bare, collapsible, defaultOpen, mode, onOverrideChange }: AddonGlobalSettingsFormProps): JSX.Element | null;
78
83
  export {};
@@ -14,6 +14,11 @@ interface FormBuilderProps {
14
14
  probeResults?: Record<string, ProbeState>;
15
15
  /** Callback to clear a probe result when a field value changes */
16
16
  onClearProbe?: (key: string) => void;
17
+ /**
18
+ * Fields only — no section border, title or description. For a parent that
19
+ * already frames the form (or wants a single field with no chrome).
20
+ */
21
+ bare?: boolean;
17
22
  }
18
- export declare function ConfigFormBuilder({ schema, values, onChange, disabled, translationFn, onTestField, probeResults, onClearProbe }: FormBuilderProps): JSX.Element;
23
+ export declare function ConfigFormBuilder({ schema, values, onChange, disabled, translationFn, onTestField, probeResults, onClearProbe, bare }: FormBuilderProps): JSX.Element;
19
24
  export {};
@@ -1,14 +1,21 @@
1
1
  /**
2
- * RoleNodePill — one pipeline role and the node that hosts it, tinted by that
3
- * node's palette colour (agent-settings `color`, else stable hash).
2
+ * RoleNodePill — a node tinted by its palette colour (agent-settings `color`,
3
+ * else stable hash). With a `roleLabel`, shows role · node · colour (Assignments).
4
+ * Without, colour icon + name only (Nodes selector and similar).
4
5
  */
5
6
  import type { NodeColorId } from "@camstack/types";
6
- import type { JSX } from "react";
7
+ import type { JSX, ReactNode } from "react";
7
8
  export interface RoleNodePillProps {
8
- readonly roleLabel: string;
9
+ /** When omitted, the pill is colour icon + node name only. */
10
+ readonly roleLabel?: string;
9
11
  readonly nodeName: string;
10
12
  readonly colorId: NodeColorId;
11
13
  readonly emphasized?: boolean;
12
14
  readonly pinned?: boolean;
15
+ /** When set, the pill is a selectable control (`role="tab"`). */
16
+ readonly onSelect?: () => void;
17
+ readonly disabled?: boolean;
18
+ /** Extra trailing content inside the pill (e.g. "offline"). */
19
+ readonly trailing?: ReactNode;
13
20
  }
14
- export declare function RoleNodePill({ roleLabel, nodeName, colorId, emphasized, pinned }: RoleNodePillProps): JSX.Element;
21
+ export declare function RoleNodePill({ roleLabel, nodeName, colorId, emphasized, pinned, onSelect, disabled, trailing }: RoleNodePillProps): JSX.Element;
package/dist/index.cjs CHANGED
@@ -30127,7 +30127,7 @@ function SectionCard$1({ section, values, onChange, disabled, translationFn, onT
30127
30127
  })]
30128
30128
  });
30129
30129
  }
30130
- function ConfigFormBuilder({ schema, values, onChange, disabled, translationFn, onTestField, probeResults, onClearProbe }) {
30130
+ function ConfigFormBuilder({ schema, values, onChange, disabled, translationFn, onTestField, probeResults, onClearProbe, bare = false }) {
30131
30131
  const handleFieldChange = (key, value) => {
30132
30132
  onChange({
30133
30133
  ...values,
@@ -30135,6 +30135,18 @@ function ConfigFormBuilder({ schema, values, onChange, disabled, translationFn,
30135
30135
  });
30136
30136
  onClearProbe?.(key);
30137
30137
  };
30138
+ if (bare) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
30139
+ className: "grid grid-cols-1 gap-y-2.5",
30140
+ children: schema.sections.flatMap((section) => section.fields.map((field) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FormField, {
30141
+ field,
30142
+ values,
30143
+ onChange: handleFieldChange,
30144
+ disabled,
30145
+ translationFn,
30146
+ onTestField,
30147
+ externalProbe: probeResults?.[field.key]
30148
+ }, field.key)))
30149
+ });
30138
30150
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
30139
30151
  className: "space-y-4",
30140
30152
  children: schema.sections.map((section) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SectionCard$1, {
@@ -30217,7 +30229,7 @@ function stripValues(schema) {
30217
30229
  }))
30218
30230
  };
30219
30231
  }
30220
- function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAfterChange, refreshToken, sectionIds, collapsible, defaultOpen, mode, onOverrideChange }) {
30232
+ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAfterChange, refreshToken, sectionIds, bare = false, collapsible, defaultOpen, mode, onOverrideChange }) {
30221
30233
  const effectiveMode = mode ?? "persist";
30222
30234
  const [hydrated, setHydrated] = (0, react$1.useState)(null);
30223
30235
  const [loading, setLoading] = (0, react$1.useState)(true);
@@ -30361,9 +30373,11 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30361
30373
  schema: schemaNoValues,
30362
30374
  values: effectiveValues,
30363
30375
  onChange: handleChange,
30364
- disabled: disabled === true
30376
+ disabled: disabled === true,
30377
+ bare
30365
30378
  })
30366
30379
  ] });
30380
+ if (bare) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: body });
30367
30381
  if (collapsible === true) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
30368
30382
  className: "rounded-lg border border-border bg-surface overflow-hidden",
30369
30383
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
@@ -32854,26 +32868,51 @@ var NODE_RING_CLASS = {
32854
32868
  "node-g": "ring-node-g/45",
32855
32869
  "node-h": "ring-node-h/45"
32856
32870
  };
32857
- function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false }) {
32858
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
32871
+ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false, onSelect, disabled = false, trailing }) {
32872
+ const title = roleLabel !== void 0 ? pinned ? `${roleLabel} pinned on ${nodeName}` : `${roleLabel} on ${nodeName}` : nodeName;
32873
+ const className = cn("inline-flex max-w-full items-center gap-1 rounded-full px-2 py-0.5 text-[10px] leading-tight ring-1 ring-inset", emphasized ? cn("role-node-pill-emphasized font-semibold ring-2", NODE_BG_EMPHASIZED_CLASS[colorId], NODE_RING_CLASS[colorId], nodeTextColorClass(colorId)) : cn("font-medium text-foreground-muted ring-border/60", NODE_BG_SOFT_CLASS[colorId]), onSelect !== void 0 && !disabled && "cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40", disabled && "cursor-not-allowed opacity-50");
32874
+ const colorIcon = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32875
+ className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)),
32876
+ "aria-hidden": true
32877
+ });
32878
+ const body = roleLabel !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
32879
+ pinned && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pin, {
32880
+ className: "h-2.5 w-2.5 shrink-0 opacity-80",
32881
+ "aria-label": "pinned"
32882
+ }),
32883
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32884
+ className: "shrink-0",
32885
+ children: roleLabel
32886
+ }),
32887
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32888
+ className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32889
+ children: nodeName
32890
+ }),
32891
+ colorIcon
32892
+ ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
32893
+ colorIcon,
32894
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32895
+ className: cn("min-w-0 truncate font-medium", emphasized ? nodeTextColorClass(colorId) : "text-foreground"),
32896
+ children: nodeName
32897
+ }),
32898
+ trailing
32899
+ ] });
32900
+ if (onSelect !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
32901
+ type: "button",
32902
+ role: "tab",
32903
+ "aria-selected": emphasized,
32859
32904
  "data-testid": "role-node-pill",
32860
- title: pinned ? `${roleLabel} pinned on ${nodeName}` : `${roleLabel} on ${nodeName}`,
32861
- className: cn("inline-flex max-w-full items-center gap-1 rounded-full px-2 py-0.5 text-[10px] leading-tight ring-1 ring-inset", emphasized ? cn("role-node-pill-emphasized font-semibold ring-2", NODE_BG_EMPHASIZED_CLASS[colorId], NODE_RING_CLASS[colorId], nodeTextColorClass(colorId)) : cn("font-medium text-foreground-muted ring-border/60", NODE_BG_SOFT_CLASS[colorId])),
32862
- children: [
32863
- pinned && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pin, {
32864
- className: "h-2.5 w-2.5 shrink-0 opacity-80",
32865
- "aria-label": "pinned"
32866
- }),
32867
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32868
- className: "shrink-0",
32869
- children: roleLabel
32870
- }),
32871
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32872
- className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32873
- children: nodeName
32874
- }),
32875
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)) })
32876
- ]
32905
+ title,
32906
+ disabled,
32907
+ onClick: onSelect,
32908
+ className,
32909
+ children: body
32910
+ });
32911
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32912
+ "data-testid": "role-node-pill",
32913
+ title,
32914
+ className,
32915
+ children: body
32877
32916
  });
32878
32917
  }
32879
32918
  //#endregion
package/dist/index.js CHANGED
@@ -30103,7 +30103,7 @@ function SectionCard$1({ section, values, onChange, disabled, translationFn, onT
30103
30103
  })]
30104
30104
  });
30105
30105
  }
30106
- function ConfigFormBuilder({ schema, values, onChange, disabled, translationFn, onTestField, probeResults, onClearProbe }) {
30106
+ function ConfigFormBuilder({ schema, values, onChange, disabled, translationFn, onTestField, probeResults, onClearProbe, bare = false }) {
30107
30107
  const handleFieldChange = (key, value) => {
30108
30108
  onChange({
30109
30109
  ...values,
@@ -30111,6 +30111,18 @@ function ConfigFormBuilder({ schema, values, onChange, disabled, translationFn,
30111
30111
  });
30112
30112
  onClearProbe?.(key);
30113
30113
  };
30114
+ if (bare) return /* @__PURE__ */ jsx("div", {
30115
+ className: "grid grid-cols-1 gap-y-2.5",
30116
+ children: schema.sections.flatMap((section) => section.fields.map((field) => /* @__PURE__ */ jsx(FormField, {
30117
+ field,
30118
+ values,
30119
+ onChange: handleFieldChange,
30120
+ disabled,
30121
+ translationFn,
30122
+ onTestField,
30123
+ externalProbe: probeResults?.[field.key]
30124
+ }, field.key)))
30125
+ });
30114
30126
  return /* @__PURE__ */ jsx("div", {
30115
30127
  className: "space-y-4",
30116
30128
  children: schema.sections.map((section) => /* @__PURE__ */ jsx(SectionCard$1, {
@@ -30193,7 +30205,7 @@ function stripValues(schema) {
30193
30205
  }))
30194
30206
  };
30195
30207
  }
30196
- function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAfterChange, refreshToken, sectionIds, collapsible, defaultOpen, mode, onOverrideChange }) {
30208
+ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAfterChange, refreshToken, sectionIds, bare = false, collapsible, defaultOpen, mode, onOverrideChange }) {
30197
30209
  const effectiveMode = mode ?? "persist";
30198
30210
  const [hydrated, setHydrated] = useState(null);
30199
30211
  const [loading, setLoading] = useState(true);
@@ -30337,9 +30349,11 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30337
30349
  schema: schemaNoValues,
30338
30350
  values: effectiveValues,
30339
30351
  onChange: handleChange,
30340
- disabled: disabled === true
30352
+ disabled: disabled === true,
30353
+ bare
30341
30354
  })
30342
30355
  ] });
30356
+ if (bare) return /* @__PURE__ */ jsx("div", { children: body });
30343
30357
  if (collapsible === true) return /* @__PURE__ */ jsxs("section", {
30344
30358
  className: "rounded-lg border border-border bg-surface overflow-hidden",
30345
30359
  children: [/* @__PURE__ */ jsxs("button", {
@@ -32830,26 +32844,51 @@ var NODE_RING_CLASS = {
32830
32844
  "node-g": "ring-node-g/45",
32831
32845
  "node-h": "ring-node-h/45"
32832
32846
  };
32833
- function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false }) {
32834
- return /* @__PURE__ */ jsxs("span", {
32847
+ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false, onSelect, disabled = false, trailing }) {
32848
+ const title = roleLabel !== void 0 ? pinned ? `${roleLabel} pinned on ${nodeName}` : `${roleLabel} on ${nodeName}` : nodeName;
32849
+ const className = cn("inline-flex max-w-full items-center gap-1 rounded-full px-2 py-0.5 text-[10px] leading-tight ring-1 ring-inset", emphasized ? cn("role-node-pill-emphasized font-semibold ring-2", NODE_BG_EMPHASIZED_CLASS[colorId], NODE_RING_CLASS[colorId], nodeTextColorClass(colorId)) : cn("font-medium text-foreground-muted ring-border/60", NODE_BG_SOFT_CLASS[colorId]), onSelect !== void 0 && !disabled && "cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40", disabled && "cursor-not-allowed opacity-50");
32850
+ const colorIcon = /* @__PURE__ */ jsx("span", {
32851
+ className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)),
32852
+ "aria-hidden": true
32853
+ });
32854
+ const body = roleLabel !== void 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
32855
+ pinned && /* @__PURE__ */ jsx(Pin, {
32856
+ className: "h-2.5 w-2.5 shrink-0 opacity-80",
32857
+ "aria-label": "pinned"
32858
+ }),
32859
+ /* @__PURE__ */ jsx("span", {
32860
+ className: "shrink-0",
32861
+ children: roleLabel
32862
+ }),
32863
+ /* @__PURE__ */ jsx("span", {
32864
+ className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32865
+ children: nodeName
32866
+ }),
32867
+ colorIcon
32868
+ ] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
32869
+ colorIcon,
32870
+ /* @__PURE__ */ jsx("span", {
32871
+ className: cn("min-w-0 truncate font-medium", emphasized ? nodeTextColorClass(colorId) : "text-foreground"),
32872
+ children: nodeName
32873
+ }),
32874
+ trailing
32875
+ ] });
32876
+ if (onSelect !== void 0) return /* @__PURE__ */ jsx("button", {
32877
+ type: "button",
32878
+ role: "tab",
32879
+ "aria-selected": emphasized,
32835
32880
  "data-testid": "role-node-pill",
32836
- title: pinned ? `${roleLabel} pinned on ${nodeName}` : `${roleLabel} on ${nodeName}`,
32837
- className: cn("inline-flex max-w-full items-center gap-1 rounded-full px-2 py-0.5 text-[10px] leading-tight ring-1 ring-inset", emphasized ? cn("role-node-pill-emphasized font-semibold ring-2", NODE_BG_EMPHASIZED_CLASS[colorId], NODE_RING_CLASS[colorId], nodeTextColorClass(colorId)) : cn("font-medium text-foreground-muted ring-border/60", NODE_BG_SOFT_CLASS[colorId])),
32838
- children: [
32839
- pinned && /* @__PURE__ */ jsx(Pin, {
32840
- className: "h-2.5 w-2.5 shrink-0 opacity-80",
32841
- "aria-label": "pinned"
32842
- }),
32843
- /* @__PURE__ */ jsx("span", {
32844
- className: "shrink-0",
32845
- children: roleLabel
32846
- }),
32847
- /* @__PURE__ */ jsx("span", {
32848
- className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32849
- children: nodeName
32850
- }),
32851
- /* @__PURE__ */ jsx("span", { className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)) })
32852
- ]
32881
+ title,
32882
+ disabled,
32883
+ onClick: onSelect,
32884
+ className,
32885
+ children: body
32886
+ });
32887
+ return /* @__PURE__ */ jsx("span", {
32888
+ "data-testid": "role-node-pill",
32889
+ title,
32890
+ className,
32891
+ children: body
32853
32892
  });
32854
32893
  }
32855
32894
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/ui-library",
3
- "version": "1.2.261",
3
+ "version": "1.2.263",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",