@asgard-js/react 0.0.40-canary.2 → 0.0.41-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 (146) hide show
  1. package/dist/components/chatbot/chatbot-body/conversation-message-renderer.d.ts.map +1 -1
  2. package/dist/components/chatbot/chatbot-footer/chatbot-footer.d.ts.map +1 -1
  3. package/dist/components/chatbot/chatbot.d.ts +0 -3
  4. package/dist/components/chatbot/chatbot.d.ts.map +1 -1
  5. package/dist/components/templates/index.d.ts +1 -0
  6. package/dist/components/templates/index.d.ts.map +1 -1
  7. package/dist/components/templates/user-image-template/index.d.ts +2 -0
  8. package/dist/components/templates/user-image-template/index.d.ts.map +1 -0
  9. package/dist/components/templates/user-image-template/user-image-template.d.ts +12 -0
  10. package/dist/components/templates/user-image-template/user-image-template.d.ts.map +1 -0
  11. package/dist/context/asgard-service-context.d.ts +1 -0
  12. package/dist/context/asgard-service-context.d.ts.map +1 -1
  13. package/dist/hooks/use-channel.d.ts +1 -1
  14. package/dist/hooks/use-channel.d.ts.map +1 -1
  15. package/dist/index.js +18568 -19052
  16. package/dist/style.css +1 -1
  17. package/dist/utils/file-validation.d.ts +12 -0
  18. package/dist/utils/file-validation.d.ts.map +1 -0
  19. package/package.json +2 -2
  20. package/.babelrc +0 -12
  21. package/dist/components/chatbot/api-key-input/api-key-input.d.ts +0 -11
  22. package/dist/components/chatbot/api-key-input/api-key-input.d.ts.map +0 -1
  23. package/dist/components/chatbot/api-key-input/index.d.ts +0 -2
  24. package/dist/components/chatbot/api-key-input/index.d.ts.map +0 -1
  25. package/eslint.config.cjs +0 -12
  26. package/src/components/chatbot/api-key-input/api-key-input.module.scss +0 -192
  27. package/src/components/chatbot/api-key-input/api-key-input.tsx +0 -119
  28. package/src/components/chatbot/api-key-input/index.ts +0 -1
  29. package/src/components/chatbot/chatbot-body/chatbot-body.module.scss +0 -13
  30. package/src/components/chatbot/chatbot-body/chatbot-body.tsx +0 -45
  31. package/src/components/chatbot/chatbot-body/conversation-message-renderer.tsx +0 -55
  32. package/src/components/chatbot/chatbot-body/index.ts +0 -1
  33. package/src/components/chatbot/chatbot-container/chatbot-container.module.scss +0 -41
  34. package/src/components/chatbot/chatbot-container/chatbot-container.tsx +0 -49
  35. package/src/components/chatbot/chatbot-container/chatbot-full-screen-container.tsx +0 -54
  36. package/src/components/chatbot/chatbot-footer/chatbot-footer.module.scss +0 -67
  37. package/src/components/chatbot/chatbot-footer/chatbot-footer.tsx +0 -140
  38. package/src/components/chatbot/chatbot-footer/index.ts +0 -1
  39. package/src/components/chatbot/chatbot-footer/speech-input-button.tsx +0 -132
  40. package/src/components/chatbot/chatbot-header/chatbot-header.module.scss +0 -48
  41. package/src/components/chatbot/chatbot-header/chatbot-header.tsx +0 -98
  42. package/src/components/chatbot/chatbot-header/index.ts +0 -1
  43. package/src/components/chatbot/chatbot.spec.tsx +0 -8
  44. package/src/components/chatbot/chatbot.tsx +0 -195
  45. package/src/components/chatbot/profile-icon.tsx +0 -26
  46. package/src/components/index.ts +0 -2
  47. package/src/components/templates/avatar/avatar.module.scss +0 -6
  48. package/src/components/templates/avatar/avatar.tsx +0 -28
  49. package/src/components/templates/avatar/index.ts +0 -1
  50. package/src/components/templates/button-template/button-template.module.scss +0 -0
  51. package/src/components/templates/button-template/button-template.tsx +0 -45
  52. package/src/components/templates/button-template/card.module.scss +0 -58
  53. package/src/components/templates/button-template/card.spec.tsx +0 -213
  54. package/src/components/templates/button-template/card.tsx +0 -123
  55. package/src/components/templates/button-template/index.ts +0 -1
  56. package/src/components/templates/carousel-template/carousel-template.module.scss +0 -15
  57. package/src/components/templates/carousel-template/carousel-template.tsx +0 -49
  58. package/src/components/templates/carousel-template/index.ts +0 -1
  59. package/src/components/templates/chart-template/chart-template.module.scss +0 -52
  60. package/src/components/templates/chart-template/chart-template.tsx +0 -75
  61. package/src/components/templates/chart-template/index.ts +0 -1
  62. package/src/components/templates/hint-template/hint-template.module.scss +0 -43
  63. package/src/components/templates/hint-template/hint-template.tsx +0 -76
  64. package/src/components/templates/hint-template/index.ts +0 -1
  65. package/src/components/templates/image-template/image-template.module.scss +0 -67
  66. package/src/components/templates/image-template/image-template.tsx +0 -58
  67. package/src/components/templates/image-template/index.ts +0 -1
  68. package/src/components/templates/index.ts +0 -10
  69. package/src/components/templates/quick-replies/index.ts +0 -1
  70. package/src/components/templates/quick-replies/quick-replies.module.scss +0 -16
  71. package/src/components/templates/quick-replies/quick-replies.tsx +0 -47
  72. package/src/components/templates/template-box/index.ts +0 -2
  73. package/src/components/templates/template-box/template-box-content.module.scss +0 -13
  74. package/src/components/templates/template-box/template-box-content.tsx +0 -30
  75. package/src/components/templates/template-box/template-box.module.scss +0 -19
  76. package/src/components/templates/template-box/template-box.tsx +0 -48
  77. package/src/components/templates/text-template/bot-typing-box.tsx +0 -81
  78. package/src/components/templates/text-template/bot-typing-placeholder.tsx +0 -28
  79. package/src/components/templates/text-template/index.ts +0 -3
  80. package/src/components/templates/text-template/text-template.module.scss +0 -131
  81. package/src/components/templates/text-template/text-template.tsx +0 -94
  82. package/src/components/templates/text-template/use-react-markdown-renderer.spec.tsx +0 -758
  83. package/src/components/templates/time/index.ts +0 -1
  84. package/src/components/templates/time/time.module.scss +0 -6
  85. package/src/components/templates/time/time.tsx +0 -34
  86. package/src/context/asgard-app-initialization-context.tsx +0 -154
  87. package/src/context/asgard-service-context.tsx +0 -145
  88. package/src/context/asgard-template-context.tsx +0 -83
  89. package/src/context/asgard-theme-context.tsx +0 -546
  90. package/src/context/index.ts +0 -4
  91. package/src/hooks/index.ts +0 -11
  92. package/src/hooks/use-asgard-service-client.ts +0 -68
  93. package/src/hooks/use-channel.ts +0 -154
  94. package/src/hooks/use-debounce.ts +0 -18
  95. package/src/hooks/use-deep-compare-memo.ts +0 -19
  96. package/src/hooks/use-is-on-screen-keyboard-open.ts +0 -43
  97. package/src/hooks/use-on-screen-keyboard-scroll-fix.ts +0 -15
  98. package/src/hooks/use-prevent-over-scrolling.ts +0 -77
  99. package/src/hooks/use-react-markdown-renderer.tsx +0 -278
  100. package/src/hooks/use-resize-observer.tsx +0 -27
  101. package/src/hooks/use-update-vh.ts +0 -30
  102. package/src/hooks/use-viewport-size.ts +0 -51
  103. package/src/icons/add_a_photo.svg +0 -3
  104. package/src/icons/bot.svg +0 -14
  105. package/src/icons/close.svg +0 -3
  106. package/src/icons/distance.svg +0 -3
  107. package/src/icons/mic.svg +0 -3
  108. package/src/icons/photo_library.svg +0 -3
  109. package/src/icons/profile.svg +0 -28
  110. package/src/icons/refresh.svg +0 -3
  111. package/src/icons/send.svg +0 -3
  112. package/src/icons/stop.svg +0 -22
  113. package/src/icons/volume_up.svg +0 -3
  114. package/src/index.ts +0 -4
  115. package/src/models/bot-provider.ts +0 -108
  116. package/src/styles/_index.scss +0 -1
  117. package/src/styles/_styles.scss +0 -11
  118. package/src/styles/colors/_colors.scss +0 -10
  119. package/src/styles/colors/_index.scss +0 -1
  120. package/src/styles/colors/_variables.scss +0 -72
  121. package/src/styles/palette/_index.scss +0 -1
  122. package/src/styles/palette/_palette.scss +0 -42
  123. package/src/styles/palette/_variables.scss +0 -40
  124. package/src/styles/radius/_index.scss +0 -1
  125. package/src/styles/radius/_radius.scss +0 -8
  126. package/src/styles/radius/_variables.scss +0 -12
  127. package/src/styles/spacing/_index.scss +0 -1
  128. package/src/styles/spacing/_spacing.scss +0 -8
  129. package/src/styles/spacing/_variables.scss +0 -13
  130. package/src/styles/utils/_index.scss +0 -1
  131. package/src/styles/utils/_map.scss +0 -22
  132. package/src/test-setup.ts +0 -1
  133. package/src/utils/color-utils.ts +0 -52
  134. package/src/utils/deep-merge.ts +0 -26
  135. package/src/utils/extractors.ts +0 -20
  136. package/src/utils/format-time.ts +0 -8
  137. package/src/utils/index.ts +0 -1
  138. package/src/utils/is.ts +0 -72
  139. package/src/utils/selectors.ts +0 -7
  140. package/src/utils/uri-validation.spec.ts +0 -208
  141. package/src/utils/uri-validation.ts +0 -103
  142. package/tsconfig.json +0 -16
  143. package/tsconfig.lib.json +0 -63
  144. package/tsconfig.spec.json +0 -36
  145. package/tsconfig.tsbuildinfo +0 -1
  146. package/vite.config.ts +0 -63
