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

Button: Use CSS-in-JS #26340

Closed
wants to merge 16 commits into from
Closed

Conversation

sarayourfriend
Copy link
Contributor

@sarayourfriend sarayourfriend commented Oct 21, 2020

Description

Use CSS-in-JS for the Button component.

Note: This is just one approach of many that can be taken. I'm not attached to it in any way and dislike parts of it (see inline comments). Hopefully @ItsJonQ will have some guidance 😺

How has this been tested?

Confirmed there are no visual differences between this branch and the production storybook buttons. Also verified in Gutenberg itself that buttons continue to appear and work the same.

Screenshots

Before:
Captura de Tela 2020-10-20 às 20 42 55

After:
Captura de Tela 2020-10-20 às 20 42 53

Types of changes

Non-breaking CSS-in-JS change. This change preserves the existing classnames ensuring anyone targeting them will still be able to do so (for example, storybook itself).

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

Comment on lines 26 to 99
const getBaseStyles = ( props ) => {
if ( props.isPrimary ) {
return buttonStyles.primary.styles;
}

if ( props.isSecondary ) {
return buttonStyles.secondary.styles;
}

if ( props.isTertiary ) {
return buttonStyles.tertiary.styles;
}

if ( props.isLink ) {
if ( props.isDestructive ) {
return css`
${ buttonStyles.link.styles }
${ buttonStyles.link.destructive }
`;
}
return buttonStyles.link.styles;
}

// check pure destructive last to allow for destructive links
if ( props.isDestructive ) {
return buttonStyles.destructive.styles;
}

return buttonStyles.shared.buttonBase;
};

const getBusyStyles = ( props ) => {
if ( ! props.isBusy ) {
return '';
}

if ( props.isPrimary ) {
return buttonStyles.busy.primary;
}

return buttonStyles.busy.generic;
};

const getPressedStyles = ( props ) => {
if ( props.isPressed ) {
return buttonStyles.shared.pressed;
}

return '';
};

const getSmallStyles = ( props, hasIcon, hasText ) => {
if ( props.isSmall ) {
if ( hasIcon && ! hasText ) {
return buttonStyles.shared.smallOnlyIcon;
}

return buttonStyles.shared.small;
}

return '';
};

