Make WordPress Core

Changeset 54272


Ignore:
Timestamp:
09/21/2022 11:41:44 AM (19 months ago)
Author:
audrasjb
Message:

Editor: Introduce spacing presets in global style properties.

This changeset is part of the Gutenberg changes merged into WP 6.1. It adds spacing presets support in global style properties.

Follow-up to [54211].

Props glendaviesnz, andrewserong, costdev, audrasjb, mukesh27.
See #56467.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/block-editor.php

    r54210 r54272  
    489489    }
    490490    if ( isset( $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'] ) ) {
    491         $editor_settings['disableCustomSpacingSizes'] = ! $editor_ettings['__experimentalFeatures']['spacing']['customSpacingSize'];
     491        $editor_settings['disableCustomSpacingSizes'] = ! $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'];
    492492        unset( $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'] );
    493493    }
  • trunk/src/wp-includes/class-wp-theme-json-resolver.php

    r54251 r54272  
    471471     * @since 5.9.0 Added user data, removed the `$settings` parameter,
    472472     *              added the `$origin` parameter.
    473      * @since 6.1.0 Added block data.
     473     * @since 6.1.0 Added block data and generation of spacingSizes array.
    474474     *
    475475     * @param string $origin Optional. To what level should we merge data.
     
    490490            $result->merge( static::get_user_data() );
    491491        }
     492
     493        // Generate the default spacingSizes array based on the merged spacingScale settings.
     494        $result->set_spacing_sizes();
    492495
    493496        return $result;
  • trunk/src/wp-includes/class-wp-theme-json.php

    r54260 r54272  
    165165            'properties'        => array( 'font-family' ),
    166166        ),
     167        array(
     168            'path'              => array( 'spacing', 'spacingSizes' ),
     169            'prevent_override'  => false,
     170            'use_default_names' => true,
     171            'value_key'         => 'size',
     172            'css_vars'          => '--wp--preset--spacing--$slug',
     173            'classes'           => array(),
     174            'properties'        => array( 'padding', 'margin' ),
     175        ),
     176        array(
     177            'path'              => array( 'spacing', 'spacingScale' ),
     178            'prevent_override'  => false,
     179            'use_default_names' => true,
     180            'value_key'         => 'size',
     181            'css_vars'          => '--wp--preset--spacing--$slug',
     182            'classes'           => array(),
     183            'properties'        => array( 'padding', 'margin' ),
     184        ),
    167185    );
    168186
     
    308326        ),
    309327        'spacing'                       => array(
    310             'blockGap' => null,
    311             'margin'   => null,
    312             'padding'  => null,
    313             'units'    => null,
     328            'customSpacingSize' => null,
     329            'spacingSizes'      => null,
     330            'spacingScale'      => null,
     331            'blockGap'          => null,
     332            'margin'            => null,
     333            'padding'           => null,
     334            'units'             => null,
    314335        ),
    315336        'typography'                    => array(
     
    28912912    }
    28922913
     2914    /**
     2915     * Sets the spacingSizes array based on the spacingScale values from theme.json.
     2916     *
     2917     * @since 6.1.0
     2918     *
     2919     * @return null|void
     2920     */
     2921    public function set_spacing_sizes() {
     2922        $spacing_scale = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'spacingScale' ), array() );
     2923
     2924        if ( ! is_numeric( $spacing_scale['steps'] )
     2925            || ! isset( $spacing_scale['mediumStep'] )
     2926            || ! isset( $spacing_scale['unit'] )
     2927            || ! isset( $spacing_scale['operator'] )
     2928            || ! isset( $spacing_scale['increment'] )
     2929            || ! isset( $spacing_scale['steps'] )
     2930            || ! is_numeric( $spacing_scale['increment'] )
     2931            || ! is_numeric( $spacing_scale['mediumStep'] )
     2932            || ( '+' !== $spacing_scale['operator'] && '*' !== $spacing_scale['operator'] ) ) {
     2933            if ( ! empty( $spacing_scale ) ) {
     2934                trigger_error( __( 'Some of the theme.json settings.spacing.spacingScale values are invalid' ), E_USER_NOTICE );
     2935            }
     2936            return null;
     2937        }
     2938
     2939        // If theme authors want to prevent the generation of the core spacing scale they can set their theme.json spacingScale.steps to 0.
     2940        if ( 0 === $spacing_scale['steps'] ) {
     2941            return null;
     2942        }
     2943
     2944        $unit            = '%' === $spacing_scale['unit'] ? '%' : sanitize_title( $spacing_scale['unit'] );
     2945        $current_step    = $spacing_scale['mediumStep'];
     2946        $steps_mid_point = round( $spacing_scale['steps'] / 2, 0 );
     2947        $x_small_count   = null;
     2948        $below_sizes     = array();
     2949        $slug            = 40;
     2950        $remainder       = 0;
     2951
     2952        for ( $below_midpoint_count = $steps_mid_point - 1; $spacing_scale['steps'] > 1 && $slug > 0 && $below_midpoint_count > 0; $below_midpoint_count-- ) {
     2953            if ( '+' === $spacing_scale['operator'] ) {
     2954                $current_step -= $spacing_scale['increment'];
     2955            } elseif ( $spacing_scale['increment'] > 1 ) {
     2956                $current_step /= $spacing_scale['increment'];
     2957            } else {
     2958                $current_step *= $spacing_scale['increment'];
     2959            }
     2960
     2961            if ( $current_step <= 0 ) {
     2962                $remainder = $below_midpoint_count;
     2963                break;
     2964            }
     2965
     2966            $below_sizes[] = array(
     2967                /* translators: %s: Digit to indicate multiple of sizing, eg. 2X-Small. */
     2968                'name' => $below_midpoint_count === $steps_mid_point - 1 ? __( 'Small' ) : sprintf( __( '%sX-Small' ), (string) $x_small_count ),
     2969                'slug' => (string) $slug,
     2970                'size' => round( $current_step, 2 ) . $unit,
     2971            );
     2972
     2973            if ( $below_midpoint_count === $steps_mid_point - 2 ) {
     2974                $x_small_count = 2;
     2975            }
     2976
     2977            if ( $below_midpoint_count < $steps_mid_point - 2 ) {
     2978                $x_small_count++;
     2979            }
     2980
     2981            $slug -= 10;
     2982        }
     2983
     2984        $below_sizes = array_reverse( $below_sizes );
     2985
     2986        $below_sizes[] = array(
     2987            'name' => __( 'Medium' ),
     2988            'slug' => '50',
     2989            'size' => $spacing_scale['mediumStep'] . $unit,
     2990        );
     2991
     2992        $current_step  = $spacing_scale['mediumStep'];
     2993        $x_large_count = null;
     2994        $above_sizes   = array();
     2995        $slug          = 60;
     2996        $steps_above   = ( $spacing_scale['steps'] - $steps_mid_point ) + $remainder;
     2997
     2998        for ( $above_midpoint_count = 0; $above_midpoint_count < $steps_above; $above_midpoint_count++ ) {
     2999            $current_step = '+' === $spacing_scale['operator']
     3000                ? $current_step + $spacing_scale['increment']
     3001                : ( $spacing_scale['increment'] >= 1 ? $current_step * $spacing_scale['increment'] : $current_step / $spacing_scale['increment'] );
     3002
     3003            $above_sizes[] = array(
     3004                /* translators: %s: Digit to indicate multiple of sizing, eg. 2X-Large. */
     3005                'name' => 0 === $above_midpoint_count ? __( 'Large' ) : sprintf( __( '%sX-Large' ), (string) $x_large_count ),
     3006                'slug' => (string) $slug,
     3007                'size' => round( $current_step, 2 ) . $unit,
     3008            );
     3009
     3010            if ( 1 === $above_midpoint_count ) {
     3011                $x_large_count = 2;
     3012            }
     3013
     3014            if ( $above_midpoint_count > 1 ) {
     3015                $x_large_count++;
     3016            }
     3017
     3018            $slug += 10;
     3019        }
     3020
     3021        $spacing_sizes = array_merge( $below_sizes, $above_sizes );
     3022
     3023        // If there are 7 or less steps in the scale revert to numbers for labels instead of t-shirt sizes.
     3024        if ( $spacing_scale['steps'] <= 7 ) {
     3025            for ( $spacing_sizes_count = 0; $spacing_sizes_count < count( $spacing_sizes ); $spacing_sizes_count++ ) {
     3026                $spacing_sizes[ $spacing_sizes_count ]['name'] = (string) ( $spacing_sizes_count + 1 );
     3027            }
     3028        }
     3029
     3030        _wp_array_set( $this->theme_json, array( 'settings', 'spacing', 'spacingSizes', 'default' ), $spacing_sizes );
     3031    }
    28933032}
  • trunk/src/wp-includes/theme-i18n.json

    r53038 r54272  
    3131                ]
    3232        },
     33        "spacing": {
     34            "spacingSizes": [
     35                {
     36                    "name": "Space size name"
     37                }
     38            ]
     39        },
    3340        "blocks": {
    3441            "*": {
     
    5663                        }
    5764                    ]
     65                },
     66                "spacing": {
     67                    "spacingSizes": [
     68                        {
     69                            "name": "Space size name"
     70                        }
     71                    ]
    5872                }
    5973            }
  • trunk/tests/phpunit/tests/theme/wpThemeJson.php

    r54257 r54272  
    34943494        $this->assertSame( $expected, $root_rules . $style_rules );
    34953495    }
     3496
     3497    /**
     3498     * Tests generating the spacing presets array based on the spacing scale provided.
     3499     *
     3500     * @ticket 56467
     3501     *
     3502     * @dataProvider data_generate_spacing_scale_fixtures
     3503     *
     3504     * @param array $spacing_scale   Example spacing scale definitions from the data provider.
     3505     * @param array $expected_output Expected output from data provider.
     3506     */
     3507    function test_should_set_spacing_sizes( $spacing_scale, $expected_output ) {
     3508        $theme_json = new WP_Theme_JSON(
     3509            array(
     3510                'version'  => 2,
     3511                'settings' => array(
     3512                    'spacing' => array(
     3513                        'spacingScale' => $spacing_scale,
     3514                    ),
     3515                ),
     3516            )
     3517        );
     3518
     3519        $theme_json->set_spacing_sizes();
     3520        $this->assertSame( $expected_output, _wp_array_get( $theme_json->get_raw_data(), array( 'settings', 'spacing', 'spacingSizes', 'default' ) ) );
     3521    }
     3522
     3523    /**
     3524     * Data provider for spacing scale tests.
     3525     *
     3526     * @ticket 56467
     3527     *
     3528     * @return array
     3529     */
     3530    function data_generate_spacing_scale_fixtures() {
     3531        return array(
     3532            'only one value when single step in spacing scale' => array(
     3533                'spacing_scale'   => array(
     3534                    'operator'   => '+',
     3535                    'increment'  => 1.5,
     3536                    'steps'      => 1,
     3537                    'mediumStep' => 4,
     3538                    'unit'       => 'rem',
     3539                ),
     3540                'expected_output' => array(
     3541                    array(
     3542                        'name' => '1',
     3543                        'slug' => '50',
     3544                        'size' => '4rem',
     3545                    ),
     3546                ),
     3547            ),
     3548            'one step above medium when two steps in spacing scale' => array(
     3549                'spacing_scale'   => array(
     3550                    'operator'   => '+',
     3551                    'increment'  => 1.5,
     3552                    'steps'      => 2,
     3553                    'mediumStep' => 4,
     3554                    'unit'       => 'rem',
     3555                ),
     3556                'expected_output' => array(
     3557                    array(
     3558                        'name' => '1',
     3559                        'slug' => '50',
     3560                        'size' => '4rem',
     3561                    ),
     3562                    array(
     3563                        'name' => '2',
     3564                        'slug' => '60',
     3565                        'size' => '5.5rem',
     3566                    ),
     3567                ),
     3568            ),
     3569            'one step above medium and one below when three steps in spacing scale' => array(
     3570                'spacing_scale'   => array(
     3571                    'operator'   => '+',
     3572                    'increment'  => 1.5,
     3573                    'steps'      => 3,
     3574                    'mediumStep' => 4,
     3575                    'unit'       => 'rem',
     3576                ),
     3577                'expected_output' => array(
     3578                    array(
     3579                        'name' => '1',
     3580                        'slug' => '40',
     3581                        'size' => '2.5rem',
     3582                    ),
     3583                    array(
     3584                        'name' => '2',
     3585                        'slug' => '50',
     3586                        'size' => '4rem',
     3587                    ),
     3588                    array(
     3589                        'name' => '3',
     3590                        'slug' => '60',
     3591                        'size' => '5.5rem',
     3592                    ),
     3593                ),
     3594            ),
     3595            'extra step added above medium when an even number of steps > 2 specified' => array(
     3596                'spacing_scale'   => array(
     3597                    'operator'   => '+',
     3598                    'increment'  => 1.5,
     3599                    'steps'      => 4,
     3600                    'mediumStep' => 4,
     3601                    'unit'       => 'rem',
     3602                ),
     3603                'expected_output' => array(
     3604                    array(
     3605                        'name' => '1',
     3606                        'slug' => '40',
     3607                        'size' => '2.5rem',
     3608                    ),
     3609                    array(
     3610                        'name' => '2',
     3611                        'slug' => '50',
     3612                        'size' => '4rem',
     3613                    ),
     3614                    array(
     3615                        'name' => '3',
     3616                        'slug' => '60',
     3617                        'size' => '5.5rem',
     3618                    ),
     3619                    array(
     3620                        'name' => '4',
     3621                        'slug' => '70',
     3622                        'size' => '7rem',
     3623                    ),
     3624                ),
     3625            ),
     3626            'extra steps above medium if bottom end will go below zero' => array(
     3627                'spacing_scale'   => array(
     3628                    'operator'   => '+',
     3629                    'increment'  => 2.5,
     3630                    'steps'      => 5,
     3631                    'mediumStep' => 5,
     3632                    'unit'       => 'rem',
     3633                ),
     3634                'expected_output' => array(
     3635                    array(
     3636                        'name' => '1',
     3637                        'slug' => '40',
     3638                        'size' => '2.5rem',
     3639                    ),
     3640                    array(
     3641                        'name' => '2',
     3642                        'slug' => '50',
     3643                        'size' => '5rem',
     3644                    ),
     3645                    array(
     3646                        'name' => '3',
     3647                        'slug' => '60',
     3648                        'size' => '7.5rem',
     3649                    ),
     3650                    array(
     3651                        'name' => '4',
     3652                        'slug' => '70',
     3653                        'size' => '10rem',
     3654                    ),
     3655                    array(
     3656                        'name' => '5',
     3657                        'slug' => '80',
     3658                        'size' => '12.5rem',
     3659                    ),
     3660                ),
     3661            ),
     3662            'multiplier correctly calculated above and below medium' => array(
     3663                'spacing_scale'   => array(
     3664                    'operator'   => '*',
     3665                    'increment'  => 1.5,
     3666                    'steps'      => 5,
     3667                    'mediumStep' => 1.5,
     3668                    'unit'       => 'rem',
     3669                ),
     3670                'expected_output' => array(
     3671                    array(
     3672                        'name' => '1',
     3673                        'slug' => '30',
     3674                        'size' => '0.67rem',
     3675                    ),
     3676                    array(
     3677                        'name' => '2',
     3678                        'slug' => '40',
     3679                        'size' => '1rem',
     3680                    ),
     3681                    array(
     3682                        'name' => '3',
     3683                        'slug' => '50',
     3684                        'size' => '1.5rem',
     3685                    ),
     3686                    array(
     3687                        'name' => '4',
     3688                        'slug' => '60',
     3689                        'size' => '2.25rem',
     3690                    ),
     3691                    array(
     3692                        'name' => '5',
     3693                        'slug' => '70',
     3694                        'size' => '3.38rem',
     3695                    ),
     3696                ),
     3697            ),
     3698            'increment < 1 combined showing * operator acting as divisor above and below medium' => array(
     3699                'spacing_scale'   => array(
     3700                    'operator'   => '*',
     3701                    'increment'  => 0.25,
     3702                    'steps'      => 5,
     3703                    'mediumStep' => 1.5,
     3704                    'unit'       => 'rem',
     3705                ),
     3706                'expected_output' => array(
     3707                    array(
     3708                        'name' => '1',
     3709                        'slug' => '30',
     3710                        'size' => '0.09rem',
     3711                    ),
     3712                    array(
     3713                        'name' => '2',
     3714                        'slug' => '40',
     3715                        'size' => '0.38rem',
     3716                    ),
     3717                    array(
     3718                        'name' => '3',
     3719                        'slug' => '50',
     3720                        'size' => '1.5rem',
     3721                    ),
     3722                    array(
     3723                        'name' => '4',
     3724                        'slug' => '60',
     3725                        'size' => '6rem',
     3726                    ),
     3727                    array(
     3728                        'name' => '5',
     3729                        'slug' => '70',
     3730                        'size' => '24rem',
     3731                    ),
     3732                ),
     3733            ),
     3734            't-shirt sizing used if more than 7 steps in scale' => array(
     3735                'spacing_scale'   => array(
     3736                    'operator'   => '*',
     3737                    'increment'  => 1.5,
     3738                    'steps'      => 8,
     3739                    'mediumStep' => 1.5,
     3740                    'unit'       => 'rem',
     3741                ),
     3742                'expected_output' => array(
     3743                    array(
     3744                        'name' => '2X-Small',
     3745                        'slug' => '20',
     3746                        'size' => '0.44rem',
     3747                    ),
     3748                    array(
     3749                        'name' => 'X-Small',
     3750                        'slug' => '30',
     3751                        'size' => '0.67rem',
     3752                    ),
     3753                    array(
     3754                        'name' => 'Small',
     3755                        'slug' => '40',
     3756                        'size' => '1rem',
     3757                    ),
     3758                    array(
     3759                        'name' => 'Medium',
     3760                        'slug' => '50',
     3761                        'size' => '1.5rem',
     3762                    ),
     3763                    array(
     3764                        'name' => 'Large',
     3765                        'slug' => '60',
     3766                        'size' => '2.25rem',
     3767                    ),
     3768                    array(
     3769                        'name' => 'X-Large',
     3770                        'slug' => '70',
     3771                        'size' => '3.38rem',
     3772                    ),
     3773                    array(
     3774                        'name' => '2X-Large',
     3775                        'slug' => '80',
     3776                        'size' => '5.06rem',
     3777                    ),
     3778                    array(
     3779                        'name' => '3X-Large',
     3780                        'slug' => '90',
     3781                        'size' => '7.59rem',
     3782                    ),
     3783                ),
     3784            ),
     3785        );
     3786    }
     3787
     3788    /**
     3789     * Tests generating the spacing presets array based on the spacing scale provided.
     3790     *
     3791     * @ticket 56467
     3792     *
     3793     * @dataProvider data_set_spacing_sizes_when_invalid
     3794     *
     3795     * @param array $spacing_scale   Example spacing scale definitions from the data provider.
     3796     * @param array $expected_output Expected output from data provider.
     3797     */
     3798    public function test_set_spacing_sizes_should_detect_invalid_spacing_scale( $spacing_scale, $expected_output ) {
     3799        $this->expectNotice();
     3800        $this->expectNoticeMessage( 'Some of the theme.json settings.spacing.spacingScale values are invalid' );
     3801
     3802        $theme_json = new WP_Theme_JSON(
     3803            array(
     3804                'version'  => 2,
     3805                'settings' => array(
     3806                    'spacing' => array(
     3807                        'spacingScale' => $spacing_scale,
     3808                    ),
     3809                ),
     3810            )
     3811        );
     3812
     3813        $theme_json->set_spacing_sizes();
     3814        $this->assertSame( $expected_output, _wp_array_get( $theme_json->get_raw_data(), array( 'settings', 'spacing', 'spacingSizes', 'default' ) ) );
     3815    }
     3816
     3817    /**
     3818     * Data provider for spacing scale tests.
     3819     *
     3820     * @ticket 56467
     3821     *
     3822     * @return array
     3823     */
     3824    function data_set_spacing_sizes_when_invalid() {
     3825        return array(
     3826            'missing operator value'  => array(
     3827                'spacing_scale'   => array(
     3828                    'operator'   => '',
     3829                    'increment'  => 1.5,
     3830                    'steps'      => 1,
     3831                    'mediumStep' => 4,
     3832                    'unit'       => 'rem',
     3833                ),
     3834                'expected_output' => null,
     3835            ),
     3836            'non numeric increment'   => array(
     3837                'spacing_scale'   => array(
     3838                    'operator'   => '+',
     3839                    'increment'  => 'add two to previous value',
     3840                    'steps'      => 1,
     3841                    'mediumStep' => 4,
     3842                    'unit'       => 'rem',
     3843                ),
     3844                'expected_output' => null,
     3845            ),
     3846            'non numeric steps'       => array(
     3847                'spacing_scale'   => array(
     3848                    'operator'   => '+',
     3849                    'increment'  => 1.5,
     3850                    'steps'      => 'spiral staircase preferred',
     3851                    'mediumStep' => 4,
     3852                    'unit'       => 'rem',
     3853                ),
     3854                'expected_output' => null,
     3855            ),
     3856            'non numeric medium step' => array(
     3857                'spacing_scale'   => array(
     3858                    'operator'   => '+',
     3859                    'increment'  => 1.5,
     3860                    'steps'      => 5,
     3861                    'mediumStep' => 'That which is just right',
     3862                    'unit'       => 'rem',
     3863                ),
     3864                'expected_output' => null,
     3865            ),
     3866            'missing unit value'      => array(
     3867                'spacing_scale'   => array(
     3868                    'operator'   => '+',
     3869                    'increment'  => 1.5,
     3870                    'steps'      => 5,
     3871                    'mediumStep' => 4,
     3872                ),
     3873                'expected_output' => null,
     3874            ),
     3875        );
     3876    }
    34963877}
Note: See TracChangeset for help on using the changeset viewer.