@gitlab/ui 35.0.0 → 36.2.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 (158) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/components/base/filtered_search/filtered_search.documentation.js +6 -0
  3. package/dist/components/base/filtered_search/filtered_search.js +12 -2
  4. package/dist/components/base/filtered_search/filtered_search_term.documentation.js +6 -0
  5. package/dist/components/base/filtered_search/filtered_search_term.js +11 -1
  6. package/dist/components/base/filtered_search/filtered_search_token_segment.documentation.js +6 -0
  7. package/dist/components/base/filtered_search/filtered_search_token_segment.js +11 -1
  8. package/dist/components/base/nav/nav.documentation.js +2 -7
  9. package/dist/components/base/popover/popover.documentation.js +1 -23
  10. package/dist/components/base/popover/popover.js +10 -0
  11. package/dist/components/base/search_box_by_click/search_box_by_click.documentation.js +3 -0
  12. package/dist/components/base/search_box_by_click/search_box_by_click.js +6 -1
  13. package/dist/components/utilities/truncate/truncate.documentation.js +2 -17
  14. package/dist/components/utilities/truncate/truncate.js +11 -0
  15. package/dist/index.css +1 -1
  16. package/dist/index.css.map +1 -1
  17. package/dist/utility_classes.css +1 -1
  18. package/dist/utility_classes.css.map +1 -1
  19. package/documentation/all_components.js +2 -2
  20. package/documentation/components_documentation.js +0 -2
  21. package/documentation/documented_stories.js +5 -0
  22. package/package.json +7 -10
  23. package/src/charts.js +19 -0
  24. package/src/components/base/alert/alert.stories.js +1 -1
  25. package/src/components/base/avatar/avatar.stories.js +1 -1
  26. package/src/components/base/avatar_labeled/avatar_labeled.stories.js +1 -1
  27. package/src/components/base/avatar_link/avatar_link.stories.js +1 -1
  28. package/src/components/base/avatars_inline/avatars_inline.stories.js +1 -1
  29. package/src/components/base/badge/badge.stories.js +1 -1
  30. package/src/components/base/banner/banner.stories.js +1 -1
  31. package/src/components/base/breadcrumb/breadcrumb.stories.js +1 -1
  32. package/src/components/base/broadcast_message/broadcast_message.stories.js +1 -1
  33. package/src/components/base/button/button.stories.js +1 -1
  34. package/src/components/base/button_group/button_group.stories.js +1 -1
  35. package/src/components/base/collapse/collapse.stories.js +1 -1
  36. package/src/components/base/drawer/drawer.stories.js +1 -1
  37. package/src/components/base/dropdown/dropdown.stories.js +1 -1
  38. package/src/components/base/dropdown/dropdown_divider.stories.js +1 -1
  39. package/src/components/base/dropdown/dropdown_form.stories.js +1 -1
  40. package/src/components/base/dropdown/dropdown_item.stories.js +1 -1
  41. package/src/components/base/dropdown/dropdown_section_header.stories.js +1 -1
  42. package/src/components/base/dropdown/dropdown_text.stories.js +1 -1
  43. package/src/components/base/filtered_search/filtered_search.documentation.js +6 -0
  44. package/src/components/base/filtered_search/filtered_search.spec.js +81 -47
  45. package/src/components/base/filtered_search/filtered_search.stories.js +1 -1
  46. package/src/components/base/filtered_search/filtered_search.vue +13 -0
  47. package/src/components/base/filtered_search/filtered_search_suggestion.stories.js +1 -1
  48. package/src/components/base/filtered_search/filtered_search_suggestion_list.stories.js +1 -1
  49. package/src/components/base/filtered_search/filtered_search_term.documentation.js +6 -0
  50. package/src/components/base/filtered_search/filtered_search_term.spec.js +42 -9
  51. package/src/components/base/filtered_search/filtered_search_term.vue +13 -0
  52. package/src/components/base/filtered_search/filtered_search_token.stories.js +1 -1
  53. package/src/components/base/filtered_search/filtered_search_token_segment.documentation.js +6 -0
  54. package/src/components/base/filtered_search/filtered_search_token_segment.spec.js +53 -0
  55. package/src/components/base/filtered_search/filtered_search_token_segment.stories.js +1 -1
  56. package/src/components/base/filtered_search/filtered_search_token_segment.vue +12 -0
  57. package/src/components/base/form/form.stories.js +1 -1
  58. package/src/components/base/form/form_checkbox/form_checkbox.stories.js +1 -1
  59. package/src/components/base/form/form_group/form_group.stories.js +1 -1
  60. package/src/components/base/form/form_input/form_input.stories.js +1 -1
  61. package/src/components/base/form/form_input_group/form_input_group.stories.js +1 -1
  62. package/src/components/base/form/form_radio/form_radio.stories.js +1 -1
  63. package/src/components/base/form/form_radio_group/form_radio_group.stories.js +1 -1
  64. package/src/components/base/form/form_select/form_select.stories.js +1 -1
  65. package/src/components/base/form/form_text/form_text.vue +3 -1
  66. package/src/components/base/form/form_textarea/form_textarea.stories.js +1 -1
  67. package/src/components/base/icon/icon.stories.js +1 -1
  68. package/src/components/base/infinite_scroll/infinite_scroll.stories.js +1 -1
  69. package/src/components/base/label/label.stories.js +1 -1
  70. package/src/components/base/link/link.stories.js +1 -1
  71. package/src/components/base/loading_icon/loading_icon.stories.js +1 -1
  72. package/src/components/base/modal/modal.scss +5 -2
  73. package/src/components/base/modal/modal.stories.js +1 -1
  74. package/src/components/base/nav/nav.documentation.js +0 -4
  75. package/src/components/base/nav/nav.md +8 -5
  76. package/src/components/base/nav/nav.stories.js +52 -15
  77. package/src/components/base/navbar/navbar.stories.js +1 -1
  78. package/src/components/base/paginated_list/paginated_list.stories.js +1 -1
  79. package/src/components/base/path/path.stories.js +1 -1
  80. package/src/components/base/popover/popover.documentation.js +0 -25
  81. package/src/components/base/popover/popover.stories.js +79 -75
  82. package/src/components/base/popover/popover.vue +8 -0
  83. package/src/components/base/progress_bar/progress_bar.stories.js +1 -1
  84. package/src/components/base/search_box_by_click/search_box_by_click.documentation.js +3 -0
  85. package/src/components/base/search_box_by_click/search_box_by_click.spec.js +14 -3
  86. package/src/components/base/search_box_by_click/search_box_by_click.stories.js +1 -1
  87. package/src/components/base/search_box_by_click/search_box_by_click.vue +7 -0
  88. package/src/components/base/search_box_by_type/search_box_by_type.stories.js +1 -1
  89. package/src/components/base/segmented_control/segmented_control.stories.js +1 -1
  90. package/src/components/base/skeleton_loader/skeleton_loader.stories.js +1 -1
  91. package/src/components/base/skeleton_loading/skeleton_loading.stories.js +1 -1
  92. package/src/components/base/sorting/sorting.stories.js +1 -1
  93. package/src/components/base/sorting/sorting_item.stories.js +1 -1
  94. package/src/components/base/table/table.stories.js +1 -1
  95. package/src/components/base/tabs/tabs/tabs.spec.js +1 -1
  96. package/src/components/base/tabs/tabs/tabs.stories.js +1 -1
  97. package/src/components/base/toast/toast.stories.js +1 -1
  98. package/src/components/base/toggle/toggle.stories.js +1 -1
  99. package/src/components/base/token/token.stories.js +1 -1
  100. package/src/components/base/tooltip/tooltip.stories.js +1 -1
  101. package/src/components/charts/area/area.stories.js +1 -1
  102. package/src/components/charts/bar/bar.stories.js +1 -1
  103. package/src/components/charts/chart/chart.stories.js +2 -2
  104. package/src/components/charts/column/column.stories.js +1 -1
  105. package/src/components/charts/discrete_scatter/discrete_scatter.stories.js +1 -1
  106. package/src/components/charts/heatmap/heatmap.stories.js +1 -1
  107. package/src/components/charts/legend/legend.stories.js +1 -1
  108. package/src/components/charts/line/line.stories.js +1 -1
  109. package/src/components/charts/series_label/series_label.stories.js +1 -1
  110. package/src/components/charts/single_stat/single_stat.stories.js +1 -1
  111. package/src/components/charts/sparkline/sparkline.stories.js +1 -1
  112. package/src/components/charts/stacked_column/stacked_column.stories.js +1 -1
  113. package/src/components/charts/tooltip/tooltip.stories.js +1 -1
  114. package/src/components/regions/dashboard_skeleton/dashboard_skeleton.stories.js +1 -1
  115. package/src/components/regions/empty_state/empty_state.stories.js +1 -1
  116. package/src/components/utilities/friendly_wrap/friendly_wrap.stories.js +1 -1
  117. package/src/components/utilities/intersection_observer/intersection_observer.stories.js +1 -1
  118. package/src/components/utilities/intersperse/intersperse.stories.js +1 -1
  119. package/src/components/utilities/sprintf/sprintf.stories.js +1 -1
  120. package/src/components/utilities/truncate/truncate.documentation.js +0 -14
  121. package/src/components/utilities/truncate/truncate.md +0 -4
  122. package/src/components/utilities/truncate/truncate.stories.js +38 -27
  123. package/src/components/utilities/truncate/truncate.vue +9 -0
  124. package/{config.js → src/config.js} +1 -1
  125. package/src/directives/hover_load/hover_load.stories.js +1 -1
  126. package/src/directives/outside/outside.stories.js +1 -1
  127. package/src/directives/resize_observer/resize_observer.stories.js +1 -1
  128. package/src/directives/safe_html/safe_html.stories.js +1 -1
  129. package/src/index.js +111 -0
  130. package/src/scss/utilities.scss +8 -0
  131. package/src/scss/utility-mixins/color.scss +4 -0
  132. package/{utils.js → src/utils.js} +1 -1
  133. package/charts.js +0 -19
  134. package/dist/components/base/nav/examples/index.js +0 -13
  135. package/dist/components/base/nav/examples/nav.basic.example.js +0 -38
  136. package/dist/components/base/nav/nav_item.documentation.js +0 -13
  137. package/dist/components/base/nav/nav_item_dropdown.documentation.js +0 -14
  138. package/dist/components/base/popover/examples/index.js +0 -25
  139. package/dist/components/base/popover/examples/popover.basic.example.js +0 -38
  140. package/dist/components/base/popover/examples/popover.loading.example.js +0 -38
  141. package/dist/components/base/popover/examples/popover.notitle.example.js +0 -38
  142. package/dist/components/utilities/truncate/examples/index.js +0 -13
  143. package/dist/components/utilities/truncate/examples/truncate.basic.example.js +0 -38
  144. package/index.js +0 -111
  145. package/src/components/base/nav/examples/index.js +0 -15
  146. package/src/components/base/nav/examples/nav.basic.example.vue +0 -8
  147. package/src/components/base/nav/nav_item.documentation.js +0 -6
  148. package/src/components/base/nav/nav_item.md +0 -7
  149. package/src/components/base/nav/nav_item.stories.js +0 -23
  150. package/src/components/base/nav/nav_item_dropdown.documentation.js +0 -7
  151. package/src/components/base/nav/nav_item_dropdown.md +0 -7
  152. package/src/components/base/nav/nav_item_dropdown.stories.js +0 -52
  153. package/src/components/base/popover/examples/index.js +0 -29
  154. package/src/components/base/popover/examples/popover.basic.example.vue +0 -13
  155. package/src/components/base/popover/examples/popover.loading.example.vue +0 -15
  156. package/src/components/base/popover/examples/popover.notitle.example.vue +0 -12
  157. package/src/components/utilities/truncate/examples/index.js +0 -15
  158. package/src/components/utilities/truncate/examples/truncate.basic.example.vue +0 -5
