@popsure/dirty-swan 20.0.11 → 27.0.2

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 (288) hide show
  1. package/Readme.md +10 -1
  2. package/dist/assets/checkmark.svg +1 -1
  3. package/dist/assets/icon-form-dropdown.svg +1 -1
  4. package/dist/index.css +1169 -137
  5. package/dist/index.css.map +1 -1
  6. package/dist/index.d.ts +2 -2
  7. package/dist/index.js +8453 -13347
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/components/button/index.d.ts +1 -1
  10. package/dist/lib/components/cards/cardButton/index.d.ts +16 -0
  11. package/dist/lib/components/cards/cardWithLeftIcon/index.d.ts +2 -2
  12. package/dist/lib/components/cards/cardWithTopIcon/index.d.ts +2 -2
  13. package/dist/lib/components/cards/cardWithTopLeftIcon/index.d.ts +2 -2
  14. package/dist/lib/components/cards/icons/index.d.ts +2 -1
  15. package/dist/lib/components/cards/index.d.ts +3 -2
  16. package/dist/lib/components/comparisonTable/components/Chevron.d.ts +5 -0
  17. package/dist/lib/components/comparisonTable/components/Row/index.d.ts +12 -0
  18. package/dist/lib/components/comparisonTable/components/TableArrows/Arrow.d.ts +5 -0
  19. package/dist/lib/components/comparisonTable/components/TableArrows/index.d.ts +9 -0
  20. package/dist/lib/components/comparisonTable/components/TableInfoButton/index.d.ts +6 -0
  21. package/dist/lib/components/comparisonTable/components/TableRating/StarIcon.d.ts +5 -0
  22. package/dist/lib/components/comparisonTable/components/TableRating/ZapIcon.d.ts +5 -0
  23. package/dist/lib/components/comparisonTable/components/TableRating/index.d.ts +8 -0
  24. package/dist/lib/components/comparisonTable/components/TableRowHeader/index.d.ts +8 -0
  25. package/dist/lib/components/comparisonTable/components/TableTrueFalse.d.ts +6 -0
  26. package/dist/lib/components/comparisonTable/hooks/useActiveTableArrows.d.ts +10 -0
  27. package/dist/lib/components/comparisonTable/index.d.ts +45 -0
  28. package/dist/lib/components/downloadButton/index.d.ts +10 -0
  29. package/dist/lib/components/input/autoSuggestInput/index.d.ts +2 -1
  30. package/dist/lib/components/input/autoSuggestMultiSelect/index.d.ts +2 -1
  31. package/dist/lib/components/input/index.d.ts +3 -3
  32. package/dist/lib/components/modal/bottomModal/index.d.ts +1 -1
  33. package/dist/lib/components/modal/hooks/useOnClose.d.ts +7 -0
  34. package/dist/lib/components/modal/index.d.ts +2 -0
  35. package/dist/lib/components/modal/regularModal/index.d.ts +1 -1
  36. package/dist/lib/components/segmentedControl/index.d.ts +12 -0
  37. package/dist/lib/index.d.ts +7 -2
  38. package/dist/lib/models/download.d.ts +1 -0
  39. package/dist/lib/scss/private/_reset.scss +10 -1
  40. package/dist/lib/scss/private/base/_border_radius.scss +15 -0
  41. package/dist/lib/scss/private/base/_display.scss +4 -0
  42. package/dist/lib/scss/private/base/_grid.scss +44 -0
  43. package/dist/lib/scss/private/base/_index.scss +2 -0
  44. package/dist/lib/scss/private/base/_spacing.scss +64 -18
  45. package/dist/lib/scss/private/base/_typography.scss +7 -0
  46. package/dist/lib/scss/private/base/demo.tsx +4 -0
  47. package/dist/lib/scss/private/base/flex/_flex.scss +63 -0
  48. package/dist/lib/scss/private/base/flex/style.module.scss +24 -0
  49. package/dist/lib/scss/private/base/style.module.scss +10 -0
  50. package/dist/lib/scss/private/components/_buttons.scss +4 -4
  51. package/dist/lib/scss/private/components/_input.scss +6 -4
  52. package/dist/lib/scss/private/components/_notices.scss +13 -1
  53. package/dist/lib/scss/private/components/assets/checkmark.svg +1 -1
  54. package/dist/lib/scss/private/components/assets/icon-form-dropdown.svg +1 -1
  55. package/dist/lib/scss/public/colors/default.scss +38 -0
  56. package/dist/lib/scss/public/demo.tsx +109 -22
  57. package/package.json +6 -3
  58. package/src/App.tsx +50 -0
  59. package/src/bin/index.ts +71 -0
  60. package/src/bin/tsconfig.json +13 -0
  61. package/src/bin/util/index.test.ts +85 -0
  62. package/src/bin/util/index.ts +132 -0
  63. package/src/bin/util/test/data.json +13 -0
  64. package/src/colors.scss +1 -0
  65. package/src/font-weight.scss +1 -0
  66. package/src/grid.scss +1 -0
  67. package/src/index.tsx +37 -0
  68. package/src/intro.stories.mdx +41 -0
  69. package/src/lib/components/autocompleteAddress/demo.tsx +38 -0
  70. package/src/lib/components/autocompleteAddress/index.stories.mdx +44 -0
  71. package/src/lib/components/autocompleteAddress/index.tsx +327 -0
  72. package/src/lib/components/autocompleteAddress/mapStyle.ts +187 -0
  73. package/src/lib/components/autocompleteAddress/style.module.scss +82 -0
  74. package/src/lib/components/autocompleteAddress/util/index.test.ts +51 -0
  75. package/src/lib/components/autocompleteAddress/util/index.ts +59 -0
  76. package/src/lib/components/button/icons/index.ts +14 -0
  77. package/src/lib/components/button/icons/send-purple.svg +4 -0
  78. package/src/lib/components/button/icons/send-white.svg +4 -0
  79. package/src/lib/components/button/index.stories.mdx +121 -0
  80. package/src/lib/components/button/index.tsx +64 -0
  81. package/src/lib/components/button/styles.module.scss +5 -0
  82. package/src/lib/components/cards/a.stories.mdx +44 -0
  83. package/src/lib/components/cards/cardButton/index.stories.mdx +47 -0
  84. package/src/lib/components/cards/cardButton/index.tsx +61 -0
  85. package/src/lib/components/cards/cardButton/style.module.scss +33 -0
  86. package/src/lib/components/cards/cardWithLeftIcon/index.stories.mdx +103 -0
  87. package/src/lib/components/cards/cardWithLeftIcon/index.tsx +87 -0
  88. package/src/lib/components/cards/cardWithLeftIcon/style.module.scss +23 -0
  89. package/src/lib/components/cards/cardWithTopIcon/index.stories.mdx +105 -0
  90. package/src/lib/components/cards/cardWithTopIcon/index.tsx +60 -0
  91. package/src/lib/components/cards/cardWithTopIcon/style.module.scss +10 -0
  92. package/src/lib/components/cards/cardWithTopLeftIcon/index.stories.mdx +101 -0
  93. package/src/lib/components/cards/cardWithTopLeftIcon/index.tsx +72 -0
  94. package/src/lib/components/cards/cardWithTopLeftIcon/style.module.scss +21 -0
  95. package/src/lib/components/cards/icons/arrow-right.svg +4 -0
  96. package/src/lib/components/cards/icons/chevron-right.svg +3 -0
  97. package/src/lib/components/cards/icons/feather-logo.svg +10 -0
  98. package/src/lib/components/cards/icons/index.ts +36 -0
  99. package/src/lib/components/cards/icons/info.svg +12 -0
  100. package/src/lib/components/cards/index.test.ts +37 -0
  101. package/src/lib/components/cards/index.tsx +57 -0
  102. package/src/lib/components/cards/infoCard/index.stories.mdx +61 -0
  103. package/src/lib/components/cards/infoCard/index.tsx +47 -0
  104. package/src/lib/components/cards/infoCard/style.module.scss +53 -0
  105. package/src/lib/components/chip/icons/remove-button-highlighted.svg +4 -0
  106. package/src/lib/components/chip/icons/remove-button.svg +4 -0
  107. package/src/lib/components/chip/index.stories.mdx +101 -0
  108. package/src/lib/components/chip/index.tsx +38 -0
  109. package/src/lib/components/chip/style.module.scss +54 -0
  110. package/src/lib/components/comparisonTable/components/Chevron.tsx +19 -0
  111. package/src/lib/components/comparisonTable/components/Row/index.tsx +68 -0
  112. package/src/lib/components/comparisonTable/components/Row/style.module.scss +114 -0
  113. package/src/lib/components/comparisonTable/components/TableArrows/Arrow.tsx +19 -0
  114. package/src/lib/components/comparisonTable/components/TableArrows/index.tsx +52 -0
  115. package/src/lib/components/comparisonTable/components/TableArrows/style.module.scss +53 -0
  116. package/src/lib/components/comparisonTable/components/TableInfoButton/index.tsx +37 -0
  117. package/src/lib/components/comparisonTable/components/TableInfoButton/style.module.scss +30 -0
  118. package/src/lib/components/comparisonTable/components/TableRating/StarIcon.tsx +13 -0
  119. package/src/lib/components/comparisonTable/components/TableRating/ZapIcon.tsx +17 -0
  120. package/src/lib/components/comparisonTable/components/TableRating/index.tsx +45 -0
  121. package/src/lib/components/comparisonTable/components/TableRating/style.module.scss +13 -0
  122. package/src/lib/components/comparisonTable/components/TableRowHeader/index.tsx +35 -0
  123. package/src/lib/components/comparisonTable/components/TableRowHeader/style.module.scss +3 -0
  124. package/src/lib/components/comparisonTable/components/TableTrueFalse.tsx +40 -0
  125. package/src/lib/components/comparisonTable/hooks/useActiveTableArrows.ts +63 -0
  126. package/src/lib/components/comparisonTable/index.stories.mdx +254 -0
  127. package/src/lib/components/comparisonTable/index.tsx +211 -0
  128. package/src/lib/components/comparisonTable/style.module.scss +104 -0
  129. package/src/lib/components/dateSelector/datepicker.scss +406 -0
  130. package/src/lib/components/dateSelector/icons/calendar.svg +6 -0
  131. package/src/lib/components/dateSelector/icons/chevron-left.svg +3 -0
  132. package/src/lib/components/dateSelector/icons/chevron-right.svg +3 -0
  133. package/src/lib/components/dateSelector/index.stories.mdx +62 -0
  134. package/src/lib/components/dateSelector/index.test.ts +33 -0
  135. package/src/lib/components/dateSelector/index.tsx +247 -0
  136. package/src/lib/components/dateSelector/style.module.scss +77 -0
  137. package/src/lib/components/downloadButton/icons/check.svg +3 -0
  138. package/src/lib/components/downloadButton/icons/download.svg +5 -0
  139. package/src/lib/components/downloadButton/index.stories.mdx +59 -0
  140. package/src/lib/components/downloadButton/index.tsx +67 -0
  141. package/src/lib/components/downloadButton/style.module.scss +19 -0
  142. package/src/lib/components/downloadRing/icons/check-outside-circle.tsx +26 -0
  143. package/src/lib/components/downloadRing/icons/download-cloud.tsx +18 -0
  144. package/src/lib/components/downloadRing/icons/style.module.scss +7 -0
  145. package/src/lib/components/downloadRing/index.stories.mdx +35 -0
  146. package/src/lib/components/downloadRing/index.tsx +79 -0
  147. package/src/lib/components/downloadRing/style.module.scss +66 -0
  148. package/src/lib/components/dropzone/images/error.tsx +18 -0
  149. package/src/lib/components/dropzone/images/file.tsx +26 -0
  150. package/src/lib/components/dropzone/images/style.module.scss +7 -0
  151. package/src/lib/components/dropzone/images/upload-complete.tsx +24 -0
  152. package/src/lib/components/dropzone/images/upload.tsx +18 -0
  153. package/src/lib/components/dropzone/index.stories.mdx +44 -0
  154. package/src/lib/components/dropzone/index.tsx +152 -0
  155. package/src/lib/components/dropzone/style.module.scss +90 -0
  156. package/src/lib/components/input/a.stories.mdx +28 -0
  157. package/src/lib/components/input/autoSuggestInput/index.stories.mdx +137 -0
  158. package/src/lib/components/input/autoSuggestInput/index.tsx +81 -0
  159. package/src/lib/components/input/autoSuggestInput/style.module.scss +71 -0
  160. package/src/lib/components/input/autoSuggestMultiSelect/index.stories.mdx +115 -0
  161. package/src/lib/components/input/autoSuggestMultiSelect/index.tsx +75 -0
  162. package/src/lib/components/input/autoSuggestMultiSelect/style.module.scss +4 -0
  163. package/src/lib/components/input/currency/format/index.test.ts +49 -0
  164. package/src/lib/components/input/currency/format/index.ts +15 -0
  165. package/src/lib/components/input/currency/index.stories.mdx +25 -0
  166. package/src/lib/components/input/currency/index.test.tsx +56 -0
  167. package/src/lib/components/input/currency/index.tsx +53 -0
  168. package/src/lib/components/input/iban/formatIban/index.test.ts +11 -0
  169. package/src/lib/components/input/iban/formatIban/index.ts +22 -0
  170. package/src/lib/components/input/iban/index.stories.mdx +21 -0
  171. package/src/lib/components/input/iban/index.tsx +20 -0
  172. package/src/lib/components/input/index.stories.mdx +62 -0
  173. package/src/lib/components/input/index.tsx +51 -0
  174. package/src/lib/components/input/style.module.scss +94 -0
  175. package/src/lib/components/modal/bottomModal/img/close.svg +4 -0
  176. package/src/lib/components/modal/bottomModal/index.tsx +68 -0
  177. package/src/lib/components/modal/bottomModal/style.module.scss +104 -0
  178. package/src/lib/components/modal/bottomOrRegularModal/index.tsx +43 -0
  179. package/src/lib/components/modal/bottomOrRegularModal/style.module.scss +16 -0
  180. package/src/lib/components/modal/hooks/useOnClose.ts +54 -0
  181. package/src/lib/components/modal/index.stories.mdx +313 -0
  182. package/src/lib/components/modal/index.ts +14 -0
  183. package/src/lib/components/modal/regularModal/img/close.svg +4 -0
  184. package/src/lib/components/modal/regularModal/index.tsx +55 -0
  185. package/src/lib/components/modal/regularModal/style.module.scss +114 -0
  186. package/src/lib/components/multiDropzone/UploadFileCell/index.tsx +138 -0
  187. package/src/lib/components/multiDropzone/UploadFileCell/style.module.scss +101 -0
  188. package/src/lib/components/multiDropzone/icons/bmp-complete.svg +10 -0
  189. package/src/lib/components/multiDropzone/icons/bmp.svg +10 -0
  190. package/src/lib/components/multiDropzone/icons/doc-complete.svg +11 -0
  191. package/src/lib/components/multiDropzone/icons/doc.svg +11 -0
  192. package/src/lib/components/multiDropzone/icons/docx-complete.svg +12 -0
  193. package/src/lib/components/multiDropzone/icons/docx.svg +12 -0
  194. package/src/lib/components/multiDropzone/icons/eye.svg +4 -0
  195. package/src/lib/components/multiDropzone/icons/generic-complete.svg +4 -0
  196. package/src/lib/components/multiDropzone/icons/generic-error.svg +7 -0
  197. package/src/lib/components/multiDropzone/icons/generic.svg +4 -0
  198. package/src/lib/components/multiDropzone/icons/heic-complete.svg +11 -0
  199. package/src/lib/components/multiDropzone/icons/heic.svg +11 -0
  200. package/src/lib/components/multiDropzone/icons/index.ts +51 -0
  201. package/src/lib/components/multiDropzone/icons/jpeg-complete.svg +11 -0
  202. package/src/lib/components/multiDropzone/icons/jpeg.svg +11 -0
  203. package/src/lib/components/multiDropzone/icons/jpg-complete.svg +10 -0
  204. package/src/lib/components/multiDropzone/icons/jpg.svg +10 -0
  205. package/src/lib/components/multiDropzone/icons/pdf-complete.svg +8 -0
  206. package/src/lib/components/multiDropzone/icons/pdf.svg +8 -0
  207. package/src/lib/components/multiDropzone/icons/png-complete.svg +10 -0
  208. package/src/lib/components/multiDropzone/icons/png.svg +10 -0
  209. package/src/lib/components/multiDropzone/icons/trash.svg +6 -0
  210. package/src/lib/components/multiDropzone/icons/upload.svg +5 -0
  211. package/src/lib/components/multiDropzone/index.stories.mdx +91 -0
  212. package/src/lib/components/multiDropzone/index.tsx +99 -0
  213. package/src/lib/components/multiDropzone/style.module.scss +32 -0
  214. package/src/lib/components/segmentedControl/index.stories.mdx +47 -0
  215. package/src/lib/components/segmentedControl/index.tsx +105 -0
  216. package/src/lib/components/segmentedControl/style.module.scss +36 -0
  217. package/src/lib/components/signaturePad/img/reset.svg +4 -0
  218. package/src/lib/components/signaturePad/img/sign.svg +3 -0
  219. package/src/lib/components/signaturePad/index.stories.mdx +17 -0
  220. package/src/lib/components/signaturePad/index.tsx +96 -0
  221. package/src/lib/components/signaturePad/style.module.scss +90 -0
  222. package/src/lib/index.tsx +71 -0
  223. package/src/lib/models/autoSuggestInput/index.ts +4 -0
  224. package/src/lib/models/download.ts +1 -0
  225. package/src/lib/models/downloadRing/index.ts +6 -0
  226. package/src/lib/scss/index.scss +22 -0
  227. package/src/lib/scss/private/_reset.scss +154 -0
  228. package/src/lib/scss/private/base/_border_radius.scss +15 -0
  229. package/src/lib/scss/private/base/_colors.scss +19 -0
  230. package/src/lib/scss/private/base/_cursors.scss +31 -0
  231. package/src/lib/scss/private/base/_display.scss +35 -0
  232. package/src/lib/scss/private/base/_grid.scss +60 -0
  233. package/src/lib/scss/private/base/_index.scss +10 -0
  234. package/src/lib/scss/private/base/_shadows.scss +2 -0
  235. package/src/lib/scss/private/base/_spacing.scss +89 -0
  236. package/src/lib/scss/private/base/_typography.scss +135 -0
  237. package/src/lib/scss/private/base/_width_and_height.scss +25 -0
  238. package/src/lib/scss/private/base/border_radius.stories.mdx +43 -0
  239. package/src/lib/scss/private/base/cursors.stories.mdx +18 -0
  240. package/src/lib/scss/private/base/demo.tsx +123 -0
  241. package/src/lib/scss/private/base/display.stories.mdx +19 -0
  242. package/src/lib/scss/private/base/flex/_flex.scss +63 -0
  243. package/src/lib/scss/private/base/flex/flex.stories.mdx +139 -0
  244. package/src/lib/scss/private/base/flex/style.module.scss +24 -0
  245. package/src/lib/scss/private/base/spacing.stories.mdx +185 -0
  246. package/src/lib/scss/private/base/style.module.scss +52 -0
  247. package/src/lib/scss/private/base/typography.stories.mdx +74 -0
  248. package/src/lib/scss/private/base/width_and_height.stories.mdx +172 -0
  249. package/src/lib/scss/private/components/_badge.scss +41 -0
  250. package/src/lib/scss/private/components/_buttons.scss +193 -0
  251. package/src/lib/scss/private/components/_cards.scss +32 -0
  252. package/src/lib/scss/private/components/_index.scss +6 -0
  253. package/src/lib/scss/private/components/_input.scss +238 -0
  254. package/src/lib/scss/private/components/_notices.scss +39 -0
  255. package/src/lib/scss/private/components/_spinner.scss +60 -0
  256. package/src/lib/scss/private/components/assets/checkmark.svg +3 -0
  257. package/src/lib/scss/private/components/assets/icon-form-dropdown.svg +3 -0
  258. package/src/lib/scss/private/components/badge.stories.mdx +37 -0
  259. package/src/lib/scss/private/components/button.stories.mdx +107 -0
  260. package/src/lib/scss/private/components/cards.stories.mdx +35 -0
  261. package/src/lib/scss/private/components/checkbox.stories.mdx +47 -0
  262. package/src/lib/scss/private/components/input.stories.mdx +33 -0
  263. package/src/lib/scss/private/components/notices.stories.mdx +37 -0
  264. package/src/lib/scss/private/components/radio.stories.mdx +47 -0
  265. package/src/lib/scss/private/components/select.stories.mdx +17 -0
  266. package/src/lib/scss/private/components/spinner.stories.mdx +25 -0
  267. package/src/lib/scss/public/colors/_index.scss +2 -0
  268. package/src/lib/scss/public/colors/default.scss +130 -0
  269. package/src/lib/scss/public/colors/overrides.scss +0 -0
  270. package/src/lib/scss/public/colors.stories.mdx +27 -0
  271. package/src/lib/scss/public/demo.tsx +297 -0
  272. package/src/lib/scss/public/font/_index.scss +2 -0
  273. package/src/lib/scss/public/font/default.scss +3 -0
  274. package/src/lib/scss/public/font/overrides.scss +0 -0
  275. package/src/lib/scss/public/font-weight.scss +9 -0
  276. package/src/lib/scss/public/font-weight.stories.mdx +32 -0
  277. package/src/lib/scss/public/grid.scss +21 -0
  278. package/src/lib/scss/public/grid.stories.mdx +41 -0
  279. package/src/lib/scss/third-party/_google_places.scss +62 -0
  280. package/src/lib/scss/third-party/_index.scss +1 -0
  281. package/src/lib/scss/utils/_index.scss +3 -0
  282. package/src/lib/util/calendarDate/index.test.ts +32 -0
  283. package/src/lib/util/calendarDate/index.ts +30 -0
  284. package/src/lib/util/zeroFill.test.ts +15 -0
  285. package/src/lib/util/zeroFill.ts +7 -0
  286. package/src/react-app-env.d.ts +1 -0
  287. package/src/setupTests.js +8 -0
  288. package/src/theme.stories.mdx +54 -0
