@fogui/react 0.1.0 → 0.3.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.
@@ -0,0 +1,147 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var React__default = /*#__PURE__*/_interopDefault(React);
8
+
9
+ // src/adapters/shadcn.tsx
10
+ function createShadcnAdapter(components) {
11
+ const {
12
+ Card,
13
+ CardHeader,
14
+ CardContent,
15
+ CardTitle,
16
+ CardDescription,
17
+ Table,
18
+ TableHeader,
19
+ TableBody,
20
+ TableRow,
21
+ TableHead,
22
+ TableCell,
23
+ Alert,
24
+ AlertTitle,
25
+ AlertDescription,
26
+ ScrollArea
27
+ } = components;
28
+ const registry = {};
29
+ if (Card) {
30
+ registry.card = ({ title, description, data }) => {
31
+ return React__default.default.createElement(
32
+ Card,
33
+ { className: "mb-4" },
34
+ (title || description) && React__default.default.createElement(
35
+ CardHeader || "div",
36
+ null,
37
+ title && React__default.default.createElement(CardTitle || "h3", null, title),
38
+ description && React__default.default.createElement(CardDescription || "p", null, description)
39
+ ),
40
+ data && React__default.default.createElement(
41
+ CardContent || "div",
42
+ null,
43
+ React__default.default.createElement(
44
+ "dl",
45
+ { className: "grid gap-2" },
46
+ Object.entries(data).map(
47
+ ([key, value]) => React__default.default.createElement(
48
+ "div",
49
+ { key, className: "flex justify-between" },
50
+ React__default.default.createElement("dt", { className: "text-muted-foreground" }, key),
51
+ React__default.default.createElement("dd", { className: "font-medium" }, String(value))
52
+ )
53
+ )
54
+ )
55
+ )
56
+ );
57
+ };
58
+ }
59
+ if (Table && TableHeader && TableBody && TableRow && TableHead && TableCell) {
60
+ registry.table = ({ columns, rows, title }) => {
61
+ const tableContent = React__default.default.createElement(
62
+ Table,
63
+ null,
64
+ React__default.default.createElement(
65
+ TableHeader,
66
+ null,
67
+ React__default.default.createElement(
68
+ TableRow,
69
+ null,
70
+ columns.map((col) => React__default.default.createElement(TableHead, { key: col }, col))
71
+ )
72
+ ),
73
+ React__default.default.createElement(
74
+ TableBody,
75
+ null,
76
+ rows.map(
77
+ (row, i) => React__default.default.createElement(
78
+ TableRow,
79
+ { key: i },
80
+ columns.map(
81
+ (col) => React__default.default.createElement(TableCell, { key: col }, String(row[col] ?? ""))
82
+ )
83
+ )
84
+ )
85
+ )
86
+ );
87
+ if (title) {
88
+ return React__default.default.createElement(
89
+ "div",
90
+ { className: "mb-4" },
91
+ React__default.default.createElement("h3", { className: "text-lg font-semibold mb-2" }, title),
92
+ tableContent
93
+ );
94
+ }
95
+ return tableContent;
96
+ };
97
+ }
98
+ registry.list = ({ title, items, ordered }) => {
99
+ const ListTag = ordered ? "ol" : "ul";
100
+ const listContent = React__default.default.createElement(
101
+ ListTag,
102
+ { className: ordered ? "list-decimal pl-5" : "list-disc pl-5" },
103
+ items.map(
104
+ (item, i) => React__default.default.createElement(
105
+ "li",
106
+ { key: i, className: "mb-1" },
107
+ typeof item === "object" ? JSON.stringify(item) : String(item)
108
+ )
109
+ )
110
+ );
111
+ const content = title ? React__default.default.createElement(
112
+ "div",
113
+ { className: "mb-4" },
114
+ React__default.default.createElement("h3", { className: "text-lg font-semibold mb-2" }, title),
115
+ listContent
116
+ ) : listContent;
117
+ return ScrollArea ? React__default.default.createElement(ScrollArea, { className: "max-h-64" }, content) : content;
118
+ };
119
+ if (Alert) {
120
+ registry.callout = ({ title, message, variant = "info" }) => {
121
+ const alertVariant = variant === "error" || variant === "warning" ? "destructive" : "default";
122
+ return React__default.default.createElement(
123
+ Alert,
124
+ { variant: alertVariant, className: "mb-4" },
125
+ title && React__default.default.createElement(AlertTitle || "h4", null, title),
126
+ React__default.default.createElement(AlertDescription || "p", null, message)
127
+ );
128
+ };
129
+ }
130
+ return registry;
131
+ }
132
+
133
+ // src/adapters/headless.tsx
134
+ function createHeadlessAdapter(config) {
135
+ const registry = {};
136
+ for (const [key, component] of Object.entries(config)) {
137
+ if (component) {
138
+ registry[key] = component;
139
+ }
140
+ }
141
+ return registry;
142
+ }
143
+
144
+ exports.createHeadlessAdapter = createHeadlessAdapter;
145
+ exports.createShadcnAdapter = createShadcnAdapter;
146
+ //# sourceMappingURL=index.js.map
147
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/shadcn.tsx","../../src/adapters/headless.tsx"],"names":["React"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Shadcn/Radix UI Adapter for FogUI\n * \n * This adapter creates a component registry that maps FogUI component types\n * to Shadcn UI components. Since Shadcn components are copied into your project\n * (not installed from npm), you pass your components to createShadcnAdapter().\n * \n * @example\n * ```tsx\n * import { FogUIProvider } from '@fogui/react';\n * import { createShadcnAdapter } from '@fogui/react/adapters';\n * \n * // Import YOUR Shadcn components\n * import { Card, CardHeader, CardContent, CardTitle, CardDescription } from '@/components/ui/card';\n * import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from '@/components/ui/table';\n * import { Alert, AlertTitle, AlertDescription } from '@/components/ui/alert';\n * \n * const components = createShadcnAdapter({\n * Card, CardHeader, CardContent, CardTitle, CardDescription,\n * Table, TableHeader, TableBody, TableRow, TableHead, TableCell,\n * Alert, AlertTitle, AlertDescription,\n * });\n * \n * function App() {\n * return (\n * <FogUIProvider apiKey=\"fog_xxx\" components={components}>\n * <Chat />\n * </FogUIProvider>\n * );\n * }\n * ```\n */\n\nimport React from 'react';\nimport type { ComponentRegistry, CardProps, ListProps, TableProps, CalloutProps } from '../components/ComponentRegistry';\n\n/**\n * The Shadcn components you need to provide.\n * All are optional - only provide what you have installed.\n */\nexport interface ShadcnComponents {\n // Card components\n Card?: React.ComponentType<any>;\n CardHeader?: React.ComponentType<any>;\n CardContent?: React.ComponentType<any>;\n CardTitle?: React.ComponentType<any>;\n CardDescription?: React.ComponentType<any>;\n CardFooter?: React.ComponentType<any>;\n \n // Table components\n Table?: React.ComponentType<any>;\n TableHeader?: React.ComponentType<any>;\n TableBody?: React.ComponentType<any>;\n TableRow?: React.ComponentType<any>;\n TableHead?: React.ComponentType<any>;\n TableCell?: React.ComponentType<any>;\n \n // Alert components (for callouts)\n Alert?: React.ComponentType<any>;\n AlertTitle?: React.ComponentType<any>;\n AlertDescription?: React.ComponentType<any>;\n \n // Badge (for tags/labels)\n Badge?: React.ComponentType<any>;\n \n // Scroll area (for lists)\n ScrollArea?: React.ComponentType<any>;\n}\n\n/**\n * Creates a FogUI component registry from Shadcn components.\n * \n * @param components - Your Shadcn UI components\n * @returns A ComponentRegistry for use with FogUIProvider\n */\nexport function createShadcnAdapter(components: ShadcnComponents): ComponentRegistry {\n const {\n Card,\n CardHeader,\n CardContent,\n CardTitle,\n CardDescription,\n Table,\n TableHeader,\n TableBody,\n TableRow,\n TableHead,\n TableCell,\n Alert,\n AlertTitle,\n AlertDescription,\n ScrollArea,\n } = components;\n\n const registry: ComponentRegistry = {};\n\n // Card component\n if (Card) {\n registry.card = ({ title, description, data }: CardProps) => {\n return React.createElement(Card, { className: 'mb-4' },\n (title || description) && React.createElement(CardHeader || 'div', null,\n title && React.createElement(CardTitle || 'h3', null, title),\n description && React.createElement(CardDescription || 'p', null, description)\n ),\n data && React.createElement(CardContent || 'div', null,\n React.createElement('dl', { className: 'grid gap-2' },\n Object.entries(data).map(([key, value]) =>\n React.createElement('div', { key, className: 'flex justify-between' },\n React.createElement('dt', { className: 'text-muted-foreground' }, key),\n React.createElement('dd', { className: 'font-medium' }, String(value))\n )\n )\n )\n )\n );\n };\n }\n\n // Table component\n if (Table && TableHeader && TableBody && TableRow && TableHead && TableCell) {\n registry.table = ({ columns, rows, title }: TableProps) => {\n const tableContent = React.createElement(Table, null,\n React.createElement(TableHeader, null,\n React.createElement(TableRow, null,\n columns.map((col) => React.createElement(TableHead, { key: col }, col))\n )\n ),\n React.createElement(TableBody, null,\n rows.map((row, i) =>\n React.createElement(TableRow, { key: i },\n columns.map((col) =>\n React.createElement(TableCell, { key: col }, String(row[col] ?? ''))\n )\n )\n )\n )\n );\n\n if (title) {\n return React.createElement('div', { className: 'mb-4' },\n React.createElement('h3', { className: 'text-lg font-semibold mb-2' }, title),\n tableContent\n );\n }\n\n return tableContent;\n };\n }\n\n // List component\n registry.list = ({ title, items, ordered }: ListProps) => {\n const ListTag = ordered ? 'ol' : 'ul';\n const listContent = React.createElement(ListTag, { className: ordered ? 'list-decimal pl-5' : 'list-disc pl-5' },\n items.map((item, i) =>\n React.createElement('li', { key: i, className: 'mb-1' },\n typeof item === 'object' ? JSON.stringify(item) : String(item)\n )\n )\n );\n\n const content = title\n ? React.createElement('div', { className: 'mb-4' },\n React.createElement('h3', { className: 'text-lg font-semibold mb-2' }, title),\n listContent\n )\n : listContent;\n\n return ScrollArea\n ? React.createElement(ScrollArea, { className: 'max-h-64' }, content)\n : content;\n };\n\n // Callout/Alert component\n if (Alert) {\n registry.callout = ({ title, message, variant = 'info' }: CalloutProps) => {\n // Map FogUI variants to Shadcn Alert variants\n const alertVariant = variant === 'error' || variant === 'warning' ? 'destructive' : 'default';\n \n return React.createElement(Alert, { variant: alertVariant, className: 'mb-4' },\n title && React.createElement(AlertTitle || 'h4', null, title),\n React.createElement(AlertDescription || 'p', null, message)\n );\n };\n }\n\n return registry;\n}\n","/**\n * Headless Adapter for FogUI\n * \n * This adapter provides maximum flexibility by giving you render props / hooks\n * for each component type. You bring your own markup and styling.\n * Perfect for Tailwind CSS, custom design systems, or any UI approach.\n * \n * @example\n * ```tsx\n * import { FogUIProvider } from '@fogui/react';\n * import { createHeadlessAdapter } from '@fogui/react/adapters';\n * \n * const components = createHeadlessAdapter({\n * card: ({ title, description, data, children }) => (\n * <div className=\"rounded-lg border p-4 shadow-sm\">\n * {title && <h3 className=\"font-bold text-lg\">{title}</h3>}\n * {description && <p className=\"text-gray-600\">{description}</p>}\n * {children}\n * </div>\n * ),\n * table: ({ columns, rows }) => (\n * <table className=\"w-full border-collapse\">\n * <thead>\n * <tr>{columns.map(col => <th key={col}>{col}</th>)}</tr>\n * </thead>\n * <tbody>\n * {rows.map((row, i) => (\n * <tr key={i}>\n * {columns.map(col => <td key={col}>{row[col]}</td>)}\n * </tr>\n * ))}\n * </tbody>\n * </table>\n * ),\n * });\n * \n * function App() {\n * return (\n * <FogUIProvider apiKey=\"fog_xxx\" components={components}>\n * <Chat />\n * </FogUIProvider>\n * );\n * }\n * ```\n */\n\nimport type { CalloutProps, CardProps, ComponentRegistry, ListProps, TableProps } from '../components/ComponentRegistry';\n\nimport React from 'react';\n\n/**\n * Configuration for creating a headless adapter.\n * Each component is a simple React component that receives typed props.\n */\nexport interface HeadlessConfig {\n /** Custom card component */\n card?: React.ComponentType<CardProps>;\n /** Custom list component */\n list?: React.ComponentType<ListProps>;\n /** Custom table component */\n table?: React.ComponentType<TableProps>;\n /** Custom callout/alert component */\n callout?: React.ComponentType<CalloutProps>;\n /** Additional custom components */\n [key: string]: React.ComponentType<any> | undefined;\n}\n\n/**\n * Creates a FogUI component registry from custom components.\n * This is the most flexible adapter - you provide complete components.\n * \n * @param config - Your custom component implementations\n * @returns A ComponentRegistry for use with FogUIProvider\n */\nexport function createHeadlessAdapter(config: HeadlessConfig): ComponentRegistry {\n const registry: ComponentRegistry = {};\n\n for (const [key, component] of Object.entries(config)) {\n if (component) {\n registry[key] = component;\n }\n }\n\n return registry;\n}\n"]}
@@ -0,0 +1,140 @@
1
+ import React from 'react';
2
+
3
+ // src/adapters/shadcn.tsx
4
+ function createShadcnAdapter(components) {
5
+ const {
6
+ Card,
7
+ CardHeader,
8
+ CardContent,
9
+ CardTitle,
10
+ CardDescription,
11
+ Table,
12
+ TableHeader,
13
+ TableBody,
14
+ TableRow,
15
+ TableHead,
16
+ TableCell,
17
+ Alert,
18
+ AlertTitle,
19
+ AlertDescription,
20
+ ScrollArea
21
+ } = components;
22
+ const registry = {};
23
+ if (Card) {
24
+ registry.card = ({ title, description, data }) => {
25
+ return React.createElement(
26
+ Card,
27
+ { className: "mb-4" },
28
+ (title || description) && React.createElement(
29
+ CardHeader || "div",
30
+ null,
31
+ title && React.createElement(CardTitle || "h3", null, title),
32
+ description && React.createElement(CardDescription || "p", null, description)
33
+ ),
34
+ data && React.createElement(
35
+ CardContent || "div",
36
+ null,
37
+ React.createElement(
38
+ "dl",
39
+ { className: "grid gap-2" },
40
+ Object.entries(data).map(
41
+ ([key, value]) => React.createElement(
42
+ "div",
43
+ { key, className: "flex justify-between" },
44
+ React.createElement("dt", { className: "text-muted-foreground" }, key),
45
+ React.createElement("dd", { className: "font-medium" }, String(value))
46
+ )
47
+ )
48
+ )
49
+ )
50
+ );
51
+ };
52
+ }
53
+ if (Table && TableHeader && TableBody && TableRow && TableHead && TableCell) {
54
+ registry.table = ({ columns, rows, title }) => {
55
+ const tableContent = React.createElement(
56
+ Table,
57
+ null,
58
+ React.createElement(
59
+ TableHeader,
60
+ null,
61
+ React.createElement(
62
+ TableRow,
63
+ null,
64
+ columns.map((col) => React.createElement(TableHead, { key: col }, col))
65
+ )
66
+ ),
67
+ React.createElement(
68
+ TableBody,
69
+ null,
70
+ rows.map(
71
+ (row, i) => React.createElement(
72
+ TableRow,
73
+ { key: i },
74
+ columns.map(
75
+ (col) => React.createElement(TableCell, { key: col }, String(row[col] ?? ""))
76
+ )
77
+ )
78
+ )
79
+ )
80
+ );
81
+ if (title) {
82
+ return React.createElement(
83
+ "div",
84
+ { className: "mb-4" },
85
+ React.createElement("h3", { className: "text-lg font-semibold mb-2" }, title),
86
+ tableContent
87
+ );
88
+ }
89
+ return tableContent;
90
+ };
91
+ }
92
+ registry.list = ({ title, items, ordered }) => {
93
+ const ListTag = ordered ? "ol" : "ul";
94
+ const listContent = React.createElement(
95
+ ListTag,
96
+ { className: ordered ? "list-decimal pl-5" : "list-disc pl-5" },
97
+ items.map(
98
+ (item, i) => React.createElement(
99
+ "li",
100
+ { key: i, className: "mb-1" },
101
+ typeof item === "object" ? JSON.stringify(item) : String(item)
102
+ )
103
+ )
104
+ );
105
+ const content = title ? React.createElement(
106
+ "div",
107
+ { className: "mb-4" },
108
+ React.createElement("h3", { className: "text-lg font-semibold mb-2" }, title),
109
+ listContent
110
+ ) : listContent;
111
+ return ScrollArea ? React.createElement(ScrollArea, { className: "max-h-64" }, content) : content;
112
+ };
113
+ if (Alert) {
114
+ registry.callout = ({ title, message, variant = "info" }) => {
115
+ const alertVariant = variant === "error" || variant === "warning" ? "destructive" : "default";
116
+ return React.createElement(
117
+ Alert,
118
+ { variant: alertVariant, className: "mb-4" },
119
+ title && React.createElement(AlertTitle || "h4", null, title),
120
+ React.createElement(AlertDescription || "p", null, message)
121
+ );
122
+ };
123
+ }
124
+ return registry;
125
+ }
126
+
127
+ // src/adapters/headless.tsx
128
+ function createHeadlessAdapter(config) {
129
+ const registry = {};
130
+ for (const [key, component] of Object.entries(config)) {
131
+ if (component) {
132
+ registry[key] = component;
133
+ }
134
+ }
135
+ return registry;
136
+ }
137
+
138
+ export { createHeadlessAdapter, createShadcnAdapter };
139
+ //# sourceMappingURL=index.mjs.map
140
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/adapters/shadcn.tsx","../../src/adapters/headless.tsx"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Shadcn/Radix UI Adapter for FogUI\n * \n * This adapter creates a component registry that maps FogUI component types\n * to Shadcn UI components. Since Shadcn components are copied into your project\n * (not installed from npm), you pass your components to createShadcnAdapter().\n * \n * @example\n * ```tsx\n * import { FogUIProvider } from '@fogui/react';\n * import { createShadcnAdapter } from '@fogui/react/adapters';\n * \n * // Import YOUR Shadcn components\n * import { Card, CardHeader, CardContent, CardTitle, CardDescription } from '@/components/ui/card';\n * import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from '@/components/ui/table';\n * import { Alert, AlertTitle, AlertDescription } from '@/components/ui/alert';\n * \n * const components = createShadcnAdapter({\n * Card, CardHeader, CardContent, CardTitle, CardDescription,\n * Table, TableHeader, TableBody, TableRow, TableHead, TableCell,\n * Alert, AlertTitle, AlertDescription,\n * });\n * \n * function App() {\n * return (\n * <FogUIProvider apiKey=\"fog_xxx\" components={components}>\n * <Chat />\n * </FogUIProvider>\n * );\n * }\n * ```\n */\n\nimport React from 'react';\nimport type { ComponentRegistry, CardProps, ListProps, TableProps, CalloutProps } from '../components/ComponentRegistry';\n\n/**\n * The Shadcn components you need to provide.\n * All are optional - only provide what you have installed.\n */\nexport interface ShadcnComponents {\n // Card components\n Card?: React.ComponentType<any>;\n CardHeader?: React.ComponentType<any>;\n CardContent?: React.ComponentType<any>;\n CardTitle?: React.ComponentType<any>;\n CardDescription?: React.ComponentType<any>;\n CardFooter?: React.ComponentType<any>;\n \n // Table components\n Table?: React.ComponentType<any>;\n TableHeader?: React.ComponentType<any>;\n TableBody?: React.ComponentType<any>;\n TableRow?: React.ComponentType<any>;\n TableHead?: React.ComponentType<any>;\n TableCell?: React.ComponentType<any>;\n \n // Alert components (for callouts)\n Alert?: React.ComponentType<any>;\n AlertTitle?: React.ComponentType<any>;\n AlertDescription?: React.ComponentType<any>;\n \n // Badge (for tags/labels)\n Badge?: React.ComponentType<any>;\n \n // Scroll area (for lists)\n ScrollArea?: React.ComponentType<any>;\n}\n\n/**\n * Creates a FogUI component registry from Shadcn components.\n * \n * @param components - Your Shadcn UI components\n * @returns A ComponentRegistry for use with FogUIProvider\n */\nexport function createShadcnAdapter(components: ShadcnComponents): ComponentRegistry {\n const {\n Card,\n CardHeader,\n CardContent,\n CardTitle,\n CardDescription,\n Table,\n TableHeader,\n TableBody,\n TableRow,\n TableHead,\n TableCell,\n Alert,\n AlertTitle,\n AlertDescription,\n ScrollArea,\n } = components;\n\n const registry: ComponentRegistry = {};\n\n // Card component\n if (Card) {\n registry.card = ({ title, description, data }: CardProps) => {\n return React.createElement(Card, { className: 'mb-4' },\n (title || description) && React.createElement(CardHeader || 'div', null,\n title && React.createElement(CardTitle || 'h3', null, title),\n description && React.createElement(CardDescription || 'p', null, description)\n ),\n data && React.createElement(CardContent || 'div', null,\n React.createElement('dl', { className: 'grid gap-2' },\n Object.entries(data).map(([key, value]) =>\n React.createElement('div', { key, className: 'flex justify-between' },\n React.createElement('dt', { className: 'text-muted-foreground' }, key),\n React.createElement('dd', { className: 'font-medium' }, String(value))\n )\n )\n )\n )\n );\n };\n }\n\n // Table component\n if (Table && TableHeader && TableBody && TableRow && TableHead && TableCell) {\n registry.table = ({ columns, rows, title }: TableProps) => {\n const tableContent = React.createElement(Table, null,\n React.createElement(TableHeader, null,\n React.createElement(TableRow, null,\n columns.map((col) => React.createElement(TableHead, { key: col }, col))\n )\n ),\n React.createElement(TableBody, null,\n rows.map((row, i) =>\n React.createElement(TableRow, { key: i },\n columns.map((col) =>\n React.createElement(TableCell, { key: col }, String(row[col] ?? ''))\n )\n )\n )\n )\n );\n\n if (title) {\n return React.createElement('div', { className: 'mb-4' },\n React.createElement('h3', { className: 'text-lg font-semibold mb-2' }, title),\n tableContent\n );\n }\n\n return tableContent;\n };\n }\n\n // List component\n registry.list = ({ title, items, ordered }: ListProps) => {\n const ListTag = ordered ? 'ol' : 'ul';\n const listContent = React.createElement(ListTag, { className: ordered ? 'list-decimal pl-5' : 'list-disc pl-5' },\n items.map((item, i) =>\n React.createElement('li', { key: i, className: 'mb-1' },\n typeof item === 'object' ? JSON.stringify(item) : String(item)\n )\n )\n );\n\n const content = title\n ? React.createElement('div', { className: 'mb-4' },\n React.createElement('h3', { className: 'text-lg font-semibold mb-2' }, title),\n listContent\n )\n : listContent;\n\n return ScrollArea\n ? React.createElement(ScrollArea, { className: 'max-h-64' }, content)\n : content;\n };\n\n // Callout/Alert component\n if (Alert) {\n registry.callout = ({ title, message, variant = 'info' }: CalloutProps) => {\n // Map FogUI variants to Shadcn Alert variants\n const alertVariant = variant === 'error' || variant === 'warning' ? 'destructive' : 'default';\n \n return React.createElement(Alert, { variant: alertVariant, className: 'mb-4' },\n title && React.createElement(AlertTitle || 'h4', null, title),\n React.createElement(AlertDescription || 'p', null, message)\n );\n };\n }\n\n return registry;\n}\n","/**\n * Headless Adapter for FogUI\n * \n * This adapter provides maximum flexibility by giving you render props / hooks\n * for each component type. You bring your own markup and styling.\n * Perfect for Tailwind CSS, custom design systems, or any UI approach.\n * \n * @example\n * ```tsx\n * import { FogUIProvider } from '@fogui/react';\n * import { createHeadlessAdapter } from '@fogui/react/adapters';\n * \n * const components = createHeadlessAdapter({\n * card: ({ title, description, data, children }) => (\n * <div className=\"rounded-lg border p-4 shadow-sm\">\n * {title && <h3 className=\"font-bold text-lg\">{title}</h3>}\n * {description && <p className=\"text-gray-600\">{description}</p>}\n * {children}\n * </div>\n * ),\n * table: ({ columns, rows }) => (\n * <table className=\"w-full border-collapse\">\n * <thead>\n * <tr>{columns.map(col => <th key={col}>{col}</th>)}</tr>\n * </thead>\n * <tbody>\n * {rows.map((row, i) => (\n * <tr key={i}>\n * {columns.map(col => <td key={col}>{row[col]}</td>)}\n * </tr>\n * ))}\n * </tbody>\n * </table>\n * ),\n * });\n * \n * function App() {\n * return (\n * <FogUIProvider apiKey=\"fog_xxx\" components={components}>\n * <Chat />\n * </FogUIProvider>\n * );\n * }\n * ```\n */\n\nimport type { CalloutProps, CardProps, ComponentRegistry, ListProps, TableProps } from '../components/ComponentRegistry';\n\nimport React from 'react';\n\n/**\n * Configuration for creating a headless adapter.\n * Each component is a simple React component that receives typed props.\n */\nexport interface HeadlessConfig {\n /** Custom card component */\n card?: React.ComponentType<CardProps>;\n /** Custom list component */\n list?: React.ComponentType<ListProps>;\n /** Custom table component */\n table?: React.ComponentType<TableProps>;\n /** Custom callout/alert component */\n callout?: React.ComponentType<CalloutProps>;\n /** Additional custom components */\n [key: string]: React.ComponentType<any> | undefined;\n}\n\n/**\n * Creates a FogUI component registry from custom components.\n * This is the most flexible adapter - you provide complete components.\n * \n * @param config - Your custom component implementations\n * @returns A ComponentRegistry for use with FogUIProvider\n */\nexport function createHeadlessAdapter(config: HeadlessConfig): ComponentRegistry {\n const registry: ComponentRegistry = {};\n\n for (const [key, component] of Object.entries(config)) {\n if (component) {\n registry[key] = component;\n }\n }\n\n return registry;\n}\n"]}
@@ -1,3 +1,51 @@
1
- export { D as DynamicComponent, f as FogUIRenderer, g as defaultComponentRegistry } from '../index-BcLda68r.mjs';
2
- import 'react/jsx-runtime';
3
- import 'react';
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { b as FogUIResponse } from '../ComponentRegistry-BFgVIcHz.mjs';
3
+ export { D as DynamicComponent, f as defaultComponentRegistry } from '../ComponentRegistry-BFgVIcHz.mjs';
4
+ import React from 'react';
5
+
6
+ interface FogUIRendererProps {
7
+ /**
8
+ * The FogUIResponse to render
9
+ */
10
+ response: FogUIResponse;
11
+ /**
12
+ * Custom component registry to override context/default components.
13
+ * If not provided, uses the registry from FogUIProvider (if any),
14
+ * falling back to defaultComponentRegistry.
15
+ */
16
+ componentRegistry?: Record<string, React.ComponentType<any>>;
17
+ /**
18
+ * Custom className for the container
19
+ */
20
+ className?: string;
21
+ /**
22
+ * Custom styles for the container
23
+ */
24
+ style?: React.CSSProperties;
25
+ }
26
+ /**
27
+ * FogUIRenderer - Renders a FogUIResponse as React components.
28
+ *
29
+ * Uses the component registry from FogUIProvider if configured,
30
+ * otherwise falls back to default components.
31
+ *
32
+ * @example Basic usage
33
+ * ```tsx
34
+ * import { FogUIRenderer } from '@fogui/react';
35
+ *
36
+ * function Chat({ response }) {
37
+ * return <FogUIRenderer response={response} />;
38
+ * }
39
+ * ```
40
+ *
41
+ * @example With inline component override
42
+ * ```tsx
43
+ * <FogUIRenderer
44
+ * response={response}
45
+ * componentRegistry={{ card: MySpecialCard }}
46
+ * />
47
+ * ```
48
+ */
49
+ declare function FogUIRenderer({ response, componentRegistry, className, style }: FogUIRendererProps): react_jsx_runtime.JSX.Element | null;
50
+
51
+ export { FogUIRenderer };
@@ -1,3 +1,51 @@
1
- export { D as DynamicComponent, f as FogUIRenderer, g as defaultComponentRegistry } from '../index-BcLda68r.js';
2
- import 'react/jsx-runtime';
3
- import 'react';
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { b as FogUIResponse } from '../ComponentRegistry-BFgVIcHz.js';
3
+ export { D as DynamicComponent, f as defaultComponentRegistry } from '../ComponentRegistry-BFgVIcHz.js';
4
+ import React from 'react';
5
+
6
+ interface FogUIRendererProps {
7
+ /**
8
+ * The FogUIResponse to render
9
+ */
10
+ response: FogUIResponse;
11
+ /**
12
+ * Custom component registry to override context/default components.
13
+ * If not provided, uses the registry from FogUIProvider (if any),
14
+ * falling back to defaultComponentRegistry.
15
+ */
16
+ componentRegistry?: Record<string, React.ComponentType<any>>;
17
+ /**
18
+ * Custom className for the container
19
+ */
20
+ className?: string;
21
+ /**
22
+ * Custom styles for the container
23
+ */
24
+ style?: React.CSSProperties;
25
+ }
26
+ /**
27
+ * FogUIRenderer - Renders a FogUIResponse as React components.
28
+ *
29
+ * Uses the component registry from FogUIProvider if configured,
30
+ * otherwise falls back to default components.
31
+ *
32
+ * @example Basic usage
33
+ * ```tsx
34
+ * import { FogUIRenderer } from '@fogui/react';
35
+ *
36
+ * function Chat({ response }) {
37
+ * return <FogUIRenderer response={response} />;
38
+ * }
39
+ * ```
40
+ *
41
+ * @example With inline component override
42
+ * ```tsx
43
+ * <FogUIRenderer
44
+ * response={response}
45
+ * componentRegistry={{ card: MySpecialCard }}
46
+ * />
47
+ * ```
48
+ */
49
+ declare function FogUIRenderer({ response, componentRegistry, className, style }: FogUIRendererProps): react_jsx_runtime.JSX.Element | null;
50
+
51
+ export { FogUIRenderer };
@@ -1,13 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var React = require('react');
4
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var React2 = require('react');
5
5
 
