@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,368 @@
1
+ import { addQueryArgs } from '@wordpress/url';
2
+ import clsx from 'clsx';
3
+ import debugFactory from 'debug';
4
+ import { useState, useEffect, useRef } from 'react';
5
+
6
+ import './style.scss';
7
+
8
+ interface MShotsImageProps {
9
+ url: string;
10
+ alt: string;
11
+ 'aria-labelledby': string;
12
+ options: MShotsOptions;
13
+ scrollable?: boolean;
14
+ }
15
+
16
+ export type MShotsOptions = {
17
+ vpw: number;
18
+ vph: number;
19
+ w: number;
20
+ h?: number;
21
+ screen_height?: number;
22
+ format?: 'png' | 'jpeg';
23
+ oldHighResImageLoading?: boolean;
24
+ };
25
+
26
+ const debug = debugFactory( 'design-picker:mshots-image' );
27
+
28
+ export function mshotsUrl( targetUrl: string, options: MShotsOptions, count = 0 ): string {
29
+ const mshotsUrl = 'https://s0.wp.com/mshots/v1/';
30
+ const mshotsRequest = addQueryArgs( mshotsUrl + encodeURIComponent( targetUrl ), {
31
+ ...options,
32
+ count,
33
+ } );
34
+ return mshotsRequest;
35
+ }
36
+
37
+ const MAXTRIES = 10;
38
+
39
+ // This custom react hook returns null while the image is loading and the page
40
+ // (not image) URL once loading is complete.
41
+ //
42
+ // It also triggers a re-render (via setState()) when the value changes, so just
43
+ // check that the requested URL matches the returned URL.
44
+ //
45
+ // Note the loading may occur immediately if the image is already available, or
46
+ // may take several seconds if mshots has to generate and cache new images.
47
+ //
48
+ // The calling code doesn't need to worry about the details except that you'll
49
+ // want some sort of loading display.
50
+ //
51
+ // Inspired by https://stackoverflow.com/a/60458593
52
+ const useMshotsImg = (
53
+ src: string,
54
+ options: MShotsOptions,
55
+ imgRef: React.MutableRefObject< HTMLImageElement | null >
56
+ ): string | null => {
57
+ const [ loadedImg, setLoadedImg ] = useState< string | null >( null );
58
+ const [ count, setCount ] = useState( 0 );
59
+ const previousSrc = useRef( src );
60
+
61
+ const timeoutIdRef = useRef< number >();
62
+
63
+ const previousImg = useRef< HTMLImageElement | null >( null );
64
+ const previousOptions = useRef< MShotsOptions >();
65
+ // Oddly, we need to assign to current here after ref creation in order to
66
+ // pass the equivalence check and avoid a spurious reset
67
+ previousOptions.current = options;
68
+
69
+ // Note: Mshots doesn't care about the "count" param, but it is important
70
+ // to browser caching. Getting this wrong looks like the url resolving
71
+ // before the image is ready.
72
+ useEffect( () => {
73
+ // If there's been a "props" change we need to reset everything:
74
+ if (
75
+ options !== previousOptions.current ||
76
+ ( src !== previousSrc.current && imgRef.current )
77
+ ) {
78
+ // Make sure an old image can't trigger a spurious state update
79
+ debug( 'resetting mShotsUrl request' );
80
+ if ( src !== previousSrc.current ) {
81
+ debug( 'src changed\nfrom', previousSrc.current, '\nto', src );
82
+ }
83
+ if ( options !== previousOptions.current ) {
84
+ debug( 'options changed\nfrom', previousOptions.current, '\nto', options );
85
+ }
86
+ if ( previousImg.current && previousImg.current.onload ) {
87
+ previousImg.current.onload = null;
88
+ if ( timeoutIdRef.current ) {
89
+ clearTimeout( timeoutIdRef.current );
90
+ timeoutIdRef.current = undefined;
91
+ }
92
+ }
93
+
94
+ setCount( 0 );
95
+ if ( previousImg.current !== imgRef.current ) {
96
+ previousImg.current = imgRef.current;
97
+ }
98
+
99
+ previousOptions.current = options;
100
+ previousSrc.current = src;
101
+ }
102
+
103
+ const srcUrl = mshotsUrl( src, options, count );
104
+
105
+ if ( imgRef.current ) {
106
+ imgRef.current.onload = () => {
107
+ // Detect default image (Don't request a 400x300 image).
108
+ //
109
+ // If this turns out to be a problem, it might help to know that the
110
+ // http request status for the default is a 307. Unfortunately we
111
+ // don't get the request through an img element so we'd need to
112
+ // take a completely different approach using ajax.
113
+ if ( imgRef.current?.naturalWidth !== 400 || imgRef.current?.naturalHeight !== 300 ) {
114
+ setLoadedImg( src );
115
+ } else if ( count < MAXTRIES ) {
116
+ // Only refresh 10 times
117
+ // Triggers a target.src change with increasing timeouts
118
+ timeoutIdRef.current = window.setTimeout(
119
+ () => setCount( ( count ) => count + 1 ),
120
+ count * 500
121
+ );
122
+ }
123
+ };
124
+ imgRef.current.src = srcUrl;
125
+ }
126
+
127
+ return () => {
128
+ if ( imgRef.current && imgRef.current.onload ) {
129
+ imgRef.current.onload = null;
130
+ }
131
+ if ( previousImg.current && previousImg.current.onload ) {
132
+ previousImg.current.onload = null;
133
+ }
134
+ clearTimeout( timeoutIdRef.current );
135
+ };
136
+ }, [ src, count, options, imgRef ] );
137
+
138
+ return loadedImg;
139
+ };
140
+
141
+ // Temporary for A/B test.
142
+ const useMshotsImgTreatment = (
143
+ src: string,
144
+ options: MShotsOptions
145
+ ): HTMLImageElement | undefined => {
146
+ const [ loadedImg, setLoadedImg ] = useState< HTMLImageElement >();
147
+ const [ count, setCount ] = useState( 0 );
148
+ const previousSrc = useRef( src );
149
+
150
+ const imgRef = useRef< HTMLImageElement >();
151
+ const timeoutIdRef = useRef< number >();
152
+
153
+ const previousImg = useRef< HTMLImageElement >();
154
+ const previousOptions = useRef< MShotsOptions >();
155
+ // Oddly, we need to assign to current here after ref creation in order to
156
+ // pass the equivalence check and avoid a spurious reset
157
+ previousOptions.current = options;
158
+
159
+ // Note: Mshots doesn't care about the "count" param, but it is important
160
+ // to browser caching. Getting this wrong looks like the url resolving
161
+ // before the image is ready.
162
+ useEffect( () => {
163
+ // If there's been a "props" change we need to reset everything:
164
+ if (
165
+ options !== previousOptions.current ||
166
+ ( src !== previousSrc.current && imgRef.current )
167
+ ) {
168
+ // Make sure an old image can't trigger a spurious state update
169
+ debug( 'resetting mShotsUrl request' );
170
+ if ( src !== previousSrc.current ) {
171
+ debug( 'src changed\nfrom', previousSrc.current, '\nto', src );
172
+ }
173
+ if ( options !== previousOptions.current ) {
174
+ debug( 'options changed\nfrom', previousOptions.current, '\nto', options );
175
+ }
176
+ if ( previousImg.current && previousImg.current.onload ) {
177
+ previousImg.current.onload = null;
178
+ if ( timeoutIdRef.current ) {
179
+ clearTimeout( timeoutIdRef.current );
180
+ timeoutIdRef.current = undefined;
181
+ }
182
+ }
183
+
184
+ setLoadedImg( undefined );
185
+ setCount( 0 );
186
+ previousImg.current = imgRef.current;
187
+
188
+ previousOptions.current = options;
189
+ previousSrc.current = src;
190
+ }
191
+
192
+ const srcUrl = mshotsUrl( src, options, count );
193
+ const newImage = new Image();
194
+ newImage.onload = () => {
195
+ // Detect default image (Don't request a 400x300 image).
196
+ //
197
+ // If this turns out to be a problem, it might help to know that the
198
+ // http request status for the default is a 307. Unfortunately we
199
+ // don't get the request through an img element so we'd need to
200
+ // take a completely different approach using ajax.
201
+ if ( newImage.naturalWidth !== 400 || newImage.naturalHeight !== 300 ) {
202
+ // Note we're using the naked object here, not the ref, because
203
+ // this is the callback on the image itself. We'd never want
204
+ // the image to finish loading and set some other image.
205
+ setLoadedImg( newImage );
206
+ } else if ( count < MAXTRIES ) {
207
+ // Only refresh 10 times
208
+ // Triggers a target.src change with increasing timeouts
209
+ timeoutIdRef.current = window.setTimeout(
210
+ () => setCount( ( count ) => count + 1 ),
211
+ count * 500
212
+ );
213
+ }
214
+ };
215
+ newImage.src = srcUrl;
216
+ imgRef.current = newImage;
217
+
218
+ return () => {
219
+ if ( imgRef.current && imgRef.current.onload ) {
220
+ imgRef.current.onload = null;
221
+ }
222
+ clearTimeout( timeoutIdRef.current );
223
+ };
224
+ }, [ src, count, options ] );
225
+
226
+ return loadedImg;
227
+ };
228
+
229
+ const MShotsImageControl = ( {
230
+ url,
231
+ 'aria-labelledby': labelledby,
232
+ alt,
233
+ options,
234
+ scrollable = false,
235
+ }: MShotsImageProps ) => {
236
+ const imgRef = useRef< HTMLImageElement | null >( null );
237
+ const currentlyLoadedUrl = useMshotsImg( url, options, imgRef );
238
+ const src: string = imgRef.current?.src || '';
239
+ const visible = src && url === currentlyLoadedUrl;
240
+ const backgroundImage = src && `url( ${ src } )`;
241
+
242
+ const animationScrollSpeedInPixelsPerSecond = 400;
243
+ const animationDuration =
244
+ ( imgRef.current?.naturalHeight || 600 ) / animationScrollSpeedInPixelsPerSecond;
245
+
246
+ const scrollableStyles = {
247
+ backgroundImage,
248
+ transition: `background-position ${ animationDuration }s`,
249
+ };
250
+
251
+ const style = {
252
+ ...( scrollable ? scrollableStyles : {} ),
253
+ };
254
+
255
+ const className = clsx(
256
+ 'mshots-image__container',
257
+ scrollable && 'hover-scroll',
258
+ visible ? 'mshots-image-visible' : 'mshots-image__loader'
259
+ );
260
+
261
+ if ( options?.oldHighResImageLoading ) {
262
+ return scrollable ? (
263
+ <div className={ className } style={ style } aria-labelledby={ labelledby }>
264
+ <img ref={ imgRef } className="mshots-dummy-image" aria-hidden="true" alt="" />
265
+ </div>
266
+ ) : (
267
+ <img
268
+ ref={ imgRef }
269
+ { ...{ className, style, src, alt } }
270
+ aria-labelledby={ labelledby }
271
+ alt={ alt }
272
+ />
273
+ );
274
+ } // else, prettier doesn't like having an else after a return
275
+ return scrollable ? (
276
+ <div className={ className } style={ style } aria-labelledby={ labelledby }>
277
+ <img ref={ imgRef } loading="lazy" className="mshots-dummy-image" aria-hidden="true" alt="" />
278
+ </div>
279
+ ) : (
280
+ <img
281
+ loading="lazy"
282
+ ref={ imgRef }
283
+ { ...{ className, style, src, alt } }
284
+ aria-labelledby={ labelledby }
285
+ alt={ alt }
286
+ />
287
+ );
288
+ };
289
+
290
+ // Temporary for A/B test.
291
+ const MShotsImageTreatment = ( {
292
+ url,
293
+ 'aria-labelledby': labelledby,
294
+ alt,
295
+ options,
296
+ scrollable = false,
297
+ }: MShotsImageProps ) => {
298
+ const maybeImage = useMshotsImgTreatment( url, options );
299
+ const src: string = maybeImage?.src || '';
300
+ const visible = !! src;
301
+ const backgroundImage = maybeImage?.src && `url( ${ maybeImage?.src } )`;
302
+
303
+ const animationScrollSpeedInPixelsPerSecond = 400;
304
+ const animationDuration =
305
+ ( maybeImage?.naturalHeight || 600 ) / animationScrollSpeedInPixelsPerSecond;
306
+
307
+ const scrollableStyles = {
308
+ backgroundImage,
309
+ transition: `background-position ${ animationDuration }s`,
310
+ };
311
+
312
+ const style = {
313
+ ...( scrollable ? scrollableStyles : {} ),
314
+ };
315
+
316
+ const className = clsx(
317
+ 'mshots-image__container',
318
+ scrollable && 'hover-scroll',
319
+ visible ? 'mshots-image-visible' : 'mshots-image__loader'
320
+ );
321
+
322
+ // The "! visible" here is only to dodge a particularly specific css
323
+ // rule effecting the placeholder while loading static images:
324
+ // '.design-picker .design-picker__image-frame img { ..., height: auto }'
325
+ return scrollable || ! visible ? (
326
+ <div className={ className } style={ style } aria-labelledby={ labelledby } />
327
+ ) : (
328
+ <img { ...{ className, style, src, alt } } aria-labelledby={ labelledby } alt={ alt } />
329
+ );
330
+ };
331
+
332
+ // For hover-scroll, we use a div with a background image (rather than an img element)
333
+ // in order to use transitions between `top` and `bottom` on the
334
+ // `background-position` property.
335
+ // The "normal" top & bottom properties are problematic individually because we
336
+ // don't know how big the images will be, and using both gets the
337
+ // right positions but with no transition (as they're different properties).
338
+ const MShotsImage = ( {
339
+ url,
340
+ 'aria-labelledby': labelledby,
341
+ alt,
342
+ options,
343
+ scrollable = false,
344
+ }: MShotsImageProps ) => {
345
+ // Return MShotsImageControl or MShotsImageTreatment depending on options.oldHighResImageLoading
346
+ if ( options?.oldHighResImageLoading ) {
347
+ return (
348
+ <MShotsImageTreatment
349
+ url={ url }
350
+ aria-labelledby={ labelledby }
351
+ alt={ alt }
352
+ options={ options }
353
+ scrollable={ scrollable }
354
+ />
355
+ );
356
+ }
357
+ return (
358
+ <MShotsImageControl
359
+ url={ url }
360
+ aria-labelledby={ labelledby }
361
+ alt={ alt }
362
+ options={ options }
363
+ scrollable={ scrollable }
364
+ />
365
+ );
366
+ };
367
+
368
+ export default MShotsImage;
@@ -0,0 +1,43 @@
1
+ @import "../../styles/mixins";
2
+
3
+ .mshots-image__loader {
4
+ @include onboarding-placeholder();
5
+ }
6
+
7
+ .mshots-image__container {
8
+ height: 100%;
9
+ }
10
+
11
+ .hover-scroll {
12
+ background-size: 100%;
13
+ background-position: top;
14
+ background-repeat: no-repeat;
15
+ margin-left: auto;
16
+ margin-right: auto;
17
+
18
+ &:hover {
19
+ background-position: bottom;
20
+ }
21
+ }
22
+
23
+ .mshots-image-visible {
24
+ animation: fadein 300ms;
25
+ }
26
+
27
+ // Increase specificity by repeating class name.
28
+ .mshots-dummy-image.mshots-dummy-image {
29
+ position: absolute;
30
+ display: block;
31
+ visibility: hidden;
32
+ height: 0;
33
+ width: 0;
34
+ }
35
+
36
+ @keyframes fadein {
37
+ from {
38
+ opacity: 0;
39
+ }
40
+ to {
41
+ opacity: 1;
42
+ }
43
+ }
@@ -0,0 +1,5 @@
1
+ describe( 'mshots-image', () => {
2
+ it( 'should be replaced with real tests', () => {
3
+ expect( 1 ).toBeTruthy();
4
+ } );
5
+ } );
@@ -0,0 +1,2 @@
1
+ export { default as useNavigatorListener } from './use-navigator-listener';
2
+ export type { OnNavigatorPathChange } from './use-navigator-listener';
@@ -0,0 +1,18 @@
1
+ import { __experimentalUseNavigator as useNavigator } from '@wordpress/components';
2
+ import { useEffect, useRef } from 'react';
3
+
4
+ export type OnNavigatorPathChange = ( path?: string ) => void;
5
+
6
+ const useNavigatorListener = ( onNavigatorPathChange?: OnNavigatorPathChange ) => {
7
+ const { location } = useNavigator();
8
+ const previousPathRef = useRef( '' );
9
+
10
+ useEffect( () => {
11
+ if ( location.path && location.path !== previousPathRef.current ) {
12
+ onNavigatorPathChange?.( location.path );
13
+ previousPathRef.current = location.path;
14
+ }
15
+ }, [ location.path, onNavigatorPathChange ] );
16
+ };
17
+
18
+ export default useNavigatorListener;
@@ -0,0 +1,7 @@
1
+ export * from './hooks';
2
+ export { NavigatorButtonAsItem, NavigatorItem } from './navigator-buttons';
3
+ export { default as NavigatorHeader } from './navigator-header';
4
+ export { default as NavigatorItemGroup } from './navigator-item-group';
5
+ export { default as NavigatorListener } from './navigator-listener';
6
+ export { default as NavigatorScreen } from './navigator-screen';
7
+ export * from './navigator-screens';
@@ -0,0 +1,58 @@
1
+ import {
2
+ __experimentalNavigatorButton as NavigatorButton,
3
+ __experimentalHStack as HStack,
4
+ __experimentalItem as Item,
5
+ FlexItem,
6
+ } from '@wordpress/components';
7
+ import { isRTL } from '@wordpress/i18n';
8
+ import { Icon, chevronLeft, chevronRight, check } from '@wordpress/icons';
9
+ import clsx from 'clsx';
10
+ import './style.scss';
11
+
12
+ interface NavigatorItemProps {
13
+ className?: string;
14
+ icon?: JSX.Element;
15
+ children: React.ReactNode;
16
+ onClick?: () => void;
17
+ checked?: boolean;
18
+ active?: boolean;
19
+ }
20
+
21
+ interface NavigatorButtonAsItemProps extends NavigatorItemProps {
22
+ path: string;
23
+ }
24
+
25
+ export function NavigatorItem( { icon, checked, active, children, ...props }: NavigatorItemProps ) {
26
+ const content = icon ? (
27
+ <HStack justify="flex-start">
28
+ <Icon className="navigator-item__icon" icon={ checked ? check : icon } size={ 24 } />
29
+ <FlexItem className="navigator-item__text" display="flex" isBlock>
30
+ { children }
31
+ </FlexItem>
32
+ </HStack>
33
+ ) : (
34
+ <FlexItem display="flex" isBlock>
35
+ { children }
36
+ </FlexItem>
37
+ );
38
+
39
+ const forwardIcon = isRTL() ? chevronLeft : chevronRight;
40
+
41
+ return (
42
+ <Item
43
+ { ...props }
44
+ className={ clsx( 'navigator-item', {
45
+ 'navigator-item--active': active,
46
+ } ) }
47
+ >
48
+ <HStack justify="space-between">
49
+ { content }
50
+ <Icon icon={ forwardIcon } size={ 24 } />
51
+ </HStack>
52
+ </Item>
53
+ );
54
+ }
55
+
56
+ export const NavigatorButtonAsItem = ( { ...props }: NavigatorButtonAsItemProps ) => {
57
+ return <NavigatorButton as={ NavigatorItem } { ...props } />;
58
+ };
@@ -0,0 +1,47 @@
1
+ @import "@automattic/typography/styles/fonts";
2
+
3
+ .components-item.navigator-item {
4
+ height: 44px;
5
+ line-height: 44px;
6
+ padding: 0 5px 0 8px;
7
+ margin: 0 -5px 0 -8px;
8
+ font-size: $font-body-small;
9
+ font-weight: 400;
10
+ letter-spacing: -0.15px;
11
+ color: var(--studio-gray-100);
12
+ border: none;
13
+ background: transparent;
14
+ cursor: pointer;
15
+
16
+ svg {
17
+ flex-shrink: 0;
18
+ fill: currentColor;
19
+ }
20
+
21
+ &:hover,
22
+ &:focus-visible {
23
+ color: var(--studio-blue-50);
24
+ }
25
+
26
+ &:focus {
27
+ box-shadow: none;
28
+ }
29
+
30
+ &:focus-visible {
31
+ border-color: var(--color-primary);
32
+ box-shadow: 0 0 0 2px var(--color-primary-light);
33
+ }
34
+
35
+ &:active {
36
+ background-color: var(--studio-blue-0);
37
+ }
38
+
39
+ .navigator-item__text {
40
+ padding-left: 1px;
41
+ }
42
+
43
+ &--active {
44
+ background-color: var(--studio-blue-0);
45
+ color: var(--studio-blue-50);
46
+ }
47
+ }
@@ -0,0 +1,40 @@
1
+ import { Button, Gridicon } from '@automattic/components';
2
+ import {
3
+ __experimentalHStack as HStack,
4
+ __experimentalNavigatorBackButton as NavigatorBackButton,
5
+ } from '@wordpress/components';
6
+ import { useTranslate, TranslateResult } from 'i18n-calypso';
7
+ import './style.scss';
8
+
9
+ interface Props {
10
+ title: JSX.Element;
11
+ description?: TranslateResult;
12
+ hideBack?: boolean;
13
+ onBack?: () => void;
14
+ }
15
+
16
+ const NavigatorHeader = ( { title, description, hideBack, onBack }: Props ) => {
17
+ const translate = useTranslate();
18
+
19
+ return (
20
+ <div className="navigator-header">
21
+ <HStack className="navigator-header__heading" spacing={ 2 } justify="flex-start">
22
+ { ! hideBack && (
23
+ <NavigatorBackButton
24
+ as={ Button }
25
+ title={ translate( 'Back' ) }
26
+ borderless
27
+ aria-label={ translate( 'Navigate to the previous view' ) }
28
+ onClick={ onBack }
29
+ >
30
+ <Gridicon icon="chevron-left" size={ 16 } />
31
+ </NavigatorBackButton>
32
+ ) }
33
+ <h2>{ title }</h2>
34
+ </HStack>
35
+ { description && <p className="navigator-header__description">{ description }</p> }
36
+ </div>
37
+ );
38
+ };
39
+
40
+ export default NavigatorHeader;
@@ -0,0 +1,45 @@
1
+ @import "@wordpress/base-styles/breakpoints";
2
+ @import "@wordpress/base-styles/mixins";
3
+ @import "@automattic/typography/styles/fonts";
4
+
5
+ .navigator-header {
6
+ display: none;
7
+ margin-bottom: 30px;
8
+
9
+ @include break-large {
10
+ display: block;
11
+ }
12
+ }
13
+
14
+ .navigator-header__heading {
15
+ margin-bottom: 8px;
16
+ color: var(--color-neutral-100);
17
+ text-wrap: pretty;
18
+
19
+ h2 {
20
+ font-family: Recoleta, sans-serif;
21
+ font-style: normal;
22
+ font-weight: 400;
23
+ font-size: $font-title-large;
24
+ line-height: 40px;
25
+ letter-spacing: -0.32px;
26
+ }
27
+
28
+ .button.is-borderless .gridicon {
29
+ top: 4px;
30
+ }
31
+
32
+ .premium-badge {
33
+ margin-inline-start: 2px;
34
+ }
35
+ }
36
+
37
+ .navigator-header__description {
38
+ font-size: $font-body-small;
39
+ font-weight: 400;
40
+ line-height: 20px;
41
+ letter-spacing: -0.15px;
42
+ color: var(--color-neutral-60);
43
+ margin: 0;
44
+ text-wrap: pretty;
45
+ }
@@ -0,0 +1,23 @@
1
+ import {
2
+ __experimentalVStack as VStack,
3
+ __experimentalItemGroup as ItemGroup,
4
+ } from '@wordpress/components';
5
+ import './style.scss';
6
+
7
+ type Props = {
8
+ children: React.ReactNode;
9
+ title?: string;
10
+ };
11
+
12
+ const NavigatorItemGroup = ( { children, title }: Props ) => {
13
+ return (
14
+ <section className="navigator-item-group">
15
+ <VStack direction="column" justify="flex-start" alignment="stretch">
16
+ { title && <h3 className="navigator-item-group__title">{ title }</h3> }
17
+ <ItemGroup>{ children }</ItemGroup>
18
+ </VStack>
19
+ </section>
20
+ );
21
+ };
22
+
23
+ export default NavigatorItemGroup;
@@ -0,0 +1,28 @@
1
+ @import "@automattic/typography/styles/fonts";
2
+
3
+ .navigator-item-group {
4
+ flex-shrink: 0;
5
+
6
+ .components-item-group > div[role="listitem"] {
7
+ display: flex;
8
+ }
9
+
10
+ .navigator-item {
11
+ flex-grow: 1;
12
+ }
13
+
14
+ &:nth-child(1 of &):nth-last-child(1 of &) {
15
+ .navigator-item-group__title {
16
+ display: none;
17
+ }
18
+ }
19
+ }
20
+
21
+ .navigator-item-group__title {
22
+ color: var(--color-neutral-100);
23
+ font-size: $font-body-small;
24
+ font-weight: 500;
25
+ letter-spacing: -0.15px;
26
+ line-height: 1.4;
27
+ margin-bottom: 8px;
28
+ }