@thalassic/themes 22.16.0 → 22.17.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 (37) hide show
  1. package/package.json +1 -1
  2. package/themes/thalassic/components/_confirm.scss +28 -3
  3. package/themes/thalassic/components/_odometer.scss +1 -14
  4. package/themes/thalassic/components/_password.scss +1 -1
  5. package/themes/thalassic/components/_table.scss +29 -2
  6. package/themes/thalassic/components/_virtual-scroll.scss +11 -0
  7. package/themes/thalassic/components/autocomplete/_autocomplete-panel.scss +21 -0
  8. package/themes/thalassic/components/calendar/_agenda.scss +3 -2
  9. package/themes/thalassic/components/calendar/_calendar.scss +27 -0
  10. package/themes/thalassic/components/calendar/_compact.scss +21 -0
  11. package/themes/thalassic/components/calendar/_lines.scss +23 -0
  12. package/themes/thalassic/components/calendar/_month-view.scss +132 -6
  13. package/themes/thalassic/components/calendar/_time-grid.scss +6 -5
  14. package/themes/thalassic/components/dialog/_dialog.scss +43 -0
  15. package/themes/thalassic/components/drawer/_drawer-side.scss +65 -0
  16. package/themes/thalassic/components/drawer/_drawer.scss +16 -0
  17. package/themes/thalassic/components/index.scss +3 -0
  18. package/themes/thalassic/components/multi-select/_multi-select-panel.scss +21 -0
  19. package/themes/thalassic/components/pagination/_pagination.scss +1 -1
  20. package/themes/thalassic/components/progress/_index.scss +3 -0
  21. package/themes/thalassic/components/progress/_progress-color.scss +5 -0
  22. package/themes/thalassic/components/progress/_progress-size.scss +13 -0
  23. package/themes/thalassic/components/progress/_progress.scss +38 -0
  24. package/themes/thalassic/components/rating/_index.scss +3 -0
  25. package/themes/thalassic/components/rating/_rating-color.scss +43 -0
  26. package/themes/thalassic/components/rating/_rating-size.scss +13 -0
  27. package/themes/thalassic/components/rating/_rating.scss +144 -0
  28. package/themes/thalassic/components/select/_select-panel.scss +21 -0
  29. package/themes/thalassic/components/stepper/_index.scss +1 -0
  30. package/themes/thalassic/components/stepper/_stepper-color.scss +34 -152
  31. package/themes/thalassic/components/stepper/_stepper-label-position.scss +41 -0
  32. package/themes/thalassic/components/stepper/_stepper-orientation.scss +13 -1
  33. package/themes/thalassic/components/stepper/_stepper.scss +37 -11
  34. package/themes/thalassic/components/toast/_toast.scss +4 -3
  35. package/themes/thalassic/mixins/_index.scss +2 -0
  36. package/themes/thalassic/mixins/_pop.scss +26 -0
  37. package/themes/thalassic/mixins/_visually-hidden.scss +19 -0
@@ -27,20 +27,85 @@
27
27
  max-height: 100dvh;
28
28
  }
29
29
 
30
+ // Sized by content along the main axis, capped so a short panel hugs its content
31
+ // while a tall one still scrolls instead of filling the viewport.
32
+ &--auto {
33
+ &.tls-drawer--start,
34
+ &.tls-drawer--end {
35
+ width: fit-content;
36
+ max-width: 90dvw;
37
+ }
38
+
39
+ &.tls-drawer--top,
40
+ &.tls-drawer--bottom {
41
+ height: fit-content;
42
+ max-height: 90dvh;
43
+ }
44
+ }
45
+
46
+ // Each side pins the grabber to the panel's inner edge (the one facing the
47
+ // viewport), centered along the cross axis. Logical insets keep the side panels'
48
+ // placement correct in RTL, where the physical edges swap.
30
49
  &--start {
31
50
  --tls-drawer-offset: translateX(-100%);
51
+
52
+ .tls-drawer__grabber {
53
+ inset-inline-end: var(--tls-drawer-grabber-inset);
54
+ inset-block: 0;
55
+
56
+ width: var(--tls-drawer-grabber-thickness);
57
+ height: var(--tls-drawer-grabber-length);
58
+
59
+ margin-block: auto;
60
+ }
32
61
  }
