diff --git a/assets/src/blocks/Counter/CounterBlock.js b/assets/src/blocks/Counter/CounterBlock.js index d08062f07..d160285c2 100644 --- a/assets/src/blocks/Counter/CounterBlock.js +++ b/assets/src/blocks/Counter/CounterBlock.js @@ -1,97 +1,106 @@ import {CounterEditor} from './CounterEditor'; import {frontendRendered} from '../frontendRendered'; +import {CounterFrontend} from './CounterFrontend'; +import {renderToString} from 'react-dom/server'; -const BLOCK_NAME = 'planet4-blocks/counter'; +export const BLOCK_NAME = 'planet4-blocks/counter'; -export class CounterBlock { - constructor() { - const {registerBlockType, unregisterBlockStyle, registerBlockStyle} = wp.blocks; - const {__} = wp.i18n; - const attributes = { - title: { - type: 'string', - default: '', - }, - description: { - type: 'string', - default: '', - }, - completed: { - type: 'integer', - default: '', - }, - completed_api: { - type: 'string', - default: '', - }, - target: { - type: 'integer', - default: '', - }, - text: { - type: 'string', - default: '', - }, - style: { // Needed to convert existing blocks - type: 'string', - default: '', - }, - }; - - registerBlockType(BLOCK_NAME, { - title: __('Counter', 'planet4-blocks-backend'), - icon: 'dashboard', - category: 'planet4-blocks', - attributes, - supports: { - html: false, // Disable "Edit as HTMl" block option. - }, - deprecated: [ - { - attributes, - save() { - return null; - }, - }, - ], - // eslint-disable-next-line no-shadow - edit: ({isSelected, attributes, setAttributes}) => { - return ; - }, - save: frontendRendered(BLOCK_NAME), - }); +const attributes = { + title: { + type: 'string', + default: '', + }, + description: { + type: 'string', + default: '', + }, + completed: { + type: 'integer', + default: '', + }, + completed_api: { + type: 'string', + default: '', + }, + target: { + type: 'integer', + default: '', + }, + text: { + type: 'string', + default: '', + }, + style: { // Needed to convert existing blocks + type: 'string', + default: '', + }, +}; - // Remove the default style since it's the same as "text only" - unregisterBlockStyle(BLOCK_NAME, 'default'); +export const registerCounterBlock = () => { + const {registerBlockType, unregisterBlockStyle, registerBlockStyle} = wp.blocks; + const {RawHTML} = wp.element; - const styles = [ - { - name: 'plain', - label: 'Text Only', - isDefault: true, - }, + registerBlockType(BLOCK_NAME, { + title: 'Counter', + icon: 'dashboard', + category: 'planet4-blocks', + attributes, + supports: { + html: false, // Disable "Edit as HTMl" block option. + }, + // eslint-disable-next-line no-shadow + edit: CounterEditor, + save: props => { + const markup = renderToString( +
+ +
+ ); + return {markup}; + }, + deprecated: [ { - name: 'bar', - label: 'Progress Bar', + attributes, + save: frontendRendered(BLOCK_NAME), }, { - name: 'arc', - label: 'Progress Dial', + attributes, + save() { + return null; + }, }, + ], + }); + + // Remove the default style since it's the same as "text only" + unregisterBlockStyle(BLOCK_NAME, 'default'); - ]; + const styles = [ + { + name: 'plain', + label: 'Text Only', + isDefault: true, + }, + { + name: 'bar', + label: 'Progress Bar', + }, + { + name: 'arc', + label: 'Progress Dial', + }, - if (window.p4ge_vars.features.feature_engaging_networks) { - styles.push({ - name: 'en-forms-bar', - label: 'Progress Bar inside EN Form', - }); - } - // Add our custom styles - registerBlockStyle(BLOCK_NAME, styles); + ]; + + if (window.p4ge_vars.features.feature_engaging_networks) { + styles.push({ + name: 'en-forms-bar', + label: 'Progress Bar inside EN Form', + }); } -} + // Add our custom styles + registerBlockStyle(BLOCK_NAME, styles); +}; diff --git a/assets/src/blocks/Counter/CounterEditor.js b/assets/src/blocks/Counter/CounterEditor.js index 6105d1867..634c7eac1 100644 --- a/assets/src/blocks/Counter/CounterEditor.js +++ b/assets/src/blocks/Counter/CounterEditor.js @@ -1,90 +1,71 @@ -import {Component, Fragment} from '@wordpress/element'; import {InspectorControls, RichText} from '@wordpress/block-editor'; import { TextControl, TextareaControl, PanelBody, } from '@wordpress/components'; - import {URLInput} from '../../components/URLInput/URLInput'; - import {CounterFrontend} from './CounterFrontend'; const {__} = wp.i18n; -export class CounterEditor extends Component { - constructor(props) { - super(props); - - this.toAttribute = this.toAttribute.bind(this); - } - - toAttribute(attributeName) { - const {setAttributes} = this.props; - return value => { - setAttributes({[attributeName]: value}); - }; - } - - renderEdit() { - const {attributes} = this.props; +export const CounterEditor = ({setAttributes, attributes, isSelected}) => { - return ( - - - -
- this.toAttribute('completed')(Number(value))} - min={0} - /> -
+ const toAttribute = attributeName => value => setAttributes({[attributeName]: value}); -
- -
+ const renderEdit = () => ( + <> + + +
+ toAttribute('completed')(Number(value))} + min={0} + /> +
-
- this.toAttribute('target')(Number(value))} - min={0} - /> -
+
+ +
-
- -
-
- {__('These placeholders can be used:', 'planet4-blocks-backend')}{' '}%completed%, %target%, %remaining% -
-
-
-
- ); - } +
+ toAttribute('target')(Number(value))} + min={0} + /> +
- renderView() { - const {attributes} = this.props; +
+ +
+
+ {__('These placeholders can be used:', 'planet4-blocks-backend')}{' '}%completed%, %target%, %remaining% +
+ + + + ); - return + const renderView = () => ( + <>
-
; - } + + ); - render() { - return ( - - { - this.props.isSelected ? - this.renderEdit() : - null - } - {this.renderView()} - - ); - } -} + return ( + <> + {isSelected ? renderEdit() : null} + {renderView()} + + ); +}; diff --git a/assets/src/blocks/Counter/CounterEditorScript.js b/assets/src/blocks/Counter/CounterEditorScript.js new file mode 100644 index 000000000..7e4b94796 --- /dev/null +++ b/assets/src/blocks/Counter/CounterEditorScript.js @@ -0,0 +1,3 @@ +import {registerCounterBlock} from './CounterBlock'; + +registerCounterBlock(); diff --git a/assets/src/blocks/Counter/CounterFrontend.js b/assets/src/blocks/Counter/CounterFrontend.js index 25f827976..959161be5 100644 --- a/assets/src/blocks/Counter/CounterFrontend.js +++ b/assets/src/blocks/Counter/CounterFrontend.js @@ -1,4 +1,4 @@ -import {Component, Fragment} from '@wordpress/element'; +import {Component} from '@wordpress/element'; import {getStyleFromClassName} from '../getStyleFromClassName'; export class CounterFrontend extends Component { @@ -118,40 +118,38 @@ export class CounterFrontend extends Component { } return ( - -
- {title && !isEditing && -
-

{title}

-
+
+ {title && !isEditing && +
+

{title}

+
+ } + {description && !isEditing && +

+ } +

+ {(style === 'bar' || style === 'en-forms-bar') && +
+
+
} - {description && !isEditing && -

+ {style === 'arc' && + + + + } -

- {(style === 'bar' || style === 'en-forms-bar') && -
-
-
- } - {style === 'arc' && - - - - - } - {text && -
- } -
-
- + {text && +
+ } +
+
); } } diff --git a/assets/src/blocks/Counter/CounterScript.js b/assets/src/blocks/Counter/CounterScript.js new file mode 100644 index 000000000..41d8da66d --- /dev/null +++ b/assets/src/blocks/Counter/CounterScript.js @@ -0,0 +1,15 @@ +import {CounterFrontend} from './CounterFrontend'; +import {hydrateBlock} from '../../functions/hydrateBlock'; +import {BLOCK_NAME} from './CounterBlock'; +import {createRoot} from 'react-dom/client'; + +hydrateBlock(BLOCK_NAME, CounterFrontend); + +// Fallback for non migrated content. Remove after migration. +document.querySelectorAll(`[data-render="${BLOCK_NAME}"]`).forEach( + blockNode => { + const attributes = JSON.parse(blockNode.dataset.attributes); + const rootElement = createRoot(blockNode); + rootElement.render(); + } +); diff --git a/assets/src/editorIndex.js b/assets/src/editorIndex.js index 42d81f95a..17cb79b02 100644 --- a/assets/src/editorIndex.js +++ b/assets/src/editorIndex.js @@ -1,7 +1,6 @@ import {ArticlesBlock} from './blocks/Articles/ArticlesBlock'; import {registerColumnsBlock} from './blocks/Columns/ColumnsBlock'; import {CookiesBlock} from './blocks/Cookies/CookiesBlock'; -import {CounterBlock} from './blocks/Counter/CounterBlock'; import {HappypointBlock} from './blocks/Happypoint/HappypointBlock'; import {registerMediaBlock} from './blocks/Media/MediaBlock'; import {registerSocialMediaBlock} from './blocks/SocialMedia/SocialMediaBlock'; @@ -27,7 +26,6 @@ blockEditorValidation(); new ArticlesBlock(); registerColumnsBlock(); new CookiesBlock(); -new CounterBlock(); new HappypointBlock(); registerMediaBlock(); registerSocialMediaBlock(); diff --git a/assets/src/frontendIndex.js b/assets/src/frontendIndex.js index 33bf1be31..8d723d52b 100644 --- a/assets/src/frontendIndex.js +++ b/assets/src/frontendIndex.js @@ -1,4 +1,3 @@ -import {CounterFrontend} from './blocks/Counter/CounterFrontend'; import {ArticlesFrontend} from './blocks/Articles/ArticlesFrontend'; import {CookiesFrontend} from './blocks/Cookies/CookiesFrontend'; import {SplittwocolumnsFrontend} from './blocks/Splittwocolumns/SplittwocolumnsFrontend'; @@ -15,7 +14,6 @@ import {createRoot} from 'react-dom/client'; // Render React components const COMPONENTS = { - 'planet4-blocks/counter': CounterFrontend, 'planet4-blocks/articles': ArticlesFrontend, 'planet4-blocks/cookies': CookiesFrontend, 'planet4-blocks/split-two-columns': SplittwocolumnsFrontend, diff --git a/assets/src/styles/blocks.scss b/assets/src/styles/blocks.scss index 034e23ea9..fc6815419 100644 --- a/assets/src/styles/blocks.scss +++ b/assets/src/styles/blocks.scss @@ -1,7 +1,6 @@ // P4 Blocks @import "blocks/Articles"; @import "blocks/Columns"; -@import "blocks/Counter"; @import "blocks/File"; @import "blocks/Happypoint"; @import "blocks/Media"; diff --git a/assets/src/styles/blocks/Counter.scss b/assets/src/styles/blocks/Counter/CounterStyle.scss similarity index 93% rename from assets/src/styles/blocks/Counter.scss rename to assets/src/styles/blocks/Counter/CounterStyle.scss index d70062fec..65683ed60 100644 --- a/assets/src/styles/blocks/Counter.scss +++ b/assets/src/styles/blocks/Counter/CounterStyle.scss @@ -1,3 +1,6 @@ +@import "../../master-theme/assets/src/scss/base/colors"; +@import "../../master-theme/assets/src/scss/base/variables"; + .counter-block { _-- { font-family: var(--headings--font-family); diff --git a/classes/blocks/class-counter.php b/classes/blocks/class-counter.php index 1e06b1722..0524c2ab9 100644 --- a/classes/blocks/class-counter.php +++ b/classes/blocks/class-counter.php @@ -61,6 +61,9 @@ public function __construct() { ], ] ); + + add_action( 'enqueue_block_editor_assets', [ self::class, 'enqueue_editor_assets' ] ); + add_action( 'wp_enqueue_scripts', [ self::class, 'enqueue_frontend_assets' ] ); } /** diff --git a/webpack.config.js b/webpack.config.js index 7c6f1a896..b0a20abfa 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -45,6 +45,7 @@ const publicJsConfig = { TimelineScript: './assets/src/blocks/Timeline/TimelineScript.js', GalleryScript: './assets/src/blocks/Gallery/GalleryScript.js', GuestBookScript: './assets/src/blocks/GuestBook/GuestBookScript.js', + CounterScript: './assets/src/blocks/Counter/CounterScript.js', }, }; const adminJsConfig = { @@ -67,6 +68,7 @@ const adminJsConfig = { SocialMediaEditorScript: './assets/src/blocks/SocialMedia/SocialMediaEditorScript.js', GalleryEditorScript: './assets/src/blocks/Gallery/GalleryEditorScript.js', GuestBookEditorScript: './assets/src/blocks/GuestBook/GuestBookEditorScript.js', + CounterEditorScript: './assets/src/blocks/Counter/CounterEditorScript.js', }, }; const cssConfig = { @@ -90,6 +92,7 @@ const cssConfig = { CoversEditorStyle: './assets/src/styles/blocks/Covers/CoversEditorStyle.scss', GalleryStyle: './assets/src/styles/blocks/Gallery/GalleryStyle.scss', GalleryEditorStyle: './assets/src/styles/blocks/Gallery/GalleryEditorStyle.scss', + CounterStyle: './assets/src/styles/blocks/Counter/CounterStyle.scss', }, output: { filename: '[name].js',