@gravity-ui/aikit 0.6.0 → 1.0.1

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 (109) hide show
  1. package/dist/components/atoms/ActionButton/__stories__/ActionButton.stories.d.ts +8 -0
  2. package/dist/components/atoms/ActionButton/__stories__/ActionButton.stories.js +48 -0
  3. package/dist/components/atoms/Alert/__stories__/Alert.stories.d.ts +10 -0
  4. package/dist/components/atoms/Alert/__stories__/Alert.stories.js +72 -0
  5. package/dist/components/atoms/ChatDate/__stories__/ChatDate.stories.d.ts +16 -0
  6. package/dist/components/atoms/ChatDate/__stories__/ChatDate.stories.js +83 -0
  7. package/dist/components/atoms/ContextIndicator/__stories__/ContextIndicator.stories.d.ts +17 -0
  8. package/dist/components/atoms/ContextIndicator/__stories__/ContextIndicator.stories.js +72 -0
  9. package/dist/components/atoms/ContextItem/__stories__/ContextItem.stories.d.ts +8 -0
  10. package/dist/components/atoms/ContextItem/__stories__/ContextItem.stories.js +36 -0
  11. package/dist/components/atoms/DiffStat/__stories__/DiffStat.stories.d.ts +8 -0
  12. package/dist/components/atoms/DiffStat/__stories__/DiffStat.stories.js +45 -0
  13. package/dist/components/atoms/Disclaimer/__stories__/Disclaimer.stories.d.ts +12 -0
  14. package/dist/components/atoms/Disclaimer/__stories__/Disclaimer.stories.js +64 -0
  15. package/dist/components/atoms/Loader/__stories__/Loader.stories.d.ts +8 -0
  16. package/dist/components/atoms/Loader/__stories__/Loader.stories.js +47 -0
  17. package/dist/components/atoms/MarkdownRenderer/__stories__/MarkdownRenderer.stories.d.ts +6 -0
  18. package/dist/components/atoms/MarkdownRenderer/__stories__/MarkdownRenderer.stories.js +49 -0
  19. package/dist/components/atoms/MessageBalloon/__stories__/MessageBalloon.stories.d.ts +6 -0
  20. package/dist/components/atoms/MessageBalloon/__stories__/MessageBalloon.stories.js +32 -0
  21. package/dist/components/atoms/Shimmer/__stories__/Shimmer.stories.d.ts +5 -0
  22. package/dist/components/atoms/Shimmer/__stories__/Shimmer.stories.js +28 -0
  23. package/dist/components/atoms/SubmitButton/__stories__/SubmitButton.stories.d.ts +13 -0
  24. package/dist/components/atoms/SubmitButton/__stories__/SubmitButton.stories.js +98 -0
  25. package/dist/components/atoms/ToolIndicator/__stories__/ToolIndicator.stories.d.ts +9 -0
  26. package/dist/components/atoms/ToolIndicator/__stories__/ToolIndicator.stories.js +34 -0
  27. package/dist/components/molecules/BaseMessage/__stories__/BaseMessage.stories.d.ts +9 -0
  28. package/dist/components/molecules/BaseMessage/__stories__/BaseMessage.stories.js +77 -0
  29. package/dist/components/molecules/BaseMessage/index.d.ts +1 -1
  30. package/dist/components/molecules/BaseMessage/index.js +51 -20
  31. package/dist/components/molecules/ButtonGroup/__stories__/ButtonGroup.stories.d.ts +6 -0
  32. package/dist/components/molecules/ButtonGroup/__stories__/ButtonGroup.stories.js +44 -0
  33. package/dist/components/molecules/PromptInputBody/__stories__/PromptInputBody.stories.d.ts +11 -0
  34. package/dist/components/molecules/PromptInputBody/__stories__/PromptInputBody.stories.js +62 -0
  35. package/dist/components/molecules/PromptInputFooter/__stories__/PromptInputFooter.stories.d.ts +11 -0
  36. package/dist/components/molecules/PromptInputFooter/__stories__/PromptInputFooter.stories.js +96 -0
  37. package/dist/components/molecules/PromptInputHeader/__stories__/PromptInputHeader.stories.d.ts +15 -0
  38. package/dist/components/molecules/PromptInputHeader/__stories__/PromptInputHeader.stories.js +123 -0
  39. package/dist/components/molecules/PromptInputPanel/__stories__/PromptInputPanel.stories.d.ts +8 -0
  40. package/dist/components/molecules/PromptInputPanel/__stories__/PromptInputPanel.stories.js +38 -0
  41. package/dist/components/molecules/Suggestions/__stories__/Suggestions.stories.d.ts +22 -0
  42. package/dist/components/molecules/Suggestions/__stories__/Suggestions.stories.js +182 -0
  43. package/dist/components/molecules/Tabs/__stories__/Tabs.stories.d.ts +9 -0
  44. package/dist/components/molecules/Tabs/__stories__/Tabs.stories.js +103 -0
  45. package/dist/components/molecules/ToolFooter/__stories__/ToolFooter.stories.d.ts +7 -0
  46. package/dist/components/molecules/ToolFooter/__stories__/ToolFooter.stories.js +58 -0
  47. package/dist/components/molecules/ToolFooter/index.js +8 -1
  48. package/dist/components/molecules/ToolHeader/__stories__/ToolHeader.stories.d.ts +8 -0
  49. package/dist/components/molecules/ToolHeader/__stories__/ToolHeader.stories.js +59 -0
  50. package/dist/components/molecules/ToolHeader/index.js +10 -1
  51. package/dist/components/molecules/ToolStatus/__stories__/ToolStatus.stories.d.ts +9 -0
  52. package/dist/components/molecules/ToolStatus/__stories__/ToolStatus.stories.js +44 -0
  53. package/dist/components/organisms/AssistantMessage/__stories__/AssistantMessage.stories.d.ts +13 -0
  54. package/dist/components/organisms/AssistantMessage/__stories__/AssistantMessage.stories.js +151 -0
  55. package/dist/components/organisms/Header/Header.js +16 -17
  56. package/dist/components/organisms/Header/__stories__/Header.stories.d.ts +15 -0
  57. package/dist/components/organisms/Header/__stories__/Header.stories.js +159 -0
  58. package/dist/components/organisms/Header/types.d.ts +2 -3
  59. package/dist/components/organisms/Header/useHeader.d.ts +2 -4
  60. package/dist/components/organisms/Header/useHeader.js +2 -24
  61. package/dist/components/organisms/MessageList/MessageList.js +5 -6
  62. package/dist/components/organisms/MessageList/__stories__/MessageList.stories.d.ts +25 -0
  63. package/dist/components/organisms/MessageList/__stories__/MessageList.stories.js +340 -0
  64. package/dist/components/organisms/PromptInput/__stories__/PromptInput.stories.d.ts +19 -0
  65. package/dist/components/organisms/PromptInput/__stories__/PromptInput.stories.js +304 -0
  66. package/dist/components/organisms/ThinkingMessage/__stories__/ThinkingMessage.stories.d.ts +12 -0
  67. package/dist/components/organisms/ThinkingMessage/__stories__/ThinkingMessage.stories.js +105 -0
  68. package/dist/components/organisms/ToolMessage/__stories__/ToolMessage.stories.d.ts +11 -0
  69. package/dist/components/organisms/ToolMessage/__stories__/ToolMessage.stories.js +70 -0
  70. package/dist/components/organisms/UserMessage/__stories__/UserMessage.stories.d.ts +9 -0
  71. package/dist/components/organisms/UserMessage/__stories__/UserMessage.stories.js +118 -0
  72. package/dist/components/pages/ChatContainer/__stories__/ChatContainer.stories.d.ts +79 -0
  73. package/dist/components/pages/ChatContainer/__stories__/ChatContainer.stories.js +1006 -0
  74. package/dist/components/templates/ChatContent/__stories__/ChatContent.stories.d.ts +14 -0
  75. package/dist/components/templates/ChatContent/__stories__/ChatContent.stories.js +315 -0
  76. package/dist/components/templates/EmptyContainer/__stories__/EmptyContainer.stories.d.ts +20 -0
  77. package/dist/components/templates/EmptyContainer/__stories__/EmptyContainer.stories.js +250 -0
  78. package/dist/components/templates/History/ChatItem.d.ts +2 -2
  79. package/dist/components/templates/History/ChatItem.js +2 -5
  80. package/dist/components/templates/History/History.scss +13 -9
  81. package/dist/components/templates/History/HistoryList.d.ts +3 -1
  82. package/dist/components/templates/History/HistoryList.js +9 -5
  83. package/dist/components/templates/History/__stories__/History.stories.d.ts +18 -0
  84. package/dist/components/templates/History/__stories__/History.stories.js +289 -0
  85. package/dist/demo/ContentWrapper/ContentWrapper.d.ts +4 -0
  86. package/dist/demo/ContentWrapper/ContentWrapper.js +9 -0
  87. package/dist/demo/ContentWrapper/index.d.ts +1 -0
  88. package/dist/demo/ContentWrapper/index.js +1 -0
  89. package/dist/demo/Showcase/Showcase.d.ts +9 -0
  90. package/dist/demo/Showcase/Showcase.js +7 -0
  91. package/dist/demo/Showcase/index.d.ts +1 -0
  92. package/dist/demo/Showcase/index.js +1 -0
  93. package/dist/demo/ShowcaseItem/ShowcaseItem.d.ts +8 -0
  94. package/dist/demo/ShowcaseItem/ShowcaseItem.js +7 -0
  95. package/dist/demo/ShowcaseItem/index.d.ts +1 -0
  96. package/dist/demo/ShowcaseItem/index.js +1 -0
  97. package/dist/demo/SwapArea/SwapArea.d.ts +2 -0
  98. package/dist/demo/SwapArea/SwapArea.js +7 -0
  99. package/dist/demo/SwapArea/index.d.ts +1 -0
  100. package/dist/demo/SwapArea/index.js +1 -0
  101. package/dist/hooks/useSmartScroll.d.ts +7 -2
  102. package/dist/hooks/useSmartScroll.js +24 -22
  103. package/dist/types/common.d.ts +13 -5
  104. package/dist/types/messages.d.ts +9 -6
  105. package/dist/utils/actionUtils.d.ts +14 -0
  106. package/dist/utils/actionUtils.js +17 -0
  107. package/dist/utils/messageUtils.d.ts +7 -9
  108. package/dist/utils/messageUtils.js +7 -1
  109. package/package.json +12 -7
