UNPKG

15.7 kBtext/lessView Raw
1@import (reference) 'antd/dist/antd.less';
2@import './mixin';
3
4@form-prefix-cls: ~'@{ant-prefix}-legacy-form';
5@form-component-height: @input-height-base;
6@form-component-max-height: @input-height-lg;
7@form-feedback-icon-size: @font-size-base;
8@form-help-margin-top: (@form-component-height - @form-component-max-height) / 2 +
9 2px;
10@form-explain-font-size: @font-size-base;
11// Extends additional 1px to fix precision issue.
12// https://github.com/ant-design/ant-design/issues/12803
13// https://github.com/ant-design/ant-design/issues/8220
14@form-explain-precision: 1px;
15@form-explain-height: floor(@form-explain-font-size * @line-height-base);
16@input-affix-width: 19px;
17@outline-fade: 20%;
18
19.@{form-prefix-cls} {
20 .reset-component;
21 .reset-form;
22}
23
24.@{form-prefix-cls}-item-required::before {
25 display: inline-block;
26 margin-right: 4px;
27 color: @label-required-color;
28 font-size: @font-size-base;
29 font-family: SimSun, sans-serif;
30 line-height: 1;
31 content: '*';
32 .@{form-prefix-cls}-hide-required-mark & {
33 display: none;
34 }
35}
36
37.@{form-prefix-cls}-item-label > label {
38 color: @label-color;
39
40 &::after {
41 & when (@form-item-trailing-colon=true) {
42 content: ':';
43 }
44 & when not (@form-item-trailing-colon=true) {
45 content: ' ';
46 }
47
48 position: relative;
49 top: -0.5px;
50 margin: 0 @form-item-label-colon-margin-right 0
51 @form-item-label-colon-margin-left;
52 }
53
54 &.@{form-prefix-cls}-item-no-colon::after {
55 content: ' ';
56 }
57}
58
59// Form items
60// You should wrap labels and controls in .@{form-prefix-cls}-item for optimum spacing
61.@{form-prefix-cls}-item {
62 label {
63 position: relative;
64
65 > .@{iconfont-css-prefix} {
66 font-size: @font-size-base;
67 vertical-align: top;
68 }
69 }
70
71 .reset-component;
72
73 margin-bottom: @form-item-margin-bottom;
74 vertical-align: top;
75
76 &-control {
77 position: relative;
78 line-height: @form-component-max-height;
79 .clearfix;
80 }
81
82 &-children {
83 position: relative;
84 }
85
86 &-with-help {
87 margin-bottom: max(
88 0,
89 @form-item-margin-bottom - @form-explain-height - @form-help-margin-top
90 );
91 }
92
93 &-label {
94 display: inline-block;
95 overflow: hidden;
96 line-height: @form-component-max-height - 0.0001px;
97 white-space: nowrap;
98 text-align: right;
99 vertical-align: middle;
100 flex-grow: 0;
101
102 &-left {
103 text-align: left;
104 }
105 }
106
107 &-control-wrapper {
108 flex: 1 1 0;
109 }
110
111 .@{ant-prefix}-switch {
112 margin: 2px 0 4px;
113 }
114}
115
116.@{form-prefix-cls}-explain,
117.@{form-prefix-cls}-extra {
118 clear: both;
119 min-height: @form-explain-height + @form-explain-precision;
120 margin-top: @form-help-margin-top;
121 color: @text-color-secondary;
122 font-size: @form-explain-font-size;
123 line-height: @line-height-base;
124 transition: color 0.3s @ease-out; // sync input color transition
125}
126
127.@{form-prefix-cls}-explain {
128 margin-bottom: -@form-explain-precision;
129}
130
131.@{form-prefix-cls}-extra {
132 padding-top: 4px;
133}
134
135.@{form-prefix-cls}-text {
136 display: inline-block;
137 padding-right: 8px;
138}
139
140.@{form-prefix-cls}-split {
141 display: block;
142 text-align: center;
143}
144
145form {
146 .has-feedback {
147 .@{ant-prefix}-input {
148 padding-right: @input-padding-horizontal-base + @input-affix-width;
149 }
150
151 // https://github.com/ant-design/ant-design/issues/19884
152 .@{ant-prefix}-input-affix-wrapper {
153 .@{ant-prefix}-input-suffix {
154 padding-right: 18px;
155 }
156 .@{ant-prefix}-input {
157 padding-right: @input-padding-horizontal-base + @input-affix-width * 2;
158 }
159 &.@{ant-prefix}-input-affix-wrapper-input-with-clear-btn {
160 .@{ant-prefix}-input {
161 padding-right: @input-padding-horizontal-base + @input-affix-width * 3;
162 }
163 }
164 }
165
166 // Fix overlapping between feedback icon and <Select>'s arrow.
167 // https://github.com/ant-design/ant-design/issues/4431
168 > .@{ant-prefix}-select .@{ant-prefix}-select-arrow,
169 > .@{ant-prefix}-select .@{ant-prefix}-select-selection__clear,
170 :not(.@{ant-prefix}-input-group-addon)
171 > .@{ant-prefix}-select
172 .@{ant-prefix}-select-arrow,
173 :not(.@{ant-prefix}-input-group-addon)
174 > .@{ant-prefix}-select
175 .@{ant-prefix}-select-selection__clear {
176 right: (@form-component-height / 2) + @form-feedback-icon-size - 2px;
177 }
178 > .@{ant-prefix}-select .@{ant-prefix}-select-selection-selected-value,
179 :not(.@{ant-prefix}-input-group-addon)
180 > .@{ant-prefix}-select
181 .@{ant-prefix}-select-selection-selected-value {
182 padding-right: 42px;
183 }
184
185 .@{ant-prefix}-cascader-picker {
186 &-arrow {
187 margin-right: (@form-component-height / 2) + @form-feedback-icon-size -
188 13px;
189 }
190 &-clear {
191 right: (@form-component-height / 2) + @form-feedback-icon-size - 2px;
192 }
193 }
194
195 // Fix issue: https://github.com/ant-design/ant-design/issues/7854
196 .@{ant-prefix}-input-search:not(.@{ant-prefix}-input-search-enter-button) {
197 .@{ant-prefix}-input-suffix {
198 right: (@form-component-height / 2) + @form-feedback-icon-size - 2px;
199 }
200 }
201
202 // Fix issue: https://github.com/ant-design/ant-design/issues/4783
203 .@{ant-prefix}-calendar-picker,
204 .@{ant-prefix}-time-picker {
205 &-icon,
206 &-clear {
207 right: (@form-component-height / 2) + @form-feedback-icon-size - 2px;
208 }
209 }
210
211 .@{ant-prefix}-picker {
212 .@{ant-prefix}-picker-suffix {
213 padding-right: @input-affix-width - 2px;
214 }
215 }
216 }
217
218 .@{ant-prefix}-mentions,
219 textarea.@{ant-prefix}-input {
220 height: auto;
221 margin-bottom: 4px;
222 }
223
224 // input[type=file]
225 .@{ant-prefix}-upload {
226 background: transparent;
227 }
228
229 input[type='radio'],
230 input[type='checkbox'] {
231 width: 14px;
232 height: 14px;
233 }
234
235 // Radios and checkboxes on same line
236 .@{ant-prefix}-radio-inline,
237 .@{ant-prefix}-checkbox-inline {
238 display: inline-block;
239 margin-left: 8px;
240 font-weight: normal;
241 vertical-align: middle;
242 cursor: pointer;
243
244 &:first-child {
245 margin-left: 0;
246 }
247 }
248
249 .@{ant-prefix}-checkbox-vertical,
250 .@{ant-prefix}-radio-vertical {
251 display: block;
252 }
253
254 .@{ant-prefix}-checkbox-vertical + .@{ant-prefix}-checkbox-vertical,
255 .@{ant-prefix}-radio-vertical + .@{ant-prefix}-radio-vertical {
256 margin-left: 0;
257 }
258
259 .@{ant-prefix}-input-number {
260 + .@{form-prefix-cls}-text {
261 margin-left: 8px;
262 }
263 &-handler-wrap {
264 z-index: 2; // https://github.com/ant-design/ant-design/issues/6289
265 }
266 }
267
268 .@{ant-prefix}-select,
269 .@{ant-prefix}-cascader-picker {
270 width: 100%;
271 }
272
273 // Don't impact select inside input group
274 .@{ant-prefix}-input-group .@{ant-prefix}-select,
275 .@{ant-prefix}-input-group .@{ant-prefix}-cascader-picker {
276 width: auto;
277 }
278
279 // fix input with addon position. https://github.com/ant-design/ant-design/issues/8243
280 :not(.@{ant-prefix}-input-group-wrapper) > .@{ant-prefix}-input-group,
281 .@{ant-prefix}-input-group-wrapper {
282 position: relative;
283 top: -1px;
284 display: inline-block;
285 vertical-align: middle;
286 }
287}
288
289// Form layout
290//== Vertical Form
291.make-vertical-layout-label() {
292 display: block;
293 margin: @form-vertical-label-margin;
294 padding: @form-vertical-label-padding;
295 line-height: @line-height-base;
296 white-space: initial;
297 text-align: left;
298 flex-basis: 100%;
299
300 label::after {
301 display: none;
302 }
303}
304.make-vertical-layout-control-wrapper() {
305 flex-basis: 100%;
306}
307
308.make-vertical-layout() {
309 .@{form-prefix-cls}-item-label,
310 .@{form-prefix-cls}-item-control-wrapper {
311 display: block;
312 width: 100%;
313 }
314 .@{form-prefix-cls}-item-label {
315 .make-vertical-layout-label();
316 }
317 .@{form-prefix-cls}-item-control-wrapper {
318 .make-vertical-layout-control-wrapper();
319 }
320}
321
322.@{form-prefix-cls}-vertical .@{form-prefix-cls}-item-label,
323 // when labelCol is 24, it is a vertical form
324.@{ant-prefix}-col-24.@{form-prefix-cls}-item-label,
325.@{ant-prefix}-col-xl-24.@{form-prefix-cls}-item-label {
326 .make-vertical-layout-label();
327}
328
329.@{form-prefix-cls}-vertical {
330 .@{form-prefix-cls}-item {
331 padding-bottom: 8px;
332 }
333 .@{form-prefix-cls}-item-control {
334 line-height: @line-height-base;
335 }
336 .@{form-prefix-cls}-explain {
337 margin-top: 2px;
338 margin-bottom: -4px - @form-explain-precision;
339 }
340 .@{form-prefix-cls}-extra {
341 margin-top: 2px;
342 margin-bottom: -4px;
343 }
344}
345
346@media (max-width: @screen-xs-max) {
347 .make-vertical-layout();
348 .@{ant-prefix}-col-xs-24.@{form-prefix-cls}-item-label {
349 .make-vertical-layout-label();
350 }
351}
352
353@media (max-width: @screen-sm-max) {
354 .@{ant-prefix}-col-sm-24.@{form-prefix-cls}-item-label {
355 .make-vertical-layout-label();
356 }
357}
358
359@media (max-width: @screen-md-max) {
360 .@{ant-prefix}-col-md-24.@{form-prefix-cls}-item-label {
361 .make-vertical-layout-label();
362 }
363}
364
365@media (max-width: @screen-lg-max) {
366 .@{ant-prefix}-col-lg-24.@{form-prefix-cls}-item-label {
367 .make-vertical-layout-label();
368 }
369}
370
371@media (max-width: @screen-xl-max) {
372 .@{ant-prefix}-col-xl-24.@{form-prefix-cls}-item-label {
373 .make-vertical-layout-label();
374 }
375}
376
377//== Inline Form
378.@{form-prefix-cls}-inline {
379 .@{form-prefix-cls}-item {
380 display: inline-block;
381 margin-right: 16px;
382 margin-bottom: 0;
383
384 &-with-help {
385 margin-bottom: @form-item-margin-bottom;
386 }
387
388 > .@{form-prefix-cls}-item-control-wrapper,
389 > .@{form-prefix-cls}-item-label {
390 display: inline-block;
391 vertical-align: top;
392 }
393 }
394
395 .@{form-prefix-cls}-text {
396 display: inline-block;
397 }
398
399 .has-feedback {
400 display: inline-block;
401 }
402}
403
404// Validation state
405.has-success,
406.has-warning,
407.has-error,
408.is-validating {
409 &.has-feedback .@{form-prefix-cls}-item-children-icon {
410 position: absolute;
411 top: 50%;
412 right: 0;
413 z-index: 1;
414 width: @form-component-height;
415 height: 20px;
416 margin-top: -10px;
417 font-size: @form-feedback-icon-size;
418 line-height: 20px;
419 text-align: center;
420 visibility: visible;
421 animation: zoomIn 0.3s @ease-out-back;
422 pointer-events: none;
423
424 & svg {
425 position: absolute;
426 top: 0;
427 right: 0;
428 bottom: 0;
429 left: 0;
430 margin: auto;
431 }
432 }
433}
434
435.has-success {
436 &.has-feedback .@{form-prefix-cls}-item-children-icon {
437 color: @success-color;
438 animation-name: diffZoomIn1 !important;
439 }
440}
441
442.has-warning {
443 .form-control-validation(
444 @warning-color; @warning-color; @form-warning-input-bg;
445 );
446
447 &.has-feedback .@{form-prefix-cls}-item-children-icon {
448 color: @warning-color;
449 animation-name: diffZoomIn3 !important;
450 }
451
452 //select
453 .@{ant-prefix}-select {
454 &-selection {
455 border-color: @warning-color;
456 &:hover {
457 border-color: @warning-color;
458 }
459 }
460 &-open .@{ant-prefix}-select-selection,
461 &-focused .@{ant-prefix}-select-selection {
462 .active(@warning-color);
463 }
464 }
465
466 // arrow and icon
467 .@{ant-prefix}-calendar-picker-icon::after,
468 .@{ant-prefix}-time-picker-icon::after,
469 .@{ant-prefix}-picker-icon::after,
470 .@{ant-prefix}-select-arrow,
471 .@{ant-prefix}-cascader-picker-arrow {
472 color: @warning-color;
473 }
474
475 //input-number, timepicker
476 .@{ant-prefix}-input-number,
477 .@{ant-prefix}-time-picker-input {
478 border-color: @warning-color;
479 &-focused,
480 &:focus {
481 .active(@warning-color);
482 }
483 &:not([disabled]):hover {
484 border-color: @warning-color;
485 }
486 }
487
488 .@{ant-prefix}-cascader-picker {
489 &:focus .@{ant-prefix}-cascader-input {
490 .active(@warning-color);
491 }
492 &:hover .@{ant-prefix}-cascader-input {
493 border-color: @warning-color;
494 }
495 }
496
497 // input
498 .@{ant-prefix}-input-affix-wrapper {
499 border-color: @warning-color;
500 &-focused {
501 box-shadow: @input-outline-offset @outline-blur-size @outline-width
502 fade(@warning-color, @outline-fade);
503 }
504 .@{ant-prefix}-input {
505 &:focus {
506 box-shadow: none;
507 }
508 }
509 }
510}
511
512.has-error {
513 .form-control-validation(@error-color; @error-color; @form-error-input-bg;);
514
515 &.has-feedback .@{form-prefix-cls}-item-children-icon {
516 color: @error-color;
517 animation-name: diffZoomIn2 !important;
518 }
519
520 //select
521 .@{ant-prefix}-select {
522 &-selection {
523 border-color: @error-color;
524 &:hover {
525 border-color: @error-color;
526 }
527 }
528 &-open .@{ant-prefix}-select-selection,
529 &-focused .@{ant-prefix}-select-selection {
530 .active(@error-color);
531 }
532 }
533
534 .@{ant-prefix}-select.@{ant-prefix}-select-auto-complete {
535 .@{ant-prefix}-input:focus {
536 border-color: @error-color;
537 }
538 }
539
540 .@{ant-prefix}-input-group-addon .@{ant-prefix}-select {
541 &-selection {
542 border-color: transparent;
543 box-shadow: none;
544 }
545 }
546
547 // arrow and icon
548 .@{ant-prefix}-calendar-picker-icon::after,
549 .@{ant-prefix}-time-picker-icon::after,
550 .@{ant-prefix}-picker-icon::after,
551 .@{ant-prefix}-select-arrow,
552 .@{ant-prefix}-cascader-picker-arrow {
553 color: @error-color;
554 }
555
556 //input-number, timepicker
557 .@{ant-prefix}-input-number,
558 .@{ant-prefix}-time-picker-input {
559 border-color: @error-color;
560 &-focused,
561 &:focus {
562 .active(@error-color);
563 }
564 &:not([disabled]):hover {
565 border-color: @error-color;
566 }
567 }
568 .@{ant-prefix}-mention-wrapper {
569 .@{ant-prefix}-mention-editor {
570 &,
571 &:not([disabled]):hover {
572 border-color: @error-color;
573 }
574 }
575 &.@{ant-prefix}-mention-active:not([disabled])
576 .@{ant-prefix}-mention-editor,
577 .@{ant-prefix}-mention-editor:not([disabled]):focus {
578 .active(@error-color);
579 }
580 }
581
582 .@{ant-prefix}-cascader-picker {
583 &:focus .@{ant-prefix}-cascader-input {
584 .active(@error-color);
585 }
586 &:hover .@{ant-prefix}-cascader-input {
587 border-color: @error-color;
588 }
589 }
590
591 // transfer
592 .@{ant-prefix}-transfer {
593 &-list {
594 border-color: @error-color;
595
596 &-search:not([disabled]) {
597 border-color: @input-border-color;
598
599 &:hover {
600 .hover();
601 }
602
603 &:focus {
604 .active();
605 }
606 }
607 }
608 }
609
610 // input
611 .@{ant-prefix}-input-affix-wrapper {
612 border-color: @error-color;
613 &-focused {
614 box-shadow: @input-outline-offset @outline-blur-size @outline-width
615 fade(@error-color, @outline-fade);
616 }
617 .@{ant-prefix}-input {
618 &:focus {
619 box-shadow: none;
620 }
621 }
622 }
623}
624
625.is-validating {
626 &.has-feedback .@{form-prefix-cls}-item-children-icon {
627 display: inline-block;
628 color: @primary-color;
629 }
630}
631
632.@{ant-prefix}-advanced-search-form {
633 .@{form-prefix-cls}-item {
634 margin-bottom: @form-item-margin-bottom;
635
636 &-with-help {
637 margin-bottom: @form-item-margin-bottom - @form-explain-height -
638 @form-help-margin-top;
639 }
640 }
641}
642
643.show-help-motion(@className, @keyframeName, @duration: @animation-duration-slow) {
644 .make-motion(@className, @keyframeName, @duration);
645 .@{className}-enter,
646 .@{className}-appear {
647 opacity: 0;
648 animation-timing-function: @ease-in-out;
649 }
650 .@{className}-leave {
651 animation-timing-function: @ease-in-out;
652 }
653}
654
655.show-help-motion(show-help, antShowHelp, 0.3s);
656
657@keyframes antShowHelpIn {
658 0% {
659 transform: translateY(-5px);
660 opacity: 0;
661 }
662 100% {
663 transform: translateY(0);
664 opacity: 1;
665 }
666}
667
668@keyframes antShowHelpOut {
669 to {
670 transform: translateY(-5px);
671 opacity: 0;
672 }
673}
674
675// need there different zoom animation
676// otherwise won't trigger anim
677@keyframes diffZoomIn1 {
678 0% {
679 transform: scale(0);
680 }
681 100% {
682 transform: scale(1);
683 }
684}
685
686@keyframes diffZoomIn2 {
687 0% {
688 transform: scale(0);
689 }
690 100% {
691 transform: scale(1);
692 }
693}
694
695@keyframes diffZoomIn3 {
696 0% {
697 transform: scale(0);
698 }
699 100% {
700 transform: scale(1);
701 }
702}