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

SDK: import Calypso UI into a Gutenberg extension and scope styles #26683

Closed
wants to merge 15 commits into from

Conversation

simison
Copy link
Member

@simison simison commented Aug 14, 2018

(Based on @dmsnell earlier work in #26541)

See also #26820

Scopes imported Calypso component styles with .calypso CSS class.

Ends up with styles like this:

.calypso .ribbon.is-green .ribbon__title::after {
  border-right-color: #2c703d;
  border-top-color: #2c703d;
}
.wp-block-a8c-editor-notes__box {
  background-color: #fdf7f7;
  border-color: #d94f4f;
}

Namespacer library

Existing solutions for namespacing (namespace-css, postcss-prefixwrap) seem to lack support for scoping things like @keyframes and @font, so there's a change that we would need to build our own CSS-name-spacer to really scope all CSS that Calypso components have. Fortunately, it's fairly straightforward
as demonstrated in Gutenberg.

I've wrapped the whole Gutenberg block with calypso CSS class but that's not ideal; Gutenberg block should not need to know anything about CSS scopes and this should all be manual. See other explorations for automating that part in #26852 and #26851

Resets and other shared styles

I didn't import shared styles like CSS-resets or typography.

Editor styles leaking in

If you can observe .card CSS class coming from Gutenberg overwriting some styles. This is a problem.

Testing

  1. Build the extension:

    npm run sdk:gutenberg -- --editor-script=client/gutenberg/extensions/editor-notes/index.js
  2. Open compiled CSS client/gutenberg/extensions/editor-notes/build/editor-notes-editor.css

    • Calypso components are namespaced with .calypso
    • Block styles aren't scoped (look for .wp-block-a8c-editor-notes__box)
    • Mixins and colour constants worked for both Calypso components and block styles:
      • No z-index: z-index( '.ribbon', '.ribbon__title::before' ); but z-index: -1
      • No $white but white in Calypso components
      • No $alert-red but #d94f4f in block styles
  3. Confirm the block works in Gutenberg outside Calypso
    image

  4. Confirm that this doesn't affect Calypso builds

@matticbot
Copy link
Contributor

@simison simison force-pushed the try/global-sass-prefix-calypso branch from 70abd52 to 9e55b90 Compare August 17, 2018 07:25
@simison simison added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] In Progress labels Aug 17, 2018
@simison simison changed the title SDK: explore importing Calypso UI into a Gutenberg extension, take two SDK: import Calypso UI into a Gutenberg extension and namespace styles Aug 17, 2018
@simison
Copy link
Member Author

simison commented Aug 17, 2018

Looks like @import's are failing in Jest → needs some more work. I'd be happy for a half-way review, though.

@simison
Copy link
Member Author

simison commented Aug 17, 2018

