autoui-react 0.0.4-alpha → 0.0.5-alpha

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.
package/dist/index.js CHANGED
@@ -9,10 +9,41 @@ var React = require('react');
9
9
  var openai = require('@ai-sdk/openai');
10
10
  var ai = require('ai');
11
11
  var zod = require('zod');
12
+ var DialogPrimitive = require('@radix-ui/react-dialog');
13
+ var lucideReact = require('lucide-react');
14
+ var SelectPrimitive = require('@radix-ui/react-select');
15
+ var CheckboxPrimitive = require('@radix-ui/react-checkbox');
16
+ var RadioGroupPrimitive = require('@radix-ui/react-radio-group');
17
+ var TabsPrimitive = require('@radix-ui/react-tabs');
18
+ var LabelPrimitive = require('@radix-ui/react-label');
12
19
 
13
20
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
21
 
22
+ function _interopNamespace(e) {
23
+ if (e && e.__esModule) return e;
24
+ var n = Object.create(null);
25
+ if (e) {
26
+ Object.keys(e).forEach(function (k) {
27
+ if (k !== 'default') {
28
+ var d = Object.getOwnPropertyDescriptor(e, k);
29
+ Object.defineProperty(n, k, d.get ? d : {
30
+ enumerable: true,
31
+ get: function () { return e[k]; }
32
+ });
33
+ }
34
+ });
35
+ }
36
+ n.default = e;
37
+ return Object.freeze(n);
38
+ }
39
+
15
40
  var React__default = /*#__PURE__*/_interopDefault(React);
41
+ var DialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(DialogPrimitive);
42
+ var SelectPrimitive__namespace = /*#__PURE__*/_interopNamespace(SelectPrimitive);
43
+ var CheckboxPrimitive__namespace = /*#__PURE__*/_interopNamespace(CheckboxPrimitive);
44
+ var RadioGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(RadioGroupPrimitive);
45
+ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
46
+ var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
16
47
 
17
48
  var __defProp = Object.defineProperty;
18
49
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -299,6 +330,72 @@ var initialState = {
299
330
  };
300
331
 
301
332
  // src/core/action-router.ts
