How to get a typography into my angular material theme?

I'm creating a custom theme for my angular app. Then I'm trying to set up bootstrap's reboot to set a basic starting point for all non material elements. Since reboot uses quite a few variables that overlap with material, I've turned it into a mixin, to which I pass my created theme and wherein I try to extract the required values (e.g. font-family or color).

theme.scss:

$wb-theme: mat.define-dark-theme((
  color: (
    primary: $wb-primary,
    accent: $wb-accent,
    warn: $wb-warn,
  )
));

@include mat.all-component-themes($wb-theme);
@include reboot.theme($wb-theme);

_reboot.scss

@mixin theme($theme) {
  $typography-config: mat.get-typography-config($theme);
  $color-config: mat.get-color-config($theme);

  $primary-palette: map.get($color-config, primary);

  body {
    font-family: mat.font-family($typography-config);
    color: mat.get-color-from-palette($primary-palette, 50);
  }
}

Setting the color works fine but the font-family line throws an exception in angular's _typography-utils.scss, stating that SassError: $map: null is not a map. in line 46 │ $font-family: map.get($config, font-family);

I've noticed that mat.get-typography-config($theme); returns null, since apparently my theme does not contain the key typography and I do not pass a default value as 2nd argument. I've tested the return value of map.has-key($theme, typography) and it does indeed return false.

@angular_theming.scss:

/// Gets the typography configuration from the given theme or configuration.
/// For backwards compatibility, typography is not included by default.
/// @param {Map} $theme-or-config  The theme map returned from `define-light-theme` or
///     `define-dark-theme`.
/// @param {Map} $default The default value returned if the given `$theme` does not include a
///     `typography` configuration.
/// @returns {Map} Typography configuration for a theme.
@function get-typography-config($theme-or-config, $default: null) {
  // If a configuration has been passed, return the config directly.
  @if not private-is-theme-object($theme-or-config) {
    @return $theme-or-config;
  }
  // In case a theme has been passed, extract the configuration if present,
  // or fall back to the default typography config.
  @if (map.has-key($theme-or-config, typography)) {
    @return map.get($theme-or-config, typography);
  }
  @return $default;
}

According to the commentary in the file however, I should be able to pass in my $wb-theme I created with define-dark-theme and get a typography config back. Since I did not specifically create a typography I assumed I'd get a default typography back but no, I do not get anything back.

It does state that typography is not uncluded by default, however. So then I tried to create a default typography but I'm absolutely unable to find out on how to add this typography into my theme so I can extract it later on again. The define-dark-theme function does not contain an argument for typography but only allows to pass the three color palettes.

@angular_theming.scss:

@function define-dark-theme($primary, $accent: null, $warn: define-palette(palette.$red-palette)) { ... }

I've tried to just create the default typography and throw it into the mat.core function hoping this might set it somewhere in a variable (default or something, maybe?), which the theme creation then accesses but no, this didn't do anything; my theme is still without a typography. I've tried to set it both before and after calling the define-dark-theme and all-component-themes to no avail.

theme.scss:

$wb-typography-config: mat.define-typography-config();
@include mat.core($wb-typography-config);
    
$wb-theme: mat.define-dark-theme(...);
@include mat.all-component-themes($wb-theme);
@include reboot.theme($wb-theme);

or

$wb-theme: mat.define-dark-theme(...);
$wb-typography-config: mat.define-typography-config();

@include mat.all-component-themes($wb-theme);
@include mat.core($wb-typography-config);
@include reboot.theme($wb-theme);

Neither google nor any of the typography guides were of any help because none of them actually set the typography in the theme, but the material functions scream in my face that yes, that damn theme should have a typography. So what is going on here? How do I get a typography into my theme so that get-typography-config($theme) actually does return a typography config? Am I being stuck in deprecated thinking and that whole function isn't used anymore? Then how would I do this at all, what would I have to set and access? I would prefer having the typography in my theme, though.

Upvotes: 4

Views: 2625

Answers (2)

Philippe
Philippe

Reputation: 1049

In my case I could add Angular's default typography by using mat.define-typography-config() (defined in _typography.scss) and adding its returned map to mat.define-light-theme() (next to color).

$theme-or-config: mat.define-light-theme(
  (
    color: (
      primary: $wb-primary,
      accent: $wb-accent,
      warn: $wb-warn,
    ),
    typography: mat.define-typography-config(), //❗👀
  )
);

And now I am able to retrieve typography values in my components theme file:

@mixin -typography($theme) {
  $typography-config: mat.get-typography-config($theme);

  font: {
    family: mat.font-family($typography-config, button);
    size: mat.font-size($typography-config, button);
    weight: mat.font-weight($typography-config, button);
  }
}

Upvotes: 1

Stephen Legge
Stephen Legge

Reputation: 21

You just need to add the typography config into the theme map when you create it.

    $theme-or-config: mat.define-light-theme(
        (
            color: (
                primary: $wb-primary,
                accent: $wb-accent,
                warn: $wb-warn,
            ),
            typography: $wb-typography-config
        )
    );

Upvotes: 2

Related Questions