From 1257a534af5ebda9f167b5bfd283e0ade8ed7b80 Mon Sep 17 00:00:00 2001
From: Volpeon <git@volpeon.ink>
Date: Fri, 18 Oct 2024 13:02:18 +0200
Subject: New CSS variable management

---
 .stylelintrc.json |  10 +-
 pnpm-lock.yaml    |  14 +-
 src/_props.scss   | 454 ++++++++----------------------------------------------
 3 files changed, 70 insertions(+), 408 deletions(-)

diff --git a/.stylelintrc.json b/.stylelintrc.json
index 97f6f6c..ad8225f 100644
--- a/.stylelintrc.json
+++ b/.stylelintrc.json
@@ -12,13 +12,5 @@
             }
         ],
         "scss/dollar-variable-colon-space-after": null
-    },
-    "overrides": [
-        {
-            "files": [
-                "**/*.scss"
-            ],
-            "customSyntax": "postcss-scss"
-        }
-    ]
+    }
 }
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 34920b4..b436de9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -25,7 +25,7 @@ importers:
         version: 8.1.0(sass@1.79.4)
       sassdoc:
         specifier: ^2.7.3
-        version: 2.7.4(chokidar@4.0.1)
+        version: 2.7.4(chokidar@3.6.0)
       stylelint:
         specifier: ^16.9.0
         version: 16.9.0
@@ -2692,13 +2692,13 @@ snapshots:
 
   number-is-nan@1.0.1: {}
 
-  nunjucks@3.2.4(chokidar@4.0.1):
+  nunjucks@3.2.4(chokidar@3.6.0):
     dependencies:
       a-sync-waterfall: 1.0.1
       asap: 2.0.6
       commander: 5.1.0
     optionalDependencies:
-      chokidar: 4.0.1
+      chokidar: 3.6.0
 
   object-assign@3.0.0: {}
 
@@ -2969,7 +2969,7 @@ snapshots:
     dependencies:
       marked: 0.6.3
 
-  sassdoc-theme-default@2.8.6(chokidar@4.0.1):
+  sassdoc-theme-default@2.8.6(chokidar@3.6.0):
     dependencies:
       babel-runtime: 6.26.0
       chroma-js: 1.4.1
@@ -2978,12 +2978,12 @@ snapshots:
       extend: 3.0.2
       fs-extra: 2.1.2
       html-minifier: 3.5.21
-      nunjucks: 3.2.4(chokidar@4.0.1)
+      nunjucks: 3.2.4(chokidar@3.6.0)
       sassdoc-extras: 2.5.1
     transitivePeerDependencies:
       - chokidar
 
-  sassdoc@2.7.4(chokidar@4.0.1):
+  sassdoc@2.7.4(chokidar@3.6.0):
     dependencies:
       ansi-styles: 4.3.0
       babel-runtime: 6.26.0
@@ -3001,7 +3001,7 @@ snapshots:
       rimraf: 3.0.2
       safe-wipe: 0.2.5
       sass-convert: 0.5.2
-      sassdoc-theme-default: 2.8.6(chokidar@4.0.1)
+      sassdoc-theme-default: 2.8.6(chokidar@3.6.0)
       scss-comment-parser: 0.8.4
       strip-indent: 3.0.0
       through2: 1.1.1
diff --git a/src/_props.scss b/src/_props.scss
index 14295bd..c80c18b 100644
--- a/src/_props.scss
+++ b/src/_props.scss
@@ -1,434 +1,104 @@
-////
-/// Property trees.
-///
-/// Property trees allow you to organize properties in a tree structure (internally nested maps).
-/// The intended use is to store all your properties at the beginning and for the rest of the
-/// stylesheet you just get them.
-///
-/// @group Property trees
-///
-/// @access public
-////
-
-@use 'sass:map';
 @use 'sass:list';
-@use 'sass:string';
+@use 'sass:map';
 @use 'sass:meta';
