gerillass 2.2.1 → 2.3.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.
Files changed (48) hide show
  1. package/SKILL.md +19 -2
  2. package/gerillass.json +301 -69
  3. package/package.json +1 -1
  4. package/scss/internal/_color-problem.scss +99 -0
  5. package/scss/internal/_color-stops-problem.scss +94 -0
  6. package/scss/internal/_condition-width.scss +22 -0
  7. package/scss/internal/_custom-property-in.scss +25 -0
  8. package/scss/internal/_image-value.scss +68 -0
  9. package/scss/internal/_is-condition-value.scss +94 -0
  10. package/scss/internal/_is-css-function.scss +21 -0
  11. package/scss/internal/_is-size.scss +22 -0
  12. package/scss/internal/_keyword-value.scss +76 -0
  13. package/scss/internal/_length-problem.scss +127 -0
  14. package/scss/internal/_sibling-index.scss +51 -0
  15. package/scss/internal/_words.scss +35 -0
  16. package/scss/library/_adaptive.scss +17 -0
  17. package/scss/library/_after.scss +2 -12
  18. package/scss/library/_background-dots.scss +29 -37
  19. package/scss/library/_background-image.scss +37 -25
  20. package/scss/library/_background-stripes.scss +34 -37
  21. package/scss/library/_before.scss +2 -12
  22. package/scss/library/_border-radius.scss +83 -0
  23. package/scss/library/_brand-logo.scss +10 -24
  24. package/scss/library/_breakpoint.scss +16 -23
  25. package/scss/library/_circle.scss +7 -0
  26. package/scss/library/_columnizer.scss +62 -2
  27. package/scss/library/_container-query.scss +11 -27
  28. package/scss/library/_container.scss +2 -19
  29. package/scss/library/_counter.scss +3 -14
  30. package/scss/library/_ellipsis.scss +78 -1
  31. package/scss/library/_except.scss +15 -0
  32. package/scss/library/_focus-ring.scss +29 -0
  33. package/scss/library/_font-face.scss +117 -1
  34. package/scss/library/_line-clamp.scss +2 -13
  35. package/scss/library/_linear-gradient.scss +7 -0
  36. package/scss/library/_only.scss +16 -0
  37. package/scss/library/_position.scss +63 -12
  38. package/scss/library/_radial-gradient.scss +154 -0
  39. package/scss/library/_resizable.scss +29 -2
  40. package/scss/library/_screen-agent.scss +8 -22
  41. package/scss/library/_sizer.scss +9 -0
  42. package/scss/library/_sprite.scss +65 -0
  43. package/scss/library/_text-gradient.scss +8 -0
  44. package/scss/library/_text-image.scss +2 -23
  45. package/scss/library/_text-stroke.scss +30 -0
  46. package/scss/library/_triangle.scss +25 -56
  47. package/scss/utilities/_validate-breakpoint.scss +32 -6
  48. package/scss/utilities/_validate-scissors.scss +7 -0
@@ -5,8 +5,16 @@
5
5
  @use "sass:math";
6
6
  @use "sass:meta";
7
7
  @use "../maps/map-for-directions" as *;
8
+ @use "../internal/color-stops-problem" as *;
8
9
 
