@gitlab/ui 38.0.1 → 38.2.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 (140) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +1 -1
  3. package/dist/components/base/breadcrumb/breadcrumb.js +10 -5
  4. package/dist/components/base/{filtered_search/examples/filtered_search.single_unique.example.js → breadcrumb/breadcrumb_item.js} +32 -28
  5. package/dist/components/base/dropdown/dropdown.documentation.js +1 -5
  6. package/dist/components/base/dropdown/dropdown_item.documentation.js +2 -3
  7. package/dist/components/base/filtered_search/filtered_search.documentation.js +2 -66
  8. package/dist/components/base/filtered_search/filtered_search.js +51 -20
  9. package/dist/components/base/filtered_search/filtered_search_suggestion.documentation.js +2 -8
  10. package/dist/components/base/filtered_search/filtered_search_suggestion.js +5 -1
  11. package/dist/components/base/filtered_search/filtered_search_suggestion_list.documentation.js +2 -7
  12. package/dist/components/base/filtered_search/filtered_search_suggestion_list.js +4 -0
  13. package/dist/components/base/filtered_search/filtered_search_term.documentation.js +2 -44
  14. package/dist/components/base/filtered_search/filtered_search_term.js +37 -0
  15. package/dist/components/base/filtered_search/filtered_search_token.documentation.js +2 -31
  16. package/dist/components/base/filtered_search/filtered_search_token.js +80 -23
  17. package/dist/components/base/filtered_search/filtered_search_token_segment.documentation.js +2 -46
  18. package/dist/components/base/filtered_search/filtered_search_token_segment.js +48 -0
  19. package/dist/components/base/filtered_search/filtered_search_utils.js +42 -9
  20. package/dist/components/base/form/form_checkbox_tree/form_checkbox_tree.documentation.js +2 -27
  21. package/dist/components/base/form/form_checkbox_tree/form_checkbox_tree.js +16 -1
  22. package/dist/components/charts/series_label/series_label.js +6 -1
  23. package/dist/index.css +1 -1
  24. package/dist/index.css.map +1 -1
  25. package/dist/utils/use_mock_intersection_observer.js +2 -2
  26. package/documentation/components_documentation.js +0 -4
  27. package/documentation/documented_stories.js +10 -1
  28. package/package.json +11 -9
  29. package/src/components/base/avatar_link/avatar_link.stories.js +2 -2
  30. package/src/components/base/breadcrumb/breadcrumb.spec.js +24 -10
  31. package/src/components/base/breadcrumb/breadcrumb.vue +11 -6
  32. package/src/components/base/breadcrumb/breadcrumb_item.spec.js +45 -0
  33. package/src/components/base/breadcrumb/breadcrumb_item.vue +43 -0
  34. package/src/components/base/dropdown/dropdown.documentation.js +0 -3
  35. package/src/components/base/dropdown/dropdown.md +7 -2
  36. package/src/components/base/dropdown/dropdown.stories.js +487 -439
  37. package/src/components/base/dropdown/dropdown_item.documentation.js +0 -1
  38. package/src/components/base/dropdown/dropdown_item.md +0 -6
  39. package/src/components/base/dropdown/dropdown_item.stories.js +107 -35
  40. package/src/components/base/filtered_search/filtered_search.documentation.js +0 -76
  41. package/src/components/base/filtered_search/filtered_search.md +3 -4
  42. package/src/components/base/filtered_search/filtered_search.spec.js +37 -12
  43. package/src/components/base/filtered_search/filtered_search.stories.js +260 -17
  44. package/src/components/base/filtered_search/filtered_search.vue +57 -14
  45. package/src/components/base/filtered_search/filtered_search_suggestion.documentation.js +0 -6
  46. package/src/components/base/filtered_search/filtered_search_suggestion.md +1 -7
  47. package/src/components/base/filtered_search/filtered_search_suggestion.stories.js +26 -18
  48. package/src/components/base/filtered_search/filtered_search_suggestion.vue +6 -0
  49. package/src/components/base/filtered_search/filtered_search_suggestion_list.documentation.js +0 -5
  50. package/src/components/base/filtered_search/filtered_search_suggestion_list.md +1 -7
  51. package/src/components/base/filtered_search/filtered_search_suggestion_list.stories.js +33 -25
  52. package/src/components/base/filtered_search/filtered_search_suggestion_list.vue +5 -0
  53. package/src/components/base/filtered_search/filtered_search_term.documentation.js +0 -41
  54. package/src/components/base/filtered_search/filtered_search_term.md +0 -2
  55. package/src/components/base/filtered_search/filtered_search_term.stories.js +33 -26
  56. package/src/components/base/filtered_search/filtered_search_term.vue +54 -0
  57. package/src/components/base/filtered_search/filtered_search_token.documentation.js +0 -26
  58. package/src/components/base/filtered_search/filtered_search_token.md +1 -3
  59. package/src/components/base/filtered_search/filtered_search_token.spec.js +31 -1
  60. package/src/components/base/filtered_search/filtered_search_token.stories.js +137 -132
  61. package/src/components/base/filtered_search/filtered_search_token.vue +93 -21
  62. package/src/components/base/filtered_search/filtered_search_token_segment.documentation.js +0 -43
  63. package/src/components/base/filtered_search/filtered_search_token_segment.md +0 -2
  64. package/src/components/base/filtered_search/filtered_search_token_segment.stories.js +86 -79
  65. package/src/components/base/filtered_search/filtered_search_token_segment.vue +42 -0
  66. package/src/components/base/filtered_search/filtered_search_utils.js +38 -5
  67. package/src/components/base/form/form.stories.js +2 -0
  68. package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.documentation.js +0 -26
  69. package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.md +0 -4
  70. package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.stories.js +123 -92
  71. package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.vue +13 -1
  72. package/src/components/base/form/form_radio/form_radio.spec.js +21 -8
  73. package/src/components/base/form/form_radio_group/form_radio_group.stories.js +2 -1
  74. package/src/components/base/markdown/markdown.scss +21 -0
  75. package/src/components/base/markdown/markdown_typescale_demo.html +17 -6
  76. package/src/components/base/navbar/navbar.stories.js +2 -1
  77. package/src/components/base/skeleton_loader/skeleton_loader.stories.js +67 -21
  78. package/src/components/base/tabs/tabs/tabs.stories.js +2 -2
  79. package/src/components/charts/series_label/series_label.stories.js +6 -3
  80. package/src/components/charts/series_label/series_label.vue +3 -0
  81. package/src/scss/typescale/typescale.md +0 -2
  82. package/src/scss/typescale/typescale.stories.js +17 -4
  83. package/src/utils/use_mock_intersection_observer.js +3 -3
  84. package/dist/components/base/dropdown/dropdown_divider.documentation.js +0 -8
  85. package/dist/components/base/dropdown/dropdown_form.documentation.js +0 -17
  86. package/dist/components/base/dropdown/dropdown_section_header.documentation.js +0 -8
  87. package/dist/components/base/dropdown/dropdown_text.documentation.js +0 -8
  88. package/dist/components/base/dropdown/examples/dropdown.default.example.js +0 -38
  89. package/dist/components/base/dropdown/examples/dropdown.links.example.js +0 -38
  90. package/dist/components/base/dropdown/examples/dropdown.with_avatar_and_secondary_text.example.js +0 -38
  91. package/dist/components/base/dropdown/examples/dropdown.with_checked_items.example.js +0 -38
  92. package/dist/components/base/dropdown/examples/dropdown.with_clear_all.example.js +0 -38
  93. package/dist/components/base/dropdown/examples/dropdown.with_divider.example.js +0 -38
  94. package/dist/components/base/dropdown/examples/dropdown.with_form.example.js +0 -38
  95. package/dist/components/base/dropdown/examples/dropdown.with_header.example.js +0 -38
  96. package/dist/components/base/dropdown/examples/dropdown.with_highlighted_items.example.js +0 -38
  97. package/dist/components/base/dropdown/examples/dropdown.with_icons.example.js +0 -38
  98. package/dist/components/base/dropdown/examples/dropdown.with_right_align.example.js +0 -38
  99. package/dist/components/base/dropdown/examples/dropdown.with_search.example.js +0 -67
  100. package/dist/components/base/dropdown/examples/dropdown.with_section_headers.example.js +0 -38
  101. package/dist/components/base/dropdown/examples/index.js +0 -85
  102. package/dist/components/base/filtered_search/examples/filtered_search.default.example.js +0 -422
  103. package/dist/components/base/filtered_search/examples/filtered_search.friendly.example.js +0 -423
  104. package/dist/components/base/filtered_search/examples/filtered_search.history.example.js +0 -91
  105. package/dist/components/base/filtered_search/examples/filtered_search.multi_select.example.js +0 -196
  106. package/dist/components/base/filtered_search/examples/index.js +0 -32
  107. package/dist/components/base/form/form_checkbox_tree/examples/form_checkbox_tree.basic.example.js +0 -103
  108. package/dist/components/base/form/form_checkbox_tree/examples/index.js +0 -13
  109. package/src/components/base/dropdown/dropdown_divider.documentation.js +0 -6
  110. package/src/components/base/dropdown/dropdown_divider.md +0 -7
  111. package/src/components/base/dropdown/dropdown_divider.stories.js +0 -16
  112. package/src/components/base/dropdown/dropdown_form.documentation.js +0 -9
  113. package/src/components/base/dropdown/dropdown_form.md +0 -4
  114. package/src/components/base/dropdown/dropdown_form.stories.js +0 -17
  115. package/src/components/base/dropdown/dropdown_section_header.documentation.js +0 -6
  116. package/src/components/base/dropdown/dropdown_section_header.stories.js +0 -17
  117. package/src/components/base/dropdown/dropdown_text.documentation.js +0 -6
  118. package/src/components/base/dropdown/dropdown_text.stories.js +0 -16
  119. package/src/components/base/dropdown/examples/dropdown.default.example.vue +0 -7
  120. package/src/components/base/dropdown/examples/dropdown.links.example.vue +0 -7
  121. package/src/components/base/dropdown/examples/dropdown.with_avatar_and_secondary_text.example.vue +0 -7
  122. package/src/components/base/dropdown/examples/dropdown.with_checked_items.example.vue +0 -6
  123. package/src/components/base/dropdown/examples/dropdown.with_clear_all.example.vue +0 -7
  124. package/src/components/base/dropdown/examples/dropdown.with_divider.example.vue +0 -9
  125. package/src/components/base/dropdown/examples/dropdown.with_form.example.vue +0 -10
  126. package/src/components/base/dropdown/examples/dropdown.with_header.example.vue +0 -7
  127. package/src/components/base/dropdown/examples/dropdown.with_highlighted_items.example.vue +0 -9
  128. package/src/components/base/dropdown/examples/dropdown.with_icons.example.vue +0 -43
  129. package/src/components/base/dropdown/examples/dropdown.with_right_align.example.vue +0 -7
  130. package/src/components/base/dropdown/examples/dropdown.with_search.example.vue +0 -38
  131. package/src/components/base/dropdown/examples/dropdown.with_section_headers.example.vue +0 -10
  132. package/src/components/base/dropdown/examples/index.js +0 -99
  133. package/src/components/base/filtered_search/examples/filtered_search.default.example.vue +0 -298
  134. package/src/components/base/filtered_search/examples/filtered_search.friendly.example.vue +0 -300
  135. package/src/components/base/filtered_search/examples/filtered_search.history.example.vue +0 -50
  136. package/src/components/base/filtered_search/examples/filtered_search.multi_select.example.vue +0 -132
  137. package/src/components/base/filtered_search/examples/filtered_search.single_unique.example.vue +0 -31
  138. package/src/components/base/filtered_search/examples/index.js +0 -38
  139. package/src/components/base/form/form_checkbox_tree/examples/form_checkbox_tree.basic.example.vue +0 -77
  140. package/src/components/base/form/form_checkbox_tree/examples/index.js +0 -15