const baseConfig = getBaseConfig( {
externalizeWordPressPackages: true,
stylesNamespacing: 'calypso',
stylesNamespacingExclude: path.join( __rootDir, 'client', 'gutenberg' ),
Copy link
Member

Choose a reason for hiding this comment

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

do we need a customizable exclude list? do you think we could get by with a whitelist instead just namespacing Calypso's components directory and maybe some others?

Copy link
Member Author

Choose a reason for hiding this comment

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

You had the right intuition — it was indeed possible to simplify this and get rid of the custom exclusion-list. Thanks for pointing it out!

@simison simison force-pushed the try/global-sass-prefix-calypso branch from f3b95d2 to 07e5716 Compare August 17, 2018 12:55
@simison
Copy link
Member Author

simison commented Aug 17, 2018

Looks like wp-desktop tests are failing and Webpack config would need sass-loader added there, too.

*
* @param {object} env environment options
* @param {boolean} env.externalizeWordPressPackages whether to bundle or extern the `@wordpress/` packages
* @param {string} env.stylesNamespacing prefix Calypso component styles with CSS class or ID
Copy link
Member

@dmsnell dmsnell Aug 17, 2018

Choose a reason for hiding this comment

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

probably singular might work more naturally here…

/**
 * @param {string} styleNamespace prefix Calypso component styles with this class or ID
 */

also of not here leading back to my earlier comment - the explanation is that this applies to Calypso components but we're only excluding specific directories. is it more difficult to whitelist directories instead? if the exclude-list is better then we should probably update this comment to make that less confusing

(could even see cssNamespace being clearer - no strong opinion though)

dmsnell and others added 5 commits August 22, 2018 12:33
In this patch I'm doing two things at once to reach the goal of using
Calypso UI components: pulling in the UI code and pulling in the styles.

As you may note I'm bringing in the entirety of the Calypso styles since
the framework styles are monolithic. This has the immediate drawback
that the stylesheet is over a megabyte in size, but the immediate
advantage that we can import Calypso UI and not have to write it all
ourselves.

If this turns out to be a good path then we will obviously have to
optimize the CSS, which is already in the plans. As the SDK and Calypso
framework improves we should see that bundled CSS drop down to very
small sizes. Currently the framework isn't ready to split apart the CSS
though I'm afraid.
Previously we were pulling in the top-level stylesheet from Calypso
and we were doing so from the top of the extension code. This pulled
in over a megabyte of CSS and required us to be aware of Calypso's
styling and style paths.

In this change I have updated the `Card` and `Ribbon` components so
that they explicitly import their SASS dependencies. This allows us
to pull in _only_ the required style when building the extension.

The output dropped from a megabyte to three kilobytes.
> - configuration.module.rules[2].exclude should be one of these:
>   RegExp | non-empty string | function | [RegExp | non-empty string | function | (recursive) | object { and?, exclude?, include?, not?, or?, test? }] | object { and?, exclude?, include?, not?, or?, test? }

Setting it to `undefined`  would work as well.
@simison simison force-pushed the try/global-sass-prefix-calypso branch from c72ff9c to 052349f Compare August 22, 2018 09:43
@simison simison added [Status] In Progress and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Aug 24, 2018
@simison simison changed the title SDK: import Calypso UI into a Gutenberg extension and namespace styles SDK: import Calypso UI into a Gutenberg extension and scope styles Aug 24, 2018
Copy link
Member

@tyxla tyxla left a comment

Choose a reason for hiding this comment

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

It seems the styles are being loaded as scripts when I run a regular Calypso build locally:


@@ -1,3 +1,5 @@
@import '../../../assets/stylesheets/shared/_utils.scss';
Copy link
Member

Choose a reason for hiding this comment

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

We seem to need only:

  • assets/stylesheets/shared/_colors.scss
  • assets/stylesheets/shared/mixins/clear-fix.scss
  • assets/stylesheets/shared/mixins/breakpoints.scss

How do you feel about being even more specific and listing them specifically? Being granular enough will hopefully result in smaller bundle sizes.

@@ -1,3 +1,5 @@
@import '../../../assets/stylesheets/shared/_utils.scss';
Copy link
Member

Choose a reason for hiding this comment

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

We seem to need only:

  • assets/stylesheets/shared/_colors.scss
  • assets/stylesheets/shared/functions/_z-index.scss

How do you feel about being even more specific and listing them specifically? Being granular enough will hopefully result in smaller bundle sizes.

) }
const edit = ( { attributes: { notes }, className, setAttributes } ) => (
<Card highlight="error" className={ `${ className } ${ className }__box calypso` }>
<Ribbon>Hidden</Ribbon>
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we should localize this string?

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe we should localize this string?

We definitely should give it a try! 😍

Copy link
Member

Choose a reason for hiding this comment

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

Let's wait until we have some more clarity on i18n, before we dip our toes into this :)

@@ -14,23 +16,16 @@ const attributes = {
},
};

const edit = ( { attributes: { notes }, className, isSelected, setAttributes } ) => (
<div className={ isSelected ? 'is-selected' : '' }>
{ ! isSelected && (
Copy link
Member

Choose a reason for hiding this comment

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

Any good reason to be getting rid of this functionality? It was nice to have the notebook icon while editing the block content.

*
* @param {object} env environment options
* @param {boolean} env.externalizeWordPressPackages whether to bundle or extern the `@wordpress/` packages
* @param {string} env.styleNamespace prefix Calypso component styles with CSS class or ID
Copy link
Member

Choose a reason for hiding this comment

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

Nit: param description seems to be misaligned here

* @param {object} env additional config options
* @param {boolean} env.externalizeWordPressPackages whether to bundle or extern the `@wordpress/` packages
* @param {object} argv given by webpack?
* `env` params are typically set by files in `bin/sdk/*`
Copy link
Member

Choose a reason for hiding this comment

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

This comment might be confusing for anyone who isn't familiar with the SDK. Would you mind clarifying what can be found in bin/sdk/*? Or is there a chance we're leaking SDK functionality out of the SDK directory too much?

};

// When styles-namespacing is enabled, these are the files we want to namespace
const styleNamespaceDirectories = [ path.join( __dirname, 'client', 'components' ) ];
Copy link
Member

Choose a reason for hiding this comment

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

From the outside perspective, it feels a little inconsistent to namespace only components, and not namespace the block stylesheets. If I'm an external plugin/theme developer, I'd be confused why some stylesheets have the prefix and others don't. What do you think?

Theory is that this doesn't have any affect.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants