naive-ui 2.23.2 → 2.24.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 (314) hide show
  1. package/README.md +1 -1
  2. package/README.zh-CN.md +1 -1
  3. package/es/_internal/icons/Switcher.js +2 -3
  4. package/es/_internal/selection/src/styles/index.cssr.js +1 -1
  5. package/es/_internal/selection/styles/_common.js +1 -1
  6. package/es/auto-complete/src/AutoComplete.d.ts +12 -12
  7. package/es/auto-complete/src/AutoComplete.js +13 -15
  8. package/es/back-top/src/BackTop.d.ts +3 -3
  9. package/es/calendar/src/Calendar.d.ts +5 -1
  10. package/es/calendar/src/Calendar.js +16 -4
  11. package/es/calendar/src/interface.d.ts +4 -0
  12. package/es/carousel/index.d.ts +1 -0
  13. package/es/carousel/index.js +1 -0
  14. package/es/carousel/src/Carousel.d.ts +235 -19
  15. package/es/carousel/src/Carousel.js +683 -229
  16. package/es/carousel/src/CarouselArrow.d.ts +9 -0
  17. package/es/carousel/src/CarouselArrow.js +43 -0
  18. package/es/carousel/src/CarouselDots.d.ts +66 -0
  19. package/es/carousel/src/CarouselDots.js +118 -0
  20. package/es/carousel/src/CarouselItem.d.ts +11 -0
  21. package/es/carousel/src/CarouselItem.js +72 -0
  22. package/es/carousel/src/interface.d.ts +28 -0
  23. package/es/carousel/src/interface.js +2 -0
  24. package/es/carousel/src/styles/index.cssr.js +141 -38
  25. package/es/carousel/src/utils.d.ts +12 -0
  26. package/es/carousel/src/utils.js +58 -0
  27. package/es/carousel/styles/light.d.ts +3 -0
  28. package/es/carousel/styles/light.js +5 -2
  29. package/es/cascader/src/Cascader.d.ts +6 -2
  30. package/es/cascader/src/Cascader.js +2 -1
  31. package/es/cascader/src/CascaderOption.d.ts +1 -0
  32. package/es/cascader/src/CascaderOption.js +7 -4
  33. package/es/cascader/src/interface.d.ts +2 -1
  34. package/es/checkbox/src/styles/index.cssr.js +1 -1
  35. package/es/code/src/Code.d.ts +5 -0
  36. package/es/code/src/Code.js +6 -3
  37. package/es/code/src/styles/index.cssr.js +2 -2
  38. package/es/color-picker/src/ColorInputUnit.js +2 -2
  39. package/es/color-picker/src/ColorPicker.d.ts +13 -5
  40. package/es/color-picker/src/ColorPicker.js +19 -10
  41. package/es/color-picker/src/ColorPickerTrigger.d.ts +1 -1
  42. package/es/color-picker/src/ColorPickerTrigger.js +23 -17
  43. package/es/color-picker/src/interface.d.ts +2 -0
  44. package/es/color-picker/src/styles/index.cssr.js +1 -0
  45. package/es/config-provider/src/ConfigProvider.d.ts +27 -0
  46. package/es/data-table/src/DataTable.d.ts +10 -55
  47. package/es/data-table/src/DataTable.js +23 -49
  48. package/es/data-table/src/interface.d.ts +1 -1
  49. package/es/data-table/src/styles/index.cssr.js +4 -1
  50. package/es/data-table/src/utils.js +4 -1
  51. package/es/date-picker/src/DatePicker.d.ts +26 -22
  52. package/es/date-picker/src/DatePicker.js +99 -49
  53. package/es/date-picker/src/interface.d.ts +17 -2
  54. package/es/date-picker/src/panel/use-calendar.js +2 -2
  55. package/es/drawer/src/Drawer.d.ts +18 -58
  56. package/es/drawer/src/Drawer.js +32 -49
  57. package/es/drawer/src/DrawerBodyWrapper.js +21 -13
  58. package/es/drawer/src/DrawerContent.js +6 -6
  59. package/es/dropdown/src/Dropdown.d.ts +5 -0
  60. package/es/form/src/Feedbacks.js +4 -1
  61. package/es/form/src/Form.d.ts +7 -7
  62. package/es/form/src/Form.js +17 -8
  63. package/es/form/src/FormItem.d.ts +12 -7
  64. package/es/form/src/FormItem.js +24 -12
  65. package/es/form/src/FormItemCol.d.ts +8 -4
  66. package/es/form/src/FormItemGridItem.d.ts +8 -4
  67. package/es/form/src/FormItemRow.d.ts +7 -3
  68. package/es/form/src/interface.d.ts +6 -2
  69. package/es/form/src/styles/form-item.cssr.js +2 -0
  70. package/es/form/src/utils.d.ts +2 -2
  71. package/es/form/src/utils.js +29 -18
  72. package/es/image/src/Image.d.ts +279 -10
  73. package/es/image/src/Image.js +4 -17
  74. package/es/image/src/ImageGroup.d.ts +272 -2
  75. package/es/image/src/ImageGroup.js +5 -8
  76. package/es/image/src/ImagePreview.d.ts +195 -7
  77. package/es/image/src/ImagePreview.js +50 -31
  78. package/es/image/src/interface.d.ts +94 -0
  79. package/es/image/src/interface.js +2 -1
  80. package/es/image/src/styles/index.cssr.js +8 -4
  81. package/es/image/styles/dark.js +8 -1
  82. package/es/image/styles/light.d.ts +32 -3
  83. package/es/image/styles/light.js +8 -1
  84. package/es/input-number/src/utils.js +2 -2
  85. package/es/locales/common/deDE.js +10 -0
  86. package/es/locales/common/enUS.d.ts +9 -0
  87. package/es/locales/common/enUS.js +10 -0
  88. package/es/locales/common/frFR.js +10 -0
  89. package/es/locales/common/idID.js +10 -0
  90. package/es/locales/common/jaJP.js +10 -0
  91. package/es/locales/common/nbNO.js +10 -0
  92. package/es/locales/common/ruRU.js +10 -0
  93. package/es/locales/common/ukUA.js +10 -0
  94. package/es/locales/common/zhCN.js +9 -0
  95. package/es/locales/common/zhTW.js +10 -0
  96. package/es/mention/src/utils.js +0 -1
  97. package/es/message/index.d.ts +2 -1
  98. package/es/message/src/Message.d.ts +191 -19
  99. package/es/message/src/Message.js +13 -11
  100. package/es/message/src/MessageEnvironment.d.ts +3 -3
  101. package/es/message/src/MessageProvider.d.ts +5 -10
  102. package/es/message/src/MessageProvider.js +1 -1
  103. package/es/message/src/message-props.d.ts +5 -2
  104. package/es/message/src/types.d.ts +15 -0
  105. package/es/message/src/types.js +1 -0
  106. package/es/modal/src/Modal.d.ts +5 -0
  107. package/es/modal/src/Modal.js +2 -1
  108. package/es/page-header/index.d.ts +1 -1
  109. package/es/page-header/src/PageHeader.d.ts +1 -1
  110. package/es/pagination/index.d.ts +1 -1
  111. package/es/pagination/src/Pagination.d.ts +8 -4
  112. package/es/pagination/src/Pagination.js +66 -19
  113. package/es/pagination/src/interface.d.ts +10 -1
  114. package/es/pagination/src/utils.d.ts +2 -2
  115. package/es/pagination/src/utils.js +2 -4
  116. package/es/popconfirm/src/Popconfirm.d.ts +5 -0
  117. package/es/popover/src/Popover.d.ts +7 -0
  118. package/es/popover/src/Popover.js +24 -1
  119. package/es/popover/src/PopoverBody.d.ts +5 -0
  120. package/es/popover/src/PopoverBody.js +28 -46
  121. package/es/popover/src/styles/index.cssr.js +9 -8
  122. package/es/popselect/src/Popselect.d.ts +62 -73
  123. package/es/popselect/src/Popselect.js +2 -2
  124. package/es/progress/src/Circle.d.ts +7 -0
  125. package/es/progress/src/Circle.js +8 -1
  126. package/es/progress/src/Line.d.ts +2 -2
  127. package/es/progress/src/Line.js +4 -1
  128. package/es/progress/src/Progress.d.ts +6 -2
  129. package/es/progress/src/Progress.js +2 -2
  130. package/es/progress/src/styles/index.cssr.js +16 -16
  131. package/es/radio/src/styles/radio.cssr.js +4 -1
  132. package/es/result/src/Result.js +9 -10
  133. package/es/result/src/styles/index.cssr.js +7 -7
  134. package/es/select/src/Select.d.ts +8 -27
  135. package/es/select/src/Select.js +16 -24
  136. package/es/slider/src/Slider.d.ts +2 -4
  137. package/es/tabs/index.d.ts +1 -0
  138. package/es/tabs/src/Tabs.d.ts +2 -2
  139. package/es/tabs/src/Tabs.js +25 -22
  140. package/es/tabs/src/interface.d.ts +3 -0
  141. package/es/time-picker/src/TimePicker.d.ts +22 -2
  142. package/es/time-picker/src/TimePicker.js +59 -29
  143. package/es/time-picker/src/interface.d.ts +4 -2
  144. package/es/tooltip/src/Tooltip.d.ts +5 -0
  145. package/es/tree/src/Tree.d.ts +5 -1
  146. package/es/tree/src/Tree.js +4 -2
  147. package/es/tree/src/TreeNodeSwitcher.d.ts +1 -1
  148. package/es/tree/src/TreeNodeSwitcher.js +25 -14
  149. package/es/tree/src/interface.d.ts +2 -0
  150. package/es/tree/src/styles/index.cssr.js +4 -2
  151. package/es/upload/src/Upload.d.ts +15 -6
  152. package/es/upload/src/Upload.js +18 -9
  153. package/es/upload/src/UploadFile.d.ts +5 -5
  154. package/es/upload/src/UploadFileList.js +2 -2
  155. package/es/upload/src/interface.d.ts +11 -4
  156. package/es/version.d.ts +1 -1
  157. package/es/version.js +1 -1
  158. package/lib/_internal/icons/Switcher.js +2 -3
  159. package/lib/_internal/selection/src/styles/index.cssr.js +1 -1
  160. package/lib/_internal/selection/styles/_common.js +1 -1
  161. package/lib/auto-complete/src/AutoComplete.d.ts +12 -12
  162. package/lib/auto-complete/src/AutoComplete.js +14 -16
  163. package/lib/back-top/src/BackTop.d.ts +3 -3
  164. package/lib/calendar/src/Calendar.d.ts +5 -1
  165. package/lib/calendar/src/Calendar.js +15 -3
  166. package/lib/calendar/src/interface.d.ts +4 -0
  167. package/lib/carousel/index.d.ts +1 -0
  168. package/lib/carousel/index.js +3 -1
  169. package/lib/carousel/src/Carousel.d.ts +235 -19
  170. package/lib/carousel/src/Carousel.js +681 -227
  171. package/lib/carousel/src/CarouselArrow.d.ts +9 -0
  172. package/lib/carousel/src/CarouselArrow.js +45 -0
  173. package/lib/carousel/src/CarouselDots.d.ts +66 -0
  174. package/lib/carousel/src/CarouselDots.js +120 -0
  175. package/lib/carousel/src/CarouselItem.d.ts +11 -0
  176. package/lib/carousel/src/CarouselItem.js +74 -0
  177. package/lib/carousel/src/interface.d.ts +28 -0
  178. package/lib/carousel/src/interface.js +6 -0
  179. package/lib/carousel/src/styles/index.cssr.js +141 -38
  180. package/lib/carousel/src/utils.d.ts +12 -0
  181. package/lib/carousel/src/utils.js +69 -0
  182. package/lib/carousel/styles/light.d.ts +3 -0
  183. package/lib/carousel/styles/light.js +5 -2
  184. package/lib/cascader/src/Cascader.d.ts +6 -2
  185. package/lib/cascader/src/Cascader.js +2 -1
  186. package/lib/cascader/src/CascaderOption.d.ts +1 -0
  187. package/lib/cascader/src/CascaderOption.js +7 -4
  188. package/lib/cascader/src/interface.d.ts +2 -1
  189. package/lib/checkbox/src/styles/index.cssr.js +1 -1
  190. package/lib/code/src/Code.d.ts +5 -0
  191. package/lib/code/src/Code.js +6 -3
  192. package/lib/code/src/styles/index.cssr.js +1 -1
  193. package/lib/color-picker/src/ColorInputUnit.js +1 -1
  194. package/lib/color-picker/src/ColorPicker.d.ts +13 -5
  195. package/lib/color-picker/src/ColorPicker.js +19 -10
  196. package/lib/color-picker/src/ColorPickerTrigger.d.ts +1 -1
  197. package/lib/color-picker/src/ColorPickerTrigger.js +22 -16
  198. package/lib/color-picker/src/interface.d.ts +2 -0
  199. package/lib/color-picker/src/styles/index.cssr.js +1 -0
  200. package/lib/config-provider/src/ConfigProvider.d.ts +27 -0
  201. package/lib/data-table/src/DataTable.d.ts +10 -55
  202. package/lib/data-table/src/DataTable.js +21 -47
  203. package/lib/data-table/src/interface.d.ts +1 -1
  204. package/lib/data-table/src/styles/index.cssr.js +4 -1
  205. package/lib/data-table/src/utils.js +3 -0
  206. package/lib/date-picker/src/DatePicker.d.ts +26 -22
  207. package/lib/date-picker/src/DatePicker.js +98 -48
  208. package/lib/date-picker/src/interface.d.ts +17 -2
  209. package/lib/date-picker/src/panel/use-calendar.js +2 -2
  210. package/lib/drawer/src/Drawer.d.ts +18 -58
  211. package/lib/drawer/src/Drawer.js +30 -47
  212. package/lib/drawer/src/DrawerBodyWrapper.js +21 -13
  213. package/lib/drawer/src/DrawerContent.js +6 -6
  214. package/lib/dropdown/src/Dropdown.d.ts +5 -0
  215. package/lib/form/src/Feedbacks.js +4 -1
  216. package/lib/form/src/Form.d.ts +7 -7
  217. package/lib/form/src/Form.js +16 -7
  218. package/lib/form/src/FormItem.d.ts +12 -7
  219. package/lib/form/src/FormItem.js +23 -11
  220. package/lib/form/src/FormItemCol.d.ts +8 -4
  221. package/lib/form/src/FormItemGridItem.d.ts +8 -4
  222. package/lib/form/src/FormItemRow.d.ts +7 -3
  223. package/lib/form/src/interface.d.ts +6 -2
  224. package/lib/form/src/styles/form-item.cssr.js +2 -0
  225. package/lib/form/src/utils.d.ts +2 -2
  226. package/lib/form/src/utils.js +29 -18
  227. package/lib/image/src/Image.d.ts +279 -10
  228. package/lib/image/src/Image.js +4 -17
  229. package/lib/image/src/ImageGroup.d.ts +272 -2
  230. package/lib/image/src/ImageGroup.js +4 -7
  231. package/lib/image/src/ImagePreview.d.ts +195 -7
  232. package/lib/image/src/ImagePreview.js +49 -30
  233. package/lib/image/src/interface.d.ts +94 -0
  234. package/lib/image/src/interface.js +3 -0
  235. package/lib/image/src/styles/index.cssr.js +8 -4
  236. package/lib/image/styles/dark.js +8 -1
  237. package/lib/image/styles/light.d.ts +32 -3
  238. package/lib/image/styles/light.js +8 -1
  239. package/lib/input-number/src/utils.js +2 -2
  240. package/lib/locales/common/deDE.js +10 -0
  241. package/lib/locales/common/enUS.d.ts +9 -0
  242. package/lib/locales/common/enUS.js +10 -0
  243. package/lib/locales/common/frFR.js +10 -0
  244. package/lib/locales/common/idID.js +10 -0
  245. package/lib/locales/common/jaJP.js +10 -0
  246. package/lib/locales/common/nbNO.js +10 -0
  247. package/lib/locales/common/ruRU.js +10 -0
  248. package/lib/locales/common/ukUA.js +10 -0
  249. package/lib/locales/common/zhCN.js +9 -0
  250. package/lib/locales/common/zhTW.js +10 -0
  251. package/lib/mention/src/utils.js +0 -1
  252. package/lib/message/index.d.ts +2 -1
  253. package/lib/message/src/Message.d.ts +191 -19
  254. package/lib/message/src/Message.js +13 -11
  255. package/lib/message/src/MessageEnvironment.d.ts +3 -3
  256. package/lib/message/src/MessageProvider.d.ts +5 -10
  257. package/lib/message/src/MessageProvider.js +1 -1
  258. package/lib/message/src/message-props.d.ts +5 -2
  259. package/lib/message/src/types.d.ts +15 -0
  260. package/lib/message/src/types.js +2 -0
  261. package/lib/modal/src/Modal.d.ts +5 -0
  262. package/lib/modal/src/Modal.js +2 -1
  263. package/lib/page-header/index.d.ts +1 -1
  264. package/lib/page-header/src/PageHeader.d.ts +1 -1
  265. package/lib/pagination/index.d.ts +1 -1
  266. package/lib/pagination/src/Pagination.d.ts +8 -4
  267. package/lib/pagination/src/Pagination.js +65 -18
  268. package/lib/pagination/src/interface.d.ts +10 -1
  269. package/lib/pagination/src/utils.d.ts +2 -2
  270. package/lib/pagination/src/utils.js +2 -4
  271. package/lib/popconfirm/src/Popconfirm.d.ts +5 -0
  272. package/lib/popover/src/Popover.d.ts +7 -0
  273. package/lib/popover/src/Popover.js +23 -0
  274. package/lib/popover/src/PopoverBody.d.ts +5 -0
  275. package/lib/popover/src/PopoverBody.js +27 -45
  276. package/lib/popover/src/styles/index.cssr.js +9 -8
  277. package/lib/popselect/src/Popselect.d.ts +62 -73
  278. package/lib/popselect/src/Popselect.js +2 -2
  279. package/lib/progress/src/Circle.d.ts +7 -0
  280. package/lib/progress/src/Circle.js +8 -1
  281. package/lib/progress/src/Line.d.ts +2 -2
  282. package/lib/progress/src/Line.js +4 -1
  283. package/lib/progress/src/Progress.d.ts +6 -2
  284. package/lib/progress/src/Progress.js +2 -2
  285. package/lib/progress/src/styles/index.cssr.js +16 -16
  286. package/lib/radio/src/styles/radio.cssr.js +4 -1
  287. package/lib/result/src/Result.js +8 -9
  288. package/lib/result/src/styles/index.cssr.js +6 -6
  289. package/lib/select/src/Select.d.ts +8 -27
  290. package/lib/select/src/Select.js +14 -22
  291. package/lib/slider/src/Slider.d.ts +2 -4
  292. package/lib/tabs/index.d.ts +1 -0
  293. package/lib/tabs/src/Tabs.d.ts +2 -2
  294. package/lib/tabs/src/Tabs.js +25 -22
  295. package/lib/tabs/src/interface.d.ts +3 -0
  296. package/lib/time-picker/src/TimePicker.d.ts +22 -2
  297. package/lib/time-picker/src/TimePicker.js +59 -29
  298. package/lib/time-picker/src/interface.d.ts +4 -2
  299. package/lib/tooltip/src/Tooltip.d.ts +5 -0
  300. package/lib/tree/src/Tree.d.ts +5 -1
  301. package/lib/tree/src/Tree.js +4 -2
  302. package/lib/tree/src/TreeNodeSwitcher.d.ts +1 -1
  303. package/lib/tree/src/TreeNodeSwitcher.js +24 -13
  304. package/lib/tree/src/interface.d.ts +2 -0
  305. package/lib/tree/src/styles/index.cssr.js +4 -2
  306. package/lib/upload/src/Upload.d.ts +15 -6
  307. package/lib/upload/src/Upload.js +18 -9
  308. package/lib/upload/src/UploadFile.d.ts +5 -5
  309. package/lib/upload/src/UploadFileList.js +2 -2
  310. package/lib/upload/src/interface.d.ts +11 -4
  311. package/lib/version.d.ts +1 -1
  312. package/lib/version.js +1 -1
  313. package/package.json +21 -13
  314. package/web-types.json +413 -31
