funda-ui 4.5.712 → 4.5.766

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 (501) hide show
  1. package/Chatbox/index.d.ts +54 -0
  2. package/{publish/lib/cjs/Date → Chatbox}/index.js +2465 -3802
  3. package/README.md +4 -105
  4. package/Utils/useStreamController.d.ts +71 -0
  5. package/Utils/useStreamController.js +494 -0
  6. package/{publish/all.d.ts → all.d.ts} +1 -0
  7. package/{publish/all.js → all.js} +1 -0
  8. package/lib/cjs/Chatbox/index.d.ts +54 -0
  9. package/lib/cjs/Chatbox/index.js +4863 -0
  10. package/lib/cjs/Utils/useStreamController.d.ts +71 -0
  11. package/lib/cjs/Utils/useStreamController.js +494 -0
  12. package/lib/cjs/index.d.ts +1 -0
  13. package/lib/cjs/index.js +1 -0
  14. package/lib/esm/Chatbox/PureLoader.tsx +45 -0
  15. package/lib/esm/Chatbox/TypingEffect.tsx +32 -0
  16. package/lib/esm/Chatbox/index.scss +502 -0
  17. package/lib/esm/Chatbox/index.tsx +1171 -0
  18. package/lib/esm/Chatbox/useStreamController.tsx +277 -0
  19. package/lib/esm/Chatbox/utils/func.ts +107 -0
  20. package/lib/esm/Textarea/index.tsx +1 -0
  21. package/lib/esm/Utils/hooks/useStreamController.tsx +277 -0
  22. package/lib/esm/index.js +1 -0
  23. package/package.json +44 -41
  24. package/.gitattributes +0 -2
  25. package/README_PUBLISH.md +0 -126
  26. package/logo.png +0 -0
  27. package/preview.png +0 -0
  28. package/publish/LICENSE +0 -21
  29. package/publish/README.md +0 -126
  30. package/publish/lib/cjs/Accordion/index.d.ts +0 -2
  31. package/publish/lib/cjs/Accordion/index.js +0 -1035
  32. package/publish/lib/cjs/BackToTop/index.d.ts +0 -17
  33. package/publish/lib/cjs/BackToTop/index.js +0 -904
  34. package/publish/lib/cjs/CascadingSelect/index.d.ts +0 -60
  35. package/publish/lib/cjs/CascadingSelect/index.js +0 -2943
  36. package/publish/lib/cjs/CascadingSelectE2E/index.d.ts +0 -71
  37. package/publish/lib/cjs/CascadingSelectE2E/index.js +0 -3540
  38. package/publish/lib/cjs/Checkbox/index.d.ts +0 -28
  39. package/publish/lib/cjs/Checkbox/index.js +0 -662
  40. package/publish/lib/cjs/ColorPicker/index.d.ts +0 -27
  41. package/publish/lib/cjs/ColorPicker/index.js +0 -662
  42. package/publish/lib/cjs/Date/index.d.ts +0 -70
  43. package/publish/lib/cjs/DigitalClock/index.d.ts +0 -7
  44. package/publish/lib/cjs/DigitalClock/index.js +0 -402
  45. package/publish/lib/cjs/DragDropList/index.d.ts +0 -44
  46. package/publish/lib/cjs/DragDropList/index.js +0 -1587
  47. package/publish/lib/cjs/DropdownMenu/index.d.ts +0 -38
  48. package/publish/lib/cjs/DropdownMenu/index.js +0 -1498
  49. package/publish/lib/cjs/DynamicFields/index.d.ts +0 -40
  50. package/publish/lib/cjs/DynamicFields/index.js +0 -810
  51. package/publish/lib/cjs/EventCalendar/index.d.ts +0 -61
  52. package/publish/lib/cjs/EventCalendar/index.js +0 -3740
  53. package/publish/lib/cjs/EventCalendarTimeline/index.d.ts +0 -100
  54. package/publish/lib/cjs/EventCalendarTimeline/index.js +0 -6084
  55. package/publish/lib/cjs/File/index.d.ts +0 -40
  56. package/publish/lib/cjs/File/index.js +0 -1751
  57. package/publish/lib/cjs/HorizontalScrollContent/index.d.ts +0 -14
  58. package/publish/lib/cjs/HorizontalScrollContent/index.js +0 -426
  59. package/publish/lib/cjs/Input/index.d.ts +0 -59
  60. package/publish/lib/cjs/Input/index.js +0 -1455
  61. package/publish/lib/cjs/LiveSearch/index.d.ts +0 -69
  62. package/publish/lib/cjs/LiveSearch/index.js +0 -3626
  63. package/publish/lib/cjs/MasonryLayout/index.d.ts +0 -14
  64. package/publish/lib/cjs/MasonryLayout/index.js +0 -689
  65. package/publish/lib/cjs/ModalDialog/index.d.ts +0 -79
  66. package/publish/lib/cjs/ModalDialog/index.js +0 -1695
  67. package/publish/lib/cjs/ModeSwitch/index.d.ts +0 -17
  68. package/publish/lib/cjs/ModeSwitch/index.js +0 -202
  69. package/publish/lib/cjs/MultilevelDropdownMenu/index.d.ts +0 -20
  70. package/publish/lib/cjs/MultilevelDropdownMenu/index.js +0 -930
  71. package/publish/lib/cjs/MultipleCheckboxes/index.d.ts +0 -41
  72. package/publish/lib/cjs/MultipleCheckboxes/index.js +0 -1717
  73. package/publish/lib/cjs/MultipleSelect/index.d.ts +0 -65
  74. package/publish/lib/cjs/MultipleSelect/index.js +0 -3704
  75. package/publish/lib/cjs/NativeSelect/index.d.ts +0 -37
  76. package/publish/lib/cjs/NativeSelect/index.js +0 -1631
  77. package/publish/lib/cjs/NumberInput/index.d.ts +0 -40
  78. package/publish/lib/cjs/NumberInput/index.js +0 -1188
  79. package/publish/lib/cjs/Pagination/index.d.ts +0 -51
  80. package/publish/lib/cjs/Pagination/index.js +0 -612
  81. package/publish/lib/cjs/Radio/index.d.ts +0 -45
  82. package/publish/lib/cjs/Radio/index.js +0 -1391
  83. package/publish/lib/cjs/RangeSlider/index.d.ts +0 -22
  84. package/publish/lib/cjs/RangeSlider/index.js +0 -2665
  85. package/publish/lib/cjs/RootPortal/index.d.ts +0 -8
  86. package/publish/lib/cjs/RootPortal/index.js +0 -141
  87. package/publish/lib/cjs/ScrollReveal/index.d.ts +0 -21
  88. package/publish/lib/cjs/ScrollReveal/index.js +0 -401
  89. package/publish/lib/cjs/Scrollbar/index.d.ts +0 -17
  90. package/publish/lib/cjs/Scrollbar/index.js +0 -1107
  91. package/publish/lib/cjs/SearchBar/index.d.ts +0 -41
  92. package/publish/lib/cjs/SearchBar/index.js +0 -701
  93. package/publish/lib/cjs/Select/index.d.ts +0 -99
  94. package/publish/lib/cjs/Select/index.js +0 -5697
  95. package/publish/lib/cjs/ShowMoreLess/index.d.ts +0 -36
  96. package/publish/lib/cjs/ShowMoreLess/index.js +0 -387
  97. package/publish/lib/cjs/Switch/index.d.ts +0 -25
  98. package/publish/lib/cjs/Switch/index.js +0 -628
  99. package/publish/lib/cjs/Table/index.d.ts +0 -12
  100. package/publish/lib/cjs/Table/index.js +0 -2062
  101. package/publish/lib/cjs/Tabs/index.d.ts +0 -3
  102. package/publish/lib/cjs/Tabs/index.js +0 -771
  103. package/publish/lib/cjs/TagInput/index.d.ts +0 -31
  104. package/publish/lib/cjs/TagInput/index.js +0 -1144
  105. package/publish/lib/cjs/Textarea/index.d.ts +0 -50
  106. package/publish/lib/cjs/Textarea/index.js +0 -1784
  107. package/publish/lib/cjs/Toast/index.d.ts +0 -34
  108. package/publish/lib/cjs/Toast/index.js +0 -861
  109. package/publish/lib/cjs/Tooltip/index.d.ts +0 -23
  110. package/publish/lib/cjs/Tooltip/index.js +0 -1674
  111. package/publish/lib/cjs/Tree/index.d.ts +0 -62
  112. package/publish/lib/cjs/Tree/index.js +0 -1960
  113. package/publish/lib/cjs/Utils/anim.d.ts +0 -11
  114. package/publish/lib/cjs/Utils/anim.js +0 -400
  115. package/publish/lib/cjs/Utils/bodyScrollLock.d.ts +0 -8
  116. package/publish/lib/cjs/Utils/bodyScrollLock.js +0 -311
  117. package/publish/lib/cjs/Utils/buffer.d.ts +0 -67
  118. package/publish/lib/cjs/Utils/buffer.js +0 -343
  119. package/publish/lib/cjs/Utils/cls.d.ts +0 -15
  120. package/publish/lib/cjs/Utils/cls.js +0 -124
  121. package/publish/lib/cjs/Utils/convert.d.ts +0 -25
  122. package/publish/lib/cjs/Utils/convert.js +0 -109
  123. package/publish/lib/cjs/Utils/date.d.ts +0 -217
  124. package/publish/lib/cjs/Utils/date.js +0 -567
  125. package/publish/lib/cjs/Utils/dom.d.ts +0 -13
  126. package/publish/lib/cjs/Utils/dom.js +0 -215
  127. package/publish/lib/cjs/Utils/easing.d.ts +0 -29
  128. package/publish/lib/cjs/Utils/easing.js +0 -221
  129. package/publish/lib/cjs/Utils/extract.d.ts +0 -28
  130. package/publish/lib/cjs/Utils/extract.js +0 -130
  131. package/publish/lib/cjs/Utils/getElementProperty.d.ts +0 -52
  132. package/publish/lib/cjs/Utils/getElementProperty.js +0 -189
  133. package/publish/lib/cjs/Utils/guid.d.ts +0 -7
  134. package/publish/lib/cjs/Utils/guid.js +0 -67
  135. package/publish/lib/cjs/Utils/initDefaultOptions.d.ts +0 -21
  136. package/publish/lib/cjs/Utils/initDefaultOptions.js +0 -131
  137. package/publish/lib/cjs/Utils/inputsCalculation.d.ts +0 -28
  138. package/publish/lib/cjs/Utils/inputsCalculation.js +0 -188
  139. package/publish/lib/cjs/Utils/math.d.ts +0 -77
  140. package/publish/lib/cjs/Utils/math.js +0 -305
  141. package/publish/lib/cjs/Utils/object.d.ts +0 -18
  142. package/publish/lib/cjs/Utils/object.js +0 -120
  143. package/publish/lib/cjs/Utils/os.d.ts +0 -2
  144. package/publish/lib/cjs/Utils/os.js +0 -104
  145. package/publish/lib/cjs/Utils/performance.d.ts +0 -3
  146. package/publish/lib/cjs/Utils/performance.js +0 -94
  147. package/publish/lib/cjs/Utils/tree.d.ts +0 -40
  148. package/publish/lib/cjs/Utils/tree.js +0 -195
  149. package/publish/lib/cjs/Utils/useAutosizeTextArea.d.ts +0 -10
  150. package/publish/lib/cjs/Utils/useAutosizeTextArea.js +0 -227
  151. package/publish/lib/cjs/Utils/useBoundedDrag.d.ts +0 -125
  152. package/publish/lib/cjs/Utils/useBoundedDrag.js +0 -380
  153. package/publish/lib/cjs/Utils/useClickOutside.d.ts +0 -33
  154. package/publish/lib/cjs/Utils/useClickOutside.js +0 -166
  155. package/publish/lib/cjs/Utils/useComId.d.ts +0 -6
  156. package/publish/lib/cjs/Utils/useComId.js +0 -114
  157. package/publish/lib/cjs/Utils/useDebounce.d.ts +0 -20
  158. package/publish/lib/cjs/Utils/useDebounce.js +0 -138
  159. package/publish/lib/cjs/Utils/useDragDropPosition.d.ts +0 -169
  160. package/publish/lib/cjs/Utils/useDragDropPosition.js +0 -456
  161. package/publish/lib/cjs/Utils/useDraggable.d.ts +0 -62
  162. package/publish/lib/cjs/Utils/useDraggable.js +0 -348
  163. package/publish/lib/cjs/Utils/useInterval.d.ts +0 -5
  164. package/publish/lib/cjs/Utils/useInterval.js +0 -168
  165. package/publish/lib/cjs/Utils/useIsMobile.d.ts +0 -2
  166. package/publish/lib/cjs/Utils/useIsMobile.js +0 -168
  167. package/publish/lib/cjs/Utils/useKeyPress.d.ts +0 -44
  168. package/publish/lib/cjs/Utils/useKeyPress.js +0 -200
  169. package/publish/lib/cjs/Utils/useThrottle.d.ts +0 -2
  170. package/publish/lib/cjs/Utils/useThrottle.js +0 -136
  171. package/publish/lib/cjs/Utils/useWindowScroll.d.ts +0 -12
  172. package/publish/lib/cjs/Utils/useWindowScroll.js +0 -217
  173. package/publish/lib/cjs/Utils/viewport.d.ts +0 -7
  174. package/publish/lib/cjs/Utils/viewport.js +0 -64
  175. package/publish/lib/cjs/index.d.ts +0 -45
  176. package/publish/lib/cjs/index.js +0 -46
  177. package/publish/lib/css/BackToTop/index.css +0 -34
  178. package/publish/lib/css/CascadingSelect/index.css +0 -216
  179. package/publish/lib/css/CascadingSelectE2E/index.css +0 -216
  180. package/publish/lib/css/ColorPicker/index.css +0 -58
  181. package/publish/lib/css/Date/index.css +0 -434
  182. package/publish/lib/css/DragDropList/index.css +0 -188
  183. package/publish/lib/css/DropdownMenu/index.css +0 -151
  184. package/publish/lib/css/EventCalendar/index.css +0 -300
  185. package/publish/lib/css/EventCalendarTimeline/index.css +0 -694
  186. package/publish/lib/css/HorizontalScrollContent/index.css +0 -70
  187. package/publish/lib/css/LiveSearch/index.css +0 -55
  188. package/publish/lib/css/MultilevelDropdownMenu/index.css +0 -38
  189. package/publish/lib/css/MultipleSelect/index.css +0 -313
  190. package/publish/lib/css/RangeSlider/index.css +0 -150
  191. package/publish/lib/css/Scrollbar/index.css +0 -176
  192. package/publish/lib/css/Select/index.css +0 -368
  193. package/publish/lib/css/ShowMoreLess/index.css +0 -23
  194. package/publish/lib/css/Table/index.css +0 -584
  195. package/publish/lib/css/TagInput/index.css +0 -91
  196. package/publish/lib/css/Toast/index.css +0 -201
  197. package/publish/lib/css/Tooltip/index.css +0 -197
  198. package/publish/lib/css/Tree/index.css +0 -232
  199. package/publish/lib/esm/Accordion/Accordion.tsx +0 -184
  200. package/publish/lib/esm/Accordion/AccordionItem.tsx +0 -143
  201. package/publish/lib/esm/Accordion/index.tsx +0 -2
  202. package/publish/lib/esm/BackToTop/index.scss +0 -47
  203. package/publish/lib/esm/BackToTop/index.tsx +0 -177
  204. package/publish/lib/esm/CascadingSelect/Group.tsx +0 -82
  205. package/publish/lib/esm/CascadingSelect/index.scss +0 -291
  206. package/publish/lib/esm/CascadingSelect/index.tsx +0 -1203
  207. package/publish/lib/esm/CascadingSelectE2E/Group.tsx +0 -83
  208. package/publish/lib/esm/CascadingSelectE2E/index.scss +0 -293
  209. package/publish/lib/esm/CascadingSelectE2E/index.tsx +0 -1471
  210. package/publish/lib/esm/Checkbox/index.tsx +0 -193
  211. package/publish/lib/esm/ColorPicker/index.scss +0 -91
  212. package/publish/lib/esm/ColorPicker/index.tsx +0 -204
  213. package/publish/lib/esm/Date/Calendar.tsx +0 -723
  214. package/publish/lib/esm/Date/index.scss +0 -567
  215. package/publish/lib/esm/Date/index.tsx +0 -1683
  216. package/publish/lib/esm/Date/localization/en_US.js +0 -13
  217. package/publish/lib/esm/Date/localization/zh_CN.js +0 -12
  218. package/publish/lib/esm/DigitalClock/index.tsx +0 -74
  219. package/publish/lib/esm/DragDropList/index.scss +0 -245
  220. package/publish/lib/esm/DragDropList/index.tsx +0 -494
  221. package/publish/lib/esm/DropdownMenu/Option.tsx +0 -55
  222. package/publish/lib/esm/DropdownMenu/index.scss +0 -205
  223. package/publish/lib/esm/DropdownMenu/index.tsx +0 -377
  224. package/publish/lib/esm/DynamicFields/index.tsx +0 -404
  225. package/publish/lib/esm/EventCalendar/index.scss +0 -407
  226. package/publish/lib/esm/EventCalendar/index.tsx +0 -1004
  227. package/publish/lib/esm/EventCalendarTimeline/index.scss +0 -926
  228. package/publish/lib/esm/EventCalendarTimeline/index.tsx +0 -2683
  229. package/publish/lib/esm/File/index.tsx +0 -477
  230. package/publish/lib/esm/HorizontalScrollContent/index.scss +0 -87
  231. package/publish/lib/esm/HorizontalScrollContent/index.tsx +0 -171
  232. package/publish/lib/esm/Input/index.tsx +0 -614
  233. package/publish/lib/esm/LiveSearch/index.scss +0 -82
  234. package/publish/lib/esm/LiveSearch/index.tsx +0 -960
  235. package/publish/lib/esm/MasonryLayout/index.tsx +0 -326
  236. package/publish/lib/esm/ModalDialog/index.tsx +0 -552
  237. package/publish/lib/esm/ModeSwitch/index.tsx +0 -82
  238. package/publish/lib/esm/MultilevelDropdownMenu/ItemList.tsx +0 -265
  239. package/publish/lib/esm/MultilevelDropdownMenu/index.scss +0 -79
  240. package/publish/lib/esm/MultilevelDropdownMenu/index.tsx +0 -77
  241. package/publish/lib/esm/MultipleCheckboxes/index.tsx +0 -669
  242. package/publish/lib/esm/MultipleSelect/index.scss +0 -398
  243. package/publish/lib/esm/MultipleSelect/index.tsx +0 -766
  244. package/publish/lib/esm/MultipleSelect/utils/func.ts +0 -61
  245. package/publish/lib/esm/NativeSelect/index.tsx +0 -396
  246. package/publish/lib/esm/NativeSelect/utils/func.ts +0 -49
  247. package/publish/lib/esm/NumberInput/index.tsx +0 -385
  248. package/publish/lib/esm/Pagination/index.tsx +0 -286
  249. package/publish/lib/esm/Pagination/pagination-navigators.tsx +0 -60
  250. package/publish/lib/esm/Radio/index.tsx +0 -670
  251. package/publish/lib/esm/RangeSlider/index.scss +0 -186
  252. package/publish/lib/esm/RangeSlider/index.tsx +0 -241
  253. package/publish/lib/esm/RootPortal/index.tsx +0 -53
  254. package/publish/lib/esm/ScrollReveal/index.tsx +0 -148
  255. package/publish/lib/esm/Scrollbar/index.scss +0 -221
  256. package/publish/lib/esm/Scrollbar/index.tsx +0 -561
  257. package/publish/lib/esm/SearchBar/index.tsx +0 -253
  258. package/publish/lib/esm/Select/index.scss +0 -553
  259. package/publish/lib/esm/Select/index.tsx +0 -2816
  260. package/publish/lib/esm/Select/utils/func.ts +0 -106
  261. package/publish/lib/esm/ShowMoreLess/index.scss +0 -27
  262. package/publish/lib/esm/ShowMoreLess/index.tsx +0 -145
  263. package/publish/lib/esm/Switch/index.tsx +0 -147
  264. package/publish/lib/esm/Table/Table.tsx +0 -257
  265. package/publish/lib/esm/Table/TableBody.tsx +0 -41
  266. package/publish/lib/esm/Table/TableCaption.tsx +0 -34
  267. package/publish/lib/esm/Table/TableCell.tsx +0 -123
  268. package/publish/lib/esm/Table/TableColgroup.tsx +0 -38
  269. package/publish/lib/esm/Table/TableContext.tsx +0 -26
  270. package/publish/lib/esm/Table/TableFoot.tsx +0 -28
  271. package/publish/lib/esm/Table/TableHead.tsx +0 -28
  272. package/publish/lib/esm/Table/TableRow.tsx +0 -76
  273. package/publish/lib/esm/Table/index.scss +0 -418
  274. package/publish/lib/esm/Table/index.tsx +0 -14
  275. package/publish/lib/esm/Table/utils/DragHandleSprite.tsx +0 -46
  276. package/publish/lib/esm/Table/utils/SortSprite.tsx +0 -57
  277. package/publish/lib/esm/Table/utils/TableFilter.tsx +0 -56
  278. package/publish/lib/esm/Table/utils/ToggleSelection.tsx +0 -225
  279. package/publish/lib/esm/Table/utils/func.ts +0 -171
  280. package/publish/lib/esm/Table/utils/hooks/useTableDraggable.tsx +0 -342
  281. package/publish/lib/esm/Table/utils/hooks/useTableKeyPress.tsx +0 -154
  282. package/publish/lib/esm/Table/utils/hooks/useTableResponsive.tsx +0 -92
  283. package/publish/lib/esm/Table/utils/hooks/useTableSort.tsx +0 -143
  284. package/publish/lib/esm/Tabs/TabList.tsx +0 -50
  285. package/publish/lib/esm/Tabs/TabPanel.tsx +0 -44
  286. package/publish/lib/esm/Tabs/Tabs.tsx +0 -282
  287. package/publish/lib/esm/Tabs/index.tsx +0 -3
  288. package/publish/lib/esm/TagInput/index.scss +0 -126
  289. package/publish/lib/esm/TagInput/index.tsx +0 -352
  290. package/publish/lib/esm/Textarea/index.tsx +0 -608
  291. package/publish/lib/esm/Toast/Item.tsx +0 -124
  292. package/publish/lib/esm/Toast/index.scss +0 -269
  293. package/publish/lib/esm/Toast/index.tsx +0 -374
  294. package/publish/lib/esm/Tooltip/index.scss +0 -269
  295. package/publish/lib/esm/Tooltip/index.tsx +0 -312
  296. package/publish/lib/esm/Tree/TreeList.tsx +0 -616
  297. package/publish/lib/esm/Tree/index.scss +0 -386
  298. package/publish/lib/esm/Tree/index.tsx +0 -396
  299. package/publish/lib/esm/Tree/init-height.tsx +0 -27
  300. package/publish/lib/esm/Tree/utils/func.ts +0 -15
  301. package/publish/lib/esm/Utils/hooks/useAutosizeTextArea.tsx +0 -125
  302. package/publish/lib/esm/Utils/hooks/useBoundedDrag.tsx +0 -301
  303. package/publish/lib/esm/Utils/hooks/useClickOutside.tsx +0 -69
  304. package/publish/lib/esm/Utils/hooks/useComId.tsx +0 -13
  305. package/publish/lib/esm/Utils/hooks/useDebounce.tsx +0 -40
  306. package/publish/lib/esm/Utils/hooks/useDragDropPosition.tsx +0 -420
  307. package/publish/lib/esm/Utils/hooks/useDraggable.tsx +0 -265
  308. package/publish/lib/esm/Utils/hooks/useInterval.tsx +0 -74
  309. package/publish/lib/esm/Utils/hooks/useIsMobile.tsx +0 -56
  310. package/publish/lib/esm/Utils/hooks/useKeyPress.tsx +0 -104
  311. package/publish/lib/esm/Utils/hooks/useThrottle.tsx +0 -39
  312. package/publish/lib/esm/Utils/hooks/useWindowScroll.tsx +0 -83
  313. package/publish/lib/esm/Utils/libs/anim.ts +0 -96
  314. package/publish/lib/esm/Utils/libs/buffer.ts +0 -262
  315. package/publish/lib/esm/Utils/libs/cls.ts +0 -64
  316. package/publish/lib/esm/Utils/libs/convert.ts +0 -59
  317. package/publish/lib/esm/Utils/libs/date.ts +0 -578
  318. package/publish/lib/esm/Utils/libs/dom.ts +0 -150
  319. package/publish/lib/esm/Utils/libs/easing.ts +0 -201
  320. package/publish/lib/esm/Utils/libs/extract.ts +0 -86
  321. package/publish/lib/esm/Utils/libs/getElementProperty.ts +0 -150
  322. package/publish/lib/esm/Utils/libs/guid.ts +0 -16
  323. package/publish/lib/esm/Utils/libs/initDefaultOptions.ts +0 -104
  324. package/publish/lib/esm/Utils/libs/inputsCalculation.ts +0 -160
  325. package/publish/lib/esm/Utils/libs/math.ts +0 -276
  326. package/publish/lib/esm/Utils/libs/object.ts +0 -68
  327. package/publish/lib/esm/Utils/libs/os.ts +0 -63
  328. package/publish/lib/esm/Utils/libs/performance.ts +0 -47
  329. package/publish/lib/esm/Utils/libs/tree.ts +0 -119
  330. package/publish/lib/esm/Utils/libs/viewport.ts +0 -20
  331. package/publish/lib/esm/Utils/plugins/bodyScrollLock.ts +0 -286
  332. package/publish/lib/esm/index.js +0 -43
  333. package/publish/package.json +0 -1
  334. /package/{publish/Accordion → Accordion}/index.d.ts +0 -0
  335. /package/{publish/Accordion → Accordion}/index.js +0 -0
  336. /package/{publish/BackToTop → BackToTop}/index.css +0 -0
  337. /package/{publish/BackToTop → BackToTop}/index.d.ts +0 -0
  338. /package/{publish/BackToTop → BackToTop}/index.js +0 -0
  339. /package/{publish/CascadingSelect → CascadingSelect}/index.css +0 -0
  340. /package/{publish/CascadingSelect → CascadingSelect}/index.d.ts +0 -0
  341. /package/{publish/CascadingSelect → CascadingSelect}/index.js +0 -0
  342. /package/{publish/CascadingSelectE2E → CascadingSelectE2E}/index.css +0 -0
  343. /package/{publish/CascadingSelectE2E → CascadingSelectE2E}/index.d.ts +0 -0
  344. /package/{publish/CascadingSelectE2E → CascadingSelectE2E}/index.js +0 -0
  345. /package/{publish/Checkbox → Checkbox}/index.d.ts +0 -0
  346. /package/{publish/Checkbox → Checkbox}/index.js +0 -0
  347. /package/{publish/ColorPicker → ColorPicker}/index.css +0 -0
  348. /package/{publish/ColorPicker → ColorPicker}/index.d.ts +0 -0
  349. /package/{publish/ColorPicker → ColorPicker}/index.js +0 -0
  350. /package/{publish/Date → Date}/index.css +0 -0
  351. /package/{publish/Date → Date}/index.d.ts +0 -0
  352. /package/{publish/Date → Date}/index.js +0 -0
  353. /package/{publish/DigitalClock → DigitalClock}/index.d.ts +0 -0
  354. /package/{publish/DigitalClock → DigitalClock}/index.js +0 -0
  355. /package/{publish/DragDropList → DragDropList}/index.css +0 -0
  356. /package/{publish/DragDropList → DragDropList}/index.d.ts +0 -0
  357. /package/{publish/DragDropList → DragDropList}/index.js +0 -0
  358. /package/{publish/DropdownMenu → DropdownMenu}/index.css +0 -0
  359. /package/{publish/DropdownMenu → DropdownMenu}/index.d.ts +0 -0
  360. /package/{publish/DropdownMenu → DropdownMenu}/index.js +0 -0
  361. /package/{publish/DynamicFields → DynamicFields}/index.d.ts +0 -0
  362. /package/{publish/DynamicFields → DynamicFields}/index.js +0 -0
  363. /package/{publish/EventCalendar → EventCalendar}/index.css +0 -0
  364. /package/{publish/EventCalendar → EventCalendar}/index.d.ts +0 -0
  365. /package/{publish/EventCalendar → EventCalendar}/index.js +0 -0
  366. /package/{publish/EventCalendarTimeline → EventCalendarTimeline}/index.css +0 -0
  367. /package/{publish/EventCalendarTimeline → EventCalendarTimeline}/index.d.ts +0 -0
  368. /package/{publish/EventCalendarTimeline → EventCalendarTimeline}/index.js +0 -0
  369. /package/{publish/File → File}/index.d.ts +0 -0
  370. /package/{publish/File → File}/index.js +0 -0
  371. /package/{publish/HorizontalScrollContent → HorizontalScrollContent}/index.css +0 -0
  372. /package/{publish/HorizontalScrollContent → HorizontalScrollContent}/index.d.ts +0 -0
  373. /package/{publish/HorizontalScrollContent → HorizontalScrollContent}/index.js +0 -0
  374. /package/{publish/Input → Input}/index.d.ts +0 -0
  375. /package/{publish/Input → Input}/index.js +0 -0
  376. /package/{publish/LiveSearch → LiveSearch}/index.css +0 -0
  377. /package/{publish/LiveSearch → LiveSearch}/index.d.ts +0 -0
  378. /package/{publish/LiveSearch → LiveSearch}/index.js +0 -0
  379. /package/{publish/MasonryLayout → MasonryLayout}/index.d.ts +0 -0
  380. /package/{publish/MasonryLayout → MasonryLayout}/index.js +0 -0
  381. /package/{publish/ModalDialog → ModalDialog}/index.d.ts +0 -0
  382. /package/{publish/ModalDialog → ModalDialog}/index.js +0 -0
  383. /package/{publish/ModeSwitch → ModeSwitch}/index.d.ts +0 -0
  384. /package/{publish/ModeSwitch → ModeSwitch}/index.js +0 -0
  385. /package/{publish/MultilevelDropdownMenu → MultilevelDropdownMenu}/index.css +0 -0
  386. /package/{publish/MultilevelDropdownMenu → MultilevelDropdownMenu}/index.d.ts +0 -0
  387. /package/{publish/MultilevelDropdownMenu → MultilevelDropdownMenu}/index.js +0 -0
  388. /package/{publish/MultipleCheckboxes → MultipleCheckboxes}/index.d.ts +0 -0
  389. /package/{publish/MultipleCheckboxes → MultipleCheckboxes}/index.js +0 -0
  390. /package/{publish/MultipleSelect → MultipleSelect}/index.css +0 -0
  391. /package/{publish/MultipleSelect → MultipleSelect}/index.d.ts +0 -0
  392. /package/{publish/MultipleSelect → MultipleSelect}/index.js +0 -0
  393. /package/{publish/NativeSelect → NativeSelect}/index.d.ts +0 -0
  394. /package/{publish/NativeSelect → NativeSelect}/index.js +0 -0
  395. /package/{publish/NumberInput → NumberInput}/index.d.ts +0 -0
  396. /package/{publish/NumberInput → NumberInput}/index.js +0 -0
  397. /package/{publish/Pagination → Pagination}/index.d.ts +0 -0
  398. /package/{publish/Pagination → Pagination}/index.js +0 -0
  399. /package/{publish/Radio → Radio}/index.d.ts +0 -0
  400. /package/{publish/Radio → Radio}/index.js +0 -0
  401. /package/{publish/RangeSlider → RangeSlider}/index.css +0 -0
  402. /package/{publish/RangeSlider → RangeSlider}/index.d.ts +0 -0
  403. /package/{publish/RangeSlider → RangeSlider}/index.js +0 -0
  404. /package/{publish/RootPortal → RootPortal}/index.d.ts +0 -0
  405. /package/{publish/RootPortal → RootPortal}/index.js +0 -0
  406. /package/{publish/ScrollReveal → ScrollReveal}/index.d.ts +0 -0
  407. /package/{publish/ScrollReveal → ScrollReveal}/index.js +0 -0
  408. /package/{publish/Scrollbar → Scrollbar}/index.css +0 -0
  409. /package/{publish/Scrollbar → Scrollbar}/index.d.ts +0 -0
  410. /package/{publish/Scrollbar → Scrollbar}/index.js +0 -0
  411. /package/{publish/SearchBar → SearchBar}/index.d.ts +0 -0
  412. /package/{publish/SearchBar → SearchBar}/index.js +0 -0
  413. /package/{publish/Select → Select}/index.css +0 -0
  414. /package/{publish/Select → Select}/index.d.ts +0 -0
  415. /package/{publish/Select → Select}/index.js +0 -0
  416. /package/{publish/ShowMoreLess → ShowMoreLess}/index.css +0 -0
  417. /package/{publish/ShowMoreLess → ShowMoreLess}/index.d.ts +0 -0
  418. /package/{publish/ShowMoreLess → ShowMoreLess}/index.js +0 -0
  419. /package/{publish/Switch → Switch}/index.d.ts +0 -0
  420. /package/{publish/Switch → Switch}/index.js +0 -0
  421. /package/{publish/Table → Table}/index.css +0 -0
  422. /package/{publish/Table → Table}/index.d.ts +0 -0
  423. /package/{publish/Table → Table}/index.js +0 -0
  424. /package/{publish/Tabs → Tabs}/index.d.ts +0 -0
  425. /package/{publish/Tabs → Tabs}/index.js +0 -0
  426. /package/{publish/TagInput → TagInput}/index.css +0 -0
  427. /package/{publish/TagInput → TagInput}/index.d.ts +0 -0
  428. /package/{publish/TagInput → TagInput}/index.js +0 -0
  429. /package/{publish/Textarea → Textarea}/index.d.ts +0 -0
  430. /package/{publish/Textarea → Textarea}/index.js +0 -0
  431. /package/{publish/Toast → Toast}/index.css +0 -0
  432. /package/{publish/Toast → Toast}/index.d.ts +0 -0
  433. /package/{publish/Toast → Toast}/index.js +0 -0
  434. /package/{publish/Tooltip → Tooltip}/index.css +0 -0
  435. /package/{publish/Tooltip → Tooltip}/index.d.ts +0 -0
  436. /package/{publish/Tooltip → Tooltip}/index.js +0 -0
  437. /package/{publish/Tree → Tree}/index.css +0 -0
  438. /package/{publish/Tree → Tree}/index.d.ts +0 -0
  439. /package/{publish/Tree → Tree}/index.js +0 -0
  440. /package/{publish/Utils → Utils}/anim.d.ts +0 -0
  441. /package/{publish/Utils → Utils}/anim.js +0 -0
  442. /package/{publish/Utils → Utils}/bodyScrollLock.d.ts +0 -0
  443. /package/{publish/Utils → Utils}/bodyScrollLock.js +0 -0
  444. /package/{publish/Utils → Utils}/buffer.d.ts +0 -0
  445. /package/{publish/Utils → Utils}/buffer.js +0 -0
  446. /package/{publish/Utils → Utils}/cls.d.ts +0 -0
  447. /package/{publish/Utils → Utils}/cls.js +0 -0
  448. /package/{publish/Utils → Utils}/convert.d.ts +0 -0
  449. /package/{publish/Utils → Utils}/convert.js +0 -0
  450. /package/{publish/Utils → Utils}/date.d.ts +0 -0
  451. /package/{publish/Utils → Utils}/date.js +0 -0
  452. /package/{publish/Utils → Utils}/dom.d.ts +0 -0
  453. /package/{publish/Utils → Utils}/dom.js +0 -0
  454. /package/{publish/Utils → Utils}/easing.d.ts +0 -0
  455. /package/{publish/Utils → Utils}/easing.js +0 -0
  456. /package/{publish/Utils → Utils}/extract.d.ts +0 -0
  457. /package/{publish/Utils → Utils}/extract.js +0 -0
  458. /package/{publish/Utils → Utils}/getElementProperty.d.ts +0 -0
  459. /package/{publish/Utils → Utils}/getElementProperty.js +0 -0
  460. /package/{publish/Utils → Utils}/guid.d.ts +0 -0
  461. /package/{publish/Utils → Utils}/guid.js +0 -0
  462. /package/{publish/Utils → Utils}/initDefaultOptions.d.ts +0 -0
  463. /package/{publish/Utils → Utils}/initDefaultOptions.js +0 -0
  464. /package/{publish/Utils → Utils}/inputsCalculation.d.ts +0 -0
  465. /package/{publish/Utils → Utils}/inputsCalculation.js +0 -0
  466. /package/{publish/Utils → Utils}/math.d.ts +0 -0
  467. /package/{publish/Utils → Utils}/math.js +0 -0
  468. /package/{publish/Utils → Utils}/object.d.ts +0 -0
  469. /package/{publish/Utils → Utils}/object.js +0 -0
  470. /package/{publish/Utils → Utils}/os.d.ts +0 -0
  471. /package/{publish/Utils → Utils}/os.js +0 -0
  472. /package/{publish/Utils → Utils}/performance.d.ts +0 -0
  473. /package/{publish/Utils → Utils}/performance.js +0 -0
  474. /package/{publish/Utils → Utils}/tree.d.ts +0 -0
  475. /package/{publish/Utils → Utils}/tree.js +0 -0
  476. /package/{publish/Utils → Utils}/useAutosizeTextArea.d.ts +0 -0
  477. /package/{publish/Utils → Utils}/useAutosizeTextArea.js +0 -0
  478. /package/{publish/Utils → Utils}/useBoundedDrag.d.ts +0 -0
  479. /package/{publish/Utils → Utils}/useBoundedDrag.js +0 -0
  480. /package/{publish/Utils → Utils}/useClickOutside.d.ts +0 -0
  481. /package/{publish/Utils → Utils}/useClickOutside.js +0 -0
  482. /package/{publish/Utils → Utils}/useComId.d.ts +0 -0
  483. /package/{publish/Utils → Utils}/useComId.js +0 -0
  484. /package/{publish/Utils → Utils}/useDebounce.d.ts +0 -0
  485. /package/{publish/Utils → Utils}/useDebounce.js +0 -0
  486. /package/{publish/Utils → Utils}/useDragDropPosition.d.ts +0 -0
  487. /package/{publish/Utils → Utils}/useDragDropPosition.js +0 -0
  488. /package/{publish/Utils → Utils}/useDraggable.d.ts +0 -0
  489. /package/{publish/Utils → Utils}/useDraggable.js +0 -0
  490. /package/{publish/Utils → Utils}/useInterval.d.ts +0 -0
  491. /package/{publish/Utils → Utils}/useInterval.js +0 -0
  492. /package/{publish/Utils → Utils}/useIsMobile.d.ts +0 -0
  493. /package/{publish/Utils → Utils}/useIsMobile.js +0 -0
  494. /package/{publish/Utils → Utils}/useKeyPress.d.ts +0 -0
  495. /package/{publish/Utils → Utils}/useKeyPress.js +0 -0
  496. /package/{publish/Utils → Utils}/useThrottle.d.ts +0 -0
  497. /package/{publish/Utils → Utils}/useThrottle.js +0 -0
  498. /package/{publish/Utils → Utils}/useWindowScroll.d.ts +0 -0
  499. /package/{publish/Utils → Utils}/useWindowScroll.js +0 -0
  500. /package/{publish/Utils → Utils}/viewport.d.ts +0 -0
  501. /package/{publish/Utils → Utils}/viewport.js +0 -0
