@gitlab/ui 46.1.0 → 47.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/components/base/breadcrumb/breadcrumb.js +1 -1
  3. package/dist/components/base/datepicker/datepicker.js +17 -11
  4. package/dist/components/base/dropdown/dropdown.js +3 -3
  5. package/dist/components/base/filtered_search/filtered_search.js +1 -1
  6. package/dist/components/base/form/form_checkbox_tree/form_checkbox_tree.js +1 -1
  7. package/dist/components/base/form/form_checkbox_tree/models/tree.js +0 -1
  8. package/dist/components/base/infinite_scroll/infinite_scroll.js +17 -26
  9. package/dist/components/base/pagination/pagination.js +3 -1
  10. package/dist/components/base/search_box_by_click/search_box_by_click.js +1 -1
  11. package/dist/components/charts/column/column.js +0 -1
  12. package/dist/components/utilities/intersperse/intersperse.js +1 -1
  13. package/dist/utility_classes.css +1 -1
  14. package/dist/utility_classes.css.map +1 -1
  15. package/package.json +7 -7
  16. package/src/components/base/alert/alert.spec.js +3 -3
  17. package/src/components/base/breadcrumb/breadcrumb.spec.js +0 -2
  18. package/src/components/base/breadcrumb/breadcrumb.vue +1 -1
  19. package/src/components/base/datepicker/datepicker.vue +18 -11
  20. package/src/components/base/daterange_picker/daterange_picker.spec.js +1 -3
  21. package/src/components/base/dropdown/dropdown.vue +4 -4
  22. package/src/components/base/filtered_search/filtered_search.vue +29 -30
  23. package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.vue +1 -1
  24. package/src/components/base/form/form_checkbox_tree/models/tree.js +0 -1
  25. package/src/components/base/form/form_group/form_group.spec.js +1 -0
  26. package/src/components/base/infinite_scroll/infinite_scroll.vue +15 -24
  27. package/src/components/base/new_dropdowns/base_dropdown/base_dropdown.spec.js +1 -0
  28. package/src/components/base/new_dropdowns/listbox/listbox.spec.js +1 -0
  29. package/src/components/base/new_dropdowns/listbox/listbox.stories.js +64 -99
  30. package/src/components/base/pagination/pagination.spec.js +1 -1
  31. package/src/components/base/pagination/pagination.vue +6 -4
  32. package/src/components/base/search_box_by_click/search_box_by_click.spec.js +6 -5
  33. package/src/components/base/search_box_by_click/search_box_by_click.vue +1 -1
  34. package/src/components/base/sorting/sorting.spec.js +0 -17
  35. package/src/components/base/tabs/tab/tab.spec.js +2 -3
  36. package/src/components/base/tabs/tabs/scrollable_tabs.spec.js +3 -1
  37. package/src/components/charts/column/column.vue +1 -1
  38. package/src/components/utilities/intersection_observer/intersection_observer.spec.js +1 -1
  39. package/src/components/utilities/intersperse/intersperse.vue +1 -1
  40. package/src/components/utilities/sprintf/sprintf.spec.js +1 -5
  41. package/src/components/utilities/truncate/truncate.spec.js +4 -5
  42. package/src/directives/hover_load/hover_load.spec.js +1 -1
  43. package/src/directives/safe_link/safe_link.spec.js +11 -13
  44. package/src/scss/utilities.scss +2 -12
  45. package/src/scss/utility-mixins/spacing.scss +1 -8
