@wordpress/block-library 8.20.0 → 8.21.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 (277) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +12 -0
  3. package/build/block/index.js +2 -1
  4. package/build/block/index.js.map +1 -1
  5. package/build/code/edit.native.js +8 -2
  6. package/build/code/edit.native.js.map +1 -1
  7. package/build/cover/deprecated.js +110 -1
  8. package/build/cover/deprecated.js.map +1 -1
  9. package/build/cover/edit/index.js +9 -3
  10. package/build/cover/edit/index.js.map +1 -1
  11. package/build/cover/edit/inspector-controls.js +1 -2
  12. package/build/cover/edit/inspector-controls.js.map +1 -1
  13. package/build/cover/index.js +0 -3
  14. package/build/cover/index.js.map +1 -1
  15. package/build/cover/save.js +2 -1
  16. package/build/cover/save.js.map +1 -1
  17. package/build/cover/shared.js +1 -1
  18. package/build/cover/shared.js.map +1 -1
  19. package/build/footnotes/index.js +1 -0
  20. package/build/footnotes/index.js.map +1 -1
  21. package/build/form/edit.js +138 -0
  22. package/build/form/edit.js.map +1 -0
  23. package/build/form/index.js +92 -0
  24. package/build/form/index.js.map +1 -0
  25. package/build/form/init.js +13 -0
  26. package/build/form/init.js.map +1 -0
  27. package/build/form/save.js +28 -0
  28. package/build/form/save.js.map +1 -0
  29. package/build/form/utils.js +24 -0
  30. package/build/form/utils.js.map +1 -0
  31. package/build/form/variations.js +95 -0
  32. package/build/form/variations.js.map +1 -0
  33. package/build/form/view.js +42 -0
  34. package/build/form/view.js.map +1 -0
  35. package/build/form-input/edit.js +124 -0
  36. package/build/form-input/edit.js.map +1 -0
  37. package/build/form-input/index.js +105 -0
  38. package/build/form-input/index.js.map +1 -0
  39. package/build/form-input/init.js +13 -0
  40. package/build/form-input/init.js.map +1 -0
  41. package/build/form-input/save.js +87 -0
  42. package/build/form-input/save.js.map +1 -0
  43. package/build/form-input/variations.js +93 -0
  44. package/build/form-input/variations.js.map +1 -0
  45. package/build/form-submission-notification/edit.js +59 -0
  46. package/build/form-submission-notification/edit.js.map +1 -0
  47. package/build/form-submission-notification/index.js +56 -0
  48. package/build/form-submission-notification/index.js.map +1 -0
  49. package/build/form-submission-notification/init.js +13 -0
  50. package/build/form-submission-notification/init.js.map +1 -0
  51. package/build/form-submission-notification/save.js +33 -0
  52. package/build/form-submission-notification/save.js.map +1 -0
  53. package/build/form-submission-notification/variations.js +63 -0
  54. package/build/form-submission-notification/variations.js.map +1 -0
  55. package/build/form-submit-button/edit.js +32 -0
  56. package/build/form-submit-button/edit.js.map +1 -0
  57. package/build/form-submit-button/index.js +44 -0
  58. package/build/form-submit-button/index.js.map +1 -0
  59. package/build/form-submit-button/init.js +13 -0
  60. package/build/form-submit-button/init.js.map +1 -0
  61. package/build/form-submit-button/save.js +22 -0
  62. package/build/form-submit-button/save.js.map +1 -0
  63. package/build/group/index.js +0 -1
  64. package/build/group/index.js.map +1 -1
  65. package/build/heading/index.js +3 -2
  66. package/build/heading/index.js.map +1 -1
  67. package/build/image/image.js +4 -1
  68. package/build/image/image.js.map +1 -1
  69. package/build/image/view.js +82 -40
  70. package/build/image/view.js.map +1 -1
  71. package/build/index.js +10 -0
  72. package/build/index.js.map +1 -1
  73. package/build/latest-posts/edit.js +6 -2
  74. package/build/latest-posts/edit.js.map +1 -1
  75. package/build/list-item/hooks/use-merge.js +15 -15
  76. package/build/list-item/hooks/use-merge.js.map +1 -1
  77. package/build/lock-unlock.js +1 -1
  78. package/build/lock-unlock.js.map +1 -1
  79. package/build/missing/edit.native.js +14 -62
  80. package/build/missing/edit.native.js.map +1 -1
  81. package/build/navigation/edit/index.js +0 -1
  82. package/build/navigation/edit/index.js.map +1 -1
  83. package/build/navigation/index.js +2 -1
  84. package/build/navigation/index.js.map +1 -1
  85. package/build/navigation/view.js +27 -5
  86. package/build/navigation/view.js.map +1 -1
  87. package/build/page-list-item/edit.js +3 -1
  88. package/build/page-list-item/edit.js.map +1 -1
  89. package/build/paragraph/index.js +7 -0
  90. package/build/paragraph/index.js.map +1 -1
  91. package/build/pattern/index.js +2 -1
  92. package/build/pattern/index.js.map +1 -1
  93. package/build/template-part/index.js +2 -1
  94. package/build/template-part/index.js.map +1 -1
  95. package/build-module/block/index.js +2 -1
  96. package/build-module/block/index.js.map +1 -1
  97. package/build-module/code/edit.native.js +8 -2
  98. package/build-module/code/edit.native.js.map +1 -1
  99. package/build-module/cover/deprecated.js +110 -1
  100. package/build-module/cover/deprecated.js.map +1 -1
  101. package/build-module/cover/edit/index.js +9 -3
  102. package/build-module/cover/edit/index.js.map +1 -1
  103. package/build-module/cover/edit/inspector-controls.js +1 -2
  104. package/build-module/cover/edit/inspector-controls.js.map +1 -1
  105. package/build-module/cover/index.js +0 -3
  106. package/build-module/cover/index.js.map +1 -1
  107. package/build-module/cover/save.js +2 -1
  108. package/build-module/cover/save.js.map +1 -1
  109. package/build-module/cover/shared.js +1 -1
  110. package/build-module/cover/shared.js.map +1 -1
  111. package/build-module/footnotes/index.js +1 -0
  112. package/build-module/footnotes/index.js.map +1 -1
  113. package/build-module/form/edit.js +130 -0
  114. package/build-module/form/edit.js.map +1 -0
  115. package/build-module/form/index.js +82 -0
  116. package/build-module/form/index.js.map +1 -0
  117. package/build-module/form/init.js +6 -0
  118. package/build-module/form/init.js.map +1 -0
  119. package/build-module/form/save.js +20 -0
  120. package/build-module/form/save.js.map +1 -0
  121. package/build-module/form/utils.js +15 -0
  122. package/build-module/form/utils.js.map +1 -0
  123. package/build-module/form/variations.js +86 -0
  124. package/build-module/form/variations.js.map +1 -0
  125. package/build-module/form/view.js +40 -0
  126. package/build-module/form/view.js.map +1 -0
  127. package/build-module/form-input/edit.js +115 -0
  128. package/build-module/form-input/edit.js.map +1 -0
  129. package/build-module/form-input/index.js +95 -0
  130. package/build-module/form-input/index.js.map +1 -0
  131. package/build-module/form-input/init.js +6 -0
  132. package/build-module/form-input/init.js.map +1 -0
  133. package/build-module/form-input/save.js +80 -0
  134. package/build-module/form-input/save.js.map +1 -0
  135. package/build-module/form-input/variations.js +85 -0
  136. package/build-module/form-input/variations.js.map +1 -0
  137. package/build-module/form-submission-notification/edit.js +50 -0
  138. package/build-module/form-submission-notification/edit.js.map +1 -0
  139. package/build-module/form-submission-notification/index.js +47 -0
  140. package/build-module/form-submission-notification/index.js.map +1 -0
  141. package/build-module/form-submission-notification/init.js +6 -0
  142. package/build-module/form-submission-notification/init.js.map +1 -0
  143. package/build-module/form-submission-notification/save.js +25 -0
  144. package/build-module/form-submission-notification/save.js.map +1 -0
  145. package/build-module/form-submission-notification/variations.js +55 -0
  146. package/build-module/form-submission-notification/variations.js.map +1 -0
  147. package/build-module/form-submit-button/edit.js +24 -0
  148. package/build-module/form-submit-button/edit.js.map +1 -0
  149. package/build-module/form-submit-button/index.js +34 -0
  150. package/build-module/form-submit-button/index.js.map +1 -0
  151. package/build-module/form-submit-button/init.js +6 -0
  152. package/build-module/form-submit-button/init.js.map +1 -0
  153. package/build-module/form-submit-button/save.js +14 -0
  154. package/build-module/form-submit-button/save.js.map +1 -0
  155. package/build-module/group/index.js +0 -1
  156. package/build-module/group/index.js.map +1 -1
  157. package/build-module/heading/index.js +3 -2
  158. package/build-module/heading/index.js.map +1 -1
  159. package/build-module/image/image.js +4 -1
  160. package/build-module/image/image.js.map +1 -1
  161. package/build-module/image/view.js +82 -40
  162. package/build-module/image/view.js.map +1 -1
  163. package/build-module/index.js +10 -0
  164. package/build-module/index.js.map +1 -1
  165. package/build-module/latest-posts/edit.js +6 -2
  166. package/build-module/latest-posts/edit.js.map +1 -1
  167. package/build-module/list-item/hooks/use-merge.js +15 -15
  168. package/build-module/list-item/hooks/use-merge.js.map +1 -1
  169. package/build-module/lock-unlock.js +1 -1
  170. package/build-module/lock-unlock.js.map +1 -1
  171. package/build-module/missing/edit.native.js +17 -65
  172. package/build-module/missing/edit.native.js.map +1 -1
  173. package/build-module/navigation/edit/index.js +0 -1
  174. package/build-module/navigation/edit/index.js.map +1 -1
  175. package/build-module/navigation/index.js +2 -1
  176. package/build-module/navigation/index.js.map +1 -1
  177. package/build-module/navigation/view.js +27 -5
  178. package/build-module/navigation/view.js.map +1 -1
  179. package/build-module/page-list-item/edit.js +3 -1
  180. package/build-module/page-list-item/edit.js.map +1 -1
  181. package/build-module/paragraph/index.js +7 -0
  182. package/build-module/paragraph/index.js.map +1 -1
  183. package/build-module/pattern/index.js +2 -1
  184. package/build-module/pattern/index.js.map +1 -1
  185. package/build-module/template-part/index.js +2 -1
  186. package/build-module/template-part/index.js.map +1 -1
  187. package/build-style/editor-rtl.css +50 -0
  188. package/build-style/editor.css +50 -0
  189. package/build-style/form-input/editor-rtl.css +106 -0
  190. package/build-style/form-input/editor.css +106 -0
  191. package/build-style/form-input/style-rtl.css +135 -0
  192. package/build-style/form-input/style.css +135 -0
  193. package/build-style/form-submission-notification/editor-rtl.css +118 -0
  194. package/build-style/form-submission-notification/editor.css +118 -0
  195. package/build-style/form-submit-button/style-rtl.css +91 -0
  196. package/build-style/form-submit-button/style.css +91 -0
  197. package/build-style/image/style-rtl.css +39 -5
  198. package/build-style/image/style.css +39 -5
  199. package/build-style/query/style-rtl.css +0 -10
  200. package/build-style/query/style.css +0 -10
  201. package/build-style/style-rtl.css +87 -5
  202. package/build-style/style.css +87 -5
  203. package/package.json +32 -32
  204. package/src/block/block.json +2 -1
  205. package/src/code/edit.native.js +15 -1
  206. package/src/cover/block.json +0 -3
  207. package/src/cover/deprecated.js +151 -1
  208. package/src/cover/edit/index.js +12 -3
  209. package/src/cover/edit/inspector-controls.js +19 -25
  210. package/src/cover/save.js +2 -1
  211. package/src/cover/shared.js +1 -1
  212. package/src/editor.scss +2 -0
  213. package/src/footnotes/block.json +1 -0
  214. package/src/form/block.json +60 -0
  215. package/src/form/edit.js +179 -0
  216. package/src/form/index.js +20 -0
  217. package/src/form/index.php +214 -0
  218. package/src/form/init.js +6 -0
  219. package/src/form/save.js +20 -0
  220. package/src/form/utils.js +39 -0
  221. package/src/form/variations.js +139 -0
  222. package/src/form/view.js +41 -0
  223. package/src/form-input/block.json +73 -0
  224. package/src/form-input/edit.js +151 -0
  225. package/src/form-input/editor.scss +24 -0
  226. package/src/form-input/index.js +20 -0
  227. package/src/form-input/index.php +45 -0
  228. package/src/form-input/init.js +6 -0
  229. package/src/form-input/save.js +83 -0
  230. package/src/form-input/style.scss +61 -0
  231. package/src/form-input/variations.js +82 -0
  232. package/src/form-submission-notification/block.json +19 -0
  233. package/src/form-submission-notification/edit.js +63 -0
  234. package/src/form-submission-notification/editor.scss +45 -0
  235. package/src/form-submission-notification/index.js +26 -0
  236. package/src/form-submission-notification/index.php +48 -0
  237. package/src/form-submission-notification/init.js +6 -0
  238. package/src/form-submission-notification/save.js +28 -0
  239. package/src/form-submission-notification/variations.js +59 -0
  240. package/src/form-submit-button/block.json +14 -0
  241. package/src/form-submit-button/edit.js +33 -0
  242. package/src/form-submit-button/index.js +18 -0
  243. package/src/form-submit-button/init.js +6 -0
  244. package/src/form-submit-button/save.js +14 -0
  245. package/src/form-submit-button/style.scss +3 -0
  246. package/src/group/block.json +0 -1
  247. package/src/heading/index.js +4 -2
  248. package/src/image/image.js +10 -0
  249. package/src/image/index.php +128 -82
  250. package/src/image/style.scss +49 -5
  251. package/src/image/view.js +100 -52
  252. package/src/index.js +10 -0
  253. package/src/latest-posts/edit.js +11 -2
  254. package/src/latest-posts/index.php +17 -8
  255. package/src/list-item/hooks/use-merge.js +20 -23
  256. package/src/lock-unlock.js +1 -1
  257. package/src/missing/edit.native.js +17 -115
  258. package/src/missing/style.native.scss +0 -67
  259. package/src/missing/test/edit-integration.native.js +135 -49
  260. package/src/missing/test/edit.native.js +0 -41
  261. package/src/navigation/block.json +2 -1
  262. package/src/navigation/edit/index.js +0 -1
  263. package/src/navigation/index.php +28 -8
  264. package/src/navigation/view.js +25 -6
  265. package/src/page-list-item/edit.js +2 -0
  266. package/src/paragraph/index.js +10 -0
  267. package/src/pattern/block.json +2 -1
  268. package/src/pattern/index.php +0 -3
  269. package/src/post-navigation-link/index.php +2 -1
  270. package/src/preformatted/test/edit.native.js +38 -0
  271. package/src/query/index.php +3 -2
  272. package/src/query/style.scss +0 -11
  273. package/src/search/index.php +0 -4
  274. package/src/style.scss +1 -0
  275. package/src/template-part/block.json +2 -1
  276. package/src/template-part/index.php +4 -7
  277. package/src/verse/test/edit.native.js +37 -0
