@eturnity/eturnity_reusable_components 7.48.1-EPDM-12680.2 → 7.48.1-EPDM-11314.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (375) hide show
  1. package/README.md +29 -29
  2. package/package.json +85 -85
  3. package/src/App.vue +30 -30
  4. package/src/Test.vue +128 -128
  5. package/src/assets/icons/arrow_down.svg +3 -3
  6. package/src/assets/icons/arrow_up_red.svg +3 -3
  7. package/src/assets/icons/black_spinner.svg +35 -35
  8. package/src/assets/icons/delete_icon.svg +11 -11
  9. package/src/assets/icons/delete_icon_gray.svg +11 -11
  10. package/src/assets/icons/drag_icon.svg +8 -8
  11. package/src/assets/icons/external_icon.svg +6 -6
  12. package/src/assets/icons/language_icon.svg +6 -6
  13. package/src/assets/icons/pdf_icon.svg +6 -6
  14. package/src/assets/icons/plus_button.svg +4 -4
  15. package/src/assets/icons/search_icon_black.svg +3 -3
  16. package/src/assets/icons/subposition_icon.svg +3 -3
  17. package/src/assets/icons/subposition_marker.svg +3 -3
  18. package/src/assets/icons/warning_icon.svg +3 -3
  19. package/src/assets/svgIcons/2d_active.svg +7 -7
  20. package/src/assets/svgIcons/2d_inactive.svg +8 -8
  21. package/src/assets/svgIcons/3d_active.svg +7 -7
  22. package/src/assets/svgIcons/3d_inactive.svg +8 -8
  23. package/src/assets/svgIcons/_readme.md +7 -7
  24. package/src/assets/svgIcons/accept.svg +5 -5
  25. package/src/assets/svgIcons/activate_panels_active.svg +22 -22
  26. package/src/assets/svgIcons/activate_panels_inactive.svg +20 -20
  27. package/src/assets/svgIcons/add_icon-1.svg +3 -3
  28. package/src/assets/svgIcons/add_icon.svg +4 -4
  29. package/src/assets/svgIcons/address_book.svg +3 -3
  30. package/src/assets/svgIcons/adjust_roof.svg +6 -6
  31. package/src/assets/svgIcons/after_sale_as_a_service.svg +6 -6
  32. package/src/assets/svgIcons/all_good.svg +3 -3
  33. package/src/assets/svgIcons/angle_active.svg +5 -5
  34. package/src/assets/svgIcons/angle_inactive.svg +4 -4
  35. package/src/assets/svgIcons/area_active.svg +11 -11
  36. package/src/assets/svgIcons/area_inactive.svg +26 -26
  37. package/src/assets/svgIcons/areas_tool.svg +14 -14
  38. package/src/assets/svgIcons/arrow_down.svg +3 -3
  39. package/src/assets/svgIcons/arrow_left.svg +4 -4
  40. package/src/assets/svgIcons/arrow_right.svg +4 -4
  41. package/src/assets/svgIcons/arrow_up.svg +3 -3
  42. package/src/assets/svgIcons/attachment.svg +3 -3
  43. package/src/assets/svgIcons/base_layer.svg +3 -3
  44. package/src/assets/svgIcons/battery.svg +3 -3
  45. package/src/assets/svgIcons/bell.svg +3 -3
  46. package/src/assets/svgIcons/bexio.svg +4 -4
  47. package/src/assets/svgIcons/bold.svg +3 -3
  48. package/src/assets/svgIcons/bom.svg +3 -3
  49. package/src/assets/svgIcons/bom_generation.svg +10 -10
  50. package/src/assets/svgIcons/bookmaker.svg +3 -3
  51. package/src/assets/svgIcons/bubble.svg +3 -3
  52. package/src/assets/svgIcons/bug.svg +5 -5
  53. package/src/assets/svgIcons/buildings.svg +55 -55
  54. package/src/assets/svgIcons/bullet_list.svg +8 -8
  55. package/src/assets/svgIcons/calendar.svg +7 -7
  56. package/src/assets/svgIcons/calendar_icon.svg +7 -7
  57. package/src/assets/svgIcons/call.svg +3 -3
  58. package/src/assets/svgIcons/camera.svg +3 -3
  59. package/src/assets/svgIcons/car.svg +3 -3
  60. package/src/assets/svgIcons/cart.svg +3 -3
  61. package/src/assets/svgIcons/charger_icon_white.svg +44 -44
  62. package/src/assets/svgIcons/checkbox.svg +3 -3
  63. package/src/assets/svgIcons/clear_formatting.svg +7 -7
  64. package/src/assets/svgIcons/clickable_info.svg +4 -4
  65. package/src/assets/svgIcons/clip.svg +3 -3
  66. package/src/assets/svgIcons/clock.svg +17 -17
  67. package/src/assets/svgIcons/clock_full.svg +3 -3
  68. package/src/assets/svgIcons/close_for_modals,_tool_tips.svg +4 -4
  69. package/src/assets/svgIcons/co_branding.svg +5 -5
  70. package/src/assets/svgIcons/collapse.svg +4 -4
  71. package/src/assets/svgIcons/collections.svg +3 -3
  72. package/src/assets/svgIcons/component_library.svg +7 -7
  73. package/src/assets/svgIcons/consumption_tariffs.svg +43 -43
  74. package/src/assets/svgIcons/context_menu-1.svg +6 -6
  75. package/src/assets/svgIcons/context_menu-2.svg +5 -5
  76. package/src/assets/svgIcons/context_menu.svg +5 -5
  77. package/src/assets/svgIcons/context_menu_tabs.svg +5 -5
  78. package/src/assets/svgIcons/cross.svg +4 -4
  79. package/src/assets/svgIcons/current_variant.svg +4 -4
  80. package/src/assets/svgIcons/dashboard.svg +3 -3
  81. package/src/assets/svgIcons/data_transfer.svg +3 -3
  82. package/src/assets/svgIcons/deadline.svg +4 -4
  83. package/src/assets/svgIcons/deal_flow.svg +5 -5
  84. package/src/assets/svgIcons/delete.svg +4 -4
  85. package/src/assets/svgIcons/delete_area_active.svg +16 -16
  86. package/src/assets/svgIcons/delete_area_inactive.svg +15 -15
  87. package/src/assets/svgIcons/direction_active-1.svg +12 -12
  88. package/src/assets/svgIcons/direction_active.svg +5 -5
  89. package/src/assets/svgIcons/direction_arrow.svg +4 -4
  90. package/src/assets/svgIcons/direction_inactive.svg +4 -4
  91. package/src/assets/svgIcons/dislike.svg +3 -3
  92. package/src/assets/svgIcons/distance_tool.svg +8 -8
  93. package/src/assets/svgIcons/distances_active.svg +9 -9
  94. package/src/assets/svgIcons/distances_inactive.svg +8 -8
  95. package/src/assets/svgIcons/distort_tool.svg +10 -10
  96. package/src/assets/svgIcons/distort_tool2.svg +16 -16
  97. package/src/assets/svgIcons/document.svg +3 -3
  98. package/src/assets/svgIcons/documents.svg +4 -4
  99. package/src/assets/svgIcons/downarrow.svg +3 -3
  100. package/src/assets/svgIcons/download.svg +4 -4
  101. package/src/assets/svgIcons/drag_icon.svg +8 -8
  102. package/src/assets/svgIcons/draggable_corner.svg +5 -5
  103. package/src/assets/svgIcons/draw_tool.svg +3 -3
  104. package/src/assets/svgIcons/duplicate-1.svg +8 -8
  105. package/src/assets/svgIcons/duplicate-2.svg +5 -5
  106. package/src/assets/svgIcons/duplicate.svg +4 -4
  107. package/src/assets/svgIcons/e-mobility_configurator.svg +6 -6
  108. package/src/assets/svgIcons/e_signature.svg +5 -5
  109. package/src/assets/svgIcons/edit_button.svg +3 -3
  110. package/src/assets/svgIcons/electricity_tariff.svg +3 -3
  111. package/src/assets/svgIcons/email.svg +3 -3
  112. package/src/assets/svgIcons/ems-1.svg +3 -3
  113. package/src/assets/svgIcons/ems.svg +3 -3
  114. package/src/assets/svgIcons/end_of_the_list.svg +5 -5
  115. package/src/assets/svgIcons/erase.svg +4 -4
  116. package/src/assets/svgIcons/external_icon.svg +5 -5
  117. package/src/assets/svgIcons/fav_icon.svg +4 -4
  118. package/src/assets/svgIcons/finance.svg +3 -3
  119. package/src/assets/svgIcons/financing_for_pv-1.svg +5 -5
  120. package/src/assets/svgIcons/financing_for_pv-2.svg +3 -3
  121. package/src/assets/svgIcons/financing_for_pv.svg +6 -6
  122. package/src/assets/svgIcons/finish-1.svg +4 -4
  123. package/src/assets/svgIcons/finish.svg +3 -3
  124. package/src/assets/svgIcons/flatten.svg +11 -11
  125. package/src/assets/svgIcons/flatten_roof.svg +20 -20
  126. package/src/assets/svgIcons/folder.svg +3 -3
  127. package/src/assets/svgIcons/free_technology.svg +5 -5
  128. package/src/assets/svgIcons/handle.svg +5 -5
  129. package/src/assets/svgIcons/heat_calc.svg +7 -7
  130. package/src/assets/svgIcons/height_equalize.svg +3 -3
  131. package/src/assets/svgIcons/height_snap.svg +3 -3
  132. package/src/assets/svgIcons/house.svg +3 -3
  133. package/src/assets/svgIcons/house_3d-1.svg +7 -7
  134. package/src/assets/svgIcons/house_3d.svg +7 -7
  135. package/src/assets/svgIcons/inclination.svg +2 -2
  136. package/src/assets/svgIcons/info.svg +3 -3
  137. package/src/assets/svgIcons/initial_situation.svg +3 -3
  138. package/src/assets/svgIcons/integrations.svg +3 -3
  139. package/src/assets/svgIcons/intro-tour-1.svg +3 -3
  140. package/src/assets/svgIcons/intro-tour.svg +3 -3
  141. package/src/assets/svgIcons/inverter-1.svg +5 -5
  142. package/src/assets/svgIcons/inverter.svg +3 -3
  143. package/src/assets/svgIcons/italic.svg +3 -3
  144. package/src/assets/svgIcons/key.svg +3 -3
  145. package/src/assets/svgIcons/lake.svg +29 -29
  146. package/src/assets/svgIcons/layers_close.svg +4 -4
  147. package/src/assets/svgIcons/layers_open.svg +4 -4
  148. package/src/assets/svgIcons/lead_marketplace.svg +6 -6
  149. package/src/assets/svgIcons/lead_provider.svg +4 -4
  150. package/src/assets/svgIcons/length_2d.svg +2 -2
  151. package/src/assets/svgIcons/length_3d.svg +4 -4
  152. package/src/assets/svgIcons/length_calculator.svg +2 -2
  153. package/src/assets/svgIcons/length_in_2d_active.svg +12 -12
  154. package/src/assets/svgIcons/length_in_2d_inctive.svg +13 -13
  155. package/src/assets/svgIcons/light_bulb.svg +3 -3
  156. package/src/assets/svgIcons/like.svg +3 -3
  157. package/src/assets/svgIcons/line_graph.svg +3 -3
  158. package/src/assets/svgIcons/local_subsidies.svg +18 -18
  159. package/src/assets/svgIcons/location.svg +3 -3
  160. package/src/assets/svgIcons/lock.svg +3 -3
  161. package/src/assets/svgIcons/logout.svg +3 -3
  162. package/src/assets/svgIcons/loop.svg +3 -3
  163. package/src/assets/svgIcons/low-vegetation.svg +37 -37
  164. package/src/assets/svgIcons/lunch.svg +4 -4
  165. package/src/assets/svgIcons/magic_tool.svg +6 -6
  166. package/src/assets/svgIcons/map_icon.svg +5 -5
  167. package/src/assets/svgIcons/map_settings.svg +3 -3
  168. package/src/assets/svgIcons/margin_tool.svg +4 -4
  169. package/src/assets/svgIcons/meeting.svg +6 -6
  170. package/src/assets/svgIcons/move_copy.svg +4 -4
  171. package/src/assets/svgIcons/new_area_inactive.svg +11 -11
  172. package/src/assets/svgIcons/next.svg +4 -4
  173. package/src/assets/svgIcons/normal-tg.svg +30 -30
  174. package/src/assets/svgIcons/normal-vegetation.svg +53 -53
  175. package/src/assets/svgIcons/not_equal_to.svg +3 -3
  176. package/src/assets/svgIcons/numbered_list.svg +6 -6
  177. package/src/assets/svgIcons/obstacle_tool.svg +8 -8
  178. package/src/assets/svgIcons/obstacle_tool_origin.svg +3 -3
  179. package/src/assets/svgIcons/offset_tool.svg +8 -8
  180. package/src/assets/svgIcons/open-tg.svg +21 -21
  181. package/src/assets/svgIcons/outline_tool.svg +11 -11
  182. package/src/assets/svgIcons/pan_tool.svg +12 -12
  183. package/src/assets/svgIcons/panels_tool.svg +8 -8
  184. package/src/assets/svgIcons/pen_tool.svg +4 -4
  185. package/src/assets/svgIcons/picker_tool.svg +4 -4
  186. package/src/assets/svgIcons/picture.svg +3 -3
  187. package/src/assets/svgIcons/pin.svg +5 -5
  188. package/src/assets/svgIcons/presentation.svg +3 -3
  189. package/src/assets/svgIcons/previous.svg +4 -4
  190. package/src/assets/svgIcons/profile-1.svg +4 -4
  191. package/src/assets/svgIcons/profile.svg +4 -4
  192. package/src/assets/svgIcons/profitability.svg +3 -3
  193. package/src/assets/svgIcons/project_analysis.svg +4 -4
  194. package/src/assets/svgIcons/project_settings.svg +4 -4
  195. package/src/assets/svgIcons/protected-tg.svg +47 -47
  196. package/src/assets/svgIcons/pv.svg +3 -3
  197. package/src/assets/svgIcons/quotations.svg +6 -6
  198. package/src/assets/svgIcons/redo.svg +6 -6
  199. package/src/assets/svgIcons/resizer.svg +5 -5
  200. package/src/assets/svgIcons/roof_layer.svg +3 -3
  201. package/src/assets/svgIcons/rotate_tool.svg +3 -3
  202. package/src/assets/svgIcons/rotate_view.svg +5 -5
  203. package/src/assets/svgIcons/ruler_tool.svg +3 -3
  204. package/src/assets/svgIcons/run_simulation.svg +3 -3
  205. package/src/assets/svgIcons/save.svg +3 -3
  206. package/src/assets/svgIcons/scaling_tool.svg +8 -8
  207. package/src/assets/svgIcons/sea.svg +34 -34
  208. package/src/assets/svgIcons/search.svg +3 -3
  209. package/src/assets/svgIcons/security.svg +3 -3
  210. package/src/assets/svgIcons/settings.svg +3 -3
  211. package/src/assets/svgIcons/show_in_a_new_tab.svg +12 -12
  212. package/src/assets/svgIcons/smartphone.svg +4 -4
  213. package/src/assets/svgIcons/solar_calc.svg +13 -13
  214. package/src/assets/svgIcons/sorting.svg +4 -4
  215. package/src/assets/svgIcons/split.svg +12 -12
  216. package/src/assets/svgIcons/start_of_the_list.svg +5 -5
  217. package/src/assets/svgIcons/strikethrough.svg +4 -4
  218. package/src/assets/svgIcons/subscriptions.svg +3 -3
  219. package/src/assets/svgIcons/subsidies-1.svg +5 -5
  220. package/src/assets/svgIcons/subsidies-2.svg +3 -3
  221. package/src/assets/svgIcons/subsidies.svg +3 -3
  222. package/src/assets/svgIcons/subtract_icon.svg +3 -3
  223. package/src/assets/svgIcons/suitcase.svg +3 -3
  224. package/src/assets/svgIcons/summer.svg +3 -3
  225. package/src/assets/svgIcons/template_icon_not_clickable.svg +6 -6
  226. package/src/assets/svgIcons/transfer.svg +4 -4
  227. package/src/assets/svgIcons/trim_tool.svg +4 -4
  228. package/src/assets/svgIcons/truck.svg +3 -3
  229. package/src/assets/svgIcons/underlined.svg +3 -3
  230. package/src/assets/svgIcons/undo.svg +6 -6
  231. package/src/assets/svgIcons/uparrow.svg +3 -3
  232. package/src/assets/svgIcons/update.svg +3 -3
  233. package/src/assets/svgIcons/upload_avatar-1.svg +12 -12
  234. package/src/assets/svgIcons/upload_avatar.svg +5 -5
  235. package/src/assets/svgIcons/upload_image.svg +8 -8
  236. package/src/assets/svgIcons/upload_image_tool.svg +7 -7
  237. package/src/assets/svgIcons/variants.svg +6 -6
  238. package/src/assets/svgIcons/vertical_tool.svg +3 -3
  239. package/src/assets/svgIcons/virtual_storage.svg +4 -4
  240. package/src/assets/svgIcons/warning.svg +4 -4
  241. package/src/assets/svgIcons/way.svg +5 -5
  242. package/src/assets/svgIcons/wifi.svg +3 -3
  243. package/src/assets/svgIcons/winter.svg +3 -3
  244. package/src/assets/svgIcons/workflow_template.svg +11 -11
  245. package/src/assets/tests/__mocks__/iconCache.js +1 -1
  246. package/src/assets/tests/__mocks__/svgMock.js +1 -1
  247. package/src/assets/tests/helpers.js +12 -12
  248. package/src/assets/theme.js +44 -44
  249. package/src/components/addNewButton/AddNewButton.stories.js +17 -17
  250. package/src/components/addNewButton/addNewButton.spec.js +23 -23
  251. package/src/components/addNewButton/index.vue +62 -62
  252. package/src/components/banner/actionBanner/ActionBanner.stories.js +45 -45
  253. package/src/components/banner/actionBanner/actionBanner.spec.js +76 -76
  254. package/src/components/banner/actionBanner/index.vue +86 -86
  255. package/src/components/banner/banner/Banner.stories.js +64 -64
  256. package/src/components/banner/banner/banner.spec.js +149 -149
  257. package/src/components/banner/banner/index.vue +205 -205
  258. package/src/components/banner/infoBanner/InfoBanner.spec.js +70 -70
  259. package/src/components/banner/infoBanner/InfoBanner.stories.js +42 -42
  260. package/src/components/banner/infoBanner/index.vue +97 -97
  261. package/src/components/buttons/buttonIcon/index.vue +145 -147
  262. package/src/components/buttons/closeButton/CloseButton.stories.js +25 -25
  263. package/src/components/buttons/closeButton/index.vue +62 -62
  264. package/src/components/buttons/mainButton/MainButton.stories.js +51 -51
  265. package/src/components/buttons/mainButton/index.vue +150 -158
  266. package/src/components/buttons/mainButton/mainButton.spec.js +35 -35
  267. package/src/components/card/Card.stories.js +79 -79
  268. package/src/components/card/card.spec.js +135 -135
  269. package/src/components/card/index.vue +116 -116
  270. package/src/components/collapsableInfoText/index.vue +127 -127
  271. package/src/components/deleteIcon/DeleteIcon.stories.js +29 -29
  272. package/src/components/deleteIcon/index.vue +78 -78
  273. package/src/components/draggableInputHandle/index.vue +46 -46
  274. package/src/components/dropdown/Dropdown.stories.js +53 -53
  275. package/src/components/dropdown/index.vue +138 -138
  276. package/src/components/errorMessage/index.vue +64 -64
  277. package/src/components/filter/filterSettings.vue +669 -669
  278. package/src/components/filter/index.vue +154 -154
  279. package/src/components/filter/parentDropdown.vue +91 -91
  280. package/src/components/icon/Icons.stories.js +41 -41
  281. package/src/components/icon/iconCache.mjs +23 -23
  282. package/src/components/icon/iconCollection.vue +82 -82
  283. package/src/components/icon/index.vue +140 -141
  284. package/src/components/iconWrapper/index.vue +179 -179
  285. package/src/components/infoCard/InfoCard.stories.js +144 -0
  286. package/src/components/infoCard/defaultProps.js +7 -0
  287. package/src/components/infoCard/index.vue +140 -67
  288. package/src/components/infoCard/infoCard.spec.js +56 -0
  289. package/src/components/infoText/index.vue +190 -190
  290. package/src/components/inputs/checkbox/Checkbox.stories.js +63 -63
  291. package/src/components/inputs/checkbox/checkbox.spec.js +109 -109
  292. package/src/components/inputs/checkbox/index.vue +225 -225
  293. package/src/components/inputs/inputNumber/InputNumber.stories.js +150 -150
  294. package/src/components/inputs/inputNumber/index.vue +789 -963
  295. package/src/components/inputs/inputNumberQuestion/index.vue +218 -218
  296. package/src/components/inputs/inputText/InputText.stories.js +70 -70
  297. package/src/components/inputs/inputText/index.vue +417 -438
  298. package/src/components/inputs/inputText/inputText.spec.js +588 -588
  299. package/src/components/inputs/radioButton/RadioButton.stories.js +77 -77
  300. package/src/components/inputs/radioButton/defaultProps.js +31 -33
  301. package/src/components/inputs/radioButton/index.vue +309 -330
  302. package/src/components/inputs/radioButton/radioButton.spec.js +269 -269
  303. package/src/components/inputs/searchInput/SearchInput.stories.js +66 -66
  304. package/src/components/inputs/searchInput/defaultProps.js +12 -12
  305. package/src/components/inputs/searchInput/index.vue +159 -159
  306. package/src/components/inputs/searchInput/searchInput.spec.js +64 -64
  307. package/src/components/inputs/select/index.vue +918 -950
  308. package/src/components/inputs/select/option/index.vue +156 -165
  309. package/src/components/inputs/select/select.stories.js +58 -58
  310. package/src/components/inputs/slider/index.vue +126 -126
  311. package/src/components/inputs/switchField/index.vue +254 -254
  312. package/src/components/inputs/textAreaInput/TextAreaInput.stories.js +127 -127
  313. package/src/components/inputs/textAreaInput/index.vue +198 -198
  314. package/src/components/inputs/toggle/Toggle.stories.js +77 -77
  315. package/src/components/inputs/toggle/index.vue +317 -317
  316. package/src/components/inputs/toggle/toggle.spec.js +102 -102
  317. package/src/components/label/index.vue +99 -99
  318. package/src/components/markerItem/index.vue +88 -95
  319. package/src/components/modals/actionModal/index.vue +64 -64
  320. package/src/components/modals/infoModal/index.vue +52 -52
  321. package/src/components/modals/modal/index.vue +196 -190
  322. package/src/components/modals/modal/modal.stories.js +31 -31
  323. package/src/components/navigationTabs/index.vue +114 -114
  324. package/src/components/pageSubtitle/PageSubtitle.stories.js +59 -59
  325. package/src/components/pageSubtitle/index.vue +78 -78
  326. package/src/components/pageSubtitle/pageSubtitle.spec.js +46 -46
  327. package/src/components/pageTitle/PageTitle.stories.js +95 -95
  328. package/src/components/pageTitle/index.vue +91 -91
  329. package/src/components/pageTitle/pageTitle.spec.js +46 -46
  330. package/src/components/pagination/index.vue +148 -148
  331. package/src/components/progressBar/index.vue +125 -125
  332. package/src/components/projectMarker/index.vue +300 -300
  333. package/src/components/rangeSlider/Slider.vue +573 -573
  334. package/src/components/rangeSlider/index.vue +517 -517
  335. package/src/components/rangeSlider/utils/dom.js +49 -49
  336. package/src/components/rangeSlider/utils/fns.js +26 -26
  337. package/src/components/roundTabs/index.vue +107 -107
  338. package/src/components/selectedOptions/index.vue +471 -471
  339. package/src/components/selectedOptions/selectedOptions.spec.js +176 -176
  340. package/src/components/selectedOptions/selectedOptions.stories.js +155 -155
  341. package/src/components/sideMenu/index.vue +270 -270
  342. package/src/components/spinner/Spinner.stories.js +34 -34
  343. package/src/components/spinner/index.vue +85 -96
  344. package/src/components/spinner/spinner.spec.js +69 -69
  345. package/src/components/tableDropdown/index.vue +638 -638
  346. package/src/components/tables/mainTable/exampleNested.vue +328 -328
  347. package/src/components/tables/mainTable/index.vue +510 -510
  348. package/src/components/tables/viewTable/index.vue +195 -195
  349. package/src/components/tabsHeader/index.vue +83 -83
  350. package/src/components/threeDots/index.vue +413 -413
  351. package/src/components/videoThumbnail/index.vue +103 -103
  352. package/src/components/videoThumbnail/videoThumbnail.stories.js +33 -33
  353. package/src/helpers/currencyMapping.js +28 -28
  354. package/src/helpers/numberConverter.js +103 -103
  355. package/src/helpers/translateLang.js +128 -128
  356. package/src/main.js +7 -7
  357. package/src/mixins/inputValidations.js +97 -97
  358. package/src/router/dynamicRoutes.js +23 -23
  359. package/src/stories/Button.stories.js +48 -48
  360. package/src/stories/Button.vue +52 -52
  361. package/src/stories/Configure.mdx +364 -364
  362. package/src/stories/Header.stories.js +41 -41
  363. package/src/stories/Header.vue +59 -59
  364. package/src/stories/Page.stories.js +30 -30
  365. package/src/stories/Page.vue +83 -83
  366. package/src/stories/button.css +30 -30
  367. package/src/stories/header.css +32 -32
  368. package/src/stories/page.css +69 -69
  369. package/src/utils/index.js +12 -12
  370. package/src/assets/svgIcons/collapse_all.svg +0 -4
  371. package/src/assets/svgIcons/hybrid.svg +0 -4
  372. package/src/assets/svgIcons/module.svg +0 -3
  373. package/src/assets/svgIcons/optimizer.svg +0 -6
  374. package/src/assets/svgIcons/string_design.svg +0 -5
  375. package/src/components/stringDesign/DropdownMenu/index.vue +0 -417
