From 8e480deae3501eaec7d8d5f5b959bff10ab699d7 Mon Sep 17 00:00:00 2001 From: Elizabeth Mitchell Date: Fri, 8 Sep 2023 10:58:14 -0700 Subject: [PATCH] feat(typography): add typography Sass APIs BREAKING CHANGE: composite `-type` tokens are no longer supported. Use discrete `-font`, `-size`, `-line-height`, and `-weight` tokens instead. PiperOrigin-RevId: 563797716 --- tokens/_md-ref-typeface.scss | 26 ++++++----- tokens/_md-sys-typescale.scss | 86 ++++++++++++++++++++++++----------- typography/_typeface.scss | 49 ++++++++++++++++++++ typography/_typescale.scss | 50 ++++++++++++++++++++ 4 files changed, 173 insertions(+), 38 deletions(-) create mode 100644 typography/_typeface.scss create mode 100644 typography/_typescale.scss diff --git a/tokens/_md-ref-typeface.scss b/tokens/_md-ref-typeface.scss index 5fb74eb337..15c59616b6 100644 --- a/tokens/_md-ref-typeface.scss +++ b/tokens/_md-ref-typeface.scss @@ -8,6 +8,7 @@ // go/keep-sorted end // go/keep-sorted start @use './v0_172/md-ref-typeface'; +@use './values'; // go/keep-sorted end $supported-tokens: ( @@ -20,18 +21,21 @@ $supported-tokens: ( // go/keep-sorted end ); -@function values($exclude-hardcoded-values: false) { - $tokens: md-ref-typeface.values($exclude-hardcoded-values); +@function values( + $exclude-hardcoded-values: false, + $exclude-custom-properties: false +) { + $tokens: md-ref-typeface.values( + $exclude-hardcoded-values: $exclude-hardcoded-values, + ); - @each $token in $supported-tokens { - $value: map.get($tokens, $token); - @if $value != null { - $tokens: map.set( - $tokens, - $token, - var(--md-ref-typeface-#{$token}, #{$value}) - ); + @if not $exclude-custom-properties { + // Create --md-ref-typeface-* custom properties + @each $token, $value in $tokens { + $var: var(--md-ref-typeface-#{$token}, #{$value}); + $tokens: map.set($tokens, $token, $var); } } - @return $tokens; + + @return values.validate($tokens, $supported-tokens: $supported-tokens); } diff --git a/tokens/_md-sys-typescale.scss b/tokens/_md-sys-typescale.scss index 70e33c8a78..6da9d3ad4e 100644 --- a/tokens/_md-sys-typescale.scss +++ b/tokens/_md-sys-typescale.scss @@ -9,80 +9,69 @@ // go/keep-sorted start @use './md-ref-typeface'; @use './v0_172/md-sys-typescale'; +@use './values'; // go/keep-sorted end $supported-tokens: ( // go/keep-sorted start - 'body-large', 'body-large-font', 'body-large-line-height', 'body-large-size', 'body-large-weight', - 'body-medium', 'body-medium-font', 'body-medium-line-height', 'body-medium-size', - 'body-small', + 'body-medium-weight', 'body-small-font', 'body-small-line-height', 'body-small-size', 'body-small-weight', - 'display-large', 'display-large-font', 'display-large-line-height', 'display-large-size', 'display-large-weight', - 'display-medium', 'display-medium-font', 'display-medium-line-height', 'display-medium-size', 'display-medium-weight', - 'display-small', 'display-small-font', 'display-small-line-height', 'display-small-size', 'display-small-weight', - 'headline-large', 'headline-large-font', 'headline-large-line-height', 'headline-large-size', 'headline-large-weight', - 'headline-medium', 'headline-medium-font', 'headline-medium-line-height', 'headline-medium-size', 'headline-medium-weight', - 'headline-small', 'headline-small-font', 'headline-small-line-height', 'headline-small-size', 'headline-small-weight', - 'label-large', 'label-large-font', 'label-large-line-height', 'label-large-size', 'label-large-weight', - 'label-medium', + 'label-large-weight-prominent', 'label-medium-font', 'label-medium-line-height', 'label-medium-size', 'label-medium-weight', - 'label-small', + 'label-medium-weight-prominent', 'label-small-font', 'label-small-line-height', 'label-small-size', 'label-small-weight', - 'title-large', 'title-large-font', 'title-large-line-height', 'title-large-size', 'title-large-weight', - 'title-medium', 'title-medium-font', 'title-medium-line-height', 'title-medium-size', 'title-medium-weight', - 'title-small', 'title-small-font', 'title-small-line-height', 'title-small-size', @@ -90,23 +79,66 @@ $supported-tokens: ( // go/keep-sorted end ); +$unsupported-tokens: ( + // go/keep-sorted start + 'body-large', + 'body-large-tracking', + 'body-medium', + 'body-medium-tracking', + 'body-small', + 'body-small-tracking', + 'display-large', + 'display-large-tracking', + 'display-medium', + 'display-medium-tracking', + 'display-small', + 'display-small-tracking', + 'headline-large', + 'headline-large-tracking', + 'headline-medium', + 'headline-medium-tracking', + 'headline-small', + 'headline-small-tracking', + 'label-large', + 'label-large-tracking', + 'label-medium', + 'label-medium-tracking', + 'label-small', + 'label-small-tracking', + 'title-large', + 'title-large-tracking', + 'title-medium', + 'title-medium-tracking', + 'title-small', + 'title-small-tracking', + // go/keep-sorted end +); + $_default: ( 'md-ref-typeface': md-ref-typeface.values(), ); -@function values($deps: $_default, $exclude-hardcoded-values: false) { - $tokens: md-sys-typescale.values($deps, $exclude-hardcoded-values); +@function values( + $deps: $_default, + $exclude-hardcoded-values: false, + $exclude-custom-properties: false +) { + $tokens: md-sys-typescale.values( + $deps, + $exclude-hardcoded-values: $exclude-hardcoded-values + ); - // TODO(b/271876162): Remove when the token compiler emits these custom properties - @each $token in $supported-tokens { - $value: map.get($tokens, $token); - @if $value != null { - $tokens: map.set( - $tokens, - $token, - var(--md-sys-typescale-#{$token}, #{$value}) - ); + @if not $exclude-custom-properties { + // Create --md-sys-typescale-* custom properties + @each $token, $value in $tokens { + $var: var(--md-sys-typescale-#{$token}, #{$value}); + $tokens: map.set($tokens, $token, $var); } } - @return $tokens; + + @return values.validate( + $tokens, + $supported-tokens: $supported-tokens, + $unsupported-tokens: $unsupported-tokens + ); } diff --git a/typography/_typeface.scss b/typography/_typeface.scss new file mode 100644 index 0000000000..9ad3ced119 --- /dev/null +++ b/typography/_typeface.scss @@ -0,0 +1,49 @@ +// +// Copyright 2023 Google LLC +// SPDX-License-Identifier: Apache-2.0 +// + +// go/keep-sorted start +@use 'sass:list'; +// go/keep-sorted end +// go/keep-sorted start +@use '../tokens'; +// go/keep-sorted end + +/// `typeface.theme()` emits `--md-ref-typeface-*` custom properties for given +/// font families and weights. +/// +/// Use this to change the font families or weights for all typescales. +/// +/// @example scss +/// @use '@material/web/typography/typeface'; +/// +/// :root { +/// @include typeface.theme( +/// 'brand': 'Open Sans', +/// 'plain': sans-serif, +/// 'weight-bold': 900, +/// ); +/// } +/// +/// /* Generated CSS */ +/// :root { +/// --md-ref-typeface-brand: 'Open Sans'; +/// --md-ref-typeface-plain: sans-serif; +/// --md-ref-typeface-weight-bold: 900; +/// } +/// +/// @param {Map} $tokens - A Map with `md-ref-typeface` token name keys and +/// their corresponding font family or weight values. +/// @output Emits `--md-ref-typeface-*` custom properties. +@mixin theme($tokens) { + @each $token, $value in $tokens { + @if list.index(tokens.$md-ref-typeface-supported-tokens, $token) == null { + @error 'md-ref-typeface `#{$token}` is not a supported token.'; + } + + @if $value { + --md-ref-typeface-#{$token}: #{$value}; + } + } +} diff --git a/typography/_typescale.scss b/typography/_typescale.scss new file mode 100644 index 0000000000..ee10e189e2 --- /dev/null +++ b/typography/_typescale.scss @@ -0,0 +1,50 @@ +// +// Copyright 2023 Google LLC +// SPDX-License-Identifier: Apache-2.0 +// + +// go/keep-sorted start +@use 'sass:list'; +// go/keep-sorted end +// go/keep-sorted start +@use '../tokens'; +// go/keep-sorted end + +/// `typescale.theme()` emits `--md-sys-typescale-*` custom properties for given +/// typescale tokens. +/// +/// Use `typeface.theme()` to change font family and weight for all typescales, +/// rather than individually. +/// +/// @example scss +/// @use '@material/web/typography/typescale'; +/// +/// :root { +/// @include typescale.theme( +/// 'body-medium-size': 1rem, +/// 'body-medium-line-height': 1.5rem, +/// /* ... */ +/// ); +/// } +/// +/// /* Generated CSS */ +/// :root { +/// --md-sys-typescale-body-medium-size: 1rem; +/// --md-sys-typescale-body-medium-line-height: 1.5rem; +/// /* ... */ +/// } +/// +/// @param {Map} $tokens - A Map with `md-sys-typescale` token name keys and +/// their corresponding `font` shorthand values. +/// @output Emits `--md-sys-typescale-*` custom properties for given typescales. +@mixin theme($tokens) { + @each $token, $value in $tokens { + @if list.index(tokens.$md-sys-typescale-supported-tokens, $token) == null { + @error 'md-sys-typescale `#{$token}` is not a supported token.'; + } + + @if $value { + --md-sys-typescale-#{$token}: #{$value}; + } + } +}