@gitlab/ui 130.1.1 → 131.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/components/base/new_dropdowns/base_dropdown/base_dropdown.js +9 -0
  2. package/dist/components/base/new_dropdowns/disclosure/disclosure_dropdown.js +18 -2
  3. package/dist/components/base/toast/index.js +66 -0
  4. package/dist/components/base/toast/toast.js +117 -89
  5. package/dist/components/base/toast/toaster.js +87 -0
  6. package/dist/components/charts/single_stat/single_stat.js +13 -1
  7. package/dist/components/index.js +1 -1
  8. package/dist/index.css +2 -2
  9. package/dist/index.css.map +1 -1
  10. package/dist/tailwind.css +1 -1
  11. package/dist/tailwind.css.map +1 -1
  12. package/package.json +4 -1
  13. package/src/components/base/new_dropdowns/base_dropdown/base_dropdown.vue +9 -0
  14. package/src/components/base/new_dropdowns/disclosure/disclosure_dropdown.vue +23 -1
  15. package/src/components/base/toast/index.js +66 -0
  16. package/src/components/base/toast/toast.scss +31 -5
  17. package/src/components/base/toast/toast.vue +131 -0
  18. package/src/components/base/toast/toaster.vue +70 -0
  19. package/src/components/charts/single_stat/single_stat.vue +31 -3
  20. package/src/components/index.js +1 -1
  21. package/src/scss/bootstrap_vue.scss +0 -1
  22. package/dist/vendor/bootstrap-vue/src/components/toast/helpers/bv-toast.js +0 -234
  23. package/dist/vendor/bootstrap-vue/src/components/toast/index.js +0 -19
  24. package/dist/vendor/bootstrap-vue/src/components/toast/toast.js +0 -407
  25. package/dist/vendor/bootstrap-vue/src/components/toast/toaster.js +0 -142
  26. package/src/components/base/toast/toast.js +0 -102
  27. package/src/vendor/bootstrap-vue/src/components/toast/_toast.scss +0 -77
  28. package/src/vendor/bootstrap-vue/src/components/toast/_toaster.scss +0 -108
  29. package/src/vendor/bootstrap-vue/src/components/toast/helpers/bv-toast.js +0 -231
  30. package/src/vendor/bootstrap-vue/src/components/toast/index.js +0 -12
  31. package/src/vendor/bootstrap-vue/src/components/toast/index.scss +0 -2
  32. package/src/vendor/bootstrap-vue/src/components/toast/toast.js +0 -439
  33. package/src/vendor/bootstrap-vue/src/components/toast/toaster.js +0 -136
@@ -163,6 +163,14 @@ var script = {
163
163
  required: false,
164
164
  default: null
165
165
  },
