Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Enable more style options for the Featured Category block (#6276)
Browse files Browse the repository at this point in the history
* Enable more options for the Featured Category block

* Fix the focal point picker
* Fix the resizeable handle
* Fix the overlay and move to own section
* Enable gradient and duotone
* Add padding and fix min height

* Export ConstrainedResizeable from Featured Product

* Wrap duotone in feature plugin flag

* Add support for `border-radius`

* Change prop order

* Add SSR for new options on Featured Category block

* Optional chaining on border radius

Co-authored-by: Tom Cafferkey <[email protected]>

* Add default to overlay and height

* Optional chaining on border radius for Featured Product block

* Fix gradient persistence and default overlay discrepacies

* Explicitly add box-sizing to the featured-product/category wrapper

Co-authored-by: Tom Cafferkey <[email protected]>
  • Loading branch information
sunyatasattva and tjcafferkey authored Apr 21, 2022
1 parent a065984 commit e079f26
Show file tree
Hide file tree
Showing 8 changed files with 401 additions and 128 deletions.
231 changes: 178 additions & 53 deletions assets/js/blocks/featured-category/block.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/* eslint-disable @wordpress/no-unsafe-wp-apis */

/**
* External dependencies
*/
import { useCallback } from 'react';
import { __ } from '@wordpress/i18n';
import {
AlignmentToolbar,
Expand All @@ -9,25 +12,28 @@ import {
InspectorControls,
MediaReplaceFlow,
RichText,
__experimentalGetSpacingClassesAndStyles as getSpacingClassesAndStyles,
__experimentalPanelColorGradientSettings as PanelColorGradientSettings,
__experimentalUseGradient as useGradient,
} from '@wordpress/block-editor';
import {
Button,
FocalPointPicker,
PanelBody,
Placeholder,
RangeControl,
ResizableBox,
Spinner,
ToggleControl,
ToolbarGroup,
withSpokenMessages,
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';
import classnames from 'classnames';
import { Component } from '@wordpress/element';
import { withSelect } from '@wordpress/data';
import { compose, createHigherOrderComponent } from '@wordpress/compose';
import PropTypes from 'prop-types';
import { getSetting } from '@woocommerce/settings';
import { folderStarred } from '@woocommerce/icons';
import { Icon } from '@wordpress/icons';
import ProductCategoryControl from '@woocommerce/editor-components/product-category-control';
Expand All @@ -39,11 +45,12 @@ import TextToolbarButton from '@woocommerce/editor-components/text-toolbar-butto
*/
import {
dimRatioToClass,
getBackgroundImageStyles,
getCategoryImageId,
getCategoryImageSrc,
} from './utils';
import { withCategory } from '../../hocs';
import { calculateBackgroundImagePosition } from '../featured-product/utils';
import { ConstrainedResizable } from '../featured-product/block';

/**
* Component to handle edit mode of "Featured Category".
Expand All @@ -70,6 +77,18 @@ const FeaturedCategory = ( {
debouncedSpeak,
triggerUrlUpdate = () => void null,
} ) => {
const { setGradient } = useGradient( {
gradientAttribute: 'overlayGradient',
customGradientAttribute: 'overlayGradient',
} );

const onResize = useCallback(
( _event, _direction, elt ) => {
setAttributes( { minHeight: parseInt( elt.style.height, 10 ) } );
},
[ setAttributes ]
);

const renderApiError = () => (
<ErrorPlaceholder
className="wc-block-featured-category-error"
Expand Down Expand Up @@ -157,39 +176,114 @@ const FeaturedCategory = ( {
</PanelBody>
{ !! url && (
<>
<PanelBody
{ focalPointPickerExists && (
<PanelBody
title={ __(
'Media settings',
'woo-gutenberg-products-block'
) }
>
<ToggleGroupControl
help={
<>
<p>
{ __(
'Choose “Cover” if you want the image to scale automatically to always fit its container.',
'woo-gutenberg-products-block'
) }
</p>
<p>
{ __(
'Note: by choosing “Cover” you will lose the ability to freely move the focal point precisely.',
'woo-gutenberg-products-block'
) }
</p>
</>
}
label={ __(
'Image fit',
'woo-gutenberg-products-block'
) }
value={ attributes.imageFit }
onChange={ ( value ) =>
setAttributes( {
imageFit: value,
} )
}
>
<ToggleGroupControlOption
label={ __(
'None',
'woo-gutenberg-products-block'
) }
value="none"
/>
<ToggleGroupControlOption
/* translators: "Cover" is a verb that indicates an image covering the entire container. */
label={ __(
'Cover',
'woo-gutenberg-products-block'
) }
value="cover"
/>
</ToggleGroupControl>
<FocalPointPicker
label={ __(
'Focal Point Picker',
'woo-gutenberg-products-block'
) }
url={ url }
value={ focalPoint }
onChange={ ( value ) =>
setAttributes( {
focalPoint: value,
} )
}
/>
</PanelBody>
) }
<PanelColorGradientSettings
__experimentalHasMultipleOrigins
__experimentalIsRenderedInSidebar
title={ __(
'Overlay',
'woo-gutenberg-products-block'
) }
initialOpen={ true }
settings={ [
{
colorValue: attributes.overlayColor,
gradientValue: attributes.overlayGradient,
onColorChange: ( overlayColor ) =>
setAttributes( { overlayColor } ),
onGradientChange: ( overlayGradient ) => {
setGradient( overlayGradient );
setAttributes( {
overlayGradient,
} );
},
label: __(
'Color',
'woo-gutenberg-products-block'
),
},
] }
>
<RangeControl
label={ __(
'Background Opacity',
'Opacity',
'woo-gutenberg-products-block'
) }
value={ attributes.dimRatio }
onChange={ ( ratio ) =>
setAttributes( { dimRatio: ratio } )
onChange={ ( dimRatio ) =>
setAttributes( { dimRatio } )
}
min={ 0 }
max={ 100 }
step={ 10 }
required
/>
{ focalPointPickerExists && (
<FocalPointPicker
label={ __(
'Focal Point Picker',
'woo-gutenberg-products-block'
) }
url={ url }
value={ focalPoint }
onChange={ ( value ) =>
setAttributes( { focalPoint: value } )
}
/>
) }
</PanelBody>
</PanelColorGradientSettings>
</>
) }
</InspectorControls>
Expand Down Expand Up @@ -295,11 +389,16 @@ const FeaturedCategory = ( {

const renderCategory = () => {
const {
height,
contentAlign,
dimRatio,
focalPoint,
imageFit,
mediaSrc,
minHeight,
overlayColor,
overlayGradient,
showDesc,
style,
} = attributes;

const classes = classnames(
Expand All @@ -313,47 +412,73 @@ const FeaturedCategory = ( {
dimRatioToClass( dimRatio ),
contentAlign !== 'center' && `has-${ contentAlign }-content`
);
const mediaSrc = attributes.mediaSrc || getCategoryImageSrc( category );
const style = !! category ? getBackgroundImageStyles( mediaSrc ) : {};
if ( focalPoint ) {
const bgPosX = focalPoint.x * 100;
const bgPosY = focalPoint.y * 100;
style.backgroundPosition = `${ bgPosX }% ${ bgPosY }%`;
}

const onResizeStop = ( event, direction, elt ) => {
setAttributes( { height: parseInt( elt.style.height, 10 ) } );
const containerStyle = {
borderRadius: style?.border?.radius,
};

const backgroundImageSrc = mediaSrc || getCategoryImageSrc( category );

const wrapperStyle = {
...getSpacingClassesAndStyles( attributes ).style,
minHeight,
};

const backgroundImageStyle = {
...calculateBackgroundImagePosition( focalPoint ),
objectFit: imageFit,
};

const overlayStyle = {
background: overlayGradient,
backgroundColor: overlayColor,
};

return (
<ResizableBox
className={ classes }
size={ { height } }
minHeight={ getSetting( 'min_height', 500 ) }
enable={ { bottom: true } }
onResizeStop={ onResizeStop }
style={ style }
>
<div className="wc-block-featured-category__wrapper">
<h2
className="wc-block-featured-category__title"
dangerouslySetInnerHTML={ {
__html: category.name,
} }
/>
{ showDesc && (
<>
<ConstrainedResizable
enable={ { bottom: true } }
onResize={ onResize }
showHandle={ isSelected }
style={ { minHeight } }
/>
<div className={ classes } style={ containerStyle }>
<div
className="wc-block-featured-category__wrapper"
style={ wrapperStyle }
>
<div
className="wc-block-featured-category__description"
className="wc-block-featured-category__overlay"
style={ overlayStyle }
/>
{ backgroundImageSrc && (
<img
alt={ category.description }
className="wc-block-featured-category__background-image"
src={ backgroundImageSrc }
style={ backgroundImageStyle }
/>
) }
<h2
className="wc-block-featured-category__title"
dangerouslySetInnerHTML={ {
__html: category.description,
__html: category.name,
} }
/>
) }
<div className="wc-block-featured-category__link">
{ renderButton() }
{ showDesc && (
<div
className="wc-block-featured-category__description"
dangerouslySetInnerHTML={ {
__html: category.description,
} }
/>
) }
<div className="wc-block-featured-category__link">
{ renderButton() }
</div>
</div>
</div>
</ResizableBox>
</>
);
};

Expand Down
Loading

0 comments on commit e079f26

Please sign in to comment.