/** * Checks if a list contains a certain value. * * @param {list} $list - the list to check * @param {value} $var - the value to search for * @param {bool} $recursive (false) - should any contained lists be checked for the value * * @return {bool} true if the value is found from the list, false otherwise * * @group lists */ @function contains($list, $value, $recursive: false) { @if $recursive == false { @return (false != index($list, $value)); } $ret: false; @each $item in $list { @if type-of($item) == list and $recursive { @if contains($item, $value, true) { @return true; } } @else if $item == $value { @return true; } } @return false; } /** * Check whether a list contains nested lists. * * @param {list} $list - the list to check * * @return {bool} true of the list contains other nested lists, false otherwise * * @group lists */ @function list-of-lists($list) { @each $part in $list { @if type-of($part) != list { @return false; } } @return true; } /** * Get the first color value from a list. * * @param {list} $list - a list which should contain a color value * * @return {color} The first color encountered in the list * * @group lists */ @function first-color($list) { @return first-of-type($list, color); } /** * Get the first number value from a list. * * @param {list} $list - a list which should contain a number value * * @return {number} The first number encountered in the list * * @group lists */ @function first-number($list) { @return first-of-type($list, number); } /** * Get the first string value from a list. * * @param {list} $list - a list which should contain a string value * * @return {string} The first string encountered in the list * * @group lists */ @function first-string($list) { @return first-of-type($list, string); } /** * Get the first contained list from the list passed as the parameter. * * @param {list} $list - a list which should contain a nested list * * @return {list} The first list encountered in the list passed as the parameter * * @group lists */ @function first-list($list) { @return first-of-type($list, list); } /** * Get the first value of a certain type from a list. * * @param {list} $list - a list which should contain a value of the certain type * @param {string} $type - the type of value to search for * * @return {value} The first item of the certain type encountered in the list * * @group lists */ @function first-of-type($list, $type) { @each $item in $list { @if type-of($item) == $type { @return $item; } @else if type-of($item) == list { $ret: first-of-type($item, $type); @if $ret { @return $ret; } } } @return null; } /** * Flatten nested lists to one list, while maintaining the original list separators. * * @param {list} $list - the list to flatten * * @return {list} the same list with all nested lists flattened * * @group lists */ @function flatten-list($list) { $ret: (); @each $item in $list { @if type-of($item) != list and $item != null { $ret: join($ret, $item); } @else if length($item) > 0 and $item != null { $t: flatten-list($item); @if length($t) > 0 { $ret: join($ret, $t); } } } @return $ret; } // Author: Hugo Giraudel // Repository: https://github.com/Team-Sass/Sass-list-functions // License: MIT @function first($list) { @return nth($list, 1); } @function last($list) { @return nth($list, length($list)); } @function last-index($list, $value) { @for $i from length($list)*-1 through -1 { @if nth($list, abs($i)) == $value { @return abs($i); } } @return null; } @function to-string($list, $glue: '', $is-nested: false) { $result: null; @for $i from 1 through length($list) { $e: nth($list, $i); @if type-of($e) == list { $result: $result#{to-string($e, $glue, true)}; } @else { $result: if($i != length($list) or $is-nested, $result#{$e}#{$glue}, $result#{$e}); } } @return $result; } @function prepend($list, $value) { @return join($value, $list); } @function insert-nth($list, $index, $value) { $result: false; @if type-of($index) != number { @warn "$index: #{quote($index)} is not a number for `insert-nth`."; @return $result; } @else if $index < 1 { @warn "List index 0 must be a non-zero integer for `insert-nth`"; @return $result; } @else if $index > length($list) { @warn "List index is #{$index} but list is only #{length($list)} item long for `insert-nth'."; @return $result; } @else { $result: (); @for $i from 1 through length($list) { @if $i == $index { $result: append($result, $value); } $result: append($result, nth($list, $i)); } } @return $result; } @function replace-nth($list, $index, $value) { $result: false; @if type-of($index) != number { @warn "$index: #{quote($index)} is not a number for `replace-nth`."; @return $result; } @else if $index == 0 { @warn "List index 0 must be a non-zero integer for `replace-nth`."; @return $result; } @else if abs($index) > length($list) { @warn "List index is #{$index} but list is only #{length($list)} item long for `replace-nth`."; @return $result; } @else { $result: (); $index: if($index < 0, length($list) + $index + 1, $index); @for $i from 1 through length($list) { @if $i == $index { $result: append($result, $value); } @else { $result: append($result, nth($list, $i)); } } } @return $result; } @function replace($list, $old-value, $new-value, $recursive: false) { $result: (); @for $i from 1 through length($list) { @if type-of(nth($list, $i)) == list and $recursive { $result: append($result, replace(nth($list, $i), $old-value, $new-value, $recursive)); } @else { @if nth($list, $i) == $old-value { $result: append($result, $new-value); } @else { $result: append($result, nth($list, $i)); } } } @return $result; } @function remove-nth($list, $index) { $result: false; @if type-of($index) != number { @warn "$index: #{quote($index)} is not a number for `remove-nth`."; @return $result; } @else if $index == 0 { @warn "List index 0 must be a non-zero integer for `remove-nth`."; @return $result; } @else if abs($index) > length($list) { @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; @return $result; } @else { $result: (); $index: if($index < 0, length($list) + $index + 1, $index); @for $i from 1 through length($list) { @if $i != $index { $result: append($result, nth($list, $i)); } } } @return $result; } @function remove($list, $value, $recursive: false) { $result: (); @for $i from 1 through length($list) { @if type-of(nth($list, $i)) == list and $recursive { $result: append($result, remove(nth($list, $i), $value, $recursive)); } @else if nth($list, $i) != $value { $result: append($result, nth($list, $i)); } } @return $result; } @function slice($list, $start: 1, $end: length($list)) { $result: false; @if type-of($start) != number or type-of($end) != number { @warn "Either $start or $end are not a number for `slice`."; @return $result; } @else if $start > $end { @warn "The start index has to be lesser than or equals to the end index for `slice`."; @return $result; } @else if $start < 1 or $end < 1 { @warn "List indexes must be non-zero integers for `slice`."; @return $result; } @else if $start > length($list) { @warn "List index is #{$start} but list is only #{length($list)} item long for `slice`."; @return $result; } @else if $end > length($list) { @warn "List index is #{$end} but list is only #{length($list)} item long for `slice`."; @return $result; } @else { $result: (); @for $i from $start through $end { $result: append($result, nth($list, $i)); } } @return $result; } @function reverse($list, $recursive: false) { $result: (); @for $i from length($list)*-1 through -1 { @if type-of(nth($list, abs($i))) == list and $recursive { $result: append($result, reverse(nth($list, abs($i)), $recursive)); } @else { $result: append($result, nth($list, abs($i))); } } @return $result; } @function shift($list, $value: 1) { $result: (); @for $i from 0 to length($list) { $result: append($result, nth($list, ($i - $value) % length($list) + 1)); } @return $result; }