@carbon/styles 1.112.0 → 1.113.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.
@@ -0,0 +1,421 @@
1
+ //
2
+ // Copyright IBM Corp. 2026
3
+ //
4
+ // This source code is licensed under the Apache-2.0 license found in the
5
+ // LICENSE file in the root directory of this source tree.
6
+ //
7
+
8
+ @use '../../config' as *;
9
+ @use '../../spacing' as *;
10
+ @use '../../theme' as *;
11
+ @use '../../utilities/ai-gradient' as *;
12
+ @use '../../utilities/convert' as *;
13
+ @use '../../utilities/skeleton' as *;
14
+
15
+ /// Shared v12 date-picker rules for both React and Web Components. Each one
16
+ /// scopes them differently so they don't clash with the v11 date picker:
17
+ /// - React nests them under `.#{$prefix}--date-picker--next` (via the
18
+ /// `date-picker-next` mixin) so they only apply to the next date picker.
19
+ /// - Web Components uses them as-is and `@extend` them onto their shadow
20
+ /// `:host()`. Shadow DOM keeps them scoped to the next date picker's own
21
+ /// elements, so they never reach the v11 date picker.
22
+
23
+ // =============================================================================
24
+ // SHARED FRAMEWORK-AGNOSTIC STYLES
25
+ // These styles work for both Web Components and React
26
+ // =============================================================================
27
+ /// @access public
28
+ /// @group date-picker
29
+
30
+ @mixin date-picker-next-rules {
31
+ // Input wrapper needs relative positioning for icon placement
32
+ .#{$prefix}--date-picker-input__wrapper {
33
+ position: relative;
34
+ anchor-name: --date-picker-input;
35
+ }
36
+
37
+ // Enable pointer events on the calendar icon button
38
+ // Carbon sets pointer-events: none by default, but we need clicks to work
39
+ .#{$prefix}--date-picker__icon {
40
+ position: absolute;
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ padding: 0;
45
+ border: none;
46
+ background: transparent;
47
+ color: $icon-primary;
48
+ cursor: pointer;
49
+ inset-block-start: 50%;
50
+ inset-inline-end: 1rem;
51
+ pointer-events: auto;
52
+ transform: translateY(-50%);
53
+
54
+ // Remove focus outline, border, and background
55
+ &:focus {
56
+ border: none;
57
+ background: transparent;
58
+ outline: none;
59
+ }
60
+
61
+ // Remove any hover/active borders and backgrounds
62
+ &:hover,
63
+ &:active {
64
+ border: none;
65
+ background: transparent;
66
+ }
67
+ }
68
+
69
+ // Popover API styling with CSS anchor positioning
70
+ .#{$prefix}--date-picker__calendar-popover {
71
+ // Position using CSS anchor positioning
72
+ position: absolute;
73
+ z-index: 9000;
74
+
75
+ // Reset popover defaults
76
+ padding: 0;
77
+ border: none;
78
+ margin: 0;
79
+ background: transparent;
80
+
81
+ // Remove focus outline from popover
82
+ &:focus {
83
+ outline: none;
84
+ }
85
+
86
+ inset-area: block-end span-inline-start;
87
+ margin-block-start: $spacing-02;
88
+ position-anchor: --date-picker-input;
89
+
90
+ // Fallback positioning for browsers without anchor positioning
91
+ @supports not (inset-area: block-end) {
92
+ position: absolute;
93
+ inset-block-start: anchor(bottom);
94
+ inset-inline-start: anchor(left);
95
+ margin-block-start: $spacing-02;
96
+ }
97
+
98
+ // Handle viewport overflow
99
+ position-try-options: --bottom-left, --top-left, --bottom-right, --top-right;
100
+
101
+ @position-try --bottom-left {
102
+ inset-area: block-end span-inline-start;
103
+ margin-block-start: $spacing-02;
104
+ }
105
+
106
+ @position-try --top-left {
107
+ inset-area: block-start span-inline-start;
108
+ margin-block-end: $spacing-02;
109
+ }
110
+
111
+ @position-try --bottom-right {
112
+ inset-area: block-end span-inline-end;
113
+ margin-block-start: $spacing-02;
114
+ }
115
+
116
+ @position-try --top-right {
117
+ inset-area: block-start span-inline-end;
118
+ margin-block-end: $spacing-02;
119
+ }
120
+ }
121
+
122
+ .#{$prefix}--date-picker__calendar.open {
123
+ margin-block-start: 0;
124
+ }
125
+
126
+ // Remove focus outline from calendar container
127
+ // Calendar container styling
128
+ .#{$prefix}--date-picker__calendar-container {
129
+ position: absolute;
130
+ z-index: 9000;
131
+ display: block;
132
+ inset-block-start: 100%;
133
+ inset-inline-start: 0;
134
+ margin-block-start: 0;
135
+ }
136
+
137
+ // DATE PICKER INPUT STYLES
138
+ .#{$prefix}--date-picker-container {
139
+ outline: none;
140
+
141
+ .#{$prefix}--form-requirement[hidden] {
142
+ display: none;
143
+ }
144
+ }
145
+
146
+ .#{$prefix}--date-picker-container--warn:not(
147
+ .#{$prefix}--date-picker-container--invalid
148
+ ) {
149
+ .#{$prefix}--form-requirement {
150
+ color: $text-primary;
151
+ }
152
+ }
153
+
154
+ // Simple date picker sizing
155
+ .#{$prefix}--date-picker-container--simple {
156
+ .#{$prefix}--date-picker__input {
157
+ inline-size: rem(120px);
158
+ }
159
+
160
+ .#{$prefix}--date-picker__input--invalid,
161
+ .#{$prefix}--date-picker__input--warn {
162
+ inline-size: rem(152px);
163
+ }
164
+ }
165
+
166
+ .#{$prefix}--date-picker-container--short {
167
+ &.#{$prefix}--date-picker-container--simple {
168
+ .#{$prefix}--date-picker__input {
169
+ inline-size: rem(90px);
170
+ }
171
+ }
172
+ }
173
+
174
+ // Single date picker sizing
175
+ .#{$prefix}--date-picker-container--single {
176
+ max-inline-size: rem(288px);
177
+
178
+ .#{$prefix}--date-picker__input {
179
+ inline-size: rem(288px);
180
+ }
181
+ }
182
+
183
+ // Range date picker sizing
184
+ .#{$prefix}--date-picker-container--from {
185
+ margin-inline-end: rem(1px);
186
+ }
187
+
188
+ .#{$prefix}--date-picker-container--from,
189
+ .#{$prefix}--date-picker-container--to {
190
+ inline-size: rem(143.5px);
191
+
192
+ .#{$prefix}--date-picker__input {
193
+ inline-size: rem(143.5px);
194
+ }
195
+ }
196
+
197
+ // AI label decorator
198
+ .#{$prefix}--date-picker-container--ai-label {
199
+ .#{$prefix}--date-picker__input--decorator {
200
+ @include ai-gradient;
201
+ }
202
+ }
203
+
204
+ // =============================================================================
205
+ // SKELETON STYLES
206
+ // =============================================================================
207
+
208
+ .#{$prefix}--date-picker-input-skeleton {
209
+ display: inline-block;
210
+
211
+ .#{$prefix}--label {
212
+ @include skeleton;
213
+
214
+ block-size: rem(14px);
215
+ inline-size: rem(75px);
216
+ }
217
+
218
+ .#{$prefix}--date-picker-input-skeleton-container {
219
+ display: inline-block;
220
+ }
221
+ }
222
+
223
+ .#{$prefix}--date-picker-input-skeleton--range {
224
+ .#{$prefix}--date-picker-input-skeleton-container {
225
+ inline-size: rem(143.5px);
226
+
227
+ .#{$prefix}--date-picker__input {
228
+ inline-size: rem(143.5px);
229
+ }
230
+ }
231
+ }
232
+ // New skeleton styles for DatePickerSkeleton component
233
+ .#{$prefix}--date-picker.#{$prefix}--skeleton {
234
+ .#{$prefix}--date-picker__input.#{$prefix}--skeleton {
235
+ @include skeleton;
236
+
237
+ position: relative;
238
+ overflow: hidden;
239
+ border: none;
240
+ block-size: rem(40px);
241
+ cursor: default;
242
+ inline-size: 100%;
243
+ pointer-events: none;
244
+ }
245
+
246
+ .#{$prefix}--date-picker__icon.#{$prefix}--skeleton {
247
+ display: none;
248
+ }
249
+ }
250
+
251
+ // =============================================================================
252
+ // CALENDAR COMPONENT STYLES
253
+ // =============================================================================
254
+
255
+ .#{$prefix}--date-picker__calendar {
256
+ display: block;
257
+ padding: $spacing-03;
258
+ border: none;
259
+ background-color: $layer;
260
+ box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2);
261
+ inline-size: rem(288px);
262
+ max-inline-size: rem(288px);
263
+ outline: none;
264
+
265
+ &:focus {
266
+ outline: none;
267
+ }
268
+ }
269
+
270
+ // Month header styling
271
+ .#{$prefix}--date-picker__month {
272
+ display: flex;
273
+ align-items: center;
274
+ justify-content: space-between;
275
+ margin-block-end: $spacing-03;
276
+ }
277
+
278
+ .#{$prefix}--date-picker__month-nav {
279
+ display: flex;
280
+ align-items: center;
281
+ justify-content: center;
282
+ border: none;
283
+ background-color: transparent;
284
+ block-size: rem(40px);
285
+ cursor: pointer;
286
+ inline-size: rem(40px);
287
+
288
+ &:hover {
289
+ background-color: $layer-hover;
290
+ }
291
+
292
+ &:focus {
293
+ outline: 2px solid $focus;
294
+ outline-offset: -2px;
295
+ }
296
+
297
+ svg {
298
+ fill: $icon-primary;
299
+ }
300
+ }
301
+
302
+ .#{$prefix}--date-picker__current-month {
303
+ flex: 1;
304
+ color: $text-primary;
305
+ font-size: rem(14px);
306
+ font-weight: 600;
307
+ text-align: center;
308
+ }
309
+
310
+ // Weekdays grid - 7 columns
311
+ .#{$prefix}--date-picker__weekdays {
312
+ display: grid;
313
+ gap: 0;
314
+ grid-template-columns: repeat(7, 1fr);
315
+ margin-block-end: $spacing-02;
316
+ }
317
+
318
+ .#{$prefix}--date-picker__weekday {
319
+ display: flex;
320
+ align-items: center;
321
+ justify-content: center;
322
+ block-size: rem(40px);
323
+ color: $text-primary;
324
+ font-size: rem(12px);
325
+ font-weight: 600;
326
+ // Remove fixed width to allow grid to distribute space evenly
327
+ // inline-size: rem(40px);
328
+ }
329
+
330
+ // Days grid - 7 columns, 6 rows
331
+ .#{$prefix}--date-picker__days {
332
+ display: grid;
333
+ gap: 0;
334
+ grid-template-columns: repeat(7, 1fr);
335
+ }
336
+
337
+ .#{$prefix}--date-picker__day {
338
+ display: flex;
339
+ align-items: center;
340
+ justify-content: center;
341
+ border: none;
342
+ background-color: transparent;
343
+ block-size: rem(40px);
344
+ color: $text-primary;
345
+ cursor: pointer;
346
+ font-size: rem(14px);
347
+ // Remove fixed width to allow grid to distribute space evenly
348
+ // inline-size: rem(40px);
349
+ &:hover:not(:disabled, .selected) {
350
+ background-color: $layer-hover;
351
+ }
352
+
353
+ &:focus {
354
+ outline: 2px solid $focus;
355
+ outline-offset: -2px;
356
+ }
357
+
358
+ // Selected date - white text on blue background (no hover state)
359
+ &.selected {
360
+ background-color: $interactive;
361
+ color: $text-inverse;
362
+ }
363
+
364
+ // Today's date - blue dot indicator
365
+ &.today:not(.selected) {
366
+ position: relative;
367
+ color: $text-primary;
368
+ font-weight: 600;
369
+
370
+ // Blue dot below the date number
371
+ &::after {
372
+ position: absolute;
373
+ border-radius: 50%;
374
+ background-color: $interactive;
375
+ block-size: 4px;
376
+ content: '';
377
+ inline-size: 4px;
378
+ inset-block-end: 4px;
379
+ inset-inline-start: 50%;
380
+ transform: translateX(-50%);
381
+ }
382
+ }
383
+
384
+ // Date in selected range (for range picker)
385
+ &.inRange:not(.selected) {
386
+ background-color: $highlight;
387
+ }
388
+
389
+ // Dates from other months (but not if selected)
390
+ &.prevMonthDay:not(.selected),
391
+ &.nextMonthDay:not(.selected) {
392
+ color: $text-secondary;
393
+ }
394
+
395
+ // Disabled dates
396
+ &.disabled {
397
+ color: $text-disabled;
398
+ cursor: not-allowed;
399
+ opacity: 0.5;
400
+ }
401
+
402
+ // Keyboard focus state (different from browser :focus)
403
+ &.focused:not(.selected) {
404
+ background-color: $layer-hover;
405
+ outline: 2px solid $focus;
406
+ outline-offset: -2px;
407
+ }
408
+ }
409
+ }
410
+
411
+ /// React scoping: nest the next rules under `.#{$prefix}--date-picker--next`
412
+ /// so they only apply to the next date picker and stay isolated from v11.
413
+ /// @access public
414
+ /// @group date-picker
415
+ @mixin date-picker-next {
416
+ .#{$prefix}--date-picker--next {
417
+ position: relative;
418
+
419
+ @include date-picker-next-rules;
420
+ }
421
+ }
@@ -6,6 +6,9 @@
6
6
  //
