@swisspost/design-system-styles 6.3.0 → 6.4.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.
@@ -9,6 +9,7 @@
9
9
  @use 'button';
10
10
  @use 'button-group';
11
11
  @use 'card';
12
+ @use 'choice-control-card';
12
13
  @use 'carousel';
13
14
  @use 'close';
14
15
  @use 'elevation';
@@ -0,0 +1,146 @@
1
+ @use '../variables/color';
2
+ @use '../variables/commons';
3
+ @use '../variables/spacing';
4
+ @use '../mixins/utilities';
5
+
6
+ .radio-button-card,
7
+ .checkbox-button-card {
8
+ --post-card-select--hover-bg: #{color.$gray-10};
9
+
10
+ position: relative;
11
+ display: flex;
12
+ gap: 0 spacing.$size-mini;
13
+
14
+ width: 100%;
15
+
16
+ color: color.$gray-80;
17
+ background-color: color.$white;
18
+ border: 2px solid color.$gray-60;
19
+ border-radius: commons.$border-radius;
20
+ padding: spacing.$size-regular;
21
+ transition: color 100ms ease-in-out, background-color 100ms ease-in-out,
22
+ border-color 100ms ease-in-out;
23
+
24
+ // Checked
25
+ &:where(:has(input:checked), .checked) {
26
+ --post-card-select--hover-bg: #{color.$yellow};
27
+ background-color: color.$yellow;
28
+ border-color: color.$gray-60;
29
+
30
+ input {
31
+ background-color: color.$white !important;
32
+ }
33
+ }
34
+
35
+ // Focus
36
+ &:where(:has(input:focus-visible), .focused) {
37
+ background-color: var(--post-card-select--hover-bg);
38
+ outline: 2px solid color.$black;
39
+ outline-offset: 2px;
40
+ border-color: color.$black;
41
+
42
+ input {
43
+ border-color: color.$black;
44
+ }
45
+ }
46
+
47
+ // Hover
48
+ &:where(:hover:not(:has(input:disabled)), :hover:not(.disabled)) {
49
+ border-color: color.$black;
50
+ color: color.$black;
51
+ background-color: var(--post-card-select--hover-bg);
52
+
53
+ input {
54
+ border-color: color.$black;
55
+ }
56
+
57
+ @include utilities.high-contrast-mode() {
58
+ border-color: Highlight;
59
+ transition: none;
60
+ }
61
+ }
62
+
63
+ // Disabled
64
+ &:has(input:disabled),
65
+ &.disabled {
66
+ border-color: color.$gray-20;
67
+ color: color.$gray-40 !important;
68
+
69
+ > * {
70
+ cursor: default;
71
+ }
72
+ }
73
+
74
+ &:has(input:disabled:checked),
75
+ &.disabled.checked {
76
+ background-color: color.$gray-10;
77
+ }
78
+
79
+ // Error
80
+ &:has(input[aria-invalid]),
81
+ &:has(input.is-invalid),
82
+ &.is-invalid {
83
+ color: color.$error;
84
+ border-color: color.$error;
85
+
86
+ ~ .invalid-feedback {
87
+ display: block;
88
+ }
89
+ }
90
+
91
+ &:last-child {
92
+ margin-bottom: 0;
93
+ }
94
+
95
+ > * {
96
+ cursor: pointer;
97
+ }
98
+
99
+ post-icon {
100
+ width: 2em;
101
+ height: 2em;
102
+ margin-left: spacing.$size-mini;
103
+ pointer-events: none;
104
+ }
105
+
106
+ input {
107
+ border-color: color.$gray-80;
108
+ background-color: color.$white;
109
+ transition: border-color 100ms ease-in-out;
110
+ grid-column: 1 / 2;
111
+
112
+ &:focus {
113
+ box-shadow: none !important;
114
+ }
115
+ }
116
+
117
+ .form-check-label {
118
+ padding-left: 0;
119
+
120
+ &::before {
121
+ // This spans up the click area of the label to the whole
122
+ // card in order to make it clickable natively.
123
+ content: '';
124
+ position: absolute;
125
+ inset: -2px;
126
+ }
127
+
128
+ span {
129
+ // Lift spans above the before element to make them selectable
130
+ position: relative;
131
+ }
132
+ }
133
+
134
+ input,
135
+ .form-check-label {
136
+ margin-block: 0.25rem;
137
+ }
138
+
139
+ // Align input and label if there is an icon
140
+ &:has(post-icon) {
141
+ input,
142
+ .form-check-label {
143
+ margin-top: 0.25rem;
144
+ }
145
+ }
146
+ }
@@ -5,6 +5,7 @@
5
5
  @use './../variables/components/datepicker';
