From f0dc07c5f7798fc27f498fa47c0ac3c0ba7803b6 Mon Sep 17 00:00:00 2001 From: Jorge Costa Date: Mon, 28 Oct 2019 09:44:55 +0000 Subject: [PATCH] Add class mechanism for preset gradients. (#18008) --- .../src/components/block-edit/context.js | 6 ++ .../src/components/gradients/index.js | 77 +++++++++++++++++++ packages/block-editor/src/components/index.js | 1 + packages/block-editor/src/store/defaults.js | 18 +++++ packages/block-library/src/button/block.json | 3 + packages/block-library/src/button/edit.js | 25 +++--- packages/block-library/src/button/save.js | 8 +- packages/block-library/src/style.scss | 76 ++++++++++++++++++ 8 files changed, 201 insertions(+), 13 deletions(-) create mode 100644 packages/block-editor/src/components/gradients/index.js diff --git a/packages/block-editor/src/components/block-edit/context.js b/packages/block-editor/src/components/block-edit/context.js index 4157735cd2fa70..08f2ac9f1dd6b1 100644 --- a/packages/block-editor/src/components/block-edit/context.js +++ b/packages/block-editor/src/components/block-edit/context.js @@ -19,6 +19,12 @@ const Context = createContext( { const { Provider, Consumer } = Context; export { Provider as BlockEditContextProvider }; + +/** + * A hook that returns the block edit context. + * + * @return {Object} Block edit context + */ export function useBlockEditContext() { return useContext( Context ); } diff --git a/packages/block-editor/src/components/gradients/index.js b/packages/block-editor/src/components/gradients/index.js new file mode 100644 index 00000000000000..b08be314861e03 --- /dev/null +++ b/packages/block-editor/src/components/gradients/index.js @@ -0,0 +1,77 @@ +/** + * External dependencies + */ +import { find } from 'lodash'; + +/** + * WordPress dependencies + */ +import { useCallback } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { useBlockEditContext } from '../block-edit'; + +export function __experimentalGetGradientClass( gradientSlug ) { + if ( ! gradientSlug ) { + return undefined; + } + return `has-${ gradientSlug }-gradient-background`; +} + +function getGradientValueBySlug( gradients, slug ) { + const gradient = find( gradients, [ 'slug', slug ] ); + return gradient && gradient.gradient; +} + +function getGradientSlugByValue( gradients, value ) { + const gradient = find( gradients, [ 'gradient', value ] ); + return gradient && gradient.slug; +} + +export function __experimentalUseGradient( { + gradientAttribute = 'gradient', + customGradientAttribute = 'customGradient', +} = {} ) { + const { clientId } = useBlockEditContext(); + + const { gradients, gradient, customGradient } = useSelect( ( select ) => { + const { getBlockAttributes, getSettings } = select( 'core/block-editor' ); + const attributes = getBlockAttributes( clientId ); + return { + gradient: attributes[ gradientAttribute ], + customGradient: attributes[ customGradientAttribute ], + gradients: getSettings().gradients, + }; + }, [ clientId ] ); + + const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); + const setGradient = useCallback( + ( newGradientValue ) => { + const slug = getGradientSlugByValue( gradients, newGradientValue ); + if ( slug ) { + updateBlockAttributes( clientId, { + [ gradientAttribute ]: slug, + [ customGradientAttribute ]: undefined, + } ); + return; + } + updateBlockAttributes( clientId, { + [ gradientAttribute ]: undefined, + [ customGradientAttribute ]: newGradientValue, + } ); + }, + [ gradients, clientId, updateBlockAttributes ] + ); + + const gradientClass = __experimentalGetGradientClass( gradient ); + let gradientValue; + if ( gradient ) { + gradientValue = getGradientValueBySlug( gradients, gradient ); + } else { + gradientValue = customGradient; + } + return { gradientClass, gradientValue, setGradient }; +} diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index 5818e37395c8ea..7ec60098a8c737 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -3,6 +3,7 @@ */ export * from './colors'; +export * from './gradients'; export * from './font-sizes'; export { default as AlignmentToolbar } from './alignment-toolbar'; export { default as Autocomplete } from './autocomplete'; diff --git a/packages/block-editor/src/store/defaults.js b/packages/block-editor/src/store/defaults.js index a983abacc36b8a..54233e3bda2e91 100644 --- a/packages/block-editor/src/store/defaults.js +++ b/packages/block-editor/src/store/defaults.js @@ -158,75 +158,93 @@ export const SETTINGS_DEFAULTS = { { name: __( 'Vivid cyan blue to vivid purple' ), gradient: 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)', + slug: 'vivid-cyan-blue-to-vivid-purple', }, { name: __( 'Vivid green cyan to vivid cyan blue' ), gradient: 'linear-gradient(135deg,rgba(0,208,132,1) 0%,rgba(6,147,227,1) 100%)', + slug: 'vivid-green-cyan-to-vivid-cyan-blue', }, { name: __( 'Light green cyan to vivid green cyan' ), gradient: 'linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%)', + slug: 'light-green-cyan-to-vivid-green-cyan', }, { name: __( 'Luminous vivid amber to luminous vivid orange' ), gradient: 'linear-gradient(135deg,rgba(252,185,0,1) 0%,rgba(255,105,0,1) 100%)', + slug: 'luminous-vivid-amber-to-luminous-vivid-orange', }, { name: __( 'Luminous vivid orange to vivid red' ), gradient: 'linear-gradient(135deg,rgba(255,105,0,1) 0%,rgb(207,46,46) 100%)', + slug: 'luminous-vivid-orange-to-vivid-red', }, { name: __( 'Very light gray to cyan bluish gray' ), gradient: 'linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%)', + slug: 'very-light-gray-to-cyan-bluish-gray', }, // The following use new, customized colors. { name: __( 'Cool to warm spectrum' ), gradient: 'linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%)', + slug: 'cool-to-warm-spectrum', }, { name: __( 'Blush light purple' ), gradient: 'linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%)', + slug: 'blush-light-purple', }, { name: __( 'Blush bordeaux' ), gradient: 'linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%)', + slug: 'blush-bordeaux', }, { name: __( 'Purple crush' ), gradient: 'linear-gradient(135deg,rgb(52,226,228) 0%,rgb(71,33,251) 50%,rgb(171,29,254) 100%)', + slug: 'purple-crush', }, { name: __( 'Luminous dusk' ), gradient: 'linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%)', + slug: 'luminous-dusk', }, { name: __( 'Hazy dawn' ), gradient: 'linear-gradient(135deg,rgb(250,172,168) 0%,rgb(218,208,236) 100%)', + slug: 'hazy-dawn', }, { name: __( 'Pale ocean' ), gradient: 'linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%)', + slug: 'pale-ocean', }, { name: __( 'Electric grass' ), gradient: 'linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%)', + slug: 'electric-grass', }, { name: __( 'Subdued olive' ), gradient: 'linear-gradient(135deg,rgb(250,250,225) 0%,rgb(103,166,113) 100%)', + slug: 'subdued-olive', }, { name: __( 'Atomic cream' ), gradient: 'linear-gradient(135deg,rgb(253,215,154) 0%,rgb(0,74,89) 100%)', + slug: 'atomic-cream', }, { name: __( 'Nightshade' ), gradient: 'linear-gradient(135deg,rgb(51,9,104) 0%,rgb(49,205,207) 100%)', + slug: 'nightshade', }, { name: __( 'Midnight' ), gradient: 'linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%)', + slug: 'midnight', }, ], }; diff --git a/packages/block-library/src/button/block.json b/packages/block-library/src/button/block.json index ff43c67db5e834..bc35b9ff5ee32e 100644 --- a/packages/block-library/src/button/block.json +++ b/packages/block-library/src/button/block.json @@ -49,6 +49,9 @@ "borderRadius": { "type": "number" }, + "gradient": { + "type": "string" + }, "customGradient": { "type": "string" } diff --git a/packages/block-library/src/button/edit.js b/packages/block-library/src/button/edit.js index b624aa7e5f6218..11d1deef862cfd 100644 --- a/packages/block-library/src/button/edit.js +++ b/packages/block-library/src/button/edit.js @@ -24,6 +24,7 @@ import { } from '@wordpress/components'; import { __experimentalGradientPickerPanel, + __experimentalUseGradient, ContrastChecker, InspectorControls, PanelColorSettings, @@ -94,7 +95,6 @@ function ButtonEdit( { text, title, url, - customGradient, } = attributes; const onSetLinkRel = useCallback( ( value ) => { @@ -121,6 +121,11 @@ function ButtonEdit( { }, [ rel, setAttributes ] ); + const { + gradientClass, + gradientValue, + setGradient, + } = __experimentalUseGradient(); const linkId = `wp-block-button__inline-link-${ instanceId }`; return ( @@ -132,16 +137,17 @@ function ButtonEdit( { withoutInteractiveFormatting className={ classnames( 'wp-block-button__link', { - 'has-background': backgroundColor.color || customGradient, - [ backgroundColor.class ]: ! customGradient && backgroundColor.class, + 'has-background': backgroundColor.color || gradientValue, + [ backgroundColor.class ]: ! gradientValue && backgroundColor.class, 'has-text-color': textColor.color, [ textColor.class ]: textColor.class, + [ gradientClass ]: gradientClass, 'no-border-radius': borderRadius === 0, } ) } style={ { - ...( customGradient ? - { background: customGradient } : + ...( ! backgroundColor.color && gradientValue ? + { background: gradientValue } : { backgroundColor: backgroundColor.color } ), color: textColor.color, @@ -200,14 +206,11 @@ function ButtonEdit( { <__experimentalGradientPickerPanel onChange={ ( newGradient ) => { - setAttributes( { - customGradient: newGradient, - backgroundColor: undefined, - customBackgroundColor: undefined, - } ); + setGradient( newGradient ); + setBackgroundColor(); } } - value={ customGradient } + value={ gradientValue } />