diff --git a/src/block-components/icon/index.js b/src/block-components/icon/index.js index f968cca94..f79276fc9 100644 --- a/src/block-components/icon/index.js +++ b/src/block-components/icon/index.js @@ -282,6 +282,12 @@ export const Icon = props => { lastIconValueRef.current = newIcon } processedIconRef.current = _icon + } else if ( iconStr.includes( ' { const classNames = classnames( [ 'stk--svg-wrapper' ], { - 'stk--show-cursor': debouncedIsSelected, + 'stk--show-cursor': debouncedIsSelected || openEvenIfUnselected, 'stk--has-icon2': getAttribute( 'icon2' ), } ) diff --git a/src/block/icon-list-item/edit.js b/src/block/icon-list-item/edit.js index 4e78765fe..b8ce42e1b 100644 --- a/src/block/icon-list-item/edit.js +++ b/src/block/icon-list-item/edit.js @@ -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, @@ -23,7 +23,6 @@ import { EffectsAnimations, ConditionalDisplay, Transform, - Icon, } from '~stackable/block-components' import { version as VERSION } from 'stackable' import classnames from 'classnames' @@ -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' ] @@ -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, @@ -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 ] ) + } } } @@ -150,18 +135,12 @@ const Edit = props => {
- { ! ordered && icon && - } - { ! ordered && ! icon && parentUniqueId && - } + { 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. diff --git a/src/block/icon-list-item/list-item-icon.js b/src/block/icon-list-item/list-item-icon.js new file mode 100644 index 000000000..c2ba12f25 --- /dev/null +++ b/src/block/icon-list-item/list-item-icon.js @@ -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 ( + { + setAttributes( { icon: newIcon } ) + } } + /> + ) +} diff --git a/src/block/icon-list-item/util.js b/src/block/icon-list-item/util.js index ca48a416e..80947669f 100644 --- a/src/block/icon-list-item/util.js +++ b/src/block/icon-list-item/util.js @@ -5,7 +5,7 @@ import { useRefEffect } from '@wordpress/compose' import { useRef } from '@wordpress/element' import { - useSelect, + select, useDispatch, } from '@wordpress/data' import { @@ -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 @@ -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 )