Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/block-components/icon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,12 @@ export const Icon = props => {
lastIconValueRef.current = newIcon
}
processedIconRef.current = _icon
} else if ( iconStr.includes( '<use' ) ) {
if ( iconStr !== lastIconValueRef.current ) {
setIcon( iconStr )
lastIconValueRef.current = iconStr
}
processedIconRef.current = _icon
} else if ( ! _icon ) {
// Clear processed ref when icon is removed
processedIconRef.current = null
Expand Down Expand Up @@ -322,7 +328,7 @@ export const Icon = props => {
const classNames = classnames(
[ 'stk--svg-wrapper' ],
{
'stk--show-cursor': debouncedIsSelected,
'stk--show-cursor': debouncedIsSelected || openEvenIfUnselected,
'stk--has-icon2': getAttribute( 'icon2' ),
}
)
Expand Down
67 changes: 23 additions & 44 deletions src/block/icon-list-item/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Internal dependencies
*/
import blockStyles from './style'
import { getUseSvgDef } from '../icon-list/util'
import { ListItemIcon } from './list-item-icon'
import {
convertToListItems,
useEnter,
Expand All @@ -23,7 +23,6 @@ import {
EffectsAnimations,
ConditionalDisplay,
Transform,
Icon,
} from '~stackable/block-components'
import { version as VERSION } from 'stackable'
import classnames from 'classnames'
Expand All @@ -40,10 +39,8 @@ import {
*/
import { __ } from '@wordpress/i18n'
import { compose, createHigherOrderComponent } from '@wordpress/compose'
import { dispatch, useSelect } from '@wordpress/data'
import {
useEffect, useRef, memo,
} from '@wordpress/element'
import { dispatch, select } from '@wordpress/data'
import { useEffect, memo } from '@wordpress/element'

const TABS = [ 'style', 'advanced' ]

Expand All @@ -61,42 +58,26 @@ const Edit = props => {
const { icon, text } = attributes
const textClasses = getTypographyClasses( props.attributes )
const blockAlignmentClass = getAlignmentClasses( props.attributes )
const { parentBlock } = useSelect( select => {
const { getBlockRootClientId, getBlock } = select( 'core/block-editor' )
const parentClientId = getBlockRootClientId( clientId )
return {
parentBlock: getBlock( parentClientId ),
}
}, [ clientId ] )

const {
'stackable/ordered': ordered,
'stackable/uniqueId': parentUniqueId,
} = context

const updateOrderedTimeout = useRef()
const updateUniqueIdTimeout = useRef()

// Set the attributes so they can be used in Save.
useEffect( () => {
clearTimeout( updateOrderedTimeout.current )
if ( ordered !== props.attributes.ordered ) {
updateOrderedTimeout.current = setTimeout( () => {
dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent()
setAttributes( { ordered } )
}, 300 )
dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent()
setAttributes( { ordered } )
}
}, [ ordered ] )
}, [ ordered, props.attributes.ordered, setAttributes ] )

useEffect( () => {
clearTimeout( updateUniqueIdTimeout.current )
if ( parentUniqueId !== props.attributes.parentUniqueId ) {
updateUniqueIdTimeout.current = setTimeout( () => {
dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent()
setAttributes( { parentUniqueId } )
}, 300 )
dispatch( 'core/block-editor' ).__unstableMarkNextChangeAsNotPersistent()
setAttributes( { parentUniqueId } )
}
}, [ parentUniqueId ] )
}, [ parentUniqueId, props.attributes.parentUniqueId, setAttributes ] )

const blockClassNames = classnames( [
className,
Expand All @@ -115,10 +96,14 @@ const Edit = props => {
mergeBlocks( forward )

// Remove icon list item and icon list on backspace if there is no text and is the only item on the list.
if ( ! forward &&
! attributes.text &&
parentBlock.innerBlocks.length === 1 ) {
dispatch( 'core/block-editor' ).removeBlocks( [ clientId, parentBlock.clientId ] )
if ( ! forward && ! attributes.text ) {
const { getBlockRootClientId, getBlock } = select( 'core/block-editor' )
const parentClientId = getBlockRootClientId( clientId )
const parentBlock = getBlock( parentClientId )

if ( parentBlock?.innerBlocks?.length === 1 ) {
dispatch( 'core/block-editor' ).removeBlocks( [ clientId, parentClientId ] )
}
}
}

Expand Down Expand Up @@ -150,18 +135,12 @@ const Edit = props => {

<CustomCSS mainBlockClass="stk-block-icon-list-item" />
<div className="stk-block-icon-list-item__content">
{ ! ordered && icon &&
<Icon
value={ icon }
openEvenIfUnselected={ true }
hasLinearGradient={ false }
/> }
{ ! ordered && ! icon && parentUniqueId &&
<Icon
value={ getUseSvgDef( `#stk-icon-list__icon-svg-def-${ parentUniqueId }` ) }
openEvenIfUnselected={ true }
hasLinearGradient={ false }
/> }
<ListItemIcon
ordered={ ordered }
icon={ icon }
parentUniqueId={ parentUniqueId }
setAttributes={ setAttributes }
/>
{ ordered &&
// This will contain the numbers in ::before pseudo-element for ordered lists.
// Placing the numbers here instead on li allows us to center the text vertically.
Expand Down
59 changes: 59 additions & 0 deletions src/block/icon-list-item/list-item-icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* External dependencies
*/
import { Icon } from '~stackable/block-components'

/**
* Internal dependencies
*/
import { getUseSvgDef } from '../icon-list/util'

/**
* Icon display for icon list items.
*
* Always mounts the full Icon picker so users can click any entry's icon
* without first selecting that list item (openEvenIfUnselected).
*
* @param {Object} props
* @param {boolean} props.ordered
* @param {string} props.icon
* @param {string} props.parentUniqueId
* @param {Function} props.setAttributes
*/
export const ListItemIcon = ( {
ordered,
icon,
parentUniqueId,
setAttributes,
} ) => {
if ( ordered ) {
return null
}

const hasCustomIcon = !! icon
const iconValue = icon || (
parentUniqueId
? getUseSvgDef( `#stk-icon-list__icon-svg-def-${ parentUniqueId }` )
: ''
)

if ( ! iconValue ) {
return null
}

// Remount when switching between custom and inherited icons so the Icon
// component's internal state resets correctly (e.g. after "Clear icon").
const iconKey = hasCustomIcon ? 'custom' : `inherit-${ parentUniqueId }`

return (
<Icon
key={ iconKey }
value={ iconValue }
openEvenIfUnselected={ true }
hasLinearGradient={ false }
onChange={ newIcon => {
setAttributes( { icon: newIcon } )
} }
/>
)
}
9 changes: 5 additions & 4 deletions src/block/icon-list-item/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { useRefEffect } from '@wordpress/compose'
import { useRef } from '@wordpress/element'
import {
useSelect,
select,
useDispatch,
} from '@wordpress/data'
import {
Expand Down Expand Up @@ -51,9 +51,6 @@ export const useEnter = ( text, clientId ) => {
const {
removeBlocks, selectionChange, insertBlocks,
} = useDispatch( blockEditorStore )
const {
getBlock, getBlockRootClientId, getBlockIndex,
} = useSelect( blockEditorStore )

const textRef = useRef( text )
textRef.current = text
Expand All @@ -69,6 +66,10 @@ export const useEnter = ( text, clientId ) => {
}
event.preventDefault()

const {
getBlock, getBlockRootClientId, getBlockIndex,
} = select( blockEditorStore )

// Here we are in top level list so we need to split.
const topParentListBlock = getBlock(
getBlockRootClientId( clientId )
Expand Down
Loading