@danske/sapphire-css 49.0.0 → 49.1.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.
@@ -1,9 +1,11 @@
1
1
  .sapphire-bulk-actions-bar {
2
2
  display: flex;
3
+ min-height: var(--sapphire-global-size-generic-180);
4
+ box-sizing: border-box;
3
5
  align-items: center;
4
6
  justify-content: space-between;
5
- padding: var(--sapphire-semantic-size-spacing-sm)
6
- var(--sapphire-semantic-size-spacing-md);
7
+ padding: var(--sapphire-semantic-size-spacing-md)
8
+ var(--sapphire-semantic-size-spacing-xl);
7
9
  /* the bg color here is a hack until the design of this changes */
8
10
  background: var(--sapphire-semantic-color-background-neutral-subtle);
9
11
  position: sticky;
@@ -58,6 +58,7 @@
58
58
 
59
59
  .sapphire-button__content {
60
60
  align-items: center;
61
+ text-align: center;
61
62
  vertical-align: middle;
62
63
  white-space: nowrap;
63
64
  user-select: none;
@@ -1,7 +1,7 @@
1
1
  .sapphire-field-group {
2
2
  display: flex;
3
3
  flex-wrap: wrap;
4
- column-gap: var(--sapphire-semantic-size-spacing-lg);
4
+ column-gap: var(--sapphire-semantic-size-spacing-xl);
5
5
  row-gap: var(--sapphire-semantic-size-spacing-sm);
6
6
  }
7
7
 
@@ -14,5 +14,5 @@
14
14
  }
15
15
 
16
16
  .sapphire-field-group--md {
17
- row-gap: var(--sapphire-semantic-size-spacing-2xs);
17
+ row-gap: var(--sapphire-semantic-size-spacing-xs);
18
18
  }
@@ -479,3 +479,34 @@ tbody .sapphire-table__row--highlighted > .sapphire-table__cell:first-child {
479
479
  right: 0;
480
480
  left: 0;
481
481
  }
482
+
483
+ /**
484
+ * Editable cell
485
+ */
486
+ .sapphire-table__cell-container--editable {
487
+ display: flex;
488
+ align-items: center;
489
+ justify-content: space-between;
490
+ gap: var(--sapphire-semantic-size-spacing-md);
491
+ }
492
+
493
+ .sapphire-table__edit-cell-popover {
494
+ display: flex;
495
+ align-items: start;
496
+ justify-content: space-between;
497
+ gap: var(--sapphire-semantic-size-spacing-sm);
498
+ }
499
+
500
+ .sapphire-table__edit-button {
501
+ /* Making sure the button does not change the row height */
502
+ margin-top: calc(-1 * var(--sapphire-semantic-size-spacing-2xs));
503
+ margin-bottom: calc(-1 * var(--sapphire-semantic-size-spacing-2xs));
504
+ visibility: hidden;
505
+ flex-shrink: 0;
506
+ }
507
+
508
+ .sapphire-table__row.is-hover .sapphire-table__edit-button,
509
+ .sapphire-table__row:hover .sapphire-table__edit-button,
510
+ .sapphire-table__row:focus-within .sapphire-table__edit-button {
511
+ visibility: visible;
512
+ }
@@ -43,6 +43,9 @@ declare const styles: {
43
43
  readonly "sapphire-table__footer": string;
44
44
  readonly "sapphire-table__footer--sticky": string;
45
45
  readonly "sapphire-table__footer--virtualized": string;
46
+ readonly "sapphire-table__cell-container--editable": string;
47
+ readonly "sapphire-table__edit-cell-popover": string;
48
+ readonly "sapphire-table__edit-button": string;
46
49
  };
47
50
  export = styles;
48
51
 
@@ -8,6 +8,7 @@
8
8
  .sapphire-tag {
9
9
  display: inline-flex;
10
10
  height: var(--sapphire-semantic-size-height-control-sm);
11
+ max-width: calc(var(--sapphire-semantic-size-height-control-sm) * 10);
11
12
  padding: 0 var(--sapphire-semantic-size-spacing-md);
12
13
  align-items: center;
13
14
  border-radius: var(--sapphire-semantic-size-height-control-sm);
@@ -59,6 +60,15 @@
59
60
  display: inline-flex;
60
61
  align-items: center;
61
62
  gap: var(--sapphire-semantic-size-spacing-xs);
63
+ min-width: 0;
64
+ flex: 1;
65
+ }
66
+
67
+ .sapphire-tag__label {
68
+ overflow: hidden;
69
+ text-overflow: ellipsis;
70
+ white-space: nowrap;
71
+ min-width: 0;
62
72
  }
63
73
 
64
74
  /* Actionable */
@@ -97,6 +107,7 @@
97
107
  display: flex;
98
108
  align-items: center;
99
109
  color: var(--sapphire-semantic-color-foreground-negative);
110
+ flex-shrink: 0;
100
111
  }
