-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Use color panel for contentOnly pattern editing #71982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
2b1d23f
a2c05bd
2ddd2f4
b095cbe
02794d2
9c9b8b9
133a9a9
0364031
e864e25
ffa1529
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,7 +4,6 @@ | |
| import { PanelBody } from '@wordpress/components'; | ||
| import { __ } from '@wordpress/i18n'; | ||
| import { useDispatch, useSelect } from '@wordpress/data'; | ||
| import { useState, useEffect } from '@wordpress/element'; | ||
|
|
||
| /** | ||
| * Internal dependencies | ||
|
|
@@ -20,99 +19,34 @@ import { ColorToolsPanel } from '../global-styles/color-panel'; | |
| function SectionBlockControls( { blockName, clientId, contentClientIds } ) { | ||
| const settings = useBlockSettings( blockName ); | ||
| const { updateBlockAttributes } = useDispatch( blockEditorStore ); | ||
| const [ defaultControls, setDefaultControls ] = useState( { | ||
| text: true, | ||
| background: true, | ||
| button: true, | ||
| heading: true, | ||
| caption: true, | ||
| link: true, | ||
| } ); | ||
|
|
||
| const contentBlocks = useSelect( | ||
| const { hasButton, hasHeading } = useSelect( | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice touch. I was initially thinking to just show a defined subset, but it's fancier to detect the block! |
||
| ( select ) => { | ||
| const { getBlock } = select( blockEditorStore ); | ||
|
|
||
| // Get only the content-exposed blocks | ||
| return contentClientIds | ||
| ? contentClientIds | ||
| .map( ( id ) => getBlock( id ) ) | ||
| .filter( Boolean ) | ||
| : []; | ||
| }, | ||
| [ contentClientIds ] | ||
| ); | ||
|
|
||
| useEffect( () => { | ||
| let hasButton = false; | ||
| let hasHeading = false; | ||
| let hasCaption = false; | ||
| let hasLink = false; | ||
|
|
||
| for ( const block of contentBlocks ) { | ||
| // Check for button blocks | ||
| if ( block.name === 'core/button' ) { | ||
| hasButton = true; | ||
| } | ||
| // Check for heading blocks | ||
| if ( block.name === 'core/heading' ) { | ||
| hasHeading = true; | ||
| } | ||
|
|
||
| // Check for actual caption content | ||
| if ( | ||
| block.name === 'core/image' || | ||
| block.name === 'core/video' || | ||
| block.name === 'core/audio' || | ||
| block.name === 'core/gallery' | ||
| ) { | ||
| const caption = block.attributes?.caption; | ||
| // Caption can be a string, array, or rich-text object | ||
| const hasCaptionContent = | ||
| caption && | ||
| ( ( typeof caption === 'string' && | ||
| caption.trim() !== '' ) || | ||
| ( Array.isArray( caption ) && caption.length > 0 ) || | ||
| ( typeof caption === 'object' && | ||
| caption.text && | ||
| caption.text.trim() !== '' ) ); | ||
| if ( hasCaptionContent ) { | ||
| hasCaption = true; | ||
| const { getBlockName } = select( blockEditorStore ); | ||
| let foundButton = false; | ||
| let foundHeading = false; | ||
|
|
||
| for ( const contentClientId of contentClientIds ) { | ||
|
||
| const name = getBlockName( contentClientId ); | ||
| if ( name === 'core/heading' ) { | ||
| foundHeading = true; | ||
| } | ||
| if ( name === 'core/button' ) { | ||
| foundButton = true; | ||
| } | ||
| } | ||
|
|
||
| // Check for actual link content | ||
| let blockHasLink = false; | ||
|
|
||
| if ( block.name === 'core/paragraph' ) { | ||
| // Check if paragraph content contains anchor tags | ||
| blockHasLink = | ||
| block.attributes?.content && | ||
| block.attributes.content.includes( '<a ' ); | ||
| } else if ( block.name === 'core/heading' ) { | ||
| // Check if heading content contains anchor tags | ||
| blockHasLink = | ||
| block.attributes?.content && | ||
| block.attributes.content.includes( '<a ' ); | ||
| } else if ( block.name === 'core/button' ) { | ||
| // Buttons always have links | ||
| blockHasLink = !! block.attributes?.url; | ||
| } | ||
|
|
||
| if ( blockHasLink ) { | ||
| hasLink = true; | ||
| if ( foundHeading && foundButton ) { | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| setDefaultControls( { | ||
| text: true, | ||
| background: true, | ||
| button: hasButton, | ||
| heading: hasHeading, | ||
| caption: hasCaption, | ||
| link: hasLink, | ||
| } ); | ||
| }, [ contentBlocks ] ); | ||
| return { | ||
| hasButton: foundButton, | ||
| hasHeading: foundHeading, | ||
| }; | ||
| }, | ||
| [ contentClientIds ] | ||
| ); | ||
|
|
||
| const setAttributes = ( newAttributes ) => { | ||
| updateBlockAttributes( clientId, newAttributes ); | ||
|
|
@@ -126,7 +60,12 @@ function SectionBlockControls( { blockName, clientId, contentClientIds } ) { | |
| setAttributes={ setAttributes } | ||
| asWrapper={ ColorToolsPanel } | ||
| label={ __( 'Color' ) } | ||
| defaultControls={ defaultControls } | ||
| defaultControls={ { | ||
| text: true, | ||
| background: true, | ||
| button: hasButton, | ||
| heading: hasHeading, | ||
| } } | ||
| /> | ||
| ); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine to abstract these and not fill the hooks with too much section-specific logic. If more styles are required down the track we might revisit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. They were easily accessible one level up, so I thought passing them in would be easier for now.