gerillass 2.3.0 → 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.
- package/SKILL.md +17 -1
- package/gerillass.json +287 -68
- 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/_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 +29 -37
- package/scss/library/_background-image.scss +37 -25
- package/scss/library/_background-stripes.scss +34 -37
- 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 +16 -23
- package/scss/library/_circle.scss +7 -0
- package/scss/library/_columnizer.scss +62 -2
- package/scss/library/_container-query.scss +11 -27
- 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/_line-clamp.scss +2 -13
- package/scss/library/_linear-gradient.scss +7 -0
- package/scss/library/_only.scss +16 -0
- package/scss/library/_position.scss +34 -3
- package/scss/library/_radial-gradient.scss +154 -0
- 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 +8 -0
- 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/_validate-breakpoint.scss +32 -6
- package/scss/utilities/_validate-scissors.scss +7 -0
|
@@ -1,8 +1,77 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
3
|
@use "sass:list";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "sass:string";
|
|
4
6
|
@use "../lists/list-of-directions" as *;
|
|
5
7
|
@use "../utilities/fill-nulls" as *;
|
|
8
|
+
@use "../internal/length-problem" as *;
|
|
9
|
+
|
|
10
|
+
// The parts of $text between the separator, empty parts left out.
|
|
11
|
+
@function -split($text, $separator) {
|
|
12
|
+
$parts: ();
|
|
13
|
+
$at: string.index($text, $separator);
|
|
14
|
+
@while $at {
|
|
15
|
+
@if $at > 1 {
|
|
16
|
+
$parts: list.append($parts, string.unquote(string.slice($text, 1, $at - 1)));
|
|
17
|
+
}
|
|
18
|
+
$text: string.slice($text, $at + 1);
|
|
19
|
+
$at: string.index($text, $separator);
|
|
20
|
+
}
|
|
21
|
+
@if string.length($text) > 0 {
|
|
22
|
+
$parts: list.append($parts, string.unquote($text));
|
|
23
|
+
}
|
|
24
|
+
@return $parts;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// What is wrong with $value as the radii of one declaration, or null. Measured
|
|
28
|
+
// in Chrome 152: border-radius kept one to four radii, and a slash between two
|
|
29
|
+
// such sets; a corner's own property kept one or two radii and no slash. Both
|
|
30
|
+
// kept a length, 0, a percentage and a CSS-wide keyword alone, and dropped a
|
|
31
|
+
// negative radius, a keyword such as auto, and more radii than that.
|
|
32
|
+
// Interpolation, as in `#{$a}/#{$b}`, gives the same value as a string, so a
|
|
33
|
+
// string is read by its parts. null is a corner left out, as fillNulls has it.
|
|
34
|
+
@function -radii-problem($value, $max, $slash: false) {
|
|
35
|
+
@if $value == null {
|
|
36
|
+
@return null;
|
|
37
|
+
}
|
|
38
|
+
$is-text: meta.type-of($value) == "string" and string.slice(meta.inspect($value), 1, 1) != "\"" and not string.index($value, "(");
|
|
39
|
+
@if ($is-text and string.index($value, "/")) or (meta.type-of($value) == "list" and list.separator($value) == "slash") {
|
|
40
|
+
$sets: $value;
|
|
41
|
+
@if $is-text {
|
|
42
|
+
$sets: -split($value, "/");
|
|
43
|
+
}
|
|
44
|
+
@if not $slash {
|
|
45
|
+
@return "a slash only works in the one-argument form, between two sets of radii";
|
|
46
|
+
}
|
|
47
|
+
@if list.length($sets) != 2 {
|
|
48
|
+
@return "a slash goes between exactly two sets of radii";
|
|
49
|
+
}
|
|
50
|
+
@each $set in $sets {
|
|
51
|
+
$problem: -radii-problem($set, $max);
|
|
52
|
+
@if $problem {
|
|
53
|
+
@return $problem;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
@return null;
|
|
57
|
+
}
|
|
58
|
+
$radii: $value;
|
|
59
|
+
@if $is-text and string.index($value, " ") {
|
|
60
|
+
$radii: -split($value, " ");
|
|
61
|
+
}
|
|
62
|
+
@if list.length($radii) > $max {
|
|
63
|
+
@return "it is #{list.length($radii)} radii where at most #{$max} are meant";
|
|
64
|
+
}
|
|
65
|
+
@each $radius in $radii {
|
|
66
|
+
@if $radius != null {
|
|
67
|
+
$problem: lengthProblem($radius, $negative: false, $css-wide: list.length($radii) == 1);
|
|
68
|
+
@if $problem {
|
|
69
|
+
@return $problem;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
@return null;
|
|
74
|
+
}
|
|
6
75
|
|
|
7
76
|
@mixin border-radius($args...) {
|
|
8
77
|
// Logical corners are named block side first, inline side second, like the
|
|
@@ -12,11 +81,19 @@
|
|
|
12
81
|
$list: list.join(list.join($list-of-directions, ("cross-left", "cross-right", "all")), $logical);
|
|
13
82
|
@if list.length($args) == 1 {
|
|
14
83
|
$value: list.nth($args, 1);
|
|
84
|
+
$problem: -radii-problem($value, 4, $slash: true);
|
|
85
|
+
@if $problem {
|
|
86
|
+
@error "`#{meta.inspect($value)}` is not a valid radius for `border-radius`: #{$problem}. A browser drops the declaration.";
|
|
87
|
+
}
|
|
15
88
|
border-radius: fillNulls($value, space);
|
|
16
89
|
} @else if list.length($args) == 2 {
|
|
17
90
|
$corner: list.nth($args, 1);
|
|
18
91
|
$value: list.nth($args, 2);
|
|
19
92
|
@if list.index($list, $corner) {
|
|
93
|
+
$problem: -radii-problem($value, 2);
|
|
94
|
+
@if $problem {
|
|
95
|
+
@error "`#{meta.inspect($value)}` is not a valid radius for `border-radius`: #{$problem}. A browser drops the declaration.";
|
|
96
|
+
}
|
|
20
97
|
@if $corner == "top" {
|
|
21
98
|
border-top-left-radius: $value;
|
|
22
99
|
border-top-right-radius: $value;
|
|
@@ -70,6 +147,12 @@
|
|
|
70
147
|
@error "Corner value must be one of the followings: #{$list}.";
|
|
71
148
|
}
|
|
72
149
|
} @else if list.length($args) == 4 {
|
|
150
|
+
@each $value in $args {
|
|
151
|
+
$problem: -radii-problem($value, 2);
|
|
152
|
+
@if $problem {
|
|
153
|
+
@error "`#{meta.inspect($value)}` is not a valid radius for `border-radius`: #{$problem}. A browser drops the declaration.";
|
|
154
|
+
}
|
|
155
|
+
}
|
|
73
156
|
$args: fillNulls($args, space, true);
|
|
74
157
|
border-top-left-radius: list.nth($args, 1);
|
|
75
158
|
border-top-right-radius: list.nth($args, 2);
|
|
@@ -1,37 +1,23 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
|
-
@use "sass:list";
|
|
4
|
-
@use "sass:meta";
|
|
5
|
-
@use "sass:string";
|
|
6
|
-
|
|
7
3
|
@use "../library/stretched-link" as *;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@function -image($value) {
|
|
12
|
-
@if -is-css-function($value, "var" "url" "image-set" "linear-gradient" "radial-gradient" "conic-gradient" "repeating-linear-gradient" "repeating-radial-gradient" "repeating-conic-gradient") {
|
|
13
|
-
@return $value;
|
|
14
|
-
}
|
|
15
|
-
@return url($value);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// True for an unquoted call to one of $names, such as var(--x). A quoted string
|
|
19
|
-
// stays text, so `"var(--x)"` is not a call.
|
|
20
|
-
@function -is-css-function($value, $names) {
|
|
21
|
-
@if meta.type-of($value) != "string" or string.slice(meta.inspect($value), 1, 1) == "\"" {
|
|
22
|
-
@return false;
|
|
23
|
-
}
|
|
24
|
-
$open: string.index($value, "(");
|
|
25
|
-
@return $open != null and list.index($names, string.to-lower-case(string.slice($value, 1, $open - 1))) != null;
|
|
26
|
-
}
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "../internal/image-value" as *;
|
|
6
|
+
@use "../internal/length-problem" as *;
|
|
27
7
|
|
|
28
8
|
@mixin brand-logo($width, $height, $image-url: null) {
|
|
9
|
+
@each $name, $value in ("$width": $width, "$height": $height) {
|
|
10
|
+
$problem: sizeProblem($value);
|
|
11
|
+
@if $problem {
|
|
12
|
+
@error "`#{meta.inspect($value)}` is not a valid #{$name} for `brand-logo`: #{$problem}. A browser drops the declaration.";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
29
15
|
display: inline-block;
|
|
30
16
|
position: relative;
|
|
31
17
|
width: $width;
|
|
32
18
|
height: $height;
|
|
33
19
|
@if $image-url {
|
|
34
|
-
background-image:
|
|
20
|
+
background-image: imageValue($image-url, "brand-logo", "$image-url");
|
|
35
21
|
}
|
|
36
22
|
background-position: center;
|
|
37
23
|
background-repeat: no-repeat;
|
|
@@ -2,38 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
@use "sass:list";
|
|
4
4
|
@use "sass:map";
|
|
5
|
-
@use "sass:meta";
|
|
6
|
-
@use "sass:string";
|
|
7
5
|
@use "../maps/map-for-breakpoints" as *;
|
|
8
6
|
@use "../utilities/validate-breakpoint" as *;
|
|
7
|
+
@use "../internal/custom-property-in" as *;
|
|
8
|
+
@use "../internal/condition-width" as *;
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
@function -custom-property-in($value) {
|
|
16
|
-
@each $item in $value {
|
|
17
|
-
@if meta.type-of($item) == "list" or meta.type-of($item) == "arglist" {
|
|
18
|
-
$found: -custom-property-in($item);
|
|
19
|
-
@if $found {
|
|
20
|
-
@return $found;
|
|
21
|
-
}
|
|
22
|
-
} @else if string.index(meta.inspect($item), "var(") {
|
|
23
|
-
@return $item;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
@return null;
|
|
27
|
-
}
|
|
28
|
-
|
|
10
|
+
// Every size goes through conditionWidth before a query is written, so a size no
|
|
11
|
+
// width condition can match raises instead of compiling into one. The queries
|
|
12
|
+
// themselves are written as they always were, and the checks in the branches
|
|
13
|
+
// below are called only for the error they raise, so a call that worked writes
|
|
14
|
+
// the same CSS.
|
|
29
15
|
@mixin breakpoint($params...) {
|
|
30
|
-
$custom-property:
|
|
16
|
+
$custom-property: customPropertyIn($params);
|
|
31
17
|
@if $custom-property {
|
|
32
18
|
@error "`#{$custom-property}` cannot be used in a breakpoint: custom properties are not evaluated in a @media condition, so the rule would never apply. Pass a length or a key from $map-for-breakpoints.";
|
|
33
19
|
}
|
|
34
20
|
@if list.length($params) == 1 {
|
|
35
21
|
$value: list.nth($params, 1);
|
|
36
|
-
|
|
22
|
+
// Checked before the warning below, so a size that is wrong outright is
|
|
23
|
+
// refused rather than described as a single pixel.
|
|
24
|
+
$width: conditionWidth($value, "breakpoint");
|
|
37
25
|
// One argument matches a single pixel, which two agent trials took for
|
|
38
26
|
// "from this width up". Still emitted, so no stylesheet changes, but said
|
|
39
27
|
// out loud until 3.0.0 refuses it.
|
|
@@ -51,12 +39,16 @@
|
|
|
51
39
|
@if not list.index("only" "min" "max" "between", list.nth($params, 1)) {
|
|
52
40
|
$start: list.nth($params, 1);
|
|
53
41
|
$end: list.nth($params, 2);
|
|
42
|
+
$checked: conditionWidth($start, "breakpoint") conditionWidth($end, "breakpoint");
|
|
54
43
|
@media (min-width: #{validateBreakpoint($start)}) and (max-width: #{if(map.has-key($map-for-breakpoints, $end), validateBreakpoint($end) - 1, $end)}) {
|
|
55
44
|
@content;
|
|
56
45
|
}
|
|
57
46
|
} @else {
|
|
58
47
|
$mode: list.nth($params, 1);
|
|
59
48
|
$value: list.nth($params, 2);
|
|
49
|
+
@if $mode != "between" {
|
|
50
|
+
$checked: conditionWidth($value, "breakpoint");
|
|
51
|
+
}
|
|
60
52
|
@if $mode == "only" {
|
|
61
53
|
@if map.has-key($map-for-breakpoints, $value) {
|
|
62
54
|
@media (width: map.get($map-for-breakpoints, $value)) {
|
|
@@ -90,6 +82,7 @@
|
|
|
90
82
|
} @else if $mode == "between" {
|
|
91
83
|
$start: list.nth($value, 1);
|
|
92
84
|
$end: list.nth($value, 2);
|
|
85
|
+
$checked: conditionWidth($start, "breakpoint") conditionWidth($end, "breakpoint");
|
|
93
86
|
@media (min-width: #{validateBreakpoint($start)}) and (max-width: #{if(map.has-key($map-for-breakpoints, $end), validateBreakpoint($end) - 1, $end)}) {
|
|
94
87
|
@content;
|
|
95
88
|
}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
@use "../internal/length-problem" as *;
|
|
5
|
+
|
|
3
6
|
@mixin circle($size) {
|
|
7
|
+
$problem: sizeProblem($size);
|
|
8
|
+
@if $problem {
|
|
9
|
+
@error "`#{meta.inspect($size)}` is not a valid $size for `circle`: #{$problem}. A browser drops the width and height.";
|
|
10
|
+
}
|
|
4
11
|
width: $size;
|
|
5
12
|
height: $size;
|
|
6
13
|
display: inline-block;
|
|
@@ -1,15 +1,75 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
3
|
@use "sass:list";
|
|
4
|
+
@use "sass:math";
|
|
4
5
|
@use "sass:meta";
|
|
6
|
+
@use "sass:string";
|
|
5
7
|
@use "../library/border-box" as *;
|
|
6
8
|
@use "../utilities/is-gutter" as *;
|
|
9
|
+
@use "../internal/length-problem" as *;
|
|
10
|
+
|
|
11
|
+
// The count divides 100% in calc(), which in Chrome 152 kept a unitless number
|
|
12
|
+
// and a function that resolves to one, var(), env() or attr(), or maths with
|
|
13
|
+
// one of those inside. It dropped a count with a unit, a word and maths on
|
|
14
|
+
// lengths alone, such as calc(100% - 10px): 100% divided by a length is not a
|
|
15
|
+
// length.
|
|
16
|
+
@function -count-problem($columns) {
|
|
17
|
+
@if meta.type-of($columns) == "number" {
|
|
18
|
+
@if math.is-unitless($columns) {
|
|
19
|
+
@return null;
|
|
20
|
+
}
|
|
21
|
+
@return "a column count has no unit";
|
|
22
|
+
}
|
|
23
|
+
// Interpolation, as in `#{$cols}`, gives the number as an unquoted string,
|
|
24
|
+
// which is written into calc() as it reads.
|
|
25
|
+
@if meta.type-of($columns) == "string" and string.slice(meta.inspect($columns), 1, 1) != "\"" and not string.index($columns, "(") {
|
|
26
|
+
$digits: 0;
|
|
27
|
+
@for $i from 1 through string.length($columns) {
|
|
28
|
+
$character: string.slice($columns, $i, $i);
|
|
29
|
+
@if string.index("0123456789", $character) {
|
|
30
|
+
$digits: $digits + 1;
|
|
31
|
+
} @else if not string.index(".+-", $character) {
|
|
32
|
+
@return "it is not a column count";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
@if $digits > 0 {
|
|
36
|
+
@return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
@if meta.type-of($columns) == "calculation" or (meta.type-of($columns) == "string" and string.index($columns, "(")) {
|
|
40
|
+
$text: string.to-lower-case(meta.inspect($columns));
|
|
41
|
+
@if string.index($text, "var(") or string.index($text, "env(") or string.index($text, "attr(") {
|
|
42
|
+
@return null;
|
|
43
|
+
}
|
|
44
|
+
@return "maths on lengths does not give a count; pass a number, or var(), env() or attr()";
|
|
45
|
+
}
|
|
46
|
+
@return "it is not a column count";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// The gutter is multiplied in calc() and written as a margin. Chrome 152 kept a
|
|
50
|
+
// length, a percentage and a negative length, and dropped the flex-basis for a
|
|
51
|
+
// unitless number, a unit that is not a length and a word. A unitless 0 made
|
|
52
|
+
// `(3 - 1) * 0`, a number rather than a length, so it is written as 0px.
|
|
53
|
+
@function -gutter($gutter) {
|
|
54
|
+
$problem: lengthProblem($gutter);
|
|
55
|
+
@if $problem {
|
|
56
|
+
@error "`#{meta.inspect($gutter)}` is not a valid gutter for `columnizer`: #{$problem}. A browser drops the column width.";
|
|
57
|
+
}
|
|
58
|
+
@if (meta.type-of($gutter) == "number" and math.is-unitless($gutter)) or (meta.type-of($gutter) == "string" and string.unquote($gutter) == string.unquote("0")) {
|
|
59
|
+
@return 0px;
|
|
60
|
+
}
|
|
61
|
+
@return $gutter;
|
|
62
|
+
}
|
|
7
63
|
|
|
8
64
|
@mixin columnizer($params...) {
|
|
9
65
|
@if list.length($params) < 1 or list.length($params) > 3 {
|
|
10
66
|
@error "`columnizer` takes 1 to 3 arguments; you passed #{list.length($params)}. Pass the column count, optionally a gutter length, and optionally a boolean telling the last row whether to fill.";
|
|
11
67
|
}
|
|
12
68
|
$columns: list.nth($params, 1);
|
|
69
|
+
$count-problem: -count-problem($columns);
|
|
70
|
+
@if $count-problem {
|
|
71
|
+
@error "`#{meta.inspect($columns)}` is not a valid column count for `columnizer`: #{$count-problem}. A browser drops the column width.";
|
|
72
|
+
}
|
|
13
73
|
$gutter: null;
|
|
14
74
|
$fill: false;
|
|
15
75
|
display: flex;
|
|
@@ -33,7 +93,7 @@
|
|
|
33
93
|
margin-right: 0;
|
|
34
94
|
}
|
|
35
95
|
} @else if isGutter(list.nth($params, 2)) {
|
|
36
|
-
$gutter: list.nth($params, list.length($params));
|
|
96
|
+
$gutter: -gutter(list.nth($params, list.length($params)));
|
|
37
97
|
flex-grow: 0;
|
|
38
98
|
flex-shrink: 0;
|
|
39
99
|
flex-basis: calc((100% - (#{$columns} - 1) * #{$gutter}) / #{$columns});
|
|
@@ -48,7 +108,7 @@
|
|
|
48
108
|
@error "`#{list.nth($params, 2)}` is not a valid second argument for `columnizer`. Pass a gutter length such as `20px` or `var(--gap)`, or a boolean telling the last row whether to fill.";
|
|
49
109
|
}
|
|
50
110
|
} @else if list.length($params) == 3 {
|
|
51
|
-
$gutter: list.nth($params, 2);
|
|
111
|
+
$gutter: -gutter(list.nth($params, 2));
|
|
52
112
|
$fill: list.nth($params, list.length($params));
|
|
53
113
|
flex-grow: if($fill == true, 1, 0);
|
|
54
114
|
flex-shrink: 0;
|
|
@@ -5,26 +5,8 @@
|
|
|
5
5
|
@use "sass:meta";
|
|
6
6
|
@use "sass:string";
|
|
7
7
|
@use "../maps/map-for-breakpoints" as *;
|
|
8
|
-
@use "../
|
|
9
|
-
|
|
10
|
-
// Returns the first value in $value that holds var(), looking inside lists and
|
|
11
|
-
// calculations, or null. Custom properties are not evaluated in a @media or
|
|
12
|
-
// @container condition, so a rule built from one never applies, and nothing
|
|
13
|
-
// warns. Measured in Chrome 152: `(min-width: var(--wide))` did not match with
|
|
14
|
-
// `--wide: 200px`, while `(min-width: 200px)` did.
|
|
15
|
-
@function -custom-property-in($value) {
|
|
16
|
-
@each $item in $value {
|
|
17
|
-
@if meta.type-of($item) == "list" or meta.type-of($item) == "arglist" {
|
|
18
|
-
$found: -custom-property-in($item);
|
|
19
|
-
@if $found {
|
|
20
|
-
@return $found;
|
|
21
|
-
}
|
|
22
|
-
} @else if string.index(meta.inspect($item), "var(") {
|
|
23
|
-
@return $item;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
@return null;
|
|
27
|
-
}
|
|
8
|
+
@use "../internal/custom-property-in" as *;
|
|
9
|
+
@use "../internal/condition-width" as *;
|
|
28
10
|
|
|
29
11
|
// Characters and names a browser will not keep as the name in an @container
|
|
30
12
|
// rule. Measured in Chrome 152, the rule was dropped for `var(--n)`, `none`,
|
|
@@ -88,7 +70,7 @@ $-forbidden-in-name: "." "," "/" "#" ":" ";" "(" ")" "[" "]" "{" "}" "!" "@" "$"
|
|
|
88
70
|
}
|
|
89
71
|
}
|
|
90
72
|
|
|
91
|
-
$custom-property:
|
|
73
|
+
$custom-property: customPropertyIn($params);
|
|
92
74
|
@if $custom-property {
|
|
93
75
|
@error "`#{$custom-property}` cannot be used in a container query: custom properties are not evaluated in a @container condition, so the rule would never apply. Pass a length or a key from $map-for-breakpoints.";
|
|
94
76
|
}
|
|
@@ -96,7 +78,9 @@ $-forbidden-in-name: "." "," "/" "#" ":" ";" "(" ")" "[" "]" "{" "}" "!" "@" "$"
|
|
|
96
78
|
|
|
97
79
|
@if $count == 1 {
|
|
98
80
|
$value: list.nth($params, 1);
|
|
99
|
-
|
|
81
|
+
// Checked before the warning, as in `breakpoint`. conditionWidth returns
|
|
82
|
+
// what validateBreakpoint did, so a working call writes the same condition.
|
|
83
|
+
$width: conditionWidth($value, "container-query", "@container");
|
|
100
84
|
$condition: "(width: #{$width})";
|
|
101
85
|
// A single pixel, as in `breakpoint`; still emitted until 3.0.0 refuses it.
|
|
102
86
|
@warn "`container-query(#{$value})` matches only a container exactly #{$width} wide, `(width: #{$width})`. Write `container-query(only, #{$value})` for that width, or `container-query(min, #{$value})` from it upwards. The one-argument form will be refused in 3.0.0.";
|
|
@@ -104,19 +88,19 @@ $-forbidden-in-name: "." "," "/" "#" ":" ";" "(" ")" "[" "]" "{" "}" "!" "@" "$"
|
|
|
104
88
|
$mode: list.nth($params, 1);
|
|
105
89
|
@if not list.index("only" "min" "max" "between", $mode) {
|
|
106
90
|
// Two bare sizes mean a range, as they do in `breakpoint`.
|
|
107
|
-
$condition: "(min-width: #{
|
|
91
|
+
$condition: "(min-width: #{conditionWidth($mode, "container-query", "@container")}) and (max-width: #{conditionWidth(list.nth($params, 2), "container-query", "@container")})";
|
|
108
92
|
} @else {
|
|
109
93
|
$value: list.nth($params, 2);
|
|
110
94
|
@if $mode == "only" {
|
|
111
|
-
$condition: "(width: #{
|
|
95
|
+
$condition: "(width: #{conditionWidth($value, "container-query", "@container")})";
|
|
112
96
|
} @else if $mode == "min" {
|
|
113
|
-
$condition: "(min-width: #{
|
|
97
|
+
$condition: "(min-width: #{conditionWidth($value, "container-query", "@container")})";
|
|
114
98
|
} @else if $mode == "max" {
|
|
115
|
-
$condition: "(max-width: #{
|
|
99
|
+
$condition: "(max-width: #{conditionWidth($value, "container-query", "@container")})";
|
|
116
100
|
} @else {
|
|
117
101
|
$start: list.nth($value, 1);
|
|
118
102
|
$end: list.nth($value, 2);
|
|
119
|
-
$condition: "(min-width: #{
|
|
103
|
+
$condition: "(min-width: #{conditionWidth($start, "container-query", "@container")}) and (max-width: #{conditionWidth($end, "container-query", "@container")})";
|
|
120
104
|
}
|
|
121
105
|
}
|
|
122
106
|
} @else {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
@use "sass:list";
|
|
4
4
|
@use "sass:meta";
|
|
5
5
|
@use "sass:string";
|
|
6
|
+
@use "../internal/words" as *;
|
|
6
7
|
|
|
7
8
|
// What a browser will not keep in `container-name`. Measured in Chrome 152, the
|
|
8
9
|
// declaration was dropped for `and`, `or`, `not` and `default` in any case, a
|
|
@@ -16,30 +17,12 @@ $-reserved-names: "and" "or" "not" "default";
|
|
|
16
17
|
$-alone-names: "none" "inherit" "initial" "unset" "revert" "revert-layer";
|
|
17
18
|
$-forbidden-in-name: "." "," "/" "#" ":" ";" "(" ")" "[" "]" "{" "}" "!" "@" "$" "%" "^" "&" "*" "+" "=" "<" ">" "?" "\\" "|" "~" "`" "'" "\"";
|
|
18
19
|
|
|
19
|
-
@function -words($text) {
|
|
20
|
-
$words: ();
|
|
21
|
-
$rest: $text;
|
|
22
|
-
$at: string.index($rest, " ");
|
|
23
|
-
@while $at {
|
|
24
|
-
$word: string.slice($rest, 1, $at - 1);
|
|
25
|
-
@if string.length($word) > 0 {
|
|
26
|
-
$words: list.append($words, $word);
|
|
27
|
-
}
|
|
28
|
-
$rest: string.slice($rest, $at + 1);
|
|
29
|
-
$at: string.index($rest, " ");
|
|
30
|
-
}
|
|
31
|
-
@if string.length($rest) > 0 {
|
|
32
|
-
$words: list.append($words, $rest);
|
|
33
|
-
}
|
|
34
|
-
@return $words;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
20
|
@function -name-problem($name) {
|
|
38
21
|
$text: "#{$name}";
|
|
39
22
|
@if string.index($text, "var(") {
|
|
40
23
|
@return null;
|
|
41
24
|
}
|
|
42
|
-
$words:
|
|
25
|
+
$words: wordsOf($text);
|
|
43
26
|
@each $word in $words {
|
|
44
27
|
$lower: string.to-lower-case($word);
|
|
45
28
|
@if list.index($-alone-names, $lower) and list.length($words) > 1 {
|
|
@@ -1,19 +1,8 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
3
|
@use "sass:list";
|
|
4
|
-
@use "sass:meta";
|
|
5
|
-
@use "sass:string";
|
|
6
4
|
@use "../lists/list-of-counter-styles" as *;
|
|
7
|
-
|
|
8
|
-
// True for an unquoted call to one of $names, such as var(--x). A quoted string
|
|
9
|
-
// stays text, so `"var(--x)"` is not a call.
|
|
10
|
-
@function -is-css-function($value, $names) {
|
|
11
|
-
@if meta.type-of($value) != "string" or string.slice(meta.inspect($value), 1, 1) == "\"" {
|
|
12
|
-
@return false;
|
|
13
|
-
}
|
|
14
|
-
$open: string.index($value, "(");
|
|
15
|
-
@return $open != null and list.index($names, string.to-lower-case(string.slice($value, 1, $open - 1))) != null;
|
|
16
|
-
}
|
|
5
|
+
@use "../internal/is-css-function" as *;
|
|
17
6
|
|
|
18
7
|
@mixin counter($params...) {
|
|
19
8
|
$counter: null;
|
|
@@ -49,10 +38,10 @@
|
|
|
49
38
|
// quoting would turn into the literal characters.
|
|
50
39
|
$quote-before: '"';
|
|
51
40
|
$quote-after: '"';
|
|
52
|
-
@if
|
|
41
|
+
@if isCssFunction($counter-before, "var" "attr" "counter" "counters") {
|
|
53
42
|
$quote-before: "";
|
|
54
43
|
}
|
|
55
|
-
@if
|
|
44
|
+
@if isCssFunction($counter-after, "var" "attr" "counter" "counters") {
|
|
56
45
|
$quote-after: "";
|
|
57
46
|
}
|
|
58
47
|
&.counter-start {
|
|
@@ -1,7 +1,84 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "sass:string";
|
|
6
|
+
@use "../internal/keyword-value" as *;
|
|
7
|
+
@use "../internal/length-problem" as *;
|
|
8
|
+
@use "../internal/words" as *;
|
|
9
|
+
|
|
10
|
+
// The display keywords, sorted by the part of the value each one fills.
|
|
11
|
+
// Measured in Chrome 152, one keyword, or two or three in any order, were kept
|
|
12
|
+
// when they named at most one outer type, one inner type and one list-item:
|
|
13
|
+
// `inline flex`, `flex block`, `block flow list-item`, `list-item inline flow`.
|
|
14
|
+
// These were dropped: two of a kind (`block inline`, `flex grid`,
|
|
15
|
+
// `block block`), `list-item` beside an inner type other than flow or
|
|
16
|
+
// flow-root (`list-item flex`), and a compound keyword such as `inline-block`
|
|
17
|
+
// beside anything. Chrome also dropped `run-in`, the ruby-base family and the
|
|
18
|
+
// -moz- and -ms- boxes; they are in the specification or used by other
|
|
19
|
+
// engines, so they are let through.
|
|
20
|
+
$-outer: "block" "inline" "run-in";
|
|
21
|
+
$-inner: "flow" "flow-root" "table" "flex" "grid" "ruby" "math";
|
|
22
|
+
$-alone: "none" "contents" "inline-block" "inline-table" "inline-flex" "inline-grid" "table-row-group" "table-header-group" "table-footer-group" "table-row" "table-cell" "table-column-group" "table-column" "table-caption" "ruby-base" "ruby-text" "ruby-base-container" "ruby-text-container";
|
|
23
|
+
|
|
24
|
+
@function -display-problem($display) {
|
|
25
|
+
$keywords: list.join(list.join(list.join($-outer, $-inner), $-alone), ("list-item",));
|
|
26
|
+
$problem: keywordProblem($display, $keywords, 3, $vendor: true);
|
|
27
|
+
@if $problem or $display == null {
|
|
28
|
+
@return $problem;
|
|
29
|
+
}
|
|
30
|
+
$words: wordsOf($display);
|
|
31
|
+
$outer: 0;
|
|
32
|
+
$inner: null;
|
|
33
|
+
$inners: 0;
|
|
34
|
+
$list-items: 0;
|
|
35
|
+
@each $word in $words {
|
|
36
|
+
@if string.index($word, "(") {
|
|
37
|
+
@return null;
|
|
38
|
+
}
|
|
39
|
+
$lower: string.to-lower-case(string.unquote($word));
|
|
40
|
+
@if list.length($words) > 1 and not list.index($-outer, $lower) and not list.index($-inner, $lower) and $lower != "list-item" {
|
|
41
|
+
@return "`#{$lower}` only works as the whole value";
|
|
42
|
+
}
|
|
43
|
+
@if list.index($-outer, $lower) {
|
|
44
|
+
$outer: $outer + 1;
|
|
45
|
+
} @else if list.index($-inner, $lower) {
|
|
46
|
+
$inners: $inners + 1;
|
|
47
|
+
$inner: $lower;
|
|
48
|
+
} @else if $lower == "list-item" {
|
|
49
|
+
$list-items: $list-items + 1;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
@if $outer > 1 {
|
|
53
|
+
@return "it names two outer display types; pass one of block, inline or run-in";
|
|
54
|
+
}
|
|
55
|
+
@if $inners > 1 {
|
|
56
|
+
@return "it names two inner display types; pass one of flow, flow-root, table, flex, grid, ruby or math";
|
|
57
|
+
}
|
|
58
|
+
@if $list-items > 1 {
|
|
59
|
+
@return "it names list-item twice";
|
|
60
|
+
}
|
|
61
|
+
@if $list-items == 1 and $inner and not list.index("flow" "flow-root", $inner) {
|
|
62
|
+
@return "`list-item` only goes with flow or flow-root, not `#{$inner}`";
|
|
63
|
+
}
|
|
64
|
+
@return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
3
67
|
@mixin ellipsis($width: 100%, $display: inline-block) {
|
|
4
|
-
|
|
68
|
+
$problem: -display-problem($display);
|
|
69
|
+
@if $problem {
|
|
70
|
+
@error "`#{meta.inspect($display)}` is not a valid $display for `ellipsis`: #{$problem}. A browser drops the declaration.";
|
|
71
|
+
}
|
|
72
|
+
$problem: sizeProblem($width, $max: true);
|
|
73
|
+
@if $problem {
|
|
74
|
+
@error "`#{meta.inspect($width)}` is not a valid $width for `ellipsis`, which sets max-width: #{$problem}. A browser drops the declaration.";
|
|
75
|
+
}
|
|
76
|
+
// Written without quotes, since `display: "block"` was dropped.
|
|
77
|
+
@if meta.type-of($display) == "string" {
|
|
78
|
+
display: string.unquote($display);
|
|
79
|
+
} @else {
|
|
80
|
+
display: $display;
|
|
81
|
+
}
|
|
5
82
|
max-width: $width;
|
|
6
83
|
text-overflow: ellipsis;
|
|
7
84
|
white-space: nowrap;
|
|
@@ -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 except($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 excludes
|
|
15
|
+
// nothing; see scss/internal/_sibling-index.scss.
|
|
16
|
+
$problem: siblingIndexProblem($value, "except");
|
|
17
|
+
@if $problem {
|
|
18
|
+
@error "`#{meta.inspect($value)}` is not a valid position for `except`: #{$problem}.";
|
|
19
|
+
}
|
|
13
20
|
@if $value < 0 {
|
|
14
21
|
&:not(:nth-last-of-type(#{$value * -1})) {
|
|
15
22
|
@content;
|
|
@@ -45,6 +52,14 @@
|
|
|
45
52
|
@error "`#{$value}` is not a valid argument for `except`. Pass a positive or negative number, one of `first`, `last`, `odd`, `even`, or a selector such as `.foo`.";
|
|
46
53
|
}
|
|
47
54
|
} @else if list.length($params) > 1 {
|
|
55
|
+
// Every item is checked first. A word used to fail with Sass's own
|
|
56
|
+
// `Undefined operation`, and one bad position dropped the whole rule.
|
|
57
|
+
@each $item in $params {
|
|
58
|
+
$problem: siblingIndexProblem($item, "except", true);
|
|
59
|
+
@if $problem {
|
|
60
|
+
@error "`#{meta.inspect($item)}` is not a valid position for `except`: #{$problem}.";
|
|
61
|
+
}
|
|
62
|
+
}
|
|
48
63
|
$items: "";
|
|
49
64
|
@for $i from 1 through list.length($params) {
|
|
50
65
|
$items: $items + if(list.nth($params, $i) < 0, string.unquote(":not(:nth-last-of-type(#{list.nth($params, $i) * -1}))"), string.unquote(":not(:nth-of-type(#{list.nth($params, $i)}))"));
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
@charset "UTF-8";
|
|
2
2
|
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
@use "../internal/color-problem" as *;
|
|
5
|
+
@use "../internal/length-problem" as *;
|
|
6
|
+
|
|
3
7
|
// Draws a focus ring for keyboard users. Two things are usually got wrong by
|
|
4
8
|
// hand, and this writes the version that avoids both.
|
|
5
9
|
//
|
|
@@ -26,6 +30,31 @@
|
|
|
26
30
|
@if not & {
|
|
27
31
|
@error "`focus-ring` styles the element it is called in, so call it inside a selector, such as `.button { @include focus-ring; }`.";
|
|
28
32
|
}
|
|
33
|
+
// The colour goes into the outline shorthand, where Chrome 152 dropped a word
|
|
34
|
+
// that is not a colour, a quoted colour, a length and a CSS-wide keyword, so
|
|
35
|
+
// the ring was not drawn at all. null leaves the colour to the browser.
|
|
36
|
+
@if $color != null {
|
|
37
|
+
$problem: colorProblem($color);
|
|
38
|
+
@if $problem {
|
|
39
|
+
@error "`#{meta.inspect($color)}` is not a valid $color for `focus-ring`: #{$problem}. A browser drops the outline, so no ring is drawn. Pass a colour such as `#1a73e8`, `currentColor`, or a function such as `var(--focus)`.";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// The width goes into the same shorthand, which in Chrome 152 kept a length,
|
|
43
|
+
// 0 and thin, medium or thick, and dropped a percentage, a negative width and
|
|
44
|
+
// a CSS-wide keyword. The offset is a declaration of its own: it kept a
|
|
45
|
+
// negative length and a CSS-wide keyword, and dropped a percentage and thin.
|
|
46
|
+
@if $width != null {
|
|
47
|
+
$problem: lengthProblem($width, $percent: false, $negative: false, $keywords: "thin" "medium" "thick");
|
|
48
|
+
@if $problem {
|
|
49
|
+
@error "`#{meta.inspect($width)}` is not a valid $width for `focus-ring`: #{$problem}. A browser drops the outline, so no ring is drawn.";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
@if $offset != null {
|
|
53
|
+
$problem: lengthProblem($offset, $percent: false, $css-wide: true);
|
|
54
|
+
@if $problem {
|
|
55
|
+
@error "`#{meta.inspect($offset)}` is not a valid $offset for `focus-ring`: #{$problem}. A browser drops the declaration.";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
29
58
|
|
|
30
59
|
&:focus-visible {
|
|
31
60
|
outline: $width solid $color;
|