newspack-components 4.7.0 → 4.8.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 (251) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/DEVELOPMENT.md +42 -21
  3. package/dist/cjs/_mixins.scss +13 -0
  4. package/dist/cjs/_variables.scss +12 -0
  5. package/dist/cjs/action-card/index.js +18 -10
  6. package/dist/cjs/action-card/index.test.js +91 -0
  7. package/dist/cjs/action-card/style.scss +2 -40
  8. package/dist/cjs/button/index.js +8 -3
  9. package/dist/cjs/button/index.test.js +61 -5
  10. package/dist/cjs/card/core-card.js +0 -2
  11. package/dist/cjs/card/style-core.scss +7 -5
  12. package/dist/cjs/card-feature/index.js +75 -61
  13. package/dist/cjs/card-feature/index.test.js +396 -54
  14. package/dist/cjs/card-feature/style.scss +20 -31
  15. package/dist/cjs/card-form/index.js +5 -5
  16. package/dist/cjs/card-sortable-list/index.js +5 -3
  17. package/dist/cjs/card-sortable-list/index.test.js +50 -0
  18. package/dist/cjs/collapsible-group/context.js +19 -0
  19. package/dist/cjs/collapsible-group/index.js +24 -0
  20. package/dist/cjs/collapsible-group/index.test.js +215 -0
  21. package/dist/cjs/collapsible-group/item.js +61 -0
  22. package/dist/cjs/collapsible-group/root.js +62 -0
  23. package/dist/cjs/collapsible-group/style.scss +47 -0
  24. package/dist/cjs/collapsible-group/types.js +5 -0
  25. package/dist/cjs/empty-state/actions.js +45 -0
  26. package/dist/cjs/empty-state/context.js +41 -0
  27. package/dist/cjs/empty-state/header.js +66 -0
  28. package/dist/cjs/empty-state/index.js +31 -0
  29. package/dist/cjs/empty-state/index.test.js +303 -0
  30. package/dist/cjs/empty-state/root.js +56 -0
  31. package/dist/cjs/empty-state/style.scss +51 -0
  32. package/dist/cjs/empty-state/types.js +5 -0
  33. package/dist/cjs/index.js +34 -20
  34. package/dist/cjs/info-button/index.js +59 -43
  35. package/dist/cjs/info-button/index.test.js +199 -0
  36. package/dist/cjs/info-button/style.scss +41 -9
  37. package/dist/cjs/modal/style.scss +12 -12
  38. package/dist/cjs/newspack-icon/style.scss +4 -4
  39. package/dist/cjs/notice/style.scss +3 -3
  40. package/dist/cjs/page/style.scss +16 -16
  41. package/dist/cjs/plugin-installer/index.js +5 -9
  42. package/dist/cjs/plugin-installer/style.scss +3 -14
  43. package/dist/cjs/section-header/index.js +31 -18
  44. package/dist/cjs/section-header/index.test.js +40 -0
  45. package/dist/cjs/section-header/style.scss +22 -6
  46. package/dist/cjs/settings/DateRangeSetting.js +309 -0
  47. package/dist/cjs/settings/SettingsSection.js +19 -5
  48. package/dist/cjs/settings/SettingsSection.test.js +49 -0
  49. package/dist/cjs/settings/index.js +3 -1
  50. package/dist/cjs/settings/style.scss +40 -7
  51. package/dist/cjs/stat-card/body.js +41 -0
  52. package/dist/cjs/stat-card/constants.js +11 -0
  53. package/dist/cjs/stat-card/context.js +54 -0
  54. package/dist/cjs/stat-card/delta.js +91 -0
  55. package/dist/cjs/stat-card/footer.js +72 -0
  56. package/dist/cjs/stat-card/index.js +47 -0
  57. package/dist/cjs/stat-card/index.test.js +938 -0
  58. package/dist/cjs/stat-card/label.js +66 -0
  59. package/dist/cjs/stat-card/root.js +69 -0
  60. package/dist/cjs/stat-card/secondary.js +38 -0
  61. package/dist/cjs/stat-card/style.scss +89 -0
  62. package/dist/cjs/stat-card/types.js +5 -0
  63. package/dist/cjs/stat-card/value.js +78 -0
  64. package/dist/cjs/status-indicator/index.js +66 -0
  65. package/dist/cjs/status-indicator/index.test.js +101 -0
  66. package/dist/cjs/status-indicator/statuses.js +39 -0
  67. package/dist/cjs/status-indicator/style.scss +9 -0
  68. package/dist/cjs/status-indicator/types.js +5 -0
  69. package/dist/cjs/style.scss +9 -9
  70. package/dist/cjs/tabbed-navigation/style.scss +6 -4
  71. package/dist/cjs/types.js +5 -0
  72. package/dist/cjs/web-preview/style.scss +11 -11
  73. package/dist/cjs/with-wizard/style.scss +10 -10
  74. package/dist/cjs/with-wizard-screen/style.scss +9 -9
  75. package/dist/cjs/wizard/index.js +33 -4
  76. package/dist/cjs/wizard/store/index.js +23 -1
  77. package/dist/esm/_mixins.scss +13 -0
  78. package/dist/esm/_variables.scss +12 -0
  79. package/dist/esm/action-card/index.js +18 -10
  80. package/dist/esm/action-card/index.test.js +89 -0
  81. package/dist/esm/action-card/style.scss +2 -40
  82. package/dist/esm/button/index.js +9 -4
  83. package/dist/esm/button/index.test.js +63 -5
  84. package/dist/esm/card/core-card.js +0 -2
  85. package/dist/esm/card/style-core.scss +7 -5
  86. package/dist/esm/card-feature/index.js +78 -62
  87. package/dist/esm/card-feature/index.test.js +397 -55
  88. package/dist/esm/card-feature/style.scss +20 -31
  89. package/dist/esm/card-form/index.js +5 -5
  90. package/dist/esm/card-sortable-list/index.js +6 -4
  91. package/dist/esm/card-sortable-list/index.test.js +46 -0
  92. package/dist/esm/collapsible-group/context.js +13 -0
  93. package/dist/esm/collapsible-group/index.js +17 -0
  94. package/dist/esm/collapsible-group/index.test.js +215 -0
  95. package/dist/esm/collapsible-group/item.js +53 -0
  96. package/dist/esm/collapsible-group/root.js +54 -0
  97. package/dist/esm/collapsible-group/style.scss +47 -0
  98. package/dist/esm/collapsible-group/types.js +1 -0
  99. package/dist/esm/empty-state/actions.js +37 -0
  100. package/dist/esm/empty-state/context.js +35 -0
  101. package/dist/esm/empty-state/header.js +58 -0
  102. package/dist/esm/empty-state/index.js +23 -0
  103. package/dist/esm/empty-state/index.test.js +299 -0
  104. package/dist/esm/empty-state/root.js +56 -0
  105. package/dist/esm/empty-state/style.scss +51 -0
  106. package/dist/esm/empty-state/types.js +1 -0
  107. package/dist/esm/index.js +4 -2
  108. package/dist/esm/info-button/index.js +54 -43
  109. package/dist/esm/info-button/index.test.js +195 -0
  110. package/dist/esm/info-button/style.scss +41 -9
  111. package/dist/esm/modal/style.scss +12 -12
  112. package/dist/esm/newspack-icon/style.scss +4 -4
  113. package/dist/esm/notice/style.scss +3 -3
  114. package/dist/esm/page/style.scss +16 -16
  115. package/dist/esm/plugin-installer/index.js +5 -9
  116. package/dist/esm/plugin-installer/style.scss +3 -14
  117. package/dist/esm/section-header/index.js +27 -14
  118. package/dist/esm/section-header/index.test.js +36 -0
  119. package/dist/esm/section-header/style.scss +22 -6
  120. package/dist/esm/settings/DateRangeSetting.js +304 -0
  121. package/dist/esm/settings/SettingsSection.js +16 -3
  122. package/dist/esm/settings/SettingsSection.test.js +45 -0
  123. package/dist/esm/settings/index.js +3 -1
  124. package/dist/esm/settings/style.scss +40 -7
  125. package/dist/esm/stat-card/body.js +36 -0
  126. package/dist/esm/stat-card/constants.js +5 -0
  127. package/dist/esm/stat-card/context.js +48 -0
  128. package/dist/esm/stat-card/delta.js +86 -0
  129. package/dist/esm/stat-card/footer.js +67 -0
  130. package/dist/esm/stat-card/index.js +33 -0
  131. package/dist/esm/stat-card/index.test.js +939 -0
  132. package/dist/esm/stat-card/label.js +61 -0
  133. package/dist/esm/stat-card/root.js +64 -0
  134. package/dist/esm/stat-card/secondary.js +33 -0
  135. package/dist/esm/stat-card/style.scss +89 -0
  136. package/dist/esm/stat-card/types.js +1 -0
  137. package/dist/esm/stat-card/value.js +73 -0
  138. package/dist/esm/status-indicator/index.js +52 -0
  139. package/dist/esm/status-indicator/index.test.js +96 -0
  140. package/dist/esm/status-indicator/statuses.js +33 -0
  141. package/dist/esm/status-indicator/style.scss +9 -0
  142. package/dist/esm/status-indicator/types.js +1 -0
  143. package/dist/esm/style.scss +9 -9
  144. package/dist/esm/tabbed-navigation/style.scss +6 -4
  145. package/dist/esm/types.js +1 -0
  146. package/dist/esm/web-preview/style.scss +11 -11
  147. package/dist/esm/with-wizard/style.scss +10 -10
  148. package/dist/esm/with-wizard-screen/style.scss +9 -9
  149. package/dist/esm/wizard/index.js +38 -7
  150. package/dist/esm/wizard/store/index.js +23 -1
  151. package/package.json +1 -1
  152. package/src/_mixins.scss +13 -0
  153. package/src/_variables.scss +12 -0
  154. package/src/action-card/action-card.d.ts +3 -2
  155. package/src/action-card/index.js +12 -12
  156. package/src/action-card/index.test.js +56 -0
  157. package/src/action-card/style.scss +2 -40
  158. package/src/button/index.test.js +52 -5
  159. package/src/button/index.tsx +9 -4
  160. package/src/card/core-card.js +0 -2
  161. package/src/card/style-core.scss +7 -5
  162. package/src/card-feature/README.md +68 -27
  163. package/src/card-feature/index.test.js +242 -27
  164. package/src/card-feature/index.tsx +77 -67
  165. package/src/card-feature/style.scss +20 -31
  166. package/src/card-form/README.md +10 -10
  167. package/src/card-form/index.tsx +4 -8
  168. package/src/card-sortable-list/README.md +4 -5
  169. package/src/card-sortable-list/index.test.js +29 -0
  170. package/src/card-sortable-list/index.tsx +7 -4
  171. package/src/collapsible-group/README.md +50 -0
  172. package/src/collapsible-group/context.ts +13 -0
  173. package/src/collapsible-group/index.test.js +168 -0
  174. package/src/collapsible-group/index.tsx +17 -0
  175. package/src/collapsible-group/item.tsx +42 -0
  176. package/src/collapsible-group/root.tsx +42 -0
  177. package/src/collapsible-group/style.scss +47 -0
  178. package/src/collapsible-group/types.ts +22 -0
  179. package/src/drawer/README.md +2 -2
  180. package/src/empty-state/README.md +165 -0
  181. package/src/empty-state/actions.tsx +37 -0
  182. package/src/empty-state/context.ts +40 -0
  183. package/src/empty-state/header.tsx +48 -0
  184. package/src/empty-state/index.test.js +247 -0
  185. package/src/empty-state/index.tsx +22 -0
  186. package/src/empty-state/root.tsx +39 -0
  187. package/src/empty-state/style.scss +51 -0
  188. package/src/empty-state/types.ts +33 -0
  189. package/src/index.js +4 -2
  190. package/src/info-button/README.md +115 -0
  191. package/src/info-button/index.test.js +163 -0
  192. package/src/info-button/index.tsx +64 -0
  193. package/src/info-button/style.scss +41 -9
  194. package/src/modal/style.scss +12 -12
  195. package/src/newspack-icon/style.scss +4 -4
  196. package/src/notice/style.scss +3 -3
  197. package/src/page/style.scss +16 -16
  198. package/src/plugin-installer/index.js +3 -9
  199. package/src/plugin-installer/style.scss +3 -14
  200. package/src/section-header/index.js +27 -14
  201. package/src/section-header/index.test.js +28 -0
  202. package/src/section-header/style.scss +22 -6
  203. package/src/settings/DateRangeSetting.js +266 -0
  204. package/src/settings/SettingsSection.js +24 -4
  205. package/src/settings/SettingsSection.test.js +45 -0
  206. package/src/settings/index.js +2 -0
  207. package/src/settings/style.scss +40 -7
  208. package/src/stat-card/README.md +434 -0
  209. package/src/stat-card/body.tsx +28 -0
  210. package/src/stat-card/constants.ts +5 -0
  211. package/src/stat-card/context.ts +53 -0
  212. package/src/stat-card/delta.tsx +88 -0
  213. package/src/stat-card/footer.tsx +68 -0
  214. package/src/stat-card/index.test.js +818 -0
  215. package/src/stat-card/index.tsx +48 -0
  216. package/src/stat-card/label.tsx +61 -0
  217. package/src/stat-card/root.tsx +40 -0
  218. package/src/stat-card/secondary.tsx +27 -0
  219. package/src/stat-card/style.scss +89 -0
  220. package/src/stat-card/types.ts +84 -0
  221. package/src/stat-card/value.tsx +72 -0
  222. package/src/status-indicator/README.md +123 -0
  223. package/src/status-indicator/index.test.js +70 -0
  224. package/src/status-indicator/index.tsx +39 -0
  225. package/src/status-indicator/statuses.ts +35 -0
  226. package/src/status-indicator/style.scss +9 -0
  227. package/src/status-indicator/types.ts +28 -0
  228. package/src/style.scss +9 -9
  229. package/src/tabbed-navigation/style.scss +6 -4
  230. package/src/types.ts +25 -0
  231. package/src/web-preview/style.scss +11 -11
  232. package/src/with-wizard/style.scss +10 -10
  233. package/src/with-wizard-screen/style.scss +9 -9
  234. package/src/wizard/index.js +49 -7
  235. package/src/wizard/store/index.js +26 -1
  236. package/dist/cjs/accordion/index.js +0 -72
  237. package/dist/cjs/accordion/index.test.js +0 -80
  238. package/dist/cjs/accordion/style.scss +0 -35
  239. package/dist/cjs/badge/index.js +0 -32
  240. package/dist/cjs/badge/style.scss +0 -36
  241. package/dist/esm/accordion/index.js +0 -63
  242. package/dist/esm/accordion/index.test.js +0 -79
  243. package/dist/esm/accordion/style.scss +0 -35
  244. package/dist/esm/badge/index.js +0 -24
  245. package/dist/esm/badge/style.scss +0 -36
  246. package/src/accordion/index.js +0 -46
  247. package/src/accordion/index.test.js +0 -62
  248. package/src/accordion/style.scss +0 -35
  249. package/src/badge/index.tsx +0 -26
  250. package/src/badge/style.scss +0 -36
  251. package/src/info-button/index.js +0 -38