166
+ /**
167
+ * The `aria-label` attribute value for the toggle `button`.
168
+ */
169
+ ariaLabel: {
170
+ type: String,
171
+ required: false,
172
+ default: null
173
+ },
166
174
  /**
167
175
  * Custom value to be passed to the offset middleware.
168
176
  * https://floating-ui.com/docs/offset
@@ -273,6 +281,7 @@ var script = {
273
281
  'aria-expanded': String(this.visible),
274
282
  'aria-haspopup': this.ariaHaspopup,
275
283
  'aria-labelledby': this.toggleLabelledBy,
284
+ 'aria-label': this.ariaLabel || undefined,
276
285
  'aria-activedescendant': this.ariaActiveDescendant
277
286
  };
278
287
  },
@@ -1,5 +1,5 @@
1
1
  import { uniqueId, clamp } from 'lodash-es';
2
- import { stopEvent, filterVisible } from '../../../../utils/utils';
2
+ import { logWarning, stopEvent, filterVisible } from '../../../../utils/utils';
3
3
  import { GL_DROPDOWN_SHOWN, GL_DROPDOWN_HIDDEN, GL_DROPDOWN_BEFORE_CLOSE, GL_DROPDOWN_FOCUS_CONTENT, POSITION_ABSOLUTE, POSITION_FIXED, HOME, END, ARROW_UP, ARROW_DOWN, ENTER, SPACE, GL_DROPDOWN_CONTENTS_CLASS } from '../constants';
4
4
  import { buttonCategoryOptions, dropdownVariantOptions, buttonSizeOptions, dropdownPlacements } from '../../../../utils/constants';
5
5
  import GlBaseDropdown from '../base_dropdown/base_dropdown';
@@ -143,6 +143,17 @@ var script = {
143
143
  required: false,
144
144
  default: null
145
145
  },
146
+ /**
147
+ * The `aria-label` attribute value for the toggle button.
148
+ * Use when there is no visible label element to reference with `toggleAriaLabelledBy`.
149
+ * Do not provide both `toggleAriaLabel` and `toggleAriaLabelledBy`.
150
+ * When both are present, `toggleAriaLabelledBy` takes precedence per the WAI-ARIA spec.
151
+ */
152
+ toggleAriaLabel: {
153
+ type: String,
154
+ required: false,
155
+ default: null
156
+ },
146
157
  /**
147
158
  * The `aria-labelledby` attribute value for the list of options
148
159
  * Provide the string of ids seperated by space
@@ -230,6 +241,11 @@ var script = {
230
241
  }
231
242
  },
232
243
  mounted() {
244
+ if (this.toggleAriaLabel && this.toggleAriaLabelledBy) {
245
+ logWarning('Do not provide both `toggleAriaLabel` and `toggleAriaLabelledBy`. ' + 'When both are present, `toggleAriaLabelledBy` takes precedence and `toggleAriaLabel` is ignored. ' + 'See https://design.gitlab.com/components/dropdown-disclosure/#accessibility', {
246
+ name: 'GlDisclosureDropdown'
247
+ });
248
+ }
233
249
  if (this.startOpened) {
234
250
  this.open();
235
251
  }
@@ -349,7 +365,7 @@ var script = {
349
365
  const __vue_script__ = script;
350
366
 
351
367
  /* template */
