@gravity-ui/aikit 1.7.0 → 1.9.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.
Files changed (127) hide show
  1. package/README.md +0 -2
  2. package/dist/components/atoms/Alert/Alert.css +28 -0
  3. package/dist/components/atoms/Alert/index.js +1 -1
  4. package/dist/components/atoms/ChatDate/ChatDate.css +9 -0
  5. package/dist/components/atoms/ChatDate/ChatDate.js +1 -1
  6. package/dist/components/atoms/ContextIndicator/ContextIndicator.css +66 -0
  7. package/dist/components/atoms/ContextIndicator/index.js +1 -1
  8. package/dist/components/atoms/DiffStat/DiffStat.css +23 -0
  9. package/dist/components/atoms/DiffStat/index.js +1 -1
  10. package/dist/components/atoms/Disclaimer/Disclaimer.css +7 -0
  11. package/dist/components/atoms/Disclaimer/Disclaimer.js +1 -1
  12. package/dist/components/atoms/IntersectionContainer/IntersectionContainer.css +3 -0
  13. package/dist/components/atoms/IntersectionContainer/IntersectionContainer.js +1 -1
  14. package/dist/components/atoms/Loader/Loader.css +48 -0
  15. package/dist/components/atoms/Loader/Loader.js +1 -1
  16. package/dist/components/atoms/MarkdownRenderer/MarkdownRenderer.css +5 -0
  17. package/dist/components/atoms/MarkdownRenderer/MarkdownRenderer.js +1 -1
  18. package/dist/components/atoms/MessageBalloon/MessageBalloon.css +7 -0
  19. package/dist/components/atoms/MessageBalloon/index.js +1 -1
  20. package/dist/components/atoms/Shimmer/Shimmer.css +18 -0
  21. package/dist/components/atoms/Shimmer/index.js +1 -1
  22. package/dist/components/atoms/SubmitButton/SubmitButton.css +20 -0
  23. package/dist/components/atoms/SubmitButton/SubmitButton.js +1 -1
  24. package/dist/components/atoms/ToolIndicator/ToolIndicator.css +9 -0
  25. package/dist/components/atoms/ToolIndicator/index.js +1 -1
  26. package/dist/components/molecules/BaseMessage/BaseMessage.css +27 -0
  27. package/dist/components/molecules/BaseMessage/__stories__/BaseMessage.stories.d.ts +1 -0
  28. package/dist/components/molecules/BaseMessage/__stories__/BaseMessage.stories.js +10 -0
  29. package/dist/components/molecules/BaseMessage/index.js +22 -14
  30. package/dist/components/molecules/ButtonGroup/ButtonGroup.css +13 -0
  31. package/dist/components/molecules/ButtonGroup/index.js +1 -1
  32. package/dist/components/molecules/PromptInputBody/PromptInputBody.css +15 -0
  33. package/dist/components/molecules/PromptInputBody/PromptInputBody.js +1 -1
  34. package/dist/components/molecules/PromptInputFooter/PromptInputFooter.css +18 -0
  35. package/dist/components/molecules/PromptInputFooter/PromptInputFooter.js +1 -1
  36. package/dist/components/molecules/PromptInputHeader/PromptInputHeader.css +21 -0
  37. package/dist/components/molecules/PromptInputHeader/PromptInputHeader.js +1 -1
  38. package/dist/components/molecules/PromptInputPanel/PromptInputPanel.css +7 -0
  39. package/dist/components/molecules/PromptInputPanel/PromptInputPanel.js +1 -1
  40. package/dist/components/molecules/Suggestions/Suggestions.css +71 -0
  41. package/dist/components/molecules/Suggestions/Suggestions.js +1 -1
  42. package/dist/components/molecules/Tabs/Tabs.css +35 -0
  43. package/dist/components/molecules/Tabs/Tabs.js +1 -1
  44. package/dist/components/molecules/ToolFooter/ToolFooter.css +10 -0
  45. package/dist/components/molecules/ToolFooter/index.js +1 -1
  46. package/dist/components/molecules/ToolHeader/ToolHeader.css +18 -0
  47. package/dist/components/molecules/ToolHeader/index.js +1 -1
  48. package/dist/components/molecules/ToolStatus/ToolStatus.css +1 -0
  49. package/dist/components/molecules/ToolStatus/index.js +1 -1
  50. package/dist/components/organisms/AssistantMessage/AssistantMessage.css +6 -0
  51. package/dist/components/organisms/AssistantMessage/AssistantMessage.d.ts +2 -2
  52. package/dist/components/organisms/AssistantMessage/AssistantMessage.js +3 -3
  53. package/dist/components/organisms/AssistantMessage/__stories__/AssistantMessage.stories.d.ts +1 -0
  54. package/dist/components/organisms/AssistantMessage/__stories__/AssistantMessage.stories.js +12 -1
  55. package/dist/components/organisms/Header/Header.css +40 -0
  56. package/dist/components/organisms/Header/Header.js +1 -1
  57. package/dist/components/organisms/MessageList/MessageList.css +26 -0
  58. package/dist/components/organisms/MessageList/MessageList.js +2 -2
  59. package/dist/components/organisms/MessageList/__stories__/MessageList.stories.d.ts +1 -0
  60. package/dist/components/organisms/MessageList/__stories__/MessageList.stories.js +54 -4
  61. package/dist/components/organisms/PromptInput/PromptInput.css +50 -0
  62. package/dist/components/organisms/PromptInput/PromptInput.js +1 -1
  63. package/dist/components/organisms/ThinkingMessage/ThinkingMessage.css +20 -0
  64. package/dist/components/organisms/ThinkingMessage/index.js +1 -1
  65. package/dist/components/organisms/ToolMessage/ToolMessage.css +13 -0
  66. package/dist/components/organisms/ToolMessage/index.js +1 -1
  67. package/dist/components/organisms/UserMessage/UserMessage.css +10 -0
  68. package/dist/components/organisms/UserMessage/index.js +1 -1
  69. package/dist/components/pages/ChatContainer/ChatContainer.css +49 -0
  70. package/dist/components/pages/ChatContainer/ChatContainer.js +1 -1
  71. package/dist/components/pages/ChatContainer/__stories__/ChatContainer.stories.d.ts +5 -0
  72. package/dist/components/pages/ChatContainer/__stories__/ChatContainer.stories.js +77 -0
  73. package/dist/components/templates/ChatContent/ChatContent.css +23 -0
  74. package/dist/components/templates/ChatContent/ChatContent.js +1 -1
  75. package/dist/components/templates/EmptyContainer/EmptyContainer.css +64 -0
  76. package/dist/components/templates/EmptyContainer/EmptyContainer.js +1 -1
  77. package/dist/components/templates/History/History.css +81 -0
  78. package/dist/components/templates/History/HistoryList.js +1 -1
  79. package/dist/demo/ContentWrapper/ContentWrapper.css +6 -0
  80. package/dist/demo/ContentWrapper/ContentWrapper.js +1 -1
  81. package/dist/demo/DocsDecorator/DocsDecorator.css +87 -0
  82. package/dist/demo/Showcase/Showcase.css +34 -0
  83. package/dist/demo/Showcase/Showcase.js +1 -1
  84. package/dist/demo/ShowcaseItem/ShowcaseItem.css +7 -0
  85. package/dist/demo/ShowcaseItem/ShowcaseItem.js +1 -1
  86. package/dist/demo/SwapArea/SwapArea.css +11 -0
  87. package/dist/demo/SwapArea/SwapArea.js +1 -1
  88. package/dist/styles/variables.css +1 -0
  89. package/dist/types/messages.d.ts +3 -0
  90. package/package.json +6 -5
  91. package/dist/components/atoms/Alert/Alert.scss +0 -39
  92. package/dist/components/atoms/ChatDate/ChatDate.scss +0 -15
  93. package/dist/components/atoms/ContextIndicator/ContextIndicator.scss +0 -93
  94. package/dist/components/atoms/DiffStat/DiffStat.scss +0 -36
  95. package/dist/components/atoms/Disclaimer/Disclaimer.scss +0 -13
  96. package/dist/components/atoms/IntersectionContainer/IntersectionContainer.scss +0 -7
  97. package/dist/components/atoms/Loader/Loader.scss +0 -72
  98. package/dist/components/atoms/MarkdownRenderer/MarkdownRenderer.scss +0 -10
  99. package/dist/components/atoms/MessageBalloon/MessageBalloon.scss +0 -11
  100. package/dist/components/atoms/Shimmer/Shimmer.scss +0 -32
  101. package/dist/components/atoms/SubmitButton/SubmitButton.scss +0 -29
  102. package/dist/components/atoms/ToolIndicator/ToolIndicator.scss +0 -15
  103. package/dist/components/molecules/BaseMessage/BaseMessage.scss +0 -41
  104. package/dist/components/molecules/ButtonGroup/ButtonGroup.scss +0 -19
  105. package/dist/components/molecules/PromptInputBody/PromptInputBody.scss +0 -22
  106. package/dist/components/molecules/PromptInputFooter/PromptInputFooter.scss +0 -25
  107. package/dist/components/molecules/PromptInputHeader/PromptInputHeader.scss +0 -27
  108. package/dist/components/molecules/PromptInputPanel/PromptInputPanel.scss +0 -11
  109. package/dist/components/molecules/Suggestions/Suggestions.scss +0 -90
  110. package/dist/components/molecules/Tabs/Tabs.scss +0 -46
  111. package/dist/components/molecules/ToolFooter/ToolFooter.scss +0 -15
  112. package/dist/components/molecules/ToolHeader/ToolHeader.scss +0 -24
  113. package/dist/components/molecules/ToolStatus/ToolStatus.scss +0 -6
  114. package/dist/components/organisms/AssistantMessage/AssistantMessage.scss +0 -10
  115. package/dist/components/organisms/Header/Header.scss +0 -51
  116. package/dist/components/organisms/MessageList/MessageList.scss +0 -35
  117. package/dist/components/organisms/PromptInput/PromptInput.scss +0 -77
  118. package/dist/components/organisms/ThinkingMessage/ThinkingMessage.scss +0 -27
  119. package/dist/components/organisms/ToolMessage/ToolMessage.scss +0 -19
  120. package/dist/components/organisms/UserMessage/UserMessage.scss +0 -14
  121. package/dist/components/pages/ChatContainer/ChatContainer.scss +0 -60
  122. package/dist/components/templates/ChatContent/ChatContent.scss +0 -30
  123. package/dist/components/templates/EmptyContainer/EmptyContainer.scss +0 -86
  124. package/dist/components/templates/History/History.scss +0 -103
  125. package/dist/styles/_functions.scss +0 -5
  126. package/dist/styles/variables.scss +0 -1
  127. /package/dist/styles/{styles.scss → styles.css} +0 -0
