diff --git a/projects/packages/forms/changelog/update-forms-text-field-height-input b/projects/packages/forms/changelog/update-forms-text-field-height-input
new file mode 100644
index 000000000000..9c99b033b531
--- /dev/null
+++ b/projects/packages/forms/changelog/update-forms-text-field-height-input
@@ -0,0 +1,4 @@
+Significance: minor
+Type: added
+
+Forms: allow resizing height of multi line text field
diff --git a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php
index 81b90d613a8f..a39f8925d324 100644
--- a/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php
+++ b/projects/packages/forms/src/blocks/contact-form/class-contact-form-block.php
@@ -144,6 +144,11 @@ public static function register_child_blocks() {
'color' => '.wp-block-jetpack-input, .is-style-outlined .notched-label:has(+ .wp-block-jetpack-input) > *,.is-style-outlined .wp-block-jetpack-input + .notched-label > *, .is-style-outlined .wp-block-jetpack-field-select .notched-label > *',
),
'uses_context' => array( 'jetpack/field-default-value' ),
+ 'attributes' => array(
+ 'height' => array(
+ 'type' => 'string',
+ ),
+ ),
)
);
Blocks::jetpack_register_block(
diff --git a/projects/packages/forms/src/blocks/input/edit.js b/projects/packages/forms/src/blocks/input/edit.js
index a76b42194af9..2f6f7cab530b 100644
--- a/projects/packages/forms/src/blocks/input/edit.js
+++ b/projects/packages/forms/src/blocks/input/edit.js
@@ -1,5 +1,15 @@
-import { InspectorControls, RichText, useBlockProps } from '@wordpress/block-editor';
-import { PanelBody, __experimentalNumberControl as NumberControl } from '@wordpress/components'; // eslint-disable-line @wordpress/no-unsafe-wp-apis
+import {
+ InspectorControls,
+ RichText,
+ store as blockEditorStore,
+ useBlockProps,
+} from '@wordpress/block-editor';
+import {
+ __experimentalNumberControl as NumberControl, // eslint-disable-line @wordpress/no-unsafe-wp-apis
+ PanelBody,
+ ResizableBox,
+} from '@wordpress/components';
+import { useSelect } from '@wordpress/data';
import { useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { clsx } from 'clsx';
@@ -29,10 +39,18 @@ const getInputClass = type => {
return 'jetpack-field__input';
};
-const InputEdit = ( { attributes, clientId, isSelected, name, setAttributes, context } ) => {
+const InputEdit = ( {
+ attributes,
+ clientId,
+ context,
+ isSelected,
+ name,
+ setAttributes,
+ toggleSelection,
+} ) => {
const { 'jetpack/field-share-attributes': isSynced } = context;
useSyncedAttributes( name, isSynced, SYNCED_ATTRIBUTE_KEYS, attributes, setAttributes );
- const { max, min, placeholder, type } = attributes;
+ const { max, min, height, placeholder, type } = attributes;
const variationProps = useVariationStyleProperties( {
clientId,
inputBlockName: name,
@@ -44,6 +62,17 @@ const InputEdit = ( { attributes, clientId, isSelected, name, setAttributes, con
const blockProps = useBlockProps( { className, style: variationProps?.cssVars } );
const onKeyDown = useInsertAfterOnEnterKeyDown( clientId );
+ // Check if the parent block (e.g. textarea-field) is selected
+ const isParentSelected = useSelect(
+ select => {
+ const { getBlockRootClientId, getSelectedBlockClientId } = select( blockEditorStore );
+ const parentClientId = getBlockRootClientId( clientId );
+ const selectedBlockClientId = getSelectedBlockClientId();
+ return parentClientId && parentClientId === selectedBlockClientId;
+ },
+ [ clientId ]
+ );
+
const onChange = useCallback(
event => {
if ( type !== 'time' ) {
@@ -68,13 +97,39 @@ const InputEdit = ( { attributes, clientId, isSelected, name, setAttributes, con
}
if ( type === 'textarea' ) {
+ const currentHeight = height
+ ? parseInt( typeof height === 'string' ? height.replace( 'px', '' ) : height, 10 ) || 200
+ : 200;
+
return (
-
+ {
+ const newHeight = currentHeight + delta.height;
+ setAttributes( {
+ height: `${ newHeight }px`,
+ } );
+ toggleSelection( true );
+ } }
+ onResizeStart={ () => {
+ toggleSelection( false );
+ } }
+ showHandle={ isSelected || isParentSelected }
+ >
+
+
);
}
diff --git a/projects/packages/forms/src/blocks/input/index.js b/projects/packages/forms/src/blocks/input/index.js
index f7220f38636a..ebb23c5486c9 100644
--- a/projects/packages/forms/src/blocks/input/index.js
+++ b/projects/packages/forms/src/blocks/input/index.js
@@ -69,6 +69,9 @@ const settings = {
type: { type: 'string' },
min: { type: 'number' },
max: { type: 'number' },
+ height: {
+ type: 'string',
+ },
},
edit,
save,
diff --git a/projects/packages/forms/src/contact-form/class-contact-form-field.php b/projects/packages/forms/src/contact-form/class-contact-form-field.php
index 6fce4b93dbe8..a01e0315dbb2 100644
--- a/projects/packages/forms/src/contact-form/class-contact-form-field.php
+++ b/projects/packages/forms/src/contact-form/class-contact-form-field.php
@@ -174,6 +174,8 @@ public function __construct( $attributes, $content = null, $form = null ) {
'showotheroption' => null,
// derived from block metadata for blockVisibility support
'labelhiddenbyblockvisibility' => null,
+ // support resizeable textarea
+ 'height' => null,
),
$attributes,
'contact-field'
@@ -663,6 +665,10 @@ public function render() {
$extra_attrs = array();
+ if ( $field_type === 'textarea' && ! empty( $this->get_attribute( 'height' ) ) ) {
+ $extra_attrs['height'] = $this->get_attribute( 'height' );
+ }
+
if ( $field_type === 'number' || $field_type === 'slider' ) {
if ( is_numeric( $this->get_attribute( 'min' ) ) ) {
$extra_attrs['min'] = $this->get_attribute( 'min' );
@@ -1197,22 +1203,26 @@ public function render_url_field( $id, $label, $value, $class, $required, $requi
* @param bool $required - if the field is marked as required.
* @param string $required_field_text - the text in the required text field.
* @param string $placeholder - the field placeholder content.
+ * @param array $extra_attrs Extra attributes (e.g., height).
* @param bool $required_indicator Whether to display the required indicator.
*
* @return string HTML
*/
- public function render_textarea_field( $id, $label, $value, $class, $required, $required_field_text, $placeholder, $required_indicator = true ) {
+ public function render_textarea_field( $id, $label, $value, $class, $required, $required_field_text, $placeholder, $extra_attrs = array(), $required_indicator = true ) {
if ( ! is_string( $value ) ) {
$value = '';
}
+ if ( isset( $extra_attrs['height'] ) ) {
+ $this->field_styles .= 'height: ' . esc_attr( $extra_attrs['height'] ) . ';';
+ }
+
$field = $this->render_label( 'textarea', 'contact-form-comment-' . $id, $label, $required, $required_field_text, array(), false, $required_indicator );
$aria_label = ! empty( $placeholder ) ? $placeholder : Contact_Form_Plugin::strip_tags( $this->get_attribute( 'label' ) );
$field .= "