@zkwq/business 0.0.1

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 (231) hide show
  1. package/dist/index.css +1 -0
  2. package/dist/index.js +21861 -0
  3. package/dist/index.umd.cjs +46 -0
  4. package/package.json +27 -0
  5. package/src/components/base/ui/alert/Alert.vue +94 -0
  6. package/src/components/base/ui/autocomplete/autocomplete-suggestions.vue +77 -0
  7. package/src/components/base/ui/autocomplete/autocomplete.vue +305 -0
  8. package/src/components/base/ui/backtop/main.vue +112 -0
  9. package/src/components/base/ui/button/Button.vue +84 -0
  10. package/src/components/base/ui/button/ButtonGroup.vue +10 -0
  11. package/src/components/base/ui/carousel/Carousel.vue +304 -0
  12. package/src/components/base/ui/carousel/CarouselItem.vue +137 -0
  13. package/src/components/base/ui/cascader/cascader.vue +650 -0
  14. package/src/components/base/ui/cascader-panel/cascader-menu.vue +138 -0
  15. package/src/components/base/ui/cascader-panel/cascader-node.vue +246 -0
  16. package/src/components/base/ui/cascader-panel/cascader-panel.vue +382 -0
  17. package/src/components/base/ui/cascader-panel/node.js +166 -0
  18. package/src/components/base/ui/cascader-panel/store.js +62 -0
  19. package/src/components/base/ui/checkbox/checkbox-button.vue +199 -0
  20. package/src/components/base/ui/checkbox/checkbox-group.vue +48 -0
  21. package/src/components/base/ui/checkbox/checkbox.vue +222 -0
  22. package/src/components/base/ui/col/col.js +71 -0
  23. package/src/components/base/ui/collapse/collapse-item.vue +180 -0
  24. package/src/components/base/ui/collapse/collapse.vue +73 -0
  25. package/src/components/base/ui/color-picker/color.js +317 -0
  26. package/src/components/base/ui/color-picker/components/alpha-slider.vue +132 -0
  27. package/src/components/base/ui/color-picker/components/hue-slider.vue +123 -0
  28. package/src/components/base/ui/color-picker/components/picker-dropdown.vue +119 -0
  29. package/src/components/base/ui/color-picker/components/predefine.vue +61 -0
  30. package/src/components/base/ui/color-picker/components/sv-panel.vue +100 -0
  31. package/src/components/base/ui/color-picker/draggable.js +36 -0
  32. package/src/components/base/ui/color-picker/index.js +2 -0
  33. package/src/components/base/ui/color-picker/main.vue +188 -0
  34. package/src/components/base/ui/date-picker/basic/date-table.vue +441 -0
  35. package/src/components/base/ui/date-picker/basic/month-table.vue +254 -0
  36. package/src/components/base/ui/date-picker/basic/time-spinner.vue +304 -0
  37. package/src/components/base/ui/date-picker/basic/year-table.vue +101 -0
  38. package/src/components/base/ui/date-picker/panel/date-range.vue +680 -0
  39. package/src/components/base/ui/date-picker/panel/date.vue +597 -0
  40. package/src/components/base/ui/date-picker/panel/month-range.vue +289 -0
  41. package/src/components/base/ui/date-picker/panel/time-range.vue +248 -0
  42. package/src/components/base/ui/date-picker/panel/time-select.vue +178 -0
  43. package/src/components/base/ui/date-picker/panel/time.vue +186 -0
  44. package/src/components/base/ui/date-picker/picker/date-picker.js +43 -0
  45. package/src/components/base/ui/date-picker/picker/time-picker.js +39 -0
  46. package/src/components/base/ui/date-picker/picker/time-select.js +21 -0
  47. package/src/components/base/ui/date-picker/picker.vue +942 -0
  48. package/src/components/base/ui/dialog/Index.vue +212 -0
  49. package/src/components/base/ui/directive/repeat-click.js +24 -0
  50. package/src/components/base/ui/directive/ripple.js +303 -0
  51. package/src/components/base/ui/divider/Divider.vue +37 -0
  52. package/src/components/base/ui/drawer/Drawer.vue +202 -0
  53. package/src/components/base/ui/dropdown/dropdown-item.vue +39 -0
  54. package/src/components/base/ui/dropdown/dropdown-menu.vue +63 -0
  55. package/src/components/base/ui/dropdown/dropdown.vue +308 -0
  56. package/src/components/base/ui/form/Form.vue +167 -0
  57. package/src/components/base/ui/form/FormItem.vue +334 -0
  58. package/src/components/base/ui/form/LabelWrap.vue +69 -0
  59. package/src/components/base/ui/icon/icon.vue +13 -0
  60. package/src/components/base/ui/image/image-viewer.vue +302 -0
  61. package/src/components/base/ui/image/main.vue +248 -0
  62. package/src/components/base/ui/index.js +189 -0
  63. package/src/components/base/ui/input/Input.vue +438 -0
  64. package/src/components/base/ui/input/calcTextareaHeight.js +104 -0
  65. package/src/components/base/ui/input-number/input-number.vue +285 -0
  66. package/src/components/base/ui/locale/format.js +32 -0
  67. package/src/components/base/ui/locale/index.js +48 -0
  68. package/src/components/base/ui/locale/lang/zh-CN.js +120 -0
  69. package/src/components/base/ui/menu/menu-item-group.vue +45 -0
  70. package/src/components/base/ui/menu/menu-item.vue +112 -0
  71. package/src/components/base/ui/menu/menu-mixin.js +44 -0
  72. package/src/components/base/ui/menu/menu.vue +312 -0
  73. package/src/components/base/ui/menu/submenu.vue +408 -0
  74. package/src/components/base/ui/message/index.js +2 -0
  75. package/src/components/base/ui/message/main.js +87 -0
  76. package/src/components/base/ui/message/main.vue +110 -0
  77. package/src/components/base/ui/message-box/main.js +216 -0
  78. package/src/components/base/ui/message-box/main.vue +323 -0
  79. package/src/components/base/ui/mixin/emitter.js +31 -0
  80. package/src/components/base/ui/mixin/focus.js +9 -0
  81. package/src/components/base/ui/mixin/locale.js +9 -0
  82. package/src/components/base/ui/mixin/migrating.js +33 -0
  83. package/src/components/base/ui/pagination/pager.vue +163 -0
  84. package/src/components/base/ui/pagination/pagination.jsx +391 -0
  85. package/src/components/base/ui/popover/directive.js +20 -0
  86. package/src/components/base/ui/popover/index.js +14 -0
  87. package/src/components/base/ui/popover/main.vue +236 -0
  88. package/src/components/base/ui/progress/Progress.vue +227 -0
  89. package/src/components/base/ui/radio/radio-button.vue +114 -0
  90. package/src/components/base/ui/radio/radio-group.vue +111 -0
  91. package/src/components/base/ui/radio/radio.vue +134 -0
  92. package/src/components/base/ui/row/row.js +47 -0
  93. package/src/components/base/ui/scrollbar/bar.jsx +91 -0
  94. package/src/components/base/ui/scrollbar/index.jsx +203 -0
  95. package/src/components/base/ui/scrollbar/util.js +32 -0
  96. package/src/components/base/ui/select/Option.vue +168 -0
  97. package/src/components/base/ui/select/OptionGroup.vue +60 -0
  98. package/src/components/base/ui/select/Select.vue +920 -0
  99. package/src/components/base/ui/select/SelectDropdown.vue +74 -0
  100. package/src/components/base/ui/select/navigation-mixin.js +54 -0
  101. package/src/components/base/ui/skeleton/index.js +8 -0
  102. package/src/components/base/ui/skeleton/src/img-placeholder.vue +16 -0
  103. package/src/components/base/ui/skeleton/src/index.vue +80 -0
  104. package/src/components/base/ui/skeleton/src/item.vue +22 -0
  105. package/src/components/base/ui/skeleton-item/index.js +8 -0
  106. package/src/components/base/ui/slider/button.vue +238 -0
  107. package/src/components/base/ui/slider/main.vue +427 -0
  108. package/src/components/base/ui/slider/marker.js +18 -0
  109. package/src/components/base/ui/style/alert.scss +147 -0
  110. package/src/components/base/ui/style/animations.scss +65 -0
  111. package/src/components/base/ui/style/autocomplete.scss +81 -0
  112. package/src/components/base/ui/style/backtop.scss +20 -0
  113. package/src/components/base/ui/style/button-group.scss +0 -0
  114. package/src/components/base/ui/style/button.scss +380 -0
  115. package/src/components/base/ui/style/carousel-item.scss +50 -0
  116. package/src/components/base/ui/style/carousel.scss +161 -0
  117. package/src/components/base/ui/style/cascader-panel.scss +120 -0
  118. package/src/components/base/ui/style/cascader.scss +185 -0
  119. package/src/components/base/ui/style/checkbox-button.scss +0 -0
  120. package/src/components/base/ui/style/checkbox-group.scss +0 -0
  121. package/src/components/base/ui/style/checkbox.scss +360 -0
  122. package/src/components/base/ui/style/col.scss +156 -0
  123. package/src/components/base/ui/style/collapse-item.scss +0 -0
  124. package/src/components/base/ui/style/collapse.scss +114 -0
  125. package/src/components/base/ui/style/color-picker.scss +387 -0
  126. package/src/components/base/ui/style/config.scss +4 -0
  127. package/src/components/base/ui/style/date-picker/date-picker.scss +97 -0
  128. package/src/components/base/ui/style/date-picker/date-range-picker.scss +101 -0
  129. package/src/components/base/ui/style/date-picker/date-table.scss +151 -0
  130. package/src/components/base/ui/style/date-picker/month-table.scss +82 -0
  131. package/src/components/base/ui/style/date-picker/picker-panel.scss +117 -0
  132. package/src/components/base/ui/style/date-picker/picker.scss +197 -0
  133. package/src/components/base/ui/style/date-picker/time-picker.scss +85 -0
  134. package/src/components/base/ui/style/date-picker/time-range-picker.scss +31 -0
  135. package/src/components/base/ui/style/date-picker/time-spinner.scss +110 -0
  136. package/src/components/base/ui/style/date-picker/year-table.scss +51 -0
  137. package/src/components/base/ui/style/date-picker.scss +12 -0
  138. package/src/components/base/ui/style/dialog.scss +123 -0
  139. package/src/components/base/ui/style/divider.scss +47 -0
  140. package/src/components/base/ui/style/drawer.scss +218 -0
  141. package/src/components/base/ui/style/dropdown-item.scss +0 -0
  142. package/src/components/base/ui/style/dropdown-menu.scss +0 -0
  143. package/src/components/base/ui/style/dropdown.scss +185 -0
  144. package/src/components/base/ui/style/form-item.scss +0 -0
  145. package/src/components/base/ui/style/form.scss +203 -0
  146. package/src/components/base/ui/style/function.scss +43 -0
  147. package/src/components/base/ui/style/icon.scss +1167 -0
  148. package/src/components/base/ui/style/image.scss +184 -0
  149. package/src/components/base/ui/style/index.scss +57 -0
  150. package/src/components/base/ui/style/input-number.scss +187 -0
  151. package/src/components/base/ui/style/input.scss +477 -0
  152. package/src/components/base/ui/style/menu-item-group.scss +0 -0
  153. package/src/components/base/ui/style/menu-item.scss +0 -0
  154. package/src/components/base/ui/style/menu.scss +294 -0
  155. package/src/components/base/ui/style/message-box.scss +231 -0
  156. package/src/components/base/ui/style/message.scss +120 -0
  157. package/src/components/base/ui/style/mixins.scss +196 -0
  158. package/src/components/base/ui/style/option-group.scss +42 -0
  159. package/src/components/base/ui/style/option.scss +36 -0
  160. package/src/components/base/ui/style/pagination.scss +295 -0
  161. package/src/components/base/ui/style/popover.scss +40 -0
  162. package/src/components/base/ui/style/popper.scss +102 -0
  163. package/src/components/base/ui/style/popup.scss +42 -0
  164. package/src/components/base/ui/style/progress.scss +141 -0
  165. package/src/components/base/ui/style/radio-button.scss +113 -0
  166. package/src/components/base/ui/style/radio-group.scss +9 -0
  167. package/src/components/base/ui/style/radio.scss +203 -0
  168. package/src/components/base/ui/style/ripple.scss +35 -0
  169. package/src/components/base/ui/style/row.scss +39 -0
  170. package/src/components/base/ui/style/scrollbar.scss +75 -0
  171. package/src/components/base/ui/style/select-dropdown.scss +59 -0
  172. package/src/components/base/ui/style/select.scss +154 -0
  173. package/src/components/base/ui/style/skeleton-item.scss +84 -0
  174. package/src/components/base/ui/style/skeleton.scss +40 -0
  175. package/src/components/base/ui/style/slider.scss +250 -0
  176. package/src/components/base/ui/style/switch.scss +116 -0
  177. package/src/components/base/ui/style/tabs.scss +602 -0
  178. package/src/components/base/ui/style/tag.scss +174 -0
  179. package/src/components/base/ui/style/tooltip.scss +146 -0
  180. package/src/components/base/ui/style/transition.scss +138 -0
  181. package/src/components/base/ui/style/upload.scss +603 -0
  182. package/src/components/base/ui/style/utils.scss +39 -0
  183. package/src/components/base/ui/style/var.scss +1007 -0
  184. package/src/components/base/ui/switch/index.vue +174 -0
  185. package/src/components/base/ui/tabs/tab-bar.vue +57 -0
  186. package/src/components/base/ui/tabs/tab-nav.vue +294 -0
  187. package/src/components/base/ui/tabs/tab-pane.vue +56 -0
  188. package/src/components/base/ui/tabs/tabs.vue +191 -0
  189. package/src/components/base/ui/tag/Tag.vue +60 -0
  190. package/src/components/base/ui/tooltip/tooltip.jsx +234 -0
  191. package/src/components/base/ui/upload/Index.vue +340 -0
  192. package/src/components/base/ui/upload/Upload.vue +216 -0
  193. package/src/components/base/ui/upload/UploadDragger.vue +70 -0
  194. package/src/components/base/ui/upload/UploadList.vue +100 -0
  195. package/src/components/base/ui/upload/ajax.js +85 -0
  196. package/src/components/base/ui/util/aria-dialog.js +90 -0
  197. package/src/components/base/ui/util/aria-utils.js +122 -0
  198. package/src/components/base/ui/util/clickoutside.js +76 -0
  199. package/src/components/base/ui/util/date-util.js +292 -0
  200. package/src/components/base/ui/util/date.js +370 -0
  201. package/src/components/base/ui/util/debounce.js +21 -0
  202. package/src/components/base/ui/util/deepmerge.js +100 -0
  203. package/src/components/base/ui/util/dom.js +215 -0
  204. package/src/components/base/ui/util/index.js +262 -0
  205. package/src/components/base/ui/util/menu/aria-menubar.js +14 -0
  206. package/src/components/base/ui/util/menu/aria-menuitem.js +49 -0
  207. package/src/components/base/ui/util/menu/aria-submenu.js +59 -0
  208. package/src/components/base/ui/util/merge.js +14 -0
  209. package/src/components/base/ui/util/popper.js +1235 -0
  210. package/src/components/base/ui/util/popup/index.js +218 -0
  211. package/src/components/base/ui/util/popup/popup-manager.js +194 -0
  212. package/src/components/base/ui/util/resize-events.js +32 -0
  213. package/src/components/base/ui/util/scroll-into-view.js +27 -0
  214. package/src/components/base/ui/util/scrollbar-width.js +29 -0
  215. package/src/components/base/ui/util/shared.js +7 -0
  216. package/src/components/base/ui/util/throttle.js +91 -0
  217. package/src/components/base/ui/util/types.js +24 -0
  218. package/src/components/base/ui/util/vdom.js +5 -0
  219. package/src/components/base/ui/util/vue-popper.js +188 -0
  220. package/src/components/normal/AggsItemH.vue +139 -0
  221. package/src/index.js +10 -0
  222. package/src/static/base-icons.ttf +0 -0
  223. package/src/static/base-icons.woff +0 -0
  224. package/src/static/label_bg.png +0 -0
  225. package/src/static/term-label-bg.png +0 -0
  226. package/src/style/app-article.scss +698 -0
  227. package/src/style/app-comment.scss +259 -0
  228. package/src/style/app-recommend.scss +48 -0
  229. package/src/style/app-richtext.scss +176 -0
  230. package/src/style/index.scss +523 -0
  231. package/vite.config.js +38 -0
