@gitlab/ui 32.43.3 → 32.46.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 (166) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/config.js +15 -3
  3. package/dist/components/base/avatar/avatar.documentation.js +2 -5
  4. package/dist/components/base/avatar_link/avatar_link.documentation.js +2 -5
  5. package/dist/components/base/form/form_group/form_group.js +11 -1
  6. package/dist/components/base/form/form_input/form_input.documentation.js +2 -27
  7. package/dist/components/base/form/form_input/form_input.js +23 -6
  8. package/dist/components/base/form/form_text/form_text.documentation.js +1 -4
  9. package/dist/components/base/label/label.documentation.js +2 -9
  10. package/dist/components/base/label/label.js +23 -1
  11. package/dist/components/base/pagination/pagination.documentation.js +2 -85
  12. package/dist/components/base/pagination/pagination.js +76 -0
  13. package/dist/components/base/segmented_control/segmented_control.documentation.js +2 -14
  14. package/dist/components/base/segmented_control/segmented_control.js +6 -0
  15. package/dist/components/base/skeleton_loader/skeleton_loader.documentation.js +2 -28
  16. package/dist/components/base/skeleton_loader/skeleton_loader.js +30 -0
  17. package/dist/components/charts/chart/chart.js +17 -4
  18. package/dist/components/charts/discrete_scatter/discrete_scatter.documentation.js +1 -7
  19. package/dist/components/charts/heatmap/heatmap.js +1 -9
  20. package/dist/components/charts/sparkline/sparkline.js +1 -1
  21. package/dist/components/charts/stacked_column/stacked_column.documentation.js +2 -5
  22. package/dist/config.js +15 -3
  23. package/dist/index.css +1 -1
  24. package/dist/index.css.map +1 -1
  25. package/dist/utility_classes.css +1 -1
  26. package/dist/utility_classes.css.map +1 -1
  27. package/documentation/documented_stories.js +9 -0
  28. package/package.json +11 -10
  29. package/src/components/base/alert/alert.spec.js +2 -2
  30. package/src/components/base/avatar/avatar.documentation.js +0 -2
  31. package/src/components/base/avatar/avatar.md +0 -2
  32. package/src/components/base/avatar/avatar.spec.js +1 -2
  33. package/src/components/base/avatar/avatar.stories.js +88 -101
  34. package/src/components/base/avatar_link/avatar_link.documentation.js +0 -2
  35. package/src/components/base/avatar_link/avatar_link.md +4 -7
  36. package/src/components/base/avatar_link/avatar_link.stories.js +66 -54
  37. package/src/components/base/filtered_search/filtered_search.spec.js +35 -35
  38. package/src/components/base/filtered_search/filtered_search_term.spec.js +1 -1
  39. package/src/components/base/form/form_group/form_group.scss +4 -0
  40. package/src/components/base/form/form_group/form_group.spec.js +66 -64
  41. package/src/components/base/form/form_group/form_group.stories.js +36 -13
  42. package/src/components/base/form/form_group/form_group.vue +15 -2
  43. package/src/components/base/form/form_input/form_input.documentation.js +0 -31
  44. package/src/components/base/form/form_input/form_input.md +0 -2
  45. package/src/components/base/form/form_input/form_input.stories.js +50 -42
  46. package/src/components/base/form/form_input/form_input.vue +23 -6
  47. package/src/components/base/form/form_input_group/form_input_group.spec.js +1 -3
  48. package/src/components/base/form/form_text/form_text.documentation.js +0 -2
  49. package/src/components/base/form/form_text/form_text.md +1 -3
  50. package/src/components/base/form/form_text/form_text.stories.js +20 -8
  51. package/src/components/base/icon/icon.spec.js +1 -4
  52. package/src/components/base/infinite_scroll/infinite_scroll.spec.js +1 -4
  53. package/src/components/base/label/label.documentation.js +2 -12
  54. package/src/components/base/label/label.md +2 -7
  55. package/src/components/base/label/label.stories.js +66 -92
  56. package/src/components/base/label/label.vue +22 -2
  57. package/src/components/base/modal/modal.spec.js +19 -23
  58. package/src/components/base/paginated_list/__snapshots__/paginated_list.spec.js.snap +10 -10
  59. package/src/components/base/pagination/pagination.documentation.js +0 -100
  60. package/src/components/base/pagination/pagination.md +5 -9
  61. package/src/components/base/pagination/pagination.spec.js +1 -4
  62. package/src/components/base/pagination/pagination.stories.js +109 -117
  63. package/src/components/base/pagination/pagination.vue +85 -0
  64. package/src/components/base/search_box_by_click/search_box_by_click.spec.js +1 -5
  65. package/src/components/base/segmented_control/segmented_control.documentation.js +0 -15
  66. package/src/components/base/segmented_control/segmented_control.md +0 -2
  67. package/src/components/base/segmented_control/segmented_control.stories.js +46 -36
  68. package/src/components/base/segmented_control/segmented_control.vue +5 -0
  69. package/src/components/base/skeleton_loader/skeleton_loader.documentation.js +0 -27
  70. package/src/components/base/skeleton_loader/skeleton_loader.md +0 -2
  71. package/src/components/base/skeleton_loader/skeleton_loader.stories.js +23 -9
  72. package/src/components/base/skeleton_loader/skeleton_loader.vue +24 -0
  73. package/src/components/base/sorting/sorting.spec.js +1 -4
  74. package/src/components/base/toast/toast.spec.js +4 -6
  75. package/src/components/base/token/token.spec.js +1 -4
  76. package/src/components/base/token_selector/token_container.spec.js +2 -3
  77. package/src/components/charts/chart/chart.spec.js +33 -4
  78. package/src/components/charts/chart/chart.vue +16 -4
  79. package/src/components/charts/discrete_scatter/discrete_scatter.documentation.js +0 -5
  80. package/src/components/charts/discrete_scatter/discrete_scatter.stories.js +34 -46
  81. package/src/components/charts/gauge/gauge.spec.js +7 -7
  82. package/src/components/charts/heatmap/heatmap.vue +2 -9
  83. package/src/components/charts/sparkline/sparkline.spec.js +1 -4
  84. package/src/components/charts/sparkline/sparkline.vue +7 -1
  85. package/src/components/charts/stacked_column/stacked_column.documentation.js +0 -2
  86. package/src/components/charts/stacked_column/stacked_column.md +0 -2
  87. package/src/components/charts/stacked_column/stacked_column.stories.js +74 -99
  88. package/src/components/utilities/friendly_wrap/friendly_wrap.spec.js +1 -4
  89. package/src/components/utilities/intersperse/intersperse.spec.js +1 -4
  90. package/src/directives/hover_load/hover_load.spec.js +2 -13
  91. package/src/directives/outside/outside.spec.js +1 -6
  92. package/src/directives/resize_observer/resize_observer.spec.js +4 -10
  93. package/src/scss/storybook.scss +8 -0
  94. package/src/scss/utilities.scss +8 -0
  95. package/src/scss/utility-mixins/transform.scss +4 -0
  96. package/dist/components/base/avatar/examples/avatar.fallback.example.js +0 -38
  97. package/dist/components/base/avatar/examples/avatar.image.example.js +0 -38
  98. package/dist/components/base/avatar/examples/avatar.rect.example.js +0 -38
  99. package/dist/components/base/avatar/examples/avatar.tooltip.example.js +0 -38
  100. package/dist/components/base/avatar/examples/index.js +0 -31
  101. package/dist/components/base/avatar_link/examples/avatar.link.example.js +0 -38
  102. package/dist/components/base/avatar_link/examples/index.js +0 -13
  103. package/dist/components/base/form/form_input/examples/form_input/form_input.text.example.js +0 -38
  104. package/dist/components/base/form/form_input/examples/form_input/form_input.text_disabled.example.js +0 -38
  105. package/dist/components/base/form/form_input/examples/form_input/form_input.text_reactive.example.js +0 -57
  106. package/dist/components/base/form/form_input/examples/form_input/index.js +0 -22
  107. package/dist/components/base/form/form_text/examples/form_text.basic.example.js +0 -38
  108. package/dist/components/base/form/form_text/examples/index.js +0 -13
  109. package/dist/components/base/label/examples/index.js +0 -19
  110. package/dist/components/base/label/examples/label.basic.example.js +0 -38
  111. package/dist/components/base/label/examples/label.scoped.example.js +0 -38
  112. package/dist/components/base/pagination/examples/index.js +0 -37
  113. package/dist/components/base/pagination/examples/pagination.basic.example.js +0 -45
  114. package/dist/components/base/pagination/examples/pagination.compact.example.js +0 -58
  115. package/dist/components/base/pagination/examples/pagination.double_truncation.example.js +0 -45
  116. package/dist/components/base/pagination/examples/pagination.event.example.js +0 -51
  117. package/dist/components/base/pagination/examples/pagination.links.example.js +0 -45
  118. package/dist/components/base/segmented_control/examples/index.js +0 -19
  119. package/dist/components/base/segmented_control/examples/segmented_control.basic.example.js +0 -65
  120. package/dist/components/base/segmented_control/examples/segmented_control.whitespace.example.js +0 -55
  121. package/dist/components/base/skeleton_loader/examples/ci_header_skeleton.basic.example.js +0 -38
  122. package/dist/components/base/skeleton_loader/examples/default_skeleton.basic.example.js +0 -38
  123. package/dist/components/base/skeleton_loader/examples/default_skeleton_custom_props.basic.example.js +0 -38
  124. package/dist/components/base/skeleton_loader/examples/index.js +0 -37
  125. package/dist/components/base/skeleton_loader/examples/issue_card_skeleton.basic.example.js +0 -38
  126. package/dist/components/base/skeleton_loader/examples/job_log_skeleton.basic.example.js +0 -38
  127. package/dist/components/charts/discrete_scatter/examples/discrete_scatter.basic.example.js +0 -51
  128. package/dist/components/charts/discrete_scatter/examples/index.js +0 -13
  129. package/dist/components/charts/stacked_column/examples/index.js +0 -13
  130. package/dist/components/charts/stacked_column/examples/stacked_column.basic.example.js +0 -46
  131. package/src/components/base/avatar/examples/avatar.fallback.example.vue +0 -3
  132. package/src/components/base/avatar/examples/avatar.image.example.vue +0 -3
  133. package/src/components/base/avatar/examples/avatar.rect.example.vue +0 -6
  134. package/src/components/base/avatar/examples/avatar.tooltip.example.vue +0 -3
  135. package/src/components/base/avatar/examples/index.js +0 -36
  136. package/src/components/base/avatar_link/examples/avatar.link.example.vue +0 -5
  137. package/src/components/base/avatar_link/examples/index.js +0 -15
  138. package/src/components/base/form/form_input/examples/form_input/form_input.text.example.vue +0 -3
  139. package/src/components/base/form/form_input/examples/form_input/form_input.text_disabled.example.vue +0 -3
  140. package/src/components/base/form/form_input/examples/form_input/form_input.text_reactive.example.vue +0 -24
  141. package/src/components/base/form/form_input/examples/form_input/index.js +0 -26
  142. package/src/components/base/form/form_text/examples/form_text.basic.example.vue +0 -5
  143. package/src/components/base/form/form_text/examples/index.js +0 -15
  144. package/src/components/base/label/examples/index.js +0 -22
  145. package/src/components/base/label/examples/label.basic.example.vue +0 -3
  146. package/src/components/base/label/examples/label.scoped.example.vue +0 -3
  147. package/src/components/base/pagination/examples/index.js +0 -43
  148. package/src/components/base/pagination/examples/pagination.basic.example.vue +0 -17
  149. package/src/components/base/pagination/examples/pagination.compact.example.vue +0 -33
  150. package/src/components/base/pagination/examples/pagination.double_truncation.example.vue +0 -11
  151. package/src/components/base/pagination/examples/pagination.event.example.vue +0 -26
  152. package/src/components/base/pagination/examples/pagination.links.example.vue +0 -18
  153. package/src/components/base/segmented_control/examples/index.js +0 -22
  154. package/src/components/base/segmented_control/examples/segmented_control.basic.example.vue +0 -19
  155. package/src/components/base/segmented_control/examples/segmented_control.whitespace.example.vue +0 -18
  156. package/src/components/base/skeleton_loader/examples/ci_header_skeleton.basic.example.vue +0 -10
  157. package/src/components/base/skeleton_loader/examples/default_skeleton.basic.example.vue +0 -3
  158. package/src/components/base/skeleton_loader/examples/default_skeleton_custom_props.basic.example.vue +0 -9
  159. package/src/components/base/skeleton_loader/examples/index.js +0 -44
  160. package/src/components/base/skeleton_loader/examples/issue_card_skeleton.basic.example.vue +0 -26
  161. package/src/components/base/skeleton_loader/examples/job_log_skeleton.basic.example.vue +0 -13
  162. package/src/components/charts/discrete_scatter/discrete_scatter.md +0 -1
  163. package/src/components/charts/discrete_scatter/examples/discrete_scatter.basic.example.vue +0 -31
  164. package/src/components/charts/discrete_scatter/examples/index.js +0 -15
  165. package/src/components/charts/stacked_column/examples/index.js +0 -15
  166. package/src/components/charts/stacked_column/examples/stacked_column.basic.example.vue +0 -18
