@eturnity/eturnity_reusable_components 7.32.1-EPDM-11313.0 → 7.32.1-EPDM-11143.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/.eslintrc.js +184 -184
  2. package/.prettierrc +9 -9
  3. package/.storybook/main.js +8 -8
  4. package/.storybook/preview.js +46 -46
  5. package/README.md +29 -29
  6. package/babel.config.js +5 -5
  7. package/package.json +50 -50
  8. package/postcss.config.js +6 -6
  9. package/src/App.vue +110 -110
  10. package/src/assets/icons/arrow_down.svg +3 -3
  11. package/src/assets/icons/arrow_up_red.svg +3 -3
  12. package/src/assets/icons/black_spinner.svg +35 -35
  13. package/src/assets/icons/delete_icon.svg +11 -11
  14. package/src/assets/icons/delete_icon_gray.svg +11 -11
  15. package/src/assets/icons/drag_icon.svg +8 -8
  16. package/src/assets/icons/external_icon.svg +6 -6
  17. package/src/assets/icons/language_icon.svg +6 -6
  18. package/src/assets/icons/pdf_icon.svg +6 -6
  19. package/src/assets/icons/plus_button.svg +4 -4
  20. package/src/assets/icons/search_icon_black.svg +3 -3
  21. package/src/assets/icons/subposition_icon.svg +3 -3
  22. package/src/assets/icons/subposition_marker.svg +3 -3
  23. package/src/assets/icons/warning_icon.svg +3 -3
  24. package/src/assets/svgIcons/2d_active.svg +7 -7
  25. package/src/assets/svgIcons/2d_inactive.svg +8 -8
  26. package/src/assets/svgIcons/3d_active.svg +7 -7
  27. package/src/assets/svgIcons/3d_inactive.svg +8 -8
  28. package/src/assets/svgIcons/_readme.md +7 -7
  29. package/src/assets/svgIcons/accept.svg +5 -5
  30. package/src/assets/svgIcons/activate_panels_active.svg +22 -22
  31. package/src/assets/svgIcons/activate_panels_inactive.svg +20 -20
  32. package/src/assets/svgIcons/add_icon-1.svg +3 -3
  33. package/src/assets/svgIcons/add_icon.svg +4 -4
  34. package/src/assets/svgIcons/address_book.svg +3 -3
  35. package/src/assets/svgIcons/after_sale_as_a_service.svg +6 -6
  36. package/src/assets/svgIcons/all_good.svg +3 -3
  37. package/src/assets/svgIcons/angle_active.svg +5 -5
  38. package/src/assets/svgIcons/angle_inactive.svg +4 -4
  39. package/src/assets/svgIcons/area_active.svg +11 -11
  40. package/src/assets/svgIcons/area_inactive.svg +26 -26
  41. package/src/assets/svgIcons/areas_tool.svg +14 -14
  42. package/src/assets/svgIcons/arrow_down.svg +3 -3
  43. package/src/assets/svgIcons/arrow_left.svg +4 -4
  44. package/src/assets/svgIcons/arrow_right.svg +4 -4
  45. package/src/assets/svgIcons/arrow_up.svg +3 -3
  46. package/src/assets/svgIcons/attachment.svg +3 -3
  47. package/src/assets/svgIcons/base_layer.svg +3 -3
  48. package/src/assets/svgIcons/battery.svg +3 -3
  49. package/src/assets/svgIcons/bell.svg +3 -3
  50. package/src/assets/svgIcons/bexio.svg +4 -4
  51. package/src/assets/svgIcons/bold.svg +3 -3
  52. package/src/assets/svgIcons/bom.svg +3 -3
  53. package/src/assets/svgIcons/bom_generation.svg +10 -10
  54. package/src/assets/svgIcons/bookmaker.svg +3 -3
  55. package/src/assets/svgIcons/bubble.svg +3 -3
  56. package/src/assets/svgIcons/bug.svg +5 -5
  57. package/src/assets/svgIcons/bullet_list.svg +8 -8
  58. package/src/assets/svgIcons/calendar.svg +7 -7
  59. package/src/assets/svgIcons/calendar_icon.svg +7 -7
  60. package/src/assets/svgIcons/call.svg +3 -3
  61. package/src/assets/svgIcons/camera.svg +3 -3
  62. package/src/assets/svgIcons/car.svg +3 -3
  63. package/src/assets/svgIcons/cart.svg +3 -3
  64. package/src/assets/svgIcons/charger_icon_white.svg +44 -44
  65. package/src/assets/svgIcons/checkbox.svg +3 -3
  66. package/src/assets/svgIcons/clear_formatting.svg +7 -7
  67. package/src/assets/svgIcons/clickable_info.svg +4 -4
  68. package/src/assets/svgIcons/clip.svg +3 -3
  69. package/src/assets/svgIcons/clock.svg +17 -17
  70. package/src/assets/svgIcons/clock_full.svg +3 -3
  71. package/src/assets/svgIcons/close_for_modals,_tool_tips.svg +4 -4
  72. package/src/assets/svgIcons/co_branding.svg +5 -5
  73. package/src/assets/svgIcons/collapse.svg +4 -4
  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/copy.svg +10 -0
  82. package/src/assets/svgIcons/cross.svg +4 -4
  83. package/src/assets/svgIcons/current_variant.svg +4 -4
  84. package/src/assets/svgIcons/dashboard.svg +3 -3
  85. package/src/assets/svgIcons/data_transfer.svg +3 -3
  86. package/src/assets/svgIcons/deadline.svg +4 -4
  87. package/src/assets/svgIcons/deal_flow.svg +5 -5
  88. package/src/assets/svgIcons/delete.svg +4 -4
  89. package/src/assets/svgIcons/delete_area_active.svg +16 -16
  90. package/src/assets/svgIcons/delete_area_inactive.svg +15 -15
  91. package/src/assets/svgIcons/direction_active-1.svg +12 -12
  92. package/src/assets/svgIcons/direction_active.svg +5 -5
  93. package/src/assets/svgIcons/direction_arrow.svg +4 -4
  94. package/src/assets/svgIcons/direction_inactive.svg +4 -4
  95. package/src/assets/svgIcons/dislike.svg +3 -3
  96. package/src/assets/svgIcons/distance_tool.svg +8 -8
  97. package/src/assets/svgIcons/distances_active.svg +9 -9
  98. package/src/assets/svgIcons/distances_inactive.svg +8 -8
  99. package/src/assets/svgIcons/distort_tool.svg +10 -10
  100. package/src/assets/svgIcons/distort_tool2.svg +16 -16
  101. package/src/assets/svgIcons/document.svg +3 -3
  102. package/src/assets/svgIcons/documents.svg +4 -4
  103. package/src/assets/svgIcons/downarrow.svg +3 -3
  104. package/src/assets/svgIcons/download.svg +4 -4
  105. package/src/assets/svgIcons/drag_icon.svg +8 -8
  106. package/src/assets/svgIcons/draggable_corner.svg +5 -5
  107. package/src/assets/svgIcons/draw_tool.svg +3 -3
  108. package/src/assets/svgIcons/duplicate-1.svg +8 -8
  109. package/src/assets/svgIcons/duplicate-2.svg +5 -5
  110. package/src/assets/svgIcons/duplicate.svg +4 -4
  111. package/src/assets/svgIcons/e-mobility_configurator.svg +6 -6
  112. package/src/assets/svgIcons/e_signature.svg +5 -5
  113. package/src/assets/svgIcons/edit_button.svg +3 -3
  114. package/src/assets/svgIcons/electricity_tariff.svg +3 -3
  115. package/src/assets/svgIcons/email.svg +3 -3
  116. package/src/assets/svgIcons/ems-1.svg +3 -3
  117. package/src/assets/svgIcons/ems.svg +3 -3
  118. package/src/assets/svgIcons/end_of_the_list.svg +5 -5
  119. package/src/assets/svgIcons/erase.svg +4 -4
  120. package/src/assets/svgIcons/external_icon.svg +5 -5
  121. package/src/assets/svgIcons/fav_icon.svg +4 -4
  122. package/src/assets/svgIcons/finance.svg +3 -3
  123. package/src/assets/svgIcons/financing_for_pv-1.svg +5 -5
  124. package/src/assets/svgIcons/financing_for_pv-2.svg +3 -3
  125. package/src/assets/svgIcons/financing_for_pv.svg +6 -6
  126. package/src/assets/svgIcons/finish-1.svg +4 -4
  127. package/src/assets/svgIcons/finish.svg +3 -3
  128. package/src/assets/svgIcons/flatten.svg +11 -11
  129. package/src/assets/svgIcons/flatten_roof.svg +20 -20
  130. package/src/assets/svgIcons/folder.svg +3 -3
  131. package/src/assets/svgIcons/free_technology.svg +5 -5
  132. package/src/assets/svgIcons/handle.svg +5 -5
  133. package/src/assets/svgIcons/heat_calc.svg +7 -7
  134. package/src/assets/svgIcons/height_equalize.svg +3 -3
  135. package/src/assets/svgIcons/height_snap.svg +3 -3
  136. package/src/assets/svgIcons/house.svg +3 -3
  137. package/src/assets/svgIcons/house_3d-1.svg +7 -7
  138. package/src/assets/svgIcons/house_3d.svg +7 -7
  139. package/src/assets/svgIcons/inclination.svg +2 -2
  140. package/src/assets/svgIcons/info.svg +3 -3
  141. package/src/assets/svgIcons/initial_situation.svg +3 -3
  142. package/src/assets/svgIcons/integrations.svg +3 -3
  143. package/src/assets/svgIcons/intro-tour-1.svg +3 -3
  144. package/src/assets/svgIcons/intro-tour.svg +3 -3
  145. package/src/assets/svgIcons/inverter-1.svg +5 -5
  146. package/src/assets/svgIcons/inverter.svg +3 -3
  147. package/src/assets/svgIcons/italic.svg +3 -3
  148. package/src/assets/svgIcons/key.svg +3 -3
  149. package/src/assets/svgIcons/layers_close.svg +4 -4
  150. package/src/assets/svgIcons/layers_open.svg +4 -4
  151. package/src/assets/svgIcons/lead_marketplace.svg +6 -6
  152. package/src/assets/svgIcons/lead_provider.svg +4 -4
  153. package/src/assets/svgIcons/length_2d.svg +2 -2
  154. package/src/assets/svgIcons/length_3d.svg +4 -4
  155. package/src/assets/svgIcons/length_calculator.svg +2 -2
  156. package/src/assets/svgIcons/length_in_2d_active.svg +12 -12
  157. package/src/assets/svgIcons/length_in_2d_inctive.svg +13 -13
  158. package/src/assets/svgIcons/light_bulb.svg +3 -3
  159. package/src/assets/svgIcons/like.svg +3 -3
  160. package/src/assets/svgIcons/line_graph.svg +3 -3
  161. package/src/assets/svgIcons/local_subsidies.svg +18 -18
  162. package/src/assets/svgIcons/location.svg +3 -3
  163. package/src/assets/svgIcons/lock.svg +3 -3
  164. package/src/assets/svgIcons/logout.svg +3 -3
  165. package/src/assets/svgIcons/loop.svg +3 -3
  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/move_copy.svg +4 -4
  173. package/src/assets/svgIcons/new_area_inactive.svg +11 -11
  174. package/src/assets/svgIcons/next.svg +4 -4
  175. package/src/assets/svgIcons/not_equal_to.svg +3 -3
  176. package/src/assets/svgIcons/numbered_list.svg +6 -6
  177. package/src/assets/svgIcons/obstacle_tool.svg +9 -9
  178. package/src/assets/svgIcons/obstacle_tool_origin.svg +3 -3
  179. package/src/assets/svgIcons/offset_tool.svg +8 -8
  180. package/src/assets/svgIcons/outline_tool.svg +11 -11
  181. package/src/assets/svgIcons/pan_tool.svg +12 -12
  182. package/src/assets/svgIcons/panels_tool.svg +8 -8
  183. package/src/assets/svgIcons/pen_tool.svg +4 -4
  184. package/src/assets/svgIcons/picker_tool.svg +4 -4
  185. package/src/assets/svgIcons/picture.svg +3 -3
  186. package/src/assets/svgIcons/pin.svg +5 -5
  187. package/src/assets/svgIcons/presentation.svg +3 -3
  188. package/src/assets/svgIcons/previous.svg +4 -4
  189. package/src/assets/svgIcons/profile-1.svg +4 -4
  190. package/src/assets/svgIcons/profile.svg +4 -4
  191. package/src/assets/svgIcons/profitability.svg +3 -3
  192. package/src/assets/svgIcons/project_analysis.svg +4 -4
  193. package/src/assets/svgIcons/project_settings.svg +4 -4
  194. package/src/assets/svgIcons/pv.svg +3 -3
  195. package/src/assets/svgIcons/quotations.svg +6 -6
  196. package/src/assets/svgIcons/redo.svg +6 -6
  197. package/src/assets/svgIcons/resizer.svg +5 -5
  198. package/src/assets/svgIcons/roof_layer.svg +3 -3
  199. package/src/assets/svgIcons/rotate_tool.svg +3 -3
  200. package/src/assets/svgIcons/rotate_view.svg +5 -5
  201. package/src/assets/svgIcons/ruler_tool.svg +3 -3
  202. package/src/assets/svgIcons/run_simulation.svg +3 -3
  203. package/src/assets/svgIcons/save.svg +3 -3
  204. package/src/assets/svgIcons/scaling_tool.svg +8 -8
  205. package/src/assets/svgIcons/search.svg +3 -3
  206. package/src/assets/svgIcons/security.svg +3 -3
  207. package/src/assets/svgIcons/settings.svg +3 -3
  208. package/src/assets/svgIcons/show_in_a_new_tab.svg +12 -12
  209. package/src/assets/svgIcons/smartphone.svg +4 -4
  210. package/src/assets/svgIcons/solar_calc.svg +13 -13
  211. package/src/assets/svgIcons/sorting.svg +4 -4
  212. package/src/assets/svgIcons/split.svg +12 -12
  213. package/src/assets/svgIcons/start_of_the_list.svg +5 -5
  214. package/src/assets/svgIcons/strikethrough.svg +4 -4
  215. package/src/assets/svgIcons/subscriptions.svg +3 -3
  216. package/src/assets/svgIcons/subsidies-1.svg +5 -5
  217. package/src/assets/svgIcons/subsidies-2.svg +3 -3
  218. package/src/assets/svgIcons/subsidies.svg +3 -3
  219. package/src/assets/svgIcons/subtract_icon.svg +3 -3
  220. package/src/assets/svgIcons/suitcase.svg +3 -3
  221. package/src/assets/svgIcons/summer.svg +3 -3
  222. package/src/assets/svgIcons/template_icon_not_clickable.svg +6 -6
  223. package/src/assets/svgIcons/transfer.svg +4 -4
  224. package/src/assets/svgIcons/trim_tool.svg +4 -4
  225. package/src/assets/svgIcons/truck.svg +3 -3
  226. package/src/assets/svgIcons/underlined.svg +3 -3
  227. package/src/assets/svgIcons/undo.svg +6 -6
  228. package/src/assets/svgIcons/uparrow.svg +3 -3
  229. package/src/assets/svgIcons/update.svg +3 -3
  230. package/src/assets/svgIcons/upload_avatar-1.svg +12 -12
  231. package/src/assets/svgIcons/upload_avatar.svg +5 -5
  232. package/src/assets/svgIcons/upload_image.svg +8 -8
  233. package/src/assets/svgIcons/upload_image_tool.svg +7 -7
  234. package/src/assets/svgIcons/variants.svg +6 -6
  235. package/src/assets/svgIcons/vertical_tool.svg +3 -3
  236. package/src/assets/svgIcons/virtual_storage.svg +4 -4
  237. package/src/assets/svgIcons/warning.svg +4 -4
  238. package/src/assets/svgIcons/way.svg +5 -5
  239. package/src/assets/svgIcons/wifi.svg +3 -3
  240. package/src/assets/svgIcons/winter.svg +3 -3
  241. package/src/assets/svgIcons/workflow_template.svg +11 -11
  242. package/src/assets/theme.js +41 -41
  243. package/src/components/addNewButton/AddNewButton.stories.js +24 -24
  244. package/src/components/addNewButton/index.vue +61 -61
  245. package/src/components/banner/actionBanner/index.vue +64 -64
  246. package/src/components/banner/banner/banner.stories.js +31 -31
  247. package/src/components/banner/banner/index.vue +188 -188
  248. package/src/components/banner/infoBanner/index.vue +57 -57
  249. package/src/components/buttons/buttonIcon/index.vue +145 -145
  250. package/src/components/buttons/closeButton/CloseButton.stories.js +29 -29
  251. package/src/components/buttons/closeButton/index.vue +61 -61
  252. package/src/components/buttons/mainButton/index.vue +140 -142
  253. package/src/components/card/index.vue +96 -96
  254. package/src/components/collapsableInfoText/index.vue +127 -127
  255. package/src/components/deleteIcon/DeleteIcon.stories.js +29 -29
  256. package/src/components/deleteIcon/index.vue +78 -78
  257. package/src/components/draggableInputHandle/index.vue +46 -46
  258. package/src/components/dropdown/Dropdown.stories.js +53 -53
  259. package/src/components/dropdown/index.vue +138 -138
  260. package/src/components/errorMessage/index.vue +64 -64
  261. package/src/components/filter/filterSettings.vue +639 -639
  262. package/src/components/filter/index.vue +154 -154
  263. package/src/components/filter/parentDropdown.vue +91 -91
  264. package/src/components/icon/Icons.stories.js +41 -41
  265. package/src/components/icon/iconCache.js +23 -23
  266. package/src/components/icon/iconCollection.vue +68 -68
  267. package/src/components/icon/index.vue +140 -140
  268. package/src/components/iconWrapper/index.vue +179 -179
  269. package/src/components/infoCard/index.vue +40 -40
  270. package/src/components/infoText/index.vue +170 -170
  271. package/src/components/inputs/checkbox/Checkbox.stories.js +57 -57
  272. package/src/components/inputs/checkbox/index.vue +224 -224
  273. package/src/components/inputs/inputNumber/InputNumber.stories.js +150 -150
  274. package/src/components/inputs/inputNumber/index.vue +784 -784
  275. package/src/components/inputs/inputNumberQuestion/index.vue +218 -218
  276. package/src/components/inputs/inputText/InputText.stories.js +75 -75
  277. package/src/components/inputs/inputText/index.vue +376 -376
  278. package/src/components/inputs/radioButton/RadioButton.stories.js +58 -58
  279. package/src/components/inputs/radioButton/index.vue +273 -273
  280. package/src/components/inputs/searchInput/SearchInput.stories.js +40 -40
  281. package/src/components/inputs/searchInput/index.vue +151 -151
  282. package/src/components/inputs/select/index.vue +907 -907
  283. package/src/components/inputs/select/option/index.vue +148 -148
  284. package/src/components/inputs/select/select.stories.js +58 -58
  285. package/src/components/inputs/slider/index.vue +126 -126
  286. package/src/components/inputs/switchField/index.vue +254 -254
  287. package/src/components/inputs/textAreaInput/TextAreaInput.stories.js +127 -127
  288. package/src/components/inputs/textAreaInput/index.vue +198 -198
  289. package/src/components/inputs/toggle/Toggle.stories.js +77 -77
  290. package/src/components/inputs/toggle/index.vue +285 -285
  291. package/src/components/label/index.vue +99 -99
  292. package/src/components/markerItem/index.vue +88 -88
  293. package/src/components/modals/actionModal/index.vue +64 -64
  294. package/src/components/modals/infoModal/index.vue +52 -52
  295. package/src/components/modals/modal/index.vue +188 -188
  296. package/src/components/modals/modal/modal.stories.js +31 -31
  297. package/src/components/navigationTabs/index.vue +114 -114
  298. package/src/components/pageSubtitle/index.vue +67 -67
  299. package/src/components/pageTitle/index.vue +68 -68
  300. package/src/components/pagination/index.vue +148 -148
  301. package/src/components/progressBar/index.vue +125 -125
  302. package/src/components/projectMarker/index.vue +300 -300
  303. package/src/components/rangeSlider/Slider.vue +573 -573
  304. package/src/components/rangeSlider/index.vue +517 -517
  305. package/src/components/rangeSlider/utils/dom.js +49 -49
  306. package/src/components/rangeSlider/utils/fns.js +26 -26
  307. package/src/components/selectedOptions/index.vue +145 -145
  308. package/src/components/sideMenu/index.vue +270 -270
  309. package/src/components/spinner/index.vue +68 -68
  310. package/src/components/tableDropdown/index.vue +638 -638
  311. package/src/components/tables/mainTable/exampleNested.vue +328 -328
  312. package/src/components/tables/mainTable/index.vue +510 -510
  313. package/src/components/tables/viewTable/index.vue +195 -195
  314. package/src/components/tabsHeader/index.vue +83 -83
  315. package/src/components/threeDots/index.vue +413 -413
  316. package/src/components/videoThumbnail/index.vue +103 -103
  317. package/src/components/videoThumbnail/videoThumbnail.stories.js +33 -33
  318. package/src/helpers/currencyMapping.js +28 -28
  319. package/src/helpers/numberConverter.js +103 -103
  320. package/src/helpers/translateLang.js +128 -128
  321. package/src/main.js +6 -6
  322. package/src/mixins/inputValidations.js +97 -97
