@btst/stack 3.1.2 → 4.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 +2 -2
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.cjs +112 -103
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.mjs +112 -103
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.cjs +5 -2
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.mjs +5 -2
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.cjs +99 -88
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.mjs +99 -88
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-message.cjs +12 -3
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-message.mjs +12 -3
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.cjs +6 -2
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.mjs +6 -2
- package/dist/packages/stack/src/plugins/ai-chat/client/hooks/chat-hooks.cjs +5 -5
- package/dist/packages/stack/src/plugins/ai-chat/client/hooks/chat-hooks.mjs +5 -5
- package/dist/packages/stack/src/plugins/blog/client/components/shared/page-wrapper.cjs +3 -2
- package/dist/packages/stack/src/plugins/blog/client/components/shared/page-wrapper.mjs +3 -2
- package/dist/packages/stack/src/plugins/blog/client/components/shared/post-card.cjs +81 -52
- package/dist/packages/stack/src/plugins/blog/client/components/shared/post-card.mjs +82 -53
- package/dist/packages/stack/src/plugins/blog/client/components/shared/posts-list.cjs +3 -2
- package/dist/packages/stack/src/plugins/blog/client/components/shared/posts-list.mjs +3 -2
- package/dist/packages/stack/src/plugins/cms/client/components/pages/content-list-page.internal.cjs +95 -75
- package/dist/packages/stack/src/plugins/cms/client/components/pages/content-list-page.internal.mjs +95 -75
- package/dist/packages/stack/src/plugins/cms/client/components/pages/dashboard-page.internal.cjs +16 -3
- package/dist/packages/stack/src/plugins/cms/client/components/pages/dashboard-page.internal.mjs +16 -3
- package/dist/packages/stack/src/plugins/cms/client/components/shared/page-wrapper.cjs +3 -2
- package/dist/packages/stack/src/plugins/cms/client/components/shared/page-wrapper.mjs +3 -2
- package/dist/packages/stack/src/plugins/cms/utils.cjs +6 -2
- package/dist/packages/stack/src/plugins/cms/utils.mjs +6 -3
- package/dist/packages/stack/src/plugins/form-builder/client/components/forms/form-renderer.cjs +14 -8
- package/dist/packages/stack/src/plugins/form-builder/client/components/forms/form-renderer.mjs +14 -8
- package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.cjs +94 -87
- package/dist/packages/stack/src/plugins/form-builder/client/components/pages/form-list-page.internal.mjs +94 -87
- package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.cjs +81 -74
- package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +81 -74
- package/dist/packages/stack/src/plugins/form-builder/client/components/shared/page-wrapper.cjs +3 -2
- package/dist/packages/stack/src/plugins/form-builder/client/components/shared/page-wrapper.mjs +3 -2
- package/dist/packages/stack/src/plugins/form-builder/client/components/shared/pagination.cjs +25 -16
- package/dist/packages/stack/src/plugins/form-builder/client/components/shared/pagination.mjs +25 -16
- package/dist/packages/stack/src/plugins/form-builder/utils.cjs +6 -2
- package/dist/packages/stack/src/plugins/form-builder/utils.mjs +6 -3
- package/dist/packages/stack/src/plugins/kanban/api/getters.cjs +7 -5
- package/dist/packages/stack/src/plugins/kanban/api/getters.mjs +7 -5
- package/dist/packages/stack/src/plugins/media/client/hooks/use-media.cjs +10 -8
- package/dist/packages/stack/src/plugins/media/client/hooks/use-media.mjs +10 -8
- package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/index.d.cts +2 -2
- package/dist/plugins/ai-chat/client/index.d.mts +2 -2
- package/dist/plugins/ai-chat/client/index.d.ts +2 -2
- package/dist/plugins/blog/api/index.d.cts +2 -2
- package/dist/plugins/blog/api/index.d.mts +2 -2
- package/dist/plugins/blog/api/index.d.ts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
- package/dist/plugins/blog/client/index.d.cts +20 -2
- package/dist/plugins/blog/client/index.d.mts +20 -2
- package/dist/plugins/blog/client/index.d.ts +20 -2
- package/dist/plugins/blog/query-keys.d.cts +2 -2
- package/dist/plugins/blog/query-keys.d.mts +2 -2
- package/dist/plugins/blog/query-keys.d.ts +2 -2
- package/dist/plugins/cms/api/index.d.cts +1 -1
- package/dist/plugins/cms/api/index.d.mts +1 -1
- package/dist/plugins/cms/api/index.d.ts +1 -1
- package/dist/plugins/cms/client/index.d.cts +18 -0
- package/dist/plugins/cms/client/index.d.mts +18 -0
- package/dist/plugins/cms/client/index.d.ts +18 -0
- package/dist/plugins/cms/query-keys.d.cts +1 -1
- package/dist/plugins/cms/query-keys.d.mts +1 -1
- package/dist/plugins/cms/query-keys.d.ts +1 -1
- package/dist/plugins/form-builder/client/index.d.cts +16 -0
- package/dist/plugins/form-builder/client/index.d.mts +16 -0
- package/dist/plugins/form-builder/client/index.d.ts +16 -0
- package/dist/plugins/ui-builder/client/hooks/index.d.cts +1 -1
- package/dist/plugins/ui-builder/client/hooks/index.d.mts +1 -1
- package/dist/plugins/ui-builder/client/hooks/index.d.ts +1 -1
- package/dist/plugins/ui-builder/client/index.d.cts +1 -1
- package/dist/plugins/ui-builder/client/index.d.mts +1 -1
- package/dist/plugins/ui-builder/client/index.d.ts +1 -1
- package/dist/plugins/ui-builder/query-keys.d.cts +1 -1
- package/dist/plugins/ui-builder/query-keys.d.mts +1 -1
- package/dist/plugins/ui-builder/query-keys.d.ts +1 -1
- package/dist/shared/{stack.BTStHVTy.d.cts → stack.BGzgFx3R.d.cts} +5 -5
- package/dist/shared/{stack.CtrnoQgH.d.cts → stack.BOZRaVpu.d.cts} +35 -35
- package/dist/shared/{stack.94kN3pEK.d.mts → stack.CjCSDfWy.d.mts} +5 -5
- package/dist/shared/{stack.lPKwd_v0.d.ts → stack.DlBoNqYu.d.ts} +35 -35
- package/dist/shared/{stack.DfrRYOIl.d.ts → stack.Dpg_JjIo.d.ts} +5 -5
- package/dist/shared/{stack.BggTHKlo.d.mts → stack.Dvy7FmaA.d.mts} +35 -35
- package/dist/shared/{stack.5_zzCejP.d.cts → stack.rVF0f509.d.cts} +20 -0
- package/dist/shared/{stack.5_zzCejP.d.mts → stack.rVF0f509.d.mts} +20 -0
- package/dist/shared/{stack.5_zzCejP.d.ts → stack.rVF0f509.d.ts} +20 -0
- package/package.json +11 -7
- package/src/__tests__/package-metadata.test.ts +4 -4
- package/src/plugins/ai-chat/__tests__/classnames-overrides.test.tsx +248 -0
- package/src/plugins/ai-chat/__tests__/hooks.test.tsx +70 -54
- package/src/plugins/ai-chat/client/components/chat-input.tsx +6 -1
- package/src/plugins/ai-chat/client/components/chat-interface.tsx +3 -0
- package/src/plugins/ai-chat/client/components/chat-layout.tsx +9 -2
- package/src/plugins/ai-chat/client/components/chat-message.tsx +13 -5
- package/src/plugins/ai-chat/client/components/chat-sidebar.tsx +6 -2
- package/src/plugins/ai-chat/client/hooks/chat-hooks.tsx +6 -9
- package/src/plugins/ai-chat/client/overrides.ts +21 -0
- package/src/plugins/blog/__tests__/classnames-overrides.test.tsx +206 -0
- package/src/plugins/blog/client/components/shared/page-wrapper.tsx +3 -2
- package/src/plugins/blog/client/components/shared/post-card.tsx +32 -12
- package/src/plugins/blog/client/components/shared/posts-list.tsx +3 -2
- package/src/plugins/blog/client/overrides.ts +18 -0
- package/src/plugins/cms/__tests__/classnames-overrides.test.tsx +200 -0
- package/src/plugins/cms/client/components/pages/content-list-page.internal.tsx +17 -4
- package/src/plugins/cms/client/components/pages/dashboard-page.internal.tsx +14 -3
- package/src/plugins/cms/client/components/shared/page-wrapper.tsx +3 -2
- package/src/plugins/cms/client/overrides.ts +19 -0
- package/src/plugins/form-builder/__tests__/classnames-overrides.test.tsx +312 -0
- package/src/plugins/form-builder/client/components/forms/form-renderer.tsx +14 -9
- package/src/plugins/form-builder/client/components/pages/form-list-page.internal.tsx +9 -5
- package/src/plugins/form-builder/client/components/pages/submissions-page.internal.tsx +9 -5
- package/src/plugins/form-builder/client/components/shared/page-wrapper.tsx +3 -2
- package/src/plugins/form-builder/client/components/shared/pagination.tsx +7 -1
- package/src/plugins/form-builder/client/overrides.ts +17 -0
- package/src/plugins/kanban/__tests__/getters.test.ts +14 -1
- package/src/plugins/kanban/api/getters.ts +9 -7
- package/src/plugins/kanban/types.ts +4 -6
- package/src/plugins/media/client/hooks/use-media.tsx +7 -8
- package/dist/shared/{stack.lsbdKRj7.d.mts → stack.B8PG21zX.d.mts} +16 -16
- package/dist/shared/{stack.CKc_Bais.d.cts → stack.Csi-4Mgz.d.cts} +7 -7
- package/dist/shared/{stack.CKc_Bais.d.mts → stack.Csi-4Mgz.d.mts} +7 -7
- package/dist/shared/{stack.CKc_Bais.d.ts → stack.Csi-4Mgz.d.ts} +7 -7
- package/dist/shared/{stack.BMlTZnZp.d.ts → stack.CyalJ0j6.d.ts} +16 -16
- package/dist/shared/{stack.BV0uNV4f.d.cts → stack.D6Pg-ufX.d.cts} +16 -16
package/README.md
CHANGED
|
@@ -52,13 +52,13 @@ Render the generated `<Toaster />` in your root layout and start from a clean co
|
|
|
52
52
|
Run the released generator from the application root:
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
|
-
pnpm dlx @btst/codegen@
|
|
55
|
+
pnpm dlx @btst/codegen@4.1.0 init \
|
|
56
56
|
--framework nextjs \
|
|
57
57
|
--adapter memory \
|
|
58
58
|
--plugins blog
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
The generator shows detected-file and conflict prompts before it writes. It installs `@btst/stack@
|
|
61
|
+
The generator shows detected-file and conflict prompts before it writes. It installs `@btst/stack@4.1.0`, `next-themes@0.4.6`, registers Blog on the backend and client, mounts the API and page routes, adds the plugin CSS, and wires the shared provider.
|
|
62
62
|
|
|
63
63
|
Set the trusted local origins in `.env.local`:
|
|
64
64
|
|
|
@@ -43,7 +43,8 @@ function ChatInput({
|
|
|
43
43
|
const {
|
|
44
44
|
uploadFile,
|
|
45
45
|
localization: customLocalization,
|
|
46
|
-
allowedFileTypes
|
|
46
|
+
allowedFileTypes,
|
|
47
|
+
classNames
|
|
47
48
|
} = context.usePluginOverrides(
|
|
48
49
|
"aiChat",
|
|
49
50
|
{}
|
|
@@ -217,113 +218,121 @@ function ChatInput({
|
|
|
217
218
|
)
|
|
218
219
|
}
|
|
219
220
|
),
|
|
220
|
-
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
221
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
222
|
+
"form",
|
|
223
|
+
{
|
|
224
|
+
onSubmit: handleFormSubmit,
|
|
225
|
+
className: utils.cn("space-y-2", classNames?.input),
|
|
226
|
+
"data-testid": "chat-input-form",
|
|
227
|
+
children: [
|
|
228
|
+
attachedFiles.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-2", children: attachedFiles.map((file, index) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
229
|
+
"div",
|
|
230
|
+
{
|
|
231
|
+
className: "relative group rounded-lg overflow-hidden border",
|
|
232
|
+
children: [
|
|
233
|
+
isImageFile(file.mediaType) ? (
|
|
234
|
+
// Image preview
|
|
235
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
236
|
+
"img",
|
|
237
|
+
{
|
|
238
|
+
src: file.url,
|
|
239
|
+
alt: file.filename,
|
|
240
|
+
className: "h-16 w-16 object-cover"
|
|
241
|
+
}
|
|
242
|
+
)
|
|
243
|
+
) : (
|
|
244
|
+
// File preview with icon
|
|
245
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-32 flex items-center gap-2 p-2 bg-muted", children: [
|
|
246
|
+
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.FileText, { className: "h-5 w-5 shrink-0 text-muted-foreground" }),
|
|
247
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs truncate", title: file.filename, children: file.filename })
|
|
248
|
+
] })
|
|
249
|
+
),
|
|
250
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
251
|
+
"button",
|
|
252
|
+
{
|
|
253
|
+
type: "button",
|
|
254
|
+
onClick: () => removeFile(index),
|
|
255
|
+
className: "absolute top-0.5 right-0.5 p-0.5 rounded-full bg-background/80 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
256
|
+
"aria-label": tr(
|
|
257
|
+
"FILE_REMOVE",
|
|
258
|
+
"aiChat.files.remove",
|
|
259
|
+
"Remove file"
|
|
260
|
+
),
|
|
261
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.X, { className: "h-3 w-3" })
|
|
262
|
+
}
|
|
263
|
+
)
|
|
264
|
+
]
|
|
265
|
+
},
|
|
266
|
+
index
|
|
267
|
+
)) }),
|
|
268
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center gap-2", children: [
|
|
269
|
+
canUploadFiles && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
228
270
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
229
|
-
"
|
|
271
|
+
"input",
|
|
230
272
|
{
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
273
|
+
ref: fileInputRef,
|
|
274
|
+
type: "file",
|
|
275
|
+
accept: acceptString,
|
|
276
|
+
onChange: handleFileUpload,
|
|
277
|
+
className: "hidden"
|
|
234
278
|
}
|
|
235
|
-
)
|
|
236
|
-
) : (
|
|
237
|
-
// File preview with icon
|
|
238
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-32 flex items-center gap-2 p-2 bg-muted", children: [
|
|
239
|
-
/* @__PURE__ */ jsxRuntime.jsx(LucideIcons.FileText, { className: "h-5 w-5 shrink-0 text-muted-foreground" }),
|
|
240
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs truncate", title: file.filename, children: file.filename })
|
|
241
|
-
] })
|
|
242
|
-
),
|
|
243
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
244
|
-
"button",
|
|
245
|
-
{
|
|
246
|
-
type: "button",
|
|
247
|
-
onClick: () => removeFile(index),
|
|
248
|
-
className: "absolute top-0.5 right-0.5 p-0.5 rounded-full bg-background/80 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
249
|
-
"aria-label": tr(
|
|
250
|
-
"FILE_REMOVE",
|
|
251
|
-
"aiChat.files.remove",
|
|
252
|
-
"Remove file"
|
|
253
|
-
),
|
|
254
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.X, { className: "h-3 w-3" })
|
|
255
|
-
}
|
|
256
|
-
)
|
|
257
|
-
]
|
|
258
|
-
},
|
|
259
|
-
index
|
|
260
|
-
)) }),
|
|
261
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center gap-2", children: [
|
|
262
|
-
canUploadFiles && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
263
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
264
|
-
"input",
|
|
265
|
-
{
|
|
266
|
-
ref: fileInputRef,
|
|
267
|
-
type: "file",
|
|
268
|
-
accept: acceptString,
|
|
269
|
-
onChange: handleFileUpload,
|
|
270
|
-
className: "hidden"
|
|
271
|
-
}
|
|
272
|
-
),
|
|
273
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
274
|
-
button.Button,
|
|
275
|
-
{
|
|
276
|
-
type: "button",
|
|
277
|
-
variant: "ghost",
|
|
278
|
-
size: "icon",
|
|
279
|
-
onClick: () => fileInputRef.current?.click(),
|
|
280
|
-
disabled: isLoading || isUploading,
|
|
281
|
-
className: utils.cn("shrink-0", isCompact ? "h-8 w-8" : "h-9 w-9"),
|
|
282
|
-
"aria-label": tr(
|
|
283
|
-
"FILE_UPLOAD_BUTTON",
|
|
284
|
-
"aiChat.files.attach",
|
|
285
|
-
"Attach file"
|
|
286
279
|
),
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
280
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
281
|
+
button.Button,
|
|
282
|
+
{
|
|
283
|
+
type: "button",
|
|
284
|
+
variant: "ghost",
|
|
285
|
+
size: "icon",
|
|
286
|
+
onClick: () => fileInputRef.current?.click(),
|
|
287
|
+
disabled: isLoading || isUploading,
|
|
288
|
+
className: utils.cn("shrink-0", isCompact ? "h-8 w-8" : "h-9 w-9"),
|
|
289
|
+
"aria-label": tr(
|
|
290
|
+
"FILE_UPLOAD_BUTTON",
|
|
291
|
+
"aiChat.files.attach",
|
|
292
|
+
"Attach file"
|
|
293
|
+
),
|
|
294
|
+
children: isUploading ? /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Paperclip, { className: "h-4 w-4" })
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
] }),
|
|
298
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 min-w-0", children: [
|
|
299
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
300
|
+
textarea.Textarea,
|
|
301
|
+
{
|
|
302
|
+
value: input,
|
|
303
|
+
onChange: handleInputChange,
|
|
304
|
+
onKeyDown: handleKeyDown,
|
|
305
|
+
placeholder: placeholder || tr(
|
|
306
|
+
"CHAT_PLACEHOLDER",
|
|
307
|
+
"aiChat.chat.placeholder",
|
|
308
|
+
"Type a message..."
|
|
309
|
+
),
|
|
310
|
+
className: utils.cn(
|
|
311
|
+
"resize-none pr-12 max-w-full",
|
|
312
|
+
isCompact ? "min-h-[40px] max-h-[120px] py-2" : "min-h-[50px] max-h-[200px] py-3"
|
|
313
|
+
),
|
|
314
|
+
rows: 1
|
|
315
|
+
}
|
|
319
316
|
),
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
317
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
318
|
+
button.Button,
|
|
319
|
+
{
|
|
320
|
+
type: "submit",
|
|
321
|
+
size: "icon",
|
|
322
|
+
disabled: isLoading || !input?.trim() && attachedFiles.length === 0,
|
|
323
|
+
className: utils.cn(
|
|
324
|
+
"absolute right-2 bottom-2",
|
|
325
|
+
isCompact ? "h-7 w-7" : "h-8 w-8"
|
|
326
|
+
),
|
|
327
|
+
"aria-label": tr("CHAT_SEND_BUTTON", "aiChat.chat.send", "Send"),
|
|
328
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Send, { className: utils.cn(isCompact ? "h-3.5 w-3.5" : "h-4 w-4") })
|
|
329
|
+
}
|
|
330
|
+
)
|
|
331
|
+
] })
|
|
332
|
+
] })
|
|
333
|
+
]
|
|
334
|
+
}
|
|
335
|
+
)
|
|
327
336
|
] });
|
|
328
337
|
}
|
|
329
338
|
|
|
@@ -41,7 +41,8 @@ function ChatInput({
|
|
|
41
41
|
const {
|
|
42
42
|
uploadFile,
|
|
43
43
|
localization: customLocalization,
|
|
44
|
-
allowedFileTypes
|
|
44
|
+
allowedFileTypes,
|
|
45
|
+
classNames
|
|
45
46
|
} = usePluginOverrides(
|
|
46
47
|
"aiChat",
|
|
47
48
|
{}
|
|
@@ -215,113 +216,121 @@ function ChatInput({
|
|
|
215
216
|
)
|
|
216
217
|
}
|
|
217
218
|
),
|
|
218
|
-
/* @__PURE__ */ jsxs(
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
219
|
+
/* @__PURE__ */ jsxs(
|
|
220
|
+
"form",
|
|
221
|
+
{
|
|
222
|
+
onSubmit: handleFormSubmit,
|
|
223
|
+
className: cn("space-y-2", classNames?.input),
|
|
224
|
+
"data-testid": "chat-input-form",
|
|
225
|
+
children: [
|
|
226
|
+
attachedFiles.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: attachedFiles.map((file, index) => /* @__PURE__ */ jsxs(
|
|
227
|
+
"div",
|
|
228
|
+
{
|
|
229
|
+
className: "relative group rounded-lg overflow-hidden border",
|
|
230
|
+
children: [
|
|
231
|
+
isImageFile(file.mediaType) ? (
|
|
232
|
+
// Image preview
|
|
233
|
+
/* @__PURE__ */ jsx(
|
|
234
|
+
"img",
|
|
235
|
+
{
|
|
236
|
+
src: file.url,
|
|
237
|
+
alt: file.filename,
|
|
238
|
+
className: "h-16 w-16 object-cover"
|
|
239
|
+
}
|
|
240
|
+
)
|
|
241
|
+
) : (
|
|
242
|
+
// File preview with icon
|
|
243
|
+
/* @__PURE__ */ jsxs("div", { className: "w-32 flex items-center gap-2 p-2 bg-muted", children: [
|
|
244
|
+
/* @__PURE__ */ jsx(FileText, { className: "h-5 w-5 shrink-0 text-muted-foreground" }),
|
|
245
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs truncate", title: file.filename, children: file.filename })
|
|
246
|
+
] })
|
|
247
|
+
),
|
|
248
|
+
/* @__PURE__ */ jsx(
|
|
249
|
+
"button",
|
|
250
|
+
{
|
|
251
|
+
type: "button",
|
|
252
|
+
onClick: () => removeFile(index),
|
|
253
|
+
className: "absolute top-0.5 right-0.5 p-0.5 rounded-full bg-background/80 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
254
|
+
"aria-label": tr(
|
|
255
|
+
"FILE_REMOVE",
|
|
256
|
+
"aiChat.files.remove",
|
|
257
|
+
"Remove file"
|
|
258
|
+
),
|
|
259
|
+
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
260
|
+
}
|
|
261
|
+
)
|
|
262
|
+
]
|
|
263
|
+
},
|
|
264
|
+
index
|
|
265
|
+
)) }),
|
|
266
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex items-center gap-2", children: [
|
|
267
|
+
canUploadFiles && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
226
268
|
/* @__PURE__ */ jsx(
|
|
227
|
-
"
|
|
269
|
+
"input",
|
|
228
270
|
{
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
271
|
+
ref: fileInputRef,
|
|
272
|
+
type: "file",
|
|
273
|
+
accept: acceptString,
|
|
274
|
+
onChange: handleFileUpload,
|
|
275
|
+
className: "hidden"
|
|
232
276
|
}
|
|
233
|
-
)
|
|
234
|
-
) : (
|
|
235
|
-
// File preview with icon
|
|
236
|
-
/* @__PURE__ */ jsxs("div", { className: "w-32 flex items-center gap-2 p-2 bg-muted", children: [
|
|
237
|
-
/* @__PURE__ */ jsx(FileText, { className: "h-5 w-5 shrink-0 text-muted-foreground" }),
|
|
238
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs truncate", title: file.filename, children: file.filename })
|
|
239
|
-
] })
|
|
240
|
-
),
|
|
241
|
-
/* @__PURE__ */ jsx(
|
|
242
|
-
"button",
|
|
243
|
-
{
|
|
244
|
-
type: "button",
|
|
245
|
-
onClick: () => removeFile(index),
|
|
246
|
-
className: "absolute top-0.5 right-0.5 p-0.5 rounded-full bg-background/80 opacity-0 group-hover:opacity-100 transition-opacity",
|
|
247
|
-
"aria-label": tr(
|
|
248
|
-
"FILE_REMOVE",
|
|
249
|
-
"aiChat.files.remove",
|
|
250
|
-
"Remove file"
|
|
251
|
-
),
|
|
252
|
-
children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" })
|
|
253
|
-
}
|
|
254
|
-
)
|
|
255
|
-
]
|
|
256
|
-
},
|
|
257
|
-
index
|
|
258
|
-
)) }),
|
|
259
|
-
/* @__PURE__ */ jsxs("div", { className: "relative flex items-center gap-2", children: [
|
|
260
|
-
canUploadFiles && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
261
|
-
/* @__PURE__ */ jsx(
|
|
262
|
-
"input",
|
|
263
|
-
{
|
|
264
|
-
ref: fileInputRef,
|
|
265
|
-
type: "file",
|
|
266
|
-
accept: acceptString,
|
|
267
|
-
onChange: handleFileUpload,
|
|
268
|
-
className: "hidden"
|
|
269
|
-
}
|
|
270
|
-
),
|
|
271
|
-
/* @__PURE__ */ jsx(
|
|
272
|
-
Button,
|
|
273
|
-
{
|
|
274
|
-
type: "button",
|
|
275
|
-
variant: "ghost",
|
|
276
|
-
size: "icon",
|
|
277
|
-
onClick: () => fileInputRef.current?.click(),
|
|
278
|
-
disabled: isLoading || isUploading,
|
|
279
|
-
className: cn("shrink-0", isCompact ? "h-8 w-8" : "h-9 w-9"),
|
|
280
|
-
"aria-label": tr(
|
|
281
|
-
"FILE_UPLOAD_BUTTON",
|
|
282
|
-
"aiChat.files.attach",
|
|
283
|
-
"Attach file"
|
|
284
277
|
),
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
278
|
+
/* @__PURE__ */ jsx(
|
|
279
|
+
Button,
|
|
280
|
+
{
|
|
281
|
+
type: "button",
|
|
282
|
+
variant: "ghost",
|
|
283
|
+
size: "icon",
|
|
284
|
+
onClick: () => fileInputRef.current?.click(),
|
|
285
|
+
disabled: isLoading || isUploading,
|
|
286
|
+
className: cn("shrink-0", isCompact ? "h-8 w-8" : "h-9 w-9"),
|
|
287
|
+
"aria-label": tr(
|
|
288
|
+
"FILE_UPLOAD_BUTTON",
|
|
289
|
+
"aiChat.files.attach",
|
|
290
|
+
"Attach file"
|
|
291
|
+
),
|
|
292
|
+
children: isUploading ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(Paperclip, { className: "h-4 w-4" })
|
|
293
|
+
}
|
|
294
|
+
)
|
|
295
|
+
] }),
|
|
296
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex-1 min-w-0", children: [
|
|
297
|
+
/* @__PURE__ */ jsx(
|
|
298
|
+
Textarea,
|
|
299
|
+
{
|
|
300
|
+
value: input,
|
|
301
|
+
onChange: handleInputChange,
|
|
302
|
+
onKeyDown: handleKeyDown,
|
|
303
|
+
placeholder: placeholder || tr(
|
|
304
|
+
"CHAT_PLACEHOLDER",
|
|
305
|
+
"aiChat.chat.placeholder",
|
|
306
|
+
"Type a message..."
|
|
307
|
+
),
|
|
308
|
+
className: cn(
|
|
309
|
+
"resize-none pr-12 max-w-full",
|
|
310
|
+
isCompact ? "min-h-[40px] max-h-[120px] py-2" : "min-h-[50px] max-h-[200px] py-3"
|
|
311
|
+
),
|
|
312
|
+
rows: 1
|
|
313
|
+
}
|
|
317
314
|
),
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
315
|
+
/* @__PURE__ */ jsx(
|
|
316
|
+
Button,
|
|
317
|
+
{
|
|
318
|
+
type: "submit",
|
|
319
|
+
size: "icon",
|
|
320
|
+
disabled: isLoading || !input?.trim() && attachedFiles.length === 0,
|
|
321
|
+
className: cn(
|
|
322
|
+
"absolute right-2 bottom-2",
|
|
323
|
+
isCompact ? "h-7 w-7" : "h-8 w-8"
|
|
324
|
+
),
|
|
325
|
+
"aria-label": tr("CHAT_SEND_BUTTON", "aiChat.chat.send", "Send"),
|
|
326
|
+
children: /* @__PURE__ */ jsx(Send, { className: cn(isCompact ? "h-3.5 w-3.5" : "h-4 w-4") })
|
|
327
|
+
}
|
|
328
|
+
)
|
|
329
|
+
] })
|
|
330
|
+
] })
|
|
331
|
+
]
|
|
332
|
+
}
|
|
333
|
+
)
|
|
325
334
|
] });
|
|
326
335
|
}
|
|
327
336
|
|
|
@@ -163,7 +163,8 @@ function ChatInterface({
|
|
|
163
163
|
const {
|
|
164
164
|
localization: customLocalization,
|
|
165
165
|
showAttribution,
|
|
166
|
-
chatSuggestions
|
|
166
|
+
chatSuggestions,
|
|
167
|
+
classNames
|
|
167
168
|
} = context.usePluginOverrides(
|
|
168
169
|
"aiChat",
|
|
169
170
|
{ showAttribution: true }
|
|
@@ -797,8 +798,10 @@ function ChatInterface({
|
|
|
797
798
|
{
|
|
798
799
|
className: utils.cn(
|
|
799
800
|
"flex flex-col p-4",
|
|
800
|
-
isWidget ? "max-w-full" : "max-w-3xl mx-auto w-full"
|
|
801
|
+
isWidget ? "max-w-full" : "max-w-3xl mx-auto w-full",
|
|
802
|
+
classNames?.messageList
|
|
801
803
|
),
|
|
804
|
+
"data-testid": "chat-message-list",
|
|
802
805
|
children: [
|
|
803
806
|
messages.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col h-full min-h-[300px]", children: [
|
|
804
807
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-center text-muted-foreground mb-4", children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: tr(
|
|
@@ -161,7 +161,8 @@ function ChatInterface({
|
|
|
161
161
|
const {
|
|
162
162
|
localization: customLocalization,
|
|
163
163
|
showAttribution,
|
|
164
|
-
chatSuggestions
|
|
164
|
+
chatSuggestions,
|
|
165
|
+
classNames
|
|
165
166
|
} = usePluginOverrides(
|
|
166
167
|
"aiChat",
|
|
167
168
|
{ showAttribution: true }
|
|
@@ -795,8 +796,10 @@ function ChatInterface({
|
|
|
795
796
|
{
|
|
796
797
|
className: cn(
|
|
797
798
|
"flex flex-col p-4",
|
|
798
|
-
isWidget ? "max-w-full" : "max-w-3xl mx-auto w-full"
|
|
799
|
+
isWidget ? "max-w-full" : "max-w-3xl mx-auto w-full",
|
|
800
|
+
classNames?.messageList
|
|
799
801
|
),
|
|
802
|
+
"data-testid": "chat-message-list",
|
|
800
803
|
children: [
|
|
801
804
|
messages.length === 0 ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full min-h-[300px]", children: [
|
|
802
805
|
/* @__PURE__ */ jsx("div", { className: "flex-1 flex items-center justify-center text-muted-foreground mb-4", children: /* @__PURE__ */ jsx("p", { children: tr(
|