File "edit.js"
Full Path: /home/rattkxnv/byattorney.com/wp-content/plugins/generateblocks/src/blocks/text/edit.js
File size: 6.51 KB
MIME-type: text/x-java
Charset: utf-8
import { __ } from '@wordpress/i18n';
import { RichText, useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { Platform, useEffect, useMemo } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { BlockStyles, withUniqueId } from '@edge22/block-styles';
import { withDynamicTag } from '../../hoc/withDynamicTag';
import { Icon } from './components/Icon.jsx';
import RootElement from '../../components/root-element/index.js';
import { BlockSettings } from './components/BlockSettings';
import { selectorShortcuts } from '@utils/selectorShortcuts';
import { withStyles } from '@hoc/withStyles';
import { BlockStylesBuilder } from '@components/block-styles-builder/BlockStylesBuilder';
import { AlignmentToolbar, LinkBlockToolbar, StylesOnboarder, TagNameToolbar } from '@components/index';
import { withHtmlAttributes } from '@hoc/withHtmlAttributes';
import { getBlockClasses } from '@utils/getBlockClasses';
import { DynamicTagBlockToolbar } from '../../dynamic-tags';
function EditBlock( props ) {
const {
attributes,
setAttributes,
mergeBlocks,
onReplace,
dynamicTagValue,
setContentMode,
contentMode,
name,
clientId,
onStyleChange,
getStyleValue,
editorHtmlAttributes,
isSelected,
styles,
context,
} = props;
const {
tagName,
content,
icon,
iconLocation,
iconOnly,
htmlAttributes,
} = attributes;
useEffect( () => {
if ( ! tagName ) {
setAttributes( { tagName: 'p' } );
}
}, [ tagName ] );
const contentValue = useMemo( () => {
if ( ! dynamicTagValue ) {
return content;
}
return dynamicTagValue.reduce( ( acc, { original, replacement, fallback } ) => {
if ( ! replacement ) {
return acc.replaceAll( original, fallback );
}
const replacementWithNoLinks = replacement.replace( /href="[^"]*"/g, 'href="#"' );
return acc.replaceAll( original, replacementWithNoLinks );
}, content );
}, [ dynamicTagValue, content ] );
const classNames = getBlockClasses(
'gb-text',
{
...attributes,
styles,
},
! icon
);
const blockProps = useBlockProps(
{
className: classNames.join( ' ' ).trim(),
...editorHtmlAttributes,
}
);
const TagNameWithIcon = tagName || 'p';
const richTextProps = {
identifier: 'content',
value: contentValue,
onChange: ( value ) => setAttributes( { content: value } ),
onMerge: mergeBlocks,
onReplace,
onRemove: () => onReplace( [] ),
placeholder: __( 'Text', 'generateblocks' ),
withoutInteractiveFormatting: 'a' === tagName || 'button' === tagName,
...( Platform.isNative && { deleteEnter: true } ), // setup RichText on native mobile to delete the "Enter" key as it's handled by the JS/RN side
};
const shortcuts = useMemo( () => {
const visibleSelectors = [
{
label: __( 'Main', 'generateblocks' ),
value: '',
},
];
if ( 'a' === tagName || 'button' === tagName ) {
visibleSelectors.push(
{
label: __( 'Hover', 'generateblocks' ),
value: '&:is(:hover, :focus)',
}
);
delete selectorShortcuts.links;
}
if ( icon ) {
visibleSelectors.push(
{
label: __( 'Icon', 'generateblocks' ),
value: '.gb-shape svg',
},
);
selectorShortcuts.default.items.push(
{ label: __( 'Icon', 'generateblocks' ), value: '.gb-shape svg' },
{ label: __( 'Hovered icon', 'generateblocks' ), value: '&:is(:hover, :focus) .gb-shape svg' },
);
selectorShortcuts.icons = {
label: __( 'Icon', 'generateblocks' ),
items: [
{ label: __( 'Icon', 'generateblocks' ), value: '.gb-shape svg' },
{ label: __( 'Hovered icon', 'generateblocks' ), value: '&:is(:hover, :focus) .gb-shape svg' },
],
};
}
return {
selectorShortcuts,
visibleShortcuts: visibleSelectors,
};
}, [ tagName, icon ] );
const renderContent = ( elementTagName, withBlockProps = false ) => {
if ( 'preview' === contentMode && dynamicTagValue ) {
const ElementTagName = elementTagName;
// Render a plain HTML tag in preview mode
return (
<ElementTagName
{ ...( withBlockProps && blockProps ) }
dangerouslySetInnerHTML={ { __html: contentValue } }
/>
);
}
// The RichText component can't handle the `<button>` tag for some reason.
// It doesn't allow spaces to be entered, and doesn't allow the user to type if there
// isn't already a value entered. To handle this, we'll render a `<button>` tag instead
// and use a `span` as the RichText component tag.
if ( 'button' === elementTagName ) {
return (
<button
{ ...( withBlockProps && blockProps ) }
>
<RichText
{ ...richTextProps }
tagName={ 'span' }
/>
</button>
);
}
return (
<RichText
{ ...richTextProps }
{ ...( withBlockProps && blockProps ) }
tagName={ elementTagName }
/>
);
};
return (
<>
<TagNameToolbar
label={ __( 'Choose tag name', 'generateblocks' ) }
tagName={ tagName }
onChange={ ( value ) => setAttributes( { tagName: value } ) }
/>
<LinkBlockToolbar
setAttributes={ setAttributes }
htmlAttributes={ htmlAttributes }
tagName={ tagName }
context={ context }
/>
<AlignmentToolbar
withTextAlign
getStyleValue={ getStyleValue }
onStyleChange={ onStyleChange }
setAttributes={ setAttributes }
clientId={ clientId }
/>
{ ! iconOnly && (
<DynamicTagBlockToolbar
value={ content }
tagName={ tagName }
setContentMode={ setContentMode }
contentMode={ contentMode }
isSelected={ isSelected }
onChange={ ( newValue ) => setAttributes( { content: newValue } ) }
context={ context }
/>
) }
<InspectorControls>
<StylesOnboarder />
<BlockStyles
settingsTab={ (
<BlockSettings
{ ...props }
/>
) }
stylesTab={ (
<BlockStylesBuilder
attributes={ attributes }
setAttributes={ setAttributes }
shortcuts={ shortcuts }
onStyleChange={ onStyleChange }
name={ name }
/>
) }
/>
</InspectorControls>
<RootElement
name={ name }
clientId={ clientId }
>
<>
{ !! icon && (
<TagNameWithIcon { ...blockProps }>
{ 'before' === iconLocation && ( <Icon icon={ icon } /> ) }
{ ! iconOnly && (
renderContent( 'span' )
) }
{ 'after' === iconLocation && ( <Icon icon={ icon } /> ) }
</TagNameWithIcon>
) }
{ ! icon && (
renderContent( tagName || 'span', true )
) }
</>
</RootElement>
</>
);
}
const Edit = compose(
withHtmlAttributes,
withStyles,
withDynamicTag,
withUniqueId
)( EditBlock );
export { Edit };