newspack-components 4.2.0 → 4.4.0-epic-editor-refactor.1

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 (315) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/DEVELOPMENT.md +868 -0
  3. package/copy-styles.js +3 -2
  4. package/dist/cjs/accordion/index.js +17 -12
  5. package/dist/cjs/action-card/index.js +186 -140
  6. package/dist/cjs/action-card/style.scss +25 -2
  7. package/dist/cjs/autocomplete-tokenfield/index.js +254 -234
  8. package/dist/cjs/autocomplete-with-latest-posts/index.js +351 -0
  9. package/dist/cjs/autocomplete-with-latest-posts/style.scss +150 -0
  10. package/dist/cjs/autocomplete-with-suggestions/index.js +229 -126
  11. package/dist/cjs/badge/index.js +32 -0
  12. package/dist/cjs/badge/style.scss +36 -0
  13. package/dist/cjs/box-contrast/index.js +19 -15
  14. package/dist/cjs/button/index.js +41 -24
  15. package/dist/cjs/button-props/button-props.js +5 -5
  16. package/dist/cjs/button-props/index.js +2 -2
  17. package/dist/cjs/card/core-card.js +199 -0
  18. package/dist/cjs/card/index.js +75 -35
  19. package/dist/cjs/card/style-core.scss +295 -0
  20. package/dist/cjs/card/style.scss +4 -4
  21. package/dist/cjs/card-feature/index.js +141 -0
  22. package/dist/cjs/card-feature/style.scss +75 -0
  23. package/dist/cjs/card-form/index.js +144 -0
  24. package/dist/cjs/card-form/style.scss +20 -0
  25. package/dist/cjs/card-settings-group/index.js +69 -0
  26. package/dist/cjs/card-settings-group/style.scss +33 -0
  27. package/dist/cjs/card-sortable-list/index.js +426 -0
  28. package/dist/cjs/card-sortable-list/style.scss +48 -0
  29. package/dist/cjs/category-autocomplete/index.js +175 -155
  30. package/dist/cjs/color-picker/index.js +41 -23
  31. package/dist/cjs/color-picker/index.test.js +82 -0
  32. package/dist/cjs/color-picker/style.scss +11 -13
  33. package/dist/cjs/confirm-dialog/index.js +123 -0
  34. package/dist/cjs/consts.js +1 -1
  35. package/dist/cjs/custom-select-control/index.js +39 -28
  36. package/dist/cjs/dataviews/index.js +38 -0
  37. package/dist/cjs/dataviews/style.scss +9 -0
  38. package/dist/cjs/divider/index.js +47 -0
  39. package/dist/cjs/divider/style.scss +51 -0
  40. package/dist/cjs/footer/index.js +36 -30
  41. package/dist/cjs/form-token-field/index.js +51 -40
  42. package/dist/cjs/form-token-field/style.scss +0 -5
  43. package/dist/cjs/global-notices/index.js +5 -5
  44. package/dist/cjs/grid/index.js +25 -18
  45. package/dist/cjs/grid/style.scss +67 -8
  46. package/dist/cjs/handoff/index.js +204 -156
  47. package/dist/cjs/handoff-message/index.js +12 -7
  48. package/dist/cjs/hooks/index.js +10 -8
  49. package/dist/cjs/hooks/use-confirm-dialog.js +79 -0
  50. package/dist/cjs/hooks/use-unsaved-changes-dialog.js +144 -0
  51. package/dist/cjs/hooks/useObjectState.js +21 -12
  52. package/dist/cjs/hooks/useObjectState.test.js +55 -33
  53. package/dist/cjs/hooks/useOnClickOutside.js +6 -6
  54. package/dist/cjs/hooks/usePrompt.js +10 -13
  55. package/dist/cjs/image-upload/index.js +114 -123
  56. package/dist/cjs/image-upload/index.test.js +11 -13
  57. package/dist/cjs/image-upload/style.scss +12 -40
  58. package/dist/cjs/index.js +166 -92
  59. package/dist/cjs/info-button/index.js +43 -32
  60. package/dist/cjs/integration-icons/active-campaign.js +22 -0
  61. package/dist/cjs/integration-icons/constant-contact.js +28 -0
  62. package/dist/cjs/integration-icons/fundraise-up.js +25 -0
  63. package/dist/cjs/integration-icons/index.js +48 -0
  64. package/dist/cjs/integration-icons/mailchimp.js +19 -0
  65. package/dist/cjs/integration-icons/salesforce.js +17 -0
  66. package/dist/cjs/integration-icons/wisepops.js +20 -0
  67. package/dist/cjs/modal/index.js +29 -19
  68. package/dist/cjs/modal/style.scss +47 -13
  69. package/dist/cjs/newspack-icon/index.js +45 -38
  70. package/dist/cjs/newspack-icon/style.scss +5 -3
  71. package/dist/cjs/notice/index.js +64 -55
  72. package/dist/cjs/plugin-installer/index.js +259 -253
  73. package/dist/cjs/plugin-settings/SettingsSection.js +66 -60
  74. package/dist/cjs/plugin-settings/index.js +217 -200
  75. package/dist/cjs/plugin-toggle/index.js +192 -199
  76. package/dist/cjs/popover/index.js +41 -28
  77. package/dist/cjs/position-control/index.js +24 -23
  78. package/dist/cjs/progress-bar/index.js +71 -59
  79. package/dist/cjs/progress-bar/index.test.js +62 -68
  80. package/dist/cjs/proxied-imports/router.js +3 -3
  81. package/dist/cjs/radio-control/index.js +40 -27
  82. package/dist/cjs/section-header/index.js +143 -39
  83. package/dist/cjs/section-header/style.scss +129 -4
  84. package/dist/cjs/select-control/ButtonGroupControl.js +26 -21
  85. package/dist/cjs/select-control/GroupedSelectControl.js +41 -35
  86. package/dist/cjs/select-control/index.js +52 -40
  87. package/dist/cjs/settings/MinMaxSetting.js +30 -20
  88. package/dist/cjs/settings/SettingsCard.js +20 -17
  89. package/dist/cjs/settings/SettingsSection.js +22 -21
  90. package/dist/cjs/settings/index.js +5 -5
  91. package/dist/cjs/sortable-newsletter-list-control/index.js +78 -57
  92. package/dist/cjs/steps-list/index.js +44 -34
  93. package/dist/cjs/steps-list-item/index.js +47 -39
  94. package/dist/cjs/style-card/index.js +70 -63
  95. package/dist/cjs/style.scss +2 -0
  96. package/dist/cjs/tabbed-navigation/index.js +38 -36
  97. package/dist/cjs/text-control/index.js +27 -25
  98. package/dist/cjs/utils/color.js +4 -4
  99. package/dist/cjs/utils/editor-toolbar-back-button.js +61 -0
  100. package/dist/cjs/utils/index.js +31 -19
  101. package/dist/cjs/utils/style.scss +8 -0
  102. package/dist/cjs/waiting/index.js +48 -35
  103. package/dist/cjs/waiting/style.scss +4 -0
  104. package/dist/cjs/web-preview/index.js +219 -154
  105. package/dist/cjs/web-preview/style.scss +20 -53
  106. package/dist/cjs/with-wizard/index.js +362 -364
  107. package/dist/cjs/with-wizard/style.scss +28 -60
  108. package/dist/cjs/with-wizard-screen/index.js +54 -58
  109. package/dist/cjs/with-wizard-screen/style.scss +77 -10
  110. package/dist/cjs/wizard/components/WizardError.js +20 -18
  111. package/dist/cjs/wizard/components/WizardSnackbar.js +73 -0
  112. package/dist/cjs/wizard/components/style.scss +48 -0
  113. package/dist/cjs/wizard/index.js +207 -64
  114. package/dist/cjs/wizard/store/index.js +191 -97
  115. package/dist/cjs/wizard/store/utils.js +13 -8
  116. package/dist/esm/accordion/index.js +14 -9
  117. package/dist/esm/action-card/index.js +178 -124
  118. package/dist/esm/action-card/style.scss +25 -2
  119. package/dist/esm/autocomplete-tokenfield/index.js +248 -222
  120. package/dist/esm/autocomplete-with-latest-posts/index.js +347 -0
  121. package/dist/esm/autocomplete-with-latest-posts/style.scss +150 -0
  122. package/dist/esm/autocomplete-with-suggestions/index.js +226 -119
  123. package/dist/esm/badge/index.js +24 -0
  124. package/dist/esm/badge/style.scss +36 -0
  125. package/dist/esm/box-contrast/index.js +15 -11
  126. package/dist/esm/button/index.js +39 -19
  127. package/dist/esm/button-props/button-props.js +1 -1
  128. package/dist/esm/card/core-card.js +195 -0
  129. package/dist/esm/card/index.js +70 -22
  130. package/dist/esm/card/style-core.scss +295 -0
  131. package/dist/esm/card/style.scss +4 -4
  132. package/dist/esm/card-feature/index.js +131 -0
  133. package/dist/esm/card-feature/style.scss +75 -0
  134. package/dist/esm/card-form/index.js +134 -0
  135. package/dist/esm/card-form/style.scss +20 -0
  136. package/dist/esm/card-settings-group/index.js +61 -0
  137. package/dist/esm/card-settings-group/style.scss +33 -0
  138. package/dist/esm/card-sortable-list/index.js +425 -0
  139. package/dist/esm/card-sortable-list/style.scss +48 -0
  140. package/dist/esm/category-autocomplete/index.js +168 -140
  141. package/dist/esm/color-picker/index.js +39 -21
  142. package/dist/esm/color-picker/index.test.js +78 -0
  143. package/dist/esm/color-picker/style.scss +11 -13
  144. package/dist/esm/confirm-dialog/index.js +116 -0
  145. package/dist/esm/consts.js +1 -1
  146. package/dist/esm/custom-select-control/index.js +34 -15
  147. package/dist/esm/dataviews/index.js +34 -0
  148. package/dist/esm/dataviews/style.scss +9 -0
  149. package/dist/esm/divider/index.js +42 -0
  150. package/dist/esm/divider/style.scss +51 -0
  151. package/dist/esm/footer/index.js +34 -28
  152. package/dist/esm/form-token-field/index.js +46 -27
  153. package/dist/esm/form-token-field/style.scss +0 -5
  154. package/dist/esm/global-notices/index.js +3 -3
  155. package/dist/esm/grid/index.js +23 -13
  156. package/dist/esm/grid/style.scss +67 -8
  157. package/dist/esm/handoff/index.js +199 -143
  158. package/dist/esm/handoff-message/index.js +10 -6
  159. package/dist/esm/hooks/index.js +8 -6
  160. package/dist/esm/hooks/use-confirm-dialog.js +73 -0
  161. package/dist/esm/hooks/use-unsaved-changes-dialog.js +136 -0
  162. package/dist/esm/hooks/useObjectState.js +19 -9
  163. package/dist/esm/hooks/useObjectState.test.js +54 -32
  164. package/dist/esm/hooks/useOnClickOutside.js +4 -4
  165. package/dist/esm/hooks/usePrompt.js +9 -11
  166. package/dist/esm/image-upload/index.js +110 -111
  167. package/dist/esm/image-upload/index.test.js +11 -13
  168. package/dist/esm/image-upload/style.scss +12 -40
  169. package/dist/esm/index.js +13 -1
  170. package/dist/esm/info-button/index.js +38 -19
  171. package/dist/esm/integration-icons/active-campaign.js +16 -0
  172. package/dist/esm/integration-icons/constant-contact.js +22 -0
  173. package/dist/esm/integration-icons/fundraise-up.js +19 -0
  174. package/dist/esm/integration-icons/index.js +6 -0
  175. package/dist/esm/integration-icons/mailchimp.js +13 -0
  176. package/dist/esm/integration-icons/salesforce.js +11 -0
  177. package/dist/esm/integration-icons/wisepops.js +14 -0
  178. package/dist/esm/modal/index.js +27 -13
  179. package/dist/esm/modal/style.scss +47 -13
  180. package/dist/esm/newspack-icon/index.js +40 -25
  181. package/dist/esm/newspack-icon/style.scss +5 -3
  182. package/dist/esm/notice/index.js +59 -42
  183. package/dist/esm/plugin-installer/index.js +255 -243
  184. package/dist/esm/plugin-settings/SettingsSection.js +61 -50
  185. package/dist/esm/plugin-settings/index.js +212 -189
  186. package/dist/esm/plugin-toggle/index.js +187 -190
  187. package/dist/esm/popover/index.js +35 -16
  188. package/dist/esm/position-control/index.js +22 -18
  189. package/dist/esm/progress-bar/index.js +66 -49
  190. package/dist/esm/progress-bar/index.test.js +61 -67
  191. package/dist/esm/radio-control/index.js +34 -15
  192. package/dist/esm/section-header/index.js +140 -38
  193. package/dist/esm/section-header/style.scss +129 -4
  194. package/dist/esm/select-control/ButtonGroupControl.js +23 -18
  195. package/dist/esm/select-control/GroupedSelectControl.js +38 -30
  196. package/dist/esm/select-control/index.js +47 -27
  197. package/dist/esm/settings/MinMaxSetting.js +27 -16
  198. package/dist/esm/settings/SettingsCard.js +18 -13
  199. package/dist/esm/settings/SettingsSection.js +20 -19
  200. package/dist/esm/settings/index.js +3 -3
  201. package/dist/esm/sortable-newsletter-list-control/index.js +74 -53
  202. package/dist/esm/steps-list/index.js +39 -21
  203. package/dist/esm/steps-list-item/index.js +42 -26
  204. package/dist/esm/style-card/index.js +65 -50
  205. package/dist/esm/style.scss +2 -0
  206. package/dist/esm/tabbed-navigation/index.js +35 -33
  207. package/dist/esm/text-control/index.js +25 -19
  208. package/dist/esm/utils/color.js +4 -4
  209. package/dist/esm/utils/editor-toolbar-back-button.js +53 -0
  210. package/dist/esm/utils/index.js +29 -16
  211. package/dist/esm/utils/style.scss +8 -0
  212. package/dist/esm/waiting/index.js +43 -22
  213. package/dist/esm/waiting/style.scss +4 -0
  214. package/dist/esm/web-preview/index.js +218 -147
  215. package/dist/esm/web-preview/style.scss +20 -53
  216. package/dist/esm/with-wizard/index.js +360 -358
  217. package/dist/esm/with-wizard/style.scss +28 -60
  218. package/dist/esm/with-wizard-screen/index.js +48 -46
  219. package/dist/esm/with-wizard-screen/style.scss +77 -10
  220. package/dist/esm/wizard/components/WizardError.js +18 -16
  221. package/dist/esm/wizard/components/WizardSnackbar.js +70 -0
  222. package/dist/esm/wizard/components/style.scss +48 -0
  223. package/dist/esm/wizard/index.js +207 -58
  224. package/dist/esm/wizard/store/index.js +189 -90
  225. package/dist/esm/wizard/store/utils.js +13 -6
  226. package/package.json +30 -17
  227. package/release.config.js +1 -0
  228. package/shared/author-context.js +26 -0
  229. package/shared/hooks/use-coauthors.js +388 -0
  230. package/shared/hooks/use-coauthors.test.js +850 -0
  231. package/shared/hooks/use-custom-byline.js +47 -0
  232. package/shared/hooks/use-custom-byline.test.js +133 -0
  233. package/shared/scss/_mixins.scss +54 -0
  234. package/src/accordion/index.js +8 -7
  235. package/src/action-card/action-card.d.ts +7 -3
  236. package/src/action-card/index.js +39 -12
  237. package/src/action-card/style.scss +25 -2
  238. package/src/autocomplete-tokenfield/index.js +2 -2
  239. package/src/autocomplete-with-latest-posts/index.js +290 -0
  240. package/src/autocomplete-with-latest-posts/style.scss +150 -0
  241. package/src/badge/index.tsx +26 -0
  242. package/src/badge/style.scss +36 -0
  243. package/src/button/index.tsx +3 -2
  244. package/src/card/core-card.js +224 -0
  245. package/src/card/index.js +40 -1
  246. package/src/card/style-core.scss +295 -0
  247. package/src/card/style.scss +4 -4
  248. package/src/card-feature/README.md +188 -0
  249. package/src/card-feature/index.tsx +186 -0
  250. package/src/card-feature/style.scss +75 -0
  251. package/src/card-form/README.md +113 -0
  252. package/src/card-form/index.tsx +128 -0
  253. package/src/card-form/style.scss +20 -0
  254. package/src/card-settings-group/README.md +43 -0
  255. package/src/card-settings-group/index.tsx +78 -0
  256. package/src/card-settings-group/style.scss +33 -0
  257. package/src/card-sortable-list/README.md +51 -0
  258. package/src/card-sortable-list/index.tsx +435 -0
  259. package/src/card-sortable-list/style.scss +48 -0
  260. package/src/color-picker/index.js +15 -8
  261. package/src/color-picker/index.test.js +52 -0
  262. package/src/color-picker/style.scss +11 -13
  263. package/src/confirm-dialog/README.md +128 -0
  264. package/src/confirm-dialog/index.tsx +132 -0
  265. package/src/dataviews/index.tsx +34 -0
  266. package/src/dataviews/style.scss +9 -0
  267. package/src/divider/README.md +25 -0
  268. package/src/divider/index.js +31 -0
  269. package/src/divider/style.scss +51 -0
  270. package/src/form-token-field/style.scss +0 -5
  271. package/src/grid/index.tsx +2 -1
  272. package/src/grid/style.scss +67 -8
  273. package/src/handoff/README.md +93 -0
  274. package/src/handoff/index.js +46 -8
  275. package/src/hooks/index.ts +2 -1
  276. package/src/hooks/use-confirm-dialog.tsx +80 -0
  277. package/src/hooks/use-unsaved-changes-dialog.tsx +140 -0
  278. package/src/image-upload/index.js +10 -15
  279. package/src/image-upload/style.scss +12 -40
  280. package/src/index.js +13 -1
  281. package/src/integration-icons/active-campaign.js +14 -0
  282. package/src/integration-icons/constant-contact.js +22 -0
  283. package/src/integration-icons/fundraise-up.js +18 -0
  284. package/src/integration-icons/index.js +6 -0
  285. package/src/integration-icons/mailchimp.js +10 -0
  286. package/src/integration-icons/salesforce.js +10 -0
  287. package/src/integration-icons/wisepops.js +14 -0
  288. package/src/modal/index.js +12 -3
  289. package/src/modal/style.scss +47 -13
  290. package/src/newspack-icon/style.scss +5 -3
  291. package/src/plugin-installer/index.js +30 -19
  292. package/src/section-header/index.js +105 -14
  293. package/src/section-header/style.scss +129 -4
  294. package/src/select-control/index.js +4 -0
  295. package/src/style.scss +2 -0
  296. package/src/utils/editor-toolbar-back-button.tsx +48 -0
  297. package/src/utils/index.js +6 -0
  298. package/src/utils/style.scss +8 -0
  299. package/src/waiting/index.js +2 -1
  300. package/src/waiting/style.scss +4 -0
  301. package/src/web-preview/index.js +90 -35
  302. package/src/web-preview/style.scss +20 -53
  303. package/src/with-wizard/index.js +1 -1
  304. package/src/with-wizard/style.scss +28 -60
  305. package/src/with-wizard-screen/style.scss +77 -10
  306. package/src/wizard/components/WizardSnackbar.js +58 -0
  307. package/src/wizard/components/style.scss +48 -0
  308. package/src/wizard/index.js +152 -21
  309. package/src/wizard/store/index.js +28 -2
  310. package/dist/cjs/button-card/index.js +0 -72
  311. package/dist/cjs/button-card/style.scss +0 -180
  312. package/dist/esm/button-card/index.js +0 -64
  313. package/dist/esm/button-card/style.scss +0 -180
  314. package/src/button-card/index.js +0 -52
  315. package/src/button-card/style.scss +0 -180
