@thalassic/themes 22.5.1 → 22.6.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.
Files changed (31) hide show
  1. package/package.json +1 -1
  2. package/themes/thalassic/components/_checkbox.scss +9 -7
  3. package/themes/thalassic/components/_icon.scss +27 -7
  4. package/themes/thalassic/components/badge/_badge-color.scss +6 -0
  5. package/themes/thalassic/components/badge/_badge-position.scss +21 -0
  6. package/themes/thalassic/components/badge/_badge-size.scss +22 -0
  7. package/themes/thalassic/components/badge/_badge.scss +62 -0
  8. package/themes/thalassic/components/badge/_index.scss +4 -0
  9. package/themes/thalassic/components/button/_button-color.scss +4 -34
  10. package/themes/thalassic/components/button/_button-variant.scss +2 -1
  11. package/themes/thalassic/components/calendar/_calendar.scss +3 -3
  12. package/themes/thalassic/components/chip/_chip-color.scss +4 -35
  13. package/themes/thalassic/components/chip/_chip-control.scss +12 -35
  14. package/themes/thalassic/components/chip/_chip-variant.scss +5 -0
  15. package/themes/thalassic/components/date-time-picker/_mixins.scss +3 -3
  16. package/themes/thalassic/components/date-time-picker/_time-picker.scss +3 -3
  17. package/themes/thalassic/components/dialog/_dialog.scss +1 -1
  18. package/themes/thalassic/components/drawer/_drawer.scss +1 -1
  19. package/themes/thalassic/components/index.scss +2 -0
  20. package/themes/thalassic/components/multi-select/_multi-select-size.scss +6 -6
  21. package/themes/thalassic/components/multi-select/_multi-select.scss +3 -0
  22. package/themes/thalassic/components/pagination/_pagination.scss +5 -0
  23. package/themes/thalassic/components/select/_select-size.scss +6 -6
  24. package/themes/thalassic/components/select/_select.scss +3 -0
  25. package/themes/thalassic/components/toast/_index.scss +2 -0
  26. package/themes/thalassic/components/toast/_toast-color.scss +43 -0
  27. package/themes/thalassic/components/toast/_toast.scss +226 -0
  28. package/themes/thalassic/components/toggle-group/_toggle-group-color.scss +4 -34
  29. package/themes/thalassic/components/tooltip/_tooltip-color.scss +3 -34
  30. package/themes/thalassic/mixins/_color-variants.scss +39 -0
  31. package/themes/thalassic/mixins/_index.scss +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thalassic/themes",
3
- "version": "22.5.1",
3
+ "version": "22.6.0",
4
4
  "license": "MIT",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^22.0.0",
@@ -29,10 +29,9 @@
29
29
 
30
30
  background-color: var(--color-surface);
31
31
 
32
- transition:
33
- box-shadow var(--motion-fast) var(--motion-ease-in-out),
34
- border-color var(--motion-fast) var(--motion-ease-in-out),
35
- background-color var(--motion-fast) var(--motion-ease-in-out);
32
+ transition: box-shadow var(--motion-fast) var(--motion-ease-in-out),
33
+ border-color var(--motion-fast) var(--motion-ease-in-out),
34
+ background-color var(--motion-fast) var(--motion-ease-in-out);
36
35
 
37
36
  &:checked {
38
37
  background-color: var(--color-primary);
@@ -47,6 +46,10 @@
47
46
  position: absolute;
48
47
  inset: 0;
49
48
 
49
+ width: calc(var(--tls-checkbox-size) * 0.75);
50
+ height: calc(var(--tls-checkbox-size) * 0.75);
51
+ margin: auto;
52
+
50
53
  opacity: 0;
51
54
  scale: 0;
52
55
 
@@ -54,9 +57,8 @@
54
57
 
55
58
  color: var(--tls-checkbox-checked-icon-color);
56
59
 
57
- transition:
58
- scale var(--motion-default) var(--motion-ease-bounce),
59
- opacity var(--motion-fast) var(--motion-ease-in-out);
60
+ transition: scale var(--motion-default) var(--motion-ease-bounce),
61
+ opacity var(--motion-fast) var(--motion-ease-in-out);
60
62
  }
61
63
 
62
64
  // Checked & Indeterminate