333
+ var UI_GUIDANCE_BASE = `
334
+ UI Guidance:
335
+ 1. Create a focused interface that directly addresses the goal
336
+ 2. Use appropriate UI patterns (lists, forms, details, etc.)
337
+ 3. Include navigation between related views when needed
338
+ 4. Keep the interface simple and intuitive
339
+ 5. Bind to schema data where appropriate
340
+ 6. Provide event handlers for user interactions - make sure to always include both action and target properties`;
341
+ var LIST_BINDING_GUIDANCE = `7. **CRITICAL:** For \`ListView\` or \`Table\` nodes, the \`data\` binding key **MUST** point to the *exact path* of the data *array* within the context.`;
342
+ var LIST_BINDING_EXAMPLE = `Example: If the context has \`{ tasks: { data: [...] } }\`, the binding **MUST** be \`{ "bindings": { "data": "tasks.data" } }\`. If the context has \`{ userList: [...] }\`, the binding **MUST** be \`{ "bindings": { "data": "userList" } }\`. **NEVER** bind to the parent object containing the array (e.g., DO NOT USE \`{ "bindings": { "data": "tasks" } }\`).`;
343
+ var COMMON_UI_GUIDANCE = UI_GUIDANCE_BASE + "\n" + // Add a newline separator
344
+ LIST_BINDING_GUIDANCE + // Add the specific list binding rule
345
+ "\n" + // Add a newline separator
346
+ LIST_BINDING_EXAMPLE;
347
+ function processTemplate(template, values) {
348
+ return template.replace(/\${(.*?)}/g, (match, key) => {
349
+ const trimmedKey = key.trim();
350
+ return trimmedKey in values ? String(values[trimmedKey]) : match;
351
+ });
352
+ }
353
+ function buildPrompt(input, promptTemplate, templateValues) {
354
+ const { schema, goal, history, userContext } = input;
355
+ const schemaInfo = Object.entries(schema).map(([tableName, tableSchema]) => {
356
+ const schemaString = typeof tableSchema === "object" && tableSchema !== null ? JSON.stringify(tableSchema) : String(tableSchema);
357
+ return `Table: ${tableName}
358
+ Schema: ${schemaString}`;
359
+ }).join("\n\n");
360
+ const recentEvents = history && history.length > 0 ? history.slice(-5).map(
361
+ (event) => `Event: ${event.type} on node ${event.nodeId}${event.payload ? ` with payload ${JSON.stringify(event.payload)}` : ""}`
362
+ ).join("\n") : "No recent events";
363
+ const userContextSection = userContext ? `
364
+
365
+ User Context:
366
+ ${JSON.stringify(userContext)}` : "";
367
+ if (promptTemplate && templateValues) {
368
+ const fullTemplateValues = {
369
+ ...templateValues,
370
+ schemaInfo,
371
+ recentEvents,
372
+ userContextString: userContextSection.trim(),
373
+ // Use trimmed version
374
+ commonUIGuidance: COMMON_UI_GUIDANCE,
375
+ goal
376
+ // Ensure goal is always available to templates
377
+ };
378
+ return processTemplate(promptTemplate, fullTemplateValues);
379
+ }
380
+ const interactionDescription = history && history.length > 0 ? `The user's last action was: ${history[history.length - 1].type} on node ${history[history.length - 1].nodeId}` : "The user initiated the session for the goal";
381
+ return `
382
+ You are an expert UI generator.
383
+ Create a user interface that achieves the following goal: "${goal}".
384
+ ${interactionDescription}.
385
+
386
+ Available data schema:
387
+ ${schemaInfo}
388
+
389
+ Recent user interactions:
390
+ ${recentEvents}${userContextSection}
391
+
392
+ Generate a complete UI specification in JSON format that matches the following TypeScript type:
393
+ type UISpecNode = { id: string; node_type: string; props?: Record<string, unknown>; bindings?: Record<string, unknown>; events?: Record<string, { action: string; target: string; payload?: Record<string, unknown>; }>; children?: UISpecNode[]; };
394
+ ${COMMON_UI_GUIDANCE}
395
+
396
+ Respond ONLY with the JSON UI specification and no other text.
397
+ `;
398
+ }
302
399
  var ActionType = /* @__PURE__ */ ((ActionType2) => {
303
400
  ActionType2["FULL_REFRESH"] = "FULL_REFRESH";
304
401
  ActionType2["UPDATE_NODE"] = "UPDATE_NODE";
@@ -333,19 +430,39 @@ var ActionRouter = class {
333
430
  * @returns Route resolution or null if no match
334
431
  */
335
432
  resolveRoute(event, schema, layout, dataContext, goal, userContext) {
433
+ console.log(
434
+ `[ActionRouter Debug] resolveRoute called for event type: ${event.type}`
435
+ );
336
436
  const routes = this.routes[event.type] || [];
437
+ console.log(
438
+ `[ActionRouter Debug] Found ${routes.length} routes for ${event.type}`
439
+ );
337
440
  if (routes.length === 0) {
338
- return {
441
+ console.log(
442
+ `[ActionRouter Debug] No specific route found for ${event.type}, using default FULL_REFRESH.`
443
+ );
444
+ const defaultPlannerInput = {
445
+ schema,
446
+ goal,
447
+ history: [event],
448
+ userContext: userContext || null
449
+ };
450
+ const defaultPrompt = buildPrompt(
451
+ defaultPlannerInput,
452
+ void 0,
453
+ void 0
454
+ );
455
+ const defaultResolution = {
339
456
  actionType: "FULL_REFRESH" /* FULL_REFRESH */,
340
457
  targetNodeId: layout?.id || "root",
341
- plannerInput: {
342
- schema,
343
- goal,
344
- history: [event],
345
- userContext: userContext || null
346
- },
347
- prompt: `Generate a new UI for the goal: "${goal}". The user just triggered: ${event.type} on node ${event.nodeId}`
458
+ plannerInput: defaultPlannerInput,
459
+ prompt: defaultPrompt
348
460
  };
461
+ console.log(
462
+ "[ActionRouter Debug] Default Resolution:",
463
+ defaultResolution
464
+ );
465
+ return defaultResolution;
349
466
  }
350
467
  const sourceNode = layout ? findNodeById(layout, event.nodeId) : void 0;
351
468
  const nodeConfig = sourceNode?.events?.[event.type];
@@ -358,6 +475,7 @@ var ActionRouter = class {
358
475
  if (!matchingRoute) {
359
476
  matchingRoute = routes[0];
360
477
  }
478
+ console.log("[ActionRouter Debug] Matching Route Config:", matchingRoute);
361
479
  const targetNodeId = nodeConfig?.target || matchingRoute.targetNodeId || event.nodeId;
362
480
  const additionalContext = {};
363
481
  if (matchingRoute.contextKeys) {
@@ -402,16 +520,24 @@ var ActionRouter = class {
402
520
  ...additionalContext
403
521
  // Spread additionalContext afterwards (can override userContext keys)
404
522
  };
405
- const prompt = this.processTemplate(
523
+ console.log("[ActionRouter Debug] Template Values:", templateValues);
524
+ const finalPrompt = buildPrompt(
525
+ plannerInput2,
406
526
  matchingRoute.promptTemplate,
527
+ // Pass template if it exists (can be undefined)
407
528
  templateValues
529
+ // Pass templateValues (used only if promptTemplate exists)
408
530
  );
409
- return {
531
+ console.log("[ActionRouter Debug] Generated Prompt:", finalPrompt);
532
+ const finalResolution = {
410
533
  actionType: matchingRoute.actionType,
411
534
  targetNodeId,
412
535
  plannerInput: plannerInput2,
413
- prompt
536
+ prompt: finalPrompt
537
+ // Use the generated prompt
414
538
  };
539
+ console.log("[ActionRouter Debug] Final Resolution:", finalResolution);
540
+ return finalResolution;
415
541
  }
416
542
  /**
417
543
  * Process a prompt template with variables
@@ -429,8 +555,11 @@ function createDefaultRouter() {
429
555
  const router = new ActionRouter();
430
556
  router.registerRoute("CLICK", {
431
557
  actionType: "FULL_REFRESH" /* FULL_REFRESH */,
432
- targetNodeId: "root",
433
- promptTemplate: 'Generate a new UI for the goal: "${goal}". The user just clicked on node ${nodeId}'
558
+ targetNodeId: "root"
559
+ });
560
+ router.registerRoute("INIT", {
561
+ actionType: "FULL_REFRESH" /* FULL_REFRESH */,
562
+ targetNodeId: "root"
434
563
  });
435
564
  router.registerRoute("CLICK", {
436
565
  actionType: "SHOW_DETAIL" /* SHOW_DETAIL */,
@@ -460,7 +589,31 @@ function createDefaultRouter() {
460
589
  });
461
590
  return router;
462
591
  }
592
+ var componentType = zod.z.enum([
593
+ // Layout components
594
+ "Container",
595
+ "Card",
596
+ "Header",
597
+ // Input components
598
+ "Button",
599
+ "Input",
600
+ "Select",
601
+ "Textarea",
602
+ "Checkbox",
603
+ "RadioGroup",
604
+ // Data display components
605
+ "ListView",
606
+ "Detail",
607
+ "Tabs",
608
+ "Dialog",
609
+ // Typography
610
+ "Heading",
611
+ "Text"
612
+ ]);
613
+
614
+ // src/schema/ui.ts
463
615
  var uiEventType = zod.z.enum([
616
+ "INIT",
464
617
  "CLICK",
465
618
  "CHANGE",
466
619
  "SUBMIT",
@@ -481,12 +634,16 @@ var openAISimplifiedValue = zod.z.string().nullable();
481
634
  var openAIRecordSimplifiedNullable = zod.z.record(openAISimplifiedValue).nullable();
482
635
  var openAIEventPayloadSimplifiedNullable = zod.z.record(openAISimplifiedValue).nullable();
483
636
  var openAIBaseNode = zod.z.object({
484
- id: zod.z.string(),
485
- node_type: zod.z.string(),
486
- props: openAIRecordSimplifiedNullable,
487
- // Nullable record
488
- bindings: openAIRecordSimplifiedNullable,
489
- // Nullable record
637
+ id: zod.z.string().describe("Unique identifier for the UI node."),
638
+ node_type: componentType.describe(
639
+ "The type of UI component (e.g., Container, Text, Button, ListView)."
640
+ ),
641
+ props: openAIRecordSimplifiedNullable.describe(
642
+ 'Component-specific properties (attributes). Values should be strings or null. E.g., for Header use { "title": "My Title" }; for Text use { "text": "My Text" }.'
643
+ ),
644
+ bindings: openAIRecordSimplifiedNullable.describe(
645
+ 'Data bindings map context paths to component props. Values are paths (e.g., "user.name") or templates (e.g., "{{item.title}}"). **CRITICAL for ListView/Table:** the `data` key MUST point to the *exact array path* (e.g., { "data": "tasks.data" } or { "data": "userList" }), NOT the parent object.'
646
+ ),
490
647
  events: zod.z.record(
491
648
  zod.z.string(),
492
649
  zod.z.object({
@@ -634,67 +791,22 @@ function createSystemEvent(type, data) {
634
791
 
635
792
  // src/env.ts
636
793
  var rawApiKeyFromEnv = process.env.VITE_OPENAI_API_KEY;
637
- var defaultApiKeyLiteral = "sk-proj-literal-default-for-debug-in-env-ts";
638
794
  var env = {
639
- MOCK_PLANNER: process.env.VITE_MOCK_PLANNER || "1",
795
+ MOCK_PLANNER: process.env.VITE_MOCK_PLANNER || "0",
640
796
  // Simplified MOCK_PLANNER assignment
641
- NODE_ENV: process.env.VITE_NODE_ENV || "development",
797
+ NODE_ENV: process.env.VITE_NODE_ENV || "production",
642
798
  // Simplified NODE_ENV assignment
643
- OPENAI_API_KEY: rawApiKeyFromEnv === void 0 ? defaultApiKeyLiteral : rawApiKeyFromEnv
799
+ OPENAI_API_KEY: rawApiKeyFromEnv || ""
644
800
  };
645
801
 
646
802
  // src/core/planner.ts
647
- var strictOpenAI = openai.createOpenAI({
648
- compatibility: "strict"
649
- // Required for structured outputs with OpenAI API
650
- });
651
- function buildPrompt(input, customPrompt) {
652
- const { schema, goal, history, userContext } = input;
653
- const schemaInfo = Object.entries(schema).map(([tableName, tableSchema]) => {
654
- return `Table: ${tableName}
655
- Schema: ${JSON.stringify(tableSchema)}`;
656
- }).join("\n\n");
657
- const recentEvents = history?.slice(-5).map(
658
- (event) => `Event: ${event.type} on node ${event.nodeId}${event.payload ? ` with payload ${JSON.stringify(event.payload)}` : ""}`
659
- ).join("\n") || "No recent events";
660
- const userContextSection = userContext ? `
661
-
662
- User Context:
663
- ${JSON.stringify(userContext)}` : "";
664
- if (customPrompt) {
665
- return customPrompt;
666
- }
667
- return `
668
- You are an expert UI generator.
669
- Create a user interface that achieves the following goal: "${goal}"
670
-
671
- Available data schema:
672
- ${schemaInfo}
673
-
674
- Recent user interactions:
675
- ${recentEvents}${userContextSection}
676
-
677
- Generate a complete UI specification in JSON format that matches the following TypeScript type:
678
- type UISpecNode = {
679
- id: string;
680
- node_type: string;
681
- props?: Record<string, unknown>;
682
- bindings?: Record<string, unknown>;
683
- events?: Record<string, { action: string; target: string; payload?: Record<string, unknown>; }>;
684
- children?: UISpecNode[];
803
+ var getOpenAIClient = (apiKey) => {
804
+ return openai.createOpenAI({
805
+ apiKey,
806
+ // Use the provided key directly
807
+ compatibility: "strict"
808
+ });
685
809
  };
686
-
687
- UI Guidance:
688
- 1. Create a focused interface that directly addresses the goal
689
- 2. Use appropriate UI patterns (lists, forms, details, etc.)
690
- 3. Include navigation between related views when needed
691
- 4. Keep the interface simple and intuitive
692
- 5. Bind to schema data where appropriate
693
- 6. Provide event handlers for user interactions - make sure to always include both action and target properties
694
-
695
- Respond ONLY with the JSON UI specification and no other text.
696
- `;
697
- }
698
810
  function mockPlanner(input, targetNodeId, customPrompt) {
699
811
  if (customPrompt) {
700
812
  console.log("mockPlanner received customPrompt:", customPrompt);
@@ -800,7 +912,7 @@ function mockPlanner(input, targetNodeId, customPrompt) {
800
912
  selectable: "true"
801
913
  },
802
914
  bindings: {
803
- items: JSON.stringify(taskData),
915
+ data: "tasks.data",
804
916
  fields: JSON.stringify([
805
917
  { key: "id", label: "ID" },
806
918
  { key: "title", label: "Title" },
@@ -853,24 +965,35 @@ function mockPlanner(input, targetNodeId, customPrompt) {
853
965
  };
854
966
  return mockNode;
855
967
  }
856
- async function callPlannerLLM(input, routeResolution) {
968
+ async function callPlannerLLM(input, openaiApiKey, routeResolution) {
857
969
  await systemEvents.emit(
858
970
  createSystemEvent("PLAN_START" /* PLAN_START */, { plannerInput: input })
859
971
  );
860
- if (env.MOCK_PLANNER === "1" || !env.OPENAI_API_KEY) {
972
+ if (env.MOCK_PLANNER === "1") {
973
+ console.warn(
974
+ `Using mock planner because MOCK_PLANNER environment variable is set to "1".`
975
+ );
976
+ return mockPlanner(input);
977
+ }
978
+ if (!openaiApiKey) {
861
979
  console.warn(
862
- "Using mock planner because MOCK_PLANNER is enabled or OPENAI_API_KEY is not available"
980
+ `OpenAI API key was not provided to callPlannerLLM. Falling back to mock planner.`
863
981
  );
864
982
  return mockPlanner(input);
865
983
  }
866
984
  const startTime = Date.now();
867
- const prompt = routeResolution?.prompt || buildPrompt(input);
985
+ const prompt = routeResolution?.prompt;
986
+ if (!prompt) {
987
+ throw new Error("ActionRouter did not provide a prompt to callPlannerLLM.");
988
+ }
868
989
  await systemEvents.emit(
869
990
  createSystemEvent("PLAN_PROMPT_CREATED" /* PLAN_PROMPT_CREATED */, { prompt })
870
991
  );
871
992
  try {
872
993
  const { object: uiSpec } = await ai.generateObject({
873
- model: strictOpenAI("gpt-4o", { structuredOutputs: true }),
994
+ model: getOpenAIClient(openaiApiKey)("gpt-4o", {
995
+ structuredOutputs: true
996
+ }),
874
997
  schema: openAIUISpec,
875
998
  messages: [{ role: "user", content: prompt }],
876
999
  temperature: 0.2,
@@ -893,7 +1016,7 @@ async function callPlannerLLM(input, routeResolution) {
893
1016
  throw error;
894
1017
  }
895
1018
  }
896
- async function processEvent(event, router, schema, layout, dataContext, goal, userContext) {
1019
+ async function processEvent(event, router, schema, layout, dataContext, goal, userContext, openaiApiKey) {
897
1020
  const routeResolution = await router.resolveRoute(
898
1021
  event,
899
1022
  schema,
@@ -913,7 +1036,11 @@ async function processEvent(event, router, schema, layout, dataContext, goal, us
913
1036
  return layout;
914
1037
  }
915
1038
  const plannerInputForLLM = routeResolution.plannerInput;
916
- const newLayout = await callPlannerLLM(plannerInputForLLM, routeResolution);
1039
+ const newLayout = await callPlannerLLM(
1040
+ plannerInputForLLM,
1041
+ openaiApiKey || "",
1042
+ routeResolution
1043
+ );
917
1044
  return newLayout;
918
1045
  }
919
1046
 
@@ -921,6 +1048,7 @@ async function processEvent(event, router, schema, layout, dataContext, goal, us
921
1048
  function useUIStateEngine({
922
1049
  schema,
923
1050
  goal,
1051
+ openaiApiKey,
924
1052
  userContext,
925
1053
  mockMode = false,
926
1054
  planningConfig,
@@ -967,7 +1095,11 @@ function useUIStateEngine({
967
1095
  route.prompt
968
1096
  );
969
1097
  } else {
970
- resolvedNode = await callPlannerLLM(route.plannerInput, route);
1098
+ resolvedNode = await callPlannerLLM(
1099
+ route.plannerInput,
1100
+ openaiApiKey || "",
1101
+ route
1102
+ );
971
1103
  }
972
1104
  } else {
973
1105
  const input = {
@@ -979,7 +1111,11 @@ function useUIStateEngine({
979
1111
  if (mockMode) {
980
1112
  resolvedNode = mockPlanner(input);
981
1113
  } else {
982
- resolvedNode = await callPlannerLLM(input);
1114
+ resolvedNode = await callPlannerLLM(
1115
+ input,
1116
+ openaiApiKey || "",
1117
+ void 0
1118
+ );
983
1119
  }
984
1120
  }
985
1121
  } else {
@@ -993,7 +1129,11 @@ function useUIStateEngine({
993
1129
  if (mockMode) {
994
1130
  resolvedNode = mockPlanner(input);
995
1131
  } else {
996
- resolvedNode = await callPlannerLLM(input);
1132
+ resolvedNode = await callPlannerLLM(
1133
+ input,
1134
+ openaiApiKey || "",
1135
+ void 0
1136
+ );
997
1137
  }
998
1138
  }
999
1139
  switch (actionTypeForDispatch) {
@@ -1039,6 +1179,7 @@ function useUIStateEngine({
1039
1179
  router,
1040
1180
  mockMode,
1041
1181
  dataContext,
1182
+ openaiApiKey,
1042
1183
  enablePartialUpdates,
1043
1184
  dispatch
1044
1185
  // Add dispatch
@@ -1052,13 +1193,48 @@ function useUIStateEngine({
1052
1193
  schema,
1053
1194
  goal,
1054
1195
  history: [],
1196
+ // Initial history is empty
1055
1197
  userContext
1056
1198
  };
1057
1199
  let node;
1058
1200
  if (mockMode) {
1059
1201
  node = mockPlanner(input);
1060
1202
  } else {
1061
- node = await callPlannerLLM(input);
1203
+ const initEvent = {
1204
+ type: "INIT",
1205
+ // Assuming "INIT" is your initial event type
1206
+ nodeId: "system",
1207
+ // Or some other appropriate initial nodeId
1208
+ timestamp: Date.now(),
1209
+ payload: null
1210
+ };
1211
+ const route = router.resolveRoute(
1212
+ initEvent,
1213
+ schema,
1214
+ null,
1215
+ // No existing layout on initial fetch
1216
+ dataContext,
1217
+ goal,
1218
+ userContext
1219
+ );
1220
+ if (!route || !route.prompt) {
1221
+ console.error(
1222
+ "[UIStateEngine] Initial fetch: Failed to resolve route or get prompt for INIT event."
1223
+ );
1224
+ throw new Error("Failed to initialize UI due to routing error.");
1225
+ }
1226
+ systemEvents.emit(
1227
+ createSystemEvent("PLAN_START" /* PLAN_START */, {
1228
+ plannerInput: route.plannerInput
1229
+ })
1230
+ );
1231
+ node = await callPlannerLLM(
1232
+ route.plannerInput,
1233
+ // Use plannerInput from the resolved route
1234
+ openaiApiKey || "",
1235
+ route
1236
+ // Pass the entire route object
1237
+ );
1062
1238
  }
1063
1239
  dispatch({ type: "AI_RESPONSE", node });
1064
1240
  } catch (e) {
@@ -1075,135 +1251,531 @@ function useUIStateEngine({
1075
1251
  }
1076
1252
  };
1077
1253
  initialFetch();
1078
- }, [goal, schema, userContext, mockMode, dispatch]);
1254
+ }, [goal, schema, userContext, mockMode, dispatch, openaiApiKey]);
1079
1255
  return {
1080
1256
  state,
1081
1257
  dispatch,
1082
1258
  handleEvent
1083
1259
  };
1084
1260
  }
1085
- zod.z.enum([
1086
- // Layout components
1087
- "Container",
1088
- "Card",
1089
- "Header",
1090
- // Input components
1091
- "Button",
1092
- "Input",
1093
- "Select",
1094
- "Textarea",
1095
- "Checkbox",
1096
- "RadioGroup",
1097
- // Data display components
1098
- "ListView",
1099
- "Detail",
1100
- "Tabs",
1101
- "Dialog",
1102
- // Typography
1103
- "Heading",
1104
- "Text"
1105
- ]);
1106
- var ShimmerBlock = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-8 bg-gray-200 animate-pulse rounded" });
1107
- var ShimmerTable = ({ rows = 3 }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full space-y-2", children: [
1108
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-10 bg-gray-200 animate-pulse rounded" }),
1109
- Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-12 bg-gray-200 animate-pulse rounded" }, i))
1110
- ] });
1111
- var ShimmerCard = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full p-4 space-y-4 border rounded-lg", children: [
1112
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-3/4 h-6 bg-gray-200 animate-pulse rounded" }),
1113
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
1114
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-4 bg-gray-200 animate-pulse rounded" }),
1115
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-4 bg-gray-200 animate-pulse rounded" }),
1116
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-5/6 h-4 bg-gray-200 animate-pulse rounded" })
1117
- ] })
1118
- ] });
1119
- var Container = (props) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `autoui-mock-container ${props.className || ""}`, children: props.children });
1120
- var Header = ({
1121
- title,
1122
- className
1123
- }) => /* @__PURE__ */ jsxRuntime.jsx(
1124
- "header",
1125
- {
1126
- className: `py-4 px-6 border-b border-gray-300 mb-4 bg-gray-50 dark:bg-gray-800 ${className || ""}`,
1127
- children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-gray-800 dark:text-white", children: title })
1128
- }
1129
- );
1130
- var Button = ({ onClick, children, variant = "default" }) => /* @__PURE__ */ jsxRuntime.jsx(
1131
- "button",
1132
- {
1133
- className: `px-4 py-2 rounded-md font-medium transition-colors ${variant === "default" ? "bg-blue-600 text-white hover:bg-blue-700" : variant === "outline" ? "border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800" : "bg-red-600 text-white hover:bg-red-700"}`,
1134
- onClick,
1135
- children
1136
- }
1137
- );
1138
- var Table = ({ items = [], fields = [], onSelect, selectable }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full border border-gray-300 dark:border-gray-700 rounded-lg overflow-hidden shadow-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full", children: [
1139
- /* @__PURE__ */ jsxRuntime.jsx("thead", { className: "bg-gray-100 dark:bg-gray-800 border-b border-gray-300 dark:border-gray-700", children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: fields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1140
- "th",
1141
- {
1142
- className: "px-6 py-3 text-left text-xs font-medium text-gray-700 dark:text-gray-300 uppercase tracking-wider",
1143
- children: field.label
1144
- },
1145
- field.key
1146
- )) }) }),
1147
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "bg-white dark:bg-gray-900 divide-y divide-gray-200 dark:divide-gray-700", children: items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
1148
- "tr",
1261
+
1262
+ // src/adapters/shadcn.tsx
1263
+ init_utils();
1264
+
1265
+ // components/ui/dialog.tsx
1266
+ init_utils();
1267
+ function Dialog({
1268
+ ...props
1269
+ }) {
1270
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Root, { "data-slot": "dialog", ...props });
1271
+ }
1272
+ function DialogPortal({
1273
+ ...props
1274
+ }) {
1275
+ return /* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Portal, { "data-slot": "dialog-portal", ...props });
1276
+ }
1277
+ function DialogOverlay({
1278
+ className,
1279
+ ...props
1280
+ }) {
1281
+ return /* @__PURE__ */ jsxRuntime.jsx(
1282
+ DialogPrimitive__namespace.Overlay,
1149
1283
  {
1150
- onClick: () => selectable && onSelect && onSelect(item),
1151
- className: selectable ? "cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-800" : "",
1152
- children: fields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
1153
- "td",
1154
- {
1155
- className: "px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-300",
1156
- children: item[field.key] ?? ""
1157
- },
1158
- field.key
1159
- ))
1160
- },
1161
- index
1162
- )) })
1163
- ] }) });
1164
- var Detail = ({ data, fields = [], title, visible = true, onBack }) => {
1165
- if (!visible)
1166
- return null;
1167
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full border border-gray-300 dark:border-gray-700 rounded-lg p-6 space-y-4 bg-white dark:bg-gray-900 shadow-sm", children: [
1168
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center border-b border-gray-200 dark:border-gray-700 pb-3", children: [
1169
- title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-medium text-gray-800 dark:text-white", children: title }),
1170
- onBack && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: onBack, children: "Back" })
1171
- ] }),
1172
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: fields.map((field) => {
1173
- if (field.type === "heading") {
1174
- return /* @__PURE__ */ jsxRuntime.jsx(
1175
- "h3",
1176
- {
1177
- className: "text-xl font-semibold text-gray-800 dark:text-white",
1178
- children: data?.[field.key] ?? ""
1179
- },
1180
- field.key
1181
- );
1182
- }
1183
- if (field.type === "content") {
1184
- return /* @__PURE__ */ jsxRuntime.jsx(
1185
- "div",
1186
- {
1187
- className: "text-sm text-gray-700 dark:text-gray-300",
1188
- children: data?.[field.key] ?? ""
1189
- },
1190
- field.key
1191
- );
1284
+ "data-slot": "dialog-overlay",
1285
+ className: cn(
1286
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
1287
+ className
1288
+ ),
1289
+ ...props
1290
+ }
1291
+ );
1292
+ }
1293
+ function DialogContent({
1294
+ className,
1295
+ children,
1296
+ ...props
1297
+ }) {
1298
+ return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { "data-slot": "dialog-portal", children: [
1299
+ /* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
1300
+ /* @__PURE__ */ jsxRuntime.jsxs(
1301
+ DialogPrimitive__namespace.Content,
1302
+ {
1303
+ "data-slot": "dialog-content",
1304
+ className: cn(
1305
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
1306
+ className
1307
+ ),
1308
+ ...props,
1309
+ children: [
1310
+ children,
1311
+ /* @__PURE__ */ jsxRuntime.jsxs(DialogPrimitive__namespace.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", children: [
1312
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {}),
1313
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: "Close" })
1314
+ ] })
1315
+ ]
1192
1316
  }
1193
- return /* @__PURE__ */ jsxRuntime.jsxs(
1194
- "div",
1195
- {
1196
- className: "flex flex-col border-b border-gray-100 dark:border-gray-800 py-2",
1197
- children: [
1198
- field.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-600 dark:text-gray-400 font-medium", children: field.label }),
1199
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-800 dark:text-gray-200", children: data?.[field.key] ?? "" })
1200
- ]
1201
- },
1202
- field.key
1203
- );
1204
- }) })
1317
+ )
1205
1318
  ] });
