Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce experimental form & inputs blocks to allow building basic forms #44214

Merged
merged 133 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
133 commits
Select commit Hold shift + click to select a range
cb1d87c
Initial forms POC
aristath Sep 16, 2022
e3f0028
this was just copy-pasted :facepalm:
aristath Sep 16, 2022
f54a4a8
Use RichText for labels
aristath Sep 20, 2022
3604793
Make things editable
aristath Sep 21, 2022
e57a178
Add initial PHP implementation & filters for form action & method
aristath Sep 21, 2022
0a72468
Add name attribute in fields
aristath Sep 21, 2022
9e58c75
rename action
aristath Sep 23, 2022
d9f587e
Default form submissions to POST instead of GET
aristath Sep 29, 2022
c47ee84
Add default action to send an email on form-submission
aristath Sep 29, 2022
68d4322
Move "name" attribute to the Advanced section.
aristath Oct 3, 2022
031e301
Add checkbox field-type
aristath Oct 3, 2022
ccbd777
update block.json
aristath Oct 3, 2022
f0f5fc8
Add a class on labels
aristath Oct 3, 2022
44fa12a
Add test stylesheet
aristath Oct 3, 2022
9cb6468
fix input styles loading
aristath Oct 3, 2022
ca6275a
basic styles
aristath Oct 3, 2022
26a5caf
split input-types array to a separate utils file
aristath Oct 3, 2022
a98ba8f
add ALLOWED_BLOCKS in forms
aristath Oct 17, 2022
ea55791
Add input fields variations
aristath Oct 17, 2022
2cfd077
fix admin styles for inputs
aristath Oct 17, 2022
0aed66e
refactor inline labels & other fixes
aristath Oct 17, 2022
a5423ab
Allow marking fields as required
aristath Oct 17, 2022
f4118df
Allow defining a form-ID
aristath Oct 17, 2022
08f761e
generate fixtures
aristath Oct 17, 2022
5d6a8e4
typo
aristath Oct 17, 2022
6022f68
forgot to rename these 2
aristath Oct 17, 2022
00e6211
Add a template
aristath Oct 18, 2022
f13aa48
Add block supports
aristath Oct 18, 2022
d91871f
Styling tweak
aristath Oct 18, 2022
9fad79b
Mark as an experiment
aristath Oct 18, 2022
774f31e
fixtures
aristath Oct 18, 2022
2b781a0
Rename input-field block to form-input
aristath Oct 24, 2022
2561516
Add default init.js file for the form-input block
aristath Oct 24, 2022
7812b80
Use WP_HTML_Tag_Processor
aristath Nov 9, 2022
791490e
use the HTML for the label
aristath Nov 9, 2022
06faa93
Use an attribute for "required"
aristath Nov 9, 2022
86427f0
fix for submit button label
aristath Nov 9, 2022
7316fb4
Add placeholder to inputs
aristath Nov 15, 2022
cdbf8ba
Revert "Add placeholder to inputs"
aristath Nov 15, 2022
dd3b81f
Remove identifier
aristath Nov 22, 2022
6fedc10
cleanup
aristath Nov 22, 2022
24280db
re-introduce placeholders
aristath Nov 22, 2022
3dcedc0
Use a div instead of label in the editor to avoid on-click focus issues
aristath Nov 22, 2022
e2a9153
Simplification for textareas
aristath Nov 22, 2022
b6c8210
Use the big appender when there are no inner blocks
aristath Nov 22, 2022
56d8240
Add form-submit-button block
aristath Nov 22, 2022
21344a5
implement form-submit button & improve variations
aristath Nov 22, 2022
9850eff
Add support for colors and border-radius to input blocks
aristath Nov 23, 2022
82a6319
make input fields select the block (wrong position for blockProps)
aristath Nov 23, 2022
50a9692
add __experimentalRole: content
aristath Nov 23, 2022
54e3888
fix HTML escaping in labels
aristath Nov 23, 2022
d407c4d
CSS fixes
aristath Nov 23, 2022
4d11133
Use a nonce to improve security
aristath Nov 23, 2022
bbfe6e9
Check that the nonce exists before checking its validity.
aristath Nov 24, 2022
dec8682
Use a new REST API endpoint for form submissions
aristath Nov 29, 2022
bb5b623
Add support for link-colors
aristath Dec 7, 2022
9a18c9b
Don't include rest_route in the email to be sent
aristath Dec 8, 2022
51b0243
Add icons
aristath Dec 20, 2022
1ed94f1
fix alignment of checkboxes
aristath Jan 13, 2023
2134093
Remove color options from fields
aristath Jan 13, 2023
92b0dfc
Add margins support to inputs + default margin-bottom
aristath Jan 13, 2023
0fbaa3a
Fix the name attribute generated from labels
aristath Jan 16, 2023
10632be
Move form-submissions class to the experimental folder
aristath Feb 15, 2023
7e907cd
Add a filter for wp_kses_allowed_html
aristath Feb 17, 2023
d3fee69
Move rest-api registration to 6.3
aristath Feb 17, 2023
a534371
change since to 6.3.0
aristath Feb 23, 2023
65aa09d
Fix method comment
aristath Mar 2, 2023
a66a8c4
Remove restriction (1 per page) in form-submit-button
aristath Mar 3, 2023
fc6a8e4
Add a bottom margin so that the appender can appear
aristath May 9, 2023
030f90e
Remove "Website" from default template
aristath May 9, 2023
c6e57bc
update the docs
aristath Jun 6, 2023
98785dd
Update packages/block-library/src/form-input/style.scss
aristath Jun 19, 2023
4175273
Move to experimental
aristath Jun 19, 2023
ed2174f
Remove default values from block.json
aristath Jun 20, 2023
44462ff
Tweak for comment-forms
aristath Jun 20, 2023
b40793e
fix rebase conflict
aristath Jun 20, 2023
6c93881
Use the sitename
aristath Jun 20, 2023
cf32b38
Fix URL
aristath Jun 20, 2023
8cf086e
Add advanced options to the form
aristath Jul 10, 2023
3a90982
Remove REST-API endpoint & use the advanced fields
aristath Jul 10, 2023
48691fe
Add back empty line
aristath Jul 10, 2023
93da56c
Only add `action` if not empty
aristath Jul 10, 2023
b846130
Handle contact forms
aristath Jul 10, 2023
680e79f
Change help text to clarify what happens when value is empty
aristath Jul 10, 2023
10781a9
fix doc
aristath Jul 11, 2023
bd47c0c
Add comment-form variation
aristath Jul 11, 2023
e540608
Remove icon from comment-form variation
aristath Jul 11, 2023
f9d4504
Handle GET data in contact forms as well
aristath Jul 11, 2023
75ac288
Redirect to same page on contact-form submission
aristath Jul 11, 2023
c19ff54
Increase padding-bottom to 0.5em
aristath Jul 11, 2023
e748cda
Remove formId attribute. We already have an anchor
aristath Jul 11, 2023
2c34b2d
labels cannot include div elements. Use a span instead.
aristath Jul 14, 2023
325e4c3
textarea elements should not have a type defined.
aristath Jul 14, 2023
82dd142
manually update fixtures
aristath Jul 14, 2023
1c5e437
Move inspector controls from advanced section to normal
aristath Jul 17, 2023
b22b075
Add visibilityPermissions attribute
aristath Jul 17, 2023
e5f9158
Rename comment-form variation
aristath Jul 17, 2023
6de676c
Add option to send email, and a field to define the address
aristath Jul 31, 2023
6eac41a
Filter the email content to allow 3rd-party plugins to change things
aristath Jul 31, 2023
2ba5cc3
Basic sanitization for the email content
aristath Jul 31, 2023
474aa80
Code improvement
aristath Jul 31, 2023
e6e92e9
Add render_block_core_form_email_sent action
aristath Aug 1, 2023
e7745d6
It's possible to use comma-separated values for the email address
aristath Aug 1, 2023
55168e3
Add a `hidden` input-type
aristath Aug 3, 2023
115de36
remove columns and groups for now
aristath Aug 3, 2023
f5aba1a
Checkbox labels should always be inline
aristath Aug 3, 2023
da0d125
Default inlineLabel to true for checkboxes
aristath Aug 3, 2023
2d7562c
coding fix
aristath Aug 3, 2023
c9b132c
Add ADMIN_URL placeholder (facilitates ajax requests)
aristath Aug 4, 2023
237ef10
Add a privacy-request form
aristath Aug 4, 2023
00fa2ea
Make methods hookable
aristath Aug 7, 2023
1f87413
Add form-submission-notification block
aristath Aug 8, 2023
1cab064
add it to the list of allowed blocks
aristath Aug 8, 2023
eb2cfa0
add form notifications to variations
aristath Aug 9, 2023
cf2fbee
improve default notifications
aristath Aug 9, 2023
c37baab
Now that we have variations we don't need the separate control
aristath Aug 9, 2023
3b3bf18
Default to success notification
aristath Aug 9, 2023
320d427
Add editor styles for notifications
aristath Aug 9, 2023
b4c93aa
condition is not necessary
aristath Aug 9, 2023
ce6c9b7
Remove redirect for emails forms. Still buggy, need to figure out smthng
aristath Aug 9, 2023
c18d3bf
Refactor emails form & add a view script
aristath Aug 11, 2023
50a5528
Don't show `hidden` inputs in the UI
aristath Aug 24, 2023
45c61d8
rename functions
aristath Aug 24, 2023
1f315d6
Update styles for notifications in the editor
aristath Aug 24, 2023
39be966
remove hidden variation
aristath Aug 24, 2023
dabde4c
Remove formOptions & fix controls spacing
aristath Sep 7, 2023
669ee86
fix styles for inline labels
aristath Sep 8, 2023
dda5880
CS fix
aristath Sep 25, 2023
0d64f85
Check if the experiment is enabled before registering the blocks
aristath Oct 4, 2023
3e480b6
Only localize the script if the experiment is enabled
aristath Oct 4, 2023
77d132a
Only filter wp_kses_allowed_html if the experiment is active
aristath Oct 4, 2023
695de74
fix filter return
aristath Oct 4, 2023
8f7fc17
Add experiment to the tests
aristath Oct 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,45 @@ 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:** anchor, color (background, gradients, link, text), spacing (margin, padding), typography (fontSize, lineHeight), ~~className~~
- **Attributes:** action, email, method, submissionMethod