const getIconStyles = ( hasIcon, hasText ) => {
if ( hasIcon ) {
if ( hasText ) {
return buttonStyles.shared.iconWithText;
}

return buttonStyles.shared.icon;
}

return '';
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't love this whole slew of functions. Any ideas for how to improve this or different approaches that could be taken to accomplish the same thing would be very welcome.

Comment on lines -34 to +35
200: '#ddd', // Used for most borders.
300: '#ddd', // Used for most borders.
200: '#e0e0e0',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure about this change. These colors originally did not correspond with the colors in the Sass variables. This change aligns them, but maybe they weren't meant to be aligned in the first place?

@@ -169,6 +170,7 @@ export const COLORS = {
darkOpacity: DARK_OPACITY,
darkOpacityLight: DARK_OPACITY_LIGHT,
mediumGray: G2.mediumGray,
gray: G2.gray,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also not sure if exposing gray in this way is desirable or if these are meant to be aliased with names.

@github-actions
Copy link

github-actions bot commented Oct 21, 2020

Size Change: +2.47 kB (0%)

Total Size: 1.2 MB

Filename Size Change
build/a11y/index.js 1.14 kB -1 B
build/block-directory/index.js 8.59 kB -1 B
build/block-editor/index.js 130 kB +21 B (0%)
build/block-library/index.js 145 kB +10 B (0%)
build/block-serialization-default-parser/index.js 1.78 kB +3 B (0%)
build/blocks/index.js 47.6 kB +36 B (0%)
build/components/index.js 174 kB +3.8 kB (2%)
build/components/style-rtl.css 14.5 kB -899 B (6%)
build/components/style.css 14.5 kB -901 B (6%)
build/compose/index.js 9.63 kB +2 B (0%)
build/core-data/index.js 12.1 kB +1 B
build/data/index.js 8.63 kB +6 B (0%)
build/deprecated/index.js 773 B +1 B
build/edit-navigation/index.js 10.8 kB +3 B (0%)
build/edit-post/index.js 306 kB -12 B (0%)
build/edit-site/index.js 22.1 kB +402 B (1%)
build/edit-site/style-rtl.css 3.79 kB +6 B (0%)
build/edit-site/style.css 3.79 kB +5 B (0%)
build/edit-widgets/index.js 26.6 kB -14 B (0%)
build/editor/index.js 42.6 kB -5 B (0%)
build/element/index.js 4.45 kB +1 B
build/format-library/index.js 7.49 kB -1 B
build/html-entities/index.js 621 B -1 B
build/i18n/index.js 3.55 kB +2 B (0%)
build/keyboard-shortcuts/index.js 2.39 kB +1 B
build/list-reusable-blocks/index.js 3.02 kB +1 B
build/media-utils/index.js 5.13 kB +4 B (0%)
build/notices/index.js 1.69 kB +1 B
build/nux/index.js 3.27 kB +1 B
build/plugins/index.js 2.44 kB -2 B (0%)
build/primitives/index.js 1.35 kB -1 B
build/reusable-blocks/index.js 3.06 kB -2 B (0%)
build/token-list/index.js 1.24 kB +1 B
build/viewport/index.js 1.75 kB +2 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/annotations/index.js 3.54 kB 0 B
build/api-fetch/index.js 3.35 kB 0 B
build/autop/index.js 2.72 kB 0 B
build/blob/index.js 668 B 0 B
build/block-directory/style-rtl.css 943 B 0 B
build/block-directory/style.css 942 B 0 B
build/block-editor/style-rtl.css 11 kB 0 B
build/block-editor/style.css 11 kB 0 B
build/block-library/editor-rtl.css 8.93 kB 0 B
build/block-library/editor.css 8.93 kB 0 B
build/block-library/style-rtl.css 7.75 kB 0 B
build/block-library/style.css 7.75 kB 0 B
build/block-library/theme-rtl.css 741 B 0 B
build/block-library/theme.css 741 B 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/data-controls/index.js 684 B 0 B
build/date/index.js 31.9 kB 0 B
build/dom-ready/index.js 569 B 0 B
build/dom/index.js 4.43 kB 0 B
build/edit-navigation/style-rtl.css 881 B 0 B
build/edit-navigation/style.css 885 B 0 B
build/edit-post/style-rtl.css 6.37 kB 0 B
build/edit-post/style.css 6.35 kB 0 B
build/edit-widgets/style-rtl.css 3.09 kB 0 B
build/edit-widgets/style.css 3.09 kB 0 B
build/editor/editor-styles-rtl.css 480 B 0 B
build/editor/editor-styles.css 482 B 0 B
build/editor/style-rtl.css 3.85 kB 0 B
build/editor/style.css 3.84 kB 0 B
build/escape-html/index.js 733 B 0 B
build/format-library/style-rtl.css 547 B 0 B
build/format-library/style.css 548 B 0 B
build/hooks/index.js 1.74 kB 0 B
build/is-shallow-equal/index.js 709 B 0 B
build/keycodes/index.js 1.85 kB 0 B
build/list-reusable-blocks/style-rtl.css 476 B 0 B
build/list-reusable-blocks/style.css 476 B 0 B
build/nux/style-rtl.css 671 B 0 B
build/nux/style.css 668 B 0 B
build/priority-queue/index.js 789 B 0 B
build/redux-routine/index.js 2.85 kB 0 B
build/rich-text/index.js 13 kB 0 B
build/server-side-render/index.js 2.61 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/url/index.js 4.06 kB 0 B
build/warning/index.js 1.13 kB 0 B
build/wordcount/index.js 1.23 kB 0 B

compressed-size-action

@ItsJonQ
Copy link

ItsJonQ commented Oct 21, 2020

@saramarcondes Haiii!! Oh wow! Tackling the Button :D.

This will be an interesting one. An important one as well!


Besides Buttons being used everywhere (often with custom/ad-hoc adjustments)... Buttons are one of the more complex elements within a Component library/framework. This is because they have sooo many variations (e.g. size, variant, states, content (like icon), etc...), and all of these variations can be mixed together.

This complexity is often mirrored in the style code, regardless of language (e.g. Sass, Less, JS, etc...).

With all that being said... I think figuring out how to do this would help set the tone for how we can approach CSS-in-JS in the components package moving forward. That was something I've experienced in past UI framework projects, with the most recent one being G2 Components.


I noticed this PR went with the JSX pragma approach. I left my thoughts on CSS-in-JS JSX pragma in one of your other PRs
#26366 (comment)

I'll copy and paste a part of my thoughts here to make this PR easier to follow:


I would recommend continuing to use styled as your continuing your CSS-in-JS journey within Gutenberg.
It would be consistent with the current (but limited) implementation.

I think introducing the JSX pragma may cause some fragmentation in tidying and refactoring things.

@sarayourfriend sarayourfriend marked this pull request as ready for review October 27, 2020 15:42
@ItsJonQ
Copy link

ItsJonQ commented Oct 27, 2020

@saramarcondes Haii! I've added a "resolver" to hopefully fix some of the style conflicts between Emotion and the other styles, as it relates to specificity and ordering 🙏 .

Please let me know if that code makes sense. Feel free to make any modification as needed!

@ItsJonQ
Copy link

ItsJonQ commented Oct 28, 2020

@saramarcondes Haii! I've made so more updates to the resolver. Hopefully this helps 🙏

📝 Variables

Another thing that's worth noting is that the CSS-in-JS solution does not automatically support CSS variable fallbacks.

It's understandable that Button is using quite a few variables, as it relates to the admin theme color.

Previously, these fallback values were manually added.

We really need to support a more automated way to do this. I wrote a library specifically to try and tackle this issue:
https://github.com/ItsJonQ/stylis-plugin-css-variables

Of course, if we want to use this (or any Emotion/Stylis plugin), we'll need to create a top/app level Provider. One that has a customized Emotion instance with the plugin setup.

Something like this:
https://github.com/ItsJonQ/styled-providers/blob/master/src/emotion/ScopeProvider.js#L9

@ItsJonQ
Copy link

ItsJonQ commented Oct 28, 2020

@saramarcondes Since we're talking about this potential Provider more and more... I wonder if it may be a good idea to move the "magical" resolver solution to it. That way, it's a little bit more explicit in that, the style tags only shift if this StyleProvider is used.

@ItsJonQ ItsJonQ mentioned this pull request Oct 28, 2020
6 tasks
@sarayourfriend
Copy link
Contributor Author

@ItsJonQ I think that's a good idea. In the current state of things I don't think this PR is mergable given that it would interact with style tags introduced outside of wp/components, which seems like something a general component library should not do.

@ItsJonQ
Copy link

ItsJonQ commented Oct 28, 2020

Since we're exploring the idea for a StyleProvider... perhaps we can pick this up again:
#24094

I had created one several months ago. We can add the new resolver in that :)

@gziolo gziolo added the [Package] Components /packages/components label Nov 8, 2020
@sarayourfriend
Copy link
Contributor Author

Closing in favor of focusing on G2-components integration.

@aristath aristath deleted the refactor/use-css-in-js-for-button branch November 10, 2020 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Components /packages/components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants