diff --git a/packages/block-editor/src/utils/transform-styles/index.js b/packages/block-editor/src/utils/transform-styles/index.js index 763554707bd2e..847ce1f9d8cb1 100644 --- a/packages/block-editor/src/utils/transform-styles/index.js +++ b/packages/block-editor/src/utils/transform-styles/index.js @@ -14,6 +14,7 @@ import { compose } from '@wordpress/compose'; import traverse from './traverse'; import urlRewrite from './transforms/url-rewrite'; import wrap from './transforms/wrap'; +import avoidEditorComponents from './transforms/avoid-editor-components'; /** * Applies a series of CSS rule transforms to wrap selectors inside a given class and/or rewrite URLs depending on the parameters passed. @@ -29,6 +30,7 @@ const transformStyles = ( styles, wrapperClassName = '' ) => { const transforms = []; if ( wrapperClassName && ! __experimentalNoWrapper ) { transforms.push( wrap( wrapperClassName ) ); + transforms.push( avoidEditorComponents() ); } if ( baseURL ) { transforms.push( urlRewrite( baseURL ) ); diff --git a/packages/block-editor/src/utils/transform-styles/transforms/avoid-editor-components.js b/packages/block-editor/src/utils/transform-styles/transforms/avoid-editor-components.js new file mode 100644 index 0000000000000..f239dbb47c00b --- /dev/null +++ b/packages/block-editor/src/utils/transform-styles/transforms/avoid-editor-components.js @@ -0,0 +1,46 @@ +/** + * This transform targets inputs and buttons and prevents css styles for the editor + * from the theme to bleed into the editor's components. It is a bit hacky but + * it is contained and prevents us from having to do make changes over multiple files. + * + * @constant string IS_BUTTON_TAG Regex to check if the selector is a button tag selector. + * @constant string IS_INPUT_TAG Regex to check if the selector is an input tag selector. + */ +const IS_BUTTON_TAG = /^(button).*$/; + +const IS_INPUT_TAG = /^(input).*$/; + +const avoidEditorComponents = ( ignore = [] ) => ( node ) => { + const updateSelector = ( selector ) => { + if ( ignore.includes( selector.trim() ) ) { + return selector; + } + + if ( selector.match( IS_BUTTON_TAG ) ) { + return selector.replace( + IS_BUTTON_TAG, + 'button:not(.components-button):not([id^=mceu_])' + ); + } + + if ( selector.match( IS_INPUT_TAG ) ) { + return selector.replace( + IS_INPUT_TAG, + 'input:not(.components-text-control__input):not(.components-placeholder__input):not(.components-form-token-field__input)' + ); + } + + return selector; + }; + + if ( node.type === 'rule' ) { + return { + ...node, + selectors: node.selectors.map( updateSelector ), + }; + } + + return node; +}; + +export default avoidEditorComponents; diff --git a/packages/block-editor/src/utils/transform-styles/transforms/test/__snapshots__/avoid-editor-components.js.snap b/packages/block-editor/src/utils/transform-styles/transforms/test/__snapshots__/avoid-editor-components.js.snap new file mode 100644 index 0000000000000..ff2ca6ef778ab --- /dev/null +++ b/packages/block-editor/src/utils/transform-styles/transforms/test/__snapshots__/avoid-editor-components.js.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`CSS selector wrap should add editor classes to buttons 1`] = ` +"button:not(.components-button):not([id^=mceu_]) { +background-color: #ff0000; +}" +`; + +exports[`CSS selector wrap should add editor classes to inputs 1`] = ` +"input:not(.components-text-control__input):not(.components-placeholder__input):not(.components-form-token-field__input) { +border-color: #ff0000; +}" +`; diff --git a/packages/block-editor/src/utils/transform-styles/transforms/test/__snapshots__/wrap.js.snap b/packages/block-editor/src/utils/transform-styles/transforms/test/__snapshots__/wrap.js.snap index 9060dda747029..f067738326e17 100644 --- a/packages/block-editor/src/utils/transform-styles/transforms/test/__snapshots__/wrap.js.snap +++ b/packages/block-editor/src/utils/transform-styles/transforms/test/__snapshots__/wrap.js.snap @@ -22,6 +22,12 @@ color: red; }" `; +exports[`CSS selector wrap should replace :root selectors 1`] = ` +".my-namespace { +--my-color: #ff0000; +}" +`; + exports[`CSS selector wrap should replace root tags 1`] = ` ".my-namespace, .my-namespace h1 { @@ -41,9 +47,3 @@ exports[`CSS selector wrap should wrap regular selectors 1`] = ` color: red; }" `; - -exports[`CSS selector wrap should replace :root selectors 1`] = ` -".my-namespace { ---my-color: #ff0000; -}" -`; diff --git a/packages/block-editor/src/utils/transform-styles/transforms/test/avoid-editor-components.js b/packages/block-editor/src/utils/transform-styles/transforms/test/avoid-editor-components.js new file mode 100644 index 0000000000000..a661c4d48d595 --- /dev/null +++ b/packages/block-editor/src/utils/transform-styles/transforms/test/avoid-editor-components.js @@ -0,0 +1,29 @@ +/** + * Internal dependencies + */ +import traverse from '../../traverse'; +import avoidEditorComponents from '../avoid-editor-components'; + +describe( 'CSS selector wrap', () => { + it( 'should add editor classes to buttons', () => { + const callback = avoidEditorComponents(); + const input = ` + button { + background-color: #ff0000; + }`; + const output = traverse( input, callback ); + + expect( output ).toMatchSnapshot(); + } ); + + it( 'should add editor classes to inputs', () => { + const callback = avoidEditorComponents(); + const input = ` + input { + border-color: #ff0000; + }`; + const output = traverse( input, callback ); + + expect( output ).toMatchSnapshot(); + } ); +} );