@gitlab/duo-ui 0.2.0 → 0.3.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 (77) hide show
  1. package/CHANGELOG.md +3 -11701
  2. package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_details_modal/duo_chat_context_item_details_modal.js +1 -1
  3. package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_items_loading.js +1 -1
  4. package/dist/components/chat/components/duo_chat_message/constants.js +5 -0
  5. package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_message/duo_chat_message.js +26 -2
  6. package/dist/components/{experimental/duo/chat → chat}/mock_data.js +1 -1
  7. package/dist/components.css +2 -0
  8. package/dist/components.css.map +1 -0
  9. package/package.json +2 -2
  10. package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_details_modal/duo_chat_context_item_details_modal.vue +1 -1
  11. package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_items_loading.vue +1 -1
  12. package/src/components/chat/components/duo_chat_message/constants.js +3 -0
  13. package/src/components/{experimental/duo/chat → chat}/components/duo_chat_message/duo_chat_message.scss +31 -2
  14. package/src/components/{experimental/duo/chat → chat}/components/duo_chat_message/duo_chat_message.vue +33 -2
  15. package/src/components/chat/duo_chat.scss +393 -0
  16. package/src/components/{experimental/duo/chat → chat}/mock_data.js +1 -1
  17. package/src/index.js +3 -3
  18. package/src/scss/components.scss +6 -0
  19. package/src/components/experimental/duo/chat/duo_chat.scss +0 -168
  20. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/constants.js +0 -0
  21. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu.js +0 -0
  22. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_category_items.js +0 -0
  23. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_item.js +0 -0
  24. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_items.js +0 -0
  25. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_popover/duo_chat_context_item_popover.js +0 -0
  26. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections.js +0 -0
  27. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/mock_context_data.js +0 -0
  28. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_context/utils.js +0 -0
  29. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_conversation/duo_chat_conversation.js +0 -0
  30. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_loader/duo_chat_loader.js +0 -0
  31. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_message/buttons_utils.js +0 -0
  32. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_message/copy_code_element.js +0 -0
  33. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_message/insert_code_snippet_element.js +0 -0
  34. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_message/utils.js +0 -0
  35. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_message_sources/duo_chat_message_sources.js +0 -0
  36. /package/dist/components/{experimental/duo/chat → chat}/components/duo_chat_predefined_prompts/duo_chat_predefined_prompts.js +0 -0
  37. /package/dist/components/{experimental/duo/chat → chat}/constants.js +0 -0
  38. /package/dist/components/{experimental/duo/chat → chat}/duo_chat.js +0 -0
  39. /package/dist/components/{experimental/duo/chat → chat}/markdown_renderer.js +0 -0
  40. /package/dist/components/{experimental/duo/user_feedback → user_feedback}/user_feedback.js +0 -0
  41. /package/dist/components/{experimental/duo/user_feedback → user_feedback}/user_feedback_modal.js +0 -0
  42. /package/dist/components/{experimental/duo/workflow → workflow}/components/duo_workflow_panel/duo_workflow_panel.js +0 -0
  43. /package/dist/components/{experimental/duo/workflow → workflow}/components/duo_workflow_prompt/duo_workflow_prompt.js +0 -0
  44. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/constants.js +0 -0
  45. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu.vue +0 -0
  46. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_category_items.vue +0 -0
  47. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_item.vue +0 -0
  48. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_menu/duo_chat_context_item_menu_search_items.vue +0 -0
  49. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_popover/duo_chat_context_item_popover.vue +0 -0
  50. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections.vue +0 -0
  51. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/mock_context_data.js +0 -0
  52. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_context/utils.js +0 -0
  53. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_conversation/duo_chat_conversation.md +0 -0
  54. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_conversation/duo_chat_conversation.vue +0 -0
  55. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_loader/duo_chat_loader.md +0 -0
  56. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_loader/duo_chat_loader.scss +0 -0
  57. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_loader/duo_chat_loader.vue +0 -0
  58. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_message/buttons_utils.js +0 -0
  59. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_message/copy_code_element.js +0 -0
  60. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_message/duo_chat_message.md +0 -0
  61. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_message/insert_code_snippet_element.js +0 -0
  62. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_message/utils.js +0 -0
  63. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_message_sources/duo_chat_message_sources.md +0 -0
  64. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_message_sources/duo_chat_message_sources.vue +0 -0
  65. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_predefined_prompts/duo_chat_predefined_prompts.md +0 -0
  66. /package/src/components/{experimental/duo/chat → chat}/components/duo_chat_predefined_prompts/duo_chat_predefined_prompts.vue +0 -0
  67. /package/src/components/{experimental/duo/chat → chat}/constants.js +0 -0
  68. /package/src/components/{experimental/duo/chat → chat}/duo_chat.md +0 -0
  69. /package/src/components/{experimental/duo/chat → chat}/duo_chat.vue +0 -0
  70. /package/src/components/{experimental/duo/chat → chat}/markdown_renderer.js +0 -0
  71. /package/src/components/{experimental/duo/user_feedback → user_feedback}/user_feedback.md +0 -0
  72. /package/src/components/{experimental/duo/user_feedback → user_feedback}/user_feedback.vue +0 -0
  73. /package/src/components/{experimental/duo/user_feedback → user_feedback}/user_feedback_modal.vue +0 -0
  74. /package/src/components/{experimental/duo/workflow → workflow}/components/duo_workflow_panel/duo_workflow_panel.md +0 -0
  75. /package/src/components/{experimental/duo/workflow → workflow}/components/duo_workflow_panel/duo_workflow_panel.vue +0 -0
  76. /package/src/components/{experimental/duo/workflow → workflow}/components/duo_workflow_prompt/duo_workflow_prompt.md +0 -0
  77. /package/src/components/{experimental/duo/workflow → workflow}/components/duo_workflow_prompt/duo_workflow_prompt.vue +0 -0
@@ -18,7 +18,7 @@ var script = {
18
18
  renderGFM: {
19
19
  from: 'renderGFM',
20
20
  default: () => element => {
21
- element.classList.add('gl-markdown', 'gl-compact-markdown');
21
+ element.classList.add('duo-chat-markdown', 'duo-chat-compact-markdown');
22
22
  }
23
23
  }
24
24
  },