1206
- };
1319
+ }
1320
+ function DialogHeader({ className, ...props }) {
1321
+ return /* @__PURE__ */ jsxRuntime.jsx(
1322
+ "div",
1323
+ {
1324
+ "data-slot": "dialog-header",
1325
+ className: cn("flex flex-col gap-2 text-center sm:text-left", className),
1326
+ ...props
1327
+ }
1328
+ );
1329
+ }
1330
+ function DialogTitle({
1331
+ className,
1332
+ ...props
1333
+ }) {
1334
+ return /* @__PURE__ */ jsxRuntime.jsx(
1335
+ DialogPrimitive__namespace.Title,
1336
+ {
1337
+ "data-slot": "dialog-title",
1338
+ className: cn("text-lg leading-none font-semibold", className),
1339
+ ...props
1340
+ }
1341
+ );
1342
+ }
1343
+ function DialogDescription({
1344
+ className,
1345
+ ...props
1346
+ }) {
1347
+ return /* @__PURE__ */ jsxRuntime.jsx(
1348
+ DialogPrimitive__namespace.Description,
1349
+ {
1350
+ "data-slot": "dialog-description",
1351
+ className: cn("text-muted-foreground text-sm", className),
1352
+ ...props
1353
+ }
1354
+ );
1355
+ }
1356
+
1357
+ // components/ui/card.tsx
1358
+ init_utils();
1359
+ function Card({ className, ...props }) {
1360
+ return /* @__PURE__ */ jsxRuntime.jsx(
1361
+ "div",
1362
+ {
1363
+ "data-slot": "card",
1364
+ className: cn(
1365
+ "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
1366
+ className
1367
+ ),
1368
+ ...props
1369
+ }
1370
+ );
1371
+ }
1372
+ function CardContent({ className, ...props }) {
1373
+ return /* @__PURE__ */ jsxRuntime.jsx(
1374
+ "div",
1375
+ {
1376
+ "data-slot": "card-content",
1377
+ className: cn("px-6", className),
1378
+ ...props
1379
+ }
1380
+ );
1381
+ }
1382
+
1383
+ // components/ui/input.tsx
1384
+ init_utils();
1385
+ function Input({ className, type, ...props }) {
1386
+ return /* @__PURE__ */ jsxRuntime.jsx(
1387
+ "input",
1388
+ {
1389
+ type,
1390
+ "data-slot": "input",
1391
+ className: cn(
1392
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
1393
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
1394
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
1395
+ className
1396
+ ),
1397
+ ...props
1398
+ }
1399
+ );
1400
+ }
1401
+
1402
+ // components/ui/textarea.tsx
1403
+ init_utils();
1404
+ function Textarea({ className, ...props }) {
1405
+ return /* @__PURE__ */ jsxRuntime.jsx(
1406
+ "textarea",
1407
+ {
1408
+ "data-slot": "textarea",
1409
+ className: cn(
1410
+ "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
1411
+ className
1412
+ ),
1413
+ ...props
1414
+ }
1415
+ );
1416
+ }
1417
+
1418
+ // components/ui/select.tsx
1419
+ init_utils();
1420
+ function Select({
1421
+ ...props
1422
+ }) {
1423
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Root, { "data-slot": "select", ...props });
1424
+ }
1425
+ function SelectValue({
1426
+ ...props
1427
+ }) {
1428
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Value, { "data-slot": "select-value", ...props });
1429
+ }
1430
+ function SelectTrigger({
1431
+ className,
1432
+ size = "default",
1433
+ children,
1434
+ ...props
1435
+ }) {
1436
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1437
+ SelectPrimitive__namespace.Trigger,
1438
+ {
1439
+ "data-slot": "select-trigger",
1440
+ "data-size": size,
1441
+ className: cn(
1442
+ "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1443
+ className
1444
+ ),
1445
+ ...props,
1446
+ children: [
1447
+ children,
1448
+ /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Icon, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "size-4 opacity-50" }) })
1449
+ ]
1450
+ }
1451
+ );
1452
+ }
1453
+ function SelectContent({
1454
+ className,
1455
+ children,
1456
+ position = "popper",
1457
+ ...props
1458
+ }) {
1459
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
1460
+ SelectPrimitive__namespace.Content,
1461
+ {
1462
+ "data-slot": "select-content",
1463
+ className: cn(
1464
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
1465
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
1466
+ className
1467
+ ),
1468
+ position,
1469
+ ...props,
1470
+ children: [
1471
+ /* @__PURE__ */ jsxRuntime.jsx(SelectScrollUpButton, {}),
1472
+ /* @__PURE__ */ jsxRuntime.jsx(
1473
+ SelectPrimitive__namespace.Viewport,
1474
+ {
1475
+ className: cn(
1476
+ "p-1",
1477
+ position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1"
1478
+ ),
1479
+ children
1480
+ }
1481
+ ),
1482
+ /* @__PURE__ */ jsxRuntime.jsx(SelectScrollDownButton, {})
1483
+ ]
1484
+ }
1485
+ ) });
1486
+ }
1487
+ function SelectItem({
1488
+ className,
1489
+ children,
1490
+ ...props
1491
+ }) {
1492
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1493
+ SelectPrimitive__namespace.Item,
1494
+ {
1495
+ "data-slot": "select-item",
1496
+ className: cn(
1497
+ "focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
1498
+ className
1499
+ ),
1500
+ ...props,
1501
+ children: [
1502
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "size-4" }) }) }),
1503
+ /* @__PURE__ */ jsxRuntime.jsx(SelectPrimitive__namespace.ItemText, { children })
1504
+ ]
1505
+ }
1506
+ );
1507
+ }
1508
+ function SelectScrollUpButton({
1509
+ className,
1510
+ ...props
1511
+ }) {
1512
+ return /* @__PURE__ */ jsxRuntime.jsx(
1513
+ SelectPrimitive__namespace.ScrollUpButton,
1514
+ {
1515
+ "data-slot": "select-scroll-up-button",
1516
+ className: cn(
1517
+ "flex cursor-default items-center justify-center py-1",
1518
+ className
1519
+ ),
1520
+ ...props,
1521
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronUpIcon, { className: "size-4" })
1522
+ }
1523
+ );
1524
+ }
1525
+ function SelectScrollDownButton({
1526
+ className,
1527
+ ...props
1528
+ }) {
1529
+ return /* @__PURE__ */ jsxRuntime.jsx(
1530
+ SelectPrimitive__namespace.ScrollDownButton,
1531
+ {
1532
+ "data-slot": "select-scroll-down-button",
1533
+ className: cn(
1534
+ "flex cursor-default items-center justify-center py-1",
1535
+ className
1536
+ ),
1537
+ ...props,
1538
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDownIcon, { className: "size-4" })
1539
+ }
1540
+ );
1541
+ }
1542
+
1543
+ // components/ui/checkbox.tsx
1544
+ init_utils();
1545
+ function Checkbox({
1546
+ className,
1547
+ ...props
1548
+ }) {
1549
+ return /* @__PURE__ */ jsxRuntime.jsx(
1550
+ CheckboxPrimitive__namespace.Root,
1551
+ {
1552
+ "data-slot": "checkbox",
1553
+ className: cn(
1554
+ "peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
1555
+ className
1556
+ ),
1557
+ ...props,
1558
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1559
+ CheckboxPrimitive__namespace.Indicator,
1560
+ {
1561
+ "data-slot": "checkbox-indicator",
1562
+ className: "flex items-center justify-center text-current transition-none",
1563
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckIcon, { className: "size-3.5" })
1564
+ }
1565
+ )
1566
+ }
1567
+ );
1568
+ }
1569
+
1570
+ // components/ui/radio-group.tsx
1571
+ init_utils();
1572
+ function RadioGroup({
1573
+ className,
1574
+ ...props
1575
+ }) {
1576
+ return /* @__PURE__ */ jsxRuntime.jsx(
1577
+ RadioGroupPrimitive__namespace.Root,
1578
+ {
1579
+ "data-slot": "radio-group",
1580
+ className: cn("grid gap-3", className),
1581
+ ...props
1582
+ }
1583
+ );
1584
+ }
1585
+ function RadioGroupItem({
1586
+ className,
1587
+ ...props
1588
+ }) {
1589
+ return /* @__PURE__ */ jsxRuntime.jsx(
1590
+ RadioGroupPrimitive__namespace.Item,
1591
+ {
1592
+ "data-slot": "radio-group-item",
1593
+ className: cn(
1594
+ "border-input text-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 aspect-square size-4 shrink-0 rounded-full border shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
1595
+ className
1596
+ ),
1597
+ ...props,
1598
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1599
+ RadioGroupPrimitive__namespace.Indicator,
1600
+ {
1601
+ "data-slot": "radio-group-indicator",
1602
+ className: "relative flex items-center justify-center",
1603
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleIcon, { className: "fill-primary absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2" })
1604
+ }
1605
+ )
1606
+ }
1607
+ );
1608
+ }
1609
+
1610
+ // components/ui/tabs.tsx
1611
+ init_utils();
1612
+ function Tabs({
1613
+ className,
1614
+ ...props
1615
+ }) {
1616
+ return /* @__PURE__ */ jsxRuntime.jsx(
1617
+ TabsPrimitive__namespace.Root,
1618
+ {
1619
+ "data-slot": "tabs",
1620
+ className: cn("flex flex-col gap-2", className),
1621
+ ...props
1622
+ }
1623
+ );
1624
+ }
1625
+ function TabsList({
1626
+ className,
1627
+ ...props
1628
+ }) {
1629
+ return /* @__PURE__ */ jsxRuntime.jsx(
1630
+ TabsPrimitive__namespace.List,
1631
+ {
1632
+ "data-slot": "tabs-list",
1633
+ className: cn(
1634
+ "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
1635
+ className
1636
+ ),
1637
+ ...props
1638
+ }
1639
+ );
1640
+ }
1641
+ function TabsTrigger({
1642
+ className,
1643
+ ...props
1644
+ }) {
1645
+ return /* @__PURE__ */ jsxRuntime.jsx(
1646
+ TabsPrimitive__namespace.Trigger,
1647
+ {
1648
+ "data-slot": "tabs-trigger",
1649
+ className: cn(
1650
+ "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1651
+ className
1652
+ ),
1653
+ ...props
1654
+ }
1655
+ );
1656
+ }
1657
+ function TabsContent({
1658
+ className,
1659
+ ...props
1660
+ }) {
1661
+ return /* @__PURE__ */ jsxRuntime.jsx(
1662
+ TabsPrimitive__namespace.Content,
1663
+ {
1664
+ "data-slot": "tabs-content",
1665
+ className: cn("flex-1 outline-none", className),
1666
+ ...props
1667
+ }
1668
+ );
1669
+ }
1670
+
1671
+ // components/ui/label.tsx
1672
+ init_utils();
1673
+ function Label2({
1674
+ className,
1675
+ ...props
1676
+ }) {
1677
+ return /* @__PURE__ */ jsxRuntime.jsx(
1678
+ LabelPrimitive__namespace.Root,
1679
+ {
1680
+ "data-slot": "label",
1681
+ className: cn(
1682
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
1683
+ className
1684
+ ),
1685
+ ...props
1686
+ }
1687
+ );
1688
+ }
1689
+ var parseStyleString = (styleString) => {
1690
+ if (typeof styleString !== "string") {
1691
+ return typeof styleString === "object" ? styleString : {};
1692
+ }
1693
+ const style = {};
1694
+ styleString.split(";").forEach((declaration) => {
1695
+ const [property, value] = declaration.split(":");
1696
+ if (property && value) {
1697
+ const camelCasedProperty = property.trim().replace(/-([a-z])/g, (g) => g[1].toUpperCase());
1698
+ style[camelCasedProperty] = value.trim();
1699
+ }
1700
+ });
1701
+ return style;
1702
+ };
1703
+ var isArrayOf = (guard) => (arr) => Array.isArray(arr) && arr.every(guard);
1704
+ var ShimmerBlock = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-8 bg-gray-200 animate-pulse rounded" });
1705
+ var ShimmerTable = ({ rows = 3 }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full space-y-2", children: [
1706
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-10 bg-gray-200 animate-pulse rounded" }),
1707
+ Array.from({ length: rows }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-12 bg-gray-200 animate-pulse rounded" }, i))
1708
+ ] });
1709
+ var ShimmerCard = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full p-4 space-y-4 border rounded-lg", children: [
1710
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-3/4 h-6 bg-gray-200 animate-pulse rounded" }),
1711
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
1712
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-4 bg-gray-200 animate-pulse rounded" }),
1713
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full h-4 bg-gray-200 animate-pulse rounded" }),
1714
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-5/6 h-4 bg-gray-200 animate-pulse rounded" })
1715
+ ] })
1716
+ ] });
1717
+ var Container = (props) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `autoui-mock-container ${props.className || ""}`, children: props.children });
1718
+ var Header = ({
1719
+ title,
1720
+ className
1721
+ }) => /* @__PURE__ */ jsxRuntime.jsx(
1722
+ "header",
1723
+ {
1724
+ className: `py-4 px-6 border-b border-gray-300 mb-4 bg-gray-50 dark:bg-gray-800 ${className || ""}`,
1725
+ children: /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-semibold text-gray-800 dark:text-white", children: title })
1726
+ }
1727
+ );
1728
+ var Button = ({ onClick, children, variant = "default" }) => /* @__PURE__ */ jsxRuntime.jsx(
1729
+ "button",
1730
+ {
1731
+ className: `px-4 py-2 rounded-md font-medium transition-colors ${variant === "default" ? "bg-blue-600 text-white hover:bg-blue-700" : variant === "outline" ? "border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-800" : "bg-red-600 text-white hover:bg-red-700"}`,
1732
+ onClick: () => onClick?.(),
1733
+ children
1734
+ }
1735
+ );
1736
+ var Detail = ({ data, fields = [], title, visible = true, onBack }) => {
1737
+ if (!visible)
1738
+ return null;
1739
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full border border-gray-300 dark:border-gray-700 rounded-lg p-6 space-y-4 bg-white dark:bg-gray-900 shadow-sm", children: [
1740
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center border-b border-gray-200 dark:border-gray-700 pb-3", children: [
1741
+ title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-medium text-gray-800 dark:text-white", children: title }),
1742
+ onBack && /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "outline", onClick: onBack, children: "Back" })
1743
+ ] }),
1744
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: fields.map((field) => {
1745
+ if (field.type === "heading") {
1746
+ return /* @__PURE__ */ jsxRuntime.jsx(
1747
+ "h3",
1748
+ {
1749
+ className: "text-xl font-semibold text-gray-800 dark:text-white",
1750
+ children: data?.[field.key] ?? ""
1751
+ },
1752
+ field.key
1753
+ );
1754
+ }
1755
+ if (field.type === "content") {
1756
+ return /* @__PURE__ */ jsxRuntime.jsx(
1757
+ "div",
1758
+ {
1759
+ className: "text-sm text-gray-700 dark:text-gray-300",
1760
+ children: data?.[field.key] ?? ""
1761
+ },
1762
+ field.key
1763
+ );
1764
+ }
1765
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1766
+ "div",
1767
+ {
1768
+ className: "flex flex-col border-b border-gray-100 dark:border-gray-800 py-2",
1769
+ children: [
1770
+ field.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-gray-600 dark:text-gray-400 font-medium", children: field.label }),
1771
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-800 dark:text-gray-200", children: data?.[field.key] ?? "" })
1772
+ ]
1773
+ },
1774
+ field.key
1775
+ );
1776
+ }) })
1777
+ ] });
1778
+ };
1207
1779
  var getSafeProp = (props, key, validator, defaultValue) => {
1208
1780
  if (props && typeof props === "object" && key in props) {
1209
1781
  const value = props[key];
@@ -1216,7 +1788,6 @@ var getSafeProp = (props, key, validator, defaultValue) => {
1216
1788
  var isObject = (value) => typeof value === "object" && value !== null;
1217
1789
  var isString = (value) => typeof value === "string";
1218
1790
  var isBoolean = (value) => typeof value === "boolean";
1219
- var isCSSProperties = (value) => isObject(value);
1220
1791
  var isButtonVariant = (value) => isString(value) && ["default", "outline", "destructive"].includes(value);
1221
1792
  var getSafeBinding = (bindings, key, validator, defaultValue) => {
1222
1793
  if (bindings && typeof bindings === "object" && key in bindings) {
@@ -1227,12 +1798,20 @@ var getSafeBinding = (bindings, key, validator, defaultValue) => {
1227
1798
  }
1228
1799
  return defaultValue;
1229
1800
  };
1230
- var isArrayOf = (itemValidator) => (arr) => Array.isArray(arr) && arr.every(itemValidator);
1231
1801
  var isReactNode = (value) => {
1232
1802
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null || typeof value === "undefined" || typeof value === "object" && value !== null && "$$typeof" in value;
1233
1803
  };
1234
1804
  var isRecordWithReactNodeValues = (value) => isObject(value) && Object.values(value).every(isReactNode);
1235
- var isFieldObject = (item) => isObject(item) && isString(item.key) && isString(item.label);
1805
+ var isSelectOptionObject = (item) => isObject(item) && isString(item.value) && isString(item.label);
1806
+ var isTabObject = (item) => (
1807
+ // Allow content to be optional initially
1808
+ isObject(item) && isString(item.value) && isString(item.label) && (item.content === void 0 || isUISpecNode(item.content))
1809
+ );
1810
+ var isUISpecNode = (value) => {
1811
+ if (!isObject(value))
1812
+ return false;
1813
+ return isString(value.id) && isString(value.node_type);
1814
+ };
1236
1815
  var isDetailFieldObject = (item) => isObject(item) && isString(item.key) && isString(item.label) && (item.type === void 0 || isString(item.type));
1237
1816
  var createEventHandler = (node, eventName, uiEventType2, processEvent2) => {
1238
1817
  const eventConfig = node.events?.[uiEventType2];
@@ -1252,14 +1831,36 @@ var createEventHandler = (node, eventName, uiEventType2, processEvent2) => {
1252
1831
  };
1253
1832
  };
1254
1833
  var adapterMap = {
1255
- Container: (node, processEvent2) => /* @__PURE__ */ jsxRuntime.jsx(
1256
- Container,
1257
- {
1258
- style: getSafeProp(node.props, "style", isCSSProperties, {}),
1259
- className: getSafeProp(node.props, "className", isString, ""),
1260
- children: node.children?.map((child) => renderNode(child, processEvent2))
1261
- }
1262
- ),
1834
+ Container: (node, processEvent2) => {
1835
+ const { className, style: styleProp, key, ...restProps } = node.props || {};
1836
+ const children = node.children?.map(
1837
+ (child) => (
1838
+ // Use React.cloneElement to add the key prop to the element returned by renderNode
1839
+ React__default.default.cloneElement(renderNode(child, processEvent2), { key: child.id })
1840
+ )
1841
+ );
1842
+ const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
1843
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1844
+ "div",
1845
+ {
1846
+ className: cn("autoui-container", className),
1847
+ style,
1848
+ ...restProps,
1849
+ "data-id": node.id,
1850
+ children: [
1851
+ (() => {
1852
+ console.log(
1853
+ `[Adapter Debug] Rendering Container: id=${node.id}, props=`,
1854
+ node.props
1855
+ );
1856
+ return null;
1857
+ })(),
1858
+ children
1859
+ ]
1860
+ },
1861
+ key
1862
+ );
1863
+ },
1263
1864
  Header: (node) => /* @__PURE__ */ jsxRuntime.jsx(
1264
1865
  Header,
1265
1866
  {
@@ -1276,37 +1877,28 @@ var adapterMap = {
1276
1877
  }
1277
1878
  ),
1278
1879
  ListView: (node, processEvent2) => {
1279
- const items = getSafeBinding(
1280
- node.bindings,
1281
- "items",
1282
- isArrayOf(isRecordWithReactNodeValues),
1283
- []
1880
+ const { className, style: styleProp, key, ...restProps } = node.props || {};
1881
+ const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
1882
+ console.log(
1883
+ `[Adapter Debug] Rendering ListView: id=${node.id}, props=`,
1884
+ node.props
1284
1885
  );
1285
- const fields = getSafeBinding(
1286
- node.bindings,
1287
- "fields",
1288
- isArrayOf(isFieldObject),
1289
- []
1886
+ const children = node.children?.map(
1887
+ (child) => React__default.default.cloneElement(renderNode(child, processEvent2), { key: child.id })
1290
1888
  );
1291
- const selectable = getSafeProp(node.props, "selectable", isBoolean, false);
1292
1889
  return /* @__PURE__ */ jsxRuntime.jsx(
1293
- Table,
1890
+ "div",
1294
1891
  {
1295
- items,
1296
- fields,
1297
- selectable,
1298
- onSelect: (item) => {
1299
- const handler = createEventHandler(
1300
- node,
1301
- "onSelect",
1302
- "CLICK",
1303
- processEvent2
1304
- );
1305
- if (handler) {
1306
- handler({ selectedItem: item });
1307
- }
1308
- }
1309
- }
1892
+ className: cn(
1893
+ "autoui-listview-container space-y-2",
1894
+ className
1895
+ ),
1896
+ style,
1897
+ ...restProps,
1898
+ "data-id": node.id,
1899
+ children
1900
+ },
1901
+ key
1310
1902
  );
1311
1903
  },
1312
1904
  Detail: (node, processEvent2) => {
@@ -1334,6 +1926,449 @@ var adapterMap = {
1334
1926
  onBack: createEventHandler(node, "onBack", "CLICK", processEvent2)
1335
1927
  }
1336
1928
  );
1929
+ },
1930
+ Card: (node, processEvent2) => {
1931
+ const { className, style: styleProp, key, ...restProps } = node.props || {};
1932
+ const children = node.children?.map(
1933
+ (child) => React__default.default.cloneElement(renderNode(child, processEvent2), { key: child.id })
1934
+ );
1935
+ const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
1936
+ return /* @__PURE__ */ jsxRuntime.jsx(
1937
+ Card,
1938
+ {
1939
+ className: cn("autoui-card", className),
1940
+ style,
1941
+ ...restProps,
1942
+ "data-id": node.id,
1943
+ children: /* @__PURE__ */ jsxRuntime.jsxs(CardContent, { className: "p-0", children: [
1944
+ " ",
1945
+ children
1946
+ ] })
1947
+ },
1948
+ key
1949
+ );
1950
+ },
1951
+ Input: (node, processEvent2) => {
1952
+ const name = getSafeProp(node.props, "name", isString, "inputName");
1953
+ const label = getSafeProp(node.props, "label", isString, "");
1954
+ const value = getSafeBinding(node.bindings, "value", isString, "");
1955
+ const placeholder = getSafeProp(node.props, "placeholder", isString, "");
1956
+ const disabled = getSafeProp(node.props, "disabled", isBoolean, false);
1957
+ const className = getSafeProp(node.props, "className", isString, "");
1958
+ const handleChange = (e) => {
1959
+ const handler = createEventHandler(
1960
+ node,
1961
+ "onChange",
1962
+ "CHANGE",
1963
+ processEvent2
1964
+ );
1965
+ if (handler)
1966
+ handler({ value: e.target.value });
1967
+ };
1968
+ const handleFocus = () => {
1969
+ const handler = createEventHandler(
1970
+ node,
1971
+ "onFocus",
1972
+ "FOCUS",
1973
+ processEvent2
1974
+ );
1975
+ if (handler)
1976
+ handler({});
1977
+ };
1978
+ const handleBlur = () => {
1979
+ const handler = createEventHandler(node, "onBlur", "BLUR", processEvent2);
1980
+ if (handler)
1981
+ handler({});
1982
+ };
1983
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid w-full max-w-sm items-center gap-1.5", children: [
1984
+ label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: name, children: label }),
1985
+ /* @__PURE__ */ jsxRuntime.jsx(
1986
+ Input,
1987
+ {
1988
+ id: name,
1989
+ name,
1990
+ placeholder,
1991
+ disabled,
1992
+ value,
1993
+ onChange: handleChange,
1994
+ onFocus: handleFocus,
1995
+ onBlur: handleBlur,
1996
+ className
1997
+ }
1998
+ )
1999
+ ] });
2000
+ },
2001
+ Select: (node, processEvent2) => {
2002
+ const name = getSafeProp(node.props, "name", isString, "selectName");
2003
+ const label = getSafeProp(node.props, "label", isString, "");
2004
+ const placeholder = getSafeProp(
2005
+ node.props,
2006
+ "placeholder",
2007
+ isString,
2008
+ "Select..."
2009
+ );
2010
+ const disabled = getSafeProp(node.props, "disabled", isBoolean, false);
2011
+ const value = getSafeBinding(node.bindings, "value", isString, "");
2012
+ const options = getSafeBinding(
2013
+ node.bindings,
2014
+ "options",
2015
+ isArrayOf(isSelectOptionObject),
2016
+ []
2017
+ );
2018
+ const className = getSafeProp(node.props, "className", isString, "");
2019
+ const handleValueChange = (selectedValue) => {
2020
+ const handler = createEventHandler(
2021
+ node,
2022
+ "onValueChange",
2023
+ "CHANGE",
2024
+ processEvent2
2025
+ );
2026
+ if (handler)
2027
+ handler({ value: selectedValue });
2028
+ };
2029
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2030
+ "div",
2031
+ {
2032
+ className: cn("grid w-full max-w-sm items-center gap-1.5", className),
2033
+ children: [
2034
+ label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: name, children: label }),
2035
+ /* @__PURE__ */ jsxRuntime.jsxs(
2036
+ Select,
2037
+ {
2038
+ name,
2039
+ value,
2040
+ onValueChange: handleValueChange,
2041
+ disabled,
2042
+ children: [
2043
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { id: name, children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder }) }),
2044
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
2045
+ ]
2046
+ }
2047
+ )
2048
+ ]
2049
+ }
2050
+ );
2051
+ },
2052
+ Textarea: (node, processEvent2) => {
2053
+ const { key, ...propsWithoutKey } = node.props || {};
2054
+ const name = getSafeProp(propsWithoutKey, "name", isString, "textareaName");
2055
+ const label = getSafeProp(propsWithoutKey, "label", isString, "");
2056
+ const placeholder = getSafeProp(
2057
+ propsWithoutKey,
2058
+ "placeholder",
2059
+ isString,
2060
+ ""
2061
+ );
2062
+ const disabled = getSafeProp(propsWithoutKey, "disabled", isBoolean, false);
2063
+ const rows = getSafeProp(
2064
+ propsWithoutKey,
2065
+ "rows",
2066
+ (v) => typeof v === "number",
2067
+ 3
2068
+ );
2069
+ const value = getSafeBinding(node.bindings, "value", isString, "");
2070
+ const className = getSafeProp(propsWithoutKey, "className", isString, "");
2071
+ const handleChange = (e) => {
2072
+ const handler = createEventHandler(
2073
+ node,
2074
+ "onChange",
2075
+ "CHANGE",
2076
+ processEvent2
2077
+ );
2078
+ if (handler)
2079
+ handler({ value: e.target.value });
2080
+ };
2081
+ const handleFocus = () => {
2082
+ const handler = createEventHandler(
2083
+ node,
2084
+ "onFocus",
2085
+ "FOCUS",
2086
+ processEvent2
2087
+ );
2088
+ if (handler)
2089
+ handler({});
2090
+ };
2091
+ const handleBlur = () => {
2092
+ const handler = createEventHandler(node, "onBlur", "BLUR", processEvent2);
2093
+ if (handler)
2094
+ handler({});
2095
+ };
2096
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid w-full gap-1.5", children: [
2097
+ label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: name, children: label }),
2098
+ /* @__PURE__ */ jsxRuntime.jsx(
2099
+ Textarea,
2100
+ {
2101
+ id: name,
2102
+ name,
2103
+ placeholder,
2104
+ disabled,
2105
+ rows,
2106
+ value,
2107
+ onChange: handleChange,
2108
+ onFocus: handleFocus,
2109
+ onBlur: handleBlur,
2110
+ className
2111
+ }
2112
+ )
2113
+ ] }, key);
2114
+ },
2115
+ Checkbox: (node, processEvent2) => {
2116
+ const { key, ...propsWithoutKey } = node.props || {};
2117
+ const name = getSafeProp(propsWithoutKey, "name", isString, "checkboxName");
2118
+ const label = getSafeProp(propsWithoutKey, "label", isString, "");
2119
+ const checked = getSafeBinding(node.bindings, "checked", isBoolean, false);
2120
+ const disabled = getSafeProp(propsWithoutKey, "disabled", isBoolean, false);
2121
+ const className = getSafeProp(propsWithoutKey, "className", isString, "");
2122
+ const handleCheckedChange = (isChecked) => {
2123
+ if (typeof isChecked === "boolean") {
2124
+ const handler = createEventHandler(
2125
+ node,
2126
+ "onCheckedChange",
2127
+ "CHANGE",
2128
+ processEvent2
2129
+ );
2130
+ if (handler)
2131
+ handler({ checked: isChecked });
2132
+ }
2133
+ };
2134
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2135
+ "div",
2136
+ {
2137
+ className: cn("flex items-center space-x-2", className),
2138
+ children: [
2139
+ /* @__PURE__ */ jsxRuntime.jsx(
2140
+ Checkbox,
2141
+ {
2142
+ id: name,
2143
+ name,
2144
+ checked,
2145
+ disabled,
2146
+ onCheckedChange: handleCheckedChange
2147
+ }
2148
+ ),
2149
+ label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { htmlFor: name, className: "cursor-pointer", children: label })
2150
+ ]
2151
+ },
2152
+ key
2153
+ );
2154
+ },
2155
+ RadioGroup: (node, processEvent2) => {
2156
+ const { key, ...propsWithoutKey } = node.props || {};
2157
+ const name = getSafeProp(
2158
+ propsWithoutKey,
2159
+ "name",
2160
+ isString,
2161
+ "radioGroupName"
2162
+ );
2163
+ const label = getSafeProp(propsWithoutKey, "label", isString, "");
2164
+ const value = getSafeBinding(node.bindings, "value", isString, "");
2165
+ const options = getSafeBinding(
2166
+ node.bindings,
2167
+ "options",
2168
+ isArrayOf(isSelectOptionObject),
2169
+ []
2170
+ );
2171
+ const disabled = getSafeProp(propsWithoutKey, "disabled", isBoolean, false);
2172
+ const className = getSafeProp(propsWithoutKey, "className", isString, "");
2173
+ const handleValueChange = (selectedValue) => {
2174
+ const handler = createEventHandler(
2175
+ node,
2176
+ "onValueChange",
2177
+ "CHANGE",
2178
+ processEvent2
2179
+ );
2180
+ if (handler)
2181
+ handler({ value: selectedValue });
2182
+ };
2183
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2184
+ "div",
2185
+ {
2186
+ className: cn("grid gap-1.5", className),
2187
+ children: [
2188
+ label && /* @__PURE__ */ jsxRuntime.jsx(Label2, { className: "mb-1", children: label }),
2189
+ /* @__PURE__ */ jsxRuntime.jsx(
2190
+ RadioGroup,
2191
+ {
2192
+ name,
2193
+ value,
2194
+ onValueChange: handleValueChange,
2195
+ disabled,
2196
+ className: "flex flex-col space-y-1",
2197
+ children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center space-x-2", children: [
2198
+ /* @__PURE__ */ jsxRuntime.jsx(
2199
+ RadioGroupItem,
2200
+ {
2201
+ value: option.value,
2202
+ id: `${name}-${option.value}`
2203
+ }
2204
+ ),
2205
+ /* @__PURE__ */ jsxRuntime.jsx(
2206
+ Label2,
2207
+ {
2208
+ htmlFor: `${name}-${option.value}`,
2209
+ className: "cursor-pointer",
2210
+ children: option.label
2211
+ }
2212
+ )
2213
+ ] }, option.value))
2214
+ }
2215
+ )
2216
+ ]
2217
+ },
2218
+ key
2219
+ );
2220
+ },
2221
+ Tabs: (node, processEvent2) => {
2222
+ const { key, ...propsWithoutKey } = node.props || {};
2223
+ const rawTabs = getSafeBinding(
2224
+ node.bindings,
2225
+ "tabs",
2226
+ isArrayOf(isTabObject),
2227
+ []
2228
+ );
2229
+ const defaultValue = getSafeProp(
2230
+ propsWithoutKey,
2231
+ "defaultValue",
2232
+ isString,
2233
+ rawTabs[0]?.value || ""
2234
+ );
2235
+ const className = getSafeProp(propsWithoutKey, "className", isString, "");
2236
+ const handleValueChange = (value) => {
2237
+ const handler = createEventHandler(
2238
+ node,
2239
+ "onValueChange",
2240
+ "CHANGE",
2241
+ processEvent2
2242
+ );
2243
+ if (handler)
2244
+ handler({ value });
2245
+ };
2246
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2247
+ Tabs,
2248
+ {
2249
+ defaultValue,
2250
+ onValueChange: handleValueChange,
2251
+ className: cn("autoui-tabs w-full", className),
2252
+ "data-id": node.id,
2253
+ children: [
2254
+ /* @__PURE__ */ jsxRuntime.jsx(TabsList, { children: rawTabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(TabsTrigger, { value: tab.value, children: tab.label }, tab.value)) }),
2255
+ rawTabs.map((tab) => /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: tab.value, children: tab.content ? renderNode(tab.content, processEvent2) : null }, tab.value))
2256
+ ]
2257
+ },
2258
+ key
2259
+ );
2260
+ },
2261
+ Dialog: (node, processEvent2) => {
2262
+ const isOpen = getSafeBinding(
2263
+ node.bindings,
2264
+ "open",
2265
+ isBoolean,
2266
+ getSafeProp(node.props, "open", isBoolean, false)
2267
+ );
2268
+ const {
2269
+ title,
2270
+ description,
2271
+ className,
2272
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2273
+ style: _styleProp,
2274
+ key,
2275
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2276
+ open: _openProp,
2277
+ ...restProps
2278
+ } = node.props || {};
2279
+ const children = node.children?.map(
2280
+ (child) => React__default.default.cloneElement(renderNode(child, processEvent2), { key: child.id })
2281
+ );
2282
+ const handleOpenChange = (open) => {
2283
+ if (!open) {
2284
+ const handler = createEventHandler(
2285
+ node,
2286
+ "onClose",
2287
+ // Assumed event name in UISpec
2288
+ "CLICK",
2289
+ // Use CLICK as the event type for closing dialogs
2290
+ processEvent2
2291
+ );
2292
+ if (handler) {
2293
+ handler({});
2294
+ }
2295
+ }
2296
+ };
2297
+ console.log(
2298
+ `[Adapter Debug] Rendering Dialog: id=${node.id}, props=`,
2299
+ node.props,
2300
+ `isOpen=${isOpen}`
2301
+ );
2302
+ return /* @__PURE__ */ jsxRuntime.jsx(
2303
+ Dialog,
2304
+ {
2305
+ open: isOpen,
2306
+ onOpenChange: handleOpenChange,
2307
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
2308
+ DialogContent,
2309
+ {
2310
+ className: cn("autoui-dialog-content", className),
2311
+ ...restProps,
2312
+ "data-id": node.id,
2313
+ children: [
2314
+ (title || description) && /* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { children: [
2315
+ title && /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: title }),
2316
+ description && /* @__PURE__ */ jsxRuntime.jsx(DialogDescription, { children: description })
2317
+ ] }),
2318
+ children
2319
+ ]
2320
+ }
2321
+ )
2322
+ },
2323
+ key
2324
+ );
2325
+ },
2326
+ Heading: (node) => {
2327
+ const { className, style: styleProp, key, ...restProps } = node.props || {};
2328
+ const text = getSafeProp(node.props, "text", isString, "Heading");
2329
+ let level = getSafeProp(
2330
+ node.props,
2331
+ "level",
2332
+ (v) => typeof v === "number" && v >= 1 && v <= 6,
2333
+ 2
2334
+ );
2335
+ if (typeof level !== "number" || level < 1 || level > 6) {
2336
+ level = 2;
2337
+ }
2338
+ const Tag = `h${level}`;
2339
+ const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
2340
+ const headingStyles = {
2341
+ 1: "scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl",
2342
+ 2: "scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0",
2343
+ 3: "scroll-m-20 text-2xl font-semibold tracking-tight",
2344
+ 4: "scroll-m-20 text-xl font-semibold tracking-tight"
2345
+ // Add styles for h5, h6 if needed, using text-lg, text-base etc.
2346
+ }[level] || "text-lg font-semibold";
2347
+ return /* @__PURE__ */ jsxRuntime.jsx(
2348
+ Tag,
2349
+ {
2350
+ className: cn(headingStyles, className),
2351
+ style,
2352
+ ...restProps,
2353
+ children: text
2354
+ },
2355
+ key
2356
+ );
2357
+ },
2358
+ Text: (node) => {
2359
+ const { className, style: styleProp, key, ...restProps } = node.props || {};
2360
+ const text = getSafeProp(node.props, "text", isString, "Some text");
2361
+ const style = typeof styleProp === "string" ? parseStyleString(styleProp) : styleProp;
2362
+ return /* @__PURE__ */ jsxRuntime.jsx(
2363
+ "p",
2364
+ {
2365
+ className: cn("leading-7", className),
2366
+ style,
2367
+ ...restProps,
2368
+ children: text
2369
+ },
2370
+ key
2371
+ );
1337
2372
  }
