From 86aeb396cb0e4f4c7a43e3d29464645b8e81e09f Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Fri, 4 Jul 2025 10:56:36 +0200 Subject: [PATCH] Migrate from `ember-css-modules` to `ember-scoped-css` The former isn't particularly well maintained anymore and blocks all sorts of other migration. --- app/app.css | 198 ++++++++ app/app.js | 2 + ...-menu.module.css => color-scheme-menu.css} | 0 app/components/color-scheme-menu.hbs | 13 +- ...st.module.css => crate-downloads-list.css} | 0 app/components/crate-downloads-list.hbs | 6 +- ...ate-header.module.css => crate-header.css} | 2 +- app/components/crate-header.hbs | 16 +- .../{crate-list.module.css => crate-list.css} | 0 app/components/crate-list.hbs | 2 +- .../{crate-row.module.css => crate-row.css} | 6 +- app/components/crate-row.hbs | 29 +- ...e-sidebar.module.css => crate-sidebar.css} | 6 +- app/components/crate-sidebar.hbs | 45 +- ...ns.module.css => install-instructions.css} | 0 .../crate-sidebar/install-instructions.hbs | 42 +- .../{link.module.css => link.css} | 0 app/components/crate-sidebar/link.hbs | 12 +- .../{row.module.css => row.css} | 6 +- app/components/dependency-list/row.hbs | 28 +- ...ad-graph.module.css => download-graph.css} | 0 app/components/download-graph.hbs | 6 +- .../{dropdown.module.css => dropdown.css} | 0 app/components/dropdown.hbs | 2 +- .../{content.module.css => content.css} | 0 app/components/dropdown/content.hbs | 2 +- .../{menu-item.module.css => menu-item.css} | 2 +- app/components/dropdown/menu-item.hbs | 2 +- .../dropdown/{menu.module.css => menu.css} | 0 app/components/dropdown/menu.hbs | 2 +- .../{trigger.module.css => trigger.css} | 0 app/components/dropdown/trigger.hbs | 4 +- .../{edition.module.css => edition.css} | 0 app/components/edition.hbs | 2 +- ...email-input.module.css => email-input.css} | 0 app/components/email-input.hbs | 31 +- ...ow-button.module.css => follow-button.css} | 2 +- app/components/follow-button.hbs | 3 +- .../{footer.module.css => footer.css} | 12 +- app/components/footer.hbs | 4 +- .../{item.module.css => item.css} | 2 +- app/components/front-page-list/item.hbs | 10 +- ...placeholder.module.css => placeholder.css} | 0 .../front-page-list/item/placeholder.hbs | 10 +- .../{header.module.css => header.css} | 6 +- app/components/header.hbs | 68 ++- ...spinner.module.css => loading-spinner.css} | 0 app/components/loading-spinner.hbs | 2 +- app/components/{msrv.module.css => msrv.css} | 0 app/components/msrv.hbs | 2 +- .../{nav-tabs.module.css => nav-tabs.css} | 0 app/components/nav-tabs.hbs | 2 +- .../nav-tabs/{tab.module.css => tab.css} | 0 app/components/nav-tabs/tab.hbs | 2 +- ...ate-row.module.css => owned-crate-row.css} | 0 app/components/owned-crate-row.hbs | 6 +- ...owners-list.module.css => owners-list.css} | 0 app/components/owners-list.hbs | 10 +- ...page-header.module.css => page-header.css} | 0 app/components/page-header.hbs | 8 +- .../{pagination.module.css => pagination.css} | 19 +- app/components/pagination.hbs | 6 +- ...odule.css => pending-owner-invite-row.css} | 0 app/components/pending-owner-invite-row.hbs | 4 +- ...placeholder.module.css => placeholder.css} | 0 app/components/placeholder.hbs | 2 +- ...ction.module.css => privileged-action.css} | 0 app/components/privileged-action.hbs | 2 +- ...ogress-bar.module.css => progress-bar.css} | 0 app/components/progress-bar.hbs | 2 +- ...lts-count.module.css => results-count.css} | 0 app/components/results-count.hbs | 6 +- ...rev-dep-row.module.css => rev-dep-row.css} | 0 app/components/rev-dep-row.hbs | 18 +- ...search-form.module.css => search-form.css} | 0 app/components/search-form.hbs | 10 +- ...ings-page.module.css => settings-page.css} | 2 +- app/components/settings-page.hbs | 4 +- .../{api-tokens.module.css => api-tokens.css} | 0 app/components/settings/api-tokens.hbs | 59 ++- .../{side-menu.module.css => side-menu.css} | 0 app/components/side-menu.hbs | 2 +- .../side-menu/{item.module.css => item.css} | 0 app/components/side-menu/item.hbs | 2 +- ...-dropdown.module.css => sort-dropdown.css} | 0 app/components/sort-dropdown.hbs | 4 +- ...stats-value.module.css => stats-value.css} | 0 app/components/stats-value.hbs | 8 +- ...-form.module.css => crate-report-form.css} | 33 +- app/components/support/crate-report-form.hbs | 20 +- ...xt-content.module.css => text-content.css} | 18 +- app/components/text-content.hbs | 2 +- .../{tooltip.module.css => tooltip.css} | 0 app/components/tooltip.hbs | 4 +- .../version-list/{row.module.css => row.css} | 10 +- app/components/version-list/row.hbs | 59 ++- app/components/version-list/row.js | 2 +- app/css/normalize.css | 351 +++++++++++++ app/css/shared/a11y.css | 12 + app/css/shared/buttons.css | 103 ++++ app/css/shared/forms.css | 27 + app/css/shared/sort-by.css | 9 + app/css/shared/typography.css | 20 + app/index.html | 2 + app/styles/application.module.css | 203 -------- app/styles/settings/appearance.module.css | 19 - app/styles/shared/a11y.module.css | 10 - app/styles/shared/buttons.module.css | 101 ---- app/styles/shared/forms.module.css | 25 - app/styles/shared/sort-by.module.css | 7 - app/styles/shared/typography.module.css | 18 - app/styles/support.module.css | 19 - app/templates/application.css | 18 + app/templates/application.hbs | 6 +- .../catch-all.css} | 0 app/templates/catch-all.hbs | 17 +- .../categories.css} | 0 app/templates/categories.hbs | 12 +- .../category-slugs.css} | 0 app/templates/category-slugs.hbs | 2 +- .../category/index.css} | 0 app/templates/category/index.hbs | 12 +- .../crate/delete.css} | 10 +- app/templates/crate/delete.hbs | 31 +- .../crate/reverse-dependencies.css} | 0 app/templates/crate/reverse-dependencies.hbs | 8 +- .../crate/settings/index.css} | 4 +- app/templates/crate/settings/index.hbs | 28 +- .../crate/settings/new-trusted-publisher.css} | 0 .../crate/settings/new-trusted-publisher.hbs | 47 +- .../crate/version-dependencies.css} | 0 app/templates/crate/version-dependencies.hbs | 14 +- .../crate/version.css} | 0 app/templates/crate/version.hbs | 69 ++- .../crate/versions.css} | 0 app/templates/crate/versions.hbs | 19 +- .../crates.css} | 0 app/templates/crates.hbs | 4 +- .../dashboard.css} | 4 +- app/templates/dashboard.hbs | 36 +- .../index.module.css => templates/index.css} | 2 +- app/templates/index.hbs | 41 +- .../keyword.css} | 0 app/templates/keyword.hbs | 4 +- .../keywords.css} | 0 app/templates/keywords.hbs | 6 +- .../me/crates.css} | 0 app/templates/me/crates.hbs | 4 +- .../me/following.css} | 0 app/templates/me/following.hbs | 4 +- .../me/pending-invites.css} | 0 app/templates/me/pending-invites.hbs | 6 +- .../search.css} | 0 app/templates/search.hbs | 9 +- .../settings/email-notifications.css} | 0 .../settings/email-notifications.hbs | 14 +- .../settings/profile.css} | 0 app/templates/settings/profile.hbs | 18 +- .../settings/tokens/new.css} | 18 +- app/templates/settings/tokens/new.hbs | 51 +- app/templates/support.css | 46 ++ app/templates/support.hbs | 8 +- .../team.module.css => templates/team.css} | 2 +- app/templates/team.hbs | 12 +- .../user.module.css => templates/user.css} | 2 +- app/templates/user.hbs | 8 +- config/targets.js | 13 - ember-cli-build.js | 55 +-- package.json | 16 +- pnpm-lock.yaml | 460 ++++++++++++------ 170 files changed, 1755 insertions(+), 1224 deletions(-) create mode 100644 app/app.css rename app/components/{color-scheme-menu.module.css => color-scheme-menu.css} (100%) rename app/components/{crate-downloads-list.module.css => crate-downloads-list.css} (100%) rename app/components/{crate-header.module.css => crate-header.css} (98%) rename app/components/{crate-list.module.css => crate-list.css} (100%) rename app/components/{crate-row.module.css => crate-row.css} (97%) rename app/components/{crate-sidebar.module.css => crate-sidebar.css} (97%) rename app/components/crate-sidebar/{install-instructions.module.css => install-instructions.css} (100%) rename app/components/crate-sidebar/{link.module.css => link.css} (100%) rename app/components/dependency-list/{row.module.css => row.css} (98%) rename app/components/{download-graph.module.css => download-graph.css} (100%) rename app/components/{dropdown.module.css => dropdown.css} (100%) rename app/components/dropdown/{content.module.css => content.css} (100%) rename app/components/dropdown/{menu-item.module.css => menu-item.css} (90%) rename app/components/dropdown/{menu.module.css => menu.css} (100%) rename app/components/dropdown/{trigger.module.css => trigger.css} (100%) rename app/components/{edition.module.css => edition.css} (100%) rename app/components/{email-input.module.css => email-input.css} (100%) rename app/components/{follow-button.module.css => follow-button.css} (79%) rename app/components/{footer.module.css => footer.css} (94%) rename app/components/front-page-list/{item.module.css => item.css} (98%) rename app/components/front-page-list/item/{placeholder.module.css => placeholder.css} (100%) rename app/components/{header.module.css => header.css} (98%) rename app/components/{loading-spinner.module.css => loading-spinner.css} (100%) rename app/components/{msrv.module.css => msrv.css} (100%) rename app/components/{nav-tabs.module.css => nav-tabs.css} (100%) rename app/components/nav-tabs/{tab.module.css => tab.css} (100%) rename app/components/{owned-crate-row.module.css => owned-crate-row.css} (100%) rename app/components/{owners-list.module.css => owners-list.css} (100%) rename app/components/{page-header.module.css => page-header.css} (100%) rename app/components/{pagination.module.css => pagination.css} (66%) rename app/components/{pending-owner-invite-row.module.css => pending-owner-invite-row.css} (100%) rename app/components/{placeholder.module.css => placeholder.css} (100%) rename app/components/{privileged-action.module.css => privileged-action.css} (100%) rename app/components/{progress-bar.module.css => progress-bar.css} (100%) rename app/components/{results-count.module.css => results-count.css} (100%) rename app/components/{rev-dep-row.module.css => rev-dep-row.css} (100%) rename app/components/{search-form.module.css => search-form.css} (100%) rename app/components/{settings-page.module.css => settings-page.css} (88%) rename app/components/settings/{api-tokens.module.css => api-tokens.css} (100%) rename app/components/{side-menu.module.css => side-menu.css} (100%) rename app/components/side-menu/{item.module.css => item.css} (100%) rename app/components/{sort-dropdown.module.css => sort-dropdown.css} (100%) rename app/components/{stats-value.module.css => stats-value.css} (100%) rename app/components/support/{crate-report-form.module.css => crate-report-form.css} (61%) rename app/components/{text-content.module.css => text-content.css} (95%) rename app/components/{tooltip.module.css => tooltip.css} (100%) rename app/components/version-list/{row.module.css => row.css} (98%) create mode 100644 app/css/normalize.css create mode 100644 app/css/shared/a11y.css create mode 100644 app/css/shared/buttons.css create mode 100644 app/css/shared/forms.css create mode 100644 app/css/shared/sort-by.css create mode 100644 app/css/shared/typography.css delete mode 100644 app/styles/application.module.css delete mode 100644 app/styles/settings/appearance.module.css delete mode 100644 app/styles/shared/a11y.module.css delete mode 100644 app/styles/shared/buttons.module.css delete mode 100644 app/styles/shared/forms.module.css delete mode 100644 app/styles/shared/sort-by.module.css delete mode 100644 app/styles/shared/typography.module.css delete mode 100644 app/styles/support.module.css create mode 100644 app/templates/application.css rename app/{styles/catch-all.module.css => templates/catch-all.css} (100%) rename app/{styles/categories.module.css => templates/categories.css} (100%) rename app/{styles/category-slugs.module.css => templates/category-slugs.css} (100%) rename app/{styles/category/index.module.css => templates/category/index.css} (100%) rename app/{styles/crate/delete.module.css => templates/crate/delete.css} (94%) rename app/{styles/crate/reverse-dependencies.module.css => templates/crate/reverse-dependencies.css} (100%) rename app/{styles/crate/settings/index.module.css => templates/crate/settings/index.css} (95%) rename app/{styles/crate/settings/new-trusted-publisher.module.css => templates/crate/settings/new-trusted-publisher.css} (100%) rename app/{styles/crate/version-dependencies.module.css => templates/crate/version-dependencies.css} (100%) rename app/{styles/crate/version.module.css => templates/crate/version.css} (100%) rename app/{styles/crate/versions.module.css => templates/crate/versions.css} (100%) rename app/{styles/crates.module.css => templates/crates.css} (100%) rename app/{styles/dashboard.module.css => templates/dashboard.css} (98%) rename app/{styles/index.module.css => templates/index.css} (97%) rename app/{styles/keyword/index.module.css => templates/keyword.css} (100%) rename app/{styles/keywords.module.css => templates/keywords.css} (100%) rename app/{styles/me/crates.module.css => templates/me/crates.css} (100%) rename app/{styles/me/following.module.css => templates/me/following.css} (100%) rename app/{styles/me/pending-invites.module.css => templates/me/pending-invites.css} (100%) rename app/{styles/search.module.css => templates/search.css} (100%) rename app/{styles/settings/email-notifications.module.css => templates/settings/email-notifications.css} (100%) rename app/{styles/settings/profile.module.css => templates/settings/profile.css} (100%) rename app/{styles/settings/tokens/new.module.css => templates/settings/tokens/new.css} (94%) create mode 100644 app/templates/support.css rename app/{styles/team.module.css => templates/team.css} (97%) rename app/{styles/user.module.css => templates/user.css} (95%) delete mode 100644 config/targets.js diff --git a/app/app.css b/app/app.css new file mode 100644 index 00000000000..21543ec6ee7 --- /dev/null +++ b/app/app.css @@ -0,0 +1,198 @@ +@import "./css/shared/a11y.css"; +@import "./css/shared/buttons.css"; +@import "./css/shared/forms.css"; +@import "./css/shared/sort-by.css"; +@import "./css/shared/typography.css"; + +/* + * The `normalize.css` file does not use CSS layers, so we need to vendor it + * with a layer to ensure it is applied before our global styles. + */ +@import "./css/normalize.css"; + +@layer global { + :root, [data-theme="classic"] { + --violet800: hsl(252, 44%, 24%); + --grey900: hsl(200, 15%, 19%); + --grey700: hsl(200, 11%, 43%); + --grey600: hsl(200, 13%, 60%); + --grey200: hsl(200, 17%, 96%); + --green800: hsl(115, 31%, 31%); + --green900: hsl(115, 31%, 21%); + + --orange-50: #fff7ed; + --orange-100: #ffedd5; + --orange-200: #fed7aa; + --orange-300: #fdba74; + --orange-400: #fb923c; + --orange-500: #f97316; + --orange-600: #ea580c; + --orange-700: #c2410c; + --orange-800: #9a3412; + --orange-900: #7c2d12; + + --yellow100: hsl(44, 100%, 90%); + --yellow500: hsl(44, 100%, 60%); + --yellow700: hsl(44, 67%, 50%); + --yellow800: hsl(44, 67%, 20%); + + --header-bg-color: light-dark(hsl(115, 31%, 20%), #141413); + + --transition-x-slow: 1000ms; + --transition-slow: 500ms; + --transition-medium: 250ms; + --transition-fast: 150ms; + --transition-x-fast: 50ms; + --transition-instant: 0ms; + + --font-heading: "Fira Sans", sans-serif; + --font-body: var(--font-heading); + --font-monospace: "Fira Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", + "Courier New", monospace; + + --main-color: light-dark(#383838, #f9f7ec); + --main-color-light: light-dark(#858585, #a6a6a6); + --main-shadow-color: light-dark(var(--green900), hsl(111, 10%, 8%)); + --main-bg: light-dark(#f9f7ec, hsl(0, 1%, 19%)); + --main-bg-dark: light-dark(#edebdd, #141413); + --gray-border: light-dark(#d5d3cb, #666561); + --link-color: rgb(0, 172, 91); + --link-hover-color: #007940; + + --placeholder-bg: hsl(212, 7%, 57%); + --placeholder-bg2: hsl(213, 16%, 75%); + + /* see https://utopia.fyi/space/calculator?c=320,14,1.2,1140,18,1.25,5,2,&s=0.75|0.5|0.25|0.125,1.5|2|3|4|6,s-l */ + + --space-4xs: clamp(0.13rem, calc(0.13rem + 0.00vw), 0.13rem); + --space-3xs: clamp(0.25rem, calc(0.23rem + 0.12vw), 0.31rem); + --space-2xs: clamp(0.44rem, calc(0.39rem + 0.24vw), 0.56rem); + --space-xs: clamp(0.69rem, calc(0.61rem + 0.37vw), 0.88rem); + --space-s: clamp(0.88rem, calc(0.78rem + 0.49vw), 1.13rem); + --space-m: clamp(1.31rem, calc(1.17rem + 0.73vw), 1.69rem); + --space-l: clamp(1.75rem, calc(1.55rem + 0.98vw), 2.25rem); + --space-xl: clamp(2.63rem, calc(2.33rem + 1.46vw), 3.38rem); + --space-2xl: clamp(3.50rem, calc(3.11rem + 1.95vw), 4.50rem); + --space-3xl: clamp(5.25rem, calc(4.66rem + 2.93vw), 6.75rem); + + /* One-up pairs */ + --space-4xs-3xs: clamp(0.13rem, calc(0.05rem + 0.37vw), 0.31rem); + --space-3xs-2xs: clamp(0.25rem, calc(0.13rem + 0.61vw), 0.56rem); + --space-2xs-xs: clamp(0.44rem, calc(0.27rem + 0.85vw), 0.88rem); + --space-xs-s: clamp(0.69rem, calc(0.52rem + 0.85vw), 1.13rem); + --space-s-m: clamp(0.88rem, calc(0.56rem + 1.59vw), 1.69rem); + --space-m-l: clamp(1.31rem, calc(0.95rem + 1.83vw), 2.25rem); + --space-l-xl: clamp(1.75rem, calc(1.12rem + 3.17vw), 3.38rem); + --space-xl-2xl: clamp(2.63rem, calc(1.89rem + 3.66vw), 4.50rem); + --space-2xl-3xl: clamp(3.50rem, calc(2.23rem + 6.34vw), 6.75rem); + + /* Custom pairs */ + --space-s-l: clamp(0.88rem, calc(0.34rem + 2.68vw), 2.25rem); + + color-scheme: light dark; + } + + [data-color-scheme="light"] { + color-scheme: light; + } + + [data-color-scheme="dark"] { + color-scheme: dark; + } + + * { + box-sizing: border-box; + } + + html, body { + margin: 0; + scroll-behavior: smooth; + } + + body { + background-color: var(--header-bg-color); + font-family: var(--font-body); + font-size: 16px; + display: flex; + flex-direction: column; + min-height: 100vh; + } + + h1, h2, h3, h4 { + font-family: var(--font-heading); + } + + h1 { + @media only screen and (max-width: 400px) { + font-size: 1.5em; + } + } + + a, .link, .text--link { + color: var(--link-color); + text-decoration: none; + cursor: pointer; + + &:hover { + color: var(--link-hover-color); + } + } + + /* Using `:not(...)` here for specificity reasons */ + a:not([href]) { + color: unset; + cursor: initial; + } + + pre.terminal { + background: var(--main-color); + color: white; + padding: var(--space-s); + font-family: var(--font-monospace); + } + + abbr[title] { + text-decoration: none; + border-bottom: 1px dotted; + } + + noscript { + display: grid; + justify-items: center; + padding: var(--space-m); + color: white; + } + + /* see https://github.com/twbs/bootstrap/pull/30269 */ + ::-webkit-datetime-edit, + ::-webkit-datetime-edit-fields-wrapper, + ::-webkit-datetime-edit-text, + ::-webkit-datetime-edit-minute, + ::-webkit-datetime-edit-hour-field, + ::-webkit-datetime-edit-day-field, + ::-webkit-datetime-edit-month-field, + ::-webkit-datetime-edit-year-field { + padding: 0; + } + + ::-webkit-calendar-picker-indicator { + font-size: 0.9em + } + + .c-notification__icon { + display: flex; + justify-content: center; + align-items: center; + } + + .c-notification__content { + line-height: 1.5; + } + + .width-limit { + width: 960px; + @media only screen and (max-width: 960px) { + width: 100%; + } + } +} diff --git a/app/app.js b/app/app.js index f38b750bc48..0680f1c7778 100644 --- a/app/app.js +++ b/app/app.js @@ -6,6 +6,8 @@ import Resolver from 'ember-resolver'; import config from './config/environment'; import * as Sentry from './sentry'; +import './app.css'; + // eslint-disable-next-line unicorn/prefer-add-event-listener window.onerror = undefined; Sentry.init(); diff --git a/app/components/color-scheme-menu.module.css b/app/components/color-scheme-menu.css similarity index 100% rename from app/components/color-scheme-menu.module.css rename to app/components/color-scheme-menu.css diff --git a/app/components/color-scheme-menu.hbs b/app/components/color-scheme-menu.hbs index f9446338273..4f6843ec22f 100644 --- a/app/components/color-scheme-menu.hbs +++ b/app/components/color-scheme-menu.hbs @@ -1,19 +1,18 @@ - - - {{svg-jar this.icon local-class="icon"}} + + + {{svg-jar this.icon class=(scoped-class "icon")}} Change color scheme - + {{#each this.colorSchemes as |colorScheme|}} {{/each}} diff --git a/app/components/crate-downloads-list.module.css b/app/components/crate-downloads-list.css similarity index 100% rename from app/components/crate-downloads-list.module.css rename to app/components/crate-downloads-list.css diff --git a/app/components/crate-downloads-list.hbs b/app/components/crate-downloads-list.hbs index 058585e31b8..a526b42c274 100644 --- a/app/components/crate-downloads-list.hbs +++ b/app/components/crate-downloads-list.hbs @@ -1,9 +1,9 @@ -
    +
      {{#each @crates as |crate|}}
    • - + {{ crate.name }} ({{ crate.max_version }}) - {{svg-jar "download-arrow" local-class="download-icon"}} + {{svg-jar "download-arrow" class=(scoped-class "download-icon")}} {{ format-num crate.downloads }}
    • diff --git a/app/components/crate-header.module.css b/app/components/crate-header.css similarity index 98% rename from app/components/crate-header.module.css rename to app/components/crate-header.css index ed31269b47d..ac7220ec040 100644 --- a/app/components/crate-header.module.css +++ b/app/components/crate-header.css @@ -25,7 +25,7 @@ white-space: nowrap; cursor: default; - svg { + :global(svg) { width: 1em; height: 1em; flex-shrink: 0; diff --git a/app/components/crate-header.hbs b/app/components/crate-header.hbs index 4e0ab00d868..4b010ad3661 100644 --- a/app/components/crate-header.hbs +++ b/app/components/crate-header.hbs @@ -1,11 +1,11 @@ - -

      + +

      {{@crate.name}} {{#if @version}} v{{@version.num}} {{#if @version.yanked}} - + {{svg-jar "trash"}} Yanked @@ -19,17 +19,17 @@

      {{#if @crate.description}} -
      +
      {{@crate.description}}
      {{/if}} {{#if this.keywords}} -
        +
          {{#each this.keywords as |keyword|}}
        • - #{{keyword.id}} + #{{keyword.id}}
        • {{/each}} @@ -37,11 +37,11 @@ {{/if}} {{#if this.session.currentUser}} - +