@process.co/ui 0.0.21 → 0.0.23

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,5 +1,39 @@
1
1
  import React__default, { PropsWithChildren } from 'react';
2
2
 
3
+ /**
4
+ * Optional config for slot/case awareness in dev.
5
+ * Each control type can have unique data shape; getSlots interprets the field value and returns slot options.
6
+ */
7
+ interface DevSlotConfig {
8
+ /** Property key (field) whose value holds the slot data (e.g. 'switchValue' or 'cases'). When set, getSlots and activeIdPath are applied to data[field]. */
9
+ field?: string;
10
+ /** Path (relative to the field value when field is set) where we store the active slot id in dev. This is mocked in dev only; we do not use the element definition's slots.activeSlotId (e.g. $.results.pathId). */
11
+ activeIdPath: string;
12
+ /**
13
+ * Given the field value (or full data when field is unset), return the list of slots for the Active path/case selector.
14
+ * Enables any control-specific shape (e.g. value.cases.cases, value.branches, etc.).
15
+ */
16
+ getSlots: (fieldValueOrData: Record<string, any>) => {
17
+ id: string;
18
+ label: string;
19
+ }[];
20
+ }
21
+ /** Preset for slot/case awareness (legacy); prefer deriving from elementDefinition.slots. */
22
+ type SlotPreset = 'switch' | 'cases' | 'branches';
23
+ /**
24
+ * Action/signal definition shape (defineAction): optional slots, initValue, props.
25
+ * Used to derive slotConfig and optionally initialData.
26
+ */
27
+ interface ElementDefinition {
28
+ slots?: {
29
+ slots?: any[];
30
+ activeSlotId?: string;
31
+ [k: string]: any;
32
+ };
33
+ initValue?: Record<string, any>;
34
+ props?: Record<string, any>;
35
+ [k: string]: any;
36
+ }
3
37
  /**
4
38
  * Configuration for the DevProvider
5
39
  */
@@ -12,6 +46,17 @@ interface DevProviderConfig {
12
46
  persist?: boolean;
13
47
  /** Mock node ID (default: 'dev-node-1') */
14
48
  nodeId?: string;
49
+ /** Key in dev data that holds the control value (e.g. devField). In the definition, the control is the prop with the UI (e.g. cases with ui.switch); in dev that value lives at data[propertyKey], so devField = $.data.cases. Default: 'devField' */
50
+ propertyKey?: string;
51
+ /** When set, provider builds slotConfig internally; loader does not need to pass slotConfig. */
52
+ slotPreset?: SlotPreset;
53
+ /** Optional. Full slot config; overrides slotPreset and elementDefinition when provided. */
54
+ slotConfig?: DevSlotConfig;
55
+ /**
56
+ * Action or signal definition (defineAction result). Provider derives slotConfig from slots + initValue
57
+ * and uses initValue as initialData when initialData is not provided.
58
+ */
59
+ elementDefinition?: ElementDefinition | null;
15
60
  }
16
61
  /**
17
62
  * Context value for development/testing
@@ -28,6 +73,14 @@ interface DevContextValue {
28
73
  /** Remove all inferred types */
29
74
  clearAllInferredTypes: () => void;
30
75
  nodeId: string;
76
+ /** Current active slot/case id (for elements with slots, e.g. Switch). Null when none selected. Provider state only; not stored in data. */
77
+ activeSlotId: string | null;
78
+ /** Set the active slot/case id. Stored in provider state only; not written to data. */
79
+ setActiveSlotId: (id: string | null) => void;
80
+ /** Slot config when provided to DevProvider (so toolbar can call getSlots(data)). */
81
+ slotConfig: DevSlotConfig | undefined;
82
+ /** Action/signal definition passed to DevProvider (for debugging). */
83
+ elementDefinition: ElementDefinition | null | undefined;
31
84
  clearAll: () => void;
32
85
  exportData: () => string;
33
86
  importData: (json: string) => void;
@@ -74,15 +127,23 @@ declare function useInferredTypes(): {
74
127
  * }
