@camstack/ui-library 1.2.262 → 1.2.264

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 {};
@@ -18,7 +18,7 @@ export type { NetworkLinkBadgeProps, NetworkLinkStatusLike } from "./network-lin
18
18
  export { NetworkLinkBadge } from "./network-link-badge";
19
19
  export { NODE_COLOR_IDS, assignNodeColorId, nodeColorClass, nodeTextColorClass } from "./node-color";
20
20
  export type { NodeColorId } from "./node-color";
21
- export type { RoleNodePillProps } from "./role-node-pill";
21
+ export type { PipelineRoleId, RoleNodePillProps } from "./role-node-pill";
22
22
  export { RoleNodePill } from "./role-node-pill";
23
23
  export * from "./breadcrumb";
24
24
  export type { AdaptiveHintsReport, AdaptiveOfferPhase, ApplyDownlinkProbe, DownlinkProbeAnswer } from "./adaptive-downlink";
@@ -1,14 +1,19 @@
1
1
  /**
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).
2
+ * RoleNodePill — with a role: chrome tinted by ROLE (Detection / Decode /
3
+ * Audio) and a trailing node-colour dot. Without a role: colour icon + name
4
+ * only (Nodes selector and similar).
5
5
  */
6
6
  import type { NodeColorId } from "@camstack/types";
7
7
  import type { JSX, ReactNode } from "react";
8
+ /** Stable ids for the three camera roles on Assignments. */
9
+ export type PipelineRoleId = "detection" | "decode" | "audio";
8
10
  export interface RoleNodePillProps {
9
11
  /** When omitted, the pill is colour icon + node name only. */
10
12
  readonly roleLabel?: string;
13
+ /** When set with a role label, chrome uses role tones instead of node palette. */
14
+ readonly roleId?: PipelineRoleId;
11
15
  readonly nodeName: string;
16
+ /** Node palette — trailing host dot (and full chrome when there is no roleId). */
12
17
  readonly colorId: NodeColorId;
13
18
  readonly emphasized?: boolean;
14
19
  readonly pinned?: boolean;
@@ -18,4 +23,4 @@ export interface RoleNodePillProps {
18
23
  /** Extra trailing content inside the pill (e.g. "offline"). */
19
24
  readonly trailing?: ReactNode;
20
25
  }
21
- export declare function RoleNodePill({ roleLabel, nodeName, colorId, emphasized, pinned, onSelect, disabled, trailing }: RoleNodePillProps): JSX.Element;
26
+ export declare function RoleNodePill({ roleLabel, roleId, 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", {
@@ -32823,6 +32837,16 @@ function nodeTextColorClass(id) {
32823
32837
  }
32824
32838
  //#endregion
32825
32839
  //#region src/composites/role-node-pill.tsx
32840
+ var ROLE_SOFT_CLASS = {
32841
+ detection: "bg-info/12 text-info ring-info/35",
32842
+ decode: "bg-warning/12 text-warning ring-warning/35",
32843
+ audio: "bg-success/12 text-success ring-success/35"
32844
+ };
32845
+ var ROLE_EMPHASIZED_CLASS = {
32846
+ detection: "bg-info/22 text-info ring-info/55",
32847
+ decode: "bg-warning/22 text-warning ring-warning/55",
32848
+ audio: "bg-success/22 text-success ring-success/55"
32849
+ };
32826
32850
  /** Full class strings so Tailwind v4 JIT retains node palette opacity utilities. */
32827
32851
  var NODE_BG_SOFT_CLASS = {
32828
32852
  "node-a": "bg-node-a/12",
@@ -32854,9 +32878,10 @@ var NODE_RING_CLASS = {
32854
32878
  "node-g": "ring-node-g/45",
32855
32879
  "node-h": "ring-node-h/45"
32856
32880
  };
32857
- function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false, onSelect, disabled = false, trailing }) {
32881
+ function RoleNodePill({ roleLabel, roleId, nodeName, colorId, emphasized = false, pinned = false, onSelect, disabled = false, trailing }) {
32858
32882
  const title = roleLabel !== void 0 ? pinned ? `${roleLabel} pinned on ${nodeName}` : `${roleLabel} on ${nodeName}` : nodeName;
32859
- 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");
32883
+ const roleChrome = roleLabel !== void 0 && roleId !== void 0;
32884
+ 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", roleChrome ? emphasized ? cn("role-node-pill-emphasized font-semibold ring-2", ROLE_EMPHASIZED_CLASS[roleId]) : cn("font-medium", ROLE_SOFT_CLASS[roleId]) : 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");
32860
32885
  const colorIcon = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32861
32886
  className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)),
32862
32887
  "aria-hidden": true
@@ -32871,7 +32896,7 @@ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned
32871
32896
  children: roleLabel
32872
32897
  }),
