@gitlab/ui 128.5.0 → 128.6.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.
@@ -1,5 +1,3 @@
1
- import curry from 'lodash/fp/curry';
2
-
3
1
  const getRepeatingValue = index => {
4
2
  const values = [100, 500, 400, 200, 100, 800, 400, 500, 600, 300, 800, 900, 110, 700, 400, 300, 500, 300, 400, 600, 700];
5
3
  return index < values.length ? values[index] : values[index % values.length];
@@ -8,14 +6,14 @@ const generateTimeSeries = () => new Array(100).fill(0).map((el, i) => [new Date
8
6
 
9
7
  // takes an element and a list and `intersperses' that element between the elements of the list.
10
8
  // (',' ['a', 'b', 'c']) -> ['a', ',', 'b', ',', 'c']
11
- const intersperse = curry((separator, items) => {
9
+ const intersperse = (separator, items) => {
12
10
  const [head, ...rest] = items;
13
11
  const separatorFactory = typeof separator === 'function' ? separator : () => separator;
14
12
  return [head, ...rest.flatMap(item => [separatorFactory(), item], rest)];
15
- });
13
+ };
16
14
 
17
15
  // inserts a value at a given index into an array
18
16
  // (1, 2, [1, 3, 4]) -> [1, 2, 3, 4]
19
- const insert = curry((index, newItem, items) => [...items.slice(0, index), newItem, ...items.slice(index)]);
17
+ const insert = (index, newItem, items) => [...items.slice(0, index), newItem, ...items.slice(index)];
20
18
 
21
19
  export { generateTimeSeries, insert, intersperse };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "128.5.0",
3
+ "version": "128.6.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -69,7 +69,7 @@
69
69
  "echarts": "^5.6.0",
70
70
  "gridstack": "^12.4.2",
71
71
  "iframe-resizer": "^4.4.5",
72
- "lodash": "^4.17.21",
72
+ "lodash": "^4.17.23",
73
73
  "popper.js": "^1.16.1",
74
74
  "portal-vue": "2.1.7",
75
75
  "vue-functional-data-merge": "^3.1.0",
@@ -237,9 +237,6 @@ export default {
237
237
  hasIconOnly() {
238
238
  return isSlotEmpty(this, 'default') && this.hasIcon && this.count == null;
239
239
  },
240
- isButtonDisabled() {
241
- return this.disabled;
242
- },
243
240
  isButtonAriaDisabled() {
244
241
  return this.isButton && this.loading;
245
242
  },
@@ -300,7 +297,7 @@ export default {
300
297
  // Type only used for "real" buttons
301
298
  type: this.isButton ? this.type : null,
302
299
  // Disabled only set on "real" buttons
303
- disabled: this.isButton ? this.isButtonDisabled : null,
300
+ disabled: this.isButton ? this.disabled : null,
304
301
  // We add a role of button when the tag is not a link or button or when link has `href` of `#`
305
302
  role: this.isNonStandardTag || this.isHashLink ? 'button' : this.$attrs?.role,
306
303
  // We set the `aria-disabled` state for non-standard tags
@@ -196,6 +196,14 @@ export default {
196
196
  required: false,
197
197
  default: false,
198
198
  },
199
+ /**
200
+ * Allows the dropdown panel to match the width of the trigger element
201
+ */
202
+ panelMatchTriggerWidth: {
203
+ type: Boolean,
204
+ required: false,
205
+ default: false,
206
+ },
199
207
  /**
200
208
  * Strategy to be applied by computePosition. If this is set to fixed, the dropdown's position
201
209
  * needs to be set to fixed in CSS as well.
@@ -362,7 +370,8 @@ export default {
362
370
  panelClasses() {
363
371
  return {
364
372
  '!gl-block': this.visible,
365
- [FIXED_WIDTH_CLASS]: !this.fluidWidth,
373
+ [FIXED_WIDTH_CLASS]: !this.fluidWidth && !this.panelMatchTriggerWidth,
374
+ 'gl-new-dropdown-panel-fluid-width': this.fluidWidth && !this.panelMatchTriggerWidth,
366
375
  'gl-fixed': this.openedYet && this.isFixed,
367
376
  'gl-absolute': this.openedYet && !this.isFixed,
368
377
  };
@@ -397,6 +406,11 @@ export default {
397
406
  maxWidth: `${Math.max(0, availableWidth)}px`,
398
407
  }
399
408
  : {};
409
+ const triggerWidth = this.panelMatchTriggerWidth
410
+ ? {
411
+ minWidth: `${this.toggleElement.getBoundingClientRect().width}px`,
412
+ }
413
+ : {};
400
414
 
401
415
  Object.assign(
402
416
  contentsEl.style,
@@ -404,6 +418,7 @@ export default {
404
418
  maxHeight: `${Math.max(contentsAvailableHeight, 0)}px`,
405
419
  },
406
420
  maxWidth,
421
+ triggerWidth,
407
422
  );
408
423
  },
409
424
  }),
@@ -112,9 +112,12 @@
112
112
  @apply gl-drop-shadow-md;
113
113
  top: 0;
114
114
  left: 0;
115
+ z-index: 1000;
116
+ }
117
+
118
+ .gl-new-dropdown-panel-fluid-width {
115
119
  min-width: $gl-new-dropdown-min-width;
116
120
  max-width: $gl-new-dropdown-max-width;
117
- z-index: 1000;
118
121
  }
119
122
 
120
123
  .gl-new-dropdown-inner {
@@ -346,6 +346,14 @@ export default {
346
346
  required: false,
347
347
  default: false,
348
348
  },
349
+ /**
350
+ * Allows the dropdown panel to match the width of the trigger element
351
+ */
352
+ panelMatchTriggerWidth: {
353
+ type: Boolean,
354
+ required: false,
355
+ default: false,
356
+ },
349
357
  /**
350
358
  * Strategy to be applied by computePosition. If the dropdown's container is too short for it to
351
359
  * fit in, setting this to fixed will let it position itself above its container.
@@ -980,6 +988,7 @@ export default {
980
988
  :placement="placement"
981
989
  :offset="dropdownOffset"
982
990
  :fluid-width="fluidWidth"
991
+ :panel-match-trigger-width="panelMatchTriggerWidth"
983
992
  :positioning-strategy="positioningStrategy"
984
993
  @[$options.events.GL_DROPDOWN_FOCUS_CONTENT]="onFocusContent"
985
994
  @[$options.events.GL_DROPDOWN_SHOWN]="onShow"
@@ -1,14 +1,10 @@
1
1
  <script>
2
2
  import Vue from 'vue';
3
- import compose from 'lodash/fp/compose';
4
- import fill from 'lodash/fp/fill';
5
- import filter from 'lodash/fp/filter';
6
3
  import { intersperse, insert } from '../../../utils/data_utils';
7
4
  import { isVnodeEmpty } from '../../../utils/is_slot_empty';
8
5
 
9
- const filterEmptyNodesVue2 = filter(
10
- (vNode) => typeof vNode.tag === 'string' || vNode.text.trim() !== '',
11
- );
6
+ const filterEmptyNodesVue2 = (vNodes) =>
7
+ vNodes.filter((vNode) => typeof vNode.tag === 'string' || vNode.text.trim() !== '');
12
8
 
13
9
  const { Fragment } = Vue;
14
10
  const filterEmptyNodesVue3 = (vNode) => {
@@ -25,20 +21,23 @@ const filterEmptyNodesVue3 = (vNode) => {
25
21
  };
26
22
 
27
23
  const filterEmptyNodes = Vue.version.startsWith('3') ? filterEmptyNodesVue3 : filterEmptyNodesVue2;
28
- const insertAfterSecondLastItem = insert(-1);
29
- const replaceSecondLastItem = fill(-2, -1);
30
24
 
31
25
  // handles the addition of the lastSeparator in these two cases:
32
26
  // item1, item2, item3 => item1, item2, and item3
33
27
  // item1, item2 => item1 and item2
34
- const addLastSeparator = (lastSeparator) => (items) => {
28
+ const addLastSeparator = (lastSeparator, items) => {
35
29
  if (!lastSeparator) {
36
30
  return items;
37
31
  }
38
32
 
39
- return items.length > 3
40
- ? insertAfterSecondLastItem(lastSeparator, items)
41
- : replaceSecondLastItem(lastSeparator, items);
33
+ if (items.length > 3) {
34
+ return insert(-1, lastSeparator, items);
35
+ }
36
+
37
+ // Replace the second-to-last item with lastSeparator
38
+ const result = [...items];
39
+ result[result.length - 2] = lastSeparator;
40
+ return result;
42
41
  };
43
42
 
44
43
  export default {
@@ -63,13 +62,12 @@ export default {
63
62
  data,
64
63
  } = context;
65
64
 
66
- const filterAndSeparate = compose(
67
- addLastSeparator(lastSeparator),
68
- intersperse(separator),
69
- filterEmptyNodes,
70
- );
65
+ const slotContent = slots().default || [];
66
+ const filtered = filterEmptyNodes(slotContent);
67
+ const separated = intersperse(separator, filtered);
68
+ const withLastSeparator = addLastSeparator(lastSeparator, separated);
71
69
 
72
- return createElement('span', data, filterAndSeparate(slots().default));
70
+ return createElement('span', data, withLastSeparator);
73
71
  },
74
72
  };
75
73
  </script>
@@ -1,5 +1,3 @@
1
- import curry from 'lodash/fp/curry';
2
-
3
1
  const getRepeatingValue = (index) => {
4
2
  const values = [
5
3
  100, 500, 400, 200, 100, 800, 400, 500, 600, 300, 800, 900, 110, 700, 400, 300, 500, 300, 400,
@@ -13,16 +11,16 @@ export const generateTimeSeries = () =>
13
11
 
14
12
  // takes an element and a list and `intersperses' that element between the elements of the list.
15
13
  // (',' ['a', 'b', 'c']) -> ['a', ',', 'b', ',', 'c']
16
- export const intersperse = curry((separator, items) => {
14
+ export const intersperse = (separator, items) => {
17
15
  const [head, ...rest] = items;
18
16
  const separatorFactory = typeof separator === 'function' ? separator : () => separator;
19
17
  return [head, ...rest.flatMap((item) => [separatorFactory(), item], rest)];
20
- });
18
+ };
21
19
 
22
20
  // inserts a value at a given index into an array
23
21
  // (1, 2, [1, 3, 4]) -> [1, 2, 3, 4]
24
- export const insert = curry((index, newItem, items) => [
22
+ export const insert = (index, newItem, items) => [
25
23
  ...items.slice(0, index),
26
24
  newItem,
27
25
  ...items.slice(index),
28
- ]);
26
+ ];