101
112
 
102
113
  /**
@@ -117,6 +128,7 @@
117
128
  margin: 0;
118
129
  padding: 0;
119
130
  background: transparent;
131
+ flex-shrink: 0;
120
132
 
121
133
  /* transition */
122
134
  transition-property: color;
@@ -4,6 +4,7 @@ declare const styles: {
4
4
  readonly "is-focus": string;
5
5
  readonly "js-focus": string;
6
6
  readonly "sapphire-tag__content": string;
7
+ readonly "sapphire-tag__label": string;
7
8
  readonly "sapphire-tag--actionable": string;
8
9
  readonly "is-disabled": string;
9
10
  readonly "is-active": string;
@@ -1,106 +1,193 @@
1
- @keyframes fade-in {
1
+ @keyframes slide-in {
2
2
  from {
3
- opacity: 0;
4
3
  transform: translate3d(
5
4
  0,
6
- calc(var(--sapphire-toast-animation-direction, 1) * 100%),
5
+ /* NOTE: 1rem is hardcoded since sapphire variables are not accessible
6
+ at html::view-transition-* pseudo-elements. Can be improved when scoped
7
+ view transitions are implemented: https://developer.chrome.com/blog/scoped-view-transitions-feedback
8
+ */
9
+ calc(var(--sapphire-toast-animation-direction, 1) * 100% + 1rem),
7
10
  0
8
11
  )
9
- translateX(var(--sapphire-toast-horizontal-transform)) scale(0.9);
12
+ scale(0.9);
10
13
  }
14
+ }
11
15
 
16
+ @keyframes slide-out {
12
17
  to {
13
- opacity: 1;
14
- transform: translate3d(0, 0, 0)
15
- translateX(var(--sapphire-toast-horizontal-transform)) scale(1);
18
+ opacity: 0;
19
+ transform: translate3d(
20
+ 0,
21
+ calc(var(--sapphire-toast-animation-direction, 1) * 100% + 1rem),
22
+ 0
23
+ )
24
+ scale(0.9);
16
25
  }
17
26
  }
18
27
 
19
- @keyframes fade-out {
20
- from {
21
- opacity: 1;
28
+ ::view-transition-group(.sapphire-toast-view-transition--reverse) {
29
+ --sapphire-toast-animation-direction: -1;
30
+ }
31
+
32
+ @media (prefers-reduced-motion: no-preference) {
33
+ ::view-transition-group(.sapphire-toast-view-transition) {
34
+ /* NOTE: the values are hardcoded since sapphire variables are not accessible
35
+ at html::view-transition-* pseudo-elements. Can be improved when scoped
36
+ view transitions are implemented: https://developer.chrome.com/blog/scoped-view-transitions-feedback
37
+ */
38
+ animation-duration: 200ms;
39
+ animation-timing-function: cubic-bezier(0, 0, 0, 1);
22
40
  }
23
41
 
24
- to {
25
- opacity: 0;
42
+ /*
43
+ * animation customization
44
+ * the default view transition animation works fine
45
+ * for all state changes except for two cases that we need to customize:
46
+ * 1. a new toast should be added with a slide-in animation
47
+ * 2. the first toast should be removed with a slide-out animation
48
+ */
49
+ ::view-transition-new(.sapphire-toast-view-transition):only-child {
50
+ animation-name: slide-in;
51
+ }
52
+ ::view-transition-old(.sapphire-toast-view-transition):only-child {
53
+ animation-name: slide-out;
54
+ }
55
+ }
56
+
57
+ @media (prefers-reduced-motion: reduce) {
58
+ /* Avoid view transition for individual toast when user prefers reduced motion */
59
+ .sapphire-toast {
60
+ view-transition-name: none !important;
26
61
  }
27
62
  }
28
63
 
29
64
  .sapphire-toast-container {
30
65
  pointer-events: none;
31
66
  position: fixed;
67
+ display: flex;
68
+ flex-direction: column;
69
+ align-items: center;
70
+ width: 100%;
71
+ max-height: calc(100vh - 2 * var(--sapphire-semantic-size-spacing-md));
32
72
  }
33
73
 
34
74
  /* Placement */
35
75
  .sapphire-toast-container--bottom {
36
- --sapphire-toast-horizontal-transform: -50%;
37
- bottom: 0;
38
- left: 50%;
39
- margin-bottom: var(--sapphire-semantic-size-spacing-md);
76
+ bottom: var(--sapphire-semantic-size-spacing-md);
77
+ left: 0;
40
78
  }
41
79
 
42
80
  .sapphire-toast-container--bottom-left {
43
- --sapphire-toast-horizontal-transform: 0%;
44
- bottom: 0;
45
- left: 0;
46
- margin-bottom: var(--sapphire-semantic-size-spacing-md);
47
- margin-left: var(--sapphire-semantic-size-spacing-md);
81
+ bottom: var(--sapphire-semantic-size-spacing-md);
82
+ left: var(--sapphire-semantic-size-spacing-md);
83
+ align-items: flex-start;
48
84
  }
49
85
 
50
86
  .sapphire-toast-container--bottom-right {
51
- --sapphire-toast-horizontal-transform: 0%;
52
- bottom: 0;
53
- right: 0;
54
- margin-bottom: var(--sapphire-semantic-size-spacing-md);
55
- margin-right: var(--sapphire-semantic-size-spacing-md);
87
+ bottom: var(--sapphire-semantic-size-spacing-md);
88
+ right: var(--sapphire-semantic-size-spacing-md);
89
+ align-items: flex-end;
56
90
  }
57
91
 
58
92
  .sapphire-toast-container--top {
59
- --sapphire-toast-animation-direction: -1;
60
- --sapphire-toast-horizontal-transform: -50%;
61
- top: 0;
62
- left: 50%;
63
- margin-top: var(--sapphire-semantic-size-spacing-md);
93
+ top: var(--sapphire-semantic-size-spacing-md);
94
+ left: 0;
64
95
  }
65
96
 
66
97
  .sapphire-toast-container--top-left {
67
- --sapphire-toast-animation-direction: -1;
68
- --sapphire-toast-horizontal-transform: 0%;
69
- top: 0;
70
- left: 0;
71
- margin-top: var(--sapphire-semantic-size-spacing-md);
72
- margin-left: var(--sapphire-semantic-size-spacing-md);
98
+ top: var(--sapphire-semantic-size-spacing-md);
99
+ left: var(--sapphire-semantic-size-spacing-md);
100
+ align-items: flex-start;
73
101
  }
74
102
 
75
103
  .sapphire-toast-container--top-right {
76
- --sapphire-toast-animation-direction: -1;
77
- --sapphire-toast-horizontal-transform: 0%;
104
+ top: var(--sapphire-semantic-size-spacing-md);
105
+ right: var(--sapphire-semantic-size-spacing-md);
106
+ align-items: flex-end;
107
+ }
108
+
109
+ .sapphire-toast-container--top:has(.sapphire-toast-list--expanded),
110
+ .sapphire-toast-container--top-left:has(.sapphire-toast-list--expanded),
111
+ .sapphire-toast-container--top-right:has(.sapphire-toast-list--expanded) {
78
112
  top: 0;
79
- right: 0;
80
- margin-top: var(--sapphire-semantic-size-spacing-md);
81
- margin-right: var(--sapphire-semantic-size-spacing-md);
113
+ }
114
+
115
+ .sapphire-toast-container--bottom:has(.sapphire-toast-list--expanded),
116
+ .sapphire-toast-container--bottom-left:has(.sapphire-toast-list--expanded),
117
+ .sapphire-toast-container--bottom-right:has(.sapphire-toast-list--expanded) {
118
+ bottom: 0;
119
+ }
120
+
121
+ .sapphire-toast-list {
122
+ flex-grow: 1;
123
+ pointer-events: all;
124
+ position: relative;
125
+ display: flex;
126
+ flex-direction: column-reverse;
127
+ align-items: center;
128
+ gap: var(--sapphire-semantic-size-spacing-sm);
129
+
130
+ padding: 0;
131
+ margin: 0;
132
+ transition: perspective-origin var(--sapphire-semantic-time-motion-default)
133
+ var(--sapphire-semantic-transitions-dynamic);
134
+ }
135
+
136
+ .sapphire-toast-list--expanded {
137
+ overflow-y: auto;
138
+ overflow-x: visible;
139
+ padding: var(--sapphire-semantic-size-spacing-md)
140
+ calc(var(--sapphire-semantic-size-focus-ring) * 2);
141
+ margin: 0 calc(var(--sapphire-semantic-size-focus-ring) * -2);
142
+ }
143
+
144
+ .sapphire-toast-list--collapsed {
145
+ perspective: calc(
146
+ var(--sapphire-semantic-size-spacing-sm) * 2 +
147
+ var(--sapphire-global-size-generic-140)
148
+ );
149
+ --sapphire-origin-y: 200%;
150
+ perspective-origin: center calc(-1 * var(--sapphire-origin-y));
151
+ }
152
+
153
+ .sapphire-toast-list--collapsed.js-hover.is-hover:has(> :nth-child(2)),
154
+ .sapphire-toast-list--collapsed:not(.js-hover):hover:has(> :nth-child(2)) {
155
+ --sapphire-origin-y: 280%;
156
+ }
157
+
158
+ .sapphire-toast-container--top .sapphire-toast-list,
159
+ .sapphire-toast-container--top-left .sapphire-toast-list,
160
+ .sapphire-toast-container--top-right .sapphire-toast-list {
161
+ perspective-origin: center calc(100% + var(--sapphire-origin-y));
162
+ flex-direction: column;
163
+ }
164
+
165
+ .sapphire-toast-list:has(> :nth-child(2)) .sapphire-toast,
166
+ .sapphire-toast-list:has(> :nth-child(2)) .sapphire-toast {
167
+ cursor: pointer;
168
+ }
169
+
170
+ /* when the view transition is active, we want to delay the transition of the toast list
171
+ to make sure hover effects are not triggered */
172
+ :root:active-view-transition .sapphire-toast-list {
173
+ transition-delay: 2s;
82
174
  }
83
175
 
84
176
  /************************************************************/
85
177
 
86
178
  .sapphire-toast {
87
179
  pointer-events: initial;
88
- position: absolute;
180
+ position: relative;
89
181
  inset: inherit;
90
- /* absolute position & center */
91
- transform: translateX(var(--sapphire-toast-horizontal-transform));
92
182
 
93
- /* let the text grow until max-width */
94
- width: max-content;
183
+ width: min(
184
+ var(--sapphire-global-size-generic-850),
185
+ calc(100vw - 2 * var(--sapphire-semantic-size-spacing-md))
186
+ );
187
+ flex-shrink: 0;
95
188
 
96
189
  overflow: hidden;
97
- max-width: var(--sapphire-global-size-generic-1400);
98
- min-width: var(--sapphire-global-size-generic-750);
99
190
  border-radius: var(--sapphire-semantic-size-radius-lg);
100
- animation-duration: var(--sapphire-semantic-time-motion-default);
101
-
102
- animation-timing-function: var(--sapphire-semantic-transitions-fade);
103
-
104
191
  /* if implemented as focusable, we don't want the outline because this is not
105
192
  * an an interactive element in itself */
106
193
  outline: none;
@@ -120,22 +207,54 @@
120
207
  -moz-osx-font-smoothing: grayscale;
121
208
  }
122
209
 
123
- .sapphire-toast--entering {
124
- animation-name: fade-in;
210
+ /* focus */
211
+ .sapphire-toast:not(.js-focus):focus-visible,
212
+ .sapphire-toast.is-focus {
213
+ outline: var(--sapphire-semantic-size-focus-ring) solid
214
+ var(--sapphire-semantic-color-focus-ring);
215
+ outline-offset: var(--sapphire-semantic-size-focus-ring);
125
216
  }
126
217
 
127
- /* This represents the toast which appears immediately after the current one
128
- * disappears */
129
- .sapphire-toast--queued {
130
- opacity: 0;
131
- animation-name: fade-in;
132
- animation-delay: var(--sapphire-semantic-time-motion-default);
133
- animation-fill-mode: forwards;
218
+ .sapphire-toast.sapphire-toast--stacked {
219
+ /* Position absolute is needed for the correct container sizing */
220
+ /* stylelint-disable csstools/value-no-unknown-custom-properties */
221
+ position: absolute;
222
+ /* when stacked, toasts after the third one should not be visible.
223
+ They are still expected to be rendered so that the view transition
224
+ works as expected without needing any special style */
225
+ --sapphire-toast-position-index: min(var(--sapphire-toast-index, 0), 2);
226
+
227
+ translate: 0 0
228
+ calc(
229
+ var(--sapphire-toast-position-index) *
230
+ var(--sapphire-semantic-size-spacing-xs) * -1
231
+ );
232
+ max-height: var(--sapphire-global-size-generic-140);
134
233
  }
135
234
 
136
- .sapphire-toast--exiting {
137
- animation-name: fade-out;
138
- animation-fill-mode: forwards;
235
+ .sapphire-toast-container--bottom .sapphire-toast.sapphire-toast--stacked,
236
+ .sapphire-toast-container--bottom-left .sapphire-toast.sapphire-toast--stacked,
237
+ .sapphire-toast-container--bottom-right
238
+ .sapphire-toast.sapphire-toast--stacked {
239
+ top: 0;
240
+ }
241
+
242
+ .sapphire-toast-container--top .sapphire-toast.sapphire-toast--stacked,
243
+ .sapphire-toast-container--top-left .sapphire-toast.sapphire-toast--stacked,
244
+ .sapphire-toast-container--top-right .sapphire-toast.sapphire-toast--stacked {
245
+ bottom: 0;
246
+ }
247
+
248
+ .sapphire-toast--stacked .sapphire-toast__text-content {
249
+ visibility: hidden;
250
+ }
251
+
252
+ .sapphire-toast--stacked::after {
253
+ content: '';
254
+ position: absolute;
255
+ inset: 0;
256
+ background: var(--sapphire-semantic-color-background-surface);
257
+ opacity: calc(var(--sapphire-toast-index) * 0.2);
139
258
  }
140
259
 
141
260
  .sapphire-toast__content {
@@ -160,6 +279,7 @@
160
279
  flex: 1;
161
280
  justify-content: center;
162
281
  padding: var(--sapphire-semantic-size-spacing-2xs);
282
+ overflow: hidden;
163
283
  }
164
284
 
165
285
  .sapphire-toast__text-content > :nth-child(1 of :not(:only-child)) {
@@ -1,4 +1,9 @@
1
1
  declare const styles: {
2
+ readonly "sapphire-toast-view-transition--reverse": string;
3
+ readonly "sapphire-toast-view-transition": string;
4
+ readonly "slide-in": string;
5
+ readonly "slide-out": string;
6
+ readonly "sapphire-toast": string;
2
7
  readonly "sapphire-toast-container": string;
3
8
  readonly "sapphire-toast-container--bottom": string;
4
9
  readonly "sapphire-toast-container--bottom-left": string;
@@ -6,14 +11,16 @@ declare const styles: {
6
11
  readonly "sapphire-toast-container--top": string;
7
12
  readonly "sapphire-toast-container--top-left": string;
8
13
  readonly "sapphire-toast-container--top-right": string;
9
- readonly "sapphire-toast": string;
10
- readonly "sapphire-toast--entering": string;
11
- readonly "fade-in": string;
12
- readonly "sapphire-toast--queued": string;
13
- readonly "sapphire-toast--exiting": string;
14
- readonly "fade-out": string;
15
- readonly "sapphire-toast__content": string;
14
+ readonly "sapphire-toast-list--expanded": string;
15
+ readonly "sapphire-toast-list": string;
16
+ readonly "sapphire-toast-list--collapsed": string;
17
+ readonly "js-hover": string;
18
+ readonly "is-hover": string;
19
+ readonly "js-focus": string;
20
+ readonly "is-focus": string;
21
+ readonly "sapphire-toast--stacked": string;
16
22
  readonly "sapphire-toast__text-content": string;
23
+ readonly "sapphire-toast__content": string;
17
24
  readonly "sapphire-toast__content--success": string;
18
25
  readonly "sapphire-toast__content--error": string;
19
26
  readonly "sapphire-toast__title--with-icon": string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danske/sapphire-css",
3
- "version": "49.0.0",
3
+ "version": "49.1.0",
4
4
  "description": "CSS implementation of the Sapphire Design System from Danske Bank A/S",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "sideEffects": false,
@@ -67,7 +67,7 @@
67
67
  "typescript": "~4.6.4"
68
68
  },
69
69
  "dependencies": {
70
- "@danske/sapphire-design-tokens": "^42.2.1"
70
+ "@danske/sapphire-design-tokens": "^42.3.0"
71
71
  },
72
- "gitHead": "95e11ee77650ba6158811bcc5969bc7c7aaab530"
72
+ "gitHead": "88e11202ab17bb9830ba1f261d631ab24edf57d2"
73
73
  }