diff --git a/lib/client-assets.php b/lib/client-assets.php
index 3bf11c6510ca5b..e56bec615f6495 100644
--- a/lib/client-assets.php
+++ b/lib/client-assets.php
@@ -703,6 +703,21 @@ function gutenberg_extend_settings_custom_spacing( $settings ) {
}
add_filter( 'block_editor_settings', 'gutenberg_extend_settings_custom_spacing' );
+
+/**
+ * Extends block editor settings to determine whether to use custom spacing controls.
+ * Currently experimental.
+ *
+ * @param array $settings Default editor settings.
+ *
+ * @return array Filtered editor settings.
+ */
+function gutenberg_extend_settings_link_color( $settings ) {
+ $settings['__experimentalEnableLinkColor'] = get_theme_support( 'experimental-link-color' );
+ return $settings;
+}
+add_filter( 'block_editor_settings', 'gutenberg_extend_settings_link_color' );
+
/*
* Register default patterns if not registered in Core already.
*/
diff --git a/lib/edit-site-page.php b/lib/edit-site-page.php
index 817c3ef9cb809f..9704bda44f7f1b 100644
--- a/lib/edit-site-page.php
+++ b/lib/edit-site-page.php
@@ -155,8 +155,8 @@ function gutenberg_edit_site_init( $hook ) {
$current_template = gutenberg_find_template_post_and_parts( $template_type );
if ( isset( $current_template ) ) {
- $template_ids[ $current_template['template_post']->post_name ] = $current_template['template_post']->ID;
- $template_part_ids = $template_part_ids + $current_template['template_part_ids'];
+ $template_ids[ $template_type ] = $current_template['template_post']->ID;
+ $template_part_ids = $template_part_ids + $current_template['template_part_ids'];
}
}
diff --git a/lib/global-styles.php b/lib/global-styles.php
index d14fdaad531d56..166d84df01badc 100644
--- a/lib/global-styles.php
+++ b/lib/global-styles.php
@@ -439,6 +439,16 @@ function gutenberg_experimental_global_styles_resolver( $tree ) {
)
);
}
+
+ if ( gutenberg_experimental_global_styles_has_theme_json_support() ) {
+ // To support all themes, we added in the block-library stylesheet
+ // a style rule such as .has-link-color a { color: var(--wp--style--color--link, #00e); }
+ // so that existing link colors themes used didn't break.
+ // We add this here to make it work for themes that opt-in to theme.json
+ // In the future, we may do this differently.
+ $stylesheet .= 'a { color: var(--wp--style--color--link, #00e); }';
+ }
+
return $stylesheet;
}
@@ -455,15 +465,6 @@ function gutenberg_experimental_global_styles_resolver_styles( $block_selector,
$css_rule = '';
$css_declarations = '';
- if ( gutenberg_experimental_global_styles_has_theme_json_support() ) {
- // To support all themes, we added in the block-library stylesheet
- // a style rule such as .has-link-color a { color: var(--wp--style--color--link, #00e); }
- // so that existing link colors themes used didn't break.
- // We add this here to make it work for themes that opt-in to theme.json
- // In the future, we may do this differently.
- $css_rule = 'a { color: var(--wp--style--color--link, #00e); }';
- }
-
foreach ( $block_styles as $property => $value ) {
// Only convert to CSS:
//
diff --git a/lib/template-loader.php b/lib/template-loader.php
index 12ac078ad9231b..dd158e89fd3434 100644
--- a/lib/template-loader.php
+++ b/lib/template-loader.php
@@ -134,68 +134,67 @@ function gutenberg_override_query_template( $template, $type, array $templates =
* @return int[] A list of template parts IDs for the given block.
*/
function create_auto_draft_for_template_part_block( $block ) {
- if ( 'core/template-part' !== $block['blockName'] ) {
- return array();
- }
+ $template_part_ids = array();
- if ( isset( $block['attrs']['postId'] ) ) {
- // Template part is customized.
- $template_part_id = $block['attrs']['postId'];
- } else {
- // A published post might already exist if this template part
- // was customized elsewhere or if it's part of a customized
- // template. We also check if an auto-draft was already created
- // because preloading can make this run twice, so, different code
- // paths can end up with different posts for the same template part.
- // E.g. The server could send back post ID 1 to the client, preload,
- // and create another auto-draft. So, if the client tries to resolve the
- // post ID from the slug and theme, it won't match with what the server sent.
- $template_part_query = new WP_Query(
- array(
- 'post_type' => 'wp_template_part',
- 'post_status' => array( 'publish', 'auto-draft' ),
- 'name' => $block['attrs']['slug'],
- 'meta_key' => 'theme',
- 'meta_value' => $block['attrs']['theme'],
- 'posts_per_page' => 1,
- 'no_found_rows' => true,
- )
- );
- $template_part_post = $template_part_query->have_posts() ? $template_part_query->next_post() : null;
- if ( $template_part_post ) {
- $template_part_id = $template_part_post->ID;
+ if ( 'core/template-part' === $block['blockName'] ) {
+ if ( isset( $block['attrs']['postId'] ) ) {
+ // Template part is customized.
+ $template_part_id = $block['attrs']['postId'];
} else {
- // Template part is not customized, get it from a file and make an auto-draft for it.
- $template_part_file_path =
- get_stylesheet_directory() . '/block-template-parts/' . $block['attrs']['slug'] . '.html';
- if ( ! file_exists( $template_part_file_path ) ) {
- if ( gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing-demo' ) ) {
- $template_part_file_path =
- dirname( __FILE__ ) . '/demo-block-template-parts/' . $block['attrs']['slug'] . '.html';
- if ( ! file_exists( $template_part_file_path ) ) {
+ // A published post might already exist if this template part
+ // was customized elsewhere or if it's part of a customized
+ // template. We also check if an auto-draft was already created
+ // because preloading can make this run twice, so, different code
+ // paths can end up with different posts for the same template part.
+ // E.g. The server could send back post ID 1 to the client, preload,
+ // and create another auto-draft. So, if the client tries to resolve the
+ // post ID from the slug and theme, it won't match with what the server sent.
+ $template_part_query = new WP_Query(
+ array(
+ 'post_type' => 'wp_template_part',
+ 'post_status' => array( 'publish', 'auto-draft' ),
+ 'name' => $block['attrs']['slug'],
+ 'meta_key' => 'theme',
+ 'meta_value' => $block['attrs']['theme'],
+ 'posts_per_page' => 1,
+ 'no_found_rows' => true,
+ )
+ );
+ $template_part_post = $template_part_query->have_posts() ? $template_part_query->next_post() : null;
+ if ( $template_part_post ) {
+ $template_part_id = $template_part_post->ID;
+ } else {
+ // Template part is not customized, get it from a file and make an auto-draft for it.
+ $template_part_file_path =
+ get_stylesheet_directory() . '/block-template-parts/' . $block['attrs']['slug'] . '.html';
+ if ( ! file_exists( $template_part_file_path ) ) {
+ if ( gutenberg_is_experiment_enabled( 'gutenberg-full-site-editing-demo' ) ) {
+ $template_part_file_path =
+ dirname( __FILE__ ) . '/demo-block-template-parts/' . $block['attrs']['slug'] . '.html';
+ if ( ! file_exists( $template_part_file_path ) ) {
+ return;
+ }
+ } else {
return;
}
- } else {
- return;
}
+ $template_part_id = wp_insert_post(
+ array(
+ 'post_content' => file_get_contents( $template_part_file_path ),
+ 'post_title' => $block['attrs']['slug'],
+ 'post_status' => 'auto-draft',
+ 'post_type' => 'wp_template_part',
+ 'post_name' => $block['attrs']['slug'],
+ 'meta_input' => array(
+ 'theme' => $block['attrs']['theme'],
+ ),
+ )
+ );
}
- $template_part_id = wp_insert_post(
- array(
- 'post_content' => file_get_contents( $template_part_file_path ),
- 'post_title' => $block['attrs']['slug'],
- 'post_status' => 'auto-draft',
- 'post_type' => 'wp_template_part',
- 'post_name' => $block['attrs']['slug'],
- 'meta_input' => array(
- 'theme' => $block['attrs']['theme'],
- ),
- )
- );
}
+ $template_part_ids[ $block['attrs']['slug'] ] = $template_part_id;
}
- $template_part_ids = array( $block['attrs']['slug'] => $template_part_id );
-
foreach ( $block['innerBlocks'] as $inner_block ) {
$template_part_ids = array_merge( $template_part_ids, create_auto_draft_for_template_part_block( $inner_block ) );
}
@@ -319,6 +318,21 @@ function gutenberg_find_template_post_and_parts( $template_type, $template_hiera
}
}
+ // If we haven't found any template post by here, it means that this theme doesn't even come with a fallback
+ // `index.html` block template. We create one so that people that are trying to access the editor are greeted
+ // with a blank page rather than an error.
+ if ( ! $current_template_post && ( is_admin() || defined( 'REST_REQUEST' ) ) ) {
+ $current_template_post = array(
+ 'post_title' => 'index',
+ 'post_status' => 'auto-draft',
+ 'post_type' => 'wp_template',
+ 'post_name' => 'index',
+ );
+ $current_template_post = get_post(
+ wp_insert_post( $current_template_post )
+ );
+ }
+
if ( $current_template_post ) {
$template_part_ids = array();
if ( is_admin() ) {
diff --git a/package-lock.json b/package-lock.json
index 39c5e9fb473555..1bd80bd9a51fca 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -35795,9 +35795,9 @@
}
},
"extract-zip": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.0.tgz",
- "integrity": "sha512-i42GQ498yibjdvIhivUsRslx608whtGoFIhF26Z7O4MYncBxp8CwalOs1lnHy21A9sIohWO2+uiE4SRtC9JXDg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
"dev": true,
"requires": {
"@types/yauzl": "^2.9.1",
diff --git a/packages/block-editor/src/hooks/color.js b/packages/block-editor/src/hooks/color.js
index 0c527226798924..12837b4322cef0 100644
--- a/packages/block-editor/src/hooks/color.js
+++ b/packages/block-editor/src/hooks/color.js
@@ -180,9 +180,13 @@ const getLinkColorFromAttributeValue = ( colors, value ) => {
*/
export function ColorEdit( props ) {
const { name: blockName, attributes } = props;
- const { colors, gradients } = useSelect( ( select ) => {
- return select( 'core/block-editor' ).getSettings();
- }, [] );
+ const { colors, gradients, __experimentalEnableLinkColor } = useSelect(
+ ( select ) => {
+ return select( 'core/block-editor' ).getSettings();
+ },
+ []
+ );
+
// Shouldn't be needed but right now the ColorGradientsPanel
// can trigger both onChangeColor and onChangeBackground
// synchronously causing our two callbacks to override changes
@@ -310,7 +314,8 @@ export function ColorEdit( props ) {
? onChangeGradient
: undefined,
},
- ...( hasLinkColorSupport( blockName )
+ ...( __experimentalEnableLinkColor &&
+ hasLinkColorSupport( blockName )
? [
{
label: __( 'Link Color' ),
diff --git a/packages/block-editor/src/hooks/padding.js b/packages/block-editor/src/hooks/padding.js
index ce9316309e4231..e042a2de83cac4 100644
--- a/packages/block-editor/src/hooks/padding.js
+++ b/packages/block-editor/src/hooks/padding.js
@@ -37,7 +37,22 @@ export function PaddingEdit( props ) {
const onChange = ( next ) => {
const newStyle = {
...style,
- padding: next,
+ spacing: {
+ padding: next,
+ },
+ };
+
+ setAttributes( {
+ style: cleanEmptyObject( newStyle ),
+ } );
+ };
+
+ const onChangeShowVisualizer = ( next ) => {
+ const newStyle = {
+ ...style,
+ visualizers: {
+ padding: next,
+ },
};
setAttributes( {
@@ -49,8 +64,9 @@ export function PaddingEdit( props ) {
web: (
<>
@@ -61,8 +77,8 @@ export function PaddingEdit( props ) {
}
export const paddingStyleMappings = {
- paddingTop: [ 'padding', 'top' ],
- paddingRight: [ 'padding', 'right' ],
- paddingBottom: [ 'padding', 'bottom' ],
- paddingLeft: [ 'padding', 'left' ],
+ paddingTop: [ 'spacing', 'padding', 'top' ],
+ paddingRight: [ 'spacing', 'padding', 'right' ],
+ paddingBottom: [ 'spacing', 'padding', 'bottom' ],
+ paddingLeft: [ 'spacing', 'padding', 'left' ],
};
diff --git a/packages/block-editor/src/hooks/style.js b/packages/block-editor/src/hooks/style.js
index f8fbf30c6b6e3f..a3b101b86790aa 100644
--- a/packages/block-editor/src/hooks/style.js
+++ b/packages/block-editor/src/hooks/style.js
@@ -74,11 +74,17 @@ export function getInlineStyles( styles = {} ) {
};
const output = {};
- Object.entries( mappings ).forEach( ( [ styleKey, objectKey ] ) => {
- if ( has( styles, objectKey ) ) {
- output[ styleKey ] = compileStyleValue( get( styles, objectKey ) );
+ Object.entries( mappings ).forEach(
+ ( [ styleKey, ...otherObjectKeys ] ) => {
+ const [ objectKeys ] = otherObjectKeys;
+
+ if ( has( styles, objectKeys ) ) {
+ output[ styleKey ] = compileStyleValue(
+ get( styles, objectKeys )
+ );
+ }
}
- } );
+ );
return output;
}
diff --git a/packages/block-library/src/cover/edit.js b/packages/block-library/src/cover/edit.js
index 076d0881cbe6e1..6f2794da106b25 100644
--- a/packages/block-library/src/cover/edit.js
+++ b/packages/block-library/src/cover/edit.js
@@ -475,7 +475,10 @@ function CoverEdit( {
<>
{ controls }
-
+
{
diff --git a/packages/block-library/src/image/edit.js b/packages/block-library/src/image/edit.js
index b7dba1d0f2db98..dd938ee6860d66 100644
--- a/packages/block-library/src/image/edit.js
+++ b/packages/block-library/src/image/edit.js
@@ -161,6 +161,7 @@ export function ImageEdit( {
alt: undefined,
id: undefined,
title: undefined,
+ caption: undefined,
} );
return;
}
@@ -175,9 +176,9 @@ export function ImageEdit( {
}
}
- // If a caption text was meanwhile written by the user, make sure the
- // text is not overwritten by another caption.
- if ( caption ) {
+ // If a caption text was meanwhile written by the user,
+ // make sure the text is not overwritten by empty captions.
+ if ( caption && ! get( mediaAttributes, [ 'caption' ] ) ) {
mediaAttributes = omit( mediaAttributes, [ 'caption' ] );
}
@@ -403,33 +404,11 @@ export function ImageEdit( {
imageHeight,
} = useImageSize( ref, url, [ align ] );
- let captionField;
-
- if ( ! RichText.isEmpty( caption ) || isSelected ) {
- captionField = (
- setAttributes( { caption: value } ) }
- isSelected={ captionFocused }
- inlineToolbar
- __unstableOnSplitAtEnd={ () =>
- insertBlocksAfter( createBlock( 'core/paragraph' ) )
- }
- />
- );
- }
-
if ( ! url ) {
return (
<>
{ controls }
-
- { mediaPlaceholder }
- { captionField }
-
+ { mediaPlaceholder }
>
);
}
@@ -617,7 +596,22 @@ export function ImageEdit( {
{ controls }
{ img }
- { captionField }
+ { ( ! RichText.isEmpty( caption ) || isSelected ) && (
+
+ setAttributes( { caption: value } )
+ }
+ isSelected={ captionFocused }
+ inlineToolbar
+ __unstableOnSplitAtEnd={ () =>
+ insertBlocksAfter( createBlock( 'core/paragraph' ) )
+ }
+ />
+ ) }
{ mediaPlaceholder }
>
diff --git a/packages/components/src/box-control/README.md b/packages/components/src/box-control/README.md
index e4105871042dc3..47d398243297fd 100644
--- a/packages/components/src/box-control/README.md
+++ b/packages/components/src/box-control/README.md
@@ -111,7 +111,14 @@ Heading label for BoxControl.
### onChange
-A function that receives the values of the inputs.
+A callback function when an input value changes.
+
+- Type: `Function`
+- Required: Yes
+
+### onChangeShowVisualizer
+
+A callback function for visualizer changes, based on input hover interactions.
- Type: `Function`
- Required: Yes
diff --git a/packages/components/src/box-control/all-input-control.js b/packages/components/src/box-control/all-input-control.js
index 8a40dd47e6612d..1f1260898505d1 100644
--- a/packages/components/src/box-control/all-input-control.js
+++ b/packages/components/src/box-control/all-input-control.js
@@ -6,16 +6,19 @@ import { noop } from 'lodash';
* Internal dependencies
*/
import UnitControl from './unit-control';
-import { LABELS, getAllValue, isValuesMixed } from './utils';
+import { LABELS, getAllValue, isValuesMixed, isValuesDefined } from './utils';
export default function AllInputControl( {
onChange = noop,
onFocus = noop,
+ onHoverOn = noop,
+ onHoverOff = noop,
values,
...props
} ) {
const allValue = getAllValue( values );
- const isMixed = isValuesMixed( values );
+ const hasValues = isValuesDefined( values );
+ const isMixed = hasValues && isValuesMixed( values );
const allPlaceholder = isMixed ? LABELS.mixed : null;
@@ -34,6 +37,24 @@ export default function AllInputControl( {
onChange( nextValues );
};
+ const handleOnHoverOn = () => {
+ onHoverOn( {
+ top: true,
+ bottom: true,
+ left: true,
+ right: true,
+ } );
+ };
+
+ const handleOnHoverOff = () => {
+ onHoverOff( {
+ top: false,
+ bottom: false,
+ left: false,
+ right: false,
+ } );
+ };
+
return (
);
diff --git a/packages/components/src/box-control/index.js b/packages/components/src/box-control/index.js
index 387fd317563f35..f75a4aee4b77d6 100644
--- a/packages/components/src/box-control/index.js
+++ b/packages/components/src/box-control/index.js
@@ -7,7 +7,7 @@ import { noop } from 'lodash';
* WordPress dependencies
*/
import { useInstanceId } from '@wordpress/compose';
-import { useState, useRef } from '@wordpress/element';
+import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
/**
@@ -26,7 +26,12 @@ import {
Header,
HeaderControlWrapper,
} from './styles/box-control-styles';
-import { DEFAULT_VALUES, isValuesMixed } from './utils';
+import {
+ DEFAULT_VALUES,
+ DEFAULT_VISUALIZER_VALUES,
+ isValuesMixed,
+ isValuesDefined,
+} from './utils';
import { useControlledState } from '../utils/hooks';
const defaultInputProps = {
@@ -43,17 +48,21 @@ export default function BoxControl( {
id: idProp,
inputProps = defaultInputProps,
onChange = noop,
+ onChangeShowVisualizer = noop,
label = __( 'Box Control' ),
- values: valuesProp = DEFAULT_VALUES,
+ values: valuesProp,
units,
} ) {
const [ values, setValues ] = useControlledState( valuesProp );
+ const inputValues = values || DEFAULT_VALUES;
+ const hasInitialValue = isValuesDefined( valuesProp );
- const [ isDirty, setIsDirty ] = useState( false );
- const [ isLinked, setIsLinked ] = useState( ! isValuesMixed( values ) );
- const [ side, setSide ] = useState( isLinked ? 'all' : 'top' );
+ const [ isDirty, setIsDirty ] = useState( hasInitialValue );
+ const [ isLinked, setIsLinked ] = useState(
+ ! hasInitialValue || ! isValuesMixed( inputValues )
+ );
- const initialValuesRef = useRef( values );
+ const [ side, setSide ] = useState( isLinked ? 'all' : 'top' );
const id = useUniqueId( idProp );
const headingId = `${ id }-heading`;
@@ -73,8 +82,16 @@ export default function BoxControl( {
setIsDirty( true );
};
+ const handleOnHoverOn = ( next = {} ) => {
+ onChangeShowVisualizer( { ...DEFAULT_VISUALIZER_VALUES, ...next } );
+ };
+
+ const handleOnHoverOff = ( next = {} ) => {
+ onChangeShowVisualizer( { ...DEFAULT_VISUALIZER_VALUES, ...next } );
+ };
+
const handleOnReset = () => {
- const initialValues = initialValuesRef.current;
+ const initialValues = DEFAULT_VALUES;
onChange( initialValues );
setValues( initialValues );
@@ -85,9 +102,11 @@ export default function BoxControl( {
...inputProps,
onChange: handleOnChange,
onFocus: handleOnFocus,
+ onHoverOn: handleOnHoverOn,
+ onHoverOff: handleOnHoverOff,
isLinked,
units,
- values,
+ values: inputValues,
};
return (
diff --git a/packages/components/src/box-control/input-controls.js b/packages/components/src/box-control/input-controls.js
index 36242e1e2a0f26..0177052151273f 100644
--- a/packages/components/src/box-control/input-controls.js
+++ b/packages/components/src/box-control/input-controls.js
@@ -13,6 +13,8 @@ import { LayoutContainer, Layout } from './styles/box-control-styles';
export default function BoxInputControls( {
onChange = noop,
onFocus = noop,
+ onHoverOn = noop,
+ onHoverOff = noop,
values,
...props
} ) {
@@ -20,6 +22,14 @@ export default function BoxInputControls( {
onFocus( event, { side } );
};
+ const createHandleOnHoverOn = ( side ) => () => {
+ onHoverOn( { [ side ]: true } );
+ };
+
+ const createHandleOnHoverOff = ( side ) => () => {
+ onHoverOff( { [ side ]: false } );
+ };
+
const handleOnChange = ( nextValues ) => {
onChange( nextValues );
};
@@ -69,6 +79,8 @@ export default function BoxInputControls( {
value={ top }
onChange={ createHandleOnChange( 'top' ) }
onFocus={ createHandleOnFocus( 'top' ) }
+ onHoverOn={ createHandleOnHoverOn( 'top' ) }
+ onHoverOff={ createHandleOnHoverOff( 'top' ) }
label={ LABELS.top }
/>
diff --git a/packages/components/src/box-control/stories/index.js b/packages/components/src/box-control/stories/index.js
index 47e8520eeb9fb9..60205d435fb944 100644
--- a/packages/components/src/box-control/stories/index.js
+++ b/packages/components/src/box-control/stories/index.js
@@ -28,6 +28,8 @@ function DemoExample() {
left: '10px',
} );
+ const [ showVisualizer, setShowVisualizer ] = useState( {} );
+
return (
@@ -36,13 +38,17 @@ function DemoExample() {
label="Padding"
values={ values }
onChange={ setValues }
+ onChangeShowVisualizer={ setShowVisualizer }
/>
-
+
diff --git a/packages/components/src/box-control/unit-control.js b/packages/components/src/box-control/unit-control.js
index d5842da2168841..1211452f7d3155 100644
--- a/packages/components/src/box-control/unit-control.js
+++ b/packages/components/src/box-control/unit-control.js
@@ -1,3 +1,9 @@
+/**
+ * External dependencies
+ */
+import { noop } from 'lodash';
+import { useHover } from 'react-use-gesture';
+
/**
* Internal dependencies
*/
@@ -8,12 +14,22 @@ export default function BoxUnitControl( {
isFirst,
isLast,
isOnly,
+ onHoverOn = noop,
+ onHoverOff = noop,
label,
value,
...props
} ) {
+ const bindHoverGesture = useHover( ( { event, ...state } ) => {
+ if ( state.hovering ) {
+ onHoverOn( event, state );
+ } else {
+ onHoverOff( event, state );
+ }
+ } );
+
return (
-
+
-
+
{ children }
);
}
-function Sides( { values } ) {
+function Sides( { showValues = DEFAULT_VISUALIZER_VALUES, values } ) {
const { top, right, bottom, left } = values;
return (
<>
-
-
-
-
+
+
+
+
>
);
}
-function Top( { value } ) {
+function Top( { isVisible = false, value } ) {
const height = value;
const animationProps = useSideAnimation( height );
+ const isActive = animationProps.isActive || isVisible;
- return ;
+ return ;
}
-function Right( { value } ) {
+function Right( { isVisible = false, value } ) {
const width = value;
const animationProps = useSideAnimation( width );
+ const isActive = animationProps.isActive || isVisible;
- return ;
+ return ;
}
-function Bottom( { value } ) {
+function Bottom( { isVisible = false, value } ) {
const height = value;
const animationProps = useSideAnimation( height );
+ const isActive = animationProps.isActive || isVisible;
- return ;
+ return ;
}
-function Left( { value } ) {
+function Left( { isVisible = false, value } ) {
const width = value;
const animationProps = useSideAnimation( width );
+ const isActive = animationProps.isActive || isVisible;
- return ;
+ return ;
}
/**
diff --git a/packages/e2e-tests/specs/editor/blocks/image.test.js b/packages/e2e-tests/specs/editor/blocks/image.test.js
index bb9127494e306e..3e93c7a340fdaa 100644
--- a/packages/e2e-tests/specs/editor/blocks/image.test.js
+++ b/packages/e2e-tests/specs/editor/blocks/image.test.js
@@ -98,15 +98,4 @@ describe( 'Image', () => {
await page.evaluate( () => document.activeElement.innerHTML )
).toBe( '12' );
} );
-
- it( 'should keep caption after upload', async () => {
- await insertBlock( 'Image' );
- await page.keyboard.type( '1' );
- const filename1 = await upload( '.wp-block-image input[type="file"]' );
-
- const regex = new RegExp(
- `\\s*\\s*`
- );
- expect( await getEditedPostContent() ).toMatch( regex );
- } );
} );
diff --git a/packages/e2e-tests/specs/editor/plugins/templates.test.js b/packages/e2e-tests/specs/editor/plugins/templates.test.js
index 5983fb0390a313..a738ffae94da2a 100644
--- a/packages/e2e-tests/specs/editor/plugins/templates.test.js
+++ b/packages/e2e-tests/specs/editor/plugins/templates.test.js
@@ -37,7 +37,6 @@ describe( 'templates', () => {
// re-added after saving and reloading the editor.
await page.click( '.editor-post-title__input' );
await page.keyboard.press( 'ArrowDown' );
- await pressKeyWithModifier( 'shift', 'Tab' );
await page.keyboard.press( 'Backspace' );
await saveDraft();
await page.reload();
@@ -50,7 +49,6 @@ describe( 'templates', () => {
// re-added after saving and reloading the editor.
await page.type( '.editor-post-title__input', 'My Empty Book' );
await page.keyboard.press( 'ArrowDown' );
- await pressKeyWithModifier( 'shift', 'Tab' );
await pressKeyWithModifier( 'primary', 'A' );
await page.keyboard.press( 'Backspace' );
await saveDraft();
@@ -102,7 +100,6 @@ describe( 'templates', () => {
await page.type( '.editor-post-title__input', 'My Image Format' );
await clickBlockAppender();
await page.keyboard.press( 'Backspace' );
- await pressKeyWithModifier( 'shift', 'Tab' );
await page.keyboard.press( 'Backspace' );
await saveDraft();
await page.reload();
diff --git a/packages/e2e-tests/specs/editor/various/adding-blocks.test.js b/packages/e2e-tests/specs/editor/various/adding-blocks.test.js
index 50489e406442f0..6e222ff24e5b79 100644
--- a/packages/e2e-tests/specs/editor/various/adding-blocks.test.js
+++ b/packages/e2e-tests/specs/editor/various/adding-blocks.test.js
@@ -8,7 +8,6 @@ import {
pressKeyTimes,
setBrowserViewport,
closeGlobalBlockInserter,
- pressKeyWithModifier,
} from '@wordpress/e2e-test-utils';
/** @typedef {import('puppeteer').ElementHandle} ElementHandle */
@@ -67,7 +66,6 @@ describe( 'adding blocks', () => {
await page.keyboard.press( 'Enter' );
expect( await getEditedPostContent() ).toMatchSnapshot();
await page.keyboard.press( 'Backspace' );
- await pressKeyWithModifier( 'shift', 'Tab' );
await page.keyboard.press( 'Backspace' );
expect( await getEditedPostContent() ).toMatchSnapshot();
diff --git a/packages/e2e-tests/specs/editor/various/block-deletion.test.js b/packages/e2e-tests/specs/editor/various/block-deletion.test.js
index 207d06869da6c1..00027d94137cf2 100644
--- a/packages/e2e-tests/specs/editor/various/block-deletion.test.js
+++ b/packages/e2e-tests/specs/editor/various/block-deletion.test.js
@@ -118,9 +118,6 @@ describe( 'block deletion -', () => {
await page.click(
'.wp-block[data-type="core/image"] .components-placeholder__label'
);
- await page.click(
- '.wp-block[data-type="core/image"] .components-placeholder__label'
- );
await page.keyboard.press( 'Backspace' );
expect( await getEditedPostContent() ).toMatchSnapshot();
@@ -199,7 +196,6 @@ describe( 'deleting all blocks', () => {
// Add and remove a block.
await insertBlock( 'Image' );
- await pressKeyWithModifier( 'shift', 'Tab' );
await page.keyboard.press( 'Backspace' );
// Verify there is no selected block.
diff --git a/packages/editor/src/components/provider/index.js b/packages/editor/src/components/provider/index.js
index a0b03cd64bb3b8..57cfb4af84da4d 100644
--- a/packages/editor/src/components/provider/index.js
+++ b/packages/editor/src/components/provider/index.js
@@ -118,6 +118,7 @@ class EditorProvider extends Component {
'__experimentalDisableCustomLineHeight',
'__experimentalEnableCustomSpacing',
'__experimentalEnableLegacyWidgetBlock',
+ '__experimentalEnableLinkColor',
'__experimentalEnableFullSiteEditing',
'__experimentalEnableFullSiteEditingDemo',
'__experimentalFeatures',