From 8e85fe56f35ecf5cda423eb4a2f35088bff19079 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 6 Apr 2022 15:35:23 -0400 Subject: [PATCH 1/6] Ensure CSS file extension for ".css" files --- app/javascript/packages/build-sass/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/packages/build-sass/index.js b/app/javascript/packages/build-sass/index.js index 07a6b71fdc2..0888e576cb3 100644 --- a/app/javascript/packages/build-sass/index.js +++ b/app/javascript/packages/build-sass/index.js @@ -44,7 +44,7 @@ export async function buildFile(file, options) { const postcssPlugins = compact([autoprefixer, optimize && cssnano]); const postcssResult = await postcss(postcssPlugins).process(sassResult.css, { from: file }); - let outFile = basename(file, '.scss'); + let outFile = `${basename(basename(file, '.scss'), '.css')}.css`; if (outDir) { outFile = join(outDir, outFile); } From df2e1b37c45be7a5e079aeafb539140a306912ad Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 6 Apr 2022 15:40:34 -0400 Subject: [PATCH 2/6] Extract component-specific stylesheets **Why**: So that, like with component-specific scripts, we can create stylesheet bundles which are loaded only on pages where the component is used, rather than as part of the single common "application" stylesheet, thereby reducing the size of the common stylesheet, and allowing for stylesheets to be broken up for parallel download. changelog: Internal, Optimization, Reduce size of common stylesheet --- app/assets/stylesheets/application.css.scss | 3 +- app/assets/stylesheets/components/all.scss | 1 - .../stylesheets/document-capture.css.scss | 2 - .../stylesheets/utilities/_typography.scss | 54 ----------- app/assets/stylesheets/variables/_app.scss | 15 --- app/assets/stylesheets/variables/_vendor.scss | 20 ---- app/components/base_component.rb | 30 ++++-- .../troubleshooting_options_component.rb | 4 + app/helpers/stylesheet_helper.rb | 16 ++++ app/javascript/packages/build-sass/cli.js | 5 +- .../packages/build-sass/package.json | 1 + .../components/troubleshooting-options.scss} | 2 + .../packages/document-capture/styles.scss | 2 +- .../packages/idp-required-scss/README.md | 3 + .../packages/idp-required-scss/_index.scss | 92 +++++++++++++++++++ .../packages/idp-required-scss/package.json | 8 ++ app/views/layouts/base.html.erb | 1 + package.json | 2 +- yarn.lock | 2 +- 19 files changed, 159 insertions(+), 104 deletions(-) delete mode 100644 app/assets/stylesheets/document-capture.css.scss delete mode 100644 app/assets/stylesheets/variables/_vendor.scss create mode 100644 app/helpers/stylesheet_helper.rb rename app/{assets/stylesheets/components/_troubleshooting-options.scss => javascript/packages/components/troubleshooting-options.scss} (90%) create mode 100644 app/javascript/packages/idp-required-scss/README.md create mode 100644 app/javascript/packages/idp-required-scss/_index.scss create mode 100644 app/javascript/packages/idp-required-scss/package.json diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss index eb8c42e8c6e..d88f49e4269 100644 --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -1,7 +1,6 @@ @import 'variables/app'; -@import 'required'; +@import '@18f/identity-idp-required-scss'; @import 'design-system-waiting-room'; -@import 'identity-style-guide/dist/assets/scss/packages/required'; @import 'identity-style-guide/dist/assets/scss/packages/global'; @import 'identity-style-guide/dist/assets/scss/packages/components'; @import 'components/all'; diff --git a/app/assets/stylesheets/components/all.scss b/app/assets/stylesheets/components/all.scss index 54a41872b5b..2905b4889fa 100644 --- a/app/assets/stylesheets/components/all.scss +++ b/app/assets/stylesheets/components/all.scss @@ -22,5 +22,4 @@ @import 'spinner-dots'; @import 'full-screen'; @import 'step-indicator'; -@import 'troubleshooting-options'; @import 'i18n-dropdown'; diff --git a/app/assets/stylesheets/document-capture.css.scss b/app/assets/stylesheets/document-capture.css.scss deleted file mode 100644 index 5fc7f686456..00000000000 --- a/app/assets/stylesheets/document-capture.css.scss +++ /dev/null @@ -1,2 +0,0 @@ -@import 'required'; -@import '../../javascript/packages/document-capture/styles'; diff --git a/app/assets/stylesheets/utilities/_typography.scss b/app/assets/stylesheets/utilities/_typography.scss index 9b8678f5bc0..00c096a2dd0 100644 --- a/app/assets/stylesheets/utilities/_typography.scss +++ b/app/assets/stylesheets/utilities/_typography.scss @@ -16,60 +16,6 @@ body { font-size: 20px; } -%h1 { - line-height: 1.35; - font-size: $h1; - - @include at-media('tablet') { - font-size: $sm-h1; - } -} - -%h2 { - line-height: 1.35; - font-size: $h2; - - @include at-media('tablet') { - font-size: $sm-h2; - } -} - -%h3 { - line-height: $line-height; - font-size: $h3; - - @include at-media('tablet') { - font-size: $sm-h3; - } -} - -%h4 { - line-height: $line-height; - font-size: $h4; - - @include at-media('tablet') { - font-size: $sm-h4; - } -} - -%h5 { - line-height: $line-height; - font-size: $h5; - - @include at-media('tablet') { - font-size: $sm-h5; - } -} - -%h6 { - line-height: $line-height; - font-size: $h6; - - @include at-media('tablet') { - font-size: $sm-h6; - } -} - h1, .h1 { @extend %h1; diff --git a/app/assets/stylesheets/variables/_app.scss b/app/assets/stylesheets/variables/_app.scss index 29152ee8a55..9856ea451b7 100644 --- a/app/assets/stylesheets/variables/_app.scss +++ b/app/assets/stylesheets/variables/_app.scss @@ -1,21 +1,6 @@ -$line-height: 1.5 !default; $bold-font-weight: bold !default; $heading-font-weight: bold !default; -$h1: 1.5rem !default; -$h2: 1.25rem !default; -$h3: 1.125rem !default; -$h4: 1rem !default; -$h5: 0.875rem !default; -$h6: 0.75rem !default; - -$sm-h1: 1.75rem !default; -$sm-h2: 1.375rem !default; -$sm-h3: 1.125rem !default; -$sm-h4: 1rem !default; -$sm-h5: 0.875rem !default; -$sm-h6: 0.75rem !default; - $form-field-font-size-sm: 1.25rem !default; $border-width: 1px !default; diff --git a/app/assets/stylesheets/variables/_vendor.scss b/app/assets/stylesheets/variables/_vendor.scss deleted file mode 100644 index d1bb16c2ed2..00000000000 --- a/app/assets/stylesheets/variables/_vendor.scss +++ /dev/null @@ -1,20 +0,0 @@ -$theme-body-font-size: 'sm'; -$theme-font-path: '.'; -$theme-image-path: 'identity-style-guide/dist/assets/img'; -$theme-global-border-box-sizing: true; -$theme-global-link-styles: true; -$theme-grid-container-max-width: 'tablet-lg'; -$theme-header-min-width: 'tablet'; -$theme-link-visited-color: 'primary'; -$theme-style-body-element: true; -$theme-utility-breakpoints: ( - 'card': false, - 'card-lg': false, - 'mobile': false, - 'mobile-lg': false, - 'tablet': true, - 'tablet-lg': false, - 'desktop': false, - 'desktop-lg': false, - 'widescreen': false, -); diff --git a/app/components/base_component.rb b/app/components/base_component.rb index 9b445580b21..b1adc94c8fd 100644 --- a/app/components/base_component.rb +++ b/app/components/base_component.rb @@ -1,17 +1,35 @@ class BaseComponent < ViewComponent::Base def before_render - return if @rendered_scripts - @rendered_scripts = true - if helpers.respond_to?(:enqueue_component_scripts) && self.class.scripts.present? - helpers.enqueue_component_scripts(*self.class.scripts) - end + render_assets unless @has_rendered_assets end def self.scripts - @scripts ||= _sidecar_files(['js', 'ts']).map { |file| File.basename(file, '.*') } + @scripts ||= sidecar_files_basenames(['js', 'ts']) + end + + def self.stylesheets + @stylesheets ||= sidecar_files_basenames(['scss']) end def unique_id @unique_id ||= SecureRandom.hex(4) end + + private + + def self.sidecar_files_basenames(extensions) + _sidecar_files(extensions).map { |file| File.basename(file, '.*') } + end + + def render_assets + if helpers.respond_to?(:enqueue_component_scripts) && self.class.scripts.present? + helpers.enqueue_component_scripts(*self.class.scripts) + end + + if helpers.respond_to?(:enqueue_component_stylesheets) && self.class.stylesheets.present? + helpers.enqueue_component_stylesheets(*self.class.stylesheets) + end + + @has_rendered_assets = true + end end diff --git a/app/components/troubleshooting_options_component.rb b/app/components/troubleshooting_options_component.rb index 16f97a9d042..768e0adf75d 100644 --- a/app/components/troubleshooting_options_component.rb +++ b/app/components/troubleshooting_options_component.rb @@ -4,6 +4,10 @@ class TroubleshootingOptionsComponent < BaseComponent attr_reader :tag_options + def self.stylesheets + ['troubleshooting-options'] + end + def initialize(**tag_options) @tag_options = tag_options end diff --git a/app/helpers/stylesheet_helper.rb b/app/helpers/stylesheet_helper.rb new file mode 100644 index 00000000000..c9a32171e53 --- /dev/null +++ b/app/helpers/stylesheet_helper.rb @@ -0,0 +1,16 @@ +# rubocop:disable Rails/HelperInstanceVariable +module StylesheetHelper + def stylesheet_tag_once(*names) + @stylesheets ||= [] + @stylesheets |= names + nil + end + + alias_method :enqueue_component_stylesheets, :stylesheet_tag_once + + def render_stylesheet_once_tags + return if @stylesheets.blank? + safe_join(@stylesheets.map { |stylesheet| stylesheet_link_tag(stylesheet) }) + end +end +# rubocop:enable Rails/HelperInstanceVariable diff --git a/app/javascript/packages/build-sass/cli.js b/app/javascript/packages/build-sass/cli.js index 43164037e58..81aa0c0e43f 100755 --- a/app/javascript/packages/build-sass/cli.js +++ b/app/javascript/packages/build-sass/cli.js @@ -3,6 +3,7 @@ /* eslint-disable no-console */ import { watch } from 'chokidar'; +import glob from 'fast-glob'; import { fileURLToPath } from 'url'; import { buildFile } from './index.js'; @@ -13,12 +14,14 @@ const env = process.env.NODE_ENV || process.env.RAILS_ENV || 'development'; const isProduction = env === 'production'; const args = process.argv.slice(2); -const files = args.filter((arg) => !arg.startsWith('-')); +const patterns = args.filter((arg) => !arg.startsWith('-')); const flags = args.filter((arg) => arg.startsWith('-')); const isWatching = flags.includes('--watch'); const outDir = flags.find((flag) => flag.startsWith('--out-dir='))?.slice(10); +const files = glob.sync(patterns); + /** @type {BuildOptions & SyncSassOptions} */ const options = { outDir, optimize: isProduction }; diff --git a/app/javascript/packages/build-sass/package.json b/app/javascript/packages/build-sass/package.json index a5dd3ef5f56..f7af8d5c3cc 100644 --- a/app/javascript/packages/build-sass/package.json +++ b/app/javascript/packages/build-sass/package.json @@ -10,6 +10,7 @@ "autoprefixer": "^10.4.4", "chokidar": "^3.5.3", "cssnano": "^5.1.7", + "fast-glob": "^3.2.11", "postcss": "^8.4.12", "sass": "^1.49.0" } diff --git a/app/assets/stylesheets/components/_troubleshooting-options.scss b/app/javascript/packages/components/troubleshooting-options.scss similarity index 90% rename from app/assets/stylesheets/components/_troubleshooting-options.scss rename to app/javascript/packages/components/troubleshooting-options.scss index 41a823e9440..c8c331d50f7 100644 --- a/app/assets/stylesheets/components/_troubleshooting-options.scss +++ b/app/javascript/packages/components/troubleshooting-options.scss @@ -1,3 +1,5 @@ +@import '@18f/identity-idp-required-scss'; + .troubleshooting-options { @include u-margin-y(4); diff --git a/app/javascript/packages/document-capture/styles.scss b/app/javascript/packages/document-capture/styles.scss index aa63ce7562f..b3f76d076fa 100644 --- a/app/javascript/packages/document-capture/styles.scss +++ b/app/javascript/packages/document-capture/styles.scss @@ -1,4 +1,4 @@ -@import 'identity-style-guide/dist/assets/scss/packages/required'; +@import '@18f/identity-idp-required-scss'; @import './components/acuant-capture'; @import './components/acuant-capture-canvas'; @import './components/form-steps'; diff --git a/app/javascript/packages/idp-required-scss/README.md b/app/javascript/packages/idp-required-scss/README.md new file mode 100644 index 00000000000..6819e0db514 --- /dev/null +++ b/app/javascript/packages/idp-required-scss/README.md @@ -0,0 +1,3 @@ +# `@18f/identity-idp-required-scss` + +Minimal Sass configuration and mixins required for any stylesheet which intends to make use of [Login.gov Design System](https://design.login.gov/) utilities. This contains only configuration which is specific to the IdP application, and any program-wide configuration should reside in the [design system codebase](https://github.com/18F/identity-style-guide). diff --git a/app/javascript/packages/idp-required-scss/_index.scss b/app/javascript/packages/idp-required-scss/_index.scss new file mode 100644 index 00000000000..16003ae6f36 --- /dev/null +++ b/app/javascript/packages/idp-required-scss/_index.scss @@ -0,0 +1,92 @@ +@import 'identity-style-guide/dist/assets/scss/packages/required'; + +$theme-body-font-size: 'sm'; +$theme-font-path: '.'; +$theme-image-path: 'identity-style-guide/dist/assets/img'; +$theme-global-border-box-sizing: true; +$theme-global-link-styles: true; +$theme-grid-container-max-width: 'tablet-lg'; +$theme-header-min-width: 'tablet'; +$theme-link-visited-color: 'primary'; +$theme-style-body-element: true; +$theme-utility-breakpoints: ( + 'card': false, + 'card-lg': false, + 'mobile': false, + 'mobile-lg': false, + 'tablet': true, + 'tablet-lg': false, + 'desktop': false, + 'desktop-lg': false, + 'widescreen': false, +); + +$line-height: 1.5; + +$h1: 1.5rem; +$h2: 1.25rem; +$h3: 1.125rem; +$h4: 1rem; +$h5: 0.875rem; +$h6: 0.75rem; + +$sm-h1: 1.75rem; +$sm-h2: 1.375rem; +$sm-h3: 1.125rem; +$sm-h4: 1rem; +$sm-h5: 0.875rem; +$sm-h6: 0.75rem; + +%h1 { + line-height: 1.35; + font-size: $h1; + + @include at-media('tablet') { + font-size: $sm-h1; + } +} + +%h2 { + line-height: 1.35; + font-size: $h2; + + @include at-media('tablet') { + font-size: $sm-h2; + } +} + +%h3 { + line-height: $line-height; + font-size: $h3; + + @include at-media('tablet') { + font-size: $sm-h3; + } +} + +%h4 { + line-height: $line-height; + font-size: $h4; + + @include at-media('tablet') { + font-size: $sm-h4; + } +} + +%h5 { + line-height: $line-height; + font-size: $h5; + + @include at-media('tablet') { + font-size: $sm-h5; + } +} + +%h6 { + line-height: $line-height; + font-size: $h6; + + @include at-media('tablet') { + font-size: $sm-h6; + } +} diff --git a/app/javascript/packages/idp-required-scss/package.json b/app/javascript/packages/idp-required-scss/package.json new file mode 100644 index 00000000000..9816b70ef98 --- /dev/null +++ b/app/javascript/packages/idp-required-scss/package.json @@ -0,0 +1,8 @@ +{ + "name": "@18f/identity-idp-required-scss", + "private": true, + "version": "1.0.0", + "peerDependencies": { + "identity-style-guide": "*" + } +} diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb index 18b3f91f379..67c561b488d 100644 --- a/app/views/layouts/base.html.erb +++ b/app/views/layouts/base.html.erb @@ -29,6 +29,7 @@ <%= preload_link_tag font_url('public-sans/PublicSans-Bold.woff2') %> <%= preload_link_tag font_url('public-sans/PublicSans-Regular.woff2') %> <%= stylesheet_link_tag 'application', media: 'all' %> + <%= render_stylesheet_once_tags %> diff --git a/package.json b/package.json index 2bada0b0363..29a37869327 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "clean": "rm -rf public/packs/*", "prebuild": "yarn run clean", "build": "webpack", - "build:css": "build-sass app/assets/stylesheets/*.css.scss --out-dir=app/assets/builds" + "build:css": "build-sass 'app/assets/stylesheets/*.css.scss' 'app/javascript/packages/*/*.scss' '!**/_*' --out-dir=app/assets/builds" }, "dependencies": { "@babel/core": "^7.15.5", diff --git a/yarn.lock b/yarn.lock index bf159f2e42e..40355cbd868 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4563,7 +4563,7 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@1.2.6, minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.2.0, minimist@^1.2.5: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== From db59bff2cb5388f4e8a5e27863f6d1ef9b5f3c76 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 6 Apr 2022 16:45:27 -0400 Subject: [PATCH 3/6] Create method for rendered assets ivar **Why**: Bit more conventional from condition usage site --- app/components/base_component.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/components/base_component.rb b/app/components/base_component.rb index b1adc94c8fd..56e15060b97 100644 --- a/app/components/base_component.rb +++ b/app/components/base_component.rb @@ -1,6 +1,6 @@ class BaseComponent < ViewComponent::Base def before_render - render_assets unless @has_rendered_assets + render_assets unless rendered_assets? end def self.scripts @@ -32,4 +32,8 @@ def render_assets @has_rendered_assets = true end + + def rendered_assets? + @has_rendered_assets + end end From cfbe98c0a7ec83f3303ec8087b4745393693f2ba Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 6 Apr 2022 16:49:28 -0400 Subject: [PATCH 4/6] Fix lint error for private class method --- app/components/base_component.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/components/base_component.rb b/app/components/base_component.rb index 56e15060b97..a447094dfd4 100644 --- a/app/components/base_component.rb +++ b/app/components/base_component.rb @@ -17,8 +17,10 @@ def unique_id private - def self.sidecar_files_basenames(extensions) - _sidecar_files(extensions).map { |file| File.basename(file, '.*') } + class << self + def sidecar_files_basenames(extensions) + _sidecar_files(extensions).map { |file| File.basename(file, '.*') } + end end def render_assets From d58c71f05cec084c7b6471244d3ab867cd896408 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 6 Apr 2022 16:52:15 -0400 Subject: [PATCH 5/6] Rename document-capture stylesheet to use for pack name --- .../document-capture/{styles.scss => document-capture.scss} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/javascript/packages/document-capture/{styles.scss => document-capture.scss} (100%) diff --git a/app/javascript/packages/document-capture/styles.scss b/app/javascript/packages/document-capture/document-capture.scss similarity index 100% rename from app/javascript/packages/document-capture/styles.scss rename to app/javascript/packages/document-capture/document-capture.scss From c3a62f0900bb55e17d062eda6cf9b76bbb1d8737 Mon Sep 17 00:00:00 2001 From: Andrew Duthie Date: Wed, 6 Apr 2022 16:52:30 -0400 Subject: [PATCH 6/6] Include TroubleshootingOptions stylesheet in document capture --- app/javascript/packages/document-capture/document-capture.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/packages/document-capture/document-capture.scss b/app/javascript/packages/document-capture/document-capture.scss index b3f76d076fa..764bdea6e1d 100644 --- a/app/javascript/packages/document-capture/document-capture.scss +++ b/app/javascript/packages/document-capture/document-capture.scss @@ -1,4 +1,5 @@ @import '@18f/identity-idp-required-scss'; +@import '@18f/identity-components/troubleshooting-options'; @import './components/acuant-capture'; @import './components/acuant-capture-canvas'; @import './components/form-steps';