@gitlab/ui 38.8.2 → 38.10.1

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 (64) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/components/base/filtered_search/filtered_search.js +0 -5
  3. package/dist/components/base/form/form_textarea/form_textarea.js +62 -2
  4. package/dist/components/base/popover/popover.js +7 -1
  5. package/dist/components/base/toast/toast.js +5 -2
  6. package/dist/index.css +2 -2
  7. package/dist/index.css.map +1 -1
  8. package/dist/utility_classes.css +1 -1
  9. package/dist/utility_classes.css.map +1 -1
  10. package/dist/utils/constants.js +7 -2
  11. package/package.json +1 -1
  12. package/src/components/base/accordion/accordion.stories.js +2 -4
  13. package/src/components/base/accordion/accordion_item.stories.js +2 -4
  14. package/src/components/base/alert/alert.stories.js +2 -4
  15. package/src/components/base/avatar/avatar.stories.js +3 -9
  16. package/src/components/base/avatar_labeled/avatar_labeled.stories.js +6 -12
  17. package/src/components/base/avatar_link/avatar_link.stories.js +2 -6
  18. package/src/components/base/avatars_inline/avatars_inline.stories.js +2 -4
  19. package/src/components/base/badge/badge.scss +10 -0
  20. package/src/components/base/badge/badge.stories.js +3 -9
  21. package/src/components/base/banner/banner.stories.js +1 -3
  22. package/src/components/base/broadcast_message/broadcast_message.stories.js +4 -8
  23. package/src/components/base/button/button.stories.js +8 -16
  24. package/src/components/base/datepicker/datepicker.stories.js +2 -2
  25. package/src/components/base/daterange_picker/daterange_picker.stories.js +2 -6
  26. package/src/components/base/dropdown/dropdown.stories.js +4 -12
  27. package/src/components/base/dropdown/dropdown_item.stories.js +2 -6
  28. package/src/components/base/filtered_search/filtered_search.vue +0 -5
  29. package/src/components/base/form/form_group/form_group.stories.js +1 -1
  30. package/src/components/base/form/form_input/form_input.stories.js +1 -3
  31. package/src/components/base/form/form_input_group/form_input_group.stories.js +4 -12
  32. package/src/components/base/form/form_radio/form_radio.stories.js +1 -3
  33. package/src/components/base/form/form_select/form_select.stories.js +4 -8
  34. package/src/components/base/form/form_textarea/form_textarea.spec.js +115 -8
  35. package/src/components/base/form/form_textarea/form_textarea.stories.js +21 -0
  36. package/src/components/base/form/form_textarea/form_textarea.vue +73 -8
  37. package/src/components/base/icon/icon.stories.js +4 -8
  38. package/src/components/base/infinite_scroll/infinite_scroll.stories.js +37 -13
  39. package/src/components/base/label/label.stories.js +2 -6
  40. package/src/components/base/link/link.stories.js +2 -4
  41. package/src/components/base/loading_icon/loading_icon.stories.js +4 -8
  42. package/src/components/base/modal/modal.stories.js +16 -32
  43. package/src/components/base/pagination/pagination.stories.js +65 -83
  44. package/src/components/base/path/path.stories.js +2 -6
  45. package/src/components/base/popover/popover.scss +3 -1
  46. package/src/components/base/popover/popover.spec.js +15 -1
  47. package/src/components/base/popover/popover.stories.js +3 -5
  48. package/src/components/base/popover/popover.vue +7 -0
  49. package/src/components/base/progress_bar/progress_bar.stories.js +2 -4
  50. package/src/components/base/search_box_by_click/search_box_by_click.stories.js +1 -3
  51. package/src/components/base/segmented_control/segmented_control.stories.js +1 -3
  52. package/src/components/base/skeleton_loading/skeleton_loading.stories.js +2 -4
  53. package/src/components/base/table/table.stories.js +2 -4
  54. package/src/components/base/toast/toast.js +5 -2
  55. package/src/components/base/toast/toast.spec.js +42 -0
  56. package/src/components/base/toggle/toggle.stories.js +4 -10
  57. package/src/components/base/token/token.stories.js +2 -4
  58. package/src/components/base/token_selector/token_selector.stories.js +2 -4
  59. package/src/components/charts/single_stat/single_stat.stories.js +1 -3
  60. package/src/directives/resize_observer/resize_observer.stories.js +1 -3
  61. package/src/scss/utilities.scss +32 -0
  62. package/src/scss/utility-mixins/color.scss +4 -0
  63. package/src/scss/utility-mixins/sizing.scss +12 -0
  64. package/src/utils/constants.js +6 -0
