You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

429 lines
13KB

  1. /*!
  2. * bsStepper v1.7.0 (https://github.com/Johann-S/bs-stepper)
  3. * Copyright 2018 - 2019 Johann-S <johann.servoire@gmail.com>
  4. * Licensed under MIT (https://github.com/Johann-S/bs-stepper/blob/master/LICENSE)
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global = global || self, global.Stepper = factory());
  10. }(this, function () { 'use strict';
  11. function _extends() {
  12. _extends = Object.assign || function (target) {
  13. for (var i = 1; i < arguments.length; i++) {
  14. var source = arguments[i];
  15. for (var key in source) {
  16. if (Object.prototype.hasOwnProperty.call(source, key)) {
  17. target[key] = source[key];
  18. }
  19. }
  20. }
  21. return target;
  22. };
  23. return _extends.apply(this, arguments);
  24. }
  25. var matches = window.Element.prototype.matches;
  26. var closest = function closest(element, selector) {
  27. return element.closest(selector);
  28. };
  29. var WinEvent = function WinEvent(inType, params) {
  30. return new window.Event(inType, params);
  31. };
  32. var createCustomEvent = function createCustomEvent(eventName, params) {
  33. var cEvent = new window.CustomEvent(eventName, params);
  34. return cEvent;
  35. };
  36. /* istanbul ignore next */
  37. function polyfill() {
  38. if (!window.Element.prototype.matches) {
  39. matches = window.Element.prototype.msMatchesSelector || window.Element.prototype.webkitMatchesSelector;
  40. }
  41. if (!window.Element.prototype.closest) {
  42. closest = function closest(element, selector) {
  43. if (!document.documentElement.contains(element)) {
  44. return null;
  45. }
  46. do {
  47. if (matches.call(element, selector)) {
  48. return element;
  49. }
  50. element = element.parentElement || element.parentNode;
  51. } while (element !== null && element.nodeType === 1);
  52. return null;
  53. };
  54. }
  55. if (!window.Event || typeof window.Event !== 'function') {
  56. WinEvent = function WinEvent(inType, params) {
  57. params = params || {};
  58. var e = document.createEvent('Event');
  59. e.initEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable));
  60. return e;
  61. };
  62. }
  63. if (typeof window.CustomEvent !== 'function') {
  64. var originPreventDefault = window.Event.prototype.preventDefault;
  65. createCustomEvent = function createCustomEvent(eventName, params) {
  66. var evt = document.createEvent('CustomEvent');
  67. params = params || {
  68. bubbles: false,
  69. cancelable: false,
  70. detail: null
  71. };
  72. evt.initCustomEvent(eventName, params.bubbles, params.cancelable, params.detail);
  73. evt.preventDefault = function () {
  74. if (!this.cancelable) {
  75. return;
  76. }
  77. originPreventDefault.call(this);
  78. Object.defineProperty(this, 'defaultPrevented', {
  79. get: function get() {
  80. return true;
  81. }
  82. });
  83. };
  84. return evt;
  85. };
  86. }
  87. }
  88. polyfill();
  89. var MILLISECONDS_MULTIPLIER = 1000;
  90. var ClassName = {
  91. ACTIVE: 'active',
  92. LINEAR: 'linear',
  93. BLOCK: 'dstepper-block',
  94. NONE: 'dstepper-none',
  95. FADE: 'fade',
  96. VERTICAL: 'vertical'
  97. };
  98. var transitionEndEvent = 'transitionend';
  99. var customProperty = 'bsStepper';
  100. var show = function show(stepperNode, indexStep, options, done) {
  101. var stepper = stepperNode[customProperty];
  102. if (stepper._steps[indexStep].classList.contains(ClassName.ACTIVE) || stepper._stepsContents[indexStep].classList.contains(ClassName.ACTIVE)) {
  103. return;
  104. }
  105. var showEvent = createCustomEvent('show.bs-stepper', {
  106. cancelable: true,
  107. detail: {
  108. from: stepper._currentIndex,
  109. to: indexStep,
  110. indexStep: indexStep
  111. }
  112. });
  113. stepperNode.dispatchEvent(showEvent);
  114. var activeStep = stepper._steps.filter(function (step) {
  115. return step.classList.contains(ClassName.ACTIVE);
  116. });
  117. var activeContent = stepper._stepsContents.filter(function (content) {
  118. return content.classList.contains(ClassName.ACTIVE);
  119. });
  120. if (showEvent.defaultPrevented) {
  121. return;
  122. }
  123. if (activeStep.length) {
  124. activeStep[0].classList.remove(ClassName.ACTIVE);
  125. }
  126. if (activeContent.length) {
  127. activeContent[0].classList.remove(ClassName.ACTIVE);
  128. if (!stepperNode.classList.contains(ClassName.VERTICAL) && !stepper.options.animation) {
  129. activeContent[0].classList.remove(ClassName.BLOCK);
  130. }
  131. }
  132. showStep(stepperNode, stepper._steps[indexStep], stepper._steps, options);
  133. showContent(stepperNode, stepper._stepsContents[indexStep], stepper._stepsContents, activeContent, done);
  134. };
  135. var showStep = function showStep(stepperNode, step, stepList, options) {
  136. stepList.forEach(function (step) {
  137. var trigger = step.querySelector(options.selectors.trigger);
  138. trigger.setAttribute('aria-selected', 'false'); // if stepper is in linear mode, set disabled attribute on the trigger
  139. if (stepperNode.classList.contains(ClassName.LINEAR)) {
  140. trigger.setAttribute('disabled', 'disabled');
  141. }
  142. });
  143. step.classList.add(ClassName.ACTIVE);
  144. var currentTrigger = step.querySelector(options.selectors.trigger);
  145. currentTrigger.setAttribute('aria-selected', 'true'); // if stepper is in linear mode, remove disabled attribute on current
  146. if (stepperNode.classList.contains(ClassName.LINEAR)) {
  147. currentTrigger.removeAttribute('disabled');
  148. }
  149. };
  150. var showContent = function showContent(stepperNode, content, contentList, activeContent, done) {
  151. var stepper = stepperNode[customProperty];
  152. var toIndex = contentList.indexOf(content);
  153. var shownEvent = createCustomEvent('shown.bs-stepper', {
  154. cancelable: true,
  155. detail: {
  156. from: stepper._currentIndex,
  157. to: toIndex,
  158. indexStep: toIndex
  159. }
  160. });
  161. function complete() {
  162. content.classList.add(ClassName.BLOCK);
  163. content.removeEventListener(transitionEndEvent, complete);
  164. stepperNode.dispatchEvent(shownEvent);
  165. done();
  166. }
  167. if (content.classList.contains(ClassName.FADE)) {
  168. content.classList.remove(ClassName.NONE);
  169. var duration = getTransitionDurationFromElement(content);
  170. content.addEventListener(transitionEndEvent, complete);
  171. if (activeContent.length) {
  172. activeContent[0].classList.add(ClassName.NONE);
  173. }
  174. content.classList.add(ClassName.ACTIVE);
  175. emulateTransitionEnd(content, duration);
  176. } else {
  177. content.classList.add(ClassName.ACTIVE);
  178. content.classList.add(ClassName.BLOCK);
  179. stepperNode.dispatchEvent(shownEvent);
  180. done();
  181. }
  182. };
  183. var getTransitionDurationFromElement = function getTransitionDurationFromElement(element) {
  184. if (!element) {
  185. return 0;
  186. } // Get transition-duration of the element
  187. var transitionDuration = window.getComputedStyle(element).transitionDuration;
  188. var floatTransitionDuration = parseFloat(transitionDuration); // Return 0 if element or transition duration is not found
  189. if (!floatTransitionDuration) {
  190. return 0;
  191. } // If multiple durations are defined, take the first
  192. transitionDuration = transitionDuration.split(',')[0];
  193. return parseFloat(transitionDuration) * MILLISECONDS_MULTIPLIER;
  194. };
  195. var emulateTransitionEnd = function emulateTransitionEnd(element, duration) {
  196. var called = false;
  197. var durationPadding = 5;
  198. var emulatedDuration = duration + durationPadding;
  199. function listener() {
  200. called = true;
  201. element.removeEventListener(transitionEndEvent, listener);
  202. }
  203. element.addEventListener(transitionEndEvent, listener);
  204. window.setTimeout(function () {
  205. if (!called) {
  206. element.dispatchEvent(WinEvent(transitionEndEvent));
  207. }
  208. element.removeEventListener(transitionEndEvent, listener);
  209. }, emulatedDuration);
  210. };
  211. var detectAnimation = function detectAnimation(contentList, options) {
  212. if (options.animation) {
  213. contentList.forEach(function (content) {
  214. content.classList.add(ClassName.FADE);
  215. content.classList.add(ClassName.NONE);
  216. });
  217. }
  218. };
  219. var buildClickStepLinearListener = function buildClickStepLinearListener() {
  220. return function clickStepLinearListener(event) {
  221. event.preventDefault();
  222. };
  223. };
  224. var buildClickStepNonLinearListener = function buildClickStepNonLinearListener(options) {
  225. return function clickStepNonLinearListener(event) {
  226. event.preventDefault();
  227. var step = closest(event.target, options.selectors.steps);
  228. var stepperNode = closest(step, options.selectors.stepper);
  229. var stepper = stepperNode[customProperty];
  230. var stepIndex = stepper._steps.indexOf(step);
  231. show(stepperNode, stepIndex, options, function () {
  232. stepper._currentIndex = stepIndex;
  233. });
  234. };
  235. };
  236. var DEFAULT_OPTIONS = {
  237. linear: true,
  238. animation: false,
  239. selectors: {
  240. steps: '.step',
  241. trigger: '.step-trigger',
  242. stepper: '.bs-stepper'
  243. }
  244. };
  245. var Stepper =
  246. /*#__PURE__*/
  247. function () {
  248. function Stepper(element, _options) {
  249. var _this = this;
  250. if (_options === void 0) {
  251. _options = {};
  252. }
  253. this._element = element;
  254. this._currentIndex = 0;
  255. this._stepsContents = [];
  256. this.options = _extends({}, DEFAULT_OPTIONS, {}, _options);
  257. this.options.selectors = _extends({}, DEFAULT_OPTIONS.selectors, {}, this.options.selectors);
  258. if (this.options.linear) {
  259. this._element.classList.add(ClassName.LINEAR);
  260. }
  261. this._steps = [].slice.call(this._element.querySelectorAll(this.options.selectors.steps));
  262. this._steps.filter(function (step) {
  263. return step.hasAttribute('data-target');
  264. }).forEach(function (step) {
  265. _this._stepsContents.push(_this._element.querySelector(step.getAttribute('data-target')));
  266. });
  267. detectAnimation(this._stepsContents, this.options);
  268. this._setLinkListeners();
  269. Object.defineProperty(this._element, customProperty, {
  270. value: this,
  271. writable: true
  272. });
  273. if (this._steps.length) {
  274. show(this._element, this._currentIndex, this.options, function () {});
  275. }
  276. } // Private
  277. var _proto = Stepper.prototype;
  278. _proto._setLinkListeners = function _setLinkListeners() {
  279. var _this2 = this;
  280. this._steps.forEach(function (step) {
  281. var trigger = step.querySelector(_this2.options.selectors.trigger);
  282. if (_this2.options.linear) {
  283. _this2._clickStepLinearListener = buildClickStepLinearListener(_this2.options);
  284. trigger.addEventListener('click', _this2._clickStepLinearListener);
  285. } else {
  286. _this2._clickStepNonLinearListener = buildClickStepNonLinearListener(_this2.options);
  287. trigger.addEventListener('click', _this2._clickStepNonLinearListener);
  288. }
  289. });
  290. } // Public
  291. ;
  292. _proto.next = function next() {
  293. var _this3 = this;
  294. var nextStep = this._currentIndex + 1 <= this._steps.length - 1 ? this._currentIndex + 1 : this._steps.length - 1;
  295. show(this._element, nextStep, this.options, function () {
  296. _this3._currentIndex = nextStep;
  297. });
  298. };
  299. _proto.previous = function previous() {
  300. var _this4 = this;
  301. var previousStep = this._currentIndex - 1 >= 0 ? this._currentIndex - 1 : 0;
  302. show(this._element, previousStep, this.options, function () {
  303. _this4._currentIndex = previousStep;
  304. });
  305. };
  306. _proto.to = function to(stepNumber) {
  307. var _this5 = this;
  308. var tempIndex = stepNumber - 1;
  309. var nextStep = tempIndex >= 0 && tempIndex < this._steps.length ? tempIndex : 0;
  310. show(this._element, nextStep, this.options, function () {
  311. _this5._currentIndex = nextStep;
  312. });
  313. };
  314. _proto.reset = function reset() {
  315. var _this6 = this;
  316. show(this._element, 0, this.options, function () {
  317. _this6._currentIndex = 0;
  318. });
  319. };
  320. _proto.destroy = function destroy() {
  321. var _this7 = this;
  322. this._steps.forEach(function (step) {
  323. var trigger = step.querySelector(_this7.options.selectors.trigger);
  324. if (_this7.options.linear) {
  325. trigger.removeEventListener('click', _this7._clickStepLinearListener);
  326. } else {
  327. trigger.removeEventListener('click', _this7._clickStepNonLinearListener);
  328. }
  329. });
  330. this._element[customProperty] = undefined;
  331. this._element = undefined;
  332. this._currentIndex = undefined;
  333. this._steps = undefined;
  334. this._stepsContents = undefined;
  335. this._clickStepLinearListener = undefined;
  336. this._clickStepNonLinearListener = undefined;
  337. };
  338. return Stepper;
  339. }();
  340. return Stepper;
  341. }));
  342. //# sourceMappingURL=bs-stepper.js.map