9
10
  @mixin text-gradient($direction, $colors) {
11
+ // A stop the browser does not keep drops the whole gradient, and with it the
12
+ // text, which this mixin makes transparent; see
13
+ // scss/internal/_color-stops-problem.scss.
14
+ $problem: colorStopsProblem($colors);
15
+ @if $problem {
16
+ @error "`#{meta.inspect($colors)}` is not a valid $colors for `text-gradient`: #{$problem}. A browser drops the whole gradient, and the transparent text with it.";
17
+ }
10
18
  $list: ();
11
19
  @for $i from 1 through list.length($colors) {
12
20
  $list: list.append($list, list.nth($colors, $i), comma);
@@ -1,31 +1,10 @@
1
1
  @charset "UTF-8";
2
2
 
3
- @use "sass:list";
4
- @use "sass:meta";
5
- @use "sass:string";
6
-
7
- // An image path goes into url(). A var(), url(), image-set() or gradient is
8
- // already an image, and wrapping it produced url(var(--x)), which loads nothing.
9
- @function -image($value) {
10
- @if -is-css-function($value, "var" "url" "image-set" "linear-gradient" "radial-gradient" "conic-gradient" "repeating-linear-gradient" "repeating-radial-gradient" "repeating-conic-gradient") {
11
- @return $value;
12
- }
13
- @return url($value);
14
- }
15
-
16
- // True for an unquoted call to one of $names, such as var(--x). A quoted string
17
- // stays text, so `"var(--x)"` is not a call.
18
- @function -is-css-function($value, $names) {
19
- @if meta.type-of($value) != "string" or string.slice(meta.inspect($value), 1, 1) == "\"" {
20
- @return false;
21
- }
22
- $open: string.index($value, "(");
23
- @return $open != null and list.index($names, string.to-lower-case(string.slice($value, 1, $open - 1))) != null;
24
- }
3
+ @use "../internal/image-value" as *;
25
4
 
26
5
  @mixin text-image($image: null) {
27
6
  @if $image {
28
- background-image: -image($image);
7
+ background-image: imageValue($image, "text-image", "$image");
29
8
  }
30
9
  background-size: cover;
31
10
  background-position: center;
@@ -1,11 +1,41 @@
1
1
  @charset "UTF-8";
2
2
 
3
+ @use "sass:meta";
4
+ @use "../internal/color-problem" as *;
5
+ @use "../internal/length-problem" as *;
6
+
7
+ // Each colour is a declaration of its own, where Chrome 152 kept a CSS-wide
8
+ // keyword and dropped a word that is not a colour, a quoted colour, a length and
9
+ // two colours side by side; see scss/internal/_color-problem.scss. null leaves
10
+ // that declaration out, as it always has.
3
11
  @mixin text-stroke(
4
12
  $fallback-color: black,
5
13
  $color: transparent,
6
14
  $stroke-color: black,
7
15
  $stroke-width: 1px
8
16
  ) {
17
+ $colors: (
18
+ "$fallback-color": $fallback-color,
19
+ "$color": $color,
20
+ "$stroke-color": $stroke-color,
21
+ );
22
+ @each $name, $value in $colors {
23
+ @if $value != null {
24
+ $problem: colorProblem($value, $css-wide: true);
25
+ @if $problem {
26
+ @error "`#{meta.inspect($value)}` is not a valid #{$name} for `text-stroke`: #{$problem}. A browser drops the declaration. Pass a colour such as `black`, `currentColor`, or a function such as `var(--stroke)`.";
27
+ }
28
+ }
29
+ }
30
+ // -webkit-text-stroke-width kept a length, 0, thin, medium or thick and a
31
+ // CSS-wide keyword in Chrome 152, and dropped a percentage and a negative
32
+ // width.
33
+ @if $stroke-width != null {
34
+ $problem: lengthProblem($stroke-width, $percent: false, $negative: false, $keywords: "thin" "medium" "thick", $css-wide: true);
35
+ @if $problem {
36
+ @error "`#{meta.inspect($stroke-width)}` is not a valid $stroke-width for `text-stroke`: #{$problem}. A browser drops the declaration.";
37
+ }
38
+ }
9
39
  color: $fallback-color;
10
40
  -webkit-text-fill-color: $color;
11
41
  -webkit-text-stroke-color: $stroke-color;
@@ -2,61 +2,10 @@
2
2
 
3
3
  @use "sass:list";
4
4
  @use "sass:meta";
5
- @use "sass:string";
6
5
  @use "../lists/list-of-directions" 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
- }
6
+ @use "../internal/is-size" as *;
7
+ @use "../internal/color-problem" as *;
8
+ @use "../internal/length-problem" as *;
60
9
 
61
10
  // The logical directions point along the writing direction rather than a fixed
62
11
  // side: inline-end is right in a left-to-right page and left in a right-to-left
@@ -70,11 +19,31 @@ $-logical-directions: ("inline-start", "inline-end", "block-start", "block-end")
70
19
  // Halving a size in calc() rather than math.div() keeps var() and clamp()
71
20
  // working instead of emitting `var(--w)/2`, which is not valid CSS.
72
21
  @each $item in $size {
73
- @if not -is-size($item) {
22
+ @if not isSize($item) {
74
23
  @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.";
75
24
  }
25
+ // The sizes land in border-width, which in Chrome 152 dropped a
26
+ // percentage, a negative width and a unit that is not a length. isSize
27
+ // above takes any number, since it only guards calc().
28
+ $problem: lengthProblem($item, $percent: false, $negative: false);
29
+ @if $problem {
30
+ @error "`#{meta.inspect($size)}` is not a valid $size for `triangle`: #{$problem}. A browser drops the border widths, so no triangle is drawn.";
31
+ }
32
+ }
33
+ // The colour is checked by colorProblem in scss/internal/, each item of a
34
+ // list on its own, as isColor used to accept a list. CSS-wide keywords stay
35
+ // refused: the mixin writes the colour into a border-color shorthand beside
36
+ // `transparent`, and a CSS-wide keyword is only valid as the whole value, so
37
+ // `transparent transparent inherit` was rejected in Chrome 152. The check
38
+ // used to name four functions; system colours such as Canvas and
39
+ // contrast-color(), which a border keeps, were refused until it was shared.
40
+ $color-problem: null;
41
+ @each $item in $color {
42
+ @if not $color-problem {
43
+ $color-problem: colorProblem($item);
44
+ }
76
45
  }
77
- @if not -is-css-color($color) {
46
+ @if $color-problem {
78
47
  @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(...)`.";
79
48
  } @else {
80
49
  content: "";
@@ -2,14 +2,40 @@
2
2
 
3
3
  @use "sass:list";
4
4
  @use "sass:map";
5
+ @use "sass:meta";
6
+ @use "sass:string";
5
7
  @use "../maps/map-for-breakpoints" as *;
6
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.
7
21
  @function validateBreakpoint($value) {
8
- @for $i from 1 through list.length($value) {
9
- @if map.has-key($map-for-breakpoints, $value) {
10
- @return map.get($map-for-breakpoints, list.nth($value, $i));
11
- } @else {
12
- @return list.nth($value, $i);
13
- }
22
+ @if $value == null {
23
+ @return null;
14
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;
15
41
  }
@@ -4,6 +4,7 @@
4
4
  @use "sass:math";
5
5
  @use "sass:meta";
6
6
  @use "../utilities/pixelify" as *;
7
+ @use "../internal/is-condition-value" as *;
7
8
 
8
9
  @function validateScissors($value) {
9
10
  $list: ();
@@ -14,6 +15,12 @@
14
15
  @if $item != null and meta.type-of($item) != "number" {
15
16
  @error "`#{$item}` is not a valid corner size. Pass a length such as `12px`, or a unitless number which is treated as pixels.";
16
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
+ }
17
24
  @if list.nth($value, $i) == null {
18
25
  $list: list.append($list, 0px, comma);
19
26
  } @else if math.is-unitless(list.nth($value, $i)) {