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.
- checksums.yaml +4 -4
- data/LICENSE.md +13 -0
- data/README.md +328 -0
- data/SKILL.md +282 -0
- data/gerillass.json +2713 -0
- data/lib/gerillass/engine.rb +55 -0
- data/lib/gerillass/jekyll.rb +13 -0
- data/lib/gerillass.rb +26 -0
- data/scss/_gerillass.scss +15 -0
- data/scss/internal/_color-problem.scss +99 -0
- data/scss/internal/_color-stops-problem.scss +94 -0
- data/scss/internal/_condition-width.scss +22 -0
- data/scss/internal/_custom-property-in.scss +25 -0
- data/scss/internal/_gradient.scss +425 -0
- data/scss/internal/_image-value.scss +68 -0
- data/scss/internal/_is-condition-value.scss +94 -0
- data/scss/internal/_is-css-function.scss +21 -0
- data/scss/internal/_is-size.scss +22 -0
- data/scss/internal/_keyword-value.scss +76 -0
- data/scss/internal/_length-problem.scss +127 -0
- data/scss/internal/_sibling-index.scss +51 -0
- data/scss/internal/_words.scss +35 -0
- data/scss/library/_adaptive.scss +31 -0
- data/scss/library/_after.scss +28 -0
- data/scss/library/_all-buttons.scss +21 -0
- data/scss/library/_all-text-inputs.scss +21 -0
- data/{core → scss}/library/_antialias.scss +5 -1
- data/scss/library/_aspect-ratio.scss +27 -0
- data/scss/library/_background-dots.scss +104 -0
- data/scss/library/_background-image.scss +89 -0
- data/scss/library/_background-stripes.scss +88 -0
- data/scss/library/_before.scss +28 -0
- data/scss/library/_border-box.scss +30 -0
- data/scss/library/_border-radius.scss +164 -0
- data/scss/library/_brand-logo.scss +33 -0
- data/scss/library/_breakpoint.scss +96 -0
- data/scss/library/_breakpointer.scss +40 -0
- data/scss/library/_center.scss +19 -0
- data/scss/library/_circle.scss +15 -0
- data/{core → scss}/library/_clearfix.scss +1 -1
- data/scss/library/_columnizer.scss +125 -0
- data/scss/library/_container-query.scss +119 -0
- data/scss/library/_container.scss +72 -0
- data/scss/library/_counter.scss +59 -0
- data/scss/library/_ellipsis.scss +87 -0
- data/scss/library/_escape-to-parent.scss +12 -0
- data/scss/library/_except.scss +71 -0
- data/scss/library/_focus-ring.scss +63 -0
- data/scss/library/_font-face.scss +240 -0
- data/scss/library/_gradient.scss +31 -0
- data/scss/library/_hide.scss +25 -0
- data/scss/library/_index.scss +57 -0
- data/scss/library/_line-clamp.scss +38 -0
- data/scss/library/_loadify.scss +62 -0
- data/scss/library/_motion-safe.scss +28 -0
- data/scss/library/_only.scss +73 -0
- data/scss/library/_placeholder-shown.scss +7 -0
- data/scss/library/_placeholder.scss +19 -0
- data/scss/library/_position.scss +72 -0
- data/scss/library/_remove.scss +40 -0
- data/scss/library/_reset-css.scss +57 -0
- data/scss/library/_reset-figure.scss +10 -0
- data/scss/library/_resizable.scss +34 -0
- data/scss/library/_responsive-image.scss +6 -0
- data/scss/library/_scissors.scss +34 -0
- data/scss/library/_screen-agent.scss +34 -0
- data/scss/library/_sizer.scss +15 -0
- data/scss/library/_smartphone.scss +29 -0
- data/scss/library/_sprite.scss +100 -0
- data/scss/library/_stretched-link.scss +21 -0
- data/scss/library/_tablet.scss +29 -0
- data/scss/library/_text-gradient.scss +48 -0
- data/scss/library/_text-image.scss +15 -0
- data/scss/library/_text-selection.scss +22 -0
- data/scss/library/_text-shadow.scss +145 -0
- data/scss/library/_text-stroke.scss +43 -0
- data/scss/library/_tokens.scss +111 -0
- data/scss/library/_triangle.scss +115 -0
- data/scss/lists/_index.scss +8 -0
- data/scss/lists/_list-of-anchor-pseudo-classes.scss +9 -0
- data/scss/lists/_list-of-buttons.scss +8 -0
- data/scss/lists/_list-of-counter-styles.scss +59 -0
- data/scss/lists/_list-of-directions.scss +12 -0
- data/scss/lists/_list-of-length-units.scss +23 -0
- data/scss/lists/_list-of-text-inputs.scss +20 -0
- data/scss/maps/_index.scss +8 -0
- data/scss/maps/_map-for-breakpoints.scss +9 -0
- data/scss/maps/_map-for-directions.scss +12 -0
- data/scss/maps/_map-for-font-formats.scss +9 -0
- data/scss/maps/_map-for-positions.scss +13 -0
- data/scss/maps/_map-for-smartphones.scss +72 -0
- data/scss/maps/_map-for-tablets.scss +32 -0
- data/scss/utilities/_clear-unit.scss +11 -0
- data/scss/utilities/_clear-whitespace.scss +15 -0
- data/scss/utilities/_convert-to-em.scss +16 -0
- data/scss/utilities/_convert-to-number.scss +45 -0
- data/scss/utilities/_fill-nulls.scss +18 -0
- data/scss/utilities/_fluid.scss +76 -0
- data/scss/utilities/_font-sizer.scss +19 -0
- data/scss/utilities/_font-source.scss +23 -0
- data/scss/utilities/_gradient-value.scss +24 -0
- data/scss/utilities/_index.scss +26 -0
- data/scss/utilities/_is-color.scss +16 -0
- data/scss/utilities/_is-gutter.scss +24 -0
- data/scss/utilities/_is-number.scss +11 -0
- data/scss/utilities/_is-time.scss +14 -0
- data/scss/utilities/_map-deep-get.scss +10 -0
- data/scss/utilities/_pixelify.scss +20 -0
- data/scss/utilities/_pseudo-selector.scss +12 -0
- data/scss/utilities/_remify.scss +16 -0
- data/scss/utilities/_shade.scss +10 -0
- data/scss/utilities/_shorthand-property.scss +17 -0
- data/scss/utilities/_tint.scss +10 -0
- data/scss/utilities/_validate-breakpoint.scss +41 -0
- data/scss/utilities/_validate-length.scss +37 -0
- data/scss/utilities/_validate-ratio.scss +77 -0
- data/scss/utilities/_validate-scissors.scss +34 -0
- metadata +131 -46
- data/core/_gerillass.scss +0 -4
- data/core/library/_before.scss +0 -18
- data/core/library/_border-box.scss +0 -26
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
@use "../internal/custom-property-in" as *;
|
|
9
|
+
@use "../internal/condition-width" as *;
|
|
10
|
+
|
|
11
|
+
// Characters and names a browser will not keep as the name in an @container
|
|
12
|
+
// rule. Measured in Chrome 152, the rule was dropped for `var(--n)`, `none`,
|
|
13
|
+
// `and`, `or`, `default`, `inherit`, `initial`, `unset`, `revert`,
|
|
14
|
+
// `revert-layer`, `my card`, `1card`, `-1card`, `a.b`, `#card` and `card!`,
|
|
15
|
+
// in any case. `not` was worse: the rule was kept with no name, as a negated
|
|
16
|
+
// query, so it matched the opposite of what was asked. `--card`, `-card`,
|
|
17
|
+
// `_card`, `c-`, `ünlü`, `auto` and `normal` were kept.
|
|
18
|
+
$-reserved-names: "none" "and" "or" "not" "default" "inherit" "initial" "unset" "revert" "revert-layer";
|
|
19
|
+
$-forbidden-in-name: "." "," "/" "#" ":" ";" "(" ")" "[" "]" "{" "}" "!" "@" "$" "%" "^" "&" "*" "+" "=" "<" ">" "?" "\\" "|" "~" "`" "'" "\"";
|
|
20
|
+
|
|
21
|
+
@function -name-problem($name) {
|
|
22
|
+
// An empty name has always compiled to an unnamed query, which works, so it
|
|
23
|
+
// is left alone rather than refused.
|
|
24
|
+
$text: "#{$name}";
|
|
25
|
+
@if string.length($text) == 0 {
|
|
26
|
+
@return null;
|
|
27
|
+
}
|
|
28
|
+
@if string.index($text, "var(") {
|
|
29
|
+
@return "a custom property is not evaluated in a @container condition, so the rule would never apply. Pass the name itself, such as `\"card\"`; the `container` mixin can still take its name from a custom property";
|
|
30
|
+
}
|
|
31
|
+
@if string.index($text, " ") {
|
|
32
|
+
@return "a query names one container. Pass one name, such as `\"card\"`";
|
|
33
|
+
}
|
|
34
|
+
@if list.index($-reserved-names, string.to-lower-case($text)) {
|
|
35
|
+
@return "`none`, `and`, `or`, `not`, `default` and the CSS-wide keywords are reserved there. A browser drops the rule, and reads `not` as negating the query instead. Pass another name, such as `\"card\"`";
|
|
36
|
+
}
|
|
37
|
+
$first: string.slice($text, 1, 1);
|
|
38
|
+
$second: string.slice($text, 2, 2);
|
|
39
|
+
@if string.index("0123456789", $first) or ($first == "-" and string.length($text) > 1 and string.index("0123456789", $second)) {
|
|
40
|
+
@return "a container name cannot start with a digit, or with a hyphen and a digit. Pass a name such as `\"card\"`";
|
|
41
|
+
}
|
|
42
|
+
@each $character in $-forbidden-in-name {
|
|
43
|
+
@if string.index($text, $character) {
|
|
44
|
+
@return "a container name cannot contain `#{$character}`. Use letters, digits, hyphens and underscores";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
@return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// A @container rule, taking the same argument shapes as `breakpoint` so the two
|
|
51
|
+
// read alike. Sizes may be a key from $map-for-breakpoints or a raw length; a
|
|
52
|
+
// container is usually narrower than the viewport, so a length is the common
|
|
53
|
+
// case.
|
|
54
|
+
//
|
|
55
|
+
// Pass $name to query one named container rather than the nearest ancestor.
|
|
56
|
+
// The container itself is declared with the `container` mixin, on an ancestor
|
|
57
|
+
// of whatever this styles.
|
|
58
|
+
@mixin container-query($params...) {
|
|
59
|
+
$keywords: meta.keywords($params);
|
|
60
|
+
$name: map.get($keywords, name);
|
|
61
|
+
$count: list.length($params);
|
|
62
|
+
|
|
63
|
+
@if $name != null and meta.type-of($name) != "string" {
|
|
64
|
+
@error "`#{$name}` is not a valid $name for `container-query`. Pass a container name as a string, such as `\"card\"`.";
|
|
65
|
+
}
|
|
66
|
+
@if $name != null {
|
|
67
|
+
$problem: -name-problem($name);
|
|
68
|
+
@if $problem {
|
|
69
|
+
@error "`#{$name}` is not a valid $name for `container-query`: #{$problem}.";
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
$custom-property: customPropertyIn($params);
|
|
74
|
+
@if $custom-property {
|
|
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.";
|
|
76
|
+
}
|
|
77
|
+
$condition: null;
|
|
78
|
+
|
|
79
|
+
@if $count == 1 {
|
|
80
|
+
$value: list.nth($params, 1);
|
|
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");
|
|
84
|
+
$condition: "(width: #{$width})";
|
|
85
|
+
// A single pixel, as in `breakpoint`; still emitted, with a warning.
|
|
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.";
|
|
87
|
+
} @else if $count == 2 {
|
|
88
|
+
$mode: list.nth($params, 1);
|
|
89
|
+
@if not list.index("only" "min" "max" "between", $mode) {
|
|
90
|
+
// Two bare sizes mean a range, as they do in `breakpoint`.
|
|
91
|
+
$condition: "(min-width: #{conditionWidth($mode, "container-query", "@container")}) and (max-width: #{conditionWidth(list.nth($params, 2), "container-query", "@container")})";
|
|
92
|
+
} @else {
|
|
93
|
+
$value: list.nth($params, 2);
|
|
94
|
+
@if $mode == "only" {
|
|
95
|
+
$condition: "(width: #{conditionWidth($value, "container-query", "@container")})";
|
|
96
|
+
} @else if $mode == "min" {
|
|
97
|
+
$condition: "(min-width: #{conditionWidth($value, "container-query", "@container")})";
|
|
98
|
+
} @else if $mode == "max" {
|
|
99
|
+
$condition: "(max-width: #{conditionWidth($value, "container-query", "@container")})";
|
|
100
|
+
} @else {
|
|
101
|
+
$start: list.nth($value, 1);
|
|
102
|
+
$end: list.nth($value, 2);
|
|
103
|
+
$condition: "(min-width: #{conditionWidth($start, "container-query", "@container")}) and (max-width: #{conditionWidth($end, "container-query", "@container")})";
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
} @else {
|
|
107
|
+
@error "`container-query` takes one or two arguments, and was given #{$count}. Pass a size, two sizes for a range, or one of `min`, `max`, `only` or `between` followed by a size.";
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@if $name {
|
|
111
|
+
@container #{string.unquote($name)} #{$condition} {
|
|
112
|
+
@content;
|
|
113
|
+
}
|
|
114
|
+
} @else {
|
|
115
|
+
@container #{$condition} {
|
|
116
|
+
@content;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "sass:string";
|
|
6
|
+
@use "../internal/words" as *;
|
|
7
|
+
|
|
8
|
+
// What a browser will not keep in `container-name`. Measured in Chrome 152, the
|
|
9
|
+
// declaration was dropped for `and`, `or`, `not` and `default` in any case, a
|
|
10
|
+
// name starting with a digit or a hyphen and a digit, and a name holding `.`,
|
|
11
|
+
// `#` or `!`; and for a list with any one of those in it, such as `card and`,
|
|
12
|
+
// and for `none` or a CSS-wide keyword beside another name, such as `NONE card`
|
|
13
|
+
// or `card inherit`. `none`, `inherit`, `revert` and the other CSS-wide
|
|
14
|
+
// keywords were kept on their own, as were several valid names,
|
|
15
|
+
// `-card`, and `var()`, which a container can take its name from.
|
|
16
|
+
$-reserved-names: "and" "or" "not" "default";
|
|
17
|
+
$-alone-names: "none" "inherit" "initial" "unset" "revert" "revert-layer";
|
|
18
|
+
$-forbidden-in-name: "." "," "/" "#" ":" ";" "(" ")" "[" "]" "{" "}" "!" "@" "$" "%" "^" "&" "*" "+" "=" "<" ">" "?" "\\" "|" "~" "`" "'" "\"";
|
|
19
|
+
|
|
20
|
+
@function -name-problem($name) {
|
|
21
|
+
$text: "#{$name}";
|
|
22
|
+
@if string.index($text, "var(") {
|
|
23
|
+
@return null;
|
|
24
|
+
}
|
|
25
|
+
$words: wordsOf($text);
|
|
26
|
+
@each $word in $words {
|
|
27
|
+
$lower: string.to-lower-case($word);
|
|
28
|
+
@if list.index($-alone-names, $lower) and list.length($words) > 1 {
|
|
29
|
+
@return "`#{$word}` only works as the whole value, not beside another name";
|
|
30
|
+
}
|
|
31
|
+
@if list.index($-reserved-names, $lower) {
|
|
32
|
+
@return "`and`, `or`, `not` and `default` cannot name a container";
|
|
33
|
+
}
|
|
34
|
+
$first: string.slice($word, 1, 1);
|
|
35
|
+
@if string.index("0123456789", $first) or ($first == "-" and string.length($word) > 1 and string.index("0123456789", string.slice($word, 2, 2))) {
|
|
36
|
+
@return "a container name cannot start with a digit, or with a hyphen and a digit";
|
|
37
|
+
}
|
|
38
|
+
@each $character in $-forbidden-in-name {
|
|
39
|
+
@if string.index($word, $character) {
|
|
40
|
+
@return "a container name cannot contain `#{$character}`";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
@return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Marks an element as a query container, so `container-query` can ask about its
|
|
48
|
+
// width instead of the viewport's.
|
|
49
|
+
//
|
|
50
|
+
// The rule that asks has to sit on a descendant. An element is not matched by a
|
|
51
|
+
// @container rule that reads its own container, and nothing warns you: the rule
|
|
52
|
+
// is simply never applied. Measured in a browser, a 600px element with
|
|
53
|
+
// `container-type: inline-size` on itself did not match `@container (min-width:
|
|
54
|
+
// 400px)`, while the same query did match a child of it.
|
|
55
|
+
@mixin container($name: null, $type: inline-size) {
|
|
56
|
+
@if not list.index("inline-size" "size" "normal", $type) {
|
|
57
|
+
@error "`#{$type}` is not a valid $type for `container`. Pass one of: inline-size, size, normal.";
|
|
58
|
+
}
|
|
59
|
+
@if $name != null and meta.type-of($name) != "string" {
|
|
60
|
+
@error "`#{$name}` is not a valid $name for `container`. Pass a name as a string, such as `\"card\"`, or no name at all.";
|
|
61
|
+
}
|
|
62
|
+
@if $name != null {
|
|
63
|
+
$problem: -name-problem($name);
|
|
64
|
+
@if $problem {
|
|
65
|
+
@error "`#{$name}` is not a valid $name for `container`: #{$problem}, and a browser drops the whole declaration. Pass a name such as `\"card\"`.";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
container-type: $type;
|
|
69
|
+
@if $name {
|
|
70
|
+
container-name: string.unquote($name);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "../lists/list-of-counter-styles" as *;
|
|
5
|
+
@use "../internal/is-css-function" as *;
|
|
6
|
+
|
|
7
|
+
@mixin counter($params...) {
|
|
8
|
+
$counter: null;
|
|
9
|
+
$counter-before: null;
|
|
10
|
+
$counter-after: null;
|
|
11
|
+
|
|
12
|
+
@if list.length($params) == 1 {
|
|
13
|
+
@if list.index($list-of-counter-styles, list.nth($params, 1)) {
|
|
14
|
+
$counter: list.nth($params, 1);
|
|
15
|
+
} @else {
|
|
16
|
+
$counter-after: list.nth($params, 1);
|
|
17
|
+
}
|
|
18
|
+
} @else if list.length($params) == 2 {
|
|
19
|
+
@if list.index($list-of-counter-styles, list.nth($params, 1)) {
|
|
20
|
+
$counter: list.nth($params, 1);
|
|
21
|
+
$counter-after: list.nth($params, 2);
|
|
22
|
+
} @else if list.index($list-of-counter-styles, list.nth($params, 2)) {
|
|
23
|
+
$counter-before: list.nth($params, 1);
|
|
24
|
+
$counter: list.nth($params, 2);
|
|
25
|
+
} @else {
|
|
26
|
+
$counter-before: list.nth($params, 1);
|
|
27
|
+
$counter-after: list.nth($params, 2);
|
|
28
|
+
}
|
|
29
|
+
} @else if list.length($params) == 3 {
|
|
30
|
+
@if list.index($list-of-counter-styles, list.nth($params, 2)) {
|
|
31
|
+
$counter-before: list.nth($params, 1);
|
|
32
|
+
$counter: list.nth($params, 2);
|
|
33
|
+
$counter-after: list.nth($params, 3);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// A prefix or suffix is quoted into text, except a call CSS resolves, which
|
|
38
|
+
// quoting would turn into the literal characters.
|
|
39
|
+
$quote-before: '"';
|
|
40
|
+
$quote-after: '"';
|
|
41
|
+
@if isCssFunction($counter-before, "var" "attr" "counter" "counters") {
|
|
42
|
+
$quote-before: "";
|
|
43
|
+
}
|
|
44
|
+
@if isCssFunction($counter-after, "var" "attr" "counter" "counters") {
|
|
45
|
+
$quote-after: "";
|
|
46
|
+
}
|
|
47
|
+
&.counter-start {
|
|
48
|
+
counter-reset: glsCounter;
|
|
49
|
+
}
|
|
50
|
+
&.counter-start .counter-item::before,
|
|
51
|
+
&.counter-continue .counter-item::before {
|
|
52
|
+
content: #{if($counter-before, $quote-before + $counter-before + $quote-before + " ", null)}counter(
|
|
53
|
+
glsCounter#{if($counter, ", " + $counter, null)}
|
|
54
|
+
)
|
|
55
|
+
#{if($counter-after, " " + $quote-after + $counter-after + $quote-after, null)};
|
|
56
|
+
counter-increment: glsCounter;
|
|
57
|
+
@content;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
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
|
+
|
|
67
|
+
@mixin ellipsis($width: 100%, $display: inline-block) {
|
|
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
|
+
}
|
|
82
|
+
max-width: $width;
|
|
83
|
+
text-overflow: ellipsis;
|
|
84
|
+
white-space: nowrap;
|
|
85
|
+
overflow: hidden;
|
|
86
|
+
word-wrap: normal;
|
|
87
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
|
|
5
|
+
@mixin escape-to-parent($selector: null) {
|
|
6
|
+
@if $selector != null and meta.type-of($selector) != "string" {
|
|
7
|
+
@error "`#{$selector}` is not a valid $selector for `escape-to-parent`. Pass a selector as a string, such as `\".theme-dark\"`.";
|
|
8
|
+
}
|
|
9
|
+
@at-root #{$selector}#{&} {
|
|
10
|
+
@content;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:list";
|
|
4
|
+
@use "sass:meta";
|
|
5
|
+
@use "sass:string";
|
|
6
|
+
@use "../internal/sibling-index" as *;
|
|
7
|
+
|
|
8
|
+
@mixin except($params...) {
|
|
9
|
+
@if list.length($params) == 0 {
|
|
10
|
+
@error "Please pass an argument. The argument must be either a negative or positive number or list of numbers. Or pass one of the following predefined string values: 'first', 'last', 'odd', 'even'.";
|
|
11
|
+
} @else if list.length($params) == 1 {
|
|
12
|
+
$value: list.nth($params, 1);
|
|
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
|
+
}
|
|
20
|
+
@if $value < 0 {
|
|
21
|
+
&:not(:nth-last-of-type(#{$value * -1})) {
|
|
22
|
+
@content;
|
|
23
|
+
}
|
|
24
|
+
} @else {
|
|
25
|
+
&:not(:nth-of-type(#{$value})) {
|
|
26
|
+
@content;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
} @else if meta.type-of($value) == "string" {
|
|
30
|
+
@if $value == "odd" {
|
|
31
|
+
&:not(:nth-of-type(odd)) {
|
|
32
|
+
@content;
|
|
33
|
+
}
|
|
34
|
+
} @else if $value == "even" {
|
|
35
|
+
&:not(:nth-of-type(even)) {
|
|
36
|
+
@content;
|
|
37
|
+
}
|
|
38
|
+
} @else if $value == "first" {
|
|
39
|
+
&:not(:first-of-type) {
|
|
40
|
+
@content;
|
|
41
|
+
}
|
|
42
|
+
} @else if $value == "last" {
|
|
43
|
+
&:not(:last-of-type) {
|
|
44
|
+
@content;
|
|
45
|
+
}
|
|
46
|
+
} @else {
|
|
47
|
+
&:not(#{$value}) {
|
|
48
|
+
@content;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} @else {
|
|
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`.";
|
|
53
|
+
}
|
|
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
|
+
}
|
|
63
|
+
$items: "";
|
|
64
|
+
@for $i from 1 through list.length($params) {
|
|
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)}))"));
|
|
66
|
+
}
|
|
67
|
+
&#{$items} {
|
|
68
|
+
@content;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
2
|
+
|
|
3
|
+
@use "sass:meta";
|
|
4
|
+
@use "../internal/color-problem" as *;
|
|
5
|
+
@use "../internal/length-problem" as *;
|
|
6
|
+
|
|
7
|
+
// Draws a focus ring for keyboard users. Two things are usually got wrong by
|
|
8
|
+
// hand, and this writes the version that avoids both.
|
|
9
|
+
//
|
|
10
|
+
// The ring goes on :focus-visible, not :focus. Measured in Chrome 152: a mouse
|
|
11
|
+
// click on a button or a link does not match :focus-visible, so the ring stays
|
|
12
|
+
// out of the way of pointer users, while Tab does match it. Text inputs are the
|
|
13
|
+
// exception and match it on a click too, which is the browser's own choice.
|
|
14
|
+
// Hiding the ring with `:focus { outline: none; }` is the common mistake it
|
|
15
|
+
// replaces: tabbing to that button gave no outline and no shadow at all.
|
|
16
|
+
//
|
|
17
|
+
// The ring is an outline, not a box-shadow. A box-shadow ring looks the same
|
|
18
|
+
// in an ordinary page, but forced-colors mode, as Windows High Contrast is
|
|
19
|
+
// exposed to CSS, sets box-shadow to none and repaints outline-color in a
|
|
20
|
+
// system colour, so a shadow ring vanishes for the users who most need it.
|
|
21
|
+
// That part follows the CSS Color Adjustment specification; it was not
|
|
22
|
+
// measured here, because the browser used could not emulate the mode.
|
|
23
|
+
//
|
|
24
|
+
// Two things measured about the outline itself. It follows border-radius: on a
|
|
25
|
+
// button with a 12px radius the ring is rounded to match. And an ancestor with
|
|
26
|
+
// overflow: hidden clips it: a 2px offset left only the ring's corners showing,
|
|
27
|
+
// while an offset of -4px drew it inside the element, fully visible. Pass a
|
|
28
|
+
// negative $offset where the element sits in a clipping container.
|
|
29
|
+
@mixin focus-ring($width: 2px, $offset: 2px, $color: currentColor) {
|
|
30
|
+
@if not & {
|
|
31
|
+
@error "`focus-ring` styles the element it is called in, so call it inside a selector, such as `.button { @include focus-ring; }`.";
|
|
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
|
+
}
|
|
58
|
+
|
|
59
|
+
&:focus-visible {
|
|
60
|
+
outline: $width solid $color;
|
|
61
|
+
outline-offset: $offset;
|
|
62
|
+
}
|
|
63
|
+
}
|