@@ -0,0 +1,71 @@
1
+ .g-aikit-suggestions__container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--g-spacing-2);
5
+ }
6
+ .g-aikit-suggestions__title {
7
+ padding-bottom: 0;
8
+ }
9
+ .g-aikit-suggestions {
10
+ display: flex;
11
+ align-items: flex-start;
12
+ align-content: flex-start;
13
+ gap: var(--g-spacing-2) var(--g-spacing-2);
14
+ align-self: stretch;
15
+ flex-wrap: wrap;
16
+ }
17
+ .g-aikit-suggestions_layout_grid {
18
+ flex-direction: row;
19
+ }
20
+ .g-aikit-suggestions_layout_list {
21
+ flex-direction: column;
22
+ }
23
+ .g-aikit-suggestions_layout_list .g-aikit-suggestions__button {
24
+ width: 100%;
25
+ }
26
+ .g-aikit-suggestions__button {
27
+ padding: calc(var(--g-spacing-base) * 2) calc(var(--g-spacing-base) * 4);
28
+ height: 100%;
29
+ box-shadow: none;
30
+ }
31
+ .g-aikit-suggestions__button .g-button__text {
32
+ width: 100%;
33
+ }
34
+ .g-aikit-suggestions__button-content {
35
+ display: flex;
36
+ flex-direction: row;
37
+ align-items: center;
38
+ justify-content: space-between;
39
+ flex: 1;
40
+ gap: calc(var(--g-spacing-base) * 1);
41
+ min-width: 0;
42
+ }
43
+ .g-aikit-suggestions__button-content_text-align_left {
44
+ justify-content: flex-start;
45
+ }
46
+ .g-aikit-suggestions__button-content_text-align_center {
47
+ justify-content: center;
48
+ }
49
+ .g-aikit-suggestions__button-content_text-align_right {
50
+ justify-content: flex-end;
51
+ }
52
+ .g-aikit-suggestions__button-text {
53
+ overflow: hidden;
54
+ text-overflow: ellipsis;
55
+ white-space: nowrap;
56
+ min-width: 0;
57
+ }
58
+ .g-aikit-suggestions__button-text-wrap {
59
+ word-break: break-word;
60
+ white-space: normal;
61
+ min-width: 0;
62
+ text-align: left;
63
+ }
64
+ .g-aikit-suggestions__button-icon {
65
+ width: 16px;
66
+ height: 16px;
67
+ color: var(--g-color-text-hint);
68
+ flex-shrink: 0;
69
+ display: flex;
70
+ align-items: center;
71
+ }
@@ -3,7 +3,7 @@ import { ChevronLeft, ChevronRight } from '@gravity-ui/icons';
3
3
  import { Icon, Text } from '@gravity-ui/uikit';
