@automattic/onboarding 1.0.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 (383) hide show
  1. package/README.md +20 -0
  2. package/dist/cjs/action-buttons/index.js +50 -0
  3. package/dist/cjs/action-buttons/index.js.map +1 -0
  4. package/dist/cjs/action-buttons/style.scss +108 -0
  5. package/dist/cjs/cart/create-cart-manager-client.js +30 -0
  6. package/dist/cjs/cart/create-cart-manager-client.js.map +1 -0
  7. package/dist/cjs/cart/index.js +239 -0
  8. package/dist/cjs/cart/index.js.map +1 -0
  9. package/dist/cjs/confetti/index.js +8 -0
  10. package/dist/cjs/confetti/index.js.map +1 -0
  11. package/dist/cjs/feature-icon/index.js +19 -0
  12. package/dist/cjs/feature-icon/index.js.map +1 -0
  13. package/dist/cjs/flow-progress/index.js +14 -0
  14. package/dist/cjs/flow-progress/index.js.map +1 -0
  15. package/dist/cjs/flow-progress/style.scss +5 -0
  16. package/dist/cjs/flow-progress/use-flow-progress.js +92 -0
  17. package/dist/cjs/flow-progress/use-flow-progress.js.map +1 -0
  18. package/dist/cjs/hooray/index.js +12 -0
  19. package/dist/cjs/hooray/index.js.map +1 -0
  20. package/dist/cjs/hooray/style.scss +66 -0
  21. package/dist/cjs/index.js +54 -0
  22. package/dist/cjs/index.js.map +1 -0
  23. package/dist/cjs/intent-screen/index.js +11 -0
  24. package/dist/cjs/intent-screen/index.js.map +1 -0
  25. package/dist/cjs/mshots-image/index.js +234 -0
  26. package/dist/cjs/mshots-image/index.js.map +1 -0
  27. package/dist/cjs/mshots-image/style.scss +43 -0
  28. package/dist/cjs/navigator/hooks/index.js +6 -0
  29. package/dist/cjs/navigator/hooks/index.js.map +1 -0
  30. package/dist/cjs/navigator/hooks/use-navigator-listener.js +16 -0
  31. package/dist/cjs/navigator/hooks/use-navigator-listener.js.map +1 -0
  32. package/dist/cjs/navigator/index.js +18 -0
  33. package/dist/cjs/navigator/index.js.map +1 -0
  34. package/dist/cjs/navigator/navigator-buttons/index.js +23 -0
  35. package/dist/cjs/navigator/navigator-buttons/index.js.map +1 -0
  36. package/dist/cjs/navigator/navigator-buttons/style.scss +47 -0
  37. package/dist/cjs/navigator/navigator-header/index.js +13 -0
  38. package/dist/cjs/navigator/navigator-header/index.js.map +1 -0
  39. package/dist/cjs/navigator/navigator-header/style.scss +45 -0
  40. package/dist/cjs/navigator/navigator-item-group/index.js +10 -0
  41. package/dist/cjs/navigator/navigator-item-group/index.js.map +1 -0
  42. package/dist/cjs/navigator/navigator-item-group/style.scss +28 -0
  43. package/dist/cjs/navigator/navigator-listener/index.js +9 -0
  44. package/dist/cjs/navigator/navigator-listener/index.js.map +1 -0
  45. package/dist/cjs/navigator/navigator-screen/index.js +16 -0
  46. package/dist/cjs/navigator/navigator-screen/index.js.map +1 -0
  47. package/dist/cjs/navigator/navigator-screens/hooks/index.js +8 -0
  48. package/dist/cjs/navigator/navigator-screens/hooks/index.js.map +1 -0
  49. package/dist/cjs/navigator/navigator-screens/hooks/use-navigator-buttons.js +17 -0
  50. package/dist/cjs/navigator/navigator-screens/hooks/use-navigator-buttons.js.map +1 -0
  51. package/dist/cjs/navigator/navigator-screens/hooks/use-navigator-screens.js +14 -0
  52. package/dist/cjs/navigator/navigator-screens/hooks/use-navigator-screens.js.map +1 -0
  53. package/dist/cjs/navigator/navigator-screens/index.js +9 -0
  54. package/dist/cjs/navigator/navigator-screens/index.js.map +1 -0
  55. package/dist/cjs/navigator/navigator-screens/navigator-screens.js +18 -0
  56. package/dist/cjs/navigator/navigator-screens/navigator-screens.js.map +1 -0
  57. package/dist/cjs/navigator/navigator-screens/navigator-screens.scss +60 -0
  58. package/dist/cjs/navigator/navigator-screens/types.js +3 -0
  59. package/dist/cjs/navigator/navigator-screens/types.js.map +1 -0
  60. package/dist/cjs/notice/index.js +12 -0
  61. package/dist/cjs/notice/index.js.map +1 -0
  62. package/dist/cjs/notice/style.scss +19 -0
  63. package/dist/cjs/progress/index.js +11 -0
  64. package/dist/cjs/progress/index.js.map +1 -0
  65. package/dist/cjs/progress/style.scss +34 -0
  66. package/dist/cjs/select-card-checkbox/index.js +17 -0
  67. package/dist/cjs/select-card-checkbox/index.js.map +1 -0
  68. package/dist/cjs/select-card-checkbox/style.scss +30 -0
  69. package/dist/cjs/select-card-radio/index.js +21 -0
  70. package/dist/cjs/select-card-radio/index.js.map +1 -0
  71. package/dist/cjs/select-card-radio/style.scss +44 -0
  72. package/dist/cjs/select-items/index.js +13 -0
  73. package/dist/cjs/select-items/index.js.map +1 -0
  74. package/dist/cjs/select-items/style.scss +96 -0
  75. package/dist/cjs/select-items-alt/index.js +14 -0
  76. package/dist/cjs/select-items-alt/index.js.map +1 -0
  77. package/dist/cjs/select-items-alt/style.scss +72 -0
  78. package/dist/cjs/sensei-logo/index.js +8 -0
  79. package/dist/cjs/sensei-logo/index.js.map +1 -0
  80. package/dist/cjs/setup-tailored-site-after-creation.js +109 -0
  81. package/dist/cjs/setup-tailored-site-after-creation.js.map +1 -0
  82. package/dist/cjs/step-container/index.js +65 -0
  83. package/dist/cjs/step-container/index.js.map +1 -0
  84. package/dist/cjs/step-container/style.scss +304 -0
  85. package/dist/cjs/step-navigation-link/index.js +35 -0
  86. package/dist/cjs/step-navigation-link/index.js.map +1 -0
  87. package/dist/cjs/step-navigation-link/style.scss +42 -0
  88. package/dist/cjs/titles/index.js +13 -0
  89. package/dist/cjs/titles/index.js.map +1 -0
  90. package/dist/cjs/titles/styles.scss +29 -0
  91. package/dist/cjs/upload-and-set-site-logo.js +32 -0
  92. package/dist/cjs/upload-and-set-site-logo.js.map +1 -0
  93. package/dist/cjs/utils/contrastChecker.js +38 -0
  94. package/dist/cjs/utils/contrastChecker.js.map +1 -0
  95. package/dist/cjs/utils/domain-suggester.js +113 -0
  96. package/dist/cjs/utils/domain-suggester.js.map +1 -0
  97. package/dist/cjs/utils/flows.js +218 -0
  98. package/dist/cjs/utils/flows.js.map +1 -0
  99. package/dist/cjs/utils/index.js +13 -0
  100. package/dist/cjs/utils/index.js.map +1 -0
  101. package/dist/cjs/utils/is-domain.js +22 -0
  102. package/dist/cjs/utils/is-domain.js.map +1 -0
  103. package/dist/cjs/utils/use-data-loss-warning.js +20 -0
  104. package/dist/cjs/utils/use-data-loss-warning.js.map +1 -0
  105. package/dist/cjs/videopress-logo/index.js +8 -0
  106. package/dist/cjs/videopress-logo/index.js.map +1 -0
  107. package/dist/esm/action-buttons/index.js +42 -0
  108. package/dist/esm/action-buttons/index.js.map +1 -0
  109. package/dist/esm/action-buttons/style.scss +108 -0
  110. package/dist/esm/cart/create-cart-manager-client.js +27 -0
  111. package/dist/esm/cart/create-cart-manager-client.js.map +1 -0
  112. package/dist/esm/cart/index.js +229 -0
  113. package/dist/esm/cart/index.js.map +1 -0
  114. package/dist/esm/confetti/index.js +6 -0
  115. package/dist/esm/confetti/index.js.map +1 -0
  116. package/dist/esm/feature-icon/index.js +16 -0
  117. package/dist/esm/feature-icon/index.js.map +1 -0
  118. package/dist/esm/flow-progress/index.js +12 -0
  119. package/dist/esm/flow-progress/index.js.map +1 -0
  120. package/dist/esm/flow-progress/style.scss +5 -0
  121. package/dist/esm/flow-progress/use-flow-progress.js +88 -0
  122. package/dist/esm/flow-progress/use-flow-progress.js.map +1 -0
  123. package/dist/esm/hooray/index.js +9 -0
  124. package/dist/esm/hooray/index.js.map +1 -0
  125. package/dist/esm/hooray/style.scss +66 -0
  126. package/dist/esm/index.js +22 -0
  127. package/dist/esm/index.js.map +1 -0
  128. package/dist/esm/intent-screen/index.js +8 -0
  129. package/dist/esm/intent-screen/index.js.map +1 -0
  130. package/dist/esm/mshots-image/index.js +229 -0
  131. package/dist/esm/mshots-image/index.js.map +1 -0
  132. package/dist/esm/mshots-image/style.scss +43 -0
  133. package/dist/esm/navigator/hooks/index.js +2 -0
  134. package/dist/esm/navigator/hooks/index.js.map +1 -0
  135. package/dist/esm/navigator/hooks/use-navigator-listener.js +14 -0
  136. package/dist/esm/navigator/hooks/use-navigator-listener.js.map +1 -0
  137. package/dist/esm/navigator/index.js +8 -0
  138. package/dist/esm/navigator/index.js.map +1 -0
  139. package/dist/esm/navigator/navigator-buttons/index.js +17 -0
  140. package/dist/esm/navigator/navigator-buttons/index.js.map +1 -0
  141. package/dist/esm/navigator/navigator-buttons/style.scss +47 -0
  142. package/dist/esm/navigator/navigator-header/index.js +11 -0
  143. package/dist/esm/navigator/navigator-header/index.js.map +1 -0
  144. package/dist/esm/navigator/navigator-header/style.scss +45 -0
  145. package/dist/esm/navigator/navigator-item-group/index.js +8 -0
  146. package/dist/esm/navigator/navigator-item-group/index.js.map +1 -0
  147. package/dist/esm/navigator/navigator-item-group/style.scss +28 -0
  148. package/dist/esm/navigator/navigator-listener/index.js +7 -0
  149. package/dist/esm/navigator/navigator-listener/index.js.map +1 -0
  150. package/dist/esm/navigator/navigator-screen/index.js +14 -0
  151. package/dist/esm/navigator/navigator-screen/index.js.map +1 -0
  152. package/dist/esm/navigator/navigator-screens/hooks/index.js +3 -0
  153. package/dist/esm/navigator/navigator-screens/hooks/index.js.map +1 -0
  154. package/dist/esm/navigator/navigator-screens/hooks/use-navigator-buttons.js +14 -0
  155. package/dist/esm/navigator/navigator-screens/hooks/use-navigator-buttons.js.map +1 -0
  156. package/dist/esm/navigator/navigator-screens/hooks/use-navigator-screens.js +11 -0
  157. package/dist/esm/navigator/navigator-screens/hooks/use-navigator-screens.js.map +1 -0
  158. package/dist/esm/navigator/navigator-screens/index.js +4 -0
  159. package/dist/esm/navigator/navigator-screens/index.js.map +1 -0
  160. package/dist/esm/navigator/navigator-screens/navigator-screens.js +15 -0
  161. package/dist/esm/navigator/navigator-screens/navigator-screens.js.map +1 -0
  162. package/dist/esm/navigator/navigator-screens/navigator-screens.scss +60 -0
  163. package/dist/esm/navigator/navigator-screens/types.js +2 -0
  164. package/dist/esm/navigator/navigator-screens/types.js.map +1 -0
  165. package/dist/esm/notice/index.js +9 -0
  166. package/dist/esm/notice/index.js.map +1 -0
  167. package/dist/esm/notice/style.scss +19 -0
  168. package/dist/esm/progress/index.js +8 -0
  169. package/dist/esm/progress/index.js.map +1 -0
  170. package/dist/esm/progress/style.scss +34 -0
  171. package/dist/esm/select-card-checkbox/index.js +14 -0
  172. package/dist/esm/select-card-checkbox/index.js.map +1 -0
  173. package/dist/esm/select-card-checkbox/style.scss +30 -0
  174. package/dist/esm/select-card-radio/index.js +15 -0
  175. package/dist/esm/select-card-radio/index.js.map +1 -0
  176. package/dist/esm/select-card-radio/style.scss +44 -0
  177. package/dist/esm/select-items/index.js +10 -0
  178. package/dist/esm/select-items/index.js.map +1 -0
  179. package/dist/esm/select-items/style.scss +96 -0
  180. package/dist/esm/select-items-alt/index.js +11 -0
  181. package/dist/esm/select-items-alt/index.js.map +1 -0
  182. package/dist/esm/select-items-alt/style.scss +72 -0
  183. package/dist/esm/sensei-logo/index.js +6 -0
  184. package/dist/esm/sensei-logo/index.js.map +1 -0
  185. package/dist/esm/setup-tailored-site-after-creation.js +103 -0
  186. package/dist/esm/setup-tailored-site-after-creation.js.map +1 -0
  187. package/dist/esm/step-container/index.js +62 -0
  188. package/dist/esm/step-container/index.js.map +1 -0
  189. package/dist/esm/step-container/style.scss +304 -0
  190. package/dist/esm/step-navigation-link/index.js +32 -0
  191. package/dist/esm/step-navigation-link/index.js.map +1 -0
  192. package/dist/esm/step-navigation-link/style.scss +42 -0
  193. package/dist/esm/titles/index.js +7 -0
  194. package/dist/esm/titles/index.js.map +1 -0
  195. package/dist/esm/titles/styles.scss +29 -0
  196. package/dist/esm/upload-and-set-site-logo.js +27 -0
  197. package/dist/esm/upload-and-set-site-logo.js.map +1 -0
  198. package/dist/esm/utils/contrastChecker.js +33 -0
  199. package/dist/esm/utils/contrastChecker.js.map +1 -0
  200. package/dist/esm/utils/domain-suggester.js +108 -0
  201. package/dist/esm/utils/domain-suggester.js.map +1 -0
  202. package/dist/esm/utils/flows.js +179 -0
  203. package/dist/esm/utils/flows.js.map +1 -0
  204. package/dist/esm/utils/index.js +6 -0
  205. package/dist/esm/utils/index.js.map +1 -0
  206. package/dist/esm/utils/is-domain.js +18 -0
  207. package/dist/esm/utils/is-domain.js.map +1 -0
  208. package/dist/esm/utils/use-data-loss-warning.js +16 -0
  209. package/dist/esm/utils/use-data-loss-warning.js.map +1 -0
  210. package/dist/esm/videopress-logo/index.js +6 -0
  211. package/dist/esm/videopress-logo/index.js.map +1 -0
  212. package/dist/styles/base-styles.scss +7 -0
  213. package/dist/styles/mixins.scss +262 -0
  214. package/dist/styles/variables.scss +26 -0
  215. package/dist/styles/z-index.scss +41 -0
  216. package/dist/tsconfig-cjs.tsbuildinfo +1 -0
  217. package/dist/tsconfig.tsbuildinfo +1 -0
  218. package/dist/types/action-buttons/index.d.ts +17 -0
  219. package/dist/types/action-buttons/index.d.ts.map +1 -0
  220. package/dist/types/cart/create-cart-manager-client.d.ts +3 -0
  221. package/dist/types/cart/create-cart-manager-client.d.ts.map +1 -0
  222. package/dist/types/cart/index.d.ts +47 -0
  223. package/dist/types/cart/index.d.ts.map +1 -0
  224. package/dist/types/confetti/index.d.ts +6 -0
  225. package/dist/types/confetti/index.d.ts.map +1 -0
  226. package/dist/types/feature-icon/index.d.ts +9 -0
  227. package/dist/types/feature-icon/index.d.ts.map +1 -0
  228. package/dist/types/flow-progress/index.d.ts +9 -0
  229. package/dist/types/flow-progress/index.d.ts.map +1 -0
  230. package/dist/types/flow-progress/use-flow-progress.d.ts +11 -0
  231. package/dist/types/flow-progress/use-flow-progress.d.ts.map +1 -0
  232. package/dist/types/hooray/index.d.ts +10 -0
  233. package/dist/types/hooray/index.d.ts.map +1 -0
  234. package/dist/types/index.d.ts +25 -0
  235. package/dist/types/index.d.ts.map +1 -0
  236. package/dist/types/intent-screen/index.d.ts +12 -0
  237. package/dist/types/intent-screen/index.d.ts.map +1 -0
  238. package/dist/types/mshots-image/index.d.ts +21 -0
  239. package/dist/types/mshots-image/index.d.ts.map +1 -0
  240. package/dist/types/navigator/hooks/index.d.ts +3 -0
  241. package/dist/types/navigator/hooks/index.d.ts.map +1 -0
  242. package/dist/types/navigator/hooks/use-navigator-listener.d.ts +4 -0
  243. package/dist/types/navigator/hooks/use-navigator-listener.d.ts.map +1 -0
  244. package/dist/types/navigator/index.d.ts +8 -0
  245. package/dist/types/navigator/index.d.ts.map +1 -0
  246. package/dist/types/navigator/navigator-buttons/index.d.ts +17 -0
  247. package/dist/types/navigator/navigator-buttons/index.d.ts.map +1 -0
  248. package/dist/types/navigator/navigator-header/index.d.ts +12 -0
  249. package/dist/types/navigator/navigator-header/index.d.ts.map +1 -0
  250. package/dist/types/navigator/navigator-item-group/index.d.ts +9 -0
  251. package/dist/types/navigator/navigator-item-group/index.d.ts.map +1 -0
  252. package/dist/types/navigator/navigator-listener/index.d.ts +7 -0
  253. package/dist/types/navigator/navigator-listener/index.d.ts.map +1 -0
  254. package/dist/types/navigator/navigator-screen/index.d.ts +11 -0
  255. package/dist/types/navigator/navigator-screen/index.d.ts.map +1 -0
  256. package/dist/types/navigator/navigator-screens/hooks/index.d.ts +3 -0
  257. package/dist/types/navigator/navigator-screens/hooks/index.d.ts.map +1 -0
  258. package/dist/types/navigator/navigator-screens/hooks/use-navigator-buttons.d.ts +4 -0
  259. package/dist/types/navigator/navigator-screens/hooks/use-navigator-buttons.d.ts.map +1 -0
  260. package/dist/types/navigator/navigator-screens/hooks/use-navigator-screens.d.ts +4 -0
  261. package/dist/types/navigator/navigator-screens/hooks/use-navigator-screens.d.ts.map +1 -0
  262. package/dist/types/navigator/navigator-screens/index.d.ts +4 -0
  263. package/dist/types/navigator/navigator-screens/index.d.ts.map +1 -0
  264. package/dist/types/navigator/navigator-screens/navigator-screens.d.ts +12 -0
  265. package/dist/types/navigator/navigator-screens/navigator-screens.d.ts.map +1 -0
  266. package/dist/types/navigator/navigator-screens/types.d.ts +17 -0
  267. package/dist/types/navigator/navigator-screens/types.d.ts.map +1 -0
  268. package/dist/types/notice/index.d.ts +7 -0
  269. package/dist/types/notice/index.d.ts.map +1 -0
  270. package/dist/types/progress/index.d.ts +10 -0
  271. package/dist/types/progress/index.d.ts.map +1 -0
  272. package/dist/types/select-card-checkbox/index.d.ts +11 -0
  273. package/dist/types/select-card-checkbox/index.d.ts.map +1 -0
  274. package/dist/types/select-card-radio/index.d.ts +22 -0
  275. package/dist/types/select-card-radio/index.d.ts.map +1 -0
  276. package/dist/types/select-items/index.d.ts +25 -0
  277. package/dist/types/select-items/index.d.ts.map +1 -0
  278. package/dist/types/select-items-alt/index.d.ts +19 -0
  279. package/dist/types/select-items-alt/index.d.ts.map +1 -0
  280. package/dist/types/sensei-logo/index.d.ts +8 -0
  281. package/dist/types/sensei-logo/index.d.ts.map +1 -0
  282. package/dist/types/setup-tailored-site-after-creation.d.ts +8 -0
  283. package/dist/types/setup-tailored-site-after-creation.d.ts.map +1 -0
  284. package/dist/types/step-container/index.d.ts +45 -0
  285. package/dist/types/step-container/index.d.ts.map +1 -0
  286. package/dist/types/step-navigation-link/index.d.ts +18 -0
  287. package/dist/types/step-navigation-link/index.d.ts.map +1 -0
  288. package/dist/types/titles/index.d.ts +12 -0
  289. package/dist/types/titles/index.d.ts.map +1 -0
  290. package/dist/types/upload-and-set-site-logo.d.ts +13 -0
  291. package/dist/types/upload-and-set-site-logo.d.ts.map +1 -0
  292. package/dist/types/utils/contrastChecker.d.ts +17 -0
  293. package/dist/types/utils/contrastChecker.d.ts.map +1 -0
  294. package/dist/types/utils/domain-suggester.d.ts +15 -0
  295. package/dist/types/utils/domain-suggester.d.ts.map +1 -0
  296. package/dist/types/utils/flows.d.ts +89 -0
  297. package/dist/types/utils/flows.d.ts.map +1 -0
  298. package/dist/types/utils/index.d.ts +6 -0
  299. package/dist/types/utils/index.d.ts.map +1 -0
  300. package/dist/types/utils/is-domain.d.ts +2 -0
  301. package/dist/types/utils/is-domain.d.ts.map +1 -0
  302. package/dist/types/utils/use-data-loss-warning.d.ts +2 -0
  303. package/dist/types/utils/use-data-loss-warning.d.ts.map +1 -0
  304. package/dist/types/videopress-logo/index.d.ts +8 -0
  305. package/dist/types/videopress-logo/index.d.ts.map +1 -0
  306. package/jest.config.js +5 -0
  307. package/package.json +63 -0
  308. package/src/action-buttons/index.tsx +113 -0
  309. package/src/action-buttons/style.scss +108 -0
  310. package/src/cart/create-cart-manager-client.ts +34 -0
  311. package/src/cart/index.tsx +375 -0
  312. package/src/cart/test/index.ts +172 -0
  313. package/src/confetti/index.tsx +95 -0
  314. package/src/feature-icon/index.tsx +102 -0
  315. package/src/flow-progress/index.tsx +22 -0
  316. package/src/flow-progress/style.scss +5 -0
  317. package/src/flow-progress/use-flow-progress.ts +108 -0
  318. package/src/hooray/index.tsx +34 -0
  319. package/src/hooray/style.scss +66 -0
  320. package/src/index.ts +36 -0
  321. package/src/intent-screen/README.md +12 -0
  322. package/src/intent-screen/index.tsx +26 -0
  323. package/src/intent-screen/test/index.tsx +197 -0
  324. package/src/mshots-image/index.tsx +368 -0
  325. package/src/mshots-image/style.scss +43 -0
  326. package/src/mshots-image/test/mshots-image.tsx +5 -0
  327. package/src/navigator/hooks/index.tsx +2 -0
  328. package/src/navigator/hooks/use-navigator-listener.tsx +18 -0
  329. package/src/navigator/index.ts +7 -0
  330. package/src/navigator/navigator-buttons/index.tsx +58 -0
  331. package/src/navigator/navigator-buttons/style.scss +47 -0
  332. package/src/navigator/navigator-header/index.tsx +40 -0
  333. package/src/navigator/navigator-header/style.scss +45 -0
  334. package/src/navigator/navigator-item-group/index.tsx +23 -0
  335. package/src/navigator/navigator-item-group/style.scss +28 -0
  336. package/src/navigator/navigator-listener/index.tsx +12 -0
  337. package/src/navigator/navigator-screen/index.tsx +24 -0
  338. package/src/navigator/navigator-screens/hooks/index.tsx +2 -0
  339. package/src/navigator/navigator-screens/hooks/use-navigator-buttons.tsx +32 -0
  340. package/src/navigator/navigator-screens/hooks/use-navigator-screens.tsx +57 -0
  341. package/src/navigator/navigator-screens/index.ts +3 -0
  342. package/src/navigator/navigator-screens/navigator-screens.scss +60 -0
  343. package/src/navigator/navigator-screens/navigator-screens.tsx +41 -0
  344. package/src/navigator/navigator-screens/types.ts +15 -0
  345. package/src/notice/index.tsx +16 -0
  346. package/src/notice/style.scss +19 -0
  347. package/src/progress/index.tsx +23 -0
  348. package/src/progress/style.scss +34 -0
  349. package/src/select-card-checkbox/index.tsx +38 -0
  350. package/src/select-card-checkbox/style.scss +30 -0
  351. package/src/select-card-radio/index.tsx +64 -0
  352. package/src/select-card-radio/style.scss +44 -0
  353. package/src/select-card-radio/test/index.tsx +50 -0
  354. package/src/select-items/README.md +13 -0
  355. package/src/select-items/index.tsx +90 -0
  356. package/src/select-items/style.scss +96 -0
  357. package/src/select-items-alt/README.md +13 -0
  358. package/src/select-items-alt/index.tsx +61 -0
  359. package/src/select-items-alt/style.scss +72 -0
  360. package/src/sensei-logo/index.tsx +30 -0
  361. package/src/setup-tailored-site-after-creation.ts +149 -0
  362. package/src/step-container/index.tsx +251 -0
  363. package/src/step-container/style.scss +304 -0
  364. package/src/step-navigation-link/index.tsx +71 -0
  365. package/src/step-navigation-link/style.scss +42 -0
  366. package/src/titles/index.tsx +36 -0
  367. package/src/titles/styles.scss +29 -0
  368. package/src/types.d.ts +1 -0
  369. package/src/upload-and-set-site-logo.ts +38 -0
  370. package/src/utils/contrastChecker.ts +52 -0
  371. package/src/utils/domain-suggester.ts +126 -0
  372. package/src/utils/flows.ts +232 -0
  373. package/src/utils/index.ts +5 -0
  374. package/src/utils/is-domain.ts +18 -0
  375. package/src/utils/test/domain-suggester.ts +87 -0
  376. package/src/utils/use-data-loss-warning.ts +17 -0
  377. package/src/videopress-logo/index.tsx +36 -0
  378. package/styles/base-styles.scss +7 -0
  379. package/styles/mixins.scss +262 -0
  380. package/styles/variables.scss +26 -0
  381. package/styles/z-index.scss +41 -0
  382. package/tsconfig-cjs.json +7 -0
  383. package/tsconfig.json +15 -0
