@gitlab/ui 39.3.0 → 39.3.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.
- package/CHANGELOG.md +7 -0
- package/dist/components/base/modal/modal.js +14 -2
- package/package.json +4 -11
- package/src/components/base/modal/modal.spec.js +20 -0
- package/src/components/base/modal/modal.vue +14 -1
- package/dist/components/base/accordion/accordion.documentation.js +0 -8
- package/dist/components/base/accordion/accordion_item.documentation.js +0 -7
- package/dist/components/base/alert/alert.documentation.js +0 -13
- package/dist/components/base/avatar/avatar.documentation.js +0 -8
- package/dist/components/base/avatar_labeled/avatar_labeled.documentation.js +0 -8
- package/dist/components/base/avatar_link/avatar_link.documentation.js +0 -8
- package/dist/components/base/avatars_inline/avatars_inline.documentation.js +0 -13
- package/dist/components/base/badge/badge.documentation.js +0 -8
- package/dist/components/base/banner/banner.documentation.js +0 -8
- package/dist/components/base/breadcrumb/breadcrumb.documentation.js +0 -8
- package/dist/components/base/broadcast_message/broadcast_message.documentation.js +0 -8
- package/dist/components/base/button/button.documentation.js +0 -24
- package/dist/components/base/button_group/button_group.documentation.js +0 -8
- package/dist/components/base/card/card.documentation.js +0 -13
- package/dist/components/base/carousel/carousel.documentation.js +0 -8
- package/dist/components/base/collapse/collapse.documentation.js +0 -7
- package/dist/components/base/datepicker/datepicker.documentation.js +0 -7
- package/dist/components/base/daterange_picker/daterange_picker.documentation.js +0 -8
- package/dist/components/base/drawer/drawer.documentation.js +0 -8
- package/dist/components/base/dropdown/dropdown.documentation.js +0 -8
- package/dist/components/base/dropdown/dropdown_item.documentation.js +0 -7
- package/dist/components/base/filtered_search/filtered_search.documentation.js +0 -13
- package/dist/components/base/filtered_search/filtered_search_suggestion.documentation.js +0 -7
- package/dist/components/base/filtered_search/filtered_search_suggestion_list.documentation.js +0 -7
- package/dist/components/base/filtered_search/filtered_search_term.documentation.js +0 -12
- package/dist/components/base/filtered_search/filtered_search_token.documentation.js +0 -12
- package/dist/components/base/filtered_search/filtered_search_token_segment.documentation.js +0 -12
- package/dist/components/base/form/form.documentation.js +0 -7
- package/dist/components/base/form/form_checkbox/form_checkbox.documentation.js +0 -8
- package/dist/components/base/form/form_checkbox_tree/form_checkbox_tree.documentation.js +0 -12
- package/dist/components/base/form/form_combobox/form_combobox.documentation.js +0 -13
- package/dist/components/base/form/form_group/form_group.documentation.js +0 -7
- package/dist/components/base/form/form_input/form_input.documentation.js +0 -8
- package/dist/components/base/form/form_input_group/form_input_group.documentation.js +0 -8
- package/dist/components/base/form/form_radio/form_radio.documentation.js +0 -8
- package/dist/components/base/form/form_radio_group/form_radio_group.documentation.js +0 -8
- package/dist/components/base/form/form_select/form_select.documentation.js +0 -8
- package/dist/components/base/form/form_text/form_text.documentation.js +0 -14
- package/dist/components/base/form/form_textarea/form_textarea.documentation.js +0 -7
- package/dist/components/base/form/input_group_text/input_group_text.documentation.js +0 -12
- package/dist/components/base/icon/icon.documentation.js +0 -8
- package/dist/components/base/infinite_scroll/examples/index.js +0 -49
- package/dist/components/base/infinite_scroll/examples/infinite_scroll.all_items.example.js +0 -49
- package/dist/components/base/infinite_scroll/examples/infinite_scroll.basic.example.js +0 -62
- package/dist/components/base/infinite_scroll/examples/infinite_scroll.finite_total_items.example.js +0 -72
- package/dist/components/base/infinite_scroll/examples/infinite_scroll.large_fetched_items.example.js +0 -62
- package/dist/components/base/infinite_scroll/examples/infinite_scroll.reverse.example.js +0 -63
- package/dist/components/base/infinite_scroll/examples/infinite_scroll.small_fetched_items.example.js +0 -62
- package/dist/components/base/infinite_scroll/examples/infinite_scroll.two_way.example.js +0 -94
- package/dist/components/base/infinite_scroll/infinite_scroll.documentation.js +0 -8
- package/dist/components/base/keyset_pagination/keyset_pagination.documentation.js +0 -13
- package/dist/components/base/label/label.documentation.js +0 -8
- package/dist/components/base/link/link.documentation.js +0 -7
- package/dist/components/base/loading_icon/loading_icon.documentation.js +0 -8
- package/dist/components/base/markdown/markdown.documentation.js +0 -12
- package/dist/components/base/modal/modal.documentation.js +0 -8
- package/dist/components/base/nav/nav.documentation.js +0 -12
- package/dist/components/base/navbar/navbar.documentation.js +0 -12
- package/dist/components/base/paginated_list/paginated_list.documentation.js +0 -7
- package/dist/components/base/pagination/pagination.documentation.js +0 -8
- package/dist/components/base/path/path.documentation.js +0 -8
- package/dist/components/base/popover/popover.documentation.js +0 -5
- package/dist/components/base/search_box_by_click/search_box_by_click.documentation.js +0 -8
- package/dist/components/base/search_box_by_type/search_box_by_type.documentation.js +0 -8
- package/dist/components/base/segmented_control/segmented_control.documentation.js +0 -8
- package/dist/components/base/skeleton_loader/skeleton_loader.documentation.js +0 -13
- package/dist/components/base/skeleton_loading/skeleton_loading.documentation.js +0 -7
- package/dist/components/base/sorting/sorting.documentation.js +0 -7
- package/dist/components/base/sorting/sorting_item.documentation.js +0 -8
- package/dist/components/base/table/table.documentation.js +0 -8
- package/dist/components/base/table_lite/table_lite.documentation.js +0 -13
- package/dist/components/base/tabs/tabs/tabs.documentation.js +0 -8
- package/dist/components/base/toast/toast.documentation.js +0 -8
- package/dist/components/base/toggle/toggle.documentation.js +0 -13
- package/dist/components/base/token/token.documentation.js +0 -5
- package/dist/components/base/token_selector/token_selector.documentation.js +0 -12
- package/dist/components/base/tooltip/tooltip.documentation.js +0 -8
- package/dist/components/charts/area/area.documentation.js +0 -5
- package/dist/components/charts/bar/bar.documentation.js +0 -8
- package/dist/components/charts/chart/chart.documentation.js +0 -7
- package/dist/components/charts/column/column.documentation.js +0 -5
- package/dist/components/charts/discrete_scatter/discrete_scatter.documentation.js +0 -5
- package/dist/components/charts/gauge/gauge.documentation.js +0 -12
- package/dist/components/charts/heatmap/heatmap.documentation.js +0 -8
- package/dist/components/charts/line/line.documentation.js +0 -8
- package/dist/components/charts/series_label/series_label.documentation.js +0 -7
- package/dist/components/charts/single_stat/single_stat.documentation.js +0 -7
- package/dist/components/charts/sparkline/sparkline.documentation.js +0 -8
- package/dist/components/charts/stacked_column/stacked_column.documentation.js +0 -8
- package/dist/components/charts/tooltip/tooltip.documentation.js +0 -8
- package/dist/components/editors/rich_text_editor/rich_text_editor.documentation.js +0 -12
- package/dist/components/regions/dashboard_skeleton/dashboard_skeleton.documentation.js +0 -7
- package/dist/components/regions/empty_state/empty_state.documentation.js +0 -7
- package/dist/components/utilities/animated_number/animated_number.documentation.js +0 -13
- package/dist/components/utilities/friendly_wrap/friendly_wrap.documentation.js +0 -7
- package/dist/components/utilities/intersection_observer/intersection_observer.documentation.js +0 -12
- package/dist/components/utilities/intersperse/intersperse.documentation.js +0 -8
- package/dist/components/utilities/sprintf/sprintf.documentation.js +0 -8
- package/dist/components/utilities/truncate/truncate.documentation.js +0 -7
- package/dist/directives/hover_load/hover_load.documentation.js +0 -13
- package/dist/directives/outside/outside.documentation.js +0 -13
- package/dist/directives/resize_observer/resize_observer.documentation.js +0 -8
- package/dist/directives/safe_html/safe_html.documentation.js +0 -8
- package/dist/directives/safe_link/safe_link.documentation.js +0 -8
- package/documentation/all_components.js +0 -8
- package/documentation/components/component_documentation_generator.vue +0 -321
- package/documentation/components/example_display.vue +0 -231
- package/documentation/components/example_explorer.vue +0 -63
- package/documentation/components_documentation.js +0 -111
- package/documentation/index.js +0 -8
- package/src/components/base/accordion/accordion.documentation.js +0 -6
- package/src/components/base/accordion/accordion_item.documentation.js +0 -5
- package/src/components/base/alert/alert.documentation.js +0 -6
- package/src/components/base/avatar/avatar.documentation.js +0 -6
- package/src/components/base/avatar_labeled/avatar_labeled.documentation.js +0 -6
- package/src/components/base/avatar_link/avatar_link.documentation.js +0 -6
- package/src/components/base/avatars_inline/avatars_inline.documentation.js +0 -6
- package/src/components/base/badge/badge.documentation.js +0 -6
- package/src/components/base/banner/banner.documentation.js +0 -6
- package/src/components/base/breadcrumb/breadcrumb.documentation.js +0 -6
- package/src/components/base/broadcast_message/broadcast_message.documentation.js +0 -6
- package/src/components/base/button/button.documentation.js +0 -24
- package/src/components/base/button_group/button_group.documentation.js +0 -6
- package/src/components/base/card/card.documentation.js +0 -6
- package/src/components/base/carousel/carousel.documentation.js +0 -6
- package/src/components/base/collapse/collapse.documentation.js +0 -5
- package/src/components/base/datepicker/datepicker.documentation.js +0 -5
- package/src/components/base/daterange_picker/daterange_picker.documentation.js +0 -6
- package/src/components/base/drawer/drawer.documentation.js +0 -6
- package/src/components/base/dropdown/dropdown.documentation.js +0 -6
- package/src/components/base/dropdown/dropdown_item.documentation.js +0 -5
- package/src/components/base/filtered_search/filtered_search.documentation.js +0 -6
- package/src/components/base/filtered_search/filtered_search_suggestion.documentation.js +0 -5
- package/src/components/base/filtered_search/filtered_search_suggestion_list.documentation.js +0 -5
- package/src/components/base/filtered_search/filtered_search_term.documentation.js +0 -5
- package/src/components/base/filtered_search/filtered_search_token.documentation.js +0 -5
- package/src/components/base/filtered_search/filtered_search_token_segment.documentation.js +0 -5
- package/src/components/base/form/form.documentation.js +0 -5
- package/src/components/base/form/form_checkbox/form_checkbox.documentation.js +0 -6
- package/src/components/base/form/form_checkbox_tree/form_checkbox_tree.documentation.js +0 -5
- package/src/components/base/form/form_combobox/form_combobox.documentation.js +0 -6
- package/src/components/base/form/form_group/form_group.documentation.js +0 -5
- package/src/components/base/form/form_input/form_input.documentation.js +0 -6
- package/src/components/base/form/form_input_group/form_input_group.documentation.js +0 -6
- package/src/components/base/form/form_radio/form_radio.documentation.js +0 -6
- package/src/components/base/form/form_radio_group/form_radio_group.documentation.js +0 -6
- package/src/components/base/form/form_select/form_select.documentation.js +0 -6
- package/src/components/base/form/form_text/form_text.documentation.js +0 -7
- package/src/components/base/form/form_textarea/form_textarea.documentation.js +0 -5
- package/src/components/base/form/input_group_text/input_group_text.documentation.js +0 -5
- package/src/components/base/icon/icon.documentation.js +0 -6
- package/src/components/base/infinite_scroll/examples/index.js +0 -57
- package/src/components/base/infinite_scroll/examples/infinite_scroll.all_items.example.vue +0 -25
- package/src/components/base/infinite_scroll/examples/infinite_scroll.basic.example.vue +0 -43
- package/src/components/base/infinite_scroll/examples/infinite_scroll.finite_total_items.example.vue +0 -44
- package/src/components/base/infinite_scroll/examples/infinite_scroll.large_fetched_items.example.vue +0 -43
- package/src/components/base/infinite_scroll/examples/infinite_scroll.reverse.example.vue +0 -46
- package/src/components/base/infinite_scroll/examples/infinite_scroll.small_fetched_items.example.vue +0 -43
- package/src/components/base/infinite_scroll/examples/infinite_scroll.two_way.example.vue +0 -75
- package/src/components/base/infinite_scroll/infinite_scroll.documentation.js +0 -6
- package/src/components/base/keyset_pagination/keyset_pagination.documentation.js +0 -6
- package/src/components/base/label/label.documentation.js +0 -6
- package/src/components/base/link/link.documentation.js +0 -5
- package/src/components/base/loading_icon/loading_icon.documentation.js +0 -6
- package/src/components/base/markdown/markdown.documentation.js +0 -5
- package/src/components/base/modal/modal.documentation.js +0 -6
- package/src/components/base/nav/nav.documentation.js +0 -5
- package/src/components/base/navbar/navbar.documentation.js +0 -5
- package/src/components/base/paginated_list/paginated_list.documentation.js +0 -5
- package/src/components/base/pagination/pagination.documentation.js +0 -6
- package/src/components/base/path/path.documentation.js +0 -6
- package/src/components/base/popover/popover.documentation.js +0 -3
- package/src/components/base/search_box_by_click/search_box_by_click.documentation.js +0 -6
- package/src/components/base/search_box_by_type/search_box_by_type.documentation.js +0 -6
- package/src/components/base/segmented_control/segmented_control.documentation.js +0 -6
- package/src/components/base/skeleton_loader/skeleton_loader.documentation.js +0 -6
- package/src/components/base/skeleton_loading/skeleton_loading.documentation.js +0 -5
- package/src/components/base/sorting/sorting.documentation.js +0 -5
- package/src/components/base/sorting/sorting_item.documentation.js +0 -6
- package/src/components/base/table/table.documentation.js +0 -6
- package/src/components/base/table_lite/table_lite.documentation.js +0 -6
- package/src/components/base/tabs/tabs/tabs.documentation.js +0 -6
- package/src/components/base/toast/toast.documentation.js +0 -6
- package/src/components/base/toggle/toggle.documentation.js +0 -6
- package/src/components/base/token/token.documentation.js +0 -3
- package/src/components/base/token_selector/token_selector.documentation.js +0 -5
- package/src/components/base/tooltip/tooltip.documentation.js +0 -6
- package/src/components/charts/area/area.documentation.js +0 -3
- package/src/components/charts/bar/bar.documentation.js +0 -6
- package/src/components/charts/chart/chart.documentation.js +0 -5
- package/src/components/charts/column/column.documentation.js +0 -3
- package/src/components/charts/discrete_scatter/discrete_scatter.documentation.js +0 -3
- package/src/components/charts/gauge/gauge.documentation.js +0 -5
- package/src/components/charts/heatmap/heatmap.documentation.js +0 -6
- package/src/components/charts/line/line.documentation.js +0 -6
- package/src/components/charts/series_label/series_label.documentation.js +0 -5
- package/src/components/charts/single_stat/single_stat.documentation.js +0 -5
- package/src/components/charts/sparkline/sparkline.documentation.js +0 -6
- package/src/components/charts/stacked_column/stacked_column.documentation.js +0 -6
- package/src/components/charts/tooltip/tooltip.documentation.js +0 -6
- package/src/components/editors/rich_text_editor/rich_text_editor.documentation.js +0 -5
- package/src/components/regions/dashboard_skeleton/dashboard_skeleton.documentation.js +0 -5
- package/src/components/regions/empty_state/empty_state.documentation.js +0 -5
- package/src/components/utilities/animated_number/animated_number.documentation.js +0 -6
- package/src/components/utilities/friendly_wrap/friendly_wrap.documentation.js +0 -5
- package/src/components/utilities/intersection_observer/intersection_observer.documentation.js +0 -5
- package/src/components/utilities/intersperse/intersperse.documentation.js +0 -6
- package/src/components/utilities/sprintf/sprintf.documentation.js +0 -6
- package/src/components/utilities/truncate/truncate.documentation.js +0 -5
- package/src/directives/hover_load/hover_load.documentation.js +0 -6
- package/src/directives/outside/outside.documentation.js +0 -6
- package/src/directives/resize_observer/resize_observer.documentation.js +0 -6
- package/src/directives/safe_html/safe_html.documentation.js +0 -6
- package/src/directives/safe_link/safe_link.documentation.js +0 -6
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
var description = "A Vue Directive to sanitize HTML to avoid any XSS vulnerabilities.\n\n## Usage\n\nThis directive can be used to sanitize HTML code which may contain user input, to prevent cross-site\nscripting (XSS) vulnerabilities.\n\nUnder the hood, it uses [DOMPurify](https://github.com/cure53/DOMPurify) to sanitize the provided HTML.\n\nDOMPurify will strip out dangerous HTML and will keep the safe HTML. You can refer complete list of\n[tags][1] and [attributes][2] allowed by DOMPurify.\n\n[1]: https://github.com/cure53/DOMPurify/blob/main/src/tags.js\n[2]: https://github.com/cure53/DOMPurify/blob/main/src/attrs.js\n\n## Example\n\n```html\n<script>\nimport { GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';\n\nexport default {\n directives: {\n SafeHtml,\n },\n data() {\n return {\n rawHtml: \"Hello! <script>alert('XSS')</script>\",\n };\n },\n};\n</script>\n\n<template>\n <div v-safe-html=\"rawHtml\"></div>\n</template>\n```\n\n## Advanced configuration\n\n```js\n// It allows only <b> tags\nconst config = { ALLOWED_TAGS: ['b'] };\n\n// It doesn't allow any html tags\nconst config = { ALLOWED_TAGS: [] };\n```\n\n```html\n<div v-safe-html:[config]=\"rawHtml\"></div>\n```\n\nFor advanced configuration options, please refer to [DOMPurify's documentation](https://github.com/cure53/DOMPurify#can-i-configure-dompurify).\n\n### Notes\n\n1. `target` attribute is not allowed by default - See <https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1427>.\n1. To know more about other tips & caveats - See <https://gitlab.com/groups/gitlab-org/-/epics/4273#caveats>.\n";
|
|
2
|
-
|
|
3
|
-
var safe_html_documentation = {
|
|
4
|
-
followsDesignSystem: false,
|
|
5
|
-
description
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export default safe_html_documentation;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
var description = "A Vue directive to make the hyperlinks secure by default.\n\n## Security measures\n\n### rel\n\nWhen setting target to `_blank`, the rel attribute gets set automatically to `noopener noreferrer`,\nthis is done to avoid the `window.opener` [API exploit]. If you set the `rel` attribute manually,\nthis will overwrite the aforementioned logic.\n\n### href\n\nThis directive enforces \"safe\" URLs. What this means is that, if the provided `href`\ndoesn't point to a safe protocol (one of `http:`, `https:`, `mailto:` or `ftp:`), then it is\nreplaced with `about:blank` to prevent [URL injections].\n\n```html\n<script>\nimport { GlSafeLinkDirective as SafeLink } from '@gitlab/ui';\n\nexport default {\n data() {\n return {\n url: 'javascript:alert(1)',\n };\n },\n directives: { SafeLink },\n};\n</script>\n<template>\n <a v-safe-link href=\"url\" target=\"_blank\">Click</a>\n <!-- Renders to: <a href=\"about:blank\" target=\"_blank\">Click</a> -->\n</template>\n```\n\n[API exploit]: https://www.jitbit.com/alexblog/256-targetblank---the-most-underestimated-vulnerability-ever/\n[URL injections]: https://vuejs.org/v2/guide/security.html#Injecting-URLs\n";
|
|
2
|
-
|
|
3
|
-
var safe_link_documentation = {
|
|
4
|
-
followsDesignSystem: false,
|
|
5
|
-
description
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export default safe_link_documentation;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import * as chartComponents from '../src/charts';
|
|
2
|
-
import * as components from '../src';
|
|
3
|
-
|
|
4
|
-
export const gitlabComponents = { ...components, ...chartComponents };
|
|
5
|
-
export const gitlabChartComponents = { ...chartComponents };
|
|
6
|
-
|
|
7
|
-
export const componentValidator = (componentName) =>
|
|
8
|
-
Object.keys(gitlabComponents).includes(componentName);
|
|
@@ -1,321 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import BootstrapVue from 'bootstrap-vue';
|
|
3
|
-
import * as vueComponents from 'bootstrap-vue/src/components/index';
|
|
4
|
-
import { isString, isUndefined } from 'lodash';
|
|
5
|
-
import camelCase from 'lodash/camelCase';
|
|
6
|
-
import isArray from 'lodash/isArray';
|
|
7
|
-
import isFunction from 'lodash/isFunction';
|
|
8
|
-
import kebabCase from 'lodash/kebabCase';
|
|
9
|
-
import merge from 'lodash/merge';
|
|
10
|
-
import Vue from 'vue';
|
|
11
|
-
|
|
12
|
-
import GlBadge from '../../src/components/base/badge/badge.vue';
|
|
13
|
-
import GlTable from '../../src/components/base/table/table.vue';
|
|
14
|
-
import * as enumConstants from '../../src/utils/constants';
|
|
15
|
-
import { getValidationInfoText } from '../../src/utils/validation_utils';
|
|
16
|
-
|
|
17
|
-
import { gitlabComponents, gitlabChartComponents, componentValidator } from '../all_components';
|
|
18
|
-
|
|
19
|
-
import { getDocumentationFor } from '../components_documentation';
|
|
20
|
-
|
|
21
|
-
Vue.use(BootstrapVue);
|
|
22
|
-
|
|
23
|
-
function getPropDefaultValue(defaultValue) {
|
|
24
|
-
let returnValue = '';
|
|
25
|
-
if (isString(defaultValue)) {
|
|
26
|
-
returnValue = defaultValue;
|
|
27
|
-
}
|
|
28
|
-
if (isFunction(defaultValue) && !isArray(defaultValue)) {
|
|
29
|
-
returnValue = defaultValue();
|
|
30
|
-
}
|
|
31
|
-
if (!isString(defaultValue) && !isUndefined(defaultValue)) {
|
|
32
|
-
returnValue = JSON.stringify(defaultValue);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (defaultValue === null || defaultValue === undefined) {
|
|
36
|
-
returnValue = String(defaultValue);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (isString(returnValue)) returnValue = returnValue.replace(/"/g, "'");
|
|
40
|
-
return returnValue;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default {
|
|
44
|
-
components: {
|
|
45
|
-
GlTable,
|
|
46
|
-
GlBadge,
|
|
47
|
-
},
|
|
48
|
-
props: {
|
|
49
|
-
componentName: {
|
|
50
|
-
type: String,
|
|
51
|
-
required: false,
|
|
52
|
-
default: 'Link',
|
|
53
|
-
validator: componentValidator,
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
computed: {
|
|
57
|
-
actualComponent() {
|
|
58
|
-
if (gitlabComponents[this.componentName]) {
|
|
59
|
-
return Vue.options.components[this.componentName] || {};
|
|
60
|
-
}
|
|
61
|
-
return {};
|
|
62
|
-
},
|
|
63
|
-
importSubDir() {
|
|
64
|
-
if (gitlabChartComponents[this.componentName]) {
|
|
65
|
-
return '/dist/charts';
|
|
66
|
-
}
|
|
67
|
-
return '';
|
|
68
|
-
},
|
|
69
|
-
actualComponentOptions() {
|
|
70
|
-
return this.actualComponent.options || {};
|
|
71
|
-
},
|
|
72
|
-
componentVModel() {
|
|
73
|
-
const { model } = this.actualComponentOptions;
|
|
74
|
-
|
|
75
|
-
if (!model) {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
prop: 'value',
|
|
81
|
-
event: 'input',
|
|
82
|
-
...model,
|
|
83
|
-
};
|
|
84
|
-
},
|
|
85
|
-
documentationInfo() {
|
|
86
|
-
return getDocumentationFor(this.componentName);
|
|
87
|
-
},
|
|
88
|
-
bootstrapComponentName() {
|
|
89
|
-
return this.documentationInfo.bootstrapComponent || '';
|
|
90
|
-
},
|
|
91
|
-
bootstrapComponentLink() {
|
|
92
|
-
return this.bootstrapComponentName.replace('b-', '').toLowerCase();
|
|
93
|
-
},
|
|
94
|
-
bootstrapComponentOptions() {
|
|
95
|
-
const bootstrapRegisterName = this.bootstrapComponentName
|
|
96
|
-
? this.bootstrapComponentName[0].toUpperCase() +
|
|
97
|
-
camelCase(this.bootstrapComponentName).substr(1)
|
|
98
|
-
: '';
|
|
99
|
-
const bootstrapComponent = vueComponents[bootstrapRegisterName];
|
|
100
|
-
return bootstrapComponent && bootstrapComponent.options ? bootstrapComponent.options : {};
|
|
101
|
-
},
|
|
102
|
-
componentPropertiesFields() {
|
|
103
|
-
return [
|
|
104
|
-
{ key: 'prop', label: 'Property' },
|
|
105
|
-
{ key: 'type', label: 'Type' },
|
|
106
|
-
{ key: 'required', label: 'Required' },
|
|
107
|
-
{ key: 'val', label: 'Value' },
|
|
108
|
-
];
|
|
109
|
-
},
|
|
110
|
-
eventsFields() {
|
|
111
|
-
return [
|
|
112
|
-
{ key: 'event', label: 'Event' },
|
|
113
|
-
{ key: 'args', label: 'Arguments' },
|
|
114
|
-
{ key: 'description', label: 'Description' },
|
|
115
|
-
];
|
|
116
|
-
},
|
|
117
|
-
componentProperties() {
|
|
118
|
-
const { props } = this.actualComponentOptions;
|
|
119
|
-
if (!props) return [];
|
|
120
|
-
if (this.documentationInfo.propsInfo) {
|
|
121
|
-
merge(props, this.documentationInfo.propsInfo);
|
|
122
|
-
}
|
|
123
|
-
return this.getPropsMap(props);
|
|
124
|
-
},
|
|
125
|
-
bootstrapComponentProperties() {
|
|
126
|
-
const { props } = this.bootstrapComponentOptions;
|
|
127
|
-
if (!props) return [];
|
|
128
|
-
if (this.documentationInfo.bootstrapPropsInfo) {
|
|
129
|
-
merge(props, this.documentationInfo.bootstrapPropsInfo);
|
|
130
|
-
}
|
|
131
|
-
return this.getPropsMap(props);
|
|
132
|
-
},
|
|
133
|
-
displayComponentProperties() {
|
|
134
|
-
let returnProps = Object.assign([], this.componentProperties);
|
|
135
|
-
const bootstrapProps = this.bootstrapComponentProperties;
|
|
136
|
-
|
|
137
|
-
if (bootstrapProps && bootstrapProps.length > 0) {
|
|
138
|
-
const applyableBootstrapProps = bootstrapProps.reduce((actualProps, prop) => {
|
|
139
|
-
const checkComp = returnProps.find((checkProp) => checkProp.prop === prop.prop);
|
|
140
|
-
if (!checkComp) {
|
|
141
|
-
// eslint-disable-next-line no-param-reassign, no-underscore-dangle
|
|
142
|
-
prop._cellVariants = { prop: 'info' };
|
|
143
|
-
actualProps.push(prop);
|
|
144
|
-
}
|
|
145
|
-
return actualProps;
|
|
146
|
-
}, []);
|
|
147
|
-
returnProps = returnProps.concat(applyableBootstrapProps);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return returnProps;
|
|
151
|
-
},
|
|
152
|
-
displayEvents() {
|
|
153
|
-
const events = this.documentationInfo.events || [];
|
|
154
|
-
if (this.componentVModel) {
|
|
155
|
-
const vModelEventIndex = events.findIndex(
|
|
156
|
-
({ event }) => event === this.componentVModel.event
|
|
157
|
-
);
|
|
158
|
-
if (vModelEventIndex === -1) {
|
|
159
|
-
events.push({
|
|
160
|
-
event: this.componentVModel.event,
|
|
161
|
-
args: [
|
|
162
|
-
{
|
|
163
|
-
arg: this.componentVModel.prop,
|
|
164
|
-
},
|
|
165
|
-
],
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return events;
|
|
170
|
-
},
|
|
171
|
-
displaySlots() {
|
|
172
|
-
return this.documentationInfo.slots || [];
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
methods: {
|
|
176
|
-
getPropsMap: (props) =>
|
|
177
|
-
Object.keys(props).map((prop) => {
|
|
178
|
-
const selProp = props[prop];
|
|
179
|
-
|
|
180
|
-
// Copying over values if available from documentation definition
|
|
181
|
-
const propsInfo = {
|
|
182
|
-
prop: kebabCase(prop),
|
|
183
|
-
required: selProp.required,
|
|
184
|
-
additionalInfo: selProp.additionalInfo,
|
|
185
|
-
validationInfo: getValidationInfoText(selProp.validation),
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
// Figuring out the actual type of this property
|
|
189
|
-
const baseType = selProp.type || Object;
|
|
190
|
-
if (Array.isArray(baseType)) {
|
|
191
|
-
propsInfo.type = baseType.map((t) => t.name).join(' or ');
|
|
192
|
-
} else {
|
|
193
|
-
propsInfo.type = baseType.name;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// Getting the defaultValue and setting it then also the value
|
|
197
|
-
if (propsInfo.type === 'Function' && isFunction(selProp.default)) {
|
|
198
|
-
propsInfo.val = selProp.default.toString();
|
|
199
|
-
} else if ('default' in selProp) {
|
|
200
|
-
propsInfo.val = getPropDefaultValue(selProp.default);
|
|
201
|
-
} else {
|
|
202
|
-
propsInfo.val = '';
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// If we have an enum on this property we assign it and look up its values in the constant file
|
|
206
|
-
if (selProp.enum) {
|
|
207
|
-
propsInfo.enum = selProp.enum;
|
|
208
|
-
propsInfo.enumValues = Object.values(enumConstants[selProp.enum]);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return propsInfo;
|
|
212
|
-
}),
|
|
213
|
-
},
|
|
214
|
-
};
|
|
215
|
-
</script>
|
|
216
|
-
|
|
217
|
-
<template>
|
|
218
|
-
<div v-if="actualComponent.options">
|
|
219
|
-
<div v-if="displayComponentProperties.length > 0">
|
|
220
|
-
<h3>Props</h3>
|
|
221
|
-
<gl-table
|
|
222
|
-
:items="displayComponentProperties"
|
|
223
|
-
:fields="componentPropertiesFields"
|
|
224
|
-
small
|
|
225
|
-
head-variant="default"
|
|
226
|
-
striped
|
|
227
|
-
>
|
|
228
|
-
<template #cell(prop)="field">
|
|
229
|
-
<div>
|
|
230
|
-
<span :title="field.item._cellVariants ? 'Inherited from Vue Bootstrap' : ''">
|
|
231
|
-
{{ field.value }}
|
|
232
|
-
<gl-badge
|
|
233
|
-
v-if="componentVModel && field.value === componentVModel.prop"
|
|
234
|
-
variant="info"
|
|
235
|
-
>
|
|
236
|
-
v-model
|
|
237
|
-
</gl-badge>
|
|
238
|
-
</span>
|
|
239
|
-
</div>
|
|
240
|
-
</template>
|
|
241
|
-
<template #cell(required)="data">
|
|
242
|
-
<span v-if="data.value === true">✅</span>
|
|
243
|
-
</template>
|
|
244
|
-
<template #cell(val)="data">
|
|
245
|
-
<code v-if="data.value">
|
|
246
|
-
{{ data.value }}
|
|
247
|
-
</code>
|
|
248
|
-
<template v-if="data.item.validationInfo">({{ data.item.validationInfo }})</template>
|
|
249
|
-
<div v-if="data.item.additionalInfo">
|
|
250
|
-
<i>{{ data.item.additionalInfo }}</i>
|
|
251
|
-
</div>
|
|
252
|
-
<template v-if="data.item.enum">
|
|
253
|
-
<div>
|
|
254
|
-
{{ data.item.enum }}: <i>{{ data.item.enumValues.join(', ') }}</i>
|
|
255
|
-
</div>
|
|
256
|
-
</template>
|
|
257
|
-
</template>
|
|
258
|
-
</gl-table>
|
|
259
|
-
</div>
|
|
260
|
-
|
|
261
|
-
<div v-if="displaySlots.length > 0">
|
|
262
|
-
<h4>Slots</h4>
|
|
263
|
-
<gl-table :items="displaySlots" small head-variant="default" striped />
|
|
264
|
-
</div>
|
|
265
|
-
|
|
266
|
-
<div v-if="displayEvents.length > 0">
|
|
267
|
-
<h4>Events</h4>
|
|
268
|
-
<gl-table :items="displayEvents" :fields="eventsFields" small head-variant="default" striped>
|
|
269
|
-
<template #cell(event)="field">
|
|
270
|
-
{{ field.value }}
|
|
271
|
-
<gl-badge v-if="componentVModel && field.value === componentVModel.event" variant="info">
|
|
272
|
-
v-model
|
|
273
|
-
</gl-badge>
|
|
274
|
-
</template>
|
|
275
|
-
<template #cell(args)="field">
|
|
276
|
-
<div
|
|
277
|
-
v-for="argument in field.value"
|
|
278
|
-
:key="`event-${field.item.event}-${argument.arg ? argument.arg : 'none'}`"
|
|
279
|
-
>
|
|
280
|
-
<code v-if="argument.arg">{{ argument.arg }}</code>
|
|
281
|
-
<span>{{ argument.description }}</span>
|
|
282
|
-
</div>
|
|
283
|
-
</template>
|
|
284
|
-
</gl-table>
|
|
285
|
-
</div>
|
|
286
|
-
|
|
287
|
-
<div v-if="componentVModel">
|
|
288
|
-
<h4>v-model</h4>
|
|
289
|
-
<gl-table
|
|
290
|
-
:items="[componentVModel]"
|
|
291
|
-
:fields="['prop', 'event']"
|
|
292
|
-
small
|
|
293
|
-
head-variant="default"
|
|
294
|
-
striped
|
|
295
|
-
/>
|
|
296
|
-
</div>
|
|
297
|
-
|
|
298
|
-
<h3>Import</h3>
|
|
299
|
-
|
|
300
|
-
<p>
|
|
301
|
-
<code>import { {{ componentName }} } from '@gitlab/ui{{ importSubDir }}';</code>
|
|
302
|
-
</p>
|
|
303
|
-
|
|
304
|
-
<template v-if="bootstrapComponentName">
|
|
305
|
-
<h3 id="under-the-hood">vue-bootstrap component</h3>
|
|
306
|
-
<p>
|
|
307
|
-
This component uses
|
|
308
|
-
<a
|
|
309
|
-
:href="`https://bootstrap-vue.org/docs/components/${bootstrapComponentLink}`"
|
|
310
|
-
target="blank"
|
|
311
|
-
><code><{{ bootstrapComponentName }}></code></a
|
|
312
|
-
>
|
|
313
|
-
from vue-bootstrap internally. So please take a look also there at their extensive
|
|
314
|
-
documentation.
|
|
315
|
-
</p>
|
|
316
|
-
</template>
|
|
317
|
-
</div>
|
|
318
|
-
<b-alert v-else show variant="warning">
|
|
319
|
-
No GitLab UI component found with the name {{ componentName }}
|
|
320
|
-
</b-alert>
|
|
321
|
-
</template>
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
/* eslint-disable vue/no-v-html */
|
|
3
|
-
|
|
4
|
-
import * as Babel from '@babel/standalone';
|
|
5
|
-
import BootstrapVue from 'bootstrap-vue';
|
|
6
|
-
import copyToClipboard from 'copy-to-clipboard';
|
|
7
|
-
import hljs from 'highlight.js';
|
|
8
|
-
import { html } from 'js-beautify';
|
|
9
|
-
import Vue from 'vue';
|
|
10
|
-
import { parseComponent } from 'vue-template-compiler';
|
|
11
|
-
import 'highlight.js/styles/monokai.css';
|
|
12
|
-
import { gitlabComponents } from '../all_components';
|
|
13
|
-
import * as Documentation from '../components_documentation';
|
|
14
|
-
|
|
15
|
-
// We need to register globally all components as we don't know the components that are used in the dynamically compiled .example.vue files
|
|
16
|
-
// This is only for design.gitlab.com and shouldn't be done in our actual application
|
|
17
|
-
Vue.use(BootstrapVue);
|
|
18
|
-
Object.keys(gitlabComponents).forEach((comp) => {
|
|
19
|
-
if (!comp.includes('Directive')) {
|
|
20
|
-
Vue.component(comp, gitlabComponents[comp]);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
// We need to do Directives for now manually
|
|
25
|
-
Vue.directive('gl-tooltip', gitlabComponents.GlTooltipDirective);
|
|
26
|
-
Vue.directive('gl-modal-directive', gitlabComponents.GlModalDirective);
|
|
27
|
-
Vue.directive('gl-resize-observer-directive', gitlabComponents.GlResizeObserverDirective);
|
|
28
|
-
Vue.directive('gl-safe-html-directive', gitlabComponents.GlSafeHtmlDirective);
|
|
29
|
-
Vue.directive('gl-collapse-toggle', gitlabComponents.GlCollapseToggleDirective);
|
|
30
|
-
Vue.directive('gl-outside', gitlabComponents.GlOutsideDirective);
|
|
31
|
-
Vue.directive('gl-hover-load', gitlabComponents.GlHoverLoadDirective);
|
|
32
|
-
|
|
33
|
-
function findComponentExample(exampleName) {
|
|
34
|
-
/* eslint-disable no-restricted-syntax */
|
|
35
|
-
// Doing it with a for loop to have an early return/break during iteration
|
|
36
|
-
for (const component of Object.values(Documentation)) {
|
|
37
|
-
if (component.examples) {
|
|
38
|
-
// Looking for an example in the component documentation definition that matches the exampleName
|
|
39
|
-
for (const exampleGroup of component.examples) {
|
|
40
|
-
const foundExample = exampleGroup.items.find((example) => example.id === exampleName);
|
|
41
|
-
if (foundExample) {
|
|
42
|
-
return foundExample;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
/* eslint-enable no-restricted-syntax */
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const animationTimeout = 2000;
|
|
52
|
-
|
|
53
|
-
export default {
|
|
54
|
-
props: {
|
|
55
|
-
exampleName: {
|
|
56
|
-
type: String,
|
|
57
|
-
required: true,
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
data() {
|
|
61
|
-
return {
|
|
62
|
-
source: '',
|
|
63
|
-
renderedHtml: '',
|
|
64
|
-
copiedSource: false,
|
|
65
|
-
copiedOutput: false,
|
|
66
|
-
};
|
|
67
|
-
},
|
|
68
|
-
computed: {
|
|
69
|
-
// Based on the set exampleName we try to look it up in the currently loaded Documentation Examples and then read it-> parse and compile it
|
|
70
|
-
currentExampleComponent() {
|
|
71
|
-
// Going through all documentation objects of all components
|
|
72
|
-
const foundExample = findComponentExample(this.exampleName);
|
|
73
|
-
|
|
74
|
-
// Live loading of .example.vue files
|
|
75
|
-
// Examples are included with webpack through raw-loader -> Results in a string
|
|
76
|
-
if (foundExample && foundExample !== undefined) {
|
|
77
|
-
const base = {
|
|
78
|
-
name: '',
|
|
79
|
-
template: '<div></div>',
|
|
80
|
-
};
|
|
81
|
-
try {
|
|
82
|
-
// At Runtime we parse it with `parseComponent` from `vue-template-compiler` (Line 64)
|
|
83
|
-
const parsed = parseComponent(foundExample.component);
|
|
84
|
-
|
|
85
|
-
let compiled = {};
|
|
86
|
-
if (parsed.script) {
|
|
87
|
-
// We parse the script part with Babel.transform (Line 68 in example_display)
|
|
88
|
-
const { code } = Babel.transform(parsed.script.content, {
|
|
89
|
-
presets: ['es2015', ['stage-2', { decoratorsBeforeExport: false }]],
|
|
90
|
-
});
|
|
91
|
-
compiled = eval(`const exports = {};${code}`); // eslint-disable-line no-eval
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Results in the original source of the template and the compiled and working Vue component
|
|
95
|
-
compiled.template = parsed.template.content;
|
|
96
|
-
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
|
|
97
|
-
this.source = compiled.template;
|
|
98
|
-
|
|
99
|
-
return { ...base, ...compiled };
|
|
100
|
-
} catch (e) {
|
|
101
|
-
// eslint-disable-next-line no-console
|
|
102
|
-
console.log('ERR : ', e);
|
|
103
|
-
return base;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return null;
|
|
107
|
-
},
|
|
108
|
-
exampleHTMLOutput() {
|
|
109
|
-
return this.$refs.exampleComponent || '';
|
|
110
|
-
},
|
|
111
|
-
sourceFormatted() {
|
|
112
|
-
if (this.source) {
|
|
113
|
-
return hljs.fixMarkup(hljs.highlight('html', this.source).value);
|
|
114
|
-
}
|
|
115
|
-
return '';
|
|
116
|
-
},
|
|
117
|
-
renderedHtmlFormatted() {
|
|
118
|
-
if (this.renderedHtml) {
|
|
119
|
-
return hljs.fixMarkup(hljs.highlight('html', this.renderedHtml).value);
|
|
120
|
-
}
|
|
121
|
-
return '';
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
watch: {
|
|
125
|
-
currentExampleComponent() {
|
|
126
|
-
Vue.nextTick(() => {
|
|
127
|
-
this.setHtml();
|
|
128
|
-
});
|
|
129
|
-
},
|
|
130
|
-
},
|
|
131
|
-
created() {
|
|
132
|
-
// Converting Tabs to spaces to make display look indented
|
|
133
|
-
hljs.configure({ tabReplace: ' ', useBR: true });
|
|
134
|
-
},
|
|
135
|
-
mounted() {
|
|
136
|
-
this.setHtml();
|
|
137
|
-
},
|
|
138
|
-
methods: {
|
|
139
|
-
setHtml() {
|
|
140
|
-
if (this.$refs.compiled) {
|
|
141
|
-
const markup = this.$refs.compiled.$el.outerHTML;
|
|
142
|
-
if (markup) {
|
|
143
|
-
// Splitting lines for easier readability on the rendered output
|
|
144
|
-
const preFormattedHTML = markup.replace(/><(?!\/i|\/label|\/span|option)/g, '>\n<');
|
|
145
|
-
this.renderedHtml = html(preFormattedHTML, {
|
|
146
|
-
indent_size: 2,
|
|
147
|
-
indent_char: ' ',
|
|
148
|
-
wrap_attributes: 'auto',
|
|
149
|
-
wrap_attributes_indent_size: 2,
|
|
150
|
-
end_with_newline: false,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
copySource() {
|
|
156
|
-
copyToClipboard(this.source);
|
|
157
|
-
this.copiedSource = true;
|
|
158
|
-
setTimeout(() => {
|
|
159
|
-
this.copiedSource = false;
|
|
160
|
-
}, animationTimeout);
|
|
161
|
-
},
|
|
162
|
-
copyHtml() {
|
|
163
|
-
copyToClipboard(this.renderedHtml);
|
|
164
|
-
this.copiedOutput = true;
|
|
165
|
-
setTimeout(() => {
|
|
166
|
-
this.copiedOutput = false;
|
|
167
|
-
}, animationTimeout);
|
|
168
|
-
},
|
|
169
|
-
},
|
|
170
|
-
};
|
|
171
|
-
</script>
|
|
172
|
-
|
|
173
|
-
<template>
|
|
174
|
-
<div>
|
|
175
|
-
<div v-if="currentExampleComponent">
|
|
176
|
-
<b-card no-body>
|
|
177
|
-
<template #header>
|
|
178
|
-
<div>
|
|
179
|
-
<b-row>
|
|
180
|
-
<b-col>
|
|
181
|
-
<strong>{{ exampleName }}</strong>
|
|
182
|
-
</b-col>
|
|
183
|
-
<b-col class="text-right">
|
|
184
|
-
<b-button-group size="sm" class="mx-1">
|
|
185
|
-
<b-btn v-b-toggle.collapseSource>Source</b-btn>
|
|
186
|
-
<b-btn v-b-toggle.collapseHTML>HTML</b-btn>
|
|
187
|
-
</b-button-group>
|
|
188
|
-
</b-col>
|
|
189
|
-
</b-row>
|
|
190
|
-
</div>
|
|
191
|
-
</template>
|
|
192
|
-
<b-card-body>
|
|
193
|
-
<component :is="currentExampleComponent" ref="compiled" />
|
|
194
|
-
</b-card-body>
|
|
195
|
-
<b-list-group flush>
|
|
196
|
-
<b-collapse id="collapseSource" class="mt-2">
|
|
197
|
-
<b-list-group-item>
|
|
198
|
-
<b-row>
|
|
199
|
-
<b-col cols="8"><h6>Source</h6></b-col>
|
|
200
|
-
<b-col class="text-right">
|
|
201
|
-
<template v-if="copiedSource">Copied!</template>
|
|
202
|
-
<b-button-group size="sm">
|
|
203
|
-
<b-button :disabled="copiedSource" @click="copySource">Copy</b-button>
|
|
204
|
-
</b-button-group>
|
|
205
|
-
</b-col>
|
|
206
|
-
</b-row>
|
|
207
|
-
<code class="hljs html" v-html="sourceFormatted"></code>
|
|
208
|
-
</b-list-group-item>
|
|
209
|
-
</b-collapse>
|
|
210
|
-
<b-collapse id="collapseHTML" class="mt-2">
|
|
211
|
-
<b-list-group-item>
|
|
212
|
-
<b-row>
|
|
213
|
-
<b-col cols="8"><h6>HTML Output</h6></b-col>
|
|
214
|
-
<b-col class="text-right">
|
|
215
|
-
<template v-if="copiedOutput">Copied!</template>
|
|
216
|
-
<b-button-group size="sm">
|
|
217
|
-
<b-button :disabled="copiedOutput" @click="copyHtml">Copy</b-button>
|
|
218
|
-
</b-button-group>
|
|
219
|
-
</b-col>
|
|
220
|
-
</b-row>
|
|
221
|
-
<code class="hljs html" v-html="renderedHtmlFormatted"></code>
|
|
222
|
-
</b-list-group-item>
|
|
223
|
-
</b-collapse>
|
|
224
|
-
</b-list-group>
|
|
225
|
-
</b-card>
|
|
226
|
-
</div>
|
|
227
|
-
<b-alert v-else-if="exampleName" show variant="warning"
|
|
228
|
-
>No Example found with the name "{{ exampleName }}"</b-alert
|
|
229
|
-
>
|
|
230
|
-
</div>
|
|
231
|
-
</template>
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import GlFormSelect from '../../src/components/base/form/form_select/form_select.vue';
|
|
3
|
-
import { getDocumentationFor } from '../components_documentation';
|
|
4
|
-
import GlExampleDisplay from './example_display.vue';
|
|
5
|
-
|
|
6
|
-
export default {
|
|
7
|
-
components: {
|
|
8
|
-
GlExampleDisplay,
|
|
9
|
-
GlFormSelect,
|
|
10
|
-
},
|
|
11
|
-
props: {
|
|
12
|
-
componentName: {
|
|
13
|
-
type: String,
|
|
14
|
-
required: true,
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
data() {
|
|
18
|
-
return {
|
|
19
|
-
selectedExampleId: '',
|
|
20
|
-
};
|
|
21
|
-
},
|
|
22
|
-
computed: {
|
|
23
|
-
exampleGroups() {
|
|
24
|
-
return getDocumentationFor(this.componentName).examples || [];
|
|
25
|
-
},
|
|
26
|
-
firstExampleId() {
|
|
27
|
-
if (
|
|
28
|
-
this.exampleGroups &&
|
|
29
|
-
this.exampleGroups.length > 0 &&
|
|
30
|
-
this.exampleGroups[0].items &&
|
|
31
|
-
this.exampleGroups[0].items.length > 0
|
|
32
|
-
) {
|
|
33
|
-
return this.exampleGroups[0].items[0].id;
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
mounted() {
|
|
39
|
-
if (this.firstExampleId) {
|
|
40
|
-
this.selectedExampleId = this.firstExampleId;
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
};
|
|
44
|
-
</script>
|
|
45
|
-
|
|
46
|
-
<template>
|
|
47
|
-
<div>
|
|
48
|
-
<h3>Examples</h3>
|
|
49
|
-
<gl-form-select
|
|
50
|
-
v-if="exampleGroups && exampleGroups.length > 0"
|
|
51
|
-
v-model="selectedExampleId"
|
|
52
|
-
class="mb-3"
|
|
53
|
-
>
|
|
54
|
-
<template v-for="exampleGroup in exampleGroups">
|
|
55
|
-
<optgroup :key="exampleGroup.title" :label="exampleGroup.name"></optgroup>
|
|
56
|
-
<template v-for="example in exampleGroup.items">
|
|
57
|
-
<option :key="example.id" :value="example.id">{{ example.name }}</option>
|
|
58
|
-
</template>
|
|
59
|
-
</template>
|
|
60
|
-
</gl-form-select>
|
|
61
|
-
<gl-example-display v-if="selectedExampleId" :example-name="selectedExampleId" />
|
|
62
|
-
</div>
|
|
63
|
-
</template>
|