@@ -125,17 +125,19 @@ describe('search box by click component', () => {
125
125
 
126
126
  it('displays disabled history dropdown', () => {
127
127
  expect(wrapper.findComponent({ ref: 'historyDropdown' }).exists()).toBe(true);
128
- expect(wrapper.findComponent({ ref: 'historyDropdown' }).attributes('disabled')).toBe('true');
128
+ expect(
129
+ wrapper.findComponent({ ref: 'historyDropdown' }).attributes('disabled')
130
+ ).toBeDefined();
129
131
  });
130
132
 
131
133
  it('displays disabled input', () => {
132
134
  expect(wrapper.findComponent({ ref: 'input' }).exists()).toBe(true);
133
- expect(wrapper.findComponent({ ref: 'input' }).attributes('disabled')).toBe('true');
135
+ expect(wrapper.findComponent({ ref: 'input' }).attributes('disabled')).toBeDefined();
134
136
  });
135
137
 
136
138
  it('displays disabled search button', () => {
137
139
  expect(findSearchButton().exists()).toBe(true);
138
- expect(findSearchButton().attributes('disabled')).toBe('true');
140
+ expect(findSearchButton().attributes('disabled')).toBeDefined();
139
141
  });
140
142
 
141
143
  it('does not render clear icon even with value', () => {
@@ -146,9 +148,8 @@ describe('search box by click component', () => {
146
148
  it('emits submit event when Enter key is pressed', async () => {
147
149
  createComponent({ value: 'some-input' });
148
150
 
149
- wrapper.findComponent(GlFormInput).vm.$emit('keydown', { type: 'key', keyCode: 13 });
151
+ await wrapper.findComponent(GlFormInput).trigger('keydown.enter');
150
152
 
151
- await wrapper.vm.$nextTick();
152
153
  expect(wrapper.emitted('submit')[0]).toEqual(['some-input']);
153
154
  });
154
155
 
@@ -258,7 +258,7 @@ export default {
258
258
  :disabled="disabled"
259
259
  @focus="isFocused = true"
260
260
  @blur="isFocused = false"
261
- @keydown.enter="search(currentValue)"
261
+ @keydown.enter.native="search(currentValue)"
262
262
  />
263
263
  </slot>
264
264
  <gl-clear-icon-button
@@ -1,9 +1,7 @@
1
1
  import { mount } from '@vue/test-utils';
2
2
  import GlDropdown from '../dropdown/dropdown.vue';
3
- import GlDropdownItem from '../dropdown/dropdown_item.vue';
4
3
  import GlIcon from '../icon/icon.vue';
5
4
  import GlSorting from './sorting.vue';
6
- import GlSortingItem from './sorting_item.vue';
7
5
 
8
6
  describe('sorting component', () => {
9
7
  let wrapper;
@@ -22,25 +20,10 @@ describe('sorting component', () => {
22
20
 
23
21
  const createComponent = (propsData) => {
24
22
  wrapper = mount(GlSorting, {
25
- attachTo: document.body,
26
- components: {
27
- GlSortingItem,
28
- },
29
- slots: {
30
- default: [
31
- '<gl-sorting-item :active="true">First item</gl-sorting-item>',
32
- '<gl-sorting-item>Second item</gl-sorting-item>',
33
- '<gl-sorting-item>Third item</gl-sorting-item>',
34
- ],
35
- },
36
23
  propsData: {
37
24
  ...defaultProps,
38
25
  ...propsData,
39
26
  },
40
- stubs: {
41
- GlSortingItem,
42
- GlDropdownItem,
43
- },
44
27
  });
45
28
  };
46
29
 
@@ -1,4 +1,5 @@
1
1
  import { shallowMount } from '@vue/test-utils';
2
+ import { BTab } from 'bootstrap-vue';
2
3
  import { DEFAULT_TAB_TITLE_LINK_CLASS } from '../constants';
3
4
  import GlTab from './tab.vue';
4
5
 
@@ -27,9 +28,7 @@ describe('Tab component', () => {
27
28
  },
28
29
  });
29
30
 
30
- expect(wrapper.html()).toBe(
31
- `<b-tab-stub tag="div" title="" titlelinkclass="${expectedProp}"></b-tab-stub>`
32
- );
31
+ expect(wrapper.findComponent(BTab).props('titleLinkClass')).toStrictEqual(expectedProp);
33
32
  }
34
33
  );
35
34
  });
@@ -58,7 +58,9 @@ describe('GlScrollableTabs', () => {
58
58
  ...props,
59
59
  },
60
60
  slots: {
61
- default: `<gl-tab v-for="tab in tabs" :key="tab.key" :title="tab.title">{{ tab.content }}</gl-tab>`,
61
+ default: {
62
+ template: `<div><gl-tab v-for="tab in tabs" :key="tab.key" :title="tab.title">{{ tab.content }}</gl-tab></div>`,
63
+ },
62
64
  },
63
65
  stubs: {
64
66
  'gl-tab': GlTab,
@@ -96,7 +96,7 @@ export default {
96
96
  barSeries() {
97
97
  return this.bars.map(({ name, data }, index) => {
98
98
  const color = colorFromDefaultPalette(index);
99
- return generateBarSeries({ stack: this.groupBy, name, data, color });
99
+ return generateBarSeries({ name, data, color });
100
100
  });
101
101
  },
102
102
  lineSeries() {
@@ -47,7 +47,7 @@ describe('IntersectionObserver', () => {
47
47
  });
48
48
 
49
49
  it('renders slot', () => {
50
- expect(wrapper.element.innerHTML).toEqual(TEST_SLOT);
50
+ expect(wrapper.html()).toContain(TEST_SLOT);
51
51
  });
52
52
 
53
53
  it('creates 1 intersection observer', () => {
@@ -7,7 +7,7 @@ import filter from 'lodash/fp/filter';
7
7
  import { intersperse, insert } from '../../../utils/data_utils';
8
8
 
9
9
  const containsWhitespaceOnly = (vNode) => vNode.text.trim() === '';
10
- const isTag = (vNode) => vNode.tag !== undefined;
10
+ const isTag = (vNode) => typeof vNode.tag === 'string';
11
11
  const filterWhitespaceNodes = filter((vNode) => isTag(vNode) || !containsWhitespaceOnly(vNode));
12
12
 
13
13
  const insertAfterSecondLastItem = insert(-1);
@@ -89,11 +89,7 @@ describe('sprintf component', () => {
89
89
  });
90
90
 
91
91
  it('should work with a default slot', () => {
92
- createComponent(
93
- `<sprintf message="Written by %{default}">
94
- <template>Author</template>
95
- </sprintf>`
96
- );
92
+ createComponent(`<sprintf message="Written by %{default}">Author</sprintf>`);
97
93
 
98
94
  expect(wrapper.element.innerHTML).toBe('Written by Author');
99
95
  });
@@ -1,5 +1,5 @@
1
1
  import { shallowMount } from '@vue/test-utils';
2
- import { createMockDirective, getBinding } from '~helpers/vue_mock_directive';
2
+ import { getBinding } from '~helpers/vue_mock_directive';
3
3
  import { POSITION } from './constants';
4
4
  import Truncate from './truncate.vue';
5
5
 
@@ -17,10 +17,9 @@ describe('Truncate component', () => {
17
17
  };
18
18
 
19
19
  const createComponent = (props) => {
20
- wrapper = shallowMount(
21
- { extends: Truncate, directives: { GlTooltip: createMockDirective('gl-tooltip') } },
22
- { propsData: { ...defaultProps, ...props } }
23
- );
20
+ wrapper = shallowMount(Truncate, {
21
+ propsData: { ...defaultProps, ...props },
22
+ });
24
23
  };
25
24
 
26
25
  describe('All', () => {
@@ -5,7 +5,7 @@ jest.useFakeTimers();
5
5
 
6
6
  describe('hover load directive', () => {
7
7
  let wrapper;
8
- const findTarget = () => wrapper.find('.target');
8
+ const findTarget = () => wrapper.findComponent('.target');
9
9
 
10
10
  const createComponent = (handleLoad) => {
11
11
  const component = {
@@ -17,20 +17,18 @@ describe('safe link directive', () => {
17
17
  mountFn = shallowMount,
18
18
  } = {}) => {
19
19
  const component = {
20
+ props: {
21
+ href: { type: String },
22
+ safeLinkConfig: { type: Object },
23
+ },
20
24
  directives: {
21
25
  SafeLink: SafeLinkDirective,
22
26
  },
23
27
  components,
24
- data() {
25
- return {
26
- href,
27
- safeLinkConfig,
28
- };
29
- },
30
28
  template,
31
29
  };
32
30
 
33
- wrapper = mountFn(component);
31
+ wrapper = mountFn(component, { propsData: { href, safeLinkConfig } });
34
32
  };
35
33
 
36
34
  describe('default', () => {
@@ -64,7 +62,7 @@ describe('safe link directive', () => {
64
62
  describe('valid urls', () => {
65
63
  const validUrls = [...absoluteUrls, ...relativeUrls, ...encodedJavaScriptUrls];
66
64
  /* Note:
67
- /* Encoded JavaScript URLs are safe urls in Vue context, since
65
+ /* Encoded JavaScript URLs are safe urls in Vue context, since
68
66
  /* Vue attribute bindings are also automatically escaped
69
67
  /* https://vuejs.org/v2/guide/security.html#Injecting-URLs
70
68
  */
@@ -99,13 +97,13 @@ describe('safe link directive', () => {
99
97
  expect(wrapper.attributes('href')).toBe('about:blank');
100
98
 
101
99
  // set href to a valid url
102
- wrapper.setData({ href: 'https://gitlab.com' });
103
- await Vue.nextTick();
100
+ await wrapper.setProps({ href: 'https://gitlab.com' });
104
101
  expect(wrapper.attributes('href')).toBe('https://gitlab.com');
105
102
 
106
103
  // set href to back to an invalid url
107
- wrapper.setData({ href: javascriptUrls[1] });
104
+ await wrapper.setProps({ href: javascriptUrls[1] });
108
105
  await Vue.nextTick();
106
+
109
107
  expect(wrapper.attributes('href')).toBe('about:blank');
110
108
  });
111
109
 
@@ -123,12 +121,12 @@ describe('safe link directive', () => {
123
121
  expect(wrapper.attributes('href')).toBe(url);
124
122
 
125
123
  // set href to a valid url
126
- wrapper.setData({ href: 'https://gitlab.com' });
124
+ await wrapper.setProps({ href: 'https://gitlab.com' });
127
125
  await Vue.nextTick();
128
126
  expect(wrapper.attributes('href')).toBe('https://gitlab.com');
129
127
 
130
128
  // set href to back to an invalid url
131
- wrapper.setData({ href: url });
129
+ await wrapper.setProps({ href: url });
132
130
  await Vue.nextTick();
133
131
  expect(wrapper.attributes('href')).toBe(url);
134
132
  });
@@ -6633,12 +6633,12 @@
6633
6633
  }
6634
6634
  }
6635
6635
  .gl-sm-pr-2 {
6636
- @include gl-media-breakpoint-down(sm) {
6636
+ @include gl-media-breakpoint-up(sm) {
6637
6637
  padding-right: $gl-spacing-scale-2;
6638
6638
  }
6639
6639
  }
6640
6640
  .gl-sm-pr-2\! {
6641
- @include gl-media-breakpoint-down(sm) {
6641
+ @include gl-media-breakpoint-up(sm) {
6642
6642
  padding-right: $gl-spacing-scale-2 !important;
6643
6643
  }
6644
6644
  }
@@ -6762,16 +6762,6 @@
6762
6762
  padding-right: $gl-spacing-scale-1 !important;
6763
6763
  }
6764
6764
  }
6765
- .gl-md-pr-2 {
6766
- @include gl-media-breakpoint-up(md) {
6767
- padding-right: $gl-spacing-scale-2;
6768
- }
6769
- }
6770
- .gl-md-pr-2\! {
6771
- @include gl-media-breakpoint-up(md) {
6772
- padding-right: $gl-spacing-scale-2 !important;
6773
- }
6774
- }
6775
6765
  .gl-md-pr-3 {
6776
6766
  @include gl-media-breakpoint-up(md) {
6777
6767
  padding-right: $gl-spacing-scale-3;
@@ -1061,8 +1061,7 @@
1061
1061
  */
1062
1062
 
1063
1063
  @mixin gl-sm-pr-2 {
1064
- // stylelint-disable-next-line @gitlab/no-gl-media-breakpoint-down
1065
- @include gl-media-breakpoint-down(sm) {
1064
+ @include gl-media-breakpoint-up(sm) {
1066
1065
  @include gl-pr-2;
1067
1066
  }
1068
1067
  }
@@ -1143,12 +1142,6 @@
1143
1142
  }
1144
1143
  }
1145
1144
 
1146
- @mixin gl-md-pr-2 {
1147
- @include gl-media-breakpoint-up(md) {
1148
- @include gl-pr-2;
1149
- }
1150
- }
1151
-
1152
1145
  @mixin gl-md-pr-3 {
1153
1146
  @include gl-media-breakpoint-up(md) {
1154
1147
  @include gl-pr-3;