@admin-layout/tailwind-chat-pro 12.2.4-alpha.76

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/lib/components/index.d.ts +2 -0
  4. package/lib/components/index.d.ts.map +1 -0
  5. package/lib/components/messages-container-ui/DefaultInputToolBar.d.ts +21 -0
  6. package/lib/components/messages-container-ui/DefaultInputToolBar.d.ts.map +1 -0
  7. package/lib/components/messages-container-ui/DefaultInputToolBar.js +46 -0
  8. package/lib/components/messages-container-ui/DefaultInputToolBar.js.map +1 -0
  9. package/lib/components/messages-container-ui/DefaultMessageGroup.d.ts +16 -0
  10. package/lib/components/messages-container-ui/DefaultMessageGroup.d.ts.map +1 -0
  11. package/lib/components/messages-container-ui/DefaultMessageGroup.js +64 -0
  12. package/lib/components/messages-container-ui/DefaultMessageGroup.js.map +1 -0
  13. package/lib/components/messages-container-ui/MessagesContainerUI.d.ts +98 -0
  14. package/lib/components/messages-container-ui/MessagesContainerUI.d.ts.map +1 -0
  15. package/lib/components/messages-container-ui/MessagesContainerUI.js +88 -0
  16. package/lib/components/messages-container-ui/MessagesContainerUI.js.map +1 -0
  17. package/lib/components/messages-container-ui/PlanModeView.d.ts +107 -0
  18. package/lib/components/messages-container-ui/PlanModeView.d.ts.map +1 -0
  19. package/lib/components/messages-container-ui/PlanModeView.js +294 -0
  20. package/lib/components/messages-container-ui/PlanModeView.js.map +1 -0
  21. package/lib/components/messages-container-ui/index.d.ts +9 -0
  22. package/lib/components/messages-container-ui/index.d.ts.map +1 -0
  23. package/lib/components/messages-container-ui/types.d.ts +63 -0
  24. package/lib/components/messages-container-ui/types.d.ts.map +1 -0
  25. package/lib/index.d.ts +2 -0
  26. package/lib/index.d.ts.map +1 -0
  27. package/lib/index.js +1 -0
  28. package/lib/index.js.map +1 -0
  29. package/lib/routes.json +1 -0
  30. package/package.json +42 -0
  31. package/rollup.config.mjs +34 -0
  32. package/src/components/index.ts +1 -0
  33. package/src/components/messages-container-ui/DefaultInputToolBar.tsx +63 -0
  34. package/src/components/messages-container-ui/DefaultMessageGroup.tsx +75 -0
  35. package/src/components/messages-container-ui/MessagesContainerUI.tsx +178 -0
  36. package/src/components/messages-container-ui/PlanModeView.tsx +457 -0
  37. package/src/components/messages-container-ui/index.ts +8 -0
  38. package/src/components/messages-container-ui/types.ts +68 -0
  39. package/src/index.ts +1 -0
  40. package/tsconfig.json +27 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,19 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [12.2.4-alpha.76](https://github.com/CDEBase/admin-layout/compare/v12.2.4-alpha.75...v12.2.4-alpha.76) (2026-06-27)
7
+
8
+ **Note:** Version bump only for package @admin-layout/tailwind-chat-pro
9
+
10
+ ## [12.2.4-alpha.75](https://github.com/CDEBase/admin-layout/compare/v12.2.4-alpha.74...v12.2.4-alpha.75) (2026-06-27)
11
+
12
+ **Note:** Version bump only for package @admin-layout/tailwind-chat-pro
13
+
14
+ ## [12.2.4-alpha.74](https://github.com/CDEBase/admin-layout/compare/v12.2.4-alpha.73...v12.2.4-alpha.74) (2026-06-27)
15
+
16
+ ### Features
17
+
18
+ - **tailwind-chat-pro:** customizable base MessagesContainerUI ([a4bc1b3](https://github.com/CDEBase/admin-layout/commit/a4bc1b38152d27adbb6ece4a50c70b8a6829b5c9))
19
+ - **tailwind-chat-pro:** default input toolbar to @admin-layout/tailwind-ui InputToolBar ([b9e9ab8](https://github.com/CDEBase/admin-layout/commit/b9e9ab846786d0f370db9ca98c0c16aa1a201d13))
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2017 CDMBase LLC.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,2 @@
1
+ export * from './messages-container-ui';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import type { PlanModeViewInputToolbarProps } from './types';
3
+ export interface DefaultInputToolBarProps extends PlanModeViewInputToolbarProps {
4
+ placeholder?: string;
5
+ /** When true, the send button shows a stop affordance (wired to onStop). */
6
+ isLoading?: boolean;
7
+ onStop?: () => void;
8
+ className?: string;
9
+ }
10
+ /**
11
+ * DefaultInputToolBar — the input composer used when no `renderInputToolbar` is
12
+ * provided. It wraps `@admin-layout/tailwind-ui`'s `InputToolBar` (the shared
13
+ * "ai-tool-box") wired to the base's toolbar props: a built-in textarea
14
+ * (Enter sends, Shift+Enter newlines) plus the mic/send/stop button.
15
+ *
16
+ * Consumers that need the richer composer (mode switcher, templates, attachments,
17
+ * project settings, …) pass their own `renderInputToolbar` instead.
18
+ */
19
+ export declare const DefaultInputToolBar: React.FC<DefaultInputToolBarProps>;
20
+ export default DefaultInputToolBar;
21
+ //# sourceMappingURL=DefaultInputToolBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultInputToolBar.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/DefaultInputToolBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,SAAS,CAAC;AAE7D,MAAM,WAAW,wBAAyB,SAAQ,6BAA6B;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAuClE,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,46 @@
1
+ import {jsx}from'react/jsx-runtime';import {InputToolBar}from'@admin-layout/tailwind-ui';/**
2
+ * DefaultInputToolBar — the input composer used when no `renderInputToolbar` is
3
+ * provided. It wraps `@admin-layout/tailwind-ui`'s `InputToolBar` (the shared
4
+ * "ai-tool-box") wired to the base's toolbar props: a built-in textarea
5
+ * (Enter sends, Shift+Enter newlines) plus the mic/send/stop button.
6
+ *
7
+ * Consumers that need the richer composer (mode switcher, templates, attachments,
8
+ * project settings, …) pass their own `renderInputToolbar` instead.
9
+ */
10
+ const DefaultInputToolBar = ({
11
+ value,
12
+ onChange,
13
+ onSend,
14
+ disabled = false,
15
+ placeholder = 'Message',
16
+ isLoading = false,
17
+ onStop,
18
+ className
19
+ }) => {
20
+ const hasContent = value.trim().length > 0;
21
+ return jsx(InputToolBar, {
22
+ className: className,
23
+ inputConfig: {
24
+ value,
25
+ onChange: e => onChange(e.target.value),
26
+ placeholder,
27
+ disabled,
28
+ onKeyDown: e => {
29
+ if (e.key === 'Enter' && !e.shiftKey) {
30
+ e.preventDefault();
31
+ if (hasContent && !disabled && !isLoading) onSend();
32
+ }
33
+ }
34
+ },
35
+ micSendButton: {
36
+ hasContent,
37
+ onSend,
38
+ onMic: () => {
39
+ /* voice input not wired in the base default */
40
+ },
41
+ disabled,
42
+ isLoading,
43
+ onStop: isLoading ? onStop : undefined
44
+ }
45
+ });
46
+ };export{DefaultInputToolBar};//# sourceMappingURL=DefaultInputToolBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultInputToolBar.js","sources":["../../../src/components/messages-container-ui/DefaultInputToolBar.tsx"],"sourcesContent":[null],"names":["_jsx"],"mappings":"yFAYA;;;;;;;;AAQG;AACI,MAAM,mBAAmB,GAAuC,CAAC;OAUpE;UAEA;;AAKY,EAAA,QAAA,GAAA,KAAA;aACA,GAAA,SAAW;cACX,KAAA;AACA,EAAA,MAAA;;;AAGQ,EAAA,MAAA,UAAA,GAAA,aAAc,MAAK,GAAA,CAAA;AAAwB,EAAA,OAAAA,GAAA,CAAA,YAAA,EAAA;wBAC9C;eACJ,EAAA;AACJ,MAAA,KACD;cACI,EAAA,CAAA,IAAA,QAAU,CAAA,CAAA,CAAA,MAAA,CAAA,KAAA,CAAA;iBACV;cACA;iBACI,CAAA,IAAA;YACJ,CAAC,CAAA,GAAA,KAAA,OAAA,IAAA,CAAA,CAAA,CAAA,QAAA,EAAA;YACD,cAAQ,EAAA;cACR,UAAS,IAAA,CAAA,QAAA,IAAA,CAAA,SAAA,EAAA,MAAA,EAAA;;AAEZ,MAAA;AAGb,KAAE;AAEF,IAAA;;;;;;;;;;;"}
@@ -0,0 +1,16 @@
1
+ import React from 'react';
2
+ import type { MessageGroupRenderProps } from './types';
3
+ /**
4
+ * DefaultMessageGroup — the base renderer used when no `MessageGroupComponent`
5
+ * is injected. Renders the post's text in a left/right aligned bubble with an
6
+ * optional author name, avatar and timestamp. Whitespace is preserved so
7
+ * plain-text replies read naturally.
8
+ *
9
+ * Consumers that need rich rendering (markdown, code blocks, media/travel/
10
+ * workflow widget cards, …) inject their own component via
11
+ * `MessagesContainerUI`'s `MessageGroupComponent` prop — e.g. messenger-box's
12
+ * `ModernMessageGroupComponent`.
13
+ */
14
+ export declare const DefaultMessageGroup: React.FC<MessageGroupRenderProps>;
15
+ export default DefaultMessageGroup;
16
+ //# sourceMappingURL=DefaultMessageGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultMessageGroup.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/DefaultMessageGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAMvD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAqDjE,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,64 @@
1
+ import {jsx,jsxs}from'react/jsx-runtime';import clsx from'clsx';const ASSISTANT_BUBBLE_BG = 'bg-white';
2
+ const USER_BUBBLE_BG = 'bg-indigo-50';
3
+ const BORDER_COLOR = 'border-gray-200';
4
+ /**
5
+ * DefaultMessageGroup — the base renderer used when no `MessageGroupComponent`
6
+ * is injected. Renders the post's text in a left/right aligned bubble with an
7
+ * optional author name, avatar and timestamp. Whitespace is preserved so
8
+ * plain-text replies read naturally.
9
+ *
10
+ * Consumers that need rich rendering (markdown, code blocks, media/travel/
11
+ * workflow widget cards, …) inject their own component via
12
+ * `MessagesContainerUI`'s `MessageGroupComponent` prop — e.g. messenger-box's
13
+ * `ModernMessageGroupComponent`.
14
+ */
15
+ const DefaultMessageGroup = ({
16
+ messages,
17
+ onMessageClick,
18
+ showAuthorName = false,
19
+ showAvatar = false,
20
+ showTimestamp = false
21
+ }) => {
22
+ const post = messages?.[0];
23
+ if (!post) return null;
24
+ const role = post?.propsConfiguration?.contents?.role;
25
+ const isUser = role === 'USER' || role === 'user' || post?.author?.isCurrentUser === true;
26
+ const text = typeof post?.message === 'string' ? post.message : '';
27
+ const author = post?.author ?? {};
28
+ const name = author.fullName || author.givenName || author.username || (isUser ? 'You' : 'Assistant');
29
+ const picture = author.picture ?? null;
30
+ const created = post?.createdAt ? new Date(post.createdAt) : null;
31
+ const timeLabel = created && !Number.isNaN(created.getTime()) ? created.toLocaleTimeString() : '';
32
+ return jsx("div", {
33
+ className: clsx('flex w-full', isUser ? 'justify-end' : 'justify-start'),
34
+ children: jsxs("div", {
35
+ className: clsx('flex max-w-[85%] gap-2', isUser ? 'flex-row-reverse' : 'flex-row'),
36
+ children: [showAvatar && jsx("div", {
37
+ className: "flex-shrink-0",
38
+ children: picture ?
39
+ // eslint-disable-next-line @next/next/no-img-element
40
+ jsx("img", {
41
+ src: picture,
42
+ alt: name,
43
+ className: "w-7 h-7 rounded-full object-cover"
44
+ }) : jsx("div", {
45
+ className: "w-7 h-7 rounded-full bg-gray-200 flex items-center justify-center text-xs font-medium text-gray-600",
46
+ children: name.charAt(0).toUpperCase()
47
+ })
48
+ }), jsxs("div", {
49
+ className: clsx('min-w-0', isUser ? 'text-right' : 'text-left'),
50
+ children: [showAuthorName && jsx("div", {
51
+ className: "mb-0.5 text-xs font-medium text-gray-500",
52
+ children: name
53
+ }), jsx("div", {
54
+ onClick: onMessageClick ? () => onMessageClick(post) : undefined,
55
+ className: clsx('inline-block rounded-2xl px-4 py-2.5 text-[15px] leading-relaxed text-gray-900', 'whitespace-pre-wrap break-words border', BORDER_COLOR, isUser ? USER_BUBBLE_BG : ASSISTANT_BUBBLE_BG, onMessageClick && 'cursor-pointer'),
56
+ children: text
57
+ }), showTimestamp && timeLabel && jsx("div", {
58
+ className: "mt-0.5 text-[11px] text-gray-400",
59
+ children: timeLabel
60
+ })]
61
+ })]
62
+ })
63
+ });
64
+ };export{DefaultMessageGroup};//# sourceMappingURL=DefaultMessageGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultMessageGroup.js","sources":["../../../src/components/messages-container-ui/DefaultMessageGroup.tsx"],"sourcesContent":[null],"names":[],"mappings":"gEAIA,MAAM,mBAAmB,GAAG,UAAU;AACtC,MAAM,cAAc,GAAG,cAAc;AACrC,MAAM,YAAY,GAAG,iBAAiB;AAEtC;;;;;;;;;;AAUG;MACU,mBAAmB,GAAsC,CAAC;AAOnE,EAAA,QAAM;AACN,EAAA,cAAS;AAAE,EAAA,iBAAW,KAAC;YAEjB,QAAO;AACb,EAAA,gBAAY;AACZ,CAAA,KAAA;AACA,EAAA,MAAA,eAAmB,GAAE,CAAA,CAAA;MACrB,CAAA,IAAM,EAAA,OAAe,IAAO;AAC5B,EAAA,MAAA,WAAa,EAAkB,4BAAuB,EAAA,IAAA;AACtD,EAAA,MAAA,SAAa,IAAG,KAAM,MAAA,IAAU,IAAE,WAAa,IAAC,IAAA,EAAS,QAAQ,aAAC,KAAA,IAAA;QAClE,IAAM,GAAA,OAAY,IAAA,EAAA,YAAkB,QAAO,GAAA,IAAQ,CAAA,UAAW,EAAE;QAEhE,qBACS,IAAA,EAAS;qBAKM,CAAA,QAAA,IAAA,MAAA,CAAA,SAAA,IAAA,MAAA,CAAA,QAAA,KAAqD,MAAA,GAAA,KAAA,GAAA,WAAA,CAAA;AACrD,EAAA,MAAA,OAAA,GAAA,MAAA,CAAA,OAAA,IAAK,IAAK;AA2BtC,EAAE,MAAA,OAAA,GAAA,IAAA,EAAA,SAAA,GAAA,IAAA,IAAA,CAAA,IAAA,CAAA,SAAA,CAAA,GAAA,IAAA;AAEF,EAAA,MAAA,8BAAmC,CAAA,KAAA,CAAA,OAAA,CAAA,OAAA,EAAA,CAAA,GAAA,OAAA,CAAA,kBAAA,EAAA,GAAA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,98 @@
1
+ import React from 'react';
2
+ import type { PlanMessage, MessageGroupComponentType } from './types';
3
+ import type { PlanModeViewInputToolbarProps } from './PlanModeView';
4
+ export interface MessagesContainerUIProps {
5
+ messages: PlanMessage[];
6
+ streamingContent?: string;
7
+ currentUser: {
8
+ id: string;
9
+ name?: string;
10
+ avatar?: string;
11
+ [key: string]: any;
12
+ };
13
+ onSend: (text: string) => void;
14
+ /** Optional classes applied to the container root (useful for width/padding tweaks). */
15
+ className?: string;
16
+ /** Optional ref for the scroll container inside PlanModeView. */
17
+ scrollContainerRef?: React.Ref<HTMLDivElement>;
18
+ /** Optional className applied to PlanModeView root wrapper. */
19
+ planModeViewClassName?: string;
20
+ /** Optional className applied to PlanModeView scroll container element. */
21
+ planModeScrollContainerClassName?: string;
22
+ /** When true, hide scrollbar visuals but keep it scrollable. */
23
+ hideScrollbar?: boolean;
24
+ disabled?: boolean;
25
+ isLoading?: boolean;
26
+ onStop?: () => void;
27
+ showDate?: boolean;
28
+ showAvatar?: boolean;
29
+ showMessageBubbleBorder?: boolean;
30
+ /** When false (default), do NOT create an internal scroll container (avoids nested scroll). */
31
+ useInternalScroll?: boolean;
32
+ /** When true, the built-in input toolbar area is not rendered. */
33
+ hideInputToolbar?: boolean;
34
+ /**
35
+ * Where to place the input toolbar.
36
+ * - `bottom` (default): render toolbar in the bottom area.
37
+ * - `inlineWhenEmpty`: when there are no messages and no streaming/loading, render the toolbar inline
38
+ * inside the empty state (matches landing UI), otherwise use bottom placement.
39
+ */
40
+ inputPlacement?: 'bottom' | 'inlineWhenEmpty';
41
+ /**
42
+ * Optional: render the input composer; receives value, onChange, onSend, disabled.
43
+ * Defaults to `@admin-layout/tailwind-ui`'s `InputToolBar`, so the base works out of the box.
44
+ */
45
+ renderInputToolbar?: (props: PlanModeViewInputToolbarProps) => React.ReactNode;
46
+ /** Placeholder for the default input composer (ignored when `renderInputToolbar` is provided). */
47
+ inputPlaceholder?: string;
48
+ /** Optional: passed to the injected message-group renderer */
49
+ onOpen?: (element?: any) => void;
50
+ onMessageClick?: (msg: any) => void;
51
+ isDesktopView?: boolean;
52
+ isSmallScreen?: boolean;
53
+ sandboxErrors?: any[];
54
+ currentFiles?: Record<string, string>;
55
+ onFixError?: (errorMessage: string) => Promise<void>;
56
+ /** Optional: error message to show above messages; use with onRetry for retry button */
57
+ error?: string | null;
58
+ /** Optional: called when user clicks retry (e.g. after error) */
59
+ onRetry?: () => void;
60
+ /**
61
+ * Optional: custom content when there are no messages and no streaming/loading.
62
+ * Receives input toolbar props so you can render the composer inline (e.g. landing UI).
63
+ */
64
+ renderEmptyState?: (ctx: {
65
+ inputToolbarProps: PlanModeViewInputToolbarProps;
66
+ }) => React.ReactNode;
67
+ /**
68
+ * Optional: when provided, scroll to bottom whenever these deps change (e.g. [streamingContent, messages.length]).
69
+ * Use from the parent to keep the view at bottom on each stream chunk.
70
+ */
71
+ scrollToBottomDeps?: React.DependencyList;
72
+ /** Optional: className applied to the content wrapper inside PlanModeView. */
73
+ contentClassName?: string;
74
+ /** Optional: className applied to the post container inside PlanModeView. */
75
+ postContainerClassName?: string;
76
+ /** When true, code blocks show copy and download actions (default: true). */
77
+ showCopyDownloadOnCodeBlock?: boolean;
78
+ /**
79
+ * The message-group renderer. Defaults to a plain-text bubble renderer so the base
80
+ * works standalone. Inject a rich renderer (e.g. messenger-box's
81
+ * `ModernMessageGroupComponent`) for markdown / code / widget-card rendering.
82
+ */
83
+ MessageGroupComponent?: MessageGroupComponentType;
84
+ /** Optional: how to render the in-flight streaming assistant content (default: plain text). */
85
+ renderStreamingContent?: (content: string) => React.ReactNode;
86
+ /** Optional: override how a PlanMessage is mapped to the post shape handed to the renderer. */
87
+ mapMessageToPost?: (msg: PlanMessage, currentUser: MessagesContainerUIProps['currentUser']) => any;
88
+ }
89
+ /**
90
+ * MessagesContainerUI — a customizable base chat container for plan mode
91
+ * (chat / search / research). Owns the layout, scrolling, streaming area,
92
+ * empty / error / loading states and the input-toolbar slot. The actual message
93
+ * rendering is delegated to an injectable `MessageGroupComponent` (defaults to a
94
+ * plain-text bubble renderer), so consumers plug in their own rich renderer.
95
+ */
96
+ export declare function MessagesContainerUI({ messages, streamingContent, currentUser, onSend, className, scrollContainerRef, planModeViewClassName, planModeScrollContainerClassName, hideScrollbar, disabled, isLoading, onStop, showDate, showAvatar, showMessageBubbleBorder, useInternalScroll, hideInputToolbar, inputPlacement, renderInputToolbar, inputPlaceholder, onOpen, onMessageClick, isDesktopView, isSmallScreen, sandboxErrors, currentFiles, onFixError, error, onRetry, renderEmptyState, scrollToBottomDeps, contentClassName, postContainerClassName, showCopyDownloadOnCodeBlock, MessageGroupComponent, renderStreamingContent, mapMessageToPost, }: MessagesContainerUIProps): import("react/jsx-runtime").JSX.Element;
97
+ export default MessagesContainerUI;
98
+ //# sourceMappingURL=MessagesContainerUI.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessagesContainerUI.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/MessagesContainerUI.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ import {jsx}from'react/jsx-runtime';import clsx from'clsx';import {PlanModeView}from'./PlanModeView.js';/**
2
+ * MessagesContainerUI — a customizable base chat container for plan mode
3
+ * (chat / search / research). Owns the layout, scrolling, streaming area,
4
+ * empty / error / loading states and the input-toolbar slot. The actual message
5
+ * rendering is delegated to an injectable `MessageGroupComponent` (defaults to a
6
+ * plain-text bubble renderer), so consumers plug in their own rich renderer.
7
+ */
8
+ function MessagesContainerUI({
9
+ messages,
10
+ streamingContent,
11
+ currentUser,
12
+ onSend,
13
+ className,
14
+ scrollContainerRef,
15
+ planModeViewClassName,
16
+ planModeScrollContainerClassName,
17
+ hideScrollbar = false,
18
+ disabled = false,
19
+ isLoading = false,
20
+ onStop,
21
+ showDate = false,
22
+ showAvatar = false,
23
+ showMessageBubbleBorder = false,
24
+ useInternalScroll = false,
25
+ hideInputToolbar = false,
26
+ inputPlacement = 'bottom',
27
+ renderInputToolbar,
28
+ inputPlaceholder,
29
+ onOpen,
30
+ onMessageClick,
31
+ isDesktopView = false,
32
+ isSmallScreen = false,
33
+ sandboxErrors,
34
+ currentFiles,
35
+ onFixError,
36
+ error = null,
37
+ onRetry,
38
+ renderEmptyState,
39
+ scrollToBottomDeps,
40
+ contentClassName,
41
+ postContainerClassName,
42
+ showCopyDownloadOnCodeBlock = true,
43
+ MessageGroupComponent,
44
+ renderStreamingContent,
45
+ mapMessageToPost
46
+ }) {
47
+ return jsx("div", {
48
+ className: clsx('flex flex-col flex-1 min-h-0', className),
49
+ children: jsx(PlanModeView, {
50
+ messages: messages,
51
+ streamingContent: streamingContent,
52
+ currentUser: currentUser,
53
+ onSend: onSend,
54
+ disabled: disabled,
55
+ isLoading: isLoading,
56
+ onStop: onStop,
57
+ showDate: showDate,
58
+ showAvatar: showAvatar,
59
+ showMessageBubbleBorder: showMessageBubbleBorder,
60
+ useInternalScroll: useInternalScroll,
61
+ scrollContainerRef: scrollContainerRef,
62
+ className: planModeViewClassName,
63
+ scrollContainerClassName: planModeScrollContainerClassName,
64
+ hideScrollbar: hideScrollbar,
65
+ hideInputToolbar: hideInputToolbar,
66
+ inputPlacement: inputPlacement,
67
+ renderInputToolbar: renderInputToolbar,
68
+ inputPlaceholder: inputPlaceholder,
69
+ onOpen: onOpen,
70
+ onMessageClick: onMessageClick,
71
+ isDesktopView: isDesktopView,
72
+ isSmallScreen: isSmallScreen,
73
+ sandboxErrors: sandboxErrors,
74
+ currentFiles: currentFiles,
75
+ onFixError: onFixError,
76
+ error: error,
77
+ onRetry: onRetry,
78
+ renderEmptyState: renderEmptyState,
79
+ scrollToBottomDeps: scrollToBottomDeps,
80
+ contentClassName: contentClassName,
81
+ postContainerClassName: postContainerClassName,
82
+ showCopyDownloadOnCodeBlock: showCopyDownloadOnCodeBlock,
83
+ MessageGroupComponent: MessageGroupComponent,
84
+ renderStreamingContent: renderStreamingContent,
85
+ mapMessageToPost: mapMessageToPost
86
+ })
87
+ });
88
+ }export{MessagesContainerUI};//# sourceMappingURL=MessagesContainerUI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessagesContainerUI.js","sources":["../../../src/components/messages-container-ui/MessagesContainerUI.tsx"],"sourcesContent":[null],"names":[],"mappings":"wGAuFA;;;;;;AAMG;AACG,SAAU,mBAAmB,CAAC;AAuChC,EAAA,QAAA;AA0CJ,EAAC,gBAAA;AAED,EAAA,WAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import type { MessageGroupComponentType, PlanMessage } from './types';
3
+ export interface PlanModeViewInputToolbarProps {
4
+ value: string;
5
+ onChange: (text: string) => void;
6
+ onSend: () => void;
7
+ disabled?: boolean;
8
+ }
9
+ export interface PlanModeViewProps {
10
+ messages: PlanMessage[];
11
+ streamingContent?: string;
12
+ currentUser: {
13
+ id: string;
14
+ name?: string;
15
+ avatar?: string;
16
+ [key: string]: any;
17
+ };
18
+ onSend: (text: string) => void;
19
+ disabled?: boolean;
20
+ isLoading?: boolean;
21
+ onStop?: () => void;
22
+ showDate?: boolean;
23
+ showAvatar?: boolean;
24
+ showMessageBubbleBorder?: boolean;
25
+ /** When false (default), do NOT create an internal scroll container (avoids nested scroll). */
26
+ useInternalScroll?: boolean;
27
+ /**
28
+ * Optional ref for the scroll container element (defaults to the internal
29
+ * message list wrapper).
30
+ *
31
+ * If provided, it will be attached to the internal scroll container div
32
+ * (so parent code can read/scroll it).
33
+ */
34
+ scrollContainerRef?: React.Ref<HTMLDivElement>;
35
+ /** Optional className applied to the scroll container element. */
36
+ scrollContainerClassName?: string;
37
+ /** When true, hide the scrollbar visuals but keep it scrollable. */
38
+ hideScrollbar?: boolean;
39
+ contentClassName?: string;
40
+ postContainerClassName?: string;
41
+ /** Optional className applied to the root wrapper element. */
42
+ className?: string;
43
+ /** When true, the built-in input toolbar area is not rendered. */
44
+ hideInputToolbar?: boolean;
45
+ /**
46
+ * Where to place the input toolbar.
47
+ * - `bottom` (default): render toolbar in the bottom area.
48
+ * - `inlineWhenEmpty`: when there are no messages and no streaming/loading, render the toolbar inline
49
+ * inside the empty state (matches landing UI), otherwise use bottom placement.
50
+ */
51
+ inputPlacement?: 'bottom' | 'inlineWhenEmpty';
52
+ /**
53
+ * Optional: render the input toolbar; receives value, onChange, onSend, disabled.
54
+ * Defaults to {@link DefaultInputToolBar} (which wraps `@admin-layout/tailwind-ui`'s
55
+ * `InputToolBar`), so the base ships a working composer out of the box.
56
+ */
57
+ renderInputToolbar?: (props: PlanModeViewInputToolbarProps) => React.ReactNode;
58
+ /** Placeholder for the default input toolbar (ignored when `renderInputToolbar` is provided). */
59
+ inputPlaceholder?: string;
60
+ /** Optional: passed to the injected message-group renderer */
61
+ onOpen?: (element?: any) => void;
62
+ onMessageClick?: (msg: any) => void;
63
+ isDesktopView?: boolean;
64
+ isSmallScreen?: boolean;
65
+ sandboxErrors?: any[];
66
+ currentFiles?: Record<string, string>;
67
+ onFixError?: (errorMessage: string) => Promise<void>;
68
+ /** Optional: error message to show above messages; use with onRetry for retry button */
69
+ error?: string | null;
70
+ /** Optional: called when user clicks retry (e.g. after error) */
71
+ onRetry?: () => void;
72
+ /**
73
+ * Optional: custom content when there are no messages and no streaming/loading.
74
+ * Receives input toolbar props so you can render the composer inline (e.g. landing UI).
75
+ */
76
+ renderEmptyState?: (ctx: {
77
+ inputToolbarProps: PlanModeViewInputToolbarProps;
78
+ }) => React.ReactNode;
79
+ /**
80
+ * Optional: when provided, scroll to bottom whenever these deps change (e.g. [streamingContent, messages.length]).
81
+ * Lets the parent force scroll on each stream chunk when the internal ResizeObserver/layout effect miss.
82
+ */
83
+ scrollToBottomDeps?: React.DependencyList;
84
+ /** When true, fenced / raw code blocks show copy and download actions (default: true). */
85
+ showCopyDownloadOnCodeBlock?: boolean;
86
+ /**
87
+ * The message-group renderer. Each rendered group receives a single mapped post.
88
+ * Defaults to {@link DefaultMessageGroup} (plain-text bubbles) so the base works
89
+ * standalone. Inject a rich renderer (e.g. messenger-box's
90
+ * `ModernMessageGroupComponent`) to get markdown / code / widget-card rendering.
91
+ */
92
+ MessageGroupComponent?: MessageGroupComponentType;
93
+ /**
94
+ * Optional: how to render the in-flight streaming assistant content. Defaults to a
95
+ * plain-text bubble. Inject a richer renderer (markdown / code) if desired.
96
+ */
97
+ renderStreamingContent?: (content: string) => React.ReactNode;
98
+ /**
99
+ * Optional: override how a PlanMessage is mapped to the post shape handed to
100
+ * `MessageGroupComponent`. Defaults to {@link defaultPlanMessageToPost}.
101
+ */
102
+ mapMessageToPost?: (msg: PlanMessage, currentUser: PlanModeViewProps['currentUser']) => any;
103
+ }
104
+ /** Default mapping of a PlanMessage to the post-like shape expected by message-group renderers. */
105
+ export declare function defaultPlanMessageToPost(msg: PlanMessage, currentUser: PlanModeViewProps['currentUser']): any;
106
+ export declare function PlanModeView({ messages, streamingContent, currentUser, onSend, disabled, isLoading, onStop, showDate, showAvatar, showMessageBubbleBorder, useInternalScroll, scrollContainerRef, scrollContainerClassName, hideScrollbar, contentClassName, postContainerClassName, className, hideInputToolbar, inputPlacement, renderInputToolbar, inputPlaceholder, onOpen, onMessageClick, isDesktopView, isSmallScreen, sandboxErrors, currentFiles, onFixError, error, onRetry, renderEmptyState, scrollToBottomDeps, showCopyDownloadOnCodeBlock, MessageGroupComponent, renderStreamingContent, mapMessageToPost, }: PlanModeViewProps): import("react/jsx-runtime").JSX.Element;
107
+ //# sourceMappingURL=PlanModeView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanModeView.d.ts","sourceRoot":"","sources":["../../../src/components/messages-container-ui/PlanModeView.tsx"],"names":[],"mappings":"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"}