@@ -1,784 +1,784 @@
1
- <template>
2
- <Container :align-items="alignItems" :input-width="inputWidth">
3
- <LabelSlotWrapper
4
- v-if="hasLabelSlot"
5
- :align-items="alignItems"
6
- :border-color="borderColor"
7
- :is-error="isError"
8
- :is-interactive="isInteractive"
9
- :no-border="noBorder"
10
- @mousedown="initInteraction"
11
- >
12
- <slot name="label"></slot>
13
- </LabelSlotWrapper>
14
-
15
- <LabelWrapper v-if="labelText">
16
- <LabelText :data-id="labelDataId" :label-font-color="labelFontColor">
17
- {{ labelText }}
18
- </LabelText>
19
-
20
- <InfoText
21
- v-if="labelInfoText"
22
- :align-arrow="labelInfoAlign"
23
- :text="labelInfoText"
24
- />
25
- </LabelWrapper>
26
- <InputWrapper>
27
- <InputContainer
28
- v-bind="$attrs"
29
- ref="inputField1"
30
- :align-items="alignItems"
31
- :background-color="backgroundColor"
32
- :border-color="borderColor"
33
- :data-id="inputDataId"
34
- :disabled="disabled"
35
- :font-color="fontColor"
36
- :font-size="fontSize"
37
- :has-label-slot="hasLabelSlot"
38
- :has-slot="hasSlot"
39
- :has-unit="unitName && !!unitName.length"
40
- :input-height="inputHeight"
41
- :is-disabled="disabled"
42
- :is-error="isError"
43
- :is-interactive="isInteractive"
44
- :min-width="minWidth"
45
- :no-border="noBorder"
46
- :placeholder="displayedPlaceholder"
47
- :show-linear-unit-name="showLinearUnitName"
48
- :slot-size="slotSize"
49
- :text-align="textAlign"
50
- :value="formatWithCurrency(value)"
51
- @blur="onInputBlur($event)"
52
- @focus="focusInput()"
53
- @input="onInput($event)"
54
- @keyup.enter="onEnterPress"
55
- />
56
- <SlotContainer v-if="hasSlot" :is-error="isError" :slot-size="slotSize">
57
- <slot></slot>
58
- </SlotContainer>
59
-
60
- <UnitContainer
61
- v-if="unitName && showLinearUnitName && !hasSlot"
62
- :has-length="!!textInput.length"
63
- :is-error="isError"
64
- >{{ unitName }}</UnitContainer
65
- >
66
- <IconWrapper
67
- v-if="isError && !showLinearUnitName"
68
- :margin-right="showSelect ? selectWidth : 0"
69
- size="16px"
70
- >
71
- <Icon cursor="default" name="warning" size="16px" />
72
- </IconWrapper>
73
- <SelectWrapper v-if="showSelect">
74
- <Divider />
75
- <Select
76
- :select-width="`${selectWidth}px`"
77
- :show-border="false"
78
- @input-change="$emit('select-change', $event)"
79
- >
80
- <template #selector>
81
- <SelectText>{{ getSelectValue }}</SelectText>
82
- </template>
83
- <template #dropdown>
84
- <Option
85
- v-for="item in selectOptions"
86
- :key="item.value"
87
- :value="item.value"
88
- >
89
- {{ item.label }}
90
- </Option>
91
- </template>
92
- </Select>
93
- </SelectWrapper>
94
- </InputWrapper>
95
- <ErrorMessage v-if="isError">{{ errorMessage }}</ErrorMessage>
96
- </Container>
97
- </template>
98
-
99
- <script>
100
- // import InputNumber from "@eturnity/eturnity_reusable_components/src/components/inputs/inputNumber"
101
- //This component should be used for questions with input fields only
102
- //How to use:
103
- // <input-number
104
- // placeholder="Enter distance"
105
- // :isError="false" //default is false
106
- // inputWidth="150px" //by default, this is 100%
107
- // minWidth="100px"
108
- // :numberPrecision="3"
109
- // minDecimals="2"
110
- // unitName="pc"
111
- // :value="inputValue" //required -- String
112
- // @input-change="onInputChange($event)" //required
113
- // @on-enter-click="onInputSubmit()"
114
- // :errorMessage="Enter a number between 1 and 10"
115
- // :disabled="false"
116
- // :noBorder="true"
117
- // textAlign="left" // "left, right, center"
118
- // :showLinearUnitName="true"
119
- // fontSize="13px"
120
- // labelText="Number of Modules"
121
- // labelInfoText="Here is some information for you..."
122
- // labelInfoAlign="left"
123
- // :minNumber="0"
124
- // fontColor="blue"
125
- // >
126
- //<template name=label><img>....</template>
127
- //</inputNumber>
128
- import styled from 'vue3-styled-components'
129
- import {
130
- stringToNumber,
131
- numberToString,
132
- } from '../../../helpers/numberConverter'
133
- import InfoText from '../../infoText'
134
- import ErrorMessage from '../../errorMessage'
135
- import Select from '../select'
136
- import Option from '../select/option'
137
- import warningIcon from '../../../assets/icons/error_icon.png'
138
- import Icon from '../../icon'
139
-
140
- const inputProps = {
141
- isError: Boolean,
142
- hasUnit: Boolean,
143
- inputWidth: String,
144
- minWidth: String,
145
- isDisabled: Boolean,
146
- noBorder: Boolean,
147
- textAlign: String,
148
- fontSize: String,
149
- fontColor: String,
150
- backgroundColor: String,
151
- hasSlot: Boolean,
152
- hasLabelSlot: Boolean,
153
- slotSize: String,
154
- inputHeight: String,
155
- isInteractive: Boolean,
156
- alignItems: String,
157
- labelFontColor: String,
158
- borderColor: String,
159
- showLinearUnitName: Boolean,
160
- }
161
-
162
- const Container = styled('div', inputProps)`
163
- width: ${(props) => (props.inputWidth ? props.inputWidth : '100%')};
164
- position: relative;
165
- display: grid;
166
- grid-template-columns: ${(props) =>
167
- props.alignItems === 'vertical' ? '1fr' : 'auto 1fr'};
168
- `
169
-
170
- const InputContainer = styled('input', inputProps)`
171
- border: ${(props) =>
172
- props.isError
173
- ? '1px solid ' + props.theme.colors.red
174
- : props.noBorder
175
- ? 'none'
176
- : props.borderColor
177
- ? props.theme.colors[props.borderColor]
178
- ? '1px solid ' + props.theme.colors[props.borderColor]
179
- : '1px solid ' + props.borderColor
180
- : '1px solid ' + props.theme.colors.grey4};
181
- height: ${(props) => props.inputHeight};
182
- max-height: ${(props) => props.inputHeight};
183
- padding: 0 10px;
184
- padding-right: ${({ slotSize, isError, showLinearUnitName }) =>
185
- slotSize
186
- ? isError && !showLinearUnitName
187
- ? 'calc(' + slotSize + ' + 24px)'
188
- : 'calc(' + slotSize + ' + 10px)'
189
- : isError && !showLinearUnitName
190
- ? '24px'
191
- : '5px'};
192
- border-radius: ${(props) =>
193
- props.isInteractive && props.alignItems != 'vertical'
194
- ? '0 4px 4px 0'
195
- : '4px'};
196
- text-align: ${(props) => props.textAlign};
197
- cursor: ${(props) => (props.isDisabled ? 'not-allowed' : 'auto')};
198
- font-size: ${(props) => (props.fontSize ? props.fontSize : '13px')};
199
- color: ${(props) =>
200
- props.isError
201
- ? props.theme.colors.grey6
202
- : props.isDisabled
203
- ? props.theme.colors.grey2
204
- : props.fontColor
205
- ? props.fontColor + ' !important'
206
- : props.theme.colors.black};
207
- background-color: ${(props) =>
208
- props.backgroundColor
209
- ? props.backgroundColor + ' !important'
210
- : props.theme.colors.white};
211
- width: ${(props) =>
212
- props.inputWidth && !props.hasLabelSlot ? props.inputWidth : '100%'};
213
- min-width: ${(props) => (props.minWidth ? props.minWidth : 'unset')};
214
- background-color: ${(props) =>
215
- props.isDisabled ? props.theme.colors.grey5 : '#fff'};
216
- box-sizing: border-box;
217
-
218
- &::placeholder {
219
- color: ${(props) => props.theme.colors.grey2};
220
- }
221
-
222
- &:focus {
223
- outline: none;
224
- }
225
- `
226
-
227
- const InputWrapper = styled.span`
228
- position: relative;
229
- `
230
-
231
- const UnitContainer = styled('span', inputProps)`
232
- border-left: 1px solid
233
- ${(props) =>
234
- props.isError
235
- ? props.theme.colors.red
236
- : props.hasLength
237
- ? props.theme.colors.black
238
- : props.theme.colors.mediumGray};
239
- position: absolute;
240
- right: 10px;
241
- top: 10px;
242
- padding-left: 10px;
243
- text-align: right;
244
- color: ${(props) =>
245
- props.isError
246
- ? props.theme.colors.red
247
- : props.hasLength
248
- ? props.theme.colors.black
249
- : props.theme.colors.mediumGray};
250
- `
251
-
252
- const SlotContainer = styled('span', inputProps)`
253
- text-align: right;
254
- border-left: 1px solid
255
- ${(props) =>
256
- props.isError
257
- ? props.theme.colors.red
258
- : props.hasLength
259
- ? props.theme.colors.black
260
- : props.theme.colors.mediumGray};
261
- position: absolute;
262
- width: ${(props) =>
263
- props.slotSize ? 'calc(' + props.slotSize + ' - 10px)' : 'fit-content'};
264
- right: 10px;
265
- top: 10px;
266
- padding-left: 10px;
267
- color: ${(props) =>
268
- props.isError
269
- ? props.theme.colors.red
270
- : props.hasLength
271
- ? props.theme.colors.black
272
- : props.theme.colors.mediumGray};
273
- `
274
-
275
- const LabelWrapper = styled('div', inputProps)`
276
- display: flex;
277
- align-items: center;
278
- gap: 10px;
279
- margin-bottom: 8px;
280
- cursor: ${(props) => (props.isInteractive ? 'ew-resize' : 'auto')};
281
- `
282
- const LabelSlotWrapper = styled('div', inputProps)`
283
- display: flex;
284
- gap: 10px;
285
- align-items: center;
286
- cursor: ${(props) => (props.isInteractive ? 'ew-resize' : 'auto')};
287
- border: ${(props) =>
288
- props.alignItems == 'vertical'
289
- ? 'none'
290
- : props.isError
291
- ? '1px solid ' + props.theme.colors.red
292
- : props.noBorder
293
- ? 'none'
294
- : props.borderColor
295
- ? props.theme.colors[props.borderColor]
296
- ? '1px solid ' + props.theme.colors[props.borderColor]
297
- : '1px solid ' + props.borderColor
298
- : '1px solid ' + props.theme.colors.grey4};
299
- border-radius: 4px 0 0 4px;
300
- border-right: none;
301
- `
302
-
303
- const LabelText = styled('div', inputProps)`
304
- font-size: 13px;
305
- color: ${(props) =>
306
- props.theme.colors[props.labelFontColor]
307
- ? props.theme.colors[props.labelFontColor]
308
- : props.labelFontColor};
309
- font-weight: 700;
310
- `
311
-
312
- const IconAttrs = { size: String, marginRight: Number }
313
- const IconWrapper = styled('div', IconAttrs)`
314
- position: absolute;
315
- top: 0;
316
- bottom: 0;
317
- margin: auto;
318
- right: ${(props) => props.marginRight + 10}px;
319
- height: ${(props) => (props.size ? props.size : 'auto')};
320
- `
321
-
322
- const SelectText = styled.div`
323
- font-size: 13px;
324
- `
325
-
326
- const SelectWrapper = styled.div`
327
- position: absolute;
328
- top: 2px;
329
- right: 2px;
330
- display: flex;
331
- height: 100%;
332
- `
333
-
334
- const Divider = styled.div`
335
- margin-top: 6px;
336
- height: calc(100% - 16px);
337
- width: 1px;
338
- background-color: ${({ theme }) => theme.colors.grey4};
339
- `
340
-
341
- export default {
342
- name: 'InputNumber',
343
- components: {
344
- Container,
345
- InputContainer,
346
- InputWrapper,
347
- UnitContainer,
348
- ErrorMessage,
349
- LabelWrapper,
350
- LabelSlotWrapper,
351
- LabelText,
352
- InfoText,
353
- Icon,
354
- SlotContainer,
355
- IconWrapper,
356
- Select,
357
- Option,
358
- SelectWrapper,
359
- SelectText,
360
- Divider,
361
- },
362
- inheritAttrs: false,
363
- props: {
364
- placeholder: {
365
- required: false,
366
- default: '',
367
- },
368
- isError: {
369
- required: false,
370
- default: false,
371
- },
372
- inputWidth: {
373
- required: false,
374
- default: null,
375
- },
376
- minWidth: {
377
- required: false,
378
- default: null,
379
- },
380
- inputHeight: {
381
- required: false,
382
- default: '40px',
383
- },
384
- value: {
385
- required: true,
386
- default: null,
387
- },
388
- clearInput: {
389
- required: false,
390
- default: false,
391
- },
392
- alignItems: {
393
- required: false,
394
- default: 'vertical',
395
- },
396
- errorMessage: {
397
- required: false,
398
- default: 'Please insert a correct number',
399
- },
400
- numberPrecision: {
401
- required: false,
402
- default: 0,
403
- },
404
- minDecimals: {
405
- required: false,
406
- default: 0,
407
- },
408
- unitName: {
409
- required: false,
410
- default: '',
411
- },
412
- showLinearUnitName: {
413
- required: false,
414
- default: false,
415
- },
416
- disabled: {
417
- required: false,
418
- default: false,
419
- },
420
- noBorder: {
421
- required: false,
422
- default: false,
423
- },
424
- borderColor: {
425
- required: false,
426
- },
427
- textAlign: {
428
- required: false,
429
- default: 'left',
430
- },
431
- fontSize: {
432
- required: false,
433
- default: '13px',
434
- },
435
- isInteractive: {
436
- required: false,
437
- default: false,
438
- },
439
- interactionStep: {
440
- required: false,
441
- default: 1,
442
- },
443
- labelText: {
444
- required: false,
445
- default: null,
446
- },
447
- labelInfoText: {
448
- required: false,
449
- default: null,
450
- },
451
- labelInfoAlign: {
452
- required: false,
453
- default: 'left',
454
- },
455
- defaultNumber: {
456
- required: false,
457
- default: null,
458
- },
459
- minNumber: {
460
- required: false,
461
- default: null,
462
- },
463
- fontColor: {
464
- required: false,
465
- default: null,
466
- },
467
- backgroundColor: {
468
- required: false,
469
- default: null,
470
- },
471
- numberToStringEnabled: {
472
- required: false,
473
- default: true,
474
- },
475
- allowNegative: {
476
- required: false,
477
- default: true,
478
- },
479
- slotSize: {
480
- required: false,
481
- },
482
- labelFontColor: {
483
- required: false,
484
- default: 'eturnityGrey',
485
- },
486
- focus: {
487
- required: false,
488
- default: false,
489
- },
490
- labelDataId: {
491
- required: false,
492
- default: '',
493
- },
494
- inputDataId: {
495
- required: false,
496
- default: '',
497
- },
498
- showSelect: {
499
- type: Boolean,
500
- default: false,
501
- },
502
- selectWidth: {
503
- type: Number,
504
- default: 70,
505
- },
506
- selectOptions: {
507
- type: Array,
508
- default: () => [],
509
- },
510
- selectValue: {
511
- type: [String, Number],
512
- default: null,
513
- },
514
- },
515
- data() {
516
- return {
517
- textInput: '',
518
- isFocused: false,
519
- warningIcon: warningIcon,
520
- }
521
- },
522
- computed: {
523
- displayedPlaceholder() {
524
- if (this.placeholder) return this.placeholder
525
- if (this.defaultNumber)
526
- return `${this.defaultNumber} ${this.unitName ? this.unitName : ''}`
527
- return `${this.minNumber || 0} ${this.unitName ? this.unitName : ''}`
528
- },
529
- hasSlot() {
530
- return !!this.$slots.default
531
- },
532
- hasLabelSlot() {
533
- return !!this.$slots.label
534
- },
535
- getSelectValue() {
536
- const item = this.selectOptions.find(
537
- ({ value }) => value === this.selectValue
538
- )
539
-
540
- return item ? item.label : '-'
541
- },
542
- },
543
- watch: {
544
- focus(value) {
545
- if (value) {
546
- this.focusInput()
547
- }
548
- },
549
- clearInput: function (value) {
550
- if (value) {
551
- // If the value is typed, then we should clear the textInput on Continue
552
- this.textInput = ''
553
- }
554
- },
555
- },
556
- created() {
557
- if (this.value) {
558
- this.textInput = numberToString({
559
- value: this.value,
560
- numberPrecision: this.numberPrecision,
561
- minDecimals: this.minDecimals,
562
- })
563
- } else if (this.defaultNumber !== null) {
564
- this.textInput = numberToString({
565
- value: this.defaultNumber,
566
- numberPrecision: this.numberPrecision,
567
- minDecimals: this.minDecimals,
568
- })
569
- } else if (this.minNumber !== null) {
570
- this.textInput = numberToString({
571
- value: this.minNumber,
572
- numberPrecision: this.numberPrecision,
573
- minDecimals: this.minDecimals,
574
- })
575
- }
576
- },
577
- mounted() {
578
- if (this.focus) {
579
- this.focusInput()
580
- }
581
- },
582
- methods: {
583
- onEnterPress() {
584
- this.$emit('on-enter-click')
585
- this.$refs.inputField1.$el.blur()
586
- },
587
- onChangeHandler(event) {
588
- if (isNaN(event) || event === '') {
589
- event = this.defaultNumber
590
- ? this.defaultNumber
591
- : this.minNumber || this.minNumber === 0
592
- ? this.minNumber
593
- : event
594
- }
595
- if (!this.allowNegative) {
596
- event = Math.abs(event)
597
- }
598
- event = parseFloat(event)
599
- // Need to return an integer rather than a string
600
- this.$emit('input-change', event)
601
- },
602
- onEvaluateCode(event) {
603
- // function to perform math on the code
604
- // filter the string in case of any malicious content
605
- const val = event.target.value
606
- let filtered = val.replace('(auto)', '').replace(/[^-()\d/*+.,]/g, '')
607
- filtered = filtered.split(/([-+*/()])/)
608
- let formatted = filtered.map((item) => {
609
- if (
610
- item === '+' ||
611
- item === '-' ||
612
- item === '*' ||
613
- item === '/' ||
614
- item === '(' ||
615
- item === ')' ||
616
- item === ''
617
- ) {
618
- return item
619
- } else {
620
- let num = stringToNumber({
621
- value: item,
622
- numberPrecision: false,
623
- minDecimals: this.minDecimals,
624
- })
625
- return num
626
- }
627
- })
628
- let evaluated
629
- formatted = this.removeStringItemsAfterLastNumber(formatted)
630
- evaluated = eval(formatted.join(' '))
631
- if (typeof evaluated === 'string') {
632
- evaluated = stringToNumber({
633
- value: evaluated,
634
- numberPrecision: this.numberPrecision,
635
- minDecimals: this.minDecimals,
636
- })
637
- } else if (typeof evaluated === 'number') {
638
- evaluated = evaluated.toFixed(this.numberPrecision)
639
- }
640
- return evaluated
641
- },
642
- removeStringItemsAfterLastNumber(array) {
643
- // fixed in EPDM-6487, in order to prevent 'Unexpected end of input'
644
- let lastNumberIndex = -1
645
- // Find the index of the last number in the array
646
- for (let i = array.length - 1; i >= 0; i--) {
647
- if (typeof array[i] === 'number') {
648
- lastNumberIndex = i
649
- break
650
- }
651
- }
652
- // if there are no numbers, return an empty array
653
- if (lastNumberIndex === -1) {
654
- return []
655
- }
656
- // Remove non-numeric items after the last number
657
- if (lastNumberIndex !== -1) {
658
- const newArray = array.slice(0, lastNumberIndex + 1)
659
- return newArray
660
- }
661
- return array
662
- },
663
- onInput(event) {
664
- if (!this.isFocused) {
665
- return
666
- }
667
- if (event.target.value === '') {
668
- this.$emit('on-input', '')
669
- }
670
- let evaluatedVal
671
- try {
672
- evaluatedVal = this.onEvaluateCode(event)
673
- } finally {
674
- if (evaluatedVal && this.value != evaluatedVal) {
675
- this.$emit('on-input', evaluatedVal)
676
- }
677
- }
678
- },
679
- onInputBlur(e) {
680
- this.isFocused = false
681
- let value = e.target.value
682
- let evaluatedInput = this.onEvaluateCode(e)
683
- this.onChangeHandler(evaluatedInput ? evaluatedInput : value)
684
- if ((evaluatedInput && value.length) || this.minNumber !== null) {
685
- this.textInput = numberToString({
686
- value:
687
- evaluatedInput && value.length
688
- ? evaluatedInput
689
- : this.defaultNumber
690
- ? this.defaultNumber
691
- : this.minNumber,
692
- numberPrecision: this.numberPrecision,
693
- minDecimals: this.minDecimals,
694
- })
695
- }
696
- let adjustedMinValue =
697
- evaluatedInput && evaluatedInput.length
698
- ? evaluatedInput
699
- : this.defaultNumber
700
- ? this.defaultNumber
701
- : this.minNumber || this.minNumber === 0
702
- ? this.minNumber
703
- : ''
704
- this.$emit('input-blur', adjustedMinValue)
705
- },
706
- focusInput() {
707
- if (this.disabled) {
708
- return
709
- }
710
- this.isFocused = true
711
- this.$nextTick(() => {
712
- this.$refs.inputField1.$el.select()
713
- })
714
- this.$emit('input-focus')
715
- },
716
- blurInput() {
717
- if (this.disabled) {
718
- return
719
- }
720
- this.isFocused = false
721
- this.$nextTick(() => {
722
- this.$refs.inputField1.$el.blur()
723
- })
724
- },
725
- formatWithCurrency(value) {
726
- let adjustedMinValue =
727
- value || value === 0
728
- ? value
729
- : this.defaultNumber
730
- ? this.defaultNumber
731
- : this.minNumber || this.minNumber === 0
732
- ? this.minNumber
733
- : ''
734
- if ((adjustedMinValue || adjustedMinValue === 0) && !this.isFocused) {
735
- let input = this.numberToStringEnabled
736
- ? numberToString({
737
- value: adjustedMinValue,
738
- numberPrecision: this.numberPrecision,
739
- minDecimals: this.minDecimals,
740
- })
741
- : adjustedMinValue
742
- let unit = this.showLinearUnitName ? '' : this.unitName
743
- //return input + ' ' + unit
744
- return input + ' ' + unit
745
- } else if (!adjustedMinValue && adjustedMinValue !== 0) {
746
- return ''
747
- } else {
748
- return this.numberToStringEnabled
749
- ? numberToString({
750
- value: adjustedMinValue,
751
- numberPrecision: this.numberPrecision,
752
- minDecimals: this.minDecimals,
753
- })
754
- : adjustedMinValue
755
- }
756
- },
757
- initInteraction(e) {
758
- this.focusInput()
759
- e.preventDefault()
760
- window.addEventListener('mousemove', this.interact, false)
761
- window.addEventListener('mouseup', this.stopInteract, false)
762
- },
763
- interact(e) {
764
- e.preventDefault()
765
- let value = parseFloat(this.value || 0)
766
- value += parseFloat(this.interactionStep) * parseInt(e.movementX)
767
- this.$emit('on-input-drag', value)
768
-
769
- this.textInput = numberToString({
770
- value: value && value.length ? value : this.minNumber,
771
- numberPrecision: this.numberPrecision,
772
- minDecimals: this.minDecimals,
773
- })
774
- //this.value=value
775
- },
776
- stopInteract(e) {
777
- e.preventDefault()
778
- window.removeEventListener('mousemove', this.interact, false)
779
- window.removeEventListener('mouseup', this.stopInteract, false)
780
- this.blurInput()
781
- },
782
- },
783
- }
784
- </script>
1
+ <template>
2
+ <Container :align-items="alignItems" :input-width="inputWidth">
3
+ <LabelSlotWrapper
4
+ v-if="hasLabelSlot"
5
+ :align-items="alignItems"
6
+ :border-color="borderColor"
7
+ :is-error="isError"
8
+ :is-interactive="isInteractive"
9
+ :no-border="noBorder"
10
+ @mousedown="initInteraction"
11
+ >
12
+ <slot name="label"></slot>
13
+ </LabelSlotWrapper>
14
+
15
+ <LabelWrapper v-if="labelText">
16
+ <LabelText :data-id="labelDataId" :label-font-color="labelFontColor">
17
+ {{ labelText }}
18
+ </LabelText>
19
+
20
+ <InfoText
21
+ v-if="labelInfoText"
22
+ :align-arrow="labelInfoAlign"
23
+ :text="labelInfoText"
24
+ />
25
+ </LabelWrapper>
26
+ <InputWrapper>
27
+ <InputContainer
28
+ v-bind="$attrs"
29
+ ref="inputField1"
30
+ :align-items="alignItems"
31
+ :background-color="backgroundColor"
32
+ :border-color="borderColor"
33
+ :data-id="inputDataId"
34
+ :disabled="disabled"
35
+ :font-color="fontColor"
36
+ :font-size="fontSize"
37
+ :has-label-slot="hasLabelSlot"
38
+ :has-slot="hasSlot"
39
+ :has-unit="unitName && !!unitName.length"
40
+ :input-height="inputHeight"
41
+ :is-disabled="disabled"
42
+ :is-error="isError"
43
+ :is-interactive="isInteractive"
44
+ :min-width="minWidth"
45
+ :no-border="noBorder"
46
+ :placeholder="displayedPlaceholder"
47
+ :show-linear-unit-name="showLinearUnitName"
48
+ :slot-size="slotSize"
49
+ :text-align="textAlign"
50
+ :value="formatWithCurrency(value)"
51
+ @blur="onInputBlur($event)"
52
+ @focus="focusInput()"
53
+ @input="onInput($event)"
54
+ @keyup.enter="onEnterPress"
55
+ />
56
+ <SlotContainer v-if="hasSlot" :is-error="isError" :slot-size="slotSize">
57
+ <slot></slot>
58
+ </SlotContainer>
59
+
60
+ <UnitContainer
61
+ v-if="unitName && showLinearUnitName && !hasSlot"
62
+ :has-length="!!textInput.length"
63
+ :is-error="isError"
64
+ >{{ unitName }}</UnitContainer
65
+ >
66
+ <IconWrapper
67
+ v-if="isError && !showLinearUnitName"
68
+ :margin-right="showSelect ? selectWidth : 0"
69
+ size="16px"
70
+ >
71
+ <Icon cursor="default" name="warning" size="16px" />
72
+ </IconWrapper>
73
+ <SelectWrapper v-if="showSelect">
74
+ <Divider />
75
+ <Select
76
+ :select-width="`${selectWidth}px`"
77
+ :show-border="false"
78
+ @input-change="$emit('select-change', $event)"
79
+ >
80
+ <template #selector>
81
+ <SelectText>{{ getSelectValue }}</SelectText>
82
+ </template>
83
+ <template #dropdown>
84
+ <Option
85
+ v-for="item in selectOptions"
86
+ :key="item.value"
87
+ :value="item.value"
88
+ >
89
+ {{ item.label }}
90
+ </Option>
91
+ </template>
92
+ </Select>
93
+ </SelectWrapper>
94
+ </InputWrapper>
95
+ <ErrorMessage v-if="isError">{{ errorMessage }}</ErrorMessage>
96
+ </Container>
97
+ </template>
98
+
99
+ <script>
100
+ // import InputNumber from "@eturnity/eturnity_reusable_components/src/components/inputs/inputNumber"
101
+ //This component should be used for questions with input fields only
102
+ //How to use:
103
+ // <input-number
104
+ // placeholder="Enter distance"
105
+ // :isError="false" //default is false
106
+ // inputWidth="150px" //by default, this is 100%
107
+ // minWidth="100px"
108
+ // :numberPrecision="3"
109
+ // minDecimals="2"
110
+ // unitName="pc"
111
+ // :value="inputValue" //required -- String
112
+ // @input-change="onInputChange($event)" //required
113
+ // @on-enter-click="onInputSubmit()"
114
+ // :errorMessage="Enter a number between 1 and 10"
115
+ // :disabled="false"
116
+ // :noBorder="true"
117
+ // textAlign="left" // "left, right, center"
118
+ // :showLinearUnitName="true"
119
+ // fontSize="13px"
120
+ // labelText="Number of Modules"
121
+ // labelInfoText="Here is some information for you..."
122
+ // labelInfoAlign="left"
123
+ // :minNumber="0"
124
+ // fontColor="blue"
125
+ // >
126
+ //<template name=label><img>....</template>
127
+ //</inputNumber>
128
+ import styled from 'vue3-styled-components'
129
+ import {
130
+ stringToNumber,
131
+ numberToString,
132
+ } from '../../../helpers/numberConverter'
133
+ import InfoText from '../../infoText'
134
+ import ErrorMessage from '../../errorMessage'
135
+ import Select from '../select'
136
+ import Option from '../select/option'
137
+ import warningIcon from '../../../assets/icons/error_icon.png'
138
+ import Icon from '../../icon'
139
+
140
+ const inputProps = {
141
+ isError: Boolean,
142
+ hasUnit: Boolean,
143
+ inputWidth: String,
144
+ minWidth: String,
145
+ isDisabled: Boolean,
146
+ noBorder: Boolean,
147
+ textAlign: String,
148
+ fontSize: String,
149
+ fontColor: String,
150
+ backgroundColor: String,
151
+ hasSlot: Boolean,
152
+ hasLabelSlot: Boolean,
153
+ slotSize: String,
154
+ inputHeight: String,
155
+ isInteractive: Boolean,
156
+ alignItems: String,
157
+ labelFontColor: String,
158
+ borderColor: String,
159
+ showLinearUnitName: Boolean,
160
+ }
161
+
162
+ const Container = styled('div', inputProps)`
163
+ width: ${(props) => (props.inputWidth ? props.inputWidth : '100%')};
164
+ position: relative;
165
+ display: grid;
166
+ grid-template-columns: ${(props) =>
167
+ props.alignItems === 'vertical' ? '1fr' : 'auto 1fr'};
168
+ `
169
+
170
+ const InputContainer = styled('input', inputProps)`
171
+ border: ${(props) =>
172
+ props.isError
173
+ ? '1px solid ' + props.theme.colors.red
174
+ : props.noBorder
175
+ ? 'none'
176
+ : props.borderColor
177
+ ? props.theme.colors[props.borderColor]
178
+ ? '1px solid ' + props.theme.colors[props.borderColor]
179
+ : '1px solid ' + props.borderColor
180
+ : '1px solid ' + props.theme.colors.grey4};
181
+ height: ${(props) => props.inputHeight};
182
+ max-height: ${(props) => props.inputHeight};
183
+ padding: 0 10px;
184
+ padding-right: ${({ slotSize, isError, showLinearUnitName }) =>
185
+ slotSize
186
+ ? isError && !showLinearUnitName
187
+ ? 'calc(' + slotSize + ' + 24px)'
188
+ : 'calc(' + slotSize + ' + 10px)'
189
+ : isError && !showLinearUnitName
190
+ ? '24px'
191
+ : '5px'};
192
+ border-radius: ${(props) =>
193
+ props.isInteractive && props.alignItems != 'vertical'
194
+ ? '0 4px 4px 0'
195
+ : '4px'};
196
+ text-align: ${(props) => props.textAlign};
197
+ cursor: ${(props) => (props.isDisabled ? 'not-allowed' : 'auto')};
198
+ font-size: ${(props) => (props.fontSize ? props.fontSize : '13px')};
199
+ color: ${(props) =>
200
+ props.isError
201
+ ? props.theme.colors.grey6
202
+ : props.isDisabled
203
+ ? props.theme.colors.grey2
204
+ : props.fontColor
205
+ ? props.fontColor + ' !important'
206
+ : props.theme.colors.black};
207
+ background-color: ${(props) =>
208
+ props.backgroundColor
209
+ ? props.backgroundColor + ' !important'
210
+ : props.theme.colors.white};
211
+ width: ${(props) =>
212
+ props.inputWidth && !props.hasLabelSlot ? props.inputWidth : '100%'};
213
+ min-width: ${(props) => (props.minWidth ? props.minWidth : 'unset')};
214
+ background-color: ${(props) =>
215
+ props.isDisabled ? props.theme.colors.grey5 : '#fff'};
216
+ box-sizing: border-box;
217
+
218
+ &::placeholder {
219
+ color: ${(props) => props.theme.colors.grey2};
220
+ }
221
+
222
+ &:focus {
223
+ outline: none;
224
+ }
225
+ `
226
+
227
+ const InputWrapper = styled.span`
228
+ position: relative;
229
+ `
230
+
231
+ const UnitContainer = styled('span', inputProps)`
232
+ border-left: 1px solid
233
+ ${(props) =>
234
+ props.isError
235
+ ? props.theme.colors.red
236
+ : props.hasLength
237
+ ? props.theme.colors.black
238
+ : props.theme.colors.mediumGray};
239
+ position: absolute;
240
+ right: 10px;
241
+ top: 10px;
242
+ padding-left: 10px;
243
+ text-align: right;
244
+ color: ${(props) =>
245
+ props.isError
246
+ ? props.theme.colors.red
247
+ : props.hasLength
248
+ ? props.theme.colors.black
249
+ : props.theme.colors.mediumGray};
250
+ `
251
+
252
+ const SlotContainer = styled('span', inputProps)`
253
+ text-align: right;
254
+ border-left: 1px solid
255
+ ${(props) =>
256
+ props.isError
257
+ ? props.theme.colors.red
258
+ : props.hasLength
259
+ ? props.theme.colors.black
260
+ : props.theme.colors.mediumGray};
261
+ position: absolute;
262
+ width: ${(props) =>
263
+ props.slotSize ? 'calc(' + props.slotSize + ' - 10px)' : 'fit-content'};
264
+ right: 10px;
265
+ top: 10px;
266
+ padding-left: 10px;
267
+ color: ${(props) =>
268
+ props.isError
269
+ ? props.theme.colors.red
270
+ : props.hasLength
271
+ ? props.theme.colors.black
272
+ : props.theme.colors.mediumGray};
273
+ `
274
+
275
+ const LabelWrapper = styled('div', inputProps)`
276
+ display: flex;
277
+ align-items: center;
278
+ gap: 10px;
279
+ margin-bottom: 8px;
280
+ cursor: ${(props) => (props.isInteractive ? 'ew-resize' : 'auto')};
281
+ `
282
+ const LabelSlotWrapper = styled('div', inputProps)`
283
+ display: flex;
284
+ gap: 10px;
285
+ align-items: center;
286
+ cursor: ${(props) => (props.isInteractive ? 'ew-resize' : 'auto')};
287
+ border: ${(props) =>
288
+ props.alignItems == 'vertical'
289
+ ? 'none'
290
+ : props.isError
291
+ ? '1px solid ' + props.theme.colors.red
292
+ : props.noBorder
293
+ ? 'none'
294
+ : props.borderColor
295
+ ? props.theme.colors[props.borderColor]
296
+ ? '1px solid ' + props.theme.colors[props.borderColor]
297
+ : '1px solid ' + props.borderColor
298
+ : '1px solid ' + props.theme.colors.grey4};
299
+ border-radius: 4px 0 0 4px;
300
+ border-right: none;
301
+ `
302
+
303
+ const LabelText = styled('div', inputProps)`
304
+ font-size: 13px;
305
+ color: ${(props) =>
306
+ props.theme.colors[props.labelFontColor]
307
+ ? props.theme.colors[props.labelFontColor]
308
+ : props.labelFontColor};
309
+ font-weight: 700;
310
+ `
311
+
312
+ const IconAttrs = { size: String, marginRight: Number }
313
+ const IconWrapper = styled('div', IconAttrs)`
314
+ position: absolute;
315
+ top: 0;
316
+ bottom: 0;
317
+ margin: auto;
318
+ right: ${(props) => props.marginRight + 10}px;
319
+ height: ${(props) => (props.size ? props.size : 'auto')};
320
+ `
321
+
322
+ const SelectText = styled.div`
323
+ font-size: 13px;
324
+ `
325
+
326
+ const SelectWrapper = styled.div`
327
+ position: absolute;
328
+ top: 2px;
329
+ right: 2px;
330
+ display: flex;
331
+ height: 100%;
332
+ `
333
+
334
+ const Divider = styled.div`
335
+ margin-top: 6px;
336
+ height: calc(100% - 16px);
337
+ width: 1px;
338
+ background-color: ${({ theme }) => theme.colors.grey4};
339
+ `
340
+
341
+ export default {
342
+ name: 'InputNumber',
343
+ components: {
344
+ Container,
345
+ InputContainer,
346
+ InputWrapper,
347
+ UnitContainer,
348
+ ErrorMessage,
349
+ LabelWrapper,
350
+ LabelSlotWrapper,
351
+ LabelText,
352
+ InfoText,
353
+ Icon,
354
+ SlotContainer,
355
+ IconWrapper,
356
+ Select,
357
+ Option,
358
+ SelectWrapper,
359
+ SelectText,
360
+ Divider,
361
+ },
362
+ inheritAttrs: false,
363
+ props: {
364
+ placeholder: {
365
+ required: false,
366
+ default: '',
367
+ },
368
+ isError: {
369
+ required: false,
370
+ default: false,
371
+ },
372
+ inputWidth: {
373
+ required: false,
374
+ default: null,
375
+ },
376
+ minWidth: {
377
+ required: false,
378
+ default: null,
379
+ },
380
+ inputHeight: {
381
+ required: false,
382
+ default: '40px',
383
+ },
384
+ value: {
385
+ required: true,
386
+ default: null,
387
+ },
388
+ clearInput: {
389
+ required: false,
390
+ default: false,
391
+ },
392
+ alignItems: {
393
+ required: false,
394
+ default: 'vertical',
395
+ },
396
+ errorMessage: {
397
+ required: false,
398
+ default: 'Please insert a correct number',
399
+ },
400
+ numberPrecision: {
401
+ required: false,
402
+ default: 0,
403
+ },
404
+ minDecimals: {
405
+ required: false,
406
+ default: 0,
407
+ },
408
+ unitName: {
409
+ required: false,
410
+ default: '',
411
+ },
412
+ showLinearUnitName: {
413
+ required: false,
414
+ default: false,
415
+ },
416
+ disabled: {
417
+ required: false,
418
+ default: false,
419
+ },
420
+ noBorder: {
421
+ required: false,
422
+ default: false,
423
+ },
424
+ borderColor: {
425
+ required: false,
426
+ },
427
+ textAlign: {
428
+ required: false,
429
+ default: 'left',
430
+ },
431
+ fontSize: {
432
+ required: false,
433
+ default: '13px',
434
+ },
435
+ isInteractive: {
436
+ required: false,
437
+ default: false,
438
+ },
439
+ interactionStep: {
440
+ required: false,
441
+ default: 1,
442
+ },
443
+ labelText: {
444
+ required: false,
445
+ default: null,
446
+ },
447
+ labelInfoText: {
448
+ required: false,
449
+ default: null,
450
+ },
451
+ labelInfoAlign: {
452
+ required: false,
453
+ default: 'left',
454
+ },
455
+ defaultNumber: {
456
+ required: false,
457
+ default: null,
458
+ },
459
+ minNumber: {
460
+ required: false,
461
+ default: null,
462
+ },
463
+ fontColor: {
464
+ required: false,
465
+ default: null,
466
+ },
467
+ backgroundColor: {
468
+ required: false,
469
+ default: null,
470
+ },
471
+ numberToStringEnabled: {
472
+ required: false,
473
+ default: true,
474
+ },
475
+ allowNegative: {
476
+ required: false,
477
+ default: true,
478
+ },
479
+ slotSize: {
480
+ required: false,
481
+ },
482
+ labelFontColor: {
483
+ required: false,
484
+ default: 'eturnityGrey',
485
+ },
486
+ focus: {
487
+ required: false,
488
+ default: false,
489
+ },
490
+ labelDataId: {
491
+ required: false,
492
+ default: '',
493
+ },
494
+ inputDataId: {
495
+ required: false,
496
+ default: '',
497
+ },
498
+ showSelect: {
499
+ type: Boolean,
500
+ default: false,
501
+ },
502
+ selectWidth: {
503
+ type: Number,
504
+ default: 70,
505
+ },
506
+ selectOptions: {
507
+ type: Array,
508
+ default: () => [],
509
+ },
510
+ selectValue: {
511
+ type: [String, Number],
512
+ default: null,
513
+ },
514
+ },
515
+ data() {
516
+ return {
517
+ textInput: '',
518
+ isFocused: false,
519
+ warningIcon: warningIcon,
520
+ }
521
+ },
522
+ computed: {
523
+ displayedPlaceholder() {
524
+ if (this.placeholder) return this.placeholder
525
+ if (this.defaultNumber)
526
+ return `${this.defaultNumber} ${this.unitName ? this.unitName : ''}`
527
+ return `${this.minNumber || 0} ${this.unitName ? this.unitName : ''}`
528
+ },
529
+ hasSlot() {
530
+ return !!this.$slots.default
531
+ },
532
+ hasLabelSlot() {
533
+ return !!this.$slots.label
534
+ },
535
+ getSelectValue() {
536
+ const item = this.selectOptions.find(
537
+ ({ value }) => value === this.selectValue
538
+ )
539
+
540
+ return item ? item.label : '-'
541
+ },
542
+ },
543
+ watch: {
544
+ focus(value) {
545
+ if (value) {
546
+ this.focusInput()
547
+ }
548
+ },
549
+ clearInput: function (value) {
550
+ if (value) {
551
+ // If the value is typed, then we should clear the textInput on Continue
552
+ this.textInput = ''
553
+ }
554
+ },
555
+ },
556
+ created() {
557
+ if (this.value) {
558
+ this.textInput = numberToString({
559
+ value: this.value,
560
+ numberPrecision: this.numberPrecision,
561
+ minDecimals: this.minDecimals,
562
+ })
563
+ } else if (this.defaultNumber !== null) {
564
+ this.textInput = numberToString({
565
+ value: this.defaultNumber,
566
+ numberPrecision: this.numberPrecision,
567
+ minDecimals: this.minDecimals,
568
+ })
569
+ } else if (this.minNumber !== null) {
570
+ this.textInput = numberToString({
571
+ value: this.minNumber,
572
+ numberPrecision: this.numberPrecision,
573
+ minDecimals: this.minDecimals,
574
+ })
575
+ }
576
+ },
577
+ mounted() {
578
+ if (this.focus) {
579
+ this.focusInput()
580
+ }
581
+ },
582
+ methods: {
583
+ onEnterPress() {
584
+ this.$emit('on-enter-click')
585
+ this.$refs.inputField1.$el.blur()
586
+ },
587
+ onChangeHandler(event) {
588
+ if (isNaN(event) || event === '') {
589
+ event = this.defaultNumber
590
+ ? this.defaultNumber
591
+ : this.minNumber || this.minNumber === 0
592
+ ? this.minNumber
593
+ : event
594
+ }
595
+ if (!this.allowNegative) {
596
+ event = Math.abs(event)
597
+ }
598
+ event = parseFloat(event)
599
+ // Need to return an integer rather than a string
600
+ this.$emit('input-change', event)
601
+ },
602
+ onEvaluateCode(event) {
603
+ // function to perform math on the code
604
+ // filter the string in case of any malicious content
605
+ const val = event.target.value
606
+ let filtered = val.replace('(auto)', '').replace(/[^-()\d/*+.,]/g, '')
607
+ filtered = filtered.split(/([-+*/()])/)
608
+ let formatted = filtered.map((item) => {
609
+ if (
610
+ item === '+' ||
611
+ item === '-' ||
612
+ item === '*' ||
613
+ item === '/' ||
614
+ item === '(' ||
615
+ item === ')' ||
616
+ item === ''
617
+ ) {
618
+ return item
619
+ } else {
620
+ let num = stringToNumber({
621
+ value: item,
622
+ numberPrecision: false,
623
+ minDecimals: this.minDecimals,
624
+ })
625
+ return num
626
+ }
627
+ })
628
+ let evaluated
629
+ formatted = this.removeStringItemsAfterLastNumber(formatted)
630
+ evaluated = eval(formatted.join(' '))
631
+ if (typeof evaluated === 'string') {
632
+ evaluated = stringToNumber({
633
+ value: evaluated,
634
+ numberPrecision: this.numberPrecision,
635
+ minDecimals: this.minDecimals,
636
+ })
637
+ } else if (typeof evaluated === 'number') {
638
+ evaluated = evaluated.toFixed(this.numberPrecision)
639
+ }
640
+ return evaluated
641
+ },
642
+ removeStringItemsAfterLastNumber(array) {
643
+ // fixed in EPDM-6487, in order to prevent 'Unexpected end of input'
644
+ let lastNumberIndex = -1
645
+ // Find the index of the last number in the array
646
+ for (let i = array.length - 1; i >= 0; i--) {
647
+ if (typeof array[i] === 'number') {
648
+ lastNumberIndex = i
649
+ break
650
+ }
651
+ }
652
+ // if there are no numbers, return an empty array
653
+ if (lastNumberIndex === -1) {
654
+ return []
655
+ }
656
+ // Remove non-numeric items after the last number
657
+ if (lastNumberIndex !== -1) {
658
+ const newArray = array.slice(0, lastNumberIndex + 1)
659
+ return newArray
660
+ }
661
+ return array
662
+ },
663
+ onInput(event) {
664
+ if (!this.isFocused) {
665
+ return
666
+ }
667
+ if (event.target.value === '') {
668
+ this.$emit('on-input', '')
669
+ }
670
+ let evaluatedVal
671
+ try {
672
+ evaluatedVal = this.onEvaluateCode(event)
673
+ } finally {
674
+ if (evaluatedVal && this.value != evaluatedVal) {
675
+ this.$emit('on-input', evaluatedVal)
676
+ }
677
+ }
678
+ },
679
+ onInputBlur(e) {
680
+ this.isFocused = false
681
+ let value = e.target.value
682
+ let evaluatedInput = this.onEvaluateCode(e)
683
+ this.onChangeHandler(evaluatedInput ? evaluatedInput : value)
684
+ if ((evaluatedInput && value.length) || this.minNumber !== null) {
685
+ this.textInput = numberToString({
686
+ value:
687
+ evaluatedInput && value.length
688
+ ? evaluatedInput
689
+ : this.defaultNumber
690
+ ? this.defaultNumber
691
+ : this.minNumber,
692
+ numberPrecision: this.numberPrecision,
693
+ minDecimals: this.minDecimals,
694
+ })
695
+ }
696
+ let adjustedMinValue =
697
+ evaluatedInput && evaluatedInput.length
698
+ ? evaluatedInput
699
+ : this.defaultNumber
700
+ ? this.defaultNumber
701
+ : this.minNumber || this.minNumber === 0
702
+ ? this.minNumber
703
+ : ''
704
+ this.$emit('input-blur', adjustedMinValue)
705
+ },
706
+ focusInput() {
707
+ if (this.disabled) {
708
+ return
709
+ }
710
+ this.isFocused = true
711
+ this.$nextTick(() => {
712
+ this.$refs.inputField1.$el.select()
713
+ })
714
+ this.$emit('input-focus')
715
+ },
716
+ blurInput() {
717
+ if (this.disabled) {
718
+ return
719
+ }
720
+ this.isFocused = false
721
+ this.$nextTick(() => {
722
+ this.$refs.inputField1.$el.blur()
723
+ })
724
+ },
725
+ formatWithCurrency(value) {
726
+ let adjustedMinValue =
727
+ value || value === 0
728
+ ? value
729
+ : this.defaultNumber
730
+ ? this.defaultNumber
731
+ : this.minNumber || this.minNumber === 0
732
+ ? this.minNumber
733
+ : ''
734
+ if ((adjustedMinValue || adjustedMinValue === 0) && !this.isFocused) {
735
+ let input = this.numberToStringEnabled
736
+ ? numberToString({
737
+ value: adjustedMinValue,
738
+ numberPrecision: this.numberPrecision,
739
+ minDecimals: this.minDecimals,
740
+ })
741
+ : adjustedMinValue
742
+ let unit = this.showLinearUnitName ? '' : this.unitName
743
+ //return input + ' ' + unit
744
+ return input + ' ' + unit
745
+ } else if (!adjustedMinValue && adjustedMinValue !== 0) {
746
+ return ''
747
+ } else {
748
+ return this.numberToStringEnabled
749
+ ? numberToString({
750
+ value: adjustedMinValue,
751
+ numberPrecision: this.numberPrecision,
752
+ minDecimals: this.minDecimals,
753
+ })
754
+ : adjustedMinValue
755
+ }
756
+ },
757
+ initInteraction(e) {
758
+ this.focusInput()
759
+ e.preventDefault()
760
+ window.addEventListener('mousemove', this.interact, false)
761
+ window.addEventListener('mouseup', this.stopInteract, false)
762
+ },
763
+ interact(e) {
764
+ e.preventDefault()
765
+ let value = parseFloat(this.value || 0)
766
+ value += parseFloat(this.interactionStep) * parseInt(e.movementX)
767
+ this.$emit('on-input-drag', value)
768
+
769
+ this.textInput = numberToString({
770
+ value: value && value.length ? value : this.minNumber,
771
+ numberPrecision: this.numberPrecision,
772
+ minDecimals: this.minDecimals,
773
+ })
774
+ //this.value=value
775
+ },
776
+ stopInteract(e) {
777
+ e.preventDefault()
778
+ window.removeEventListener('mousemove', this.interact, false)
779
+ window.removeEventListener('mouseup', this.stopInteract, false)
780
+ this.blurInput()
781
+ },
782
+ },
783
+ }
784
+ </script>