@@ -3,20 +3,20 @@
3
3
  */
4
4
 
5
5
  @use "~@wordpress/base-styles/colors" as wp-colors;
6
- @use "../../../colors/colors.module" as colors;
6
+ @use "../../../colors/colors.module" as np-colors;
7
7
 
8
8
  .newspack-web-preview {
9
9
  // Color
10
- --wp-admin-theme-color: #{colors.$primary-600};
11
- --wp-admin-theme-color--rgb: #{colors.$primary-600--rgb};
12
- --wp-admin-theme-color-darker-10: #{colors.$primary-700};
13
- --wp-admin-theme-color-darker-10--rgb: #{colors.$primary-700--rgb};
14
- --wp-admin-theme-color-darker-20: #{colors.$primary-800};
15
- --wp-admin-theme-color-darker-20--rgb: #{colors.$primary-800--rgb};
16
- --wp-admin-theme-color-lighter-10: #{colors.$primary-000};
17
- --wp-admin-theme-color-lighter-10--rgb: #{colors.$primary-000--rgb};
18
-
19
- background: color-mix(in srgb, colors.$neutral-1000, transparent 65%);
10
+ --wp-admin-theme-color: #{np-colors.$primary-600};
11
+ --wp-admin-theme-color--rgb: #{np-colors.$primary-600--rgb};
12
+ --wp-admin-theme-color-darker-10: #{np-colors.$primary-700};
13
+ --wp-admin-theme-color-darker-10--rgb: #{np-colors.$primary-700--rgb};
14
+ --wp-admin-theme-color-darker-20: #{np-colors.$primary-800};
15
+ --wp-admin-theme-color-darker-20--rgb: #{np-colors.$primary-800--rgb};
16
+ --wp-admin-theme-color-lighter-10: #{np-colors.$primary-000};
17
+ --wp-admin-theme-color-lighter-10--rgb: #{np-colors.$primary-000--rgb};
18
+
19
+ background: color-mix(in srgb, np-colors.$neutral-1000, transparent 65%);
20
20
  box-sizing: border-box;
21
21
  height: 100%;
22
22
  left: 0;
@@ -3,19 +3,19 @@
3
3
  */
4
4
 
5
5
  @use "~@wordpress/base-styles/colors" as wp-colors;
6
- @use "../../../colors/colors.module" as colors;
6
+ @use "../../../colors/colors.module" as np-colors;
7
7
 
8
8
  // Styling for full-page-react Wizards (ignoring admin-header-only wizards).
9
9
  body.newspack-wizard-page:not(.newspack-admin-header) {
10
- --wp-admin-theme-color: #{colors.$primary-600};
11
- --wp-admin-theme-color--rgb: #{colors.$primary-600--rgb};
12
- --wp-admin-theme-color-darker-10: #{colors.$primary-700};
13
- --wp-admin-theme-color-darker-10--rgb: #{colors.$primary-700--rgb};
14
- --wp-admin-theme-color-darker-20: #{colors.$primary-800};
15
- --wp-admin-theme-color-darker-20--rgb: #{colors.$primary-800--rgb};
16
- --wp-admin-theme-color-lighter-10: #{colors.$primary-000};
17
- --wp-admin-theme-color-lighter-10--rgb: #{colors.$primary-000--rgb};
18
- --wp-components-color-accent: #{colors.$primary-600};
10
+ --wp-admin-theme-color: #{np-colors.$primary-600};
11
+ --wp-admin-theme-color--rgb: #{np-colors.$primary-600--rgb};
12
+ --wp-admin-theme-color-darker-10: #{np-colors.$primary-700};
13
+ --wp-admin-theme-color-darker-10--rgb: #{np-colors.$primary-700--rgb};
14
+ --wp-admin-theme-color-darker-20: #{np-colors.$primary-800};
15
+ --wp-admin-theme-color-darker-20--rgb: #{np-colors.$primary-800--rgb};
16
+ --wp-admin-theme-color-lighter-10: #{np-colors.$primary-000};
17
+ --wp-admin-theme-color-lighter-10--rgb: #{np-colors.$primary-000--rgb};
18
+ --wp-components-color-accent: #{np-colors.$primary-600};
19
19
 
20
20
  background: #{wp-colors.$white};
21
21
 
@@ -3,18 +3,18 @@
3
3
  */
4
4
 
5
5
  @use "~@wordpress/base-styles/colors" as wp-colors;
6
- @use "../../../colors/colors.module" as colors;
6
+ @use "../../../colors/colors.module" as np-colors;
7
7
 
8
8
  .newspack-wizard {
9
9
  // Color
10
- --wp-admin-theme-color: #{colors.$primary-600};
11
- --wp-admin-theme-color--rgb: #{colors.$primary-600--rgb};
12
- --wp-admin-theme-color-darker-10: #{colors.$primary-700};
13
- --wp-admin-theme-color-darker-10--rgb: #{colors.$primary-700--rgb};
14
- --wp-admin-theme-color-darker-20: #{colors.$primary-800};
15
- --wp-admin-theme-color-darker-20--rgb: #{colors.$primary-800--rgb};
16
- --wp-admin-theme-color-lighter-10: #{colors.$primary-000};
17
- --wp-admin-theme-color-lighter-10--rgb: #{colors.$primary-000--rgb};
10
+ --wp-admin-theme-color: #{np-colors.$primary-600};
11
+ --wp-admin-theme-color--rgb: #{np-colors.$primary-600--rgb};
12
+ --wp-admin-theme-color-darker-10: #{np-colors.$primary-700};
13
+ --wp-admin-theme-color-darker-10--rgb: #{np-colors.$primary-700--rgb};
14
+ --wp-admin-theme-color-darker-20: #{np-colors.$primary-800};
15
+ --wp-admin-theme-color-darker-20--rgb: #{np-colors.$primary-800--rgb};
16
+ --wp-admin-theme-color-lighter-10: #{np-colors.$primary-000};
17
+ --wp-admin-theme-color-lighter-10--rgb: #{np-colors.$primary-000--rgb};
18
18
 
19
19
  color: wp-colors.$gray-900;
20
20
 
@@ -205,6 +205,7 @@ var Wizard = function Wizard(_ref2, ref) {
205
205
  sectionDescription = headerData.sectionDescription,
206
206
  sectionMenu = headerData.sectionMenu,
207
207
  sectionName = headerData.sectionName,
208
+ sectionSize = headerData.sectionSize,
208
209
  sectionTitle = headerData.sectionTitle,
209
210
  sectionPrimaryAction = headerData.sectionPrimaryAction,
210
211
  sectionSecondaryAction = headerData.sectionSecondaryAction;
@@ -227,6 +228,14 @@ var Wizard = function Wizard(_ref2, ref) {
227
228
  _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
228
229
  pluginRequirementsSatisfied = _useState2[0],
229
230
  setPluginRequirementsSatisfied = _useState2[1];
231
+ // Whether the requirements check has reported back. Until it has, the check
232
+ // shows the same fetching treatment as the rest of the wizard rather than
233
+ // the installer's own spinner and the swapped header; the installer only
234
+ // surfaces once a plugin is actually found missing.
235
+ var _useState3 = (0, _element.useState)(requiredPlugins.length === 0),
236
+ _useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
237
+ pluginRequirementsKnown = _useState4[0],
238
+ setPluginRequirementsKnown = _useState4[1];
230
239
 
231
240
  // The data fetch above runs once per mount, while the required plugins are
232
241
  // still missing — endpoints that need them answer empty or error outright,
@@ -241,6 +250,7 @@ var Wizard = function Wizard(_ref2, ref) {
241
250
  // Leave the installer first: whatever happens to the refetch, the user
242
251
  // should not be stranded on a required-plugins screen for a plugin they
243
252
  // just installed.
253
+ setPluginRequirementsKnown(true);
244
254
  setPluginRequirementsSatisfied(complete);
245
255
  if (!complete) {
246
256
  requirementsWereUnmet.current = true;
@@ -252,13 +262,31 @@ var Wizard = function Wizard(_ref2, ref) {
252
262
  }
253
263
  };
254
264
  if (!pluginRequirementsSatisfied) {
255
- headerText = requiredPlugins.length > 1 ? (0, _i18n.__)('Required plugins', 'newspack-plugin') : (0, _i18n.__)('Required plugin', 'newspack-plugin');
265
+ if (pluginRequirementsKnown) {
266
+ headerText = requiredPlugins.length > 1 ? (0, _i18n.__)('Required plugins', 'newspack-plugin') : (0, _i18n.__)('Required plugin', 'newspack-plugin');
267
+ }
256
268
  displayedSections = [{
257
269
  path: '/',
258
270
  render: function render() {
259
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_.PluginInstaller, {
260
- plugins: requiredPlugins,
261
- onStatus: onPluginStatus
271
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
272
+ children: [!pluginRequirementsKnown && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
273
+ className: "newspack-wizard__loader",
274
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.__experimentalVStack, {
275
+ alignment: "center",
276
+ spacing: 2,
277
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_.Waiting, {
278
+ noMargin: true
279
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("strong", {
280
+ children: (0, _i18n.__)('Fetching…', 'newspack-plugin')
281
+ })]
282
+ })
283
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
284
+ hidden: !pluginRequirementsKnown,
285
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_.PluginInstaller, {
286
+ plugins: requiredPlugins,
287
+ onStatus: onPluginStatus
288
+ })
289
+ })]
262
290
  });
263
291
  }
264
292
  }];
@@ -322,6 +350,7 @@ var Wizard = function Wizard(_ref2, ref) {
322
350
  primaryAction: sectionPrimaryAction || section.primaryAction,
323
351
  secondaryAction: sectionSecondaryAction || section.secondaryAction,
324
352
  heading: 2,
353
+ size: sectionSize || section.size,
325
354
  noMargin: true
326
355
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(SectionComponent, _objectSpread(_objectSpread(_objectSpread({}, routerProps), sectionProps), sharedProps))]
327
356
  });