75
128
  * ```
76
129
  */
77
- declare function DevProvider({ children, storageKey, initialData, persist, nodeId, }: PropsWithChildren<DevProviderConfig>): React__default.JSX.Element;
130
+ declare function DevProvider({ children, storageKey, initialData, persist, nodeId, propertyKey, slotPreset, slotConfig: slotConfigProp, elementDefinition, }: PropsWithChildren<DevProviderConfig>): React__default.JSX.Element;
78
131
 
132
+ /**
133
+ * Helper: get slots from data when the shape is { cases: { cases: [...] } } or similar.
134
+ * Use this inside slotConfig.getSlots for Switch-style data, or implement your own for other shapes.
135
+ */
136
+ declare function getSlotsFromCasesData(data: Record<string, any>): {
137
+ id: string;
138
+ label: string;
139
+ }[];
79
140
  /**
80
141
  * DevToolbar - Optional toolbar for development
81
142
  * Shows current data state and provides controls for import/export/clear
82
- * Also allows spoofing inferred types for testing components that depend on external field types
143
+ * Also allows spoofing inferred types and selecting active path/case when slotConfig.getSlots is provided
83
144
  */
84
145
  declare function DevToolbar({ className }: {
85
146
  className?: string;
86
147
  }): React__default.JSX.Element;
87
148
 
88
- export { DevContext, type DevContextValue, DevProvider, type DevProviderConfig, DevToolbar, useDevContext, useInferredTypes, useNodeProperty };
149
+ export { DevContext, type DevContextValue, DevProvider, type DevProviderConfig, type DevSlotConfig, DevToolbar, type ElementDefinition, type SlotPreset, getSlotsFromCasesData, useDevContext, useInferredTypes, useNodeProperty };
@@ -1,5 +1,39 @@
1
1
  import React__default, { PropsWithChildren } from 'react';
2
2
 
3
+ /**
4
+ * Optional config for slot/case awareness in dev.
5
+ * Each control type can have unique data shape; getSlots interprets the field value and returns slot options.
6
+ */
7
+ interface DevSlotConfig {
8
+ /** Property key (field) whose value holds the slot data (e.g. 'switchValue' or 'cases'). When set, getSlots and activeIdPath are applied to data[field]. */
9
+ field?: string;
10
+ /** Path (relative to the field value when field is set) where we store the active slot id in dev. This is mocked in dev only; we do not use the element definition's slots.activeSlotId (e.g. $.results.pathId). */
11
+ activeIdPath: string;
12
+ /**
13
+ * Given the field value (or full data when field is unset), return the list of slots for the Active path/case selector.
14
+ * Enables any control-specific shape (e.g. value.cases.cases, value.branches, etc.).
15
+ */
16
+ getSlots: (fieldValueOrData: Record<string, any>) => {
17
+ id: string;
18
+ label: string;
19
+ }[];
20
+ }
21
+ /** Preset for slot/case awareness (legacy); prefer deriving from elementDefinition.slots. */
22
+ type SlotPreset = 'switch' | 'cases' | 'branches';
23
+ /**
24
+ * Action/signal definition shape (defineAction): optional slots, initValue, props.
25
+ * Used to derive slotConfig and optionally initialData.
26
+ */
27
+ interface ElementDefinition {
28
+ slots?: {
29
+ slots?: any[];
30
+ activeSlotId?: string;
31
+ [k: string]: any;
32
+ };
33
+ initValue?: Record<string, any>;
34
+ props?: Record<string, any>;
35
+ [k: string]: any;
36
+ }
3
37
  /**
4
38
  * Configuration for the DevProvider
5
39
  */
@@ -12,6 +46,17 @@ interface DevProviderConfig {
12
46
  persist?: boolean;
13
47
  /** Mock node ID (default: 'dev-node-1') */
14
48
  nodeId?: string;
49
+ /** Key in dev data that holds the control value (e.g. devField). In the definition, the control is the prop with the UI (e.g. cases with ui.switch); in dev that value lives at data[propertyKey], so devField = $.data.cases. Default: 'devField' */
50
+ propertyKey?: string;
51
+ /** When set, provider builds slotConfig internally; loader does not need to pass slotConfig. */
52
+ slotPreset?: SlotPreset;
53
+ /** Optional. Full slot config; overrides slotPreset and elementDefinition when provided. */
54
+ slotConfig?: DevSlotConfig;
55
+ /**
56
+ * Action or signal definition (defineAction result). Provider derives slotConfig from slots + initValue
57
+ * and uses initValue as initialData when initialData is not provided.
58
+ */
59
+ elementDefinition?: ElementDefinition | null;
15
60
  }
16
61
  /**
17
62
  * Context value for development/testing
@@ -28,6 +73,14 @@ interface DevContextValue {
28
73
  /** Remove all inferred types */
29
74
  clearAllInferredTypes: () => void;
30
75
  nodeId: string;
76
+ /** Current active slot/case id (for elements with slots, e.g. Switch). Null when none selected. Provider state only; not stored in data. */
77
+ activeSlotId: string | null;
78
+ /** Set the active slot/case id. Stored in provider state only; not written to data. */
79
+ setActiveSlotId: (id: string | null) => void;
80
+ /** Slot config when provided to DevProvider (so toolbar can call getSlots(data)). */
81
+ slotConfig: DevSlotConfig | undefined;
82
+ /** Action/signal definition passed to DevProvider (for debugging). */
83
+ elementDefinition: ElementDefinition | null | undefined;
31
84
  clearAll: () => void;
32
85
  exportData: () => string;
33
86
  importData: (json: string) => void;
@@ -74,15 +127,23 @@ declare function useInferredTypes(): {
74
127
  * }
75
128
  * ```
