Context stacks - Feuerfuchs/sass-ignis GitHub Wiki

Context stacks are a temporary data storage and, as the name suggests, are used like a conventional stack data structure. This means: Whenever you want to store a context — which is an identifier and any kind of data, such as a map, a list, a string, etc... — you push it to the stack. From then on, this context is publicly accessible. In order to remove it, you pop the stack.

This feature becomes extremely useful when paired with mixins and their @content directive: Pushing a context to the stack before @content and popping the stack afterwards gives it the role of a call stack. Thats how the BEM system, for example, attaches metadata to the selectors it generates. These information are used to generate optimal selectors without much parsing.

Usage

Context stack operations

Type Description
ig-context-stack-create($name) Function, Mixin Create a new context stack called $name.
ig-context-stack-create($name) Function, Mixin Delete the context stack called $name.
ig-context-stack-count($name) Function, Mixin Get the number of contexts in the context stack called $name.
ig-context-stack-clear($name) Function, Mixin Remove all contexts from the context stack called $name.

Context operations

Type Description
ig-context-push($stack, $context-id, $context-data) Function, Mixin Push a new context to the context stack called $stack. The contetx will have the id $context-id and contain the data $context-data.
ig-context-pop($stack) Function, Mixin Remove the latest context from the context stack called $stack.
ig-context-get($stack, $n) Function Get the $n-th context from the context stack called $stack. $n behaves like the index for the SASS function nth(), with 1 being the last pushed context, -1 being the first pushed context, and so on.
ig-context-get($stack, $context-ids) Function Get the first context which has one of the IDs in $context-ids from the context stack called $stack.
ig-context-stack-contains($stack-id, $context-ids, $check-head-only: false) Function Check if the context stack called $stack contains a context whose ID matches one of the IDs in $context-ids. If $check-head-only is true, only the latest context is checked.
ig-context-assert-stack-must-contain($stack-id, $context-ids, $check-head-only: false) Mixin Assert that the context stack called $stack must contain a context whose ID matches one of the IDs in $context-ids. If $check-head-only is true, only the latest context is checked.
ig-context-assert-stack-must-not-contain($stack-id, $context-ids, $check-head-only: false) Mixin Assert that the context stack called $stack must not contain a context whose ID matches one of the IDs in $context-ids. If $check-head-only is true, only the latest context is checked.

Example

$context-id: 'some-context-stack';

@mixin anything($p) {
    @include ig-context-push($context-id, 'anything', (
        --this: 1,
        --is:   true,
        --the:  'test',
        --data: $p
    ));

    @content;

    @include ig-context-pop($context-id);
}

// Usage:

.test {
    @include anything('hello') {
        $context-data: nth(ig-context-get($context-id, 'anything'), 2);
        $this: map-get($context-data, --this); // 1
        $is:   map-get($context-data, --is);   // true
        $the:  map-get($context-data, --the);  // 'test'
        $data: map-get($context-data, --data); // 'hello'
    }
}