@@ -1,4 +1,4 @@
1
- import React, { useMemo } from 'react';
1
+ import { useMemo } from 'react';
2
2
  import { HeaderAction } from './types';
3
3
  export function useHeader(props) {
4
4
  const { icon, title, preview, baseActions = [], handleNewChat, handleHistoryToggle, handleClose, handleFolding, foldingState = 'opened', additionalActions = [], titlePosition = 'left', withIcon = true, showTitle = true, className, historyButtonRef, } = props;
@@ -11,7 +11,6 @@ export function useHeader(props) {
11
11
  actions.push({
12
12
  id: action,
13
13
  type: 'base',
14
- content: null, // Will be rendered in component
15
14
  onClick: () => {
16
15
  const newState = foldingState === 'opened' ? 'collapsed' : 'opened';
17
16
  handleFolding(newState);
@@ -31,39 +30,18 @@ export function useHeader(props) {
31
30
  actions.push({
32
31
  id: action,
33
32
  type: 'base',
34
- content: null, // Will be rendered in component
35
33
  onClick: handler,
36
34
  });
37
35
  }
38
36
  });
39
37
  return actions;
40
38
  }, [baseActions, handleNewChat, handleHistoryToggle, handleClose, handleFolding, foldingState]);
41
- // Build additional actions
42
- const additionalActionsList = useMemo(() => {
43
- return additionalActions.map((action, index) => {
44
- if (React.isValidElement(action)) {
45
- return {
46
- id: `additional-${index}`,
47
- type: 'additional',
48
- content: action,
49
- };
50
- }
51
- // If it's ButtonProps, create a button
52
- const buttonProps = action;
53
- return {
54
- id: buttonProps.qa || `additional-${index}`,
55
- type: 'additional',
56
- content: null, // Will be rendered in component
57
- buttonProps,
58
- };
59
- });
60
- }, [additionalActions]);
61
39
  return {
62
40
  title,
63
41
  preview,
64
42
  icon,
65
43
  baseActions: baseActionsList,
66
- additionalActions: additionalActionsList,
44
+ additionalActions,
67
45
  titlePosition,
68
46
  withIcon,
69
47
  showTitle,
@@ -1,5 +1,4 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect } from 'react';
3
2
  import { useScrollPreservation, useSmartScroll } from '../../../hooks';
4
3
  import { isAssistantMessage, isUserMessage, resolveMessageActions, } from '../../../utils';
5
4
  import { block } from '../../../utils/cn';
@@ -13,12 +12,12 @@ const b = block('message-list');
13
12
  export function MessageList({ messages, messageRendererRegistry, transformOptions, showActionsOnHover, showTimestamp, showAvatar, userActions, assistantActions, loaderStatuses = ['submitted'], className, qa, status, errorMessage, onRetry, hasPreviousMessages = false, onLoadPreviousMessages, }) {
14
13
  const isStreaming = status === 'streaming';
15
14
  const isSubmitted = status === 'submitted';
16
- const messagesCount = messages.length;
17
15
  const showLoader = status && loaderStatuses.includes(status);
18
- const { containerRef, endRef, scrollToBottom } = useSmartScroll(isStreaming, messagesCount);
19
- useEffect(() => {
20
- scrollToBottom();
21
- }, []);
16
+ const { containerRef, endRef } = useSmartScroll({
17
+ isStreaming: isStreaming || isSubmitted,
18
+ messagesCount: messages.length,
19
+ status,
20
+ });
22
21
  // Preserve scroll position when older messages are loaded
23
22
  useScrollPreservation(containerRef, messages.length);
24
23
  const renderMessage = (message, index) => {
@@ -0,0 +1,25 @@
1
+ import { Meta, StoryFn, StoryObj } from '@storybook/react-webpack5';
2
+ import { type MessageListProps } from '..';
3
+ import type { TMessageContent } from '../../../../types/messages';
4
+ declare const _default: Meta;
5
+ export default _default;
6
+ export declare const Playground: StoryFn<MessageListProps>;
7
+ export declare const WithSubmittedStatus: StoryObj<MessageListProps>;
8
+ export declare const WithErrorMessage: StoryObj<MessageListProps>;
9
+ export declare const WithToolMessage: StoryObj<MessageListProps>;
10
+ interface ChartMessageData {
11
+ chartData: {
12
+ labels: string[];
13
+ datasets: Array<{
14
+ label: string;
15
+ data: number[];
16
+ color?: string;
17
+ }>;
18
+ };
19
+ chartType: 'line' | 'bar' | 'pie';
20
+ }
21
+ type ChartMessageContent = TMessageContent<'chart', ChartMessageData>;
22
+ export declare const WithCustomMessageType: StoryObj<MessageListProps<ChartMessageContent>>;
23
+ export declare const WithStreamingMessage: StoryObj<MessageListProps>;
24
+ export declare const WithDefaultActions: StoryObj<MessageListProps>;
25
+ export declare const WithPreviousMessages: StoryObj<MessageListProps>;
@@ -0,0 +1,340 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
+ import { Pencil } from '@gravity-ui/icons';
4
+ import { Icon, Text } from '@gravity-ui/uikit';
5
+ import { MessageList } from '..';
6
+ import { ContentWrapper } from '../../../../demo/ContentWrapper';
7
+ import { Showcase } from '../../../../demo/Showcase';
8
+ import { ShowcaseItem } from '../../../../demo/ShowcaseItem';
9
+ import { createMessageRendererRegistry, registerMessageRenderer, } from '../../../../utils/messageTypeRegistry';
10
+ import { BaseMessageActionType } from '../../../molecules/BaseMessage';
11
+ import MDXDocs from './Docs.mdx';
12
+ export default {
13
+ title: 'organisms/MessageList',
14
+ component: MessageList,
15
+ parameters: {
16
+ docs: {
17
+ page: MDXDocs,
18
+ },
19
+ },
20
+ argTypes: {
21
+ messages: {
22
+ control: 'object',
23
+ description: 'Array of messages to render',
24
+ },
25
+ messageRendererRegistry: {
26
+ control: false,
27
+ description: 'Custom message renderer registry',
28
+ },
29
+ showActionsOnHover: {
30
+ control: 'boolean',
31
+ description: 'Show action buttons on hover for all messages',
32
+ },
33
+ showTimestamp: {
34
+ control: 'boolean',
35
+ description: 'Show timestamp for all messages',
36
+ },
37
+ showAvatar: {
38
+ control: 'boolean',
39
+ description: 'Show avatar for user messages',
40
+ },
41
+ className: {
42
+ control: 'text',
43
+ description: 'Additional CSS class',
44
+ },
45
+ qa: {
46
+ control: 'text',
47
+ description: 'QA/test identifier',
48
+ },
49
+ },
50
+ };
51
+ const defaultDecorators = [
52
+ (StoryComponent) => (_jsx(Showcase, { children: _jsx(StoryComponent, {}) })),
53
+ ];
54
+ const userMessage = {
55
+ id: '1',
56
+ role: 'user',
57
+ timestamp: '2024-01-01T00:00:00Z',
58
+ content: 'Hello, how are you?',
59
+ };
60
+ const assistantMessage = {
61
+ id: '2',
62
+ role: 'assistant',
63
+ timestamp: '2024-01-01T00:00:01Z',
64
+ content: 'Hi! I am doing well, thank you for asking.',
65
+ };
66
+ export const Playground = (args) => (_jsx(ContentWrapper, { width: "480px", children: _jsx(MessageList, Object.assign({}, args)) }));
67
+ Playground.args = {
68
+ messages: [userMessage, assistantMessage],
69
+ };
70
+ export const WithSubmittedStatus = {
71
+ render: (args) => (_jsx(ShowcaseItem, { title: "With Submitted Status", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(MessageList, Object.assign({}, args, { messages: [userMessage], status: "submitted" })) }) })),
72
+ };
73
+ export const WithErrorMessage = {
74
+ render: (args) => (_jsx(ShowcaseItem, { title: "With Error Message", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(MessageList, Object.assign({}, args, { messages: [userMessage], status: "error",
75
+ // eslint-disable-next-line no-console
76
+ onRetry: () => console.log('retry') })) }) })),
77
+ };
78
+ const toolIcon = _jsx(Icon, { data: Pencil });
79
+ const toolHeaderContent = (_jsx(Text, { color: "secondary", variant: "body-1", children: "expectScreenshotFixture.ts" }));
80
+ export const WithToolMessage = {
81
+ render: (args) => (_jsx(ShowcaseItem, { title: "With Tool Message", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(MessageList, Object.assign({}, args, { messages: [
82
+ {
83
+ role: 'user',
84
+ content: 'Analyze the project and suggest a better solution to implement a feature-name',
85
+ },
86
+ {
87
+ role: 'assistant',
88
+ content: [
89
+ {
90
+ type: 'text',
91
+ data: {
92
+ text: "I'll scan the SCSS structure: global styles and mixins, theme files, and a couple of component styles. I'll also search for the custom Sass function usage and theming patterns.",
93
+ },
94
+ },
95
+ {
96
+ type: 'tool',
97
+ data: {
98
+ toolName: 'Reading',
99
+ status: 'success',
100
+ toolIcon,
101
+ expandable: true,
102
+ headerContent: toolHeaderContent,
103
+ },
104
+ },
105
+ {
106
+ type: 'text',
107
+ data: {
108
+ text: "Absolutely! Here are some suggestions for improving the SCSS structure: \n\n- Consider organizing global styles and mixins into separate directories for better modularity. \n- Group theme files and component styles to simplify maintenance. \n- Use consistent naming patterns for custom Sass functions and variables. \n- Leverage nesting carefully to avoid deeply nested selectors and improve readability. \n- Document theming patterns to ease onboarding for new contributors.\n\nLet me know if you'd like examples or more details on any point!",
109
+ },
110
+ },
111
+ ],
112
+ },
113
+ ] })) }) })),
114
+ decorators: defaultDecorators,
115
+ };
116
+ const ChartMessageView = ({ part }) => {
117
+ const { chartData, chartType } = part.data;
118
+ return (_jsxs("div", { style: {
119
+ padding: '16px',
120
+ border: '1px solid var(--g-color-line-generic)',
121
+ borderRadius: '8px',
122
+ backgroundColor: 'var(--g-color-base-float)',
123
+ }, children: [_jsxs("div", { style: { marginBottom: '8px', fontWeight: 'bold' }, children: ["Chart: ", chartType] }), _jsxs("div", { style: { fontSize: '12px', color: 'var(--g-color-text-secondary)' }, children: ["Labels: ", chartData.labels.join(', ')] }), _jsxs("div", { style: { fontSize: '12px', color: 'var(--g-color-text-secondary)' }, children: ["Datasets: ", chartData.datasets.length] })] }));
124
+ };
125
+ export const WithCustomMessageType = {
126
+ render: (args) => {
127
+ const customRegistry = createMessageRendererRegistry();
128
+ registerMessageRenderer(customRegistry, 'chart', {
129
+ component: ChartMessageView,
130
+ });
131
+ return (_jsx(ShowcaseItem, { title: "With Custom Message Type", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(MessageList, Object.assign({}, args, { messages: [
132
+ {
133
+ id: 'user-1',
134
+ role: 'user',
135
+ timestamp: '2024-01-01T00:00:00Z',
136
+ content: 'Hi! Can you show me the sales statistics for the first months of the year?',
137
+ },
138
+ {
139
+ id: 'assistant-1',
140
+ role: 'assistant',
141
+ timestamp: '2024-01-01T00:00:02Z',
142
+ content: [
143
+ {
144
+ type: 'text',
145
+ data: {
146
+ text: 'Sure! Here is a bar chart showing sales statistics by month. As you can see, February had the highest sales.',
147
+ },
148
+ },
149
+ {
150
+ type: 'chart',
151
+ data: {
152
+ chartData: {
153
+ labels: ['January', 'February', 'March', 'April'],
154
+ datasets: [
155
+ {
156
+ label: 'Sales',
157
+ data: [12, 19, 3, 5],
158
+ color: '#0077ff',
159
+ },
160
+ ],
161
+ },
162
+ chartType: 'bar',
163
+ },
164
+ },
165
+ ],
166
+ },
167
+ ], messageRendererRegistry: customRegistry })) }) }));
168
+ },
169
+ decorators: defaultDecorators,
170
+ };
171
+ const streamingText = 'React Hooks are functions that let you use state and other React features without writing a class. ' +
172
+ 'The most commonly used hooks are:\n\n' +
173
+ '1. **useState** - for managing component state\n' +
174
+ '2. **useEffect** - for side effects like data fetching or subscriptions\n' +
175
+ '3. **useContext** - for consuming context values\n' +
176
+ '4. **useCallback** - for memoizing functions\n' +
177
+ '5. **useMemo** - for memoizing computed values\n\n' +
178
+ 'Each hook serves a specific purpose and helps you write cleaner, more maintainable React code. ' +
179
+ 'Would you like examples of how to use any of these hooks?';
180
+ export const WithStreamingMessage = {
181
+ render: (args) => {
182
+ const [streamedText, setStreamedText] = useState('');
183
+ const [isStreaming, setIsStreaming] = useState(true);
184
+ useEffect(() => {
185
+ setStreamedText('');
186
+ setIsStreaming(true);
187
+ const resultText = streamingText.repeat(10);
188
+ let currentIndex = 0;
189
+ const interval = setInterval(() => {
190
+ if (currentIndex < resultText.length) {
191
+ const nextChunk = resultText.slice(0, currentIndex + 1);
192
+ setStreamedText(nextChunk);
193
+ currentIndex += Math.floor(Math.random() * 4) + 3;
194
+ }
195
+ else {
196
+ setIsStreaming(false);
197
+ clearInterval(interval);
198
+ }
199
+ }, 20);
200
+ return () => {
201
+ clearInterval(interval);
202
+ };
203
+ }, []);
204
+ const messages = [
205
+ {
206
+ id: 'user-1',
207
+ role: 'user',
208
+ timestamp: '2024-01-01T00:00:00Z',
209
+ content: 'Can you explain React Hooks to me?',
210
+ },
211
+ {
212
+ id: 'assistant-1',
213
+ role: 'assistant',
214
+ timestamp: '2024-01-01T00:00:01Z',
215
+ content: streamedText || ' ',
216
+ },
217
+ ];
218
+ return (_jsx(ShowcaseItem, { title: "With Streaming Message", children: _jsx(ContentWrapper, { width: "480px", height: "200px", display: "flex", children: _jsx(MessageList, Object.assign({}, args, { messages: messages, status: isStreaming ? 'streaming' : 'ready' })) }) }));
219
+ },
220
+ decorators: defaultDecorators,
221
+ };
222
+ export const WithDefaultActions = {
223
+ render: (args) => {
224
+ const userActions = [
225
+ {
226
+ actionType: BaseMessageActionType.Edit,
227
+ onClick: (message) => {
228
+ // eslint-disable-next-line no-console
229
+ console.log('Edit user message:', message.id);
230
+ },
231
+ },
232
+ {
233
+ actionType: BaseMessageActionType.Delete,
234
+ onClick: (message) => {
235
+ // eslint-disable-next-line no-console
236
+ console.log('Delete user message:', message.id);
237
+ },
238
+ },
239
+ ];
240
+ const assistantActions = [
241
+ {
242
+ actionType: BaseMessageActionType.Copy,
243
+ onClick: (message) => {
244
+ // eslint-disable-next-line no-console
245
+ console.log('Copy assistant message:', message.id);
246
+ },
247
+ },
248
+ {
249
+ actionType: BaseMessageActionType.Like,
250
+ onClick: (message) => {
251
+ // eslint-disable-next-line no-console
252
+ console.log('Like assistant message:', message.id);
253
+ },
254
+ },
255
+ ];
256
+ return (_jsx(ShowcaseItem, { title: "With Default Actions", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(MessageList, Object.assign({}, args, { messages: [
257
+ {
258
+ id: 'user-1',
259
+ role: 'user',
260
+ timestamp: '2024-01-01T00:00:00Z',
261
+ content: 'Hello! This message has default actions.',
262
+ },
263
+ {
264
+ id: 'assistant-1',
265
+ role: 'assistant',
266
+ timestamp: '2024-01-01T00:00:01Z',
267
+ content: 'Hi! This message also has default actions.',
268
+ },
269
+ {
270
+ id: 'user-2',
271
+ role: 'user',
272
+ timestamp: '2024-01-01T00:00:02Z',
273
+ content: 'This message has custom actions.',
274
+ actions: [
275
+ {
276
+ actionType: 'custom',
277
+ onClick: () => {
278
+ // eslint-disable-next-line no-console
279
+ console.log('Custom action clicked');
280
+ },
281
+ },
282
+ ],
283
+ },
284
+ {
285
+ id: 'assistant-1',
286
+ role: 'assistant',
287
+ timestamp: '2024-01-01T00:00:01Z',
288
+ content: 'On stream, the last message does not have actions.',
289
+ },
290
+ ], userActions: userActions, assistantActions: assistantActions, status: "streaming" })) }) }));
291
+ },
292
+ decorators: defaultDecorators,
293
+ };
294
+ export const WithPreviousMessages = {
295
+ render: (args) => {
296
+ const createMessage = (num) => {
297
+ const isUser = num % 2 === 1;
298
+ return {
299
+ id: `msg-${num}`,
300
+ role: isUser ? 'user' : 'assistant',
301
+ timestamp: `2024-01-01T00:00:${String(num).padStart(2, '0')}Z`,
302
+ content: isUser ? `User message ${num}` : `Assistant response ${num}`,
303
+ };
304
+ };
305
+ const [messages, setMessages] = useState(() => Array.from({ length: 10 }, (_, i) => createMessage(11 + i)));
306
+ const [hasMore, setHasMore] = useState(true);
307
+ const isLoadingRef = useRef(false);
308
+ const handleLoadPrevious = useCallback(() => {
309
+ if (isLoadingRef.current || !hasMore) {
310
+ return;
311
+ }
312
+ isLoadingRef.current = true;
313
+ setTimeout(() => {
314
+ setMessages((prev) => {
315
+ const firstMessage = prev[0];
316
+ if (!(firstMessage === null || firstMessage === void 0 ? void 0 : firstMessage.id)) {
317
+ isLoadingRef.current = false;
318
+ return prev;
319
+ }
320
+ const firstNum = parseInt(firstMessage.id.replace('msg-', ''), 10);
321
+ const startNum = Math.max(1, firstNum - 5);
322
+ const count = firstNum - startNum;
323
+ if (count <= 0 || startNum >= firstNum) {
324
+ setHasMore(false);
325
+ isLoadingRef.current = false;
326
+ return prev;
327
+ }
328
+ const newMessages = Array.from({ length: count }, (_, i) => createMessage(startNum + i));
329
+ if (startNum <= 1) {
330
+ setHasMore(false);
331
+ }
332
+ isLoadingRef.current = false;
333
+ return [...newMessages, ...prev];
334
+ });
335
+ }, 500);
336
+ }, [hasMore]);
337
+ return (_jsx(ShowcaseItem, { title: "With Previous Messages Loading", children: _jsx(ContentWrapper, { width: "480px", height: "400px", display: "flex", children: _jsx(MessageList, Object.assign({}, args, { messages: messages, hasPreviousMessages: hasMore, onLoadPreviousMessages: handleLoadPrevious })) }) }));
338
+ },
339
+ decorators: defaultDecorators,
340
+ };
@@ -0,0 +1,19 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { PromptInput } from '../PromptInput';
3
+ declare const _default: Meta;
4
+ export default _default;
5
+ type Story = StoryObj<typeof PromptInput>;
6
+ export declare const Playground: Story;
7
+ export declare const FullView: Story;
8
+ export declare const WithSuggestions: Story;
9
+ export declare const WithSuggestionsAndTitle: Story;
10
+ export declare const WithContextIndicator: Story;
11
+ export declare const WithCustomTopContent: Story;
12
+ export declare const WithCustomBottomContent: Story;
13
+ export declare const WithTopPanel: Story;
14
+ export declare const WithBottomPanel: Story;
15
+ export declare const WithBothPanels: Story;
16
+ export declare const WithPanelToggle: Story;
17
+ export declare const Disabled: Story;
18
+ export declare const Streaming: Story;
19
+ export declare const ComplexExample: Story;