@gitlab/ui 32.45.0 → 32.48.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 (139) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/config.js +15 -3
  3. package/dist/components/base/avatar_labeled/avatar_labeled.documentation.js +2 -9
  4. package/dist/components/base/avatars_inline/avatars_inline.documentation.js +2 -5
  5. package/dist/components/base/form/form_combobox/form_combobox.documentation.js +2 -9
  6. package/dist/components/base/form/form_combobox/form_combobox.js +5 -0
  7. package/dist/components/base/form/form_group/form_group.js +11 -1
  8. package/dist/components/base/form/input_group_text/input_group_text.documentation.js +1 -5
  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/skeleton_loader/skeleton_loader.documentation.js +2 -28
  12. package/dist/components/base/skeleton_loader/skeleton_loader.js +30 -0
  13. package/dist/components/charts/discrete_scatter/discrete_scatter.documentation.js +1 -7
  14. package/dist/components/charts/gauge/gauge.documentation.js +2 -6
  15. package/dist/components/charts/stacked_column/stacked_column.documentation.js +2 -5
  16. package/dist/components/charts/tooltip/tooltip.documentation.js +1 -5
  17. package/dist/components/utilities/intersperse/intersperse.documentation.js +2 -5
  18. package/dist/config.js +15 -3
  19. package/dist/index.css +1 -1
  20. package/dist/index.css.map +1 -1
  21. package/documentation/documented_stories.js +11 -0
  22. package/package.json +1 -1
  23. package/src/components/base/avatar_labeled/avatar_labeled.documentation.js +0 -9
  24. package/src/components/base/avatar_labeled/avatar_labeled.md +2 -5
  25. package/src/components/base/avatar_labeled/avatar_labeled.stories.js +68 -62
  26. package/src/components/base/avatar_labeled/avatar_labeled.vue +1 -0
  27. package/src/components/base/avatars_inline/avatars_inline.documentation.js +0 -2
  28. package/src/components/base/avatars_inline/avatars_inline.md +1 -3
  29. package/src/components/base/avatars_inline/avatars_inline.stories.js +49 -44
  30. package/src/components/base/form/form_combobox/form_combobox.documentation.js +0 -8
  31. package/src/components/base/form/form_combobox/form_combobox.md +0 -2
  32. package/src/components/base/form/form_combobox/form_combobox.stories.js +30 -30
  33. package/src/components/base/form/form_combobox/form_combobox.vue +4 -0
  34. package/src/components/base/form/form_group/form_group.scss +4 -0
  35. package/src/components/base/form/form_group/form_group.spec.js +66 -64
  36. package/src/components/base/form/form_group/form_group.stories.js +36 -13
  37. package/src/components/base/form/form_group/form_group.vue +15 -2
  38. package/src/components/base/form/input_group_text/input_group_text.documentation.js +0 -3
  39. package/src/components/base/form/input_group_text/input_group_text.stories.js +24 -18
  40. package/src/components/base/label/label.documentation.js +2 -12
  41. package/src/components/base/label/label.md +2 -7
  42. package/src/components/base/label/label.stories.js +66 -92
  43. package/src/components/base/label/label.vue +22 -2
  44. package/src/components/base/skeleton_loader/skeleton_loader.documentation.js +0 -27
  45. package/src/components/base/skeleton_loader/skeleton_loader.md +0 -2
  46. package/src/components/base/skeleton_loader/skeleton_loader.stories.js +23 -9
  47. package/src/components/base/skeleton_loader/skeleton_loader.vue +24 -0
  48. package/src/components/charts/discrete_scatter/discrete_scatter.documentation.js +0 -5
  49. package/src/components/charts/discrete_scatter/discrete_scatter.stories.js +34 -46
  50. package/src/components/charts/gauge/gauge.documentation.js +0 -3
  51. package/src/components/charts/gauge/gauge.md +0 -2
  52. package/src/components/charts/gauge/gauge.stories.js +70 -86
  53. package/src/components/charts/stacked_column/stacked_column.documentation.js +0 -2
  54. package/src/components/charts/stacked_column/stacked_column.md +0 -2
  55. package/src/components/charts/stacked_column/stacked_column.stories.js +74 -99
  56. package/src/components/charts/tooltip/tooltip.documentation.js +0 -3
  57. package/src/components/charts/tooltip/tooltip.stories.js +59 -44
  58. package/src/components/utilities/intersperse/intersperse.documentation.js +0 -2
  59. package/src/components/utilities/intersperse/intersperse.md +0 -2
  60. package/src/components/utilities/intersperse/intersperse.stories.js +38 -38
  61. package/dist/components/base/avatar_labeled/examples/avatar.labeled.example.js +0 -38
  62. package/dist/components/base/avatar_labeled/examples/avatar.labeled_badges.example.js +0 -38
  63. package/dist/components/base/avatar_labeled/examples/avatar.labeled_links.example.js +0 -38
  64. package/dist/components/base/avatar_labeled/examples/avatar.labeled_tooltip.example.js +0 -38
  65. package/dist/components/base/avatar_labeled/examples/index.js +0 -31
  66. package/dist/components/base/avatars_inline/examples/avatars.inline.example.js +0 -58
  67. package/dist/components/base/avatars_inline/examples/avatars.inline_large.example.js +0 -58
  68. package/dist/components/base/avatars_inline/examples/avatars.inline_links_and_tooltips.example.js +0 -70
  69. package/dist/components/base/avatars_inline/examples/avatars.inline_links_and_tooltips_badge.example.js +0 -70
  70. package/dist/components/base/avatars_inline/examples/index.js +0 -31
  71. package/dist/components/base/form/form_combobox/examples/form_combobox.basic.example.js +0 -50
  72. package/dist/components/base/form/form_combobox/examples/index.js +0 -13
  73. package/dist/components/base/form/input_group_text/examples/index.js +0 -13
  74. package/dist/components/base/form/input_group_text/examples/input_group_text.basic.example.js +0 -38
  75. package/dist/components/base/label/examples/index.js +0 -19
  76. package/dist/components/base/label/examples/label.basic.example.js +0 -38
  77. package/dist/components/base/label/examples/label.scoped.example.js +0 -38
  78. package/dist/components/base/skeleton_loader/examples/ci_header_skeleton.basic.example.js +0 -38
  79. package/dist/components/base/skeleton_loader/examples/default_skeleton.basic.example.js +0 -38
  80. package/dist/components/base/skeleton_loader/examples/default_skeleton_custom_props.basic.example.js +0 -38
  81. package/dist/components/base/skeleton_loader/examples/index.js +0 -37
  82. package/dist/components/base/skeleton_loader/examples/issue_card_skeleton.basic.example.js +0 -38
  83. package/dist/components/base/skeleton_loader/examples/job_log_skeleton.basic.example.js +0 -38
  84. package/dist/components/charts/discrete_scatter/examples/discrete_scatter.basic.example.js +0 -51
  85. package/dist/components/charts/discrete_scatter/examples/index.js +0 -13
  86. package/dist/components/charts/gauge/examples/gauge.basic.example.js +0 -38
  87. package/dist/components/charts/gauge/examples/gauge.no_thresholds.example.js +0 -38
  88. package/dist/components/charts/gauge/examples/gauge.no_value.example.js +0 -38
  89. package/dist/components/charts/gauge/examples/gauge.with_text.example.js +0 -38
  90. package/dist/components/charts/gauge/examples/index.js +0 -31
  91. package/dist/components/charts/stacked_column/examples/index.js +0 -13
  92. package/dist/components/charts/stacked_column/examples/stacked_column.basic.example.js +0 -46
  93. package/dist/components/charts/tooltip/examples/chart_tooltip.basic.example.js +0 -54
  94. package/dist/components/charts/tooltip/examples/index.js +0 -13
  95. package/dist/components/utilities/intersperse/examples/index.js +0 -31
  96. package/dist/components/utilities/intersperse/examples/intersperse.custom_last_separator.example.js +0 -38
  97. package/dist/components/utilities/intersperse/examples/intersperse.custom_last_separator_two_items.example.js +0 -38
  98. package/dist/components/utilities/intersperse/examples/intersperse.custom_separator.example.js +0 -38
  99. package/dist/components/utilities/intersperse/examples/intersperse.default.example.js +0 -38
  100. package/src/components/base/avatar_labeled/examples/avatar.labeled.example.vue +0 -8
  101. package/src/components/base/avatar_labeled/examples/avatar.labeled_badges.example.vue +0 -17
  102. package/src/components/base/avatar_labeled/examples/avatar.labeled_links.example.vue +0 -10
  103. package/src/components/base/avatar_labeled/examples/avatar.labeled_tooltip.example.vue +0 -10
  104. package/src/components/base/avatar_labeled/examples/index.js +0 -36
  105. package/src/components/base/avatars_inline/examples/avatars.inline.example.vue +0 -18
  106. package/src/components/base/avatars_inline/examples/avatars.inline_large.example.vue +0 -18
  107. package/src/components/base/avatars_inline/examples/avatars.inline_links_and_tooltips.example.vue +0 -24
  108. package/src/components/base/avatars_inline/examples/avatars.inline_links_and_tooltips_badge.example.vue +0 -31
  109. package/src/components/base/avatars_inline/examples/index.js +0 -36
  110. package/src/components/base/form/form_combobox/examples/form_combobox.basic.example.vue +0 -31
  111. package/src/components/base/form/form_combobox/examples/index.js +0 -15
  112. package/src/components/base/form/input_group_text/examples/index.js +0 -15
  113. package/src/components/base/form/input_group_text/examples/input_group_text.basic.example.vue +0 -3
  114. package/src/components/base/label/examples/index.js +0 -22
  115. package/src/components/base/label/examples/label.basic.example.vue +0 -3
  116. package/src/components/base/label/examples/label.scoped.example.vue +0 -3
  117. package/src/components/base/skeleton_loader/examples/ci_header_skeleton.basic.example.vue +0 -10
  118. package/src/components/base/skeleton_loader/examples/default_skeleton.basic.example.vue +0 -3
  119. package/src/components/base/skeleton_loader/examples/default_skeleton_custom_props.basic.example.vue +0 -9
  120. package/src/components/base/skeleton_loader/examples/index.js +0 -44
  121. package/src/components/base/skeleton_loader/examples/issue_card_skeleton.basic.example.vue +0 -26
  122. package/src/components/base/skeleton_loader/examples/job_log_skeleton.basic.example.vue +0 -13
  123. package/src/components/charts/discrete_scatter/discrete_scatter.md +0 -1
  124. package/src/components/charts/discrete_scatter/examples/discrete_scatter.basic.example.vue +0 -31
  125. package/src/components/charts/discrete_scatter/examples/index.js +0 -15
  126. package/src/components/charts/gauge/examples/gauge.basic.example.vue +0 -5
  127. package/src/components/charts/gauge/examples/gauge.no_thresholds.example.vue +0 -5
  128. package/src/components/charts/gauge/examples/gauge.no_value.example.vue +0 -5
  129. package/src/components/charts/gauge/examples/gauge.with_text.example.vue +0 -12
  130. package/src/components/charts/gauge/examples/index.js +0 -36
  131. package/src/components/charts/stacked_column/examples/index.js +0 -15
  132. package/src/components/charts/stacked_column/examples/stacked_column.basic.example.vue +0 -18
  133. package/src/components/charts/tooltip/examples/chart_tooltip.basic.example.vue +0 -32
  134. package/src/components/charts/tooltip/examples/index.js +0 -15
  135. package/src/components/utilities/intersperse/examples/index.js +0 -36
  136. package/src/components/utilities/intersperse/examples/intersperse.custom_last_separator.example.vue +0 -7
  137. package/src/components/utilities/intersperse/examples/intersperse.custom_last_separator_two_items.example.vue +0 -6
  138. package/src/components/utilities/intersperse/examples/intersperse.custom_separator.example.vue +0 -7
  139. package/src/components/utilities/intersperse/examples/intersperse.default.example.vue +0 -7