7
7
 
8
8
  @forward 'date-picker';
9
+ @forward 'date-picker-next';
9
10
  @use 'date-picker';
11
+ @use 'date-picker-next';
10
12
 
11
13
  @include date-picker.date-picker;
14
+ @include date-picker-next.date-picker-next;
@@ -33,15 +33,7 @@
33
33
  .#{$prefix}--modal {
34
34
  // For modals using the native dialog element, the modal visibility is handled
35
35
  // by the Dialog styles.
36
- @if not(
37
- enabled('enable-experimental-focus-wrap-without-sentinels') or
38
- $enable-experimental-focus-wrap-without-sentinels or
39
- enabled('enable-focus-wrap-without-sentinels') or
40
- $enable-focus-wrap-without-sentinels or
41
- enabled('enable-dialog-element') or
42
- $enable-dialog-element
43
- )
44
- {
36
+ @if not(enabled('enable-dialog-element') or $enable-dialog-element) {
45
37
  position: fixed;
46
38
  z-index: z('modal');
47
39
  display: flex;
@@ -70,15 +62,7 @@
70
62
 
71
63
  // For modals using the native dialog element, the modal visibility is handled
72
64
  // by the Dialog styles.
73
- @if not(
74
- enabled('enable-experimental-focus-wrap-without-sentinels') or
75
- $enable-experimental-focus-wrap-without-sentinels or
76
- enabled('enable-focus-wrap-without-sentinels') or
77
- $enable-focus-wrap-without-sentinels or
78
- enabled('enable-dialog-element') or
79
- $enable-dialog-element
80
- )
81
- {
65
+ @if not(enabled('enable-dialog-element') or $enable-dialog-element) {
82
66
  .#{$prefix}--modal--enable-presence {
83
67
  @include modal-container-animations($has-presence: true);
84
68
  }
@@ -1,5 +1,5 @@
1
1
  //
2
- // Copyright IBM Corp. 2016, 2023
2
+ // Copyright IBM Corp. 2016, 2026
3
3
  //
4
4
  // This source code is licensed under the Apache-2.0 license found in the
5
5
  // LICENSE file in the root directory of this source tree.
@@ -101,8 +101,10 @@
101
101
  padding-inline: $spacing-05 2.25rem;
102
102
  }
103
103
 
104
- .#{$prefix}--pagination .#{$prefix}--select-input:hover {
105
- background: $layer-hover;
104
+ @media (any-hover: hover) {
105
+ .#{$prefix}--pagination .#{$prefix}--select-input:hover {
106
+ background: $layer-hover;
107
+ }
106
108
  }
107
109
 
108
110
  .#{$prefix}--pagination
@@ -235,9 +237,11 @@
235
237
  border-inline-start: 0;
236
238
  }
