mirror of
https://github.com/material-components/material-web.git
synced 2026-01-09 07:21:09 +08:00
240 lines
7.2 KiB
SCSS
240 lines
7.2 KiB
SCSS
//
|
|
// Copyright 2021 Google LLC
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
// go/keep-sorted start
|
|
@use 'sass:map';
|
|
@use 'sass:meta';
|
|
@use 'sass:string';
|
|
// go/keep-sorted end
|
|
// go/keep-sorted start
|
|
@use '../../sass/ext/string_ext';
|
|
// go/keep-sorted end
|
|
|
|
/// Creates a custom property `var()` string.
|
|
///
|
|
/// @param {String} $name - The name of the custom property.
|
|
/// @param {*} $fallback [null] - Optional `var()` fallback value.
|
|
/// @return {String} A custom property `var()` string.
|
|
@function create($name, $fallback: null) {
|
|
$name: create-name($name);
|
|
@if $fallback == null {
|
|
@return var(#{$name});
|
|
}
|
|
|
|
@if is-var($fallback) {
|
|
$fallback-name: name($fallback);
|
|
$fallback-fallback: fallback($fallback);
|
|
@return var(#{$name}, create($fallback-name, $fallback-fallback));
|
|
}
|
|
|
|
@return var(#{$name}, $fallback);
|
|
}
|
|
|
|
/// Create a custom property variable name.
|
|
///
|
|
/// Providing a custom property name with `--*` will ignore the global prefix.
|
|
///
|
|
/// @example - scss
|
|
/// .foo {
|
|
/// color: var(#{var.create-name(foo)});
|
|
/// background: var(#{var.create-name(--bar)});
|
|
/// }
|
|
///
|
|
/// @example - css
|
|
/// .foo {
|
|
/// color: var(--md-foo);
|
|
/// background: var(--bar);
|
|
/// }
|
|
///
|
|
/// @param {String} $name - The name of the custom property.
|
|
/// @return {String} The full valid CSS custom property variable name.
|
|
@function create-name($name) {
|
|
@if string_ext.starts-with($name, '--') {
|
|
@return $name;
|
|
}
|
|
|
|
@return string.unquote('--md-#{$name}');
|
|
}
|
|
|
|
/// Returns the custom property variable name of `var()` string.
|
|
///
|
|
/// @throw If the value is not a custom property.
|
|
/// @param {String} $var - A custom property `var()` string.
|
|
/// @return {String} The custom property variable name.
|
|
@function name($var) {
|
|
$var: _parse-and-validate($var);
|
|
@return map.get($var, name);
|
|
}
|
|
|
|
/// Returns the fallback value of a custom property `var()` string. The value
|
|
/// may be null if the `var()` does not have a fallback value.
|
|
///
|
|
/// @example - scss
|
|
/// $fallback: var.fallback(var(--foo, var(--bar, 8px));
|
|
/// // "var(--bar, 8px)"
|
|
///
|
|
/// @throw If the value is not a custom property.
|
|
/// @param {String} $var - A custom property `var()` string.
|
|
/// @return {String} The fallback value of the `var()` string. May be null if
|
|
/// the `var()` does not have a fallback value.
|
|
@function fallback($var) {
|
|
$var: _parse-and-validate($var);
|
|
$fallback: map.get($var, fallback);
|
|
@if is-var($fallback) {
|
|
@return create(name($fallback), fallback($fallback));
|
|
}
|
|
|
|
@return $fallback;
|
|
}
|
|
|
|
/// Returns the deep fallback value of a custom property `var()` string. The
|
|
/// value may be null if the `var()` does not have a fallback value.
|
|
///
|
|
/// If a fallback value is another `var()`, this function will return the final
|
|
/// concrete value in the chain.
|
|
///
|
|
/// @example - scss
|
|
/// $fallback: var.deep-fallback(var(--foo, var(--bar, 8px));
|
|
/// // "8px"
|
|
///
|
|
/// @throw If the value is not a custom property.
|
|
/// @param {String} $var - A custom property `var()` string.
|
|
/// @return {String} The deep fallback value of the `var()` string. May be null
|
|
/// if the `var()` does not have a fallback value.
|
|
@function deep-fallback($var) {
|
|
$fallback: fallback($var);
|
|
@if is-var($fallback) {
|
|
@return deep-fallback($fallback);
|
|
}
|
|
|
|
@return $fallback;
|
|
}
|
|
|
|
/// Creates a new custom property `var()` string and returns it with the
|
|
/// specified new fallback value.
|
|
///
|
|
/// @example - scss
|
|
/// $new-var: set-fallback(var(--foo, var(--bar, 8px)), 16px);
|
|
/// // "var(--foo, 16px)"
|
|
///
|
|
/// @throw If the value is not a custom property.
|
|
/// @param {String} $var - A custom property `var()` string.
|
|
/// @param {*} $new-fallback - The new fallback value. May be null to remove a
|
|
/// value.
|
|
/// @return {String} A custom property `var()` string with the new fallback
|
|
/// value.
|
|
@function set-fallback($var, $new-fallback) {
|
|
$name: name($var);
|
|
@return create($name, $new-fallback);
|
|
}
|
|
|
|
/// Creates a new custom property `var()` string and returns it with the
|
|
/// specified new deep fallback value.
|
|
///
|
|
/// If the provided `var()` string's fallback value is another `var()`, this
|
|
/// function will set the final fallback value in the chain.
|
|
///
|
|
/// @example - scss
|
|
/// $new-var: deep-set-fallback(var(--foo, var(--bar, 8px)), 16px);
|
|
/// // "var(--foo, var(--bar, 16px))"
|
|
///
|
|
/// @throw If the value is not a custom property.
|
|
/// @param {String} $var - A custom property `var()` string.
|
|
/// @param {*} $new-fallback - The new fallback value. May be null to remove a
|
|
/// value.
|
|
/// @return {String} A custom property `var()` string with the new deep
|
|
/// fallback value.
|
|
@function deep-set-fallback($var, $new-fallback) {
|
|
$old-fallback: fallback($var);
|
|
@if is-var($old-fallback) {
|
|
$new-fallback: deep-set-fallback($old-fallback, $new-fallback);
|
|
}
|
|
|
|
@return set-fallback($var, $new-fallback);
|
|
}
|
|
|
|
/// Indicates whether or not a value is a custom property `var()` string.
|
|
///
|
|
/// @example - scss
|
|
/// $is-var: var.is-var('var(--foo)'); // true
|
|
///
|
|
/// @param {*} $var - The value to test.
|
|
/// @return {Bool} True if the value is a custom property `var()` string, or
|
|
/// false if not.
|
|
@function is-var($var) {
|
|
@return _parse($var) != null;
|
|
}
|
|
|
|
/// Indicates whether or not a value is a `var()` string.
|
|
///
|
|
/// @param {*} $var - The value to test.
|
|
/// @return {Bool} True if the value is a custom property `var()` string, or
|
|
/// false if not.
|
|
@function _is-var-string($var) {
|
|
@return meta.type-of($var) == 'string' and
|
|
string_ext.starts-with($var, 'var(');
|
|
}
|
|
|
|
/// Parses a `var()` string into a Map with `name` and `fallback` keys. This
|
|
/// function returns null if the value is invalid.
|
|
///
|
|
/// @param {*} $var - The value to parse.
|
|
/// @return {Map} A Map containing a string `name` key with the custom property
|
|
/// name and a `fallback` key with the fallback value (which may be null).
|
|
/// The returned Map itself may be null if the provided value is not valid.
|
|
@function _parse($var) {
|
|
@if meta.type-of($var) ==
|
|
'map' and
|
|
map.has-key($var, name) and
|
|
map.has-key($var, fallback)
|
|
{
|
|
@return $var;
|
|
}
|
|
|
|
@if not _is-var-string($var) {
|
|
@return null;
|
|
}
|
|
|
|
// Remove function name and parens
|
|
$var: string_ext.replace-start($var, 'var(', '');
|
|
$var: string_ext.replace-end($var, ')', '');
|
|
|
|
$name: string_ext.trim($var);
|
|
$fallback: null;
|
|
$comma: string.index($var, ',');
|
|
@if $comma != null {
|
|
$name: string_ext.trim(string.slice($var, 1, $comma - 1));
|
|
$fallback: string_ext.trim(string.slice($var, $comma + 1));
|
|
@if _is-var-string($fallback) {
|
|
$fallback: _parse($fallback);
|
|
@if $fallback == null {
|
|
// Invalid var() fallback string
|
|
@return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
@if $name == '' or $fallback == '' {
|
|
@return null;
|
|
}
|
|
|
|
@return (name: $name, fallback: $fallback);
|
|
}
|
|
|
|
/// Parses a `var()` string into a Map with `name` and `fallback` keys.
|
|
///
|
|
/// @throw If the value is not a custom property.
|
|
/// @param {*} $var - The value to parse.
|
|
/// @return {Map} A Map containing a string `name` key with the custom property
|
|
/// name and a `fallback` key with the fallback value (which may be null).
|
|
@function _parse-and-validate($var) {
|
|
$var-map: _parse($var);
|
|
@if $var-map == null {
|
|
@error '"#{$var}" is not a valid var() string';
|
|
}
|
|
|
|
@return $var-map;
|
|
}
|