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 border radius #27664

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
5 changes: 4 additions & 1 deletion packages/block-library/src/search/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
},
"supports": {
"align": [ "left", "center", "right" ],
"html": false
"html": false,
"__experimentalBorder": {
"radius": true
}
}
}
117 changes: 83 additions & 34 deletions packages/block-library/src/search/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ const CSS_UNITS = [
{ value: 'px', label: 'px', default: PX_WIDTH_DEFAULT },
];

// Used to calculate adjustment to inner button border radius.
const DEFAULT_INPUT_PADDING = 4;

// Minimum inner radius of 1px as having none when there is an outer radius jars.
const MIN_INNER_RADIUS = 1;

export default function SearchEdit( {
className,
attributes,
Expand All @@ -70,8 +76,10 @@ export default function SearchEdit( {
buttonText,
buttonPosition,
buttonUseIcon,
style,
} = attributes;

const borderRadius = style?.border?.radius;
const unitControlInstanceId = useInstanceId( UnitControl );
const unitControlInputId = `wp-block-search__width-${ unitControlInstanceId }`;

Expand Down Expand Up @@ -123,10 +131,33 @@ export default function SearchEdit( {
};
};

const getInnerBorderRadiusStyle = () => {
if ( ! borderRadius ) {
return undefined;
}

if ( 'button-inside' === buttonPosition ) {
const radius = Math.max(
borderRadius - DEFAULT_INPUT_PADDING,
MIN_INNER_RADIUS
);
return radius ? `${ radius }px` : undefined;
}

return `${ borderRadius }px`;
};

const sharedStyles = {
borderRadius: getInnerBorderRadiusStyle(),
};

const renderTextField = () => {
const textFieldStyles = { ...sharedStyles };

return (
<input
className="wp-block-search__input"
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 +174,22 @@ export default function SearchEdit( {
};

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

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

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

const renderInputs = () => {
const wrapperStyles =
'button-inside' === buttonPosition
? {
borderRadius: borderRadius
? `${ borderRadius }px`
: undefined,
}
: {};

return (
<ResizableBox
size={ { width: `${ width }${ widthUnit }` } }
className="wp-block-search__inside-wrapper"
style={ wrapperStyles }
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 @@ -243,7 +324,7 @@ export default function SearchEdit( {
</BlockControls>

<InspectorControls>
<PanelBody title={ __( 'Display Settings' ) }>
<PanelBody title={ __( 'Display settings' ) }>
<BaseControl
label={ __( 'Width' ) }
id={ unitControlInputId }
Expand Down Expand Up @@ -327,39 +408,7 @@ export default function SearchEdit( {
/>
) }

<ResizableBox
size={ {
width: `${ width }${ widthUnit }`,
} }
className="wp-block-search__inside-wrapper"
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>
{ renderInputs() }
</div>
);
}
61 changes: 55 additions & 6 deletions packages/block-library/src/search/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ function render_block_core_search( $attributes ) {
$label_markup = '';
$input_markup = '';
$button_markup = '';
$width_styles = '';

$border_radius_css = block_core_search_build_css_border_radius( $attributes );

if ( $show_label ) {
if ( ! empty( $attributes['label'] ) ) {
Expand All @@ -55,9 +56,14 @@ function render_block_core_search( $attributes ) {
}

if ( $show_input ) {
$input_styles = ! empty( $border_radius_css['style'] )
? sprintf( ' style="%s"', esc_attr( $border_radius_css['style'] ) )
: '';

$input_markup = sprintf(
'<input type="search" id="%s" class="wp-block-search__input" name="s" value="%s" placeholder="%s" required />',
'<input type="search" id="%s" class="wp-block-search__input"%s name="s" value="%s" placeholder="%s" required />',
$input_id,
$input_styles,
esc_attr( get_search_query() ),
esc_attr( $attributes['placeholder'] )
);
Expand All @@ -66,6 +72,9 @@ function render_block_core_search( $attributes ) {
if ( $show_button ) {
$button_internal_markup = '';
$button_classes = '';
$button_styles = ! empty( $border_radius_css['style'] )
? sprintf( ' style="%s"', esc_attr( $border_radius_css['style'] ) )
: '';

if ( ! $use_icon_button ) {
if ( ! empty( $attributes['buttonText'] ) ) {
Expand All @@ -80,22 +89,29 @@ function render_block_core_search( $attributes ) {
}

$button_markup = sprintf(
'<button type="submit"class="wp-block-search__button ' . $button_classes . '">%s</button>',
'<button type="submit" class="wp-block-search__button %s"%s>%s</button>',
$button_classes,
$button_styles,
$button_internal_markup
);
}

$field_styles = ( array_key_exists( 'buttonPosition', $attributes ) && 'button-inside' === $attributes['buttonPosition'] )
? $border_radius_css['wrapper_style']
: '';

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: ' . $attributes['width'] . $attributes['widthUnit'] . ';"';
}
}

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

$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );

return sprintf(
Expand All @@ -119,6 +135,39 @@ function register_block_core_search() {
}
add_action( 'init', 'register_block_core_search' );

/**
* Build an array with inline styles defining the border radius
* which will be applied to the inner elements and wrapper of the search block
* on the frontend.
*
* @param array $attributes Search block attributes.
* @return array Border radius inline styles.
*/
function block_core_search_build_css_border_radius( $attributes ) {
$padding = 4;
$border_radius = array(
'style' => '',
'wrapper_style' => '',
);

$has_border_radius = isset( $attributes['style']['border']['radius'] );
if ( ! $has_border_radius ) {
return $border_radius;
}

$radius_value = $attributes['style']['border']['radius'];
$button_inside = array_key_exists( 'buttonPosition', $attributes )
&& 'button-inside' === $attributes['buttonPosition'];

// Uses min value of 1 as having no radius when the outer does is jarring.
$radius = $button_inside ? max( $radius_value - $padding, 1 ) : $radius_value;

$border_radius['style'] = sprintf( 'border-radius: %spx;', esc_attr( $radius ) );
$border_radius['wrapper_style'] = sprintf( 'border-radius: %spx;', esc_attr( $radius_value ) );

return $border_radius;
}

/**
* Builds the correct top level classnames for the 'core/search' block.
*
Expand Down