33
62
 
34
63
  &--end {
35
64
  --tls-drawer-offset: translateX(100%);
65
+
66
+ .tls-drawer__grabber {
67
+ inset-inline-start: var(--tls-drawer-grabber-inset);
68
+ inset-block: 0;
69
+
70
+ width: var(--tls-drawer-grabber-thickness);
71
+ height: var(--tls-drawer-grabber-length);
72
+
73
+ margin-block: auto;
74
+ }
36
75
  }
37
76
 
38
77
  &--top {
39
78
  --tls-drawer-offset: translateY(-100%);
79
+
80
+ // Keeps the content clear of a device cutout on the pinned edge.
81
+ padding-top: env(safe-area-inset-top);
82
+
83
+ .tls-drawer__grabber {
84
+ bottom: var(--tls-drawer-grabber-inset);
85
+ inset-inline: 0;
86
+
87
+ width: var(--tls-drawer-grabber-length);
88
+ height: var(--tls-drawer-grabber-thickness);
89
+
90
+ margin-inline: auto;
91
+ }
40
92
  }
41
93
 
42
94
  &--bottom {
43
95
  --tls-drawer-offset: translateY(100%);
96
+
97
+ // Keeps the content clear of the home indicator on the pinned edge.
98
+ padding-bottom: env(safe-area-inset-bottom);
99
+
100
+ .tls-drawer__grabber {
101
+ top: var(--tls-drawer-grabber-inset);
102
+ inset-inline: 0;
103
+
104
+ width: var(--tls-drawer-grabber-length);
105
+ height: var(--tls-drawer-grabber-thickness);
106
+
107
+ margin-inline: auto;
108
+ }
44
109
  }
45
110
 
46
111
  // Rounds the inner edge only (the two corners facing the viewport). Opt-in; the
@@ -34,6 +34,9 @@
34
34
  --tls-drawer-padding: var(--spacing-6);
35
35
  --tls-drawer-close-size: 16px;
36
36
  --tls-drawer-close-padding: var(--spacing-4);
37
+ --tls-drawer-grabber-length: 36px;
38
+ --tls-drawer-grabber-thickness: 5px;
39
+ --tls-drawer-grabber-inset: var(--spacing-2);
37
40
 
38
41
  position: relative;
39
42
 
@@ -93,6 +96,17 @@
93
96
  }
94
97
  }
95
98
 
99
+ // Grabber pill, the visual affordance of a sheet-style panel. Placement along the
100
+ // panel's inner edge is side-dependent and lives with the side modifiers.
101
+ &__grabber {
102
+ position: absolute;
103
+ z-index: 1;
104
+
105
+ border-radius: calc(var(--tls-drawer-grabber-thickness) / 2);
106
+
107
+ background-color: var(--color-outline-variant);
108
+ }
109
+
96
110
  &__header {
97
111
  padding: var(--tls-drawer-padding) var(--tls-drawer-padding) 0;
98
112
  }
@@ -108,6 +122,8 @@
108
122
  flex: 1;
109
123
  padding: var(--spacing-4) var(--tls-drawer-padding);
110
124
  overflow-y: auto;
125
+ // Scrolling the drawer's content must not chain into scrolling the page behind it.
126
+ overscroll-behavior: contain;
111
127
  }
112
128
 
