@eturnity/eturnity_reusable_components 7.48.1-EPDM-10679.1 → 7.48.1-EPDM-12680.14

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