@gitlab/ui 48.2.0 → 48.3.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.
@@ -321,14 +321,14 @@ describe('Filtered search token segment', () => {
321
321
  );
322
322
  });
323
323
 
324
- describe.each([true, false])('and viewOnly is %s', (viewOnly) => {
325
- const readonly = viewOnly ? 'readonly' : undefined;
326
-
327
- it(`sets the input \`readonly\` atttribute to ${readonly}`, () => {
328
- createWrappedComponent({ value: 'test', active: true, viewOnly });
324
+ it('sets the input `readonly` atttribute when viewOnly is true', () => {
325
+ createWrappedComponent({ value: 'test', active: true, viewOnly: true });
326
+ expect(wrapper.find('input').attributes('readonly')).toBeDefined();
327
+ });
329
328
 
330
- expect(wrapper.find('input').attributes('readonly')).toBe(readonly);
331
- });
329
+ it('does not set the input `readonly` atttribute when viewOnly is false', () => {
330
+ createWrappedComponent({ value: 'test', active: true, viewOnly: false });
331
+ expect(wrapper.find('input').attributes('readonly')).toBeUndefined();
332
332
  });
333
333
  });
334
334
  });
@@ -6,6 +6,44 @@ import GlFilteredSearchSuggestion from './filtered_search_suggestion.vue';
6
6
  import GlFilteredSearchSuggestionList from './filtered_search_suggestion_list.vue';
7
7
  import { splitOnQuotes, wrapTokenInQuotes } from './filtered_search_utils';
8
8
 