@@ -261,6 +261,28 @@ var store = (0, _data.createReduxStore)(WIZARD_STORE_NAMESPACE, {
261
261
  })
262
262
  }
263
263
  });
264
+
265
+ /**
266
+ * Register the wizard store, unless it already exists.
267
+ *
268
+ * This package is bundled separately into each consuming plugin, so more than one
269
+ * bundle can call this on the same page (e.g. the block editor loads assets from
270
+ * both newspack-blocks and newspack-manager). @wordpress/data keeps a single
271
+ * registry on `wp.data`, so the second call is a no-op that logs
272
+ * `Store "newspack/wizards" is already registered.` — guard it instead.
273
+ *
274
+ * The first bundle to register wins, and it is not necessarily the newest one:
275
+ * consumers rebuild on their own schedules, so an older copy of this package can
276
+ * get there first and leave newer selectors missing. That is worth knowing about
277
+ * while developing, so keep the breadcrumb outside production builds.
278
+ */
264
279
  var _default = exports["default"] = function _default() {
265
- return (0, _data.register)(store);
280
+ if ((0, _data.select)(WIZARD_STORE_NAMESPACE)) {
281
+ if ('production' !== process.env.NODE_ENV) {
282
+ // eslint-disable-next-line no-console
283
+ console.warn("Wizard store: \"".concat(WIZARD_STORE_NAMESPACE, "\" is already registered, so this copy of newspack-components was ignored. Two bundles of the package are on this page and the first one to load wins."));
284
+ }
285
+ return;
286
+ }
287
+ (0, _data.register)(store);
266
288
  };
