@n8n/chat 0.3.0 → 0.4.0

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 (104) hide show
  1. package/README.md +22 -5
  2. package/chat.bundle.es.js +10756 -0
  3. package/chat.bundle.umd.js +18 -0
  4. package/chat.es.js +6866 -0
  5. package/chat.umd.js +18 -0
  6. package/package.json +62 -2
  7. package/style.css +1 -0
  8. package/types/App.vue.d.ts +8 -0
  9. package/types/__stories__/App.stories.d.ts +17 -0
  10. package/types/__tests__/index.spec.d.ts +1 -0
  11. package/types/__tests__/setup.d.ts +0 -0
  12. package/types/__tests__/utils/create.d.ts +5 -0
  13. package/types/__tests__/utils/fetch.d.ts +4 -0
  14. package/types/__tests__/utils/selectors.d.ts +12 -0
  15. package/types/api/generic.d.ts +6 -0
  16. package/types/api/message.d.ts +3 -0
  17. package/types/components/Button.vue.d.ts +9 -0
  18. package/types/components/Chat.vue.d.ts +2 -0
  19. package/types/components/ChatWindow.vue.d.ts +2 -0
  20. package/types/components/GetStarted.vue.d.ts +2 -0
  21. package/types/components/GetStartedFooter.vue.d.ts +2 -0
  22. package/types/components/Input.vue.d.ts +2 -0
  23. package/types/components/Layout.vue.d.ts +11 -0
  24. package/types/components/Message.vue.d.ts +21 -0
  25. package/types/components/MessageTyping.vue.d.ts +15 -0
  26. package/types/components/MessagesList.vue.d.ts +14 -0
  27. package/types/components/PoweredBy.vue.d.ts +2 -0
  28. package/types/composables/useChat.d.ts +2 -0
  29. package/types/composables/useI18n.d.ts +4 -0
  30. package/types/composables/useOptions.d.ts +4 -0
  31. package/types/constants/defaults.d.ts +3 -0
  32. package/types/constants/localStorage.d.ts +2 -0
  33. package/types/constants/symbols.d.ts +4 -0
  34. package/types/event-buses/chatEventBus.d.ts +1 -0
  35. package/types/index.d.ts +2 -0
  36. package/types/plugins/chat.d.ts +3 -0
  37. package/types/types/chat.d.ts +11 -0
  38. package/types/types/messages.d.ts +6 -0
  39. package/types/types/options.d.ts +24 -0
  40. package/types/types/webhook.d.ts +15 -0
  41. package/types/utils/event-bus.d.ts +8 -0
  42. package/types/utils/mount.d.ts +1 -0
  43. package/.eslintignore +0 -2
  44. package/.eslintrc.cjs +0 -52
  45. package/.np-config.json +0 -5
  46. package/.storybook/main.ts +0 -27
  47. package/.storybook/preview.scss +0 -4
  48. package/.storybook/preview.ts +0 -16
  49. package/.vscode/extensions.json +0 -3
  50. package/env.d.ts +0 -1
  51. package/index.html +0 -13
  52. package/resources/workflow.json +0 -293
  53. package/scripts/pack.js +0 -11
  54. package/scripts/postbuild.js +0 -16
  55. package/src/App.vue +0 -23
  56. package/src/__stories__/App.stories.ts +0 -43
  57. package/src/__tests__/index.spec.ts +0 -223
  58. package/src/__tests__/setup.ts +0 -1
  59. package/src/__tests__/utils/create.ts +0 -16
  60. package/src/__tests__/utils/fetch.ts +0 -18
  61. package/src/__tests__/utils/selectors.ts +0 -53
  62. package/src/api/generic.ts +0 -64
  63. package/src/api/message.ts +0 -31
  64. package/src/components/Button.vue +0 -41
  65. package/src/components/Chat.vue +0 -48
  66. package/src/components/ChatWindow.vue +0 -125
  67. package/src/components/GetStarted.vue +0 -24
  68. package/src/components/GetStartedFooter.vue +0 -20
  69. package/src/components/Input.vue +0 -93
  70. package/src/components/Layout.vue +0 -82
  71. package/src/components/Message.vue +0 -97
  72. package/src/components/MessageTyping.vue +0 -109
  73. package/src/components/MessagesList.vue +0 -37
  74. package/src/components/PoweredBy.vue +0 -17
  75. package/src/composables/useChat.ts +0 -7
  76. package/src/composables/useI18n.ts +0 -16
  77. package/src/composables/useOptions.ts +0 -11
  78. package/src/constants/defaults.ts +0 -25
  79. package/src/constants/localStorage.ts +0 -2
  80. package/src/constants/symbols.ts +0 -8
  81. package/src/event-buses/chatEventBus.ts +0 -3
  82. package/src/index.ts +0 -42
  83. package/src/main.scss +0 -40
  84. package/src/plugins/chat.ts +0 -101
  85. package/src/shims.d.ts +0 -6
  86. package/src/types/chat.ts +0 -12
  87. package/src/types/messages.ts +0 -6
  88. package/src/types/options.ts +0 -23
  89. package/src/types/webhook.ts +0 -17
  90. package/src/utils/event-bus.ts +0 -51
  91. package/src/utils/mount.ts +0 -16
  92. package/tsconfig.json +0 -27
  93. package/vite.config.ts +0 -51
  94. package/vitest.config.ts +0 -20
  95. /package/{public/favicon.ico → favicon.ico} +0 -0
  96. /package/{src/__tests__/utils/index.ts → types/__tests__/utils/index.d.ts} +0 -0
  97. /package/{src/api/index.ts → types/api/index.d.ts} +0 -0
  98. /package/{src/components/index.ts → types/components/index.d.ts} +0 -0
  99. /package/{src/composables/index.ts → types/composables/index.d.ts} +0 -0
  100. /package/{src/constants/index.ts → types/constants/index.d.ts} +0 -0
  101. /package/{src/event-buses/index.ts → types/event-buses/index.d.ts} +0 -0
  102. /package/{src/plugins/index.ts → types/plugins/index.d.ts} +0 -0
  103. /package/{src/types/index.ts → types/types/index.d.ts} +0 -0
  104. /package/{src/utils/index.ts → types/utils/index.d.ts} +0 -0
