@asgard-js/react 0.0.43 → 0.0.44-canary.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 (136) hide show
  1. package/dist/components/chatbot/chatbot.d.ts +1 -1
  2. package/dist/components/chatbot/chatbot.d.ts.map +1 -1
  3. package/dist/context/asgard-service-context.d.ts +1 -1
  4. package/dist/context/asgard-service-context.d.ts.map +1 -1
  5. package/dist/hooks/use-channel.d.ts +1 -1
  6. package/dist/hooks/use-channel.d.ts.map +1 -1
  7. package/dist/index.js +20457 -20222
  8. package/package.json +3 -3
  9. package/.babelrc +0 -12
  10. package/eslint.config.cjs +0 -12
  11. package/src/components/.DS_Store +0 -0
  12. package/src/components/chatbot/api-key-input/api-key-input.module.scss +0 -156
  13. package/src/components/chatbot/api-key-input/api-key-input.tsx +0 -111
  14. package/src/components/chatbot/api-key-input/index.ts +0 -1
  15. package/src/components/chatbot/chatbot-body/chatbot-body.module.scss +0 -13
  16. package/src/components/chatbot/chatbot-body/chatbot-body.tsx +0 -45
  17. package/src/components/chatbot/chatbot-body/conversation-message-renderer.tsx +0 -55
  18. package/src/components/chatbot/chatbot-body/index.ts +0 -1
  19. package/src/components/chatbot/chatbot-container/chatbot-container.module.scss +0 -41
  20. package/src/components/chatbot/chatbot-container/chatbot-container.tsx +0 -49
  21. package/src/components/chatbot/chatbot-container/chatbot-full-screen-container.tsx +0 -54
  22. package/src/components/chatbot/chatbot-footer/chatbot-footer.module.scss +0 -67
  23. package/src/components/chatbot/chatbot-footer/chatbot-footer.tsx +0 -140
  24. package/src/components/chatbot/chatbot-footer/index.ts +0 -1
  25. package/src/components/chatbot/chatbot-footer/speech-input-button.tsx +0 -132
  26. package/src/components/chatbot/chatbot-header/chatbot-header.module.scss +0 -48
  27. package/src/components/chatbot/chatbot-header/chatbot-header.tsx +0 -98
  28. package/src/components/chatbot/chatbot-header/index.ts +0 -1
  29. package/src/components/chatbot/chatbot.module.scss +0 -24
  30. package/src/components/chatbot/chatbot.spec.tsx +0 -8
  31. package/src/components/chatbot/chatbot.tsx +0 -227
  32. package/src/components/chatbot/profile-icon.tsx +0 -26
  33. package/src/components/index.ts +0 -2
  34. package/src/components/templates/avatar/avatar.module.scss +0 -6
  35. package/src/components/templates/avatar/avatar.tsx +0 -28
  36. package/src/components/templates/avatar/index.ts +0 -1
  37. package/src/components/templates/button-template/button-template.module.scss +0 -0
  38. package/src/components/templates/button-template/button-template.tsx +0 -45
  39. package/src/components/templates/button-template/card.module.scss +0 -58
  40. package/src/components/templates/button-template/card.spec.tsx +0 -213
  41. package/src/components/templates/button-template/card.tsx +0 -123
  42. package/src/components/templates/button-template/index.ts +0 -1
  43. package/src/components/templates/carousel-template/carousel-template.module.scss +0 -15
  44. package/src/components/templates/carousel-template/carousel-template.tsx +0 -49
  45. package/src/components/templates/carousel-template/index.ts +0 -1
  46. package/src/components/templates/chart-template/chart-template.module.scss +0 -52
  47. package/src/components/templates/chart-template/chart-template.tsx +0 -75
  48. package/src/components/templates/chart-template/index.ts +0 -1
  49. package/src/components/templates/hint-template/hint-template.module.scss +0 -43
  50. package/src/components/templates/hint-template/hint-template.tsx +0 -76
  51. package/src/components/templates/hint-template/index.ts +0 -1
  52. package/src/components/templates/image-template/image-template.module.scss +0 -67
  53. package/src/components/templates/image-template/image-template.tsx +0 -58
  54. package/src/components/templates/image-template/index.ts +0 -1
  55. package/src/components/templates/index.ts +0 -10
  56. package/src/components/templates/quick-replies/index.ts +0 -1
  57. package/src/components/templates/quick-replies/quick-replies.module.scss +0 -16
  58. package/src/components/templates/quick-replies/quick-replies.tsx +0 -47
  59. package/src/components/templates/template-box/index.ts +0 -2
  60. package/src/components/templates/template-box/template-box-content.module.scss +0 -13
  61. package/src/components/templates/template-box/template-box-content.tsx +0 -30
  62. package/src/components/templates/template-box/template-box.module.scss +0 -19
  63. package/src/components/templates/template-box/template-box.tsx +0 -48
  64. package/src/components/templates/text-template/bot-typing-box.tsx +0 -81
  65. package/src/components/templates/text-template/bot-typing-placeholder.tsx +0 -28
  66. package/src/components/templates/text-template/index.ts +0 -3
  67. package/src/components/templates/text-template/text-template.module.scss +0 -131
  68. package/src/components/templates/text-template/text-template.tsx +0 -94
  69. package/src/components/templates/text-template/use-react-markdown-renderer.spec.tsx +0 -758
  70. package/src/components/templates/time/index.ts +0 -1
  71. package/src/components/templates/time/time.module.scss +0 -6
  72. package/src/components/templates/time/time.tsx +0 -34
  73. package/src/context/asgard-app-initialization-context.tsx +0 -154
  74. package/src/context/asgard-service-context.tsx +0 -148
  75. package/src/context/asgard-template-context.tsx +0 -83
  76. package/src/context/asgard-theme-context.tsx +0 -553
  77. package/src/context/index.ts +0 -4
  78. package/src/hooks/index.ts +0 -11
  79. package/src/hooks/use-asgard-service-client.ts +0 -68
  80. package/src/hooks/use-channel.ts +0 -160
  81. package/src/hooks/use-debounce.ts +0 -18
  82. package/src/hooks/use-deep-compare-memo.ts +0 -19
  83. package/src/hooks/use-is-on-screen-keyboard-open.ts +0 -43
  84. package/src/hooks/use-on-screen-keyboard-scroll-fix.ts +0 -17
  85. package/src/hooks/use-prevent-over-scrolling.ts +0 -77
  86. package/src/hooks/use-react-markdown-renderer.tsx +0 -278
  87. package/src/hooks/use-resize-observer.tsx +0 -27
  88. package/src/hooks/use-update-vh.ts +0 -30
  89. package/src/hooks/use-viewport-size.ts +0 -51
  90. package/src/icons/add_a_photo.svg +0 -3
  91. package/src/icons/bot.svg +0 -14
  92. package/src/icons/close.svg +0 -3
  93. package/src/icons/distance.svg +0 -3
  94. package/src/icons/eye-off.svg +0 -4
  95. package/src/icons/eye.svg +0 -4
  96. package/src/icons/mic.svg +0 -3
  97. package/src/icons/photo_library.svg +0 -3
  98. package/src/icons/profile.svg +0 -28
  99. package/src/icons/refresh.svg +0 -3
  100. package/src/icons/send.svg +0 -3
  101. package/src/icons/stop.svg +0 -22
  102. package/src/icons/volume_up.svg +0 -3
  103. package/src/index.ts +0 -4
  104. package/src/models/bot-provider.ts +0 -108
  105. package/src/styles/_index.scss +0 -1
  106. package/src/styles/_styles.scss +0 -11
  107. package/src/styles/colors/_colors.scss +0 -10
  108. package/src/styles/colors/_index.scss +0 -1
  109. package/src/styles/colors/_variables.scss +0 -72
  110. package/src/styles/palette/_index.scss +0 -1
  111. package/src/styles/palette/_palette.scss +0 -42
  112. package/src/styles/palette/_variables.scss +0 -40
  113. package/src/styles/radius/_index.scss +0 -1
  114. package/src/styles/radius/_radius.scss +0 -8
  115. package/src/styles/radius/_variables.scss +0 -12
  116. package/src/styles/spacing/_index.scss +0 -1
  117. package/src/styles/spacing/_spacing.scss +0 -8
  118. package/src/styles/spacing/_variables.scss +0 -13
  119. package/src/styles/utils/_index.scss +0 -1
  120. package/src/styles/utils/_map.scss +0 -22
  121. package/src/test-setup.ts +0 -1
  122. package/src/utils/color-utils.ts +0 -52
  123. package/src/utils/deep-merge.ts +0 -26
  124. package/src/utils/extractors.ts +0 -20
  125. package/src/utils/format-time.ts +0 -8
  126. package/src/utils/index.ts +0 -1
  127. package/src/utils/is.ts +0 -72
  128. package/src/utils/selectors.ts +0 -7
  129. package/src/utils/uri-validation.spec.ts +0 -208
  130. package/src/utils/uri-validation.ts +0 -103
  131. package/tsconfig.json +0 -16
  132. package/tsconfig.lib.json +0 -63
  133. package/tsconfig.spec.json +0 -36
  134. package/tsconfig.tsbuildinfo +0 -1
  135. package/vite.config.ts +0 -63
  136. /package/dist/{style.css → index.css} +0 -0
