diff --git a/lib/block-supports/typography.php b/lib/block-supports/typography.php
index 2126aaf847fdec..b1adaf1a679b81 100644
--- a/lib/block-supports/typography.php
+++ b/lib/block-supports/typography.php
@@ -328,8 +328,17 @@ function gutenberg_get_typography_value_and_unit( $raw_value, $options = array()
$unit = $options['coerce_to'];
}
+ /*
+ * No calculation is required if swapping between em and rem yet,
+ * since we assume a root size value. Later we might like to differentiate between
+ * :root font size (rem) and parent element font size (em) relativity.
+ */
+ if ( ( 'em' === $options['coerce_to'] || 'rem' === $options['coerce_to'] ) && ( 'em' === $unit || 'rem' === $unit ) ) {
+ $unit = $options['coerce_to'];
+ }
+
return array(
- 'value' => $value,
+ 'value' => round( $value, 3 ),
'unit' => $unit,
);
}
@@ -357,14 +366,16 @@ function gutenberg_get_computed_fluid_typography_value( $args = array() ) {
$minimum_font_size_raw = isset( $args['minimum_font_size'] ) ? $args['minimum_font_size'] : null;
$scale_factor = isset( $args['scale_factor'] ) ? $args['scale_factor'] : null;
- // Grab the minimum font size and normalize it in order to use the value for calculations.
+ // Normalizes the minimum font size in order to use the value for calculations.
$minimum_font_size = gutenberg_get_typography_value_and_unit( $minimum_font_size_raw );
- // We get a 'preferred' unit to keep units consistent when calculating,
- // otherwise the result will not be accurate.
+ /*
+ * We get a 'preferred' unit to keep units consistent when calculating,
+ * otherwise the result will not be accurate.
+ */
$font_size_unit = isset( $minimum_font_size['unit'] ) ? $minimum_font_size['unit'] : 'rem';
- // Grab the maximum font size and normalize it in order to use the value for calculations.
+ // Grabs the maximum font size and normalize it in order to use the value for calculations.
$maximum_font_size = gutenberg_get_typography_value_and_unit(
$maximum_font_size_raw,
array(
@@ -372,12 +383,12 @@ function gutenberg_get_computed_fluid_typography_value( $args = array() ) {
)
);
- // Protect against unsupported units.
+ // Checks for mandatory min and max sizes, and protects against unsupported units.
if ( ! $maximum_font_size || ! $minimum_font_size ) {
return null;
}
- // Use rem for accessible fluid target font scaling.
+ // Uses rem for accessible fluid target font scaling.
$minimum_font_size_rem = gutenberg_get_typography_value_and_unit(
$minimum_font_size_raw,
array(
@@ -403,8 +414,9 @@ function gutenberg_get_computed_fluid_typography_value( $args = array() ) {
// Borrowed from https://websemantics.uk/tools/responsive-font-calculator/.
$view_port_width_offset = round( $minimum_viewport_width['value'] / 100, 3 ) . $font_size_unit;
$linear_factor = 100 * ( ( $maximum_font_size['value'] - $minimum_font_size['value'] ) / ( $maximum_viewport_width['value'] - $minimum_viewport_width['value'] ) );
- $linear_factor = round( $linear_factor, 3 ) * $scale_factor;
- $fluid_target_font_size = implode( '', $minimum_font_size_rem ) . " + ((1vw - $view_port_width_offset) * $linear_factor)";
+ $linear_factor_scaled = round( $linear_factor * $scale_factor, 3 );
+ $linear_factor_scaled = empty( $linear_factor_scaled ) ? 1 : $linear_factor_scaled;
+ $fluid_target_font_size = implode( '', $minimum_font_size_rem ) . " + ((1vw - $view_port_width_offset) * $linear_factor_scaled)";
return "clamp($minimum_font_size_raw, $fluid_target_font_size, $maximum_font_size_raw)";
}
@@ -437,7 +449,7 @@ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_ty
return $preset['size'];
}
- // Check if fluid font sizes are activated.
+ // Checks if fluid font sizes are activated.
$typography_settings = gutenberg_get_global_settings( array( 'typography' ) );
$should_use_fluid_typography = isset( $typography_settings['fluid'] ) && true === $typography_settings['fluid'] ? true : $should_use_fluid_typography;
@@ -451,6 +463,7 @@ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_ty
$default_minimum_font_size_factor = 0.75;
$default_maximum_font_size_factor = 1.5;
$default_scale_factor = 1;
+ $default_minimum_font_size_limit = '14px';
// Font sizes.
$fluid_font_size_settings = isset( $preset['fluid'] ) ? $preset['fluid'] : null;
@@ -472,13 +485,48 @@ function gutenberg_get_typography_font_size_value( $preset, $should_use_fluid_ty
return $preset['size'];
}
- // If no fluid min or max font sizes are available, create some using min/max font size factors.
+ // If no fluid max font size is available, create one using max font size factor.
+ if ( ! $maximum_font_size_raw ) {
+ $maximum_font_size_raw = round( $preferred_size['value'] * $default_maximum_font_size_factor, 3 ) . $preferred_size['unit'];
+ }
+
+ // If no fluid min font size is available, create one using min font size factor.
if ( ! $minimum_font_size_raw ) {
- $minimum_font_size_raw = ( $preferred_size['value'] * $default_minimum_font_size_factor ) . $preferred_size['unit'];
+ $minimum_font_size_raw = round( $preferred_size['value'] * $default_minimum_font_size_factor, 3 ) . $preferred_size['unit'];
}
- if ( ! $maximum_font_size_raw ) {
- $maximum_font_size_raw = ( $preferred_size['value'] * $default_maximum_font_size_factor ) . $preferred_size['unit'];
+ // Parses the minimum font size limit, so we can perform checks using it.
+ $minimum_font_size_limit = gutenberg_get_typography_value_and_unit(
+ $default_minimum_font_size_limit,
+ array(
+ 'coerce_to' => $preferred_size['unit'],
+ )
+ );
+
+ if ( ! empty( $minimum_font_size_limit ) ) {
+ /*
+ * If a minimum size was not passed to this function
+ * and the user-defined font size is lower than $minimum_font_size_limit,
+ * then uses the user-defined font size as the minimum font-size.
+ */
+ if ( ! isset( $fluid_font_size_settings['min'] ) && $preferred_size['value'] < $minimum_font_size_limit['value'] ) {
+ $minimum_font_size_raw = implode( '', $preferred_size );
+ } else {
+ $minimum_font_size_parsed = gutenberg_get_typography_value_and_unit(
+ $minimum_font_size_raw,
+ array(
+ 'coerce_to' => $preferred_size['unit'],
+ )
+ );
+
+ /*
+ * If the passed or calculated minimum font size is lower than $minimum_font_size_limit
+ * use $minimum_font_size_limit instead.
+ */
+ if ( ! empty( $minimum_font_size_parsed ) && $minimum_font_size_parsed['value'] < $minimum_font_size_limit['value'] ) {
+ $minimum_font_size_raw = implode( '', $minimum_font_size_limit );
+ }
+ }
}
$fluid_font_size_value = gutenberg_get_computed_fluid_typography_value(
diff --git a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php
index 6d63556cb1e290..37464485adbb81 100644
--- a/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php
+++ b/lib/compat/wordpress-6.1/class-wp-theme-json-6-1.php
@@ -19,10 +19,14 @@ class WP_Theme_JSON_6_1 extends WP_Theme_JSON_6_0 {
* Define which defines which pseudo selectors are enabled for
* which elements.
* Note: this will effect both top level and block level elements.
+ *
+ * The order of the selectors should be: visited, hover, focus, active.
+ * This is to ensure that 'visited' has the lowest specificity
+ * and the other selectors can always overwrite it.
*/
const VALID_ELEMENT_PSEUDO_SELECTORS = array(
- 'link' => array( ':hover', ':focus', ':active', ':visited' ),
- 'button' => array( ':hover', ':focus', ':active', ':visited' ),
+ 'link' => array( ':visited', ':hover', ':focus', ':active' ),
+ 'button' => array( ':visited', ':hover', ':focus', ':active' ),
);
/**
@@ -688,6 +692,51 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets'
return $stylesheet;
}
+ /**
+ * Returns a filtered declarations array if there is a separator block with only a background
+ * style defined in theme.json by adding a color attribute to reflect the changes in the front.
+ *
+ * @param array $declarations List of declarations.
+ *
+ * @return array $declarations List of declarations filtered.
+ */
+ private static function update_separator_declarations( $declarations ) {
+ $background_matches = array_values(
+ array_filter(
+ $declarations,
+ function( $declaration ) {
+ return 'background-color' === $declaration['name'];
+ }
+ )
+ );
+ if ( ! empty( $background_matches && isset( $background_matches[0]['value'] ) ) ) {
+ $border_color_matches = array_values(
+ array_filter(
+ $declarations,
+ function( $declaration ) {
+ return 'border-color' === $declaration['name'];
+ }
+ )
+ );
+ $text_color_matches = array_values(
+ array_filter(
+ $declarations,
+ function( $declaration ) {
+ return 'color' === $declaration['name'];
+ }
+ )
+ );
+ if ( empty( $border_color_matches ) && empty( $text_color_matches ) ) {
+ $declarations[] = array(
+ 'name' => 'color',
+ 'value' => $background_matches[0]['value'],
+ );
+ }
+ }
+
+ return $declarations;
+ }
+
/**
* Gets the CSS rules for a particular block from theme.json.
*
@@ -776,6 +825,11 @@ function( $pseudo_selector ) use ( $selector ) {
}
}
+ // Update declarations if there are separators with only background color defined.
+ if ( '.wp-block-separator' === $selector ) {
+ $declarations = static::update_separator_declarations( $declarations );
+ }
+
// 2. Generate and append the rules that use the general selector.
$block_rules .= static::to_ruleset( $selector, $declarations );
diff --git a/packages/block-editor/src/components/block-popover/style.scss b/packages/block-editor/src/components/block-popover/style.scss
index 1ed4774a56c010..8bb5a42be6ede3 100644
--- a/packages/block-editor/src/components/block-popover/style.scss
+++ b/packages/block-editor/src/components/block-popover/style.scss
@@ -21,7 +21,7 @@
}
// Enable pointer events for the toolbar's content.
- &:not(.block-editor-block-popover__inbetween) .components-popover__content {
+ &:not(.block-editor-block-popover__inbetween, .block-editor-block-list__block-side-inserter-popover) .components-popover__content {
* {
pointer-events: all;
}
diff --git a/packages/block-editor/src/components/block-tools/selected-block-popover.js b/packages/block-editor/src/components/block-tools/selected-block-popover.js
index 530a3b7bdc263d..4b9a91aacc3484 100644
--- a/packages/block-editor/src/components/block-tools/selected-block-popover.js
+++ b/packages/block-editor/src/components/block-tools/selected-block-popover.js
@@ -21,6 +21,7 @@ import BlockContextualToolbar from './block-contextual-toolbar';
import { store as blockEditorStore } from '../../store';
import BlockPopover from '../block-popover';
import useBlockToolbarPopoverProps from './use-block-toolbar-popover-props';
+import Inserter from '../inserter';
function selector( select ) {
const {
@@ -120,45 +121,85 @@ function SelectedBlockPopover( {
clientId,
} );
- if ( ! shouldShowBreadcrumb && ! shouldShowContextualToolbar ) {
+ if (
+ ! shouldShowBreadcrumb &&
+ ! shouldShowContextualToolbar &&
+ ! showEmptyBlockSideInserter
+ ) {
return null;
}
return (
-
- { shouldShowContextualToolbar && (
- {
- initialToolbarItemIndexRef.current = index;
- } }
- // Resets the index whenever the active block changes so
- // this is not persisted. See https://github.com/WordPress/gutenberg/pull/25760#issuecomment-717906169
- key={ clientId }
- />
+ <>
+ { showEmptyBlockSideInserter && (
+
+
+
+
+
) }
- { shouldShowBreadcrumb && (
-
+ { ( shouldShowBreadcrumb || shouldShowContextualToolbar ) && (
+
+ { shouldShowContextualToolbar && (
+ {
+ initialToolbarItemIndexRef.current = index;
+ } }
+ // Resets the index whenever the active block changes so
+ // this is not persisted. See https://github.com/WordPress/gutenberg/pull/25760#issuecomment-717906169
+ key={ clientId }
+ />
+ ) }
+ { shouldShowBreadcrumb && (
+
+ ) }
+
) }
-
+ >
);
}
diff --git a/packages/block-editor/src/components/block-tools/style.scss b/packages/block-editor/src/components/block-tools/style.scss
index 112178ea0ae6e7..ea6cba19639cdb 100644
--- a/packages/block-editor/src/components/block-tools/style.scss
+++ b/packages/block-editor/src/components/block-tools/style.scss
@@ -42,7 +42,16 @@
left: calc(50% - #{$button-size-small * 0.5});
}
+.block-editor-block-list__block-side-inserter-popover .components-popover__content > div {
+ pointer-events: none;
+
+ > * {
+ pointer-events: all;
+ }
+}
+
// Sibling inserter / "inbetweenserter".
+.block-editor-block-list__empty-block-inserter,
.block-editor-default-block-appender,
.block-editor-block-list__insertion-point-inserter {
.block-editor-inserter__toggle.components-button.has-icon {
diff --git a/packages/block-editor/src/components/default-block-appender/style.scss b/packages/block-editor/src/components/default-block-appender/style.scss
index 015743207898d8..ca93381349c0ce 100644
--- a/packages/block-editor/src/components/default-block-appender/style.scss
+++ b/packages/block-editor/src/components/default-block-appender/style.scss
@@ -34,6 +34,7 @@
// The black plus that shows up on the right side of an empty paragraph block, or the initial appender
// that exists only on empty documents.
+.block-editor-block-list__empty-block-inserter.block-editor-block-list__empty-block-inserter,
.block-editor-default-block-appender .block-editor-inserter {
position: absolute;
top: 0;
diff --git a/packages/block-editor/src/components/font-sizes/fluid-utils.js b/packages/block-editor/src/components/font-sizes/fluid-utils.js
index 7294a83da106f8..2c6540f89d0494 100644
--- a/packages/block-editor/src/components/font-sizes/fluid-utils.js
+++ b/packages/block-editor/src/components/font-sizes/fluid-utils.js
@@ -10,6 +10,7 @@ const DEFAULT_MINIMUM_VIEWPORT_WIDTH = '768px';
const DEFAULT_SCALE_FACTOR = 1;
const DEFAULT_MINIMUM_FONT_SIZE_FACTOR = 0.75;
const DEFAULT_MAXIMUM_FONT_SIZE_FACTOR = 1.5;
+const DEFAULT_MINIMUM_FONT_SIZE_LIMIT = '14px';
/**
* Computes a fluid font-size value that uses clamp(). A minimum and maxinmum
@@ -53,11 +54,20 @@ export function getComputedFluidTypographyValue( {
scaleFactor = DEFAULT_SCALE_FACTOR,
minimumFontSizeFactor = DEFAULT_MINIMUM_FONT_SIZE_FACTOR,
maximumFontSizeFactor = DEFAULT_MAXIMUM_FONT_SIZE_FACTOR,
+ minimumFontSizeLimit = DEFAULT_MINIMUM_FONT_SIZE_LIMIT,
} ) {
- // Calculate missing minimumFontSize and maximumFontSize from
- // defaultFontSize if provided.
- if ( fontSize && ( ! minimumFontSize || ! maximumFontSize ) ) {
- // Parse default font size.
+ /*
+ * Caches minimumFontSize in minimumFontSizeValue
+ * so we can check if minimumFontSize exists later.
+ */
+ let minimumFontSizeValue = minimumFontSize;
+
+ /*
+ * Calculates missing minimumFontSize and maximumFontSize from
+ * defaultFontSize if provided.
+ */
+ if ( fontSize ) {
+ // Parses default font size.
const fontSizeParsed = getTypographyValueAndUnit( fontSize );
// Protect against invalid units.
@@ -66,46 +76,95 @@ export function getComputedFluidTypographyValue( {
}
// If no minimumFontSize is provided, derive using min scale factor.
- if ( ! minimumFontSize ) {
- minimumFontSize =
- fontSizeParsed.value * minimumFontSizeFactor +
- fontSizeParsed.unit;
+ if ( ! minimumFontSizeValue ) {
+ minimumFontSizeValue =
+ roundToPrecision(
+ fontSizeParsed.value * minimumFontSizeFactor,
+ 3
+ ) + fontSizeParsed.unit;
+ }
+
+ // Parses the minimum font size limit, so we can perform checks using it.
+ const minimumFontSizeLimitParsed = getTypographyValueAndUnit(
+ minimumFontSizeLimit,
+ {
+ coerceTo: fontSizeParsed.unit,
+ }
+ );
+
+ if ( !! minimumFontSizeLimitParsed?.value ) {
+ /*
+ * If a minimum size was not passed to this function
+ * and the user-defined font size is lower than `minimumFontSizeLimit`,
+ * then uses the user-defined font size as the minimum font-size.
+ */
+ if (
+ ! minimumFontSize &&
+ fontSizeParsed?.value < minimumFontSizeLimitParsed?.value
+ ) {
+ minimumFontSizeValue = `${ fontSizeParsed.value }${ fontSizeParsed.unit }`;
+ } else {
+ const minimumFontSizeParsed = getTypographyValueAndUnit(
+ minimumFontSizeValue,
+ {
+ coerceTo: fontSizeParsed.unit,
+ }
+ );
+
+ /*
+ * Otherwise, if the passed or calculated minimum font size is lower than `minimumFontSizeLimit`
+ * use `minimumFontSizeLimit` instead.
+ */
+ if (
+ !! minimumFontSizeParsed?.value &&
+ minimumFontSizeParsed.value <
+ minimumFontSizeLimitParsed.value
+ ) {
+ minimumFontSizeValue = `${ minimumFontSizeLimitParsed.value }${ minimumFontSizeLimitParsed.unit }`;
+ }
+ }
}
// If no maximumFontSize is provided, derive using max scale factor.
if ( ! maximumFontSize ) {
maximumFontSize =
- fontSizeParsed.value * maximumFontSizeFactor +
- fontSizeParsed.unit;
+ roundToPrecision(
+ fontSizeParsed.value * maximumFontSizeFactor,
+ 3
+ ) + fontSizeParsed.unit;
}
}
// Return early if one of the provided inputs is not provided.
- if ( ! minimumFontSize || ! maximumFontSize ) {
+ if ( ! minimumFontSizeValue || ! maximumFontSize ) {
return null;
}
// Grab the minimum font size and normalize it in order to use the value for calculations.
- const minimumFontSizeParsed = getTypographyValueAndUnit( minimumFontSize );
+ const minimumFontSizeParsed =
+ getTypographyValueAndUnit( minimumFontSizeValue );
// We get a 'preferred' unit to keep units consistent when calculating,
// otherwise the result will not be accurate.
const fontSizeUnit = minimumFontSizeParsed?.unit || 'rem';
- // Grab the maximum font size and normalize it in order to use the value for calculations.
+ // Grabs the maximum font size and normalize it in order to use the value for calculations.
const maximumFontSizeParsed = getTypographyValueAndUnit( maximumFontSize, {
coerceTo: fontSizeUnit,
} );
- // Protect against unsupported units.
+ // Checks for mandatory min and max sizes, and protects against unsupported units.
if ( ! minimumFontSizeParsed || ! maximumFontSizeParsed ) {
return null;
}
- // Use rem for accessible fluid target font scaling.
- const minimumFontSizeRem = getTypographyValueAndUnit( minimumFontSize, {
- coerceTo: 'rem',
- } );
+ // Uses rem for accessible fluid target font scaling.
+ const minimumFontSizeRem = getTypographyValueAndUnit(
+ minimumFontSizeValue,
+ {
+ coerceTo: 'rem',
+ }
+ );
// Viewport widths defined for fluid typography. Normalize units
const maximumViewPortWidthParsed = getTypographyValueAndUnit(
@@ -133,17 +192,20 @@ export function getComputedFluidTypographyValue( {
3
);
- const viewPortWidthOffset = minViewPortWidthOffsetValue + fontSizeUnit;
- let linearFactor =
+ const viewPortWidthOffset =
+ roundToPrecision( minViewPortWidthOffsetValue, 3 ) + fontSizeUnit;
+ const linearFactor =
100 *
( ( maximumFontSizeParsed.value - minimumFontSizeParsed.value ) /
( maximumViewPortWidthParsed.value -
minumumViewPortWidthParsed.value ) );
- linearFactor = roundToPrecision( linearFactor, 3 ) || 1;
- const linearFactorScaled = linearFactor * scaleFactor;
+ const linearFactorScaled = roundToPrecision(
+ ( linearFactor || 1 ) * scaleFactor,
+ 3
+ );
const fluidTargetFontSize = `${ minimumFontSizeRem.value }${ minimumFontSizeRem.unit } + ((1vw - ${ viewPortWidthOffset }) * ${ linearFactorScaled })`;
- return `clamp(${ minimumFontSize }, ${ fluidTargetFontSize }, ${ maximumFontSize })`;
+ return `clamp(${ minimumFontSizeValue }, ${ fluidTargetFontSize }, ${ maximumFontSize })`;
}
/**
@@ -199,8 +261,20 @@ export function getTypographyValueAndUnit( rawValue, options = {} ) {
unit = coerceTo;
}
+ /*
+ * No calculation is required if swapping between em and rem yet,
+ * since we assume a root size value. Later we might like to differentiate between
+ * :root font size (rem) and parent element font size (em) relativity.
+ */
+ if (
+ ( 'em' === coerceTo || 'rem' === coerceTo ) &&
+ ( 'em' === unit || 'rem' === unit )
+ ) {
+ unit = coerceTo;
+ }
+
return {
- value: returnValue,
+ value: roundToPrecision( returnValue, 3 ),
unit,
};
}
@@ -215,7 +289,8 @@ export function getTypographyValueAndUnit( rawValue, options = {} ) {
* @return {number|undefined} Value rounded to standard precision.
*/
export function roundToPrecision( value, digits = 3 ) {
+ const base = Math.pow( 10, digits );
return Number.isFinite( value )
- ? parseFloat( value.toFixed( digits ) )
+ ? parseFloat( Math.round( value * base ) / base )
: undefined;
}
diff --git a/packages/block-editor/src/components/font-sizes/test/fluid-utils.js b/packages/block-editor/src/components/font-sizes/test/fluid-utils.js
index cd45c3593e1a48..aa268d04d7f1f2 100644
--- a/packages/block-editor/src/components/font-sizes/test/fluid-utils.js
+++ b/packages/block-editor/src/components/font-sizes/test/fluid-utils.js
@@ -33,7 +33,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
fontSize: '30px',
} );
expect( fluidTypographyValues ).toBe(
- 'clamp(22.5px, 1.40625rem + ((1vw - 7.68px) * 2.704), 45px)'
+ 'clamp(22.5px, 1.406rem + ((1vw - 7.68px) * 2.704), 45px)'
);
} );
@@ -42,7 +42,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
fontSize: '30px',
} );
expect( fluidTypographyValues ).toBe(
- 'clamp(22.5px, 1.40625rem + ((1vw - 7.68px) * 2.704), 45px)'
+ 'clamp(22.5px, 1.406rem + ((1vw - 7.68px) * 2.704), 45px)'
);
} );
@@ -53,7 +53,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
maximumViewPortWidth: '1000px',
} );
expect( fluidTypographyValues ).toBe(
- 'clamp(22.5px, 1.40625rem + ((1vw - 5px) * 4.5), 45px)'
+ 'clamp(22.5px, 1.406rem + ((1vw - 5px) * 4.5), 45px)'
);
} );
@@ -63,7 +63,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
scaleFactor: '2',
} );
expect( fluidTypographyValues ).toBe(
- 'clamp(22.5px, 1.40625rem + ((1vw - 7.68px) * 5.408), 45px)'
+ 'clamp(22.5px, 1.406rem + ((1vw - 7.68px) * 5.409), 45px)'
);
} );
@@ -74,7 +74,7 @@ describe( 'getComputedFluidTypographyValue()', () => {
maximumFontSizeFactor: '2',
} );
expect( fluidTypographyValues ).toBe(
- 'clamp(15px, 0.9375rem + ((1vw - 7.68px) * 5.409), 60px)'
+ 'clamp(15px, 0.938rem + ((1vw - 7.68px) * 5.409), 60px)'
);
} );
diff --git a/packages/block-editor/src/components/inner-blocks/index.js b/packages/block-editor/src/components/inner-blocks/index.js
index 4105d7291957ed..8c27ca9ac881a3 100644
--- a/packages/block-editor/src/components/inner-blocks/index.js
+++ b/packages/block-editor/src/components/inner-blocks/index.js
@@ -150,6 +150,7 @@ const ForwardedInnerBlocks = forwardRef( ( props, ref ) => {
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/inner-blocks/README.md
*/
export function useInnerBlocksProps( props = {}, options = {} ) {
+ const { __unstableDisableDropZone } = options;
const { clientId } = useBlockEditContext();
const isSmallScreen = useViewportMatch( 'medium', '<' );
const { __experimentalCaptureToolbars, hasOverlay } = useSelect(
@@ -185,11 +186,13 @@ export function useInnerBlocksProps( props = {}, options = {} ) {
[ clientId, isSmallScreen ]
);
+ const blockDropZoneRef = useBlockDropZone( {
+ rootClientId: clientId,
+ } );
+
const ref = useMergeRefs( [
props.ref,
- useBlockDropZone( {
- rootClientId: clientId,
- } ),
+ __unstableDisableDropZone ? null : blockDropZoneRef,
] );
const innerBlocksProps = {
diff --git a/packages/block-library/src/cover/edit/index.js b/packages/block-library/src/cover/edit/index.js
index ee9536aa1ed2b5..8068fb48f52a10 100644
--- a/packages/block-library/src/cover/edit/index.js
+++ b/packages/block-library/src/cover/edit/index.js
@@ -194,7 +194,9 @@ function CoverEdit( {
className: 'wp-block-cover__inner-container',
},
{
- template: innerBlocksTemplate,
+ // Avoid template sync when the `templateLock` value is `all` or `contentOnly`.
+ // See: https://github.com/WordPress/gutenberg/pull/45632
+ template: ! hasInnerBlocks ? innerBlocksTemplate : undefined,
templateInsertUpdatesSelection: true,
allowedBlocks,
templateLock,
diff --git a/packages/block-library/src/list-item/edit.js b/packages/block-library/src/list-item/edit.js
index a52fea8e044f9e..d0548490c49717 100644
--- a/packages/block-library/src/list-item/edit.js
+++ b/packages/block-library/src/list-item/edit.js
@@ -66,6 +66,7 @@ export default function ListItemEdit( {
const blockProps = useBlockProps( { ref: useCopy( clientId ) } );
const innerBlocksProps = useInnerBlocksProps( blockProps, {
allowedBlocks: [ 'core/list' ],
+ __unstableDisableDropZone: true,
} );
const useEnterRef = useEnter( { content, clientId } );
const useSpaceRef = useSpace( clientId );
diff --git a/packages/block-library/src/list/utils.js b/packages/block-library/src/list/utils.js
index 9603c1d08e0f01..a80ce456e29ab0 100644
--- a/packages/block-library/src/list/utils.js
+++ b/packages/block-library/src/list/utils.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
-import { createBlock } from '@wordpress/blocks';
+import { createBlock, rawHandler } from '@wordpress/blocks';
export function createListBlockFromDOMElement( listElement ) {
const listAttributes = {
@@ -70,15 +70,7 @@ export function migrateToListV2( attributes ) {
list.setAttribute( 'type', type );
}
- const listBlock = createListBlockFromDOMElement( list );
+ const [ listBlock ] = rawHandler( { HTML: list.outerHTML } );
- const { values: omittedValues, ...restAttributes } = attributes;
-
- return [
- {
- ...restAttributes,
- ...listBlock.attributes,
- },
- listBlock.innerBlocks,
- ];
+ return [ listBlock.attributes, listBlock.innerBlocks ];
}
diff --git a/packages/block-library/src/page-list/edit.js b/packages/block-library/src/page-list/edit.js
index aa15f913ddfa93..71cbfa437a1f9a 100644
--- a/packages/block-library/src/page-list/edit.js
+++ b/packages/block-library/src/page-list/edit.js
@@ -52,50 +52,64 @@ export default function PageListEdit( { context, clientId } ) {
style: { ...context.style?.color },
} );
- return (
- <>
- { allowConvertToLinks && (
-
-
- { __( 'Edit' ) }
-
-
- ) }
- { allowConvertToLinks && isOpen && (
-
- ) }
- { ! hasResolvedPages && (
+ const getBlockContent = () => {
+ if ( ! hasResolvedPages ) {
+ return (
- ) }
+ );
+ }
- { hasResolvedPages && totalPages === null && (
+ if ( totalPages === null ) {
+ return (
{ __( 'Page List: Cannot retrieve Pages.' ) }
- ) }
+ );
+ }
- { totalPages === 0 && (
+ if ( totalPages === 0 ) {
+ return (
{ __( 'Page List: Cannot retrieve Pages.' ) }
- ) }
- { totalPages > 0 && (
+ );
+ }
+
+ if ( totalPages > 0 ) {
+ return (
+ );
+ }
+ };
+
+ return (
+ <>
+ { allowConvertToLinks && (
+
+
+ { __( 'Edit' ) }
+
+
) }
+ { allowConvertToLinks && isOpen && (
+
+ ) }
+
+ { getBlockContent() }
>
);
}
diff --git a/packages/block-library/src/post-featured-image/index.php b/packages/block-library/src/post-featured-image/index.php
index 495c8ec534a41c..40a7f41cd78ac3 100644
--- a/packages/block-library/src/post-featured-image/index.php
+++ b/packages/block-library/src/post-featured-image/index.php
@@ -29,11 +29,18 @@ function render_block_core_post_featured_image( $attributes, $content, $block )
$attr['alt'] = $post_title;
}
+ if ( ! empty( $attributes['height'] ) ) {
+ $extra_styles = "height:{$attributes['height']};";
+ if ( ! empty( $attributes['scale'] ) ) {
+ $extra_styles .= "object-fit:{$attributes['scale']};";
+ }
+ $attr['style'] = empty( $attr['style'] ) ? $extra_styles : $attr['style'] . $extra_styles;
+ }
+
$featured_image = get_the_post_thumbnail( $post_ID, $size_slug, $attr );
if ( ! $featured_image ) {
return '';
}
- $wrapper_attributes = get_block_wrapper_attributes();
if ( $is_link ) {
$link_target = $attributes['linkTarget'];
$rel = ! empty( $attributes['rel'] ) ? 'rel="' . esc_attr( $attributes['rel'] ) . '"' : '';
@@ -49,23 +56,9 @@ function render_block_core_post_featured_image( $attributes, $content, $block )
$featured_image = $featured_image . $overlay_markup;
}
- $has_width = ! empty( $attributes['width'] );
- $has_height = ! empty( $attributes['height'] );
- if ( ! $has_height && ! $has_width ) {
- return "{$featured_image}";
- }
-
- if ( $has_width ) {
- $wrapper_attributes = get_block_wrapper_attributes( array( 'style' => "width:{$attributes['width']};" ) );
- }
-
- if ( $has_height ) {
- $image_styles = "height:{$attributes['height']};";
- if ( ! empty( $attributes['scale'] ) ) {
- $image_styles .= "object-fit:{$attributes['scale']};";
- }
- $featured_image = str_replace( '
"width:{$attributes['width']};" ) );
return "{$featured_image}";
}
diff --git a/packages/block-library/src/table/editor.scss b/packages/block-library/src/table/editor.scss
index ca6cfc3d0da8cb..f1fbae335748c6 100644
--- a/packages/block-library/src/table/editor.scss
+++ b/packages/block-library/src/table/editor.scss
@@ -31,6 +31,7 @@
td,
th {
border: $border-width solid;
+ padding: 0.5em;
}
td.is-selected,
diff --git a/packages/block-library/src/table/style.scss b/packages/block-library/src/table/style.scss
index ffc7ad266c6f72..9721513a53eee0 100644
--- a/packages/block-library/src/table/style.scss
+++ b/packages/block-library/src/table/style.scss
@@ -11,6 +11,13 @@
width: 100%;
}
+ // Match default border style to default style in editor
+ td,
+ th {
+ border: $border-width solid;
+ padding: 0.5em;
+ }
+
// Fixed layout toggle
.has-fixed-layout {
table-layout: fixed;
diff --git a/packages/block-library/src/table/theme.scss b/packages/block-library/src/table/theme.scss
index d1f32ff066e2ac..81558143627876 100644
--- a/packages/block-library/src/table/theme.scss
+++ b/packages/block-library/src/table/theme.scss
@@ -11,8 +11,6 @@
td,
th {
- padding: 0.5em;
- border: 1px solid;
word-break: normal;
}
diff --git a/packages/block-library/src/template-part/index.php b/packages/block-library/src/template-part/index.php
index 838210480ca288..bef49341d7bb56 100644
--- a/packages/block-library/src/template-part/index.php
+++ b/packages/block-library/src/template-part/index.php
@@ -193,6 +193,11 @@ function build_template_part_block_instance_variations() {
if ( wp_installing() ) {
return array();
}
+
+ if ( ! current_theme_supports( 'block-templates' ) && ! current_theme_supports( 'block-template-parts' ) ) {
+ return array();
+ }
+
$variations = array();
$template_parts = get_block_templates(
array(
diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md
index bf32aadd73ff5a..3440d431ddf1fc 100644
--- a/packages/components/CHANGELOG.md
+++ b/packages/components/CHANGELOG.md
@@ -2,6 +2,22 @@
## Unreleased
+### Breaking Changes
+
+- `Popover`: The deprecated `range` and `__unstableShift` props have been removed ([#45195](https://github.com/WordPress/gutenberg/pull/45195)).
+
+### Deprecations
+
+- `Popover`: the deprecation messages for anchor-related props (`anchorRef`, `anchorRect`, `getAnchorRect`) have been updated. ([#45195](https://github.com/WordPress/gutenberg/pull/45195)).
+
+### New Feature
+
+- `BoxControl` & `CustomSelectControl`: Add `onMouseOver` and `onMouseOut` callback props to allow handling of these events by parent components ([#44955](https://github.com/WordPress/gutenberg/pull/44955))
+
+## Enhancements
+
+- `FontSizePicker`: Improved slider design when `withSlider` is set ([#44598](https://github.com/WordPress/gutenberg/pull/44598)).
+
### Bug Fix
- `FontSizePicker`: Ensure that fluid font size presets appear correctly in the UI controls ([#44791](https://github.com/WordPress/gutenberg/pull/44791))
@@ -16,6 +32,7 @@
### Internal
- `NavigationMenu` updated to ignore `react/exhaustive-deps` eslint rule ([#44090](https://github.com/WordPress/gutenberg/pull/44090)).
+- `ColorPalette`: Convert to TypeScript ([#44632](https://github.com/WordPress/gutenberg/pull/44632)).
## 21.0.0 (2022-09-13)
@@ -80,6 +97,7 @@
- `IsolatedEventContainer`: Refactor tests to `@testing-library/react` ([#44073](https://github.com/WordPress/gutenberg/pull/44073)).
- `KeyboardShortcuts`: Refactor tests to `@testing-library/react` ([#44075](https://github.com/WordPress/gutenberg/pull/44075)).
- `Slot`/`Fill`: Refactor tests to `@testing-library/react` ([#44084](https://github.com/WordPress/gutenberg/pull/44084)).
+- `ColorPalette`: Refactor tests to `@testing-library/react` ([#44108](https://github.com/WordPress/gutenberg/pull/44108)).
## 20.0.0 (2022-08-24)
diff --git a/packages/components/src/border-control/types.ts b/packages/components/src/border-control/types.ts
index 20cef1e4f6be4f..a0330de20ee7f7 100644
--- a/packages/components/src/border-control/types.ts
+++ b/packages/components/src/border-control/types.ts
@@ -16,7 +16,7 @@ export type Border = {
export type Color = {
name: string;
- color: CSSProperties[ 'color' ];
+ color: NonNullable< CSSProperties[ 'color' ] >;
};
export type ColorOrigin = {
diff --git a/packages/components/src/circular-option-picker/index.js b/packages/components/src/circular-option-picker/index.js
index 6b85a492203748..f41813906fcaba 100644
--- a/packages/components/src/circular-option-picker/index.js
+++ b/packages/components/src/circular-option-picker/index.js
@@ -16,13 +16,14 @@ import Button from '../button';
import Dropdown from '../dropdown';
import Tooltip from '../tooltip';
-function Option( {
- className,
- isSelected,
- selectedIconProps,
- tooltipText,
- ...additionalProps
-} ) {
+function Option( props ) {
+ const {
+ className,
+ isSelected,
+ selectedIconProps,
+ tooltipText,
+ ...additionalProps
+ } = props;
const optionButton = (