Skip to content

fix: Wave 3 — Sass deprecations, deep combinator, and template fixes#428

Open
tobydrinkall wants to merge 2 commits into
upgrade/angular-corefrom
upgrade/component-template
Open

fix: Wave 3 — Sass deprecations, deep combinator, and template fixes#428
tobydrinkall wants to merge 2 commits into
upgrade/angular-corefrom
upgrade/component-template

Conversation

@tobydrinkall

@tobydrinkall tobydrinkall commented Jul 2, 2026

Copy link
Copy Markdown

Summary

Resolves Sass deprecations and CSS deep combinator issues that would become errors in Dart Sass 2.0, as part of the Angular 9→20 migration.

Sass @import@use/@forward across all 13 SCSS files:

// before
@import "../../shared/scss/media";
@import "../../shared/scss/theme_variables";

// after
@use "../../shared/scss/media" as *;
@use "../../shared/scss/theme_variables" as *;

/ division → math.div() in error-message.component.scss and _themes.scss:

// before
left: $skull-size / 15;
border-top: $skull-size / 8 solid $wrapper-background-color;

// after  
left: math.div($skull-size, 15);
border-top: math.div($skull-size, 8) solid $wrapper-background-color;

darken()color.adjust() in _themes.scss:

// before
darken($theme-amoledblack-text-color, 33%)
// after
color.adjust($theme-amoledblack-text-color, $lightness: -33%)

:host >>>:host ::ng-deep in comment.component.scss and user.component.scss:

// before
:host >>> { a { ... } }
:host >>> pre { ... }
// after
:host ::ng-deep { a { ... } }
:host ::ng-deep pre { ... }

:host prefix preserved to keep styles scoped to the component and prevent global leaks.

No template or component API breaking changes found — all components already use standalone: false, no @ViewChild/@ContentChild usage, and NgModule patterns are compatible with Angular 20. Build passes cleanly with npx ng build.

Link to Devin session: https://app.devin.ai/sessions/fb28a14a2b814b00944621984df964be
Requested by: @tobydrinkall


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Open in Devin Review (Staging)
Open in Devin Review

- Replace @import with @use/@forward across all SCSS files
- Replace / division operator with math.div() in error-message and themes
- Replace darken() with color.adjust() in _themes.scss
- Replace deprecated >>> deep combinator with ::ng-deep
- Add @use 'sass:math' and @use 'sass:color' where needed

Co-Authored-By: Toby Drinkall <toby.drinkall@cognition.ai>
@tobydrinkall tobydrinkall self-assigned this Jul 2, 2026
@devin-ai-integration

Copy link
Copy Markdown

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 5 potential issues.

Open in Devin Review

@use "../../shared/scss/theme_variables" as *;

:host >>> {
::ng-deep {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Comment link styles leak globally to all links in the application

Deep style rules for links are applied without host scoping (::ng-deep at src/app/item-details/comment/comment.component.scss:4) instead of being scoped to the component's host, so all <a> tags across the entire application become bold with no text-decoration.

Impact: Every link in the app gets overridden with bold weight and no underline, breaking the intended styling of other components.

Mechanism: :host scoping removed during deep combinator migration

The original code was :host >>> { a { ... } }. In Angular's emulated view encapsulation, :host >>> (or equivalently :host ::ng-deep) compiles to [_nghost-xxx] selector, meaning the deep styles only apply to descendants of this component's host element. This was intentional — the component uses [innerHTML]="comment.content" (src/app/item-details/comment/comment.component.html:9) to render user-generated HTML that contains <a> tags which don't receive Angular's encapsulation attributes.

The new code ::ng-deep { a { ... } } without :host compiles to just a { ... } globally (no scoping attribute is added). This means the bold/no-decoration styles leak to every link in the application.

The correct migration is :host ::ng-deep { a { ... } } which preserves the original scoping behavior.

Suggested change
::ng-deep {
:host ::ng-deep {
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed — added :host prefix so styles remain scoped to the component's host element: :host ::ng-deep {.

Comment thread src/app/user/user.component.scss Outdated
@use "../shared/scss/theme_variables" as *;

:host >>> pre {
::ng-deep pre {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 User component's pre-wrap style leaks globally to all pre elements

The deep style rule for <pre> elements is applied without host scoping (::ng-deep pre at src/app/user/user.component.scss:4) instead of being scoped to the component's host, so all <pre> tags across the entire application get the white-space: pre-wrap style.

Impact: All <pre> elements in the app are forced to pre-wrap, which may break formatting in other components that rely on default <pre> behavior.

Mechanism: :host scoping removed during deep combinator migration

The original code was :host >>> pre { white-space: pre-wrap; }. In Angular's emulated view encapsulation, :host >>> compiles to [_nghost-xxx] pre, scoping the style to <pre> elements that are descendants of this component's host. The component uses [innerHTML]="user.about" (src/app/user/user.component.html:17) which may contain <pre> tags that don't receive Angular's encapsulation attributes.

The new code ::ng-deep pre { ... } without :host compiles to just pre { ... } globally. The correct migration is :host ::ng-deep pre { ... }.

Suggested change
::ng-deep pre {
:host ::ng-deep pre {
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Fixed — added :host prefix: :host ::ng-deep pre {.

$theme-amoledblack-text-color,
$theme-amoledblack-text-color,
darken($theme-amoledblack-text-color, 33%),
color.adjust($theme-amoledblack-text-color, $lightness: -33%),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: darken() to color.adjust() conversion is semantically equivalent

The conversion from darken($theme-amoledblack-text-color, 33%) to color.adjust($theme-amoledblack-text-color, $lightness: -33%) at src/app/shared/scss/_themes.scss:235 is correct. Sass's darken($color, $amount) is defined as equivalent to color.adjust($color, $lightness: -$amount) — both subtract the given percentage points from the HSL lightness value. The input color $theme-amoledblack-text-color is rgba(255, 255, 255, 0.75) (defined at src/app/shared/scss/_theme_variables.scss:35), which has lightness 100%, so subtracting 33 percentage points yields lightness 67% — identical behavior to the original.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines 4 to 7
::ng-deep {
a {
font-weight: bold;
text-decoration: none;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 Info: ::ng-deep is itself deprecated and will eventually be removed

While this PR correctly migrates away from the :host >>> syntax (which was removed in newer Angular versions), the replacement ::ng-deep is also deprecated by Angular. The Angular team has not yet provided a full replacement, but the deprecation means this code will need another migration in the future. For now, ::ng-deep is the only available mechanism for piercing view encapsulation to style dynamically-inserted innerHTML content (as used in src/app/item-details/comment/comment.component.html:9 and src/app/user/user.component.html:17). This is acceptable as a transitional solution.

(Refers to lines 4-12)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment thread src/styles.scss
@@ -1,4 +1,4 @@
@import "./app/shared/scss/themes";
@use "./app/shared/scss/themes";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📝 *Info: styles.scss uses @use without 'as ' correctly for side-effect-only import

The @use "./app/shared/scss/themes" at src/styles.scss:1 intentionally omits as * because this file doesn't need to access any variables or mixins from the themes partial — it only needs the CSS output generated by the @include theme(...) calls within _themes.scss. The default namespaced import (accessible as themes.$var if needed) is fine here since no members are referenced. This differs from the component SCSS files which use as * to access $mobile-only, $laptop-only, etc. without a namespace prefix.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Co-Authored-By: Toby Drinkall <toby.drinkall@cognition.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant