Pilot-in / PiloPress

The most advanced WordPress Page Builder using Advanced Custom Fields & TailwindCSS
https://www.pilopress.com
63 stars 11 forks source link

Tailwindcss dont build for admin style #236

Open fgdaniel opened 1 year ago

fgdaniel commented 1 year ago

Describe the bug When you press the 'Update & Build' button, the tailwind css files for admin do not compile, it seems that the purgecss function of tailwindcss does not work for admin

To Reproduce I cannot do that because i install the plugin on local dev with laragon and i have php8 and this issues is only when i press 'update & build'

Expected behavior PurgeCSS of tailwindcss must scan in all screens like 'styles, buttons, typography', i search in plugin file and plugin seems to do that but not so good

Screenshots https://imgur.com/dJlR45T in the screenshot i have dev tools opened to inspect element and none of style is there...

WordPress, Plugins WordPress version: 6.1.1 Pilo'Press version: 0.4.3.1 ACF Pro version: 6.0.7 ACFE version: 0.8.9.2 ACF add-ons: none

I use default config for tailwindcss

fgdaniel commented 1 year ago

I detected the problem, tailwindcss compiles the css but in the 'styles > buttons' area it does not put the corresponding classes, in the live preview the buttons must be put the class you write in the text input 'Class name' must not be applied the classes from the 'Class(es) to apply' input

Below is a screenshot with dev-tools turned on https://imgur.com/0tgX2M6

Below you have the js code that I modified

File: pilopress\assets\js\pilopress-live-preview.js -> function apply_btn_styles_to_preview but this must do for every zone, like typography and so on.

/**
 * Change buttons classes for live preview
 *
 * @param $acf_row
 * @param wrapper
 */
function apply_btn_styles_to_preview( $acf_row, wrapper ) {
    let $class       = $acf_row.find( '.acf-field-custom-button-class input[type="text"]' ).val(); // Get class name
    let classes       = $acf_row.find( '.acf-field-custom-button-classes textarea' ).val(); // Old way with classes to apply
    let $live_preview = $acf_row.find( wrapper );
    $live_preview.find( '.pip-live-preview > button' ).removeClass();

    // Get states classes
    $acf_row.find( '.acf-field-custom-button-states' ).each(
        function () {
            $( this ).find( '.acf-row' ).each(
                function () {
                    let state_name  = $( this ).find( '.acf-field-state-type' ).find( 'select' );
                    let state_value = $( this ).find( '.acf-field-state-classes-to-apply' ).find( 'input[type="text"]' );

                    if ( state_name.val() && state_value.val() ) {
                        let state_values = state_value.val().split( ' ' );

                        $.each(
                            state_values,
                            function ( key, item ) {
                                classes += ' ' + state_name.val() + ':' + item;
                            },
                        );
                    }
                },
            );
        },
    );

    // $live_preview.find( '.pip-live-preview > button' ).addClass( classes ); // old way with classes to apply
    $live_preview.find( '.pip-live-preview > button' ).addClass( $class ); // add class name not classes to apply
}

Feel free to improve my code, thanks!

jerome-pilotin commented 1 year ago

Thank you @fgdaniel for telling us about this issue!

The current behavior is for the live preview to be updated, well, live: if you add/remove a class in the textarea, the button should change instantly and reflect the change.

There are two issues however:

  1. if no other code in the project call these Tailwind classes, they are never compiled into the CSS and therefore the preview cannot work as is
  2. if we change instead to your suggestion, the preview will work on page load (and display the right styles, as the Tailwind classes have been compiled into a CSS class) but not work on class changes

We have to work internally and discuss this. I see two way forward:

  1. change the live preview behavior to a regular preview: it just previews what the user has saved/compiled, not what has been entered into the textarea
  2. or make sure the Tailwind classes are also compiled as individual CSS classes (but this will still create weird situations where the live preview is not really live since the user can enter classes that are not yet compiled)

Thinking about this, I'm leaning towards your proposed solution. Thank you anyway about the issue and the proposed working solution!

fgdaniel commented 1 year ago

Yes my solution work only after we do 'Update & build' because the classes must exist(and this solution is only in javascript), i do the same fix with typography preview.

I put the entire code below for future purpose(maybe this help), i commented where i modify

