diff --git a/packages/block-library/src/search/block.json b/packages/block-library/src/search/block.json index 92de1d6f028b3..66610a432e9fd 100644 --- a/packages/block-library/src/search/block.json +++ b/packages/block-library/src/search/block.json @@ -29,6 +29,9 @@ "buttonUseIcon": { "type": "bool", "default": false + }, + "borderRadius": { + "type": "number" } }, "supports": { diff --git a/packages/block-library/src/search/edit.js b/packages/block-library/src/search/edit.js index 1f14360668dbe..e7f38041bbeeb 100644 --- a/packages/block-library/src/search/edit.js +++ b/packages/block-library/src/search/edit.js @@ -24,6 +24,7 @@ import { ResizableBox, PanelBody, BaseControl, + RangeControl, } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { search } from '@wordpress/icons'; @@ -48,6 +49,8 @@ const MIN_WIDTH = 220; const MIN_WIDTH_UNIT = 'px'; const PC_WIDTH_DEFAULT = 50; const PX_WIDTH_DEFAULT = 350; +const MIN_BORDER_RADIUS_VALUE = 0; +const MAX_BORDER_RADIUS_VALUE = 50; const CSS_UNITS = [ { value: '%', label: '%', default: PC_WIDTH_DEFAULT }, { value: 'px', label: 'px', default: PX_WIDTH_DEFAULT }, @@ -70,6 +73,7 @@ export default function SearchEdit( { buttonText, buttonPosition, buttonUseIcon, + borderRadius, } = attributes; const unitControlInstanceId = useInstanceId( UnitControl ); @@ -123,10 +127,28 @@ export default function SearchEdit( { }; }; + const sharedStyles = { + borderRadius: borderRadius ? borderRadius + 'px' : undefined, + }; + + const sharedClasses = { + 'no-border-radius': borderRadius === 0, + }; + const renderTextField = () => { + const textFieldStyles = { + ...sharedStyles, + }; + + const textFieldClasses = classnames( + 'wp-block-search__input', + sharedClasses + ); + return ( { + const buttonStyles = { + ...sharedStyles, + }; + + const buttonClasses = classnames( + 'wp-block-search__button', + sharedClasses + ); + return ( <> { buttonUseIcon && ( ', + '', + sprintf( ' class="%s"', esc_attr( implode( ' ', $button_classes ) ) ), + ( ! empty( $button_styles ) ) ? sprintf( ' style="%s"', esc_attr( $button_styles ) ) : '', $button_internal_markup ); } + $field_classes = array_merge( + array( 'wp-block-search__inside-wrapper' ), + ( array_key_exists( 'buttonPosition', $attributes ) && 'button-inside' === $attributes['buttonPosition'] ) + ? array_filter( $shared_classes ) + : array() + ); + $field_styles = ( array_key_exists( 'buttonPosition', $attributes ) && 'button-inside' === $attributes['buttonPosition'] ) + ? $shared_styles + : ''; + if ( ! empty( $attributes['width'] ) && ! empty( $attributes['widthUnit'] ) ) { if ( ! empty( $attributes['buttonPosition'] ) && 'button-only' !== $attributes['buttonPosition'] ) { - $width_styles = ' style="width: ' . $attributes['width'] . $attributes['widthUnit'] . ';"'; + $field_styles .= ' width: ' . esc_attr( $attributes['width'] ) . esc_attr( $attributes['widthUnit'] ) . ';'; } } $field_markup = sprintf( - '
%s
', - $width_styles, + '
%3$s
', + sprintf( ' class="%s"', esc_attr( implode( ' ', $field_classes ) ) ), + ( ! empty( $field_styles ) ) ? sprintf( ' style="%s"', esc_attr( $field_styles ) ) : '', $input_markup . $button_markup ); return sprintf( '', esc_url( home_url( '/' ) ), - $classnames, + esc_attr( implode( ' ', $base_classnames ) ), $label_markup . $field_markup ); } @@ -116,6 +146,35 @@ function register_block_core_search() { } add_action( 'init', 'register_block_core_search' ); +/** + * Build an array with CSS classes and inline styles defining the border radius + * which will be applied to the search markup in the front-end. + * + * @param array $attributes Search block attributes. + * @return array Border radius CSS classes and inline styles. + */ +function block_core_search_build_css_border_radius( $attributes ) { + $border_radius = array( + 'css_classes' => array(), + 'inline_styles' => '', + ); + + $has_border_radius = array_key_exists( 'borderRadius', $attributes ); + + if ( $has_border_radius ) { + $border_radius['css_classes'][] = ( $attributes['borderRadius'] === 0 ) + ? 'no-border-radius' + : ''; + + $border_radius['inline_styles'] = sprintf( + 'border-radius: %spx;', + esc_attr( $attributes['borderRadius'] ) + ); + } + + return $border_radius; +} + /** * Builds the correct top level classnames for the 'core/search' block. * @@ -123,10 +182,10 @@ function register_block_core_search() { * * @return string The classnames used in the block. */ -function classnames_for_block_core_search( $attributes ) { +function block_core_build_base_classnames( $attributes ) { $classnames = array(); - if ( ! empty( $attributes['buttonPosition'] ) ) { + if ( array_key_exists( 'buttonPosition', $attributes ) ) { if ( 'button-inside' === $attributes['buttonPosition'] ) { $classnames[] = 'wp-block-search__button-inside'; } @@ -145,7 +204,7 @@ function classnames_for_block_core_search( $attributes ) { } if ( isset( $attributes['buttonUseIcon'] ) ) { - if ( ! empty( $attributes['buttonPosition'] ) && 'no-button' !== $attributes['buttonPosition'] ) { + if ( array_key_exists( 'buttonPosition', $attributes ) && 'no-button' !== $attributes['buttonPosition'] ) { if ( $attributes['buttonUseIcon'] ) { $classnames[] = 'wp-block-search__icon-button'; } else { @@ -154,5 +213,5 @@ function classnames_for_block_core_search( $attributes ) { } } - return implode( ' ', $classnames ); + return $classnames; }