@@ -60,6 +60,7 @@ export const setupStorybookReadme = () =>
60
60
  'GlTableLite',
61
61
  'GlAlert',
62
62
  'GlSparklineChart',
63
+ 'GlAvatarsInline',
63
64
  'GlSprintf',
64
65
  'GlLink',
65
66
  'GlChart',
@@ -88,7 +89,9 @@ export const setupStorybookReadme = () =>
88
89
  'GlFormCheckbox',
89
90
  'GlAccordion',
90
91
  'GlAccordionItem',
92
+ 'GlIntersperse',
91
93
  'GlDaterangePicker',
94
+ 'GlAvatarLabeled',
92
95
  'GlBarChart',
93
96
  'GlCarousel',
94
97
  'GlMarkdown',
@@ -100,6 +103,14 @@ export const setupStorybookReadme = () =>
100
103
  'GlAvatar',
101
104
  'GlAvatarLink',
102
105
  'GlPagination',
106
+ 'GlSkeletonLoader',
107
+ 'GlLabel',
108
+ 'GlStackedColumnChart',
109
+ 'GlDiscreteScatterChart',
110
+ 'GlFormCombobox',
111
+ 'GlChartTooltip',
112
+ 'GlInputGroupText',
113
+ 'GlGaugeChart',
103
114
  ],