@@ -1,12 +1,9 @@
1
- import { shallowMount, createLocalVue } from '@vue/test-utils';
1
+ import { shallowMount } from '@vue/test-utils';
2
2
  import GlDropdownItem from '../dropdown/dropdown_item.vue';
3
3
  import GlFormInput from '../form/form_input/form_input.vue';
4
4
  import SearchBoxByClick from './search_box_by_click.vue';
5
5
  import ClearIcon from '~/components/shared_components/clear_icon_button/clear_icon_button.vue';
6
6
 
7
- const localVue = createLocalVue();
8
- localVue.directive('gl-tooltip', {});
9
-
10
7
  const GlFormInputGroupStub = {
11
8
  template: `
12
9
  <div>
@@ -24,7 +21,6 @@ describe('search box by click component', () => {
24
21
  wrapper = shallowMount(SearchBoxByClick, {
25
22
  propsData,
26
23
  stubs: { GlFormInputGroup: GlFormInputGroupStub },
27
- localVue,
28
24
  });
29
25
  };
30
26
 
@@ -1,21 +1,6 @@
1
- import examples from './examples';
2
1
  import description from './segmented_control.md';
3
2
 
4
3
  export default {
5
4
  followsDesignSystem: false,
6
5
  description,
7
- examples,
8
- bootstrapComponent: 'b-form-radio-group',
9
- events: [
10
- {
11
- event: 'input',
12
- description: 'Emitted when the selection changes',
13
- args: [
14
- {
15
- arg: 'checked',
16
- description: 'The selected option',
17
- },
18
- ],
19
- },
20
- ],
21
6
  };
@@ -1,3 +1 @@
1
- # Segmented control
2
-
3
1
  Button group of equal options where only one can be selected and active.
@@ -1,52 +1,62 @@
1
- import { withKnobs, object, text } from '@storybook/addon-knobs';
2
- import { documentedStoriesOf } from '../../../../documentation/documented_stories';
3
1
  import { GlSegmentedControl } from '../../../../index';
4
2
  import readme from './segmented_control.md';
5
3
 
6
- const components = {
7
- GlSegmentedControl,
8
- };
9
-
10
4
  const defaultOptions = [
11
5
  { value: 'Pizza', text: 'Pizza' },
12
6
  { value: 'Tacos', text: 'Tacos' },
13
7
  { value: 'Burger', text: 'Burger', disabled: true },
14
8
  ];
15
9
 
16
- function generateProps({ options = defaultOptions } = {}) {
17
- const props = {
18
- options: {
19
- type: Array,
20
- default: object('options', options),
21
- },
22
- initSelected: {
23
- type: String,
24
- default: text('selected value', 'Tacos'),
25
- },
26
- };
27
-
28
- return props;
29
- }
10
+ const generateProps = ({ options = defaultOptions, initSelected = 'Tacos' } = {}) => ({
11
+ options,
12
+ initSelected,
13
+ });
30
14
 
31
- documentedStoriesOf('base/segmented control', readme)
32
- .addDecorator(withKnobs)
33
- .add('default', () => ({
34
- props: generateProps(),
35
- data() {
36
- return {
37
- selected: this.initSelected,
38
- };
39
- },
40
- watch: {
41
- initSelected(val) {
42
- this.selected = val;
43
- },
15
+ export const Default = (args, { argTypes }) => ({
16
+ components: { GlSegmentedControl },
17
+ props: Object.keys(argTypes),
18
+ data() {
19
+ return {
20
+ selected: this.initSelected,
21
+ };
22
+ },
23
+ watch: {
24
+ initSelected(val) {
25
+ this.selected = val;
44
26
  },
45
- components,
46
- template: `
27
+ },
28
+ template: `
47
29
  <gl-segmented-control
48
30
  :options="options"
49
31
  v-model="selected"
50
32
  />
51
33
  `,
