Skip to content

Commit

Permalink
Search Block: Add border color support (#31783)
Browse files Browse the repository at this point in the history
  • Loading branch information
ramonjd authored Jul 19, 2021
1 parent 90fd29e commit ceaa2da
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 52 deletions.
1 change: 1 addition & 0 deletions packages/block-library/src/search/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"supports": {
"align": [ "left", "center", "right" ],
"__experimentalBorder": {
"color": true,
"radius": true,
"__experimentalSkipSerialization": true
},
Expand Down
88 changes: 57 additions & 31 deletions packages/block-library/src/search/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export default function SearchEdit( {
} = attributes;

const borderRadius = style?.border?.radius;
const borderColor = style?.border?.color;
const borderProps = useBorderProps( attributes );

// Check for old deprecated numerical border radius. Done as a separate
Expand All @@ -83,6 +84,10 @@ export default function SearchEdit( {

const unitControlInstanceId = useInstanceId( UnitControl );
const unitControlInputId = `wp-block-search__width-${ unitControlInstanceId }`;
const isButtonPositionInside = 'button-inside' === buttonPosition;
const isButtonPositionOutside = 'button-outside' === buttonPosition;
const hasNoButton = 'no-button' === buttonPosition;
const hasOnlyButton = 'button-only' === buttonPosition;

const units = useCustomUnits( {
availableUnits: [ '%', 'px' ],
Expand All @@ -92,22 +97,19 @@ export default function SearchEdit( {
const getBlockClassNames = () => {
return classnames(
className,
'button-inside' === buttonPosition
! isButtonPositionInside ? borderProps.className : undefined,
isButtonPositionInside
? 'wp-block-search__button-inside'
: undefined,
'button-outside' === buttonPosition
isButtonPositionOutside
? 'wp-block-search__button-outside'
: undefined,
'no-button' === buttonPosition
? 'wp-block-search__no-button'
: undefined,
'button-only' === buttonPosition
? 'wp-block-search__button-only'
: undefined,
! buttonUseIcon && 'no-button' !== buttonPosition
hasNoButton ? 'wp-block-search__no-button' : undefined,
hasOnlyButton ? 'wp-block-search__button-only' : undefined,
! buttonUseIcon && ! hasNoButton
? 'wp-block-search__text-button'
: undefined,
buttonUseIcon && 'no-button' !== buttonPosition
buttonUseIcon && ! hasNoButton
? 'wp-block-search__icon-button'
: undefined
);
Expand Down Expand Up @@ -163,21 +165,30 @@ export default function SearchEdit( {
};

const getResizableSides = () => {
if ( 'button-only' === buttonPosition ) {
if ( hasOnlyButton ) {
return {};
}

return {
right: align === 'right' ? false : true,
left: align === 'right' ? true : false,
right: align !== 'right',
left: align === 'right',
};
};

const renderTextField = () => {
// If the input is inside the wrapper, the wrapper gets the border color styles/classes, not the input control.
const textFieldClasses = classnames(
'wp-block-search__input',
isButtonPositionInside ? undefined : borderProps.className
);
const textFieldStyles = isButtonPositionInside
? { borderRadius }
: borderProps.style;

return (
<input
className="wp-block-search__input"
style={ borderProps.style }
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 @@ -194,20 +205,29 @@ export default function SearchEdit( {
};

const renderButton = () => {
// If the button is inside the wrapper, the wrapper gets the border color styles/classes, not the button.
const buttonClasses = classnames(
'wp-block-search__button',
isButtonPositionInside ? undefined : borderProps.className
);
const buttonStyles = isButtonPositionInside
? { borderRadius }
: borderProps.style;

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

{ ! buttonUseIcon && (
<RichText
className="wp-block-search__button"
style={ borderProps.style }
className={ buttonClasses }
style={ buttonStyles }
aria-label={ __( 'Button text' ) }
placeholder={ __( 'Add button text…' ) }
withoutInteractiveFormatting
Expand Down Expand Up @@ -240,7 +260,7 @@ export default function SearchEdit( {
label={ __( 'Change button position' ) }
controls={ buttonPositionControls }
/>
{ 'no-button' !== buttonPosition && (
{ ! hasNoButton && (
<ToolbarButton
title={ __( 'Use button with icon' ) }
icon={ buttonWithIcon }
Expand Down Expand Up @@ -329,13 +349,18 @@ export default function SearchEdit( {
radius ? `calc(${ radius } + ${ DEFAULT_INNER_PADDING })` : undefined;

const getWrapperStyles = () => {
const styles = {
borderColor,
};

const isNonZeroBorderRadius = parseInt( borderRadius, 10 ) !== 0;

if ( 'button-inside' === buttonPosition && isNonZeroBorderRadius ) {
if ( isButtonPositionInside && isNonZeroBorderRadius ) {
// We have button inside wrapper and a border radius value to apply.
// Add default padding so we don't get "fat" corners.
//
// CSS calc() is used here to support non-pixel units.
// CSS calc() is used here to support non-pixel units. The inline
// style using calc() will only apply if both values have units.

if ( typeof borderRadius === 'object' ) {
// Individual corner border radii present.
Expand All @@ -351,6 +376,7 @@ export default function SearchEdit( {
borderTopRightRadius: padBorderRadius( topRight ),
borderBottomLeftRadius: padBorderRadius( bottomLeft ),
borderBottomRightRadius: padBorderRadius( bottomRight ),
...styles,
};
}

Expand All @@ -361,12 +387,10 @@ export default function SearchEdit( {
? `${ borderRadius }px`
: borderRadius;

return {
borderRadius: `calc(${ radius } + ${ DEFAULT_INNER_PADDING })`,
};
styles.borderRadius = `calc(${ radius } + ${ DEFAULT_INNER_PADDING })`;
}

return undefined;
return styles;
};

const blockProps = useBlockProps( {
Expand All @@ -392,7 +416,10 @@ export default function SearchEdit( {
size={ {
width: `${ width }${ widthUnit }`,
} }
className="wp-block-search__inside-wrapper"
className={ classnames(
'wp-block-search__inside-wrapper',
isButtonPositionInside ? borderProps.className : undefined
) }
style={ getWrapperStyles() }
minWidth={ MIN_WIDTH }
enable={ getResizableSides() }
Expand All @@ -411,16 +438,15 @@ export default function SearchEdit( {
} }
showHandle={ isSelected }
>
{ ( 'button-inside' === buttonPosition ||
'button-outside' === buttonPosition ) && (
{ ( isButtonPositionInside || isButtonPositionOutside ) && (
<>
{ renderTextField() }
{ renderButton() }
</>
) }

{ 'button-only' === buttonPosition && renderButton() }
{ 'no-button' === buttonPosition && renderTextField() }
{ hasOnlyButton && renderButton() }
{ hasNoButton && renderTextField() }
</ResizableBox>
</div>
);
Expand Down
84 changes: 63 additions & 21 deletions packages/block-library/src/search/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,20 @@ function render_block_core_search( $attributes ) {
)
);

$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 = '';
$inline_styles = styles_for_block_core_search( $attributes );
$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 = '';
$inline_styles = styles_for_block_core_search( $attributes );
$is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
'button-inside' === $attributes['buttonPosition'];
// Border color classes need to be applied to the elements that have a border color.
$border_color_classes = get_border_color_classes_for_block_core_search( $attributes );

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

if ( $show_input ) {
$input_markup = sprintf(
'<input type="search" id="%s" class="wp-block-search__input" name="s" value="%s" placeholder="%s" %s required />',
$input_classes = ! $is_button_inside ? $border_color_classes : '';
$input_markup = sprintf(
'<input type="search" id="%s" class="wp-block-search__input %s" name="s" value="%s" placeholder="%s" %s required />',
$input_id,
$input_classes,
esc_attr( get_search_query() ),
esc_attr( $attributes['placeholder'] ),
$inline_styles['shared']
Expand All @@ -66,34 +72,36 @@ function render_block_core_search( $attributes ) {

if ( $show_button ) {
$button_internal_markup = '';
$button_classes = '';
$button_classes = ! $is_button_inside ? $border_color_classes : '';

if ( ! $use_icon_button ) {
if ( ! empty( $attributes['buttonText'] ) ) {
$button_internal_markup = $attributes['buttonText'];
}
} else {
$button_classes .= 'has-icon';
$button_classes .= ' has-icon';
$button_internal_markup =
'<svg id="search-icon" class="search-icon" viewBox="0 0 24 24" width="24" height="24">
<path d="M13.5 6C10.5 6 8 8.5 8 11.5c0 1.1.3 2.1.9 3l-3.4 3 1 1.1 3.4-2.9c1 .9 2.2 1.4 3.6 1.4 3 0 5.5-2.5 5.5-5.5C19 8.5 16.5 6 13.5 6zm0 9.5c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"></path>
</svg>';
}

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

$field_markup = sprintf(
'<div class="wp-block-search__inside-wrapper"%s>%s</div>',
$field_markup_classes = $is_button_inside ? $border_color_classes : '';
$field_markup = sprintf(
'<div class="wp-block-search__inside-wrapper %s" %s>%s</div>',
$field_markup_classes,
$inline_styles['wrapper'],
$input_markup . $button_markup
);
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );
$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) );

return sprintf(
'<form role="search" method="get" action="%s" %s>%s</form>',
Expand Down Expand Up @@ -190,7 +198,8 @@ function styles_for_block_core_search( $attributes ) {
if ( $has_border_radius ) {
$default_padding = '4px';
$border_radius = $attributes['style']['border']['radius'];
$button_inside = ! empty( $attributes['buttonPosition'] ) &&
// Apply wrapper border radius if button placed inside.
$is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
'button-inside' === $attributes['buttonPosition'];

if ( is_array( $border_radius ) ) {
Expand All @@ -209,7 +218,7 @@ function styles_for_block_core_search( $attributes ) {

// Add adjusted border radius styles for the wrapper element
// if button is positioned inside.
if ( $button_inside && intval( $value ) !== 0 ) {
if ( $is_button_inside && intval( $value ) !== 0 ) {
$wrapper_styles[] = sprintf(
'border-%s-radius: calc(%s + %s);',
esc_attr( $name ),
Expand All @@ -224,7 +233,7 @@ function styles_for_block_core_search( $attributes ) {
$border_radius = is_numeric( $border_radius ) ? $border_radius . 'px' : $border_radius;
$shared_styles[] = sprintf( 'border-radius: %s;', esc_attr( $border_radius ) );

if ( $button_inside && intval( $border_radius ) !== 0 ) {
if ( $is_button_inside && intval( $border_radius ) !== 0 ) {
// Adjust wrapper border radii to maintain visual consistency
// with inner elements when button is positioned inside.
$wrapper_styles[] = sprintf(
Expand All @@ -236,8 +245,41 @@ function styles_for_block_core_search( $attributes ) {
}
}

// Add border color styles.
$has_border_color = ! empty( $attributes['style']['border']['color'] );

if ( $has_border_color ) {
$border_color = $attributes['style']['border']['color'];
$is_button_inside = ! empty( $attributes['buttonPosition'] ) &&
'button-inside' === $attributes['buttonPosition'];

// Apply wrapper border color if button placed inside.
if ( $is_button_inside ) {
$wrapper_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
} else {
$shared_styles[] = sprintf( 'border-color: %s;', esc_attr( $border_color ) );
}
}

return array(
'shared' => ! empty( $shared_styles ) ? sprintf( ' style="%s"', implode( ' ', $shared_styles ) ) : '',
'wrapper' => ! empty( $wrapper_styles ) ? sprintf( ' style="%s"', implode( ' ', $wrapper_styles ) ) : '',
);
}

/**
* Returns border color classnames depending on whether there are named or custom border colors.
*
* @param array $attributes The block attributes.
*
* @return string The border color classnames to be applied to the block elements.
*/
function get_border_color_classes_for_block_core_search( $attributes ) {
$has_custom_border_color = ! empty( $attributes['style']['border']['color'] );
$border_color_classes = ! empty( $attributes['borderColor'] ) ? sprintf( 'has-border-color has-%s-border-color', $attributes['borderColor'] ) : '';
// If there's a border color style and no `borderColor` text string, we still want to add the generic `has-border-color` class name to the element.
if ( $has_custom_border_color && empty( $attributes['borderColor'] ) ) {
$border_color_classes = 'has-border-color';
}
return $border_color_classes;
}

0 comments on commit ceaa2da

Please sign in to comment.