@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.
- package/dist/components/atoms/ActionButton/__stories__/ActionButton.stories.d.ts +8 -0
- package/dist/components/atoms/ActionButton/__stories__/ActionButton.stories.js +48 -0
- package/dist/components/atoms/Alert/__stories__/Alert.stories.d.ts +10 -0
- package/dist/components/atoms/Alert/__stories__/Alert.stories.js +72 -0
- package/dist/components/atoms/ChatDate/__stories__/ChatDate.stories.d.ts +16 -0
- package/dist/components/atoms/ChatDate/__stories__/ChatDate.stories.js +83 -0
- package/dist/components/atoms/ContextIndicator/__stories__/ContextIndicator.stories.d.ts +17 -0
- package/dist/components/atoms/ContextIndicator/__stories__/ContextIndicator.stories.js +72 -0
- package/dist/components/atoms/ContextItem/__stories__/ContextItem.stories.d.ts +8 -0
- package/dist/components/atoms/ContextItem/__stories__/ContextItem.stories.js +36 -0
- package/dist/components/atoms/DiffStat/__stories__/DiffStat.stories.d.ts +8 -0
- package/dist/components/atoms/DiffStat/__stories__/DiffStat.stories.js +45 -0
- package/dist/components/atoms/Disclaimer/__stories__/Disclaimer.stories.d.ts +12 -0
- package/dist/components/atoms/Disclaimer/__stories__/Disclaimer.stories.js +64 -0
- package/dist/components/atoms/Loader/__stories__/Loader.stories.d.ts +8 -0
- package/dist/components/atoms/Loader/__stories__/Loader.stories.js +47 -0
- package/dist/components/atoms/MarkdownRenderer/__stories__/MarkdownRenderer.stories.d.ts +6 -0
- package/dist/components/atoms/MarkdownRenderer/__stories__/MarkdownRenderer.stories.js +49 -0
- package/dist/components/atoms/MessageBalloon/__stories__/MessageBalloon.stories.d.ts +6 -0
- package/dist/components/atoms/MessageBalloon/__stories__/MessageBalloon.stories.js +32 -0
- package/dist/components/atoms/Shimmer/__stories__/Shimmer.stories.d.ts +5 -0
- package/dist/components/atoms/Shimmer/__stories__/Shimmer.stories.js +28 -0
- package/dist/components/atoms/SubmitButton/__stories__/SubmitButton.stories.d.ts +13 -0
- package/dist/components/atoms/SubmitButton/__stories__/SubmitButton.stories.js +98 -0
- package/dist/components/atoms/ToolIndicator/__stories__/ToolIndicator.stories.d.ts +9 -0
- package/dist/components/atoms/ToolIndicator/__stories__/ToolIndicator.stories.js +34 -0
- package/dist/components/molecules/BaseMessage/__stories__/BaseMessage.stories.d.ts +9 -0
- package/dist/components/molecules/BaseMessage/__stories__/BaseMessage.stories.js +77 -0
- package/dist/components/molecules/BaseMessage/index.d.ts +1 -1
- package/dist/components/molecules/BaseMessage/index.js +51 -20
- package/dist/components/molecules/ButtonGroup/__stories__/ButtonGroup.stories.d.ts +6 -0
- package/dist/components/molecules/ButtonGroup/__stories__/ButtonGroup.stories.js +44 -0
- package/dist/components/molecules/PromptInputBody/__stories__/PromptInputBody.stories.d.ts +11 -0
- package/dist/components/molecules/PromptInputBody/__stories__/PromptInputBody.stories.js +62 -0
- package/dist/components/molecules/PromptInputFooter/__stories__/PromptInputFooter.stories.d.ts +11 -0
- package/dist/components/molecules/PromptInputFooter/__stories__/PromptInputFooter.stories.js +96 -0
- package/dist/components/molecules/PromptInputHeader/__stories__/PromptInputHeader.stories.d.ts +15 -0
- package/dist/components/molecules/PromptInputHeader/__stories__/PromptInputHeader.stories.js +123 -0
- package/dist/components/molecules/PromptInputPanel/__stories__/PromptInputPanel.stories.d.ts +8 -0
- package/dist/components/molecules/PromptInputPanel/__stories__/PromptInputPanel.stories.js +38 -0
- package/dist/components/molecules/Suggestions/__stories__/Suggestions.stories.d.ts +22 -0
- package/dist/components/molecules/Suggestions/__stories__/Suggestions.stories.js +182 -0
- package/dist/components/molecules/Tabs/__stories__/Tabs.stories.d.ts +9 -0
- package/dist/components/molecules/Tabs/__stories__/Tabs.stories.js +103 -0
- package/dist/components/molecules/ToolFooter/__stories__/ToolFooter.stories.d.ts +7 -0
- package/dist/components/molecules/ToolFooter/__stories__/ToolFooter.stories.js +58 -0
- package/dist/components/molecules/ToolFooter/index.js +8 -1
- package/dist/components/molecules/ToolHeader/__stories__/ToolHeader.stories.d.ts +8 -0
- package/dist/components/molecules/ToolHeader/__stories__/ToolHeader.stories.js +59 -0
- package/dist/components/molecules/ToolHeader/index.js +10 -1
- package/dist/components/molecules/ToolStatus/__stories__/ToolStatus.stories.d.ts +9 -0
- package/dist/components/molecules/ToolStatus/__stories__/ToolStatus.stories.js +44 -0
- package/dist/components/organisms/AssistantMessage/__stories__/AssistantMessage.stories.d.ts +13 -0
- package/dist/components/organisms/AssistantMessage/__stories__/AssistantMessage.stories.js +151 -0
- package/dist/components/organisms/Header/Header.js +16 -17
- package/dist/components/organisms/Header/__stories__/Header.stories.d.ts +15 -0
- package/dist/components/organisms/Header/__stories__/Header.stories.js +159 -0
- package/dist/components/organisms/Header/types.d.ts +2 -3
- package/dist/components/organisms/Header/useHeader.d.ts +2 -4
- package/dist/components/organisms/Header/useHeader.js +2 -24
- package/dist/components/organisms/MessageList/MessageList.js +5 -6
- package/dist/components/organisms/MessageList/__stories__/MessageList.stories.d.ts +25 -0
- package/dist/components/organisms/MessageList/__stories__/MessageList.stories.js +340 -0
- package/dist/components/organisms/PromptInput/__stories__/PromptInput.stories.d.ts +19 -0
- package/dist/components/organisms/PromptInput/__stories__/PromptInput.stories.js +304 -0
- package/dist/components/organisms/ThinkingMessage/__stories__/ThinkingMessage.stories.d.ts +12 -0
- package/dist/components/organisms/ThinkingMessage/__stories__/ThinkingMessage.stories.js +105 -0
- package/dist/components/organisms/ToolMessage/__stories__/ToolMessage.stories.d.ts +11 -0
- package/dist/components/organisms/ToolMessage/__stories__/ToolMessage.stories.js +70 -0
- package/dist/components/organisms/UserMessage/__stories__/UserMessage.stories.d.ts +9 -0
- package/dist/components/organisms/UserMessage/__stories__/UserMessage.stories.js +118 -0
- package/dist/components/pages/ChatContainer/__stories__/ChatContainer.stories.d.ts +79 -0
- package/dist/components/pages/ChatContainer/__stories__/ChatContainer.stories.js +1006 -0
- package/dist/components/templates/ChatContent/__stories__/ChatContent.stories.d.ts +14 -0
- package/dist/components/templates/ChatContent/__stories__/ChatContent.stories.js +315 -0
- package/dist/components/templates/EmptyContainer/__stories__/EmptyContainer.stories.d.ts +20 -0
- package/dist/components/templates/EmptyContainer/__stories__/EmptyContainer.stories.js +250 -0
- package/dist/components/templates/History/ChatItem.d.ts +2 -2
- package/dist/components/templates/History/ChatItem.js +2 -5
- package/dist/components/templates/History/History.scss +13 -9
- package/dist/components/templates/History/HistoryList.d.ts +3 -1
- package/dist/components/templates/History/HistoryList.js +9 -5
- package/dist/components/templates/History/__stories__/History.stories.d.ts +18 -0
- package/dist/components/templates/History/__stories__/History.stories.js +289 -0
- package/dist/demo/ContentWrapper/ContentWrapper.d.ts +4 -0
- package/dist/demo/ContentWrapper/ContentWrapper.js +9 -0
- package/dist/demo/ContentWrapper/index.d.ts +1 -0
- package/dist/demo/ContentWrapper/index.js +1 -0
- package/dist/demo/Showcase/Showcase.d.ts +9 -0
- package/dist/demo/Showcase/Showcase.js +7 -0
- package/dist/demo/Showcase/index.d.ts +1 -0
- package/dist/demo/Showcase/index.js +1 -0
- package/dist/demo/ShowcaseItem/ShowcaseItem.d.ts +8 -0
- package/dist/demo/ShowcaseItem/ShowcaseItem.js +7 -0
- package/dist/demo/ShowcaseItem/index.d.ts +1 -0
- package/dist/demo/ShowcaseItem/index.js +1 -0
- package/dist/demo/SwapArea/SwapArea.d.ts +2 -0
- package/dist/demo/SwapArea/SwapArea.js +7 -0
- package/dist/demo/SwapArea/index.d.ts +1 -0
- package/dist/demo/SwapArea/index.js +1 -0
- package/dist/hooks/useSmartScroll.d.ts +7 -2
- package/dist/hooks/useSmartScroll.js +24 -22
- package/dist/types/common.d.ts +13 -5
- package/dist/types/messages.d.ts +9 -6
- package/dist/utils/actionUtils.d.ts +14 -0
- package/dist/utils/actionUtils.js +17 -0
- package/dist/utils/messageUtils.d.ts +7 -9
- package/dist/utils/messageUtils.js +7 -1
- package/package.json +12 -7
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
2
3
|
import { Button, Text } from '@gravity-ui/uikit';
|
|
4
|
+
import { isActionConfig } from '../../../utils/actionUtils';
|
|
3
5
|
import { block } from '../../../utils/cn';
|
|
4
6
|
import { Loader, Shimmer } from '../../atoms';
|
|
5
7
|
import { ButtonGroup } from '../ButtonGroup';
|
|
6
8
|
import './ToolFooter.scss';
|
|
7
9
|
const b = block('tool-footer');
|
|
8
10
|
export function ToolFooter({ actions, content, showLoader = true, className, qa }) {
|
|
9
|
-
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) =>
|
|
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) => {
|
|
12
|
+
if (!isActionConfig(action)) {
|
|
13
|
+
return _jsx(React.Fragment, { children: action }, index);
|
|
14
|
+
}
|
|
15
|
+
return (_jsx(Button, { view: action.view, onClick: action.onClick, size: "s", children: action.label }, index));
|
|
16
|
+
}) })] }));
|
|
10
17
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Meta, StoryFn, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import type { ToolHeaderProps } from '../../../../types/tool';
|
|
3
|
+
declare const _default: Meta;
|
|
4
|
+
export default _default;
|
|
5
|
+
export declare const Playground: StoryFn<ToolHeaderProps>;
|
|
6
|
+
export declare const Loading: StoryObj<ToolHeaderProps>;
|
|
7
|
+
export declare const Success: StoryObj<ToolHeaderProps>;
|
|
8
|
+
export declare const Cancelled: StoryObj<ToolHeaderProps>;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ChevronDown, Copy, Pencil } from '@gravity-ui/icons';
|
|
3
|
+
import { Icon, Text } from '@gravity-ui/uikit';
|
|
4
|
+
import { ToolHeader } from '..';
|
|
5
|
+
import { ContentWrapper } from '../../../../demo/ContentWrapper';
|
|
6
|
+
import { Showcase } from '../../../../demo/Showcase';
|
|
7
|
+
import MDXDocs from './Docs.mdx';
|
|
8
|
+
export default {
|
|
9
|
+
title: 'molecules/ToolHeader',
|
|
10
|
+
component: ToolHeader,
|
|
11
|
+
parameters: {
|
|
12
|
+
docs: {
|
|
13
|
+
page: MDXDocs,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
argTypes: {
|
|
17
|
+
toolName: {
|
|
18
|
+
control: 'text',
|
|
19
|
+
description: 'Name of the tool',
|
|
20
|
+
},
|
|
21
|
+
status: {
|
|
22
|
+
control: 'select',
|
|
23
|
+
options: ['success', 'error', 'loading', 'cancelled'],
|
|
24
|
+
description: 'Status indicator',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
const defaultDecorators = [
|
|
29
|
+
(Story) => (_jsx(Showcase, { children: _jsx(Story, {}) })),
|
|
30
|
+
];
|
|
31
|
+
const copyAction = {
|
|
32
|
+
label: 'Copy',
|
|
33
|
+
onClick: () => alert('Copied'),
|
|
34
|
+
icon: _jsx(Icon, { data: Copy, size: 16 }),
|
|
35
|
+
};
|
|
36
|
+
const collapseAction = {
|
|
37
|
+
label: 'Collapse',
|
|
38
|
+
onClick: () => alert('Collapsed'),
|
|
39
|
+
icon: _jsx(Icon, { data: ChevronDown, size: 16 }),
|
|
40
|
+
};
|
|
41
|
+
export const Playground = (args) => (_jsx(ContentWrapper, { width: "430px", children: _jsx(ToolHeader, Object.assign({}, args)) }));
|
|
42
|
+
Playground.args = {
|
|
43
|
+
toolIcon: _jsx(Icon, { data: Pencil, size: 16 }),
|
|
44
|
+
toolName: 'Writing',
|
|
45
|
+
content: (_jsx(Text, { color: "secondary", variant: "body-1", children: "expectScreenshotFixture.ts" })),
|
|
46
|
+
status: 'success',
|
|
47
|
+
};
|
|
48
|
+
export const Loading = {
|
|
49
|
+
render: (args) => (_jsx(ContentWrapper, { width: "430px", children: _jsx(ToolHeader, Object.assign({}, args, { toolIcon: _jsx(Icon, { data: Pencil, size: 16 }), toolName: "Writing", content: _jsx(Text, { color: "secondary", variant: "body-1", children: "expectScreenshotFixture.ts" }), status: "loading" })) })),
|
|
50
|
+
decorators: defaultDecorators,
|
|
51
|
+
};
|
|
52
|
+
export const Success = {
|
|
53
|
+
render: (args) => (_jsx(ContentWrapper, { width: "430px", children: _jsx(ToolHeader, Object.assign({}, args, { toolIcon: _jsx(Icon, { data: Pencil, size: 16 }), toolName: "Writing", content: _jsx(Text, { color: "secondary", variant: "body-1", children: "expectScreenshotFixture.ts" }), actions: [collapseAction, copyAction], status: "success" })) })),
|
|
54
|
+
decorators: defaultDecorators,
|
|
55
|
+
};
|
|
56
|
+
export const Cancelled = {
|
|
57
|
+
render: (args) => (_jsx(ContentWrapper, { width: "430px", children: _jsx(ToolHeader, Object.assign({}, args, { toolIcon: _jsx(Icon, { data: Pencil, size: 16 }), toolName: "Writing", content: _jsx(Text, { color: "secondary", variant: "body-1", children: "expectScreenshotFixture.ts" }), status: "cancelled" })) })),
|
|
58
|
+
decorators: defaultDecorators,
|
|
59
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
2
3
|
import { Text } from '@gravity-ui/uikit';
|
|
4
|
+
import { isActionConfig } from '../../../utils/actionUtils';
|
|
3
5
|
import { block } from '../../../utils/cn';
|
|
4
6
|
import { ActionButton } from '../../atoms';
|
|
5
7
|
import { ButtonGroup } from '../ButtonGroup';
|
|
@@ -9,5 +11,12 @@ const b = block('tool-header');
|
|
|
9
11
|
export function ToolHeader(props) {
|
|
10
12
|
const { toolIcon, toolName, content, actions, status, className, qa } = props;
|
|
11
13
|
const hasActions = actions && actions.length > 0;
|
|
12
|
-
return (_jsxs("div", { className: b('', className), "data-qa": qa, children: [_jsxs("div", { className: b('left'), children: [toolIcon, _jsx(Text, { children: toolName }), content] }), _jsxs("div", { className: b('right'), children: [hasActions && (_jsx(ButtonGroup, { children: actions.map((action, index) =>
|
|
14
|
+
return (_jsxs("div", { className: b('', className), "data-qa": qa, children: [_jsxs("div", { className: b('left'), children: [toolIcon, _jsx(Text, { children: toolName }), content] }), _jsxs("div", { className: b('right'), children: [hasActions && (_jsx(ButtonGroup, { children: actions.map((action, index) => {
|
|
15
|
+
// Check if action is a ReactNode (not an object with properties)
|
|
16
|
+
if (!isActionConfig(action)) {
|
|
17
|
+
return _jsx(React.Fragment, { children: action }, index);
|
|
18
|
+
}
|
|
19
|
+
// TypeScript now knows that action is ActionConfig
|
|
20
|
+
return (_jsx(ActionButton, { tooltipTitle: action.label, view: action.view || 'flat-secondary', size: "s", onClick: action.onClick, children: action.icon }, index));
|
|
21
|
+
}) })), _jsx(ToolStatus, { status: status })] })] }));
|
|
13
22
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Meta, StoryFn, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import type { ToolStatusProps } from '../index';
|
|
3
|
+
declare const _default: Meta;
|
|
4
|
+
export default _default;
|
|
5
|
+
export declare const Playground: StoryFn<ToolStatusProps>;
|
|
6
|
+
export declare const Success: StoryObj<ToolStatusProps>;
|
|
7
|
+
export declare const Error: StoryObj<ToolStatusProps>;
|
|
8
|
+
export declare const Loading: StoryObj<ToolStatusProps>;
|
|
9
|
+
export declare const Cancelled: StoryObj<ToolStatusProps>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ToolStatus } from '..';
|
|
3
|
+
import { ContentWrapper } from '../../../../demo/ContentWrapper';
|
|
4
|
+
import { Showcase } from '../../../../demo/Showcase';
|
|
5
|
+
import MDXDocs from './Docs.mdx';
|
|
6
|
+
export default {
|
|
7
|
+
title: 'molecules/ToolStatus',
|
|
8
|
+
component: ToolStatus,
|
|
9
|
+
parameters: {
|
|
10
|
+
docs: {
|
|
11
|
+
page: MDXDocs,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
argTypes: {
|
|
15
|
+
status: {
|
|
16
|
+
control: 'select',
|
|
17
|
+
options: ['success', 'error', 'loading', 'cancelled', undefined],
|
|
18
|
+
description: 'Tool status',
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const defaultDecorators = [
|
|
23
|
+
(Story) => (_jsx(Showcase, { children: _jsx(Story, {}) })),
|
|
24
|
+
];
|
|
25
|
+
export const Playground = (args) => (_jsx(ContentWrapper, { width: "430px", children: _jsx(ToolStatus, Object.assign({}, args)) }));
|
|
26
|
+
Playground.args = {
|
|
27
|
+
status: 'success',
|
|
28
|
+
};
|
|
29
|
+
export const Success = {
|
|
30
|
+
render: (args) => (_jsx(ContentWrapper, { width: "430px", children: _jsx(ToolStatus, Object.assign({}, args, { status: "success" })) })),
|
|
31
|
+
decorators: defaultDecorators,
|
|
32
|
+
};
|
|
33
|
+
export const Error = {
|
|
34
|
+
render: (args) => (_jsx(ContentWrapper, { width: "430px", children: _jsx(ToolStatus, Object.assign({}, args, { status: "error" })) })),
|
|
35
|
+
decorators: defaultDecorators,
|
|
36
|
+
};
|
|
37
|
+
export const Loading = {
|
|
38
|
+
render: (args) => (_jsx(ContentWrapper, { width: "430px", children: _jsx(ToolStatus, Object.assign({}, args, { status: "loading" })) })),
|
|
39
|
+
decorators: defaultDecorators,
|
|
40
|
+
};
|
|
41
|
+
export const Cancelled = {
|
|
42
|
+
render: (args) => (_jsx(ContentWrapper, { width: "430px", children: _jsx(ToolStatus, Object.assign({}, args, { status: "cancelled" })) })),
|
|
43
|
+
decorators: defaultDecorators,
|
|
44
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Meta, StoryFn, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import { type AssistantMessageProps } from '..';
|
|
3
|
+
import type { TMessageContent } from '../../../../types/messages';
|
|
4
|
+
declare const _default: Meta;
|
|
5
|
+
export default _default;
|
|
6
|
+
export declare const Playground: StoryFn<AssistantMessageProps>;
|
|
7
|
+
export declare const WithToolCall: StoryObj<AssistantMessageProps>;
|
|
8
|
+
interface CustomMessageData {
|
|
9
|
+
title: string;
|
|
10
|
+
description: string;
|
|
11
|
+
}
|
|
12
|
+
type CustomMessageContent = TMessageContent<'custom', CustomMessageData>;
|
|
13
|
+
export declare const WithCustomRenderer: StoryObj<AssistantMessageProps<CustomMessageContent>>;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
import { Pencil } from '@gravity-ui/icons';
|
|
4
|
+
import { Icon, Text } from '@gravity-ui/uikit';
|
|
5
|
+
import { AssistantMessage } 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 MDXDocs from './Docs.mdx';
|
|
11
|
+
export default {
|
|
12
|
+
title: 'organisms/AssistantMessage',
|
|
13
|
+
component: AssistantMessage,
|
|
14
|
+
parameters: {
|
|
15
|
+
docs: {
|
|
16
|
+
page: MDXDocs,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
argTypes: {
|
|
20
|
+
content: {
|
|
21
|
+
control: 'object',
|
|
22
|
+
description: 'Message content',
|
|
23
|
+
},
|
|
24
|
+
actions: {
|
|
25
|
+
control: 'object',
|
|
26
|
+
description: 'Message actions',
|
|
27
|
+
},
|
|
28
|
+
timestamp: {
|
|
29
|
+
control: 'text',
|
|
30
|
+
description: 'Message timestamp',
|
|
31
|
+
},
|
|
32
|
+
id: {
|
|
33
|
+
control: 'text',
|
|
34
|
+
description: 'Message ID',
|
|
35
|
+
},
|
|
36
|
+
messageRendererRegistry: {
|
|
37
|
+
control: false,
|
|
38
|
+
description: 'Custom message renderer registry',
|
|
39
|
+
},
|
|
40
|
+
showActionsOnHover: {
|
|
41
|
+
control: 'boolean',
|
|
42
|
+
description: 'Show action buttons on hover',
|
|
43
|
+
},
|
|
44
|
+
showTimestamp: {
|
|
45
|
+
control: 'boolean',
|
|
46
|
+
description: 'Show timestamp in actions area',
|
|
47
|
+
},
|
|
48
|
+
className: {
|
|
49
|
+
control: 'text',
|
|
50
|
+
description: 'Additional CSS class',
|
|
51
|
+
},
|
|
52
|
+
qa: {
|
|
53
|
+
control: 'text',
|
|
54
|
+
description: 'QA/test identifier',
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const simpleMessage = {
|
|
59
|
+
id: '1',
|
|
60
|
+
role: 'assistant',
|
|
61
|
+
content: 'Hello! How can I help you today?',
|
|
62
|
+
};
|
|
63
|
+
const multiPartMessage = {
|
|
64
|
+
id: '4',
|
|
65
|
+
role: 'assistant',
|
|
66
|
+
content: [
|
|
67
|
+
{
|
|
68
|
+
type: 'text',
|
|
69
|
+
data: {
|
|
70
|
+
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.",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type: 'tool',
|
|
75
|
+
data: {
|
|
76
|
+
toolName: 'Reading',
|
|
77
|
+
headerContent: (_jsx(Text, { color: "secondary", variant: "body-1", children: "Warning.css" })),
|
|
78
|
+
status: 'success',
|
|
79
|
+
toolIcon: _jsx(Icon, { data: Pencil }),
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
type: 'text',
|
|
84
|
+
data: {
|
|
85
|
+
text: 'I’m organizing which files to read first. I’ll start with the essentials like package.json, README.md, tsconfig.json, jest.config.js, and eslint.config.mjs.',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
const actions = [
|
|
91
|
+
// eslint-disable-next-line no-console
|
|
92
|
+
{ actionType: 'copy', onClick: () => console.log('Copy clicked') },
|
|
93
|
+
// eslint-disable-next-line no-console
|
|
94
|
+
{ actionType: 'like', onClick: () => console.log('Like clicked') },
|
|
95
|
+
// eslint-disable-next-line no-console
|
|
96
|
+
{ actionType: 'unlike', onClick: () => console.log('Unlike clicked') },
|
|
97
|
+
];
|
|
98
|
+
export const Playground = (args) => (_jsx(ContentWrapper, { width: "480px", children: _jsx(AssistantMessage, Object.assign({}, args)) }));
|
|
99
|
+
Playground.args = {
|
|
100
|
+
content: simpleMessage.content,
|
|
101
|
+
actions,
|
|
102
|
+
timestamp: simpleMessage.timestamp,
|
|
103
|
+
id: simpleMessage.id,
|
|
104
|
+
};
|
|
105
|
+
export const WithToolCall = {
|
|
106
|
+
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
|
+
decorators: [
|
|
108
|
+
(StoryComponent) => (_jsx(Showcase, { children: _jsx(StoryComponent, {}) })),
|
|
109
|
+
],
|
|
110
|
+
};
|
|
111
|
+
const CustomMessageView = ({ part, }) => {
|
|
112
|
+
const { title, description } = part.data;
|
|
113
|
+
return (_jsxs("div", { style: {
|
|
114
|
+
padding: '16px',
|
|
115
|
+
border: '1px solid var(--g-color-line-generic)',
|
|
116
|
+
borderRadius: '8px',
|
|
117
|
+
backgroundColor: 'var(--g-color-base-float)',
|
|
118
|
+
}, children: [_jsx("div", { style: { fontWeight: 'bold', marginBottom: '8px' }, children: title }), _jsx("div", { style: { color: 'var(--g-color-text-secondary)' }, children: description })] }));
|
|
119
|
+
};
|
|
120
|
+
export const WithCustomRenderer = {
|
|
121
|
+
render: (args) => {
|
|
122
|
+
const customRegistry = createMessageRendererRegistry();
|
|
123
|
+
registerMessageRenderer(customRegistry, 'custom', {
|
|
124
|
+
component: CustomMessageView,
|
|
125
|
+
});
|
|
126
|
+
const customMessage = {
|
|
127
|
+
id: '5',
|
|
128
|
+
role: 'assistant',
|
|
129
|
+
timestamp: '2024-01-01T00:00:04Z',
|
|
130
|
+
content: [
|
|
131
|
+
{
|
|
132
|
+
type: 'text',
|
|
133
|
+
data: {
|
|
134
|
+
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.",
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
type: 'custom',
|
|
139
|
+
data: {
|
|
140
|
+
title: 'Custom Message',
|
|
141
|
+
description: 'This is a custom message part rendered with a custom renderer.',
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
],
|
|
145
|
+
};
|
|
146
|
+
return (_jsx(ShowcaseItem, { title: "With Custom Renderer", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(AssistantMessage, Object.assign({}, args, { content: customMessage.content, actions: actions, timestamp: customMessage.timestamp, id: customMessage.id, messageRendererRegistry: customRegistry })) }) }));
|
|
147
|
+
},
|
|
148
|
+
decorators: [
|
|
149
|
+
(StoryComponent) => (_jsx(Showcase, { children: _jsx(StoryComponent, {}) })),
|
|
150
|
+
],
|
|
151
|
+
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React from 'react';
|
|
2
|
+
import React, { useCallback } from 'react';
|
|
3
3
|
import { ChevronsCollapseUpRight, ChevronsExpandUpRight, ClockArrowRotateLeft, Plus, Sparkles, Xmark, } from '@gravity-ui/icons';
|
|
4
|
-
import {
|
|
4
|
+
import { Icon, Text } from '@gravity-ui/uikit';
|
|
5
|
+
import { isActionConfig } from '../../../utils/actionUtils';
|
|
5
6
|
import { block } from '../../../utils/cn';
|
|
6
7
|
import { ActionButton } from '../../atoms';
|
|
7
8
|
import { ButtonGroup } from '../../molecules';
|
|
@@ -30,8 +31,11 @@ const FOLDING_ICONS = {
|
|
|
30
31
|
*/
|
|
31
32
|
export function Header(props) {
|
|
32
33
|
const { title, preview, icon, baseActions, additionalActions, titlePosition, withIcon, showTitle = true, className, historyButtonRef, } = useHeader(props);
|
|
34
|
+
// Determine class for title positioning
|
|
35
|
+
const titlePositionClass = b('title-container', { position: titlePosition });
|
|
36
|
+
const iconElement = icon ? (_jsx("div", { className: b('icon'), children: icon })) : (_jsx(Icon, { data: Sparkles, size: 16 }));
|
|
33
37
|
// Render base action
|
|
34
|
-
const renderBaseAction = (action) => {
|
|
38
|
+
const renderBaseAction = useCallback((action, ref) => {
|
|
35
39
|
let IconComponent = ACTION_ICONS[action.id];
|
|
36
40
|
// Handle folding icon based on state
|
|
37
41
|
if (action.id === HeaderAction.Folding && action.foldingState) {
|
|
@@ -46,21 +50,16 @@ export function Header(props) {
|
|
|
46
50
|
tooltipKey = `action-tooltip-folding-${action.foldingState}`;
|
|
47
51
|
}
|
|
48
52
|
// Determine ref for history button
|
|
49
|
-
const buttonRef = action.id === HeaderAction.History ?
|
|
53
|
+
const buttonRef = action.id === HeaderAction.History ? ref : undefined;
|
|
50
54
|
return (_jsx(ActionButton, { ref: buttonRef, tooltipTitle: i18n(tooltipKey), size: "m", view: "flat", onClick: action.onClick, className: b('action-button'), qa: `header-action-${action.id}`, children: _jsx(Icon, { data: IconComponent, size: 16 }) }, action.id));
|
|
51
|
-
};
|
|
55
|
+
}, []);
|
|
52
56
|
// Render additional action
|
|
53
|
-
const renderAdditionalAction = (action, index) => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (action.buttonProps) {
|
|
58
|
-
return _jsx(Button, Object.assign({}, action.buttonProps), action.id);
|
|
57
|
+
const renderAdditionalAction = useCallback((action, index) => {
|
|
58
|
+
const id = `additional-${index}`;
|
|
59
|
+
if (!isActionConfig(action)) {
|
|
60
|
+
return _jsx(React.Fragment, { children: action }, id);
|
|
59
61
|
}
|
|
60
|
-
return
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
const titlePositionClass = b('title-container', { position: titlePosition });
|
|
64
|
-
const iconElement = icon ? (_jsx("div", { className: b('icon'), children: icon })) : (_jsx(Icon, { data: Sparkles, size: 16 }));
|
|
65
|
-
return (_jsxs("div", { className: b('', className), children: [withIcon && iconElement, showTitle && (_jsxs("div", { className: titlePositionClass, children: [title && (_jsx(Text, { as: "div", variant: "subheader-2", className: b('title'), children: title })), preview && _jsx("div", { className: b('preview'), children: preview })] })), _jsxs(ButtonGroup, { children: [additionalActions.map((action, index) => renderAdditionalAction(action, index)), baseActions.map((action) => renderBaseAction(action))] })] }));
|
|
62
|
+
return (_jsx(ActionButton, Object.assign({}, action, { view: action.view || 'flat', size: "m", children: action.icon || action.label }), `${index}`));
|
|
63
|
+
}, []);
|
|
64
|
+
return (_jsxs("div", { className: b('', className), children: [withIcon && iconElement, showTitle && (_jsxs("div", { className: titlePositionClass, children: [title && (_jsx(Text, { as: "div", variant: "subheader-2", className: b('title'), children: title })), preview && _jsx("div", { className: b('preview'), children: preview })] })), _jsxs(ButtonGroup, { children: [additionalActions.map((action, index) => renderAdditionalAction(action, index)), baseActions.map((action) => renderBaseAction(action, historyButtonRef))] })] }));
|
|
66
65
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Meta, StoryFn, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import { type HeaderProps } from '../index';
|
|
3
|
+
declare const _default: Meta;
|
|
4
|
+
export default _default;
|
|
5
|
+
export declare const Playground: StoryFn<HeaderProps>;
|
|
6
|
+
export declare const WithTitle: StoryFn<HeaderProps>;
|
|
7
|
+
export declare const WithIcon: StoryFn<HeaderProps>;
|
|
8
|
+
export declare const WithoutIcon: StoryFn<HeaderProps>;
|
|
9
|
+
export declare const WithPreview: StoryFn<HeaderProps>;
|
|
10
|
+
export declare const WithoutTitle: StoryFn<HeaderProps>;
|
|
11
|
+
export declare const TitlePositions: StoryObj<HeaderProps>;
|
|
12
|
+
export declare const BaseActions: StoryObj<HeaderProps>;
|
|
13
|
+
export declare const AdditionalActions: StoryFn<HeaderProps>;
|
|
14
|
+
export declare const FullExample: StoryFn<HeaderProps>;
|
|
15
|
+
export declare const FoldingInteractive: StoryFn<HeaderProps>;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Gear } from '@gravity-ui/icons';
|
|
4
|
+
import { Icon } from '@gravity-ui/uikit';
|
|
5
|
+
import { ContentWrapper } from '../../../../demo/ContentWrapper';
|
|
6
|
+
import { Showcase } from '../../../../demo/Showcase';
|
|
7
|
+
import { ShowcaseItem } from '../../../../demo/ShowcaseItem';
|
|
8
|
+
import { Header, HeaderAction } from '../index';
|
|
9
|
+
import MDXDocs from './Docs.mdx';
|
|
10
|
+
export default {
|
|
11
|
+
title: 'organisms/Header',
|
|
12
|
+
component: Header,
|
|
13
|
+
parameters: {
|
|
14
|
+
docs: {
|
|
15
|
+
page: MDXDocs,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
argTypes: {
|
|
19
|
+
titlePosition: {
|
|
20
|
+
control: 'radio',
|
|
21
|
+
options: ['left', 'center'],
|
|
22
|
+
description: 'Title position',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
const defaultDecorators = [
|
|
27
|
+
(Story) => (_jsx(Showcase, { children: _jsx(Story, {}) })),
|
|
28
|
+
];
|
|
29
|
+
// Mock handlers for actions
|
|
30
|
+
const mockHandlers = {
|
|
31
|
+
handleNewChat: () => {
|
|
32
|
+
// eslint-disable-next-line no-console
|
|
33
|
+
console.log('New chat clicked');
|
|
34
|
+
},
|
|
35
|
+
handleHistoryToggle: () => {
|
|
36
|
+
// eslint-disable-next-line no-console
|
|
37
|
+
console.log('History toggle clicked');
|
|
38
|
+
},
|
|
39
|
+
handleFolding: (value) => {
|
|
40
|
+
// eslint-disable-next-line no-console
|
|
41
|
+
console.log('Folding clicked:', value);
|
|
42
|
+
},
|
|
43
|
+
handleClose: () => {
|
|
44
|
+
// eslint-disable-next-line no-console
|
|
45
|
+
console.log('Close clicked');
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
export const Playground = (args) => {
|
|
49
|
+
return (_jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({}, args)) }));
|
|
50
|
+
};
|
|
51
|
+
Playground.args = Object.assign({ title: 'Chat Header', baseActions: [
|
|
52
|
+
HeaderAction.NewChat,
|
|
53
|
+
HeaderAction.History,
|
|
54
|
+
HeaderAction.Folding,
|
|
55
|
+
HeaderAction.Close,
|
|
56
|
+
], foldingState: 'opened' }, mockHandlers);
|
|
57
|
+
export const WithTitle = (args) => {
|
|
58
|
+
return (_jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "Chat Header", baseActions: [HeaderAction.NewChat, HeaderAction.History, HeaderAction.Close] }, mockHandlers, args)) }));
|
|
59
|
+
};
|
|
60
|
+
export const WithIcon = (args) => {
|
|
61
|
+
return (_jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ icon: _jsx("div", { style: { width: 24, height: 24, background: '#ccc', borderRadius: 4 } }), title: "Chat Header", baseActions: [HeaderAction.NewChat, HeaderAction.History, HeaderAction.Close] }, mockHandlers, args)) }));
|
|
62
|
+
};
|
|
63
|
+
export const WithoutIcon = (args) => {
|
|
64
|
+
return (_jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ withIcon: false, title: "Chat Header", baseActions: [HeaderAction.NewChat, HeaderAction.History, HeaderAction.Close] }, mockHandlers, args)) }));
|
|
65
|
+
};
|
|
66
|
+
export const WithPreview = (args) => {
|
|
67
|
+
return (_jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "Chat Header", preview: _jsx("div", { children: "Preview" }), baseActions: [HeaderAction.NewChat, HeaderAction.History, HeaderAction.Close] }, mockHandlers, args)) }));
|
|
68
|
+
};
|
|
69
|
+
export const WithoutTitle = (args) => {
|
|
70
|
+
return (_jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "Chat Header", preview: _jsx("div", { children: "Preview" }), showTitle: false, baseActions: [HeaderAction.NewChat, HeaderAction.History, HeaderAction.Close] }, mockHandlers, args)) }));
|
|
71
|
+
};
|
|
72
|
+
export const TitlePositions = {
|
|
73
|
+
render: (args) => {
|
|
74
|
+
return (_jsxs(_Fragment, { children: [_jsx(ShowcaseItem, { title: "Left", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "Left Title", titlePosition: "left", baseActions: [HeaderAction.NewChat, HeaderAction.Close] }, mockHandlers, args)) }) }), _jsx(ShowcaseItem, { title: "Center", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "Center Title", titlePosition: "center", baseActions: [HeaderAction.NewChat, HeaderAction.Close] }, mockHandlers, args)) }) })] }));
|
|
75
|
+
},
|
|
76
|
+
decorators: defaultDecorators,
|
|
77
|
+
};
|
|
78
|
+
export const BaseActions = {
|
|
79
|
+
render: (args) => {
|
|
80
|
+
return (_jsxs(_Fragment, { children: [_jsx(ShowcaseItem, { title: "All actions", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "All Actions", baseActions: [
|
|
81
|
+
HeaderAction.NewChat,
|
|
82
|
+
HeaderAction.History,
|
|
83
|
+
HeaderAction.Folding,
|
|
84
|
+
HeaderAction.Close,
|
|
85
|
+
], foldingState: "opened" }, mockHandlers)) }) }), _jsx(ShowcaseItem, { title: "Folding opened", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "With Folding (opened)", baseActions: [
|
|
86
|
+
HeaderAction.NewChat,
|
|
87
|
+
HeaderAction.History,
|
|
88
|
+
HeaderAction.Folding,
|
|
89
|
+
], foldingState: "opened" }, mockHandlers)) }) }), _jsx(ShowcaseItem, { title: "Folding collapsed", children: _jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "With Folding (collapsed)", baseActions: [
|
|
90
|
+
HeaderAction.NewChat,
|
|
91
|
+
HeaderAction.History,
|
|
92
|
+
HeaderAction.Folding,
|
|
93
|
+
], foldingState: "collapsed" }, mockHandlers, args)) }) })] }));
|
|
94
|
+
},
|
|
95
|
+
decorators: defaultDecorators,
|
|
96
|
+
};
|
|
97
|
+
// Статический массив для additionalActions - вынесен за пределы компонента,
|
|
98
|
+
// чтобы не создавать новый массив при каждом рендере
|
|
99
|
+
const additionalActionsConfig = [
|
|
100
|
+
{
|
|
101
|
+
label: 'Action 1',
|
|
102
|
+
onClick: () => {
|
|
103
|
+
// eslint-disable-next-line no-console
|
|
104
|
+
console.log('Additional action 1');
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
icon: _jsx(Icon, { data: Gear, size: 16 }),
|
|
109
|
+
onClick: () => {
|
|
110
|
+
// eslint-disable-next-line no-console
|
|
111
|
+
console.log('Settings clicked');
|
|
112
|
+
},
|
|
113
|
+
view: 'flat',
|
|
114
|
+
},
|
|
115
|
+
// Custom ReactNode
|
|
116
|
+
_jsx("button", { onClick: () => {
|
|
117
|
+
// eslint-disable-next-line no-console
|
|
118
|
+
console.log('Custom button');
|
|
119
|
+
}, style: { padding: '6px 12px', cursor: 'pointer' }, children: "Custom" }, "custom"),
|
|
120
|
+
];
|
|
121
|
+
export const AdditionalActions = (args) => {
|
|
122
|
+
return (_jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "With Additional Actions", baseActions: [HeaderAction.NewChat, HeaderAction.History, HeaderAction.Close], additionalActions: additionalActionsConfig }, mockHandlers, args)) }));
|
|
123
|
+
};
|
|
124
|
+
// Статический массив для FullExample - вынесен за пределы компонента
|
|
125
|
+
const fullExampleAdditionalActions = [
|
|
126
|
+
{
|
|
127
|
+
label: 'Settings',
|
|
128
|
+
view: 'outlined',
|
|
129
|
+
onClick: () => {
|
|
130
|
+
// eslint-disable-next-line no-console
|
|
131
|
+
console.log('Settings clicked');
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
icon: _jsx(Icon, { data: Gear, size: 16 }),
|
|
136
|
+
onClick: () => {
|
|
137
|
+
// eslint-disable-next-line no-console
|
|
138
|
+
console.log('Settings icon clicked');
|
|
139
|
+
},
|
|
140
|
+
view: 'flat',
|
|
141
|
+
},
|
|
142
|
+
];
|
|
143
|
+
export const FullExample = (args) => {
|
|
144
|
+
return (_jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ icon: _jsx("div", { style: { width: 24, height: 24, background: '#ccc', borderRadius: 4 } }), title: "Chat Header", preview: _jsx("div", { children: "Preview" }), baseActions: [HeaderAction.NewChat, HeaderAction.History, HeaderAction.Close], additionalActions: fullExampleAdditionalActions, titlePosition: "center" }, mockHandlers, args)) }));
|
|
145
|
+
};
|
|
146
|
+
// Interactive story to demonstrate folding state toggle
|
|
147
|
+
export const FoldingInteractive = (args) => {
|
|
148
|
+
const [foldingState, setFoldingState] = useState('opened');
|
|
149
|
+
return (_jsx(ContentWrapper, { width: "480px", children: _jsx(Header, Object.assign({ title: "Interactive Folding", baseActions: [
|
|
150
|
+
HeaderAction.NewChat,
|
|
151
|
+
HeaderAction.History,
|
|
152
|
+
HeaderAction.Folding,
|
|
153
|
+
HeaderAction.Close,
|
|
154
|
+
], foldingState: foldingState, handleFolding: (value) => {
|
|
155
|
+
setFoldingState(value);
|
|
156
|
+
// eslint-disable-next-line no-console
|
|
157
|
+
console.log('Folding state changed to:', value);
|
|
158
|
+
}, handleNewChat: mockHandlers.handleNewChat, handleHistoryToggle: mockHandlers.handleHistoryToggle, handleClose: mockHandlers.handleClose }, args)) }));
|
|
159
|
+
};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Action } from '../../../types/common';
|
|
2
2
|
export declare enum HeaderAction {
|
|
3
3
|
NewChat = "newChat",
|
|
4
4
|
History = "history",
|
|
5
5
|
Folding = "folding",
|
|
6
6
|
Close = "close"
|
|
7
7
|
}
|
|
8
|
-
export type AdditionalActionsConfig = ButtonProps | React.ReactNode;
|
|
9
8
|
export type HeaderProps = {
|
|
10
9
|
icon?: React.ReactNode;
|
|
11
10
|
title?: string;
|
|
@@ -15,7 +14,7 @@ export type HeaderProps = {
|
|
|
15
14
|
handleHistoryToggle?: () => void;
|
|
16
15
|
handleFolding?: (value: 'collapsed' | 'opened') => void;
|
|
17
16
|
handleClose?: () => void;
|
|
18
|
-
additionalActions?:
|
|
17
|
+
additionalActions?: Action[];
|
|
19
18
|
historyButtonRef?: React.RefObject<HTMLElement>;
|
|
20
19
|
foldingState?: 'collapsed' | 'opened';
|
|
21
20
|
titlePosition?: 'left' | 'center';
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Action } from '../../../types/common';
|
|
3
3
|
import { type HeaderProps } from './types';
|
|
4
4
|
export type ActionItem = {
|
|
5
5
|
id: string;
|
|
6
6
|
type: 'base' | 'additional';
|
|
7
|
-
content: React.ReactNode;
|
|
8
7
|
onClick?: () => void;
|
|
9
|
-
buttonProps?: ButtonProps;
|
|
10
8
|
foldingState?: 'collapsed' | 'opened';
|
|
11
9
|
};
|
|
12
10
|
export declare function useHeader(props: HeaderProps): {
|
|
@@ -14,7 +12,7 @@ export declare function useHeader(props: HeaderProps): {
|
|
|
14
12
|
preview: React.ReactNode | undefined;
|
|
15
13
|
icon: React.ReactNode | undefined;
|
|
16
14
|
baseActions: ActionItem[];
|
|
17
|
-
additionalActions:
|
|
15
|
+
additionalActions: Action[];
|
|
18
16
|
titlePosition: 'left' | 'center';
|
|
19
17
|
withIcon: boolean;
|
|
20
18
|
showTitle: boolean;
|