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

Search Block: Add support for setting the border radius #25203

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
3 changes: 3 additions & 0 deletions packages/block-library/src/search/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
"buttonUseIcon": {
"type": "bool",
"default": false
},
"borderRadius": {
"type": "number"
}
},
"supports": {
Expand Down
103 changes: 98 additions & 5 deletions packages/block-library/src/search/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
ResizableBox,
PanelBody,
BaseControl,
RangeControl,
} from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { search } from '@wordpress/icons';
Expand All @@ -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 },
Expand All @@ -70,6 +73,7 @@ export default function SearchEdit( {
buttonText,
buttonPosition,
buttonUseIcon,
borderRadius,
} = attributes;

const unitControlInstanceId = useInstanceId( UnitControl );
Expand Down Expand Up @@ -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 (
<input
className="wp-block-search__input"
className={ textFieldClasses }
style={ textFieldStyles }
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
Expand All @@ -143,18 +165,29 @@ export default function SearchEdit( {
};

const renderButton = () => {
const buttonStyles = {
...sharedStyles,
};

const buttonClasses = classnames(
'wp-block-search__button',
sharedClasses
);

return (
<>
{ buttonUseIcon && (
<Button
icon={ search }
className="wp-block-search__button"
className={ buttonClasses }
style={ buttonStyles }
/>
) }

{ ! buttonUseIcon && (
<RichText
className="wp-block-search__button"
className={ buttonClasses }
style={ buttonStyles }
aria-label={ __( 'Button text' ) }
placeholder={ __( 'Add button text…' ) }
withoutInteractiveFormatting
Expand All @@ -168,6 +201,54 @@ export default function SearchEdit( {
);
};

const renderInputs = () => {
const wrapperStyles =
'button-inside' === buttonPosition ? { ...sharedStyles } : {};

const wrapperClasses = classnames(
'wp-block-search__inside-wrapper',
'button-inside' === buttonPosition ? sharedClasses : undefined
);

return (
<ResizableBox
size={ {
width: `${ width }${ widthUnit }`,
} }
className={ wrapperClasses }
style={ wrapperStyles }
isResetValueOnUnitChange
minWidth={ MIN_WIDTH }
enable={ getResizableSides() }
onResizeStart={ ( event, direction, elt ) => {
setAttributes( {
width: parseInt( elt.offsetWidth, 10 ),
widthUnit: 'px',
} );
toggleSelection( false );
} }
onResizeStop={ ( event, direction, elt, delta ) => {
setAttributes( {
width: parseInt( width + delta.width, 10 ),
} );
toggleSelection( true );
} }
showHandle={ isSelected }
>
{ ( 'button-inside' === buttonPosition ||
'button-outside' === buttonPosition ) && (
<>
{ renderTextField() }
{ renderButton() }
</>
) }

{ 'button-only' === buttonPosition && renderButton() }
{ 'no-button' === buttonPosition && renderTextField() }
</ResizableBox>
);
};

const controls = (
<>
<BlockControls>
Expand Down Expand Up @@ -254,7 +335,7 @@ export default function SearchEdit( {
</BlockControls>

<InspectorControls>
<PanelBody title={ __( 'Display Settings' ) }>
<PanelBody title={ __( 'Design Settings' ) }>
<BaseControl
label={ __( 'Width' ) }
id={ unitControlInputId }
Expand Down Expand Up @@ -314,6 +395,18 @@ export default function SearchEdit( {
} ) }
</ButtonGroup>
</BaseControl>

<RangeControl
value={ borderRadius }
label={ __( 'Border Radius' ) }
min={ MIN_BORDER_RADIUS_VALUE }
max={ MAX_BORDER_RADIUS_VALUE }
initialPosition={ 0 }
allowReset
onChange={ ( newBorderRadius ) =>
setAttributes( { borderRadius: newBorderRadius } )
}
/>
</PanelBody>
</InspectorControls>
</>
Expand Down Expand Up @@ -372,6 +465,6 @@ export default function SearchEdit( {
{ 'button-only' === buttonPosition && renderButton() }
{ 'no-button' === buttonPosition && renderTextField() }
</ResizableBox>
</div>
</Block.div>
);
}
103 changes: 81 additions & 22 deletions packages/block-library/src/search/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,25 @@ function render_block_core_search( $attributes ) {
$attributes = wp_parse_args(
$attributes,
array(
'label' => __( 'Search' ),
'label' => __( 'Search' ),
'buttonText' => __( 'Search' ),
)
);

$input_id = 'wp-block-search__input-' . ++$instance_id;
$classnames = classnames_for_block_core_search( $attributes );
$show_label = ( ! empty( $attributes['showLabel'] ) ) ? true : false;
$use_icon_button = ( ! empty( $attributes['buttonUseIcon'] ) ) ? true : false;
$show_input = ( ! empty( $attributes['buttonPosition'] ) && 'button-only' === $attributes['buttonPosition'] ) ? false : true;
$show_button = ( ! empty( $attributes['buttonPosition'] ) && 'no-button' === $attributes['buttonPosition'] ) ? false : true;
$label_markup = '';
$input_markup = '';
$button_markup = '';
$width_styles = '';
$input_id = 'wp-block-search__input-' . ++$instance_id;
$base_classnames = block_core_build_base_classnames( $attributes );
$show_label = array_key_exists( 'showLabel', $attributes );
$use_icon_button = array_key_exists( 'buttonUseIcon', $attributes ) && $attributes['buttonUseIcon'];
$has_width = array_key_exists( 'width', $attributes );
$has_width_unit = array_key_exists( 'widthUnit', $attributes );
$show_input = array_key_exists( 'buttonPosition', $attributes ) && 'button-only' === $attributes['buttonPosition'] ? false : true;
$show_button = array_key_exists( 'buttonPosition', $attributes ) && 'no-button' === $attributes['buttonPosition'] ? false : true;
$label_markup = '';
$input_markup = '';
$button_markup = '';

$shared_classes = block_core_search_build_css_border_radius( $attributes )['css_classes'];
$shared_styles = block_core_search_build_css_border_radius( $attributes )['inline_styles'];

if ( $show_label ) {
if ( ! empty( $attributes['label'] ) ) {
Expand All @@ -55,15 +59,28 @@ function render_block_core_search( $attributes ) {
}

if ( $show_input ) {
$input_classes = array_merge(
array( 'wp-block-search__input' ),
array_filter( $shared_classes )
);
$input_styles = $shared_styles;

$input_markup = sprintf(
'<input type="search" id="%s" class="wp-block-search__input" name="s" value="%s" placeholder="%s" required />',
$input_id,
'<input type="search" id="%1$s" %2$s%3$sname="s" value="%4$s" placeholder="%5$s" required />',
esc_attr( $input_id ),
sprintf( ' class="%s"', esc_attr( implode( ' ', $input_classes ) ) ),
( ! empty( $input_styles ) ) ? sprintf( ' style="%s"', esc_attr( $input_styles ) ) : '',
esc_attr( get_search_query() ),
esc_attr( $attributes['placeholder'] )
);
}

if ( $show_button ) {
$button_classes = array_merge(
array( 'wp-block-search__button' ),
array_filter( $shared_classes )
);
$button_styles = $shared_styles;
$button_internal_markup = '';

if ( ! $use_icon_button ) {
Expand All @@ -78,27 +95,40 @@ function render_block_core_search( $attributes ) {
}

$button_markup = sprintf(
'<button type="submit" class="wp-block-search__button">%s</button>',
'<button type="submit"%1$s%2$s>%3$s</button>',
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'] ) . ';"';
apeatling marked this conversation as resolved.
Show resolved Hide resolved
}
}

$field_markup = sprintf(
'<div class="wp-block-search__inside-wrapper"%s>%s</div>',
$width_styles,
'<div %1$s%2$s>%3$s</div>',
sprintf( ' class="%s"', esc_attr( implode( ' ', $field_classes ) ) ),
( ! empty( $field_styles ) ) ? sprintf( ' style="%s"', esc_attr( $field_styles ) ) : '',
$input_markup . $button_markup
);

return sprintf(
'<form role="search" method="get" action="%s" class="%s">%s</form>',
esc_url( home_url( '/' ) ),
$classnames,
esc_attr( implode( ' ', $base_classnames ) ),
$label_markup . $field_markup
);
}
Expand All @@ -116,17 +146,46 @@ 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.
*
* @param array $attributes The block attributes.
*
* @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';
}
Expand All @@ -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 {
Expand All @@ -154,5 +213,5 @@ function classnames_for_block_core_search( $attributes ) {
}
}

return implode( ' ', $classnames );
return $classnames;
}