@gmfe/react 2.14.17 → 2.14.19-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/package.json +3 -3
  2. package/src/common/hooks/index.js +3 -3
  3. package/src/common/hooks/use_mutation_observer.js +25 -25
  4. package/src/common/util.js +52 -52
  5. package/src/component/affix/affix.stories.js +13 -13
  6. package/src/component/affix/index.js +21 -21
  7. package/src/component/box/box.js +31 -31
  8. package/src/component/box/box.stories.js +94 -94
  9. package/src/component/box/box_form.js +77 -77
  10. package/src/component/box/box_panel.js +91 -91
  11. package/src/component/box/box_table.js +51 -51
  12. package/src/component/box/index.js +6 -6
  13. package/src/component/box/style.less +39 -39
  14. package/src/component/button/button.stories.js +91 -91
  15. package/src/component/button/index.js +92 -92
  16. package/src/component/button/style.less +114 -114
  17. package/src/component/calendar/calendar.js +52 -52
  18. package/src/component/calendar/calendar.stories.js +57 -57
  19. package/src/component/calendar/content.js +89 -89
  20. package/src/component/calendar/day.js +109 -109
  21. package/src/component/calendar/head.js +243 -243
  22. package/src/component/calendar/index.js +4 -4
  23. package/src/component/calendar/range_calendar.js +150 -150
  24. package/src/component/calendar/style.less +140 -140
  25. package/src/component/calendar/week.js +27 -27
  26. package/src/component/carousel/carousel.js +178 -178
  27. package/src/component/carousel/stories.js +50 -50
  28. package/src/component/carousel/style.less +48 -48
  29. package/src/component/cascader/cascader.js +443 -443
  30. package/src/component/cascader/cascader.select.js +195 -195
  31. package/src/component/cascader/stories.js +240 -240
  32. package/src/component/cascader/style.less +122 -122
  33. package/src/component/checkbox/checkbox.js +86 -86
  34. package/src/component/checkbox/checkbox_group.js +66 -66
  35. package/src/component/checkbox/index.js +4 -4
  36. package/src/component/checkbox/stories.js +103 -103
  37. package/src/component/checkbox/style.less +88 -88
  38. package/src/component/collapse/collapse.stories.js +18 -18
  39. package/src/component/collapse/index.js +36 -36
  40. package/src/component/color_picker/index.js +190 -190
  41. package/src/component/color_picker/stories.js +17 -17
  42. package/src/component/color_picker/style.less +41 -41
  43. package/src/component/date_picker/date_picker.stories.js +102 -102
  44. package/src/component/date_picker/index.js +217 -217
  45. package/src/component/date_picker/overlay.js +119 -119
  46. package/src/component/date_picker/style.less +22 -22
  47. package/src/component/date_picker/time_select.js +62 -62
  48. package/src/component/date_range_picker/date_range_picker.stories.js +196 -196
  49. package/src/component/date_range_picker/index.js +206 -206
  50. package/src/component/date_range_picker/left.js +127 -127
  51. package/src/component/date_range_picker/overlay.js +202 -202
  52. package/src/component/date_range_picker/style.less +46 -46
  53. package/src/component/date_range_picker/time_range_select.js +150 -150
  54. package/src/component/date_range_picker/two.js +129 -129
  55. package/src/component/date_range_picker/util.js +42 -42
  56. package/src/component/dialog/index.js +240 -240
  57. package/src/component/dialog/stories.js +125 -125
  58. package/src/component/divider/index.js +28 -28
  59. package/src/component/divider/stories.js +5 -5
  60. package/src/component/divider/style.less +15 -15
  61. package/src/component/drawer/index.js +107 -107
  62. package/src/component/drawer/style.less +43 -43
  63. package/src/component/drop_down/drop_down.js +84 -84
  64. package/src/component/drop_down/drop_down_item.js +43 -43
  65. package/src/component/drop_down/drop_down_items.js +22 -22
  66. package/src/component/drop_down/index.js +5 -5
  67. package/src/component/drop_down/stories.js +38 -38
  68. package/src/component/drop_down/style.less +21 -21
  69. package/src/component/drop_select/index.js +208 -208
  70. package/src/component/drop_select/style.less +69 -69
  71. package/src/component/dropper/index.js +62 -62
  72. package/src/component/dropper/style.less +18 -18
  73. package/src/component/editable_text/editable_text.stories.js +47 -47
  74. package/src/component/editable_text/index.js +106 -106
  75. package/src/component/editable_text/style.less +29 -29
  76. package/src/component/filter_select/filter.select.js +416 -416
  77. package/src/component/filter_select/multiple.filter.select.js +425 -425
  78. package/src/component/filter_select/style.less +117 -117
  79. package/src/component/flex/index.js +132 -132
  80. package/src/component/flex/stories.js +13 -13
  81. package/src/component/flex/style.less +101 -101
  82. package/src/component/flip_number/index.js +196 -196
  83. package/src/component/flip_number/stories.js +25 -25
  84. package/src/component/flip_number/utils.js +50 -50
  85. package/src/component/form/form.js +153 -153
  86. package/src/component/form/form.stories.js +553 -553
  87. package/src/component/form/form_block.js +59 -59
  88. package/src/component/form/form_button.js +29 -29
  89. package/src/component/form/form_group.js +173 -173
  90. package/src/component/form/form_item.js +163 -163
  91. package/src/component/form/form_panel.js +71 -71
  92. package/src/component/form/index.js +8 -8
  93. package/src/component/form/style.less +130 -130
  94. package/src/component/form/util.js +13 -13
  95. package/src/component/function_set/function_set.stories.js +91 -91
  96. package/src/component/function_set/index.js +98 -98
  97. package/src/component/function_set/overlay.js +56 -56
  98. package/src/component/grid/col.js +72 -72
  99. package/src/component/grid/grid.stories.js +123 -123
  100. package/src/component/grid/index.js +4 -4
  101. package/src/component/grid/mixin.less +48 -48
  102. package/src/component/grid/row.js +44 -44
  103. package/src/component/grid/style.less +26 -26
  104. package/src/component/grid/util.js +11 -11
  105. package/src/component/icon_down_up/index.js +28 -28
  106. package/src/component/icon_down_up/stories.js +18 -18
  107. package/src/component/icon_down_up/style.less +8 -8
  108. package/src/component/image_preview/index.js +20 -20
  109. package/src/component/image_preview/preview_modal.js +193 -193
  110. package/src/component/image_preview/style.less +119 -119
  111. package/src/component/img_uploader/index.js +149 -149
  112. package/src/component/img_uploader/index.stories.js +51 -51
  113. package/src/component/img_uploader/style.less +22 -22
  114. package/src/component/input/index.js +19 -19
  115. package/src/component/input_number/index.js +73 -73
  116. package/src/component/input_number/number.js +158 -158
  117. package/src/component/input_number/stories.js +21 -21
  118. package/src/component/input_number/style.less +10 -10
  119. package/src/component/layout_root/index.js +165 -165
  120. package/src/component/lazy_img/index.js +68 -68
  121. package/src/component/level_list/index.js +120 -120
  122. package/src/component/level_list/level_item.js +64 -64
  123. package/src/component/level_list/level_list.stories.js +139 -139
  124. package/src/component/level_list/style.less +47 -47
  125. package/src/component/level_list/util.js +22 -22
  126. package/src/component/level_select/index.js +240 -240
  127. package/src/component/level_select/level_select.stories.js +67 -67
  128. package/src/component/list/base.js +155 -155
  129. package/src/component/list/index.js +93 -93
  130. package/src/component/list/list.stories.js +99 -99
  131. package/src/component/list/style.less +58 -58
  132. package/src/component/loading/index.js +45 -45
  133. package/src/component/loading/loading_chunk.js +59 -59
  134. package/src/component/loading/loading_full_screen.js +62 -62
  135. package/src/component/loading/stories.js +46 -46
  136. package/src/component/loading/style.less +92 -92
  137. package/src/component/mask/index.js +34 -34
  138. package/src/component/mask/style.less +10 -10
  139. package/src/component/modal/clean_modal.js +36 -36
  140. package/src/component/modal/index.js +293 -293
  141. package/src/component/modal/right_side_modal.js +37 -37
  142. package/src/component/modal/stories.js +96 -96
  143. package/src/component/modal/style.less +145 -145
  144. package/src/component/more_select/base.js +517 -517
  145. package/src/component/more_select/index.js +91 -91
  146. package/src/component/more_select/stories.js +261 -261
  147. package/src/component/more_select/style.less +130 -130
  148. package/src/component/nav/index.js +269 -269
  149. package/src/component/nav/nav.stories.js +133 -133
  150. package/src/component/nav/style.less +156 -156
  151. package/src/component/nprogress/index.js +34 -34
  152. package/src/component/nprogress/stories.js +22 -22
  153. package/src/component/nprogress/style.less +39 -39
  154. package/src/component/pagination/base.js +67 -67
  155. package/src/component/pagination/left.js +65 -65
  156. package/src/component/pagination/page.js +120 -120
  157. package/src/component/pagination/page_peek.js +96 -96
  158. package/src/component/pagination/pagination.js +54 -54
  159. package/src/component/pagination/pagination.stories.js +104 -104
  160. package/src/component/pagination/pagination_text.js +71 -71
  161. package/src/component/pagination/pagination_v2.js +30 -30
  162. package/src/component/pagination/right.js +67 -67
  163. package/src/component/pagination/style.less +52 -52
  164. package/src/component/pagination/util.js +5 -5
  165. package/src/component/picture_preview/index.js +21 -21
  166. package/src/component/popover/index.js +373 -373
  167. package/src/component/popover/stories.js +101 -101
  168. package/src/component/popup/index.js +4 -4
  169. package/src/component/popup/popup.js +172 -172
  170. package/src/component/popup/popup_content_confirm.js +67 -67
  171. package/src/component/popup/style.less +105 -105
  172. package/src/component/price/index.js +147 -147
  173. package/src/component/price/stories.js +34 -34
  174. package/src/component/progress/index.js +101 -101
  175. package/src/component/progress/stories.js +60 -60
  176. package/src/component/progress/style.less +88 -88
  177. package/src/component/progress_circle/index.js +116 -116
  178. package/src/component/progress_circle/stories.js +54 -54
  179. package/src/component/progress_circle/style.less +17 -17
  180. package/src/component/radio/index.js +4 -4
  181. package/src/component/radio/radio.js +76 -76
  182. package/src/component/radio/radio_group.js +51 -51
  183. package/src/component/radio/stories.js +80 -80
  184. package/src/component/radio/style.less +63 -63
  185. package/src/component/recommend_input/index.js +118 -118
  186. package/src/component/recommend_input/recommend_input.stories.js +56 -56
  187. package/src/component/recommend_input/style.less +25 -25
  188. package/src/component/select/index.js +4 -4
  189. package/src/component/select/option.js +22 -22
  190. package/src/component/select/select.js +186 -186
  191. package/src/component/select/select.stories.js +79 -79
  192. package/src/component/select/style.less +4 -4
  193. package/src/component/selection/index.js +132 -132
  194. package/src/component/selection/selection.stories.js +41 -41
  195. package/src/component/selection/style.less +67 -67
  196. package/src/component/sheet/index.js +7 -7
  197. package/src/component/sheet/sheet.js +348 -348
  198. package/src/component/sheet/sheet_action.js +16 -16
  199. package/src/component/sheet/sheet_batch_action.js +16 -16
  200. package/src/component/sheet/sheet_column.js +21 -21
  201. package/src/component/sheet/sheet_select.js +31 -31
  202. package/src/component/sheet/stories.js +210 -210
  203. package/src/component/sheet/style.less +95 -95
  204. package/src/component/steps/index.js +66 -66
  205. package/src/component/steps/steps.stories.js +15 -15
  206. package/src/component/steps/style.less +39 -39
  207. package/src/component/storage/index.js +54 -54
  208. package/src/component/storage/stories.js +38 -38
  209. package/src/component/switch/index.js +118 -118
  210. package/src/component/switch/stories.js +7 -7
  211. package/src/component/switch/style.less +70 -70
  212. package/src/component/table_select/index.js +152 -152
  213. package/src/component/table_select/style.less +12 -12
  214. package/src/component/table_select/table_select.stories.js +91 -91
  215. package/src/component/table_select/util.js +21 -21
  216. package/src/component/tabs/style.less +33 -33
  217. package/src/component/tabs/tabs.js +97 -97
  218. package/src/component/tabs/tabs.stories.js +48 -48
  219. package/src/component/time_span/style.less +45 -45
  220. package/src/component/time_span/time_span.js +183 -183
  221. package/src/component/time_span/time_span.stories.js +66 -66
  222. package/src/component/time_span/time_span_picker.js +112 -112
  223. package/src/component/time_span/time_span_picker.stories.js +71 -71
  224. package/src/component/tip/index.js +168 -168
  225. package/src/component/tip/stories.js +54 -54
  226. package/src/component/tip/style.less +41 -41
  227. package/src/component/tool_tip/index.js +58 -58
  228. package/src/component/tool_tip/stories.js +36 -36
  229. package/src/component/transfer/box.js +186 -141
  230. package/src/component/transfer/index.js +4 -4
  231. package/src/component/transfer/stories.js +108 -118
  232. package/src/component/transfer/style.less +34 -34
  233. package/src/component/transfer/transfer.js +181 -173
  234. package/src/component/transfer/transfer_group.js +178 -178
  235. package/src/component/transfer_v2/index.js +171 -171
  236. package/src/component/transfer_v2/transfer_v2.stories.js +226 -226
  237. package/src/component/tree/bottom.js +41 -41
  238. package/src/component/tree/index.js +205 -205
  239. package/src/component/tree/item.js +154 -154
  240. package/src/component/tree/list.js +151 -151
  241. package/src/component/tree/style.less +147 -147
  242. package/src/component/tree/tree.stories.js +241 -241
  243. package/src/component/tree/util.js +24 -24
  244. package/src/component/tree_v2/bottom.js +40 -40
  245. package/src/component/tree_v2/index.js +260 -260
  246. package/src/component/tree_v2/list.js +230 -230
  247. package/src/component/tree_v2/style.less +38 -38
  248. package/src/component/tree_v2/tree.stories.js +419 -419
  249. package/src/component/tree_v2/util.js +185 -185
  250. package/src/component/uploader/index.js +108 -108
  251. package/src/component/uploader/style.less +24 -24
  252. package/src/component/uploader/uploader.stories.js +51 -51
  253. package/src/css/arrow.less +56 -56
  254. package/src/css/bg.less +52 -52
  255. package/src/css/border.less +40 -40
  256. package/src/css/cover.less +236 -236
  257. package/src/css/cursor.less +19 -19
  258. package/src/css/display.less +16 -16
  259. package/src/css/distance.less +324 -324
  260. package/src/css/error.less +10 -10
  261. package/src/css/other.less +16 -16
  262. package/src/css/overflow.less +23 -23
  263. package/src/css/position.less +11 -11
  264. package/src/css/rotate.less +28 -28
  265. package/src/css/shadow.less +11 -11
  266. package/src/css/stories.js +104 -104
  267. package/src/css/svg.less +51 -51
  268. package/src/css/text.less +120 -120
  269. package/src/css/variables.less +62 -62
  270. package/src/event_type.js +16 -16
  271. package/src/fonts/glyphicons-halflings-regular.svg +542 -542
  272. package/src/index.js +237 -237
  273. package/src/index.less +108 -108
  274. package/src/less/.csscomb.json +304 -304
  275. package/src/less/.csslintrc +19 -19
  276. package/src/less/alerts.less +72 -72
  277. package/src/less/badges.less +65 -65
  278. package/src/less/bootstrap.less +51 -51
  279. package/src/less/breadcrumbs.less +25 -25
  280. package/src/less/button-groups.less +253 -253
  281. package/src/less/buttons.less +186 -186
  282. package/src/less/carousel.less +269 -269
  283. package/src/less/close.less +33 -33
  284. package/src/less/code.less +68 -68
  285. package/src/less/component-animations.less +39 -39
  286. package/src/less/custom.less +37 -37
  287. package/src/less/dropdowns.less +215 -215
  288. package/src/less/forms.less +612 -612
  289. package/src/less/glyphicons.less +1614 -1614
  290. package/src/less/grid.less +76 -76
  291. package/src/less/input-groups.less +175 -175
  292. package/src/less/jumbotron.less +53 -53
  293. package/src/less/labels.less +64 -64
  294. package/src/less/list-group.less +126 -126
  295. package/src/less/media.less +66 -66
  296. package/src/less/mixins/alerts.less +14 -14
  297. package/src/less/mixins/background-variant.less +9 -9
  298. package/src/less/mixins/border-radius.less +21 -21
  299. package/src/less/mixins/buttons.less +65 -65
  300. package/src/less/mixins/center-block.less +7 -7
  301. package/src/less/mixins/clearfix.less +22 -22
  302. package/src/less/mixins/forms.less +84 -84
  303. package/src/less/mixins/gradients.less +59 -59
  304. package/src/less/mixins/grid-framework.less +96 -96
  305. package/src/less/mixins/grid.less +134 -134
  306. package/src/less/mixins/hide-text.less +21 -21
  307. package/src/less/mixins/image.less +25 -25
  308. package/src/less/mixins/labels.less +12 -12
  309. package/src/less/mixins/list-group.less +30 -30
  310. package/src/less/mixins/nav-divider.less +10 -10
  311. package/src/less/mixins/nav-vertical-align.less +9 -9
  312. package/src/less/mixins/opacity.less +8 -8
  313. package/src/less/mixins/pagination.less +24 -24
  314. package/src/less/mixins/panels.less +24 -24
  315. package/src/less/mixins/progress-bar.less +10 -10
  316. package/src/less/mixins/reset-filter.less +8 -8
  317. package/src/less/mixins/reset-text.less +18 -18
  318. package/src/less/mixins/resize.less +6 -6
  319. package/src/less/mixins/responsive-visibility.less +21 -21
  320. package/src/less/mixins/size.less +10 -10
  321. package/src/less/mixins/tab-focus.less +9 -9
  322. package/src/less/mixins/table-row.less +28 -28
  323. package/src/less/mixins/text-emphasis.less +9 -9
  324. package/src/less/mixins/text-overflow.less +8 -8
  325. package/src/less/mixins/vendor-prefixes.less +254 -254
  326. package/src/less/mixins.less +36 -36
  327. package/src/less/modals.less +163 -163
  328. package/src/less/navbar.less +651 -651
  329. package/src/less/navs.less +236 -236
  330. package/src/less/normalize.less +424 -424
  331. package/src/less/pager.less +54 -54
  332. package/src/less/pagination.less +90 -90
  333. package/src/less/panels.less +274 -274
  334. package/src/less/popovers.less +140 -140
  335. package/src/less/print.less +103 -103
  336. package/src/less/progress-bars.less +92 -92
  337. package/src/less/responsive-embed.less +35 -35
  338. package/src/less/responsive-utilities.less +209 -209
  339. package/src/less/scaffolding.less +154 -154
  340. package/src/less/tables.less +228 -228
  341. package/src/less/theme.less +344 -344
  342. package/src/less/thumbnails.less +35 -35
  343. package/src/less/tooltip.less +115 -115
  344. package/src/less/type.less +352 -352
  345. package/src/less/utilities.less +57 -57
  346. package/src/less/variables.less +833 -833
  347. package/src/less/wells.less +29 -29
  348. package/src/sotries.js +4 -4
  349. package/src/validator/index.js +10 -10
  350. package/src/validator/rules.js +66 -66
  351. package/src/validator/type.js +10 -10
  352. package/src/validator/validator.js +86 -86
  353. package/src/var.less +4 -4
  354. package/svg/calendar-month.svg +8 -8
  355. package/svg/calendar-year.svg +13 -13
  356. package/svg/calendar.svg +17 -17
  357. package/svg/check-detail.svg +18 -18
  358. package/svg/close-circle.svg +13 -13
  359. package/svg/closeup.svg +20 -20
  360. package/svg/delete.svg +10 -10
  361. package/svg/down-small.svg +1 -1
  362. package/svg/down.svg +1 -1
  363. package/svg/edit-box.svg +17 -17
  364. package/svg/edit-pen.svg +17 -17
  365. package/svg/empty.svg +27 -27
  366. package/svg/expand.svg +21 -21
  367. package/svg/left-small.svg +1 -1
  368. package/svg/more.svg +10 -10
  369. package/svg/next.svg +40 -40
  370. package/svg/pen.svg +12 -12
  371. package/svg/remove.svg +1 -1
  372. package/svg/right-small.svg +1 -1
  373. package/svg/search.svg +8 -8
  374. package/svg/setting.svg +17 -17
  375. package/svg/up-small.svg +1 -1
  376. package/svg/up.svg +1 -1
