slider.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import _extends from "@babel/runtime/helpers/esm/extends";
  3. import { resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue";
  4. import json2mq from '../_util/json2mq';
  5. import BaseMixin from '../_util/BaseMixin';
  6. import { cloneElement } from '../_util/vnode';
  7. import InnerSlider from './inner-slider';
  8. import defaultProps from './default-props';
  9. import { canUseDOM } from './utils/innerSliderUtils';
  10. import { getSlot } from '../_util/props-util';
  11. import { defineComponent } from 'vue';
  12. export default defineComponent({
  13. name: 'Slider',
  14. mixins: [BaseMixin],
  15. inheritAttrs: false,
  16. props: _extends({}, defaultProps),
  17. data() {
  18. this._responsiveMediaHandlers = [];
  19. return {
  20. breakpoint: null
  21. };
  22. },
  23. // handles responsive breakpoints
  24. mounted() {
  25. if (this.responsive) {
  26. const breakpoints = this.responsive.map(breakpt => breakpt.breakpoint);
  27. // sort them in increasing order of their numerical value
  28. breakpoints.sort((x, y) => x - y);
  29. breakpoints.forEach((breakpoint, index) => {
  30. // media query for each breakpoint
  31. let bQuery;
  32. if (index === 0) {
  33. bQuery = json2mq({
  34. minWidth: 0,
  35. maxWidth: breakpoint
  36. });
  37. } else {
  38. bQuery = json2mq({
  39. minWidth: breakpoints[index - 1] + 1,
  40. maxWidth: breakpoint
  41. });
  42. }
  43. // when not using server side rendering
  44. canUseDOM() && this.media(bQuery, () => {
  45. this.setState({
  46. breakpoint
  47. });
  48. });
  49. });
  50. // Register media query for full screen. Need to support resize from small to large
  51. // convert javascript object to media query string
  52. const query = json2mq({
  53. minWidth: breakpoints.slice(-1)[0]
  54. });
  55. canUseDOM() && this.media(query, () => {
  56. this.setState({
  57. breakpoint: null
  58. });
  59. });
  60. }
  61. },
  62. beforeUnmount() {
  63. this._responsiveMediaHandlers.forEach(function (obj) {
  64. obj.mql.removeListener(obj.listener);
  65. });
  66. },
  67. methods: {
  68. innerSliderRefHandler(ref) {
  69. this.innerSlider = ref;
  70. },
  71. media(query, handler) {
  72. // javascript handler for css media query
  73. const mql = window.matchMedia(query);
  74. const listener = _ref => {
  75. let {
  76. matches
  77. } = _ref;
  78. if (matches) {
  79. handler();
  80. }
  81. };
  82. mql.addListener(listener);
  83. listener(mql);
  84. this._responsiveMediaHandlers.push({
  85. mql,
  86. query,
  87. listener
  88. });
  89. },
  90. slickPrev() {
  91. var _a;
  92. (_a = this.innerSlider) === null || _a === void 0 ? void 0 : _a.slickPrev();
  93. },
  94. slickNext() {
  95. var _a;
  96. (_a = this.innerSlider) === null || _a === void 0 ? void 0 : _a.slickNext();
  97. },
  98. slickGoTo(slide) {
  99. let dontAnimate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  100. var _a;
  101. (_a = this.innerSlider) === null || _a === void 0 ? void 0 : _a.slickGoTo(slide, dontAnimate);
  102. },
  103. slickPause() {
  104. var _a;
  105. (_a = this.innerSlider) === null || _a === void 0 ? void 0 : _a.pause('paused');
  106. },
  107. slickPlay() {
  108. var _a;
  109. (_a = this.innerSlider) === null || _a === void 0 ? void 0 : _a.handleAutoPlay('play');
  110. }
  111. },
  112. render() {
  113. var _a;
  114. let settings;
  115. let newProps;
  116. if (this.breakpoint) {
  117. newProps = this.responsive.filter(resp => resp.breakpoint === this.breakpoint);
  118. settings = newProps[0].settings === 'unslick' ? 'unslick' : _extends(_extends({}, this.$props), newProps[0].settings);
  119. } else {
  120. settings = _extends({}, this.$props);
  121. }
  122. // force scrolling by one if centerMode is on
  123. if (settings.centerMode) {
  124. if (settings.slidesToScroll > 1 && process.env.NODE_ENV !== 'production') {
  125. console.warn(`slidesToScroll should be equal to 1 in centerMode, you are using ${settings.slidesToScroll}`);
  126. }
  127. settings.slidesToScroll = 1;
  128. }
  129. // force showing one slide and scrolling by one if the fade mode is on
  130. if (settings.fade) {
  131. if (settings.slidesToShow > 1 && process.env.NODE_ENV !== 'production') {
  132. console.warn(`slidesToShow should be equal to 1 when fade is true, you're using ${settings.slidesToShow}`);
  133. }
  134. if (settings.slidesToScroll > 1 && process.env.NODE_ENV !== 'production') {
  135. console.warn(`slidesToScroll should be equal to 1 when fade is true, you're using ${settings.slidesToScroll}`);
  136. }
  137. settings.slidesToShow = 1;
  138. settings.slidesToScroll = 1;
  139. }
  140. // makes sure that children is an array, even when there is only 1 child
  141. let children = getSlot(this) || [];
  142. // Children may contain false or null, so we should filter them
  143. // children may also contain string filled with spaces (in certain cases where we use jsx strings)
  144. children = children.filter(child => {
  145. if (typeof child === 'string') {
  146. return !!child.trim();
  147. }
  148. return !!child;
  149. });
  150. // rows and slidesPerRow logic is handled here
  151. if (settings.variableWidth && (settings.rows > 1 || settings.slidesPerRow > 1)) {
  152. console.warn(`variableWidth is not supported in case of rows > 1 or slidesPerRow > 1`);
  153. settings.variableWidth = false;
  154. }
  155. const newChildren = [];
  156. let currentWidth = null;
  157. for (let i = 0; i < children.length; i += settings.rows * settings.slidesPerRow) {
  158. const newSlide = [];
  159. for (let j = i; j < i + settings.rows * settings.slidesPerRow; j += settings.slidesPerRow) {
  160. const row = [];
  161. for (let k = j; k < j + settings.slidesPerRow; k += 1) {
  162. if (settings.variableWidth && ((_a = children[k].props) === null || _a === void 0 ? void 0 : _a.style)) {
  163. currentWidth = children[k].props.style.width;
  164. }
  165. if (k >= children.length) break;
  166. row.push(cloneElement(children[k], {
  167. key: 100 * i + 10 * j + k,
  168. tabindex: -1,
  169. style: {
  170. width: `${100 / settings.slidesPerRow}%`,
  171. display: 'inline-block'
  172. }
  173. }));
  174. }
  175. newSlide.push(_createVNode("div", {
  176. "key": 10 * i + j
  177. }, [row]));
  178. }
  179. if (settings.variableWidth) {
  180. newChildren.push(_createVNode("div", {
  181. "key": i,
  182. "style": {
  183. width: currentWidth
  184. }
  185. }, [newSlide]));
  186. } else {
  187. newChildren.push(_createVNode("div", {
  188. "key": i
  189. }, [newSlide]));
  190. }
  191. }
  192. if (settings === 'unslick') {
  193. const className = 'regular slider ' + (this.className || '');
  194. return _createVNode("div", {
  195. "class": className
  196. }, [children]);
  197. } else if (newChildren.length <= settings.slidesToShow) {
  198. settings.unslick = true;
  199. }
  200. const sliderProps = _extends(_extends(_extends({}, this.$attrs), settings), {
  201. children: newChildren,
  202. ref: this.innerSliderRefHandler
  203. });
  204. return _createVNode(InnerSlider, _objectSpread(_objectSpread({}, sliderProps), {}, {
  205. "__propsSymbol__": []
  206. }), this.$slots);
  207. }
  208. });