-@use './functions';
-@use './contexts';
-
-///
-/// The maximum depth of resolved iro-prop-ref() references.
-///
-/// @type number
-///
-$native-assign-max-depth: 2 !default;
-
-///
-/// Indicate if property names must start with two dashes (--).
-/// This is required if property trees are also used for native CSS custom properties.
-///
-/// @type bool
-///
-$enforce-double-dashes: true !default;
-
-///
-/// Default tree name to use if no name is specified.
-///
-/// @type string
-///
-$default-tree: 'default' !default;
-
-///
-/// List of all created property trees.
-///
-/// @type list
-///
-/// @access private
-///
-$trees: ();
-
-///
-/// Default context name used for the namespace context.
-///
-/// @type string
-///
-$namespace-context-id: 'namespace' !default;
-
-///
-/// Declare a namespace, meaning that all variables declared and accessed.
-///
-/// @param {string} $name - Name of the namespace
-///
-@mixin namespace($name) {
-    $key: '--#{$name}';
-
-    $ns-key: get-ns-key();
-
-    @if $ns-key != null {
-        $key: list.append($ns-key, $key);
-    } @else {
-        $key: ($key);
-    }
-
-    @include contexts.push($namespace-context-id, 'namespace', (
-        'name': $name,
-        'key':  $key
-    ));
-
-    @content;
-
-    @include contexts.pop($namespace-context-id);
-}
-
-///
-/// Get the current namespace name.
-///
-@function namespace() {
-    $noop: contexts.assert-stack-must-contain($namespace-context-id, 'namespace');
-
-    $data: list.nth(contexts.get($namespace-context-id, 'namespace'), 2);
-    $name: map.get($data, 'name');
-
-    @return $name;
-}
-
-/// 
-/// Save a property tree. If a tree with the sane name already exists, the trees
-/// will be merged.
-///
-/// @param {map}    $map                             - Map containing properties
-/// @param {string} $tree  [$default-tree] - ID the map is saved as
-/// @param {bool}   $merge [true]                    - If a tree named $tree already exists and this value is set to true, they will be merged. Otherwise an error will be emitted.
-///
-@mixin store($map, $tree: $default-tree, $merge: true, $global: false) {
-    $noop: store($map, $tree, $merge, $global);
-}
-
-/// 
-/// Save a property tree.
-///
-/// @param {map}    $map                             - Map containing properties
-/// @param {string} $tree  [$default-tree] - ID the map is saved as
-/// @param {bool}   $merge [true]                    - If a tree named $tree already exists and this value is set to true, they will be merged. Otherwise an error will be emitted.
-///
-@function store($map, $tree: $default-tree, $merge: true, $global: false) {
-    $prop-map: null;
+@use 'functions';
 
-    @if $enforce-double-dashes {
-        @if not validate($map) {
-            @error 'Property tree keys must start with two dashes (--). If you don\'t use property trees for native CSS custom properties, set $enforce-double-dashes to false.';
-        }
+@function is-prop-ref($value) {
+    @if meta.type-of($value) != 'list' {
+        @return false;
     }
-
-    @if not $global {
-        $ns-key: get-ns-key();
-
-        @if $ns-key != null {
-            $map: ($ns-key: $map);
-        }
+    @if list.length($value) != 4 {
+        @return false;
     }
-
-    @if map.has-key($trees, $tree) {
-        @if $merge {
-            $map: map.deep-merge(map.get($trees, $tree), $map);
-        } @else {
-            @error 'Property tree #{inspect($tree)} does already exist.';
-        }
+    @if list.nth($value, 1) != 'prop-ref' {
+        @return false;
     }
-
-    $trees: map.merge($trees, ($tree: $map)) !global;
-
-    @return null;
+    @return true;
 }
 
-/// 
-/// Delete a property tree.
-///
-/// @param {string} $tree [$default-tree] - ID of the tree to be deleted
-///
-@mixin clear($tree: $default-tree) {
-    $noop: clear($tree);
+@function def($name, $value: (), $metadata: null) {
+    @return ('prop-ref' $name $value $metadata);
 }
 
-/// 
-/// Delete a property tree.
-///
-/// @param {string} $tree [$default-tree] - ID of the tree to be deleted
-///
-/// @throw If the property tree does not exist
-///
-@function clear($tree: $default-tree) {
-    @if not map.has-key($trees, $tree) {
-        @error 'Property tree "#{inspect($tree)}" does not exist.';
+@function merge($ref, $value) {
+    @if not is-prop-ref($ref) {
+        @return $ref;
     }
 
-    $trees: map.remove($trees, $tree) !global;
-
-    @return null;
+    $v:   list.nth($ref, 3);
+    $ref: list.set-nth($ref, 3, map.deep-merge($v, $value));
+    @return $ref;
 }
 
-/// 
-/// Access a whole property or a subsection (i.e. value) of it.
-///
-/// @param {string | list} $key     [null]                    - Key of the property to read. If this is a list of keys, the map will be traversed in that order.
-/// @param {string}        $tree    [$default-tree] - ID of the property tree to use
-/// @param {any}           $default [null]                    - Default value to return of no match was found. If null, this function will throw an error instead.
-///
-/// @return {any} Value assigned to property or $default
-///
-/// @throw If there was no match for $key and $default is null
-///
-@function get-static($key: (), $tree: $default-tree, $default: null, $global: false) {
-    @if not map.has-key($trees, $tree) {
-        @error 'Unknown tree "#{$tree}".';
-    }
-
-    $result: map.get($trees, $tree);
-
-    @if not $global {
-        $ns-key: get-ns-key();
-
-        @if $ns-key != null {
-            $orig-key: $key;
-            $key:      $ns-key;
-
-            @if meta.type-of($orig-key) == list {
-                @each $subkey in $orig-key {
-                    $key: list.append($key, $subkey);
-                }
-            } @else {
-                $key: list.append($key, $orig-key);
-            }
-        }
-    }
-
-    @if meta.type-of($key) == list {
-        $stop: false;
-
-        @each $k in $key {
-            @if not $stop and map.has-key($result, $k) {
-                $result: map.get($result, $k);
-
-                @if meta.type-of($result) == list and list.nth($result, 1) == 'iro-prop-ref' {
-                    @if list.length($result) == 2 {
-                        $result: get-static($tree: list.nth($result, 2), $global: true);
-                    } @else {
-                        $result: get-static(list.nth($result, 3), nth($result, 2), $global: true);
-                    }
-                }
-            } @else {
-                $stop: true;
-            }
-        }
-
-        @if $stop {
-            $result: null;
-        }
-    } @else {
-        $result: map.get($result, $key);
-
-        @if meta.type-of($result) == list and list.nth($result, 1) == 'iro-prop-ref' {
-            @if list.length($result) == 2 {
-                $result: get-static($tree: list.nth($result, 2), $global: true);
-            } @else {
-                $result: get-static(list.nth($result, 3), nth($result, 2), $global: true);
-            }
-        }
+@function get-deep($name, $value, $key: null, $keys...) {
+    @if is-prop-ref($value) {
+        @return get($value, $key, $keys);
     }
-
-    @if $result == null {
-        @if $default == null {
-            @error '"#{$key}" is null.';
-        } @else {
-            @return $default;
-        }
+    @if meta.type-of($value) == 'map' and $key != null {
+        @return get-deep(#{$name}#{$key}, map.get($value, $key), $keys...);
     }
-
-    @return $result;
+    @return $name $value;
 }
 
-/// 
-/// Generate a var() function call to get native CSS custom property.
-///
-/// @param {string | list} $key            - Key of the property to read. If this is a list of keys, the map will be traversed in that order.
-/// @param {string | null} $tree    [null] - Optional tree to check if the property actually exists.
-/// @param {any}           $default [null] - Default value to return of no match was found.
-///
-/// @return {string} var()
-///
-@function get($key, $tree: $default-tree, $default: null, $global: false) {
-    @if $tree != null {
-        $value: get-static($key, $tree, $default, $global);
-
-        @if meta.type-of($value) == map {
-            $result: ();
-            @each $k in map.keys($value) {
-                $result: map.set($result, $k, get(list.append($key, $k), $tree, $default, $global));
-            }
-            @return $result;
-        }
-    }
-
-    @if not $global {
-        $ns-key: get-ns-key();
-
-        @if $ns-key != null {
-            $orig-key: $key;
-            $key:      $ns-key;
-
-            @if meta.type-of($orig-key) == list {
-                @each $subkey in $orig-key {
-                    $key: list.append($key, $subkey);
-                }
-            } @else {
-                $key: list.append($key, $orig-key);
-            }
-        }
+@function map-to-vars($name, $map) {
+    @if meta.type-of($map) != 'map' {
+        @return var($name);
     }
 
-    $native-var: '';
+    $out: ();
 
-    @if meta.type-of($key) == list {
-        @each $subkey in $key {
-            $native-var: $native-var + $subkey;
-        }
-    } @else {
-        $native-var: $key;
+    @each $key, $value in $map {
+        $out: map.set($out, $key, map-to-vars(#{$name}#{$key}, $value));
     }
 
-    @if $default == null {
-        @return var(#{$native-var});
-    } @else {
-        @return var(#{$native-var}, #{$default});
-    }
+    @return $out;
 }
 
-/// 
-/// Generate assignments for native CSS custom properties with the values from the specified tree.
-///
-/// @param {string} $tree [$default-tree] - ID of the property tree to use
-/// @param {string} $root [()]                      - Sub-tree to use for assignment
-///
-@mixin assign($tree: $default-tree, $root: (), $skip: (), $prefix: $root, $global: false) {
-    $map: get-static($root, $tree, $global: $global);
-    $map: map.remove($map, $skip...);
-
-    @if meta.type-of($prefix) == list {
-        $prefix: functions.str-implode($prefix);
+@function get($ref, $key: null, $keys...) {
+    @if not is-prop-ref($ref) {
+        @return $ref;
     }
 
-    @if not $global {
-        $ns-key: get-ns-key();
+    $name:  list.nth($ref, 2);
+    $value: get(list.nth($ref, 3));
 
-        @if $ns-key != null {
-            $prefix: $prefix + functions.str-implode($ns-key);
+    @if meta.type-of($value) == 'map' {
+        $res:   get-deep($name, $value, $key, $keys...);
+        $name:  list.nth($res, 1);
+        $value: list.nth($res, 2);
+    } @else if meta.type-of($value) == 'list' {
+        $i: 1;
+        @each $item in $value {
+            $value: list.set-nth($value, $i, get($item));
+            $i: $i + 1;
         }
     }
 
-    @include assign-internal($map, $prefix);
+    @return map-to-vars($name, $value);
 }
 
-///
-/// @access private
-///
-@mixin assign-internal($map, $prefix: '', $ref-depth: $native-assign-max-depth) {
-    @each $key, $value in $map {
-        $rd: $ref-depth;
-        @if meta.type-of($value) == list and list.length($value) > 0 and list.nth($value, 1) == 'iro-prop-ref' {
-            @if $ref-depth != 0 {
-                $rd: $rd - 1;
-                @if list.length($value) == 2 {
-                    $value: get-static($tree: list.nth($value, 2));
-                } @else {
-                    $value: get-static(list.nth($value, 3), nth($value, 2));
-                }
-            } @else {
-                $value: null;
-            }
-        }
-        @if meta.type-of($value) != map and $value != () {
-            #{$prefix + $key}: #{$value};
-        } @else {
-            @include assign-internal($value, $prefix + $key, $rd);
+@mixin materialize-helper($name, $value) {
+    @if meta.type-of($value) == 'map' {
+        @each $key, $value in $value {
+            @include materialize-helper(#{$name}#{$key}, $value);
         }
+    } @else {
+        #{$name}: #{$value};
     }
 }
 
-/// 
-/// Validate property names.
-///
-/// @access private
-///
-@function validate($map) {
-    @each $key, $value in $map {
-        @if string.index($key, '--') != 1 {
-            @return false;
-        }
+@mixin materialize($ref, $match-meta: null) {
+    @if is-prop-ref($ref) {
+        $name:  list.nth($ref, 2);
+        $value: get(list.nth($ref, 3));
+        $meta:  get(list.nth($ref, 4));
 
-        @if meta.type-of($value) == map {
-            @if not validate($value) {
-                @return false;
-            }
+        @if $meta == $match-meta {
+            @include materialize-helper($name, $value);
         }
-    }
-
-    @return true;
-}
-
-/// 
-/// Generate a reference to another tree. Dereferencing is lazy, so you may specify a tree that hasn't been created yet.
-///
-/// @param {string}        $tree [$default-tree] - ID of the property tree to use
-/// @param {string | list} $key                            - Key of the property to read. If this is a list of keys, the map will be traversed in that order.
-///
-/// @return {list} A special list that let's Ignis know that this is a lazy value.
-///
-/// @throw If there was no match for $key and $default is null
-///
-@function ref($tree: $default-tree, $key: null, $global: false) {
-    @if not $global {
-        $ns-key: get-ns-key();
-
-        @if $ns-key != null {
-            $orig-key: $key;
-            $key:      $ns-key;
-
-            @if $orig-key != null {
-                @if meta.type-of($orig-key) == list {
-                    @each $subkey in $orig-key {
-                        $key: list.append($key, $subkey);
-                    }
-                } @else {
-                    $key: list.append($key, $orig-key);
-                }
-            }
+    } @else if meta.type-of($ref) == 'list' {
+        @each $r in $ref {
+            @include materialize($r);
         }
     }
-
-    @if $key == null {
-        @return ('iro-prop-ref' $tree);
-    } @else {
-        @return ('iro-prop-ref' $tree $key);
-    }
 }
-
-/// 
-/// Get the current namespace key.
-///
-/// @access private
-///
-@function get-ns-key() {
-    $ctx: contexts.get($namespace-context-id, 'namespace');
-
-    @if $ctx == null {
-        @return null;
-    }
-
-    $data: list.nth($ctx, 2);
-    $key:  map.get($data, 'key');
-
-    @return $key;
-}
-
-@include contexts.create($namespace-context-id);
-- 
cgit v1.2.3-70-g09d2