113
129
  &__footer {
@@ -41,7 +41,9 @@
41
41
  @forward 'input-number';
42
42
  @forward 'pin-input';
43
43
  @forward 'popover';
44
+ @forward 'progress';
44
45
  @forward 'radio-button';
46
+ @forward 'rating';
45
47
  @forward 'rich-text-editor';
46
48
  @forward 'skeleton';
47
49
  @forward 'slider';
@@ -49,3 +51,4 @@
49
51
  @forward 'table';
50
52
  @forward 'toggle-button';
51
53
  @forward 'toggle-group';
54
+ @forward 'virtual-scroll';
@@ -23,6 +23,27 @@
23
23
  list-style: none;
24
24
 
25
25
  @include mixins.panel-open;
26
+
27
+ &--virtual {
28
+ // The virtual-scroll viewport inside is the scroll container; the panel only clips
29
+ // to its rounded corners.
30
+ overflow: hidden;
31
+
32
+ // Windowing positions every row at a fixed offset, so each row must occupy exactly
33
+ // the item size the viewport publishes — a taller custom option template is clipped
34
+ // rather than allowed to drift the rows out of place.
35
+ .tls-multi-select__option {
36
+ height: var(--tls-virtual-scroll-item-size);
37
+
38
+ box-sizing: border-box;
39
+
40
+ overflow: hidden;
41
+ }
42
+
43
+ .tls-multi-select__option-button {
44
+ height: 100%;
45
+ }
46
+ }
26
47
  }
27
48
 