@@ -1,950 +1,918 @@
1
- <template>
2
- <Container
3
- :no-relative="noRelative"
4
- :select-width="selectWidth"
5
- @mouseenter="mouseEnterHandler"
6
- @mouseleave="mouseLeaveHandler"
7
- >
8
- <InputWrapper
9
- :align-items="alignItems"
10
- :has-label="!!label && label.length > 0"
11
- :no-relative="noRelative"
12
- >
13
- <LabelWrapper
14
- v-if="label"
15
- :data-id="labelDataId"
16
- :info-text-message="!!infoTextMessage || !!$slots.infoText"
17
- >
18
- <InputLabel
19
- :font-color="
20
- labelFontColor || colorMode == 'dark' || colorMode == 'transparent'
21
- ? 'white'
22
- : 'eturnityGrey'
23
- "
24
- :font-size="fontSize"
25
- >{{ label }}
26
- <OptionalLabel v-if="labelOptional">
27
- ({{ $gettext('Optional') }})</OptionalLabel
28
- >
29
- </InputLabel>
30
- <InfoText
31
- v-if="infoTextMessage || !!$slots.infoText"
32
- :align-arrow="infoTextAlignArrow"
33
- :max-width="infoTextWidth"
34
- :size="infoTextSize"
35
- :text="infoTextMessage"
36
- :width="infoTextWidth"
37
- >
38
- <slot name="infoText"></slot>
39
- </InfoText>
40
- </LabelWrapper>
41
- <SelectButtonWrapper :disabled="disabled">
42
- <SelectButton
43
- ref="select"
44
- :bg-color="
45
- buttonBgColor || colorMode == 'dark'
46
- ? 'transparentBlack1'
47
- : colorMode == 'transparent'
48
- ? 'transparent'
49
- : 'white'
50
- "
51
- class="select-button"
52
- :color-mode="colorMode"
53
- :data-id="dataId"
54
- :disabled="disabled"
55
- :font-color="
56
- buttonFontColor || colorMode == 'dark' || colorMode == 'transparent'
57
- ? 'white'
58
- : 'black'
59
- "
60
- :font-size="fontSize"
61
- :has-error="hasError"
62
- :has-no-padding="isSearchBarVisible || !hasSelectButtonPadding"
63
- :height="height"
64
- :is-search-bar-visible="isSearchBarVisible"
65
- :no-relative="noRelative"
66
- :padding-left="paddingLeft"
67
- :select-height="selectHeight"
68
- :select-min-height="selectMinHeight"
69
- :select-width="selectWidth"
70
- :show-border="showBorder"
71
- :show-disabled-background="showDisabledBackground"
72
- :table-padding-left="tablePaddingLeft"
73
- @click="toggleDropdown"
74
- @keydown="onKeyDown"
75
- >
76
- <DraggableInputHandle
77
- v-if="isDraggable && !isSearchBarVisible"
78
- :height="selectHeight"
79
- />
80
- <InputText
81
- v-if="isSearchBarVisible"
82
- ref="searchInput"
83
- background-color="transparent"
84
- :font-color="
85
- buttonFontColor ||
86
- colorMode == 'dark' ||
87
- colorMode == 'transparent'
88
- ? 'white'
89
- : 'black'
90
- "
91
- :font-size="fontSize"
92
- input-height="34px"
93
- :input-width="computedWidth"
94
- :no-border="true"
95
- tabindex="0"
96
- :value="textSearch"
97
- @click.stop
98
- @input-change="searchChange"
99
- @keydown.stop="onKeyDown"
100
- />
101
- <Selector
102
- v-else
103
- :padding-left="paddingLeft"
104
- :select-width="selectWidth"
105
- :show-border="showBorder"
106
- >
107
- <slot name="selector" :selected-value="selectedValue"></slot>
108
- </Selector>
109
- <Caret
110
- class="caret_dropdown"
111
- :color-mode="colorMode"
112
- @click.stop="toggleCaretDropdown"
113
- >
114
- <Icon
115
- v-if="isDropdownOpen"
116
- :color="
117
- caretColor || colorMode == 'dark' || colorMode == 'transparent'
118
- ? 'white'
119
- : 'transparentBlack1'
120
- "
121
- name="arrow_up"
122
- :size="colorMode === 'transparent' ? '8px' : '12px'"
123
- />
124
- <Icon
125
- v-else
126
- :color="
127
- caretColor || colorMode == 'dark' || colorMode == 'transparent'
128
- ? 'white'
129
- : 'transparentBlack1'
130
- "
131
- name="arrow_down"
132
- :size="colorMode === 'transparent' ? '8px' : '12px'"
133
- />
134
- </Caret>
135
- </SelectButton>
136
- <DropdownWrapper ref="dropdownWrapperRef" :no-relative="noRelative">
137
- <Teleport to="#portal-target">
138
- <SelectDropdown
139
- v-show="isSelectDropdownShown"
140
- ref="dropdown"
141
- :bg-color="
142
- dropdownBgColor ||
143
- colorMode == 'dark' ||
144
- colorMode == 'transparent'
145
- ? 'black'
146
- : 'white'
147
- "
148
- :dropdown-position="dropdownPosition"
149
- :font-color="
150
- dropdownFontColor ||
151
- colorMode == 'dark' ||
152
- colorMode == 'transparent'
153
- ? 'white'
154
- : 'black'
155
- "
156
- :font-size="fontSize"
157
- :hovered-bg-color="
158
- colorMode == 'dark'
159
- ? '#000000'
160
- : colorMode == 'transparent'
161
- ? 'grey6'
162
- : dropdownBgColor
163
- "
164
- :hovered-index="hoveredIndex"
165
- :hovered-value="hoveredValue"
166
- :is-active="isActive"
167
- :min-width="minWidth"
168
- :no-relative="noRelative"
169
- :option-width="getOptionWidth"
170
- :selected-value="selectedValue"
171
- @mouseleave="optionLeave"
172
- @option-hovered="optionHovered"
173
- @option-selected="optionSelected"
174
- >
175
- <slot name="dropdown"></slot>
176
- </SelectDropdown>
177
- </Teleport>
178
- </DropdownWrapper>
179
- </SelectButtonWrapper>
180
- </InputWrapper>
181
- </Container>
182
- </template>
183
-
184
- <script>
185
- //How to use it
186
- // <Select
187
- // hoverDropdown="true"
188
- // selectWidth="100%"
189
- // minWidth="220px"
190
- // optionWidth="50%"
191
- // label="that is a label"
192
- // alignItems="vertical"
193
- // label-data-id="test-label-data-id"
194
- // data-id="test-data-id"
195
- // :hasSelectButtonPadding="false"
196
- // >
197
- // <template #selector="{selectedValue}">
198
- // value selected: {{selectedValue}}
199
- // </template>
200
- // <template #dropdown>
201
- // <Option value="1">value one</Option>
202
- // <Option value="2">value two</Option>
203
- // <Option value="3">value three</Option>
204
- // <Option value="4">value four</Option>
205
- // </template>
206
- // </Select>
207
-
208
- import { Teleport } from 'vue'
209
- import styled from 'vue3-styled-components'
210
- import InfoText from '../../infoText'
211
- import Icon from '../../icon'
212
- import InputText from '../inputText'
213
- import DraggableInputHandle from '../../draggableInputHandle'
214
- import { debounce } from '../../../utils'
215
-
216
- const CARET_WIDTH = '30px'
217
- const BORDER_WIDTH = '1px'
218
-
219
- const CaretAttrs = { colorMode: String }
220
- const Caret = styled('div', CaretAttrs)`
221
- display: flex;
222
- align-items: center;
223
- justify-content: center;
224
- width: ${(props) =>
225
- props.colorMode === 'transparent' ? '15px' : CARET_WIDTH};
226
- min-width: ${(props) =>
227
- props.colorMode === 'transparent' ? '15px' : CARET_WIDTH};
228
- height: 100%;
229
- align-items: center;
230
- cursor: pointer;
231
- margin-left: auto;
232
- `
233
-
234
- const selectorProps = {
235
- selectWidth: String,
236
- paddingLeft: String,
237
- showBorder: Boolean,
238
- }
239
- const Selector = styled('div', selectorProps)`
240
- ${(props) =>
241
- props.selectWidth === '100%'
242
- ? 'width: 100%;'
243
- : `width: calc(${props.selectWidth} -
244
- (
245
- ${CARET_WIDTH} +
246
- ${props.paddingLeft}
247
- ${props.showBorder ? `+ (${BORDER_WIDTH} * 2)` : ''}
248
- )
249
- );
250
- white-space: nowrap;
251
- text-overflow: ellipsis;
252
- overflow: hidden;`}
253
- `
254
-
255
- const labelAttrs = { fontSize: String, fontColor: String }
256
- const InputLabel = styled('div', labelAttrs)`
257
- color: ${(props) =>
258
- props.theme.colors[props.fontColor]
259
- ? props.theme.colors[props.fontColor]
260
- : props.fontColor};
261
- font-size: ${(props) => props.fontSize};
262
- font-weight: 700;
263
- `
264
- const OptionalLabel = styled.span`
265
- font-weight: 300;
266
- text-transform: lowercase;
267
- `
268
- const inputProps = {
269
- selectWidth: String,
270
- optionWidth: String,
271
- noRelative: Boolean,
272
- }
273
- const Container = styled('div', inputProps)`
274
- width: ${(props) => props.selectWidth};
275
- position: ${(props) => (props.noRelative ? 'static' : 'relative')};
276
- display: inline-block;
277
- `
278
-
279
- const LabelWrapperAttrs = { infoTextMessage: Boolean }
280
- const LabelWrapper = styled('div', LabelWrapperAttrs)`
281
- display: inline-grid;
282
- grid-template-columns: ${(props) =>
283
- props.infoTextMessage ? 'auto auto' : 'auto'};
284
- grid-gap: 12px;
285
- align-items: center;
286
- justify-content: start;
287
- `
288
-
289
- const SelectButtonWrapperAttrs = {
290
- disabled: Boolean,
291
- }
292
- const SelectButtonWrapper = styled('div', SelectButtonWrapperAttrs)`
293
- ${(props) => (props.disabled ? 'cursor: not-allowed' : 'cursor: pointer')};
294
- `
295
-
296
- const selectButtonAttrs = {
297
- bgColor: String,
298
- fontColor: String,
299
- hasError: Boolean,
300
- disabled: Boolean,
301
- selectHeight: String,
302
- selectWidth: String,
303
- height: String,
304
- selectMinHeight: String,
305
- hasNoPadding: Boolean,
306
- showBorder: Boolean,
307
- paddingLeft: String,
308
- noRelative: Boolean,
309
- tablePaddingLeft: String,
310
- showDisabledBackground: Boolean,
311
- colorMode: String,
312
- isSearchBarVisible: Boolean,
313
- }
314
- const SelectButton = styled('div', selectButtonAttrs)`
315
- position: ${(props) => (props.noRelative ? 'static' : 'relative')};
316
- box-sizing: border-box;
317
- border-radius: 4px;
318
- max-width: ${(props) => (props.selectWidth ? props.selectWidth : '100%')};
319
- ${(props) =>
320
- props.colorMode === 'transparent'
321
- ? props.isSearchBarVisible
322
- ? 'padding: 10px 15px 10px 5px;'
323
- : 'padding: 10px 15px;'
324
- : props.isSearchBarVisible
325
- ? ''
326
- : `padding-left: ${
327
- props.hasNoPadding
328
- ? '0'
329
- : props.tablePaddingLeft
330
- ? props.tablePaddingLeft
331
- : props.paddingLeft
332
- }`};
333
- text-align: left;
334
- min-height: ${(props) =>
335
- props.selectHeight
336
- ? props.selectHeight
337
- : props.selectMinHeight
338
- ? props.selectMinHeight
339
- : props.height
340
- ? props.height
341
- : '36px'};
342
- display: flex;
343
- align-items: center;
344
- height: ${(props) => props.selectHeight};
345
- ${({ showBorder, theme, hasError }) =>
346
- showBorder &&
347
- `
348
- border: ${BORDER_WIDTH} solid ${
349
- hasError ? theme.colors.red : theme.colors.grey4
350
- }
351
- `}
352
- background-color:${(props) =>
353
- props.disabled && props.showDisabledBackground
354
- ? props.theme.colors.grey5
355
- : props.theme.colors[props.bgColor]
356
- ? props.theme.colors[props.bgColor]
357
- : props.bgColor};
358
- color: ${(props) =>
359
- props.theme.colors[props.fontColor]
360
- ? props.theme.colors[props.fontColor]
361
- : props.fontColor};
362
- ${(props) => (props.disabled ? 'pointer-events: none' : '')};
363
- overflow: hidden;
364
- & > .handle {
365
- border-right: ${(props) =>
366
- props.hasError ? props.theme.colors.red : props.theme.colors.grey4}
367
- 1px solid;
368
- }
369
- `
370
- const selectDropdownAttrs = {
371
- hoveredBgColor: String,
372
- bgColor: String,
373
- fontColor: String,
374
- optionWidth: String,
375
- hoveredIndex: Number,
376
- fontSize: String,
377
- dropdownPosition: Object,
378
- hoveredValue: Number | String,
379
- selectedValue: Number | String,
380
- noRelative: Boolean,
381
- minWidth: String,
382
- }
383
- const SelectDropdown = styled('div', selectDropdownAttrs)`
384
- box-sizing: border-box;
385
- z-index: ${(props) => (props.isActive ? '2' : '99999')};
386
- position: absolute;
387
- top: ${(props) =>
388
- props.noRelative ? 'auto' : props.dropdownPosition?.top + 'px'};
389
- left: ${(props) => props.dropdownPosition?.left}px;
390
- border: ${BORDER_WIDTH} solid ${(props) => props.theme.colors.grey4};
391
- border-radius: 4px;
392
- display: flex;
393
- flex-direction: column;
394
- align-items: flex-start;
395
- padding: 0px;
396
- box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
397
- width: ${(props) => (props.optionWidth ? props.optionWidth : '100%')};
398
- min-width: ${(props) =>
399
- props.minWidth
400
- ? props.minWidth
401
- : props.optionWidth
402
- ? props.optionWidth
403
- : '100%'};
404
- background-color: ${(props) =>
405
- props.theme.colors[props.bgColor]
406
- ? props.theme.colors[props.bgColor]
407
- : props.bgColor};
408
- color: ${(props) =>
409
- props.theme.colors[props.fontColor]
410
- ? props.theme.colors[props.fontColor]
411
- : props.fontColor};
412
- max-height: 300px;
413
- overflow-y: auto;
414
- & > div[data-value='${(props) => props.hoveredValue}'] {
415
- background-color: ${(props) =>
416
- props.theme.colors[props.hoveredBgColor]
417
- ? props.theme.colors[props.hoveredBgColor]
418
- : props.hoveredBgColor};
419
- }
420
- font-size: ${(props) => props.fontSize};
421
- `
422
- SelectDropdown.emits = ['option-hovered', 'option-selected']
423
- const DropdownAttrs = { noRelative: Boolean }
424
- const DropdownWrapper = styled('div', DropdownAttrs)`
425
- position: ${(props) => (props.noRelative ? 'static' : 'relative')};
426
- `
427
- const inputAttrs = {
428
- alignItems: String,
429
- hasLabel: Boolean,
430
- noRelative: Boolean,
431
- }
432
- const InputWrapper = styled('div', inputAttrs)`
433
- position: ${(props) => (props.noRelative ? 'static' : 'relative')};
434
- display: grid;
435
- width: 100%;
436
- min-width: ${(props) => (props.minWidth ? props.minWidth : '150px')};
437
- align-items: center;
438
- gap: 8px;
439
- grid-template-columns: ${(props) =>
440
- props.alignItems === 'vertical' || !props.hasLabel ? '1fr' : 'auto 1fr'};
441
- `
442
-
443
- const DROPDOWN_HEIGHT_OFFSET = 4
444
- const DROPDOWN_TOP_OFFSET = 21
445
- const MIN_OPTION_LENGTH = 5
446
-
447
- const DROPDOWN_MENU_POSITIONS = {
448
- Automatic: 'automatic',
449
- Bottom: 'bottom',
450
- }
451
-
452
- export default {
453
- name: 'RCselect',
454
-
455
- components: {
456
- SelectButton,
457
- SelectButtonWrapper,
458
- SelectDropdown,
459
- Container,
460
- InputLabel,
461
- LabelWrapper,
462
- OptionalLabel,
463
- InfoText,
464
- InputWrapper,
465
- DropdownWrapper,
466
- Icon,
467
- Caret,
468
- Selector,
469
- InputText,
470
- Teleport,
471
- DraggableInputHandle,
472
- },
473
-
474
- props: {
475
- value: {
476
- required: false,
477
- default: null,
478
- },
479
- fontSize: {
480
- required: false,
481
- default: '13px',
482
- },
483
- noRelative: {
484
- required: false,
485
- default: false,
486
- },
487
- label: {
488
- required: false,
489
- },
490
- labelOptional: {
491
- required: false,
492
- default: false,
493
- },
494
- labelDataId: {
495
- required: false,
496
- default: '',
497
- },
498
- infoTextMessage: {
499
- required: false,
500
- },
501
- selectWidth: {
502
- type: String,
503
- required: false,
504
- default: '100%',
505
- },
506
- minWidth: {
507
- required: false,
508
- },
509
- maxWidth: {
510
- required: false,
511
- },
512
- selectHeight: {
513
- type: String,
514
- required: false,
515
- default: null,
516
- },
517
- height: {
518
- required: false,
519
- default: null,
520
- },
521
- selectMinHeight: {
522
- required: false,
523
- default: '36px',
524
- },
525
- optionWidth: {
526
- required: false,
527
- default: null,
528
- },
529
- hoverDropdown: {
530
- required: false,
531
- default: false,
532
- },
533
- dropdownAutoClose: {
534
- required: false,
535
- default: false,
536
- },
537
- alignItems: {
538
- required: false,
539
- default: 'horizontal',
540
- },
541
- buttonBgColor: {
542
- required: false,
543
- },
544
- buttonFontColor: {
545
- required: false,
546
- },
547
- dropdownBgColor: {
548
- required: false,
549
- default: 'grey5',
550
- },
551
- dropdownFontColor: {
552
- required: false,
553
- },
554
- dropDownArrowVisible: {
555
- required: false,
556
- default: true,
557
- },
558
- caretColor: {
559
- required: false,
560
- },
561
- labelFontColor: {
562
- required: false,
563
- },
564
- colorMode: {
565
- required: false,
566
- default: 'light',
567
- },
568
- isSearchable: {
569
- required: false,
570
- default: true,
571
- },
572
- hasError: {
573
- required: false,
574
- default: false,
575
- },
576
- disabled: {
577
- required: false,
578
- default: false,
579
- },
580
- isAutoSearch: {
581
- required: false,
582
- default: true,
583
- },
584
- showBorder: {
585
- required: false,
586
- default: true,
587
- },
588
- infoTextSize: {
589
- required: false,
590
- default: '14px',
591
- },
592
- dataId: {
593
- type: String,
594
- default: '',
595
- },
596
- hasSelectButtonPadding: {
597
- required: false,
598
- type: Boolean,
599
- default: true,
600
- },
601
- isDraggable: {
602
- type: Boolean,
603
- default: false,
604
- },
605
- leftPadding: {
606
- type: String,
607
- default: '15px',
608
- },
609
- tablePaddingLeft: {
610
- required: false,
611
- },
612
- showDisabledBackground: {
613
- required: false,
614
- default: true,
615
- },
616
- minOptionLength: {
617
- type: Number,
618
- default: MIN_OPTION_LENGTH,
619
- },
620
- dropdownMenuPosition: {
621
- type: String,
622
- default: DROPDOWN_MENU_POSITIONS.Automatic, // options: ['automatic', bottom]
623
- },
624
- infoTextWidth: {
625
- type: String,
626
- required: false,
627
- },
628
- infoTextAlignArrow: {
629
- type: String,
630
- required: false,
631
- },
632
- },
633
-
634
- data() {
635
- return {
636
- selectedValue: null,
637
- paddingLeft: this.isDraggable ? '30px' : this.leftPadding,
638
- isDropdownOpen: false,
639
- isActive: false,
640
- textSearch: '',
641
- hoveredIndex: 0,
642
- isClickOutsideActive: false,
643
- dropdownPosition: {
644
- left: null,
645
- top: null,
646
- },
647
- dropdownWidth: null,
648
- hoveredValue: null,
649
- }
650
- },
651
- computed: {
652
- optionLength() {
653
- if (this.isDropdownOpen) {
654
- return this.$refs.dropdown.$el.childElementCount > 1
655
- ? this.$refs.dropdown.$el.childElementCount
656
- : this.$refs.dropdown.$el.children[0]
657
- ? this.$refs.dropdown.$el.children[0].childElementCount
658
- : 0
659
- }
660
-
661
- return 0
662
- },
663
- isSearchBarVisible() {
664
- return (
665
- this.isSearchable &&
666
- this.optionLength >= this.minOptionLength &&
667
- this.isDropdownOpen
668
- )
669
- },
670
- computedWidth() {
671
- function removePX(item) {
672
- return Number(item.replace('px', ''))
673
- }
674
-
675
- return this.selectWidth === '100%'
676
- ? '100%'
677
- : removePX(this.selectWidth) - removePX(CARET_WIDTH) + 'px'
678
- },
679
- getOptionWidth() {
680
- if (this.optionWidth) return this.optionWidth
681
-
682
- return this.dropdownWidth
683
- },
684
- isSelectDropdownShown() {
685
- return (
686
- this.isDropdownOpen &&
687
- this.dropdownPosition.left !== null &&
688
- (!this.isSearchable || this.isSearchable)
689
- )
690
- },
691
- isMobileDevice() {
692
- const userAgent =
693
- navigator.userAgent || navigator.vendor || window.opera
694
- const touchCapable =
695
- 'ontouchstart' in window ||
696
- navigator.maxTouchPoints > 0 ||
697
- navigator.msMaxTouchPoints > 0
698
-
699
- return (
700
- /Android/i.test(userAgent) ||
701
- /iPad|iPhone|iPod/.test(userAgent) ||
702
- (/Macintosh/.test(userAgent) && touchCapable) ||
703
- /windows phone/i.test(userAgent)
704
- )
705
- },
706
- },
707
- watch: {
708
- value(val) {
709
- this.selectedValue = val
710
- },
711
- async isDropdownOpen(val) {
712
- if (val) {
713
- this.$emit('on-dropdown-open')
714
- setTimeout(() => {
715
- this.isClickOutsideActive = true
716
- }, 10)
717
- await this.$nextTick()
718
- this.handleSetDropdownOffet()
719
- } else {
720
- this.dropdownPosition.left = null
721
- setTimeout(() => {
722
- this.isClickOutsideActive = false
723
- }, 10)
724
- }
725
- if (val && this.isSearchable) {
726
- this.$nextTick(() => {
727
- if (this.$refs.searchInput && !this.isMobileDevice) {
728
- this.$refs.searchInput.$el.querySelector('input').focus()
729
- }
730
- })
731
- }
732
- },
733
- },
734
- mounted() {
735
- this.observeDropdownHeight()
736
- this.observeSelectWidth()
737
- window.addEventListener('resize', this.handleSetDropdownOffet)
738
- },
739
- beforeMount() {
740
- this.selectedValue = this.value
741
- document.addEventListener('click', this.clickOutside)
742
- this.getDropdownPosition()
743
- window.removeEventListener('resize', this.handleSetDropdownOffet)
744
- if (this.dropdownResizeObserver) this.dropdownResizeObserver.disconnect()
745
- if (this.selectResizeObserver) this.selectResizeObserver.disconnect()
746
- },
747
- unmounted() {
748
- document.removeEventListener('click', this.clickOutside)
749
- },
750
- methods: {
751
- focus() {
752
- this.isActive = true
753
- },
754
- blur(e) {
755
- this.isActive = false
756
- this.$emit('blur', e)
757
- },
758
- toggleDropdown() {
759
- this.isDropdownOpen = !this.isDropdownOpen
760
- },
761
- toggleCaretDropdown() {
762
- this.isDropdownOpen = !this.isDropdownOpen
763
- },
764
- closeDropdown() {
765
- this.blur()
766
- this.clearSearch()
767
- this.isDropdownOpen = false
768
- },
769
- clearSearch() {
770
- this.textSearch = ''
771
- this.searchChange('')
772
- },
773
- optionSelected(e) {
774
- this.selectedValue = e
775
- this.closeDropdown()
776
- this.blur()
777
- this.$emit('input-change', e)
778
- },
779
- optionHovered: debounce(function (e) {
780
- this.hoveredValue = e
781
- }, 300),
782
- mouseEnterHandler() {
783
- if (this.hoverDropdown) {
784
- this.focus()
785
- this.isDropdownOpen = true
786
- }
787
- },
788
- mouseLeaveHandler() {
789
- if (this.hoverDropdown) {
790
- this.blur()
791
- }
792
- },
793
- optionLeave() {
794
- if (this.dropdownAutoClose) {
795
- this.isDropdownOpen = false
796
- }
797
- },
798
- searchChange(value) {
799
- this.textSearch = value
800
- this.$emit('search-change', value)
801
- const dropdownChildren = [...this.$refs.dropdown.$el.children]
802
- dropdownChildren.forEach((el) => {
803
- if (!el.textContent.toLowerCase().includes(value.toLowerCase())) {
804
- el.style.display = 'none'
805
-
806
- return
807
- }
808
-
809
- el.style.display = 'inherit'
810
- })
811
- },
812
- clickOutside(event) {
813
- const dropdownRef = this.$refs.dropdown
814
- // we need to prevent closing on selecting an option, because in the case of
815
- // a disabled option, we don't want to close the dropdown
816
- if (!this.isClickOutsideActive) return
817
- if (
818
- this.$refs.select.$el == event.target ||
819
- this.$refs.select.$el.contains(event.target) ||
820
- event.target.id === 'more-button' ||
821
- event.target.parentNode === dropdownRef.$el
822
- ) {
823
- return
824
- } else {
825
- this.closeDropdown()
826
- }
827
- },
828
- onKeyDown(e) {
829
- if (e.key == 'ArrowDown') {
830
- this.onArrowPress(1)
831
- } else if (e.key == 'ArrowUp') {
832
- this.onArrowPress(-1)
833
- } else if (e.key == 'Enter') {
834
- const optionHoveredComponent = [...this.$refs.dropdown.$el.children][
835
- (this.hoveredIndex - 1 + this.optionLength) % this.optionLength
836
- ]
837
- this.optionSelected(optionHoveredComponent.$el.dataset.value)
838
- }
839
- },
840
- // If some part of the dropdown menu is outside viewport of the bottom of the screen,
841
- // we need to offset it and display it at the top of the select dropdown instead
842
- async getDropdownPosition() {
843
- if (
844
- !this.$refs.dropdownWrapperRef ||
845
- !this.$refs.select ||
846
- !this.$refs.dropdown
847
- ) {
848
- return
849
- }
850
- await this.$nextTick()
851
- const isDisplayedAtBottom = await this.generateDropdownPosition()
852
- // If the dropdown menu is going to be displayed at the bottom,
853
- // we need reverify its position after a dom update (nextTick)
854
- await this.$nextTick()
855
- if (isDisplayedAtBottom) this.generateDropdownPosition()
856
- },
857
- async generateDropdownPosition() {
858
- const isDropdownNotCompletelyVisible =
859
- await this.isBottomOfDropdownOutOfViewport()
860
- const dropdownWrapperEl = this.$refs.dropdownWrapperRef.$el
861
- const selectButtonHeight = this.$refs.select.$el.clientHeight
862
- const dropdownHeight = this.$refs.dropdown.$el.clientHeight
863
- const dropdownWrapperRelativeHeight =
864
- dropdownWrapperEl.getBoundingClientRect().top +
865
- window.scrollY +
866
- DROPDOWN_HEIGHT_OFFSET
867
-
868
- const top =
869
- isDropdownNotCompletelyVisible ||
870
- (!isDropdownNotCompletelyVisible &&
871
- this.dropdownMenuPosition === DROPDOWN_MENU_POSITIONS.Bottom)
872
- ? dropdownWrapperRelativeHeight
873
- : dropdownWrapperRelativeHeight -
874
- dropdownHeight -
875
- selectButtonHeight -
876
- DROPDOWN_TOP_OFFSET
877
- const left = this.dropdownPosition.left
878
- ? this.dropdownPosition.left
879
- : dropdownWrapperEl.getBoundingClientRect().left + window.scrollX
880
-
881
- this.dropdownPosition = { left: Math.floor(left), top: Math.floor(top) }
882
-
883
- return isDropdownNotCompletelyVisible
884
- },
885
- async isBottomOfDropdownOutOfViewport() {
886
- if (
887
- !this.$refs.dropdown ||
888
- this.dropdownMenuPosition === DROPDOWN_MENU_POSITIONS.Bottom
889
- ) {
890
- return false
891
- }
892
-
893
- await this.$nextTick()
894
- const rect = this.$refs.dropdown.$el.getBoundingClientRect()
895
- const windowHeight =
896
- window.innerHeight || document.documentElement.clientHeight
897
-
898
- if (windowHeight <= 650) return true
899
-
900
- // using Math.floor because the offsets may contain decimals we are not going to consider here
901
- return Math.floor(rect.top) + Math.floor(rect.height) <= windowHeight
902
- },
903
- observeDropdownHeight() {
904
- if (!this.$refs.dropdown) return
905
- this.dropdownResizeObserver = new ResizeObserver(() => {
906
- this.$nextTick(() => this.getDropdownPosition())
907
- })
908
- this.dropdownResizeObserver.observe(this.$refs.dropdown.$el)
909
- },
910
- handleSetDropdownOffet() {
911
- if (!this.$refs.select) return
912
- this.dropdownPosition.left = Math.floor(
913
- this.$refs.select.$el.getBoundingClientRect().left
914
- )
915
- this.getDropdownWidth()
916
- },
917
- observeSelectWidth() {
918
- if (!this.$refs.select) return
919
- this.selectResizeObserver = new ResizeObserver(() =>
920
- // eslint-disable-next-line vue/valid-next-tick
921
- this.$nextTick(() => this.getDropdownWidth())
922
- )
923
- this.selectResizeObserver.observe(this.$refs.dropdown.$el)
924
- },
925
- async getDropdownWidth() {
926
- if (!this.$refs.select) return
927
- await this.$nextTick()
928
- this.dropdownWidth = `${this.$refs.select.$el.clientWidth}px`
929
- },
930
- onArrowPress(dir) {
931
- let newHoveredElem
932
- const currentHoveredElem = this.$refs.dropdown.$el.querySelector(
933
- `[data-value="${this.hoveredValue}"]`
934
- )
935
- if (currentHoveredElem) {
936
- if (dir > 0) {
937
- newHoveredElem = currentHoveredElem.nextElementSibling
938
- } else {
939
- newHoveredElem = currentHoveredElem.previousElementSibling
940
- }
941
- if (newHoveredElem) {
942
- this.hoveredValue = newHoveredElem.getAttribute('data-value')
943
- const topPos = newHoveredElem.offsetTop
944
- this.$refs.dropdown.$el.scrollTop = topPos
945
- }
946
- }
947
- },
948
- },
949
- }
950
- </script>
1
+ <template>
2
+ <Container
3
+ :no-relative="noRelative"
4
+ :select-width="selectWidth"
5
+ @mouseenter="mouseEnterHandler"
6
+ @mouseleave="mouseLeaveHandler"
7
+ >
8
+ <InputWrapper
9
+ :align-items="alignItems"
10
+ :has-label="!!label && label.length > 0"
11
+ :no-relative="noRelative"
12
+ >
13
+ <LabelWrapper
14
+ v-if="label"
15
+ :data-id="labelDataId"
16
+ :info-text-message="!!infoTextMessage || !!$slots.infoText"
17
+ >
18
+ <InputLabel
19
+ :font-color="
20
+ labelFontColor || colorMode == 'dark' ? 'white' : 'eturnityGrey'
21
+ "
22
+ :font-size="fontSize"
23
+ >{{ label }}
24
+ <OptionalLabel v-if="labelOptional">
25
+ ({{ $gettext('Optional') }})</OptionalLabel
26
+ >
27
+ </InputLabel>
28
+ <InfoText
29
+ v-if="infoTextMessage || !!$slots.infoText"
30
+ :align-arrow="infoTextAlignArrow"
31
+ :max-width="infoTextWidth"
32
+ :size="infoTextSize"
33
+ :text="infoTextMessage"
34
+ :width="infoTextWidth"
35
+ >
36
+ <slot name="infoText"></slot>
37
+ </InfoText>
38
+ </LabelWrapper>
39
+ <SelectButtonWrapper :disabled="disabled">
40
+ <SelectButton
41
+ ref="select"
42
+ :bg-color="
43
+ buttonBgColor || colorMode == 'dark' ? 'transparentBlack1' : 'white'
44
+ "
45
+ class="select-button"
46
+ :data-id="dataId"
47
+ :disabled="disabled"
48
+ :font-color="
49
+ buttonFontColor || colorMode == 'dark' ? 'white' : 'black'
50
+ "
51
+ :font-size="fontSize"
52
+ :has-error="hasError"
53
+ :has-no-padding="isSearchBarVisible || !hasSelectButtonPadding"
54
+ :height="height"
55
+ :no-relative="noRelative"
56
+ :padding-left="paddingLeft"
57
+ :select-height="selectHeight"
58
+ :select-min-height="selectMinHeight"
59
+ :select-width="selectWidth"
60
+ :show-border="showBorder"
61
+ :show-disabled-background="showDisabledBackground"
62
+ :table-padding-left="tablePaddingLeft"
63
+ @click="toggleDropdown"
64
+ @keydown="onKeyDown"
65
+ >
66
+ <DraggableInputHandle
67
+ v-if="isDraggable && !isSearchBarVisible"
68
+ :height="selectHeight"
69
+ />
70
+ <InputText
71
+ v-if="isSearchBarVisible"
72
+ ref="searchInput"
73
+ background-color="transparent"
74
+ :font-color="
75
+ buttonFontColor || colorMode == 'dark' ? 'white' : 'black'
76
+ "
77
+ :font-size="fontSize"
78
+ input-height="34px"
79
+ :input-width="computedWidth"
80
+ :no-border="true"
81
+ tabindex="0"
82
+ :value="textSearch"
83
+ @click.stop
84
+ @input-change="searchChange"
85
+ @keydown.stop="onKeyDown"
86
+ />
87
+ <Selector
88
+ v-else
89
+ :disabled="disabled"
90
+ :padding-left="paddingLeft"
91
+ :select-width="selectWidth"
92
+ :show-border="showBorder"
93
+ >
94
+ <slot name="selector" :selected-value="selectedValue"></slot>
95
+ </Selector>
96
+ <Caret class="caret_dropdown" @click.stop="toggleCaretDropdown">
97
+ <Icon
98
+ v-if="isDropdownOpen"
99
+ :color="
100
+ caretColor || disabled
101
+ ? 'grey2'
102
+ : colorMode == 'dark'
103
+ ? 'white'
104
+ : 'transparentBlack1'
105
+ "
106
+ name="arrow_up"
107
+ size="12px"
108
+ />
109
+ <Icon
110
+ v-else
111
+ :color="
112
+ caretColor || disabled
113
+ ? 'grey2'
114
+ : colorMode == 'dark'
115
+ ? 'white'
116
+ : 'transparentBlack1'
117
+ "
118
+ name="arrow_down"
119
+ size="12px"
120
+ />
121
+ </Caret>
122
+ </SelectButton>
123
+ <DropdownWrapper ref="dropdownWrapperRef" :no-relative="noRelative">
124
+ <Teleport to="#portal-target">
125
+ <SelectDropdown
126
+ v-show="isSelectDropdownShown"
127
+ ref="dropdown"
128
+ :bg-color="
129
+ dropdownBgColor || colorMode == 'dark' ? 'black' : 'white'
130
+ "
131
+ :dropdown-position="dropdownPosition"
132
+ :font-color="
133
+ dropdownFontColor || colorMode == 'dark' ? 'white' : 'black'
134
+ "
135
+ :font-size="fontSize"
136
+ :hovered-bg-color="
137
+ colorMode == 'dark' ? '#000000' : dropdownBgColor
138
+ "
139
+ :hovered-index="hoveredIndex"
140
+ :hovered-value="hoveredValue"
141
+ :is-active="isActive"
142
+ :min-width="minWidth"
143
+ :no-relative="noRelative"
144
+ :option-width="getOptionWidth"
145
+ :selected-value="selectedValue"
146
+ @mouseleave="optionLeave"
147
+ @option-hovered="optionHovered"
148
+ @option-selected="optionSelected"
149
+ >
150
+ <slot name="dropdown"></slot>
151
+ </SelectDropdown>
152
+ </Teleport>
153
+ </DropdownWrapper>
154
+ </SelectButtonWrapper>
155
+ </InputWrapper>
156
+ </Container>
157
+ </template>
158
+
159
+ <script>
160
+ //How to use it
161
+ // <Select
162
+ // hoverDropdown="true"
163
+ // selectWidth="100%"
164
+ // minWidth="220px"
165
+ // optionWidth="50%"
166
+ // label="that is a label"
167
+ // alignItems="vertical"
168
+ // label-data-id="test-label-data-id"
169
+ // data-id="test-data-id"
170
+ // :hasSelectButtonPadding="false"
171
+ // >
172
+ // <template #selector="{selectedValue}">
173
+ // value selected: {{selectedValue}}
174
+ // </template>
175
+ // <template #dropdown>
176
+ // <Option value="1">value one</Option>
177
+ // <Option value="2">value two</Option>
178
+ // <Option value="3">value three</Option>
179
+ // <Option value="4">value four</Option>
180
+ // </template>
181
+ // </Select>
182
+
183
+ import { Teleport } from 'vue'
184
+ import styled from 'vue3-styled-components'
185
+ import InfoText from '../../infoText'
186
+ import Icon from '../../icon'
187
+ import InputText from '../inputText'
188
+ import DraggableInputHandle from '../../draggableInputHandle'
189
+ import { debounce } from '../../../utils'
190
+
191
+ const CARET_WIDTH = '30px'
192
+ const BORDER_WIDTH = '1px'
193
+
194
+ const Caret = styled.div`
195
+ display: flex;
196
+ align-items: center;
197
+ justify-content: center;
198
+ width: ${CARET_WIDTH};
199
+ min-width: ${CARET_WIDTH};
200
+ height: 100%;
201
+ align-items: center;
202
+ cursor: pointer;
203
+ margin-left: auto;
204
+ `
205
+
206
+ const selectorProps = {
207
+ disabled: Boolean,
208
+ selectWidth: String,
209
+ paddingLeft: String,
210
+ showBorder: Boolean,
211
+ }
212
+ const Selector = styled('div', selectorProps)`
213
+ color: ${(props) => (props.disabled ? props.theme.colors.grey2 : '')};
214
+ ${(props) =>
215
+ props.selectWidth === '100%'
216
+ ? 'width: 100%;'
217
+ : `width: calc(${props.selectWidth} -
218
+ (
219
+ ${CARET_WIDTH} +
220
+ ${props.paddingLeft}
221
+ ${props.showBorder ? `+ (${BORDER_WIDTH} * 2)` : ''}
222
+ )
223
+ );
224
+ white-space: nowrap;
225
+ text-overflow: ellipsis;
226
+ overflow: hidden;`}
227
+ `
228
+
229
+ const labelAttrs = { fontSize: String, fontColor: String }
230
+ const InputLabel = styled('div', labelAttrs)`
231
+ color: ${(props) =>
232
+ props.theme.colors[props.fontColor]
233
+ ? props.theme.colors[props.fontColor]
234
+ : props.fontColor};
235
+ font-size: ${(props) => props.fontSize};
236
+ font-weight: 700;
237
+ `
238
+ const OptionalLabel = styled.span`
239
+ font-weight: 300;
240
+ `
241
+ const inputProps = {
242
+ selectWidth: String,
243
+ optionWidth: String,
244
+ noRelative: Boolean,
245
+ }
246
+ const Container = styled('div', inputProps)`
247
+ width: ${(props) => props.selectWidth};
248
+ position: ${(props) => (props.noRelative ? 'static' : 'relative')};
249
+ display: inline-block;
250
+ `
251
+
252
+ const LabelWrapperAttrs = { infoTextMessage: Boolean }
253
+ const LabelWrapper = styled('div', LabelWrapperAttrs)`
254
+ display: inline-grid;
255
+ grid-template-columns: ${(props) =>
256
+ props.infoTextMessage ? 'auto auto' : 'auto'};
257
+ grid-gap: 12px;
258
+ align-items: center;
259
+ justify-content: start;
260
+ `
261
+
262
+ const SelectButtonWrapperAttrs = {
263
+ disabled: Boolean,
264
+ }
265
+ const SelectButtonWrapper = styled('div', SelectButtonWrapperAttrs)`
266
+ ${(props) => (props.disabled ? 'cursor: not-allowed' : 'cursor: pointer')};
267
+ `
268
+
269
+ const selectButtonAttrs = {
270
+ bgColor: String,
271
+ fontColor: String,
272
+ hasError: Boolean,
273
+ disabled: Boolean,
274
+ selectHeight: String,
275
+ selectWidth: String,
276
+ height: String,
277
+ selectMinHeight: String,
278
+ hasNoPadding: Boolean,
279
+ showBorder: Boolean,
280
+ paddingLeft: String,
281
+ noRelative: Boolean,
282
+ tablePaddingLeft: String,
283
+ showDisabledBackground: Boolean,
284
+ }
285
+ const SelectButton = styled('div', selectButtonAttrs)`
286
+ position: ${(props) => (props.noRelative ? 'static' : 'relative')};
287
+ box-sizing: border-box;
288
+ border-radius: 4px;
289
+ max-width: ${(props) => (props.selectWidth ? props.selectWidth : '100%')};
290
+ ${(props) =>
291
+ props.isSearchBarVisible
292
+ ? ''
293
+ : `padding-left: ${
294
+ props.hasNoPadding
295
+ ? '0'
296
+ : props.tablePaddingLeft
297
+ ? props.tablePaddingLeft
298
+ : props.paddingLeft
299
+ }`};
300
+ text-align: left;
301
+ min-height: ${(props) =>
302
+ props.selectHeight
303
+ ? props.selectHeight
304
+ : props.selectMinHeight
305
+ ? props.selectMinHeight
306
+ : props.height
307
+ ? props.height
308
+ : '36px'};
309
+ display: flex;
310
+ align-items: center;
311
+ height: ${(props) => props.selectHeight};
312
+ ${({ showBorder, theme, hasError }) =>
313
+ showBorder &&
314
+ `
315
+ border: ${BORDER_WIDTH} solid ${
316
+ hasError ? theme.colors.red : theme.colors.grey4
317
+ }
318
+ `}
319
+ background-color:${(props) =>
320
+ props.disabled && props.showDisabledBackground
321
+ ? props.theme.colors.grey5
322
+ : props.theme.colors[props.bgColor]
323
+ ? props.theme.colors[props.bgColor]
324
+ : props.bgColor};
325
+ color: ${(props) =>
326
+ props.theme.colors[props.fontColor]
327
+ ? props.theme.colors[props.fontColor]
328
+ : props.fontColor};
329
+ ${(props) => (props.disabled ? 'pointer-events: none' : '')};
330
+ overflow: hidden;
331
+ & > .handle {
332
+ border-right: ${(props) =>
333
+ props.hasError ? props.theme.colors.red : props.theme.colors.grey4}
334
+ 1px solid;
335
+ }
336
+ `
337
+ const selectDropdownAttrs = {
338
+ hoveredBgColor: String,
339
+ bgColor: String,
340
+ fontColor: String,
341
+ optionWidth: String,
342
+ hoveredIndex: Number,
343
+ fontSize: String,
344
+ dropdownPosition: Object,
345
+ hoveredValue: Number | String,
346
+ selectedValue: Number | String,
347
+ noRelative: Boolean,
348
+ minWidth: String,
349
+ }
350
+ const SelectDropdown = styled('div', selectDropdownAttrs)`
351
+ box-sizing: border-box;
352
+ z-index: ${(props) => (props.isActive ? '2' : '99999')};
353
+ position: absolute;
354
+ top: ${(props) =>
355
+ props.noRelative ? 'auto' : props.dropdownPosition?.top + 'px'};
356
+ left: ${(props) => props.dropdownPosition?.left}px;
357
+ border: ${BORDER_WIDTH} solid ${(props) => props.theme.colors.grey4};
358
+ border-radius: 4px;
359
+ display: flex;
360
+ flex-direction: column;
361
+ align-items: flex-start;
362
+ padding: 0px;
363
+ box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
364
+ width: ${(props) => (props.optionWidth ? props.optionWidth : '100%')};
365
+ min-width: ${(props) =>
366
+ props.minWidth
367
+ ? props.minWidth
368
+ : props.optionWidth
369
+ ? props.optionWidth
370
+ : '100%'};
371
+ background-color: ${(props) =>
372
+ props.theme.colors[props.bgColor]
373
+ ? props.theme.colors[props.bgColor]
374
+ : props.bgColor};
375
+ color: ${(props) =>
376
+ props.theme.colors[props.fontColor]
377
+ ? props.theme.colors[props.fontColor]
378
+ : props.fontColor};
379
+ max-height: 300px;
380
+ overflow-y: auto;
381
+ & > div[data-value='${(props) => props.hoveredValue}'] {
382
+ background-color: ${(props) =>
383
+ props.theme.colors[props.hoveredBgColor]
384
+ ? props.theme.colors[props.hoveredBgColor]
385
+ : props.hoveredBgColor};
386
+ }
387
+ font-size: ${(props) => props.fontSize};
388
+ `
389
+ SelectDropdown.emits = ['option-hovered', 'option-selected']
390
+ const DropdownAttrs = { noRelative: Boolean }
391
+ const DropdownWrapper = styled('div', DropdownAttrs)`
392
+ position: ${(props) => (props.noRelative ? 'static' : 'relative')};
393
+ `
394
+ const inputAttrs = {
395
+ alignItems: String,
396
+ hasLabel: Boolean,
397
+ noRelative: Boolean,
398
+ }
399
+ const InputWrapper = styled('div', inputAttrs)`
400
+ position: ${(props) => (props.noRelative ? 'static' : 'relative')};
401
+ display: grid;
402
+ width: 100%;
403
+ min-width: ${(props) => (props.minWidth ? props.minWidth : '150px')};
404
+ align-items: center;
405
+ gap: 8px;
406
+ grid-template-columns: ${(props) =>
407
+ props.alignItems === 'vertical' || !props.hasLabel ? '1fr' : 'auto 1fr'};
408
+ `
409
+
410
+ const DROPDOWN_HEIGHT_OFFSET = 4
411
+ const DROPDOWN_TOP_OFFSET = 21
412
+ const MIN_OPTION_LENGTH = 5
413
+
414
+ const DROPDOWN_MENU_POSITIONS = {
415
+ Automatic: 'automatic',
416
+ Bottom: 'bottom',
417
+ }
418
+
419
+ export default {
420
+ name: 'RCselect',
421
+
422
+ components: {
423
+ SelectButton,
424
+ SelectButtonWrapper,
425
+ SelectDropdown,
426
+ Container,
427
+ InputLabel,
428
+ LabelWrapper,
429
+ OptionalLabel,
430
+ InfoText,
431
+ InputWrapper,
432
+ DropdownWrapper,
433
+ Icon,
434
+ Caret,
435
+ Selector,
436
+ InputText,
437
+ Teleport,
438
+ DraggableInputHandle,
439
+ },
440
+
441
+ props: {
442
+ value: {
443
+ required: false,
444
+ default: null,
445
+ },
446
+ fontSize: {
447
+ required: false,
448
+ default: '13px',
449
+ },
450
+ noRelative: {
451
+ required: false,
452
+ default: false,
453
+ },
454
+ label: {
455
+ required: false,
456
+ },
457
+ labelOptional: {
458
+ required: false,
459
+ default: false,
460
+ },
461
+ labelDataId: {
462
+ required: false,
463
+ default: '',
464
+ },
465
+ infoTextMessage: {
466
+ required: false,
467
+ },
468
+ selectWidth: {
469
+ type: String,
470
+ required: false,
471
+ default: '100%',
472
+ },
473
+ minWidth: {
474
+ required: false,
475
+ },
476
+ maxWidth: {
477
+ required: false,
478
+ },
479
+ selectHeight: {
480
+ type: String,
481
+ required: false,
482
+ default: null,
483
+ },
484
+ height: {
485
+ required: false,
486
+ default: null,
487
+ },
488
+ selectMinHeight: {
489
+ required: false,
490
+ default: '36px',
491
+ },
492
+ optionWidth: {
493
+ required: false,
494
+ default: null,
495
+ },
496
+ hoverDropdown: {
497
+ required: false,
498
+ default: false,
499
+ },
500
+ dropdownAutoClose: {
501
+ required: false,
502
+ default: false,
503
+ },
504
+ alignItems: {
505
+ required: false,
506
+ default: 'horizontal',
507
+ },
508
+ buttonBgColor: {
509
+ required: false,
510
+ },
511
+ buttonFontColor: {
512
+ required: false,
513
+ },
514
+ dropdownBgColor: {
515
+ required: false,
516
+ default: 'grey5',
517
+ },
518
+ dropdownFontColor: {
519
+ required: false,
520
+ },
521
+ dropDownArrowVisible: {
522
+ required: false,
523
+ default: true,
524
+ },
525
+ caretColor: {
526
+ required: false,
527
+ },
528
+ labelFontColor: {
529
+ required: false,
530
+ },
531
+ colorMode: {
532
+ required: false,
533
+ default: 'light',
534
+ },
535
+ isSearchable: {
536
+ required: false,
537
+ default: true,
538
+ },
539
+ hasError: {
540
+ required: false,
541
+ default: false,
542
+ },
543
+ disabled: {
544
+ required: false,
545
+ type: Boolean,
546
+ default: false,
547
+ },
548
+ isAutoSearch: {
549
+ required: false,
550
+ default: true,
551
+ },
552
+ showBorder: {
553
+ required: false,
554
+ default: true,
555
+ },
556
+ infoTextSize: {
557
+ required: false,
558
+ default: '14px',
559
+ },
560
+ dataId: {
561
+ type: String,
562
+ default: '',
563
+ },
564
+ hasSelectButtonPadding: {
565
+ required: false,
566
+ type: Boolean,
567
+ default: true,
568
+ },
569
+ isDraggable: {
570
+ type: Boolean,
571
+ default: false,
572
+ },
573
+ leftPadding: {
574
+ type: String,
575
+ default: '15px',
576
+ },
577
+ tablePaddingLeft: {
578
+ required: false,
579
+ },
580
+ showDisabledBackground: {
581
+ required: false,
582
+ default: true,
583
+ },
584
+ minOptionLength: {
585
+ type: Number,
586
+ default: MIN_OPTION_LENGTH,
587
+ },
588
+ dropdownMenuPosition: {
589
+ type: String,
590
+ default: DROPDOWN_MENU_POSITIONS.Automatic, // options: ['automatic', bottom]
591
+ },
592
+ infoTextWidth: {
593
+ type: String,
594
+ required: false,
595
+ },
596
+ infoTextAlignArrow: {
597
+ type: String,
598
+ required: false,
599
+ },
600
+ },
601
+
602
+ data() {
603
+ return {
604
+ selectedValue: null,
605
+ paddingLeft: this.isDraggable ? '30px' : this.leftPadding,
606
+ isDropdownOpen: false,
607
+ isActive: false,
608
+ textSearch: '',
609
+ hoveredIndex: 0,
610
+ isClickOutsideActive: false,
611
+ dropdownPosition: {
612
+ left: null,
613
+ top: null,
614
+ },
615
+ dropdownWidth: null,
616
+ hoveredValue: null,
617
+ }
618
+ },
619
+ computed: {
620
+ optionLength() {
621
+ if (this.isDropdownOpen) {
622
+ return this.$refs.dropdown.$el.childElementCount > 1
623
+ ? this.$refs.dropdown.$el.childElementCount
624
+ : !!this.$refs.dropdown.$el.children[0]
625
+ ? this.$refs.dropdown.$el.children[0].childElementCount
626
+ : 0
627
+ }
628
+
629
+ return 0
630
+ },
631
+ isSearchBarVisible() {
632
+ return (
633
+ this.isSearchable &&
634
+ this.optionLength >= this.minOptionLength &&
635
+ this.isDropdownOpen
636
+ )
637
+ },
638
+ computedWidth() {
639
+ function removePX(item) {
640
+ return Number(item.replace('px', ''))
641
+ }
642
+
643
+ return this.selectWidth === '100%'
644
+ ? '100%'
645
+ : removePX(this.selectWidth) - removePX(CARET_WIDTH) + 'px'
646
+ },
647
+ getOptionWidth() {
648
+ if (this.optionWidth) return this.optionWidth
649
+
650
+ return this.dropdownWidth
651
+ },
652
+ isSelectDropdownShown() {
653
+ return (
654
+ this.isDropdownOpen &&
655
+ this.dropdownPosition.left !== null &&
656
+ (!this.isSearchable || this.isSearchable)
657
+ )
658
+ },
659
+ isMobileDevice() {
660
+ const userAgent =
661
+ navigator.userAgent || navigator.vendor || window.opera
662
+ const touchCapable =
663
+ 'ontouchstart' in window ||
664
+ navigator.maxTouchPoints > 0 ||
665
+ navigator.msMaxTouchPoints > 0
666
+
667
+ return (
668
+ /Android/i.test(userAgent) ||
669
+ /iPad|iPhone|iPod/.test(userAgent) ||
670
+ (/Macintosh/.test(userAgent) && touchCapable) ||
671
+ /windows phone/i.test(userAgent)
672
+ )
673
+ },
674
+ },
675
+ watch: {
676
+ value(val) {
677
+ this.selectedValue = val
678
+ },
679
+ async isDropdownOpen(val) {
680
+ if (val) {
681
+ this.$emit('on-dropdown-open')
682
+ setTimeout(() => {
683
+ this.isClickOutsideActive = true
684
+ }, 10)
685
+ await this.$nextTick()
686
+ this.handleSetDropdownOffet()
687
+ } else {
688
+ this.dropdownPosition.left = null
689
+ setTimeout(() => {
690
+ this.isClickOutsideActive = false
691
+ }, 10)
692
+ }
693
+ if (val && this.isSearchable) {
694
+ this.$nextTick(() => {
695
+ if (this.$refs.searchInput && !this.isMobileDevice) {
696
+ this.$refs.searchInput.$el.querySelector('input').focus()
697
+ }
698
+ })
699
+ }
700
+ },
701
+ },
702
+ mounted() {
703
+ this.observeDropdownHeight()
704
+ this.observeSelectWidth()
705
+ window.addEventListener('resize', this.handleSetDropdownOffet)
706
+ },
707
+ beforeMount() {
708
+ this.selectedValue = this.value
709
+ document.addEventListener('click', this.clickOutside)
710
+ this.getDropdownPosition()
711
+ window.removeEventListener('resize', this.handleSetDropdownOffet)
712
+ if (this.dropdownResizeObserver) this.dropdownResizeObserver.disconnect()
713
+ if (this.selectResizeObserver) this.selectResizeObserver.disconnect()
714
+ },
715
+ unmounted() {
716
+ document.removeEventListener('click', this.clickOutside)
717
+ },
718
+ methods: {
719
+ focus() {
720
+ this.isActive = true
721
+ },
722
+ blur(e) {
723
+ this.isActive = false
724
+ this.$emit('blur', e)
725
+ },
726
+ toggleDropdown() {
727
+ this.isDropdownOpen = !this.isDropdownOpen
728
+ },
729
+ toggleCaretDropdown() {
730
+ this.isDropdownOpen = !this.isDropdownOpen
731
+ },
732
+ closeDropdown() {
733
+ this.blur()
734
+ this.clearSearch()
735
+ this.isDropdownOpen = false
736
+ },
737
+ clearSearch() {
738
+ this.textSearch = ''
739
+ this.searchChange('')
740
+ },
741
+ optionSelected(e) {
742
+ this.selectedValue = e
743
+ this.closeDropdown()
744
+ this.blur()
745
+ this.$emit('input-change', e)
746
+ },
747
+ optionHovered: debounce(function (e) {
748
+ this.hoveredValue = e
749
+ }, 300),
750
+ mouseEnterHandler() {
751
+ if (this.hoverDropdown) {
752
+ this.focus()
753
+ this.isDropdownOpen = true
754
+ }
755
+ },
756
+ mouseLeaveHandler() {
757
+ if (this.hoverDropdown) {
758
+ this.blur()
759
+ }
760
+ },
761
+ optionLeave() {
762
+ if (this.dropdownAutoClose) {
763
+ this.isDropdownOpen = false
764
+ }
765
+ },
766
+ searchChange(value) {
767
+ this.textSearch = value
768
+ this.$emit('search-change', value)
769
+ const dropdownChildren = [...this.$refs.dropdown.$el.children]
770
+ dropdownChildren.forEach((el) => {
771
+ if (!el.textContent.toLowerCase().includes(value.toLowerCase())) {
772
+ el.style.display = 'none'
773
+
774
+ return
775
+ }
776
+
777
+ el.style.display = 'inherit'
778
+ })
779
+ },
780
+ clickOutside(event) {
781
+ const dropdownRef = this.$refs.dropdown
782
+ // we need to prevent closing on selecting an option, because in the case of
783
+ // a disabled option, we don't want to close the dropdown
784
+ if (!this.isClickOutsideActive) return
785
+ if (
786
+ this.$refs.select.$el == event.target ||
787
+ this.$refs.select.$el.contains(event.target) ||
788
+ event.target.id === 'more-button' ||
789
+ event.target.parentNode === dropdownRef.$el
790
+ ) {
791
+ return
792
+ } else {
793
+ this.closeDropdown()
794
+ }
795
+ },
796
+ onKeyDown(e) {
797
+ if (e.key == 'ArrowDown') {
798
+ this.onArrowPress(1)
799
+ } else if (e.key == 'ArrowUp') {
800
+ this.onArrowPress(-1)
801
+ } else if (e.key == 'Enter') {
802
+ const optionHoveredComponent = [...this.$refs.dropdown.$el.children][
803
+ (this.hoveredIndex - 1 + this.optionLength) % this.optionLength
804
+ ]
805
+ this.optionSelected(optionHoveredComponent.$el.dataset.value)
806
+ }
807
+ },
808
+ // If some part of the dropdown menu is outside viewport of the bottom of the screen,
809
+ // we need to offset it and display it at the top of the select dropdown instead
810
+ async getDropdownPosition() {
811
+ if (
812
+ !this.$refs.dropdownWrapperRef ||
813
+ !this.$refs.select ||
814
+ !this.$refs.dropdown
815
+ ) {
816
+ return
817
+ }
818
+ await this.$nextTick()
819
+ const isDisplayedAtBottom = await this.generateDropdownPosition()
820
+ // If the dropdown menu is going to be displayed at the bottom,
821
+ // we need reverify its position after a dom update (nextTick)
822
+ await this.$nextTick()
823
+ if (isDisplayedAtBottom) this.generateDropdownPosition()
824
+ },
825
+ async generateDropdownPosition() {
826
+ const isDropdownNotCompletelyVisible =
827
+ await this.isBottomOfDropdownOutOfViewport()
828
+ const dropdownWrapperEl = this.$refs.dropdownWrapperRef.$el
829
+ const selectButtonHeight = this.$refs.select.$el.clientHeight
830
+ const dropdownHeight = this.$refs.dropdown.$el.clientHeight
831
+ const dropdownWrapperRelativeHeight =
832
+ dropdownWrapperEl.getBoundingClientRect().top +
833
+ window.scrollY +
834
+ DROPDOWN_HEIGHT_OFFSET
835
+
836
+ const top =
837
+ isDropdownNotCompletelyVisible ||
838
+ (!isDropdownNotCompletelyVisible &&
839
+ this.dropdownMenuPosition === DROPDOWN_MENU_POSITIONS.Bottom)
840
+ ? dropdownWrapperRelativeHeight
841
+ : dropdownWrapperRelativeHeight -
842
+ dropdownHeight -
843
+ selectButtonHeight -
844
+ DROPDOWN_TOP_OFFSET
845
+ const left = this.dropdownPosition.left
846
+ ? this.dropdownPosition.left
847
+ : dropdownWrapperEl.getBoundingClientRect().left + window.scrollX
848
+
849
+ this.dropdownPosition = { left: Math.floor(left), top: Math.floor(top) }
850
+
851
+ return isDropdownNotCompletelyVisible
852
+ },
853
+ async isBottomOfDropdownOutOfViewport() {
854
+ if (
855
+ !this.$refs.dropdown ||
856
+ this.dropdownMenuPosition === DROPDOWN_MENU_POSITIONS.Bottom
857
+ ) {
858
+ return false
859
+ }
860
+
861
+ await this.$nextTick()
862
+ const rect = this.$refs.dropdown.$el.getBoundingClientRect()
863
+ const windowHeight =
864
+ window.innerHeight || document.documentElement.clientHeight
865
+
866
+ if (windowHeight <= 650) return true
867
+
868
+ // using Math.floor because the offsets may contain decimals we are not going to consider here
869
+ return Math.floor(rect.top) + Math.floor(rect.height) <= windowHeight
870
+ },
871
+ observeDropdownHeight() {
872
+ if (!this.$refs.dropdown) return
873
+ this.dropdownResizeObserver = new ResizeObserver(() => {
874
+ this.$nextTick(() => this.getDropdownPosition())
875
+ })
876
+ this.dropdownResizeObserver.observe(this.$refs.dropdown.$el)
877
+ },
878
+ handleSetDropdownOffet() {
879
+ if (!this.$refs.select) return
880
+ this.dropdownPosition.left = Math.floor(
881
+ this.$refs.select.$el.getBoundingClientRect().left
882
+ )
883
+ this.getDropdownWidth()
884
+ },
885
+ observeSelectWidth() {
886
+ if (!this.$refs.select) return
887
+ this.selectResizeObserver = new ResizeObserver(() =>
888
+ // eslint-disable-next-line vue/valid-next-tick
889
+ this.$nextTick(() => this.getDropdownWidth())
890
+ )
891
+ this.selectResizeObserver.observe(this.$refs.dropdown.$el)
892
+ },
893
+ async getDropdownWidth() {
894
+ if (!this.$refs.select) return
895
+ await this.$nextTick()
896
+ this.dropdownWidth = `${this.$refs.select.$el.clientWidth}px`
897
+ },
898
+ onArrowPress(dir) {
899
+ let newHoveredElem
900
+ const currentHoveredElem = this.$refs.dropdown.$el.querySelector(
901
+ `[data-value="${this.hoveredValue}"]`
902
+ )
903
+ if (currentHoveredElem) {
904
+ if (dir > 0) {
905
+ newHoveredElem = currentHoveredElem.nextElementSibling
906
+ } else {
907
+ newHoveredElem = currentHoveredElem.previousElementSibling
908
+ }
909
+ if (newHoveredElem) {
910
+ this.hoveredValue = newHoveredElem.getAttribute('data-value')
911
+ const topPos = newHoveredElem.offsetTop
912
+ this.$refs.dropdown.$el.scrollTop = topPos
913
+ }
914
+ }
915
+ },
916
+ },
917
+ }
918
+ </script>