@@ -0,0 +1,13 @@
1
+ @use "../../colors/colors.module" as colors;
2
+ @use "~@wordpress/base-styles/colors" as wp-colors;
3
+ @use "~@wordpress/base-styles/variables" as wp-vars;
4
+
5
+ @mixin text-muted {
6
+ /* stylelint-disable-next-line plugin-wpds/no-unknown-ds-tokens -- the plugin's token list lags the prebuilt design-tokens.css names. */
7
+ color: var( --wpds-color-foreground-content-neutral-weak, #{wp-colors.$gray-700} );
8
+ }
9
+
10
+ @mixin wpds-focus-ring {
11
+ /* stylelint-disable-next-line plugin-wpds/no-unknown-ds-tokens -- the plugin's token list lags the prebuilt design-tokens.css names. */
12
+ outline: var( --wpds-border-width-focus, var( --wp-admin-border-width-focus, #{wp-vars.$border-width-focus-fallback} ) ) solid var( --wpds-color-stroke-focus, var( --wp-admin-theme-color, #{colors.$primary-600} ) );
13
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * SCSS Variables.
3
+ *
4
+ * The steps this package needs above the @wordpress/base-styles scale. Please
5
+ * reach for a base-styles variable first, and only add here when there is no
6
+ * counterpart and you're pretty sure the value will be reused in many places.
7
+ * It's purely for UI. Don't add component-specific values, which belong in that
8
+ * component's own stylesheet.
9
+ */
10
+
11
+ $font-size-3x-large: 48px;
12
+ $font-line-height-3x-large: 1.125;
@@ -13,6 +13,7 @@ import { Draggable, ExternalLink, ToggleControl } from '@wordpress/components';
13
13
  import { useEffect, useState } from '@wordpress/element';
14
14
  import { __ } from '@wordpress/i18n';
15
15
  import { Icon, check, chevronDown, chevronUp, dragHandle } from '@wordpress/icons';
16
+ import { Badge } from '@wordpress/ui';
16
17
 
17
18
  /**
18
19
  * Internal dependencies
@@ -32,8 +33,7 @@ import classnames from 'classnames';
32
33
  */
33
34
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
34
35
  var ActionCard = function ActionCard(_ref) {
35
- var badge = _ref.badge,
36
- badgeLevel = _ref.badgeLevel,
36
+ var badges = _ref.badges,
37
37
  className = _ref.className,
38
38
  checkbox = _ref.checkbox,
39
39
  children = _ref.children,
@@ -86,6 +86,13 @@ var ActionCard = function ActionCard(_ref) {
86
86
  dragIndex = _ref.dragIndex,
87
87
  dragWrapperRef = _ref.dragWrapperRef,
88
88
  onDragCallback = _ref.onDragCallback;
89
+ // A badge with no label paints an empty pill, since the library Badge styles its
90
+ // wrapper rather than its text. Callers derive labels from data that can be absent
91
+ // (a gateway with no connection status, an unmapped placement), so drop those here
92
+ // rather than asking every caller to guard its own array.
93
+ var visibleBadges = (badges || []).filter(function (badge) {
94
+ return badge === null || badge === void 0 ? void 0 : badge.label;
95
+ });
89
96
  var _useState = useState(Boolean(isExpanded)),
90
97
  _useState2 = _slicedToArray(_useState, 2),
91
98
  expanded = _useState2[0],
@@ -133,7 +140,6 @@ var ActionCard = function ActionCard(_ref) {
133
140
  var togglePositionClass = togglePosition === 'trailing' ? 'is-toggle-trailing' : 'is-toggle-leading';
134
141
  var hasInternalLink = href && href.indexOf('http') !== 0;
135
142
  var isDisplayingSecondaryAction = secondaryActionText && onSecondaryActionClick;
136
- var badges = !Array.isArray(badge) && badge ? [badge] : badge;
137
143
  var HeadingTag = "h".concat(heading);
138
144
  var cardContent = /*#__PURE__*/_jsxs(_Fragment, {
139
145
  children: [/*#__PURE__*/_jsxs("div", {
@@ -180,10 +186,12 @@ var ActionCard = function ActionCard(_ref) {
180
186
  },
181
187
  children: title
182
188
  }), !titleLink && !expandable && title]
183
- })), (badges === null || badges === void 0 ? void 0 : badges.length) && badges.map(function (badgeText, i) {
184
- return /*#__PURE__*/_jsx("span", {
185
- className: "newspack-action-card__badge newspack-action-card__badge-level-".concat(badgeLevel),
186
- children: badgeText
189
+ })), visibleBadges.map(function (_ref2, i) {
190
+ var label = _ref2.label,
191
+ intent = _ref2.intent;
192
+ return /*#__PURE__*/_jsx(Badge, {
193
+ intent: intent !== null && intent !== void 0 ? intent : 'none',
194
+ children: label
187
195
  }, "badge-".concat(i));
188
196
  })]
189
197
  }), description && /*#__PURE__*/_jsxs("p", {
@@ -316,9 +324,9 @@ var ActionCard = function ActionCard(_ref) {
316
324
  onDragStart: handleDragStart,
317
325
  onDragEnd: handleDragEnd,
318
326
  onDragOver: handleDragOver,
319
- children: function children(_ref2) {
320
- var onDraggableStart = _ref2.onDraggableStart,
321
- onDraggableEnd = _ref2.onDraggableEnd;
327
+ children: function children(_ref3) {
328
+ var onDraggableStart = _ref3.onDraggableStart,
329
+ onDraggableEnd = _ref3.onDraggableEnd;
322
330
  return /*#__PURE__*/_jsxs(Card, {
323
331
  className: classes,
324
332
  onClick: simple && onClick,
@@ -0,0 +1,89 @@
1
+ /**
2
+ * External dependencies.
3
+ */
4
+ import { render, screen } from '@testing-library/react';
5
+
6
+ /**
7
+ * Internal dependencies.
8
+ */
9
+ import ActionCard from './index';
10
+
11
+ /**
12
+ * The library Badge styles its wrapper rather than its text, so a badge with no label
13
+ * paints a bare coloured pill. Callers build the `badges` array from data that can be
14
+ * absent — a payment gateway reports no connection status until it is enabled, a prompt
15
+ * can sit on a placement with no entry in the placement map — and an array literal is
16
+ * always non-empty, so the component has to drop those itself.
17
+ */
18
+ import { jsx as _jsx } from "react/jsx-runtime";
19
+ describe('ActionCard badges', function () {
20
+ var badgeText = function badgeText() {
21
+ return screen.queryAllByText(function (_, node) {
22
+ return /__badge/.test((node === null || node === void 0 ? void 0 : node.className) || '');
23
+ });
24
+ };
25
+ it('renders a badge that has a label', function () {
26
+ render(/*#__PURE__*/_jsx(ActionCard, {
27
+ title: "Stripe",
28
+ badges: [{
29
+ label: 'Connected',
30
+ intent: 'stable'
31
+ }]
32
+ }));
33
+ expect(screen.getByText('Connected')).toBeInTheDocument();
34
+ });
35
+ it('renders no badge when the label is null', function () {
36
+ var _render = render(/*#__PURE__*/_jsx(ActionCard, {
37
+ title: "Stripe",
38
+ badges: [{
39
+ label: null,
40
+ intent: 'informational'
41
+ }]
42
+ })),
43
+ container = _render.container;
44
+ expect(container.querySelectorAll('[class*="__badge"]')).toHaveLength(0);
45
+ });
46
+ it('renders no badge when the label is undefined or empty', function () {
47
+ var _render2 = render(/*#__PURE__*/_jsx(ActionCard, {
48
+ title: "Stripe",
49
+ badges: [{
50
+ label: undefined
51
+ }, {
52
+ label: ''
53
+ }]
54
+ })),
55
+ container = _render2.container;
56
+ expect(container.querySelectorAll('[class*="__badge"]')).toHaveLength(0);
57
+ });
58
+ it('keeps the labelled badges and drops only the empty ones', function () {
59
+ render(/*#__PURE__*/_jsx(ActionCard, {
60
+ title: "Plans",
61
+ badges: [{
62
+ label: 'Premium'
63
+ }, {
64
+ label: null
65
+ }, {
66
+ label: 'Archived',
67
+ intent: 'draft'
68
+ }]
69
+ }));
70
+ expect(screen.getByText('Premium')).toBeInTheDocument();
71
+ expect(screen.getByText('Archived')).toBeInTheDocument();
72
+ expect(badgeText()).toHaveLength(2);
73
+ });
74
+ it('renders nothing for an absent or empty badges prop', function () {
75
+ var _render3 = render(/*#__PURE__*/_jsx(ActionCard, {
76
+ title: "Stripe"
77
+ })),
78
+ withoutProp = _render3.container;
79
+ expect(withoutProp.querySelectorAll('[class*="__badge"]')).toHaveLength(0);
80
+ var _render4 = render(/*#__PURE__*/_jsx(ActionCard, {
81
+ title: "Stripe",
82
+ badges: []
83
+ })),
84
+ withEmptyArray = _render4.container;
85
+ expect(withEmptyArray.querySelectorAll('[class*="__badge"]')).toHaveLength(0);
86
+ // An empty array used to fall through as a literal `0` in the heading.
87
+ expect(withEmptyArray.textContent).not.toContain('0');
88
+ });
89
+ });
@@ -4,6 +4,7 @@
4
4
 
5
5
  @use "sass:color";
6
6
  @use "~@wordpress/base-styles/colors" as wp-colors;
7
+ @use "~@wordpress/base-styles/variables" as wp-vars;
7
8
 
8
9
  .newspack-card.newspack-action-card {
9
10
  padding: 0;
@@ -196,11 +197,7 @@
196
197
  align-items: center;
197
198
  display: flex;
198
199
  flex-wrap: wrap;
199
- margin-right: -8px;
200
-
201
- .newspack-action-card__title {
202
- margin-right: 8px;
203
- }
200
+ gap: wp-vars.$grid-unit-10;
204
201
 
205
202
  a {
206
203
  color: inherit;
@@ -372,41 +369,6 @@
372
369
  margin: 0;
373
370
  }
374
371
 
375
- /* Badge */
376
- .newspack-action-card__badge {
377
- background: wp-colors.$gray-100;
378
- border-radius: 2px;
379
- color: wp-colors.$gray-900;
380
- display: block;
381
- flex: 0 0 auto;
382
- font-size: 12px;
383
- font-weight: 400;
384
- line-height: 1.333;
385
- margin: 0 8px 0 0;
386
- padding: 2px 4px;
387
-
388
- &.newspack-action-card__badge-level-warning {
389
- background-color: color-mix(in srgb, #fff 90%, wp-colors.$alert-yellow);
390
- color: color-mix(in srgb, #000 50%, wp-colors.$alert-yellow);
391
- }
392
- &.newspack-action-card__badge-level-error {
393
- background-color: color-mix(in srgb, #fff 90%, wp-colors.$alert-red);
394
- color: color-mix(in srgb, #000 50%, wp-colors.$alert-red);
395
- }
396
- &.newspack-action-card__badge-level-success {
397
- background-color: color-mix(in srgb, #fff 90%, wp-colors.$alert-green);
398
- color: color-mix(in srgb, #000 50%, wp-colors.$alert-green);
399
- }
400
- &.newspack-action-card__badge-level-brand {
401
- background-color: color-mix(in srgb, #fff 90%, var(--wp-admin-theme-color));
402
- color: color-mix(in srgb, #000 50%, var(--wp-admin-theme-color));
403
- }
404
-
405
- + .newspack-action-card__badge {
406
- margin-left: -4px;
407
- }
408
- }
409
-
410
372
  /* Description Card */
411
373
  &.newspack-description-card {
412
374
  font-style: italic;
@@ -15,7 +15,7 @@ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try {
15
15
  * WordPress dependencies.
16
16
  */
17
17
  import { Button as BaseComponent } from '@wordpress/components';
18
- import { useEffect, useState } from '@wordpress/element';
18
+ import { forwardRef, useEffect, useState } from '@wordpress/element';
19
19
 
20
20
  /**
21
21
  * Internal dependencies
@@ -29,7 +29,7 @@ var useHistory = Router.useHistory;
29
29
  var isJavascriptHref = function isJavascriptHref(href) {
30
30
  return 'string' === typeof href && href.replace(/[\u0000-\u0020]/g, '').toLowerCase().startsWith('javascript:');
31
31
  };
32
- var Button = function Button(_ref) {
32
+ var Button = forwardRef(function (_ref, ref) {
33
33
  var href = _ref.href,
34
34
  _ref$loading = _ref.loading,
35
35
  loading = _ref$loading === void 0 ? undefined : _ref$loading,
@@ -84,9 +84,14 @@ var Button = function Button(_ref) {
84
84
  if (isAwaitingOnClick) {
85
85
  otherProps.disabled = true;
86
86
  }
87
+ // `loading` is this component's own prop name; @wordpress/components' Button
88
+ // expresses the same state as `isBusy`. Forwarding `loading` verbatim would
89
+ // land it on the DOM node, which React rejects as a non-boolean attribute.
87
90
  // @ts-expect-error - @wordpress/components' Button can only have either href or onClick, not both.
88
91
  return /*#__PURE__*/_jsx(BaseComponent, _objectSpread({
89
- loading: loading ? true : undefined
92
+ ref: ref,
93
+ isBusy: loading ? true : undefined
90
94
  }, otherProps));
91
- };
95
+ });
96
+ Button.displayName = 'Button';
92
97
  export default Button;
@@ -7,6 +7,11 @@ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try {
7
7
  import { act, render, screen } from '@testing-library/react';
8
8
  import { MemoryRouter, useHistory } from 'react-router-dom';
9
9
 
10
+ /**
11
+ * WordPress dependencies.
12
+ */
13
+ import { createRef } from '@wordpress/element';
14
+
10
15
  /**
11
16
  * Internal dependencies.
12
17
  */
@@ -44,6 +49,18 @@ var clickButton = /*#__PURE__*/function () {
44
49
  return _ref2.apply(this, arguments);
45
50
  };
46
51
  }();
52
+
53
+ // React formats its warnings with `%s` placeholders and passes the values as
54
+ // further arguments, so assert against the whole call rather than one argument.
55
+ var messagesFrom = function messagesFrom(spy) {
56
+ return spy.mock.calls.flat().join(' ');
57
+ };
58
+
59
+ // A failing assertion skips any `mockRestore()` left after it, which would leave
60
+ // the console swallowed for every later test in the file.
61
+ afterEach(function () {
62
+ jest.restoreAllMocks();
63
+ });
47
64
  describe('Button href with onClick', function () {
48
65
  it('awaits the onClick, then pushes the route', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
49
66
  var historyRef, onClick;
@@ -234,7 +251,6 @@ describe('Button href with onClick outside a router', function () {
234
251
  })));
235
252
  case 1:
236
253
  expect(warn).toHaveBeenCalledWith(expect.stringContaining('javascript:'));
237
- warn.mockRestore();
238
254
  case 2:
239
255
  return _context10.a(2);
240
256
  }
@@ -246,22 +262,21 @@ describe('Button with a javascript: href alone', function () {
246
262
  return screen.getByText('Save').closest('a');
247
263
  };
248
264
  it('renders no link', function () {
249
- var warn = jest.spyOn(console, 'warn').mockImplementation(function () {});
265
+ // Silenced only; the assertion below is about the markup, not the warning.
266
+ jest.spyOn(console, 'warn').mockImplementation(function () {});
250
267
  render(/*#__PURE__*/_jsx(Button, {
251
268
  href: "JavaScript:alert(1)",
252
269
  children: "Save"
253
270
  }));
254
271
  expect(link()).toBeNull();
255
- warn.mockRestore();
256
272
  });
257
273
  it('sees through interleaved control characters', function () {
258
- var warn = jest.spyOn(console, 'warn').mockImplementation(function () {});
274
+ jest.spyOn(console, 'warn').mockImplementation(function () {});
259
275
  render(/*#__PURE__*/_jsx(Button, {
260
276
  href: 'java\nscript:alert(1)',
261
277
  children: "Save"
262
278
  }));
263
279
  expect(link()).toBeNull();
264
- warn.mockRestore();
265
280
  });
266
281
  it('leaves an ordinary href alone', function () {
267
282
  render(/*#__PURE__*/_jsx(Button, {
@@ -270,4 +285,47 @@ describe('Button with a javascript: href alone', function () {
270
285
  }));
271
286
  expect(link()).toHaveAttribute('href', '/wp-admin/admin.php?page=next');
272
287
  });
288
+ });
289
+ describe('Button loading prop', function () {
290
+ var button = function button() {
291
+ return screen.getByRole('button', {
292
+ name: 'Save'
293
+ });
294
+ };
295
+ it('renders the core busy state without putting `loading` on the DOM node', function () {
296
+ var error = jest.spyOn(console, 'error').mockImplementation(function () {});
297
+ var _render = render(/*#__PURE__*/_jsx(Button, {
298
+ children: "Save"
299
+ })),
300
+ rerender = _render.rerender;
301
+ expect(button()).not.toHaveClass('is-busy');
302
+ rerender(/*#__PURE__*/_jsx(Button, {
303
+ loading: true,
304
+ children: "Save"
305
+ }));
306
+ expect(button()).toHaveClass('is-busy');
307
+ // React drops an unknown boolean-valued attribute instead of writing it, so
308
+ // the warning rather than the absent attribute is what a revert trips. It is
309
+ // also deduped per property name for the life of the module registry, which
310
+ // is why this names the message instead of asserting no errors at all.
311
+ expect(messagesFrom(error)).not.toContain('non-boolean attribute');
312
+ });
313
+ });
314
+
315
+ // core's Button wraps itself in a Tooltip when it is given a `label`, and the
316
+ // Tooltip needs a ref on its child. Two call sites do that with this Button:
317
+ // the experimental-tools back button and the audience segment-group heading.
318
+ describe('Button ref', function () {
319
+ it('forwards the ref to the rendered button', function () {
320
+ var error = jest.spyOn(console, 'error').mockImplementation(function () {});
321
+ var ref = createRef();
322
+ render(/*#__PURE__*/_jsx(Button, {
323
+ ref: ref,
324
+ children: "Save"
325
+ }));
326
+ expect(ref.current).toBe(screen.getByRole('button', {
327
+ name: 'Save'
328
+ }));
329
+ expect(messagesFrom(error)).not.toContain('Function components cannot be given refs');
330
+ });
273
331
  });
@@ -137,7 +137,6 @@ var CoreCard = function CoreCard(_ref) {
137
137
  }), (actions === null || actions === void 0 ? void 0 : actions.length) > 0 && actionType === 'toggle' && /*#__PURE__*/_jsx(ToggleControl, {
138
138
  className: "newspack-card--core__action",
139
139
  label: otherProps.title,
140
- hideLabelFromVision: true,
141
140
  checked: isActive,
142
141
  onChange: onToggle
143
142
  }), header && /*#__PURE__*/_jsx("div", {
@@ -151,7 +150,6 @@ var CoreCard = function CoreCard(_ref) {
151
150
  }), !(actions !== null && actions !== void 0 && actions.length) > 0 && actionType === 'toggle' && /*#__PURE__*/_jsx(ToggleControl, {
152
151
  className: "newspack-card--core__action",
153
152
  label: otherProps.title,
154
- hideLabelFromVision: true,
155
153
  checked: isActive,
156
154
  onChange: onToggle
157
155
  }), (actions === null || actions === void 0 ? void 0 : actions.length) > 0 && /*#__PURE__*/_jsx(DropdownMenu, {
@@ -4,7 +4,6 @@
4
4
 
5
5
  @use "~@wordpress/base-styles/colors" as wp-colors;
6
6
  @use "~@wordpress/base-styles/variables" as wp-vars;
7
- @use "../../../colors/colors.module" as colors;
8
7
 
9
8
  .newspack-card--core,
10
9
  .newspack-wizard .newspack-card--core {
@@ -45,7 +44,13 @@
45
44
  }
46
45
  .newspack-card--core {
47
46
  &__header-content {
48
- * {
47
+ h1,
48
+ h2,
49
+ h3,
50
+ h4,
51
+ h5,
52
+ h6,
53
+ p {
49
54
  line-height: wp-vars.$font-line-height-small;
50
55
  }
51
56
  }
@@ -210,9 +215,6 @@
210
215
  text-decoration: underline;
211
216
  }
212
217
  }
213
- .newspack-badge {
214
- font-weight: 400;
215
- }
216
218
  }
217
219
  }
218
220
  &__is-selectable {