@volverjs/style 0.1.26 → 0.1.28
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 +12 -0
- package/dist/base.css +1 -1
- package/dist/components/vv-accordion.css +1 -1
- package/dist/components/vv-alert-group.css +1 -1
- package/dist/components/vv-alert.css +1 -1
- package/dist/components/vv-avatar.css +1 -1
- package/dist/components/vv-badge.css +1 -1
- package/dist/components/vv-button-group.css +1 -1
- package/dist/components/vv-button.css +1 -1
- package/dist/components/vv-card.css +1 -1
- package/dist/components/vv-checkbox.css +1 -1
- package/dist/components/vv-dialog.css +1 -1
- package/dist/components/vv-dropdown-option.css +1 -1
- package/dist/components/vv-dropdown.css +1 -1
- package/dist/components/vv-input-file.css +1 -1
- package/dist/components/vv-input-range.css +1 -1
- package/dist/components/vv-input-text.css +1 -1
- package/dist/components/vv-nav.css +1 -1
- package/dist/components/vv-progress.css +1 -1
- package/dist/components/vv-radio.css +1 -1
- package/dist/components/vv-select.css +1 -1
- package/dist/components/vv-textarea.css +1 -1
- package/dist/components.css +1 -1
- package/dist/export.css +1 -1
- package/dist/props/background.css +1 -1
- package/dist/props/input.css +1 -1
- package/dist/props/typography.css +1 -1
- package/dist/props.css +1 -1
- package/dist/reset.css +1 -1
- package/dist/utilities/backgrounds.css +1 -1
- package/dist/utilities/flexbox.css +1 -1
- package/dist/utilities/layout.css +1 -1
- package/dist/utilities/sizing.css +1 -1
- package/dist/utilities/typography.css +1 -1
- package/dist/utilities.css +1 -1
- package/dist/volver.css +1 -1
- package/package.json +8 -1
- package/src/_config.scss +6 -1
- package/src/settings/_input.scss +8 -0
- package/src/settings/components/_vv-accordion.scss +6 -4
- package/src/settings/components/_vv-alert.scss +8 -3
- package/src/settings/components/_vv-badge.scss +21 -1
- package/src/settings/components/_vv-button.scss +12 -5
- package/src/settings/components/_vv-checkbox.scss +27 -3
- package/src/settings/components/_vv-dropdown-option.scss +4 -1
- package/src/settings/components/_vv-input-text.scss +3 -0
- package/src/settings/components/_vv-nav.scss +26 -1
- package/src/settings/components/_vv-radio.scss +17 -2
- package/src/settings/components/_vv-select.scss +5 -0
- package/src/tools/mixin-modules/_bem.scss +65 -11
- package/src/utilities/flexbox.scss +27 -0
package/package.json
CHANGED
|
@@ -24,10 +24,17 @@
|
|
|
24
24
|
"bugs": {
|
|
25
25
|
"url": "https://github.com/volverjs/style/issues"
|
|
26
26
|
},
|
|
27
|
-
"version": "0.1.
|
|
27
|
+
"version": "0.1.28",
|
|
28
28
|
"engines": {
|
|
29
29
|
"node": ">= 20.x"
|
|
30
30
|
},
|
|
31
|
+
"browserslist": [
|
|
32
|
+
"chrome >= 133",
|
|
33
|
+
"edge >= 133",
|
|
34
|
+
"firefox >= 128",
|
|
35
|
+
"safari >= 16.4",
|
|
36
|
+
"ios_saf >= 16.4"
|
|
37
|
+
],
|
|
31
38
|
"type": "module",
|
|
32
39
|
"main": "dist/volver.css",
|
|
33
40
|
"style": "dist/volver.css",
|
package/src/_config.scss
CHANGED
|
@@ -22,7 +22,12 @@ $zero-specificity-for-utilities: true !default;
|
|
|
22
22
|
// components prefix
|
|
23
23
|
$components-prefix: vv !default;
|
|
24
24
|
|
|
25
|
-
// preflight
|
|
25
|
+
// preflight: bare form controls under `.preflight` take the look of their
|
|
26
|
+
// component through `@extend` of its placeholders, the block-level state
|
|
27
|
+
// placeholders included. A `state.disabled` or `state.readonly` override in a
|
|
28
|
+
// component map therefore reaches every bare disabled or readonly control on
|
|
29
|
+
// the page, not only the ones inside a `.vv-*` block, and only the compiled
|
|
30
|
+
// CSS shows it. Overrides on the `element` maps of a state stay in the block.
|
|
26
31
|
$preflight: true !default;
|
|
27
32
|
|
|
28
33
|
// components names
|
package/src/settings/_input.scss
CHANGED
|
@@ -59,6 +59,14 @@ $input: (
|
|
|
59
59
|
translate: 0 -0.8em,
|
|
60
60
|
),
|
|
61
61
|
),
|
|
62
|
+
// Block size of a checkbox, a radio or the pill of a switch: the side of
|
|
63
|
+
// the square, and the figure the offset that keeps the control on the
|
|
64
|
+
// first line of a wrapping label is derived from. It was written twice per
|
|
65
|
+
// component, once as `min-width` and once as `height`, and the switch
|
|
66
|
+
// spelled a third value.
|
|
67
|
+
control: (
|
|
68
|
+
size: var(--spacing-20),
|
|
69
|
+
),
|
|
62
70
|
range: (
|
|
63
71
|
accent-color: var(--color-brand),
|
|
64
72
|
track-color: var(--color-surface-3),
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
$vv-accordion: (
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
// `1lh` is resolved where the token is read, on the summary, so the reserved
|
|
3
|
+
// space follows the line box of the summary rather than a line height
|
|
4
|
+
// spelled out a second time here.
|
|
5
|
+
--accordion-marker-size: calc(var(--spacing-sm) + 1lh),
|
|
4
6
|
--accordion-padding-top: var(--spacing-14),
|
|
5
7
|
--accordion-padding-right: var(--spacing-14),
|
|
6
8
|
--accordion-padding-bottom: var(--spacing-14),
|
|
@@ -57,8 +59,8 @@ $vv-accordion: (
|
|
|
57
59
|
position: absolute,
|
|
58
60
|
[top]: var(--accordion-padding-top),
|
|
59
61
|
[left]: var(--accordion-padding-left),
|
|
60
|
-
width:
|
|
61
|
-
height:
|
|
62
|
+
width: 1lh,
|
|
63
|
+
height: 1lh,
|
|
62
64
|
background-image: var(--bg-chevron),
|
|
63
65
|
background-position: center,
|
|
64
66
|
background-size: 1em,
|
|
@@ -8,7 +8,7 @@ $vv-alert: (
|
|
|
8
8
|
border-width: var(--border),
|
|
9
9
|
display: flex,
|
|
10
10
|
flex-wrap: wrap,
|
|
11
|
-
align-items:
|
|
11
|
+
align-items: flex-start,
|
|
12
12
|
gap: var(--spacing-sm),
|
|
13
13
|
min-width: 0,
|
|
14
14
|
overflow: hidden,
|
|
@@ -16,13 +16,13 @@ $vv-alert: (
|
|
|
16
16
|
element: (
|
|
17
17
|
header: (
|
|
18
18
|
display: flex,
|
|
19
|
-
align-items:
|
|
19
|
+
align-items: flex-start,
|
|
20
20
|
gap: var(--spacing-sm),
|
|
21
21
|
line-height: var(--leading-normal),
|
|
22
22
|
color: var(--color-word),
|
|
23
23
|
overflow: hidden,
|
|
24
24
|
text-overflow: ellipsis,
|
|
25
|
-
|
|
25
|
+
min-width: 0,
|
|
26
26
|
),
|
|
27
27
|
title: (
|
|
28
28
|
min-width: 0,
|
|
@@ -53,7 +53,12 @@ $vv-alert: (
|
|
|
53
53
|
border-radius: var(--rounded),
|
|
54
54
|
),
|
|
55
55
|
icon: (
|
|
56
|
+
--alert-icon-size: 1.1em,
|
|
57
|
+
[inline-size]: var(--alert-icon-size),
|
|
58
|
+
block-size: auto,
|
|
59
|
+
aspect-ratio: 1,
|
|
56
60
|
flex-shrink: 0,
|
|
61
|
+
[translate]: 0 calc((1lh - var(--alert-icon-size)) / 2),
|
|
57
62
|
),
|
|
58
63
|
close-mask: (
|
|
59
64
|
display: none,
|
|
@@ -38,10 +38,26 @@ $vv-badge: (
|
|
|
38
38
|
),
|
|
39
39
|
),
|
|
40
40
|
element: (
|
|
41
|
+
icon: (
|
|
42
|
+
// A descendant selector, not a child one: the icon of an action
|
|
43
|
+
// badge sits inside the button. `svg:not(svg *)` leaves the parts
|
|
44
|
+
// of a composite icon to the icon itself.
|
|
45
|
+
_alias: ':where(svg:not(svg *), [data-icon])',
|
|
46
|
+
aspect-ratio: 1,
|
|
47
|
+
inline-size: 1lh,
|
|
48
|
+
block-size: auto,
|
|
49
|
+
flex-shrink: 0,
|
|
50
|
+
background-position: center,
|
|
51
|
+
background-repeat: no-repeat,
|
|
52
|
+
background-size: contain,
|
|
53
|
+
),
|
|
41
54
|
button: (
|
|
42
55
|
_alias: '> button',
|
|
43
56
|
_combinator: '>',
|
|
44
57
|
cursor: pointer,
|
|
58
|
+
display: inline-flex,
|
|
59
|
+
align-items: center,
|
|
60
|
+
justify-content: center,
|
|
45
61
|
padding: 0 0.5em,
|
|
46
62
|
margin: 0 -0.5em,
|
|
47
63
|
min-height: 2em,
|
|
@@ -58,7 +74,11 @@ $vv-badge: (
|
|
|
58
74
|
),
|
|
59
75
|
modifier: (
|
|
60
76
|
action: (
|
|
61
|
-
gap
|
|
77
|
+
// The same gap as a badge that holds its icon directly. The button
|
|
78
|
+
// widens its hit area toward the text with a negative margin and
|
|
79
|
+
// puts the drawing back with an equal padding, so the extra 0.5em
|
|
80
|
+
// this gap used to carry only pushed the icon away from the label.
|
|
81
|
+
gap: 0.5ch,
|
|
62
82
|
),
|
|
63
83
|
sm: (
|
|
64
84
|
--badge-font-size: 0.6rem,
|
|
@@ -49,7 +49,14 @@ $vv-button: (
|
|
|
49
49
|
inline-size: 1.1em,
|
|
50
50
|
margin: 0,
|
|
51
51
|
flex-shrink: 0,
|
|
52
|
-
|
|
52
|
+
// The box is 1.1em wide and at least one line tall, so it is not
|
|
53
|
+
// square. An `<svg>` centres itself in it, an icon painted as a
|
|
54
|
+
// background does not: these three are inert for the first and
|
|
55
|
+
// place the second. The `_alias` claims to take both.
|
|
56
|
+
background-position: center,
|
|
57
|
+
background-repeat: no-repeat,
|
|
58
|
+
background-size: contain,
|
|
59
|
+
[min-height]: 1lh,
|
|
53
60
|
),
|
|
54
61
|
label: (
|
|
55
62
|
white-space: nowrap,
|
|
@@ -259,8 +266,8 @@ $vv-button: (
|
|
|
259
266
|
element: (
|
|
260
267
|
icon: (
|
|
261
268
|
margin-inline: -0.125ch,
|
|
262
|
-
block-size:
|
|
263
|
-
inline-size:
|
|
269
|
+
block-size: 1lh,
|
|
270
|
+
inline-size: 1lh,
|
|
264
271
|
),
|
|
265
272
|
),
|
|
266
273
|
),
|
|
@@ -298,8 +305,8 @@ $vv-button: (
|
|
|
298
305
|
element: (
|
|
299
306
|
icon: (
|
|
300
307
|
margin-inline: -0.125ch,
|
|
301
|
-
block-size:
|
|
302
|
-
inline-size:
|
|
308
|
+
block-size: 1lh,
|
|
309
|
+
inline-size: 1lh,
|
|
303
310
|
),
|
|
304
311
|
),
|
|
305
312
|
),
|
|
@@ -24,8 +24,17 @@ $vv-checkbox: (
|
|
|
24
24
|
input: (
|
|
25
25
|
_alias: "> input[type='checkbox']",
|
|
26
26
|
border: var(--spacing-2) solid var(--input-color),
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
// Plain declarations, so the size is read on the control: the
|
|
28
|
+
// `switch` modifier overrides the token, and a `var()` inside a
|
|
29
|
+
// generated custom property would have been substituted at the
|
|
30
|
+
// root and frozen at the default.
|
|
31
|
+
[min-width]: var(--input-control-size),
|
|
32
|
+
[height]: var(--input-control-size),
|
|
33
|
+
// The control belongs to the first line of the label, not to the
|
|
34
|
+
// centre of a label that wraps. `align-self` rather than
|
|
35
|
+
// `align-items` on the block, so the hint keeps its own alignment.
|
|
36
|
+
align-self: flex-start,
|
|
37
|
+
[translate]: 0 calc((1lh - var(--input-control-size)) / 2),
|
|
29
38
|
margin: 0 var(--input-label-gap) 0 0,
|
|
30
39
|
background-position: center,
|
|
31
40
|
background-size: var(--text-12) auto,
|
|
@@ -45,6 +54,19 @@ $vv-checkbox: (
|
|
|
45
54
|
),
|
|
46
55
|
),
|
|
47
56
|
),
|
|
57
|
+
label: (
|
|
58
|
+
// Without an element the label is an anonymous flex item, and one
|
|
59
|
+
// whose max-content width does not fit starts a new flex line:
|
|
60
|
+
// a long label dropped below the control instead of sitting next
|
|
61
|
+
// to it. `@volverjs/ui-vue` renders the span this reaches.
|
|
62
|
+
// Only a span without a class of its own, for plain markup: a
|
|
63
|
+
// badge or an icon written next to the label is a span too, and
|
|
64
|
+
// `flex: 1` would stretch it. Anything carrying a class takes
|
|
65
|
+
// `vv-checkbox__label` to be the label.
|
|
66
|
+
_alias: '> span:not([class])',
|
|
67
|
+
flex: 1,
|
|
68
|
+
min-width: 0,
|
|
69
|
+
),
|
|
48
70
|
hint: (
|
|
49
71
|
_alias: '> small',
|
|
50
72
|
_combinator: '>',
|
|
@@ -68,9 +90,11 @@ $vv-checkbox: (
|
|
|
68
90
|
switch: (
|
|
69
91
|
element: (
|
|
70
92
|
input: (
|
|
93
|
+
--input-control-size: var(--spacing-24),
|
|
71
94
|
border: 0,
|
|
95
|
+
// Not a plain declaration: this one reads no token of the
|
|
96
|
+
// control, so it keeps its generated custom property.
|
|
72
97
|
min-width: var(--spacing-44),
|
|
73
|
-
height: var(--spacing-24),
|
|
74
98
|
border-radius: var(--spacing-12),
|
|
75
99
|
background-color: var(--color-word-5),
|
|
76
100
|
position: relative,
|
|
@@ -3,7 +3,10 @@ $vv-dropdown-option: (
|
|
|
3
3
|
min-width: 0,
|
|
4
4
|
overflow: hidden,
|
|
5
5
|
gap: var(--spacing-sm),
|
|
6
|
-
|
|
6
|
+
// The hint is smaller than the label: `baseline` is what keeps the two
|
|
7
|
+
// sitting on the same line of text. `flex-end` aligned their bottom edges
|
|
8
|
+
// instead, which drifts with the descenders of the font.
|
|
9
|
+
align-items: baseline,
|
|
7
10
|
padding: var(--spacing-sm),
|
|
8
11
|
state: (
|
|
9
12
|
disabled: (
|
|
@@ -25,6 +25,9 @@ $vv-input-text: (
|
|
|
25
25
|
display: flex,
|
|
26
26
|
align-items: center,
|
|
27
27
|
flex: 1,
|
|
28
|
+
// The wrapper clips its content: the `::after` bars run along the
|
|
29
|
+
// bottom edge and the input never paints outside the box. The
|
|
30
|
+
// `vv-select` wrapper does not clip, on purpose: see its map.
|
|
28
31
|
overflow: hidden,
|
|
29
32
|
background-color: var(--input-background-color),
|
|
30
33
|
will-change: background-color,
|
|
@@ -21,6 +21,7 @@ $vv-nav: (
|
|
|
21
21
|
_alias: 'li > :is(a, button)',
|
|
22
22
|
display: flex,
|
|
23
23
|
align-items: center,
|
|
24
|
+
gap: 0.5ch,
|
|
24
25
|
will-change: background-color color,
|
|
25
26
|
transition: var(--transition-all),
|
|
26
27
|
color: var(--color-word-2),
|
|
@@ -40,6 +41,23 @@ $vv-nav: (
|
|
|
40
41
|
),
|
|
41
42
|
),
|
|
42
43
|
),
|
|
44
|
+
icon: (
|
|
45
|
+
_alias: 'li > :is(a, button) > :where(svg, [data-icon])',
|
|
46
|
+
--nav-icon-size: 1.1em,
|
|
47
|
+
// `align-self` and not `align-items` on the item: the label of a
|
|
48
|
+
// voice can wrap, and the icon belongs to its first line, while
|
|
49
|
+
// everything else in the item (a counter badge, a chevron) stays
|
|
50
|
+
// centred on the whole voice.
|
|
51
|
+
align-self: flex-start,
|
|
52
|
+
flex-shrink: 0,
|
|
53
|
+
[inline-size]: var(--nav-icon-size),
|
|
54
|
+
block-size: auto,
|
|
55
|
+
aspect-ratio: 1,
|
|
56
|
+
background-position: center,
|
|
57
|
+
background-repeat: no-repeat,
|
|
58
|
+
background-size: contain,
|
|
59
|
+
[translate]: 0 calc((1lh - var(--nav-icon-size)) / 2),
|
|
60
|
+
),
|
|
43
61
|
separator: (
|
|
44
62
|
_alias: 'li[role="separator"]',
|
|
45
63
|
display: block,
|
|
@@ -134,7 +152,14 @@ $vv-nav: (
|
|
|
134
152
|
flex: 1 1 0%,
|
|
135
153
|
),
|
|
136
154
|
item-label: (
|
|
137
|
-
|
|
155
|
+
// Still a flex container: as a block it puts the icon of a
|
|
156
|
+
// voice back on the baseline, where `align-self` is inert and
|
|
157
|
+
// the `gap` between the icon and the label is dropped, and the
|
|
158
|
+
// first line offset the icon carries becomes a nudge of its
|
|
159
|
+
// own. `justify-content` centres the icon and the label
|
|
160
|
+
// together, `text-align` the lines of a label that wraps.
|
|
161
|
+
display: flex,
|
|
162
|
+
justify-content: center,
|
|
138
163
|
width: 100%,
|
|
139
164
|
text-align: center,
|
|
140
165
|
),
|
|
@@ -42,13 +42,28 @@ $vv-radio: (
|
|
|
42
42
|
),
|
|
43
43
|
),
|
|
44
44
|
element: (
|
|
45
|
+
label: (
|
|
46
|
+
// See `vv-checkbox`: an anonymous flex item cannot be kept beside
|
|
47
|
+
// the control once the label wraps.
|
|
48
|
+
// Only a span without a class of its own, for plain markup: a
|
|
49
|
+
// badge or an icon written next to the label is a span too, and
|
|
50
|
+
// `flex: 1` would stretch it. Anything carrying a class takes
|
|
51
|
+
// `vv-radio__label` to be the label.
|
|
52
|
+
_alias: '> span:not([class])',
|
|
53
|
+
flex: 1,
|
|
54
|
+
min-width: 0,
|
|
55
|
+
),
|
|
45
56
|
input: (
|
|
46
57
|
_alias: "> input[type='radio']",
|
|
47
58
|
border-width: var(--spacing-2),
|
|
48
59
|
border-style: solid,
|
|
49
60
|
border-color: currentcolor,
|
|
50
|
-
|
|
51
|
-
|
|
61
|
+
// Plain declarations for the same reason as `vv-checkbox`: the
|
|
62
|
+
// size is read on the control, not at the root.
|
|
63
|
+
[min-width]: var(--input-control-size),
|
|
64
|
+
[height]: var(--input-control-size),
|
|
65
|
+
align-self: flex-start,
|
|
66
|
+
[translate]: 0 calc((1lh - var(--input-control-size)) / 2),
|
|
52
67
|
border-radius: 50%,
|
|
53
68
|
margin: 0 var(--input-label-gap) 0 0,
|
|
54
69
|
background-color: transparent,
|
|
@@ -26,6 +26,11 @@ $vv-select: (
|
|
|
26
26
|
display: flex,
|
|
27
27
|
align-items: center,
|
|
28
28
|
flex: 1,
|
|
29
|
+
// No `overflow: hidden` here, unlike the wrapper of `vv-input-text`,
|
|
30
|
+
// `vv-textarea` and `vv-input-file`: this wrapper also hosts the
|
|
31
|
+
// dropdown of a combobox, which a clip would cut off whenever the
|
|
32
|
+
// positioning strategy is not `fixed`. The ellipsis of a long value
|
|
33
|
+
// is clipped by the `value` element instead.
|
|
29
34
|
background-color: var(--input-background-color),
|
|
30
35
|
will-change: background-color,
|
|
31
36
|
transition: var(--transition-colors),
|
|
@@ -322,6 +322,10 @@ $-state-suffixes: (
|
|
|
322
322
|
|
|
323
323
|
@if meta.type-of(map.get($map, $key)) == 'map' {
|
|
324
324
|
@each $element, $value in map.get($map, $key) {
|
|
325
|
+
// `$block` is the block selector alone, threaded down unchanged
|
|
326
|
+
// from `spread-map-into-bem`: what a state or a transition
|
|
327
|
+
// expands to travels in `$modifier` instead. Passing a selector
|
|
328
|
+
// list here would suffix its last entry alone.
|
|
325
329
|
$selector: $block + '__' + $element;
|
|
326
330
|
|
|
327
331
|
// combinator
|
|
@@ -354,6 +358,10 @@ $-state-suffixes: (
|
|
|
354
358
|
|
|
355
359
|
@if $alias {
|
|
356
360
|
@if $modifier {
|
|
361
|
+
// One entry per selector of the modifier, in the same
|
|
362
|
+
// order as `$selector` above: `spread-map-into-states`
|
|
363
|
+
// pairs the two lists by index, so an `_alias` has to be
|
|
364
|
+
// a single selector, not a list of them.
|
|
357
365
|
$aliases: ();
|
|
358
366
|
|
|
359
367
|
@each $item in selector.parse($modifier) {
|
|
@@ -442,15 +450,35 @@ $-state-suffixes: (
|
|
|
442
450
|
@each $state, $value in map.get($map, $key) {
|
|
443
451
|
@if list.index($-valid-states, $state) {
|
|
444
452
|
$selectors: ();
|
|
453
|
+
$block-items: selector.parse($block);
|
|
454
|
+
$alias-items: ();
|
|
455
|
+
|
|
456
|
+
// `$block` and `$alias` are built side by side by the caller,
|
|
457
|
+
// one entry per selector of the parent, so they are walked by
|
|
458
|
+
// index: the alias belongs to the block item it was nested
|
|
459
|
+
// under. Suffixing the list as a whole would reach its last
|
|
460
|
+
// entry alone and leave the ones before it in the rule bare.
|
|
461
|
+
@if $alias {
|
|
462
|
+
$alias-items: selector.parse($alias);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
$i: 0;
|
|
466
|
+
|
|
467
|
+
@each $block-item in $block-items {
|
|
468
|
+
$i: $i + 1;
|
|
469
|
+
$alias-item: null;
|
|
470
|
+
|
|
471
|
+
@if $i <= list.length($alias-items) {
|
|
472
|
+
$alias-item: list.nth($alias-items, $i);
|
|
473
|
+
}
|
|
445
474
|
|
|
446
|
-
@each $block-item in selector.parse($block) {
|
|
447
475
|
$selectors: list.join(
|
|
448
476
|
$selectors,
|
|
449
477
|
('#{$modifier}#{$block-item}--#{$state}', '#{$modifier}#{$block-item}.#{$state}')
|
|
450
478
|
);
|
|
451
479
|
|
|
452
|
-
@if $alias {
|
|
453
|
-
$selectors: list.join($selectors, '#{$modifier}#{$alias}.#{$state}');
|
|
480
|
+
@if $alias-item {
|
|
481
|
+
$selectors: list.join($selectors, '#{$modifier}#{$alias-item}.#{$state}');
|
|
454
482
|
}
|
|
455
483
|
|
|
456
484
|
// Special state handling - use function to get updated selectors
|
|
@@ -458,7 +486,7 @@ $-state-suffixes: (
|
|
|
458
486
|
$state: $state,
|
|
459
487
|
$block-item: $block-item,
|
|
460
488
|
$modifier: $modifier,
|
|
461
|
-
$alias: $alias,
|
|
489
|
+
$alias: $alias-item,
|
|
462
490
|
$selectors: $selectors
|
|
463
491
|
);
|
|
464
492
|
}
|
|
@@ -558,6 +586,27 @@ $-state-suffixes: (
|
|
|
558
586
|
$block: &;
|
|
559
587
|
}
|
|
560
588
|
|
|
589
|
+
// A state and a transition hand their whole selector list down as the
|
|
590
|
+
// modifier, so the block is compounded onto each of its entries: written
|
|
591
|
+
// as one interpolation it would reach the last entry alone and leave the
|
|
592
|
+
// ones before it in the rule unscoped.
|
|
593
|
+
$selector: '#{$modifier}#{$block}';
|
|
594
|
+
|
|
595
|
+
@if $modifier and $modifier != '' and $block {
|
|
596
|
+
$selectors: ();
|
|
597
|
+
|
|
598
|
+
@each $modifier-item in selector.parse($modifier) {
|
|
599
|
+
@each $block-item in selector.parse($block) {
|
|
600
|
+
$selectors: list.join(
|
|
601
|
+
$selectors,
|
|
602
|
+
'#{$modifier-item}#{$block-item}'
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
$selector: list-to-string($selectors);
|
|
608
|
+
}
|
|
609
|
+
|
|
561
610
|
@if meta.type-of(map.get($map, $key)) == 'map' {
|
|
562
611
|
@each $breakpoint, $value in map.get($map, $key) {
|
|
563
612
|
@if string.index($breakpoint, '-') {
|
|
@@ -566,7 +615,7 @@ $-state-suffixes: (
|
|
|
566
615
|
|
|
567
616
|
@if map.has-key($bps, $bp) {
|
|
568
617
|
@if $operator == 'up' {
|
|
569
|
-
@include wrap-with-where($selector:
|
|
618
|
+
@include wrap-with-where($selector: $selector, $enabled: $zero-specificity) {
|
|
570
619
|
@include media-breakpoint-up($bp, $bps) {
|
|
571
620
|
@include spread-map-into-attrs(
|
|
572
621
|
$original: $original,
|
|
@@ -581,7 +630,7 @@ $-state-suffixes: (
|
|
|
581
630
|
}
|
|
582
631
|
|
|
583
632
|
@if $operator == 'down' {
|
|
584
|
-
@include wrap-with-where($selector:
|
|
633
|
+
@include wrap-with-where($selector: $selector, $enabled: $zero-specificity) {
|
|
585
634
|
@include media-breakpoint-down($bp, $bps) {
|
|
586
635
|
@include spread-map-into-attrs(
|
|
587
636
|
$original: $original,
|
|
@@ -596,7 +645,7 @@ $-state-suffixes: (
|
|
|
596
645
|
}
|
|
597
646
|
|
|
598
647
|
@if map.has-key($bps, $operator) {
|
|
599
|
-
@include wrap-with-where($selector:
|
|
648
|
+
@include wrap-with-where($selector: $selector, $enabled: $zero-specificity) {
|
|
600
649
|
@include media-breakpoint-between($operator, $bp, $bps) {
|
|
601
650
|
@include spread-map-into-attrs(
|
|
602
651
|
$original: $original,
|
|
@@ -611,7 +660,7 @@ $-state-suffixes: (
|
|
|
611
660
|
}
|
|
612
661
|
}
|
|
613
662
|
} @else if map.has-key($bps, $breakpoint) {
|
|
614
|
-
@include wrap-with-where($selector:
|
|
663
|
+
@include wrap-with-where($selector: $selector, $enabled: $zero-specificity) {
|
|
615
664
|
@include media-breakpoint-up($breakpoint, $bps) {
|
|
616
665
|
@include spread-map-into-attrs(
|
|
617
666
|
$original: $original,
|
|
@@ -765,6 +814,11 @@ $-state-suffixes: (
|
|
|
765
814
|
);
|
|
766
815
|
$alias: map.get($map, 'element', $element, '_alias');
|
|
767
816
|
|
|
817
|
+
// The alias is a second selector for the same element, not a
|
|
818
|
+
// descendant of the first, so the list is glued with a comma
|
|
819
|
+
// before it is emitted: interpolating it would join the two
|
|
820
|
+
// with a space and compile them to one selector that matches
|
|
821
|
+
// a `.vv-input-text` nested inside its own element.
|
|
768
822
|
@if $alias {
|
|
769
823
|
$element-selector: list.append(
|
|
770
824
|
$element-selector,
|
|
@@ -773,7 +827,7 @@ $-state-suffixes: (
|
|
|
773
827
|
}
|
|
774
828
|
|
|
775
829
|
@include wrap-with-where(
|
|
776
|
-
$selector: $element-selector,
|
|
830
|
+
$selector: list-to-string($element-selector),
|
|
777
831
|
$enabled: $zero-specificity
|
|
778
832
|
) {
|
|
779
833
|
@extend %#{$block}-state-#{$state}__#{$element} !optional;
|
|
@@ -794,7 +848,7 @@ $-state-suffixes: (
|
|
|
794
848
|
}
|
|
795
849
|
|
|
796
850
|
@include wrap-with-where(
|
|
797
|
-
$selector: $element-selector-state,
|
|
851
|
+
$selector: list-to-string($element-selector-state),
|
|
798
852
|
$enabled: $zero-specificity
|
|
799
853
|
) {
|
|
800
854
|
@extend %#{$block}-state-#{$state}-element-#{$element}--#{$element-state}
|
|
@@ -816,7 +870,7 @@ $-state-suffixes: (
|
|
|
816
870
|
}
|
|
817
871
|
|
|
818
872
|
@include wrap-with-where(
|
|
819
|
-
$selector: $element-selector-pseudo,
|
|
873
|
+
$selector: list-to-string($element-selector-pseudo),
|
|
820
874
|
$enabled: $zero-specificity
|
|
821
875
|
) {
|
|
822
876
|
@extend %#{$block}-state-#{$state}-element-#{$element}--#{$pseudo}
|
|
@@ -136,4 +136,31 @@
|
|
|
136
136
|
);
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
// Optically aligns an icon with the first line of a wrapping label instead of
|
|
140
|
+
// with the centre of the whole block. `align-self: center` centres the icon on
|
|
141
|
+
// the flex line, which is the whole block once the label wraps, and
|
|
142
|
+
// `align-self: flex-start` drops the half leading of the first line. The offset
|
|
143
|
+
// is half the difference between the line box and the icon, so it holds at any
|
|
144
|
+
// font size and any icon size. The offset itself is never zero: on a label that
|
|
145
|
+
// does not wrap it puts the icon exactly where `align-self: center` would, since
|
|
146
|
+
// the first line is then the whole block, which is why the class is safe to
|
|
147
|
+
// apply unconditionally and needs no breakpoint variant.
|
|
148
|
+
// https://ishadeed.com/article/aligning-list-icons/
|
|
149
|
+
// `--icon-size` is the rendered size of the icon and defaults to the `1em` an
|
|
150
|
+
// inline SVG carries. `transform` and not `translate`, because components of
|
|
151
|
+
// the library move their own elements with `translate` and the two would
|
|
152
|
+
// overwrite each other.
|
|
153
|
+
%self-first-line {
|
|
154
|
+
flex-shrink: 0;
|
|
155
|
+
align-self: flex-start;
|
|
156
|
+
transform: translateY(calc((1lh - var(--icon-size, 1em)) / 2));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@include wrap-with-where(
|
|
160
|
+
$selector: '.self-first-line',
|
|
161
|
+
$enabled: $zero-specificity-for-utilities
|
|
162
|
+
) {
|
|
163
|
+
@extend %self-first-line;
|
|
164
|
+
}
|
|
165
|
+
|
|
139
166
|
}
|