@@ -1,26 +0,0 @@
1
- import { ReactNode } from 'react';
2
- import ProfileSvg from '../../icons/profile.svg?react';
3
-
4
- interface ProfileIconProps {
5
- avatar?: string;
6
- }
7
-
8
- export function ProfileIcon(props: ProfileIconProps): ReactNode {
9
- const { avatar } = props;
10
-
11
- if (avatar) {
12
- return (
13
- <img
14
- src={avatar}
15
- alt="avatar"
16
- style={{
17
- width: 33,
18
- height: 32,
19
- borderRadius: '50%',
20
- }}
21
- />
22
- );
23
- }
24
-
25
- return <ProfileSvg />;
26
- }
@@ -1,2 +0,0 @@
1
- export * from './chatbot/chatbot';
2
- export * from './templates';
@@ -1,6 +0,0 @@
1
- .bot_avatar {
2
- flex: 0 0 auto;
3
- width: 24px;
4
- height: 24px;
5
- border-radius: 50%;
6
- }
@@ -1,28 +0,0 @@
1
- import { memo, ReactNode } from 'react';
2
- import styles from './avatar.module.scss';
3
- import BotSvg from '../../../icons/bot.svg?react';
4
- import clsx from 'clsx';
5
-
6
- interface AvatarProps {
7
- avatar?: string;
8
- }
9
-
10
- export const Avatar = memo((props: AvatarProps): ReactNode => {
11
- const { avatar } = props;
12
-
13
- if (avatar) {
14
- return (
15
- <img
16
- src={avatar}
17
- alt="Bot Avatar"
18
- className={clsx('asgard-avatar', styles.bot_avatar)}
19
- />
20
- );
21
- }
22
-
23
- return (
24
- <div className={clsx('asgard-avatar', styles.bot_avatar)}>
25
- <BotSvg />
26
- </div>
27
- );
28
- });
@@ -1 +0,0 @@
1
- export * from './avatar';
@@ -1,45 +0,0 @@
1
- import { ButtonMessageTemplate, ConversationBotMessage } from '@asgard-js/core';
2
- import { ReactNode } from 'react';
3
- import { TemplateBox, TemplateBoxContent } from '../template-box';
4
- import { Avatar } from '../avatar';
5
- import { Card } from './card';
6
- import { useAsgardContext } from '../../../context/asgard-service-context';
7
- import { useAsgardThemeContext } from '../../../context/asgard-theme-context';
8
-
9
- interface ButtonTemplateProps {
10
- message: ConversationBotMessage;
11
- }
12
-
13
- export function ButtonTemplate(props: ButtonTemplateProps): ReactNode {
14
- const { message } = props;
15
-
16
- const { template: themeTemplate } = useAsgardThemeContext();
17
-
18
- const { avatar } = useAsgardContext();
19
-
20
- const template = message.message.template as ButtonMessageTemplate;
21
-
22
- return (
23
- <TemplateBox
24
- className="asgard-button-template"
25
- type="bot"
26
- direction="horizontal"
27
- style={themeTemplate?.ButtonMessageTemplate?.style}
28
- >
29
- <Avatar avatar={avatar} />
30
- <TemplateBoxContent
31
- time={message.time}
32
- quickReplies={template?.quickReplies}
33
- >
34
- <Card
35
- template={template}
36
- customStyle={{
37
- button: {
38
- style: themeTemplate?.ButtonMessageTemplate?.button?.style ?? {},
39
- },
40
- }}
41
- />
42
- </TemplateBoxContent>
43
- </TemplateBox>
44
- );
45
- }
@@ -1,58 +0,0 @@
1
- .card_root {
2
- width: 255px;
3
- height: 368px;
4
- max-height: 380px;
5
- border-radius: 8px;
6
- background: rgba(51, 51, 51, 1);
7
- overflow: hidden;
8
- display: grid;
9
- grid-template-rows: max-content auto;
10
- }
11
-
12
- .card_content {
13
- display: grid;
14
- grid-template-rows: 1.5em auto max-content;
15
- gap: var(--asg-spacing-2);
16
- padding: 12px;
17
- line-height: 1.5em;
18
- }
19
-
20
- .card_title {
21
- color: white;
22
- margin: 0;
23
- font-size: 15px;
24
- }
25
-
26
- .card_description {
27
- color: rgba(140, 140, 140, 1);
28
- font-size: 13px;
29
- font-weight: 400;
30
- max-height: 4.5em;
31
- overflow: hidden;
32
- text-overflow: ellipsis;
33
- display: -webkit-box;
34
- line-clamp: 3;
35
- -webkit-line-clamp: 3;
36
- -webkit-box-orient: vertical;
37
- text-underline-position: from-font;
38
- text-decoration-skip-ink: none;
39
- }
40
-
41
- .card_actions {
42
- display: flex;
43
- flex-direction: column;
44
- gap: 8px;
45
-
46
- > button {
47
- width: 100%;
48
- height: 32px;
49
- line-height: 32px;
50
- text-align: center;
51
- border: none;
52
- border-radius: 4px;
53
- background: rgba(71, 103, 235, 1);
54
- color: white;
55
- font-size: 15px;
56
- cursor: pointer;
57
- }
58
- }
@@ -1,213 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
- import { render, screen, fireEvent } from '@testing-library/react';
3
- import { Card } from './card';
4
- import { MessageTemplateType } from '@asgard-js/core';
5
- import { useAsgardContext } from '../../../context/asgard-service-context';
6
- import { useAsgardTemplateContext } from '../../../context/asgard-template-context';
7
- import * as uriValidation from '../../../utils/uri-validation';
8
-
9
- // Mock the contexts
10
- vi.mock('../../../context/asgard-service-context');
11
- vi.mock('../../../context/asgard-template-context');
12
-
13
- // Mock the URI validation utility
14
- vi.mock('../../../utils/uri-validation');
15
-
16
- const mockUseAsgardContext = vi.mocked(useAsgardContext);
17
- const mockUseAsgardTemplateContext = vi.mocked(useAsgardTemplateContext);
18
- const mockSafeWindowOpen = vi.mocked(uriValidation.safeWindowOpen);
19
-
20
- describe('Card Component - Security Tests', () => {
21
- const mockSendMessage = vi.fn();
22
- const mockOnTemplateBtnClick = vi.fn();
23
- const defaultLinkTarget = '_blank';
24
-
25
- // Define malicious URI as variable to avoid ESLint script URL warning
26
- // eslint-disable-next-line no-script-url
27
- const maliciousJsUri = 'javascript:alert("xss")';
28
-
29
- const baseTemplate = {
30
- type: MessageTemplateType.BUTTON,
31
- title: 'Test Card',
32
- text: 'Test description',
33
- thumbnailImageUrl: 'https://example.com/image.jpg',
34
- imageAspectRatio: 'rectangle' as const,
35
- imageSize: 'cover' as const,
36
- imageBackgroundColor: '#ffffff',
37
- defaultAction: {
38
- type: 'message' as const,
39
- text: 'Default action',
40
- },
41
- quickReplies: [],
42
- buttons: [
43
- {
44
- label: 'Safe Link',
45
- action: {
46
- type: 'uri' as const,
47
- uri: 'https://example.com',
48
- },
49
- },
50
- {
51
- label: 'Malicious Link',
52
- action: {
53
- type: 'uri' as const,
54
- uri: maliciousJsUri,
55
- },
56
- },
57
- ],
58
- };
59
-
60
- beforeEach(() => {
61
- mockUseAsgardContext.mockReturnValue({
62
- sendMessage: mockSendMessage,
63
- client: null,
64
- isOpen: false,
65
- isResetting: false,
66
- isConnecting: false,
67
- conversation: null,
68
- resetChannel: vi.fn(),
69
- closeChannel: vi.fn(),
70
- avatar: null,
71
- });
72
-
73
- mockUseAsgardTemplateContext.mockReturnValue({
74
- onTemplateBtnClick: mockOnTemplateBtnClick,
75
- defaultLinkTarget,
76
- onErrorClick: undefined,
77
- errorMessageRenderer: undefined,
78
- });
79
-
80
- mockSafeWindowOpen.mockReturnValue(null);
81
- });
82
-
83
- afterEach(() => {
84
- vi.clearAllMocks();
85
- });
86
-
87
- describe('URI security validation', () => {
88
- it('should call safeWindowOpen for URI actions instead of window.open directly', () => {
89
- render(<Card template={baseTemplate} />);
90
-
91
- const safeButton = screen.getByText('Safe Link');
92
- fireEvent.click(safeButton);
93
-
94
- expect(mockSafeWindowOpen).toHaveBeenCalledWith(
95
- 'https://example.com',
96
- '_blank'
97
- );
98
- });
99
-
100
- it('should call safeWindowOpen for malicious URIs (letting validation utility handle security)', () => {
101
- render(<Card template={baseTemplate} />);
102
-
103
- const maliciousButton = screen.getByText('Malicious Link');
104
- fireEvent.click(maliciousButton);
105
-
106
- expect(mockSafeWindowOpen).toHaveBeenCalledWith(
107
- maliciousJsUri,
108
- '_blank'
109
- );
110
- });
111
-
112
- it('should use action target if provided', () => {
113
- const templateWithTarget = {
114
- ...baseTemplate,
115
- buttons: [
116
- {
117
- label: 'Link with Target',
118
- action: {
119
- type: 'uri' as const,
120
- uri: 'https://example.com',
121
- target: '_self' as const,
122
- },
123
- },
124
- ],
125
- };
126
-
127
- render(<Card template={templateWithTarget} />);
128
-
129
- const button = screen.getByText('Link with Target');
130
- fireEvent.click(button);
131
-
132
- expect(mockSafeWindowOpen).toHaveBeenCalledWith(
133
- 'https://example.com',
134
- '_self'
135
- );
136
- });
137
-
138
- it('should fallback to defaultLinkTarget when no action target', () => {
139
- mockUseAsgardTemplateContext.mockReturnValue({
140
- onTemplateBtnClick: mockOnTemplateBtnClick,
141
- defaultLinkTarget: '_parent',
142
- });
143
-
144
- render(<Card template={baseTemplate} />);
145
-
146
- const safeButton = screen.getByText('Safe Link');
147
- fireEvent.click(safeButton);
148
-
149
- expect(mockSafeWindowOpen).toHaveBeenCalledWith(
150
- 'https://example.com',
151
- '_parent'
152
- );
153
- });
154
-
155
- it('should fallback to _blank when no action target or defaultLinkTarget', () => {
156
- mockUseAsgardTemplateContext.mockReturnValue({
157
- onTemplateBtnClick: mockOnTemplateBtnClick,
158
- defaultLinkTarget: undefined,
159
- });
160
-
161
- render(<Card template={baseTemplate} />);
162
-
163
- const safeButton = screen.getByText('Safe Link');
164
- fireEvent.click(safeButton);
165
-
166
- expect(mockSafeWindowOpen).toHaveBeenCalledWith(
167
- 'https://example.com',
168
- '_blank'
169
- );
170
- });
171
-
172
- it('should handle uppercase URI action type', () => {
173
- const templateWithUppercase = {
174
- ...baseTemplate,
175
- buttons: [
176
- {
177
- label: 'Uppercase URI',
178
- action: {
179
- type: 'URI' as const,
180
- uri: 'https://example.com',
181
- },
182
- },
183
- ],
184
- };
185
-
186
- render(<Card template={templateWithUppercase} />);
187
-
188
- const button = screen.getByText('Uppercase URI');
189
- fireEvent.click(button);
190
-
191
- expect(mockSafeWindowOpen).toHaveBeenCalledWith(
192
- 'https://example.com',
193
- '_blank'
194
- );
195
- });
196
- });
197
-
198
- describe('basic rendering', () => {
199
- it('should render card with title and description', () => {
200
- render(<Card template={baseTemplate} />);
201
-
202
- expect(screen.getByText('Test Card')).toBeDefined();
203
- expect(screen.getByText('Test description')).toBeDefined();
204
- });
205
-
206
- it('should render buttons', () => {
207
- render(<Card template={baseTemplate} />);
208
-
209
- expect(screen.getByText('Safe Link')).toBeDefined();
210
- expect(screen.getByText('Malicious Link')).toBeDefined();
211
- });
212
- });
213
- });
@@ -1,123 +0,0 @@
1
- import {
2
- MouseEventHandler,
3
- ReactNode,
4
- useCallback,
5
- useMemo,
6
- CSSProperties,
7
- } from 'react';
8
- import styles from './card.module.scss';
9
- import {
10
- ButtonAction,
11
- ButtonMessageTemplate,
12
- CarouselMessageTemplate,
13
- } from '@asgard-js/core';
14
- import { useAsgardContext } from '../../../context/asgard-service-context';
15
- import { useAsgardTemplateContext } from '../../../context/asgard-template-context';
16
- import { safeWindowOpen } from '../../../utils/uri-validation';
17
- import clsx from 'clsx';
18
-
19
- interface CardProps {
20
- template: ButtonMessageTemplate | CarouselMessageTemplate['columns'][number];
21
- customStyle?: {
22
- style?: CSSProperties;
23
- button?: {
24
- style?: CSSProperties;
25
- };
26
- };
27
- }
28
-
29
- export function Card(props: CardProps): ReactNode {
30
- const { template, customStyle } = props;
31
-
32
- const { sendMessage } = useAsgardContext();
33
- const { onTemplateBtnClick, defaultLinkTarget } = useAsgardTemplateContext();
34
-
35
- const src = useMemo(() => {
36
- return (
37
- template?.thumbnailImageUrl
38
- ?.replace(/^http:/, '')
39
- .replace(/^https:/, '') ||
40
- 'https://via.assets.so/img.jpg?w=200&h=270&tc=white&bg=#eeeeee'
41
- );
42
- }, [template]);
43
-
44
- const aspectRatio = useMemo(() => {
45
- switch (template?.imageAspectRatio) {
46
- case 'square':
47
- return '1 / 1';
48
- case 'rectangle':
49
- default:
50
- return '1.51 / 1';
51
- }
52
- }, [template]);
53
-
54
- const handleClick = useCallback(
55
- (action: ButtonAction): MouseEventHandler<HTMLButtonElement> => {
56
- return function clickHandler() {
57
- switch (action.type) {
58
- case 'message':
59
- case 'MESSAGE':
60
- sendMessage?.({ text: action.text });
61
-
62
- return;
63
- case 'uri':
64
- case 'URI':
65
- safeWindowOpen(
66
- action.uri,
67
- action.target || defaultLinkTarget || '_blank'
68
- );
69
-
70
- return;
71
- case 'emit':
72
- case 'EMIT':
73
- onTemplateBtnClick?.(action.payload, {
74
- sse: {
75
- sendMessage: (payload) => {
76
- sendMessage?.(payload);
77
- },
78
- },
79
- });
80
-
81
- return;
82
- }
83
- };
84
- },
85
- [sendMessage, onTemplateBtnClick, defaultLinkTarget]
86
- );
87
-
88
- return (
89
- <div
90
- className={clsx('asgard-card', styles.card_root)}
91
- style={customStyle?.style}
92
- >
93
- {template?.thumbnailImageUrl && (
94
- <img
95
- alt={template?.title}
96
- src={src}
97
- style={{
98
- display: 'block',
99
- width: '100%',
100
- maxHeight: '170px',
101
- objectFit: template?.imageSize,
102
- aspectRatio,
103
- }}
104
- />
105
- )}
106
- <div className={styles.card_content}>
107
- <h5 className={styles.card_title}>{template?.title}</h5>
108
- <div className={styles.card_description}>{template?.text}</div>
109
- <div className={styles.card_actions}>
110
- {template?.buttons?.map((btn: { label: string; action: ButtonAction }, index: number) => (
111
- <button
112
- key={index}
113
- onClick={handleClick(btn.action)}
114
- style={customStyle?.button?.style}
115
- >
116
- {btn.label}
117
- </button>
118
- ))}
119
- </div>
120
- </div>
121
- </div>
122
- );
123
- }
@@ -1 +0,0 @@
1
- export * from './button-template';
@@ -1,15 +0,0 @@
1
- .carousel_root {
2
- width: 100%;
3
- display: flex;
4
- flex-wrap: nowrap;
5
- overflow-x: scroll;
6
- gap: 8px;
7
-
8
- > div {
9
- flex: 0 0 auto;
10
- }
11
- }
12
-
13
- .carousel_time {
14
- justify-content: flex-end;
15
- }
@@ -1,49 +0,0 @@
1
- import { ReactNode } from 'react';
2
- import { TemplateBox, TemplateBoxContent } from '../template-box';
3
- import { Avatar } from '../avatar';
4
- import styles from './carousel-template.module.scss';
5
- import { Card } from '../button-template/card';
6
- import {
7
- CarouselMessageTemplate,
8
- ConversationBotMessage,
9
- ButtonMessageTemplate,
10
- } from '@asgard-js/core';
11
- import { Time } from '../time';
12
- import { useAsgardContext } from '../../../context/asgard-service-context';
13
- import { useAsgardThemeContext } from '../../../context/asgard-theme-context';
14
-
15
- interface CarouselTemplateProps {
16
- message: ConversationBotMessage;
17
- }
18
-
19
- export function CarouselTemplate(props: CarouselTemplateProps): ReactNode {
20
- const { message } = props;
21
-
22
- const { template: themeTemplate } = useAsgardThemeContext();
23
- const { avatar } = useAsgardContext();
24
-
25
- const template = message.message.template as CarouselMessageTemplate;
26
-
27
- return (
28
- <TemplateBox
29
- className="asgard-carousel-template"
30
- type="bot"
31
- direction="vertical"
32
- style={themeTemplate?.CarouselMessageTemplate?.style}
33
- >
34
- <Avatar avatar={avatar} />
35
- <TemplateBoxContent quickReplies={template.quickReplies}>
36
- <div className={styles.carousel_root}>
37
- {template.columns?.map((column: Omit<ButtonMessageTemplate, 'type' | 'quickReplies'>, index: number) => (
38
- <Card
39
- key={index}
40
- template={column}
41
- customStyle={themeTemplate?.CarouselMessageTemplate?.card}
42
- />
43
- ))}
44
- </div>
45
- </TemplateBoxContent>
46
- <Time className={styles.carousel_time} time={message.time} />
47
- </TemplateBox>
48
- );
49
- }
@@ -1 +0,0 @@
1
- export * from './carousel-template';
@@ -1,52 +0,0 @@
1
- .text {
2
- display: inline-block;
3
- padding: 8px 12px;
4
- border-radius: 8px;
5
- color: white;
6
- word-break: break-all;
7
-
8
- > span {
9
- word-break: break-all;
10
- }
11
-
12
- .md_container {
13
- display: inline-block;
14
-
15
- p {
16
- margin: 0;
17
- }
18
- }
19
- }
20
-
21
- .text--user {
22
- max-width: 75%;
23
- background: #4767eb;
24
- border-top-right-radius: 0;
25
- }
26
-
27
- .text--bot {
28
- max-width: 70%;
29
- background: #585858;
30
- border-top-left-radius: 0;
31
- }
32
-
33
- .chart_time {
34
- justify-content: flex-end;
35
- }
36
-
37
- .quick_replies_box {
38
- display: flex;
39
- flex-wrap: wrap;
40
- gap: 8px;
41
- }
42
-
43
- .quick_reply {
44
- font: inherit;
45
- font-size: 13px;
46
- padding: 4px 8px;
47
- border-radius: 8px;
48
- border: 1px solid #434343;
49
- background: rgba(88, 88, 88, 0.2);
50
- color: white;
51
- cursor: pointer;
52
- }