diff --git a/labs/gb/styles/tailwind.scss b/labs/gb/styles/tailwind.scss index 5b44b32dac..9f67e727ee 100644 --- a/labs/gb/styles/tailwind.scss +++ b/labs/gb/styles/tailwind.scss @@ -70,50 +70,136 @@ #{'--font-*'}: initial; // Do not use Tailwind's default font utilities. --font-brand: var(--md-ref-typeface-brand); --font-plain: var(--md-ref-typeface-plain); + --font-weight-normal: var(--md-ref-typeface-weight-regular); + --font-weight-medium: var(--md-ref-typeface-weight-medium); + --font-weight-bold: var(--md-ref-typeface-weight-bold); #{'--text-*'}: initial; // Do not use Tailwind's default text utilities. #{'--tracking-*'}: initial; #{'--leading-*'}: initial; // Use the `typescale--` utility to apply typography tokens. --typescale-label-sm: var(--md-sys-typescale-label-sm); --typescale-label-sm-tracking: var(--md-sys-typescale-label-sm-tracking); + --typescale-label-sm-axes: var(--md-sys-typescale-label-sm-axes); --typescale-label-md: var(--md-sys-typescale-label-md); --typescale-label-md-tracking: var(--md-sys-typescale-label-md-tracking); + --typescale-label-md-axes: var(--md-sys-typescale-label-md-axes); --typescale-label-lg: var(--md-sys-typescale-label-lg); --typescale-label-lg-tracking: var(--md-sys-typescale-label-lg-tracking); + --typescale-label-lg-axes: var(--md-sys-typescale-label-lg-axes); --typescale-body-sm: var(--md-sys-typescale-body-sm); --typescale-body-sm-tracking: var(--md-sys-typescale-body-sm-tracking); + --typescale-body-sm-axes: var(--md-sys-typescale-body-sm-axes); --typescale-body-md: var(--md-sys-typescale-body-md); --typescale-body-md-tracking: var(--md-sys-typescale-body-md-tracking); + --typescale-body-md-axes: var(--md-sys-typescale-body-md-axes); --typescale-body-lg: var(--md-sys-typescale-body-lg); --typescale-body-lg-tracking: var(--md-sys-typescale-body-lg-tracking); + --typescale-body-lg-axes: var(--md-sys-typescale-body-lg-axes); --typescale-title-sm: var(--md-sys-typescale-title-sm); --typescale-title-sm-tracking: var(--md-sys-typescale-title-sm-tracking); + --typescale-title-sm-axes: var(--md-sys-typescale-title-sm-axes); --typescale-title-md: var(--md-sys-typescale-title-md); --typescale-title-md-tracking: var(--md-sys-typescale-title-md-tracking); + --typescale-title-md-axes: var(--md-sys-typescale-title-md-axes); --typescale-title-lg: var(--md-sys-typescale-title-lg); --typescale-title-lg-tracking: var(--md-sys-typescale-title-lg-tracking); + --typescale-title-lg-axes: var(--md-sys-typescale-title-lg-axes); --typescale-headline-sm: var(--md-sys-typescale-headline-sm); --typescale-headline-sm-tracking: var( --md-sys-typescale-headline-sm-tracking ); + --typescale-headline-sm-axes: var(--md-sys-typescale-headline-sm-axes); --typescale-headline-md: var(--md-sys-typescale-headline-md); --typescale-headline-md-tracking: var( --md-sys-typescale-headline-md-tracking ); + --typescale-headline-md-axes: var(--md-sys-typescale-headline-md-axes); --typescale-headline-lg: var(--md-sys-typescale-headline-lg); --typescale-headline-lg-tracking: var( --md-sys-typescale-headline-lg-tracking ); + --typescale-headline-lg-axes: var(--md-sys-typescale-headline-lg-axes); --typescale-display-sm: var(--md-sys-typescale-display-sm); --typescale-display-sm-tracking: var(--md-sys-typescale-display-sm-tracking); + --typescale-display-sm-axes: var(--md-sys-typescale-display-sm-axes); --typescale-display-md: var(--md-sys-typescale-display-md); --typescale-display-md-tracking: var(--md-sys-typescale-display-md-tracking); + --typescale-display-md-axes: var(--md-sys-typescale-display-md-axes); --typescale-display-lg: var(--md-sys-typescale-display-lg); --typescale-display-lg-tracking: var(--md-sys-typescale-display-lg-tracking); - #{'--font-weight-*'}: initial; // Material supports a limited set of font weights. - --font-weight-normal: var(--md-ref-typeface-weight-regular); - --font-weight-medium: var(--md-ref-typeface-weight-medium); - --font-weight-bold: var(--md-ref-typeface-weight-bold); + --typescale-display-lg-axes: var(--md-sys-typescale-display-lg-axes); + --typescale-emphasized-label-sm: var(--md-sys-typescale-emphasized-label-sm); + --typescale-emphasized-label-sm-axes: var( + --md-sys-typescale-emphasized-label-sm-axes + ); + --typescale-emphasized-label-md: var(--md-sys-typescale-emphasized-label-md); + --typescale-emphasized-label-md-axes: var( + --md-sys-typescale-emphasized-label-md-axes + ); + --typescale-emphasized-label-lg: var(--md-sys-typescale-emphasized-label-lg); + --typescale-emphasized-label-lg-axes: var( + --md-sys-typescale-emphasized-label-lg-axes + ); + --typescale-emphasized-body-sm: var(--md-sys-typescale-emphasized-body-sm); + --typescale-emphasized-body-sm-axes: var( + --md-sys-typescale-emphasized-body-sm-axes + ); + --typescale-emphasized-body-md: var(--md-sys-typescale-emphasized-body-md); + --typescale-emphasized-body-md-axes: var( + --md-sys-typescale-emphasized-body-md-axes + ); + --typescale-emphasized-body-lg: var(--md-sys-typescale-emphasized-body-lg); + --typescale-emphasized-body-lg-axes: var( + --md-sys-typescale-emphasized-body-lg-axes + ); + --typescale-emphasized-title-sm: var(--md-sys-typescale-emphasized-title-sm); + --typescale-emphasized-title-sm-axes: var( + --md-sys-typescale-emphasized-title-sm-axes + ); + --typescale-emphasized-title-md: var(--md-sys-typescale-emphasized-title-md); + --typescale-emphasized-title-md-axes: var( + --md-sys-typescale-emphasized-title-md-axes + ); + --typescale-emphasized-title-lg: var(--md-sys-typescale-emphasized-title-lg); + --typescale-emphasized-title-lg-axes: var( + --md-sys-typescale-emphasized-title-lg-axes + ); + --typescale-emphasized-headline-sm: var( + --md-sys-typescale-emphasized-headline-sm + ); + --typescale-emphasized-headline-sm-axes: var( + --md-sys-typescale-emphasized-headline-sm-axes + ); + --typescale-emphasized-headline-md: var( + --md-sys-typescale-emphasized-headline-md + ); + --typescale-emphasized-headline-md-axes: var( + --md-sys-typescale-emphasized-headline-md-axes + ); + --typescale-emphasized-headline-lg: var( + --md-sys-typescale-emphasized-headline-lg + ); + --typescale-emphasized-headline-lg-axes: var( + --md-sys-typescale-emphasized-headline-lg-axes + ); + --typescale-emphasized-display-sm: var( + --md-sys-typescale-emphasized-display-sm + ); + --typescale-emphasized-display-sm-axes: var( + --md-sys-typescale-emphasized-display-sm-axes + ); + --typescale-emphasized-display-md: var( + --md-sys-typescale-emphasized-display-md + ); + --typescale-emphasized-display-md-axes: var( + --md-sys-typescale-emphasized-display-md-axes + ); + --typescale-emphasized-display-lg: var( + --md-sys-typescale-emphasized-display-lg + ); + --typescale-emphasized-display-lg-axes: var( + --md-sys-typescale-emphasized-display-lg-axes + ); // Shape --radius-xs: var(--md-sys-shape-corner-xs); @@ -149,4 +235,10 @@ @utility typescale-* { font: #{'--value(--typescale-*)'}; letter-spacing: #{'--value(--typescale-*-tracking)'}; + font-variation-settings: #{'--value(--typescale-*-axes)'}; +} +@utility typescale-emphasized-* { + font: #{'--value(--typescale-emphasized-*)'}; + letter-spacing: #{'--value(--typescale-*-tracking)'}; + font-variation-settings: #{'--value(--typescale-emphasized-*-axes)'}; } diff --git a/labs/gb/styles/typography/internal/_typography-tokens.scss b/labs/gb/styles/typography/internal/_typography-tokens.scss index c5fb0aab76..b78adbff2e 100644 --- a/labs/gb/styles/typography/internal/_typography-tokens.scss +++ b/labs/gb/styles/typography/internal/_typography-tokens.scss @@ -4,17 +4,24 @@ // // go/keep-sorted start by_regex='(.+) prefix_order=sass: +@use 'sass:list'; @use 'sass:map'; @use 'sass:meta'; +@use 'sass:string'; @use '../../../../../sass/ext/map_ext'; @use '../../../../../tokens/versions/latest/sass/md-ref-typeface'; @use '../../../../../tokens/versions/latest/sass/md-sys-typescale'; +@use '../../../../../tokens/versions/latest/sass/md-sys-typescale-emphasized'; +@use '../../../../../tokens/versions/latest/sass/md-sys-typescale-emphasized-meta'; @use '../../../../../tokens/versions/latest/sass/md-sys-typescale-meta'; // go/keep-sorted end @mixin emit-custom-properties( $typescale-vars: meta.module-variables(md-sys-typescale), $typescale-meta: meta.module-variables(md-sys-typescale-meta), + $typescale-emphasized-vars: meta.module-variables(md-sys-typescale-emphasized), + $typescale-emphasized-meta: + meta.module-variables(md-sys-typescale-emphasized-meta), $typeface-vars: map.merge( meta.module-variables(md-ref-typeface), @@ -55,26 +62,88 @@ @each $scale in $scales { @each $long-size, $short-size in $sizes { $typescale: '#{$scale}-#{$long-size}'; - $weight: map_ext.get-strict( - $typescale-meta, - '#{$typescale}-weight--resolved' - ); - $size: map_ext.get-strict($typescale-vars, '#{$typescale}-size'); - $line-height: map_ext.get-strict( - $typescale-vars, - '#{$typescale}-line-height' + + $font: _font($typescale, $typescale-vars, $typescale-meta); + $tracking: map_ext.get-strict($typescale-vars, '#{$typescale}-tracking'); + $axes: _axes($typescale, $typescale-vars); + $emphasized-font: _font( + $typescale, + $typescale-emphasized-vars, + $typescale-emphasized-meta ); - $font: map_ext.get-strict( - $typescale-meta, - '#{$typescale}-font--resolved' + $emphasized-axes: _axes-emphasized( + $typescale, + $typescale-emphasized-vars ); - $tracking: map_ext.get-strict($typescale-vars, '#{$typescale}-tracking'); - --md-sys-typescale-#{$scale}-#{$short-size}: #{$weight} - #{$size} / - #{$line-height} - #{$font}; + --md-sys-typescale-#{$scale}-#{$short-size}: #{$font}; --md-sys-typescale-#{$scale}-#{$short-size}-tracking: #{$tracking}; + --md-sys-typescale-#{$scale}-#{$short-size}-axes: #{$axes}; + --md-sys-typescale-emphasized-#{$scale}-#{$short-size}: #{$emphasized-font}; + --md-sys-typescale-emphasized-#{$scale}-#{$short-size}-axes: #{$emphasized-axes}; } } } + +/// Returns the `font` shorthand for a typescale from the provided token and +/// metadata variable maps. +@function _font($typescale, $vars, $meta) { + $weight: map_ext.get-strict($meta, '#{$typescale}-weight--resolved'); + $size: map_ext.get-strict($vars, '#{$typescale}-size'); + $line-height: map_ext.get-strict($vars, '#{$typescale}-line-height'); + $family: map_ext.get-strict($meta, '#{$typescale}-font--resolved'); + @return #{$weight} #{$size} / #{$line-height} #{$family}; +} + +/// Returns the `font-variation-settings` value for a typescale from the +/// provided token variable map. Returns `normal` if no axes are changed from +/// their default values. +@function _axes($typescale, $vars) { + $axes: (); + $axes: _append-axis($axes, map_ext.get-strict($vars, '#{$typescale}-rond')); + $axes: _append-axis($axes, map_ext.get-strict($vars, '#{$typescale}-grad')); + @if list.length($axes) == 0 { + @return normal; + } + @return $axes; +} + +// TODO: Remove this function once emphasized tokens are fixed to use `'ROND' 100` +@function _axes-emphasized($typescale, $vars) { + $axes: (); + $axes: _append-axis($axes, ('ROND' 100)); + $axes: _append-axis($axes, map_ext.get-strict($vars, '#{$typescale}-grad')); + @return $axes; +} + +/// Appends a font axis to a list if it is not the default value for the axis. +@function _append-axis($axes, $axis) { + // Not all axes from Carbon are supported in gBreeze. + // - 'opsz': use `font-size` + // - 'slnt': use `font-style` + // - 'wdth': use `font-stretch`/`font-width` + // - 'wght': use `font-weight` + $default-axes: ( + 'ROND': 0, + 'GRAD': 0, + // These axes are unused in Material, but included for Carbon completeness. + 'CRSV': 0, + 'FILL': 0, + 'HEXP': 0, + ); + $axis-tag: list.nth($axis, 1); + $axis-value: list.nth($axis, 2); + @if not map.has-key($default-axes, $axis-tag) { + // Do not append unsupported axes. + @return $axes; + } + @if map.get($default-axes, $axis-tag) == $axis-value { + // Do not append axes with default values. + @return $axes; + } + + // Manually add quotes since Sass removes them for custom property values, + // even with string.quote(). + $axis: '"#{$axis-tag}" #{$axis-value}'; + @return list.append($axes, $axis, $separator: comma); +}