4
4
  import { block } from '../../../utils/cn';
5
5
  import { ActionButton } from '../../atoms';
6
- import './Suggestions.scss';
6
+ import './Suggestions.css';
7
7
  const b = block('suggestions');
8
8
  /**
9
9
  * Suggestions component displays a group of clickable suggestion buttons
@@ -0,0 +1,35 @@
1
+ .g-aikit-tabs {
2
+ display: flex;
3
+ width: 100%;
4
+ flex-direction: row;
5
+ align-items: flex-start;
6
+ gap: var(--g-spacing-2);
7
+ overflow: scroll hidden;
8
+ white-space: nowrap;
9
+ padding: var(--g-spacing-1) 0;
10
+ scrollbar-width: thin;
11
+ transition: scrollbar-color 0.3s ease-in-out;
12
+ scrollbar-color: transparent transparent;
13
+ }
14
+ .g-aikit-tabs:hover {
15
+ scrollbar-color: var(--g-color-base-generic-medium) transparent;
16
+ }
17
+ .g-aikit-tabs::-webkit-scrollbar {
18
+ height: 6px;
19
+ }
20
+ .g-aikit-tabs::-webkit-scrollbar-track {
21
+ background: transparent;
22
+ }
23
+ .g-aikit-tabs::-webkit-scrollbar-thumb {
24
+ background-color: transparent;
25
+ border-radius: 3px;
26
+ transition: background-color 0.3s ease-in-out;
27
+ }
28
+ .g-aikit-tabs:hover::-webkit-scrollbar-thumb {
29
+ background-color: var(--g-color-base-generic-medium);
30
+ }
31
+ .g-aikit-tabs__tab {
32
+ flex-shrink: 0;
33
+ cursor: default;
34
+ overflow: hidden;
35
+ }
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useCallback } from 'react';
4
4
  import { Label } from '@gravity-ui/uikit';
5
5
  import { block } from '../../../utils/cn';
6
- import './Tabs.scss';
6
+ import './Tabs.css';
7
7
  const b = block('tabs');
8
8
  export const Tabs = (props) => {
9
9
  const { items, activeId, onSelectItem, onDeleteItem, allowDelete = false, className, style, qa, } = props;
@@ -0,0 +1,10 @@
1
+ .g-aikit-tool-footer {
2
+ display: flex;
3
+ justify-content: space-between;
4
+ align-items: center;
5
+ }
6
+ .g-aikit-tool-footer__left {
7
+ display: flex;
8
+ align-items: center;
9
+ gap: var(--g-spacing-2);
10
+ }
@@ -5,7 +5,7 @@ import { isActionConfig } from '../../../utils/actionUtils';
5
5
  import { block } from '../../../utils/cn';
6
6
  import { Loader, Shimmer } from '../../atoms';
7
7
  import { ButtonGroup } from '../ButtonGroup';
8
- import './ToolFooter.scss';
8
+ import './ToolFooter.css';
9
9
  const b = block('tool-footer');
10
10
  export function ToolFooter({ actions, content, showLoader = true, className, qa }) {
11
11
  return (_jsxs("div", { className: b('', className), "data-qa": qa, children: [_jsxs("div", { className: b('left'), children: [showLoader && _jsx(Loader, { view: "loading", size: "xs" }), content && (_jsx(Shimmer, { children: _jsx(Text, { children: content }) }))] }), _jsx(ButtonGroup, { children: actions.map((action, index) => {
@@ -0,0 +1,18 @@
1
+ .g-aikit-tool-header {
2
+ display: flex;
3
+ justify-content: space-between;
4
+ align-items: center;
5
+ height: 24px;
6
+ gap: var(--g-spacing-2);
7
+ }
8
+ .g-aikit-tool-header__left {
9
+ display: flex;
10
+ flex-direction: row;
11
+ align-items: center;
12
+ gap: var(--g-spacing-2);
13
+ }
14
+ .g-aikit-tool-header__right {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: var(--g-spacing-3);
18
+ }
@@ -6,7 +6,7 @@ import { block } from '../../../utils/cn';
6
6
  import { ActionButton } from '../../atoms';
7
7
  import { ButtonGroup } from '../ButtonGroup';
8
8
  import { ToolStatus } from '../ToolStatus';
9
- import './ToolHeader.scss';
9
+ import './ToolHeader.css';
10
10
  const b = block('tool-header');
11
11
  export function ToolHeader(props) {
12
12
  const { toolIcon, toolName, content, actions, status, className, qa } = props;
@@ -3,7 +3,7 @@ import { Text } from '@gravity-ui/uikit';
3
3
  import { block } from '../../../utils/cn';
4
4
  import { ToolIndicator } from '../../atoms';
5
5
  import { i18n } from './i18n';
6
- import './ToolStatus.scss';
6
+ import './ToolStatus.css';
7
7
  const b = block('tool-status');
8
8
  function getIndicatorStatus(status) {
9
9
  if (status === 'success' || status === 'error' || status === 'loading') {
@@ -0,0 +1,6 @@
1
+ .g-aikit-assistant-message__content {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--g-spacing-3);
5
+ width: 100%;
6
+ }
@@ -3,7 +3,7 @@ import type { BaseMessageProps, TAssistantMessage, TMessageContent, TMessageMeta
3
3
  import { type MessageRendererRegistry } from '../../../utils/messageTypeRegistry';
4
4
  import './AssistantMessage.scss';
5
5
  type BaseMessagePick = Pick<BaseMessageProps, 'actions' | 'timestamp' | 'showActionsOnHover' | 'showTimestamp'>;
6
- type AssistantMessagePick<TContent extends TMessageContent> = Pick<TAssistantMessage<TContent, TMessageMetadata>, 'id' | 'content'>;
6
+ type AssistantMessagePick<TContent extends TMessageContent> = Pick<TAssistantMessage<TContent, TMessageMetadata>, 'id' | 'content' | 'userRating'>;
7
7
  export type AssistantMessageProps<TContent extends TMessageContent = never> = BaseMessagePick & AssistantMessagePick<TContent> & {
8
8
  messageRendererRegistry?: MessageRendererRegistry;
9
9
  transformOptions?: OptionsType;
@@ -11,5 +11,5 @@ export type AssistantMessageProps<TContent extends TMessageContent = never> = Ba
11
11
  className?: string;
12
12
  qa?: string;
13
13
  };
14
- export declare function AssistantMessage<TContent extends TMessageContent = never>({ content, actions, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, className, qa, }: AssistantMessageProps<TContent>): import("react/jsx-runtime").JSX.Element | null;
14
+ export declare function AssistantMessage<TContent extends TMessageContent = never>({ content, actions, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, userRating, className, qa, }: AssistantMessageProps<TContent>): import("react/jsx-runtime").JSX.Element | null;
15
15
  export {};
@@ -5,9 +5,9 @@ import { getMessageRenderer, mergeMessageRendererRegistries, } from '../../../ut
5
5
  import { normalizeContent } from '../../../utils/messageUtils';
6
6
  import { BaseMessage } from '../../molecules/BaseMessage';
7
7
  import { createDefaultMessageRegistry } from './defaultMessageTypeRegistry';
8
- import './AssistantMessage.scss';
8
+ import './AssistantMessage.css';
9
9
  const b = block('assistant-message');
10
- export function AssistantMessage({ content, actions, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, className, qa, }) {
10
+ export function AssistantMessage({ content, actions, timestamp, id, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, userRating, className, qa, }) {
11
11
  const registry = useMemo(() => {
12
12
  const defaultRegistry = createDefaultMessageRegistry(transformOptions, shouldParseIncompleteMarkdown);
13
13
  if (messageRendererRegistry) {
@@ -27,5 +27,5 @@ export function AssistantMessage({ content, actions, timestamp, id, messageRende
27
27
  const key = part.id || `${id || 'message'}-part-${partIndex}`;
28
28
  return _jsx(PartComponent, { part: part }, key);
29
29
  };
30
- return (_jsx(BaseMessage, { role: "assistant", actions: actions, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, timestamp: timestamp, className: b(null, className), qa: qa, children: _jsx("div", { className: b('content'), children: parts.map((part, index) => renderPart(part, index)) }) }));
30
+ return (_jsx(BaseMessage, { role: "assistant", actions: actions, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, timestamp: timestamp, userRating: userRating, className: b(null, className), qa: qa, children: _jsx("div", { className: b('content'), children: parts.map((part, index) => renderPart(part, index)) }) }));
31
31
  }
@@ -4,6 +4,7 @@ import type { TMessageContent } from '../../../../types/messages';
4
4
  declare const _default: Meta;
5
5
  export default _default;
6
6
  export declare const Playground: StoryFn<AssistantMessageProps>;
7
+ export declare const WithUserRating: StoryObj<AssistantMessageProps>;
7
8
  export declare const WithToolCall: StoryObj<AssistantMessageProps>;
8
9
  export declare const WithThinkingContent: StoryObj<AssistantMessageProps>;
9
10
  interface CustomMessageData {
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /* eslint-disable no-console */
3
3
  import { Pencil } from '@gravity-ui/icons';