237
239
 
238
- .#{$prefix}--pagination__button:hover,
239
- .#{$prefix}--btn--ghost:hover.#{$prefix}--pagination__button {
240
- background: $layer-hover;
240
+ @media (any-hover: hover) {
241
+ .#{$prefix}--pagination__button:hover,
242
+ .#{$prefix}--btn--ghost:hover.#{$prefix}--pagination__button {
243
+ background: $layer-hover;
244
+ }
241
245
  }
242
246
 
243
247
  .#{$prefix}--pagination__button--no-index,
@@ -246,14 +250,16 @@
246
250
  fill: $icon-disabled;
247
251
  }
248
252
 
249
- .#{$prefix}--pagination__button:disabled:hover,
250
- .#{$prefix}--pagination__button--no-index:hover,
251
- .#{$prefix}--btn--ghost:disabled:hover.#{$prefix}--pagination__button,
252
- .#{$prefix}--btn--ghost:hover.#{$prefix}--pagination__button--no-index {
253
- border-color: $border-subtle;
254
- background: $layer;
255
- cursor: not-allowed;
256
- fill: $icon-disabled;
253
+ @media (any-hover: hover) {
254
+ .#{$prefix}--pagination__button:disabled:hover,
255
+ .#{$prefix}--pagination__button--no-index:hover,
256
+ .#{$prefix}--btn--ghost:disabled:hover.#{$prefix}--pagination__button,
257
+ .#{$prefix}--btn--ghost:hover.#{$prefix}--pagination__button--no-index {
258
+ border-color: $border-subtle;
259
+ background: $layer;
260
+ cursor: not-allowed;
261
+ fill: $icon-disabled;
262
+ }
257
263
  }
