@camstack/ui-library 1.2.260 → 1.2.262

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.
@@ -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
@@ -29241,6 +29241,13 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
29241
29241
  };
29242
29242
  const canRemove = rows.length > minRows;
29243
29243
  const canAdd = rows.length < maxRows;
29244
+ const idKey = field.itemIdKey ?? "id";
29245
+ const rowReactKey = (row, idx) => {
29246
+ const raw = row[idKey];
29247
+ if (typeof raw === "string" && raw.length > 0) return raw;
29248
+ if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
29249
+ return `row-${String(idx)}`;
29250
+ };
29244
29251
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
29245
29252
  className: "col-span-full space-y-2",
29246
29253
  children: [
@@ -29287,7 +29294,7 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
29287
29294
  onAction
29288
29295
  }, sub.key))
29289
29296
  })]
29290
- }, idx))
29297
+ }, rowReactKey(row, idx)))
29291
29298
  }),
29292
29299
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
29293
29300
  type: "button",
@@ -30166,23 +30173,44 @@ var Chevron$1 = ({ open }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg",
30166
30173
  "aria-hidden": true,
30167
30174
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polyline", { points: "9 18 15 12 9 6" })
30168
30175
  });
30176
+ function isValueBearingField(f) {
30177
+ return f.type !== "separator" && f.type !== "info" && f.type !== "button" && f.type !== "group";
30178
+ }
30169
30179
  function extractValues(schema) {
30170
30180
  const out = {};
30171
30181
  if (!schema) return out;
30172
30182
  for (const s of schema.sections) for (const f of s.fields) {
30173
- if (f.type === "separator" || f.type === "info" || f.type === "button" || f.type === "group") continue;
30183
+ if (!isValueBearingField(f)) continue;
30174
30184
  const key = f.key;
30175
30185
  out[key] = f.value;
30176
30186
  }
30177
30187
  return out;
30178
30188
  }
30189
+ /** Paint operator edits into the hydrated schema so controlled inputs keep focus. */
30190
+ function applyValuesToSchema(schema, nextValues) {
30191
+ return {
30192
+ ...schema,
30193
+ sections: schema.sections.map((s) => ({
30194
+ ...s,
30195
+ fields: s.fields.map((f) => {
30196
+ if (!isValueBearingField(f)) return f;
30197
+ const key = f.key;
30198
+ if (!(key in nextValues)) return f;
30199
+ return {
30200
+ ...f,
30201
+ value: nextValues[key]
30202
+ };
30203
+ })
30204
+ }))
30205
+ };
30206
+ }
30179
30207
  function stripValues(schema) {
30180
30208
  return {
30181
30209
  ...schema,
30182
30210
  sections: schema.sections.map((s) => ({
30183
30211
  ...s,
30184
30212
  fields: s.fields.map((f) => {
30185
- if (f.type === "separator" || f.type === "info" || f.type === "button" || f.type === "group") return f;
30213
+ if (!isValueBearingField(f)) return f;
30186
30214
  const { value: _drop, ...rest } = f;
30187
30215
  return rest;
30188
30216
  })
@@ -30198,6 +30226,8 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30198
30226
  const [open, setOpen] = (0, react$1.useState)(defaultOpen ?? false);
30199
30227
  const [overrideValues, setOverrideValues] = (0, react$1.useState)({});
30200
30228
  const [baseValues, setBaseValues] = (0, react$1.useState)(null);
30229
+ /** Bumps on every persist edit; a stale refetch must not clobber a newer local paint. */
30230
+ const persistSeq = (0, react$1.useRef)(0);
30201
30231
  (0, react$1.useEffect)(() => {
30202
30232
  setBaseValues(null);
30203
30233
  setOverrideValues({});
@@ -30266,7 +30296,10 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30266
30296
  const patch = {};
30267
30297
  for (const k of Object.keys(nextValues)) if (nextValues[k] !== values[k]) patch[k] = nextValues[k];
30268
30298
  if (Object.keys(patch).length === 0) return;
30299
+ const seq = ++persistSeq.current;
30300
+ setHydrated((prev) => prev === null ? prev : applyValuesToSchema(prev, nextValues));
30269
30301
  setSaving(true);
30302
+ setError(null);
30270
30303
  try {
30271
30304
  await trpc.addonSettings.updateGlobalSettings.mutate({
30272
30305
  addonId,
@@ -30277,12 +30310,12 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30277
30310
  addonId,
30278
30311
  nodeId
30279
30312
  });
30280
- if (next) setHydrated(next);
30281
- onAfterChange?.();
30313
+ if (next && seq === persistSeq.current) setHydrated(next);
30314
+ if (seq === persistSeq.current) onAfterChange?.();
30282
30315
  } catch (err) {
30283
- setError(err instanceof Error ? err.message : String(err));
30316
+ if (seq === persistSeq.current) setError(err instanceof Error ? err.message : String(err));
30284
30317
  } finally {
30285
- setSaving(false);
30318
+ if (seq === persistSeq.current) setSaving(false);
30286
30319
  }
30287
30320
  };
30288
30321
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -30314,15 +30347,23 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30314
30347
  ...values,
30315
30348
  ...overrideValues
30316
30349
  } : values;
30317
- const body = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [effectiveMode === "override" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
30318
- className: "mb-2 text-[11px] text-foreground-subtle",
30319
- children: "Benchmark override — applies to this run only. The addon's saved settings are not changed."
30320
- }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfigFormBuilder, {
30321
- schema: schemaNoValues,
30322
- values: effectiveValues,
30323
- onChange: handleChange,
30324
- disabled: disabled === true || saving
30325
- })] });
30350
+ const body = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
30351
+ effectiveMode === "override" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
30352
+ className: "mb-2 text-[11px] text-foreground-subtle",
30353
+ children: "Benchmark override — applies to this run only. The addon's saved settings are not changed."
30354
+ }) : null,
30355
+ saving ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
30356
+ className: "mb-2 text-[11px] text-foreground-subtle",
30357
+ "aria-live": "polite",
30358
+ children: "Saving…"
30359
+ }) : null,
30360
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfigFormBuilder, {
30361
+ schema: schemaNoValues,
30362
+ values: effectiveValues,
30363
+ onChange: handleChange,
30364
+ disabled: disabled === true
30365
+ })
30366
+ ] });
30326
30367
  if (collapsible === true) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
