@gitlab/ui 88.6.0 → 89.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 (36) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/index.css +1 -1
  3. package/dist/index.css.map +1 -1
  4. package/dist/index.js +0 -2
  5. package/dist/vendor/bootstrap-vue/src/components/index.js +0 -2
  6. package/dist/vendor/bootstrap-vue/src/components/tooltip/helpers/bv-tooltip.js +1 -1
  7. package/dist/vendor/bootstrap-vue/src/constants/components.js +1 -3
  8. package/dist/vendor/bootstrap-vue/src/index.js +0 -3
  9. package/package.json +1 -1
  10. package/src/index.js +0 -2
  11. package/src/scss/bootstrap.scss +0 -1
  12. package/src/scss/components.scss +0 -1
  13. package/src/vendor/bootstrap-vue/nuxt/index.js +0 -1
  14. package/src/vendor/bootstrap-vue/package.json +0 -1
  15. package/src/vendor/bootstrap-vue/src/components/index.d.ts +0 -1
  16. package/src/vendor/bootstrap-vue/src/components/index.js +0 -2
  17. package/src/vendor/bootstrap-vue/src/components/tooltip/helpers/bv-tooltip.js +1 -1
  18. package/src/vendor/bootstrap-vue/src/constants/components.js +0 -2
  19. package/src/vendor/bootstrap-vue/src/index.js +0 -5
  20. package/dist/components/base/carousel/carousel.js +0 -48
  21. package/dist/components/base/carousel/carousel_slide.js +0 -47
  22. package/dist/vendor/bootstrap-vue/src/components/carousel/carousel-slide.js +0 -123
  23. package/dist/vendor/bootstrap-vue/src/components/carousel/carousel.js +0 -617
  24. package/dist/vendor/bootstrap-vue/src/components/carousel/index.js +0 -14
  25. package/src/components/base/carousel/carousel.md +0 -3
  26. package/src/components/base/carousel/carousel.scss +0 -29
  27. package/src/components/base/carousel/carousel.vue +0 -19
  28. package/src/components/base/carousel/carousel_slide.vue +0 -18
  29. package/src/vendor/bootstrap-vue/src/components/carousel/README.md +0 -320
  30. package/src/vendor/bootstrap-vue/src/components/carousel/carousel-slide.js +0 -132
  31. package/src/vendor/bootstrap-vue/src/components/carousel/carousel-slide.spec.js +0 -276
  32. package/src/vendor/bootstrap-vue/src/components/carousel/carousel.js +0 -655
  33. package/src/vendor/bootstrap-vue/src/components/carousel/carousel.spec.js +0 -1069
  34. package/src/vendor/bootstrap-vue/src/components/carousel/index.d.ts +0 -20
  35. package/src/vendor/bootstrap-vue/src/components/carousel/index.js +0 -12
  36. package/src/vendor/bootstrap-vue/src/components/carousel/package.json +0 -185
