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,69 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports["default"] = void 0;
8
+ var _classnames = _interopRequireDefault(require("classnames"));
9
+ var _ = require("../");
10
+ require("./style.scss");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ /**
13
+ * Card - Settings group component.
14
+ */
15
+
16
+ /**
17
+ * External dependencies
18
+ */
19
+
20
+ /**
21
+ * Internal dependencies
22
+ */
23
+
24
+ var CardSettingsGroup = function CardSettingsGroup(_ref) {
25
+ var _ref$actionType = _ref.actionType,
26
+ actionType = _ref$actionType === void 0 ? 'none' : _ref$actionType,
27
+ children = _ref.children,
28
+ className = _ref.className,
29
+ _ref$disabled = _ref.disabled,
30
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
31
+ _ref$icon = _ref.icon,
32
+ icon = _ref$icon === void 0 ? null : _ref$icon,
33
+ headerAction = _ref.headerAction,
34
+ _ref$title = _ref.title,
35
+ title = _ref$title === void 0 ? '' : _ref$title,
36
+ _ref$description = _ref.description,
37
+ description = _ref$description === void 0 ? '' : _ref$description,
38
+ _ref$isActive = _ref.isActive,
39
+ isActive = _ref$isActive === void 0 ? false : _ref$isActive,
40
+ _ref$onEnable = _ref.onEnable,
41
+ onEnable = _ref$onEnable === void 0 ? function () {} : _ref$onEnable,
42
+ _ref$onHeaderClick = _ref.onHeaderClick,
43
+ onHeaderClick = _ref$onHeaderClick === void 0 ? function () {} : _ref$onHeaderClick;
44
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_.Card, {
45
+ className: (0, _classnames["default"])('newspack-card--core--settings-group', className),
46
+ actionType: actionType,
47
+ isSmall: true,
48
+ __experimentalCoreCard: true,
49
+ __experimentalCoreProps: {
50
+ header: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
51
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("h3", {
52
+ children: title
53
+ }), description && /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
54
+ children: description
55
+ })]
56
+ }),
57
+ headerAction: headerAction,
58
+ onHeaderClick: onHeaderClick,
59
+ onToggle: onEnable,
60
+ disabled: disabled,
61
+ icon: icon,
62
+ iconBackgroundColor: true,
63
+ isActive: isActive,
64
+ title: title
65
+ },
66
+ children: isActive && children
67
+ });
68
+ };
69
+ var _default = exports["default"] = CardSettingsGroup;
@@ -0,0 +1,33 @@
1
+ .newspack-card--core--settings-group {
2
+ .components-card__body {
3
+ > .newspack-notice {
4
+ margin: 16px 0;
5
+ }
6
+ > .components-base-control {
7
+ &:first-child {
8
+ margin-top: 0;
9
+ }
10
+ + .components-base-control,
11
+ + .newspack-form-token-field {
12
+ margin-top: 16px;
13
+ }
14
+ }
15
+
16
+ /** ToggleControl switch should appear after the label. */
17
+ > .components-toggle-control {
18
+ .components-h-stack {
19
+ .components-form-toggle {
20
+ order: 2;
21
+ }
22
+ }
23
+ .components-toggle-control__help {
24
+ margin-inline-start: auto;
25
+ }
26
+ }
27
+ .newspack-grid:last-child,
28
+ .components-base-control:last-child,
29
+ p:last-child {
30
+ margin-bottom: 0;
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,426 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports["default"] = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+ var _components = require("@wordpress/components");
12
+ var _element = require("@wordpress/element");
13
+ var _ = require("../");
14
+ require("./style.scss");
15
+ var _classnames = _interopRequireDefault(require("classnames"));
16
+ var _jsxRuntime = require("react/jsx-runtime");
17
+ 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; }
18
+ 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) { (0, _defineProperty2["default"])(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; } /**
19
+ * Card - Sortable list component.
20
+ */ /**
21
+ * WordPress dependencies.
22
+ */ // eslint-disable-line @wordpress/no-unsafe-wp-apis
23
+ /**
24
+ * Internal dependencies
25
+ */ /**
26
+ * External dependencies
27
+ */
28
+ var DROP_ANIMATION_DURATION = 400; // ms — must match $drop-duration in style.scss
29
+ var BUTTON_MOVE_DURATION = 200; // ms — must match $shift-duration in style.scss
30
+
31
+ var CardSortableList = function CardSortableList(_ref) {
32
+ var _ref$disabled = _ref.disabled,
33
+ disabled = _ref$disabled === void 0 ? false : _ref$disabled,
34
+ _ref$items = _ref.items,
35
+ items = _ref$items === void 0 ? [] : _ref$items,
36
+ _ref$onDragCallback = _ref.onDragCallback,
37
+ onDragCallback = _ref$onDragCallback === void 0 ? function () {} : _ref$onDragCallback;
38
+ var _useState = (0, _element.useState)(items),
39
+ _useState2 = (0, _slicedToArray2["default"])(_useState, 2),
40
+ sortedItems = _useState2[0],
41
+ setSortedItems = _useState2[1];
42
+ var _useState3 = (0, _element.useState)(null),
43
+ _useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
44
+ draggingIndex = _useState4[0],
45
+ setDraggingIndex = _useState4[1];
46
+ var _useState5 = (0, _element.useState)(null),
47
+ _useState6 = (0, _slicedToArray2["default"])(_useState5, 2),
48
+ hoverIndex = _useState6[0],
49
+ setHoverIndex = _useState6[1];
50
+ var _useState7 = (0, _element.useState)(null),
51
+ _useState8 = (0, _slicedToArray2["default"])(_useState7, 2),
52
+ droppedIndex = _useState8[0],
53
+ setDroppedIndex = _useState8[1];
54
+ var _useState9 = (0, _element.useState)(null),
55
+ _useState0 = (0, _slicedToArray2["default"])(_useState9, 2),
56
+ measurements = _useState0[0],
57
+ setMeasurements = _useState0[1];
58
+ var listRef = (0, _element.useRef)(null);
59
+ var itemRefs = (0, _element.useRef)([]);
60
+ var dropAnimationTimer = (0, _element.useRef)(null);
61
+ var buttonMoveTimer = (0, _element.useRef)(null);
62
+ var buttonFlipRef = (0, _element.useRef)(null);
63
+ var _useState1 = (0, _element.useState)(0),
64
+ _useState10 = (0, _slicedToArray2["default"])(_useState1, 2),
65
+ buttonMoveId = _useState10[0],
66
+ setButtonMoveId = _useState10[1];
67
+ var documentDragOverRef = (0, _element.useRef)(null);
68
+
69
+ // Keep sortedItems in sync when the items prop changes externally (e.g. after a save).
70
+ (0, _element.useEffect)(function () {
71
+ setSortedItems(items);
72
+ }, [items]);
73
+
74
+ // Clean up any pending animation timer on unmount.
75
+ (0, _element.useEffect)(function () {
76
+ return function () {
77
+ if (dropAnimationTimer.current) {
78
+ clearTimeout(dropAnimationTimer.current);
79
+ }
80
+ if (buttonMoveTimer.current) {
81
+ clearTimeout(buttonMoveTimer.current);
82
+ }
83
+ if (documentDragOverRef.current) {
84
+ document.removeEventListener('dragover', documentDragOverRef.current);
85
+ }
86
+ };
87
+ }, []);
88
+
89
+ /**
90
+ * Handle a chevron-button move. Records item positions before the reorder so
91
+ * the FLIP animation can play after React commits the new DOM order.
92
+ */
93
+ var handleButtonMove = function handleButtonMove(fromIndex, toIndex) {
94
+ if (toIndex < 0 || toIndex >= sortedItems.length) {
95
+ return;
96
+ }
97
+ var fromEl = itemRefs.current[fromIndex];
98
+ var toEl = itemRefs.current[toIndex];
99
+ if (!fromEl || !toEl) {
100
+ return;
101
+ }
102
+ var stride = Math.abs(toEl.getBoundingClientRect().top - fromEl.getBoundingClientRect().top);
103
+ var direction = toIndex > fromIndex ? 1 : -1;
104
+ buttonFlipRef.current = {
105
+ fromIndex: fromIndex,
106
+ toIndex: toIndex,
107
+ stride: stride,
108
+ direction: direction
109
+ };
110
+ var reordered = (0, _toConsumableArray2["default"])(sortedItems);
111
+ var _reordered$splice = reordered.splice(fromIndex, 1),
112
+ _reordered$splice2 = (0, _slicedToArray2["default"])(_reordered$splice, 1),
113
+ moved = _reordered$splice2[0];
114
+ reordered.splice(toIndex, 0, moved);
115
+ setSortedItems(reordered);
116
+ setButtonMoveId(function (id) {
117
+ return id + 1;
118
+ });
119
+ };
120
+
121
+ /**
122
+ * FLIP Invert+Play step: runs synchronously after React commits the reordered
123
+ * DOM. Animate each swapped item from its previous position to its new one
124
+ * using inline CSS transitions (no CSS classes, to avoid creating a new
125
+ * containing block that would break position:fixed on the Draggable clone).
126
+ */
127
+ (0, _element.useLayoutEffect)(function () {
128
+ var flipData = buttonFlipRef.current;
129
+ if (!flipData) {
130
+ return;
131
+ }
132
+ buttonFlipRef.current = null;
133
+ var fromIndex = flipData.fromIndex,
134
+ toIndex = flipData.toIndex,
135
+ stride = flipData.stride,
136
+ direction = flipData.direction;
137
+ var startAnimation = function startAnimation(el, startY) {
138
+ if (!el) {
139
+ return;
140
+ }
141
+ // Snap to the starting position with no transition.
142
+ el.style.transition = 'none';
143
+ el.style.transform = "translateY(".concat(startY, "px)");
144
+ // Force a reflow so the browser registers the starting position
145
+ // before we switch to the animated transition.
146
+ el.getBoundingClientRect();
147
+ // Animate from startY back to 0 (its new natural position).
148
+ el.style.transition = "transform ".concat(BUTTON_MOVE_DURATION, "ms ease-out");
149
+ el.style.transform = '';
150
+ };
151
+
152
+ // Moved item is now at toIndex: animate it in from its old position.
153
+ startAnimation(itemRefs.current[toIndex], -direction * stride);
154
+ // Displaced item is now at fromIndex: animate it in from its old position.
155
+ startAnimation(itemRefs.current[fromIndex], direction * stride);
156
+ if (buttonMoveTimer.current) {
157
+ clearTimeout(buttonMoveTimer.current);
158
+ }
159
+ buttonMoveTimer.current = setTimeout(function () {
160
+ // Clear inline animation styles before calling the external callback so
161
+ // the subsequent React re-render doesn't fight a live animation.
162
+ [fromIndex, toIndex].forEach(function (i) {
163
+ var el = itemRefs.current[i];
164
+ if (el) {
165
+ el.style.transition = '';
166
+ el.style.transform = '';
167
+ }
168
+ });
169
+
170
+ // Move focus to the matching chevron button on the card at toIndex.
171
+ // Focus before onDragCallback so a parent rerender can't steal focus.
172
+ var targetEl = itemRefs.current[toIndex];
173
+ if (targetEl) {
174
+ var moveButtons = targetEl.querySelectorAll('.newspack-card--core__header__draggable-controls__move-buttons button');
175
+ // direction > 0 = moved down → prefer the down button (index 1).
176
+ // direction < 0 = moved up → prefer the up button (index 0).
177
+ var preferred = direction > 0 ? moveButtons[1] : moveButtons[0];
178
+ var fallback = direction > 0 ? moveButtons[0] : moveButtons[1];
179
+ if (preferred && !preferred.disabled) {
180
+ preferred.focus();
181
+ } else if (fallback && !fallback.disabled) {
182
+ fallback.focus();
183
+ }
184
+ }
185
+ onDragCallback(fromIndex, toIndex);
186
+ buttonMoveTimer.current = null;
187
+ }, BUTTON_MOVE_DURATION);
188
+ }, [buttonMoveId]); // eslint-disable-line react-hooks/exhaustive-deps
189
+
190
+ var handleDragStart = function handleDragStart(index) {
191
+ // Cancel any in-progress button-move animation so no item wrapper keeps
192
+ // an inline transform. A transformed ancestor breaks position:fixed on
193
+ // the Draggable clone (CSS spec: fixed positioning is relative to the
194
+ // nearest ancestor with a transform/filter/perspective).
195
+ if (buttonMoveTimer.current) {
196
+ clearTimeout(buttonMoveTimer.current);
197
+ buttonMoveTimer.current = null;
198
+ itemRefs.current.forEach(function (el) {
199
+ if (el) {
200
+ el.style.transition = '';
201
+ el.style.transform = '';
202
+ }
203
+ });
204
+ }
205
+ var listEl = listRef.current;
206
+ if (listEl) {
207
+ var _rects$index$height, _rects$index;
208
+ var itemEls = itemRefs.current;
209
+ var rects = itemEls.map(function (el) {
210
+ return el === null || el === void 0 ? void 0 : el.getBoundingClientRect();
211
+ });
212
+
213
+ // Stride = item height + gap to next item (difference between consecutive tops).
214
+ var itemStrides = rects.map(function (rect, i) {
215
+ if (!rect) {
216
+ return 0;
217
+ }
218
+ var nextRect = rects[i + 1];
219
+ return nextRect ? nextRect.top - rect.top : rect.height;
220
+ });
221
+ setMeasurements({
222
+ lockedHeight: listEl.getBoundingClientRect().height,
223
+ sourceHeight: (_rects$index$height = (_rects$index = rects[index]) === null || _rects$index === void 0 ? void 0 : _rects$index.height) !== null && _rects$index$height !== void 0 ? _rects$index$height : 0,
224
+ itemStrides: itemStrides,
225
+ itemTops: rects.map(function (rect) {
226
+ var _rect$top;
227
+ return (_rect$top = rect === null || rect === void 0 ? void 0 : rect.top) !== null && _rect$top !== void 0 ? _rect$top : 0;
228
+ })
229
+ });
230
+ }
231
+ // Make the entire document a valid drop target so the browser skips
232
+ // its snap-back animation when the cursor is released outside the list.
233
+ var preventSnapback = function preventSnapback(e) {
234
+ return e.preventDefault();
235
+ };
236
+ document.addEventListener('dragover', preventSnapback);
237
+ documentDragOverRef.current = preventSnapback;
238
+ setDraggingIndex(index);
239
+ setDroppedIndex(null);
240
+ };
241
+ var clearDragState = function clearDragState() {
242
+ if (documentDragOverRef.current) {
243
+ document.removeEventListener('dragover', documentDragOverRef.current);
244
+ documentDragOverRef.current = null;
245
+ }
246
+ setDraggingIndex(null);
247
+ setHoverIndex(null);
248
+ setMeasurements(null);
249
+ };
250
+
251
+ /**
252
+ * Determine the drop target index from cursor coordinates and the item
253
+ * top positions snapshotted at drag start. Mirrors the midpoint logic
254
+ * previously used in getDropIndex but works without a live event target.
255
+ */
256
+ var getDropIndexFromCursor = function getDropIndexFromCursor(clientY, m, sourceIndex) {
257
+ var itemTops = m.itemTops,
258
+ itemStrides = m.itemStrides,
259
+ sourceHeight = m.sourceHeight;
260
+ for (var i = 0; i < itemTops.length; i++) {
261
+ var movingDown = sourceIndex > i;
262
+ var midpoint = itemTops[i] + (movingDown ? itemStrides[i] : itemStrides[i] - sourceHeight);
263
+ if (clientY < midpoint) {
264
+ return i;
265
+ }
266
+ }
267
+ return itemTops.length; // below all items
268
+ };
269
+ var handleDragEnd = function handleDragEnd(event) {
270
+ // Take a local copy of measurements before clearDragState nulls it.
271
+ var m = measurements;
272
+ var sourceIndex = draggingIndex;
273
+ clearDragState();
274
+ if (m === null || sourceIndex === null) {
275
+ return;
276
+ }
277
+ var dropIndex = getDropIndexFromCursor(event.clientY, m, sourceIndex);
278
+
279
+ // Compute the destination index in the post-removal array.
280
+ // After splicing out the dragged item, indices above it shift down by one.
281
+ var insertIndex = dropIndex > sourceIndex ? dropIndex - 1 : dropIndex;
282
+ if (insertIndex === sourceIndex) {
283
+ return;
284
+ }
285
+ var reordered = (0, _toConsumableArray2["default"])(sortedItems);
286
+ var _reordered$splice3 = reordered.splice(sourceIndex, 1),
287
+ _reordered$splice4 = (0, _slicedToArray2["default"])(_reordered$splice3, 1),
288
+ moved = _reordered$splice4[0];
289
+ reordered.splice(insertIndex, 0, moved);
290
+
291
+ // First render: show items in their new order with no animation.
292
+ // The dragging CSS classes are already cleared by clearDragState() above,
293
+ // so no transitions will fire on this paint.
294
+ setSortedItems(reordered);
295
+
296
+ // Next frame: trigger the drop animation on the newly-positioned item,
297
+ // then call onDragCallback after the animation completes.
298
+ requestAnimationFrame(function () {
299
+ setDroppedIndex(insertIndex);
300
+ dropAnimationTimer.current = setTimeout(function () {
301
+ setDroppedIndex(null);
302
+ onDragCallback(sourceIndex, insertIndex);
303
+ }, DROP_ANIMATION_DURATION);
304
+ });
305
+ };
306
+ var handleDragOver = function handleDragOver(event, index) {
307
+ event.preventDefault();
308
+ if (!measurements) {
309
+ return;
310
+ }
311
+ var rect = event.currentTarget.getBoundingClientRect();
312
+ var midpoint = rect.top + rect.height / 2;
313
+ setHoverIndex(event.clientY < midpoint ? index : index + 1);
314
+ };
315
+
316
+ /**
317
+ * Compute the translateY for a non-source item at `index` given the current
318
+ * draggingIndex and hoverIndex, so that items visually shift to show the gap
319
+ * while the container's layout height stays fixed.
320
+ *
321
+ * The source item has been visually hidden but still occupies its layout slot.
322
+ * Items between the source and the hover position need to slide by the source
323
+ * item's stride (height + gap) to either fill the vacated source slot or make
324
+ * room for the incoming gap at the hover position.
325
+ */
326
+ var getTranslateY = function getTranslateY(index) {
327
+ var _itemStrides$dragging;
328
+ if (draggingIndex === null || hoverIndex === null || !measurements) {
329
+ return 0;
330
+ }
331
+ if (index === draggingIndex) {
332
+ return 0;
333
+ }
334
+ var itemStrides = measurements.itemStrides,
335
+ sourceHeight = measurements.sourceHeight;
336
+ var sourceStride = (_itemStrides$dragging = itemStrides[draggingIndex]) !== null && _itemStrides$dragging !== void 0 ? _itemStrides$dragging : sourceHeight;
337
+ if (hoverIndex > draggingIndex) {
338
+ // Dragging downward: items strictly between source and hover position slide up.
339
+ if (index > draggingIndex && index < hoverIndex) {
340
+ return -sourceStride;
341
+ }
342
+ } else if (index >= hoverIndex && index < draggingIndex) {
343
+ // Dragging upward: items between hover position and source slide down.
344
+ return sourceStride;
345
+ }
346
+ return 0;
347
+ };
348
+ var isDragging = draggingIndex !== null;
349
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalVStack, {
350
+ ref: listRef,
351
+ className: (0, _classnames["default"])('newspack-card--core--sortable-list', disabled && 'newspack-card--core--sortable-list__is-disabled', isDragging && 'newspack-card--core--sortable-list__is-dragging'),
352
+ style: measurements ? {
353
+ height: measurements.lockedHeight
354
+ } : undefined,
355
+ spacing: 4,
356
+ children: sortedItems.map(function (item, index) {
357
+ var translateY = getTranslateY(index);
358
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Disabled, {
359
+ isDisabled: disabled,
360
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
361
+ ref: function ref(el) {
362
+ itemRefs.current[index] = el;
363
+ },
364
+ className: (0, _classnames["default"])('newspack-card--core--sortable-list__item', {
365
+ 'is-source': draggingIndex === index,
366
+ 'is-dropped': droppedIndex === index
367
+ }),
368
+ style: translateY ? {
369
+ transform: "translateY(".concat(translateY, "px)")
370
+ } : {
371
+ transition: !isDragging ? 'none' : undefined
372
+ },
373
+ id: "draggable-card-".concat(index),
374
+ onDragOver: function onDragOver(e) {
375
+ return handleDragOver(e, index);
376
+ },
377
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.Draggable, {
378
+ transferData: {},
379
+ cloneClassname: "newspack-card--core--sortable-list__item__clone",
380
+ elementId: "draggable-card-".concat(index),
381
+ onDragStart: function onDragStart() {
382
+ return handleDragStart(index);
383
+ },
384
+ onDragEnd: handleDragEnd,
385
+ appendToOwnerDocument: true,
386
+ children: function children(_ref2) {
387
+ var onDraggableStart = _ref2.onDraggableStart,
388
+ onDraggableEnd = _ref2.onDraggableEnd;
389
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_.Card, {
390
+ isSmall: true,
391
+ draggable: true,
392
+ onDragStart: onDraggableStart,
393
+ onDragEnd: onDraggableEnd,
394
+ __experimentalCoreCard: true,
395
+ __experimentalCoreProps: _objectSpread(_objectSpread({
396
+ header: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
397
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("h3", {
398
+ children: [item.title, /*#__PURE__*/(0, _jsxRuntime.jsx)(_.Badge, {
399
+ level: item.badgeLevel,
400
+ text: item.badgeText
401
+ })]
402
+ }), item.description && /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
403
+ children: item.description
404
+ })]
405
+ }),
406
+ isDraggable: true,
407
+ isFirstTarget: index === 0,
408
+ isLastTarget: index === sortedItems.length - 1,
409
+ dragIndex: index,
410
+ onDragCallback: handleButtonMove
411
+ }, item.onToggleChange !== undefined && {
412
+ actionType: 'toggle',
413
+ isActive: item.toggleChecked,
414
+ onToggle: item.onToggleChange
415
+ }), item.actions !== undefined && {
416
+ actions: item.actions
417
+ })
418
+ });
419
+ }
420
+ })
421
+ })
422
+ }, item.id);
423
+ })
424
+ });
425
+ };
426
+ var _default = exports["default"] = CardSortableList;
@@ -0,0 +1,48 @@
1
+ $collapse-duration: 200ms;
2
+ $shift-duration: 150ms;
3
+ $drop-duration: 400ms; /* must match DROP_ANIMATION_DURATION in index.tsx */
4
+
5
+ .newspack-card--core--sortable-list {
6
+ &__item {
7
+ cursor: grab;
8
+
9
+ /*
10
+ * Animate items sliding to fill/make space around the dragged item.
11
+ */
12
+ transition: transform $shift-duration ease;
13
+
14
+ /*
15
+ * Collapse the source item's content — the wrapper stays in layout as the
16
+ * anchor point, and the container height is locked via inline style in JS.
17
+ */
18
+ &.is-source {
19
+ cursor: grabbing;
20
+ opacity: 0;
21
+ transition: opacity $collapse-duration ease;
22
+ }
23
+
24
+ /*
25
+ * Drop landing animation: brief fade-in and scale on the newly placed item.
26
+ */
27
+ &.is-dropped {
28
+ animation: newspack-sortable-drop $drop-duration ease forwards;
29
+ opacity: 0;
30
+ }
31
+
32
+ }
33
+ }
34
+
35
+ @keyframes newspack-sortable-drop {
36
+ 0% {
37
+ opacity: 0;
38
+ transform: scale(0.98);
39
+ }
40
+ 60% {
41
+ opacity: 1;
42
+ transform: scale(1.01);
43
+ }
44
+ 100% {
45
+ opacity: 1;
46
+ transform: scale(1);
47
+ }
48
+ }