mirror of
https://github.com/material-components/material-web.git
synced 2026-03-09 00:09:23 +08:00
155 lines
4.7 KiB
SCSS
155 lines
4.7 KiB
SCSS
//
|
|
// Copyright 2021 Google LLC
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
|
|
// go/keep-sorted start
|
|
@use 'sass:list';
|
|
@use 'sass:map';
|
|
@use 'sass:meta';
|
|
@use 'sass:string';
|
|
// go/keep-sorted end
|
|
// go/keep-sorted start
|
|
@use './string-ext';
|
|
@use './var';
|
|
// go/keep-sorted end
|
|
|
|
/// Resolves one or more shape tokens and expands them into 4 separate logical
|
|
/// tokens for each corner.
|
|
///
|
|
/// Must be called after `theme.create-theme-vars()`
|
|
///
|
|
/// @example - scss
|
|
/// $theme: (container-shape: (4px 4px 0 0));
|
|
/// $tokens: theme.create-theme-vars($theme, component);
|
|
/// $tokens: shape.resolve-tokens(
|
|
/// $tokens,
|
|
/// container-shape,
|
|
/// );
|
|
///
|
|
/// // (
|
|
/// // container-shape-start-start: var(--md-component-container-shape-start-start, var(--md-component-container-shape, 4px)),
|
|
/// // container-shape-start-end: var(--md-component-container-shape-start-end, var(--md-component-container-shape, 4px)),
|
|
/// // container-shape-end-end: var(--md-component-container-shape-end-start, var(--md-component-container-shape, 0)),
|
|
/// // container-shape-end-start: var(--md-component-container-shape-end-end, var(--md-component-container-shape, 0)),
|
|
/// // )
|
|
///
|
|
/// @param {Map} $tokens - The theme to resolve tokens for.
|
|
/// @param {String...} $shape-tokens - The shape tokens to resolve.
|
|
/// @return {Map} The theme with resolved shape tokens.
|
|
@function resolve-tokens($tokens, $shape-tokens...) {
|
|
@each $token in $shape-tokens {
|
|
$shape: map.get($tokens, $token);
|
|
@if $shape != null {
|
|
@if not var.is-var($shape) {
|
|
@error 'resolve-tokens() must be called after theme.create-theme-vars()';
|
|
}
|
|
$shape-name: var.name($shape);
|
|
// fallback may be a stringified list, split into sass list again
|
|
$shape: string-ext.split(var.fallback($shape));
|
|
$shape-theme: resolver(
|
|
$shape: $shape,
|
|
);
|
|
|
|
@each $key, $value in $shape-theme {
|
|
$corner-name: '#{$shape-name}-#{$key}';
|
|
$shape-theme: map.set(
|
|
$shape-theme,
|
|
$key,
|
|
var.create($corner-name, var.create($shape-name, $value))
|
|
);
|
|
}
|
|
|
|
// Add resolved values, but allow $theme to override the results if needed.
|
|
$tokens: map.merge(
|
|
(
|
|
'#{$token}-start-start': map.get($shape-theme, start-start),
|
|
'#{$token}-start-end': map.get($shape-theme, start-end),
|
|
'#{$token}-end-end': map.get($shape-theme, end-end),
|
|
'#{$token}-end-start': map.get($shape-theme, end-start),
|
|
),
|
|
$tokens
|
|
);
|
|
|
|
$tokens: map.remove($tokens, $token);
|
|
}
|
|
}
|
|
|
|
@return $tokens;
|
|
}
|
|
|
|
/// Generate a shape token list from the expanded corners.
|
|
///
|
|
/// @example - scss
|
|
/// $shape: shape.corners-to-shape-token(--md-component-container-shape);
|
|
/// // (
|
|
/// // var(--md-component-container-shape-start-start),
|
|
/// // var(--md-component-container-shape-start-end),
|
|
/// // var(--md-component-container-shape-end-end),
|
|
/// // var(--md-component-container-shape-end-start),
|
|
/// // )
|
|
/// foo.theme((shape: $shape))
|
|
///
|
|
/// @param {String} $shape-token - The shape variable the corners are generated from
|
|
/// @return {List} A list that can be processed by `expand-corners`
|
|
@function corners-to-shape-token($shape-token) {
|
|
// NOTE: use a space separated list to avoid confusing `string-ext.split()`
|
|
@return (
|
|
var.create('#{$shape-token}-start-start')
|
|
var.create('#{$shape-token}-start-end')
|
|
var.create('#{$shape-token}-end-end')
|
|
var.create('#{$shape-token}-end-start')
|
|
);
|
|
}
|
|
|
|
/// Resolves a shape value by expanding it into logical values for each corner.
|
|
///
|
|
/// @param {Number|List} $shape - The shape token's value.
|
|
/// @return {Map} A map with logical tokens for each corner's value.
|
|
@function resolver($args...) {
|
|
$args: meta.keywords($args);
|
|
$shape: map.get($args, shape);
|
|
@if meta.type-of($shape) != 'list' {
|
|
@return (
|
|
start-start: $shape,
|
|
start-end: $shape,
|
|
end-end: $shape,
|
|
end-start: $shape
|
|
);
|
|
}
|
|
|
|
@if list.length($shape) == 1 {
|
|
@return (
|
|
start-start: list.nth($shape, 1),
|
|
start-end: list.nth($shape, 1),
|
|
end-end: list.nth($shape, 1),
|
|
end-start: list.nth($shape, 1)
|
|
);
|
|
}
|
|
|
|
@if list.length($shape) == 2 {
|
|
@return (
|
|
start-start: list.nth($shape, 1),
|
|
start-end: list.nth($shape, 2),
|
|
end-end: list.nth($shape, 1),
|
|
end-start: list.nth($shape, 2)
|
|
);
|
|
}
|
|
|
|
@if list.length($shape) == 3 {
|
|
@return (
|
|
start-start: list.nth($shape, 1),
|
|
start-end: list.nth($shape, 2),
|
|
end-end: list.nth($shape, 3),
|
|
end-start: list.nth($shape, 2)
|
|
);
|
|
}
|
|
|
|
@return (
|
|
start-start: list.nth($shape, 1),
|
|
start-end: list.nth($shape, 2),
|
|
end-end: list.nth($shape, 3),
|
|
end-start: list.nth($shape, 4)
|
|
);
|
|
}
|