@@ -0,0 +1,375 @@
1
+ import config from '@automattic/calypso-config';
2
+ import { getUrlParts } from '@automattic/calypso-url';
3
+ import { DomainSuggestion, NewSiteSuccessResponse, Site } from '@automattic/data-stores';
4
+ import { guessTimezone, getLanguage } from '@automattic/i18n-utils';
5
+ import debugFactory from 'debug';
6
+ import { getLocaleSlug } from 'i18n-calypso';
7
+ import { startsWith, isEmpty } from 'lodash';
8
+ import wpcomRequest from 'wpcom-proxy-request';
9
+ import {
10
+ setupSiteAfterCreation,
11
+ isTailoredSignupFlow,
12
+ isMigrationFlow,
13
+ HUNDRED_YEAR_PLAN_FLOW,
14
+ isAnyHostingFlow,
15
+ } from '../';
16
+ import cartManagerClient from './create-cart-manager-client';
17
+ import type { MinimalRequestCartProduct } from '@automattic/shopping-cart';
18
+
19
+ const debug = debugFactory( 'calypso:signup:step-actions' );
20
+
21
+ interface GetNewSiteParams {
22
+ flowToCheck: string;
23
+ isPurchasingDomainItem: boolean;
24
+ themeSlugWithRepo: string;
25
+ siteUrl?: string;
26
+ siteTitle: string;
27
+ siteAccentColor: string;
28
+ useThemeHeadstart: boolean;
29
+ siteVisibility: Site.Visibility;
30
+ username: string;
31
+ sourceSlug?: string;
32
+ }
33
+
34
+ type NewSiteParams = {
35
+ blog_title: string;
36
+ public: Site.Visibility;
37
+ blog_name: string;
38
+ find_available_url: boolean;
39
+ options: {
40
+ designType: string;
41
+ theme?: string;
42
+ use_theme_annotation: boolean;
43
+ default_annotation_as_primary_fallback: boolean;
44
+ site_segment: undefined;
45
+ site_information: {
46
+ title: string;
47
+ };
48
+ site_creation_flow: string;
49
+ timezone_string?: string;
50
+ wpcom_public_coming_soon: 0 | 1;
51
+ site_accent_color?: string;
52
+ };
53
+ validate: boolean;
54
+ };
55
+
56
+ const getBlogNameGenerationParams = ( {
57
+ siteUrl,
58
+ siteTitle,
59
+ flowToCheck,
60
+ username,
61
+ isPurchasingDomainItem,
62
+ }: GetNewSiteParams ) => {
63
+ if ( siteUrl ) {
64
+ const blog_name = siteUrl.replace( '.wordpress.com', '' );
65
+
66
+ if ( isMigrationFlow( flowToCheck ) ) {
67
+ return {
68
+ blog_name,
69
+ find_available_url: true,
70
+ };
71
+ }
72
+
73
+ return {
74
+ blog_name,
75
+ find_available_url: !! isPurchasingDomainItem,
76
+ };
77
+ }
78
+
79
+ if ( siteTitle ) {
80
+ return {
81
+ blog_name: siteTitle,
82
+ find_available_url: true,
83
+ };
84
+ }
85
+
86
+ if ( isAnyHostingFlow( flowToCheck ) ) {
87
+ return {
88
+ blog_name: '',
89
+ find_available_url: true,
90
+ };
91
+ }
92
+
93
+ return {
94
+ blog_name: username,
95
+ find_available_url: true,
96
+ };
97
+ };
98
+
99
+ export const getNewSiteParams = ( params: GetNewSiteParams ) => {
100
+ const {
101
+ flowToCheck,
102
+ themeSlugWithRepo,
103
+ siteTitle,
104
+ siteAccentColor,
105
+ useThemeHeadstart = false,
106
+ siteVisibility,
107
+ sourceSlug,
108
+ } = params;
109
+
110
+ // We will use the default annotation instead of theme annotation as fallback,
111
+ // when segment and vertical values are not sent. Check pbAok1-p2#comment-834.
112
+ const newSiteParams: NewSiteParams = {
113
+ ...getBlogNameGenerationParams( params ),
114
+ blog_title: siteTitle,
115
+ public: siteVisibility,
116
+ options: {
117
+ designType: '',
118
+ use_theme_annotation: useThemeHeadstart,
119
+ default_annotation_as_primary_fallback: true,
120
+ site_segment: undefined,
121
+ site_information: {
122
+ title: siteTitle,
123
+ },
124
+ site_creation_flow: flowToCheck,
125
+ timezone_string: guessTimezone(),
126
+ wpcom_public_coming_soon: siteVisibility === 0 ? 1 : 0,
127
+ ...( sourceSlug && { site_source_slug: sourceSlug } ),
128
+ ...( siteAccentColor && { site_accent_color: siteAccentColor } ),
129
+ ...( themeSlugWithRepo && { theme: themeSlugWithRepo } ),
130
+ },
131
+ validate: false,
132
+ };
133
+
134
+ return newSiteParams;
135
+ };
136
+
137
+ export const createSiteWithCart = async (
138
+ flowName: string,
139
+ userIsLoggedIn: boolean,
140
+ isPurchasingDomainItem: boolean,
141
+ themeSlugWithRepo: string,
142
+ siteVisibility: Site.Visibility,
143
+ siteTitle: string,
144
+ siteAccentColor: string,
145
+ useThemeHeadstart: boolean,
146
+ username: string,
147
+ domainItem?: DomainSuggestion,
148
+ domainCartItem?: MinimalRequestCartProduct,
149
+ sourceSlug?: string
150
+ ) => {
151
+ const siteUrl = domainItem?.domain_name;
152
+ const isFreeThemePreselected = startsWith( themeSlugWithRepo, 'pub' );
153
+
154
+ const newSiteParams = getNewSiteParams( {
155
+ flowToCheck: flowName,
156
+ isPurchasingDomainItem,
157
+ themeSlugWithRepo,
158
+ siteUrl,
159
+ siteTitle,
160
+ siteAccentColor,
161
+ useThemeHeadstart,
162
+ siteVisibility,
163
+ username,
164
+ sourceSlug,
165
+ } );
166
+
167
+ // if ( isEmpty( bearerToken ) && 'onboarding-registrationless' === flowToCheck ) {
168
+ // saveToLocalStorageAndProceed( state, domainItem, themeItem, newSiteParams, callback );
169
+ // return;
170
+ // }
171
+
172
+ const locale = getLocaleSlug();
173
+ const hasSegmentationSurvey: boolean =
174
+ newSiteParams[ 'options' ][ 'site_creation_flow' ] === 'entrepreneur';
175
+ const segmentationSurveyAnswersAnonId = localStorage.getItem( 'ss-anon-id' );
176
+ localStorage.removeItem( 'ss-anon-id' );
177
+
178
+ const siteCreationResponse: NewSiteSuccessResponse = await wpcomRequest( {
179
+ path: '/sites/new',
180
+ apiVersion: '1.1',
181
+ method: 'POST',
182
+ body: {
183
+ ...newSiteParams,
184
+ locale,
185
+ lang_id: getLanguage( locale as string )?.value,
186
+ client_id: config( 'wpcom_signup_id' ),
187
+ client_secret: config( 'wpcom_signup_key' ),
188
+ options: {
189
+ ...newSiteParams.options,
190
+ has_segmentation_survey: hasSegmentationSurvey,
191
+ ...( hasSegmentationSurvey && segmentationSurveyAnswersAnonId
192
+ ? { segmentation_survey_answers_anon_id: segmentationSurveyAnswersAnonId }
193
+ : {} ),
194
+ },
195
+ },
196
+ } );
197
+
198
+ if ( ! siteCreationResponse.success ) {
199
+ // TODO ebuccelli: Manage siteCreationResponse.errors
200
+ return;
201
+ }
202
+
203
+ const parsedBlogURL = getUrlParts( siteCreationResponse?.blog_details.url );
204
+ const siteSlug = parsedBlogURL.hostname;
205
+ const siteId = siteCreationResponse?.blog_details.blogid;
206
+ const providedDependencies = {
207
+ siteId,
208
+ siteSlug,
209
+ domainItem,
210
+ };
211
+
212
+ if ( isTailoredSignupFlow( flowName ) || HUNDRED_YEAR_PLAN_FLOW === flowName ) {
213
+ await setupSiteAfterCreation( { siteId, flowName } );
214
+ }
215
+
216
+ await processItemCart(
217
+ siteSlug,
218
+ isFreeThemePreselected,
219
+ themeSlugWithRepo,
220
+ flowName,
221
+ userIsLoggedIn,
222
+ domainCartItem
223
+ );
224
+
225
+ return providedDependencies;
226
+ };
227
+
228
+ function prepareItemForAddingToCart( item: MinimalRequestCartProduct, lastKnownFlow?: string ) {
229
+ return {
230
+ ...item,
231
+ extra: {
232
+ ...item.extra,
233
+ context: 'signup',
234
+ ...( lastKnownFlow && { signup_flow: lastKnownFlow } ),
235
+ },
236
+ };
237
+ }
238
+
239
+ export async function addPlanToCart(
240
+ siteSlug: string,
241
+ flowName: string,
242
+ userIsLoggedIn: boolean,
243
+ themeSlugWithRepo: string,
244
+ cartItem: MinimalRequestCartProduct
245
+ ) {
246
+ if ( isEmpty( cartItem ) ) {
247
+ // the user selected the free plan
248
+ return;
249
+ }
250
+
251
+ const isFreeThemePreselected = startsWith( themeSlugWithRepo, 'pub' );
252
+
253
+ await processItemCart(
254
+ siteSlug,
255
+ isFreeThemePreselected,
256
+ themeSlugWithRepo,
257
+ flowName,
258
+ userIsLoggedIn,
259
+ cartItem
260
+ );
261
+ }
262
+
263
+ export async function replaceProductsInCart(
264
+ siteSlug: string,
265
+ cartItems: MinimalRequestCartProduct[]
266
+ ) {
267
+ const cartKey = await cartManagerClient.getCartKeyForSiteSlug( siteSlug );
268
+
269
+ try {
270
+ const updatedCart = await cartManagerClient
271
+ .forCartKey( cartKey )
272
+ .actions.replaceProductsInCart( cartItems );
273
+
274
+ debug( 'product replace request complete', updatedCart );
275
+ } catch ( error ) {
276
+ debug( 'product replace request had an error', error );
277
+ }
278
+ }
279
+
280
+ const addToCartAndProceed = async (
281
+ newCartItem: MinimalRequestCartProduct,
282
+ siteSlug: string,
283
+ flowName: string
284
+ ) => {
285
+ const cartItem = prepareItemForAddingToCart( newCartItem, flowName );
286
+
287
+ if ( cartItem ) {
288
+ debug( 'adding products to cart', cartItem );
289
+ const cartKey = await cartManagerClient.getCartKeyForSiteSlug( siteSlug );
290
+
291
+ try {
292
+ const updatedCart = await cartManagerClient
293
+ .forCartKey( cartKey )
294
+ .actions.addProductsToCart( [ cartItem ] );
295
+
296
+ debug( 'product add request complete', updatedCart );
297
+ } catch ( error ) {
298
+ debug( 'product add request had an error', error );
299
+ //TODO Manage error
300
+ // reduxStore.dispatch( errorNotice( error.message ) );
301
+ }
302
+ } else {
303
+ debug( 'no cart items to add' );
304
+ }
305
+ };
306
+
307
+ export async function addProductsToCart(
308
+ siteSlug: string,
309
+ flowName: string,
310
+ cartItems: MinimalRequestCartProduct[] | null
311
+ ) {
312
+ if ( Array.isArray( cartItems ) ) {
313
+ const cartItemsToAdd = cartItems.map( ( cartItem ) =>
314
+ prepareItemForAddingToCart( cartItem, flowName )
315
+ );
316
+
317
+ debug( 'adding products to cart', cartItems );
318
+ const cartKey = await cartManagerClient.getCartKeyForSiteSlug( siteSlug );
319
+
320
+ try {
321
+ const updatedCart = await cartManagerClient
322
+ .forCartKey( cartKey )
323
+ .actions.addProductsToCart( cartItemsToAdd );
324
+
325
+ debug( 'product add request complete', updatedCart );
326
+ } catch ( error ) {
327
+ debug( 'product add request had an error', error );
328
+ }
329
+ }
330
+ }
331
+
332
+ export async function setThemeOnSite(
333
+ siteSlug: string,
334
+ themeSlugWithRepo: string,
335
+ themeStyleVariation?: string
336
+ ) {
337
+ if ( isEmpty( themeSlugWithRepo ) ) {
338
+ return;
339
+ }
340
+
341
+ const theme = themeSlugWithRepo.split( '/' )[ 1 ];
342
+
343
+ try {
344
+ await wpcomRequest( {
345
+ path: `/sites/${ siteSlug }/themes/mine`,
346
+ method: 'POST',
347
+ apiVersion: '1.1',
348
+ body: {
349
+ theme,
350
+ ...( themeStyleVariation && { style_variation_slug: themeStyleVariation } ),
351
+ },
352
+ } );
353
+ } catch ( error ) {
354
+ //TODO: Manage error
355
+ }
356
+ }
357
+
358
+ async function processItemCart(
359
+ siteSlug: string,
360
+ isFreeThemePreselected: boolean,
361
+ themeSlugWithRepo: string,
362
+ lastKnownFlow: string,
363
+ userIsLoggedIn: boolean,
364
+ newCartItem?: MinimalRequestCartProduct
365
+ ) {
366
+ if ( ! userIsLoggedIn && isFreeThemePreselected ) {
367
+ await setThemeOnSite( siteSlug, themeSlugWithRepo );
368
+ newCartItem && ( await addToCartAndProceed( newCartItem, siteSlug, lastKnownFlow ) );
369
+ } else if ( userIsLoggedIn && isFreeThemePreselected ) {
370
+ await setThemeOnSite( siteSlug, themeSlugWithRepo );
371
+ newCartItem && ( await addToCartAndProceed( newCartItem, siteSlug, lastKnownFlow ) );
372
+ } else {
373
+ newCartItem && ( await addToCartAndProceed( newCartItem, siteSlug, lastKnownFlow ) );
374
+ }
375
+ }
@@ -0,0 +1,172 @@
1
+ import { Visibility } from '@automattic/data-stores';
2
+ import { getNewSiteParams } from '..';
3
+ import { HOSTING_LP_FLOW, MIGRATION_FLOW } from '../../utils/flows';
4
+
5
+ describe( 'getNewSiteParams', () => {
6
+ function testParams( partialParams: Partial< Parameters< typeof getNewSiteParams >[ 0 ] > = {} ) {
7
+ return {
8
+ flowToCheck: 'test-flow',
9
+ isPurchasingDomainItem: false,
10
+ themeSlugWithRepo: 'pub/test-theme',
11
+ siteTitle: 'test site title',
12
+ siteAccentColor: '#deface',
13
+ useThemeHeadstart: false,
14
+ siteVisibility: Visibility.Private,
15
+ username: 'testuser',
16
+ ...partialParams,
17
+ } satisfies Parameters< typeof getNewSiteParams >[ 0 ];
18
+ }
19
+
20
+ test( 'siteVisibility set to publicly indexed', () => {
21
+ expect(
22
+ getNewSiteParams(
23
+ testParams( {
24
+ siteVisibility: Visibility.PublicIndexed,
25
+ } )
26
+ )
27
+ ).toEqual(
28
+ expect.objectContaining( {
29
+ public: Visibility.PublicIndexed,
30
+ options: expect.objectContaining( {
31
+ wpcom_public_coming_soon: 0,
32
+ } ),
33
+ } )
34
+ );
35
+ } );
36
+
37
+ test( 'siteVisibility set to public but not indexed', () => {
38
+ expect(
39
+ getNewSiteParams(
40
+ testParams( {
41
+ siteVisibility: Visibility.PublicNotIndexed,
42
+ } )
43
+ )
44
+ ).toEqual(
45
+ expect.objectContaining( {
46
+ public: Visibility.PublicNotIndexed,
47
+ options: expect.objectContaining( {
48
+ wpcom_public_coming_soon: 1,
49
+ } ),
50
+ } )
51
+ );
52
+ } );
53
+
54
+ test( 'siteVisibility set to private', () => {
55
+ expect(
56
+ getNewSiteParams(
57
+ testParams( {
58
+ siteVisibility: Visibility.Private,
59
+ } )
60
+ )
61
+ ).toEqual(
62
+ expect.objectContaining( {
63
+ public: Visibility.Private,
64
+ options: expect.objectContaining( {
65
+ wpcom_public_coming_soon: 0, // Private sites are not "private" from all traffic
66
+ } ),
67
+ } )
68
+ );
69
+ } );
70
+
71
+ test( 'blog_name hint uses the site title when no site URL is present', () => {
72
+ expect(
73
+ getNewSiteParams(
74
+ testParams( {
75
+ siteUrl: undefined,
76
+ siteTitle: 'Testing Inc.',
77
+ } )
78
+ )
79
+ ).toEqual(
80
+ expect.objectContaining( {
81
+ blog_name: 'Testing Inc.',
82
+ find_available_url: true,
83
+ } )
84
+ );
85
+ } );
86
+
87
+ test( 'blog_name hint falls back to the username when no site URL or title is present', () => {
88
+ expect(
89
+ getNewSiteParams(
90
+ testParams( {
91
+ flowToCheck: HOSTING_LP_FLOW,
92
+ siteUrl: undefined,
93
+ siteTitle: '',
94
+ username: 'janedoe',
95
+ } )
96
+ )
97
+ ).toEqual(
98
+ expect.objectContaining( {
99
+ blog_name: '',
100
+ find_available_url: true,
101
+ } )
102
+ );
103
+ } );
104
+
105
+ test( 'Hosting flow does not fall back to username when site title and URL are missing', () => {
106
+ expect(
107
+ getNewSiteParams(
108
+ testParams( {
109
+ siteUrl: undefined,
110
+ siteTitle: '',
111
+ username: 'janedoe',
112
+ } )
113
+ )
114
+ ).toEqual(
115
+ expect.objectContaining( {
116
+ blog_name: 'janedoe',
117
+ find_available_url: true,
118
+ } )
119
+ );
120
+ } );
121
+
122
+ test( 'blog_name hint uses the site URL when present', () => {
123
+ expect(
124
+ getNewSiteParams(
125
+ testParams( {
126
+ siteUrl: 'testing123.wordpress.com',
127
+ siteTitle: 'Testing Inc.',
128
+ username: 'janedoe',
129
+ isPurchasingDomainItem: true,
130
+ } )
131
+ )
132
+ ).toEqual(
133
+ expect.objectContaining( {
134
+ blog_name: 'testing123',
135
+ find_available_url: true,
136
+ } )
137
+ );
138
+
139
+ expect(
140
+ getNewSiteParams(
141
+ testParams( {
142
+ siteUrl: 'testing123.wordpress.com',
143
+ siteTitle: 'Testing Inc.',
144
+ username: 'janedoe',
145
+ isPurchasingDomainItem: false,
146
+ } )
147
+ )
148
+ ).toEqual(
149
+ expect.objectContaining( {
150
+ blog_name: 'testing123',
151
+ find_available_url: false,
152
+ } )
153
+ );
154
+ } );
155
+
156
+ test( 'Migration flow uses find_available_url', () => {
157
+ expect(
158
+ getNewSiteParams(
159
+ testParams( {
160
+ flowToCheck: MIGRATION_FLOW,
161
+ siteUrl: 'testing123.wordpress.com',
162
+ isPurchasingDomainItem: false,
163
+ } )
164
+ )
165
+ ).toEqual(
166
+ expect.objectContaining( {
167
+ blog_name: 'testing123',
168
+ find_available_url: true, // True despite the fact isPurchasingDomainItem is false
169
+ } )
170
+ );
171
+ } );
172
+ } );
@@ -0,0 +1,95 @@
1
+ /* eslint-disable wpcalypso/jsx-classname-namespace */
2
+
3
+ import { SVG, Rect, Circle } from '@wordpress/components';
4
+ import * as React from 'react';
5
+
6
+ const Index: React.FunctionComponent< { className?: string } > = ( { className } ) => (
7
+ <SVG
8
+ fill="none"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ viewBox="0 0 356 136"
11
+ role="presentation"
12
+ className={ className }
13
+ >
14
+ <Rect
15
+ x="314.913"
16
+ y="59.963"
17
+ width="7"
18
+ height="22"
19
+ rx="3.5"
20
+ transform="rotate(-50 314.913 59.963)"
21
+ fill="#984A9C"
22
+ />
23
+ <Rect
24
+ y="121.876"
25
+ width="5.091"
26
+ height="16"
27
+ rx="2.545"
28
+ transform="rotate(-50 0 121.876)"
29
+ fill="#64CA43"
30
+ />
31
+ <Rect
32
+ x="21.447"
33
+ y="85.104"
34
+ width="7"
35
+ height="22"
36
+ rx="3.5"
37
+ transform="rotate(-120 21.447 85.104)"
38
+ fill="#37E788"
39
+ />
40
+ <Rect
41
+ x="75"
42
+ y="61.64"
43
+ width="4"
44
+ height="12.571"
45
+ rx="2"
46
+ transform="rotate(130 75 61.64)"
47
+ fill="#FF2D55"
48
+ />
49
+ <Rect
50
+ x="247.461"
51
+ y="63.86"
52
+ width="4.773"
53
+ height="15"
54
+ rx="2.386"
55
+ transform="rotate(118 247.461 63.86)"
56
+ fill="#E7C037"
57
+ />
58
+ <Rect
59
+ x="97"
60
+ y="2.529"
61
+ width="4.773"
62
+ height="15"
63
+ rx="2.386"
64
+ transform="rotate(-32 97 2.53)"
65
+ fill="#117AC9"
66
+ />
67
+ <Rect
68
+ x="323.638"
69
+ y="110.513"
70
+ width="5.091"
71
+ height="16"
72
+ rx="2.545"
73
+ transform="rotate(40 323.638 110.513)"
74
+ fill="#3361CC"
75
+ />
76
+ <Rect
77
+ x="160.138"
78
+ y="27"
79
+ width="7"
80
+ height="22"
81
+ rx="3.5"
82
+ transform="rotate(40 160.138 27)"
83
+ fill="#FF8085"
84
+ />
85
+ <Circle cx="40.5" cy="101.095" r="4.5" fill="#F0B849" />
86
+ <Circle cx="20.928" cy="47.751" r="3" fill="#BF5AF2" />
87
+ <Circle cx="341" cy="134" r="2" fill="#F0C930" />
88
+ <Circle cx="131" cy="83" r="2" fill="#3361CC" />
89
+ <Circle cx="214.5" cy="13.5" r="2.5" fill="#37E688" />
90
+ <Circle cx="352.763" cy="98.263" r="3" fill="#009E73" />
91
+ <Circle cx="285.181" cy="60.541" r="3" fill="#FF3B30" />
92
+ </SVG>
93
+ );
94
+
95
+ export default Index;