jQuery( document ).ready(
    function ( $ ) {

        let $typo_class           = $( '.acf-field-typography-class-name' ); // the new way with class-name not classes to apply

        let $typo_classes           = $( '.acf-field-typography-classes' ); // old way classes to apply
        let $simple_color_value     = $( '.acf-field-simple-color-value' );
        let $colors_shades_repeater = $( '.acf-field-colors-shades-shades' );
        let $buttons_wrapper        = $( '.acf-field-pip-button' );
        let $fonts_wrapper          = $( '.acf-field-pip-fonts' );

        // Load previews on page load
        load_previews();

        // Change previews on typing
        previews_on_typing();

        if ( typeof acf !== 'undefined' ) {
            // When a new row is added
            acf.addAction(
                'append',
                function ( $row ) {
                    if ( !$( '.acf-field-typography-message' ).hasClass( 'acf-hidden' ) ) {

                        // Typography
                        $row.find( '.acf-field-typography-classes textarea' ).keyup(
                            function () {
                                apply_styles_to_preview( $( this ), '.acf-field-typography-preview' );
                            },
                        );

                    } else if ( !$( '.acf-field-font-color-message' ).hasClass( 'acf-hidden' ) ) {

                        // Simple colors
                        $row.find( '.acf-field-simple-color-value input[type="text"]' ).keyup(
                            function () {
                                add_css_to_preview( $( this ), '.acf-field-pip-simple-colors-preview', 'background-color' );
                            },
                        );

                        // Colors with shades
                        $row.find( '.acf-field-shade-value input[type="text"]' ).keyup(
                            function () {
                                let rows = $( this ).parents( '.acf-row' );
                                add_css_to_preview_repeater( $( rows[0] ), '.acf-field-colors-shades-shades-preview', 'background-color', $( this ).val() );
                            },
                        );

                    } else if ( !$( '.acf-field-button-message' ).hasClass( 'acf-hidden' ) ) {

                        // Buttons - Main textarea
                        $row.find( '.acf-field-custom-button-classes input[type="text"]' ).keyup(
                            function () {
                                let rows = $( this ).parents( '.acf-row' );
                                apply_btn_styles_to_preview( $( rows[0] ), '.acf-field-pip-button-preview', $( this ).val() );
                            },
                        );

                        // Buttons - Every state input
                        $row.find( '.acf-field-custom-button-states .acf-field-state-classes-to-apply input[type="text"]' ).keyup(
                            function () {
                                let rows = $( this ).parents( '.acf-row' );
                                apply_btn_styles_to_preview( $( rows[( rows.length - 1 )] ), '.acf-field-pip-button-preview' );
                            },
                        );

                    }
                },
            );

            // PILO_TODO: update preview when a row is removed
            // When a row is removed
            /*acf.add_action(
             'remove',
             function ( $row ) {

             if ( !$( '.acf-field-button-message' ).hasClass( 'acf-hidden' ) ) {

             let rows = $row.parents( '.acf-row' );
             apply_btn_styles_to_preview( $( rows[0] ), '.acf-field-pip-button-preview' );

             }
             },
             );*/
        }

        /**
         * All actions to load previews on page load
         */
        function load_previews() {
            // Typography
            $typo_class.each(
                function () {
                    apply_styles_to_preview( $( this ).find( 'input[type="text"]' ), '.acf-field-typography-preview' );
                },
            ); // new way with class name

            // $typo_classes.each(
            //     function () {
            //         apply_styles_to_preview( $( this ).find( 'textarea' ), '.acf-field-typography-preview' );
            //     },
            // ); // Old way with classes to apply

            // Simple colors
            $simple_color_value.each(
                function () {
                    add_css_to_preview( $( this ).find( 'input[type="text"]' ), '.acf-field-pip-simple-colors-preview', 'background-color' );
                },
            );

            // Colors with shades
            $colors_shades_repeater.each(
                function () {
                    $( this ).find( '.acf-row' ).each(
                        function () {
                            add_css_to_preview_repeater( $( this ), '.acf-field-colors-shades-shades-preview', 'background-color', $( this ).find( '.acf-field-shade-value input[type="text"]' ).val() );
                        },
                    );
                },
            );

            // Buttons
            $buttons_wrapper.each(
                function () {
                    $( this ).find( '.acf-row' ).each(
                        function () {
                            apply_btn_styles_to_preview( $( this ), '.acf-field-pip-button-preview' );
                        },
                    );
                },
            );

            // Fonts
            $fonts_wrapper.each(
                function () {
                    $( this ).find( '.layout' ).each(
                        function () {
                            // External fonts
                            let external_font_name = $( this ).find( '.acf-field-google-font-class-name input[type="text"]' ).val();
                            $( this ).find( '.acf-field-google-font-preview .pip-live-preview > div' ).addClass( 'font-' + external_font_name );

                            // Custom fonts
                            let custom_font_name = $( this ).find( '.acf-field-custom-font-class-name input[type="text"]' ).val();
                            $( this ).find( '.acf-field-custom-font-preview .pip-live-preview > div' ).addClass( 'font-' + custom_font_name );
                        },
                    );
                },
            );
        }

        /**
         * All actions to change previews on typing
         */
        function previews_on_typing() {
            // Typography
            $typo_class.find( 'input[type="text"]' ).keyup(
                function () {
                    apply_styles_to_preview( $( this ), '.acf-field-typography-preview' );
                },
            ); // new way with class name

            // $typo_classes.find( 'textarea' ).keyup(
            //     function () {
            //         apply_styles_to_preview( $( this ), '.acf-field-typography-preview' );
            //     },
            // ); // old way with classes to apply

            // Simple colors
            $simple_color_value.find( 'input[type="text"]' ).keyup(
                function () {
                    add_css_to_preview( $( this ), '.acf-field-pip-simple-colors-preview', 'background-color' );
                },
            );

            // Colors with shades
            $colors_shades_repeater.find( '.acf-row .acf-field-shade-value input[type="text"]' ).keyup(
                function () {
                    let rows = $( this ).parents( '.acf-row' );
                    add_css_to_preview_repeater( $( rows[0] ), '.acf-field-colors-shades-shades-preview', 'background-color', $( this ).val() );
                },
            );

            // Buttons - Main textarea
            $buttons_wrapper.find( '.acf-row .acf-field-custom-button-classes textarea' ).keyup(
                function () {
                    let rows = $( this ).parents( '.acf-row' );
                    apply_btn_styles_to_preview( $( rows[0] ), '.acf-field-pip-button-preview', $( this ).val() );
                },
            );

            // Buttons - Every state select
            $buttons_wrapper.find( '.acf-row .acf-field-custom-button-states .acf-field-state-type select' ).change(
                function () {
                    let rows = $( this ).parents( '.acf-row' );
                    apply_btn_styles_to_preview( $( rows[( rows.length - 1 )] ), '.acf-field-pip-button-preview' );
                },
            );

            // Buttons - Every state input
            $buttons_wrapper.find( '.acf-row .acf-field-custom-button-states .acf-field-state-classes-to-apply input[type="text"]' ).keyup(
                function () {
                    let rows = $( this ).parents( '.acf-row' );
                    apply_btn_styles_to_preview( $( rows[( rows.length - 1 )] ), '.acf-field-pip-button-preview' );
                },
            );
        }

        /**
         * Change classes for live preview
         *
         * @param $input
         * @param wrapper
         */
        function apply_styles_to_preview( $input, wrapper ) {
            $input.parents( '.acf-row' ).find( wrapper ).find( '.pip-live-preview > div' ).removeClass().addClass( $input.val() );
        }

        /**
         * Change buttons classes for live preview
         *
         * @param $acf_row
         * @param wrapper
         */
        function apply_btn_styles_to_preview( $acf_row, wrapper ) {
            let $class       = $acf_row.find( '.acf-field-custom-button-class input[type="text"]' ).val(); // Get class name
            let classes       = $acf_row.find( '.acf-field-custom-button-classes textarea' ).val(); // Old way with classes to apply
            let $live_preview = $acf_row.find( wrapper );
            $live_preview.find( '.pip-live-preview > button' ).removeClass();

            // Get states classes
            $acf_row.find( '.acf-field-custom-button-states' ).each(
                function () {
                    $( this ).find( '.acf-row' ).each(
                        function () {
                            let state_name  = $( this ).find( '.acf-field-state-type' ).find( 'select' );
                            let state_value = $( this ).find( '.acf-field-state-classes-to-apply' ).find( 'input[type="text"]' );

                            if ( state_name.val() && state_value.val() ) {
                                let state_values = state_value.val().split( ' ' );

                                $.each(
                                    state_values,
                                    function ( key, item ) {
                                        classes += ' ' + state_name.val() + ':' + item;
                                    },
                                );
                            }
                        },
                    );
                },
            );

            // $live_preview.find( '.pip-live-preview > button' ).addClass( classes ); // old way with classes to apply
            $live_preview.find( '.pip-live-preview > button' ).addClass( $class ); // add class name not classes to apply
        }

        /**
         * Add CSS for live preview
         *
         * @param $input
         * @param wrapper
         * @param property
         */
        function add_css_to_preview( $input, wrapper, property ) {
            $input.parents( '.acf-row' ).find( wrapper ).find( '.pip-live-preview > div' ).css( property, $input.val() );
        }

        /**
         * Add CSS for live preview with repeater fields
         *
         * @param $input
         * @param wrapper
         * @param property
         * @param value
         */
        function add_css_to_preview_repeater( $input, wrapper, property, value ) {
            $input.find( wrapper ).find( '.pip-live-preview > div' ).css( property, value );
        }
    },
);