@gitlab/ui 60.0.0 → 60.2.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 (24) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/components/base/banner/banner.js +1 -1
  3. package/dist/components/base/broadcast_message/broadcast_message.js +1 -1
  4. package/dist/components/base/new_dropdowns/base_dropdown/base_dropdown.js +7 -1
  5. package/dist/components/base/new_dropdowns/disclosure/disclosure_dropdown.js +10 -1
  6. package/dist/components/base/new_dropdowns/listbox/listbox.js +10 -1
  7. package/dist/index.css +1 -1
  8. package/dist/index.css.map +1 -1
  9. package/package.json +2 -2
  10. package/scss_to_js/scss_variables.js +2 -1
  11. package/scss_to_js/scss_variables.json +8 -3
  12. package/src/components/base/banner/banner.vue +1 -1
  13. package/src/components/base/broadcast_message/broadcast_message.vue +1 -1
  14. package/src/components/base/new_dropdowns/base_dropdown/base_dropdown.spec.js +9 -0
  15. package/src/components/base/new_dropdowns/base_dropdown/base_dropdown.vue +6 -0
  16. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.md +8 -0
  17. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.spec.js +7 -0
  18. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.vue +10 -0
  19. package/src/components/base/new_dropdowns/dropdown.scss +2 -1
  20. package/src/components/base/new_dropdowns/listbox/listbox.md +8 -0
  21. package/src/components/base/new_dropdowns/listbox/listbox.spec.js +7 -0
  22. package/src/components/base/new_dropdowns/listbox/listbox.stories.js +58 -1
  23. package/src/components/base/new_dropdowns/listbox/listbox.vue +10 -0
  24. package/src/scss/variables.scss +2 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "60.0.0",
3
+ "version": "60.2.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -90,7 +90,7 @@
90
90
  "@gitlab/eslint-plugin": "18.3.0",
91
91
  "@gitlab/fonts": "^1.2.0",
92
92
  "@gitlab/stylelint-config": "4.1.0",
93
- "@gitlab/svgs": "3.36.0",
93
+ "@gitlab/svgs": "3.38.0",
94
94
  "@rollup/plugin-commonjs": "^11.1.0",
95
95
  "@rollup/plugin-node-resolve": "^7.1.3",
96
96
  "@rollup/plugin-replace": "^2.3.2",
@@ -331,7 +331,8 @@ export const glIconRadio = ''
331
331
  export const defaultIconSize = '1rem'
332
332
  export const glIconSizes = '8 12 14 16 24 32 48 72'
333
333
  export const glDropdownWidth = '15rem'
334
- export const glNewDropdownWidth = '16rem'
334
+ export const glNewDropdownMinWidth = '15.5rem'
335
+ export const glNewDropdownMaxWidth = '28.5rem'
335
336
  export const glDropdownWidthNarrow = '10rem'
336
337
  export const glDropdownWidthWide = '25rem'
337
338
  export const glMaxDropdownMaxHeight = '19.5rem'
@@ -1766,9 +1766,14 @@
1766
1766
  "compiledValue": "15rem"
1767
1767
  },
1768
1768
  {
1769
- "name": "$gl-new-dropdown-width",
1770
- "value": "px-to-rem(256px)",
1771
- "compiledValue": "16rem"
1769
+ "name": "$gl-new-dropdown-min-width",
1770
+ "value": "px-to-rem(248px)",
1771
+ "compiledValue": "15.5rem"
1772
+ },
1773
+ {
1774
+ "name": "$gl-new-dropdown-max-width",
1775
+ "value": "px-to-rem(456px)",
1776
+ "compiledValue": "28.5rem"
1772
1777
  },