52
- }));
34
+ });
35
+ Default.args = generateProps();
36
+
37
+ export default {
38
+ title: 'base/segmented control',
39
+ component: GlSegmentedControl,
40
+ parameters: {
41
+ bootstrapComponent: 'b-form-radio-group',
42
+ knobs: { disable: true },
43
+ docs: {
44
+ description: {
45
+ component: readme,
46
+ },
47
+ },
48
+ },
49
+ argTypes: {
50
+ initSelected: {
51
+ options: Object.values(defaultOptions)
52
+ .filter(({ disabled }) => !disabled)
53
+ .map(({ value }) => value),
54
+ control: {
55
+ type: 'radio',
56
+ },
57
+ table: {
58
+ disable: true,
59
+ },
60
+ },
61
+ },
62
+ };
@@ -50,6 +50,11 @@ export default {
50
50
  if (this.enabledOptions.length) {
51
51
  const suggestion =
52
52
  oldValue && this.isValidValue(oldValue) ? oldValue : this.enabledOptions[0].value;
53
+ /**
54
+ * Emitted when the selection changes
55
+ * @event input
56
+ * @argument checked The selected option
57
+ */
53
58
  this.$emit('input', suggestion);
54
59
  }
55
60
  }
@@ -1,33 +1,6 @@
1
- import examples from './examples';
2
1
  import * as description from './skeleton_loader.md';