@@ -18,7 +18,7 @@ var script = {
18
18
  const __vue_script__ = script;
19
19
 
20
20
  /* template */
21
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_vm._l((_vm.rows),function(index){return _c('div',{key:index,staticClass:"gl-mx-3 gl-mb-4 gl-pt-3",attrs:{"data-testid":"search-results-loading"}},[_vm._m(0,true),_vm._v(" "),_c('div',{staticClass:"gl-animate-skeleton-loader gl-h-4 gl-w-1/2 gl-rounded-base"})])}),_vm._v(" "),_c('span',{staticClass:"sr-only"},[_vm._v(_vm._s(_vm.$options.i18n.loadingMessage))])],2)};
21
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_vm._l((_vm.rows),function(index){return _c('div',{key:index,staticClass:"gl-mx-3 gl-mb-4 gl-pt-3",attrs:{"data-testid":"search-results-loading"}},[_vm._m(0,true),_vm._v(" "),_c('div',{staticClass:"gl-animate-skeleton-loader gl-h-4 gl-w-1/2 gl-rounded-base"})])}),_vm._v(" "),_c('span',{staticClass:"gl-sr-only"},[_vm._v(_vm._s(_vm.$options.i18n.loadingMessage))])],2)};
22
22
  var __vue_staticRenderFns__ = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-mb-2 gl-flex"},[_c('div',{staticClass:"gl-animate-skeleton-loader gl-mr-3 gl-h-5 gl-w-5 gl-rounded-base"}),_vm._v(" "),_c('div',{staticClass:"gl-animate-skeleton-loader gl-h-5 gl-grow gl-rounded-base"})])}];
23
23
 
24
24
  /* style */
@@ -0,0 +1,5 @@
1
+ const DUO_CODE_SCRIM_TOP_CLASS = 'scrim-top';
2
+ const DUO_CODE_SCRIM_BOTTOM_CLASS = 'scrim-bottom';
3
+ const DUO_CODE_SCRIM_OFFSET = 16;
4
+
5
+ export { DUO_CODE_SCRIM_BOTTOM_CLASS, DUO_CODE_SCRIM_OFFSET, DUO_CODE_SCRIM_TOP_CLASS };
@@ -1,5 +1,6 @@
1
1
  import { GlFormGroup, GlFormTextarea, GlIcon, GlLoadingIcon, GlSafeHtmlDirective, GlTooltipDirective } from '@gitlab/ui';
2
2
  import { translate, translatePlural, sprintf } from '@gitlab/ui/dist/utils/i18n';
3
+ import throttle from 'lodash/throttle';
3
4
  import GlDuoChatContextItemSelections from '../duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections';
4
5
  import GlDuoUserFeedback from '../../../user_feedback/user_feedback';
5
6
  import { SELECTED_CONTEXT_ITEMS_DEFAULT_COLLAPSED, MESSAGE_MODEL_ROLES } from '../../constants';
@@ -8,6 +9,7 @@ import { renderDuoChatMarkdownPreview } from '../../markdown_renderer';
8
9
  import { CopyCodeElement } from './copy_code_element';
9
10
  import { InsertCodeSnippetElement } from './insert_code_snippet_element';
10
11
  import { concatUntilEmpty } from './utils';
12
+ import { DUO_CODE_SCRIM_BOTTOM_CLASS, DUO_CODE_SCRIM_OFFSET, DUO_CODE_SCRIM_TOP_CLASS } from './constants';
11
13
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
12
14
 
13
15
  const i18n = {
@@ -54,7 +56,7 @@ var script = {
54
56
  renderGFM: {
55
57
  from: 'renderGFM',
56
58
  default: () => element => {
57
- element.classList.add('gl-markdown', 'gl-compact-markdown');
59
+ element.classList.add('duo-chat-markdown', 'duo-chat-compact-markdown');
58
60
  }
59
61
  },
60
62
  renderMarkdown: {
@@ -190,6 +192,7 @@ var script = {
190
192
  if (!this.isChunk && this.$refs.content) {
191
193
  this.$nextTick(this.renderGFM(this.$refs.content));
192
194
  }
195
+ this.detectScrollableCodeBlocks();
193
196
  },
194
197
  logEvent(e) {
195
198
  this.$emit('track-feedback', {
@@ -213,6 +216,27 @@ var script = {
213
216
  messageId: this.message.id,
214
217
  contextItem
215
218
  });
219
+ },
220
+ detectScrollableCodeBlocks() {
221
+ const codeBlocks = document.querySelectorAll('.duo-chat-message pre');
222
+ codeBlocks.forEach(e => {
223
+ if (e.scrollHeight > e.offsetHeight) {
224
+ e.classList.add(DUO_CODE_SCRIM_BOTTOM_CLASS);
225
+ e.addEventListener('scroll', throttle(() => this.toggleScrolling(e), 200));
226
+ }
227
+ });
228
+ },
229
+ toggleScrolling(e) {
230
+ if (e.scrollHeight - e.scrollTop <= e.offsetHeight + DUO_CODE_SCRIM_OFFSET) {
231
+ e.classList.remove(DUO_CODE_SCRIM_BOTTOM_CLASS);
232
+ } else {
233
+ e.classList.add(DUO_CODE_SCRIM_BOTTOM_CLASS);
234
+ }
235
+ if (e.scrollTop > DUO_CODE_SCRIM_OFFSET) {
236
+ e.classList.add(DUO_CODE_SCRIM_TOP_CLASS);
237
+ } else {
238
+ e.classList.remove(DUO_CODE_SCRIM_TOP_CLASS);
239
+ }
216
240
  }
217
241
  }
218
242
  };
@@ -226,7 +250,7 @@ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=
226
250
  'gl-rounded-bl-none gl-border-1 gl-border-solid gl-border-gray-50 gl-text-gray-900':
227
251
  _vm.isAssistantMessage,
228
252
  'gl-bg-white': _vm.isAssistantMessage && !_vm.error,
229
- '!gl-border-none gl-bg-red-50': _vm.error,
253
+ 'duo-chat-message-with-error !gl-border-none gl-bg-red-50': _vm.error,
230
254
  },on:{"insert-code-snippet":_vm.onInsertCodeSnippet}},[(_vm.error)?_c('gl-icon',{staticClass:"error-icon gl-border gl-mr-3 gl-shrink-0 gl-rounded-full gl-border-red-500 gl-text-red-600",attrs:{"aria-label":_vm.$options.i18n.MESSAGE_ERROR,"name":"status_warning_borderless","size":16,"data-testid":"error"}}):_vm._e(),_vm._v(" "),_c('div',{ref:"content-wrapper",class:{ 'has-error': _vm.error }},[(_vm.displaySelectedContextItems && _vm.isAssistantMessage)?_c('gl-duo-chat-context-item-selections',{attrs:{"selections":_vm.selectedContextItems,"title":_vm.selectedContextItemsTitle,"default-collapsed":_vm.selectedContextItemsDefaultCollapsed,"variant":"assistant"},on:{"get-content":_vm.onGetContextItemContent}}):_vm._e(),_vm._v(" "),(_vm.error)?_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(_vm.renderedError),expression:"renderedError",arg:_vm.$options.safeHtmlConfigExtension}],ref:"error-message"}):_c('div',[_c('div',{directives:[{name:"safe-html",rawName:"v-safe-html:[$options.safeHtmlConfigExtension]",value:(_vm.messageContent),expression:"messageContent",arg:_vm.$options.safeHtmlConfigExtension}],ref:"content"}),_vm._v(" "),(_vm.isAssistantMessage)?[(_vm.sources)?_c('documentation-sources',{attrs:{"sources":_vm.sources}}):_vm._e(),_vm._v(" "),_c('div',{staticClass:"duo-chat-message-feedback gl-mt-4 gl-flex gl-items-end"},[(_vm.isChunkAndNotCancelled)?_c('gl-loading-icon',{staticClass:"gl-pt-4",attrs:{"variant":"dots","inline":""}}):_vm._e(),_vm._v(" "),(_vm.isNotChunkOrCancelled)?_c('gl-duo-user-feedback',{attrs:{"feedback-received":_vm.hasFeedback,"modal-title":_vm.$options.i18n.MODAL.TITLE,"modal-alert":_vm.$options.i18n.MODAL.ALERT_TEXT},on:{"feedback":_vm.logEvent},scopedSlots:_vm._u([{key:"feedback-extra-fields",fn:function(){return [_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.DID_WHAT,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.INTERACTION},model:{value:(_vm.didWhat),callback:function ($$v) {_vm.didWhat=$$v;},expression:"didWhat"}})],1),_vm._v(" "),_c('gl-form-group',{attrs:{"label":_vm.$options.i18n.MODAL.IMPROVE_WHAT,"optional":""}},[_c('gl-form-textarea',{attrs:{"placeholder":_vm.$options.i18n.MODAL.BETTER_RESPONSE},model:{value:(_vm.improveWhat),callback:function ($$v) {_vm.improveWhat=$$v;},expression:"improveWhat"}})],1)]},proxy:true}],null,false,419229417)}):_vm._e()],1)]:_vm._e()],2),_vm._v(" "),(_vm.displaySelectedContextItems && _vm.isUserMessage)?_c('gl-duo-chat-context-item-selections',{attrs:{"selections":_vm.selectedContextItems,"title":_vm.selectedContextItemsTitle,"default-collapsed":_vm.selectedContextItemsDefaultCollapsed,"variant":"user"},on:{"get-content":_vm.onGetContextItemContent}}):_vm._e()],1)],1)};
