@gravity-ui/aikit 0.2.0 → 0.2.2
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/components/pages/ChatContainer/ChatContainer.js +9 -18
- package/dist/components/pages/ChatContainer/ChatContainer.scss +16 -0
- package/dist/components/pages/ChatContainer/types.d.ts +18 -14
- package/dist/components/templates/EmptyContainer/EmptyContainer.d.ts +6 -4
- package/dist/components/templates/EmptyContainer/EmptyContainer.js +2 -2
- package/dist/themes/variables.css +4 -0
- package/package.json +1 -1
|
@@ -19,7 +19,7 @@ const b = block('chat-container');
|
|
|
19
19
|
*/
|
|
20
20
|
export function ChatContainer(props) {
|
|
21
21
|
var _a, _b;
|
|
22
|
-
const { chats = [], messages = [], onSendMessage, onDeleteChat, onCancel, onRetry, status = 'ready', error = null, showActionsOnHover = false, contextItems = [], transformOptions, headerProps = {}, contentProps = {}, emptyContainerProps = {}, promptInputProps = {}, historyProps = {}, welcomeConfig, i18nConfig = {}, className, qa, } = props;
|
|
22
|
+
const { chats = [], messages = [], onSendMessage, onDeleteChat, onCancel, onRetry, status = 'ready', error = null, showActionsOnHover = false, contextItems = [], transformOptions, headerProps = {}, contentProps = {}, emptyContainerProps = {}, promptInputProps = {}, historyProps = {}, welcomeConfig, i18nConfig = {}, className, headerClassName, contentClassName, footerClassName, qa, } = props;
|
|
23
23
|
const hookState = useChatContainer(props);
|
|
24
24
|
// Collect i18n texts with overrides
|
|
25
25
|
const headerTitle = useMemo(() => {
|
|
@@ -41,24 +41,15 @@ export function ChatContainer(props) {
|
|
|
41
41
|
]);
|
|
42
42
|
// Build props for EmptyContainer
|
|
43
43
|
const finalEmptyContainerProps = useMemo(() => {
|
|
44
|
-
var _a, _b, _c, _d
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
id: s.id,
|
|
48
|
-
title: s.label || s.content, // Use label or content as button title
|
|
49
|
-
}));
|
|
50
|
-
return Object.assign(Object.assign({}, emptyContainerProps), { image: welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.image, title: (welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.title) || ((_b = i18nConfig.emptyState) === null || _b === void 0 ? void 0 : _b.title) || i18n('empty-state-title'), description: (welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.description) ||
|
|
51
|
-
((_c = i18nConfig.emptyState) === null || _c === void 0 ? void 0 : _c.description) ||
|
|
44
|
+
var _a, _b, _c, _d;
|
|
45
|
+
return Object.assign(Object.assign({}, emptyContainerProps), { image: welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.image, title: (welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.title) || ((_a = i18nConfig.emptyState) === null || _a === void 0 ? void 0 : _a.title) || i18n('empty-state-title'), description: (welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.description) ||
|
|
46
|
+
((_b = i18nConfig.emptyState) === null || _b === void 0 ? void 0 : _b.description) ||
|
|
52
47
|
i18n('empty-state-description'), suggestionTitle: (welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.suggestionTitle) ||
|
|
53
|
-
((
|
|
54
|
-
i18n('empty-state-suggestions-title'), suggestions:
|
|
55
|
-
((
|
|
48
|
+
((_c = i18nConfig.emptyState) === null || _c === void 0 ? void 0 : _c.suggestionsTitle) ||
|
|
49
|
+
i18n('empty-state-suggestions-title'), suggestions: welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.suggestions, alignment: welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.alignment, wrapText: welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.wrapText, showMore: welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.showMore, showMoreText: (welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.showMoreText) ||
|
|
50
|
+
((_d = i18nConfig.emptyState) === null || _d === void 0 ? void 0 : _d.showMoreText) ||
|
|
56
51
|
i18n('empty-state-show-more'), onSuggestionClick: async (clickedTitle) => {
|
|
57
|
-
|
|
58
|
-
// Find original suggestion by title to get content
|
|
59
|
-
const originalSuggestion = (_a = welcomeConfig === null || welcomeConfig === void 0 ? void 0 : welcomeConfig.suggestions) === null || _a === void 0 ? void 0 : _a.find((s) => (s.label || s.content) === clickedTitle);
|
|
60
|
-
const contentToSend = (originalSuggestion === null || originalSuggestion === void 0 ? void 0 : originalSuggestion.content) || clickedTitle;
|
|
61
|
-
await onSendMessage({ content: contentToSend });
|
|
52
|
+
await onSendMessage({ content: clickedTitle });
|
|
62
53
|
} });
|
|
63
54
|
}, [welcomeConfig, i18nConfig.emptyState, emptyContainerProps, onSendMessage]);
|
|
64
55
|
// Build props for MessageList
|
|
@@ -106,5 +97,5 @@ export function ChatContainer(props) {
|
|
|
106
97
|
historyProps,
|
|
107
98
|
]);
|
|
108
99
|
const showFooter = finalPromptInputProps || disclaimerProps;
|
|
109
|
-
return (_jsxs("div", { className: b(null, className), "data-qa": qa, children: [_jsx("div", { className: b('header'), children: _jsx(Header, Object.assign({}, finalHeaderProps)) }), _jsx("div", { className: b('content'), children: _jsx(ChatContent, Object.assign({}, finalContentProps)) }), showFooter && (_jsxs("div", { className: b('footer'), children: [finalPromptInputProps && _jsx(PromptInput, Object.assign({}, finalPromptInputProps)), disclaimerProps && _jsx(Disclaimer, Object.assign({}, disclaimerProps))] })), _jsx(History, Object.assign({}, finalHistoryProps))] }));
|
|
100
|
+
return (_jsxs("div", { className: b(null, className), "data-qa": qa, children: [_jsx("div", { className: b('header', headerClassName), children: _jsx(Header, Object.assign({}, finalHeaderProps)) }), _jsx("div", { className: b('content', { view: hookState.chatContentView }, contentClassName), children: _jsx(ChatContent, Object.assign({}, finalContentProps)) }), showFooter && (_jsxs("div", { className: b('footer', { view: hookState.chatContentView }, footerClassName), children: [finalPromptInputProps && _jsx(PromptInput, Object.assign({}, finalPromptInputProps)), disclaimerProps && _jsx(Disclaimer, Object.assign({}, disclaimerProps))] })), _jsx(History, Object.assign({}, finalHistoryProps))] }));
|
|
110
101
|
}
|
|
@@ -32,6 +32,14 @@
|
|
|
32
32
|
flex: 1 0 0;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
&__content_view_empty {
|
|
36
|
+
background: var(--g-aikit-chat-container-content-empty-background);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&__content_view_chat {
|
|
40
|
+
background: var(--g-aikit-chat-container-content-chat-background);
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
&__footer {
|
|
36
44
|
display: flex;
|
|
37
45
|
padding: var(--g-aikit-layout-base-padding-m);
|
|
@@ -41,4 +49,12 @@
|
|
|
41
49
|
align-self: stretch;
|
|
42
50
|
background: var(--g-aikit-chat-container-footer-background);
|
|
43
51
|
}
|
|
52
|
+
|
|
53
|
+
&__footer_view_empty {
|
|
54
|
+
background: var(--g-aikit-chat-container-footer-empty-background);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&__footer_view_chat {
|
|
58
|
+
background: var(--g-aikit-chat-container-footer-chat-background);
|
|
59
|
+
}
|
|
44
60
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { OptionsType } from '@diplodoc/transform/lib/typings';
|
|
2
2
|
import type { ChatStatus, ChatType, TChatMessage, TSubmitData } from '../../../types';
|
|
3
3
|
import type { ContextItemConfig } from '../../molecules/PromptInputHeader';
|
|
4
|
+
import type { SuggestionsItem } from '../../molecules/Suggestions';
|
|
4
5
|
import type { HeaderProps } from '../../organisms/Header';
|
|
5
6
|
import type { PromptInputProps } from '../../organisms/PromptInput';
|
|
6
7
|
import type { ChatContentProps } from '../../templates/ChatContent';
|
|
7
|
-
import type { EmptyContainerProps } from '../../templates/EmptyContainer';
|
|
8
|
+
import type { AlignmentConfig, EmptyContainerProps } from '../../templates/EmptyContainer';
|
|
8
9
|
import type { HistoryProps } from '../../templates/History';
|
|
9
10
|
/**
|
|
10
11
|
* I18n configuration for all text labels in ChatContainer
|
|
@@ -60,21 +61,18 @@ export interface ChatContainerI18nConfig {
|
|
|
60
61
|
export interface WelcomeConfig {
|
|
61
62
|
/** Image or icon to display */
|
|
62
63
|
image?: React.ReactNode;
|
|
63
|
-
/** Title text */
|
|
64
|
-
title?: string;
|
|
65
|
-
/** Description text */
|
|
66
|
-
description?: string;
|
|
64
|
+
/** Title text or custom React element */
|
|
65
|
+
title?: string | React.ReactNode;
|
|
66
|
+
/** Description text or custom React element */
|
|
67
|
+
description?: string | React.ReactNode;
|
|
67
68
|
/** Suggestions section title */
|
|
68
69
|
suggestionTitle?: string;
|
|
69
|
-
/** Array of suggestions */
|
|
70
|
-
suggestions?:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
/** Display title for the suggestion button (defaults to content if not provided) */
|
|
76
|
-
label?: string;
|
|
77
|
-
}>;
|
|
70
|
+
/** Array of suggestions (title will be used as message content) */
|
|
71
|
+
suggestions?: SuggestionsItem[];
|
|
72
|
+
/** Alignment configuration for image, title, and description */
|
|
73
|
+
alignment?: AlignmentConfig;
|
|
74
|
+
/** Enable text wrapping inside suggestion buttons instead of ellipsis */
|
|
75
|
+
wrapText?: boolean;
|
|
78
76
|
/** Show more suggestions callback */
|
|
79
77
|
showMore?: () => void;
|
|
80
78
|
/** Show more button text */
|
|
@@ -138,6 +136,12 @@ export interface ChatContainerProps {
|
|
|
138
136
|
showClose?: boolean;
|
|
139
137
|
/** Additional CSS class */
|
|
140
138
|
className?: string;
|
|
139
|
+
/** Additional CSS class for header section */
|
|
140
|
+
headerClassName?: string;
|
|
141
|
+
/** Additional CSS class for content section */
|
|
142
|
+
contentClassName?: string;
|
|
143
|
+
/** Additional CSS class for footer section */
|
|
144
|
+
footerClassName?: string;
|
|
141
145
|
/** QA/test identifier */
|
|
142
146
|
qa?: string;
|
|
143
147
|
}
|
|
@@ -26,10 +26,10 @@ export interface AlignmentConfig {
|
|
|
26
26
|
export interface EmptyContainerProps {
|
|
27
27
|
/** Image or icon to display at the top */
|
|
28
28
|
image?: React.ReactNode;
|
|
29
|
-
/** Title text for the welcome screen */
|
|
30
|
-
title?: string;
|
|
31
|
-
/** Description text explaining the functionality */
|
|
32
|
-
description?: string;
|
|
29
|
+
/** Title text or custom React element for the welcome screen */
|
|
30
|
+
title?: string | React.ReactNode;
|
|
31
|
+
/** Description text or custom React element explaining the functionality */
|
|
32
|
+
description?: string | React.ReactNode;
|
|
33
33
|
/** Title for the suggestions section */
|
|
34
34
|
suggestionTitle?: string;
|
|
35
35
|
/** Array of suggestion items */
|
|
@@ -38,6 +38,8 @@ export interface EmptyContainerProps {
|
|
|
38
38
|
onSuggestionClick?: (content: string, id?: string) => void;
|
|
39
39
|
/** Alignment configuration for image, title, and description */
|
|
40
40
|
alignment?: AlignmentConfig;
|
|
41
|
+
/** Enable text wrapping inside suggestion buttons instead of ellipsis */
|
|
42
|
+
wrapText?: boolean;
|
|
41
43
|
/** Callback for showing more suggestions */
|
|
42
44
|
showMore?: () => void;
|
|
43
45
|
/** Custom text for the show more button */
|
|
@@ -14,7 +14,7 @@ const b = block('empty-container');
|
|
|
14
14
|
* @returns React component
|
|
15
15
|
*/
|
|
16
16
|
export function EmptyContainer(props) {
|
|
17
|
-
const { image, title, description, suggestionTitle, suggestions = [], onSuggestionClick, alignment, showMore, showMoreText, className, qa, } = props;
|
|
17
|
+
const { image, title, description, suggestionTitle, suggestions = [], onSuggestionClick, alignment, wrapText = false, showMore, showMoreText, className, qa, } = props;
|
|
18
18
|
const hasContent = title || description || (suggestions && suggestions.length > 0);
|
|
19
19
|
// Define alignment for each element
|
|
20
20
|
const imageAlignment = (alignment === null || alignment === void 0 ? void 0 : alignment.image) || 'left';
|
|
@@ -22,5 +22,5 @@ export function EmptyContainer(props) {
|
|
|
22
22
|
const descriptionAlignment = (alignment === null || alignment === void 0 ? void 0 : alignment.description) || 'left';
|
|
23
23
|
// Define text for "Show more" button with localization support
|
|
24
24
|
const showMoreButtonText = showMoreText || i18n('show-more-button');
|
|
25
|
-
return (_jsx("div", { className: b(null, className), "data-qa": qa, children: _jsx("div", { className: b('content'), children: hasContent && (_jsxs(_Fragment, { children: [_jsxs("div", { className: b('welcome-section'), children: [image && (_jsx("div", { className: b('image-container', { align: imageAlignment }), children: image })), _jsxs("div", { className: b('text-container'), children: [title && (_jsx(Text, { variant: "header-2", className: b('title', { align: titleAlignment }), children: title })), description && (_jsx(Text, { variant: "body-2", color: "complementary", className: b('description', { align: descriptionAlignment }), children: description }))] })] }), suggestions && suggestions.length > 0 && onSuggestionClick && (_jsxs("div", { className: b('suggestions-section'), children: [suggestionTitle && (_jsx("div", { className: b('suggestions-title'), children: _jsx(Text, { variant: "subheader-3", color: "primary", children: suggestionTitle }) })), _jsx("div", { children: _jsx(Suggestions, { items: suggestions, onClick: onSuggestionClick, layout: "grid" }) }), showMore && (_jsx("div", { className: b('show-more'), children: _jsxs(Button, { view: "flat-secondary", size: "l", onClick: showMore, className: b('show-more-button'), children: [_jsx(Button.Icon, { children: _jsx(ArrowRotateRight, {}) }), showMoreButtonText] }) }))] }))] })) }) }));
|
|
25
|
+
return (_jsx("div", { className: b(null, className), "data-qa": qa, children: _jsx("div", { className: b('content'), children: hasContent && (_jsxs(_Fragment, { children: [_jsxs("div", { className: b('welcome-section'), children: [image && (_jsx("div", { className: b('image-container', { align: imageAlignment }), children: image })), _jsxs("div", { className: b('text-container'), children: [title && (_jsx(Text, { variant: "header-2", className: b('title', { align: titleAlignment }), children: title })), description && (_jsx(Text, { variant: "body-2", color: "complementary", className: b('description', { align: descriptionAlignment }), children: description }))] })] }), suggestions && suggestions.length > 0 && onSuggestionClick && (_jsxs("div", { className: b('suggestions-section'), children: [suggestionTitle && (_jsx("div", { className: b('suggestions-title'), children: _jsx(Text, { variant: "subheader-3", color: "primary", children: suggestionTitle }) })), _jsx("div", { children: _jsx(Suggestions, { items: suggestions, onClick: onSuggestionClick, layout: "grid", wrapText: wrapText }) }), showMore && (_jsx("div", { className: b('show-more'), children: _jsxs(Button, { view: "flat-secondary", size: "l", onClick: showMore, className: b('show-more-button'), children: [_jsx(Button.Icon, { children: _jsx(ArrowRotateRight, {}) }), showMoreButtonText] }) }))] }))] })) }) }));
|
|
26
26
|
}
|
|
@@ -66,4 +66,8 @@
|
|
|
66
66
|
--g-aikit-chat-container-content-background: var(--g-color-base-background);
|
|
67
67
|
--g-aikit-chat-container-footer-background: var(--g-color-base-background);
|
|
68
68
|
--g-aikit-chat-container-background: var(--g-color-base-background);
|
|
69
|
+
--g-aikit-chat-container-content-empty-background: var(--g-color-base-background);
|
|
70
|
+
--g-aikit-chat-container-content-chat-background: var(--g-color-base-background);
|
|
71
|
+
--g-aikit-chat-container-footer-empty-background: var(--g-color-base-background);
|
|
72
|
+
--g-aikit-chat-container-footer-chat-background: var(--g-color-base-background);
|
|
69
73
|
}
|