diff --git a/packages/block-editor/src/components/block-styles/index.native.js b/packages/block-editor/src/components/block-styles/index.native.js index 982274b6bd6212..858e8a2c7a5f9f 100644 --- a/packages/block-editor/src/components/block-styles/index.native.js +++ b/packages/block-editor/src/components/block-styles/index.native.js @@ -9,6 +9,7 @@ import { find } from 'lodash'; */ import { store as blocksStore } from '@wordpress/blocks'; import { useSelect, useDispatch } from '@wordpress/data'; +import { useMemo } from '@wordpress/element'; import { _x } from '@wordpress/i18n'; /** @@ -33,10 +34,6 @@ function BlockStyles( { clientId, url } ) { const { updateBlockAttributes } = useDispatch( 'core/block-editor' ); - if ( ! styles || styles.length === 0 ) { - return null; - } - const renderedStyles = find( styles, 'isDefault' ) ? styles : [ @@ -48,37 +45,46 @@ function BlockStyles( { clientId, url } ) { ...styles, ]; - const activeStyle = getActiveStyle( renderedStyles, className ); + const mappedRenderedStyles = useMemo( () => { + const activeStyle = getActiveStyle( renderedStyles, className ); + + return renderedStyles.map( ( style ) => { + const styleClassName = replaceActiveStyle( + className, + activeStyle, + style + ); + const isActive = activeStyle === style; + + const onStylePress = () => { + updateBlockAttributes( clientId, { + className: styleClassName, + } ); + }; + + return ( + + ); + } ); + }, [ renderedStyles, className, clientId ] ); + + if ( ! styles || styles.length === 0 ) { + return null; + } + return ( - { renderedStyles.map( ( style ) => { - const styleClassName = replaceActiveStyle( - className, - activeStyle, - style - ); - const isActive = activeStyle === style; - - const onStylePress = () => { - updateBlockAttributes( clientId, { - className: styleClassName, - } ); - }; - - return ( - - ); - } ) } + { mappedRenderedStyles } ); } diff --git a/packages/block-editor/src/components/block-styles/preview.native.js b/packages/block-editor/src/components/block-styles/preview.native.js index c9f663dc7f7945..c5461bf330acb9 100644 --- a/packages/block-editor/src/components/block-styles/preview.native.js +++ b/packages/block-editor/src/components/block-styles/preview.native.js @@ -71,7 +71,7 @@ function StylePreview( { onPress, isActive, style, url } ) { return ( ); } ); diff --git a/packages/block-library/src/button/color-edit.js b/packages/block-library/src/button/color-edit.js index fbb1b2766ed396..e5611a97aee69d 100644 --- a/packages/block-library/src/button/color-edit.js +++ b/packages/block-library/src/button/color-edit.js @@ -7,7 +7,13 @@ import { pickBy, isEqual, isObject, identity, mapValues } from 'lodash'; * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { useState, useEffect, useRef, Platform } from '@wordpress/element'; +import { + useState, + useEffect, + useRef, + useMemo, + Platform, +} from '@wordpress/element'; /** * Internal dependencies @@ -200,32 +206,43 @@ function ColorEdit( props ) { }; }; + const settings = useMemo( () => { + return [ + { + label: __( 'Text Color' ), + onColorChange: onChangeColor( 'text' ), + colorValue: getColorObjectByAttributeValues( + colors, + textColor, + style?.color?.text + ).color, + }, + { + label: __( 'Background Color' ), + onColorChange: onChangeColor( 'background' ), + colorValue: getColorObjectByAttributeValues( + colors, + backgroundColor, + style?.color?.background + ).color, + gradientValue, + onGradientChange: onChangeGradient, + }, + ]; + }, [ + colors, + textColor, + backgroundColor, + gradientValue, + style?.color?.text, + style?.color?.background, + ] ); + return ( ); } diff --git a/packages/block-library/src/button/edit.native.js b/packages/block-library/src/button/edit.native.js index 48a1f6dd6a1945..d7e8bfeb37cffd 100644 --- a/packages/block-library/src/button/edit.native.js +++ b/packages/block-library/src/button/edit.native.js @@ -61,6 +61,37 @@ class ButtonEdit extends Component { isButtonFocused: true, placeholderTextWidth: 0, }; + + this.linkSettingsActions = [ + { + label: __( 'Remove link' ), + onPress: this.onClearSettings, + }, + ]; + + this.linkSettingsOptions = { + url: { + label: __( 'Button Link URL' ), + placeholder: __( 'Add URL' ), + autoFocus: true, + autoFill: true, + }, + openInNewTab: { + label: __( 'Open in new tab' ), + }, + linkRel: { + label: __( 'Link Rel' ), + placeholder: __( 'None' ), + }, + }; + + this.noFocusLinkSettingOptions = { + ...this.linkSettingsOptions, + url: { + ...this.linkSettingsOptions.url, + autoFocus: false, + }, + }; } componentDidMount() { @@ -221,39 +252,22 @@ class ButtonEdit extends Component { getLinkSettings( isCompatibleWithSettings ) { const { isLinkSheetVisible } = this.state; const { attributes, setAttributes } = this.props; - const actions = [ - { - label: __( 'Remove link' ), - onPress: this.onClearSettings, - }, - ]; - - const options = { - url: { - label: __( 'Button Link URL' ), - placeholder: __( 'Add URL' ), - autoFocus: ! isCompatibleWithSettings, - autoFill: true, - }, - openInNewTab: { - label: __( 'Open in new tab' ), - }, - linkRel: { - label: __( 'Link Rel' ), - placeholder: __( 'None' ), - }, - }; - return ( ); @@ -392,35 +406,35 @@ class ButtonEdit extends Component { { isSelected && ( - - - - - + <> + + + + + + { this.getLinkSettings( false ) } + + + + + + + { this.getLinkSettings( true ) } + + + ) } - - { this.getLinkSettings( false ) } - - - - - - - - { this.getLinkSettings( true ) } - - ); } diff --git a/packages/block-library/src/buttons/content-justification-dropdown.js b/packages/block-library/src/buttons/content-justification-dropdown.js index 40ecdd66f94649..003b738d521aec 100644 --- a/packages/block-library/src/buttons/content-justification-dropdown.js +++ b/packages/block-library/src/buttons/content-justification-dropdown.js @@ -2,6 +2,7 @@ * WordPress dependencies */ import { DropdownMenu } from '@wordpress/components'; +import { useMemo } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { justifyLeft, justifyCenter, justifyRight } from '@wordpress/icons'; @@ -44,21 +45,25 @@ export default function ContentJustificationDropdown( { toggleProps, value, } ) { + const controls = useMemo( () => { + return allowedValues.map( ( allowedValue ) => { + return { + ...CONTROLS[ allowedValue ], + isActive: value === allowedValue, + role: 'menuitemradio', + onClick: () => + onChange( + value === allowedValue ? undefined : allowedValue + ), + }; + } ); + }, [ allowedValues, value, onChange ] ); + return ( { - return { - ...CONTROLS[ allowedValue ], - isActive: value === allowedValue, - role: 'menuitemradio', - onClick: () => - onChange( - value === allowedValue ? undefined : allowedValue - ), - }; - } ) } + controls={ controls } toggleProps={ toggleProps } /> ); diff --git a/packages/block-library/src/buttons/edit.native.js b/packages/block-library/src/buttons/edit.native.js index e9102809a331b3..f2ee9894fe6f9e 100644 --- a/packages/block-library/src/buttons/edit.native.js +++ b/packages/block-library/src/buttons/edit.native.js @@ -117,19 +117,21 @@ export default function ButtonsEdit( { return ( <> - - - - { ( toggleProps ) => ( - - ) } - - - + { isSelected && ( + + + + { ( toggleProps ) => ( + + ) } + + + + ) } { resizeObserver } ( { + value: slug, + name, + } ) ); } componentDidMount() { @@ -336,65 +359,48 @@ export class ImageEdit extends Component { : width; } + setMappedAttributes( { url: href, ...restAttributes } ) { + const { setAttributes } = this.props; + return href === undefined + ? setAttributes( restAttributes ) + : setAttributes( { ...restAttributes, href } ); + } + getLinkSettings() { const { isLinkSheetVisible } = this.state; const { attributes: { href: url, ...unMappedAttributes }, - setAttributes, } = this.props; const mappedAttributes = { ...unMappedAttributes, url }; - const setMappedAttributes = ( { url: href, ...restAttributes } ) => - href === undefined - ? setAttributes( restAttributes ) - : setAttributes( { ...restAttributes, href } ); - - const options = { - url: { - label: __( 'Image Link URL' ), - placeholder: __( 'Add URL' ), - autoFocus: false, - autoFill: true, - }, - openInNewTab: { - label: __( 'Open in new tab' ), - }, - linkRel: { - label: __( 'Link Rel' ), - placeholder: __( 'None' ), - }, - }; return ( ); } + onSizeChangeValue( newValue ) { + this.onSetSizeSlug( newValue ); + } + render() { const { isCaptionSelected } = this.state; - const { - attributes, - isSelected, - image, - imageSizes, - clientId, - } = this.props; + const { attributes, isSelected, image, clientId } = this.props; const { align, url, alt, id, sizeSlug, className } = attributes; - const sizeOptions = map( imageSizes, ( { name, slug } ) => ( { - value: slug, - name, - } ) ); - const sizeOptionsValid = find( sizeOptions, [ + const sizeOptionsValid = find( this.sizeOptions, [ 'value', DEFAULT_SIZE_SLUG, ] ); @@ -427,10 +433,8 @@ export class ImageEdit extends Component { icon={ expand } label={ __( 'Size' ) } value={ sizeSlug || DEFAULT_SIZE_SLUG } - onChangeValue={ ( newValue ) => - this.onSetSizeSlug( newValue ) - } - options={ sizeOptions } + onChangeValue={ this.onSizeChangeValue } + options={ this.sizeOptions } /> ) } - { getInspectorControls() } - { getMediaOptions() } + { isSelected && getInspectorControls() } + { isSelected && getMediaOptions() } { ! this.state.isCaptionSelected && getToolbarEditButton( openMediaOptions ) } - - setHasUrl( true ) ); } - function onCloseSettingsSheet() { + const onCloseSettingsSheet = useCallback( () => { setIsLinkSheetVisible( false ); - } + }, [] ); - function onOpenSettingsSheet() { + const onOpenSettingsSheet = useCallback( () => { setIsLinkSheetVisible( true ); - } + }, [] ); - function onEmptyURL() { + const onEmptyURL = useCallback( () => { animatedValue.setValue( 0 ); setHasUrl( false ); - } + }, [ animatedValue ] ); function onIconPress() { if ( isSelected ) { @@ -147,30 +147,35 @@ const SocialLinkEdit = ( { return ( { isSelected && ( - - - - - + <> + + + + + + + ) } - + { + if ( ! value && onEmptyURL ) { + onEmptyURL(); + } + setUrlInputValue( value ); + }, + [ onEmptyURL ] + ); - function onChangeLabel( value ) { + const onChangeLabel = useCallback( ( value ) => { setLabelInputValue( value ); - } + }, [] ); - function onSetAttributes() { + const onSetAttributes = useCallback( () => { setAttributes( { url: prependHTTP( urlInputValue ), label: labelInputValue, rel: linkRelInputValue, } ); - } + }, [ urlInputValue, labelInputValue, linkRelInputValue, setAttributes ] ); - function onCloseSettingsSheet() { + const onCloseSettingsSheet = useCallback( () => { onSetAttributes(); if ( onClose ) { onClose(); } - } + }, [ onClose, onSetAttributes ] ); - function onChangeOpenInNewTab( value ) { - const newLinkTarget = value ? '_blank' : undefined; + const onChangeOpenInNewTab = useCallback( + ( value ) => { + const newLinkTarget = value ? '_blank' : undefined; - let updatedRel = linkRelInputValue; - if ( newLinkTarget && ! linkRelInputValue ) { - updatedRel = NEW_TAB_REL; - } else if ( ! newLinkTarget && linkRelInputValue === NEW_TAB_REL ) { - updatedRel = undefined; - } + let updatedRel = linkRelInputValue; + if ( newLinkTarget && ! linkRelInputValue ) { + updatedRel = NEW_TAB_REL; + } else if ( ! newLinkTarget && linkRelInputValue === NEW_TAB_REL ) { + updatedRel = undefined; + } - setAttributes( { - linkTarget: newLinkTarget, - rel: updatedRel, - } ); - } + setAttributes( { + linkTarget: newLinkTarget, + rel: updatedRel, + } ); + }, + [ linkRelInputValue ] + ); - function onChangeLinkRel( value ) { + const onChangeLinkRel = useCallback( ( value ) => { setLinkRelInputValue( value ); - } + }, [] ); async function getURLFromClipboard() { const clipboardText = await Clipboard.getString(); diff --git a/packages/components/src/mobile/link-settings/link-settings-navigation.native.js b/packages/components/src/mobile/link-settings/link-settings-navigation.native.js index 1ca459f5cb5023..a66a226840fbe7 100644 --- a/packages/components/src/mobile/link-settings/link-settings-navigation.native.js +++ b/packages/components/src/mobile/link-settings/link-settings-navigation.native.js @@ -1,3 +1,7 @@ +/** + * WordPress dependencies + */ +import { memo } from '@wordpress/element'; /** * Internal dependencies */ @@ -41,4 +45,4 @@ function LinkSettingsNavigation( props ) { ); } -export default LinkSettingsNavigation; +export default memo( LinkSettingsNavigation ); diff --git a/packages/components/src/mobile/link-settings/link-settings-screen.native.js b/packages/components/src/mobile/link-settings/link-settings-screen.native.js index 105bf553ea70c1..cf81843d6ee16f 100644 --- a/packages/components/src/mobile/link-settings/link-settings-screen.native.js +++ b/packages/components/src/mobile/link-settings/link-settings-screen.native.js @@ -16,7 +16,7 @@ import LinkSettings from './'; const LinkSettingsScreen = ( props ) => { const navigation = useNavigation(); const route = useRoute(); - const { url = '' } = props.attributes || {}; + const { url = '' } = props; const { inputValue = url } = route.params || {}; const onLinkCellPressed = () => { diff --git a/packages/components/src/panel/actions.native.js b/packages/components/src/panel/actions.native.js index 55dfbf3357e160..cea78ce46fef0a 100644 --- a/packages/components/src/panel/actions.native.js +++ b/packages/components/src/panel/actions.native.js @@ -8,6 +8,7 @@ import { View } from 'react-native'; */ import { TextControl } from '@wordpress/components'; import { withPreferredColorScheme } from '@wordpress/compose'; +import { useMemo } from '@wordpress/element'; /** * Internal dependencies @@ -16,6 +17,19 @@ import styles from './actions.scss'; import BottomSeparatorCover from './bottom-separator-cover'; function PanelActions( { actions, getStylesFromColorScheme } ) { + const mappedActions = useMemo( () => { + return actions.map( ( { label, onPress } ) => { + return ( + + ); + } ); + }, [ actions ] ); + return ( - { actions.map( ( { label, onPress } ) => { - return ( - - ); - } ) } + { mappedActions } );