Skip to content

Add support for per-component stylesheets#8375

Merged
aduth merged 10 commits intomainfrom
aduth-component-stylesheets-2
May 18, 2023
Merged

Add support for per-component stylesheets#8375
aduth merged 10 commits intomainfrom
aduth-component-stylesheets-2

Conversation

@aduth
Copy link
Contributor

@aduth aduth commented May 10, 2023

🛠 Summary of changes

Supports components implementing stylesheet "sidecar" assets, with a similar developer experience to how it functions for JavaScript/TypeScript files.

This is a continuation of the idea originally proposed in #6168, which is now more supportable with USWDS v3's new component-specific imports.

Why?

  • Developer experience consistency, to support accompanying styles for a component in the same way we already support accompanying scripts
  • Improved performance, so that users aren't forced to download style data which isn't relevant to the current page
  • Clearer dependency tracking and separation of concerns, so that there's a closer and more direct connection between styles and the application code that uses it

Results:

This is a minimal proof-of-concept, so the impact is not expected to be drastic.

NODE_ENV=production yarn build:css
brotli-size app/assets/builds/application.css

Before: 29.8kb
After: 29.6kb

📜 Testing Plan

Repeat Testing Plan from #8307. There should be no visual impact of these changes.

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'd like to find a better way to do this, since having some files with @use 'uswds-core' as *; and others with @use 'required' as *; is going to cause confusion, but Sass compilation will error when trying to load both uswds-core and required as separate directives.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

b8b4f67 is a slight improvement at least as far as restoring @use 'uswds-core' as *; as the conventional way to bring USWDS functions in scope.

It might be more streamlined to go the opposite direction, creating a separate "core" entrypoint that we maintain (basically what required is), and change every stylesheet to use that instead. Then, we still have consistency, while only needing one @use 'core' as *;, vs. separate @forward 'required'; @use 'uswds-core' as *;. The downside is this moves away from how someone might expect to use USWDS. It could be interesting to try to add another layer of "interception" like what LGDS does, so that @use 'uswds-core' as *; is actually loading a stylesheet internal to the IdP.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It could be interesting to try to add another layer of "interception" like what LGDS does, so that @use 'uswds-core' as *; is actually loading a stylesheet internal to the IdP.

Gave this a try in 316cfd431. The hard part was figuring out how to load the "original" uswds-core, but I managed it by adding node_modules as a separate load path and referencing the @18f/identity-design-system path from there.

This might create some possible performance impact depending if more load paths causes a lot of filesystem noise, since we only need to resolve node_modules in this one location, but now it'll be the first thing checked for every @forward, @use, and @import.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This might create some possible performance impact depending if more load paths causes a lot of filesystem noise, since we only need to resolve node_modules in this one location, but now it'll be the first thing checked for every @forward, @use, and @import.

Apparently I forgot that node_modules is a load path by default 😅

loadPaths: ['node_modules', ...loadPaths],

@zachmargolis
Copy link
Contributor

Do we have a component in mind we wanted to demo this with?

@aduth
Copy link
Contributor Author

aduth commented May 11, 2023

Do we have a component in mind we wanted to demo this with?

The changes are already updating ClipboardButtonComponent to use this convention. I'd imagine it could apply generally to most of our components, especially ones which map one-to-one with a design system component, or ones with a few component-specific styles. I think it'll be a little trickier at the moment for components which are also implemented in React, but that might be something we could sort out in the future.

Some other good candidates:

  • MemorableDateComponent (design system component)
  • CaptchaSubmitButtonComponent (currently _recaptcha-badge.scss)
  • ClickObserverComponent (currently _click-observer.scss)
  • LanguagePickerComponent (currently _language-picker.scss)
  • ModalComponent (currently _modal.scss)
  • OneTimeCodeInputComponent (currently _one-time-code-input.scss)
  • PasswordToggleComponent (currently _password-toggle.scss)
  • PhoneInputComponent (currently _phone-input.scss)

Ones which would be good to do, but blocked by React usage:

  • AlertComponent
  • AccordionComponent
  • BlockLinkComponent
  • IconComponent
  • MemorableDateComponent
  • PageHeadingComponent (currently _page-heading.scss)
  • SpinnerButtonComponent
  • StepIndicatorComponent
  • TroubleshootingOptionsComponent