@@ -1,301 +1,755 @@
1
- import { h, defineComponent, ref, toRef, cloneVNode, nextTick, computed, onMounted, watchEffect, onBeforeUnmount } from 'vue';
2
- import { indexMap } from 'seemly';
1
+ import { h, defineComponent, ref, provide, cloneVNode, computed, onBeforeUnmount, watch, withDirectives, vShow, Transition, toRef, nextTick, onMounted, watchEffect, onUpdated } from 'vue';
2
+ import { VResizeObserver } from 'vueuc';
3
3
  import { on, off } from 'evtd';
4
- import { BackwardIcon, ForwardIcon } from '../../_internal/icons';
5
4
  import { useConfig, useTheme } from '../../_mixins';
6
- import { flatten } from '../../_utils';
5
+ import { flatten, keep } from '../../_utils';
7
6
  import { carouselLight } from '../styles';
7
+ import { calculateSize, getNextIndex, getPrevIndex, getDisplayIndex, getRealIndex, isTouchEvent, clampValue, resolveSpeed } from './utils';
8
+ import NCarouselDots from './CarouselDots';
9
+ import NCarouselArrow from './CarouselArrow';
10
+ import NCarouselItem from './CarouselItem';
11
+ import { carouselMethodsInjectionKey, tuple } from './interface';
8
12
  import style from './styles/index.cssr';
