Skip to content

Commit 9f48e9f

Browse files
committed
fix hover state styles
1 parent 615074e commit 9f48e9f

File tree

5 files changed

+43
-15
lines changed

5 files changed

+43
-15
lines changed

src/components/block-css/block-style-generator-class.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ export class BlockStyleGenerator {
213213
instanceId: args.instanceId,
214214
attributes,
215215
editorMode: true,
216+
generateForAllBlockStates: args.generateForAllBlockStates,
216217
} )
217218
if ( css ) {
218219
generatedCss.push( css )
@@ -237,6 +238,7 @@ export class BlockStyleGenerator {
237238
instanceId: args.instanceId,
238239
attributes,
239240
editorMode: true,
241+
generateForAllBlockStates: args.generateForAllBlockStates,
240242
} )
241243

242244
if ( css ) {

src/components/block-css/index.js

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ const BlockCss = props => {
8383
clientId = '', // The block's clientId, only used if rendering for the editor.
8484
instanceId = '', // Used by the Query Loop block, this is the instance of the template being displayed.
8585
blockState = 'normal', // The block's hover state to render the styles for.
86+
87+
generateForAllBlockStates = false, // If true, it will generate styles for all block states
8688
} = props
8789

8890
// const editorMode = ! compileCssTo
@@ -301,15 +303,20 @@ const BlockCss = props => {
301303

302304
// TODO: why do we have this condition for the collapsedSelector, but they just do the same prepending??
303305
if ( hasCollapsed ) {
304-
if ( blockState === 'collapsed' ) {
306+
if ( generateForAllBlockStates ) {
307+
collapsedSelector = prependClass( selector, '%h :where(.stk-block-accordion.stk--is-open) .%s' )
308+
} else if ( blockState === 'collapsed' ) {
305309
collapsedSelector = prependClass( selector, ':where(.stk-block-accordion.stk--is-open) .%s' )
306310
} else {
307311
collapsedSelector = prependClass( selector, ':where(.stk-block-accordion.stk--is-open) .%s' )
308312
}
309313
}
310314

315+
// Use %h as a placeholder to indicate that a hover state class should be prepended to the selector.
311316
if ( hasParentHover ) {
312-
if ( blockState === 'parent-hover' ) {
317+
if ( generateForAllBlockStates ) {
318+
parentHoverSelector = [ prependClass( selector, '%h.%s.stk--is-hovered' ), prependClass( selector, ':where(.stk-hover-parent:hover, .stk-hover-parent.stk--is-hovered) .%s' ) ]
319+
} else if ( blockState === 'parent-hover' ) {
313320
parentHoverSelector = prependClass( selector, '.%s.stk--is-hovered' )
314321
} else {
315322
parentHoverSelector = prependClass( selector, ':where(.stk-hover-parent:hover, .stk-hover-parent.stk--is-hovered) .%s' )
@@ -322,18 +329,24 @@ const BlockCss = props => {
322329
// using the selector `[data-block="clientId"]`, for these scenarios the
323330
// method will not work. Instead we just append `:hover` to the block
324331
// selector directly.
332+
// Use %h as a placeholder to indicate that a hover state class should be prepended to the selector.
325333
if ( hasHover ) {
326334
const selectorHasDataBlock = ( hoverSelector || selector ).includes( '[data-block=' ) && ( hoverSelector || selector ).endsWith( ']' )
327335
if ( selectorHasDataBlock ) {
328336
// If there is a [data-block] append the :hover or .stk-is-hovered directly to it.
329-
if ( blockState === 'hover' ) {
337+
if ( generateForAllBlockStates ) {
338+
hoverSelector = [ appendClass( selector, '%h.stk--is-hovered' ), hoverSelector || appendClass( selector, ':hover' ) ]
339+
} else if ( blockState === 'hover' ) {
330340
// In editor, always use the `selector` instead of the hoverSelector.
331341
hoverSelector = appendClass( selector, '.stk--is-hovered' )
332342
} else {
333343
hoverSelector = hoverSelector || appendClass( selector, ':hover' )
334344
}
335345
} else {
336346
// Prepend .%s:hover to the selector.
347+
if ( generateForAllBlockStates ) {
348+
hoverSelector = [ prependClass( selector, '%h.%s.stk--is-hovered' ), hoverSelector || prependClass( selector, '.%s:hover' ) ]
349+
}
337350
if ( blockState === 'hover' ) { // eslint-disable-line no-lonely-if
338351
// In editor, always use the `selector` instead of the hoverSelector.
339352
hoverSelector = prependClass( selector, '.%s.stk--is-hovered' )
@@ -353,8 +366,8 @@ const BlockCss = props => {
353366
if ( typeof selector === 'string' ) {
354367
// Add instance id to classes. ( e.g. `stk-abc123` -> `stk-abc123-2`, where 2 is `instanceId`. )
355368
selector = selector.replace( /[^^?](.%s)([^-])/g, `$1-${ instanceId }$2` )
356-
hoverSelector = hoverSelector.replace( /[^^?](.%s)([^-])/g, `$1-${ instanceId }$2` )
357-
parentHoverSelector = parentHoverSelector.replace( /[^^?](.%s)([^-])/g, `$1-${ instanceId }$2` )
369+
hoverSelector = typeof hoverSelector === 'string' ? hoverSelector.replace( /[^^?](.%s)([^-])/g, `$1-${ instanceId }$2` ) : hoverSelector.map( s => s.replace( /[^^?](.%s)([^-])/g, `$1-${ instanceId }$2` ) )
370+
parentHoverSelector = typeof parentHoverSelector === 'string' ? parentHoverSelector.replace( /[^^?](.%s)([^-])/g, `$1-${ instanceId }$2` ) : parentHoverSelector.map( s => s.replace( /[^^?](.%s)([^-])/g, `$1-${ instanceId }$2` ) )
358371
collapsedSelector = collapsedSelector.replace( /[^^?](.%s)([^-])/g, `$1-${ instanceId }$2` )
359372
}
360373
}
@@ -372,16 +385,20 @@ const BlockCss = props => {
372385
if ( Array.isArray( hoverSelector ) ) {
373386
hoverSelector = hoverSelector.join( ', ' )
374387
}
388+
if ( Array.isArray( parentHoverSelector ) ) {
389+
parentHoverSelector = parentHoverSelector.join( ', ' )
390+
}
375391

376-
selector = prependCSSClass( selector, blockUniqueClassName, blockUniqueClassName, editorMode ? '.editor-styles-wrapper' : '' )
392+
const wrapSelector = editorMode ? '.editor-styles-wrapper' : ''
393+
selector = prependCSSClass( selector, blockUniqueClassName, blockUniqueClassName, wrapSelector )
377394
if ( hasHover ) {
378-
hoverSelector = prependCSSClass( hoverSelector, blockUniqueClassName, blockUniqueClassName, editorMode ? '.editor-styles-wrapper' : '' )
395+
hoverSelector = prependCSSClass( hoverSelector, blockUniqueClassName, blockUniqueClassName, wrapSelector, generateForAllBlockStates ? '.stk-preview-state--hover' : '' )
379396
}
380397
if ( hasParentHover ) {
381-
parentHoverSelector = prependCSSClass( parentHoverSelector, blockUniqueClassName, blockUniqueClassName, editorMode ? '.editor-styles-wrapper' : '' )
398+
parentHoverSelector = prependCSSClass( parentHoverSelector, blockUniqueClassName, blockUniqueClassName, wrapSelector, generateForAllBlockStates ? '.stk-preview-state--parent-hover' : '' )
382399
}
383400
if ( hasCollapsed ) {
384-
collapsedSelector = prependCSSClass( collapsedSelector, blockUniqueClassName, blockUniqueClassName, editorMode ? '.editor-styles-wrapper' : '' )
401+
collapsedSelector = prependCSSClass( collapsedSelector, blockUniqueClassName, blockUniqueClassName, wrapSelector, generateForAllBlockStates ? '.stk-preview-state--collapsed' : '' )
385402
}
386403

387404
let css = ''

src/components/block-css/use-block-style-generator.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useQueryLoopInstanceId } from '~stackable/util'
22
import { useMemo, useRef } from '@wordpress/element'
3-
import { useBlockStyleContext, useRafEffect } from '~stackable/hooks'
3+
import { useRafEffect } from '~stackable/hooks'
44
import CssSaveCompiler from './css-save-compiler'
55

66
export const useBlockCssGenerator = props => {
@@ -25,8 +25,6 @@ export const useBlockCssGenerator = props => {
2525
// Keep the generated CSS for editor and return it when only the text attribute has changed.
2626
const oldCss = useRef( null )
2727

28-
const [ , editCssRef ] = useBlockStyleContext()
29-
3028
const editCss = useMemo( () => {
3129
if ( oldText.current !== attributes.text ) {
3230
oldText.current = attributes.text
@@ -48,7 +46,6 @@ export const useBlockCssGenerator = props => {
4846
context, // This is used for dynamic content.
4947
} )
5048
oldCss.current = css
51-
editCssRef.current = css
5249
return css
5350
}, [ attributes, version, blockState, clientId, attributes.uniqueId, instanceId, context ] )
5451

src/hooks/use-block-style-context.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export const useBlockStyleContext = () => {
1313
export const BlockStyleProvider = props => {
1414
return <BlockStyleContext.Provider value={ [
1515
props.blockStyles,
16-
props.editCss,
1716
{
1817
blockState: props.blockState,
1918
clientId: props.clientId,

src/util/index.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,11 @@ const prependCSSClassCache = {}
251251
* @param {string} mainClassName The main class of the block to target.
252252
* @param {string} uniqueClassName The unique parent classname to wrap the selector.
253253
* @param {string} wrapSelector All selectors will be wrapped in this if provided.
254+
* @param {string} hoverStateSelector selectors with %h in it will be wrapped in this if provided.
254255
*
255256
* @return {string} The modified CSS selector.
256257
*/
257-
export const prependCSSClass = ( cssSelector, mainClassName = '', uniqueClassName = '', wrapSelector = '' ) => {
258+
export const prependCSSClass = ( cssSelector, mainClassName = '', uniqueClassName = '', wrapSelector = '', hoverStateSelector = '' ) => {
258259
const key = `${ cssSelector }-${ mainClassName }-${ uniqueClassName }-${ wrapSelector }`
259260
if ( prependCSSClassCache[ key ] ) {
260261
return prependCSSClassCache[ key ]
@@ -268,6 +269,13 @@ export const prependCSSClass = ( cssSelector, mainClassName = '', uniqueClassNam
268269
.split( ',' )
269270
.map( s => {
270271
let newSelector = ''
272+
let hasHoverStateSelector = false
273+
274+
if ( s.includes( '%h' ) ) {
275+
hasHoverStateSelector = true
276+
s = s.replaceAll( '%h', '' ).trim()
277+
}
278+
271279
if ( s.includes( '[data-block=' ) ||
272280
s === 'html' ||
273281
s === 'body'
@@ -286,6 +294,11 @@ export const prependCSSClass = ( cssSelector, mainClassName = '', uniqueClassNam
286294
.replace( new RegExp( `(.${ uniqueClassName }) (.${ mainClassName }(#|:|\\[|\\.|\\s|$))`, 'g' ), '$1$2' )
287295
.replace( /\s:(?!(is|where))/, ':' ) // If the selector given is just a pseudo selector ':before', it will produce ' :before', remove the extra space.
288296
}
297+
298+
if ( hasHoverStateSelector && hoverStateSelector && wrapSelector ) {
299+
return `${ hoverStateSelector }${ wrapSelector } ${ newSelector }`
300+
}
301+
289302
return wrapSelector ? `${ wrapSelector } ${ newSelector }` : newSelector
290303
} )
291304
.join( ', ' )

0 commit comments

Comments
 (0)