blob: d8b15af7fe27dd10176f0cc3a06befc31cf1ae8a [file] [log] [blame]
// Internal counter for creating unique keyframe names
$-mui-custom: 0;
/// Creates a keyframe from one or more effect functions. Use this function instead of `mui-animation` if you want to create a keyframe animation *without* automatically assigning it to the element.
/// @param {String} $name - Name of the keyframe.
/// @param {Function} $effects... - One or more effect functions to build the keyframe with.
@mixin mui-keyframes($name, $effects...) {
$obj: -mui-process-args($effects...);
$obj: map-remove($obj, name);
@keyframes #{$name} {
// Now iterate through each keyframe percentage
@each $pct, $props in $obj {
#{-mui-keyframe-pct($pct)} {
// Lastly, iterate through each CSS property within a percentage and print it out
@each $prop, $value in $props {
#{$prop}: #{$value};
}
}
}
}
}
/// Creates a string for a CSS keyframe, by converting a list of numbers to a comma-separated list of percentage values.
/// @param {Number|List} $input - List of numbers to use.
/// @return {String} A set of comma-separated percentage values.
/// @access private
@function -mui-keyframe-pct($input) {
$output: ();
@if type-of($input) == 'number' {
$output: ($input * 1%);
} @else if type-of($input) == 'list' {
@each $i in $input {
$output: append($output, ($i * 1%), comma);
}
}
@return $output;
}
/// Prints the CSS properties from a specific key in a keyframes map. Used to borrow CSS from keyframe functions for use in transitions.
/// @param {Map} $kf - Keyframe map to extract from.
/// @param {Number} $key - Key in the map to print the CSS of.
/// @access private
@mixin -mui-keyframe-get($kf, $key) {
$map: map-get($kf, $key);
@each $prop, $value in $map or () {
// Some keyframe maps store transforms as quoted strings
@if type-of($value) == 'string' {
$value: unquote($value);
}
#{$prop}: $value;
}
}
/// Reformats a map containing keys with a list of values, so that each key is a single value.
/// @param {Map} $map - Map to split up.
/// @return {Map} A reformatted map.
/// @access private
@function -mui-keyframe-split($map) {
$new-map: ();
// Split keys with multiple values into individual keys
@each $key, $item in $map {
$key-type: type-of($key);
@if $key-type == 'number' {
$new-map: map-merge($new-map, ($key: $item));
} @else if $key-type == 'list' {
@each $k in $key {
$new-map: map-merge($new-map, ($k: $item));
}
}
}
@return $new-map;
}
/// Combines a series of keyframe objects into one.
/// @param {Map} $maps... - A series of maps to merge, as individual parameters.
/// @return {Map} A combined keyframe object.
/// @access private
@function -mui-keyframe-combine($maps...) {
$new-map: ();
// Iterate through each map passed in
@each $map in $maps {
@if type-of($map) == 'string' {
$map: call(get-function($map));
}
$map: -mui-keyframe-split($map);
// Iterate through each keyframe in the map
// $key is the keyframe percentage
// $value is a map of CSS properties
@each $key, $value in $map {
$new-value: ();
@if map-has-key($new-map, $key) {
// If the map already has the keyframe %, append the new property
$new-value: -mui-merge-properties(map-get($new-map, $key), $value);
} @else {
// Otherwise, create a new map with the new property
$new-value: $value;
}
// Finally, merge the modified keyframe value into the output map
$new-map: map-merge($new-map, ($key: $new-value));
}
}
// Make a name for the keyframes
$-mui-custom: $-mui-custom + 1 !global;
$map-name: (name: 'custom-#{$-mui-custom}');
$new-map: map-merge($new-map, $map-name);
@return $new-map;
}
/// Combines two maps of CSS properties into one map. If both maps have a transform property, the values from each will be combined into one property.
/// @param {Map} $one - First map to merge.
/// @param {Map} $two - Second map to merge.
/// @return {Map} A combined map.
/// @access private
@function -mui-merge-properties($one, $two) {
@if map-has-key($one, transform) and map-has-key($two, transform) {
$transform: join(map-get($one, transform), map-get($two, transform));
$one: map-merge($one, (transform: $transform));
$two: map-remove($two, transform);
}
@return map-merge($one, $two);
}