@penggy/element-ui 2.4.11 → 2.4.12

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 (334) hide show
  1. package/lib/autocomplete.js +8 -8
  2. package/lib/carousel.js +1 -1
  3. package/lib/cascader.js +9 -9
  4. package/lib/checkbox-button.js +1 -1
  5. package/lib/checkbox-group.js +1 -1
  6. package/lib/checkbox.js +1 -1
  7. package/lib/collapse-item.js +3 -3
  8. package/lib/color-picker.js +6 -6
  9. package/lib/date-picker.js +17 -17
  10. package/lib/dialog.js +3 -3
  11. package/lib/directives/repeat-click.js +1 -1
  12. package/lib/dropdown-item.js +1 -1
  13. package/lib/dropdown-menu.js +1 -1
  14. package/lib/dropdown.js +6 -6
  15. package/lib/element-ui.common.js +443 -91
  16. package/lib/form-item.js +3 -3
  17. package/lib/form.js +1 -1
  18. package/lib/index.js +1 -1
  19. package/lib/input-number.js +3 -3
  20. package/lib/input.js +4 -4
  21. package/lib/loading.js +4 -4
  22. package/lib/locale/format.js +11 -11
  23. package/lib/locale/index.js +1 -1
  24. package/lib/menu-item.js +2 -2
  25. package/lib/menu.js +28 -28
  26. package/lib/message-box.js +9 -9
  27. package/lib/message.js +2 -2
  28. package/lib/mixins/locale.js +1 -1
  29. package/lib/mixins/migrating.js +20 -20
  30. package/lib/notification.js +2 -2
  31. package/lib/option-group.js +1 -1
  32. package/lib/option.js +2 -2
  33. package/lib/pagination.js +5 -5
  34. package/lib/popover.js +3 -3
  35. package/lib/radio-button.js +1 -1
  36. package/lib/radio-group.js +1 -1
  37. package/lib/radio.js +1 -1
  38. package/lib/rate.js +2 -2
  39. package/lib/scrollbar.js +4 -4
  40. package/lib/select.js +13 -13
  41. package/lib/slider.js +3 -3
  42. package/lib/steps.js +1 -1
  43. package/lib/submenu.js +3 -3
  44. package/lib/switch.js +2 -2
  45. package/lib/table-column.js +4 -4
  46. package/lib/table.js +14 -14
  47. package/lib/tabs.js +1 -1
  48. package/lib/time-picker.js +15 -15
  49. package/lib/time-select.js +14 -14
  50. package/lib/tooltip.js +4 -4
  51. package/lib/transfer.js +7 -7
  52. package/lib/transitions/collapse-transition.js +1 -1
  53. package/lib/tree.js +6 -6
  54. package/lib/upload.js +3 -3
  55. package/lib/utils/after-leave.js +7 -7
  56. package/lib/utils/aria-dialog.js +16 -16
  57. package/lib/utils/aria-utils.js +25 -25
  58. package/lib/utils/clickoutside.js +8 -8
  59. package/lib/utils/date.js +37 -37
  60. package/lib/utils/popper.js +321 -321
  61. package/lib/utils/popup/index.js +2 -2
  62. package/lib/utils/popup/popup-manager.js +1 -1
  63. package/lib/utils/vdom.js +1 -1
  64. package/lib/utils/vue-popper.js +8 -8
  65. package/package.json +1 -1
  66. package/packages/alert/index.js +8 -8
  67. package/packages/alert/src/main.vue +88 -88
  68. package/packages/aside/index.js +8 -8
  69. package/packages/aside/src/main.vue +20 -20
  70. package/packages/autocomplete/index.js +8 -8
  71. package/packages/autocomplete/src/autocomplete-suggestions.vue +76 -76
  72. package/packages/autocomplete/src/autocomplete.vue +269 -269
  73. package/packages/badge/index.js +8 -8
  74. package/packages/badge/src/main.vue +53 -53
  75. package/packages/breadcrumb/index.js +8 -8
  76. package/packages/breadcrumb/src/breadcrumb-item.vue +41 -41
  77. package/packages/breadcrumb/src/breadcrumb.vue +34 -34
  78. package/packages/breadcrumb-item/index.js +8 -8
  79. package/packages/button/index.js +8 -8
  80. package/packages/button/src/button-group.vue +10 -10
  81. package/packages/button/src/button.vue +78 -78
  82. package/packages/button-group/index.js +8 -8
  83. package/packages/card/index.js +8 -8
  84. package/packages/card/src/main.vue +23 -23
  85. package/packages/carousel/index.js +8 -8
  86. package/packages/carousel/src/item.vue +114 -114
  87. package/packages/carousel/src/main.vue +262 -262
  88. package/packages/carousel-item/index.js +8 -8
  89. package/packages/cascader/index.js +8 -8
  90. package/packages/cascader/src/main.vue +456 -456
  91. package/packages/cascader/src/menu.vue +376 -376
  92. package/packages/checkbox/index.js +8 -8
  93. package/packages/checkbox/src/checkbox-button.vue +191 -191
  94. package/packages/checkbox/src/checkbox-group.vue +48 -48
  95. package/packages/checkbox/src/checkbox.vue +219 -219
  96. package/packages/checkbox-button/index.js +8 -8
  97. package/packages/checkbox-group/index.js +8 -8
  98. package/packages/col/index.js +9 -9
  99. package/packages/col/src/col.js +71 -71
  100. package/packages/collapse/index.js +9 -9
  101. package/packages/collapse/src/collapse-item.vue +113 -113
  102. package/packages/collapse/src/collapse.vue +73 -73
  103. package/packages/collapse-item/index.js +8 -8
  104. package/packages/color-picker/index.js +8 -8
  105. package/packages/color-picker/src/color.js +316 -316
  106. package/packages/color-picker/src/components/alpha-slider.vue +132 -132
  107. package/packages/color-picker/src/components/hue-slider.vue +123 -123
  108. package/packages/color-picker/src/components/picker-dropdown.vue +121 -121
  109. package/packages/color-picker/src/components/predefine.vue +60 -60
  110. package/packages/color-picker/src/components/sv-panel.vue +100 -100
  111. package/packages/color-picker/src/draggable.js +36 -36
  112. package/packages/color-picker/src/main.vue +188 -188
  113. package/packages/container/index.js +8 -8
  114. package/packages/container/src/main.vue +33 -33
  115. package/packages/date-picker/index.js +8 -8
  116. package/packages/date-picker/src/basic/date-table.vue +437 -437
  117. package/packages/date-picker/src/basic/month-table.vue +105 -105
  118. package/packages/date-picker/src/basic/time-spinner.vue +301 -301
  119. package/packages/date-picker/src/basic/year-table.vue +101 -101
  120. package/packages/date-picker/src/panel/date-range.vue +640 -640
  121. package/packages/date-picker/src/panel/date.vue +579 -579
  122. package/packages/date-picker/src/panel/time-range.vue +248 -248
  123. package/packages/date-picker/src/panel/time-select.vue +177 -177
  124. package/packages/date-picker/src/panel/time.vue +186 -186
  125. package/packages/date-picker/src/picker/date-picker.js +40 -40
  126. package/packages/date-picker/src/picker/time-picker.js +39 -39
  127. package/packages/date-picker/src/picker/time-select.js +21 -21
  128. package/packages/date-picker/src/picker.vue +924 -924
  129. package/packages/date-picker/src/util/index.js +273 -273
  130. package/packages/dialog/index.js +8 -8
  131. package/packages/dialog/src/component.vue +201 -201
  132. package/packages/dropdown/index.js +8 -8
  133. package/packages/dropdown/src/dropdown-item.vue +35 -35
  134. package/packages/dropdown/src/dropdown-menu.vue +60 -60
  135. package/packages/dropdown/src/dropdown.vue +271 -271
  136. package/packages/dropdown-item/index.js +8 -8
  137. package/packages/dropdown-menu/index.js +8 -8
  138. package/packages/footer/index.js +8 -8
  139. package/packages/footer/src/main.vue +20 -20
  140. package/packages/form/index.js +8 -8
  141. package/packages/form/src/form-item.vue +290 -290
  142. package/packages/form/src/form.vue +148 -148
  143. package/packages/form-item/index.js +8 -8
  144. package/packages/header/index.js +8 -8
  145. package/packages/header/src/main.vue +20 -20
  146. package/packages/icon/index.js +8 -8
  147. package/packages/icon/src/icon.vue +13 -13
  148. package/packages/input/index.js +8 -8
  149. package/packages/input/src/calcTextareaHeight.js +104 -104
  150. package/packages/input/src/input.vue +349 -349
  151. package/packages/input-number/index.js +8 -8
  152. package/packages/input-number/src/input-number.vue +255 -255
  153. package/packages/loading/index.js +11 -11
  154. package/packages/loading/src/directive.js +128 -128
  155. package/packages/loading/src/index.js +106 -106
  156. package/packages/loading/src/loading.vue +41 -41
  157. package/packages/main/index.js +8 -8
  158. package/packages/main/src/main.vue +12 -12
  159. package/packages/menu/index.js +8 -8
  160. package/packages/menu/src/menu-item-group.vue +45 -45
  161. package/packages/menu/src/menu-item.vue +112 -112
  162. package/packages/menu/src/menu-mixin.js +44 -44
  163. package/packages/menu/src/menu.vue +311 -311
  164. package/packages/menu/src/submenu.vue +335 -335
  165. package/packages/menu-item/index.js +8 -8
  166. package/packages/menu-item-group/index.js +8 -8
  167. package/packages/message/index.js +2 -2
  168. package/packages/message/src/main.js +72 -72
  169. package/packages/message/src/main.vue +112 -112
  170. package/packages/message-box/index.js +2 -2
  171. package/packages/message-box/src/main.js +216 -216
  172. package/packages/message-box/src/main.vue +327 -327
  173. package/packages/notification/index.js +2 -2
  174. package/packages/notification/src/main.js +93 -93
  175. package/packages/notification/src/main.vue +152 -152
  176. package/packages/option/index.js +8 -8
  177. package/packages/option-group/index.js +8 -8
  178. package/packages/pagination/index.js +8 -8
  179. package/packages/pagination/src/pager.vue +163 -163
  180. package/packages/pagination/src/pagination.js +430 -430
  181. package/packages/popover/index.js +14 -14
  182. package/packages/popover/src/directive.js +20 -20
  183. package/packages/popover/src/main.vue +207 -207
  184. package/packages/progress/index.js +8 -8
  185. package/packages/progress/src/progress.vue +138 -138
  186. package/packages/radio/index.js +8 -8
  187. package/packages/radio/src/radio-button.vue +114 -114
  188. package/packages/radio/src/radio-group.vue +100 -100
  189. package/packages/radio/src/radio.vue +126 -126
  190. package/packages/radio-button/index.js +8 -8
  191. package/packages/radio-group/index.js +8 -8
  192. package/packages/rate/index.js +8 -8
  193. package/packages/rate/src/main.vue +350 -350
  194. package/packages/row/index.js +9 -9
  195. package/packages/row/src/row.js +47 -47
  196. package/packages/scrollbar/index.js +8 -8
  197. package/packages/scrollbar/src/bar.js +88 -88
  198. package/packages/scrollbar/src/main.js +130 -130
  199. package/packages/scrollbar/src/util.js +34 -34
  200. package/packages/select/index.js +8 -8
  201. package/packages/select/src/navigation-mixin.js +54 -54
  202. package/packages/select/src/option-group.vue +60 -60
  203. package/packages/select/src/option.vue +159 -159
  204. package/packages/select/src/select-dropdown.vue +74 -74
  205. package/packages/select/src/select.vue +878 -878
  206. package/packages/slider/index.js +8 -8
  207. package/packages/slider/src/button.vue +235 -235
  208. package/packages/slider/src/main.vue +385 -385
  209. package/packages/spinner/index.js +8 -8
  210. package/packages/spinner/src/spinner.vue +27 -27
  211. package/packages/step/index.js +8 -8
  212. package/packages/steps/index.js +8 -8
  213. package/packages/steps/src/step.vue +180 -180
  214. package/packages/steps/src/steps.vue +68 -68
  215. package/packages/submenu/index.js +8 -8
  216. package/packages/switch/index.js +9 -9
  217. package/packages/switch/src/component.vue +163 -163
  218. package/packages/tab-pane/index.js +8 -8
  219. package/packages/table/index.js +8 -8
  220. package/packages/table/src/dropdown.js +28 -28
  221. package/packages/table/src/filter-panel.vue +203 -203
  222. package/packages/table/src/layout-observer.js +68 -68
  223. package/packages/table/src/table-body.js +392 -392
  224. package/packages/table/src/table-column.js +462 -462
  225. package/packages/table/src/table-footer.js +147 -147
  226. package/packages/table/src/table-header.js +522 -522
  227. package/packages/table/src/table-layout.js +231 -231
  228. package/packages/table/src/table-store.js +657 -657
  229. package/packages/table/src/table.vue +660 -660
  230. package/packages/table/src/util.js +122 -122
  231. package/packages/table-column/index.js +8 -8
  232. package/packages/tabs/index.js +8 -8
  233. package/packages/tabs/src/tab-bar.vue +57 -57
  234. package/packages/tabs/src/tab-nav.vue +280 -280
  235. package/packages/tabs/src/tab-pane.vue +58 -58
  236. package/packages/tabs/src/tabs.vue +185 -185
  237. package/packages/tag/index.js +8 -8
  238. package/packages/tag/src/tag.vue +39 -39
  239. package/packages/time-picker/index.js +8 -8
  240. package/packages/time-select/index.js +8 -8
  241. package/packages/tooltip/index.js +8 -8
  242. package/packages/tooltip/src/main.js +216 -216
  243. package/packages/transfer/index.js +8 -8
  244. package/packages/transfer/src/main.vue +231 -231
  245. package/packages/transfer/src/transfer-panel.vue +251 -251
  246. package/packages/tree/index.js +8 -8
  247. package/packages/tree/src/model/node.js +481 -481
  248. package/packages/tree/src/model/tree-store.js +333 -333
  249. package/packages/tree/src/model/util.js +27 -27
  250. package/packages/tree/src/tree-node.vue +277 -277
  251. package/packages/tree/src/tree.vue +495 -495
  252. package/packages/upload/index.js +8 -8
  253. package/packages/upload/src/ajax.js +85 -85
  254. package/packages/upload/src/index.vue +315 -315
  255. package/packages/upload/src/upload-dragger.vue +70 -70
  256. package/packages/upload/src/upload-list.vue +103 -103
  257. package/packages/upload/src/upload.vue +211 -211
  258. package/src/directives/mousewheel.js +18 -18
  259. package/src/directives/repeat-click.js +24 -24
  260. package/src/index.js +1 -1
  261. package/src/locale/format.js +46 -46
  262. package/src/locale/index.js +48 -48
  263. package/src/locale/lang/af-ZA.js +109 -109
  264. package/src/locale/lang/ar.js +108 -108
  265. package/src/locale/lang/bg.js +109 -109
  266. package/src/locale/lang/ca.js +108 -108
  267. package/src/locale/lang/cs-CZ.js +111 -111
  268. package/src/locale/lang/da.js +108 -108
  269. package/src/locale/lang/de.js +110 -110
  270. package/src/locale/lang/ee.js +109 -109
  271. package/src/locale/lang/el.js +109 -109
  272. package/src/locale/lang/en.js +109 -109
  273. package/src/locale/lang/es.js +108 -108
  274. package/src/locale/lang/eu.js +109 -109
  275. package/src/locale/lang/fa.js +109 -109
  276. package/src/locale/lang/fi.js +109 -109
  277. package/src/locale/lang/fr.js +108 -108
  278. package/src/locale/lang/he.js +109 -109
  279. package/src/locale/lang/hu.js +108 -108
  280. package/src/locale/lang/id.js +109 -109
  281. package/src/locale/lang/it.js +108 -108
  282. package/src/locale/lang/ja.js +109 -109
  283. package/src/locale/lang/km.js +109 -109
  284. package/src/locale/lang/ko.js +109 -109
  285. package/src/locale/lang/ku.js +109 -109
  286. package/src/locale/lang/kz.js +109 -109
  287. package/src/locale/lang/lt.js +109 -109
  288. package/src/locale/lang/lv.js +109 -109
  289. package/src/locale/lang/mn.js +109 -109
  290. package/src/locale/lang/nb-NO.js +108 -108
  291. package/src/locale/lang/nl.js +109 -109
  292. package/src/locale/lang/pl.js +109 -109
  293. package/src/locale/lang/pt-br.js +109 -109
  294. package/src/locale/lang/pt.js +109 -109
  295. package/src/locale/lang/ro.js +109 -109
  296. package/src/locale/lang/ru-RU.js +109 -109
  297. package/src/locale/lang/sk.js +111 -111
  298. package/src/locale/lang/sl.js +109 -109
  299. package/src/locale/lang/sr.js +109 -109
  300. package/src/locale/lang/sv-SE.js +109 -109
  301. package/src/locale/lang/ta.js +108 -108
  302. package/src/locale/lang/th.js +109 -109
  303. package/src/locale/lang/tk.js +109 -109
  304. package/src/locale/lang/tr-TR.js +109 -109
  305. package/src/locale/lang/ua.js +109 -109
  306. package/src/locale/lang/ug-CN.js +109 -109
  307. package/src/locale/lang/vi.js +109 -109
  308. package/src/locale/lang/zh-CN.js +109 -109
  309. package/src/locale/lang/zh-TW.js +109 -109
  310. package/src/mixins/emitter.js +33 -33
  311. package/src/mixins/focus.js +9 -9
  312. package/src/mixins/locale.js +9 -9
  313. package/src/mixins/migrating.js +51 -51
  314. package/src/transitions/collapse-transition.js +77 -77
  315. package/src/utils/after-leave.js +27 -27
  316. package/src/utils/aria-dialog.js +90 -90
  317. package/src/utils/aria-utils.js +121 -121
  318. package/src/utils/clickoutside.js +76 -76
  319. package/src/utils/date.js +344 -344
  320. package/src/utils/dom.js +174 -174
  321. package/src/utils/menu/aria-menubar.js +14 -14
  322. package/src/utils/menu/aria-menuitem.js +49 -49
  323. package/src/utils/menu/aria-submenu.js +59 -59
  324. package/src/utils/merge.js +15 -15
  325. package/src/utils/popper.js +1276 -1276
  326. package/src/utils/popup/index.js +226 -226
  327. package/src/utils/popup/popup-manager.js +194 -194
  328. package/src/utils/resize-event.js +35 -35
  329. package/src/utils/scroll-into-view.js +27 -27
  330. package/src/utils/scrollbar-width.js +29 -29
  331. package/src/utils/shared.js +7 -7
  332. package/src/utils/util.js +122 -122
  333. package/src/utils/vdom.js +9 -9
  334. package/src/utils/vue-popper.js +200 -200
