@wordpress/block-library 8.20.1 → 8.21.1-next.f8d8eceb.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 (412) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +12 -0
  3. package/build/avatar/index.js +5 -1
  4. package/build/avatar/index.js.map +1 -1
  5. package/build/block/edit-title.native.js +11 -3
  6. package/build/block/edit-title.native.js.map +1 -1
  7. package/build/block/index.js +2 -1
  8. package/build/block/index.js.map +1 -1
  9. package/build/code/edit.native.js +8 -2
  10. package/build/code/edit.native.js.map +1 -1
  11. package/build/column/edit.js +2 -1
  12. package/build/column/edit.js.map +1 -1
  13. package/build/column/edit.native.js +2 -1
  14. package/build/column/edit.native.js.map +1 -1
  15. package/build/columns/edit.native.js +2 -1
  16. package/build/columns/edit.native.js.map +1 -1
  17. package/build/cover/controls.native.js +2 -1
  18. package/build/cover/controls.native.js.map +1 -1
  19. package/build/cover/deprecated.js +110 -1
  20. package/build/cover/deprecated.js.map +1 -1
  21. package/build/cover/edit/index.js +11 -4
  22. package/build/cover/edit/index.js.map +1 -1
  23. package/build/cover/edit/inspector-controls.js +3 -3
  24. package/build/cover/edit/inspector-controls.js.map +1 -1
  25. package/build/cover/index.js +0 -3
  26. package/build/cover/index.js.map +1 -1
  27. package/build/cover/save.js +2 -1
  28. package/build/cover/save.js.map +1 -1
  29. package/build/cover/shared.js +1 -1
  30. package/build/cover/shared.js.map +1 -1
  31. package/build/file/view.js +1 -1
  32. package/build/file/view.js.map +1 -1
  33. package/build/footnotes/index.js +1 -0
  34. package/build/footnotes/index.js.map +1 -1
  35. package/build/form/edit.js +138 -0
  36. package/build/form/edit.js.map +1 -0
  37. package/build/form/index.js +92 -0
  38. package/build/form/index.js.map +1 -0
  39. package/build/form/init.js +13 -0
  40. package/build/form/init.js.map +1 -0
  41. package/build/form/save.js +28 -0
  42. package/build/form/save.js.map +1 -0
  43. package/build/form/utils.js +24 -0
  44. package/build/form/utils.js.map +1 -0
  45. package/build/form/variations.js +95 -0
  46. package/build/form/variations.js.map +1 -0
  47. package/build/form/view.js +42 -0
  48. package/build/form/view.js.map +1 -0
  49. package/build/form-input/edit.js +124 -0
  50. package/build/form-input/edit.js.map +1 -0
  51. package/build/form-input/index.js +105 -0
  52. package/build/form-input/index.js.map +1 -0
  53. package/build/form-input/init.js +13 -0
  54. package/build/form-input/init.js.map +1 -0
  55. package/build/form-input/save.js +87 -0
  56. package/build/form-input/save.js.map +1 -0
  57. package/build/form-input/variations.js +93 -0
  58. package/build/form-input/variations.js.map +1 -0
  59. package/build/form-submission-notification/edit.js +59 -0
  60. package/build/form-submission-notification/edit.js.map +1 -0
  61. package/build/form-submission-notification/index.js +56 -0
  62. package/build/form-submission-notification/index.js.map +1 -0
  63. package/build/form-submission-notification/init.js +13 -0
  64. package/build/form-submission-notification/init.js.map +1 -0
  65. package/build/form-submission-notification/save.js +33 -0
  66. package/build/form-submission-notification/save.js.map +1 -0
  67. package/build/form-submission-notification/variations.js +63 -0
  68. package/build/form-submission-notification/variations.js.map +1 -0
  69. package/build/form-submit-button/edit.js +32 -0
  70. package/build/form-submit-button/edit.js.map +1 -0
  71. package/build/form-submit-button/index.js +44 -0
  72. package/build/form-submit-button/index.js.map +1 -0
  73. package/build/form-submit-button/init.js +13 -0
  74. package/build/form-submit-button/init.js.map +1 -0
  75. package/build/form-submit-button/save.js +22 -0
  76. package/build/form-submit-button/save.js.map +1 -0
  77. package/build/group/edit.js +2 -11
  78. package/build/group/edit.js.map +1 -1
  79. package/build/group/index.js +0 -1
  80. package/build/group/index.js.map +1 -1
  81. package/build/heading/index.js +3 -2
  82. package/build/heading/index.js.map +1 -1
  83. package/build/html/preview.js +2 -4
  84. package/build/html/preview.js.map +1 -1
  85. package/build/image/image.js +15 -6
  86. package/build/image/image.js.map +1 -1
  87. package/build/image/view.js +71 -39
  88. package/build/image/view.js.map +1 -1
  89. package/build/index.js +10 -0
  90. package/build/index.js.map +1 -1
  91. package/build/latest-posts/edit.js +6 -2
  92. package/build/latest-posts/edit.js.map +1 -1
  93. package/build/list-item/hooks/use-merge.js +15 -15
  94. package/build/list-item/hooks/use-merge.js.map +1 -1
  95. package/build/lock-unlock.js +1 -1
  96. package/build/lock-unlock.js.map +1 -1
  97. package/build/missing/edit.native.js +54 -64
  98. package/build/missing/edit.native.js.map +1 -1
  99. package/build/navigation/edit/index.js +0 -1
  100. package/build/navigation/edit/index.js.map +1 -1
  101. package/build/navigation/index.js +2 -1
  102. package/build/navigation/index.js.map +1 -1
  103. package/build/navigation/view.js +27 -5
  104. package/build/navigation/view.js.map +1 -1
  105. package/build/page-list-item/edit.js +3 -1
  106. package/build/page-list-item/edit.js.map +1 -1
  107. package/build/paragraph/edit.js +1 -1
  108. package/build/paragraph/edit.js.map +1 -1
  109. package/build/paragraph/index.js +7 -0
  110. package/build/paragraph/index.js.map +1 -1
  111. package/build/pattern/index.js +2 -1
  112. package/build/pattern/index.js.map +1 -1
  113. package/build/post-featured-image/dimension-controls.js +2 -2
  114. package/build/post-featured-image/dimension-controls.js.map +1 -1
  115. package/build/query/edit/enhanced-pagination-modal.js +27 -13
  116. package/build/query/edit/enhanced-pagination-modal.js.map +1 -1
  117. package/build/query/edit/inspector-controls/enhanced-pagination-control.js +15 -12
  118. package/build/query/edit/inspector-controls/enhanced-pagination-control.js.map +1 -1
  119. package/build/query/utils.js +29 -8
  120. package/build/query/utils.js.map +1 -1
  121. package/build/query/view.js +4 -2
  122. package/build/query/view.js.map +1 -1
  123. package/build/search/edit.js +1 -2
  124. package/build/search/edit.js.map +1 -1
  125. package/build/social-link/edit.native.js +7 -19
  126. package/build/social-link/edit.native.js.map +1 -1
  127. package/build/spacer/controls.js +3 -3
  128. package/build/spacer/controls.js.map +1 -1
  129. package/build/spacer/controls.native.js +2 -1
  130. package/build/spacer/controls.native.js.map +1 -1
  131. package/build/spacer/edit.js +1 -1
  132. package/build/spacer/edit.js.map +1 -1
  133. package/build/spacer/edit.native.js +5 -1
  134. package/build/spacer/edit.native.js.map +1 -1
  135. package/build/tag-cloud/edit.js +2 -1
  136. package/build/tag-cloud/edit.js.map +1 -1
  137. package/build/template-part/edit/inner-blocks.js +2 -2
  138. package/build/template-part/edit/inner-blocks.js.map +1 -1
  139. package/build/template-part/index.js +2 -1
  140. package/build/template-part/index.js.map +1 -1
  141. package/build/term-description/index.js +0 -1
  142. package/build/term-description/index.js.map +1 -1
  143. package/build-module/avatar/index.js +5 -1
  144. package/build-module/avatar/index.js.map +1 -1
  145. package/build-module/block/edit-title.native.js +12 -4
  146. package/build-module/block/edit-title.native.js.map +1 -1
  147. package/build-module/block/index.js +2 -1
  148. package/build-module/block/index.js.map +1 -1
  149. package/build-module/code/edit.native.js +8 -2
  150. package/build-module/code/edit.native.js.map +1 -1
  151. package/build-module/column/edit.js +3 -2
  152. package/build-module/column/edit.js.map +1 -1
  153. package/build-module/column/edit.native.js +3 -2
  154. package/build-module/column/edit.native.js.map +1 -1
  155. package/build-module/columns/edit.native.js +3 -2
  156. package/build-module/columns/edit.native.js.map +1 -1
  157. package/build-module/cover/controls.native.js +3 -2
  158. package/build-module/cover/controls.native.js.map +1 -1
  159. package/build-module/cover/deprecated.js +110 -1
  160. package/build-module/cover/deprecated.js.map +1 -1
  161. package/build-module/cover/edit/index.js +12 -5
  162. package/build-module/cover/edit/index.js.map +1 -1
  163. package/build-module/cover/edit/inspector-controls.js +4 -4
  164. package/build-module/cover/edit/inspector-controls.js.map +1 -1
  165. package/build-module/cover/index.js +0 -3
  166. package/build-module/cover/index.js.map +1 -1
  167. package/build-module/cover/save.js +2 -1
  168. package/build-module/cover/save.js.map +1 -1
  169. package/build-module/cover/shared.js +1 -1
  170. package/build-module/cover/shared.js.map +1 -1
  171. package/build-module/file/view.js +2 -2
  172. package/build-module/file/view.js.map +1 -1
  173. package/build-module/footnotes/index.js +1 -0
  174. package/build-module/footnotes/index.js.map +1 -1
  175. package/build-module/form/edit.js +130 -0
  176. package/build-module/form/edit.js.map +1 -0
  177. package/build-module/form/index.js +82 -0
  178. package/build-module/form/index.js.map +1 -0
  179. package/build-module/form/init.js +6 -0
  180. package/build-module/form/init.js.map +1 -0
  181. package/build-module/form/save.js +20 -0
  182. package/build-module/form/save.js.map +1 -0
  183. package/build-module/form/utils.js +15 -0
  184. package/build-module/form/utils.js.map +1 -0
  185. package/build-module/form/variations.js +86 -0
  186. package/build-module/form/variations.js.map +1 -0
  187. package/build-module/form/view.js +40 -0
  188. package/build-module/form/view.js.map +1 -0
  189. package/build-module/form-input/edit.js +115 -0
  190. package/build-module/form-input/edit.js.map +1 -0
  191. package/build-module/form-input/index.js +95 -0
  192. package/build-module/form-input/index.js.map +1 -0
  193. package/build-module/form-input/init.js +6 -0
  194. package/build-module/form-input/init.js.map +1 -0
  195. package/build-module/form-input/save.js +80 -0
  196. package/build-module/form-input/save.js.map +1 -0
  197. package/build-module/form-input/variations.js +85 -0
  198. package/build-module/form-input/variations.js.map +1 -0
  199. package/build-module/form-submission-notification/edit.js +50 -0
  200. package/build-module/form-submission-notification/edit.js.map +1 -0
  201. package/build-module/form-submission-notification/index.js +47 -0
  202. package/build-module/form-submission-notification/index.js.map +1 -0
  203. package/build-module/form-submission-notification/init.js +6 -0
  204. package/build-module/form-submission-notification/init.js.map +1 -0
  205. package/build-module/form-submission-notification/save.js +25 -0
  206. package/build-module/form-submission-notification/save.js.map +1 -0
  207. package/build-module/form-submission-notification/variations.js +55 -0
  208. package/build-module/form-submission-notification/variations.js.map +1 -0
  209. package/build-module/form-submit-button/edit.js +24 -0
  210. package/build-module/form-submit-button/edit.js.map +1 -0
  211. package/build-module/form-submit-button/index.js +34 -0
  212. package/build-module/form-submit-button/index.js.map +1 -0
  213. package/build-module/form-submit-button/init.js +6 -0
  214. package/build-module/form-submit-button/init.js.map +1 -0
  215. package/build-module/form-submit-button/save.js +14 -0
  216. package/build-module/form-submit-button/save.js.map +1 -0
  217. package/build-module/group/edit.js +3 -12
  218. package/build-module/group/edit.js.map +1 -1
  219. package/build-module/group/index.js +0 -1
  220. package/build-module/group/index.js.map +1 -1
  221. package/build-module/heading/index.js +3 -2
  222. package/build-module/heading/index.js.map +1 -1
  223. package/build-module/html/preview.js +2 -4
  224. package/build-module/html/preview.js.map +1 -1
  225. package/build-module/image/image.js +16 -7
  226. package/build-module/image/image.js.map +1 -1
  227. package/build-module/image/view.js +71 -39
  228. package/build-module/image/view.js.map +1 -1
  229. package/build-module/index.js +10 -0
  230. package/build-module/index.js.map +1 -1
  231. package/build-module/latest-posts/edit.js +6 -2
  232. package/build-module/latest-posts/edit.js.map +1 -1
  233. package/build-module/list-item/hooks/use-merge.js +15 -15
  234. package/build-module/list-item/hooks/use-merge.js.map +1 -1
  235. package/build-module/lock-unlock.js +1 -1
  236. package/build-module/lock-unlock.js.map +1 -1
  237. package/build-module/missing/edit.native.js +58 -68
  238. package/build-module/missing/edit.native.js.map +1 -1
  239. package/build-module/navigation/edit/index.js +0 -1
  240. package/build-module/navigation/edit/index.js.map +1 -1
  241. package/build-module/navigation/index.js +2 -1
  242. package/build-module/navigation/index.js.map +1 -1
  243. package/build-module/navigation/view.js +27 -5
  244. package/build-module/navigation/view.js.map +1 -1
  245. package/build-module/page-list-item/edit.js +3 -1
  246. package/build-module/page-list-item/edit.js.map +1 -1
  247. package/build-module/paragraph/edit.js +2 -2
  248. package/build-module/paragraph/edit.js.map +1 -1
  249. package/build-module/paragraph/index.js +7 -0
  250. package/build-module/paragraph/index.js.map +1 -1
  251. package/build-module/pattern/index.js +2 -1
  252. package/build-module/pattern/index.js.map +1 -1
  253. package/build-module/post-featured-image/dimension-controls.js +3 -3
  254. package/build-module/post-featured-image/dimension-controls.js.map +1 -1
  255. package/build-module/query/edit/enhanced-pagination-modal.js +28 -14
  256. package/build-module/query/edit/enhanced-pagination-modal.js.map +1 -1
  257. package/build-module/query/edit/inspector-controls/enhanced-pagination-control.js +17 -14
  258. package/build-module/query/edit/inspector-controls/enhanced-pagination-control.js.map +1 -1
  259. package/build-module/query/utils.js +27 -5
  260. package/build-module/query/utils.js.map +1 -1
  261. package/build-module/query/view.js +4 -2
  262. package/build-module/query/view.js.map +1 -1
  263. package/build-module/search/edit.js +2 -3
  264. package/build-module/search/edit.js.map +1 -1
  265. package/build-module/social-link/edit.native.js +8 -20
  266. package/build-module/social-link/edit.native.js.map +1 -1
  267. package/build-module/spacer/controls.js +4 -4
  268. package/build-module/spacer/controls.js.map +1 -1
  269. package/build-module/spacer/controls.native.js +3 -2
  270. package/build-module/spacer/controls.native.js.map +1 -1
  271. package/build-module/spacer/edit.js +2 -2
  272. package/build-module/spacer/edit.js.map +1 -1
  273. package/build-module/spacer/edit.native.js +6 -2
  274. package/build-module/spacer/edit.native.js.map +1 -1
  275. package/build-module/tag-cloud/edit.js +3 -2
  276. package/build-module/tag-cloud/edit.js.map +1 -1
  277. package/build-module/template-part/edit/inner-blocks.js +3 -3
  278. package/build-module/template-part/edit/inner-blocks.js.map +1 -1
  279. package/build-module/template-part/index.js +2 -1
  280. package/build-module/template-part/index.js.map +1 -1
  281. package/build-module/term-description/index.js +0 -1
  282. package/build-module/term-description/index.js.map +1 -1
  283. package/build-style/editor-rtl.css +50 -0
  284. package/build-style/editor.css +50 -0
  285. package/build-style/file/style-rtl.css +0 -5
  286. package/build-style/file/style.css +0 -5
  287. package/build-style/form-input/editor-rtl.css +106 -0
  288. package/build-style/form-input/editor.css +106 -0
  289. package/build-style/form-input/style-rtl.css +135 -0
  290. package/build-style/form-input/style.css +135 -0
  291. package/build-style/form-submission-notification/editor-rtl.css +118 -0
  292. package/build-style/form-submission-notification/editor.css +118 -0
  293. package/build-style/form-submit-button/style-rtl.css +91 -0
  294. package/build-style/form-submit-button/style.css +91 -0
  295. package/build-style/image/style-rtl.css +39 -5
  296. package/build-style/image/style.css +39 -5
  297. package/build-style/navigation/style-rtl.css +5 -0
  298. package/build-style/navigation/style.css +5 -0
  299. package/build-style/query/style-rtl.css +0 -10
  300. package/build-style/query/style.css +0 -10
  301. package/build-style/style-rtl.css +92 -10
  302. package/build-style/style.css +92 -10
  303. package/package.json +32 -32
  304. package/src/avatar/block.json +5 -1
  305. package/src/block/block.json +2 -1
  306. package/src/block/edit-title.native.js +16 -13
  307. package/src/calendar/index.php +2 -6
  308. package/src/code/edit.native.js +15 -1
  309. package/src/column/edit.js +3 -8
  310. package/src/column/edit.native.js +3 -8
  311. package/src/columns/edit.native.js +3 -8
  312. package/src/comment-author-avatar/index.php +1 -1
  313. package/src/cover/block.json +0 -3
  314. package/src/cover/controls.native.js +3 -8
  315. package/src/cover/deprecated.js +151 -1
  316. package/src/cover/edit/index.js +15 -5
  317. package/src/cover/edit/inspector-controls.js +22 -33
  318. package/src/cover/save.js +2 -1
  319. package/src/cover/shared.js +1 -1
  320. package/src/editor.scss +2 -0
  321. package/src/file/index.php +2 -1
  322. package/src/file/style.scss +0 -6
  323. package/src/file/view.js +2 -2
  324. package/src/footnotes/block.json +1 -0
  325. package/src/form/block.json +60 -0
  326. package/src/form/edit.js +179 -0
  327. package/src/form/index.js +20 -0
  328. package/src/form/index.php +214 -0
  329. package/src/form/init.js +6 -0
  330. package/src/form/save.js +20 -0
  331. package/src/form/utils.js +39 -0
  332. package/src/form/variations.js +139 -0
  333. package/src/form/view.js +41 -0
  334. package/src/form-input/block.json +73 -0
  335. package/src/form-input/edit.js +151 -0
  336. package/src/form-input/editor.scss +24 -0
  337. package/src/form-input/index.js +20 -0
  338. package/src/form-input/index.php +45 -0
  339. package/src/form-input/init.js +6 -0
  340. package/src/form-input/save.js +83 -0
  341. package/src/form-input/style.scss +61 -0
  342. package/src/form-input/variations.js +82 -0
  343. package/src/form-submission-notification/block.json +19 -0
  344. package/src/form-submission-notification/edit.js +63 -0
  345. package/src/form-submission-notification/editor.scss +45 -0
  346. package/src/form-submission-notification/index.js +26 -0
  347. package/src/form-submission-notification/index.php +48 -0
  348. package/src/form-submission-notification/init.js +6 -0
  349. package/src/form-submission-notification/save.js +28 -0
  350. package/src/form-submission-notification/variations.js +59 -0
  351. package/src/form-submit-button/block.json +14 -0
  352. package/src/form-submit-button/edit.js +33 -0
  353. package/src/form-submit-button/index.js +18 -0
  354. package/src/form-submit-button/init.js +6 -0
  355. package/src/form-submit-button/save.js +14 -0
  356. package/src/form-submit-button/style.scss +3 -0
  357. package/src/freeform/test/__snapshots__/index.native.js.snap +7 -0
  358. package/src/freeform/test/index.native.js +57 -0
  359. package/src/group/block.json +0 -1
  360. package/src/group/edit.js +2 -7
  361. package/src/heading/index.js +4 -2
  362. package/src/html/preview.js +9 -4
  363. package/src/image/image.js +27 -6
  364. package/src/image/index.php +128 -83
  365. package/src/image/style.scss +49 -5
  366. package/src/image/view.js +93 -51
  367. package/src/index.js +10 -0
  368. package/src/latest-posts/edit.js +11 -2
  369. package/src/latest-posts/index.php +17 -8
  370. package/src/list-item/hooks/use-merge.js +20 -23
  371. package/src/lock-unlock.js +1 -1
  372. package/src/missing/edit.native.js +56 -117
  373. package/src/missing/style.native.scss +0 -67
  374. package/src/missing/test/edit-integration.native.js +135 -49
  375. package/src/missing/test/edit.native.js +0 -41
  376. package/src/navigation/block.json +2 -1
  377. package/src/navigation/edit/index.js +0 -1
  378. package/src/navigation/index.php +28 -8
  379. package/src/navigation/style.scss +6 -1
  380. package/src/navigation/view.js +25 -6
  381. package/src/page-list-item/edit.js +2 -0
  382. package/src/paragraph/edit.js +2 -2
  383. package/src/paragraph/index.js +10 -0
  384. package/src/pattern/block.json +2 -1
  385. package/src/pattern/index.php +0 -3
  386. package/src/post-featured-image/dimension-controls.js +3 -3
  387. package/src/post-navigation-link/index.php +2 -1
  388. package/src/preformatted/test/edit.native.js +38 -0
  389. package/src/query/edit/enhanced-pagination-modal.js +37 -21
  390. package/src/query/edit/inspector-controls/enhanced-pagination-control.js +18 -22
  391. package/src/query/index.php +100 -10
  392. package/src/query/style.scss +0 -11
  393. package/src/query/utils.js +29 -8
  394. package/src/query/view.js +11 -2
  395. package/src/query-pagination-next/index.php +1 -1
  396. package/src/query-pagination-previous/index.php +1 -1
  397. package/src/search/edit.js +5 -3
  398. package/src/search/index.php +0 -4
  399. package/src/social-link/edit.native.js +12 -26
  400. package/src/social-link/editor.native.scss +0 -9
  401. package/src/social-link/index.php +2 -2
  402. package/src/spacer/controls.js +9 -12
  403. package/src/spacer/controls.native.js +3 -8
  404. package/src/spacer/edit.js +2 -2
  405. package/src/spacer/edit.native.js +6 -5
  406. package/src/style.scss +1 -0
  407. package/src/tag-cloud/edit.js +3 -7
  408. package/src/template-part/block.json +2 -1
  409. package/src/template-part/edit/inner-blocks.js +3 -3
  410. package/src/template-part/index.php +4 -7
  411. package/src/term-description/block.json +0 -1
  412. package/src/verse/test/edit.native.js +37 -0
