From 073241ea983708fe31b771af02b05a7ed620714b Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Thu, 17 Jul 2025 14:48:15 +0300 Subject: [PATCH 01/18] Forms: explore using inner blocks for dropdown --- .../src/blocks/contact-form/child-blocks.js | 2 + .../forms/src/blocks/dropdown/edit.js | 35 ++++++++++ .../forms/src/blocks/dropdown/editor.scss | 6 ++ .../forms/src/blocks/dropdown/index.js | 70 +++++++++++++++++++ .../forms/src/blocks/dropdown/save.js | 7 ++ .../forms/src/blocks/field-select/edit.js | 5 +- .../class-contact-form-plugin.php | 14 ++++ 7 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 projects/packages/forms/src/blocks/dropdown/edit.js create mode 100644 projects/packages/forms/src/blocks/dropdown/editor.scss create mode 100644 projects/packages/forms/src/blocks/dropdown/index.js create mode 100644 projects/packages/forms/src/blocks/dropdown/save.js diff --git a/projects/packages/forms/src/blocks/contact-form/child-blocks.js b/projects/packages/forms/src/blocks/contact-form/child-blocks.js index fa9131225dcc9..e999eb7f5837f 100644 --- a/projects/packages/forms/src/blocks/contact-form/child-blocks.js +++ b/projects/packages/forms/src/blocks/contact-form/child-blocks.js @@ -4,6 +4,7 @@ import { } from '@automattic/jetpack-shared-extension-utils'; import DeprecatedOptionCheckbox from '../deprecated/field-option-checkbox'; import DeprecatedOptionRadio from '../deprecated/field-option-radio'; +import JetpackDropdown from '../dropdown'; import JetpackDropzone from '../dropzone'; import JetpackCheckboxField from '../field-checkbox'; import JetpackConsentField from '../field-consent/'; @@ -42,6 +43,7 @@ import JetpackOptions from '../options'; export const childBlocks = [ JetpackLabel, JetpackDropzone, + JetpackDropdown, JetpackInput, JetpackOption, JetpackOptions, diff --git a/projects/packages/forms/src/blocks/dropdown/edit.js b/projects/packages/forms/src/blocks/dropdown/edit.js new file mode 100644 index 0000000000000..75e3cda3b4895 --- /dev/null +++ b/projects/packages/forms/src/blocks/dropdown/edit.js @@ -0,0 +1,35 @@ +import { InnerBlocks, useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor'; +import { __ } from '@wordpress/i18n'; + +import './editor.scss'; + +const DEFAULT_BLOCK = { + name: 'core/paragraph', + attributes: { placeholder: __( 'Add option…', 'jetpack-forms' ) }, +}; + +const BLOCKS_TEMPLATE = [ + [ + DEFAULT_BLOCK.name, + { + ...DEFAULT_BLOCK.attributes, + }, + ], +]; + +export default function DropdownEdit() { + const blockProps = useBlockProps( { className: 'jetpack-field-dropdown__popover' } ); + const innerBlocksProps = useInnerBlocksProps( blockProps ); + + return ( +
+ +
+ ); +} diff --git a/projects/packages/forms/src/blocks/dropdown/editor.scss b/projects/packages/forms/src/blocks/dropdown/editor.scss new file mode 100644 index 0000000000000..5c0dc40c14049 --- /dev/null +++ b/projects/packages/forms/src/blocks/dropdown/editor.scss @@ -0,0 +1,6 @@ +.wp-block-jetpack-dropdown { + + p { + margin-bottom: 10px + } +} \ No newline at end of file diff --git a/projects/packages/forms/src/blocks/dropdown/index.js b/projects/packages/forms/src/blocks/dropdown/index.js new file mode 100644 index 0000000000000..6edd3e6788eac --- /dev/null +++ b/projects/packages/forms/src/blocks/dropdown/index.js @@ -0,0 +1,70 @@ +import { __ } from '@wordpress/i18n'; +import { menu } from '@wordpress/icons'; +import { getIconColor } from '../shared/util/block-icons'; +import edit from './edit'; +import save from './save'; + +const name = 'dropdown'; +const settings = { + apiVersion: 3, + title: __( 'Dropdown', 'jetpack-forms' ), + description: __( 'Options for dropdown fields.', 'jetpack-forms' ), + parent: [ 'jetpack/field-select' ], + allowedBlocks: [ 'core/paragraph' ], + category: 'contact-form', + icon: { + foreground: getIconColor(), + src: menu, + }, + attributes: { + style: { + type: 'object', + default: { + dimensions: { + maxHeight: '350px', + }, + }, + }, + }, + supports: { + reusable: false, + html: false, + color: { + gradients: true, + heading: true, + button: true, + link: true, + __experimentalDefaultControls: { + background: true, + text: true, + }, + }, + spacing: { + margin: [ 'top' ], + padding: true, + }, + dimensions: { + minHeight: true, + maxHeight: true, // Doesn't work :-( + }, + __experimentalBorder: { + color: true, + radius: true, + style: true, + width: true, + __experimentalDefaultControls: { + color: true, + radius: true, + style: true, + width: true, + }, + }, + }, + edit, + save, +}; + +export default { + name, + settings, +}; diff --git a/projects/packages/forms/src/blocks/dropdown/save.js b/projects/packages/forms/src/blocks/dropdown/save.js new file mode 100644 index 0000000000000..d1f7875a14526 --- /dev/null +++ b/projects/packages/forms/src/blocks/dropdown/save.js @@ -0,0 +1,7 @@ +import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor'; + +export default () => { + const blockProps = useBlockProps.save(); + const innerBlocksProps = useInnerBlocksProps.save( blockProps ); + return
; +}; diff --git a/projects/packages/forms/src/blocks/field-select/edit.js b/projects/packages/forms/src/blocks/field-select/edit.js index daa58d46992cc..49d27ebff9713 100644 --- a/projects/packages/forms/src/blocks/field-select/edit.js +++ b/projects/packages/forms/src/blocks/field-select/edit.js @@ -52,13 +52,14 @@ export default function DropdownFieldEdit( props ) { 'jetpack/input', { type: 'dropdown', placeholder: __( 'Select one option', 'jetpack-forms' ) }, ], + [ 'jetpack/dropdown', { options, lock: { move: true, remove: true } } ], ]; - }, [ required ] ); + }, [ required, options ] ); const innerBlocksProps = useInnerBlocksProps( { className: 'jetpack-field-dropdown__wrapper' }, { - allowedBlocks: ALLOWED_INNER_BLOCKS, + allowedBlocks: [ ...ALLOWED_INNER_BLOCKS, 'jetpack/dropdown' ], template, templateLock: 'all', } diff --git a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php index 7b15940968a4d..f5828c6ed746f 100644 --- a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php +++ b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php @@ -1242,6 +1242,20 @@ public static function gutenblock_render_field_file( $atts, $content, $block ) { return $output; } + + /** + * Render the dropdown field. + * + * @param array $atts - the block attributes. + * @param string $content - html content. + * + * @return string HTML for the dropdown in select field. + */ + public static function gutenblock_render_dropdown( $atts, $content ) { + + return $content; + } + /** * Render the dropzone field. * From 8f1c2c567bacaf749d999cdb432887314e827760 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Thu, 17 Jul 2025 14:57:23 +0300 Subject: [PATCH 02/18] Use useInnerBlocksProps --- .../forms/src/blocks/dropdown/edit.js | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/projects/packages/forms/src/blocks/dropdown/edit.js b/projects/packages/forms/src/blocks/dropdown/edit.js index 75e3cda3b4895..150b46c6561ee 100644 --- a/projects/packages/forms/src/blocks/dropdown/edit.js +++ b/projects/packages/forms/src/blocks/dropdown/edit.js @@ -19,17 +19,14 @@ const BLOCKS_TEMPLATE = [ export default function DropdownEdit() { const blockProps = useBlockProps( { className: 'jetpack-field-dropdown__popover' } ); - const innerBlocksProps = useInnerBlocksProps( blockProps ); + const innerBlocksProps = useInnerBlocksProps( blockProps, { + __experimentalCaptureToolbars: true, + defaultBlock: DEFAULT_BLOCK, + directInsert: true, + renderAppender: InnerBlocks.DefaultBlockAppender, + template: BLOCKS_TEMPLATE, + templateLock: false, + } ); - return ( -
- -
- ); + return
{ innerBlocksProps.children }
; } From 296c97e8d1bb921ea3a8e6ebf079a24aaea6cd1b Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Thu, 17 Jul 2025 17:40:20 +0300 Subject: [PATCH 03/18] Use dropdown option sub block --- .../src/blocks/contact-form/child-blocks.js | 2 + .../contact-form/class-contact-form-block.php | 14 +++++ .../forms/src/blocks/dropdown-option/edit.js | 52 +++++++++++++++++++ .../forms/src/blocks/dropdown-option/index.js | 32 ++++++++++++ .../forms/src/blocks/dropdown-option/save.js | 7 +++ .../forms/src/blocks/dropdown/edit.js | 27 +++++----- .../forms/src/blocks/dropdown/index.js | 6 +-- .../use-insert-after-on-enter-key-down.js | 6 +-- .../class-contact-form-plugin.php | 13 ++++- 9 files changed, 140 insertions(+), 19 deletions(-) create mode 100644 projects/packages/forms/src/blocks/dropdown-option/edit.js create mode 100644 projects/packages/forms/src/blocks/dropdown-option/index.js create mode 100644 projects/packages/forms/src/blocks/dropdown-option/save.js diff --git a/projects/packages/forms/src/blocks/contact-form/child-blocks.js b/projects/packages/forms/src/blocks/contact-form/child-blocks.js index e999eb7f5837f..56c0c9c3cb362 100644 --- a/projects/packages/forms/src/blocks/contact-form/child-blocks.js +++ b/projects/packages/forms/src/blocks/contact-form/child-blocks.js @@ -5,6 +5,7 @@ import { import DeprecatedOptionCheckbox from '../deprecated/field-option-checkbox'; import DeprecatedOptionRadio from '../deprecated/field-option-radio'; import JetpackDropdown from '../dropdown'; +import JetpackDropdownOption from '../dropdown-option'; import JetpackDropzone from '../dropzone'; import JetpackCheckboxField from '../field-checkbox'; import JetpackConsentField from '../field-consent/'; @@ -44,6 +45,7 @@ export const childBlocks = [ JetpackLabel, JetpackDropzone, JetpackDropdown, + JetpackDropdownOption, JetpackInput, JetpackOption, JetpackOptions, 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 351b66ca93a4d..88d1a37c4f527 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 @@ -445,6 +445,20 @@ public static function register_child_blocks() { ) ); + Blocks::jetpack_register_block( + 'jetpack/dropdown', + array( + 'render_callback' => array( Contact_Form_Plugin::class, 'gutenblock_render_dropdown' ), + ) + ); + + Blocks::jetpack_register_block( + 'jetpack/dropdown-option', + array( + 'render_callback' => array( Contact_Form_Plugin::class, 'gutenblock_render_dropdown_option' ), + ) + ); + if ( Blocks::get_variation() === 'beta' ) { Blocks::jetpack_register_block( 'jetpack/field-hidden', diff --git a/projects/packages/forms/src/blocks/dropdown-option/edit.js b/projects/packages/forms/src/blocks/dropdown-option/edit.js new file mode 100644 index 0000000000000..bb1015ba90abb --- /dev/null +++ b/projects/packages/forms/src/blocks/dropdown-option/edit.js @@ -0,0 +1,52 @@ +import { RichText, useBlockProps, store as blockEditorStore } from '@wordpress/block-editor'; +import { Button, Flex, FlexItem } from '@wordpress/components'; +import { useDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { close } from '@wordpress/icons'; +import useInsertAfterOnEnterKeyDown from '../shared/hooks/use-insert-after-on-enter-key-down'; + +const noop = () => undefined; + +export default function DropdownOptionEdit( props ) { + // eslint-disable-next-line no-console + console.log( props ); + const { attributes, clientId, setAttributes, name } = props; + const { option } = attributes; + const className = 'jetpack-field-dropdown__option'; + const blockProps = useBlockProps( { className } ); + const onKeyDown = useInsertAfterOnEnterKeyDown( clientId, name ); + + const { removeBlocks } = useDispatch( blockEditorStore ); // insertAfterBlock + + const onRemove = () => { + return removeBlocks( clientId ); + }; + + return ( +
+ + + setAttributes( { option: value } ) } + onKeyDown={ onKeyDown } + onRemove={ onRemove } + onReplace={ noop } + placeholder={ __( 'Add option…', 'jetpack-forms' ) } + value={ option || '' } + withoutInteractiveFormatting + /> + + + + + +
+ ); +} diff --git a/projects/packages/forms/src/blocks/dropdown-option/index.js b/projects/packages/forms/src/blocks/dropdown-option/index.js new file mode 100644 index 0000000000000..959c2a3fdfff7 --- /dev/null +++ b/projects/packages/forms/src/blocks/dropdown-option/index.js @@ -0,0 +1,32 @@ +import { __ } from '@wordpress/i18n'; +import { lineSolid } from '@wordpress/icons'; +import { getIconColor } from '../shared/util/block-icons'; +import edit from './edit'; +import save from './save'; + +const name = 'dropdown-option'; +const settings = { + apiVersion: 3, + title: __( 'Option', 'jetpack-forms' ), + description: __( 'Option for dropdown fields.', 'jetpack-forms' ), + parent: [ 'jetpack/dropdown' ], + category: 'contact-form', + icon: { + foreground: getIconColor(), + src: lineSolid, + }, + attributes: { option: { type: 'string', default: '' } }, + supports: { + anchor: false, + customClassName: false, + html: false, + reusable: false, + }, + edit, + save, +}; + +export default { + name, + settings, +}; diff --git a/projects/packages/forms/src/blocks/dropdown-option/save.js b/projects/packages/forms/src/blocks/dropdown-option/save.js new file mode 100644 index 0000000000000..38da9345a3943 --- /dev/null +++ b/projects/packages/forms/src/blocks/dropdown-option/save.js @@ -0,0 +1,7 @@ +import { useBlockProps, RichText } from '@wordpress/block-editor'; + +export default ( { attributes } ) => { + const blockProps = useBlockProps.save(); + + return ; +}; diff --git a/projects/packages/forms/src/blocks/dropdown/edit.js b/projects/packages/forms/src/blocks/dropdown/edit.js index 150b46c6561ee..702c4ce17d348 100644 --- a/projects/packages/forms/src/blocks/dropdown/edit.js +++ b/projects/packages/forms/src/blocks/dropdown/edit.js @@ -1,11 +1,10 @@ import { InnerBlocks, useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor'; -import { __ } from '@wordpress/i18n'; import './editor.scss'; const DEFAULT_BLOCK = { - name: 'core/paragraph', - attributes: { placeholder: __( 'Add option…', 'jetpack-forms' ) }, + name: 'jetpack/dropdown-option', + attributes: {}, }; const BLOCKS_TEMPLATE = [ @@ -19,14 +18,18 @@ const BLOCKS_TEMPLATE = [ export default function DropdownEdit() { const blockProps = useBlockProps( { className: 'jetpack-field-dropdown__popover' } ); - const innerBlocksProps = useInnerBlocksProps( blockProps, { - __experimentalCaptureToolbars: true, - defaultBlock: DEFAULT_BLOCK, - directInsert: true, - renderAppender: InnerBlocks.DefaultBlockAppender, - template: BLOCKS_TEMPLATE, - templateLock: false, - } ); + const innerBlocksProps = useInnerBlocksProps( blockProps ); - return
{ innerBlocksProps.children }
; + return ( +
+ +
+ ); } diff --git a/projects/packages/forms/src/blocks/dropdown/index.js b/projects/packages/forms/src/blocks/dropdown/index.js index 6edd3e6788eac..2f2fd6a537937 100644 --- a/projects/packages/forms/src/blocks/dropdown/index.js +++ b/projects/packages/forms/src/blocks/dropdown/index.js @@ -10,7 +10,7 @@ const settings = { title: __( 'Dropdown', 'jetpack-forms' ), description: __( 'Options for dropdown fields.', 'jetpack-forms' ), parent: [ 'jetpack/field-select' ], - allowedBlocks: [ 'core/paragraph' ], + allowedBlocks: [ 'jetpack/dropdown-option' ], category: 'contact-form', icon: { foreground: getIconColor(), @@ -20,8 +20,8 @@ const settings = { style: { type: 'object', default: { - dimensions: { - maxHeight: '350px', + spacing: { + margin: { top: '10px' }, }, }, }, diff --git a/projects/packages/forms/src/blocks/shared/hooks/use-insert-after-on-enter-key-down.js b/projects/packages/forms/src/blocks/shared/hooks/use-insert-after-on-enter-key-down.js index 657ba3fbd939c..2863fad64ff75 100644 --- a/projects/packages/forms/src/blocks/shared/hooks/use-insert-after-on-enter-key-down.js +++ b/projects/packages/forms/src/blocks/shared/hooks/use-insert-after-on-enter-key-down.js @@ -3,7 +3,7 @@ import { createBlock, getDefaultBlockName } from '@wordpress/blocks'; import { useSelect, useDispatch } from '@wordpress/data'; import { useCallback } from '@wordpress/element'; -export default function ( clientId, isParent = false ) { +export default function ( clientId, isParent = false, defaultBlockName ) { const { fieldParentId, parentIndex, formParentId } = useSelect( select => { const blockEditor = select( blockEditorStore ); @@ -40,12 +40,12 @@ export default function ( clientId, isParent = false ) { ) { event.preventDefault(); insertBlock( - createBlock( getDefaultBlockName() ), + createBlock( defaultBlockName || getDefaultBlockName() ), parentIndex + 1, formParentId // Insert in the same context as the field block. ); } }, - [ insertBlock, fieldParentId, formParentId, parentIndex ] + [ insertBlock, fieldParentId, formParentId, parentIndex, defaultBlockName ] ); } diff --git a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php index f5828c6ed746f..0350458d11921 100644 --- a/projects/packages/forms/src/contact-form/class-contact-form-plugin.php +++ b/projects/packages/forms/src/contact-form/class-contact-form-plugin.php @@ -1244,7 +1244,7 @@ public static function gutenblock_render_field_file( $atts, $content, $block ) { } /** - * Render the dropdown field. + * Render the dropdown. * * @param array $atts - the block attributes. * @param string $content - html content. @@ -1252,7 +1252,18 @@ public static function gutenblock_render_field_file( $atts, $content, $block ) { * @return string HTML for the dropdown in select field. */ public static function gutenblock_render_dropdown( $atts, $content ) { + return $content; + } + /** + * Render the dropdown option. + * + * @param array $atts - the block attributes. + * @param string $content - html content. + * + * @return string HTML for the dropdown option in select field. + */ + public static function gutenblock_render_dropdown_option( $atts, $content ) { return $content; } From 2f1e82c752d9a0a94a33219d13a999bc64916138 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Thu, 17 Jul 2025 17:41:28 +0300 Subject: [PATCH 04/18] changelog --- .../packages/forms/changelog/update-forms-select-inner-blocks | 4 ++++ .../jetpack/changelog/update-forms-select-inner-blocks | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 projects/packages/forms/changelog/update-forms-select-inner-blocks create mode 100644 projects/plugins/jetpack/changelog/update-forms-select-inner-blocks diff --git a/projects/packages/forms/changelog/update-forms-select-inner-blocks b/projects/packages/forms/changelog/update-forms-select-inner-blocks new file mode 100644 index 0000000000000..91284ef45717b --- /dev/null +++ b/projects/packages/forms/changelog/update-forms-select-inner-blocks @@ -0,0 +1,4 @@ +Significance: minor +Type: changed + +Forms: improve adding, editing and removing options for dropdown field diff --git a/projects/plugins/jetpack/changelog/update-forms-select-inner-blocks b/projects/plugins/jetpack/changelog/update-forms-select-inner-blocks new file mode 100644 index 0000000000000..56aa26b3f3795 --- /dev/null +++ b/projects/plugins/jetpack/changelog/update-forms-select-inner-blocks @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Forms: improve adding, editing and removing options for dropdown field From a4d5ebcd13252456a1e32cd0d3b188c519a8835b Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 00:48:39 +0300 Subject: [PATCH 05/18] Create new option on Enter --- .../forms/src/blocks/dropdown-option/edit.js | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/projects/packages/forms/src/blocks/dropdown-option/edit.js b/projects/packages/forms/src/blocks/dropdown-option/edit.js index bb1015ba90abb..b2574a7adf08c 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/edit.js +++ b/projects/packages/forms/src/blocks/dropdown-option/edit.js @@ -1,22 +1,29 @@ import { RichText, useBlockProps, store as blockEditorStore } from '@wordpress/block-editor'; import { Button, Flex, FlexItem } from '@wordpress/components'; import { useDispatch } from '@wordpress/data'; +import { useCallback } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { close } from '@wordpress/icons'; -import useInsertAfterOnEnterKeyDown from '../shared/hooks/use-insert-after-on-enter-key-down'; const noop = () => undefined; export default function DropdownOptionEdit( props ) { - // eslint-disable-next-line no-console - console.log( props ); - const { attributes, clientId, setAttributes, name } = props; + const { attributes, clientId, setAttributes } = props; const { option } = attributes; const className = 'jetpack-field-dropdown__option'; const blockProps = useBlockProps( { className } ); - const onKeyDown = useInsertAfterOnEnterKeyDown( clientId, name ); - const { removeBlocks } = useDispatch( blockEditorStore ); // insertAfterBlock + const { removeBlocks, insertAfterBlock } = useDispatch( blockEditorStore ); + + const onKeyDown = useCallback( + event => { + if ( event.key === 'Enter' && ! event.shiftKey ) { + event.preventDefault(); + insertAfterBlock( clientId ); + } + }, + [ insertAfterBlock, clientId ] + ); const onRemove = () => { return removeBlocks( clientId ); @@ -30,7 +37,6 @@ export default function DropdownOptionEdit( props ) { allowedFormats={ [] } onChange={ value => setAttributes( { option: value } ) } onKeyDown={ onKeyDown } - onRemove={ onRemove } onReplace={ noop } placeholder={ __( 'Add option…', 'jetpack-forms' ) } value={ option || '' } From 9aa497da506ecdcd1b648043cff1c19ee633f815 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 02:51:12 +0300 Subject: [PATCH 06/18] Copy paste and splitting --- .../forms/src/blocks/dropdown-option/edit.js | 57 ++++++++++++------- .../forms/src/blocks/dropdown-option/index.js | 1 + .../forms/src/blocks/dropdown/edit.js | 17 ++---- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/projects/packages/forms/src/blocks/dropdown-option/edit.js b/projects/packages/forms/src/blocks/dropdown-option/edit.js index b2574a7adf08c..1ab9c9581dccf 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/edit.js +++ b/projects/packages/forms/src/blocks/dropdown-option/edit.js @@ -1,43 +1,60 @@ import { RichText, useBlockProps, store as blockEditorStore } from '@wordpress/block-editor'; +import { createBlock } from '@wordpress/blocks'; import { Button, Flex, FlexItem } from '@wordpress/components'; -import { useDispatch } from '@wordpress/data'; -import { useCallback } from '@wordpress/element'; +import { useDispatch, useSelect } from '@wordpress/data'; import { __ } from '@wordpress/i18n'; import { close } from '@wordpress/icons'; -const noop = () => undefined; - export default function DropdownOptionEdit( props ) { const { attributes, clientId, setAttributes } = props; const { option } = attributes; const className = 'jetpack-field-dropdown__option'; - const blockProps = useBlockProps( { className } ); - - const { removeBlocks, insertAfterBlock } = useDispatch( blockEditorStore ); - - const onKeyDown = useCallback( - event => { - if ( event.key === 'Enter' && ! event.shiftKey ) { - event.preventDefault(); - insertAfterBlock( clientId ); - } - }, - [ insertAfterBlock, clientId ] - ); + const blockProps = useBlockProps( { + className, + } ); + + const { removeBlocks, insertBlocks } = useDispatch( blockEditorStore ); + const { getBlockRootClientId, getBlockIndex } = useSelect( blockEditorStore ); const onRemove = () => { return removeBlocks( clientId ); }; + const onPaste = event => { + const pastedText = event.clipboardData.getData( 'text/plain' ); + + // Check if the pasted text contains multiple lines + if ( pastedText.includes( '\n' ) ) { + event.preventDefault(); + + const lines = pastedText.split( '\n' ); + + // Grab first element of the pasted list as a value for current option block + const firstLine = lines.shift(); + setAttributes( { option: `${ option || '' }${ firstLine }` } ); + + // Append rest of the lines as new option blocks + const newOptions = lines.map( line => + createBlock( 'jetpack/dropdown-option', { option: line } ) + ); + const rootClientId = getBlockRootClientId( clientId ); + const index = getBlockIndex( clientId ); + + insertBlocks( newOptions, index + 1, rootClientId ); + } + }; + return (
setAttributes( { option: value } ) } - onKeyDown={ onKeyDown } - onReplace={ noop } + onPaste={ onPaste } + onRemove={ onRemove } placeholder={ __( 'Add option…', 'jetpack-forms' ) } value={ option || '' } withoutInteractiveFormatting diff --git a/projects/packages/forms/src/blocks/dropdown-option/index.js b/projects/packages/forms/src/blocks/dropdown-option/index.js index 959c2a3fdfff7..a6bfc076ee084 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/index.js +++ b/projects/packages/forms/src/blocks/dropdown-option/index.js @@ -21,6 +21,7 @@ const settings = { customClassName: false, html: false, reusable: false, + splitting: true, }, edit, save, diff --git a/projects/packages/forms/src/blocks/dropdown/edit.js b/projects/packages/forms/src/blocks/dropdown/edit.js index 702c4ce17d348..202ae19d514cd 100644 --- a/projects/packages/forms/src/blocks/dropdown/edit.js +++ b/projects/packages/forms/src/blocks/dropdown/edit.js @@ -4,17 +4,9 @@ import './editor.scss'; const DEFAULT_BLOCK = { name: 'jetpack/dropdown-option', - attributes: {}, }; -const BLOCKS_TEMPLATE = [ - [ - DEFAULT_BLOCK.name, - { - ...DEFAULT_BLOCK.attributes, - }, - ], -]; +const TEMPLATE = [ [ DEFAULT_BLOCK.name ] ]; export default function DropdownEdit() { const blockProps = useBlockProps( { className: 'jetpack-field-dropdown__popover' } ); @@ -23,12 +15,13 @@ export default function DropdownEdit() { return (
); From 1e3025350544be408e6895e83390309bdcbc18c8 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 03:29:55 +0300 Subject: [PATCH 07/18] Allow merging options --- .../forms/src/blocks/dropdown-option/edit.js | 24 +++++++++++++------ .../forms/src/blocks/dropdown-option/index.js | 4 ++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/projects/packages/forms/src/blocks/dropdown-option/edit.js b/projects/packages/forms/src/blocks/dropdown-option/edit.js index 1ab9c9581dccf..cd52f20963b08 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/edit.js +++ b/projects/packages/forms/src/blocks/dropdown-option/edit.js @@ -6,19 +6,15 @@ import { __ } from '@wordpress/i18n'; import { close } from '@wordpress/icons'; export default function DropdownOptionEdit( props ) { - const { attributes, clientId, setAttributes } = props; + const { attributes, clientId, mergeBlocks, setAttributes } = props; const { option } = attributes; const className = 'jetpack-field-dropdown__option'; const blockProps = useBlockProps( { className, } ); - const { removeBlocks, insertBlocks } = useDispatch( blockEditorStore ); - const { getBlockRootClientId, getBlockIndex } = useSelect( blockEditorStore ); - - const onRemove = () => { - return removeBlocks( clientId ); - }; + const { getBlockIndex, getBlockRootClientId, getNextBlockClientId, getPreviousBlockClientId } = + useSelect( blockEditorStore ); const onPaste = event => { const pastedText = event.clipboardData.getData( 'text/plain' ); @@ -44,6 +40,19 @@ export default function DropdownOptionEdit( props ) { } }; + const onRemove = () => { + const nextBlockClientId = getNextBlockClientId( clientId ); + const previousBlockClientId = getPreviousBlockClientId( clientId ); + + if ( ! nextBlockClientId || ! previousBlockClientId ) { + // If this is the the only option, remove by emptying value + setAttributes( { option: '' } ); + return; + } + + return removeBlocks( clientId ); + }; + return (
@@ -53,6 +62,7 @@ export default function DropdownOptionEdit( props ) { aria-label={ __( 'Dropdown option value', 'jetpack-forms' ) } identifier="option" onChange={ value => setAttributes( { option: value } ) } + onMerge={ mergeBlocks } onPaste={ onPaste } onRemove={ onRemove } placeholder={ __( 'Add option…', 'jetpack-forms' ) } diff --git a/projects/packages/forms/src/blocks/dropdown-option/index.js b/projects/packages/forms/src/blocks/dropdown-option/index.js index a6bfc076ee084..66d97a5447940 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/index.js +++ b/projects/packages/forms/src/blocks/dropdown-option/index.js @@ -23,6 +23,10 @@ const settings = { reusable: false, splitting: true, }, + merge: ( attributes, { option = '' } ) => ( { + ...attributes, + option: ( attributes.option || '' ) + option, + } ), edit, save, }; From 7141a36c51bd2ed48c936b9ea40cd2e097d6ef29 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 03:34:09 +0300 Subject: [PATCH 08/18] Disallow formatting --- projects/packages/forms/src/blocks/dropdown-option/edit.js | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/packages/forms/src/blocks/dropdown-option/edit.js b/projects/packages/forms/src/blocks/dropdown-option/edit.js index cd52f20963b08..da83ab9dd64c6 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/edit.js +++ b/projects/packages/forms/src/blocks/dropdown-option/edit.js @@ -59,6 +59,7 @@ export default function DropdownOptionEdit( props ) { setAttributes( { option: value } ) } From adfcd8496fa4e3fbe5b24616a3e4bff447433038 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 04:10:33 +0300 Subject: [PATCH 09/18] Support copy-pasting over existing items --- .../forms/src/blocks/dropdown-option/edit.js | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/projects/packages/forms/src/blocks/dropdown-option/edit.js b/projects/packages/forms/src/blocks/dropdown-option/edit.js index da83ab9dd64c6..48d52520c8c6f 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/edit.js +++ b/projects/packages/forms/src/blocks/dropdown-option/edit.js @@ -12,13 +12,31 @@ export default function DropdownOptionEdit( props ) { const blockProps = useBlockProps( { className, } ); - const { removeBlocks, insertBlocks } = useDispatch( blockEditorStore ); - const { getBlockIndex, getBlockRootClientId, getNextBlockClientId, getPreviousBlockClientId } = - useSelect( blockEditorStore ); + const { removeBlocks, replaceBlocks, insertBlocks } = useDispatch( blockEditorStore ); + const { + getBlockIndex, + getBlockRootClientId, + getMultiSelectedBlockClientIds, + getNextBlockClientId, + getPreviousBlockClientId, + } = useSelect( blockEditorStore ); const onPaste = event => { const pastedText = event.clipboardData.getData( 'text/plain' ); + // While pasting, multiple blocks were selected + const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(); + if ( multiSelectedBlockClientIds.length ) { + const lines = pastedText.split( '\n' ); + const newOptions = lines.map( line => + createBlock( 'jetpack/dropdown-option', { option: line } ) + ); + replaceBlocks( multiSelectedBlockClientIds, newOptions ); + return; + } + + // Otherwise pasting in a single block… + // Check if the pasted text contains multiple lines if ( pastedText.includes( '\n' ) ) { event.preventDefault(); From 63e3e237e90ef2943879750e7ce4d3bc673a2bdb Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 04:13:33 +0300 Subject: [PATCH 10/18] Fix ensuring list isnt empty on removal --- projects/packages/forms/src/blocks/dropdown-option/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/packages/forms/src/blocks/dropdown-option/edit.js b/projects/packages/forms/src/blocks/dropdown-option/edit.js index 48d52520c8c6f..390d81ae2802c 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/edit.js +++ b/projects/packages/forms/src/blocks/dropdown-option/edit.js @@ -62,7 +62,7 @@ export default function DropdownOptionEdit( props ) { const nextBlockClientId = getNextBlockClientId( clientId ); const previousBlockClientId = getPreviousBlockClientId( clientId ); - if ( ! nextBlockClientId || ! previousBlockClientId ) { + if ( ! nextBlockClientId && ! previousBlockClientId ) { // If this is the the only option, remove by emptying value setAttributes( { option: '' } ); return; From 504b1ecc2b258199713cbb4011d48146b2c4de98 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 04:45:41 +0300 Subject: [PATCH 11/18] Simplify output --- .../packages/forms/src/blocks/dropdown-option/edit.js | 1 + .../packages/forms/src/blocks/dropdown-option/save.js | 8 +------- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/projects/packages/forms/src/blocks/dropdown-option/edit.js b/projects/packages/forms/src/blocks/dropdown-option/edit.js index 390d81ae2802c..5813282c3af61 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/edit.js +++ b/projects/packages/forms/src/blocks/dropdown-option/edit.js @@ -85,6 +85,7 @@ export default function DropdownOptionEdit( props ) { onPaste={ onPaste } onRemove={ onRemove } placeholder={ __( 'Add option…', 'jetpack-forms' ) } + tagName="div" value={ option || '' } withoutInteractiveFormatting /> diff --git a/projects/packages/forms/src/blocks/dropdown-option/save.js b/projects/packages/forms/src/blocks/dropdown-option/save.js index 38da9345a3943..461f67a0a4bcb 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/save.js +++ b/projects/packages/forms/src/blocks/dropdown-option/save.js @@ -1,7 +1 @@ -import { useBlockProps, RichText } from '@wordpress/block-editor'; - -export default ( { attributes } ) => { - const blockProps = useBlockProps.save(); - - return ; -}; +export default () => null; From 536c282059df0872f1b8ab5dacf189aa028cf3f4 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 04:45:58 +0300 Subject: [PATCH 12/18] Disable dropdown container styling for now --- projects/packages/forms/src/blocks/dropdown/index.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/projects/packages/forms/src/blocks/dropdown/index.js b/projects/packages/forms/src/blocks/dropdown/index.js index 2f2fd6a537937..50cda8f73d33c 100644 --- a/projects/packages/forms/src/blocks/dropdown/index.js +++ b/projects/packages/forms/src/blocks/dropdown/index.js @@ -17,6 +17,7 @@ const settings = { src: menu, }, attributes: { + /* style: { type: 'object', default: { @@ -25,10 +26,13 @@ const settings = { }, }, }, + */ }, supports: { + anchor: false, reusable: false, html: false, + /* color: { gradients: true, heading: true, @@ -59,6 +63,7 @@ const settings = { width: true, }, }, + */ }, edit, save, From 739ae458bea209bd5c75495f2d4569c33c58d589 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 14:48:06 +0300 Subject: [PATCH 13/18] remove old stuff --- .../forms/src/blocks/dropdown/edit.js | 1 - .../forms/src/blocks/field-select/edit.js | 153 +++--------------- 2 files changed, 26 insertions(+), 128 deletions(-) diff --git a/projects/packages/forms/src/blocks/dropdown/edit.js b/projects/packages/forms/src/blocks/dropdown/edit.js index 202ae19d514cd..6c32cd0d432db 100644 --- a/projects/packages/forms/src/blocks/dropdown/edit.js +++ b/projects/packages/forms/src/blocks/dropdown/edit.js @@ -18,7 +18,6 @@ export default function DropdownEdit() { __experimentalCaptureToolbars={ true } defaultBlock={ DEFAULT_BLOCK } directInsert={ true } - renderAppender={ false } template={ TEMPLATE } templateLock={ false } templateInsertUpdatesSelection={ true } diff --git a/projects/packages/forms/src/blocks/field-select/edit.js b/projects/packages/forms/src/blocks/field-select/edit.js index 49d27ebff9713..6740d091f623f 100644 --- a/projects/packages/forms/src/blocks/field-select/edit.js +++ b/projects/packages/forms/src/blocks/field-select/edit.js @@ -1,23 +1,18 @@ import { - RichText, + InspectorControls, store as blockEditorStore, useBlockProps, useInnerBlocksProps, } from '@wordpress/block-editor'; -import { Icon, Button, Flex, FlexItem } from '@wordpress/components'; +import { PanelBody } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; import { useMemo, useRef } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; -import { close } from '@wordpress/icons'; import clsx from 'clsx'; import JetpackFieldControls from '../shared/components/jetpack-field-controls'; import useFormWrapper from '../shared/hooks/use-form-wrapper'; import useJetpackFieldStyles from '../shared/hooks/use-jetpack-field-styles'; -import { getCaretPosition } from '../shared/util/caret'; import { ALLOWED_INNER_BLOCKS } from '../shared/util/constants'; -import setFocus from '../shared/util/set-focus'; - -const noop = () => undefined; export default function DropdownFieldEdit( props ) { const { attributes, clientId, isSelected, name, setAttributes } = props; @@ -64,132 +59,36 @@ export default function DropdownFieldEdit( props ) { templateLock: 'all', } ); - + /* const optionWrapperStyles = { className: 'jetpack-field-dropdown__popover', }; const changeFocus = ( index, cursorToEnd ) => setFocus( optionsWrapper.current, '[role=textbox]', index, cursorToEnd ); - - const handleSingleValue = ( index, value ) => { - const _options = [ ...options ]; - - _options[ index ] = value; - - setAttributes( { options: _options } ); - changeFocus( index ); - }; - - const handleMultiValues = ( index, array ) => { - const _options = [ ...attributes.options ]; - const cursorToEnd = array[ array.length - 1 ] !== ''; - - if ( _options[ index ] ) { - _options[ index ] = array.shift(); - index++; - } - - _options.splice( index, 0, ...array ); - - setAttributes( { options: _options } ); - changeFocus( index + array.length - 1, cursorToEnd ); - }; - - const handleChangeOption = index => value => { - const values = ( value || '' ).split( '\n' ).filter( op => op && op.trim() !== '' ); - - if ( ! values.length ) { - return; - } - - if ( values.length > 1 ) { - handleMultiValues( index, values ); - } else { - handleSingleValue( index, values.pop() ); - } - }; - - const handleKeyDown = index => e => { - // Create a new dropdown option when the user hits Enter. - // Previously handled with the onSplit prop, which was removed in https://github.com/WordPress/gutenberg/pull/54543 - if ( 'Enter' !== e.key ) { - return; - } - - e.preventDefault(); - - const value = attributes.options[ index ]; - - if ( ! value ) { - return; - } - - const caretPos = getCaretPosition( e.target ); - // splitValue is the value after the caret position when a user hits Enter - const splitValue = caretPos ? value.slice( caretPos ) : ''; - - handleMultiValues( - index, - splitValue ? [ value.slice( 0, caretPos ), splitValue ] : [ value, '' ] - ); - }; - - const handleDeleteOption = index => () => { - if ( attributes.options.length === 1 ) { - return; - } - - const _options = [ ...attributes.options ]; - _options.splice( index, 1 ); - if ( _options.length === 0 || _options.filter( option => option ).length === 0 ) { - return; - } - setAttributes( { options: _options } ); - changeFocus( Math.max( index - 1, 0 ), true ); - }; - +*/ return ( -
-
- { ( isSelected || isInnerBlockSelected ) && ( -
- { options.map( ( option, index ) => ( - - - - - - { ( options.filter( opt => opt ).length > 1 || option === '' ) && ( - - ) } - - - ) ) } -
- ) } - -
+ <> +
+
+ + + + { options.filter( opt => opt ).length && ( +
    + { options.map( ( option, index ) => ( option ?
  • { option }
  • : null ) ) } +
+ ) } +
+
+
+ ); } From 541b86f38af4c604991410833f7bdbd862d4be81 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 22 Jul 2025 18:08:21 +0300 Subject: [PATCH 14/18] Show option value in List view sidebar --- projects/packages/forms/src/blocks/dropdown-option/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/packages/forms/src/blocks/dropdown-option/index.js b/projects/packages/forms/src/blocks/dropdown-option/index.js index 66d97a5447940..8590f19c21b2b 100644 --- a/projects/packages/forms/src/blocks/dropdown-option/index.js +++ b/projects/packages/forms/src/blocks/dropdown-option/index.js @@ -29,6 +29,7 @@ const settings = { } ), edit, save, + __experimentalLabel: ( { option } ) => option, }; export default { From e6f8e7cdb634f76387d5c5569adb3c4fc5510e07 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 9 Sep 2025 14:22:25 +0300 Subject: [PATCH 15/18] Cleanup/linter --- .../forms/src/blocks/field-select/edit.js | 21 +------------------ .../use-insert-after-on-enter-key-down.js | 6 +++--- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/projects/packages/forms/src/blocks/field-select/edit.js b/projects/packages/forms/src/blocks/field-select/edit.js index 6740d091f623f..0dd090f238249 100644 --- a/projects/packages/forms/src/blocks/field-select/edit.js +++ b/projects/packages/forms/src/blocks/field-select/edit.js @@ -1,12 +1,10 @@ import { - InspectorControls, store as blockEditorStore, useBlockProps, useInnerBlocksProps, } from '@wordpress/block-editor'; -import { PanelBody } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; -import { useMemo, useRef } from '@wordpress/element'; +import { useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import clsx from 'clsx'; import JetpackFieldControls from '../shared/components/jetpack-field-controls'; @@ -37,7 +35,6 @@ export default function DropdownFieldEdit( props ) { style: blockStyle, } ); - const optionsWrapper = useRef( undefined ); useFormWrapper( { attributes, clientId, name } ); const template = useMemo( () => { @@ -59,14 +56,7 @@ export default function DropdownFieldEdit( props ) { templateLock: 'all', } ); - /* - const optionWrapperStyles = { - className: 'jetpack-field-dropdown__popover', - }; - const changeFocus = ( index, cursorToEnd ) => - setFocus( optionsWrapper.current, '[role=textbox]', index, cursorToEnd ); -*/ return ( <>
@@ -79,15 +69,6 @@ export default function DropdownFieldEdit( props ) { width={ width } type="dropdown" /> - - - { options.filter( opt => opt ).length && ( -
    - { options.map( ( option, index ) => ( option ?
  • { option }
  • : null ) ) } -
- ) } -
-
); diff --git a/projects/packages/forms/src/blocks/shared/hooks/use-insert-after-on-enter-key-down.js b/projects/packages/forms/src/blocks/shared/hooks/use-insert-after-on-enter-key-down.js index 2863fad64ff75..657ba3fbd939c 100644 --- a/projects/packages/forms/src/blocks/shared/hooks/use-insert-after-on-enter-key-down.js +++ b/projects/packages/forms/src/blocks/shared/hooks/use-insert-after-on-enter-key-down.js @@ -3,7 +3,7 @@ import { createBlock, getDefaultBlockName } from '@wordpress/blocks'; import { useSelect, useDispatch } from '@wordpress/data'; import { useCallback } from '@wordpress/element'; -export default function ( clientId, isParent = false, defaultBlockName ) { +export default function ( clientId, isParent = false ) { const { fieldParentId, parentIndex, formParentId } = useSelect( select => { const blockEditor = select( blockEditorStore ); @@ -40,12 +40,12 @@ export default function ( clientId, isParent = false, defaultBlockName ) { ) { event.preventDefault(); insertBlock( - createBlock( defaultBlockName || getDefaultBlockName() ), + createBlock( getDefaultBlockName() ), parentIndex + 1, formParentId // Insert in the same context as the field block. ); } }, - [ insertBlock, fieldParentId, formParentId, parentIndex, defaultBlockName ] + [ insertBlock, fieldParentId, formParentId, parentIndex ] ); } From aaa003d004fa4c6aae355b8b6e7092ca47122527 Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 9 Sep 2025 14:28:44 +0300 Subject: [PATCH 16/18] For now no styling --- .../forms/src/blocks/dropdown/index.js | 44 ------------------- 1 file changed, 44 deletions(-) diff --git a/projects/packages/forms/src/blocks/dropdown/index.js b/projects/packages/forms/src/blocks/dropdown/index.js index 50cda8f73d33c..db652cc638c7a 100644 --- a/projects/packages/forms/src/blocks/dropdown/index.js +++ b/projects/packages/forms/src/blocks/dropdown/index.js @@ -16,54 +16,10 @@ const settings = { foreground: getIconColor(), src: menu, }, - attributes: { - /* - style: { - type: 'object', - default: { - spacing: { - margin: { top: '10px' }, - }, - }, - }, - */ - }, supports: { anchor: false, reusable: false, html: false, - /* - color: { - gradients: true, - heading: true, - button: true, - link: true, - __experimentalDefaultControls: { - background: true, - text: true, - }, - }, - spacing: { - margin: [ 'top' ], - padding: true, - }, - dimensions: { - minHeight: true, - maxHeight: true, // Doesn't work :-( - }, - __experimentalBorder: { - color: true, - radius: true, - style: true, - width: true, - __experimentalDefaultControls: { - color: true, - radius: true, - style: true, - width: true, - }, - }, - */ }, edit, save, From ee3e1146af6d5692ca7db28f3d0e59bafe676eed Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 9 Sep 2025 14:38:26 +0300 Subject: [PATCH 17/18] Hide dropdown when block is not selected --- .../packages/forms/src/blocks/dropdown/editor.scss | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/projects/packages/forms/src/blocks/dropdown/editor.scss b/projects/packages/forms/src/blocks/dropdown/editor.scss index 5c0dc40c14049..ac6d347187cdb 100644 --- a/projects/packages/forms/src/blocks/dropdown/editor.scss +++ b/projects/packages/forms/src/blocks/dropdown/editor.scss @@ -1,6 +1,15 @@ .wp-block-jetpack-dropdown { + display: none; p { - margin-bottom: 10px + margin-bottom: 10px; } -} \ No newline at end of file +} + +.is-selected, +.has-child-selected { + + .wp-block-jetpack-dropdown { + display: block; + } +} From f247b1b684baa2ebd951c6343cdd6969f7f571fc Mon Sep 17 00:00:00 2001 From: Mikael Korpela Date: Tue, 9 Sep 2025 14:52:07 +0300 Subject: [PATCH 18/18] Polish --- projects/packages/forms/src/blocks/field-select/index.js | 2 ++ projects/packages/forms/src/blocks/input/edit.js | 3 +++ 2 files changed, 5 insertions(+) diff --git a/projects/packages/forms/src/blocks/field-select/index.js b/projects/packages/forms/src/blocks/field-select/index.js index 6da85d6c8dbce..aa66fe6c3085e 100644 --- a/projects/packages/forms/src/blocks/field-select/index.js +++ b/projects/packages/forms/src/blocks/field-select/index.js @@ -10,11 +10,13 @@ import save from './save'; const name = 'field-select'; const settings = { ...defaultSettings, + allowedBlocks: [ 'jetpack/label', 'jetpack/dropdown' ], title: __( 'Dropdown field', 'jetpack-forms' ), keywords: [ __( 'Choose', 'jetpack-forms' ), __( 'Dropdown', 'jetpack-forms' ), __( 'Option', 'jetpack-forms' ), + __( 'Select', 'jetpack-forms' ), ], description: __( 'Add a compact select box, that when expanded, allows visitors to choose one value from the list.', diff --git a/projects/packages/forms/src/blocks/input/edit.js b/projects/packages/forms/src/blocks/input/edit.js index 79e996f5c2fb2..9050470951fb6 100644 --- a/projects/packages/forms/src/blocks/input/edit.js +++ b/projects/packages/forms/src/blocks/input/edit.js @@ -57,6 +57,9 @@ const InputEdit = ( { attributes, clientId, isSelected, name, setAttributes, con return (
setAttributes( { placeholder: value } ) } value={ placeholder ? placeholder : __( 'Select one option', 'jetpack-forms' ) }