@gitlab/ui 59.4.0 → 60.0.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": "59.4.0",
3
+ "version": "60.0.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -1,22 +1,23 @@
1
1
  ## Usage
2
2
 
3
- This component provides a `<slot #avatar>` so an avatar can appear before the first breadcrumb.
3
+ This component also allows for optional avatars on each item.
4
+
5
+ `avatarPath` should passed along with `text` and `href` in `items`.
6
+ Here is an example of how an item with an avatar should look:
4
7
 
5
8
  **note:** the component supports passing the property `to` in the list items to enable navigation
6
9
  through `vue-router`
7
10
 
8
11
  ### Example
9
12
 
10
- ```html
11
- <gl-breadcrumb :items="items">
12
- <template #avatar>
13
- <img
14
- alt=""
15
- class="gl-breadcrumb-avatar-tile"
16
- src="/path/to/image.png"
17
- width="16"
18
- height="16"
19
- />
20
- </template>
21
- </gl-breadcrumb>
13
+ ```js
14
+ items = [
15
+ {
16
+ text: 'First item',
17
+ href: '#',
18
+ avatarPath: '/avatar.png',
19
+ },
20
+ ];
21
+
22
+ <gl-breadcrumb :items="items" />
22
23
  ```
@@ -16,14 +16,6 @@ $breadcrumb-max-width: $grid-size * 16;
16
16
  }
17
17
  }
18
18
 
19
- .gl-breadcrumb-avatar-tile {
20
- @include gl-mr-2;
21
- @include gl-border-1;
22
- @include gl-border-solid;
23
- @include gl-border-gray-a-08;
24
- @include gl-rounded-base;
25
- }
26
-
27
19
  // bootstrap overrides
28
20
  .gl-breadcrumb-item {
29
21
  @include gl-font-sm;
@@ -1,5 +1,7 @@
1
1
  import { shallowMount } from '@vue/test-utils';
2
2
  import { nextTick } from 'vue';
3
+ import avatarPath1 from '../../../../static/img/avatar.png';
4
+ import avatarPath3 from '../../../../static/img/avatar_1.png';
3
5
  import Breadcrumb, { COLLAPSE_AT_SIZE } from './breadcrumb.vue';
4
6
  import GlBreadcrumbItem from './breadcrumb_item.vue';
5
7
 
@@ -7,23 +9,27 @@ describe('Breadcrumb component', () => {
7
9
  let wrapper;
8
10
 
9
11
  const items = [
10
- { text: 'first_breadcrumb', href: 'http://gitlab.com' },
12
+ { text: 'first_breadcrumb', href: 'https://gitlab.com', avatarPath: avatarPath1 },
11
13
  {
12
14
  text: 'second_breadcrumb',
13
15
  to: 'to_value',
14
16
  },
15
- { text: 'third_breadcrumb', href: 'http://about.gitlab.com' },
17
+ {
18
+ text: 'third_breadcrumb',
19
+ href: 'https://about.gitlab.com',
20
+ avatarPath: avatarPath3,
21
+ },
16
22
  ];
17
23
 
18
24
  const extraItems = [
19
- { text: 'fourth_breadcrumb', href: 'http://gitlab.com' },
25
+ { text: 'fourth_breadcrumb', href: 'https://gitlab.com' },
20
26
  {
21
27
  text: 'fifth_breadcrumb',
22
28
  to: 'to_value',
23
29
  },
24
30
  ];
25
31
 
26
- const findAvatarSlot = () => wrapper.find('[data-testid="avatar-slot"]');
32
+ const findAllAvatars = () => wrapper.findAll('[data-testid="avatar"]');
27
33
  const findBreadcrumbItems = () => wrapper.findAllComponents(GlBreadcrumbItem);
28
34
  const findCollapsedListExpander = () => wrapper.find('[data-testid="collapsed-expander"]');
29
35
 
@@ -35,9 +41,6 @@ describe('Breadcrumb component', () => {
35
41
  const createComponent = (propsData = { items }) => {
36
42
  wrapper = shallowMount(Breadcrumb, {
37
43
  propsData,
38
- slots: {
39
- avatar: '<div data-testid="avatar-slot"></div>',
40
- },
41
44
  stubs: {
42
45
  GlBreadcrumbItem,
43
46
  },
@@ -50,19 +53,19 @@ describe('Breadcrumb component', () => {
50
53
  ];
51
54
  };
52
55
 
53
- describe('slots', () => {
54
- it('has an avatar slot', () => {
56
+ describe('items', () => {
57
+ it('has one breadcrumb-item for each item in the items props', () => {
55
58
  createComponent();
56
59
 
57
- expect(findAvatarSlot().exists()).toBe(true);
60
+ expect(findBreadcrumbItems()).toHaveLength(items.length);
58
61
  });
59
62
  });
60
63
 
61
- describe('items', () => {
62
- it('has one breadcrumb-item for each item in the items props', () => {
64
+ describe('avatars', () => {
65
+ it('renders 2 avatars when 2 avatarPaths are passed', () => {
63
66
  createComponent();
64
67
 
65
- expect(findBreadcrumbItems()).toHaveLength(items.length);
68
+ expect(findAllAvatars()).toHaveLength(2);
66
69
  });
67
70
  });
68
71
 
@@ -1,24 +1,19 @@
1
- import avatarPath from '../../../../static/img/avatar.png';
1
+ import avatarPath1 from '../../../../static/img/avatar_1.png';
2
+ import avatarPath2 from '../../../../static/img/avatar_2.png';
2
3
  import GlBreadcrumb from './breadcrumb.vue';
3
4
  import readme from './breadcrumb.md';
4
5
 
5
6
  const template = `