@@ -1,655 +0,0 @@
1
- import { extend } from '../../vue'
2
- import { NAME_CAROUSEL } from '../../constants/components'
3
- import { IS_BROWSER, HAS_POINTER_EVENT_SUPPORT, HAS_TOUCH_SUPPORT } from '../../constants/env'
4
- import {
5
- EVENT_NAME_PAUSED,
6
- EVENT_NAME_SLIDING_END,
7
- EVENT_NAME_SLIDING_START,
8
- EVENT_NAME_UNPAUSED,
9
- EVENT_OPTIONS_NO_CAPTURE
10
- } from '../../constants/events'
11
- import { CODE_ENTER, CODE_LEFT, CODE_RIGHT, CODE_SPACE } from '../../constants/key-codes'
12
- import {
13
- PROP_TYPE_BOOLEAN,
14
- PROP_TYPE_NUMBER,
15
- PROP_TYPE_NUMBER_STRING,
16
- PROP_TYPE_STRING
17
- } from '../../constants/props'
18
- import {
19
- addClass,
20
- getActiveElement,
21
- reflow,
22
- removeClass,
23
- requestAF,
24
- selectAll,
25
- setAttr
26
- } from '../../utils/dom'
27
- import { eventOn, eventOff, stopEvent } from '../../utils/events'
28
- import { isUndefined } from '../../utils/inspect'
29
- import { mathAbs, mathFloor, mathMax, mathMin } from '../../utils/math'
30
- import { makeModelMixin } from '../../utils/model'
31
- import { toInteger } from '../../utils/number'
32
- import { noop } from '../../utils/noop'
33
- import { sortKeys } from '../../utils/object'
34
- import { observeDom } from '../../utils/observe-dom'
35
- import { makeProp, makePropsConfigurable } from '../../utils/props'
36
- import { idMixin, props as idProps } from '../../mixins/id'
37
- import { normalizeSlotMixin } from '../../mixins/normalize-slot'
38
-
39
- // --- Constants ---
40
-
41
- const {
42
- mixin: modelMixin,
43
- props: modelProps,
44
- prop: MODEL_PROP_NAME,
45
- event: MODEL_EVENT_NAME
46
- } = makeModelMixin('value', {
47
- type: PROP_TYPE_NUMBER,
48
- defaultValue: 0
49
- })
50
-
51
- // Slide directional classes
52
- const DIRECTION = {
53
- next: {
54
- dirClass: 'carousel-item-left',
55
- overlayClass: 'carousel-item-next'
56
- },
57
- prev: {
58
- dirClass: 'carousel-item-right',
59
- overlayClass: 'carousel-item-prev'
60
- }
61
- }
62
-
63
- // Fallback Transition duration (with a little buffer) in ms
64
- const TRANS_DURATION = 600 + 50
65
-
66
- // Time for mouse compat events to fire after touch
67
- const TOUCH_EVENT_COMPAT_WAIT = 500
68
-
69
- // Number of pixels to consider touch move a swipe
70
- const SWIPE_THRESHOLD = 40
71
-
72
- // PointerEvent pointer types
73
- const PointerType = {
74
- TOUCH: 'touch',
75
- PEN: 'pen'
76
- }
77
-
78
- // Transition Event names
79
- const TransitionEndEvents = {
80
- WebkitTransition: 'webkitTransitionEnd',
81
- MozTransition: 'transitionend',
82
- OTransition: 'otransitionend oTransitionEnd',
83
- transition: 'transitionend'
84
- }
85
-
86
- // --- Helper methods ---
87
-
88
- // Return the browser specific transitionEnd event name
89
- const getTransitionEndEvent = el => {
90
- for (const name in TransitionEndEvents) {
91
- if (!isUndefined(el.style[name])) {
92
- return TransitionEndEvents[name]
93
- }
94
- }
95
- // Fallback
96
- /* istanbul ignore next */
97
- return null
98
- }
99
-
100
- // --- Props ---
101
-
102
- export const props = makePropsConfigurable(
103
- sortKeys({
104
- ...idProps,
105
- ...modelProps,
106
- background: makeProp(PROP_TYPE_STRING),
107
- controls: makeProp(PROP_TYPE_BOOLEAN, false),
108
- // Enable cross-fade animation instead of slide animation
109
- fade: makeProp(PROP_TYPE_BOOLEAN, false),
110
- // Sniffed by carousel-slide
111
- imgHeight: makeProp(PROP_TYPE_NUMBER_STRING),
112
- // Sniffed by carousel-slide
113
- imgWidth: makeProp(PROP_TYPE_NUMBER_STRING),
114
- indicators: makeProp(PROP_TYPE_BOOLEAN, false),
115
- interval: makeProp(PROP_TYPE_NUMBER, 5000),
116
- labelGotoSlide: makeProp(PROP_TYPE_STRING, 'Goto slide'),
117
- labelIndicators: makeProp(PROP_TYPE_STRING, 'Select a slide to display'),
118
- labelNext: makeProp(PROP_TYPE_STRING, 'Next slide'),
119
- labelPrev: makeProp(PROP_TYPE_STRING, 'Previous slide'),
120
- // Disable slide/fade animation
121
- noAnimation: makeProp(PROP_TYPE_BOOLEAN, false),
122
- // Disable pause on hover
123
- noHoverPause: makeProp(PROP_TYPE_BOOLEAN, false),
124
- // Sniffed by carousel-slide
125
- noTouch: makeProp(PROP_TYPE_BOOLEAN, false),
126
- // Disable wrapping/looping when start/end is reached
127
- noWrap: makeProp(PROP_TYPE_BOOLEAN, false)
128
- }),
129
- NAME_CAROUSEL
130
- )
131
-
132
- // --- Main component ---
133
-
134
- // @vue/component
135
- export const BCarousel = /*#__PURE__*/ extend({
136
- name: NAME_CAROUSEL,
137
- mixins: [idMixin, modelMixin, normalizeSlotMixin],
138
- provide() {
139
- return { getBvCarousel: () => this }
140
- },
141
- props,
142
- data() {
143
- return {
144
- index: this[MODEL_PROP_NAME] || 0,
145
- isSliding: false,
146
- transitionEndEvent: null,
147
- slides: [],
148
- direction: null,
149
- isPaused: !(toInteger(this.interval, 0) > 0),
150
- // Touch event handling values
151
- touchStartX: 0,
152
- touchDeltaX: 0
153
- }
154
- },
155
- computed: {
156
- numSlides() {
157
- return this.slides.length
158
- }
159
- },
160
- watch: {
161
- [MODEL_PROP_NAME](newValue, oldValue) {
162
- if (newValue !== oldValue) {
163
- this.setSlide(toInteger(newValue, 0))
164
- }
165
- },
166
- interval(newValue, oldValue) {
167
- /* istanbul ignore next */
168
- if (newValue === oldValue) {
169
- return
170
- }
171
- if (!newValue) {
172
- // Pausing slide show
173
- this.pause(false)
174
- } else {
175
- // Restarting or Changing interval
176
- this.pause(true)
177
- this.start(false)
178
- }
179
- },
180
- isPaused(newValue, oldValue) {
181
- if (newValue !== oldValue) {
182
- this.$emit(newValue ? EVENT_NAME_PAUSED : EVENT_NAME_UNPAUSED)
183
- }
184
- },
185
- index(to, from) {
186
- /* istanbul ignore next */
187
- if (to === from || this.isSliding) {
188
- return
189
- }
190
- this.doSlide(to, from)
191
- }
192
- },
193
- created() {
194
- // Create private non-reactive props
195
- this.$_interval = null
196
- this.$_animationTimeout = null
197
- this.$_touchTimeout = null
198
- this.$_observer = null
199
- // Set initial paused state
200
- this.isPaused = !(toInteger(this.interval, 0) > 0)
201
- },
202
- mounted() {
203
- // Cache current browser transitionend event name
204
- this.transitionEndEvent = getTransitionEndEvent(this.$el) || null
205
- // Get all slides
206
- this.updateSlides()
207
- // Observe child changes so we can update slide list
208
- this.setObserver(true)
209
- },
210
- beforeDestroy() {
211
- this.clearInterval()
212
- this.clearAnimationTimeout()
213
- this.clearTouchTimeout()
214
- this.setObserver(false)
215
- },
216
- methods: {
217
- clearInterval() {
218
- clearInterval(this.$_interval)
219
- this.$_interval = null
220
- },
221
- clearAnimationTimeout() {
222
- clearTimeout(this.$_animationTimeout)
223
- this.$_animationTimeout = null
224
- },
225
- clearTouchTimeout() {
226
- clearTimeout(this.$_touchTimeout)
227
- this.$_touchTimeout = null
228
- },
229
- setObserver(on = false) {
230
- this.$_observer && this.$_observer.disconnect()
231
- this.$_observer = null
232
- if (on) {
233
- this.$_observer = observeDom(this.$refs.inner, this.updateSlides.bind(this), {
234
- subtree: false,
235
- childList: true,
236
- attributes: true,
237
- attributeFilter: ['id']
238
- })
239
- }
240
- },
241
- // Set slide
242
- setSlide(slide, direction = null) {
243
- // Don't animate when page is not visible
244
- /* istanbul ignore if: difficult to test */
245
- if (IS_BROWSER && document.visibilityState && document.hidden) {
246
- return
247
- }
248
- const noWrap = this.noWrap
249
- const numSlides = this.numSlides
250
- // Make sure we have an integer (you never know!)
251
- slide = mathFloor(slide)
252
- // Don't do anything if nothing to slide to
253
- if (numSlides === 0) {
254
- return
255
- }
256
- // Don't change slide while transitioning, wait until transition is done
257
- if (this.isSliding) {
258
- // Schedule slide after sliding complete
259
- this.$once(EVENT_NAME_SLIDING_END, () => {
260
- // Wrap in `requestAF()` to allow the slide to properly finish to avoid glitching
261
- requestAF(() => this.setSlide(slide, direction))
262
- })
263
- return
264
- }
265
- this.direction = direction
266
- // Set new slide index
267
- // Wrap around if necessary (if no-wrap not enabled)
268
- this.index =
269
- slide >= numSlides
270
- ? noWrap
271
- ? numSlides - 1
272
- : 0
273
- : slide < 0
274
- ? noWrap
275
- ? 0
276
- : numSlides - 1
277
- : slide
278
- // Ensure the v-model is synched up if no-wrap is enabled
279
- // and user tried to slide pass either ends
280
- if (noWrap && this.index !== slide && this.index !== this[MODEL_PROP_NAME]) {
281
- this.$emit(MODEL_EVENT_NAME, this.index)
282
- }
283
- },
284
- // Previous slide
285
- prev() {
286
- this.setSlide(this.index - 1, 'prev')
287
- },
288
- // Next slide
289
- next() {
290
- this.setSlide(this.index + 1, 'next')
291
- },
292
- // Pause auto rotation
293
- pause(event) {
294
- if (!event) {
295
- this.isPaused = true
296
- }
297
- this.clearInterval()
298
- },
299
- // Start auto rotate slides
300
- start(event) {
301
- if (!event) {
302
- this.isPaused = false
303
- }
304
- /* istanbul ignore next: most likely will never happen, but just in case */
305
- this.clearInterval()
306
- // Don't start if no interval, or less than 2 slides
307
- if (this.interval && this.numSlides > 1) {
308
- this.$_interval = setInterval(this.next, mathMax(1000, this.interval))
309
- }
310
- },
311
- // Restart auto rotate slides when focus/hover leaves the carousel
312
- /* istanbul ignore next */
313
- restart() {
314
- if (!this.$el.contains(getActiveElement())) {
315
- this.start()
316
- }
317
- },
318
- doSlide(to, from) {
319
- const isCycling = Boolean(this.interval)
320
- // Determine sliding direction
321
- const direction = this.calcDirection(this.direction, from, to)
322
- const overlayClass = direction.overlayClass
323
- const dirClass = direction.dirClass
324
- // Determine current and next slides
325
- const currentSlide = this.slides[from]
326
- const nextSlide = this.slides[to]
327
- // Don't do anything if there aren't any slides to slide to
328
- if (!currentSlide || !nextSlide) {
329
- /* istanbul ignore next */
330
- return
331
- }
332
- // Start animating
333
- this.isSliding = true
334
- if (isCycling) {
335
- this.pause(false)
336
- }
337
- this.$emit(EVENT_NAME_SLIDING_START, to)
338
- // Update v-model
339
- this.$emit(MODEL_EVENT_NAME, this.index)
340
- if (this.noAnimation) {
341
- addClass(nextSlide, 'active')
342
- removeClass(currentSlide, 'active')
343
- this.isSliding = false
344
- // Notify ourselves that we're done sliding (slid)
345
- this.$nextTick(() => this.$emit(EVENT_NAME_SLIDING_END, to))
346
- } else {
347
- addClass(nextSlide, overlayClass)
348
- // Trigger a reflow of next slide
349
- reflow(nextSlide)
350
- addClass(currentSlide, dirClass)
351
- addClass(nextSlide, dirClass)
352
- // Transition End handler
353
- let called = false
354
- /* istanbul ignore next: difficult to test */
355
- const onceTransEnd = () => {
356
- if (called) {
357
- return
358
- }
359
- called = true
360
- /* istanbul ignore if: transition events cant be tested in JSDOM */
361
- if (this.transitionEndEvent) {
362
- const events = this.transitionEndEvent.split(/\s+/)
363
- events.forEach(event =>
364
- eventOff(nextSlide, event, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE)
365
- )
366
- }
367
- this.clearAnimationTimeout()
368
- removeClass(nextSlide, dirClass)
369
- removeClass(nextSlide, overlayClass)
370
- addClass(nextSlide, 'active')
371
- removeClass(currentSlide, 'active')
372
- removeClass(currentSlide, dirClass)
373
- removeClass(currentSlide, overlayClass)
374
- setAttr(currentSlide, 'aria-current', 'false')
375
- setAttr(nextSlide, 'aria-current', 'true')
376
- setAttr(currentSlide, 'aria-hidden', 'true')
377
- setAttr(nextSlide, 'aria-hidden', 'false')
378
- this.isSliding = false
379
- this.direction = null
380
- // Notify ourselves that we're done sliding (slid)
381
- this.$nextTick(() => this.$emit(EVENT_NAME_SLIDING_END, to))
382
- }
383
- // Set up transitionend handler
384
- /* istanbul ignore if: transition events cant be tested in JSDOM */
385
- if (this.transitionEndEvent) {
386
- const events = this.transitionEndEvent.split(/\s+/)
387
- events.forEach(event => eventOn(nextSlide, event, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE))
388
- }
389
- // Fallback to setTimeout()
390
- this.$_animationTimeout = setTimeout(onceTransEnd, TRANS_DURATION)
391
- }
392
- if (isCycling) {
393
- this.start(false)
394
- }
395
- },
396
- // Update slide list
397
- updateSlides() {
398
- this.pause(true)
399
- // Get all slides as DOM elements
400
- this.slides = selectAll('.carousel-item', this.$refs.inner)
401
- const numSlides = this.slides.length
402
- // Keep slide number in range
403
- const index = mathMax(0, mathMin(mathFloor(this.index), numSlides - 1))
404
- this.slides.forEach((slide, idx) => {
405
- const n = idx + 1
406
- if (idx === index) {
407
- addClass(slide, 'active')
408
- setAttr(slide, 'aria-current', 'true')
409
- } else {
410
- removeClass(slide, 'active')
411
- setAttr(slide, 'aria-current', 'false')
412
- }
413
- setAttr(slide, 'aria-posinset', String(n))
414
- setAttr(slide, 'aria-setsize', String(numSlides))
415
- })
416
- // Set slide as active
417
- this.setSlide(index)
418
- this.start(this.isPaused)
419
- },
420
- calcDirection(direction = null, curIndex = 0, nextIndex = 0) {
421
- if (!direction) {
422
- return nextIndex > curIndex ? DIRECTION.next : DIRECTION.prev
423
- }
424
- return DIRECTION[direction]
425
- },
426
- handleClick(event, fn) {
427
- const keyCode = event.keyCode
428
- if (event.type === 'click' || keyCode === CODE_SPACE || keyCode === CODE_ENTER) {
429
- stopEvent(event)
430
- fn()
431
- }
432
- },
433
- /* istanbul ignore next: JSDOM doesn't support touch events */
434
- handleSwipe() {
435
- const absDeltaX = mathAbs(this.touchDeltaX)
436
- if (absDeltaX <= SWIPE_THRESHOLD) {
437
- return
438
- }
439
- const direction = absDeltaX / this.touchDeltaX
440
- // Reset touch delta X
441
- // https://github.com/twbs/bootstrap/pull/28558
442
- this.touchDeltaX = 0
443
- if (direction > 0) {
444
- // Swipe left
445
- this.prev()
446
- } else if (direction < 0) {
447
- // Swipe right
448
- this.next()
449
- }
450
- },
451
- /* istanbul ignore next: JSDOM doesn't support touch events */
452
- touchStart(event) {
453
- if (HAS_POINTER_EVENT_SUPPORT && PointerType[event.pointerType.toUpperCase()]) {
454
- this.touchStartX = event.clientX
455
- } else if (!HAS_POINTER_EVENT_SUPPORT) {
456
- this.touchStartX = event.touches[0].clientX
457
- }
458
- },
459
- /* istanbul ignore next: JSDOM doesn't support touch events */
460
- touchMove(event) {
461
- // Ensure swiping with one touch and not pinching
462
- if (event.touches && event.touches.length > 1) {
463
- this.touchDeltaX = 0
464
- } else {
465
- this.touchDeltaX = event.touches[0].clientX - this.touchStartX
466
- }
467
- },
468
- /* istanbul ignore next: JSDOM doesn't support touch events */
469
- touchEnd(event) {
470
- if (HAS_POINTER_EVENT_SUPPORT && PointerType[event.pointerType.toUpperCase()]) {
471
- this.touchDeltaX = event.clientX - this.touchStartX
472
- }
473
- this.handleSwipe()
474
- // If it's a touch-enabled device, mouseenter/leave are fired as
475
- // part of the mouse compatibility events on first tap - the carousel
476
- // would stop cycling until user tapped out of it;
477
- // here, we listen for touchend, explicitly pause the carousel
478
- // (as if it's the second time we tap on it, mouseenter compat event
479
- // is NOT fired) and after a timeout (to allow for mouse compatibility
480
- // events to fire) we explicitly restart cycling
481
- this.pause(false)
482
- this.clearTouchTimeout()
483
- this.$_touchTimeout = setTimeout(
484
- this.start,
485
- TOUCH_EVENT_COMPAT_WAIT + mathMax(1000, this.interval)
486
- )
487
- }
488
- },
489
- render(h) {
490
- const {
491
- indicators,
492
- background,
493
- noAnimation,
494
- noHoverPause,
495
- noTouch,
496
- index,
497
- isSliding,
498
- pause,
499
- restart,
500
- touchStart,
501
- touchEnd
502
- } = this
503
- const idInner = this.safeId('__BV_inner_')
504
-
505
- // Wrapper for slides
506
- const $inner = h(
507
- 'div',
508
- {
509
- staticClass: 'carousel-inner',
510
- attrs: {
511
- id: idInner,
512
- role: 'list'
513
- },
514
- ref: 'inner'
515
- },
516
- [this.normalizeSlot()]
517
- )
518
-
519
- // Prev and next controls
520
- let $controls = h()
521
- if (this.controls) {
522
- const makeControl = (direction, label, handler) => {
523
- const handlerWrapper = event => {
524
- /* istanbul ignore next */
525
- if (!isSliding) {
526
- this.handleClick(event, handler)
527
- } else {
528
- stopEvent(event, { propagation: false })
529
- }
530
- }
531
-
532
- return h(
533
- 'a',
534
- {
535
- staticClass: `carousel-control-${direction}`,
536
- attrs: {
537
- href: '#',
538
- role: 'button',
539
- 'aria-controls': idInner,
540
- 'aria-disabled': isSliding ? 'true' : null
541
- },
542
- on: {
543
- click: handlerWrapper,
544
- keydown: handlerWrapper
545
- }
546
- },
547
- [
548
- h('span', {
549
- staticClass: `carousel-control-${direction}-icon`,
550
- attrs: { 'aria-hidden': 'true' }
551
- }),
552
- h('span', { class: 'sr-only' }, [label])
553
- ]
554
- )
555
- }
556
-
557
- $controls = [
558
- makeControl('prev', this.labelPrev, this.prev),
559
- makeControl('next', this.labelNext, this.next)
560
- ]
561
- }
562
-
563
- // Indicators
564
- const $indicators = h(
565
- 'ol',
566
- {
567
- staticClass: 'carousel-indicators',
568
- directives: [{ name: 'show', value: indicators }],
569
- attrs: {
570
- id: this.safeId('__BV_indicators_'),
571
- 'aria-hidden': indicators ? 'false' : 'true',
572
- 'aria-label': this.labelIndicators,
573
- 'aria-owns': idInner
574
- }
575
- },
576
- this.slides.map((slide, i) => {
577
- const handler = event => {
578
- this.handleClick(event, () => {
579
- this.setSlide(i)
580
- })
581
- }
582
-
583
- return h('li', {
584
- class: { active: i === index },
585
- attrs: {
586
- role: 'button',
587
- id: this.safeId(`__BV_indicator_${i + 1}_`),
588
- tabindex: indicators ? '0' : '-1',
589
- 'aria-current': i === index ? 'true' : 'false',
590
- 'aria-label': `${this.labelGotoSlide} ${i + 1}`,
591
- 'aria-describedby': slide.id || null,
592
- 'aria-controls': idInner
593
- },
594
- on: {
595
- click: handler,
596
- keydown: handler
597
- },
598
- key: `slide_${i}`
599
- })
600
- })
601
- )
602
-
603
- const on = {
604
- mouseenter: noHoverPause ? noop : pause,
605
- mouseleave: noHoverPause ? noop : restart,
606
- focusin: pause,
607
- focusout: restart,
608
- keydown: event => {
609
- /* istanbul ignore next */
610
- if (/input|textarea/i.test(event.target.tagName)) {
611
- return
612
- }
613
- const { keyCode } = event
614
- if (keyCode === CODE_LEFT || keyCode === CODE_RIGHT) {
615
- stopEvent(event)
616
- this[keyCode === CODE_LEFT ? 'prev' : 'next']()
617
- }
618
- }
619
- }
620
- // Touch support event handlers for environment
621
- if (HAS_TOUCH_SUPPORT && !noTouch) {
622
- // Attach appropriate listeners (prepend event name with '&' for passive mode)
623
- /* istanbul ignore next: JSDOM doesn't support touch events */
624
- if (HAS_POINTER_EVENT_SUPPORT) {
625
- on['&pointerdown'] = touchStart
626
- on['&pointerup'] = touchEnd
627
- } else {
628
- on['&touchstart'] = touchStart
629
- on['&touchmove'] = this.touchMove
630
- on['&touchend'] = touchEnd
631
- }
632
- }
633
-
634
- // Return the carousel
635
- return h(
636
- 'div',
637
- {
638
- staticClass: 'carousel',
639
- class: {
640
- slide: !noAnimation,
641
- 'carousel-fade': !noAnimation && this.fade,
642
- 'pointer-event': HAS_TOUCH_SUPPORT && HAS_POINTER_EVENT_SUPPORT && !noTouch
643
- },
644
- style: { background },
645
- attrs: {
646
- role: 'region',
647
- id: this.safeId(),
648
- 'aria-busy': isSliding ? 'true' : 'false'
649
- },
650
- on
651
- },
652
- [$inner, $controls, $indicators]
653
- )
654
- }
655
- })