258
264
 
259
265
  // Skeleton state
@@ -276,10 +282,15 @@
276
282
  // Override for disabled select inputs to maintain layer background color
277
283
  .#{$prefix}--pagination
278
284
  .#{$prefix}--select--inline
279
- .#{$prefix}--select-input[disabled],
280
- .#{$prefix}--pagination
281
- .#{$prefix}--select--inline
282
- .#{$prefix}--select-input[disabled]:hover {
285
+ .#{$prefix}--select-input[disabled] {
283
286
  background-color: $layer;
284
287
  }
288
+
289
+ @media (any-hover: hover) {
290
+ .#{$prefix}--pagination
291
+ .#{$prefix}--select--inline
292
+ .#{$prefix}--select-input[disabled]:hover {
293
+ background-color: $layer;
294
+ }
295
+ }
285
296
  }
@@ -1,5 +1,5 @@
1
1
  //
2
- // Copyright IBM Corp. 2016, 2023
2
+ // Copyright IBM Corp. 2016, 2026
3
3
  //
4
4
  // This source code is licensed under the Apache-2.0 license found in the
5
5
  // LICENSE file in the root directory of this source tree.
@@ -103,9 +103,11 @@
103
103
  @include focus-outline('outline');
104
104
  }
105
105
 
106
- .#{$prefix}--unstable-pagination__button:hover {
107
- background: $layer-hover;
108
- color: $icon-primary;
106
+ @media (any-hover: hover) {
107
+ .#{$prefix}--unstable-pagination__button:hover {
108
+ background: $layer-hover;
109
+ color: $icon-primary;
110
+ }
109
111
  }