@@ -1,8 +1,6 @@
1
- import { withKnobs, boolean } from '@storybook/addon-knobs';
2
1
  import PortalVue from 'portal-vue';
3
2
  import Vue from 'vue';
4
3
  import { GlFilteredSearchSuggestion } from '../../../index';
5
- import { documentedStoriesOf } from '../../../../documentation/documented_stories';
6
4
  import { provide } from './common_story_options';
7
5
  import readme from './filtered_search_term.md';
8
6
  import GlFilteredSearchTokenSegment from './filtered_search_token_segment.vue';
@@ -14,84 +12,93 @@ const staticOptions = [
14
12
  { icon: 'eye', value: false, title: 'No' },
15
13
  ];
16
14
 
17
- documentedStoriesOf('base/filtered-search/token-segment', readme)
18
- .addDecorator(withKnobs)
19
- .add('default', () => ({
20
- components: {
21
- GlFilteredSearchTokenSegment,
22
- GlFilteredSearchSuggestion,
23
- },
24
- provide,
25
- props: {
26
- active: {
27
- type: Boolean,
28
- default: boolean('active', true),
29
- },
30
- },
31
- data() {
32
- return {
33
- value: 'demo1',
34
- };
35
- },
36
- mounted() {
37
- this.$nextTick(() => document.activeElement.blur());
38
- },
39
- template: `
15
+ const generateProps = ({ active = true } = {}) => ({
16
+ active,
17
+ });
18
+
19
+ // eslint-disable-next-line no-unused-vars
20
+ export const Default = (args, { argTypes }) => ({
21
+ components: {
22
+ GlFilteredSearchTokenSegment,
23
+ GlFilteredSearchSuggestion,
24
+ },
25
+ provide,
26
+ props: ['active'],
27
+ data() {
28
+ return {
29
+ value: 'demo1',
30
+ };
31
+ },
32
+ mounted() {
33
+ this.$nextTick(() => document.activeElement.blur());
34
+ },
35
+ template: `
36
+ <div>
37
+ <div>v-model value: {{ value }} </div>
38
+ <div class="gl-border-1 gl-border-solid gl-border-gray-200">
39
+ <gl-filtered-search-token-segment
40
+ v-model="value"
41
+ class="gl-h-full"
42
+ :active="active"
43
+ >
44
+ <template #suggestions>
45
+ <gl-filtered-search-suggestion value="demo1">Static suggestion 1</gl-filtered-search-suggestion>
46
+ <gl-filtered-search-suggestion value="demo2">Static suggestion 2</gl-filtered-search-suggestion>
47
+ </template>
48
+ </gl-filtered-search-token-segment>
49
+ </div>
40
50
  <div>
41
- <div>v-model value: {{ value }} </div>
42
- <div class="gl-border-1 gl-border-solid gl-border-gray-200">
43
- <gl-filtered-search-token-segment
44
- v-model="value"
45
- class="gl-h-full"
46
- :active="active"
47
- >
48
- <template #suggestions>
49
- <gl-filtered-search-suggestion value="demo1">Static suggestion 1</gl-filtered-search-suggestion>
50
- <gl-filtered-search-suggestion value="demo2">Static suggestion 2</gl-filtered-search-suggestion>
51
- </template>
52
- </gl-filtered-search-token-segment>
53
- </div>
54
- <div>
55
- <portal-target name="portal" class="gl-relative" />
56
- </div>
51
+ <portal-target name="portal" class="gl-relative" />
52
+ </div>
53
+ </div>
54
+ `,
55
+ });
56
+ Default.args = generateProps();
57
+
58
+ // eslint-disable-next-line no-unused-vars
59
+ export const WithStaticOptions = (args, { argTypes }) => ({
60
+ components: {
61
+ GlFilteredSearchTokenSegment,
62
+ },
63
+ provide,
64
+ props: ['active'],
65
+ data() {
66
+ return {
67
+ value: true,
68
+ staticOptions,
69
+ };
70
+ },
71
+ mounted() {
72
+ this.$nextTick(() => document.activeElement.blur());
73
+ },
74
+ template: `
75
+ <div>
76
+ <div>v-model value: {{ value }} </div>
77
+ <div class="gl-border-1 gl-border-solid gl-border-gray-200">
78
+ <gl-filtered-search-token-segment
79
+ v-model="value"
80
+ class="gl-h-full"
81
+ :active="active"
82
+ :options="staticOptions"
83
+ option-text-field="title"
84
+ />
57
85
  </div>
58
- `,
59
- }))
60
- .add('with static options', () => ({
61
- components: {
62
- GlFilteredSearchTokenSegment,
63
- },
64
- provide,
65
- props: {
66
- active: {
67
- type: Boolean,
68
- default: boolean('active', true),
69
- },
70
- },
71
- data() {
72
- return {
73
- value: true,
74
- staticOptions,
75
- };
76
- },
77
- mounted() {
78
- this.$nextTick(() => document.activeElement.blur());
79
- },
80
- template: `
81
86
  <div>
82
- <div>v-model value: {{ value }} </div>
83
- <div class="gl-border-1 gl-border-solid gl-border-gray-200">
84
- <gl-filtered-search-token-segment
85
- v-model="value"
86
- class="gl-h-full"
87
- :active="active"
88
- :options="staticOptions"
89
- option-text-field="title"
90
- />
91
- </div>
92
- <div>
93
- <portal-target name="portal" class="gl-relative" />
94
- </div>
87
+ <portal-target name="portal" class="gl-relative" />
95
88
  </div>
96
- `,
97
- }));
89
+ </div>
90
+ `,
91
+ });
92
+ WithStaticOptions.args = generateProps();
93
+
94
+ export default {
95
+ title: 'base/filtered-search/token-segment',
96
+ component: GlFilteredSearchTokenSegment,
97
+ parameters: {
98
+ docs: {
99
+ description: {
100
+ component: readme,
101
+ },
102
+ },
103
+ },
104
+ };
@@ -7,6 +7,7 @@ import GlFilteredSearchSuggestionList from './filtered_search_suggestion_list.vu
7
7
  import { splitOnQuotes, wrapTokenInQuotes } from './filtered_search_utils';
8
8
 
9
9
  export default {
10
+ name: 'GlFilteredSearchTokenSegment',
10
11
  components: {
11
12
  Portal,
12
13
  GlFilteredSearchSuggestionList,
@@ -15,6 +16,9 @@ export default {
15
16
  inject: ['portalName', 'alignSuggestions'],
16
17
  inheritAttrs: false,
17
18
  props: {
19
+ /**
20
+ * If this token segment is currently being edited.
21
+ */
18
22
  active: {
19
23
  type: Boolean,
20
24
  required: false,
@@ -45,15 +49,24 @@ export default {
45
49
  required: false,
46
50
  default: () => () => false,
47
51
  },
52
+ /**
53
+ * Current term value
54
+ */
48
55
  value: {
49
56
  required: true,
50
57
  validator: () => true,
51
58
  },
59
+ /**
60
+ * HTML attributes to add to the search input
61
+ */
52
62
  searchInputAttributes: {
53
63
  type: Object,
54
64
  required: false,
55
65
  default: () => ({}),
56
66
  },
67
+ /**
68
+ * If this is the last token
69
+ */
57
70
  isLastToken: {
58
71
  type: Boolean,
59
72
  required: false,
@@ -89,6 +102,11 @@ export default {
89
102
  },
90
103
 
91
104
  set(v) {
105
+ /**
106
+ * Emitted when this token segment's value changes.
107
+ *
108
+ * @type {object} option The current option.
109
+ */
92
110
  this.$emit('input', this.getMatchingOptionForInputValue(v)?.value ?? v);
93
111
  },
94
112
  },
@@ -145,6 +163,10 @@ export default {
145
163
  this.$emit('input', this.getMatchingOptionForInputValue(firstWord)?.value ?? firstWord);
146
164
 
147
165
  if (otherWords.length) {
166
+ /**
167
+ * Emitted when Space appears in token segment value
168
+ * @property {array|string} newStrings New strings to be converted into term tokens
169
+ */
148
170
  this.$emit('split', otherWords);
149
171
  }
150
172
  },
@@ -153,6 +175,9 @@ export default {
153
175
  methods: {
154
176
  emitIfInactive(e) {
155
177
  if (!this.active) {
178
+ /**
179
+ * Emitted on mousedown event on the main component.
180
+ */
156
181
  this.$emit('activate');
157
182
  e.preventDefault();
158
183
  }
@@ -190,6 +215,11 @@ export default {
190
215
  applySuggestion(suggestedValue) {
191
216
  const formattedSuggestedValue = wrapTokenInQuotes(suggestedValue);
192
217
 
218
+ /**
219
+ * Emitted when autocomplete entry is selected.
220
+ *
221
+ * @type {string} value The selected value.
222
+ */
193
223
  this.$emit('select', formattedSuggestedValue);
194
224
 
195
225
  if (!this.multiSelect) {
@@ -205,6 +235,9 @@ export default {
205
235
  if (key === 'Backspace') {
206
236
  if (this.inputValue === '') {
207
237
  e.preventDefault();
238
+ /**
239
+ * Emitted when Backspace is pressed and the value is empty
240
+ */
208
241
  this.$emit('backspace');
209
242
  }
210
243
  return;
@@ -216,6 +249,9 @@ export default {
216
249
  if (suggestedValue != null) {
217
250
  this.applySuggestion(suggestedValue);
218
251
  } else {
252
+ /**
253
+ * Emitted when Enter is pressed and no suggestion is selected
254
+ */
219
255
  this.$emit('submit');
220
256
  }
221
257
  },
@@ -227,6 +263,9 @@ export default {
227
263
  },
228
264
  Escape: () => {
229
265
  e.preventDefault();
266
+ /**
267
+ * Emitted when suggestion is selected from the suggestion list
268
+ */
230
269
  this.$emit('complete');
231
270
  },
232
271
  };
@@ -258,6 +297,9 @@ export default {
258
297
  if (this.multiSelect) {
259
298
  this.$emit('complete');
260
299
  } else if (this.active) {
300
+ /**
301
+ * Emitted when this term token will lose its focus.
302
+ */
261
303
  this.$emit('deactivate');
262
304
  }
263
305
  },
@@ -39,7 +39,42 @@ export function needDenormalization(tokens) {
39
39
 
40
40
  assertValidTokens(tokens);
41
41
 
42
- return tokens.some((t) => typeof t === 'string');
42
+ return tokens.some((t) => typeof t === 'string' || !t.id);
43
+ }
44
+
45
+ let tokenIdCounter = 0;
46
+ const getTokenId = () => {
47
+ const tokenId = `token-${tokenIdCounter}`;
48
+ tokenIdCounter += 1;
49
+ return tokenId;
50
+ };
51
+ /**
52
+ * Ensure the given token has an `id` property, which `GlFilteredSearch` relies
53
+ * on as a unique key for the token.
54
+ *
55
+ * If the given token does not have an `id`, it returns a shallow copy of the
56
+ * token with an `id`. Otherwise, it returns the given token.
57
+ *
58
+ * @param {object} token The token to check.
59
+ * @returns {object} A token with an `id`.
60
+ */
61
+ export function ensureTokenId(token) {
62
+ if (!token.id) {
63
+ return {
64
+ ...token,
65
+ id: getTokenId(),
66
+ };
67
+ }
68
+
69
+ return token;
70
+ }
71
+
72
+ export function createTerm(data = '') {
73
+ return {
74
+ id: getTokenId(),
75
+ type: TERM_TOKEN_TYPE,
76
+ value: { data },
77
+ };
43
78
  }
44
79
 
45
80
  export function denormalizeTokens(inputTokens) {
@@ -51,11 +86,9 @@ export function denormalizeTokens(inputTokens) {
51
86
  tokens.forEach((t) => {
52
87
  if (typeof t === 'string') {
53
88
  const stringTokens = t.split(' ').filter(Boolean);
54
- stringTokens.forEach((strToken) =>
55
- result.push({ type: TERM_TOKEN_TYPE, value: { data: strToken } })
56
- );
89
+ stringTokens.forEach((strToken) => result.push(createTerm(strToken)));
57
90
  } else {
58
- result.push(t);
91
+ result.push(ensureTokenId(t));
59
92
  }
60
93
  });
61
94
  return result;
@@ -4,6 +4,7 @@ import {
4
4
  GlFormInput,
5
5
  GlFormSelect,
6
6
  GlFormCheckbox,
7
+ GlFormCheckboxGroup,
7
8
  GlButton,
8
9
  } from '../../../index';
9
10
  import { setStoryTimeout } from '../../../utils/test_utils';
@@ -16,6 +17,7 @@ export const Default = (args) => ({
16
17
  GlFormInput,
17
18
  GlFormSelect,
18
19
  GlFormCheckbox,
20
+ GlFormCheckboxGroup,
19
21
  GlButton,
20
22
  },
21
23
  props: Object.keys(args),
@@ -1,31 +1,5 @@
1
- import examples from './examples';
2
1
  import * as description from './form_checkbox_tree.md';
3
- import { V_MODEL } from './models/constants';
4
2
 
5
3
  export default {
6
4
  description,
7
- examples,
8
- propsInfo: {
9
- options: {
10
- additionalInfo: 'The options tree.',
11
- },
12
- [V_MODEL.PROP]: {
13
- additionalInfo: 'The selected options as an array of values.',
14
- },
15
- hideToggleAll: {
16
- additionalInfo: 'Set to true to hide the "Select/unselect all" checkbox',
17
- },
18
- selectAllLabel: {
19
- additionalInfo: 'Label for the toggle all checkbox when some or all options are unchecked',
20
- },
21
- unselectAllLabel: {
22
- additionalInfo: 'Label for the toggle all checkbox when all options are checked',
23
- },
24
- },
25
- events: [
26
- {
27
- event: V_MODEL.EVENT,
28
- description: 'Emitted the selection changes.',
29
- },
30
- ],
31
5
  };
@@ -1,7 +1,3 @@
1
- # GlFormCheckboxTree
2
-
3
- <!-- STORY -->
4
-
5
1
  `GlFormCheckboxTree` lets you display an options structure where any option can have n-level of
6
2
  children. It can be useful for creating a search filter that has nested facets.
7
3
 
@@ -1,5 +1,3 @@
1
- import { withKnobs, boolean } from '@storybook/addon-knobs';
2
- import { documentedStoriesOf } from '../../../../../documentation/documented_stories';
3
1
  import GlToken from '../../token/token.vue';
4
2
  import readme from './form_checkbox_tree.md';
5
3
  import GlFormCheckboxTree from './form_checkbox_tree.vue';
@@ -9,95 +7,128 @@ const components = {
9
7
  GlToken,
10
8
  };
11
9
 
12
- documentedStoriesOf('base/form/form-checkbox-tree', readme)
13
- .addDecorator(withKnobs)
14
- .add('default', () => ({
15
- props: {
16
- hideToggleAll: {
17
- default: boolean('Hide toggle all checkbox?', false),
10
+ const defaultOptions = [
11
+ {
12
+ value: 1,
13
+ label: 'Felidae',
14
+ children: [
15
+ {
16
+ value: 11,
17
+ label: 'Lion',
18
+ },
19
+ {
20
+ value: 12,
21
+ label: 'Felinae',
22
+ children: [
23
+ {
24
+ value: 121,
25
+ label: 'Cheetah',
26
+ },
27
+ {
28
+ value: 122,
29
+ label: 'Ocelot',
30
+ },
31
+ ],
32
+ },
33
+ ],
34
+ },
35
+ {
36
+ value: 2,
37
+ label: 'Canidae',
38
+ children: [
39
+ {
40
+ value: 21,
41
+ label: 'Caninae',
42
+ children: [
43
+ {
44
+ value: 211,
45
+ label: 'Canis lupus',
46
+ children: [
47
+ {
48
+ value: 2112,
49
+ label: 'Wolf',
50
+ },
51
+ {
52
+ value: 2113,
53
+ label: 'Himalayan wolf',
54
+ },
55
+ {
56
+ value: 2114,
57
+ label: 'Dingo',
58
+ },
59
+ ],
60
+ },
61
+ {
62
+ value: 212,
63
+ label: 'Black-backed jackal',
64
+ },
65
+ ],
66
+ },
67
+ {
68
+ value: 22,
69
+ label: 'Fennec fox',
70
+ },
71
+ ],
72
+ },
73
+ {
74
+ value: 3,
75
+ label: 'Karabair',
76
+ },
77
+ {
78
+ value: 4,
79
+ label: 'Okapi',
80
+ },
81
+ ];
82
+
83
+ const defaultValue = (prop) => GlFormCheckboxTree.props[prop].default;
84
+
85
+ const generateProps = ({
86
+ options = defaultOptions,
87
+ hideToggleAll = defaultValue('hideToggleAll'),
88
+ selectAllLabel = defaultValue('selectAllLabel'),
89
+ unselectAllLabel = defaultValue('unselectAllLabel'),
90
+ label = defaultValue('label'),
91
+ labelSrOnly = defaultValue('labelSrOnly'),
92
+ } = {}) => ({
93
+ options,
94
+ hideToggleAll,
95
+ selectAllLabel,
96
+ unselectAllLabel,
97
+ label,
98
+ labelSrOnly,
99
+ });
100
+
101
+ export const Default = (args, { argTypes }) => ({
102
+ props: Object.keys(argTypes),
103
+ data: () => ({
104
+ checked: [1, 11, 12, 121, 122, 2113, 3],
105
+ }),
106
+ components,
107
+ template: `
108
+ <div>
109
+ <gl-form-checkbox-tree
110
+ v-model="checked"
111
+ :options="options"
112
+ :hide-toggle-all="hideToggleAll"
113
+ :select-all-label="selectAllLabel"
114
+ :unselect-all-label="unselectAllLabel"
115
+ :label="label"
116
+ :label-sr-only="labelSrOnly" />
117
+ Selected options:
118
+ <gl-token v-for="value in checked" :key="value" class="gl-mr-1" view-only>{{ value }}</gl-token>
119
+ </div>
120
+ `,
121
+ });
122
+ Default.args = generateProps();
123
+
124
+ export default {
125
+ title: 'base/form/form-checkbox-tree',
126
+ component: GlFormCheckboxTree,
127
+ parameters: {
128
+ docs: {
129
+ description: {
130
+ component: readme,
18
131
  },
19
132
  },
20
- data: () => ({
21
- checked: [1, 11, 12, 121, 122, 2113, 3],
22
- options: [
23
- {
24
- value: 1,
25
- label: 'Felidae',
26
- children: [
27
- {
28
- value: 11,
29
- label: 'Lion',
30
- },
31
- {
32
- value: 12,
33
- label: 'Felinae',
34
- children: [
35
- {
36
- value: 121,
37
- label: 'Cheetah',
38
- },
39
- {
40
- value: 122,
41
- label: 'Ocelot',
42
- },
43
- ],
44
- },
45
- ],
46
- },
47
- {
48
- value: 2,
49
- label: 'Canidae',
50
- children: [
51
- {
52
- value: 21,
53
- label: 'Caninae',
54
- children: [
55
- {
56
- value: 211,
57
- label: 'Canis lupus',
58
- children: [
59
- {
60
- value: 2112,
61
- label: 'Wolf',
62
- },
63
- {
64
- value: 2113,
65
- label: 'Himalayan wolf',
66
- },
67
- {
68
- value: 2114,
69
- label: 'Dingo',
70
- },
71
- ],
72
- },
73
- {
74
- value: 212,
75
- label: 'Black-backed jackal',
76
- },
77
- ],
78
- },
79
- {
80
- value: 22,
81
- label: 'Fennec fox',
82
- },
83
- ],
84
- },
85
- {
86
- value: 3,
87
- label: 'Karabair',
88
- },
89
- {
90
- value: 4,
91
- label: 'Okapi',
92
- },
93
- ],
94
- }),
95
- components,
96
- template: `
97
- <div>
98
- <gl-form-checkbox-tree :hide-toggle-all="hideToggleAll" :options="options" v-model="checked" />
99
- Selected options:
100
- <gl-token v-for="value in checked" :key="value" class="gl-mr-1" view-only>{{ value }}</gl-token>
101
- </div>
102
- `,
103
- }));
133
+ },
134
+ };
@@ -34,23 +34,32 @@ export default {
34
34
  required: true,
35
35
  },
36
36
  /**
37
- * Selected options
37
+ * The selected options as an array of values
38
38
  */
39
39
  value: {
40
40
  type: Array,
41
41
  required: false,
42
42
  default: () => [],
43
43
  },
44
+ /**
45
+ * Set to true to hide the "Select/unselect all" checkbox
46
+ */
44
47
  hideToggleAll: {
45
48
  type: Boolean,
46
49
  required: false,
47
50
  default: false,
48
51
  },
52
+ /**
53
+ * Label for the toggle all checkbox when some or all options are unchecked
54
+ */
49
55
  selectAllLabel: {
50
56
  type: String,
51
57
  required: false,
52
58
  default: 'Select all',
53
59
  },
60
+ /**
61
+ * Label for the toggle all checkbox when all options are checked
62
+ */
54
63
  unselectAllLabel: {
55
64
  type: String,
56
65
  required: false,
@@ -80,6 +89,9 @@ export default {
80
89
  watch: {
81
90
  'tree.selected': {
82
91
  handler(selected) {
92
+ /**
93
+ * Emitted when the selection changes.
94
+ */
83
95
  this.$emit(V_MODEL.EVENT, selected);
84
96
  },
85
97
  },