@n8n/chat 0.18.0 → 0.19.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 (110) hide show
  1. package/README.md +2 -2
  2. package/dist/App.vue.d.ts +8 -0
  3. package/dist/__stories__/App.stories.d.ts +18 -0
  4. package/dist/__tests__/index.spec.d.ts +1 -0
  5. package/dist/__tests__/setup.d.ts +1 -0
  6. package/dist/__tests__/utils/create.d.ts +6 -0
  7. package/dist/__tests__/utils/fetch.d.ts +5 -0
  8. package/dist/__tests__/utils/selectors.d.ts +12 -0
  9. package/dist/api/generic.d.ts +6 -0
  10. package/dist/api/message.d.ts +4 -0
  11. package/dist/chat.bundle.es.js +11029 -0
  12. package/dist/chat.bundle.umd.js +37 -0
  13. package/dist/chat.es.js +6939 -0
  14. package/dist/chat.umd.js +18 -0
  15. package/dist/components/Button.vue.d.ts +11 -0
  16. package/dist/components/Chat.vue.d.ts +2 -0
  17. package/dist/components/ChatWindow.vue.d.ts +2 -0
  18. package/dist/components/GetStarted.vue.d.ts +2 -0
  19. package/dist/components/GetStartedFooter.vue.d.ts +2 -0
  20. package/dist/components/Input.vue.d.ts +2 -0
  21. package/dist/components/Layout.vue.d.ts +13 -0
  22. package/dist/components/Message.vue.d.ts +26 -0
  23. package/dist/components/MessageTyping.vue.d.ts +29 -0
  24. package/dist/components/MessagesList.vue.d.ts +17 -0
  25. package/dist/components/PoweredBy.vue.d.ts +2 -0
  26. package/dist/composables/useChat.d.ts +3 -0
  27. package/dist/composables/useI18n.d.ts +4 -0
  28. package/dist/composables/useOptions.d.ts +5 -0
  29. package/dist/constants/defaults.d.ts +4 -0
  30. package/dist/constants/localStorage.d.ts +2 -0
  31. package/dist/constants/symbols.d.ts +5 -0
  32. package/dist/event-buses/chatEventBus.d.ts +1 -0
  33. package/dist/index.d.ts +3 -0
  34. package/dist/plugins/chat.d.ts +4 -0
  35. package/dist/style.css +1 -0
  36. package/dist/types/chat.d.ts +12 -0
  37. package/{src/types/messages.ts → dist/types/messages.d.ts} +10 -12
  38. package/dist/types/options.d.ts +31 -0
  39. package/dist/types/webhook.d.ts +16 -0
  40. package/dist/utils/event-bus.d.ts +8 -0
  41. package/dist/utils/mount.d.ts +1 -0
  42. package/package.json +45 -9
  43. package/.eslintignore +0 -2
  44. package/.eslintrc.cjs +0 -10
  45. package/.np-config.json +0 -5
  46. package/.storybook/main.ts +0 -4
  47. package/.storybook/preview.scss +0 -4
  48. package/.storybook/preview.ts +0 -15
  49. package/.vscode/extensions.json +0 -3
  50. package/build.config.js +0 -21
  51. package/env.d.ts +0 -1
  52. package/index.html +0 -13
  53. package/resources/images/fullscreen.png +0 -0
  54. package/resources/images/windowed.png +0 -0
  55. package/resources/workflow-manual.json +0 -238
  56. package/resources/workflow.json +0 -119
  57. package/scripts/pack.js +0 -11
  58. package/scripts/postbuild.js +0 -36
  59. package/src/App.vue +0 -23
  60. package/src/__stories__/App.stories.ts +0 -43
  61. package/src/__tests__/index.spec.ts +0 -218
  62. package/src/__tests__/setup.ts +0 -1
  63. package/src/__tests__/utils/create.ts +0 -16
  64. package/src/__tests__/utils/fetch.ts +0 -18
  65. package/src/__tests__/utils/selectors.ts +0 -53
  66. package/src/api/generic.ts +0 -63
  67. package/src/api/message.ts +0 -37
  68. package/src/components/Button.vue +0 -41
  69. package/src/components/Chat.vue +0 -96
  70. package/src/components/ChatWindow.vue +0 -123
  71. package/src/components/GetStarted.vue +0 -24
  72. package/src/components/GetStartedFooter.vue +0 -20
  73. package/src/components/Input.vue +0 -108
  74. package/src/components/Layout.vue +0 -99
  75. package/src/components/Message.vue +0 -137
  76. package/src/components/MessageTyping.vue +0 -110
  77. package/src/components/MessagesList.vue +0 -33
  78. package/src/components/PoweredBy.vue +0 -17
  79. package/src/composables/useChat.ts +0 -7
  80. package/src/composables/useI18n.ts +0 -21
  81. package/src/composables/useOptions.ts +0 -11
  82. package/src/constants/defaults.ts +0 -30
  83. package/src/constants/localStorage.ts +0 -2
  84. package/src/constants/symbols.ts +0 -8
  85. package/src/css/_tokens.scss +0 -38
  86. package/src/css/index.scss +0 -1
  87. package/src/event-buses/chatEventBus.ts +0 -3
  88. package/src/index.ts +0 -42
  89. package/src/main.scss +0 -5
  90. package/src/plugins/chat.ts +0 -115
  91. package/src/shims.d.ts +0 -6
  92. package/src/types/chat.ts +0 -12
  93. package/src/types/icons.d.ts +0 -5
  94. package/src/types/options.ts +0 -33
  95. package/src/types/webhook.ts +0 -18
  96. package/src/utils/event-bus.ts +0 -51
  97. package/src/utils/mount.ts +0 -16
  98. package/tsconfig.json +0 -27
  99. package/vite.config.mts +0 -53
  100. package/vitest.config.mts +0 -30
  101. /package/{src/__tests__/utils/index.ts → dist/__tests__/utils/index.d.ts} +0 -0
  102. /package/{src/api/index.ts → dist/api/index.d.ts} +0 -0
  103. /package/{src/components/index.ts → dist/components/index.d.ts} +0 -0
  104. /package/{src/composables/index.ts → dist/composables/index.d.ts} +0 -0
  105. /package/{src/constants/index.ts → dist/constants/index.d.ts} +0 -0
  106. /package/{src/event-buses/index.ts → dist/event-buses/index.d.ts} +0 -0
  107. /package/{public → dist}/favicon.ico +0 -0
  108. /package/{src/plugins/index.ts → dist/plugins/index.d.ts} +0 -0
  109. /package/{src/types/index.ts → dist/types/index.d.ts} +0 -0
  110. /package/{src/utils/index.ts → dist/utils/index.d.ts} +0 -0
