@gitlab/ui 64.8.0 → 64.10.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "64.8.0",
3
+ "version": "64.10.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -10,6 +10,7 @@ export default {
10
10
  GlButton,
11
11
  GlIcon,
12
12
  },
13
+ inheritAttrs: false,
13
14
  props: {
14
15
  // The following 4 properties match the default names of the
15
16
  // [PageInfo](https://docs.gitlab.com/ee/api/graphql/reference/index.html#pageinfo)
@@ -68,6 +69,15 @@ export default {
68
69
  required: false,
69
70
  default: null,
70
71
  },
72
+ /**
73
+ * The aria-label that needs to be set for the
74
+ * pagination landmark region.
75
+ */
76
+ navigationLabel: {
77
+ type: String,
78
+ required: false,
79
+ default: 'Pagination',
80
+ },
71
81
  /**
72
82
  * The text that will be rendered inside the "Next" button.
73
83
  * It\'s important to provide this parameter since the default text is not translatable.
@@ -99,34 +109,36 @@ export default {
99
109
  </script>
100
110
 
101
111
  <template>
102
- <gl-button-group class="gl-keyset-pagination" v-bind="$attrs" v-on="$listeners">
103
- <gl-button
104
- :href="prevButtonLink"
105
- :disabled="disabled || !hasPreviousPage"
106
- data-testid="prevButton"
107
- @click="$emit('prev', startCursor)"
108
- >
109
- <!-- @slot Used to customize the appearance of the "Prev" button -->
110
- <slot name="previous-button-content">
111
- <div class="gl-display-flex gl-align-center">
112
- <gl-icon name="chevron-left" />
113
- {{ prevText }}
114
- </div>
115
- </slot>
116
- </gl-button>
117
- <gl-button
118
- :href="nextButtonLink"
119
- :disabled="disabled || !hasNextPage"
120
- data-testid="nextButton"
121
- @click="$emit('next', endCursor)"
122
- >
123
- <!-- @slot Used to customize the appearance of the "Next" button -->
124
- <slot name="next-button-content">
125
- <div class="gl-display-flex gl-align-center">
126
- {{ nextText }}
127
- <gl-icon name="chevron-right" />
128
- </div>
129
- </slot>
130
- </gl-button>
131
- </gl-button-group>
112
+ <nav class="gl-pagination" :aria-label="navigationLabel">
113
+ <gl-button-group class="gl-keyset-pagination" v-bind="$attrs" v-on="$listeners">
114
+ <gl-button
115
+ :href="prevButtonLink"
116
+ :disabled="disabled || !hasPreviousPage"
117
+ data-testid="prevButton"
118
+ @click="$emit('prev', startCursor)"
119
+ >
120
+ <!-- @slot Used to customize the appearance of the "Prev" button -->
121
+ <slot name="previous-button-content">
122
+ <div class="gl-display-flex gl-align-center">
123
+ <gl-icon name="chevron-left" />
124
+ {{ prevText }}
125
+ </div>
126
+ </slot>
127
+ </gl-button>
128
+ <gl-button
129
+ :href="nextButtonLink"
130
+ :disabled="disabled || !hasNextPage"
131
+ data-testid="nextButton"
132
+ @click="$emit('next', endCursor)"
133
+ >
134
+ <!-- @slot Used to customize the appearance of the "Next" button -->
135
+ <slot name="next-button-content">
136
+ <div class="gl-display-flex gl-align-center">
137
+ {{ nextText }}
138
+ <gl-icon name="chevron-right" />
139
+ </div>
140
+ </slot>
141
+ </gl-button>
142
+ </gl-button-group>
143
+ </nav>
132
144
  </template>
@@ -1,2 +1,6 @@
1
1
  export const DISCLOSURE_DROPDOWN_ITEM_NAME = 'GlDisclosureDropdownItem';
2
2
  export const DISCLOSURE_DROPDOWN_GROUP_NAME = 'GlDisclosureDropdownGroup';
3
+ export const DISCLOSURE_DROPDOWN_GROUP_BORDER_POSITIONS = {
4
+ top: 'top',
5
+ bottom: 'bottom',
6
+ };
@@ -91,7 +91,7 @@ template. If you want to render a custom template for items, use the
91
91
  <template #list-item="{ item }">
92
92
  <span class="gl-display-flex gl-align-items-center gl-justify-content-space-between">
93
93
  {{item.text}}
94
- <gl-icon v-if="item.icon" :name="item.icon"/>
94
+ <gl-icon v-if="item.icon" :name="item.icon" />
95
95
  </span>
96
96
  </template>
97
97
  </gl-disclosure-dropdown>
@@ -117,6 +117,16 @@ To render custom group labels, use the `group-label` scoped slot:
117
117
  </gl-disclosure-dropdown>
118
118
  ```
119
119
 
120
+ To draw a horizontal line that separates two groups, set the `bordered` property.
121
+ By default, the border appears above the group. You can change the border position
122
+ using the `border-position` property:
123
+
124
+ ```html
125
+ <gl-disclosure-dropdown>
126
+ <gl-disclosure-dropdown-group bordered border-position="bottom" :group="group" />
127
+ </gl-disclosure-dropdown>
128
+ ```
129
+
120
130
  #### Miscellaneous content
121
131
 
122
132
  Besides default components, disclosure dropdown can render miscellaneous content inside it.
@@ -125,7 +135,7 @@ In this case the user is responsible for handling all events and navigation insi
125
135
  #### Dealing with long option texts
126
136
 
127
137
  - Some options might have long non-wrapping text that would overflow the dropdown maximum width. In
128
- such cases, it's recommended to override the `#list-item` slot and to truncate the option text using
129
- `GlTruncate`.
138
+ such cases, it's recommended to override the `#list-item` slot and to truncate the option text using
139
+ `GlTruncate`.
130
140
  - If the toggle text reflects the selected option text, it might be necessary to truncate
131
- it too by overriding the `#toggle` slot.
141
+ it too by overriding the `#toggle` slot.
@@ -14,6 +14,7 @@ import { makeContainer } from '../../../../utils/story_decorators/container';
14
14
  import GlDisclosureDropdown from './disclosure_dropdown.vue';
15
15
  import GlDisclosureDropdownItem from './disclosure_dropdown_item.vue';
16
16
  import GlDisclosureDropdownGroup from './disclosure_dropdown_group.vue';
17
+ import { DISCLOSURE_DROPDOWN_GROUP_BORDER_POSITIONS } from './constants';
17
18
  import readme from './disclosure_dropdown.md';
18
19
  import {
19
20
  mockItems,
@@ -229,7 +230,7 @@ export const CustomGroupsItemsAndToggle = makeGroupedExample({
229
230
  </template>
230
231
  </gl-disclosure-dropdown-item>
231
232
  </gl-disclosure-dropdown-group>
232
- <gl-disclosure-dropdown-group bordered :group="$options.groups[0]" @action="closeDropdown">
233
+ <gl-disclosure-dropdown-group :bordered="bordered" :border-position="borderPosition" :group="$options.groups[0]" @action="closeDropdown">
233
234
  <template #list-item="{ item }">
234
235
  <span class="gl-display-flex gl-align-items-center gl-justify-content-space-between">
235
236
  {{item.text}}
@@ -237,7 +238,7 @@ export const CustomGroupsItemsAndToggle = makeGroupedExample({
237
238
  </span>
238
239
  </template>
239
240
  </gl-disclosure-dropdown-group>
240
- <gl-disclosure-dropdown-group bordered>
241
+ <gl-disclosure-dropdown-group :bordered="bordered" :border-position="borderPosition">
241
242
  <template #group-label>
242
243
  <span class="gl-font-sm">Navigation redesign</span>
243
244
  <gl-badge size="sm" variant="info">Beta</gl-badge>
@@ -253,7 +254,7 @@ export const CustomGroupsItemsAndToggle = makeGroupedExample({
253
254
  <template #list-item>Provide feedback</template>
254
255
  </gl-disclosure-dropdown-item>
255
256
  </gl-disclosure-dropdown-group>
256
- <gl-disclosure-dropdown-group bordered :group="$options.groups[1]" @action="closeDropdown"/>
257
+ <gl-disclosure-dropdown-group :bordered="bordered" :border-position="borderPosition" :group="$options.groups[1]" @action="closeDropdown"/>
257
258
  `,
258
259
  {
259
260
  after: `
@@ -292,7 +293,18 @@ CustomGroupsItemsAndToggle.args = {
292
293
  toggleText: 'User profile menu',
293
294
  textSrOnly: true,
294
295
  autoClose: false,
296
+ bordered: true,
297
+ borderPosition: DISCLOSURE_DROPDOWN_GROUP_BORDER_POSITIONS.top,
295
298
  };
299
+ CustomGroupsItemsAndToggle.argTypes = {
300
+ borderPosition: {
301
+ options: DISCLOSURE_DROPDOWN_GROUP_BORDER_POSITIONS,
302
+ control: {
303
+ type: 'select',
304
+ },
305
+ },
306
+ };
307
+
296
308
  CustomGroupsItemsAndToggle.decorators = [makeContainer({ height: '400px' })];
297
309
 
298
310
  export const MiscellaneousContent = (args, { argTypes }) => ({
@@ -334,26 +346,26 @@ export default {
334
346
  category: {
335
347
  control: {
336
348
  type: 'select',
337
- options: buttonCategoryOptions,
338
349
  },
350
+ options: buttonCategoryOptions,
339
351
  },
340
352
  variant: {
341
353
  control: {
342
354
  type: 'select',
343
- options: buttonVariantOptions,
344
355
  },
356
+ options: buttonVariantOptions,
345
357
  },
346
358
  size: {
347
359
  control: {
348
360
  type: 'select',
349
- options: Object.keys(buttonSizeOptions),
350
361
  },
362
+ options: Object.keys(buttonSizeOptions),
351
363
  },
352
364
  placement: {
353
365
  control: {
354
366
  type: 'select',
355
- options: Object.keys(dropdownPlacements),
356
367
  },
368
+ options: Object.keys(dropdownPlacements),
357
369
  },
358
370
  },
359
371
  args: {
@@ -1,9 +1,8 @@
1
1
  import { shallowMount } from '@vue/test-utils';
2
- import GlDisclosureDropdownGroup, {
3
- GROUP_TOP_BORDER_CLASSES,
4
- } from './disclosure_dropdown_group.vue';
2
+ import GlDisclosureDropdownGroup, { BORDER_CLASSES } from './disclosure_dropdown_group.vue';
5
3
  import GlDisclosureDropdownItem from './disclosure_dropdown_item.vue';
6
4
  import { mockGroups, mockProfileGroups } from './mock_data';
5
+ import { DISCLOSURE_DROPDOWN_GROUP_BORDER_POSITIONS as borderPositions } from './constants';
7
6
 
8
7
  describe('GlDisclosureDropdownGroup', () => {
9
8
  let wrapper;
@@ -69,17 +68,17 @@ describe('GlDisclosureDropdownGroup', () => {
69
68
  });
70
69
  });
71
70
 
72
- describe('separator', () => {
73
- const topBorderClasses = GROUP_TOP_BORDER_CLASSES.split(' ');
74
-
75
- it('should not add top border by default', () => {
76
- buildWrapper();
77
- expect(wrapper.classes()).not.toEqual(expect.arrayContaining(topBorderClasses));
78
- });
79
-
80
- it('should add top border classes when `bordered` props is set to `true`', () => {
81
- buildWrapper({ propsData: { bordered: true } });
82
- expect(wrapper.classes()).toEqual(expect.arrayContaining(topBorderClasses));
83
- });
84
- });
71
+ it.each`
72
+ bordered | borderPosition | classes
73
+ ${true} | ${borderPositions.top} | ${BORDER_CLASSES[borderPositions.top].split(' ')}
74
+ ${true} | ${borderPositions.bottom} | ${BORDER_CLASSES[borderPositions.bottom].split(' ')}
75
+ ${false} | ${borderPositions.top} | ${[]}
76
+ ${false} | ${borderPositions.bottom} | ${[]}
77
+ `(
78
+ 'adds border classes `$classes` when bordered=$bordered and borderPosition=$borderPosition',
79
+ ({ bordered, borderPosition, classes }) => {
80
+ buildWrapper({ propsData: { bordered, borderPosition } });
81
+ expect(wrapper.classes()).toEqual(classes);
82
+ }
83
+ );
85
84
  });
@@ -2,9 +2,15 @@
2
2
  import uniqueId from 'lodash/uniqueId';
3
3
  import GlDisclosureDropdownItem from './disclosure_dropdown_item.vue';
4
4
  import { isGroup } from './utils';
5
- import { DISCLOSURE_DROPDOWN_GROUP_NAME } from './constants';
5
+ import {
6
+ DISCLOSURE_DROPDOWN_GROUP_NAME,
7
+ DISCLOSURE_DROPDOWN_GROUP_BORDER_POSITIONS as borderPositions,
8
+ } from './constants';
6
9
 
7
- export const GROUP_TOP_BORDER_CLASSES = 'gl-border-t gl-pt-2 gl-mt-2';
10
+ export const BORDER_CLASSES = {
11
+ [borderPositions.top]: 'gl-border-t gl-pt-2 gl-mt-2',
12
+ [borderPositions.bottom]: 'gl-border-b gl-pb-2 gl-mb-2',
13
+ };
8
14
 
9
15
  export default {
10
16
  name: DISCLOSURE_DROPDOWN_GROUP_NAME,
@@ -23,17 +29,30 @@ export default {
23
29
  },
24
30
  /**
25
31
  * If 'true', will set top border for the group
26
- * to separate from other groups
32
+ * to separate from other groups. You can control
33
+ * the border position using the `borderPosition`
34
+ * property.
27
35
  */
28
36
  bordered: {
29
37
  type: Boolean,
30
38
  required: false,
31
39
  default: false,
32
40
  },
41
+
42
+ /**
43
+ * Controls the position of the group's border. Valid
44
+ * values are 'top' and 'bottom'.
45
+ */
46
+ borderPosition: {
47
+ type: String,
48
+ required: false,
49
+ default: borderPositions.top,
50
+ validator: (value) => Object.keys(borderPositions).includes(value),
51
+ },
33
52
  },
34
53
  computed: {
35
54
  borderClass() {
36
- return this.bordered ? GROUP_TOP_BORDER_CLASSES : null;
55
+ return this.bordered ? BORDER_CLASSES[this.borderPosition] : null;
37
56
  },
38
57
  showHeader() {
39
58
  return this.$scopedSlots['group-label'] || this.group?.name;
@@ -21,6 +21,9 @@
21
21
  @return $value;
22
22
  }
23
23
 
24
+ // Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0
25
+ // We can't update this yet since GitLab uses SassC, which doesn't support math.div
26
+ // See https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1954#note_1078281533
24
27
  $converted: $value / $font-size-base;
25
28
 
26
29
  @return strip-unit($converted) * 1rem;
@@ -54,6 +57,9 @@
54
57
  $min-width: px-to-rem($min-width);
55
58
  $max-width: px-to-rem($max-width);
56
59
 
60
+ // Using / for division outside of calc() is deprecated and will be removed in Dart Sass 2.0.0
61
+ // We can't update this yet since GitLab uses SassC, which doesn't support math.div
62
+ // See https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1954#note_1078281533
57
63
  $slope: ($max - $min) / ($max-width - $min-width);
58
64
  $intersection: (-$min-width * $slope) + $min;
59
65
 
@@ -3639,6 +3639,18 @@
3639
3639
  flex-basis: 33% !important;
3640
3640
  }
3641
3641
 
3642
+ .gl-md-flex-basis-third {
3643
+ @include gl-media-breakpoint-up(md) {
3644
+ flex-basis: 33%;
3645
+ }
3646
+ }
3647
+
3648
+ .gl-md-flex-basis-third\! {
3649
+ @include gl-media-breakpoint-up(md) {
3650
+ flex-basis: 33% !important;
3651
+ }
3652
+ }
3653
+
3642
3654
  .gl-flex-basis-two-thirds {
3643
3655
  flex-basis: 66%;
3644
3656
  }
@@ -225,6 +225,12 @@
225
225
  flex-basis: 33%;
226
226
  }
227
227
 
228
+ @mixin gl-md-flex-basis-third {
229
+ @include gl-media-breakpoint-up(md) {
230
+ @include gl-flex-basis-third;
231
+ }
232
+ }
233
+
228
234
  @mixin gl-flex-basis-two-thirds {
229
235
  flex-basis: 66%;
230
236
  }