@@ -1,924 +1,924 @@
1
- <template>
2
- <el-input
3
- class="el-date-editor"
4
- :class="'el-date-editor--' + type"
5
- :readonly="!editable || readonly || type === 'dates'"
6
- :disabled="pickerDisabled"
7
- :size="pickerSize"
8
- :name="name"
9
- v-bind="firstInputId"
10
- v-if="!ranged"
11
- v-clickoutside="handleClose"
12
- :placeholder="placeholder"
13
- @focus="handleFocus"
14
- @keydown.native="handleKeydown"
15
- :value="displayValue"
16
- @input="value => userInput = value"
17
- @change="handleChange"
18
- @mouseenter.native="handleMouseEnter"
19
- @mouseleave.native="showClose = false"
20
- :validateEvent="false"
21
- ref="reference">
22
- <i slot="prefix"
23
- class="el-input__icon"
24
- :class="triggerClass"
25
- @click="handleFocus">
26
- </i>
27
- <i slot="suffix"
28
- class="el-input__icon"
29
- @click="handleClickIcon"
30
- :class="[showClose ? '' + clearIcon : '']"
31
- v-if="haveTrigger">
32
- </i>
33
- </el-input>
34
- <div
35
- class="el-date-editor el-range-editor el-input__inner"
36
- :class="[
37
- 'el-date-editor--' + type,
38
- pickerSize ? `el-range-editor--${ pickerSize }` : '',
39
- pickerDisabled ? 'is-disabled' : '',
40
- pickerVisible ? 'is-active' : ''
41
- ]"
42
- @click="handleRangeClick"
43
- @mouseenter="handleMouseEnter"
44
- @mouseleave="showClose = false"
45
- @keydown="handleKeydown"
46
- ref="reference"
47
- v-clickoutside="handleClose"
48
- v-else>
49
- <i :class="['el-input__icon', 'el-range__icon', triggerClass]"></i>
50
- <input
51
- autocomplete="off"
52
- :placeholder="startPlaceholder"
53
- :value="displayValue && displayValue[0]"
54
- :disabled="pickerDisabled"
55
- v-bind="firstInputId"
56
- :readonly="!editable || readonly"
57
- :name="name && name[0]"
58
- @input="handleStartInput"
59
- @change="handleStartChange"
60
- @focus="handleFocus"
61
- class="el-range-input">
62
- <slot name="range-separator">
63
- <span class="el-range-separator">{{ rangeSeparator }}</span>
64
- </slot>
65
- <input
66
- autocomplete="off"
67
- :placeholder="endPlaceholder"
68
- :value="displayValue && displayValue[1]"
69
- :disabled="pickerDisabled"
70
- v-bind="secondInputId"
71
- :readonly="!editable || readonly"
72
- :name="name && name[1]"
73
- @input="handleEndInput"
74
- @change="handleEndChange"
75
- @focus="handleFocus"
76
- class="el-range-input">
77
- <i
78
- @click="handleClickIcon"
79
- v-if="haveTrigger"
80
- :class="[showClose ? '' + clearIcon : '']"
81
- class="el-input__icon el-range__close-icon">
82
- </i>
83
- </div>
84
- </template>
85
-
86
- <script>
87
- import Vue from 'vue';
88
- import Clickoutside from 'element-ui/src/utils/clickoutside';
89
- import { formatDate, parseDate, isDateObject, getWeekNumber } from './util';
90
- import Popper from 'element-ui/src/utils/vue-popper';
91
- import Emitter from 'element-ui/src/mixins/emitter';
92
- import ElInput from 'element-ui/packages/input';
93
- import merge from 'element-ui/src/utils/merge';
94
-
95
- const NewPopper = {
96
- props: {
97
- appendToBody: Popper.props.appendToBody,
98
- offset: Popper.props.offset,
99
- boundariesPadding: Popper.props.boundariesPadding,
100
- arrowOffset: Popper.props.arrowOffset
101
- },
102
- methods: Popper.methods,
103
- data() {
104
- return merge({ visibleArrow: true }, Popper.data);
105
- },
106
- beforeDestroy: Popper.beforeDestroy
107
- };
108
-
109
- const DEFAULT_FORMATS = {
110
- date: 'yyyy-MM-dd',
111
- month: 'yyyy-MM',
112
- datetime: 'yyyy-MM-dd HH:mm:ss',
113
- time: 'HH:mm:ss',
114
- week: 'yyyywWW',
115
- timerange: 'HH:mm:ss',
116
- daterange: 'yyyy-MM-dd',
117
- datetimerange: 'yyyy-MM-dd HH:mm:ss',
118
- year: 'yyyy'
119
- };
120
- const HAVE_TRIGGER_TYPES = [
121
- 'date',
122
- 'datetime',
123
- 'time',
124
- 'time-select',
125
- 'week',
126
- 'month',
127
- 'year',
128
- 'daterange',
129
- 'timerange',
130
- 'datetimerange',
131
- 'dates'
132
- ];
133
- const DATE_FORMATTER = function(value, format) {
134
- if (format === 'timestamp') return value.getTime();
135
- return formatDate(value, format);
136
- };
137
- const DATE_PARSER = function(text, format) {
138
- if (format === 'timestamp') return new Date(Number(text));
139
- return parseDate(text, format);
140
- };
141
- const RANGE_FORMATTER = function(value, format) {
142
- if (Array.isArray(value) && value.length === 2) {
143
- const start = value[0];
144
- const end = value[1];
145
-
146
- if (start && end) {
147
- return [DATE_FORMATTER(start, format), DATE_FORMATTER(end, format)];
148
- }
149
- }
150
- return '';
151
- };
152
- const RANGE_PARSER = function(array, format, separator) {
153
- if (!Array.isArray(array)) {
154
- array = array.split(separator);
155
- }
156
- if (array.length === 2) {
157
- const range1 = array[0];
158
- const range2 = array[1];
159
-
160
- return [DATE_PARSER(range1, format), DATE_PARSER(range2, format)];
161
- }
162
- return [];
163
- };
164
- const TYPE_VALUE_RESOLVER_MAP = {
165
- default: {
166
- formatter(value) {
167
- if (!value) return '';
168
- return '' + value;
169
- },
170
- parser(text) {
171
- if (text === undefined || text === '') return null;
172
- return text;
173
- }
174
- },
175
- week: {
176
- formatter(value, format) {
177
- let week = getWeekNumber(value);
178
- let month = value.getMonth();
179
- const trueDate = new Date(value);
180
- if (week === 1 && month === 11) {
181
- trueDate.setHours(0, 0, 0, 0);
182
- trueDate.setDate(trueDate.getDate() + 3 - (trueDate.getDay() + 6) % 7);
183
- }
184
- let date = formatDate(trueDate, format);
185
-
186
- date = /WW/.test(date)
187
- ? date.replace(/WW/, week < 10 ? '0' + week : week)
188
- : date.replace(/W/, week);
189
- return date;
190
- },
191
- parser(text) {
192
- const array = (text || '').split('w');
193
- if (array.length === 2) {
194
- const year = Number(array[0]);
195
- const month = Number(array[1]);
196
-
197
- if (!isNaN(year) && !isNaN(month) && month < 54) {
198
- return text;
199
- }
200
- }
201
- return null;
202
- }
203
- },
204
- date: {
205
- formatter: DATE_FORMATTER,
206
- parser: DATE_PARSER
207
- },
208
- datetime: {
209
- formatter: DATE_FORMATTER,
210
- parser: DATE_PARSER
211
- },
212
- daterange: {
213
- formatter: RANGE_FORMATTER,
214
- parser: RANGE_PARSER
215
- },
216
- datetimerange: {
217
- formatter: RANGE_FORMATTER,
218
- parser: RANGE_PARSER
219
- },
220
- timerange: {
221
- formatter: RANGE_FORMATTER,
222
- parser: RANGE_PARSER
223
- },
224
- time: {
225
- formatter: DATE_FORMATTER,
226
- parser: DATE_PARSER
227
- },
228
- month: {
229
- formatter: DATE_FORMATTER,
230
- parser: DATE_PARSER
231
- },
232
- year: {
233
- formatter: DATE_FORMATTER,
234
- parser: DATE_PARSER
235
- },
236
- number: {
237
- formatter(value) {
238
- if (!value) return '';
239
- return '' + value;
240
- },
241
- parser(text) {
242
- let result = Number(text);
243
-
244
- if (!isNaN(text)) {
245
- return result;
246
- } else {
247
- return null;
248
- }
249
- }
250
- },
251
- dates: {
252
- formatter(value, format) {
253
- return value.map(date => DATE_FORMATTER(date, format));
254
- },
255
- parser(value, format) {
256
- return (typeof value === 'string' ? value.split(', ') : value)
257
- .map(date => date instanceof Date ? date : DATE_PARSER(date, format));
258
- }
259
- }
260
- };
261
- const PLACEMENT_MAP = {
262
- left: 'bottom-start',
263
- center: 'bottom',
264
- right: 'bottom-end'
265
- };
266
-
267
- const parseAsFormatAndType = (value, customFormat, type, rangeSeparator = '-') => {
268
- if (!value) return null;
269
- const parser = (
270
- TYPE_VALUE_RESOLVER_MAP[type] ||
271
- TYPE_VALUE_RESOLVER_MAP['default']
272
- ).parser;
273
- const format = customFormat || DEFAULT_FORMATS[type];
274
- return parser(value, format, rangeSeparator);
275
- };
276
-
277
- const formatAsFormatAndType = (value, customFormat, type) => {
278
- if (!value) return null;
279
- const formatter = (
280
- TYPE_VALUE_RESOLVER_MAP[type] ||
281
- TYPE_VALUE_RESOLVER_MAP['default']
282
- ).formatter;
283
- const format = customFormat || DEFAULT_FORMATS[type];
284
- return formatter(value, format);
285
- };
286
-
287
- /*
288
- * Considers:
289
- * 1. Date object
290
- * 2. date string
291
- * 3. array of 1 or 2
292
- */
293
- const valueEquals = function(a, b) {
294
- // considers Date object and string
295
- const dateEquals = function(a, b) {
296
- const aIsDate = a instanceof Date;
297
- const bIsDate = b instanceof Date;
298
- if (aIsDate && bIsDate) {
299
- return a.getTime() === b.getTime();
300
- }
301
- if (!aIsDate && !bIsDate) {
302
- return a === b;
303
- }
304
- return false;
305
- };
306
-
307
- const aIsArray = a instanceof Array;
308
- const bIsArray = b instanceof Array;
309
- if (aIsArray && bIsArray) {
310
- if (a.length !== b.length) {
311
- return false;
312
- }
313
- return a.every((item, index) => dateEquals(item, b[index]));
314
- }
315
- if (!aIsArray && !bIsArray) {
316
- return dateEquals(a, b);
317
- }
318
- return false;
319
- };
320
-
321
- const isString = function(val) {
322
- return typeof val === 'string' || val instanceof String;
323
- };
324
-
325
- const validator = function(val) {
326
- // either: String, Array of String, null / undefined
327
- return (
328
- val === null ||
329
- val === undefined ||
330
- isString(val) ||
331
- (Array.isArray(val) && val.length === 2 && val.every(isString))
332
- );
333
- };
334
-
335
- export default {
336
- mixins: [Emitter, NewPopper],
337
-
338
- inject: {
339
- elForm: {
340
- default: ''
341
- },
342
- elFormItem: {
343
- default: ''
344
- }
345
- },
346
-
347
- props: {
348
- size: String,
349
- format: String,
350
- valueFormat: String,
351
- readonly: Boolean,
352
- placeholder: String,
353
- startPlaceholder: String,
354
- endPlaceholder: String,
355
- prefixIcon: String,
356
- clearIcon: {
357
- type: String,
358
- default: 'el-icon-circle-close'
359
- },
360
- name: {
361
- default: '',
362
- validator
363
- },
364
- disabled: Boolean,
365
- clearable: {
366
- type: Boolean,
367
- default: true
368
- },
369
- id: {
370
- default: '',
371
- validator
372
- },
373
- popperClass: String,
374
- editable: {
375
- type: Boolean,
376
- default: true
377
- },
378
- align: {
379
- type: String,
380
- default: 'left'
381
- },
382
- value: {},
383
- defaultValue: {},
384
- defaultTime: {},
385
- rangeSeparator: {
386
- default: '-'
387
- },
388
- pickerOptions: {},
389
- unlinkPanels: Boolean
390
- },
391
-
392
- components: { ElInput },
393
-
394
- directives: { Clickoutside },
395
-
396
- data() {
397
- return {
398
- pickerVisible: false,
399
- showClose: false,
400
- userInput: null,
401
- valueOnOpen: null, // value when picker opens, used to determine whether to emit change
402
- unwatchPickerOptions: null
403
- };
404
- },
405
-
406
- watch: {
407
- pickerVisible(val) {
408
- if (this.readonly || this.pickerDisabled) return;
409
- if (val) {
410
- this.showPicker();
411
- this.valueOnOpen = Array.isArray(this.value) ? [...this.value] : this.value;
412
- } else {
413
- this.hidePicker();
414
- this.emitChange(this.value);
415
- this.userInput = null;
416
- this.dispatch('ElFormItem', 'el.form.blur');
417
- this.$emit('blur', this);
418
- this.blur();
419
- }
420
- },
421
- parsedValue: {
422
- immediate: true,
423
- handler(val) {
424
- if (this.picker) {
425
- this.picker.value = val;
426
- }
427
- }
428
- },
429
- defaultValue(val) {
430
- // NOTE: should eventually move to jsx style picker + panel ?
431
- if (this.picker) {
432
- this.picker.defaultValue = val;
433
- }
434
- },
435
- value(val, oldVal) {
436
- if (!valueEquals(val, oldVal) && !this.pickerVisible) {
437
- this.dispatch('ElFormItem', 'el.form.change', val);
438
- }
439
- }
440
- },
441
-
442
- computed: {
443
- ranged() {
444
- return this.type.indexOf('range') > -1;
445
- },
446
-
447
- reference() {
448
- const reference = this.$refs.reference;
449
- return reference.$el || reference;
450
- },
451
-
452
- refInput() {
453
- if (this.reference) {
454
- return [].slice.call(this.reference.querySelectorAll('input'));
455
- }
456
- return [];
457
- },
458
-
459
- valueIsEmpty() {
460
- const val = this.value;
461
- if (Array.isArray(val)) {
462
- for (let i = 0, len = val.length; i < len; i++) {
463
- if (val[i]) {
464
- return false;
465
- }
466
- }
467
- } else {
468
- if (val) {
469
- return false;
470
- }
471
- }
472
- return true;
473
- },
474
-
475
- triggerClass() {
476
- return this.prefixIcon || (this.type.indexOf('time') !== -1 ? 'el-icon-time' : 'el-icon-date');
477
- },
478
-
479
- selectionMode() {
480
- if (this.type === 'week') {
481
- return 'week';
482
- } else if (this.type === 'month') {
483
- return 'month';
484
- } else if (this.type === 'year') {
485
- return 'year';
486
- } else if (this.type === 'dates') {
487
- return 'dates';
488
- }
489
-
490
- return 'day';
491
- },
492
-
493
- haveTrigger() {
494
- if (typeof this.showTrigger !== 'undefined') {
495
- return this.showTrigger;
496
- }
497
- return HAVE_TRIGGER_TYPES.indexOf(this.type) !== -1;
498
- },
499
-
500
- displayValue() {
501
- const formattedValue = formatAsFormatAndType(this.parsedValue, this.format, this.type, this.rangeSeparator);
502
- if (Array.isArray(this.userInput)) {
503
- return [
504
- this.userInput[0] || (formattedValue && formattedValue[0]) || '',
505
- this.userInput[1] || (formattedValue && formattedValue[1]) || ''
506
- ];
507
- } else if (this.userInput !== null) {
508
- return this.userInput;
509
- } else if (formattedValue) {
510
- return this.type === 'dates'
511
- ? formattedValue.join(', ')
512
- : formattedValue;
513
- } else {
514
- return '';
515
- }
516
- },
517
-
518
- parsedValue() {
519
- if (!this.value) return this.value; // component value is not set
520
- if (this.type === 'time-select') return this.value; // time-select does not require parsing, this might change in next major version
521
-
522
- const valueIsDateObject = isDateObject(this.value) || (Array.isArray(this.value) && this.value.every(isDateObject));
523
- if (valueIsDateObject) {
524
- return this.value;
525
- }
526
-
527
- if (this.valueFormat) {
528
- return parseAsFormatAndType(this.value, this.valueFormat, this.type, this.rangeSeparator) || this.value;
529
- }
530
-
531
- // NOTE: deal with common but incorrect usage, should remove in next major version
532
- // user might provide string / timestamp without value-format, coerce them into date (or array of date)
533
- return Array.isArray(this.value) ? this.value.map(val => new Date(val)) : new Date(this.value);
534
- },
535
-
536
- _elFormItemSize() {
537
- return (this.elFormItem || {}).elFormItemSize;
538
- },
539
-
540
- pickerSize() {
541
- return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
542
- },
543
-
544
- pickerDisabled() {
545
- return this.disabled || (this.elForm || {}).disabled;
546
- },
547
-
548
- firstInputId() {
549
- const obj = {};
550
- let id;
551
- if (this.ranged) {
552
- id = this.id && this.id[0];
553
- } else {
554
- id = this.id;
555
- }
556
- if (id) obj.id = id;
557
- return obj;
558
- },
559
-
560
- secondInputId() {
561
- const obj = {};
562
- let id;
563
- if (this.ranged) {
564
- id = this.id && this.id[1];
565
- }
566
- if (id) obj.id = id;
567
- return obj;
568
- }
569
- },
570
-
571
- created() {
572
- // vue-popper
573
- this.popperOptions = {
574
- boundariesPadding: 0,
575
- gpuAcceleration: false
576
- };
577
- this.placement = PLACEMENT_MAP[this.align] || PLACEMENT_MAP.left;
578
-
579
- this.$on('fieldReset', this.handleFieldReset);
580
- },
581
-
582
- methods: {
583
- focus() {
584
- if (!this.ranged) {
585
- this.$refs.reference.focus();
586
- } else {
587
- this.handleFocus();
588
- }
589
- },
590
-
591
- blur() {
592
- this.refInput.forEach(input => input.blur());
593
- },
594
-
595
- // {parse, formatTo} Value deals maps component value with internal Date
596
- parseValue(value) {
597
- const isParsed = isDateObject(value) || (Array.isArray(value) && value.every(isDateObject));
598
- if (this.valueFormat && !isParsed) {
599
- return parseAsFormatAndType(value, this.valueFormat, this.type, this.rangeSeparator) || value;
600
- } else {
601
- return value;
602
- }
603
- },
604
-
605
- formatToValue(date) {
606
- const isFormattable = isDateObject(date) || (Array.isArray(date) && date.every(isDateObject));
607
- if (this.valueFormat && isFormattable) {
608
- return formatAsFormatAndType(date, this.valueFormat, this.type, this.rangeSeparator);
609
- } else {
610
- return date;
611
- }
612
- },
613
-
614
- // {parse, formatTo} String deals with user input
615
- parseString(value) {
616
- const type = Array.isArray(value) ? this.type : this.type.replace('range', '');
617
- return parseAsFormatAndType(value, this.format, type);
618
- },
619
-
620
- formatToString(value) {
621
- const type = Array.isArray(value) ? this.type : this.type.replace('range', '');
622
- return formatAsFormatAndType(value, this.format, type);
623
- },
624
-
625
- handleMouseEnter() {
626
- if (this.readonly || this.pickerDisabled) return;
627
- if (!this.valueIsEmpty && this.clearable) {
628
- this.showClose = true;
629
- }
630
- },
631
-
632
- handleChange() {
633
- if (this.userInput) {
634
- const value = this.parseString(this.displayValue);
635
- if (value) {
636
- this.picker.value = value;
637
- if (this.isValidValue(value)) {
638
- this.emitInput(value);
639
- this.userInput = null;
640
- }
641
- }
642
- }
643
- if (this.userInput === '') {
644
- this.emitInput(null);
645
- this.emitChange(null);
646
- this.userInput = null;
647
- }
648
- },
649
-
650
- handleStartInput(event) {
651
- if (this.userInput) {
652
- this.userInput = [event.target.value, this.userInput[1]];
653
- } else {
654
- this.userInput = [event.target.value, null];
655
- }
656
- },
657
-
658
- handleEndInput(event) {
659
- if (this.userInput) {
660
- this.userInput = [this.userInput[0], event.target.value];
661
- } else {
662
- this.userInput = [null, event.target.value];
663
- }
664
- },
665
-
666
- handleStartChange(event) {
667
- const value = this.parseString(this.userInput && this.userInput[0]);
668
- if (value) {
669
- this.userInput = [this.formatToString(value), this.displayValue[1]];
670
- const newValue = [value, this.picker.value && this.picker.value[1]];
671
- this.picker.value = newValue;
672
- if (this.isValidValue(newValue)) {
673
- this.emitInput(newValue);
674
- this.userInput = null;
675
- }
676
- }
677
- },
678
-
679
- handleEndChange(event) {
680
- const value = this.parseString(this.userInput && this.userInput[1]);
681
- if (value) {
682
- this.userInput = [this.displayValue[0], this.formatToString(value)];
683
- const newValue = [this.picker.value && this.picker.value[0], value];
684
- this.picker.value = newValue;
685
- if (this.isValidValue(newValue)) {
686
- this.emitInput(newValue);
687
- this.userInput = null;
688
- }
689
- }
690
- },
691
-
692
- handleClickIcon(event) {
693
- if (this.readonly || this.pickerDisabled) return;
694
- if (this.showClose) {
695
- this.valueOnOpen = this.value;
696
- event.stopPropagation();
697
- this.emitInput(null);
698
- this.emitChange(null);
699
- this.showClose = false;
700
- if (this.picker && typeof this.picker.handleClear === 'function') {
701
- this.picker.handleClear();
702
- }
703
- } else {
704
- this.pickerVisible = !this.pickerVisible;
705
- }
706
- },
707
-
708
- handleClose() {
709
- if (!this.pickerVisible) return;
710
- this.pickerVisible = false;
711
-
712
- if (this.type === 'dates') {
713
- // restore to former value
714
- const oldValue = parseAsFormatAndType(this.valueOnOpen, this.valueFormat, this.type, this.rangeSeparator) || this.valueOnOpen;
715
- this.emitInput(oldValue);
716
- }
717
- },
718
-
719
- handleFieldReset(initialValue) {
720
- this.userInput = initialValue === '' ? null : initialValue;
721
- },
722
-
723
- handleFocus() {
724
- const type = this.type;
725
-
726
- if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1 && !this.pickerVisible) {
727
- this.pickerVisible = true;
728
- }
729
- this.$emit('focus', this);
730
- },
731
-
732
- handleKeydown(event) {
733
- const keyCode = event.keyCode;
734
-
735
- // ESC
736
- if (keyCode === 27) {
737
- this.pickerVisible = false;
738
- event.stopPropagation();
739
- return;
740
- }
741
-
742
- // Tab
743
- if (keyCode === 9) {
744
- if (!this.ranged) {
745
- this.handleChange();
746
- this.pickerVisible = this.picker.visible = false;
747
- this.blur();
748
- event.stopPropagation();
749
- } else {
750
- // user may change focus between two input
751
- setTimeout(() => {
752
- if (this.refInput.indexOf(document.activeElement) === -1) {
753
- this.pickerVisible = false;
754
- this.blur();
755
- event.stopPropagation();
756
- }
757
- }, 0);
758
- }
759
- return;
760
- }
761
-
762
- // Enter
763
- if (keyCode === 13) {
764
- if (this.userInput === '' || this.isValidValue(this.parseString(this.displayValue))) {
765
- this.handleChange();
766
- this.pickerVisible = this.picker.visible = false;
767
- this.blur();
768
- }
769
- event.stopPropagation();
770
- return;
771
- }
772
-
773
- // if user is typing, do not let picker handle key input
774
- if (this.userInput) {
775
- event.stopPropagation();
776
- return;
777
- }
778
-
779
- // delegate other keys to panel
780
- if (this.picker && this.picker.handleKeydown) {
781
- this.picker.handleKeydown(event);
782
- }
783
- },
784
-
785
- handleRangeClick() {
786
- const type = this.type;
787
-
788
- if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1 && !this.pickerVisible) {
789
- this.pickerVisible = true;
790
- }
791
- this.$emit('focus', this);
792
- },
793
-
794
- hidePicker() {
795
- if (this.picker) {
796
- this.picker.resetView && this.picker.resetView();
797
- this.pickerVisible = this.picker.visible = false;
798
- this.destroyPopper();
799
- }
800
- },
801
-
802
- showPicker() {
803
- if (this.$isServer) return;
804
- if (!this.picker) {
805
- this.mountPicker();
806
- }
807
- this.pickerVisible = this.picker.visible = true;
808
-
809
- this.updatePopper();
810
-
811
- this.picker.value = this.parsedValue;
812
- this.picker.resetView && this.picker.resetView();
813
-
814
- this.$nextTick(() => {
815
- this.picker.adjustSpinners && this.picker.adjustSpinners();
816
- });
817
- },
818
-
819
- mountPicker() {
820
- this.picker = new Vue(this.panel).$mount();
821
- this.picker.defaultValue = this.defaultValue;
822
- this.picker.defaultTime = this.defaultTime;
823
- this.picker.popperClass = this.popperClass;
824
- this.popperElm = this.picker.$el;
825
- this.picker.width = this.reference.getBoundingClientRect().width;
826
- this.picker.showTime = this.type === 'datetime' || this.type === 'datetimerange';
827
- this.picker.selectionMode = this.selectionMode;
828
- this.picker.unlinkPanels = this.unlinkPanels;
829
- this.picker.arrowControl = this.arrowControl || this.timeArrowControl || false;
830
- this.$watch('format', (format) => {
831
- this.picker.format = format;
832
- });
833
-
834
- const updateOptions = () => {
835
- const options = this.pickerOptions;
836
-
837
- if (options && options.selectableRange) {
838
- let ranges = options.selectableRange;
839
- const parser = TYPE_VALUE_RESOLVER_MAP.datetimerange.parser;
840
- const format = DEFAULT_FORMATS.timerange;
841
-
842
- ranges = Array.isArray(ranges) ? ranges : [ranges];
843
- this.picker.selectableRange = ranges.map(range => parser(range, format, this.rangeSeparator));
844
- }
845
-
846
- for (const option in options) {
847
- if (options.hasOwnProperty(option) &&
848
- // 忽略 time-picker 的该配置项
849
- option !== 'selectableRange') {
850
- this.picker[option] = options[option];
851
- }
852
- }
853
-
854
- // main format must prevail over undocumented pickerOptions.format
855
- if (this.format) {
856
- this.picker.format = this.format;
857
- }
858
- };
859
- updateOptions();
860
- this.unwatchPickerOptions = this.$watch('pickerOptions', () => updateOptions(), { deep: true });
861
-
862
- this.$el.appendChild(this.picker.$el);
863
- this.picker.resetView && this.picker.resetView();
864
-
865
- this.picker.$on('dodestroy', this.doDestroy);
866
- this.picker.$on('pick', (date = '', visible = false) => {
867
- this.userInput = null;
868
- this.pickerVisible = this.picker.visible = visible;
869
- this.emitInput(date);
870
- this.picker.resetView && this.picker.resetView();
871
- });
872
-
873
- this.picker.$on('select-range', (start, end, pos) => {
874
- if (this.refInput.length === 0) return;
875
- if (!pos || pos === 'min') {
876
- this.refInput[0].setSelectionRange(start, end);
877
- this.refInput[0].focus();
878
- } else if (pos === 'max') {
879
- this.refInput[1].setSelectionRange(start, end);
880
- this.refInput[1].focus();
881
- }
882
- });
883
- },
884
-
885
- unmountPicker() {
886
- if (this.picker) {
887
- this.picker.$destroy();
888
- this.picker.$off();
889
- if (typeof this.unwatchPickerOptions === 'function') {
890
- this.unwatchPickerOptions();
891
- }
892
- this.picker.$el.parentNode.removeChild(this.picker.$el);
893
- }
894
- },
895
-
896
- emitChange(val) {
897
- // determine user real change only
898
- if (!valueEquals(val, this.valueOnOpen)) {
899
- this.$emit('change', val);
900
- this.dispatch('ElFormItem', 'el.form.change', val);
901
- this.valueOnOpen = val;
902
- }
903
- },
904
-
905
- emitInput(val) {
906
- const formatted = this.formatToValue(val);
907
- if (!valueEquals(this.value, formatted)) {
908
- this.$emit('input', formatted);
909
- }
910
- },
911
-
912
- isValidValue(value) {
913
- if (!this.picker) {
914
- this.mountPicker();
915
- }
916
- if (this.picker.isValidValue) {
917
- return value && this.picker.isValidValue(value);
918
- } else {
919
- return true;
920
- }
921
- }
922
- }
923
- };
924
- </script>
1
+ <template>
2
+ <el-input
3
+ class="el-date-editor"
4
+ :class="'el-date-editor--' + type"
5
+ :readonly="!editable || readonly || type === 'dates'"
6
+ :disabled="pickerDisabled"
7
+ :size="pickerSize"
8
+ :name="name"
9
+ v-bind="firstInputId"
10
+ v-if="!ranged"
11
+ v-clickoutside="handleClose"
12
+ :placeholder="placeholder"
13
+ @focus="handleFocus"
14
+ @keydown.native="handleKeydown"
15
+ :value="displayValue"
16
+ @input="value => userInput = value"
17
+ @change="handleChange"
18
+ @mouseenter.native="handleMouseEnter"
19
+ @mouseleave.native="showClose = false"
20
+ :validateEvent="false"
21
+ ref="reference">
22
+ <i slot="prefix"
23
+ class="el-input__icon"
24
+ :class="triggerClass"
25
+ @click="handleFocus">
26
+ </i>
27
+ <i slot="suffix"
28
+ class="el-input__icon"
29
+ @click="handleClickIcon"
30
+ :class="[showClose ? '' + clearIcon : '']"
31
+ v-if="haveTrigger">
32
+ </i>
33
+ </el-input>
34
+ <div
35
+ class="el-date-editor el-range-editor el-input__inner"
36
+ :class="[
37
+ 'el-date-editor--' + type,
38
+ pickerSize ? `el-range-editor--${ pickerSize }` : '',
39
+ pickerDisabled ? 'is-disabled' : '',
40
+ pickerVisible ? 'is-active' : ''
41
+ ]"
42
+ @click="handleRangeClick"
43
+ @mouseenter="handleMouseEnter"
44
+ @mouseleave="showClose = false"
45
+ @keydown="handleKeydown"
46
+ ref="reference"
47
+ v-clickoutside="handleClose"
48
+ v-else>
49
+ <i :class="['el-input__icon', 'el-range__icon', triggerClass]"></i>
50
+ <input
51
+ autocomplete="off"
52
+ :placeholder="startPlaceholder"
53
+ :value="displayValue && displayValue[0]"
54
+ :disabled="pickerDisabled"
55
+ v-bind="firstInputId"
56
+ :readonly="!editable || readonly"
57
+ :name="name && name[0]"
58
+ @input="handleStartInput"
59
+ @change="handleStartChange"
60
+ @focus="handleFocus"
61
+ class="el-range-input">
62
+ <slot name="range-separator">
63
+ <span class="el-range-separator">{{ rangeSeparator }}</span>
64
+ </slot>
65
+ <input
66
+ autocomplete="off"
67
+ :placeholder="endPlaceholder"
68
+ :value="displayValue && displayValue[1]"
69
+ :disabled="pickerDisabled"
70
+ v-bind="secondInputId"
71
+ :readonly="!editable || readonly"
72
+ :name="name && name[1]"
73
+ @input="handleEndInput"
74
+ @change="handleEndChange"
75
+ @focus="handleFocus"
76
+ class="el-range-input">
77
+ <i
78
+ @click="handleClickIcon"
79
+ v-if="haveTrigger"
80
+ :class="[showClose ? '' + clearIcon : '']"
81
+ class="el-input__icon el-range__close-icon">
82
+ </i>
83
+ </div>
84
+ </template>
85
+
86
+ <script>
87
+ import Vue from 'vue';
88
+ import Clickoutside from '@penggy/element-ui/src/utils/clickoutside';
89
+ import { formatDate, parseDate, isDateObject, getWeekNumber } from './util';
90
+ import Popper from '@penggy/element-ui/src/utils/vue-popper';
91
+ import Emitter from '@penggy/element-ui/src/mixins/emitter';
92
+ import ElInput from '@penggy/element-ui/packages/input';
93
+ import merge from '@penggy/element-ui/src/utils/merge';
94
+
95
+ const NewPopper = {
96
+ props: {
97
+ appendToBody: Popper.props.appendToBody,
98
+ offset: Popper.props.offset,
99
+ boundariesPadding: Popper.props.boundariesPadding,
100
+ arrowOffset: Popper.props.arrowOffset
101
+ },
102
+ methods: Popper.methods,
103
+ data() {
104
+ return merge({ visibleArrow: true }, Popper.data);
105
+ },
106
+ beforeDestroy: Popper.beforeDestroy
107
+ };
108
+
109
+ const DEFAULT_FORMATS = {
110
+ date: 'yyyy-MM-dd',
111
+ month: 'yyyy-MM',
112
+ datetime: 'yyyy-MM-dd HH:mm:ss',
113
+ time: 'HH:mm:ss',
114
+ week: 'yyyywWW',
115
+ timerange: 'HH:mm:ss',
116
+ daterange: 'yyyy-MM-dd',
117
+ datetimerange: 'yyyy-MM-dd HH:mm:ss',
118
+ year: 'yyyy'
119
+ };
120
+ const HAVE_TRIGGER_TYPES = [
121
+ 'date',
122
+ 'datetime',
123
+ 'time',
124
+ 'time-select',
125
+ 'week',
126
+ 'month',
127
+ 'year',
128
+ 'daterange',
129
+ 'timerange',
130
+ 'datetimerange',
131
+ 'dates'
132
+ ];
133
+ const DATE_FORMATTER = function(value, format) {
134
+ if (format === 'timestamp') return value.getTime();
135
+ return formatDate(value, format);
136
+ };
137
+ const DATE_PARSER = function(text, format) {
138
+ if (format === 'timestamp') return new Date(Number(text));
139
+ return parseDate(text, format);
140
+ };
141
+ const RANGE_FORMATTER = function(value, format) {
142
+ if (Array.isArray(value) && value.length === 2) {
143
+ const start = value[0];
144
+ const end = value[1];
145
+
146
+ if (start && end) {
147
+ return [DATE_FORMATTER(start, format), DATE_FORMATTER(end, format)];
148
+ }
149
+ }
150
+ return '';
151
+ };
152
+ const RANGE_PARSER = function(array, format, separator) {
153
+ if (!Array.isArray(array)) {
154
+ array = array.split(separator);
155
+ }
156
+ if (array.length === 2) {
157
+ const range1 = array[0];
158
+ const range2 = array[1];
159
+
160
+ return [DATE_PARSER(range1, format), DATE_PARSER(range2, format)];
161
+ }
162
+ return [];
163
+ };
164
+ const TYPE_VALUE_RESOLVER_MAP = {
165
+ default: {
166
+ formatter(value) {
167
+ if (!value) return '';
168
+ return '' + value;
169
+ },
170
+ parser(text) {
171
+ if (text === undefined || text === '') return null;
172
+ return text;
173
+ }
174
+ },
175
+ week: {
176
+ formatter(value, format) {
177
+ let week = getWeekNumber(value);
178
+ let month = value.getMonth();
179
+ const trueDate = new Date(value);
180
+ if (week === 1 && month === 11) {
181
+ trueDate.setHours(0, 0, 0, 0);
182
+ trueDate.setDate(trueDate.getDate() + 3 - (trueDate.getDay() + 6) % 7);
183
+ }
184
+ let date = formatDate(trueDate, format);
185
+
186
+ date = /WW/.test(date)
187
+ ? date.replace(/WW/, week < 10 ? '0' + week : week)
188
+ : date.replace(/W/, week);
189
+ return date;
190
+ },
191
+ parser(text) {
192
+ const array = (text || '').split('w');
193
+ if (array.length === 2) {
194
+ const year = Number(array[0]);
195
+ const month = Number(array[1]);
196
+
197
+ if (!isNaN(year) && !isNaN(month) && month < 54) {
198
+ return text;
199
+ }
200
+ }
201
+ return null;
202
+ }
203
+ },
204
+ date: {
205
+ formatter: DATE_FORMATTER,
206
+ parser: DATE_PARSER
207
+ },
208
+ datetime: {
209
+ formatter: DATE_FORMATTER,
210
+ parser: DATE_PARSER
211
+ },
212
+ daterange: {
213
+ formatter: RANGE_FORMATTER,
214
+ parser: RANGE_PARSER
215
+ },
216
+ datetimerange: {
217
+ formatter: RANGE_FORMATTER,
218
+ parser: RANGE_PARSER
219
+ },
220
+ timerange: {
221
+ formatter: RANGE_FORMATTER,
222
+ parser: RANGE_PARSER
223
+ },
224
+ time: {
225
+ formatter: DATE_FORMATTER,
226
+ parser: DATE_PARSER
227
+ },
228
+ month: {
229
+ formatter: DATE_FORMATTER,
230
+ parser: DATE_PARSER
231
+ },
232
+ year: {
233
+ formatter: DATE_FORMATTER,
234
+ parser: DATE_PARSER
235
+ },
236
+ number: {
237
+ formatter(value) {
238
+ if (!value) return '';
239
+ return '' + value;
240
+ },
241
+ parser(text) {
242
+ let result = Number(text);
243
+
244
+ if (!isNaN(text)) {
245
+ return result;
246
+ } else {
247
+ return null;
248
+ }
249
+ }
250
+ },
251
+ dates: {
252
+ formatter(value, format) {
253
+ return value.map(date => DATE_FORMATTER(date, format));
254
+ },
255
+ parser(value, format) {
256
+ return (typeof value === 'string' ? value.split(', ') : value)
257
+ .map(date => date instanceof Date ? date : DATE_PARSER(date, format));
258
+ }
259
+ }
260
+ };
261
+ const PLACEMENT_MAP = {
262
+ left: 'bottom-start',
263
+ center: 'bottom',
264
+ right: 'bottom-end'
265
+ };
266
+
267
+ const parseAsFormatAndType = (value, customFormat, type, rangeSeparator = '-') => {
268
+ if (!value) return null;
269
+ const parser = (
270
+ TYPE_VALUE_RESOLVER_MAP[type] ||
271
+ TYPE_VALUE_RESOLVER_MAP['default']
272
+ ).parser;
273
+ const format = customFormat || DEFAULT_FORMATS[type];
274
+ return parser(value, format, rangeSeparator);
275
+ };
276
+
277
+ const formatAsFormatAndType = (value, customFormat, type) => {
278
+ if (!value) return null;
279
+ const formatter = (
280
+ TYPE_VALUE_RESOLVER_MAP[type] ||
281
+ TYPE_VALUE_RESOLVER_MAP['default']
282
+ ).formatter;
283
+ const format = customFormat || DEFAULT_FORMATS[type];
284
+ return formatter(value, format);
285
+ };
286
+
287
+ /*
288
+ * Considers:
289
+ * 1. Date object
290
+ * 2. date string
291
+ * 3. array of 1 or 2
292
+ */
293
+ const valueEquals = function(a, b) {
294
+ // considers Date object and string
295
+ const dateEquals = function(a, b) {
296
+ const aIsDate = a instanceof Date;
297
+ const bIsDate = b instanceof Date;
298
+ if (aIsDate && bIsDate) {
299
+ return a.getTime() === b.getTime();
300
+ }
301
+ if (!aIsDate && !bIsDate) {
302
+ return a === b;
303
+ }
304
+ return false;
305
+ };
306
+
307
+ const aIsArray = a instanceof Array;
308
+ const bIsArray = b instanceof Array;
309
+ if (aIsArray && bIsArray) {
310
+ if (a.length !== b.length) {
311
+ return false;
312
+ }
313
+ return a.every((item, index) => dateEquals(item, b[index]));
314
+ }
315
+ if (!aIsArray && !bIsArray) {
316
+ return dateEquals(a, b);
317
+ }
318
+ return false;
319
+ };
320
+
321
+ const isString = function(val) {
322
+ return typeof val === 'string' || val instanceof String;
323
+ };
324
+
325
+ const validator = function(val) {
326
+ // either: String, Array of String, null / undefined
327
+ return (
328
+ val === null ||
329
+ val === undefined ||
330
+ isString(val) ||
331
+ (Array.isArray(val) && val.length === 2 && val.every(isString))
332
+ );
333
+ };
334
+
335
+ export default {
336
+ mixins: [Emitter, NewPopper],
337
+
338
+ inject: {
339
+ elForm: {
340
+ default: ''
341
+ },
342
+ elFormItem: {
343
+ default: ''
344
+ }
345
+ },
346
+
347
+ props: {
348
+ size: String,
349
+ format: String,
350
+ valueFormat: String,
351
+ readonly: Boolean,
352
+ placeholder: String,
353
+ startPlaceholder: String,
354
+ endPlaceholder: String,
355
+ prefixIcon: String,
356
+ clearIcon: {
357
+ type: String,
358
+ default: 'el-icon-circle-close'
359
+ },
360
+ name: {
361
+ default: '',
362
+ validator
363
+ },
364
+ disabled: Boolean,
365
+ clearable: {
366
+ type: Boolean,
367
+ default: true
368
+ },
369
+ id: {
370
+ default: '',
371
+ validator
372
+ },
373
+ popperClass: String,
374
+ editable: {
375
+ type: Boolean,
376
+ default: true
377
+ },
378
+ align: {
379
+ type: String,
380
+ default: 'left'
381
+ },
382
+ value: {},
383
+ defaultValue: {},
384
+ defaultTime: {},
385
+ rangeSeparator: {
386
+ default: '-'
387
+ },
388
+ pickerOptions: {},
389
+ unlinkPanels: Boolean
390
+ },
391
+
392
+ components: { ElInput },
393
+
394
+ directives: { Clickoutside },
395
+
396
+ data() {
397
+ return {
398
+ pickerVisible: false,
399
+ showClose: false,
400
+ userInput: null,
401
+ valueOnOpen: null, // value when picker opens, used to determine whether to emit change
402
+ unwatchPickerOptions: null
403
+ };
404
+ },
405
+
406
+ watch: {
407
+ pickerVisible(val) {
408
+ if (this.readonly || this.pickerDisabled) return;
409
+ if (val) {
410
+ this.showPicker();
411
+ this.valueOnOpen = Array.isArray(this.value) ? [...this.value] : this.value;
412
+ } else {
413
+ this.hidePicker();
414
+ this.emitChange(this.value);
415
+ this.userInput = null;
416
+ this.dispatch('ElFormItem', 'el.form.blur');
417
+ this.$emit('blur', this);
418
+ this.blur();
419
+ }
420
+ },
421
+ parsedValue: {
422
+ immediate: true,
423
+ handler(val) {
424
+ if (this.picker) {
425
+ this.picker.value = val;
426
+ }
427
+ }
428
+ },
429
+ defaultValue(val) {
430
+ // NOTE: should eventually move to jsx style picker + panel ?
431
+ if (this.picker) {
432
+ this.picker.defaultValue = val;
433
+ }
434
+ },
435
+ value(val, oldVal) {
436
+ if (!valueEquals(val, oldVal) && !this.pickerVisible) {
437
+ this.dispatch('ElFormItem', 'el.form.change', val);
438
+ }
439
+ }
440
+ },
441
+
442
+ computed: {
443
+ ranged() {
444
+ return this.type.indexOf('range') > -1;
445
+ },
446
+
447
+ reference() {
448
+ const reference = this.$refs.reference;
449
+ return reference.$el || reference;
450
+ },
451
+
452
+ refInput() {
453
+ if (this.reference) {
454
+ return [].slice.call(this.reference.querySelectorAll('input'));
455
+ }
456
+ return [];
457
+ },
458
+
459
+ valueIsEmpty() {
460
+ const val = this.value;
461
+ if (Array.isArray(val)) {
462
+ for (let i = 0, len = val.length; i < len; i++) {
463
+ if (val[i]) {
464
+ return false;
465
+ }
466
+ }
467
+ } else {
468
+ if (val) {
469
+ return false;
470
+ }
471
+ }
472
+ return true;
473
+ },
474
+
475
+ triggerClass() {
476
+ return this.prefixIcon || (this.type.indexOf('time') !== -1 ? 'el-icon-time' : 'el-icon-date');
477
+ },
478
+
479
+ selectionMode() {
480
+ if (this.type === 'week') {
481
+ return 'week';
482
+ } else if (this.type === 'month') {
483
+ return 'month';
484
+ } else if (this.type === 'year') {
485
+ return 'year';
486
+ } else if (this.type === 'dates') {
487
+ return 'dates';
488
+ }
489
+
490
+ return 'day';
491
+ },
492
+
493
+ haveTrigger() {
494
+ if (typeof this.showTrigger !== 'undefined') {
495
+ return this.showTrigger;
496
+ }
497
+ return HAVE_TRIGGER_TYPES.indexOf(this.type) !== -1;
498
+ },
499
+
500
+ displayValue() {
501
+ const formattedValue = formatAsFormatAndType(this.parsedValue, this.format, this.type, this.rangeSeparator);
502
+ if (Array.isArray(this.userInput)) {
503
+ return [
504
+ this.userInput[0] || (formattedValue && formattedValue[0]) || '',
505
+ this.userInput[1] || (formattedValue && formattedValue[1]) || ''
506
+ ];
507
+ } else if (this.userInput !== null) {
508
+ return this.userInput;
509
+ } else if (formattedValue) {
510
+ return this.type === 'dates'
511
+ ? formattedValue.join(', ')
512
+ : formattedValue;
513
+ } else {
514
+ return '';
515
+ }
516
+ },
517
+
518
+ parsedValue() {
519
+ if (!this.value) return this.value; // component value is not set
520
+ if (this.type === 'time-select') return this.value; // time-select does not require parsing, this might change in next major version
521
+
522
+ const valueIsDateObject = isDateObject(this.value) || (Array.isArray(this.value) && this.value.every(isDateObject));
523
+ if (valueIsDateObject) {
524
+ return this.value;
525
+ }
526
+
527
+ if (this.valueFormat) {
528
+ return parseAsFormatAndType(this.value, this.valueFormat, this.type, this.rangeSeparator) || this.value;
529
+ }
530
+
531
+ // NOTE: deal with common but incorrect usage, should remove in next major version
532
+ // user might provide string / timestamp without value-format, coerce them into date (or array of date)
533
+ return Array.isArray(this.value) ? this.value.map(val => new Date(val)) : new Date(this.value);
534
+ },
535
+
536
+ _elFormItemSize() {
537
+ return (this.elFormItem || {}).elFormItemSize;
538
+ },
539
+
540
+ pickerSize() {
541
+ return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
542
+ },
543
+
544
+ pickerDisabled() {
545
+ return this.disabled || (this.elForm || {}).disabled;
546
+ },
547
+
548
+ firstInputId() {
549
+ const obj = {};
550
+ let id;
551
+ if (this.ranged) {
552
+ id = this.id && this.id[0];
553
+ } else {
554
+ id = this.id;
555
+ }
556
+ if (id) obj.id = id;
557
+ return obj;
558
+ },
559
+
560
+ secondInputId() {
561
+ const obj = {};
562
+ let id;
563
+ if (this.ranged) {
564
+ id = this.id && this.id[1];
565
+ }
566
+ if (id) obj.id = id;
567
+ return obj;
568
+ }
569
+ },
570
+
571
+ created() {
572
+ // vue-popper
573
+ this.popperOptions = {
574
+ boundariesPadding: 0,
575
+ gpuAcceleration: false
576
+ };
577
+ this.placement = PLACEMENT_MAP[this.align] || PLACEMENT_MAP.left;
578
+
579
+ this.$on('fieldReset', this.handleFieldReset);
580
+ },
581
+
582
+ methods: {
583
+ focus() {
584
+ if (!this.ranged) {
585
+ this.$refs.reference.focus();
586
+ } else {
587
+ this.handleFocus();
588
+ }
589
+ },
590
+
591
+ blur() {
592
+ this.refInput.forEach(input => input.blur());
593
+ },
594
+
595
+ // {parse, formatTo} Value deals maps component value with internal Date
596
+ parseValue(value) {
597
+ const isParsed = isDateObject(value) || (Array.isArray(value) && value.every(isDateObject));
598
+ if (this.valueFormat && !isParsed) {
599
+ return parseAsFormatAndType(value, this.valueFormat, this.type, this.rangeSeparator) || value;
600
+ } else {
601
+ return value;
602
+ }
603
+ },
604
+
605
+ formatToValue(date) {
606
+ const isFormattable = isDateObject(date) || (Array.isArray(date) && date.every(isDateObject));
607
+ if (this.valueFormat && isFormattable) {
608
+ return formatAsFormatAndType(date, this.valueFormat, this.type, this.rangeSeparator);
609
+ } else {
610
+ return date;
611
+ }
612
+ },
613
+
614
+ // {parse, formatTo} String deals with user input
615
+ parseString(value) {
616
+ const type = Array.isArray(value) ? this.type : this.type.replace('range', '');
617
+ return parseAsFormatAndType(value, this.format, type);
618
+ },
619
+
620
+ formatToString(value) {
621
+ const type = Array.isArray(value) ? this.type : this.type.replace('range', '');
622
+ return formatAsFormatAndType(value, this.format, type);
623
+ },
624
+
625
+ handleMouseEnter() {
626
+ if (this.readonly || this.pickerDisabled) return;
627
+ if (!this.valueIsEmpty && this.clearable) {
628
+ this.showClose = true;
629
+ }
630
+ },
631
+
632
+ handleChange() {
633
+ if (this.userInput) {
634
+ const value = this.parseString(this.displayValue);
635
+ if (value) {
636
+ this.picker.value = value;
637
+ if (this.isValidValue(value)) {
638
+ this.emitInput(value);
639
+ this.userInput = null;
640
+ }
641
+ }
642
+ }
643
+ if (this.userInput === '') {
644
+ this.emitInput(null);
645
+ this.emitChange(null);
646
+ this.userInput = null;
647
+ }
648
+ },
649
+
650
+ handleStartInput(event) {
651
+ if (this.userInput) {
652
+ this.userInput = [event.target.value, this.userInput[1]];
653
+ } else {
654
+ this.userInput = [event.target.value, null];
655
+ }
656
+ },
657
+
658
+ handleEndInput(event) {
659
+ if (this.userInput) {
660
+ this.userInput = [this.userInput[0], event.target.value];
661
+ } else {
662
+ this.userInput = [null, event.target.value];
663
+ }
664
+ },
665
+
666
+ handleStartChange(event) {
667
+ const value = this.parseString(this.userInput && this.userInput[0]);
668
+ if (value) {
669
+ this.userInput = [this.formatToString(value), this.displayValue[1]];
670
+ const newValue = [value, this.picker.value && this.picker.value[1]];
671
+ this.picker.value = newValue;
672
+ if (this.isValidValue(newValue)) {
673
+ this.emitInput(newValue);
674
+ this.userInput = null;
675
+ }
676
+ }
677
+ },
678
+
679
+ handleEndChange(event) {
680
+ const value = this.parseString(this.userInput && this.userInput[1]);
681
+ if (value) {
682
+ this.userInput = [this.displayValue[0], this.formatToString(value)];
683
+ const newValue = [this.picker.value && this.picker.value[0], value];
684
+ this.picker.value = newValue;
685
+ if (this.isValidValue(newValue)) {
686
+ this.emitInput(newValue);
687
+ this.userInput = null;
688
+ }
689
+ }
690
+ },
691
+
692
+ handleClickIcon(event) {
693
+ if (this.readonly || this.pickerDisabled) return;
694
+ if (this.showClose) {
695
+ this.valueOnOpen = this.value;
696
+ event.stopPropagation();
697
+ this.emitInput(null);
698
+ this.emitChange(null);
699
+ this.showClose = false;
700
+ if (this.picker && typeof this.picker.handleClear === 'function') {
701
+ this.picker.handleClear();
702
+ }
703
+ } else {
704
+ this.pickerVisible = !this.pickerVisible;
705
+ }
706
+ },
707
+
708
+ handleClose() {
709
+ if (!this.pickerVisible) return;
710
+ this.pickerVisible = false;
711
+
712
+ if (this.type === 'dates') {
713
+ // restore to former value
714
+ const oldValue = parseAsFormatAndType(this.valueOnOpen, this.valueFormat, this.type, this.rangeSeparator) || this.valueOnOpen;
715
+ this.emitInput(oldValue);
716
+ }
717
+ },
718
+
719
+ handleFieldReset(initialValue) {
720
+ this.userInput = initialValue === '' ? null : initialValue;
721
+ },
722
+
723
+ handleFocus() {
724
+ const type = this.type;
725
+
726
+ if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1 && !this.pickerVisible) {
727
+ this.pickerVisible = true;
728
+ }
729
+ this.$emit('focus', this);
730
+ },
731
+
732
+ handleKeydown(event) {
733
+ const keyCode = event.keyCode;
734
+
735
+ // ESC
736
+ if (keyCode === 27) {
737
+ this.pickerVisible = false;
738
+ event.stopPropagation();
739
+ return;
740
+ }
741
+
742
+ // Tab
743
+ if (keyCode === 9) {
744
+ if (!this.ranged) {
745
+ this.handleChange();
746
+ this.pickerVisible = this.picker.visible = false;
747
+ this.blur();
748
+ event.stopPropagation();
749
+ } else {
750
+ // user may change focus between two input
751
+ setTimeout(() => {
752
+ if (this.refInput.indexOf(document.activeElement) === -1) {
753
+ this.pickerVisible = false;
754
+ this.blur();
755
+ event.stopPropagation();
756
+ }
757
+ }, 0);
758
+ }
759
+ return;
760
+ }
761
+
762
+ // Enter
763
+ if (keyCode === 13) {
764
+ if (this.userInput === '' || this.isValidValue(this.parseString(this.displayValue))) {
765
+ this.handleChange();
766
+ this.pickerVisible = this.picker.visible = false;
767
+ this.blur();
768
+ }
769
+ event.stopPropagation();
770
+ return;
771
+ }
772
+
773
+ // if user is typing, do not let picker handle key input
774
+ if (this.userInput) {
775
+ event.stopPropagation();
776
+ return;
777
+ }
778
+
779
+ // delegate other keys to panel
780
+ if (this.picker && this.picker.handleKeydown) {
781
+ this.picker.handleKeydown(event);
782
+ }
783
+ },
784
+
785
+ handleRangeClick() {
786
+ const type = this.type;
787
+
788
+ if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1 && !this.pickerVisible) {
789
+ this.pickerVisible = true;
790
+ }
791
+ this.$emit('focus', this);
792
+ },
793
+
794
+ hidePicker() {
795
+ if (this.picker) {
796
+ this.picker.resetView && this.picker.resetView();
797
+ this.pickerVisible = this.picker.visible = false;
798
+ this.destroyPopper();
799
+ }
800
+ },
801
+
802
+ showPicker() {
803
+ if (this.$isServer) return;
804
+ if (!this.picker) {
805
+ this.mountPicker();
806
+ }
807
+ this.pickerVisible = this.picker.visible = true;
808
+
809
+ this.updatePopper();
810
+
811
+ this.picker.value = this.parsedValue;
812
+ this.picker.resetView && this.picker.resetView();
813
+
814
+ this.$nextTick(() => {
815
+ this.picker.adjustSpinners && this.picker.adjustSpinners();
816
+ });
817
+ },
818
+
819
+ mountPicker() {
820
+ this.picker = new Vue(this.panel).$mount();
821
+ this.picker.defaultValue = this.defaultValue;
822
+ this.picker.defaultTime = this.defaultTime;
823
+ this.picker.popperClass = this.popperClass;
824
+ this.popperElm = this.picker.$el;
825
+ this.picker.width = this.reference.getBoundingClientRect().width;
826
+ this.picker.showTime = this.type === 'datetime' || this.type === 'datetimerange';
827
+ this.picker.selectionMode = this.selectionMode;
828
+ this.picker.unlinkPanels = this.unlinkPanels;
829
+ this.picker.arrowControl = this.arrowControl || this.timeArrowControl || false;
830
+ this.$watch('format', (format) => {
831
+ this.picker.format = format;
832
+ });
833
+
834
+ const updateOptions = () => {
835
+ const options = this.pickerOptions;
836
+
837
+ if (options && options.selectableRange) {
838
+ let ranges = options.selectableRange;
839
+ const parser = TYPE_VALUE_RESOLVER_MAP.datetimerange.parser;
840
+ const format = DEFAULT_FORMATS.timerange;
841
+
842
+ ranges = Array.isArray(ranges) ? ranges : [ranges];
843
+ this.picker.selectableRange = ranges.map(range => parser(range, format, this.rangeSeparator));
844
+ }
845
+
846
+ for (const option in options) {
847
+ if (options.hasOwnProperty(option) &&
848
+ // 忽略 time-picker 的该配置项
849
+ option !== 'selectableRange') {
850
+ this.picker[option] = options[option];
851
+ }
852
+ }
853
+
854
+ // main format must prevail over undocumented pickerOptions.format
855
+ if (this.format) {
856
+ this.picker.format = this.format;
857
+ }
858
+ };
859
+ updateOptions();
860
+ this.unwatchPickerOptions = this.$watch('pickerOptions', () => updateOptions(), { deep: true });
861
+
862
+ this.$el.appendChild(this.picker.$el);
863
+ this.picker.resetView && this.picker.resetView();
864
+
865
+ this.picker.$on('dodestroy', this.doDestroy);
866
+ this.picker.$on('pick', (date = '', visible = false) => {
867
+ this.userInput = null;
868
+ this.pickerVisible = this.picker.visible = visible;
869
+ this.emitInput(date);
870
+ this.picker.resetView && this.picker.resetView();
871
+ });
872
+
873
+ this.picker.$on('select-range', (start, end, pos) => {
874
+ if (this.refInput.length === 0) return;
875
+ if (!pos || pos === 'min') {
876
+ this.refInput[0].setSelectionRange(start, end);
877
+ this.refInput[0].focus();
878
+ } else if (pos === 'max') {
879
+ this.refInput[1].setSelectionRange(start, end);
880
+ this.refInput[1].focus();
881
+ }
882
+ });
883
+ },
884
+
885
+ unmountPicker() {
886
+ if (this.picker) {
887
+ this.picker.$destroy();
888
+ this.picker.$off();
889
+ if (typeof this.unwatchPickerOptions === 'function') {
890
+ this.unwatchPickerOptions();
891
+ }
892
+ this.picker.$el.parentNode.removeChild(this.picker.$el);
893
+ }
894
+ },
895
+
896
+ emitChange(val) {
897
+ // determine user real change only
898
+ if (!valueEquals(val, this.valueOnOpen)) {
899
+ this.$emit('change', val);
900
+ this.dispatch('ElFormItem', 'el.form.change', val);
901
+ this.valueOnOpen = val;
902
+ }
903
+ },
904
+
905
+ emitInput(val) {
906
+ const formatted = this.formatToValue(val);
907
+ if (!valueEquals(this.value, formatted)) {
908
+ this.$emit('input', formatted);
909
+ }
910
+ },
911
+
912
+ isValidValue(value) {
913
+ if (!this.picker) {
914
+ this.mountPicker();
915
+ }
916
+ if (this.picker.isValidValue) {
917
+ return value && this.picker.isValidValue(value);
918
+ } else {
919
+ return true;
920
+ }
921
+ }
922
+ }
923
+ };
924
+ </script>