@@ -1,96 +0,0 @@
1
- <script setup lang="ts">
2
- import Close from 'virtual:icons/mdi/close';
3
- import { computed, nextTick, onMounted } from 'vue';
4
- import Layout from '@n8n/chat/components/Layout.vue';
5
- import GetStarted from '@n8n/chat/components/GetStarted.vue';
6
- import GetStartedFooter from '@n8n/chat/components/GetStartedFooter.vue';
7
- import MessagesList from '@n8n/chat/components/MessagesList.vue';
8
- import Input from '@n8n/chat/components/Input.vue';
9
- import { useI18n, useChat, useOptions } from '@n8n/chat/composables';
10
- import { chatEventBus } from '@n8n/chat/event-buses';
11
-
12
- const { t } = useI18n();
13
- const chatStore = useChat();
14
-
15
- const { messages, currentSessionId } = chatStore;
16
- const { options } = useOptions();
17
-
18
- const showCloseButton = computed(() => options.mode === 'window' && options.showWindowCloseButton);
19
-
20
- async function getStarted() {
21
- if (!chatStore.startNewSession) {
22
- return;
23
- }
24
- void chatStore.startNewSession();
25
- void nextTick(() => {
26
- chatEventBus.emit('scrollToBottom');
27
- });
28
- }
29
-
30
- async function initialize() {
31
- if (!chatStore.loadPreviousSession) {
32
- return;
33
- }
34
- await chatStore.loadPreviousSession();
35
- void nextTick(() => {
36
- chatEventBus.emit('scrollToBottom');
37
- });
38
- }
39
-
40
- function closeChat() {
41
- chatEventBus.emit('close');
42
- }
43
-
44
- onMounted(async () => {
45
- await initialize();
46
- if (!options.showWelcomeScreen && !currentSessionId.value) {
47
- await getStarted();
48
- }
49
- });
50
- </script>
51
-
52
- <template>
53
- <Layout class="chat-wrapper">
54
- <template #header>
55
- <div class="chat-heading">
56
- <h1>
57
- {{ t('title') }}
58
- </h1>
59
- <button
60
- v-if="showCloseButton"
61
- class="chat-close-button"
62
- :title="t('closeButtonTooltip')"
63
- @click="closeChat"
64
- >
65
- <Close height="18" width="18" />
66
- </button>
67
- </div>
68
- <p v-if="t('subtitle')">{{ t('subtitle') }}</p>
69
- </template>
70
- <GetStarted v-if="!currentSessionId && options.showWelcomeScreen" @click:button="getStarted" />
71
- <MessagesList v-else :messages="messages" />
72
- <template #footer>
73
- <Input v-if="currentSessionId" />
74
- <GetStartedFooter v-else />
75
- </template>
76
- </Layout>
77
- </template>
78
-
79
- <style lang="scss">
80
- .chat-heading {
81
- display: flex;
82
- justify-content: space-between;
83
- align-items: center;
84
- }
85
-
86
- .chat-close-button {
87
- display: flex;
88
- border: none;
89
- background: none;
90
- cursor: pointer;
91
-
92
- &:hover {
93
- color: var(--chat--close--button--color-hover, var(--chat--color-primary));
94
- }
95
- }
96
- </style>
@@ -1,123 +0,0 @@
1
- <script lang="ts" setup>
2
- import IconChat from 'virtual:icons/mdi/chat';
3
- import IconChevronDown from 'virtual:icons/mdi/chevron-down';
4
- import { nextTick, ref } from 'vue';
5
- import Chat from '@n8n/chat/components/Chat.vue';
6
- import { chatEventBus } from '@n8n/chat/event-buses';
7
-
8
- const isOpen = ref(false);
9
-
10
- function toggle() {
11
- isOpen.value = !isOpen.value;
12
-
13
- if (isOpen.value) {
14
- void nextTick(() => {
15
- chatEventBus.emit('scrollToBottom');
16
- });
17
- }
18
- }
19
- </script>
20
-
21
- <template>
22
- <div class="chat-window-wrapper">
23
- <Transition name="chat-window-transition">
24
- <div v-show="isOpen" class="chat-window">
25
- <Chat />
26
- </div>
27
- </Transition>
28
- <div class="chat-window-toggle" @click="toggle">
29
- <Transition name="chat-window-toggle-transition" mode="out-in">
30
- <IconChat v-if="!isOpen" height="32" width="32" />
31
- <IconChevronDown v-else height="32" width="32" />
32
- </Transition>
33
- </div>
34
- </div>
35
- </template>
36
-
37
- <style lang="scss">
38
- .chat-window-wrapper {
39
- position: fixed;
40
- display: flex;
41
- flex-direction: column;
42
- bottom: var(--chat--window--bottom, var(--chat--spacing));
43
- right: var(--chat--window--right, var(--chat--spacing));
44
- z-index: var(--chat--window--z-index, 9999);
45
-
46
- max-width: calc(100% - var(--chat--window--right, var(--chat--spacing)) * 2);
47
- max-height: calc(100% - var(--chat--window--bottom, var(--chat--spacing)) * 2);
48
-
49
- .chat-window {
50
- display: flex;
51
- width: var(--chat--window--width);
52
- height: var(--chat--window--height);
53
- max-width: 100%;
54
- max-height: 100%;
55
- border: var(--chat--window--border, 1px solid var(--chat--color-light-shade-100));
56
- border-radius: var(--chat--window--border-radius, var(--chat--border-radius));
57
- margin-bottom: var(--chat--window--margin-bottom, var(--chat--spacing));
58
- overflow: hidden;
59
- transform-origin: bottom right;
60
-
61
- .chat-layout {
62
- width: auto;
63
- height: auto;
64
- flex: 1;
65
- }
66
- }
67
-
68
- .chat-window-toggle {
69
- flex: 0 0 auto;
70
- background: var(--chat--toggle--background);
71
- color: var(--chat--toggle--color);
72
- cursor: pointer;
73
- width: var(--chat--toggle--width, var(--chat--toggle--size));
74
- height: var(--chat--toggle--height, var(--chat--toggle--size));
75
- border-radius: var(--chat--toggle--border-radius, 50%);
76
- display: inline-flex;
77
- align-items: center;
78
- justify-content: center;
79
- margin-left: auto;
80
- transition:
81
- transform var(--chat--transition-duration) ease,
82
- background var(--chat--transition-duration) ease;
83
-
84
- &:hover,
85
- &:focus {
86
- transform: scale(1.05);
87
- background: var(--chat--toggle--hover--background);
88
- }
89
-
90
- &:active {
91
- transform: scale(0.95);
92
- background: var(--chat--toggle--active--background);
93
- }
94
- }
95
- }
96
-
97
- .chat-window-transition {
98
- &-enter-active,
99
- &-leave-active {
100
- transition:
101
- transform var(--chat--transition-duration) ease,
102
- opacity var(--chat--transition-duration) ease;
103
- }
104
-
105
- &-enter-from,
106
- &-leave-to {
107
- transform: scale(0);
108
- opacity: 0;
109
- }
110
- }
111
-
112
- .chat-window-toggle-transition {
113
- &-enter-active,
114
- &-leave-active {
115
- transition: opacity var(--chat--transition-duration) ease;
116
- }
117
-
118
- &-enter-from,
119
- &-leave-to {
120
- opacity: 0;
121
- }
122
- }
123
- </style>
@@ -1,24 +0,0 @@
1
- <script setup lang="ts">
2
- import Button from '@n8n/chat/components/Button.vue';
3
- import { useI18n } from '@n8n/chat/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 '@n8n/chat/composables';
3
- import PoweredBy from '@n8n/chat/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,108 +0,0 @@
1
- <script setup lang="ts">
2
- import IconSend from 'virtual:icons/mdi/send';
3
- import { computed, onMounted, ref } from 'vue';
4
- import { useI18n, useChat, useOptions } from '@n8n/chat/composables';
5
- import { chatEventBus } from '@n8n/chat/event-buses';
6
-
7
- const { options } = useOptions();
8
- const chatStore = useChat();
9
- const { waitingForResponse } = chatStore;
10
- const { t } = useI18n();
11
-
12
- const chatTextArea = ref<HTMLTextAreaElement | null>(null);
13
- const input = ref('');
14
-
15
- const isSubmitDisabled = computed(() => {
16
- return input.value === '' || waitingForResponse.value || options.disabled?.value === true;
17
- });
18
-
19
- const isInputDisabled = computed(() => options.disabled?.value === true);
20
-
21
- onMounted(() => {
22
- chatEventBus.on('focusInput', () => {
23
- if (chatTextArea.value) {
24
- chatTextArea.value.focus();
25
- }
26
- });
27
- });
28
-
29
- async function onSubmit(event: MouseEvent | KeyboardEvent) {
30
- event.preventDefault();
31
-
32
- if (isSubmitDisabled.value) {
33
- return;
34
- }
35
-
36
- const messageText = input.value;
37
- input.value = '';
38
- await chatStore.sendMessage(messageText);
39
- }
40
-
41
- async function onSubmitKeydown(event: KeyboardEvent) {
42
- if (event.shiftKey) {
43
- return;
44
- }
45
-
46
- await onSubmit(event);
47
- }
48
- </script>
49
-
50
- <template>
51
- <div class="chat-input">
52
- <textarea
53
- ref="chatTextArea"
54
- v-model="input"
55
- rows="1"
56
- :disabled="isInputDisabled"
57
- :placeholder="t('inputPlaceholder')"
58
- @keydown.enter="onSubmitKeydown"
59
- />
60
- <button :disabled="isSubmitDisabled" class="chat-input-send-button" @click="onSubmit">
61
- <IconSend height="32" width="32" />
62
- </button>
63
- </div>
64
- </template>
65
-
66
- <style lang="scss">
67
- .chat-input {
68
- display: flex;
69
- justify-content: center;
70
- align-items: center;
71
- width: 100%;
72
- background: white;
73
-
74
- textarea {
75
- font-family: inherit;
76
- font-size: var(--chat--input--font-size, inherit);
77
- width: 100%;
78
- border: 0;
79
- padding: var(--chat--spacing);
80
- max-height: var(--chat--textarea--height);
81
- resize: none;
82
- }
83
-
84
- .chat-input-send-button {
85
- height: var(--chat--textarea--height);
86
- width: var(--chat--textarea--height);
87
- background: white;
88
- cursor: pointer;
89
- color: var(--chat--input--send--button--color, var(--chat--color-secondary));
90
- border: 0;
91
- font-size: 24px;
92
- display: inline-flex;
93
- align-items: center;
94
- justify-content: center;
95
- transition: color var(--chat--transition-duration) ease;
96
-
97
- &:hover,
98
- &:focus {
99
- color: var(--chat--color-secondary-shade-50);
100
- }
101
-
102
- &[disabled] {
103
- cursor: default;
104
- color: var(--chat--color-disabled);
105
- }
106
- }
107
- }
108
- </style>
@@ -1,99 +0,0 @@
1
- <script setup lang="ts">
2
- import { onBeforeUnmount, onMounted, ref } from 'vue';
3
- import { chatEventBus } from '@n8n/chat/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" ref="chatBodyRef" class="chat-body">
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
- display: flex;
62
- flex-direction: column;
63
- justify-content: center;
64
- gap: 1em;
65
- height: var(--chat--header-height, auto);
66
- padding: var(--chat--header--padding, var(--chat--spacing));
67
- background: var(--chat--header--background, var(--chat--color-dark));
68
- color: var(--chat--header--color, var(--chat--color-light));
69
- border-top: var(--chat--header--border-top, none);
70
- border-bottom: var(--chat--header--border-bottom, none);
71
- border-left: var(--chat--header--border-left, none);
72
- border-right: var(--chat--header--border-right, none);
73
- h1 {
74
- font-size: var(--chat--heading--font-size);
75
- color: var(--chat--header--color, var(--chat--color-light));
76
- }
77
- p {
78
- font-size: var(--chat--subtitle--font-size, inherit);
79
- line-height: var(--chat--subtitle--line-height, 1.8);
80
- }
81
- }
82
-
83
- .chat-body {
84
- background: var(--chat--body--background, var(--chat--color-light));
85
- flex: 1;
86
- display: flex;
87
- flex-direction: column;
88
- overflow-y: auto;
89
- position: relative;
90
- min-height: 100px;
91
- }
92
-
93
- .chat-footer {
94
- border-top: 1px solid var(--chat--color-light-shade-100);
95
- background: var(--chat--footer--background, var(--chat--color-light));
96
- color: var(--chat--footer--color, var(--chat--color-dark));
97
- }
98
- }
99
- </style>
@@ -1,137 +0,0 @@
1
- <script lang="ts" setup>
2
- /* eslint-disable @typescript-eslint/naming-convention */
3
- import { computed, toRefs } from 'vue';
4
- import VueMarkdown from 'vue-markdown-render';
5
- import hljs from 'highlight.js/lib/core';
6
- import markdownLink from 'markdown-it-link-attributes';
7
- import type MarkdownIt from 'markdown-it';
8
- import type { ChatMessage, ChatMessageText } from '@n8n/chat/types';
9
- import { useOptions } from '@n8n/chat/composables';
10
-
11
- const props = defineProps<{
12
- message: ChatMessage;
13
- }>();
14
-
15
- const { message } = toRefs(props);
16
- const { options } = useOptions();
17
-
18
- const messageText = computed(() => {
19
- return (message.value as ChatMessageText).text || '&lt;Empty response&gt;';
20
- });
21
-
22
- const classes = computed(() => {
23
- return {
24
- 'chat-message-from-user': message.value.sender === 'user',
25
- 'chat-message-from-bot': message.value.sender === 'bot',
26
- 'chat-message-transparent': message.value.transparent === true,
27
- };
28
- });
29
-
30
- const linksNewTabPlugin = (vueMarkdownItInstance: MarkdownIt) => {
31
- vueMarkdownItInstance.use(markdownLink, {
32
- attrs: {
33
- target: '_blank',
34
- rel: 'noopener',
35
- },
36
- });
37
- };
38
-
39
- const markdownOptions = {
40
- highlight(str: string, lang: string) {
41
- if (lang && hljs.getLanguage(lang)) {
42
- try {
43
- return hljs.highlight(str, { language: lang }).value;
44
- } catch {}
45
- }
46
-
47
- return ''; // use external default escaping
48
- },
49
- };
50
-
51
- const messageComponents = options?.messageComponents ?? {};
52
- </script>
53
- <template>
54
- <div class="chat-message" :class="classes">
55
- <slot>
56
- <template v-if="message.type === 'component' && messageComponents[message.key]">
57
- <component :is="messageComponents[message.key]" v-bind="message.arguments" />
58
- </template>
59
- <VueMarkdown
60
- v-else
61
- class="chat-message-markdown"
62
- :source="messageText"
63
- :options="markdownOptions"
64
- :plugins="[linksNewTabPlugin]"
65
- />
66
- </slot>
67
- </div>
68
- </template>
69
-
70
- <style lang="scss">
71
- .chat-message {
72
- display: block;
73
- max-width: 80%;
74
- font-size: var(--chat--message--font-size, 1rem);
75
- padding: var(--chat--message--padding, var(--chat--spacing));
76
- border-radius: var(--chat--message--border-radius, var(--chat--border-radius));
77
-
78
- p {
79
- line-height: var(--chat--message-line-height, 1.8);
80
- word-wrap: break-word;
81
- }
82
-
83
- // Default message gap is half of the spacing
84
- + .chat-message {
85
- margin-top: var(--chat--message--margin-bottom, calc(var(--chat--spacing) * 0.5));
86
- }
87
-
88
- // Spacing between messages from different senders is double the individual message gap
89
- &.chat-message-from-user + &.chat-message-from-bot,
90
- &.chat-message-from-bot + &.chat-message-from-user {
91
- margin-top: var(--chat--spacing);
92
- }
93
-
94
- &.chat-message-from-bot {
95
- &:not(.chat-message-transparent) {
96
- background-color: var(--chat--message--bot--background);
97
- border: var(--chat--message--bot--border, none);
98
- }
99
- color: var(--chat--message--bot--color);
100
- border-bottom-left-radius: 0;
101
- }
102
-
103
- &.chat-message-from-user {
104
- &:not(.chat-message-transparent) {
105
- background-color: var(--chat--message--user--background);
106
- border: var(--chat--message--user--border, none);
107
- }
108
- color: var(--chat--message--user--color);
109
- margin-left: auto;
110
- border-bottom-right-radius: 0;
111
- }
112
-
113
- > .chat-message-markdown {
114
- display: block;
115
- box-sizing: border-box;
116
-
117
- > *:first-child {
118
- margin-top: 0;
119
- }
120
-
121
- > *:last-child {
122
- margin-bottom: 0;
123
- }
124
-
125
- pre {
126
- font-family: inherit;
127
- font-size: inherit;
128
- margin: 0;
129
- white-space: pre-wrap;
130
- box-sizing: border-box;
131
- padding: var(--chat--spacing);
132
- background: var(--chat--message--pre--background);
133
- border-radius: var(--chat--border-radius);
134
- }
135
- }
136
- }
137
- </style>