104
115
  components: {
105
116
  GlComponentDocumentation,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitlab/ui",
3
- "version": "32.45.0",
3
+ "version": "32.48.0",
4
4
  "description": "GitLab UI Components",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -1,15 +1,6 @@
1
1
  import description from './avatar_labeled.md';
2
- import examples from './examples';
3
2
 
4
3
  export default {
5
4
  followsDesignSystem: true,
6
5
  description,
7
- examples,
8
- slots: [
9
- {
10
- name: 'meta',
11
- description:
12
- 'Meta data to add to the avatar. Generally used for badges or user status emoji.',
13
- },
14
- ],
15
6
  };
@@ -1,6 +1,3 @@
1
- # Avatar labeled
2
-
3
- <!-- STORY -->
4
1
  ## Usage
5
2
 
6
3
  Avatars may also be adjacent to a text alternative, such as a user or project name. In these cases,
@@ -12,7 +9,7 @@ properties as the avatar component to modify the avatar’s shape and size.
12
9
 
13
10
  ## Using the component
14
11
 
15
- ~~~js
12
+ ```js
16
13
  <gl-avatar-labeled
17
14
  :shape="shape"
18
15
  :size="size"
@@ -20,4 +17,4 @@ properties as the avatar component to modify the avatar’s shape and size.
20
17
  :label="label"
21
18
  :sub-label="subLabel"
22
19
  />
23
- ~~~
20
+ ```
@@ -1,62 +1,32 @@
1
- import { text, withKnobs, select } from '@storybook/addon-knobs';
2
1
  import Vue from 'vue';
3
- import { documentedStoriesOf } from '../../../../documentation/documented_stories';
4
2
  import { GlTooltipDirective } from '../../../directives/tooltip';
5
3
  import { avatarSizeOptions, avatarShapeOptions, tooltipPlacements } from '../../../utils/constants';
6
4
  import readme from './avatar_labeled.md';
7
5
 
8
6
  Vue.directive('gl-tooltip', GlTooltipDirective);
9
7
 
10
- function generateProps() {
11
- const props = {
12
- label: {
13
- type: String,
14
- default: text('label', 'GitLab User'),
15
- },
16
- subLabel: {
17
- type: String,
18
- default: text('subLabel', '@gitlab'),
19
- },
20
- size: {
21
- type: Number,
22
- default: select('size', avatarSizeOptions, 32),
23
- },
24
- shape: {
25
- type: String,
26
- default: select('shape', avatarShapeOptions, 'circle'),
27
- },
28
- src: {
29
- type: String,
30
- default: text(
31
- 'src',
32
- 'https://assets.gitlab-static.net/uploads/-/system/group/avatar/9970/logo-extra-whitespace.png?width=64'
33
- ),
34
- },
35
- };
36
-
37
- return props;
38
- }
39
-
40
- function generateTooltipProps() {
41
- const props = {
42
- tooltipText: {
43
- type: String,
44
- default: text('tooltipText', 'Avatar tooltip'),
45
- },
46
- placement: {
47
- type: String,
48
- default: select('placement', tooltipPlacements, 'top'),
49
- },
50
- };
8
+ const generateProps = ({
9
+ label = 'GitLab User',
10
+ subLabel = '@gitlab',
11
+ size = 32,
12
+ shape = 'circle',
13
+ src = 'https://assets.gitlab-static.net/uploads/-/system/group/avatar/9970/logo-extra-whitespace.png?width=64',
14
+ } = {}) => ({
15
+ label,
16
+ subLabel,
17
+ size,
18
+ shape,
19
+ src,
20
+ });
51
21
 
52
- return props;
53
- }
22
+ const generateTooltipProps = ({ tooltipText = 'Avatar tooltip', placement = 'top' } = {}) => ({
23
+ tooltipText,
24
+ placement,
25
+ });
54
26
 
55
- documentedStoriesOf('base/avatar/labeled', readme)
56
- .addDecorator(withKnobs)
57
- .add('default', () => ({
58
- props: generateProps(),
59
- template: `
27
+ export const Default = (args, { argTypes }) => ({
28
+ props: Object.keys(argTypes),
29
+ template: `
60
30
  <gl-avatar-labeled
61
31
  :shape="shape"
62
32
  :size="size"
@@ -65,13 +35,12 @@ documentedStoriesOf('base/avatar/labeled', readme)
65
35
  :sub-label="subLabel"
66
36
  />
67
37
  `,
68
- }))
69
- .add('with-tooltip', () => ({
70
- props: {
71
- ...generateProps(),
72
- ...generateTooltipProps(),
73
- },
74
- template: `
38
+ });
39
+ Default.args = generateProps();
40
+
41
+ export const WithTooltip = (args, { argTypes }) => ({
42
+ props: Object.keys(argTypes),
43
+ template: `
75
44
  <gl-avatar-labeled
76
45
  :shape="shape"
77
46
  :size="size"
@@ -82,10 +51,20 @@ documentedStoriesOf('base/avatar/labeled', readme)
82
51
  v-gl-tooltip="{ placement }"
83
52
  />
84
53
  `,
85
- }))
86
- .add('with-badges', () => ({
87
- props: generateProps(),
88
- template: `
54
+ });
55
+ WithTooltip.args = { ...generateProps(), ...generateTooltipProps() };
56
+ WithTooltip.argTypes = {
57
+ placement: {
58
+ control: {
59
+ type: 'select',
60
+ options: tooltipPlacements,
61
+ },
62
+ },
63
+ };
64
+
65
+ export const WithBadges = (args, { argTypes }) => ({
66
+ props: Object.keys(argTypes),
67
+ template: `
89
68
  <gl-avatar-labeled
90
69
  :shape="shape"
91
70
  :size="size"
@@ -103,4 +82,31 @@ documentedStoriesOf('base/avatar/labeled', readme)
103
82
  </template>
104
83
  </gl-avatar-labeled>
105
84
  `,
106
- }));
85
+ });
86
+ WithBadges.args = generateProps();
87
+
88
+ export default {
89
+ title: 'base/avatar/labeled',
90
+ parameters: {
91
+ knobs: { disable: true },
92
+ docs: {
93
+ description: {
94
+ component: readme,
95
+ },
96
+ },
97
+ },
98
+ argTypes: {
99
+ size: {
100
+ control: {
101
+ type: 'select',
102
+ options: avatarSizeOptions,
103
+ },
104
+ },
105
+ shape: {
106
+ control: {
107
+ type: 'select',
108
+ options: avatarShapeOptions,
109
+ },
110
+ },
111
+ },
112
+ };
@@ -49,6 +49,7 @@ export default {
49
49
  <span class="gl-avatar-labeled-label">{{ label }}</span>
50
50
  </gl-link>
51
51
  <span v-else class="gl-avatar-labeled-label">{{ label }}</span>
52
+ <!-- @slot Metadata to add to the avatar. Generally used for badges or user status emoji. -->
52
53
  <slot name="meta"></slot>
53
54
  </div>
54
55
  <gl-link v-if="hasSubLabelLink" :href="subLabelLink" class="gl-avatar-link">
@@ -1,8 +1,6 @@
1
1
  import * as description from './avatars_inline.md';
2
- import examples from './examples';
3
2
 
4
3
  export default {
5
4
  followsDesignSystem: true,
6
5
  description,
7
- examples,
8
6
  };
@@ -1,12 +1,10 @@
1
- ## Avatars inline
2
-
3
1
  Use `<avatars-inline />` to display multiple avatars organized in a single row.
4
2
 
5
3
  ### Basic usage
6
4
 
7
5
  The `avatars` property accepts an array of objects that contains the avatar properties. By default,
8
6
  `<avatars-inline />` expects each object contained in the array to have the same shape as the
9
- properties of the `<avatar />` component. You can customize the display of each avatar by
7
+ properties of the `<avatar />` component. You can customize the display of each avatar by
10
8
  overriding the default slot:
11
9
 
12
10
  ```html
@@ -1,7 +1,4 @@
1
- import { number, boolean, object, select, withKnobs } from '@storybook/addon-knobs';
2
- import { documentedStoriesOf } from '../../../../documentation/documented_stories';
3
1
  import { avatarsInlineSizeOptions } from '../../../utils/constants';
4
-
5
2
  import readme from './avatars_inline.md';
6
3
 
7
4
  const defaultAvatars = [
@@ -12,53 +9,61 @@ const defaultAvatars = [
12
9
  { src: 'https://picsum.photos/id/1012/32' },
13
10
  ];
14
11
 
15
- function generateProps(avatars = defaultAvatars) {
16
- const props = {
17
- maxVisible: {
18
- type: Number,
19
- default: number('maxVisible', 2),
20
- },
21
- collapsed: {
22
- type: Boolean,
23
- default: boolean('collapsed', true),
24
- },
25
- size: {
26
- type: Number,
27
- default: select('size', avatarsInlineSizeOptions, 24),
28
- },
29
- avatars: {
30
- type: Array,
31
- default: object('avatars', avatars),
32
- },
33
- };
34
-
35
- return props;
36
- }
12
+ const generateProps = (
13
+ avatars = defaultAvatars,
14
+ { maxVisible = 2, collapsed = true, avatarSize = 24 } = {}
15
+ ) => ({
16
+ maxVisible,
17
+ collapsed,
18
+ avatarSize,
19
+ avatars,
20
+ });
37
21
 
38
- documentedStoriesOf('base/avatar/avatars-inline', readme)
39
- .addDecorator(withKnobs)
40
- .add('default', () => ({
41
- props: generateProps(),
42
- template: `
43
- <gl-avatars-inline :avatars="avatars" :collapsed="collapsed" :avatar-size="size" :max-visible="maxVisible">
22
+ export const Default = (args, { argTypes }) => ({
23
+ props: Object.keys(argTypes),
24
+ template: `
25
+ <gl-avatars-inline :avatars="avatars" :collapsed="collapsed" :avatar-size="avatarSize" :max-visible="maxVisible">
44
26
  </gl-avatars-inline>
45
27
  `,
46
- }))
47
- .add('with links and tooltips', () => ({
48
- props: generateProps(
49
- defaultAvatars.map((avatar, index) => ({
50
- ...avatar,
51
- href: '//gitlab.com',
52
- tooltip: `Avatar ${index}`,
53
- }))
54
- ),
55
- template: `
56
- <gl-avatars-inline :avatars="avatars" :collapsed="collapsed" :avatar-size="size" :max-visible="maxVisible">
28
+ });
29
+ Default.args = generateProps();
30
+
31
+ export const WithLinksAndTooltips = (args, { argTypes }) => ({
32
+ props: Object.keys(argTypes),
33
+ template: `
34
+ <gl-avatars-inline :avatars="avatars" :collapsed="collapsed" :avatar-size="avatarSize" :max-visible="maxVisible">
57
35
  <template #avatar="{ avatar }">
58
36
  <gl-avatar-link target="blank" :href="avatar.href" v-gl-tooltip :title="avatar.tooltip">
59
- <gl-avatar :src="avatar.src" :size="size" />
37
+ <gl-avatar :src="avatar.src" :size="avatarSize" />
60
38
  </gl-avatar-link>
61
39
  </template>
62
40
  </gl-avatars-inline>
63
41
  `,
64
- }));
42
+ });
43
+ WithLinksAndTooltips.args = generateProps(
44
+ defaultAvatars.map((avatar, index) => ({
45
+ ...avatar,
46
+ href: '//gitlab.com',
47
+ tooltip: `Avatar ${index}`,
48
+ }))
49
+ );
50
+
51
+ export default {
52
+ title: 'base/avatar/avatars-inline',
53
+ parameters: {
54
+ knobs: { disable: true },
55
+ docs: {
56
+ description: {
57
+ component: readme,
58
+ },
59
+ },
60
+ },
61
+ argTypes: {
62
+ avatarSize: {
63
+ control: {
64
+ type: 'select',
65
+ options: avatarsInlineSizeOptions,
66
+ },
67
+ },
68
+ },
69
+ };
@@ -1,14 +1,6 @@
1
- import examples from './examples';
2
1
  import * as description from './form_combobox.md';
3
2
 
4
3
  export default {
5
4
  followsDesignSystem: true,
6
5
  description,
7
- examples,
8
- events: [
9
- {
10
- event: 'value-selected',
11
- description: 'Emitted when a value is selected.',
12
- },
13
- ],
14
6
  };
@@ -1,5 +1,3 @@
1
- # GlFormCombobox
2
-
3
1
  Use this component to add a [`FormInput`](/?path=/story/base-form-form-input--default) component
4
2
  with synchronous autocomplete dropdown. It behaves as follows:
5
3
 
@@ -1,41 +1,41 @@
1
- import { withKnobs, object, text } from '@storybook/addon-knobs';
2
- import { documentedStoriesOf } from '../../../../../documentation/documented_stories';
3
1
  import { tokenList, labelText } from './constants';
4
2
  import readme from './form_combobox.md';
5
3
  import GlFormCombobox from './form_combobox.vue';
6
4
 
7
- const components = {
8
- GlFormCombobox,
9
- };
10
-
11
- const getProps = () => {
12
- return {
13
- tokenList: {
14
- type: Array,
15
- default: object('tokens', tokenList),
16
- },
17
- labelText: {
18
- type: String,
19
- default: text('label text', labelText),
20
- },
21
- };
22
- };
5
+ const getProps = () => ({
6
+ tokenList,
7
+ labelText,
8
+ });
23
9
 
24
- documentedStoriesOf('base/form/form-combobox', readme)
25
- .addDecorator(withKnobs)
26
- .add('default', () => ({
27
- components,
28
- props: getProps(),
29
- data: () => {
30
- return {
31
- value: '',
32
- };
33
- },
34
- template: `
10
+ const Template = (args) => ({
11
+ components: { GlFormCombobox },
12
+ data: () => {
13
+ return {
14
+ value: '',
15
+ };
16
+ },
17
+ props: Object.keys(args),
18
+ template: `
35
19
  <gl-form-combobox
36
20
  v-model="value"
37
21
  :token-list="tokenList"
38
22
  :labelText="labelText"
39
23
  />
40
24
  `,
41
- }));
25
+ });
26
+
27
+ export const Default = Template.bind({});
28
+ Default.args = getProps();
29
+
30
+ export default {
31
+ title: 'base/form/form-combobox',
32
+ component: GlFormCombobox,
33
+ parameters: {
34
+ knobs: { disable: true },
35
+ docs: {
36
+ description: {
37
+ component: readme,
38
+ },
39
+ },
40
+ },
41
+ };
@@ -128,6 +128,10 @@ export default {
128
128
  selectToken(value) {
129
129
  this.$emit('input', value);
130
130
  this.closeSuggestions();
131
+ /**
132
+ * Emitted when a value is selected.
133
+ * @event value-selected
134
+ */
131
135
  this.$emit('value-selected', value);
132
136
  },
133
137
  },
@@ -13,6 +13,10 @@
13
13
  }
14
14
  }
15
15
 
16
+ .optional-label {
17
+ @include gl-font-weight-normal;
18
+ }
19
+
16
20
  .invalid-feedback,
17
21
  .text-gl-muted {
18
22
  @include gl-font-base;
@@ -1,17 +1,17 @@
1
- import { shallowMount, mount } from '@vue/test-utils';
1
+ import { shallowMount } from '@vue/test-utils';
2
2
  import { BFormGroup } from 'bootstrap-vue';
3
- import GlFormText from '../form_text/form_text.vue';
4
3
  import GlFormGroup from './form_group.vue';
5
4
 
6
5
  describe('Form group component', () => {
7
6
  let wrapper;
8
7
 
9
- const findDescription = () => {
10
- return wrapper.find('[data-testid="label-description"]');
11
- };
8
+ const findByTestId = (testId) => wrapper.find(`[data-testid="${testId}"]`);
9
+
10
+ const findLabelDescription = () => findByTestId('label-description');
11
+ const findOptionalLabel = () => findByTestId('optional-label');
12
12
 
13
- const createComponent = (options, mountFn = shallowMount) => {
14
- wrapper = mountFn(GlFormGroup, {
13
+ const createComponent = (options) => {
14
+ wrapper = shallowMount(GlFormGroup, {
15
15
  ...options,
16
16
  });
17
17
  };
@@ -35,73 +35,75 @@ describe('Form group component', () => {
35
35
  }
36
36
  );
37
37
 
38
- describe('description slot', () => {
39
- it('renders text when label-description prop is defined', () => {
40
- const labelDescription = 'description via props';
41
-
42
- createComponent(
43
- {
44
- propsData: {
45
- labelDescription,
46
- },
47
- },
48
- mount
49
- );
50
-
51
- expect(findDescription().text()).toBe(labelDescription);
52
- });
53
-
54
- it('renders a user provided label-description slot', () => {
55
- const labelDescription = 'description via slot';
56
-
57
- createComponent(
58
- {
59
- slots: {
60
- 'label-description': 'description via slot',
61
- },
62
- stubs: {
63
- GlFormText,
64
- },
65
- },
66
- mount
67
- );
68
-
69
- expect(findDescription().text()).toBe(labelDescription);
70
- });
38
+ describe('label-description slot', () => {
39
+ const labelDescriptionFromPropOptions = {
40
+ propsData: { labelDescription: 'label-description from props' },
41
+ };
42
+ const labelDescriptionFromSlotOptions = {
43
+ slots: { 'label-description': 'label-description from slots' },
44
+ };
45
+
46
+ it.each`
47
+ labelDescriptionFrom | options
48
+ ${'prop'} | ${labelDescriptionFromPropOptions}
49
+ ${'prop'} | ${labelDescriptionFromPropOptions}
50
+ ${'slot'} | ${labelDescriptionFromSlotOptions}
51
+ ${'slot'} | ${labelDescriptionFromSlotOptions}
52
+ `(
53
+ 'when label-description is provided from $labelDescriptionFrom',
54
+ ({ labelDescriptionFrom, options }) => {
55
+ createComponent({
56
+ ...options,
57
+ });
58
+
59
+ expect(findLabelDescription().text()).toContain(
60
+ `label-description from ${labelDescriptionFrom}`
61
+ );
62
+ }
63
+ );
71
64
  });
72
65
 
73
66
  describe('label slot', () => {
74
- it('renders text when label prop is defined', () => {
75
- const label = 'label via props';
76
-
77
- createComponent(
78
- {
67
+ const labelFromPropOptions = {
68
+ propsData: { label: 'label from props' },
69
+ };
70
+ const labelFromSlotOptions = {
71
+ slots: { label: 'label from slots' },
72
+ };
73
+
74
+ it.each`
75
+ labelFrom | options | optional | expectedOptional
76
+ ${'prop'} | ${labelFromPropOptions} | ${true} | ${true}
77
+ ${'prop'} | ${labelFromPropOptions} | ${false} | ${false}
78
+ ${'slot'} | ${labelFromSlotOptions} | ${true} | ${false}
79
+ ${'slot'} | ${labelFromSlotOptions} | ${false} | ${false}
80
+ `(
81
+ 'when label is provided from $labelFrom, `optional` is $optional',
82
+ ({ labelFrom, options, optional, expectedOptional }) => {
83
+ createComponent({
84
+ ...options,
79
85
  propsData: {
80
- label,
86
+ ...options.propsData,
87
+ optional,
81
88
  },
82
- },
83
- mount
84
- );
89
+ });
85
90
 
86
- expect(wrapper.text()).toBe(label);
87
- });
91
+ expect(wrapper.text()).toContain(`label from ${labelFrom}`);
92
+ expect(findOptionalLabel().exists()).toBe(expectedOptional);
93
+ }
94
+ );
88
95
 
89
- it('renders a user provided label slot', () => {
90
- const label = 'label via slot';
96
+ it('renders optionalText when `optional` is true', () => {
97
+ const optionalText = '(not required)';
91
98
 
92
- createComponent(
93
- {
94
- slots: {
95
- label: 'label via slot',
96
- },
97
- stubs: {
98
- GlFormText,
99
- },
99
+ createComponent({
100
+ propsData: {
101
+ optional: true,
102
+ optionalText,
100
103
  },
101
- mount
102
- );
104
+ });
103
105
 
104
- expect(wrapper.text()).toBe(label);
106
+ expect(findOptionalLabel().text()).toBe(optionalText);
105
107
  });
106
108
  });
107
109
  });