gerillass 2.3.0 → 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.
- package/README.md +46 -7
- package/SKILL.md +37 -12
- package/gerillass.json +527 -145
- package/package.json +1 -1
- package/scss/internal/_color-problem.scss +99 -0
- package/scss/internal/_color-stops-problem.scss +94 -0
- package/scss/internal/_condition-width.scss +22 -0
- package/scss/internal/_custom-property-in.scss +25 -0
- package/scss/internal/_gradient.scss +425 -0
- package/scss/internal/_image-value.scss +68 -0
- package/scss/internal/_is-condition-value.scss +94 -0
- package/scss/internal/_is-css-function.scss +21 -0
- package/scss/internal/_is-size.scss +22 -0
- package/scss/internal/_keyword-value.scss +76 -0
- package/scss/internal/_length-problem.scss +127 -0
- package/scss/internal/_sibling-index.scss +51 -0
- package/scss/internal/_words.scss +35 -0
- package/scss/library/_adaptive.scss +17 -0
- package/scss/library/_after.scss +2 -12
- package/scss/library/_background-dots.scss +36 -43
- package/scss/library/_background-image.scss +40 -52
- package/scss/library/_background-stripes.scss +40 -54
- package/scss/library/_before.scss +2 -12
- package/scss/library/_border-radius.scss +83 -0
- package/scss/library/_brand-logo.scss +10 -24
- package/scss/library/_breakpoint.scss +19 -26
- package/scss/library/_circle.scss +7 -0
- package/scss/library/_columnizer.scss +62 -2
- package/scss/library/_container-query.scss +13 -29
- package/scss/library/_container.scss +2 -19
- package/scss/library/_counter.scss +3 -14
- package/scss/library/_ellipsis.scss +78 -1
- package/scss/library/_except.scss +15 -0
- package/scss/library/_focus-ring.scss +29 -0
- package/scss/library/_font-face.scss +117 -1
- package/scss/library/_gradient.scss +31 -0
- package/scss/library/_index.scss +1 -2
- package/scss/library/_line-clamp.scss +2 -13
- package/scss/library/_only.scss +16 -0
- package/scss/library/_position.scss +34 -3
- package/scss/library/_remove.scss +1 -1
- package/scss/library/_resizable.scss +29 -2
- package/scss/library/_screen-agent.scss +8 -22
- package/scss/library/_sizer.scss +9 -0
- package/scss/library/_sprite.scss +65 -0
- package/scss/library/_text-gradient.scss +36 -18
- package/scss/library/_text-image.scss +2 -23
- package/scss/library/_text-stroke.scss +30 -0
- package/scss/library/_triangle.scss +25 -56
- package/scss/utilities/_gradient-value.scss +24 -0
- package/scss/utilities/_index.scss +1 -0
- package/scss/utilities/_validate-breakpoint.scss +32 -6
- package/scss/utilities/_validate-scissors.scss +7 -0
- package/scss/library/_linear-gradient.scss +0 -26
- package/scss/library/_radial-gradient.scss +0 -30
package/scss/library/_only.scss
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
@use "sass:list";
|
|
4
4
|
@use "sass:meta";
|
|
5
5
|
@use "sass:string";
|
|
6
|
+
@use "../internal/sibling-index" as *;
|
|
6
7
|
|
|
7
8
|
@mixin only($params...) {
|
|
8
9
|
@if list.length($params) == 0 {
|
|
@@ -10,6 +11,12 @@
|
|
|
10
11
|
} @else if list.length($params) == 1 {
|
|
11
12
|
$value: list.nth($params, 1);
|
|
12
13
|
@if meta.type-of($value) == "number" {
|
|
14
|
+
// A unit or a fraction makes a selector the browser drops, and 0 matches
|
|
15
|
+
// nothing; see scss/internal/_sibling-index.scss.
|
|
16
|
+
$problem: siblingIndexProblem($value, "only");
|
|
17
|
+
@if $problem {
|
|
18
|
+
@error "`#{meta.inspect($value)}` is not a valid position for `only`: #{$problem}.";
|
|
19
|
+
}
|
|
13
20
|
@if $value < 0 {
|
|
14
21
|
&:nth-last-of-type(#{$value * -1}) {
|
|
15
22
|
@content;
|
|
@@ -46,6 +53,15 @@
|
|
|
46
53
|
@error "`#{$value}` is not a valid argument for `only`. Pass a positive or negative number, one of `first`, `last`, `odd`, `even`, or a selector such as `.foo`.";
|
|
47
54
|
}
|
|
48
55
|
} @else if list.length($params) > 1 {
|
|
56
|
+
// Every item is checked first. A word used to fail with Sass's own
|
|
57
|
+
// `Undefined operation`, and one bad position emptied the whole selector
|
|
58
|
+
// list, taking the good positions with it.
|
|
59
|
+
@each $item in $params {
|
|
60
|
+
$problem: siblingIndexProblem($item, "only", true);
|
|
61
|
+
@if $problem {
|
|
62
|
+
@error "`#{meta.inspect($item)}` is not a valid position for `only`: #{$problem}.";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
49
65
|
$list: ();
|
|
50
66
|
@for $i from 1 through list.length($params) {
|
|
51
67
|
$list: list.append($list, if(list.nth($params, $i) < 0, string.unquote("&:nth-last-of-type(#{list.nth($params, $i) * -1})"), string.unquote("&:nth-of-type(#{list.nth($params, $i)})")), comma);
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
@use "sass:list";
|
|
4
4
|
@use "sass:meta";
|
|
5
|
+
@use "sass:string";
|
|
5
6
|
@use "../utilities/shorthand-property" as *;
|
|
6
|
-
@use "../
|
|
7
|
+
@use "../internal/keyword-value" as *;
|
|
8
|
+
@use "../internal/length-problem" as *;
|
|
7
9
|
|
|
8
10
|
// Sets position and its four offsets in shorthand order: top, right, bottom,
|
|
9
11
|
// left, as `margin` and `padding` take them.
|
|
@@ -24,17 +26,46 @@
|
|
|
24
26
|
@if $logical != true and $logical != false and $logical != null {
|
|
25
27
|
@error "`#{meta.inspect($logical)}` is not a valid $logical for `position`. Pass true for offsets that follow the writing direction, or false for top, right, bottom and left.";
|
|
26
28
|
}
|
|
29
|
+
// Measured in Chrome 152, `position` kept the five keywords in any case, the
|
|
30
|
+
// CSS-wide keywords and var(), and dropped anything else, a quoted keyword
|
|
31
|
+
// included. A vendor keyword is let through: Chrome drops `-webkit-sticky`,
|
|
32
|
+
// which Safari uses. null leaves position out, as it always has.
|
|
33
|
+
$problem: keywordProblem($position, "static" "relative" "absolute" "fixed" "sticky", $vendor: true);
|
|
34
|
+
@if $problem {
|
|
35
|
+
@error "`#{meta.inspect($position)}` is not a valid $position for `position`: #{$problem}. A browser drops the declaration.";
|
|
36
|
+
}
|
|
27
37
|
|
|
28
38
|
$offsets: shorthandProperty($offsets);
|
|
39
|
+
// Each offset is a declaration of its own. Measured in Chrome 152, top, left
|
|
40
|
+
// and the inset-* properties kept a length, a negative length, a percentage,
|
|
41
|
+
// 0, auto and a CSS-wide keyword in any case, var(), maths functions, anchor()
|
|
42
|
+
// and anchor-size(), and dropped any other word, a unitless number, a unit
|
|
43
|
+
// that is not a length, a colour, an image and a quoted length. This used to
|
|
44
|
+
// go through validateLength, which only warns, and warned about working
|
|
45
|
+
// values such as AUTO and revert-layer while saying nothing about 10deg or
|
|
46
|
+
// url(); validateLength itself is unchanged, for callers who want a warning.
|
|
47
|
+
@each $value in $offsets {
|
|
48
|
+
@if $value != null {
|
|
49
|
+
$problem: lengthProblem($value, $keywords: ("auto",), $functions: "anchor" "anchor-size", $css-wide: true);
|
|
50
|
+
@if $problem {
|
|
51
|
+
@error "`#{meta.inspect($value)}` is not a valid offset for `position`: #{$problem}. A browser drops the declaration.";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
29
55
|
$edges: top right bottom left;
|
|
30
56
|
@if $logical {
|
|
31
57
|
$edges: inset-block-start inset-inline-end inset-block-end inset-inline-start;
|
|
32
58
|
}
|
|
33
59
|
|
|
34
|
-
position:
|
|
60
|
+
// Written without quotes, since `position: "sticky"` was dropped.
|
|
61
|
+
@if meta.type-of($position) == "string" {
|
|
62
|
+
position: string.unquote($position);
|
|
63
|
+
} @else {
|
|
64
|
+
position: $position;
|
|
65
|
+
}
|
|
35
66
|
@for $i from 1 through 4 {
|
|
36
67
|
$value: list.nth($offsets, $i);
|
|
37
|
-
@if
|
|
68
|
+
@if $value != null {
|
|
38
69
|
#{list.nth($edges, $i)}: $value;
|
|
39
70
|
}
|
|
40
71
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
@include breakpoint(only, $value) {
|
|
14
14
|
display: none;
|
|
15
15
|
}
|
|
16
|
-
@warn "`remove(#{$value})` hides the element only at a viewport exactly that wide, a single pixel. Write `remove(only, #{$value})` for that width, or `remove(min, #{$value})` from it upwards.
|
|
16
|
+
@warn "`remove(#{$value})` hides the element only at a viewport exactly that wide, a single pixel. Write `remove(only, #{$value})` for that width, or `remove(min, #{$value})` from it upwards.";
|
|
17
17
|
} @else if list.length($params) == 2 {
|
|
18
18
|
@if list.index("min" "max", list.nth($params, 1)) {
|
|
19
19
|
$mode: list.nth($params, 1);
|
|
@@ -1,7 +1,34 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
@use "sass:string";
|
|
5
|
+
@use "../internal/keyword-value" as *;
|
|
6
|
+
|
|
7
|
+
// Measured in Chrome 152, `resize` kept none, both, horizontal, vertical, block,
|
|
8
|
+
// inline and auto, and `overflow` one or two of visible, hidden, clip, scroll,
|
|
9
|
+
// auto and overlay, all in any case, with the CSS-wide keywords on their own and
|
|
10
|
+
// var(). Both dropped a quoted keyword, three overflow values, and a CSS-wide
|
|
11
|
+
// keyword beside another, such as `overflow: inherit auto`. null leaves the
|
|
12
|
+
// declaration out, as it always has.
|
|
3
13
|
@mixin resizable($direction: both, $overflow: auto) {
|
|
4
|
-
|
|
5
|
-
|
|
14
|
+
$problem: keywordProblem($direction, "none" "both" "horizontal" "vertical" "block" "inline" "auto");
|
|
15
|
+
@if $problem {
|
|
16
|
+
@error "`#{meta.inspect($direction)}` is not a valid $direction for `resizable`: #{$problem}. A browser drops the declaration.";
|
|
17
|
+
}
|
|
18
|
+
$problem: keywordProblem($overflow, "visible" "hidden" "clip" "scroll" "auto" "overlay", 2);
|
|
19
|
+
@if $problem {
|
|
20
|
+
@error "`#{meta.inspect($overflow)}` is not a valid $overflow for `resizable`: #{$problem}. A browser drops the declaration.";
|
|
21
|
+
}
|
|
22
|
+
// Written without quotes, since `resize: "both"` was dropped.
|
|
23
|
+
@if meta.type-of($direction) == "string" {
|
|
24
|
+
resize: string.unquote($direction);
|
|
25
|
+
} @else {
|
|
26
|
+
resize: $direction;
|
|
27
|
+
}
|
|
28
|
+
@if meta.type-of($overflow) == "string" {
|
|
29
|
+
overflow: string.unquote($overflow);
|
|
30
|
+
} @else {
|
|
31
|
+
overflow: $overflow;
|
|
32
|
+
}
|
|
6
33
|
max-width: 100%;
|
|
7
34
|
}
|
|
@@ -1,30 +1,11 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
|
-
@use "sass:list";
|
|
4
3
|
@use "sass:meta";
|
|
5
|
-
@use "
|
|
6
|
-
|
|
7
|
-
// Returns the first value in $value that holds var(), looking inside lists and
|
|
8
|
-
// calculations, or null. Custom properties are not evaluated in a @media or
|
|
9
|
-
// @container condition, so a rule built from one never applies, and nothing
|
|
10
|
-
// warns. Measured in Chrome 152: `(min-width: var(--wide))` did not match with
|
|
11
|
-
// `--wide: 200px`, while `(min-width: 200px)` did.
|
|
12
|
-
@function -custom-property-in($value) {
|
|
13
|
-
@each $item in $value {
|
|
14
|
-
@if meta.type-of($item) == "list" or meta.type-of($item) == "arglist" {
|
|
15
|
-
$found: -custom-property-in($item);
|
|
16
|
-
@if $found {
|
|
17
|
-
@return $found;
|
|
18
|
-
}
|
|
19
|
-
} @else if string.index(meta.inspect($item), "var(") {
|
|
20
|
-
@return $item;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
@return null;
|
|
24
|
-
}
|
|
4
|
+
@use "../internal/custom-property-in" as *;
|
|
5
|
+
@use "../internal/is-condition-value" as *;
|
|
25
6
|
|
|
26
7
|
@mixin screen-agent($resolution) {
|
|
27
|
-
$custom-property:
|
|
8
|
+
$custom-property: customPropertyIn($resolution);
|
|
28
9
|
@if $custom-property {
|
|
29
10
|
@error "`#{$custom-property}` cannot be used as a resolution: custom properties are not evaluated in a @media condition, so the rule would never apply. Pass `1x`, `2x`, `3x` or a resolution such as `2dppx`.";
|
|
30
11
|
}
|
|
@@ -41,6 +22,11 @@
|
|
|
41
22
|
@content;
|
|
42
23
|
}
|
|
43
24
|
} @else {
|
|
25
|
+
// Measured in Chrome 152, `(min-resolution: huge)`, `(min-resolution: 2)`,
|
|
26
|
+
// `(min-resolution: 10px)` and `(min-resolution: -1dppx)` never match.
|
|
27
|
+
@if not isConditionValue($resolution, "resolution") {
|
|
28
|
+
@error "`#{meta.inspect($resolution)}` is not a valid $resolution for `screen-agent`: `(min-resolution: #{meta.inspect($resolution)})` would never match. Pass `1x`, `2x`, `3x`, or a resolution such as `2dppx`, `192dpi` or `38dpcm`.";
|
|
29
|
+
}
|
|
44
30
|
@media (min-resolution: #{$resolution}) {
|
|
45
31
|
@content;
|
|
46
32
|
}
|
package/scss/library/_sizer.scss
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
@use "../internal/length-problem" as *;
|
|
5
|
+
|
|
3
6
|
@mixin sizer($width, $height: $width) {
|
|
7
|
+
@each $name, $value in ("$width": $width, "$height": $height) {
|
|
8
|
+
$problem: sizeProblem($value);
|
|
9
|
+
@if $problem {
|
|
10
|
+
@error "`#{meta.inspect($value)}` is not a valid #{$name} for `sizer`: #{$problem}. A browser drops the declaration.";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
4
13
|
width: $width;
|
|
5
14
|
height: $height;
|
|
6
15
|
}
|
|
@@ -3,6 +3,55 @@
|
|
|
3
3
|
@use "sass:list";
|
|
4
4
|
@use "sass:meta";
|
|
5
5
|
@use "sass:string";
|
|
6
|
+
@use "../internal/length-problem" as *;
|
|
7
|
+
|
|
8
|
+
$-places: "left" "center" "right" "top" "bottom";
|
|
9
|
+
|
|
10
|
+
// What is wrong with $position as a background-position, or null. Measured in
|
|
11
|
+
// Chrome 152, background-position kept one or two lengths, percentages or
|
|
12
|
+
// place keywords, keywords with offsets such as `left 10px top 5px`, var(),
|
|
13
|
+
// maths functions and a CSS-wide keyword alone. It dropped a unitless number
|
|
14
|
+
// other than 0, a unit that is not a length, any other word or colour, an image,
|
|
15
|
+
// and three or four lengths with no keyword. Interpolation, as in
|
|
16
|
+
// `#{$x}px #{$y}px`, gives the same value as strings, so each part is read.
|
|
17
|
+
@function -position-problem($position) {
|
|
18
|
+
$parts: $position;
|
|
19
|
+
@if meta.type-of($position) == "string" and string.slice(meta.inspect($position), 1, 1) != "\"" and not string.index($position, "(") and string.index($position, " ") {
|
|
20
|
+
$parts: ();
|
|
21
|
+
$text: $position;
|
|
22
|
+
$at: string.index($text, " ");
|
|
23
|
+
@while $at {
|
|
24
|
+
@if $at > 1 {
|
|
25
|
+
$parts: list.append($parts, string.unquote(string.slice($text, 1, $at - 1)));
|
|
26
|
+
}
|
|
27
|
+
$text: string.slice($text, $at + 1);
|
|
28
|
+
$at: string.index($text, " ");
|
|
29
|
+
}
|
|
30
|
+
$parts: list.append($parts, string.unquote($text));
|
|
31
|
+
} @else if meta.type-of($position) != "list" {
|
|
32
|
+
$parts: ($position,);
|
|
33
|
+
}
|
|
34
|
+
@if list.length($parts) > 4 {
|
|
35
|
+
@return "a background position takes at most four values";
|
|
36
|
+
}
|
|
37
|
+
$keywords: 0;
|
|
38
|
+
@each $part in $parts {
|
|
39
|
+
@if meta.type-of($part) == "string" and list.index($-places, string.to-lower-case($part)) {
|
|
40
|
+
$keywords: $keywords + 1;
|
|
41
|
+
} @else {
|
|
42
|
+
$problem: lengthProblem($part, $css-wide: list.length($parts) == 1);
|
|
43
|
+
@if $problem == "it is not a length" {
|
|
44
|
+
@return "`#{meta.inspect($part)}` is not a length or one of left, center, right, top or bottom";
|
|
45
|
+
} @else if $problem {
|
|
46
|
+
@return "in `#{meta.inspect($part)}`, #{$problem}";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
@if list.length($parts) > 2 and $keywords == 0 {
|
|
51
|
+
@return "three or four values need place keywords, such as `left 10px top 5px`";
|
|
52
|
+
}
|
|
53
|
+
@return null;
|
|
54
|
+
}
|
|
6
55
|
|
|
7
56
|
@mixin sprite($params...) {
|
|
8
57
|
@if list.length($params) == 1 {
|
|
@@ -19,11 +68,27 @@
|
|
|
19
68
|
}
|
|
20
69
|
} @else {
|
|
21
70
|
$position: list.nth($params, 1);
|
|
71
|
+
$problem: -position-problem($position);
|
|
72
|
+
@if $problem {
|
|
73
|
+
@error "`#{meta.inspect($position)}` is not a valid position for `sprite`: #{$problem}. A browser drops the declaration.";
|
|
74
|
+
}
|
|
22
75
|
background-position: $position;
|
|
23
76
|
}
|
|
24
77
|
} @else if list.length($params) == 2 {
|
|
25
78
|
$image-url: list.nth($params, 1);
|
|
26
79
|
$position: list.nth($params, 2);
|
|
80
|
+
// The one-argument form checks its path; this one did not, so a list was
|
|
81
|
+
// written into url(), which a browser drops, and a number asked for a file
|
|
82
|
+
// of that name. Measured in Chrome 152: `url(16 9)` was dropped.
|
|
83
|
+
@if meta.type-of($image-url) != "string" {
|
|
84
|
+
@error "`#{meta.inspect($image-url)}` is not a valid image path for `sprite`: with two arguments the first is one path as a string, and a browser drops a list in `url()`. Pass a path such as `\"/img/sprite.png\"`, then the position.";
|
|
85
|
+
}
|
|
86
|
+
@if $position != null {
|
|
87
|
+
$problem: -position-problem($position);
|
|
88
|
+
@if $problem {
|
|
89
|
+
@error "`#{meta.inspect($position)}` is not a valid position for `sprite`: #{$problem}. A browser drops the declaration.";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
27
92
|
display: inline-block;
|
|
28
93
|
background-image: url($image-url);
|
|
29
94
|
background-position: $position;
|
|
@@ -1,28 +1,46 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
3
|
@use "sass:list";
|
|
4
|
-
@use "sass:map";
|
|
5
|
-
@use "sass:math";
|
|
6
4
|
@use "sass:meta";
|
|
7
|
-
@use "
|
|
5
|
+
@use "sass:string";
|
|
6
|
+
@use "../internal/gradient" as *;
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
8
|
+
// Fills the letters with a gradient: the gradient mixin's arguments, and
|
|
9
|
+
// background-clip: text. The gradient is built and checked in
|
|
10
|
+
// scss/internal/_gradient.scss.
|
|
11
|
+
//
|
|
12
|
+
// The colours come first since 3.0.0, as in gradient, so a direction, a type
|
|
13
|
+
// and a colour space can all be left out. A call in the old order,
|
|
14
|
+
// `text-gradient("top", (red, blue))`, would otherwise fail on `"top"` not
|
|
15
|
+
// being a colour, so it is caught and answered with the new form.
|
|
16
|
+
//
|
|
17
|
+
// It still writes the background shorthand rather than background-image, so a
|
|
18
|
+
// call in the new order compiles to exactly what the same call compiled to in
|
|
19
|
+
// the old order.
|
|
20
|
+
@mixin text-gradient(
|
|
21
|
+
$colors,
|
|
22
|
+
$type: linear,
|
|
23
|
+
$direction: null,
|
|
24
|
+
$shape: null,
|
|
25
|
+
$position: null,
|
|
26
|
+
$from: null,
|
|
27
|
+
$in: null,
|
|
28
|
+
$repeating: false
|
|
29
|
+
) {
|
|
30
|
+
@if gradientDirection($colors) != null and not list.index("linear" "radial" "conic", string.to-lower-case("#{$type}")) {
|
|
31
|
+
$written: meta.inspect($type);
|
|
32
|
+
@if list.separator($type) == "comma" {
|
|
33
|
+
$written: "(#{$written})";
|
|
24
34
|
}
|
|
35
|
+
@error "`text-gradient` takes the colours first since 3.0.0. Write `text-gradient(#{$written}, $direction: #{meta.inspect($colors)})`.";
|
|
36
|
+
}
|
|
37
|
+
$value: gradientOf($colors, $type, $direction, $shape, $position, $from, $in, $repeating, $member: "text-gradient");
|
|
38
|
+
// Written without the space first, as the gradient mixin does, for a browser
|
|
39
|
+
// that does not know `in`.
|
|
40
|
+
@if $in != null {
|
|
41
|
+
background: gradientOf($colors, $type, $direction, $shape, $position, $from, null, $repeating, $member: "text-gradient", $warn: false);
|
|
25
42
|
}
|
|
43
|
+
background: $value;
|
|
26
44
|
-webkit-background-clip: text;
|
|
27
45
|
-webkit-text-fill-color: transparent;
|
|
28
46
|
background-clip: text;
|
|
@@ -1,31 +1,10 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
|
-
@use "
|
|
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
|
|
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
|
-
|
|
9
|
-
|
|
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
|
|
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
|
|
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: "";
|
|
@@ -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
|
+
}
|
|
@@ -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
|
-
@
|
|
9
|
-
@
|
|
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)) {
|