352
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-base-dropdown',{ref:"baseDropdown",staticClass:"gl-disclosure-dropdown",attrs:{"aria-labelledby":_vm.toggleAriaLabelledBy,"arrow-element":_vm.$refs.disclosureArrow,"toggle-id":_vm.toggleId,"toggle-text":_vm.toggleText,"toggle-class":_vm.toggleClass,"text-sr-only":_vm.textSrOnly,"category":_vm.category,"variant":_vm.variant,"size":_vm.size,"icon":_vm.icon,"disabled":_vm.disabled,"loading":_vm.loading,"no-caret":_vm.noCaret,"placement":_vm.placement,"block":_vm.block,"offset":_vm.dropdownOffset,"fluid-width":_vm.fluidWidth,"positioning-strategy":_vm.positioningStrategy,"is-disclosure":""},on:_vm._d({},[_vm.$options.events.GL_DROPDOWN_SHOWN,_vm.onShow,_vm.$options.events.GL_DROPDOWN_HIDDEN,_vm.onHide,_vm.$options.events.GL_DROPDOWN_BEFORE_CLOSE,_vm.onBeforeClose,_vm.$options.events.GL_DROPDOWN_FOCUS_CONTENT,_vm.onKeydown]),scopedSlots:_vm._u([(_vm.hasCustomToggle)?{key:"toggle",fn:function(slotProps){return [_vm._t("toggle",null,null,slotProps)]}}:null],null,true)},[_vm._v(" "),_vm._t("header"),_vm._v(" "),_c(_vm.disclosureTag,{ref:"content",tag:"component",class:_vm.$options.GL_DROPDOWN_CONTENTS_CLASS,attrs:{"id":_vm.disclosureId,"aria-labelledby":_vm.listAriaLabelledBy || _vm.toggleId,"data-testid":"disclosure-content","tabindex":"-1"},on:{"keydown":_vm.onKeydown,"click":_vm.handleAutoClose}},[_vm._t("default",function(){return [_vm._l((_vm.items),function(item,index){return [(_vm.isItem(item))?[_c('gl-disclosure-dropdown-item',{key:_vm.uniqueItemId(),attrs:{"siblings-have-icons":_vm.siblingsHaveIcons,"item":item},on:{"action":_vm.handleAction},scopedSlots:_vm._u([('list-item' in _vm.$scopedSlots)?{key:"list-item",fn:function(){return [_vm._t("list-item",null,{"item":item})]},proxy:true}:null],null,true)})]:[_c('gl-disclosure-dropdown-group',{key:item.name,attrs:{"bordered":index !== 0,"group":item},on:{"action":_vm.handleAction},scopedSlots:_vm._u([(_vm.$scopedSlots['group-label'])?{key:"group-label",fn:function(){return [_vm._t("group-label",null,{"group":item})]},proxy:true}:null,(_vm.$scopedSlots['list-item'])?{key:"default",fn:function(){return _vm._l((item.items),function(groupItem){return _c('gl-disclosure-dropdown-item',{key:_vm.uniqueItemId(),attrs:{"siblings-have-icons":_vm.doSomeItemsHaveIcon(item.items),"item":groupItem},on:{"action":_vm.handleAction},scopedSlots:_vm._u([{key:"list-item",fn:function(){return [_vm._t("list-item",null,{"item":groupItem})]},proxy:true}],null,true)})})},proxy:true}:null],null,true)})]]})]})],2),_vm._v(" "),_vm._t("footer")],2)};
368
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('gl-base-dropdown',{ref:"baseDropdown",staticClass:"gl-disclosure-dropdown",attrs:{"aria-labelledby":_vm.toggleAriaLabelledBy,"aria-label":_vm.toggleAriaLabelledBy ? undefined : _vm.toggleAriaLabel,"arrow-element":_vm.$refs.disclosureArrow,"toggle-id":_vm.toggleId,"toggle-text":_vm.toggleText,"toggle-class":_vm.toggleClass,"text-sr-only":_vm.textSrOnly,"category":_vm.category,"variant":_vm.variant,"size":_vm.size,"icon":_vm.icon,"disabled":_vm.disabled,"loading":_vm.loading,"no-caret":_vm.noCaret,"placement":_vm.placement,"block":_vm.block,"offset":_vm.dropdownOffset,"fluid-width":_vm.fluidWidth,"positioning-strategy":_vm.positioningStrategy,"is-disclosure":""},on:_vm._d({},[_vm.$options.events.GL_DROPDOWN_SHOWN,_vm.onShow,_vm.$options.events.GL_DROPDOWN_HIDDEN,_vm.onHide,_vm.$options.events.GL_DROPDOWN_BEFORE_CLOSE,_vm.onBeforeClose,_vm.$options.events.GL_DROPDOWN_FOCUS_CONTENT,_vm.onKeydown]),scopedSlots:_vm._u([(_vm.hasCustomToggle)?{key:"toggle",fn:function(slotProps){return [_vm._t("toggle",null,null,slotProps)]}}:null],null,true)},[_vm._v(" "),_vm._t("header"),_vm._v(" "),_c(_vm.disclosureTag,{ref:"content",tag:"component",class:_vm.$options.GL_DROPDOWN_CONTENTS_CLASS,attrs:{"id":_vm.disclosureId,"aria-labelledby":_vm.listAriaLabelledBy || _vm.toggleId,"data-testid":"disclosure-content","tabindex":"-1"},on:{"keydown":_vm.onKeydown,"click":_vm.handleAutoClose}},[_vm._t("default",function(){return [_vm._l((_vm.items),function(item,index){return [(_vm.isItem(item))?[_c('gl-disclosure-dropdown-item',{key:_vm.uniqueItemId(),attrs:{"siblings-have-icons":_vm.siblingsHaveIcons,"item":item},on:{"action":_vm.handleAction},scopedSlots:_vm._u([('list-item' in _vm.$scopedSlots)?{key:"list-item",fn:function(){return [_vm._t("list-item",null,{"item":item})]},proxy:true}:null],null,true)})]:[_c('gl-disclosure-dropdown-group',{key:item.name,attrs:{"bordered":index !== 0,"group":item},on:{"action":_vm.handleAction},scopedSlots:_vm._u([(_vm.$scopedSlots['group-label'])?{key:"group-label",fn:function(){return [_vm._t("group-label",null,{"group":item})]},proxy:true}:null,(_vm.$scopedSlots['list-item'])?{key:"default",fn:function(){return _vm._l((item.items),function(groupItem){return _c('gl-disclosure-dropdown-item',{key:_vm.uniqueItemId(),attrs:{"siblings-have-icons":_vm.doSomeItemsHaveIcon(item.items),"item":groupItem},on:{"action":_vm.handleAction},scopedSlots:_vm._u([{key:"list-item",fn:function(){return [_vm._t("list-item",null,{"item":groupItem})]},proxy:true}],null,true)})})},proxy:true}:null],null,true)})]]})]})],2),_vm._v(" "),_vm._t("footer")],2)};
353
369
  var __vue_staticRenderFns__ = [];