@@ -1,4 +1,5 @@
1
1
  import { GlFormTextarea } from '../../../../index';
2
+ import { textareaCountOptions } from '../../../../utils/constants';
2
3
  import readme from './form_textarea.md';
3
4
 
4
5
  const template = `
@@ -7,6 +8,10 @@ const template = `
7
8
  :placeholder="placeholder"
8
9
  :rows="5"
9
10
  :no-resize="noResize"
11
+ :count="count"
12
+ :countType="countType"
13
+ :character-count-text="characterCountText"
14
+ :character-count-over-limit-text="characterCountOverLimitText"
10
15
  />
11
16
  `;
12
17
 
@@ -14,10 +19,18 @@ const generateProps = ({
14
19
  model = 'We take inspiration from other companies, and we always go for the boring solutions. Just like the rest of our work, we continually adjust our values and strive always to make them better. We used to have more values, but it was difficult to remember them all, so we condensed them and gave sub-values and created an acronym. Everyone is welcome to suggest improvements.',
15
20
  placeholder = 'hello',
16
21
  noResize = GlFormTextarea.props.noResize.default,
22
+ count = 400,
23
+ countType = textareaCountOptions.max,
24
+ characterCountText = '%{count} characters left',
25
+ characterCountOverLimitText = '%{count} characters over limit',
17
26
  } = {}) => ({
18
27
  model,
19
28
  placeholder,
20
29
  noResize,
30
+ count,
31
+ countType,
32
+ characterCountText,
33
+ characterCountOverLimitText,
21
34
  });
22
35
 
23
36
  const Template = (args) => ({
@@ -41,4 +54,12 @@ export default {
41
54
  },
42
55
  },
43
56
  },
57
+ argTypes: {
58
+ countType: {
59
+ control: {
60
+ type: 'select',
61
+ options: textareaCountOptions,
62
+ },
63
+ },
64
+ },
44
65
  };
@@ -1,5 +1,7 @@
1
1
  <script>
2
2
  import { BFormTextarea } from 'bootstrap-vue';
3
+ import GlSprintf from '../../../utilities/sprintf/sprintf.vue';
4
+ import { textareaCountOptions } from '../../../../utils/constants';
3
5
 
4
6
  const model = {
5
7
  prop: 'value',
@@ -9,6 +11,7 @@ const model = {
9
11
  export default {
10
12
  components: {
11
13
  BFormTextarea,
14
+ GlSprintf,
12
15
  },
13
16
  inheritAttrs: false,
14
17
  model,
@@ -30,6 +33,27 @@ export default {
30
33
  required: false,
31
34
  default: false,
32
35
  },
36
+ count: {
37
+ type: Number,
38
+ required: false,
39
+ default: 0,
40
+ },
41
+ countType: {
42
+ required: false,
43
+ type: String,
44
+ default: textareaCountOptions.max,
45
+ validator: (value) => Object.keys(textareaCountOptions).includes(value),
46
+ },
47
+ characterCountText: {
48
+ required: false,
49
+ type: String,
50
+ default: '',
51
+ },
52
+ characterCountOverLimitText: {
53
+ required: false,
54
+ type: String,
55
+ default: '',
56
+ },
33
57
  },
34
58
  computed: {
35
59
  listeners() {
@@ -56,6 +80,37 @@ export default {
56
80
  keypressEvent() {
57
81
  return this.submitOnEnter ? 'keyup' : null;
58
82
  },
83
+ characters() {
84
+ return this.value.length;
85
+ },
86
+ remainingCharacters() {
87
+ if (this.count) {
88
+ return Math.abs(this.count - this.characters);
89
+ }
90
+
91
+ return null;
92
+ },
93
+ characterCountClasses() {
94
+ switch (this.countType) {
95
+ case textareaCountOptions.max:
96
+ return {
97
+ 'gl-text-red-500': this.value.length > this.count,
98
+ 'gl-text-gray-500': this.value.length <= this.count,
99
+ };
100
+ case textareaCountOptions.recommended:
101
+ return 'gl-text-gray-500';
102
+ default:
103
+ return {};
104
+ }
105
+ },
106
+ hasCount() {
107
+ return this.remainingCharacters != null;
108
+ },
109
+ characterCountMessage() {
110
+ return this.characters > this.count
111
+ ? this.characterCountOverLimitText
112
+ : this.characterCountText;
113
+ },
59
114
  },
60
115
  methods: {
61
116
  handleKeyPress(e) {
@@ -68,12 +123,22 @@ export default {
68
123
  </script>
69
124
 
70
125
  <template>
71
- <b-form-textarea
72
- class="gl-form-input gl-form-textarea"
73
- :no-resize="noResize"
74
- v-bind="$attrs"
75
- :value="value"
76
- v-on="listeners"
77
- @[keypressEvent].native="handleKeyPress"
78
- />
126
+ <div>
127
+ <b-form-textarea
128
+ ref="textarea"
129
+ class="gl-form-input gl-form-textarea"
130
+ :no-resize="noResize"
131
+ v-bind="$attrs"
132
+ :value="value"
133
+ v-on="listeners"
134
+ @[keypressEvent].native="handleKeyPress"
135
+ />
136
+ <div v-if="hasCount">
137
+ <small :class="characterCountClasses" aria-live="polite">
138
+ <gl-sprintf :message="characterCountMessage">
139
+ <template #count>{{ remainingCharacters }}</template>
140
+ </gl-sprintf>
141
+ </small>
142
+ </div>
143
+ </div>
79
144
  </template>
@@ -44,16 +44,12 @@ export default {
44
44
  argTypes: {
45
45
  ...disableControls(['useDeprecatedSizes']),
46
46
  name: {
47
- control: {
48
- type: 'select',
49
- options: iconSpriteInfo.icons,
50
- },
47
+ options: iconSpriteInfo.icons,
48
+ control: 'select',
51
49
  },
52
50
  size: {
53
- control: {
54
- type: 'select',
55
- options: iconSizeOptions,
56
- },
51
+ options: iconSizeOptions,
52
+ control: 'select',
57
53
  },
58
54
  },
59
55
  };
@@ -1,52 +1,76 @@
1
1
  import { setStoryTimeout } from '../../../utils/test_utils';
2
- import { GlInfiniteScroll } from '../../../index';
2
+ import { GlInfiniteScroll, GlLoadingIcon } from '../../../index';
3
3
  import readme from './infinite_scroll.md';
4
4
 
5
5
  const ITEMS_BATCH_SIZE = 20;
6
6
 
7
7
  const template = `