9
+ // We need some helpers to ensure @vue/compat compatibility
10
+ // @vue/compat will render comment nodes for v-if and comments in HTML
11
+ // Also it makes use of fragments - both comments and nodes are Symbols.
12
+ // In Vue3 all of them (Comment, Fragment) are exposed as named exports on vue module
13
+ // However we want to maintain compatibility with Vue2, so taking this hacky approach
14
+ // relying on Symbol.toString()
15
+
16
+ // I'm keeping this directly here instead of helper to increase probability of
17
+ // fixing ASAP and because I don't want this helper to be reused
18
+ // FIXME: replace with Symbols when we will switch to Vue3
19
+
20
+ const isVue3Comment = (vnode) => vnode?.type?.toString?.() === 'Symbol(Comment)';
21
+ const isVue3Fragment = (vnode) => vnode?.type?.toString?.() === 'Symbol(Fragment)';
22
+
23
+ const isVNodeEmpty = (vnode) => {
24
+ if (isVue3Fragment(vnode)) {
25
+ // vnode.children might be an array or single node in edge cases
26
+ return Array.isArray(vnode.children)
27
+ ? vnode.children.every(isVNodeEmpty)
28
+ : isVNodeEmpty(vnode.children);
29
+ }
30
+
31
+ if (isVue3Comment(vnode)) {
32
+ return true;
33
+ }
34
+
35
+ return false;
36
+ };
37
+
38
+ const isSlotNotEmpty = (slot) => {
39
+ if (!slot) {
40
+ return false;
41
+ }
42
+
43
+ const vnodes = typeof slot === 'function' ? slot() : slot;
44
+ return !(Array.isArray(vnodes) ? vnodes.every(isVNodeEmpty) : isVNodeEmpty(vnodes));
45
+ };
46
+
9
47
  export default {
10
48
  name: 'GlFilteredSearchTokenSegment',
11
49
  components: {
@@ -124,7 +162,7 @@ export default {
124
162
 
125
163
  hasOptionsOrSuggestions() {
126
164
  // eslint-disable-next-line @gitlab/vue-prefer-dollar-scopedslots
127
- return this.options?.length || this.$slots.suggestions;
165
+ return this.options?.length || isSlotNotEmpty(this.$slots.suggestions);
128
166
  },
129
167
 
130
168
  defaultSuggestedValue() {
@@ -249,7 +249,6 @@ const makeGroupedExample = (changes) => {
249
249
  openListbox(this);
250
250
  }
251
251
  },
252
- template: template(''),
253
252
  ...changes,
254
253
  });
255
254
 
@@ -259,7 +258,53 @@ const makeGroupedExample = (changes) => {
259
258
  return story;
260
259
  };
261
260
 
262
- export const Groups = makeGroupedExample();
261
+ export const Groups = makeGroupedExample({
262
+ template: template('', {
263
+ bindingOverrides: {
264
+ ':toggle-text': 'customToggleText',
265
+ ':items': 'computedItems',
266
+ },
267
+ }),
268
+ data() {
269
+ return {
270
+ selected: ['v1.0'],
271
+ };
272
+ },
273
+ computed: {
274
+ customToggleText() {
275
+ return this.selected.length ? `${this.selected.length} refs selected` : 'Select refs';
276
+ },
277
+ computedItems() {
278
+ const isSelected = (option) => this.selected.includes(option.value);
279
+ const notSelected = (option) => !isSelected(option);
280
+
281
+ const selectedBranches = mockGroups[0].options.filter(isSelected);
282
+ const availableBranches = mockGroups[0].options.filter(notSelected);
283
+ const selectedTags = mockGroups[1].options.filter(isSelected);
284
+ const availableTags = mockGroups[1].options.filter(notSelected);
285
+
286
+ return [
287
+ {
288
+ text: 'Selected branches',
289
+ options: selectedBranches,
290
+ },
291
+ {
292
+ text: 'Selected tags',
293
+ options: selectedTags,
294
+ },
295
+ {
296
+ text: 'Branches',
297
+ options: availableBranches,
298
+ },
299
+ {
300
+ text: 'Tags',
301
+ options: availableTags,
302
+ },
303
+ ].filter((group) => group.options.length);
304
+ },
305
+ },
306
+ });
307
+ Groups.args = generateProps({ multiple: true });
263
308
 
264
309
  export const CustomGroupsAndItems = makeGroupedExample({
265
310
  template: template(`
@@ -30,13 +30,13 @@ Object {
30
30
  ],
31
31
  "emphasis": Object {
32
32
  "itemStyle": Object {
33
- "color": "rgba(87, 114, 255, 0.4)",
33
+ "color": "rgba(97, 122, 226, 0.4)",
34
34
  },
35
35
  },
36
36
  "itemStyle": Object {
37
- "borderColor": "#5772ff",
37
+ "borderColor": "#617ae2",
38
38
  "borderWidth": 1,
39
- "color": "rgba(87, 114, 255, 0.2)",
39
+ "color": "rgba(97, 122, 226, 0.2)",
40
40
  },
41
41
  "name": "Office",
42
42
  "stack": "chart",
@@ -46,13 +46,13 @@ Object {
46
46
  ],
47
47
  "emphasis": Object {
48
48
  "itemStyle": Object {
49
- "color": "rgba(87, 114, 255, 0.4)",
49
+ "color": "rgba(97, 122, 226, 0.4)",
50
50
  },
51
51
  },
52
52
  "itemStyle": Object {
53
- "borderColor": "#5772ff",
53
+ "borderColor": "#617ae2",
54
54
  "borderWidth": 1,
55
- "color": "rgba(87, 114, 255, 0.2)",
55
+ "color": "rgba(97, 122, 226, 0.2)",
56
56
  },
57
57
  "name": "Full",
58
58
  "stack": "stacked",
@@ -142,10 +142,10 @@ Object {
142
142
  ],
143
143
  ],
144
144
  "itemStyle": Object {
145
- "color": "#5772ff",
145
+ "color": "#617ae2",
146
146
  },
147
147
  "lineStyle": Object {
148
- "color": "#5772ff",
148
+ "color": "#617ae2",
149
149
  },
150
150
  "name": "Median line",
151
151
  "type": "line",
@@ -236,13 +236,13 @@ Object {
236
236
  ],
237
237
  "emphasis": Object {
238
238
  "itemStyle": Object {
239
- "color": "rgba(87, 114, 255, 0.4)",
239
+ "color": "rgba(97, 122, 226, 0.4)",
240
240
  },
241
241
  },
242
242
  "itemStyle": Object {
243
- "borderColor": "#5772ff",
243
+ "borderColor": "#617ae2",
244
244
  "borderWidth": 1,
245
- "color": "rgba(87, 114, 255, 0.2)",
245
+ "color": "rgba(97, 122, 226, 0.2)",
246
246
  },
247
247
  "name": "Full",
248
248
  "stack": "stacked",
@@ -267,13 +267,13 @@ Object {
267
267
  ],
268
268
  "emphasis": Object {
269
269
  "itemStyle": Object {
270
- "color": "rgba(178, 72, 0, 0.4)",
270
+ "color": "rgba(177, 79, 24, 0.4)",
271
271
  },
272
272
  },
273
273
  "itemStyle": Object {
274
- "borderColor": "#b24800",
274
+ "borderColor": "#b14f18",
275
275
  "borderWidth": 1,
276
- "color": "rgba(178, 72, 0, 0.2)",
276
+ "color": "rgba(177, 79, 24, 0.2)",
277
277
  },
278
278
  "name": "Secondary 1",
279
279
  "stack": "tiled",
@@ -286,13 +286,13 @@ Object {
286
286
  ],
287
287
  "emphasis": Object {
288
288
  "itemStyle": Object {
289
- "color": "rgba(87, 114, 255, 0.4)",
289
+ "color": "rgba(97, 122, 226, 0.4)",
290
290
  },
291
291
  },
292
292
  "itemStyle": Object {
293
- "borderColor": "#5772ff",
293
+ "borderColor": "#617ae2",
294
294
  "borderWidth": 1,
295
- "color": "rgba(87, 114, 255, 0.2)",
295
+ "color": "rgba(97, 122, 226, 0.2)",
296
296
  },
297
297
  "name": "Fun 1",
298
298
  "stack": Array [
@@ -330,13 +330,13 @@ Object {
330
330
  ],
331
331
  "emphasis": Object {
332
332
  "itemStyle": Object {
333
- "color": "rgba(178, 72, 0, 0.4)",
333
+ "color": "rgba(177, 79, 24, 0.4)",
334
334
  },
335
335
  },
336
336
  "itemStyle": Object {
337
- "borderColor": "#b24800",
337
+ "borderColor": "#b14f18",
338
338
  "borderWidth": 1,
339
- "color": "rgba(178, 72, 0, 0.2)",
339
+ "color": "rgba(177, 79, 24, 0.2)",
340
340
  },
341
341
  "name": "Fun 2",
342
342
  "stack": Array [
@@ -374,13 +374,13 @@ Object {
374
374
  ],
375
375
  "emphasis": Object {
376
376
  "itemStyle": Object {
377
- "color": "rgba(0, 148, 182, 0.4)",
377
+ "color": "rgba(0, 144, 177, 0.4)",
378
378
  },
379
379
  },
380
380
  "itemStyle": Object {
381
- "borderColor": "#0094b6",
381
+ "borderColor": "#0090b1",
382
382
  "borderWidth": 1,
383
- "color": "rgba(0, 148, 182, 0.2)",
383
+ "color": "rgba(0, 144, 177, 0.2)",
384
384
  },
385
385
  "name": "Fun 3",
386
386
  "stack": Array [
@@ -540,10 +540,10 @@ Object {
540
540
  28,
541
541
  ],
542
542
  "itemStyle": Object {
543
- "color": "#5772ff",
543
+ "color": "#617ae2",
544
544
  },
545
545
  "lineStyle": Object {
546
- "color": "#5772ff",
546
+ "color": "#617ae2",
547
547
  },
548
548
  "name": "Stacked median line",
549
549
  "type": "line",
@@ -647,13 +647,13 @@ Object {
647
647
  ],
648
648
  "emphasis": Object {
649
649
  "itemStyle": Object {
650
- "color": "rgba(87, 114, 255, 0.4)",
650
+ "color": "rgba(97, 122, 226, 0.4)",
651
651
  },
652
652
  },
653
653
  "itemStyle": Object {
654
- "borderColor": "#5772ff",
654
+ "borderColor": "#617ae2",
655
655
  "borderWidth": 1,
656
- "color": "rgba(87, 114, 255, 0.2)",
656
+ "color": "rgba(97, 122, 226, 0.2)",
657
657
  },
658
658
  "name": "Fun 1",
659
659
  "stack": Array [
@@ -691,13 +691,13 @@ Object {
691
691
  ],
692
692
  "emphasis": Object {
693
693
  "itemStyle": Object {
694
- "color": "rgba(178, 72, 0, 0.4)",
694
+ "color": "rgba(177, 79, 24, 0.4)",
695
695
  },
696
696
  },
697
697
  "itemStyle": Object {
698
- "borderColor": "#b24800",
698
+ "borderColor": "#b14f18",
699
699
  "borderWidth": 1,
700
- "color": "rgba(178, 72, 0, 0.2)",
700
+ "color": "rgba(177, 79, 24, 0.2)",
701
701
  },
702
702
  "name": "Fun 2",
703
703
  "stack": Array [
@@ -735,13 +735,13 @@ Object {
735
735
  ],
736
736
  "emphasis": Object {
737
737
  "itemStyle": Object {
738
- "color": "rgba(0, 148, 182, 0.4)",
738
+ "color": "rgba(0, 144, 177, 0.4)",
739
739
  },
740
740
  },
741
741
  "itemStyle": Object {
742
- "borderColor": "#0094b6",
742
+ "borderColor": "#0090b1",
743
743
  "borderWidth": 1,
744
- "color": "rgba(0, 148, 182, 0.2)",
744
+ "color": "rgba(0, 144, 177, 0.2)",
745
745
  },
746
746
  "name": "Fun 3",
747
747
  "stack": Array [
@@ -823,13 +823,13 @@ Object {
823
823
  ],
824
824
  "emphasis": Object {
825
825
  "itemStyle": Object {
826
- "color": "rgba(149, 9, 67, 0.4)",
826
+ "color": "rgba(124, 33, 79, 0.4)",
827
827
  },
828
828
  },
829
829
  "itemStyle": Object {
830
- "borderColor": "#950943",
830
+ "borderColor": "#7c214f",
831
831
  "borderWidth": 1,
832
- "color": "rgba(149, 9, 67, 0.2)",
832
+ "color": "rgba(124, 33, 79, 0.2)",
833
833
  },
834
834
  "name": "Secondary 1",
835
835
  "stack": "tiled",
@@ -37,7 +37,7 @@ const startListening = () => {
37
37
  return;
38
38
  }
39
39
 
40
- document.addEventListener('click', globalListener);
40
+ document.addEventListener('click', globalListener, { capture: true });
41
41
  listening = true;
42
42
  };
43
43
 
@@ -129,7 +129,9 @@ describe('outside directive', () => {
129
129
  it('attaches the global listener on first initialisation', async () => {
130
130
  await createComponent();
131
131
 
132
- expect(document.addEventListener.mock.calls).toEqual([['click', expect.any(Function)]]);
132
+ expect(document.addEventListener.mock.calls).toEqual([
133
+ ['click', expect.any(Function), { capture: true }],
134
+ ]);
133
135
  });
134
136
 
135
137
  it('detaches the global listener when last binding is removed', async () => {
@@ -150,7 +152,9 @@ describe('outside directive', () => {
150
152
  `,
151
153
  });
152
154
 
153
- expect(document.addEventListener.mock.calls).toEqual([['click', expect.any(Function)]]);
155
+ expect(document.addEventListener.mock.calls).toEqual([
156
+ ['click', expect.any(Function), { capture: true }],
157
+ ]);
154
158
  });
