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