354
370
 
355
371
  /* style */
@@ -0,0 +1,66 @@
1
+ import Vue from 'vue';
2
+ import { createNewChildComponent } from '../../../vendor/bootstrap-vue/src/utils/create-new-child-component';
3
+ import GlToaster from './toaster';
4
+
5
+ /* eslint-disable import/no-default-export */
6
+ let toastsCount = 0;
7
+ let toasterInstance = null;
8
+ function ensureToaster(vm) {
9
+ if (toasterInstance) {
10
+ const portalTarget = document.getElementById('gl-toaster');
11
+ if (portalTarget && document.body.contains(portalTarget)) {
12
+ return toasterInstance;
13
+ }
14
+ toasterInstance.$destroy();
15
+ toasterInstance = null;
16
+ }
17
+ const ToasterComponent = Vue.extend(GlToaster);
18
+ toasterInstance = createNewChildComponent(vm, ToasterComponent);
19
+ toasterInstance.$mount(document.createElement('div'));
20
+ return toasterInstance;
21
+ }
22
+ function showToast(message) {
23
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
24
+ const toaster = ensureToaster(this);
25
+
26
+ // eslint-disable-next-line @gitlab/tailwind-no-interpolation -- Not a CSS utility
27
+ const id = `gl-toast-${toastsCount}`;
28
+ toastsCount += 1;
29
+ const hide = () => toaster.hideToast(id);
30
+ const toast = {
31
+ id,
32
+ hide
33
+ };
34
+ const autoHideDelay = !Number.isNaN(options === null || options === void 0 ? void 0 : options.autoHideDelay) ? options.autoHideDelay : undefined;
35
+ toaster.addToast({
36
+ id,
37
+ message,
38
+ action: options.action || null,
39
+ autoHideDelay,
40
+ onComplete: options.onComplete || null
41
+ });
42
+ return toast;
43
+ }
44
+
45
+ /**
46
+ * Note: This is not a typical Vue component and needs to be registered before instantiating a Vue app.
47
+ * Once registered, the toast will be globally available throughout your app.
48
+ *
49
+ * See https://design.gitlab.com/storybook for detailed documentation.
50
+ */
51
+ var index = {
52
+ install(V) {
53
+ V.mixin({
54
+ beforeCreate() {
55
+ if (this.$toast) {
56
+ return;
57
+ }
58
+ this.$toast = {
59
+ show: showToast.bind(this)
60
+ };
61
+ }
62
+ });
63
+ }
64
+ };
65
+
66
+ export { index as default };
@@ -1,97 +1,125 @@
1
- import { isFunction } from 'lodash-es';
2
- import { ToastPlugin } from '../../../vendor/bootstrap-vue/src/components/toast/index';
3
1
  import CloseButton from '../../shared_components/close_button/close_button';
2
+ import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
4
3
 
