|
3 | 3 | */ |
4 | 4 | import { useSelect } from '@wordpress/data' |
5 | 5 | import { useEffect, useState } from '@wordpress/element' |
| 6 | +import { useBlockEditContext } from '@wordpress/block-editor' |
6 | 7 |
|
7 | 8 | /** |
8 | 9 | * External dependencies |
9 | 10 | */ |
10 | 11 | import { compact } from 'lodash' |
| 12 | +import { useBlockHoverState } from '~stackable/hooks' |
11 | 13 | /* |
12 | 14 | :root { --stk-container-border-radius: 10px 10px 10px 10px; :where(.stk--is-hovered, .stk-block:hover) {--stk-container-border-radius: 50px 50px 50px 50px;}} |
13 | 15 | */ |
14 | | -const renderGlobalStyles = ( blockLayouts, setStyles, breakDesktop = 1024, breakTablet = 768 ) => { |
| 16 | + |
| 17 | +const transformToNested = ( _blockLayouts ) => { |
| 18 | + const devices = [ "desktop", "tablet", "mobile" ] |
| 19 | + |
| 20 | + const blockLayouts = {} |
| 21 | + |
| 22 | + for ( const property in _blockLayouts ) { |
| 23 | + blockLayouts[ property ] = {} |
| 24 | + |
| 25 | + devices.forEach( device => { |
| 26 | + blockLayouts[ property ][ device ] = {} |
| 27 | + |
| 28 | + if ( typeof blockLayouts[ property ][ `${ device }` ] !== undefined ) { |
| 29 | + blockLayouts[ property ][ device ][ 'normal' ] = blockLayouts[ property ][ `${ device }` ] |
| 30 | + } |
| 31 | + |
| 32 | + if ( typeof blockLayouts[ property ][ `${ device }Hover` ] !== undefined ) { |
| 33 | + blockLayouts[ property ][ device ][ 'hover' ] = blockLayouts[ property ][ `${ device }Hover` ] |
| 34 | + } |
| 35 | + |
| 36 | + if ( typeof blockLayouts[ property ][ `${ device }ParentHover` ] !== undefined ) { |
| 37 | + blockLayouts[ property ][ device ][ 'parent-hover' ] = blockLayouts[ property ][ `${ device }ParentHover` ] |
| 38 | + } |
| 39 | + } ) |
| 40 | + } |
| 41 | + |
| 42 | + return blockLayouts |
| 43 | +} |
| 44 | + |
| 45 | +const renderGlobalStyles = ( blockLayouts, setStyles, currentHoverState, blockUniqueId, parentHoverBlock, breakDesktop = 1024, breakTablet = 768 ) => { |
15 | 46 | if ( Object.keys( blockLayouts ).length === 0 ) { |
16 | 47 | setStyles( '' ) |
17 | 48 | return |
18 | 49 | } |
19 | 50 | let css = '' |
20 | 51 |
|
21 | | - const desktopCss = [] |
22 | | - const tabletCss = [] |
23 | | - const mobileCss = [] |
| 52 | + const deviceCss = { |
| 53 | + 'desktop': [], |
| 54 | + 'tablet': [], |
| 55 | + 'mobile': [] |
| 56 | + } |
24 | 57 |
|
25 | 58 | const getUnit = ( property, state ) => { |
26 | 59 | return blockLayouts[ property ][ `${ state }Unit` ] ?? 'px' |
27 | 60 | } |
28 | 61 |
|
29 | | - const getValue = ( _property, state, value, unit ) => { |
| 62 | + const getValue = ( _property, device, state, value, unit ) => { |
30 | 63 | let property = _property |
31 | 64 |
|
32 | | - if ( state.indexOf( 'ParentHover' ) !== -1 ) { |
33 | | - property += '-parent-hover' |
34 | | - } else if ( state.indexOf( 'Hover' ) !== -1 ) { |
| 65 | + if ( state === 'parent-hover' && currentHoverState === 'parent-hover' && blockUniqueId && parentHoverBlock ) { |
35 | 66 | property += '-hover' |
| 67 | + } else if ( state !== 'normal' ) { |
| 68 | + property += `-${ state }` |
36 | 69 | } |
37 | 70 |
|
38 | | - if ( property.indexOf( 'shadow' ) !== -1 ) { |
39 | | - return `${ property }: ${ value };` |
| 71 | + let style = '' |
| 72 | + if ( property.includes( 'shadow' ) ) { |
| 73 | + style = `${ property }: ${ value };` |
| 74 | + } else if ( typeof value === 'object' ) { |
| 75 | + style = `${ property }: ${ value.top }${ unit } ${ value.right }${ unit } ${ value.left }${ unit } ${ value.bottom }${ unit };` |
| 76 | + } else { |
| 77 | + style = `${ property }: ${ value }${ unit };` |
40 | 78 | } |
41 | 79 |
|
42 | | - if ( typeof value === 'object' ) { |
43 | | - return `${ property }: ${ value.top }${ unit } ${ value.right }${ unit } ${ value.left }${ unit } ${ value.bottom }${ unit };` |
| 80 | + if ( currentHoverState === 'parent-hover' && state === 'parent-hover' && blockUniqueId && parentHoverBlock ) { |
| 81 | + style = `.stk--is-hovered.stk-${ blockUniqueId }{ ${ style } }` |
44 | 82 | } |
45 | 83 |
|
46 | | - return `${ property }: ${ value }${ unit };` |
| 84 | + return style |
47 | 85 | } |
48 | 86 |
|
49 | 87 | Object.keys( blockLayouts ).forEach( property => { |
50 | 88 | const values = Object.keys( blockLayouts[ property ] ) |
51 | 89 | .filter( key => key.indexOf( 'Unit' ) === -1 ) |
52 | | - .reduce( ( obj, key ) => { |
| 90 | + .reduce( ( _blockLayouts, key ) => { |
53 | 91 | return { |
54 | | - ...obj, |
| 92 | + ..._blockLayouts, |
55 | 93 | [ key ]: blockLayouts[ property ][ key ], |
56 | 94 | } |
57 | 95 | }, {} ) |
58 | 96 |
|
59 | 97 | Object.entries( values ).forEach( ( [ state, value ] ) => { |
60 | 98 | const unit = getUnit( property, state ) |
61 | 99 |
|
62 | | - if ( state.indexOf( 'desktop' ) !== -1 ) { |
63 | | - desktopCss.push( getValue( property, state, value, unit ) ) |
64 | | - } |
65 | | - |
66 | | - if ( state.indexOf( 'tablet' ) !== -1 ) { |
67 | | - tabletCss.push( getValue( property, state, value, unit ) ) |
68 | | - } |
| 100 | + const device = state.includes( 'desktop' ) ? 'desktop' : ( state.includes( 'tablet' ) ? 'tablet' : 'mobile' ) |
| 101 | + const hoverState = state.includes( 'ParentHover' ) ? 'parent-hover' : ( state.includes( 'Hover' ) ? 'hover' : 'normal' ) |
69 | 102 |
|
70 | | - if ( state.indexOf( 'mobile' ) !== -1 ) { |
71 | | - mobileCss.push( getValue( property, state, value, unit ) ) |
72 | | - } |
| 103 | + deviceCss[ device ].push( getValue( property, device, hoverState, value, unit ) ) |
73 | 104 | } ) |
74 | 105 | } ) |
75 | 106 |
|
76 | | - css += `:root { ${ compact( desktopCss ).join( '' ) }}` |
| 107 | + if ( deviceCss.desktop.length > 0 ) { |
| 108 | + css += `:root { ${ compact( deviceCss.desktop ).join( '' ) }}` |
| 109 | + } |
77 | 110 |
|
78 | | - if ( tabletCss.length > 0 ) { |
79 | | - css += `@media screen and (max-width: ${ breakDesktop - 1 }px){ :root { ${ compact( tabletCss ).join( '' ) }} }` |
| 111 | + if ( deviceCss.tablet.length > 0 ) { |
| 112 | + css += `@media screen and (max-width: ${ breakDesktop - 1 }px){ :root { ${ compact( deviceCss.tablet ).join( '' ) }} }` |
80 | 113 | } |
81 | 114 |
|
82 | | - if ( mobileCss.length > 0 ) { |
83 | | - css += `@media screen and (max-width: ${ breakTablet - 1 }px){:root { ${ compact( mobileCss ).join( '' ) }}}` |
| 115 | + if ( deviceCss.mobile.length > 0 ) { |
| 116 | + css += `@media screen and (max-width: ${ breakTablet - 1 }px){:root { ${ compact( deviceCss.mobile ).join( '' ) }}}` |
84 | 117 | } |
85 | 118 |
|
86 | 119 | setStyles( css ) |
87 | 120 | } |
88 | 121 |
|
89 | 122 | export const GlobalBlockLayoutStyles = () => { |
90 | | - const { blockLayouts } = useSelect( select => ( { |
| 123 | + const { blockLayouts, selectedBlockUniqueId, SelectedParentHoverBlock,SelectedParentHoverBlockChildren, SelectedHoverChildren } = useSelect( select => ( { |
91 | 124 | blockLayouts: select( 'stackable/global-block-layouts' ).getBlockLayouts() || [], |
| 125 | + selectedBlockUniqueId: select( 'core/block-editor' ).getSelectedBlock()?.attributes?.uniqueId, |
| 126 | + SelectedParentHoverBlock: select( 'stackable/hover-state').getSelectedParentHoverBlock(), |
| 127 | + SelectedParentHoverBlockChildren: select( 'stackable/hover-state').getSelectedParentHoverBlockChildren(), |
| 128 | + SelectedHoverChildren: select( 'stackable/hover-state').getSelectedHoverChildren() |
92 | 129 | } ), [] ) |
93 | 130 |
|
| 131 | + const [ currentHoverState ] = useBlockHoverState( { globalControl: true } ) |
94 | 132 | const [ styles, setStyles ] = useState( '' ) |
95 | 133 |
|
96 | 134 | useEffect( () => { |
97 | 135 | if ( blockLayouts && typeof blockLayouts === 'object' ) { |
98 | | - renderGlobalStyles( blockLayouts, setStyles ) |
| 136 | + renderGlobalStyles( blockLayouts, setStyles, currentHoverState, selectedBlockUniqueId, SelectedParentHoverBlock ) |
99 | 137 | } |
100 | | - }, [ JSON.stringify( blockLayouts ) ] ) |
| 138 | + }, [ JSON.stringify( blockLayouts ), currentHoverState, SelectedParentHoverBlock ] ) |
101 | 139 |
|
102 | 140 | return styles |
103 | 141 | } |
0 commit comments