4
4
  import { Icon, Text } from '@gravity-ui/uikit';
@@ -45,6 +45,11 @@ export default {
45
45
  control: 'boolean',
46
46
  description: 'Show timestamp in actions area',
47
47
  },
48
+ userRating: {
49
+ control: 'radio',
50
+ options: [undefined, 'like', 'dislike'],
51
+ description: 'Current user rating (filled like/unlike icons when set)',
52
+ },
48
53
  className: {
49
54
  control: 'text',
50
55
  description: 'Additional CSS class',
@@ -102,6 +107,12 @@ Playground.args = {
102
107
  timestamp: simpleMessage.timestamp,
103
108
  id: simpleMessage.id,
104
109
  };
110
+ export const WithUserRating = {
111
+ render: (args) => (_jsxs(_Fragment, { children: [_jsx(ShowcaseItem, { title: "Rated like", width: "400px", children: _jsx(AssistantMessage, Object.assign({}, args, { content: "This message has userRating: like (thumb up filled).", actions: actions, userRating: "like" })) }), _jsx(ShowcaseItem, { title: "Rated dislike", width: "400px", children: _jsx(AssistantMessage, Object.assign({}, args, { content: "This message has userRating: dislike (thumb down filled).", actions: actions, userRating: "dislike" })) })] })),
112
+ decorators: [
113
+ (Story) => (_jsx(ContentWrapper, { children: _jsx(Showcase, { children: _jsx(Story, {}) }) })),
114
+ ],
115
+ };
105
116
  export const WithToolCall = {
106
117
  render: (args) => (_jsx(ShowcaseItem, { title: "With Tool Call", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(AssistantMessage, Object.assign({}, args, { content: multiPartMessage.content, actions: actions, timestamp: multiPartMessage.timestamp, id: multiPartMessage.id })) }) })),
