You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

192 lines
6.2 KiB

//
// Copyright 2018 Google Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
@import "./variables";
//
// Flips the radius values based on RTL context.
//
// Examples:
//
// 1. mdc-shape-flip-radius((0, 4px, 4px, 0)) => 4px 0 0 4px
// 2. mdc-shape-flip-radius((0, 8px)) => 8px 0
//
@function mdc-shape-flip-radius($radius) {
@if type-of($radius) == "list" {
@if length($radius) > 4 {
@error "Invalid radius: '#{$radius}' is more than 4 values";
}
}
@if length($radius) == 4 {
@return nth($radius, 2) nth($radius, 1) nth($radius, 4) nth($radius, 3);
} @else if length($radius) == 3 {
@return nth($radius, 2) nth($radius, 1) nth($radius, 2) nth($radius, 3);
} @else if length($radius) == 2 {
@return nth($radius, 2) nth($radius, 1);
} @else {
@return $radius;
}
}
//
// Resolves the percentage unit radius to appropriate absolute radius value based on component height.
// Use this for fixed height components only.
//
// Examples:
//
// mdc-shape-resolve-percentage-radius(36px, 50%) => `18px` (i.e., 36px / 2)
//
@function mdc-shape-resolve-percentage-radius($component-height, $radius) {
$radius: mdc-shape-prop-value($radius);
@if type-of($radius) == "list" {
$radius-value: ();
@each $corner in $radius {
$radius-value: append($radius-value, mdc-shape-resolve-percentage-for-corner_($component-height, $corner));
}
@return $radius-value;
} @else {
@return mdc-shape-resolve-percentage-for-corner_($component-height, $radius);
}
}
//
// Returns $radius value of shape category - `large`, `medium` or `small`.
// Otherwise, it returns the $radius itself if valid.
// $radius can be a single value, or a list of up to 4 values.
//
// Examples:
//
// mdc-shape-prop-value(small) => 4px
// mdc-shape-prop-value(small small 0 0) => 4px 4px 0 0
//
@function mdc-shape-prop-value($radius) {
@if type-of($radius) == "list" {
@if length($radius) > 4 {
@error "Invalid radius: '#{$radius}' is more than 4 values";
}
$radius-values: ();
@for $i from 1 through length($radius) {
$corner: nth($radius, $i);
@if map-has-key($mdc-shape-category-values, $corner) {
// If a category is encountered within a list of radii, apply the category's value for the corresponding corner
$radius-values:
append($radius-values, nth(mdc-shape-unpack-radius_(map-get($mdc-shape-category-values, $corner)), $i));
} @else {
$radius-values: append($radius-values, mdc-shape-validate-radius-value_($corner));
}
}
@return $radius-values;
} @else {
@if map-has-key($mdc-shape-category-values, $radius) {
@return map-get($mdc-shape-category-values, $radius);
} @else {
@return mdc-shape-validate-radius-value_($radius);
}
}
}
//
// Accepts radius number or list of 2-4 radius values and returns 4 value list with
// masked corners as mentioned in `$masked-corners`
//
// Example:
//
// 1. mdc-shape-mask-radius(2px 3px, 1 1 0 0) => 2px 3px 0 0
// 2. mdc-shape-mask-radius(8px, 0 0 1 1) => 0 0 8px 8px
// 3. mdc-shape-mask-radius(4px 4px 4px 4px, 0 1 1 0) => 0 4px 4px 0
//
@function mdc-shape-mask-radius($radius, $masked-corners) {
@if type-of($radius) == "list" {
@if length($radius) > 4 {
@error "Invalid radius: '#{$radius}' is more than 4 values";
}
}
@if length($masked-corners) != 4 {
@error "Expected masked-corners of length 4 but got '#{length($masked-corners)}'.";
}
$radius: mdc-shape-unpack-radius_($radius);
@return if(nth($masked-corners, 1) == 1, nth($radius, 1), 0)
if(nth($masked-corners, 2) == 1, nth($radius, 2), 0)
if(nth($masked-corners, 3) == 1, nth($radius, 3), 0)
if(nth($masked-corners, 4) == 1, nth($radius, 4), 0);
}
//
// Unpacks shorthand values for border-radius (i.e. lists of 1-3 values).
// If a list of 4 values is given, it is returned as-is.
//
// Examples:
//
// 1. mdc-shape-unpack-radius_(4px) => 4px 4px 4px 4px
// 2. mdc-shape-unpack-radius_(4px 2px) => 4px 2px 4px 2px
// 3. mdc-shape-unpack-radius_(4px 2px 2px) => 4px 2px 2px 2px
// 2. mdc-shape-unpack-radius_(4px 2px 0 2px) => 4px 2px 0 2px
//
// TODO: This is private for purposes of getting it into a patch; make it public for a future minor/major release.
//
@function mdc-shape-unpack-radius_($radius) {
@if length($radius) == 4 {
@return $radius;
} @else if length($radius) == 3 {
@return nth($radius, 1) nth($radius, 2) nth($radius, 3) nth($radius, 2);
} @else if length($radius) == 2 {
@return nth($radius, 1) nth($radius, 2) nth($radius, 1) nth($radius, 2);
} @else if length($radius) == 1 {
@return $radius $radius $radius $radius;
}
@error "Invalid radius: '#{$radius}' is more than 4 values";
}
@function mdc-shape-resolve-percentage-for-corner_($component-height, $radius) {
@if type-of($radius) == "number" and unit($radius) == "%" {
// Converts the percentage to number without unit. Example: 50% => 50.
$percentage: $radius / ($radius * 0 + 1);
@return $component-height * ($percentage / 100);
} @else {
@return $radius;
}
}
@function mdc-shape-validate-radius-value_($radius) {
$is-number: type-of($radius) == "number";
@if not ($is-number or str_index($radius, "var(") or str_index($radius, "calc(")) {
@error "Invalid radius: #{$radius}";
}
@return $radius;
}