Open tanishqmanuja opened 5 months ago
It's not properly documented yet, but there's a use-system-variables
in the color
and typography
fields of M3 themes. If you set it to true
, you'll be able to theme dynamically by changing a ~10 CSS variables at runtime. Here's how to pass it: https://github.com/angular/components/blob/main/src/dev-app/theme-m3.scss#L15
Thanks, this is exactly what I needed. Can you also provide a link to find what CSS Vars are used ?
Below are all the possible ones. You don't need to provide all of them, e.g. if you don't set use-system-variables
for the typography, you can skip the whole typography section. We also have the mat.system-level-colors
and mat.system-level-typography
mixins that you can use to generate the values from a theme.
// Colors
--sys-background
--sys-error
--sys-error-container
--sys-inverse-on-surface
--sys-inverse-primary
--sys-inverse-surface
--sys-on-background
--sys-on-error
--sys-on-error-container
--sys-on-primary
--sys-on-primary-container
--sys-on-primary-fixed
--sys-on-primary-fixed-variant
--sys-on-secondary
--sys-on-secondary-container
--sys-on-secondary-fixed
--sys-on-secondary-fixed-variant
--sys-on-surface
--sys-on-surface-variant
--sys-on-tertiary
--sys-on-tertiary-container
--sys-on-tertiary-fixed
--sys-on-tertiary-fixed-variant
--sys-outline
--sys-outline-variant
--sys-primary
--sys-primary-container
--sys-primary-fixed
--sys-primary-fixed-dim
--sys-scrim
--sys-secondary
--sys-secondary-container
--sys-secondary-fixed
--sys-secondary-fixed-dim
--sys-shadow
--sys-surface
--sys-surface-bright
--sys-surface-container
--sys-surface-container-high
--sys-surface-container-highest
--sys-surface-container-low
--sys-surface-container-lowest
--sys-surface-dim
--sys-surface-tint
--sys-surface-variant
--sys-tertiary
--sys-tertiary-container
--sys-tertiary-fixed
--sys-tertiary-fixed-dim
// Typography
--sys-body-large
--sys-body-large-font
--sys-body-large-line-height
--sys-body-large-size
--sys-body-large-tracking
--sys-body-large-weight
--sys-body-medium
--sys-body-medium-font
--sys-body-medium-line-height
--sys-body-medium-size
--sys-body-medium-tracking
--sys-body-medium-weight
--sys-body-small
--sys-body-small-font
--sys-body-small-line-height
--sys-body-small-size
--sys-body-small-tracking
--sys-body-small-weight
--sys-display-large
--sys-display-large-font
--sys-display-large-line-height
--sys-display-large-size
--sys-display-large-tracking
--sys-display-large-weight
--sys-display-medium
--sys-display-medium-font
--sys-display-medium-line-height
--sys-display-medium-size
--sys-display-medium-tracking
--sys-display-medium-weight
--sys-display-small
--sys-display-small-font
--sys-display-small-line-height
--sys-display-small-size
--sys-display-small-tracking
--sys-display-small-weight
--sys-headline-large
--sys-headline-large-font
--sys-headline-large-line-height
--sys-headline-large-size
--sys-headline-large-tracking
--sys-headline-large-weight
--sys-headline-medium
--sys-headline-medium-font
--sys-headline-medium-line-height
--sys-headline-medium-size
--sys-headline-medium-tracking
--sys-headline-medium-weight
--sys-headline-small
--sys-headline-small-font
--sys-headline-small-line-height
--sys-headline-small-size
--sys-headline-small-tracking
--sys-headline-small-weight
--sys-label-large
--sys-label-large-font
--sys-label-large-line-height
--sys-label-large-size
--sys-label-large-tracking
--sys-label-large-weight
--sys-label-large-weight-prominent
--sys-label-medium
--sys-label-medium-font
--sys-label-medium-line-height
--sys-label-medium-size
--sys-label-medium-tracking
--sys-label-medium-weight
--sys-label-medium-weight-prominent
--sys-label-small
--sys-label-small-font
--sys-label-small-line-height
--sys-label-small-size
--sys-label-small-tracking
--sys-label-small-weight
--sys-title-large
--sys-title-large-font
--sys-title-large-line-height
--sys-title-large-size
--sys-title-large-tracking
--sys-title-large-weight
--sys-title-medium
--sys-title-medium-font
--sys-title-medium-line-height
--sys-title-medium-size
--sys-title-medium-tracking
--sys-title-medium-weight
--sys-title-small
--sys-title-small-font
--sys-title-small-line-height
--sys-title-small-size
--sys-title-small-tracking
--sys-title-small-weight
That's awesome, they are the same as material-web style tokens with just different prefix --md-sys <-> --sys. With material-color-utilities npm package, it should be super simple to provide these.
AFAIK material-color-utilities don't inject surface tokens as of now, here's a snippet if anyone needs it.
import { hexFromArgb, Theme } from "@material/material-color-utilities";
export function applySurfaceStyles(
theme: Theme,
{ dark }: { dark: boolean },
): void {
if (dark) {
const elevationProps = {
"--md-sys-color-surface-dim": theme.palettes.neutral.tone(6),
"--md-sys-color-surface-bright": theme.palettes.neutral.tone(24),
"--md-sys-color-surface-container-lowest": theme.palettes.neutral.tone(4),
"--md-sys-color-surface-container-low": theme.palettes.neutral.tone(10),
"--md-sys-color-surface-container": theme.palettes.neutral.tone(12),
"--md-sys-color-surface-container-high": theme.palettes.neutral.tone(17),
"--md-sys-color-surface-container-highest":
theme.palettes.neutral.tone(22),
};
for (const [property, argbColor] of Object.entries(elevationProps)) {
document.body.style.setProperty(property, hexFromArgb(argbColor));
}
} else {
const elevationProps = {
"--md-sys-color-surface-dim": theme.palettes.neutral.tone(87),
"--md-sys-color-surface-bright": theme.palettes.neutral.tone(98),
"--md-sys-color-surface-container-lowest":
theme.palettes.neutral.tone(100),
"--md-sys-color-surface-container-low": theme.palettes.neutral.tone(96),
"--md-sys-color-surface-container": theme.palettes.neutral.tone(94),
"--md-sys-color-surface-container-high": theme.palettes.neutral.tone(92),
"--md-sys-color-surface-container-highest":
theme.palettes.neutral.tone(90),
};
for (const [property, argbColor] of Object.entries(elevationProps)) {
document.body.style.setProperty(property, hexFromArgb(argbColor));
}
}
}
Change the prefix as per requirement 🤞🏻
There is a new option to configure the prefix of system variables.
Read more about this in my article, which includes a live demo: https://konstantin-denerz.com/angular-material-3-theming-design-tokens-and-system-variables/
Offtopic - Your site looks really amazing, I have mostly seen bottom navs (on mobile view) with icons but your text based bottom nav is 🔥
First attempt after reading @konstantindenerz article https://github.com/tanishqmanuja/demo.ng-material-dynamic-theme
Is this inline with the best practices suggested by angular-material ?
PS: I am still confused about how to inject typography tokens
For one of my article, I used applyTheme
from @material/material-color-utilities
, and it generated all the needed colors. You can read the article with demo at https://angular-material.dev/articles/angular-material-theming-css-vars
Is there a way to do this at component level easily.
The double inheritance problem, Why this wont work for individual components? - lit playground
Also this is a very common use-case, suppose i want to display multiple color schemes option at once to a user.
PRACTICAL NEED: Suppose I make a theme service that applies the dynamically generated css vars like --md-sys-* etc to the host component where the service is provided, the service depends on a minimal injection token SOURCE_COLOR for generating the color scheme. Now the problem arises because even though every thing should work in theory, as it works with lit based material components (which are now on maintenance mode, and the docs reads "use angular material for angular framework" ), but due to inherited css vars used in angular-material components, there is no way to make such a thing work with angular-material. Any thoughts ?
At component level angular material uses lots of internal variables. But, with Angular Material 18, team have introduced overrides API, you can use it like below, of course, for runtime changes you will still need to figure out all of CSS (--mat- and --mdc-) the variables.
button {
@include mat.button-overrides((
ripple-color: red
))
}
figuring out all those without docs doesnt sound too good either. So that's a no for sure :(
Feature Description
The ability to generate theme based on a seed color at runtime instead of compile time.
Use Case
This is very common in native android apps and would also benefit ionic/capacitor user to make their app feel more native