@@ -1,7 +1,7 @@
1
1
  import { withKnobs, boolean } from '@storybook/addon-knobs';
2
2
  import PortalVue from 'portal-vue';
3
3
  import Vue from 'vue';
4
- import { GlFilteredSearchSuggestion } from '../../../../index';
4
+ import { GlFilteredSearchSuggestion } from '../../../index';
5
5
  import { documentedStoriesOf } from '../../../../documentation/documented_stories';
6
6
  import { provide } from './common_story_options';
7
7
  import readme from './filtered_search_term.md';
@@ -49,6 +49,16 @@ export default {
49
49
  required: true,
50
50
  validator: () => true,
51
51
  },
52
+ searchInputAttributes: {
53
+ type: Object,
54
+ required: false,
55
+ default: () => ({}),
56
+ },
57
+ isLastToken: {
58
+ type: Boolean,
59
+ required: false,
60
+ default: false,
61
+ },
52
62
  },
53
63
 
54
64
  data() {
@@ -244,6 +254,7 @@ export default {
244
254
 
245
255
  <template>
246
256
  <div
257
+ v-bind="isLastToken && !active && searchInputAttributes"
247
258
  class="gl-filtered-search-token-segment"
248
259
  :class="{ 'gl-filtered-search-token-segment-active': active }"
249
260
  data-testid="filtered-search-token-segment"
@@ -252,6 +263,7 @@ export default {
252
263
  <template v-if="active">
253
264
  <input
254
265
  ref="input"
266
+ v-bind="searchInputAttributes"
255
267
  v-model="inputValue"
256
268
  class="gl-filtered-search-token-segment-input"
257
269
  :aria-label="label"
@@ -5,7 +5,7 @@ import {
5
5
  GlFormSelect,
6
6
  GlFormCheckbox,
7
7
  GlButton,
8
- } from '../../../../index';
8
+ } from '../../../index';
9
9
  import { setStoryTimeout } from '../../../utils/test_utils';
10
10
  import readme from './form.md';
11
11
 
@@ -1,4 +1,4 @@
1
- import { GlFormCheckbox, GlFormCheckboxGroup } from '../../../../../index';
1
+ import { GlFormCheckbox, GlFormCheckboxGroup } from '../../../../index';
2
2
  import readme from './form_checkbox.md';
3
3
 
4
4
  const components = {
@@ -1,6 +1,6 @@
1
1
  import { withKnobs, text, select, boolean } from '@storybook/addon-knobs';
2
2
  import { documentedStoriesOf } from '../../../../../documentation/documented_stories';
3
- import { GlFormGroup, GlFormInput, GlFormTextarea } from '../../../../../index';
3
+ import { GlFormGroup, GlFormInput, GlFormTextarea } from '../../../../index';
4
4
  import { sizeOptions } from '../../../../utils/constants';
5
5
  import readme from './form_group.md';
6
6
 
@@ -1,4 +1,4 @@
1
- import { GlFormInput } from '../../../../../index';
1
+ import { GlFormInput } from '../../../../index';
2
2
  import { formInputSizes } from '../../../../utils/constants';
3
3
  import readme from './form_input.md';
4
4
 
@@ -1,6 +1,6 @@
1
1
  import { withKnobs, boolean, object, text } from '@storybook/addon-knobs';
2
2
  import { documentedStoriesOf } from '../../../../../documentation/documented_stories';
3
- import { GlFormInputGroup, GlInputGroupText } from '../../../../../index';
3
+ import { GlFormInputGroup, GlInputGroupText } from '../../../../index';
4
4
  import readme from './form_input_group.md';
5
5
 
6
6
  const components = {
@@ -1,4 +1,4 @@
1
- import { GlFormRadio } from '../../../../../index';
1
+ import { GlFormRadio } from '../../../../index';
2
2
  import readme from './form_radio.md';
3
3
 
4
4
  const defaultOptions = [
@@ -1,6 +1,6 @@
1
1
  import { withKnobs, object, text } from '@storybook/addon-knobs';
2
2
  import { documentedStoriesOf } from '../../../../../documentation/documented_stories';
3
- import { GlFormRadioGroup, GlFormRadio } from '../../../../../index';
3
+ import { GlFormRadioGroup, GlFormRadio } from '../../../../index';
4
4
  import readme from './form_radio_group.md';
5
5
 
6
6
  const components = {
@@ -1,4 +1,4 @@
1
- import { GlFormSelect } from '../../../../../index';
1
+ import { GlFormSelect } from '../../../../index';
2
2
  import { sizeOptions, formStateOptions } from '../../../../utils/constants';
3
3
  import { formSelectOptions } from './constants';
4
4
  import readme from './form_select.md';
@@ -1,3 +1,5 @@
1
1
  <script>
2
- export { BFormText as default } from 'bootstrap-vue';
2
+ import { BFormText } from 'bootstrap-vue';
3
+
4
+ export default BFormText;
3
5
  </script>
@@ -1,4 +1,4 @@
1
- import { GlFormTextarea } from '../../../../../index';
1
+ import { GlFormTextarea } from '../../../../index';
2
2
  import readme from './form_textarea.md';
3
3
 
4
4
  const template = `
@@ -1,5 +1,5 @@
1
1
  import iconSpriteInfo from '@gitlab/svgs/dist/icons.json';
2
- import { GlIcon } from '../../../../index';
2
+ import { GlIcon } from '../../../index';
3
3
  import { iconSizeOptions } from '../../../utils/constants';
4
4
  import readme from './icon.md';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { setStoryTimeout } from '../../../utils/test_utils';
2
- import { GlInfiniteScroll } from '../../../../index';
2
+ import { GlInfiniteScroll } from '../../../index';
3
3
  import readme from './infinite_scroll.md';
4
4
 
5
5
  const ITEMS_BATCH_SIZE = 20;
@@ -1,4 +1,4 @@
1
- import { GlLabel } from '../../../../index';
1
+ import { GlLabel } from '../../../index';
2
2
  import { labelSizeOptions, tooltipPlacements } from '../../../utils/constants';
3
3
  import readme from './label.md';
4
4
 
@@ -1,4 +1,4 @@
1
- import { GlLink } from '../../../../index';
1
+ import { GlLink } from '../../../index';
2
2
  import { targetOptions } from '../../../utils/constants';
3
3
  import readme from './link.md';
4
4
 
@@ -1,4 +1,4 @@
1
- import { GlLoadingIcon } from '../../../../index';
1
+ import { GlLoadingIcon } from '../../../index';
2
2
  import { viewModeOptions, loadingIconSizes } from '../../../utils/constants';
3
3
  import readme from './loading_icon.md';
4
4
 
@@ -53,7 +53,8 @@ body.modal-open {
53
53
 
54
54
  .modal-header {
55
55
  @include gl-bg-white;
56
- @include gl-pr-3;
56
+ @include gl-pb-3;
57
+ @include gl-border-none;
57
58
 
58
59
  .modal-title {
59
60
  @include gl-font-lg;
@@ -68,6 +69,7 @@ body.modal-open {
68
69
  @include gl-bg-white;
69
70
  @include gl-relative;
70
71
  @include gl-p-5;
72
+ @include gl-py-3;
71
73
  @include gl-text-left;
72
74
  @include gl-white-space-normal;
73
75
  @include gl-font-base;
@@ -78,7 +80,8 @@ body.modal-open {
78
80
  @include gl-display-flex;
79
81
  @include gl-flex-direction-row;
80
82
  @include gl-p-5;
81
- @include gl-bg-gray-10;
83
+ @include gl-pt-3;
84
+ @include gl-border-none;
82
85
 
83
86
  .btn {
84
87
  @include gl-m-0;
@@ -1,4 +1,4 @@
1
- import { GlModal, GlModalDirective, GlButton } from '../../../../index';
1
+ import { GlModal, GlModalDirective, GlButton } from '../../../index';
2
2
  import { variantOptionsWithNoDefault } from '../../../utils/constants';
3
3
  import readme from './modal.md';
4
4
 
@@ -1,9 +1,5 @@
1
- import examples from './examples';
2
1
  import * as description from './nav.md';
3
2
 
4
3
  export default {
5
4
  description,
6
- examples,
7
- bootstrapComponent: 'b-nav',
8
- propsInfo: {},
9
5
  };
@@ -1,8 +1,11 @@
1
- # Nav
1
+ The navigation component is built with flexbox and provides a strong foundation for building all
2
+ types of navigation components.
2
3
 
3
- <!-- STORY -->
4
+ ## `GlNavItem`
4
5
 
5
- ## Usage
6
+ Use `GlNavItem` to add actionable links (or router links) to your nav. `GlNavItem` wraps [`BNavItem`](https://bootstrap-vue.org/docs/components/navbar#b-nav-item).
6
7
 
7
- The navigation component is built with flexbox and provides a strong foundation for building all
8
- types of navigation components.
8
+ ## `GlNavItemDropdown`
9
+
10
+ Use `GlNavItemDropdown` to place dropdown items within your nav.
11
+ `GlNavItemDropdown` wraps [`BNavItemDropdown`](https://bootstrap-vue.org/docs/components/navbar#b-nav-item-dropdown).
@@ -1,23 +1,60 @@
1
- import { withKnobs } from '@storybook/addon-knobs';
2
- import { documentedStoriesOf } from '../../../../documentation/documented_stories';
3
- import { GlNav, GlNavItem } from '../../../../index';
4
- import readme from './nav.md';
5
-
6
- const components = {
1
+ import {
7
2
  GlNav,
8
3
  GlNavItem,
9
- };
4
+ GlNavItemDropdown,
5
+ GlDropdownItem,
6
+ GlDropdownDivider,
7
+ GlIcon,
8
+ } from '../../../index';
9
+ import readme from './nav.md';
10
10
 
11
- documentedStoriesOf('base/nav', readme)
12
- .addDecorator(withKnobs)
13
- .add('default', () => ({
14
- components,
15
- template: `
11
+ export const Default = (_args, { argTypes }) => ({
12
+ props: Object.keys(argTypes),
13
+ components: {
14
+ GlNav,
15
+ GlNavItem,
16
+ GlNavItemDropdown,
17
+ GlDropdownItem,
18
+ GlDropdownDivider,
19
+ GlIcon,
20
+ },
21
+ template: `
22
+ <div style="height: 150px">
16
23
  <gl-nav>
17
24
  <gl-nav-item active>Active</gl-nav-item>
18
25
  <gl-nav-item>Link</gl-nav-item>
19
- <gl-nav-item>Another Link</gl-nav-item>
26
+ <gl-nav-item-dropdown text="Dropdown">
27
+ <gl-dropdown-item>Above divider</gl-dropdown-item>
28
+ <gl-dropdown-divider />
29
+ <gl-dropdown-item>Below divider</gl-dropdown-item>
30
+ </gl-nav-item-dropdown>
31
+ <gl-nav-item-dropdown text="Dropdown">
32
+ <template #button-content>
33
+ <gl-icon name="question" />
34
+ <gl-icon name="angle-down" />
35
+ </template>
36
+ <gl-dropdown-item>One</gl-dropdown-item>
37
+ <gl-dropdown-item>Two</gl-dropdown-item>
38
+ </gl-nav-item-dropdown>
20
39
  <gl-nav-item disabled>Disabled</gl-nav-item>
21
40
  </gl-nav>
22
- `,
23
- }));
41
+ </div>`,
42
+ });
43
+
44
+ export default {
45
+ title: 'base/nav',
46
+ component: GlNav,
47
+ subcomponents: {
48
+ GlNavItem,
49
+ GlNavItemDropdown,
50
+ },
51
+ parameters: {
52
+ bootstrapComponent: 'b-nav',
53
+ knobs: { disable: true },
54
+ docs: {
55
+ description: {
56
+ component: readme,
57
+ },
58
+ },
59
+ },
60
+ };
@@ -1,4 +1,4 @@
1
- import { GlNavbar } from '../../../../index';
1
+ import { GlNavbar } from '../../../index';
2
2
  import readme from './navbar.md';
3
3
 
4
4
  const Template = (args, { argTypes }) => ({
@@ -1,4 +1,4 @@
1
- import { GlPaginatedList, GlButton } from '../../../../index';
1
+ import { GlPaginatedList, GlButton } from '../../../index';
2
2
  import readme from './paginated_list.md';
3
3
 
4
4
  const sampleList = [
@@ -1,4 +1,4 @@
1
- import { GlPath, GlPopover } from '../../../../index';
1
+ import { GlPath, GlPopover } from '../../../index';
2
2
  import { glThemes } from '../../../utils/constants';
3
3
  import { mockPathItems } from './data';
4
4
  import readme from './path.md';
@@ -1,28 +1,3 @@
1
- import examples from './examples';
2
-
3
1
  export default {
4
2
  followsDesignSystem: true,
5
- examples,
6
- bootstrapComponent: 'b-popover',
7
- bootstrapPropsInfo: {
8
- target: {
9
- additionalInfo:
10
- 'Element string ID, or a reference to an element or component, that you want to trigger the popover.',
11
- required: true,
12
- },
13
- triggers: {
14
- enum: 'triggerVariantOptions',
15
- },
16
- placement: {
17
- enum: 'popoverPlacements',
18
- },
19
- boundary: {
20
- additionalInfo:
21
- '"scrollParent", "viewport", "window", or a reference to an HTML element. This is the container that the popover will be constrained to visually.You may need to change this if your target element is in a small container with overflow scroll',
22
- },
23
- container: {
24
- additionalInfo:
25
- 'Specify container as null (default, appends to <body>) to avoid rendering problems in more complex components (like input groups, button groups, etc). You can use container to optionally specify a different element to append the popover to.',
26
- },
27
- },
28
3
  };
@@ -1,8 +1,8 @@
1
- import { withKnobs, select, text } from '@storybook/addon-knobs';
2
- import { GlPopover, GlButton } from '../../../../index';
3
- import { documentedStoriesOf } from '../../../../documentation/documented_stories';
1
+ import { GlPopover, GlButton } from '../../../index';
4
2
  import { popoverPlacements } from '../../../utils/constants';
5
3
 
4
+ const defaultValue = (prop) => GlPopover.props[prop].default;
5
+
6
6
  const components = { GlPopover, GlButton };
7
7
 
8
8
  const contentString = `
@@ -11,84 +11,88 @@ const contentString = `
11
11
  massa ac, porta condimentum libero. Ut id lacus tristique, egestas arcu non, molestie nisi.
12
12
  `;
13
13
 
14
- const template = `
15
- <div class="gl-display-flex gl-justify-content-center gl-p-6">
16
- <gl-button id="pop-top">{{placement}}</gl-button>
17
- <gl-popover target="pop-top"
18
- triggers="hover focus"
14
+ const getTemplate = (id, slots = '') => `
15
+ <div style="height:400px;" class="gl-display-flex gl-justify-content-center gl-align-items-center">
16
+ <gl-button id="${id}">{{placement}}</gl-button>
17
+ <gl-popover
18
+ target="${id}"
19
+ :triggers="triggers"
19
20
  :title="title"
20
21
  :placement="placement"
22
+ :show-close-button="showCloseButton"
21
23
  content="${contentString}"
22
- data-testid="popover-with-props"
23
- show
24
- />
25
- </div>
26
- `;
24
+ data-testid="${id}"
25
+ :show="$options.viewMode !== 'docs'">${slots}</gl-popover>
26
+ </div>`;
27
27
 
28
- const scopedSlotTemplate = `
29
- <div class="gl-display-flex gl-justify-content-center gl-p-6">
30
- <gl-button id="pop-top-two" data-testid="popover-button-click">{{placement}}</gl-button>
31
- <gl-popover target="pop-top-two"
32
- triggers="click"
33
- :placement="placement"
34
- content="${contentString}"
35
- >
36
- <template #title>
37
- <span data-testid="popover-title">Popover title</span>
38
- </template>
39
- </gl-popover>
40
- </div>
41
- `;
28
+ const generateProps = ({
29
+ placement = popoverPlacements.top,
30
+ title = 'Popover',
31
+ triggers = defaultValue('triggers'),
32
+ cssClasses = defaultValue('cssClasses'),
33
+ showCloseButton = defaultValue('showCloseButton'),
34
+ } = {}) => ({
35
+ placement,
36
+ title,
37
+ triggers,
38
+ cssClasses,
39
+ showCloseButton,
40
+ });
41
+
42
+ export const Default = (_args, { viewMode, argTypes }) => ({
43
+ viewMode,
44
+ components,
45
+ props: Object.keys(argTypes),
46
+ template: getTemplate('popover-with-props'),
47
+ });
48
+ Default.args = generateProps();
42
49
 
43
- function generateProps({ placement = popoverPlacements.top, title = 'Popover', triggers } = {}) {
44
- return {
50
+ export const WithCloseButton = (_args, { viewMode, argTypes }) => ({
51
+ viewMode,
52
+ components,
53
+ props: Object.keys(argTypes),
54
+ template: getTemplate('popover-with-close-button'),
55
+ });
56
+ WithCloseButton.args = generateProps({
57
+ showCloseButton: true,
58
+ });
59
+
60
+ export const OnClick = (_args, { viewMode, argTypes }) => ({
61
+ viewMode,
62
+ components,
63
+ props: Object.keys(argTypes),
64
+ template: getTemplate(
65
+ 'popover-button-click',
66
+ `
67
+ <template #title>
68
+ <span data-testid="popover-title">Popover title</span>
69
+ </template>
70
+ `
71
+ ),
72
+ });
73
+ OnClick.args = generateProps({
74
+ triggers: 'click',
75
+ });
76
+ OnClick.parameters = {
77
+ storyshots: { disable: true },
78
+ };
79
+
80
+ export default {
81
+ title: 'base/popover',
82
+ component: GlPopover,
83
+ parameters: {
84
+ knobs: { disable: true },
85
+ bootstrapComponent: 'b-popover',
86
+ },
87
+ argTypes: {
45
88
  placement: {
46
- type: String,
47
- default: select('placement', popoverPlacements, placement),
89
+ options: Object.values(popoverPlacements),
90
+ control: {
91
+ type: 'select',
92
+ },
48
93
  },
49
94
  title: {
50
- type: String,
51
- default: text('title', title),
95
+ control: { type: 'text' },
52
96
  },
53
- triggers: {
54
- type: String,
55
- default: text('hover focus', triggers),
56
- },
57
- };
58
- }
59
-
60
- documentedStoriesOf('base/popover', '')
61
- .addDecorator(withKnobs)
62
- .add('default', () => ({
63
- components,
64
- template,
65
- props: generateProps(),
66
- }))
67
- .add('with close button', () => ({
68
- components,
69
- template: `
70
- <div class="gl-display-flex gl-justify-content-center gl-p-6">
71
- <gl-button id="pop-with-close-button">{{placement}}</gl-button>
72
- <gl-popover
73
- target="pop-with-close-button"
74
- data-testid="popover-with-close-button"
75
- triggers="hover focus"
76
- :title="title"
77
- :placement="placement"
78
- content="${contentString}"
79
- show
80
- show-close-button
81
- />
82
- </div>
83
- `,
84
- props: generateProps(),
85
- }))
86
- .add(
87
- 'on click',
88
- () => ({
89
- components,
90
- template: scopedSlotTemplate,
91
- props: generateProps(),
92
- }),
93
- { storyshots: false }
94
- );
97
+ },
98
+ };
@@ -18,6 +18,11 @@ export default {
18
18
  required: false,
19
19
  default: () => [],
20
20
  },
21
+ /**
22
+ * Space-separated triggers for the popover.
23
+ *
24
+ * @values click, hover, focus, manual
25
+ */
21
26
  triggers: {
22
27
  type: String,
23
28
  required: false,
@@ -45,6 +50,9 @@ export default {
45
50
  methods: {
46
51
  close(e) {
47
52
  this.$refs[popoverRefName].doClose();
53
+ /**
54
+ * Emitted when the close button is clicked (requires showCloseButton to be `true`).
55
+ */
48
56
  this.$emit('close-button-clicked', e);
49
57
  },
50
58
  },
@@ -1,4 +1,4 @@
1
- import { GlProgressBar } from '../../../../index';
1
+ import { GlProgressBar } from '../../../index';
2
2
  import { variantOptions } from '../../../utils/constants';
3
3
 
4
4
  const generateProps = ({ value = 30, variant = variantOptions.primary } = {}) => ({
@@ -52,6 +52,9 @@ export default {
52
52
  additionalInfo:
53
53
  'Container for tooltip. Valid values: DOM node, selector string or `false` for default',
54
54
  },
55
+ searchButtonAttributes: {
56
+ additionalInfo: 'HTML attributes to add to the search button',
57
+ },
55
58
  },
56
59
  events: [
57
60
  {
@@ -25,6 +25,7 @@ describe('search box by click component', () => {
25
25
  };
26
26
 
27
27
  const findClearIcon = () => wrapper.findComponent(ClearIcon);
28
+ const findSearchButton = () => wrapper.find('[data-testid="search-button"]');
28
29
 
29
30
  it('emits input event when input changes', async () => {
30
31
  createComponent({ value: 'somevalue' });
@@ -125,8 +126,8 @@ describe('search box by click component', () => {
125
126
  });
126
127
 
127
128
  it('displays disabled search button', () => {
128
- expect(wrapper.findComponent({ ref: 'searchButton' }).exists()).toBe(true);
129
- expect(wrapper.findComponent({ ref: 'searchButton' }).attributes('disabled')).toBe('true');
129
+ expect(findSearchButton().exists()).toBe(true);
130
+ expect(findSearchButton().attributes('disabled')).toBe('true');
130
131
  });
131
132
 
132
133
  it('does not render clear icon even with value', () => {
@@ -145,9 +146,19 @@ describe('search box by click component', () => {
145
146
 
146
147
  it('emits submit event when search button is pressed', async () => {
147
148
  createComponent({ value: 'some-input' });
148
- wrapper.findComponent({ ref: 'searchButton' }).vm.$emit('click');
149
+ findSearchButton().vm.$emit('click');
149
150
 
150
151
  await wrapper.vm.$nextTick();
151
152
  expect(wrapper.emitted().submit[0]).toEqual(['some-input']);
152
153
  });
154
+
155
+ it('adds `searchButtonAttributes` prop to search button', () => {
156
+ const searchButtonAttributes = { 'data-qa-selector': 'foo-bar' };
157
+
158
+ createComponent({ searchButtonAttributes });
159
+
160
+ expect(findSearchButton().attributes('data-qa-selector')).toBe(
161
+ searchButtonAttributes['data-qa-selector']
162
+ );
163
+ });
153
164
  });
@@ -1,6 +1,6 @@
1
1
  import { withKnobs, boolean, text } from '@storybook/addon-knobs';
2
2
  import { documentedStoriesOf } from '../../../../documentation/documented_stories';
3
- import { GlSearchBoxByClick } from '../../../../index';
3
+ import { GlSearchBoxByClick } from '../../../index';
4
4
  import readme from './search_box_by_click.md';
5
5
 
6
6
  const components = {
@@ -84,6 +84,11 @@ export default {
84
84
  validator: (value) =>
85
85
  value === false || typeof value === 'string' || value instanceof HTMLElement,
86
86
  },
87
+ searchButtonAttributes: {
88
+ type: Object,
89
+ required: false,
90
+ default: () => ({}),
91
+ },
87
92
  },
88
93
  data() {
89
94
  return {
@@ -216,11 +221,13 @@ export default {
216
221
  />
217
222
  <template #append class="gl-search-box-by-click-input-group-control">
218
223
  <gl-button
224
+ v-bind="searchButtonAttributes"
219
225
  ref="searchButton"
220
226
  class="gl-search-box-by-click-search-button"
221
227
  icon="search"
222
228
  :disabled="disabled"
223
229
  aria-label="Search"
230
+ data-testid="search-button"
224
231
  @click="search(currentValue)"
225
232
  />
226
233
  </template>
@@ -1,6 +1,6 @@
1
1
  import { withKnobs, boolean, text } from '@storybook/addon-knobs';
2
2
  import { documentedStoriesOf } from '../../../../documentation/documented_stories';
3
- import { GlSearchBoxByType } from '../../../../index';
3
+ import { GlSearchBoxByType } from '../../../index';
4
4
  import readme from './search_box_by_type.md';
5
5
 
6
6
  const components = {