3
2
 
4
3
  export default {
5
4
  followsDesignSystem: true,
6
5
  description,
7
- examples,
8
- propsInfo: {
9
- width: {
10
- additionalInfo:
11
- 'It will be set in the viewbox attr in the <svg />. Defaults to 400 when skeleton is passed via the slot. Defaults to 235 when default skeleton is used',
12
- },
13
- height: {
14
- additionalInfo:
15
- 'It will be set in the viewbox attr in the <svg />. Defaults to 130 when skeleton is passed via the slot. Defaults to the combined height of the lines when default skeleton is used',
16
- },
17
- uniqueKey: {
18
- additionalInfo: 'Defaults to unique id',
19
- },
20
- preserveAspectRatio: {
21
- additionalInfo: 'Aspect ratio option of <svg/>',
22
- },
23
- baseUrl: {
24
- additionalInfo: `Required if you're using <base url="/" /> in your <head />. Defaults to an empty string. This prop is common used as: <gl-skeleton-loader :base-url="$route.fullPath" /> which will fill the SVG attribute with the relative path.`,
25
- },
26
- lines: {
27
- additionalInfo: 'Number of lines to show when using the default skeleton',
28
- },
29
- equalWidthLines: {
30
- additionalInfo: 'If the default skeleton lines should all be the same width',
31
- },
32
- },
33
6
  };
