administrate-bootstrap-theme 0.1.0 → 0.1.9
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.
- checksums.yaml +4 -4
- data/README.md +25 -11
- data/Rakefile +10 -14
- data/app/assets/config/administrate-bootstrap-theme_manifest.js +1 -0
- data/app/assets/javascripts/administrate-bootstrap-theme/theme.js +2 -0
- data/app/assets/stylesheets/administrate-bootstrap-theme/_base.scss +17 -1
- data/app/assets/stylesheets/administrate-bootstrap-theme/components/_content_body.scss +17 -3
- data/app/assets/stylesheets/administrate-bootstrap-theme/components/_form.scss +52 -16
- data/app/assets/stylesheets/administrate-bootstrap-theme/theme.scss +12 -0
- data/lib/administrate-bootstrap-theme/engine.rb +2 -0
- data/lib/administrate-bootstrap-theme/version.rb +1 -1
- data/node_modules/bootstrap/js/src/alert.js +141 -0
- data/node_modules/bootstrap/js/src/base-component.js +46 -0
- data/node_modules/bootstrap/js/src/button.js +95 -0
- data/node_modules/bootstrap/js/src/carousel.js +624 -0
- data/node_modules/bootstrap/js/src/collapse.js +410 -0
- data/node_modules/bootstrap/js/src/dom/data.js +57 -0
- data/node_modules/bootstrap/js/src/dom/event-handler.js +331 -0
- data/node_modules/bootstrap/js/src/dom/manipulator.js +80 -0
- data/node_modules/bootstrap/js/src/dom/selector-engine.js +75 -0
- data/node_modules/bootstrap/js/src/dropdown.js +543 -0
- data/node_modules/bootstrap/js/src/modal.js +582 -0
- data/node_modules/bootstrap/js/src/offcanvas.js +279 -0
- data/node_modules/bootstrap/js/src/popover.js +171 -0
- data/node_modules/bootstrap/js/src/scrollspy.js +319 -0
- data/node_modules/bootstrap/js/src/tab.js +220 -0
- data/node_modules/bootstrap/js/src/toast.js +219 -0
- data/node_modules/bootstrap/js/src/tooltip.js +802 -0
- data/node_modules/bootstrap/js/src/util/index.js +253 -0
- data/node_modules/bootstrap/js/src/util/sanitizer.js +127 -0
- data/node_modules/bootstrap/js/src/util/scrollbar.js +70 -0
- data/node_modules/bootstrap/scss/_accordion.scss +116 -0
- data/node_modules/bootstrap/scss/_alert.scss +57 -0
- data/node_modules/bootstrap/scss/_badge.scss +29 -0
- data/node_modules/bootstrap/scss/_breadcrumb.scss +28 -0
- data/node_modules/bootstrap/scss/_button-group.scss +139 -0
- data/node_modules/bootstrap/scss/_buttons.scss +111 -0
- data/node_modules/bootstrap/scss/_card.scss +215 -0
- data/node_modules/bootstrap/scss/_carousel.scss +229 -0
- data/node_modules/bootstrap/scss/_close.scss +40 -0
- data/node_modules/bootstrap/scss/_containers.scss +41 -0
- data/node_modules/bootstrap/scss/_dropdown.scss +246 -0
- data/node_modules/bootstrap/scss/_forms.scss +9 -0
- data/node_modules/bootstrap/scss/_functions.scss +205 -0
- data/node_modules/bootstrap/scss/_grid.scss +22 -0
- data/node_modules/bootstrap/scss/_helpers.scss +7 -0
- data/node_modules/bootstrap/scss/_images.scss +42 -0
- data/node_modules/bootstrap/scss/_list-group.scss +174 -0
- data/node_modules/bootstrap/scss/_mixins.scss +41 -0
- data/node_modules/bootstrap/scss/_modal.scss +237 -0
- data/node_modules/bootstrap/scss/_nav.scss +139 -0
- data/node_modules/bootstrap/scss/_navbar.scss +306 -0
- data/node_modules/bootstrap/scss/_offcanvas.scss +77 -0
- data/node_modules/bootstrap/scss/_pagination.scss +64 -0
- data/node_modules/bootstrap/scss/_popover.scss +158 -0
- data/node_modules/bootstrap/scss/_progress.scss +48 -0
- data/node_modules/bootstrap/scss/_reboot.scss +621 -0
- data/node_modules/bootstrap/scss/_root.scss +16 -0
- data/node_modules/bootstrap/scss/_spinners.scss +69 -0
- data/node_modules/bootstrap/scss/_tables.scss +150 -0
- data/node_modules/bootstrap/scss/_toasts.scss +51 -0
- data/node_modules/bootstrap/scss/_tooltip.scss +115 -0
- data/node_modules/bootstrap/scss/_transitions.scss +21 -0
- data/node_modules/bootstrap/scss/_type.scss +104 -0
- data/node_modules/bootstrap/scss/_utilities.scss +594 -0
- data/node_modules/bootstrap/scss/_variables.scss +1464 -0
- data/node_modules/bootstrap/scss/bootstrap-grid.scss +65 -0
- data/node_modules/bootstrap/scss/bootstrap-reboot.scss +15 -0
- data/node_modules/bootstrap/scss/bootstrap-utilities.scss +18 -0
- data/node_modules/bootstrap/scss/bootstrap.scss +52 -0
- data/node_modules/bootstrap/scss/forms/_floating-labels.scss +61 -0
- data/node_modules/bootstrap/scss/forms/_form-check.scss +152 -0
- data/node_modules/bootstrap/scss/forms/_form-control.scss +219 -0
- data/node_modules/bootstrap/scss/forms/_form-range.scss +91 -0
- data/node_modules/bootstrap/scss/forms/_form-select.scss +67 -0
- data/node_modules/bootstrap/scss/forms/_form-text.scss +11 -0
- data/node_modules/bootstrap/scss/forms/_input-group.scss +121 -0
- data/node_modules/bootstrap/scss/forms/_labels.scss +36 -0
- data/node_modules/bootstrap/scss/forms/_validation.scss +12 -0
- data/node_modules/bootstrap/scss/helpers/_clearfix.scss +3 -0
- data/node_modules/bootstrap/scss/helpers/_colored-links.scss +12 -0
- data/node_modules/bootstrap/scss/helpers/_position.scss +30 -0
- data/node_modules/bootstrap/scss/helpers/_ratio.scss +26 -0
- data/node_modules/bootstrap/scss/helpers/_stretched-link.scss +15 -0
- data/node_modules/bootstrap/scss/helpers/_text-truncation.scss +7 -0
- data/node_modules/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
- data/node_modules/bootstrap/scss/mixins/_alert.scss +11 -0
- data/node_modules/bootstrap/scss/mixins/_border-radius.scss +78 -0
- data/node_modules/bootstrap/scss/mixins/_box-shadow.scss +18 -0
- data/node_modules/bootstrap/scss/mixins/_breakpoints.scss +127 -0
- data/node_modules/bootstrap/scss/mixins/_buttons.scss +133 -0
- data/node_modules/bootstrap/scss/mixins/_caret.scss +64 -0
- data/node_modules/bootstrap/scss/mixins/_clearfix.scss +9 -0
- data/node_modules/bootstrap/scss/mixins/_container.scss +9 -0
- data/node_modules/bootstrap/scss/mixins/_deprecate.scss +10 -0
- data/node_modules/bootstrap/scss/mixins/_forms.scss +134 -0
- data/node_modules/bootstrap/scss/mixins/_gradients.scss +47 -0
- data/node_modules/bootstrap/scss/mixins/_grid.scss +120 -0
- data/node_modules/bootstrap/scss/mixins/_image.scss +16 -0
- data/node_modules/bootstrap/scss/mixins/_list-group.scss +24 -0
- data/node_modules/bootstrap/scss/mixins/_lists.scss +7 -0
- data/node_modules/bootstrap/scss/mixins/_pagination.scss +31 -0
- data/node_modules/bootstrap/scss/mixins/_reset-text.scss +17 -0
- data/node_modules/bootstrap/scss/mixins/_resize.scss +6 -0
- data/node_modules/bootstrap/scss/mixins/_table-variants.scss +21 -0
- data/node_modules/bootstrap/scss/mixins/_text-truncate.scss +8 -0
- data/node_modules/bootstrap/scss/mixins/_transition.scss +26 -0
- data/node_modules/bootstrap/scss/mixins/_utilities.scss +68 -0
- data/node_modules/bootstrap/scss/mixins/_visually-hidden.scss +29 -0
- data/node_modules/bootstrap/scss/utilities/_api.scss +47 -0
- data/node_modules/bootstrap/scss/vendor/_rfs.scss +312 -0
- metadata +106 -19
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* --------------------------------------------------------------------------
|
|
3
|
+
* Bootstrap (v5.0.0-beta3): base-component.js
|
|
4
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
|
+
* --------------------------------------------------------------------------
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import Data from './dom/data'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* ------------------------------------------------------------------------
|
|
12
|
+
* Constants
|
|
13
|
+
* ------------------------------------------------------------------------
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const VERSION = '5.0.0-beta3'
|
|
17
|
+
|
|
18
|
+
class BaseComponent {
|
|
19
|
+
constructor(element) {
|
|
20
|
+
element = typeof element === 'string' ? document.querySelector(element) : element
|
|
21
|
+
|
|
22
|
+
if (!element) {
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this._element = element
|
|
27
|
+
Data.set(this._element, this.constructor.DATA_KEY, this)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
dispose() {
|
|
31
|
+
Data.remove(this._element, this.constructor.DATA_KEY)
|
|
32
|
+
this._element = null
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Static */
|
|
36
|
+
|
|
37
|
+
static getInstance(element) {
|
|
38
|
+
return Data.get(element, this.DATA_KEY)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static get VERSION() {
|
|
42
|
+
return VERSION
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default BaseComponent
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* --------------------------------------------------------------------------
|
|
3
|
+
* Bootstrap (v5.0.0-beta3): button.js
|
|
4
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
|
+
* --------------------------------------------------------------------------
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { defineJQueryPlugin } from './util/index'
|
|
9
|
+
import Data from './dom/data'
|
|
10
|
+
import EventHandler from './dom/event-handler'
|
|
11
|
+
import BaseComponent from './base-component'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* ------------------------------------------------------------------------
|
|
15
|
+
* Constants
|
|
16
|
+
* ------------------------------------------------------------------------
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const NAME = 'button'
|
|
20
|
+
const DATA_KEY = 'bs.button'
|
|
21
|
+
const EVENT_KEY = `.${DATA_KEY}`
|
|
22
|
+
const DATA_API_KEY = '.data-api'
|
|
23
|
+
|
|
24
|
+
const CLASS_NAME_ACTIVE = 'active'
|
|
25
|
+
|
|
26
|
+
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="button"]'
|
|
27
|
+
|
|
28
|
+
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* ------------------------------------------------------------------------
|
|
32
|
+
* Class Definition
|
|
33
|
+
* ------------------------------------------------------------------------
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
class Button extends BaseComponent {
|
|
37
|
+
// Getters
|
|
38
|
+
|
|
39
|
+
static get DATA_KEY() {
|
|
40
|
+
return DATA_KEY
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Public
|
|
44
|
+
|
|
45
|
+
toggle() {
|
|
46
|
+
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
|
47
|
+
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Static
|
|
51
|
+
|
|
52
|
+
static jQueryInterface(config) {
|
|
53
|
+
return this.each(function () {
|
|
54
|
+
let data = Data.get(this, DATA_KEY)
|
|
55
|
+
|
|
56
|
+
if (!data) {
|
|
57
|
+
data = new Button(this)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (config === 'toggle') {
|
|
61
|
+
data[config]()
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* ------------------------------------------------------------------------
|
|
69
|
+
* Data Api implementation
|
|
70
|
+
* ------------------------------------------------------------------------
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, event => {
|
|
74
|
+
event.preventDefault()
|
|
75
|
+
|
|
76
|
+
const button = event.target.closest(SELECTOR_DATA_TOGGLE)
|
|
77
|
+
|
|
78
|
+
let data = Data.get(button, DATA_KEY)
|
|
79
|
+
if (!data) {
|
|
80
|
+
data = new Button(button)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
data.toggle()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* ------------------------------------------------------------------------
|
|
88
|
+
* jQuery
|
|
89
|
+
* ------------------------------------------------------------------------
|
|
90
|
+
* add .Button to jQuery only if jQuery is present
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
defineJQueryPlugin(NAME, Button)
|
|
94
|
+
|
|
95
|
+
export default Button
|
|
@@ -0,0 +1,624 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* --------------------------------------------------------------------------
|
|
3
|
+
* Bootstrap (v5.0.0-beta3): carousel.js
|
|
4
|
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
|
5
|
+
* --------------------------------------------------------------------------
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
defineJQueryPlugin,
|
|
10
|
+
emulateTransitionEnd,
|
|
11
|
+
getElementFromSelector,
|
|
12
|
+
getTransitionDurationFromElement,
|
|
13
|
+
isRTL,
|
|
14
|
+
isVisible,
|
|
15
|
+
reflow,
|
|
16
|
+
triggerTransitionEnd,
|
|
17
|
+
typeCheckConfig
|
|
18
|
+
} from './util/index'
|
|
19
|
+
import Data from './dom/data'
|
|
20
|
+
import EventHandler from './dom/event-handler'
|
|
21
|
+
import Manipulator from './dom/manipulator'
|
|
22
|
+
import SelectorEngine from './dom/selector-engine'
|
|
23
|
+
import BaseComponent from './base-component'
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* ------------------------------------------------------------------------
|
|
27
|
+
* Constants
|
|
28
|
+
* ------------------------------------------------------------------------
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
const NAME = 'carousel'
|
|
32
|
+
const DATA_KEY = 'bs.carousel'
|
|
33
|
+
const EVENT_KEY = `.${DATA_KEY}`
|
|
34
|
+
const DATA_API_KEY = '.data-api'
|
|
35
|
+
|
|
36
|
+
const ARROW_LEFT_KEY = 'ArrowLeft'
|
|
37
|
+
const ARROW_RIGHT_KEY = 'ArrowRight'
|
|
38
|
+
const TOUCHEVENT_COMPAT_WAIT = 500 // Time for mouse compat events to fire after touch
|
|
39
|
+
const SWIPE_THRESHOLD = 40
|
|
40
|
+
|
|
41
|
+
const Default = {
|
|
42
|
+
interval: 5000,
|
|
43
|
+
keyboard: true,
|
|
44
|
+
slide: false,
|
|
45
|
+
pause: 'hover',
|
|
46
|
+
wrap: true,
|
|
47
|
+
touch: true
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const DefaultType = {
|
|
51
|
+
interval: '(number|boolean)',
|
|
52
|
+
keyboard: 'boolean',
|
|
53
|
+
slide: '(boolean|string)',
|
|
54
|
+
pause: '(string|boolean)',
|
|
55
|
+
wrap: 'boolean',
|
|
56
|
+
touch: 'boolean'
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const ORDER_NEXT = 'next'
|
|
60
|
+
const ORDER_PREV = 'prev'
|
|
61
|
+
const DIRECTION_LEFT = 'left'
|
|
62
|
+
const DIRECTION_RIGHT = 'right'
|
|
63
|
+
|
|
64
|
+
const EVENT_SLIDE = `slide${EVENT_KEY}`
|
|
65
|
+
const EVENT_SLID = `slid${EVENT_KEY}`
|
|
66
|
+
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`
|
|
67
|
+
const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY}`
|
|
68
|
+
const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY}`
|
|
69
|
+
const EVENT_TOUCHSTART = `touchstart${EVENT_KEY}`
|
|
70
|
+
const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY}`
|
|
71
|
+
const EVENT_TOUCHEND = `touchend${EVENT_KEY}`
|
|
72
|
+
const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}`
|
|
73
|
+
const EVENT_POINTERUP = `pointerup${EVENT_KEY}`
|
|
74
|
+
const EVENT_DRAG_START = `dragstart${EVENT_KEY}`
|
|
75
|
+
const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`
|
|
76
|
+
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
|
77
|
+
|
|
78
|
+
const CLASS_NAME_CAROUSEL = 'carousel'
|
|
79
|
+
const CLASS_NAME_ACTIVE = 'active'
|
|
80
|
+
const CLASS_NAME_SLIDE = 'slide'
|
|
81
|
+
const CLASS_NAME_END = 'carousel-item-end'
|
|
82
|
+
const CLASS_NAME_START = 'carousel-item-start'
|
|
83
|
+
const CLASS_NAME_NEXT = 'carousel-item-next'
|
|
84
|
+
const CLASS_NAME_PREV = 'carousel-item-prev'
|
|
85
|
+
const CLASS_NAME_POINTER_EVENT = 'pointer-event'
|
|
86
|
+
|
|
87
|
+
const SELECTOR_ACTIVE = '.active'
|
|
88
|
+
const SELECTOR_ACTIVE_ITEM = '.active.carousel-item'
|
|
89
|
+
const SELECTOR_ITEM = '.carousel-item'
|
|
90
|
+
const SELECTOR_ITEM_IMG = '.carousel-item img'
|
|
91
|
+
const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'
|
|
92
|
+
const SELECTOR_INDICATORS = '.carousel-indicators'
|
|
93
|
+
const SELECTOR_INDICATOR = '[data-bs-target]'
|
|
94
|
+
const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'
|
|
95
|
+
const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'
|
|
96
|
+
|
|
97
|
+
const POINTER_TYPE_TOUCH = 'touch'
|
|
98
|
+
const POINTER_TYPE_PEN = 'pen'
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* ------------------------------------------------------------------------
|
|
102
|
+
* Class Definition
|
|
103
|
+
* ------------------------------------------------------------------------
|
|
104
|
+
*/
|
|
105
|
+
class Carousel extends BaseComponent {
|
|
106
|
+
constructor(element, config) {
|
|
107
|
+
super(element)
|
|
108
|
+
|
|
109
|
+
this._items = null
|
|
110
|
+
this._interval = null
|
|
111
|
+
this._activeElement = null
|
|
112
|
+
this._isPaused = false
|
|
113
|
+
this._isSliding = false
|
|
114
|
+
this.touchTimeout = null
|
|
115
|
+
this.touchStartX = 0
|
|
116
|
+
this.touchDeltaX = 0
|
|
117
|
+
|
|
118
|
+
this._config = this._getConfig(config)
|
|
119
|
+
this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element)
|
|
120
|
+
this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0
|
|
121
|
+
this._pointerEvent = Boolean(window.PointerEvent)
|
|
122
|
+
|
|
123
|
+
this._addEventListeners()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Getters
|
|
127
|
+
|
|
128
|
+
static get Default() {
|
|
129
|
+
return Default
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static get DATA_KEY() {
|
|
133
|
+
return DATA_KEY
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Public
|
|
137
|
+
|
|
138
|
+
next() {
|
|
139
|
+
if (!this._isSliding) {
|
|
140
|
+
this._slide(ORDER_NEXT)
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
nextWhenVisible() {
|
|
145
|
+
// Don't call next when the page isn't visible
|
|
146
|
+
// or the carousel or its parent isn't visible
|
|
147
|
+
if (!document.hidden && isVisible(this._element)) {
|
|
148
|
+
this.next()
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
prev() {
|
|
153
|
+
if (!this._isSliding) {
|
|
154
|
+
this._slide(ORDER_PREV)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
pause(event) {
|
|
159
|
+
if (!event) {
|
|
160
|
+
this._isPaused = true
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) {
|
|
164
|
+
triggerTransitionEnd(this._element)
|
|
165
|
+
this.cycle(true)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
clearInterval(this._interval)
|
|
169
|
+
this._interval = null
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
cycle(event) {
|
|
173
|
+
if (!event) {
|
|
174
|
+
this._isPaused = false
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (this._interval) {
|
|
178
|
+
clearInterval(this._interval)
|
|
179
|
+
this._interval = null
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (this._config && this._config.interval && !this._isPaused) {
|
|
183
|
+
this._updateInterval()
|
|
184
|
+
|
|
185
|
+
this._interval = setInterval(
|
|
186
|
+
(document.visibilityState ? this.nextWhenVisible : this.next).bind(this),
|
|
187
|
+
this._config.interval
|
|
188
|
+
)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
to(index) {
|
|
193
|
+
this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)
|
|
194
|
+
const activeIndex = this._getItemIndex(this._activeElement)
|
|
195
|
+
|
|
196
|
+
if (index > this._items.length - 1 || index < 0) {
|
|
197
|
+
return
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (this._isSliding) {
|
|
201
|
+
EventHandler.one(this._element, EVENT_SLID, () => this.to(index))
|
|
202
|
+
return
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (activeIndex === index) {
|
|
206
|
+
this.pause()
|
|
207
|
+
this.cycle()
|
|
208
|
+
return
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const order = index > activeIndex ?
|
|
212
|
+
ORDER_NEXT :
|
|
213
|
+
ORDER_PREV
|
|
214
|
+
|
|
215
|
+
this._slide(order, this._items[index])
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
dispose() {
|
|
219
|
+
EventHandler.off(this._element, EVENT_KEY)
|
|
220
|
+
|
|
221
|
+
this._items = null
|
|
222
|
+
this._config = null
|
|
223
|
+
this._interval = null
|
|
224
|
+
this._isPaused = null
|
|
225
|
+
this._isSliding = null
|
|
226
|
+
this._activeElement = null
|
|
227
|
+
this._indicatorsElement = null
|
|
228
|
+
|
|
229
|
+
super.dispose()
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Private
|
|
233
|
+
|
|
234
|
+
_getConfig(config) {
|
|
235
|
+
config = {
|
|
236
|
+
...Default,
|
|
237
|
+
...config
|
|
238
|
+
}
|
|
239
|
+
typeCheckConfig(NAME, config, DefaultType)
|
|
240
|
+
return config
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
_handleSwipe() {
|
|
244
|
+
const absDeltax = Math.abs(this.touchDeltaX)
|
|
245
|
+
|
|
246
|
+
if (absDeltax <= SWIPE_THRESHOLD) {
|
|
247
|
+
return
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const direction = absDeltax / this.touchDeltaX
|
|
251
|
+
|
|
252
|
+
this.touchDeltaX = 0
|
|
253
|
+
|
|
254
|
+
if (!direction) {
|
|
255
|
+
return
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
this._slide(direction > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT)
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
_addEventListeners() {
|
|
262
|
+
if (this._config.keyboard) {
|
|
263
|
+
EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event))
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (this._config.pause === 'hover') {
|
|
267
|
+
EventHandler.on(this._element, EVENT_MOUSEENTER, event => this.pause(event))
|
|
268
|
+
EventHandler.on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event))
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (this._config.touch && this._touchSupported) {
|
|
272
|
+
this._addTouchEventListeners()
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
_addTouchEventListeners() {
|
|
277
|
+
const start = event => {
|
|
278
|
+
if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {
|
|
279
|
+
this.touchStartX = event.clientX
|
|
280
|
+
} else if (!this._pointerEvent) {
|
|
281
|
+
this.touchStartX = event.touches[0].clientX
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const move = event => {
|
|
286
|
+
// ensure swiping with one touch and not pinching
|
|
287
|
+
this.touchDeltaX = event.touches && event.touches.length > 1 ?
|
|
288
|
+
0 :
|
|
289
|
+
event.touches[0].clientX - this.touchStartX
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const end = event => {
|
|
293
|
+
if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {
|
|
294
|
+
this.touchDeltaX = event.clientX - this.touchStartX
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
this._handleSwipe()
|
|
298
|
+
if (this._config.pause === 'hover') {
|
|
299
|
+
// If it's a touch-enabled device, mouseenter/leave are fired as
|
|
300
|
+
// part of the mouse compatibility events on first tap - the carousel
|
|
301
|
+
// would stop cycling until user tapped out of it;
|
|
302
|
+
// here, we listen for touchend, explicitly pause the carousel
|
|
303
|
+
// (as if it's the second time we tap on it, mouseenter compat event
|
|
304
|
+
// is NOT fired) and after a timeout (to allow for mouse compatibility
|
|
305
|
+
// events to fire) we explicitly restart cycling
|
|
306
|
+
|
|
307
|
+
this.pause()
|
|
308
|
+
if (this.touchTimeout) {
|
|
309
|
+
clearTimeout(this.touchTimeout)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach(itemImg => {
|
|
317
|
+
EventHandler.on(itemImg, EVENT_DRAG_START, e => e.preventDefault())
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
if (this._pointerEvent) {
|
|
321
|
+
EventHandler.on(this._element, EVENT_POINTERDOWN, event => start(event))
|
|
322
|
+
EventHandler.on(this._element, EVENT_POINTERUP, event => end(event))
|
|
323
|
+
|
|
324
|
+
this._element.classList.add(CLASS_NAME_POINTER_EVENT)
|
|
325
|
+
} else {
|
|
326
|
+
EventHandler.on(this._element, EVENT_TOUCHSTART, event => start(event))
|
|
327
|
+
EventHandler.on(this._element, EVENT_TOUCHMOVE, event => move(event))
|
|
328
|
+
EventHandler.on(this._element, EVENT_TOUCHEND, event => end(event))
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
_keydown(event) {
|
|
333
|
+
if (/input|textarea/i.test(event.target.tagName)) {
|
|
334
|
+
return
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (event.key === ARROW_LEFT_KEY) {
|
|
338
|
+
event.preventDefault()
|
|
339
|
+
this._slide(DIRECTION_LEFT)
|
|
340
|
+
} else if (event.key === ARROW_RIGHT_KEY) {
|
|
341
|
+
event.preventDefault()
|
|
342
|
+
this._slide(DIRECTION_RIGHT)
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
_getItemIndex(element) {
|
|
347
|
+
this._items = element && element.parentNode ?
|
|
348
|
+
SelectorEngine.find(SELECTOR_ITEM, element.parentNode) :
|
|
349
|
+
[]
|
|
350
|
+
|
|
351
|
+
return this._items.indexOf(element)
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
_getItemByOrder(order, activeElement) {
|
|
355
|
+
const isNext = order === ORDER_NEXT
|
|
356
|
+
const isPrev = order === ORDER_PREV
|
|
357
|
+
const activeIndex = this._getItemIndex(activeElement)
|
|
358
|
+
const lastItemIndex = this._items.length - 1
|
|
359
|
+
const isGoingToWrap = (isPrev && activeIndex === 0) || (isNext && activeIndex === lastItemIndex)
|
|
360
|
+
|
|
361
|
+
if (isGoingToWrap && !this._config.wrap) {
|
|
362
|
+
return activeElement
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const delta = isPrev ? -1 : 1
|
|
366
|
+
const itemIndex = (activeIndex + delta) % this._items.length
|
|
367
|
+
|
|
368
|
+
return itemIndex === -1 ?
|
|
369
|
+
this._items[this._items.length - 1] :
|
|
370
|
+
this._items[itemIndex]
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
_triggerSlideEvent(relatedTarget, eventDirectionName) {
|
|
374
|
+
const targetIndex = this._getItemIndex(relatedTarget)
|
|
375
|
+
const fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element))
|
|
376
|
+
|
|
377
|
+
return EventHandler.trigger(this._element, EVENT_SLIDE, {
|
|
378
|
+
relatedTarget,
|
|
379
|
+
direction: eventDirectionName,
|
|
380
|
+
from: fromIndex,
|
|
381
|
+
to: targetIndex
|
|
382
|
+
})
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
_setActiveIndicatorElement(element) {
|
|
386
|
+
if (this._indicatorsElement) {
|
|
387
|
+
const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement)
|
|
388
|
+
|
|
389
|
+
activeIndicator.classList.remove(CLASS_NAME_ACTIVE)
|
|
390
|
+
activeIndicator.removeAttribute('aria-current')
|
|
391
|
+
|
|
392
|
+
const indicators = SelectorEngine.find(SELECTOR_INDICATOR, this._indicatorsElement)
|
|
393
|
+
|
|
394
|
+
for (let i = 0; i < indicators.length; i++) {
|
|
395
|
+
if (Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) {
|
|
396
|
+
indicators[i].classList.add(CLASS_NAME_ACTIVE)
|
|
397
|
+
indicators[i].setAttribute('aria-current', 'true')
|
|
398
|
+
break
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
_updateInterval() {
|
|
405
|
+
const element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)
|
|
406
|
+
|
|
407
|
+
if (!element) {
|
|
408
|
+
return
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10)
|
|
412
|
+
|
|
413
|
+
if (elementInterval) {
|
|
414
|
+
this._config.defaultInterval = this._config.defaultInterval || this._config.interval
|
|
415
|
+
this._config.interval = elementInterval
|
|
416
|
+
} else {
|
|
417
|
+
this._config.interval = this._config.defaultInterval || this._config.interval
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
_slide(directionOrOrder, element) {
|
|
422
|
+
const order = this._directionToOrder(directionOrOrder)
|
|
423
|
+
const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element)
|
|
424
|
+
const activeElementIndex = this._getItemIndex(activeElement)
|
|
425
|
+
const nextElement = element || this._getItemByOrder(order, activeElement)
|
|
426
|
+
|
|
427
|
+
const nextElementIndex = this._getItemIndex(nextElement)
|
|
428
|
+
const isCycling = Boolean(this._interval)
|
|
429
|
+
|
|
430
|
+
const isNext = order === ORDER_NEXT
|
|
431
|
+
const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END
|
|
432
|
+
const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV
|
|
433
|
+
const eventDirectionName = this._orderToDirection(order)
|
|
434
|
+
|
|
435
|
+
if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE)) {
|
|
436
|
+
this._isSliding = false
|
|
437
|
+
return
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName)
|
|
441
|
+
if (slideEvent.defaultPrevented) {
|
|
442
|
+
return
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
if (!activeElement || !nextElement) {
|
|
446
|
+
// Some weirdness is happening, so we bail
|
|
447
|
+
return
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
this._isSliding = true
|
|
451
|
+
|
|
452
|
+
if (isCycling) {
|
|
453
|
+
this.pause()
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
this._setActiveIndicatorElement(nextElement)
|
|
457
|
+
this._activeElement = nextElement
|
|
458
|
+
|
|
459
|
+
if (this._element.classList.contains(CLASS_NAME_SLIDE)) {
|
|
460
|
+
nextElement.classList.add(orderClassName)
|
|
461
|
+
|
|
462
|
+
reflow(nextElement)
|
|
463
|
+
|
|
464
|
+
activeElement.classList.add(directionalClassName)
|
|
465
|
+
nextElement.classList.add(directionalClassName)
|
|
466
|
+
|
|
467
|
+
const transitionDuration = getTransitionDurationFromElement(activeElement)
|
|
468
|
+
|
|
469
|
+
EventHandler.one(activeElement, 'transitionend', () => {
|
|
470
|
+
nextElement.classList.remove(directionalClassName, orderClassName)
|
|
471
|
+
nextElement.classList.add(CLASS_NAME_ACTIVE)
|
|
472
|
+
|
|
473
|
+
activeElement.classList.remove(CLASS_NAME_ACTIVE, orderClassName, directionalClassName)
|
|
474
|
+
|
|
475
|
+
this._isSliding = false
|
|
476
|
+
|
|
477
|
+
setTimeout(() => {
|
|
478
|
+
EventHandler.trigger(this._element, EVENT_SLID, {
|
|
479
|
+
relatedTarget: nextElement,
|
|
480
|
+
direction: eventDirectionName,
|
|
481
|
+
from: activeElementIndex,
|
|
482
|
+
to: nextElementIndex
|
|
483
|
+
})
|
|
484
|
+
}, 0)
|
|
485
|
+
})
|
|
486
|
+
|
|
487
|
+
emulateTransitionEnd(activeElement, transitionDuration)
|
|
488
|
+
} else {
|
|
489
|
+
activeElement.classList.remove(CLASS_NAME_ACTIVE)
|
|
490
|
+
nextElement.classList.add(CLASS_NAME_ACTIVE)
|
|
491
|
+
|
|
492
|
+
this._isSliding = false
|
|
493
|
+
EventHandler.trigger(this._element, EVENT_SLID, {
|
|
494
|
+
relatedTarget: nextElement,
|
|
495
|
+
direction: eventDirectionName,
|
|
496
|
+
from: activeElementIndex,
|
|
497
|
+
to: nextElementIndex
|
|
498
|
+
})
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (isCycling) {
|
|
502
|
+
this.cycle()
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
_directionToOrder(direction) {
|
|
507
|
+
if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) {
|
|
508
|
+
return direction
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
if (isRTL()) {
|
|
512
|
+
return direction === DIRECTION_RIGHT ? ORDER_PREV : ORDER_NEXT
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
return direction === DIRECTION_RIGHT ? ORDER_NEXT : ORDER_PREV
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
_orderToDirection(order) {
|
|
519
|
+
if (![ORDER_NEXT, ORDER_PREV].includes(order)) {
|
|
520
|
+
return order
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
if (isRTL()) {
|
|
524
|
+
return order === ORDER_NEXT ? DIRECTION_LEFT : DIRECTION_RIGHT
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
return order === ORDER_NEXT ? DIRECTION_RIGHT : DIRECTION_LEFT
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Static
|
|
531
|
+
|
|
532
|
+
static carouselInterface(element, config) {
|
|
533
|
+
let data = Data.get(element, DATA_KEY)
|
|
534
|
+
let _config = {
|
|
535
|
+
...Default,
|
|
536
|
+
...Manipulator.getDataAttributes(element)
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
if (typeof config === 'object') {
|
|
540
|
+
_config = {
|
|
541
|
+
..._config,
|
|
542
|
+
...config
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
const action = typeof config === 'string' ? config : _config.slide
|
|
547
|
+
|
|
548
|
+
if (!data) {
|
|
549
|
+
data = new Carousel(element, _config)
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
if (typeof config === 'number') {
|
|
553
|
+
data.to(config)
|
|
554
|
+
} else if (typeof action === 'string') {
|
|
555
|
+
if (typeof data[action] === 'undefined') {
|
|
556
|
+
throw new TypeError(`No method named "${action}"`)
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
data[action]()
|
|
560
|
+
} else if (_config.interval && _config.ride) {
|
|
561
|
+
data.pause()
|
|
562
|
+
data.cycle()
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
static jQueryInterface(config) {
|
|
567
|
+
return this.each(function () {
|
|
568
|
+
Carousel.carouselInterface(this, config)
|
|
569
|
+
})
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
static dataApiClickHandler(event) {
|
|
573
|
+
const target = getElementFromSelector(this)
|
|
574
|
+
|
|
575
|
+
if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
|
|
576
|
+
return
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
const config = {
|
|
580
|
+
...Manipulator.getDataAttributes(target),
|
|
581
|
+
...Manipulator.getDataAttributes(this)
|
|
582
|
+
}
|
|
583
|
+
const slideIndex = this.getAttribute('data-bs-slide-to')
|
|
584
|
+
|
|
585
|
+
if (slideIndex) {
|
|
586
|
+
config.interval = false
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
Carousel.carouselInterface(target, config)
|
|
590
|
+
|
|
591
|
+
if (slideIndex) {
|
|
592
|
+
Data.get(target, DATA_KEY).to(slideIndex)
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
event.preventDefault()
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* ------------------------------------------------------------------------
|
|
601
|
+
* Data Api implementation
|
|
602
|
+
* ------------------------------------------------------------------------
|
|
603
|
+
*/
|
|
604
|
+
|
|
605
|
+
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler)
|
|
606
|
+
|
|
607
|
+
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
|
608
|
+
const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE)
|
|
609
|
+
|
|
610
|
+
for (let i = 0, len = carousels.length; i < len; i++) {
|
|
611
|
+
Carousel.carouselInterface(carousels[i], Data.get(carousels[i], DATA_KEY))
|
|
612
|
+
}
|
|
613
|
+
})
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* ------------------------------------------------------------------------
|
|
617
|
+
* jQuery
|
|
618
|
+
* ------------------------------------------------------------------------
|
|
619
|
+
* add .Carousel to jQuery only if jQuery is present
|
|
620
|
+
*/
|
|
621
|
+
|
|
622
|
+
defineJQueryPlugin(NAME, Carousel)
|
|
623
|
+
|
|
624
|
+
export default Carousel
|