This repository has been archived by the owner on Feb 23, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
1,026 additions
and
341 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { isObject } from 'lodash'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
getImageSrcFromProduct, | ||
} from '../../utils/products'; | ||
|
||
/** | ||
* Generate a style object given either a product object or URL to an image. | ||
* | ||
* @param {object|string} url A product object as returned from the API, or an image URL. | ||
* @return {object} A style object with a backgroundImage set (if a valid image is provided). | ||
*/ | ||
function getBackgroundImageStyles( url ) { | ||
// If `url` is an object, it's actually a product. | ||
if ( isObject( url ) ) { | ||
url = getImageSrcFromProduct( url ); | ||
} | ||
if ( url ) { | ||
return { backgroundImage: `url(${ url })` }; | ||
} | ||
return {}; | ||
} | ||
|
||
/** | ||
* Convert the selected ratio to the correct background class. | ||
* | ||
* @param {number} ratio Selected opacity from 0 to 100. | ||
* @return {string} The class name, if applicable (not used for ratio 0 or 50). | ||
*/ | ||
function dimRatioToClass( ratio ) { | ||
return ratio === 0 || ratio === 50 ? | ||
null : | ||
`has-background-dim-${ 10 * Math.round( ratio / 10 ) }`; | ||
} | ||
|
||
export { getBackgroundImageStyles, dimRatioToClass }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import classnames from 'classnames'; | ||
import { Component } from '@wordpress/element'; | ||
import PropTypes from 'prop-types'; | ||
import { withInstanceId, compose } from '@wordpress/compose'; | ||
import { PlainText } from '@wordpress/editor'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import './editor.scss'; | ||
import './style.scss'; | ||
|
||
/** | ||
* Component displaying a product search form. | ||
*/ | ||
class ProductSearchBlock extends Component { | ||
renderView() { | ||
const { attributes: { label, placeholder, formId, className, hasLabel, align } } = this.props; | ||
const home = wc_product_block_data.homeUrl; | ||
const classes = classnames( | ||
'wc-block-product-search', | ||
align ? 'align' + align : '', | ||
className, | ||
); | ||
|
||
return ( | ||
<div className={ classes }> | ||
<form role="search" method="get" action={ home }> | ||
<label | ||
htmlFor={ formId } | ||
className={ hasLabel ? 'wc-block-product-search__label' : 'wc-block-product-search__label screen-reader-text' } | ||
> | ||
{ label } | ||
</label> | ||
<div className="wc-block-product-search__fields"> | ||
<input | ||
type="search" | ||
id={ formId } | ||
className="wc-block-product-search__field" | ||
placeholder={ placeholder } | ||
name="s" | ||
/> | ||
<input type="hidden" name="post_type" value="product" /> | ||
<button | ||
type="submit" | ||
className="wc-block-product-search__button" | ||
label={ __( 'Search', 'woo-gutenberg-products-block' ) } | ||
> | ||
<svg aria-hidden="true" role="img" focusable="false" className="dashicon dashicons-arrow-right-alt2" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> | ||
<path d="M6 15l5-5-5-5 1-2 7 7-7 7z"></path> | ||
</svg> | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
); | ||
} | ||
|
||
renderEdit() { | ||
const { attributes, setAttributes, instanceId } = this.props; | ||
const { label, placeholder, formId, className, hasLabel, align } = attributes; | ||
const classes = classnames( | ||
'wc-block-product-search', | ||
align ? 'align' + align : '', | ||
className, | ||
); | ||
|
||
if ( ! formId ) { | ||
setAttributes( { formId: `wc-block-product-search-${ instanceId }` } ); | ||
} | ||
|
||
return ( | ||
<div className={ classes }> | ||
{ !! hasLabel && ( | ||
<PlainText | ||
className="wc-block-product-search__label" | ||
value={ label } | ||
onChange={ ( value ) => setAttributes( { label: value } ) } | ||
/> | ||
) } | ||
<div className="wc-block-product-search__fields"> | ||
<PlainText | ||
className="wc-block-product-search__field input-control" | ||
value={ placeholder } | ||
onChange={ ( value ) => setAttributes( { placeholder: value } ) } | ||
/> | ||
<button | ||
type="submit" | ||
className="wc-block-product-search__button" | ||
label={ __( 'Search', 'woo-gutenberg-products-block' ) } | ||
onClick={ ( e ) => e.preventDefault() } | ||
tabIndex="-1" | ||
> | ||
<svg aria-hidden="true" role="img" focusable="false" className="dashicon dashicons-arrow-right-alt2" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"> | ||
<path d="M6 15l5-5-5-5 1-2 7 7-7 7z"></path> | ||
</svg> | ||
</button> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
render() { | ||
if ( this.props.isPreview ) { | ||
return this.renderEdit(); | ||
} | ||
|
||
return this.renderView(); | ||
} | ||
} | ||
|
||
ProductSearchBlock.propTypes = { | ||
/** | ||
* The attributes for this block. | ||
*/ | ||
attributes: PropTypes.object.isRequired, | ||
/** | ||
* A unique ID for identifying the label for the select dropdown. | ||
*/ | ||
instanceId: PropTypes.number, | ||
/** | ||
* Whether this is the block preview or frontend display. | ||
*/ | ||
isPreview: PropTypes.bool, | ||
/** | ||
* A callback to update attributes. | ||
*/ | ||
setAttributes: PropTypes.func, | ||
}; | ||
|
||
export default compose( [ | ||
withInstanceId, | ||
] )( ProductSearchBlock ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
.wc-block-product-search__field.input-control { | ||
color: #828b96 !important; | ||
} | ||
.wc-block-product-search { | ||
.wc-block-product-search__fields { | ||
.block-editor-rich-text { | ||
flex-grow: 1; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { registerBlockType } from '@wordpress/blocks'; | ||
import { InspectorControls } from '@wordpress/editor'; | ||
import { PanelBody, ToggleControl } from '@wordpress/components'; | ||
import { Fragment } from '@wordpress/element'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import './style.scss'; | ||
import './editor.scss'; | ||
import Block from './block.js'; | ||
|
||
registerBlockType( 'woocommerce/product-search', { | ||
title: __( 'Product Search', 'woo-gutenberg-products-block' ), | ||
icon: { | ||
src: 'search', | ||
foreground: '#96588a', | ||
}, | ||
category: 'woocommerce', | ||
keywords: [ __( 'WooCommerce', 'woo-gutenberg-products-block' ) ], | ||
description: __( | ||
'Help visitors find your products.', | ||
'woo-gutenberg-products-block' | ||
), | ||
supports: { | ||
align: [ 'wide', 'full' ], | ||
}, | ||
|
||
attributes: { | ||
/** | ||
* Whether to show the field label. | ||
*/ | ||
hasLabel: { | ||
type: 'boolean', | ||
default: true, | ||
}, | ||
|
||
/** | ||
* Search field label. | ||
*/ | ||
label: { | ||
type: 'string', | ||
default: __( 'Search', 'woo-gutenberg-products-block' ), | ||
source: 'text', | ||
selector: 'label', | ||
}, | ||
|
||
/** | ||
* Search field placeholder. | ||
*/ | ||
placeholder: { | ||
type: 'string', | ||
default: __( 'Search products...', 'woo-gutenberg-products-block' ), | ||
source: 'attribute', | ||
selector: 'input.wc-block-product-search__field', | ||
attribute: 'placeholder', | ||
}, | ||
|
||
/** | ||
* Store the instance ID. | ||
*/ | ||
formId: { | ||
type: 'string', | ||
default: '', | ||
}, | ||
}, | ||
|
||
/** | ||
* Renders and manages the block. | ||
*/ | ||
edit( props ) { | ||
const { attributes, setAttributes } = props; | ||
const { hasLabel } = attributes; | ||
return ( | ||
<Fragment> | ||
<InspectorControls key="inspector"> | ||
<PanelBody | ||
title={ __( 'Content', 'woo-gutenberg-products-block' ) } | ||
initialOpen | ||
> | ||
|
||
<ToggleControl | ||
label={ __( 'Show search field label', 'woo-gutenberg-products-block' ) } | ||
help={ | ||
hasLabel ? | ||
__( 'Label is visible.', 'woo-gutenberg-products-block' ) : | ||
__( 'Label is hidden.', 'woo-gutenberg-products-block' ) | ||
} | ||
checked={ hasLabel } | ||
onChange={ () => setAttributes( { hasLabel: ! hasLabel } ) } | ||
/> | ||
</PanelBody> | ||
</InspectorControls> | ||
<Block { ...props } isPreview /> | ||
</Fragment> | ||
); | ||
}, | ||
|
||
/** | ||
* Save the props to post content. | ||
*/ | ||
save( attributes ) { | ||
return ( | ||
<div> | ||
<Block { ...attributes } /> | ||
</div> | ||
); | ||
}, | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
.wc-block-product-search { | ||
.wc-block-product-search__fields { | ||
display: flex; | ||
} | ||
.wc-block-product-search__field { | ||
padding: 6px 8px; | ||
line-height: 1.8; | ||
flex-grow: 1; | ||
} | ||
.wc-block-product-search__button { | ||
display: flex; | ||
align-items: center; | ||
text-decoration: none; | ||
font-size: 13px; | ||
margin: 0 0 0 6px; | ||
border: none; | ||
cursor: pointer; | ||
background: none; | ||
padding: 8px; | ||
color: #555d66; | ||
position: relative; | ||
overflow: hidden; | ||
border-radius: 4px; | ||
svg { | ||
fill: currentColor; | ||
outline: none; | ||
} | ||
.screen-reader-text { | ||
height: auto; | ||
} | ||
&:active { | ||
color: currentColor; | ||
} | ||
&:disabled, | ||
&[aria-disabled="true"] { | ||
cursor: default; | ||
opacity: 0.3; | ||
} | ||
&:focus:enabled { | ||
background-color: #fff; | ||
color: #191e23; | ||
box-shadow: inset 0 0 0 1px #6c7781, inset 0 0 0 2px #fff; | ||
outline: 2px solid transparent; | ||
outline-offset: -2px; | ||
} | ||
&:not(:disabled):not([aria-disabled="true"]):hover { | ||
background-color: #fff; | ||
color: #191e23; | ||
box-shadow: inset 0 0 0 1px #e2e4e7, inset 0 0 0 2px #fff, 0 1px 1px rgba(25, 30, 35, 0.2); | ||
} | ||
&:not(:disabled):not([aria-disabled="true"]):active { | ||
outline: none; | ||
background-color: #fff; | ||
color: #191e23; | ||
box-shadow: inset 0 0 0 1px #ccd0d4, inset 0 0 0 2px #fff; | ||
} | ||
&[aria-disabled="true"]:focus, | ||
&:disabled:focus { | ||
box-shadow: none; | ||
} | ||
} | ||
} |
Oops, something went wrong.