@stackoverflow/stacks 0.75.0 → 0.76.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 (87) hide show
  1. package/LICENSE.MD +9 -9
  2. package/README.md +47 -47
  3. package/dist/controllers/index.d.ts +7 -0
  4. package/dist/controllers/s-expandable-control.d.ts +17 -0
  5. package/dist/controllers/s-modal.d.ts +97 -0
  6. package/dist/controllers/s-navigation-tablist.d.ts +36 -0
  7. package/dist/controllers/s-popover.d.ts +155 -0
  8. package/dist/controllers/s-table.d.ts +8 -0
  9. package/dist/controllers/s-tooltip.d.ts +82 -0
  10. package/dist/controllers/s-uploader.d.ts +48 -0
  11. package/dist/css/stacks.css +86 -53
  12. package/dist/css/stacks.min.css +1 -1
  13. package/dist/index.d.ts +3 -0
  14. package/dist/js/stacks.js +6128 -5505
  15. package/dist/js/stacks.min.js +1 -1
  16. package/dist/stacks.d.ts +21 -0
  17. package/lib/css/atomic/_stacks-borders.less +378 -378
  18. package/lib/css/atomic/_stacks-colors.less +209 -209
  19. package/lib/css/atomic/_stacks-flex.less +374 -374
  20. package/lib/css/atomic/_stacks-grid.less +174 -173
  21. package/lib/css/atomic/_stacks-misc.less +343 -343
  22. package/lib/css/atomic/_stacks-spacing.less +168 -168
  23. package/lib/css/atomic/_stacks-typography.less +273 -273
  24. package/lib/css/atomic/_stacks-width-height.less +195 -195
  25. package/lib/css/base/_stacks-body.less +44 -46
  26. package/lib/css/base/_stacks-configuration-static.less +59 -59
  27. package/lib/css/base/_stacks-icons.less +20 -20
  28. package/lib/css/base/_stacks-internals.less +220 -230
  29. package/lib/css/base/_stacks-reset-meyer.less +64 -64
  30. package/lib/css/base/_stacks-reset-normalize.less +449 -449
  31. package/lib/css/base/_stacks-reset.less +20 -20
  32. package/lib/css/components/_stacks-activity-indicator.less +45 -45
  33. package/lib/css/components/_stacks-avatars.less +189 -189
  34. package/lib/css/components/_stacks-badges.less +209 -209
  35. package/lib/css/components/_stacks-banners.less +80 -81
  36. package/lib/css/components/_stacks-blank-states.less +26 -26
  37. package/lib/css/components/_stacks-breadcrumbs.less +44 -44
  38. package/lib/css/components/_stacks-button-groups.less +104 -104
  39. package/lib/css/components/_stacks-buttons.less +658 -660
  40. package/lib/css/components/_stacks-cards.less +44 -44
  41. package/lib/css/components/_stacks-code-blocks.less +130 -130
  42. package/lib/css/components/_stacks-collapsible.less +104 -104
  43. package/lib/css/components/_stacks-inputs.less +728 -728
  44. package/lib/css/components/_stacks-link-previews.less +136 -136
  45. package/lib/css/components/_stacks-links.less +218 -218
  46. package/lib/css/components/_stacks-menu.less +47 -47
  47. package/lib/css/components/_stacks-modals.less +133 -133
  48. package/lib/css/components/_stacks-navigation.less +146 -146
  49. package/lib/css/components/_stacks-notices.less +233 -233
  50. package/lib/css/components/_stacks-page-titles.less +60 -60
  51. package/lib/css/components/_stacks-pagination.less +55 -55
  52. package/lib/css/components/_stacks-popovers.less +197 -197
  53. package/lib/css/components/_stacks-post-summary.less +425 -425
  54. package/lib/css/components/_stacks-progress-bars.less +331 -331
  55. package/lib/css/components/_stacks-prose.less +503 -503
  56. package/lib/css/components/_stacks-spinner.less +107 -107
  57. package/lib/css/components/_stacks-tables.less +341 -341
  58. package/lib/css/components/_stacks-tags.less +236 -244
  59. package/lib/css/components/_stacks-toggle-switches.less +144 -144
  60. package/lib/css/components/_stacks-topbar.less +425 -440
  61. package/lib/css/components/_stacks-uploader.less +210 -210
  62. package/lib/css/components/_stacks-user-cards.less +169 -169
  63. package/lib/css/components/_stacks-widget-dynamic.less +33 -33
  64. package/lib/css/components/_stacks-widget-static.less +272 -272
  65. package/lib/css/exports/_stacks-constants-colors.less +1112 -1112
  66. package/lib/css/exports/_stacks-constants-helpers.less +139 -139
  67. package/lib/css/exports/_stacks-constants-type.less +152 -91
  68. package/lib/css/exports/_stacks-exports.less +15 -15
  69. package/lib/css/exports/_stacks-mixins.less +220 -220
  70. package/lib/css/stacks-dynamic.less +35 -36
  71. package/lib/css/stacks-static.less +86 -86
  72. package/lib/ts/controllers/index.ts +8 -0
  73. package/lib/ts/controllers/s-expandable-control.ts +189 -190
  74. package/lib/ts/controllers/s-modal.ts +321 -323
  75. package/lib/ts/controllers/s-navigation-tablist.ts +118 -119
  76. package/lib/ts/controllers/s-popover.ts +547 -549
  77. package/lib/ts/controllers/s-table.ts +220 -220
  78. package/lib/ts/controllers/s-tooltip.ts +246 -247
  79. package/lib/ts/controllers/s-uploader.ts +172 -174
  80. package/lib/ts/index.ts +20 -0
  81. package/lib/ts/stacks.ts +88 -83
  82. package/lib/tsconfig.json +13 -11
  83. package/package.json +87 -71
  84. package/dist/css/stacks-flexgrid-shim.min.css +0 -1
  85. package/lib/css/base/_stacks-configuration-dynamic.less +0 -106
  86. package/lib/ts/finalize.ts +0 -1
  87. package/lib/ts/stimulus.d.ts +0 -4
