@eturnity/eturnity_reusable_components 8.16.9-EPDM-13618.0 → 8.16.9-EPDM-EPDM-14492.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +640 -652
  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 +213 -221
  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 +138 -146
  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 -672
  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 +1003 -1002
  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 -1055
  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 +125 -116
  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,1055 +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
- <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>
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>