@c8y/style 1024.15.13 → 1024.16.5

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c8y/style",
3
- "version": "1024.15.13",
3
+ "version": "1024.16.5",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Cumulocity GmbH",
6
6
  "description": "Styles for Cumulocity IoT applications",
@@ -1,5 +1,5 @@
1
- @use '../../../variables/index'as *;
2
- @use "../../mixins/tab-focus";
1
+ @use '../../../variables/index' as *;
2
+ @use '../../mixins/tab-focus';
3
3
  /**
4
4
  * C8Y AI Chat - AI chat widget component
5
5
  *
@@ -14,6 +14,7 @@
14
14
  * - Font-size em values (1.2em, 1.5em, 2em): Relative heading sizes
15
15
  * - Line-height values (1.7): Unitless ratio
16
16
  * - Z-index values: Stacking order
17
+ * - Working indicator dot gap (2px): Fine visual spacing smaller than $size-4
17
18
  */
18
19
 
19
20
  c8y-widget-ai-chat-section {
@@ -33,13 +34,14 @@ c8y-widget-ai-chat-section {
33
34
 
34
35
  c8y-agent-chat {
35
36
  width: 100%;
37
+ display: flex;
38
+ flex-direction: column;
36
39
  }
37
40
 
38
41
  .chat-input {
39
42
  display: flex;
40
43
  width: 100%;
41
44
  flex-direction: column;
42
- gap: $size-8;
43
45
  padding: $size-16 $size-16 $size-4 $size-16;
44
46
  background-color: $component-background-default;
45
47
  border-top: 1px solid var(--c8y-root-component-border-color);
@@ -52,12 +54,14 @@ c8y-agent-chat {
52
54
  width: 100%;
53
55
 
54
56
  textarea {
55
- border-radius: 20px !important;
57
+ border-top-right-radius: $size-20 !important;
58
+ border-top-left-radius: $size-20 !important;
56
59
  min-height: $size-40;
57
- padding-top: $size-10;
58
- padding-right: $size-40;
59
- padding-bottom: $size-10;
60
- padding-left: $size-16;
60
+ padding-top: $size-16;
61
+ padding-right: $size-48;
62
+ padding-bottom: $size-16;
63
+ padding-left: $size-24;
64
+ margin-bottom: 0px;
61
65
 
62
66
  &::-webkit-scrollbar {
63
67
  width: unset;
@@ -83,15 +87,42 @@ c8y-agent-chat {
83
87
  }
84
88
  }
85
89
 
90
+ &.chat-input-with-action-bar textarea {
91
+ padding-bottom: calc(var(--c8y-unit-base) * 6);
92
+ }
93
+
94
+ &.chat-input-with-action-bar .chat-action-bar {
95
+ border-top: 1px solid var(--c8y-root-component-border-color);
96
+ }
97
+
86
98
  .chat-input-group-btn {
87
99
  position: absolute;
88
- right: $size-4;
89
- bottom: $size-4;
100
+ right: $size-8;
101
+ top: $size-8;
90
102
 
91
103
  .btn-dot {
92
104
  margin: 0 !important;
93
105
  height: $form-control-height-base !important;
94
106
  border-radius: 50%;
107
+ &:active, &:hover {
108
+ border-radius: 50%;
109
+ }
110
+ }
111
+ }
112
+ }
113
+
114
+ .chat-action-bar {
115
+ width: 100%;
116
+ border: 1px solid var(--c8y-form-control-border-color-default);
117
+ border-top: 0;
118
+ border-bottom-left-radius: $size-20;
119
+ border-bottom-right-radius: $size-20;
120
+ padding: $size-8;
121
+ .btn-dot {
122
+ height: $form-control-height-base !important;
123
+ border-radius: 50%;
124
+ &:active, &:hover {
125
+ border-radius: 50%;
95
126
  }
96
127
  }
97
128
  }
@@ -120,7 +151,7 @@ c8y-agent-chat {
120
151
  align-self: flex-start;
121
152
  min-width: 0;
122
153
  width: 100%;
123
- margin-top: $size-16;
154
+ // margin-top: $size-16;
124
155
  padding: $size-16 $size-24 $size-16 $size-16;
125
156
 
126
157
  h1 {
@@ -198,9 +229,7 @@ c8y-agent-chat {
198
229
  }
199
230
  }
200
231
 
201
-
202
232
  c8y-ai-chat {
203
-
204
233
  // Visually hidden label included when users copy-paste from the chat, e.g. to report issues.
205
234
  .hidden-copy-label {
206
235
  display: block;
@@ -216,11 +245,11 @@ c8y-ai-chat {
216
245
  flex-direction: column;
217
246
  max-width: 100%;
218
247
  min-inline-size: 1rem;
219
- transition: all .35s ease;
248
+ transition: all 0.35s ease;
220
249
 
221
- &:has([aria-expanded="true"]) {
250
+ &:has([aria-expanded='true']) {
222
251
  min-inline-size: 100%;
223
- transition: all .35s ease;
252
+ transition: all 0.35s ease;
224
253
  }
225
254
 
226
255
  &:focus-within {
@@ -252,8 +281,72 @@ c8y-ai-chat {
252
281
  margin-bottom: 0;
253
282
  }
254
283
  }
284
+ }
285
+
286
+ .working-indicator__dots {
287
+ display: inline-flex;
288
+ align-items: baseline;
289
+ gap: 2px;
290
+
291
+ span {
292
+ width: $size-4;
293
+ height: $size-4;
294
+ border-radius: 50%;
295
+ background-color: currentColor;
296
+ opacity: 0.2;
297
+ animation: working-indicator-dot 1.2s ease-in-out infinite;
298
+
299
+ &:nth-child(2) {
300
+ animation-delay: 0.2s;
301
+ }
302
+
303
+ &:nth-child(3) {
304
+ animation-delay: 0.4s;
305
+ }
306
+ }
307
+ }
308
+
309
+ @keyframes working-indicator-dot {
310
+ 0%,
311
+ 80%,
312
+ 100% {
313
+ opacity: 0.2;
314
+ }
315
+
316
+ 40% {
317
+ opacity: 1;
318
+ }
319
+ }
320
+ }
321
+
322
+ c8y-ai-chat-speech-to-text {
323
+ // While recognition is running the microphone turns to the danger color and its icon pulses to
324
+ // signal that the app is actively listening.
325
+ .c8y-speech-to-text-btn--listening {
326
+ color: var(--c8y-palette-status-danger, var(--c8y-brand-primary));
255
327
 
328
+ .c8y-speech-to-text-btn__icon {
329
+ animation: speech-to-text-pulse 1.4s ease-in-out infinite;
330
+ }
256
331
  }
257
332
 
333
+ @keyframes speech-to-text-pulse {
334
+ 0%,
335
+ 100% {
336
+ opacity: 1;
337
+ transform: scale(1);
338
+ }
258
339
 
340
+ 50% {
341
+ opacity: 0.55;
342
+ transform: scale(1.18);
343
+ }
344
+ }
345
+
346
+ // Respect users who prefer reduced motion: keep the color change but drop the pulsing.
347
+ @media (prefers-reduced-motion: reduce) {
348
+ .c8y-speech-to-text-btn--listening .c8y-speech-to-text-btn__icon {
349
+ animation: none;
350
+ }
351
+ }
259
352
  }
@@ -68,6 +68,25 @@ pre {
68
68
  font-size: inherit;
69
69
  overflow-wrap: break-word;
70
70
  }
71
+
72
+ &[data-label]{
73
+ position: relative;
74
+ padding-top: $margin-24;
75
+ border-radius: $btn-border-radius-base;
76
+ &::before{
77
+ content: attr(data-label);
78
+ display: inline-block;
79
+ background-color: $text-muted;
80
+ color: $component-background-default;
81
+ position: absolute;
82
+ top: 0;
83
+ left: 0;
84
+ padding: 0 4px;
85
+ text-transform: uppercase;
86
+ font-size: 10px;
87
+ font-family: $font-family-base;
88
+ }
89
+ }
71
90
  }
72
91
 
73
92
  // pre:has(code) {
@@ -132,6 +132,16 @@
132
132
  .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
133
133
  @include border-radius.border-left-radius(0);
134
134
  }
135
+ // adjust margin and border radius when nested btn-group with dropdown is using cdkTrapFocus
136
+ .btn-group:has(.btn-group + .cdk-visually-hidden:last-child){
137
+ > .btn-group{
138
+ margin-left: -2px;
139
+ > .btn:first-child {
140
+ @include border-radius.border-left-radius(0);
141
+ @include border-radius.border-right-radius($btn-border-radius-base);
142
+ }
143
+ }
144
+ }
135
145
 
136
146
  // On active and open, don't show outline
137
147
  .btn-group .dropdown-toggle:active,
@@ -80,6 +80,11 @@ fieldset.c8y-fieldset {
80
80
  padding-block-end: 0;
81
81
  padding-inline-start: 1.1428571429em;
82
82
  min-inline-size: 100%;
83
+
84
+ &.ai-tool-call__fieldset{
85
+ padding-inline-start: 0.742857em;
86
+ }
87
+
83
88
  &--lg {
84
89
  padding-block-start: 1rem;
85
90
  padding-inline-end: 1.5em;
@@ -7,6 +7,9 @@
7
7
  *
8
8
  * Intentionally hardcoded values:
9
9
  * - 1px border widths: Standard border width, not spacing
10
+ * - 0 border radius: Reset, not a size on the token scale
11
+ * - 50% and 9999px border radius: Shape ratios for circles and pills, which have to
12
+ * hold at any element size, so they cannot come from the fixed $size-* scale
10
13
  */
11
14
 
12
15
  .border-all {
@@ -129,9 +132,38 @@
129
132
  }
130
133
 
131
134
 
132
- // Removed unused border-radius utilities - verified 0 usages:
133
- // .b-r-8, .b-r-24, .b-r-32, .b-r-40
135
+ // border radius
136
+ //
137
+ // `.b-r-4` was never defined, in the SCSS layer or the LESS one before it, yet two ai-chat templates
138
+ // carried the class from a scale that only existed on paper. Defining it here would have given those
139
+ // two surfaces a radius they never had, so the dead class was removed from them in the same change.
140
+ // `.b-r-2` stays undefined: nothing uses it and nothing documents it.
134
141
 
142
+ .b-r-0 {
143
+ border-radius: 0 !important;
144
+ }
145
+ .b-r-4 {
146
+ border-radius: $size-4 !important;
147
+ }
148
+ .b-r-8 {
149
+ border-radius: $size-8 !important;
150
+ }
135
151
  .b-r-16 {
136
152
  border-radius: $size-16 !important;
137
153
  }
154
+ .b-r-24 {
155
+ border-radius: $size-24 !important;
156
+ }
157
+ .b-r-32 {
158
+ border-radius: $size-32 !important;
159
+ }
160
+ .b-r-40 {
161
+ border-radius: $size-40 !important;
162
+ }
163
+
164
+ .b-r-circle {
165
+ border-radius: 50% !important;
166
+ }
167
+ .b-r-pill {
168
+ border-radius: 9999px !important;
169
+ }
@@ -31,46 +31,74 @@
31
31
  .text-primary {
32
32
  @include text-emphasis.text-emphasis-variant(var(--c8y-root-component-brand-primary,$brand-primary));
33
33
  }
34
- // Removed unused: .text-primary-light, .text-primary-dark
34
+ .text-primary-light {
35
+ @include text-emphasis.text-emphasis-variant($brand-primary-light);
36
+ }
37
+ .text-primary-dark {
38
+ @include text-emphasis.text-emphasis-variant($brand-primary-dark);
39
+ }
35
40
 
36
41
  // Accent text colors
37
42
  .text-accent {
38
43
  @include text-emphasis.text-emphasis-variant($brand-accent);
39
44
  }
40
- // Removed unused: .text-accent-light, .text-accent-dark
41
- // Note: .text-accent was NOT in cat5-text-utils.txt (step 225), only light/dark were.
42
- // Checking cat5-text-utils.txt again...
43
- // It lists: .text-accent-dark, .text-accent-light. NOT .text-accent.
45
+ .text-accent-light {
46
+ @include text-emphasis.text-emphasis-variant($brand-accent-light);
47
+ }
48
+ .text-accent-dark {
49
+ @include text-emphasis.text-emphasis-variant($brand-accent-dark);
50
+ }
44
51
 
45
52
  // Success text colors
46
53
  .text-success {
47
54
  @include text-emphasis.text-emphasis-variant($status-success);
48
55
  }
49
- // Removed unused: .text-success-light, .text-success-dark
56
+ .text-success-light {
57
+ @include text-emphasis.text-emphasis-variant($status-success-light);
58
+ }
59
+ .text-success-dark {
60
+ @include text-emphasis.text-emphasis-variant($status-success-dark);
61
+ }
50
62
 
51
63
  // Info text colors
52
64
  .text-info {
53
65
  @include text-emphasis.text-emphasis-variant($status-info);
54
66
  }
55
- // Removed unused: .text-info-light, .text-info-dark
67
+ .text-info-light {
68
+ @include text-emphasis.text-emphasis-variant($status-info-light);
69
+ }
70
+ .text-info-dark {
71
+ @include text-emphasis.text-emphasis-variant($status-info-dark);
72
+ }
56
73
 
57
74
  // Warning text colors
58
75
  .text-warning {
59
76
  @include text-emphasis.text-emphasis-variant($status-warning);
60
77
  }
61
- // Removed unused: .text-warning-light, .text-warning-high, .text-warning-dark
78
+ .text-warning-light {
79
+ @include text-emphasis.text-emphasis-variant($status-warning-light);
80
+ }
81
+ // Dropped on purpose, not restored: .text-warning-high
82
+ .text-warning-dark {
83
+ @include text-emphasis.text-emphasis-variant($status-warning-dark);
84
+ }
62
85
 
63
86
  // Danger text colors
64
87
  .text-danger {
65
88
  @include text-emphasis.text-emphasis-variant($status-danger);
66
89
  }
67
- // Removed unused: .text-danger-light, .text-danger-dark
68
-
69
- // Gray text colors
70
- // Removed unused gray text colors - verified 0 usages:
71
- // .text-gray-10...100
90
+ .text-danger-light {
91
+ @include text-emphasis.text-emphasis-variant($status-danger-light);
92
+ }
93
+ .text-danger-dark {
94
+ @include text-emphasis.text-emphasis-variant($status-danger-dark);
95
+ }
72
96
 
73
97
  // backwards compatibility
98
+ //
99
+ // Dropped on purpose and deliberately not restored: .text-gray-medium, .text-gray-medium-dark,
100
+ // .text-gray-light, .text-gray-white. A few legacy templates still carry these class names; that is
101
+ // harmless, since the class simply does not match anything.
74
102
 
75
103
  .text-gray-darker {
76
104
  @include text-emphasis.text-emphasis-variant($brand-primary-dark);
@@ -80,20 +108,14 @@
80
108
  @include text-emphasis.text-emphasis-variant($gray-30);
81
109
  }
82
110
 
83
- // Removed unused: .text-gray-medium-dark, .text-gray-medium
84
-
85
111
  .text-gray {
86
112
  @include text-emphasis.text-emphasis-variant($gray-50);
87
113
  }
88
114
 
89
- // Removed unused: .text-gray-light
90
-
91
115
  .text-gray-lighter {
92
116
  @include text-emphasis.text-emphasis-variant($gray-90);
93
117
  }
94
118
 
95
- // Removed unused: .text-gray-white
96
-
97
119
  //================================
98
120
  // Contextual backgrounds
99
121
  //================================
@@ -105,13 +127,29 @@
105
127
  @include background-variant.bg-variant($brand-primary-light);
106
128
  }
107
129
 
108
- // Removed unused: .bg-complementary
130
+ .bg-complementary {
131
+ @include background-variant.bg-variant($brand-complementary);
132
+ }
109
133
 
110
- // Removed unused: .bg-accent, .bg-accent-dark, .bg-accent-light
111
- // cat6-bg-utils.txt list: .bg-accent, .bg-accent-dark, .bg-accent-light.
134
+ .bg-accent {
135
+ @include background-variant.bg-variant($brand-accent);
136
+ }
137
+ .bg-accent-light {
138
+ @include background-variant.bg-variant($brand-accent-light);
139
+ }
140
+ .bg-accent-dark {
141
+ @include background-variant.bg-variant($brand-accent-dark);
142
+ }
112
143
 
113
- // Removed unused: .bg-success, .bg-success-dark, .bg-success-light
114
- // cat6-bg-utils.txt list: .bg-success, .bg-success-dark, .bg-success-light.
144
+ .bg-success {
145
+ @include background-variant.bg-variant($status-success);
146
+ }
147
+ .bg-success-light {
148
+ @include background-variant.bg-variant($status-success-light);
149
+ }
150
+ .bg-success-dark {
151
+ @include background-variant.bg-variant($status-success-dark);
152
+ }
115
153
 
116
154
  .bg-info {
117
155
  @include background-variant.bg-variant($status-info);
@@ -119,16 +157,30 @@
119
157
  .bg-info-light {
120
158
  @include background-variant.bg-variant($status-info-light);
121
159
  }
122
- // Removed unused: .bg-info-dark (cat6 lists .bg-info-dark, but not .bg-info or .bg-info-light)
160
+ .bg-info-dark {
161
+ @include background-variant.bg-variant($status-info-dark);
162
+ }
123
163
 
124
164
  .bg-warning {
125
165
  @include background-variant.bg-variant($status-warning);
126
166
  }
127
- // Removed unused: .bg-warning-light, .bg-warning-lightest, .bg-warning-dark (cat6 lists these)
128
- // cat6 does NOT list .bg-warning.
167
+ .bg-warning-light {
168
+ @include background-variant.bg-variant($status-warning-light);
169
+ }
170
+ .bg-warning-dark {
171
+ @include background-variant.bg-variant($status-warning-dark);
172
+ }
173
+ // Dropped on purpose, not restored: .bg-warning-lightest, .bg-transparent
129
174
 
130
- // Removed unused: .bg-danger, .bg-danger-light, .bg-danger-dark
131
- // cat6 lists .bg-danger, .bg-danger-light, .bg-danger-dark.
175
+ .bg-danger {
176
+ @include background-variant.bg-variant($status-danger);
177
+ }
178
+ .bg-danger-light {
179
+ @include background-variant.bg-variant($status-danger-light);
180
+ }
181
+ .bg-danger-dark {
182
+ @include background-variant.bg-variant($status-danger-dark);
183
+ }
132
184
 
133
185
  .bg-checkered {
134
186
  background-image:
@@ -142,7 +194,13 @@
142
194
 
143
195
  // Levels
144
196
 
145
- // Removed unused: bg-level-4, bg-level-3
197
+ .bg-level-4 {
198
+ @include background-variant.bg-variant(var(--c8y-level-4));
199
+ }
200
+
201
+ .bg-level-3 {
202
+ @include background-variant.bg-variant(var(--c8y-level-3));
203
+ }
146
204
 
147
205
  .bg-level-2 {
148
206
  @include background-variant.bg-variant(var(--c8y-level-2));
@@ -156,10 +214,16 @@
156
214
  @include background-variant.bg-variant(var(--c8y-level-0));
157
215
  }
158
216
 
159
- // Removed unused: .bg-transparent
160
-
161
217
  // Grays
162
- // Removed unused: .bg-gray-10...100
218
+ // Numbered gray text/background utilities, driven by the gray palette tokens.
219
+ @each $step in (10, 20, 30, 40, 50, 60, 70, 80, 90, 100) {
220
+ .text-gray-#{$step} {
221
+ @include text-emphasis.text-emphasis-variant(var(--c8y-palette-gray-#{$step}));
222
+ }
223
+ .bg-gray-#{$step} {
224
+ @include background-variant.bg-variant(var(--c8y-palette-gray-#{$step}));
225
+ }
226
+ }
163
227
 
164
228
  .bg-inherit {
165
229
  @include background-variant.bg-variant(inherit);
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * Intentionally hardcoded values:
9
9
  * - 0 values: Zero position offsets, not spacing
10
- * - Position keywords: relative, absolute, static, sticky
10
+ * - Position keywords: relative, absolute, static, sticky, fixed
11
11
  */
12
12
 
13
13
  .p-relative {
@@ -22,6 +22,9 @@
22
22
  .p-sticky {
23
23
  position: sticky !important;
24
24
  }
25
+ .p-fixed {
26
+ position: fixed !important;
27
+ }
25
28
 
26
29
  .top-0 {
27
30
  top: 0 !important;
@@ -29,9 +32,12 @@
29
32
  .left-0 {
30
33
  left: 0 !important;
31
34
  }
32
-
33
- // Removed unused positioning utilities - verified 0 usages:
34
- // .right-0, .bottom-0
35
+ .right-0 {
36
+ right: 0 !important;
37
+ }
38
+ .bottom-0 {
39
+ bottom: 0 !important;
40
+ }
35
41
 
36
42
  // media queries
37
43
  @media (max-width: $screen-xs-max) {
@@ -47,6 +53,9 @@
47
53
  .p-sticky-xs {
48
54
  position: sticky !important;
49
55
  }
56
+ .p-fixed-xs {
57
+ position: fixed !important;
58
+ }
50
59
  .top-0-xs {
51
60
  top: 0 !important;
52
61
  }
@@ -74,6 +83,9 @@
74
83
  .p-sticky-sm {
75
84
  position: sticky !important;
76
85
  }
86
+ .p-fixed-sm {
87
+ position: fixed !important;
88
+ }
77
89
  .top-0-sm {
78
90
  top: 0 !important;
79
91
  }
@@ -101,6 +113,9 @@
101
113
  .p-sticky-md {
102
114
  position: sticky !important;
103
115
  }
116
+ .p-fixed-md {
117
+ position: fixed !important;
118
+ }
104
119
  .top-0-md {
105
120
  top: 0 !important;
106
121
  }
@@ -128,6 +143,9 @@
128
143
  .p-sticky-lg {
129
144
  position: sticky !important;
130
145
  }
146
+ .p-fixed-lg {
147
+ position: fixed !important;
148
+ }
131
149
  .top-0-lg {
132
150
  top: 0 !important;
133
151
  }
@@ -73,6 +73,8 @@
73
73
  height: 100% !important;
74
74
  }
75
75
 
76
+ // Superseded by .fit-h-md, which follows the .class-{breakpoint} convention used by
77
+ // every other responsive utility. Kept so existing markup keeps working.
76
78
  .fit-h--md{
77
79
  @media (min-width: $screen-md-min){
78
80
  height: 100% !important;
@@ -83,6 +85,31 @@
83
85
  height: 20px !important;
84
86
  }
85
87
 
88
+ //media queries
89
+ @media (max-width: $screen-xs-max) {
90
+ .fit-h-xs {
91
+ height: 100% !important;
92
+ }
93
+ }
94
+
95
+ @media (min-width: $screen-sm-min) {
96
+ .fit-h-sm {
97
+ height: 100% !important;
98
+ }
99
+ }
100
+
101
+ @media (min-width: $screen-md-min) {
102
+ .fit-h-md {
103
+ height: 100% !important;
104
+ }
105
+ }
106
+
107
+ @media (min-width: $screen-lg-min) {
108
+ .fit-h-lg {
109
+ height: 100% !important;
110
+ }
111
+ }
112
+
86
113
  // Sticky header
87
114
  .sticky-header-top-0 {
88
115
  position: sticky !important;