@thalassic/themes 22.11.0 → 22.12.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/package.json +1 -1
- package/themes/thalassic/components/index.scss +1 -0
- package/themes/thalassic/components/tab-header/_index.scss +3 -0
- package/themes/thalassic/components/tab-header/_tab-header-orientation.scss +60 -0
- package/themes/thalassic/components/tab-header/_tab-header-variant.scss +118 -0
- package/themes/thalassic/components/tab-header/_tab-header.scss +89 -0
- package/themes/thalassic/components/tabs/_tabs-header-position.scss +22 -19
- package/themes/thalassic/components/tabs/_tabs-orientation.scss +2 -66
- package/themes/thalassic/components/tabs/_tabs-variant.scss +4 -115
- package/themes/thalassic/components/tabs/_tabs.scss +7 -74
package/package.json
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
.tls-tab-header {
|
|
2
|
+
// Horizontal
|
|
3
|
+
&.tls-tab-header--horizontal {
|
|
4
|
+
overflow-x: auto;
|
|
5
|
+
overflow-y: hidden;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Vertical
|
|
9
|
+
&.tls-tab-header--vertical {
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
|
|
12
|
+
overflow-x: hidden;
|
|
13
|
+
overflow-y: auto;
|
|
14
|
+
|
|
15
|
+
// Flat
|
|
16
|
+
&.tls-tab-header--flat {
|
|
17
|
+
border-bottom-width: 0;
|
|
18
|
+
border-inline-end-width: var(--tls-tab-header-border-width);
|
|
19
|
+
border-inline-end-style: solid;
|
|
20
|
+
|
|
21
|
+
.tls-tab-header__item {
|
|
22
|
+
margin-bottom: 0;
|
|
23
|
+
margin-inline-end: -1px;
|
|
24
|
+
|
|
25
|
+
border-bottom-width: 0;
|
|
26
|
+
border-inline-end-width: var(--tls-tab-header-active-border-width);
|
|
27
|
+
border-inline-end-style: solid;
|
|
28
|
+
|
|
29
|
+
// See the flat variant's own hover rule for why this is needed:
|
|
30
|
+
// it keeps the divider line visible under the hover fill.
|
|
31
|
+
&:hover:not(.tls-tab-header__item--active) {
|
|
32
|
+
border-inline-end-color: var(--tls-tab-header-border-color);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Outlined
|
|
38
|
+
&.tls-tab-header--outlined {
|
|
39
|
+
border-bottom-width: 0;
|
|
40
|
+
border-inline-end-width: var(--tls-tab-header-border-width);
|
|
41
|
+
border-inline-end-style: solid;
|
|
42
|
+
|
|
43
|
+
.tls-tab-header__item {
|
|
44
|
+
margin-bottom: 0;
|
|
45
|
+
margin-inline-end: -1px;
|
|
46
|
+
|
|
47
|
+
border-inline-start-width: 0;
|
|
48
|
+
border-inline-end-width: 0;
|
|
49
|
+
border-block-start-width: var(--tls-tab-header-active-border-width);
|
|
50
|
+
border-block-end-width: var(--tls-tab-header-active-border-width);
|
|
51
|
+
border-style: solid;
|
|
52
|
+
|
|
53
|
+
&:first-child {
|
|
54
|
+
border-inline-start-width: 0;
|
|
55
|
+
border-block-start-width: 0;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
@use '../../functions' as functions;
|
|
2
|
+
|
|
3
|
+
.tls-tab-header {
|
|
4
|
+
// Flat
|
|
5
|
+
&.tls-tab-header--flat {
|
|
6
|
+
--tls-tab-header-active-background-color: #{functions.tint(var(--color-primary), 8%)};
|
|
7
|
+
--tls-tab-header-active-hover-background-color: #{functions.tint(var(--color-primary), 12%)};
|
|
8
|
+
|
|
9
|
+
border-bottom-width: var(--tls-tab-header-border-width);
|
|
10
|
+
border-bottom-style: solid;
|
|
11
|
+
|
|
12
|
+
.tls-tab-header__item {
|
|
13
|
+
margin-bottom: -1px;
|
|
14
|
+
|
|
15
|
+
// Border is always reserved at the active width and toggles only
|
|
16
|
+
// border-color (transparent to active) so switching tabs never
|
|
17
|
+
// changes the item's box height and shifts the label.
|
|
18
|
+
border-bottom-width: var(--tls-tab-header-active-border-width);
|
|
19
|
+
border-bottom-style: solid;
|
|
20
|
+
|
|
21
|
+
&.tls-tab-header__item--active {
|
|
22
|
+
background-color: var(--tls-tab-header-active-background-color);
|
|
23
|
+
|
|
24
|
+
&:hover {
|
|
25
|
+
background-color: var(--tls-tab-header-active-hover-background-color);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Hover fill sits on the item, not the control, so it paints under
|
|
30
|
+
// the item's border and reaches the divider line instead of
|
|
31
|
+
// stopping short and leaving a gap. Excludes the active item so
|
|
32
|
+
// its primary tint is not replaced by the neutral hover fill.
|
|
33
|
+
//
|
|
34
|
+
// The item's border overlaps the strip's divider line by
|
|
35
|
+
// `--tls-tab-header-border-width` (see `margin-bottom: -1px` above).
|
|
36
|
+
// Made opaque only while hovering, it paints over the hover
|
|
37
|
+
// fill and keeps that shared pixel visible instead of the
|
|
38
|
+
// fill covering it. The active item already has an opaque
|
|
39
|
+
// border, so it needs neither of these.
|
|
40
|
+
&:hover:not(.tls-tab-header__item--active) {
|
|
41
|
+
background-color: var(--color-surface-container);
|
|
42
|
+
border-bottom-color: var(--tls-tab-header-border-color);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Outlined
|
|
48
|
+
&.tls-tab-header--outlined {
|
|
49
|
+
--tls-tab-header-background-color: var(--color-surface-container);
|
|
50
|
+
--tls-tab-header-active-background-color: var(--color-surface);
|
|
51
|
+
--tls-tab-header-active-border-width: 1px;
|
|
52
|
+
--tls-tab-header-active-border-color: var(--tls-tab-header-border-color);
|
|
53
|
+
|
|
54
|
+
border-bottom-width: var(--tls-tab-header-border-width);
|
|
55
|
+
border-bottom-style: solid;
|
|
56
|
+
|
|
57
|
+
background-color: var(--tls-tab-header-background-color);
|
|
58
|
+
|
|
59
|
+
.tls-tab-header__item {
|
|
60
|
+
margin-bottom: -1px;
|
|
61
|
+
|
|
62
|
+
border-width: 0;
|
|
63
|
+
border-inline-start-width: var(--tls-tab-header-active-border-width);
|
|
64
|
+
border-inline-end-width: var(--tls-tab-header-active-border-width);
|
|
65
|
+
border-style: solid;
|
|
66
|
+
|
|
67
|
+
&:hover {
|
|
68
|
+
color: var(--tls-tab-header-active-label-color);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&:first-child {
|
|
72
|
+
border-inline-start-width: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&.tls-tab-header__item--active {
|
|
76
|
+
background-color: var(--tls-tab-header-active-background-color);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Segmented
|
|
82
|
+
&.tls-tab-header--segmented {
|
|
83
|
+
--tls-tab-header-border-radius: var(--radius-lg);
|
|
84
|
+
--tls-tab-header-pill-radius: var(--radius-md);
|
|
85
|
+
--tls-tab-header-background-color: var(--color-surface-container);
|
|
86
|
+
--tls-tab-header-pill-background-color: var(--color-surface);
|
|
87
|
+
--tls-tab-header-padding: var(--spacing-2);
|
|
88
|
+
--tls-tab-header-active-label-color: var(--color-on-surface);
|
|
89
|
+
|
|
90
|
+
padding: var(--tls-tab-header-padding);
|
|
91
|
+
gap: var(--tls-tab-header-padding);
|
|
92
|
+
|
|
93
|
+
border-radius: var(--tls-tab-header-border-radius);
|
|
94
|
+
|
|
95
|
+
background-color: var(--tls-tab-header-background-color);
|
|
96
|
+
|
|
97
|
+
.tls-tab-header__item {
|
|
98
|
+
border: none;
|
|
99
|
+
border-radius: var(--tls-tab-header-pill-radius);
|
|
100
|
+
|
|
101
|
+
&:hover:not(.tls-tab-header__item--active) {
|
|
102
|
+
background-color: var(--color-surface-container-high);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
&.tls-tab-header__item--active {
|
|
106
|
+
background-color: var(--tls-tab-header-pill-background-color);
|
|
107
|
+
box-shadow: var(--shadow-xs);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Both shapes of the interactive element: a child control (the
|
|
111
|
+
// button inside `tls-tabs`) or the item itself (the nav anchor).
|
|
112
|
+
&.tls-tab-header__item-control,
|
|
113
|
+
.tls-tab-header__item-control {
|
|
114
|
+
padding: var(--spacing-2) var(--spacing-5);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// Shared tab-strip visuals used by two components: the header row inside
|
|
2
|
+
// `tls-tabs` (buttons driving tabpanels) and the standalone `tls-tab-nav`
|
|
3
|
+
// (router links styled as tabs). The block carries its own variant /
|
|
4
|
+
// orientation modifiers so it renders identically in both hosts.
|
|
5
|
+
//
|
|
6
|
+
// Structure: the block is the strip, `__item` is one tab slot (an `<li>` in
|
|
7
|
+
// `tls-tabs`, the anchor itself in `tls-tab-nav`) and `__item-control` is the
|
|
8
|
+
// interactive element (the `<button>`, or again the anchor — an element may
|
|
9
|
+
// carry both classes when it plays both roles).
|
|
10
|
+
.tls-tab-header {
|
|
11
|
+
--tls-tab-header-label-color: var(--color-outline);
|
|
12
|
+
--tls-tab-header-active-label-color: var(--color-primary);
|
|
13
|
+
--tls-tab-header-border-color: var(--color-outline-variant);
|
|
14
|
+
--tls-tab-header-border-width: 1px;
|
|
15
|
+
--tls-tab-header-active-border-color: var(--color-primary);
|
|
16
|
+
--tls-tab-header-active-border-width: 2px;
|
|
17
|
+
--tls-tab-header-disabled-opacity: 0.38;
|
|
18
|
+
|
|
19
|
+
flex-shrink: 0;
|
|
20
|
+
display: flex;
|
|
21
|
+
|
|
22
|
+
border-color: var(--tls-tab-header-border-color);
|
|
23
|
+
|
|
24
|
+
// Tabs that exceed the strip's extent scroll instead of shrinking
|
|
25
|
+
// (e.g. a horizontal strip on a narrow viewport). The scrollbar is
|
|
26
|
+
// hidden so it never covers the active-tab indicator line, while
|
|
27
|
+
// wheel/touch/keyboard scrolling stays available.
|
|
28
|
+
scrollbar-width: none;
|
|
29
|
+
|
|
30
|
+
&::-webkit-scrollbar {
|
|
31
|
+
display: none;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&__item {
|
|
35
|
+
flex-shrink: 0;
|
|
36
|
+
|
|
37
|
+
display: flex;
|
|
38
|
+
|
|
39
|
+
border-color: transparent;
|
|
40
|
+
|
|
41
|
+
color: var(--tls-tab-header-label-color);
|
|
42
|
+
|
|
43
|
+
transition: color var(--motion-fast),
|
|
44
|
+
border-color var(--motion-fast),
|
|
45
|
+
background-color var(--motion-theme);
|
|
46
|
+
|
|
47
|
+
// The control fills its item only when it is a separate child element
|
|
48
|
+
// (the button inside `tls-tabs`); a nav anchor is the item itself and
|
|
49
|
+
// is sized by its own content.
|
|
50
|
+
> .tls-tab-header__item-control {
|
|
51
|
+
width: 100%;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&.tls-tab-header__item--active {
|
|
55
|
+
color: var(--tls-tab-header-active-label-color);
|
|
56
|
+
border-color: var(--tls-tab-header-active-border-color);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
&.tls-tab-header__item--disabled {
|
|
60
|
+
opacity: var(--tls-tab-header-disabled-opacity);
|
|
61
|
+
|
|
62
|
+
&,
|
|
63
|
+
.tls-tab-header__item-control {
|
|
64
|
+
cursor: not-allowed;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&-control {
|
|
69
|
+
padding: var(--spacing-3) var(--spacing-6);
|
|
70
|
+
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
justify-content: center;
|
|
74
|
+
gap: var(--spacing-2);
|
|
75
|
+
|
|
76
|
+
// TODO: use mixin
|
|
77
|
+
font-size: var(--font-label-large-size);
|
|
78
|
+
font-weight: var(--font-label-large-weight);
|
|
79
|
+
line-height: var(--font-label-large-line-height);
|
|
80
|
+
letter-spacing: var(--font-label-large-letter-spacing);
|
|
81
|
+
text-decoration: none;
|
|
82
|
+
color: inherit;
|
|
83
|
+
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
|
|
86
|
+
transition: background-color var(--motion-fast);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
// Header-position styles are a tabs-composite concern (the header's order and
|
|
2
|
+
// divider edge relative to the content panel), so they stay here and reach
|
|
3
|
+
// into the shared tab-header block from the container.
|
|
1
4
|
.tls-tabs {
|
|
2
5
|
&.tls-tabs--header-end {
|
|
3
|
-
.tls-
|
|
6
|
+
.tls-tab-header {
|
|
4
7
|
order: 1;
|
|
5
8
|
}
|
|
6
9
|
|
|
@@ -12,33 +15,33 @@
|
|
|
12
15
|
// Horizontal: divider faces the content, so it moves from the header's
|
|
13
16
|
// bottom edge to its top edge once the header trails the content.
|
|
14
17
|
&.tls-tabs--horizontal.tls-tabs--header-end {
|
|
15
|
-
|
|
18
|
+
.tls-tab-header--flat {
|
|
16
19
|
border-bottom-width: 0;
|
|
17
|
-
border-top-width: var(--tls-
|
|
20
|
+
border-top-width: var(--tls-tab-header-border-width);
|
|
18
21
|
border-top-style: solid;
|
|
19
22
|
|
|
20
|
-
|
|
23
|
+
.tls-tab-header__item {
|
|
21
24
|
margin-bottom: 0;
|
|
22
25
|
margin-top: -1px;
|
|
23
26
|
|
|
24
27
|
border-bottom-width: 0;
|
|
25
|
-
border-top-width: var(--tls-
|
|
28
|
+
border-top-width: var(--tls-tab-header-active-border-width);
|
|
26
29
|
border-top-style: solid;
|
|
27
30
|
|
|
28
31
|
// See the flat variant's own hover rule for why this is needed:
|
|
29
32
|
// it keeps the divider line visible under the hover fill.
|
|
30
|
-
&:hover:not(.tls-
|
|
31
|
-
border-top-color: var(--tls-
|
|
33
|
+
&:hover:not(.tls-tab-header__item--active) {
|
|
34
|
+
border-top-color: var(--tls-tab-header-border-color);
|
|
32
35
|
}
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
|
|
39
|
+
.tls-tab-header--outlined {
|
|
37
40
|
border-bottom-width: 0;
|
|
38
|
-
border-top-width: var(--tls-
|
|
41
|
+
border-top-width: var(--tls-tab-header-border-width);
|
|
39
42
|
border-top-style: solid;
|
|
40
43
|
|
|
41
|
-
|
|
44
|
+
.tls-tab-header__item {
|
|
42
45
|
margin-bottom: 0;
|
|
43
46
|
margin-top: -1px;
|
|
44
47
|
}
|
|
@@ -48,33 +51,33 @@
|
|
|
48
51
|
// Vertical: divider faces the content, so it moves from the header's
|
|
49
52
|
// inline-end edge to its inline-start edge once the header trails the content.
|
|
50
53
|
&.tls-tabs--vertical.tls-tabs--header-end {
|
|
51
|
-
|
|
54
|
+
.tls-tab-header--flat {
|
|
52
55
|
border-inline-end-width: 0;
|
|
53
|
-
border-inline-start-width: var(--tls-
|
|
56
|
+
border-inline-start-width: var(--tls-tab-header-border-width);
|
|
54
57
|
border-inline-start-style: solid;
|
|
55
58
|
|
|
56
|
-
|
|
59
|
+
.tls-tab-header__item {
|
|
57
60
|
margin-inline-end: 0;
|
|
58
61
|
margin-inline-start: -1px;
|
|
59
62
|
|
|
60
63
|
border-inline-end-width: 0;
|
|
61
|
-
border-inline-start-width: var(--tls-
|
|
64
|
+
border-inline-start-width: var(--tls-tab-header-active-border-width);
|
|
62
65
|
border-inline-start-style: solid;
|
|
63
66
|
|
|
64
67
|
// See the flat variant's own hover rule for why this is needed:
|
|
65
68
|
// it keeps the divider line visible under the hover fill.
|
|
66
|
-
&:hover:not(.tls-
|
|
67
|
-
border-inline-start-color: var(--tls-
|
|
69
|
+
&:hover:not(.tls-tab-header__item--active) {
|
|
70
|
+
border-inline-start-color: var(--tls-tab-header-border-color);
|
|
68
71
|
}
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
74
|
|
|
72
|
-
|
|
75
|
+
.tls-tab-header--outlined {
|
|
73
76
|
border-inline-end-width: 0;
|
|
74
|
-
border-inline-start-width: var(--tls-
|
|
77
|
+
border-inline-start-width: var(--tls-tab-header-border-width);
|
|
75
78
|
border-inline-start-style: solid;
|
|
76
79
|
|
|
77
|
-
|
|
80
|
+
.tls-tab-header__item {
|
|
78
81
|
margin-inline-end: 0;
|
|
79
82
|
margin-inline-start: -1px;
|
|
80
83
|
}
|
|
@@ -1,77 +1,13 @@
|
|
|
1
|
+
// Orientation styles that concern the tabs container itself; the header
|
|
2
|
+
// strip's orientation styles live in the shared tab-header block.
|
|
1
3
|
.tls-tabs {
|
|
2
|
-
// Horizontal
|
|
3
|
-
&.tls-tabs--horizontal {
|
|
4
|
-
.tls-tabs-header {
|
|
5
|
-
overflow-x: auto;
|
|
6
|
-
overflow-y: hidden;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
4
|
// Vertical
|
|
11
5
|
&.tls-tabs--vertical {
|
|
12
6
|
display: flex;
|
|
13
7
|
flex-direction: row;
|
|
14
8
|
|
|
15
|
-
.tls-tabs-header {
|
|
16
|
-
flex-direction: column;
|
|
17
|
-
|
|
18
|
-
overflow-x: hidden;
|
|
19
|
-
overflow-y: auto;
|
|
20
|
-
|
|
21
|
-
border-color: var(--tls-tabs-border-color);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
9
|
.tls-tabs-content {
|
|
25
10
|
flex-grow: 1;
|
|
26
11
|
}
|
|
27
|
-
|
|
28
|
-
// Flat
|
|
29
|
-
&.tls-tabs--flat {
|
|
30
|
-
.tls-tabs-header {
|
|
31
|
-
border-bottom-width: 0;
|
|
32
|
-
border-inline-end-width: var(--tls-tabs-border-width);
|
|
33
|
-
border-inline-end-style: solid;
|
|
34
|
-
|
|
35
|
-
&__item {
|
|
36
|
-
margin-bottom: 0;
|
|
37
|
-
margin-inline-end: -1px;
|
|
38
|
-
|
|
39
|
-
border-bottom-width: 0;
|
|
40
|
-
border-inline-end-width: var(--tls-tabs-active-border-width);
|
|
41
|
-
border-inline-end-style: solid;
|
|
42
|
-
|
|
43
|
-
// See the flat variant's own hover rule for why this is needed:
|
|
44
|
-
// it keeps the divider line visible under the hover fill.
|
|
45
|
-
&:hover:not(.tls-tabs-header__item--active) {
|
|
46
|
-
border-inline-end-color: var(--tls-tabs-border-color);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Outlined
|
|
53
|
-
&.tls-tabs--outlined {
|
|
54
|
-
.tls-tabs-header {
|
|
55
|
-
border-bottom-width: 0;
|
|
56
|
-
border-inline-end-width: var(--tls-tabs-border-width);
|
|
57
|
-
border-inline-end-style: solid;
|
|
58
|
-
|
|
59
|
-
&__item {
|
|
60
|
-
margin-bottom: 0;
|
|
61
|
-
margin-inline-end: -1px;
|
|
62
|
-
|
|
63
|
-
border-inline-start-width: 0;
|
|
64
|
-
border-inline-end-width: 0;
|
|
65
|
-
border-block-start-width: var(--tls-tabs-active-border-width);
|
|
66
|
-
border-block-end-width: var(--tls-tabs-active-border-width);
|
|
67
|
-
border-style: solid;
|
|
68
|
-
|
|
69
|
-
&:first-child {
|
|
70
|
-
border-inline-start-width: 0;
|
|
71
|
-
border-block-start-width: 0;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
12
|
}
|
|
77
13
|
}
|
|
@@ -1,124 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// Variant styles that concern the tabs container itself; the header strip's
|
|
2
|
+
// variant styles live in the shared tab-header block.
|
|
3
3
|
.tls-tabs {
|
|
4
|
-
// Flat
|
|
5
|
-
&.tls-tabs--flat {
|
|
6
|
-
--tls-tabs-active-background-color: #{functions.tint(var(--color-primary), 8%)};
|
|
7
|
-
--tls-tabs-active-hover-background-color: #{functions.tint(var(--color-primary), 12%)};
|
|
8
|
-
|
|
9
|
-
.tls-tabs-header {
|
|
10
|
-
border-bottom-width: var(--tls-tabs-border-width);
|
|
11
|
-
border-bottom-style: solid;
|
|
12
|
-
|
|
13
|
-
&__item {
|
|
14
|
-
margin-bottom: -1px;
|
|
15
|
-
|
|
16
|
-
// Border is always reserved at the active width and toggles only
|
|
17
|
-
// border-color (transparent to active) so switching tabs never
|
|
18
|
-
// changes the item's box height and shifts the label.
|
|
19
|
-
border-bottom-width: var(--tls-tabs-active-border-width);
|
|
20
|
-
border-bottom-style: solid;
|
|
21
|
-
|
|
22
|
-
&.tls-tabs-header__item--active {
|
|
23
|
-
background-color: var(--tls-tabs-active-background-color);
|
|
24
|
-
|
|
25
|
-
&:hover {
|
|
26
|
-
background-color: var(--tls-tabs-active-hover-background-color);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Hover fill sits on the item, not the button, so it paints under
|
|
31
|
-
// the item's border and reaches the divider line instead of
|
|
32
|
-
// stopping short and leaving a gap. Excludes the active item so
|
|
33
|
-
// its primary tint is not replaced by the neutral hover fill.
|
|
34
|
-
//
|
|
35
|
-
// The item's border overlaps the header's divider line by
|
|
36
|
-
// `--tls-tabs-border-width` (see `margin-bottom: -1px` above).
|
|
37
|
-
// Made opaque only while hovering, it paints over the hover
|
|
38
|
-
// fill and keeps that shared pixel visible instead of the
|
|
39
|
-
// fill covering it. The active item already has an opaque
|
|
40
|
-
// border, so it needs neither of these.
|
|
41
|
-
&:hover:not(.tls-tabs-header__item--active) {
|
|
42
|
-
background-color: var(--color-surface-container);
|
|
43
|
-
border-bottom-color: var(--tls-tabs-border-color);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
4
|
// Outlined
|
|
50
5
|
&.tls-tabs--outlined {
|
|
6
|
+
--tls-tabs-border-color: var(--color-outline-variant);
|
|
7
|
+
--tls-tabs-border-width: 1px;
|
|
51
8
|
--tls-tabs-border-radius: var(--radius-sm);
|
|
52
|
-
--tls-tabs-header-background-color: var(--color-surface-container);
|
|
53
|
-
--tls-tabs-active-border-width: 1px;
|
|
54
|
-
--tls-tabs-active-border-color: var(--tls-tabs-border-color);
|
|
55
9
|
|
|
56
10
|
border: var(--tls-tabs-border-width) solid var(--tls-tabs-border-color);
|
|
57
11
|
border-radius: var(--tls-tabs-border-radius);
|
|
58
|
-
|
|
59
|
-
.tls-tabs-header {
|
|
60
|
-
border-bottom-width: var(--tls-tabs-border-width);
|
|
61
|
-
border-bottom-style: solid;
|
|
62
|
-
|
|
63
|
-
background-color: var(--tls-tabs-header-background-color);
|
|
64
|
-
|
|
65
|
-
&__item {
|
|
66
|
-
margin-bottom: -1px;
|
|
67
|
-
|
|
68
|
-
border-width: 0;
|
|
69
|
-
border-inline-start-width: var(--tls-tabs-active-border-width);
|
|
70
|
-
border-inline-end-width: var(--tls-tabs-active-border-width);
|
|
71
|
-
border-style: solid;
|
|
72
|
-
|
|
73
|
-
&:hover {
|
|
74
|
-
color: var(--tls-tabs-active-label-color);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
&:first-child {
|
|
78
|
-
border-inline-start-width: 0;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
&.tls-tabs-header__item--active {
|
|
82
|
-
background-color: var(--tls-tabs-background-color);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Segmented
|
|
89
|
-
&.tls-tabs--segmented {
|
|
90
|
-
--tls-tabs-border-radius: var(--radius-lg);
|
|
91
|
-
--tls-tabs-pill-radius: var(--radius-md);
|
|
92
|
-
--tls-tabs-header-background-color: var(--color-surface-container);
|
|
93
|
-
--tls-tabs-pill-background-color: var(--color-surface);
|
|
94
|
-
--tls-tabs-header-padding: var(--spacing-2);
|
|
95
|
-
--tls-tabs-active-label-color: var(--color-on-surface);
|
|
96
|
-
|
|
97
|
-
.tls-tabs-header {
|
|
98
|
-
padding: var(--tls-tabs-header-padding);
|
|
99
|
-
gap: var(--tls-tabs-header-padding);
|
|
100
|
-
|
|
101
|
-
border-radius: var(--tls-tabs-border-radius);
|
|
102
|
-
|
|
103
|
-
background-color: var(--tls-tabs-header-background-color);
|
|
104
|
-
|
|
105
|
-
&__item {
|
|
106
|
-
border: none;
|
|
107
|
-
border-radius: var(--tls-tabs-pill-radius);
|
|
108
|
-
|
|
109
|
-
&:hover:not(.tls-tabs-header__item--active) {
|
|
110
|
-
background-color: var(--color-surface-container-high);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
&.tls-tabs-header__item--active {
|
|
114
|
-
background-color: var(--tls-tabs-pill-background-color);
|
|
115
|
-
box-shadow: var(--shadow-xs);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
&-button {
|
|
119
|
-
padding: var(--spacing-2) var(--spacing-5);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
12
|
}
|
|
124
13
|
}
|
|
@@ -1,87 +1,20 @@
|
|
|
1
|
+
// Container-level styles for `tls-tabs` (background, layout, content panel).
|
|
2
|
+
// The header strip itself is the shared `.tls-tab-header` block
|
|
3
|
+
// (components/tab-header), which `tls-tabs` renders as its tablist and
|
|
4
|
+
// `tls-tab-nav` renders as router links.
|
|
1
5
|
.tls-tabs {
|
|
2
6
|
--tls-tabs-background-color: var(--color-surface);
|
|
3
|
-
--tls-tabs-label-color: var(--color-outline);
|
|
4
|
-
--tls-tabs-active-label-color: var(--color-primary);
|
|
5
|
-
--tls-tabs-border-color: var(--color-outline-variant);
|
|
6
|
-
--tls-tabs-border-width: 1px;
|
|
7
|
-
--tls-tabs-active-border-color: var(--color-primary);
|
|
8
|
-
--tls-tabs-active-border-width: 2px;
|
|
9
|
-
--tls-tabs-disabled-opacity: 0.38;
|
|
10
7
|
--tls-tabs-content-padding: var(--spacing-4);
|
|
11
8
|
|
|
12
|
-
background: var(--tls-tabs-background-color);
|
|
13
|
-
|
|
14
9
|
display: flex;
|
|
15
10
|
flex-direction: column;
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
background-color var(--motion-theme);
|
|
12
|
+
background: var(--tls-tabs-background-color);
|
|
19
13
|
|
|
20
14
|
overflow: clip;
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
display: flex;
|
|
25
|
-
|
|
26
|
-
border-color: var(--tls-tabs-border-color);
|
|
27
|
-
|
|
28
|
-
// Tabs that exceed the header's extent scroll instead of shrinking
|
|
29
|
-
// (e.g. a horizontal strip on a narrow viewport). The scrollbar is
|
|
30
|
-
// hidden so it never covers the active-tab indicator line, while
|
|
31
|
-
// wheel/touch/keyboard scrolling stays available.
|
|
32
|
-
scrollbar-width: none;
|
|
33
|
-
|
|
34
|
-
&::-webkit-scrollbar {
|
|
35
|
-
display: none;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
&__item {
|
|
39
|
-
flex-shrink: 0;
|
|
40
|
-
|
|
41
|
-
display: flex;
|
|
42
|
-
|
|
43
|
-
color: var(--tls-tabs-label-color);
|
|
44
|
-
|
|
45
|
-
border-color: transparent;
|
|
46
|
-
|
|
47
|
-
transition: color var(--motion-fast),
|
|
48
|
-
border-color var(--motion-fast),
|
|
49
|
-
background-color var(--motion-theme);
|
|
50
|
-
|
|
51
|
-
&:has(&-link:hover, &-link:focus) {
|
|
52
|
-
background-color: var(--color-grey-95);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
&.tls-tabs-header__item--active {
|
|
56
|
-
color: var(--tls-tabs-active-label-color);
|
|
57
|
-
border-color: var(--tls-tabs-active-border-color);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
&.tls-tabs-header__item--disabled {
|
|
61
|
-
opacity: var(--tls-tabs-disabled-opacity);
|
|
62
|
-
|
|
63
|
-
.tls-tabs-header__item-button {
|
|
64
|
-
cursor: not-allowed;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
&-button {
|
|
69
|
-
width: 100%;
|
|
70
|
-
|
|
71
|
-
padding: var(--spacing-3) var(--spacing-6);
|
|
72
|
-
|
|
73
|
-
// TODO: use mixin
|
|
74
|
-
font-size: var(--font-label-large-size);
|
|
75
|
-
font-weight: var(--font-label-large-weight);
|
|
76
|
-
line-height: var(--font-label-large-line-height);
|
|
77
|
-
letter-spacing: var(--font-label-large-letter-spacing);
|
|
78
|
-
|
|
79
|
-
cursor: pointer;
|
|
80
|
-
|
|
81
|
-
transition: background-color var(--motion-fast);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
16
|
+
transition: border-color var(--motion-theme),
|
|
17
|
+
background-color var(--motion-theme);
|
|
85
18
|
|
|
86
19
|
.tls-tabs-content {
|
|
87
20
|
padding: var(--tls-tabs-content-padding);
|