6
6
  @use './../variables/components/forms';
7
7
  @use './../variables/commons';
8
+ @use './../mixins/icons' as icons-mx;
8
9
 
9
10
  ngb-datepicker {
10
11
  // Conversion for compatibility
@@ -131,7 +132,9 @@ span.ngb-dp-navigation-chevron {
131
132
  width: forms.$input-height-inner;
132
133
  background: transparent;
133
134
 
135
+ .pi-3203,
134
136
  .pi-calendar {
137
+ @include icons-mx.pi(3203);
135
138
  width: datepicker.$ngb-dp-icon-size;
136
139
  height: datepicker.$ngb-dp-icon-size;
137
140
  transform: none;
@@ -142,6 +145,7 @@ span.ngb-dp-navigation-chevron {
142
145
  height: forms.$input-height-inner-sm;
143
146
  width: forms.$input-height-inner-sm;
144
147
 
148
+ .pi-3203,
145
149
  .pi-calendar {
146
150
  width: datepicker.$ngb-dp-icon-size-sm;
147
151
  height: datepicker.$ngb-dp-icon-size-sm;
@@ -158,6 +162,7 @@ span.ngb-dp-navigation-chevron {
158
162
  height: forms.$input-height-inner-lg;
159
163
  width: forms.$input-height-inner-lg;
160
164
 
165
+ .pi-3203,
161
166
  .pi-calendar {
162
167
  width: datepicker.$ngb-dp-icon-size-lg;
163
168
  height: datepicker.$ngb-dp-icon-size-lg;
@@ -200,40 +205,63 @@ input[ngbDatepicker] {
200
205
  }
201
206
  }
202
207
 
203
- .form-control[ngbDatepicker] {
208
+ .form-control[ngbdatepicker] {
209
+ padding-right: 3rem;
210
+
204
211
  &.is-invalid,
205
212
  &.is-valid,
206
213
  &.show-ng-validation.ng-touched.ng-invalid,
207
214
  &.show-ng-validation.ng-touched.ng-valid {
208
- padding-right: 1rem;
209
215
  background-position: calc(100% - #{forms.$input-height-inner}) center;
210
216
  }
211
217
 
218
+ &.is-invalid {
219
+ padding-right: 5rem;
220
+ }
221
+
212
222
  .form-floating > &,
213
223
  &.form-control-lg {
224
+ padding-right: 4rem;
225
+
214
226
  &.is-invalid,
215
227
  &.is-valid,
216
228
  &.show-ng-validation.ng-touched.ng-invalid,
217
229
  &.show-ng-validation.ng-touched.ng-valid {
218
230
  background-position: calc(100% - #{forms.$input-height-inner-lg}) center !important;
219
231
  }
232
+
233
+ &.is-invalid {
234
+ padding-right: 6rem;
235
+ }
220
236
  }
221
237
 
222
238
  &.form-control-rg {
239
+ padding-right: 2.5rem;
240
+
223
241
  &.is-invalid,
224
242
  &.is-valid,
225
243
  &.show-ng-validation.ng-touched.ng-invalid,
226
244
  &.show-ng-validation.ng-touched.ng-valid {
227
245
  background-position: calc(100% - #{forms.$input-height-inner-rg}) center;
228
246
  }
247
+
248
+ &.is-invalid {
249
+ padding-right: 4.5rem;
250
+ }
229
251
  }
230
252
 
231
253
  &.form-control-sm {
254
+ padding-right: 2rem;
255
+
232
256
  &.is-invalid,
233
257
  &.is-valid,
234
258
  &.show-ng-validation.ng-touched.ng-invalid,
235
259
  &.show-ng-validation.ng-touched.ng-valid {
236
260
  background-position: calc(100% - #{forms.$input-height-inner-sm}) center;
237
261
  }
262
+
263
+ &.is-invalid {
264
+ padding-right: 3.5rem;
265
+ }
238
266
  }
239
267
  }
@@ -43,20 +43,41 @@
43
43
  }
44
44
  }
45
45
 
46
+ $gray-arrow-down: icons.get-colored-svg-url('2052', color.$gray-80);
47
+ $white-arrow-down: icons.get-colored-svg-url('2052', color.$white);
48
+ $gray-arrow-up: icons.get-colored-svg-url('2051', color.$gray-80);
49
+ $white-arrow-up: icons.get-colored-svg-url('2051', color.$white);
50
+ $hcm-arrow-down: icons.get-colored-svg-url('2052', buttonText);
51
+ $hcm-arrow-up: icons.get-colored-svg-url('2052', buttonText);
52
+
46
53
  .dropdown-toggle {
47
54
  &::after {
48
55
  @extend %toggler-icon;
49
- background-image: url(icons.get-colored-svg-url('2052', color.$gray-80));
56
+ background-image: url($gray-arrow-down);
57
+ @include utilities.high-contrast-mode() {
58
+ background-image: url($hcm-arrow-down);
59
+ }
60
+ }
61
+
62
+ &.btn-primary::after {
63
+ background-image: url($white-arrow-down);
50
64
  @include utilities.high-contrast-mode() {
51
- background-image: url(icons.get-colored-svg-url('2052', color.$white));
65
+ background-image: url($hcm-arrow-down);
52
66
  }
53
67
  }
54
68
 
55
69
  &[aria-expanded='true'] {
56
70
  &::after {
57
- background-image: url(icons.get-colored-svg-url('2051', color.$gray-80));
71
+ background-image: url($gray-arrow-up);
72
+ @include utilities.high-contrast-mode() {
73
+ background-image: url($hcm-arrow-up);
74
+ }
75
+ }
76
+
77
+ &.btn-primary::after {
78
+ background-image: url($white-arrow-up);
58
79
  @include utilities.high-contrast-mode() {
59
- background-image: url(icons.get-colored-svg-url('2051', color.$white));
80
+ background-image: url($hcm-arrow-up);
60
81
  }
61
82
  }
62
83
  }
@@ -64,17 +85,31 @@
64
85
  .dropup & {
65
86
  &::after {
66
87
  @extend %toggler-icon;
67
- background-image: url(icons.get-colored-svg-url('2051', color.$gray-80));
88
+ background-image: url($gray-arrow-up);
68
89
  @include utilities.high-contrast-mode() {
69
- background-image: url(icons.get-colored-svg-url('2051', color.$white));
90
+ background-image: url($hcm-arrow-up);
91
+ }
92
+ }
93
+
94
+ &.btn-primary::after {
95
+ background-image: url($white-arrow-up);
96
+ @include utilities.high-contrast-mode() {
97
+ background-image: url($hcm-arrow-up);
70
98
  }
71
99
  }
72
100
 
73
101
  &[aria-expanded='true'] {
74
102
  &::after {
75
- background-image: url(icons.get-colored-svg-url('2052', color.$gray-80));
103
+ background-image: url($gray-arrow-down);
104
+ @include utilities.high-contrast-mode() {
105
+ background-image: url($hcm-arrow-down);
106
+ }
107
+ }
108
+
109
+ &.btn-primary::after {
110
+ background-image: url($white-arrow-down);
76
111
  @include utilities.high-contrast-mode() {
77
- background-image: url(icons.get-colored-svg-url('2052', color.$white));
112
+ background-image: url($hcm-arrow-down);
78
113
  }
79
114
  }
80
115
  }
@@ -51,9 +51,9 @@
51
51
  cursor: form-check.$form-check-label-cursor;
52
52
  }
53
53
 
54
- &[type='radio']:checked,
55
- &[type='checkbox']:checked,
56
- &[type='checkbox']:indeterminate {
54
+ &[type='radio']:checked:not(.is-invalid),
55
+ &[type='checkbox']:checked:not(.is-invalid),
56
+ &[type='checkbox']:indeterminate:not(.is-invalid) {
57
57
  @include form-checks-mixins.form-check-color(form-check.$form-check-input-checked-color);
58
58
  }
59
59
 
@@ -71,8 +71,8 @@
71
71
  }
72
72
  }
73
73
 
74
- &[type='radio']:hover:not(:disabled),
75
- &[type='checkbox']:hover:not(:disabled) {
74
+ &[type='radio']:hover:not(:disabled):not(.is-invalid),
75
+ &[type='checkbox']:hover:not(:disabled):not(.is-invalid) {
76
76
  @include form-checks-mixins.form-check-color(form-check.$form-check-input-hover-color);
77
77
  }
78
78
  }
@@ -0,0 +1,152 @@
1
+ @forward './../../variables/options';
2
+
3
+ @use './../../mixins/color' as color-mx;
4
+ @use './../../mixins/utilities' as utilities-mx;
5
+ @use './../../variables/color';
6
+ @use './../../variables/spacing';
7
+ @use './../../variables/components/nav';
8
+
9
+ .tab-title {
10
+ display: inline-block;
11
+ position: relative;
12
+ box-sizing: border-box;
13
+ padding: nav.$nav-link-padding;
14
+ transition: background-color 100ms;
15
+ border-right: 1px solid transparent;
16
+ border-left: 1px solid transparent;
17
+ outline-color: currentColor;
18
+ opacity: 0.7;
19
+ color: var(--post-contrast-color);
20
+ text-decoration: none;
21
+
22
+ &:focus {
23
+ background-color: unset;
24
+ color: var(--post-contrast-color);
25
+ }
26
+
27
+ &:hover {
28
+ opacity: 1;
29
+ background-color: nav.$nav-tabs-link-active-bg;
30
+ color: var(--post-contrast-color);
31
+ }
32
+
33
+ // same styles as focus, can't use placeholder here because focus-visible can't be described outside of the support condition
34
+ &:focus-visible {
35
+ outline: transparent;
36
+ opacity: 1;
37
+ background-color: nav.$nav-tabs-link-active-bg;
38
+ color: var(--post-contrast-color);
39
+ box-shadow: none;
40
+
41
+ &::after {
42
+ content: '';
43
+ display: block;
44
+ position: absolute;
45
+ top: nav.$nav-tabs-focus-box-shadow-width;
46
+ right: nav.$nav-tabs-focus-box-shadow-width - 1px;
47
+ bottom: 0;
48
+ left: nav.$nav-tabs-focus-box-shadow-width - 1px;
49
+ box-shadow: nav.$nav-tabs-focus-box-shadow;
50
+ }
51
+ }
52
+
53
+ &.active {
54
+ z-index: 1; // Lift above the line and make focus visible all around
55
+ border-right-color: nav.$nav-tabs-border-color;
56
+ border-left-color: nav.$nav-tabs-border-color;
57
+ opacity: 1;
58
+ background-color: nav.$nav-tabs-link-active-bg;
59
+ color: var(--post-contrast-color);
60
+ font-weight: 700;
61
+
62
+ // Create a line that does not suffer from border corner mitering
63
+ &::before {
64
+ content: '';
65
+ display: block;
66
+ position: absolute;
67
+ top: 0;
68
+ right: -1px;
69
+ left: -1px;
70
+ height: spacing.$size-micro;
71
+ background-color: nav.$nav-tabs-link-active-border-color;
72
+ }
73
+ }
74
+
75
+ // Tabs with dark backgrounds
76
+ @include color-mx.on-dark-background() {
77
+ &:hover {
78
+ background-color: rgba(nav.$nav-tabs-link-active-bg, 0.2);
79
+ }
80
+
81
+ &:focus-visible {
82
+ background-color: rgba(nav.$nav-tabs-link-active-bg, 0.2);
83
+ }
84
+ }
85
+
86
+ @include utilities-mx.high-contrast-mode() {
87
+ opacity: 1;
88
+ border-left-color: Canvas;
89
+ border-right-color: Canvas;
90
+ color: LinkText;
91
+
92
+ &:hover,
93
+ &:focus,
94
+ &:focus-within,
95
+ &:focus-visible {
96
+ outline: spacing.$size-line solid Highlight;
97
+ outline-offset: -(spacing.$size-micro);
98
+ }
99
+
100
+ &.active {
101
+ border-left-color: ButtonText;
102
+ border-right-color: ButtonText;
103
+ color: Highlight;
104
+
105
+ &::before {
106
+ background-color: Highlight;
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ // Careful, this generates a lot of code
113
+ @each $key, $color in color.$background-colors {
114
+ .bg-#{$key} {
115
+ .tab-title {
116
+ background-color: $color;
117
+
118
+ &.active {
119
+ background-color: $color;
120
+ }
121
+ }
122
+
123
+ .nav-item {
124
+ background-color: $color;
125
+ }
126
+ }
127
+ }
128
+
129
+ [class*='bg-'] .tab-title.active {
130
+ &:focus {
131
+ &::after {
132
+ background-color: rgba(255, 255, 255, 0.2);
133
+ }
134
+ }
135
+
136
+ // write supports for selectors this way: https://stackoverflow.com/a/62666132
137
+ // need to include * otherwise it throws build error
138
+ @supports #{'\selector(*:focus-visible)'} {
139
+ &:focus {
140
+ &::after {
141
+ background-color: unset;
142
+ }
143
+ }
144
+
145
+ // same styles as focus, can't use placeholder here because focus-visible can't be described outside of the support condition
146
+ &:focus-visible {
147
+ &::after {
148
+ background-color: rgba(255, 255, 255, 0.2);
149
+ }
150
+ }
151
+ }
152
+ }
@@ -0,0 +1,69 @@
1
+ @forward './../../variables/options';
2
+
3
+ @use './../../mixins/utilities' as utilities-mx;
4
+ @use './../../variables/color';
5
+ @use './../../variables/spacing';
6
+ @use './../../variables/components/nav';
7
+
8
+ .tabs-wrapper {
9
+ position: relative;
10
+ padding-top: spacing.$spacer;
11
+ border: 0;
12
+ background-color: color.$gray-background-light;
13
+
14
+ // Create a line that lies below the active but above the passive elements
15
+ // This way hover works smoothly with the background color
16
+ &::after {
17
+ content: '';
18
+ position: absolute;
19
+ bottom: 0;
20
+ width: 100%;
21
+ height: 1px;
22
+ background-color: nav.$nav-tabs-border-color;
23
+ }
24
+
25
+ // Small hack to save a lot of code and provide a lot of flexibility to tabs coloring
26
+ .tabs {
27
+ background-color: transparent !important;
28
+ }
29
+
30
+ @include utilities-mx.high-contrast-mode() {
31
+ &::after {
32
+ background-color: ButtonBorder;
33
+ }
34
+ }
35
+ }
36
+
37
+ .tabs {
38
+ @include utilities-mx.reset-list;
39
+ display: flex;
40
+ flex-wrap: nowrap;
41
+ overflow-x: auto;
42
+
43
+ /* prevent scroll chaining on x scroll */
44
+ overscroll-behavior-x: contain;
45
+ white-space: nowrap;
46
+
47
+ // Scrolling fix to make the tabs scroll a little more so the right most tab is not
48
+ // flush with the window border
49
+ &::after {
50
+ content: '';
51
+ display: block;
52
+ flex: 1 0 auto;
53
+ width: nav.$nav-link-padding-x;
54
+ }
55
+ }
56
+
57
+ .tab-content {
58
+ padding-top: spacing.$spacer;
59
+ padding-bottom: spacing.$spacer;
60
+ }
61
+
62
+ // Careful, this generates a lot of code
63
+ @each $key, $color in color.$background-colors {
64
+ .bg-#{$key} {
65
+ .tabs-wrapper {
66
+ background-color: $color;
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,2 @@
1
+ @use 'tabs-wrapper';
2
+ @use 'tab-title';
@@ -1,10 +1,20 @@
1
1
  @use 'sass:map';
2
+ @use 'sass:meta';
2
3
 
3
4
  @use './color';
4
5
  @use './utilities';
5
6
  @use './../variables/icons';
6
7
 
7
8
  @function add-fill-color($svg, $color) {
9
+ @if (meta.type-of($color) == string) {
10
+ @return set-svg-properties(
11
+ $svg,
12
+ (
13
+ 'fill': $color,
14
+ )
15
+ );
16
+ }
17
+
8
18
  $opacity: alpha($color);
9
19
  $color: color.get-hex-string($color);
10
20
  $clean-color: utilities.replace('#{$color}', '#', '%23');