8
8
  <gl-infinite-scroll
9
- :max-list-height="285"
10
- :fetched-items="fetchedItems"
11
- @bottomReached="bottomReached"
9
+ :total-items="totalItems"
10
+ :fetched-items="localFetchedItems"
11
+ :max-list-height="maxListHeight"
12
+ @bottomReached="onBottomReached"
12
13
  >
13
14
  <template #items>
14
15
  <ul class="list-group list-group-flushed list-unstyled">
15
- <li v-for="item in fetchedItems" :key="item" class="list-group-item">Item #{{ item }}</li>
16
+ <li v-for="item in localFetchedItems" :key="item" class="list-group-item">Item #{{ item }}</li>
16
17
  </ul>
17
18
  </template>
18
19
 
19
- <template #default>
20
+ <template v-if="localIsLoading" #default>
20
21
  <div class="gl-mt-3">
21
- <gl-loading-icon v-if="isLoading" />
22
- <span v-else>{{ fetchedItems }} items loaded</span>
22
+ <gl-loading-icon />
23
23
  </div>
24
24
  </template>
25
25
  </gl-infinite-scroll>
26
26
  `;
27
27
 
28
- const generateProps = ({ isLoading = false, fetchedItems = ITEMS_BATCH_SIZE } = {}) => ({
28
+ const generateProps = ({
29
+ isLoading = false,
30
+ totalItems = null,
31
+ fetchedItems = ITEMS_BATCH_SIZE,
32
+ maxListHeight = 285,
33
+ } = {}) => ({
29
34
  isLoading,
35
+ totalItems,
30
36
  fetchedItems,
37
+ maxListHeight,
31
38
  });
32
39
 
33
40
  const Template = (args, { argTypes }) => ({
34
41
  components: {
35
42
  GlInfiniteScroll,
43
+ GlLoadingIcon,
36
44
  },
37
45
  props: Object.keys(argTypes),
46
+ watch: {
47
+ fetchedItems: {
48
+ immediate: true,
49
+ handler(fetchedItems) {
50
+ this.localFetchedItems = fetchedItems;
51
+ },
52
+ },
53
+ isLoading: {
54
+ immediate: true,
55
+ handler(isLoading) {
56
+ this.localIsLoading = isLoading;
57
+ },
58
+ },
59
+ },
38
60
  data() {
39
61
  return {
40
62
  loadTimer: null,
63
+ localFetchedItems: null,
64
+ localIsLoading: false,
41
65
  };
42
66
  },
43
67
  methods: {
44
- bottomReached() {
68
+ onBottomReached() {
45
69
  clearTimeout(this.loadTimer);
46
- this.isLoading = true;
70
+ this.localIsLoading = true;
47
71
  this.loadTimer = setStoryTimeout(() => {
48
- this.fetchedItems += ITEMS_BATCH_SIZE;
49
- this.isLoading = false;
72
+ this.localFetchedItems += ITEMS_BATCH_SIZE;
73
+ this.localIsLoading = false;
50
74
  }, 500);
51
75
  },
52
76
  },
@@ -67,18 +67,14 @@ export default {
67
67
  },
68
68
  argTypes: {
69
69
  backgroundColor: {
70
- control: {
71
- type: 'color',
72
- },
70
+ control: 'color',
73
71
  },
74
72
  size: {
75
73
  options: labelSizeOptions,
76
74
  },
77
75
  tooltipPlacement: {
78
76
  options: tooltipPlacements,
79
- control: {
80
- type: 'select',
81
- },
77
+ control: 'select',
82
78
  },
83
79
  },
84
80
  };
@@ -40,10 +40,8 @@ export default {
40
40
  },
41
41
  argTypes: {
42
42
  target: {
43
- control: {
44
- type: 'select',
45
- options: targetOptions,
46
- },
43
+ options: targetOptions,
44
+ control: 'select',
47
45
  },
48
46
  },
49
47
  };
@@ -46,16 +46,12 @@ export default {
46
46
  },
47
47
  argTypes: {
48
48
  color: {
49
- control: {
50
- type: 'select',
51
- options: viewModeOptions,
52
- },
49
+ options: viewModeOptions,
50
+ control: 'select',
53
51
  },
54
52
  size: {
55
- control: {
56
- type: 'select',
57
- options: loadingIconSizes,
58
- },
53
+ options: loadingIconSizes,
54
+ control: 'select',
59
55
  },
60
56
  },
61
57
  };
@@ -115,52 +115,36 @@ export default {
115
115
  },
116
116
  argTypes: {
117
117
  headerBgVariant: {
118
- control: {
119
- type: 'select',
120
- options: variantOptionsWithNoDefault,
121
- },
118
+ options: variantOptionsWithNoDefault,
119
+ control: 'select',
122
120
  },
123
121
  headerBorderVariant: {
124
- control: {
125
- type: 'select',
126
- options: variantOptionsWithNoDefault,
127
- },
122
+ options: variantOptionsWithNoDefault,
123
+ control: 'select',
128
124
  },
129
125
  headerTextVariant: {
130
- control: {
131
- type: 'select',
132
- options: variantOptionsWithNoDefault,
133
- },
126
+ options: variantOptionsWithNoDefault,
127
+ control: 'select',
134
128
  },
135
129
  bodyBgVariant: {
136
- control: {
137
- type: 'select',
138
- options: variantOptionsWithNoDefault,
139
- },
130
+ options: variantOptionsWithNoDefault,
131
+ control: 'select',
140
132
  },
141
133
  bodyTextVariant: {
142
- control: {
143
- type: 'select',
144
- options: variantOptionsWithNoDefault,
145
- },
134
+ options: variantOptionsWithNoDefault,
135
+ control: 'select',
146
136
  },
147
137
  footerBgVariant: {
148
- control: {
149
- type: 'select',
150
- options: variantOptionsWithNoDefault,
151
- },
138
+ options: variantOptionsWithNoDefault,
139
+ control: 'select',
152
140
  },
153
141
  footerBorderVariant: {
154
- control: {
155
- type: 'select',
156
- options: variantOptionsWithNoDefault,
157
- },
142
+ options: variantOptionsWithNoDefault,
143
+ control: 'select',
158
144
  },
159
145
  footerTextVariant: {
160
- control: {
161
- type: 'select',
162
- options: variantOptionsWithNoDefault,
163
- },
146
+ options: variantOptionsWithNoDefault,
147
+ control: 'select',
164
148
  },
165
149
  },
166
150
  };
@@ -4,27 +4,51 @@ import GlPagination from './pagination.vue';
4
4
 
5
5
  const components = { GlPagination };
6
6
 
7
- const generateBaseProps = ({
8
- prevText = 'Previous',
9
- nextText = 'Next',
10
- disabled = false,
7
+ const defaultValue = (name) => GlPagination.props[name].default;
8
+
9
+ const generateProps = ({
10
+ page = 3,
11
+ align = defaultValue('align'),
12
+ disabled = defaultValue('disabled'),
13
+ linkGen = defaultValue('linkGen'),
14
+ nextPage = defaultValue('nextPage'),
15
+ nextText = defaultValue('nextText'),
16
+ perPage = 10, // Existing stories/shots used this value instead of the default
17
+ prevPage = defaultValue('prevPage'),
18
+ prevText = defaultValue('prevText'),
19
+ totalItems = 200, // The component's default value of 0 is for compact pagination, which most stories here do not use.
11
20
  } = {}) => ({
12
- prevText,
13
- nextText,
21
+ page,
22
+ align,
14
23
  disabled,
15
- });
16
-
17
- const generateFullProps = ({ page = 3, perPage = 10, totalItems = 200 } = {}) => ({
18
- initialPage: page,
24
+ linkGen,
25
+ nextPage,
26
+ nextText,
19
27
  perPage,
28
+ prevPage,
29
+ prevText,
20
30
  totalItems,
21
- ...generateBaseProps(),
22
31
  });
23
32
 
24
- const defaults = {
33
+ const template = `
34
+ <gl-pagination
35
+ v-model="page"
36
+ :align="align"
37
+ :disabled="disabled"
38
+ :link-gen="linkGen"
39
+ :next-page="nextPage"
40
+ :next-text="nextText"
41
+ :per-page="perPage"
42
+ :prev-page="prevPage"
43
+ :prev-text="prevText"
44
+ :total-items="totalItems"
45
+ />
46
+ `;
47
+
48
+ const defaults = (args) => ({
25
49
  data() {
26
50
  return {
27
- page: 3,
51
+ currentPage: args.page,
28
52
  alignOptions,
29
53
  };
30
54
  },
@@ -33,33 +57,20 @@ const defaults = {
33
57
  this.page = page;
34
58
  },
35
59
  },
36
- };
60
+ });
37
61
 
38
62
  export const Default = (args, { argTypes }) => ({
39
63
  components,
40
64
  props: Object.keys(argTypes),
41
- ...defaults,
42
- template: `<gl-pagination
43
- v-model="page"
44
- :per-page="perPage"
45
- :total-items="totalItems"
46
- :prev-text="prevText"
47
- :next-text="nextText"
48
- :disabled="disabled"
49
- />`,
65
+ ...defaults(args),
66
+ template,
50
67
  });
51
- Default.args = generateFullProps();
68
+ Default.args = generateProps();
52
69
 
53
- export const Compact = () => ({
70
+ export const Compact = (args, { argTypes }) => ({
54
71
  components,
55
- ...defaults,
56
- props: generateFullProps(),
57
- data() {
58
- return {
59
- page: 1,
60
- alignOptions,
61
- };
62
- },
72
+ props: Object.keys(argTypes),
73
+ ...defaults(args),
63
74
  computed: {
64
75
  prevPage() {
65
76
  return Math.max(this.page - 1, 0);
@@ -70,72 +81,37 @@ export const Compact = () => ({
70
81
  },
71
82
  },
72
83
  template: `
73
- <div class="text-center gl-font-base">
74
- <gl-pagination
75
- v-model="page"
76
- :prev-page="prevPage"
77
- :next-page="nextPage"
78
- :prev-text="prevText"
79
- :next-text="nextText"
80
- :disabled="disabled"
81
- :align="alignOptions.center"
82
- />
83
- Page {{ page }} of 3
84
- </div>`,
84
+ <div class="text-center gl-font-base">
85
+ ${template}
86
+ Page {{ page }} of 3
87
+ </div>
88
+ `,
85
89
  });
90
+ Compact.args = generateProps({ page: 1, totalItems: 0, align: alignOptions.center });
86
91
 
87
92
  export const LinkBased = (args, { argTypes }) => ({
88
93
  components,
89
94
  props: Object.keys(argTypes),
90
- ...defaults,
91
- methods: {
92
- linkGen(page) {
93
- return `/page/${page}`;
94
- },
95
- },
96
- template: `<gl-pagination
97
- v-model="page"
98
- :per-page="perPage"
99
- :total-items="totalItems"
100
- :prev-text="prevText"
101
- :next-text="nextText"
102
- :disabled="disabled"
103
- :link-gen="linkGen"
104
- />`,
95
+ ...defaults(args),
96
+ template,
105
97
  });
