@gitlab/ui 66.34.0 → 66.35.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [66.35.1](https://gitlab.com/gitlab-org/gitlab-ui/compare/v66.35.0...v66.35.1) (2023-10-20)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **GlDuoChatMessage:** nextTick() when rendering GFM ([835900c](https://gitlab.com/gitlab-org/gitlab-ui/commit/835900cb9cf01e26b4e24120be3abc6f48c3c371))
7
+
8
+ # [66.35.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v66.34.0...v66.35.0) (2023-10-20)
9
+
10
+
11
+ ### Features
12
+
13
+ * **DisclosureDropdown:** Add startOpened prop ([4896b9c](https://gitlab.com/gitlab-org/gitlab-ui/commit/4896b9c3a6f9075a76fa71ea275f2153de111249))
14
+
1
15
  # [66.34.0](https://gitlab.com/gitlab-org/gitlab-ui/compare/v66.33.0...v66.34.0) (2023-10-18)
2
16
 
3
17
 
@@ -198,6 +198,14 @@ var script = {
198
198
  required: false,
199
199
  default: POSITION_ABSOLUTE,
200
200
  validator: strategy => [POSITION_ABSOLUTE, POSITION_FIXED].includes(strategy)
201
+ },
202
+ /**
203
+ * Opens dropdown on render
204
+ */
205
+ startOpened: {
206
+ type: Boolean,
207
+ required: false,
208
+ default: false
201
209
  }
202
210
  },
203
211
  data() {
@@ -218,6 +226,11 @@ var script = {
218
226
  return Boolean(this.$scopedSlots.toggle);
219
227
  }
220
228
  },
229
+ mounted() {
230
+ if (this.startOpened) {
231
+ this.open();
232
+ }
233
+ },
221
234
  methods: {
222
235
  open() {
223
236
  this.$refs.baseDropdown.open();
@@ -1,3 +1,4 @@
1
+ import { nextTick } from 'vue';
1
2
  import GlDuoUserFeedback from '../../../user_feedback/user_feedback';
2
3
  import { SafeHtmlDirective } from '../../../../../../directives/safe_html/safe_html';
3
4
  import { MESSAGE_MODEL_ROLES } from '../../constants';
@@ -60,7 +61,7 @@ var script = {
60
61
  if (!chunkId) {
61
62
  this.messageChunks = [];
62
63
  this.messageContent = this.content;
63
- this.renderGFM(this.$refs.content);
64
+ this.hydrateContentWithGFM();
64
65
  } else {
65
66
  this.messageChunks[chunkId] = content;
66
67
  this.messageContent = this.renderMarkdown(concatIndicesUntilEmpty(this.messageChunks));
@@ -81,7 +82,13 @@ var script = {
81
82
  if (this.message.chunkId) {
82
83
  this.messageChunks[this.message.chunkId] = this.message.content;
83
84
  }
84
- this.renderGFM(this.$refs.content);
85
+ this.hydrateContentWithGFM();
86
+ },
87
+ methods: {
88
+ async hydrateContentWithGFM() {
89
+ await nextTick();
90
+ this.renderGFM(this.$refs.content);
91
+ }
85
92
  }
86
93
  };
87
94
 
@@ -80,5 +80,12 @@ const MOCK_USER_PROMPT_MESSAGE = {
80
80
  timestamp: '2021-04-21T12:00:00.000Z',
81
81
  extras: null
82
82
  };
83
+ const renderMarkdown = content => content;
84
+ const renderGFM = el => {
85
+ const codeBlock = el.querySelectorAll('.markdown-code-block');
86
+ codeBlock.forEach(block => {
87
+ block === null || block === void 0 ? void 0 : block.classList.add('gl-bg-purple-50', 'gl-p-3', 'gl-mb-3');
88
+ });
89
+ };
83
90
 
84
- export { MOCK_CHUNK_RESPONSE_MESSAGE, MOCK_RESPONSE_MESSAGE, MOCK_RESPONSE_MESSAGE_FOR_STREAMING, MOCK_USER_PROMPT_MESSAGE, generateMockResponseChunks };
91
+ export { MOCK_CHUNK_RESPONSE_MESSAGE, MOCK_RESPONSE_MESSAGE, MOCK_RESPONSE_MESSAGE_FOR_STREAMING, MOCK_USER_PROMPT_MESSAGE, generateMockResponseChunks, renderGFM, renderMarkdown };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 18 Oct 2023 11:15:35 GMT
3
+ * Generated on Fri, 20 Oct 2023 18:59:55 GMT
4
4
  */
5
5
 
6
6
  :root {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 18 Oct 2023 11:15:35 GMT
3
+ * Generated on Fri, 20 Oct 2023 18:59:55 GMT
4
4
  */
5
5
 
6
6
  :root.gl-dark {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 18 Oct 2023 11:15:35 GMT
3
+ * Generated on Fri, 20 Oct 2023 18:59:55 GMT
4
4
  */
5
5
 
6
6
  export const BLACK = "#fff";
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Do not edit directly
3
- * Generated on Wed, 18 Oct 2023 11:15:35 GMT
3
+ * Generated on Fri, 20 Oct 2023 18:59:55 GMT
4
4
  */
5
5
 
6
6
  export const BLACK = "#000";
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Wed, 18 Oct 2023 11:15:35 GMT
3
+ // Generated on Fri, 20 Oct 2023 18:59:55 GMT
4
4
 
5
5
  $red-950: #fff4f3;
6
6
  $red-900: #fcf1ef;
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Do not edit directly
3
- // Generated on Wed, 18 Oct 2023 11:15:35 GMT
3
+ // Generated on Fri, 20 Oct 2023 18:59:55 GMT
4
4
 
5
5
  $gl-line-height-52: 3.25rem;
6
6
  $gl-line-height-44: 2.75rem;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "66.34.0",
3
+ "version": "66.35.1",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -1,5 +1,6 @@
1
1
  import { mount } from '@vue/test-utils';
2
2
  import { autoUpdate } from '@floating-ui/dom';
3
+ import { nextTick } from 'vue';
3
4
  import * as utils from '../../../../utils/utils';
4
5
  import GlBaseDropdown from '../base_dropdown/base_dropdown.vue';
5
6
  import {
@@ -43,6 +44,7 @@ describe('GlDisclosureDropdown', () => {
43
44
  const findDisclosureItems = (root = wrapper) => root.findAllComponents(GlDisclosureDropdownItem);
44
45
  const findDisclosureGroups = () => wrapper.findAllComponents(GlDisclosureDropdownGroup);
45
46
  const findListItem = (index) => findDisclosureItems().at(index).findComponent(ITEM_SELECTOR);
47
+ const findDropdownMenu = () => wrapper.find("[data-testid='base-dropdown-menu']");
46
48
 
47
49
  jest.spyOn(utils, 'filterVisible').mockImplementation((items) => items);
48
50
 
@@ -387,4 +389,17 @@ describe('GlDisclosureDropdown', () => {
387
389
  }
388
390
  );
389
391
  });
392
+ describe('startOpened', () => {
393
+ it('should open dropdown on render when startOpened is true', async () => {
394
+ buildWrapper({ items: mockItems, startOpened: true });
395
+ await nextTick();
396
+ expect(findDropdownMenu().classes()).toContain('gl-display-block!');
397
+ });
398
+
399
+ it('should not open dropdown on render as default', async () => {
400
+ buildWrapper({ items: mockItems });
401
+ await nextTick();
402
+ expect(findDropdownMenu().classes()).not.toContain('gl-display-block!');
403
+ });
404
+ });
390
405
  });
@@ -44,17 +44,13 @@ const makeBindings = (overrides = {}) =>
44
44
  ':fluid-width': 'fluidWidth',
45
45
  ':auto-close': 'autoClose',
46
46
  ':positioning-strategy': 'positioningStrategy',
47
+ ':start-opened': 'startOpened',
48
+
47
49
  ...overrides,
48
50
  })
49
51
  .map(([key, value]) => `${key}="${value}"`)
50
52
  .join('\n');
51
53
 
52
- function openDisclosure(component) {
53
- component.$nextTick(() => {
54
- component.$refs.disclosure.open();
55
- });
56
- }
57
-
58
54
  const template = (content = '', { bindingOverrides = {}, after = '' } = {}) => `
59
55
  <div>
60
56
  <gl-disclosure-dropdown
@@ -75,11 +71,6 @@ export const Default = (args, { argTypes }) => ({
75
71
  GlDisclosureDropdown,
76
72
  GlTooltip,
77
73
  },
78
- mounted() {
79
- if (this.startOpened) {
80
- openDisclosure(this);
81
- }
82
- },
83
74
  template: `
84
75
  <div>
85
76
  ${template()}
@@ -105,11 +96,6 @@ export const CustomListItem = (args, { argTypes }) => ({
105
96
  GlDisclosureDropdown,
106
97
  GlBadge,
107
98
  },
108
- mounted() {
109
- if (this.startOpened) {
110
- openDisclosure(this);
111
- }
112
- },
113
99
  template: template(
114
100
  `
115
101
  <template #list-item="{ item }">
@@ -147,11 +133,6 @@ const makeGroupedExample = (changes) => {
147
133
  GlModal,
148
134
  GlIcon,
149
135
  },
150
- mounted() {
151
- if (this.startOpened) {
152
- openDisclosure(this);
153
- }
154
- },
155
136
  ...changes,
156
137
  });
157
138
 
@@ -177,11 +158,6 @@ export const CustomGroupsAndItems = (args, { argTypes }) => ({
177
158
  GlDisclosureDropdown,
178
159
  GlBadge,
179
160
  },
180
- mounted() {
181
- if (this.startOpened) {
182
- openDisclosure(this);
183
- }
184
- },
185
161
  methods: {
186
162
  getTotalMrs(items) {
187
163
  return items.reduce((acc, item) => acc + item.count, 0);
@@ -312,11 +288,6 @@ export const MiscellaneousContent = (args, { argTypes }) => ({
312
288
  components: {
313
289
  GlDisclosureDropdown,
314
290
  },
315
- mounted() {
316
- if (this.startOpened) {
317
- openDisclosure(this);
318
- }
319
- },
320
291
  template: template(
321
292
  `
322
293
  <div class="gl-p-3">A disclosure dropdown is a button that toggles a panel containing a list of items and/or links.</div>
@@ -219,6 +219,14 @@ export default {
219
219
  default: POSITION_ABSOLUTE,
220
220
  validator: (strategy) => [POSITION_ABSOLUTE, POSITION_FIXED].includes(strategy),
221
221
  },
222
+ /**
223
+ * Opens dropdown on render
224
+ */
225
+ startOpened: {
226
+ type: Boolean,
227
+ required: false,
228
+ default: false,
229
+ },
222
230
  },
223
231
  data() {
224
232
  return {
@@ -237,6 +245,11 @@ export default {
237
245
  return Boolean(this.$scopedSlots.toggle);
238
246
  },
239
247
  },
248
+ mounted() {
249
+ if (this.startOpened) {
250
+ this.open();
251
+ }
252
+ },
240
253
  methods: {
241
254
  open() {
242
255
  this.$refs.baseDropdown.open();
@@ -1,10 +1,13 @@
1
- import { MOCK_USER_PROMPT_MESSAGE, MOCK_RESPONSE_MESSAGE } from '../../mock_data';
1
+ import {
2
+ MOCK_USER_PROMPT_MESSAGE,
3
+ MOCK_RESPONSE_MESSAGE,
4
+ renderGFM,
5
+ renderMarkdown,
6
+ } from '../../mock_data';
2
7
  import GlDuoChatConversation from './duo_chat_conversation.vue';
3
8
  import readme from './duo_chat_conversation.md';
4
9
 
5
10
  const defaultValue = (prop) => GlDuoChatConversation.props[prop].default;
6
- const renderMarkdown = (content) => content;
7
- const renderGFM = () => {};
8
11
 
9
12
  const generateProps = ({ messages = [], showDelimiter = defaultValue('showDelimiter') } = {}) => ({
10
13
  messages,
@@ -109,8 +109,9 @@ describe('DuoChatMessage', () => {
109
109
  });
110
110
 
111
111
  describe('message output', () => {
112
- it('hydrates the message with GLFM when mounting the component', () => {
112
+ it('hydrates the message with GLFM when mounting the component', async () => {
113
113
  createComponent();
114
+ await nextTick();
114
115
  expect(renderGFM).toHaveBeenCalled();
115
116
  });
116
117
 
@@ -327,6 +328,7 @@ describe('DuoChatMessage', () => {
327
328
  message: chunk1,
328
329
  },
329
330
  });
331
+ await nextTick();
330
332
  renderGFM.mockClear();
331
333
  expect(renderGFM).not.toHaveBeenCalled();
332
334
 
@@ -1,10 +1,12 @@
1
- import { MOCK_RESPONSE_MESSAGE, MOCK_USER_PROMPT_MESSAGE } from '../../mock_data';
1
+ import {
2
+ MOCK_RESPONSE_MESSAGE,
3
+ MOCK_USER_PROMPT_MESSAGE,
4
+ renderGFM,
5
+ renderMarkdown,
6
+ } from '../../mock_data';
2
7
  import GlDuoChatMessage from './duo_chat_message.vue';
3
8
  import readme from './duo_chat_message.md';
4
9
 
5
- const renderMarkdown = (content) => content;
6
- const renderGFM = () => {};
7
-
8
10
  const generateProps = ({ message = MOCK_RESPONSE_MESSAGE } = {}) => ({
9
11
  message,
10
12
  });
@@ -1,4 +1,5 @@
1
1
  <script>
2
+ import { nextTick } from 'vue';
2
3
  import GlDuoUserFeedback from '../../../user_feedback/user_feedback.vue';
3
4
  import { SafeHtmlDirective as SafeHtml } from '../../../../../../directives/safe_html/safe_html';
4
5
  import { MESSAGE_MODEL_ROLES } from '../../constants';
@@ -60,7 +61,7 @@ export default {
60
61
  if (!chunkId) {
61
62
  this.messageChunks = [];
62
63
  this.messageContent = this.content;
63
- this.renderGFM(this.$refs.content);
64
+ this.hydrateContentWithGFM();
64
65
  } else {
65
66
  this.messageChunks[chunkId] = content;
66
67
  this.messageContent = this.renderMarkdown(concatIndicesUntilEmpty(this.messageChunks));
@@ -81,7 +82,13 @@ export default {
81
82
  if (this.message.chunkId) {
82
83
  this.messageChunks[this.message.chunkId] = this.message.content;
83
84
  }
84
- this.renderGFM(this.$refs.content);
85
+ this.hydrateContentWithGFM();
86
+ },
87
+ methods: {
88
+ async hydrateContentWithGFM() {
89
+ await nextTick();
90
+ this.renderGFM(this.$refs.content);
91
+ },
85
92
  },
86
93
  };
87
94
  </script>
@@ -1,5 +1,5 @@
1
1
  .duo-chat {
2
- z-index: 999;
2
+ @include gl-z-index-999;
3
3
 
4
4
  .message-enter-active,
5
5
  .message-leave-active {
@@ -8,11 +8,10 @@ import {
8
8
  MOCK_RESPONSE_MESSAGE,
9
9
  MOCK_USER_PROMPT_MESSAGE,
10
10
  generateMockResponseChunks,
11
+ renderGFM,
12
+ renderMarkdown,
11
13
  } from './mock_data';
12
14
 
13
- const renderMarkdown = (content) => content;
14
- const renderGFM = () => {};
15
-
16
15
  const defaultValue = (prop) =>
17
16
  typeof GlDuoChat.props[prop].default === 'function'
18
17
  ? GlDuoChat.props[prop].default()
@@ -94,3 +94,11 @@ export const MOCK_USER_PROMPT_MESSAGE = {
94
94
  timestamp: '2021-04-21T12:00:00.000Z',
95
95
  extras: null,
96
96
  };
97
+
98
+ export const renderMarkdown = (content) => content;
99
+ export const renderGFM = (el) => {
100
+ const codeBlock = el.querySelectorAll('.markdown-code-block');
101
+ codeBlock.forEach((block) => {
102
+ block?.classList.add('gl-bg-purple-50', 'gl-p-3', 'gl-mb-3');
103
+ });
104
+ };