@streamoid/chat-components 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +33 -0
- package/dist/index.js +181 -0
- package/package.json +37 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface DynamicFormProps {
|
|
4
|
+
workspaceId: string;
|
|
5
|
+
userId: string;
|
|
6
|
+
email: string;
|
|
7
|
+
conversationId: string;
|
|
8
|
+
isActive: boolean;
|
|
9
|
+
submitted?: boolean;
|
|
10
|
+
submittedValues?: Record<string, unknown>;
|
|
11
|
+
uiProps: Record<string, unknown>;
|
|
12
|
+
meta?: Record<string, unknown>;
|
|
13
|
+
onSubmit: (values: Record<string, unknown>, message?: string) => void;
|
|
14
|
+
onCancel?: () => void;
|
|
15
|
+
}
|
|
16
|
+
declare function DynamicForm(props: DynamicFormProps): react_jsx_runtime.JSX.Element;
|
|
17
|
+
|
|
18
|
+
declare const dynamicFormManifest: {
|
|
19
|
+
readonly name: "common:dynamic-form";
|
|
20
|
+
readonly aliases: readonly ["dynamic_form"];
|
|
21
|
+
readonly service: "common";
|
|
22
|
+
readonly description: "Server-driven dynamic form supporting text, textarea, number, select, multiselect, checkbox, radio, approval, todo_list, and file upload fields";
|
|
23
|
+
readonly containerStyle: {
|
|
24
|
+
readonly overflow: "auto";
|
|
25
|
+
readonly display: "flex";
|
|
26
|
+
readonly marginTop: "8px";
|
|
27
|
+
readonly paddingBottom: "16px";
|
|
28
|
+
readonly position: "relative";
|
|
29
|
+
readonly width: "100%";
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { DynamicForm, dynamicFormManifest };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// src/DynamicForm.tsx
|
|
2
|
+
import { useState, useCallback } from "react";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
function DynamicForm(props) {
|
|
5
|
+
const { submitted, submittedValues, uiProps, onSubmit, onCancel } = props;
|
|
6
|
+
const title = uiProps.title;
|
|
7
|
+
const description = uiProps.description;
|
|
8
|
+
const fields = uiProps.fields || [];
|
|
9
|
+
const submitText = uiProps.submit_button_text || "Submit";
|
|
10
|
+
const cancelText = uiProps.cancel_button_text;
|
|
11
|
+
const [formValues, setFormValues] = useState(() => {
|
|
12
|
+
if (submittedValues) return submittedValues;
|
|
13
|
+
const initial = {};
|
|
14
|
+
fields.forEach((f) => {
|
|
15
|
+
initial[f.id] = f.default_value ?? "";
|
|
16
|
+
});
|
|
17
|
+
return initial;
|
|
18
|
+
});
|
|
19
|
+
const [isSubmitted, setIsSubmitted] = useState(submitted === true);
|
|
20
|
+
const handleChange = useCallback((fieldId, value) => {
|
|
21
|
+
setFormValues((prev) => ({ ...prev, [fieldId]: value }));
|
|
22
|
+
}, []);
|
|
23
|
+
const handleSubmit = useCallback(() => {
|
|
24
|
+
setIsSubmitted(true);
|
|
25
|
+
onSubmit(formValues, "Form submitted.");
|
|
26
|
+
}, [formValues, onSubmit]);
|
|
27
|
+
if (isSubmitted) {
|
|
28
|
+
return /* @__PURE__ */ jsx(
|
|
29
|
+
"div",
|
|
30
|
+
{
|
|
31
|
+
style: {
|
|
32
|
+
padding: "16px",
|
|
33
|
+
border: "1px solid #e5e7eb",
|
|
34
|
+
borderRadius: "8px",
|
|
35
|
+
fontFamily: "system-ui, sans-serif"
|
|
36
|
+
},
|
|
37
|
+
children: /* @__PURE__ */ jsxs("p", { style: { fontWeight: 600, color: "#16a34a" }, children: [
|
|
38
|
+
"\u2713 ",
|
|
39
|
+
title || "Form",
|
|
40
|
+
" submitted"
|
|
41
|
+
] })
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
return /* @__PURE__ */ jsxs(
|
|
46
|
+
"div",
|
|
47
|
+
{
|
|
48
|
+
style: {
|
|
49
|
+
padding: "16px",
|
|
50
|
+
border: "1px solid #e5e7eb",
|
|
51
|
+
borderRadius: "8px",
|
|
52
|
+
fontFamily: "system-ui, sans-serif",
|
|
53
|
+
width: "100%"
|
|
54
|
+
},
|
|
55
|
+
children: [
|
|
56
|
+
title && /* @__PURE__ */ jsx("h3", { style: { margin: "0 0 4px", fontSize: "16px" }, children: title }),
|
|
57
|
+
description && /* @__PURE__ */ jsx("p", { style: { margin: "0 0 12px", fontSize: "13px", color: "#666" }, children: description }),
|
|
58
|
+
fields.map((field) => /* @__PURE__ */ jsxs("div", { style: { marginBottom: "12px" }, children: [
|
|
59
|
+
field.label && /* @__PURE__ */ jsxs(
|
|
60
|
+
"label",
|
|
61
|
+
{
|
|
62
|
+
style: {
|
|
63
|
+
display: "block",
|
|
64
|
+
fontSize: "13px",
|
|
65
|
+
fontWeight: 500,
|
|
66
|
+
marginBottom: "4px"
|
|
67
|
+
},
|
|
68
|
+
children: [
|
|
69
|
+
field.label,
|
|
70
|
+
field.required && /* @__PURE__ */ jsx("span", { style: { color: "#ef4444" }, children: " *" })
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
),
|
|
74
|
+
field.type === "textarea" ? /* @__PURE__ */ jsx(
|
|
75
|
+
"textarea",
|
|
76
|
+
{
|
|
77
|
+
style: {
|
|
78
|
+
width: "100%",
|
|
79
|
+
padding: "8px",
|
|
80
|
+
border: "1px solid #d1d5db",
|
|
81
|
+
borderRadius: "6px",
|
|
82
|
+
fontSize: "14px",
|
|
83
|
+
resize: "vertical"
|
|
84
|
+
},
|
|
85
|
+
placeholder: field.placeholder,
|
|
86
|
+
value: formValues[field.id] || "",
|
|
87
|
+
onChange: (e) => handleChange(field.id, e.target.value)
|
|
88
|
+
}
|
|
89
|
+
) : field.type === "select" ? /* @__PURE__ */ jsxs(
|
|
90
|
+
"select",
|
|
91
|
+
{
|
|
92
|
+
style: {
|
|
93
|
+
width: "100%",
|
|
94
|
+
padding: "8px",
|
|
95
|
+
border: "1px solid #d1d5db",
|
|
96
|
+
borderRadius: "6px",
|
|
97
|
+
fontSize: "14px"
|
|
98
|
+
},
|
|
99
|
+
value: formValues[field.id] || "",
|
|
100
|
+
onChange: (e) => handleChange(field.id, e.target.value),
|
|
101
|
+
children: [
|
|
102
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Select..." }),
|
|
103
|
+
field.options?.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
) : /* @__PURE__ */ jsx(
|
|
107
|
+
"input",
|
|
108
|
+
{
|
|
109
|
+
style: {
|
|
110
|
+
width: "100%",
|
|
111
|
+
padding: "8px",
|
|
112
|
+
border: "1px solid #d1d5db",
|
|
113
|
+
borderRadius: "6px",
|
|
114
|
+
fontSize: "14px"
|
|
115
|
+
},
|
|
116
|
+
type: field.type === "number" ? "number" : "text",
|
|
117
|
+
placeholder: field.placeholder,
|
|
118
|
+
value: formValues[field.id] || "",
|
|
119
|
+
onChange: (e) => handleChange(field.id, e.target.value)
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
] }, field.id)),
|
|
123
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", marginTop: "16px" }, children: [
|
|
124
|
+
/* @__PURE__ */ jsx(
|
|
125
|
+
"button",
|
|
126
|
+
{
|
|
127
|
+
onClick: handleSubmit,
|
|
128
|
+
style: {
|
|
129
|
+
padding: "8px 16px",
|
|
130
|
+
background: "#111",
|
|
131
|
+
color: "#fff",
|
|
132
|
+
border: "none",
|
|
133
|
+
borderRadius: "6px",
|
|
134
|
+
cursor: "pointer",
|
|
135
|
+
fontSize: "14px",
|
|
136
|
+
fontWeight: 500
|
|
137
|
+
},
|
|
138
|
+
children: submitText
|
|
139
|
+
}
|
|
140
|
+
),
|
|
141
|
+
cancelText && /* @__PURE__ */ jsx(
|
|
142
|
+
"button",
|
|
143
|
+
{
|
|
144
|
+
onClick: onCancel,
|
|
145
|
+
style: {
|
|
146
|
+
padding: "8px 16px",
|
|
147
|
+
background: "transparent",
|
|
148
|
+
color: "#666",
|
|
149
|
+
border: "1px solid #d1d5db",
|
|
150
|
+
borderRadius: "6px",
|
|
151
|
+
cursor: "pointer",
|
|
152
|
+
fontSize: "14px"
|
|
153
|
+
},
|
|
154
|
+
children: cancelText
|
|
155
|
+
}
|
|
156
|
+
)
|
|
157
|
+
] })
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/manifest.ts
|
|
164
|
+
var dynamicFormManifest = {
|
|
165
|
+
name: "common:dynamic-form",
|
|
166
|
+
aliases: ["dynamic_form"],
|
|
167
|
+
service: "common",
|
|
168
|
+
description: "Server-driven dynamic form supporting text, textarea, number, select, multiselect, checkbox, radio, approval, todo_list, and file upload fields",
|
|
169
|
+
containerStyle: {
|
|
170
|
+
overflow: "auto",
|
|
171
|
+
display: "flex",
|
|
172
|
+
marginTop: "8px",
|
|
173
|
+
paddingBottom: "16px",
|
|
174
|
+
position: "relative",
|
|
175
|
+
width: "100%"
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
export {
|
|
179
|
+
DynamicForm,
|
|
180
|
+
dynamicFormManifest
|
|
181
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@streamoid/chat-components",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared chat UI components for the Streamoid chat host — DynamicForm and other cross-service components",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"prepublishOnly": "npm run build"
|
|
21
|
+
},
|
|
22
|
+
"peerDependencies": {
|
|
23
|
+
"react": "^18.0.0",
|
|
24
|
+
"react-dom": "^18.0.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@streamoid/chat-component-types": "^0.1.0",
|
|
28
|
+
"@types/react": "^18.0.0",
|
|
29
|
+
"@types/react-dom": "^18.0.0",
|
|
30
|
+
"tsup": "^8.0.0",
|
|
31
|
+
"typescript": "^5.0.0"
|
|
32
|
+
},
|
|
33
|
+
"license": "ISC",
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
}
|
|
37
|
+
}
|