## 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
- **Parent:** core/form
- **Supports:** anchor, spacing (margin), ~~reusable~~
- **Attributes:** inlineLabel, label, name, placeholder, required, type, value, visibilityPermissions

## Form Submission Notification

Provide a notification message after the form has been submitted. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/form-submission-notification))

- **Name:** core/form-submission-notification
- **Category:** common
- **Parent:** core/form
- **Supports:**
- **Attributes:** type

## Form submit button

A submission button for forms. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/form-submit-button))

- **Name:** core/form-submit-button
- **Category:** common
- **Parent:** core/form
- **Supports:**
- **Attributes:**

## Classic

Use the classic WordPress editor. ([Source](https://github.com/WordPress/gutenberg/tree/trunk/packages/block-library/src/freeform))
Expand Down
5 changes: 5 additions & 0 deletions lib/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ function gutenberg_reregister_core_block_types() {
'column',
'columns',
'details',
'form-input',
'form-submit-button',
'group',
'html',
'list',
Expand Down Expand Up @@ -66,6 +68,9 @@ function gutenberg_reregister_core_block_types() {
'comments.php' => 'core/comments',
'footnotes.php' => 'core/footnotes',
'file.php' => 'core/file',
'form.php' => 'core/form',
'form-input.php' => 'core/form-input',
'form-submission-notification.php' => 'core/form-submission-notification',
'home-link.php' => 'core/home-link',
'image.php' => 'core/image',
'gallery.php' => 'core/gallery',
Expand Down
12 changes: 12 additions & 0 deletions lib/experimental/editor-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' );
43 changes: 43 additions & 0 deletions lib/experimental/kses-allowed-html.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Modifies the wp_kses_allowed_html array.
*
* @package gutenberg
*/

/**
* Add the form elements to the allowed tags array.
*
* @param array $allowedtags The allowed tags.
*
* @return array The allowed tags.
*/
function gutenberg_kses_allowed_html( $allowedtags ) {
if ( ! gutenberg_is_experiment_enabled( 'gutenberg-form-blocks' ) ) {
return $allowedtags;
}

$allowedtags['input'] = array(
'type' => array(),
'name' => array(),
'value' => array(),
'checked' => array(),
'required' => array(),
'aria-required' => array(),
'class' => array(),
);

$allowedtags['label'] = array(
'for' => array(),
'class' => array(),
);

$allowedtags['textarea'] = array(
'name' => array(),
'required' => array(),
'aria-required' => array(),
'class' => array(),
);
return $allowedtags;
}
add_filter( 'wp_kses_allowed_html', 'gutenberg_kses_allowed_html', 10, 2 );
aristath marked this conversation as resolved.
Show resolved Hide resolved
11 changes: 11 additions & 0 deletions lib/experiments-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
2 changes: 2 additions & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ function gutenberg_is_experiment_enabled( $name ) {
}
require_once __DIR__ . '/experimental/class-gutenberg-rest-template-revision-count.php';
require_once __DIR__ . '/experimental/rest-api.php';

require_once __DIR__ . '/experimental/kses-allowed-html.php';
}

require __DIR__ . '/experimental/editor-settings.php';
Expand Down
2 changes: 2 additions & 0 deletions packages/block-library/src/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
@import "./details/editor.scss";
@import "./embed/editor.scss";
@import "./file/editor.scss";
@import "./form-input/editor.scss";
@import "./form-submission-notification/editor.scss";
draganescu marked this conversation as resolved.
Show resolved Hide resolved
@import "./freeform/editor.scss";
@import "./gallery/editor.scss";
@import "./group/editor.scss";
Expand Down
72 changes: 72 additions & 0 deletions packages/block-library/src/form-input/block.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "core/form-input",
"title": "Input field",
"category": "common",
"parent": [ "core/form" ],
"description": "The basic building block for forms.",
"keywords": [ "input", "form" ],
"textdomain": "default",
"icon": "forms",
"attributes": {
"type": {
"type": "string",
"default": "text"
},
"name": {
"type": "string"
},
"label": {
"type": "string",
"default": "Label",
"selector": ".wp-block-form-input__label-content",
"source": "html",
"__experimentalRole": "content"
},
"inlineLabel": {
fabiankaegy marked this conversation as resolved.
Show resolved Hide resolved
"type": "boolean",
"default": false
},
"required": {
"type": "boolean",
"default": false,
"selector": ".wp-block-form-input__input",
"source": "attribute",
"attribute": "required"
},
"placeholder": {
"type": "string",
"selector": ".wp-block-form-input__input",
"source": "attribute",
"attribute": "placeholder",
"__experimentalRole": "content"
},
"value": {
"type": "string",
"default": "",
"selector": "input",
"source": "attribute",
"attribute": "value"
},
"visibilityPermissions": {
"type": "string",
"default": "all"
}
fabiankaegy marked this conversation as resolved.
Show resolved Hide resolved
},
"supports": {
"anchor": true,
"reusable": false,
"spacing": {
"margin": [ "top", "bottom" ]
},
"__experimentalBorder": {
"radius": true,
"__experimentalSkipSerialization": true,
"__experimentalDefaultControls": {
"radius": true
}
}
},
"style": [ "wp-block-form-input" ]
}
151 changes: 151 additions & 0 deletions packages/block-library/src/form-input/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/**
* External dependencies
*/
import classNames from 'classnames';

/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import {
InspectorControls,
RichText,
useBlockProps,
__experimentalUseBorderProps as useBorderProps,
__experimentalUseColorProps as useColorProps,
} from '@wordpress/block-editor';
import { PanelBody, TextControl, CheckboxControl } from '@wordpress/components';

import { useRef } from '@wordpress/element';

function InputFieldBlock( { attributes, setAttributes, className } ) {
const { type, name, label, inlineLabel, required, placeholder, value } =
attributes;
const blockProps = useBlockProps();
const ref = useRef();
const TagName = type === 'textarea' ? 'textarea' : 'input';

const borderProps = useBorderProps( attributes );
const colorProps = useColorProps( attributes );
if ( ref.current ) {
ref.current.focus();
}

const controls = (
<>
{ 'hidden' !== type && (
<InspectorControls>
<PanelBody title={ __( 'Input settings' ) }>
{ 'checkbox' !== type && (
<CheckboxControl
label={ __( 'Inline label' ) }
checked={ inlineLabel }
onChange={ ( newVal ) => {
setAttributes( {
inlineLabel: newVal,
} );
} }
/>
) }
<CheckboxControl
label={ __( 'Required' ) }
checked={ required }
onChange={ ( newVal ) => {
setAttributes( {
required: newVal,
} );
} }
/>
</PanelBody>
</InspectorControls>
) }
<InspectorControls __experimentalGroup="advanced">
<TextControl
autoComplete="off"
label={ __( 'Name' ) }
value={ name }
onChange={ ( newVal ) => {
setAttributes( {
name: newVal,
} );
} }
help={ __(
'Affects the "name" atribute of the input element, and is used as a name for the form submission results.'
) }
/>
</InspectorControls>
</>
);

if ( 'hidden' === type ) {
return (
<>
{ controls }
<input
type="hidden"
className={ classNames(
className,
'wp-block-form-input__input',
colorProps.className,
borderProps.className
) }
aria-label={ __( 'Value' ) }
value={ value }
onChange={ ( event ) =>
setAttributes( { value: event.target.value } )
}
/>
</>
);
}

return (
<div { ...blockProps }>
{ controls }
<span
className={ classNames( 'wp-block-form-input__label', {
'is-label-inline': inlineLabel || 'checkbox' === type,
} ) }
>
<RichText
tagName="span"
className="wp-block-form-input__label-content"
value={ label }
onChange={ ( newLabel ) =>
setAttributes( { label: newLabel } )
}
aria-label={ label ? __( 'Label' ) : __( 'Empty label' ) }
data-empty={ label ? false : true }
placeholder={ __( 'Type the label for this input' ) }
/>
<TagName
type={ 'textarea' === type ? undefined : type }
className={ classNames(
className,
'wp-block-form-input__input',
colorProps.className,
borderProps.className
) }
aria-label={ __( 'Optional placeholder text' ) }
// We hide the placeholder field's placeholder when there is a value. This
// stops screen readers from reading the placeholder field's placeholder
// which is confusing.
placeholder={
placeholder ? undefined : __( 'Optional placeholder…' )
}
value={ placeholder }
onChange={ ( event ) =>
setAttributes( { placeholder: event.target.value } )
}
aria-required={ required }
style={ {
...borderProps.style,
...colorProps.style,
} }
/>
</span>
</div>
);
}

export default InputFieldBlock;
Loading
Loading