@gravity-ui/aikit 1.3.0 → 1.3.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2023 YANDEX LLC
3
+ Copyright (c) 2025 YANDEX LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -26,6 +26,8 @@ export type PromptInputBodyProps = {
26
26
  children?: ReactNode;
27
27
  /** Additional CSS class */
28
28
  className?: string;
29
+ /** Additional CSS class for input element */
30
+ inputClassName?: string;
29
31
  /** QA/test identifier */
30
32
  qa?: string;
31
33
  };
@@ -12,14 +12,14 @@ const b = block('prompt-input-body');
12
12
  * @returns React component
13
13
  */
14
14
  export const PromptInputBody = forwardRef((props, ref) => {
15
- const { value, placeholder, maxLength, minRows = 1, maxRows = 15, autoFocus = false, disabledInput = false, onChange, onKeyDown, children, className, qa, } = props;
15
+ const { value, placeholder, maxLength, minRows = 1, maxRows = 15, autoFocus = false, disabledInput = false, onChange, onKeyDown, children, className, inputClassName, qa, } = props;
16
16
  // If custom content is provided, render it
17
17
  if (children) {
18
18
  return (_jsx("div", { className: b(null, className), "data-qa": qa, children: children }));
19
19
  }
20
20
  // Render default textarea
21
21
  return (_jsx("div", { className: b(null, className), "data-qa": qa, children: _jsx(TextArea, { controlRef: ref, size: "l", value: value, placeholder: placeholder, minRows: minRows, maxRows: maxRows, autoFocus: autoFocus, disabled: disabledInput, onUpdate: onChange, onKeyDown: onKeyDown, view: "clear", className: b('textarea'), controlProps: {
22
- className: b('textarea-control'),
22
+ className: b('textarea-control', inputClassName),
23
23
  maxLength,
24
24
  } }) }));
25
25
  });
@@ -22,6 +22,10 @@ $block: '.#{variables.$ns}prompt-input';
22
22
  gap: var(--g-spacing-2);
23
23
  }
24
24
 