@@ -0,0 +1,327 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import classNames from 'classnames';
3
+ import debounce from 'lodash.debounce';
4
+ import isEqual from 'lodash.isequal';
5
+ import Input from '../input';
6
+ import {
7
+ Address,
8
+ countryNameFromAlphaCode,
9
+ Alpha2CountryCode,
10
+ } from '@popsure/public-models';
11
+
12
+ import { geocoderAddressComponentToPartialAddress } from './util';
13
+
14
+ import styles from './style.module.scss';
15
+
16
+ const GERMANY_LAT_LNG = { lat: 51.54317, lng: 10.3181503 };
17
+
18
+ const GERMANY_ALPHA_CODE = 'DE';
19
+
20
+ const MAP_CONFIG_OBJ = {
21
+ zoom: 6,
22
+ center: GERMANY_LAT_LNG,
23
+ fullscreenControl: false,
24
+ mapTypeControl: false,
25
+ panControl: false,
26
+ zoomControl: false,
27
+ streetViewControl: false,
28
+ scrollwheel: false,
29
+ scaleControl: false,
30
+ rotateControl: false,
31
+ draggable: false,
32
+ };
33
+
34
+ const loadGoogleMapsApiDynamically = (callback: () => void, apiKey: string) => {
35
+ const existingScript = document.getElementById('googleMapsImportScript');
36
+
37
+ if (existingScript) {
38
+ return;
39
+ }
40
+
41
+ const googleMapImportScript = document.createElement('script');
42
+ googleMapImportScript.id = 'googleMapsImportScript';
43
+ googleMapImportScript.type = 'text/javascript';
44
+ googleMapImportScript.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`;
45
+ document.head.appendChild(googleMapImportScript);
46
+
47
+ googleMapImportScript.onload = () => {
48
+ callback();
49
+ };
50
+ };
51
+
52
+ const AutoCompleteAddress = ({
53
+ apiKey,
54
+ address: initialAddress,
55
+ onAddressChange,
56
+ }: {
57
+ apiKey: string;
58
+ address?: Partial<Address>;
59
+ onAddressChange: (address: Partial<Address>) => void;
60
+ }) => {
61
+ const [manualAddressEntry, setManualAddressEntry] = useState(false);
62
+ const [isLoading, setIsLoading] = useState(false);
63
+ const autocomplete = useRef<google.maps.places.Autocomplete | null>(null);
64
+ const autocompleteElement = useRef<HTMLInputElement | null>(null);
65
+ const map = useRef<google.maps.Map | null>(null);
66
+ const marker = useRef<google.maps.Marker | null>(null);
67
+ const [address, setAddress] = useState(initialAddress);
68
+ const [hasLoadedGoogleAPI, setHasLoadedGoogleAPI] = useState(
69
+ window.google !== undefined
70
+ );
71
+
72
+ loadGoogleMapsApiDynamically(() => {
73
+ setHasLoadedGoogleAPI(true);
74
+ }, apiKey);
75
+
76
+ const [place, setPlace] = useState<google.maps.places.PlaceResult | null>(
77
+ null
78
+ );
79
+
80
+ useEffect(() => {
81
+ if (address) {
82
+ if (autocompleteElement.current && address.street) {
83
+ autocompleteElement.current.value = address.street;
84
+ }
85
+
86
+ if (isEqual(address, initialAddress) === false) {
87
+ onAddressChange({ ...address });
88
+ }
89
+ handleEnterAddressManually();
90
+ }
91
+ }, [initialAddress, address, onAddressChange, hasLoadedGoogleAPI]);
92
+
93
+ useEffect(() => {
94
+ if (hasLoadedGoogleAPI === false) {
95
+ return;
96
+ }
97
+
98
+ const reference = document.getElementById(
99
+ 'autocomplete'
100
+ ) as HTMLInputElement;
101
+
102
+ autocomplete.current = new google.maps.places.Autocomplete(reference, {
103
+ types: ['address'],
104
+ componentRestrictions: { country: GERMANY_ALPHA_CODE },
105
+ });
106
+
107
+ autocomplete.current.addListener('place_changed', onPlaceChanged);
108
+
109
+ map.current = new google.maps.Map(
110
+ document.getElementById('map')!,
111
+ MAP_CONFIG_OBJ
112
+ );
113
+
114
+ import('./mapStyle').then(({ style }) => {
115
+ map.current?.mapTypes.set('styled_map', style);
116
+ map.current?.setMapTypeId('styled_map');
117
+ });
118
+
119
+ marker.current = new google.maps.Marker({
120
+ map: map.current,
121
+ });
122
+
123
+ setPlaceFromAddress(address);
124
+ }, [hasLoadedGoogleAPI]); // eslint-disable-line
125
+
126
+ const onPlaceChanged = (
127
+ newPlace:
128
+ | google.maps.places.PlaceResult
129
+ | undefined = autocomplete.current?.getPlace(),
130
+ updateAddress: boolean = true
131
+ ) => {
132
+ if (newPlace?.geometry?.location) {
133
+ const geocoderAddress = geocoderAddressComponentToPartialAddress(
134
+ newPlace.address_components!
135
+ );
136
+
137
+ setPlace(newPlace);
138
+ if (updateAddress) {
139
+ setAddress((oldValue) => ({
140
+ ...geocoderAddress,
141
+ additionalInformation: oldValue?.additionalInformation,
142
+ }));
143
+ }
144
+
145
+ map.current?.panTo(newPlace.geometry.location);
146
+ map.current?.setZoom(15);
147
+
148
+ marker.current?.setPosition(newPlace.geometry.location);
149
+ }
150
+ };
151
+
152
+ const setPlaceFromAddress = useCallback(
153
+ (address: Partial<Address> | undefined) => {
154
+ if (!map.current) {
155
+ return;
156
+ }
157
+
158
+ if (address) {
159
+ const service = new google.maps.places.PlacesService(map.current);
160
+ const query = `${address.street ?? ''} ${address.houseNumber ?? ''}, ${
161
+ address.city ?? ''
162
+ }, ${
163
+ address.country
164
+ ? countryNameFromAlphaCode(address.country as Alpha2CountryCode)
165
+ : ''
166
+ }`;
167
+ setIsLoading(true);
168
+ service.findPlaceFromQuery(
169
+ {
170
+ fields: ['place_id'],
171
+ query,
172
+ },
173
+ (results) => {
174
+ const firstResult = results && results[0];
175
+ if (firstResult && firstResult.place_id) {
176
+ service.getDetails(
177
+ { placeId: firstResult.place_id },
178
+ (newPlace) => {
179
+ onPlaceChanged(newPlace ?? undefined, false);
180
+ }
181
+ );
182
+ }
183
+ setIsLoading(false);
184
+ }
185
+ );
186
+ }
187
+ },
188
+ []
189
+ );
190
+
191
+ const debouncedSetPlace = debounce(setPlaceFromAddress, 1000);
192
+
193
+ const handleEnterAddressManually = () => {
194
+ setManualAddressEntry(true);
195
+ };
196
+
197
+ return (
198
+ <>
199
+ <div
200
+ className={classNames(`wmx8 bg-grey-500 ${styles['map-container']}`, {
201
+ [styles['map-container--hidden']]: place === null,
202
+ })}
203
+ >
204
+ <div className={styles.map} id="map" />
205
+ {isLoading && (
206
+ <div className={styles['loading-spinner']}>
207
+ <div className="ds-spinner ds-spinner__m" />
208
+ </div>
209
+ )}
210
+ </div>
211
+ <div className={`wmx8`}>
212
+ {manualAddressEntry === false ? (
213
+ <div style={{ position: 'relative' }}>
214
+ <Input
215
+ className="w100"
216
+ id="autocomplete"
217
+ data-cy="autocomplete"
218
+ type="text"
219
+ placeholder="Search for address"
220
+ ref={autocompleteElement}
221
+ />
222
+ {hasLoadedGoogleAPI === false && (
223
+ <div className={styles['loading-spinner']}>
224
+ <div className="ds-spinner ds-spinner__m" />
225
+ </div>
226
+ )}
227
+ </div>
228
+ ) : (
229
+ <>
230
+ <div className={`d-flex ${styles['input-line']}`}>
231
+ <Input
232
+ className="w100"
233
+ data-cy="autocomplete"
234
+ type="text"
235
+ placeholder="Street"
236
+ value={address?.street || ''}
237
+ onChange={(e) => {
238
+ const newAddress = {
239
+ ...address,
240
+ street: e.target.value,
241
+ country: GERMANY_ALPHA_CODE,
242
+ };
243
+ setAddress(newAddress);
244
+ debouncedSetPlace(newAddress);
245
+ }}
246
+ />
247
+ <Input
248
+ className={`wmx2 ${styles['house-number-input']}`}
249
+ data-cy="autocomplete-house-number"
250
+ placeholder="House Number"
251
+ value={address?.houseNumber || ''}
252
+ onChange={(e) => {
253
+ const newAddress = {
254
+ ...address,
255
+ houseNumber: e.target.value,
256
+ country: GERMANY_ALPHA_CODE,
257
+ };
258
+ setAddress(newAddress);
259
+ debouncedSetPlace(newAddress);
260
+ }}
261
+ />
262
+ </div>
263
+ <Input
264
+ className="mt16"
265
+ data-cy="autocomplete-additional-info"
266
+ placeholder="Additional information (C/O, appartment…)"
267
+ value={address?.additionalInformation || ''}
268
+ onChange={(e) => {
269
+ const newAddress = {
270
+ ...address,
271
+ additionalInformation: e.target.value,
272
+ country: GERMANY_ALPHA_CODE,
273
+ };
274
+ setAddress(newAddress);
275
+ }}
276
+ />
277
+ <div className={`d-flex mt16 ${styles['input-line']}`}>
278
+ <Input
279
+ className="w100"
280
+ data-cy="autocomplete-postcode"
281
+ placeholder="Postcode"
282
+ value={address?.postcode || ''}
283
+ onChange={(e) => {
284
+ const newAddress = {
285
+ ...address,
286
+ postcode: e.target.value,
287
+ country: GERMANY_ALPHA_CODE,
288
+ };
289
+ setAddress(newAddress);
290
+ debouncedSetPlace(newAddress);
291
+ }}
292
+ />
293
+ <Input
294
+ className="w100"
295
+ data-cy="autocomplete-city"
296
+ placeholder="City"
297
+ value={address?.city || ''}
298
+ onChange={(e) => {
299
+ const newAddress = {
300
+ ...address,
301
+ city: e.target.value,
302
+ country: GERMANY_ALPHA_CODE,
303
+ };
304
+ setAddress(newAddress);
305
+ debouncedSetPlace(newAddress);
306
+ }}
307
+ />
308
+ </div>
309
+ </>
310
+ )}
311
+ </div>
312
+ {manualAddressEntry === false && (
313
+ <div className="p-p mt8">
314
+ Or{' '}
315
+ <span
316
+ className="p-a fw-bold c-pointer"
317
+ onClick={handleEnterAddressManually}
318
+ >
319
+ Enter address manually
320
+ </span>
321
+ </div>
322
+ )}
323
+ </>
324
+ );
325
+ };
326
+
327
+ export default AutoCompleteAddress;
@@ -0,0 +1,187 @@
1
+ export const style = new google.maps.StyledMapType(
2
+ [
3
+ {
4
+ elementType: 'geometry',
5
+ stylers: [
6
+ {
7
+ color: '#f5f5f5',
8
+ },
9
+ ],
10
+ },
11
+ {
12
+ elementType: 'labels',
13
+ stylers: [
14
+ {
15
+ visibility: 'off',
16
+ },
17
+ ],
18
+ },
19
+ {
20
+ elementType: 'labels.icon',
21
+ stylers: [
22
+ {
23
+ visibility: 'off',
24
+ },
25
+ ],
26
+ },
27
+ {
28
+ elementType: 'labels.text.fill',
29
+ stylers: [
30
+ {
31
+ color: '#616161',
32
+ },
33
+ ],
34
+ },
35
+ {
36
+ elementType: 'labels.text.stroke',
37
+ stylers: [
38
+ {
39
+ color: '#f5f5f5',
40
+ },
41
+ ],
42
+ },
43
+ {
44
+ featureType: 'administrative.land_parcel',
45
+ stylers: [
46
+ {
47
+ visibility: 'off',
48
+ },
49
+ ],
50
+ },
51
+ {
52
+ featureType: 'administrative.land_parcel',
53
+ elementType: 'labels.text.fill',
54
+ stylers: [
55
+ {
56
+ color: '#bdbdbd',
57
+ },
58
+ ],
59
+ },
60
+ {
61
+ featureType: 'administrative.neighborhood',
62
+ stylers: [
63
+ {
64
+ visibility: 'off',
65
+ },
66
+ ],
67
+ },
68
+ {
69
+ featureType: 'poi',
70
+ elementType: 'geometry',
71
+ stylers: [
72
+ {
73
+ color: '#eeeeee',
74
+ },
75
+ ],
76
+ },
77
+ {
78
+ featureType: 'poi',
79
+ elementType: 'labels.text.fill',
80
+ stylers: [
81
+ {
82
+ color: '#757575',
83
+ },
84
+ ],
85
+ },
86
+ {
87
+ featureType: 'poi.park',
88
+ elementType: 'geometry',
89
+ stylers: [
90
+ {
91
+ color: '#e5e5e5',
92
+ },
93
+ ],
94
+ },
95
+ {
96
+ featureType: 'poi.park',
97
+ elementType: 'labels.text.fill',
98
+ stylers: [
99
+ {
100
+ color: '#9e9e9e',
101
+ },
102
+ ],
103
+ },
104
+ {
105
+ featureType: 'road',
106
+ elementType: 'geometry',
107
+ stylers: [
108
+ {
109
+ color: '#ffffff',
110
+ },
111
+ ],
112
+ },
113
+ {
114
+ featureType: 'road.arterial',
115
+ elementType: 'labels.text.fill',
116
+ stylers: [
117
+ {
118
+ color: '#757575',
119
+ },
120
+ ],
121
+ },
122
+ {
123
+ featureType: 'road.highway',
124
+ elementType: 'geometry',
125
+ stylers: [
126
+ {
127
+ color: '#dadada',
128
+ },
129
+ ],
130
+ },
131
+ {
132
+ featureType: 'road.highway',
133
+ elementType: 'labels.text.fill',
134
+ stylers: [
135
+ {
136
+ color: '#616161',
137
+ },
138
+ ],
139
+ },
140
+ {
141
+ featureType: 'road.local',
142
+ elementType: 'labels.text.fill',
143
+ stylers: [
144
+ {
145
+ color: '#9e9e9e',
146
+ },
147
+ ],
148
+ },
149
+ {
150
+ featureType: 'transit.line',
151
+ elementType: 'geometry',
152
+ stylers: [
153
+ {
154
+ color: '#e5e5e5',
155
+ },
156
+ ],
157
+ },
158
+ {
159
+ featureType: 'transit.station',
160
+ elementType: 'geometry',
161
+ stylers: [
162
+ {
163
+ color: '#eeeeee',
164
+ },
165
+ ],
166
+ },
167
+ {
168
+ featureType: 'water',
169
+ elementType: 'geometry',
170
+ stylers: [
171
+ {
172
+ color: '#c9c9c9',
173
+ },
174
+ ],
175
+ },
176
+ {
177
+ featureType: 'water',
178
+ elementType: 'labels.text.fill',
179
+ stylers: [
180
+ {
181
+ color: '#9e9e9e',
182
+ },
183
+ ],
184
+ },
185
+ ],
186
+ { name: 'Styled Map' }
187
+ );
@@ -0,0 +1,82 @@
1
+ @use "../../scss/public/grid" as *;
2
+ @use "../../scss/public/colors" as *;
3
+
4
+ .input-line {
5
+ margin-left: -16px;
6
+
7
+ > * {
8
+ margin-left: 16px;
9
+ }
10
+
11
+ @include p-size-mobile {
12
+ flex-direction: column;
13
+
14
+ > *:not(:first-child) {
15
+ margin-top: 16px;
16
+ }
17
+ }
18
+ }
19
+
20
+ .house-number-input {
21
+ @include p-size-mobile {
22
+ max-width: none;
23
+ }
24
+ }
25
+
26
+ .map-container {
27
+ position: relative;
28
+
29
+ height: 112px;
30
+ margin-bottom: 16px;
31
+
32
+ border-radius: 8px;
33
+
34
+ transition: 0.3s height ease-in-out, 0.3s margin-top ease-in-out;
35
+
36
+ overflow: hidden;
37
+
38
+ &--hidden {
39
+ height: 0;
40
+ margin: 0;
41
+ }
42
+ }
43
+
44
+ @keyframes appear-in {
45
+ from {
46
+ opacity: 0;
47
+ }
48
+ to {
49
+ opacity: 1;
50
+ }
51
+ }
52
+
53
+ .appear-in-animate {
54
+ animation-name: appear-in;
55
+ animation-duration: 0.3s;
56
+ animation-fill-mode: both;
57
+ }
58
+
59
+ .loading-spinner {
60
+ display: flex;
61
+
62
+ justify-content: center;
63
+ align-items: center;
64
+
65
+ position: absolute !important;
66
+ background-color: rgba($ds-primary-500, 0.25);
67
+
68
+ top: 0;
69
+ left: 0;
70
+ bottom: 0;
71
+ right: 0;
72
+ z-index: 100;
73
+
74
+ animation-name: appear-in;
75
+ animation-duration: 0.3s;
76
+ animation-fill-mode: both;
77
+ }
78
+
79
+ .map {
80
+ width: 100%;
81
+ height: 100%;
82
+ }
@@ -0,0 +1,51 @@
1
+ import { geocoderAddressComponentToPartialAddress } from '.';
2
+
3
+ describe('geocoderAddressComponentToPartialAddress text', () => {
4
+ it('Should extract street, houseNumber, postcode, city, country from GeocoderAddressComponent[]', () => {
5
+ const input = [
6
+ { long_name: '103A', short_name: '103A', types: ['street_number'] },
7
+ {
8
+ long_name: 'Kottbusser Damm',
9
+ short_name: 'Kottbusser Damm',
10
+ types: ['route'],
11
+ },
12
+ {
13
+ long_name: 'Bezirk Neukölln',
14
+ short_name: 'Bezirk Neukölln',
15
+ types: ['sublocality_level_1', 'sublocality', 'political'],
16
+ },
17
+ {
18
+ long_name: 'Berlin',
19
+ short_name: 'Berlin',
20
+ types: ['locality', 'political'],
21
+ },
22
+ {
23
+ long_name: 'Berlin',
24
+ short_name: 'Berlin',
25
+ types: ['administrative_area_level_1', 'political'],
26
+ },
27
+ {
28
+ long_name: 'Germany',
29
+ short_name: 'DE',
30
+ types: ['country', 'political'],
31
+ },
32
+ {
33
+ long_name: '10967',
34
+ short_name: '10967',
35
+ types: ['postal_code'],
36
+ },
37
+ ];
38
+
39
+ const expectedOutput = {
40
+ street: 'Kottbusser Damm',
41
+ houseNumber: '103A',
42
+ postcode: '10967',
43
+ city: 'Berlin',
44
+ country: 'DE',
45
+ };
46
+
47
+ expect(geocoderAddressComponentToPartialAddress(input)).toEqual(
48
+ expectedOutput
49
+ );
50
+ });
51
+ });
@@ -0,0 +1,59 @@
1
+ import {
2
+ Address,
3
+ countryNameFromAlphaCode,
4
+ Alpha2CountryCode,
5
+ } from '@popsure/public-models';
6
+
7
+ export const geocoderAddressComponentToPartialAddress = (
8
+ input: google.maps.GeocoderAddressComponent[]
9
+ ): Partial<Address> => {
10
+ interface MappedType {
11
+ key: keyof Address;
12
+ value: 'long_name' | 'short_name';
13
+ }
14
+
15
+ const mapping: {
16
+ route: MappedType;
17
+ street_number: MappedType;
18
+ postal_code: MappedType;
19
+ locality: MappedType;
20
+ country: MappedType;
21
+ } = {
22
+ route: {
23
+ key: 'street',
24
+ value: 'long_name',
25
+ },
26
+ street_number: {
27
+ key: 'houseNumber',
28
+ value: 'long_name',
29
+ },
30
+ postal_code: {
31
+ key: 'postcode',
32
+ value: 'long_name',
33
+ },
34
+ locality: {
35
+ key: 'city',
36
+ value: 'long_name',
37
+ },
38
+ country: {
39
+ key: 'country',
40
+ value: 'short_name',
41
+ },
42
+ };
43
+
44
+ const toReturn: Partial<Address> = {};
45
+ input.forEach((value) => {
46
+ const type = value.types[0] as keyof typeof mapping;
47
+ const mappedValue = mapping[type];
48
+ if (mappedValue) {
49
+ toReturn[mappedValue.key] = value[mappedValue.value];
50
+ }
51
+ });
52
+
53
+ return toReturn;
54
+ };
55
+
56
+ export const inlineAddress = (address: Address) =>
57
+ `${address.street} ${address.houseNumber}, ${
58
+ address.city
59
+ }, ${countryNameFromAlphaCode(address.country as Alpha2CountryCode)}`;
@@ -0,0 +1,14 @@
1
+ import purpleSendImage from './send-purple.svg';
2
+ import whiteSendImage from './send-white.svg';
3
+
4
+ const purpleSend = {
5
+ src: purpleSendImage,
6
+ alt: 'Paper plane',
7
+ };
8
+
9
+ const whiteSend = {
10
+ src: whiteSendImage,
11
+ alt: 'Paper plane',
12
+ };
13
+
14
+ export { purpleSend, whiteSend };