@@ -0,0 +1,347 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
+ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
6
+ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
7
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
8
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9
+ /**
10
+ * External dependencies
11
+ */
12
+ import debounce from 'lodash/debounce';
13
+
14
+ /**
15
+ * WordPress dependencies
16
+ */
17
+ import apiFetch from '@wordpress/api-fetch';
18
+ import { Button, CheckboxControl, FormTokenField, Spinner } from '@wordpress/components';
19
+ import { decodeEntities } from '@wordpress/html-entities';
20
+ import { useEffect, useState } from '@wordpress/element';
21
+ import { __ } from '@wordpress/i18n';
22
+ import { addQueryArgs } from '@wordpress/url';
23
+ import './style.scss';
24
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
25
+ var AutocompleteWithLatestPosts = function AutocompleteWithLatestPosts(_ref) {
26
+ var _ref$fetchSuggestions = _ref.fetchSuggestions,
27
+ fetchSuggestions = _ref$fetchSuggestions === void 0 ? false : _ref$fetchSuggestions,
28
+ _ref$help = _ref.help,
29
+ help = _ref$help === void 0 ? __('Begin typing search term, click autocomplete result to select.', 'newspack-plugin') : _ref$help,
30
+ _ref$hideHelp = _ref.hideHelp,
31
+ hideHelp = _ref$hideHelp === void 0 ? true : _ref$hideHelp,
32
+ _ref$hideFormTokenHel = _ref.hideFormTokenHelp,
33
+ hideFormTokenHelp = _ref$hideFormTokenHel === void 0 ? true : _ref$hideFormTokenHel,
34
+ _ref$label = _ref.label,
35
+ label = _ref$label === void 0 ? __('Search', 'newspack-plugin') : _ref$label,
36
+ _ref$maxItemsToSugges = _ref.maxItemsToSuggest,
37
+ maxItemsToSuggest = _ref$maxItemsToSugges === void 0 ? 0 : _ref$maxItemsToSugges,
38
+ _ref$multiSelect = _ref.multiSelect,
39
+ multiSelect = _ref$multiSelect === void 0 ? false : _ref$multiSelect,
40
+ _ref$onChange = _ref.onChange,
41
+ onChange = _ref$onChange === void 0 ? false : _ref$onChange,
42
+ _ref$selectedItems = _ref.selectedItems,
43
+ selectedItems = _ref$selectedItems === void 0 ? [] : _ref$selectedItems,
44
+ _ref$suggestionsToFet = _ref.suggestionsToFetch,
45
+ suggestionsToFetch = _ref$suggestionsToFet === void 0 ? 20 : _ref$suggestionsToFet;
46
+ var _useState = useState(true),
47
+ _useState2 = _slicedToArray(_useState, 2),
48
+ isLoading = _useState2[0],
49
+ setIsLoading = _useState2[1];
50
+ var _useState3 = useState(false),
51
+ _useState4 = _slicedToArray(_useState3, 2),
52
+ isLoadingMore = _useState4[0],
53
+ setIsLoadingMore = _useState4[1];
54
+ var _useState5 = useState([]),
55
+ _useState6 = _slicedToArray(_useState5, 2),
56
+ suggestions = _useState6[0],
57
+ setSuggestions = _useState6[1];
58
+ var _useState7 = useState(0),
59
+ _useState8 = _slicedToArray(_useState7, 2),
60
+ maxSuggestions = _useState8[0],
61
+ setMaxSuggestions = _useState8[1];
62
+ var _useState9 = useState([]),
63
+ _useState0 = _slicedToArray(_useState9, 2),
64
+ searchSuggestions = _useState0[0],
65
+ setSearchSuggestions = _useState0[1];
66
+ var _useState1 = useState({}),
67
+ _useState10 = _slicedToArray(_useState1, 2),
68
+ validValues = _useState10[0],
69
+ setValidValues = _useState10[1];
70
+ var _useState11 = useState(false),
71
+ _useState12 = _slicedToArray(_useState11, 2),
72
+ isSearching = _useState12[0],
73
+ setIsSearching = _useState12[1];
74
+ // Leaving this in here so we can expand to use different post types in the future; right now it defaults to 'post'.
75
+ var postTypeToSearch = 'post';
76
+ var classNames = ['newspack-autocomplete-with-latest-posts'];
77
+ if (hideFormTokenHelp) {
78
+ classNames.push('hide-form-token-help');
79
+ }
80
+ if (hideHelp) {
81
+ classNames.push('hide-help');
82
+ }
83
+
84
+ /**
85
+ * Debounced function to update search suggestions.
86
+ */
87
+ var debouncedUpdateSuggestions = debounce(function (input) {
88
+ if (!input || input.length < 2) {
89
+ setSearchSuggestions([]);
90
+ setIsSearching(false);
91
+ return;
92
+ }
93
+ setIsSearching(true);
94
+ handleFetchSuggestions(input, 0, postTypeToSearch).then(function (_suggestions) {
95
+ setSearchSuggestions(_suggestions);
96
+ // Update valid values for token conversion
97
+ var newValidValues = _objectSpread({}, validValues);
98
+ _suggestions.forEach(function (suggestion) {
99
+ newValidValues[suggestion.value] = suggestion.label;
100
+ });
101
+ setValidValues(newValidValues);
102
+ })["finally"](function () {
103
+ return setIsSearching(false);
104
+ });
105
+ }, 500);
106
+
107
+ /**
108
+ * Fetch recent posts to show as suggestions.
109
+ */
110
+ useEffect(function () {
111
+ setIsLoading(true);
112
+ handleFetchSuggestions(null, 0, postTypeToSearch).then(function (_suggestions) {
113
+ if (0 < _suggestions.length) {
114
+ setSuggestions(_suggestions);
115
+ // Update valid values for token conversion
116
+ var newValidValues = _objectSpread({}, validValues);
117
+ _suggestions.forEach(function (suggestion) {
118
+ newValidValues[suggestion.value] = suggestion.label;
119
+ });
120
+ setValidValues(newValidValues);
121
+ }
122
+ })["finally"](function () {
123
+ return setIsLoading(false);
124
+ });
125
+ }, []);
126
+
127
+ /**
128
+ * Fetch more suggestions.
129
+ */
130
+ useEffect(function () {
131
+ if (isLoadingMore) {
132
+ handleFetchSuggestions(null, suggestions.length, postTypeToSearch).then(function (_suggestions) {
133
+ if (0 < _suggestions.length) {
134
+ setSuggestions(suggestions.concat(_suggestions));
135
+ }
136
+ })["finally"](function () {
137
+ return setIsLoadingMore(false);
138
+ });
139
+ }
140
+ }, [isLoadingMore]);
141
+
142
+ /**
143
+ * If passed a `fetchSuggestions` prop, use that, otherwise, build it based on the selected post type.
144
+ */
145
+ var handleFetchSuggestions = fetchSuggestions ? fetchSuggestions : /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
146
+ var search,
147
+ offset,
148
+ searchSlug,
149
+ postTypeSlug,
150
+ endpoint,
151
+ response,
152
+ total,
153
+ posts,
154
+ _args = arguments;
155
+ return _regenerator().w(function (_context) {
156
+ while (1) switch (_context.n) {
157
+ case 0:
158
+ search = _args.length > 0 && _args[0] !== undefined ? _args[0] : null;
159
+ offset = _args.length > 1 && _args[1] !== undefined ? _args[1] : 0;
160
+ searchSlug = _args.length > 2 && _args[2] !== undefined ? _args[2] : null;
161
+ postTypeSlug = searchSlug || postTypeToSearch;
162
+ endpoint = 'post' === postTypeSlug || 'page' === postTypeSlug ? postTypeSlug + 's' // Default post type endpoints are plural.
163
+ : postTypeSlug; // Custom post type endpoints are singular.
164
+ _context.n = 1;
165
+ return apiFetch({
166
+ parse: false,
167
+ path: addQueryArgs('/wp/v2/' + endpoint, {
168
+ search: search,
169
+ offset: offset,
170
+ per_page: suggestionsToFetch,
171
+ _fields: 'id,title'
172
+ })
173
+ });
174
+ case 1:
175
+ response = _context.v;
176
+ total = parseInt(response.headers.get('x-wp-total') || 0);
177
+ _context.n = 2;
178
+ return response.json();
179
+ case 2:
180
+ posts = _context.v;
181
+ setMaxSuggestions(total);
182
+
183
+ // Format suggestions for FormTokenField display.
184
+ return _context.a(2, posts.reduce(function (acc, post) {
185
+ acc.push({
186
+ value: parseInt(post.id),
187
+ label: decodeEntities(post === null || post === void 0 ? void 0 : post.title.rendered) || __('(no title)', 'newspack-plugin')
188
+ });
189
+ return acc;
190
+ }, []));
191
+ }
192
+ }, _callee);
193
+ }));
194
+
195
+ /**
196
+ * Get labels for token values.
197
+ */
198
+ var getLabelsForValues = function getLabelsForValues(values) {
199
+ return values.reduce(function (accumulator, value) {
200
+ if (!value) {
201
+ return accumulator;
202
+ }
203
+ if (value.label) {
204
+ return [].concat(_toConsumableArray(accumulator), [value.label]);
205
+ }
206
+ return validValues[value] ? [].concat(_toConsumableArray(accumulator), [validValues[value]]) : accumulator;
207
+ }, []);
208
+ };
209
+
210
+ /**
211
+ * Get values for token labels.
212
+ */
213
+ var getValuesForLabels = function getValuesForLabels(labels) {
214
+ // eslint-disable-next-line @typescript-eslint/no-shadow
215
+ return labels.reduce(function (acc, label) {
216
+ Object.keys(validValues).forEach(function (key) {
217
+ if (validValues[key] === label) {
218
+ var value = isNaN(parseInt(key)) ? key.toString() : parseInt(key);
219
+ acc.push({
220
+ value: value,
221
+ label: label
222
+ });
223
+ }
224
+ });
225
+ return acc;
226
+ }, []);
227
+ };
228
+
229
+ /**
230
+ * Handle FormTokenField onChange.
231
+ */
232
+ var handleTokenChange = function handleTokenChange(tokenStrings) {
233
+ var newSelections = getValuesForLabels(tokenStrings);
234
+
235
+ // If only allowing one selection, just return the one selected item.
236
+ if (!multiSelect) {
237
+ var newSelection = newSelections[newSelections.length - 1]; // Get the last selected item
238
+ if (newSelection) {
239
+ return onChange([_objectSpread(_objectSpread({}, newSelection), {}, {
240
+ postType: postTypeToSearch
241
+ })]);
242
+ }
243
+ return onChange([]);
244
+ }
245
+
246
+ // For multi-select, include currently selected post type in selection results.
247
+ onChange(newSelections.map(function (selection) {
248
+ return _objectSpread(_objectSpread({}, selection), {}, {
249
+ postType: postTypeToSearch
250
+ });
251
+ }));
252
+ };
253
+
254
+ /**
255
+ * Get tokens for FormTokenField.
256
+ */
257
+ var getTokens = function getTokens() {
258
+ return getLabelsForValues(selectedItems);
259
+ };
260
+
261
+ /**
262
+ * Render a single suggestion object that can be clicked to select it immediately.
263
+ *
264
+ * @param {Object} suggestion Suggestion object with value and label keys.
265
+ */
266
+ var renderSuggestion = function renderSuggestion(suggestion) {
267
+ if (multiSelect) {
268
+ var isSelected = !!selectedItems.find(function (_selection) {
269
+ return parseInt(_selection.value) === parseInt(suggestion.value) && _selection.label === suggestion.label;
270
+ });
271
+ return /*#__PURE__*/_jsx(CheckboxControl, {
272
+ checked: isSelected,
273
+ onChange: function onChange() {
274
+ // For multi-select, we need to toggle the selection
275
+ var currentTokens = getTokens();
276
+ var suggestionLabel = suggestion.label;
277
+ if (isSelected) {
278
+ // Remove the suggestion
279
+ var newTokens = currentTokens.filter(function (token) {
280
+ return token !== suggestionLabel;
281
+ });
282
+ handleTokenChange(newTokens);
283
+ } else {
284
+ // Add the suggestion
285
+ handleTokenChange([].concat(_toConsumableArray(currentTokens), [suggestionLabel]));
286
+ }
287
+ },
288
+ label: suggestion.label
289
+ }, suggestion.value);
290
+ }
291
+ return /*#__PURE__*/_jsx(Button, {
292
+ isLink: true,
293
+ onClick: function onClick() {
294
+ return handleTokenChange([].concat(_toConsumableArray(getTokens()), [suggestion.label]));
295
+ },
296
+ children: suggestion.label
297
+ }, suggestion.value);
298
+ };
299
+
300
+ /**
301
+ * Render a list of suggestions that can be clicked to select instead of searching by title.
302
+ */
303
+ var renderSuggestions = function renderSuggestions() {
304
+ if (0 === suggestions.length) {
305
+ return null;
306
+ }
307
+ var className = multiSelect ? 'newspack-autocomplete-with-latest-posts__search-suggestions-multiselect' : 'newspack-autocomplete-with-latest-posts__search-suggestions';
308
+ return /*#__PURE__*/_jsx(_Fragment, {
309
+ children: /*#__PURE__*/_jsxs("div", {
310
+ className: "newspack-autocomplete-with-latest-posts__search-suggestions-container",
311
+ children: [/*#__PURE__*/_jsx("p", {
312
+ className: "newspack-autocomplete-with-suggestions__label",
313
+ children: __('Latest Posts', 'newspack-plugin')
314
+ }), /*#__PURE__*/_jsxs("div", {
315
+ className: className,
316
+ children: [suggestions.map(renderSuggestion), suggestions.length < (maxItemsToSuggest || maxSuggestions) && /*#__PURE__*/_jsx(Button, {
317
+ disabled: isLoadingMore,
318
+ isSecondary: true,
319
+ onClick: function onClick() {
320
+ return setIsLoadingMore(true);
321
+ },
322
+ children: isLoadingMore ? __('Loading…', 'newspack-plugin') : __('Load more', 'newspack-plugin')
323
+ })]
324
+ })]
325
+ })
326
+ });
327
+ };
328
+ return /*#__PURE__*/_jsxs("div", {
329
+ className: classNames.join(' '),
330
+ children: [/*#__PURE__*/_jsxs("div", {
331
+ className: "newspack-autocomplete-with-latest-posts__input-container",
332
+ children: [/*#__PURE__*/_jsx(FormTokenField, {
333
+ value: getTokens(),
334
+ suggestions: searchSuggestions.map(function (suggestion) {
335
+ return suggestion.label;
336
+ }),
337
+ onChange: handleTokenChange,
338
+ onInputChange: debouncedUpdateSuggestions,
339
+ label: label,
340
+ help: !hideHelp && help,
341
+ __next40pxDefaultSize: true,
342
+ __nextHasNoMarginBottom: true
343
+ }), (isLoading || isSearching) && /*#__PURE__*/_jsx(Spinner, {})]
344
+ }), renderSuggestions()]
345
+ });
346
+ };
347
+ export default AutocompleteWithLatestPosts;
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Styles for AutocompleteWithLatestPosts component.
3
+ */
4
+
5
+ @use "~@wordpress/base-styles/colors" as wp-colors;
6
+
7
+ .newspack-autocomplete-with-latest-posts {
8
+ display: grid;
9
+ gap: 16px;
10
+ width: 100%;
11
+
12
+ .components-select-control__input {
13
+ max-width: none;
14
+ }
15
+
16
+ .components-input-control__backdrop {
17
+ border-color: wp-colors.$gray-700 !important;
18
+ }
19
+
20
+ .newspack-autocomplete-with-latest-posts__label,
21
+ .components-form-token-field__label,
22
+ .components-input-control__label,
23
+ .components-checkbox-control__label {
24
+ color: wp-colors.$gray-900 !important;
25
+ }
26
+
27
+ .newspack-autocomplete-tokenfield__help {
28
+ font-size: inherit;
29
+ margin-bottom: 8px !important;
30
+ }
31
+
32
+ .components-form-token-field {
33
+ &__input-container {
34
+ border-color: wp-colors.$gray-700;
35
+ }
36
+
37
+ &__suggestion {
38
+ padding: 8px;
39
+ }
40
+ }
41
+
42
+ // Hide the built-in "Separate with commas or the Enter key." help text when hideFormTokenHelp is true
43
+ &.hide-form-token-help .components-form-token-field__help {
44
+ display: none;
45
+ }
46
+
47
+ p.newspack-autocomplete-with-latest-posts__label {
48
+ font-size: inherit;
49
+ margin: 0 0 8px;
50
+ }
51
+
52
+ &__selected-items {
53
+ border-bottom: 1px solid wp-colors.$gray-700;
54
+ display: flex;
55
+ flex-wrap: wrap;
56
+ gap: 8px;
57
+ margin-bottom: 16px;
58
+ padding-bottom: 12px;
59
+
60
+ p.newspack-autocomplete-with-latest-posts__label {
61
+ flex: 0 0 100%;
62
+ margin: 0;
63
+ }
64
+ }
65
+
66
+ &__selected-item-button.components-button.is-tertiary {
67
+ background-color: wp-colors.$gray-300;
68
+ border-radius: 2px;
69
+ color: wp-colors.$gray-900;
70
+ font-size: 13px;
71
+ height: auto;
72
+ margin: 0;
73
+ padding-left: 8px;
74
+ padding-right: 8px;
75
+
76
+ &::after {
77
+ content: "✕";
78
+ margin-left: 8px;
79
+ }
80
+
81
+ &:hover {
82
+ box-shadow: none;
83
+ color: black;
84
+ }
85
+ }
86
+
87
+ &__search-suggestions,
88
+ &__search-suggestions-multiselect {
89
+ max-height: 220px;
90
+ overflow: visible auto;
91
+ margin: 0 -4px;
92
+ padding: 4px 4px 0;
93
+
94
+ .components-button {
95
+ display: block;
96
+ line-height: normal;
97
+ margin: auto;
98
+
99
+ &.is-link {
100
+ color: wp-colors.$gray-900;
101
+ padding: 8px;
102
+ text-decoration: none;
103
+ width: 100%;
104
+
105
+ &:active:not(:disabled),
106
+ &:hover:not(:disabled) {
107
+ background: wp-colors.$gray-900;
108
+ background: var(--wp-admin-theme-color);
109
+ color: white;
110
+ }
111
+ }
112
+ &.is-secondary {
113
+ margin-bottom: 8px;
114
+ margin-top: 8px;
115
+ width: 100%;
116
+ }
117
+ }
118
+ }
119
+
120
+ &__search-suggestions {
121
+ border-radius: 2px;
122
+ border: 1px solid wp-colors.$gray-700;
123
+ padding: 0;
124
+
125
+ .components-button {
126
+ line-height: normal;
127
+
128
+ &:focus:not(:disabled) {
129
+ border-radius: 0;
130
+ box-shadow: inset 0 0 0 1.5px wp-colors.$gray-900;
131
+ box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
132
+ }
133
+
134
+ &.is-secondary {
135
+ width: calc(100% - 16px);
136
+ }
137
+ }
138
+ }
139
+
140
+ // Temp: CSS work-around.
141
+ .newspack-autocomplete-with-suggestions__label {
142
+ font-size: 11px;
143
+ font-weight: 500;
144
+ line-height: 1.4;
145
+ text-transform: uppercase;
146
+ display: block;
147
+ margin: 0 0 8px;
148
+ padding: 0;
149
+ }
150
+ }