gerillass 0.0.6 → 3.0.0

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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +13 -0
  3. data/README.md +328 -0
  4. data/SKILL.md +282 -0
  5. data/gerillass.json +2713 -0
  6. data/lib/gerillass/engine.rb +55 -0
  7. data/lib/gerillass/jekyll.rb +13 -0
  8. data/lib/gerillass.rb +26 -0
  9. data/scss/_gerillass.scss +15 -0
  10. data/scss/internal/_color-problem.scss +99 -0
  11. data/scss/internal/_color-stops-problem.scss +94 -0
  12. data/scss/internal/_condition-width.scss +22 -0
  13. data/scss/internal/_custom-property-in.scss +25 -0
  14. data/scss/internal/_gradient.scss +425 -0
  15. data/scss/internal/_image-value.scss +68 -0
  16. data/scss/internal/_is-condition-value.scss +94 -0
  17. data/scss/internal/_is-css-function.scss +21 -0
  18. data/scss/internal/_is-size.scss +22 -0
  19. data/scss/internal/_keyword-value.scss +76 -0
  20. data/scss/internal/_length-problem.scss +127 -0
  21. data/scss/internal/_sibling-index.scss +51 -0
  22. data/scss/internal/_words.scss +35 -0
  23. data/scss/library/_adaptive.scss +31 -0
  24. data/scss/library/_after.scss +28 -0
  25. data/scss/library/_all-buttons.scss +21 -0
  26. data/scss/library/_all-text-inputs.scss +21 -0
  27. data/{core → scss}/library/_antialias.scss +5 -1
  28. data/scss/library/_aspect-ratio.scss +27 -0
  29. data/scss/library/_background-dots.scss +104 -0
  30. data/scss/library/_background-image.scss +89 -0
  31. data/scss/library/_background-stripes.scss +88 -0
  32. data/scss/library/_before.scss +28 -0
  33. data/scss/library/_border-box.scss +30 -0
  34. data/scss/library/_border-radius.scss +164 -0
  35. data/scss/library/_brand-logo.scss +33 -0
  36. data/scss/library/_breakpoint.scss +96 -0
  37. data/scss/library/_breakpointer.scss +40 -0
  38. data/scss/library/_center.scss +19 -0
  39. data/scss/library/_circle.scss +15 -0
  40. data/{core → scss}/library/_clearfix.scss +1 -1
  41. data/scss/library/_columnizer.scss +125 -0
  42. data/scss/library/_container-query.scss +119 -0
  43. data/scss/library/_container.scss +72 -0
  44. data/scss/library/_counter.scss +59 -0
  45. data/scss/library/_ellipsis.scss +87 -0
  46. data/scss/library/_escape-to-parent.scss +12 -0
  47. data/scss/library/_except.scss +71 -0
  48. data/scss/library/_focus-ring.scss +63 -0
  49. data/scss/library/_font-face.scss +240 -0
  50. data/scss/library/_gradient.scss +31 -0
  51. data/scss/library/_hide.scss +25 -0
  52. data/scss/library/_index.scss +57 -0
  53. data/scss/library/_line-clamp.scss +38 -0
  54. data/scss/library/_loadify.scss +62 -0
  55. data/scss/library/_motion-safe.scss +28 -0
  56. data/scss/library/_only.scss +73 -0
  57. data/scss/library/_placeholder-shown.scss +7 -0
  58. data/scss/library/_placeholder.scss +19 -0
  59. data/scss/library/_position.scss +72 -0
  60. data/scss/library/_remove.scss +40 -0
  61. data/scss/library/_reset-css.scss +57 -0
  62. data/scss/library/_reset-figure.scss +10 -0
  63. data/scss/library/_resizable.scss +34 -0
  64. data/scss/library/_responsive-image.scss +6 -0
  65. data/scss/library/_scissors.scss +34 -0
  66. data/scss/library/_screen-agent.scss +34 -0
  67. data/scss/library/_sizer.scss +15 -0
  68. data/scss/library/_smartphone.scss +29 -0
  69. data/scss/library/_sprite.scss +100 -0
  70. data/scss/library/_stretched-link.scss +21 -0
  71. data/scss/library/_tablet.scss +29 -0
  72. data/scss/library/_text-gradient.scss +48 -0
  73. data/scss/library/_text-image.scss +15 -0
  74. data/scss/library/_text-selection.scss +22 -0
  75. data/scss/library/_text-shadow.scss +145 -0
  76. data/scss/library/_text-stroke.scss +43 -0
  77. data/scss/library/_tokens.scss +111 -0
  78. data/scss/library/_triangle.scss +115 -0
  79. data/scss/lists/_index.scss +8 -0
  80. data/scss/lists/_list-of-anchor-pseudo-classes.scss +9 -0
  81. data/scss/lists/_list-of-buttons.scss +8 -0
  82. data/scss/lists/_list-of-counter-styles.scss +59 -0
  83. data/scss/lists/_list-of-directions.scss +12 -0
  84. data/scss/lists/_list-of-length-units.scss +23 -0
  85. data/scss/lists/_list-of-text-inputs.scss +20 -0
  86. data/scss/maps/_index.scss +8 -0
  87. data/scss/maps/_map-for-breakpoints.scss +9 -0
  88. data/scss/maps/_map-for-directions.scss +12 -0
  89. data/scss/maps/_map-for-font-formats.scss +9 -0
  90. data/scss/maps/_map-for-positions.scss +13 -0
  91. data/scss/maps/_map-for-smartphones.scss +72 -0
  92. data/scss/maps/_map-for-tablets.scss +32 -0
  93. data/scss/utilities/_clear-unit.scss +11 -0
  94. data/scss/utilities/_clear-whitespace.scss +15 -0
  95. data/scss/utilities/_convert-to-em.scss +16 -0
  96. data/scss/utilities/_convert-to-number.scss +45 -0
  97. data/scss/utilities/_fill-nulls.scss +18 -0
  98. data/scss/utilities/_fluid.scss +76 -0
  99. data/scss/utilities/_font-sizer.scss +19 -0
  100. data/scss/utilities/_font-source.scss +23 -0
  101. data/scss/utilities/_gradient-value.scss +24 -0
  102. data/scss/utilities/_index.scss +26 -0
  103. data/scss/utilities/_is-color.scss +16 -0
  104. data/scss/utilities/_is-gutter.scss +24 -0
  105. data/scss/utilities/_is-number.scss +11 -0
  106. data/scss/utilities/_is-time.scss +14 -0
  107. data/scss/utilities/_map-deep-get.scss +10 -0
  108. data/scss/utilities/_pixelify.scss +20 -0
  109. data/scss/utilities/_pseudo-selector.scss +12 -0
  110. data/scss/utilities/_remify.scss +16 -0
  111. data/scss/utilities/_shade.scss +10 -0
  112. data/scss/utilities/_shorthand-property.scss +17 -0
  113. data/scss/utilities/_tint.scss +10 -0
  114. data/scss/utilities/_validate-breakpoint.scss +41 -0
  115. data/scss/utilities/_validate-length.scss +37 -0
  116. data/scss/utilities/_validate-ratio.scss +77 -0
  117. data/scss/utilities/_validate-scissors.scss +34 -0
  118. metadata +131 -46
  119. data/core/_gerillass.scss +0 -4
  120. data/core/library/_before.scss +0 -18
  121. data/core/library/_border-box.scss +0 -26
