@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 +138 -0
- package/dist/components/index.d.mts +3 -0
- package/dist/components/index.d.ts +3 -0
- package/dist/components/index.js +96 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +88 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/index-BcLda68r.d.mts +136 -0
- package/dist/index-BcLda68r.d.ts +136 -0
- package/dist/index.d.mts +69 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.js +234 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +223 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +67 -0
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
|
+
[](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,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 };
|