diff --git a/packages/block-library/src/search/block.json b/packages/block-library/src/search/block.json
index 0a2f217aca34b..92de1d6f028b3 100644
--- a/packages/block-library/src/search/block.json
+++ b/packages/block-library/src/search/block.json
@@ -5,16 +5,35 @@
"label": {
"type": "string"
},
+ "showLabel": {
+ "type": "bool",
+ "default": true
+ },
"placeholder": {
"type": "string",
"default": ""
},
+ "width": {
+ "type": "number"
+ },
+ "widthUnit": {
+ "type": "string"
+ },
"buttonText": {
"type": "string"
+ },
+ "buttonPosition": {
+ "type": "string",
+ "default": "button-outside"
+ },
+ "buttonUseIcon": {
+ "type": "bool",
+ "default": false
}
},
"supports": {
- "align": true,
- "html": false
+ "align": [ "left", "center", "right" ],
+ "html": false,
+ "lightBlockWrapper": true
}
}
diff --git a/packages/block-library/src/search/edit.js b/packages/block-library/src/search/edit.js
index 5de591fb867ae..3665c8cdac047 100644
--- a/packages/block-library/src/search/edit.js
+++ b/packages/block-library/src/search/edit.js
@@ -1,22 +1,130 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+
/**
* WordPress dependencies
*/
-import { RichText } from '@wordpress/block-editor';
+import {
+ __experimentalBlock as Block,
+ BlockControls,
+ InspectorControls,
+ RichText,
+ __experimentalUnitControl as UnitControl,
+} from '@wordpress/block-editor';
+import {
+ DropdownMenu,
+ MenuGroup,
+ MenuItem,
+ ToolbarGroup,
+ Button,
+ ButtonGroup,
+ ToolbarButton,
+ ResizableBox,
+ PanelBody,
+ BaseControl,
+} from '@wordpress/components';
+import { useInstanceId } from '@wordpress/compose';
+import { search } from '@wordpress/icons';
import { __ } from '@wordpress/i18n';
-export default function SearchEdit( { className, attributes, setAttributes } ) {
- const { label, placeholder, buttonText } = attributes;
+/**
+ * Internal dependencies
+ */
+import {
+ buttonOnly,
+ buttonOutside,
+ buttonInside,
+ noButton,
+ buttonWithIcon,
+ toggleLabel,
+} from './icons';
- return (
-
- setAttributes( { label: html } ) }
- />
+/**
+ * Constants
+ */
+const MIN_WIDTH = 220;
+const MIN_WIDTH_UNIT = 'px';
+const PC_WIDTH_DEFAULT = 50;
+const PX_WIDTH_DEFAULT = 350;
+const CSS_UNITS = [
+ { value: '%', label: '%', default: PC_WIDTH_DEFAULT },
+ { value: 'px', label: 'px', default: PX_WIDTH_DEFAULT },
+];
+
+export default function SearchEdit( {
+ className,
+ attributes,
+ setAttributes,
+ toggleSelection,
+ isSelected,
+} ) {
+ const {
+ label,
+ showLabel,
+ placeholder,
+ width,
+ widthUnit,
+ align,
+ buttonText,
+ buttonPosition,
+ buttonUseIcon,
+ } = attributes;
+
+ const unitControlInstanceId = useInstanceId( UnitControl );
+ const unitControlInputId = `wp-block-search__width-${ unitControlInstanceId }`;
+
+ const getBlockClassNames = () => {
+ return classnames(
+ className,
+ 'button-inside' === buttonPosition
+ ? 'wp-block-search__button-inside'
+ : undefined,
+ 'button-outside' === buttonPosition
+ ? '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
+ ? 'wp-block-search__text-button'
+ : undefined,
+ ! buttonUseIcon && 'no-button' !== buttonPosition
+ ? 'wp-block-search__icon-button'
+ : undefined
+ );
+ };
+
+ const getButtonPositionIcon = () => {
+ switch ( buttonPosition ) {
+ case 'button-inside':
+ return buttonInside;
+ case 'button-outside':
+ return buttonOutside;
+ case 'no-button':
+ return noButton;
+ case 'button-only':
+ return buttonOnly;
+ }
+ };
+
+ const getResizableSides = () => {
+ if ( 'button-only' === buttonPosition ) {
+ return {};
+ }
+
+ return {
+ right: align === 'right' ? false : true,
+ left: align === 'right' ? true : false,
+ };
+ };
+
+ const renderTextField = () => {
+ return (
- setAttributes( { buttonText: html } ) }
- />
-
+ );
+ };
+
+ const renderButton = () => {
+ return (
+ <>
+ { buttonUseIcon && (
+
+ ) }
+
+ { ! buttonUseIcon && (
+
+ setAttributes( { buttonText: html } )
+ }
+ />
+ ) }
+ >
+ );
+ };
+
+ const controls = (
+ <>
+
+
+ {
+ setAttributes( {
+ showLabel: ! showLabel,
+ } );
+ } }
+ className={ showLabel ? 'is-pressed' : undefined }
+ />
+
+ { ( { onClose } ) => (
+
+
+
+
+
+
+ ) }
+
+
+ { 'no-button' !== buttonPosition && (
+ {
+ setAttributes( {
+ buttonUseIcon: ! buttonUseIcon,
+ } );
+ } }
+ className={
+ buttonUseIcon ? 'is-pressed' : undefined
+ }
+ />
+ ) }
+
+
+
+
+
+
+ {
+ const filteredWidth =
+ widthUnit === '%' &&
+ parseInt( newWidth, 10 ) > 100
+ ? 100
+ : newWidth;
+
+ setAttributes( {
+ width: parseInt( filteredWidth, 10 ),
+ } );
+ } }
+ onUnitChange={ ( newUnit ) => {
+ setAttributes( {
+ width:
+ '%' === newUnit
+ ? PC_WIDTH_DEFAULT
+ : PX_WIDTH_DEFAULT,
+ widthUnit: newUnit,
+ } );
+ } }
+ style={ { maxWidth: 80 } }
+ value={ `${ width }${ widthUnit }` }
+ unit={ widthUnit }
+ units={ CSS_UNITS }
+ />
+
+
+ { [ 25, 50, 75, 100 ].map( ( widthValue ) => {
+ return (
+
+ );
+ } ) }
+
+
+
+
+ >
+ );
+
+ return (
+
+ { controls }
+
+ { showLabel && (
+ setAttributes( { label: html } ) }
+ />
+ ) }
+
+ {
+ 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() }
+
+
);
}
diff --git a/packages/block-library/src/search/editor.scss b/packages/block-library/src/search/editor.scss
index 1564fcedc3cda..bc2cd0dfe6e38 100644
--- a/packages/block-library/src/search/editor.scss
+++ b/packages/block-library/src/search/editor.scss
@@ -1,18 +1,27 @@
.wp-block-search {
- &__input {
+ .wp-block-search__input {
+ padding: $grid-unit-10;
+ }
+
+ &.wp-block-search__button-inside .wp-block-search__inside-wrapper {
+ padding: $grid-unit-05;
+ }
+
+ .wp-block-search__input,
+ &.wp-block-search__button-inside .wp-block-search__inside-wrapper {
border-radius: $radius-block-ui;
border: 1px solid $dark-gray-200;
color: $dark-gray-placeholder;
font-family: $default-font;
font-size: $default-font-size;
- padding: $grid-unit-10;
+ background-color: $white;
&:focus {
outline: none;
}
}
- &__button {
+ .wp-block-search__button {
background: #f7f7f7;
border-radius: $radius-block-ui;
border: 1px solid #ccc;
@@ -20,5 +29,10 @@
font-family: $default-font;
font-size: $default-font-size;
padding: 6px 10px;
+ color: $dark-gray-700;
+ }
+
+ &__components-button-group {
+ margin-top: 10px;
}
}
diff --git a/packages/block-library/src/search/icons.js b/packages/block-library/src/search/icons.js
new file mode 100644
index 0000000000000..d795398382859
--- /dev/null
+++ b/packages/block-library/src/search/icons.js
@@ -0,0 +1,89 @@
+/**
+ * WordPress dependencies
+ */
+import { SVG, Rect } from '@wordpress/components';
+
+export const buttonOnly = (
+
+);
+
+export const buttonOutside = (
+
+);
+
+export const buttonInside = (
+
+);
+
+export const noButton = (
+
+);
+
+export const buttonWithIcon = (
+
+);
+
+export const toggleLabel = (
+
+);
diff --git a/packages/block-library/src/search/index.php b/packages/block-library/src/search/index.php
index d1f7e84d2d915..08c8652839835 100644
--- a/packages/block-library/src/search/index.php
+++ b/packages/block-library/src/search/index.php
@@ -27,42 +27,79 @@ function render_block_core_search( $attributes ) {
)
);
- $input_id = 'wp-block-search__input-' . ++$instance_id;
- $label_markup = '';
- $button_markup = '';
+ $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 = '';
- if ( ! empty( $attributes['label'] ) ) {
- $label_markup = sprintf(
- '',
- $input_id,
- $attributes['label']
- );
- } else {
- $label_markup = sprintf(
- '',
+ if ( $show_label ) {
+ if ( ! empty( $attributes['label'] ) ) {
+ $label_markup = sprintf(
+ '',
+ $input_id,
+ $attributes['label']
+ );
+ } else {
+ $label_markup = sprintf(
+ '',
+ $input_id,
+ __( 'Search' )
+ );
+ }
+ }
+
+ if ( $show_input ) {
+ $input_markup = sprintf(
+ '',
$input_id,
- __( 'Search' )
+ esc_attr( get_search_query() ),
+ esc_attr( $attributes['placeholder'] )
);
}
- $input_markup = sprintf(
- '',
- $input_id,
- esc_attr( get_search_query() ),
- esc_attr( $attributes['placeholder'] )
- );
+ if ( $show_button ) {
+ $button_internal_markup = '';
+
+ if ( ! $use_icon_button ) {
+ if ( ! empty( $attributes['buttonText'] ) ) {
+ $button_internal_markup = $attributes['buttonText'];
+ }
+ } else {
+ $button_internal_markup =
+ '';
+ }
- if ( ! empty( $attributes['buttonText'] ) ) {
$button_markup = sprintf(
'',
- $attributes['buttonText']
+ $button_internal_markup
);
}
+ if ( ! empty( $attributes['width'] ) && ! empty( $attributes['widthUnit'] ) ) {
+ if ( ! empty( $attributes['buttonPosition'] ) && 'button-only' !== $attributes['buttonPosition'] ) {
+ $width_styles = ' style="width: ' . $attributes['width'] . $attributes['widthUnit'] . ';"';
+ }
+ }
+
+ $field_markup = sprintf(
+ '%s
',
+ $width_styles,
+ $input_markup . $button_markup
+ );
+
return sprintf(
- '',
+ '',
esc_url( home_url( '/' ) ),
- $label_markup . $input_markup . $button_markup
+ $classnames,
+ $label_markup . $field_markup
);
}
@@ -78,3 +115,44 @@ function register_block_core_search() {
);
}
add_action( 'init', 'register_block_core_search' );
+
+/**
+ * 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 ) {
+ $classnames = array();
+
+ if ( ! empty( $attributes['buttonPosition'] ) ) {
+ if ( 'button-inside' === $attributes['buttonPosition'] ) {
+ $classnames[] = 'wp-block-search__button-inside';
+ }
+
+ if ( 'button-outside' === $attributes['buttonPosition'] ) {
+ $classnames[] = 'wp-block-search__button-outside';
+ }
+
+ if ( 'no-button' === $attributes['buttonPosition'] ) {
+ $classnames[] = 'wp-block-search__no-button';
+ }
+
+ if ( 'button-only' === $attributes['buttonPosition'] ) {
+ $classnames[] = 'wp-block-search__button-only';
+ }
+ }
+
+ if ( isset( $attributes['buttonUseIcon'] ) ) {
+ if ( ! empty( $attributes['buttonPosition'] ) && 'no-button' !== $attributes['buttonPosition'] ) {
+ if ( $attributes['buttonUseIcon'] ) {
+ $classnames[] = 'wp-block-search__icon-button';
+ } else {
+ $classnames[] = 'wp-block-search__text-button';
+ }
+ }
+ }
+
+ return implode( ' ', $classnames );
+}
diff --git a/packages/block-library/src/search/style.scss b/packages/block-library/src/search/style.scss
index aaa4724ac3192..2c8b03cafb275 100644
--- a/packages/block-library/src/search/style.scss
+++ b/packages/block-library/src/search/style.scss
@@ -1,6 +1,10 @@
.wp-block-search {
- display: flex;
- flex-wrap: wrap;
+ .wp-block-search__inside-wrapper {
+ display: flex;
+ flex: auto;
+ flex-wrap: nowrap;
+ max-width: 100%;
+ }
.wp-block-search__label {
width: 100%;
@@ -8,10 +12,43 @@
.wp-block-search__input {
flex-grow: 1;
- max-width: 22.5em;
+ min-width: 3em;
+ border: 1px solid $dark-gray-200;
}
.wp-block-search__button {
margin-left: 0.625em;
+ word-break: normal;
+
+ svg {
+ min-width: 1.5em;
+ min-height: 1.5em;
+ }
+ }
+
+ &.wp-block-search__button-only {
+ .wp-block-search__button {
+ margin-left: 0;
+ }
+ }
+
+ &.wp-block-search__button-inside .wp-block-search__inside-wrapper {
+ padding: $grid-unit-05;
+ border: 1px solid $dark-gray-200;
+
+ .wp-block-search__input {
+ border-radius: 0;
+ border: none;
+ padding: 0 0 0 0.25em;
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ .wp-block-search__button {
+ padding: 0.125em 0.5em;
+ }
}
}
+
diff --git a/packages/e2e-tests/fixtures/blocks/core__search.json b/packages/e2e-tests/fixtures/blocks/core__search.json
index e52d38cd79ca2..9bfe776f2127f 100644
--- a/packages/e2e-tests/fixtures/blocks/core__search.json
+++ b/packages/e2e-tests/fixtures/blocks/core__search.json
@@ -4,7 +4,10 @@
"name": "core/search",
"isValid": true,
"attributes": {
- "placeholder": ""
+ "buttonPosition": "button-outside",
+ "buttonUseIcon": false,
+ "placeholder": "",
+ "showLabel": true
},
"innerBlocks": [],
"originalContent": ""
diff --git a/packages/e2e-tests/fixtures/blocks/core__search__custom-text.json b/packages/e2e-tests/fixtures/blocks/core__search__custom-text.json
index fb91161919c83..5d2c86a18d590 100644
--- a/packages/e2e-tests/fixtures/blocks/core__search__custom-text.json
+++ b/packages/e2e-tests/fixtures/blocks/core__search__custom-text.json
@@ -4,9 +4,12 @@
"name": "core/search",
"isValid": true,
"attributes": {
+ "buttonPosition": "button-outside",
"label": "Custom label",
"placeholder": "Custom placeholder",
- "buttonText": "Custom button text"
+ "buttonText": "Custom button text",
+ "buttonUseIcon": false,
+ "showLabel": true
},
"innerBlocks": [],
"originalContent": ""