155
159
 
156
160
  it('only unbinds once there are no instances', async () => {
@@ -227,64 +227,64 @@ $theme-light-red-950: #5c1105 !default;
227
227
  // Data visualization color palette
228
228
 
229
229
  $data-viz-green-50: #ddfab7;
230
- $data-viz-green-100: #c9f097;
231
- $data-viz-green-200: #b0de73;
230
+ $data-viz-green-100: #c6ed94;
231
+ $data-viz-green-200: #b0d97b;
232
232
  $data-viz-green-300: #94c25e;
233
- $data-viz-green-400: #83ab4a;
234
- $data-viz-green-500: #608b2f;
235
- $data-viz-green-600: #487900;
233
+ $data-viz-green-400: #81ac41;
234
+ $data-viz-green-500: #619025;
235
+ $data-viz-green-600: #4e7f0e;
236
236
  $data-viz-green-700: #366800;
237
237
  $data-viz-green-800: #275600;
238
238
  $data-viz-green-900: #1a4500;
239
- $data-viz-green-950: #0f3300;
240
-
241
- $data-viz-aqua-50: #b8fff2;
242
- $data-viz-aqua-100: #93fae7;
243
- $data-viz-aqua-200: #5eebdf;
244
- $data-viz-aqua-300: #25d2d2;
245
- $data-viz-aqua-400: #0bb6c6;
246
- $data-viz-aqua-500: #0094b6;
247
- $data-viz-aqua-600: #0080a1;
248
- $data-viz-aqua-700: #006887;
249
- $data-viz-aqua-800: #004d67;
250
- $data-viz-aqua-900: #003f57;
251
- $data-viz-aqua-950: #00293d;
239
+ $data-viz-green-950: #133a03;
240
+
241
+ $data-viz-aqua-50: #b5fefd;
242
+ $data-viz-aqua-100: #93f2ef;
243
+ $data-viz-aqua-200: #5edee3;
244
+ $data-viz-aqua-300: #32c5d2;
245
+ $data-viz-aqua-400: #00acc4;
246
+ $data-viz-aqua-500: #0090b1;
247
+ $data-viz-aqua-600: #007b9b;
248
+ $data-viz-aqua-700: #006381;
249
+ $data-viz-aqua-800: #00516c;
250
+ $data-viz-aqua-900: #004059;
251
+ $data-viz-aqua-950: #00344b;
252
252
 
253
253
  $data-viz-blue-50: #e9ebff;
254
- $data-viz-blue-100: #d4dcfa;
254
+ $data-viz-blue-100: #d2dcff;
255
255
  $data-viz-blue-200: #b7c6ff;
256
256
  $data-viz-blue-300: #97acff;
257
- $data-viz-blue-400: #748eff;
258
- $data-viz-blue-500: #5772ff;
259
- $data-viz-blue-600: #445cf2;
260
- $data-viz-blue-700: #3547de;
261
- $data-viz-blue-800: #232fcf;
262
- $data-viz-blue-900: #1e23a8;
263
- $data-viz-blue-950: #11118a;
257
+ $data-viz-blue-400: #7992f5;
258
+ $data-viz-blue-500: #617ae2;
259
+ $data-viz-blue-600: #4e65cd;
260
+ $data-viz-blue-700: #3f51ae;
261
+ $data-viz-blue-800: #374291;
262
+ $data-viz-blue-900: #303470;
263
+ $data-viz-blue-950: #2a2b59;
264
264
 
265
265
  $data-viz-magenta-50: #ffe3eb;
266
- $data-viz-magenta-100: #ffc9d9;
266
+ $data-viz-magenta-100: #ffccdb;
267
267
  $data-viz-magenta-200: #fcacc5;
268
- $data-viz-magenta-300: #ff85af;
269
- $data-viz-magenta-400: #f2639a;
270
- $data-viz-magenta-500: #d84280;
271
- $data-viz-magenta-600: #c52c6b;
272
- $data-viz-magenta-700: #b31756;
273
- $data-viz-magenta-800: #950943;
274
- $data-viz-magenta-900: #7a0033;
275
- $data-viz-magenta-950: #570028;
268
+ $data-viz-magenta-300: #f88aaf;
269
+ $data-viz-magenta-400: #e86e9a;
270
+ $data-viz-magenta-500: #cf4d81;
271
+ $data-viz-magenta-600: #b93d71;
272
+ $data-viz-magenta-700: #9a2e5d;
273
+ $data-viz-magenta-800: #7c214f;
274
+ $data-viz-magenta-900: #661e3a;
275
+ $data-viz-magenta-950: #541d31;
276
276
 
277
277
  $data-viz-orange-50: #fae8d1;
278
- $data-viz-orange-100: #f7d8b5;
279
- $data-viz-orange-200: #f3c291;
280
- $data-viz-orange-300: #eb9a5c;
281
- $data-viz-orange-400: #e17223;
282
- $data-viz-orange-500: #d14e00;
283
- $data-viz-orange-600: #b24800;
284
- $data-viz-orange-700: #944100;
278
+ $data-viz-orange-100: #f5d6b3;
279
+ $data-viz-orange-200: #eebd8c;
280
+ $data-viz-orange-300: #e99b60;
281
+ $data-viz-orange-400: #e07e41;
282
+ $data-viz-orange-500: #c95d2e;
283
+ $data-viz-orange-600: #b14f18;
284
+ $data-viz-orange-700: #92430a;
285
285
  $data-viz-orange-800: #6f3500;
286
- $data-viz-orange-900: #5c2b00;
287
- $data-viz-orange-950: #421e00;
286
+ $data-viz-orange-900: #5e2f05;
287
+ $data-viz-orange-950: #4b2707;
288
288
 
289
289
  $darken-normal-factor: 7%;
290
290
  $darken-dark-factor: 10%;