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 = (