@leanmcp/ui 0.1.0

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 ADDED
@@ -0,0 +1,789 @@
1
+ 'use strict';
2
+
3
+ require('reflect-metadata');
4
+ var React7 = require('react');
5
+ var extApps = require('@modelcontextprotocol/ext-apps');
6
+ var reactSlot = require('@radix-ui/react-slot');
7
+ var clsx = require('clsx');
8
+ var reactTable = require('@tanstack/react-table');
9
+ var chart_js = require('chart.js');
10
+ var reactChartjs2 = require('react-chartjs-2');
11
+ var prismReactRenderer = require('prism-react-renderer');
12
+
13
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
+
15
+ var React7__default = /*#__PURE__*/_interopDefault(React7);
16
+
17
+ var __defProp = Object.defineProperty;
18
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
19
+ var UI_APP_COMPONENT_KEY = "ui:app:component";
20
+ var UI_APP_URI_KEY = "ui:app:uri";
21
+ var UI_APP_OPTIONS_KEY = "ui:app:options";
22
+ function UIApp(options) {
23
+ return (target, propertyKey, descriptor) => {
24
+ const methodName = String(propertyKey);
25
+ const className = target.constructor.name.toLowerCase().replace("service", "");
26
+ const uri = options.uri ?? `ui://${className}/${methodName}`;
27
+ Reflect.defineMetadata(UI_APP_COMPONENT_KEY, options.component, descriptor.value);
28
+ Reflect.defineMetadata(UI_APP_URI_KEY, uri, descriptor.value);
29
+ Reflect.defineMetadata(UI_APP_OPTIONS_KEY, options, descriptor.value);
30
+ const existingMeta = Reflect.getMetadata("tool:meta", descriptor.value) || {};
31
+ Reflect.defineMetadata("tool:meta", {
32
+ ...existingMeta,
33
+ "ui/resourceUri": uri
34
+ }, descriptor.value);
35
+ return descriptor;
36
+ };
37
+ }
38
+ __name(UIApp, "UIApp");
39
+ function getUIAppMetadata(target) {
40
+ const component = Reflect.getMetadata(UI_APP_COMPONENT_KEY, target);
41
+ if (!component) return void 0;
42
+ return {
43
+ component,
44
+ uri: Reflect.getMetadata(UI_APP_URI_KEY, target),
45
+ ...Reflect.getMetadata(UI_APP_OPTIONS_KEY, target)
46
+ };
47
+ }
48
+ __name(getUIAppMetadata, "getUIAppMetadata");
49
+ function getUIAppUri(target) {
50
+ return Reflect.getMetadata(UI_APP_URI_KEY, target);
51
+ }
52
+ __name(getUIAppUri, "getUIAppUri");
53
+ var McpAppContext = /* @__PURE__ */ React7.createContext(null);
54
+ function AppProvider({ appInfo, capabilities = {}, options = {
55
+ autoResize: true
56
+ }, children }) {
57
+ const [app, setApp] = React7.useState(null);
58
+ const [isConnected, setIsConnected] = React7.useState(false);
59
+ const [error, setError] = React7.useState(null);
60
+ const [hostContext, setHostContext] = React7.useState({});
61
+ const [toolInput, setToolInput] = React7.useState(null);
62
+ const [toolInputPartial, setToolInputPartial] = React7.useState(null);
63
+ const [toolResult, setToolResult] = React7.useState(null);
64
+ React7.useEffect(() => {
65
+ let mounted = true;
66
+ let appInstance = null;
67
+ async function connect() {
68
+ try {
69
+ const transport = new extApps.PostMessageTransport(window.parent);
70
+ appInstance = new extApps.App(appInfo, capabilities, options);
71
+ appInstance.ontoolinput = (params) => {
72
+ if (mounted) {
73
+ setToolInput(params.arguments);
74
+ }
75
+ };
76
+ appInstance.ontoolinputpartial = (params) => {
77
+ if (mounted) {
78
+ setToolInputPartial(params.arguments);
79
+ }
80
+ };
81
+ appInstance.ontoolresult = (params) => {
82
+ if (mounted) {
83
+ setToolResult(params);
84
+ }
85
+ };
86
+ appInstance.onhostcontextchanged = (params) => {
87
+ if (mounted) {
88
+ setHostContext((prev) => ({
89
+ ...prev,
90
+ ...params
91
+ }));
92
+ }
93
+ };
94
+ await appInstance.connect(transport);
95
+ if (mounted) {
96
+ setApp(appInstance);
97
+ setIsConnected(true);
98
+ setError(null);
99
+ }
100
+ } catch (err) {
101
+ if (mounted) {
102
+ setError(err instanceof Error ? err : new Error(String(err)));
103
+ setIsConnected(false);
104
+ }
105
+ }
106
+ }
107
+ __name(connect, "connect");
108
+ connect();
109
+ return () => {
110
+ mounted = false;
111
+ if (appInstance) {
112
+ appInstance.close();
113
+ }
114
+ };
115
+ }, [
116
+ appInfo.name,
117
+ appInfo.version
118
+ ]);
119
+ const callTool = React7.useCallback(async (name, args = {}) => {
120
+ if (!app) {
121
+ throw new Error("Not connected to host");
122
+ }
123
+ const result = await app.callServerTool({
124
+ name,
125
+ arguments: args
126
+ });
127
+ setToolResult(result);
128
+ return result;
129
+ }, [
130
+ app
131
+ ]);
132
+ const sendMessage = React7.useCallback(async (text) => {
133
+ if (!app) {
134
+ console.warn("[AppProvider] Not connected - cannot send message");
135
+ return;
136
+ }
137
+ await app.sendMessage({
138
+ role: "user",
139
+ content: [
140
+ {
141
+ type: "text",
142
+ text
143
+ }
144
+ ]
145
+ });
146
+ }, [
147
+ app
148
+ ]);
149
+ const sendLog = React7.useCallback(async (level, data) => {
150
+ if (!app) {
151
+ console.log(`[MCP App] ${level}:`, data);
152
+ return;
153
+ }
154
+ await app.sendLog({
155
+ level,
156
+ data
157
+ });
158
+ }, [
159
+ app
160
+ ]);
161
+ const openLink = React7.useCallback(async (url) => {
162
+ if (!app) {
163
+ window.open(url, "_blank", "noopener,noreferrer");
164
+ return;
165
+ }
166
+ await app.sendOpenLink({
167
+ url
168
+ });
169
+ }, [
170
+ app
171
+ ]);
172
+ const value = {
173
+ app,
174
+ isConnected,
175
+ error,
176
+ hostContext,
177
+ toolInput,
178
+ toolInputPartial,
179
+ toolResult,
180
+ callTool,
181
+ sendMessage,
182
+ sendLog,
183
+ openLink
184
+ };
185
+ const theme = hostContext.theme ?? "light";
186
+ return /* @__PURE__ */ React7__default.default.createElement(McpAppContext.Provider, {
187
+ value
188
+ }, /* @__PURE__ */ React7__default.default.createElement("div", {
189
+ className: "lui-root",
190
+ "data-theme": theme
191
+ }, children));
192
+ }
193
+ __name(AppProvider, "AppProvider");
194
+ var ssrDefaultContext = {
195
+ app: null,
196
+ isConnected: false,
197
+ error: null,
198
+ hostContext: {},
199
+ toolInput: null,
200
+ toolInputPartial: null,
201
+ toolResult: null,
202
+ callTool: /* @__PURE__ */ __name(async () => {
203
+ throw new Error("callTool not available during SSR");
204
+ }, "callTool"),
205
+ sendMessage: /* @__PURE__ */ __name(async () => {
206
+ console.warn("sendMessage not available during SSR");
207
+ }, "sendMessage"),
208
+ sendLog: /* @__PURE__ */ __name(async () => {
209
+ console.warn("sendLog not available during SSR");
210
+ }, "sendLog"),
211
+ openLink: /* @__PURE__ */ __name(async () => {
212
+ console.warn("openLink not available during SSR");
213
+ }, "openLink")
214
+ };
215
+ function useMcpApp() {
216
+ const context = React7.useContext(McpAppContext);
217
+ if (!context) {
218
+ return ssrDefaultContext;
219
+ }
220
+ return context;
221
+ }
222
+ __name(useMcpApp, "useMcpApp");
223
+ function useTool(toolName) {
224
+ const { callTool } = useMcpApp();
225
+ const [loading, setLoading] = React7.useState(false);
226
+ const [result, setResult] = React7.useState(null);
227
+ const [error, setError] = React7.useState(null);
228
+ const call = React7.useCallback(async (args = {}) => {
229
+ setLoading(true);
230
+ setError(null);
231
+ try {
232
+ const response = await callTool(toolName, args);
233
+ const data = response?.structuredContent ?? response;
234
+ setResult(data);
235
+ return data;
236
+ } catch (err) {
237
+ const error2 = err instanceof Error ? err : new Error(String(err));
238
+ setError(error2);
239
+ throw error2;
240
+ } finally {
241
+ setLoading(false);
242
+ }
243
+ }, [
244
+ callTool,
245
+ toolName
246
+ ]);
247
+ const reset = React7.useCallback(() => {
248
+ setResult(null);
249
+ setError(null);
250
+ }, []);
251
+ return {
252
+ call,
253
+ loading,
254
+ result,
255
+ error,
256
+ reset
257
+ };
258
+ }
259
+ __name(useTool, "useTool");
260
+
261
+ // src/mcp/useToolResult.ts
262
+ function useToolResult() {
263
+ const { toolResult } = useMcpApp();
264
+ let result = null;
265
+ let textContent = null;
266
+ if (toolResult) {
267
+ if ("structuredContent" in toolResult && toolResult.structuredContent) {
268
+ result = toolResult.structuredContent;
269
+ }
270
+ if (!result && toolResult.content) {
271
+ const textItem = toolResult.content.find((c) => c.type === "text");
272
+ if (textItem) {
273
+ textContent = textItem.text;
274
+ try {
275
+ result = JSON.parse(textItem.text);
276
+ } catch {
277
+ }
278
+ }
279
+ }
280
+ }
281
+ return {
282
+ result,
283
+ rawResult: toolResult,
284
+ hasResult: toolResult !== null,
285
+ textContent
286
+ };
287
+ }
288
+ __name(useToolResult, "useToolResult");
289
+
290
+ // src/mcp/useToolInput.ts
291
+ function useToolInput() {
292
+ const { toolInput } = useMcpApp();
293
+ return {
294
+ input: toolInput,
295
+ hasInput: toolInput !== null
296
+ };
297
+ }
298
+ __name(useToolInput, "useToolInput");
299
+
300
+ // src/mcp/useToolInputPartial.ts
301
+ function useToolInputPartial() {
302
+ const { toolInputPartial } = useMcpApp();
303
+ return {
304
+ partialArgs: toolInputPartial,
305
+ isStreaming: toolInputPartial !== null
306
+ };
307
+ }
308
+ __name(useToolInputPartial, "useToolInputPartial");
309
+
310
+ // src/mcp/useHostContext.ts
311
+ function useHostContext() {
312
+ const { hostContext } = useMcpApp();
313
+ return {
314
+ theme: hostContext.theme ?? "light",
315
+ displayMode: hostContext.displayMode ?? "inline",
316
+ viewport: hostContext.viewport ?? null,
317
+ locale: hostContext.locale ?? null,
318
+ timeZone: hostContext.timeZone ?? null,
319
+ platform: hostContext.platform ?? null,
320
+ rawContext: hostContext
321
+ };
322
+ }
323
+ __name(useHostContext, "useHostContext");
324
+ var Button = /* @__PURE__ */ React7.forwardRef(({ className, variant = "primary", size = "md", loading = false, disabled, asChild = false, leftIcon, rightIcon, children, ...props }, ref) => {
325
+ const Comp = asChild ? reactSlot.Slot : "button";
326
+ return /* @__PURE__ */ React7__default.default.createElement(Comp, {
327
+ ref,
328
+ className: clsx.clsx("lui-button", `lui-button--${variant}`, `lui-button--${size}`, loading && "lui-button--loading", className),
329
+ disabled: disabled || loading,
330
+ ...props
331
+ }, loading && /* @__PURE__ */ React7__default.default.createElement("span", {
332
+ className: "lui-button__spinner",
333
+ "aria-hidden": "true"
334
+ }, /* @__PURE__ */ React7__default.default.createElement("svg", {
335
+ viewBox: "0 0 24 24",
336
+ fill: "none",
337
+ className: "lui-spinner-icon"
338
+ }, /* @__PURE__ */ React7__default.default.createElement("circle", {
339
+ cx: "12",
340
+ cy: "12",
341
+ r: "10",
342
+ stroke: "currentColor",
343
+ strokeWidth: "3",
344
+ strokeLinecap: "round",
345
+ strokeDasharray: "32",
346
+ strokeDashoffset: "12"
347
+ }))), leftIcon && !loading && /* @__PURE__ */ React7__default.default.createElement("span", {
348
+ className: "lui-button__icon"
349
+ }, leftIcon), /* @__PURE__ */ React7__default.default.createElement("span", {
350
+ className: "lui-button__content"
351
+ }, children), rightIcon && /* @__PURE__ */ React7__default.default.createElement("span", {
352
+ className: "lui-button__icon"
353
+ }, rightIcon));
354
+ });
355
+ Button.displayName = "Button";
356
+
357
+ // src/mcp/ActionButton.tsx
358
+ function ActionButton({ toolName, toolArgs = {}, onToolSuccess, onToolError, showResult = false, renderResult, children, ...buttonProps }) {
359
+ const { call, loading, result, error } = useTool(toolName);
360
+ const [hasResult, setHasResult] = React7.useState(false);
361
+ const handleClick = /* @__PURE__ */ __name(async () => {
362
+ try {
363
+ const res = await call(toolArgs);
364
+ setHasResult(true);
365
+ onToolSuccess?.(res);
366
+ } catch (err) {
367
+ onToolError?.(err instanceof Error ? err : new Error(String(err)));
368
+ }
369
+ }, "handleClick");
370
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
371
+ className: "lui-action-button-wrapper"
372
+ }, /* @__PURE__ */ React7__default.default.createElement(Button, {
373
+ ...buttonProps,
374
+ loading,
375
+ onClick: handleClick
376
+ }, children), showResult && hasResult && result !== null && /* @__PURE__ */ React7__default.default.createElement("div", {
377
+ className: "lui-action-button-result"
378
+ }, renderResult ? renderResult(result) : /* @__PURE__ */ React7__default.default.createElement("pre", null, JSON.stringify(result, null, 2))), error && /* @__PURE__ */ React7__default.default.createElement("div", {
379
+ className: "lui-action-button-error"
380
+ }, error.message));
381
+ }
382
+ __name(ActionButton, "ActionButton");
383
+ var Input = /* @__PURE__ */ React7.forwardRef(({ className, label, helperText, error, size = "md", leftElement, rightElement, fullWidth = false, id, ...props }, ref) => {
384
+ const inputId = id || `input-${Math.random().toString(36).substr(2, 9)}`;
385
+ const hasError = Boolean(error);
386
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
387
+ className: clsx.clsx("lui-input-wrapper", fullWidth && "lui-input-wrapper--full-width", className)
388
+ }, label && /* @__PURE__ */ React7__default.default.createElement("label", {
389
+ htmlFor: inputId,
390
+ className: "lui-input-label"
391
+ }, label), /* @__PURE__ */ React7__default.default.createElement("div", {
392
+ className: clsx.clsx("lui-input-container", `lui-input-container--${size}`, hasError && "lui-input-container--error", leftElement && "lui-input-container--has-left", rightElement && "lui-input-container--has-right")
393
+ }, leftElement && /* @__PURE__ */ React7__default.default.createElement("span", {
394
+ className: "lui-input-element lui-input-element--left"
395
+ }, leftElement), /* @__PURE__ */ React7__default.default.createElement("input", {
396
+ ref,
397
+ id: inputId,
398
+ className: "lui-input",
399
+ "aria-invalid": hasError,
400
+ "aria-describedby": error ? `${inputId}-error` : helperText ? `${inputId}-helper` : void 0,
401
+ ...props
402
+ }), rightElement && /* @__PURE__ */ React7__default.default.createElement("span", {
403
+ className: "lui-input-element lui-input-element--right"
404
+ }, rightElement)), (error || helperText) && /* @__PURE__ */ React7__default.default.createElement("p", {
405
+ id: error ? `${inputId}-error` : `${inputId}-helper`,
406
+ className: clsx.clsx("lui-input-message", error && "lui-input-message--error")
407
+ }, error || helperText));
408
+ });
409
+ Input.displayName = "Input";
410
+ function ToolForm({ toolName, fields, submitText = "Submit", onSuccess, onError, showResult = false, className }) {
411
+ const { call, loading, result, error } = useTool(toolName);
412
+ const [formData, setFormData] = React7.useState(() => {
413
+ const initial = {};
414
+ fields.forEach((field) => {
415
+ if (field.defaultValue !== void 0) {
416
+ initial[field.name] = field.defaultValue;
417
+ }
418
+ });
419
+ return initial;
420
+ });
421
+ const handleSubmit = /* @__PURE__ */ __name(async (e) => {
422
+ e.preventDefault();
423
+ const args = {};
424
+ fields.forEach((field) => {
425
+ const value = formData[field.name];
426
+ if (field.type === "number" && value !== void 0) {
427
+ args[field.name] = Number(value);
428
+ } else {
429
+ args[field.name] = value;
430
+ }
431
+ });
432
+ try {
433
+ const res = await call(args);
434
+ onSuccess?.(res);
435
+ } catch (err) {
436
+ onError?.(err instanceof Error ? err : new Error(String(err)));
437
+ }
438
+ }, "handleSubmit");
439
+ const handleChange = /* @__PURE__ */ __name((name, value) => {
440
+ setFormData((prev) => ({
441
+ ...prev,
442
+ [name]: value
443
+ }));
444
+ }, "handleChange");
445
+ return /* @__PURE__ */ React7__default.default.createElement("form", {
446
+ className: clsx.clsx("lui-tool-form", className),
447
+ onSubmit: handleSubmit
448
+ }, /* @__PURE__ */ React7__default.default.createElement("div", {
449
+ className: "lui-tool-form-fields"
450
+ }, fields.map((field) => /* @__PURE__ */ React7__default.default.createElement("div", {
451
+ key: field.name,
452
+ className: "lui-tool-form-field"
453
+ }, field.type === "textarea" ? /* @__PURE__ */ React7__default.default.createElement("div", {
454
+ className: "lui-input-wrapper lui-input-wrapper--full-width"
455
+ }, /* @__PURE__ */ React7__default.default.createElement("label", {
456
+ className: "lui-input-label"
457
+ }, field.label), /* @__PURE__ */ React7__default.default.createElement("textarea", {
458
+ className: "lui-tool-form-textarea",
459
+ name: field.name,
460
+ placeholder: field.placeholder,
461
+ required: field.required,
462
+ value: formData[field.name] ?? "",
463
+ onChange: /* @__PURE__ */ __name((e) => handleChange(field.name, e.target.value), "onChange")
464
+ }), field.helperText && /* @__PURE__ */ React7__default.default.createElement("p", {
465
+ className: "lui-input-message"
466
+ }, field.helperText)) : /* @__PURE__ */ React7__default.default.createElement(Input, {
467
+ fullWidth: true,
468
+ label: field.label,
469
+ type: field.type ?? "text",
470
+ name: field.name,
471
+ placeholder: field.placeholder,
472
+ required: field.required,
473
+ helperText: field.helperText,
474
+ value: formData[field.name] ?? "",
475
+ onChange: /* @__PURE__ */ __name((e) => handleChange(field.name, e.target.value), "onChange")
476
+ })))), /* @__PURE__ */ React7__default.default.createElement("div", {
477
+ className: "lui-tool-form-actions"
478
+ }, /* @__PURE__ */ React7__default.default.createElement(Button, {
479
+ type: "submit",
480
+ loading
481
+ }, submitText)), error && /* @__PURE__ */ React7__default.default.createElement("div", {
482
+ className: "lui-tool-form-error"
483
+ }, error.message), showResult && result !== null && /* @__PURE__ */ React7__default.default.createElement("div", {
484
+ className: "lui-tool-form-result"
485
+ }, /* @__PURE__ */ React7__default.default.createElement("pre", null, JSON.stringify(result, null, 2))));
486
+ }
487
+ __name(ToolForm, "ToolForm");
488
+ var Card = /* @__PURE__ */ React7.forwardRef(({ className, variant = "default", padding = "md", interactive = false, children, ...props }, ref) => {
489
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
490
+ ref,
491
+ className: clsx.clsx("lui-card", `lui-card--${variant}`, `lui-card--padding-${padding}`, interactive && "lui-card--interactive", className),
492
+ ...props
493
+ }, children);
494
+ });
495
+ Card.displayName = "Card";
496
+ var CardHeader = /* @__PURE__ */ React7.forwardRef(({ className, title, description, action, children, ...props }, ref) => {
497
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
498
+ ref,
499
+ className: clsx.clsx("lui-card-header", className),
500
+ ...props
501
+ }, (title || description) && /* @__PURE__ */ React7__default.default.createElement("div", {
502
+ className: "lui-card-header__text"
503
+ }, title && /* @__PURE__ */ React7__default.default.createElement("h3", {
504
+ className: "lui-card-header__title"
505
+ }, title), description && /* @__PURE__ */ React7__default.default.createElement("p", {
506
+ className: "lui-card-header__description"
507
+ }, description)), action && /* @__PURE__ */ React7__default.default.createElement("div", {
508
+ className: "lui-card-header__action"
509
+ }, action), children);
510
+ });
511
+ CardHeader.displayName = "CardHeader";
512
+ var CardContent = /* @__PURE__ */ React7.forwardRef(({ className, children, ...props }, ref) => {
513
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
514
+ ref,
515
+ className: clsx.clsx("lui-card-content", className),
516
+ ...props
517
+ }, children);
518
+ });
519
+ CardContent.displayName = "CardContent";
520
+ var CardFooter = /* @__PURE__ */ React7.forwardRef(({ className, children, ...props }, ref) => {
521
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
522
+ ref,
523
+ className: clsx.clsx("lui-card-footer", className),
524
+ ...props
525
+ }, children);
526
+ });
527
+ CardFooter.displayName = "CardFooter";
528
+ function DataGrid({ data, columns, searchable = false, searchPlaceholder = "Search...", onRowClick, loading = false, emptyMessage = "No data", className }) {
529
+ const [sorting, setSorting] = React7.useState([]);
530
+ const [globalFilter, setGlobalFilter] = React7.useState("");
531
+ const tableColumns = React7.useMemo(() => columns.map((col) => ({
532
+ id: String(col.key),
533
+ accessorKey: col.key,
534
+ header: col.header,
535
+ cell: col.cell ? ({ getValue, row }) => col.cell(getValue(), row.original) : ({ getValue }) => String(getValue() ?? ""),
536
+ enableSorting: col.sortable ?? true,
537
+ size: typeof col.width === "number" ? col.width : void 0
538
+ })), [
539
+ columns
540
+ ]);
541
+ const table = reactTable.useReactTable({
542
+ data,
543
+ columns: tableColumns,
544
+ state: {
545
+ sorting,
546
+ globalFilter
547
+ },
548
+ onSortingChange: setSorting,
549
+ onGlobalFilterChange: setGlobalFilter,
550
+ getCoreRowModel: reactTable.getCoreRowModel(),
551
+ getSortedRowModel: reactTable.getSortedRowModel(),
552
+ getFilteredRowModel: reactTable.getFilteredRowModel()
553
+ });
554
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
555
+ className: clsx.clsx("lui-datagrid", className)
556
+ }, searchable && /* @__PURE__ */ React7__default.default.createElement("div", {
557
+ className: "lui-datagrid-search"
558
+ }, /* @__PURE__ */ React7__default.default.createElement("input", {
559
+ type: "text",
560
+ value: globalFilter,
561
+ onChange: /* @__PURE__ */ __name((e) => setGlobalFilter(e.target.value), "onChange"),
562
+ placeholder: searchPlaceholder,
563
+ className: "lui-datagrid-search-input"
564
+ })), /* @__PURE__ */ React7__default.default.createElement("div", {
565
+ className: "lui-datagrid-container"
566
+ }, /* @__PURE__ */ React7__default.default.createElement("table", {
567
+ className: "lui-datagrid-table"
568
+ }, /* @__PURE__ */ React7__default.default.createElement("thead", null, table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ React7__default.default.createElement("tr", {
569
+ key: headerGroup.id
570
+ }, headerGroup.headers.map((header) => /* @__PURE__ */ React7__default.default.createElement("th", {
571
+ key: header.id,
572
+ className: clsx.clsx("lui-datagrid-th", header.column.getCanSort() && "lui-datagrid-th--sortable"),
573
+ onClick: header.column.getToggleSortingHandler(),
574
+ style: {
575
+ width: header.column.getSize()
576
+ }
577
+ }, /* @__PURE__ */ React7__default.default.createElement("div", {
578
+ className: "lui-datagrid-th-content"
579
+ }, reactTable.flexRender(header.column.columnDef.header, header.getContext()), header.column.getIsSorted() && /* @__PURE__ */ React7__default.default.createElement("span", {
580
+ className: "lui-datagrid-sort-icon"
581
+ }, header.column.getIsSorted() === "asc" ? "\u2191" : "\u2193"))))))), /* @__PURE__ */ React7__default.default.createElement("tbody", null, loading ? /* @__PURE__ */ React7__default.default.createElement("tr", null, /* @__PURE__ */ React7__default.default.createElement("td", {
582
+ colSpan: columns.length,
583
+ className: "lui-datagrid-loading"
584
+ }, "Loading...")) : table.getRowModel().rows.length === 0 ? /* @__PURE__ */ React7__default.default.createElement("tr", null, /* @__PURE__ */ React7__default.default.createElement("td", {
585
+ colSpan: columns.length,
586
+ className: "lui-datagrid-empty"
587
+ }, emptyMessage)) : table.getRowModel().rows.map((row) => /* @__PURE__ */ React7__default.default.createElement("tr", {
588
+ key: row.id,
589
+ className: clsx.clsx("lui-datagrid-row", onRowClick && "lui-datagrid-row--clickable"),
590
+ onClick: /* @__PURE__ */ __name(() => onRowClick?.(row.original), "onClick")
591
+ }, row.getVisibleCells().map((cell) => /* @__PURE__ */ React7__default.default.createElement("td", {
592
+ key: cell.id,
593
+ className: "lui-datagrid-td"
594
+ }, reactTable.flexRender(cell.column.columnDef.cell, cell.getContext())))))))));
595
+ }
596
+ __name(DataGrid, "DataGrid");
597
+ chart_js.Chart.register(chart_js.CategoryScale, chart_js.LinearScale, chart_js.PointElement, chart_js.LineElement, chart_js.BarElement, chart_js.ArcElement, chart_js.Title, chart_js.Tooltip, chart_js.Legend);
598
+ function Chart({ type, data, options, height = 300, width = "100%", className }) {
599
+ const defaultOptions = {
600
+ responsive: true,
601
+ maintainAspectRatio: false,
602
+ plugins: {
603
+ legend: {
604
+ display: true,
605
+ position: "top",
606
+ labels: {
607
+ usePointStyle: true,
608
+ padding: 16
609
+ }
610
+ },
611
+ tooltip: {
612
+ mode: "index",
613
+ intersect: false,
614
+ backgroundColor: "rgba(15, 23, 42, 0.9)",
615
+ titleColor: "#f1f5f9",
616
+ bodyColor: "#cbd5e1",
617
+ borderColor: "#334155",
618
+ borderWidth: 1,
619
+ cornerRadius: 8,
620
+ padding: 12
621
+ }
622
+ },
623
+ scales: type !== "pie" && type !== "doughnut" ? {
624
+ x: {
625
+ grid: {
626
+ color: "rgba(226, 232, 240, 0.5)"
627
+ },
628
+ ticks: {
629
+ color: "#64748b"
630
+ }
631
+ },
632
+ y: {
633
+ grid: {
634
+ color: "rgba(226, 232, 240, 0.5)"
635
+ },
636
+ ticks: {
637
+ color: "#64748b"
638
+ }
639
+ }
640
+ } : void 0
641
+ };
642
+ const mergedOptions = {
643
+ ...defaultOptions,
644
+ ...options,
645
+ plugins: {
646
+ ...defaultOptions.plugins,
647
+ ...options?.plugins
648
+ }
649
+ };
650
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
651
+ className: clsx.clsx("lui-chart", className),
652
+ style: {
653
+ height,
654
+ width
655
+ }
656
+ }, /* @__PURE__ */ React7__default.default.createElement(reactChartjs2.Chart, {
657
+ type,
658
+ data,
659
+ options: mergedOptions
660
+ }));
661
+ }
662
+ __name(Chart, "Chart");
663
+ function AppShell({ header, sidebar, footer, sidebarPosition = "left", sidebarWidth = 240, autoResize = true, padding = "md", className, children, ...props }) {
664
+ const containerRef = React7.useRef(null);
665
+ React7.useEffect(() => {
666
+ if (!autoResize || !containerRef.current) return;
667
+ const resizeObserver = new ResizeObserver((entries) => {
668
+ for (const entry of entries) {
669
+ const { height } = entry.contentRect;
670
+ window.parent.postMessage({
671
+ type: "resize",
672
+ height: Math.ceil(height)
673
+ }, "*");
674
+ }
675
+ });
676
+ resizeObserver.observe(containerRef.current);
677
+ return () => {
678
+ resizeObserver.disconnect();
679
+ };
680
+ }, [
681
+ autoResize
682
+ ]);
683
+ const sidebarStyle = {
684
+ width: typeof sidebarWidth === "number" ? `${sidebarWidth}px` : sidebarWidth,
685
+ flexShrink: 0
686
+ };
687
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
688
+ ref: containerRef,
689
+ className: clsx.clsx("lui-app-shell", `lui-app-shell--padding-${padding}`, className),
690
+ ...props
691
+ }, header && /* @__PURE__ */ React7__default.default.createElement("header", {
692
+ className: "lui-app-shell-header"
693
+ }, header), /* @__PURE__ */ React7__default.default.createElement("div", {
694
+ className: "lui-app-shell-body"
695
+ }, sidebar && sidebarPosition === "left" && /* @__PURE__ */ React7__default.default.createElement("aside", {
696
+ className: "lui-app-shell-sidebar",
697
+ style: sidebarStyle
698
+ }, sidebar), /* @__PURE__ */ React7__default.default.createElement("main", {
699
+ className: "lui-app-shell-main"
700
+ }, children), sidebar && sidebarPosition === "right" && /* @__PURE__ */ React7__default.default.createElement("aside", {
701
+ className: "lui-app-shell-sidebar",
702
+ style: sidebarStyle
703
+ }, sidebar)), footer && /* @__PURE__ */ React7__default.default.createElement("footer", {
704
+ className: "lui-app-shell-footer"
705
+ }, footer));
706
+ }
707
+ __name(AppShell, "AppShell");
708
+ function CodeBlock({ code, language = "text", showLineNumbers = false, copyable = true, className }) {
709
+ const [copied, setCopied] = React7__default.default.useState(false);
710
+ const handleCopy = /* @__PURE__ */ __name(async () => {
711
+ await navigator.clipboard.writeText(code);
712
+ setCopied(true);
713
+ setTimeout(() => setCopied(false), 2e3);
714
+ }, "handleCopy");
715
+ return /* @__PURE__ */ React7__default.default.createElement("div", {
716
+ className: clsx.clsx("lui-code-block", className)
717
+ }, copyable && /* @__PURE__ */ React7__default.default.createElement("button", {
718
+ type: "button",
719
+ className: "lui-code-block-copy",
720
+ onClick: handleCopy,
721
+ "aria-label": copied ? "Copied!" : "Copy code"
722
+ }, copied ? /* @__PURE__ */ React7__default.default.createElement("svg", {
723
+ viewBox: "0 0 24 24",
724
+ fill: "none",
725
+ stroke: "currentColor",
726
+ strokeWidth: "2"
727
+ }, /* @__PURE__ */ React7__default.default.createElement("polyline", {
728
+ points: "20,6 9,17 4,12"
729
+ })) : /* @__PURE__ */ React7__default.default.createElement("svg", {
730
+ viewBox: "0 0 24 24",
731
+ fill: "none",
732
+ stroke: "currentColor",
733
+ strokeWidth: "2"
734
+ }, /* @__PURE__ */ React7__default.default.createElement("rect", {
735
+ x: "9",
736
+ y: "9",
737
+ width: "13",
738
+ height: "13",
739
+ rx: "2",
740
+ ry: "2"
741
+ }), /* @__PURE__ */ React7__default.default.createElement("path", {
742
+ d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"
743
+ }))), /* @__PURE__ */ React7__default.default.createElement(prismReactRenderer.Highlight, {
744
+ theme: prismReactRenderer.themes.nightOwl,
745
+ code: code.trim(),
746
+ language
747
+ }, ({ className: hlClassName, style, tokens, getLineProps, getTokenProps }) => /* @__PURE__ */ React7__default.default.createElement("pre", {
748
+ className: clsx.clsx("lui-code-block-pre", hlClassName),
749
+ style
750
+ }, tokens.map((line, i) => /* @__PURE__ */ React7__default.default.createElement("div", {
751
+ key: i,
752
+ ...getLineProps({
753
+ line
754
+ })
755
+ }, showLineNumbers && /* @__PURE__ */ React7__default.default.createElement("span", {
756
+ className: "lui-code-block-line-number"
757
+ }, i + 1), line.map((token, key) => /* @__PURE__ */ React7__default.default.createElement("span", {
758
+ key,
759
+ ...getTokenProps({
760
+ token
761
+ })
762
+ })))))));
763
+ }
764
+ __name(CodeBlock, "CodeBlock");
765
+
766
+ exports.ActionButton = ActionButton;
767
+ exports.AppProvider = AppProvider;
768
+ exports.AppShell = AppShell;
769
+ exports.Button = Button;
770
+ exports.Card = Card;
771
+ exports.CardContent = CardContent;
772
+ exports.CardFooter = CardFooter;
773
+ exports.CardHeader = CardHeader;
774
+ exports.Chart = Chart;
775
+ exports.CodeBlock = CodeBlock;
776
+ exports.DataGrid = DataGrid;
777
+ exports.Input = Input;
778
+ exports.ToolForm = ToolForm;
779
+ exports.UIApp = UIApp;
780
+ exports.getUIAppMetadata = getUIAppMetadata;
781
+ exports.getUIAppUri = getUIAppUri;
782
+ exports.useHostContext = useHostContext;
783
+ exports.useMcpApp = useMcpApp;
784
+ exports.useTool = useTool;
785
+ exports.useToolInput = useToolInput;
786
+ exports.useToolInputPartial = useToolInputPartial;
787
+ exports.useToolResult = useToolResult;
788
+ //# sourceMappingURL=index.js.map
789
+ //# sourceMappingURL=index.js.map