@stackoverflow/stacks 1.0.0 → 1.2.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 (74) hide show
  1. package/README.md +47 -47
  2. package/dist/controllers/s-popover.d.ts +11 -2
  3. package/dist/css/stacks.css +257 -8
  4. package/dist/css/stacks.min.css +1 -1
  5. package/dist/js/stacks.js +18 -2
  6. package/dist/js/stacks.min.js +1 -1
  7. package/lib/css/atomic/borders.less +378 -378
  8. package/lib/css/atomic/colors.less +209 -209
  9. package/lib/css/atomic/flex.less +375 -375
  10. package/lib/css/atomic/grid.less +174 -174
  11. package/lib/css/atomic/misc.less +343 -343
  12. package/lib/css/atomic/spacing.less +342 -314
  13. package/lib/css/atomic/typography.less +273 -273
  14. package/lib/css/atomic/width-height.less +194 -194
  15. package/lib/css/base/body.less +44 -44
  16. package/lib/css/base/configuration-static.less +61 -61
  17. package/lib/css/base/icons.less +20 -20
  18. package/lib/css/base/internals.less +220 -220
  19. package/lib/css/base/reset-meyer.less +64 -64
  20. package/lib/css/base/reset-normalize.less +449 -449
  21. package/lib/css/base/reset.less +20 -20
  22. package/lib/css/components/activity-indicator.less +44 -45
  23. package/lib/css/components/avatars.less +189 -189
  24. package/lib/css/components/badges.less +254 -209
  25. package/lib/css/components/banners.less +80 -80
  26. package/lib/css/components/blank-states.less +26 -26
  27. package/lib/css/components/breadcrumbs.less +44 -44
  28. package/lib/css/components/button-groups.less +104 -104
  29. package/lib/css/components/buttons.less +665 -665
  30. package/lib/css/components/cards.less +44 -44
  31. package/lib/css/components/code-blocks.less +130 -130
  32. package/lib/css/components/collapsible.less +104 -104
  33. package/lib/css/components/inputs.less +728 -728
  34. package/lib/css/components/link-previews.less +136 -136
  35. package/lib/css/components/links.less +218 -218
  36. package/lib/css/components/menu.less +47 -47
  37. package/lib/css/components/modals.less +133 -133
  38. package/lib/css/components/navigation.less +146 -146
  39. package/lib/css/components/notices.less +233 -233
  40. package/lib/css/components/page-titles.less +60 -60
  41. package/lib/css/components/pagination.less +55 -55
  42. package/lib/css/components/popovers.less +197 -197
  43. package/lib/css/components/post-summary.less +436 -425
  44. package/lib/css/components/progress-bars.less +330 -330
  45. package/lib/css/components/prose.less +503 -503
  46. package/lib/css/components/spinner.less +107 -107
  47. package/lib/css/components/tables.less +341 -341
  48. package/lib/css/components/tags.less +236 -236
  49. package/lib/css/components/toggle-switches.less +144 -144
  50. package/lib/css/components/topbar.less +427 -427
  51. package/lib/css/components/uploader.less +210 -210
  52. package/lib/css/components/user-cards.less +169 -169
  53. package/lib/css/components/widget-dynamic.less +33 -33
  54. package/lib/css/components/widget-static.less +273 -273
  55. package/lib/css/exports/constants-colors.less +1092 -1092
  56. package/lib/css/exports/constants-helpers.less +108 -108
  57. package/lib/css/exports/constants-type.less +153 -153
  58. package/lib/css/exports/exports.less +15 -15
  59. package/lib/css/exports/mixins.less +237 -237
  60. package/lib/css/stacks-dynamic.less +35 -35
  61. package/lib/css/stacks-static.less +86 -86
  62. package/lib/css/stacks.less +13 -13
  63. package/lib/ts/controllers/index.ts +7 -7
  64. package/lib/ts/controllers/s-expandable-control.ts +188 -188
  65. package/lib/ts/controllers/s-modal.ts +321 -321
  66. package/lib/ts/controllers/s-navigation-tablist.ts +117 -117
  67. package/lib/ts/controllers/s-popover.ts +567 -547
  68. package/lib/ts/controllers/s-table.ts +220 -220
  69. package/lib/ts/controllers/s-tooltip.ts +246 -246
  70. package/lib/ts/controllers/s-uploader.ts +172 -172
  71. package/lib/ts/index.ts +20 -20
  72. package/lib/ts/stacks.ts +88 -88
  73. package/lib/tsconfig.json +13 -13
  74. package/package.json +86 -87
