├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── _.scss
├── lib
├── _.scss
├── _init.scss
├── constants
│ ├── _.scss
│ ├── _init.scss
│ ├── const.scss
│ └── define.scss
├── functions
│ ├── _.scss
│ ├── class-escape.scss
│ ├── class-sanitize.scss
│ ├── class-template.scss
│ ├── em.scss
│ ├── get-function-safe.scss
│ ├── important.scss
│ ├── is-null.scss
│ ├── list-append.scss
│ ├── list-contains.scss
│ ├── list-each.scss
│ ├── list-every.scss
│ ├── list-prepend.scss
│ ├── list-remove.scss
│ ├── list-replace.scss
│ ├── list-reverse.scss
│ ├── list-sort.scss
│ ├── list-unique.scss
│ ├── map-append.scss
│ ├── map-each-key.scss
│ ├── map-each-value.scss
│ ├── map-flatten.scss
│ ├── map-get-key.scss
│ ├── map-prepend.scss
│ ├── map-stringify-keys-deep.scss
│ ├── map-stringify-keys.scss
│ ├── map-unique.scss
│ ├── random-color.scss
│ ├── rem.scss
│ ├── str-append.scss
│ ├── str-compare.scss
│ ├── str-contains.scss
│ ├── str-escape.scss
│ ├── str-prepend.scss
│ ├── str-remove.scss
│ ├── str-replace.scss
│ ├── throw.scss
│ ├── to-length.scss
│ ├── to-negative.scss
│ ├── to-number.scss
│ ├── to-string.scss
│ ├── type-check.scss
│ ├── unit-convert.scss
│ └── unit-strip.scss
├── mixins
│ ├── _.scss
│ ├── css-ruleset.scss
│ ├── extends.scss
│ ├── important.scss
│ ├── query.scss
│ ├── responsive.scss
│ └── type-scale.scss
├── options
│ ├── _.scss
│ ├── _init.scss
│ ├── option.scss
│ └── set-option.scss
└── tokens
│ ├── _.scss
│ ├── _init.scss
│ ├── get.scss
│ ├── helpers
│ ├── _.scss
│ ├── angle.scss
│ ├── background-image.scss
│ ├── baseline.scss
│ ├── border-radius.scss
│ ├── box-shadow.scss
│ ├── breakpoint.scss
│ ├── color.scss
│ ├── coordinate.scss
│ ├── duration.scss
│ ├── easing.scss
│ ├── flex-grid.scss
│ ├── font-family.scss
│ ├── font-size.scss
│ ├── font-weight.scss
│ ├── gradient.scss
│ ├── keyframe.scss
│ ├── letter-spacing.scss
│ ├── line-height.scss
│ ├── line-style.scss
│ ├── line-width.scss
│ ├── module.scss
│ ├── opacity.scss
│ ├── ratio.scss
│ ├── spacing.scss
│ ├── text-measure.scss
│ ├── text-shadow.scss
│ └── wrapper-width.scss
│ ├── set-default.scss
│ ├── set.scss
│ └── unset.scss
├── package.json
├── sache.json
├── sassdoc.yaml
├── scarab-logo.svg
├── test
├── constants
│ ├── _.scss
│ ├── const.scss
│ └── define.scss
├── functions
│ ├── _.scss
│ ├── class-escape.scss
│ ├── class-sanitize.scss
│ ├── class-template.scss
│ ├── em.scss
│ ├── get-function-safe.scss
│ ├── important.scss
│ ├── is-null.scss
│ ├── list-append.scss
│ ├── list-contains.scss
│ ├── list-each.scss
│ ├── list-every.scss
│ ├── list-prepend.scss
│ ├── list-remove.scss
│ ├── list-replace.scss
│ ├── list-reverse.scss
│ ├── list-sort.scss
│ ├── list-unique.scss
│ ├── map-append.scss
│ ├── map-each-key.scss
│ ├── map-each-value.scss
│ ├── map-flatten.scss
│ ├── map-get-key.scss
│ ├── map-prepend.scss
│ ├── map-stringify-keys-deep.scss
│ ├── map-stringify-keys.scss
│ ├── map-unique.scss
│ ├── random-color.scss
│ ├── rem.scss
│ ├── str-append.scss
│ ├── str-compare.scss
│ ├── str-contains.scss
│ ├── str-escape.scss
│ ├── str-prepend.scss
│ ├── str-remove.scss
│ ├── str-replace.scss
│ ├── throw.scss
│ ├── to-length.scss
│ ├── to-negative.scss
│ ├── to-number.scss
│ ├── to-string.scss
│ ├── type-check.scss
│ ├── unit-convert.scss
│ └── unit-strip.scss
├── mixins
│ ├── _.scss
│ ├── css-ruleset.scss
│ ├── extends.scss
│ ├── important.scss
│ ├── query.scss
│ ├── responsive.scss
│ └── type-scale.scss
├── options
│ ├── _.scss
│ ├── option.scss
│ └── set-option.scss
├── test_sass.js
├── tests.scss
└── tokens
│ ├── _.scss
│ ├── get.scss
│ ├── helpers
│ ├── _.scss
│ ├── angle.scss
│ ├── background-image.scss
│ ├── baseline.scss
│ ├── border-radius.scss
│ ├── box-shadow.scss
│ ├── breakpoint.scss
│ ├── color.scss
│ ├── coordinate.scss
│ ├── duration.scss
│ ├── easing.scss
│ ├── flex-grid.scss
│ ├── font-family.scss
│ ├── font-size.scss
│ ├── font-weight.scss
│ ├── gradient.scss
│ ├── keyframe.scss
│ ├── letter-spacing.scss
│ ├── line-height.scss
│ ├── line-style.scss
│ ├── line-width.scss
│ ├── module.scss
│ ├── opacity.scss
│ ├── ratio.scss
│ ├── spacing.scss
│ ├── text-measure.scss
│ ├── text-shadow.scss
│ └── wrapper-width.scss
│ ├── set-default.scss
│ ├── set.scss
│ └── unset.scss
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | node_modules/
3 | sassdoc/
4 |
5 | .DS_Store
6 | .sass-cache
7 | *.css.map
8 |
9 | *.log
10 | pids
11 | *.pid
12 | *.seed
13 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - 'node'
5 | - 'lts/*'
6 |
7 | install:
8 | - npm install
9 |
10 | script:
11 | - npm test
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2018, Kyle Oliveiro
4 | All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | * Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | * Neither the name of Scarab nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
Scarab Core
4 |
Sass library for rapid stylesheet development
5 |
6 | Design token management · Responsive mixins · Helper functions
7 |
8 | [](https://www.npmjs.com/package/@scarab/core)
9 | [](https://travis-ci.org/kyleoliveiro/scarab-core)
10 |
11 | ---
12 |
13 | [💿 Installation](#installation) · [📚 Documentation](#documentation) · [⭐️ Features](#features) · [🍃 Ecosystem](#ecosystem)
14 |
15 | [🎉 Motivation](#motivation) · [❤️ Contributing](#contributing) · [📃️ License](#license)
16 |
17 |
18 | ---
19 |
20 | ## 💿 Installation
21 | 1. Install Scarab Core as a dev-dependency:
22 |
23 | ```bash
24 | # With yarn
25 | $ yarn add @scarab/core -D
26 |
27 | # Or with npm
28 | $ npm install @scarab/core --save-dev
29 | ```
30 |
31 | 2. Add `node_modules/` to your Sass [`includePaths`](https://github.com/sass/node-sass#includepaths).
32 |
33 | 3. Import the Scarab Core library before all other stylesheets:
34 |
35 | ```scss
36 | // Import the Scarab Library
37 | @import '@scarab/core/_';
38 |
39 | // Write your Sass here...
40 | ```
41 |
42 |
43 | ## 📚 Documentation
44 | API documentation and guides:
45 | [**https://scarab.style/core**](https://scarab.style/core)
46 |
47 | ## ⭐️ Features
48 |
49 | ### Design token management
50 |
51 | Design systems consist of reusable “tokens”. Each token has a name and a value associated with it. Constructing digital interfaces using only the values of tokens that are defined in a design system ensures visual consistency. Scarab provides a simple interface for managing design tokens.
52 |
53 | ### Helper functions
54 | Provides additional syntactic sugar on top of the default Sass functions.
55 |
56 |
57 | ### Responsive mixins
58 | Simplifies working with breakpoints and media queries.
59 |
60 | ## 🍃 Ecosystem
61 |
62 | In addition to the core library, the following packages are available in the Scarab ecosystem:
63 |
64 | | Package name | Description |
65 | | :-- | :-- |
66 | | [**Carapace**](https://github.com/kyleoliveiro/scarab-carapace.git) | CSS utility class generator |
67 | | [**Scarab CLI** (WIP)](https://github.com/kyleoliveiro/scarab-cli.git) | Command-line tools for the Scarab ecosystem |
68 | | [**Scarab snippets** (WIP)](https://github.com/kyleoliveiro/scarab-snippets.git) | Scarab snippets for your favorite text editors and IDE's |
69 |
70 | ## 🎉 Motivation
71 |
72 | ### Why another Sass library?
73 | Scarab is the resulting by-product of years of web development work. It's designed and built as a library to manage design tokens and to provide additional syntactic sugar for writing stylesheets.
74 |
75 | ### Why use Scarab?
76 |
77 | - Define design tokens in Sass (ideal since it's a styling language)
78 | - Use tokens in Sass with Scarab, and in HTML with Carapace
79 | - Ability to export design tokens from Sass to JSON
80 | - Written in Sass; No additional dependencies
81 | - Well tested with 100+ unit tests
82 | - Ecosystem of related packages
83 |
84 | ### Why not just use Sass variables?
85 | Using Sass variables to manage design tokens can be a viable solution for small projects. However, this approach has its limitations. For instance, in Sass, it's not possible to dynamically reference a variable by name. On the other hand, this becomes possible if tokens are stored in a Sass map instead of variables. This opens up many possibilities, and is the main impetus behind the Scarab library.
86 |
87 | ### Alternative libraries
88 | Other options are available, and you should pick one that caters to your project's requirements.
89 |
90 | - [Tailwind](https://tailwindcss.com/) — Generates CSS utility classes with short compile time. Requires PostCSS or Tailwind CLI.
91 | - [Tachyons](https://tachyons.io/) — Good for smaller sites that use native CSS variables (a.k.a. custom properties).
92 | - [BassCSS](http://basscss.com/) — Alternative to Tachyons. Also uses CSS variables.
93 | - [Vue DS](https://vueds.com) — Full-featured design system framework for Vue.
94 |
95 | ### ❤️ Contributing
96 | Issues and feature requests and PR's are welcome!
97 |
98 | ### 📃️ License
99 | Licensed under BSD 3-Clause. Copyright © Kyle Oliveiro 2018.
100 |
--------------------------------------------------------------------------------
/_.scss:
--------------------------------------------------------------------------------
1 | ////
2 | /// Scarab
3 | /// Stylesheet tokens management and useful functions for Sass.
4 | ///
5 | /// @author Kyle Oliveiro
6 | ////
7 |
8 | // Import the Scarab library
9 | @import 'lib/_';
10 |
--------------------------------------------------------------------------------
/lib/_.scss:
--------------------------------------------------------------------------------
1 | @import '_init';
2 |
3 | @import 'functions/_';
4 | @import 'mixins/_';
5 | @import 'options/_';
6 | @import 'constants/_';
7 | @import 'tokens/_';
8 |
--------------------------------------------------------------------------------
/lib/_init.scss:
--------------------------------------------------------------------------------
1 | /// Global variable where all user configuration is stored.
2 | ///
3 | /// Never modify this variable or its children directly. Instead, use:
4 | /// - `set-option()` / `option()` to manage options
5 | /// - `define()` / `const()` to manage constants
6 | /// - `set()` / `get()` to manage the tokens
7 | ///
8 | /// @access private
9 | /// @group 0_variables
10 | ///
11 | /// @type Map
12 | /// @prop {Map} OPTIONS - Contains Scarab options
13 | /// @prop {Map} CONSTANTS - Contains constant values
14 | /// @prop {Map} TOKENS - Contains the stylesheet tokens
15 |
16 | $__SCARAB: (
17 | 'CONSTANTS' : (),
18 | 'TOKENS' : (),
19 | 'OPTIONS' : ()
20 | );
21 |
--------------------------------------------------------------------------------
/lib/constants/_.scss:
--------------------------------------------------------------------------------
1 | ////
2 | /// Constants
3 | ///
4 | /// Helpers for managing constants.
5 | ////
6 |
7 | @import '_init';
8 |
9 | @import 'define';
10 | @import 'const';
11 |
--------------------------------------------------------------------------------
/lib/constants/const.scss:
--------------------------------------------------------------------------------
1 | /// Returns a value from the `CONSTANTS` map.
2 | ///
3 | /// @group 2_constants
4 | ///
5 | /// @requires {variable} __SCARAB
6 | /// @requires {function} to-string
7 | ///
8 | /// @param {ArgList} $path - Path to the key to retrieve the value from
9 | ///
10 | /// @return {*} - Value from the `CONSTANTS` map
11 | ///
12 | /// @example
13 | /// @debug const(MATH, LOG2E);
14 | /// // => 1.4426950408889634
15 | ///
16 | /// @debug const(CSS, MAX_Z_INDEX);
17 | /// // => 2147483647
18 | ///
19 | /// @debug const(INTERVAL, AUGMENTED_FOURTH);
20 | /// // => 1.414
21 |
22 | @function const($path...) {
23 | $result: map-get($__SCARAB, 'CONSTANTS');
24 |
25 | @each $key in $path {
26 | $result : map-get($result, to-string($key));
27 | }
28 |
29 | @return $result;
30 | }
31 |
--------------------------------------------------------------------------------
/lib/constants/define.scss:
--------------------------------------------------------------------------------
1 | /// Defines a new constant.
2 | ///
3 | /// Constants that already exist may not be re-defined.
4 | ///
5 | /// @group 2_constants
6 | ///
7 | /// @requires {variable} __SCARAB
8 | /// @requires {function} to-string
9 | /// @requires {function} map-stringify-keys-deep
10 | ///
11 | /// @param {ArgList} $definition - Definition of the new constant
12 | ///
13 | /// @return {ArgList} - Definition of the new constant
14 | ///
15 | /// @example
16 | /// $_: define(COMPANY, NAME, 'Acme Inc');
17 | ///
18 | /// @debug const(COMPANY, NAME);
19 | /// // => 'Acme Inc'
20 |
21 | @function define($definition...) {
22 | // Get a copy of the current $CONSTANTS state
23 | $CONSTANTS: map-get($__SCARAB, 'CONSTANTS');
24 |
25 | $result: (); // key-value pair that will be merged with $CONSTANTS
26 |
27 | // If there are only 2 args, we can easily determine the result
28 | @if length($definition) == 2 {
29 | $key : nth($definition, 1);
30 | $new-value : nth($definition, 2);
31 |
32 | // Check that the constant does not already exist
33 | @if not map-has-key($CONSTANTS, to-string($key)) {
34 | $result: ($key: $new-value);
35 | }
36 | }
37 |
38 | // For more than 2 args, we have to build the result backwards
39 | @if length($definition) > 2 {
40 |
41 | // The new value is the last arg in $definition
42 | $new-value: nth($definition, -1);
43 |
44 | // Build a list of maps preceding the new one
45 | $maps: ($CONSTANTS,);
46 |
47 | @for $i from 1 through length($definition) - 2 {
48 | $current-key : nth($definition, $i);
49 | $current-map : nth($maps, -1);
50 | $current-value : map-get($current-map, to-string($current-key)) or ();
51 |
52 | $maps: append($maps, $current-value);
53 | }
54 |
55 | @for $i from length($maps) through 1 {
56 | $current-map : nth($maps, $i);
57 | $current-key : nth($definition, $i);
58 | $current-value : map-get($current-map, to-string($current-key));
59 |
60 | @if $i == length($maps) {
61 | // Check that the constant does not already exist
62 | @if not map-has-key($current-map, to-string($current-key)) {
63 | $current-value: $new-value;
64 | }
65 | } @else {
66 | $current-value: $result;
67 | }
68 |
69 | $result: map-merge($current-map, (to-string($current-key): $current-value));
70 | }
71 | }
72 |
73 | // Update the local $CONSTANTS map
74 | $CONSTANTS: map-merge($CONSTANTS, map-stringify-keys-deep($result));
75 |
76 | // Merge the updated $CONSTANTS map back into $__SCARAB
77 | $__SCARAB: map-merge($__SCARAB, ('CONSTANTS': $CONSTANTS)) !global;
78 | @return $definition;
79 | }
80 |
81 |
82 |
83 | /// Calls `@function define()`.
84 | ///
85 | /// @group 2_constants
86 | ///
87 | /// @requires {function} define
88 | ///
89 | /// @param {ArgList} $args - Args for `define`
90 | ///
91 | /// @example
92 | /// @include define(COMPANY, NAME, 'Acme Inc');
93 | ///
94 | /// @debug const(COMPANY, NAME);
95 | /// // => 'Acme Inc'
96 |
97 | @mixin define($definition...) {
98 | $_: define($definition...);
99 | }
100 |
--------------------------------------------------------------------------------
/lib/functions/_.scss:
--------------------------------------------------------------------------------
1 | ////
2 | /// Functions
3 | ///
4 | /// Helper functions.
5 | ////
6 |
7 | @import 'throw';
8 | @import 'type-check';
9 | @import 'get-function-safe';
10 | @import 'important';
11 | @import 'is-null';
12 | @import 'to-string';
13 | @import 'to-length';
14 | @import 'to-number';
15 | @import 'to-negative';
16 | @import 'unit-strip';
17 | @import 'unit-convert';
18 | @import 'class-escape';
19 | @import 'class-sanitize';
20 | @import 'class-template';
21 | @import 'random-color';
22 | @import 'em';
23 | @import 'rem';
24 | @import 'str-compare';
25 | @import 'str-contains';
26 | @import 'str-replace';
27 | @import 'str-remove';
28 | @import 'str-escape';
29 | @import 'str-prepend';
30 | @import 'str-append';
31 | @import 'list-append';
32 | @import 'list-contains';
33 | @import 'list-each';
34 | @import 'list-prepend';
35 | @import 'list-remove';
36 | @import 'list-replace';
37 | @import 'list-reverse';
38 | @import 'list-sort';
39 | @import 'list-unique';
40 | @import 'list-every';
41 | @import 'map-append';
42 | @import 'map-prepend';
43 | @import 'map-get-key';
44 | @import 'map-flatten';
45 | @import 'map-stringify-keys';
46 | @import 'map-stringify-keys-deep';
47 | @import 'map-unique';
48 | @import 'map-each-key';
49 | @import 'map-each-value';
50 |
--------------------------------------------------------------------------------
/lib/functions/class-escape.scss:
--------------------------------------------------------------------------------
1 | /// Escapes a string for use as a CSS class name.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} const
6 | /// @requires {function} str-remove
7 | /// @requires {function} str-escape
8 | /// @requires {function} str-prepend
9 | /// @requires {function} list-contains
10 | ///
11 | /// @link https://mathiasbynens.be/notes/css-escapes Notes on CSS escapes
12 | ///
13 | /// @param {String} $class-name - The class name to escape
14 | ///
15 | /// @return {String} - Escaped string
16 | ///
17 | /// @example
18 | /// class-escape('blue')
19 | /// // => 'blue'
20 | ///
21 | /// class-escape('13lue')
22 | /// // => '\31 3lue'
23 | ///
24 | /// class-escape('@cl@ss:(1)')
25 | /// // => '\@cl\@ss\3A \(1\)'
26 |
27 | @function class-escape($class-name) {
28 | $result: $class-name;
29 | $first-char: str-slice($class-name, 1, 1);
30 |
31 | // Remove whitespace
32 | $result: str-remove($result, ' ', true);
33 |
34 | // Escape special characters
35 | $result: str-escape($result);
36 |
37 | // Unicode-escape the first character if it's a number
38 | @if list-contains(const(CHARSPACE, DECIMAL), $first-char) {
39 | $result: str-slice($result, 2); // Remove the first character
40 | $result: str-prepend($result, ' ', $first-char, '\\3');
41 | }
42 |
43 | @return $result;
44 | }
45 |
--------------------------------------------------------------------------------
/lib/functions/class-sanitize.scss:
--------------------------------------------------------------------------------
1 | /// Removes `selector-format` placeholders from a string.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} const
6 | /// @requires {function} str-remove
7 | ///
8 | /// @param {String} $class-name - Class name to sanitize
9 | ///
10 | /// @return {String} - Sanitized, unescaped class name
11 | ///
12 | /// @example
13 | /// class-sanitize('{{b}}{{bp}}{{s}}{{sp}}{{rp}}opacity{{rs}}{{vp}}{{v}}--75{{ms}}{{ss}}{{bs}}')
14 | /// // => 'opacity--75'
15 |
16 | @function class-sanitize($class-name) {
17 | $result: $class-name;
18 |
19 | $illegal-strings: const(SCARAB, SELECTOR_FORMAT_PLACEHOLDERS);
20 | @each $string in $illegal-strings {
21 | $result: str-remove($result, $string);
22 | }
23 |
24 | @return $result;
25 | }
26 |
--------------------------------------------------------------------------------
/lib/functions/class-template.scss:
--------------------------------------------------------------------------------
1 | /// Returns the result of hydrating the `selector-format` with given values.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} option
6 | /// @requires {function} module
7 | /// @requires {function} is-null
8 | /// @requires {function} str-remove
9 | /// @requires {function} str-replace
10 | ///
11 | /// @param {String|Map} $module - Module name, or map containing a `root` key, and optional `prefix` and `suffix` overrides.
12 | /// @param {String} $variant [''] - Class variant
13 | /// @param {String} $modifier [''] - Class modifier
14 | ///
15 | /// @return {String} - Templated, unescaped CSS class name
16 | ///
17 | /// @example
18 | /// class-template((
19 | /// root: 'margin'
20 | /// ), top, 0)
21 | /// // => 'margin-top:0'
22 | ///
23 | /// class-template((
24 | /// root: 'padding',
25 | /// variant-prefix: '',
26 | /// modifier-prefix: '--'
27 | /// ), top, 0)
28 | /// // => 'paddingtop--0'
29 |
30 | @function class-template($module, $variant: '', $modifier: '') {
31 | @if type-of($module) == 'string' {
32 | $module: module($module);
33 | }
34 |
35 | $variant: to-string($variant);
36 | $modifier: to-string($modifier);
37 |
38 | // Get module options
39 | $root: map-get($module, 'root');
40 |
41 | $selector-format : if(map-has-key($module, 'selector-format'),
42 | map-get($module, 'selector-format'),
43 | option(namescheme, selector-format)
44 | );
45 |
46 | $root-prefix : if(map-has-key($module, 'root-prefix'),
47 | map-get($module, 'root-prefix'),
48 | option(namescheme, root-prefix)
49 | );
50 |
51 | $root-suffix : if(map-has-key($module, 'root-suffix'),
52 | map-get($module, 'root-suffix'),
53 | option(namescheme, root-suffix)
54 | );
55 |
56 | $variant-prefix : if(map-has-key($module, 'variant-prefix'),
57 | map-get($module, 'variant-prefix'),
58 | option(namescheme, variant-prefix)
59 | );
60 |
61 | $variant-suffix : if(map-has-key($module, 'variant-suffix'),
62 | map-get($module, 'variant-suffix'),
63 | option(namescheme, variant-suffix)
64 | );
65 |
66 | $modifier-prefix : if(map-has-key($module, 'modifier-prefix'),
67 | map-get($module, 'modifier-prefix'),
68 | option(namescheme, modifier-prefix)
69 | );
70 |
71 | $modifier-suffix : if(map-has-key($module, 'modifier-suffix'),
72 | map-get($module, 'modifier-suffix'),
73 | option(namescheme, modifier-suffix)
74 | );
75 |
76 | $result: $selector-format;
77 | $template-schema: (
78 | 'r': (
79 | 'value' : $root,
80 | 'prefix' : $root-prefix,
81 | 'suffix' : $root-suffix
82 | ),
83 | 'v': (
84 | 'value' : $variant,
85 | 'prefix' : $variant-prefix,
86 | 'suffix' : $variant-suffix
87 | ),
88 | 'm': (
89 | 'value' : $modifier,
90 | 'prefix' : $modifier-prefix,
91 | 'suffix' : $modifier-suffix
92 | )
93 | );
94 |
95 | // Replace template placeholders with actual values
96 | @each $key, $map in $template-schema {
97 | $value : map-get($map, value);
98 | $prefix : map-get($map, prefix);
99 | $suffix : map-get($map, suffix);
100 |
101 | // Dynamically generate the template placeholders
102 | $p: '{{' + $key + '}}';
103 | $pp: '{{' + $key + 'p' + '}}';
104 | $ps: '{{' + $key + 's' + '}}';
105 |
106 | @if not is-null($value) and str-length($value) > 0 {
107 | $result: str-replace($result, $p, $value);
108 | $result: str-replace($result, $pp, $prefix);
109 | $result: str-replace($result, $ps, $suffix);
110 | } @else {
111 | $result: str-remove($result, $p);
112 | $result: str-remove($result, $pp);
113 | $result: str-remove($result, $ps);
114 | }
115 | }
116 |
117 | @return $result;
118 | }
119 |
--------------------------------------------------------------------------------
/lib/functions/em.scss:
--------------------------------------------------------------------------------
1 | /// Converts `px` to `em`.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} unit-strip
6 | ///
7 | /// @param {Number} $value - Value (in px) to convert
8 | /// @param {Number} $base-font-size [16] - Value of the base font size (in px)
9 | ///
10 | /// @return {Number} - `$value` in `em` units
11 | ///
12 | /// @example
13 | /// em(32)
14 | /// // => 2em
15 |
16 | @function em($value, $base-font-size: 16) {
17 | $result: $value / unit-strip($base-font-size) * 1em;
18 | @return $result;
19 | }
20 |
--------------------------------------------------------------------------------
/lib/functions/get-function-safe.scss:
--------------------------------------------------------------------------------
1 | /// Safely calls native `get-function()`. Intended for use with natice `call()`.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} to-string
6 | ///
7 | /// @param {String} $function-name - Function name to call
8 | ///
9 | /// @return {Function|String} - Depending on Sass version
10 | ///
11 | /// @example
12 | /// call(get-function-safe('str-length'), 'hello world')
13 | /// // => 11
14 |
15 | @function get-function-safe($function-name) {
16 | $function-name: to-string($function-name);
17 |
18 | $result: if(function-exists('get-function'),
19 | get-function($function-name),
20 | $function-name
21 | );
22 |
23 | @return $result;
24 | }
25 |
--------------------------------------------------------------------------------
/lib/functions/important.scss:
--------------------------------------------------------------------------------
1 | /// Returns `!important` or an empty string.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {Bool} $output [option(output, important)] - Whether to output `!important`
6 | ///
7 | /// @return {String}
8 | ///
9 | /// @example
10 | /// important()
11 | /// // => !important
12 |
13 | @function important($output: option(output, important)) {
14 | $result: if($output, !important, null);
15 | @return $result;
16 | }
17 |
--------------------------------------------------------------------------------
/lib/functions/is-null.scss:
--------------------------------------------------------------------------------
1 | /// Checks if the specified value is `null`.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {*} $value - Value to evaluate
6 | ///
7 | /// @return {Boolean} - Whether `$value` is `null`
8 | ///
9 | /// @example
10 | /// is-null(null)
11 | /// // => true
12 | ///
13 | /// is-null(false)
14 | /// // => false
15 | ///
16 | /// is-null('')
17 | /// // => false
18 | ///
19 | /// is-null(0)
20 | /// // => false
21 |
22 | @function is-null($value) {
23 | $result: if(type-of($value) == 'null', true, false);
24 | @return $result;
25 | }
26 |
--------------------------------------------------------------------------------
/lib/functions/list-append.scss:
--------------------------------------------------------------------------------
1 | /// Adds values to the end of a list.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {List} $list - List to append to
6 | /// @param {ArgList} $values - Value(s) to be appended
7 | ///
8 | /// @return {List} - New list appended with `$values`
9 | ///
10 | /// @example
11 | /// list-append((1 2), 3)
12 | /// // => 1 2 3
13 | ///
14 | /// list-append((1 2), 3, 4, 5)
15 | /// // => 1 2 3 4 5
16 |
17 | @function list-append($list, $values...) {
18 | $result: $list;
19 |
20 | @each $value in $values {
21 | $result: append($result, $value);
22 | }
23 |
24 | @return $result;
25 | }
26 |
--------------------------------------------------------------------------------
/lib/functions/list-contains.scss:
--------------------------------------------------------------------------------
1 | /// Checks if a list contains the specified value.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {List} $list - List to search
6 | /// @param {*} $value - Value to search for
7 | ///
8 | /// @return {Bool} - Whether `$list` contains `$value`
9 | ///
10 | /// @example
11 | /// list-contains((1, 2, 3), 2)
12 | /// // => true
13 | ///
14 | /// list-contains((1, 2, 3), 4)
15 | /// // => false
16 |
17 | @function list-contains($list, $value) {
18 | $result: if(index($list, $value), true, false);
19 | @return $result;
20 | }
21 |
--------------------------------------------------------------------------------
/lib/functions/list-each.scss:
--------------------------------------------------------------------------------
1 | /// Calls a function on each item in a list.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} get-function-safe
6 | ///
7 | /// @param {List} $list - List to operate on
8 | /// @param {String} $function-name - Name of the function to call on each item
9 | /// @param {List} $args [()] - List of args to pass to the function
10 | ///
11 | /// @return {List} - New list with modified values
12 | ///
13 | /// @example
14 | /// list-each((1.2, 2.5, 3.7), 'round')
15 | /// // => (1, 3, 4)
16 | ///
17 | /// list-each(('hello', 'world'), 'str-insert', ('123', 1))
18 | /// // => ('123hello', '123world')
19 |
20 | @function list-each($list, $function-name, $args: ()) {
21 | $separator : list-separator($list);
22 | $bracketed : is-bracketed($list);
23 |
24 | $result: ();
25 |
26 | // Apply the transformation to each item in $list
27 | // and push the results into a new list
28 | @each $item in $list {
29 | $item: call(get-function-safe($function-name), $item, $args...);
30 | $result: append($result, $item);
31 | }
32 |
33 | // Preserve list seperator and brackets
34 | $result: join($result, (), $separator, $bracketed);
35 | @return $result;
36 | }
37 |
--------------------------------------------------------------------------------
/lib/functions/list-every.scss:
--------------------------------------------------------------------------------
1 | /// Checks if the result of calling a given function on every item in a list is true.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} get-function-safe
6 | ///
7 | /// @param {List} $list - List to operate on
8 | /// @param {String} $function-name - Name of the function to call
9 | /// @param {List} $args [()] - List of args to pass to the function
10 | ///
11 | /// @return {Bool} - Whether the result of every item returned `true`
12 | ///
13 | /// @example
14 | /// list-every((1, 2, 3), 'unitless')
15 | /// // => true
16 | ///
17 | /// list-every((1, 2px, 3), 'unitless')
18 | /// // => false
19 |
20 | @function list-every($list, $function-name, $args: ()) {
21 | @each $item in $list {
22 | @if not call(get-function-safe($function-name), $item, $args...) {
23 | @return false;
24 | }
25 | }
26 |
27 | @return true;
28 | }
29 |
--------------------------------------------------------------------------------
/lib/functions/list-prepend.scss:
--------------------------------------------------------------------------------
1 | /// Adds values to the start of a list.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {List} $list - List to prepend to
6 | /// @param {ArgList} $values - Value(s) to be prepended
7 | ///
8 | /// @return {List} - New list prepended with `$values`
9 | ///
10 | /// @example
11 | /// list-prepend((1 2), 3)
12 | /// // => 3 1 2
13 | ///
14 | /// list-prepend((1 2), 3, 4, 5)
15 | /// // => 3 4 5 1 2
16 |
17 | @function list-prepend($list, $values...) {
18 | $separator : list-separator($list);
19 | $bracketed : is-bracketed($list);
20 |
21 | $result: $list;
22 |
23 | @each $value in $values {
24 | $result: join(($value,), $result);
25 | }
26 |
27 | // Preserve list seperator and brackets
28 | $result: join((), $result, $separator, $bracketed);
29 | @return $result;
30 | }
31 |
--------------------------------------------------------------------------------
/lib/functions/list-remove.scss:
--------------------------------------------------------------------------------
1 | /// Finds and removes a value in a list.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {List} $list - List to search
6 | /// @param {*} $search - Value to remove
7 | /// @param {Bool} $all [false] - Whether to remove all occurrances of the value
8 | ///
9 | /// @return {List} - New list with value(s) removed
10 | ///
11 | /// @example
12 | /// list-remove(1 2 3 1 2 3, 2)
13 | /// // => (1 3 1 2 3)
14 | ///
15 | /// list-remove(1 2 3 1 2 3, 2, true)
16 | /// // => (1 3 1 3)
17 |
18 | @function list-remove($list, $search, $all: false) {
19 | $separator : list-separator($list);
20 | $bracketed : is-bracketed($list);
21 |
22 | $result: ();
23 |
24 | // Remove the first instance of $search
25 | $first-search-index: index($list, $search);
26 | $i: 0;
27 |
28 | @each $item in $list {
29 | $i: $i + 1;
30 | @if $i != $first-search-index {
31 | $result: append($result, $item);
32 | }
33 | }
34 |
35 | @if $all == true {
36 | // Remove all remanining instances of $search
37 | @while not not index($result, $search) {
38 | $result: list-remove($result, $search);
39 | }
40 | }
41 |
42 | // Preserve list seperator and brackets
43 | $result: join($result, (), $separator, $bracketed);
44 |
45 | @return $result;
46 | }
47 |
--------------------------------------------------------------------------------
/lib/functions/list-replace.scss:
--------------------------------------------------------------------------------
1 | /// Finds and replaces a value in a list.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {List} $list - List to search
6 | /// @param {*} $search - Value search for
7 | /// @param {*} $replace - Replacement value
8 | /// @param {Bool} $all [false] - Whether to replace all occurrances of the value
9 | ///
10 | /// @return {List} - New list with value(s) replaced
11 | ///
12 | /// @example
13 | /// list-replace((1 2 3), 2)
14 | /// // => (1 2)
15 | ///
16 | /// list-replace((1 2 2 2 3), 2, 4)
17 | /// // => (1 4 2 2 3)
18 | ///
19 | /// list-replace((1 2 2 2 3), 2, 4, true)
20 | /// // => (1 4 4 4 3)
21 |
22 | @function list-replace($list, $search, $replace, $all: false) {
23 | // Replace the first instance of $search
24 | $result: set-nth($list, index($list, $search), $replace);
25 |
26 | @if $all == true {
27 | // Replace all remanining instances of $search
28 | @while not not index($result, $search) {
29 | $result: list-replace($result, $search, $replace);
30 | }
31 | }
32 |
33 | @return $result;
34 | }
35 |
--------------------------------------------------------------------------------
/lib/functions/list-reverse.scss:
--------------------------------------------------------------------------------
1 | /// Reverses the order of values in a list.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} to-negative
6 | ///
7 | /// @param {List} $list - List to reverse
8 | ///
9 | /// @return {List} - New list with reversed order
10 | ///
11 | /// @example
12 | /// list-reverse(1, a, 3)
13 | /// // => (3, a, 1)
14 |
15 | @function list-reverse($list) {
16 | $separator : list-separator($list);
17 | $bracketed : is-bracketed($list);
18 |
19 | $result: ();
20 |
21 | @for $i from to-negative(length($list)) through -1 {
22 | $result: append($result, nth($list, abs($i)));
23 | }
24 |
25 | // Preserve list seperator and brackets
26 | $result: join($result, (), $separator, $bracketed);
27 |
28 | @return $result;
29 | }
30 |
--------------------------------------------------------------------------------
/lib/functions/list-sort.scss:
--------------------------------------------------------------------------------
1 | /// Sorts items in a list.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} const
6 | /// @requires {function} str-compare
7 | ///
8 | /// @param {List} $list - List to sort
9 | /// @param {List} $order [const(CHARSPACE, SORT_ORDER)] - Sort order
10 | ///
11 | /// @return {List} - New list with sorted items
12 | ///
13 | /// @example
14 | /// list-sort(b c a)
15 | /// // => (a b c)
16 | ///
17 | /// list-sort(b c a, (c, b, a))
18 | /// // => (c b a)
19 |
20 | @function list-sort($list, $order: const(CHARSPACE, SORT_ORDER)) {
21 | $separator : list-separator($list);
22 | $bracketed : is-bracketed($list);
23 | $less : ();
24 | $equal : ();
25 | $large : ();
26 |
27 | $result: join($list, (), 'comma', false);
28 |
29 | @if length($list) > 1 {
30 | $seed: nth($list, ceil(length($list) / 2));
31 |
32 | @each $item in $list {
33 | @if $item == $seed {
34 | $equal: append($equal, $item);
35 | } @else if str-compare($item, $seed, $order) {
36 | $less: append($less, $item);
37 | } @else if not str-compare($item, $seed, $order) {
38 | $large: append($large, $item);
39 | }
40 | }
41 |
42 | $result: join(join(list-sort($less, $order), $equal), list-sort($large, $order));
43 | }
44 |
45 | $result: join($result, (), $separator, $bracketed);
46 | @return $result;
47 | }
48 |
--------------------------------------------------------------------------------
/lib/functions/list-unique.scss:
--------------------------------------------------------------------------------
1 | /// Removes duplicate values from a list.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {List} $list - List to remove duplicates from
6 | ///
7 | /// @return {List} - List with duplicates items removed
8 | ///
9 | /// @example
10 | /// list-unique((a, b, c, a, a, c))
11 | /// // => (a, b, c);
12 |
13 | @function list-unique($list) {
14 | $separator : list-separator($list);
15 | $bracketed : is-bracketed($list);
16 |
17 | $result: ();
18 |
19 | @each $item in $list {
20 | @if not index($result, $item) {
21 | $result: append($result, $item);
22 | }
23 | }
24 |
25 | // Preserve list seperator and brackets
26 | $result: join($result, (), $separator, $bracketed);
27 |
28 | @return $result;
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/lib/functions/map-append.scss:
--------------------------------------------------------------------------------
1 | /// Adds a single key-value pair onto the end of a map.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {Map} $map - Map to append to
6 | /// @param {*} $key - Key to be appended
7 | /// @param {*} $value - Value to be appended
8 | ///
9 | /// @return {Map} - New map appended with key-value pair
10 | ///
11 | /// @example
12 | /// map-append((a: 1, b: 2), c, 3)
13 | /// // => (a: 1, b: 2, c: 3)
14 |
15 | @function map-append($map, $key, $value) {
16 | $result: map-merge($map, ($key: $value));
17 | @return $result;
18 | }
19 |
--------------------------------------------------------------------------------
/lib/functions/map-each-key.scss:
--------------------------------------------------------------------------------
1 | /// Calls a function on each key in a map.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} get-function-safe
6 | ///
7 | /// @param {Map} $map - Map to operate on
8 | /// @param {String} $function-name - Name of the function to call
9 | /// @param {List} $args [()] - List of args to pass to the function
10 | ///
11 | /// @return {Map} - New map with modified keys
12 | ///
13 | /// @example
14 | /// map-each-key((1.1: a, 2.5: b, 3.6: c), 'round')
15 | /// // => (1: a, 3: b, 4: c)
16 | ///
17 | /// map-each-key(('apple': 1, 'orange': 2), 'str-replace', ('a', '4'))
18 | /// // => ('4pple': 1, 'or4nge': 2)
19 |
20 | @function map-each-key($map, $function-name, $args: ()) {
21 | $result: ();
22 |
23 | @each $key, $value in $map {
24 | $key: call(get-function-safe($function-name), $key, $args...);
25 | $result: map-merge($result, ($key: $value));
26 | }
27 |
28 | @return $result;
29 | }
30 |
--------------------------------------------------------------------------------
/lib/functions/map-each-value.scss:
--------------------------------------------------------------------------------
1 | /// Calls a function on each value in a map.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} get-function-safe
6 | ///
7 | /// @param {Map} $map - Map to operate on
8 | /// @param {String} $function-name - Name of the function to call
9 | /// @param {List} $args [()] - List of args to pass to the function
10 | ///
11 | /// @return {Map} - New map with modified values
12 | ///
13 | /// @example
14 | /// map-each-value((a: 1.1, b: 2.5, c: 3.6), 'round')
15 | /// // => (a: 1, b: 3, c: 4)
16 | ///
17 | /// map-each-value((a: 'apple', b: 'orange'), 'str-replace', ('a', '4'))
18 | /// // => (a: '4pple', b: 'or4nge')
19 |
20 | @function map-each-value($map, $function-name, $args: ()) {
21 | $result: ();
22 |
23 | @each $key, $value in $map {
24 | $value: call(get-function-safe($function-name), $value, $args...);
25 | $result: map-merge($result, ($key: $value));
26 | }
27 |
28 | @return $result;
29 | }
30 |
--------------------------------------------------------------------------------
/lib/functions/map-flatten.scss:
--------------------------------------------------------------------------------
1 | /// Flattens a map one-level deep.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} option
6 | /// @requires {function} map-append
7 | ///
8 | /// @param {Map} $map - Map to operate on
9 | /// @param {String} $separator [option(namescheme, variant-prefix)] - Separator to use for flattened key names
10 | ///
11 | /// @return {Map} - New flattened map
12 | ///
13 | /// @example
14 | /// map-flatten(('cyan': ('1': #00ffff, '2': #00aaaa)), '-')
15 | /// // => ('cyan-1': #00ffff, 'cyan-2': #00aaaa)
16 |
17 | @function map-flatten($map, $separator: option(namescheme, variant-prefix)) {
18 | $result: ();
19 |
20 | @each $key, $val in $map {
21 | @if type-of($val) == 'map' {
22 | $_result: ();
23 | @each $k, $v in $val {
24 | @if $k == option(namescheme, default-key) {
25 | $_result: map-append($_result, $key, $v);
26 | } @else {
27 | $_result: map-append($_result, #{$key}#{$separator}#{$k}, $v);
28 | }
29 | }
30 |
31 | $result: map-merge($result, $_result);
32 | } @else {
33 | $result: map-append($result, $key, $val);
34 | }
35 | }
36 |
37 | @return $result;
38 | }
39 |
--------------------------------------------------------------------------------
/lib/functions/map-get-key.scss:
--------------------------------------------------------------------------------
1 | /// Returns the key(s) in a map associated with a given value.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {Map} $map - Map to operate on
6 | /// @param {*} $search - Value to search for
7 | ///
8 | /// @return {List} - List containing keys with values that match $search
9 | ///
10 | /// @example
11 | /// map-get-key((a: 1, b: 2, c: 3), 2)
12 | /// // => (b)
13 | ///
14 | /// map-get-key((a: 1, b: 2, c: 2), 2)
15 | /// // => (b, c)
16 |
17 | @function map-get-key($map, $search) {
18 | $result: ();
19 |
20 | $keys: map-keys($map);
21 | $values: map-values($map);
22 |
23 | @for $i from 1 through length($values) {
24 | @if nth($values, $i) == $search {
25 | $result: list-append($result, nth($keys, $i));
26 | }
27 | }
28 |
29 | // Convert result to comma list
30 | $result: join($result, (), 'comma');
31 |
32 | @return $result;
33 | }
34 |
--------------------------------------------------------------------------------
/lib/functions/map-prepend.scss:
--------------------------------------------------------------------------------
1 | /// Adds a single key-value pair onto the start of a map.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {Map} $map - Map to prepend to
6 | /// @param {*} $key - Key to be prepended
7 | /// @param {*} $value - Value to be prepended
8 | ///
9 | /// @return {Map} - New map prepended with key-value pair
10 | ///
11 | /// @example
12 | /// map-prepend((a: 1, b: 2), c, 3)
13 | /// // => (c: 3, a: 1, b: 2)
14 |
15 | @function map-prepend($map, $key, $value) {
16 | $result: map-merge(($key: $value), $map);
17 | @return $result;
18 | }
19 |
--------------------------------------------------------------------------------
/lib/functions/map-stringify-keys-deep.scss:
--------------------------------------------------------------------------------
1 | /// Converts all keys in a map to strings, including keys of nested maps.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} map-stringify-keys
6 | ///
7 | /// @param {Map} $map - Map to stringify
8 | ///
9 | /// @return {Map} - New map with all keys converted to strings
10 | ///
11 | /// @example
12 | /// $map: (
13 | /// 1: 1,
14 | /// hello: 2,
15 | /// red: 3,
16 | /// map: (
17 | /// 1: 1,
18 | /// blue: 2
19 | /// )
20 | /// );
21 | ///
22 | /// @each $key, $val in $map {
23 | /// @debug type-of($key);
24 | ///
25 | /// @if type-of($val) == 'map' {
26 | /// @each $k, $v in $val {
27 | /// @debug type-of($v);
28 | /// }
29 | /// }
30 | /// }
31 | ///
32 | /// // DEBUG: number
33 | /// // DEBUG: string
34 | /// // DEBUG: color
35 | /// // DEBUG: string
36 | /// // DEBUG: number
37 | /// // DEBUG: color
38 | ///
39 | /// $stringified-map: stringify-keys($map);
40 | ///
41 | /// @each $key, $val in $stringified-map {
42 | /// @debug type-of($key);
43 | /// }
44 | ///
45 | /// // DEBUG: string
46 | /// // DEBUG: string
47 | /// // DEBUG: string
48 | /// // DEBUG: string
49 | /// // DEBUG: string
50 | /// // DEBUG: string
51 |
52 | @function map-stringify-keys-deep($map) {
53 | $result: map-stringify-keys($map);
54 |
55 | @each $key, $val in $map {
56 | @if type-of($val) == 'map' {
57 | $val: map-stringify-keys-deep($val);
58 | $result: map-merge($result, map-stringify-keys(($key: $val)));
59 | }
60 | }
61 |
62 | @return $result;
63 | }
64 |
--------------------------------------------------------------------------------
/lib/functions/map-stringify-keys.scss:
--------------------------------------------------------------------------------
1 | /// Converts direct keys of a map to strings.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} to-string
6 | ///
7 | /// @param {Map} $map - Map to stringify
8 | ///
9 | /// @return {Map} - New map with direct keys converted to strings
10 | ///
11 | /// @example
12 | /// $map: (
13 | /// 1: 1,
14 | /// hello: 2,
15 | /// red: 3,
16 | /// map: (
17 | /// 1: 1,
18 | /// blue: 2
19 | /// )
20 | /// );
21 | ///
22 | /// @each $key, $val in $map {
23 | /// @debug type-of($key);
24 | ///
25 | /// @if type-of($val) == 'map' {
26 | /// @each $k, $v in $val {
27 | /// @debug type-of($v);
28 | /// }
29 | /// }
30 | /// }
31 | ///
32 | /// // DEBUG: number
33 | /// // DEBUG: string
34 | /// // DEBUG: color
35 | /// // DEBUG: string
36 | /// // DEBUG: number
37 | /// // DEBUG: color
38 | ///
39 | /// $stringified-map: stringify-keys($map);
40 | ///
41 | /// @each $key, $val in $stringified-map {
42 | /// @debug type-of($key);
43 | /// }
44 | ///
45 | /// // DEBUG: string
46 | /// // DEBUG: string
47 | /// // DEBUG: string
48 | /// // DEBUG: string
49 | /// // DEBUG: number
50 | /// // DEBUG: color
51 |
52 | @function map-stringify-keys($map) {
53 | $result: ();
54 |
55 | @each $key, $value in $map {
56 | $key: quote(to-string($key));
57 | $result: map-merge($result, ($key: $value));
58 | }
59 |
60 | @return $result;
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/lib/functions/map-unique.scss:
--------------------------------------------------------------------------------
1 | /// Removes key-value pairs from a map which contain duplicate values.
2 | ///
3 | /// If a map contains key-value pairs with multiple values,
4 | /// the first key in the map is retained, and duplicates are removed.
5 | ///
6 | /// @group 5_functions
7 | ///
8 | /// @param {Map} $map - Map to remove duplicates from
9 | ///
10 | /// @return {Map} - New map with duplicates removed
11 | ///
12 | /// @example
13 | /// map-unique((
14 | /// blue: #0000ff,
15 | /// red: #ff0000,
16 | /// green: #00ff00,
17 | /// brand: #0000ff
18 | /// ));
19 | /// // => (
20 | /// // blue: #0000ff,
21 | /// // red: #ff0000,
22 | /// // green: #00ff00
23 | /// // );
24 |
25 | @function map-unique($map) {
26 | $indices : ();
27 | $values : map-values($map);
28 |
29 | $result: ();
30 |
31 | @each $value in $values {
32 | $indices: append($indices, index($values, $value));
33 | }
34 |
35 | $last-index: 0;
36 | @each $index in $indices {
37 | @if $index > $last-index {
38 | $result: map-merge($result, (
39 | nth(nth($map, $index), 1): nth(nth($map, $index), 2)
40 | ));
41 | }
42 |
43 | $last-index: $index;
44 | }
45 |
46 | @return $result;
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/lib/functions/random-color.scss:
--------------------------------------------------------------------------------
1 | /// Returns a random color.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @return {Color} - Random color
6 | ///
7 | /// @example
8 | /// type-of(random-color())
9 | /// // => 'color'
10 |
11 | @function random-color() {
12 | $result: rgb(random(255), random(255), random(255));
13 | @return $result;
14 | }
15 |
--------------------------------------------------------------------------------
/lib/functions/rem.scss:
--------------------------------------------------------------------------------
1 | /// Converts `px` to `rem`.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} unit-strip
6 | ///
7 | /// @param {Number} $value - Value (in px) to convert
8 | /// @param {Number} $base-font-size [16] - Value of the base font size (in px)
9 | ///
10 | /// @return {Number} - `$value` in `rem` units
11 | ///
12 | /// @example
13 | /// rem(32)
14 | /// // => 2rem
15 |
16 | @function rem($value, $base-font-size: 16) {
17 | $result: $value / unit-strip($base-font-size) * 1rem;
18 | @return $result;
19 | }
20 |
--------------------------------------------------------------------------------
/lib/functions/str-append.scss:
--------------------------------------------------------------------------------
1 | /// Appends to a string.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} is-null
6 | ///
7 | /// @param {String} $string - String to append to
8 | /// @param {ArgList} $strings - String(s) to be appended
9 | ///
10 | /// @return {String}
11 | ///
12 | /// @example
13 | /// str-append('hello', 'world')
14 | /// // => 'helloworld'
15 | ///
16 | /// str-append('hello', ' ', 'world')
17 | /// // => 'hello world'
18 |
19 | @function str-append($string, $strings...) {
20 | $result: $string;
21 |
22 | @each $str in $strings {
23 | $str: if(is-null($str), '', $str);
24 | $result: $result + $str;
25 | }
26 |
27 | @return $result;
28 | }
29 |
--------------------------------------------------------------------------------
/lib/functions/str-compare.scss:
--------------------------------------------------------------------------------
1 | /// Compares two strings or numbers to determine which comes first.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} const
6 | /// @requires {function} to-string
7 | ///
8 | /// @param {String|Number} $a - First string
9 | /// @param {String|Number} $b - Second string
10 | /// @param {List} $order [const(CHARSPACE, SORT_ORDER)] - Sort order
11 | ///
12 | /// @return {Bool} - Whether $a comes before $b in the given $order
13 | ///
14 | /// @example
15 | /// str-compare('a', 'b')
16 | /// // => true
17 | ///
18 | /// str-compare(2, 1)
19 | /// // => false
20 |
21 | @function str-compare($a, $b, $order: const(CHARSPACE, SORT_ORDER)) {
22 | @if type-of($a) == "number" and type-of($b) == "number" {
23 | @return $a < $b;
24 | }
25 |
26 | $a : to-lower-case(to-string($a));
27 | $b : to-lower-case(to-string($b));
28 |
29 | @for $i from 1 through min(str-length($a), str-length($b)) {
30 | $char-a: str-slice($a, $i, $i);
31 | $char-b: str-slice($b, $i, $i);
32 |
33 | @if $char-a and $char-b and index($order, $char-a) != index($order, $char-b) {
34 | @return index($order, $char-a) < index($order, $char-b);
35 | }
36 | }
37 |
38 | @return str-length($a) < str-length($b);
39 | }
40 |
--------------------------------------------------------------------------------
/lib/functions/str-contains.scss:
--------------------------------------------------------------------------------
1 | /// Checks if a string contains a substring.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} is-null
6 | ///
7 | /// @param {String} $string - String to search in
8 | /// @param {String} $substring - Substring to search for
9 | ///
10 | /// @return {Bool} - Whether `$string` contains `$substring`
11 | ///
12 | /// @example
13 | /// str-contains('team', 'i')
14 | /// // => false
15 | ///
16 | /// str-contains('hello', 'hell')
17 | /// // => true
18 |
19 | @function str-contains($string, $substring) {
20 | $result: if(is-null(str-index($string, $substring)), false, true);
21 | @return $result;
22 | }
23 |
--------------------------------------------------------------------------------
/lib/functions/str-escape.scss:
--------------------------------------------------------------------------------
1 | /// Escapes CSS special characters within a string.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} const
6 | /// @requires {function} str-replace
7 | /// @requires {function} list-contains
8 | ///
9 | /// @link https://mathiasbynens.be/notes/css-escapes Notes on CSS escapes
10 | ///
11 | /// @param {String} $string - String to escape
12 | ///
13 | /// @return {String}
14 | ///
15 | /// @example
16 | /// str-escape('_a:b!😀(b)c-d@')
17 | /// // => '_a\3A b\!😀\(b\)c\-d\@'
18 |
19 | @function str-escape($string) {
20 | $result: $string;
21 | $count: 0;
22 |
23 | @for $i from 1 through str-length($string) {
24 | $char: str-slice($string, $i, $i);
25 |
26 | // Escape special characters with a backslash.
27 | // Although recommended, we do not escape colon `:` as `\3A `,
28 | // because this causes problems when using Webpack.
29 | @if list-contains(const(CSS, SPECIAL_CHARS), $char) {
30 | $result: str-insert($result, '\\', ($i + $count));
31 | $count: $count + 1;
32 | }
33 | }
34 |
35 | @return $result;
36 | }
37 |
--------------------------------------------------------------------------------
/lib/functions/str-prepend.scss:
--------------------------------------------------------------------------------
1 | /// Prepends to a string.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {String} $string - String to prepend to
6 | /// @param {ArgList} $strings - String(s) to be prepended
7 | ///
8 | /// @return {String}
9 | ///
10 | /// @example
11 | /// str-prepend('hello', 'world')
12 | /// // => 'worldhello'
13 | ///
14 | /// str-prepend('hello', ' ', 'world')
15 | /// // => 'world hello'
16 |
17 | @function str-prepend($string, $strings...) {
18 | $result: $string;
19 |
20 | @each $string in $strings {
21 | $result: $string + $result;
22 | }
23 |
24 | @return $result;
25 | }
26 |
--------------------------------------------------------------------------------
/lib/functions/str-remove.scss:
--------------------------------------------------------------------------------
1 | /// Removes a substring within a string.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} str-replace
6 | ///
7 | /// @param {String} $string - String to search in
8 | /// @param {String} $search - Substring to search for
9 | /// @param {Boolean} $all [false] - Whether to remove all occurances
10 | ///
11 | /// @return {String}
12 | ///
13 | /// @example
14 | /// str-remove('Beetle', 'e')
15 | /// // => Betle
16 | ///
17 | /// str-remove('Beetle', 'e', true)
18 | /// // => Btl
19 |
20 | @function str-remove($string, $search, $all: false) {
21 | $result: $string;
22 | $index: str-index($string, $search);
23 |
24 | @if $index {
25 | $result: str-replace($string, $search, '', $all);
26 | }
27 |
28 | @return $result;
29 | }
30 |
--------------------------------------------------------------------------------
/lib/functions/str-replace.scss:
--------------------------------------------------------------------------------
1 | /// Replaces a substring within a string.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} str-append
6 | /// @requires {function} str-remove
7 | /// @requires {function} str-contains
8 | /// @requires {function} list-append
9 | ///
10 | /// @param {String} $string - String to search in
11 | /// @param {String} $search - Substring to search for
12 | /// @param {String} $replace [''] - Replacement string
13 | /// @param {Boolean} $all [false] - Whether to replace all occurances
14 | ///
15 | /// @return {String}
16 | ///
17 | /// @example
18 | /// str-replace($string, 'e', '3')
19 | /// // => B3etle
20 | ///
21 | /// str-replace($string, 'e', '3', true)
22 | /// // => B33tl3
23 | ///
24 | /// str-replace($string, 'e', true)
25 | /// // => Btl
26 |
27 | @function str-replace($string, $search, $replace: '', $all: false) {
28 | $result: $string;
29 | $first-index: str-index($string, $search);
30 |
31 | @if $first-index {
32 | @if not $all {
33 | // Replace the first occurance
34 | $result: str-append(
35 | str-slice($string, 1, ($first-index - 1)),
36 | $replace,
37 | str-slice($string, $first-index + str-length($search))
38 | );
39 | } @else {
40 | $indexes: [];
41 | $occurances: 0;
42 | $_string: $string;
43 |
44 | @while str-contains($_string, $search) {
45 | $index: str-index($_string, $search) + ($occurances * str-length($replace));
46 | $indexes: list-append($indexes, $index);
47 | $_string: str-remove($_string, $search);
48 | $occurances: $occurances + 1;
49 | }
50 |
51 | @each $index in $indexes {
52 | // Remove $search at $index
53 | $result: str-append(
54 | str-slice($result, 1, $index - 1),
55 | str-slice($result, ($index + str-length($search)))
56 | );
57 |
58 | // Insert $replace at $index
59 | $result: str-insert($result, $replace, $index);
60 | }
61 | }
62 | }
63 |
64 | @return $result;
65 | }
66 |
--------------------------------------------------------------------------------
/lib/functions/throw.scss:
--------------------------------------------------------------------------------
1 | /// Throws an error.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {String} $exception - Exception type
6 | /// @param {String} $message - Message to return
7 | /// @param {Boolean} $throw [option(throw-errors)] - Whether to throw or return the error as a string
8 | ///
9 | /// @return {String}
10 | /// @throws `[$exception] $message`
11 |
12 | @function throw($exception, $message, $throw: option(throw-errors)) {
13 | $result: '[#{$exception}] #{$message}';
14 |
15 | @if $throw {
16 | @error $result;
17 | }
18 |
19 | @return $result
20 | }
21 |
22 |
23 |
24 | @mixin throw($args...) {
25 | $_: throw($args...);
26 | }
27 |
--------------------------------------------------------------------------------
/lib/functions/to-length.scss:
--------------------------------------------------------------------------------
1 | /// Adds a unit to a value
2 | ///
3 | /// @author Hugo Giraudel
4 | ///
5 | /// @group 5_functions
6 | ///
7 | /// @param {Number} $value - Value to add unit to
8 | /// @param {String} $unit - String representation of the unit
9 | ///
10 | /// @return {Number} - `$value` expressed in `$unit`
11 |
12 | @function to-length($value, $unit) {
13 | $units: (
14 | 'px' : 1px,
15 | 'cm' : 1cm,
16 | 'mm' : 1mm,
17 | '%' : 1%,
18 | 'ch' : 1ch,
19 | 'pc' : 1pc,
20 | 'in' : 1in,
21 | 'em' : 1em,
22 | 'rem' : 1rem,
23 | 'pt' : 1pt,
24 | 'ex' : 1ex,
25 | 'vw' : 1vw,
26 | 'vh' : 1vh,
27 | 'vmin' : 1vmin,
28 | 'vmax' : 1vmax
29 | );
30 |
31 | @return $value * map-get($units, $unit);
32 | }
33 |
--------------------------------------------------------------------------------
/lib/functions/to-negative.scss:
--------------------------------------------------------------------------------
1 | /// Converts a number, list, or map of values to negative value(s).
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @requires {function} list-each
6 | /// @requires {function} map-append
7 | ///
8 | /// @param {Number|List|Map} $value - Number, list, or map to convert
9 | ///
10 | /// @return {Number|List|Map} - Converted value
11 | ///
12 | /// @example
13 | /// to-negative(10px)
14 | /// // => -10px;
15 | ///
16 | /// to-negative((1, -2rem, 30px))
17 | /// // => (-1, -2rem, -30px);
18 | ///
19 | /// to-negative((a: 1, b: (1, -2rem, 30px)))
20 | /// // => (a: -1, b: (-1, -2rem, -30px));
21 |
22 | @function to-negative($value) {
23 | $result: $value;
24 |
25 | @if type-of($value) == 'number' {
26 | $result: abs($value) * -1;
27 | }
28 |
29 | @else if type-of($value) == 'list' {
30 | $result: list-each($value, 'to-negative');
31 | }
32 |
33 | @else if type-of($value) == 'map' {
34 | $result: ();
35 |
36 | $map : $value;
37 | $keys : map-keys($map);
38 | $values : map-values($map);
39 |
40 | $index: 0;
41 | @each $val in $values {
42 | $index : $index + 1;
43 | $key : nth($keys, $index);
44 | $val : to-negative($val);
45 |
46 | $result: map-append($result, $key, $val);
47 | }
48 | }
49 |
50 | @return $result;
51 | }
52 |
--------------------------------------------------------------------------------
/lib/functions/to-number.scss:
--------------------------------------------------------------------------------
1 | /// Converts a value to a number.
2 | ///
3 | /// @author Hugo Giraudel
4 | ///
5 | /// @group 5_functions
6 | ///
7 | /// @param {*} $value - Value to convert
8 | ///
9 | /// @return {Number} - Numeric value
10 | ///
11 | /// @example
12 | /// to-number('10px')
13 | /// // => 10px
14 | ///
15 | /// to-number('-0.2674')
16 | /// // => -0.2674
17 |
18 | @function to-number($value) {
19 | @if type-of($value) == 'number' {
20 | @return $value;
21 | }
22 |
23 | $result: 0;
24 | $digits: 0;
25 | $minus: str-slice($value, 1, 1) == '-';
26 | $numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9);
27 |
28 | @for $i from if($minus, 2, 1) through str-length($value) {
29 | $character: str-slice($value, $i, $i);
30 |
31 | @if not (index(map-keys($numbers), $character) or $character == '.') {
32 | @return if($minus, -$result, $result);
33 | }
34 |
35 | @if $character == '.' {
36 | $digits: 1;
37 | } @else if $digits == 0 {
38 | $result: $result * 10 + map-get($numbers, $character);
39 | } @else {
40 | $digits: $digits * 10;
41 | $result: $result + map-get($numbers, $character) / $digits;
42 | }
43 | }
44 |
45 | @return if($minus, -$result, $result);;
46 | }
47 |
--------------------------------------------------------------------------------
/lib/functions/to-string.scss:
--------------------------------------------------------------------------------
1 | /// Converts a value to a string.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {*} $value - Value to convert
6 | ///
7 | /// @return {String} - Stringified value
8 | ///
9 | /// @example
10 | /// to-string(2.1)
11 | /// // => '2.1'
12 | ///
13 | /// type-of(to-string(red))
14 | /// // => 'string'
15 |
16 | @function to-string($value) {
17 | @if type-of($value) == 'string' {
18 | $value: unquote($value);
19 | }
20 |
21 | $result: inspect($value);
22 | @return $result;
23 | }
24 |
--------------------------------------------------------------------------------
/lib/functions/type-check.scss:
--------------------------------------------------------------------------------
1 | /// Performs type checks on values.
2 | ///
3 | /// Returns `true` if all checks pass. Throws an error otherwise.
4 | ///
5 | /// @group 5_functions
6 | ///
7 | /// @requires {function} throw
8 | ///
9 | /// @param {String} $called-from - Name of the calling function or mixin
10 | /// @param {List} $checks - Map of checks to perform
11 | /// @param {Boolean} $throw - Whether to throw or return the error as a string
12 | ///
13 | /// @return {Boolean|String} - `true` if all checks pass
14 | /// @throws [TypeError] `$called-from` expected `$valid-types`, was: `$value` {`$value-type`}
15 |
16 | @function type-check($called-from, $checks, $throw) {
17 | // Perform type checks on each variable
18 | @each $check in $checks {
19 | $value: nth(nth($check, 1), 1);
20 | $value-type: type-of($value);
21 | $valid-types: nth(nth($check, 1), 2);
22 |
23 | @if not index($valid-types, $value-type) {
24 | @return throw('TypeError', '#{$called-from} expected {#{$valid-types}}, was: #{$value} {#{$value-type}}', $throw)
25 | }
26 | }
27 |
28 | @return true;
29 | }
30 |
--------------------------------------------------------------------------------
/lib/functions/unit-convert.scss:
--------------------------------------------------------------------------------
1 | /// Converts units of a value.
2 | ///
3 | /// Can only convert comparable units.
4 | ///
5 | /// @group 5_functions
6 | ///
7 | /// @param {Number} $value - Value to convert
8 | /// @param {String} $unit - Unit to convert to
9 | ///
10 | /// @return {Number} - Converted value
11 | ///
12 | /// @example
13 | /// unit-convert(10px, pt)
14 | /// // => 7.5pt
15 | ///
16 | /// unit-convert(180deg, turn)
17 | /// // => 0.5turn
18 |
19 | @function unit-convert($value, $unit) {
20 | $valid-units: (
21 | px: 0px, pt: 0pt, pc: 0pc, mm: 0mm, cm: 0cm, in: 0in,
22 | deg: 0deg, grad: 0grad, rad: 0rad, turn: 0turn,
23 | Hz: 0Hz, kHz: 0kHz,
24 | ms: 0ms, s: 0s
25 | );
26 |
27 | $result: map-get($valid-units, $unit) + $value;
28 | @return $result;
29 | }
30 |
--------------------------------------------------------------------------------
/lib/functions/unit-strip.scss:
--------------------------------------------------------------------------------
1 | /// Strips units from a value.
2 | ///
3 | /// @group 5_functions
4 | ///
5 | /// @param {Number} $value - Value to strip units from
6 | ///
7 | /// @return {Number} - Unitless value
8 | ///
9 | /// @example
10 | /// unit-strip(10px)
11 | /// // => 10
12 |
13 | @function unit-strip($value) {
14 | $result: $value / ($value * 0 + 1);
15 | @return $result;
16 | }
17 |
--------------------------------------------------------------------------------
/lib/mixins/_.scss:
--------------------------------------------------------------------------------
1 | ////
2 | /// Mixins
3 | ///
4 | /// Mixins that output CSS.
5 | ////
6 |
7 | @import 'query';
8 | @import 'extends';
9 | @import 'important';
10 | @import 'responsive';
11 | @import 'type-scale';
12 | @import 'css-ruleset';
13 |
--------------------------------------------------------------------------------
/lib/mixins/css-ruleset.scss:
--------------------------------------------------------------------------------
1 | /// Generates CSS ruleset(s) from a Scarab module.
2 | ///
3 | /// @group 6_mixins
4 | ///
5 | /// @requires {function} get
6 | /// @requires {function} option
7 | /// @requires {function} class-template
8 | /// @requires {function} class-sanitize
9 | /// @requires {function} class-escape
10 | /// @requires {function} str-replace
11 | /// @requires {function} is-null
12 | ///
13 | /// @param {Map} $module - Contains `root`, `breakpoints`, `states`, and `prefix/suffix` overrides
14 | /// @param {String} $variant - Selector variant
15 | /// @param {String} $modifier - Selector modifier
16 | ///
17 | /// @output CSS ruleset(s)
18 |
19 | @mixin css-ruleset($module, $variant: '', $modifier: '') {
20 | @if type-of($module) == 'string' {
21 | $module: module($module);
22 | }
23 |
24 | $variant: to-string($variant);
25 | $modifier: to-string($modifier);
26 |
27 | // Get module options
28 | $root : map-get($module, 'root');
29 | $breakpoints : map-get($module, 'breakpoints');
30 | $states : map-get($module, 'states');
31 |
32 | // Allow $breakpoints to accept a list
33 | @if type-of($breakpoints) == 'list' {
34 | $_breakpoints: ();
35 |
36 | @each $name in $breakpoints {
37 | $_breakpoints: map-append($_breakpoints, to-string($name), get(breakpoint, $name));
38 | }
39 |
40 | $breakpoints: $_breakpoints;
41 | }
42 |
43 | // Allow $states to accept a list
44 | @if type-of($states) == 'list' {
45 | $_states: ();
46 |
47 | @each $state in $states {
48 | $state-key: nth(map-get-key(option(namescheme, states), $state), 1);
49 | $_states: map-append($_states, $state-key, $state);
50 | }
51 |
52 | $states: $_states;
53 | }
54 |
55 | // Allow $module to overwrite global prefix/suffix options
56 | $breakpoint-prefix : if(is-null(map-get($module, 'breakpoint-prefix')),
57 | option(namescheme, breakpoint-prefix),
58 | map-get($module, 'breakpoint-prefix')
59 | );
60 |
61 | $breakpoint-suffix : if(is-null(map-get($module, 'breakpoint-suffix')),
62 | option(namescheme, breakpoint-suffix),
63 | map-get($module, 'breakpoint-suffix')
64 | );
65 |
66 | $state-prefix : if(is-null(map-get($module, 'state-prefix')),
67 | option(namescheme, state-prefix),
68 | map-get($module, 'state-prefix')
69 | );
70 |
71 | $state-suffix : if(is-null(map-get($module, 'state-suffix')),
72 | option(namescheme, state-suffix),
73 | map-get($module, 'state-suffix')
74 | );
75 |
76 | // Build the selector
77 | $class-template: class-template($module, $variant, $modifier);
78 |
79 | // Output base class
80 | .#{class-escape(class-sanitize($class-template))} {
81 | @content;
82 | }
83 |
84 | // Output stateful classes
85 | @if not is-null($states) {
86 | @each $state-name, $state-value in $states {
87 | $state-selector: str-replace($class-template, '{{s}}', $state-name);
88 | $state-selector: str-replace($state-selector, '{{sp}}', $state-prefix);
89 | $state-selector: str-replace($state-selector, '{{ss}}', $state-suffix);
90 |
91 | .#{class-escape(class-sanitize($state-selector))}:#{$state-value} {
92 | @content;
93 | }
94 | }
95 | }
96 |
97 | @if not is-null($breakpoints) {
98 | // Output responsive classes
99 | @each $bp-name, $bp-value in $breakpoints {
100 | $bp-selector: str-replace($class-template, '{{b}}', $bp-name);
101 | $bp-selector: str-replace($bp-selector, '{{bp}}', $breakpoint-prefix);
102 | $bp-selector: str-replace($bp-selector, '{{bs}}', $breakpoint-suffix);
103 |
104 | @include query($bp-value) {
105 | // Output base responsive class
106 | .#{class-escape(class-sanitize($bp-selector))} {
107 | @content;
108 | }
109 |
110 | // Output responsive, stateful classes
111 | @if not is-null($states) {
112 | @each $state-name, $state-value in $states {
113 | $rs-selector: str-replace($bp-selector, '{{s}}', $state-name);
114 | $rs-selector: str-replace($rs-selector, '{{sp}}', $state-prefix);
115 | $rs-selector: str-replace($rs-selector, '{{ss}}', $state-suffix);
116 |
117 | .#{class-escape(class-sanitize($rs-selector))}:#{$state-value} {
118 | @content;
119 | }
120 | }
121 | }
122 | }
123 | }
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/lib/mixins/extends.scss:
--------------------------------------------------------------------------------
1 | /// Extends multiple classes
2 | ///
3 | /// @group 6_mixins
4 | ///
5 | /// @requires {function} to-string
6 | /// @requires {function} class-escape
7 | ///
8 | /// @param {Arglist} $classes - Arglist of classes to extend
9 | ///
10 | /// @output Multiple Sass `@extend` directives
11 |
12 | @mixin extends($classes...) {
13 | @each $class in $classes {
14 | @extend .#{class-escape(to-string($class))};
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/lib/mixins/important.scss:
--------------------------------------------------------------------------------
1 | /// Generates `!important` property declaration(s).
2 | ///
3 | /// @group 6_mixins
4 | ///
5 | /// @param {Map} $property-map - Map of properties to values
6 | ///
7 | /// @output !important property declaration(s)
8 |
9 | @mixin important($property-map) {
10 | @each $property, $value in $property-map {
11 | #{$property}: #{$value} !important;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/mixins/query.scss:
--------------------------------------------------------------------------------
1 | /// Wraps declarations inside an `@media` block.
2 | ///
3 | /// @group 6_mixins
4 | ///
5 | /// @requires {function} get
6 | /// @requires {function} class-template
7 | ///
8 | /// @param {Number|List|Map} $query
9 | ///
10 | /// @output Style declarations inside an `@media` block
11 | ///
12 | /// @todo Add support for other types of media queries (besides width)
13 |
14 | @mixin query($query) {
15 | $breakpoint: ();
16 | $media-query: ();
17 |
18 | // If $query is a number, generate a `min-width: ` media query
19 | @if type-of($query) == 'number' {
20 | $breakpoint: $query;
21 | $media-query: '(min-width: #{$breakpoint})'
22 | }
23 |
24 | // If $query is a list, accept the following formats:
25 | // - query(from #{$bp}) => @media (min-width: #{$bp})
26 | // - query(above #{$bp}) => @media (min-width: #{$bp} + 1px)
27 | // - query(until #{$bp}) => @media (max-width: #{$bp})
28 | // - query(below #{$bp}) => @media (max-width: #{$bp} - 1px)
29 | // - query(from #{$bp1} to #{$bp2}) => @media (min-width: #{$bp1}) and (max-width: #{$bp2})
30 | @else if type-of($query) == 'list' {
31 |
32 | @if (length($query) == 2) {
33 | $breakpoint: nth($query, 2);
34 |
35 | @if type-of($breakpoint) == 'number' {
36 | // "from #{$bp}" syntax
37 | @if nth($query, 1) == 'from' {
38 | $media-query: (min-width: #{$breakpoint});
39 | }
40 |
41 | // "above #{$bp}" syntax
42 | @if nth($query, 1) == 'above' {
43 | $original-unit: unit($breakpoint);
44 |
45 | @if (unit($breakpoint) == 'em') or (unit($breakpoint) == 'rem') {
46 | $breakpoint: unit-strip((unit-strip($breakpoint) * 16px) + 1px) / 16#{$original-unit};
47 | } @else {
48 | $breakpoint: unit-convert(unit-convert($breakpoint, 'px') + 1px, $original-unit);
49 | }
50 |
51 | $media-query: (min-width: #{$breakpoint});
52 | }
53 |
54 | // "until #{$bp}" syntax
55 | @if nth($query, 1) == 'until' {
56 | $media-query: (max-width: #{$breakpoint});
57 | }
58 |
59 | // "below #{$bp}" syntax
60 | @if nth($query, 1) == 'below' {
61 | $original-unit: unit($breakpoint);
62 |
63 | @if (unit($breakpoint) == 'em') or (unit($breakpoint) == 'rem') {
64 | $breakpoint: unit-strip((unit-strip($breakpoint) * 16px) - 1px) / 16#{$original-unit};
65 | } @else {
66 | $breakpoint: unit-convert(unit-convert($breakpoint, 'px') - 1px, $original-unit);
67 | }
68 |
69 | $media-query: (max-width: #{$breakpoint});
70 | }
71 | }
72 | }
73 |
74 | // "from #{$bp1} to #{$bp2}" syntax
75 | @if length($query) == 4 {
76 | $bp1: nth($query, 2);
77 | $bp2: nth($query, 4);
78 |
79 | $media-query: '(min-width: #{$bp1}) and (max-width: #{$bp2})';
80 | }
81 |
82 | }
83 |
84 | // If $query is a map, expect it to have `type` and `condition` keys
85 | @else if type-of($query) == 'map' {
86 | $type: if(map-has-key($query, type), map-get($query, type), null);
87 | $condition: if(map-has-key($query, condition), map-get($query, condition), null);
88 |
89 | @if ($type) and ($condition) {
90 | $media-query: '#{$type} and #{unquote($condition)}';
91 | }
92 |
93 | @else if $type {
94 | $media-query: #{$type};
95 | }
96 |
97 | @else if $condition {
98 | $media-query: #{$condition};
99 | }
100 | }
101 |
102 | @media #{$media-query} {
103 | @content;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/lib/mixins/responsive.scss:
--------------------------------------------------------------------------------
1 | /// Generates responsive property declaration(s).
2 | ///
3 | /// @group 6_mixins
4 | ///
5 | /// @requires {function} get
6 | /// @requires {function} option
7 | /// @requires {mixin} query
8 | ///
9 | /// @param {String|List} $properties - Properties to declare
10 | /// @param {Map} $breakpoint-map - Map of breakpoint values to property values
11 | /// @param {Null|Boolean} $important [null] - Whether to ouput !important rules
12 | ///
13 | /// @output Responsive properties
14 |
15 | @mixin responsive($properties, $breakpoint-map, $important: null) {
16 | @each $breakpoint, $value in $breakpoint-map {
17 | @if $breakpoint == option(namescheme, default-key) {
18 | @each $property in $properties {
19 | #{$property}: $value important($important);
20 | }
21 | } @else {
22 | // If $breakpoint is a string, get the breakpoint value
23 | @if type-of($breakpoint) == 'string' {
24 | $breakpoint: get(breakpoint, $breakpoint);
25 | }
26 |
27 | @include query($breakpoint) {
28 | @each $property in $properties {
29 | #{$property}: $value important($important);
30 | }
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/lib/mixins/type-scale.scss:
--------------------------------------------------------------------------------
1 | /// Generates `font-size` and `line-height` property declaration(s).
2 | ///
3 | /// @group 6_mixins
4 | ///
5 | /// @requires {function} get
6 | /// @requires {mixin} responsive
7 | ///
8 | /// @param {String} $size - Name of size in `get(font-sizes)` and `get(line-heights)`
9 | /// @param {Null|Boolean} $important [null] - Whether to ouput !important rules
10 | ///
11 | /// @output Property declarations for `font-size` and `line-height`
12 |
13 | @mixin type-scale($size, $important: null) {
14 | $font-size: get(font-size, $size);
15 | $line-height: get(line-height, $size);
16 |
17 | @if type-of($font-size) == 'map' {
18 | @include responsive(font-size, get(font-size, $size), $important);
19 | } @else {
20 | font-size: $font-size important($important);
21 | }
22 |
23 | @if type-of($line-height) == 'map' {
24 | @include responsive(line-height, get(line-height, $size), $important);
25 | } @else {
26 | line-height: $line-height important($important);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/options/_.scss:
--------------------------------------------------------------------------------
1 | ////
2 | /// Options
3 | ///
4 | /// Function for managing Scarab options.
5 | ////
6 |
7 | @import '_init';
8 |
9 | @import 'option';
10 | @import 'set-option';
11 |
--------------------------------------------------------------------------------
/lib/options/_init.scss:
--------------------------------------------------------------------------------
1 | /// Options for the Scarab framework.
2 | ///
3 | /// Scarab options can be configured using `set-option()`.
4 | /// Refer to the table below for a description of each option.
5 | ///
6 | /// *During initialization, the `$__SCARAB_OPTIONS` variable is merged into `$__SCARAB`.
7 | /// Subsequently, its value is set to `null`.*
8 | ///
9 | /// @access private
10 | /// @group 0_variables
11 | ///
12 | /// @type Map
13 | /// @prop {Bool} throw-errors [true] - Whether to throw or return errors as strings
14 | /// @prop {Map} output - Contains options for the CSS output
15 | /// @prop {Bool} output.classes [true] - Whether Scarab should ouput CSS classes
16 | /// @prop {Bool} output.placeholders [true] - Whether Scarab should ouput Sass placeholders
17 | /// @prop {Bool} ouput.reset [true] - Whether Scarab should ouput CSS reset rules
18 | /// @prop {Bool} ouput.normalize [true] - Whether Scarab should ouput CSS normalize rules
19 | /// @prop {Bool} important [true] - Whether to append !important to generated modules
20 | /// @prop {Map} namescheme - Contains options for the naming scheme
21 | /// @prop {String} namescheme.default-key ['_'] - Key name to use for the "default" value in a map
22 | /// @prop {Map} namescheme.directions - Map of directional shorthands to values
23 | /// @prop {Map} namescheme.states - Map of state shorthands to values
24 | /// @prop {String} namescheme.selector-format - Format for programmatically generated CSS selectors
25 | /// @prop {String} namescheme.root-prefix [''] - Root prefix
26 | /// @prop {String} namescheme.root-suffix [''] - Root suffix
27 | /// @prop {String} namescheme.variant-prefix ['-'] - Variant prefix
28 | /// @prop {String} namescheme.variant-suffix [''] - Variant suffix
29 | /// @prop {String} namescheme.modifier-prefix [':'] - Modifier prefix
30 | /// @prop {String} namescheme.modifier-suffix [''] - Modifier suffix
31 | /// @prop {String} namescheme.breakpoint-prefix ['('] - Breakpoint prefix
32 | /// @prop {String} namescheme.breakpoint-suffix [')'] - Breakpoint suffix
33 | /// @prop {String} namescheme.state-prefix ['('] - State prefix
34 | /// @prop {String} namescheme.state-suffix [')'] - State suffix
35 |
36 | $__SCARAB_OPTIONS: (
37 | 'throw-errors' : true,
38 | 'output' : (
39 | 'classes' : true,
40 | 'placeholders' : true,
41 | 'reset' : true,
42 | 'normalize' : true,
43 | 'important' : true
44 | ),
45 | 'namescheme' : (
46 | 'default-key' : '_',
47 | 'directions' : (
48 | 'x' : horizontal,
49 | 'y' : vertical,
50 | 't' : top,
51 | 'r' : right,
52 | 'b' : bottom,
53 | 'l' : left
54 | ),
55 | 'anchors' : (
56 | 't' : top,
57 | 'b' : bottom,
58 | 'l' : left,
59 | 'r' : right,
60 | 'c' : center,
61 | 'tr' : top right,
62 | 'tl' : top left,
63 | 'br' : bottom right,
64 | 'bl' : bottom left
65 | ),
66 | 'states' : (
67 | 'hv': hover,
68 | 'fc': focus,
69 | 'ac': active
70 | ),
71 | 'selector-format' : '{{b}}{{bp}}{{s}}{{sp}}{{rp}}{{r}}{{rs}}{{vp}}{{v}}{{vs}}{{mp}}{{m}}{{ms}}{{ss}}{{bs}}',
72 | 'root-prefix' : '',
73 | 'root-suffix' : '',
74 | 'variant-prefix' : '-',
75 | 'variant-suffix' : '',
76 | 'modifier-prefix' : ':',
77 | 'modifier-suffix' : '',
78 | 'breakpoint-prefix' : '(',
79 | 'breakpoint-suffix' : ')',
80 | 'state-prefix' : '(',
81 | 'state-suffix' : ')'
82 | )
83 | );
84 |
85 | // Merge into $__SCARAB
86 | $__SCARAB: map-merge($__SCARAB, ('OPTIONS': $__SCARAB_OPTIONS));
87 | $__SCARAB_OPTIONS: null;
88 |
--------------------------------------------------------------------------------
/lib/options/option.scss:
--------------------------------------------------------------------------------
1 | /// Returns a value from the `OPTIONS` map
2 | ///
3 | /// @group 1_options
4 | ///
5 | /// @requires {variable} __SCARAB
6 | /// @requires {function} to-string
7 | ///
8 | /// @see {mixin} set
9 | ///
10 | /// @param {ArgList} $path - Path of the key to retrieve the value from
11 | /// @return {*}
12 | ///
13 | /// @example
14 | /// @include set-option(throw-errors, false);
15 | ///
16 | /// option(throw-errors);
17 | /// // => false
18 |
19 | @function option($path...) {
20 | $result: map-get($__SCARAB, 'OPTIONS');
21 |
22 | @each $key in $path {
23 | $result: map-get($result, to-string($key));
24 | }
25 |
26 | @return $result;
27 | }
28 |
--------------------------------------------------------------------------------
/lib/options/set-option.scss:
--------------------------------------------------------------------------------
1 | /// Sets or updates a value of a key in the `OPTIONS` map
2 | ///
3 | /// @group 1_options
4 | ///
5 | /// @requires {variable} __SCARAB
6 | /// @requires {function} to-string
7 | /// @requires {function} map-stringify-keys-deep
8 | ///
9 | /// @see {function} option
10 | ///
11 | /// @param {ArgList} $definition - Definition of the new value
12 | ///
13 | /// @return {ArgList} - Definition of the new value
14 | ///
15 | /// @example
16 | /// $_: set-option(throw-errors, false);
17 | ///
18 | /// option(throw-errors);
19 | /// // => false
20 |
21 | @function set-option($definition...) {
22 |
23 | // Get a copy of the current $OPTIONS state
24 | $OPTIONS: map-get($__SCARAB, 'OPTIONS');
25 |
26 | $result: (); // key-value pair that will be merged with $OPTIONS
27 |
28 | // If there are only 2 args, we can easily determine the result
29 | @if length($definition) == 2 {
30 | $key : nth($definition, 1);
31 | $new-value : nth($definition, 2);
32 |
33 | $result: ($key: $new-value);
34 | }
35 |
36 | // For more than 2 args, we have to build the result backwards
37 | @if length($definition) > 2 {
38 |
39 | // The new value is the last arg in $definition
40 | $new-value: nth($definition, -1);
41 |
42 | // Build a list of maps preceding the new one
43 | $maps: ($OPTIONS,);
44 |
45 | @for $i from 1 through length($definition) - 2 {
46 | $current-map : nth($maps, -1);
47 | $current-key : nth($definition, $i);
48 | $current-value : map-get($current-map, to-string($current-key)) or ();
49 |
50 | $maps: append($maps, $current-value);
51 | }
52 |
53 | @for $i from length($maps) through 1 {
54 | $current-map : nth($maps, $i);
55 | $current-key : nth($definition, $i);
56 | $current-value : ();
57 |
58 | @if $i == length($maps) {
59 | $current-value: $new-value;
60 | } @else {
61 | $current-value: $result;
62 | }
63 |
64 | $result: map-merge($current-map, (to-string($current-key): $current-value));
65 | }
66 | }
67 |
68 | // Update the local $OPTIONS map
69 | $OPTIONS: map-merge($OPTIONS, map-stringify-keys-deep($result));
70 |
71 | // Merge the updated $OPTIONS map back into $__SCARAB
72 | $__SCARAB: map-merge($__SCARAB, ('OPTIONS': $OPTIONS)) !global;
73 | @return $definition;
74 |
75 | }
76 |
77 |
78 |
79 | /// Calls `set-option`
80 | ///
81 | /// @group 1_options
82 | ///
83 | /// @requires {function} set-option
84 | ///
85 | /// @param {ArgList} $args - Args for `set-option`
86 | ///
87 | /// @example
88 | /// @include set-option(throw-errors, false);
89 | ///
90 | /// option(throw-errors);
91 | /// // => false
92 |
93 | @mixin set-option($args...) {
94 | $_: set-option($args...);
95 | }
96 |
--------------------------------------------------------------------------------
/lib/tokens/_.scss:
--------------------------------------------------------------------------------
1 | ////
2 | /// Inventory
3 | ///
4 | /// Functions for design token management.
5 | ////
6 |
7 | @import '_init';
8 |
9 | @import 'get';
10 | @import 'set';
11 | @import 'set-default';
12 | @import 'unset';
13 |
14 | @import 'helpers/_';
15 |
--------------------------------------------------------------------------------
/lib/tokens/_init.scss:
--------------------------------------------------------------------------------
1 | /// The global stylesheet tokens.
2 | ///
3 | /// Token values can be configured using `set()`.
4 | /// They can be retrieved using `get()`, or any of the tokens helper functions like `font-size()`, `fz()`, etc.
5 | ///
6 | /// *During initialization, the `$__SCARAB_TOKENS` variable is merged into `$__SCARAB`.
7 | /// Subsequently, its value is set to `null`.*
8 | ///
9 | /// @access private
10 | /// @group 0_variables
11 | ///
12 | /// @type Map
13 |
14 | $__SCARAB_TOKENS : (
15 | 'baseline' : 1rem,
16 | 'breakpoint' : (),
17 | 'color' : (),
18 | 'gradient' : (),
19 | 'opacity' : (),
20 | 'background-image' : (),
21 | 'letter-spacing' : (),
22 | 'line-height' : (),
23 | 'font-family' : (),
24 | 'font-size' : (),
25 | 'font-weight' : (),
26 | 'line-style' : (),
27 | 'line-width' : (),
28 | 'text-measure' : (),
29 | 'wrapper-width' : (),
30 | 'spacing' : (),
31 | 'coordinate' : (),
32 | 'flex-grid' : (),
33 | 'ratio' : (),
34 | 'angle' : (),
35 | 'duration' : (),
36 | 'easing' : (),
37 | 'border-radius' : (),
38 | 'box-shadow' : (),
39 | 'text-shadow' : (),
40 | 'keyframe' : (),
41 | 'module' : ()
42 | );
43 |
44 | // Merge into $__SCARAB
45 | $__SCARAB: map-merge($__SCARAB, ('TOKENS': $__SCARAB_TOKENS));
46 | $__SCARAB_TOKENS: null;
47 |
--------------------------------------------------------------------------------
/lib/tokens/get.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a token.
2 | ///
3 | /// @group 3_tokens
4 | ///
5 | /// @requires {variable} __SCARAB
6 | /// @requires {function} to-string
7 | ///
8 | /// @param {ArgList} $path - Path to the token
9 | ///
10 | /// @return {*} - Token value
11 | ///
12 | /// @example
13 | /// @include set(breakpoint, (
14 | /// small : 600px,
15 | /// medium : 1024px,
16 | /// large : 1300px,
17 | /// huge : 1600px
18 | /// ) );
19 | ///
20 | /// get(breakpoint, small)
21 | /// // => 600px
22 | ///
23 | /// get(breakpoint)
24 | /// // => (
25 | /// // small : 600px,
26 | /// // medium : 1024px,
27 | /// // large : 1300px,
28 | /// // huge : 1600px
29 | /// // )
30 |
31 | @function get($path...) {
32 | $result: map-get($__SCARAB, 'TOKENS');
33 |
34 | @each $key in $path {
35 | $result: map-get($result, to-string($key));
36 | }
37 |
38 | @return $result;
39 | }
40 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/_.scss:
--------------------------------------------------------------------------------
1 | ////
2 | /// Token Helpers
3 | ///
4 | /// Helper functions for retrieving values in the stylesheet tokens.
5 | ////
6 |
7 | @import 'baseline';
8 | @import 'breakpoint';
9 | @import 'color';
10 | @import 'gradient';
11 | @import 'opacity';
12 | @import 'background-image';
13 | @import 'letter-spacing';
14 | @import 'line-height';
15 | @import 'font-family';
16 | @import 'font-size';
17 | @import 'font-weight';
18 | @import 'line-style';
19 | @import 'line-width';
20 | @import 'text-measure';
21 | @import 'wrapper-width';
22 | @import 'flex-grid';
23 | @import 'spacing';
24 | @import 'coordinate';
25 | @import 'ratio';
26 | @import 'angle';
27 | @import 'duration';
28 | @import 'easing';
29 | @import 'border-radius';
30 | @import 'box-shadow';
31 | @import 'text-shadow';
32 | @import 'keyframe';
33 | @import 'module';
34 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/angle.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of an angle token.
2 | ///
3 | /// @group 4_token-helpers
4 | ///
5 | /// @requires {function} get
6 | ///
7 | /// @param {String} $path - Path to the token
8 | ///
9 | /// @return {*}
10 |
11 | @function angle($path...) {
12 | $result: get(angle, $path...);
13 | @return $result;
14 | }
15 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/background-image.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a background image token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function bgi()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | ///
12 | /// @return {*}
13 |
14 | @function background-image($path...) {
15 | $result: get(background-image, $path...);
16 | @return $result;
17 | }
18 |
19 |
20 |
21 | /// @group 4_token-helpers
22 | /// @alias background-image
23 |
24 | @function bgi($args...) {
25 | @return background-image($args...);
26 | }
27 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/baseline.scss:
--------------------------------------------------------------------------------
1 | /// Returns a multiple of the global typographic baseline value.
2 | ///
3 | /// **Aliases**
4 | /// - `@function bl()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {Number} $multiplier [1] - Baseline multiplier
11 | ///
12 | /// @return {Number} - Unit depends on the baseline value
13 | ///
14 | /// @example
15 | /// @include set(baseline, 1rem);
16 | ///
17 | /// baseline(2)
18 | /// // => 2rem
19 | ///
20 | /// bl(2.5)
21 | /// // => 2.5rem
22 |
23 | @function baseline($multiplier: 1) {
24 | $result: get(baseline) * $multiplier;
25 | @return $result;
26 | }
27 |
28 |
29 |
30 | /// @group 4_token-helpers
31 | /// @alias baseline
32 |
33 | @function bl($args...) {
34 | @return baseline($args...);
35 | }
36 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/border-radius.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a border-radius token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function radius()`
5 | /// - `@function bdr()`
6 | ///
7 | /// @group 4_token-helpers
8 | ///
9 | /// @requires {function} get
10 | ///
11 | /// @param {String} $path - Path to the token
12 | /// @return {*}
13 |
14 | @function border-radius($path...) {
15 | $result: get(border-radius, $path...);
16 | @return $result;
17 | }
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias border-radius
22 |
23 | @function bdr($args...) {
24 | @return border-radius($args...);
25 | }
26 |
27 |
28 |
29 | /// @group 4_token-helpers
30 | /// @alias border-radius
31 |
32 | @function radius($args...) {
33 | @return border-radius($args...);
34 | }
35 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/box-shadow.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a box-shadow token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function bsh()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function box-shadow($path...) {
14 | $result: get(box-shadow, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias box-shadow
22 |
23 | @function bsh($args...) {
24 | @return box-shadow($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/breakpoint.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a breakpoint token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function bp()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function breakpoint($path...) {
14 | $result: get(breakpoint, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias breakpoint
22 |
23 | @function bp($args...) {
24 | @return breakpoint($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/color.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a color token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function c()`
5 | /// - `@function palette()`
6 | ///
7 | /// @group 4_token-helpers
8 | ///
9 | /// @requires {function} get
10 | ///
11 | /// @param {String} $path - Path to the token
12 | /// @return {*}
13 |
14 | @function color($path...) {
15 | $result: get(color, $path...);
16 |
17 | @if type-of($result) == 'map' {
18 | $result: map-get($result, option(namescheme, default-key));
19 | }
20 |
21 | @return $result;
22 | }
23 |
24 |
25 |
26 | /// @group 4_token-helpers
27 | /// @alias color
28 |
29 | @function c($args...) {
30 | @return color($args...);
31 | }
32 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/coordinate.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a coordinate token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function coord()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function coordinate($path...) {
14 | $result: get(coordinate, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias coordinate
22 |
23 | @function coord($args...) {
24 | @return coordinate($args...);
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/duration.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a duration token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function dur()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function duration($path...) {
14 | $result: get(duration, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias duration
22 |
23 | @function dur($args...) {
24 | @return duration($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/easing.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of an easing token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function ease()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function easing($path...) {
14 | $result: get(easing, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias easing
22 |
23 | @function ease($args...) {
24 | @return easing($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/flex-grid.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a flex-grid token.
2 | ///
3 | /// @group 4_token-helpers
4 | ///
5 | /// @requires {function} get
6 | ///
7 | /// @param {String} $path - Path to the token
8 | /// @return {*}
9 |
10 | @function flex-grid($path...) {
11 | $result: get(flex-grid, $path...);
12 | @return $result;
13 | }
14 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/font-family.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a font family token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function ff()`
5 | /// - `@function typeface()`
6 | ///
7 | /// @group 4_token-helpers
8 | ///
9 | /// @requires {function} get
10 | ///
11 | /// @param {String} $path - Path to the token
12 | /// @return {*}
13 |
14 | @function font-family($path...) {
15 | $result: get(font-family, $path...);
16 | @return $result;
17 | }
18 |
19 |
20 |
21 | /// @group 4_token-helpers
22 | /// @alias font-family
23 |
24 | @function ff($args...) {
25 | @return font-family($args...);
26 | }
27 |
28 |
29 |
30 | /// @group 4_token-helpers
31 | /// @alias font-family
32 |
33 | @function typeface($args...) {
34 | @return font-family($args...);
35 | }
36 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/font-size.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a font size token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function fz()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function font-size($path...) {
14 | $result: get(font-size, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias font-size
22 |
23 | @function fz($args...) {
24 | @return font-size($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/font-weight.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a font weight token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function fw()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function font-weight($path...) {
14 | $result: get(font-weight, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias font-weight
22 |
23 | @function fw($args...) {
24 | @return font-weight($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/gradient.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a gradient token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function g()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function gradient($path...) {
14 | $result: get(gradient, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias gradient
22 |
23 | @function g($args...) {
24 | @return gradient($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/keyframe.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a keyframe token.
2 | ///
3 | /// @group 4_token-helpers
4 | ///
5 | /// @requires {function} get
6 | ///
7 | /// @param {String} $path - Path to the token
8 | /// @return {*}
9 |
10 | @function keyframe($path...) {
11 | $result: get(keyframe, $path...);
12 | @return $result;
13 | }
14 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/letter-spacing.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a letter spacing token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function ls()`
5 | /// - `@function tracking()`
6 | ///
7 | /// @group 4_token-helpers
8 | ///
9 | /// @requires {function} get
10 | ///
11 | /// @param {String} $path - Path to the token
12 | /// @return {*}
13 |
14 | @function letter-spacing($path...) {
15 | $result: get(letter-spacing, $path...);
16 | @return $result;
17 | }
18 |
19 |
20 |
21 | /// @group 4_token-helpers
22 | /// @alias letter-spacing
23 |
24 | @function ls($args...) {
25 | @return letter-spacing($args...);
26 | }
27 |
28 |
29 |
30 | /// @group 4_token-helpers
31 | /// @alias letter-spacing
32 |
33 | @function tracking($args...) {
34 | @return letter-spacing($args...);
35 | }
36 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/line-height.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a line height token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function lh()`
5 | /// - `@function leading()`
6 | ///
7 | /// @group 4_token-helpers
8 | ///
9 | /// @requires {function} get
10 | ///
11 | /// @param {String} $path - Path to the token
12 | /// @return {*}
13 |
14 | @function line-height($path...) {
15 | $result: get(line-height, $path...);
16 | @return $result;
17 | }
18 |
19 |
20 |
21 | /// @group 4_token-helpers
22 | /// @alias line-height
23 |
24 | @function lh($args...) {
25 | @return line-height($args...);
26 | }
27 |
28 |
29 |
30 | /// @group 4_token-helpers
31 | /// @alias line-height
32 |
33 | @function leading($args...) {
34 | @return line-height($args...);
35 | }
36 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/line-style.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a line style token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function c()`
5 | /// - `@function palette()`
6 | ///
7 | /// @group 4_token-helpers
8 | ///
9 | /// @requires {function} get
10 | ///
11 | /// @param {String} $path - Path to the token
12 | /// @return {*}
13 |
14 | @function line-style($path...) {
15 | $result: get(line-style, $path...);
16 | @return $result;
17 | }
18 |
19 |
20 |
21 | /// @group 4_token-helpers
22 | /// @alias line-style
23 |
24 | @function lns($args...) {
25 | @return line-style($args...);
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/line-width.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a line width token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function lnw()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function line-width($path...) {
14 | $result: get(line-width, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias line-width
22 |
23 | @function lnw($args...) {
24 | @return line-width($args...);
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/module.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a module token.
2 | ///
3 | /// @group 4_token-helpers
4 | ///
5 | /// @requires {function} get
6 | ///
7 | /// @param {String} $path - Path to the token
8 | /// @return {*}
9 |
10 | @function module($path...) {
11 | $result: get(module, $path...);
12 | @return $result;
13 | }
14 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/opacity.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of an opacity token.
2 | ///
3 | ///
4 | /// **Aliases**
5 | /// - `@function o()`
6 | ///
7 | /// @group 4_token-helpers
8 | ///
9 | /// @requires {function} get
10 | ///
11 | /// @param {String} $path - Path to the token
12 | /// @return {*}
13 |
14 | @function opacity($path...) {
15 | $result: get(opacity, $path...);
16 | @return $result;
17 | }
18 |
19 |
20 |
21 | /// @group 4_token-helpers
22 | /// @alias opacity
23 |
24 | @function o($args...) {
25 | @return opacity($args...);
26 | }
27 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/ratio.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of an aspect ratio token.
2 | ///
3 | /// @group 4_token-helpers
4 | ///
5 | /// @requires {function} get
6 | ///
7 | /// @param {String} $path - Path to the token
8 | /// @return {*}
9 |
10 | @function ratio($path...) {
11 | $result: get(ratio, $path...);
12 | @return $result;
13 | }
14 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/spacing.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a spacing token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function s()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function spacing($path...) {
14 | $result: get(spacing, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias spacing
22 |
23 | @function s($args...) {
24 | @return spacing($args...);
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/text-measure.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a text measure token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function measure()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function text-measure($path...) {
14 | $result: get(text-measure, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias text-measure
22 |
23 | @function measure($args...) {
24 | @return text-measure($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/text-shadow.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a text-shadow token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function tsh()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function text-shadow($path...) {
14 | $result: get(text-shadow, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias text-shadow
22 |
23 | @function tsh($args...) {
24 | @return text-shadow($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/helpers/wrapper-width.scss:
--------------------------------------------------------------------------------
1 | /// Returns the value of a wrapper width token.
2 | ///
3 | /// **Aliases**
4 | /// - `@function wrap()`
5 | ///
6 | /// @group 4_token-helpers
7 | ///
8 | /// @requires {function} get
9 | ///
10 | /// @param {String} $path - Path to the token
11 | /// @return {*}
12 |
13 | @function wrapper-width($path...) {
14 | $result: get(wrapper-width, $path...);
15 | @return $result;
16 | }
17 |
18 |
19 |
20 | /// @group 4_token-helpers
21 | /// @alias wrapper-width
22 |
23 | @function wrap($args...) {
24 | @return wrapper-width($args...);
25 | }
26 |
--------------------------------------------------------------------------------
/lib/tokens/set-default.scss:
--------------------------------------------------------------------------------
1 | /// Sets a default value for a key in the stylesheet tokens.
2 | ///
3 | /// @group 3_tokens
4 | ///
5 | /// @requires {variable} __SCARAB
6 | /// @requires {function} set
7 | /// @requires {function} to-string
8 | ///
9 | /// @param {ArgList} $definition - Definition of the default value
10 | ///
11 | /// @return {ArgList} - Definition of the default value
12 | ///
13 | /// @example
14 | /// // Sets a default value
15 | /// $_: set-default(baseline, 1rem);
16 | ///
17 | /// get(baseline)
18 | /// // => 1rem
19 | ///
20 | /// // Updates the value
21 | /// $_: set(baseline, 1.25rem);
22 | ///
23 | /// get(baseline)
24 | /// // => 1.25rem
25 | ///
26 | /// // Doesn't update the value since it already exists
27 | /// $_: set-default(baseline, 1rem);
28 | ///
29 | /// get(baseline)
30 | /// // => 1.25rem
31 |
32 | @function set-default($definition...) {
33 |
34 | // Get a copy of the current $TOKENS state
35 | $TOKENS: map-get($__SCARAB, 'TOKENS');
36 |
37 | // Check if the key exists to determine whether to set the new value
38 | $key-exists: true;
39 |
40 | @if length($definition) == 2 {
41 | $key: nth($definition, 1);
42 |
43 | @if not map-has-key($TOKENS, to-string($key)) {
44 | $key-exists: false;
45 | }
46 | }
47 |
48 | @else if length($definition) > 2 {
49 | $current-map: $TOKENS;
50 |
51 | @for $i from 1 through length($definition) - 1 {
52 | $current-key: nth($definition, $i);
53 |
54 | @if not map-has-key($current-map, to-string($current-key)) {
55 | $key-exists: false;
56 | } @else {
57 | $current-map: map-get($current-map, to-string($current-key));
58 | }
59 | }
60 | }
61 |
62 | @if not $key-exists {
63 | $_: set($definition...);
64 | }
65 |
66 | @return $definition;
67 |
68 | }
69 |
70 |
71 | /// Calls `set-default`
72 | ///
73 | /// @group 3_tokens
74 | ///
75 | /// @requires {function} set-default
76 | ///
77 | /// @param {ArgList} $args - Args for `set-default`
78 | ///
79 | /// @example
80 | /// // Sets a default value
81 | /// @include set-default(baseline, 1rem);
82 | ///
83 | /// get(baseline)
84 | /// // => 1rem
85 | ///
86 | /// // Updates the value
87 | /// @include set(baseline, 1.25rem);
88 | ///
89 | /// get(baseline)
90 | /// // => 1.25rem
91 | ///
92 | /// // Doesn't update the value since it already exists
93 | /// @include set-default(baseline, 1rem);
94 | ///
95 | /// get(baseline)
96 | /// // => 1.25rem
97 |
98 | @mixin set-default($args...) {
99 | $_: set-default($args...);
100 | }
101 |
--------------------------------------------------------------------------------
/lib/tokens/set.scss:
--------------------------------------------------------------------------------
1 | /// Sets or updates a value of a key in the stylesheet tokens.
2 | ///
3 | /// @group 3_tokens
4 | ///
5 | /// @requires {variable} __SCARAB
6 | /// @requires {function} to-string
7 | /// @requires {function} map-stringify-keys-deep
8 | ///
9 | /// @param {ArgList} $definition - Definition of the new value
10 | ///
11 | /// @return {ArgList} - Definition of the new value
12 | ///
13 | /// @example
14 | /// $_: set(baseline, 1.25rem);
15 | ///
16 | /// $_: set(breakpoint, (
17 | /// s : 600px,
18 | /// m : 1024px,
19 | /// l : 1300px,
20 | /// xl : 1600px
21 | /// ));
22 | ///
23 | /// get(baseline)
24 | /// // => 1.25rem
25 | ///
26 | /// get(breakpoint)
27 | /// // => (
28 | /// // small : 600px,
29 | /// // medium : 1024px,
30 | /// // large : 1300px,
31 | /// // huge : 1600px
32 | /// // )
33 | ///
34 | /// get(breakpoints, small)
35 | /// // => 600px
36 | ///
37 | /// @todo Improve performance by optimizing `map-stringify-keys-deep`
38 |
39 | @function set($definition...) {
40 |
41 | // Get a copy of the current $TOKENS state
42 | $TOKENS: map-get($__SCARAB, 'TOKENS');
43 |
44 | $result: (); // key-value pair that will be merged with $TOKENS
45 |
46 | // If there are only 2 args, we can easily determine the result
47 | @if length($definition) == 2 {
48 | $key : nth($definition, 1);
49 | $new-value : nth($definition, 2);
50 |
51 | $result: ($key: $new-value);
52 | }
53 |
54 | // For more than 2 args, we have to build the result backwards
55 | @if length($definition) > 2 {
56 |
57 | // The new value is the last arg in $definition
58 | $new-value: nth($definition, -1);
59 |
60 | // Build a list of maps preceding the new one
61 | $maps: ($TOKENS,);
62 |
63 | @for $i from 1 through length($definition) - 2 {
64 | $current-map : nth($maps, -1);
65 | $current-key : nth($definition, $i);
66 | $current-value : map-get($current-map, to-string($current-key)) or ();
67 |
68 | $maps: append($maps, $current-value);
69 | }
70 |
71 | @for $i from length($maps) through 1 {
72 | $current-map : nth($maps, $i);
73 | $current-key : nth($definition, $i);
74 | $current-value : ();
75 |
76 | @if $i == length($maps) {
77 | $current-value: $new-value;
78 | } @else {
79 | $current-value: $result;
80 | }
81 |
82 | $result: map-merge($current-map, (to-string($current-key): $current-value));
83 | }
84 | }
85 |
86 | // Update the local $TOKENS map
87 | $TOKENS: map-merge($TOKENS, map-stringify-keys-deep($result));
88 |
89 | // Merge the updated $TOKENS map back into $__SCARAB
90 | $__SCARAB: map-merge($__SCARAB, ('TOKENS': $TOKENS)) !global;
91 | @return $definition;
92 |
93 | }
94 |
95 |
96 |
97 | /// Calls `set`
98 | ///
99 | /// @group 3_tokens
100 | ///
101 | /// @requires {function} set
102 | ///
103 | /// @param {ArgList} $args - Args for `set`
104 | ///
105 | /// @example
106 | /// @include set(baseline, 1.25rem);
107 | ///
108 | /// @include set(breakpoints, (
109 | /// s : 600px,
110 | /// m : 1024px,
111 | /// l : 1300px,
112 | /// xl : 1600px
113 | /// ));
114 | ///
115 | /// @debug get(baseline); // 1.25rem
116 | ///
117 | /// @debug get(breakpoints);
118 | /// // => (
119 | /// // small : 600px,
120 | /// // medium : 1024px,
121 | /// // large : 1300px,
122 | /// // huge : 1600px
123 | /// // )
124 | ///
125 | /// @debug get(breakpoints, small); // 600px
126 |
127 | @mixin set($args...) {
128 | $_: set($args...);
129 | }
130 |
--------------------------------------------------------------------------------
/lib/tokens/unset.scss:
--------------------------------------------------------------------------------
1 | /// Removes a key-value pair from the stylesheet tokens.
2 | ///
3 | /// @group 3_tokens
4 | ///
5 | /// @requires {variable} __SCARAB
6 | /// @requires {function} set
7 | /// @requires {function} list-each
8 | /// @requires {function} list-remove
9 | ///
10 | /// @param {ArgList} $path - Path to the key to remove
11 | ///
12 | /// @return {ArgList} - Path to the key to remove
13 | ///
14 | /// @example
15 | /// $_: set(breakpoint, (
16 | /// small : 600px,
17 | /// medium : 1024px,
18 | /// large : 1300px,
19 | /// huge : 1600px
20 | /// ) );
21 | ///
22 | /// $_: unset(breakpoint, medium);
23 | ///
24 | /// @debug get(breakpoint);
25 | /// // => (
26 | /// // small : 600px,
27 | /// // large : 1300px,
28 | /// // huge : 1600px
29 | /// // )
30 |
31 | @function unset($path...) {
32 |
33 | // Get a copy of the current $TOKENS state
34 | $TOKENS: map-get($__SCARAB, 'TOKENS');
35 |
36 | @if length($path) == 1 {
37 | $key: nth($path, 1);
38 |
39 | $TOKENS: map-remove($TOKENS, to-string($key));
40 | $__SCARAB: map-merge($__SCARAB, ('TOKENS': $TOKENS)) !global;
41 | }
42 |
43 | @else if length($path) > 1 {
44 | $path : list-each($path, to-string);
45 | $last-key : nth($path, -1);
46 | $key-address : list-remove($path, $last-key);
47 | $last-map : map-remove(get($key-address...), $last-key);
48 | $definition : ();
49 |
50 | @each $key in $key-address {
51 | $definition: append($definition, $key);
52 | }
53 |
54 | $definition: append($definition, $last-map);
55 |
56 | $_: set($definition...);
57 | }
58 |
59 | @return $path;
60 |
61 | }
62 |
63 |
64 |
65 | /// Calls `unset`
66 | ///
67 | /// @group 3_tokens
68 | ///
69 | /// @requires {function} unset
70 | ///
71 | /// @param {ArgList} $args - Args for `unset`
72 | ///
73 | /// @example
74 | /// @include set(breakpoint, (
75 | /// small : 600px,
76 | /// medium : 1024px,
77 | /// large : 1300px,
78 | /// huge : 1600px
79 | /// ) );
80 | ///
81 | /// @include unset(breakpoint, medium);
82 | ///
83 | /// @debug get(breakpoint);
84 | /// // (
85 | /// // small : 600px,
86 | /// // large : 1300px,
87 | /// // huge : 1600px
88 | /// // )
89 |
90 | @mixin unset($args...) {
91 | $_: unset($args...);
92 | }
93 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@scarab/core",
3 | "version": "7.0.0-rc.7",
4 | "description": "Sass library for rapid stylesheet development",
5 | "keywords": [
6 | "sass",
7 | "scss",
8 | "design tokens",
9 | "library",
10 | "helpers",
11 | "mixins",
12 | "responsive",
13 | "front-end"
14 | ],
15 | "main": "_.scss",
16 | "scripts": {
17 | "start": "onchange \"lib/**/*\" \"test/**/*\" \"*.scss\" -- npm test || true",
18 | "watch:mocha": "onchange \"lib/**/*\" \"test/**/*\" \"*.scss\" -- npm run test",
19 | "watch:node": "onchange \"lib/**/*\" \"test/**/*\" \"*.scss\" -- npm run test:node",
20 | "watch:ruby": "onchange \"lib/**/*\" \"test/**/*\" \"*.scss\" -- npm run test:ruby",
21 | "watch:sassdoc": "onchange \"lib/**/*\" \"test/**/*\" \"*.scss\" -- npm run build-sassdoc",
22 | "test:node": "clrscr && node-sass --include-path node_modules test/tests.scss || true",
23 | "test:ruby": "clrscr && sass -I node_modules test/tests.scss || true",
24 | "test": "mocha",
25 | "build": "node-sass --include-path node_modules scarab.scss -o build/",
26 | "build-sassdoc": "clrscr && sassdoc ./ --config sassdoc.yaml"
27 | },
28 | "author": "Kyle Oliveiro ",
29 | "license": "BSD-3-Clause",
30 | "repository": {
31 | "type": "git",
32 | "url": "https://github.com/kyleoliveiro/scarab-core"
33 | },
34 | "devDependencies": {
35 | "clrscr": "^1.0.4",
36 | "mocha": "^4.1.0",
37 | "node-sass": "^4.9.4",
38 | "onchange": "^3.3.0",
39 | "sass-true": "^3.1.0",
40 | "sassdoc": "^2.5.1"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/sache.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@scarab/core",
3 | "description": "Sass library for rapid stylesheet development",
4 | "tags": ["design tokens", "design system", "library", "framework", "utilities", "helpers", "responsive", "functions", "mixins", "variables"]
5 | }
6 |
--------------------------------------------------------------------------------
/sassdoc.yaml:
--------------------------------------------------------------------------------
1 | dest: ./sassdoc
2 | display:
3 | alias: false
4 | watermark: false
5 | exclude:
6 | - node_modules/**/*
7 | - build/**/*
8 | - test/**/*
9 | - docs/**/*
10 | groups:
11 | 0_variables: Variables
12 | 1_options: Options
13 | 2_constants: Constants
14 | 3_tokens: Stylesheet tokens
15 | 4_token-helpers: Token helpers
16 | 5_functions: Pure functions
17 | 6_mixins: Mixins
18 | verbose: true
19 | basePath: https://github.com/kyleoliveiro/scarab-core/tree/master
20 | googleAnalytics: UA-106098263-1
21 |
--------------------------------------------------------------------------------
/scarab-logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/test/constants/_.scss:
--------------------------------------------------------------------------------
1 | @import 'const';
2 | @import 'define';
3 |
4 | // Reset $__SCARAB
5 | @import '../../lib/options/_init';
6 | @import '../../lib/constants/_init';
7 | @import '../../lib/tokens/_init';
8 |
--------------------------------------------------------------------------------
/test/constants/const.scss:
--------------------------------------------------------------------------------
1 | @include describe('const [func]') {
2 |
3 | @include it('Returns a value from the `CONSTANTS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (),
6 | 'CONSTANTS': (
7 | 'c' : 299792458,
8 | 'g' : 9.80665,
9 | 'e' : 2.71828182845904523536028747135266249775724709369995,
10 | 'pi' : 3.1415926535897932384626433832795028841971693993751,
11 | 'phi' : 1.6180339887498,
12 | 'ln10' : 2.302585092994046,
13 | 'ln2' : 0.6931471805599453,
14 | 'log10e' : 0.4342944819032518,
15 | 'log2e' : 1.4426950408889634,
16 | 'sqrt1_2' : 0.7071067811865476,
17 | 'sqrt2' : 1.4142135623730951,
18 | 'min_z_index' : -2147483647,
19 | 'max_z_index' : 2147483647,
20 | 'sort_order' : (
21 | "!" "#" "$" "%" "&" "'" "(" ")" "*" "+" "," "-" "." "/" "[" "\\" "]" "^"
22 | "_" "{" "|" "}" "~" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "a" "b" "c"
23 | "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u"
24 | "v" "w" "x" "y" "z"
25 | ),
26 | 'custom' : (
27 | 'red' : 1
28 | )
29 | )
30 | ) !global;
31 |
32 |
33 | @include assert-equal(
34 | const(pi),
35 | 3.1415926535897932384626433832795028841971693993751,
36 | 'Root-level constant'
37 | );
38 |
39 | @include assert-equal(
40 | const(custom, red),
41 | 1,
42 | 'Nested constant'
43 | );
44 |
45 | @include assert-equal(
46 | const(custom, 'red'),
47 | 1,
48 | 'Use single quoted keys'
49 | );
50 |
51 | @include assert-equal(
52 | const(custom, "red"),
53 | 1,
54 | 'Use double quoted keys'
55 | );
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/test/constants/define.scss:
--------------------------------------------------------------------------------
1 | @include describe('define [func]') {
2 |
3 | @include it('Defines a new constant') {
4 | $__SCARAB: (
5 | 'CONSTANTS': ()
6 | ) !global;
7 |
8 | @include define(custom, 100);
9 |
10 | @include assert-equal(
11 | inspect($__SCARAB),
12 | inspect((
13 | 'CONSTANTS': (
14 | 'custom': 100
15 | )
16 | ))
17 | );
18 |
19 |
20 |
21 | $__SCARAB: (
22 | 'CONSTANTS': ()
23 | ) !global;
24 |
25 | @include define(custom2, a, blue, 1);
26 |
27 | @include assert-equal(
28 | inspect($__SCARAB),
29 | inspect((
30 | 'CONSTANTS': (
31 | 'custom2': (
32 | 'a': (
33 | 'blue': 1
34 | )
35 | )
36 | )
37 | )),
38 | 'Defines a nested constant'
39 | );
40 |
41 |
42 |
43 | $__SCARAB: (
44 | 'CONSTANTS': (
45 | 'pi': 3.1415926535897932384626433832795028841971693993751
46 | )
47 | ) !global;
48 |
49 | @include define(pi, apple);
50 |
51 | @include assert-equal(
52 | inspect($__SCARAB),
53 | inspect((
54 | 'CONSTANTS': (
55 | 'pi': 3.1415926535897932384626433832795028841971693993751
56 | )
57 | )),
58 | 'Fails to define a constant that already exists'
59 | );
60 |
61 |
62 |
63 | $__SCARAB: (
64 | 'CONSTANTS': (
65 | 'custom': (
66 | 'a': (
67 | '1': 1,
68 | '2': 2,
69 | '3': 3
70 | )
71 | )
72 | )
73 | ) !global;
74 |
75 | @include define(custom, a, 2, two);
76 |
77 | @include assert-equal(
78 | inspect($__SCARAB),
79 | inspect((
80 | 'CONSTANTS': (
81 | 'custom': (
82 | 'a': (
83 | '1': 1,
84 | '2': 2,
85 | '3': 3
86 | )
87 | )
88 | )
89 | )),
90 | 'Fails to define a nested constant that already exists'
91 | );
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/test/functions/_.scss:
--------------------------------------------------------------------------------
1 | @import 'throw';
2 | @import 'type-check';
3 | @import 'get-function-safe';
4 | @import 'important';
5 | @import 'is-null';
6 | @import 'to-string';
7 | @import 'to-length';
8 | @import 'to-number';
9 | @import 'to-negative';
10 | @import 'unit-strip';
11 | @import 'unit-convert';
12 | @import 'class-escape';
13 | @import 'class-sanitize';
14 | @import 'class-template';
15 | @import 'random-color';
16 | @import 'em';
17 | @import 'rem';
18 | @import 'str-compare';
19 | @import 'str-contains';
20 | @import 'str-replace';
21 | @import 'str-remove';
22 | @import 'str-escape';
23 | @import 'str-prepend';
24 | @import 'str-append';
25 | @import 'list-append';
26 | @import 'list-contains';
27 | @import 'list-each';
28 | @import 'list-prepend';
29 | @import 'list-remove';
30 | @import 'list-replace';
31 | @import 'list-reverse';
32 | @import 'list-sort';
33 | @import 'list-unique';
34 | @import 'list-every';
35 | @import 'map-append';
36 | @import 'map-prepend';
37 | @import 'map-get-key';
38 | @import 'map-flatten';
39 | @import 'map-stringify-keys';
40 | @import 'map-stringify-keys-deep';
41 | @import 'map-unique';
42 | @import 'map-each-key';
43 | @import 'map-each-value';
44 |
45 | // Reset $__SCARAB
46 | @import '../../lib/options/_init';
47 | @import '../../lib/constants/_init';
48 | @import '../../lib/tokens/_init';
49 |
50 |
--------------------------------------------------------------------------------
/test/functions/class-escape.scss:
--------------------------------------------------------------------------------
1 | @include describe('class-escape [func]') {
2 |
3 | @include it('Escapes a class name') {
4 | @include assert-equal(
5 | class-escape('blue'),
6 | 'blue',
7 | 'Returns valid class name as-is'
8 | );
9 |
10 | @include assert-equal(
11 | class-escape('$cl@ss:*(1)'),
12 | '\\$cl\\@ss\\:\\*\\(1\\)',
13 | 'Escapes special characters'
14 | );
15 |
16 | @include assert-equal(
17 | class-escape('13lue'),
18 | '\\31 3lue',
19 | 'Escapes class names beginning with a number'
20 | );
21 |
22 | @include assert-equal(
23 | class-escape('13l++ue!'),
24 | '\\31 3l\\+\\+ue\\!',
25 | 'Escapes special characters and class names beginning with a number'
26 | );
27 |
28 | @include assert-equal(
29 | class-escape('bl_ u e !'),
30 | 'bl_ue\\!',
31 | 'Removes whitespace in class names'
32 | );
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/test/functions/class-sanitize.scss:
--------------------------------------------------------------------------------
1 | @include describe('class-sanitize [func]') {
2 |
3 | @include it('Removes Scarab template placeholders from a string') {
4 | @include assert-equal(
5 | class-sanitize('{{b}}{{bp}}{{s}}{{sp}}{{rp}}opacity{{rs}}{{vp}}{{v}}--75{{ms}}{{ss}}{{bs}}'),
6 | 'opacity--75'
7 | );
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/test/functions/class-template.scss:
--------------------------------------------------------------------------------
1 | @include describe('class-template [func]') {
2 |
3 | @include it('Returns a class template with breakpoint and state placeholders') {
4 |
5 | @include assert-equal(
6 | class-template(('root': 'm')),
7 | '{{b}}{{bp}}{{s}}{{sp}}m{{ss}}{{bs}}',
8 | 'No variant, no modifier'
9 | );
10 |
11 | @include assert-equal(
12 | class-template(('root': 'm'), 'l'),
13 | '{{b}}{{bp}}{{s}}{{sp}}m-l{{ss}}{{bs}}',
14 | 'With variant, no modifier'
15 | );
16 |
17 | @include assert-equal(
18 | class-template(('root': 'm'), 'l', '0'),
19 | '{{b}}{{bp}}{{s}}{{sp}}m-l:0{{ss}}{{bs}}',
20 | 'With variant, with modifier'
21 | );
22 |
23 | @include assert-equal(
24 | class-template(('root': 'm', 'variant-prefix': '**'), 'l', '0'),
25 | '{{b}}{{bp}}{{s}}{{sp}}m**l:0{{ss}}{{bs}}',
26 | 'With variant, with modifier, with custom prefix'
27 | );
28 |
29 | @include assert-equal(
30 | class-template((
31 | 'root' : 'm',
32 | 'root-prefix' : '__',
33 | 'root-suffix' : '_!',
34 | 'variant-prefix' : '**',
35 | 'variant-suffix' : ')(',
36 | 'modifier-prefix' : '199',
37 | 'modifier-suffix' : '-+=',
38 | 'selector-format' : '{{b}}{{bp}}{{s}}{{sp}}{{v}}{{vp}}{{vs}}{{rp}}{{r}}{{rs}}{{mp}}{{m}}{{ms}}{{ss}}{{bs}}'
39 | ), 'l', '0'),
40 | '{{b}}{{bp}}{{s}}{{sp}}l**)(__m_!1990-+={{ss}}{{bs}}',
41 | 'With variant, with modifier, with custom prefixes and format'
42 | );
43 |
44 | }
45 |
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/test/functions/em.scss:
--------------------------------------------------------------------------------
1 | @include describe('em [func]') {
2 |
3 | @include it('Converts px to em') {
4 | @include assert-equal(
5 | em(32),
6 | 2em,
7 | 'Default base font size'
8 | );
9 |
10 | @include assert-equal(
11 | em(32, 10),
12 | 3.2em,
13 | 'Custom base font size'
14 | );
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/test/functions/get-function-safe.scss:
--------------------------------------------------------------------------------
1 | @include describe('get-function-safe [func]') {
2 |
3 | @include it('Safely calls native `get-function` if supported') {
4 | // Expect {func} if `get-function` is supported.
5 | // Otherwise, expect a {string}
6 | @if function-exists('get-function') {
7 | @include assert-equal(
8 | get-function-safe('rgb'),
9 | get-function('rgb'),
10 | 'Current Sass compiler supports `get-function()`'
11 | );
12 | } @else {
13 | @include assert-equal(
14 | get-function-safe('rgb'),
15 | 'rgb',
16 | 'Current Sass compuler does not support `get-function()`'
17 | );
18 | }
19 | }
20 |
21 | @include it('Can be used safely with `call()`') {
22 | @include assert-equal(
23 | call(get-function-safe('str-length'), 'hello world'),
24 | 11
25 | );
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/test/functions/important.scss:
--------------------------------------------------------------------------------
1 | @include describe('important [func]') {
2 |
3 |
4 | @include it('Returns returns null when $output is null') {
5 | @include assert-equal(
6 | important(null),
7 | null
8 | );
9 | }
10 |
11 | @include it('Returns returns null when $output is false') {
12 | @include assert-equal(
13 | important(false),
14 | null
15 | );
16 | }
17 |
18 | @include it('Returns returns `!important` when $output is true') {
19 | @include assert-equal(
20 | important(true),
21 | '!important'
22 | );
23 | }
24 |
25 | @include it('Returns returns `!important` when output.important option is true') {
26 | $_: set-option(output, important, true);
27 |
28 | @include assert-equal(
29 | important(),
30 | '!important'
31 | );
32 | }
33 |
34 | @include it('Returns returns null when output.important option is false') {
35 | $_: set-option(output, important, false);
36 |
37 | @include assert-equal(
38 | important(),
39 | null
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/functions/is-null.scss:
--------------------------------------------------------------------------------
1 | @include describe('is-null [func]') {
2 |
3 | @include it('Returns whether the specified value is `null`') {
4 | @include assert-true(
5 | is-null(null),
6 | 'Null is null'
7 | );
8 |
9 | @include assert-false(
10 | is-null(false),
11 | 'false is not null'
12 | );
13 |
14 | @include assert-false(
15 | is-null(0),
16 | '0 is not null'
17 | );
18 |
19 | @include assert-false(
20 | is-null(''),
21 | 'Empty string is not null'
22 | );
23 |
24 | $list: [];
25 | @include assert-false(
26 | is-null($list),
27 | 'Empty list is not null'
28 | );
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/test/functions/list-append.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-append [func]') {
2 |
3 | @include it('Appends a single value to the end of a list') {
4 | @include assert-equal(
5 | list-append(1 2, 3),
6 | (1 2 3),
7 | 'Supports space lists'
8 | );
9 |
10 | @include assert-equal(
11 | list-append((1, 2), 3),
12 | (1, 2, 3),
13 | 'Supports comma lists'
14 | );
15 |
16 | @include assert-equal(
17 | list-append([1 2], 3),
18 | [1 2 3],
19 | 'Supports bracketed space lists'
20 | );
21 |
22 | @include assert-equal(
23 | list-append([1, 2], 3),
24 | [1, 2, 3],
25 | 'Supports bracketed comma lists'
26 | );
27 | }
28 |
29 | @include it('Appends multiple values to the end of a list') {
30 | @include assert-equal(
31 | list-append(1 2, 3, 4, 5 6),
32 | (1 2 3 4 (5 6)),
33 | 'Supports space lists'
34 | );
35 |
36 | @include assert-equal(
37 | list-append((1, 2), 3, 4, (5, 6)),
38 | (1, 2, 3, 4, (5, 6)),
39 | 'Supports comma lists'
40 | );
41 |
42 | @include assert-equal(
43 | list-append([1 2], 3, 4, [5 6]),
44 | [1 2 3 4 [5 6]],
45 | 'Supports bracketed space lists'
46 | );
47 |
48 | @include assert-equal(
49 | list-append([1, 2], 3, 4, [5, 6]),
50 | [1, 2, 3, 4, [5, 6]],
51 | 'Supports bracketed comma lists'
52 | );
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/test/functions/list-contains.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-contains [func]') {
2 |
3 | @include it('Returns true if a list contains a value') {
4 | @include assert-true(
5 | list-contains(1 2 3, 2),
6 | 'Supports space lists'
7 | );
8 |
9 | @include assert-true(
10 | list-contains((1, 2, 3), 2),
11 | 'Supports comma lists'
12 | );
13 |
14 | @include assert-true(
15 | list-contains([1 2 3], 2),
16 | 'Supports bracketed space lists'
17 | );
18 |
19 | @include assert-true(
20 | list-contains([1, 2, 3], 2),
21 | 'Supports bracketed comma lists'
22 | );
23 | }
24 |
25 | @include it('Returns false if a list does not contain a value') {
26 | @include assert-false(
27 | list-contains(1 2 3, 4),
28 | 'Supports space lists'
29 | );
30 |
31 | @include assert-false(
32 | list-contains((1, 2, 3), 4),
33 | 'Supports comma lists'
34 | );
35 |
36 | @include assert-false(
37 | list-contains([1 2 3], 4),
38 | 'Supports bracketed space lists'
39 | );
40 |
41 | @include assert-false(
42 | list-contains([1, 2, 3], 4),
43 | 'Supports bracketed comma lists'
44 | );
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/test/functions/list-each.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-each [func]') {
2 |
3 | @include it('Calls a function on each item in a list') {
4 | @include assert-equal(
5 | list-each(1.2 2.5 3.7, 'round'),
6 | (1 3 4),
7 | 'Supports space lists'
8 | );
9 |
10 | @include assert-equal(
11 | list-each((1.2, 2.5, 3.7), 'round'),
12 | (1, 3, 4),
13 | 'Supports comma lists'
14 | );
15 |
16 | @include assert-equal(
17 | list-each([1.2 2.5 3.7], 'round'),
18 | [1 3 4],
19 | 'Supports bracketed space lists'
20 | );
21 |
22 | @include assert-equal(
23 | list-each([1.2, 2.5, 3.7], 'round'),
24 | [1, 3, 4],
25 | 'Supports bracketed comma lists'
26 | );
27 | }
28 |
29 | @include it('Supports passing args to the called function') {
30 | @include assert-equal(
31 | list-each(('hello', 'world'), 'str-insert', ('123', 1)),
32 | ('123hello', '123world')
33 | );
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/test/functions/list-every.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-every [func]') {
2 |
3 | @include it('Checks if every value in a list returns true for a given function') {
4 | @include assert-true(
5 | list-every(1.2 2.5 3.7, 'unitless')
6 | );
7 |
8 | @include assert-false(
9 | list-every(1.2 2.5rem 3.7, 'unitless')
10 | );
11 | }
12 |
13 | @include it('Supports passing args to the called function') {
14 | @include assert-equal(
15 | true,
16 | true
17 | );
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/test/functions/list-prepend.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-prepend [func]') {
2 |
3 | @include it('Prepends a single value to the start of a list') {
4 | @include assert-equal(
5 | list-prepend(10px 20px, 30px),
6 | (30px 10px 20px),
7 | 'Supports space lists'
8 | );
9 |
10 | @include assert-equal(
11 | list-prepend((10px, 20px), 30px),
12 | (30px, 10px, 20px),
13 | 'Supports comma lists'
14 | );
15 |
16 | @include assert-equal(
17 | list-prepend([10px 20px], 30px),
18 | [30px 10px 20px],
19 | 'Supports bracketed space lists'
20 | );
21 |
22 | @include assert-equal(
23 | list-prepend([10px, 20px], 30px),
24 | [30px, 10px, 20px],
25 | 'Supports bracketed comma lists'
26 | );
27 | }
28 |
29 | @include it('Prepends multiple values to the start of a list') {
30 | @include assert-equal(
31 | list-prepend(1 2, 3, 4, 5 6),
32 | ((5 6) 4 3 1 2),
33 | 'Supports space lists'
34 | );
35 |
36 | @include assert-equal(
37 | list-prepend((1, 2), 3, 4, (5, 6)),
38 | ((5, 6), 4, 3, 1, 2),
39 | 'Supports comma lists'
40 | );
41 |
42 | @include assert-equal(
43 | list-prepend([1 2], 3, 4, [5 6]),
44 | [[5 6] 4 3 1 2],
45 | 'Supports bracketed space lists'
46 | );
47 |
48 | @include assert-equal(
49 | list-prepend([1, 2], 3, 4, [5, 6]),
50 | [[5, 6], 4, 3, 1, 2],
51 | 'Supports bracketed comma lists'
52 | );
53 | }
54 | }
--------------------------------------------------------------------------------
/test/functions/list-remove.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-remove [func]') {
2 |
3 | @include it('Removes the first occurance of a value in a list') {
4 | @include assert-equal(
5 | list-remove(1 2 3 1 2 3, 2),
6 | 1 3 1 2 3,
7 | 'Supports space lists'
8 | );
9 |
10 | @include assert-equal(
11 | list-remove((1, 2, 3, 1, 2, 3), 2),
12 | (1, 3, 1, 2, 3),
13 | 'Supports comma lists'
14 | );
15 |
16 | @include assert-equal(
17 | list-remove([1 2 3 1 2 3], 2),
18 | [1 3 1 2 3],
19 | 'Supports bracketed space lists'
20 | );
21 |
22 | @include assert-equal(
23 | list-remove([1, 2, 3, 1, 2, 3], 2),
24 | [1, 3, 1, 2, 3],
25 | 'Supports bracketed comma lists'
26 | );
27 | }
28 |
29 | @include it('Removes all occurances of a value in a list') {
30 | @include assert-equal(
31 | list-remove(1 2 3 1 2 3, 2, true),
32 | 1 3 1 3,
33 | 'Support space lists'
34 | );
35 |
36 | @include assert-equal(
37 | list-remove((1, 2, 3, 1, 2, 3), 2, true),
38 | (1, 3, 1, 3),
39 | 'Support comma lists'
40 | );
41 |
42 | @include assert-equal(
43 | list-remove([1 2 3 1 2 3], 2, true),
44 | [1 3 1 3],
45 | 'Support bracketed lists'
46 | );
47 |
48 | @include assert-equal(
49 | list-remove([1, 2, 3, 1, 2, 3], 2, true),
50 | [1, 3, 1, 3],
51 | 'Support bracketed comma lists'
52 | );
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/test/functions/list-replace.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-replace [func]') {
2 |
3 | @include it('Replaces the first occurance of a value in a list') {
4 | @include assert-equal(
5 | list-replace(1 2 2 2 3, 2, 4),
6 | 1 4 2 2 3,
7 | 'Supports space lists'
8 | );
9 |
10 | @include assert-equal(
11 | list-replace((1, 2, 2, 2, 3), 2, 4),
12 | (1, 4, 2, 2, 3),
13 | 'Supports comma lists'
14 | );
15 |
16 | @include assert-equal(
17 | list-replace([1 2 2 2 3], 2, 4),
18 | [1 4 2 2 3],
19 | 'Supports bracketed space lists'
20 | );
21 |
22 | @include assert-equal(
23 | list-replace([1, 2, 2, 2, 3], 2, 4),
24 | [1, 4, 2, 2, 3],
25 | 'Supports bracketed comma lists'
26 | );
27 | }
28 |
29 | @include it('Replaces all occurances of a value in a list') {
30 | @include assert-equal(
31 | list-replace(1 2 3 1 1 1 2 2 2 3 3 3, 2, 4, true),
32 | 1 4 3 1 1 1 4 4 4 3 3 3,
33 | 'Support space lists'
34 | );
35 |
36 | @include assert-equal(
37 | list-replace((1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3), 2, 4, true),
38 | (1, 4, 3, 1, 1, 1, 4, 4, 4, 3, 3, 3),
39 | 'Support comma lists'
40 | );
41 |
42 | @include assert-equal(
43 | list-replace([1 2 3 1 1 1 2 2 2 3 3 3], 2, 4, true),
44 | [1 4 3 1 1 1 4 4 4 3 3 3],
45 | 'Support bracketed lists'
46 | );
47 |
48 | @include assert-equal(
49 | list-replace([1, 2, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3], 2, 4, true),
50 | [1, 4, 3, 1, 1, 1, 4, 4, 4, 3, 3, 3],
51 | 'Support bracketed comma lists'
52 | );
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/test/functions/list-reverse.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-reverse [func]') {
2 |
3 | @include it('Reverses items in a list') {
4 | @include assert-equal(
5 | list-reverse(b c a d),
6 | d a c b,
7 | 'Supports space lists'
8 | );
9 |
10 | @include assert-equal(
11 | list-reverse((b, c, a, d)),
12 | (d, a, c, b),
13 | 'Supports comma lists'
14 | );
15 |
16 | @include assert-equal(
17 | list-reverse([b c a d]),
18 | [d a c b],
19 | 'Supports bracketed space lists'
20 | );
21 |
22 | @include assert-equal(
23 | list-reverse([b, c, a, d]),
24 | [d, a, c, b],
25 | 'Supports bracketed comma lists'
26 | );
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/test/functions/list-sort.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-sort [func]') {
2 |
3 | @include it('Sorts strings in a list') {
4 | @include assert-equal(
5 | list-sort(b c a d),
6 | a b c d,
7 | 'Supports space lists'
8 | );
9 |
10 | @include assert-equal(
11 | list-sort((b, c, a, d)),
12 | (a, b, c, d),
13 | 'Supports comma lists'
14 | );
15 |
16 | @include assert-equal(
17 | list-sort([b c a d]),
18 | [a b c d],
19 | 'Supports bracketed space lists'
20 | );
21 |
22 | @include assert-equal(
23 | list-sort([b, c, a, d]),
24 | [a, b, c, d],
25 | 'Supports bracketed comma lists'
26 | );
27 | }
28 |
29 | @include it('Sorts numbers in a list') {
30 | @include assert-equal(
31 | list-sort(2 4 1 3),
32 | 1 2 3 4,
33 | 'Supports space lists'
34 | );
35 |
36 | @include assert-equal(
37 | list-sort((2, 4, 1, 3)),
38 | (1, 2, 3, 4),
39 | 'Supports comma lists'
40 | );
41 |
42 | @include assert-equal(
43 | list-sort([2 4 1 3]),
44 | [1 2 3 4],
45 | 'Supports bracketed space lists'
46 | );
47 |
48 | @include assert-equal(
49 | list-sort([2, 4, 1, 3]),
50 | [1, 2, 3, 4],
51 | 'Supports bracketed comma lists'
52 | );
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/test/functions/list-unique.scss:
--------------------------------------------------------------------------------
1 | @include describe('list-unqiue [func]') {
2 |
3 | @include it('Removes duplicate values from a list') {
4 | @include assert-equal(
5 | list-unique((1 a (b: 3) cyan a cyan 1 2 3 red (b: 3))),
6 | (1 a (b: 3) cyan 2 3 red),
7 | 'Supports space lists'
8 | );
9 |
10 | @include assert-equal(
11 | list-unique((1, a, (b: 3), cyan, a, cyan, 1, 2, 3, red, (b: 3))),
12 | (1, a, (b: 3), cyan, 2, 3, red),
13 | 'Supports comma lists'
14 | );
15 |
16 | @include assert-equal(
17 | list-unique([1 a (b: 3) cyan a cyan 1 2 3 red (b: 3)]),
18 | ([1 a (b: 3) cyan 2 3 red]),
19 | 'Supports bracketed space lists'
20 | );
21 |
22 | @include assert-equal(
23 | list-unique([1, a, (b: 3), cyan, a, cyan, 1, 2, 3, red, (b: 3)]),
24 | ([1, a, (b: 3), cyan, 2, 3, red]),
25 | 'Supports bracketed comma lists'
26 | );
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/test/functions/map-append.scss:
--------------------------------------------------------------------------------
1 | @include describe('map-append [func]') {
2 |
3 | @include it('Appends a single key-value pair onto the end of a map') {
4 | @include assert-equal(
5 | map-append((a: 1, b: 2), c, 3),
6 | (a: 1, b: 2, c: 3)
7 | );
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/test/functions/map-each-key.scss:
--------------------------------------------------------------------------------
1 | @include describe('map-each-key [func]') {
2 |
3 | @include it('Calls a function on each key in a map') {
4 | @include assert-equal(
5 | map-each-key((
6 | a : 1,
7 | b : 2,
8 | c : 3
9 | ), 'to-upper-case'),
10 | (
11 | A : 1,
12 | B : 2,
13 | C : 3
14 | )
15 | );
16 | }
17 |
18 | @include it('Supports passing args to the called function') {
19 | @include assert-equal(
20 | map-each-key((
21 | 'apple' : 1,
22 | 'orange' : 2,
23 | 'banana' : 3
24 | ), 'str-replace', ('a', '4', true)),
25 | (
26 | '4pple' : 1,
27 | 'or4nge' : 2,
28 | 'b4n4n4' : 3
29 | )
30 | );
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/test/functions/map-each-value.scss:
--------------------------------------------------------------------------------
1 | @include describe('map-each-value [func]') {
2 |
3 | @include it('Calls a function on each value in a map') {
4 | @include assert-equal(
5 | map-each-value((
6 | 1 : 1.1,
7 | 'a' : 2.5,
8 | blue : 3.7
9 | ), 'round'),
10 | (
11 | 1 : 1,
12 | 'a' : 3,
13 | blue : 4
14 | )
15 | );
16 | }
17 |
18 | @include it('Supports passing args to the called function') {
19 | @include assert-equal(
20 | map-each-value((
21 | a : 'apple',
22 | b : 'orange',
23 | c : 'banana'
24 | ), 'str-replace', ('a', '4', true)),
25 | (
26 | a : '4pple',
27 | b : 'or4nge',
28 | c : 'b4n4n4'
29 | )
30 | );
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/test/functions/map-flatten.scss:
--------------------------------------------------------------------------------
1 | @include describe('map-flatten [func]') {
2 |
3 | @include it('Flattens a map one level deep') {
4 | @include assert-equal(
5 | map-flatten((
6 | 'blue': #0000ff,
7 | 'red': (
8 | '1': #ff0000,
9 | '2': #cc0000
10 | ),
11 | 'cyan': (
12 | '1': (
13 | 'a': #00ffff,
14 | 'b': #00cccc
15 | ),
16 | '2': (
17 | 'a': #00ffff,
18 | 'b': #00cccc
19 | )
20 | )
21 | )),
22 | (
23 | 'blue': #0000ff,
24 | 'red-1': #ff0000,
25 | 'red-2': #cc0000,
26 | 'cyan-1': (
27 | 'a': #00ffff,
28 | 'b': #00cccc
29 | ),
30 | 'cyan-2': (
31 | 'a': #00ffff,
32 | 'b': #00cccc
33 | )
34 | )
35 | );
36 | }
37 |
38 | @include it('Accepts a custom separator') {
39 | @include assert-equal(
40 | map-flatten((
41 | 'blue': #0000ff,
42 | 'red': (
43 | '1': #ff0000,
44 | '2': #cc0000
45 | ),
46 | 'cyan': (
47 | '1': (
48 | 'a': #00ffff,
49 | 'b': #00cccc
50 | ),
51 | '2': (
52 | 'a': #00ffff,
53 | 'b': #00cccc
54 | )
55 | )
56 | ), '@='),
57 | (
58 | 'blue': #0000ff,
59 | 'red@=1': #ff0000,
60 | 'red@=2': #cc0000,
61 | 'cyan@=1': (
62 | 'a': #00ffff,
63 | 'b': #00cccc
64 | ),
65 | 'cyan@=2': (
66 | 'a': #00ffff,
67 | 'b': #00cccc
68 | )
69 | )
70 | );
71 | }
72 |
73 | @include it('Does not generate variant for default key') {
74 | @include assert-equal(
75 | map-flatten((
76 | transparent: transparent,
77 | grey: (
78 | _: #cccccc,
79 | 1: #999999,
80 | 2: #333333
81 | )
82 | )),
83 | (
84 | transparent: transparent,
85 | grey: #cccccc,
86 | grey-1: #999999,
87 | grey-2: #333333
88 | )
89 | );
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/test/functions/map-get-key.scss:
--------------------------------------------------------------------------------
1 | @include describe('map-get-key [func]') {
2 |
3 | @include it('Returns the key(s) in a map associated with a given value.') {
4 | @include assert-equal(
5 | map-get-key((a: 1, b: 2, c: 3), 2),
6 | (b,),
7 | 'Single matching key'
8 | );
9 |
10 | @include assert-equal(
11 | map-get-key((a: 1, b: 2, c: 2), 2),
12 | (b, c),
13 | 'Multiple matching keys'
14 | );
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/test/functions/map-prepend.scss:
--------------------------------------------------------------------------------
1 | @include describe('map-prepend [func]') {
2 |
3 | @include it('Prepends a single key-value pair onto the start of a map') {
4 | @include assert-equal(
5 | map-prepend((a: 1, b: 2), c, 3),
6 | (c: 3, a: 1, b: 2)
7 | );
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/test/functions/map-stringify-keys-deep.scss:
--------------------------------------------------------------------------------
1 | @include describe('map-stringify-keys-deep [func]') {
2 |
3 | @include it('Converts keys of nested maps') {
4 | @include assert-equal(
5 | map-stringify-keys-deep((
6 | #000000: (
7 | red: (
8 | 1: 1,
9 | 2: (
10 | blue: 1
11 | )
12 | ),
13 | 2: 2,
14 | a: 3
15 | ),
16 | white: 2
17 | )),
18 | (
19 | '#000000': (
20 | 'red': (
21 | '1': 1,
22 | '2': (
23 | 'blue': 1
24 | )
25 | ),
26 | '2': 2,
27 | 'a': 3
28 | ),
29 | 'white': 2
30 | )
31 | );
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/test/functions/map-stringify-keys.scss:
--------------------------------------------------------------------------------
1 | @include describe('map-stringify-keys [func]') {
2 |
3 | @include it('Converts direct keys of a map to strings') {
4 | @include assert-equal(
5 | map-stringify-keys((
6 | 1: 1,
7 | a: 2,
8 | red: 3,
9 | )),
10 | (
11 | '1': 1,
12 | 'a': 2,
13 | 'red': 3
14 | )
15 | );
16 |
17 | @include assert-equal(
18 | map-stringify-keys((
19 | #000000: 1,
20 | white: 2
21 | )),
22 | (
23 | '#000000': 1,
24 | 'white': 2
25 | ),
26 | 'Converts colors'
27 | );
28 |
29 | @include assert-equal(
30 | map-stringify-keys((
31 | 1: 1,
32 | 20px: 2,
33 | 300rem: 3,
34 | 4s: 4
35 | )),
36 | (
37 | '1': 1,
38 | '20px': 2,
39 | '300rem': 3,
40 | '4s': 4
41 | ),
42 | 'Converts numbers'
43 | );
44 | }
45 |
46 | @include it('Does not convert keys of nested maps') {
47 | @include assert-equal(
48 | map-stringify-keys((
49 | #000000: (
50 | red: 1,
51 | 2: 2,
52 | a: 3
53 | ),
54 | white: 2,
55 | )),
56 | (
57 | '#000000': (
58 | red: 1,
59 | 2: 2,
60 | a: 3
61 | ),
62 | 'white': 2
63 | )
64 | );
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/test/functions/map-unique.scss:
--------------------------------------------------------------------------------
1 | @include describe('map-unique [func]') {
2 |
3 | @include it('Removes key-value pairs from a map which contain duplicate values') {
4 | @include assert-equal(
5 | map-unique((a: 1, b: 2, c: 3, d: 1, e: 1, f: 3)),
6 | (a: 1, b: 2, c: 3)
7 | );
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/test/functions/random-color.scss:
--------------------------------------------------------------------------------
1 | @include describe('random-color [func]') {
2 |
3 | @include it('Returns a random color value') {
4 | @include assert-equal(
5 | type-of(random-color()),
6 | color
7 | );
8 | }
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/test/functions/rem.scss:
--------------------------------------------------------------------------------
1 | @include describe('rem [func]') {
2 |
3 | @include it('Converts px to rem') {
4 | @include assert-equal(
5 | rem(32),
6 | 2rem,
7 | 'Default base font size'
8 | );
9 |
10 | @include assert-equal(
11 | rem(32, 10),
12 | 3.2rem,
13 | 'Custom base font size'
14 | );
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/test/functions/str-append.scss:
--------------------------------------------------------------------------------
1 | @include describe('str-append [func]') {
2 |
3 | @include it('Appends to a string') {
4 | @include assert-equal(
5 | str-append('hello', 'world'),
6 | 'helloworld',
7 | 'Single string'
8 | );
9 |
10 | @include assert-equal(
11 | str-append('hello', 'world', 'foo', 'bar'),
12 | 'helloworldfoobar',
13 | 'Multiple strings'
14 | );
15 | }
16 |
17 | @include it('Treats null as empty string') {
18 | @include assert-equal(
19 | str-append('hello', null, 'world'),
20 | 'helloworld'
21 | )
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/test/functions/str-compare.scss:
--------------------------------------------------------------------------------
1 | @include describe('str-compare [func]') {
2 |
3 | @include it('Compares two strings to determine which comes first') {
4 | @include assert-true(
5 | str-compare('a', 'b'),
6 | 'Letter `a` comes before `b`'
7 | );
8 |
9 | @include assert-false(
10 | str-compare('b', 'a'),
11 | 'Letter `b` comes before `a`'
12 | );
13 |
14 | @include assert-true(
15 | str-compare('apples', 'oranges'),
16 | '`apples` comes before `oranges`'
17 | );
18 |
19 | @include assert-false(
20 | str-compare('oranges', 'apples'),
21 | '`oranges` comes before `apples`'
22 | );
23 |
24 | @include assert-true(
25 | str-compare('room-13', 'room-24'),
26 | '`room-13` comes before `room-24`'
27 | );
28 |
29 | @include assert-false(
30 | str-compare('room-24', 'room-13'),
31 | '`room-24` comes before `room-13`'
32 | );
33 |
34 | @include assert-true(
35 | str-compare('room 13', 'room 24'),
36 | '`room 13` comes before `room 24`'
37 | );
38 |
39 | @include assert-false(
40 | str-compare('room 24', 'room 13'),
41 | '`room 24` comes before `room 13`'
42 | );
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/test/functions/str-contains.scss:
--------------------------------------------------------------------------------
1 | @include describe('str-contains [func]') {
2 |
3 | @include it('Checks if a string contains a substring') {
4 | @include assert-true(
5 | str-contains('hello world', 'hello'),
6 | '`hello world` contains `hello`'
7 | );
8 |
9 | @include assert-false(
10 | str-contains('team', 'i'),
11 | '`team` does not contain `i`'
12 | );
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/test/functions/str-escape.scss:
--------------------------------------------------------------------------------
1 | @include describe('str-escape [func]') {
2 |
3 | @include it('Escapes special characters in a string') {
4 | @include assert-equal(
5 | str-escape('a@d#5!^g:g5f%)_3+='),
6 | 'a\\@d\\#5\\!\\^g\\:g5\\&\\#f\\%\\)_3\\+\\=',
7 | 'Escapes CSS special characters'
8 | );
9 |
10 | @include assert-equal(
11 | str-escape('look---_,_some_underscores_!'),
12 | 'look---_\\,_some_underscores_\\!',
13 | 'Does not escape underscores'
14 | );
15 |
16 | @include assert-equal(
17 | str-escape('😮 emoji\'s and weird stuff ♥ go unnoticed! 😀©'),
18 | '😮 emoji\\\'s and weird stuff ♥ go unnoticed\\! 😀©',
19 | 'Does not escape characters with no special meaning in CSS'
20 | )
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/test/functions/str-prepend.scss:
--------------------------------------------------------------------------------
1 | @include describe('str-prepend [func]') {
2 |
3 | @include it('Prepends to a string') {
4 | @include assert-equal(
5 | str-prepend('world', 'hello'),
6 | 'helloworld',
7 | 'Single string'
8 | );
9 |
10 | @include assert-equal(
11 | str-prepend('bar', 'foo', 'world', 'hello'),
12 | 'helloworldfoobar',
13 | 'Multiple strings'
14 | );
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/test/functions/str-remove.scss:
--------------------------------------------------------------------------------
1 | @include describe('str-remove [func]') {
2 |
3 | @include it('Removes first occurance of text in a string') {
4 | @include assert-equal(
5 | str-remove('beetle', 'e'),
6 | 'betle'
7 | );
8 | }
9 |
10 | @include it('Removes all occurances of text in a string') {
11 | @include assert-equal(
12 | str-remove('beetle', 'e', true),
13 | 'btl'
14 | );
15 | }
16 |
17 | @include it('Returns original string if no substrings are found') {
18 | @include assert-equal(
19 | str-remove('beetle', '1'),
20 | 'beetle'
21 | );
22 |
23 | @include assert-equal(
24 | str-remove('beetle', '1', true),
25 | 'beetle'
26 | );
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/test/functions/str-replace.scss:
--------------------------------------------------------------------------------
1 | @include describe('str-replace [func]') {
2 |
3 | @include it('Replaces first occurance of text in a string') {
4 | @include assert-equal(
5 | str-replace('beetle', 'e', '3'),
6 | 'b3etle',
7 | 'Replaces text'
8 | );
9 |
10 | @include assert-equal(
11 | str-replace('beetlee', 'e', 'ee'),
12 | 'beeetlee',
13 | 'Replaces text where $replace contains $search'
14 | );
15 |
16 | @include assert-equal(
17 | str-replace('beetlee', 'ee', 'ee'),
18 | 'beetlee',
19 | 'Replaces text where $replace == $search'
20 | );
21 |
22 | @include assert-equal(
23 | str-replace('beetlee', 'ee', 'e'),
24 | 'betlee',
25 | 'Replaces text where $search contains $replace'
26 | );
27 |
28 | @include assert-equal(
29 | str-replace('beetle', 'e'),
30 | 'betle',
31 | 'Removes text if no $replacement is defined'
32 | );
33 | }
34 |
35 | @include it('Replaces all occurances of text in a string') {
36 | @include assert-equal(
37 | str-replace('beetle', 'e', '3', true),
38 | 'b33tl3',
39 | 'Replaces text'
40 | );
41 |
42 | @include assert-equal(
43 | str-replace('beetlee', 'e', 'ee', true),
44 | 'beeeetleeee',
45 | 'Replaces text where $replace contains $search'
46 | );
47 |
48 | @include assert-equal(
49 | str-replace('beetlee', 'ee', 'ee', true),
50 | 'beetlee',
51 | 'Replaces text where $replace == $search'
52 | );
53 |
54 | @include assert-equal(
55 | str-replace('beetlee', 'ee', 'e', true),
56 | 'betle',
57 | 'Replaces text where $search contains $replace'
58 | );
59 |
60 | @include assert-equal(
61 | str-replace('beetle', 'e', '', true),
62 | 'btl',
63 | 'Removes text if no $replacement is defined'
64 | );
65 | }
66 |
67 | @include it('Returns original string if no substrings are found') {
68 | @include assert-equal(
69 | str-replace('beetle', '1', '3'),
70 | 'beetle'
71 | );
72 |
73 | @include assert-equal(
74 | str-replace('beetle', '1', '3', true),
75 | 'beetle'
76 | );
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/test/functions/throw.scss:
--------------------------------------------------------------------------------
1 | @include describe('throw [func]') {
2 |
3 | @include it('Throws an error') {
4 |
5 | @include assert-equal(
6 | throw('exception', 'message', false),
7 | '[exception] message'
8 | );
9 |
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/test/functions/to-length.scss:
--------------------------------------------------------------------------------
1 | @include describe('to-length [func]') {
2 |
3 | @include it('Adds a unit to a value') {
4 |
5 | @include assert-equal(
6 | to-length(10, '%'),
7 | 10%
8 | );
9 |
10 | }
11 |
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/test/functions/to-negative.scss:
--------------------------------------------------------------------------------
1 | @include describe('to-negative [func]') {
2 |
3 | @include it('Converts a value to a negative value') {
4 | @include assert-equal(
5 | to-negative(1),
6 | -1
7 | );
8 | }
9 |
10 | @include it('Converts a list containing numbers to negative values') {
11 | @include assert-equal(
12 | to-negative((a, 1, -2, 3.142)),
13 | (a, -1, -2, -3.142)
14 | );
15 | }
16 |
17 | @include it('Converts a map containing numbers to a negative value') {
18 | @include assert-equal(
19 | to-negative((a: 1, b: -2, c: (1: 5))),
20 | (a: -1, b: -2, c: (1: -5))
21 | );
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/test/functions/to-number.scss:
--------------------------------------------------------------------------------
1 | @include describe('to-number [func]') {
2 |
3 | @include it('Converts a value to a number') {
4 | @include assert-equal(
5 | to-number('10'),
6 | 10
7 | );
8 |
9 | @include assert-equal(
10 | to-number('4px'),
11 | 4px
12 | );
13 |
14 | @include assert-equal(
15 | to-number('1em'),
16 | 1em
17 | );
18 |
19 | @include assert-equal(
20 | to-number('1xxx'),
21 | 1
22 | );
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/test/functions/to-string.scss:
--------------------------------------------------------------------------------
1 | @include describe('to-string [func]') {
2 |
3 | @include it('Converts a value to an unquoted string') {
4 | @include assert-equal(
5 | to-string(false),
6 | 'false',
7 | 'Boolean'
8 | );
9 |
10 | @include assert-equal(
11 | to-string(null),
12 | 'null',
13 | 'Null'
14 | );
15 |
16 | @include assert-equal(
17 | to-string(1),
18 | '1',
19 | 'Integer'
20 | );
21 |
22 | @include assert-equal(
23 | to-string(3.142),
24 | '3.142',
25 | 'Float'
26 | );
27 |
28 | @include assert-equal(
29 | to-string(32px),
30 | '32px',
31 | 'Number with units'
32 | );
33 |
34 | @include assert-equal(
35 | to-string(blue),
36 | 'blue',
37 | 'Color'
38 | );
39 |
40 | @include assert-equal(
41 | to-string((1,2,3)),
42 | '1, 2, 3',
43 | 'Comma list'
44 | );
45 |
46 | @include assert-equal(
47 | to-string((1 2 3)),
48 | '1 2 3',
49 | 'Space list'
50 | );
51 |
52 | @include assert-equal(
53 | to-string([1,2,3]),
54 | '[1, 2, 3]',
55 | 'Comma bracket list'
56 | );
57 |
58 | @include assert-equal(
59 | to-string([1 2 3]),
60 | '[1 2 3]',
61 | 'Space bracket list'
62 | );
63 |
64 | @include assert-equal(
65 | to-string((a: 1, b: 2)),
66 | '(a: 1, b: 2)',
67 | 'Map'
68 | );
69 |
70 | @include assert-equal(
71 | to-string(hello),
72 | inspect(hello),
73 | 'Unquoted string'
74 | );
75 |
76 | @include assert-equal(
77 | to-string('hello'),
78 | inspect(hello),
79 | 'Single quoted string'
80 | );
81 |
82 | @include assert-equal(
83 | to-string("hello"),
84 | inspect(hello),
85 | 'Double quoted string'
86 | );
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/test/functions/type-check.scss:
--------------------------------------------------------------------------------
1 | @include describe('type-check [func]') {
2 |
3 | @include it('Returns true if all checks pass') {
4 | $arg1: 'a';
5 | $arg2: 2;
6 | $arg3: red;
7 |
8 | @include assert-true(
9 | type-check('func', [
10 | ($arg1: string)
11 | ], false)
12 | );
13 |
14 | @include assert-true(
15 | type-check('func', [
16 | ($arg1: string),
17 | ($arg2: number),
18 | ($arg3: color)
19 | ], false)
20 | );
21 |
22 | }
23 |
24 | @include it('Returns error string if one or more checks fail') {
25 | $arg1: 'a';
26 | $arg2: 2;
27 | $arg3: red;
28 |
29 | @include assert-equal(
30 | type-check('my-function', [
31 | ($arg1: number)
32 | ], false),
33 | '[TypeError] my-function expected {number}, was: #{$arg1} {#{type-of($arg1)}}'
34 | );
35 |
36 | @include assert-equal(
37 | type-check('my-function', [
38 | ($arg1: string),
39 | ($arg2: number),
40 | ($arg3: number)
41 | ], false),
42 | '[TypeError] my-function expected {number}, was: #{$arg3} {#{type-of($arg3)}}'
43 | );
44 |
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/test/functions/unit-convert.scss:
--------------------------------------------------------------------------------
1 | @include describe('unit-convert [func]') {
2 |
3 | @include it('Converts units of a value') {
4 | @include assert-equal(
5 | unit-convert(10px, pt),
6 | 7.5pt,
7 | 'Length'
8 | );
9 |
10 | @include assert-equal(
11 | unit-convert(42ms, 's'),
12 | 0.042s,
13 | 'Time'
14 | );
15 |
16 | @include assert-equal(
17 | unit-convert(1turn, 'deg'),
18 | 360deg,
19 | 'Rotation'
20 | );
21 |
22 | @include assert-equal(
23 | unit-convert(60Hz, 'kHz'),
24 | 0.06kHz,
25 | 'Frequency'
26 | );
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/test/functions/unit-strip.scss:
--------------------------------------------------------------------------------
1 | @include describe('unit-strip [func]') {
2 |
3 | @include it('Strips units from a number') {
4 | @include assert-equal(
5 | unit-strip(1rem),
6 | 1,
7 | 'rem'
8 | );
9 |
10 | @include assert-equal(
11 | unit-strip(2em),
12 | 2,
13 | 'em'
14 | );
15 |
16 | @include assert-equal(
17 | unit-strip(3px),
18 | 3,
19 | 'px'
20 | );
21 |
22 | @include assert-equal(
23 | unit-strip(4s),
24 | 4,
25 | 's'
26 | );
27 |
28 | @include assert-equal(
29 | unit-strip(5ms),
30 | 5,
31 | 'ms'
32 | );
33 |
34 | @include assert-equal(
35 | unit-strip(6deg),
36 | 6,
37 | 'deg'
38 | );
39 |
40 | @include assert-equal(
41 | unit-strip(-20px),
42 | -20,
43 | 'Negative number'
44 | );
45 |
46 | @include assert-equal(
47 | unit-strip(3.142px),
48 | 3.142,
49 | 'Positive float'
50 | );
51 |
52 | @include assert-equal(
53 | unit-strip(-3.142px),
54 | -3.142,
55 | 'Negative float'
56 | );
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/test/mixins/_.scss:
--------------------------------------------------------------------------------
1 | @import 'query';
2 | // @import 'extends';
3 | @import 'important';
4 | @import 'responsive';
5 | @import 'type-scale';
6 | @import 'css-ruleset';
7 |
8 | // Reset $__SCARAB
9 | @import '../../lib/options/_init';
10 | @import '../../lib/constants/_init';
11 | @import '../../lib/tokens/_init';
12 |
--------------------------------------------------------------------------------
/test/mixins/extends.scss:
--------------------------------------------------------------------------------
1 | @include describe('extends [mixin]') {
2 |
3 | @include it('Extends a class') {
4 |
5 | @include assert {
6 | @include output(false) {
7 | .bold {
8 | font-weight: bold;
9 | }
10 |
11 | .component {
12 | @include extends('bold');
13 | }
14 | }
15 |
16 | @include expect(false) {
17 | .bold,
18 | .component {
19 | font-weight: bold;
20 | }
21 | }
22 | }
23 |
24 | }
25 |
26 | }
27 |
28 |
--------------------------------------------------------------------------------
/test/mixins/important.scss:
--------------------------------------------------------------------------------
1 | @include describe('important [mixin]') {
2 |
3 | @include it('Applies `!important` to all property declarations inside it') {
4 |
5 | @include assert('Single property') {
6 | @include output {
7 | @include important((
8 | margin: 20px
9 | ));
10 | }
11 |
12 | @include expect {
13 | margin: 20px !important;
14 | }
15 | }
16 |
17 | @include assert('Multiple properties') {
18 | @include output {
19 | @include important((
20 | margin: 20px,
21 | color: red,
22 | font-weight: bold
23 | ));
24 | }
25 |
26 | @include expect {
27 | margin: 20px !important;
28 | color: red !important;
29 | font-weight: bold !important;
30 | }
31 | }
32 |
33 | }
34 |
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/test/mixins/query.scss:
--------------------------------------------------------------------------------
1 | @include describe('query [mixin]') {
2 |
3 | @include it('Wraps styles in a media query block') {
4 |
5 | @include assert('when $query is a number, generates a `min-width` media query') {
6 | @include output {
7 | @include query(30em) {
8 | color: red;
9 | }
10 | }
11 |
12 | @include expect {
13 | @media (min-width: 30em) {
14 | color: red;
15 | }
16 | }
17 | }
18 |
19 | @include assert('accepts query as a list with "from $bp" syntax') {
20 | @include output {
21 | @include query(from 30em) {
22 | color: red;
23 | }
24 | }
25 |
26 | @include expect {
27 | @media (min-width: 30em) {
28 | color: red;
29 | }
30 | }
31 | }
32 |
33 | @include assert('accepts query as a list with "above $bp" syntax') {
34 | @include output {
35 | @include query(above 30em) {
36 | color: red;
37 | }
38 |
39 | @include query(above 100px) {
40 | color: green;
41 | }
42 |
43 | @include query(above 10in) {
44 | color: blue;
45 | }
46 |
47 | @include query(above 20pt) {
48 | color: yellow;
49 | }
50 | }
51 |
52 | @include expect {
53 | @media (min-width: 30.0625em) {
54 | color: red;
55 | }
56 |
57 | @media (min-width: 101px) {
58 | color: green;
59 | }
60 |
61 | @media (min-width: 10.01042in) {
62 | color: blue;
63 | }
64 |
65 | @media (min-width: 20.75pt) {
66 | color: yellow;
67 | }
68 | }
69 | }
70 |
71 | @include assert('accepts query as a list with "until $bp" syntax') {
72 | @include output {
73 | @include query(until 30em) {
74 | color: red;
75 | }
76 | }
77 |
78 | @include expect {
79 | @media (max-width: 30em) {
80 | color: red;
81 | }
82 | }
83 | }
84 |
85 | @include assert('accepts query as a list with "below $bp" syntax') {
86 | @include output {
87 | @include query(below 30em) {
88 | color: red;
89 | }
90 |
91 | @include query(below 100px) {
92 | color: green;
93 | }
94 |
95 | @include query(below 10in) {
96 | color: blue;
97 | }
98 |
99 | @include query(below 20pt) {
100 | color: yellow;
101 | }
102 | }
103 |
104 | @include expect {
105 | @media (max-width: 29.9375em) {
106 | color: red;
107 | }
108 |
109 | @media (max-width: 99px) {
110 | color: green;
111 | }
112 |
113 | @media (max-width: 9.98958in) {
114 | color: blue;
115 | }
116 |
117 | @media (max-width: 19.25pt) {
118 | color: yellow;
119 | }
120 | }
121 | }
122 |
123 | @include assert('accepts query as a list with "from $bp1 to $bp2" syntax') {
124 | @include output {
125 | @include query(from 30em to 40em) {
126 | color: red;
127 | }
128 | }
129 |
130 | @include expect {
131 | @media (min-width: 30em) and (max-width: 40em) {
132 | color: red;
133 | }
134 | }
135 | }
136 |
137 | @include assert('accepts $query as a map with a `type` key') {
138 | @include output {
139 | @include query((
140 | type: print
141 | )) {
142 | color: red;
143 | }
144 | }
145 |
146 | @include expect {
147 | @media print {
148 | color: red;
149 | }
150 | }
151 | }
152 |
153 | @include assert('accepts $query as a map with a `condition` key') {
154 | @include output {
155 | @include query((
156 | condition: "(min-width: 30em)"
157 | )) {
158 | color: red;
159 | }
160 | }
161 |
162 | @include expect {
163 | @media (min-width: 30em) {
164 | color: red;
165 | }
166 | }
167 | }
168 |
169 | @include assert('accepts $query as a map with `type` and `condition` keys') {
170 | @include output {
171 | @include query((
172 | type: print,
173 | condition: "(min-width: 30em)"
174 | )) {
175 | color: red;
176 | }
177 | }
178 |
179 | @include expect {
180 | @media print and (min-width: 30em) {
181 | color: red;
182 | }
183 | }
184 | }
185 |
186 | }
187 |
188 | @include it('Can contain a class declaration') {
189 | @include assert {
190 | @include output {
191 | @include query(30em) {
192 | .class {
193 | color: red;
194 | }
195 | }
196 | }
197 |
198 | @include expect {
199 | @media (min-width: 30em) {
200 | .class {
201 | color: red;
202 | }
203 | }
204 | }
205 | }
206 | }
207 |
208 | }
209 |
210 |
--------------------------------------------------------------------------------
/test/mixins/responsive.scss:
--------------------------------------------------------------------------------
1 | @include describe('responsive [mixin]') {
2 |
3 | @include it('Generates responsive properties') {
4 |
5 | @include assert('Single property') {
6 | @include output {
7 | @include responsive(margin, (
8 | _ : 11px,
9 | 111px : 27px,
10 | 278px : 34px,
11 | 394px : 46px
12 | ));
13 | }
14 |
15 | @include expect {
16 | margin: 11px;
17 |
18 | @media (min-width: 111px) {
19 | margin: 27px;
20 | }
21 |
22 | @media (min-width: 278px) {
23 | margin: 34px;
24 | }
25 |
26 | @media (min-width: 394px) {
27 | margin: 46px;
28 | }
29 | }
30 | }
31 |
32 | @include assert('Multiple properties') {
33 | @include output {
34 | @include responsive((margin, padding), (
35 | _ : 11px,
36 | 111px : 27px,
37 | 278px : 34px,
38 | 394px : 46px
39 | ));
40 | }
41 |
42 | @include expect {
43 | margin: 11px;
44 | padding: 11px;
45 |
46 | @media (min-width: 111px) {
47 | margin: 27px;
48 | padding: 27px;
49 | }
50 |
51 | @media (min-width: 278px) {
52 | margin: 34px;
53 | padding: 34px;
54 | }
55 |
56 | @media (min-width: 394px) {
57 | margin: 46px;
58 | padding: 46px;
59 | }
60 | }
61 | }
62 |
63 | }
64 |
65 | @include it('Accepts breakpoint names in the breakpoint map') {
66 |
67 | @include assert {
68 |
69 | @include output {
70 | @include set(breakpoint, (
71 | small: 400px,
72 | medium: 600px,
73 | large: 900px
74 | ));
75 |
76 | @include responsive(margin, (
77 | _ : 11px,
78 | small : 27px,
79 | medium : 34px,
80 | large : 46px
81 | ));
82 | }
83 |
84 | @include expect {
85 | margin: 11px;
86 |
87 | @media (min-width: 400px) {
88 | margin: 27px;
89 | }
90 |
91 | @media (min-width: 600px) {
92 | margin: 34px;
93 | }
94 |
95 | @media (min-width: 900px) {
96 | margin: 46px;
97 | }
98 | }
99 | }
100 |
101 | }
102 |
103 | }
104 |
--------------------------------------------------------------------------------
/test/mixins/type-scale.scss:
--------------------------------------------------------------------------------
1 | @include describe('type-scale [mixin]') {
2 |
3 | @include it('Generates font-size and line-height property declarations') {
4 |
5 | @include assert('Non-responsive sizes') {
6 | @include output {
7 | $_: set(font-size, (
8 | 's': 11px,
9 | 'm': 17px,
10 | 'l': 24px
11 | ));
12 |
13 | $_: set(line-height, (
14 | 's': 16px,
15 | 'm': 25px,
16 | 'l': 36px
17 | ));
18 |
19 | @include type-scale(s);
20 | }
21 |
22 | @include expect {
23 | font-size: 11px;
24 | line-height: 16px;
25 | }
26 | }
27 |
28 | @include assert('Responsive sizes') {
29 | @include output {
30 | $_: set(breakpoint, (
31 | s: 200px,
32 | m: 444px
33 | ));
34 |
35 | $_: set(font-size, m, (
36 | _ : 16px,
37 | s : 20px,
38 | m : 55px
39 | ));
40 |
41 | $_: set(line-height, m, (
42 | _ : 20px,
43 | s : 25px,
44 | m : 64px
45 | ));
46 |
47 | @include type-scale(m);
48 | }
49 |
50 | @include expect {
51 | font-size: 16px;
52 | line-height: 20px;
53 |
54 | @media (min-width: 200px) {
55 | font-size: 20px;
56 | }
57 |
58 | @media (min-width: 444px) {
59 | font-size: 55px;
60 | }
61 |
62 | @media (min-width: 200px) {
63 | line-height: 25px;
64 | }
65 |
66 | @media (min-width: 444px) {
67 | line-height: 64px;
68 | }
69 | }
70 | }
71 |
72 | }
73 |
74 | }
75 |
76 |
--------------------------------------------------------------------------------
/test/options/_.scss:
--------------------------------------------------------------------------------
1 | @import 'option';
2 | @import 'set-option';
3 |
4 | // Reset $__SCARAB
5 | @import '../../lib/options/_init';
6 | @import '../../lib/constants/_init';
7 | @import '../../lib/tokens/_init';
8 |
9 |
--------------------------------------------------------------------------------
/test/options/option.scss:
--------------------------------------------------------------------------------
1 | @include describe('get [func]') {
2 |
3 | @include it('Returns a value from the `OPTIONS` map') {
4 | $__SCARAB: (
5 | 'OPTIONS': (
6 | 'throw-errors': true,
7 | 'namescheme' : (
8 | 'selector-format' : '{{b}}{{bp}}{{s}}{{sp}}{{rp}}{{r}}{{rs}}{{vp}}{{v}}{{vs}}{{mp}}{{m}}{{ms}}{{ss}}{{bs}}',
9 | 'default-key' : '_',
10 | 'root-prefix' : '',
11 | 'root-suffix' : '',
12 | 'variant-prefix' : '-',
13 | 'variant-suffix' : '',
14 | 'modifier-prefix' : ':',
15 | 'modifier-suffix' : '',
16 | 'breakpoint-prefix' : '(',
17 | 'breakpoint-suffix' : ')',
18 | 'state-prefix' : '(',
19 | 'state-suffix' : ')',
20 | 'states' : (
21 | 'hover' : 'hv',
22 | 'focus' : 'fc',
23 | 'active' : 'ac'
24 | ),
25 | 'directions' : (
26 | 'horizontal' : 'x',
27 | 'vertical' : 'y',
28 | 'top' : 't',
29 | 'right' : 'r',
30 | 'bottom' : 'b',
31 | 'left' : 'l'
32 | )
33 | )
34 | )
35 | ) !global;
36 |
37 |
38 | @include assert-equal(
39 | option(throw-errors),
40 | true
41 | );
42 |
43 | @include assert-equal(
44 | option(namescheme, states),
45 | (
46 | 'hover' : 'hv',
47 | 'focus' : 'fc',
48 | 'active' : 'ac'
49 | )
50 | );
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/test/test_sass.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var sassTrue = require('sass-true');
3 |
4 | var sassFile = path.join(__dirname, '/tests.scss');
5 | sassTrue.runSass({
6 | file: sassFile,
7 | includePaths: ['node_modules'],
8 | }, describe, it);
9 |
--------------------------------------------------------------------------------
/test/tests.scss:
--------------------------------------------------------------------------------
1 | // Import the True Sass unit-testing tool
2 | @import 'sass-true/sass/true';
3 |
4 | // Import Scarab
5 | @import '../lib/_';
6 |
7 | // Import tests
8 | @import 'functions/_';
9 | @import 'mixins/_';
10 | @import 'options/_';
11 | @import 'constants/_';
12 | @import 'tokens/_';
13 |
14 | @include report();
15 |
--------------------------------------------------------------------------------
/test/tokens/_.scss:
--------------------------------------------------------------------------------
1 | @import 'get';
2 | @import 'set';
3 | @import 'set-default';
4 | @import 'unset';
5 | @import 'helpers/_';
6 |
7 | // Reset $__SCARAB
8 | @import '../../lib/options/_init';
9 | @import '../../lib/constants/_init';
10 | @import '../../lib/tokens/_init';
11 |
12 |
--------------------------------------------------------------------------------
/test/tokens/get.scss:
--------------------------------------------------------------------------------
1 | @include describe('get [func]') {
2 |
3 | @include it('Returns a value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'baseline': 1rem,
7 | 'palettes': (
8 | 'blue': (
9 | 'light' : #9999ff,
10 | 'base' : #6666cc,
11 | 'dark' : #000099
12 | )
13 | )
14 | ),
15 | 'CONSTANTS': ()
16 | ) !global;
17 |
18 |
19 | @include assert-equal(
20 | get(baseline),
21 | 1rem
22 | );
23 |
24 | @include assert-equal(
25 | get(palettes, blue),
26 | (
27 | 'light' : #9999ff,
28 | 'base' : #6666cc,
29 | 'dark' : #000099
30 | ),
31 | 'Supports keys that are color names'
32 | );
33 |
34 | @include assert-equal(
35 | get(palettes, blue, dark),
36 | #000099,
37 | 'Returns nested values'
38 | );
39 |
40 | @include assert-equal(
41 | get('palettes', 'blue', 'dark'),
42 | #000099,
43 | 'Supports single quoted keys'
44 | );
45 |
46 | @include assert-equal(
47 | get("palettes", "blue", "dark"),
48 | #000099,
49 | 'Supports double quoted keys'
50 | );
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/test/tokens/helpers/_.scss:
--------------------------------------------------------------------------------
1 | @import 'baseline';
2 | @import 'breakpoint';
3 | @import 'color';
4 | @import 'gradient';
5 | @import 'opacity';
6 | @import 'background-image';
7 | @import 'letter-spacing';
8 | @import 'line-height';
9 | @import 'font-family';
10 | @import 'font-size';
11 | @import 'font-weight';
12 | @import 'line-style';
13 | @import 'line-width';
14 | @import 'text-measure';
15 | @import 'wrapper-width';
16 | @import 'flex-grid';
17 | @import 'spacing';
18 | @import 'coordinate';
19 | @import 'ratio';
20 | @import 'angle';
21 | @import 'duration';
22 | @import 'easing';
23 | @import 'border-radius';
24 | @import 'box-shadow';
25 | @import 'text-shadow';
26 | @import 'keyframe';
27 | @import 'module';
28 |
--------------------------------------------------------------------------------
/test/tokens/helpers/angle.scss:
--------------------------------------------------------------------------------
1 | @include describe('angle [func]') {
2 |
3 | @include it('Returns a `angle` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'angle': (
7 | '0': 0,
8 | 'slant': 15deg,
9 | 'right': 90deg
10 | )
11 | )
12 | ) !global;
13 |
14 | @include assert-equal(
15 | angle(slant),
16 | 15deg
17 | );
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/test/tokens/helpers/background-image.scss:
--------------------------------------------------------------------------------
1 | @include describe('background-image [func]') {
2 |
3 | @include it('Returns a `background-image` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'background-image': (
7 | '0': none,
8 | 'tiles': url(../images/tiles.png)
9 | )
10 | )
11 | ) !global;
12 |
13 | @include assert-equal(
14 | background-image(tiles),
15 | 'url(../images/tiles.png)'
16 | );
17 | }
18 |
19 | }
20 |
21 | @include describe('bgi [func]') {
22 |
23 | @include it('Returns a `background-image` value from the `TOKENS` map') {
24 | $__SCARAB: (
25 | 'TOKENS': (
26 | 'background-image': (
27 | '0': none,
28 | 'tiles': url(../images/tiles.png)
29 | )
30 | )
31 | ) !global;
32 |
33 | @include assert-equal(
34 | bgi(tiles),
35 | 'url(../images/tiles.png)'
36 | );
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/test/tokens/helpers/baseline.scss:
--------------------------------------------------------------------------------
1 | @include describe('baseline [func]') {
2 |
3 | @include it('Returns a multiple of `get(baseline)`') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'baseline': 20px
7 | )
8 | ) !global;
9 |
10 | @include assert-equal(
11 | baseline(3),
12 | 60px,
13 | 'Positive integer'
14 | );
15 |
16 | @include assert-equal(
17 | baseline(1.5),
18 | 30px,
19 | 'Positive float'
20 | );
21 |
22 | @include assert-equal(
23 | baseline(-2),
24 | -40px,
25 | 'Negative integer'
26 | );
27 |
28 | @include assert-equal(
29 | baseline(-0.468),
30 | -9.36px,
31 | 'Negative float'
32 | );
33 | }
34 |
35 | @include it('Defaults to the baseline value if no $multiplier is defined') {
36 | $__SCARAB: (
37 | 'TOKENS': (
38 | 'baseline': 1rem
39 | )
40 | ) !global;
41 |
42 | @include assert-equal(
43 | baseline(),
44 | 1rem
45 | );
46 | }
47 |
48 | }
49 |
50 | @include describe('bl [func]') {
51 |
52 | @include it('Returns a multiple of `get(baseline)`') {
53 | $__SCARAB: (
54 | 'TOKENS': (
55 | 'baseline': 20px
56 | )
57 | ) !global;
58 |
59 | @include assert-equal(
60 | bl(3),
61 | 60px,
62 | 'Positive integer'
63 | );
64 |
65 | @include assert-equal(
66 | bl(1.5),
67 | 30px,
68 | 'Positive float'
69 | );
70 |
71 | @include assert-equal(
72 | bl(-2),
73 | -40px,
74 | 'Negative integer'
75 | );
76 |
77 | @include assert-equal(
78 | bl(-0.468),
79 | -9.36px,
80 | 'Negative float'
81 | );
82 | }
83 |
84 | @include it('Defaults to the baseline value if no $multiplier is defined') {
85 | $__SCARAB: (
86 | 'TOKENS': (
87 | 'baseline': 1rem
88 | )
89 | ) !global;
90 |
91 | @include assert-equal(
92 | bl(),
93 | 1rem
94 | );
95 | }
96 |
97 | }
98 |
99 |
--------------------------------------------------------------------------------
/test/tokens/helpers/border-radius.scss:
--------------------------------------------------------------------------------
1 | @include describe('border-radius [func]') {
2 |
3 | @include it('Returns a `border-radius` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'border-radius': (
7 | '0': linear,
8 | 'pill': 9999px,
9 | 'round': 100%
10 | )
11 | )
12 | ) !global;
13 |
14 | @include assert-equal(
15 | border-radius(pill),
16 | 9999px
17 | );
18 | }
19 |
20 | }
21 |
22 | @include describe('radius [func]') {
23 |
24 | @include it('Returns a `border-radius` value from the `TOKENS` map') {
25 | $__SCARAB: (
26 | 'TOKENS': (
27 | 'border-radius': (
28 | '0': linear,
29 | 'pill': 9999px,
30 | 'round': 100%
31 | )
32 | )
33 | ) !global;
34 |
35 | @include assert-equal(
36 | radius(pill),
37 | 9999px
38 | );
39 | }
40 |
41 | }
42 |
43 | @include describe('bdr [func]') {
44 |
45 | @include it('Returns a `border-radius` value from the `TOKENS` map') {
46 | $__SCARAB: (
47 | 'TOKENS': (
48 | 'border-radius': (
49 | '0': linear,
50 | 'pill': 9999px,
51 | 'round': 100%
52 | )
53 | )
54 | ) !global;
55 |
56 | @include assert-equal(
57 | bdr(pill),
58 | 9999px
59 | );
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/test/tokens/helpers/box-shadow.scss:
--------------------------------------------------------------------------------
1 | @include describe('box-shadow [func]') {
2 |
3 | @include it('Returns a `box-shadow` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'box-shadow': (
7 | '0': linear,
8 | 's': 0 2px 4px rgba(0,0,0,0.2),
9 | 'm': 0 3px 6px rgba(0,0,0,0.2),
10 | 'l': 0 4px 6px rgba(0,0,0,0.2)
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | box-shadow(m),
17 | 0 3px 6px rgba(0,0,0,0.2)
18 | );
19 | }
20 |
21 | }
22 |
23 | @include describe('bsh [func]') {
24 |
25 | @include it('Returns a `box-shadow` value from the `TOKENS` map') {
26 | $__SCARAB: (
27 | 'TOKENS': (
28 | 'box-shadow': (
29 | '0': linear,
30 | 's': 0 2px 4px rgba(0,0,0,0.2),
31 | 'm': 0 3px 6px rgba(0,0,0,0.2),
32 | 'l': 0 4px 6px rgba(0,0,0,0.2)
33 | )
34 | )
35 | ) !global;
36 |
37 | @include assert-equal(
38 | bsh(m),
39 | 0 3px 6px rgba(0,0,0,0.2)
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/tokens/helpers/breakpoint.scss:
--------------------------------------------------------------------------------
1 | @include describe('breakpoint [func]') {
2 |
3 | @include it('Returns a `breakpoint` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'breakpoint': (
7 | 's': 25em,
8 | 'm': 40em,
9 | 'l': 65em
10 | )
11 | )
12 | ) !global;
13 |
14 | @include assert-equal(
15 | breakpoint(m),
16 | 40em
17 | );
18 | }
19 |
20 | }
21 |
22 | @include describe('bp [func]') {
23 |
24 | @include it('Returns a `breakpoint` value from the `TOKENS` map') {
25 | $__SCARAB: (
26 | 'TOKENS': (
27 | 'breakpoint': (
28 | 's': 25em,
29 | 'm': 40em,
30 | 'l': 65em
31 | )
32 | )
33 | ) !global;
34 |
35 | @include assert-equal(
36 | bp(m),
37 | 40em
38 | );
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/test/tokens/helpers/color.scss:
--------------------------------------------------------------------------------
1 | @include describe('color [func]') {
2 |
3 | @include it('Returns a `color` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'OPTIONS': (
6 | 'namescheme': (
7 | 'default-key': '_'
8 | )
9 | ),
10 | 'TOKENS': (
11 | 'color': (
12 | 'transparent': transparent,
13 | 'red': #ff0000,
14 | 'blue': (
15 | '_' : blue,
16 | '1' : #0000ff,
17 | '2' : #000099,
18 | '3' : #000033,
19 | )
20 | )
21 | ),
22 | ) !global;
23 |
24 | @include assert-equal(
25 | color(transparent),
26 | transparent,
27 | 'Single-level color'
28 | );
29 |
30 | @include assert-equal(
31 | color(red),
32 | #ff0000,
33 | 'Single-level color'
34 | );
35 |
36 | @include assert-equal(
37 | color(blue),
38 | blue,
39 | 'Default color'
40 | );
41 |
42 | @include assert-equal(
43 | color(blue, 2),
44 | #000099,
45 | 'Nested color'
46 | );
47 | }
48 |
49 | }
50 |
51 | @include describe('c [func]') {
52 |
53 | @include it('Returns a `color` value from the `TOKENS` map') {
54 | $__SCARAB: (
55 | 'OPTIONS': (
56 | 'namescheme': (
57 | 'default-key': '_'
58 | )
59 | ),
60 | 'TOKENS': (
61 | 'color': (
62 | 'transparent': transparent,
63 | 'red': #ff0000,
64 | 'blue': (
65 | '_': blue,
66 | '1': #0000ff,
67 | '2': #000099,
68 | '3': #000033,
69 | )
70 | )
71 | )
72 | ) !global;
73 |
74 | @include assert-equal(
75 | c(transparent),
76 | transparent,
77 | 'Single-level color'
78 | );
79 |
80 | @include assert-equal(
81 | c(red),
82 | #ff0000,
83 | 'Single-level color'
84 | );
85 |
86 | @include assert-equal(
87 | color(blue),
88 | blue,
89 | 'Default color'
90 | );
91 |
92 | @include assert-equal(
93 | c(blue, 2),
94 | #000099,
95 | 'Nested color'
96 | );
97 | }
98 |
99 | }
100 |
--------------------------------------------------------------------------------
/test/tokens/helpers/coordinate.scss:
--------------------------------------------------------------------------------
1 | @include describe('coordinate [func]') {
2 |
3 | @include it('Returns a `coordinate` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'coordinate': (
7 | '0': none,
8 | 's': 2rem,
9 | 'm': 4rem,
10 | 'l': 8rem
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | coordinate(l),
17 | 8rem
18 | );
19 | }
20 |
21 | }
22 |
23 | @include describe('coord [func]') {
24 |
25 | @include it('Returns a `coordinate` value from the `TOKENS` map') {
26 | $__SCARAB: (
27 | 'TOKENS': (
28 | 'coordinate': (
29 | '0': none,
30 | 's': 2rem,
31 | 'm': 4rem,
32 | 'l': 8rem
33 | )
34 | )
35 | ) !global;
36 |
37 | @include assert-equal(
38 | coord(l),
39 | 8rem
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/tokens/helpers/duration.scss:
--------------------------------------------------------------------------------
1 | @include describe('duration [func]') {
2 |
3 | @include it('Returns a `duration` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'duration': (
7 | '0': 0,
8 | 's': 0.2s,
9 | 'm': 0.5s,
10 | 'l': 1s
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | duration(m),
17 | 0.5s
18 | );
19 | }
20 |
21 | }
22 |
23 | @include describe('dur [func]') {
24 |
25 | @include it('Returns a `duration` value from the `TOKENS` map') {
26 | $__SCARAB: (
27 | 'TOKENS': (
28 | 'duration': (
29 | '0': 0,
30 | 's': 0.2s,
31 | 'm': 0.5s,
32 | 'l': 1s
33 | )
34 | )
35 | ) !global;
36 |
37 | @include assert-equal(
38 | dur(m),
39 | 0.5s
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/tokens/helpers/easing.scss:
--------------------------------------------------------------------------------
1 | @include describe('easing [func]') {
2 |
3 | @include it('Returns a `easing` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'easing': (
7 | '0': linear,
8 | 'out': ease-out,
9 | 'in': ease-in,
10 | 'out-quart': cubic-bezier(0.165, 0.84, 0.44, 1)
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | easing(out-quart),
17 | cubic-bezier(0.165, 0.84, 0.44, 1)
18 | );
19 | }
20 |
21 | }
22 |
23 | @include describe('ease [func]') {
24 |
25 | @include it('Returns a `easing` value from the `TOKENS` map') {
26 | $__SCARAB: (
27 | 'TOKENS': (
28 | 'easing': (
29 | '0': linear,
30 | 'out': ease-out,
31 | 'in': ease-in,
32 | 'out-quart': cubic-bezier(0.165, 0.84, 0.44, 1)
33 | )
34 | )
35 | ) !global;
36 |
37 | @include assert-equal(
38 | ease(out-quart),
39 | cubic-bezier(0.165, 0.84, 0.44, 1)
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/tokens/helpers/flex-grid.scss:
--------------------------------------------------------------------------------
1 | @include describe('flex-grid [func]') {
2 |
3 | @include it('Returns a `flex-grid` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'flex-grid': (
7 | 'standard': 12,
8 | 'mini': 5
9 | )
10 | )
11 | ) !global;
12 |
13 | @include assert-equal(
14 | flex-grid(standard),
15 | 12
16 | );
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/test/tokens/helpers/font-family.scss:
--------------------------------------------------------------------------------
1 | @include describe('font-family [func]') {
2 |
3 | @include it('Returns a `font-family` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'font-family': (
7 | 'sans': ('Helvetica', sans-serif),
8 | 'serif': ('Georgia', serif)
9 | )
10 | )
11 | ) !global;
12 |
13 | @include assert-equal(
14 | font-family(sans),
15 | ('Helvetica', sans-serif)
16 | );
17 | }
18 |
19 | }
20 |
21 | @include describe('ff [func]') {
22 |
23 | @include it('Returns a `font-family` value from the `TOKENS` map') {
24 | $__SCARAB: (
25 | 'TOKENS': (
26 | 'font-family': (
27 | 'sans': ('Helvetica', sans-serif),
28 | 'serif': ('Georgia', serif)
29 | )
30 | )
31 | ) !global;
32 |
33 | @include assert-equal(
34 | ff(sans),
35 | ('Helvetica', sans-serif)
36 | );
37 | }
38 |
39 | }
40 |
41 | @include describe('typeface [func]') {
42 |
43 | @include it('Returns a `font-family` value from the `TOKENS` map') {
44 | $__SCARAB: (
45 | 'TOKENS': (
46 | 'font-family': (
47 | 'sans': ('Helvetica', sans-serif),
48 | 'serif': ('Georgia', serif)
49 | )
50 | )
51 | ) !global;
52 |
53 | @include assert-equal(
54 | typeface(sans),
55 | ('Helvetica', sans-serif)
56 | );
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/test/tokens/helpers/font-size.scss:
--------------------------------------------------------------------------------
1 | @include describe('font-size [func]') {
2 |
3 | @include it('Returns a `font-size` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'font-size': (
7 | '0': 0,
8 | 'xs': 10px,
9 | 's': 13px,
10 | 'm': 16px,
11 | 'l': 19px,
12 | 'xl': 24px
13 | )
14 | )
15 | ) !global;
16 |
17 | @include assert-equal(
18 | font-size(l),
19 | 19px
20 | );
21 | }
22 |
23 | }
24 |
25 | @include describe('fz [func]') {
26 |
27 | @include it('Returns a `font-size` value from the `TOKENS` map') {
28 | $__SCARAB: (
29 | 'TOKENS': (
30 | 'font-size': (
31 | '0': 0,
32 | 'xs': 10px,
33 | 's': 13px,
34 | 'm': 16px,
35 | 'l': 19px,
36 | 'xl': 24px
37 | )
38 | )
39 | ) !global;
40 |
41 | @include assert-equal(
42 | fz(l),
43 | 19px
44 | );
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/test/tokens/helpers/font-weight.scss:
--------------------------------------------------------------------------------
1 | @include describe('font-weight [func]') {
2 |
3 | @include it('Returns a `font-weight` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'font-weight': (
7 | '0': normal,
8 | 'bold': bold,
9 | 'extrabold': 800
10 | )
11 | )
12 | ) !global;
13 |
14 | @include assert-equal(
15 | font-weight(extrabold),
16 | 800
17 | );
18 | }
19 |
20 | }
21 |
22 | @include describe('fw [func]') {
23 |
24 | @include it('Returns a `font-weight` value from the `TOKENS` map') {
25 | $__SCARAB: (
26 | 'TOKENS': (
27 | 'font-weight': (
28 | '0': normal,
29 | 'bold': bold,
30 | 'extrabold': 800
31 | )
32 | )
33 | ) !global;
34 |
35 | @include assert-equal(
36 | fw(extrabold),
37 | 800
38 | );
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/test/tokens/helpers/gradient.scss:
--------------------------------------------------------------------------------
1 | @include describe('gradient [func]') {
2 |
3 | @include it('Returns a `gradient` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'gradient': (
7 | '0': none,
8 | 'hz-white-black': linear-gradient(to right, white 0%, black 100%)
9 | )
10 | )
11 | ) !global;
12 |
13 | @include assert-equal(
14 | gradient(hz-white-black),
15 | linear-gradient(to right, white 0%, black 100%)
16 | );
17 | }
18 |
19 | }
20 |
21 | @include describe('g [func]') {
22 |
23 | @include it('Returns a `gradient` value from the `TOKENS` map') {
24 | $__SCARAB: (
25 | 'TOKENS': (
26 | 'gradient': (
27 | '0': none,
28 | 'hz-white-black': linear-gradient(to right, white 0%, black 100%)
29 | )
30 | )
31 | ) !global;
32 |
33 | @include assert-equal(
34 | g(hz-white-black),
35 | linear-gradient(to right, white 0%, black 100%)
36 | );
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/test/tokens/helpers/keyframe.scss:
--------------------------------------------------------------------------------
1 | @include describe('keyframe [func]') {
2 |
3 | @include it('Returns a `keyframe` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'keyframe': (
7 | 'fade' : (
8 | '0%': (
9 | opacity: 0
10 | ),
11 | '100%': (
12 | opacity: 1
13 | )
14 | )
15 | )
16 | )
17 | ) !global;
18 |
19 | @include assert-equal(
20 | keyframe(fade),
21 | (
22 | '0%': (
23 | opacity: 0
24 | ),
25 | '100%': (
26 | opacity: 1
27 | )
28 | )
29 | );
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/test/tokens/helpers/letter-spacing.scss:
--------------------------------------------------------------------------------
1 | @include describe('letter-spacing [func]') {
2 |
3 | @include it('Returns a `letter-spacing` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'letter-spacing': (
7 | '0': 0,
8 | 'loose-1': 0.2em,
9 | 'tight-1': -0.2em
10 | )
11 | )
12 | ) !global;
13 |
14 | @include assert-equal(
15 | letter-spacing(loose-1),
16 | 0.2em
17 | );
18 | }
19 |
20 | }
21 |
22 | @include describe('ls [func]') {
23 |
24 | @include it('Returns a `letter-spacing` value from the `TOKENS` map') {
25 | $__SCARAB: (
26 | 'TOKENS': (
27 | 'letter-spacing': (
28 | '0': 0,
29 | 'loose-1': 0.2em,
30 | 'tight-1': -0.2em
31 | )
32 | )
33 | ) !global;
34 |
35 | @include assert-equal(
36 | ls(loose-1),
37 | 0.2em
38 | );
39 | }
40 |
41 | }
42 |
43 | @include describe('tracking [func]') {
44 |
45 | @include it('Returns a `letter-spacing` value from the `TOKENS` map') {
46 | $__SCARAB: (
47 | 'TOKENS': (
48 | 'letter-spacing': (
49 | '0': 0,
50 | 'loose-1': 0.2em,
51 | 'tight-1': -0.2em
52 | )
53 | )
54 | ) !global;
55 |
56 | @include assert-equal(
57 | tracking(loose-1),
58 | 0.2em
59 | );
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/test/tokens/helpers/line-height.scss:
--------------------------------------------------------------------------------
1 | @include describe('line-height [func]') {
2 |
3 | @include it('Returns a `line-height` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'line-height': (
7 | '0': none,
8 | '1': 18px
9 | )
10 | )
11 | ) !global;
12 |
13 | @include assert-equal(
14 | line-height(1),
15 | 18px
16 | );
17 | }
18 |
19 | }
20 |
21 | @include describe('lh [func]') {
22 |
23 | @include it('Returns a `line-height` value from the `TOKENS` map') {
24 | $__SCARAB: (
25 | 'TOKENS': (
26 | 'line-height': (
27 | '0': none,
28 | '1': 18px
29 | )
30 | )
31 | ) !global;
32 |
33 | @include assert-equal(
34 | lh(1),
35 | 18px
36 | );
37 | }
38 |
39 | }
40 |
41 | @include describe('leading [func]') {
42 |
43 | @include it('Returns a `line-height` value from the `TOKENS` map') {
44 | $__SCARAB: (
45 | 'TOKENS': (
46 | 'line-height': (
47 | '0': none,
48 | '1': 18px
49 | )
50 | )
51 | ) !global;
52 |
53 | @include assert-equal(
54 | leading(1),
55 | 18px
56 | );
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/test/tokens/helpers/line-style.scss:
--------------------------------------------------------------------------------
1 | @include describe('line-style [func]') {
2 |
3 | @include it('Returns a `line-style` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'line-style': (
7 | '0': none,
8 | 'dot': dotted
9 | )
10 | )
11 | ) !global;
12 |
13 | @include assert-equal(
14 | line-style(dot),
15 | dotted
16 | );
17 | }
18 |
19 | }
20 |
21 | @include describe('lns [func]') {
22 |
23 | @include it('Returns a `line-style` value from the `TOKENS` map') {
24 | $__SCARAB: (
25 | 'TOKENS': (
26 | 'line-style': (
27 | '0': none,
28 | 'dot': dotted
29 | )
30 | )
31 | ) !global;
32 |
33 | @include assert-equal(
34 | lns(dot),
35 | dotted
36 | );
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/test/tokens/helpers/line-width.scss:
--------------------------------------------------------------------------------
1 | @include describe('line-width [func]') {
2 |
3 | @include it('Returns a `line-width` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'line-width': (
7 | '0': none,
8 | 's': 1px,
9 | 'm': 3px,
10 | 'l': 5px
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | line-width(m),
17 | 3px
18 | );
19 | }
20 |
21 | }
22 |
23 | @include describe('lnw [func]') {
24 |
25 | @include it('Returns a `line-width` value from the `TOKENS` map') {
26 | $__SCARAB: (
27 | 'TOKENS': (
28 | 'line-width': (
29 | '0': none,
30 | 's': 1px,
31 | 'm': 3px,
32 | 'l': 5px
33 | )
34 | )
35 | ) !global;
36 |
37 | @include assert-equal(
38 | lnw(m),
39 | 3px
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/tokens/helpers/module.scss:
--------------------------------------------------------------------------------
1 | @include describe('module [func]') {
2 |
3 | @include it('Returns a `module` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'module': (
7 | 'margin': (
8 | root : 'm',
9 | values : get(spacing),
10 | breakpoints : get(breakpoint)
11 | )
12 | )
13 | )
14 | ) !global;
15 |
16 | @include assert-equal(
17 | module(margin),
18 | (
19 | root : 'm',
20 | values : get(spacing),
21 | breakpoints : get(breakpoint)
22 | )
23 | );
24 |
25 | @include assert-equal(
26 | module(margin, root),
27 | 'm'
28 | );
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/test/tokens/helpers/opacity.scss:
--------------------------------------------------------------------------------
1 | @include describe('opacity [func]') {
2 |
3 | @include it('Returns a `opacity` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'opacity': (
7 | '0' : 0,
8 | '50': 0.5
9 | )
10 | )
11 | ) !global;
12 |
13 | @include assert-equal(
14 | opacity(50),
15 | 0.5
16 | );
17 | }
18 |
19 | }
20 |
21 | @include describe('o [func]') {
22 |
23 | @include it('Returns a `opacity` value from the `TOKENS` map') {
24 | $__SCARAB: (
25 | 'TOKENS': (
26 | 'opacity': (
27 | '0' : 0,
28 | '50': 0.5
29 | )
30 | )
31 | ) !global;
32 |
33 | @include assert-equal(
34 | o(50),
35 | 0.5
36 | );
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/test/tokens/helpers/ratio.scss:
--------------------------------------------------------------------------------
1 | @include describe('ratio [func]') {
2 |
3 | @include it('Returns a `ratio` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'ratio': (
7 | '0': 0,
8 | '1by2': (1/2)*100%,
9 | '3by4': (3/4)*100%,
10 | '16by9': (16/9)*100%
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | ratio(16by9),
17 | (16/9)*100%
18 | );
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/test/tokens/helpers/spacing.scss:
--------------------------------------------------------------------------------
1 | @include describe('spacing [func]') {
2 |
3 | @include it('Returns a `spacing` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'spacing': (
7 | '0': none,
8 | 's': 2rem,
9 | 'm': 4rem,
10 | 'l': 8rem
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | spacing(l),
17 | 8rem
18 | );
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/test/tokens/helpers/text-measure.scss:
--------------------------------------------------------------------------------
1 | @include describe('text-measure [func]') {
2 |
3 | @include it('Returns a `measure` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'text-measure': (
7 | '0': none,
8 | 's': 12em,
9 | 'm': 20em,
10 | 'l': 30em
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | text-measure(m),
17 | 20em
18 | );
19 | }
20 |
21 | }
22 |
23 | @include describe('measure [func]') {
24 |
25 | @include it('Returns a `measure` value from the `TOKENS` map') {
26 | $__SCARAB: (
27 | 'TOKENS': (
28 | 'text-measure': (
29 | '0': none,
30 | 's': 12em,
31 | 'm': 20em,
32 | 'l': 30em
33 | )
34 | )
35 | ) !global;
36 |
37 | @include assert-equal(
38 | measure(m),
39 | 20em
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/tokens/helpers/text-shadow.scss:
--------------------------------------------------------------------------------
1 | @include describe('text-shadow [func]') {
2 |
3 | @include it('Returns a `text-shadow` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'text-shadow': (
7 | '0': linear,
8 | 's': 0 2px 4px rgba(0,0,0,0.2),
9 | 'm': 0 3px 6px rgba(0,0,0,0.2),
10 | 'l': 0 4px 6px rgba(0,0,0,0.2)
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | text-shadow(m),
17 | 0 3px 6px rgba(0,0,0,0.2)
18 | );
19 | }
20 |
21 | }
22 |
23 | @include describe('tsh [func]') {
24 |
25 | @include it('Returns a `text-shadow` value from the `TOKENS` map') {
26 | $__SCARAB: (
27 | 'TOKENS': (
28 | 'text-shadow': (
29 | '0': linear,
30 | 's': 0 2px 4px rgba(0,0,0,0.2),
31 | 'm': 0 3px 6px rgba(0,0,0,0.2),
32 | 'l': 0 4px 6px rgba(0,0,0,0.2)
33 | )
34 | )
35 | ) !global;
36 |
37 | @include assert-equal(
38 | tsh(m),
39 | 0 3px 6px rgba(0,0,0,0.2)
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/tokens/helpers/wrapper-width.scss:
--------------------------------------------------------------------------------
1 | @include describe('wrapper-width [func]') {
2 |
3 | @include it('Returns a `wrap` value from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'wrapper-width': (
7 | '0': none,
8 | 's': 15rem,
9 | 'm': 22.5rem,
10 | 'l': 35rem
11 | )
12 | )
13 | ) !global;
14 |
15 | @include assert-equal(
16 | wrapper-width(l),
17 | 35rem
18 | );
19 | }
20 |
21 | }
22 |
23 | @include describe('wrap [func]') {
24 |
25 | @include it('Returns a `wrap` value from the `TOKENS` map') {
26 | $__SCARAB: (
27 | 'TOKENS': (
28 | 'wrapper-width': (
29 | '0': none,
30 | 's': 15rem,
31 | 'm': 22.5rem,
32 | 'l': 35rem
33 | )
34 | )
35 | ) !global;
36 |
37 | @include assert-equal(
38 | wrap(l),
39 | 35rem
40 | );
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/tokens/set-default.scss:
--------------------------------------------------------------------------------
1 | @include describe('set-default [func]') {
2 |
3 | @include it('Sets a new value in the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': ()
6 | ) !global;
7 |
8 | $_: set-default(baseline, 2rem);
9 |
10 | @include assert-equal(
11 | inspect($__SCARAB),
12 | inspect((
13 | 'TOKENS': (
14 | 'baseline': 2rem
15 | )
16 | )),
17 | 'Register value for a key does not exist'
18 | );
19 |
20 |
21 |
22 | $__SCARAB: (
23 | 'TOKENS': (
24 | 'baseline': 1rem
25 | )
26 | ) !global;
27 |
28 | $_: set-default(baseline, 2rem);
29 |
30 | @include assert-equal(
31 | inspect($__SCARAB),
32 | inspect((
33 | 'TOKENS': (
34 | 'baseline': 1rem
35 | )
36 | )),
37 | 'Fails to register value for existing keys'
38 | );
39 |
40 |
41 |
42 | $__SCARAB: (
43 | 'TOKENS': (
44 | 'palettes': (
45 | 'blue': (
46 | 'light': lightblue,
47 | 'base': blue
48 | )
49 | )
50 | )
51 | ) !global;
52 |
53 | $_: set-default(palettes, blue, dark, darkblue);
54 |
55 | @include assert-equal(
56 | inspect($__SCARAB),
57 | inspect((
58 | 'TOKENS': (
59 | 'palettes': (
60 | 'blue': (
61 | 'light': lightblue,
62 | 'base': blue,
63 | 'dark': darkblue
64 | )
65 | )
66 | )
67 | )),
68 | 'Register value for a nested key does not exist'
69 | );
70 |
71 |
72 |
73 | $__SCARAB: (
74 | 'TOKENS': (
75 | 'palettes': (
76 | 'blue': (
77 | 'light': lightblue,
78 | 'base': blue
79 | )
80 | )
81 | )
82 | ) !global;
83 |
84 | $_: set-default(palettes, blue, light, skyblue);
85 |
86 | @include assert-equal(
87 | inspect($__SCARAB),
88 | inspect((
89 | 'TOKENS': (
90 | 'palettes': (
91 | 'blue': (
92 | 'light': lightblue,
93 | 'base': blue
94 | )
95 | )
96 | )
97 | )),
98 | 'Fails to register a value for existing nested keys'
99 | );
100 | }
101 |
102 | }
103 |
104 |
105 |
106 | @include describe('set-default [mixin]') {
107 |
108 | @include it('Sets a new value in the `TOKENS` map') {
109 | $__SCARAB: (
110 | 'TOKENS': ()
111 | ) !global;
112 |
113 | @include set-default(baseline, 2rem);
114 |
115 | @include assert-equal(
116 | inspect($__SCARAB),
117 | inspect((
118 | 'TOKENS': (
119 | 'baseline': 2rem
120 | )
121 | )),
122 | 'Register value for a key does not exist'
123 | );
124 |
125 |
126 |
127 | $__SCARAB: (
128 | 'TOKENS': (
129 | 'baseline': 1rem
130 | )
131 | ) !global;
132 |
133 | @include set-default(baseline, 2rem);
134 |
135 | @include assert-equal(
136 | inspect($__SCARAB),
137 | inspect((
138 | 'TOKENS': (
139 | 'baseline': 1rem
140 | )
141 | )),
142 | 'Fails to register value for existing keys'
143 | );
144 |
145 |
146 |
147 | $__SCARAB: (
148 | 'TOKENS': (
149 | 'palettes': (
150 | 'blue': (
151 | 'light': lightblue,
152 | 'base': blue
153 | )
154 | )
155 | )
156 | ) !global;
157 |
158 | @include set-default(palettes, blue, dark, darkblue);
159 |
160 | @include assert-equal(
161 | inspect($__SCARAB),
162 | inspect((
163 | 'TOKENS': (
164 | 'palettes': (
165 | 'blue': (
166 | 'light': lightblue,
167 | 'base': blue,
168 | 'dark': darkblue
169 | )
170 | )
171 | )
172 | )),
173 | 'Register value for a nested key does not exist'
174 | );
175 |
176 |
177 |
178 | $__SCARAB: (
179 | 'TOKENS': (
180 | 'palettes': (
181 | 'blue': (
182 | 'light': lightblue,
183 | 'base': blue
184 | )
185 | )
186 | )
187 | ) !global;
188 |
189 | @include set-default(palettes, blue, light, skyblue);
190 |
191 | @include assert-equal(
192 | inspect($__SCARAB),
193 | inspect((
194 | 'TOKENS': (
195 | 'palettes': (
196 | 'blue': (
197 | 'light': lightblue,
198 | 'base': blue
199 | )
200 | )
201 | )
202 | )),
203 | 'Fails to register a value for existing nested keys'
204 | );
205 | }
206 |
207 | }
208 |
--------------------------------------------------------------------------------
/test/tokens/set.scss:
--------------------------------------------------------------------------------
1 | @include describe('set [func]') {
2 |
3 | @include it('Sets a new value in the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': ()
6 | ) !global;
7 |
8 | $_: set(baseline, 2rem);
9 |
10 | @include assert-equal(
11 | inspect($__SCARAB),
12 | inspect((
13 | 'TOKENS': (
14 | 'baseline': 2rem
15 | )
16 | )),
17 | 'Register value for new key'
18 | );
19 |
20 |
21 |
22 | $__SCARAB: (
23 | 'TOKENS': ()
24 | ) !global;
25 |
26 | $_: set(breakpoints, custom, 777px);
27 |
28 | @include assert-equal(
29 | inspect($__SCARAB),
30 | inspect((
31 | 'TOKENS': (
32 | 'breakpoints': (
33 | 'custom': 777px
34 | )
35 | )
36 | )),
37 | 'Register value for new nested key'
38 | );
39 |
40 |
41 |
42 |
43 | $__SCARAB: (
44 | 'TOKENS': (
45 | 'baseline': 2rem
46 | )
47 | ) !global;
48 |
49 | $_: set(baseline, 0.5rem);
50 |
51 | @include assert-equal(
52 | inspect($__SCARAB),
53 | inspect((
54 | 'TOKENS': (
55 | 'baseline': 0.5rem
56 | )
57 | )),
58 | 'Update value for existing key'
59 | );
60 |
61 |
62 |
63 | $__SCARAB: (
64 | 'TOKENS': ()
65 | ) !global;
66 |
67 | $_: set(palettes, (
68 | blue: (
69 | light: skyblue,
70 | base: blue,
71 | dark: darkblue
72 | )
73 | ));
74 |
75 | @include assert-equal(
76 | inspect($__SCARAB),
77 | inspect((
78 | 'TOKENS': (
79 | 'palettes': (
80 | 'blue': (
81 | 'light': skyblue,
82 | 'base': blue,
83 | 'dark': darkblue
84 | )
85 | )
86 | )
87 | )),
88 | 'Set a map-based value'
89 | );
90 |
91 |
92 |
93 | $__SCARAB: (
94 | 'TOKENS': ()
95 | ) !global;
96 |
97 | $_: set(palettes, blue, (
98 | light: skyblue,
99 | base: blue,
100 | dark: darkblue
101 | ));
102 |
103 | @include assert-equal(
104 | inspect($__SCARAB),
105 | inspect((
106 | 'TOKENS': (
107 | 'palettes': (
108 | 'blue': (
109 | 'light': skyblue,
110 | 'base': blue,
111 | 'dark': darkblue
112 | )
113 | )
114 | )
115 | )),
116 | 'Set a nested map-based value'
117 | );
118 | }
119 |
120 | }
121 |
122 |
123 |
124 | @include describe('set [mixin]') {
125 |
126 | @include it('Sets a new value in the `TOKENS` map') {
127 | $__SCARAB: (
128 | 'TOKENS': ()
129 | ) !global;
130 |
131 | @include set(baseline, 2rem);
132 |
133 | @include assert-equal(
134 | inspect($__SCARAB),
135 | inspect((
136 | 'TOKENS': (
137 | 'baseline': 2rem
138 | )
139 | )),
140 | 'Register value for new key'
141 | );
142 |
143 |
144 |
145 | $__SCARAB: (
146 | 'TOKENS': ()
147 | ) !global;
148 |
149 | @include set(breakpoints, custom, 777px);
150 |
151 | @include assert-equal(
152 | inspect($__SCARAB),
153 | inspect((
154 | 'TOKENS': (
155 | 'breakpoints': (
156 | 'custom': 777px
157 | )
158 | )
159 | )),
160 | 'Register value for new nested key'
161 | );
162 |
163 |
164 |
165 |
166 | $__SCARAB: (
167 | 'TOKENS': (
168 | 'baseline': 2rem
169 | )
170 | ) !global;
171 |
172 | @include set(baseline, 0.5rem);
173 |
174 | @include assert-equal(
175 | inspect($__SCARAB),
176 | inspect((
177 | 'TOKENS': (
178 | 'baseline': 0.5rem
179 | )
180 | )),
181 | 'Update value for existing key'
182 | );
183 |
184 |
185 |
186 | $__SCARAB: (
187 | 'TOKENS': ()
188 | ) !global;
189 |
190 | @include set(palettes, (
191 | blue: (
192 | light: skyblue,
193 | base: blue,
194 | dark: darkblue
195 | )
196 | ));
197 |
198 | @include assert-equal(
199 | inspect($__SCARAB),
200 | inspect((
201 | 'TOKENS': (
202 | 'palettes': (
203 | 'blue': (
204 | 'light': skyblue,
205 | 'base': blue,
206 | 'dark': darkblue
207 | )
208 | )
209 | )
210 | )),
211 | 'Set a map-based value'
212 | );
213 |
214 |
215 |
216 | $__SCARAB: (
217 | 'TOKENS': ()
218 | ) !global;
219 |
220 | @include set(palettes, blue, (
221 | light: skyblue,
222 | base: blue,
223 | dark: darkblue
224 | ));
225 |
226 | @include assert-equal(
227 | inspect($__SCARAB),
228 | inspect((
229 | 'TOKENS': (
230 | 'palettes': (
231 | 'blue': (
232 | 'light': skyblue,
233 | 'base': blue,
234 | 'dark': darkblue
235 | )
236 | )
237 | )
238 | )),
239 | 'Set a nested map-based value'
240 | );
241 | }
242 |
243 | }
244 |
--------------------------------------------------------------------------------
/test/tokens/unset.scss:
--------------------------------------------------------------------------------
1 | @include describe('unset [func]') {
2 |
3 | @include it('Removes a key-value pair from the `TOKENS` map') {
4 | $__SCARAB: (
5 | 'TOKENS': (
6 | 'baseline': 1rem,
7 | 'breakpoints': (
8 | 's': 100px,
9 | 'm': 200px,
10 | 'l': 300px
11 | )
12 | )
13 | ) !global;
14 |
15 | $_: unset(baseline);
16 |
17 | @include assert-equal(
18 | inspect($__SCARAB),
19 | inspect((
20 | 'TOKENS': (
21 | 'breakpoints': (
22 | 's': 100px,
23 | 'm': 200px,
24 | 'l': 300px
25 | )
26 | )
27 | ))
28 | );
29 |
30 |
31 |
32 | $__SCARAB: (
33 | 'TOKENS': (
34 | 'baseline': 1rem,
35 | 'palettes': (
36 | 'blue': (
37 | 'light': skyblue,
38 | 'base': blue,
39 | 'dark': darkblue
40 | )
41 | )
42 | )
43 | ) !global;
44 |
45 | $_: unset(palettes, blue, base);
46 |
47 | @include assert-equal(
48 | inspect($__SCARAB),
49 | inspect((
50 | 'TOKENS': (
51 | 'baseline': 1rem,
52 | 'palettes': (
53 | 'blue': (
54 | 'light': skyblue,
55 | 'dark': darkblue
56 | )
57 | )
58 | )
59 | )),
60 | 'Removes a nested key'
61 | );
62 |
63 |
64 |
65 | $__SCARAB: (
66 | 'TOKENS': (
67 | 'baseline': 1rem,
68 | 'palettes': (
69 | 'blue': (
70 | 'light': skyblue,
71 | 'base': blue,
72 | 'dark': darkblue
73 | )
74 | )
75 | )
76 | ) !global;
77 |
78 | $_: unset(palettes, blue);
79 |
80 | @include assert-equal(
81 | inspect($__SCARAB),
82 | inspect((
83 | 'TOKENS': (
84 | 'baseline': 1rem,
85 | 'palettes': (
86 | )
87 | )
88 | )),
89 | 'Removes a nested key that is a color name'
90 | );
91 | }
92 |
93 | }
94 |
95 |
96 |
97 | @include describe('unset [mixin]') {
98 |
99 | @include it('Removes a key-value pair from the `TOKENS` map') {
100 | $__SCARAB: (
101 | 'TOKENS': (
102 | 'baseline': 1rem,
103 | 'breakpoints': (
104 | 's': 100px,
105 | 'm': 200px,
106 | 'l': 300px
107 | )
108 | )
109 | ) !global;
110 |
111 | @include unset(baseline);
112 |
113 | @include assert-equal(
114 | inspect($__SCARAB),
115 | inspect((
116 | 'TOKENS': (
117 | 'breakpoints': (
118 | 's': 100px,
119 | 'm': 200px,
120 | 'l': 300px
121 | )
122 | )
123 | ))
124 | );
125 |
126 |
127 |
128 | $__SCARAB: (
129 | 'TOKENS': (
130 | 'baseline': 1rem,
131 | 'palettes': (
132 | 'blue': (
133 | 'light': skyblue,
134 | 'base': blue,
135 | 'dark': darkblue
136 | )
137 | )
138 | )
139 | ) !global;
140 |
141 | @include unset(palettes, blue, base);
142 |
143 | @include assert-equal(
144 | inspect($__SCARAB),
145 | inspect((
146 | 'TOKENS': (
147 | 'baseline': 1rem,
148 | 'palettes': (
149 | 'blue': (
150 | 'light': skyblue,
151 | 'dark': darkblue
152 | )
153 | )
154 | )
155 | )),
156 | 'Removes a nested key'
157 | );
158 |
159 |
160 |
161 | $__SCARAB: (
162 | 'TOKENS': (
163 | 'baseline': 1rem,
164 | 'palettes': (
165 | 'blue': (
166 | 'light': skyblue,
167 | 'base': blue,
168 | 'dark': darkblue
169 | )
170 | )
171 | )
172 | ) !global;
173 |
174 | @include unset(palettes, blue);
175 |
176 | @include assert-equal(
177 | inspect($__SCARAB),
178 | inspect((
179 | 'TOKENS': (
180 | 'baseline': 1rem,
181 | 'palettes': (
182 | )
183 | )
184 | )),
185 | 'Removes a nested key that is a color name'
186 | );
187 | }
188 |
189 | }
190 |
--------------------------------------------------------------------------------