From 8f2ce6e4491d630a35dca9612daedf95b4a2954b Mon Sep 17 00:00:00 2001 From: Volpeon Date: Wed, 17 Mar 2021 17:32:14 +0100 Subject: Added namespaces and shortcodes for property trees --- src/_contexts.scss | 6 +- src/_props.scss | 182 ++++++++++++++++++++++++++++++++++++++++------ src/props-shortcodes.scss | 77 ++++++++++++++++++++ 3 files changed, 238 insertions(+), 27 deletions(-) create mode 100644 src/props-shortcodes.scss (limited to 'src') diff --git a/src/_contexts.scss b/src/_contexts.scss index 556fde3..9fe0e8c 100644 --- a/src/_contexts.scss +++ b/src/_contexts.scss @@ -124,9 +124,9 @@ $iro-context-stacks: (); @error 'Context stack "#{inspect($stack-id)}" does not exist.'; } - $context: $id $data; - $context-stack: map-get($iro-context-stacks, $stack-id); - $context-stack: append($context-stack, $context); + $context: $id $data; + $context-stack: map-get($iro-context-stacks, $stack-id); + $context-stack: append($context-stack, $context); $iro-context-stacks: map-merge($iro-context-stacks, ($stack-id: $context-stack)) !global; @return $context; diff --git a/src/_props.scss b/src/_props.scss index 86530f7..86a2215 100644 --- a/src/_props.scss +++ b/src/_props.scss @@ -41,26 +41,71 @@ $iro-props-default-tree: 'default' !default; /// $iro-props-trees: (); +/// +/// Default context name used for the namespace context. +/// +/// @type string +/// +$iro-props-namespace-context-id: 'namespace' !default; + +/// +/// Declare a namespace, meaning that all variables declared and accessed. +/// +/// @param {string} $name - Name of the namespace +/// +@mixin iro-props-namespace($name) { + $key: '--#{$name}'; + + $ns-key: iro-props-get-ns-key(); + + @if $ns-key != null { + $key: append($ns-key, $key); + } @else { + $key: ($key); + } + + @include iro-context-push($iro-props-namespace-context-id, 'namespace', ( + 'name': $name, + 'key': $key + )); + + @content; + + @include iro-context-pop($iro-props-namespace-context-id); +} + +/// +/// Get the current namespace name. +/// +@function iro-props-ns-name() { + $noop: iro-context-assert-stack-must-contain($iro-props-namespace-context-id, 'namespace'); + + $data: nth(iro-context-get($iro-props-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 {map} $map - Map containing properties /// @param {string} $tree [$iro-props-default-tree] - ID the map is saved as -/// @param {bool} $merge [false] - If a tree named $tree already exists and this value is set to true, they will be merged. Otherwise an error will be emitted. +/// @param {bool} $merge [false] - 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 iro-props-save($map, $tree: $iro-props-default-tree, $merge: false) { - $noop: iro-props-save($map, $tree, $merge); +@mixin iro-props-store($map, $tree: $iro-props-default-tree, $merge: false, $global: false) { + $noop: iro-props-store($map, $tree, $merge, $global); } /// /// Save a property tree. /// -/// @param {map} $map - Map containing properties +/// @param {map} $map - Map containing properties /// @param {string} $tree [$iro-props-default-tree] - ID the map is saved as -/// @param {bool} $merge [false] - If a tree named $tree already exists and this value is set to true, they will be merged. Otherwise an error will be emitted. +/// @param {bool} $merge [false] - 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 iro-props-save($map, $tree: $iro-props-default-tree, $merge: false) { +@function iro-props-store($map, $tree: $iro-props-default-tree, $merge: false, $global: false) { $prop-map: null; @if $iro-props-enforce-double-dashes { @@ -69,6 +114,14 @@ $iro-props-trees: (); } } + @if not $global { + $ns-key: iro-props-get-ns-key(); + + @if $ns-key != null { + $map: ($ns-key: $map) + } + } + @if map-has-key($iro-props-trees, $tree) { @if $merge { $map: iro-map-merge-recursive(map-get($iro-props-trees, $tree), $map); @@ -87,18 +140,18 @@ $iro-props-trees: (); /// /// @param {string} $tree [$iro-props-default-tree] - ID of the tree to be deleted /// -@mixin iro-props-delete($tree: $iro-props-default-tree) { - $noop: iro-props-delete($tree); +@mixin iro-props-clear($tree: $iro-props-default-tree) { + $noop: iro-props-clear($tree); } /// -/// Unset a property tree. +/// Delete a property tree. /// /// @param {string} $tree [$iro-props-default-tree] - ID of the tree to be deleted /// /// @throw If the property tree does not exist /// -@function iro-props-delete($tree: $iro-props-default-tree) { +@function iro-props-clear($tree: $iro-props-default-tree) { @if not map-has-key($iro-props-trees, $tree) { @error 'Property tree "#{inspect($tree)}" does not exist.'; } @@ -111,33 +164,50 @@ $iro-props-trees: (); /// /// 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 | 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 [$iro-props-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. +/// @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 iro-props-get($key: (), $tree: $iro-props-default-tree, $default: null) { +@function iro-props-get($key: (), $tree: $iro-props-default-tree, $default: null, $global: false) { @if not map-has-key($iro-props-trees, $tree) { @error 'Unknown tree "#{$tree}".'; } $result: map-get($iro-props-trees, $tree); + @if not $global { + $ns-key: iro-props-get-ns-key(); + + @if $ns-key != null { + $orig-key: $key; + $key: $ns-key; + + @if type-of($orig-key) == list { + @each $subkey in $orig-key { + $key: append($key, $subkey); + } + } @else { + $key: append($key, $orig-key); + } + } + } + @if type-of($key) == list { $stop: false; @each $k in $key { - @if map-has-key($result, $k) and not $stop { + @if not $stop and map-has-key($result, $k) { $result: map-get($result, $k); @if type-of($result) == list and nth($result, 1) == 'iro-prop-ref' { @if length($result) == 2 { - $result: iro-props-get($tree: nth($result, 2)); + $result: iro-props-get($tree: nth($result, 2), $global: true); } @else { - $result: iro-props-get(nth($result, 3), nth($result, 2)); + $result: iro-props-get(nth($result, 3), nth($result, 2), $global: true); } } } @else { @@ -153,9 +223,9 @@ $iro-props-trees: (); @if type-of($result) == list and nth($result, 1) == 'iro-prop-ref' { @if length($result) == 2 { - $result: iro-props-get($tree: nth($result, 2)); + $result: iro-props-get($tree: nth($result, 2), $global: true); } @else { - $result: iro-props-get(nth($result, 3), nth($result, 2)); + $result: iro-props-get(nth($result, 3), nth($result, 2), $global: true); } } } @@ -180,11 +250,28 @@ $iro-props-trees: (); /// /// @return {string} var() /// -@function iro-props-get-native($key, $tree: null, $default: null) { +@function iro-props-get-native($key, $tree: null, $default: null, $global: false) { @if $tree != null { $noop: iro-props-get($key, $tree, $default); } + @if not $global { + $ns-key: iro-props-get-ns-key(); + + @if $ns-key != null { + $orig-key: $key; + $key: $ns-key; + + @if type-of($orig-key) == list { + @each $subkey in $orig-key { + $key: append($key, $subkey); + } + } @else { + $key: append($key, $orig-key); + } + } + } + $native-var: ''; @if type-of($key) == list { @@ -206,9 +293,9 @@ $iro-props-trees: (); /// Generate assignments for native CSS custom properties with the values from the specified tree. /// /// @param {string} $tree [$iro-props-default-tree] - ID of the property tree to use -/// @param {string} $root [()] - Sub-tree to use for assignment +/// @param {string} $root [()] - Sub-tree to use for assignment /// -@mixin iro-props-assign-native($tree: $iro-props-default-tree, $root: (), $skip: (), $prefix: '') { +@mixin iro-props-assign-native($tree: $iro-props-default-tree, $root: (), $skip: (), $prefix: '', $global: false) { $map: iro-props-get($root, $tree); $map: map-remove($map, $skip...); @@ -216,6 +303,14 @@ $iro-props-trees: (); $prefix: iro-str-implode($prefix) } + @if not $global { + $ns-key: iro-props-get-ns-key(); + + @if $ns-key != null { + $prefix: $prefix + iro-str-implode($ns-key); + } + } + @include iro-props-assign-native-internal($map, $prefix); } @@ -270,16 +365,55 @@ $iro-props-trees: (); /// Generate a reference to another tree. Dereferencing is lazy, so you may specify a tree that hasn't been created yet. /// /// @param {string} $tree [$iro-props-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. +/// @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 iro-props-ref($tree: $iro-props-default-tree, $key: null) { +@function iro-props-ref($tree: $iro-props-default-tree, $key: null, $global: false) { + @if not $global { + $ns-key: iro-props-get-ns-key(); + + @if $ns-key != null { + $orig-key: $key; + $key: $ns-key; + + @if $orig-key != null { + @if type-of($orig-key) == list { + @each $subkey in $orig-key { + $key: append($key, $subkey); + } + } @else { + $key: append($key, $orig-key); + } + } + } + } + @if $key == null { @return ('iro-prop-ref' $tree); } @else { @return ('iro-prop-ref' $tree $key); } } + +/// +/// Get the current namespace key. +/// +/// @access private +/// +@function iro-props-get-ns-key() { + $ctx: iro-context-get($iro-props-namespace-context-id, 'namespace'); + + @if $ctx == null { + @return null; + } + + $data: nth($ctx, 2); + $key: map-get($data, 'key'); + + @return $key; +} + +@include iro-context-stack-create($iro-props-namespace-context-id); diff --git a/src/props-shortcodes.scss b/src/props-shortcodes.scss new file mode 100644 index 0000000..2c678a7 --- /dev/null +++ b/src/props-shortcodes.scss @@ -0,0 +1,77 @@ +//// +/// Shorter version of the prop-related functions. Useful to reduce clutter. +/// +/// @group Props shortcodes +/// +/// @access public +//// + +/// +/// @alias iro-props-namespace +/// +@mixin namespace($name) { + @include iro-props-namespace($name); +} + +/// +/// @alias iro-props-ns-name +/// +@function namespace() { + @return iro-props-ns-name(); +} + +/// +/// @alias iro-props-store +/// +@function store($map, $tree: $iro-props-default-tree, $merge: false, $global: false) { + @return iro-props-store($map, $tree, $merge, $global); +} + +/// +/// @alias iro-props-store +/// +@mixin store($map, $tree: $iro-props-default-tree, $merge: false, $global: false) { + @include iro-props-store($map, $tree, $merge, $global); +} + +/// +/// @alias iro-props-clear +/// +@mixin clear($tree: $iro-props-default-tree) { + @include iro-props-clear($tree); +} + +/// +/// @alias iro-props-clear +/// +@function clear($tree: $iro-props-default-tree) { + @return iro-props-clear($tree); +} + +/// +/// @alias iro-props-get +/// +@function prop($key: (), $tree: $iro-props-default-tree, $default: null, $global: false) { + @return iro-props-get($key, $tree, $default, $global); +} + +/// +/// @alias iro-props-get-native +/// +@function n-prop($key, $tree: null, $default: null, $global: false) { + @return iro-props-get-native($key, $tree, $default, $global); +} + +/// +/// @alias iro-props-assign-native +/// +@mixin n-assign($tree: $iro-props-default-tree, $root: (), $skip: (), $prefix: '', $global: false) { + @include iro-props-assign-native($tree, $root, $skip, $prefix, $global); +} + +/// +/// @alias iro-props-ref +/// +@function ref($tree: $iro-props-default-tree, $key: null, $global: false) { + @return iro-props-ref($tree, $key, $global); +} -- cgit v1.2.3-70-g09d2