231
255
  var __vue_staticRenderFns__ = [];
232
256
 
@@ -133,7 +133,7 @@ const renderMarkdown = content => content;
133
133
  const renderGFM = el => {
134
134
  const codeBlock = el.querySelectorAll('.markdown-code-block');
135
135
  codeBlock.forEach(block => {
136
- block === null || block === void 0 ? void 0 : block.classList.add('gl-markdown', 'gl-compact-markdown');
136
+ block === null || block === void 0 ? void 0 : block.classList.add('duo-chat-markdown', 'duo-chat-compact-markdown');
137
137
  });
138
138
  };
139
139
  const SLASH_COMMANDS = [{
@@ -0,0 +1,2 @@
1
+ @charset "UTF-8";.duo-chat{z-index:999}.duo-chat .message-enter-active,.duo-chat .message-leave-active{transition:all .5s ease}.duo-chat .message-enter,.duo-chat .message-leave-to{opacity:0;transform:translateY(10px)}.duo-chat .duo-chat-loader.message-leave,.duo-chat .duo-chat-loader.message-leave-to{transition:none}.duo-chat .duo-chat-drawer-body-scrim-on-footer:before{background:linear-gradient(180deg,#fbfafd00,#fbfafd)}.duo-chat .duo-chat-drawer-body{overflow-y:auto}.duo-chat .duo-chat-drawer-body>*,.duo-chat .duo-chat-drawer-header{padding:1rem}.duo-chat-drawer{display:flex;flex-direction:column;font-size:.875rem;height:100%;line-height:1rem;overflow-y:auto;position:fixed;right:0;transition-duration:.2s;transition-property:all;transition-timing-function:ease}.duo-chat-drawer-header,.duo-chat-drawer-header-sticky{border-bottom:1px solid var(--gray-100,#dcdcde)}.duo-chat-drawer-header-sticky{position:sticky;top:0}.duo-chat-drawer-body{background-color:inherit;flex-grow:1}.duo-chat-drawer-footer{border-top:1px solid var(--gray-100,#dcdcde);padding:1rem}.duo-chat-drawer-footer-sticky{bottom:0;position:sticky}.duo-chat-drawer-body-scrim-on-footer:before{--tw-translate-y:-100%;background:linear-gradient(180deg,#fbfafd00,#fbfafd);content:"";height:2rem;left:0;pointer-events:none;position:absolute;top:-1px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));width:100%}.duo-chat-history{scroll-behavior:smooth}.duo-chat-history.force-scroll-bar{min-height:calc(100% + 1rem)}.duo-chat-history *{overflow-anchor:none}.duo-chat-history .scroll-anchor{height:1px;margin-top:-1px;overflow-anchor:auto}.duo-chat-input{display:flex;flex-direction:column;max-height:240px;overflow:hidden}.duo-chat-input:focus-within{box-shadow:inset 0 0 0 1px #28272d,0 0 0 1px var(--gl-focus-ring-inner-color),0 0 0 3px var(--gl-focus-ring-outer-color);outline:none}@media (forced-colors:active){.duo-chat-input:focus-within{outline:2px solid LinkText}}.duo-chat-input .gl-form-textarea.form-control{flex:1;max-height:240px;padding-right:40px;resize:none}.duo-chat-input:after{content:attr(data-value) " ";padding-bottom:.75rem;padding-top:.75rem;visibility:hidden;white-space:pre-wrap}.slash-commands{margin-top:-.25rem}.slash-commands .active-command{background-color:var(--gray-50,#ececef);border-radius:.25rem}.slash-commands .gl-dropdown-item button.dropdown-item{background-color:initial;font-size:.75rem;padding-left:.5rem;padding-right:.5rem}.slash-commands .gl-dropdown-item button.dropdown-item:hover{background-color:initial}.duo-chat-markdown{color:#28272d;font-family:var(--default-regular-font,"GitLab Sans"),-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Noto Sans",Ubuntu,Cantarell,"Helvetica Neue",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5rem}.duo-chat-markdown :first-child{margin-top:0}.duo-chat-markdown .gl-h1,.duo-chat-markdown h1{font-size:clamp(1.5rem,.8333333333rem + 1.3888888889vw,1.875rem);font-weight:600;letter-spacing:-.01em;line-height:1.25;margin-bottom:1rem;margin-top:2rem}.duo-chat-markdown .gl-h2,.duo-chat-markdown h2{font-size:clamp(1.3125rem,.8680555556rem + .9259259259vw,1.5625rem);font-weight:600;letter-spacing:-.01em;line-height:1.25;margin-bottom:1rem;margin-top:1.5rem}.duo-chat-markdown .gl-h3,.duo-chat-markdown h3{font-size:clamp(1.125rem,.9027777778rem + .462962963vw,1.25rem);font-weight:600;letter-spacing:inherit;line-height:1.25;margin-bottom:1rem;margin-top:1.5rem}.duo-chat-markdown .gl-h4,.duo-chat-markdown h4{font-size:1rem;font-weight:600;letter-spacing:inherit;line-height:1.25;margin-bottom:1rem;margin-top:1rem}.duo-chat-markdown .gl-h5,.duo-chat-markdown h5{font-size:.875rem;font-weight:600;letter-spacing:inherit;line-height:1.25;margin-bottom:1rem;margin-top:1rem}.duo-chat-markdown .gl-h6,.duo-chat-markdown h6{font-size:.8125rem;font-weight:600;letter-spacing:inherit;line-height:1.25;margin-bottom:1rem;margin-top:1rem}.duo-chat-markdown .gl-paragraph,.duo-chat-markdown p{margin-bottom:0;margin-top:0}.duo-chat-markdown .gl-paragraph+.gl-paragraph,.duo-chat-markdown .gl-paragraph+p,.duo-chat-markdown p+.gl-paragraph,.duo-chat-markdown p+p{margin-top:1rem}.duo-chat-markdown .gl-paragraph.sm,.duo-chat-markdown .sm,.duo-chat-markdown p.sm{font-size:.875rem;line-height:1.25rem}.duo-chat-markdown .monospace,.duo-chat-markdown code{font-family:var(--default-mono-font,"GitLab Mono"),"JetBrains Mono","Menlo","DejaVu Sans Mono","Liberation Mono","Consolas","Ubuntu Mono","Courier New","andale mono","lucida console",monospace;font-variant-ligatures:none}.duo-chat-markdown blockquote{box-shadow:inset 4px 0 0 0 #dcdcde;color:var(--gray-700,#4c4b51);margin:.5rem 0;padding-bottom:.5rem;padding-left:1.5rem;padding-top:.5rem}.duo-chat-markdown .idiff{border-radius:.25rem;display:inline-flex;padding-left:.25rem;padding-right:.25rem}.duo-chat-markdown .deletion{background-color:var(--red-100,#fdd4cd)}.duo-chat-markdown .addition{background-color:var(--green-100,#c3e6cd)}.duo-chat-markdown code{background-color:var(--gray-50,#ececef);border-radius:.25rem;color:var(--gray-950,#18171d);padding:.125rem .25rem}.duo-chat-markdown pre{border-radius:.25rem;box-shadow:inset 0 0 0 1px #dcdcde;margin-bottom:2rem;margin-top:2rem;overflow:auto;padding:.5rem .75rem}.duo-chat-markdown pre code{background-color:var(--white,#fff);border-radius:0;color:var(--gray-900,#28272d);padding:0}.duo-chat-markdown .audio-container{display:inline-flex;flex-direction:column;width:100%}.duo-chat-markdown .audio-container audio{width:100%}.duo-chat-markdown .audio-container a{margin-top:.5rem}.duo-chat-markdown .audio-container a:before{-webkit-font-smoothing:antialiased;content:"📎";margin-right:.25rem;text-rendering:auto}.duo-chat-markdown table{margin-bottom:2rem;margin-top:2rem}.duo-chat-markdown table td,.duo-chat-markdown table th{box-shadow:inset 0 -1px 0 0 #dcdcde;padding:.75rem .5rem;vertical-align:top}.duo-chat-markdown table th{box-shadow:inset 0 1px 0 0 #dcdcde,inset 0 -1px 0 0 #dcdcde;font-weight:600}.duo-chat-markdown table thead{background-color:var(--gray-50,#ececef)}.duo-chat-markdown table tr:nth-child(2n){background-color:var(--gray-10,#fbfafd)}.duo-chat-compact-markdown{font-size:.875rem;line-height:1.25rem}.duo-chat-compact-markdown .gl-h1,.duo-chat-compact-markdown h1{font-size:1.5rem;font-weight:600;letter-spacing:-.01em;line-height:1.25;margin-bottom:1rem;margin-top:2rem}.duo-chat-compact-markdown .gl-h2,.duo-chat-compact-markdown h2{font-size:1.3125rem;font-weight:600;letter-spacing:-.01em;line-height:1.25;margin-bottom:1rem;margin-top:1.5rem}.duo-chat-compact-markdown .gl-h3,.duo-chat-compact-markdown h3{font-size:1.125rem;font-weight:600;letter-spacing:inherit;line-height:1.25;margin-bottom:1rem;margin-top:1.5rem}.duo-chat-compact-markdown .gl-h4,.duo-chat-compact-markdown h4{font-size:1rem;font-weight:600;letter-spacing:inherit;line-height:1.25;margin-bottom:1rem;margin-top:1rem}.duo-chat-compact-markdown .gl-h5,.duo-chat-compact-markdown h5{font-size:.875rem;font-weight:600;letter-spacing:inherit;line-height:1.25;margin-bottom:1rem;margin-top:1rem}.duo-chat-compact-markdown .gl-h6,.duo-chat-compact-markdown h6{font-size:.8125rem;font-weight:600;letter-spacing:inherit;line-height:1.25;margin-bottom:1rem;margin-top:1rem}.duo-chat-compact-markdown .sm{font-size:.75rem}.duo-chat-compact-markdown .monospace,.duo-chat-compact-markdown code{font-family:var(--default-mono-font,"GitLab Mono"),"JetBrains Mono","Menlo","DejaVu Sans Mono","Liberation Mono","Consolas","Ubuntu Mono","Courier New","andale mono","lucida console",monospace;font-variant-ligatures:none}.duo-chat-compact-markdown table td,.duo-chat-compact-markdown table th{padding-bottom:.5rem;padding-top:.5rem}.duo-chat-loader{color:var(--gray-500,#737278);display:flex}.duo-chat-loader .transition{transition:width .5s ease}.duo-chat-loader .text-enter{opacity:0}.duo-chat-loader .text-enter-active{transition:opacity 1s ease-in}.duo-chat-loader .text-enter-to,.duo-chat-loader .text-leave{opacity:1}.duo-chat-loader .text-leave-active{transition:opacity .7s linear}.duo-chat-loader .text-leave-to{opacity:0}.duo-chat-loader__dot{animation:DuoChatLoading 1.4s ease-in-out infinite;animation-fill-mode:both;background-color:#bfbfc3;border-radius:100%;display:inline-block;height:.3rem;width:.3rem}.duo-chat-loader__dot--1{animation-delay:-.3s}.duo-chat-loader__dot--2{animation-delay:-.15s}@keyframes DuoChatLoading{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}.duo-chat-message{max-width:90%;position:relative}.duo-chat-message code{background-color:var(--gray-100,#dcdcde)}.duo-chat-message pre{border-color:var(--gl-border-color-default);border-style:solid;border-width:1px;box-shadow:none!important;color:inherit;max-height:60vh;padding:.5rem .75rem}.duo-chat-message pre:after,.duo-chat-message pre:before{content:"";height:2rem;left:1px;pointer-events:none;position:absolute;width:calc(100% - 2px)}.duo-chat-message pre.scrim-top:before{background:linear-gradient(0deg,#fbfafd00,#fbfafd);border-top-left-radius:.25rem;border-top-right-radius:.25rem;top:1px}.duo-chat-message pre.scrim-bottom:after{background:linear-gradient(180deg,#fbfafd00,#fbfafd);border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem;bottom:1px}.duo-chat-message pre code{background-color:initial;font-size:.75rem;line-height:1;white-space:inherit}.duo-chat-message p:last-of-type{margin-bottom:0}.duo-chat-message copy-code,.duo-chat-message insert-code-snippet{opacity:0;position:absolute;right:.5rem;top:.5rem;transition-duration:.2s;transition-property:all;transition-timing-function:ease}.duo-chat-message copy-code{margin-right:2.5rem}.duo-chat-message .js-markdown-code.markdown-code-block:hover copy-code,.duo-chat-message .js-markdown-code.markdown-code-block:hover copy-code:focus-within,.duo-chat-message .js-markdown-code.markdown-code-block:hover insert-code-snippet,.duo-chat-message .js-markdown-code.markdown-code-block:hover insert-code-snippet:focus-within{opacity:1}.duo-chat-message .has-error{margin-left:1.5rem}.duo-chat-message .error-icon{position:absolute;top:14px}.insert-code-hidden insert-code-snippet{display:none}.insert-code-hidden copy-code{margin-right:0}
2
+ /*# sourceMappingURL=components.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["components.scss"],"names":[],"mappings":"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","file":"components.css","sourcesContent":["@charset \"UTF-8\";\n/*\n* SASS preserves units in arithmetic operations. For example:\n* 12em * 0 = 0em. This function return the unit of a numeric value.\n*\n* For more examples, see: https://codepen.io/paulgv/pen/XWrqMgQ\n*/\n/**\n* Declares a property with a fluid value that decreases or\n* rises depending on the viewport’s size. The property type\n* should be numeric.\n*\n* Values are expected in rem units.\n* Fluid range: between 48rem (768px) – 75rem (1200px).\n*\n* @param $property Property name, i.e. line-height, font-size, width, height, etc.\n* @param $min Property value lower bound.\n* @param $max Property value upper bound.\n*/\n/**\n* Helper function for :focus\n*\n* @param $size is deprecated and should not be used anymore\n*/\n/**\n* Helper function for @media of at least the minimum\n* breakpoint width.\n*\n* @param $name Breakpoint name, such as `sm` or `md`.\n*/\n/**\n* Helper function for @media of at most the maximum\n* breakpoint width.\n*\n* Note: Before using, consider using a mobile-first\n* approach, and define @media for larger breakpoints\n* using `gl-media-breakpoint-up` while using this rule as\n* the starting point instead.\n*\n* @param $name Breakpoint, such as `sm` or `md`. `xs` is not valid\n*/\n/**\n* Helper function to resolve font-size value from $gl-font-sizes and\n* $gl-font-sizes-fixed maps.\n*\n* @param $size Number font-size scale\n* @param $fixed Boolean toggle default and fixed font size scales\n*/\n/**\n* Defines default properties for heading typography based on font-size\n* scale value and default or fixed sizing.\n*\n* Note: overrides Bootstrap margin-top, other margin is determined by\n* individual context\n*\n* @param $size Number font-size scale\n* @param $fixed Boolean toggle default and fixed font size scales\n*/\n.duo-chat {\n z-index: 999;\n}\n.duo-chat .message-enter-active,\n.duo-chat .message-leave-active {\n transition: all 0.5s ease;\n}\n.duo-chat .message-enter,\n.duo-chat .message-leave-to {\n @apply gl-opacity-0;\n transform: translateY(10px);\n}\n.duo-chat .duo-chat-loader.message-leave,\n.duo-chat .duo-chat-loader.message-leave-to {\n transition: none;\n}\n.duo-chat .duo-chat-drawer-body-scrim-on-footer::before {\n background: linear-gradient(to bottom, rgba(251, 250, 253, 0), #fbfafd);\n}\n.duo-chat .duo-chat-drawer-body {\n overflow-y: auto;\n}\n.duo-chat .duo-chat-drawer-header,\n.duo-chat .duo-chat-drawer-body > * {\n @apply gl-p-5;\n}\n\n.duo-chat-drawer {\n right: 0;\n @apply gl-transition-all;\n position: fixed;\n @apply gl-h-full;\n @apply gl-overflow-y-auto;\n @apply gl-text-base;\n @apply gl-leading-normal;\n @apply gl-flex;\n @apply gl-flex-col;\n}\n\n.duo-chat-drawer-header {\n @apply gl-border-b-solid gl-border-b-gray-100 gl-border-b-1;\n}\n\n.duo-chat-drawer-header-sticky {\n top: 0;\n position: sticky;\n @apply gl-border-b-solid gl-border-b-gray-100 gl-border-b-1;\n}\n\n.duo-chat-drawer-body {\n @apply gl-grow;\n background-color: inherit;\n}\n\n.duo-chat-drawer-footer {\n @apply gl-border-t-solid gl-border-t-gray-100 gl-border-t-1;\n @apply gl-p-5;\n}\n\n.duo-chat-drawer-footer-sticky {\n bottom: 0;\n position: sticky;\n}\n\n.duo-chat-drawer-body-scrim-on-footer::before {\n background: linear-gradient(to bottom, rgba(251, 250, 253, 0), #fbfafd);\n top: -1px;\n @apply -gl-translate-y-full;\n content: \"\";\n left: 0;\n position: absolute;\n @apply gl-pointer-events-none;\n @apply gl-w-full;\n @apply gl-h-7;\n}\n\n.duo-chat-history {\n scroll-behavior: smooth;\n /*\n Browsers a are pretty good at keeping the focus on an element while\n the parent element grows in size. With this we mark all child elements\n of the chat history as \"non\" anchors.\n https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-anchor\n */\n /*\n Right at the bottom of the chat history we add a scroll-anchor element.\n This scroll-anchor element is the only \"possible\" anchor. The beauty of it:\n It only will be used as an anchor _if_ it is currently inside the view port.\n So if the user manually scrolls up while a chunked message is coming in,\n it won't stick to the bottom while the message still loads.\n */\n}\n.duo-chat-history.force-scroll-bar {\n min-height: calc(100% + 1rem);\n}\n.duo-chat-history * {\n overflow-anchor: none;\n}\n.duo-chat-history .scroll-anchor {\n overflow-anchor: auto;\n height: 1px;\n margin-top: -1px;\n}\n\n.duo-chat-input {\n @apply gl-flex;\n @apply gl-flex-col;\n max-height: 240px;\n overflow: hidden;\n}\n.duo-chat-input:focus-within {\n box-shadow: inset 0 0 0 1px #28272d, 0 0 0 1px var(--gl-focus-ring-inner-color), 0 0 0 3px var(--gl-focus-ring-outer-color);\n outline: none;\n}\n@media (forced-colors: active) {\n .duo-chat-input:focus-within {\n outline: 2px solid LinkText;\n }\n}\n.duo-chat-input .gl-form-textarea.form-control {\n flex: 1;\n resize: none;\n max-height: 240px;\n padding-right: 40px;\n}\n.duo-chat-input::after {\n content: attr(data-value) \" \";\n @apply gl-invisible;\n @apply gl-whitespace-pre-wrap;\n @apply gl-py-4;\n}\n\n.slash-commands {\n @apply -gl-mt-2;\n}\n.slash-commands .active-command {\n @apply gl-bg-gray-50;\n @apply gl-rounded-base;\n}\n.slash-commands .gl-dropdown-item button.dropdown-item {\n @apply gl-text-sm;\n @apply gl-px-3;\n @apply gl-bg-transparent;\n}\n.slash-commands .gl-dropdown-item button.dropdown-item:hover {\n @apply gl-bg-transparent;\n}\n\n.duo-chat-markdown {\n @apply gl-text-lg;\n @apply gl-leading-24;\n color: #28272d;\n @apply gl-font-regular;\n @apply gl-font-normal;\n}\n.duo-chat-markdown :first-child {\n @apply gl-mt-0;\n}\n.duo-chat-markdown h1,\n.duo-chat-markdown .gl-h1 {\n @apply gl-heading-1;\n @apply gl-mt-7;\n}\n.duo-chat-markdown h2,\n.duo-chat-markdown .gl-h2 {\n @apply gl-heading-2;\n @apply gl-mt-6;\n}\n.duo-chat-markdown h3,\n.duo-chat-markdown .gl-h3 {\n @apply gl-heading-3;\n @apply gl-mt-6;\n}\n.duo-chat-markdown h4,\n.duo-chat-markdown .gl-h4 {\n @apply gl-heading-4;\n @apply gl-mt-5;\n}\n.duo-chat-markdown h5,\n.duo-chat-markdown .gl-h5 {\n @apply gl-heading-5;\n @apply gl-mt-5;\n}\n.duo-chat-markdown h6,\n.duo-chat-markdown .gl-h6 {\n @apply gl-heading-6;\n @apply gl-mt-5;\n}\n.duo-chat-markdown p,\n.duo-chat-markdown .gl-paragraph {\n @apply gl-mt-0;\n @apply gl-mb-0;\n}\n.duo-chat-markdown p + p,\n.duo-chat-markdown p + .gl-paragraph,\n.duo-chat-markdown .gl-paragraph + p,\n.duo-chat-markdown .gl-paragraph + .gl-paragraph {\n @apply gl-mt-5;\n}\n.duo-chat-markdown p.sm,\n.duo-chat-markdown .gl-paragraph.sm {\n font-size: 0.875rem;\n @apply gl-leading-20;\n}\n.duo-chat-markdown .sm {\n font-size: 0.875rem;\n @apply gl-leading-20;\n}\n.duo-chat-markdown .monospace,\n.duo-chat-markdown code {\n @apply gl-font-monospace;\n}\n.duo-chat-markdown blockquote {\n @apply gl-text-gray-700;\n @apply gl-py-3;\n @apply gl-pl-6;\n @apply gl-my-3;\n @apply gl-mx-0;\n box-shadow: inset 4px 0 0 0 #dcdcde;\n}\n.duo-chat-markdown .idiff {\n @apply gl-rounded-base;\n @apply gl-inline-flex;\n @apply gl-px-2;\n}\n.duo-chat-markdown .deletion {\n @apply gl-bg-red-100;\n}\n.duo-chat-markdown .addition {\n @apply gl-bg-green-100;\n}\n.duo-chat-markdown code {\n @apply gl-rounded-base;\n @apply gl-bg-gray-50;\n @apply gl-text-gray-950;\n @apply gl-px-2;\n @apply gl-py-1;\n}\n.duo-chat-markdown pre {\n @apply gl-rounded-base;\n @apply gl-py-3;\n @apply gl-px-4;\n box-shadow: inset 0 0 0 1px #dcdcde;\n @apply gl-my-7;\n @apply gl-overflow-auto;\n}\n.duo-chat-markdown pre code {\n @apply gl-bg-white;\n @apply gl-rounded-none;\n @apply gl-text-gray-900;\n @apply gl-p-0;\n}\n.duo-chat-markdown .audio-container {\n @apply gl-inline-flex;\n @apply gl-flex-col;\n @apply gl-w-full;\n}\n.duo-chat-markdown .audio-container audio {\n @apply gl-w-full;\n}\n.duo-chat-markdown .audio-container a {\n @apply gl-mt-3;\n}\n.duo-chat-markdown .audio-container a::before {\n @apply gl-mr-2;\n text-rendering: auto;\n -webkit-font-smoothing: antialiased;\n content: \"📎\";\n}\n.duo-chat-markdown table {\n @apply gl-my-7;\n}\n.duo-chat-markdown table th,\n.duo-chat-markdown table td {\n @apply gl-px-3;\n @apply gl-py-4;\n box-shadow: inset 0 -1px 0 0 #dcdcde;\n @apply gl-align-top;\n}\n.duo-chat-markdown table th {\n box-shadow: inset 0 1px 0 0 #dcdcde, inset 0 -1px 0 0 #dcdcde;\n @apply gl-font-bold;\n}\n.duo-chat-markdown table thead {\n @apply gl-bg-gray-50;\n}\n.duo-chat-markdown table tr:nth-child(even) {\n @apply gl-bg-gray-10;\n}\n\n.duo-chat-compact-markdown {\n @apply gl-text-base;\n @apply gl-leading-20;\n}\n.duo-chat-compact-markdown h1,\n.duo-chat-compact-markdown .gl-h1 {\n @apply gl-heading-1-fixed;\n @apply gl-mt-7;\n}\n.duo-chat-compact-markdown h2,\n.duo-chat-compact-markdown .gl-h2 {\n @apply gl-heading-2-fixed;\n @apply gl-mt-6;\n}\n.duo-chat-compact-markdown h3,\n.duo-chat-compact-markdown .gl-h3 {\n @apply gl-heading-3-fixed;\n @apply gl-mt-6;\n}\n.duo-chat-compact-markdown h4,\n.duo-chat-compact-markdown .gl-h4 {\n @apply gl-heading-4-fixed;\n @apply gl-mt-5;\n}\n.duo-chat-compact-markdown h5,\n.duo-chat-compact-markdown .gl-h5 {\n @apply gl-heading-5-fixed;\n @apply gl-mt-5;\n}\n.duo-chat-compact-markdown h6,\n.duo-chat-compact-markdown .gl-h6 {\n @apply gl-heading-6-fixed;\n @apply gl-mt-5;\n}\n.duo-chat-compact-markdown .sm {\n @apply gl-text-sm;\n}\n.duo-chat-compact-markdown .monospace,\n.duo-chat-compact-markdown code {\n @apply gl-font-monospace;\n}\n.duo-chat-compact-markdown table th,\n.duo-chat-compact-markdown table td {\n @apply gl-py-3;\n}\n\n.duo-chat-loader {\n @apply gl-flex;\n @apply gl-text-gray-500;\n}\n.duo-chat-loader .transition {\n transition: width 0.5s ease;\n}\n.duo-chat-loader .text-enter {\n @apply gl-opacity-0;\n}\n.duo-chat-loader .text-enter-active {\n transition: opacity 1s ease-in;\n}\n.duo-chat-loader .text-enter-to {\n @apply gl-opacity-10;\n}\n.duo-chat-loader .text-leave {\n @apply gl-opacity-10;\n}\n.duo-chat-loader .text-leave-active {\n transition: opacity 0.7s linear;\n}\n.duo-chat-loader .text-leave-to {\n @apply gl-opacity-0;\n}\n.duo-chat-loader__dot {\n display: inline-block;\n width: 0.3rem;\n height: 0.3rem;\n background-color: #bfbfc3;\n border-radius: 100%;\n animation: DuoChatLoading 1400ms ease-in-out infinite;\n animation-fill-mode: both;\n}\n.duo-chat-loader__dot--1 {\n animation-delay: -0.3s;\n}\n.duo-chat-loader__dot--2 {\n animation-delay: -0.15s;\n}\n\n@keyframes DuoChatLoading {\n 0%, 80%, 100% {\n transform: scale(0);\n }\n 40% {\n transform: scale(1);\n }\n}\n.duo-chat-message {\n max-width: 90%;\n position: relative;\n}\n.duo-chat-message code {\n @apply gl-bg-gray-100;\n}\n.duo-chat-message pre {\n box-shadow: none !important;\n @apply gl-border gl-max-h-[60vh] gl-px-4 gl-py-3 gl-text-inherit;\n}\n.duo-chat-message pre::before, .duo-chat-message pre::after {\n content: \"\";\n left: 1px;\n width: calc(100% - 2px);\n position: absolute;\n @apply gl-pointer-events-none;\n @apply gl-h-7;\n}\n.duo-chat-message pre.scrim-top::before {\n background: linear-gradient(to top, rgba(251, 250, 253, 0), #fbfafd);\n top: 1px;\n @apply gl-rounded-t-base;\n}\n.duo-chat-message pre.scrim-bottom::after {\n background: linear-gradient(to bottom, rgba(251, 250, 253, 0), #fbfafd);\n bottom: 1px;\n @apply gl-rounded-b-base;\n}\n.duo-chat-message pre code {\n @apply gl-text-sm;\n @apply gl-leading-1;\n @apply gl-bg-transparent;\n white-space: inherit;\n}\n.duo-chat-message p:last-of-type {\n @apply gl-mb-0;\n}\n.duo-chat-message copy-code,\n.duo-chat-message insert-code-snippet {\n position: absolute;\n @apply gl-transition-all;\n @apply gl-opacity-0;\n right: 0.5rem;\n top: 0.5rem;\n}\n.duo-chat-message copy-code {\n margin-right: 2.5rem;\n}\n.duo-chat-message .js-markdown-code.markdown-code-block:hover copy-code,\n.duo-chat-message .js-markdown-code.markdown-code-block:hover copy-code:focus-within,\n.duo-chat-message .js-markdown-code.markdown-code-block:hover insert-code-snippet,\n.duo-chat-message .js-markdown-code.markdown-code-block:hover insert-code-snippet:focus-within {\n @apply gl-opacity-10;\n}\n.duo-chat-message .has-error {\n margin-left: 1.5rem;\n}\n.duo-chat-message .error-icon {\n top: 14px;\n position: absolute;\n}\n\n.insert-code-hidden insert-code-snippet {\n display: none;\n}\n.insert-code-hidden copy-code {\n margin-right: 0;\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/duo-ui",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Duo UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "peerDependencies": {
85
85
  "@gitlab/svgs": "^1.116.0 || ^2.0.0 || ^3.0.0",
86
- "@gitlab/ui": "^96.0.0",
86
+ "@gitlab/ui": "^101.3.1",
87
87
  "bootstrap": ">=4.5.3 <=4.6.2",
88
88
  "dompurify": ">=2.5.2 <3.0.0 || >=3.1.2",
89
89
  "emoji-regex": ">=10.0.0",
@@ -23,7 +23,7 @@ export default {
23
23
  renderGFM: {
24
24
  from: 'renderGFM',
25
25
  default: () => (element) => {
26
- element.classList.add('gl-markdown', 'gl-compact-markdown');
26
+ element.classList.add('duo-chat-markdown', 'duo-chat-compact-markdown');
27
27
  },
28
28
  },
29
29
  },
@@ -29,6 +29,6 @@ export default {
29
29
  </div>
30
30
  <div class="gl-animate-skeleton-loader gl-h-4 gl-w-1/2 gl-rounded-base"></div>
31
31
  </div>
32
- <span class="sr-only">{{ $options.i18n.loadingMessage }}</span>
32
+ <span class="gl-sr-only">{{ $options.i18n.loadingMessage }}</span>
33
33
  </div>
34
34
  </template>
@@ -0,0 +1,3 @@
1
+ export const DUO_CODE_SCRIM_TOP_CLASS = 'scrim-top';
2
+ export const DUO_CODE_SCRIM_BOTTOM_CLASS = 'scrim-bottom';
3
+ export const DUO_CODE_SCRIM_OFFSET = 16;
@@ -1,3 +1,6 @@
1
+ $duo-code-scrim-bottom-gradient: linear-gradient(to bottom, rgba($gray-10, 0), $gray-10);
2
+ $duo-code-scrim-top-gradient: linear-gradient(to top, rgba($gray-10, 0), $gray-10);
3
+
1
4
  .duo-chat-message {
2
5
  max-width: 90%;
3
6
  position: relative;
@@ -7,8 +10,34 @@
7
10
  }
8
11
 
9
12
  pre {
10
- @apply gl-text-inherit;
11
- padding: $gl-spacing-scale-3 $gl-spacing-scale-4;
13
+ box-shadow: none !important;
14
+ @apply gl-border gl-max-h-[60vh] gl-px-4 gl-py-3 gl-text-inherit;
15
+
16
+ &::before,
17
+ &::after {
18
+ content: '';
19
+ left: 1px;
20
+ width: calc(100% - 2px);
21
+ position: absolute;
22
+ @apply gl-pointer-events-none;
23
+ @apply gl-h-7;
24
+ }
25
+
26
+ &.scrim-top {
27
+ &::before {
28
+ background: $duo-code-scrim-top-gradient;
29
+ top: 1px;
30
+ @apply gl-rounded-t-base;
31
+ }
32
+ }
33
+
34
+ &.scrim-bottom {
35
+ &::after {
36
+ background: $duo-code-scrim-bottom-gradient;
37
+ bottom: 1px;
38
+ @apply gl-rounded-b-base;
39
+ }
40
+ }
12
41
  }
13
42
 
14
43
  pre code {
@@ -9,6 +9,7 @@ import {
9
9
  } from '@gitlab/ui';
10
10
 
11
11
  import { sprintf, translate, translatePlural } from '@gitlab/ui/dist/utils/i18n';
12
+ import throttle from 'lodash/throttle';
12
13
  import GlDuoChatContextItemSelections from '../duo_chat_context/duo_chat_context_item_selections/duo_chat_context_item_selections.vue';
13
14
  import GlDuoUserFeedback from '../../../user_feedback/user_feedback.vue';
14
15
  import { MESSAGE_MODEL_ROLES, SELECTED_CONTEXT_ITEMS_DEFAULT_COLLAPSED } from '../../constants';
@@ -19,6 +20,11 @@ import { renderDuoChatMarkdownPreview } from '../../markdown_renderer';
19
20
  import { CopyCodeElement } from './copy_code_element';
20
21
  import { InsertCodeSnippetElement } from './insert_code_snippet_element';
21
22
  import { concatUntilEmpty } from './utils';
23
+ import {
24
+ DUO_CODE_SCRIM_BOTTOM_CLASS,
25
+ DUO_CODE_SCRIM_OFFSET,
26
+ DUO_CODE_SCRIM_TOP_CLASS,
27
+ } from './constants';
22
28
 
23
29
  export const i18n = {
24
30
  MODAL: {
@@ -77,7 +83,7 @@ export default {
77
83
  renderGFM: {
78
84
  from: 'renderGFM',
79
85
  default: () => (element) => {
80
- element.classList.add('gl-markdown', 'gl-compact-markdown');
86
+ element.classList.add('duo-chat-markdown', 'duo-chat-compact-markdown');
81
87
  },
82
88
  },
83
89
  renderMarkdown: {
@@ -220,6 +226,7 @@ export default {
220
226
  if (!this.isChunk && this.$refs.content) {
221
227
  this.$nextTick(this.renderGFM(this.$refs.content));
222
228
  }
229
+ this.detectScrollableCodeBlocks();
223
230
  },
224
231
  logEvent(e) {
225
232
  this.$emit('track-feedback', {
@@ -244,6 +251,30 @@ export default {
244
251
  contextItem,
245
252
  });
246
253
  },
254
+ detectScrollableCodeBlocks() {
255
+ const codeBlocks = document.querySelectorAll('.duo-chat-message pre');
256
+ codeBlocks.forEach((e) => {
257
+ if (e.scrollHeight > e.offsetHeight) {
258
+ e.classList.add(DUO_CODE_SCRIM_BOTTOM_CLASS);
259
+ e.addEventListener(
260
+ 'scroll',
261
+ throttle(() => this.toggleScrolling(e), 200)
262
+ );
263
+ }
264
+ });
265
+ },
266
+ toggleScrolling(e) {
267
+ if (e.scrollHeight - e.scrollTop <= e.offsetHeight + DUO_CODE_SCRIM_OFFSET) {
268
+ e.classList.remove(DUO_CODE_SCRIM_BOTTOM_CLASS);
269
+ } else {
270
+ e.classList.add(DUO_CODE_SCRIM_BOTTOM_CLASS);
271
+ }
272
+ if (e.scrollTop > DUO_CODE_SCRIM_OFFSET) {
273
+ e.classList.add(DUO_CODE_SCRIM_TOP_CLASS);
274
+ } else {
275
+ e.classList.remove(DUO_CODE_SCRIM_TOP_CLASS);
276
+ }
277
+ },
247
278
  },
248
279
  };
249
280
  </script>
@@ -255,7 +286,7 @@ export default {
255
286
  'gl-rounded-bl-none gl-border-1 gl-border-solid gl-border-gray-50 gl-text-gray-900':
256
287
  isAssistantMessage,
257
288
  'gl-bg-white': isAssistantMessage && !error,
258
- '!gl-border-none gl-bg-red-50': error,
289
+ 'duo-chat-message-with-error !gl-border-none gl-bg-red-50': error,
259
290
  }"
260
291
  @insert-code-snippet="onInsertCodeSnippet"
261
292
  >