From cb1d87cc0a2807d8d4874fe7c4f09c5bb0bd0eb2 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Fri, 16 Sep 2022 10:23:17 +0300 Subject: [PATCH 001/133] Initial forms POC --- docs/reference-guides/core-blocks.md | 18 +++ packages/block-library/src/form/block.json | 10 ++ packages/block-library/src/form/edit.js | 14 ++ .../block-library/src/form/edit.native.js | 137 ++++++++++++++++++ packages/block-library/src/form/index.js | 18 +++ packages/block-library/src/form/init.js | 6 + packages/block-library/src/form/save.js | 14 ++ packages/block-library/src/index.js | 4 + .../block-library/src/input-field/block.json | 26 ++++ .../block-library/src/input-field/edit.js | 119 +++++++++++++++ .../block-library/src/input-field/index.js | 18 +++ .../block-library/src/input-field/save.js | 35 +++++ 12 files changed, 419 insertions(+) create mode 100644 packages/block-library/src/form/block.json create mode 100644 packages/block-library/src/form/edit.js create mode 100644 packages/block-library/src/form/edit.native.js create mode 100644 packages/block-library/src/form/index.js create mode 100644 packages/block-library/src/form/init.js create mode 100644 packages/block-library/src/form/save.js create mode 100644 packages/block-library/src/input-field/block.json create mode 100644 packages/block-library/src/input-field/edit.js create mode 100644 packages/block-library/src/input-field/index.js create mode 100644 packages/block-library/src/input-field/save.js diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index a7570bf590a397..907489e06d573e 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -277,6 +277,15 @@ Display footnotes added to the page. ([Source](https://github.com/WordPress/gute - **Supports:** color (background, link, text), spacing (margin, padding), typography (fontSize, lineHeight), ~~html~~, ~~multiple~~, ~~reusable~~ - **Attributes:** +## Form + +A form. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/form)) + +- **Name:** core/form +- **Category:** common +- **Supports:** +- **Attributes:** + ## Classic Use the classic WordPress editor. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/freeform)) @@ -341,6 +350,15 @@ Insert an image to make a visual statement. ([Source](https://github.com/WordPre - **Supports:** anchor, color (~~background~~, ~~text~~), filter (duotone) - **Attributes:** align, alt, aspectRatio, caption, height, href, id, lightbox, linkClass, linkDestination, linkTarget, rel, scale, sizeSlug, title, url, width +## Input field + +The basic building block for forms. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/input-field)) + +- **Name:** core/input-field +- **Category:** common +- **Supports:** +- **Attributes:** inlineLabel, label, type + ## Latest Comments Display a list of your most recent comments. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/latest-comments)) diff --git a/packages/block-library/src/form/block.json b/packages/block-library/src/form/block.json new file mode 100644 index 00000000000000..b9bdd98d5f6190 --- /dev/null +++ b/packages/block-library/src/form/block.json @@ -0,0 +1,10 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "core/form", + "title": "Form", + "category": "common", + "description": "A form.", + "keywords": [ "container", "wrapper", "row", "section" ], + "textdomain": "default" +} diff --git a/packages/block-library/src/form/edit.js b/packages/block-library/src/form/edit.js new file mode 100644 index 00000000000000..2bc463fcdde574 --- /dev/null +++ b/packages/block-library/src/form/edit.js @@ -0,0 +1,14 @@ +/** + * WordPress dependencies + */ +import { InnerBlocks, useBlockProps } from '@wordpress/block-editor'; + +const Edit = () => { + const blockProps = useBlockProps(); + return ( +
+ + + ); +}; +export default Edit; diff --git a/packages/block-library/src/form/edit.native.js b/packages/block-library/src/form/edit.native.js new file mode 100644 index 00000000000000..b04211b725a911 --- /dev/null +++ b/packages/block-library/src/form/edit.native.js @@ -0,0 +1,137 @@ +/** + * External dependencies + */ +import { View } from 'react-native'; + +/** + * WordPress dependencies + */ +import { withSelect } from '@wordpress/data'; +import { + compose, + withPreferredColorScheme, + useResizeObserver, +} from '@wordpress/compose'; +import { + InnerBlocks, + store as blockEditorStore, +} from '@wordpress/block-editor'; +import { useCallback } from '@wordpress/element'; +import { alignmentHelpers } from '@wordpress/components'; + +/** + * Internal dependencies + */ +import styles from './editor.scss'; + +const { isFullWidth } = alignmentHelpers; + +function GroupEdit( { + attributes, + hasInnerBlocks, + isSelected, + isLastInnerBlockSelected, + getStylesFromColorScheme, + style, + blockWidth, +} ) { + const { align } = attributes; + const [ resizeObserver, sizes ] = useResizeObserver(); + const { width } = sizes || { width: 0 }; + + const renderAppender = useCallback( + () => ( + + + + ), + [ align, hasInnerBlocks ] + ); + + if ( ! isSelected && ! hasInnerBlocks ) { + return ( + + ); + } + + return ( + + { resizeObserver } + + + ); +} + +export default compose( [ + withSelect( ( select, { clientId } ) => { + const { + getBlock, + getBlockIndex, + hasSelectedInnerBlock, + getBlockRootClientId, + getSelectedBlockClientId, + getBlockAttributes, + } = select( blockEditorStore ); + + const block = getBlock( clientId ); + const hasInnerBlocks = !! ( block && block.innerBlocks.length ); + const isInnerBlockSelected = + hasInnerBlocks && hasSelectedInnerBlock( clientId, true ); + let isLastInnerBlockSelected = false; + + if ( isInnerBlockSelected ) { + const { innerBlocks } = block; + const selectedBlockClientId = getSelectedBlockClientId(); + const totalInnerBlocks = innerBlocks.length - 1; + const blockIndex = getBlockIndex( selectedBlockClientId ); + isLastInnerBlockSelected = totalInnerBlocks === blockIndex; + } + + const parentId = getBlockRootClientId( clientId ); + const parentBlockAlignment = getBlockAttributes( parentId )?.align; + + return { + hasInnerBlocks, + isLastInnerBlockSelected, + parentBlockAlignment, + }; + } ), + withPreferredColorScheme, +] )( GroupEdit ); diff --git a/packages/block-library/src/form/index.js b/packages/block-library/src/form/index.js new file mode 100644 index 00000000000000..4c60b5f5c20639 --- /dev/null +++ b/packages/block-library/src/form/index.js @@ -0,0 +1,18 @@ +/** + * Internal dependencies + */ +import initBlock from '../utils/init-block'; +import edit from './edit'; +import metadata from './block.json'; +import save from './save'; + +const { name } = metadata; + +export { metadata, name }; + +export const settings = { + edit, + save, +}; + +export const init = () => initBlock( { name, metadata, settings } ); diff --git a/packages/block-library/src/form/init.js b/packages/block-library/src/form/init.js new file mode 100644 index 00000000000000..79f0492c2cb2f8 --- /dev/null +++ b/packages/block-library/src/form/init.js @@ -0,0 +1,6 @@ +/** + * Internal dependencies + */ +import { init } from './'; + +export default init(); diff --git a/packages/block-library/src/form/save.js b/packages/block-library/src/form/save.js new file mode 100644 index 00000000000000..72991db918c5e4 --- /dev/null +++ b/packages/block-library/src/form/save.js @@ -0,0 +1,14 @@ +/** + * WordPress dependencies + */ +import { InnerBlocks, useBlockProps } from '@wordpress/block-editor'; + +const Save = () => { + const blockProps = useBlockProps.save(); + return ( +
+ + + ); +}; +export default Save; diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index 736b552bf4259b..b9e9be4788a49d 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -48,12 +48,14 @@ import * as cover from './cover'; import * as details from './details'; import * as embed from './embed'; import * as file from './file'; +import * as form from './form'; import * as gallery from './gallery'; import * as group from './group'; import * as heading from './heading'; import * as homeLink from './home-link'; import * as html from './html'; import * as image from './image'; +import * as inputField from './input-field'; import * as latestComments from './latest-comments'; import * as latestPosts from './latest-posts'; import * as list from './list'; @@ -150,8 +152,10 @@ const getAllBlocks = () => { details, embed, file, + form, group, html, + inputField, latestComments, latestPosts, mediaText, diff --git a/packages/block-library/src/input-field/block.json b/packages/block-library/src/input-field/block.json new file mode 100644 index 00000000000000..2465312d7f437f --- /dev/null +++ b/packages/block-library/src/input-field/block.json @@ -0,0 +1,26 @@ +{ + "$schema": "https://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "core/input-field", + "title": "Input field", + "category": "common", + "parent": [ "core/form" ], + "description": "The basic building block for forms.", + "keywords": [ "input", "text", "textarea" ], + "textdomain": "default", + "attributes": { + "type": { + "type": "string", + "default": "text" + }, + "label": { + "type": "string", + "default": "Label" + }, + "inlineLabel": { + "type": "boolean", + "default": false + } + }, + "style": [ "wp-block-input-field" ] +} diff --git a/packages/block-library/src/input-field/edit.js b/packages/block-library/src/input-field/edit.js new file mode 100644 index 00000000000000..f8fab23c58e1c7 --- /dev/null +++ b/packages/block-library/src/input-field/edit.js @@ -0,0 +1,119 @@ +/** + * WordPress dependencies + */ +import { __ } from '@wordpress/i18n'; +import { InspectorControls } from '@wordpress/block-editor'; +import { + PanelBody, + CustomSelectControl, + TextControl, + CheckboxControl, +} from '@wordpress/components'; + +const inputTypeOptions = [ + { + key: 'text', + name: __( 'Text' ), + }, + { + key: 'textarea', + name: __( 'Textarea' ), + }, + { + key: 'email', + name: __( 'Email' ), + }, + { + key: 'url', + name: __( 'URL' ), + }, + { + key: 'tel', + name: __( 'Telephone' ), + }, + { + key: 'number', + name: __( 'Number' ), + }, + { + key: 'datetime-local', + name: __( 'Date and time' ), + }, + { + key: 'submit', + name: __( 'Submit' ), + }, +]; + +function InputFieldBlock( { attributes, setAttributes } ) { + const { type, label, inlineLabel } = attributes; + + return ( + <> + + + option.key === type + ) } + options={ inputTypeOptions } + onChange={ ( newVal ) => { + setAttributes( { + type: newVal?.selectedItem?.key, + } ); + } } + /> + { + setAttributes( { + label: newVal, + } ); + } } + /> + { + setAttributes( { + inlineLabel: newVal, + } ); + } } + /> + + + + { type === 'textarea' && ( + + + + +
+ + diff --git a/test/integration/fixtures/blocks/core__form.json b/test/integration/fixtures/blocks/core__form.json new file mode 100644 index 00000000000000..0c9f29ac87ee0c --- /dev/null +++ b/test/integration/fixtures/blocks/core__form.json @@ -0,0 +1,68 @@ +[ + { + "name": "core/form", + "isValid": true, + "attributes": { + "action": "#", + "method": "post", + "formId": "the-form-id" + }, + "innerBlocks": [ + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "text", + "label": "Name - required, inline label", + "inlineLabel": true, + "required": true + }, + "innerBlocks": [] + }, + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "checkbox", + "label": "Checkbox - inline label", + "inlineLabel": true, + "required": true + }, + "innerBlocks": [] + }, + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "email", + "label": "Email - required", + "inlineLabel": false, + "required": true + }, + "innerBlocks": [] + }, + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "textarea", + "label": "Textarea input", + "inlineLabel": false, + "required": false + }, + "innerBlocks": [] + }, + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "submit", + "label": "Submit", + "inlineLabel": false, + "required": false + }, + "innerBlocks": [] + } + ] + } +] diff --git a/test/integration/fixtures/blocks/core__form.parsed.json b/test/integration/fixtures/blocks/core__form.parsed.json new file mode 100644 index 00000000000000..1cb360568ad8fb --- /dev/null +++ b/test/integration/fixtures/blocks/core__form.parsed.json @@ -0,0 +1,88 @@ +[ + { + "blockName": "core/form", + "attrs": { + "formId": "the-form-id" + }, + "innerBlocks": [ + { + "blockName": "core/input-field", + "attrs": { + "label": "Name - required, inline label", + "inlineLabel": true, + "required": true + }, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ + "\n\n" + ] + }, + { + "blockName": "core/input-field", + "attrs": { + "type": "checkbox", + "label": "Checkbox - inline label", + "inlineLabel": true, + "required": true + }, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ + "\n\n" + ] + }, + { + "blockName": "core/input-field", + "attrs": { + "type": "email", + "label": "Email - required", + "required": true + }, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ + "\n\n" + ] + }, + { + "blockName": "core/input-field", + "attrs": { + "type": "textarea", + "label": "Textarea input" + }, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ + "\n\n" + ] + }, + { + "blockName": "core/input-field", + "attrs": { + "type": "submit", + "label": "Submit" + }, + "innerBlocks": [], + "innerHTML": "\n
\n", + "innerContent": [ + "\n
\n" + ] + } + ], + "innerHTML": "\n
\n\n\n\n\n\n\n\n
\n", + "innerContent": [ + "\n
", + null, + "\n\n", + null, + "\n\n", + null, + "\n\n", + null, + "\n\n", + null, + "
\n" + ] + } +] diff --git a/test/integration/fixtures/blocks/core__form.serialized.html b/test/integration/fixtures/blocks/core__form.serialized.html new file mode 100644 index 00000000000000..9015fe38dd19c7 --- /dev/null +++ b/test/integration/fixtures/blocks/core__form.serialized.html @@ -0,0 +1,21 @@ + +
+ + + + + + + + + + + + + + + + +
+
+ diff --git a/test/integration/fixtures/blocks/core__input-field.html b/test/integration/fixtures/blocks/core__input-field.html new file mode 100644 index 00000000000000..2574bc62f5c7cb --- /dev/null +++ b/test/integration/fixtures/blocks/core__input-field.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + +
+ diff --git a/test/integration/fixtures/blocks/core__input-field.json b/test/integration/fixtures/blocks/core__input-field.json new file mode 100644 index 00000000000000..488701c5558f76 --- /dev/null +++ b/test/integration/fixtures/blocks/core__input-field.json @@ -0,0 +1,57 @@ +[ + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "text", + "label": "Name - required, inline label", + "inlineLabel": true, + "required": true + }, + "innerBlocks": [] + }, + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "checkbox", + "label": "Checkbox - inline label", + "inlineLabel": true, + "required": true + }, + "innerBlocks": [] + }, + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "email", + "label": "Email - required", + "inlineLabel": false, + "required": true + }, + "innerBlocks": [] + }, + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "textarea", + "label": "Textarea input", + "inlineLabel": false, + "required": false + }, + "innerBlocks": [] + }, + { + "name": "core/input-field", + "isValid": true, + "attributes": { + "type": "submit", + "label": "Submit", + "inlineLabel": false, + "required": false + }, + "innerBlocks": [] + } +] diff --git a/test/integration/fixtures/blocks/core__input-field.parsed.json b/test/integration/fixtures/blocks/core__input-field.parsed.json new file mode 100644 index 00000000000000..886e3e6d35ad8e --- /dev/null +++ b/test/integration/fixtures/blocks/core__input-field.parsed.json @@ -0,0 +1,94 @@ +[ + { + "blockName": "core/input-field", + "attrs": { + "label": "Name - required, inline label", + "inlineLabel": true, + "required": true + }, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ + "\n\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ "\n\n" ] + }, + { + "blockName": "core/input-field", + "attrs": { + "type": "checkbox", + "label": "Checkbox - inline label", + "inlineLabel": true, + "required": true + }, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ + "\n\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ "\n\n" ] + }, + { + "blockName": "core/input-field", + "attrs": { + "type": "email", + "label": "Email - required", + "required": true + }, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ + "\n\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ "\n\n" ] + }, + { + "blockName": "core/input-field", + "attrs": { + "type": "textarea", + "label": "Textarea input" + }, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ + "\n\n" + ] + }, + { + "blockName": null, + "attrs": {}, + "innerBlocks": [], + "innerHTML": "\n\n", + "innerContent": [ "\n\n" ] + }, + { + "blockName": "core/input-field", + "attrs": { + "type": "submit", + "label": "Submit" + }, + "innerBlocks": [], + "innerHTML": "\n
\n", + "innerContent": [ + "\n
\n" + ] + } +] diff --git a/test/integration/fixtures/blocks/core__input-field.serialized.html b/test/integration/fixtures/blocks/core__input-field.serialized.html new file mode 100644 index 00000000000000..2574bc62f5c7cb --- /dev/null +++ b/test/integration/fixtures/blocks/core__input-field.serialized.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + +
+ From 5d6a8e4184013e49b45dc2fdd7ab92de7d119baa Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 17 Oct 2022 13:33:11 +0300 Subject: [PATCH 025/133] typo --- packages/block-library/src/form/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/form/edit.js b/packages/block-library/src/form/edit.js index e303cde8690e2d..6fe41ec88053af 100644 --- a/packages/block-library/src/form/edit.js +++ b/packages/block-library/src/form/edit.js @@ -44,7 +44,7 @@ const Edit = ( { attributes, setAttributes } ) => { /> -
; + ); }; From 6022f689656ec736d9ff6771e94478301bfeef43 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 17 Oct 2022 13:50:26 +0300 Subject: [PATCH 026/133] forgot to rename these 2 --- packages/block-library/src/form/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/form/index.php b/packages/block-library/src/form/index.php index d58ebc64624514..fbe4f704b56a70 100644 --- a/packages/block-library/src/form/index.php +++ b/packages/block-library/src/form/index.php @@ -88,7 +88,7 @@ function register_block_core_form() { * Then add your own action by creating a function and hooking it to the 'wp' action. */ function submit_core_form_block() { - if ( ! isset( $_POST['block-form-hash'] ) ) { + if ( ! isset( $_POST['block-form-id'] ) ) { return; } $content = sprintf( @@ -97,7 +97,7 @@ function submit_core_form_block() { esc_url( get_site_url() . $_SERVER['REQUEST_URI'] ) ); foreach ( $_POST as $key => $value ) { - if ( 'block-form-hash' === $key ) { + if ( 'block-form-id' === $key ) { continue; } $content .= $key . ': ' . $value . '
'; From 00e6211efed2144134302e75f3dd07b2a53eed26 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 18 Oct 2022 08:26:31 +0300 Subject: [PATCH 027/133] Add a template --- packages/block-library/src/form/edit.js | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/packages/block-library/src/form/edit.js b/packages/block-library/src/form/edit.js index 6fe41ec88053af..e334c8db2d7ac9 100644 --- a/packages/block-library/src/form/edit.js +++ b/packages/block-library/src/form/edit.js @@ -17,12 +17,54 @@ const ALLOWED_BLOCKS = [ 'core/group', ]; +const TEMPLATE = [ + [ + 'core/input-field', + { + type: 'text', + label: __( 'Name' ), + required: true, + }, + ], + [ + 'core/input-field', + { + type: 'email', + label: __( 'Email' ), + required: true, + }, + ], + [ + 'core/input-field', + { + type: 'url', + label: __( 'Website' ), + }, + ], + [ + 'core/input-field', + { + type: 'textarea', + label: __( 'Comment' ), + required: true, + }, + ], + [ + 'core/input-field', + { + type: 'submit', + label: __( 'Submit' ), + }, + ], +]; + const Edit = ( { attributes, setAttributes } ) => { const { formId } = attributes; const blockProps = useBlockProps(); const innerBlocksProps = useInnerBlocksProps( blockProps, { allowedBlocks: ALLOWED_BLOCKS, + template: TEMPLATE, } ); return ( From f13aa48f512d133c236ff2dd7c967bb3d64c36a8 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 18 Oct 2022 08:38:44 +0300 Subject: [PATCH 028/133] Add block supports --- docs/reference-guides/core-blocks.md | 2 +- packages/block-library/src/form/block.json | 30 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index c394bb01f659e7..5d1d8caa1b2558 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -283,7 +283,7 @@ A form. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/blo - **Name:** core/form - **Category:** common -- **Supports:** +- **Supports:** anchor, color (background, gradients, link, text), spacing (margin, padding), typography (fontSize, lineHeight), ~~className~~ - **Attributes:** action, formId, method ## Classic diff --git a/packages/block-library/src/form/block.json b/packages/block-library/src/form/block.json index fe7da5ebe5b368..7b2f9e87ebc9d0 100644 --- a/packages/block-library/src/form/block.json +++ b/packages/block-library/src/form/block.json @@ -20,5 +20,35 @@ "type": "string", "default": "" } + }, + "supports": { + "anchor": true, + "className": false, + "color": { + "gradients": true, + "link": true, + "__experimentalDefaultControls": { + "background": true, + "text": true + } + }, + "spacing": { + "margin": true, + "padding": true + }, + "typography": { + "fontSize": true, + "lineHeight": true, + "__experimentalFontFamily": true, + "__experimentalTextDecoration": true, + "__experimentalFontStyle": true, + "__experimentalFontWeight": true, + "__experimentalLetterSpacing": true, + "__experimentalTextTransform": true, + "__experimentalDefaultControls": { + "fontSize": true + } + }, + "__experimentalSelector": "form" } } From d91871fa099a9ec0e553349f84da399d31e04dea Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 18 Oct 2022 08:42:03 +0300 Subject: [PATCH 029/133] Styling tweak --- packages/block-library/src/input-field/style.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/block-library/src/input-field/style.scss b/packages/block-library/src/input-field/style.scss index 7de8e8b3d64d16..4b7da822d7f7f7 100644 --- a/packages/block-library/src/input-field/style.scss +++ b/packages/block-library/src/input-field/style.scss @@ -21,6 +21,7 @@ textarea.wp-block-input-field { border: 1px solid currentColor; opacity: 0.75; border-radius: 0; + font-size: 1em; &:focus, &:active, From 9fad79b6b82d82d7737382eb70438953f460ad43 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 18 Oct 2022 10:09:21 +0300 Subject: [PATCH 030/133] Mark as an experiment --- lib/experimental/editor-settings.php | 12 ++++++++++++ lib/experiments-page.php | 11 +++++++++++ packages/block-library/src/index.js | 6 ++++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/experimental/editor-settings.php b/lib/experimental/editor-settings.php index c09b5cde0f16bc..00c929a3312a41 100644 --- a/lib/experimental/editor-settings.php +++ b/lib/experimental/editor-settings.php @@ -33,3 +33,15 @@ function gutenberg_enable_experiments() { } add_action( 'admin_init', 'gutenberg_enable_experiments' ); + +/** + * Sets a global JS variable used to trigger the availability of form & input blocks. + */ +function gutenberg_enable_form_input_blocks() { + $gutenberg_experiments = get_option( 'gutenberg-experiments' ); + if ( $gutenberg_experiments && array_key_exists( 'gutenberg-form-blocks', $gutenberg_experiments ) ) { + wp_add_inline_script( 'wp-block-editor', 'window.__experimentalEnableFormBlocks = true', 'before' ); + } +} + +add_action( 'admin_init', 'gutenberg_enable_form_input_blocks' ); diff --git a/lib/experiments-page.php b/lib/experiments-page.php index 133d968ba2cb76..90a88fd9592885 100644 --- a/lib/experiments-page.php +++ b/lib/experiments-page.php @@ -78,6 +78,17 @@ function gutenberg_initialize_experiments_settings() { 'id' => 'gutenberg-color-randomizer', ) ); + add_settings_field( + 'gutenberg-form-blocks', + __( 'Form and input blocks ', 'gutenberg' ), + 'gutenberg_display_experiment_field', + 'gutenberg-experiments', + 'gutenberg_experiments_section', + array( + 'label' => __( 'Test new blocks to allow building forms (Warning: The new feature is not ready. You may experience UX issues that are being addressed)', 'gutenberg' ), + 'id' => 'gutenberg-form-blocks', + ) + ); add_settings_field( 'gutenberg-group-grid-variation', diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js index b9e9be4788a49d..decf863e538501 100644 --- a/packages/block-library/src/index.js +++ b/packages/block-library/src/index.js @@ -152,10 +152,8 @@ const getAllBlocks = () => { details, embed, file, - form, group, html, - inputField, latestComments, latestPosts, mediaText, @@ -232,6 +230,10 @@ const getAllBlocks = () => { queryTitle, postAuthorBiography, ]; + if ( window?.__experimentalEnableFormBlocks ) { + blocks.push( form ); + blocks.push( inputField ); + } // When in a WordPress context, conditionally // add the classic block and TinyMCE editor From 774f31e473d2d6225ab769b8961ac2cc6f03e310 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 18 Oct 2022 13:59:18 +0300 Subject: [PATCH 031/133] fixtures --- .../fixtures/blocks/core__form.html | 18 ++-- .../fixtures/blocks/core__form.json | 53 ++++++------ .../fixtures/blocks/core__form.parsed.json | 40 ++++----- .../blocks/core__form.serialized.html | 26 +++--- .../fixtures/blocks/core__input-field.html | 20 +---- .../fixtures/blocks/core__input-field.json | 53 +----------- .../blocks/core__input-field.parsed.json | 86 +------------------ .../blocks/core__input-field.serialized.html | 20 +---- 8 files changed, 74 insertions(+), 242 deletions(-) diff --git a/test/integration/fixtures/blocks/core__form.html b/test/integration/fixtures/blocks/core__form.html index 9015fe38dd19c7..d6eafc3a66e136 100644 --- a/test/integration/fixtures/blocks/core__form.html +++ b/test/integration/fixtures/blocks/core__form.html @@ -1,18 +1,18 @@ - - - + + + - - + + - - + + - - + + diff --git a/test/integration/fixtures/blocks/core__form.json b/test/integration/fixtures/blocks/core__form.json index 0c9f29ac87ee0c..69b5ad818cf26d 100644 --- a/test/integration/fixtures/blocks/core__form.json +++ b/test/integration/fixtures/blocks/core__form.json @@ -1,65 +1,60 @@ [ { - "name": "core/form", + "name": "core/missing", "isValid": true, "attributes": { - "action": "#", - "method": "post", - "formId": "the-form-id" + "originalName": "core/form", + "originalUndelimitedContent": "\n\n\n\n\n
\n", + "originalContent": "\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n
\n" }, "innerBlocks": [ { - "name": "core/input-field", + "name": "core/missing", "isValid": true, "attributes": { - "type": "text", - "label": "Name - required, inline label", - "inlineLabel": true, - "required": true + "originalName": "core/input-field", + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, { - "name": "core/input-field", + "name": "core/missing", "isValid": true, "attributes": { - "type": "checkbox", - "label": "Checkbox - inline label", - "inlineLabel": true, - "required": true + "originalName": "core/input-field", + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, { - "name": "core/input-field", + "name": "core/missing", "isValid": true, "attributes": { - "type": "email", - "label": "Email - required", - "inlineLabel": false, - "required": true + "originalName": "core/input-field", + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, { - "name": "core/input-field", + "name": "core/missing", "isValid": true, "attributes": { - "type": "textarea", - "label": "Textarea input", - "inlineLabel": false, - "required": false + "originalName": "core/input-field", + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, { - "name": "core/input-field", + "name": "core/missing", "isValid": true, "attributes": { - "type": "submit", - "label": "Submit", - "inlineLabel": false, - "required": false + "originalName": "core/input-field", + "originalUndelimitedContent": "
", + "originalContent": "\n
\n" }, "innerBlocks": [] } diff --git a/test/integration/fixtures/blocks/core__form.parsed.json b/test/integration/fixtures/blocks/core__form.parsed.json index 1cb360568ad8fb..49fad1dca14920 100644 --- a/test/integration/fixtures/blocks/core__form.parsed.json +++ b/test/integration/fixtures/blocks/core__form.parsed.json @@ -1,60 +1,56 @@ [ { "blockName": "core/form", - "attrs": { - "formId": "the-form-id" - }, + "attrs": {}, "innerBlocks": [ { "blockName": "core/input-field", "attrs": { - "label": "Name - required, inline label", - "inlineLabel": true, + "label": "Name", "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { "blockName": "core/input-field", "attrs": { - "type": "checkbox", - "label": "Checkbox - inline label", - "inlineLabel": true, + "type": "email", + "label": "Email", "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { "blockName": "core/input-field", "attrs": { - "type": "email", - "label": "Email - required", - "required": true + "type": "url", + "label": "Website" }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { "blockName": "core/input-field", "attrs": { "type": "textarea", - "label": "Textarea input" + "label": "Comment", + "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { @@ -70,9 +66,9 @@ ] } ], - "innerHTML": "\n
\n\n\n\n\n\n\n\n
\n", + "innerHTML": "\n
\n\n\n\n\n\n\n\n
\n", "innerContent": [ - "\n
", + "\n", null, "\n\n", null, diff --git a/test/integration/fixtures/blocks/core__form.serialized.html b/test/integration/fixtures/blocks/core__form.serialized.html index 9015fe38dd19c7..c414d7a360f79e 100644 --- a/test/integration/fixtures/blocks/core__form.serialized.html +++ b/test/integration/fixtures/blocks/core__form.serialized.html @@ -1,21 +1,19 @@ - - - + + + + - - - + + - - - + + - - - + + -
-
+ + diff --git a/test/integration/fixtures/blocks/core__input-field.html b/test/integration/fixtures/blocks/core__input-field.html index 2574bc62f5c7cb..2d43ac55103b01 100644 --- a/test/integration/fixtures/blocks/core__input-field.html +++ b/test/integration/fixtures/blocks/core__input-field.html @@ -1,19 +1,3 @@ - - - - - - - - - - - - - - - - - -
+ + diff --git a/test/integration/fixtures/blocks/core__input-field.json b/test/integration/fixtures/blocks/core__input-field.json index 488701c5558f76..b0b6d508faeee9 100644 --- a/test/integration/fixtures/blocks/core__input-field.json +++ b/test/integration/fixtures/blocks/core__input-field.json @@ -1,56 +1,11 @@ [ { - "name": "core/input-field", + "name": "core/missing", "isValid": true, "attributes": { - "type": "text", - "label": "Name - required, inline label", - "inlineLabel": true, - "required": true - }, - "innerBlocks": [] - }, - { - "name": "core/input-field", - "isValid": true, - "attributes": { - "type": "checkbox", - "label": "Checkbox - inline label", - "inlineLabel": true, - "required": true - }, - "innerBlocks": [] - }, - { - "name": "core/input-field", - "isValid": true, - "attributes": { - "type": "email", - "label": "Email - required", - "inlineLabel": false, - "required": true - }, - "innerBlocks": [] - }, - { - "name": "core/input-field", - "isValid": true, - "attributes": { - "type": "textarea", - "label": "Textarea input", - "inlineLabel": false, - "required": false - }, - "innerBlocks": [] - }, - { - "name": "core/input-field", - "isValid": true, - "attributes": { - "type": "submit", - "label": "Submit", - "inlineLabel": false, - "required": false + "originalName": "core/input-field", + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] } diff --git a/test/integration/fixtures/blocks/core__input-field.parsed.json b/test/integration/fixtures/blocks/core__input-field.parsed.json index 886e3e6d35ad8e..d731db37db5fbd 100644 --- a/test/integration/fixtures/blocks/core__input-field.parsed.json +++ b/test/integration/fixtures/blocks/core__input-field.parsed.json @@ -2,93 +2,13 @@ { "blockName": "core/input-field", "attrs": { - "label": "Name - required, inline label", - "inlineLabel": true, + "label": "Name", "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" - ] - }, - { - "blockName": null, - "attrs": {}, - "innerBlocks": [], - "innerHTML": "\n\n", - "innerContent": [ "\n\n" ] - }, - { - "blockName": "core/input-field", - "attrs": { - "type": "checkbox", - "label": "Checkbox - inline label", - "inlineLabel": true, - "required": true - }, - "innerBlocks": [], - "innerHTML": "\n\n", - "innerContent": [ - "\n\n" - ] - }, - { - "blockName": null, - "attrs": {}, - "innerBlocks": [], - "innerHTML": "\n\n", - "innerContent": [ "\n\n" ] - }, - { - "blockName": "core/input-field", - "attrs": { - "type": "email", - "label": "Email - required", - "required": true - }, - "innerBlocks": [], - "innerHTML": "\n\n", - "innerContent": [ - "\n\n" - ] - }, - { - "blockName": null, - "attrs": {}, - "innerBlocks": [], - "innerHTML": "\n\n", - "innerContent": [ "\n\n" ] - }, - { - "blockName": "core/input-field", - "attrs": { - "type": "textarea", - "label": "Textarea input" - }, - "innerBlocks": [], - "innerHTML": "\n\n", - "innerContent": [ - "\n\n" - ] - }, - { - "blockName": null, - "attrs": {}, - "innerBlocks": [], - "innerHTML": "\n\n", - "innerContent": [ "\n\n" ] - }, - { - "blockName": "core/input-field", - "attrs": { - "type": "submit", - "label": "Submit" - }, - "innerBlocks": [], - "innerHTML": "\n
\n", - "innerContent": [ - "\n
\n" + "\n\n" ] } ] diff --git a/test/integration/fixtures/blocks/core__input-field.serialized.html b/test/integration/fixtures/blocks/core__input-field.serialized.html index 2574bc62f5c7cb..5e444498bf5ffc 100644 --- a/test/integration/fixtures/blocks/core__input-field.serialized.html +++ b/test/integration/fixtures/blocks/core__input-field.serialized.html @@ -1,19 +1,3 @@ - - - - - - - - - - - - - - - - - -
+ + From 2b781a051fa8b9f9a1c1905ed731b76a252370bd Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 24 Oct 2022 12:14:06 +0300 Subject: [PATCH 032/133] Rename input-field block to form-input --- docs/reference-guides/core-blocks.md | 18 +++++------ lib/blocks.php | 2 +- .../{input-field => form-input}/block.json | 4 +-- .../src/{input-field => form-input}/edit.js | 12 +++---- .../src/{input-field => form-input}/index.js | 0 .../src/{input-field => form-input}/save.js | 12 +++---- .../{input-field => form-input}/style.scss | 10 +++--- .../src/{input-field => form-input}/utils.js | 0 .../{input-field => form-input}/variations.js | 0 packages/block-library/src/form/edit.js | 12 +++---- packages/block-library/src/index.js | 4 +-- packages/block-library/src/style.scss | 2 +- .../fixtures/blocks/core__form-input.html | 3 ++ .../fixtures/blocks/core__form-input.json | 12 +++++++ .../blocks/core__form-input.parsed.json | 14 ++++++++ .../blocks/core__form-input.serialized.html | 3 ++ .../fixtures/blocks/core__form.html | 28 ++++++++-------- .../fixtures/blocks/core__form.json | 32 +++++++++---------- .../fixtures/blocks/core__form.parsed.json | 26 +++++++-------- .../blocks/core__form.serialized.html | 28 ++++++++-------- .../fixtures/blocks/core__input-field.html | 3 -- .../fixtures/blocks/core__input-field.json | 12 ------- .../blocks/core__input-field.parsed.json | 14 -------- .../blocks/core__input-field.serialized.html | 3 -- 24 files changed, 127 insertions(+), 127 deletions(-) rename packages/block-library/src/{input-field => form-input}/block.json (84%) rename packages/block-library/src/{input-field => form-input}/edit.js (93%) rename packages/block-library/src/{input-field => form-input}/index.js (100%) rename packages/block-library/src/{input-field => form-input}/save.js (79%) rename packages/block-library/src/{input-field => form-input}/style.scss (70%) rename packages/block-library/src/{input-field => form-input}/utils.js (100%) rename packages/block-library/src/{input-field => form-input}/variations.js (100%) create mode 100644 test/integration/fixtures/blocks/core__form-input.html create mode 100644 test/integration/fixtures/blocks/core__form-input.json create mode 100644 test/integration/fixtures/blocks/core__form-input.parsed.json create mode 100644 test/integration/fixtures/blocks/core__form-input.serialized.html delete mode 100644 test/integration/fixtures/blocks/core__input-field.html delete mode 100644 test/integration/fixtures/blocks/core__input-field.json delete mode 100644 test/integration/fixtures/blocks/core__input-field.parsed.json delete mode 100644 test/integration/fixtures/blocks/core__input-field.serialized.html diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 5d1d8caa1b2558..b2080f50e36114 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -286,6 +286,15 @@ A form. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/blo - **Supports:** anchor, color (background, gradients, link, text), spacing (margin, padding), typography (fontSize, lineHeight), ~~className~~ - **Attributes:** action, formId, method +## Input field + +The basic building block for forms. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/form-input)) + +- **Name:** core/form-input +- **Category:** common +- **Supports:** +- **Attributes:** inlineLabel, label, name, required, type + ## Classic Use the classic WordPress editor. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/freeform)) @@ -350,15 +359,6 @@ Insert an image to make a visual statement. ([Source](https://github.com/WordPre - **Supports:** anchor, color (~~background~~, ~~text~~), filter (duotone) - **Attributes:** align, alt, aspectRatio, caption, height, href, id, lightbox, linkClass, linkDestination, linkTarget, rel, scale, sizeSlug, title, url, width -## Input field - -The basic building block for forms. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/input-field)) - -- **Name:** core/input-field -- **Category:** common -- **Supports:** -- **Attributes:** inlineLabel, label, name, required, type - ## Latest Comments Display a list of your most recent comments. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/latest-comments)) diff --git a/lib/blocks.php b/lib/blocks.php index fe545f64c8f10d..b1e7095346ebe9 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -22,9 +22,9 @@ function gutenberg_reregister_core_block_types() { 'column', 'columns', 'details', + 'form-input', 'group', 'html', - 'input-field', 'list', 'list-item', 'media-text', diff --git a/packages/block-library/src/input-field/block.json b/packages/block-library/src/form-input/block.json similarity index 84% rename from packages/block-library/src/input-field/block.json rename to packages/block-library/src/form-input/block.json index 5732261a644fe4..3c5d185f0325de 100644 --- a/packages/block-library/src/input-field/block.json +++ b/packages/block-library/src/form-input/block.json @@ -1,7 +1,7 @@ { "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 2, - "name": "core/input-field", + "name": "core/form-input", "title": "Input field", "category": "common", "parent": [ "core/form" ], @@ -29,5 +29,5 @@ "default": false } }, - "style": [ "wp-block-input-field", "wp-block-buttons", "wp-block-button" ] + "style": [ "wp-block-form-input", "wp-block-buttons", "wp-block-button" ] } diff --git a/packages/block-library/src/input-field/edit.js b/packages/block-library/src/form-input/edit.js similarity index 93% rename from packages/block-library/src/input-field/edit.js rename to packages/block-library/src/form-input/edit.js index 2defbdb798129f..a839250f780a2f 100644 --- a/packages/block-library/src/input-field/edit.js +++ b/packages/block-library/src/form-input/edit.js @@ -95,14 +95,14 @@ function InputFieldBlock( { attributes, setAttributes } ) { { type === 'textarea' && ( /* eslint-disable jsx-a11y/label-has-associated-control */ - + + + - +
- + diff --git a/test/integration/fixtures/blocks/core__form.json b/test/integration/fixtures/blocks/core__form.json index 69b5ad818cf26d..c37c25f7a228c6 100644 --- a/test/integration/fixtures/blocks/core__form.json +++ b/test/integration/fixtures/blocks/core__form.json @@ -4,17 +4,17 @@ "isValid": true, "attributes": { "originalName": "core/form", - "originalUndelimitedContent": "
\n\n\n\n\n
\n
", - "originalContent": "\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n
\n" + "originalUndelimitedContent": "
\n\n\n\n\n
\n
", + "originalContent": "\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n
\n" }, "innerBlocks": [ { "name": "core/missing", "isValid": true, "attributes": { - "originalName": "core/input-field", - "originalUndelimitedContent": "", - "originalContent": "\n\n" + "originalName": "core/form-input", + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, @@ -22,9 +22,9 @@ "name": "core/missing", "isValid": true, "attributes": { - "originalName": "core/input-field", - "originalUndelimitedContent": "", - "originalContent": "\n\n" + "originalName": "core/form-input", + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, @@ -32,9 +32,9 @@ "name": "core/missing", "isValid": true, "attributes": { - "originalName": "core/input-field", - "originalUndelimitedContent": "", - "originalContent": "\n\n" + "originalName": "core/form-input", + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, @@ -42,9 +42,9 @@ "name": "core/missing", "isValid": true, "attributes": { - "originalName": "core/input-field", - "originalUndelimitedContent": "", - "originalContent": "\n\n" + "originalName": "core/form-input", + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, @@ -52,9 +52,9 @@ "name": "core/missing", "isValid": true, "attributes": { - "originalName": "core/input-field", + "originalName": "core/form-input", "originalUndelimitedContent": "
", - "originalContent": "\n
\n" + "originalContent": "\n
\n" }, "innerBlocks": [] } diff --git a/test/integration/fixtures/blocks/core__form.parsed.json b/test/integration/fixtures/blocks/core__form.parsed.json index 49fad1dca14920..9bb9c2adf8a8e1 100644 --- a/test/integration/fixtures/blocks/core__form.parsed.json +++ b/test/integration/fixtures/blocks/core__form.parsed.json @@ -4,57 +4,57 @@ "attrs": {}, "innerBlocks": [ { - "blockName": "core/input-field", + "blockName": "core/form-input", "attrs": { "label": "Name", "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { - "blockName": "core/input-field", + "blockName": "core/form-input", "attrs": { "type": "email", "label": "Email", "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { - "blockName": "core/input-field", + "blockName": "core/form-input", "attrs": { "type": "url", "label": "Website" }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { - "blockName": "core/input-field", + "blockName": "core/form-input", "attrs": { "type": "textarea", "label": "Comment", "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { - "blockName": "core/input-field", + "blockName": "core/form-input", "attrs": { "type": "submit", "label": "Submit" diff --git a/test/integration/fixtures/blocks/core__form.serialized.html b/test/integration/fixtures/blocks/core__form.serialized.html index c414d7a360f79e..fd03e1d64bc6fe 100644 --- a/test/integration/fixtures/blocks/core__form.serialized.html +++ b/test/integration/fixtures/blocks/core__form.serialized.html @@ -1,19 +1,19 @@
- - - - - - - - - - - - - + + + + + + + + + + + + +
- +
diff --git a/test/integration/fixtures/blocks/core__input-field.html b/test/integration/fixtures/blocks/core__input-field.html deleted file mode 100644 index 2d43ac55103b01..00000000000000 --- a/test/integration/fixtures/blocks/core__input-field.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/test/integration/fixtures/blocks/core__input-field.json b/test/integration/fixtures/blocks/core__input-field.json deleted file mode 100644 index b0b6d508faeee9..00000000000000 --- a/test/integration/fixtures/blocks/core__input-field.json +++ /dev/null @@ -1,12 +0,0 @@ -[ - { - "name": "core/missing", - "isValid": true, - "attributes": { - "originalName": "core/input-field", - "originalUndelimitedContent": "", - "originalContent": "\n\n" - }, - "innerBlocks": [] - } -] diff --git a/test/integration/fixtures/blocks/core__input-field.parsed.json b/test/integration/fixtures/blocks/core__input-field.parsed.json deleted file mode 100644 index d731db37db5fbd..00000000000000 --- a/test/integration/fixtures/blocks/core__input-field.parsed.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "blockName": "core/input-field", - "attrs": { - "label": "Name", - "required": true - }, - "innerBlocks": [], - "innerHTML": "\n\n", - "innerContent": [ - "\n\n" - ] - } -] diff --git a/test/integration/fixtures/blocks/core__input-field.serialized.html b/test/integration/fixtures/blocks/core__input-field.serialized.html deleted file mode 100644 index 5e444498bf5ffc..00000000000000 --- a/test/integration/fixtures/blocks/core__input-field.serialized.html +++ /dev/null @@ -1,3 +0,0 @@ - - - From 256151603e7e21e939073858e16133753f5d5fa3 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 24 Oct 2022 13:58:50 +0300 Subject: [PATCH 033/133] Add default init.js file for the form-input block --- packages/block-library/src/form-input/init.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 packages/block-library/src/form-input/init.js diff --git a/packages/block-library/src/form-input/init.js b/packages/block-library/src/form-input/init.js new file mode 100644 index 00000000000000..79f0492c2cb2f8 --- /dev/null +++ b/packages/block-library/src/form-input/init.js @@ -0,0 +1,6 @@ +/** + * Internal dependencies + */ +import { init } from './'; + +export default init(); From 7812b808db3cc5bfeb31641b29e2413cec325fd6 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 9 Nov 2022 10:23:56 +0200 Subject: [PATCH 034/133] Use WP_HTML_Tag_Processor --- packages/block-library/src/form/index.php | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/packages/block-library/src/form/index.php b/packages/block-library/src/form/index.php index fbe4f704b56a70..d0c0016940d4bf 100644 --- a/packages/block-library/src/form/index.php +++ b/packages/block-library/src/form/index.php @@ -49,20 +49,17 @@ function render_block_core_form( $attributes, $content, $block ) { $form_id = empty( $attributes['formId'] ) ? md5( json_encode( array( $attributes, $block ) ) ) : $attributes['formId']; + // Add the form action & method. + $processed_content = new WP_HTML_Tag_Processor( $content ); + $processed_content->next_tag( 'form' ); + $processed_content->set_attribute( 'action', esc_attr( $action ) ); + $processed_content->set_attribute( 'method', esc_attr( $method ) ); + + // Inject a hidden input with the block form-ID. return str_replace( - array( - '
', - ), - array( - sprintf( - '', - ), - $content + '
', + '
', + $processed_content->get_updated_html() ); } From 791490e57507f6d25c1d7f6b9588d223579ba651 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 9 Nov 2022 10:35:38 +0200 Subject: [PATCH 035/133] use the HTML for the label --- packages/block-library/src/form-input/block.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/form-input/block.json b/packages/block-library/src/form-input/block.json index 3c5d185f0325de..b21e3e0558629c 100644 --- a/packages/block-library/src/form-input/block.json +++ b/packages/block-library/src/form-input/block.json @@ -18,7 +18,9 @@ }, "label": { "type": "string", - "default": "Label" + "default": "Label", + "selector": ".wp-block-form-input-label__content", + "source": "html" }, "inlineLabel": { "type": "boolean", From 06faa933023215dc5f1caccd2cc25c714af45c06 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 9 Nov 2022 10:39:18 +0200 Subject: [PATCH 036/133] Use an attribute for "required" --- packages/block-library/src/form-input/block.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/form-input/block.json b/packages/block-library/src/form-input/block.json index b21e3e0558629c..c7ad078f65724a 100644 --- a/packages/block-library/src/form-input/block.json +++ b/packages/block-library/src/form-input/block.json @@ -28,7 +28,10 @@ }, "required": { "type": "boolean", - "default": false + "default": false, + "selector": ".wp-block-form-input", + "source": "attribute", + "attribute": "required" } }, "style": [ "wp-block-form-input", "wp-block-buttons", "wp-block-button" ] From 86427f040c5334618ba42c1c8f6cc31bd70dec3c Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Wed, 9 Nov 2022 10:43:54 +0200 Subject: [PATCH 037/133] fix for submit button label --- packages/block-library/src/form-input/block.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/form-input/block.json b/packages/block-library/src/form-input/block.json index c7ad078f65724a..24465cf2d829b3 100644 --- a/packages/block-library/src/form-input/block.json +++ b/packages/block-library/src/form-input/block.json @@ -19,7 +19,7 @@ "label": { "type": "string", "default": "Label", - "selector": ".wp-block-form-input-label__content", + "selector": ".wp-block-form-input-label__content,button", "source": "html" }, "inlineLabel": { From 7316fb4c451c82a1f8a1e5e925f8339bcd24efab Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 15 Nov 2022 14:35:32 +0200 Subject: [PATCH 038/133] Add placeholder to inputs --- docs/reference-guides/core-blocks.md | 2 +- .../block-library/src/form-input/block.json | 6 ++++++ packages/block-library/src/form-input/edit.js | 21 ++++++++++++++----- packages/block-library/src/form-input/save.js | 4 +++- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index b2080f50e36114..9fe8ad8c08c21b 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -293,7 +293,7 @@ The basic building block for forms. ([Source](https://github.com/WordPress/guten - **Name:** core/form-input - **Category:** common - **Supports:** -- **Attributes:** inlineLabel, label, name, required, type +- **Attributes:** inlineLabel, label, name, placeholder, required, type ## Classic diff --git a/packages/block-library/src/form-input/block.json b/packages/block-library/src/form-input/block.json index 24465cf2d829b3..0f8038bfccacb4 100644 --- a/packages/block-library/src/form-input/block.json +++ b/packages/block-library/src/form-input/block.json @@ -32,6 +32,12 @@ "selector": ".wp-block-form-input", "source": "attribute", "attribute": "required" + }, + "placeholder": { + "type": "string", + "selector": ".wp-block-form-input", + "source": "attribute", + "attribute": "placeholder" } }, "style": [ "wp-block-form-input", "wp-block-buttons", "wp-block-button" ] diff --git a/packages/block-library/src/form-input/edit.js b/packages/block-library/src/form-input/edit.js index a839250f780a2f..ce59a57eceb822 100644 --- a/packages/block-library/src/form-input/edit.js +++ b/packages/block-library/src/form-input/edit.js @@ -26,7 +26,8 @@ import { useRef } from '@wordpress/element'; import { INPUT_TYPES } from './utils'; function InputFieldBlock( { attributes, setAttributes } ) { - const { type, name, label, inlineLabel, required } = attributes; + const { type, name, label, inlineLabel, required, placeholder } = + attributes; const blockProps = useBlockProps(); const ref = useRef(); @@ -185,11 +186,21 @@ function InputFieldBlock( { attributes, setAttributes } ) { __unstableAllowPrefixTransformations /> + setAttributes( { placeholder: event.target.value } ) + } aria-required={ required } /> diff --git a/packages/block-library/src/form-input/save.js b/packages/block-library/src/form-input/save.js index f6c8d070a54bad..2ce44197d2d9a7 100644 --- a/packages/block-library/src/form-input/save.js +++ b/packages/block-library/src/form-input/save.js @@ -4,7 +4,8 @@ import classNames from 'classnames'; export default function save( { attributes } ) { - const { type, name, label, inlineLabel, required } = attributes; + const { type, name, label, inlineLabel, required, placeholder } = + attributes; return ( <> @@ -54,6 +55,7 @@ export default function save( { attributes } ) { name={ name || label } required={ required } aria-required={ required } + placeholder={ placeholder || undefined } /> /* eslint-enable jsx-a11y/label-has-associated-control */ From cdbf8bacab74d11f3ca4ecd876f62b26eb68aece Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 15 Nov 2022 14:35:32 +0200 Subject: [PATCH 039/133] Revert "Add placeholder to inputs" This reverts commit c0e6e63d8371f5c6340577c3135eb7993fc1992e. --- docs/reference-guides/core-blocks.md | 2 +- .../block-library/src/form-input/block.json | 6 ------ packages/block-library/src/form-input/edit.js | 21 +++++-------------- packages/block-library/src/form-input/save.js | 4 +--- 4 files changed, 7 insertions(+), 26 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 9fe8ad8c08c21b..b2080f50e36114 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -293,7 +293,7 @@ The basic building block for forms. ([Source](https://github.com/WordPress/guten - **Name:** core/form-input - **Category:** common - **Supports:** -- **Attributes:** inlineLabel, label, name, placeholder, required, type +- **Attributes:** inlineLabel, label, name, required, type ## Classic diff --git a/packages/block-library/src/form-input/block.json b/packages/block-library/src/form-input/block.json index 0f8038bfccacb4..24465cf2d829b3 100644 --- a/packages/block-library/src/form-input/block.json +++ b/packages/block-library/src/form-input/block.json @@ -32,12 +32,6 @@ "selector": ".wp-block-form-input", "source": "attribute", "attribute": "required" - }, - "placeholder": { - "type": "string", - "selector": ".wp-block-form-input", - "source": "attribute", - "attribute": "placeholder" } }, "style": [ "wp-block-form-input", "wp-block-buttons", "wp-block-button" ] diff --git a/packages/block-library/src/form-input/edit.js b/packages/block-library/src/form-input/edit.js index ce59a57eceb822..a839250f780a2f 100644 --- a/packages/block-library/src/form-input/edit.js +++ b/packages/block-library/src/form-input/edit.js @@ -26,8 +26,7 @@ import { useRef } from '@wordpress/element'; import { INPUT_TYPES } from './utils'; function InputFieldBlock( { attributes, setAttributes } ) { - const { type, name, label, inlineLabel, required, placeholder } = - attributes; + const { type, name, label, inlineLabel, required } = attributes; const blockProps = useBlockProps(); const ref = useRef(); @@ -186,21 +185,11 @@ function InputFieldBlock( { attributes, setAttributes } ) { __unstableAllowPrefixTransformations /> - setAttributes( { placeholder: event.target.value } ) - } + type={ type } + name={ name } + disabled="true" + required={ required } aria-required={ required } /> diff --git a/packages/block-library/src/form-input/save.js b/packages/block-library/src/form-input/save.js index 2ce44197d2d9a7..f6c8d070a54bad 100644 --- a/packages/block-library/src/form-input/save.js +++ b/packages/block-library/src/form-input/save.js @@ -4,8 +4,7 @@ import classNames from 'classnames'; export default function save( { attributes } ) { - const { type, name, label, inlineLabel, required, placeholder } = - attributes; + const { type, name, label, inlineLabel, required } = attributes; return ( <> @@ -55,7 +54,6 @@ export default function save( { attributes } ) { name={ name || label } required={ required } aria-required={ required } - placeholder={ placeholder || undefined } /> /* eslint-enable jsx-a11y/label-has-associated-control */ From dd3b81fee2ef0e66e3cb07bbdf8176247c4a195c Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 22 Nov 2022 08:56:22 +0200 Subject: [PATCH 040/133] Remove identifier --- packages/block-library/src/form-input/edit.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/block-library/src/form-input/edit.js b/packages/block-library/src/form-input/edit.js index a839250f780a2f..be5758292ff97e 100644 --- a/packages/block-library/src/form-input/edit.js +++ b/packages/block-library/src/form-input/edit.js @@ -100,7 +100,6 @@ function InputFieldBlock( { attributes, setAttributes } ) { } ) } > Date: Tue, 22 Nov 2022 09:16:57 +0200 Subject: [PATCH 041/133] cleanup --- packages/block-library/src/form-input/edit.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/block-library/src/form-input/edit.js b/packages/block-library/src/form-input/edit.js index be5758292ff97e..51125ffafc171d 100644 --- a/packages/block-library/src/form-input/edit.js +++ b/packages/block-library/src/form-input/edit.js @@ -113,8 +113,6 @@ function InputFieldBlock( { attributes, setAttributes } ) { } data-empty={ label ? false : true } placeholder={ __( 'Type the label for this input' ) } - __unstableEmbedURLOnPaste - __unstableAllowPrefixTransformations /> + diff --git a/test/integration/fixtures/blocks/core__form.json b/test/integration/fixtures/blocks/core__form.json index c37c25f7a228c6..ba07b17e4d00c6 100644 --- a/test/integration/fixtures/blocks/core__form.json +++ b/test/integration/fixtures/blocks/core__form.json @@ -4,8 +4,8 @@ "isValid": true, "attributes": { "originalName": "core/form", - "originalUndelimitedContent": "\n\n\n\n\n
\n", - "originalContent": "\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n
\n" + "originalUndelimitedContent": "
\n\n\n\n\n
\n
", + "originalContent": "\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n\n
\n" }, "innerBlocks": [ { @@ -13,8 +13,8 @@ "isValid": true, "attributes": { "originalName": "core/form-input", - "originalUndelimitedContent": "", - "originalContent": "\n\n" + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, @@ -23,8 +23,8 @@ "isValid": true, "attributes": { "originalName": "core/form-input", - "originalUndelimitedContent": "", - "originalContent": "\n\n" + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, @@ -33,8 +33,8 @@ "isValid": true, "attributes": { "originalName": "core/form-input", - "originalUndelimitedContent": "", - "originalContent": "\n\n" + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, @@ -43,8 +43,8 @@ "isValid": true, "attributes": { "originalName": "core/form-input", - "originalUndelimitedContent": "", - "originalContent": "\n\n" + "originalUndelimitedContent": "", + "originalContent": "\n\n" }, "innerBlocks": [] }, diff --git a/test/integration/fixtures/blocks/core__form.parsed.json b/test/integration/fixtures/blocks/core__form.parsed.json index 9bb9c2adf8a8e1..379bee84c84e10 100644 --- a/test/integration/fixtures/blocks/core__form.parsed.json +++ b/test/integration/fixtures/blocks/core__form.parsed.json @@ -10,9 +10,9 @@ "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { @@ -23,9 +23,9 @@ "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { @@ -35,9 +35,9 @@ "label": "Website" }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { @@ -48,9 +48,9 @@ "required": true }, "innerBlocks": [], - "innerHTML": "\n\n", + "innerHTML": "\n\n", "innerContent": [ - "\n\n" + "\n\n" ] }, { diff --git a/test/integration/fixtures/blocks/core__form.serialized.html b/test/integration/fixtures/blocks/core__form.serialized.html index fd03e1d64bc6fe..58a2a49967eb56 100644 --- a/test/integration/fixtures/blocks/core__form.serialized.html +++ b/test/integration/fixtures/blocks/core__form.serialized.html @@ -1,16 +1,16 @@
- + - + - + - +
From 1c5e4378ba30ea1e5b99a1204657f794f9505ee5 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 17 Jul 2023 12:20:28 +0300 Subject: [PATCH 095/133] Move inspector controls from advanced section to normal --- packages/block-library/src/form/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/form/edit.js b/packages/block-library/src/form/edit.js index 6d6eb7ffc842fd..f1a05a968d531e 100644 --- a/packages/block-library/src/form/edit.js +++ b/packages/block-library/src/form/edit.js @@ -74,7 +74,7 @@ const Edit = ( { attributes, setAttributes, clientId } ) => { return ( <> - + Date: Mon, 17 Jul 2023 12:46:51 +0300 Subject: [PATCH 096/133] Add visibilityPermissions attribute --- docs/reference-guides/core-blocks.md | 2 +- lib/blocks.php | 1 + .../block-library/src/form-input/block.json | 4 ++ .../block-library/src/form-input/index.php | 42 +++++++++++++++++++ packages/block-library/src/form/variations.js | 3 ++ 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 packages/block-library/src/form-input/index.php diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 892ad14e4eb54e..8224a25cd8162c 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -294,7 +294,7 @@ The basic building block for forms. ([Source](https://github.com/WordPress/guten - **Category:** common - **Parent:** core/form - **Supports:** anchor, spacing (margin), ~~reusable~~ -- **Attributes:** inlineLabel, label, name, placeholder, required, type +- **Attributes:** inlineLabel, label, name, placeholder, required, type, visibilityPermissions ## Form submit button diff --git a/lib/blocks.php b/lib/blocks.php index 2035f99a860cd1..b1d0677f06a5c9 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -69,6 +69,7 @@ function gutenberg_reregister_core_block_types() { 'footnotes.php' => 'core/footnotes', 'file.php' => 'core/file', 'form.php' => 'core/form', + 'form-input.php' => 'core/form-input', 'home-link.php' => 'core/home-link', 'image.php' => 'core/image', 'gallery.php' => 'core/gallery', diff --git a/packages/block-library/src/form-input/block.json b/packages/block-library/src/form-input/block.json index c08ebe6c6fde42..5ec76f719c3b17 100644 --- a/packages/block-library/src/form-input/block.json +++ b/packages/block-library/src/form-input/block.json @@ -41,6 +41,10 @@ "source": "attribute", "attribute": "placeholder", "__experimentalRole": "content" + }, + "visibilityPermissions": { + "type": "string", + "default": "all" } }, "supports": { diff --git a/packages/block-library/src/form-input/index.php b/packages/block-library/src/form-input/index.php new file mode 100644 index 00000000000000..52121924f2b731 --- /dev/null +++ b/packages/block-library/src/form-input/index.php @@ -0,0 +1,42 @@ + 'render_block_core_form_input', + ) + ); +} +add_action( 'init', 'register_block_core_form_input' ); diff --git a/packages/block-library/src/form/variations.js b/packages/block-library/src/form/variations.js index 1b7e07b61d3230..5da31d1fec66d4 100644 --- a/packages/block-library/src/form/variations.js +++ b/packages/block-library/src/form/variations.js @@ -22,6 +22,7 @@ const variations = [ name: 'author', label: __( 'Name' ), required: true, + visibilityPermissions: 'logged-out', }, ], [ @@ -31,6 +32,7 @@ const variations = [ name: 'email', label: __( 'Email' ), required: true, + visibilityPermissions: 'logged-out', }, ], [ @@ -40,6 +42,7 @@ const variations = [ name: 'comment', label: __( 'Comment' ), required: true, + visibilityPermissions: 'all', }, ], [ 'core/form-submit-button', {} ], From e5f91585cf222ec55451f1c3eca328bf93b483b7 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 17 Jul 2023 12:50:26 +0300 Subject: [PATCH 097/133] Rename comment-form variation --- packages/block-library/src/form/variations.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/form/variations.js b/packages/block-library/src/form/variations.js index 5da31d1fec66d4..9f044096c869a0 100644 --- a/packages/block-library/src/form/variations.js +++ b/packages/block-library/src/form/variations.js @@ -6,7 +6,7 @@ import { __ } from '@wordpress/i18n'; const variations = [ { name: 'comment-form', - title: __( 'Comment form' ), + title: __( 'Experimental Comment form' ), description: __( 'A comment form for posts and pages.' ), attributes: { action: '{SITE_URL}/wp-comments-post.php', From 6de676cc3f806f08345eac6dfb6cb59213da28b7 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 31 Jul 2023 13:42:49 +0300 Subject: [PATCH 098/133] Add option to send email, and a field to define the address --- docs/reference-guides/core-blocks.md | 2 +- packages/block-library/src/form/block.json | 4 ++ packages/block-library/src/form/edit.js | 49 +++++++++++++++------- packages/block-library/src/form/index.php | 28 +++++++------ 4 files changed, 54 insertions(+), 29 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 8224a25cd8162c..7bb65de5578d9c 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -284,7 +284,7 @@ A form. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/blo - **Name:** core/form - **Category:** common - **Supports:** anchor, color (background, gradients, link, text), spacing (margin, padding), typography (fontSize, lineHeight), ~~className~~ -- **Attributes:** action, method +- **Attributes:** action, email, method ## Input field diff --git a/packages/block-library/src/form/block.json b/packages/block-library/src/form/block.json index 337db9255529ff..ddd84d6314de35 100644 --- a/packages/block-library/src/form/block.json +++ b/packages/block-library/src/form/block.json @@ -13,6 +13,10 @@ "type": "string" }, "method": { + "type": "string", + "default": "email" + }, + "email": { "type": "string" } }, diff --git a/packages/block-library/src/form/edit.js b/packages/block-library/src/form/edit.js index f1a05a968d531e..6816781aace1be 100644 --- a/packages/block-library/src/form/edit.js +++ b/packages/block-library/src/form/edit.js @@ -50,7 +50,7 @@ const TEMPLATE = [ ]; const Edit = ( { attributes, setAttributes, clientId } ) => { - const { action, method } = attributes; + const { action, method, email } = attributes; const blockProps = useBlockProps(); const { hasInnerBlocks } = useSelect( @@ -75,33 +75,50 @@ const Edit = ( { attributes, setAttributes, clientId } ) => { return ( <> - { - setAttributes( { - action: newVal, - } ); - } } - help={ __( - 'Define where the form should be submitted. Leave empty to send an email to the site admin when a form gets submitted.' - ) } - /> setAttributes( { method: value } ) } help={ __( - 'Whether the form will submit a POST or GET request.' + 'Whether the form will send an email, or submit a POST/GET request.' ) } /> + { method === 'email' && ( + + setAttributes( { email: value } ) + } + help={ __( + 'The email address where form submissions will be sent. Leave empty to use the site admin address.' + ) } + /> + ) } + { method !== 'email' && ( + { + setAttributes( { + action: newVal, + } ); + } } + help={ __( + 'The URL where the form should be submitted.' + ) } + /> + ) } diff --git a/packages/block-library/src/form/index.php b/packages/block-library/src/form/index.php index 420c5f97b752d4..089e5088d5e89d 100644 --- a/packages/block-library/src/form/index.php +++ b/packages/block-library/src/form/index.php @@ -29,8 +29,12 @@ function render_block_core_form( $attributes, $content ) { } // Add the method attribute. If it is not set, default to `post`. - $attributes['method'] = empty( $attributes['method'] ) ? 'post' : $attributes['method']; - $processed_content->set_attribute( 'method', $attributes['method'] ); + $method = empty( $attributes['method'] ) ? 'post' : $attributes['method']; + // If the user has set the method to "email", change it to "post". + if ( 'email' === $method ) { + $method = 'post'; + } + $processed_content->set_attribute( 'method', $method ); $extra_fields = apply_filters( 'render_block_core_form_extra_fields', '', $attributes ); @@ -72,32 +76,32 @@ function gutenberg_block_core_form_extra_fields_comment_form( $extra_fields, $at * * @return string The extra fields. */ -function gutenberg_block_core_form_extra_fields_contact_form( $extra_fields, $attributes ) { - if ( empty( $attributes['action'] ) ) { +function gutenberg_block_core_form_extra_fields_email( $extra_fields, $attributes ) { + if ( 'email' === $attributes['method'] ) { $extra_fields .= wp_nonce_field( 'wp-block-form', 'wp_block_form', true, false ); $extra_fields .= ''; + $email_address = empty( $attributes['email'] ) ? get_option( 'admin_email' ) : $attributes['email']; + $extra_fields .= ''; } return $extra_fields; } -add_filter( 'render_block_core_form_extra_fields', 'gutenberg_block_core_form_extra_fields_contact_form', 10, 2 ); +add_filter( 'render_block_core_form_extra_fields', 'gutenberg_block_core_form_extra_fields_email', 10, 2 ); /** * Sends an email if the form is a contact form. * * @return void */ -function gutenberg_block_core_form_email_if_action_is_empty() { +function gutenberg_block_core_form_send_email() { // Get the POST or GET data. $params = wp_unslash( $_POST ); - if ( empty( $params['wp_block_form'] ) ) { - $params = wp_unslash( $_GET ); - } // Bail early if not a form submission, or if the nonce is not valid. if ( empty( $params['wp_block_form'] ) || empty( $params['wp-send-email'] ) || '1' !== $params['wp-send-email'] || ! wp_verify_nonce( $params['wp_block_form'], 'wp-block-form' ) + || empty( $params['wp-email-address'] ) ) { return; } @@ -109,19 +113,19 @@ function gutenberg_block_core_form_email_if_action_is_empty() { '' . get_bloginfo( 'name' ) . '' ); - $skip_fields = array( 'wp_block_form', '_wp_http_referer', 'wp-send-email' ); + $skip_fields = array( 'wp_block_form', '_wp_http_referer', 'wp-send-email', 'wp-email-address' ); foreach ( $params as $key => $value ) { if ( in_array( $key, $skip_fields, true ) ) { continue; } $content .= $key . ': ' . $value . '
'; } - wp_mail( get_option( 'admin_email' ), __( 'Form submission', 'gutenberg' ), $content ); + wp_mail( $params['wp-email-address'], __( 'Form submission', 'gutenberg' ), $content ); wp_safe_redirect( get_site_url( null, $params['_wp_http_referer'] ) ); exit; } -add_action( 'wp', 'gutenberg_block_core_form_email_if_action_is_empty' ); +add_action( 'wp', 'gutenberg_block_core_form_send_email' ); /** * Registers the `core/form` block on server. From 6eac41a8abb28cf124ed0f699a6755f55ea38405 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 31 Jul 2023 13:43:16 +0300 Subject: [PATCH 099/133] Filter the email content to allow 3rd-party plugins to change things --- packages/block-library/src/form/index.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/block-library/src/form/index.php b/packages/block-library/src/form/index.php index 089e5088d5e89d..7ac040ca4f3fec 100644 --- a/packages/block-library/src/form/index.php +++ b/packages/block-library/src/form/index.php @@ -120,8 +120,14 @@ function gutenberg_block_core_form_send_email() { } $content .= $key . ': ' . $value . '
'; } + + // Filter the email content. + $content = apply_filters( 'render_block_core_form_email_content', $content, $params ); + + // Send the email. wp_mail( $params['wp-email-address'], __( 'Form submission', 'gutenberg' ), $content ); + // Redirect back to the form. wp_safe_redirect( get_site_url( null, $params['_wp_http_referer'] ) ); exit; } From 2ba5cc319e66af7a764f9a128829003fa85a1c45 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 31 Jul 2023 13:50:28 +0300 Subject: [PATCH 100/133] Basic sanitization for the email content --- packages/block-library/src/form/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/form/index.php b/packages/block-library/src/form/index.php index 7ac040ca4f3fec..a7824383b8eb05 100644 --- a/packages/block-library/src/form/index.php +++ b/packages/block-library/src/form/index.php @@ -118,7 +118,7 @@ function gutenberg_block_core_form_send_email() { if ( in_array( $key, $skip_fields, true ) ) { continue; } - $content .= $key . ': ' . $value . '
'; + $content .= sanitize_key( $key ) . ': ' . wp_kses_post( $value ) . '
'; } // Filter the email content. From 474aa80b2d5d8812f4a2c895cab04d54fb88547f Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Mon, 31 Jul 2023 13:53:47 +0300 Subject: [PATCH 101/133] Code improvement --- packages/block-library/src/form/index.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/block-library/src/form/index.php b/packages/block-library/src/form/index.php index a7824383b8eb05..b1bc622071883d 100644 --- a/packages/block-library/src/form/index.php +++ b/packages/block-library/src/form/index.php @@ -28,12 +28,13 @@ function render_block_core_form( $attributes, $content ) { $processed_content->set_attribute( 'action', esc_attr( $action ) ); } - // Add the method attribute. If it is not set, default to `post`. - $method = empty( $attributes['method'] ) ? 'post' : $attributes['method']; - // If the user has set the method to "email", change it to "post". - if ( 'email' === $method ) { - $method = 'post'; - } + /* + * Add the method attribute. If it is not set, default to `post`. + * If the user has set the method to `email`, change it to `post`. + */ + $method = empty( $attributes['method'] ) || 'email' === $attributes['method'] + ? 'post' + : $attributes['method']; $processed_content->set_attribute( 'method', $method ); $extra_fields = apply_filters( 'render_block_core_form_extra_fields', '', $attributes ); From e6e92e95a2590b67047105b661e7b8a73857a11c Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 1 Aug 2023 09:12:09 +0300 Subject: [PATCH 102/133] Add render_block_core_form_email_sent action --- packages/block-library/src/form/index.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/block-library/src/form/index.php b/packages/block-library/src/form/index.php index b1bc622071883d..6b012fd1f1cfd2 100644 --- a/packages/block-library/src/form/index.php +++ b/packages/block-library/src/form/index.php @@ -128,11 +128,28 @@ function gutenberg_block_core_form_send_email() { // Send the email. wp_mail( $params['wp-email-address'], __( 'Form submission', 'gutenberg' ), $content ); - // Redirect back to the form. + /** + * Fires after the email has been sent. + * + * This will allow 3rd-party plugins to redirect to a different page + * by removing the default redirect, or add a success message etc. + * + * @param array $params The POST data. + */ + do_action( 'render_block_core_form_email_sent', $params ); +} +add_action( 'wp', 'gutenberg_block_core_form_send_email' ); + +/** + * Redirect to the same page when the form has been submitted and an email was sent. + * + * @param array $params The POST data. + */ +function gutenberg_block_core_form_email_sent( $params ) { wp_safe_redirect( get_site_url( null, $params['_wp_http_referer'] ) ); exit; } -add_action( 'wp', 'gutenberg_block_core_form_send_email' ); +add_action( 'render_block_core_form_email_sent', 'gutenberg_block_core_form_email_sent' ); /** * Registers the `core/form` block on server. From e7745d68ce02b8f84f8f9f33c91ef78254b722fd Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Tue, 1 Aug 2023 12:37:01 +0300 Subject: [PATCH 103/133] It's possible to use comma-separated values for the email address --- packages/block-library/src/form/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/form/edit.js b/packages/block-library/src/form/edit.js index 6816781aace1be..dd1986335cdaf6 100644 --- a/packages/block-library/src/form/edit.js +++ b/packages/block-library/src/form/edit.js @@ -99,7 +99,7 @@ const Edit = ( { attributes, setAttributes, clientId } ) => { setAttributes( { email: value } ) } help={ __( - 'The email address where form submissions will be sent. Leave empty to use the site admin address.' + 'The email address where form submissions will be sent. Separate multiple email addresses with a comma, or leave empty to use the site admin address.' ) } /> ) } From 55168e3b0450cab4db41d978c7818a47e3ef77b9 Mon Sep 17 00:00:00 2001 From: Ari Stathopoulos Date: Thu, 3 Aug 2023 13:08:16 +0300 Subject: [PATCH 104/133] Add a `hidden` input-type --- docs/reference-guides/core-blocks.md | 2 +- packages/block-library/src/editor.scss | 1 + .../block-library/src/form-input/block.json | 7 ++ packages/block-library/src/form-input/edit.js | 82 +++++++++++++------ .../block-library/src/form-input/editor.scss | 24 ++++++ packages/block-library/src/form-input/save.js | 6 +- .../src/form-input/variations.js | 13 +++ 7 files changed, 110 insertions(+), 25 deletions(-) create mode 100644 packages/block-library/src/form-input/editor.scss diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 7bb65de5578d9c..826a4b7f3129a0 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -294,7 +294,7 @@ The basic building block for forms. ([Source](https://github.com/WordPress/guten - **Category:** common - **Parent:** core/form - **Supports:** anchor, spacing (margin), ~~reusable~~ -- **Attributes:** inlineLabel, label, name, placeholder, required, type, visibilityPermissions +- **Attributes:** inlineLabel, label, name, placeholder, required, type, value, visibilityPermissions ## Form submit button diff --git a/packages/block-library/src/editor.scss b/packages/block-library/src/editor.scss index 07c58599c50980..459e8d4f0f3b31 100644 --- a/packages/block-library/src/editor.scss +++ b/packages/block-library/src/editor.scss @@ -16,6 +16,7 @@ @import "./details/editor.scss"; @import "./embed/editor.scss"; @import "./file/editor.scss"; +@import "./form-input/editor.scss"; @import "./freeform/editor.scss"; @import "./gallery/editor.scss"; @import "./group/editor.scss"; diff --git a/packages/block-library/src/form-input/block.json b/packages/block-library/src/form-input/block.json index 5ec76f719c3b17..dbe182f03b4992 100644 --- a/packages/block-library/src/form-input/block.json +++ b/packages/block-library/src/form-input/block.json @@ -42,6 +42,13 @@ "attribute": "placeholder", "__experimentalRole": "content" }, + "value": { + "type": "string", + "default": "", + "selector": "input", + "source": "attribute", + "attribute": "value" + }, "visibilityPermissions": { "type": "string", "default": "all" diff --git a/packages/block-library/src/form-input/edit.js b/packages/block-library/src/form-input/edit.js index 276a5c1bb4314c..acd20019620a35 100644 --- a/packages/block-library/src/form-input/edit.js +++ b/packages/block-library/src/form-input/edit.js @@ -19,7 +19,7 @@ import { PanelBody, TextControl, CheckboxControl } from '@wordpress/components'; import { useRef } from '@wordpress/element'; function InputFieldBlock( { attributes, setAttributes, className } ) { - const { type, name, label, inlineLabel, required, placeholder } = + const { type, name, label, inlineLabel, required, placeholder, value } = attributes; const blockProps = useBlockProps(); const ref = useRef(); @@ -33,28 +33,30 @@ function InputFieldBlock( { attributes, setAttributes, className } ) { const controls = ( <> - - - { - setAttributes( { - inlineLabel: newVal, - } ); - } } - /> - { - setAttributes( { - required: newVal, - } ); - } } - /> - - + { 'hidden' !== type && ( + + + { + setAttributes( { + inlineLabel: newVal, + } ); + } } + /> + { + setAttributes( { + required: newVal, + } ); + } } + /> + + + ) } ); + if ( 'hidden' === type ) { + return ( +
+ { controls } + + + setAttributes( { name: newValue } ) + } + aria-label={ __( 'Input name' ) } + placeholder={ __( 'Type the name for this input' ) } + /> + + setAttributes( { value: event.target.value } ) + } + /> + +
+ ); + } + return (
{ controls } diff --git a/packages/block-library/src/form-input/editor.scss b/packages/block-library/src/form-input/editor.scss new file mode 100644 index 00000000000000..2ac67e6615ed4a --- /dev/null +++ b/packages/block-library/src/form-input/editor.scss @@ -0,0 +1,24 @@ +.wp-block-form-input { + .is-input-hidden { + font-size: 0.85em; + opacity: 0.3; + border: 1px dashed; + padding: 0.5em; + box-sizing: border-box; + background: repeating-linear-gradient(45deg, transparent, transparent 5px, currentColor 5px, currentColor 6px); + + input[type="text"] { + background: transparent; + } + } + &.is-selected { + .is-input-hidden { + opacity: 1; + background: none; + + input[type="text"] { + background: unset; + } + } + } +} diff --git a/packages/block-library/src/form-input/save.js b/packages/block-library/src/form-input/save.js index 09ef9725ac01a6..0cca31ca423ee6 100644 --- a/packages/block-library/src/form-input/save.js +++ b/packages/block-library/src/form-input/save.js @@ -36,7 +36,7 @@ const getNameFromLabel = ( content ) => { }; export default function save( { attributes } ) { - const { type, name, label, inlineLabel, required, placeholder } = + const { type, name, label, inlineLabel, required, placeholder, value } = attributes; const borderProps = getBorderClassesAndStyles( attributes ); @@ -54,6 +54,10 @@ export default function save( { attributes } ) { ); const TagName = type === 'textarea' ? 'textarea' : 'input'; + if ( 'hidden' === type ) { + return ; + } + /* eslint-disable jsx-a11y/label-has-associated-control */ return (