30327
30368
  className: "rounded-lg border border-border bg-surface overflow-hidden",
30328
30369
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
@@ -32813,26 +32854,51 @@ var NODE_RING_CLASS = {
32813
32854
  "node-g": "ring-node-g/45",
32814
32855
  "node-h": "ring-node-h/45"
32815
32856
  };
32816
- function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false }) {
32817
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
32857
+ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false, onSelect, disabled = false, trailing }) {
32858
+ 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");
32860
+ const colorIcon = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32861
+ className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)),
32862
+ "aria-hidden": true
32863
+ });
32864
+ const body = roleLabel !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
32865
+ pinned && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pin, {
32866
+ className: "h-2.5 w-2.5 shrink-0 opacity-80",
32867
+ "aria-label": "pinned"
32868
+ }),
32869
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32870
+ className: "shrink-0",
32871
+ children: roleLabel
32872
+ }),
32873
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32874
+ className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32875
+ children: nodeName
32876
+ }),
32877
+ colorIcon
32878
+ ] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
32879
+ colorIcon,
32880
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32881
+ className: cn("min-w-0 truncate font-medium", emphasized ? nodeTextColorClass(colorId) : "text-foreground"),
32882
+ children: nodeName
32883
+ }),
32884
+ trailing
32885
+ ] });
32886
+ if (onSelect !== void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
32887
+ type: "button",
32888
+ role: "tab",
32889
+ "aria-selected": emphasized,
32818
32890
  "data-testid": "role-node-pill",
32819
- title: pinned ? `${roleLabel} pinned on ${nodeName}` : `${roleLabel} on ${nodeName}`,
32820
- 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])),
32821
- children: [
32822
- pinned && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pin, {
32823
- className: "h-2.5 w-2.5 shrink-0 opacity-80",
32824
- "aria-label": "pinned"
32825
- }),
32826
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32827
- className: "shrink-0",
32828
- children: roleLabel
32829
- }),
32830
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32831
- className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32832
- children: nodeName
32833
- }),
32834
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)) })
32835
- ]
32891
+ title,
32892
+ disabled,
32893
+ onClick: onSelect,
32894
+ className,
32895
+ children: body
32896
+ });
32897
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
32898
+ "data-testid": "role-node-pill",
32899
+ title,
32900
+ className,
32901
+ children: body
32836
32902
  });
32837
32903
  }
32838
32904
  //#endregion
package/dist/index.js CHANGED
@@ -29217,6 +29217,13 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
29217
29217
  };
29218
29218
  const canRemove = rows.length > minRows;
29219
29219
  const canAdd = rows.length < maxRows;
29220
+ const idKey = field.itemIdKey ?? "id";
29221
+ const rowReactKey = (row, idx) => {
29222
+ const raw = row[idKey];
29223
+ if (typeof raw === "string" && raw.length > 0) return raw;
29224
+ if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
29225
+ return `row-${String(idx)}`;
29226
+ };
29220
29227
  return /* @__PURE__ */ jsxs("div", {
29221
29228
  className: "col-span-full space-y-2",
29222
29229
  children: [
@@ -29263,7 +29270,7 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
29263
29270
  onAction
29264
29271
  }, sub.key))