110
112
 
111
113
  .#{$prefix}--unstable-pagination__button--no-index {
@@ -118,11 +120,13 @@
118
120
  background: transparent;
119
121
  }
120
122
 
121
- .#{$prefix}--unstable-pagination__button:disabled:hover,
122
- .#{$prefix}--unstable-pagination__button--no-index:hover {
123
- background: transparent;
124
- cursor: not-allowed;
125
- fill: $icon-disabled;
123
+ @media (any-hover: hover) {
124
+ .#{$prefix}--unstable-pagination__button:disabled:hover,
125
+ .#{$prefix}--unstable-pagination__button--no-index:hover {
126
+ background: transparent;
127
+ cursor: not-allowed;
128
+ fill: $icon-disabled;
129
+ }
126
130
  }
127
131
 
128
132
  .#{$prefix}--unstable-pagination__page-selector,
@@ -152,10 +156,13 @@
152
156
  min-inline-size: auto;
153
157
  }
154
158
 
155
- .#{$prefix}--unstable-pagination__page-selector
156
- .#{$prefix}--select-input:hover,
157
- .#{$prefix}--unstable-pagination__page-sizer .#{$prefix}--select-input:hover {
158
- background: $layer-hover;
159
+ @media (any-hover: hover) {
160
+ .#{$prefix}--unstable-pagination__page-selector
161
+ .#{$prefix}--select-input:hover,
162
+ .#{$prefix}--unstable-pagination__page-sizer
163
+ .#{$prefix}--select-input:hover {
164
+ background: $layer-hover;
165
+ }
159
166
  }