76
129
  */
77
- declare function DevProvider({ children, storageKey, initialData, persist, nodeId, }: PropsWithChildren<DevProviderConfig>): React__default.JSX.Element;
130
+ declare function DevProvider({ children, storageKey, initialData, persist, nodeId, propertyKey, slotPreset, slotConfig: slotConfigProp, elementDefinition, }: PropsWithChildren<DevProviderConfig>): React__default.JSX.Element;
78
131
 
132
+ /**
133
+ * Helper: get slots from data when the shape is { cases: { cases: [...] } } or similar.
134
+ * Use this inside slotConfig.getSlots for Switch-style data, or implement your own for other shapes.
135
+ */
136
+ declare function getSlotsFromCasesData(data: Record<string, any>): {
137
+ id: string;
138
+ label: string;
139
+ }[];
79
140
  /**
80
141
  * DevToolbar - Optional toolbar for development
81
142
  * Shows current data state and provides controls for import/export/clear
82
- * Also allows spoofing inferred types for testing components that depend on external field types
143
+ * Also allows spoofing inferred types and selecting active path/case when slotConfig.getSlots is provided
83
144
  */
84
145
  declare function DevToolbar({ className }: {
85
146
  className?: string;
86
147
  }): React__default.JSX.Element;
87
148
 
88
- export { DevContext, type DevContextValue, DevProvider, type DevProviderConfig, DevToolbar, useDevContext, useInferredTypes, useNodeProperty };
149
+ export { DevContext, type DevContextValue, DevProvider, type DevProviderConfig, type DevSlotConfig, DevToolbar, type ElementDefinition, type SlotPreset, getSlotsFromCasesData, useDevContext, useInferredTypes, useNodeProperty };
@@ -1,6 +1,148 @@
1
- import React2, { createContext, useContext, useCallback, useState, useEffect, useMemo } from 'react';
1
+ import React2, { createContext, useContext, useCallback, useState, useMemo, useEffect } from 'react';
2
2
 
3
3
  // src/components/dev/DevProvider.tsx
