@@ -13,8 +13,7 @@ import { useEntityProp } from '@wordpress/core-data';
1313import { __ , sprintf } from '@wordpress/i18n' ;
1414import { Button , DropdownMenu , Icon , MenuGroup , MenuItem , Modal , Path , SVG } from '@wordpress/components' ;
1515import { Component , isValidElement } from '@wordpress/element' ;
16- import { compose , ifCondition } from '@wordpress/compose' ;
17- import { register , useSelect , withDispatch , withSelect } from '@wordpress/data' ;
16+ import { register , useSelect , useDispatch } from '@wordpress/data' ;
1817
1918/**
2019 * Internal dependencies
@@ -176,78 +175,89 @@ class LayoutSelector extends Component {
176175 }
177176}
178177
178+ const LayoutSelectorApp = ( ) => {
179+ // Hooks must be called unconditionally and in the same order every render.
180+ const [ layoutSelectorEnabled ] = useEntityProp ( 'root' , 'site' , LAYOUT_SELECTOR_FEATURE_ENABLED_KEY ) ;
181+
182+ const layouts = useComputedLayouts ( ) ;
183+ const categories = useCategories ( layouts ) ;
184+
185+ const {
186+ hasLayouts,
187+ hasCategories,
188+ selectedCategory,
189+ templateSelectorActive,
190+ isMobile,
191+ hasComputedLayouts,
192+ } = useSelect ( ( select ) => {
193+ const ts = select ( 'coblocks/template-selector' ) || { } ;
194+ const vp = select ( 'core/viewport' ) || { } ;
195+ return {
196+ hasLayouts : typeof ts . hasLayouts === 'function' ? ts . hasLayouts ( ) : false ,
197+ hasCategories : typeof ts . hasCategories === 'function' ? ts . hasCategories ( ) : false ,
198+ selectedCategory : typeof ts . getSelectedCategory === 'function' ? ts . getSelectedCategory ( ) : 'most-used' ,
199+ templateSelectorActive : typeof ts . isTemplateSelectorActive === 'function' ? ts . isTemplateSelectorActive ( ) : false ,
200+ isMobile : typeof vp . isViewportMatch === 'function' ? vp . isViewportMatch ( '< medium' ) : false ,
201+ hasComputedLayouts : typeof ts . getComputedLayouts === 'function' ? ( ( ts . getComputedLayouts ( ) || [ ] ) . length > 0 ) : false ,
202+ } ;
203+ } , [ ] ) ;
204+
205+ const tsDispatch = useDispatch ( 'coblocks/template-selector' ) || { } ;
206+ const editorDispatch = useDispatch ( 'core/editor' ) || { } ;
207+ const noticesDispatch = useDispatch ( 'core/notices' ) || { } ;
208+
209+ // Non-hook logic can be conditional.
210+ const labsIsPresent = ! ! document . getElementsByClassName ( 'coblocks-labs-modal' ) ?. [ 0 ] ;
211+ const shouldRender = layoutSelectorEnabled && ! labsIsPresent && hasLayouts && hasCategories && hasComputedLayouts ;
212+
213+ if ( ! shouldRender ) {
214+ return null ;
215+ }
216+
217+ const closeTemplateSelector = typeof tsDispatch . closeTemplateSelector === 'function' ? tsDispatch . closeTemplateSelector : ( ) => { } ;
218+ const incrementLayoutUsage = typeof tsDispatch . incrementLayoutUsage === 'function' ? tsDispatch . incrementLayoutUsage : ( ) => { } ;
219+ const updateSelectedCategory = typeof tsDispatch . updateSelectedCategory === 'function' ? tsDispatch . updateSelectedCategory : ( ) => { } ;
220+ const editPost = typeof editorDispatch . editPost === 'function' ? editorDispatch . editPost : ( ) => { } ;
221+ const createSuccessNotice = typeof noticesDispatch . createSuccessNotice === 'function' ? noticesDispatch . createSuccessNotice : ( ) => { } ;
222+
223+ const useEmptyTemplateLayout = ( ) => {
224+ editPost ( { blocks : [ ] , title : '' } ) ;
225+ closeTemplateSelector ( ) ;
226+ } ;
227+
228+ const useTemplateLayout = ( layout ) => {
229+ editPost ( {
230+ blocks : layout . blocks ,
231+ title : layout . label ,
232+ } ) ;
233+ closeTemplateSelector ( ) ;
234+ incrementLayoutUsage ( layout ) ;
235+ createSuccessNotice (
236+ sprintf (
237+ /* translators: %s: layout name */
238+ __ ( '"%s" layout has been added to the page.' , 'coblocks' ) ,
239+ layout . label
240+ ) ,
241+ { type : 'snackbar' }
242+ ) ;
243+ } ;
244+
245+ return (
246+ < LayoutSelector
247+ categories = { categories }
248+ selectedCategory = { selectedCategory }
249+ updateSelectedCategory = { updateSelectedCategory }
250+ isActive = { templateSelectorActive }
251+ isMobile = { isMobile }
252+ useEmptyTemplateLayout = { useEmptyTemplateLayout }
253+ useTemplateLayout = { useTemplateLayout }
254+ layouts = { layouts }
255+ />
256+ ) ;
257+ } ;
258+
179259if ( typeof coblocksLayoutSelector !== 'undefined' && coblocksLayoutSelector . postTypeEnabled ) {
180260 registerPlugin ( 'coblocks-layout-selector' , {
181- render : compose ( [
182- ifCondition ( ( ) => {
183- const [ layoutSelectorEnabled ] = useEntityProp ( 'root' , 'site' , LAYOUT_SELECTOR_FEATURE_ENABLED_KEY ) ;
184- // Prevent render if labs modal is open.
185- const labsIsPresent = ! ! document . getElementsByClassName ( 'coblocks-labs-modal' ) ?. [ 0 ] ;
186- const {
187- hasLayouts,
188- hasCategories,
189- } = useSelect ( ( select ) => select ( 'coblocks/template-selector' ) ) ;
190-
191- return layoutSelectorEnabled && ! labsIsPresent && hasLayouts ( ) && hasCategories ( ) ;
192- } ) ,
193- withSelect ( ( select ) => {
194- const {
195- getSelectedCategory,
196- isTemplateSelectorActive,
197- } = select ( 'coblocks/template-selector' ) ;
198-
199- const { isViewportMatch } = select ( 'core/viewport' ) ;
200-
201- const layouts = useComputedLayouts ( ) ;
202-
203- return {
204- categories : useCategories ( layouts ) ,
205- isActive : isTemplateSelectorActive ( ) ,
206- isMobile : isViewportMatch ( '< medium' ) ,
207- layouts,
208- selectedCategory : getSelectedCategory ( ) ,
209- } ;
210- } ) ,
211- withDispatch ( ( dispatch ) => {
212- const {
213- closeTemplateSelector,
214- incrementLayoutUsage,
215- updateSelectedCategory,
216- } = dispatch ( 'coblocks/template-selector' ) ;
217- const { editPost } = dispatch ( 'core/editor' ) ;
218- const { createWarningNotice, createSuccessNotice } = dispatch ( 'core/notices' ) ;
219-
220- return {
221- closeTemplateSelector,
222- createSuccessNotice,
223- createWarningNotice,
224- editPost,
225- updateSelectedCategory,
226-
227- useEmptyTemplateLayout : ( ) => {
228- editPost ( { blocks : [ ] , title : '' } ) ;
229- closeTemplateSelector ( ) ;
230- } ,
231-
232- // Replace any blocks with the selected layout.
233- useTemplateLayout : ( layout ) => {
234- editPost ( {
235- blocks : layout . blocks ,
236- title : layout . label ,
237- } ) ;
238- closeTemplateSelector ( ) ;
239- incrementLayoutUsage ( layout ) ;
240- createSuccessNotice (
241- sprintf (
242- // translators: %s is the post title.
243- __ ( '"%s" layout has been added to the page.' , 'coblocks' ) ,
244- layout . label
245- ) ,
246- { type : 'snackbar' }
247- ) ;
248- } ,
249- } ;
250- } ) ,
251- ] ) ( LayoutSelector ) ,
261+ render : LayoutSelectorApp ,
252262 } ) ;
253263}
0 commit comments