I think this would also give us a pattern to create new component semantics around what are currently implemented as ad-hoc CSS classes, e.g.:

  • _code.scss ➡️ CodeSnippetComponent
  • _hr.scss ➡️ SeparatorComponent
  • _password.scss ➡️ PasswordStrengthComponent
  • _personal-key.scss ➡️ PersonalKeyComponent
  • _profile-section.scss ➡️ ProfileSectionComponent

@aduth
Copy link
Contributor Author

aduth commented May 11, 2023

It might be worth considering if there's more harm than good by splitting out e.g. 3 lines of styles to a separate CSS file, but I'm inclined to say "yes" all things considered, as long as the overhead to implement is minimal (it's actually less work in this proposed approach than in the status quo).

@zachmargolis
Copy link
Contributor

The changes are already updating ClipboardButtonComponent to use this convention.

ah whoops yes! the diff to that stylesheet was so small, I didn't register it was a move, makes sense! 👍

2 similar comments
@zachmargolis
Copy link
Contributor

The changes are already updating ClipboardButtonComponent to use this convention.

ah whoops yes! the diff to that stylesheet was so small, I didn't register it was a move, makes sense! 👍

@zachmargolis
Copy link
Contributor

The changes are already updating ClipboardButtonComponent to use this convention.

ah whoops yes! the diff to that stylesheet was so small, I didn't register it was a move, makes sense! 👍

@aduth aduth marked this pull request as ready for review May 11, 2023 20:46
@aduth aduth force-pushed the aduth-component-stylesheets-2 branch from cb360e9 to 4032301 Compare May 12, 2023 13:45
Copy link
Contributor

@zachmargolis zachmargolis left a comment

Choose a reason for hiding this comment

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

LGTM

@aduth aduth force-pushed the aduth-component-stylesheets-2 branch from 4032301 to dfe4e0e Compare May 18, 2023 12:55
@aduth aduth merged commit b9c2334 into main May 18, 2023
@aduth aduth deleted the aduth-component-stylesheets-2 branch May 18, 2023 19:58
dawei-nava pushed a commit that referenced this pull request May 18, 2023
* Add support for per-component stylesheets

changelog: Internal, Optimization, Reduce size of stylesheet assets for critical path

* Forward required to use uswds-core conventionally

* Override _uswds-core via internal load path

* Remove unnecessary load path

* Prioritize `--load-path` flag in Sass load path resolution

* Add specs for component stylesheets

* Add specs for StylesheetHelper

* Rename clipboard component stylesheet to simple scss

* Render stylesheet_once_tags everywhere application is rendered

* Fix component preview for per-component stylesheet
dawei-nava added a commit that referenced this pull request May 18, 2023
* LG-8349: Move AddressSearch component into own package

changelog: Internal, Code Structure, separate AddressSearch UI component as package.

* LG-8439: remove old component.

* LG-8439: package information.

* LG-8439: change log file.

* LG-8439: address comments

* Update app/javascript/packages/address-search/README.md

Co-authored-by: Tim Bradley <90272033+NavaTim@users.noreply.github.com>

* Update app/javascript/packages/address-search/index-spec.tsx

Co-authored-by: Tim Bradley <90272033+NavaTim@users.noreply.github.com>

* LG-8439: extra / not needed.

* Add support for per-component stylesheets (#8375)

* Add support for per-component stylesheets

changelog: Internal, Optimization, Reduce size of stylesheet assets for critical path

* Forward required to use uswds-core conventionally

* Override _uswds-core via internal load path

* Remove unnecessary load path

* Prioritize `--load-path` flag in Sass load path resolution

* Add specs for component stylesheets

* Add specs for StylesheetHelper

* Rename clipboard component stylesheet to simple scss

* Render stylesheet_once_tags everywhere application is rendered

* Fix component preview for per-component stylesheet

* LG-8439: resolve conflict

* LG-8439: address comments

* Updating how gpo pending is set in dummy profile (#8434)

* Updating how gpo pending is set in dummy profile

* changelog

[skip changelog]

---------

Co-authored-by: Tim Bradley <90272033+NavaTim@users.noreply.github.com>
Co-authored-by: Andrew Duthie <andrew.duthie@gsa.gov>
Co-authored-by: Eric Gade <105373963+eric-gade@users.noreply.github.com>
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.

2 participants