6
7
  <gl-breadcrumb
7
8
  :items="items"
8
- >
9
- <template #avatar>
10
- <img alt=""
11
- class="gl-breadcrumb-avatar-tile" src="${avatarPath}"
12
- width="16"
13
- height="16" />
14
- </template>
15
- </gl-breadcrumb>
9
+ />
16
10
  `;
17
11
 
18
12
  const defaultItems = [
19
13
  {
20
14
  text: 'First item',
21
15
  href: '#',
16
+ avatarPath: avatarPath1,
22
17
  },
23
18
  {
24
19
  text: 'Second item',
@@ -27,6 +22,7 @@ const defaultItems = [
27
22
  {
28
23
  text: 'Third item',
29
24
  href: '#',
25
+ avatarPath: avatarPath2,
30
26
  },
31
27
  {
32
28
  text: 'Fourth item',
@@ -2,6 +2,7 @@
2
2
  <script>
3
3
  import { BBreadcrumb } from 'bootstrap-vue';
4
4
  import GlButton from '../button/button.vue';
5
+ import GlAvatar from '../avatar/avatar.vue';
5
6
  import { GlTooltipDirective } from '../../../directives/tooltip';
6
7
  import GlBreadcrumbItem from './breadcrumb_item.vue';
7
8
 
@@ -12,6 +13,7 @@ export default {
12
13
  BBreadcrumb,
13
14
  GlButton,
14
15
  GlBreadcrumbItem,
16
+ GlAvatar,
15
17
  },
16
18
  directives: {
17
19
  GlTooltip: GlTooltipDirective,
@@ -25,9 +27,9 @@ export default {
25
27
  type: Array,
26
28
  required: true,
27
29
  default: () => [{ text: '', href: '' }],
28
- validator: (links) => {
29
- return links.every((link) => {
30
- const keys = Object.keys(link);
30
+ validator: (items) => {
31
+ return items.every((item) => {
32
+ const keys = Object.keys(item);
31
33
  return keys.includes('text') && (keys.includes('href') || keys.includes('to'));
32
34
  });
33
35
  },
@@ -82,8 +84,6 @@ export default {
82
84
  </script>
83
85
  <template>
84
86
  <nav class="gl-breadcrumbs" aria-label="Breadcrumb">
85
- <!-- @slot The avatar to display. -->
86
- <slot name="avatar"></slot>
87
87
  <b-breadcrumb class="gl-breadcrumb-list" v-bind="$attrs" v-on="$listeners">
88
88
  <template v-for="(item, index) in items">
89
89
  <!-- eslint-disable-next-line vue/valid-v-for (for @vue/compat) -->
@@ -94,8 +94,16 @@ export default {
94
94
  :href="item.href"
95
95
  :to="item.to"
96
96
  :aria-current="getAriaCurrentAttr(index)"
97
- >{{ item.text }}</gl-breadcrumb-item
98
- >
97
+ ><gl-avatar
98
+ v-if="item.avatarPath"
99
+ :src="item.avatarPath"
100
+ :size="16"
101
+ aria-hidden="true"
102
+ class="gl-breadcrumb-avatar-tile gl-border gl-mr-2 gl-rounded-base!"
103
+ shape="rect"
104
+ data-testid="avatar"
105
+ /><span>{{ item.text }}</span>
106
+ </gl-breadcrumb-item>
99
107
 
100
108
  <template v-if="showCollapsedBreadcrumbsExpander(index)">
101
109
  <!-- eslint-disable-next-line vue/require-v-for-key (for @vue/compat) -->
@@ -3343,6 +3343,34 @@
3343
3343
  }
3344
3344
  }
3345
3345
 
3346
+ .gl-flex-wrap-reverse {
3347
+ flex-wrap: wrap-reverse;
3348
+ }
3349
+
3350
+ .gl-flex-wrap-reverse\! {
3351
+ flex-wrap: wrap-reverse !important;
3352
+ }
3353
+
3354
+ .gl-flex-nowrap {
3355
+ flex-wrap: nowrap;
3356
+ }
3357
+
3358
+ .gl-flex-nowrap\! {
3359
+ flex-wrap: nowrap !important;
3360
+ }
3361
+
3362
+ .gl-sm-flex-nowrap {
3363
+ @include gl-media-breakpoint-up(sm) {
3364
+ flex-wrap: nowrap;
3365
+ }
3366
+ }
3367
+
3368
+ .gl-sm-flex-nowrap\! {
3369
+ @include gl-media-breakpoint-up(sm) {
3370
+ flex-wrap: nowrap !important;
3371
+ }
3372
+ }
3373
+
3346
3374
  .gl-flex-wrap-wrap {
3347
3375
  flex-wrap: wrap;
3348
3376
  }
@@ -3415,14 +3443,6 @@
3415
3443
  }
3416
3444
  }
3417
3445
 
3418
- .gl-flex-nowrap {
3419
- flex-wrap: nowrap;
3420
- }
3421
-
3422
- .gl-flex-nowrap\! {
3423
- flex-wrap: nowrap !important;
3424
- }
3425
-
3426
3446
  .gl-flex-direction-column {
3427
3447
  flex-direction: column;
3428
3448
  }
@@ -65,11 +65,6 @@
65
65
  }
66
66
  }
67
67
 
68
- /**
69
- * `gl-*flex-wrap` is deprecated; use `gl-*flex-wrap-wrap` instead.
70
- * TODO: delete `gl-*flex-wrap` utilities classes, see
71
- * https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1951
72
- */
73
68
  @mixin gl-flex-wrap {
74
69
  flex-wrap: wrap;
75
70
  }
@@ -92,6 +87,25 @@
92
87
  }
93
88
  }
94
89
 
90
+ @mixin gl-flex-wrap-reverse {
91
+ flex-wrap: wrap-reverse;
92
+ }
93
+
94
+ @mixin gl-flex-nowrap {
95
+ flex-wrap: nowrap;
96
+ }
97
+
98
+ @mixin gl-sm-flex-nowrap {
99
+ @include gl-media-breakpoint-up(sm) {
100
+ @include gl-flex-nowrap;
101
+ }
102
+ }
103
+
104
+ /**
105
+ * `gl-*flex-wrap-wrap` is deprecated; use `gl-*flex-wrap` instead.
106
+ * TODO: delete `gl-*flex-wrap-wrap` utilities classes, see
107
+ * https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2204
108
+ */
95
109
  @mixin gl-flex-wrap-wrap {
96
110
  flex-wrap: wrap;
97
111
  }
@@ -128,15 +142,6 @@
128
142
  }
129
143
  }
130
144
 
131
- /**
132
- * `gl-flex-nowrap` is deprecated; use `gl-flex-wrap-nowrap` instead.
133
- * TODO: delete `gl-flex-wrap-nowrap` utility class, see
134
- * https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1951
135
- */
136
- @mixin gl-flex-nowrap {
137
- flex-wrap: nowrap;
138
- }
139
-
140
145
  @mixin gl-flex-direction-column {
141
146
  flex-direction: column;
142
147
  }