Skip to content

Instantly share code, notes, and snippets.

@Mamaduka
Last active May 17, 2023 12:05
Show Gist options
  • Save Mamaduka/af7c342b13ef714d3c6cd3399ffa15af to your computer and use it in GitHub Desktop.
Save Mamaduka/af7c342b13ef714d3c6cd3399ffa15af to your computer and use it in GitHub Desktop.
registerBlockSupport( 'core/align', {
isSupported( blockType ) {
return hasBlockSupport( blockType, 'align' );
},
blockSettings( settings ) {
// Allow blocks to specify their own attribute definition with default values if needed.
if ( 'type' in ( settings.attributes?.align ?? {} ) ) {
return settings;
}
// Gracefully handle if settings.attributes is undefined.
settings.attributes = {
...settings.attributes,
align: {
type: 'string',
// Allow for '' since it is used by updateAlignment function
// in withToolbarControls for special cases with defined default values.
enum: [ ...ALL_ALIGNMENTS, '' ],
},
};
return settings;
},
Edit( { clientId, name: blockName, setAttributes, attributes } ) {
// Compute the block valid alignments by taking into account,
// if the theme supports wide alignments or not and the layout's
// availble alignments. We do that for conditionally rendering
// Slot.
const blockAllowedAlignments = getValidAlignments(
getBlockSupport( blockName, 'align' ),
hasBlockSupport( blockName, 'alignWide', true )
);
const validAlignments = useAvailableAlignments(
blockAllowedAlignments
).map( ( { name } ) => name );
const isContentLocked = useSelect(
( select ) => {
return select(
blockEditorStore
).__unstableGetContentLockingParent( clientId );
},
[ clientId ]
);
if ( ! validAlignments.length || isContentLocked ) {
return null;
}
const updateAlignment = ( nextAlign ) => {
if ( ! nextAlign ) {
const blockType = getBlockType( blockName );
const blockDefaultAlign = blockType?.attributes?.align?.default;
if ( blockDefaultAlign ) {
nextAlign = '';
}
}
setAttributes( { align: nextAlign } );
};
return (
<BlockControls group="block" __experimentalShareWithChildBlocks>
<BlockAlignmentControl
value={ attributes.align }
onChange={ updateAlignment }
controls={ validAlignments }
/>
</BlockControls>
);
},
getBlockProps( { attributes, blockType } ) {
const { align } = attributes;
// If an alignment is not assigned, there's no need to go through the
// effort to validate or assign its value.
if ( align === undefined ) {
return {};
}
const blockAllowedAlignments = getValidAlignments(
getBlockSupport( blockType, 'align' ),
hasBlockSupport( blockType, 'alignWide', true )
);
const validAlignments = getValidAlignments( blockAllowedAlignments );
if (
validAlignments.some( ( alignment ) => alignment.name === align )
) {
return { 'data-align': align };
}
},
getSaveProps( { attributes, blockType } ) {
const { align } = attributes;
const blockAlign = getBlockSupport( blockType, 'align' );
const hasWideBlockSupport = hasBlockSupport(
blockType,
'alignWide',
true
);
// Compute valid alignments without taking into account if
// the theme supports wide alignments or not.
// This way changing themes does not impact the block save.
const isAlignValid = getValidAlignments(
blockAlign,
hasWideBlockSupport
).includes( align );
if ( ! isAlignValid ) {
return {};
}
return {
className: `align${ align }`,
};
},
} );
registerBlockSupport( 'core/classname', {
isSupported( blockType ) {
return hasBlockSupport( blockType, 'className', true );
},
getSaveProps( { saveProps, blockType } ) {
// There is no string in the className variable,
// so we just dump the default name in there.
if ( typeof saveProps.className !== 'string' ) {
return {
className: getBlockDefaultClassName( blockType.name ),
};
}
// We have some extra classes and want to add the default classname
// We use uniq to prevent duplicate classnames.
const className = [
...new Set( [
getBlockDefaultClassName( blockType.name ),
...saveProps.className.split( ' ' ),
] ),
]
.join( ' ' )
.trim();
return {
className,
};
},
} );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment