@thalassic/themes 22.12.0 → 22.14.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/_typography.scss +4 -4
- package/themes/thalassic/components/_password.scss +16 -0
- package/themes/thalassic/components/chip/_chip-size.scss +17 -7
- package/themes/thalassic/components/form-control-group/_form-control-addon.scss +3 -0
- package/themes/thalassic/components/form-control-group/_form-control-group-size.scss +17 -0
- package/themes/thalassic/components/form-control-group/_form-control-group.scss +17 -4
- package/themes/thalassic/components/switch/_switch.scss +20 -2
- package/themes/thalassic/components/tab-header/_index.scss +1 -0
- package/themes/thalassic/components/tab-header/_tab-header-divider.scss +85 -0
- package/themes/thalassic/components/tab-header/_tab-header-variant.scss +8 -0
- package/themes/thalassic/mixins/_variant-treatment.scss +12 -4
package/package.json
CHANGED
|
@@ -62,12 +62,12 @@
|
|
|
62
62
|
|
|
63
63
|
--font-title-medium-size: 1.125rem;
|
|
64
64
|
--font-title-medium-weight: var(--font-weight-medium);
|
|
65
|
-
--font-title-medium-line-height: 1.
|
|
65
|
+
--font-title-medium-line-height: 1.4375rem;
|
|
66
66
|
--font-title-medium-letter-spacing: var(--letter-spacing-wide);
|
|
67
67
|
|
|
68
68
|
--font-title-small-size: 1rem;
|
|
69
69
|
--font-title-small-weight: var(--font-weight-medium);
|
|
70
|
-
--font-title-small-line-height: 1.
|
|
70
|
+
--font-title-small-line-height: 1.3125rem;
|
|
71
71
|
--font-title-small-letter-spacing: var(--letter-spacing-wide);
|
|
72
72
|
|
|
73
73
|
// Body styles (main content)
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
// Label styles (buttons, tabs, form labels)
|
|
90
90
|
--font-label-large-size: 1rem;
|
|
91
91
|
--font-label-large-weight: var(--font-weight-medium);
|
|
92
|
-
--font-label-large-line-height: 1.
|
|
92
|
+
--font-label-large-line-height: 1.25rem;
|
|
93
93
|
--font-label-large-letter-spacing: var(--letter-spacing-wide);
|
|
94
94
|
|
|
95
95
|
--font-label-medium-size: 0.875rem;
|
|
@@ -99,6 +99,6 @@
|
|
|
99
99
|
|
|
100
100
|
--font-label-small-size: 0.8125rem;
|
|
101
101
|
--font-label-small-weight: var(--font-weight-medium);
|
|
102
|
-
--font-label-small-line-height:
|
|
102
|
+
--font-label-small-line-height: 1rem;
|
|
103
103
|
--font-label-small-letter-spacing: var(--letter-spacing-wider);
|
|
104
104
|
}
|
|
@@ -1,12 +1,28 @@
|
|
|
1
|
+
@use '../mixins' as mixins;
|
|
2
|
+
|
|
1
3
|
.tls-password {
|
|
2
4
|
// The layout/border now lives on the inner tls-form-control-group; the host is
|
|
3
5
|
// transparent so size/fluid set on the group resolve against the password's parent.
|
|
4
6
|
display: contents;
|
|
5
7
|
|
|
6
8
|
.tls-password-toggle {
|
|
9
|
+
position: relative;
|
|
10
|
+
|
|
11
|
+
align-self: stretch;
|
|
7
12
|
display: grid;
|
|
8
13
|
align-items: center;
|
|
9
14
|
|
|
15
|
+
// Follow the group's resolved size, so an sm/lg field scales the toggle
|
|
16
|
+
// label alongside the input text. Custom properties inherit from the group.
|
|
17
|
+
font-size: var(--tls-form-control-group-font-size);
|
|
18
|
+
font-weight: var(--tls-form-control-group-font-weight);
|
|
19
|
+
line-height: var(--tls-form-control-group-line-height);
|
|
20
|
+
letter-spacing: var(--tls-form-control-group-letter-spacing);
|
|
21
|
+
|
|
22
|
+
// `align-self: stretch` already makes the full field height clickable; this
|
|
23
|
+
// covers the remaining vertical gap to the 44px minimum on touch devices.
|
|
24
|
+
@include mixins.touch-target(var(--tls-form-control-group-height));
|
|
25
|
+
|
|
10
26
|
&__item {
|
|
11
27
|
grid-area: 1 / 1;
|
|
12
28
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
padding-inline: var(--tls-chip-padding-inline);
|
|
4
4
|
|
|
5
5
|
font-size: var(--tls-chip-font-size);
|
|
6
|
-
font-weight: var(--
|
|
6
|
+
font-weight: var(--font-weight-regular);
|
|
7
7
|
line-height: var(--tls-chip-line-height);
|
|
8
8
|
letter-spacing: var(--tls-chip-letter-spacing);
|
|
9
9
|
|
|
@@ -17,12 +17,24 @@
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
&.tls-chip--xs {
|
|
21
|
+
--tls-chip-height: 24px;
|
|
22
|
+
--tls-chip-padding-inline: var(--spacing-2);
|
|
23
|
+
|
|
24
|
+
--tls-chip-font-size: 0.75rem;
|
|
25
|
+
--tls-chip-line-height: 1rem;
|
|
26
|
+
--tls-chip-letter-spacing: var(--letter-spacing-wider);
|
|
27
|
+
|
|
28
|
+
&.tls-chip--rounded {
|
|
29
|
+
--tls-chip-border-radius: var(--radius-lg);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
20
33
|
&.tls-chip--sm {
|
|
21
34
|
--tls-chip-height: var(--control-height-sm);
|
|
22
|
-
--tls-chip-padding-inline: var(--spacing-
|
|
35
|
+
--tls-chip-padding-inline: var(--spacing-3);
|
|
23
36
|
|
|
24
37
|
--tls-chip-font-size: var(--font-label-small-size);
|
|
25
|
-
--tls-chip-font-weight: var(--font-label-small-weight);
|
|
26
38
|
--tls-chip-line-height: var(--font-label-small-line-height);
|
|
27
39
|
--tls-chip-letter-spacing: var(--font-label-small-letter-spacing);
|
|
28
40
|
|
|
@@ -33,10 +45,9 @@
|
|
|
33
45
|
|
|
34
46
|
&.tls-chip--md {
|
|
35
47
|
--tls-chip-height: var(--control-height-md);
|
|
36
|
-
--tls-chip-padding-inline: var(--spacing-
|
|
48
|
+
--tls-chip-padding-inline: var(--spacing-4);
|
|
37
49
|
|
|
38
50
|
--tls-chip-font-size: var(--font-label-medium-size);
|
|
39
|
-
--tls-chip-font-weight: var(--font-label-medium-weight);
|
|
40
51
|
--tls-chip-line-height: var(--font-label-medium-line-height);
|
|
41
52
|
--tls-chip-letter-spacing: var(--font-label-medium-letter-spacing);
|
|
42
53
|
|
|
@@ -47,10 +58,9 @@
|
|
|
47
58
|
|
|
48
59
|
&.tls-chip--lg {
|
|
49
60
|
--tls-chip-height: var(--control-height-lg);
|
|
50
|
-
--tls-chip-padding-inline: var(--spacing-
|
|
61
|
+
--tls-chip-padding-inline: var(--spacing-5);
|
|
51
62
|
|
|
52
63
|
--tls-chip-font-size: var(--font-label-large-size);
|
|
53
|
-
--tls-chip-font-weight: var(--font-label-large-weight);
|
|
54
64
|
--tls-chip-line-height: var(--font-label-large-line-height);
|
|
55
65
|
--tls-chip-letter-spacing: var(--font-label-large-letter-spacing);
|
|
56
66
|
|
|
@@ -42,4 +42,21 @@
|
|
|
42
42
|
--tls-form-control-group-line-height: var(--font-label-large-line-height);
|
|
43
43
|
--tls-form-control-group-letter-spacing: var(--font-label-large-letter-spacing);
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
// The group is the single source of size: each inner control renders its own
|
|
47
|
+
// size class, so map the group's resolved size onto the control's own vars.
|
|
48
|
+
// This lets a consumer set size once on the group instead of on every child.
|
|
49
|
+
&.tls-form-control-group--sm,
|
|
50
|
+
&.tls-form-control-group--md,
|
|
51
|
+
&.tls-form-control-group--lg {
|
|
52
|
+
.tls-form-control {
|
|
53
|
+
--tls-form-control-height: var(--tls-form-control-group-height);
|
|
54
|
+
--tls-form-control-padding-inline: var(--tls-form-control-group-padding-inline);
|
|
55
|
+
|
|
56
|
+
--tls-form-control-font-size: var(--tls-form-control-group-font-size);
|
|
57
|
+
--tls-form-control-font-weight: var(--tls-form-control-group-font-weight);
|
|
58
|
+
--tls-form-control-line-height: var(--tls-form-control-group-line-height);
|
|
59
|
+
--tls-form-control-letter-spacing: var(--tls-form-control-group-letter-spacing);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
45
62
|
}
|
|
@@ -20,7 +20,10 @@
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
&:has(input.tls-form-control:focus),
|
|
23
|
-
&:has(.tls-select__trigger:focus)
|
|
23
|
+
&:has(.tls-select__trigger:focus),
|
|
24
|
+
&:has(.tls-multi-select__trigger:focus),
|
|
25
|
+
&:has(.tls-autocomplete__trigger:focus),
|
|
26
|
+
&:has(.tls-date-time-picker__trigger:focus) {
|
|
24
27
|
border: 1px solid var(--color-primary);
|
|
25
28
|
box-shadow: 0 0 3px -1px var(--color-primary);
|
|
26
29
|
}
|
|
@@ -44,10 +47,13 @@
|
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
// The group border is the single focus indicator — suppress each control's own
|
|
47
|
-
// focus border/shadow (base input :focus,
|
|
50
|
+
// focus border/shadow (base input :focus, trigger controls :focus-within) so it never doubles up.
|
|
48
51
|
input.tls-form-control:focus,
|
|
49
52
|
textarea.tls-form-control:focus,
|
|
50
|
-
.tls-select.tls-form-control:focus-within
|
|
53
|
+
.tls-select.tls-form-control:focus-within,
|
|
54
|
+
.tls-multi-select.tls-form-control:focus-within,
|
|
55
|
+
.tls-autocomplete.tls-form-control:focus-within,
|
|
56
|
+
.tls-date-time-picker.tls-form-control:focus-within {
|
|
51
57
|
border: none;
|
|
52
58
|
box-shadow: none;
|
|
53
59
|
}
|
|
@@ -55,11 +61,15 @@
|
|
|
55
61
|
// Inline padding lives on the element that actually renders the value, so the padded
|
|
56
62
|
// area is interactive (no dead zone) and never stacks with a neighbour:
|
|
57
63
|
// - leaf controls: the <input>/<textarea> itself
|
|
58
|
-
// -
|
|
64
|
+
// - trigger controls (select, multi-select, autocomplete, date-time-picker):
|
|
65
|
+
// the inner trigger button/input (the host only wraps it)
|
|
59
66
|
// Pad the inline-start only; the trailing outer edge is added on the last child below.
|
|
60
67
|
input.tls-form-control,
|
|
61
68
|
textarea.tls-form-control,
|
|
62
69
|
.tls-select__trigger,
|
|
70
|
+
.tls-multi-select__trigger,
|
|
71
|
+
.tls-autocomplete__trigger,
|
|
72
|
+
.tls-date-time-picker__trigger,
|
|
63
73
|
.tls-form-control-addon {
|
|
64
74
|
padding-block: 0;
|
|
65
75
|
padding-inline-start: var(--tls-form-control-group-padding-inline);
|
|
@@ -70,6 +80,9 @@
|
|
|
70
80
|
> :last-child input.tls-form-control,
|
|
71
81
|
> :last-child textarea.tls-form-control,
|
|
72
82
|
> :last-child .tls-select__trigger,
|
|
83
|
+
> :last-child .tls-multi-select__trigger,
|
|
84
|
+
> :last-child .tls-autocomplete__trigger,
|
|
85
|
+
> :last-child .tls-date-time-picker__trigger,
|
|
73
86
|
> .tls-form-control-addon:last-child {
|
|
74
87
|
padding-inline-end: var(--tls-form-control-group-padding-inline);
|
|
75
88
|
}
|
|
@@ -36,14 +36,29 @@
|
|
|
36
36
|
box-shadow var(--motion-fast) var(--motion-ease-in-out),
|
|
37
37
|
filter var(--motion-fast) var(--motion-ease-in-out);
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
// The invisible native input carries focus; the ring renders on the track.
|
|
40
|
+
&:has(.tls-switch-input:focus-visible) {
|
|
40
41
|
@include mixins.focus-ring;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
@include mixins.touch-target(var(--tls-switch-height));
|
|
44
45
|
|
|
46
|
+
// The real control: stretched invisibly over the track so it stays focusable
|
|
47
|
+
// and clickable while the styled track/handle underneath provide the visuals.
|
|
45
48
|
.tls-switch-input {
|
|
46
|
-
|
|
49
|
+
position: absolute;
|
|
50
|
+
inset: 0;
|
|
51
|
+
|
|
52
|
+
width: 100%;
|
|
53
|
+
height: 100%;
|
|
54
|
+
|
|
55
|
+
margin: 0;
|
|
56
|
+
|
|
57
|
+
appearance: none;
|
|
58
|
+
|
|
59
|
+
opacity: 0;
|
|
60
|
+
|
|
61
|
+
cursor: inherit;
|
|
47
62
|
}
|
|
48
63
|
|
|
49
64
|
.tls-switch-handle {
|
|
@@ -58,6 +73,9 @@
|
|
|
58
73
|
|
|
59
74
|
box-shadow: var(--shadow-xs);
|
|
60
75
|
|
|
76
|
+
// Clicks fall through to the stretched native input underneath.
|
|
77
|
+
pointer-events: none;
|
|
78
|
+
|
|
61
79
|
transition: transform var(--motion-fast) var(--motion-ease-in-out);
|
|
62
80
|
}
|
|
63
81
|
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Separators between the strip's items, drawn when the strip carries the
|
|
2
|
+
// `--divided` modifier (e.g. a `tls-tab-nav` grouping its links visually).
|
|
3
|
+
// Rendered as non-interactive lines so they never affect an item's box or the
|
|
4
|
+
// active-indicator border, and inset along the cross axis so they read as short
|
|
5
|
+
// dividers rather than full edges. Orientation picks the axis; the segmented
|
|
6
|
+
// variant nudges the line into the middle of its inter-item gap.
|
|
7
|
+
//
|
|
8
|
+
// A separator belongs to the *boundary* between two items, not to either item,
|
|
9
|
+
// so a disabled item must not fade the line beside it. The boundary before an
|
|
10
|
+
// item is normally its leading `::before`; when that item is disabled its
|
|
11
|
+
// opacity would fade the line, so the boundary is drawn on the preceding
|
|
12
|
+
// item's trailing `::after` — an element that is not faded — keeping it at full
|
|
13
|
+
// strength. Each boundary is therefore drawn exactly once.
|
|
14
|
+
.tls-tab-header--divided {
|
|
15
|
+
.tls-tab-header__item {
|
|
16
|
+
position: relative;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.tls-tab-header__item:not(:first-child):not(.tls-tab-header__item--disabled)::before,
|
|
20
|
+
.tls-tab-header__item:has(+ .tls-tab-header__item--disabled)::after {
|
|
21
|
+
content: '';
|
|
22
|
+
|
|
23
|
+
position: absolute;
|
|
24
|
+
|
|
25
|
+
background-color: var(--tls-tab-header-border-color);
|
|
26
|
+
|
|
27
|
+
pointer-events: none;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&.tls-tab-header--horizontal {
|
|
31
|
+
.tls-tab-header__item:not(:first-child):not(.tls-tab-header__item--disabled)::before,
|
|
32
|
+
.tls-tab-header__item:has(+ .tls-tab-header__item--disabled)::after {
|
|
33
|
+
inset-block: var(--spacing-2);
|
|
34
|
+
|
|
35
|
+
width: var(--tls-tab-header-border-width);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.tls-tab-header__item:not(:first-child):not(.tls-tab-header__item--disabled)::before {
|
|
39
|
+
inset-inline-start: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.tls-tab-header__item:has(+ .tls-tab-header__item--disabled)::after {
|
|
43
|
+
inset-inline-end: 0;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
&.tls-tab-header--vertical {
|
|
48
|
+
.tls-tab-header__item:not(:first-child):not(.tls-tab-header__item--disabled)::before,
|
|
49
|
+
.tls-tab-header__item:has(+ .tls-tab-header__item--disabled)::after {
|
|
50
|
+
inset-inline: var(--spacing-4);
|
|
51
|
+
|
|
52
|
+
height: var(--tls-tab-header-border-width);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.tls-tab-header__item:not(:first-child):not(.tls-tab-header__item--disabled)::before {
|
|
56
|
+
inset-block-start: 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.tls-tab-header__item:has(+ .tls-tab-header__item--disabled)::after {
|
|
60
|
+
inset-block-end: 0;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&.tls-tab-header--segmented {
|
|
65
|
+
&.tls-tab-header--horizontal {
|
|
66
|
+
.tls-tab-header__item:not(:first-child):not(.tls-tab-header__item--disabled)::before {
|
|
67
|
+
inset-inline-start: calc(var(--tls-tab-header-padding) / -2);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.tls-tab-header__item:has(+ .tls-tab-header__item--disabled)::after {
|
|
71
|
+
inset-inline-end: calc(var(--tls-tab-header-padding) / -2);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&.tls-tab-header--vertical {
|
|
76
|
+
.tls-tab-header__item:not(:first-child):not(.tls-tab-header__item--disabled)::before {
|
|
77
|
+
inset-block-start: calc(var(--tls-tab-header-padding) / -2);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.tls-tab-header__item:has(+ .tls-tab-header__item--disabled)::after {
|
|
81
|
+
inset-block-end: calc(var(--tls-tab-header-padding) / -2);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -87,6 +87,14 @@
|
|
|
87
87
|
--tls-tab-header-padding: var(--spacing-2);
|
|
88
88
|
--tls-tab-header-active-label-color: var(--color-on-surface);
|
|
89
89
|
|
|
90
|
+
// On dark surfaces elevation reads through a lighter fill, not shadow: the
|
|
91
|
+
// pill's shadow is invisible there and `--color-surface` sits *below* the
|
|
92
|
+
// track's container color, so raise the pill above the track (and above the
|
|
93
|
+
// inactive hover's container-high) instead.
|
|
94
|
+
.tls-dark & {
|
|
95
|
+
--tls-tab-header-pill-background-color: var(--color-surface-container-highest);
|
|
96
|
+
}
|
|
97
|
+
|
|
90
98
|
padding: var(--tls-tab-header-padding);
|
|
91
99
|
gap: var(--tls-tab-header-padding);
|
|
92
100
|
|
|
@@ -58,24 +58,32 @@
|
|
|
58
58
|
} @else if $treatment == outlined {
|
|
59
59
|
border-color: var(--#{$block}-color);
|
|
60
60
|
|
|
61
|
+
// Transparent at rest so the control sits on any backdrop (a tinted card,
|
|
62
|
+
// a striped row); interaction paints a translucent state layer over it.
|
|
63
|
+
background-color: transparent;
|
|
64
|
+
|
|
61
65
|
color: var(--#{$block}-color);
|
|
62
66
|
|
|
63
67
|
@include _hover-focus-state($block) {
|
|
64
|
-
background-color: color-mix(in srgb, var(--#{$block}-color) 7.5%,
|
|
68
|
+
background-color: color-mix(in srgb, var(--#{$block}-color) 7.5%, transparent);
|
|
65
69
|
}
|
|
66
70
|
|
|
67
71
|
@include _active-state($block) {
|
|
68
|
-
background-color: color-mix(in srgb, var(--#{$block}-color) 15%,
|
|
72
|
+
background-color: color-mix(in srgb, var(--#{$block}-color) 15%, transparent);
|
|
69
73
|
}
|
|
70
74
|
} @else if $treatment == text {
|
|
75
|
+
// Transparent at rest so the control sits on any backdrop (a tinted card,
|
|
76
|
+
// a striped row); interaction paints a translucent state layer over it.
|
|
77
|
+
background-color: transparent;
|
|
78
|
+
|
|
71
79
|
color: var(--#{$block}-color);
|
|
72
80
|
|
|
73
81
|
@include _hover-focus-state($block) {
|
|
74
|
-
background-color: color-mix(in srgb, var(--#{$block}-color) 7.5%,
|
|
82
|
+
background-color: color-mix(in srgb, var(--#{$block}-color) 7.5%, transparent);
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
@include _active-state($block) {
|
|
78
|
-
background-color: color-mix(in srgb, var(--#{$block}-color) 15%,
|
|
86
|
+
background-color: color-mix(in srgb, var(--#{$block}-color) 15%, transparent);
|
|
79
87
|
}
|
|
80
88
|
} @else if $treatment == elevated {
|
|
81
89
|
box-shadow: var(--shadow-sm);
|