@@ -1,15 +1,35 @@
1
- .tls-icon {
2
- width: auto;
3
- height: auto;
4
-
5
- min-width: auto;
6
- min-height: auto;
1
+ // Default 1em box at zero specificity, so any consumer size class (e.g.
2
+ // .tls-select__chevron) overrides it without needing a compound selector.
3
+ :where(.tls-icon) {
4
+ width: 1em;
5
+ height: 1em;
6
+ }
7
7
 
8
- display: inline-block;
8
+ .tls-icon {
9
+ display: inline-flex;
9
10
 
10
11
  color: inherit;
11
12
 
12
13
  .tls-svg-icon {
14
+ width: 100%;
15
+ height: 100%;
16
+
17
+ display: flex;
18
+
13
19
  color: inherit;
20
+
21
+ svg {
22
+ width: 100%;
23
+ height: 100%;
24
+
25
+ display: block;
26
+ }
27
+ }
28
+
29
+ .tls-img-icon {
30
+ width: 100%;
31
+ height: 100%;
32
+
33
+ object-fit: contain;
14
34
  }
15
35
  }
@@ -0,0 +1,6 @@
1
+ @use '../../mixins' as mixins;
2
+
3
+ .tls-badge {
4
+ @include mixins.color-variants('tls-badge', $tonal: true);
5
+ @include mixins.tonal-swap('tls-badge');
6
+ }
@@ -0,0 +1,21 @@
1
+ .tls-badge {
2
+ &--top-start &__indicator {
3
+ inset-block-start: var(--tls-badge-offset);
4
+ inset-inline-start: var(--tls-badge-offset);
5
+ }
6
+
7
+ &--top-end &__indicator {
8
+ inset-block-start: var(--tls-badge-offset);
9
+ inset-inline-end: var(--tls-badge-offset);
10
+ }
11
+
12
+ &--bottom-start &__indicator {
13
+ inset-block-end: var(--tls-badge-offset);
14
+ inset-inline-start: var(--tls-badge-offset);
15
+ }
16
+
17
+ &--bottom-end &__indicator {
18
+ inset-block-end: var(--tls-badge-offset);
19
+ inset-inline-end: var(--tls-badge-offset);
20
+ }
21
+ }
@@ -0,0 +1,22 @@
1
+ .tls-badge {
2
+ &.tls-badge--sm {
3
+ --tls-badge-size: 16px;
4
+ --tls-badge-dot-size: 6px;
5
+ --tls-badge-padding-inline: var(--spacing-1);
6
+ --tls-badge-font-size: var(--font-label-small-size);
7
+ }
8
+
9
+ &.tls-badge--md {
10
+ --tls-badge-size: 20px;
11
+ --tls-badge-dot-size: 8px;
12
+ --tls-badge-padding-inline: var(--spacing-2);
13
+ --tls-badge-font-size: var(--font-label-small-size);
14
+ }
15
+
16
+ &.tls-badge--lg {
17
+ --tls-badge-size: 24px;
18
+ --tls-badge-dot-size: 10px;
19
+ --tls-badge-padding-inline: var(--spacing-2);
20
+ --tls-badge-font-size: var(--font-label-medium-size);
21
+ }
22
+ }
@@ -0,0 +1,62 @@
1
+ @use '../../mixins' as mixins;
2
+
3
+ @keyframes tls-badge-pop {
4
+ from {
5
+ opacity: 0;
6
+ transform: scale(0);
7
+ }
8
+
9
+ to {
10
+ opacity: 1;
11
+ transform: scale(1);
12
+ }
13
+ }
14
+
15
+ .tls-badge {
16
+ position: relative;
17
+
18
+ display: inline-flex;
19
+
20
+ &__indicator {
21
+ --tls-badge-offset: calc(var(--tls-badge-size) / -2);
22
+
23
+ position: absolute;
24
+ z-index: 1;
25
+
26
+ min-width: var(--tls-badge-size);
27
+ height: var(--tls-badge-size);
28
+
29
+ padding-inline: var(--tls-badge-padding-inline);
30
+
31
+ display: inline-flex;
32
+ align-items: center;
33
+ justify-content: center;
34
+
35
+ border-radius: var(--radius-xl);
36
+
37
+ background-color: var(--tls-badge-color);
38
+
39
+ font-size: var(--tls-badge-font-size);
40
+ font-weight: 600;
41
+ line-height: 1;
42
+ color: var(--tls-badge-on-color);
43
+
44
+ pointer-events: none;
45
+
46
+ @include mixins.motion(essential) {
47
+ &--enter {
48
+ animation: tls-badge-pop var(--motion-instant) var(--motion-ease-out) both;
49
+ }
50
+
51
+ &--leave {
52
+ animation: tls-badge-pop var(--motion-instant) var(--motion-ease-in) reverse both;
53
+ }
54
+ }
55
+ }
56
+
57
+ &--dot &__indicator {
58
+ --tls-badge-size: var(--tls-badge-dot-size);
59
+
60
+ padding-inline: 0;
61
+ }
62
+ }
@@ -0,0 +1,4 @@
1
+ @forward "badge";
2
+ @forward "badge-color";
3
+ @forward "badge-position";
4
+ @forward "badge-size";
@@ -1,38 +1,8 @@
1
- .tls-button {
2
- &.tls-button--primary {
3
- --tls-button-on-color: var(--color-on-primary);
4
- --tls-button-color: var(--color-primary);
5
- }
6
-
7
- &.tls-button--secondary {
8
- --tls-button-on-color: var(--color-on-secondary);
9
- --tls-button-color: var(--color-secondary);
10
- }
11
-
12
- &.tls-button--tertiary {
13
- --tls-button-on-color: var(--color-on-tertiary);
14
- --tls-button-color: var(--color-tertiary);
15
- }
16
-
17
- &.tls-button--success {
18
- --tls-button-on-color: var(--color-on-success);
19
- --tls-button-color: var(--color-success);
20
- }
21
-
22
- &.tls-button--info {
23
- --tls-button-on-color: var(--color-on-info);
24
- --tls-button-color: var(--color-info);
25
- }
1
+ @use '../../mixins' as mixins;
26
2
 
27
- &.tls-button--warning {
28
- --tls-button-on-color: var(--color-on-warning);
29
- --tls-button-color: var(--color-warning);
30
- }
31
-
32
- &.tls-button--danger {
33
- --tls-button-on-color: var(--color-on-danger);
34
- --tls-button-color: var(--color-danger);
35
- }
3
+ .tls-button {
4
+ @include mixins.color-variants('tls-button', $tonal: true);
5
+ @include mixins.tonal-swap('tls-button');
36
6
 
37
7
  &.tls-button--disabled {
38
8
  --tls-button-on-color: var(--color-on-surface-variant);
@@ -13,7 +13,8 @@
13
13
  }
14
14
 
15
15
  // Variants
16
- &--filled {
16
+ &--filled,
17
+ &--tonal {
17
18
  color: var(--tls-button-on-color);
18
19
 
19
20
  &::before {
@@ -18,9 +18,9 @@
18
18
  }
19
19
 
20
20
  &__nav-button {
21
- svg {
22
- width: 8px;
23
- height: 14px;
21
+ .tls-icon {
22
+ width: 18px;
23
+ height: 18px;
24
24
  }
25
25
  }
26
26
 
@@ -1,36 +1,5 @@
1
- .tls-chip {
2
- &.tls-chip--primary {
3
- --tls-chip-color: var(--color-primary);
4
- --tls-chip-on-color: var(--color-on-primary);
5
- }
6
-
7
- &.tls-chip--secondary {
8
- --tls-chip-color: var(--color-secondary);
9
- --tls-chip-on-color: var(--color-on-secondary);
10
- }
11
-
12
- &.tls-chip--tertiary {
13
- --tls-chip-color: var(--color-tertiary);
14
- --tls-chip-on-color: var(--color-on-tertiary);
15
- }
16
-
17
- &.tls-chip--success {
18
- --tls-chip-color: var(--color-success);
19
- --tls-chip-on-color: var(--color-on-success);
20
- }
1
+ @use '../../mixins' as mixins;
21
2
 
22
- &.tls-chip--info {
23
- --tls-chip-color: var(--color-info);
24
- --tls-chip-on-color: var(--color-on-info);
25
- }
26
-
27
- &.tls-chip--warning {
28
- --tls-chip-color: var(--color-warning);
29
- --tls-chip-on-color: var(--color-on-warning);
30
- }
31
-
32
- &.tls-chip--danger {
33
- --tls-chip-color: var(--color-danger);
34
- --tls-chip-on-color: var(--color-on-danger);
35
- }
36
- }
3
+ .tls-chip {
4
+ @include mixins.color-variants('tls-chip', $tonal: true);
5
+ }
@@ -1,3 +1,5 @@
1
+ @use '../../mixins' as mixins;
2
+
1
3
  .tls-chip {
2
4
  &.tls-chip--control {
3
5
  cursor: pointer;
@@ -9,49 +11,24 @@
9
11
  border-color: var(--tls-chip-color);
10
12
  }
11
13
 
12
- &.tls-chip--checked-primary {
13
- --tls-chip-color: var(--color-primary);
14
- --tls-chip-on-color: var(--color-on-primary);
15
- }
16
-
17
- &.tls-chip--checked-secondary {
18
- --tls-chip-color: var(--color-secondary);
19
- --tls-chip-on-color: var(--color-on-secondary);
20
- }
21
-
22
- &.tls-chip--checked-tertiary {
23
- --tls-chip-color: var(--color-tertiary);
24
- --tls-chip-on-color: var(--color-on-tertiary);
25
- }
26
-
27
- &.tls-chip--checked-success {
28
- --tls-chip-color: var(--color-success);
29
- --tls-chip-on-color: var(--color-on-success);
30
- }
31
-
32
- &.tls-chip--checked-info {
33
- --tls-chip-color: var(--color-info);
34
- --tls-chip-on-color: var(--color-on-info);
35
- }
36
-
37
- &.tls-chip--checked-warning {
38
- --tls-chip-color: var(--color-warning);
39
- --tls-chip-on-color: var(--color-on-warning);
40
- }
41
-
42
- &.tls-chip--checked-danger {
43
- --tls-chip-color: var(--color-danger);
44
- --tls-chip-on-color: var(--color-on-danger);
45
- }
14
+ @include mixins.color-variants('tls-chip', $tonal: true, $modifier: 'checked-');
46
15
 
47
16
  // Checked variant overrides (higher specificity than the base variant so the
48
- // checked appearance wins regardless of stylesheet order).
17
+ // checked appearance wins regardless of stylesheet order). Each reads its pair
18
+ // directly rather than swapping a shared token, so the base variant never leaks
19
+ // across the checked boundary.
49
20
  &.tls-chip--checked.tls-chip--checked-filled {
50
21
  background-color: var(--tls-chip-color);
51
22
  color: var(--tls-chip-on-color);
52
23
  border-color: var(--tls-chip-color);
53
24
  }
54
25
 
26
+ &.tls-chip--checked.tls-chip--checked-tonal {
27
+ background-color: var(--tls-chip-color-container);
28
+ color: var(--tls-chip-on-color-container);
29
+ border-color: var(--tls-chip-color-container);
30
+ }
31
+
55
32
  &.tls-chip--checked.tls-chip--checked-outlined {
56
33
  background-color: transparent;
57
34
  color: var(--tls-chip-color);
@@ -4,6 +4,11 @@
4
4
  color: var(--tls-chip-on-color);
5
5
  }
6
6
 
7
+ &.tls-chip--tonal {
8
+ background-color: var(--tls-chip-color-container);
9
+ color: var(--tls-chip-on-color-container);
10
+ }
11
+
7
12
  &.tls-chip--outlined {
8
13
  background-color: transparent;
9
14
  color: var(--tls-chip-color);
@@ -88,9 +88,9 @@
88
88
 
89
89
  cursor: pointer;
90
90
 
91
- svg {
92
- width: 8px;
93
- height: 14px;
91
+ .tls-icon {
92
+ width: 18px;
93
+ height: 18px;
94
94
  }
95
95
 
96
96
  &:hover {
@@ -43,9 +43,9 @@
43
43
  cursor: pointer;
44
44
  color: var(--color-on-surface-variant);
45
45
 
46
- svg {
47
- width: 14px;
48
- height: 8px;
46
+ .tls-icon {
47
+ width: 18px;
48
+ height: 18px;
49
49
  }
50
50
 
51
51
  &:hover {
@@ -51,7 +51,7 @@
51
51
  color: var(--color-on-surface);
52
52
  }
53
53
 
54
- svg {
54
+ .tls-icon {
55
55
  width: 100%;
56
56
  height: 100%;
57
57
  }
@@ -87,7 +87,7 @@
87
87
  color: var(--color-on-surface);
88
88
  }
89
89
 
90
- svg {
90
+ .tls-icon {
91
91
  width: 100%;
92
92
  height: 100%;
93
93
  }
@@ -1,4 +1,5 @@
1
1
  @forward 'alert';
2
+ @forward 'badge';
2
3
  @forward 'button';
3
4
  @forward 'calendar';
4
5
  @forward 'chart';
@@ -16,6 +17,7 @@
16
17
  @forward 'switch';
17
18
  @forward 'tabs';
18
19
  @forward 'textarea';
20
+ @forward 'toast';
19
21
  @forward 'tooltip';
20
22
 
21
23
  @forward 'checkbox';
@@ -1,16 +1,16 @@
1
1
  .tls-multi-select {
2
2
  &.tls-form-control--sm {
3
- --tls-multi-select-icon-size: 0.625rem;
4
- --tls-multi-select-clear-size: 0.625rem;
3
+ --tls-multi-select-icon-size: 0.875rem;
4
+ --tls-multi-select-clear-size: 0.875rem;
5
5
  }
6
6
 
7
7
  &.tls-form-control--md {
8
- --tls-multi-select-icon-size: 0.75rem;
9
- --tls-multi-select-clear-size: 0.75rem;
8
+ --tls-multi-select-icon-size: 1rem;
9
+ --tls-multi-select-clear-size: 1rem;
10
10
  }
11
11
 
12
12
  &.tls-form-control--lg {
13
- --tls-multi-select-icon-size: 0.875rem;
14
- --tls-multi-select-clear-size: 0.875rem;
13
+ --tls-multi-select-icon-size: 1.125rem;
14
+ --tls-multi-select-clear-size: 1.125rem;
15
15
  }
16
16
  }
@@ -67,6 +67,9 @@
67
67
  }
68
68
 
69
69
  .tls-multi-select__chevron {
70
+ width: 100%;
71
+ height: 100%;
72
+
70
73
  transition: transform var(--motion-fast) var(--motion-ease-in-out);
71
74
  }
72
75
  }
@@ -38,6 +38,11 @@
38
38
  &-icon {
39
39
  width: var(--tls-pagination-button-icon-size);
40
40
  height: var(--tls-pagination-button-icon-size);
41
+
42
+ .tls-icon {
43
+ width: 100%;
44
+ height: 100%;
45
+ }
41
46
  }
42
47
  }
43
48
 
@@ -1,16 +1,16 @@
1
1
  .tls-select {
2
2
  &.tls-form-control--sm {
3
- --tls-select-icon-size: 0.625rem;
4
- --tls-select-clear-size: 0.625rem;
3
+ --tls-select-icon-size: 0.875rem;
4
+ --tls-select-clear-size: 0.875rem;
5
5
  }
6
6
 
7
7
  &.tls-form-control--md {
8
- --tls-select-icon-size: 0.75rem;
9
- --tls-select-clear-size: 0.75rem;
8
+ --tls-select-icon-size: 1rem;
9
+ --tls-select-clear-size: 1rem;
10
10
  }
11
11
 
12
12
  &.tls-form-control--lg {
13
- --tls-select-icon-size: 0.875rem;
14
- --tls-select-clear-size: 0.875rem;
13
+ --tls-select-icon-size: 1.125rem;
14
+ --tls-select-clear-size: 1.125rem;
15
15
  }
16
16
  }
@@ -67,6 +67,9 @@
67
67
  }
68
68
 
69
69
  .tls-select__chevron {
70
+ width: 100%;
71
+ height: 100%;
72
+
70
73
  transition: transform var(--motion-fast) var(--motion-ease-in-out);
71
74
  }
72
75
  }
@@ -0,0 +1,2 @@
1
+ @forward 'toast';
2
+ @forward 'toast-color';
@@ -0,0 +1,43 @@
1
+ .tls-toast {
2
+ &.tls-toast--primary {
3
+ --tls-toast-color: var(--color-on-primary-container);
4
+ --tls-toast-background-color: var(--color-primary-container);
5
+ --tls-toast-icon-color: var(--color-primary);
6
+ }
7
+
8
+ &.tls-toast--secondary {
9
+ --tls-toast-color: var(--color-on-secondary-container);
10
+ --tls-toast-background-color: var(--color-secondary-container);
11
+ --tls-toast-icon-color: var(--color-secondary);
12
+ }
13
+
14
+ &.tls-toast--tertiary {
15
+ --tls-toast-color: var(--color-on-tertiary-container);
16
+ --tls-toast-background-color: var(--color-tertiary-container);
17
+ --tls-toast-icon-color: var(--color-tertiary);
18
+ }
19
+
20
+ &.tls-toast--success {
21
+ --tls-toast-color: var(--color-on-success-container);
22
+ --tls-toast-background-color: var(--color-success-container);
23
+ --tls-toast-icon-color: var(--color-success);
24
+ }
25
+
26
+ &.tls-toast--info {
27
+ --tls-toast-color: var(--color-on-info-container);
28
+ --tls-toast-background-color: var(--color-info-container);
29
+ --tls-toast-icon-color: var(--color-info);
30
+ }
31
+
32
+ &.tls-toast--warning {
33
+ --tls-toast-color: var(--color-on-warning-container);
34
+ --tls-toast-background-color: var(--color-warning-container);
35
+ --tls-toast-icon-color: var(--color-warning);
36
+ }
37
+
38
+ &.tls-toast--danger {
39
+ --tls-toast-color: var(--color-on-danger-container);
40
+ --tls-toast-background-color: var(--color-danger-container);
41
+ --tls-toast-icon-color: var(--color-danger);
42
+ }
43
+ }
@@ -0,0 +1,226 @@
1
+ @use '../../mixins' as mixins;
2
+
3
+ @keyframes tls-toast-fade {
4
+ from {
5
+ opacity: 0;
6
+ }
7
+
8
+ to {
9
+ opacity: 1;
10
+ }
11
+ }
12
+
13
+ @keyframes tls-toast-progress {
14
+ from {
15
+ width: 100%;
16
+ }
17
+
18
+ to {
19
+ width: 0%;
20
+ }
21
+ }
22
+
23
+ .tls-toast-outlet {
24
+ position: fixed;
25
+ inset: 0;
26
+
27
+ pointer-events: none;
28
+ }
29
+
30
+ .tls-toast-region {
31
+ --tls-toast-region-inset: var(--spacing-4);
32
+ --tls-toast-width: 360px;
33
+
34
+ position: absolute;
35
+
36
+ width: var(--tls-toast-width);
37
+ max-width: calc(100vw - var(--tls-toast-region-inset) * 2);
38
+
39
+ pointer-events: auto;
40
+
41
+ &--top {
42
+ inset-block-start: var(--tls-toast-region-inset);
43
+ }
44
+
45
+ &--bottom {
46
+ inset-block-end: var(--tls-toast-region-inset);
47
+ }
48
+
49
+ &--start {
50
+ inset-inline-start: var(--tls-toast-region-inset);
51
+ }
52
+
53
+ &--end {
54
+ inset-inline-end: var(--tls-toast-region-inset);
55
+ }
56
+
57
+ &--center {
58
+ inset-inline: 0;
59
+
60
+ margin-inline: auto;
61
+ }
62
+
63
+ // Toasts are anchored to the region's block edge and overlap there; the outlet
64
+ // offsets them with transforms. The scale origin sits on that same edge so the
65
+ // pile shrinks toward the anchor.
66
+ &--top .tls-toast {
67
+ inset-block-start: 0;
68
+
69
+ transform-origin: top center;
70
+ }
71
+
72
+ &--bottom .tls-toast {
73
+ inset-block-end: 0;
74
+
75
+ transform-origin: bottom center;
76
+ }
77
+ }
78
+
79
+ .tls-toast {
80
+ position: absolute;
81
+ inset-inline: 0;
82
+
83
+ @include mixins.motion(essential) {
84
+ transition: transform var(--motion-default) var(--motion-ease-out);
85
+
86
+ &--enter {
87
+ animation: tls-toast-fade var(--motion-default) var(--motion-ease-out) both;
88
+ }
89
+
90
+ &--leave {
91
+ animation: tls-toast-fade var(--motion-default) var(--motion-ease-in) reverse both;
92
+ }
93
+ }
94
+
95
+ &__surface {
96
+ position: relative;
97
+
98
+ padding: var(--spacing-3) var(--spacing-4);
99
+
100
+ display: flex;
101
+ align-items: flex-start;
102
+ gap: var(--spacing-3);
103
+
104
+ border-radius: var(--radius-md);
105
+
106
+ background-color: var(--tls-toast-background-color);
107
+ box-shadow: var(--shadow-md);
108
+ opacity: var(--tls-toast-depth-opacity, 1);
109
+
110
+ color: var(--tls-toast-color);
111
+
112
+ @include mixins.motion(essential) {
113
+ transition: opacity var(--motion-default) var(--motion-ease-out);
114
+ }
115
+ }
116
+
117
+ &__icon {
118
+ width: 16px;
119
+ height: 16px;
120
+
121
+ flex-shrink: 0;
122
+
123
+ display: flex;
124
+
125
+ color: var(--tls-toast-icon-color);
126
+ }
127
+
128
+ &__body {
129
+ min-width: 0;
130
+
131
+ display: flex;
132
+ flex-direction: column;
133
+ gap: var(--spacing-1);
134
+
135
+ flex: 1;
136
+ }
137
+
138
+ &__title {
139
+ margin: 0;
140
+
141
+ font-size: var(--font-size-sm);
142
+ font-weight: var(--font-weight-semibold);
143
+ }
144
+
145
+ &__message {
146
+ margin: 0;
147
+
148
+ font-size: var(--font-size-sm);
149
+ line-height: 1.4;
150
+ overflow-wrap: anywhere;
151
+ }
152
+
153
+ &__action {
154
+ flex-shrink: 0;
155
+
156
+ margin-inline-start: calc(var(--spacing-2) * -1);
157
+ }
158
+
159
+ &__close {
160
+ flex-shrink: 0;
161
+
162
+ width: 28px;
163
+ height: 28px;
164
+
165
+ display: flex;
166
+ align-items: center;
167
+ justify-content: center;
168
+
169
+ border: none;
170
+ border-radius: var(--radius-sm);
171
+
172
+ background-color: transparent;
173
+
174
+ color: inherit;
175
+
176
+ cursor: pointer;
177
+
178
+ @include mixins.motion(essential) {
179
+ transition: background-color var(--motion-fast) var(--motion-ease-in-out);
180
+ }
181
+
182
+ &:hover {
183
+ background-color: rgb(var(--color-shadow) / 0.12);
184
+ }
185
+ }
186
+
187
+ &__close-icon {
188
+ width: 14px;
189
+ height: 14px;
190
+ }
191
+
192
+ // Countdown bar hugging the surface's block-end edge; its width animates from
193
+ // full to empty over the auto-dismiss delay. Only rendered under motion (the
194
+ // mixin hides it at the `none` level, so no misleading static bar is shown).
195
+ &__progress {
196
+ position: absolute;
197
+ inset-block-end: 0;
198
+ inset-inline-start: 0;
199
+
200
+ width: 100%;
201
+ height: 3px;
202
+
203
+ display: none;
204
+
205
+ border-end-start-radius: var(--radius-md);
206
+ border-end-end-radius: var(--radius-md);
207
+
208
+ background-color: var(--tls-toast-icon-color);
209
+ opacity: 0.9;
210
+
211
+ @include mixins.motion(essential) {
212
+ display: block;
213
+
214
+ animation: tls-toast-progress var(--tls-toast-duration, 5000ms) linear forwards;
215
+ }
216
+ }
217
+
218
+ // Freezes the bar while the stack is hovered / focused, in lockstep with the
219
+ // paused auto-dismiss timers. Gated by the same motion tier so it outranks the
220
+ // `animation` shorthand above (which resets `animation-play-state` to running).
221
+ &--paused &__progress {
222
+ @include mixins.motion(essential) {
223
+ animation-play-state: paused;
224
+ }
225
+ }
226
+ }
@@ -1,36 +1,6 @@
1
- .tls-toggle-group {
2
- &--primary {
3
- --tls-toggle-group-color: var(--color-primary);
4
- --tls-toggle-group-on-color: var(--color-on-primary);
5
- }
6
-
7
- &--secondary {
8
- --tls-toggle-group-color: var(--color-secondary);
9
- --tls-toggle-group-on-color: var(--color-on-secondary);
10
- }
11
-
12
- &--tertiary {
13
- --tls-toggle-group-color: var(--color-tertiary);
14
- --tls-toggle-group-on-color: var(--color-on-tertiary);
15
- }
16
-
17
- &--success {
18
- --tls-toggle-group-color: var(--color-success);
19
- --tls-toggle-group-on-color: var(--color-on-success);
20
- }
1
+ @use '../../mixins' as mixins;
21
2
 
22
- &--info {
23
- --tls-toggle-group-color: var(--color-info);
24
- --tls-toggle-group-on-color: var(--color-on-info);
25
- }
26
-
27
- &--warning {
28
- --tls-toggle-group-color: var(--color-warning);
29
- --tls-toggle-group-on-color: var(--color-on-warning);
30
- }
31
-
32
- &--danger {
33
- --tls-toggle-group-color: var(--color-danger);
34
- --tls-toggle-group-on-color: var(--color-on-danger);
35
- }
3
+ .tls-toggle-group {
4
+ @include mixins.color-variants('tls-toggle-group', $tonal: true);
5
+ @include mixins.tonal-swap('tls-toggle-group');
36
6
  }
@@ -1,36 +1,5 @@
1
- .tls-tooltip {
2
- &.tls-tooltip--primary {
3
- --tls-tooltip-on-color: var(--color-on-primary);
4
- --tls-tooltip-color: var(--color-primary);
5
- }
6
-
7
- &.tls-tooltip--secondary {
8
- --tls-tooltip-on-color: var(--color-on-secondary);
9
- --tls-tooltip-color: var(--color-secondary);
10
- }
11
-
12
- &.tls-tooltip--tertiary {
13
- --tls-tooltip-on-color: var(--color-on-tertiary);
14
- --tls-tooltip-color: var(--color-tertiary);
15
- }
16
-
17
- &.tls-tooltip--success {
18
- --tls-tooltip-on-color: var(--color-on-success);
19
- --tls-tooltip-color: var(--color-success);
20
- }
1
+ @use '../../mixins' as mixins;
21
2
 
22
- &.tls-tooltip--info {
23
- --tls-tooltip-on-color: var(--color-on-info);
24
- --tls-tooltip-color: var(--color-info);
25
- }
26
-
27
- &.tls-tooltip--warning {
28
- --tls-tooltip-on-color: var(--color-on-warning);
29
- --tls-tooltip-color: var(--color-warning);
30
- }
31
-
32
- &.tls-tooltip--danger {
33
- --tls-tooltip-on-color: var(--color-on-danger);
34
- --tls-tooltip-color: var(--color-danger);
35
- }
3
+ .tls-tooltip {
4
+ @include mixins.color-variants('tls-tooltip');
36
5
  }
@@ -0,0 +1,39 @@
1
+ $colors: primary, secondary, tertiary, success, info, warning, danger;
2
+
3
+ // Maps each theme hue onto a component's --<block>-color / --<block>-on-color pair.
4
+ // Expects the component to consume those two custom properties.
5
+ //
6
+ // With $tonal: true, each hue additionally exposes the container token pair
7
+ // (--<block>-color-container / --<block>-on-color-container) for a lower-emphasis,
8
+ // tonal appearance.
9
+ //
10
+ // $modifier prefixes the hue classes, so a component with a second, independently
11
+ // colored state can reuse the same mapping (e.g. $modifier: 'checked-' emits
12
+ // `--checked-primary` … `--checked-danger`).
13
+ @mixin color-variants($block, $tonal: false, $modifier: '') {
14
+ @each $color in $colors {
15
+ &.#{$block}--#{$modifier}#{$color} {
16
+ --#{$block}-color: var(--color-#{$color});
17
+ --#{$block}-on-color: var(--color-on-#{$color});
18
+
19
+ @if $tonal {
20
+ --#{$block}-color-container: var(--color-#{$color}-container);
21
+ --#{$block}-on-color-container: var(--color-on-#{$color}-container);
22
+ }
23
+ }
24
+ }
25
+ }
26
+
27
+ // Convenience for components with a single variant layer: a `tonal` class that swaps
28
+ // the active pair to the container pair, so one fill rule serves both filled and
29
+ // tonal. Requires color-variants(..., $tonal: true).
30
+ //
31
+ // Do NOT use for a component with a second variant layer (e.g. chip's base vs
32
+ // checked variant): swapping a shared token leaks the tonal treatment across the
33
+ // state boundary. Such components consume the container pair directly per rule.
34
+ @mixin tonal-swap($block, $modifier: '') {
35
+ &.#{$block}--#{$modifier}tonal {
36
+ --#{$block}-color: var(--#{$block}-color-container);
37
+ --#{$block}-on-color: var(--#{$block}-on-color-container);
38
+ }
39
+ }
@@ -1,3 +1,4 @@
1
+ @forward 'color-variants';
1
2
  @forward 'focus-ring';
2
3
  @forward 'motion';
3
4
  @forward 'panel-open';