@@ -0,0 +1,214 @@
1
+ <?php
2
+ /**
3
+ * Server-side rendering of the `core/form` block.
4
+ *
5
+ * @package WordPress
6
+ */
7
+
8
+ /**
9
+ * Renders the `core/form` block on server.
10
+ *
11
+ * @param array $attributes The block attributes.
12
+ * @param string $content The saved content.
13
+ *
14
+ * @return string The content of the block being rendered.
15
+ */
16
+ function render_block_core_form( $attributes, $content ) {
17
+
18
+ $processed_content = new WP_HTML_Tag_Processor( $content );
19
+ $processed_content->next_tag( 'form' );
20
+
21
+ // Get the action for this form.
22
+ $action = '';
23
+ if ( isset( $attributes['action'] ) ) {
24
+ $action = str_replace(
25
+ array( '{SITE_URL}', '{ADMIN_URL}' ),
26
+ array( site_url(), admin_url() ),
27
+ $attributes['action']
28
+ );
29
+ }
30
+ $processed_content->set_attribute( 'action', esc_attr( $action ) );
31
+
32
+ // Add the method attribute. If it is not set, default to `post`.
33
+ $method = empty( $attributes['method'] ) ? 'post' : $attributes['method'];
34
+ $processed_content->set_attribute( 'method', $method );
35
+
36
+ $extra_fields = apply_filters( 'render_block_core_form_extra_fields', '', $attributes );
37
+
38
+ return str_replace(
39
+ '</form>',
40
+ $extra_fields . '</form>',
41
+ $processed_content->get_updated_html()
42
+ );
43
+ }
44
+
45
+ /**
46
+ * Additional data to add to the view.js script for this block.
47
+ */
48
+ function block_core_form_view_script() {
49
+ if ( ! gutenberg_is_experiment_enabled( 'gutenberg-form-blocks' ) ) {
50
+ return;
51
+ }
52
+
53
+ wp_localize_script(
54
+ 'wp-block-form-view',
55
+ 'wpBlockFormSettings',
56
+ array(
57
+ 'nonce' => wp_create_nonce( 'wp-block-form' ),
58
+ 'ajaxUrl' => admin_url( 'admin-ajax.php' ),
59
+ 'action' => 'wp_block_form_email_submit',
60
+ )
61
+ );
62
+ }
63
+ add_action( 'wp_enqueue_scripts', 'block_core_form_view_script' );
64
+
65
+ /**
66
+ * Adds extra fields to the form.
67
+ *
68
+ * If the form is a comment form, adds the post ID as a hidden field,
69
+ * to allow the comment to be associated with the post.
70
+ *
71
+ * @param string $extra_fields The extra fields.
72
+ * @param array $attributes The block attributes.
73
+ *
74
+ * @return string The extra fields.
75
+ */
76
+ function block_core_form_extra_fields_comment_form( $extra_fields, $attributes ) {
77
+ if ( ! empty( $attributes['action'] ) && str_ends_with( $attributes['action'], '/wp-comments-post.php' ) ) {
78
+ $extra_fields .= '<input type="hidden" name="comment_post_ID" value="' . get_the_ID() . '" id="comment_post_ID">';
79
+ }
80
+ return $extra_fields;
81
+ }
82
+ add_filter( 'render_block_core_form_extra_fields', 'block_core_form_extra_fields_comment_form', 10, 2 );
83
+
84
+ /**
85
+ * Sends an email if the form is a contact form.
86
+ */
87
+ function block_core_form_send_email() {
88
+ check_ajax_referer( 'wp-block-form' );
89
+
90
+ // Get the POST data.
91
+ $params = wp_unslash( $_POST );
92
+ // Start building the email content.
93
+ $content = sprintf(
94
+ /* translators: %s: The request URI. */
95
+ __( 'Form submission from %1$s', 'gutenberg' ) . '</br>',
96
+ '<a href="' . esc_url( get_site_url( null, $params['_wp_http_referer'] ) ) . '">' . get_bloginfo( 'name' ) . '</a>'
97
+ );
98
+
99
+ $skip_fields = array( 'formAction', '_ajax_nonce', 'action' );
100
+ foreach ( $params as $key => $value ) {
101
+ if ( in_array( $key, $skip_fields, true ) ) {
102
+ continue;
103
+ }
104
+ $content .= sanitize_key( $key ) . ': ' . wp_kses_post( $value ) . '</br>';
105
+ }
106
+
107
+ // Filter the email content.
108
+ $content = apply_filters( 'render_block_core_form_email_content', $content, $params );
109
+
110
+ // Send the email.
111
+ $result = wp_mail(
112
+ str_replace( 'mailto:', '', $params['wp-email-address'] ),
113
+ __( 'Form submission', 'gutenberg' ),
114
+ $content
115
+ );
116
+
117
+ if ( ! $result ) {
118
+ wp_send_json_error( $result );
119
+ }
120
+ wp_send_json_success( $result );
121
+ }
122
+ add_action( 'wp_ajax_wp_block_form_email_submit', 'block_core_form_send_email' );
123
+ add_action( 'wp_ajax_nopriv_wp_block_form_email_submit', 'block_core_form_send_email' );
124
+
125
+ /**
126
+ * Send the data export/remove request if the form is a privacy-request form.
127
+ */
128
+ function block_core_form_privacy_form() {
129
+ // Get the POST data.
130
+ $params = wp_unslash( $_POST );
131
+
132
+ // Bail early if not a form submission, or if the nonce is not valid.
133
+ if ( empty( $params['wp-action'] )
134
+ || 'wp_privacy_send_request' !== $params['wp-action']
135
+ || empty( $params['wp-privacy-request'] )
136
+ || '1' !== $params['wp-privacy-request']
137
+ || empty( $params['email'] )
138
+ ) {
139
+ return;
140
+ }
141
+
142
+ // Get the request types.
143
+ $request_types = _wp_privacy_action_request_types();
144
+ $requests_found = array();
145
+ foreach ( $request_types as $request_type ) {
146
+ if ( ! empty( $params[ $request_type ] ) ) {
147
+ $requests_found[] = $request_type;
148
+ }
149
+ }
150
+
151
+ // Bail early if no requests were found.
152
+ if ( empty( $requests_found ) ) {
153
+ return;
154
+ }
155
+
156
+ // Process the requests.
157
+ $actions_errored = array();
158
+ $actions_performed = array();
159
+ foreach ( $requests_found as $action_name ) {
160
+ // Get the request ID.
161
+ $request_id = wp_create_user_request( $params['email'], $action_name );
162
+
163
+ // Bail early if the request ID is invalid.
164
+ if ( is_wp_error( $request_id ) ) {
165
+ $actions_errored[] = $action_name;
166
+ continue;
167
+ }
168
+
169
+ // Send the request email.
170
+ wp_send_user_request( $request_id );
171
+ $actions_performed[] = $action_name;
172
+ }
173
+
174
+ /**
175
+ * Determine whether the core/form-submission-notification block should be shown.
176
+ *
177
+ * @param bool $show Whether to show the core/form-submission-notification block.
178
+ * @param array $attributes The block attributes.
179
+ *
180
+ * @return bool Whether to show the core/form-submission-notification block.
181
+ */
182
+ $show_notification = static function ( $show, $attributes ) use ( $actions_performed, $actions_errored ) {
183
+ switch ( $attributes['type'] ) {
184
+ case 'success':
185
+ return ! empty( $actions_performed ) && empty( $actions_errored );
186
+
187
+ case 'error':
188
+ return ! empty( $actions_errored );
189
+
190
+ default:
191
+ return $show;
192
+ }
193
+ };
194
+
195
+ // Add filter to show the core/form-submission-notification block.
196
+ add_filter( 'show_form_submission_notification_block', $show_notification, 10, 2 );
197
+ }
198
+ add_action( 'wp', 'block_core_form_privacy_form' );
199
+
200
+ /**
201
+ * Registers the `core/form` block on server.
202
+ */
203
+ function register_block_core_form() {
204
+ if ( ! gutenberg_is_experiment_enabled( 'gutenberg-form-blocks' ) ) {
205
+ return;
206
+ }
207
+ register_block_type_from_metadata(
208
+ __DIR__ . '/form',
209
+ array(
210
+ 'render_callback' => 'render_block_core_form',
211
+ )
212
+ );
213
+ }
214
+ add_action( 'init', 'register_block_core_form' );
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { init } from './';
5
+
6
+ export default init();
@@ -0,0 +1,20 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
5
+
6
+ const Save = ( { attributes } ) => {
7
+ const blockProps = useBlockProps.save();
8
+ const { submissionMethod } = attributes;
9
+
10
+ return (
11
+ <form
12
+ { ...blockProps }
13
+ className="wp-block-form"
14
+ encType={ submissionMethod === 'email' ? 'text/plain' : null }
15
+ >
16
+ <InnerBlocks.Content />
17
+ </form>
18
+ );
19
+ };
20
+ export default Save;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+
6
+ export const formSubmissionNotificationSuccess = [
7
+ 'core/form-submission-notification',
8
+ {
9
+ type: 'success',
10
+ },
11
+ [
12
+ [
13
+ 'core/paragraph',
14
+ {
15
+ content:
16
+ '<mark style="background-color:rgba(0, 0, 0, 0);color:#345C00" class="has-inline-color">' +
17
+ __( 'Your form has been submitted successfully' ) +
18
+ '</mark>',
19
+ },
20
+ ],
21
+ ],
22
+ ];
23
+ export const formSubmissionNotificationError = [
24
+ 'core/form-submission-notification',
25
+ {
26
+ type: 'error',
27
+ },
28
+ [
29
+ [
30
+ 'core/paragraph',
31
+ {
32
+ content:
33
+ '<mark style="background-color:rgba(0, 0, 0, 0);color:#CF2E2E" class="has-inline-color">' +
34
+ __( 'There was an error submitting your form.' ) +
35
+ '</mark>',
36
+ },
37
+ ],
38
+ ],
39
+ ];
@@ -0,0 +1,139 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ /**
6
+ * Internal dependencies
7
+ */
8
+ import {
9
+ formSubmissionNotificationSuccess,
10
+ formSubmissionNotificationError,
11
+ } from './utils.js';
12
+
13
+ const variations = [
14
+ {
15
+ name: 'comment-form',
16
+ title: __( 'Experimental Comment form' ),
17
+ description: __( 'A comment form for posts and pages.' ),
18
+ attributes: {
19
+ submissionMethod: 'custom',
20
+ action: '{SITE_URL}/wp-comments-post.php',
21
+ method: 'post',
22
+ anchor: 'comment-form',
23
+ },
24
+ isDefault: false,
25
+ innerBlocks: [
26
+ [
27
+ 'core/form-input',
28
+ {
29
+ type: 'text',
30
+ name: 'author',
31
+ label: __( 'Name' ),
32
+ required: true,
33
+ visibilityPermissions: 'logged-out',
34
+ },
35
+ ],
36
+ [
37
+ 'core/form-input',
38
+ {
39
+ type: 'email',
40
+ name: 'email',
41
+ label: __( 'Email' ),
42
+ required: true,
43
+ visibilityPermissions: 'logged-out',
44
+ },
45
+ ],
46
+ [
47
+ 'core/form-input',
48
+ {
49
+ type: 'textarea',
50
+ name: 'comment',
51
+ label: __( 'Comment' ),
52
+ required: true,
53
+ visibilityPermissions: 'all',
54
+ },
55
+ ],
56
+ [ 'core/form-submit-button', {} ],
57
+ ],
58
+ scope: [ 'inserter', 'transform' ],
59
+ isActive: ( blockAttributes ) =>
60
+ ! blockAttributes?.type || blockAttributes?.type === 'text',
61
+ },
62
+ {
63
+ name: 'wp-privacy-form',
64
+ title: __( 'Experimental privacy request form' ),
65
+ keywords: [ 'GDPR' ],
66
+ description: __( 'A form to request data exports and/or deletion.' ),
67
+ attributes: {
68
+ submissionMethod: 'custom',
69
+ action: '',
70
+ method: 'post',
71
+ anchor: 'gdpr-form',
72
+ },
73
+ isDefault: false,
74
+ innerBlocks: [
75
+ formSubmissionNotificationSuccess,
76
+ formSubmissionNotificationError,
77
+ [
78
+ 'core/paragraph',
79
+ {
80
+ content: __(
81
+ 'To request an export or deletion of your personal data on this site, please fill-in the form below. You can define the type of request you wish to perform, and your email address. Once the form is submitted, you will receive a confirmation email with instructions on the next steps.'
82
+ ),
83
+ },
84
+ ],
85
+ [
86
+ 'core/form-input',
87
+ {
88
+ type: 'email',
89
+ name: 'email',
90
+ label: __( 'Enter your email address.' ),
91
+ required: true,
92
+ visibilityPermissions: 'all',
93
+ },
94
+ ],
95
+ [
96
+ 'core/form-input',
97
+ {
98
+ type: 'checkbox',
99
+ name: 'export_personal_data',
100
+ label: __( 'Request data export' ),
101
+ required: false,
102
+ visibilityPermissions: 'all',
103
+ },
104
+ ],
105
+ [
106
+ 'core/form-input',
107
+ {
108
+ type: 'checkbox',
109
+ name: 'remove_personal_data',
110
+ label: __( 'Request data deletion' ),
111
+ required: false,
112
+ visibilityPermissions: 'all',
113
+ },
114
+ ],
115
+ [ 'core/form-submit-button', {} ],
116
+ [
117
+ 'core/form-input',
118
+ {
119
+ type: 'hidden',
120
+ name: 'wp-action',
121
+ value: 'wp_privacy_send_request',
122
+ },
123
+ ],
124
+ [
125
+ 'core/form-input',
126
+ {
127
+ type: 'hidden',
128
+ name: 'wp-privacy-request',
129
+ value: '1',
130
+ },
131
+ ],
132
+ ],
133
+ scope: [ 'inserter', 'transform' ],
134
+ isActive: ( blockAttributes ) =>
135
+ ! blockAttributes?.type || blockAttributes?.type === 'text',
136
+ },
137
+ ];
138
+
139
+ export default variations;
@@ -0,0 +1,41 @@
1
+ // eslint-disable-next-line eslint-comments/disable-enable-pair
2
+ /* eslint-disable no-undef */
3
+ document.querySelectorAll( 'form.wp-block-form' ).forEach( function ( form ) {
4
+ // Bail If the form is not using the mailto: action.
5
+ if ( ! form.action || ! form.action.startsWith( 'mailto:' ) ) {
6
+ return;
7
+ }
8
+
9
+ const redirectNotification = ( status ) => {
10
+ const urlParams = new URLSearchParams( window.location.search );
11
+ urlParams.append( 'wp-form-result', status );
12
+ window.location.search = urlParams.toString();
13
+ };
14
+
15
+ // Add an event listener for the form submission.
16
+ form.addEventListener( 'submit', async function ( event ) {
17
+ event.preventDefault();
18
+ // Get the form data and merge it with the form action and nonce.
19
+ const formData = Object.fromEntries( new FormData( form ).entries() );
20
+ formData.formAction = form.action;
21
+ formData._ajax_nonce = wpBlockFormSettings.nonce;
22
+ formData.action = wpBlockFormSettings.action;
23
+
24
+ try {
25
+ const response = await fetch( wpBlockFormSettings.ajaxUrl, {
26
+ method: 'POST',
27
+ headers: {
28
+ 'Content-Type': 'application/x-www-form-urlencoded',
29
+ },
30
+ body: new URLSearchParams( formData ).toString(),
31
+ } );
32
+ if ( response.ok ) {
33
+ redirectNotification( 'success' );
34
+ } else {
35
+ redirectNotification( 'error' );
36
+ }
37
+ } catch ( error ) {
38
+ redirectNotification( 'error' );
39
+ }
40
+ } );
41
+ } );
@@ -0,0 +1,73 @@
1
+ {
2
+ "$schema": "https://schemas.wp.org/trunk/block.json",
3
+ "apiVersion": 3,
4
+ "__experimental": true,
5
+ "name": "core/form-input",
6
+ "title": "Input Field",
7
+ "category": "common",
8
+ "parent": [ "core/form" ],
9
+ "description": "The basic building block for forms.",
10
+ "keywords": [ "input", "form" ],
11
+ "textdomain": "default",
12
+ "icon": "forms",
13
+ "attributes": {
14
+ "type": {
15
+ "type": "string",
16
+ "default": "text"
17
+ },
18
+ "name": {
19
+ "type": "string"
20
+ },
21
+ "label": {
22
+ "type": "string",
23
+ "default": "Label",
24
+ "selector": ".wp-block-form-input__label-content",
25
+ "source": "html",
26
+ "__experimentalRole": "content"
27
+ },
28
+ "inlineLabel": {
29
+ "type": "boolean",
30
+ "default": false
31
+ },
32
+ "required": {
33
+ "type": "boolean",
34
+ "default": false,
35
+ "selector": ".wp-block-form-input__input",
36
+ "source": "attribute",
37
+ "attribute": "required"
38
+ },
39
+ "placeholder": {
40
+ "type": "string",
41
+ "selector": ".wp-block-form-input__input",
42
+ "source": "attribute",
43
+ "attribute": "placeholder",
44
+ "__experimentalRole": "content"
45
+ },
46
+ "value": {
47
+ "type": "string",
48
+ "default": "",
49
+ "selector": "input",
50
+ "source": "attribute",
51
+ "attribute": "value"
52
+ },
53
+ "visibilityPermissions": {
54
+ "type": "string",
55
+ "default": "all"
56
+ }
57
+ },
58
+ "supports": {
59
+ "anchor": true,
60
+ "reusable": false,
61
+ "spacing": {
62
+ "margin": [ "top", "bottom" ]
63
+ },
64
+ "__experimentalBorder": {
65
+ "radius": true,
66
+ "__experimentalSkipSerialization": true,
67
+ "__experimentalDefaultControls": {
68
+ "radius": true
69
+ }
70
+ }
71
+ },
72
+ "style": [ "wp-block-form-input" ]
73
+ }
@@ -0,0 +1,151 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classNames from 'classnames';
5
+
6
+ /**
7
+ * WordPress dependencies
8
+ */
9
+ import { __ } from '@wordpress/i18n';
10
+ import {
11
+ InspectorControls,
12
+ RichText,
13
+ useBlockProps,
14
+ __experimentalUseBorderProps as useBorderProps,
15
+ __experimentalUseColorProps as useColorProps,
16
+ } from '@wordpress/block-editor';
17
+ import { PanelBody, TextControl, CheckboxControl } from '@wordpress/components';
18
+
19
+ import { useRef } from '@wordpress/element';
20
+
21
+ function InputFieldBlock( { attributes, setAttributes, className } ) {
22
+ const { type, name, label, inlineLabel, required, placeholder, value } =
23
+ attributes;
24
+ const blockProps = useBlockProps();
25
+ const ref = useRef();
26
+ const TagName = type === 'textarea' ? 'textarea' : 'input';
27
+
28
+ const borderProps = useBorderProps( attributes );
29
+ const colorProps = useColorProps( attributes );
30
+ if ( ref.current ) {
31
+ ref.current.focus();
32
+ }
33
+
34
+ const controls = (
35
+ <>
36
+ { 'hidden' !== type && (
37
+ <InspectorControls>
38
+ <PanelBody title={ __( 'Input settings' ) }>
39
+ { 'checkbox' !== type && (
40
+ <CheckboxControl
41
+ label={ __( 'Inline label' ) }
42
+ checked={ inlineLabel }
43
+ onChange={ ( newVal ) => {
44
+ setAttributes( {
45
+ inlineLabel: newVal,
46
+ } );
47
+ } }
48
+ />
49
+ ) }
50
+ <CheckboxControl
51
+ label={ __( 'Required' ) }
52
+ checked={ required }
53
+ onChange={ ( newVal ) => {
54
+ setAttributes( {
55
+ required: newVal,
56
+ } );
57
+ } }
58
+ />
59
+ </PanelBody>
60
+ </InspectorControls>
61
+ ) }
62
+ <InspectorControls __experimentalGroup="advanced">
63
+ <TextControl
64
+ autoComplete="off"
65
+ label={ __( 'Name' ) }
66
+ value={ name }
67
+ onChange={ ( newVal ) => {
68
+ setAttributes( {
69
+ name: newVal,
70
+ } );
71
+ } }
72
+ help={ __(
73
+ 'Affects the "name" atribute of the input element, and is used as a name for the form submission results.'
74
+ ) }
75
+ />
76
+ </InspectorControls>
77
+ </>
78
+ );
79
+
80
+ if ( 'hidden' === type ) {
81
+ return (
82
+ <>
83
+ { controls }
84
+ <input
85
+ type="hidden"
86
+ className={ classNames(
87
+ className,
88
+ 'wp-block-form-input__input',
89
+ colorProps.className,
90
+ borderProps.className
91
+ ) }
92
+ aria-label={ __( 'Value' ) }
93
+ value={ value }
94
+ onChange={ ( event ) =>
95
+ setAttributes( { value: event.target.value } )
96
+ }
97
+ />
98
+ </>
99
+ );
100
+ }
101
+
102
+ return (
103
+ <div { ...blockProps }>
104
+ { controls }
105
+ <span
106
+ className={ classNames( 'wp-block-form-input__label', {
107
+ 'is-label-inline': inlineLabel || 'checkbox' === type,
108
+ } ) }
109
+ >
110
+ <RichText
111
+ tagName="span"
112
+ className="wp-block-form-input__label-content"
113
+ value={ label }
114
+ onChange={ ( newLabel ) =>
115
+ setAttributes( { label: newLabel } )
116
+ }
117
+ aria-label={ label ? __( 'Label' ) : __( 'Empty label' ) }
118
+ data-empty={ label ? false : true }
119
+ placeholder={ __( 'Type the label for this input' ) }
120
+ />
121
+ <TagName
122
+ type={ 'textarea' === type ? undefined : type }
123
+ className={ classNames(
124
+ className,
125
+ 'wp-block-form-input__input',
126
+ colorProps.className,
127
+ borderProps.className
128
+ ) }
129
+ aria-label={ __( 'Optional placeholder text' ) }
130
+ // We hide the placeholder field's placeholder when there is a value. This
131
+ // stops screen readers from reading the placeholder field's placeholder
132
+ // which is confusing.
133
+ placeholder={
134
+ placeholder ? undefined : __( 'Optional placeholder…' )
135
+ }
136
+ value={ placeholder }
137
+ onChange={ ( event ) =>
138
+ setAttributes( { placeholder: event.target.value } )
139
+ }
140
+ aria-required={ required }
141
+ style={ {
142
+ ...borderProps.style,
143
+ ...colorProps.style,
144
+ } }
145
+ />
146
+ </span>
147
+ </div>
148
+ );
149
+ }
150
+
151
+ export default InputFieldBlock;