4
+ function evaluateSimplePath(obj, path) {
5
+ if (!path || !obj) return void 0;
6
+ const cleanPath = path.startsWith("$.") ? path.slice(2) : path.startsWith("$") ? path.slice(1) : path;
7
+ const parts = cleanPath.split(".");
8
+ let current = obj.data ?? obj;
9
+ for (const part of parts) {
10
+ if (current == null) return void 0;
11
+ const cleanPart = part.replace(/\[\*\]$/, "");
12
+ if (cleanPart) current = current[cleanPart];
13
+ }
14
+ return current;
15
+ }
16
+ function evaluateCollectionPath(obj, path) {
17
+ if (!path || !obj) return [];
18
+ let cleanPath = path.startsWith("$.") ? path.slice(2) : path.startsWith("$") ? path.slice(1) : path;
19
+ cleanPath = cleanPath.replace(/\[\*\]$/, "");
20
+ const parts = cleanPath.split(".");
21
+ let current = obj.data ?? obj;
22
+ for (const part of parts) {
23
+ if (current == null) return [];
24
+ if (part) current = current[part];
25
+ }
26
+ if (Array.isArray(current)) return current;
27
+ if (parts.length >= 2) {
28
+ const parentPath = parts.slice(0, -1).join(".");
29
+ let parent = obj;
30
+ for (const part of parentPath.split(".")) {
31
+ if (parent == null) return [];
32
+ if (part) parent = parent[part];
33
+ }
34
+ if (Array.isArray(parent)) return parent;
35
+ }
36
+ return [];
37
+ }
38
+ function evaluateItemPath(item, fullPath, _index) {
39
+ if (!fullPath || item == null) return void 0;
40
+ const wildcardIndex = fullPath.indexOf("[*]");
41
+ if (wildcardIndex === -1) return evaluateSimplePath(item, fullPath);
42
+ const afterWildcard = fullPath.slice(wildcardIndex + 3);
43
+ if (!afterWildcard || afterWildcard === "") return item;
44
+ const propertyPath = afterWildcard.startsWith(".") ? afterWildcard.slice(1) : afterWildcard;
45
+ const parts = propertyPath.split(".");
46
+ let current = item;
47
+ for (const part of parts) {
48
+ if (current == null) return void 0;
49
+ current = current[part];
50
+ }
51
+ return current;
52
+ }
53
+ function deriveFieldFromSlotsDefinition(slotsConfig) {
54
+ for (const slot of slotsConfig) {
55
+ const path = slot.path ?? slot.idPath ?? slot.labelPath;
56
+ if (typeof path !== "string") continue;
57
+ const afterData = path.replace(/^\$\.data\./, "").replace(/^\$\./, "");
58
+ const firstSegment = afterData.split(".")[0];
59
+ if (firstSegment) return firstSegment;
60
+ }
61
+ return void 0;
62
+ }
63
+ function deriveControlPropertyKey(def, slotsField) {
64
+ const props = def?.props;
65
+ if (!props) return slotsField;
66
+ const arr = Array.isArray(props) ? props : Object.keys(props).map((k) => ({ key: k, ...props[k] }));
67
+ const withUi = arr.find((p) => p?.ui != null);
68
+ const matchKey = slotsField ? arr.find((p) => p?.key === slotsField) : withUi;
69
+ return matchKey?.key ?? withUi?.key ?? slotsField;
70
+ }
71
+ function isDynamicSlot(slot) {
72
+ if (slot.type === "dynamic") return true;
73
+ const path = slot.path ?? slot.idPath ?? slot.labelPath ?? "";
74
+ return typeof path === "string" && path.includes("[*]");
75
+ }
76
+ function getSlotDefinitions(slotsConfig) {
77
+ return slotsConfig.map((slot) => ({
78
+ ...slot,
79
+ type: isDynamicSlot(slot) ? "dynamic" : "static"
80
+ }));
81
+ }
82
+ function rewritePathForControlBase(path, definitionPropertyKey) {
83
+ if (!path || !definitionPropertyKey) return path;
84
+ const afterData = path.replace(/^\$\.data\./, "");
85
+ if (!afterData.startsWith(definitionPropertyKey + ".")) return path;
86
+ const rest = afterData.slice(definitionPropertyKey.length + 1);
87
+ return rest ? "$." + rest : path;
88
+ }
89
+ function resolveSlotDefinitions(slotDefinitions, node, nodeIdForStatic, definitionPropertyKey) {
90
+ const result = [];
91
+ for (const slot of slotDefinitions) {
92
+ if (slot.type === "static") {
93
+ const idPath = slot.idPath != null ? rewritePathForControlBase(slot.idPath, definitionPropertyKey) : void 0;
94
+ const id = idPath != null ? evaluateSimplePath(node, idPath) : slot.id != null ? String(slot.id).replace(/\{\{ID_GUID\}\}/g, nodeIdForStatic) : void 0;
95
+ const labelPath = slot.labelPath != null ? rewritePathForControlBase(slot.labelPath, definitionPropertyKey) : void 0;
96
+ const label = labelPath != null ? evaluateSimplePath(node, labelPath) : slot.labelPlaceholderValue ?? slot.label ?? (id ?? "");
97
+ result.push({ id: id ?? "", label: label ?? id ?? "" });
98
+ } else {
99
+ const path = slot.path ?? slot.idPath;
100
+ if (!path) continue;
101
+ const pathRewritten = rewritePathForControlBase(path, definitionPropertyKey);
102
+ const collection = evaluateCollectionPath(node, pathRewritten);
103
+ if (!Array.isArray(collection)) continue;
104
+ const idPath = rewritePathForControlBase(slot.idPath ?? path, definitionPropertyKey);
105
+ const labelPath = rewritePathForControlBase(slot.labelPath ?? path, definitionPropertyKey);
106
+ collection.forEach((item, index) => {
107
+ const id = evaluateItemPath(item, idPath) ?? item?.id ?? String(index);
108
+ const label = evaluateItemPath(item, labelPath) ?? item?.label ?? id ?? String(index);
109
+ result.push({ id: String(id), label: String(label) });
110
+ });
111
+ }
112
+ }
113
+ return result;
114
+ }
115
+ function buildGetSlotsFromDefinition(slotDefinitions, nodeIdForStatic, options) {
116
+ const { devPropertyKey, definitionPropertyKey } = options;
117
+ return (fullData) => {
118
+ const controlValue = devPropertyKey != null && fullData != null ? fullData[devPropertyKey] : fullData;
119
+ const node = { data: controlValue ?? {} };
120
+ return resolveSlotDefinitions(
121
+ slotDefinitions,
122
+ node,
123
+ nodeIdForStatic,
124
+ definitionPropertyKey
125
+ );
126
+ };
127
+ }
128
+ function deriveSlotConfigFromDefinition(def, nodeId, propertyKeyFromLoader) {
129
+ const slotsRoot = def?.slots;
130
+ const slotsConfig = Array.isArray(slotsRoot) ? slotsRoot : slotsRoot?.slots;
131
+ if (!Array.isArray(slotsConfig) || slotsConfig.length === 0) return void 0;
132
+ const field = deriveFieldFromSlotsDefinition(slotsConfig);
133
+ const definitionPropertyKey = deriveControlPropertyKey(def, field);
134
+ const devPropertyKey = propertyKeyFromLoader ?? definitionPropertyKey;
135
+ const slotDefinitions = getSlotDefinitions(slotsConfig);
136
+ const getSlots = buildGetSlotsFromDefinition(slotDefinitions, nodeId ?? "dev-node", {
137
+ devPropertyKey,
138
+ definitionPropertyKey
139
+ });
140
+ return {
141
+ field: devPropertyKey ?? field ?? void 0,
142
+ activeIdPath: "activeSlotId",
143
+ getSlots
144
+ };
145
+ }
4
146
  var DevContext = createContext(null);