@@ -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 var(--su-static4) 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: var(--br-sm);
55
- background-color: var(--white);
56
- color: var(--fc-dark);
57
- font-size: var(--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: var(--su-static32);
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 var(--su2); // Helps the label visually line up with inputs
153
- color: var(--fc-dark);
154
- font-family: inherit;
155
- font-size: var(--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: var(--su4);
169
- padding: var(--su2) var(--su8);
170
- border-radius: 1000px;
171
- background-color: var(--black-050);
172
- color: var(--fc-medium);
173
- font-size: var(--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 var(--su2); // Helps the label visually line up with inputs
207
- color: var(--fc-medium);
208
- font-size: var(--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: var(--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: var(--br-sm);
242
- border-bottom-left-radius: var(--br-sm);
243
- }
244
-
245
- &.order-last {
246
- border-right-width: 1px;
247
- border-top-right-radius: var(--br-sm);
248
- border-bottom-right-radius: var(--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: var(--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: var(--su32);
301
- border: 1px solid var(--bc-darker);
302
- border-radius: var(--br-sm);
303
- background-color: var(--white);
304
- outline: 0;
305
- font-size: var(--fs-body1);
306
- font-family: inherit;
307
- color: var(--black);
308
- line-height: var(--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: var(--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 var(--su-static4) 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: var(--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 var(--su-static4) 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 var(--su-static4) 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: var(--su32);
489
- }
490
-
491
- .s-select .s-input-icon {
492
- right: var(--su32);
493
- }
494
-
495
- .s-textarea {
496
- padding-right: var(--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 var(--su-static4) 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 var(--su-static4) 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 var(--su-static4) 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: var(--su2);
657
- font-size: var(--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: var(--fs-caption);
667
- }
668
- .s-input__md,
669
- .s-textarea__md,
670
- .s-label__md,
671
- .s-select__md > select {
672
- font-size: var(--fs-body3);
673
- }
674
- .s-input__lg,
675
- .s-textarea__lg,
676
- .s-label__lg,
677
- .s-select__lg > select {
678
- font-size: var(--fs-title);
679
- }
680
- .s-input__xl,
681
- .s-textarea__xl,
682
- .s-label__xl,
683
- .s-select__xl > select {
684
- font-size: var(--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: calc(var(--br-sm) + 1px);
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: calc(var(--br-sm) + 1px);
707
- }
708
-
709
- .s-input__xl,
710
- .s-textarea__xl,
711
- .s-select__xl > select {
712
- padding: 0.4em 0.5em;
713
- border-radius: var(--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 var(--su-static4) 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: var(--br-sm);
55
+ background-color: var(--white);
56
+ color: var(--fc-dark);
57
+ font-size: var(--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: var(--su-static32);
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 var(--su2); // Helps the label visually line up with inputs
153
+ color: var(--fc-dark);
154
+ font-family: inherit;
155
+ font-size: var(--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: var(--su4);
169
+ padding: var(--su2) var(--su8);
170
+ border-radius: 1000px;
171
+ background-color: var(--black-050);
172
+ color: var(--fc-medium);
173
+ font-size: var(--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 var(--su2); // Helps the label visually line up with inputs
207
+ color: var(--fc-medium);
208
+ font-size: var(--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: var(--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: var(--br-sm);
242
+ border-bottom-left-radius: var(--br-sm);
243
+ }
244
+
245
+ &.order-last {
246
+ border-right-width: 1px;
247
+ border-top-right-radius: var(--br-sm);
248
+ border-bottom-right-radius: var(--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: var(--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: var(--su32);
301
+ border: 1px solid var(--bc-darker);
302
+ border-radius: var(--br-sm);
303
+ background-color: var(--white);
304
+ outline: 0;
305
+ font-size: var(--fs-body1);
306
+ font-family: inherit;
307
+ color: var(--black);
308
+ line-height: var(--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: var(--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 var(--su-static4) 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: var(--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 var(--su-static4) 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 var(--su-static4) 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: var(--su32);
489
+ }
490
+
491
+ .s-select .s-input-icon {
492
+ right: var(--su32);
493
+ }
494
+
495
+ .s-textarea {
496
+ padding-right: var(--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 var(--su-static4) 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 var(--su-static4) 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 var(--su-static4) 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: var(--su2);
657
+ font-size: var(--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: var(--fs-caption);
667
+ }
668
+ .s-input__md,
669
+ .s-textarea__md,
670
+ .s-label__md,
671
+ .s-select__md > select {
672
+ font-size: var(--fs-body3);
673
+ }
674
+ .s-input__lg,
675
+ .s-textarea__lg,
676
+ .s-label__lg,
677
+ .s-select__lg > select {
678
+ font-size: var(--fs-title);
679
+ }
680
+ .s-input__xl,
681
+ .s-textarea__xl,
682
+ .s-label__xl,
683
+ .s-select__xl > select {
684
+ font-size: var(--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: calc(var(--br-sm) + 1px);
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: calc(var(--br-sm) + 1px);
707
+ }
708
+
709
+ .s-input__xl,
710
+ .s-textarea__xl,
711
+ .s-select__xl > select {
712
+ padding: 0.4em 0.5em;
713
+ border-radius: var(--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
+ }