107
118
  decorators: [
@@ -0,0 +1,40 @@
1
+ .g-aikit-header {
2
+ display: flex;
3
+ align-items: center;
4
+ justify-content: space-between;
5
+ gap: var(--g-spacing-2);
6
+ width: 100%;
7
+ box-sizing: border-box;
8
+ background: var(--g-aikit-header-background);
9
+ }
10
+ .g-aikit-header__icon {
11
+ display: flex;
12
+ align-items: center;
13
+ flex-shrink: 0;
14
+ }
15
+ .g-aikit-header__title-container {
16
+ display: flex;
17
+ gap: var(--g-spacing-1);
18
+ flex: 1;
19
+ align-items: baseline;
20
+ }
21
+ .g-aikit-header__title-container_position_left {
22
+ justify-content: flex-start;
23
+ }
24
+ .g-aikit-header__title-container_position_center {
25
+ justify-content: center;
26
+ }
27
+ .g-aikit-header__title {
28
+ text-overflow: ellipsis;
29
+ white-space: nowrap;
30
+ overflow: hidden;
31
+ flex-shrink: 0;
32
+ }
33
+ .g-aikit-header__preview {
34
+ display: flex;
35
+ align-items: center;
36
+ flex-shrink: 0;
37
+ }
38
+ .g-aikit-header__action-button {
39
+ flex-shrink: 0;
40
+ }
@@ -9,7 +9,7 @@ import { ButtonGroup } from '../../molecules';
9
9
  import { i18n } from './i18n';
10
10
  import { HeaderAction } from './types';
11
11
  import { useHeader } from './useHeader';
12
- import './Header.scss';
12
+ import './Header.css';
13
13
  const b = block('header');
14
14
  // Icons for base actions
15
15
  const ACTION_ICONS = {
@@ -0,0 +1,26 @@
1
+ .g-aikit-message-list {
2
+ overflow-y: auto;
3
+ display: flex;
4
+ flex-direction: column;
5
+ min-height: 0;
6
+ flex: 1;
7
+ align-self: stretch;
8
+ }
9
+ .g-aikit-message-list__messages {
10
+ display: flex;
11
+ flex-direction: column;
12
+ gap: var(--g-spacing-4);
13
+ }
14
+ .g-aikit-message-list__retry-button {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: var(--g-spacing-1);
18
+ }
19
+ .g-aikit-message-list__loader, .g-aikit-message-list__error-alert {
20
+ margin-top: var(--g-spacing-4);
21
+ }
22
+ .g-aikit-message-list__load-trigger {
23
+ display: flex;
24
+ justify-content: center;
25
+ padding: var(--g-spacing-2);
26
+ }
@@ -7,7 +7,7 @@ import { Loader } from '../../atoms/Loader';
7
7
  import { AssistantMessage } from '../AssistantMessage';
8
8
  import { UserMessage } from '../UserMessage';
9
9
  import { ErrorAlert } from './ErrorAlert';
10
- import './MessageList.scss';
10
+ import './MessageList.css';
11
11
  const b = block('message-list');
12
12
  export function MessageList({ messages, messageRendererRegistry, transformOptions, shouldParseIncompleteMarkdown, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, loaderStatuses = ['submitted', 'streaming_loading'], className, qa, status, errorMessage, onRetry, hasPreviousMessages = false, onLoadPreviousMessages, }) {
13
13
  const isStreaming = status === 'streaming' || status === 'streaming_loading';
@@ -34,7 +34,7 @@ export function MessageList({ messages, messageRendererRegistry, transformOption
34
34
  const actions = showActions && !hasOnlyThinkingContent(message.content)
35
35
  ? resolveMessageActions(message, assistantActions)
36
36
  : undefined;
37
- return (_jsx(AssistantMessage, { content: message.content, actions: actions, timestamp: message.timestamp, id: message.id, messageRendererRegistry: messageRendererRegistry, transformOptions: transformOptions, shouldParseIncompleteMarkdown: shouldParseIncompleteMarkdown, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp }, message.id || `message-${index}`));
37
+ return (_jsx(AssistantMessage, { content: message.content, actions: actions, timestamp: message.timestamp, id: message.id, messageRendererRegistry: messageRendererRegistry, transformOptions: transformOptions, shouldParseIncompleteMarkdown: shouldParseIncompleteMarkdown, showActionsOnHover: showActionsOnHover, showTimestamp: showTimestamp, userRating: message.userRating }, message.id || `message-${index}`));
38
38
  }
39
39
  return null;
40
40
  };
@@ -22,4 +22,5 @@ type ChartMessageContent = TMessageContent<'chart', ChartMessageData>;
22
22
  export declare const WithCustomMessageType: StoryObj<MessageListProps<ChartMessageContent>>;
23
23
  export declare const WithStreamingMessage: StoryObj<MessageListProps>;
24
24
  export declare const WithDefaultActions: StoryObj<MessageListProps>;
25
+ export declare const WithUserRating: StoryObj<MessageListProps>;
25
26
  export declare const WithPreviousMessages: StoryObj<MessageListProps>;
@@ -223,14 +223,14 @@ export const WithDefaultActions = {
223
223
  render: (args) => {
224
224
  const userActions = [
225
225
  {
226
- actionType: BaseMessageActionType.Edit,
226
+ type: BaseMessageActionType.Edit,
227
227
  onClick: (message) => {
228
228
  // eslint-disable-next-line no-console
229
229
  console.log('Edit user message:', message.id);
230
230
  },
231
231
  },
232
232
  {
233
- actionType: BaseMessageActionType.Delete,
233
+ type: BaseMessageActionType.Delete,
234
234
  onClick: (message) => {
235
235
  // eslint-disable-next-line no-console
236
236
  console.log('Delete user message:', message.id);
@@ -239,14 +239,14 @@ export const WithDefaultActions = {
239
239
  ];
240
240
  const assistantActions = [
241
241
  {
242
- actionType: BaseMessageActionType.Copy,
242
+ type: BaseMessageActionType.Copy,
243
243
  onClick: (message) => {
244
244
  // eslint-disable-next-line no-console
245
245
  console.log('Copy assistant message:', message.id);
246
246
  },
247
247
  },
248
248
  {
249
- actionType: BaseMessageActionType.Like,
249
+ type: BaseMessageActionType.Like,
250
250
  onClick: (message) => {
251
251
  // eslint-disable-next-line no-console
252
252
  console.log('Like assistant message:', message.id);
@@ -291,6 +291,56 @@ export const WithDefaultActions = {
291
291
  },
292
292
  decorators: defaultDecorators,
293
293
  };
294
+ export const WithUserRating = {
295
+ render: (args) => {
296
+ const assistantActions = [
297
+ {
298
+ type: BaseMessageActionType.Copy,
299
+ onClick: (message) => {
300
+ // eslint-disable-next-line no-console
301
+ console.log('Copy:', message.id);
302
+ },
303
+ },
304
+ {
305
+ type: BaseMessageActionType.Like,
306
+ onClick: (message) => {
307
+ // eslint-disable-next-line no-console
308
+ console.log('Like:', message.id);
309
+ },
310
+ },
311
+ {
312
+ type: BaseMessageActionType.Unlike,
313
+ onClick: (message) => {
314
+ // eslint-disable-next-line no-console
315
+ console.log('Unlike:', message.id);
316
+ },
317
+ },
318
+ ];
319
+ return (_jsx(ShowcaseItem, { title: "With User Rating", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(MessageList, Object.assign({}, args, { messages: [
320
+ {
321
+ id: 'user-1',
322
+ role: 'user',
323
+ timestamp: '2024-01-01T00:00:00Z',
324
+ content: 'Compare these two answers.',
325
+ },
326
+ {
327
+ id: 'assistant-like',
328
+ role: 'assistant',
329
+ timestamp: '2024-01-01T00:00:01Z',
330
+ content: 'This message is rated as liked (filled thumb up).',
331
+ userRating: 'like',
332
+ },
333
+ {
334
+ id: 'assistant-dislike',
335
+ role: 'assistant',
336
+ timestamp: '2024-01-01T00:00:02Z',
337
+ content: 'This message is rated as disliked (filled thumb down).',
338
+ userRating: 'dislike',
339
+ },
340
+ ], assistantActions: assistantActions, status: "ready" })) }) }));
341
+ },
342
+ decorators: defaultDecorators,
343
+ };
294
344
  export const WithPreviousMessages = {
295
345
  render: (args) => {
296
346
  const createMessage = (num) => {
@@ -0,0 +1,50 @@
1
+ .g-aikit-prompt-input {
2
+ border-radius: var(--g-border-radius-xl);
3
+ border: 1px solid var(--g-color-line-generic);
4
+ background: var(--g-color-base-float);
5
+ overflow: hidden;
6
+ }
7
+ .g-aikit-prompt-input_view_simple {
8
+ display: flex;
9
+ flex-direction: column;
10
+ padding: var(--g-spacing-1) var(--g-spacing-1) var(--g-spacing-1) var(--g-spacing-3);
11
+ }
12
+ .g-aikit-prompt-input_view_full {
13
+ display: flex;
14
+ padding: var(--g-spacing-2);
15
+ flex-direction: column;
16
+ align-items: flex-start;
17
+ gap: var(--g-spacing-2);
18
+ }
19
+ .g-aikit-prompt-input_view_full .g-aikit-prompt-input__textarea {
20
+ padding-top: 0;
21
+ }
22
+ .g-aikit-prompt-input__content {
23
+ display: flex;
24
+ align-items: flex-end;
25
+ gap: var(--g-spacing-2);
26
+ width: 100%;
27
+ }
28
+ .g-aikit-prompt-input__panel-wrapper {
29
+ background: var(--g-color-base-simple-hover-solid);
30
+ border-radius: var(--g-border-radius-xl);
31
+ }
32
+ .g-aikit-prompt-input__panel {
33
+ overflow: hidden;
34
+ transition: max-height 0.3s ease-in-out, opacity 0.3s ease-in-out, margin 0.3s ease-in-out;
35
+ will-change: max-height, opacity, margin;
36
+ max-height: 0;
37
+ opacity: 0;
38
+ margin: 0;
39
+ }
40
+ .g-aikit-prompt-input__panel_open {
41
+ max-height: var(--g-aikit-prompt-input-panel-max-height);
42
+ opacity: 1;
43
+ }
44
+ .g-aikit-prompt-input__suggestions-wrapper {
45
+ align-self: stretch;
46
+ flex: 1;
47
+ }
48
+ .g-aikit-prompt-input__suggestions {
49
+ padding-bottom: var(--g-spacing-2);
50
+ }
@@ -4,7 +4,7 @@ import { PromptInputSimple } from './PromptInputSimple';
4
4
  import { PromptInputWithPanels } from './PromptInputWithPanels';
5
5
  import { PromptInputWithSuggestions } from './PromptInputWithSuggestions';
6
6
  import { usePromptInput } from './usePromptInput';
7
- import './PromptInput.scss';
7
+ import './PromptInput.css';
8
8
  /**
9
9
  * PromptInput component - a flexible input component for chat interfaces
10
10
  * with support for simple and full views, attachments, suggestions, and expandable panels
@@ -0,0 +1,20 @@
1
+ .g-aikit-thinking-message {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--g-spacing-2);
5
+ padding: var(--g-spacing-1) 0 var(--g-spacing-1) var(--g-spacing-4);
6
+ border-left: 2px solid var(--g-color-line-generic);
7
+ }
8
+ .g-aikit-thinking-message__buttons {
9
+ display: flex;
10
+ align-items: center;
11
+ gap: var(--g-spacing-2);
12
+ }
13
+ .g-aikit-thinking-message__container {
14
+ display: flex;
15
+ flex-direction: column;
16
+ gap: var(--g-spacing-6);
17
+ }
18
+ .g-aikit-thinking-message__content {
19
+ color: var(--g-color-text-complementary);
20
+ }
@@ -7,7 +7,7 @@ import { block } from '../../../utils/cn';
7
7
  import { ActionButton } from '../../atoms';
8
8
  import { Loader } from '../../atoms/Loader';
9
9
  import { useThinkingMessage } from './useThinkingMessage';
10
- import './ThinkingMessage.scss';
10
+ import './ThinkingMessage.css';
11
11
  const b = block('thinking-message');
12
12
  /**
13
13
  * ThinkingMessage component displays AI model's internal reasoning process.
@@ -0,0 +1,13 @@
1
+ .g-aikit-tool-message {
2
+ padding: var(--g-spacing-2);
3
+ border-radius: var(--g-border-radius-xl);
4
+ width: 100%;
5
+ }
6
+ .g-aikit-tool-message_waiting {
7
+ border-color: var(--g-color-line-brand);
8
+ }
9
+ .g-aikit-tool-message__container {
10
+ display: flex;
11
+ flex-direction: column;
12
+ gap: var(--g-spacing-2);
13
+ }
@@ -3,7 +3,7 @@ import { Card } from '@gravity-ui/uikit';
3
3
  import { useToolMessage } from '../../../hooks/useToolMessage';
4
4
  import { block } from '../../../utils/cn';
5
5
  import { ToolFooter, ToolHeader } from '../../molecules';
6
- import './ToolMessage.scss';
6
+ import './ToolMessage.css';
7
7
  const b = block('tool-message');
8
8
  export function ToolMessage(props) {
9
9
  const { toolName, className, qa, bodyContent, status, toolIcon, headerContent } = props;
@@ -0,0 +1,10 @@
1
+ .g-aikit-user-message {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--g-spacing-1);
5
+ align-items: flex-end;
6
+ }
7
+
8
+ .g-aikit-user-message_format_plain {
9
+ white-space: pre-wrap;
10
+ }
@@ -4,7 +4,7 @@ import { block, modsClassName } from '../../../utils/cn';
4
4
  import { MarkdownRenderer } from '../../atoms/MarkdownRenderer';
5
5
  import { MessageBalloon } from '../../atoms/MessageBalloon';
6
6
  import { BaseMessage } from '../../molecules/BaseMessage';
7
- import './UserMessage.scss';
7
+ import './UserMessage.css';
8
8
  const b = block('user-message');
9
9
  export const UserMessage = (props) => {
10
10
  const { className, qa, content, actions, showActionsOnHover, showAvatar, avatarUrl = '', timestamp = '', showTimestamp, format = 'plain', transformOptions, shouldParseIncompleteMarkdown, } = props;