@@ -1,517 +1,517 @@
1
- import { getLocale } from '@gmfe/locales'
2
- import React from 'react'
3
- import PropTypes from 'prop-types'
4
- import _ from 'lodash'
5
- import classNames from 'classnames'
6
- import Popover from '../popover'
7
- import Flex from '../flex'
8
- import ListBase from '../list/base'
9
- import Loading from '../loading'
10
- import { pinYinFilter } from '@gm-common/tool'
11
- import { findDOMNode } from 'react-dom'
12
- import SVGCloseCircle from '../../../svg/close-circle.svg'
13
- import SVGRemove from '../../../svg/remove.svg'
14
-
15
- // 不要轻易改这个文件
16
- // TODO keydown item disabled
17
- // 目前全键盘还没有这种场景,暂时不管
18
- class Base extends React.Component {
19
- constructor(props) {
20
- super(props)
21
-
22
- this.ref = React.createRef()
23
- this.popoverRef = React.createRef()
24
- this.selectedRef = React.createRef()
25
-
26
- this._isUnmounted = false
27
-
28
- this.debounceDoSearch = _.debounce(this.doSearch, props.delay)
29
-
30
- this.state = {
31
- searchValue: '',
32
- loading: false,
33
- // keyboard 默认第一个位置
34
- willActiveIndex: props.isKeyboard ? 0 : null,
35
- _style: {}
36
- // isOnComposition: false
37
- }
38
- // 要后于 this.state 执行,因为 getFilterData 用到 searchValue
39
-
40
- // 有选择才有意义
41
- if (props.selected.length > 0) {
42
- this.getFilterData()
43
- const flatList = this.getFlatFilterData()
44
- const index = _.findIndex(
45
- flatList,
46
- v => v.value === props.selected[0].value
47
- )
48
- this.state.willActiveIndex = index
49
- }
50
- }
51
-
52
- isOnComposition = false
53
-
54
- setInputValue = () => {
55
- this.ref.current.value = this.state.searchValue || ''
56
- }
57
-
58
- apiDoFocus = () => {
59
- // 唤起 popover,input autoFocus 会自动聚焦,但是这种方式本质是显示 UI
60
- // this.popoverRef.current.apiDoSetActive(true)
61
-
62
- // focus 更符合直觉
63
- findDOMNode(this.selectedRef.current).focus()
64
- }
65
-
66
- apiDoSelectWillActive = () => {
67
- const { selected, onSelect, multiple } = this.props
68
- const { willActiveIndex } = this.state
69
- const flatList = this.getFlatFilterData()
70
- // 没有做过键盘操作啥也不做
71
- if (willActiveIndex !== null && willActiveIndex < flatList.length) {
72
- if (multiple) {
73
- onSelect(
74
- _.uniqBy([...selected, flatList[willActiveIndex]], item => item.value)
75
- )
76
- } else {
77
- onSelect([flatList[willActiveIndex]])
78
- }
79
- }
80
- }
81
-
82
- componentDidMount() {
83
- const dom = findDOMNode(this)
84
- const _style = { width: dom.offsetWidth }
85
- this.setState({ _style })
86
- this.setInputValue()
87
- }
88
-
89
- componentDidUpdate() {
90
- this.setInputValue()
91
- }
92
-
93
- componentWillUnmount() {
94
- this._isUnmounted = true
95
- }
96
-
97
- handleClear = (clearItem, event) => {
98
- event.stopPropagation()
99
-
100
- const { onSelect, selected } = this.props
101
-
102
- const willSelected = _.filter(
103
- selected,
104
- item => item.value !== clearItem.value
105
- )
106
-
107
- onSelect(willSelected)
108
- }
109
-
110
- handleChange = e => {
111
- const searchValue = e.target.value
112
-
113
- this.setState({
114
- searchValue
115
- })
116
- if (this.isOnComposition && this.props.isEnableChineseCheck) return
117
- this.debounceDoSearch(searchValue)
118
- }
119
-
120
- handleComposition = evt => {
121
- if (evt.type === 'compositionend') {
122
- this.isOnComposition = false
123
- if (navigator.userAgent.indexOf('Chrome') > -1) {
124
- this.handleChange(evt)
125
- }
126
- return
127
- }
128
- this.isOnComposition = true
129
- }
130
-
131
- handleSelected = values => {
132
- const { onSelect, data, multiple, selected } = this.props
133
- const items = []
134
- _.each(data, group => {
135
- _.each(group.children, item => {
136
- if (values.includes(item.value)) {
137
- items.push(item)
138
- }
139
- })
140
- })
141
-
142
- _.each(selected, item => {
143
- let flag = true // 判断当前已选择的选项中是否存在不在当前data里面的,解决onSearch异步,true则表示都不在data里面
144
- _.each(data, group => {
145
- flag = flag && _.every(group.children, v => v.value !== item.value)
146
- })
147
- if (flag) {
148
- items.push(item)
149
- }
150
- })
151
-
152
- onSelect(items)
153
-
154
- if (!multiple) {
155
- // 单选选后关闭
156
- // 要异步
157
- setTimeout(() => {
158
- if (!this._isUnmounted) {
159
- this.popoverRef.current.apiDoSetActive(false)
160
- }
161
- }, 0)
162
- }
163
- }
164
-
165
- doSearch = query => {
166
- const { onSearch, data } = this.props
167
-
168
- if (!this._isUnmounted && onSearch) {
169
- const result = onSearch(query, data)
170
-
171
- if (!result) {
172
- return
173
- }
174
-
175
- this.setState({
176
- loading: true
177
- })
178
-
179
- Promise.resolve(result)
180
- .then(() => {
181
- if (!this._isUnmounted) {
182
- this.setState({
183
- loading: false
184
- })
185
- }
186
- })
187
- .catch(() => {
188
- if (!this._isUnmounted) {
189
- this.setState({
190
- isLoading: false
191
- })
192
- }
193
- })
194
- }
195
- }
196
-
197
- getFlatFilterData = () => {
198
- return _.flatMap(this.filterData, v => v.children)
199
- }
200
-
201
- handlePopupKeyDown = event => {
202
- const { onKeyDown } = this.props
203
- let { willActiveIndex } = this.state
204
-
205
- // 不是上下方向键,不用拦截
206
- if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') {
207
- onKeyDown(event)
208
- return
209
- }
210
-
211
- const flatList = this.getFlatFilterData()
212
- // 没有过滤数据,不用拦截
213
- if (flatList.length === 0) {
214
- onKeyDown(event)
215
- return
216
- }
217
-
218
- // 以下是需要拦截部分
219
-
220
- if (event.key === 'ArrowUp') {
221
- willActiveIndex--
222
- } else if (event.key === 'ArrowDown') {
223
- willActiveIndex++
224
- }
225
-
226
- // 修正
227
- if (willActiveIndex < 0) {
228
- willActiveIndex = flatList.length - 1
229
- } else if (willActiveIndex > flatList.length - 1) {
230
- willActiveIndex = 0
231
- }
232
-
233
- this.setState({
234
- willActiveIndex
235
- })
236
- }
237
-
238
- getFilterData = () => {
239
- const { data, renderListFilter, renderListFilterType } = this.props
240
- const { searchValue } = this.state
241
-
242
- let filterData = data
243
- // 节省过滤时间
244
- if (renderListFilter) {
245
- filterData = renderListFilter(data, searchValue)
246
- } else if (renderListFilterType === 'pinyin') {
247
- filterData = renderListFilterPinYin(data, searchValue)
248
- } else {
249
- filterData = renderListFilterDefault(data, searchValue)
250
- }
251
-
252
- // 存起来给上下键用
253
- this.filterData = filterData
254
-
255
- return filterData
256
- }
257
-
258
- renderList() {
259
- const {
260
- selected,
261
- multiple,
262
- isGroupList,
263
- renderListItem,
264
- searchPlaceholder,
265
- listHeight,
266
- popupClassName,
267
- isEnableChineseCheck
268
- } = this.props
269
-
270
- const { loading, searchValue, willActiveIndex } = this.state
271
-
272
- const filterData = this.getFilterData()
273
-
274
- return (
275
- <div
276
- className={classNames('gm-more-select-popup', popupClassName)}
277
- onKeyDown={this.handlePopupKeyDown}
278
- >
279
- <div className='gm-more-select-popup-input'>
280
- {isEnableChineseCheck ? (
281
- <input
282
- autoFocus
283
- className='form-control'
284
- type='text'
285
- // value={searchValue}
286
- onChange={this.handleChange}
287
- placeholder={searchPlaceholder}
288
- onCompositionStart={this.handleComposition}
289
- onCompositionUpdate={this.handleComposition}
290
- onCompositionEnd={this.handleComposition}
291
- />
292
- ) : (
293
- <input
294
- autoFocus
295
- className='form-control'
296
- type='text'
297
- value={searchValue}
298
- onChange={this.handleChange}
299
- placeholder={searchPlaceholder}
300
- />
301
- )}
302
- </div>
303
- <div style={{ height: listHeight }}>
304
- {loading && (
305
- <Flex alignCenter justifyCenter className='gm-bg gm-padding-5'>
306
- <Loading size={20} />
307
- </Flex>
308
- )}
309
- {!loading && filterData.length === 0 && (
310
- <Flex
311
- alignCenter
312
- justifyCenter
313
- className='gm-bg gm-padding-5 gm-text-desc'
314
- >
315
- {getLocale('没有数据')}
316
- </Flex>
317
- )}
318
- {!loading && filterData.length !== 0 && (
319
- <ListBase
320
- data={filterData}
321
- selected={_.map(selected, v => v.value)}
322
- multiple={multiple}
323
- isGroupList={isGroupList}
324
- className='gm-border-0'
325
- renderItem={renderListItem}
326
- onSelect={this.handleSelected}
327
- isScrollTo
328
- willActiveIndex={willActiveIndex}
329
- style={{
330
- height: listHeight
331
- }}
332
- />
333
- )}
334
- </div>
335
- </div>
336
- )
337
- }
338
-
339
- render() {
340
- const {
341
- isInPopup,
342
- disabled,
343
- disabledClose,
344
- selected,
345
- multiple,
346
- placeholder,
347
-
348
- renderSelected,
349
-
350
- className,
351
- style,
352
- popoverType,
353
- children
354
- } = this.props
355
-
356
- const { _style } = this.state
357
-
358
- return (
359
- <div
360
- ref={this.ref}
361
- className={classNames(
362
- 'gm-more-select',
363
- {
364
- 'gm-more-select-disabled': disabled,
365
- 'gm-more-select-multiple': multiple
366
- },
367
- className
368
- )}
369
- style={{ ..._style, ...style }}
370
- >
371
- <Popover
372
- ref={this.popoverRef}
373
- type={popoverType}
374
- animName
375
- popup={() => this.renderList()}
376
- disabled={disabled}
377
- isInPopup={isInPopup}
378
- >
379
- {children || (
380
- <Flex
381
- ref={this.selectedRef}
382
- tabIndex={0}
383
- wrap
384
- className='gm-more-select-selected'
385
- >
386
- {selected.length !== 0 ? (
387
- _.map(selected, item => (
388
- <Flex
389
- key={item.value}
390
- className='gm-more-select-selected-item'
391
- >
392
- <Popover
393
- disabled={!this.props.isKeyboard}
394
- type='hover'
395
- popup={<div className='gm-padding-10'>{item.text}</div>}
396
- >
397
- <Flex flex column>
398
- {renderSelected(item)}
399
- </Flex>
400
- </Popover>
401
- {multiple ? (
402
- <SVGRemove
403
- onClick={
404
- disabled ? _.noop : this.handleClear.bind(this, item)
405
- }
406
- className='gm-cursor gm-more-select-clear-btn'
407
- />
408
- ) : (
409
- !disabledClose && ( // 是否不显示清除按钮,仅单选可用
410
- <SVGCloseCircle
411
- onClick={
412
- disabled
413
- ? _.noop
414
- : this.handleClear.bind(this, item)
415
- }
416
- className='gm-cursor gm-more-select-clear-btn'
417
- />
418
- )
419
- )}
420
- </Flex>
421
- ))
422
- ) : (
423
- // 加多个 &nbsp; 避免对齐问题。 有文本才有对齐
424
- <div className='gm-text-desc'>{placeholder}&nbsp;</div>
425
- )}
426
- </Flex>
427
- )}
428
- </Popover>
429
- </div>
430
- )
431
- }
432
- }
433
-
434
- function renderListFilterDefault(data, query) {
435
- const result = []
436
- const keywords = query.toLowerCase()
437
- // TODO 加个queryText,用于基于多个搜索结果的情况下,因为是公共组件,所以多加个字段
438
- _.each(data, v => {
439
- const arr = _.filter(
440
- v?.children || [],
441
- item =>
442
- item?.text?.toLowerCase()?.includes(keywords) ||
443
- item?.queryText?.toLowerCase()?.includes(keywords)
444
- )
445
- if (arr.length) {
446
- result.push({
447
- ...v,
448
- children: arr
449
- })
450
- }
451
- })
452
-
453
- return result
454
- }
455
-
456
- function renderListFilterPinYin(data, query) {
457
- const result = []
458
- _.each(data, v => {
459
- const arr = pinYinFilter(v.children, query, item => item.text)
460
- if (arr.length) {
461
- result.push({
462
- ...v,
463
- children: arr
464
- })
465
- }
466
- })
467
-
468
- return result
469
- }
470
-
471
- Base.renderListFilterDefault = renderListFilterDefault
472
- Base.renderListFilterPinYin = renderListFilterPinYin
473
-
474
- Base.propTypes = {
475
- // 基本属性
476
- data: PropTypes.array.isRequired, // label, children: [{value, text}]
477
- selected: PropTypes.array.isRequired, // item 数组。 非 value,也非引用,原因是想解耦 selected 和 data 的关系。这样当
478
- onSelect: PropTypes.func.isRequired, // 返回 item 数组
479
- multiple: PropTypes.bool,
480
- isEnableChineseCheck: PropTypes.bool, // 是否开启中文检查
481
-
482
- // 状态
483
- disabled: PropTypes.bool,
484
- /** 单选禁止显示关闭按钮 */
485
- disabledClose: PropTypes.bool,
486
-
487
- // 列表 搜索
488
- onSearch: PropTypes.func, // searchValue, data
489
- delay: PropTypes.number,
490
- searchPlaceholder: PropTypes.string,
491
- renderListFilter: PropTypes.func, // 过滤,提供 searchValue 和 data
492
- renderListFilterType: PropTypes.oneOf(['default', 'pinyin']), // 也可简单指定 默认的过滤类型
493
-
494
- // 展示
495
- placeholder: PropTypes.string,
496
- renderSelected: PropTypes.func, // 定制已选的区域,提供 selected
497
- renderListItem: PropTypes.func, // 定制列表
498
-
499
- // 样式
500
- listHeight: PropTypes.string,
501
-
502
- // isGroupList
503
- isGroupList: PropTypes.bool,
504
-
505
- popoverType: PropTypes.oneOf(['focus', 'realFocus']),
506
-
507
- className: PropTypes.string,
508
- style: PropTypes.object,
509
- popupClassName: PropTypes.string,
510
- isInPopup: PropTypes.bool,
511
-
512
- /** 目前为了 keyboard */
513
- isKeyboard: PropTypes.bool,
514
- onKeyDown: PropTypes.func
515
- }
516
-
517
- export default Base
1
+ import { getLocale } from '@gmfe/locales'
2
+ import React from 'react'
3
+ import PropTypes from 'prop-types'
4
+ import _ from 'lodash'
5
+ import classNames from 'classnames'
6
+ import Popover from '../popover'
7
+ import Flex from '../flex'
8
+ import ListBase from '../list/base'
9
+ import Loading from '../loading'
10
+ import { pinYinFilter } from '@gm-common/tool'
11
+ import { findDOMNode } from 'react-dom'
12
+ import SVGCloseCircle from '../../../svg/close-circle.svg'
13
+ import SVGRemove from '../../../svg/remove.svg'
14
+
15
+ // 不要轻易改这个文件
16
+ // TODO keydown item disabled
17
+ // 目前全键盘还没有这种场景,暂时不管
18
+ class Base extends React.Component {
19
+ constructor(props) {
20
+ super(props)
21
+
22
+ this.ref = React.createRef()
23
+ this.popoverRef = React.createRef()
24
+ this.selectedRef = React.createRef()
25
+
26
+ this._isUnmounted = false
27
+
28
+ this.debounceDoSearch = _.debounce(this.doSearch, props.delay)
29
+
30
+ this.state = {
31
+ searchValue: '',
32
+ loading: false,
33
+ // keyboard 默认第一个位置
34
+ willActiveIndex: props.isKeyboard ? 0 : null,
35
+ _style: {}
36
+ // isOnComposition: false
37
+ }
38
+ // 要后于 this.state 执行,因为 getFilterData 用到 searchValue
39
+
40
+ // 有选择才有意义
41
+ if (props.selected.length > 0) {
42
+ this.getFilterData()
43
+ const flatList = this.getFlatFilterData()
44
+ const index = _.findIndex(
45
+ flatList,
46
+ v => v.value === props.selected[0].value
47
+ )
48
+ this.state.willActiveIndex = index
49
+ }
50
+ }
51
+
52
+ isOnComposition = false
53
+
54
+ setInputValue = () => {
55
+ this.ref.current.value = this.state.searchValue || ''
56
+ }
57
+
58
+ apiDoFocus = () => {
59
+ // 唤起 popover,input autoFocus 会自动聚焦,但是这种方式本质是显示 UI
60
+ // this.popoverRef.current.apiDoSetActive(true)
61
+
62
+ // focus 更符合直觉
63
+ findDOMNode(this.selectedRef.current).focus()
64
+ }
65
+
66
+ apiDoSelectWillActive = () => {
67
+ const { selected, onSelect, multiple } = this.props
68
+ const { willActiveIndex } = this.state
69
+ const flatList = this.getFlatFilterData()
70
+ // 没有做过键盘操作啥也不做
71
+ if (willActiveIndex !== null && willActiveIndex < flatList.length) {
72
+ if (multiple) {
73
+ onSelect(
74
+ _.uniqBy([...selected, flatList[willActiveIndex]], item => item.value)
75
+ )
76
+ } else {
77
+ onSelect([flatList[willActiveIndex]])
78
+ }
79
+ }
80
+ }
81
+
82
+ componentDidMount() {
83
+ const dom = findDOMNode(this)
84
+ const _style = { width: dom.offsetWidth }
85
+ this.setState({ _style })
86
+ this.setInputValue()
87
+ }
88
+
89
+ componentDidUpdate() {
90
+ this.setInputValue()
91
+ }
92
+
93
+ componentWillUnmount() {
94
+ this._isUnmounted = true
95
+ }
96
+
97
+ handleClear = (clearItem, event) => {
98
+ event.stopPropagation()
99
+
100
+ const { onSelect, selected } = this.props
101
+
102
+ const willSelected = _.filter(
103
+ selected,
104
+ item => item.value !== clearItem.value
105
+ )
106
+
107
+ onSelect(willSelected)
108
+ }
109
+
110
+ handleChange = e => {
111
+ const searchValue = e.target.value
112
+
113
+ this.setState({
114
+ searchValue
115
+ })
116
+ if (this.isOnComposition && this.props.isEnableChineseCheck) return
117
+ this.debounceDoSearch(searchValue)
118
+ }
119
+
120
+ handleComposition = evt => {
121
+ if (evt.type === 'compositionend') {
122
+ this.isOnComposition = false
123
+ if (navigator.userAgent.indexOf('Chrome') > -1) {
124
+ this.handleChange(evt)
125
+ }
126
+ return
127
+ }
128
+ this.isOnComposition = true
129
+ }
130
+
131
+ handleSelected = values => {
132
+ const { onSelect, data, multiple, selected } = this.props
133
+ const items = []
134
+ _.each(data, group => {
135
+ _.each(group.children, item => {
136
+ if (values.includes(item.value)) {
137
+ items.push(item)
138
+ }
139
+ })
140
+ })
141
+
142
+ _.each(selected, item => {
143
+ let flag = true // 判断当前已选择的选项中是否存在不在当前data里面的,解决onSearch异步,true则表示都不在data里面
144
+ _.each(data, group => {
145
+ flag = flag && _.every(group.children, v => v.value !== item.value)
146
+ })
147
+ if (flag) {
148
+ items.push(item)
149
+ }
150
+ })
151
+
152
+ onSelect(items)
153
+
154
+ if (!multiple) {
155
+ // 单选选后关闭
156
+ // 要异步
157
+ setTimeout(() => {
158
+ if (!this._isUnmounted) {
159
+ this.popoverRef.current.apiDoSetActive(false)
160
+ }
161
+ }, 0)
162
+ }
163
+ }
164
+
165
+ doSearch = query => {
166
+ const { onSearch, data } = this.props
167
+
168
+ if (!this._isUnmounted && onSearch) {
169
+ const result = onSearch(query, data)
170
+
171
+ if (!result) {
172
+ return
173
+ }
174
+
175
+ this.setState({
176
+ loading: true
177
+ })
178
+
179
+ Promise.resolve(result)
180
+ .then(() => {
181
+ if (!this._isUnmounted) {
182
+ this.setState({
183
+ loading: false
184
+ })
185
+ }
186
+ })
187
+ .catch(() => {
188
+ if (!this._isUnmounted) {
189
+ this.setState({
190
+ isLoading: false
191
+ })
192
+ }
193
+ })
194
+ }
195
+ }
196
+
197
+ getFlatFilterData = () => {
198
+ return _.flatMap(this.filterData, v => v.children)
199
+ }
200
+
201
+ handlePopupKeyDown = event => {
202
+ const { onKeyDown } = this.props
203
+ let { willActiveIndex } = this.state
204
+
205
+ // 不是上下方向键,不用拦截
206
+ if (event.key !== 'ArrowDown' && event.key !== 'ArrowUp') {
207
+ onKeyDown(event)
208
+ return
209
+ }
210
+
211
+ const flatList = this.getFlatFilterData()
212
+ // 没有过滤数据,不用拦截
213
+ if (flatList.length === 0) {
214
+ onKeyDown(event)
215
+ return
216
+ }
217
+
218
+ // 以下是需要拦截部分
219
+
220
+ if (event.key === 'ArrowUp') {
221
+ willActiveIndex--
222
+ } else if (event.key === 'ArrowDown') {
223
+ willActiveIndex++
224
+ }
225
+
226
+ // 修正
227
+ if (willActiveIndex < 0) {
228
+ willActiveIndex = flatList.length - 1
229
+ } else if (willActiveIndex > flatList.length - 1) {
230
+ willActiveIndex = 0
231
+ }
232
+
233
+ this.setState({
234
+ willActiveIndex
235
+ })
236
+ }
237
+
238
+ getFilterData = () => {
239
+ const { data, renderListFilter, renderListFilterType } = this.props
240
+ const { searchValue } = this.state
241
+
242
+ let filterData = data
243
+ // 节省过滤时间
244
+ if (renderListFilter) {
245
+ filterData = renderListFilter(data, searchValue)
246
+ } else if (renderListFilterType === 'pinyin') {
247
+ filterData = renderListFilterPinYin(data, searchValue)
248
+ } else {
249
+ filterData = renderListFilterDefault(data, searchValue)
250
+ }
251
+
252
+ // 存起来给上下键用
253
+ this.filterData = filterData
254
+
255
+ return filterData
256
+ }
257
+
258
+ renderList() {
259
+ const {
260
+ selected,
261
+ multiple,
262
+ isGroupList,
263
+ renderListItem,
264
+ searchPlaceholder,
265
+ listHeight,
266
+ popupClassName,
267
+ isEnableChineseCheck
268
+ } = this.props
269
+
270
+ const { loading, searchValue, willActiveIndex } = this.state
271
+
272
+ const filterData = this.getFilterData()
273
+
274
+ return (
275
+ <div
276
+ className={classNames('gm-more-select-popup', popupClassName)}
277
+ onKeyDown={this.handlePopupKeyDown}
278
+ >
279
+ <div className='gm-more-select-popup-input'>
280
+ {isEnableChineseCheck ? (
281
+ <input
282
+ autoFocus
283
+ className='form-control'
284
+ type='text'
285
+ // value={searchValue}
286
+ onChange={this.handleChange}
287
+ placeholder={searchPlaceholder}
288
+ onCompositionStart={this.handleComposition}
289
+ onCompositionUpdate={this.handleComposition}
290
+ onCompositionEnd={this.handleComposition}
291
+ />
292
+ ) : (
293
+ <input
294
+ autoFocus
295
+ className='form-control'
296
+ type='text'
297
+ value={searchValue}
298
+ onChange={this.handleChange}
299
+ placeholder={searchPlaceholder}
300
+ />
301
+ )}
302
+ </div>
303
+ <div style={{ height: listHeight }}>
304
+ {loading && (
305
+ <Flex alignCenter justifyCenter className='gm-bg gm-padding-5'>
306
+ <Loading size={20} />
307
+ </Flex>
308
+ )}
309
+ {!loading && filterData.length === 0 && (
310
+ <Flex
311
+ alignCenter
312
+ justifyCenter
313
+ className='gm-bg gm-padding-5 gm-text-desc'
314
+ >
315
+ {getLocale('没有数据')}
316
+ </Flex>
317
+ )}
318
+ {!loading && filterData.length !== 0 && (
319
+ <ListBase
320
+ data={filterData}
321
+ selected={_.map(selected, v => v.value)}
322
+ multiple={multiple}
323
+ isGroupList={isGroupList}
324
+ className='gm-border-0'
325
+ renderItem={renderListItem}
326
+ onSelect={this.handleSelected}
327
+ isScrollTo
328
+ willActiveIndex={willActiveIndex}
329
+ style={{
330
+ height: listHeight
331
+ }}
332
+ />
333
+ )}
334
+ </div>
335
+ </div>
336
+ )
337
+ }
338
+
339
+ render() {
340
+ const {
341
+ isInPopup,
342
+ disabled,
343
+ disabledClose,
344
+ selected,
345
+ multiple,
346
+ placeholder,
347
+
348
+ renderSelected,
349
+
350
+ className,
351
+ style,
352
+ popoverType,
353
+ children
354
+ } = this.props
355
+
356
+ const { _style } = this.state
357
+
358
+ return (
359
+ <div
360
+ ref={this.ref}
361
+ className={classNames(
362
+ 'gm-more-select',
363
+ {
364
+ 'gm-more-select-disabled': disabled,
365
+ 'gm-more-select-multiple': multiple
366
+ },
367
+ className
368
+ )}
369
+ style={{ ..._style, ...style }}
370
+ >
371
+ <Popover
372
+ ref={this.popoverRef}
373
+ type={popoverType}
374
+ animName
375
+ popup={() => this.renderList()}
376
+ disabled={disabled}
377
+ isInPopup={isInPopup}
378
+ >
379
+ {children || (
380
+ <Flex
381
+ ref={this.selectedRef}
382
+ tabIndex={0}
383
+ wrap
384
+ className='gm-more-select-selected'
385
+ >
386
+ {selected.length !== 0 ? (
387
+ _.map(selected, item => (
388
+ <Flex
389
+ key={item.value}
390
+ className='gm-more-select-selected-item'
391
+ >
392
+ <Popover
393
+ disabled={!this.props.isKeyboard}
394
+ type='hover'
395
+ popup={<div className='gm-padding-10'>{item.text}</div>}
396
+ >
397
+ <Flex flex column>
398
+ {renderSelected(item)}
399
+ </Flex>
400
+ </Popover>
401
+ {multiple ? (
402
+ <SVGRemove
403
+ onClick={
404
+ disabled ? _.noop : this.handleClear.bind(this, item)
405
+ }
406
+ className='gm-cursor gm-more-select-clear-btn'
407
+ />
408
+ ) : (
409
+ !disabledClose && ( // 是否不显示清除按钮,仅单选可用
410
+ <SVGCloseCircle
411
+ onClick={
412
+ disabled
413
+ ? _.noop
414
+ : this.handleClear.bind(this, item)
415
+ }
416
+ className='gm-cursor gm-more-select-clear-btn'
417
+ />
418
+ )
419
+ )}
420
+ </Flex>
421
+ ))
422
+ ) : (
423
+ // 加多个 &nbsp; 避免对齐问题。 有文本才有对齐
424
+ <div className='gm-text-desc'>{placeholder}&nbsp;</div>
425
+ )}
426
+ </Flex>
427
+ )}
428
+ </Popover>
429
+ </div>
430
+ )
431
+ }
432
+ }
433
+
434
+ function renderListFilterDefault(data, query) {
435
+ const result = []
436
+ const keywords = query.toLowerCase()
437
+ // TODO 加个queryText,用于基于多个搜索结果的情况下,因为是公共组件,所以多加个字段
438
+ _.each(data, v => {
439
+ const arr = _.filter(
440
+ v?.children || [],
441
+ item =>
442
+ item?.text?.toLowerCase()?.includes(keywords) ||
443
+ item?.queryText?.toLowerCase()?.includes(keywords)
444
+ )
445
+ if (arr.length) {
446
+ result.push({
447
+ ...v,
448
+ children: arr
449
+ })
450
+ }
451
+ })
452
+
453
+ return result
454
+ }
455
+
456
+ function renderListFilterPinYin(data, query) {
457
+ const result = []
458
+ _.each(data, v => {
459
+ const arr = pinYinFilter(v.children, query, item => item.text)
460
+ if (arr.length) {
461
+ result.push({
462
+ ...v,
463
+ children: arr
464
+ })
465
+ }
466
+ })
467
+
468
+ return result
469
+ }
470
+
471
+ Base.renderListFilterDefault = renderListFilterDefault
472
+ Base.renderListFilterPinYin = renderListFilterPinYin
473
+
474
+ Base.propTypes = {
475
+ // 基本属性
476
+ data: PropTypes.array.isRequired, // label, children: [{value, text}]
477
+ selected: PropTypes.array.isRequired, // item 数组。 非 value,也非引用,原因是想解耦 selected 和 data 的关系。这样当
478
+ onSelect: PropTypes.func.isRequired, // 返回 item 数组
479
+ multiple: PropTypes.bool,
480
+ isEnableChineseCheck: PropTypes.bool, // 是否开启中文检查
481
+
482
+ // 状态
483
+ disabled: PropTypes.bool,
484
+ /** 单选禁止显示关闭按钮 */
485
+ disabledClose: PropTypes.bool,
486
+
487
+ // 列表 搜索
488
+ onSearch: PropTypes.func, // searchValue, data
489
+ delay: PropTypes.number,
490
+ searchPlaceholder: PropTypes.string,
491
+ renderListFilter: PropTypes.func, // 过滤,提供 searchValue 和 data
492
+ renderListFilterType: PropTypes.oneOf(['default', 'pinyin']), // 也可简单指定 默认的过滤类型
493
+
494
+ // 展示
495
+ placeholder: PropTypes.string,
496
+ renderSelected: PropTypes.func, // 定制已选的区域,提供 selected
497
+ renderListItem: PropTypes.func, // 定制列表
498
+
499
+ // 样式
500
+ listHeight: PropTypes.string,
501
+
502
+ // isGroupList
503
+ isGroupList: PropTypes.bool,
504
+
505
+ popoverType: PropTypes.oneOf(['focus', 'realFocus']),
506
+
507
+ className: PropTypes.string,
508
+ style: PropTypes.object,
509
+ popupClassName: PropTypes.string,
510
+ isInPopup: PropTypes.bool,
511
+
512
+ /** 目前为了 keyboard */
513
+ isKeyboard: PropTypes.bool,
514
+ onKeyDown: PropTypes.func
515
+ }
516
+
517
+ export default Base