106
- LinkBased.args = generateFullProps();
98
+ LinkBased.args = generateProps({ linkGen: (page) => `/page/${page}` });
107
99
 
108
100
  export const AlignCenter = (args, { argTypes }) => ({
109
101
  components,
110
102
  props: Object.keys(argTypes),
111
- ...defaults,
112
- template: `<gl-pagination
113
- v-model="page"
114
- :per-page="perPage"
115
- :total-items="totalItems"
116
- :prev-text="prevText"
117
- :next-text="nextText"
118
- :disabled="disabled"
119
- :align="alignOptions.center"
120
- />`,
103
+ ...defaults(args),
104
+ template,
121
105
  });
122
- AlignCenter.args = generateFullProps();
106
+ AlignCenter.args = generateProps({ align: alignOptions.center });
123
107
 
124
108
  export const AlignRight = (args, { argTypes }) => ({
125
109
  components,
126
110
  props: Object.keys(argTypes),
127
- ...defaults,
128
- template: `<gl-pagination
129
- v-model="page"
130
- :per-page="perPage"
131
- :total-items="totalItems"
132
- :prev-text="prevText"
133
- :next-text="nextText"
134
- :disabled="disabled"
135
- :align="alignOptions.right"
136
- />`,
111
+ ...defaults(args),
112
+ template,
137
113
  });
