@fogui/react 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/README.md ADDED
@@ -0,0 +1,138 @@
1
+ # @fogui/react
2
+
3
+ > Transform LLM output into beautiful, interactive UI components - like magic from the fog ✨
4
+
5
+ [![npm version](https://badge.fury.io/js/@fogui%2Freact.svg)](https://www.npmjs.com/package/@fogui/react)
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @fogui/react
11
+ # or
12
+ yarn add @fogui/react
13
+ # or
14
+ pnpm add @fogui/react
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```tsx
20
+ import { FogUIProvider, useFogUI, FogUIRenderer } from '@fogui/react';
21
+
22
+ // 1. Wrap your app with FogUIProvider
23
+ function App() {
24
+ return (
25
+ <FogUIProvider apiKey="fog_xxxx">
26
+ <Chat />
27
+ </FogUIProvider>
28
+ );
29
+ }
30
+
31
+ // 2. Use the hook to transform LLM output
32
+ function Chat() {
33
+ const { transform, isLoading } = useFogUI();
34
+ const [ui, setUI] = useState(null);
35
+
36
+ const handleSubmit = async (userMessage: string) => {
37
+ // Call YOUR LLM (with your own API key)
38
+ const llmResponse = await openai.chat.completions.create({
39
+ model: 'gpt-4',
40
+ messages: [{ role: 'user', content: userMessage }]
41
+ });
42
+
43
+ // Transform with FogUI - UI materializes from the fog ✨
44
+ const result = await transform(llmResponse.choices[0].message.content);
45
+
46
+ if (result.success) {
47
+ setUI(result.result);
48
+ }
49
+ };
50
+
51
+ return (
52
+ <div>
53
+ {isLoading && <p>Materializing UI...</p>}
54
+ {ui && <FogUIRenderer response={ui} />}
55
+ </div>
56
+ );
57
+ }
58
+ ```
59
+
60
+ ## API Reference
61
+
62
+ ### `<FogUIProvider>`
63
+
64
+ Wrap your app with this provider to configure FogUI.
65
+
66
+ ```tsx
67
+ <FogUIProvider apiKey="fog_xxxx">
68
+ <App />
69
+ </FogUIProvider>
70
+ ```
71
+
72
+ | Prop | Type | Description |
73
+ |------|------|-------------|
74
+ | `apiKey` | `string` | Your FogUI API key (get it from [fogui.dev/dashboard](https://fogui.dev/dashboard)) |
75
+
76
+ ### `useFogUI()`
77
+
78
+ Hook for transforming LLM output.
79
+
80
+ ```tsx
81
+ const { transform, transformStream, isLoading, error, clearError } = useFogUI();
82
+ ```
83
+
84
+ | Method | Type | Description |
85
+ |--------|------|-------------|
86
+ | `transform` | `(content: string, options?) => Promise<TransformResult>` | Transform text to UI |
87
+ | `transformStream` | `(content: string, options?) => AsyncGenerator` | Streaming transform |
88
+ | `isLoading` | `boolean` | Loading state |
89
+ | `error` | `string \| null` | Error message |
90
+ | `clearError` | `() => void` | Clear error state |
91
+
92
+ ### `<FogUIRenderer>`
93
+
94
+ Render the transformed UI response.
95
+
96
+ ```tsx
97
+ <FogUIRenderer
98
+ response={transformResult.result}
99
+ componentRegistry={customComponents} // Optional
100
+ />
101
+ ```
102
+
103
+ ## Custom Components
104
+
105
+ Override the default components with your own design system:
106
+
107
+ ```tsx
108
+ import { FogUIRenderer, defaultComponentRegistry } from '@fogui/react';
109
+ import { Card as MyCard, Table as MyTable } from 'your-ui-library';
110
+
111
+ const customRegistry = {
112
+ ...defaultComponentRegistry,
113
+ card: MyCard,
114
+ table: MyTable,
115
+ };
116
+
117
+ <FogUIRenderer response={response} componentRegistry={customRegistry} />
118
+ ```
119
+
120
+ ## Get Your API Key
121
+
122
+ 1. Visit [fogui.dev/dashboard](https://fogui.dev/dashboard)
123
+ 2. Sign up or log in
124
+ 3. Create a new API key
125
+ 4. Use it in your app
126
+
127
+ ## Why FogUI?
128
+
129
+ > UI that materializes from nothing - like magic from the fog ✨
130
+
131
+ - **Your LLM, Your Keys** - We never see your API keys
132
+ - **Any LLM Provider** - Works with OpenAI, Claude, Gemini, etc.
133
+ - **Custom Design Systems** - Plug in your own components
134
+ - **TypeScript First** - Full type safety
135
+
136
+ ## License
137
+
138
+ MIT
@@ -0,0 +1,3 @@
1
+ export { D as DynamicComponent, f as FogUIRenderer, g as defaultComponentRegistry } from '../index-BcLda68r.mjs';
2
+ import 'react/jsx-runtime';
3
+ import 'react';
@@ -0,0 +1,3 @@
1
+ export { D as DynamicComponent, f as FogUIRenderer, g as defaultComponentRegistry } from '../index-BcLda68r.js';
2
+ import 'react/jsx-runtime';
3
+ import 'react';
@@ -0,0 +1,96 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
+
8
+ var React__default = /*#__PURE__*/_interopDefault(React);
9
+
10
+ // src/components/FogUIRenderer.tsx
11
+ function DefaultCard({ title, description, data }) {
12
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { border: "1px solid #e5e7eb", borderRadius: "8px", padding: "16px", marginBottom: "12px" }, children: [
13
+ title && /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { margin: "0 0 8px", fontSize: "18px", fontWeight: 600 }, children: title }),
14
+ description && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "0 0 12px", color: "#6b7280" }, children: description }),
15
+ data && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: "14px" }, children: Object.entries(data).map(([key, value]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", padding: "4px 0" }, children: [
16
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#6b7280" }, children: key }),
17
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500 }, children: String(value) })
18
+ ] }, key)) })
19
+ ] });
20
+ }
21
+ function DefaultList({ title, items }) {
22
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "12px" }, children: [
23
+ title && /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { margin: "0 0 12px", fontSize: "18px", fontWeight: 600 }, children: title }),
24
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: 0, paddingLeft: "20px" }, children: items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx("li", { style: { marginBottom: "8px" }, children: typeof item === "object" ? JSON.stringify(item) : String(item) }, i)) })
25
+ ] });
26
+ }
27
+ function DefaultTable({ columns, rows }) {
28
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { overflowX: "auto", marginBottom: "12px" }, children: /* @__PURE__ */ jsxRuntime.jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: "14px" }, children: [
29
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("th", { style: { textAlign: "left", padding: "12px 8px", borderBottom: "2px solid #e5e7eb", fontWeight: 600 }, children: col }, col)) }) }),
30
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsxRuntime.jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsxRuntime.jsx("td", { style: { padding: "12px 8px", borderBottom: "1px solid #e5e7eb" }, children: String(row[col] ?? "") }, col)) }, i)) })
31
+ ] }) });
32
+ }
33
+ function DefaultCallout({ title, message, variant = "info" }) {
34
+ const colors = {
35
+ info: { bg: "#eff6ff", border: "#3b82f6", text: "#1e40af" },
36
+ warning: { bg: "#fffbeb", border: "#f59e0b", text: "#92400e" },
37
+ tip: { bg: "#f0fdf4", border: "#22c55e", text: "#166534" }
38
+ };
39
+ const c = colors[variant];
40
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { backgroundColor: c.bg, borderLeft: `4px solid ${c.border}`, padding: "12px 16px", marginBottom: "12px", borderRadius: "0 8px 8px 0" }, children: [
41
+ title && /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: c.text, display: "block", marginBottom: "4px" }, children: title }),
42
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: c.text }, children: message })
43
+ ] });
44
+ }
45
+ var defaultComponentRegistry = {
46
+ card: DefaultCard,
47
+ list: DefaultList,
48
+ table: DefaultTable,
49
+ callout: DefaultCallout
50
+ };
51
+ function DynamicComponent({ block, registry = defaultComponentRegistry }) {
52
+ const { componentType, props } = block;
53
+ const Component = registry[componentType];
54
+ if (!Component) {
55
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "12px", backgroundColor: "#fef3c7", border: "1px solid #fcd34d", borderRadius: "8px", fontSize: "14px" }, children: [
56
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
57
+ "Unknown component: ",
58
+ componentType
59
+ ] }),
60
+ /* @__PURE__ */ jsxRuntime.jsx("pre", { style: { margin: "8px 0 0", fontSize: "12px", overflow: "auto" }, children: JSON.stringify(props, null, 2) })
61
+ ] });
62
+ }
63
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...props });
64
+ }
65
+ function FogUIRenderer({ response, componentRegistry, className }) {
66
+ const registry = componentRegistry || defaultComponentRegistry;
67
+ if (!response || !response.content) {
68
+ return null;
69
+ }
70
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: response.content.map((block, index) => /* @__PURE__ */ jsxRuntime.jsx(
71
+ ContentBlockRenderer,
72
+ {
73
+ block,
74
+ registry
75
+ },
76
+ index
77
+ )) });
78
+ }
79
+ function ContentBlockRenderer({ block, registry }) {
80
+ if (block.type === "text") {
81
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: "12px", lineHeight: 1.6 }, children: block.value.split("\n").map((line, i) => /* @__PURE__ */ jsxRuntime.jsxs(React__default.default.Fragment, { children: [
82
+ line,
83
+ i < block.value.split("\n").length - 1 && /* @__PURE__ */ jsxRuntime.jsx("br", {})
84
+ ] }, i)) });
85
+ }
86
+ if (block.type === "component") {
87
+ return /* @__PURE__ */ jsxRuntime.jsx(DynamicComponent, { block, registry });
88
+ }
89
+ return null;
90
+ }
91
+
92
+ exports.DynamicComponent = DynamicComponent;
93
+ exports.FogUIRenderer = FogUIRenderer;
94
+ exports.defaultComponentRegistry = defaultComponentRegistry;
95
+ //# sourceMappingURL=index.js.map
96
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/ComponentRegistry.tsx","../../src/components/FogUIRenderer.tsx"],"names":["jsxs","jsx","React"],"mappings":"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","file":"index.js","sourcesContent":["import React from 'react';\nimport type { ComponentBlock } from '../types';\n\n/**\n * Default component implementations.\n * These provide basic rendering - users should customize for their design system.\n */\n\n// Card Component\nfunction DefaultCard({ title, description, data }: { title?: string; description?: string; data?: Record<string, unknown> }) {\n return (\n <div style={{ border: '1px solid #e5e7eb', borderRadius: '8px', padding: '16px', marginBottom: '12px' }}>\n {title && <h3 style={{ margin: '0 0 8px', fontSize: '18px', fontWeight: 600 }}>{title}</h3>}\n {description && <p style={{ margin: '0 0 12px', color: '#6b7280' }}>{description}</p>}\n {data && (\n <div style={{ fontSize: '14px' }}>\n {Object.entries(data).map(([key, value]) => (\n <div key={key} style={{ display: 'flex', justifyContent: 'space-between', padding: '4px 0' }}>\n <span style={{ color: '#6b7280' }}>{key}</span>\n <span style={{ fontWeight: 500 }}>{String(value)}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// List Component\nfunction DefaultList({ title, items }: { title?: string; items: unknown[] }) {\n return (\n <div style={{ marginBottom: '12px' }}>\n {title && <h3 style={{ margin: '0 0 12px', fontSize: '18px', fontWeight: 600 }}>{title}</h3>}\n <ul style={{ margin: 0, paddingLeft: '20px' }}>\n {items.map((item, i) => (\n <li key={i} style={{ marginBottom: '8px' }}>\n {typeof item === 'object' ? JSON.stringify(item) : String(item)}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\n// Table Component\nfunction DefaultTable({ columns, rows }: { columns: string[]; rows: Record<string, unknown>[] }) {\n return (\n <div style={{ overflowX: 'auto', marginBottom: '12px' }}>\n <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: '14px' }}>\n <thead>\n <tr>\n {columns.map((col) => (\n <th key={col} style={{ textAlign: 'left', padding: '12px 8px', borderBottom: '2px solid #e5e7eb', fontWeight: 600 }}>\n {col}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, i) => (\n <tr key={i}>\n {columns.map((col) => (\n <td key={col} style={{ padding: '12px 8px', borderBottom: '1px solid #e5e7eb' }}>\n {String(row[col] ?? '')}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\n// Callout Component\nfunction DefaultCallout({ title, message, variant = 'info' }: { title?: string; message: string; variant?: 'info' | 'warning' | 'tip' }) {\n const colors = {\n info: { bg: '#eff6ff', border: '#3b82f6', text: '#1e40af' },\n warning: { bg: '#fffbeb', border: '#f59e0b', text: '#92400e' },\n tip: { bg: '#f0fdf4', border: '#22c55e', text: '#166534' },\n };\n const c = colors[variant];\n return (\n <div style={{ backgroundColor: c.bg, borderLeft: `4px solid ${c.border}`, padding: '12px 16px', marginBottom: '12px', borderRadius: '0 8px 8px 0' }}>\n {title && <strong style={{ color: c.text, display: 'block', marginBottom: '4px' }}>{title}</strong>}\n <span style={{ color: c.text }}>{message}</span>\n </div>\n );\n}\n\n/**\n * Default component registry mapping componentType to React components.\n * Users can override this with their own components.\n */\nexport const defaultComponentRegistry: Record<string, React.ComponentType<any>> = {\n card: DefaultCard,\n list: DefaultList,\n table: DefaultTable,\n callout: DefaultCallout,\n};\n\ninterface DynamicComponentProps {\n block: ComponentBlock;\n registry?: Record<string, React.ComponentType<any>>;\n}\n\n/**\n * DynamicComponent - Renders a component based on componentType.\n */\nexport function DynamicComponent({ block, registry = defaultComponentRegistry }: DynamicComponentProps) {\n const { componentType, props } = block;\n const Component = registry[componentType];\n\n if (!Component) {\n return (\n <div style={{ padding: '12px', backgroundColor: '#fef3c7', border: '1px solid #fcd34d', borderRadius: '8px', fontSize: '14px' }}>\n <strong>Unknown component: {componentType}</strong>\n <pre style={{ margin: '8px 0 0', fontSize: '12px', overflow: 'auto' }}>\n {JSON.stringify(props, null, 2)}\n </pre>\n </div>\n );\n }\n\n return <Component {...props} />;\n}\n","import React from 'react';\nimport type { FogUIResponse, ContentBlock } from '../types';\nimport { DynamicComponent, defaultComponentRegistry } from './ComponentRegistry';\n\ninterface FogUIRendererProps {\n /**\n * The FogUIResponse to render\n */\n response: FogUIResponse;\n /**\n * Custom component registry to override default components\n */\n componentRegistry?: Record<string, React.ComponentType<any>>;\n /**\n * Custom className for the container\n */\n className?: string;\n}\n\n/**\n * FogUIRenderer - Renders a FogUIResponse as React components.\n * \n * @example\n * ```tsx\n * import { FogUIRenderer } from '@fogui/react';\n * \n * function Chat({ response }) {\n * return <FogUIRenderer response={response} />;\n * }\n * ```\n */\nexport function FogUIRenderer({ response, componentRegistry, className }: FogUIRendererProps) {\n const registry = componentRegistry || defaultComponentRegistry;\n\n if (!response || !response.content) {\n return null;\n }\n\n return (\n <div className={className}>\n {response.content.map((block, index) => (\n <ContentBlockRenderer \n key={index} \n block={block} \n registry={registry}\n />\n ))}\n </div>\n );\n}\n\ninterface ContentBlockRendererProps {\n block: ContentBlock;\n registry: Record<string, React.ComponentType<any>>;\n}\n\nfunction ContentBlockRenderer({ block, registry }: ContentBlockRendererProps) {\n if (block.type === 'text') {\n return (\n <div style={{ marginBottom: '12px', lineHeight: 1.6 }}>\n {block.value.split('\\n').map((line, i) => (\n <React.Fragment key={i}>\n {line}\n {i < block.value.split('\\n').length - 1 && <br />}\n </React.Fragment>\n ))}\n </div>\n );\n }\n\n if (block.type === 'component') {\n return <DynamicComponent block={block} registry={registry} />;\n }\n\n return null;\n}\n"]}
@@ -0,0 +1,88 @@
1
+ import React from 'react';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+
4
+ // src/components/FogUIRenderer.tsx
5
+ function DefaultCard({ title, description, data }) {
6
+ return /* @__PURE__ */ jsxs("div", { style: { border: "1px solid #e5e7eb", borderRadius: "8px", padding: "16px", marginBottom: "12px" }, children: [
7
+ title && /* @__PURE__ */ jsx("h3", { style: { margin: "0 0 8px", fontSize: "18px", fontWeight: 600 }, children: title }),
8
+ description && /* @__PURE__ */ jsx("p", { style: { margin: "0 0 12px", color: "#6b7280" }, children: description }),
9
+ data && /* @__PURE__ */ jsx("div", { style: { fontSize: "14px" }, children: Object.entries(data).map(([key, value]) => /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", padding: "4px 0" }, children: [
10
+ /* @__PURE__ */ jsx("span", { style: { color: "#6b7280" }, children: key }),
11
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 500 }, children: String(value) })
12
+ ] }, key)) })
13
+ ] });
14
+ }
15
+ function DefaultList({ title, items }) {
16
+ return /* @__PURE__ */ jsxs("div", { style: { marginBottom: "12px" }, children: [
17
+ title && /* @__PURE__ */ jsx("h3", { style: { margin: "0 0 12px", fontSize: "18px", fontWeight: 600 }, children: title }),
18
+ /* @__PURE__ */ jsx("ul", { style: { margin: 0, paddingLeft: "20px" }, children: items.map((item, i) => /* @__PURE__ */ jsx("li", { style: { marginBottom: "8px" }, children: typeof item === "object" ? JSON.stringify(item) : String(item) }, i)) })
19
+ ] });
20
+ }
21
+ function DefaultTable({ columns, rows }) {
22
+ return /* @__PURE__ */ jsx("div", { style: { overflowX: "auto", marginBottom: "12px" }, children: /* @__PURE__ */ jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: "14px" }, children: [
23
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsx("th", { style: { textAlign: "left", padding: "12px 8px", borderBottom: "2px solid #e5e7eb", fontWeight: 600 }, children: col }, col)) }) }),
24
+ /* @__PURE__ */ jsx("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsx("tr", { children: columns.map((col) => /* @__PURE__ */ jsx("td", { style: { padding: "12px 8px", borderBottom: "1px solid #e5e7eb" }, children: String(row[col] ?? "") }, col)) }, i)) })
25
+ ] }) });
26
+ }
27
+ function DefaultCallout({ title, message, variant = "info" }) {
28
+ const colors = {
29
+ info: { bg: "#eff6ff", border: "#3b82f6", text: "#1e40af" },
30
+ warning: { bg: "#fffbeb", border: "#f59e0b", text: "#92400e" },
31
+ tip: { bg: "#f0fdf4", border: "#22c55e", text: "#166534" }
32
+ };
33
+ const c = colors[variant];
34
+ return /* @__PURE__ */ jsxs("div", { style: { backgroundColor: c.bg, borderLeft: `4px solid ${c.border}`, padding: "12px 16px", marginBottom: "12px", borderRadius: "0 8px 8px 0" }, children: [
35
+ title && /* @__PURE__ */ jsx("strong", { style: { color: c.text, display: "block", marginBottom: "4px" }, children: title }),
36
+ /* @__PURE__ */ jsx("span", { style: { color: c.text }, children: message })
37
+ ] });
38
+ }
39
+ var defaultComponentRegistry = {
40
+ card: DefaultCard,
41
+ list: DefaultList,
42
+ table: DefaultTable,
43
+ callout: DefaultCallout
44
+ };
45
+ function DynamicComponent({ block, registry = defaultComponentRegistry }) {
46
+ const { componentType, props } = block;
47
+ const Component = registry[componentType];
48
+ if (!Component) {
49
+ return /* @__PURE__ */ jsxs("div", { style: { padding: "12px", backgroundColor: "#fef3c7", border: "1px solid #fcd34d", borderRadius: "8px", fontSize: "14px" }, children: [
50
+ /* @__PURE__ */ jsxs("strong", { children: [
51
+ "Unknown component: ",
52
+ componentType
53
+ ] }),
54
+ /* @__PURE__ */ jsx("pre", { style: { margin: "8px 0 0", fontSize: "12px", overflow: "auto" }, children: JSON.stringify(props, null, 2) })
55
+ ] });
56
+ }
57
+ return /* @__PURE__ */ jsx(Component, { ...props });
58
+ }
59
+ function FogUIRenderer({ response, componentRegistry, className }) {
60
+ const registry = componentRegistry || defaultComponentRegistry;
61
+ if (!response || !response.content) {
62
+ return null;
63
+ }
64
+ return /* @__PURE__ */ jsx("div", { className, children: response.content.map((block, index) => /* @__PURE__ */ jsx(
65
+ ContentBlockRenderer,
66
+ {
67
+ block,
68
+ registry
69
+ },
70
+ index
71
+ )) });
72
+ }
73
+ function ContentBlockRenderer({ block, registry }) {
74
+ if (block.type === "text") {
75
+ return /* @__PURE__ */ jsx("div", { style: { marginBottom: "12px", lineHeight: 1.6 }, children: block.value.split("\n").map((line, i) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
76
+ line,
77
+ i < block.value.split("\n").length - 1 && /* @__PURE__ */ jsx("br", {})
78
+ ] }, i)) });
79
+ }
80
+ if (block.type === "component") {
81
+ return /* @__PURE__ */ jsx(DynamicComponent, { block, registry });
82
+ }
83
+ return null;
84
+ }
85
+
86
+ export { DynamicComponent, FogUIRenderer, defaultComponentRegistry };
87
+ //# sourceMappingURL=index.mjs.map
88
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/ComponentRegistry.tsx","../../src/components/FogUIRenderer.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"index.mjs","sourcesContent":["import React from 'react';\nimport type { ComponentBlock } from '../types';\n\n/**\n * Default component implementations.\n * These provide basic rendering - users should customize for their design system.\n */\n\n// Card Component\nfunction DefaultCard({ title, description, data }: { title?: string; description?: string; data?: Record<string, unknown> }) {\n return (\n <div style={{ border: '1px solid #e5e7eb', borderRadius: '8px', padding: '16px', marginBottom: '12px' }}>\n {title && <h3 style={{ margin: '0 0 8px', fontSize: '18px', fontWeight: 600 }}>{title}</h3>}\n {description && <p style={{ margin: '0 0 12px', color: '#6b7280' }}>{description}</p>}\n {data && (\n <div style={{ fontSize: '14px' }}>\n {Object.entries(data).map(([key, value]) => (\n <div key={key} style={{ display: 'flex', justifyContent: 'space-between', padding: '4px 0' }}>\n <span style={{ color: '#6b7280' }}>{key}</span>\n <span style={{ fontWeight: 500 }}>{String(value)}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// List Component\nfunction DefaultList({ title, items }: { title?: string; items: unknown[] }) {\n return (\n <div style={{ marginBottom: '12px' }}>\n {title && <h3 style={{ margin: '0 0 12px', fontSize: '18px', fontWeight: 600 }}>{title}</h3>}\n <ul style={{ margin: 0, paddingLeft: '20px' }}>\n {items.map((item, i) => (\n <li key={i} style={{ marginBottom: '8px' }}>\n {typeof item === 'object' ? JSON.stringify(item) : String(item)}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n\n// Table Component\nfunction DefaultTable({ columns, rows }: { columns: string[]; rows: Record<string, unknown>[] }) {\n return (\n <div style={{ overflowX: 'auto', marginBottom: '12px' }}>\n <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: '14px' }}>\n <thead>\n <tr>\n {columns.map((col) => (\n <th key={col} style={{ textAlign: 'left', padding: '12px 8px', borderBottom: '2px solid #e5e7eb', fontWeight: 600 }}>\n {col}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, i) => (\n <tr key={i}>\n {columns.map((col) => (\n <td key={col} style={{ padding: '12px 8px', borderBottom: '1px solid #e5e7eb' }}>\n {String(row[col] ?? '')}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\n// Callout Component\nfunction DefaultCallout({ title, message, variant = 'info' }: { title?: string; message: string; variant?: 'info' | 'warning' | 'tip' }) {\n const colors = {\n info: { bg: '#eff6ff', border: '#3b82f6', text: '#1e40af' },\n warning: { bg: '#fffbeb', border: '#f59e0b', text: '#92400e' },\n tip: { bg: '#f0fdf4', border: '#22c55e', text: '#166534' },\n };\n const c = colors[variant];\n return (\n <div style={{ backgroundColor: c.bg, borderLeft: `4px solid ${c.border}`, padding: '12px 16px', marginBottom: '12px', borderRadius: '0 8px 8px 0' }}>\n {title && <strong style={{ color: c.text, display: 'block', marginBottom: '4px' }}>{title}</strong>}\n <span style={{ color: c.text }}>{message}</span>\n </div>\n );\n}\n\n/**\n * Default component registry mapping componentType to React components.\n * Users can override this with their own components.\n */\nexport const defaultComponentRegistry: Record<string, React.ComponentType<any>> = {\n card: DefaultCard,\n list: DefaultList,\n table: DefaultTable,\n callout: DefaultCallout,\n};\n\ninterface DynamicComponentProps {\n block: ComponentBlock;\n registry?: Record<string, React.ComponentType<any>>;\n}\n\n/**\n * DynamicComponent - Renders a component based on componentType.\n */\nexport function DynamicComponent({ block, registry = defaultComponentRegistry }: DynamicComponentProps) {\n const { componentType, props } = block;\n const Component = registry[componentType];\n\n if (!Component) {\n return (\n <div style={{ padding: '12px', backgroundColor: '#fef3c7', border: '1px solid #fcd34d', borderRadius: '8px', fontSize: '14px' }}>\n <strong>Unknown component: {componentType}</strong>\n <pre style={{ margin: '8px 0 0', fontSize: '12px', overflow: 'auto' }}>\n {JSON.stringify(props, null, 2)}\n </pre>\n </div>\n );\n }\n\n return <Component {...props} />;\n}\n","import React from 'react';\nimport type { FogUIResponse, ContentBlock } from '../types';\nimport { DynamicComponent, defaultComponentRegistry } from './ComponentRegistry';\n\ninterface FogUIRendererProps {\n /**\n * The FogUIResponse to render\n */\n response: FogUIResponse;\n /**\n * Custom component registry to override default components\n */\n componentRegistry?: Record<string, React.ComponentType<any>>;\n /**\n * Custom className for the container\n */\n className?: string;\n}\n\n/**\n * FogUIRenderer - Renders a FogUIResponse as React components.\n * \n * @example\n * ```tsx\n * import { FogUIRenderer } from '@fogui/react';\n * \n * function Chat({ response }) {\n * return <FogUIRenderer response={response} />;\n * }\n * ```\n */\nexport function FogUIRenderer({ response, componentRegistry, className }: FogUIRendererProps) {\n const registry = componentRegistry || defaultComponentRegistry;\n\n if (!response || !response.content) {\n return null;\n }\n\n return (\n <div className={className}>\n {response.content.map((block, index) => (\n <ContentBlockRenderer \n key={index} \n block={block} \n registry={registry}\n />\n ))}\n </div>\n );\n}\n\ninterface ContentBlockRendererProps {\n block: ContentBlock;\n registry: Record<string, React.ComponentType<any>>;\n}\n\nfunction ContentBlockRenderer({ block, registry }: ContentBlockRendererProps) {\n if (block.type === 'text') {\n return (\n <div style={{ marginBottom: '12px', lineHeight: 1.6 }}>\n {block.value.split('\\n').map((line, i) => (\n <React.Fragment key={i}>\n {line}\n {i < block.value.split('\\n').length - 1 && <br />}\n </React.Fragment>\n ))}\n </div>\n );\n }\n\n if (block.type === 'component') {\n return <DynamicComponent block={block} registry={registry} />;\n }\n\n return null;\n}\n"]}
@@ -0,0 +1,136 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+
4
+ /**
5
+ * FogUI SDK - Core types and interfaces
6
+ */
7
+ /**
8
+ * Configuration for the FogUI SDK
9
+ */
10
+ interface FogUIConfig {
11
+ /**
12
+ * Your FogUI API key (get it from https://fogui.dev/dashboard)
13
+ */
14
+ apiKey: string;
15
+ }
16
+ interface TransformOptions {
17
+ /**
18
+ * Hints about the user's intent (e.g., "weather_query", "data_analysis")
19
+ */
20
+ intent?: string;
21
+ /**
22
+ * Preferred component types to use
23
+ */
24
+ preferredComponents?: string[];
25
+ /**
26
+ * Custom instructions for transformation
27
+ */
28
+ instructions?: string;
29
+ }
30
+ interface TransformResult {
31
+ success: boolean;
32
+ result?: FogUIResponse;
33
+ error?: string;
34
+ usage?: {
35
+ transformTokens: number;
36
+ model: string;
37
+ estimatedCost: number;
38
+ processingTimeMs: number;
39
+ };
40
+ }
41
+ interface UseFogUIReturn {
42
+ /**
43
+ * Transform raw LLM text into structured UI
44
+ */
45
+ transform: (content: string, options?: TransformOptions) => Promise<TransformResult>;
46
+ /**
47
+ * Transform with streaming - returns an async generator
48
+ */
49
+ transformStream: (content: string, options?: TransformOptions) => AsyncGenerator<StreamEvent>;
50
+ /**
51
+ * Whether a transformation is in progress
52
+ */
53
+ isLoading: boolean;
54
+ /**
55
+ * Current error if any
56
+ */
57
+ error: string | null;
58
+ /**
59
+ * Clear error state
60
+ */
61
+ clearError: () => void;
62
+ }
63
+ interface StreamEvent {
64
+ type: 'chunk' | 'result' | 'usage' | 'error' | 'done';
65
+ data: unknown;
66
+ }
67
+ interface ThinkingItem {
68
+ status: 'active' | 'complete';
69
+ message: string;
70
+ timestamp?: string;
71
+ }
72
+ type ContentBlock = TextBlock | ComponentBlock;
73
+ interface TextBlock {
74
+ type: 'text';
75
+ value: string;
76
+ }
77
+ interface ComponentBlock {
78
+ type: 'component';
79
+ componentType: string;
80
+ props: Record<string, unknown>;
81
+ }
82
+ interface FogUIResponse {
83
+ thinking: ThinkingItem[];
84
+ content: ContentBlock[];
85
+ metadata?: {
86
+ timestamp?: string;
87
+ version?: string;
88
+ modelUsed?: string;
89
+ queryType?: string;
90
+ [key: string]: unknown;
91
+ };
92
+ }
93
+
94
+ interface FogUIRendererProps {
95
+ /**
96
+ * The FogUIResponse to render
97
+ */
98
+ response: FogUIResponse;
99
+ /**
100
+ * Custom component registry to override default components
101
+ */
102
+ componentRegistry?: Record<string, React.ComponentType<any>>;
103
+ /**
104
+ * Custom className for the container
105
+ */
106
+ className?: string;
107
+ }
108
+ /**
109
+ * FogUIRenderer - Renders a FogUIResponse as React components.
110
+ *
111
+ * @example
112
+ * ```tsx
113
+ * import { FogUIRenderer } from '@fogui/react';
114
+ *
115
+ * function Chat({ response }) {
116
+ * return <FogUIRenderer response={response} />;
117
+ * }
118
+ * ```
119
+ */
120
+ declare function FogUIRenderer({ response, componentRegistry, className }: FogUIRendererProps): react_jsx_runtime.JSX.Element | null;
121
+
122
+ /**
123
+ * Default component registry mapping componentType to React components.
124
+ * Users can override this with their own components.
125
+ */
126
+ declare const defaultComponentRegistry: Record<string, React.ComponentType<any>>;
127
+ interface DynamicComponentProps {
128
+ block: ComponentBlock;
129
+ registry?: Record<string, React.ComponentType<any>>;
130
+ }
131
+ /**
132
+ * DynamicComponent - Renders a component based on componentType.
133
+ */
134
+ declare function DynamicComponent({ block, registry }: DynamicComponentProps): react_jsx_runtime.JSX.Element;
135
+
136
+ export { type ContentBlock as C, DynamicComponent as D, type FogUIConfig as F, type StreamEvent as S, type TransformOptions as T, type UseFogUIReturn as U, type TransformResult as a, type FogUIResponse as b, type TextBlock as c, type ComponentBlock as d, type ThinkingItem as e, FogUIRenderer as f, defaultComponentRegistry as g };
@@ -0,0 +1,136 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React from 'react';
3
+
4
+ /**
5
+ * FogUI SDK - Core types and interfaces
6
+ */
7
+ /**
8
+ * Configuration for the FogUI SDK
9
+ */
10
+ interface FogUIConfig {
11
+ /**
12
+ * Your FogUI API key (get it from https://fogui.dev/dashboard)
13
+ */
14
+ apiKey: string;
15
+ }
16
+ interface TransformOptions {
17
+ /**
18
+ * Hints about the user's intent (e.g., "weather_query", "data_analysis")
19
+ */
20
+ intent?: string;
21
+ /**
22
+ * Preferred component types to use
23
+ */
24
+ preferredComponents?: string[];
25
+ /**
26
+ * Custom instructions for transformation
27
+ */
28
+ instructions?: string;
29
+ }
30
+ interface TransformResult {
31
+ success: boolean;
32
+ result?: FogUIResponse;
33
+ error?: string;
34
+ usage?: {
35
+ transformTokens: number;
36
+ model: string;
37
+ estimatedCost: number;
38
+ processingTimeMs: number;
39
+ };
40
+ }
41
+ interface UseFogUIReturn {
42
+ /**
43
+ * Transform raw LLM text into structured UI
44
+ */
45
+ transform: (content: string, options?: TransformOptions) => Promise<TransformResult>;
46
+ /**
47
+ * Transform with streaming - returns an async generator
48
+ */
49
+ transformStream: (content: string, options?: TransformOptions) => AsyncGenerator<StreamEvent>;
50
+ /**
51
+ * Whether a transformation is in progress
52
+ */
53
+ isLoading: boolean;
54
+ /**
55
+ * Current error if any
56
+ */
57
+ error: string | null;
58
+ /**
59
+ * Clear error state
60
+ */
61
+ clearError: () => void;
62
+ }
63
+ interface StreamEvent {
64
+ type: 'chunk' | 'result' | 'usage' | 'error' | 'done';
65
+ data: unknown;
66
+ }
67
+ interface ThinkingItem {
68
+ status: 'active' | 'complete';
69
+ message: string;
70
+ timestamp?: string;
71
+ }
72
+ type ContentBlock = TextBlock | ComponentBlock;
73
+ interface TextBlock {
74
+ type: 'text';
75
+ value: string;
76
+ }
77
+ interface ComponentBlock {
78
+ type: 'component';
79
+ componentType: string;
80
+ props: Record<string, unknown>;
81
+ }
82
+ interface FogUIResponse {
83
+ thinking: ThinkingItem[];
84
+ content: ContentBlock[];
85
+ metadata?: {
86
+ timestamp?: string;
87
+ version?: string;
88
+ modelUsed?: string;
89
+ queryType?: string;
90
+ [key: string]: unknown;
91
+ };
92
+ }
93
+
94
+ interface FogUIRendererProps {
95
+ /**
96
+ * The FogUIResponse to render
97
+ */
98
+ response: FogUIResponse;
99
+ /**
100
+ * Custom component registry to override default components
101
+ */
102
+ componentRegistry?: Record<string, React.ComponentType<any>>;
103
+ /**
104
+ * Custom className for the container
105
+ */
106
+ className?: string;
107
+ }
108
+ /**
109
+ * FogUIRenderer - Renders a FogUIResponse as React components.
110
+ *
111
+ * @example
112
+ * ```tsx
113
+ * import { FogUIRenderer } from '@fogui/react';
114
+ *
115
+ * function Chat({ response }) {
116
+ * return <FogUIRenderer response={response} />;
117
+ * }
118
+ * ```
119
+ */
120
+ declare function FogUIRenderer({ response, componentRegistry, className }: FogUIRendererProps): react_jsx_runtime.JSX.Element | null;
121
+
122
+ /**
123
+ * Default component registry mapping componentType to React components.
124
+ * Users can override this with their own components.
125
+ */
126
+ declare const defaultComponentRegistry: Record<string, React.ComponentType<any>>;
127
+ interface DynamicComponentProps {
128
+ block: ComponentBlock;
129
+ registry?: Record<string, React.ComponentType<any>>;
130
+ }
131
+ /**
132
+ * DynamicComponent - Renders a component based on componentType.
133
+ */
134
+ declare function DynamicComponent({ block, registry }: DynamicComponentProps): react_jsx_runtime.JSX.Element;
135
+
136
+ export { type ContentBlock as C, DynamicComponent as D, type FogUIConfig as F, type StreamEvent as S, type TransformOptions as T, type UseFogUIReturn as U, type TransformResult as a, type FogUIResponse as b, type TextBlock as c, type ComponentBlock as d, type ThinkingItem as e, FogUIRenderer as f, defaultComponentRegistry as g };