6
6
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
7
 
8
- var React__default = /*#__PURE__*/_interopDefault(React);
8
+ var React2__default = /*#__PURE__*/_interopDefault(React2);
9
9
 
10
- // src/components/FogUIRenderer.tsx
10
+ // src/components/ComponentRegistry.tsx
11
+ function mergeRegistries(...registries) {
12
+ return registries.reduce((merged, registry) => {
13
+ if (registry) {
14
+ return { ...merged, ...registry };
15
+ }
16
+ return merged;
17
+ }, {});
18
+ }
11
19
  function DefaultCard({ title, description, data }) {
12
20
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { border: "1px solid #e5e7eb", borderRadius: "8px", padding: "16px", marginBottom: "12px" }, children: [
13
21
  title && /* @__PURE__ */ jsxRuntime.jsx("h3", { style: { margin: "0 0 8px", fontSize: "18px", fontWeight: 600 }, children: title }),
@@ -62,12 +70,26 @@ function DynamicComponent({ block, registry = defaultComponentRegistry }) {
62
70
  }
63
71
  return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...props });
64
72
  }
65
- function FogUIRenderer({ response, componentRegistry, className }) {
66
- const registry = componentRegistry || defaultComponentRegistry;
73
+ var FogUIContext = React2.createContext(null);
74
+ function useFogUIContext() {
75
+ const context = React2.useContext(FogUIContext);
76
+ if (!context) {
77
+ throw new Error('useFogUI must be used within a FogUIProvider. Wrap your app with <FogUIProvider apiKey="...">');
78
+ }
79
+ return context;
80
+ }
81
+ function FogUIRenderer({ response, componentRegistry, className, style }) {
82
+ let contextRegistry;
83
+ try {
84
+ const context = useFogUIContext();
85
+ contextRegistry = context.componentRegistry;
86
+ } catch {
87
+ }
88
+ const registry = mergeRegistries(defaultComponentRegistry, contextRegistry, componentRegistry);
67
89
  if (!response || !response.content) {
68
90
  return null;
69
91
  }
70
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: response.content.map((block, index) => /* @__PURE__ */ jsxRuntime.jsx(
92
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style, children: response.content.map((block, index) => /* @__PURE__ */ jsxRuntime.jsx(
71
93
  ContentBlockRenderer,
72
94
  {
73
95
  block,
@@ -78,7 +100,7 @@ function FogUIRenderer({ response, componentRegistry, className }) {
78
100
  }
79
101
  function ContentBlockRenderer({ block, registry }) {
80
102
  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: [
103
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: "12px", lineHeight: 1.6 }, children: block.value.split("\n").map((line, i) => /* @__PURE__ */ jsxRuntime.jsxs(React2__default.default.Fragment, { children: [
82
104
  line,
83
105
  i < block.value.split("\n").length - 1 && /* @__PURE__ */ jsxRuntime.jsx("br", {})
84
106
  ] }, i)) });
@@ -1 +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"]}
1
+ {"version":3,"sources":["../../src/components/ComponentRegistry.tsx","../../src/FogUIProvider.tsx","../../src/components/FogUIRenderer.tsx"],"names":["jsxs","jsx","createContext","useContext","React"],"mappings":"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","file":"index.js","sourcesContent":["import React from 'react';\nimport type { ComponentBlock } from '../types';\n\n/**\n * Component registry type - maps componentType strings to React components.\n * \n * Each component receives props that match the FogUI DSL for that component type.\n */\nexport type ComponentRegistry = Record<string, React.ComponentType<any>>;\n\n/**\n * Standard prop interfaces for built-in FogUI component types.\n * Useful for implementing custom components that match the expected API.\n */\nexport interface CardProps {\n title?: string;\n description?: string;\n data?: Record<string, unknown>;\n children?: React.ReactNode;\n}\n\nexport interface ListProps {\n title?: string;\n items: unknown[];\n ordered?: boolean;\n}\n\nexport interface TableProps {\n columns: string[];\n rows: Record<string, unknown>[];\n title?: string;\n}\n\nexport interface CalloutProps {\n title?: string;\n message: string;\n variant?: 'info' | 'warning' | 'tip' | 'error';\n}\n\n/**\n * Merge multiple component registries with later registries taking precedence.\n * Useful for layering: defaults → context → prop overrides.\n */\nexport function mergeRegistries(\n ...registries: (ComponentRegistry | undefined)[]\n): ComponentRegistry {\n return registries.reduce<ComponentRegistry>((merged, registry) => {\n if (registry) {\n return { ...merged, ...registry };\n }\n return merged;\n }, {});\n}\n\n/**\n * Create a component registry from an adapter.\n * This is a convenience function for creating type-safe registries.\n * \n * @example\n * ```tsx\n * import { createRegistry } from '@fogui/react';\n * import { Card } from '@/components/ui/card';\n * \n * const myRegistry = createRegistry({\n * card: MyCardComponent,\n * table: MyTableComponent,\n * });\n * ```\n */\nexport function createRegistry(components: Partial<{\n card: React.ComponentType<CardProps>;\n list: React.ComponentType<ListProps>;\n table: React.ComponentType<TableProps>;\n callout: React.ComponentType<CalloutProps>;\n [key: string]: React.ComponentType<any>;\n}>): ComponentRegistry {\n return components as ComponentRegistry;\n}\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, { createContext, useContext, useMemo } from 'react';\n\n/**\n * FogUI Platform API endpoint\n */\nconst FOGUI_API_ENDPOINT = 'https://api.virtuoapps.com';\n\n/**\n * Component registry type - maps componentType to React components\n */\nexport type ComponentRegistry = Record<string, React.ComponentType<any>>;\n\ninterface FogUIContextValue {\n apiKey: string;\n endpoint: string;\n componentRegistry?: ComponentRegistry;\n}\n\nconst FogUIContext = createContext<FogUIContextValue | null>(null);\n\nexport interface FogUIProviderProps {\n children: React.ReactNode;\n /**\n * Your FogUI API key (get it from https://fogui.dev/dashboard)\n */\n apiKey: string;\n /**\n * Custom API endpoint (for self-hosted deployments)\n * @default 'https://api.virtuoapps.com'\n */\n endpoint?: string;\n /**\n * Custom component registry for your design system.\n * Map FogUI component types to your own React components.\n * \n * @example\n * ```tsx\n * import { Card, Table } from '@/components/ui';\n * \n * <FogUIProvider \n * apiKey=\"fog_xxx\"\n * components={{\n * card: MyCard,\n * table: MyTable,\n * list: MyList,\n * }}\n * >\n * ```\n */\n components?: ComponentRegistry;\n}\n\n/**\n * FogUIProvider - Provides FogUI configuration to the component tree.\n * \n * @example Basic usage\n * ```tsx\n * import { FogUIProvider } from '@fogui/react';\n * \n * function App() {\n * return (\n * <FogUIProvider apiKey=\"fog_xxxx\">\n * <MyApp />\n * </FogUIProvider>\n * );\n * }\n * ```\n * \n * @example With custom design system (e.g., Shadcn)\n * ```tsx\n * import { FogUIProvider } from '@fogui/react';\n * import { Card, CardHeader, CardContent } from '@/components/ui/card';\n * import { Table, TableHeader, TableBody, TableRow, TableCell } from '@/components/ui/table';\n * \n * // Map FogUI component types to your design system\n * const myComponents = {\n * card: ({ title, description, data }) => (\n * <Card>\n * <CardHeader>{title}</CardHeader>\n * <CardContent>{description}</CardContent>\n * </Card>\n * ),\n * table: MyTableComponent,\n * list: MyListComponent,\n * };\n * \n * function App() {\n * return (\n * <FogUIProvider apiKey=\"fog_xxxx\" components={myComponents}>\n * <MyApp />\n * </FogUIProvider>\n * );\n * }\n * ```\n * \n * @example Self-hosted deployment\n * ```tsx\n * <FogUIProvider \n * apiKey=\"fog_xxxx\" \n * endpoint=\"https://fogui.mycompany.com\"\n * >\n * <MyApp />\n * </FogUIProvider>\n * ```\n */\nexport function FogUIProvider({ children, apiKey, endpoint, components }: FogUIProviderProps) {\n if (!apiKey) {\n console.warn('[FogUI] API key is required. Get one at https://fogui.dev/dashboard');\n }\n\n const value = useMemo<FogUIContextValue>(() => ({\n apiKey,\n endpoint: endpoint || FOGUI_API_ENDPOINT,\n componentRegistry: components,\n }), [apiKey, endpoint, components]);\n\n return (\n <FogUIContext.Provider value={value}>\n {children}\n </FogUIContext.Provider>\n );\n}\n\n/**\n * Hook to access FogUI context\n * @internal\n */\nexport function useFogUIContext(): FogUIContextValue {\n const context = useContext(FogUIContext);\n if (!context) {\n throw new Error('useFogUI must be used within a FogUIProvider. Wrap your app with <FogUIProvider apiKey=\"...\">');\n }\n return context;\n}\n","import type { ContentBlock, FogUIResponse } from '../types';\nimport { DynamicComponent, defaultComponentRegistry, mergeRegistries } from './ComponentRegistry';\n\nimport React from 'react';\nimport { useFogUIContext } from '../FogUIProvider';\n\ninterface FogUIRendererProps {\n /**\n * The FogUIResponse to render\n */\n response: FogUIResponse;\n /**\n * Custom component registry to override context/default components.\n * If not provided, uses the registry from FogUIProvider (if any),\n * falling back to defaultComponentRegistry.\n */\n componentRegistry?: Record<string, React.ComponentType<any>>;\n /**\n * Custom className for the container\n */\n className?: string;\n /**\n * Custom styles for the container\n */\n style?: React.CSSProperties;\n}\n\n/**\n * FogUIRenderer - Renders a FogUIResponse as React components.\n * \n * Uses the component registry from FogUIProvider if configured,\n * otherwise falls back to default components.\n * \n * @example Basic usage\n * ```tsx\n * import { FogUIRenderer } from '@fogui/react';\n * \n * function Chat({ response }) {\n * return <FogUIRenderer response={response} />;\n * }\n * ```\n * \n * @example With inline component override\n * ```tsx\n * <FogUIRenderer \n * response={response} \n * componentRegistry={{ card: MySpecialCard }}\n * />\n * ```\n */\nexport function FogUIRenderer({ response, componentRegistry, className, style }: FogUIRendererProps) {\n // Try to get registry from context (set in FogUIProvider)\n let contextRegistry: Record<string, React.ComponentType<any>> | undefined;\n try {\n const context = useFogUIContext();\n contextRegistry = context.componentRegistry;\n } catch {\n // Not inside FogUIProvider, use defaults\n }\n\n // Merge: prop registry > context registry > default registry\n const registry = mergeRegistries(defaultComponentRegistry, contextRegistry, componentRegistry);\n\n if (!response || !response.content) {\n return null;\n }\n\n return (\n <div className={className} style={style}>\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"]}