5
147
  function useDevContext() {
6
148
  return useContext(DevContext);
@@ -34,20 +176,33 @@ function DevProvider({
34
176
  storageKey = "process-dev",
35
177
  initialData = {},
36
178
  persist = true,
37
- nodeId = "dev-node-1"
179
+ nodeId = "dev-node-1",
180
+ propertyKey = "devField",
181
+ slotPreset,
182
+ slotConfig: slotConfigProp,
183
+ elementDefinition
38
184
  }) {
185
+ const slotConfig = useMemo(
186
+ () => slotConfigProp ?? deriveSlotConfigFromDefinition(elementDefinition, nodeId, propertyKey),
187
+ [slotConfigProp, elementDefinition, nodeId, propertyKey]
188
+ );
189
+ const effectiveInitialData = useMemo(
190
+ () => Object.keys(initialData).length > 0 ? initialData : elementDefinition?.initValue ?? {},
191
+ [initialData, elementDefinition?.initValue]
192
+ );
193
+ const [activeSlotId, setActiveSlotIdState] = useState(null);
39
194
  const [data, setData] = useState(() => {
40
195
  if (persist && typeof window !== "undefined") {
41
196
  try {
42
197
  const stored = localStorage.getItem(`${storageKey}:data`);
43
198
  if (stored) {
44
- return { ...initialData, ...JSON.parse(stored) };
199
+ return { ...effectiveInitialData, ...JSON.parse(stored) };
45
200
  }
46
201
  } catch (e) {
47
202
  console.warn("DevProvider: Failed to load from localStorage", e);
48
203
  }
49
204
  }
50
- return initialData;
205
+ return effectiveInitialData;
51
206
  });
52
207
  const [inferredTypes, setInferredTypesState] = useState(() => {
53
208
  if (persist && typeof window !== "undefined") {
@@ -62,6 +217,10 @@ function DevProvider({
62
217
  }
63
218
  return {};
64
219
  });
220
+ useEffect(() => {
221
+ if (!elementDefinition?.initValue || typeof elementDefinition.initValue !== "object") return;
222
+ setData((prev) => Object.keys(prev).length === 0 ? { ...elementDefinition.initValue } : prev);
223
+ }, [elementDefinition?.initValue]);
65
224
  useEffect(() => {
66
225
  if (persist && typeof window !== "undefined") {
67
226
  try {
@@ -83,6 +242,9 @@ function DevProvider({
83
242
  const setProperty = useCallback((key, value2) => {
84
243
  setData((prev) => ({ ...prev, [key]: value2 }));
85
244
  }, []);
245
+ const setActiveSlotId = useCallback((id) => {
246
+ setActiveSlotIdState(id);
247
+ }, []);
86
248
  const getProperty = useCallback((key) => {
87
249
  return data[key];
88
250
  }, [data]);
@@ -131,18 +293,36 @@ function DevProvider({
131
293
  clearInferredType,
132
294
  clearAllInferredTypes,
133
295
  nodeId,
296
+ activeSlotId,
297
+ setActiveSlotId,
298
+ slotConfig,
299
+ elementDefinition,
134
300
  clearAll,
135
301
  exportData,
136
302
  importData
137
- }), [data, setProperty, getProperty, inferredTypes, setInferredType, getInferredType, clearInferredType, clearAllInferredTypes, nodeId, clearAll, exportData, importData]);
303
+ }), [data, setProperty, getProperty, inferredTypes, setInferredType, getInferredType, clearInferredType, clearAllInferredTypes, nodeId, activeSlotId, setActiveSlotId, slotConfig, elementDefinition, clearAll, exportData, importData]);
138
304
  return /* @__PURE__ */ React2.createElement(DevContext.Provider, { value }, children);
139
305
  }
306
+ function getSlotsFromCasesData(data) {
307
+ const list = data?.cases?.cases ?? data?.cases ?? data?.branches;
308
+ if (!Array.isArray(list)) return [];
309
+ return list.map((item) => ({
310
+ id: item.id ?? String(item),
311
+ label: item.label ?? item.id ?? String(item)
312
+ }));
313
+ }
140
314
  function DevToolbar({ className }) {
141
315
  const devCtx = useDevContext();
142
316
  const [showData, setShowData] = useState(false);
317
+ const [showDefinition, setShowDefinition] = useState(false);
143
318
  const [showTypeEditor, setShowTypeEditor] = useState(false);
144
319
  const [newTypeKey, setNewTypeKey] = useState("");
145
320
  const [newTypeValue, setNewTypeValue] = useState("");
321
+ const slots = useMemo(() => {
322
+ if (!devCtx?.slotConfig?.getSlots) return [];
323
+ const data = devCtx.data ?? {};
324
+ return devCtx.slotConfig.getSlots(data);
325
+ }, [devCtx?.slotConfig, devCtx?.data]);
146
326
  if (!devCtx) {
147
327
  return /* @__PURE__ */ React2.createElement("div", { className }, "DevToolbar: Not inside DevProvider");
148
328
  }
@@ -161,7 +341,7 @@ function DevToolbar({ className }) {
161
341
  devCtx.clearAllInferredTypes();
162
342
  }
163
343
  };
164
- return /* @__PURE__ */ React2.createElement("div", { className: `${className || ""} uii:border uii:rounded-lg uii:p-4 uii:bg-gray-50 dark:uii:bg-gray-900` }, /* @__PURE__ */ React2.createElement("div", { className: "uii:flex uii:items-center uii:gap-4 uii:mb-2 uii:flex-wrap" }, /* @__PURE__ */ React2.createElement("span", { className: "uii:font-semibold uii:text-sm" }, "\u{1F6E0}\uFE0F Dev Mode"), /* @__PURE__ */ React2.createElement("span", { className: "uii:text-xs uii:text-gray-500" }, "Node: ", devCtx.nodeId), /* @__PURE__ */ React2.createElement(
344
+ return /* @__PURE__ */ React2.createElement("div", { className: `${className || ""} uii:border uii:rounded-lg uii:p-4 uii:bg-gray-50 dark:uii:bg-gray-900` }, /* @__PURE__ */ React2.createElement("div", { className: "uii:flex uii:items-center uii:gap-4 uii:mb-2 uii:flex-wrap" }, /* @__PURE__ */ React2.createElement("span", { className: "uii:font-semibold uii:text-sm " }, "\u{1F6E0}\uFE0F Dev Mode"), /* @__PURE__ */ React2.createElement("span", { className: "uii:text-xs uii:text-gray-500" }, "Node: ", devCtx.nodeId), /* @__PURE__ */ React2.createElement(
165
345
  "button",
166
346
  {
167
347
  onClick: () => setShowData(!showData),
@@ -169,6 +349,14 @@ function DevToolbar({ className }) {
169
349
  },
170
350
  showData ? "Hide" : "Show",
171
351
  " Data"
352
+ ), /* @__PURE__ */ React2.createElement(
353
+ "button",
354
+ {
355
+ onClick: () => setShowDefinition(!showDefinition),
356
+ className: "uii:text-xs uii:px-2 uii:py-1 uii:bg-amber-100 dark:uii:bg-amber-900 uii:rounded hover:uii:bg-amber-200"
357
+ },
358
+ showDefinition ? "Hide" : "Show",
359
+ " Definition"
172
360
  ), /* @__PURE__ */ React2.createElement(
173
361
  "button",
174
362
  {
@@ -207,7 +395,24 @@ function DevToolbar({ className }) {
207
395
  className: "uii:text-xs uii:px-2 uii:py-1 uii:bg-red-100 dark:uii:bg-red-900 uii:rounded hover:uii:bg-red-200"
208
396
  },
209
397
  "Clear"
210
- )), showTypeEditor && /* @__PURE__ */ React2.createElement("div", { className: "uii:mt-3 uii:p-3 uii:bg-purple-50 dark:uii:bg-purple-950 uii:rounded-lg uii:border uii:border-purple-200 dark:uii:border-purple-800" }, /* @__PURE__ */ React2.createElement("div", { className: "uii:text-xs uii:font-medium uii:mb-2 uii:text-purple-700 dark:uii:text-purple-300" }, "Spoof Inferred Types (simulate external field types)"), /* @__PURE__ */ React2.createElement("div", { className: "uii:flex uii:gap-2 uii:mb-2 uii:flex-wrap" }, /* @__PURE__ */ React2.createElement(
398
+ )), slots.length > 0 && /* @__PURE__ */ React2.createElement("div", { className: "uii:mt-2 uii:p-2 uii:bg-slate-50 dark:uii:bg-slate-900 uii:rounded-lg uii:border uii:border-slate-200 dark:uii:border-slate-700" }, /* @__PURE__ */ React2.createElement("div", { className: "uii:text-xs uii:font-medium uii:mb-1.5 uii:text-slate-600 dark:uii:text-slate-400" }, "Active path / case"), /* @__PURE__ */ React2.createElement("div", { className: "uii:flex uii:flex-wrap uii:gap-1" }, /* @__PURE__ */ React2.createElement(
399
+ "button",
400
+ {
401
+ type: "button",
402
+ onClick: () => devCtx.setActiveSlotId(null),
403
+ className: `uii:text-xs uii:px-2 uii:py-1 uii:rounded uii:border ${devCtx.activeSlotId === null ? "uii:bg-slate-300 dark:uii:bg-slate-600 uii:border-slate-500" : "uii:bg-slate-100 dark:uii:bg-slate-800 uii:border-slate-300 dark:uii:border-slate-600 hover:uii:bg-slate-200"}`
404
+ },
405
+ "(none)"
406
+ ), slots.map((slot) => /* @__PURE__ */ React2.createElement(
407
+ "button",
408
+ {
409
+ key: slot.id,
410
+ type: "button",
411
+ onClick: () => devCtx.setActiveSlotId(slot.id),
412
+ className: `uii:text-xs uii:px-2 uii:py-1 uii:rounded uii:border ${devCtx.activeSlotId === slot.id ? "uii:bg-blue-200 dark:uii:bg-blue-800 uii:border-blue-500" : "uii:bg-white dark:uii:bg-slate-800 uii:border-slate-300 dark:uii:border-slate-600 hover:uii:bg-slate-100 dark:uii:hover:bg-slate-700"}`
413
+ },
414
+ slot.label || slot.id
415
+ )))), showTypeEditor && /* @__PURE__ */ React2.createElement("div", { className: "uii:mt-3 uii:p-3 uii:bg-purple-50 dark:uii:bg-purple-950 uii:rounded-lg uii:border uii:border-purple-200 dark:uii:border-purple-800" }, /* @__PURE__ */ React2.createElement("div", { className: "uii:text-xs uii:font-medium uii:mb-2 uii:text-purple-700 dark:uii:text-purple-300" }, "Spoof Inferred Types (simulate external field types)"), /* @__PURE__ */ React2.createElement("div", { className: "uii:flex uii:gap-2 uii:mb-2 uii:flex-wrap" }, /* @__PURE__ */ React2.createElement(
211
416
  "input",
212
417
  {
213
418
  type: "text",
@@ -280,9 +485,9 @@ function DevToolbar({ className }) {
280
485
  },
281
486
  "\u2715"
282
487
  )
283
- ))))), showData && /* @__PURE__ */ React2.createElement("div", { className: "uii:mt-2" }, /* @__PURE__ */ React2.createElement("div", { className: "uii:text-xs uii:mb-1 uii:font-medium" }, "Data:"), /* @__PURE__ */ React2.createElement("pre", { className: "uii:text-xs uii:bg-gray-100 dark:uii:bg-gray-800 uii:p-2 uii:rounded uii:overflow-auto uii:max-h-48" }, JSON.stringify(devCtx.data, null, 2)), /* @__PURE__ */ React2.createElement("div", { className: "uii:text-xs uii:mb-1 uii:mt-2 uii:font-medium" }, "Inferred Types:"), /* @__PURE__ */ React2.createElement("pre", { className: "uii:text-xs uii:bg-gray-100 dark:uii:bg-gray-800 uii:p-2 uii:rounded uii:overflow-auto uii:max-h-24" }, JSON.stringify(devCtx.inferredTypes, null, 2))));
488
+ ))))), showData && /* @__PURE__ */ React2.createElement("div", { className: "uii:mt-2" }, /* @__PURE__ */ React2.createElement("div", { className: "uii:text-xs uii:mb-1 uii:font-medium" }, "Data:"), /* @__PURE__ */ React2.createElement("pre", { className: "uii:text-xs uii:bg-gray-100 dark:uii:bg-gray-800 uii:p-2 uii:rounded uii:overflow-auto uii:max-h-48" }, JSON.stringify(devCtx.data, null, 2)), /* @__PURE__ */ React2.createElement("div", { className: "uii:text-xs uii:mb-1 uii:mt-2 uii:font-medium" }, "Inferred Types:"), /* @__PURE__ */ React2.createElement("pre", { className: "uii:text-xs uii:bg-gray-100 dark:uii:bg-gray-800 uii:p-2 uii:rounded uii:overflow-auto uii:max-h-24" }, JSON.stringify(devCtx.inferredTypes, null, 2))), showDefinition && /* @__PURE__ */ React2.createElement("div", { className: "uii:mt-2" }, /* @__PURE__ */ React2.createElement("div", { className: "uii:text-xs uii:mb-1 uii:font-medium" }, "Action / signal definition:"), devCtx.elementDefinition != null ? /* @__PURE__ */ React2.createElement("pre", { className: "uii:text-xs uii:bg-amber-50 dark:uii:bg-amber-950/30 uii:p-2 uii:rounded uii:overflow-auto uii:max-h-64 uii:border uii:border-amber-200 dark:uii:border-amber-800" }, JSON.stringify(devCtx.elementDefinition, null, 2)) : /* @__PURE__ */ React2.createElement("p", { className: "uii:text-xs uii:text-gray-500 uii:italic" }, "No definition passed to DevProvider.")));
284
489
  }
285
490
 
286
- export { DevContext, DevProvider, DevToolbar, useDevContext, useInferredTypes, useNodeProperty };
491
+ export { DevContext, DevProvider, DevToolbar, getSlotsFromCasesData, useDevContext, useInferredTypes, useNodeProperty };
287
492
  //# sourceMappingURL=index.js.map
288
493
  //# sourceMappingURL=index.js.map