1338
2373
  };
1339
2374
  function renderNode(node, processEvent2) {
@@ -1430,99 +2465,261 @@ function getValueByPath(context, path) {
1430
2465
  return current;
1431
2466
  }
1432
2467
  function setValueByPath(context, path, value) {
2468
+ if (!path) {
2469
+ return context;
2470
+ }
1433
2471
  const result = { ...context };
1434
2472
  const parts = path.split(".");
1435
- if (parts.length === 0)
1436
- return result;
1437
2473
  let current = result;
1438
2474
  for (let i = 0; i < parts.length - 1; i++) {
1439
2475
  const part = parts[i];
1440
2476
  if (typeof current !== "object" || current === null) {
1441
- console.error("setValueByPath: Cannot create path in a non-object.");
2477
+ console.warn(
2478
+ `setValueByPath: Cannot traverse path "${path}". Parent segment "${parts[i - 1] || "(root)"}" is not an object.`
2479
+ );
1442
2480
  return context;
1443
2481
  }
1444
2482
  const currentAsObject = current;
1445
- if (!(part in currentAsObject) || typeof currentAsObject[part] !== "object" || currentAsObject[part] === null) {
2483
+ const nextPartValue = currentAsObject[part];
2484
+ if (nextPartValue === void 0 || nextPartValue === null) {
1446
2485
  currentAsObject[part] = {};
2486
+ } else if (typeof nextPartValue !== "object") {
2487
+ console.warn(
2488
+ `setValueByPath: Cannot create nested path "${path}". Segment "${part}" is not an object.`
2489
+ );
2490
+ return context;
2491
+ } else {
2492
+ currentAsObject[part] = { ...nextPartValue };
1447
2493
  }
1448
2494
  current = currentAsObject[part];
1449
2495
  }
1450
2496
  const lastPart = parts[parts.length - 1];
1451
2497
  if (typeof current === "object" && current !== null) {
1452
2498
  current[lastPart] = value;
1453
- } else if (parts.length === 1 && typeof result === "object" && result !== null) {
1454
- result[lastPart] = value;
1455
2499
  } else {
1456
2500
  console.warn(
1457
- `setValueByPath: Could not set value for path "${path}". Final segment location is not an object.`
2501
+ `setValueByPath: Could not set value for path "${path}". Final segment parent is not an object.`
1458
2502
  );
1459
2503
  return context;
1460
2504
  }
1461
2505
  return result;
1462
2506
  }
1463
- function processBinding(binding, context) {
2507
+ function processBinding(binding, context, itemData) {
1464
2508
  if (typeof binding === "string") {
1465
- return getValueByPath(context, binding);
2509
+ const exactMatchArr = binding.match(/^{{(.*)}}$/);
2510
+ const pathInsideExact = exactMatchArr ? exactMatchArr[1].trim() : null;
2511
+ if (pathInsideExact !== null && !pathInsideExact.includes("{{") && !pathInsideExact.includes("}}")) {
2512
+ const pathToResolve = pathInsideExact;
2513
+ let resolvedValue = void 0;
2514
+ console.log(
2515
+ `[processBinding Debug] Processing EXACT template: "${binding}", Path: "${pathToResolve}", Has itemData: ${!!itemData}`
2516
+ );
2517
+ if (itemData) {
2518
+ try {
2519
+ console.log(
2520
+ `[processBinding Debug] itemData content (EXACT):`,
2521
+ JSON.parse(JSON.stringify(itemData))
2522
+ );
2523
+ } catch {
2524
+ }
2525
+ }
2526
+ if ((pathToResolve.startsWith("item.") || pathToResolve.startsWith("row.")) && itemData) {
2527
+ if (pathToResolve.startsWith("item.")) {
2528
+ resolvedValue = getValueByPath(itemData, pathToResolve.substring(5));
2529
+ } else {
2530
+ resolvedValue = getValueByPath(itemData, pathToResolve.substring(4));
2531
+ }
2532
+ } else if (itemData && pathToResolve in itemData) {
2533
+ resolvedValue = getValueByPath(itemData, pathToResolve);
2534
+ }
2535
+ if (resolvedValue === void 0) {
2536
+ resolvedValue = getValueByPath(context, pathToResolve);
2537
+ }
2538
+ return resolvedValue;
2539
+ } else if (binding.includes("{{") && binding.includes("}}")) {
2540
+ console.log(
2541
+ `[processBinding Debug] Processing EMBEDDED templates: "${binding}", Has itemData: ${!!itemData}`
2542
+ );
2543
+ if (itemData) {
2544
+ try {
2545
+ console.log(
2546
+ `[processBinding Debug] itemData content (EMBEDDED):`,
2547
+ JSON.parse(JSON.stringify(itemData))
2548
+ );
2549
+ } catch {
2550
+ }
2551
+ }
2552
+ const resolvedString = binding.replaceAll(
2553
+ /{{(.*?)}}/g,
2554
+ // Non-greedy match inside braces
2555
+ (match, path) => {
2556
+ const trimmedPath = path.trim();
2557
+ let resolvedValue = void 0;
2558
+ if ((trimmedPath.startsWith("item.") || trimmedPath.startsWith("row.")) && itemData) {
2559
+ if (trimmedPath.startsWith("item.")) {
2560
+ resolvedValue = getValueByPath(
2561
+ itemData,
2562
+ trimmedPath.substring(5)
2563
+ );
2564
+ } else {
2565
+ resolvedValue = getValueByPath(
2566
+ itemData,
2567
+ trimmedPath.substring(4)
2568
+ );
2569
+ }
2570
+ } else if (itemData && trimmedPath in itemData) {
2571
+ resolvedValue = getValueByPath(itemData, trimmedPath);
2572
+ }
2573
+ if (resolvedValue === void 0) {
2574
+ resolvedValue = getValueByPath(context, trimmedPath);
2575
+ }
2576
+ return resolvedValue === null || resolvedValue === void 0 ? "" : String(resolvedValue);
2577
+ }
2578
+ );
2579
+ return resolvedString;
2580
+ } else {
2581
+ const pathToResolve = binding;
2582
+ let resolvedValue = void 0;
2583
+ console.log(
2584
+ `[processBinding Debug] Processing PATH string: "${pathToResolve}", Has itemData: ${!!itemData}`
2585
+ );
2586
+ if (itemData && !pathToResolve.includes(".") && pathToResolve in itemData) {
2587
+ resolvedValue = getValueByPath(itemData, pathToResolve);
2588
+ }
2589
+ if (resolvedValue === void 0) {
2590
+ resolvedValue = getValueByPath(context, pathToResolve);
2591
+ }
2592
+ return resolvedValue;
2593
+ }
1466
2594
  }
1467
2595
  if (Array.isArray(binding)) {
1468
- return binding.map((item) => processBinding(item, context));
2596
+ return binding.map((item) => processBinding(item, context, itemData));
1469
2597
  }
1470
2598
  if (binding !== null && typeof binding === "object") {
1471
2599
  const result = {};
1472
2600
  for (const [key, value] of Object.entries(binding)) {
1473
- result[key] = processBinding(value, context);
2601
+ result[key] = processBinding(value, context, itemData);
1474
2602
  }
1475
2603
  return result;
1476
2604
  }
1477
2605
  return binding;
1478
2606
  }
1479
- async function resolveBindings(node, context) {
2607
+ async function resolveBindings(node, context, itemData) {
2608
+ const effectiveContext = itemData ? { ...context, item: itemData } : context;
1480
2609
  const currentTime = Date.now();
1481
- const cacheKey = createCacheKey(node.id, context);
2610
+ const cacheKey = createCacheKey(node.id, effectiveContext);
1482
2611
  const cachedNode = bindingsCache.get(cacheKey);
1483
2612
  const cachedTimestamp = nodeCacheTimestamps.get(cacheKey);
1484
2613
  if (cachedNode && cachedTimestamp && currentTime - cachedTimestamp < CACHE_TTL2) {
1485
2614
  return cachedNode;
1486
2615
  }
1487
- await systemEvents.emit(
1488
- createSystemEvent("BINDING_RESOLUTION_START" /* BINDING_RESOLUTION_START */, {
1489
- layout: node
1490
- })
1491
- );
2616
+ if (!itemData) {
2617
+ await systemEvents.emit(
2618
+ createSystemEvent("BINDING_RESOLUTION_START" /* BINDING_RESOLUTION_START */, {
2619
+ layout: node
2620
+ })
2621
+ );
2622
+ }
1492
2623
  const result = {
1493
2624
  ...node,
1494
- props: node.props ? { ...node.props } : null,
1495
- events: node.events ? { ...node.events } : null
2625
+ props: node.props ? JSON.parse(JSON.stringify(node.props)) : null,
2626
+ events: node.events ? JSON.parse(JSON.stringify(node.events)) : null,
2627
+ bindings: node.bindings ? JSON.parse(JSON.stringify(node.bindings)) : null,
2628
+ children: null
2629
+ // Initialize children to null
1496
2630
  };
2631
+ const resolvedBindings = {};
1497
2632
  if (node.bindings) {
1498
- for (const [key, binding] of Object.entries(node.bindings)) {
1499
- const value = processBinding(binding, context);
1500
- if (value !== void 0 && typeof value === "string") {
1501
- if (!result.props) {
2633
+ for (const [key, bindingValue] of Object.entries(node.bindings)) {
2634
+ const resolvedValue = processBinding(bindingValue, context, itemData);
2635
+ resolvedBindings[key] = resolvedValue;
2636
+ if (resolvedValue !== void 0) {
2637
+ if (!result.props)
1502
2638
  result.props = {};
1503
- }
1504
- result.props[key] = value;
2639
+ result.props[key] = resolvedValue;
1505
2640
  }
1506
2641
  }
1507
2642
  }
1508
- if (node.children) {
2643
+ result.bindings = null;
2644
+ if (node.events) {
2645
+ result.events = processBinding(
2646
+ node.events,
2647
+ context,
2648
+ itemData
2649
+ );
2650
+ } else {
2651
+ result.events = null;
2652
+ }
2653
+ const dataBindingValue = resolvedBindings["data"] ?? resolvedBindings["items"];
2654
+ if ((node.node_type === "ListView" || node.node_type === "Table") && Array.isArray(dataBindingValue) && node.children && node.children.length > 0) {
2655
+ const templateChild = node.children[0];
2656
+ const mappedChildren = await Promise.all(
2657
+ dataBindingValue.map(async (currentItemData, index) => {
2658
+ try {
2659
+ if (typeof currentItemData !== "object" || currentItemData === null) {
2660
+ console.warn(
2661
+ `List item at index ${index} for node ${node.id} is not an object:`,
2662
+ currentItemData
2663
+ );
2664
+ return null;
2665
+ }
2666
+ const currentItemAsRecord = currentItemData;
2667
+ const itemId = currentItemAsRecord.id;
2668
+ const instanceId = `${templateChild.id}-${itemId || index}`;
2669
+ const childNodeInstance = JSON.parse(
2670
+ JSON.stringify(templateChild)
2671
+ );
2672
+ childNodeInstance.id = instanceId;
2673
+ const resolvedChild = await resolveBindings(
2674
+ childNodeInstance,
2675
+ context,
2676
+ currentItemAsRecord
2677
+ );
2678
+ if (!resolvedChild.props)
2679
+ resolvedChild.props = {};
2680
+ resolvedChild.props.key = itemId || `${node.id}-item-${index}`;
2681
+ return resolvedChild;
2682
+ } catch (error) {
2683
+ console.error(
2684
+ `[resolveBindings Error] Error processing item at index ${index} for node ${node.id}:`,
2685
+ error,
2686
+ "Item Data:",
2687
+ currentItemData
2688
+ );
2689
+ return null;
2690
+ }
2691
+ })
2692
+ );
2693
+ result.children = mappedChildren.filter(
2694
+ (child) => child !== null
2695
+ );
2696
+ } else if (node.children && node.children.length > 0) {
1509
2697
  result.children = await Promise.all(
1510
- node.children.map((child) => resolveBindings(child, context))
2698
+ node.children.map((child) => resolveBindings(child, context, itemData))
2699
+ );
2700
+ } else {
2701
+ result.children = [];
2702
+ }
2703
+ if (!itemData) {
2704
+ await systemEvents.emit(
2705
+ createSystemEvent("BINDING_RESOLUTION_COMPLETE" /* BINDING_RESOLUTION_COMPLETE */, {
2706
+ originalLayout: node,
2707
+ resolvedLayout: result
2708
+ })
1511
2709
  );
1512
2710
  }
1513
- await systemEvents.emit(
1514
- createSystemEvent("BINDING_RESOLUTION_COMPLETE" /* BINDING_RESOLUTION_COMPLETE */, {
1515
- originalLayout: node,
1516
- resolvedLayout: result
1517
- })
1518
- );
1519
2711
  bindingsCache.set(cacheKey, result);
1520
2712
  nodeCacheTimestamps.set(cacheKey, currentTime);
1521
2713
  if (bindingsCache.size > MAX_CACHE_SIZE2) {
1522
- const entries = [...nodeCacheTimestamps.entries()];
1523
- if (entries.length > 0) {
1524
- entries.sort((a, b) => a[1] - b[1]);
1525
- const oldestKey = entries[0][0];
2714
+ let oldestKey = null;
2715
+ let oldestTimestamp = currentTime;
2716
+ for (const [key, timestamp] of nodeCacheTimestamps.entries()) {
2717
+ if (timestamp < oldestTimestamp) {
2718
+ oldestTimestamp = timestamp;
2719
+ oldestKey = key;
2720
+ }
2721
+ }
2722
+ if (oldestKey) {
1526
2723
  bindingsCache.delete(oldestKey);
1527
2724
  nodeCacheTimestamps.delete(oldestKey);
1528
2725
  }
@@ -1655,6 +2852,31 @@ function getMissingComponentsMessage() {
1655
2852
  return `Missing required shadcn components. Please run:
1656
2853
  > npm run setup-shadcn`;
1657
2854
  }
2855
+ function correctListBindingsRecursive(node, dataContext) {
2856
+ const correctedNode = JSON.parse(JSON.stringify(node));
2857
+ if ((correctedNode.node_type === "ListView" || correctedNode.node_type === "Table") && correctedNode.bindings?.data) {
2858
+ const bindingPath = correctedNode.bindings.data;
2859
+ if (typeof bindingPath === "string") {
2860
+ const pathSegments = bindingPath.split(".");
2861
+ const mainKey = pathSegments[0];
2862
+ if (pathSegments.length === 1) {
2863
+ const potentialDataContextEntry = dataContext[mainKey];
2864
+ if (potentialDataContextEntry && typeof potentialDataContextEntry === "object" && potentialDataContextEntry !== null && "data" in potentialDataContextEntry && Array.isArray(potentialDataContextEntry.data)) {
2865
+ correctedNode.bindings.data = `${mainKey}.data`;
2866
+ console.log(
2867
+ `[AutoUI Debug] Corrected list binding for node '${correctedNode.id}': from '${mainKey}' to '${mainKey}.data'`
2868
+ );
2869
+ }
2870
+ }
2871
+ }
2872
+ }
2873
+ if (correctedNode.children) {
2874
+ correctedNode.children = correctedNode.children.map(
2875
+ (child) => correctListBindingsRecursive(child, dataContext)
2876
+ );
2877
+ }
2878
+ return correctedNode;
2879
+ }
1658
2880
  var AutoUI = ({
1659
2881
  schema,
1660
2882
  goal,
@@ -1664,11 +2886,12 @@ var AutoUI = ({
1664
2886
  eventHooks,
1665
2887
  systemEventHooks,
1666
2888
  debugMode = false,
1667
- mockMode = true,
2889
+ mockMode = false,
1668
2890
  planningConfig,
1669
2891
  integration = {},
1670
2892
  scope = {},
1671
- enablePartialUpdates = false
2893
+ enablePartialUpdates = false,
2894
+ openaiApiKey
1672
2895
  }) => {
1673
2896
  const [schemaAdapterInstance] = React.useState(null);
1674
2897
  const [dataContext, setDataContext] = React.useState({});
@@ -1740,7 +2963,8 @@ var AutoUI = ({
1740
2963
  planningConfig,
1741
2964
  router: void 0,
1742
2965
  dataContext,
1743
- enablePartialUpdates
2966
+ enablePartialUpdates,
2967
+ openaiApiKey
1744
2968
  });
1745
2969
  const eventManagerRef = React.useRef(new EventManager());
1746
2970
  React.useEffect(() => {
@@ -1840,13 +3064,29 @@ var AutoUI = ({
1840
3064
  null
1841
3065
  );
1842
3066
  const resolveLayoutBindings = React.useCallback(async () => {
1843
- if (state.layout) {
1844
- try {
1845
- const resolved = await resolveBindings(state.layout, dataContext);
1846
- setResolvedLayout(resolved);
1847
- } catch (err) {
1848
- console.error("Error resolving bindings:", err);
1849
- }
3067
+ if (state.layout && dataContext) {
3068
+ console.log(
3069
+ "[AutoUI Debug] DataContext before resolving bindings:",
3070
+ JSON.stringify(dataContext, null, 2)
3071
+ );
3072
+ console.log(
3073
+ "[AutoUI Debug] Raw layout before resolving (from planner):",
3074
+ JSON.stringify(state.layout, null, 2)
3075
+ );
3076
+ const correctedLayout = correctListBindingsRecursive(
3077
+ state.layout,
3078
+ dataContext
3079
+ );
3080
+ console.log(
3081
+ "[AutoUI Debug] Layout after binding correction (before resolving):",
3082
+ JSON.stringify(correctedLayout, null, 2)
3083
+ );
3084
+ const resolved = await resolveBindings(correctedLayout, dataContext);
3085
+ setResolvedLayout(resolved);
3086
+ console.log(
3087
+ "[AutoUI Debug] Resolved layout after bindings:",
3088
+ JSON.stringify(resolved, null, 2)
3089
+ );
1850
3090
  } else {
1851
3091
  setResolvedLayout(void 0);
1852
3092
  }
@@ -2053,12 +3293,23 @@ var generateUIComponent = async (prompt) => {
2053
3293
  return `<div>Generated UI Component for: ${prompt}</div>`;
2054
3294
  };
2055
3295
  function usePlanner(options) {
2056
- const { goal, schema, userContext, router: customRouter } = options;
2057
- const [layout, setLayout] = React.useState(void 0);
3296
+ const {
3297
+ schema,
3298
+ goal,
3299
+ openaiApiKey,
3300
+ userContext,
3301
+ initialLayout,
3302
+ mockMode: optionsMockMode
3303
+ } = options;
3304
+ const [layout, setLayout] = React.useState(
3305
+ initialLayout || void 0
3306
+ );
2058
3307
  const [loading, setLoading] = React.useState(false);
2059
3308
  const [error, setError] = React.useState(null);
2060
- const router = customRouter || createDefaultRouter();
3309
+ const router = options.router || createDefaultRouter();
2061
3310
  const dataContext = {};
3311
+ const initialFetchAttempted = React.useRef(false);
3312
+ const mockMode = optionsMockMode || !openaiApiKey;
2062
3313
  const generateInitialLayout = React.useCallback(async () => {
2063
3314
  setLoading(true);
2064
3315
  setError(null);
@@ -2069,14 +3320,26 @@ function usePlanner(options) {
2069
3320
  userContext: userContext || null,
2070
3321
  history: null
2071
3322
  };
2072
- const generatedLayout = await callPlannerLLM(plannerInput2);
3323
+ let generatedLayout;
3324
+ if (mockMode) {
3325
+ console.warn(
3326
+ "Using mock planner in usePlanner hook (mockMode enabled or API key missing)."
3327
+ );
3328
+ generatedLayout = mockPlanner(plannerInput2);
3329
+ } else {
3330
+ generatedLayout = await callPlannerLLM(
3331
+ plannerInput2,
3332
+ openaiApiKey,
3333
+ void 0
3334
+ );
3335
+ }
2073
3336
  setLayout(generatedLayout);
2074
3337
  } catch (err) {
2075
3338
  setError(err instanceof Error ? err : new Error(String(err)));
2076
3339
  } finally {
2077
3340
  setLoading(false);
2078
3341
  }
2079
- }, [schema, goal, userContext]);
3342
+ }, [schema, goal, userContext, openaiApiKey, mockMode]);
2080
3343
  const handleEvent = React.useCallback(
2081
3344
  async (event) => {
2082
3345
  if (!layout) {
@@ -2093,7 +3356,8 @@ function usePlanner(options) {
2093
3356
  layout,
2094
3357
  dataContext,
2095
3358
  goal,
2096
- userContext
3359
+ userContext,
3360
+ openaiApiKey
2097
3361
  );
2098
3362
  setLayout(updatedLayout);
2099
3363
  } catch (err) {
@@ -2102,8 +3366,14 @@ function usePlanner(options) {
2102
3366
  setLoading(false);
2103
3367
  }
2104
3368
  },
2105
- [layout, router, schema, dataContext, goal, userContext]
3369
+ [layout, router, schema, dataContext, goal, userContext, openaiApiKey]
2106
3370
  );
3371
+ React.useEffect(() => {
3372
+ if (options.initialLayout === void 0 && layout === void 0 && !initialFetchAttempted.current) {
3373
+ initialFetchAttempted.current = true;
3374
+ generateInitialLayout();
3375
+ }
3376
+ }, [options.initialLayout, layout, generateInitialLayout]);
2107
3377
  return {
2108
3378
  layout,
2109
3379
  loading,