gerillass 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,75 @@
1
1
  @charset "UTF-8";
2
2
 
3
3
  @use "sass:list";
4
- @use "sass:math";
4
+ @use "sass:meta";
5
+ @use "sass:string";
5
6
  @use "../lists/list-of-directions" as *;
6
- @use "../utilities/is-color" as *;
7
+
8
+ // A size Sass can use inside calc(): a number, a calculation such as calc(),
9
+ // min() or clamp(), or var() and env(), which only the browser can resolve.
10
+ // Anything else would pass silently through calc(): `calc(nonsense * 5)`
11
+ // compiles.
12
+ @function -is-size($value) {
13
+ @if meta.type-of($value) == "number" or meta.type-of($value) == "calculation" {
14
+ @return true;
15
+ }
16
+ @if meta.type-of($value) == "string" and string.slice(meta.inspect($value), 1, 1) != "\"" {
17
+ $open: string.index($value, "(");
18
+ @return $open != null and list.index("var" "env", string.to-lower-case(string.slice($value, 1, $open - 1))) != null;
19
+ }
20
+ @return false;
21
+ }
22
+
23
+ // A value CSS will take as a colour: a Sass colour, currentColor, or a function
24
+ // that returns a colour when the browser resolves it. A list passes when every
25
+ // item does, as it did through isColor.
26
+ //
27
+ // inherit, initial, unset and revert are left out on purpose. The mixin writes
28
+ // the colour into a border-color shorthand beside `transparent`, and a CSS-wide
29
+ // keyword is only valid as the whole value: `transparent transparent inherit`
30
+ // is rejected by the browser. Checked with CSS.supports in Chrome 152.
31
+ //
32
+ // Deliberately looser than isColor, which stays strict because tint and shade
33
+ // pass its result to color.mix, and that needs a real Sass colour. A border
34
+ // colour does not. The functions are named rather than "anything with a
35
+ // parenthesis", which would let url() through as a colour.
36
+ @function -is-css-color($value) {
37
+ @if list.length($value) > 1 {
38
+ @each $item in $value {
39
+ @if not -is-css-color($item) {
40
+ @return false;
41
+ }
42
+ }
43
+ @return true;
44
+ }
45
+ @if meta.type-of($value) == "color" {
46
+ @return true;
47
+ }
48
+ @if meta.type-of($value) == "string" and string.slice(meta.inspect($value), 1, 1) != "\"" {
49
+ $text: string.to-lower-case($value);
50
+ @if $text == "currentcolor" {
51
+ @return true;
52
+ }
53
+ $open: string.index($text, "(");
54
+ @if $open and list.index("var" "color-mix" "light-dark" "env", string.slice($text, 1, $open - 1)) {
55
+ @return true;
56
+ }
57
+ }
58
+ @return false;
59
+ }
7
60
 