25
+ &_view_full &__textarea {
26
+ padding-top: 0;
27
+ }
28
+
25
29
  &__content {
26
30
  display: flex;
27
31
  align-items: flex-end;
@@ -18,7 +18,7 @@ export function PromptInputFull(props) {
18
18
  const { value, submitButtonState, handleChange, handleKeyDown, handleSubmit } = hookState;
19
19
  const shouldShowHeader = topContent || contextItems.length > 0 || showContextIndicator;
20
20
  const shouldShowFooter = true;
21
- return (_jsxs("div", { className: b({ view: 'full' }, className), "data-qa": qa, children: [shouldShowHeader && (_jsx(PromptInputHeader, { contextItems: contextItems, showContextIndicator: showContextIndicator, contextIndicatorProps: contextIndicatorProps, children: topContent })), _jsx(PromptInputBody, { value: value, placeholder: placeholder, minRows: minRows, maxRows: maxRows, autoFocus: autoFocus, onChange: handleChange, onKeyDown: handleKeyDown }), shouldShowFooter && (_jsx(PromptInputFooter, { submitButton: {
21
+ return (_jsxs("div", { className: b({ view: 'full' }, className), "data-qa": qa, children: [shouldShowHeader && (_jsx(PromptInputHeader, { contextItems: contextItems, showContextIndicator: showContextIndicator, contextIndicatorProps: contextIndicatorProps, children: topContent })), _jsx(PromptInputBody, { value: value, placeholder: placeholder, minRows: minRows, maxRows: maxRows, autoFocus: autoFocus, onChange: handleChange, onKeyDown: handleKeyDown, inputClassName: b('textarea') }), shouldShowFooter && (_jsx(PromptInputFooter, { submitButton: {
22
22
  onClick: handleSubmit,
23
23
  state: submitButtonState,
24
24
  tooltipSend: submitButtonTooltipSend,
@@ -8,5 +8,5 @@ const b = block('tool-message');
8
8
  export function ToolMessage(props) {
9
9
  const { toolName, className, qa, bodyContent, status, toolIcon, headerContent } = props;
10
10
  const { isExpanded, headerActions, footerActions, footerContent, showLoader, isWaiting } = useToolMessage(props);
11
- return (_jsx(Card, { className: b({ waiting: isWaiting }, className), "data-qa": qa, children: _jsxs("div", { className: b('container'), children: [_jsx(ToolHeader, { toolName: toolName, actions: headerActions, toolIcon: toolIcon, content: headerContent, status: status }), bodyContent && isExpanded && _jsx("div", { className: b('content'), children: bodyContent }), isWaiting && (_jsx(ToolFooter, { actions: footerActions, content: footerContent, showLoader: showLoader }))] }) }));
11
+ return (_jsx(Card, { className: b({ waiting: isWaiting }, className), qa: qa, children: _jsxs("div", { className: b('container'), children: [_jsx(ToolHeader, { toolName: toolName, actions: headerActions, toolIcon: toolIcon, content: headerContent, status: status }), bodyContent && isExpanded && _jsx("div", { className: b('content'), children: bodyContent }), isWaiting && (_jsx(ToolFooter, { actions: footerActions, content: footerContent, showLoader: showLoader }))] }) }));
12
12
  }
@@ -44,12 +44,13 @@ export function ChatContainer(props) {
44
44
  return true;
45
45
  }, [hideTitleOnEmptyChat, isChatEmpty, headerProps.showTitle]);
46
46
  // Build props for Header
47
- const finalHeaderProps = useMemo(() => (Object.assign(Object.assign({}, headerProps), { title: headerTitle, showTitle, baseActions: hookState.baseActions, handleNewChat: hookState.handleNewChat, handleHistoryToggle: hookState.handleHistoryToggle, handleClose: hookState.handleClose, historyButtonRef: hookState.historyButtonRef })), [
47
+ const finalHeaderProps = useMemo(() => (Object.assign(Object.assign({}, headerProps), { title: headerTitle, showTitle, baseActions: hookState.baseActions, handleNewChat: hookState.handleNewChat, handleHistoryToggle: hookState.handleHistoryToggle, handleFolding: hookState.handleFolding, handleClose: hookState.handleClose, historyButtonRef: hookState.historyButtonRef })), [
48
48
  headerTitle,
49
49
  showTitle,
50
50
  hookState.baseActions,
51
51
  hookState.handleNewChat,
52
52
  hookState.handleHistoryToggle,
53
+ hookState.handleFolding,
53
54
  hookState.handleClose,
54
55
  hookState.historyButtonRef,
55
56
  headerProps,
@@ -211,6 +211,7 @@ export const Playground = {
211
211
  chats: mockChats,
212
212
  showHistory: true,
213
213
  showNewChat: true,
214
+ showFolding: false,
214
215
  showClose: false,
215
216
  welcomeConfig: {
216
217
  title: 'Welcome to AI Chat',
@@ -225,6 +226,7 @@ export const Playground = {
225
226
  const [messages, setMessages] = useState(addActionsToMessages(mockChatMessages[initialChat.id] || []));
226
227
  const [status, setStatus] = useState(args.status || 'ready');
227
228
  const [activeChat, setActiveChat] = useState(initialChat);
229
+ const [foldingState, setFoldingState] = useState('opened');
228
230
  const handleSendMessage = async (data) => {
229
231
  const userMessage = {
230
232
  id: Date.now().toString(),
@@ -261,7 +263,9 @@ export const Playground = {
261
263
  const handleCancel = async () => {
262
264
  setStatus('ready');
263
265
  };
264
- return (_jsx(ChatContainer, Object.assign({}, args, { messages: messages, activeChat: activeChat, onSendMessage: handleSendMessage, onCancel: handleCancel, onSelectChat: handleSelectChat, onCreateChat: handleCreateChat, status: status })));
266
+ return (_jsx(ChatContainer, Object.assign({}, args, { headerProps: {
267
+ foldingState,
268
+ }, messages: messages, activeChat: activeChat, onSendMessage: handleSendMessage, onCancel: handleCancel, onSelectChat: handleSelectChat, onCreateChat: handleCreateChat, onFold: setFoldingState, status: status })));
265
269
  },
266
270
  decorators: defaultDecorators,
267
271
  };
@@ -111,6 +111,8 @@ export interface ChatContainerProps {
111
111
  onDeleteChat?: (chat: ChatType) => void;
112
112
  /** Callback when user deletes all chats */
113
113
  onDeleteAllChats?: () => Promise<void>;
114
+ /** Callback when user folds or unfolds the chat */
115
+ onFold?: (value: 'collapsed' | 'opened') => void;
114
116
  /** Callback when user closes the chat */
115
117
  onClose?: () => void;
116
118
  /** Callback when user cancels streaming */
@@ -132,7 +134,7 @@ export interface ChatContainerProps {
132
134
  /** MessageList configuration for actions and loader behavior */
133
135
  messageListConfig?: MessageListConfig;
134
136
  /** Props override for Header component */
135
- headerProps?: Partial<Omit<HeaderProps, 'handleNewChat' | 'handleHistoryToggle' | 'handleClose'>>;
137
+ headerProps?: Partial<Omit<HeaderProps, 'handleNewChat' | 'handleHistoryToggle' | 'handleFolding' | 'handleClose'>>;
136
138
  /** Props override for ChatContent component */
137
139
  contentProps?: Partial<Omit<ChatContentProps, 'view' | 'messageListProps'>>;
138
140
  /** Props override for EmptyContainer (welcome screen) */
@@ -151,6 +153,8 @@ export interface ChatContainerProps {
151
153
  showHistory?: boolean;
152
154
  /** Show new chat button */
153
155
  showNewChat?: boolean;
156
+ /** Show folding button */
157
+ showFolding?: boolean;
154
158
  /** Show close button */
155
159
  showClose?: boolean;
156
160
  /** Hide header title when chat is empty */
@@ -13,6 +13,7 @@ export declare function useChatContainer(props: ChatContainerProps): {
13
13
  historyButtonRef: import("react").RefObject<HTMLElement>;
14
14
  handleNewChat: () => void;
15
15
  handleHistoryToggle: () => void;
16
+ handleFolding: (value: "collapsed" | "opened") => void;
16
17
  handleClose: () => void;
17
18
  handleSelectChat: (chat: ChatContainerProps["activeChat"]) => void;
18
19
  handleHistoryOpenChange: (open: boolean) => void;
@@ -7,7 +7,7 @@ import { HeaderAction } from '../../organisms/Header';
7
7
  * @returns object with state and handlers
8
8
  */
9
9
  export function useChatContainer(props) {
10
- const { messages = [], activeChat, onCreateChat, onClose, onSelectChat, showHistory = true, showNewChat = true, showClose = false, } = props;
10
+ const { messages = [], activeChat, onCreateChat, onClose, onFold, onSelectChat, showHistory = true, showNewChat = true, showFolding = false, showClose = false, } = props;
11
11
  // Refs for History integration with Header
12
12
  const historyButtonRef = useRef(null);
13
13
  const [isHistoryOpen, setIsHistoryOpen] = useState(false);
@@ -29,6 +29,9 @@ export function useChatContainer(props) {
29
29
  const handleHistoryToggle = useCallback(() => {
30
30
  setIsHistoryOpen((prev) => !prev);
31
31
  }, []);
32
+ const handleFolding = useCallback((value) => {
33
+ onFold === null || onFold === void 0 ? void 0 : onFold(value);
34
+ }, [onFold]);
32
35
  // Handler for closing
33
36
  const handleClose = useCallback(() => {
34
37
  onClose === null || onClose === void 0 ? void 0 : onClose();
@@ -53,11 +56,14 @@ export function useChatContainer(props) {
53
56
  if (showHistory) {
54
57
  actions.push(HeaderAction.History);
55
58
  }
59
+ if (showFolding) {
60
+ actions.push(HeaderAction.Folding);
61
+ }
56
62
  if (showClose) {
57
63
  actions.push(HeaderAction.Close);
58
64
  }
59
65
  return actions;
60
- }, [showNewChat, showHistory, showClose, chatContentView]);
66
+ }, [showNewChat, showHistory, showFolding, showClose, chatContentView]);
61
67
  return {
62
68
  // State
63
69
  chatContentView,
@@ -68,6 +74,7 @@ export function useChatContainer(props) {
68
74
  // Handlers
69
75
  handleNewChat,
70
76
  handleHistoryToggle,
77
+ handleFolding,
71
78
  handleClose,
72
79
  handleSelectChat,
73
80
  handleHistoryOpenChange,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/aikit",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "Gravity UI base kit for building ai assistant chats",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",