9
- const carouselProps = Object.assign(Object.assign({}, useTheme.props), { showArrow: Boolean, autoplay: Boolean, dotPlacement: {
13
+ const transitionProperties = tuple('transitionDuration', 'transitionTimingFunction');
14
+ const carouselProps = Object.assign(Object.assign({}, useTheme.props), { defaultIndex: {
15
+ type: Number,
16
+ default: 0
17
+ }, currentIndex: Number, showArrow: Boolean, dotType: {
18
+ type: String,
19
+ default: 'dot'
20
+ }, dotPlacement: {
10
21
  type: String,
11
22
  default: 'bottom'
12
- }, interval: {
23
+ }, slidesPerView: {
24
+ type: [Number, String],
25
+ default: 1
26
+ }, spaceBetween: {
27
+ type: Number,
28
+ default: 0
29
+ }, centeredSlides: Boolean, direction: {
30
+ type: String,
31
+ default: 'horizontal'
32
+ }, autoplay: Boolean, interval: {
13
33
  type: Number,
14
34
  default: 5000
35
+ }, loop: {
36
+ type: Boolean,
37
+ default: true
38
+ }, effect: {
39
+ type: String,
40
+ default: 'slide'
41
+ }, showDots: {
42
+ type: Boolean,
43
+ default: true
15
44
  }, trigger: {
16
45
  type: String,
17
46
  default: 'click'
18
- } });
47
+ }, transitionStyle: {
48
+ type: Object,
49
+ default: () => ({
50
+ transitionDuration: '300ms'
51
+ })
52
+ }, transitionProps: Object, draggable: Boolean, touchable: {
53
+ type: Boolean,
54
+ default: true
55
+ }, mousewheel: Boolean, keyboard: Boolean, 'onUpdate:currentIndex': Function, onUpdateCurrentIndex: Function });
56
+ // only one carousel is allowed to trigger touch globally
57
+ let globalDragging = false;
19
58
  export default defineComponent({
20
59
  name: 'Carousel',
21
60
  props: carouselProps,
22
61
  setup(props) {
23
62
  const { mergedClsPrefixRef } = useConfig(props);
24
- const currentRef = ref(1);
25
- const lengthRef = { value: 1 };
26
- const touchingRef = ref(false);
27
- const dragOffsetRef = ref(0);
63
+ // Dom
28
64
  const selfElRef = ref(null);
29
- const dotPlacementRef = toRef(props, 'dotPlacement');
30
- let timerId = null;
31
- let inTransition = false;
32
- // current from 0 to length + 1
33
- function next() {
34
- if (lengthRef.value <= 1)
35
- return;
36
- if (inTransition)
37
- return;
38
- inTransition = true;
39
- // no need for reset since transitionend handler will handle it
40
- currentRef.value++;
65
+ const slidesElsRef = ref([]);
66
+ const slideVNodesRef = { value: [] };
67
+ // user wants to control the transition animation
68
+ const userWantsControlRef = computed(() => props.effect === 'custom');
69
+ const translateableRef = computed(() => !userWantsControlRef.value && props.effect === 'slide');
70
+ // TODO
71
+ const allowLoopRef = computed(() => props.loop && props.slidesPerView === 1);
72
+ // Because of the nature of the loop slide work,
73
+ // we need to add duplicates to the left and right of the carousel
74
+ // slot [ 0 1 2 ]
75
+ // display 2 0 1 2 0
76
+ // index 0 1 2 3 4
77
+ const duplicatedableRef = computed(
78
+ // only duplicate the copy operation in `slide` mode,
79
+ // because other effects have special process
80
+ () => translateableRef.value && allowLoopRef.value);
81
+ // used to calculate total views
82
+ const displaySlidesPerViewRef = computed(() => userWantsControlRef.value ||
83
+ props.centeredSlides ||
84
+ props.effect !== 'slide'
85
+ ? 1
86
+ : props.slidesPerView);
87
+ // used to calculate the size of each slide
88
+ const realSlidesPerViewRef = computed(() => userWantsControlRef.value ? 1 : props.slidesPerView);
89
+ // we automatically calculate total view for special slides per view
90
+ const autoSlideSizeRef = computed(() => displaySlidesPerViewRef.value === 'auto' ||
91
+ (props.slidesPerView === 'auto' && props.centeredSlides));
92
+ const transitionStyleRef = computed(() => props.transitionStyle
93
+ ? keep(props.transitionStyle, transitionProperties)
94
+ : {});
95
+ const speedRef = computed(() => userWantsControlRef.value
96
+ ? 0
97
+ : resolveSpeed(transitionStyleRef.value.transitionDuration));
98
+ const verticalRef = computed(() => props.direction === 'vertical');
99
+ const sizeAxisRef = computed(() => (verticalRef.value ? 'height' : 'width'));
100
+ const perViewSizeRef = ref({ width: 0, height: 0 });
101
+ const slideSizesRef = computed(() => {
102
+ const { value: slidesEls } = slidesElsRef;
103
+ const { length } = slidesEls;
104
+ if (!length)
105
+ return [];
106
+ if (autoSlideSizeRef.value) {
107
+ return slidesEls.map((slide) => calculateSize(slide));
108
+ }
109
+ const { value: slidesPerView } = realSlidesPerViewRef;
110
+ const { value: perViewSize } = perViewSizeRef;
111
+ const { value: axis } = sizeAxisRef;
112
+ let slideSize = perViewSize[axis];
113
+ if (slidesPerView !== 'auto') {
114
+ const { spaceBetween } = props;
115
+ const remaining = slideSize - (slidesPerView - 1) * spaceBetween;
116
+ const percentage = 1 / Math.max(1, slidesPerView);
117
+ slideSize = remaining * percentage;
118
+ }
119
+ return slidesEls.map(() => (Object.assign(Object.assign({}, perViewSize), { [axis]: slideSize })));
120
+ });
121
+ // The translate required to reach each slide
122
+ const slideTranlatesRef = computed(() => {
123
+ const { value: slideSizes } = slideSizesRef;
124
+ const { length } = slideSizes;
125
+ if (!length)
126
+ return [];
127
+ const { centeredSlides, spaceBetween } = props;
128
+ const { value: axis } = sizeAxisRef;
129
+ const { [axis]: perViewSize } = perViewSizeRef.value;
130
+ let previousTranslate = 0;
131
+ return slideSizes.map(({ [axis]: slideSize }) => {
132
+ let translate = previousTranslate;
133
+ if (centeredSlides) {
134
+ translate += (slideSize - perViewSize) / 2;
135
+ }
136
+ previousTranslate += slideSize + spaceBetween;
137
+ return translate;
138
+ });
139
+ });
140
+ let isMounted = false;
141
+ const slideStylesRef = computed(() => {
142
+ const { value: slideSizes } = slideSizesRef;
143
+ const { length } = slideSizes;
144
+ if (!length)
145
+ return [];
146
+ const { value: axis } = sizeAxisRef;
147
+ // when user wants to control the transition animation, we center each slide
148
+ if (userWantsControlRef.value) {
149
+ return slideSizes.map((size) => ({
150
+ [axis]: `${size[axis]}px`
151
+ }));
152
+ }
153
+ const { effect, spaceBetween } = props;
154
+ const { value: vertical } = verticalRef;
155
+ const spaceAxis = vertical ? 'bottom' : 'right';
156
+ const slideStyles = [];
157
+ for (let i = 0; i < length; i++) {
158
+ const size = slideSizes[i][axis];
159
+ const style = {
160
+ [axis]: `${size}px`,
161
+ [`margin-${spaceAxis}`]: `${spaceBetween}px`
162
+ };
163
+ // TODO: fix
164
+ // if (isMounted && (effect === 'fade' || effect === 'card')) {
165
+ if (isMounted && effect === 'fade') {
166
+ Object.assign(style, transitionStyleRef.value);
167
+ }
168
+ slideStyles.push(style);
169
+ }
170
+ return slideStyles;
171
+ });
172
+ // Total
173
+ const totalViewRef = computed(() => {
174
+ const { value: slidesPerView } = displaySlidesPerViewRef;
175
+ const { length: originLength } = slidesElsRef.value;
176
+ if (slidesPerView !== 'auto') {
177
+ return originLength - slidesPerView + 1;
178
+ }
179
+ else {
180
+ const { value: slideSizes } = slideSizesRef;
181
+ const { length } = slideSizes;
182
+ if (!length)
183
+ return originLength;
184
+ const { value: translates } = slideTranlatesRef;
185
+ const { value: axis } = sizeAxisRef;
186
+ const perViewSize = perViewSizeRef.value[axis];
187
+ let lastViewSize = slideSizes[slideSizes.length - 1][axis];
188
+ let i = length;
189
+ while (i > 1 && lastViewSize < perViewSize) {
190
+ i--;
191
+ lastViewSize += translates[i] - translates[i - 1];
192
+ }
193
+ if (i !== length)
194
+ i++;
195
+ if (i < 1)
196
+ i = 1;
197
+ return i;
198
+ }
199
+ });
200
+ const displayTotalViewRef = computed(() => {
201
+ const { value: totalView } = totalViewRef;
202
+ return duplicatedableRef.value && totalView > 3
203
+ ? totalView - 2
204
+ : totalView;
205
+ });
206
+ // Index
207
+ const initializeIndex = props.defaultIndex + (duplicatedableRef.value ? 1 : 0);
208
+ const displayIndexRef = ref(getDisplayIndex(initializeIndex, totalViewRef.value, duplicatedableRef.value));
209
+ const virtualIndexRef = ref(initializeIndex);
210
+ const realIndexRef = ref(initializeIndex);
211
+ // record the translate of each slide, so that it can be restored at touch
212
+ let previousTranslate = 0;
213
+ // Reality methods
214
+ function toRealIndex(index, speed = speedRef.value) {
215
+ var _a, _b;
216
+ const { value: length } = totalViewRef;
217
+ if ((index = clampValue(index, 0, length - 1)) !== realIndexRef.value) {
218
+ const { value: lastDisplayIndex } = displayIndexRef;
219
+ // When it is loop from the first silde to the last one,
220
+ // we control its animation effect
221
+ if (duplicatedableRef.value && displayTotalViewRef.value > 2) {
222
+ if (lastDisplayIndex === 0 && index === displayTotalViewRef.value) {
223
+ index = 0;
224
+ }
225
+ else if (lastDisplayIndex === displayTotalViewRef.value - 1 &&
226
+ index === 1) {
227
+ index = length - 1;
228
+ }
229
+ }
230
+ const displayIndex = (displayIndexRef.value = getDisplayIndex(index, totalViewRef.value, duplicatedableRef.value));
231
+ virtualIndexRef.value = index;
232
+ realIndexRef.value = getRealIndex(displayIndex, duplicatedableRef.value);
233
+ if (translateableRef.value) {
234
+ translateTo(index, speed);
235
+ }
236
+ else {
237
+ fixTranslate();
238
+ }
239
+ if (displayIndex !== lastDisplayIndex) {
240
+ (_a = props['onUpdate:currentIndex']) === null || _a === void 0 ? void 0 : _a.call(props, displayIndex, lastDisplayIndex);
241
+ (_b = props.onUpdateCurrentIndex) === null || _b === void 0 ? void 0 : _b.call(props, displayIndex, lastDisplayIndex);
242
+ }
243
+ }
244
+ }
245
+ function getRealPrevIndex(index = realIndexRef.value) {
246
+ return getPrevIndex(index, totalViewRef.value, props.loop);
247
+ }
248
+ function getRealNextIndex(index = realIndexRef.value) {
249
+ return getNextIndex(index, totalViewRef.value, props.loop);
250
+ }
251
+ function isRealPrev(slideOrIndex) {
252
+ const index = getSlideIndex(slideOrIndex);
253
+ return index !== null && getRealPrevIndex() === index;
254
+ }
255
+ function isRealNext(slideOrIndex) {
256
+ const index = getSlideIndex(slideOrIndex);
257
+ return index !== null && getRealNextIndex() === index;
258
+ }
259
+ function isRealActive(slideOrIndex) {
260
+ return realIndexRef.value === getSlideIndex(slideOrIndex);
261
+ }
262
+ // Display methods
263
+ // They are used to deal with the actual values displayed on the UI
264
+ function isDisplayActive(index) {
265
+ return displayIndexRef.value === index;
266
+ }
267
+ function isPrevDisabled() {
268
+ return getRealPrevIndex() === null;
269
+ }
270
+ function isNextDisabled() {
271
+ return getRealNextIndex() === null;
272
+ }
273
+ // Slide to
274
+ function to(index) {
275
+ const realIndex = getRealIndex(index, duplicatedableRef.value);
276
+ if (index !== displayIndexRef.value || realIndex !== realIndexRef.value) {
277
+ toRealIndex(realIndex);
278
+ }
41
279
  }
42
280
  function prev() {
43
- if (lengthRef.value <= 1)
44
- return;
45
- if (inTransition)
46
- return;
47
- inTransition = true;
48
- // no need for reset since transitionend handler will handle it
49
- currentRef.value--;
281
+ const prevIndex = getRealPrevIndex();
282
+ if (prevIndex !== null) {
283
+ toRealIndex(prevIndex);
284
+ }
50
285
  }
51
- function setCurrent(value) {
52
- if (lengthRef.value <= 1)
53
- return;
54
- if (inTransition)
55
- return;
56
- const { value: current } = currentRef;
57
- if (value === current)
58
- return;
59
- inTransition = true;
60
- if (current === 1 && value === lengthRef.value && value - current > 1) {
61
- currentRef.value--;
286
+ function next() {
287
+ const nextIndex = getRealNextIndex();
288
+ if (nextIndex !== null) {
289
+ toRealIndex(nextIndex);
290
+ }
291
+ }
292
+ // Translate to
293
+ const translateStyleRef = ref({});
294
+ let inTransition = false;
295
+ function updateTranslate(translate, speed = 0) {
296
+ const isVersical = props.direction === 'vertical';
297
+ translateStyleRef.value = Object.assign({}, transitionStyleRef.value, {
298
+ transform: isVersical
299
+ ? `translateY(${-translate}px)`
300
+ : `translateX(${-translate}px)`,
301
+ transitionDuration: `${speed}ms`
302
+ });
303
+ }
304
+ function fixTranslate(speed = 0) {
305
+ if (translateableRef.value) {
306
+ translateTo(realIndexRef.value, speed);
307
+ }
308
+ else if (previousTranslate !== 0) {
309
+ updateTranslate((previousTranslate = 0), speed);
310
+ }
311
+ }
312
+ function translateTo(index, speed = speedRef.value) {
313
+ const translate = getTranslate(index);
314
+ if (translate !== previousTranslate && speed > 0) {
315
+ inTransition = true;
62
316
  }
63
- else if (value === 1 &&
64
- current === lengthRef.value &&
65
- current - value > 1) {
66
- currentRef.value++;
317
+ updateTranslate(translate, speed);
318
+ previousTranslate = getTranslate(realIndexRef.value);
319
+ }
320
+ function getTranslate(index) {
321
+ let translate;
322
+ // Deal with auto slides pre view
323
+ if (index >= totalViewRef.value - 1) {
324
+ translate = getLastViewTranslate();
67
325
  }
68
326
  else {
69
- currentRef.value = value;
327
+ translate = slideTranlatesRef.value[index] || 0;
70
328
  }
71
- if (props.autoplay) {
72
- resetInterval();
329
+ return translate;
330
+ }
331
+ function getLastViewTranslate() {
332
+ if (displaySlidesPerViewRef.value === 'auto') {
333
+ const { value: axis } = sizeAxisRef;
334
+ const { [axis]: perViewSize } = perViewSizeRef.value;
335
+ const { value: translates } = slideTranlatesRef;
336
+ const lastTranslate = translates[translates.length - 1];
337
+ let overallSize;
338
+ if (lastTranslate === undefined) {
339
+ overallSize = perViewSize;
340
+ }
341
+ else {
342
+ const { value: slideSizes } = slideSizesRef;
343
+ overallSize = lastTranslate + slideSizes[slideSizes.length - 1][axis];
344
+ }
345
+ // Bring the last slide to the edge
346
+ return overallSize - perViewSize;
347
+ }
348
+ else {
349
+ const { value: translates } = slideTranlatesRef;
350
+ return translates[totalViewRef.value - 1] || 0;
73
351
  }
74
352
  }
75
- // slot [ 0 1 2 ]
76
- // index 0 1 2 3 4
77
- // display 2 0 1 2 0
78
- function handleTransitionEnd(e) {
79
- const target = e.target;
80
- if (target !== e.currentTarget)
353
+ // Provide
354
+ function addSlide(slide) {
355
+ if (!slide)
81
356
  return;
82
- const { value: current } = currentRef;
83
- const { value: length } = lengthRef;
84
- const nextCurrent = current === 0 ? length : current === length + 1 ? 1 : null;
85
- if (nextCurrent !== null) {
86
- currentRef.value = nextCurrent;
87
- void nextTick(() => {
88
- target.style.transition = 'none';
89
- void target.offsetWidth;
90
- target.style.transition = '';
91
- inTransition = false;
92
- });
357
+ slidesElsRef.value.push(slide);
358
+ }
359
+ function removeSlide(slide) {
360
+ if (!slide)
361
+ return;
362
+ const index = getSlideIndex(slide);
363
+ if (index !== -1) {
364
+ slidesElsRef.value.splice(index, 1);
93
365
  }
94
- else {
95
- inTransition = false;
366
+ }
367
+ function getSlideIndex(slideOrIndex) {
368
+ return typeof slideOrIndex === 'number'
369
+ ? slideOrIndex
370
+ : slidesElsRef.value.indexOf(slideOrIndex);
371
+ }
372
+ function getSlideStyle(slide) {
373
+ const index = getSlideIndex(slide);
374
+ if (index !== -1) {
375
+ return slideStylesRef.value[index];
96
376
  }
97
377
  }
98
- function handleKeydown(e, current) {
99
- switch (e.code) {
100
- case 'Enter':
101
- case 'NumpadEnter':
102
- case 'Space':
103
- setCurrent(current);
378
+ function onCarouselItemClick(index) {
379
+ // TODO fix
380
+ // if (
381
+ // !dragTriggered &&
382
+ // !userWantsControlRef.value &&
383
+ // props.effect === 'card' &&
384
+ // !isRealActive(index)
385
+ // ) {
386
+ // to(index)
387
+ // }
388
+ }
389
+ const carouselMethods = {
390
+ to,
391
+ prev: () => {
392
+ // wait transition end
393
+ if (!inTransition || !duplicatedableRef.value)
394
+ prev();
395
+ },
396
+ next: () => {
397
+ // wait transition end
398
+ if (!inTransition || !duplicatedableRef.value)
399
+ next();
400
+ },
401
+ isVertical: () => verticalRef.value,
402
+ isHorizontal: () => !verticalRef.value,
403
+ isPrev: isRealPrev,
404
+ isNext: isRealNext,
405
+ isActive: isRealActive,
406
+ isPrevDisabled,
407
+ isNextDisabled,
408
+ getCurrentIndex: () => displayIndexRef.value,
409
+ getSlideIndex,
410
+ getSlideStyle,
411
+ addSlide,
412
+ removeSlide,
413
+ onCarouselItemClick
414
+ };
415
+ provide(carouselMethodsInjectionKey, carouselMethods);
416
+ // Autoplay
417
+ let autoplayTimer = null;
418
+ function resetAutoplay(cleanOnly) {
419
+ if (autoplayTimer) {
420
+ clearInterval(autoplayTimer);
421
+ autoplayTimer = null;
422
+ }
423
+ const { autoplay, interval } = props;
424
+ if (autoplay && interval && !cleanOnly) {
425
+ autoplayTimer = setInterval(next, interval);
104
426
  }
105
427
  }
428
+ function mesureAutoplay() {
429
+ const { autoplay } = props;
430
+ if (autoplay) {
431
+ resetAutoplay();
432
+ }
433
+ else if (displayTotalViewRef.value < 2) {
434
+ resetAutoplay(true);
435
+ }
436
+ }
437
+ // Drag
106
438
  let dragStartX = 0;
107
439
  let dragStartY = 0;
440
+ let dragOffset = 0;
108
441
  let dragStartTime = 0;
109
- let memorizedContainerWidth = 0;
110
- let memorizedContainerHeight = 0;
111
- function handleTouchstart(e) {
112
- if (timerId !== null) {
113
- window.clearInterval(timerId);
114
- }
115
- e.preventDefault();
116
- const { value: dotPlacement } = dotPlacementRef;
117
- if (dotPlacement === 'left' || dotPlacement === 'right') {
118
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
119
- memorizedContainerHeight = selfElRef.value.offsetHeight;
120
- touchingRef.value = true;
121
- dragStartTime = Date.now();
122
- dragStartY = e.touches[0].clientY;
442
+ let dragging = false;
443
+ let allowClick = true;
444
+ // whether the last touch triggered the drag successfully
445
+ // const dragTriggered = false
446
+ function handleTouchstart(event) {
447
+ allowClick = true;
448
+ if (globalDragging)
449
+ return;
450
+ // pause autoplay
451
+ resetAutoplay(true);
452
+ dragging = true;
453
+ globalDragging = true;
454
+ dragStartTime = Date.now();
455
+ // dragTriggered = false
456
+ if (event.type !== 'touchstart' &&
457
+ !event.target.isContentEditable) {
458
+ event.preventDefault();
123
459
  }
124
- else {
125
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
126
- memorizedContainerWidth = selfElRef.value.offsetWidth;
127
- touchingRef.value = true;
128
- dragStartTime = Date.now();
129
- dragStartX = e.touches[0].clientX;
130
- }
131
- on('touchmove', document, handleTouchmove);
132
- on('touchend', document, handleTouchend);
133
- on('touchcancel', document, handleTouchend);
134
- }
135
- function handleTouchmove(e) {
136
- const { value: dotPlacement } = dotPlacementRef;
137
- if (dotPlacement === 'left' || dotPlacement === 'right') {
138
- const dragOffset = e.touches[0].clientY - dragStartY;
139
- dragOffsetRef.value =
140
- dragOffset > memorizedContainerHeight
141
- ? memorizedContainerHeight
142
- : dragOffset < -memorizedContainerHeight
143
- ? -memorizedContainerHeight
144
- : dragOffset;
460
+ const touchEvent = isTouchEvent(event) ? event.touches[0] : event;
461
+ if (verticalRef.value) {
462
+ dragStartY = touchEvent.clientY;
145
463
  }
146
464
  else {
147
- const dragOffset = e.touches[0].clientX - dragStartX;
148
- dragOffsetRef.value =
149
- dragOffset > memorizedContainerWidth
150
- ? memorizedContainerWidth
151
- : dragOffset < -memorizedContainerWidth
152
- ? -memorizedContainerWidth
153
- : dragOffset;
465
+ dragStartX = touchEvent.clientX;
466
+ }
467
+ if (props.touchable) {
468
+ on('touchmove', document, handleTouchmove);
469
+ on('touchend', document, handleTouchend);
470
+ on('touchcancel', document, handleTouchend);
471
+ }
472
+ if (props.draggable) {
473
+ on('mousemove', document, handleTouchmove);
474
+ on('mouseup', document, handleTouchend);
475
+ }
476
+ }
477
+ function handleTouchmove(event) {
478
+ const { value: vertical } = verticalRef;
479
+ const axis = vertical ? 'height' : 'width';
480
+ const perViewSize = perViewSizeRef.value[axis];
481
+ const touchEvent = isTouchEvent(event) ? event.touches[0] : event;
482
+ const offset = vertical
483
+ ? touchEvent.clientY - dragStartY
484
+ : touchEvent.clientX - dragStartX;
485
+ dragOffset = clampValue(offset, -perViewSize, perViewSize);
486
+ allowClick = false;
487
+ if (translateableRef.value) {
488
+ updateTranslate(previousTranslate - dragOffset, 0);
154
489
  }
155
490
  }
156
491
  function handleTouchend() {
157
- if (props.autoplay)
158
- resetInterval();
159
- void nextTick(() => {
160
- touchingRef.value = false;
161
- });
162
- const { value: selfEl } = selfElRef;
163
- if (selfEl) {
164
- const { offsetWidth, offsetHeight } = selfEl;
165
- const { value: dragOffset } = dragOffsetRef;
166
- const duration = Date.now() - dragStartTime;
167
- const { value: dotPlacement } = dotPlacementRef;
168
- // more than 50% width or faster than 0.4px per ms
169
- if (dotPlacement === 'left' || dotPlacement === 'right') {
170
- if (dragOffset > offsetHeight / 2 || dragOffset / duration > 0.4) {
171
- prev();
172
- }
173
- else if (dragOffset < -offsetHeight / 2 ||
174
- dragOffset / duration < -0.4) {
175
- next();
492
+ const duration = Date.now() - dragStartTime;
493
+ const { value: axis } = sizeAxisRef;
494
+ const { value: realIndex } = realIndexRef;
495
+ const { value: translateable } = translateableRef;
496
+ let currentIndex = realIndex;
497
+ if (!inTransition && translateable && dragOffset !== 0) {
498
+ const currentTranslate = previousTranslate - dragOffset;
499
+ const translates = [
500
+ ...slideTranlatesRef.value.slice(0, totalViewRef.value - 1),
501
+ getLastViewTranslate()
502
+ ];
503
+ let prevOffset = null;
504
+ for (let i = 0; i < translates.length; i++) {
505
+ const offset = Math.abs(translates[i] - currentTranslate);
506
+ if (prevOffset !== null && prevOffset < offset) {
507
+ break;
176
508
  }
509
+ prevOffset = offset;
510
+ currentIndex = i;
177
511
  }
178
- else {
179
- if (dragOffset > offsetWidth / 2 || dragOffset / duration > 0.4) {
180
- prev();
181
- }
182
- else if (dragOffset < -offsetWidth / 2 ||
183
- dragOffset / duration < -0.4) {
184
- next();
185
- }
512
+ }
513
+ if (currentIndex === realIndex) {
514
+ const perViewSize = perViewSizeRef.value[axis];
515
+ // more than 50% width or faster than 0.4px per ms
516
+ if (dragOffset > perViewSize / 2 || dragOffset / duration > 0.4) {
517
+ currentIndex = getRealPrevIndex(realIndex);
186
518
  }
519
+ else if (dragOffset < -perViewSize / 2 ||
520
+ dragOffset / duration < -0.4) {
521
+ currentIndex = getRealNextIndex(realIndex);
522
+ }
523
+ }
524
+ if (currentIndex !== null && currentIndex !== realIndex) {
525
+ // dragTriggered = true
526
+ toRealIndex(currentIndex);
187
527
  }
188
- dragOffsetRef.value = 0;
528
+ else {
529
+ fixTranslate(speedRef.value);
530
+ }
531
+ mesureAutoplay();
532
+ resetDragStatus();
533
+ }
534
+ function resetDragStatus() {
535
+ if (dragging) {
536
+ dragging = false;
537
+ globalDragging = false;
538
+ }
539
+ dragStartX = 0;
540
+ dragStartY = 0;
541
+ dragOffset = 0;
542
+ dragStartTime = 0;
189
543
  off('touchmove', document, handleTouchmove);
190
544
  off('touchend', document, handleTouchend);
191
545
  off('touchcancel', document, handleTouchend);
546
+ off('mousemove', document, handleTouchmove);
547
+ off('mouseup', document, handleTouchend);
192
548
  }
193
- function handleMouseenter(current) {
194
- if (props.trigger === 'hover') {
195
- setCurrent(current);
549
+ function handleTransitionEnd() {
550
+ const { value: virtualIndex } = virtualIndexRef;
551
+ const { value: realIndex } = realIndexRef;
552
+ if (inTransition && virtualIndex !== realIndex) {
553
+ translateTo(realIndex, 0);
196
554
  }
197
- }
198
- function resetInterval() {
199
- if (timerId !== null) {
200
- window.clearInterval(timerId);
555
+ else {
556
+ resetAutoplay();
557
+ }
558
+ if (translateableRef.value) {
559
+ translateStyleRef.value.transitionDuration = '0ms';
201
560
  }
202
- timerId = window.setInterval(() => {
203
- next();
204
- }, props.interval);
561
+ inTransition = false;
205
562
  }
206
- onMounted(() => {
207
- watchEffect(() => {
208
- if (props.autoplay) {
209
- resetInterval();
563
+ function handleMousewheel(event) {
564
+ event.preventDefault();
565
+ if (inTransition)
566
+ return;
567
+ const { value: vertical } = verticalRef;
568
+ let { deltaX, deltaY } = event;
569
+ if (event.shiftKey && !deltaX) {
570
+ deltaX = deltaY;
571
+ }
572
+ const PREV_R = -1;
573
+ const NEXT_R = 1;
574
+ const r = (deltaX || deltaY) > 0 ? NEXT_R : PREV_R;
575
+ let rx = 0;
576
+ let ry = 0;
577
+ if (vertical) {
578
+ ry = r;
579
+ }
580
+ else {
581
+ rx = r;
582
+ }
583
+ const RESPONSE_STEP = 10;
584
+ if (ry * deltaY >= RESPONSE_STEP || rx * deltaX >= RESPONSE_STEP) {
585
+ if (r === NEXT_R && !isNextDisabled()) {
586
+ next();
210
587
  }
211
- else {
212
- if (timerId !== null) {
213
- window.clearInterval(timerId);
214
- }
588
+ else if (r === PREV_R && !isPrevDisabled()) {
589
+ prev();
215
590
  }
216
- });
591
+ }
592
+ }
593
+ function handleClick(event) {
594
+ if (!allowClick) {
595
+ event.preventDefault();
596
+ event.stopPropagation();
597
+ allowClick = true;
598
+ }
599
+ }
600
+ function handleResize() {
601
+ perViewSizeRef.value = calculateSize(selfElRef.value, true);
602
+ resetAutoplay();
603
+ }
604
+ function handleSlideResize() {
605
+ var _a, _b;
606
+ if (autoSlideSizeRef.value) {
607
+ (_b = (_a = slideSizesRef.effect).scheduler) === null || _b === void 0 ? void 0 : _b.call(_a);
608
+ slideSizesRef.effect.run();
609
+ }
610
+ }
611
+ onMounted(() => {
612
+ watchEffect(mesureAutoplay);
613
+ void nextTick(() => (isMounted = true));
217
614
  });
218
615
  onBeforeUnmount(() => {
219
- if (timerId !== null) {
220
- window.clearInterval(timerId);
616
+ resetDragStatus();
617
+ resetAutoplay(true);
618
+ });
619
+ // Fix index when remounting
620
+ onUpdated(() => {
621
+ const { value: slidesEls } = slidesElsRef;
622
+ const { value: slideVNodes } = slideVNodesRef;
623
+ const indexMap = new Map();
624
+ const getDisplayIndex = (el) =>
625
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
626
+ indexMap.has(el) ? indexMap.get(el) : -1;
627
+ let isChanged = false;
628
+ for (let i = 0; i < slidesEls.length; i++) {
629
+ const index = slideVNodes.findIndex((v) => v.el === slidesEls[i]);
630
+ if (index !== i) {
631
+ isChanged = true;
632
+ }
633
+ indexMap.set(slidesEls[i], index);
634
+ }
635
+ if (isChanged) {
636
+ slidesEls.sort((a, b) => getDisplayIndex(a) - getDisplayIndex(b));
637
+ }
638
+ });
639
+ watch(toRef(props, 'currentIndex'), (index) => index !== undefined && to(index));
640
+ watch(duplicatedableRef, () => void nextTick(() => to(displayIndexRef.value)));
641
+ watch(slideTranlatesRef, () => translateableRef.value && fixTranslate(), {
642
+ deep: true
643
+ });
644
+ watch(translateableRef, (value) => {
645
+ if (!value) {
646
+ inTransition = false;
647
+ // if the current mode does not support translate, reset the position of the wrapper
648
+ updateTranslate((previousTranslate = 0));
649
+ }
650
+ else {
651
+ fixTranslate();
221
652
  }
222
653
  });
654
+ const caroulseSlotProps = {
655
+ arrowSlotProps: computed(() => (Object.assign({ total: displayTotalViewRef.value, currentIndex: displayIndexRef.value }, keep(carouselMethods, [
656
+ 'to',
657
+ 'prev',
658
+ 'next',
659
+ 'isPrevDisabled',
660
+ 'isNextDisabled'
661
+ ])))),
662
+ dotSlotProps: computed(() => ({
663
+ total: displayTotalViewRef.value,
664
+ currentIndex: displayIndexRef.value,
665
+ to
666
+ }))
667
+ };
668
+ const caroulseExposedMethod = {
669
+ getCurrentIndex: () => displayIndexRef.value,
670
+ to: to,
671
+ prev: prev,
672
+ next: next
673
+ };
223
674
  const themeRef = useTheme('Carousel', 'Carousel', style, carouselLight, props);
224
- return {
225
- selfElRef,
226
- mergedClsPrefix: mergedClsPrefixRef,
227
- current: currentRef,
228
- lengthRef,
229
- touching: touchingRef,
230
- dragOffset: dragOffsetRef,
231
- prev,
232
- next,
233
- setCurrent,
234
- handleKeydown,
235
- handleTouchstart,
675
+ return Object.assign(Object.assign(Object.assign({ mergedClsPrefix: mergedClsPrefixRef, selfElRef, slideVNodes: slideVNodesRef, duplicatedable: duplicatedableRef, userWantsControl: userWantsControlRef, autoSlideSize: autoSlideSizeRef, displayIndex: displayIndexRef, realIndex: realIndexRef, slideStyles: slideStylesRef, translateStyle: translateStyleRef, handleTouchstart,
236
676
  handleTransitionEnd,
237
- handleMouseenter,
238
- cssVars: computed(() => {
239
- const { common: { cubicBezierEaseInOut }, self: { dotColor, dotColorActive, dotSize, arrowColor } } = themeRef.value;
677
+ handleMousewheel,
678
+ handleClick,
679
+ handleResize,
680
+ handleSlideResize, isActive: isDisplayActive }, caroulseSlotProps), caroulseExposedMethod), { cssVars: computed(() => {
681
+ const { common: { cubicBezierEaseInOut }, self: { dotSize, dotColor, dotColorActive, dotColorFocus, dotLineWidth, dotLineWidthActive, arrowColor } } = themeRef.value;
240
682
  return {
241
683
  '--n-bezier': cubicBezierEaseInOut,
242
684
  '--n-dot-color': dotColor,
685
+ '--n-dot-color-focus': dotColorFocus,
243
686
  '--n-dot-color-active': dotColorActive,
244
687
  '--n-dot-size': dotSize,
688
+ '--n-dot-line-width': dotLineWidth,
689
+ '--n-dot-line-width-active': dotLineWidthActive,
245
690
  '--n-arrow-color': arrowColor
246
691
  };
247
- })
248
- };
692
+ }) });
249
693
  },
250
694
  render() {
251
- const { showArrow, dotPlacement, mergedClsPrefix, current, lengthRef, autoplay, $slots: { default: defaultSlot } } = this;
252
- const children = flatten((defaultSlot === null || defaultSlot === void 0 ? void 0 : defaultSlot()) || []);
253
- const { length } = children;
254
- lengthRef.value = length;
255
- const leftOverflowVNode = length ? cloneVNode(children[length - 1]) : null;
256
- const rightOverflowVNode = length ? cloneVNode(children[0]) : null;
257
- const total = length + 2;
258
- const vertical = dotPlacement === 'left' || dotPlacement === 'right';
259
- return (h("div", { class: [
695
+ const { mergedClsPrefix, showArrow, userWantsControl, draggable, touchable, slideStyles, dotType, dotPlacement, transitionProps = {}, arrowSlotProps, dotSlotProps, $slots: { default: defaultSlot, dots: dotsSlot, arrow: arrowSlot } } = this;
696
+ const children = (defaultSlot && flatten(defaultSlot())) || [];
697
+ let slides = filterCarouselItem(children);
698
+ if (!slides.length) {
699
+ slides = children.map((ch) => (h(NCarouselItem, null, {
700
+ default: () => cloneVNode(ch)
701
+ })));
702
+ }
703
+ const { length: realLength } = slides;
704
+ if (realLength > 1 && this.duplicatedable) {
705
+ slides.push(duplicateSlide(slides[0], 0, 'append'));
706
+ slides.unshift(duplicateSlide(slides[realLength - 1], realLength - 1, 'prepend'));
707
+ }
708
+ this.slideVNodes.value = slides;
709
+ // When users need to customize the size of the slide,
710
+ // we listen to them to fix the current translate
711
+ if (this.autoSlideSize) {
712
+ slides = slides.map((slide) => (h(VResizeObserver, { onResize: this.handleSlideResize }, {
713
+ default: () => slide
714
+ })));
715
+ }
716
+ return (h("div", { ref: "selfElRef", class: [
260
717
  `${mergedClsPrefix}-carousel`,
261
- `${mergedClsPrefix}-carousel--${this.dotPlacement}`
262
- ], style: this.cssVars, ref: "selfElRef" },
263
- h("div", { class: `${mergedClsPrefix}-carousel__slides`, onTouchstart: this.handleTouchstart, style: {
264
- [vertical ? 'height' : 'width']: `${total}00%`,
265
- [vertical ? 'width' : 'height']: '100%',
266
- transition: this.touching ? 'none' : '',
267
- transform: vertical
268
- ? `translate3d(0, -${(100 / total) * (current % total)}%, 0)` +
269
- (this.touching ? `translateY(${this.dragOffset}px)` : '')
270
- : `translate3d(-${(100 / total) * (current % total)}%, 0, 0)` +
271
- (this.touching ? `translateX(${this.dragOffset}px)` : '')
272
- }, onTransitionend: this.handleTransitionEnd, role: "listbox" }, [leftOverflowVNode, ...children, rightOverflowVNode].map((vNode, i) => (h("div", { "data-index": i, style: { [vertical ? 'height' : 'width']: `${100 / total}%` }, key: i, role: "option", "aria-hidden": i !== current }, vNode)))),
273
- h("div", { class: `${mergedClsPrefix}-carousel__dots`, role: "tablist" }, indexMap(length, (i) => {
274
- const selected = i + 1 === current;
275
- return (h("div", { "aria-selected": selected, role: "button", tabindex: "0", class: [
276
- `${mergedClsPrefix}-carousel__dot`,
277
- selected && `${mergedClsPrefix}-carousel__dot--active`
278
- ], onClick: () => this.setCurrent(i + 1), onMouseenter: () => this.handleMouseenter(i + 1), onMousedown: autoplay
279
- ? (e) => {
280
- e.preventDefault();
281
- }
282
- : undefined, onKeydown: (e) => this.handleKeydown(e, i + 1) }));
283
- })),
284
- showArrow && [
285
- h("div", { class: [
286
- `${mergedClsPrefix}-carousel__arrow`,
287
- `${mergedClsPrefix}-carousel__arrow--${vertical ? 'bottom' : 'right'}`
288
- ], role: "button", onClick: () => {
289
- this.next();
290
- } },
291
- h(ForwardIcon, null)),
292
- h("div", { class: [
293
- `${mergedClsPrefix}-carousel__arrow`,
294
- `${mergedClsPrefix}-carousel__arrow--${vertical ? 'top' : 'left'}`
295
- ], role: "button", onClick: () => {
296
- this.prev();
297
- } },
298
- h(BackwardIcon, null))
299
- ]));
718
+ `${mergedClsPrefix}-carousel--${dotPlacement}`,
719
+ `${mergedClsPrefix}-carousel--${this.direction}`,
720
+ `${mergedClsPrefix}-carousel--${this.effect}`,
721
+ userWantsControl && `${mergedClsPrefix}-carousel--usercontrol`
722
+ ], style: this.cssVars },
723
+ h(VResizeObserver, { onResize: this.handleResize }, {
724
+ default: () => (h("div", { class: `${mergedClsPrefix}-carousel__slides`, role: "listbox", style: this.translateStyle, onMousedown: draggable ? this.handleTouchstart : undefined, onTouchstart: touchable ? this.handleTouchstart : undefined,
725
+ // @ts-expect-error
726
+ onClickCapture: this.handleClick, onWheel: this.mousewheel ? this.handleMousewheel : undefined, onTransitionend: this.handleTransitionEnd }, userWantsControl
727
+ ? slides.map((slide, i) => (h("div", { style: slideStyles[i], key: i }, withDirectives(h(Transition, Object.assign({}, transitionProps), {
728
+ default: () => slide
729
+ }), [[vShow, this.isActive(i)]]))))
730
+ : slides))
731
+ }),
732
+ this.showDots &&
733
+ (dotsSlot
734
+ ? dotsSlot(dotSlotProps)
735
+ : dotSlotProps.total > 1 && (h(NCarouselDots, { key: dotType + dotPlacement, total: dotSlotProps.total, currentIndex: dotSlotProps.currentIndex, dotType: dotType, trigger: this.trigger, keyboard: this.keyboard }))),
736
+ showArrow &&
737
+ (arrowSlot ? arrowSlot(arrowSlotProps) : h(NCarouselArrow, null))));
300
738
  }
301
739
  });
740
+ function filterCarouselItem(vnodes, carouselItems = []) {
741
+ if (Array.isArray(vnodes)) {
742
+ vnodes.forEach((vnode) => {
743
+ if (vnode.type && vnode.type.name === 'CarouselItem') {
744
+ carouselItems.push(vnode);
745
+ }
746
+ });
747
+ }
748
+ return carouselItems;
749
+ }
750
+ function duplicateSlide(child, index, position) {
751
+ return cloneVNode(child, {
752
+ // for patch
753
+ key: `carousel-item-duplicate-${index}-${position}`
754
+ });
755
+ }