8
61
  @mixin triangle($direction: "bottom", $color: black, $size: 10px 8px) {
9
62
  @if list.index($list-of-directions, $direction) {
10
- @if isColor($color){
63
+ // Halving a size in calc() rather than math.div() keeps var() and clamp()
64
+ // working instead of emitting `var(--w)/2`, which is not valid CSS.
65
+ @each $item in $size {
66
+ @if not -is-size($item) {
67
+ @error "`#{meta.inspect($size)}` is not a valid $size for `triangle`. Pass one or two lengths, or var(), env() or a calculation in place of either.";
68
+ }
69
+ }
70
+ @if not -is-css-color($color) {
71
+ @error "`#{meta.inspect($color)}` is not a valid $color for `triangle`. Pass a colour, `currentColor`, or a CSS function such as `var(--accent)`, `color-mix(...)` or `light-dark(...)`.";
72
+ } @else {
11
73
  content: "";
12
74
  height: 0;
13
75
  width: 0;
@@ -15,25 +77,25 @@
15
77
  border-style: solid;
16
78
  @if $direction == "top"{
17
79
  border-color: transparent transparent $color;
18
- border-width: 0 math.div(list.nth($size, 1), 2) if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1));
80
+ border-width: 0 calc(list.nth($size, 1) / 2) if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1));
19
81
  } @else if $direction == "top-right" {
20
82
  border-color: transparent $color transparent transparent;
21
83
  border-width: 0 list.nth($size, 1) list.nth($size, 1) 0;
22
84
  } @else if $direction == "right" {
23
85
  border-color: transparent transparent transparent $color;
24
- border-width: math.div(if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)), 2) 0 math.div(if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)), 2) list.nth($size, 1);
86
+ border-width: calc(if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)) / 2) 0 calc(if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)) / 2) list.nth($size, 1);
25
87
  } @else if $direction == "bottom-right" {
26
88
  border-color: transparent transparent $color;
27
89
  border-width: 0 0 list.nth($size, 1) list.nth($size, 1);
28
90
  } @else if $direction == "bottom" {
29
91
  border-color: $color transparent transparent;
30
- border-width: if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)) math.div(list.nth($size, 1), 2) 0;
92
+ border-width: if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)) calc(list.nth($size, 1) / 2) 0;
31
93
  } @else if $direction == "bottom-left" {
32
94
  border-color: transparent transparent transparent $color;
33
95
  border-width: list.nth($size, 1) 0 0 list.nth($size, 1);
34
96
  } @else if $direction == "left" {
35
97
  border-color: transparent $color transparent transparent;
36
- border-width: math.div(if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)), 2) list.nth($size, 1) math.div(if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)), 2) 0;
98
+ border-width: calc(if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)) / 2) list.nth($size, 1) calc(if(list.length($size) == 2, list.nth($size, 2), list.nth($size, 1)) / 2) 0;
37
99
  } @else if $direction == "top-left" {
38
100
  border-color: $color transparent transparent;
39
101
  border-width: list.nth($size, 1) list.nth($size, 1) 0 0;
@@ -1,7 +1,11 @@
1
1
  @charset "UTF-8";
2
2
 
3
3
  @use "sass:math";
4
+ @use "sass:meta";
4
5
 
5
6
  @function clearUnit($value) {
7
+ @if meta.type-of($value) != "number" {
8
+ @error "`#{meta.inspect($value)}` is not a valid $value for `clearUnit`. Pass a number, such as `24px`.";
9
+ }
6
10
  @return math.div($value, ($value * 0 + 1));
7
11
  }
@@ -2,8 +2,14 @@
2
2
 
3
3
  @use "sass:string";
4
4
  @use "sass:math";
5
+ @use "sass:meta";
5
6
 
6
7
  @function convertToEm($value) {
8
+ // Only a pixel length converts cleanly. A unitless number or another unit
9
+ // compiled to `calc(1.5 / 1px)em`, and a word or var() to `var(--x)/16pxem`.
10
+ @if meta.type-of($value) != "number" or math.unit($value) != "px" {
11
+ @error "`#{meta.inspect($value)}` is not a valid $value for `convertToEm`. Pass a pixel length, such as `24px`.";
12
+ }
7
13
  $base-value: 16px;
8
14
  $rem-value: math.div($value, $base-value);
9
15
  @return $rem-value + string.unquote("em");
@@ -11,6 +11,21 @@
11
11
  }
12
12
 
13
13
  $string-numerals: "0" "1" "2" "3" "4" "5" "6" "7" "8" "9";
14
+
15
+ // Every character has to be a digit before the parse runs. Otherwise an
16
+ // empty string or a sign failed with Sass's own "Undefined operation", and a
17
+ // letter or a space was folded into nonsense such as `40-1`. The empty case
18
+ // is checked first because `@for $i from 1 through 0` counts down, not zero
19
+ // times.
20
+ @if string.length($value) == 0 {
21
+ @error "`\"\"` is not a valid $value for `convertToNumber`. Pass a string made only of digits, such as `\"42\"`.";
22
+ }
23
+ @for $i from 1 through string.length($value) {
24
+ @if not list.index($string-numerals, string.slice($value, $i, $i)) {
25
+ @error "`#{meta.inspect($value)}` is not a valid $value for `convertToNumber`. Pass a string made only of digits, such as `\"42\"`.";
26
+ }
27
+ }
28
+
14
29
  $calc: 0;
15
30
 
16
31
  @for $i from 1 through string.length($value) {
@@ -1,5 +1,19 @@
1
1
  @charset "UTF-8";
2
2
 
3
+ @use "sass:math";
4
+ @use "sass:meta";
5
+
3
6
  @function fontSizer($size, $time) {
7
+ @if meta.type-of($size) != "number" {
8
+ @error "`#{meta.inspect($size)}` is not a valid $size for `fontSizer`. Pass a length, such as `16px`.";
9
+ }
10
+ @if meta.type-of($time) != "number" {
11
+ @error "`#{meta.inspect($time)}` is not a valid $time for `fontSizer`. Pass a multiplier, such as `1.5`.";
12
+ }
13
+ // Two units multiply into a unit squared, which Sass writes as
14
+ // `calc(16px * 1px)`: not a length anywhere in CSS.
15
+ @if not math.is-unitless($size) and not math.is-unitless($time) {
16
+ @error "`fontSizer(#{$size}, #{$time})` multiplies two units, which is not a length. Pass the multiplier without a unit, such as `1.5`.";
17
+ }
4
18
  @return $size * $time;
5
19
  }
@@ -1,8 +1,15 @@
1
1
  @charset "UTF-8";
2
2
 
3
3
  @use "sass:math";
4
+ @use "sass:meta";
4
5
 
5
6
  @function remify($value) {
7
+ // Only a pixel length converts cleanly. Anything else used to reach the
8
+ // arithmetic unchecked: a word failed with Sass's own "Undefined operation",
9
+ // and a unitless number or another unit compiled to `calc(1.5rem / 1px)`.
10
+ @if meta.type-of($value) != "number" or math.unit($value) != "px" {
11
+ @error "`#{meta.inspect($value)}` is not a valid $value for `remify`. Pass a pixel length, such as `24px`.";
12
+ }
6
13
  $base-value: 16px;
7
14
  $rem-value: math.div($value, $base-value);
8
15
  @return $rem-value * 1rem;
@@ -6,6 +6,13 @@
6
6
  @use "sass:string";
7
7
 
8
8
  @function validateLength($value) {
9
+ // null means "leave this out": `position` skips an edge given null, as its
10
+ // documentation shows. It is not a mistake to warn about, and the warning
11
+ // printed empty backticks, because null interpolates to nothing.
12
+ @if $value == null {
13
+ @return null;
14
+ }
15
+
9
16
  $keywords: ("auto", "inherit", "initial", "unset", "revert", 0);
10
17
 
11
18
  @if list.index($keywords, $value) {
@@ -28,6 +28,13 @@
28
28
  @return $ratio;
29
29
  }
30
30
 
31
+ // var() is resolved by the browser. Checked inline rather than through a
32
+ // helper function, which tools/build-manifest.js would take for this file's
33
+ // member in place of validateRatio.
34
+ @if meta.type-of($ratio) == "string" and string.slice(meta.inspect($ratio), 1, 1) != "\"" and string.index(string.to-lower-case($ratio), "var(") == 1 {
35
+ @return $ratio;
36
+ }
37
+
31
38
  @if meta.type-of($ratio) == "string" {
32
39
  $separator: null;
33
40
  @if string.index($ratio, "/") {
@@ -38,8 +45,24 @@
38
45
  @error "`#{$ratio}` is not a valid ratio. A string ratio must separate width and height with `/` or `:`, like `\"16/9\"` or `\"16:9\"`.";
39
46
  }
40
47
 
41
- $width: convertToNumber(string.slice($ratio, 1, $separator - 1));
42
- $height: convertToNumber(string.slice($ratio, $separator + 1));
48
+ $width-text: string.slice($ratio, 1, $separator - 1);
49
+ $height-text: string.slice($ratio, $separator + 1);
50
+
51
+ // Checked here so a malformed ratio is reported as a ratio, rather than as
52
+ // a bad argument to convertToNumber, which the caller never called.
53
+ @each $part in ($width-text, $height-text) {
54
+ @if string.length($part) == 0 {
55
+ @error "`#{$ratio}` is not a valid ratio. Width and height must both be whole numbers, like `\"16/9\"` or `\"16:9\"`.";
56
+ }
57
+ @for $i from 1 through string.length($part) {
58
+ @if not list.index("0" "1" "2" "3" "4" "5" "6" "7" "8" "9", string.slice($part, $i, $i)) {
59
+ @error "`#{$ratio}` is not a valid ratio. Width and height must both be whole numbers, like `\"16/9\"` or `\"16:9\"`.";
60
+ }
61
+ }
62
+ }
63
+
64
+ $width: convertToNumber($width-text);
65
+ $height: convertToNumber($height-text);
43
66
 
44
67
  @if $width == 0 {
45
68
  @error "`#{$ratio}` is not a valid ratio. The width must be greater than zero.";