@@ -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;
@@ -0,0 +1,24 @@
1
+ .wp-block-form-input {
2
+ .is-input-hidden {
3
+ font-size: 0.85em;
4
+ opacity: 0.3;
5
+ border: 1px dashed;
6
+ padding: 0.5em;
7
+ box-sizing: border-box;
8
+ background: repeating-linear-gradient(45deg, transparent, transparent 5px, currentColor 5px, currentColor 6px);
9
+
10
+ input[type="text"] {
11
+ background: transparent;
12
+ }
13
+ }
14
+ &.is-selected {
15
+ .is-input-hidden {
16
+ opacity: 1;
17
+ background: none;
18
+
19
+ input[type="text"] {
20
+ background: unset;
21
+ }
22
+ }
23
+ }
24
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import initBlock from '../utils/init-block';
5
+ import edit from './edit';
6
+ import metadata from './block.json';
7
+ import save from './save';
8
+ import variations from './variations';
9
+
10
+ const { name } = metadata;
11
+
12
+ export { metadata, name };
13
+
14
+ export const settings = {
15
+ edit,
16
+ save,
17
+ variations,
18
+ };
19
+
20
+ export const init = () => initBlock( { name, metadata, settings } );
@@ -0,0 +1,45 @@
1
+ <?php
2
+ /**
3
+ * Server-side rendering of the `core/form-input` block.
4
+ *
5
+ * @package WordPress
6
+ */
7
+
8
+ /**
9
+ * Renders the `core/form-input` 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_input( $attributes, $content ) {
17
+ $visibility_permissions = 'all';
18
+ if ( isset( $attributes['visibilityPermissions'] ) ) {
19
+ $visibility_permissions = $attributes['visibilityPermissions'];
20
+ }
21
+
22
+ if ( 'logged-in' === $visibility_permissions && ! is_user_logged_in() ) {
23
+ return '';
24
+ }
25
+ if ( 'logged-out' === $visibility_permissions && is_user_logged_in() ) {
26
+ return '';
27
+ }
28
+ return $content;
29
+ }
30
+
31
+ /**
32
+ * Registers the `core/form-input` block on server.
33
+ */
34
+ function register_block_core_form_input() {
35
+ if ( ! gutenberg_is_experiment_enabled( 'gutenberg-form-blocks' ) ) {
36
+ return;
37
+ }
38
+ register_block_type_from_metadata(
39
+ __DIR__ . '/form-input',
40
+ array(
41
+ 'render_callback' => 'render_block_core_form_input',
42
+ )
43
+ );
44
+ }
45
+ add_action( 'init', 'register_block_core_form_input' );
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Internal dependencies
3
+ */
4
+ import { init } from './';
5
+
6
+ export default init();
@@ -0,0 +1,83 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classNames from 'classnames';
5
+ import removeAccents from 'remove-accents';
6
+
7
+ /**
8
+ * WordPress dependencies
9
+ */
10
+ import {
11
+ RichText,
12
+ __experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
13
+ __experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
14
+ } from '@wordpress/block-editor';
15
+
16
+ /**
17
+ * Get the name attribute from a content string.
18
+ *
19
+ * @param {string} content The block content.
20
+ *
21
+ * @return {string} Returns the slug.
22
+ */
23
+ const getNameFromLabel = ( content ) => {
24
+ const dummyElement = document.createElement( 'div' );
25
+ dummyElement.innerHTML = content;
26
+ // Get the slug.
27
+ return (
28
+ removeAccents( dummyElement.innerText )
29
+ // Convert anything that's not a letter or number to a hyphen.
30
+ .replace( /[^\p{L}\p{N}]+/gu, '-' )
31
+ // Convert to lowercase
32
+ .toLowerCase()
33
+ // Remove any remaining leading or trailing hyphens.
34
+ .replace( /(^-+)|(-+$)/g, '' )
35
+ );
36
+ };
37
+
38
+ export default function save( { attributes } ) {
39
+ const { type, name, label, inlineLabel, required, placeholder, value } =
40
+ attributes;
41
+
42
+ const borderProps = getBorderClassesAndStyles( attributes );
43
+ const colorProps = getColorClassesAndStyles( attributes );
44
+
45
+ const inputStyle = {
46
+ ...borderProps.style,
47
+ ...colorProps.style,
48
+ };
49
+
50
+ const inputClasses = classNames(
51
+ 'wp-block-form-input__input',
52
+ colorProps.className,
53
+ borderProps.className
54
+ );
55
+ const TagName = type === 'textarea' ? 'textarea' : 'input';
56
+
57
+ if ( 'hidden' === type ) {
58
+ return <input type={ type } name={ name } value={ value } />;
59
+ }
60
+
61
+ /* eslint-disable jsx-a11y/label-has-associated-control */
62
+ return (
63
+ <label
64
+ className={ classNames( 'wp-block-form-input__label', {
65
+ 'is-label-inline': inlineLabel,
66
+ } ) }
67
+ >
68
+ <span className="wp-block-form-input__label-content">
69
+ <RichText.Content value={ label } />
70
+ </span>
71
+ <TagName
72
+ className={ inputClasses }
73
+ type={ 'textarea' === type ? undefined : type }
74
+ name={ name || getNameFromLabel( label ) }
75
+ required={ required }
76
+ aria-required={ required }
77
+ placeholder={ placeholder || undefined }
78
+ style={ inputStyle }
79
+ />
80
+ </label>
81
+ );
82
+ /* eslint-enable jsx-a11y/label-has-associated-control */
83
+ }
@@ -0,0 +1,61 @@
1
+ .wp-block-form-input__label {
2
+ width: 100%;
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 0.25em;
6
+ margin-bottom: 0.5em;
7
+
8
+ &.is-label-inline {
9
+ flex-direction: row;
10
+ gap: 0.5em;
11
+ align-items: center;
12
+
13
+ .wp-block-form-input__label-content {
14
+ margin-bottom: 0.5em;
15
+ }
16
+ }
17
+
18
+ /*
19
+ Small tweak to left-align the checkbox.
20
+ Even though `:has` is not currently supported in Firefox, this is a small tweak
21
+ and does not affect the functionality of the block or the user's experience.
22
+ There will be a minor inconsistency between browsers. However, it's more important to provide
23
+ a better experience for 80+% of users, until Firefox catches up and supports `:has`.
24
+ */
25
+ &:has(input[type="checkbox"]) {
26
+ width: fit-content;
27
+ flex-direction: row-reverse;
28
+ }
29
+ }
30
+
31
+ .wp-block-form-input__label-content {
32
+ width: fit-content;
33
+ }
34
+
35
+ .wp-block-form-input__input {
36
+ padding: 0 0.5em;
37
+ font-size: 1em;
38
+ margin-bottom: 0.5em;
39
+
40
+ &[type="text"],
41
+ &[type="password"],
42
+ &[type="date"],
43
+ &[type="datetime"],
44
+ &[type="datetime-local"],
45
+ &[type="email"],
46
+ &[type="month"],
47
+ &[type="number"],
48
+ &[type="search"],
49
+ &[type="tel"],
50
+ &[type="time"],
51
+ &[type="url"],
52
+ &[type="week"] {
53
+ min-height: 2em;
54
+ line-height: 2;
55
+ border: 1px solid;
56
+ }
57
+ }
58
+
59
+ textarea.wp-block-form-input__input {
60
+ min-height: 10em;
61
+ }
@@ -0,0 +1,82 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+
6
+ const variations = [
7
+ {
8
+ name: 'text',
9
+ title: __( 'Text input' ),
10
+ icon: 'edit-page',
11
+ description: __( 'A generic text input.' ),
12
+ attributes: { type: 'text' },
13
+ isDefault: true,
14
+ scope: [ 'inserter', 'transform' ],
15
+ isActive: ( blockAttributes ) =>
16
+ ! blockAttributes?.type || blockAttributes?.type === 'text',
17
+ },
18
+ {
19
+ name: 'textarea',
20
+ title: __( 'Textarea input' ),
21
+ icon: 'testimonial',
22
+ description: __(
23
+ 'A textarea input to allow entering multiple lines of text.'
24
+ ),
25
+ attributes: { type: 'textarea' },
26
+ isDefault: true,
27
+ scope: [ 'inserter', 'transform' ],
28
+ isActive: ( blockAttributes ) => blockAttributes?.type === 'textarea',
29
+ },
30
+ {
31
+ name: 'checkbox',
32
+ title: __( 'Checkbox input' ),
33
+ description: __( 'A simple checkbox input.' ),
34
+ icon: 'forms',
35
+ attributes: { type: 'checkbox', inlineLabel: true },
36
+ isDefault: true,
37
+ scope: [ 'inserter', 'transform' ],
38
+ isActive: ( blockAttributes ) => blockAttributes?.type === 'checkbox',
39
+ },
40
+ {
41
+ name: 'email',
42
+ title: __( 'Email input' ),
43
+ icon: 'email',
44
+ description: __( 'Used for email addresses.' ),
45
+ attributes: { type: 'email' },
46
+ isDefault: true,
47
+ scope: [ 'inserter', 'transform' ],
48
+ isActive: ( blockAttributes ) => blockAttributes?.type === 'email',
49
+ },
50
+ {
51
+ name: 'url',
52
+ title: __( 'URL input' ),
53
+ icon: 'admin-site',
54
+ description: __( 'Used for URLs.' ),
55
+ attributes: { type: 'url' },
56
+ isDefault: true,
57
+ scope: [ 'inserter', 'transform' ],
58
+ isActive: ( blockAttributes ) => blockAttributes?.type === 'url',
59
+ },
60
+ {
61
+ name: 'tel',
62
+ title: __( 'Telephone input' ),
63
+ icon: 'phone',
64
+ description: __( 'Used for phone numbers.' ),
65
+ attributes: { type: 'tel' },
66
+ isDefault: true,
67
+ scope: [ 'inserter', 'transform' ],
68
+ isActive: ( blockAttributes ) => blockAttributes?.type === 'tel',
69
+ },
70
+ {
71
+ name: 'number',
72
+ title: __( 'Number input' ),
73
+ icon: 'edit-page',
74
+ description: __( 'A numeric input.' ),
75
+ attributes: { type: 'number' },
76
+ isDefault: true,
77
+ scope: [ 'inserter', 'transform' ],
78
+ isActive: ( blockAttributes ) => blockAttributes?.type === 'number',
79
+ },
80
+ ];
81
+
82
+ export default variations;
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "https://schemas.wp.org/trunk/block.json",
3
+ "apiVersion": 3,
4
+ "__experimental": true,
5
+ "name": "core/form-submission-notification",
6
+ "title": "Form Submission Notification",
7
+ "category": "common",
8
+ "parent": [ "core/form" ],
9
+ "description": "Provide a notification message after the form has been submitted.",
10
+ "keywords": [ "form", "feedback", "notification", "message" ],
11
+ "textdomain": "default",
12
+ "icon": "feedback",
13
+ "attributes": {
14
+ "type": {
15
+ "type": "string",
16
+ "default": "success"
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,63 @@
1
+ /**
2
+ * WordPress dependencies
3
+ */
4
+ import { __ } from '@wordpress/i18n';
5
+ import {
6
+ InnerBlocks,
7
+ useBlockProps,
8
+ useInnerBlocksProps,
9
+ store as blockEditorStore,
10
+ } from '@wordpress/block-editor';
11
+ import { useSelect } from '@wordpress/data';
12
+
13
+ /**
14
+ * External dependencies
15
+ */
16
+ import classnames from 'classnames';
17
+
18
+ const TEMPLATE = [
19
+ [
20
+ 'core/paragraph',
21
+ {
22
+ content: __(
23
+ "Enter the message you wish displayed for form submission error/success, and select the type of the message (success/error) from the block's options."
24
+ ),
25
+ },
26
+ ],
27
+ ];
28
+
29
+ const Edit = ( { attributes, clientId } ) => {
30
+ const { type } = attributes;
31
+ const blockProps = useBlockProps( {
32
+ className: classnames( 'wp-block-form-submission-notification', {
33
+ [ `form-notification-type-${ type }` ]: type,
34
+ } ),
35
+ } );
36
+
37
+ const { hasInnerBlocks } = useSelect(
38
+ ( select ) => {
39
+ const { getBlock } = select( blockEditorStore );
40
+ const block = getBlock( clientId );
41
+ return {
42
+ hasInnerBlocks: !! ( block && block.innerBlocks.length ),
43
+ };
44
+ },
45
+ [ clientId ]
46
+ );
47
+
48
+ const innerBlocksProps = useInnerBlocksProps( blockProps, {
49
+ template: TEMPLATE,
50
+ renderAppender: hasInnerBlocks
51
+ ? undefined
52
+ : InnerBlocks.ButtonBlockAppender,
53
+ } );
54
+
55
+ return (
56
+ <div
57
+ { ...innerBlocksProps }
58
+ data-message-success={ __( 'Submission success notification' ) }
59
+ data-message-error={ __( 'Submission error notification' ) }
60
+ />
61
+ );
62
+ };
63
+ export default Edit;