@@ -0,0 +1,18 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+
5
+ @function fillNulls($value, $seperation: comma, $skip: false) {
6
+ @if not list.index("comma" "space" "slash", $seperation) {
7
+ @error "`#{$seperation}` is not a valid $seperation for `fillNulls`. Pass `comma`, `space` or `slash`.";
8
+ }
9
+ $list: ();
10
+ @for $i from 1 through list.length($value) {
11
+ @if list.nth($value, $i) == null {
12
+ $list: list.append($list, if($skip, null, 0), $seperation);
13
+ } @else {
14
+ $list: list.append($list, list.nth($value, $i), $seperation);
15
+ }
16
+ }
17
+ @return $list;
18
+ }
@@ -0,0 +1,76 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+ @use "sass:math";
5
+ @use "sass:meta";
6
+ @use "sass:string";
7
+ @use "../utilities/clear-unit" as *;
8
+ @use "../utilities/remify" as *;
9
+
10
+ // A value that grows with the viewport between two widths, then stops.
11
+ //
12
+ // clamp() takes a floor, a preferred value and a ceiling. The preferred value
13
+ // is the straight line through (min-viewport, min) and (max-viewport, max):
14
+ //
15
+ // slope = (max - min) / (max-viewport - min-viewport)
16
+ // intercept = min - slope * min-viewport
17
+ // preferred = intercept + slope * 100vw
18
+ //
19
+ // The intercept is emitted in rem rather than px deliberately. A preferred
20
+ // value made only of vw ignores browser zoom, which fails WCAG 1.4.4, and
21
+ // keeping a rem term in the sum is what restores it. This is the part that is
22
+ // easy to get wrong by hand, and the reason this is a function rather than a
23
+ // mixin: the value is the hard part, and it belongs to any property, not just
24
+ // font-size.
25
+ //
26
+ // Sass cannot add rem to vw, so the sum is assembled as a string. CSS evaluates
27
+ // it; Sass only writes it.
28
+
29
+ $_fluid-root-size: 16px;
30
+
31
+ @function fluid($min, $max, $min-viewport: 320px, $max-viewport: 1280px) {
32
+ // Pairs rather than a map: two arguments can legitimately hold the same
33
+ // length, and a map would reject that as a duplicate key.
34
+ $given: (($min, "$min"), ($max, "$max"), ($min-viewport, "$min-viewport"), ($max-viewport, "$max-viewport"));
35
+ @each $pair in $given {
36
+ $value: list.nth($pair, 1);
37
+ $label: list.nth($pair, 2);
38
+ @if meta.type-of($value) != "number" or math.is-unitless($value) {
39
+ @error "`#{$value}` is not a valid #{$label} for `fluid`. Pass a length in px or rem.";
40
+ }
41
+ @if math.unit($value) != "px" and math.unit($value) != "rem" {
42
+ @error "`#{$value}` is not a valid #{$label} for `fluid`. Pass a length in px or rem, not #{math.unit($value)}.";
43
+ }
44
+ }
45
+
46
+ // Everything is compared in px, because Sass cannot convert rem to px on its
47
+ // own: it has no way to know the root font size, so the assumption is stated
48
+ // here rather than hidden.
49
+ $min-px: $min;
50
+ $max-px: $max;
51
+ $from-px: $min-viewport;
52
+ $to-px: $max-viewport;
53
+ @if math.unit($min) == "rem" { $min-px: clearUnit($min) * $_fluid-root-size; }
54
+ @if math.unit($max) == "rem" { $max-px: clearUnit($max) * $_fluid-root-size; }
55
+ @if math.unit($min-viewport) == "rem" { $from-px: clearUnit($min-viewport) * $_fluid-root-size; }
56
+ @if math.unit($max-viewport) == "rem" { $to-px: clearUnit($max-viewport) * $_fluid-root-size; }
57
+
58
+ @if $from-px >= $to-px {
59
+ @error "`fluid` needs $min-viewport to be smaller than $max-viewport, and was given #{$min-viewport} and #{$max-viewport}.";
60
+ }
61
+ @if $min-px > $max-px {
62
+ @error "`fluid` needs $min to be no larger than $max, and was given #{$min} and #{$max}. clamp() would return the floor at every width, so the value would never grow.";
63
+ }
64
+
65
+ $slope: math.div($max-px - $min-px, $to-px - $from-px);
66
+ $intercept: $min-px - $slope * $from-px;
67
+
68
+ // Four decimals is past the point any browser renders differently, and keeps
69
+ // the output readable.
70
+ $vw: math.div(math.round($slope * 100 * 10000), 10000);
71
+ $floor: math.div(math.round(clearUnit(remify($min-px)) * 10000), 10000);
72
+ $base: math.div(math.round(clearUnit(remify($intercept)) * 10000), 10000);
73
+ $ceiling: math.div(math.round(clearUnit(remify($max-px)) * 10000), 10000);
74
+
75
+ @return string.unquote("clamp(#{$floor}rem, #{$base}rem + #{$vw}vw, #{$ceiling}rem)");
76
+ }
@@ -0,0 +1,19 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:math";
4
+ @use "sass:meta";
5
+
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
+ }
18
+ @return $size * $time;
19
+ }
@@ -0,0 +1,23 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+ @use "sass:map";
5
+ @use "../maps/map-for-font-formats" as *;
6
+ @use "../utilities/clear-whitespace" as *;
7
+
8
+ @function fontSource($font-family, $file-path, $file-formats) {
9
+ $list: ();
10
+ @if map.has-key($map-for-font-formats, $file-formats) {
11
+ @if list.index(eot woff2 woff ttf, $file-formats) {
12
+ $src-value: url('#{$file-path}.#{if(not list.index(eot, $file-formats), $file-formats, $file-formats+"?#iefix")}')
13
+ #{map.get($map-for-font-formats, $file-formats)};
14
+ $list: list.append($list, $src-value, comma);
15
+ } @else if list.index(svg, $file-formats) {
16
+ $font-family: clearWhitespace($font-family);
17
+ $src-value: url('#{$file-path}.#{$file-formats + "#" + $font-family}')
18
+ #{map.get($map-for-font-formats, $file-formats)};
19
+ $list: list.append($list, $src-value, comma);
20
+ }
21
+ }
22
+ @return $list;
23
+ }
@@ -0,0 +1,24 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "../internal/gradient" as *;
4
+
5
+ // The gradient mixin's gradient as a value, for where a mixin cannot write the
6
+ // whole declaration: layered with an image in one background-image, or as a
7
+ // mask-image or border-image. It takes the same arguments and refuses the same
8
+ // input; see scss/internal/_gradient.scss.
9
+ //
10
+ // A function returns one value, so unlike the mixin it cannot write a fallback
11
+ // before a gradient with $in. Write one yourself if an old browser matters:
12
+ // the same call with $in left out, in a declaration before it.
13
+ @function gradientValue(
14
+ $colors,
15
+ $type: linear,
16
+ $direction: null,
17
+ $shape: null,
18
+ $position: null,
19
+ $from: null,
20
+ $in: null,
21
+ $repeating: false
22
+ ) {
23
+ @return gradientOf($colors, $type, $direction, $shape, $position, $from, $in, $repeating, $member: "gradientValue");
24
+ }
@@ -0,0 +1,26 @@
1
+ @charset "UTF-8";
2
+
3
+ @forward "clear-unit";
4
+ @forward "clear-whitespace";
5
+ @forward "convert-to-em";
6
+ @forward "convert-to-number";
7
+ @forward "fill-nulls";
8
+ @forward "fluid";
9
+ @forward "font-sizer";
10
+ @forward "font-source";
11
+ @forward "gradient-value";
12
+ @forward "is-color";
13
+ @forward "is-gutter";
14
+ @forward "is-number";
15
+ @forward "is-time";
16
+ @forward "map-deep-get";
17
+ @forward "pixelify";
18
+ @forward "pseudo-selector";
19
+ @forward "remify";
20
+ @forward "shade";
21
+ @forward "shorthand-property";
22
+ @forward "tint";
23
+ @forward "validate-breakpoint";
24
+ @forward "validate-length";
25
+ @forward "validate-ratio";
26
+ @forward "validate-scissors";
@@ -0,0 +1,16 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+ @use "sass:meta";
5
+
6
+ @function isColor($value) {
7
+ $list: ();
8
+ @for $i from 1 through list.length($value) {
9
+ @if meta.type-of(list.nth($value, $i)) == "color" {
10
+ $list: list.append($list, list.nth($value, $i), comma);
11
+ } @else {
12
+ @error "'#{list.nth($value, $i)}' is not a color value, please replace it with a valid one.";
13
+ }
14
+ }
15
+ @return $list;
16
+ }
@@ -0,0 +1,24 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:meta";
4
+ @use "sass:string";
5
+
6
+ // True for anything that can legally sit where a CSS length is expected: a
7
+ // number, a Sass calculation such as calc() or clamp(), or an unquoted string
8
+ // holding a parenthesis, which is how var() and env() arrive.
9
+ //
10
+ // Written because `meta.type-of($value) == number` rejects `var(--gap)`, and a
11
+ // gutter expressed as a custom property is perfectly reasonable CSS.
12
+
13
+ @function isGutter($value) {
14
+ @if meta.type-of($value) == "number" {
15
+ @return true;
16
+ }
17
+ @if meta.type-of($value) == "calculation" {
18
+ @return true;
19
+ }
20
+ @if meta.type-of($value) == "string" and string.index(string.quote($value), "(") {
21
+ @return true;
22
+ }
23
+ @return false;
24
+ }
@@ -0,0 +1,11 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:meta";
4
+
5
+ @function isNumber($value) {
6
+ @if meta.type-of($value) == "number" {
7
+ @return $value;
8
+ } @else {
9
+ @warn "Please make sure you pass a valid number!";
10
+ }
11
+ }
@@ -0,0 +1,14 @@
1
+
2
+ @use "sass:list";
3
+ @use "sass:math";
4
+ @use "sass:meta";
5
+
6
+ @function isTime($value) {
7
+ @for $i from 1 through list.length($value) {
8
+ @if (meta.type-of($value) == "number" and list.index("ms" "s", math.unit($value)) != null) or $value == 0 {
9
+ @return $value;
10
+ } @else {
11
+ @error "'#{$value}' is not a valid time value. Time values must be specified in either seconds (s) or milliseconds (ms). Please try one of the following forms: '1s', '0.2s', or '3ms'";
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,10 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:map";
4
+
5
+ @function mapDeepGet($map, $keys...) {
6
+ @each $key in $keys {
7
+ $map: map.get($map, $key);
8
+ }
9
+ @return $map;
10
+ }
@@ -0,0 +1,20 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:math";
4
+ @use "sass:meta";
5
+ @use "../utilities/clear-unit" as *;
6
+
7
+ // This function checks if the argument has a px unit. If not, it adds a px unit to the end of the argument.
8
+
9
+ @function pixelify($value) {
10
+ @if meta.type-of($value) != "number" {
11
+ @error "`#{$value}` is not a valid $value for `pixelify`. Pass a number, with or without a unit.";
12
+ }
13
+ @if math.unit($value) == "px" {
14
+ @return $value;
15
+ } @else if math.unit($value) != "px" {
16
+ @return clearUnit($value) * 1px;
17
+ } @else if math.is-unitless($value) == true {
18
+ @return $value * 1px;
19
+ }
20
+ }
@@ -0,0 +1,12 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+
5
+ @function pseudoSelector($elements, $pseudo: null) {
6
+ $list: ();
7
+ @each $element in $elements {
8
+ $element: if($pseudo, $element + ":" + $pseudo, $element);
9
+ $list: list.append($list, $element, comma);
10
+ }
11
+ @return $list;
12
+ }
@@ -0,0 +1,16 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:math";
4
+ @use "sass:meta";
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
+ }
13
+ $base-value: 16px;
14
+ $rem-value: math.div($value, $base-value);
15
+ @return $rem-value * 1rem;
16
+ }
@@ -0,0 +1,10 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:color";
4
+ @use "../utilities/is-color" as *;
5
+
6
+ @function shade($color, $percentage) {
7
+ @if isColor($color) {
8
+ @return color.mix(black, $color, $percentage);
9
+ }
10
+ }
@@ -0,0 +1,17 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+
5
+ @function shorthandProperty($value) {
6
+ @if list.length($value) == 1 {
7
+ @return list.nth($value, 1) list.nth($value, 1) list.nth($value, 1) list.nth($value, 1);
8
+ } @else if list.length($value) == 2 {
9
+ @return list.nth($value, 1) list.nth($value, 2) list.nth($value, 1) list.nth($value, 2);
10
+ } @else if list.length($value) == 3 {
11
+ @return list.nth($value, 1) list.nth($value, 2) list.nth($value, 3) list.nth($value, 2);
12
+ } @else if list.length($value) == 4 {
13
+ @return list.nth($value, 1) list.nth($value, 2) list.nth($value, 3) list.nth($value, 4);
14
+ } @else if list.length($value) > 4 {
15
+ @error "You've passed #{list.length($value)} arguments. Please do not pass more than 4.";
16
+ }
17
+ }
@@ -0,0 +1,10 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:color";
4
+ @use "../utilities/is-color" as *;
5
+
6
+ @function tint($color, $percentage) {
7
+ @if isColor($color) {
8
+ @return color.mix(white, $color, $percentage);
9
+ }
10
+ }
@@ -0,0 +1,41 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+ @use "sass:map";
5
+ @use "sass:meta";
6
+ @use "sass:string";
7
+ @use "../maps/map-for-breakpoints" as *;
8
+
9
+ // Returns the width of a key from $map-for-breakpoints, and anything else as it
10
+ // is: a declaration takes a percentage or a CSS function, and the condition
11
+ // mixins check their own sizes through scss/internal/_condition-width.scss.
12
+ //
13
+ // What it refuses is what cannot be a breakpoint anywhere. A word that is not a
14
+ // key used to come back unchanged, so `breakpoint(min, huge)` compiled to
15
+ // `@media (min-width: huge)`, which never matches, without a word; the keys are
16
+ // case-sensitive, so `"MEDIUM"` did the same. A list used to give its first
17
+ // item, because the loop here returned on its first pass.
18
+ //
19
+ // null comes back as null, as it always did, so `width: validateBreakpoint(null)`
20
+ // still leaves the declaration out. The condition mixins refuse it themselves.
21
+ @function validateBreakpoint($value) {
22
+ @if $value == null {
23
+ @return null;
24
+ }
25
+ @if map.has-key($map-for-breakpoints, $value) {
26
+ @return map.get($map-for-breakpoints, $value);
27
+ }
28
+ @if list.length($value) > 1 {
29
+ @error "`#{meta.inspect($value)}` is not a breakpoint. Pass one key from $map-for-breakpoints or one length; a range is written with `between`, such as `breakpoint(between, small large)`.";
30
+ }
31
+ // A quoted length such as "600px" starts with a digit, a dot or a sign, and a
32
+ // CSS function holds a parenthesis. Of the words, the sizing keywords stay
33
+ // accepted, because `max-width: validateBreakpoint(none)` is valid CSS; a
34
+ // condition mixin still refuses them through conditionWidth. Anything else is
35
+ // a word that cannot be a breakpoint.
36
+ $sizing-keywords: "auto" "none" "min-content" "max-content" "fit-content" "stretch" "inherit" "initial" "unset" "revert" "revert-layer";
37
+ @if meta.type-of($value) == "string" and not list.index($sizing-keywords, string.to-lower-case($value)) and not string.index($value, "(") and not string.index("0123456789.+-", string.slice($value, 1, 1)) {
38
+ @error "`#{$value}` is not a breakpoint. $map-for-breakpoints has #{map.keys($map-for-breakpoints)}; pass one of those, or a length such as `600px`.";
39
+ }
40
+ @return $value;
41
+ }
@@ -0,0 +1,37 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+ @use "sass:math";
5
+ @use "sass:meta";
6
+ @use "sass:string";
7
+
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
+
16
+ $keywords: ("auto", "inherit", "initial", "unset", "revert", 0);
17
+
18
+ @if list.index($keywords, $value) {
19
+ @return $value;
20
+ }
21
+ @if meta.type-of($value) == "number" and not math.is-unitless($value) {
22
+ @return $value;
23
+ }
24
+ // calc(), clamp(), min() and max() arrive as Sass calculations; var() and
25
+ // env() arrive as unquoted strings holding a parenthesis. Both are valid
26
+ // lengths, and warning about them means warning about correct modern CSS,
27
+ // which this function used to do.
28
+ @if meta.type-of($value) == "calculation" {
29
+ @return $value;
30
+ }
31
+ @if meta.type-of($value) == "string" and string.index(string.quote($value), "(") {
32
+ @return $value;
33
+ }
34
+
35
+ @warn "`#{$value}` does not look like a length. Pass a number with a unit such as `20px`, a CSS function such as `var(--gap)` or `calc(1rem + 2px)`, or one of: auto, inherit, initial, unset, revert, 0.";
36
+ @return $value;
37
+ }
@@ -0,0 +1,77 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+ @use "sass:math";
5
+ @use "sass:meta";
6
+ @use "sass:string";
7
+ @use "../utilities/convert-to-number" as *;
8
+
9
+ // Returns a value for the CSS aspect-ratio property.
10
+ //
11
+ // Before 2.0.0 this returned the padding-top percentage the old ratio hack
12
+ // needed -- 56.25% for 16/9. aspect-ratio is Baseline Widely Available, so the
13
+ // hack is gone and this returns the ratio itself: `16 / 9`.
14
+ @function validateRatio($ratio) {
15
+ // No argument at all keeps the 16/9 default.
16
+ @if $ratio == null {
17
+ @return list.slash(16, 9);
18
+ }
19
+
20
+ @if meta.type-of($ratio) == "number" {
21
+ @if not math.is-unitless($ratio) {
22
+ @error "`#{$ratio}` is not a valid ratio. A numeric ratio must be unitless, like `1.77`.";
23
+ }
24
+ @if $ratio <= 0 {
25
+ @error "`#{$ratio}` is not a valid ratio. A numeric ratio must be greater than zero.";
26
+ }
27
+ // aspect-ratio takes a bare number, where 1.77 means 1.77 / 1.
28
+ @return $ratio;
29
+ }
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
+
38
+ @if meta.type-of($ratio) == "string" {
39
+ $separator: null;
40
+ @if string.index($ratio, "/") {
41
+ $separator: string.index($ratio, "/");
42
+ } @else if string.index($ratio, ":") {
43
+ $separator: string.index($ratio, ":");
44
+ } @else {
45
+ @error "`#{$ratio}` is not a valid ratio. A string ratio must separate width and height with `/` or `:`, like `\"16/9\"` or `\"16:9\"`.";
46
+ }
47
+
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);
66
+
67
+ @if $width == 0 {
68
+ @error "`#{$ratio}` is not a valid ratio. The width must be greater than zero.";
69
+ }
70
+ @return list.slash($width, $height);
71
+ }
72
+
73
+ // Anything else -- most commonly a list, which is what `16/9` becomes once
74
+ // Dart Sass 2.0.0 removes slash division. Without this the mixin would emit
75
+ // no aspect-ratio at all and silently produce a box with no ratio.
76
+ @error "`#{$ratio}` is not a valid ratio. Pass a string like `\"16/9\"` or `\"16:9\"`, a unitless number like `1.77`, or no argument at all for the 16/9 default. You passed a #{meta.type-of($ratio)}.";
77
+ }
@@ -0,0 +1,34 @@
1
+ @charset "UTF-8";
2
+
3
+ @use "sass:list";
4
+ @use "sass:math";
5
+ @use "sass:meta";
6
+ @use "../utilities/pixelify" as *;
7
+ @use "../internal/is-condition-value" as *;
8
+
9
+ @function validateScissors($value) {
10
+ $list: ();
11
+ @for $i from 1 through list.length($value) {
12
+ $item: list.nth($value, $i);
13
+ // math.is-unitless() below throws on anything that is not a number, and its message
14
+ // names its own parameter rather than the corner that was wrong.
15
+ @if $item != null and meta.type-of($item) != "number" {
16
+ @error "`#{$item}` is not a valid corner size. Pass a length such as `12px`, or a unitless number which is treated as pixels.";
17
+ }
18
+ // Each size becomes a polygon() coordinate, which in Chrome 152 kept a
19
+ // length, a percentage and a negative length, and dropped a unit that is not
20
+ // a length, such as deg or x, so the clip-path was dropped.
21
+ @if $item != null and not math.is-unitless($item) and not isConditionValue($item, "length-percentage") {
22
+ @error "`#{$item}` is not a valid corner size: `#{math.unit($item)}` is not a length unit, and a browser drops the clip-path. Pass a length such as `12px`, or a unitless number which is treated as pixels.";
23
+ }
24
+ @if list.nth($value, $i) == null {
25
+ $list: list.append($list, 0px, comma);
26
+ } @else if math.is-unitless(list.nth($value, $i)) {
27
+ $pixelified: pixelify(list.nth($value, $i));
28
+ $list: list.append($list, $pixelified, comma);
29
+ } @else {
30
+ $list: list.append($list, list.nth($value, $i), comma);
31
+ }
32
+ }
33
+ @return $list;
34
+ }