1773
1778
  {
1774
1779
  "name": "$gl-dropdown-width-narrow",
@@ -95,7 +95,7 @@ export default {
95
95
  body-class="gl-display-flex gl-p-0!"
96
96
  >
97
97
  <div v-if="svgPath" class="gl-banner-illustration">
98
- <img :src="svgPath" alt="" role="presentation" />
98
+ <img :src="svgPath" alt="" />
99
99
  </div>
100
100
  <div class="gl-banner-content">
101
101
  <h2 class="gl-banner-title">{{ title }}</h2>
@@ -74,7 +74,7 @@ export default {
74
74
  </script>
75
75
 
76
76
  <template>
77
- <div class="gl-broadcast-message" :class="`${theme} ${type}`" role="alert">
77
+ <div class="gl-broadcast-message" :class="`${theme} ${type}`">
78
78
  <div class="gl-broadcast-message-content">
79
79
  <div class="gl-broadcast-message-icon gl-line-height-normal">
80
80
  <gl-icon :name="iconName" />
@@ -80,6 +80,15 @@ describe('base dropdown', () => {
80
80
  );
81
81
  });
82
82
 
83
+ it('should pass custom options to popper.js, overriding built-in ones', async () => {
84
+ await buildWrapper({ placement: 'right', popperOptions: { placement: 'auto-start' } });
85
+ expect(mockCreatePopper).toHaveBeenCalledWith(
86
+ findDefaultDropdownToggle().element,
87
+ findDropdownMenu().element,
88
+ { ...POPPER_CONFIG, placement: 'auto-start' }
89
+ );
90
+ });
91
+
83
92
  it('should update popper instance when component is updated', async () => {
84
93
  await buildWrapper();
85
94
  await findDefaultDropdownToggle().trigger('click');
@@ -117,6 +117,11 @@ export default {
117
117
  required: false,
118
118
  default: null,
119
119
  },
120
+ popperOptions: {
121
+ type: Object,
122
+ required: false,
123
+ default: () => ({}),
124
+ },
120
125
  },
121
126
  data() {
122
127
  return {
@@ -192,6 +197,7 @@ export default {
192
197
  return {
193
198
  placement: dropdownPlacements[this.placement],
194
199
  ...POPPER_CONFIG,
200
+ ...this.popperOptions,
195
201
  };
196
202
  },
197
203
  },
@@ -122,3 +122,11 @@ To render custom group labels, use the `group-label` scoped slot:
122
122
 
123
123
  Besides default components, disclosure dropdown can render miscellaneous content inside it.
124
124
  In this case the user is responsible for handling all events and navigation inside the disclosure.
125
+
126
+ #### Dealing with long option texts
127
+
128
+ - Some options might have long non-wrapping text that would overflow the dropdown maximum width. In
129
+ such cases, it's recommended to override the `#list-item` slot and to truncate the option text using
130
+ `GlTruncate`.
131
+ - If the toggle text reflects the selected option text, it might be necessary to truncate
132
+ it too by overriding the `#toggle` slot.
@@ -37,6 +37,13 @@ describe('GlDisclosureDropdown', () => {
37
37
 
38
38
  jest.spyOn(utils, 'filterVisible').mockImplementation((items) => items);
39
39
 
40
+ it('passes custom popper.js options to the base dropdown', () => {
41
+ const popperOptions = { foo: 'bar' };
42
+ buildWrapper({ popperOptions });
43
+
44
+ expect(findBaseDropdown().props('popperOptions')).toEqual(popperOptions);
45
+ });
46
+
40
47
  describe('toggle text', () => {
41
48
  it('should pass toggle text to the base dropdown', () => {
42
49
  const toggleText = 'Merge requests';
@@ -164,6 +164,15 @@ export default {
164
164
  required: false,
165
165
  default: null,
166
166
  },
167
+ /**
168
+ * Options to be passed to the underlying Popper.js instance.
169
+ * Overrides built-in options.
170
+ */
171
+ popperOptions: {
172
+ type: Object,
173
+ required: false,
174
+ default: () => ({}),
175
+ },
167
176
  },
168
177
  data() {
169
178
  return {
@@ -278,6 +287,7 @@ export default {
278
287
  :loading="loading"
279
288
  :no-caret="noCaret"
280
289
  :placement="placement"
290
+ :popper-options="popperOptions"
281
291
  class="gl-disclosure-dropdown"
282
292
  @[$options.events.GL_DROPDOWN_SHOWN]="onShow"
283
293
  @[$options.events.GL_DROPDOWN_HIDDEN]="onHide"
@@ -20,7 +20,8 @@
20
20
  @include gl-border-gray-200;
21
21
  @include gl-rounded-lg;
22
22
  @include gl-shadow-md;
23
- width: $gl-new-dropdown-width;
23
+ min-width: $gl-new-dropdown-min-width;
24
+ max-width: $gl-new-dropdown-max-width;
24
25
  z-index: 1000;
25
26
  }
26
27
 
@@ -141,3 +141,11 @@ Screen reader will announce this text when the list is updated.
141
141
  </template>
142
142
  </gl-collapsible-listbox>
143
143
  ```
144
+
145
+ #### Dealing with long option texts
146
+
147
+ - Some options might have long non-wrapping text that would overflow the dropdown maximum width. In
148
+ such cases, it's recommended to override the `#list-item` slot and to truncate the option text using
149
+ `GlTruncate`.
150
+ - If the toggle text reflects the selected option text, it might be necessary to truncate
151
+ it too by overriding the `#toggle` slot.
@@ -43,6 +43,13 @@ describe('GlCollapsibleListbox', () => {
43
43
  const findResetButton = () => wrapper.find("[data-testid='listbox-reset-button']");
44
44
  const findIntersectionObserver = () => wrapper.findComponent(GlIntersectionObserver);
45
45
 
46
+ it('passes custom popper.js options to the base dropdown', () => {
47
+ const popperOptions = { foo: 'bar' };
48
+ buildWrapper({ popperOptions });
49
+
50
+ expect(findBaseDropdown().props('popperOptions')).toEqual(popperOptions);
51
+ });
52
+
46
53
  describe('toggle text', () => {
47
54
  describe.each`
48
55
  toggleText | multiple | selected | expectedToggleText
@@ -10,6 +10,7 @@ import GlButtonGroup from '../../button_group/button_group.vue';
10
10
  import GlButton from '../../button/button.vue';
11
11
  import GlBadge from '../../badge/badge.vue';
12
12
  import GlAvatar from '../../avatar/avatar.vue';
13
+ import GlTruncate from '../../../utilities/truncate/truncate.vue';
13
14
  import { makeContainer } from '../../../../utils/story_decorators/container';
14
15
  import { setStoryTimeout } from '../../../../utils/test_utils';
15
16
  import { disableControls } from '../../../../utils/stories_utils';
@@ -20,6 +21,7 @@ import {
20
21
  ARG_TYPE_SUBCATEGORY_ACCESSIBILITY,
21
22
  ARG_TYPE_SUBCATEGORY_INFINITE_SCROLL,
22
23
  } from '../../../../utils/stories_constants';
24
+ import { POSITION } from '../../../utilities/truncate/constants';
23
25
  import readme from './listbox.md';
24
26
  import { mockOptions, mockGroups, mockUsers } from './mock_data';
25
27
  import { flattenedOptions } from './utils';
@@ -755,7 +757,6 @@ export const InfiniteScroll = (
755
757
  },
756
758
  }),
757
759
  });
758
-
759
760
  InfiniteScroll.argTypes = {
760
761
  ...disableControls(['infiniteScroll', 'infiniteScrollLoading', 'items']),
761
762
  };
@@ -764,3 +765,59 @@ InfiniteScroll.parameters = {
764
765
  };
765
766
  InfiniteScroll.args = generateProps();
766
767
  InfiniteScroll.decorators = [makeContainer({ height: '370px' })];
768
+
769
+ export const WithLongContent = (args, { argTypes: { items, ...argTypes } }) => ({
770
+ props: Object.keys(argTypes),
771
+ components: {
772
+ GlCollapsibleListbox,
773
+ GlButton,
774
+ GlTruncate,
775
+ },
776
+ data() {
777
+ const positions = Object.values(POSITION);
778
+ const longItems = Array.from({ length: positions.length }).map((_, index) => ({
779
+ value: `long_value_${index}`,
780
+ text: `${
781
+ index + 1
782
+ }. This is a super long option. Its text is so long that it overflows the max content width. Thankfully, we are truncating it!`,
783
+ truncatePosition: positions[index],
784
+ }));
785
+
786
+ return {
787
+ selected: longItems[0].value,
788
+ items: longItems,
789
+ };
790
+ },
791
+ mounted() {
792
+ if (this.startOpened) {
793
+ openListbox(this);
794
+ }
795
+ },
796
+ computed: {
797
+ customToggleText() {
798
+ return this.items.find(({ value }) => value === this.selected).text;
799
+ },
800
+ numberOfSearchResults() {
801
+ return this.filteredItems.length === 1 ? '1 result' : `${this.filteredItems.length} results`;
802
+ },
803
+ },
804
+ template: template(
805
+ `
806
+ <template #toggle>
807
+ <gl-button class="gl-w-30">
808
+ <gl-truncate :text="customToggleText" />
809
+ </gl-button>
810
+ </template>
811
+ <template #list-item="{ item }">
812
+ <gl-truncate :text="item.text" :position="item.truncatePosition" />
813
+ </template>
814
+ `,
815
+ {
816
+ label: `<span class="gl-my-0" id="listbox-label">Select the longest option</span>`,
817
+ bindingOverrides: {
818
+ ':items': 'items',
819
+ },
820
+ }
821
+ ),
822
+ });
823
+ WithLongContent.args = generateProps();
@@ -287,6 +287,15 @@ export default {
287
287
  required: false,
288
288
  default: false,
289
289
  },
290
+ /**
291
+ * Options to be passed to the underlying Popper.js instance.
292
+ * Overrides built-in options.
293
+ */
294
+ popperOptions: {
295
+ type: Object,
296
+ required: false,
297
+ default: () => ({}),
298
+ },
290
299
  },
291
300
  data() {
292
301
  return {
@@ -585,6 +594,7 @@ export default {
585
594
  :loading="loading"
586
595
  :no-caret="noCaret"
587
596
  :placement="placement"
597
+ :popper-options="popperOptions"
588
598
  @[$options.events.GL_DROPDOWN_SHOWN]="onShow"
589
599
  @[$options.events.GL_DROPDOWN_HIDDEN]="onHide"
590
600
  >
@@ -464,7 +464,8 @@ $gl-icon-sizes: 8 12 14 16 24 32 48 72;
464
464
 
465
465
  // Dropdowns
466
466
  $gl-dropdown-width: px-to-rem(240px);
467
- $gl-new-dropdown-width: px-to-rem(256px);
467
+ $gl-new-dropdown-min-width: px-to-rem(248px);
468
+ $gl-new-dropdown-max-width: px-to-rem(456px);
468
469
  $gl-dropdown-width-narrow: px-to-rem(160px);
469
470
  $gl-dropdown-width-wide: px-to-rem(400px);
470
471
  $gl-max-dropdown-max-height: px-to-rem(312px);