29265
29272
  })]
29266
- }, idx))
29273
+ }, rowReactKey(row, idx)))
29267
29274
  }),
29268
29275
  /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("button", {
29269
29276
  type: "button",
@@ -30142,23 +30149,44 @@ var Chevron$1 = ({ open }) => /* @__PURE__ */ jsx("svg", {
30142
30149
  "aria-hidden": true,
30143
30150
  children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" })
30144
30151
  });
30152
+ function isValueBearingField(f) {
30153
+ return f.type !== "separator" && f.type !== "info" && f.type !== "button" && f.type !== "group";
30154
+ }
30145
30155
  function extractValues(schema) {
30146
30156
  const out = {};
30147
30157
  if (!schema) return out;
30148
30158
  for (const s of schema.sections) for (const f of s.fields) {
30149
- if (f.type === "separator" || f.type === "info" || f.type === "button" || f.type === "group") continue;
30159
+ if (!isValueBearingField(f)) continue;
30150
30160
  const key = f.key;
30151
30161
  out[key] = f.value;
30152
30162
  }
30153
30163
  return out;
30154
30164
  }
30165
+ /** Paint operator edits into the hydrated schema so controlled inputs keep focus. */
30166
+ function applyValuesToSchema(schema, nextValues) {
30167
+ return {
30168
+ ...schema,
30169
+ sections: schema.sections.map((s) => ({
30170
+ ...s,
30171
+ fields: s.fields.map((f) => {
30172
+ if (!isValueBearingField(f)) return f;
30173
+ const key = f.key;
30174
+ if (!(key in nextValues)) return f;
30175
+ return {
30176
+ ...f,
30177
+ value: nextValues[key]
30178
+ };
30179
+ })
30180
+ }))
30181
+ };
30182
+ }
30155
30183
  function stripValues(schema) {
30156
30184
  return {
30157
30185
  ...schema,
30158
30186
  sections: schema.sections.map((s) => ({
30159
30187
  ...s,
30160
30188
  fields: s.fields.map((f) => {
30161
- if (f.type === "separator" || f.type === "info" || f.type === "button" || f.type === "group") return f;
30189
+ if (!isValueBearingField(f)) return f;
30162
30190
  const { value: _drop, ...rest } = f;
30163
30191
  return rest;
30164
30192
  })
@@ -30174,6 +30202,8 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30174
30202
  const [open, setOpen] = useState(defaultOpen ?? false);
30175
30203
  const [overrideValues, setOverrideValues] = useState({});
30176
30204
  const [baseValues, setBaseValues] = useState(null);
30205
+ /** Bumps on every persist edit; a stale refetch must not clobber a newer local paint. */
30206
+ const persistSeq = useRef(0);
30177
30207
  useEffect(() => {
30178
30208
  setBaseValues(null);
30179
30209
  setOverrideValues({});
@@ -30242,7 +30272,10 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30242
30272
  const patch = {};
30243
30273
  for (const k of Object.keys(nextValues)) if (nextValues[k] !== values[k]) patch[k] = nextValues[k];
30244
30274
  if (Object.keys(patch).length === 0) return;
30275
+ const seq = ++persistSeq.current;
30276
+ setHydrated((prev) => prev === null ? prev : applyValuesToSchema(prev, nextValues));
30245
30277
  setSaving(true);
30278
+ setError(null);
30246
30279
  try {
30247
30280
  await trpc.addonSettings.updateGlobalSettings.mutate({
30248
30281
  addonId,
@@ -30253,12 +30286,12 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30253
30286
  addonId,
30254
30287
  nodeId
30255
30288
  });
30256
- if (next) setHydrated(next);
30257
- onAfterChange?.();
30289
+ if (next && seq === persistSeq.current) setHydrated(next);
30290
+ if (seq === persistSeq.current) onAfterChange?.();
30258
30291
  } catch (err) {
30259
- setError(err instanceof Error ? err.message : String(err));
30292
+ if (seq === persistSeq.current) setError(err instanceof Error ? err.message : String(err));
30260
30293
  } finally {
30261
- setSaving(false);
30294
+ if (seq === persistSeq.current) setSaving(false);
30262
30295
  }
30263
30296
  };
30264
30297
  if (loading) return /* @__PURE__ */ jsxs("div", {
@@ -30290,15 +30323,23 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
30290
30323
  ...values,
30291
30324
  ...overrideValues
30292
30325
  } : values;
30293
- const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [effectiveMode === "override" ? /* @__PURE__ */ jsx("div", {
30294
- className: "mb-2 text-[11px] text-foreground-subtle",
30295
- children: "Benchmark override — applies to this run only. The addon's saved settings are not changed."
30296
- }) : null, /* @__PURE__ */ jsx(ConfigFormBuilder, {
30297
- schema: schemaNoValues,
30298
- values: effectiveValues,
30299
- onChange: handleChange,
30300
- disabled: disabled === true || saving
30301
- })] });
30326
+ const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [
30327
+ effectiveMode === "override" ? /* @__PURE__ */ jsx("div", {
30328
+ className: "mb-2 text-[11px] text-foreground-subtle",
30329
+ children: "Benchmark override — applies to this run only. The addon's saved settings are not changed."
30330
+ }) : null,
30331
+ saving ? /* @__PURE__ */ jsx("div", {
30332
+ className: "mb-2 text-[11px] text-foreground-subtle",
30333
+ "aria-live": "polite",
30334
+ children: "Saving…"
30335
+ }) : null,
30336
+ /* @__PURE__ */ jsx(ConfigFormBuilder, {
30337
+ schema: schemaNoValues,
30338
+ values: effectiveValues,
30339
+ onChange: handleChange,
30340
+ disabled: disabled === true
30341
+ })
30342
+ ] });
30302
30343
  if (collapsible === true) return /* @__PURE__ */ jsxs("section", {
30303
30344
  className: "rounded-lg border border-border bg-surface overflow-hidden",
30304
30345
  children: [/* @__PURE__ */ jsxs("button", {
@@ -32789,26 +32830,51 @@ var NODE_RING_CLASS = {
32789
32830
  "node-g": "ring-node-g/45",
32790
32831
  "node-h": "ring-node-h/45"
32791
32832
  };
32792
- function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false }) {
32793
- return /* @__PURE__ */ jsxs("span", {
32833
+ function RoleNodePill({ roleLabel, nodeName, colorId, emphasized = false, pinned = false, onSelect, disabled = false, trailing }) {
32834
+ 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");
32836
+ const colorIcon = /* @__PURE__ */ jsx("span", {
32837
+ className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)),
32838
+ "aria-hidden": true
32839
+ });
32840
+ const body = roleLabel !== void 0 ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
32841
+ pinned && /* @__PURE__ */ jsx(Pin, {
32842
+ className: "h-2.5 w-2.5 shrink-0 opacity-80",
32843
+ "aria-label": "pinned"
32844
+ }),
32845
+ /* @__PURE__ */ jsx("span", {
32846
+ className: "shrink-0",
32847
+ children: roleLabel
32848
+ }),
32849
+ /* @__PURE__ */ jsx("span", {
32850
+ className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32851
+ children: nodeName
32852
+ }),
32853
+ colorIcon
32854
+ ] }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
32855
+ colorIcon,
32856
+ /* @__PURE__ */ jsx("span", {
32857
+ className: cn("min-w-0 truncate font-medium", emphasized ? nodeTextColorClass(colorId) : "text-foreground"),
32858
+ children: nodeName
32859
+ }),
32860
+ trailing
32861
+ ] });
32862
+ if (onSelect !== void 0) return /* @__PURE__ */ jsx("button", {
32863
+ type: "button",
32864
+ role: "tab",
32865
+ "aria-selected": emphasized,
32794
32866
  "data-testid": "role-node-pill",
32795
- title: pinned ? `${roleLabel} pinned on ${nodeName}` : `${roleLabel} on ${nodeName}`,
32796
- 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])),
32797
- children: [
32798
- pinned && /* @__PURE__ */ jsx(Pin, {
32799
- className: "h-2.5 w-2.5 shrink-0 opacity-80",
32800
- "aria-label": "pinned"
32801
- }),
32802
- /* @__PURE__ */ jsx("span", {
32803
- className: "shrink-0",
32804
- children: roleLabel
32805
- }),
32806
- /* @__PURE__ */ jsx("span", {
32807
- className: cn("min-w-0 truncate", emphasized ? nodeTextColorClass(colorId) : "text-foreground-subtle"),
32808
- children: nodeName
32809
- }),
32810
- /* @__PURE__ */ jsx("span", { className: cn("h-1.5 w-1.5 shrink-0 rounded-full", nodeColorClass(colorId)) })
32811
- ]
32867
+ title,
32868
+ disabled,
32869
+ onClick: onSelect,
32870
+ className,
32871
+ children: body
32872
+ });
32873
+ return /* @__PURE__ */ jsx("span", {
32874
+ "data-testid": "role-node-pill",
32875
+ title,
32876
+ className,
32877
+ children: body
32812
32878
  });
32813
32879
  }
32814
32880
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/ui-library",
3
- "version": "1.2.260",
3
+ "version": "1.2.262",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",