@gitlab/ui 38.1.0 → 38.3.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.
- package/CHANGELOG.md +27 -0
- package/dist/components/base/dropdown/dropdown.documentation.js +1 -5
- package/dist/components/base/dropdown/dropdown_item.documentation.js +2 -3
- package/dist/components/base/filtered_search/filtered_search.js +13 -20
- package/dist/components/base/filtered_search/filtered_search_suggestion.js +1 -1
- package/dist/components/base/filtered_search/filtered_search_token.js +31 -23
- package/dist/components/base/filtered_search/filtered_search_utils.js +42 -9
- package/dist/components/base/form/form_checkbox_tree/form_checkbox_tree.documentation.js +2 -27
- package/dist/components/base/form/form_checkbox_tree/form_checkbox_tree.js +16 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/utility_classes.css +1 -1
- package/dist/utility_classes.css.map +1 -1
- package/dist/utils/use_mock_intersection_observer.js +2 -2
- package/documentation/components_documentation.js +0 -4
- package/documentation/documented_stories.js +4 -1
- package/package.json +12 -12
- package/src/components/base/avatar_link/avatar_link.stories.js +2 -2
- package/src/components/base/dropdown/dropdown.documentation.js +0 -3
- package/src/components/base/dropdown/dropdown.md +7 -2
- package/src/components/base/dropdown/dropdown.stories.js +487 -439
- package/src/components/base/dropdown/dropdown_item.documentation.js +0 -1
- package/src/components/base/dropdown/dropdown_item.md +0 -6
- package/src/components/base/dropdown/dropdown_item.stories.js +107 -35
- package/src/components/base/filtered_search/filtered_search.spec.js +37 -12
- package/src/components/base/filtered_search/filtered_search.stories.js +15 -7
- package/src/components/base/filtered_search/filtered_search.vue +12 -14
- package/src/components/base/filtered_search/filtered_search_suggestion.vue +1 -0
- package/src/components/base/filtered_search/filtered_search_token.spec.js +31 -1
- package/src/components/base/filtered_search/filtered_search_token.stories.js +1 -0
- package/src/components/base/filtered_search/filtered_search_token.vue +30 -21
- package/src/components/base/filtered_search/filtered_search_utils.js +38 -5
- package/src/components/base/form/form.stories.js +2 -0
- package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.documentation.js +0 -26
- package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.md +0 -4
- package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.stories.js +123 -92
- package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.vue +13 -1
- package/src/components/base/form/form_radio_group/form_radio_group.stories.js +2 -1
- package/src/components/base/markdown/markdown.scss +21 -0
- package/src/components/base/markdown/markdown_typescale_demo.html +17 -6
- package/src/components/base/navbar/navbar.stories.js +2 -1
- package/src/components/base/skeleton_loader/skeleton_loader.stories.js +67 -21
- package/src/components/base/tabs/tabs/tabs.stories.js +2 -2
- package/src/scss/typescale/typescale.md +0 -2
- package/src/scss/typescale/typescale.stories.js +17 -4
- package/src/scss/utilities.scss +24 -0
- package/src/scss/utility-mixins/display.scss +12 -0
- package/src/utils/use_mock_intersection_observer.js +3 -3
- package/dist/components/base/dropdown/dropdown_divider.documentation.js +0 -8
- package/dist/components/base/dropdown/dropdown_form.documentation.js +0 -17
- package/dist/components/base/dropdown/dropdown_section_header.documentation.js +0 -8
- package/dist/components/base/dropdown/dropdown_text.documentation.js +0 -8
- package/dist/components/base/dropdown/examples/dropdown.default.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.links.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_avatar_and_secondary_text.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_checked_items.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_clear_all.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_divider.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_form.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_header.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_highlighted_items.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_icons.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_right_align.example.js +0 -38
- package/dist/components/base/dropdown/examples/dropdown.with_search.example.js +0 -67
- package/dist/components/base/dropdown/examples/dropdown.with_section_headers.example.js +0 -38
- package/dist/components/base/dropdown/examples/index.js +0 -85
- package/dist/components/base/form/form_checkbox_tree/examples/form_checkbox_tree.basic.example.js +0 -103
- package/dist/components/base/form/form_checkbox_tree/examples/index.js +0 -13
- package/src/components/base/dropdown/dropdown_divider.documentation.js +0 -6
- package/src/components/base/dropdown/dropdown_divider.md +0 -7
- package/src/components/base/dropdown/dropdown_divider.stories.js +0 -16
- package/src/components/base/dropdown/dropdown_form.documentation.js +0 -9
- package/src/components/base/dropdown/dropdown_form.md +0 -4
- package/src/components/base/dropdown/dropdown_form.stories.js +0 -17
- package/src/components/base/dropdown/dropdown_section_header.documentation.js +0 -6
- package/src/components/base/dropdown/dropdown_section_header.stories.js +0 -17
- package/src/components/base/dropdown/dropdown_text.documentation.js +0 -6
- package/src/components/base/dropdown/dropdown_text.stories.js +0 -16
- package/src/components/base/dropdown/examples/dropdown.default.example.vue +0 -7
- package/src/components/base/dropdown/examples/dropdown.links.example.vue +0 -7
- package/src/components/base/dropdown/examples/dropdown.with_avatar_and_secondary_text.example.vue +0 -7
- package/src/components/base/dropdown/examples/dropdown.with_checked_items.example.vue +0 -6
- package/src/components/base/dropdown/examples/dropdown.with_clear_all.example.vue +0 -7
- package/src/components/base/dropdown/examples/dropdown.with_divider.example.vue +0 -9
- package/src/components/base/dropdown/examples/dropdown.with_form.example.vue +0 -10
- package/src/components/base/dropdown/examples/dropdown.with_header.example.vue +0 -7
- package/src/components/base/dropdown/examples/dropdown.with_highlighted_items.example.vue +0 -9
- package/src/components/base/dropdown/examples/dropdown.with_icons.example.vue +0 -43
- package/src/components/base/dropdown/examples/dropdown.with_right_align.example.vue +0 -7
- package/src/components/base/dropdown/examples/dropdown.with_search.example.vue +0 -38
- package/src/components/base/dropdown/examples/dropdown.with_section_headers.example.vue +0 -10
- package/src/components/base/dropdown/examples/index.js +0 -99
- package/src/components/base/form/form_checkbox_tree/examples/form_checkbox_tree.basic.example.vue +0 -77
- package/src/components/base/form/form_checkbox_tree/examples/index.js +0 -15
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
import { cloneDeep } from 'lodash';
|
|
2
3
|
import { COMMA } from '../../../utils/constants';
|
|
3
4
|
import GlToken from '../token/token.vue';
|
|
4
5
|
import GlFilteredSearchTokenSegment from './filtered_search_token_segment.vue';
|
|
5
|
-
import {
|
|
6
|
+
import { createTerm } from './filtered_search_utils';
|
|
6
7
|
|
|
7
8
|
const SEGMENT_TITLE = 'TYPE';
|
|
8
9
|
const SEGMENT_OPERATOR = 'OPERATOR';
|
|
@@ -68,6 +69,7 @@ export default {
|
|
|
68
69
|
data() {
|
|
69
70
|
return {
|
|
70
71
|
activeSegment: null,
|
|
72
|
+
tokenValue: cloneDeep(this.value),
|
|
71
73
|
};
|
|
72
74
|
},
|
|
73
75
|
|
|
@@ -77,7 +79,7 @@ export default {
|
|
|
77
79
|
},
|
|
78
80
|
|
|
79
81
|
hasDataOrDataSegmentIsCurrentlyActive() {
|
|
80
|
-
return this.
|
|
82
|
+
return this.tokenValue.data !== '' || this.isSegmentActive(SEGMENT_DATA);
|
|
81
83
|
},
|
|
82
84
|
|
|
83
85
|
availableTokensWithSelf() {
|
|
@@ -88,7 +90,7 @@ export default {
|
|
|
88
90
|
},
|
|
89
91
|
|
|
90
92
|
operatorDescription() {
|
|
91
|
-
const operator = this.operators.find((op) => op.value === this.
|
|
93
|
+
const operator = this.operators.find((op) => op.value === this.tokenValue.operator);
|
|
92
94
|
return this.showFriendlyText ? operator?.description : operator?.value;
|
|
93
95
|
},
|
|
94
96
|
},
|
|
@@ -98,7 +100,7 @@ export default {
|
|
|
98
100
|
SEGMENT_OPERATOR,
|
|
99
101
|
},
|
|
100
102
|
watch: {
|
|
101
|
-
|
|
103
|
+
tokenValue: {
|
|
102
104
|
deep: true,
|
|
103
105
|
handler(newValue) {
|
|
104
106
|
/**
|
|
@@ -111,14 +113,24 @@ export default {
|
|
|
111
113
|
},
|
|
112
114
|
},
|
|
113
115
|
|
|
116
|
+
value: {
|
|
117
|
+
handler(newValue, oldValue) {
|
|
118
|
+
if (newValue?.data === oldValue?.data && newValue?.operator === oldValue?.operator) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
this.tokenValue = cloneDeep(newValue);
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
|
|
114
126
|
active: {
|
|
115
127
|
immediate: true,
|
|
116
128
|
handler(newValue) {
|
|
117
129
|
if (newValue) {
|
|
118
130
|
if (!this.activeSegment) {
|
|
119
|
-
this.activateSegment(this.
|
|
131
|
+
this.activateSegment(this.tokenValue.data !== '' ? SEGMENT_DATA : SEGMENT_OPERATOR);
|
|
120
132
|
}
|
|
121
|
-
} else if (this.
|
|
133
|
+
} else if (this.tokenValue.data === '') {
|
|
122
134
|
this.activeSegment = null;
|
|
123
135
|
/**
|
|
124
136
|
* Emitted when token is about to be destroyed.
|
|
@@ -132,13 +144,13 @@ export default {
|
|
|
132
144
|
},
|
|
133
145
|
|
|
134
146
|
created() {
|
|
135
|
-
if (!('operator' in this.
|
|
147
|
+
if (!('operator' in this.tokenValue)) {
|
|
136
148
|
if (this.operators.length === 1) {
|
|
137
149
|
const operator = this.operators[0].value;
|
|
138
|
-
this.$emit('input', { ...this.
|
|
150
|
+
this.$emit('input', { ...this.tokenValue, operator });
|
|
139
151
|
this.activeSegment = SEGMENT_DATA;
|
|
140
152
|
} else {
|
|
141
|
-
this.$emit('input', { ...this.
|
|
153
|
+
this.$emit('input', { ...this.tokenValue, operator: '' });
|
|
142
154
|
}
|
|
143
155
|
}
|
|
144
156
|
},
|
|
@@ -166,12 +178,12 @@ export default {
|
|
|
166
178
|
},
|
|
167
179
|
|
|
168
180
|
replaceWithTermIfEmpty() {
|
|
169
|
-
if (this.
|
|
181
|
+
if (this.tokenValue.operator === '' && this.tokenValue.data === '') {
|
|
170
182
|
/**
|
|
171
183
|
* Emitted when this token is converted to another type
|
|
172
184
|
* @property {object} token Replacement token configuration
|
|
173
185
|
*/
|
|
174
|
-
this.$emit('replace',
|
|
186
|
+
this.$emit('replace', createTerm(this.config.title));
|
|
175
187
|
}
|
|
176
188
|
},
|
|
177
189
|
|
|
@@ -195,7 +207,7 @@ export default {
|
|
|
195
207
|
this.config.dataType && this.config.dataType === newTokenConfig.dataType;
|
|
196
208
|
this.$emit('replace', {
|
|
197
209
|
type: newTokenConfig.type,
|
|
198
|
-
value: isCompatible ? this.
|
|
210
|
+
value: isCompatible ? this.tokenValue : { data: '' },
|
|
199
211
|
});
|
|
200
212
|
}
|
|
201
213
|
},
|
|
@@ -212,7 +224,7 @@ export default {
|
|
|
212
224
|
key.length === 1 &&
|
|
213
225
|
!this.operators.find(({ value }) => value.startsWith(potentialValue))
|
|
214
226
|
) {
|
|
215
|
-
if (this.
|
|
227
|
+
if (this.tokenValue.data === '') {
|
|
216
228
|
applySuggestion(suggestedValue);
|
|
217
229
|
} else {
|
|
218
230
|
evt.preventDefault();
|
|
@@ -222,14 +234,14 @@ export default {
|
|
|
222
234
|
|
|
223
235
|
activateDataSegment() {
|
|
224
236
|
if (this.config.multiSelect) {
|
|
225
|
-
this.$emit('input', { ...this.
|
|
237
|
+
this.$emit('input', { ...this.tokenValue, data: '' });
|
|
226
238
|
}
|
|
227
239
|
this.activateSegment(this.$options.segments.SEGMENT_DATA);
|
|
228
240
|
},
|
|
229
241
|
|
|
230
242
|
handleComplete() {
|
|
231
243
|
if (this.config.multiSelect) {
|
|
232
|
-
this.$emit('input', { ...this.
|
|
244
|
+
this.$emit('input', { ...this.tokenValue, data: this.multiSelectValues.join(COMMA) });
|
|
233
245
|
}
|
|
234
246
|
/**
|
|
235
247
|
* Emitted when the token entry has been completed.
|
|
@@ -242,6 +254,7 @@ export default {
|
|
|
242
254
|
destroyByClose(event) {
|
|
243
255
|
if (event.target.closest(TOKEN_CLOSE_SELECTOR)) {
|
|
244
256
|
event.preventDefault();
|
|
257
|
+
event.stopPropagation();
|
|
245
258
|
this.$emit('destroy');
|
|
246
259
|
}
|
|
247
260
|
},
|
|
@@ -275,10 +288,9 @@ export default {
|
|
|
275
288
|
>
|
|
276
289
|
</template>
|
|
277
290
|
</gl-filtered-search-token-segment>
|
|
278
|
-
<!-- eslint-disable vue/no-mutating-props -->
|
|
279
291
|
<gl-filtered-search-token-segment
|
|
280
292
|
key="operator-segment"
|
|
281
|
-
v-model="
|
|
293
|
+
v-model="tokenValue.operator"
|
|
282
294
|
:active="isSegmentActive($options.segments.SEGMENT_OPERATOR)"
|
|
283
295
|
:options="operators"
|
|
284
296
|
:custom-input-keydown-handler="handleOperatorKeydown"
|
|
@@ -288,7 +300,6 @@ export default {
|
|
|
288
300
|
@complete="activateSegment($options.segments.SEGMENT_DATA)"
|
|
289
301
|
@deactivate="$emit('deactivate')"
|
|
290
302
|
>
|
|
291
|
-
<!-- eslint-enable vue/no-mutating-props -->
|
|
292
303
|
<template #view>
|
|
293
304
|
<gl-token
|
|
294
305
|
class="gl-filtered-search-token-operator"
|
|
@@ -307,7 +318,6 @@ export default {
|
|
|
307
318
|
</div>
|
|
308
319
|
</template>
|
|
309
320
|
</gl-filtered-search-token-segment>
|
|
310
|
-
<!-- eslint-disable vue/no-mutating-props -->
|
|
311
321
|
<!--
|
|
312
322
|
Emitted when a suggestion has been selected.
|
|
313
323
|
@event select
|
|
@@ -321,7 +331,7 @@ export default {
|
|
|
321
331
|
<gl-filtered-search-token-segment
|
|
322
332
|
v-if="hasDataOrDataSegmentIsCurrentlyActive"
|
|
323
333
|
key="data-segment"
|
|
324
|
-
v-model="
|
|
334
|
+
v-model="tokenValue.data"
|
|
325
335
|
:active="isSegmentActive($options.segments.SEGMENT_DATA)"
|
|
326
336
|
:multi-select="config.multiSelect"
|
|
327
337
|
:options="config.options"
|
|
@@ -334,7 +344,6 @@ export default {
|
|
|
334
344
|
@deactivate="$emit('deactivate')"
|
|
335
345
|
@split="$emit('split', $event)"
|
|
336
346
|
>
|
|
337
|
-
<!-- eslint-enable vue/no-mutating-props -->
|
|
338
347
|
<template #suggestions>
|
|
339
348
|
<!-- @slot The suggestions (implemented with GlFilteredSearchSuggestion). -->
|
|
340
349
|
<slot name="suggestions"></slot>
|
|
@@ -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,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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
21
|
-
|
|
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
|
-
*
|
|
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
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GlFormRadioGroup } from '../../../../index';
|
|
1
|
+
import { GlFormRadioGroup, GlFormRadio } from '../../../../index';
|
|
2
2
|
import readme from './form_radio_group.md';
|
|
3
3
|
|
|
4
4
|
const defaultOptions = [
|
|
@@ -34,6 +34,7 @@ const template = `
|
|
|
34
34
|
const Template = (args, { argTypes }) => ({
|
|
35
35
|
components: {
|
|
36
36
|
GlFormRadioGroup,
|
|
37
|
+
GlFormRadio,
|
|
37
38
|
},
|
|
38
39
|
props: Object.keys(argTypes),
|
|
39
40
|
template,
|
|
@@ -162,6 +162,27 @@
|
|
|
162
162
|
@include gl-px-2;
|
|
163
163
|
@include gl-py-1;
|
|
164
164
|
}
|
|
165
|
+
|
|
166
|
+
.audio-container {
|
|
167
|
+
@include gl-display-inline-flex;
|
|
168
|
+
@include gl-flex-direction-column;
|
|
169
|
+
@include gl-w-full;
|
|
170
|
+
|
|
171
|
+
audio {
|
|
172
|
+
@include gl-w-full;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
a {
|
|
176
|
+
@include gl-mt-3;
|
|
177
|
+
|
|
178
|
+
&::before {
|
|
179
|
+
@include gl-mr-2;
|
|
180
|
+
text-rendering: auto;
|
|
181
|
+
-webkit-font-smoothing: antialiased;
|
|
182
|
+
content: '📎';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
165
186
|
}
|
|
166
187
|
|
|
167
188
|
.gl-compact-markdown {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
significant ways to add some useful functionality. You can use GFM in the following areas: comments, issues, merge
|
|
4
4
|
requests, milestones, snippets and more.</p>
|
|
5
5
|
<p class="sm">MD Doc Small Paragraph • GitLab uses "GitLab Flavored Markdown" (GFM). It extends the standard Markdown
|
|
6
|
-
in a few significant ways to add some useful functionality. You can use GFM in the following areas: comments, issues,
|
|
7
|
-
merge requests, milestones, snippets and more.</p>
|
|
6
|
+
in a few significant ways to add some useful functionality. You can use GFM in the following areas: comments, issues,
|
|
7
|
+
merge requests, milestones, snippets and more.</p>
|
|
8
8
|
<p class="monospace">UI Monospace</p>
|
|
9
9
|
<p class="monospace sm">UI Small Monospace</p>
|
|
10
10
|
<h2>MD Doc h2 • GitLab uses "GitLab Flavored Markdown" (GFM)</h2>
|
|
@@ -29,15 +29,26 @@ merge requests, milestones, snippets and more.</p>
|
|
|
29
29
|
requests, milestones, snippets and more.</p>
|
|
30
30
|
<blockquote>
|
|
31
31
|
<p>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
MD Doc Blockquote • GitLab uses "GitLab Flavored Markdown" (GFM). It extends the standard Markdown in a few
|
|
33
|
+
significant ways to add some useful functionality. You can use GFM in the following areas: comments, issues, merge
|
|
34
|
+
requests, milestones, snippets and more.
|
|
35
35
|
</p>
|
|
36
36
|
</blockquote>
|
|
37
37
|
<p>
|
|
38
38
|
This is a paragraph with two types inline diff <span class="idiff addition">addition</span> and
|
|
39
39
|
<span class="idiff deletion">deletion</span>
|
|
40
40
|
</p>
|
|
41
|
-
<p>
|
|
41
|
+
<p>
|
|
42
42
|
This block implements the "GitLab Flavored Markdown" <code>Code span</code> styles.
|
|
43
43
|
</p>
|
|
44
|
+
|
|
45
|
+
<p>
|
|
46
|
+
This is an audio file
|
|
47
|
+
<span class="media-container audio-container">
|
|
48
|
+
<audio src="file.mp3" controls="true" data-setup="{}" data-title="file.mp3" data-canonical-src="file.mp3"
|
|
49
|
+
class="gfm">
|
|
50
|
+
</audio>
|
|
51
|
+
<a href="file.mp3" target="_blank" rel="noopener noreferrer" title="Download file.mp3" data-canonical-src="file.mp3"
|
|
52
|
+
data-link="true" class="gfm">file.mp3</a>
|
|
53
|
+
</span>
|
|
54
|
+
</p>
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { BNavbarBrand } from 'bootstrap-vue';
|
|
1
2
|
import { GlNavbar } from '../../../index';
|
|
2
3
|
import readme from './navbar.md';
|
|
3
4
|
|
|
4
5
|
const Template = (args, { argTypes }) => ({
|
|
5
|
-
components: { GlNavbar },
|
|
6
|
+
components: { GlNavbar, BNavbarBrand },
|
|
6
7
|
props: Object.keys(argTypes),
|
|
7
8
|
template: `
|
|
8
9
|
<gl-navbar variant="dark" type="dark">
|