32873
32898
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32874
- className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32899
+ className: cn("min-w-0 truncate", roleChrome ? "opacity-80" : emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32875
32900
  children: nodeName
32876
32901
  }),
32877
32902
  colorIcon
@@ -32888,6 +32913,7 @@ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned
32888
32913
  role: "tab",
32889
32914
  "aria-selected": emphasized,
32890
32915
  "data-testid": "role-node-pill",
32916
+ "data-role": roleId,
32891
32917
  title,
32892
32918
  disabled,
32893
32919
  onClick: onSelect,
@@ -32896,6 +32922,7 @@ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned
32896
32922
  });
32897
32923
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32898
32924
  "data-testid": "role-node-pill",
32925
+ "data-role": roleId,
32899
32926
  title,
32900
32927
  className,
32901
32928
  children: body
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", {
@@ -32799,6 +32813,16 @@ function nodeTextColorClass(id) {
32799
32813
  }
32800
32814
  //#endregion
32801
32815
  //#region src/composites/role-node-pill.tsx
32816
+ var ROLE_SOFT_CLASS = {
32817
+ detection: "bg-info/12 text-info ring-info/35",
32818
+ decode: "bg-warning/12 text-warning ring-warning/35",
32819
+ audio: "bg-success/12 text-success ring-success/35"
32820
+ };
32821
+ var ROLE_EMPHASIZED_CLASS = {
32822
+ detection: "bg-info/22 text-info ring-info/55",
32823
+ decode: "bg-warning/22 text-warning ring-warning/55",
32824
+ audio: "bg-success/22 text-success ring-success/55"
32825
+ };
32802
32826
  /** Full class strings so Tailwind v4 JIT retains node palette opacity utilities. */
32803
32827
  var NODE_BG_SOFT_CLASS = {
32804
32828
  "node-a": "bg-node-a/12",
@@ -32830,9 +32854,10 @@ var NODE_RING_CLASS = {
32830
32854
  "node-g": "ring-node-g/45",
32831
32855
  "node-h": "ring-node-h/45"
32832
32856
  };
32833
- function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false, onSelect, disabled = false, trailing }) {
32857
+ function RoleNodePill({ roleLabel, roleId, nodeName, colorId, emphasized = false, pinned = false, onSelect, disabled = false, trailing }) {
32834
32858
  const title = roleLabel !== void 0 ? pinned ? `${roleLabel} pinned on ${nodeName}` : `${roleLabel} on ${nodeName}` : nodeName;
32835
- 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");
32859
+ const roleChrome = roleLabel !== void 0 && roleId !== void 0;
32860
+ 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", roleChrome ? emphasized ? cn("role-node-pill-emphasized font-semibold ring-2", ROLE_EMPHASIZED_CLASS[roleId]) : cn("font-medium", ROLE_SOFT_CLASS[roleId]) : 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");
32836
32861
  const colorIcon = /* @__PURE__ */ jsx("span", {
32837
32862
  className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)),
32838
32863
  "aria-hidden": true
@@ -32847,7 +32872,7 @@ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned
32847
32872
  children: roleLabel
32848
32873
  }),
32849
32874
  /* @__PURE__ */ jsx("span", {
32850
- className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32875
+ className: cn("min-w-0 truncate", roleChrome ? "opacity-80" : emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32851
32876
  children: nodeName
32852
32877
  }),
32853
32878
  colorIcon
@@ -32864,6 +32889,7 @@ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned
32864
32889
  role: "tab",
32865
32890
  "aria-selected": emphasized,
32866
32891
  "data-testid": "role-node-pill",
32892
+ "data-role": roleId,
32867
32893
  title,
32868
32894
  disabled,
32869
32895
  onClick: onSelect,
@@ -32872,6 +32898,7 @@ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned
32872
32898
  });
32873
32899
  return /* @__PURE__ */ jsx("span", {
32874
32900
  "data-testid": "role-node-pill",
32901
+ "data-role": roleId,
32875
32902
  title,
32876
32903
  className,
32877
32904
  children: body
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/ui-library",
3
- "version": "1.2.262",
3
+ "version": "1.2.264",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",