28
49
  .tls-multi-select__option {
@@ -4,7 +4,7 @@
4
4
  --tls-pagination-gap: 16px;
5
5
  --tls-pagination-color: var(--color-secondary);
6
6
  --tls-pagination-radius: 4px;
7
- --tls-pagination-hover-outline: 1px solid var(--color-lines);
7
+ --tls-pagination-hover-outline: 1px solid var(--color-outline-variant);
8
8
 
9
9
  --tls-pagination-item-border-color: var(--color-outline-variant);
10
10
 
@@ -0,0 +1,3 @@
1
+ @forward 'progress';
2
+ @forward 'progress-color';
3
+ @forward 'progress-size';
@@ -0,0 +1,5 @@
1
+ @use '../../mixins' as mixins;
2
+
3
+ .tls-progress {
4
+ @include mixins.color-variants('tls-progress');
5
+ }
@@ -0,0 +1,13 @@
1
+ .tls-progress {
2
+ &.tls-progress--sm {
3
+ --tls-progress-height: 4px;
4
+ }
5
+
6
+ &.tls-progress--md {
7
+ --tls-progress-height: 8px;
8
+ }
9
+
10
+ &.tls-progress--lg {
11
+ --tls-progress-height: 12px;
12
+ }
13
+ }
@@ -0,0 +1,38 @@
1
+ @use '../../mixins' as mixins;
2
+
3
+ .tls-progress {
4
+ --tls-progress-track-color: var(--color-surface-variant);
5
+
6
+ // A track piece: the single full-width bar in continuous mode, one pill per
7
+ // step in segmented mode. Fully rounded ends at every height.
8
+ .tls-progress-segment {
9
+ height: var(--tls-progress-height);
10
+
11
+ flex: 1 1 0;
12
+
13
+ border-radius: var(--radius-xl);
14
+
15
+ background-color: var(--tls-progress-track-color);
16
+
17
+ overflow: hidden;
18
+
19
+ @include mixins.motion {
20
+ transition: flex-grow var(--motion-fast) var(--motion-ease-out);
21
+ }
22
+ }
23
+
24
+ // The filled share of a segment, clipped by the segment's rounding. Anchored
25
+ // to inline-start so the bar grows from the leading edge in both layout
26
+ // directions.
27
+ .tls-progress-fill {
28
+ height: 100%;
29
+
30
+ border-radius: inherit;
31
+
32
+ background-color: var(--tls-progress-color);
33
+
34
+ @include mixins.motion {
35
+ transition: inline-size var(--motion-fast) var(--motion-ease-out);
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,3 @@
1
+ @forward 'rating';
2
+ @forward 'rating-size';
3
+ @forward 'rating-color';
@@ -0,0 +1,43 @@
1
+ @use 'sass:map';
2
+
3
+ @use '../../../../palettes' as common-palettes;
4
+
5
+ .tls-rating {
6
+ &.tls-rating--primary {
7
+ --tls-rating-fill-color: var(--color-primary);
8
+ }
9
+
10
+ &.tls-rating--secondary {
11
+ --tls-rating-fill-color: var(--color-secondary);
12
+ }
13
+
14
+ &.tls-rating--tertiary {
15
+ --tls-rating-fill-color: var(--color-tertiary);
16
+ }
17
+
18
+ &.tls-rating--success {
19
+ --tls-rating-fill-color: var(--color-success);
20
+ }
21
+
22
+ &.tls-rating--info {
23
+ --tls-rating-fill-color: var(--color-info);
24
+ }
25
+
26
+ &.tls-rating--warning {
27
+ --tls-rating-fill-color: var(--color-warning);
28
+ }
29
+
30
+ &.tls-rating--danger {
31
+ --tls-rating-fill-color: var(--color-danger);
32
+ }
33
+
34
+ // Classic star gold, straight from the yellow palette rather than the
35
+ // `warning` semantic (whose light-mode value is a dark olive, not gold).
36
+ &.tls-rating--golden {
37
+ --tls-rating-fill-color: #{map.get(common-palettes.$yellow, 70)};
38
+
39
+ :root.tls-dark & {
40
+ --tls-rating-fill-color: #{map.get(common-palettes.$yellow, 80)};
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,13 @@
1
+ .tls-rating {
2
+ &.tls-rating--sm {
3
+ --tls-rating-star-size: 16px;
4
+ }
5
+
6
+ &.tls-rating--md {
7
+ --tls-rating-star-size: 20px;
8
+ }
9
+
10
+ &.tls-rating--lg {
11
+ --tls-rating-star-size: 24px;
12
+ }
13
+ }
@@ -0,0 +1,144 @@
1
+ @use '../../mixins' as mixins;
2
+
3
+ .tls-rating {
4
+ --tls-rating-star-size: 20px;
5
+ --tls-rating-hover-scale: 1.15;
6
+ --tls-rating-pop-scale: 1.25;
7
+
8
+ // Fallback only — the component always emits a `--<color>` modifier, and the
9
+ // default `golden` value lives in the color partial alongside the others.
10
+ --tls-rating-fill-color: var(--color-primary);
11
+ --tls-rating-empty-color: var(--color-surface-variant);
12
+ // Ghost rendering of the hover preview's delta: the fill color, mostly transparent.
13
+ --tls-rating-preview-color: color-mix(in srgb, var(--tls-rating-fill-color) 45%, transparent);
14
+
15
+ .tls-rating-star {
16
+ position: relative;
17
+
18
+ display: inline-flex;
19
+ }
20
+
21
+ .tls-rating-icons {
22
+ position: relative;
23
+
24
+ display: inline-flex;
25
+
26
+ border-radius: var(--radius-sm);
27
+
28
+ color: var(--tls-rating-empty-color);
29
+
30
+ @include mixins.motion {
31
+ transition: transform var(--motion-fast) var(--motion-ease-spring);
32
+ }
33
+ }
34
+
35
+ // The star box: a fixed square holding either the built-in icon or a
36
+ // consumer template, whose content is centered and sized to the star.
37
+ .tls-rating-icon {
38
+ width: var(--tls-rating-star-size);
39
+ height: var(--tls-rating-star-size);
40
+
41
+ display: inline-flex;
42
+ flex-shrink: 0;
43
+ align-items: center;
44
+ justify-content: center;
45
+
46
+ font-size: var(--tls-rating-star-size);
47
+ line-height: 1;
48
+
49
+ .tls-icon {
50
+ width: 100%;
51
+ height: 100%;
52
+ }
53
+ }
54
+
55
+ // The filled layer sits over the outline star, clipped to the displayed
56
+ // value's share of the box. Anchored to inline-start so the visible part is
57
+ // the leading side and the clipped part the trailing side in both layout
58
+ // directions; the inner icon keeps the star's full size so clipping narrows
59
+ // the window, not the drawing.
60
+ .tls-rating-fill {
61
+ position: absolute;
62
+ inset-block: 0;
63
+ inset-inline-start: 0;
64
+
65
+ overflow: hidden;
66
+ color: var(--tls-rating-fill-color);
67
+
68
+ &--ghost {
69
+ color: var(--tls-rating-preview-color);
70
+ }
71
+ }
72
+
73
+ // The radios are the real targets: invisible, laid over their slice of the
74
+ // star and stretched across half the surrounding gap on each side, so the row
75
+ // is one continuous hit surface with no dead zones between stars.
76
+ .tls-rating-input {
77
+ position: absolute;
78
+ inset-block: 0;
79
+ inset-inline: calc(var(--tls-rating-gap) / -2);
80
+
81
+ margin: 0;
82
+
83
+ appearance: none;
84
+
85
+ opacity: 0;
86
+
87
+ cursor: pointer;
88
+
89
+ &--start {
90
+ inset-inline-end: 50%;
91
+ }
92
+
93
+ &--end {
94
+ inset-inline-start: 50%;
95
+ }
96
+
97
+ // Tap-target expansion on the block axis only, mirroring the touch-target
98
+ // mixin's gating. The mixin's symmetric overflow cannot apply here: growing
99
+ // the inline axis would overlap the adjacent option's hit area and steal its
100
+ // edge taps, so the inline extent stays the option's own slice.
101
+ @media (pointer: coarse) {
102
+ :root:not([data-touch-targets='off']) & {
103
+ inset-block: min(
104
+ 0px,
105
+ calc((var(--tls-rating-star-size) - var(--control-touch-target)) / 2)
106
+ );
107
+ }
108
+ }
109
+ }
110
+
111
+ .tls-rating-star:has(.tls-rating-input:focus-visible) .tls-rating-icons {
112
+ @include mixins.focus-ring;
113
+ }
114
+
115
+ .tls-rating-star--pop .tls-rating-icons {
116
+ @include mixins.pop(var(--tls-rating-pop-scale));
117
+ }
118
+
119
+ // Grows the star under the pointer. The scale itself is ungated so the state
120
+ // still reads at every motion level; only the easing into it is (see the
121
+ // icons rule above).
122
+ &:not(.tls-rating--disabled):not(.tls-rating--readonly) .tls-rating-star:hover .tls-rating-icons {
123
+ transform: scale(var(--tls-rating-hover-scale));
124
+ }
125
+
126
+ // Form control
127
+ &.tls-rating--disabled {
128
+ .tls-rating-input {
129
+ cursor: not-allowed;
130
+ }
131
+
132
+ .tls-rating-icons {
133
+ filter: brightness(0.9);
134
+ }
135
+ }
136
+
137
+ &.tls-rating--readonly .tls-rating-input {
138
+ cursor: default;
139
+ }
140
+
141
+ &:not(.tls-rating--disabled).tls-rating--show-error {
142
+ --tls-rating-fill-color: var(--color-danger);
143
+ }
144
+ }
@@ -23,6 +23,27 @@
23
23
  list-style: none;
24
24
 
25
25
  @include mixins.panel-open;
26
+
27
+ &--virtual {
28
+ // The virtual-scroll viewport inside is the scroll container; the panel only clips
29
+ // to its rounded corners.
30
+ overflow: hidden;
31
+
32
+ // Windowing positions every row at a fixed offset, so each row must occupy exactly
33
+ // the item size the viewport publishes — a taller custom option template is clipped
34
+ // rather than allowed to drift the rows out of place.
35
+ .tls-select__option {
36
+ height: var(--tls-virtual-scroll-item-size);
37
+
38
+ box-sizing: border-box;
39
+
40
+ overflow: hidden;
41
+ }
42
+
43
+ .tls-select__option-button {
44
+ height: 100%;
45
+ }
46
+ }
26
47
  }
27
48
 
28
49
  .tls-select__option {
@@ -1,3 +1,4 @@
1
1
  @forward 'stepper';
2
2
  @forward 'stepper-color';
3
+ @forward 'stepper-label-position';
3
4
  @forward 'stepper-orientation';
@@ -1,3 +1,5 @@
1
+ @use '../../mixins/color-variants' as color-variants;
2
+
1
3
  .tls-stepper {
2
4
  @mixin _disabled-reset {
3
5
  --tls-stepper-label-color: var(--color-outline);
@@ -8,159 +10,39 @@
8
10
  }
9
11
 
10
12
  .tls-stepper-header {
11
- // Item
13
+ // Item — the states of one hue share a specificity level, so within each
14
+ // hue block order encodes precedence: active < completed < invalid <
15
+ // disabled, the later state overriding the earlier ones when combined.
12
16
  &__item {
13
- // Primary
14
- &.tls-stepper-header--primary {
15
- // Active
16
- &.tls-stepper-header__item--active {
17
- --tls-stepper-label-color: var(--color-primary);
18
- --tls-stepper-index-border-color: var(--color-primary);
19
- }
20
-
21
- // Completed
22
- &.tls-stepper-header__item--completed {
23
- --tls-stepper-index-on-color: var(--color-on-primary);
24
- --tls-stepper-index-background-color: var(--color-primary);
25
- --tls-stepper-index-border-color: var(--color-primary);
26
- --tls-stepper-divider-color: var(--color-primary);
27
- }
28
-
29
- // Disabled overrides color states
30
- &.tls-stepper-header__item--disabled {
31
- @include _disabled-reset;
32
- }
33
- }
34
-
35
- // Secondary
36
- &.tls-stepper-header--secondary {
37
- // Active
38
- &.tls-stepper-header__item--active {
39
- --tls-stepper-label-color: var(--color-secondary);
40
- --tls-stepper-index-border-color: var(--color-secondary);
41
- }
42
-
43
- // Completed
44
- &.tls-stepper-header__item--completed {
45
- --tls-stepper-index-on-color: var(--color-on-secondary);
46
- --tls-stepper-index-background-color: var(--color-secondary);
47
- --tls-stepper-index-border-color: var(--color-secondary);
48
- --tls-stepper-divider-color: var(--color-secondary);
49
- }
50
-
51
- // Disabled overrides color states
52
- &.tls-stepper-header__item--disabled {
53
- @include _disabled-reset;
54
- }
55
- }
56
-
57
- // Tertiary
58
- &.tls-stepper-header--tertiary {
59
- // Active
60
- &.tls-stepper-header__item--active {
61
- --tls-stepper-label-color: var(--color-tertiary);
62
- --tls-stepper-index-border-color: var(--color-tertiary);
63
- }
64
-
65
- // Completed
66
- &.tls-stepper-header__item--completed {
67
- --tls-stepper-index-on-color: var(--color-on-tertiary);
68
- --tls-stepper-index-background-color: var(--color-tertiary);
69
- --tls-stepper-index-border-color: var(--color-tertiary);
70
- --tls-stepper-divider-color: var(--color-tertiary);
71
- }
72
-
73
- // Disabled overrides color states
74
- &.tls-stepper-header__item--disabled {
75
- @include _disabled-reset;
76
- }
77
- }
78
-
79
- // Success
80
- &.tls-stepper-header--success {
81
- // Active
82
- &.tls-stepper-header__item--active {
83
- --tls-stepper-label-color: var(--color-success);
84
- --tls-stepper-index-border-color: var(--color-success);
85
- }
86
-
87
- // Completed
88
- &.tls-stepper-header__item--completed {
89
- --tls-stepper-index-on-color: var(--color-on-success);
90
- --tls-stepper-index-background-color: var(--color-success);
91
- --tls-stepper-index-border-color: var(--color-success);
92
- --tls-stepper-divider-color: var(--color-success);
93
- }
94
-
95
- // Disabled overrides color states
96
- &.tls-stepper-header__item--disabled {
97
- @include _disabled-reset;
98
- }
99
- }
100
-
101
- // Info
102
- &.tls-stepper-header--info {
103
- // Active
104
- &.tls-stepper-header__item--active {
105
- --tls-stepper-label-color: var(--color-info);
106
- --tls-stepper-index-border-color: var(--color-info);
107
- }
108
-
109
- // Completed
110
- &.tls-stepper-header__item--completed {
111
- --tls-stepper-index-on-color: var(--color-on-info);
112
- --tls-stepper-index-background-color: var(--color-info);
113
- --tls-stepper-index-border-color: var(--color-info);
114
- --tls-stepper-divider-color: var(--color-info);
115
- }
116
-
117
- // Disabled overrides color states
118
- &.tls-stepper-header__item--disabled {
119
- @include _disabled-reset;
120
- }
121
- }
122
-
123
- // Warning
124
- &.tls-stepper-header--warning {
125
- // Active
126
- &.tls-stepper-header__item--active {
127
- --tls-stepper-label-color: var(--color-warning);
128
- --tls-stepper-index-border-color: var(--color-warning);
129
- }
130
-
131
- // Completed
132
- &.tls-stepper-header__item--completed {
133
- --tls-stepper-index-on-color: var(--color-on-warning);
134
- --tls-stepper-index-background-color: var(--color-warning);
135
- --tls-stepper-index-border-color: var(--color-warning);
136
- --tls-stepper-divider-color: var(--color-warning);
137
- }
138
-
139
- // Disabled overrides color states
140
- &.tls-stepper-header__item--disabled {
141
- @include _disabled-reset;
142
- }
143
- }
144
-
145
- // Danger
146
- &.tls-stepper-header--danger {
147
- // Active
148
- &.tls-stepper-header__item--active {
149
- --tls-stepper-label-color: var(--color-danger);
150
- --tls-stepper-index-border-color: var(--color-danger);
151
- }
152
-
153
- // Completed
154
- &.tls-stepper-header__item--completed {
155
- --tls-stepper-index-on-color: var(--color-on-danger);
156
- --tls-stepper-index-background-color: var(--color-danger);
157
- --tls-stepper-index-border-color: var(--color-danger);
158
- --tls-stepper-divider-color: var(--color-danger);
159
- }
160
-
161
- // Disabled overrides color states
162
- &.tls-stepper-header__item--disabled {
163
- @include _disabled-reset;
17
+ @each $color in color-variants.$colors {
18
+ &.tls-stepper-header__item--#{$color} {
19
+ // Active
20
+ &.tls-stepper-header__item--active {
21
+ --tls-stepper-label-color: var(--color-#{$color});
22
+ --tls-stepper-index-border-color: var(--color-#{$color});
23
+ }
24
+
25
+ // Completed
26
+ &.tls-stepper-header__item--completed {
27
+ --tls-stepper-index-on-color: var(--color-on-#{$color});
28
+ --tls-stepper-index-background-color: var(--color-#{$color});
29
+ --tls-stepper-index-border-color: var(--color-#{$color});
30
+ --tls-stepper-divider-color: var(--color-#{$color});
31
+ }
32
+
33
+ // Invalid always the danger hue, regardless of the step's own
34
+ // color, so validation state reads over decoration.
35
+ &.tls-stepper-header__item--invalid {
36
+ --tls-stepper-label-color: var(--color-danger);
37
+ --tls-stepper-index-on-color: var(--color-danger);
38
+ --tls-stepper-index-background-color: var(--color-surface);
39
+ --tls-stepper-index-border-color: var(--color-danger);
40
+ }
41
+
42
+ // Disabled
43
+ &.tls-stepper-header__item--disabled {
44
+ @include _disabled-reset;
45
+ }
164
46
  }
165
47
  }
166
48
  }