Library of functional methods for Sass
npm install sassfpA set of utilities inspired by [Ramda][], [lodash FP][], and other Functional
libraries for Sass.
Like Ramda, all the functions in SassFP are iteratee-first, data-last. Some
native Sass methods have been re-supplied here with that argument order, but, so
far, only those that I've personally needed in projects.
SassFP is a node-module and can be installed via
``bash`
npm install sassfp
SassFP requires [Sass 3.3][] or greater due to its reliance on and ability to
manipulate [Sass maps][]. As of v1.3.1, it is compatible with [Sass 3.5][].
- String Methods
- prefixStr
- suffixStr
- explode
- pathToMap
- List Methods
- implode
- repeat
- slice
- head
- tail
- init
- last
- flatten
- partition
- contains
- intersection
- difference
- Functional Methods
- always
- identity
- T
- F
- map
- map-with-index
- filter
- reject
- reduce
- pipe
- compose
- cond
- Object Methods
- path
- prop
- pathOr
- propOr
- assign
- pick
- omit
- listPaths
- Mathematical Methods
- add
- multiply
- subtract
- divide
- percent
- double
- square
- inc
- dec
- sum
- power
- to-decimal-places
- Misc Methods
- applyUnit
- px
- em
- vw
- vh
- rem
- Argument-converted Sass Functions
- fpAppend
- fpJoin
- fpNth
- Convenience Type Boolean Methods
- is_list
- is_color
- is_string
- is_boolean
- is_number
- is_null
- is_map
- isnt_list
- isnt_color
- isnt_string
- isnt_boolean
- isnt_number
- isnt_null
- isnt_map
- Relational Methods
- equals
- eq
- lt
- lte
- gt
- gte
Returns
$str prefixed with $prefix.`scss
prefixStr('selector', 'one'); // => 'selectorone'
`$3
($suffix, $str)Returns
$str with $suffix appended to it.`scss
suffixStr('selector', 'one'); // => 'oneselector'
`$3
($separator, $str)Converts a string to a list by splitting on $separator.
`scss
explode('-', 'selector-one'); // => ('selector', 'one')
`$3
($path, $val)Converts a dot-delimited string and any value into a Sass map with that same
object heirarchy.
`scss
pathToMap('x', 10px); => (x: 10px)
pathToMap('x.y', 10px); => (x: (y: 10px))
pathToMap('x.y.z', 10px); => (x: (y: (z: 10px)))
`
List Methods
$3
($glue: '', $list: ())Returns a string where all the members of
$list have been concatenated
together with $glue between them.`scss
implode('-', ('selector', 'one')); // => 'selector-one'
`$3
($times, $item)Returns a list where
$item is represented $times times`scss
repeat(3, 10); // => (10, 10, 10)
`$3
($start, $end, $list)Returns
$list's members beginning at position $start and ending at
$end.`scss
slice(3, 5, ('alex', 'billy', 'charlie', 'dani', 'elliot')); // => ('charlie', 'dani', 'elliot')
`$3
($list)Returns the first member of
$list.`scss
head(('alex' 'billy' 'charlie' 'dani' 'elliot')); // => 'alex'
`$3
($list)Returns all but the first member of
$list.`scss
tail(('alex' 'billy' 'charlie' 'dani' 'elliot')); // => 'billy' 'charlie' 'dani' 'elliot'
`$3
($list)Returns all but the last member of
$list.`scss
init(('alex' 'billy' 'charlie' 'dani' 'elliot')); // => 'alex' 'billy' 'charlie' 'dani'
`$3
($list)Returns the last member of
$list.`scss
last(('alex' 'billy' 'charlie' 'dani' 'elliot')); // => 'elliot'
`$3
($list...)Returns a flattened version of
$list.`scss
flatten(#fff, red, (#222, #333)); // => (#fff, red, #222, #333)
`$3
($predicate, $list)Returns 2-dimensional list where the first member contains all the members of
$list for which $predicate is true, and the second, all those
for which it is false.`scss
partition(gt5, (4,5,6,7)); // => ((6 7), (4 5))
partition(gt5, (0,1,2,3)); // => ((), (0 1 2 3))
partition(gt5, (6,7,8,9)); // => ((6 7 8 9), ())
`$3
($item, $list)Returns a Boolean whether
$item is in $list.`scss
$strlist: ('alex' 'billy' 'charlie' 'dani' 'elliot');
contains('alex', $strlist); => true
contains('allen', $strlist); => false
contains('billy', $strlist); => true
`$3
($list1, $list2)Returns a new list of what both
$list1 and $list2 have in common.
Inverse of difference.`scss
$strlist: ('alex' 'billy' 'charlie' 'dani' 'elliot');
intersection(('alex', 'billy', 'allen'), $strlist); // // => ('alex' 'billy')
intersection(('alex.a', 'billy', 'allen'), $strlist); // // => ('billy')
intersection(('alex.a', 'allen'), $strlist); // // => ()
`$3
($list1, $list2)Returns new list of what
$list1 and $list2 do not have in common.
Inverse of intersection.`scss
$strlist: ('alex' 'billy' 'charlie' 'dani' 'elliot');
difference(('alex' 'billy'), $strlist); // => ()
difference(('alex' 'billy' 'allen'), $strlist); // => ('allen')
difference(('alex.a' 'billy' 'allen'), $strlist); // => ('alex.a' 'allen')
`Functional Methods
$3
($val, _$b_)Returns the first value passed to it. As of
v1.5.0, this accepts a second
optional parameter, _$b_, to not only better align with Ramda's signature, but
to also allow it to participate in compositional flows. identity ought to
be substituted for any previous usage of always, though there are no plans
to deprecate the single-argument functionality.`scss
always(1) // => 1
always('asdf') // => "asdf"
always(('x', 'y', 'z')) // => ("x", "y", "z")
always('x', 'y') // => "x"
always(true, false) // => true
always(false, true) // => false
`$3
($val)Returns the value passed to it.
`scss
identity(1) // => 1
identity('asdf') // => "asdf"
identity(('x', 'y', 'z')) // => ("x", "y", "z")
identity(true) // => true
identity(false) // => false
`
$3
($val...)Returns
true, regardless of what arguments are passed or how many there are.`scss
T(1) // => true
T('asdf') // => true
T(('x', 'y', 'z')) // => true
T('x', 'y', 'z') // => true
T(true) // => true
T(false) // => true
T() // => true
`
$3
($val...)Returns
false, regardless of what arguments are passed or how many there are.`scss
F(1) // => false
F('asdf') // => false
F(('x', 'y', 'z')) // => false
F('x', 'y', 'z') // => false
F(true) // => false
F(false) // => false
F() // => false
`$3
($fn, $list)Returns a new list where each member of
$list has had function $fn
run against it.`scss
@function darkenbyten($color) {
@return darken($color, 10%);
}
map(darkenbyten, (#fff, red, #222, #333)); // => #e6e6e6 #cc0000 #090909 #1a1a1a
`As of
v1.2.0, $fn may itself be a list where the first member is the
function to be run against each member of $list, and the others are extra
arguments that the function would require, in effect allowing functions to be
decorated.`scss
@function darkenby($pct, $color) {
@return darken($color, $pct);
}
map((darkenby, 10%), (#fff, red, #222, #333)); // => #e6e6e6 #cc0000 #090909 #1a1a1a
`Because Sass supports space-separated lists, the commas are optional, and
omitting them may increase legibility.
`scss
map((darkenby 10%), (#fff, red, #222, #333)); // => #e6e6e6 #cc0000 #090909 #1a1a1a
`Most important, however, is that the value(s) provided by iterating over
$list must always be in the last argument position $fn expects.$3
($fn, $list)Returns a new list where each member of
$list has had function $fn
run against it and its index as two arguments. Works identically to map,
but with the item's index passed as an additional argument to $fn in the
last argument position and the value provided by $list in the
second-to-last.
`scss
map-with-index(prefixStr, ("alex", "billy", "charlie")); // => ("alex1", "billy2", "charlie3")
map-with-index(add, (4, 5, 6)); // => (5, 7, 9)
`$3
($predicate, $list)Returns a new list where
$predicate returns true for members of
$list. Inverse of reject.`scss
@function gt5($val) {
@return $val > 5;
}
filter(gt5, (4,5,6,7)); // => (6, 7)
`$3
($predicate, $list)Returns a new list where
$predicate returns false for members of
$list. Inverse of filter.`scss
reject(gt5, (4,5,6,7)); // => (4, 5)
`$3
($fn, $initial, $list)Accumulates the result of running each member of
$list through $fn
starting with the $initial value and $list's first member.`scss
reduce(prefixStr, '.', ('alex', 'billy', 'charlie')); // => ".alexbillycharlie"
reduce(suffixStr, '', ('alex', 'billy', 'charlie')); // => "charliebillyalex"
reduce(add, 0, (4,5,6)); // => 15
`As of
v1.4.0, $fn may itself be a list where the first member is the
function to be run against each member of $list, and the others are extra
arguments that the function would require, in effect allowing functions to be
decorated.`scss
reduce((sum, 1, 2), 0 (4, 5, 6)); // => 24
`Most important, however, is that the value(s) provided by iterating over
**
$list must always be in the last argument position $fn expects and the
accumulator in the second-to-last**. So, in the example above, the execution
goes like this:`
function add'l values accumulator member outcome
⬇︎ ⬇︎ ⬇︎ ⬇︎ ⬇︎ ⬇︎
sum( 1, 2, 0, 4 ) => 7
sum( 1, 2, 7, 5 ) => 15
sum( 1, 2, 15, 6 ) => 24
`In the particular case of
sum, argument order isn't important, but for others it could very well be.$3
($params...)Accepts a list of arguments where the last item is the initial data and the
others are a sequence of functions to run. Returns the result of each of the
functions being run on the successive results from first to last. **The very
last item must be the data being operated on.** Functions being passed in with
additional parameters take the form of sub-lists.
`scss
pipe(
flatten,
(map, darkenbyten),
(#fff, red, (#222, #333))
); // => #e6e6e6 #cc0000 #090909 #1a1a1a
`$3
($params...)Same as
pipe, but functions run in reverse order. Initial data remains
last argument.`scss
compose(
unquote,
(prefixStr, '.'),
(implode, '-'),
(join, ('d', 'e')),
('a', 'b', 'c')
); // => .d-e-a-b-ccompose(
double,
(reduce, add, 0),
(map, square),
(4,5,6)
); // => 154
`$3
(($predicates-and-actions-list, $data))Accepts a two dimensional list of predicate and transformation functions that,
taken together, are read as a series of nested
if / else statements, where the
first true value encountered has its transformation executed against the
supplied data. Like pipe and compose, the data comes in the last
position.The assumption of both the predicate and transformation functions is that they
are unary functions where the provided data serves as the parameter to both
functions. Alternatively, n-ary functions may also be used in either assuming
that the passed value is coming in the functions' last argument positions, and
all other arguments are provided by as a list.
To ensure a return, use the
T function in the last position of
predicate-transformation pairs (so, second-to-last in overall list), coupled
with an always. As noted with map, omitting commas in the inner
lists may help with legibility.`scss
@function darkenby($pct, $color) { @return darken($color, $pct); }
@function lightenby($pct, $color) { @return lighten($color, $pct); }cond((
((equals yellow), (lightenby 20))
((equals red), (darkenby 10))
(T, (always #000))
red
)) // => #cc0000
`Object Methods
$3
($key-list, $map)Allows for getting at nested attributes in a Sass map using list syntax. Ensures
a null return for any unrecognized paths.
`scss
$colors: (header:(one: #333, two: #444), footer: #666);
path(('header', 'two'), $colors); // => #444
path(('footer'), $colors); // => #666
path(('header', 'two', 'three', 'four'), $colors); // => null
`$3
($path, $map)Allows for getting at nested attributes in a Sass map using dot syntax. Ensures
a null return for any unrecognized paths.
`scss
$colors: (header:(one: #333, two: #444), footer: #666);
prop('header.two', $colors); // => #444
prop('footer', $colors); // => #666
prop('body', $colors); // => null
`$3
($fallback, $key-list, $map)Returns the value of a
path lookup when successful, and returns a provided
fallback when not.`scss
$colors: (header:(one: #333, two: #444), footer: #666);
pathOr(':(', ('header', 'two'), $colors); // => #444
pathOr(':(', ('body'), $colors); // => ':('
pathOr(':(', ('header', 'two', 'three', 'four'), $colors); // => ':('
`$3
($fallback, $path, $map)Returns the value of a
prop lookup when successful, and returns a provided
fallback when not.`scss
$colors: (header:(one: #333, two: #444), footer: #666);
propOr(':(', 'header.two', $colors); // => #444
propOr(':(', 'footer', $colors); // => #666
propOr(':(', 'body', $colors); // => ':('
`$3
($map1, $map2)Merges 2 deeply-nested map objects.
`scss
$colors: (header:(one: #333, two: #444), footer: #666);
assign($colors, (header: (one: red))); // => (header:(one: red, two: #444), footer: #666)
assign($colors, (header: (three: red))); // => (header:(one: #333, two: #444, three: red), footer: #666)
`$3
($key-list, $map)Creates new map object from
$map selecting keys provided by
$key-list.`scss
$colors: (header:(one: #333, two: #444), footer: #666);
pick('footer', $colors); // => (footer: #666)
pick('header.one', $colors); // => (header:(one: #333))
pick(('header', 'footer'), $colors); // same as original
`$3
($key-list, $map)Creates new map object from the provided one, then removing a specified list of
keys.
`scss
omit(
('header.one', 'header.three.four'),
(header: (
one: #333,
two: #444,
three: (
four: red,
five: blue
)
),
footer: #666
));
// =>
// (header: (
// two: #444,
// three: (
// five: blue
// )
// ),
// footer: #666
// )
`$3
($map)Creates a flat, dot-delimited list of all the paths of
$map.`scss
$colors: (header:(one: #333, two: #444), footer: #666);
listPaths($colors); // => ("header" "header.one" "header.two" "footer")
`Mathematical Methods
$3
($x, $y)Adds
$y to $x.`scss
add(10, 2); // => 12
`$3
($x, $y)Multiplies
$x by $y.`scss
multiply(10, 2); // => 20
`$3
($x, $y)Subtracts
$y from $x.`scss
subtract(10, 2); // => 8
`$3
($x, $y)Divides
$x by $y.`scss
divide(10, 2); // => 5
`$3
($x, $y)Returns
$x's percent of $y.`scss
percent(2, 10); // => 50%
`$3
($x)Doubles
$x.`scss
double(10); // => 20
`$3
($x)Squares
$x.`scss
square(10); // => 100
`$3
($x)Increments
$x.`scss
inc(10); // => 11
`$3
($x)Decrements
$x.`scss
dec(10); // => 9
`$3
($num-list...)Accepts a list of numbers and returns the sum of them.
`scss
sum(10, 5, 2); // => 17
`$3
($exponent: 1, $num: 1)Returns the total after multiplying
$num $exponent times.`scss
power(2, 10); // => 100 (10^2)
power(10, 2); // => 1024 (2^10)
`$3
($digits: 2, $num: 1)Returns
$num to $digits number of significant digits dropping
anything beyond it. $digits is 2 by default since Sass has a default of
returning 3 significant digits.`scss
to-decimal-places(2, 10.129); // => 10.12
`
Misc Methods
$3
($unit, $val)Appends
$unit to $val.`scss
applyUnit(px, 50); // => 50px
applyUnit(em, 50); // => 50em
`$3
($val)Shortcut function to apply
px unit.`scss
px(50); // => 50px
`$3
($val)Shortcut function to apply
em unit.`scss
em(50); // => 50em
`$3
($val)Shortcut function to apply
vw unit.`scss
vw(50); // => 50vw
`$3
($val)Shortcut function to apply
vh unit.`scss
vh(50); // => 50vh
`$3
($val)Shortcut function to apply
rem unit.`scss
rem(50); // => 50rem
`Argument-converted Sass Functions
Existing Sass functions with data-last argument orders.
$3
($item, $list)Adds an item to the end of a provided list. See Sass [append][] documentation.
`scss
fpAppend('charlie', ('alex', 'billy')); // => 'alex' 'billy' 'charlie'
`$3
($list2, $list1)Joins
$list2 to the end of $list1. See Sass [join][] documentation.`scss
fpJoin(('charlie' 'dani'), ('alex', 'billy')); // => 'alex' 'billy' 'charlie' 'dani'
`$3
($position, $list)Returns the item at
$position from $list. See Sass [nth][] documentation.`scss
fpNth(2, ('alex', 'billy')); // => 'billy'
`
Convenience Type Boolean Methods
$3
($val)Returns whether
$val is a list.`scss
is_list((#fff, red, #222, #333)); // => true
is_list(#fff red #222 #333); // => true
is_list(#fff); // => false
`$3
($val)Returns whether
$val is a color.`scss
is_color(red); // => true
is_color('red'); // => false
`$3
($val)Returns whether
$val is a string.`scss
is_string('val'); // => true
is_string(false); // => false
`$3
($val)Returns whether
$val is a boolean.`scss
is_boolean(false); // => true
is_boolean('val'); // => false
`$3
($val)Returns whether
$val is a number.`scss
is_number(10); // => true
is_number('10'); // => false
`$3
($val)Returns whether
$val is a null.`scss
is_null(null); // => true
is_null(true); // => false
`$3
($val)Returns whether
$val is a map.`scss
is_map((header: red)); // => true
is_map((header red)); // => false
`$3
($val)Returns whether
$val is not a list.`scss
isnt_list((#fff, red, #222, #333)); // => false
isnt_list(#fff red #222 #333); // => false
isnt_list(#fff); // => true
`$3
($val)Returns whether
$val is not a color.`scss
isnt_color(red); // => false
isnt_color('red'); // => true
`$3
($val)Returns whether
$val is not a string.`scss
isnt_string('val'); // => false
isnt_string(false); // => true
`$3
($val)Returns whether
$val is not a boolean.`scss
isnt_boolean(false); // => false
isnt_boolean('val'); // => true
`$3
($val)Returns whether
$val is not a number.`scss
isnt_number(10); // => false
isnt_number('10'); // => true
`$3
($val)Returns whether
$val is not a null.`scss
isnt_null(null); // => false
isnt_null(true); // => true
`$3
($val)Returns whether
$val is not a map.`scss
isnt_map((header: red)); // => false
isnt_map((header red)); // => true
`Relational
$3
($a, $b)Returns whether
$a and $b are equivalent (function version of Sass
== operator).`scss
equals(1, 1); // => true
equals(1, '1'); // => false
equals((header: red), (header: red)); // => true
equals((header red), (header red)); // => true
`$3
($a, $b)Returns whether
$a and $b are equivalent (alias of equals).
$3
($a, $b)Returns whether the first argument is less than the second (function version of
Sass
< operator).`scss
lt(1, 10) // => true
lt(10, 1) // => false
lt(1, 1) // => false
`$3
($a, $b)Returns whether the first argument is less than or equal to the second (function
version of Sass
<= operator).`scss
lte(1, 10) // => true
lte(10, 1) // => false
lte(1, 1) // => true
`$3
($a, $b)Returns whether the first argument is greater than the second (function version
of Sass
> operator).`scss
gt(1, 10) // => false
gt(10, 1) // => true
gt(1, 1) // => false
`$3
($a, $b)Returns whether the first argument is greater than or equal to the second
(function version of Sass
>= operator).`scss
gte(1, 10) // => false
gte(10, 1) // => true
gte(1, 1) // => true
``
[Ramda]: http://ramdajs.com
[lodash FP]: https://github.com/lodash/lodash/wiki/FP-Guide
[Sass 3.3]: http://thesassway.com/news/sass-3-3-released#maps
[Sass maps]: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#maps
[Sass 3.5]: https://oddbird.net/2017/03/30/safe-get/
[append]: http://sass-lang.com/documentation/Sass/Script/Functions.html#append-instance_method
[join]: http://sass-lang.com/documentation/Sass/Script/Functions.html#join-instance_method
[nth]: http://sass-lang.com/documentation/Sass/Script/Functions.html#nth-instance_method