@@ -1,728 +1,728 @@
1
- //
2
- // STACK OVERFLOW
3
- // INPUTS
4
- //
5
- // This CSS comes from Stacks, our CSS & Pattern library for rapidly building
6
- // Stack Overflow. For documentation of all these classes and how to contribute,
7
- // visit https://stackoverflow.design/
8
- //
9
- // TABLE OF CONTENTS
10
- // • Variables
11
- // • Inputs
12
- // - Base Style (Input / Textarea)
13
- // - Textarea Styles
14
- // - Fieldset Resets
15
- // • Labels
16
- // • Label Statuses
17
- // • Text Styles
18
- // • Connected Input Fills
19
- // • Select Menus
20
- // • Checkbox & Radio
21
- // • Input States
22
- // • Validation States
23
- // • Input Sizes
24
- // ============================================================================
25
- // $ VARIABLES & MIXINS
26
- // ----------------------------------------------------------------------------
27
- @input-padding: 0.6em 0.7em;
28
-
29
- @autofill: {
30
- &::-webkit-contacts-auto-fill-button {
31
- background-color: var(--black); // In Safari, make the autocomplete button darkmode-aware
32
- }
33
-
34
- &:-webkit-autofill {
35
- border-color: var(--blue-300);
36
- -webkit-text-fill-color: var(--black);
37
- -webkit-box-shadow: 0 0 0 1000px var(--theme-secondary-050) inset; // This acts as a background color by stretching an inset box shadow across the input
38
- transition: background-color 0s 50000s; // A hack to infinitely delay background styles that come from the browser.
39
-
40
- &:focus {
41
- border-color: var(--blue-300);
42
- // Since the box shadow is overwritten to show a background, we have to re-add the focus outline
43
- -webkit-box-shadow: 0 0 0 1000px var(--blue-050) inset, 0 0 0 @su4 var(--focus-ring);
44
- }
45
- }
46
- }
47
-
48
- @basic-styling: {
49
- -webkit-appearance: none; // Removes shadows we don't want in mobile Safari
50
- width: 100%;
51
- margin: 0; // A guard against Core's default margins
52
- padding: @input-padding;
53
- border: 1px solid var(--bc-darker);
54
- border-radius: @br-sm;
55
- background-color: var(--white);
56
- color: var(--fc-dark);
57
- font-size: @fs-body1;
58
- font-family: inherit;
59
-
60
- // -- INCREASE FONT SIZE FOR MOBILE SAFARI
61
- // This keeps our inputs from zooming the page while focused
62
- // ------------------------------------------------------------------------
63
- @supports (-webkit-overflow-scrolling: touch) {
64
- font-size: 16px;
65
- padding: 0.36em 0.55em; // Compensate for the larger font size so we generally keep the input the same size
66
-
67
- &::-webkit-input-placeholder {
68
- line-height: normal !important;
69
- }
70
- }
71
-
72
- // -- PLACEHOLDER
73
- // ------------------------------------------------------------------------
74
- &::-webkit-input-placeholder {
75
- color: var(--black-200);
76
-
77
- .highcontrast-mode({
78
- color: var(--black-400);
79
- });
80
- }
81
-
82
- &::placeholder {
83
- color: var(--black-200);
84
- opacity: 1;
85
-
86
- .highcontrast-mode({
87
- color: var(--black-400);
88
- });
89
- }
90
-
91
- // -- STYLE SCROLLBARS
92
- @scrollbar-styles();
93
-
94
- // -- STYLE AUTOFILL STATES
95
- @autofill();
96
- }
97
-
98
- // ============================================================================
99
- // $ BASE INPUT / TEXTAREA STYLE
100
- // ----------------------------------------------------------------------------
101
- .s-input,
102
- .s-textarea {
103
- @basic-styling();
104
- }
105
-
106
- .s-input.s-input__search,
107
- .s-input.s-input__creditcard {
108
- padding-left: @su32;
109
- }
110
-
111
-
112
- // ============================================================================
113
- // $ FIELDSET
114
- // ----------------------------------------------------------------------------
115
- fieldset {
116
- min-width: 0;
117
- padding: 0;
118
- border: 0;
119
-
120
- &[disabled] {
121
- a,
122
- .s-btn,
123
- .s-link {
124
- box-shadow: none !important;
125
- opacity: 0.5;
126
- pointer-events: none;
127
- }
128
-
129
- .s-checkbox,
130
- .s-input-message,
131
- .s-label,
132
- .s-radio,
133
- .s-toggle-switch,
134
- .s-toggle-switch label {
135
- cursor: not-allowed;
136
- opacity: 0.5;
137
- }
138
-
139
- .s-input,
140
- .s-textarea,
141
- .s-select > select {
142
- cursor: not-allowed;
143
- opacity: 0.5;
144
- }
145
- }
146
- }
147
-
148
- // ============================================================================
149
- // $ LABELS
150
- // ============================================================================
151
- .s-label {
152
- padding: 0 @su2; // Helps the label visually line up with inputs
153
- color: var(--fc-dark);
154
- font-family: inherit;
155
- font-size: @fs-body2;
156
- font-weight: 600;
157
-
158
- &[for] {
159
- cursor: pointer;
160
- }
161
- }
162
-
163
- // $$ LABEL STATUS FLAG
164
- // ----------------------------------------------------------------------------
165
- // Is this form item required or optional? Flag the status for users.
166
- // Default styling is optional.
167
- .s-label--status {
168
- margin-left: @su4;
169
- padding: @su2 @su8;
170
- border-radius: 1000px;
171
- background-color: var(--black-050);
172
- color: var(--fc-medium);
173
- font-size: @fs-caption;
174
- font-weight: 400;
175
- vertical-align: text-bottom;
176
-
177
- .highcontrast-mode({
178
- border: 1px solid currentColor;
179
- });
180
-
181
- &.s-label--status__required {
182
- background-color: var(--red-100);
183
- color: var(--red-600);
184
-
185
- .dark-mode({
186
- color: var(--red-800);
187
- });
188
- }
189
-
190
- &.s-label--status__new {
191
- background-color: var(--green-100);
192
- color: var(--green-700);
193
- }
194
-
195
- &.s-label--status__beta {
196
- background-color: var(--blue-100);
197
- color: var(--blue-700);
198
- }
199
- }
200
-
201
-
202
- // ============================================================================
203
- // $ TEXT STYLES
204
- // ============================================================================
205
- .s-description {
206
- padding: 0 @su2; // Helps the label visually line up with inputs
207
- color: var(--fc-medium);
208
- font-size: @fs-caption;
209
- }
210
-
211
- .s-label .s-description,
212
- .s-label .s-input-message {
213
- padding: 0;
214
- margin-top: 4px;
215
- margin-bottom: 0;
216
- font-weight: normal;
217
- }
218
-
219
- // ============================================================================
220
- // $ CONNECTED INPUTS
221
- // To visually connect inputs together
222
- // ----------------------------------------------------------------------------
223
- .s-input-fill {
224
- padding: @input-padding;
225
- border: 1px solid var(--bc-darker);
226
- border-right-width: 0;
227
- border-left-width: 0;
228
- background-color: var(--black-050);
229
- color: var(--fc-medium);
230
- font-family: inherit;
231
- white-space: nowrap;
232
- line-height: @lh-sm;
233
-
234
- &.s-input-fill__clear {
235
- border-color: transparent;
236
- background-color: transparent;
237
- }
238
-
239
- &.order-first {
240
- border-left-width: 1px;
241
- border-top-left-radius: @br-sm;
242
- border-bottom-left-radius: @br-sm;
243
- }
244
-
245
- &.order-last {
246
- border-right-width: 1px;
247
- border-top-right-radius: @br-sm;
248
- border-bottom-right-radius: @br-sm;
249
- }
250
- }
251
-
252
-
253
- // ============================================================================
254
- // $ SELECT MENUS
255
- // ----------------------------------------------------------------------------
256
- .s-select {
257
- position: relative;
258
- color: var(--fc-dark);
259
-
260
- // -- MENU ARROWS
261
- // To customize the visual appearance of the select menu arrows, we
262
- // need to recreate them on the wrapping .select div.
263
- // ------------------------------------------------------------------------
264
- &:before,
265
- &:after {
266
- content: "";
267
- position: absolute;
268
- z-index: @zi-selected;
269
- right: 13px;
270
- border-color: currentColor transparent;
271
- border-style: solid;
272
- border-width: 4px;
273
- pointer-events: none;
274
- }
275
- &:before {
276
- top: calc(50% - 5px);
277
- border-top-width: 0;
278
- border-bottom-width: 4px;
279
- }
280
- &:after {
281
- top: calc(50% + 1px);
282
- border-top-width: 4px;
283
- border-bottom-width: 0;
284
- }
285
-
286
- // -- MENU
287
- // Now we can style the visual appearance of the select menu;
288
- // ------------------------------------------------------------------------
289
- > select {
290
- // [1] Reset the appearance
291
- -webkit-appearance: none;
292
- -moz-appearance: none;
293
- appearance: none;
294
-
295
- // [2] Update the styles
296
- position: relative; // This prevents Firefox from requiring a second click to select options
297
- width: 100%;
298
- height: 100%; // Fill the height of its parent
299
- padding: @input-padding;
300
- padding-right: @su32;
301
- border: 1px solid var(--bc-darker);
302
- border-radius: @br-sm;
303
- background-color: var(--white);
304
- outline: 0;
305
- font-size: @fs-body1;
306
- font-family: inherit;
307
- color: var(--black);
308
- line-height: @lh-sm;
309
-
310
- &::-moz-focus-inner {
311
- outline: none !important;
312
- }
313
-
314
- &:-moz-focusring {
315
- color: transparent;
316
- text-shadow: 0 0 0 #000;
317
- }
318
-
319
- &::-ms-expand {
320
- display: none;
321
- }
322
-
323
- // -- INCREASE FONT SIZE FOR MOBILE SAFARI
324
- // This keeps our inputs from zooming the page while focused
325
- // ------------------------------------------------------------------------
326
- @supports (-webkit-overflow-scrolling: touch) {
327
- font-size: 16px;
328
- padding: 0.4em 0.55em; // Compensate for the larger font size so we generally keep the input the same size
329
- }
330
-
331
- // -- STYLE AUTOFILL STATES
332
- @autofill();
333
- }
334
- }
335
-
336
-
337
- // ============================================================================
338
- // $ CHECKBOXES & RADIOS
339
- // ----------------------------------------------------------------------------
340
- .s-checkbox,
341
- .s-radio {
342
- // [1] Check to see if we can use custom styles, if so reset the defaults
343
- // ------------------------------------------------------------------------
344
- @supports ((-webkit-appearance: none) or (-moz-appearance: none) or (appearance: none)) {
345
- .appearance(none);
346
-
347
- &::-ms-check {
348
- display: none;
349
- }
350
-
351
- // [2] Now re-style the checkboxes and radios
352
- // ------------------------------------------------------------------------
353
- margin: 0; // A guard against Core's default margins
354
- width: 1em;
355
- height: 1em;
356
- border: 1px solid var(--bc-darker);
357
- background-color: var(--white);
358
- outline: 0;
359
- font-size: inherit;
360
- vertical-align: middle;
361
- cursor: pointer;
362
- }
363
-
364
- // Disabled
365
- &[disabled] {
366
- opacity: 0.5;
367
- cursor: not-allowed;
368
- }
369
- }
370
-
371
- // $$ CHECKBOXES
372
- // ----------------------------------------------------------------------------
373
- .s-checkbox {
374
- @supports ((-webkit-appearance: none) or (-moz-appearance: none) or (appearance: none)) {
375
- border-radius: @br-sm;
376
- background-position: center center;
377
- background-repeat: no-repeat;
378
- background-size: contain;
379
-
380
- &:checked {
381
- border-color: var(--theme-secondary-400) !important;
382
- background-color: var(--theme-secondary-400);
383
- background-image: url("data:image/svg+xml,%3Csvg width='11' height='11' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10 3.41L8.59 2 4 6.59 2.41 5 1 6.41l3 3z' fill='%23fff'/%3E%3C/svg%3E");
384
-
385
- .highcontrast-dark-mode({
386
- border-color: var(--blue-700) !important;
387
- background-color: var(--blue-300);
388
- });
389
-
390
- &:focus {
391
- border-color: var(--theme-secondary-400);
392
- }
393
- }
394
-
395
- &:focus {
396
- border-color: var(--theme-secondary-300);
397
- box-shadow: 0 0 0 @su4 var(--focus-ring);
398
- }
399
- }
400
- }
401
-
402
- // $$ RADIOS
403
- // ----------------------------------------------------------------------------
404
- .s-radio {
405
- @supports ((-webkit-appearance: none) or (-moz-appearance: none) or (appearance: none)) {
406
- border-radius: @br-circle;
407
-
408
- &:checked {
409
- border-color: var(--theme-secondary-400);
410
- border-width: 0.30769231em;
411
- background-color: @white; // This should always be white regardless of dark mode
412
-
413
- .highcontrast-dark-mode({
414
- border-color: var(--blue-300);
415
- outline: 1px solid var(--black);
416
- });
417
- }
418
-
419
- &:focus {
420
- box-shadow: 0 0 0 @su4 var(--focus-ring);
421
- }
422
- }
423
- }
424
-
425
- // ============================================================================
426
- // $ STATES
427
- // The many states for inputs and select menus.
428
- // ----------------------------------------------------------------------------
429
- // Focus
430
- & {
431
- @focus-style: {
432
- border-color: var(--theme-secondary-300);
433
- box-shadow: 0 0 0 @su4 var(--focus-ring);
434
- color: var(--black);
435
- outline: 0;
436
-
437
- .highcontrast-mode({
438
- border-color: var(--black);
439
- })
440
- }
441
-
442
- .s-input:focus,
443
- .s-input.has-focus,
444
- .s-textarea:focus,
445
- .s-select > select:focus {
446
- @focus-style();
447
- }
448
-
449
- // This needs to be separate from the one above, because in browsers that don't support :focus-within
450
- // it's a syntax error, rendering the whole selector null and void.
451
- .s-input:focus-within {
452
- @focus-style();
453
- }
454
- }
455
-
456
- .s-input,
457
- .s-textarea,
458
- .s-select > select {
459
- // Disabled, Read-only
460
- &[disabled],
461
- &[read-only] {
462
- cursor: not-allowed;
463
- opacity: 0.5;
464
-
465
- .highcontrast-mode({
466
- opacity: 0.5;
467
- });
468
- }
469
-
470
- // Disabled
471
- &[disabled] {
472
- cursor: not-allowed;
473
- opacity: 0.5;
474
- }
475
- }
476
-
477
- // ============================================================================
478
- // $ VALIDATION STATES
479
- // Classes are applied at the wrapping container level.
480
- // ----------------------------------------------------------------------------
481
- .is-disabled,
482
- .has-success,
483
- .has-error,
484
- .has-warning {
485
- position: relative;
486
-
487
- .s-input {
488
- padding-right: @su32;
489
- }
490
-
491
- .s-select .s-input-icon {
492
- right: @su32;
493
- }
494
-
495
- .s-textarea {
496
- padding-right: @su48;
497
-
498
- ~ .s-input-icon {
499
- top: 1.5em;
500
- right: 1.5em;
501
- }
502
- }
503
-
504
- .s-input-message a {
505
- text-decoration: underline;
506
- }
507
- }
508
-
509
- // $$ WARNING
510
- // ----------------------------------------------------------------------------
511
- .has-warning {
512
- .s-input,
513
- .s-textarea,
514
- .s-checkbox,
515
- .s-radio:not(:checked),
516
- .s-select > select {
517
- border-color: var(--yellow-600);
518
-
519
- &:focus {
520
- box-shadow: 0 0 0 @su4 var(--focus-ring-warning);
521
- }
522
- }
523
-
524
- .s-input-message {
525
- color: var(--yellow-800);
526
-
527
- a {
528
- color: var(--yellow-900);
529
- }
530
- }
531
-
532
- .s-input-icon {
533
- color: var(--yellow-600);
534
- }
535
- }
536
-
537
- // $$ ERROR
538
- // ----------------------------------------------------------------------------
539
- .has-error {
540
- .s-input,
541
- .s-textarea,
542
- .s-checkbox,
543
- .s-radio:not(:checked),
544
- .s-select > select {
545
- border-color: var(--red-400);
546
-
547
- &:focus {
548
- box-shadow: 0 0 0 @su4 var(--focus-ring-error);
549
- }
550
- }
551
-
552
- .s-input-message {
553
- color: var(--red-500);
554
-
555
- a {
556
- color: var(--red-800);
557
-
558
- &:hover {
559
- color: var(--red-900);
560
- }
561
- }
562
- }
563
-
564
- .s-input-icon {
565
- color: var(--red-400);
566
- }
567
- }
568
-
569
- // $$ SUCCESS
570
- // ----------------------------------------------------------------------------
571
- .has-success {
572
- .s-input,
573
- .s-textarea,
574
- .s-checkbox,
575
- .s-radio:not(:checked),
576
- .s-select > select {
577
- border-color: var(--green-400);
578
-
579
- &:focus {
580
- box-shadow: 0 0 0 @su4 var(--focus-ring-success);
581
- }
582
- }
583
-
584
- .s-input-message {
585
- color: var(--green-500);
586
-
587
- a {
588
- color: var(--green-800);
589
-
590
- &:hover {
591
- color: var(--green-900);
592
- }
593
- }
594
- }
595
-
596
- .s-input-icon {
597
- color: var(--green-400);
598
- }
599
- }
600
-
601
- // $$ DISABLED
602
- // ----------------------------------------------------------------------------
603
- .is-disabled {
604
- .s-select:before,
605
- .s-select:after {
606
- border-color: var(--bc-darker) transparent;
607
- }
608
-
609
- .s-label,
610
- .s-description {
611
- opacity: 0.5;
612
-
613
- .s-description {
614
- opacity: unset;
615
- }
616
- }
617
-
618
- .s-input-icon {
619
- color: var(--black-200);
620
-
621
- .highcontrast-mode({
622
- color: var(--black-400);
623
- });
624
- }
625
-
626
- .s-label {
627
- cursor: not-allowed;
628
- }
629
- }
630
-
631
- // $$ ICONS
632
- // ----------------------------------------------------------------------------
633
- .s-input-icon {
634
- position: absolute;
635
- top: 50%;
636
- right: 0.7em;
637
- margin-top: -9px; // Half the icon's height at 18px for centering;
638
- pointer-events: none;
639
-
640
- &.s-input-icon__search,
641
- &.s-input-icon__creditcard {
642
- right: auto;
643
- left: 0.7em;
644
- color: var(--black-200);
645
-
646
- .highcontrast-mode({
647
- color: var(--black-400);
648
- });
649
- }
650
- }
651
-
652
- // $$ MESSAGE
653
- // Set some baseline styles
654
- // ----------------------------------------------------------------------------
655
- .s-input-message {
656
- padding: @su2;
657
- font-size: @fs-caption;
658
- }
659
-
660
- // $$ SIZES
661
- // ----------------------------------------------------------------------------
662
- .s-input__sm,
663
- .s-textarea__sm,
664
- .s-label__sm,
665
- .s-select__sm > select {
666
- font-size: @fs-caption;
667
- }
668
- .s-input__md,
669
- .s-textarea__md,
670
- .s-label__md,
671
- .s-select__md > select {
672
- font-size: @fs-body3;
673
- }
674
- .s-input__lg,
675
- .s-textarea__lg,
676
- .s-label__lg,
677
- .s-select__lg > select {
678
- font-size: @fs-title;
679
- }
680
- .s-input__xl,
681
- .s-textarea__xl,
682
- .s-label__xl,
683
- .s-select__xl > select {
684
- font-size: @fs-headline1;
685
- }
686
-
687
- // $$ PADDING ADJUSTMENTS WITHIN SIZES
688
- // ----------------------------------------------------------------------------
689
- .s-input__md,
690
- .s-textarea__md,
691
- .s-select__md > select {
692
- padding-top: 0.5em;
693
- padding-bottom: 0.5em;
694
- border-radius: @br-sm + 1;
695
- }
696
-
697
- .s-textarea__md {
698
- padding-top: 0.72em;
699
- padding-bottom: 0.72em;
700
- }
701
-
702
- .s-input__lg,
703
- .s-textarea__lg,
704
- .s-select__lg > select {
705
- padding: 0.45em 0.6em;
706
- border-radius: @br-sm + 1;
707
- }
708
-
709
- .s-input__xl,
710
- .s-textarea__xl,
711
- .s-select__xl > select {
712
- padding: 0.4em 0.5em;
713
- border-radius: @br-md;
714
- }
715
-
716
- .s-input__md,
717
- .s-textarea__md {
718
- // -- INCREASE FONT SIZE FOR MOBILE SAFARI
719
- // This keeps our inputs from zooming the page while focused
720
- // ------------------------------------------------------------------------
721
- @supports (-webkit-overflow-scrolling: touch) {
722
- font-size: 17px;
723
-
724
- // Compensate for the larger font size so we generally keep the input the same size
725
- padding-top: 0.4em;
726
- padding-bottom: 0.4em;
727
- }
728
- }
1
+ //
2
+ // STACK OVERFLOW
3
+ // INPUTS
4
+ //
5
+ // This CSS comes from Stacks, our CSS & Pattern library for rapidly building
6
+ // Stack Overflow. For documentation of all these classes and how to contribute,
7
+ // visit https://stackoverflow.design/
8
+ //
9
+ // TABLE OF CONTENTS
10
+ // • Variables
11
+ // • Inputs
12
+ // - Base Style (Input / Textarea)
13
+ // - Textarea Styles
14
+ // - Fieldset Resets
15
+ // • Labels
16
+ // • Label Statuses
17
+ // • Text Styles
18
+ // • Connected Input Fills
19
+ // • Select Menus
20
+ // • Checkbox & Radio
21
+ // • Input States
22
+ // • Validation States
23
+ // • Input Sizes
24
+ // ============================================================================
25
+ // $ VARIABLES & MIXINS
26
+ // ----------------------------------------------------------------------------
27
+ @input-padding: 0.6em 0.7em;
28
+
29
+ @autofill: {
30
+ &::-webkit-contacts-auto-fill-button {
31
+ background-color: var(--black); // In Safari, make the autocomplete button darkmode-aware
32
+ }
33
+
34
+ &:-webkit-autofill {
35
+ border-color: var(--blue-300);
36
+ -webkit-text-fill-color: var(--black);
37
+ -webkit-box-shadow: 0 0 0 1000px var(--theme-secondary-050) inset; // This acts as a background color by stretching an inset box shadow across the input
38
+ transition: background-color 0s 50000s; // A hack to infinitely delay background styles that come from the browser.
39
+
40
+ &:focus {
41
+ border-color: var(--blue-300);
42
+ // Since the box shadow is overwritten to show a background, we have to re-add the focus outline
43
+ -webkit-box-shadow: 0 0 0 1000px var(--blue-050) inset, 0 0 0 @su4 var(--focus-ring);
44
+ }
45
+ }
46
+ }
47
+
48
+ @basic-styling: {
49
+ -webkit-appearance: none; // Removes shadows we don't want in mobile Safari
50
+ width: 100%;
51
+ margin: 0; // A guard against Core's default margins
52
+ padding: @input-padding;
53
+ border: 1px solid var(--bc-darker);
54
+ border-radius: @br-sm;
55
+ background-color: var(--white);
56
+ color: var(--fc-dark);
57
+ font-size: @fs-body1;
58
+ font-family: inherit;
59
+
60
+ // -- INCREASE FONT SIZE FOR MOBILE SAFARI
61
+ // This keeps our inputs from zooming the page while focused
62
+ // ------------------------------------------------------------------------
63
+ @supports (-webkit-overflow-scrolling: touch) {
64
+ font-size: 16px;
65
+ padding: 0.36em 0.55em; // Compensate for the larger font size so we generally keep the input the same size
66
+
67
+ &::-webkit-input-placeholder {
68
+ line-height: normal !important;
69
+ }
70
+ }
71
+
72
+ // -- PLACEHOLDER
73
+ // ------------------------------------------------------------------------
74
+ &::-webkit-input-placeholder {
75
+ color: var(--black-200);
76
+
77
+ .highcontrast-mode({
78
+ color: var(--black-400);
79
+ });
80
+ }
81
+
82
+ &::placeholder {
83
+ color: var(--black-200);
84
+ opacity: 1;
85
+
86
+ .highcontrast-mode({
87
+ color: var(--black-400);
88
+ });
89
+ }
90
+
91
+ // -- STYLE SCROLLBARS
92
+ @scrollbar-styles();
93
+
94
+ // -- STYLE AUTOFILL STATES
95
+ @autofill();
96
+ }
97
+
98
+ // ============================================================================
99
+ // $ BASE INPUT / TEXTAREA STYLE
100
+ // ----------------------------------------------------------------------------
101
+ .s-input,
102
+ .s-textarea {
103
+ @basic-styling();
104
+ }
105
+
106
+ .s-input.s-input__search,
107
+ .s-input.s-input__creditcard {
108
+ padding-left: @su32;
109
+ }
110
+
111
+
112
+ // ============================================================================
113
+ // $ FIELDSET
114
+ // ----------------------------------------------------------------------------
115
+ fieldset {
116
+ min-width: 0;
117
+ padding: 0;
118
+ border: 0;
119
+
120
+ &[disabled] {
121
+ a,
122
+ .s-btn,
123
+ .s-link {
124
+ box-shadow: none !important;
125
+ opacity: 0.5;
126
+ pointer-events: none;
127
+ }
128
+
129
+ .s-checkbox,
130
+ .s-input-message,
131
+ .s-label,
132
+ .s-radio,
133
+ .s-toggle-switch,
134
+ .s-toggle-switch label {
135
+ cursor: not-allowed;
136
+ opacity: 0.5;
137
+ }
138
+
139
+ .s-input,
140
+ .s-textarea,
141
+ .s-select > select {
142
+ cursor: not-allowed;
143
+ opacity: 0.5;
144
+ }
145
+ }
146
+ }
147
+
148
+ // ============================================================================
149
+ // $ LABELS
150
+ // ============================================================================
151
+ .s-label {
152
+ padding: 0 @su2; // Helps the label visually line up with inputs
153
+ color: var(--fc-dark);
154
+ font-family: inherit;
155
+ font-size: @fs-body2;
156
+ font-weight: 600;
157
+
158
+ &[for] {
159
+ cursor: pointer;
160
+ }
161
+ }
162
+
163
+ // $$ LABEL STATUS FLAG
164
+ // ----------------------------------------------------------------------------
165
+ // Is this form item required or optional? Flag the status for users.
166
+ // Default styling is optional.
167
+ .s-label--status {
168
+ margin-left: @su4;
169
+ padding: @su2 @su8;
170
+ border-radius: 1000px;
171
+ background-color: var(--black-050);
172
+ color: var(--fc-medium);
173
+ font-size: @fs-caption;
174
+ font-weight: 400;
175
+ vertical-align: text-bottom;
176
+
177
+ .highcontrast-mode({
178
+ border: 1px solid currentColor;
179
+ });
180
+
181
+ &.s-label--status__required {
182
+ background-color: var(--red-100);
183
+ color: var(--red-600);
184
+
185
+ .dark-mode({
186
+ color: var(--red-800);
187
+ });
188
+ }
189
+
190
+ &.s-label--status__new {
191
+ background-color: var(--green-100);
192
+ color: var(--green-700);
193
+ }
194
+
195
+ &.s-label--status__beta {
196
+ background-color: var(--blue-100);
197
+ color: var(--blue-700);
198
+ }
199
+ }
200
+
201
+
202
+ // ============================================================================
203
+ // $ TEXT STYLES
204
+ // ============================================================================
205
+ .s-description {
206
+ padding: 0 @su2; // Helps the label visually line up with inputs
207
+ color: var(--fc-medium);
208
+ font-size: @fs-caption;
209
+ }
210
+
211
+ .s-label .s-description,
212
+ .s-label .s-input-message {
213
+ padding: 0;
214
+ margin-top: 4px;
215
+ margin-bottom: 0;
216
+ font-weight: normal;
217
+ }
218
+
219
+ // ============================================================================
220
+ // $ CONNECTED INPUTS
221
+ // To visually connect inputs together
222
+ // ----------------------------------------------------------------------------
223
+ .s-input-fill {
224
+ padding: @input-padding;
225
+ border: 1px solid var(--bc-darker);
226
+ border-right-width: 0;
227
+ border-left-width: 0;
228
+ background-color: var(--black-050);
229
+ color: var(--fc-medium);
230
+ font-family: inherit;
231
+ white-space: nowrap;
232
+ line-height: @lh-sm;
233
+
234
+ &.s-input-fill__clear {
235
+ border-color: transparent;
236
+ background-color: transparent;
237
+ }
238
+
239
+ &.order-first {
240
+ border-left-width: 1px;
241
+ border-top-left-radius: @br-sm;
242
+ border-bottom-left-radius: @br-sm;
243
+ }
244
+
245
+ &.order-last {
246
+ border-right-width: 1px;
247
+ border-top-right-radius: @br-sm;
248
+ border-bottom-right-radius: @br-sm;
249
+ }
250
+ }
251
+
252
+
253
+ // ============================================================================
254
+ // $ SELECT MENUS
255
+ // ----------------------------------------------------------------------------
256
+ .s-select {
257
+ position: relative;
258
+ color: var(--fc-dark);
259
+
260
+ // -- MENU ARROWS
261
+ // To customize the visual appearance of the select menu arrows, we
262
+ // need to recreate them on the wrapping .select div.
263
+ // ------------------------------------------------------------------------
264
+ &:before,
265
+ &:after {
266
+ content: "";
267
+ position: absolute;
268
+ z-index: @zi-selected;
269
+ right: 13px;
270
+ border-color: currentColor transparent;
271
+ border-style: solid;
272
+ border-width: 4px;
273
+ pointer-events: none;
274
+ }
275
+ &:before {
276
+ top: calc(50% - 5px);
277
+ border-top-width: 0;
278
+ border-bottom-width: 4px;
279
+ }
280
+ &:after {
281
+ top: calc(50% + 1px);
282
+ border-top-width: 4px;
283
+ border-bottom-width: 0;
284
+ }
285
+
286
+ // -- MENU
287
+ // Now we can style the visual appearance of the select menu;
288
+ // ------------------------------------------------------------------------
289
+ > select {
290
+ // [1] Reset the appearance
291
+ -webkit-appearance: none;
292
+ -moz-appearance: none;
293
+ appearance: none;
294
+
295
+ // [2] Update the styles
296
+ position: relative; // This prevents Firefox from requiring a second click to select options
297
+ width: 100%;
298
+ height: 100%; // Fill the height of its parent
299
+ padding: @input-padding;
300
+ padding-right: @su32;
301
+ border: 1px solid var(--bc-darker);
302
+ border-radius: @br-sm;
303
+ background-color: var(--white);
304
+ outline: 0;
305
+ font-size: @fs-body1;
306
+ font-family: inherit;
307
+ color: var(--black);
308
+ line-height: @lh-sm;
309
+
310
+ &::-moz-focus-inner {
311
+ outline: none !important;
312
+ }
313
+
314
+ &:-moz-focusring {
315
+ color: transparent;
316
+ text-shadow: 0 0 0 #000;
317
+ }
318
+
319
+ &::-ms-expand {
320
+ display: none;
321
+ }
322
+
323
+ // -- INCREASE FONT SIZE FOR MOBILE SAFARI
324
+ // This keeps our inputs from zooming the page while focused
325
+ // ------------------------------------------------------------------------
326
+ @supports (-webkit-overflow-scrolling: touch) {
327
+ font-size: 16px;
328
+ padding: 0.4em 0.55em; // Compensate for the larger font size so we generally keep the input the same size
329
+ }
330
+
331
+ // -- STYLE AUTOFILL STATES
332
+ @autofill();
333
+ }
334
+ }
335
+
336
+
337
+ // ============================================================================
338
+ // $ CHECKBOXES & RADIOS
339
+ // ----------------------------------------------------------------------------
340
+ .s-checkbox,
341
+ .s-radio {
342
+ // [1] Check to see if we can use custom styles, if so reset the defaults
343
+ // ------------------------------------------------------------------------
344
+ @supports ((-webkit-appearance: none) or (-moz-appearance: none) or (appearance: none)) {
345
+ .appearance(none);
346
+
347
+ &::-ms-check {
348
+ display: none;
349
+ }
350
+
351
+ // [2] Now re-style the checkboxes and radios
352
+ // ------------------------------------------------------------------------
353
+ margin: 0; // A guard against Core's default margins
354
+ width: 1em;
355
+ height: 1em;
356
+ border: 1px solid var(--bc-darker);
357
+ background-color: var(--white);
358
+ outline: 0;
359
+ font-size: inherit;
360
+ vertical-align: middle;
361
+ cursor: pointer;
362
+ }
363
+
364
+ // Disabled
365
+ &[disabled] {
366
+ opacity: 0.5;
367
+ cursor: not-allowed;
368
+ }
369
+ }
370
+
371
+ // $$ CHECKBOXES
372
+ // ----------------------------------------------------------------------------
373
+ .s-checkbox {
374
+ @supports ((-webkit-appearance: none) or (-moz-appearance: none) or (appearance: none)) {
375
+ border-radius: @br-sm;
376
+ background-position: center center;
377
+ background-repeat: no-repeat;
378
+ background-size: contain;
379
+
380
+ &:checked {
381
+ border-color: var(--theme-secondary-400) !important;
382
+ background-color: var(--theme-secondary-400);
383
+ background-image: url("data:image/svg+xml,%3Csvg width='11' height='11' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10 3.41L8.59 2 4 6.59 2.41 5 1 6.41l3 3z' fill='%23fff'/%3E%3C/svg%3E");
384
+
385
+ .highcontrast-dark-mode({
386
+ border-color: var(--blue-700) !important;
387
+ background-color: var(--blue-300);
388
+ });
389
+
390
+ &:focus {
391
+ border-color: var(--theme-secondary-400);
392
+ }
393
+ }
394
+
395
+ &:focus {
396
+ border-color: var(--theme-secondary-300);
397
+ box-shadow: 0 0 0 @su4 var(--focus-ring);
398
+ }
399
+ }
400
+ }
401
+
402
+ // $$ RADIOS
403
+ // ----------------------------------------------------------------------------
404
+ .s-radio {
405
+ @supports ((-webkit-appearance: none) or (-moz-appearance: none) or (appearance: none)) {
406
+ border-radius: @br-circle;
407
+
408
+ &:checked {
409
+ border-color: var(--theme-secondary-400);
410
+ border-width: 0.30769231em;
411
+ background-color: @white; // This should always be white regardless of dark mode
412
+
413
+ .highcontrast-dark-mode({
414
+ border-color: var(--blue-300);
415
+ outline: 1px solid var(--black);
416
+ });
417
+ }
418
+
419
+ &:focus {
420
+ box-shadow: 0 0 0 @su4 var(--focus-ring);
421
+ }
422
+ }
423
+ }
424
+
425
+ // ============================================================================
426
+ // $ STATES
427
+ // The many states for inputs and select menus.
428
+ // ----------------------------------------------------------------------------
429
+ // Focus
430
+ & {
431
+ @focus-style: {
432
+ border-color: var(--theme-secondary-300);
433
+ box-shadow: 0 0 0 @su4 var(--focus-ring);
434
+ color: var(--black);
435
+ outline: 0;
436
+
437
+ .highcontrast-mode({
438
+ border-color: var(--black);
439
+ })
440
+ }
441
+
442
+ .s-input:focus,
443
+ .s-input.has-focus,
444
+ .s-textarea:focus,
445
+ .s-select > select:focus {
446
+ @focus-style();
447
+ }
448
+
449
+ // This needs to be separate from the one above, because in browsers that don't support :focus-within
450
+ // it's a syntax error, rendering the whole selector null and void.
451
+ .s-input:focus-within {
452
+ @focus-style();
453
+ }
454
+ }
455
+
456
+ .s-input,
457
+ .s-textarea,
458
+ .s-select > select {
459
+ // Disabled, Read-only
460
+ &[disabled],
461
+ &[read-only] {
462
+ cursor: not-allowed;
463
+ opacity: 0.5;
464
+
465
+ .highcontrast-mode({
466
+ opacity: 0.5;
467
+ });
468
+ }
469
+
470
+ // Disabled
471
+ &[disabled] {
472
+ cursor: not-allowed;
473
+ opacity: 0.5;
474
+ }
475
+ }
476
+
477
+ // ============================================================================
478
+ // $ VALIDATION STATES
479
+ // Classes are applied at the wrapping container level.
480
+ // ----------------------------------------------------------------------------
481
+ .is-disabled,
482
+ .has-success,
483
+ .has-error,
484
+ .has-warning {
485
+ position: relative;
486
+
487
+ .s-input {
488
+ padding-right: @su32;
489
+ }
490
+
491
+ .s-select .s-input-icon {
492
+ right: @su32;
493
+ }
494
+
495
+ .s-textarea {
496
+ padding-right: @su48;
497
+
498
+ ~ .s-input-icon {
499
+ top: 1.5em;
500
+ right: 1.5em;
501
+ }
502
+ }
503
+
504
+ .s-input-message a {
505
+ text-decoration: underline;
506
+ }
507
+ }
508
+
509
+ // $$ WARNING
510
+ // ----------------------------------------------------------------------------
511
+ .has-warning {
512
+ .s-input,
513
+ .s-textarea,
514
+ .s-checkbox,
515
+ .s-radio:not(:checked),
516
+ .s-select > select {
517
+ border-color: var(--yellow-600);
518
+
519
+ &:focus {
520
+ box-shadow: 0 0 0 @su4 var(--focus-ring-warning);
521
+ }
522
+ }
523
+
524
+ .s-input-message {
525
+ color: var(--yellow-800);
526
+
527
+ a {
528
+ color: var(--yellow-900);
529
+ }
530
+ }
531
+
532
+ .s-input-icon {
533
+ color: var(--yellow-600);
534
+ }
535
+ }
536
+
537
+ // $$ ERROR
538
+ // ----------------------------------------------------------------------------
539
+ .has-error {
540
+ .s-input,
541
+ .s-textarea,
542
+ .s-checkbox,
543
+ .s-radio:not(:checked),
544
+ .s-select > select {
545
+ border-color: var(--red-400);
546
+
547
+ &:focus {
548
+ box-shadow: 0 0 0 @su4 var(--focus-ring-error);
549
+ }
550
+ }
551
+
552
+ .s-input-message {
553
+ color: var(--red-500);
554
+
555
+ a {
556
+ color: var(--red-800);
557
+
558
+ &:hover {
559
+ color: var(--red-900);
560
+ }
561
+ }
562
+ }
563
+
564
+ .s-input-icon {
565
+ color: var(--red-400);
566
+ }
567
+ }
568
+
569
+ // $$ SUCCESS
570
+ // ----------------------------------------------------------------------------
571
+ .has-success {
572
+ .s-input,
573
+ .s-textarea,
574
+ .s-checkbox,
575
+ .s-radio:not(:checked),
576
+ .s-select > select {
577
+ border-color: var(--green-400);
578
+
579
+ &:focus {
580
+ box-shadow: 0 0 0 @su4 var(--focus-ring-success);
581
+ }
582
+ }
583
+
584
+ .s-input-message {
585
+ color: var(--green-500);
586
+
587
+ a {
588
+ color: var(--green-800);
589
+
590
+ &:hover {
591
+ color: var(--green-900);
592
+ }
593
+ }
594
+ }
595
+
596
+ .s-input-icon {
597
+ color: var(--green-400);
598
+ }
599
+ }
600
+
601
+ // $$ DISABLED
602
+ // ----------------------------------------------------------------------------
603
+ .is-disabled {
604
+ .s-select:before,
605
+ .s-select:after {
606
+ border-color: var(--bc-darker) transparent;
607
+ }
608
+
609
+ .s-label,
610
+ .s-description {
611
+ opacity: 0.5;
612
+
613
+ .s-description {
614
+ opacity: unset;
615
+ }
616
+ }
617
+
618
+ .s-input-icon {
619
+ color: var(--black-200);
620
+
621
+ .highcontrast-mode({
622
+ color: var(--black-400);
623
+ });
624
+ }
625
+
626
+ .s-label {
627
+ cursor: not-allowed;
628
+ }
629
+ }
630
+
631
+ // $$ ICONS
632
+ // ----------------------------------------------------------------------------
633
+ .s-input-icon {
634
+ position: absolute;
635
+ top: 50%;
636
+ right: 0.7em;
637
+ margin-top: -9px; // Half the icon's height at 18px for centering;
638
+ pointer-events: none;
639
+
640
+ &.s-input-icon__search,
641
+ &.s-input-icon__creditcard {
642
+ right: auto;
643
+ left: 0.7em;
644
+ color: var(--black-200);
645
+
646
+ .highcontrast-mode({
647
+ color: var(--black-400);
648
+ });
649
+ }
650
+ }
651
+
652
+ // $$ MESSAGE
653
+ // Set some baseline styles
654
+ // ----------------------------------------------------------------------------
655
+ .s-input-message {
656
+ padding: @su2;
657
+ font-size: @fs-caption;
658
+ }
659
+
660
+ // $$ SIZES
661
+ // ----------------------------------------------------------------------------
662
+ .s-input__sm,
663
+ .s-textarea__sm,
664
+ .s-label__sm,
665
+ .s-select__sm > select {
666
+ font-size: @fs-caption;
667
+ }
668
+ .s-input__md,
669
+ .s-textarea__md,
670
+ .s-label__md,
671
+ .s-select__md > select {
672
+ font-size: @fs-body3;
673
+ }
674
+ .s-input__lg,
675
+ .s-textarea__lg,
676
+ .s-label__lg,
677
+ .s-select__lg > select {
678
+ font-size: @fs-title;
679
+ }
680
+ .s-input__xl,
681
+ .s-textarea__xl,
682
+ .s-label__xl,
683
+ .s-select__xl > select {
684
+ font-size: @fs-headline1;
685
+ }
686
+
687
+ // $$ PADDING ADJUSTMENTS WITHIN SIZES
688
+ // ----------------------------------------------------------------------------
689
+ .s-input__md,
690
+ .s-textarea__md,
691
+ .s-select__md > select {
692
+ padding-top: 0.5em;
693
+ padding-bottom: 0.5em;
694
+ border-radius: @br-sm + 1;
695
+ }
696
+
697
+ .s-textarea__md {
698
+ padding-top: 0.72em;
699
+ padding-bottom: 0.72em;
700
+ }
701
+
702
+ .s-input__lg,
703
+ .s-textarea__lg,
704
+ .s-select__lg > select {
705
+ padding: 0.45em 0.6em;
706
+ border-radius: @br-sm + 1;
707
+ }
708
+
709
+ .s-input__xl,
710
+ .s-textarea__xl,
711
+ .s-select__xl > select {
712
+ padding: 0.4em 0.5em;
713
+ border-radius: @br-md;
714
+ }
715
+
716
+ .s-input__md,
717
+ .s-textarea__md {
718
+ // -- INCREASE FONT SIZE FOR MOBILE SAFARI
719
+ // This keeps our inputs from zooming the page while focused
720
+ // ------------------------------------------------------------------------
721
+ @supports (-webkit-overflow-scrolling: touch) {
722
+ font-size: 17px;
723
+
724
+ // Compensate for the larger font size so we generally keep the input the same size
725
+ padding-top: 0.4em;
726
+ padding-bottom: 0.4em;
727
+ }
728
+ }