138
- AlignRight.args = generateFullProps();
114
+ AlignRight.args = generateProps({ align: alignOptions.right });
139
115
 
140
116
  export default {
141
117
  title: 'base/pagination',
@@ -148,4 +124,10 @@ export default {
148
124
  },
149
125
  },
150
126
  },
127
+ argTypes: {
128
+ align: {
129
+ options: Object.values(alignOptions),
130
+ control: 'select',
131
+ },
132
+ },
151
133
  };
@@ -75,14 +75,10 @@ export default {
75
75
  argTypes: {
76
76
  theme: {
77
77
  options: glThemes,
78
- control: {
79
- type: 'select',
80
- },
78
+ control: 'select',
81
79
  },
82
80
  backgroundColor: {
83
- control: {
84
- type: 'color',
85
- },
81
+ control: 'color',
86
82
  },
87
83
  },
88
84
  };
@@ -67,10 +67,12 @@ $gl-popover-max-width: $grid-size * 35;
67
67
  @include gl-font-sm;
68
68
  @include gl-font-weight-bold;
69
69
  @include gl-m-0;
70
+ @include gl-border-bottom-0;
71
+ @include gl-pb-0;
70
72
  }
71
73
 
72
74
  .popover-body {
73
- @include gl-py-5;
75
+ @include gl-py-3;
74
76
  @include gl-px-4;
75
77
 
76
78
  > .popover-hr {
@@ -1,5 +1,5 @@
1
1
  import { shallowMount } from '@vue/test-utils';
2
- import { tooltipActionEvents } from '../../../utils/constants';
2
+ import { tooltipActionEvents, popoverPlacements } from '../../../utils/constants';
3
3
  import GlPopover from './popover.vue';
4
4
 
5
5
  describe('GlPopover', () => {
@@ -49,6 +49,20 @@ describe('GlPopover', () => {
49
49
  });
50
50
  });
51
51
 
52
+ describe('placement', () => {
53
+ it(`uses "${popoverPlacements.top}" placement by default`, () => {
54
+ createWrapper();
55
+
56
+ expect(findBVPopover().props('placement')).toBe(popoverPlacements.top);
57
+ });
58
+
59
+ it('uses a defined placement', () => {
60
+ createWrapper({ placement: popoverPlacements.right });
61
+
62
+ expect(findBVPopover().props('placement')).toBe(popoverPlacements.right);
63
+ });
64
+ });
65
+
52
66
  describe('close button', () => {
53
67
  let doCloseMock;
54
68
 
@@ -26,7 +26,7 @@ const getTemplate = (id, slots = '') => `
26
26
  </div>`;
27
27
 
28
28
  const generateProps = ({
29
- placement = popoverPlacements.top,
29
+ placement = defaultValue('placement'),
30
30
  title = 'Popover',
31
31
  triggers = defaultValue('triggers'),
32
32
  cssClasses = defaultValue('cssClasses'),
@@ -87,12 +87,10 @@ export default {
87
87
  argTypes: {
88
88
  placement: {
89
89
  options: Object.values(popoverPlacements),
90
- control: {
91
- type: 'select',
92
- },
90
+ control: 'select',
93
91
  },
94
92
  title: {
95
- control: { type: 'text' },
93
+ control: 'text',
96
94
  },
97
95
  },
98
96
  };