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