diff options
| author | Feuerfuchs <git@feuerfuchs.dev> | 2020-11-01 20:55:14 +0100 |
|---|---|---|
| committer | Feuerfuchs <git@feuerfuchs.dev> | 2020-11-01 20:55:14 +0100 |
| commit | d07f664450ddaaebb44127a4bd057763d13d3f82 (patch) | |
| tree | 234cfd673ac527869a8dda4f32afbec48c87b512 /src/_props.scss | |
| download | iro-sass-d07f664450ddaaebb44127a4bd057763d13d3f82.tar.gz iro-sass-d07f664450ddaaebb44127a4bd057763d13d3f82.tar.bz2 iro-sass-d07f664450ddaaebb44127a4bd057763d13d3f82.zip | |
Init
Diffstat (limited to 'src/_props.scss')
| -rw-r--r-- | src/_props.scss | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/src/_props.scss b/src/_props.scss new file mode 100644 index 0000000..7377c88 --- /dev/null +++ b/src/_props.scss | |||
| @@ -0,0 +1,281 @@ | |||
| 1 | //// | ||
| 2 | /// Property trees. | ||
| 3 | /// | ||
| 4 | /// Property trees allow you to organize properties in a tree structure (internally nested maps). | ||
| 5 | /// The intended use is to store all your properties at the beginning and for the rest of the | ||
| 6 | /// stylesheet you just get them. | ||
| 7 | /// | ||
| 8 | /// @group Property trees | ||
| 9 | /// | ||
| 10 | /// @access public | ||
| 11 | //// | ||
| 12 | |||
| 13 | /// | ||
| 14 | /// The maximum depth of resolved iro-prop-ref() references. | ||
| 15 | /// | ||
| 16 | /// @type number | ||
| 17 | /// | ||
| 18 | $iro-props-native-assing-max-depth: 2 !default; | ||
| 19 | |||
| 20 | /// | ||
| 21 | /// Indicate if property names must start with two dashes (--). | ||
| 22 | /// This is required if property trees are also used for native CSS custom properties. | ||
| 23 | /// | ||
| 24 | /// @type bool | ||
| 25 | /// | ||
| 26 | $iro-props-enforce-double-dashes: true !default; | ||
| 27 | |||
| 28 | /// | ||
| 29 | /// Default tree name to use if no name is specified. | ||
| 30 | /// | ||
| 31 | /// @type string | ||
| 32 | /// | ||
| 33 | $iro-props-default-tree: 'default' !default; | ||
| 34 | |||
| 35 | /// | ||
| 36 | /// List of all created property trees. | ||
| 37 | /// | ||
| 38 | /// @type list | ||
| 39 | /// | ||
| 40 | /// @access private | ||
| 41 | /// | ||
| 42 | $iro-props-trees: (); | ||
| 43 | |||
| 44 | /// | ||
| 45 | /// Save a property tree. If a tree with the sane name already exists, the trees | ||
| 46 | /// will be merged. | ||
| 47 | /// | ||
| 48 | /// @param {map} $map - Map containing properties | ||
| 49 | /// @param {string} $tree [$iro-props-default-tree] - ID the map is saved as | ||
| 50 | /// @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. | ||
| 51 | /// | ||
| 52 | @mixin iro-props-save($map, $tree: $iro-props-default-tree, $merge: false) { | ||
| 53 | $noop: iro-props-save($map, $tree, $merge); | ||
| 54 | } | ||
| 55 | |||
| 56 | /// | ||
| 57 | /// Save a property tree. | ||
| 58 | /// | ||
| 59 | /// @param {map} $map - Map containing properties | ||
| 60 | /// @param {string} $tree [$iro-props-default-tree] - ID the map is saved as | ||
| 61 | /// @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. | ||
| 62 | /// | ||
| 63 | @function iro-props-save($map, $tree: $iro-props-default-tree, $merge: false) { | ||
| 64 | $prop-map: null; | ||
| 65 | |||
| 66 | @if $iro-props-enforce-double-dashes { | ||
| 67 | @if not iro-props-validate($map) { | ||
| 68 | @error 'Property tree keys must start with two dashes (--). If you don\'t use property trees for native CSS custom properties, set $iro-props-enforce-double-dashes to false.'; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | @if map-has-key($iro-props-trees, $tree) { | ||
| 73 | @if $merge { | ||
| 74 | $map: iro-map-merge-recursive(map-get($iro-props-trees, $tree), $map); | ||
| 75 | } @else { | ||
| 76 | @error 'Property tree #{inspect($tree)} does already exist.'; | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | $iro-props-trees: map-merge($iro-props-trees, ($tree: $map)) !global; | ||
| 81 | |||
| 82 | @return null; | ||
| 83 | } | ||
| 84 | |||
| 85 | /// | ||
| 86 | /// Delete a property tree. | ||
| 87 | /// | ||
| 88 | /// @param {string} $tree [$iro-props-default-tree] - ID of the tree to be deleted | ||
| 89 | /// | ||
| 90 | @mixin iro-props-delete($tree: $iro-props-default-tree) { | ||
| 91 | $noop: iro-props-delete($tree); | ||
| 92 | } | ||
| 93 | |||
| 94 | /// | ||
| 95 | /// Unset a property tree. | ||
| 96 | /// | ||
| 97 | /// @param {string} $tree [$iro-props-default-tree] - ID of the tree to be deleted | ||
| 98 | /// | ||
| 99 | /// @throw If the property tree does not exist | ||
| 100 | /// | ||
| 101 | @function iro-props-delete($tree: $iro-props-default-tree) { | ||
| 102 | @if not map-has-key($iro-props-trees, $tree) { | ||
| 103 | @error 'Property tree "#{inspect($tree)}" does not exist.'; | ||
| 104 | } | ||
| 105 | |||
| 106 | $iro-props-trees: map-remove($iro-props-trees, $tree) !global; | ||
| 107 | |||
| 108 | @return null; | ||
| 109 | } | ||
| 110 | |||
| 111 | /// | ||
| 112 | /// Access a whole property or a subsection (i.e. value) of it. | ||
| 113 | /// | ||
| 114 | /// @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. | ||
| 115 | /// @param {string} $tree [$iro-props-default-tree] - ID of the property tree to use | ||
| 116 | /// @param {any} $default [null] - Default value to return of no match was found. If null, this function will throw an error instead. | ||
| 117 | /// | ||
| 118 | /// @return {any} Value assigned to property or $default | ||
| 119 | /// | ||
| 120 | /// @throw If there was no match for $key and $default is null | ||
| 121 | /// | ||
| 122 | @function iro-props-get($key: (), $tree: $iro-props-default-tree, $default: null) { | ||
| 123 | @if not map-has-key($iro-props-trees, $tree) { | ||
| 124 | @error 'Unknown tree "#{$tree}".'; | ||
| 125 | } | ||
| 126 | |||
| 127 | $result: map-get($iro-props-trees, $tree); | ||
| 128 | |||
| 129 | @if type-of($key) == list { | ||
| 130 | $stop: false; | ||
| 131 | |||
| 132 | @each $k in $key { | ||
| 133 | @if map-has-key($result, $k) and not $stop { | ||
| 134 | $result: map-get($result, $k); | ||
| 135 | |||
| 136 | @if type-of($result) == list and nth($result, 1) == 'iro-prop-ref' { | ||
| 137 | @if length($result) == 2 { | ||
| 138 | $result: iro-props-get($tree: nth($result, 2)); | ||
| 139 | } @else { | ||
| 140 | $result: iro-props-get(nth($result, 3), nth($result, 2)); | ||
| 141 | } | ||
| 142 | } | ||
| 143 | } @else { | ||
| 144 | $stop: true; | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | @if $stop { | ||
| 149 | $result: null; | ||
| 150 | } | ||
| 151 | } @else { | ||
| 152 | $result: map-get($result, $key); | ||
| 153 | |||
| 154 | @if type-of($result) == list and nth($result, 1) == 'iro-prop-ref' { | ||
| 155 | @if length($result) == 2 { | ||
| 156 | $result: iro-props-get($tree: nth($result, 2)); | ||
| 157 | } @else { | ||
| 158 | $result: iro-props-get(nth($result, 3), nth($result, 2)); | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | @if $result == null { | ||
| 164 | @if $default == null { | ||
| 165 | @error '"#{$key}" is null.'; | ||
| 166 | } @else { | ||
| 167 | @return $default; | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | @return $result; | ||
| 172 | } | ||
| 173 | |||
| 174 | /// | ||
| 175 | /// Generate a var() function call to get native CSS custom property. | ||
| 176 | /// | ||
| 177 | /// @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. | ||
| 178 | /// @param {string | null} $tree [null] - Optional tree to check if the property actually exists. | ||
| 179 | /// @param {any} $default [null] - Default value to return of no match was found. | ||
| 180 | /// | ||
| 181 | /// @return {string} var() | ||
| 182 | /// | ||
| 183 | @function iro-props-get-native($key, $tree: null, $default: null) { | ||
| 184 | @if $tree != null { | ||
| 185 | $noop: iro-props-get($key, $tree, $default); | ||
| 186 | } | ||
| 187 | |||
| 188 | $native-var: ''; | ||
| 189 | |||
| 190 | @if type-of($key) == list { | ||
| 191 | @each $subkey in $key { | ||
| 192 | $native-var: $native-var + $subkey; | ||
| 193 | } | ||
| 194 | } @else { | ||
| 195 | $native-var: $key; | ||
| 196 | } | ||
| 197 | |||
| 198 | @if $default == null { | ||
| 199 | @return var(#{$native-var}); | ||
| 200 | } @else { | ||
| 201 | @return var(#{$native-var}, #{$default}); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | |||
| 205 | /// | ||
| 206 | /// Generate assignments for native CSS custom properties with the values from the specified tree. | ||
| 207 | /// | ||
| 208 | /// @param {string} $tree [$iro-props-default-tree] - ID of the property tree to use | ||
| 209 | /// @param {string} $root [()] - Sub-tree to use for assignment | ||
| 210 | /// | ||
| 211 | @mixin iro-props-assign-native($tree: $iro-props-default-tree, $root: (), $skip: ()) { | ||
| 212 | $map: iro-props-get($root, $tree); | ||
| 213 | $map: map-remove($map, $skip...); | ||
| 214 | |||
| 215 | @include iro-props-assign-native-internal($map); | ||
| 216 | } | ||
| 217 | |||
| 218 | /// | ||
| 219 | /// @access private | ||
| 220 | /// | ||
| 221 | @mixin iro-props-assign-native-internal($map, $prefix: '', $ref-depth: $iro-props-native-assing-max-depth) { | ||
| 222 | @each $key, $value in $map { | ||
| 223 | $rd: $ref-depth; | ||
| 224 | @if type-of($value) == list and nth($value, 1) == 'iro-prop-ref' { | ||
| 225 | @if $ref-depth != 0 { | ||
| 226 | $rd: $rd - 1; | ||
| 227 | @if length($value) == 2 { | ||
| 228 | $value: iro-props-get($tree: nth($value, 2)); | ||
| 229 | } @else { | ||
| 230 | $value: iro-props-get(nth($value, 3), nth($value, 2)); | ||
| 231 | } | ||
| 232 | } @else { | ||
| 233 | $value: null; | ||
| 234 | } | ||
| 235 | } | ||
| 236 | @if type-of($value) != map { | ||
| 237 | #{$prefix + $key}: #{$value}; | ||
| 238 | } @else { | ||
| 239 | @include iro-props-assign-native-internal($value, $prefix + $key, $rd); | ||
| 240 | } | ||
| 241 | } | ||
| 242 | } | ||
| 243 | |||
| 244 | /// | ||
| 245 | /// Validate property names. | ||
| 246 | /// | ||
| 247 | /// @access private | ||
| 248 | /// | ||
| 249 | @function iro-props-validate($map) { | ||
| 250 | @each $key, $value in $map { | ||
| 251 | @if str-index($key, '--') != 1 { | ||
| 252 | @return false; | ||
| 253 | } | ||
| 254 | |||
| 255 | @if type-of($value) == map { | ||
| 256 | @if not iro-props-validate($value) { | ||
| 257 | @return false; | ||
| 258 | } | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 262 | @return true; | ||
| 263 | } | ||
| 264 | |||
| 265 | /// | ||
| 266 | /// Generate a reference to another tree. Dereferencing is lazy, so you may specify a tree that hasn't been created yet. | ||
| 267 | /// | ||
| 268 | /// @param {string} $tree [$iro-props-default-tree] - ID of the property tree to use | ||
| 269 | /// @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. | ||
| 270 | /// | ||
| 271 | /// @return {list} A special list that let's Ignis know that this is a lazy value. | ||
| 272 | /// | ||
| 273 | /// @throw If there was no match for $key and $default is null | ||
| 274 | /// | ||
| 275 | @function iro-props-ref($tree: $iro-props-default-tree, $key: null) { | ||
| 276 | @if $key == null { | ||
| 277 | @return ('iro-prop-ref' $tree); | ||
| 278 | } @else { | ||
| 279 | @return ('iro-prop-ref' $tree $key); | ||
| 280 | } | ||
| 281 | } | ||
