Skip to content

Commit

Permalink
Navigation block: avoid selector + style recalc on mount (#60572)
Browse files Browse the repository at this point in the history
Co-authored-by: ellatrix <[email protected]>
Co-authored-by: ajlende <[email protected]>
  • Loading branch information
3 people committed Apr 8, 2024
1 parent 7c25dc4 commit d6a9db5
Showing 1 changed file with 129 additions and 98 deletions.
227 changes: 129 additions & 98 deletions packages/block-library/src/navigation/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,116 @@ import AccessibleDescription from './accessible-description';
import AccessibleMenuDescription from './accessible-menu-description';
import { unlock } from '../../lock-unlock';

function ColorTools( {
textColor,
setTextColor,
backgroundColor,
setBackgroundColor,
overlayTextColor,
setOverlayTextColor,
overlayBackgroundColor,
setOverlayBackgroundColor,
clientId,
navRef,
} ) {
const [ detectedBackgroundColor, setDetectedBackgroundColor ] = useState();
const [ detectedColor, setDetectedColor ] = useState();
const [
detectedOverlayBackgroundColor,
setDetectedOverlayBackgroundColor,
] = useState();
const [ detectedOverlayColor, setDetectedOverlayColor ] = useState();
// Turn on contrast checker for web only since it's not supported on mobile yet.
const enableContrastChecking = Platform.OS === 'web';
useEffect( () => {
if ( ! enableContrastChecking ) {
return;
}
detectColors(
navRef.current,
setDetectedColor,
setDetectedBackgroundColor
);

const subMenuElement = navRef.current?.querySelector(
'[data-type="core/navigation-submenu"] [data-type="core/navigation-link"]'
);

if ( ! subMenuElement ) {
return;
}

// Only detect submenu overlay colors if they have previously been explicitly set.
// This avoids the contrast checker from reporting on inherited submenu colors and
// showing the contrast warning twice.
if ( overlayTextColor.color || overlayBackgroundColor.color ) {
detectColors(
subMenuElement,
setDetectedOverlayColor,
setDetectedOverlayBackgroundColor
);
}
}, [
enableContrastChecking,
overlayTextColor.color,
overlayBackgroundColor.color,
navRef,
] );
const colorGradientSettings = useMultipleOriginColorsAndGradients();
if ( ! colorGradientSettings.hasColorsOrGradients ) {
return null;
}
return (
<>
<ColorGradientSettingsDropdown
__experimentalIsRenderedInSidebar
settings={ [
{
colorValue: textColor.color,
label: __( 'Text' ),
onColorChange: setTextColor,
resetAllFilter: () => setTextColor(),
},
{
colorValue: backgroundColor.color,
label: __( 'Background' ),
onColorChange: setBackgroundColor,
resetAllFilter: () => setBackgroundColor(),
},
{
colorValue: overlayTextColor.color,
label: __( 'Submenu & overlay text' ),
onColorChange: setOverlayTextColor,
resetAllFilter: () => setOverlayTextColor(),
},
{
colorValue: overlayBackgroundColor.color,
label: __( 'Submenu & overlay background' ),
onColorChange: setOverlayBackgroundColor,
resetAllFilter: () => setOverlayBackgroundColor(),
},
] }
panelId={ clientId }
{ ...colorGradientSettings }
gradients={ [] }
disableCustomGradients
/>
{ enableContrastChecking && (
<>
<ContrastChecker
backgroundColor={ detectedBackgroundColor }
textColor={ detectedColor }
/>
<ContrastChecker
backgroundColor={ detectedOverlayBackgroundColor }
textColor={ detectedOverlayColor }
/>
</>
) }
</>
);
}

function Navigation( {
attributes,
setAttributes,
Expand Down Expand Up @@ -330,17 +440,6 @@ function Navigation( {
},
} );

// Turn on contrast checker for web only since it's not supported on mobile yet.
const enableContrastChecking = Platform.OS === 'web';

const [ detectedBackgroundColor, setDetectedBackgroundColor ] = useState();
const [ detectedColor, setDetectedColor ] = useState();
const [
detectedOverlayBackgroundColor,
setDetectedOverlayBackgroundColor,
] = useState();
const [ detectedOverlayColor, setDetectedOverlayColor ] = useState();

const onSelectClassicMenu = async ( classicMenu ) => {
return convertClassicMenu( classicMenu.id, classicMenu.name, 'draft' );
};
Expand Down Expand Up @@ -412,40 +511,6 @@ function Navigation( {
handleUpdateMenu,
] );

useEffect( () => {
if ( ! enableContrastChecking ) {
return;
}
detectColors(
navRef.current,
setDetectedColor,
setDetectedBackgroundColor
);

const subMenuElement = navRef.current?.querySelector(
'[data-type="core/navigation-submenu"] [data-type="core/navigation-link"]'
);

if ( ! subMenuElement ) {
return;
}

// Only detect submenu overlay colors if they have previously been explicitly set.
// This avoids the contrast checker from reporting on inherited submenu colors and
// showing the contrast warning twice.
if ( overlayTextColor.color || overlayBackgroundColor.color ) {
detectColors(
subMenuElement,
setDetectedOverlayColor,
setDetectedOverlayBackgroundColor
);
}
}, [
enableContrastChecking,
overlayTextColor.color,
overlayBackgroundColor.color,
] );

useEffect( () => {
if ( ! isSelected && ! isInnerBlockSelected ) {
hideNavigationMenuPermissionsNotice();
Expand Down Expand Up @@ -518,7 +583,6 @@ function Navigation( {
`overlay-menu-preview`
);

const colorGradientSettings = useMultipleOriginColorsAndGradients();
const stylingInspectorControls = (
<>
<InspectorControls>
Expand Down Expand Up @@ -634,58 +698,25 @@ function Navigation( {
</PanelBody>
) }
</InspectorControls>
{ colorGradientSettings.hasColorsOrGradients && (
<InspectorControls group="color">
<ColorGradientSettingsDropdown
__experimentalIsRenderedInSidebar
settings={ [
{
colorValue: textColor.color,
label: __( 'Text' ),
onColorChange: setTextColor,
resetAllFilter: () => setTextColor(),
},
{
colorValue: backgroundColor.color,
label: __( 'Background' ),
onColorChange: setBackgroundColor,
resetAllFilter: () => setBackgroundColor(),
},
{
colorValue: overlayTextColor.color,
label: __( 'Submenu & overlay text' ),
onColorChange: setOverlayTextColor,
resetAllFilter: () => setOverlayTextColor(),
},
{
colorValue: overlayBackgroundColor.color,
label: __( 'Submenu & overlay background' ),
onColorChange: setOverlayBackgroundColor,
resetAllFilter: () =>
setOverlayBackgroundColor(),
},
] }
panelId={ clientId }
{ ...colorGradientSettings }
gradients={ [] }
disableCustomGradients
/>
{ enableContrastChecking && (
<>
<ContrastChecker
backgroundColor={ detectedBackgroundColor }
textColor={ detectedColor }
/>
<ContrastChecker
backgroundColor={
detectedOverlayBackgroundColor
}
textColor={ detectedOverlayColor }
/>
</>
) }
</InspectorControls>
) }
<InspectorControls group="color">
{ /*
* Avoid useMultipleOriginColorsAndGradients and detectColors
* on block mount. InspectorControls only mounts this component
* when the block is selected.
* */ }
<ColorTools
textColor={ textColor }
setTextColor={ setTextColor }
backgroundColor={ backgroundColor }
setBackgroundColor={ setBackgroundColor }
overlayTextColor={ overlayTextColor }
setOverlayTextColor={ setOverlayTextColor }
overlayBackgroundColor={ overlayBackgroundColor }
setOverlayBackgroundColor={ setOverlayBackgroundColor }
clientId={ clientId }
navRef={ navRef }
/>
</InspectorControls>
</>
);

Expand Down

0 comments on commit d6a9db5

Please sign in to comment.