@@ -0,0 +1,920 @@
1
+ <template>
2
+ <div
3
+ class="base-select"
4
+ :class="[selectSize ? 'base-select--' + selectSize : '']"
5
+ @click.stop="toggleMenu"
6
+ v-clickoutside="handleClose">
7
+ <div
8
+ class="base-select__tags"
9
+ v-if="multiple"
10
+ ref="tags"
11
+ :style="{ 'max-width': inputWidth - 32 + 'px', width: '100%' }">
12
+ <span v-if="collapseTags && selected.length">
13
+ <base-tag
14
+ :closable="!selectDisabled"
15
+ :size="collapseTagSize"
16
+ :hit="selected[0].hitState"
17
+ type="info"
18
+ @close="deleteTag($event, selected[0])"
19
+ disable-transitions>
20
+ <span class="base-select__tags-text">{{ selected[0].currentLabel }}</span>
21
+ </base-tag>
22
+ <base-tag
23
+ v-if="selected.length > 1"
24
+ :closable="false"
25
+ :size="collapseTagSize"
26
+ type="info"
27
+ disable-transitions>
28
+ <span class="base-select__tags-text">+ {{ selected.length - 1 }}</span>
29
+ </base-tag>
30
+ </span>
31
+ <transition-group @after-leave="resetInputHeight" v-if="!collapseTags">
32
+ <base-tag
33
+ v-for="item in selected"
34
+ :key="getValueKey(item)"
35
+ :closable="!selectDisabled"
36
+ :size="collapseTagSize"
37
+ :hit="item.hitState"
38
+ type="info"
39
+ @close="deleteTag($event, item)"
40
+ disable-transitions>
41
+ <span class="base-select__tags-text">{{ item.currentLabel }}</span>
42
+ </base-tag>
43
+ </transition-group>
44
+
45
+ <input
46
+ type="text"
47
+ class="base-select__input"
48
+ :class="[selectSize ? `is-${ selectSize }` : '']"
49
+ :disabled="selectDisabled"
50
+ :autocomplete="autoComplete || autocomplete"
51
+ @focus="handleFocus"
52
+ @blur="handleNativeBlur"
53
+ @keyup="managePlaceholder"
54
+ @keydown="resetInputState"
55
+ @keydown.down.prevent="navigateOptions('next')"
56
+ @keydown.up.prevent="navigateOptions('prev')"
57
+ @keydown.enter.prevent="selectOption"
58
+ @keydown.esc.stop.prevent="visible = false"
59
+ @keydown.delete="deletePrevTag"
60
+ @keydown.tab="visible = false"
61
+ @compositionstart="handleComposition"
62
+ @compositionupdate="handleComposition"
63
+ @compositionend="handleComposition"
64
+ v-model="query"
65
+ @input="debouncedQueryChange"
66
+ v-if="filterable"
67
+ :style="{ 'flex-grow': '1', width: inputLength / (inputWidth - 32) + '%', 'max-width': inputWidth - 42 + 'px' }"
68
+ ref="input">
69
+ </div>
70
+ <base-input
71
+ ref="reference"
72
+ v-model="selectedLabel"
73
+ type="text"
74
+ :placeholder="currentPlaceholder"
75
+ :name="name"
76
+ :id="id"
77
+ :ripple="ripple"
78
+ :autocomplete="autoComplete || autocomplete"
79
+ :size="selectSize"
80
+ :disabled="selectDisabled"
81
+ :readonly="readonly"
82
+ :validate-event="false"
83
+ :class="{ 'is-focused': visible }"
84
+ :tabindex="(multiple && filterable) ? '-1' : null"
85
+ :enable-focus-class="false"
86
+ :show-label="showLabel"
87
+ @focus="handleFocus"
88
+ @blur="handleBlur"
89
+ @keyup.native="debouncedOnInputChange"
90
+ @keydown.native.down.stop.prevent="navigateOptions('next')"
91
+ @keydown.native.up.stop.prevent="navigateOptions('prev')"
92
+ @keydown.native.enter.prevent="selectOption"
93
+ @keydown.native.esc.stop.prevent="visible = false"
94
+ @keydown.native.tab="visible = false"
95
+ @paste.native="debouncedOnInputChange"
96
+ @mouseenter.native="inputHovering = true"
97
+ @mouseleave.native="inputHovering = false">
98
+ <template slot="prefix" v-if="$slots.prefix">
99
+ <slot name="prefix"></slot>
100
+ </template>
101
+ <template slot="suffix">
102
+ <i v-show="!showClose" :class="['base-select__caret', 'base-input__icon', 'base-icon-' + iconClass]"></i>
103
+ <i v-if="showClose" class="base-select__caret base-input__icon base-icon-close" @click="handleClearClick"></i>
104
+ </template>
105
+ </base-input>
106
+ <transition
107
+ name="base-zoom-in-top"
108
+ @before-enter="handleMenuEnter"
109
+ @after-leave="doDestroy">
110
+ <base-select-menu
111
+ ref="popper"
112
+ :placement="placement"
113
+ :visibleArrow="visibleArrow"
114
+ :append-to-body="popperAppendToBody"
115
+ v-show="visible && emptyText !== false">
116
+ <base-scrollbar
117
+ tag="ul"
118
+ wrap-class="base-select-dropdown__wrap"
119
+ view-class="base-select-dropdown__list"
120
+ :alone="true"
121
+ ref="scrollbar"
122
+ :class="{ 'is-empty': !allowCreate && query && filteredOptionsCount === 0 }"
123
+ v-show="options.length > 0 && !loading">
124
+ <base-option
125
+ :value="query"
126
+ created
127
+ v-if="showNewOption">
128
+ </base-option>
129
+ <slot></slot>
130
+ </base-scrollbar>
131
+ <template v-if="emptyText && (!allowCreate || loading || (allowCreate && options.length === 0 ))">
132
+ <slot name="empty" v-if="$slots.empty"></slot>
133
+ <p class="base-select-dropdown__empty" v-else>
134
+ {{ emptyText }}
135
+ </p>
136
+ </template>
137
+ </base-select-menu>
138
+ </transition>
139
+ </div>
140
+ </template>
141
+
142
+ <script type="text/babel">
143
+ import Emitter from '../mixin/emitter'
144
+ import Focus from '../mixin/focus'
145
+ import Locale from '../mixin/locale'
146
+ import BaseInput from '../input/Input'
147
+ import BaseSelectMenu from './SelectDropdown'
148
+ import BaseOption from './Option'
149
+ import BaseTag from '../tag/Tag'
150
+ import BaseScrollbar from '../scrollbar/index'
151
+ import debounce from '../util/debounce'
152
+ import Clickoutside from '../util/clickoutside'
153
+ import { addResizeListener, removeResizeListener } from '../util/resize-events'
154
+ import { t } from '../locale/index'
155
+ import scrollIntoView from '../util/scroll-into-view'
156
+ import { getValueByPath, valueEquals, isIE, isEdge } from '../util/index'
157
+ import NavigationMixin from './navigation-mixin'
158
+ import { isKorean } from '../util/shared'
159
+
160
+ export default {
161
+ mixins: [Emitter, Locale, Focus('reference'), NavigationMixin],
162
+
163
+ name: 'BaseSelect',
164
+
165
+ componentName: 'BaseSelect',
166
+
167
+ inject: {
168
+ baseForm: {
169
+ default: ''
170
+ },
171
+
172
+ baseFormItem: {
173
+ default: ''
174
+ }
175
+ },
176
+
177
+ provide() {
178
+ return {
179
+ 'select': this
180
+ }
181
+ },
182
+
183
+ computed: {
184
+ _baseFormItemSize() {
185
+ return (this.baseFormItem || {}).baseFormItemSize
186
+ },
187
+
188
+ readonly() {
189
+ return !this.filterable || this.multiple || (!isIE() && !isEdge() && !this.visible)
190
+ },
191
+
192
+ showClose() {
193
+ let hasValue = this.multiple
194
+ ? Array.isArray(this.value) && this.value.length > 0
195
+ : this.value !== undefined && this.value !== null && this.value !== ''
196
+ let criteria = this.clearable &&
197
+ !this.selectDisabled &&
198
+ this.inputHovering &&
199
+ hasValue
200
+ return criteria
201
+ },
202
+
203
+ iconClass() {
204
+ return this.remote && this.filterable ? '' : (this.visible ? 'caret-top is-reverse' : 'caret-top')
205
+ },
206
+
207
+ debounce() {
208
+ return this.remote ? 300 : 0
209
+ },
210
+
211
+ emptyText() {
212
+ if (this.loading) {
213
+ return this.loadingText || this.t('base.select.loading')
214
+ } else {
215
+ if (this.remote && this.query === '' && this.options.length === 0) return false
216
+ if (this.filterable && this.query && this.options.length > 0 && this.filteredOptionsCount === 0) {
217
+ return this.noMatchText || this.t('base.select.noMatch')
218
+ }
219
+ if (this.options.length === 0) {
220
+ return this.noDataText || this.t('base.select.noData')
221
+ }
222
+ }
223
+ return null
224
+ },
225
+
226
+ showNewOption() {
227
+ let hasExistingOption = this.options.filter(option => !option.created)
228
+ .some(option => option.currentLabel === this.query)
229
+ return this.filterable && this.allowCreate && this.query !== '' && !hasExistingOption
230
+ },
231
+
232
+ selectSize() {
233
+ return this.size || this._baseFormItemSize || (this.$ELEMENT || {}).size
234
+ },
235
+
236
+ selectDisabled() {
237
+ return this.disabled || (this.baseForm || {}).disabled
238
+ },
239
+
240
+ collapseTagSize() {
241
+ return ['small', 'mini'].indexOf(this.selectSize) > -1
242
+ ? 'mini'
243
+ : 'small'
244
+ }
245
+ },
246
+
247
+ components: {
248
+ BaseInput,
249
+ BaseSelectMenu,
250
+ BaseOption,
251
+ BaseTag,
252
+ BaseScrollbar
253
+ },
254
+
255
+ directives: { Clickoutside },
256
+
257
+ props: {
258
+ name: String,
259
+ id: String,
260
+ value: {
261
+ required: true
262
+ },
263
+ autocomplete: {
264
+ type: String,
265
+ default: 'off'
266
+ },
267
+ /** @Deprecated in next major version */
268
+ autoComplete: {
269
+ type: String,
270
+ validator(val) {
271
+ process.env.NODE_ENV !== 'production' &&
272
+ console.warn('[Baseement Warn][Select]\'auto-complete\' property will be deprecated in next major version. please use \'autocomplete\' instead.')
273
+ return true
274
+ }
275
+ },
276
+ automaticDropdown: Boolean,
277
+ size: String,
278
+ disabled: Boolean,
279
+ clearable: Boolean,
280
+ filterable: Boolean,
281
+ allowCreate: Boolean,
282
+ loading: Boolean,
283
+ popperClass: String,
284
+ remote: Boolean,
285
+ loadingText: String,
286
+ noMatchText: String,
287
+ noDataText: String,
288
+ remoteMethod: Function,
289
+ filterMethod: Function,
290
+ multiple: Boolean,
291
+ multipleLimit: {
292
+ type: Number,
293
+ default: 0
294
+ },
295
+ placeholder: {
296
+ type: String,
297
+ default() {
298
+ return t('base.select.placeholder')
299
+ }
300
+ },
301
+ defaultFirstOption: Boolean,
302
+ reserveKeyword: Boolean,
303
+ valueKey: {
304
+ type: String,
305
+ default: 'value'
306
+ },
307
+ collapseTags: Boolean,
308
+ popperAppendToBody: {
309
+ type: Boolean,
310
+ default: true
311
+ },
312
+ ripple: {
313
+ type: Boolean,
314
+ default: true
315
+ },
316
+ showLabel: {
317
+ type: Boolean,
318
+ default: true
319
+ },
320
+ placement: {
321
+ default: 'bottom-start'
322
+ },
323
+ visibleArrow: {
324
+ default: false
325
+ }
326
+ },
327
+
328
+ data() {
329
+ return {
330
+ options: [],
331
+ cachedOptions: [],
332
+ createdLabel: null,
333
+ createdSelected: false,
334
+ selected: this.multiple ? [] : {},
335
+ inputLength: 20,
336
+ inputWidth: 0,
337
+ initialInputHeight: 0,
338
+ cachedPlaceHolder: '',
339
+ optionsCount: 0,
340
+ filteredOptionsCount: 0,
341
+ visible: false,
342
+ softFocus: false,
343
+ selectedLabel: '',
344
+ hoverIndex: -1,
345
+ query: '',
346
+ previousQuery: null,
347
+ inputHovering: false,
348
+ currentPlaceholder: '',
349
+ menuVisibleOnFocus: false,
350
+ isOnComposition: false,
351
+ isSilentBlur: false
352
+ }
353
+ },
354
+
355
+ watch: {
356
+ selectDisabled() {
357
+ this.$nextTick(() => {
358
+ this.resetInputHeight()
359
+ })
360
+ },
361
+
362
+ placeholder(val) {
363
+ this.cachedPlaceHolder = this.currentPlaceholder = val
364
+ },
365
+
366
+ value(val, oldVal) {
367
+ if (this.multiple) {
368
+ this.resetInputHeight()
369
+ if ((val && val.length > 0) || (this.$refs.input && this.query !== '')) {
370
+ this.currentPlaceholder = ''
371
+ } else {
372
+ this.currentPlaceholder = this.cachedPlaceHolder
373
+ }
374
+ if (this.filterable && !this.reserveKeyword) {
375
+ this.query = ''
376
+ this.handleQueryChange(this.query)
377
+ }
378
+ }
379
+ this.setSelected()
380
+ if (this.filterable && !this.multiple) {
381
+ this.inputLength = 20
382
+ }
383
+ if (!valueEquals(val, oldVal)) {
384
+ this.dispatch('BaseFormItem', 'base.form.change', val)
385
+ }
386
+ },
387
+
388
+ visible(val) {
389
+ if (!val) {
390
+ this.broadcast('BaseSelectDropdown', 'destroyPopper')
391
+ if (this.$refs.input) {
392
+ this.$refs.input.blur()
393
+ }
394
+ this.query = ''
395
+ this.previousQuery = null
396
+ this.selectedLabel = ''
397
+ this.inputLength = 20
398
+ this.menuVisibleOnFocus = false
399
+ this.resetHoverIndex()
400
+ this.$nextTick(() => {
401
+ if (this.$refs.input &&
402
+ this.$refs.input.value === '' &&
403
+ this.selected.length === 0) {
404
+ this.currentPlaceholder = this.cachedPlaceHolder
405
+ }
406
+ })
407
+ if (!this.multiple) {
408
+ if (this.selected) {
409
+ if (this.filterable && this.allowCreate &&
410
+ this.createdSelected && this.createdLabel) {
411
+ this.selectedLabel = this.createdLabel
412
+ } else {
413
+ this.selectedLabel = this.selected.currentLabel
414
+ }
415
+ if (this.filterable) this.query = this.selectedLabel
416
+ }
417
+
418
+ if (this.filterable) {
419
+ this.currentPlaceholder = this.cachedPlaceHolder
420
+ }
421
+ }
422
+ } else {
423
+ this.broadcast('BaseSelectDropdown', 'updatePopper')
424
+ if (this.filterable) {
425
+ this.query = this.remote ? '' : this.selectedLabel
426
+ this.handleQueryChange(this.query)
427
+ if (this.multiple) {
428
+ this.$refs.input.focus()
429
+ } else {
430
+ if (!this.remote) {
431
+ this.broadcast('BaseOption', 'queryChange', '')
432
+ this.broadcast('BaseOptionGroup', 'queryChange')
433
+ }
434
+
435
+ if (this.selectedLabel) {
436
+ this.currentPlaceholder = this.selectedLabel
437
+ this.selectedLabel = ''
438
+ }
439
+ }
440
+ }
441
+ }
442
+ this.$emit('visible-change', val)
443
+ },
444
+
445
+ options() {
446
+ if (this.$isServer) return
447
+ this.$nextTick(() => {
448
+ this.broadcast('BaseSelectDropdown', 'updatePopper')
449
+ })
450
+ if (this.multiple) {
451
+ this.resetInputHeight()
452
+ }
453
+ let inputs = this.$el.querySelectorAll('input')
454
+ if ([].indexOf.call(inputs, document.activeElement) === -1) {
455
+ this.setSelected()
456
+ }
457
+ if (this.defaultFirstOption && (this.filterable || this.remote) && this.filteredOptionsCount) {
458
+ this.checkDefaultFirstOption()
459
+ }
460
+ }
461
+ },
462
+
463
+ methods: {
464
+ handleComposition(event) {
465
+ const text = event.target.value
466
+ if (event.type === 'compositionend') {
467
+ this.isOnComposition = false
468
+ this.$nextTick(_ => this.handleQueryChange(text))
469
+ } else {
470
+ const lastCharacter = text[text.length - 1] || ''
471
+ this.isOnComposition = !isKorean(lastCharacter)
472
+ }
473
+ },
474
+ handleQueryChange(val) {
475
+ if (this.previousQuery === val || this.isOnComposition) return
476
+ if (
477
+ this.previousQuery === null &&
478
+ (typeof this.filterMethod === 'function' || typeof this.remoteMethod === 'function')
479
+ ) {
480
+ this.previousQuery = val
481
+ return
482
+ }
483
+ this.previousQuery = val
484
+ this.$nextTick(() => {
485
+ if (this.visible) this.broadcast('BaseSelectDropdown', 'updatePopper')
486
+ })
487
+ this.hoverIndex = -1
488
+ if (this.multiple && this.filterable) {
489
+ this.$nextTick(() => {
490
+ const length = this.$refs.input.value.length * 15 + 20
491
+ this.inputLength = this.collapseTags ? Math.min(50, length) : length
492
+ this.managePlaceholder()
493
+ this.resetInputHeight()
494
+ })
495
+ }
496
+ if (this.remote && typeof this.remoteMethod === 'function') {
497
+ this.hoverIndex = -1
498
+ this.remoteMethod(val)
499
+ } else if (typeof this.filterMethod === 'function') {
500
+ this.filterMethod(val)
501
+ this.broadcast('BaseOptionGroup', 'queryChange')
502
+ } else {
503
+ this.filteredOptionsCount = this.optionsCount
504
+ this.broadcast('BaseOption', 'queryChange', val)
505
+ this.broadcast('BaseOptionGroup', 'queryChange')
506
+ }
507
+ if (this.defaultFirstOption && (this.filterable || this.remote) && this.filteredOptionsCount) {
508
+ this.checkDefaultFirstOption()
509
+ }
510
+ },
511
+
512
+ scrollToOption(option) {
513
+ const target = Array.isArray(option) && option[0] ? option[0].$el : option.$el
514
+ if (this.$refs.popper && target) {
515
+ const menu = this.$refs.popper.$el.querySelector('.base-select-dropdown__wrap')
516
+ scrollIntoView(menu, target)
517
+ }
518
+ this.$refs.scrollbar && this.$refs.scrollbar.handleScroll()
519
+ },
520
+
521
+ handleMenuEnter() {
522
+ this.$nextTick(() => this.scrollToOption(this.selected))
523
+ },
524
+
525
+ emitChange(val) {
526
+ if (!valueEquals(this.value, val)) {
527
+ this.$emit('change', val)
528
+ }
529
+ },
530
+
531
+ getOption(value) {
532
+ let option
533
+ const isObject = Object.prototype.toString.call(value).toLowerCase() === '[object object]'
534
+ const isNull = Object.prototype.toString.call(value).toLowerCase() === '[object null]'
535
+ const isUndefined = Object.prototype.toString.call(value).toLowerCase() === '[object undefined]'
536
+
537
+ for (let i = this.cachedOptions.length - 1; i >= 0; i--) {
538
+ const cachedOption = this.cachedOptions[i]
539
+ const isEqual = isObject
540
+ ? getValueByPath(cachedOption.value, this.valueKey) === getValueByPath(value, this.valueKey)
541
+ : cachedOption.value === value
542
+ if (isEqual) {
543
+ option = cachedOption
544
+ break
545
+ }
546
+ }
547
+ if (option) return option
548
+ const label = (!isObject && !isNull && !isUndefined)
549
+ ? value : ''
550
+ let newOption = {
551
+ value: value,
552
+ currentLabel: label
553
+ }
554
+ if (this.multiple) {
555
+ newOption.hitState = false
556
+ }
557
+ return newOption
558
+ },
559
+
560
+ setSelected() {
561
+ if (!this.multiple) {
562
+ let option = this.getOption(this.value)
563
+ if (option.created) {
564
+ this.createdLabel = option.currentLabel
565
+ this.createdSelected = true
566
+ } else {
567
+ this.createdSelected = false
568
+ }
569
+ this.selectedLabel = option.currentLabel
570
+ this.selected = option
571
+ if (this.filterable) this.query = this.selectedLabel
572
+ return
573
+ }
574
+ let result = []
575
+ if (Array.isArray(this.value)) {
576
+ this.value.forEach(value => {
577
+ result.push(this.getOption(value))
578
+ })
579
+ }
580
+ this.selected = result
581
+ this.$nextTick(() => {
582
+ this.resetInputHeight()
583
+ })
584
+ },
585
+
586
+ handleFocus(event) {
587
+ this.dispatch('BaseFormItem', 'clearValidate')
588
+ if (!this.softFocus) {
589
+ if (this.automaticDropdown || this.filterable) {
590
+ this.visible = true
591
+ if (this.filterable) {
592
+ this.menuVisibleOnFocus = true
593
+ }
594
+ }
595
+ this.$emit('focus', event)
596
+ } else {
597
+ this.$emit('soft-focus', event)
598
+ this.softFocus = false
599
+ }
600
+ },
601
+
602
+ blur() {
603
+ this.visible = false
604
+ this.$refs.reference.blur()
605
+ this.dispatch('BaseFormItem', 'base.form.blur')
606
+ },
607
+
608
+ handleBlur(event) {
609
+ setTimeout(() => {
610
+ if (this.isSilentBlur) {
611
+ this.isSilentBlur = false
612
+ this.$emit('silent-blur', event)
613
+ } else {
614
+ this.$emit('blur', event)
615
+ }
616
+ }, 50)
617
+ this.softFocus = false
618
+ },
619
+ handleNativeBlur () {
620
+ this.$emit('native-blur', event)
621
+ this.softFocus = false
622
+ this.dispatch('BaseFormItem', 'base.form.blur')
623
+ },
624
+ handleClearClick(event) {
625
+ this.deleteSelected(event)
626
+ },
627
+
628
+ doDestroy() {
629
+ this.$refs.popper && this.$refs.popper.doDestroy()
630
+ },
631
+
632
+ handleClose() {
633
+ this.visible = false
634
+ },
635
+
636
+ toggleLastOptionHitState(hit) {
637
+ if (!Array.isArray(this.selected)) return
638
+ const option = this.selected[this.selected.length - 1]
639
+ if (!option) return
640
+
641
+ if (hit === true || hit === false) {
642
+ option.hitState = hit
643
+ return hit
644
+ }
645
+
646
+ option.hitState = !option.hitState
647
+ return option.hitState
648
+ },
649
+
650
+ deletePrevTag(e) {
651
+ if (e.target.value.length <= 0 && !this.toggleLastOptionHitState()) {
652
+ const value = this.value.slice()
653
+ value.pop()
654
+ this.$emit('input', value)
655
+ this.emitChange(value)
656
+ }
657
+ },
658
+
659
+ managePlaceholder() {
660
+ if (this.currentPlaceholder !== '') {
661
+ this.currentPlaceholder = this.$refs.input.value ? '' : this.cachedPlaceHolder
662
+ }
663
+ },
664
+
665
+ resetInputState(e) {
666
+ if (e.keyCode !== 8) this.toggleLastOptionHitState(false)
667
+ this.inputLength = this.$refs.input.value.length * 15 + 20
668
+ this.resetInputHeight()
669
+ },
670
+
671
+ resetInputHeight() {
672
+ if (this.collapseTags && !this.filterable) return
673
+ this.$nextTick(() => {
674
+ if (!this.$refs.reference) return
675
+ let inputChildNodes = this.$refs.reference.$el.childNodes
676
+ let input = [].filter.call(inputChildNodes, item => item.tagName === 'INPUT')[0]
677
+ const tags = this.$refs.tags
678
+ const sizeInMap = this.initialInputHeight || 40
679
+ input.style.height = this.selected.length === 0
680
+ ? sizeInMap + 'px'
681
+ : Math.max(
682
+ tags ? (tags.clientHeight + (tags.clientHeight > sizeInMap ? 6 : 0)) : 0,
683
+ sizeInMap
684
+ ) + 'px'
685
+ if (this.visible && this.emptyText !== false) {
686
+ this.broadcast('BaseSelectDropdown', 'updatePopper')
687
+ }
688
+ })
689
+ },
690
+
691
+ resetHoverIndex() {
692
+ setTimeout(() => {
693
+ if (!this.multiple) {
694
+ this.hoverIndex = this.options.indexOf(this.selected)
695
+ } else {
696
+ if (this.selected.length > 0) {
697
+ this.hoverIndex = Math.min.apply(null, this.selected.map(item => this.options.indexOf(item)))
698
+ } else {
699
+ this.hoverIndex = -1
700
+ }
701
+ }
702
+ }, 300)
703
+ },
704
+
705
+ handleOptionSelect(option, byClick) {
706
+ if (this.multiple) {
707
+ const value = (this.value || []).slice()
708
+ const optionIndex = this.getValueIndex(value, option.value)
709
+ if (optionIndex > -1) {
710
+ value.splice(optionIndex, 1)
711
+ } else if (this.multipleLimit <= 0 || value.length < this.multipleLimit) {
712
+ value.push(option.value)
713
+ }
714
+ this.$emit('input', value)
715
+ this.emitChange(value)
716
+ if (option.created) {
717
+ this.query = ''
718
+ this.handleQueryChange('')
719
+ this.inputLength = 20
720
+ }
721
+ if (this.filterable) this.$refs.input.focus()
722
+ } else {
723
+ this.$emit('input', option.value)
724
+ this.emitChange(option.value)
725
+ this.visible = false
726
+ }
727
+ this.isSilentBlur = byClick
728
+ this.setSoftFocus()
729
+ if (this.visible) return
730
+ this.$nextTick(() => {
731
+ this.scrollToOption(option)
732
+ })
733
+ },
734
+
735
+ setSoftFocus() {
736
+ this.softFocus = true
737
+ const input = this.$refs.input || this.$refs.reference
738
+ if (input) {
739
+ input.focus()
740
+ }
741
+ },
742
+
743
+ getValueIndex(arr = [], value) {
744
+ const isObject = Object.prototype.toString.call(value).toLowerCase() === '[object object]'
745
+ if (!isObject) {
746
+ return arr.indexOf(value)
747
+ } else {
748
+ const valueKey = this.valueKey
749
+ let index = -1
750
+ arr.some((item, i) => {
751
+ if (getValueByPath(item, valueKey) === getValueByPath(value, valueKey)) {
752
+ index = i
753
+ return true
754
+ }
755
+ return false
756
+ })
757
+ return index
758
+ }
759
+ },
760
+
761
+ toggleMenu() {
762
+ if (!this.selectDisabled) {
763
+ if (this.menuVisibleOnFocus) {
764
+ this.menuVisibleOnFocus = false
765
+ } else {
766
+ this.visible = !this.visible
767
+ }
768
+ if (this.visible) {
769
+ (this.$refs.input || this.$refs.reference).focus()
770
+ }
771
+ }
772
+ },
773
+
774
+ selectOption() {
775
+ if (!this.visible) {
776
+ this.toggleMenu()
777
+ } else {
778
+ if (this.options[this.hoverIndex]) {
779
+ this.handleOptionSelect(this.options[this.hoverIndex])
780
+ }
781
+ }
782
+ },
783
+
784
+ deleteSelected(event) {
785
+ event.stopPropagation()
786
+ const value = this.multiple ? [] : ''
787
+ this.$emit('input', value)
788
+ this.emitChange(value)
789
+ this.visible = false
790
+ this.$emit('clear')
791
+ },
792
+
793
+ deleteTag(event, tag) {
794
+ let index = this.selected.indexOf(tag)
795
+ if (index > -1 && !this.selectDisabled) {
796
+ const value = this.value.slice()
797
+ value.splice(index, 1)
798
+ this.$emit('input', value)
799
+ this.emitChange(value)
800
+ this.$emit('remove-tag', tag.value)
801
+ }
802
+ event.stopPropagation()
803
+ },
804
+
805
+ onInputChange() {
806
+ if (this.filterable && this.query !== this.selectedLabel) {
807
+ this.query = this.selectedLabel
808
+ this.handleQueryChange(this.query)
809
+ }
810
+ },
811
+
812
+ onOptionDestroy(index) {
813
+ if (index > -1) {
814
+ this.optionsCount--
815
+ this.filteredOptionsCount--
816
+ this.options.splice(index, 1)
817
+ }
818
+ },
819
+
820
+ resetInputWidth() {
821
+ this.inputWidth = this.$refs.reference.$el.getBoundingClientRect().width
822
+ },
823
+
824
+ handleResize() {
825
+ this.resetInputWidth()
826
+ if (this.multiple) this.resetInputHeight()
827
+ },
828
+
829
+ checkDefaultFirstOption() {
830
+ this.hoverIndex = -1
831
+ // highlight the created option
832
+ let hasCreated = false
833
+ for (let i = this.options.length - 1; i >= 0; i--) {
834
+ if (this.options[i].created) {
835
+ hasCreated = true
836
+ this.hoverIndex = i
837
+ break
838
+ }
839
+ }
840
+ if (hasCreated) return
841
+ for (let i = 0; i !== this.options.length; ++i) {
842
+ const option = this.options[i]
843
+ if (this.query) {
844
+ // highlight first options that passes the filter
845
+ if (!option.disabled && !option.groupDisabled && option.visible) {
846
+ this.hoverIndex = i
847
+ break
848
+ }
849
+ } else {
850
+ // highlight currently selected option
851
+ if (option.itemSelected) {
852
+ this.hoverIndex = i
853
+ break
854
+ }
855
+ }
856
+ }
857
+ },
858
+
859
+ getValueKey(item) {
860
+ if (Object.prototype.toString.call(item.value).toLowerCase() !== '[object object]') {
861
+ return item.value
862
+ } else {
863
+ return getValueByPath(item.value, this.valueKey)
864
+ }
865
+ }
866
+ },
867
+
868
+ created() {
869
+ this.cachedPlaceHolder = this.currentPlaceholder = this.placeholder
870
+ if (this.multiple && !Array.isArray(this.value)) {
871
+ this.$emit('input', [])
872
+ }
873
+ if (!this.multiple && Array.isArray(this.value)) {
874
+ this.$emit('input', '')
875
+ }
876
+
877
+ this.debouncedOnInputChange = debounce(this.debounce, () => {
878
+ this.onInputChange()
879
+ })
880
+
881
+ this.debouncedQueryChange = debounce(this.debounce, (e) => {
882
+ this.handleQueryChange(e.target.value)
883
+ })
884
+
885
+ this.$on('handleOptionClick', this.handleOptionSelect)
886
+ this.$on('setSelected', this.setSelected)
887
+ },
888
+
889
+ mounted() {
890
+ if (this.multiple && Array.isArray(this.value) && this.value.length > 0) {
891
+ this.currentPlaceholder = ''
892
+ }
893
+ addResizeListener(this.$el, this.handleResize)
894
+
895
+ const reference = this.$refs.reference
896
+ if (reference && reference.$el) {
897
+ const sizeMap = {
898
+ medium: 36,
899
+ small: 32,
900
+ mini: 28
901
+ }
902
+ const input = reference.$el.querySelector('input')
903
+ this.initialInputHeight = input.getBoundingClientRect().height || sizeMap[this.selectSize]
904
+ }
905
+ if (this.remote && this.multiple) {
906
+ this.resetInputHeight()
907
+ }
908
+ this.$nextTick(() => {
909
+ if (reference && reference.$el) {
910
+ this.inputWidth = reference.$el.getBoundingClientRect().width
911
+ }
912
+ })
913
+ this.setSelected()
914
+ },
915
+
916
+ beforeDestroy() {
917
+ if (this.$el && this.handleResize) removeResizeListener(this.$el, this.handleResize)
918
+ }
919
+ }
920
+ </script>