@@ -1,2816 +0,0 @@
1
- import React, { useEffect, useState, useRef, KeyboardEvent, forwardRef, useImperativeHandle } from 'react';
2
-
3
- import {
4
- formatIndentVal,
5
- unique,
6
- stripHTML,
7
- removeItemOnce,
8
- optionsCustomSelectFlat,
9
- isObject
10
- } from './utils/func';
11
-
12
-
13
- import RootPortal from 'funda-root-portal';
14
-
15
-
16
- import useComId from 'funda-utils/dist/cjs/useComId';
17
- import {
18
- isJSON
19
- } from 'funda-utils/dist/cjs/initDefaultOptions';
20
- import useDebounce from 'funda-utils/dist/cjs/useDebounce';
21
- import useClickOutside from 'funda-utils/dist/cjs/useClickOutside';
22
- import useWindowScroll from 'funda-utils/dist/cjs/useWindowScroll';
23
- import {
24
- extractContentsOfBrackets
25
- } from 'funda-utils/dist/cjs/extract';
26
- import {
27
- convertArrToValByBrackets
28
- } from 'funda-utils/dist/cjs/convert';
29
- import {
30
- getAbsolutePositionOfStage
31
- } from 'funda-utils/dist/cjs/getElementProperty';
32
- import {
33
- addTreeDepth,
34
- addTreeIndent,
35
- } from 'funda-utils/dist/cjs/tree';
36
- import {
37
- getTextWidth
38
- } from 'funda-utils/dist/cjs/inputsCalculation';
39
- import {
40
- removeArrDuplicateItems
41
- } from 'funda-utils/dist/cjs/object';
42
-
43
- // Destroys body scroll locking
44
- import {
45
- clearAllBodyScrollLocks,
46
- disableBodyScroll,
47
- enableBodyScroll,
48
- } from 'funda-utils/dist/cjs/bodyScrollLock';
49
- import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
50
-
51
-
52
-
53
-
54
- export type SelectOptionChangeFnType = (arg1: any, arg2: any, arg3: any) => void;
55
-
56
- export interface MultiSelectDataConfig {
57
- values: string[] | number[];
58
- labels: string[] | number[];
59
- queryStrings: string[] | number[];
60
- }
61
-
62
- export interface MultiSelectControlValConfig {
63
- values: string[];
64
- labels: string[];
65
- }
66
-
67
- export interface OptionConfig {
68
- disabled?: boolean;
69
- optgroup?: any[];
70
- group?: boolean;
71
- label: any;
72
- listItemLabel?: any;
73
- value: any;
74
- queryString: string | number;
75
- callback?: () => void;
76
- }
77
-
78
-
79
- export interface MultiSelectConfig {
80
- valid: boolean;
81
- selectAll: boolean;
82
- selectAllLabel?: string;
83
- deselectAllLabel?: string;
84
- data: MultiSelectDataConfig | null;
85
- }
86
-
87
- export interface multiSelectSelectedItemOnlyStatusConfig {
88
- itemsLabel?: string;
89
- allItemsLabel?: string;
90
- noneLabel?: string;
91
- }
92
-
93
-
94
-
95
- export interface CleanTriggerConfig {
96
- valid: boolean;
97
- cleanValueLabel?: string;
98
- }
99
-
100
-
101
- export type SelectProps = {
102
- contentRef?: React.ForwardedRef<any>; // could use "Array" on contentRef.current, such as contentRef.current[0], contentRef.current[1]
103
- popupRef?: React.ForwardedRef<any>; // could use "Array" on popupRef.current, such as popupRef.current[0], popupRef.current[1]
104
- wrapperClassName?: string;
105
- controlClassName?: string;
106
- controlExClassName?: string;
107
- optionsExClassName?: string;
108
- exceededSidePosOffset?: number;
109
- multiSelect?: MultiSelectConfig;
110
- multiSelectEntireAreaTrigger?: boolean;
111
- multiSelectSelectedItemOnlyStatus?: multiSelectSelectedItemOnlyStatusConfig;
112
- renderSelectedValue?: (selectedData: MultiSelectControlValConfig, removeFunc: (e: React.MouseEvent) => void) => void;
113
- cleanTrigger?: CleanTriggerConfig;
114
- defaultValue?: string | OptionConfig;
115
- value?: string | OptionConfig;
116
- label?: React.ReactNode | string;
117
- name?: string;
118
- disabled?: any;
119
- required?: any;
120
- readOnly?: any;
121
- placeholder?: string;
122
- options?: OptionConfig[] | string;
123
- lockBodyScroll?: boolean;
124
- hierarchical?: boolean;
125
- indentation?: string;
126
- doubleIndent?: boolean;
127
- winWidth?: string | Function;
128
- controlArrow?: React.ReactNode;
129
- firstRequestAutoExec?: boolean;
130
- fetchTrigger?: boolean;
131
- fetchTriggerForDefaultData?: MultiSelectDataConfig | null;
132
- /** Set the depth value of the control to control the display of the pop-up layer appear above.
133
- * Please set it when multiple controls are used at the same time. */
134
- depth?: number;
135
- /** Incoming data, you can set the third parameter of `onFetch` */
136
- data?: any;
137
- /** Whether to use square brackets to save result and initialize default value */
138
- extractValueByBrackets?: boolean;
139
- /** -- */
140
- id?: string;
141
- autoComplete?: string;
142
- autoCapitalize?: string;
143
- spellCheck?: boolean;
144
- style?: React.CSSProperties;
145
- tabIndex?: number;
146
- [key: `data-${string}`]: string | undefined;
147
- fetchNoneInfo?: string;
148
- fetchUpdate?: boolean;
149
- fetchFuncAsync?: any;
150
- fetchFuncMethod?: string;
151
- fetchFuncMethodParams?: any[];
152
- fetchCallback?: (data: any) => void;
153
- onFetch?: (e: any, e2: any, value: string, data: any, incomingData: string | null | undefined) => void;
154
- onLoad?: (e: any, e2: any, value: string | null | undefined) => void;
155
- onSelect?: (data: any) => void;
156
- onChange?: SelectOptionChangeFnType | null;
157
- onBlur?: (e: any) => void;
158
- onFocus?: (e: any) => void;
159
- onKeyPressed?: (arg1: any, arg2: any, arg3: any) => void;
160
- };
161
-
162
-
163
- const Select = forwardRef((props: SelectProps, externalRef: any) => {
164
- const {
165
- contentRef,
166
- popupRef,
167
- wrapperClassName,
168
- controlClassName,
169
- controlExClassName,
170
- optionsExClassName,
171
- exceededSidePosOffset,
172
- multiSelect,
173
- multiSelectEntireAreaTrigger,
174
- multiSelectSelectedItemOnlyStatus,
175
- renderSelectedValue,
176
- disabled,
177
- required,
178
- defaultValue,
179
- value,
180
- label,
181
- name,
182
- readOnly,
183
- placeholder,
184
- id,
185
- autoComplete,
186
- autoCapitalize,
187
- spellCheck,
188
- options,
189
- cleanTrigger,
190
- lockBodyScroll,
191
- hierarchical,
192
- indentation,
193
- doubleIndent,
194
- style,
195
- depth,
196
- controlArrow,
197
- winWidth,
198
- tabIndex,
199
- firstRequestAutoExec,
200
- fetchTrigger,
201
- fetchTriggerForDefaultData,
202
- fetchNoneInfo,
203
- fetchUpdate,
204
- fetchFuncAsync,
205
- fetchFuncMethod,
206
- fetchFuncMethodParams,
207
- data,
208
- extractValueByBrackets,
209
- fetchCallback,
210
- onFetch,
211
- onLoad,
212
- onSelect,
213
- onChange,
214
- onBlur,
215
- onFocus,
216
- onKeyPressed,
217
- ...attributes
218
- } = props;
219
-
220
-
221
- const DEPTH = depth || 1055; // the default value same as bootstrap
222
- const MANUAL_REQ = typeof fetchTrigger !== 'undefined' && fetchTrigger === true ? true : false; // Manual requests
223
- const LIVE_SEARCH_DISABLED = !MANUAL_REQ && typeof window !== 'undefined' && typeof (window as any)['funda-ui__Select-disable-livesearch'] !== 'undefined' ? true : false; // Globally disable real-time search functionality (only valid for non-dynamic requests)
224
-
225
-
226
- const FIRST_REQUEST_AUTO = typeof firstRequestAutoExec === 'undefined' ? true : firstRequestAutoExec;
227
- const INPUT_READONLY = LIVE_SEARCH_DISABLED ? true : (typeof readOnly === 'undefined' ? null : readOnly);
228
- const VALUE_BY_BRACKETS = typeof extractValueByBrackets === 'undefined' ? true : extractValueByBrackets;
229
- const LOCK_BODY_SCROLL = typeof lockBodyScroll === 'undefined' ? false : lockBodyScroll;
230
- const WIN_WIDTH = typeof winWidth === 'function' ? winWidth() : winWidth ? winWidth : 'auto';
231
- const INDENT_PLACEHOLDER = doubleIndent ? `&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;` : `&nbsp;&nbsp;&nbsp;&nbsp;`;
232
- const INDENT_LAST_PLACEHOLDER = `${typeof indentation !== 'undefined' && indentation !== '' ? `${indentation}&nbsp;&nbsp;` : ''}`;
233
- const POS_OFFSET = 0;
234
- const EXCEEDED_SIDE_POS_OFFSET = Number(exceededSidePosOffset) || 15;
235
- const uniqueID = useComId();
236
- const idRes = id || uniqueID;
237
- const rootRef = useRef<any>(null);
238
- const rootMultiRef = useRef<any>(null);
239
- const selectInputRef = useRef<any>(null);
240
- const valueInputRef = useRef<any>(null);
241
- const listRef = useRef<any>(null);
242
- const listContentRef = useRef<any>(null);
243
- const optionsRes = options ? (isJSON(options) ? JSON.parse(options as string) : options) : [];
244
- const LIST_CONTAINER_MAX_HEIGHT = 350;
245
-
246
- const keyboardSelectedItem = useRef<any>(null);
247
-
248
-
249
- // return a array of options
250
- let staticOptionsData: OptionConfig[] = optionsRes;
251
-
252
- //
253
- const [orginalData, setOrginalData] = useState<OptionConfig[]>(staticOptionsData);
254
- const [optionsData, setOptionsData] = useState<OptionConfig[]>(staticOptionsData);
255
- const [hasErr, setHasErr] = useState<boolean>(false);
256
- const [controlLabel, setControlLabel] = useState<string | undefined>('');
257
- const [controlValue, setControlValue] = useState<string | undefined>('');
258
- const [controlTempValue, setControlTempValue] = useState<string | null>(null);
259
- const [isOpen, setIsOpen] = useState<boolean>(false);
260
- const [incomingData, setIncomingData] = useState<string | null | undefined>(null);
261
- const [firstRequestExecuted, setFirstRequestExecuted] = useState<boolean>(false);
262
-
263
-
264
- // blinking cursor
265
- const BLINKING_CURSOR_STR = '|';
266
- const [blinkingPosStart, setBlinkingPosStart] = useState<number>(0);
267
- const blinkingPosFauxRef = useRef<any>(null);
268
- const blinkingCursorPosDivRef = useRef<any>(null);
269
-
270
-
271
-
272
- const selectedSign = useRef<boolean>(false);
273
- const MULTI_SEL_VALID = multiSelect ? multiSelect.valid : false;
274
- const MULTI_SEL_ENTIRE_AREA_TRIGGER = typeof multiSelectEntireAreaTrigger === 'undefined' ? true : multiSelectEntireAreaTrigger;
275
- const MULTI_SEL_LABEL = multiSelect ? multiSelect.selectAllLabel : 'Select all';
276
- const MULTI_DESEL_LABEL = multiSelect ? multiSelect.deselectAllLabel : 'Deselect all';
277
- const MULTI_SEL_SELECTED_STATUS: Record<string, string> = {
278
- itemsLabel: '{num} Selected',
279
- allItemsLabel: 'All Content ({num})',
280
- noneLabel: 'No items selected',
281
- };
282
-
283
- const [controlArr, setControlArr] = useState<MultiSelectControlValConfig>({
284
- labels: [],
285
- values: []
286
- });
287
-
288
- const listContainerHeightLimit = (num: number) => {
289
- let res = num;
290
- if (res > LIST_CONTAINER_MAX_HEIGHT) res = LIST_CONTAINER_MAX_HEIGHT;
291
-
292
- // Avoid the height of the child div containing decimal points and scrollbars
293
- res = res + 1;
294
-
295
- return res;
296
- };
297
-
298
- const multiSelControlOptionExist = (arr: any[], val: any) => {
299
- const _data = arr.filter(Boolean);
300
- return _data.map((v: any) => v.toString()).includes(val.toString());
301
- };
302
-
303
- // clean trigger
304
- const CLEAN_TRIGGER_VALID = typeof cleanTrigger === 'undefined' ? false : (cleanTrigger ? cleanTrigger.valid : false);
305
- const CLEAN_TRIGGER_LABEL = cleanTrigger ? cleanTrigger.cleanValueLabel : 'Clean';
306
-
307
-
308
- const optionsFormatGroupOpt = (allData: any[]) => {
309
- allData.forEach((item: any) => {
310
- if (typeof item.optgroup !== 'undefined') {
311
- item.value = String(Math.random());
312
- }
313
- });
314
- };
315
-
316
- const finalRes = (val: any) => {
317
- return isObject(val) ? val.value : val;
318
- };
319
-
320
- // exposes the following methods
321
- useImperativeHandle(
322
- popupRef,
323
- () => ({
324
- close: () => {
325
- cancel();
326
-
327
- if (MULTI_SEL_VALID) popwinPosHide();
328
- },
329
- open: () => {
330
- activate();
331
- },
332
-
333
- }),
334
- [popupRef],
335
- );
336
-
337
- useImperativeHandle(
338
- contentRef,
339
- () => ({
340
- active: () => {
341
- handleShowList();
342
- selectInputRef.current.select();
343
- },
344
-
345
- focus: () => {
346
- selectInputRef.current.select();
347
- },
348
- clear: (cb?: any) => {
349
-
350
- if (MULTI_SEL_VALID) {
351
- updateOptionCheckboxes('remove');
352
- } else {
353
- handleCleanValue();
354
- }
355
-
356
- selectInputRef.current.blur();
357
-
358
- cb?.();
359
- },
360
- /*
361
- set([{"label": "Option 1","listItemLabel":"Option 1 (No: 001)","value": "value-1","queryString": "option1"}], () => { console.log('callback') }])
362
- */
363
- set: (value: any, cb?: any) => {
364
-
365
- if (MULTI_SEL_VALID) {
366
- updateOptionCheckboxesViaAddSingleItem({
367
- labels: value.map((v: any) => v.label),
368
- values: value.map((v: any) => v.value)
369
- });
370
- } else {
371
- const _val = value[0];
372
- handleSelect(null, (typeof _val === 'object' ? JSON.stringify(_val) : _val), [`${_val.value}`], [`${_val.label}`]);
373
- }
374
-
375
-
376
- cb?.();
377
- }
378
- }),
379
- [contentRef],
380
- );
381
-
382
-
383
-
384
- // click outside
385
- useClickOutside({
386
- enabled: isOpen && rootRef.current && listRef.current,
387
- isOutside: (event: any) => {
388
-
389
- // close dropdown when other dropdown is opened
390
- return (
391
- (rootRef.current !== event.target && !rootRef.current.contains(event.target as HTMLElement)) &&
392
- listRef.current !== event.target && !listRef.current.contains(event.target as HTMLElement)
393
- )
394
-
395
- },
396
- handle: (event: any) => {
397
- // cancel
398
- cancel();
399
- if (MULTI_SEL_VALID) popwinPosHide();
400
- }
401
- }, [isOpen, rootRef, listRef]);
402
-
403
-
404
-
405
- // Add function to the element that should be used as the scrollable area.
406
- const [scrollData, windowScrollUpdate] = useWindowScroll({
407
- performance: ['debounce', 500], // "['debounce', 500]" or "['throttle', 500]"
408
- handle: (scrollData: any) => {
409
- // remove data-* attibutes
410
- popwinContainerHeightReset();
411
- }
412
- });
413
-
414
-
415
- // value of multiple selection callback
416
- const multipleSelectionCallback = (valuesRes: any[], labelsRes: any[]) => {
417
- return {
418
- items: valuesRes.map((v: any, i: number) => (
419
- {label: labelsRes[i].toString(), value: v.toString()}
420
- )),
421
- labels: labelsRes.map((v: any) => v.toString()),
422
- values: valuesRes.map((v: any) => v.toString()),
423
- labelsOfString: VALUE_BY_BRACKETS ? convertArrToValByBrackets(labelsRes.map((v: any) => v.toString())) : labelsRes.map((v: any) => v.toString()).join(','),
424
- valuesOfString: VALUE_BY_BRACKETS ? convertArrToValByBrackets(valuesRes.map((v: any) => v.toString())) : valuesRes.map((v: any) => v.toString()).join(',')
425
- };
426
- };
427
-
428
-
429
- //performance
430
- const handleChangeFetchSafe = useDebounce((val: any) => {
431
-
432
- let _orginalData: OptionConfig[] = [];
433
- const update = (inputData: any) => {
434
- const filterRes = () => {
435
-
436
- return inputData.filter((item: any) => {
437
-
438
- // Avoid fatal errors causing page crashes
439
- const _queryString = typeof item.queryString !== 'undefined' && item.queryString !== null ? item.queryString : '';
440
- const _val = typeof val !== 'undefined' && val !== null ? val : '';
441
-
442
- if (
443
- (
444
- _queryString.split(',').some((l: any) => l.charAt(0) === _val.toLowerCase()) ||
445
- _queryString.split(',').some((l: any) => l.replace(/ /g, '').indexOf(_val.toLowerCase()) >= 0) ||
446
- item.label.toLowerCase().indexOf(_val.toLowerCase()) >= 0
447
- ) &&
448
- _val != ''
449
- ) {
450
- return true;
451
- } else {
452
- return false;
453
- }
454
- });
455
- }
456
-
457
- return filterRes();
458
- };
459
-
460
- if (fetchUpdate) {
461
-
462
- handleFetch(val).then((response: any) => {
463
- _orginalData = response;
464
- const _filterRes = update(_orginalData);
465
-
466
- // pop win initalization
467
- setTimeout(() => {
468
- popwinPosInit();
469
- popwinFilterItems(val);
470
- }, 0);
471
- });
472
- } else {
473
- _orginalData = orginalData;
474
- const _filterRes = update(_orginalData);
475
-
476
- // pop win initalization
477
- setTimeout(() => {
478
- popwinPosInit();
479
- popwinFilterItems(val);
480
- }, 0);
481
-
482
- }
483
-
484
-
485
- }, 350, [optionsData]);
486
-
487
-
488
-
489
- async function fetchData(params: any, valueToInputDefault: any, inputDefault: any, init: boolean = true) {
490
-
491
- // get incoming options from `data-options` of component
492
- // It is usually used for complex cascading `<Select />` components
493
- const incomingOptionsData = valueInputRef.current.dataset.options;
494
-
495
-
496
- // Determine whether the default value is user query input or default input
497
- const defaultValue = init ? valueToInputDefault : '';
498
-
499
-
500
- if (typeof fetchFuncAsync === 'object') {
501
-
502
-
503
- const response: any = await fetchFuncAsync[`${fetchFuncMethod}`](...params.split(','));
504
- let _ORGIN_DATA = response.data;
505
-
506
-
507
- // reset data structure
508
- if (typeof (fetchCallback) === 'function') {
509
- _ORGIN_DATA = fetchCallback(_ORGIN_DATA);
510
- }
511
-
512
- // Determine whether the data structure matches
513
- if (_ORGIN_DATA.length > 0 && typeof _ORGIN_DATA[0].value === 'undefined') {
514
- console.warn('The data structure does not match, please refer to the example in the component documentation.');
515
- setHasErr(true);
516
- _ORGIN_DATA = [];
517
- }
518
-
519
-
520
- // STEP 1: ===========
521
- // get incoming options from `data-options` of component
522
- if (typeof incomingOptionsData !== 'undefined') {
523
- _ORGIN_DATA = JSON.parse(incomingOptionsData);
524
-
525
- // set value if the attribute `data-options` of component exists, only valid for single selection (it may be an empty array)
526
- if (typeof defaultValue !== 'undefined' && defaultValue !== '') valueInputRef.current.dataset.value = defaultValue;
527
- }
528
-
529
-
530
- // STEP 2: ===========
531
- // Set hierarchical categories ( with sub-categories )
532
- if (hierarchical) {
533
- _ORGIN_DATA = addTreeDepth(_ORGIN_DATA);
534
- addTreeIndent(_ORGIN_DATA, INDENT_PLACEHOLDER, INDENT_LAST_PLACEHOLDER, 'label');
535
- }
536
-
537
-
538
- // STEP 3: ===========
539
- // Flatten the group
540
- _ORGIN_DATA = optionsCustomSelectFlat(_ORGIN_DATA);
541
-
542
-
543
-
544
-
545
- // STEP 4: ===========
546
- // value & label must be initialized
547
- let filterRes: any = [];
548
-
549
-
550
- if (MANUAL_REQ) {
551
-
552
- // If a manual action is used to trigger the request
553
- if (typeof fetchTriggerForDefaultData !== 'undefined' && fetchTriggerForDefaultData !== null && typeof fetchTriggerForDefaultData?.values[0] !== 'undefined') {
554
- filterRes = [{
555
- value: fetchTriggerForDefaultData?.values[0],
556
- label: fetchTriggerForDefaultData?.labels[0],
557
- queryString: fetchTriggerForDefaultData?.queryStrings[0]
558
- }];
559
- }
560
-
561
- } else {
562
-
563
- // If the default value is label, match value
564
- const filterResQueryValue = _ORGIN_DATA.filter((item: any) => item.value == defaultValue);
565
- const filterResQueryLabel = _ORGIN_DATA.filter((item: any) => item.label == defaultValue);
566
-
567
- filterRes = filterResQueryValue;
568
- if (filterResQueryValue.length === 0) filterRes = filterResQueryLabel;
569
-
570
- // if the default value is Object
571
- if (isObject(inputDefault) && filterRes.length === 0) {
572
- filterRes = [inputDefault];
573
- }
574
-
575
- }
576
-
577
-
578
-
579
- // STEP 5: ===========
580
- // ++++++++++++++++++++
581
- // Single selection
582
- // ++++++++++++++++++++
583
- if (typeof defaultValue === 'undefined' || defaultValue === '') { // Do not use `init`, otherwise the query will revert to the default value if there is no value
584
- setControlValue('');
585
- setControlLabel('');
586
- } else {
587
- if (filterRes.length > 0) {
588
- setControlValue(filterRes[0].value);
589
- setControlLabel(formatIndentVal(filterRes[0].label, INDENT_LAST_PLACEHOLDER) as string);
590
- }
591
-
592
- }
593
-
594
-
595
- // ++++++++++++++++++++
596
- // Multiple selection
597
- // ++++++++++++++++++++
598
- if (MULTI_SEL_VALID) {
599
-
600
-
601
- if ((typeof defaultValue === 'undefined' || defaultValue === '') && init) {
602
- setControlArr({
603
- labels: [],
604
- values: []
605
- });
606
- }
607
-
608
-
609
-
610
- if (typeof defaultValue !== 'undefined' && defaultValue !== '' && multiSelect?.data !== null) {
611
-
612
- // initialize default values of Multiple selection
613
- const _currentData: any = multiSelect?.data;
614
-
615
- setControlArr({
616
- labels: _currentData.labels,
617
- values: _currentData.values,
618
- });
619
-
620
- //
621
- const _values: string[] = VALUE_BY_BRACKETS ? extractContentsOfBrackets(defaultValue) : defaultValue.split(',');
622
-
623
-
624
- _values.forEach((_value: string, _index: number) => {
625
-
626
- if (!multiSelControlOptionExist(_currentData.values, _value) && typeof _currentData.values[_index] !== 'undefined') {
627
-
628
- let filterRes: any = [];
629
- filterRes = [{
630
- value: _currentData.values[_index],
631
- label: _currentData.labels[_index],
632
- queryString: _currentData.queryStrings[_index]
633
- }];
634
-
635
- setControlArr((prevState: any) => {
636
- return {
637
- labels: unique([...prevState.labels, typeof filterRes[0] !== 'undefined' ? filterRes[0].label : ''].filter((v: any) => v !== '')),
638
- values: unique([...prevState.values, typeof filterRes[0] !== 'undefined' ? filterRes[0].value : ''].filter((v: any) => v !== ''))
639
- }
640
- });
641
-
642
- }
643
-
644
- });
645
-
646
-
647
- }
648
-
649
- // Appropriate multi-item container height
650
- setTimeout(() => {
651
- adjustMultiControlContainerHeight();
652
- }, 0);
653
-
654
-
655
- // hide disabled item
656
- _ORGIN_DATA = _ORGIN_DATA.filter((v: any) => typeof v.disabled !== 'undefined' && v.disabled == true ? false : true);
657
-
658
- }
659
-
660
- // STEP 6: ===========
661
- //
662
- // remove Duplicate objects from JSON Array
663
- optionsFormatGroupOpt(_ORGIN_DATA); // prevent the value from being filtered out
664
- _ORGIN_DATA = removeArrDuplicateItems(_ORGIN_DATA, 'value');
665
-
666
- setOptionsData(_ORGIN_DATA); // data must be initialized
667
-
668
- //
669
- setOrginalData(_ORGIN_DATA);
670
-
671
-
672
- // STEP 7: ===========
673
- //
674
- onFetch?.(selectInputRef.current, valueInputRef.current, defaultValue, _ORGIN_DATA, incomingData);
675
-
676
-
677
-
678
- //
679
- return _ORGIN_DATA;
680
-
681
-
682
- } else {
683
-
684
-
685
- // STEP 1: ===========
686
- // get incoming options from `data-options` of component
687
- if (typeof incomingOptionsData !== 'undefined') {
688
- staticOptionsData = JSON.parse(incomingOptionsData);
689
-
690
- // set value if the attribute `data-options` of component exists, only valid for single selection (it may be an empty array)
691
- if (typeof defaultValue !== 'undefined' && defaultValue !== '') valueInputRef.current.dataset.value = defaultValue;
692
-
693
- }
694
-
695
-
696
- // STEP 2: ===========
697
- // Set hierarchical categories ( with sub-categories )
698
- if (hierarchical) {
699
- staticOptionsData = addTreeDepth(staticOptionsData);
700
- addTreeIndent(staticOptionsData, INDENT_PLACEHOLDER, INDENT_LAST_PLACEHOLDER, 'label');
701
- }
702
-
703
-
704
- // STEP 3: ===========
705
- // Flatten the group
706
- staticOptionsData = optionsCustomSelectFlat(staticOptionsData);
707
-
708
-
709
- // STEP 4: ===========
710
- // value & label must be initialized
711
-
712
- // If the default value is label, match value
713
- let filterRes: any = [];
714
- const filterResQueryValue = staticOptionsData.filter((item: any) => item.value == defaultValue);
715
- const filterResQueryLabel = staticOptionsData.filter((item: any) => item.label == defaultValue);
716
-
717
- filterRes = filterResQueryValue;
718
- if (filterResQueryValue.length === 0) filterRes = filterResQueryLabel;
719
-
720
-
721
- // if the default value is Object
722
- if (isObject(inputDefault) && filterRes.length === 0) {
723
- filterRes = [inputDefault];
724
- }
725
-
726
-
727
-
728
- // STEP 5: ===========
729
- // ++++++++++++++++++++
730
- // Single selection
731
- // ++++++++++++++++++++
732
- if (typeof defaultValue === 'undefined' || defaultValue === '') { // Do not use `init`, otherwise the query will revert to the default value if there is no value
733
- setControlValue('');
734
- setControlLabel('');
735
- } else {
736
- if (filterRes.length > 0) {
737
- setControlValue(filterRes[0].value);
738
- setControlLabel(formatIndentVal(filterRes[0].label, INDENT_LAST_PLACEHOLDER));
739
- }
740
-
741
- }
742
-
743
-
744
-
745
- // ++++++++++++++++++++
746
- // Multiple selection
747
- // ++++++++++++++++++++
748
- if (MULTI_SEL_VALID) {
749
-
750
-
751
- if ((typeof defaultValue === 'undefined' || defaultValue === '') && init) {
752
- setControlArr({
753
- labels: [],
754
- values: []
755
- });
756
- }
757
-
758
- if (typeof defaultValue !== 'undefined' && defaultValue !== '' && multiSelect?.data !== null) {
759
-
760
- // initialize default values of Multiple selection
761
- const _currentData: any = multiSelect?.data;
762
-
763
- setControlArr({
764
- labels: _currentData.labels,
765
- values: _currentData.values,
766
- });
767
-
768
- //
769
- const _values: string[] = typeof defaultValue !== 'undefined' ? (VALUE_BY_BRACKETS ? extractContentsOfBrackets(defaultValue) : defaultValue.split(',')) : [];
770
- _values.forEach((_value: string, _index: number) => {
771
-
772
- if (!multiSelControlOptionExist(_currentData.values, _value) && typeof _currentData.values[_index] !== 'undefined') {
773
-
774
-
775
- let filterRes: any = [];
776
- filterRes = [{
777
- value: _currentData.values[_index],
778
- label: _currentData.labels[_index],
779
- queryString: _currentData.queryStrings[_index]
780
- }];
781
-
782
- setControlArr((prevState: any) => {
783
- return {
784
- labels: unique([...prevState.labels, typeof filterRes[0] !== 'undefined' ? filterRes[0].label : ''].filter((v: any) => v !== '')),
785
- values: unique([...prevState.values, typeof filterRes[0] !== 'undefined' ? filterRes[0].value : ''].filter((v: any) => v !== ''))
786
- }
787
- });
788
-
789
-
790
- }
791
- });
792
- }
793
-
794
- // Appropriate multi-item container height
795
- setTimeout(() => {
796
- adjustMultiControlContainerHeight();
797
- }, 0);
798
-
799
-
800
- // hide disabled item
801
- staticOptionsData = staticOptionsData.filter((v: any) => typeof v.disabled !== 'undefined' && v.disabled == true ? false : true);
802
-
803
- }
804
-
805
- // STEP 6: ===========
806
- //
807
- // remove Duplicate objects from JSON Array
808
- optionsFormatGroupOpt(staticOptionsData); // prevent the value from being filtered out
809
- staticOptionsData = removeArrDuplicateItems(staticOptionsData, 'value');
810
-
811
-
812
- setOptionsData(staticOptionsData); // data must be initialized
813
-
814
- //
815
- setOrginalData(staticOptionsData);
816
-
817
- // STEP 7: ===========
818
- //
819
- onFetch?.(selectInputRef.current, valueInputRef.current, defaultValue, staticOptionsData, incomingData);
820
-
821
-
822
- //
823
- return staticOptionsData;
824
- }
825
-
826
-
827
- }
828
-
829
-
830
- function adjustMultiControlContainerHeight(scrollbarInit: boolean = true) {
831
- setTimeout(() => {
832
-
833
-
834
- // Sometimes you may get 0, you need to judge
835
- if (MULTI_SEL_VALID && rootMultiRef.current.clientHeight > 0) {
836
- rootRef.current.style.height = rootMultiRef.current.clientHeight + 'px';
837
- }
838
-
839
- // popwin position update
840
- const _modalRef: any = document.querySelector(`#custom-select__options-wrapper-${idRes}`);
841
- if (MULTI_SEL_VALID && _modalRef !== null && _modalRef.classList.contains('active')) {
842
- popwinPosInit(scrollbarInit);
843
- }
844
-
845
-
846
- }, 0);
847
- }
848
-
849
-
850
- function syncListContentScrollBody() {
851
- const el: any = listContentRef.current;
852
- if (el === null) return;
853
-
854
- const activedItem = el.querySelectorAll(`.list-group-item.${!MULTI_SEL_VALID ? 'active' : 'item-selected'}`)[0];
855
- if (typeof activedItem !== 'undefined') {
856
-
857
- const cleanItem = el.querySelector(`.list-group-item.${!MULTI_SEL_VALID ? 'custom-select-multi__control-option-item--clean' : 'custom-select-multi__control-option-item--select-all'}`);
858
- const cleanItemHeight = cleanItem === null ? 0 : cleanItem.clientHeight;
859
- const _latestScrollTop = activedItem.offsetTop - cleanItemHeight;
860
-
861
- el.scrollTop = _latestScrollTop;
862
- }
863
-
864
- }
865
-
866
-
867
- function popwinPosInit(scrollbarInit: boolean = true) {
868
- if (listContentRef.current === null || rootRef.current === null || selectInputRef.current === null) return;
869
-
870
- const contentHeightOffset = 80;
871
- let contentMaxHeight = 0;
872
-
873
- // update modal position
874
- const _modalRef: any = document.querySelector(`#custom-select__options-wrapper-${idRes}`);
875
- const _triggerRef: any = selectInputRef.current;
876
- const _triggerXaxisRef: any = rootRef.current;
877
-
878
- // console.log(getAbsolutePositionOfStage(_triggerRef));
879
-
880
- if (_modalRef === null) return;
881
-
882
- const { x } = getAbsolutePositionOfStage(_triggerXaxisRef);
883
- const { y, width, height } = getAbsolutePositionOfStage(_triggerRef);
884
- const _triggerBox = _triggerRef.getBoundingClientRect();
885
- let targetPos = '';
886
-
887
-
888
-
889
- // STEP 1:
890
- //-----------
891
- // display wrapper
892
- _modalRef.classList.add('active');
893
-
894
-
895
-
896
-
897
- // STEP 2:
898
- //-----------
899
- // Detect content MAX HEIGHT and ACTUAL HEIGHT
900
- const _contentBox = listContentRef.current.getBoundingClientRect();
901
- let _contentOldHeight = listContentRef.current.clientHeight;
902
-
903
- // height restrictions
904
- _contentOldHeight = listContainerHeightLimit(_contentOldHeight);
905
-
906
- // You need to wait for the height of the pop-up container to be set
907
- // Detect position、
908
- if (window.innerHeight - _triggerBox.top > _contentOldHeight) {
909
- targetPos = 'bottom';
910
- } else {
911
- targetPos = 'top';
912
- }
913
-
914
- if (typeof listContentRef.current.dataset.pos === 'undefined') listContentRef.current.dataset.pos = targetPos;
915
-
916
-
917
-
918
- // STEP 3:
919
- //-----------
920
- // Set the pop-up height
921
- if (targetPos === 'top') {
922
- contentMaxHeight = _triggerBox.top;
923
-
924
- // height restrictions
925
- contentMaxHeight = listContainerHeightLimit(contentMaxHeight);
926
-
927
-
928
- if (_contentBox.height > contentMaxHeight) {
929
- listContentRef.current.style.height = contentMaxHeight - contentHeightOffset + 'px';
930
- if (typeof listContentRef.current.dataset.height === 'undefined') listContentRef.current.dataset.height = contentMaxHeight - contentHeightOffset;
931
-
932
- // has scrollbar
933
- listContentRef.current.dataset.hasScrollbar = 'true';
934
-
935
-
936
- } else {
937
- if (_contentOldHeight > 50) {
938
- listContentRef.current.style.height = _contentOldHeight + 'px';
939
- if (typeof listContentRef.current.dataset.height === 'undefined') listContentRef.current.dataset.height = _contentOldHeight;
940
- }
941
-
942
- // has scrollbar
943
- listContentRef.current.dataset.hasScrollbar = 'false';
944
-
945
- }
946
- }
947
-
948
- if (targetPos === 'bottom') {
949
- contentMaxHeight = window.innerHeight - _triggerBox.bottom;
950
-
951
-
952
- // height restrictions
953
- contentMaxHeight = listContainerHeightLimit(contentMaxHeight);
954
-
955
-
956
- if (_contentBox.height > contentMaxHeight) {
957
- listContentRef.current.style.height = contentMaxHeight - 10 + 'px';
958
- if (typeof listContentRef.current.dataset.height === 'undefined') listContentRef.current.dataset.height = contentMaxHeight - 10;
959
-
960
- // has scrollbar
961
- listContentRef.current.dataset.hasScrollbar = 'true';
962
-
963
- } else {
964
- if (_contentOldHeight > 50) {
965
- listContentRef.current.style.height = _contentOldHeight + 'px';
966
- if (typeof listContentRef.current.dataset.height === 'undefined') listContentRef.current.dataset.height = _contentOldHeight;
967
- }
968
-
969
- // has scrollbar
970
- listContentRef.current.dataset.hasScrollbar = 'false';
971
-
972
- }
973
-
974
- }
975
-
976
-
977
-
978
-
979
-
980
- // STEP 4:
981
- //-----------
982
- // Adjust position
983
- if (targetPos === 'top') {
984
- _modalRef.style.left = x + 'px';
985
- //_modalRef.style.top = y - POS_OFFSET - (listContentRef.current.clientHeight) - 2 + 'px';
986
- _modalRef.style.top = 'auto';
987
- _modalRef.style.bottom = (window.innerHeight - _triggerBox.top) + POS_OFFSET + 2 + 'px';
988
- _modalRef.style.setProperty('position', 'fixed', 'important');
989
- _modalRef.classList.add('pos-top');
990
- }
991
-
992
- if (targetPos === 'bottom') {
993
- _modalRef.style.left = x + 'px';
994
- _modalRef.style.bottom = 'auto';
995
- _modalRef.style.top = y + height + POS_OFFSET + 'px';
996
- _modalRef.style.setProperty('position', 'absolute', 'important');
997
- _modalRef.classList.remove('pos-top');
998
- }
999
-
1000
-
1001
-
1002
- // STEP 5:
1003
- //-----------
1004
- // Determine whether it exceeds the far right or left side of the screen
1005
- const _modalContent = _modalRef;
1006
- const _modalBox = _modalContent.getBoundingClientRect();
1007
- if (typeof _modalContent.dataset.offset === 'undefined' && _modalBox.left > 0) {
1008
-
1009
- // 10 pixels is used to account for some bias in mobile devices
1010
- if ((_modalBox.right + 10) > window.innerWidth) {
1011
- const _modalOffsetPosition = _modalBox.right - window.innerWidth + EXCEEDED_SIDE_POS_OFFSET;
1012
- _modalContent.dataset.offset = _modalOffsetPosition;
1013
- _modalContent.style.marginLeft = `-${_modalOffsetPosition}px`;
1014
- // console.log('_modalPosition: ', _modalOffsetPosition)
1015
- }
1016
-
1017
-
1018
- if ((_modalBox.left - 10) < 0) {
1019
- const _modalOffsetPosition = Math.abs(_modalBox.left) + EXCEEDED_SIDE_POS_OFFSET;
1020
- _modalContent.dataset.offset = _modalOffsetPosition;
1021
- _modalContent.style.marginLeft = `${_modalOffsetPosition}px`;
1022
- // console.log('_modalPosition: ', _modalOffsetPosition)
1023
- }
1024
-
1025
-
1026
- }
1027
-
1028
-
1029
-
1030
-
1031
- // STEP 6:
1032
- //-----------
1033
- // no data label
1034
- popwinNoMatchInit();
1035
-
1036
-
1037
-
1038
- // STEP 7:
1039
- //-----------
1040
- // Scrollbar position synchronization
1041
- if (scrollbarInit) syncListContentScrollBody();
1042
-
1043
-
1044
-
1045
- }
1046
-
1047
-
1048
- function popwinPosHide() {
1049
-
1050
- const _modalRef: any = document.querySelector(`#custom-select__options-wrapper-${idRes}`);
1051
-
1052
- if (_modalRef !== null && listContentRef.current !== null) {
1053
-
1054
-
1055
- // remove classnames and styles
1056
- _modalRef.classList.remove('active');
1057
- listContentRef.current.style.removeProperty('height');
1058
-
1059
- // remove data-* attibutes
1060
- popwinContainerHeightReset();
1061
-
1062
-
1063
- // display all filtered items
1064
- const _items = [].slice.call(listContentRef.current.querySelectorAll('.custom-select-multi__control-option-item'));
1065
- _items.forEach((node: any) => {
1066
- node.classList.remove('hide');
1067
- });
1068
-
1069
-
1070
- // nomatch & button of select all
1071
- const _nodataDiv = listContentRef.current.querySelector('.custom-select-multi__control-option-item--nomatch');
1072
- const _btnSelectAll = listContentRef.current.querySelector('.custom-select-multi__control-option-item--select-all');
1073
- _nodataDiv.classList.add('hide');
1074
- if (_btnSelectAll !== null) _btnSelectAll.classList.remove('hide');
1075
-
1076
-
1077
- }
1078
-
1079
-
1080
- }
1081
-
1082
-
1083
- function popwinFilterItems(val: any) {
1084
- if (listContentRef.current === null) return;
1085
-
1086
-
1087
- [].slice.call(listContentRef.current.querySelectorAll('.custom-select-multi__control-option-item')).forEach((node: any) => {
1088
-
1089
- // Avoid fatal errors causing page crashes
1090
- const _queryString = typeof node.dataset.querystring !== 'undefined' && node.dataset.querystring !== null ? node.dataset.querystring : '';
1091
- const _val = typeof val !== 'undefined' && val !== null ? val : '';
1092
-
1093
- if (
1094
- (
1095
- _queryString.split(',').some((l: any) => l.charAt(0) === _val.toLowerCase()) ||
1096
- _queryString.split(',').some((l: any) => l.replace(/ /g, '').indexOf(_val.toLowerCase()) >= 0) ||
1097
- node.dataset.label.toLowerCase().indexOf(_val.toLowerCase()) >= 0
1098
- ) &&
1099
- _val != ''
1100
- ) {
1101
- node.classList.remove('hide');
1102
- } else {
1103
- node.classList.add('hide');
1104
- }
1105
-
1106
- });
1107
-
1108
-
1109
- // no data label
1110
- popwinNoMatchInit();
1111
-
1112
-
1113
- // display all filtered items
1114
- const _btnSelectAll = listContentRef.current.querySelector('.custom-select-multi__control-option-item--select-all');
1115
- const _nodataDiv = listContentRef.current.querySelector('.custom-select-multi__control-option-item--nomatch');
1116
- if ((val === null ? '' : val).replace(/\s/g, "") === '') {
1117
- [].slice.call(listContentRef.current.querySelectorAll('.custom-select-multi__control-option-item')).forEach((node: any) => {
1118
- node.classList.remove('hide');
1119
- });
1120
- _nodataDiv.classList.add('hide');
1121
- if (_btnSelectAll !== null) _btnSelectAll.classList.remove('hide');
1122
- }
1123
-
1124
-
1125
- // Appropriate list container height
1126
- popwinContainerHeightAdjust();
1127
-
1128
-
1129
- }
1130
-
1131
- function popwinContainerHeightAdjust() {
1132
- if (listContentRef.current === null) return;
1133
-
1134
- let oldHeight = listContentRef.current.dataset.height;
1135
- const pos = listContentRef.current.dataset.pos;
1136
- let filteredHeight = listContentRef.current.firstChild.clientHeight;
1137
-
1138
- // height restrictions
1139
- oldHeight = listContainerHeightLimit(oldHeight);
1140
- filteredHeight = listContainerHeightLimit(filteredHeight);
1141
-
1142
-
1143
- if (parseFloat(oldHeight) > filteredHeight) {
1144
- listContentRef.current.style.height = filteredHeight + 'px';
1145
- } else {
1146
- listContentRef.current.style.height = oldHeight + 'px';
1147
- }
1148
-
1149
- }
1150
-
1151
-
1152
-
1153
-
1154
- function popwinNoMatchInit() {
1155
- if (listContentRef.current === null) return;
1156
-
1157
- const _btnSelectAll = listContentRef.current.querySelector('.custom-select-multi__control-option-item--select-all');
1158
- const _nodataDiv = listContentRef.current.querySelector('.custom-select-multi__control-option-item--nomatch');
1159
- const emptyFieldsCheck = [].slice.call(listContentRef.current.querySelectorAll('.custom-select-multi__control-option-item')).every((node: any) => {
1160
- if (!node.classList.contains('hide')) {
1161
- return false;
1162
- }
1163
- return true;
1164
- });
1165
-
1166
- if (emptyFieldsCheck) {
1167
- _nodataDiv.classList.remove('hide');
1168
- if (_btnSelectAll !== null) _btnSelectAll.classList.add('hide');
1169
- } else {
1170
- _nodataDiv.classList.add('hide');
1171
- if (_btnSelectAll !== null) _btnSelectAll.classList.remove('hide');
1172
- }
1173
-
1174
- }
1175
-
1176
-
1177
- function popwinContainerHeightReset() {
1178
- if (listContentRef.current === null) return;
1179
-
1180
- // remove data-* attibutes
1181
- listContentRef.current.removeAttribute('data-height');
1182
- listContentRef.current.removeAttribute('data-pos');
1183
-
1184
- //
1185
- if (selectInputRef.current) selectInputRef.current.value = '';
1186
-
1187
-
1188
- }
1189
-
1190
- function cancel() {
1191
- // hide list
1192
- setIsOpen(false);
1193
- if (!MULTI_SEL_VALID) popwinPosHide();
1194
-
1195
-
1196
- if (MANUAL_REQ) {
1197
- // clean data
1198
- setOptionsData([]);
1199
- } else {
1200
- // restore data
1201
- setOptionsData(orginalData);
1202
- }
1203
-
1204
- // update temporary value
1205
- setControlTempValue(null);
1206
-
1207
-
1208
- // Unlocks the page
1209
- if (LOCK_BODY_SCROLL) enableBodyScroll(document.querySelector('body'));
1210
- }
1211
-
1212
- function activate() {
1213
-
1214
- // trigger the first asynchronous request when the options area is expanded
1215
- if (!FIRST_REQUEST_AUTO && !firstRequestExecuted) {
1216
- let curValue: any = defaultValue;
1217
-
1218
- if (typeof curValue === 'undefined') {
1219
- curValue = value;
1220
- }
1221
-
1222
- handleFirstFetch(curValue).then((response: any) => {
1223
- if (response.length > 0) {
1224
- // nomatch
1225
- const _nodataDiv = listContentRef.current.querySelector('.custom-select-multi__control-option-item--nomatch');
1226
- _nodataDiv.classList.add('hide');
1227
- }
1228
- });
1229
-
1230
- //
1231
- setFirstRequestExecuted(true);
1232
- }
1233
-
1234
- // show list
1235
- setIsOpen(true);
1236
-
1237
- // pop win initalization
1238
- setTimeout(() => {
1239
- popwinPosInit();
1240
- }, 0);
1241
-
1242
- // make sure the event handler is registered
1243
- if (orginalData.length === 0) {
1244
- setTimeout(() => {
1245
- // no data label
1246
- popwinNoMatchInit();
1247
- }, 500);
1248
-
1249
- }
1250
-
1251
-
1252
- if (MANUAL_REQ) {
1253
- // clean data
1254
- setOptionsData([]);
1255
- } else {
1256
- // restore data
1257
- setOptionsData(orginalData);
1258
- }
1259
-
1260
-
1261
- // When you select multiple times, it automatically focuses on the search input box
1262
- if (MULTI_SEL_VALID) {
1263
- selectInputRef.current.select();
1264
- }
1265
-
1266
- // update temporary value
1267
- setControlTempValue('');
1268
-
1269
-
1270
- // Locks the page
1271
- //
1272
- // Get a target element that you want to persist scrolling for (such as a modal/lightbox/flyout/nav).
1273
- // Specifically, the target element is the one we would like to allow scroll on (NOT a parent of that element).
1274
- // This is also the element to apply the CSS '-webkit-overflow-scrolling: touch;' if desired.
1275
- if (LOCK_BODY_SCROLL) disableBodyScroll(document.querySelector('body'));
1276
-
1277
-
1278
- }
1279
-
1280
-
1281
- function fixFocusStatus() {
1282
- // When selecting multiple times, in order to avoid losing
1283
- if (MULTI_SEL_VALID) handleFocus(selectInputRef.current);
1284
- }
1285
-
1286
- async function handleSelect(el: any, dataInput: any = false, valueArr: any[] = [], labelArr: any[] = []) {
1287
-
1288
- if (typeof el === 'undefined') return;
1289
-
1290
-
1291
- const curItem: any = el === null ? (isObject(dataInput) ? dataInput : JSON.parse(dataInput)) : optionsData[Number(el.currentTarget.dataset.index)];
1292
-
1293
-
1294
- // get incoming options from `data-options` of component
1295
- // It is usually used for complex cascading `<Select />` components
1296
- const incominggetOptionsData = valueInputRef.current.dataset.options;
1297
-
1298
-
1299
- // get options
1300
- const options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide):not(.no-match)'));
1301
-
1302
-
1303
- // current control of some option
1304
- const curBtn: any = options.filter((node: HTMLElement) => node.dataset.itemdata == JSON.stringify(curItem))[0];
1305
-
1306
-
1307
- // Determine whether there is a callback
1308
- const noCallback = typeof curItem.callback === 'undefined';
1309
-
1310
- // ==========================================================================
1311
- // Whether to cancel or not
1312
- // ==========================================================================
1313
- if (noCallback) {
1314
- // cancel
1315
- if (!MULTI_SEL_VALID) {
1316
- cancel();
1317
- }
1318
-
1319
- //remove focus style
1320
- if (!MULTI_SEL_VALID) {
1321
- rootRef.current?.classList.remove('focus');
1322
- }
1323
- }
1324
-
1325
-
1326
-
1327
- // update value * label
1328
- if (dataInput) {
1329
-
1330
- // ==========================================================================
1331
- // Use the "keyboard" to trigger
1332
- // ==========================================================================
1333
-
1334
- const _data = isObject(dataInput) ? dataInput : JSON.parse(dataInput);
1335
- const _value = _data.value;
1336
- const _label = _data.label;
1337
-
1338
- // ++++++++++++++++++++
1339
- // Callback
1340
- // ++++++++++++++++++++
1341
- _data.callback?.();
1342
-
1343
-
1344
- // ++++++++++++++++++++
1345
- // Single selection
1346
- // ++++++++++++++++++++
1347
- // clear all active classes of options
1348
- // (Avoid using the keyboard to select and two actives will appear after clicking on a non-selected option.)
1349
- if (noCallback) {
1350
- options.forEach((node: any) => {
1351
- node.classList.remove('active');
1352
- });
1353
- }
1354
-
1355
- // If there is a callback, delete the activated style
1356
- if (!noCallback) {
1357
- setTimeout(() => {
1358
- curBtn.classList.remove('active', 'disabled');
1359
- }, 0);
1360
- }
1361
-
1362
-
1363
-
1364
- //
1365
- setControlValue(_value);
1366
- setControlLabel(formatIndentVal(_label, INDENT_LAST_PLACEHOLDER));
1367
-
1368
-
1369
- // set value if the attribute `data-options` of component exists, only valid for single selection (it may be an empty array)
1370
- if (typeof incominggetOptionsData !== 'undefined') {
1371
- valueInputRef.current.dataset.value = _value;
1372
- }
1373
-
1374
-
1375
-
1376
- // ++++++++++++++++++++
1377
- // Multiple selection
1378
- // ++++++++++++++++++++
1379
- let currentControlValueArr: any[] = JSON.parse(JSON.stringify(valueArr));
1380
- let currentControlLabelArr: any[] = JSON.parse(JSON.stringify(labelArr));
1381
-
1382
- if (MULTI_SEL_VALID) {
1383
-
1384
- const $el = el === null ? curBtn : el.currentTarget;
1385
-
1386
-
1387
- // update option checkboxes
1388
- const _selected = $el.dataset.selected;
1389
- const _selectedVal = _selected == 'true' ? true : false;
1390
- if (_selectedVal) {
1391
- //#########
1392
- // remove item
1393
- //#########
1394
- $el.dataset.selected = 'false';
1395
- $el.querySelector('.custom-select-multi__control-option-checkbox-selected').classList.add('d-none');
1396
- $el.querySelector('.custom-select-multi__control-option-checkbox-placeholder').classList.remove('d-none');
1397
-
1398
- //
1399
- setControlArr((prevState: any) => {
1400
-
1401
- // update temporary value
1402
- setControlTempValue(prevState.labels.length >= 0 ? null : (VALUE_BY_BRACKETS ? convertArrToValByBrackets(prevState.labels) : prevState.labels.join(',')));
1403
-
1404
- return {
1405
- labels: removeItemOnce(prevState.labels, formatIndentVal(_label, INDENT_LAST_PLACEHOLDER)),
1406
- values: removeItemOnce(prevState.values, _value)
1407
- }
1408
- });
1409
-
1410
-
1411
- currentControlValueArr = removeItemOnce(currentControlValueArr, _value);
1412
- currentControlLabelArr = removeItemOnce(currentControlLabelArr, formatIndentVal(_label, INDENT_LAST_PLACEHOLDER));
1413
-
1414
-
1415
- } else {
1416
- //#########
1417
- // add item
1418
- //#########
1419
- $el.dataset.selected = 'true';
1420
- $el.querySelector('.custom-select-multi__control-option-checkbox-selected').classList.remove('d-none');
1421
- $el.querySelector('.custom-select-multi__control-option-checkbox-placeholder').classList.add('d-none');
1422
-
1423
- //
1424
- setControlArr((prevState: any) => {
1425
-
1426
- // update temporary value
1427
- setControlTempValue(prevState.labels.length >= 0 ? null : (VALUE_BY_BRACKETS ? convertArrToValByBrackets(prevState.labels) : prevState.labels.join(',')));
1428
-
1429
- return {
1430
- labels: [...prevState.labels, formatIndentVal(_label, INDENT_LAST_PLACEHOLDER)],
1431
- values: [...prevState.values, _value]
1432
- }
1433
- });
1434
-
1435
- currentControlValueArr.push(_value);
1436
- currentControlLabelArr.push(_label);
1437
-
1438
- }
1439
-
1440
- // Appropriate multi-item container height
1441
- // !!!set `false` to prevents the scrollbar position from changing when multi-selecting the option is clicked
1442
- adjustMultiControlContainerHeight(false);
1443
-
1444
-
1445
- // active current option
1446
- if (noCallback) {
1447
- setTimeout(() => {
1448
- $el.classList.add('active');
1449
- }, 0);
1450
-
1451
- }
1452
-
1453
-
1454
-
1455
- }
1456
-
1457
- //
1458
- if (noCallback && typeof (onChange) === 'function') {
1459
-
1460
- onChange?.(
1461
- selectInputRef.current,
1462
- valueInputRef.current,
1463
- !MULTI_SEL_VALID ? curItem : multipleSelectionCallback(currentControlValueArr, currentControlLabelArr)
1464
- );
1465
-
1466
-
1467
- //
1468
- selectInputRef.current.blur();
1469
- }
1470
-
1471
-
1472
-
1473
-
1474
- } else {
1475
-
1476
- // ==========================================================================
1477
- // Use the "mouse" to trigger
1478
- // ==========================================================================
1479
-
1480
- const _value = typeof curItem !== 'undefined' ? curItem.value : '';
1481
- const _label = typeof curItem !== 'undefined' ? curItem.label : '';
1482
-
1483
-
1484
-
1485
- // ++++++++++++++++++++
1486
- // Callback
1487
- // ++++++++++++++++++++
1488
- curItem.callback?.();
1489
-
1490
- // ++++++++++++++++++++
1491
- // Single selection
1492
- // ++++++++++++++++++++
1493
-
1494
- // clear all active classes of options
1495
- // (Avoid using the keyboard to select and two actives will appear after clicking on a non-selected option.)
1496
- if (noCallback) {
1497
- options.forEach((node: any) => {
1498
- node.classList.remove('active');
1499
- });
1500
-
1501
- }
1502
-
1503
-
1504
-
1505
- // If there is a callback, delete the activated style
1506
- if (!noCallback) {
1507
- setTimeout(() => {
1508
- curBtn.classList.remove('active', 'disabled');
1509
- }, 0);
1510
- }
1511
-
1512
-
1513
-
1514
- //
1515
- setControlValue(_value);
1516
- setControlLabel(formatIndentVal(_label, INDENT_LAST_PLACEHOLDER));
1517
-
1518
- // set value if the attribute `data-options` of component exists, only valid for single selection (it may be an empty array)
1519
- if (typeof incominggetOptionsData !== 'undefined') {
1520
- valueInputRef.current.dataset.value = _value;
1521
- }
1522
-
1523
-
1524
- // ++++++++++++++++++++
1525
- // Multiple selection
1526
- // ++++++++++++++++++++
1527
- let currentControlValueArr: any[] = JSON.parse(JSON.stringify(controlArr.values));
1528
- let currentControlLabelArr: any[] = JSON.parse(JSON.stringify(controlArr.labels));
1529
-
1530
- if (MULTI_SEL_VALID) {
1531
-
1532
-
1533
- const $el = el === null ? curBtn : el.currentTarget;
1534
-
1535
-
1536
- // update option checkboxes
1537
- const _selected = $el.dataset.selected;
1538
- const _selectedVal = _selected == 'true' ? true : false;
1539
- if (_selectedVal) {
1540
- //#########
1541
- // remove item
1542
- //#########
1543
- $el.dataset.selected = 'false';
1544
- $el.querySelector('.custom-select-multi__control-option-checkbox-selected').classList.add('d-none');
1545
- $el.querySelector('.custom-select-multi__control-option-checkbox-placeholder').classList.remove('d-none');
1546
-
1547
-
1548
- //
1549
- setControlArr((prevState: any) => {
1550
-
1551
- // update temporary value
1552
- setControlTempValue(prevState.labels.length >= 0 ? null : (VALUE_BY_BRACKETS ? convertArrToValByBrackets(prevState.labels) : prevState.labels.join(',')));
1553
-
1554
- return {
1555
- labels: removeItemOnce(prevState.labels, formatIndentVal(_label, INDENT_LAST_PLACEHOLDER)),
1556
- values: removeItemOnce(prevState.values, _value)
1557
- }
1558
- });
1559
-
1560
- currentControlValueArr = removeItemOnce(currentControlValueArr, _value);
1561
- currentControlLabelArr = removeItemOnce(currentControlLabelArr, formatIndentVal(_label, INDENT_LAST_PLACEHOLDER));
1562
-
1563
- } else {
1564
- //#########
1565
- // add item
1566
- //#########
1567
-
1568
- $el.dataset.selected = 'true';
1569
- $el.querySelector('.custom-select-multi__control-option-checkbox-selected').classList.remove('d-none');
1570
- $el.querySelector('.custom-select-multi__control-option-checkbox-placeholder').classList.add('d-none');
1571
-
1572
-
1573
- //
1574
- setControlArr((prevState: any) => {
1575
-
1576
- // update temporary value
1577
- setControlTempValue(prevState.labels.length >= 0 ? null : (VALUE_BY_BRACKETS ? convertArrToValByBrackets(prevState.labels) : prevState.labels.join(',')));
1578
-
1579
- return {
1580
- labels: [...prevState.labels, formatIndentVal(_label, INDENT_LAST_PLACEHOLDER)],
1581
- values: [...prevState.values, _value]
1582
- }
1583
- });
1584
-
1585
-
1586
- currentControlValueArr.push(_value);
1587
- currentControlLabelArr.push(_label);
1588
-
1589
- }
1590
-
1591
-
1592
- // Appropriate multi-item container height
1593
- // !!!set `false` to prevents the scrollbar position from changing when multi-selecting the option is clicked
1594
- adjustMultiControlContainerHeight(false);
1595
-
1596
- // active current option
1597
- if (noCallback) {
1598
- setTimeout(() => {
1599
- $el.classList.add('active');
1600
- }, 0);
1601
- }
1602
-
1603
-
1604
-
1605
- }
1606
-
1607
- //
1608
- if (noCallback && typeof (onChange) === 'function') {
1609
-
1610
- onChange?.(
1611
- selectInputRef.current,
1612
- valueInputRef.current,
1613
- !MULTI_SEL_VALID ? curItem : multipleSelectionCallback(currentControlValueArr, currentControlLabelArr)
1614
- );
1615
-
1616
-
1617
- //
1618
- selectInputRef.current.blur();
1619
- }
1620
- }
1621
-
1622
- // Fixed an out-of-focus issue
1623
- fixFocusStatus();
1624
-
1625
- }
1626
-
1627
-
1628
- function updateOptionCheckboxes(type: string) {
1629
-
1630
- const _labels: any[] = [];
1631
- const _values: any[] = [];
1632
-
1633
- [].slice.call(listContentRef.current.querySelectorAll('.custom-select-multi__control-option-item:not(.hide)')).forEach((node: any) => {
1634
-
1635
- const _label = node.dataset.label;
1636
- const _value = node.dataset.value;
1637
-
1638
-
1639
- if (type === 'remove') {
1640
- //#########
1641
- // remove item
1642
- //#########
1643
- node.dataset.selected = 'false';
1644
- node.querySelector('.custom-select-multi__control-option-checkbox-selected').classList.add('d-none');
1645
- node.querySelector('.custom-select-multi__control-option-checkbox-placeholder').classList.remove('d-none');
1646
-
1647
- //
1648
- const _indexLable = _labels.findIndex((item: any) => item == _label);
1649
- const _indexValue = _values.findIndex((item: any) => item == _value);
1650
- if (_indexLable !== -1) _labels.splice(_indexLable, 1);
1651
- if (_indexValue !== -1) _values.splice(_indexValue, 1);
1652
-
1653
-
1654
- } else {
1655
- //#########
1656
- // add item
1657
- //#########
1658
- node.dataset.selected = 'true';
1659
- node.querySelector('.custom-select-multi__control-option-checkbox-selected').classList.remove('d-none');
1660
- node.querySelector('.custom-select-multi__control-option-checkbox-placeholder').classList.add('d-none');
1661
-
1662
- //
1663
- _labels.push(_label);
1664
- _values.push(_value);
1665
-
1666
- }
1667
-
1668
- });
1669
-
1670
- setControlArr({
1671
- labels: _labels,
1672
- values: _values
1673
- });
1674
-
1675
-
1676
-
1677
- // Appropriate multi-item container height
1678
- adjustMultiControlContainerHeight();
1679
-
1680
- return {
1681
- labels: _labels,
1682
- values: _values
1683
- }
1684
-
1685
- };
1686
-
1687
- function updateOptionCheckboxesViaAddSingleItem(data: any) {
1688
-
1689
- const _labels: any[] = data.labels || [];
1690
- const _values: any[] = data.values || [];
1691
-
1692
- setControlArr({
1693
- labels: _labels,
1694
- values: _values
1695
- });
1696
-
1697
- // Appropriate multi-item container height
1698
- adjustMultiControlContainerHeight();
1699
-
1700
- };
1701
-
1702
-
1703
-
1704
- function handleSelectAll(event: any) {
1705
- event.preventDefault();
1706
- event.stopPropagation(); /* REQUIRED */
1707
-
1708
- let _labels: any[] = [];
1709
- let _values: any[] = [];
1710
-
1711
- if (controlArr.values.length === optionsData.length) { // selected all items
1712
- const { labels, values } = updateOptionCheckboxes('remove');
1713
- selectedSign.current = false;
1714
-
1715
- _labels = labels;
1716
- _values = values;
1717
- } else {
1718
-
1719
- const { labels, values } = updateOptionCheckboxes(selectedSign.current ? 'remove' : 'add');
1720
- selectedSign.current = !selectedSign.current;
1721
-
1722
- _labels = labels;
1723
- _values = values;
1724
-
1725
- }
1726
-
1727
- onChange?.(
1728
- selectInputRef.current,
1729
- valueInputRef.current,
1730
- multipleSelectionCallback(_values, _labels)
1731
- );
1732
-
1733
- // Fixed an out-of-focus issue
1734
- fixFocusStatus();
1735
-
1736
-
1737
- }
1738
-
1739
- function handleCleanValue(event?: any) {
1740
- if (typeof event !== 'undefined') {
1741
- event.preventDefault();
1742
- event.stopPropagation(); /* REQUIRED */
1743
- }
1744
-
1745
- // It is valid when a single selection
1746
- const emptyValue: Record<string, string> = { label: '', value: '', queryString: '' };
1747
- handleSelect(null, JSON.stringify(emptyValue), [], []);
1748
-
1749
- // update temporary value
1750
- setControlTempValue(null);
1751
-
1752
- }
1753
-
1754
-
1755
-
1756
- function handleMultiControlItemRemove(event: any) {
1757
- event.preventDefault();
1758
- event.stopPropagation(); /* REQUIRED */
1759
-
1760
- const valueToRemove = String(event.currentTarget.dataset.value);
1761
- const getCurrentIndex = controlArr.values.findIndex((item: any) => item.toString() === valueToRemove);
1762
-
1763
- let currentControlValueArr: any[] = JSON.parse(JSON.stringify(controlArr.values));
1764
- let currentControlLabelArr: any[] = JSON.parse(JSON.stringify(controlArr.labels));
1765
-
1766
- const _value = valueToRemove;
1767
- const _label = controlArr.labels[getCurrentIndex];
1768
-
1769
-
1770
- setControlArr((prevState: any) => {
1771
-
1772
- // update temporary value
1773
- setControlTempValue(prevState.labels.length >= 0 ? null : (VALUE_BY_BRACKETS ? convertArrToValByBrackets(prevState.labels) : prevState.labels.join(',')));
1774
-
1775
- return {
1776
- labels: removeItemOnce(prevState.labels, formatIndentVal(_label, INDENT_LAST_PLACEHOLDER)),
1777
- values: removeItemOnce(prevState.values, _value)
1778
- }
1779
- });
1780
-
1781
- currentControlValueArr = removeItemOnce(currentControlValueArr, _value);
1782
- currentControlLabelArr = removeItemOnce(currentControlLabelArr, formatIndentVal(_label, INDENT_LAST_PLACEHOLDER));
1783
-
1784
-
1785
- // Appropriate multi-item container height
1786
- adjustMultiControlContainerHeight();
1787
-
1788
-
1789
- //
1790
- if (typeof (onChange) === 'function') {
1791
-
1792
- onChange?.(
1793
- selectInputRef.current,
1794
- valueInputRef.current,
1795
- multipleSelectionCallback(currentControlValueArr, currentControlLabelArr)
1796
- );
1797
-
1798
-
1799
- //
1800
- selectInputRef.current.blur();
1801
- }
1802
-
1803
- }
1804
-
1805
-
1806
-
1807
- function handleShowList() {
1808
-
1809
- //
1810
- if (!isOpen) {
1811
- activate();
1812
- } else {
1813
- cancel();
1814
- if (MULTI_SEL_VALID) popwinPosHide();
1815
- }
1816
-
1817
- }
1818
-
1819
-
1820
- async function handleFetch(inputVal: any = null) {
1821
-
1822
- // data init
1823
- const searchStr: string = typeof inputVal === 'string' ? inputVal : (controlTempValue || controlTempValue === '' ? controlTempValue : '');
1824
- const _oparams: any[] = fetchFuncMethodParams || [];
1825
- const _params: any[] = _oparams.map((item: any) => item !== '$QUERY_STRING' ? item : searchStr);
1826
-
1827
-
1828
- const res = await fetchData((_params).join(','), '', '', false);
1829
-
1830
-
1831
- return res;
1832
- }
1833
-
1834
-
1835
- async function handleFirstFetch(inputVal: any = null) {
1836
- const _oparams: any[] = fetchFuncMethodParams || [];
1837
- const _params: any[] = _oparams.map((item: any) => item !== '$QUERY_STRING' ? item : (MANUAL_REQ ? '------' : ''));
1838
- const res = await fetchData((_params).join(','), finalRes(inputVal), inputVal);
1839
-
1840
- return res;
1841
- }
1842
-
1843
-
1844
- function handleComposition(event: any) {
1845
-
1846
- if (event.type === 'compositionstart' || event.type === 'compositionend') {
1847
- //fire change method to update for Chrome v53
1848
- handleChange(event);
1849
- }
1850
- }
1851
-
1852
-
1853
-
1854
- function handleChange(event: any) {
1855
-
1856
- const val = event.target.value;
1857
-
1858
- //Calculates the position of the blinking cursor
1859
- setBlinkingPosStart(getTextWidth(event.target, blinkingPosFauxRef.current, blinkingCursorPosDivRef.current));
1860
-
1861
- // update temporary value
1862
- setControlTempValue(val);
1863
-
1864
- //
1865
- handleChangeFetchSafe(val);
1866
-
1867
- // Fixed an out-of-focus issue
1868
- fixFocusStatus();
1869
-
1870
-
1871
- }
1872
-
1873
- //
1874
- function handleFocus(event: any) {
1875
-
1876
- rootRef.current?.classList.add('focus');
1877
-
1878
- // update temporary value
1879
- setControlTempValue('');
1880
-
1881
-
1882
- //
1883
- onFocus?.(selectInputRef.current);
1884
-
1885
- }
1886
-
1887
- function handleBlur(event: any) {
1888
-
1889
- // Fix the focus issue with using the "Tabs" and "Enter" keys
1890
- //
1891
- //
1892
- rootRef.current?.classList.remove('focus');
1893
-
1894
- if (!MULTI_SEL_VALID) {
1895
- if (!isOpen) {
1896
- cancel();
1897
- if (MULTI_SEL_VALID) popwinPosHide();
1898
- }
1899
- } else {
1900
- if (listContentRef.current) listContentRef.current.focus();
1901
- }
1902
-
1903
-
1904
- setTimeout(() => {
1905
- onBlur?.(selectInputRef.current);
1906
- }, 300);
1907
- }
1908
-
1909
-
1910
- function generateInputFocusStr() {
1911
- return controlTempValue || controlTempValue === '' ? (controlTempValue.length === 0 ? BLINKING_CURSOR_STR : controlTempValue) : (placeholder || '');
1912
- }
1913
-
1914
- function hideBlinkingCursor() {
1915
- return (generateInputFocusStr() === placeholder && placeholder !== '' && typeof placeholder !== 'undefined') || (controlTempValue === null || controlTempValue.length === 0);
1916
- }
1917
-
1918
- function optionFocus(type: string) {
1919
-
1920
- return new Promise(function (resolve) {
1921
-
1922
- // Determine the "active" class name to avoid listening to other unused components of the same type
1923
- if (listRef.current === null || !rootRef.current.classList.contains('active')) return;
1924
-
1925
-
1926
- // Avoid selecting options that are disabled
1927
- const options = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide):not(.custom-select-multi__control-option-item--select-all):not(.custom-select-multi__control-option-item--clean)'));
1928
- const currentIndex = options.findIndex((e) => e === listRef.current.querySelector('.list-group-item.active'));
1929
-
1930
-
1931
- // get the next element in the list, "%" will loop around to 0
1932
- let nextIndex;
1933
- if (type === 'increase') {
1934
- nextIndex = currentIndex + 1 % options.length;
1935
- } else {
1936
- nextIndex = (currentIndex < 0 ? options.length : currentIndex) - 1 % options.length;
1937
- }
1938
-
1939
-
1940
-
1941
- //only one
1942
- if (options.length === 1) nextIndex = 0;
1943
-
1944
-
1945
- if (!isNaN(nextIndex)) {
1946
- options.forEach((node: any, index: number) => {
1947
- node?.classList.remove('active');
1948
- });
1949
-
1950
- const targetOption = options[nextIndex] as HTMLElement;
1951
- if (typeof targetOption !== 'undefined' && !targetOption.classList.contains('no-match')) {
1952
- targetOption.classList.add('active');
1953
-
1954
- keyboardSelectedItem.current = targetOption;
1955
- resolve(targetOption);
1956
- }
1957
-
1958
- }
1959
- });
1960
-
1961
-
1962
- }
1963
-
1964
-
1965
- async function handleKeyPressed(event: KeyboardEvent<HTMLDivElement>) {
1966
- const key = event.code;
1967
-
1968
- //
1969
- onKeyPressed?.(
1970
- event,
1971
- selectInputRef.current,
1972
- valueInputRef.current
1973
- );
1974
-
1975
-
1976
- if (!isOpen) return;
1977
-
1978
- let res: any = null;
1979
-
1980
- if (key === 'Enter' || key === 'NumpadEnter') {
1981
- event.preventDefault();
1982
-
1983
- // Determine the "active" class name to avoid listening to other unused components of the same type
1984
- if (listRef.current === null || !rootRef.current.classList.contains('active')) return;
1985
-
1986
- // Avoid selecting options that are disabled
1987
- if (keyboardSelectedItem.current !== null && keyboardSelectedItem.current.classList.contains('disabled')) return;
1988
-
1989
- if (listRef.current !== null) {
1990
- const currentIndex = await listRef.current.dataset.data;
1991
-
1992
-
1993
- if (typeof currentIndex !== 'undefined') {
1994
-
1995
-
1996
- const currentData = optionsData[Number(currentIndex)];
1997
- const currentControlValueArr: any[] = [];
1998
- const currentControlLabelArr: any[] = [];
1999
-
2000
- const htmlOptions = [].slice.call(listRef.current.querySelectorAll('.list-group-item:not(.hide):not(.no-match)'));
2001
-
2002
- htmlOptions.forEach((node: any) => {
2003
- node.classList.remove('active');
2004
-
2005
- // multiple options
2006
- if (node.classList.contains('item-selected')) {
2007
- currentControlValueArr.push(node.dataset.value);
2008
- currentControlLabelArr.push(node.dataset.label);
2009
- }
2010
-
2011
- });
2012
-
2013
-
2014
- handleSelect(null, currentData, currentControlValueArr, currentControlLabelArr);
2015
-
2016
- //
2017
- if (typeof (onChange) === 'function') {
2018
-
2019
- onChange?.(
2020
- selectInputRef.current,
2021
- valueInputRef.current,
2022
- !MULTI_SEL_VALID ? currentData : multipleSelectionCallback(currentControlValueArr, currentControlLabelArr)
2023
- );
2024
-
2025
-
2026
- //
2027
- selectInputRef.current.blur();
2028
- }
2029
-
2030
- }
2031
- }
2032
- }
2033
-
2034
- if (key === 'ArrowUp') {
2035
- res = await optionFocus('decrease');
2036
-
2037
- }
2038
-
2039
- if (key === 'ArrowDown') {
2040
- res = await optionFocus('increase');
2041
- }
2042
-
2043
-
2044
- // temporary data
2045
- if (res !== null) listRef.current.dataset.data = res.dataset.index;
2046
-
2047
-
2048
- }
2049
-
2050
- function handleDocOut(e: any) {
2051
-
2052
- if (e.target.closest('.custom-select__options-wrapper') === null && e.target.closest('.custom-select__wrapper') === null) {
2053
- // cancel
2054
- cancel();
2055
- if (MULTI_SEL_VALID) popwinPosHide();
2056
-
2057
- // DO NOT USE "handleBlur(null)"
2058
- }
2059
- }
2060
-
2061
-
2062
- useEffect(() => {
2063
-
2064
-
2065
- // Call a function when the component has been rendered completely
2066
- //--------------
2067
- onLoad?.(selectInputRef.current, valueInputRef.current, finalRes(value));
2068
-
2069
-
2070
- // update incoming data
2071
- //--------------
2072
- setIncomingData(data);
2073
-
2074
-
2075
- // data init
2076
- //--------------
2077
- if (FIRST_REQUEST_AUTO) {
2078
- handleFirstFetch(value);
2079
- }
2080
-
2081
-
2082
-
2083
- return () => {
2084
- if (LOCK_BODY_SCROLL) clearAllBodyScrollLocks();
2085
- }
2086
-
2087
- }, [value, options, data]);
2088
-
2089
-
2090
- useEffect(() => {
2091
-
2092
- // update default value (It does not re-render the component because the incoming value changes.)
2093
- //--------------
2094
- if (typeof defaultValue !== 'undefined') { //REQUIRED
2095
-
2096
- // Call a function when the component has been rendered completely
2097
- //--------------
2098
- onLoad?.(selectInputRef.current, valueInputRef.current, finalRes(defaultValue));
2099
-
2100
-
2101
- // data init
2102
- //--------------
2103
- if (FIRST_REQUEST_AUTO) {
2104
- handleFirstFetch(defaultValue);
2105
- }
2106
-
2107
- }
2108
-
2109
- }, []);
2110
-
2111
-
2112
-
2113
- // Fixed an out-of-focus issue
2114
- //--------------
2115
- // !!! TIPS:
2116
- // Fixed: When `fixFocusStatus()` is triggered, the above judgment will be invalidated, and this judgment will be used
2117
- // Fixed: The pop-up window is not closed due to the mixing of business components
2118
- useEffect(() => {
2119
- document.addEventListener('pointerdown', handleDocOut);
2120
- return () => {
2121
- document.removeEventListener('pointerdown', handleDocOut);
2122
- };
2123
- }, [orginalData]); // Avoid the issue that `setOptionsData(orginalData)` sets the original value to empty on the first entry
2124
-
2125
-
2126
- return (
2127
- <>
2128
-
2129
- {label ? <><div className="custom-select__label">{typeof label === 'string' ? <label htmlFor={`label-${idRes}`} className="form-label" dangerouslySetInnerHTML={{ __html: `${label}` }}></label> : <label htmlFor={`label-${idRes}`} className="form-label">{label}</label>}</div></> : null}
2130
-
2131
- <span ref={blinkingPosFauxRef}></span>
2132
-
2133
- <div
2134
- ref={rootRef}
2135
- data-overlay-id={`custom-select__options-wrapper-${idRes}`}
2136
- id={`custom-select__wrapper-${idRes}`}
2137
- className={combinedCls(
2138
- 'custom-select__wrapper',
2139
- clsWrite(wrapperClassName, 'mb-3 position-relative'),
2140
- {
2141
- 'multiple-selection': MULTI_SEL_VALID,
2142
- 'active focus': isOpen
2143
- }
2144
- )}
2145
- onKeyDown={handleKeyPressed}
2146
-
2147
- >
2148
-
2149
-
2150
-
2151
- {!MULTI_SEL_VALID ? <>
2152
-
2153
- {/** INPUT */}
2154
- <div className="position-relative">
2155
- <input
2156
- ref={(node) => {
2157
- selectInputRef.current = node;
2158
- if (typeof externalRef === 'function') {
2159
- externalRef(node);
2160
- } else if (externalRef) {
2161
- externalRef.current = node;
2162
- }
2163
- }}
2164
- tabIndex={tabIndex || 0}
2165
- type="text"
2166
- data-overlay-id={`custom-select__options-wrapper-${idRes}`}
2167
- id={`label-${idRes}`}
2168
-
2169
- // Don't use "name", it's just a container to display the label
2170
- data-name={name?.match(/(\[.*?\])/gi) ? `${name.split('[')[0]}-label[]` : `${name}-label`}
2171
- data-select
2172
- className={combinedCls(
2173
- clsWrite(controlClassName, 'form-control'),
2174
- controlExClassName
2175
- )}
2176
- onFocus={handleFocus}
2177
- onBlur={handleBlur}
2178
- onClick={typeof readOnly === 'undefined' || !readOnly ? handleShowList : () => void (0)}
2179
- onChange={handleChange}
2180
- onCompositionStart={handleComposition}
2181
- onCompositionUpdate={handleComposition}
2182
- onCompositionEnd={handleComposition}
2183
- disabled={disabled || null}
2184
- required={required || null}
2185
- readOnly={INPUT_READONLY}
2186
- value={controlTempValue || controlTempValue === '' ? controlTempValue : (MULTI_SEL_VALID ? (VALUE_BY_BRACKETS ? convertArrToValByBrackets(formatIndentVal(controlArr.labels, INDENT_LAST_PLACEHOLDER).map((v: any) => stripHTML(v))) : formatIndentVal(controlArr.labels, INDENT_LAST_PLACEHOLDER).map((v: any) => stripHTML(v)).join(',')) : stripHTML(controlLabel as never))} // do not use `defaultValue`
2187
-
2188
- style={{
2189
- cursor: 'pointer',
2190
- color: 'transparent',
2191
- borderBottomWidth: MULTI_SEL_VALID ? '0' : '1px',
2192
- ...style
2193
- }}
2194
- autoComplete={typeof autoComplete === 'undefined' ? 'off' : autoComplete}
2195
- autoCapitalize={typeof autoCapitalize === 'undefined' ? 'off' : autoCapitalize}
2196
- spellCheck={typeof spellCheck === 'undefined' ? false : spellCheck}
2197
- {...attributes}
2198
- />
2199
-
2200
- </div>
2201
-
2202
-
2203
- </> : null}
2204
-
2205
- {/* ========== RESULT CONTAINER ========== */}
2206
- <input
2207
- ref={valueInputRef}
2208
- tabIndex={-1}
2209
- type="hidden"
2210
- id={idRes}
2211
- name={name}
2212
- value={MULTI_SEL_VALID ? (VALUE_BY_BRACKETS ? convertArrToValByBrackets(controlArr.values) : controlArr.values.join(',')) : controlValue} // do not use `defaultValue`
2213
- onChange={() => void (0)}
2214
- {...attributes}
2215
- />
2216
-
2217
-
2218
- {/* BLINKING CURSOR */}
2219
- {!MULTI_SEL_VALID ? <>
2220
- <span
2221
- className={combinedCls(
2222
- 'custom-select-multi__control-blinking-following-cursor animated',
2223
- {
2224
- 'd-none': hideBlinkingCursor()
2225
- }
2226
- )}
2227
- style={{
2228
- left: `${blinkingPosStart}px`
2229
- }}
2230
- >
2231
- {BLINKING_CURSOR_STR}
2232
- </span>
2233
- </> : null}
2234
- {/* /BLINKING CURSOR */}
2235
-
2236
- {/* ========== /RESULT CONTAINER ========== */}
2237
-
2238
-
2239
-
2240
- {/*
2241
- // ++++++++++++++++++++
2242
- // Single selection Control
2243
- // ++++++++++++++++++++
2244
- */}
2245
- {!MULTI_SEL_VALID ? <div className="custom-select-single__inputplaceholder-wrapper">
2246
-
2247
-
2248
- {/* PLACEHOLDER */}
2249
- <div className="custom-select-single__inputplaceholder-inner" style={style}>
2250
- <input
2251
- tabIndex={-1}
2252
- type="text"
2253
- className={combinedCls(
2254
- clsWrite(controlClassName, 'form-control'),
2255
- controlExClassName
2256
- )}
2257
- />
2258
-
2259
- <span ref={blinkingCursorPosDivRef} className={combinedCls(
2260
- 'custom-select-multi__control-blinking-cursor',
2261
- {
2262
- 'animated': generateInputFocusStr() === BLINKING_CURSOR_STR
2263
- }
2264
- )}>
2265
- {controlTempValue || controlTempValue === '' ? (controlTempValue.length === 0 ? <span className={`${!hideBlinkingCursor() ? 'control-placeholder' : ''}`}>{generateInputFocusStr()}</span> : <span>{controlTempValue}</span>) : (stripHTML(controlLabel as never).length === 0 ? <span className={`${!hideBlinkingCursor() ? 'control-placeholder' : ''}`}>{generateInputFocusStr()}</span> : <span>{stripHTML(controlLabel as never)}</span>)}
2266
- </span>
2267
-
2268
- </div>
2269
-
2270
-
2271
- {/* /PLACEHOLDER */}
2272
-
2273
-
2274
- {/* ARROW */}
2275
- <span className={combinedCls(
2276
- 'custom-select-arrow',
2277
- {
2278
- 'reverse': isOpen
2279
- }
2280
- )} style={{display: MANUAL_REQ ? 'none' : 'inline-block' }}>
2281
- {controlArrow ? controlArrow : <svg width="10px" height="10px" viewBox="0 -4.5 20 20">
2282
- <g stroke="none" strokeWidth="1" fill="none">
2283
- <g transform="translate(-180.000000, -6684.000000)" className="arrow-fill-g" fill="#a5a5a5">
2284
- <g transform="translate(56.000000, 160.000000)">
2285
- <path d="M144,6525.39 L142.594,6524 L133.987,6532.261 L133.069,6531.38 L133.074,6531.385 L125.427,6524.045 L124,6525.414 C126.113,6527.443 132.014,6533.107 133.987,6535 C135.453,6533.594 134.024,6534.965 144,6525.39">
2286
- </path>
2287
- </g>
2288
- </g>
2289
- </g>
2290
- </svg>}
2291
- </span>
2292
-
2293
-
2294
- {/* /ARROW */}
2295
-
2296
-
2297
-
2298
- {/* SEARCH BUTTON */}
2299
- {MANUAL_REQ ? <>
2300
- <span className="custom-select-multi__control-searchbtn">
2301
- <button tabIndex={-1} type="button" className="btn border-end-0 rounded-pill" onClick={(e: React.MouseEvent) => {
2302
- handleFetch().then((response: any) => {
2303
-
2304
- // pop win initalization
2305
- setTimeout(() => {
2306
- popwinPosInit();
2307
- popwinFilterItems(controlTempValue);
2308
- }, 0);
2309
- });
2310
- }}>
2311
- <svg width="1em" height="1em" fill="#a5a5a5" viewBox="0 0 16 16">
2312
- <path d="M12.027 9.92L16 13.95 14 16l-4.075-3.976A6.465 6.465 0 0 1 6.5 13C2.91 13 0 10.083 0 6.5 0 2.91 2.917 0 6.5 0 10.09 0 13 2.917 13 6.5a6.463 6.463 0 0 1-.973 3.42zM1.997 6.452c0 2.48 2.014 4.5 4.5 4.5 2.48 0 4.5-2.015 4.5-4.5 0-2.48-2.015-4.5-4.5-4.5-2.48 0-4.5 2.014-4.5 4.5z" fillRule="evenodd" />
2313
- </svg>
2314
- </button>
2315
-
2316
- </span>
2317
- </> : null}
2318
- {/* /SEARCH BUTTON */}
2319
-
2320
-
2321
-
2322
- </div> : null}
2323
-
2324
-
2325
-
2326
- {/*
2327
- // ++++++++++++++++++++
2328
- // Multiple selection Control
2329
- // ++++++++++++++++++++
2330
- */}
2331
- {MULTI_SEL_VALID ? <div ref={rootMultiRef} className="custom-select-multi__inputplaceholder-wrapper">
2332
-
2333
-
2334
- {/* PLACEHOLDER */}
2335
- <div className="custom-select-multi__inputplaceholder-inner">
2336
- <div style={MULTI_SEL_ENTIRE_AREA_TRIGGER ? {pointerEvents: 'auto', cursor: 'pointer'} : undefined} onClick={MULTI_SEL_ENTIRE_AREA_TRIGGER ? ( typeof readOnly === 'undefined' || !readOnly ? handleShowList : () => void (0) ) : () => void (0)}>
2337
- <ul className="custom-select-multi__list">
2338
-
2339
- {typeof multiSelectSelectedItemOnlyStatus !== 'undefined' ? <>
2340
-
2341
- <li className="custom-select-multi__list-item-statusstring" >
2342
-
2343
-
2344
- {MANUAL_REQ ? <>
2345
- {/* ===================== Manual requests ===================== */}
2346
- {
2347
- typeof multiSelectSelectedItemOnlyStatus.itemsLabel === 'string' &&
2348
- controlArr.labels.length > 0
2349
- ?
2350
- multiSelectSelectedItemOnlyStatus.itemsLabel.replace('{num}', `${controlArr.labels.length}`)
2351
- :
2352
- null
2353
- }
2354
- {
2355
- typeof multiSelectSelectedItemOnlyStatus.noneLabel === 'string' &&
2356
- controlArr.labels.length === 0
2357
- ?
2358
- multiSelectSelectedItemOnlyStatus.noneLabel
2359
- :
2360
- null
2361
- }
2362
-
2363
- {/*-- DEFAULT VALUE ---*/}
2364
- {
2365
- typeof multiSelectSelectedItemOnlyStatus.itemsLabel !== 'string' &&
2366
- controlArr.labels.length > 0
2367
- ?
2368
- MULTI_SEL_SELECTED_STATUS.itemsLabel.replace('{num}', `${controlArr.labels.length}`)
2369
- :
2370
- null
2371
- }
2372
- {
2373
- typeof multiSelectSelectedItemOnlyStatus.noneLabel !== 'string' &&
2374
- controlArr.labels.length === 0
2375
- ?
2376
- MULTI_SEL_SELECTED_STATUS.noneLabel
2377
- :
2378
- null
2379
- }
2380
-
2381
- {/* ===================== /Manual requests ===================== */}
2382
-
2383
- </> : <>
2384
- {/* ===================== Auto requests ===================== */}
2385
-
2386
- {
2387
- typeof multiSelectSelectedItemOnlyStatus.itemsLabel === 'string' &&
2388
- controlArr.labels.length > 0 &&
2389
- controlArr.labels.length < optionsData.length
2390
- ?
2391
- multiSelectSelectedItemOnlyStatus.itemsLabel.replace('{num}', `${controlArr.labels.length}`)
2392
- :
2393
- null
2394
- }
2395
- {
2396
- typeof multiSelectSelectedItemOnlyStatus.noneLabel === 'string' &&
2397
- controlArr.labels.length === 0
2398
- ?
2399
- multiSelectSelectedItemOnlyStatus.noneLabel
2400
- :
2401
- null
2402
- }
2403
-
2404
- {/* all */}
2405
- {controlArr.labels.length > 0 ? <>
2406
- {
2407
- typeof multiSelectSelectedItemOnlyStatus.allItemsLabel === 'string' &&
2408
- controlArr.labels.length === optionsData.length
2409
- ?
2410
- multiSelectSelectedItemOnlyStatus.allItemsLabel.replace('{num}', `${controlArr.labels.length}`)
2411
- :
2412
- null
2413
- }
2414
- </>: null}
2415
-
2416
-
2417
- {/*-- DEFAULT VALUE ---*/}
2418
- {
2419
- typeof multiSelectSelectedItemOnlyStatus.itemsLabel !== 'string' &&
2420
- controlArr.labels.length > 0
2421
- ?
2422
- MULTI_SEL_SELECTED_STATUS.itemsLabel.replace('{num}', `${controlArr.labels.length}`)
2423
- :
2424
- null
2425
- }
2426
- {
2427
- typeof multiSelectSelectedItemOnlyStatus.noneLabel !== 'string' &&
2428
- controlArr.labels.length === 0
2429
- ?
2430
- MULTI_SEL_SELECTED_STATUS.noneLabel
2431
- :
2432
- null
2433
- }
2434
-
2435
- {/* all */}
2436
- {controlArr.labels.length > 0 ? <>
2437
- {
2438
- typeof multiSelectSelectedItemOnlyStatus.allItemsLabel !== 'string' &&
2439
- controlArr.labels.length === optionsData.length
2440
- ?
2441
- MULTI_SEL_SELECTED_STATUS.allItemsLabel.replace('{num}', `${controlArr.labels.length}`)
2442
- :
2443
- null
2444
- }
2445
- </>: null}
2446
- {/* ===================== /Auto requests ===================== */}
2447
-
2448
- </>}
2449
-
2450
- </li>
2451
- </> : <>
2452
-
2453
- {/* ITEMS LIST */}
2454
- {typeof renderSelectedValue === 'function' ? <>
2455
- {renderSelectedValue(controlArr, handleMultiControlItemRemove)}
2456
- </> : <>
2457
- {controlArr.labels.map((item: any, index: number) => (
2458
- <li
2459
- key={'selected-item-' + index}
2460
- data-value={controlArr.values[index]}
2461
- data-label-full={item}
2462
- data-label-text={formatIndentVal(stripHTML(item), INDENT_LAST_PLACEHOLDER)}
2463
- >
2464
- {formatIndentVal(stripHTML(item), INDENT_LAST_PLACEHOLDER)}
2465
-
2466
- <a
2467
- href="#"
2468
- tabIndex={-1}
2469
- onClick={handleMultiControlItemRemove}
2470
- data-value={controlArr.values[index]}
2471
- ><svg width="10px" height="10px" viewBox="0 0 1024 1024"><path fill="#000" d="M195.2 195.2a64 64 0 0 1 90.496 0L512 421.504 738.304 195.2a64 64 0 0 1 90.496 90.496L602.496 512 828.8 738.304a64 64 0 0 1-90.496 90.496L512 602.496 285.696 828.8a64 64 0 0 1-90.496-90.496L421.504 512 195.2 285.696a64 64 0 0 1 0-90.496z" /></svg></a>
2472
- </li>
2473
- ))}
2474
- </>}
2475
-
2476
-
2477
- </>}
2478
-
2479
-
2480
- {/** INPUT */}
2481
- <li className="custom-select-multi__list-item-add">
2482
- <div className="position-relative">
2483
- {/*
2484
- // DO NOT USE following attributes in " Multiple selection Control":
2485
- a) data-select
2486
- b) value
2487
- */}
2488
- <input
2489
- ref={(node) => {
2490
- selectInputRef.current = node;
2491
- if (typeof externalRef === 'function') {
2492
- externalRef(node);
2493
- } else if (externalRef) {
2494
- externalRef.current = node;
2495
- }
2496
- }}
2497
- tabIndex={tabIndex || 0}
2498
- type="text"
2499
- data-overlay-id={`custom-select__options-wrapper-${idRes}`}
2500
- id={`label-${idRes}`}
2501
-
2502
- // Don't use "name", it's just a container to display the label
2503
- data-name={name?.match(/(\[.*?\])/gi) ? `${name.split('[')[0]}-label[]` : `${name}-label`}
2504
- className={combinedCls(
2505
- clsWrite(controlClassName, 'form-control'),
2506
- controlExClassName
2507
- )}
2508
- onFocus={handleFocus}
2509
- onBlur={handleBlur}
2510
- onClick={typeof readOnly === 'undefined' || !readOnly ? handleShowList : () => void (0)}
2511
- onChange={handleChange}
2512
- onCompositionStart={handleComposition}
2513
- onCompositionUpdate={handleComposition}
2514
- onCompositionEnd={handleComposition}
2515
- disabled={disabled || null}
2516
- required={required || null}
2517
- readOnly={INPUT_READONLY}
2518
- placeholder={placeholder}
2519
- style={style}
2520
- autoComplete={typeof autoComplete === 'undefined' ? 'off' : autoComplete}
2521
- autoCapitalize={typeof autoCapitalize === 'undefined' ? 'off' : autoCapitalize}
2522
- spellCheck={typeof spellCheck === 'undefined' ? false : spellCheck}
2523
- {...attributes}
2524
- />
2525
-
2526
- </div>
2527
-
2528
-
2529
- </li>
2530
-
2531
- </ul>
2532
-
2533
- </div>
2534
-
2535
- </div>
2536
- {/* /PLACEHOLDER */}
2537
-
2538
-
2539
-
2540
-
2541
- {/* ARROW */}
2542
- <span className={combinedCls(
2543
- 'custom-select-arrow',
2544
- {
2545
- 'reverse': isOpen
2546
- }
2547
- )} style={{display: MANUAL_REQ ? 'none' : 'inline-block' }}>
2548
- {controlArrow ? controlArrow : <svg width="10px" height="10px" viewBox="0 -4.5 20 20">
2549
- <g stroke="none" strokeWidth="1" fill="none">
2550
- <g transform="translate(-180.000000, -6684.000000)" className="arrow-fill-g" fill="#a5a5a5">
2551
- <g transform="translate(56.000000, 160.000000)">
2552
- <path d="M144,6525.39 L142.594,6524 L133.987,6532.261 L133.069,6531.38 L133.074,6531.385 L125.427,6524.045 L124,6525.414 C126.113,6527.443 132.014,6533.107 133.987,6535 C135.453,6533.594 134.024,6534.965 144,6525.39">
2553
- </path>
2554
- </g>
2555
- </g>
2556
- </g>
2557
- </svg>}
2558
- </span>
2559
- {/* /ARROW */}
2560
-
2561
-
2562
-
2563
- {/* SEARCH BUTTON */}
2564
- {MANUAL_REQ ? <>
2565
- <span className="custom-select-multi__control-searchbtn">
2566
- <button tabIndex={-1} type="button" className="btn border-end-0 rounded-pill" onClick={(e: React.MouseEvent) => {
2567
- handleFetch().then((response: any) => {
2568
-
2569
- // pop win initalization
2570
- setTimeout(() => {
2571
- popwinPosInit();
2572
- popwinFilterItems(controlTempValue);
2573
- }, 0);
2574
- });
2575
- }}>
2576
- <svg width="1em" height="1em" fill="#a5a5a5" viewBox="0 0 16 16">
2577
- <path d="M12.027 9.92L16 13.95 14 16l-4.075-3.976A6.465 6.465 0 0 1 6.5 13C2.91 13 0 10.083 0 6.5 0 2.91 2.917 0 6.5 0 10.09 0 13 2.917 13 6.5a6.463 6.463 0 0 1-.973 3.42zM1.997 6.452c0 2.48 2.014 4.5 4.5 4.5 2.48 0 4.5-2.015 4.5-4.5 0-2.48-2.015-4.5-4.5-4.5-2.48 0-4.5 2.014-4.5 4.5z" fillRule="evenodd" />
2578
- </svg>
2579
- </button>
2580
-
2581
- </span>
2582
- </> : null}
2583
-
2584
-
2585
- </div> : null}
2586
- {/* /SEARCH BUTTON */}
2587
-
2588
-
2589
-
2590
-
2591
- {optionsData && !hasErr ? <>
2592
- <RootPortal show={true} containerClassName="Select">
2593
-
2594
- <div
2595
- ref={listRef}
2596
- id={`custom-select__options-wrapper-${idRes}`}
2597
- className={combinedCls(
2598
- 'custom-select__options-wrapper list-group position-absolute border shadow small',
2599
- optionsExClassName,
2600
- {
2601
- 'multiple-selection': MULTI_SEL_VALID
2602
- }
2603
- )}
2604
- style={{ zIndex: DEPTH, width: WIN_WIDTH, display: 'none' }}
2605
- role="tablist"
2606
- >
2607
-
2608
- <div
2609
- className="custom-select__options-contentlist rounded"
2610
- style={{ backgroundColor: 'var(--bs-list-group-bg)' }}
2611
- tabIndex={0}
2612
- ref={listContentRef}
2613
- >
2614
- <div className="custom-select__options-contentlist-inner">
2615
-
2616
- {/* SELECT ALL BUTTON */}
2617
- {MULTI_SEL_VALID ? <>
2618
- <span
2619
- tabIndex={-1}
2620
- className="list-group-item list-group-item-action border-start-0 border-end-0 text-secondary bg-light custom-select-multi__control-option-item--select-all position-sticky top-0 z-3"
2621
- role="tab"
2622
- style={{ display: multiSelect?.selectAll ? 'block' : 'none' }}
2623
- >
2624
- <span
2625
- tabIndex={-1}
2626
- className="btn btn-secondary"
2627
- dangerouslySetInnerHTML={{
2628
- __html: controlArr.values.length === optionsData.length ? `${MULTI_DESEL_LABEL}` : `${MULTI_SEL_LABEL}`
2629
- }}
2630
- onClick={handleSelectAll}
2631
- ></span>
2632
- </span>
2633
- </> : null}
2634
- {/* /SELECT ALL BUTTON */}
2635
-
2636
-
2637
-
2638
- {/* CLEAN BUTTON (Only Single selection) */}
2639
- {!MULTI_SEL_VALID ? <>
2640
- {CLEAN_TRIGGER_VALID ? <>
2641
- <span
2642
- tabIndex={-1}
2643
- className="list-group-item list-group-item-action border-start-0 border-end-0 text-secondary bg-light custom-select-multi__control-option-item--clean position-sticky top-0 z-3"
2644
- role="tab"
2645
- >
2646
- <span
2647
- tabIndex={-1}
2648
- className="btn btn-secondary"
2649
- dangerouslySetInnerHTML={{
2650
- __html: `${CLEAN_TRIGGER_LABEL}`
2651
- }}
2652
- onClick={handleCleanValue}
2653
- ></span>
2654
- </span>
2655
- </> : null}
2656
- </> : null}
2657
- {/* /CLEAN BUTTON (Only Single selection) */}
2658
-
2659
-
2660
- {/* NO MATCH */}
2661
- <button tabIndex={-1} type="button" className="list-group-item list-group-item-action no-match border-0 custom-select-multi__control-option-item--nomatch hide" disabled>{fetchNoneInfo || 'No match yet'}</button>
2662
- {/* /NO MATCH */}
2663
-
2664
-
2665
- {/* OPTIONS LIST */}
2666
- {optionsData ? optionsData.map((item, index) => {
2667
- const startItemBorder = index === 0 ? 'border-top-0' : '';
2668
- const endItemBorder = index === optionsData.length - 1 ? 'border-bottom-0' : '';
2669
-
2670
-
2671
- // disable selected options (only single selection)
2672
- let disabledCurrentOption: boolean = false;
2673
- if (
2674
- (typeof controlValue !== 'undefined' && controlValue !== null && controlValue !== '') &&
2675
- (typeof item.value !== 'undefined' && item.value !== null && item.value !== '')
2676
- ) {
2677
-
2678
- if (!MULTI_SEL_VALID) {
2679
- const _defaultValue = controlValue.toString();
2680
- let filterRes: any = [];
2681
- const filterResQueryValue = optionsData.filter((item: any) => item.value == _defaultValue);
2682
- const filterResQueryLabel = optionsData.filter((item: any) => item.label == _defaultValue);
2683
-
2684
- if (filterResQueryValue.length === 0 && filterResQueryLabel.length > 0) {
2685
- filterRes = filterResQueryValue;
2686
- if (filterResQueryValue.length === 0) filterRes = filterResQueryLabel;
2687
- }
2688
-
2689
- const _targetValue = filterRes.length > 0 ? filterRes[0].value : _defaultValue;
2690
- const _realValue = item.value.toString();
2691
-
2692
- if (_realValue === _targetValue && _targetValue !== '') {
2693
- disabledCurrentOption = true;
2694
- }
2695
- }
2696
-
2697
- }
2698
-
2699
-
2700
-
2701
- if (!MULTI_SEL_VALID) {
2702
-
2703
- // ++++++++++++++++++++
2704
- // Single selection
2705
- // ++++++++++++++++++++
2706
- return <button
2707
- tabIndex={-1}
2708
- type="button"
2709
- data-index={index}
2710
- key={index}
2711
- className={combinedCls(
2712
- 'list-group-item list-group-item-action border-start-0 border-end-0 custom-select-multi__control-option-item border-bottom-0',
2713
- startItemBorder,
2714
- endItemBorder,
2715
- {
2716
- 'disabled': item.disabled,
2717
- 'active disabled': disabledCurrentOption,
2718
- 'custom-select-grouptitle': item.group
2719
- }
2720
-
2721
- )}
2722
- data-value={`${item.value}`}
2723
- data-label={`${item.label}`}
2724
- data-querystring={`${typeof item.queryString === 'undefined' ? '' : item.queryString}`}
2725
- data-itemdata={JSON.stringify(item)}
2726
- data-list-item-label={`${typeof item.listItemLabel === 'undefined' ? '' : item.listItemLabel}`}
2727
- role="tab"
2728
- dangerouslySetInnerHTML={{
2729
- __html: typeof item.listItemLabel === 'undefined' ? item.label : item.listItemLabel
2730
- }}
2731
- onClick={handleSelect}
2732
- ></button>
2733
-
2734
- } else {
2735
-
2736
- // ++++++++++++++++++++
2737
- // Multiple selection
2738
- // ++++++++++++++++++++
2739
- const itemSelected = multiSelControlOptionExist(controlArr.values, item.value) ? true : false;
2740
-
2741
- return <button
2742
- tabIndex={-1}
2743
- type="button"
2744
- data-selected={`${itemSelected ? 'true' : 'false'}`}
2745
- data-index={index}
2746
- key={index}
2747
- className={combinedCls(
2748
- 'list-group-item list-group-item-action border-start-0 border-end-0 custom-select-multi__control-option-item border-bottom-0',
2749
- startItemBorder,
2750
- endItemBorder,
2751
- {
2752
- 'list-group-item-secondary item-selected': itemSelected,
2753
- 'disabled': item.disabled,
2754
- 'custom-select-grouptitle': item.group
2755
-
2756
- }
2757
- )}
2758
- data-value={`${item.value}`}
2759
- data-label={`${item.label}`}
2760
- data-querystring={`${typeof item.queryString === 'undefined' ? '' : item.queryString}`}
2761
- data-list-item-label={`${typeof item.listItemLabel === 'undefined' ? '' : item.listItemLabel}`}
2762
- data-itemdata={JSON.stringify(item)}
2763
- role="tab"
2764
- onClick={handleSelect}
2765
- >
2766
- <var className={combinedCls(
2767
- 'me-1 custom-select-multi__control-option-checkbox-selected',
2768
- {
2769
- 'd-none': !itemSelected
2770
- }
2771
-
2772
- )}>
2773
- <svg width="1.2em" height="1.2em" fill="#000000" viewBox="0 0 24 24"><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" /></svg>
2774
-
2775
- </var>
2776
-
2777
- <var className={combinedCls(
2778
- 'me-1 custom-select-multi__control-option-checkbox-placeholder',
2779
- {
2780
- 'd-none': itemSelected
2781
- }
2782
- )}>
2783
- <svg width="1.2em" height="1.2em" fill="#000000" viewBox="0 0 24 24"><path d="M4 7.2002V16.8002C4 17.9203 4 18.4801 4.21799 18.9079C4.40973 19.2842 4.71547 19.5905 5.0918 19.7822C5.5192 20 6.07899 20 7.19691 20H16.8031C17.921 20 18.48 20 18.9074 19.7822C19.2837 19.5905 19.5905 19.2842 19.7822 18.9079C20 18.4805 20 17.9215 20 16.8036V7.19691C20 6.07899 20 5.5192 19.7822 5.0918C19.5905 4.71547 19.2837 4.40973 18.9074 4.21799C18.4796 4 17.9203 4 16.8002 4H7.2002C6.08009 4 5.51962 4 5.0918 4.21799C4.71547 4.40973 4.40973 4.71547 4.21799 5.0918C4 5.51962 4 6.08009 4 7.2002Z" /></svg>
2784
- </var>
2785
- <span dangerouslySetInnerHTML={{
2786
- __html: typeof item.listItemLabel === 'undefined' ? item.label : item.listItemLabel
2787
- }}></span>
2788
- </button>
2789
-
2790
- }
2791
-
2792
-
2793
- }) : null}
2794
- {/* /OPTIONS LIST */}
2795
-
2796
- </div>
2797
- </div>
2798
-
2799
-
2800
- </div>
2801
-
2802
- </RootPortal>
2803
-
2804
- </> : null}
2805
-
2806
-
2807
-
2808
-
2809
- </div>
2810
-
2811
-
2812
- </>
2813
- )
2814
- });
2815
-
2816
- export default Select;