@@ -1,64 +0,0 @@
1
- async function getAccessToken() {
2
- return '';
3
- }
4
-
5
- export async function authenticatedFetch<T>(...args: Parameters<typeof fetch>): Promise<T> {
6
- const accessToken = await getAccessToken();
7
-
8
- const response = await fetch(args[0], {
9
- ...args[1],
10
- mode: 'cors',
11
- cache: 'no-cache',
12
- headers: {
13
- ...(accessToken ? { authorization: `Bearer ${accessToken}` } : {}),
14
- ...args[1]?.headers,
15
- },
16
- });
17
-
18
- return (await response.json()) as Promise<T>;
19
- }
20
-
21
- export async function get<T>(
22
- url: string,
23
- query: Record<string, string> = {},
24
- options: RequestInit = {},
25
- ) {
26
- let resolvedUrl = url;
27
- if (Object.keys(query).length > 0) {
28
- resolvedUrl = `${resolvedUrl}?${new URLSearchParams(query).toString()}`;
29
- }
30
-
31
- return authenticatedFetch<T>(resolvedUrl, { ...options, method: 'GET' });
32
- }
33
-
34
- export async function post<T>(url: string, body: object = {}, options: RequestInit = {}) {
35
- return authenticatedFetch<T>(url, {
36
- ...options,
37
- method: 'POST',
38
- body: JSON.stringify(body),
39
- });
40
- }
41
-
42
- export async function put<T>(url: string, body: object = {}, options: RequestInit = {}) {
43
- return authenticatedFetch<T>(url, {
44
- ...options,
45
- method: 'PUT',
46
- body: JSON.stringify(body),
47
- });
48
- }
49
-
50
- export async function patch<T>(url: string, body: object = {}, options: RequestInit = {}) {
51
- return authenticatedFetch<T>(url, {
52
- ...options,
53
- method: 'PATCH',
54
- body: JSON.stringify(body),
55
- });
56
- }
57
-
58
- export async function del<T>(url: string, body: object = {}, options: RequestInit = {}) {
59
- return authenticatedFetch<T>(url, {
60
- ...options,
61
- method: 'DELETE',
62
- body: JSON.stringify(body),
63
- });
64
- }
@@ -1,31 +0,0 @@
1
- import { get, post } from '@/api/generic';
2
- import type { ChatOptions, LoadPreviousSessionResponse, SendMessageResponse } from '@/types';
3
-
4
- export async function loadPreviousSession(sessionId: string, options: ChatOptions) {
5
- const method = options.webhookConfig?.method === 'POST' ? post : get;
6
- return method<LoadPreviousSessionResponse>(
7
- `${options.webhookUrl}`,
8
- {
9
- action: 'loadPreviousSession',
10
- sessionId,
11
- },
12
- {
13
- headers: options.webhookConfig?.headers,
14
- },
15
- );
16
- }
17
-
18
- export async function sendMessage(message: string, sessionId: string, options: ChatOptions) {
19
- const method = options.webhookConfig?.method === 'POST' ? post : get;
20
- return method<SendMessageResponse>(
21
- `${options.webhookUrl}`,
22
- {
23
- action: 'sendMessage',
24
- sessionId,
25
- message,
26
- },
27
- {
28
- headers: options.webhookConfig?.headers,
29
- },
30
- );
31
- }
@@ -1,41 +0,0 @@
1
- <template>
2
- <button class="chat-button">
3
- <slot />
4
- </button>
5
- </template>
6
- <style lang="scss">
7
- .chat-button {
8
- display: inline-flex;
9
- text-align: center;
10
- vertical-align: middle;
11
- user-select: none;
12
- color: var(--chat--button--color, var(--chat--color-light));
13
- background-color: var(--chat--button--background, var(--chat--color-primary));
14
- border: 1px solid transparent;
15
- padding: var(--chat--button--padding, calc(var(--chat--spacing) * 1 / 2) var(--chat--spacing));
16
- font-size: 1rem;
17
- line-height: 1.5;
18
- border-radius: var(--chat--button--border-radius, var(--chat--border-radius));
19
- transition:
20
- color var(--chat--transition-duration) ease-in-out,
21
- background-color var(--chat--transition-duration) ease-in-out,
22
- border-color var(--chat--transition-duration) ease-in-out,
23
- box-shadow var(--chat--transition-duration) ease-in-out;
24
- cursor: pointer;
25
-
26
- &:hover {
27
- color: var(--chat--button--hover--color, var(--chat--color-light));
28
- background-color: var(--chat--button--hover--background, var(--chat--color-primary-shade-50));
29
- text-decoration: none;
30
- }
31
-
32
- &:focus {
33
- outline: 0;
34
- box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
35
- }
36
-
37
- &:disabled {
38
- opacity: 0.65;
39
- }
40
- }
41
- </style>
@@ -1,48 +0,0 @@
1
- <script setup lang="ts">
2
- import Layout from '@/components/Layout.vue';
3
- import GetStarted from '@/components/GetStarted.vue';
4
- import GetStartedFooter from '@/components/GetStartedFooter.vue';
5
- import MessagesList from '@/components/MessagesList.vue';
6
- import Input from '@/components/Input.vue';
7
- import { nextTick, onMounted } from 'vue';
8
- import { useI18n, useChat } from '@/composables';
9
- import { chatEventBus } from '@/event-buses';
10
-
11
- const { t } = useI18n();
12
- const chatStore = useChat();
13
-
14
- const { messages, currentSessionId } = chatStore;
15
-
16
- async function initialize() {
17
- await chatStore.loadPreviousSession();
18
- void nextTick(() => {
19
- chatEventBus.emit('scrollToBottom');
20
- });
21
- }
22
-
23
- async function getStarted() {
24
- void chatStore.startNewSession();
25
- void nextTick(() => {
26
- chatEventBus.emit('scrollToBottom');
27
- });
28
- }
29
-
30
- onMounted(() => {
31
- void initialize();
32
- });
33
- </script>
34
-
35
- <template>
36
- <Layout class="chat-wrapper">
37
- <template #header v-if="!currentSessionId">
38
- <h1>{{ t('title') }}</h1>
39
- <p>{{ t('subtitle') }}</p>
40
- </template>
41
- <GetStarted v-if="!currentSessionId" @click:button="getStarted" />
42
- <MessagesList v-else :messages="messages" />
43
- <template #footer>
44
- <Input v-if="currentSessionId" />
45
- <GetStartedFooter v-else />
46
- </template>
47
- </Layout>
48
- </template>
@@ -1,125 +0,0 @@
1
- <script lang="ts" setup>
2
- // eslint-disable-next-line import/no-unresolved
3
- import IconChat from 'virtual:icons/mdi/chat';
4
- // eslint-disable-next-line import/no-unresolved
5
- import IconChevronDown from 'virtual:icons/mdi/chevron-down';
6
- import Chat from '@/components/Chat.vue';
7
- import { nextTick, ref } from 'vue';
8
- import { chatEventBus } from '@/event-buses';
9
-
10
- const isOpen = ref(false);
11
-
12
- function toggle() {
13
- isOpen.value = !isOpen.value;
14
-
15
- if (isOpen.value) {
16
- void nextTick(() => {
17
- chatEventBus.emit('scrollToBottom');
18
- });
19
- }
20
- }
21
- </script>
22
-
23
- <template>
24
- <div class="chat-window-wrapper">
25
- <Transition name="chat-window-transition">
26
- <div class="chat-window" v-show="isOpen">
27
- <Chat />
28
- </div>
29
- </Transition>
30
- <div class="chat-window-toggle" @click="toggle">
31
- <Transition name="chat-window-toggle-transition" mode="out-in">
32
- <IconChat v-if="!isOpen" height="32" width="32" />
33
- <IconChevronDown v-else height="32" width="32" />
34
- </Transition>
35
- </div>
36
- </div>
37
- </template>
38
-
39
- <style lang="scss">
40
- .chat-window-wrapper {
41
- position: fixed;
42
- display: flex;
43
- flex-direction: column;
44
- bottom: var(--chat--window--bottom, var(--chat--spacing));
45
- right: var(--chat--window--right, var(--chat--spacing));
46
- z-index: var(--chat--window--z-index, 9999);
47
-
48
- max-width: calc(100% - var(--chat--window--right, var(--chat--spacing)) * 2);
49
- max-height: calc(100% - var(--chat--window--bottom, var(--chat--spacing)) * 2);
50
-
51
- .chat-window {
52
- display: flex;
53
- width: var(--chat--window--width);
54
- height: var(--chat--window--height);
55
- max-width: 100%;
56
- max-height: 100%;
57
- border: var(--chat--window--border, 1px solid var(--chat--color-light-shade-100));
58
- border-radius: var(--chat--window--border-radius, var(--chat--border-radius));
59
- margin-bottom: var(--chat--window--margin-bottom, var(--chat--spacing));
60
- overflow: hidden;
61
- transform-origin: bottom right;
62
-
63
- .chat-layout {
64
- width: auto;
65
- height: auto;
66
- flex: 1;
67
- }
68
- }
69
-
70
- .chat-window-toggle {
71
- flex: 0 0 auto;
72
- background: var(--chat--toggle--background);
73
- color: var(--chat--toggle--color);
74
- cursor: pointer;
75
- width: var(--chat--toggle--width, var(--chat--toggle--size));
76
- height: var(--chat--toggle--height, var(--chat--toggle--size));
77
- border-radius: var(--chat--toggle--border-radius, 50%);
78
- display: inline-flex;
79
- align-items: center;
80
- justify-content: center;
81
- margin-left: auto;
82
- transition:
83
- transform var(--chat--transition-duration) ease,
84
- background var(--chat--transition-duration) ease;
85
-
86
- &:hover,
87
- &:focus {
88
- transform: scale(1.05);
89
- background: var(--chat--toggle--hover--background);
90
- }
91
-
92
- &:active {
93
- transform: scale(0.95);
94
- background: var(--chat--toggle--active--background);
95
- }
96
- }
97
- }
98
-
99
- .chat-window-transition {
100
- &-enter-active,
101
- &-leave-active {
102
- transition:
103
- transform var(--chat--transition-duration) ease,
104
- opacity var(--chat--transition-duration) ease;
105
- }
106
-
107
- &-enter-from,
108
- &-leave-to {
109
- transform: scale(0);
110
- opacity: 0;
111
- }
112
- }
113
-
114
- .chat-window-toggle-transition {
115
- &-enter-active,
116
- &-leave-active {
117
- transition: opacity var(--chat--transition-duration) ease;
118
- }
119
-
120
- &-enter-from,
121
- &-leave-to {
122
- opacity: 0;
123
- }
124
- }
125
- </style>
@@ -1,24 +0,0 @@
1
- <script setup lang="ts">
2
- import Button from '@/components/Button.vue';
3
- import { useI18n } from '@/composables';
4
-
5
- const { t } = useI18n();
6
- </script>
7
- <template>
8
- <div class="chat-get-started">
9
- <Button @click="$emit('click:button')">
10
- {{ t('getStarted') }}
11
- </Button>
12
- </div>
13
- </template>
14
-
15
- <style lang="scss">
16
- .chat-get-started {
17
- padding-top: var(--chat--spacing);
18
- padding-bottom: var(--chat--spacing);
19
- display: flex;
20
- justify-content: center;
21
- align-items: center;
22
- height: 100%;
23
- }
24
- </style>
@@ -1,20 +0,0 @@
1
- <script setup lang="ts">
2
- import { useI18n } from '@/composables';
3
- import PoweredBy from '@/components/PoweredBy.vue';
4
-
5
- const { t, te } = useI18n();
6
- </script>
7
- <template>
8
- <div class="chat-get-started-footer">
9
- <div v-if="te('footer')">
10
- {{ t('footer') }}
11
- </div>
12
- <PoweredBy />
13
- </div>
14
- </template>
15
-
16
- <style lang="scss">
17
- .chat-get-started-footer {
18
- padding: var(--chat--spacing);
19
- }
20
- </style>
@@ -1,93 +0,0 @@
1
- <script setup lang="ts">
2
- // eslint-disable-next-line import/no-unresolved
3
- import IconSend from 'virtual:icons/mdi/send';
4
- import { useI18n, useChat } from '@/composables';
5
- import { computed, ref } from 'vue';
6
-
7
- const chatStore = useChat();
8
- const { waitingForResponse } = chatStore;
9
- const { t } = useI18n();
10
-
11
- const input = ref('');
12
-
13
- const isSubmitDisabled = computed(() => {
14
- return input.value === '' || waitingForResponse.value;
15
- });
16
-
17
- async function onSubmit(event: MouseEvent | KeyboardEvent) {
18
- event.preventDefault();
19
-
20
- if (isSubmitDisabled.value) {
21
- return;
22
- }
23
-
24
- const messageText = input.value;
25
- input.value = '';
26
- await chatStore.sendMessage(messageText);
27
- }
28
-
29
- async function onSubmitKeydown(event: KeyboardEvent) {
30
- if (event.shiftKey) {
31
- return;
32
- }
33
-
34
- await onSubmit(event);
35
- }
36
- </script>
37
-
38
- <template>
39
- <div class="chat-input">
40
- <textarea
41
- v-model="input"
42
- rows="1"
43
- :placeholder="t('inputPlaceholder')"
44
- @keydown.enter="onSubmitKeydown"
45
- />
46
- <button :disabled="isSubmitDisabled" class="chat-input-send-button" @click="onSubmit">
47
- <IconSend height="32" width="32" />
48
- </button>
49
- </div>
50
- </template>
51
-
52
- <style lang="scss">
53
- .chat-input {
54
- display: flex;
55
- justify-content: center;
56
- align-items: center;
57
- width: 100%;
58
-
59
- textarea {
60
- font-family: inherit;
61
- font-size: inherit;
62
- width: 100%;
63
- border: 0;
64
- padding: var(--chat--spacing);
65
- max-height: var(--chat--textarea--height);
66
- resize: none;
67
- }
68
-
69
- .chat-input-send-button {
70
- height: var(--chat--textarea--height);
71
- width: var(--chat--textarea--height);
72
- background: white;
73
- cursor: pointer;
74
- color: var(--chat--color-secondary);
75
- border: 0;
76
- font-size: 24px;
77
- display: inline-flex;
78
- align-items: center;
79
- justify-content: center;
80
- transition: color var(--chat--transition-duration) ease;
81
-
82
- &:hover,
83
- &:focus {
84
- color: var(--chat--color-secondary-shade-50);
85
- }
86
-
87
- &[disabled] {
88
- cursor: default;
89
- color: var(--chat--color-disabled);
90
- }
91
- }
92
- }
93
- </style>
@@ -1,82 +0,0 @@
1
- <script setup lang="ts">
2
- import { onBeforeUnmount, onMounted, ref } from 'vue';
3
- import { chatEventBus } from '@/event-buses';
4
-
5
- const chatBodyRef = ref<HTMLElement | null>(null);
6
-
7
- function scrollToBottom() {
8
- const element = chatBodyRef.value as HTMLElement;
9
- if (element) {
10
- element.scrollTop = element.scrollHeight;
11
- }
12
- }
13
-
14
- onMounted(() => {
15
- chatEventBus.on('scrollToBottom', scrollToBottom);
16
- window.addEventListener('resize', scrollToBottom);
17
- });
18
-
19
- onBeforeUnmount(() => {
20
- chatEventBus.off('scrollToBottom', scrollToBottom);
21
- window.removeEventListener('resize', scrollToBottom);
22
- });
23
- </script>
24
- <template>
25
- <main class="chat-layout">
26
- <div v-if="$slots.header" class="chat-header">
27
- <slot name="header" />
28
- </div>
29
- <div v-if="$slots.default" class="chat-body" ref="chatBodyRef">
30
- <slot />
31
- </div>
32
- <div v-if="$slots.footer" class="chat-footer">
33
- <slot name="footer" />
34
- </div>
35
- </main>
36
- </template>
37
-
38
- <style lang="scss">
39
- .chat-layout {
40
- width: 100%;
41
- height: 100%;
42
- display: flex;
43
- overflow-y: auto;
44
- flex-direction: column;
45
- font-family: var(
46
- --chat--font-family,
47
- (
48
- -apple-system,
49
- BlinkMacSystemFont,
50
- 'Segoe UI',
51
- Roboto,
52
- Oxygen-Sans,
53
- Ubuntu,
54
- Cantarell,
55
- 'Helvetica Neue',
56
- sans-serif
57
- )
58
- );
59
-
60
- .chat-header {
61
- padding: var(--chat--header--padding, var(--chat--spacing));
62
- background: var(--chat--header--background, var(--chat--color-dark));
63
- color: var(--chat--header--color, var(--chat--color-light));
64
- }
65
-
66
- .chat-body {
67
- background: var(--chat--body--background, var(--chat--color-light));
68
- flex: 1;
69
- display: flex;
70
- flex-direction: column;
71
- overflow-y: auto;
72
- position: relative;
73
- min-height: 100px;
74
- }
75
-
76
- .chat-footer {
77
- border-top: 1px solid var(--chat--color-light-shade-100);
78
- background: var(--chat--footer--background, var(--chat--color-light));
79
- color: var(--chat--footer--color, var(--chat--color-dark));
80
- }
81
- }
82
- </style>
@@ -1,97 +0,0 @@
1
- <script lang="ts" setup>
2
- /* eslint-disable @typescript-eslint/naming-convention */
3
- import type { ChatMessage } from '@/types';
4
- import type { PropType } from 'vue';
5
- import { computed, toRefs } from 'vue';
6
- import VueMarkdown from 'vue-markdown-render';
7
- import hljs from 'highlight.js/lib/core';
8
-
9
- const props = defineProps({
10
- message: {
11
- type: Object as PropType<ChatMessage>,
12
- required: true,
13
- },
14
- });
15
-
16
- const { message } = toRefs(props);
17
-
18
- const classes = computed(() => {
19
- return {
20
- 'chat-message-from-user': message.value.sender === 'user',
21
- 'chat-message-from-bot': message.value.sender === 'bot',
22
- };
23
- });
24
-
25
- const markdownOptions = {
26
- highlight(str: string, lang: string) {
27
- if (lang && hljs.getLanguage(lang)) {
28
- try {
29
- return hljs.highlight(str, { language: lang }).value;
30
- } catch {}
31
- }
32
-
33
- return ''; // use external default escaping
34
- },
35
- };
36
- </script>
37
- <template>
38
- <div class="chat-message" :class="classes">
39
- <slot>
40
- <vue-markdown
41
- class="chat-message-markdown"
42
- :source="message.text"
43
- :options="markdownOptions"
44
- />
45
- </slot>
46
- </div>
47
- </template>
48
-
49
- <style lang="scss">
50
- .chat-message {
51
- display: block;
52
- max-width: 80%;
53
- padding: var(--chat--message--padding, var(--chat--spacing));
54
- border-radius: var(--chat--message--border-radius, var(--chat--border-radius));
55
-
56
- + .chat-message {
57
- margin-top: var(--chat--message--margin-bottom, calc(var(--chat--spacing) * 0.5));
58
- }
59
-
60
- &.chat-message-from-bot {
61
- background-color: var(--chat--message--bot--background);
62
- color: var(--chat--message--bot--color);
63
- border-bottom-left-radius: 0;
64
- }
65
-
66
- &.chat-message-from-user {
67
- background-color: var(--chat--message--user--background);
68
- color: var(--chat--message--user--color);
69
- margin-left: auto;
70
- border-bottom-right-radius: 0;
71
- }
72
-
73
- > .chat-message-markdown {
74
- display: block;
75
- box-sizing: border-box;
76
-
77
- > *:first-child {
78
- margin-top: 0;
79
- }
80
-
81
- > *:last-child {
82
- margin-bottom: 0;
83
- }
84
-
85
- pre {
86
- font-family: inherit;
87
- font-size: inherit;
88
- margin: 0;
89
- white-space: pre-wrap;
90
- box-sizing: border-box;
91
- padding: var(--chat--spacing);
92
- background: var(--chat--message--pre--background);
93
- border-radius: var(--chat--border-radius);
94
- }
95
- }
96
- }
97
- </style>