160
167
 
161
168
  .#{$prefix}--unstable-pagination__page-selector .#{$prefix}--select__arrow,
@@ -0,0 +1,11 @@
1
+ //
2
+ // Copyright IBM Corp. 2025
3
+ //
4
+ // This source code is licensed under the Apache-2.0 license found in the
5
+ // LICENSE file in the root directory of this source tree.
6
+ //
7
+
8
+ @forward 'resizer';
9
+ @use 'resizer';
10
+
11
+ @include resizer.resizer;
@@ -0,0 +1,60 @@
1
+ //
2
+ // Copyright IBM Corp. 2025
3
+ //
4
+ // This source code is licensed under the Apache-2.0 license found in the
5
+ // LICENSE file in the root directory of this source tree.
6
+ //
7
+
8
+ @use '../../config' as *;
9
+ @use '../../theme';
10
+ @use '../../motion';
11
+ @use '../../utilities/focus-outline';
12
+ @use '../../utilities/visually-hidden';
13
+
14
+ @mixin resizer {
15
+ .#{$prefix}--resizer {
16
+ position: relative;
17
+ flex: none;
18
+ background-color: theme.$border-subtle;
19
+
20
+ &:hover {
21
+ @media (prefers-reduced-motion: no-preference) {
22
+ background-color: theme.$border-interactive;
23
+ transition: background-color motion.$duration-moderate-01;
24
+ }
25
+ }
26
+
27
+ &:focus {
28
+ background-color: theme.$border-interactive;
29
+ outline: none;
30
+ }
31
+
32
+ &:active {
33
+ background-color: theme.$border-interactive;
34
+ }
35
+
36
+ &:focus:not(:focus-visible) {
37
+ box-shadow: none;
38
+ outline: none;
39
+ }
40
+
41
+ &:focus-visible {
42
+ @include focus-outline.focus-outline('outline');
43
+ }
44
+
45
+ &--horizontal {
46
+ cursor: ns-resize;
47
+ }
48
+
49
+ &--vertical {
50
+ cursor: ew-resize;
51
+ }
52
+ }
53
+
54
+ // Smooth transition helper applied to resizable siblings
55
+ .#{$prefix}--smooth-resize {
56
+ @media (prefers-reduced-motion: no-preference) {
57
+ transition: all motion.$duration-moderate-01 linear;
58
+ }
59
+ }
60
+ }