@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
@@ -1,439 +0,0 @@
1
- import { Portal, Wormhole } from 'portal-vue'
2
- import { COMPONENT_UID_KEY, extend } from '../../vue'
3
- import { NAME_TOAST, NAME_TOASTER } from '../../constants/components'
4
- import {
5
- EVENT_NAME_CHANGE,
6
- EVENT_NAME_DESTROYED,
7
- EVENT_NAME_HIDDEN,
8
- EVENT_NAME_HIDE,
9
- EVENT_NAME_SHOW,
10
- EVENT_NAME_SHOWN,
11
- EVENT_OPTIONS_NO_CAPTURE
12
- } from '../../constants/events'
13
- import {
14
- PROP_TYPE_ARRAY_OBJECT_STRING,
15
- PROP_TYPE_BOOLEAN,
16
- PROP_TYPE_NUMBER_STRING,
17
- PROP_TYPE_STRING
18
- } from '../../constants/props'
19
- import { SLOT_NAME_DEFAULT, SLOT_NAME_TOAST_TITLE } from '../../constants/slots'
20
- import { BvEvent } from '../../utils/bv-event.class'
21
- import { requestAF } from '../../utils/dom'
22
- import { getRootActionEventName, getRootEventName, eventOnOff } from '../../utils/events'
23
- import { mathMax } from '../../utils/math'
24
- import { makeModelMixin } from '../../utils/model'
25
- import { toInteger } from '../../utils/number'
26
- import { pick, sortKeys } from '../../utils/object'
27
- import { makeProp, pluckProps } from '../../utils/props'
28
- import { isLink } from '../../utils/router'
29
- import { createNewChildComponent } from '../../utils/create-new-child-component'
30
- import { attrsMixin } from '../../mixins/attrs'
31
- import { idMixin, props as idProps } from '../../mixins/id'
32
- import { listenOnRootMixin } from '../../mixins/listen-on-root'
33
- import { normalizeSlotMixin } from '../../mixins/normalize-slot'
34
- import { scopedStyleMixin } from '../../mixins/scoped-style'
35
- import { BLink, props as BLinkProps } from '../link/link'
36
- import { BVTransition } from '../transition/bv-transition'
37
- import { BToaster } from './toaster'
38
-
39
- // --- Constants ---
40
-
41
- const {
42
- mixin: modelMixin,
43
- props: modelProps,
44
- prop: MODEL_PROP_NAME,
45
- event: MODEL_EVENT_NAME
46
- } = makeModelMixin('visible', {
47
- type: PROP_TYPE_BOOLEAN,
48
- defaultValue: false,
49
- event: EVENT_NAME_CHANGE
50
- })
51
-
52
- const MIN_DURATION = 1000
53
-
54
- // --- Props ---
55
-
56
- const linkProps = pick(BLinkProps, ['href', 'to'])
57
-
58
- export const props = sortKeys({
59
- ...idProps,
60
- ...modelProps,
61
- ...linkProps,
62
- appendToast: makeProp(PROP_TYPE_BOOLEAN, false),
63
- autoHideDelay: makeProp(PROP_TYPE_NUMBER_STRING, 5000),
64
- bodyClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
65
- headerClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
66
- headerTag: makeProp(PROP_TYPE_STRING, 'header'),
67
- // Switches role to 'status' and aria-live to 'polite'
68
- isStatus: makeProp(PROP_TYPE_BOOLEAN, false),
69
- noAutoHide: makeProp(PROP_TYPE_BOOLEAN, false),
70
- noFade: makeProp(PROP_TYPE_BOOLEAN, false),
71
- noHoverPause: makeProp(PROP_TYPE_BOOLEAN, false),
72
- solid: makeProp(PROP_TYPE_BOOLEAN, false),
73
- // Render the toast in place, rather than in a portal-target
74
- static: makeProp(PROP_TYPE_BOOLEAN, false),
75
- title: makeProp(PROP_TYPE_STRING),
76
- toastClass: makeProp(PROP_TYPE_ARRAY_OBJECT_STRING),
77
- toaster: makeProp(PROP_TYPE_STRING, 'b-toaster-top-right'),
78
- variant: makeProp(PROP_TYPE_STRING)
79
- })
80
-
81
- // --- Main component ---
82
-
83
- // @vue/component
84
- export const BToast = /*#__PURE__*/ extend({
85
- name: NAME_TOAST,
86
- mixins: [
87
- attrsMixin,
88
- idMixin,
89
- modelMixin,
90
- listenOnRootMixin,
91
- normalizeSlotMixin,
92
- scopedStyleMixin
93
- ],
94
- inheritAttrs: false,
95
- props,
96
- data() {
97
- return {
98
- isMounted: false,
99
- doRender: false,
100
- localShow: false,
101
- isTransitioning: false,
102
- isHiding: false,
103
- order: 0,
104
- dismissStarted: 0,
105
- resumeDismiss: 0
106
- }
107
- },
108
- computed: {
109
- toastClasses() {
110
- const { appendToast, variant } = this
111
-
112
- return {
113
- 'b-toast-solid': this.solid,
114
- 'b-toast-append': appendToast,
115
- 'b-toast-prepend': !appendToast,
116
- [`b-toast-${variant}`]: variant
117
- }
118
- },
119
- slotScope() {
120
- const { hide } = this
121
- return { hide }
122
- },
123
- computedDuration() {
124
- // Minimum supported duration is 1 second
125
- return mathMax(toInteger(this.autoHideDelay, 0), MIN_DURATION)
126
- },
127
- computedToaster() {
128
- return String(this.toaster)
129
- },
130
- transitionHandlers() {
131
- return {
132
- beforeEnter: this.onBeforeEnter,
133
- afterEnter: this.onAfterEnter,
134
- beforeLeave: this.onBeforeLeave,
135
- afterLeave: this.onAfterLeave
136
- }
137
- },
138
- computedAttrs() {
139
- return {
140
- ...this.bvAttrs,
141
- id: this.safeId(),
142
- tabindex: '0'
143
- }
144
- }
145
- },
146
- watch: {
147
- [MODEL_PROP_NAME](newValue) {
148
- this[newValue ? 'show' : 'hide']()
149
- },
150
- localShow(newValue) {
151
- if (newValue !== this[MODEL_PROP_NAME]) {
152
- this.$emit(MODEL_EVENT_NAME, newValue)
153
- }
154
- },
155
- /* istanbul ignore next */
156
- toaster() {
157
- // If toaster target changed, make sure toaster exists
158
- this.$nextTick(this.ensureToaster)
159
- },
160
- /* istanbul ignore next */
161
- static(newValue) {
162
- // If static changes to true, and the toast is showing,
163
- // ensure the toaster target exists
164
- if (newValue && this.localShow) {
165
- this.ensureToaster()
166
- }
167
- }
168
- },
169
- created() {
170
- // Create private non-reactive props
171
- this.$_dismissTimer = null
172
- },
173
- mounted() {
174
- this.isMounted = true
175
- this.$nextTick(() => {
176
- if (this[MODEL_PROP_NAME]) {
177
- requestAF(() => {
178
- this.show()
179
- })
180
- }
181
- })
182
- // Listen for global $root show events
183
- this.listenOnRoot(getRootActionEventName(NAME_TOAST, EVENT_NAME_SHOW), id => {
184
- if (id === this.safeId()) {
185
- this.show()
186
- }
187
- })
188
- // Listen for global $root hide events
189
- this.listenOnRoot(getRootActionEventName(NAME_TOAST, EVENT_NAME_HIDE), id => {
190
- if (!id || id === this.safeId()) {
191
- this.hide()
192
- }
193
- })
194
- // Make sure we hide when toaster is destroyed
195
- /* istanbul ignore next: difficult to test */
196
- this.listenOnRoot(getRootEventName(NAME_TOASTER, EVENT_NAME_DESTROYED), toaster => {
197
- /* istanbul ignore next */
198
- if (toaster === this.computedToaster) {
199
- this.hide()
200
- }
201
- })
202
- },
203
- beforeDestroy() {
204
- this.clearDismissTimer()
205
- },
206
- methods: {
207
- show() {
208
- if (!this.localShow) {
209
- this.ensureToaster()
210
- const showEvent = this.buildEvent(EVENT_NAME_SHOW)
211
- this.emitEvent(showEvent)
212
- this.dismissStarted = this.resumeDismiss = 0
213
- this.order = Date.now() * (this.appendToast ? 1 : -1)
214
- this.isHiding = false
215
- this.doRender = true
216
- this.$nextTick(() => {
217
- // We show the toast after we have rendered the portal and b-toast wrapper
218
- // so that screen readers will properly announce the toast
219
- requestAF(() => {
220
- this.localShow = true
221
- })
222
- })
223
- }
224
- },
225
- hide() {
226
- if (this.localShow) {
227
- const hideEvent = this.buildEvent(EVENT_NAME_HIDE)
228
- this.emitEvent(hideEvent)
229
- this.setHoverHandler(false)
230
- this.dismissStarted = this.resumeDismiss = 0
231
- this.clearDismissTimer()
232
- this.isHiding = true
233
- requestAF(() => {
234
- this.localShow = false
235
- })
236
- }
237
- },
238
- buildEvent(type, options = {}) {
239
- return new BvEvent(type, {
240
- cancelable: false,
241
- target: this.$el || null,
242
- relatedTarget: null,
243
- ...options,
244
- vueTarget: this,
245
- componentId: this.safeId()
246
- })
247
- },
248
- emitEvent(bvEvent) {
249
- const { type } = bvEvent
250
- this.emitOnRoot(getRootEventName(NAME_TOAST, type), bvEvent)
251
- this.$emit(type, bvEvent)
252
- },
253
- ensureToaster() {
254
- if (this.static) {
255
- return
256
- }
257
-
258
- const { computedToaster } = this
259
- const hasTarget = Wormhole.hasTarget(computedToaster)
260
- const hasDOM = document.getElementById(computedToaster)
261
- if (!hasTarget || !hasDOM) {
262
- if (hasTarget && !hasDOM) {
263
- Wormhole.unregisterTarget(computedToaster)
264
- }
265
- const div = document.createElement('div')
266
- document.body.appendChild(div)
267
-
268
- const toaster = createNewChildComponent(this.bvEventRoot, BToaster, {
269
- propsData: { name: computedToaster }
270
- })
271
-
272
- toaster.$mount(div)
273
- }
274
- },
275
- startDismissTimer() {
276
- this.clearDismissTimer()
277
- if (!this.noAutoHide) {
278
- this.$_dismissTimer = setTimeout(this.hide, this.resumeDismiss || this.computedDuration)
279
- this.dismissStarted = Date.now()
280
- this.resumeDismiss = 0
281
- }
282
- },
283
- clearDismissTimer() {
284
- clearTimeout(this.$_dismissTimer)
285
- this.$_dismissTimer = null
286
- },
287
- setHoverHandler(on) {
288
- const el = this.$refs['b-toast']
289
- eventOnOff(on, el, 'mouseenter', this.onPause, EVENT_OPTIONS_NO_CAPTURE)
290
- eventOnOff(on, el, 'mouseleave', this.onUnPause, EVENT_OPTIONS_NO_CAPTURE)
291
- },
292
- onPause() {
293
- // Determine time remaining, and then pause timer
294
- if (this.noAutoHide || this.noHoverPause || !this.$_dismissTimer || this.resumeDismiss) {
295
- return
296
- }
297
- const passed = Date.now() - this.dismissStarted
298
- if (passed > 0) {
299
- this.clearDismissTimer()
300
- this.resumeDismiss = mathMax(this.computedDuration - passed, MIN_DURATION)
301
- }
302
- },
303
- onUnPause() {
304
- // Restart timer with max of time remaining or 1 second
305
- if (this.noAutoHide || this.noHoverPause || !this.resumeDismiss) {
306
- this.resumeDismiss = this.dismissStarted = 0
307
- return
308
- }
309
- this.startDismissTimer()
310
- },
311
- onLinkClick() {
312
- // We delay the close to allow time for the
313
- // browser to process the link click
314
- this.$nextTick(() => {
315
- requestAF(() => {
316
- this.hide()
317
- })
318
- })
319
- },
320
- onBeforeEnter() {
321
- this.isTransitioning = true
322
- },
323
- onAfterEnter() {
324
- this.isTransitioning = false
325
- const hiddenEvent = this.buildEvent(EVENT_NAME_SHOWN)
326
- this.emitEvent(hiddenEvent)
327
- this.startDismissTimer()
328
- this.setHoverHandler(true)
329
- },
330
- onBeforeLeave() {
331
- this.isTransitioning = true
332
- },
333
- onAfterLeave() {
334
- this.isTransitioning = false
335
- this.order = 0
336
- this.resumeDismiss = this.dismissStarted = 0
337
- const hiddenEvent = this.buildEvent(EVENT_NAME_HIDDEN)
338
- this.emitEvent(hiddenEvent)
339
- this.doRender = false
340
- },
341
- // Render helper for generating the toast
342
- makeToast(h) {
343
- const { slotScope } = this
344
- const link = isLink(this)
345
- const $headerContent = []
346
-
347
- const $title = this.normalizeSlot(SLOT_NAME_TOAST_TITLE, slotScope)
348
- if ($title) {
349
- $headerContent.push($title)
350
- }
351
-
352
- let $header = h()
353
- if ($headerContent.length > 0) {
354
- $header = h(
355
- this.headerTag,
356
- {
357
- staticClass: 'toast-header',
358
- class: this.headerClass
359
- },
360
- $headerContent
361
- )
362
- }
363
-
364
- const $body = h(
365
- link ? BLink : 'div',
366
- {
367
- staticClass: 'toast-body',
368
- class: this.bodyClass,
369
- props: link ? pluckProps(linkProps, this) : {},
370
- on: link ? { click: this.onLinkClick } : {}
371
- },
372
- this.normalizeSlot(SLOT_NAME_DEFAULT, slotScope)
373
- )
374
-
375
- return h(
376
- 'div',
377
- {
378
- staticClass: 'toast',
379
- class: this.toastClass,
380
- attrs: this.computedAttrs,
381
- key: `toast-${this[COMPONENT_UID_KEY]}`,
382
- ref: 'toast'
383
- },
384
- [$header, $body]
385
- )
386
- }
387
- },
388
- render(h) {
389
- if (!this.doRender || !this.isMounted) {
390
- return h()
391
- }
392
-
393
- const { order, static: isStatic, isHiding, isStatus } = this
394
- const name = `b-toast-${this[COMPONENT_UID_KEY]}`
395
-
396
- const $toast = h(
397
- 'div',
398
- {
399
- staticClass: 'b-toast',
400
- class: this.toastClasses,
401
- attrs: {
402
- // If scoped styles are applied and the toast is not static,
403
- // make sure the scoped style data attribute is applied
404
- ...(isStatic ? {} : this.scopedStyleAttrs),
405
- id: this.safeId('_toast_outer'),
406
- role: isHiding ? null : isStatus ? 'status' : 'alert',
407
- 'aria-live': isHiding ? null : isStatus ? 'polite' : 'assertive',
408
- 'aria-atomic': isHiding ? null : 'true'
409
- },
410
- key: name,
411
- ref: 'b-toast'
412
- },
413
- [
414
- h(
415
- BVTransition,
416
- {
417
- props: { noFade: this.noFade },
418
- on: this.transitionHandlers
419
- },
420
- [this.localShow ? this.makeToast(h) : h()]
421
- )
422
- ]
423
- )
424
-
425
- return h(
426
- Portal,
427
- {
428
- props: {
429
- name,
430
- to: this.computedToaster,
431
- order,
432
- slim: true,
433
- disabled: isStatic
434
- }
435
- },
436
- [$toast]
437
- )
438
- }
439
- })
@@ -1,136 +0,0 @@
1
- import { PortalTarget, Wormhole } from 'portal-vue'
2
- import { extend } from '../../vue'
3
- import { NAME_TOASTER } from '../../constants/components'
4
- import { EVENT_NAME_DESTROYED } from '../../constants/events'
5
- import { PROP_TYPE_STRING } from '../../constants/props'
6
- import { removeClass, requestAF } from '../../utils/dom'
7
- import { getRootEventName } from '../../utils/events'
8
- import { makeProp } from '../../utils/props'
9
- import { warn } from '../../utils/warn'
10
- import { listenOnRootMixin } from '../../mixins/listen-on-root'
11
- import { normalizeSlotMixin } from '../../mixins/normalize-slot'
12
-
13
- // --- Helper components ---
14
-
15
- // @vue/component
16
- export const DefaultTransition = /*#__PURE__*/ extend({
17
- mixins: [normalizeSlotMixin],
18
- data() {
19
- return {
20
- // Transition classes base name
21
- name: 'b-toaster'
22
- }
23
- },
24
- methods: {
25
- onAfterEnter(el) {
26
- // Work around a Vue.js bug where `*-enter-to` class is not removed
27
- // See: https://github.com/vuejs/vue/pull/7901
28
- // The `*-move` class is also stuck on elements that moved,
29
- // but there are no JavaScript hooks to handle after move
30
- // See: https://github.com/vuejs/vue/pull/7906
31
- requestAF(() => {
32
- removeClass(el, `${this.name}-enter-to`)
33
- })
34
- }
35
- },
36
- render(h) {
37
- return h(
38
- 'transition-group',
39
- {
40
- props: { tag: 'div', name: this.name },
41
- on: { afterEnter: this.onAfterEnter }
42
- },
43
- this.normalizeSlot()
44
- )
45
- }
46
- })
47
-
48
- // --- Props ---
49
-
50
- export const props = {
51
- // Allowed: 'true' or 'false' or `null`
52
- ariaAtomic: makeProp(PROP_TYPE_STRING),
53
- ariaLive: makeProp(PROP_TYPE_STRING),
54
- name: makeProp(PROP_TYPE_STRING, undefined, true), // Required
55
- // Aria role
56
- role: makeProp(PROP_TYPE_STRING)
57
- }
58
-
59
- // --- Main component ---
60
-
61
- // @vue/component
62
- export const BToaster = /*#__PURE__*/ extend({
63
- name: NAME_TOASTER,
64
- mixins: [listenOnRootMixin],
65
- props,
66
- data() {
67
- return {
68
- // We don't render on SSR or if a an existing target found
69
- doRender: false,
70
- dead: false,
71
- // Toaster names cannot change once created
72
- staticName: this.name
73
- }
74
- },
75
- beforeMount() {
76
- const { name } = this
77
- this.staticName = name
78
-
79
- /* istanbul ignore if */
80
- if (Wormhole.hasTarget(name)) {
81
- warn(`A "<portal-target>" with name "${name}" already exists in the document.`, NAME_TOASTER)
82
- this.dead = true
83
- } else {
84
- this.doRender = true
85
- }
86
- },
87
- beforeDestroy() {
88
- // Let toasts made with `this.$bvToast.toast()` know that this toaster
89
- // is being destroyed and should should also destroy/hide themselves
90
- if (this.doRender) {
91
- this.emitOnRoot(getRootEventName(NAME_TOASTER, EVENT_NAME_DESTROYED), this.name)
92
- }
93
- },
94
- destroyed() {
95
- // Remove from DOM if needed
96
- const { $el } = this
97
- /* istanbul ignore next: difficult to test */
98
- if ($el && $el.parentNode) {
99
- $el.parentNode.removeChild($el)
100
- }
101
- },
102
- render(h) {
103
- let $toaster = h('div', { class: ['gl-hidden', { 'b-dead-toaster': this.dead }] })
104
- if (this.doRender) {
105
- const $target = h(PortalTarget, {
106
- staticClass: 'b-toaster-slot',
107
- props: {
108
- name: this.staticName,
109
- multiple: true,
110
- tag: 'div',
111
- slim: false,
112
- // transition: this.transition || DefaultTransition
113
- transition: DefaultTransition
114
- }
115
- })
116
-
117
- $toaster = h(
118
- 'div',
119
- {
120
- staticClass: 'b-toaster',
121
- class: [this.staticName],
122
- attrs: {
123
- id: this.staticName,
124
- // Fallback to null to make sure attribute doesn't exist
125
- role: this.role || null,
126
- 'aria-live': this.ariaLive,
127
- 'aria-atomic': this.ariaAtomic
128
- }
129
- },
130
- [$target]
131
- )
132
- }
133
-
134
- return $toaster
135
- }
136
- })