Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify CustomCSS UI #49721

Merged
merged 3 commits into from
May 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/**
* WordPress dependencies
*/
import {
TextareaControl,
Tooltip,
__experimentalVStack as VStack,
} from '@wordpress/components';
import { useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { Icon, info } from '@wordpress/icons';

/**
* Internal dependencies
*/
import { default as transformStyles } from '../../utils/transform-styles';

export default function AdvancedPanel( {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intention that this component will be expanded with more functionality later? Otherwise it would be clearer to call it something like "CustomCSSPanel".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is the component is equivalent to the "Advanced" section of the block inspector panel. It can contain things like custom class, anchor, ... and any "common" advanced setting.

The issue here is kind of similar to the "filters" panel where we only have duotone and the "effects" panel where we only have "box shadow" so far.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. So this panel would replace the block inspector Advanced section, once it's expanded to handle custom classes etc.?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's my hope but I'm not entirely sure. Visually at least, it helps creates a relation between the two panels (local and global ones)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand. Visually the custom CSS panel in this branch looks the same as in trunk; they both use similar fonts and spacing as the block inspector panels.

Is the idea to potentially add custom CSS to the block inspector so it can be set on individual blocks? Right now the logic in this AdvancedPanel is pretty specific to custom CSS.

Copy link
Contributor Author

@youknowriad youknowriad May 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand. Visually the custom CSS panel in this branch looks the same as in trunk; they both use similar fonts and spacing as the block inspector panels.
Is the idea to potentially add custom CSS to the block inspector so it can be set on individual blocks? Right now the logic in this AdvancedPanel is pretty specific to custom CSS.

My logic is the following. Within "inspector controls" we have "panels" and each panel has "controls".

  • Typography panel has a dozen of controls (font size, font family, line height...)
  • Color panel has some controls too (background, text, link, ...)
  • Dimensions panel has some controls too (height, width, padding, margin...)
  • Effects panel has some controls (only box shadows now)
  • Filters panel has some controls (only duotone now)
  • Advanced panel has some controls too (custom CSS). It turns out that for this one right now, custom CSS is global style only and the rest are block inspector only, that said, it was the same for "duotone" when I implemented the panel, and I believe it's the same for the effects panel too. But it doesn't mean that it will always be the case, custom CSS can be added to block inspector at any point.

Does that make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

custom CSS can be added to block inspector at any point

If that's the case then it makes sense to have this here. Though if we ever add more global styles controls here, it might be better to change the name of the site editor component from CustomCSSControl to something more generic too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

better to change the name of the site editor component from CustomCSSControl to something more generic too.

I actually agree with this, It should be AdvancedPanel too there too. It's just that I got confused, I thought you were discussing the ones in the block editor package. I'll make the update.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so I just took a look again. I think the issue right now with the naming is that we access the panel by clicking "Additional CSS" button and going into an "Custom CSS screen" which contains this component.

So if I update CustomCSSControl to AdvancedPanel, I'll be just moving the issue to another place because the CustomCSSScreen will include AdvancedPanel. (so same issue).

I think this is just a temporary issue though that will be solved when we unify the whole block sidebar in #49428 since we'll just be rendering all the panels inline exactly like the block inspector. So I think we shouldn't be doing anything here for now until the other PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense! Another thing that would be good to look at in a follow up would be adding a "reset" button that wipes any user-added CSS and restores the theme CSS if there is any.

value,
onChange,
inheritedValue = value,
} ) {
// Custom CSS
const [ cssError, setCSSError ] = useState( null );
const customCSS = inheritedValue?.css;
function handleOnChange( newValue ) {
onChange( {
...value,
css: newValue,
} );
if ( cssError ) {
const [ transformed ] = transformStyles(
[ { css: value } ],
'.editor-styles-wrapper'
);
if ( transformed ) {
setCSSError( null );
}
}
}
function handleOnBlur( event ) {
if ( ! event?.target?.value ) {
setCSSError( null );
return;
}

const [ transformed ] = transformStyles(
[ { css: event.target.value } ],
'.editor-styles-wrapper'
);

setCSSError(
transformed === null
? __( 'There is an error with your CSS structure.' )
: null
);
}

return (
<VStack spacing={ 3 }>
<TextareaControl
label={ __( 'Additional CSS' ) }
__nextHasNoMarginBottom
value={ customCSS }
onChange={ ( newValue ) => handleOnChange( newValue ) }
onBlur={ handleOnBlur }
className="block-editor-global-styles-advanced-panel__custom-css-input"
spellCheck={ false }
/>
{ cssError && (
<Tooltip text={ cssError }>
<div className="block-editor-global-styles-advanced-panel__custom-css-validation-wrapper">
<Icon
icon={ info }
className="block-editor-global-styles-advanced-panel__custom-css-validation-icon"
/>
</div>
</Tooltip>
) }
</VStack>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,7 @@ export function useGlobalStyle(
let rawResult, result;
switch ( source ) {
case 'all':
rawResult =
// The styles.css path is allowed to be empty, so don't revert to base if undefined.
finalPath === 'styles.css'
? get( userConfig, finalPath )
: get( mergedConfig, finalPath );
rawResult = get( mergedConfig, finalPath );
result = shouldDecodeEncode
? getValueFromVariable( mergedConfig, blockName, rawResult )
: rawResult;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ export { default as BorderPanel, useHasBorderPanel } from './border-panel';
export { default as ColorPanel, useHasColorPanel } from './color-panel';
export { default as EffectsPanel, useHasEffectsPanel } from './effects-panel';
export { default as FiltersPanel, useHasFiltersPanel } from './filters-panel';
export { default as AdvancedPanel } from './advanced-panel';
14 changes: 14 additions & 0 deletions packages/block-editor/src/components/global-styles/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,17 @@
height: 24px;
width: 24px;
}

.block-editor-global-styles-advanced-panel__custom-css-input textarea {
font-family: $editor_html_font;
}

.block-editor-global-styles-advanced-panel__custom-css-validation-wrapper {
position: absolute;
bottom: $grid-unit-20;
right: $grid-unit * 3;
}

.block-editor-global-styles-advanced-panel__custom-css-validation-icon {
fill: $alert-red;
}
131 changes: 16 additions & 115 deletions packages/edit-site/src/components/global-styles/custom-css.js
Original file line number Diff line number Diff line change
@@ -1,130 +1,31 @@
/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';
import {
TextareaControl,
Panel,
PanelBody,
__experimentalVStack as VStack,
Tooltip,
Icon,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import {
privateApis as blockEditorPrivateApis,
transformStyles,
} from '@wordpress/block-editor';
import { info } from '@wordpress/icons';
import { privateApis as blockEditorPrivateApis } from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import { unlock } from '../../private-apis';
import Subtitle from './subtitle';

const { useGlobalStyle } = unlock( blockEditorPrivateApis );
function CustomCSSControl( { blockName } ) {
// If blockName is defined, we are customizing CSS at the block level:
// styles.blocks.blockName.css
const block = !! blockName ? blockName : null;

const [ customCSS, setCustomCSS ] = useGlobalStyle( 'css', block );
const [ themeCSS ] = useGlobalStyle( 'css', block, 'base' );
const [ cssError, setCSSError ] = useState( null );
const ignoreThemeCustomCSS = '/* IgnoreThemeCustomCSS */';

// If there is custom css from theme.json show it in the edit box
// so the user can selectively overwrite it, rather than have the user CSS
// completely overwrite the theme CSS by default.
const themeCustomCSS =
! customCSS && themeCSS
? `/* ${ __(
'Theme Custom CSS start'
) } */\n${ themeCSS }\n/* ${ __( 'Theme Custom CSS end' ) } */`
: undefined;
youknowriad marked this conversation as resolved.
Show resolved Hide resolved

function handleOnChange( value ) {
// If there is theme custom CSS, but the user clears the input box then save the
// ignoreThemeCustomCSS string so that the theme custom CSS is not re-applied.
if ( themeCSS && value === '' ) {
setCustomCSS( ignoreThemeCustomCSS );
return;
}
setCustomCSS( value );
if ( cssError ) {
const [ transformed ] = transformStyles(
[ { css: value } ],
'.editor-styles-wrapper'
);
if ( transformed ) {
setCSSError( null );
}
}
}
const { useGlobalStyle, AdvancedPanel: StylesAdvancedPanel } = unlock(
blockEditorPrivateApis
);

function handleOnBlur( event ) {
if ( ! event?.target?.value ) {
setCSSError( null );
return;
}

const [ transformed ] = transformStyles(
[ { css: event.target.value } ],
'.editor-styles-wrapper'
);

setCSSError(
transformed === null
? __( 'There is an error with your CSS structure.' )
: null
);
}

const originalThemeCustomCSS =
themeCSS && customCSS && themeCustomCSS !== customCSS
? themeCSS
: undefined;
function CustomCSSControl( { blockName } ) {
const [ style ] = useGlobalStyle( '', blockName, 'user', {
shouldDecodeEncode: false,
} );
const [ inheritedStyle, setStyle ] = useGlobalStyle( '', blockName, 'all', {
shouldDecodeEncode: false,
} );

return (
<>
{ originalThemeCustomCSS && (
<Panel>
<PanelBody
title={ __( 'Original Theme Custom CSS' ) }
initialOpen={ false }
>
<pre className="edit-site-global-styles__custom-css-theme-css">
{ originalThemeCustomCSS }
</pre>
</PanelBody>
</Panel>
) }
<VStack spacing={ 3 }>
<Subtitle>{ __( 'Additional CSS' ) }</Subtitle>
<TextareaControl
__nextHasNoMarginBottom
value={
customCSS?.replace( ignoreThemeCustomCSS, '' ) ||
themeCustomCSS
}
onChange={ ( value ) => handleOnChange( value ) }
onBlur={ handleOnBlur }
className="edit-site-global-styles__custom-css-input"
spellCheck={ false }
/>
{ cssError && (
<Tooltip text={ cssError }>
<div className="edit-site-global-styles__custom-css-validation-wrapper">
<Icon
icon={ info }
className="edit-site-global-styles__custom-css-validation-icon"
/>
</div>
</Tooltip>
) }
</VStack>
</>
<StylesAdvancedPanel
value={ style }
onChange={ setStyle }
inheritedValue={ inheritedStyle }
/>
);
}

Expand Down
24 changes: 1 addition & 23 deletions packages/edit-site/src/components/global-styles/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
.components-v-stack {
flex: 1 1 auto;

.edit-site-global-styles__custom-css-input {
.block-editor-global-styles-advanced-panel__custom-css-input {
flex: 1 1 auto;
display: flex;
flex-direction: column;
Expand All @@ -149,28 +149,6 @@
}
}

.edit-site-global-styles__custom-css-input textarea {
font-family: $editor_html_font;
}

.edit-site-global-styles__custom-css-validation-wrapper {
position: absolute;
bottom: $grid-unit-20;
right: $grid-unit * 3;
}

.edit-site-global-styles__custom-css-validation-icon {
fill: $alert-red;
}

.edit-site-global-styles__custom-css-theme-css {
width: 100%;
line-break: anywhere;
white-space: break-spaces;
max-height: 200px;
overflow-y: scroll;
}

.edit-site-global-styles-screen-css-help-link {
display: block;
margin-top: $grid-unit-10;
Expand Down