5
- /* eslint-disable import/no-default-export */
6
- const DEFAULT_OPTIONS = {
7
- autoHideDelay: 5000,
8
- toastClass: 'gl-toast',
9
- isStatus: true,
10
- toaster: 'b-toaster-bottom-left',
11
- appendToast: true
12
- };
13
- let toastsCount = 0;
14
- function renderTitle(toast, options) {
15
- return h => {
16
- const nodes = [h(CloseButton, {
17
- class: ['gl-toast-close-button'],
18
- on: {
19
- click: toast.hide
20
- }
21
- })];
22
- if (options.action) {
23
- const {
24
- onClick,
25
- text,
26
- href
27
- } = options.action;
28
- nodes.unshift(h('a', {
29
- attrs: {
30
- role: href ? undefined : 'button',
31
- href
32
- },
33
- class: ['gl-toast-action'],
34
- on: {
35
- click: e => onClick(e, toast)
36
- }
37
- }, text));
4
+ const MIN_DURATION = 1000;
5
+ const DEFAULT_AUTO_HIDE_DELAY = 5000;
6
+ const hasAnimateSupport = typeof Element !== 'undefined' && Boolean(Element.prototype.animate);
7
+ var script = {
8
+ name: 'GlToast',
9
+ components: {
10
+ CloseButton
11
+ },
12
+ props: {
13
+ toastId: {
14
+ type: String,
15
+ required: true
16
+ },
17
+ message: {
18
+ type: String,
19
+ required: true
20
+ },
21
+ action: {
22
+ type: Object,
23
+ required: false,
24
+ default: null
25
+ },
26
+ autoHideDelay: {
27
+ type: Number,
28
+ required: false,
29
+ default: DEFAULT_AUTO_HIDE_DELAY
38
30
  }
39
- return nodes;
40
- };
41
- }
42
- function showToast(message) {
43
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
44
- // eslint-disable-next-line @gitlab/tailwind-no-interpolation -- Not a CSS utility
45
- const id = `gl-toast-${toastsCount}`;
46
- toastsCount += 1;
47
- const hide = () => {
48
- this.$bvToast.hide(id);
49
- };
50
- const toast = {
51
- id,
52
- hide
53
- };
54
- if (isFunction(options.onComplete)) {
55
- const toastHiddenCallback = e => {
56
- if (e.componentId === id) {
57
- this.$root.$off('bv::toast:hidden', toastHiddenCallback);
58
- options.onComplete(e);
59
- }
31
+ },
32
+ data() {
33
+ return {
34
+ visible: true
60
35
  };
61
- this.$root.$on('bv::toast:hidden', toastHiddenCallback);
62
- }
63
- const updatedAutoHideDelay = !Number.isNaN(options === null || options === void 0 ? void 0 : options.autoHideDelay) ? {
64
- autoHideDelay: options.autoHideDelay
65
- } : null;
66
- this.$bvToast.toast(message, {
67
- ...DEFAULT_OPTIONS,
68
- ...updatedAutoHideDelay,
69
- id,
70
- title: renderTitle(toast, options)
71
- });
72
- return toast;
73
- }
74
-
75
- /**
76
- * Note: This is not a typical Vue component and needs to be registered before instantiating a Vue app.
77
- * Once registered, the toast will be globally available throughout your app.
78
- *
79
- * See https://design.gitlab.com/storybook for detailed documentation.
80
- */
81
- var toast = {
82
- install(Vue) {
83
- Vue.use(ToastPlugin);
84
- Vue.mixin({
85
- beforeCreate() {
86
- if (this.$toast) {
87
- return;
88
- }
89
- this.$toast = {
90
- show: showToast.bind(this)
91
- };
36
+ },
37
+ computed: {
38
+ effectiveDelay() {
39
+ return Math.max(this.autoHideDelay, MIN_DURATION);
40
+ }
41
+ },
42
+ created() {
43
+ this.useCssTransition = hasAnimateSupport;
44
+ this.dismissTimer = null;
45
+ this.deadline = 0;
46
+ this.timeRemaining = this.effectiveDelay;
47
+ this.isHiding = false;
48
+ },
49
+ beforeDestroy() {
50
+ clearTimeout(this.dismissTimer);
51
+ },
52
+ methods: {
53
+ startDismissTimer() {
54
+ clearTimeout(this.dismissTimer);
55
+ this.deadline = Date.now() + this.timeRemaining;
56
+ this.dismissTimer = setTimeout(() => this.hide(), this.timeRemaining);
57
+ },
58
+ onPause() {
59
+ if (!this.dismissTimer) return;
60
+ clearTimeout(this.dismissTimer);
61
+ this.dismissTimer = null;
62
+ this.timeRemaining = Math.max(this.deadline - Date.now(), MIN_DURATION);
63
+ },
64
+ onResume() {
65
+ if (!this.timeRemaining || this.dismissTimer) return;
66
+ this.startDismissTimer();
67
+ },
68
+ hide() {
69
+ if (this.isHiding) return;
70
+ this.isHiding = true;
71
+ clearTimeout(this.dismissTimer);
72
+ this.dismissTimer = null;
73
+ this.visible = false;
74
+ },
75
+ onAfterLeave() {
76
+ this.$emit('hidden', this.toastId);
77
+ },
78
+ onActionClick(e) {
79
+ if (this.action && this.action.onClick) {
80
+ this.action.onClick(e, {
81
+ id: this.toastId,
82
+ hide: () => this.hide()
83
+ });
92
84
  }
93
- });
85
+ }
94
86
  }
95
87
  };
96
88
 
97
- export { toast as default };
89
+ /* script */
90
+ const __vue_script__ = script;
91
+
92
+ /* template */
93
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"b-toast b-toast-append",attrs:{"id":(_vm.toastId + "_toast_outer"),"role":"status","aria-live":"polite","aria-atomic":"true"}},[_c('transition',{attrs:{"enter-active-class":"fade","enter-to-class":"show","leave-class":"show","leave-active-class":"fade","appear":"","appear-active-class":"fade","appear-to-class":"show","css":_vm.useCssTransition},on:{"after-appear":_vm.startDismissTimer,"after-leave":_vm.onAfterLeave}},[(_vm.visible)?_c('div',{staticClass:"toast gl-toast",attrs:{"id":_vm.toastId,"tabindex":"0"},on:{"mouseenter":_vm.onPause,"mouseleave":_vm.onResume}},[_c('div',{staticClass:"toast-body"},[_vm._v(_vm._s(_vm.message))]),_vm._v(" "),_c('header',{staticClass:"toast-header"},[(_vm.action)?_c('a',{staticClass:"gl-toast-action",attrs:{"role":_vm.action.href ? undefined : 'button',"href":_vm.action.href},on:{"click":_vm.onActionClick}},[_vm._v(_vm._s(_vm.action.text))]):_vm._e(),_vm._v(" "),_c('close-button',{staticClass:"gl-toast-close-button",on:{"click":_vm.hide}})],1)]):_vm._e()])],1)};
94
+ var __vue_staticRenderFns__ = [];
95
+
96
+ /* style */
97
+ const __vue_inject_styles__ = undefined;
98
+ /* scoped */
99
+ const __vue_scope_id__ = undefined;
100
+ /* module identifier */
101
+ const __vue_module_identifier__ = undefined;
102
+ /* functional template */
103
+ const __vue_is_functional_template__ = false;
104
+ /* style inject */
105
+
106
+ /* style inject SSR */
107
+
108
+ /* style inject shadow dom */
109
+
110
+
111
+
112
+ const __vue_component__ = /*#__PURE__*/__vue_normalize__(
113
+ { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
114
+ __vue_inject_styles__,
115
+ __vue_script__,
116
+ __vue_scope_id__,
117
+ __vue_is_functional_template__,
118
+ __vue_module_identifier__,
119
+ false,
120
+ undefined,
121
+ undefined,
122
+ undefined
123
+ );
124
+
125
+ export { __vue_component__ as default };
@@ -0,0 +1,87 @@
1
+ import { MountingPortal } from 'portal-vue';
2
+ import GlToast from './toast';
3
+ import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
4
+
5
+ const hasViewTransitions = typeof document !== 'undefined' && typeof document.startViewTransition === 'function';
6
+ var script = {
7
+ name: 'GlToaster',
8
+ components: {
9
+ MountingPortal,
10
+ GlToast
11
+ },
12
+ expose: ['addToast', 'hideToast', 'removeToast'],
13
+ data() {
14
+ return {
15
+ toasts: []
16
+ };
17
+ },
18
+ methods: {
19
+ addToast(config) {
20
+ const add = () => this.toasts.push(config);
21
+ if (hasViewTransitions && this.toasts.length > 0) {
22
+ document.startViewTransition(add);
23
+ } else {
24
+ add();
25
+ }
26
+ },
27
+ hideToast(id) {
28
+ const refs = this.$refs.toastRefs;
29
+ if (!refs) return;
30
+ const toastComponents = Array.isArray(refs) ? refs : [refs];
31
+ const component = toastComponents.find(c => c.toastId === id);
32
+ if (component) {
33
+ component.hide();
34
+ }
35
+ },
36
+ removeToast(id) {
37
+ const idx = this.toasts.findIndex(t => t.id === id);
38
+ if (idx !== -1) {
39
+ const toast = this.toasts[idx];
40
+ this.toasts.splice(idx, 1);
41
+ if (toast.onComplete) {
42
+ toast.onComplete({
43
+ componentId: id
44
+ });
45
+ }
46
+ }
47
+ }
48
+ }
49
+ };
50
+
51
+ /* script */
52
+ const __vue_script__ = script;
53
+
54
+ /* template */
55
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('mounting-portal',{attrs:{"mount-to":"body","append":""}},[_c('div',{staticClass:"b-toaster b-toaster-bottom-left",attrs:{"id":"gl-toaster"}},[_c('div',{staticClass:"b-toaster-slot"},_vm._l((_vm.toasts),function(toast){return _c('gl-toast',{key:toast.id,ref:"toastRefs",refInFor:true,attrs:{"toast-id":toast.id,"message":toast.message,"action":toast.action,"auto-hide-delay":toast.autoHideDelay},on:{"hidden":_vm.removeToast}})}),1)])])};
56
+ var __vue_staticRenderFns__ = [];
57
+
58
+ /* style */
59
+ const __vue_inject_styles__ = undefined;
60
+ /* scoped */
61
+ const __vue_scope_id__ = undefined;
62
+ /* module identifier */
63
+ const __vue_module_identifier__ = undefined;
64
+ /* functional template */
65
+ const __vue_is_functional_template__ = false;
66
+ /* style inject */
67
+
68
+ /* style inject SSR */
69
+
70
+ /* style inject shadow dom */
71
+
72
+
73
+
74
+ const __vue_component__ = /*#__PURE__*/__vue_normalize__(
75
+ { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
76
+ __vue_inject_styles__,
77
+ __vue_script__,
78
+ __vue_scope_id__,
79
+ __vue_is_functional_template__,
80
+ __vue_module_identifier__,
81
+ false,
82
+ undefined,
83
+ undefined,
84
+ undefined
85
+ );
86
+
87
+ export { __vue_component__ as default };
@@ -3,6 +3,7 @@ import GlBadge from '../../base/badge/badge';
3
3
  import GlIcon from '../../base/icon/icon';
4
4
  import GlAnimatedNumber from '../../utilities/animated_number/animated_number';
5
5
  import { formatNumberToLocale } from '../../../utils/number_utils';
6
+ import { GlTooltipDirective } from '../../../directives/tooltip/tooltip';
6
7
  import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
7
8
 
8
9
  var script = {
@@ -12,6 +13,9 @@ var script = {
12
13
  GlBadge,
13
14
  GlAnimatedNumber
14
15
  },
16
+ directives: {
17
+ GlTooltip: GlTooltipDirective
18
+ },
15
19
  props: {
16
20
  title: {
17
21
  type: String,
@@ -63,6 +67,14 @@ var script = {
63
67
  required: false,
64
68
  default: null
65
69
  },
70
+ /**
71
+ * Tooltip text for the meta badge. When provided, the badge is wrapped in a button to ensure keyboard accessibility.
72
+ */
73
+ metaTooltip: {
74
+ type: String,
75
+ required: false,
76
+ default: ''
77
+ },
66
78
  shouldAnimate: {
67
79
  type: Boolean,
68
80
  required: false,
@@ -117,7 +129,7 @@ var script = {
117
129
  const __vue_script__ = script;
118
130
 
119
131
  /* template */
120
- var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',_vm._g(_vm._b({staticClass:"gl-single-stat gl-flex gl-flex-col gl-p-2"},'div',_vm.$attrs,false),_vm.$listeners),[_c('div',{staticClass:"gl-mb-2 gl-flex gl-items-center gl-text-heading"},[(_vm.showTitleIcon)?_c('gl-icon',{class:['gl-mr-2', _vm.titleIconClass],attrs:{"name":_vm.titleIcon,"data-testid":"title-icon"}}):_vm._e(),_vm._v(" "),_c('span',{staticClass:"gl-text-base gl-font-normal",attrs:{"data-testid":"title-text"}},[_vm._v(_vm._s(_vm.title))])],1),_vm._v(" "),_c('div',{staticClass:"gl-single-stat-content gl-flex gl-items-baseline gl-font-bold gl-text-strong"},[_c('span',{staticClass:"gl-single-stat-number gl-leading-1",class:{ 'gl-mr-2': !_vm.unit },attrs:{"data-testid":"displayValue"}},[(_vm.canAnimate)?_c('gl-animated-number',{attrs:{"number":Number(_vm.value),"decimal-places":_vm.animationDecimalPlaces,"use-delimiters":_vm.useDelimiters},on:{"animating":function($event){return _vm.setHideUnits(true)},"animated":function($event){return _vm.setHideUnits(false)}}}):_c('span',{attrs:{"data-testid":"non-animated-value"}},[_vm._v(_vm._s(_vm.statValue))])],1),_vm._v(" "),(_vm.unit)?_c('span',{staticClass:"gl-mx-2 gl-text-sm gl-opacity-10 gl-transition-all",class:{ '!gl-opacity-0': _vm.hideUnits },attrs:{"data-testid":"unit"}},[_vm._v(_vm._s(_vm.unit))]):_vm._e(),_vm._v(" "),(_vm.showMetaIcon)?_c('gl-icon',{attrs:{"variant":_vm.iconVariant,"name":_vm.metaIcon,"data-testid":"meta-icon"}}):_vm._e(),_vm._v(" "),(_vm.showBadge)?_c('gl-badge',{attrs:{"variant":_vm.variant,"icon":_vm.metaIcon,"data-testid":"meta-badge"}},[_vm._v(_vm._s(_vm.metaText))]):_vm._e()],1)])};
132
+ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',_vm._g(_vm._b({staticClass:"gl-single-stat gl-flex gl-flex-col gl-p-2"},'div',_vm.$attrs,false),_vm.$listeners),[_c('div',{staticClass:"gl-mb-2 gl-flex gl-items-center gl-text-heading"},[(_vm.showTitleIcon)?_c('gl-icon',{class:['gl-mr-2', _vm.titleIconClass],attrs:{"name":_vm.titleIcon,"data-testid":"title-icon"}}):_vm._e(),_vm._v(" "),_c('span',{staticClass:"gl-text-base gl-font-normal",attrs:{"data-testid":"title-text"}},[_vm._v(_vm._s(_vm.title))])],1),_vm._v(" "),_c('div',{staticClass:"gl-single-stat-content gl-flex gl-items-baseline gl-font-bold gl-text-strong"},[_c('span',{staticClass:"gl-single-stat-number gl-leading-1",class:{ 'gl-mr-2': !_vm.unit },attrs:{"data-testid":"displayValue"}},[(_vm.canAnimate)?_c('gl-animated-number',{attrs:{"number":Number(_vm.value),"decimal-places":_vm.animationDecimalPlaces,"use-delimiters":_vm.useDelimiters},on:{"animating":function($event){return _vm.setHideUnits(true)},"animated":function($event){return _vm.setHideUnits(false)}}}):_c('span',{attrs:{"data-testid":"non-animated-value"}},[_vm._v(_vm._s(_vm.statValue))])],1),_vm._v(" "),(_vm.unit)?_c('span',{staticClass:"gl-mx-2 gl-text-sm gl-opacity-10 gl-transition-all",class:{ '!gl-opacity-0': _vm.hideUnits },attrs:{"data-testid":"unit"}},[_vm._v(_vm._s(_vm.unit))]):_vm._e(),_vm._v(" "),(_vm.showMetaIcon)?_c('gl-icon',{attrs:{"variant":_vm.iconVariant,"name":_vm.metaIcon,"data-testid":"meta-icon"}}):_vm._e(),_vm._v(" "),(_vm.showBadge && _vm.metaTooltip)?_c('button',{directives:[{name:"gl-tooltip",rawName:"v-gl-tooltip.viewport",modifiers:{"viewport":true}}],staticClass:"!gl-cursor-default gl-border-0 gl-bg-transparent gl-p-0 gl-leading-0",attrs:{"type":"button","title":_vm.metaTooltip,"data-testid":"meta-badge-button"}},[_c('gl-badge',{attrs:{"variant":_vm.variant,"icon":_vm.metaIcon,"data-testid":"meta-badge"}},[_vm._v(_vm._s(_vm.metaText))])],1):(_vm.showBadge)?_c('gl-badge',{attrs:{"variant":_vm.variant,"icon":_vm.metaIcon,"data-testid":"meta-badge"}},[_vm._v(_vm._s(_vm.metaText))]):_vm._e()],1)])};
121
133
  var __vue_staticRenderFns__ = [];
122
134
 
123
135
  /* style */
@@ -32,7 +32,7 @@ export { default as GlBadge } from './base/badge/badge';
32
32
  export { default as GlBanner } from './base/banner/banner';
33
33
  export { default as GlButton } from './base/button/button';
34
34
  export { default as GlTooltip } from './base/tooltip/tooltip';
35
- export { default as GlToast } from './base/toast/toast';
35
+ export { default as GlToast } from './base/toast';
36
36
  export { default as GlDashboardSkeleton } from './regions/dashboard_skeleton/dashboard_skeleton';
37
37
  export { default as GlEmptyState } from './regions/empty_state/empty_state';
38
38
  export { default as GlForm } from './base/form/form';