@@ -1,5 +1,3 @@
1
- ## Usage
2
-
3
1
  Skeleton loaders are to be used when pages or sections can be progressively populated with content,
4
2
  such as text and images, as they become available. Generally speaking the first batch of content
5
3
  will be the lightest to load and is followed by secondary and tertiary content batches. Each loading
@@ -1,14 +1,9 @@
1
- import { documentedStoriesOf } from '../../../../documentation/documented_stories';
2
1
  import { GlSkeletonLoader } from '../../../../index';
3
2
  import readme from './skeleton_loader.md';
4
3
 
5
- const components = {
6
- GlSkeletonLoader,
7
- };
8
-
9
- documentedStoriesOf('base/skeleton-loader', readme).add('default', () => ({
10
- props: {},
11
- components,
4
+ const Template = (args) => ({
5
+ components: { GlSkeletonLoader },
6
+ props: Object.keys(args),
12
7
  template: `
13
8
  <div style="background: #fff; border: 1px solid #dfdfdf; box-shadow: 0 1px 2px rgba(0,0,0,0.1); width: 359px; height: 135px; padding: 1rem; border-radius: 0.25rem;">
14
9
  <div style="width: 327px; height: 102px;">
@@ -24,4 +19,23 @@ documentedStoriesOf('base/skeleton-loader', readme).add('default', () => ({
24
19
  </gl-skeleton-loader>
25
20
  </div>
26
21
  </div>`,
27
- }));
22
+ });
23
+
24
+ export const Default = Template.bind({});
25
+ Default.args = {};
26
+
27
+ export default {
28
+ title: 'base/skeleton-loader',
29
+ component: GlSkeletonLoader,
30
+ parameters: {
31
+ knobs: { disable: true },
32
+ docs: {
33
+ description: {
34
+ component: readme,
35
+ },
36
+ },
37
+ controls: {
38
+ disable: true,
39
+ },
40
+ },
41
+ };
@@ -13,36 +13,60 @@ export default {
13
13
  name: 'GlSkeletonLoader',
14
14
  functional: true,
15
15
  props: {
16
+ /**
17
+ * It will be set in the viewbox attr in the <svg />.
18
+ * Defaults to 400 when skeleton is passed via the slot. Defaults to 235 when default skeleton is used
19
+ */
16
20
  width: {
17
21
  type: Number,
18
22
  default: null,
19
23
  required: false,
20
24
  },
25
+ /**
26
+ * It will be set in the viewbox attr in the <svg />. Defaults to 130 when skeleton is passed via the slot.
27
+ * Defaults to the combined height of the lines when default skeleton is used
28
+ */
21
29
  height: {
22
30
  type: Number,
23
31
  default: null,
24
32
  required: false,
25
33
  },
34
+ /**
35
+ * Aspect ratio option of <svg/>
36
+ */
26
37
  preserveAspectRatio: {
27
38
  type: String,
28
39
  default: 'xMidYMid meet',
29
40
  required: false,
30
41
  },
42
+ /**
43
+ * Required if you're using <base url="/" /> in your <head />. Defaults to an empty string.
44
+ * This prop is common used as: <gl-skeleton-loader :base-url="$route.fullPath" /> which will fill the SVG attribute with the relative path.
45
+ */
31
46
  baseUrl: {
32
47
  type: String,
33
48
  default: '',
34
49
  required: false,
35
50
  },
51
+ /**
52
+ * Defaults to unique id
53
+ */
36
54
  uniqueKey: {
37
55
  type: String,
38
56
  default: () => uid(),
39
57
  required: false,
40
58
  },
59
+ /**
60
+ * Number of lines to show when using the default skeleton
61
+ */
41
62
  lines: {
42
63
  type: Number,
43
64
  default: 3,
44
65
  required: false,
45
66
  },
67
+ /**
68
+ * If the default skeleton lines should all be the same width
69
+ */
46
70
  equalWidthLines: {
47
71
  type: Boolean,
48
72
  default: false,
@@ -1,12 +1,10 @@
1
- import { mount, createLocalVue } from '@vue/test-utils';
1
+ import { mount } from '@vue/test-utils';
2
2
  import GlDropdown from '../dropdown/dropdown.vue';
3
3
  import GlDropdownItem from '../dropdown/dropdown_item.vue';
4
4
  import GlIcon from '../icon/icon.vue';
5
5
  import GlSorting from './sorting.vue';
6
6
  import GlSortingItem from './sorting_item.vue';
7
7
 
8
- const localVue = createLocalVue();
9
-
10
8
  describe('sorting component', () => {
11
9
  let wrapper;
12
10
 
@@ -35,7 +33,6 @@ describe('sorting component', () => {
35
33
  '<gl-sorting-item>Third item</gl-sorting-item>',
36
34
  ],
37
35
  },
38
- localVue,
39
36
  propsData: {
40
37
  ...defaultProps,
41
38
  ...propsData,
@@ -1,8 +1,8 @@
1
- import { createLocalVue, mount } from '@vue/test-utils';
1
+ import Vue from 'vue';
2
+ import { mount } from '@vue/test-utils';
2
3
  import GlToast from './toast';
3
4
 
4
- const localVue = createLocalVue();
5
- localVue.use(GlToast);
5
+ Vue.use(GlToast);
6
6
  const Component = {
7
7
  template: `<div />`,
8
8
  };
@@ -11,9 +11,7 @@ describe('GlToast', () => {
11
11
  let wrapper;
12
12
 
13
13
  beforeEach(() => {
14
- wrapper = mount(Component, {
15
- localVue,
16
- });
14
+ wrapper = mount(Component);
17
15
  });
18
16
 
19
17
  it('attaches $toast propery', () => {
@@ -1,9 +1,7 @@
1
- import { shallowMount, createLocalVue } from '@vue/test-utils';
1
+ import { shallowMount } from '@vue/test-utils';
2
2
  import CloseButton from '../../shared_components/close_button/close_button.vue';
3
3
  import Token from './token.vue';
4
4
 
5
- const localVue = createLocalVue();
6
-
7
5
  const findIcon = (wrapper) => wrapper.findComponent(CloseButton);
8
6
 
9
7
  describe('Token component', () => {
@@ -13,7 +11,6 @@ describe('Token component', () => {
13
11
 
14
12
  const createComponent = (propsData) =>
15
13
  shallowMount(Token, {
16
- localVue,
17
14
  propsData,
18
15
  });
19
16
 
@@ -40,12 +40,12 @@ describe('GlTokenContainer', () => {
40
40
  };
41
41
 
42
42
  const findTokenByName = (name) => {
43
- const tokenWrappers = wrapper.findAllComponents({ ref: 'tokens' });
43
+ const tokenWrappers = wrapper.findAll('[role=option]');
44
44
 
45
45
  return tokenWrappers.wrappers.find((tokenWrapper) => tokenWrapper.text() === name);
46
46
  };
47
47
 
48
- const findTokenContainer = () => wrapper.find({ ref: 'tokenContainer' });
48
+ const findTokenContainer = () => wrapper.findComponent({ ref: 'tokenContainer' });
49
49
 
50
50
  const blurActiveElement = () => document.activeElement?.blur?.();
51
51
 
@@ -173,7 +173,6 @@ describe('GlTokenContainer', () => {
173
173
  describe('when escape key is pressed', () => {
174
174
  it('fires `cancel-focus` event', async () => {
175
175
  await setup(0, keyboard.escape);
176
-
177
176
  expect(wrapper.emitted('cancel-focus')).toBeTruthy();
178
177
  });
179
178
  });
@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils';
2
2
  import * as echarts from 'echarts';
3
3
  import Chart from './chart.vue';
4
4
  import createTheme from '~/utils/charts/theme';
5
+ import { useMockResizeObserver } from '~helpers/mock_dom_observer';
5
6
 
6
7
  const defaultHeight = 400;
7
8
 
@@ -21,11 +22,12 @@ describe('chart component', () => {
21
22
  const themeName = 'gitlab';
22
23
  let wrapper;
23
24
 
24
- beforeEach(() => {
25
+ const { trigger: triggerResize } = useMockResizeObserver();
26
+
27
+ it('initializes chart using $refs.chart', async () => {
25
28
  wrapper = shallowMount(...mountArgs);
26
- });
29
+ await wrapper.vm.$nextTick();
27
30
 
28
- it('initializes chart using $refs.chart', () => {
29
31
  expect(echarts.init).toHaveBeenCalledWith(
30
32
  wrapper.findComponent({ ref: 'chart' }).element,
31
33
  themeName,
@@ -37,11 +39,34 @@ describe('chart component', () => {
37
39
  );
38
40
  });
39
41
 
40
- it('emits "created" after initializing chart', () => {
42
+ it('does not resize the chart when responsive = false', async () => {
43
+ wrapper = shallowMount(...mountArgs);
44
+ await wrapper.vm.$nextTick();
45
+ // initial call when chart gets created
46
+ expect(wrapper.vm.chart.resize).toHaveBeenCalledTimes(1);
47
+
48
+ triggerResize(wrapper.element);
49
+ expect(wrapper.vm.chart.resize).toHaveBeenCalledTimes(1);
50
+ });
51
+
52
+ it('resizes the chart when responsive = true', async () => {
53
+ wrapper = shallowMount(Chart, { propsData: { options: {}, responsive: true } });
54
+ await wrapper.vm.$nextTick();
55
+ expect(wrapper.vm.chart.resize).toHaveBeenCalledTimes(1);
56
+
57
+ triggerResize(wrapper.element);
58
+
59
+ expect(wrapper.vm.chart.resize).toHaveBeenCalledTimes(2);
60
+ });
61
+
62
+ it('emits "created" after initializing chart', async () => {
63
+ wrapper = shallowMount(...mountArgs);
64
+ await wrapper.vm.$nextTick();
41
65
  expect(wrapper.emitted('created')).toEqual([[wrapper.vm.chart]]);
42
66
  });
43
67
 
44
68
  it('uses GitLab theme', () => {
69
+ wrapper = shallowMount(...mountArgs);
45
70
  const [firstRegisterThemeCall] = echarts.registerTheme.mock.calls;
46
71
  expect(firstRegisterThemeCall[0]).toBe(themeName);
47
72
  expect(JSON.stringify(firstRegisterThemeCall[1])).toEqual(JSON.stringify(createTheme()));
@@ -87,6 +112,10 @@ describe('chart component', () => {
87
112
  });
88
113
 
89
114
  describe('methods', () => {
115
+ beforeEach(() => {
116
+ wrapper = shallowMount(...mountArgs);
117
+ });
118
+
90
119
  describe('draw method', () => {
91
120
  it('sets chart options', () => {
92
121
  wrapper.vm.draw();
@@ -2,8 +2,12 @@
2
2
  import * as echarts from 'echarts';
3
3
  import { defaultHeight, defaultWidth, validRenderers } from '../../../utils/charts/config';
4
4
  import createTheme, { themeName } from '../../../utils/charts/theme';
5
+ import { GlResizeObserverDirective } from '../../../directives/resize_observer/resize_observer';
5
6
 
6
7
  export default {
8
+ directives: {
9
+ resizeObserver: GlResizeObserverDirective,
10
+ },
7
11
  props: {
8
12
  options: {
9
13
  type: Object,
@@ -42,6 +46,11 @@ export default {
42
46
  return validRenderers.includes(renderer);
43
47
  },
44
48
  },
49
+ responsive: {
50
+ type: Boolean,
51
+ required: false,
52
+ default: false,
53
+ },
45
54
  },
46
55
  data() {
47
56
  return {
@@ -80,7 +89,7 @@ export default {
80
89
  echarts.connect(this.groupId);
81
90
  }
82
91
 
83
- this.chart.on('click', this.clickHandler);
92
+ this.chart.on('click', this.handleClick);
84
93
  /**
85
94
  * Emitted after calling `echarts.init`
86
95
  */
@@ -89,7 +98,7 @@ export default {
89
98
  this.setChartSize();
90
99
  },
91
100
  beforeDestroy() {
92
- this.chart.off('click', this.clickHandler);
101
+ this.chart.off('click', this.handleClick);
93
102
  },
94
103
  methods: {
95
104
  draw() {
@@ -105,7 +114,7 @@ export default {
105
114
  height: this.height || defaultHeight,
106
115
  });
107
116
  },
108
- clickHandler(params) {
117
+ handleClick(params) {
109
118
  /**
110
119
  * Emitted when clicked on a data item in the chart (e.g., a bar/column).
111
120
  *
@@ -114,10 +123,13 @@ export default {
114
123
  */
115
124
  this.$emit('chartItemClicked', { chart: this.chart, params });
116
125
  },
126
+ handleResize() {
127
+ if (this.responsive) this.chart.resize();
128
+ },
117
129
  },
118
130
  };
119
131
  </script>
120
132
 
121
133
  <template>
122
- <div ref="chart"></div>
134
+ <div ref="chart" v-resize-observer="handleResize"></div>
123
135
  </template>
@@ -1,8 +1,3 @@
1
- import description from './discrete_scatter.md';
2
- import examples from './examples';
3
-
4
1
  export default {
5
2
  followsDesignSystem: true,
6
- description,
7
- examples,
8
3
  };
@@ -1,13 +1,9 @@
1
- import { withKnobs, object, text } from '@storybook/addon-knobs';
2
1
  import { GlDiscreteScatterChart } from '../../../../charts';
3
- import { documentedStoriesOf } from '../../../../documentation/documented_stories';
4
- import readme from './discrete_scatter.md';
5
2
 
6
- const components = {
7
- GlDiscreteScatterChart,
8
- };
9
-
10
- const template = `
3
+ const Template = (args, { argTypes }) => ({
4
+ components: { GlDiscreteScatterChart },
5
+ props: Object.keys(argTypes),
6
+ template: `
11
7
  <gl-discrete-scatter-chart
12
8
  :data="data"
13
9
  :option="option"
@@ -15,9 +11,10 @@ const template = `
15
11
  :x-axis-title="xAxisTitle"
16
12
  data-testid="discrete-scatter-chart"
17
13
  />
18
- `;
14
+ `,
15
+ });
19
16
 
20
- function generateProps({
17
+ const generateProps = ({
21
18
  data = [
22
19
  {
23
20
  type: 'scatter',
@@ -35,41 +32,32 @@ function generateProps({
35
32
  option = {},
36
33
  yAxisTitle = 'Pushes per day',
37
34
  xAxisTitle = 'Date',
38
- } = {}) {
39
- return {
40
- data: {
41
- default: object('Chart Data', data),
42
- },
43
- option: {
44
- default: object('EChart Options', option),
45
- },
46
- yAxisTitle: {
47
- default: text('Y Axis Title', yAxisTitle),
48
- },
49
- xAxisTitle: {
50
- default: text('X Axis Title', xAxisTitle),
51
- },
52
- };
53
- }
35
+ } = {}) => ({
36
+ data,
37
+ option,
38
+ yAxisTitle,
39
+ xAxisTitle,
40
+ });
41
+
42
+ export const Default = Template.bind({});
43
+ Default.args = generateProps();
54
44
 
55
- documentedStoriesOf('charts/discrete-scatter-chart', readme)
56
- .addDecorator(withKnobs)
57
- .add('default', () => ({
58
- props: generateProps(),
59
- components,
60
- template,
61
- }))
62
- .add('with zoom and scroll', () => ({
63
- props: generateProps({
64
- option: {
65
- dataZoom: [
66
- {
67
- type: 'slider',
68
- startValue: 1,
69
- },
70
- ],
45
+ export const WithZoomAndScroll = Template.bind({});
46
+ WithZoomAndScroll.args = generateProps({
47
+ option: {
48
+ dataZoom: [
49
+ {
50
+ type: 'slider',
51
+ startValue: 1,
71
52
  },
72
- }),
73
- components,
74
- template,
75
- }));
53
+ ],
54
+ },
55
+ });
56
+
57
+ export default {
58
+ title: 'charts/discrete-scatter-chart',
59
+ component: GlDiscreteScatterChart,
60
+ parameters: {
61
+ knobs: { disable: true },
62
+ },
63
+ };