@@ -1,75 +0,0 @@
1
- import { ReactNode, useMemo, useState, CSSProperties } from 'react';
2
- import { TemplateBox, TemplateBoxContent } from '../template-box';
3
- import { Avatar } from '../avatar';
4
- import { ConversationBotMessage, ChartMessageTemplate } from '@asgard-js/core';
5
- import { Time } from '../time';
6
- import { useAsgardContext } from '../../../context/asgard-service-context';
7
- import { VegaLite, VisualizationSpec } from 'react-vega';
8
- import clsx from 'clsx';
9
- import classes from './chart-template.module.scss';
10
- import { useAsgardThemeContext } from '../../../context/asgard-theme-context';
11
-
12
- interface ChartTemplateProps {
13
- message: ConversationBotMessage;
14
- }
15
-
16
- export function ChartTemplate(props: ChartTemplateProps): ReactNode {
17
- const { message } = props;
18
- const template = message.message.template as ChartMessageTemplate;
19
-
20
- const { template: themeTemplate, botMessage } = useAsgardThemeContext();
21
- const { avatar } = useAsgardContext();
22
-
23
- const [option, setOption] = useState(
24
- template?.defaultChart ?? template?.chartOptions?.[0]?.type
25
- );
26
-
27
- const options = useMemo(() => template.chartOptions, [template]);
28
-
29
- const spec = useMemo(
30
- () =>
31
- (template?.chartOptions?.find((item: { type: string; title: string; spec: Record<string, unknown> }) => item.type === option)?.spec ??
32
- options[0].spec) as VisualizationSpec,
33
- [option, template.chartOptions, options]
34
- );
35
-
36
- const styles = useMemo<CSSProperties>(
37
- () => ({
38
- color: botMessage?.color,
39
- backgroundColor: botMessage?.backgroundColor,
40
- }),
41
- [botMessage]
42
- );
43
-
44
- return (
45
- <TemplateBox
46
- className="asgard-chart-template"
47
- type="bot"
48
- direction="vertical"
49
- style={themeTemplate?.ChartMessageTemplate?.style}
50
- >
51
- <Avatar avatar={avatar} />
52
- <div className={clsx(classes.text, classes['text--bot'])} style={styles}>
53
- <div>{template.title}</div>
54
- <div>{template.text}</div>
55
- </div>
56
- {options.length > 1 && (
57
- <div className={classes.quick_replies_box}>
58
- {options.map((option: { type: string; title: string; spec: Record<string, unknown> }) => (
59
- <button
60
- key={option.type}
61
- className={classes.quick_reply}
62
- onClick={() => setOption(option.type)}
63
- >
64
- {option.title}
65
- </button>
66
- ))}
67
- </div>
68
- )}
69
- <TemplateBoxContent quickReplies={template?.quickReplies}>
70
- <VegaLite spec={spec} />
71
- </TemplateBoxContent>
72
- <Time className={classes.chart_time} time={message.time} />
73
- </TemplateBox>
74
- );
75
- }
@@ -1 +0,0 @@
1
- export * from './chart-template';
@@ -1,43 +0,0 @@
1
- .hint_root {
2
- margin: 0 auto;
3
- display: flex;
4
- flex-direction: column;
5
- align-items: center;
6
- padding: 4px 12px;
7
- gap: 4px;
8
- border-radius: 2px;
9
- background: rgba(88, 88, 88, 0.2);
10
- font-size: 13px;
11
- color: white;
12
- word-break: break-all;
13
-
14
- &.hint_root__error {
15
- color: var(--asg-color-error);
16
- }
17
-
18
- .error_hint_title {
19
- display: flex;
20
- align-items: center;
21
- gap: var(--asg-spacing-2);
22
- color: var(--asg-color-error);
23
- }
24
-
25
- .error_hint_message {
26
- font-size: 12px;
27
- color: white;
28
-
29
- > span {
30
- border-bottom: 1px solid white;
31
- cursor: pointer;
32
- }
33
- }
34
- }
35
-
36
- .hint_text {
37
- color: white;
38
- }
39
-
40
- .time {
41
- font-size: 12px;
42
- color: rgba(140, 140, 140, 1);
43
- }
@@ -1,76 +0,0 @@
1
- import { ReactNode, useCallback } from 'react';
2
- import classes from './hint-template.module.scss';
3
- import { formatTime } from '../../../utils';
4
- import {
5
- ConversationErrorMessage,
6
- ConversationMessage,
7
- MessageTemplateType,
8
- } from '@asgard-js/core';
9
- import { useAsgardTemplateContext, useAsgardThemeContext } from '../../../context';
10
- import clsx from 'clsx';
11
-
12
- interface HintTemplateProps {
13
- message: ConversationMessage;
14
- }
15
-
16
- export function HintTemplate(props: HintTemplateProps): ReactNode {
17
- const { message } = props;
18
-
19
- const { template: themeTemplate } = useAsgardThemeContext();
20
- const { onErrorClick, errorMessageRenderer } = useAsgardTemplateContext();
21
-
22
- const onErrorHintClick = useCallback(() => {
23
- onErrorClick?.(message as ConversationErrorMessage);
24
- }, [message, onErrorClick]);
25
-
26
- if (message.type === 'user') return null;
27
-
28
- if (message.type === 'error')
29
- return (
30
- <div
31
- className={clsx(
32
- 'asgard-hint-template asgard-hint-template--error',
33
- classes.hint_root
34
- )}
35
- >
36
- {errorMessageRenderer?.(message) ?? (
37
- <>
38
- <div className={classes.error_hint_title}>
39
- <span className={classes.time}>{formatTime(message.time)}</span>
40
- <span>Unexpected error</span>
41
- </div>
42
- {onErrorClick && (
43
- <div
44
- className={classes.error_hint_message}
45
- onClick={onErrorHintClick}
46
- >
47
- Click <span>here</span> to view the report.
48
- </div>
49
- )}
50
- </>
51
- )}
52
- </div>
53
- );
54
-
55
- const template = message.message.template;
56
-
57
- if (template.type !== MessageTemplateType.HINT) return null;
58
-
59
- return (
60
- <div
61
- className={clsx(
62
- 'asgard-hint-template asgard-hint-template--hint',
63
- classes.hint_root
64
- )}
65
- style={themeTemplate?.HintMessageTemplate?.style}
66
- >
67
- <div className={classes.time}>{formatTime(message.time)}</div>
68
- <div
69
- className={classes.hint_text}
70
- style={themeTemplate?.HintMessageTemplate?.style}
71
- >
72
- {template.text}
73
- </div>
74
- </div>
75
- );
76
- }
@@ -1 +0,0 @@
1
- export * from './hint-template';
@@ -1,67 +0,0 @@
1
- .image_box {
2
- display: flex;
3
- align-items: center;
4
- justify-content: flex-start;
5
- max-width: 80%;
6
- border-radius: 8px;
7
- box-sizing: border-box;
8
- > img {
9
- width: 100%;
10
- border-radius: 8px;
11
- }
12
- }
13
-
14
- .time {
15
- justify-content: flex-end;
16
- }
17
-
18
- .quick_replies_box {
19
- display: flex;
20
- flex-wrap: wrap;
21
- gap: 8px;
22
- }
23
-
24
- .full_screen {
25
- display: flex;
26
- align-items: center;
27
- justify-content: center;
28
- z-index: 9999;
29
- position: fixed;
30
- top: 0;
31
- left: 0;
32
- background: rgba(30, 30, 30, 0.8);
33
- backdrop-filter: blur(5px);
34
- width: 100%;
35
- height: 100%;
36
- overflow: hidden;
37
- box-sizing: border-box;
38
- > .imageOrigin {
39
- width: 100%;
40
- max-width: 100%;
41
- height: 100%;
42
- max-height: 90%;
43
- border-radius: 8px;
44
- background-repeat: no-repeat;
45
- background-size: contain;
46
- background-position: center;
47
- }
48
- > .full_screen_close {
49
- position: absolute;
50
- top: 16px;
51
- right: 16px;
52
- font-size: 24px;
53
- cursor: pointer;
54
- z-index: 9999;
55
- }
56
- }
57
-
58
- .quick_reply {
59
- font: inherit;
60
- font-size: 13px;
61
- padding: 4px 8px;
62
- border-radius: 8px;
63
- border: 1px solid #434343;
64
- background: rgba(88, 88, 88, 0.2);
65
- color: white;
66
- cursor: pointer;
67
- }
@@ -1,58 +0,0 @@
1
- import { ReactNode, useState } from 'react';
2
- import { TemplateBox, TemplateBoxContent } from '../template-box';
3
- import { Avatar } from '../avatar';
4
- import styles from './image-template.module.scss';
5
- import { ConversationBotMessage, ImageMessageTemplate } from '@asgard-js/core';
6
- import { useAsgardContext } from '../../../context/asgard-service-context';
7
- import { useAsgardThemeContext } from '../../../context/asgard-theme-context';
8
- import CloseSvg from '../../../icons/close.svg?react';
9
-
10
- interface ImageTemplateProps {
11
- message: ConversationBotMessage;
12
- }
13
-
14
- export function ImageTemplate(props: ImageTemplateProps): ReactNode {
15
- const { message } = props;
16
- const template = message.message.template as ImageMessageTemplate;
17
- const { previewImageUrl, originalContentUrl } = template;
18
-
19
- const { template: themeTemplate } = useAsgardThemeContext();
20
-
21
- const { avatar } = useAsgardContext();
22
- const [isFullScreen, setIsFullScreen] = useState(false);
23
- if (isFullScreen) {
24
- return (
25
- <div
26
- className={styles.full_screen}
27
- onClick={() => setIsFullScreen(false)}
28
- >
29
- <div className={styles.full_screen_close}>
30
- <CloseSvg />
31
- </div>
32
- <div
33
- className={styles.imageOrigin}
34
- style={{ backgroundImage: `url(${originalContentUrl})` }}
35
- />
36
- </div>
37
- );
38
- }
39
-
40
- return (
41
- <TemplateBox
42
- className="asgard-image-template"
43
- type="bot"
44
- direction="horizontal"
45
- style={themeTemplate?.ImageMessageTemplate?.style}
46
- >
47
- <Avatar avatar={avatar} />
48
- <TemplateBoxContent
49
- quickReplies={template.quickReplies}
50
- time={message.time}
51
- >
52
- <div className={styles.image_box} onClick={() => setIsFullScreen(true)}>
53
- <img src={previewImageUrl} alt="Conversation content" />
54
- </div>
55
- </TemplateBoxContent>
56
- </TemplateBox>
57
- );
58
- }
@@ -1 +0,0 @@
1
- export * from './image-template';
@@ -1,10 +0,0 @@
1
- export * from './template-box';
2
-
3
- export * from './button-template';
4
- export * from './text-template';
5
- export * from './carousel-template';
6
- export * from './hint-template';
7
- export * from './chart-template';
8
- export * from './image-template';
9
-
10
- export * from './quick-replies';
@@ -1 +0,0 @@
1
- export * from './quick-replies';
@@ -1,16 +0,0 @@
1
- .quick_replies_box {
2
- display: flex;
3
- flex-wrap: wrap;
4
- gap: 8px;
5
- }
6
-
7
- .quick_reply {
8
- font: inherit;
9
- font-size: 13px;
10
- padding: 4px 8px;
11
- border-radius: 8px;
12
- border: 1px solid #434343;
13
- background: rgba(88, 88, 88, 0.2);
14
- color: white;
15
- cursor: pointer;
16
- }
@@ -1,47 +0,0 @@
1
- import { ReactNode, useCallback } from 'react';
2
- import styles from './quick-replies.module.scss';
3
- import { useAsgardContext } from '../../../context/asgard-service-context';
4
- import { useAsgardThemeContext } from '../../../context/asgard-theme-context';
5
- import clsx from 'clsx';
6
-
7
- interface QuickRepliesProps {
8
- quickReplies: { text: string }[];
9
- }
10
-
11
- export function QuickReplies(props: QuickRepliesProps): ReactNode {
12
- const { quickReplies } = props;
13
-
14
- const { template, botMessage } = useAsgardThemeContext();
15
- const { sendMessage, isConnecting } = useAsgardContext();
16
-
17
- const onClick = useCallback(
18
- (text: string) => sendMessage?.({ text }),
19
- [sendMessage]
20
- );
21
-
22
- if (!quickReplies?.length) {
23
- return null;
24
- }
25
-
26
- return (
27
- <div
28
- className={clsx('asgard-quick-replies', styles.quick_replies_box)}
29
- style={template?.quickReplies?.style}
30
- >
31
- {quickReplies.map((quickReply) => (
32
- <button
33
- key={quickReply.text}
34
- className={styles.quick_reply}
35
- style={{
36
- ...template?.quickReplies?.button?.style,
37
- backgroundColor: botMessage?.quickReplyBackgroundColor || template?.quickReplies?.button?.style?.backgroundColor,
38
- }}
39
- disabled={isConnecting}
40
- onClick={() => onClick(quickReply.text)}
41
- >
42
- {quickReply.text}
43
- </button>
44
- ))}
45
- </div>
46
- );
47
- }
@@ -1,2 +0,0 @@
1
- export * from './template-box';
2
- export * from './template-box-content';
@@ -1,13 +0,0 @@
1
- .template_box_content {
2
- width: 100%;
3
- display: flex;
4
- flex-direction: column;
5
- gap: 8px;
6
- }
7
-
8
- .content {
9
- width: 100%;
10
- display: flex;
11
- flex-direction: row;
12
- gap: 8px;
13
- }
@@ -1,30 +0,0 @@
1
- import { ReactNode } from 'react';
2
- import styles from './template-box-content.module.scss';
3
- import { QuickReplies } from '../quick-replies';
4
- import { Time } from '../time';
5
- import clsx from 'clsx';
6
-
7
- interface TemplateBoxContentProps {
8
- children: ReactNode;
9
- time?: Date;
10
- quickReplies?: { text: string }[];
11
- }
12
-
13
- export function TemplateBoxContent(props: TemplateBoxContentProps): ReactNode {
14
- const { quickReplies, time, children } = props;
15
-
16
- return (
17
- <div
18
- className={clsx(
19
- 'asgard-template-box-content',
20
- styles.template_box_content
21
- )}
22
- >
23
- <div className={styles.content}>
24
- {children}
25
- <Time time={time} />
26
- </div>
27
- {!!quickReplies?.length && <QuickReplies quickReplies={quickReplies} />}
28
- </div>
29
- );
30
- }
@@ -1,19 +0,0 @@
1
- .template_box {
2
- width: 100%;
3
- display: flex;
4
- gap: 8px;
5
- }
6
-
7
- .template_box--bot {
8
- &.template_box--horizontal {
9
- flex-direction: row;
10
- }
11
-
12
- &.template_box--vertical {
13
- flex-direction: column;
14
- }
15
- }
16
-
17
- .template_box--user {
18
- flex-direction: row-reverse;
19
- }
@@ -1,48 +0,0 @@
1
- import { CSSProperties, ReactNode, useMemo } from 'react';
2
- import styles from './template-box.module.scss';
3
- import clsx from 'clsx';
4
-
5
- type TemplateBoxProps =
6
- | {
7
- type: 'user';
8
- direction: 'horizontal';
9
- children: ReactNode;
10
- className?: string;
11
- style?: CSSProperties;
12
- }
13
- | {
14
- type: 'bot';
15
- direction: 'horizontal' | 'vertical';
16
- children: ReactNode;
17
- className?: string;
18
- style?: CSSProperties;
19
- };
20
-
21
- export function TemplateBox(props: TemplateBoxProps): ReactNode {
22
- const { type, direction = 'horizontal', children, style, className } = props;
23
-
24
- const boxClassName = useMemo(() => {
25
- switch (type) {
26
- case 'user':
27
- return clsx(styles.template_box, styles['template_box--user']);
28
- case 'bot':
29
- default:
30
- return clsx(
31
- styles.template_box,
32
- styles['template_box--bot'],
33
- direction === 'horizontal'
34
- ? styles['template_box--horizontal']
35
- : styles['template_box--vertical']
36
- );
37
- }
38
- }, [direction, type]);
39
-
40
- return (
41
- <div
42
- className={clsx('asgard-template-box', boxClassName, className)}
43
- style={style}
44
- >
45
- {children}
46
- </div>
47
- );
48
- }
@@ -1,81 +0,0 @@
1
- import { CSSProperties, ReactNode, useCallback, useMemo, useRef } from 'react';
2
- import { useAsgardContext } from '../../../context/asgard-service-context';
3
- import clsx from 'clsx';
4
- import { TemplateBox, TemplateBoxContent } from '../template-box';
5
- import { Avatar } from '../avatar';
6
- import { useDebounce, useResizeObserver } from '../../../hooks';
7
- import classes from './text-template.module.scss';
8
- import { useAsgardThemeContext } from '../../../context/asgard-theme-context';
9
- import { useMarkdownRenderer } from '../../../hooks/use-react-markdown-renderer';
10
- interface BotTypingBoxProps {
11
- isTyping: boolean;
12
- typingText: string | null;
13
- }
14
-
15
- export function BotTypingBox(props: BotTypingBoxProps): ReactNode {
16
- const { isTyping, typingText } = props;
17
- const { messageBoxBottomRef, avatar } = useAsgardContext();
18
-
19
- const theme = useAsgardThemeContext();
20
-
21
- const ref = useRef<HTMLDivElement>(null);
22
-
23
- const onResize = useCallback(() => {
24
- messageBoxBottomRef.current?.scrollIntoView({ behavior: 'smooth' });
25
- }, [messageBoxBottomRef]);
26
-
27
- useResizeObserver({ ref, onResize });
28
-
29
- const _isTyping = useDebounce(isTyping, 500);
30
-
31
- const { htmlBlocks, lastTypingText } = useMarkdownRenderer(
32
- typingText || '',
33
- 20
34
- );
35
-
36
- const styles = useMemo<CSSProperties>(
37
- () => ({
38
- color: theme?.botMessage?.color,
39
- backgroundColor: theme?.botMessage?.backgroundColor,
40
- }),
41
- [theme]
42
- );
43
-
44
- const dotStyles = useMemo<CSSProperties>(
45
- () => ({
46
- backgroundColor: theme?.botMessage?.color,
47
- }),
48
- [theme]
49
- );
50
-
51
- if (!_isTyping) return null;
52
-
53
- return (
54
- <TemplateBox
55
- className="asgard-text-template asgard-text-template--bot"
56
- type="bot"
57
- direction="horizontal"
58
- >
59
- <Avatar avatar={avatar} />
60
- <TemplateBoxContent time={new Date()}>
61
- <div
62
- ref={ref}
63
- className={clsx(classes.text, classes['text--bot'])}
64
- style={styles}
65
- >
66
- <span>
67
- {htmlBlocks}
68
- {lastTypingText ?? ''}
69
- {_isTyping && (
70
- <span className={classes['typing-indicator']}>
71
- <div className={classes.dot} style={dotStyles} />
72
- <div className={classes.dot} style={dotStyles} />
73
- <div className={classes.dot} style={dotStyles} />
74
- </span>
75
- )}
76
- </span>
77
- </div>
78
- </TemplateBoxContent>
79
- </TemplateBox>
80
- );
81
- }
@@ -1,28 +0,0 @@
1
- import { ReactNode, useMemo } from 'react';
2
- import { BotTypingBox } from './bot-typing-box';
3
- import { useAsgardContext } from '../../../context/asgard-service-context';
4
-
5
- interface BotTypingPlaceholderProps {
6
- placeholder: string;
7
- }
8
-
9
- export function BotTypingPlaceholder(
10
- props: BotTypingPlaceholderProps
11
- ): ReactNode {
12
- const { placeholder } = props;
13
-
14
- const { isConnecting, messages } = useAsgardContext();
15
-
16
- const hasTypingMessage = useMemo(
17
- () =>
18
- Array.from(messages?.values() ?? []).some(
19
- (message) => message.type === 'bot' && message.isTyping
20
- ),
21
- [messages]
22
- );
23
-
24
- if (isConnecting && !hasTypingMessage)
25
- return <BotTypingBox isTyping typingText={placeholder} />;
26
-
27
- return null;
28
- }
@@ -1,3 +0,0 @@
1
- export * from './text-template';
2
- export * from './bot-typing-box';
3
- export * from './bot-typing-placeholder';