@c8y/style
Version:
Styles for Cumulocity IoT applications
1,197 lines (1,112 loc) • 28.3 kB
text/less
@import "../../../variables/_dlt-c8y-icons-vars.less";
@import "../../icons/_c8y-glyphs.less";
@import "../../mixins/_c8y-scrollbar.less";
@import "../../mixins/_forms.less";
@import "../../mixins/_grid.less";
@import "../../mixins/_icon-base.less";
/**
* Forms - Form controls, inputs, labels, and validation
*
* Note: Uses @form-control-*, @form-label-*, @form-legend-*, and @size-* tokens.
*
* Intentionally hardcoded values:
* - rem-based values (1rem, 0.25rem, 1.1428571429em, 1.5em, 0.9rem): Relative sizing for fieldsets
* - Percentages (20%, 50%, 100%): Layout calculations
* - Border widths (1px): Standard borders
* - Fine-tuning offsets (1px, 2px, 3px): Precise positioning adjustments
* - Decimal positions (4.4px, 3.7px, .3px): Sub-pixel positioning for checkmarks
* - Component-specific sizes (30px, 32px, 180px): Fixed component dimensions
* - Typography sizes (12px, 14px, 16px, 18px): Font sizes
* - Checkbox/radio mark dimensions (9px, 5px): Custom control indicators
* - Shadow values (0 0 0 2px, inset 0 0 0): Box-shadow specifications
* - Transition durations (0.15s, 0.25s, 0.35s, 0.4s, 0.5s): Animation timing
* - Opacity values: Visual effects
* - Z-index values: Layering
* - Transform values (rotate, translate, scale): Positioning transforms
* - Line-height unitless values (1, 1.2, 1.5): Relative line heights
* - Calculation expressions: Complex computed values
* - Non-standard spacing (15px): Off-token legacy spacing
*/
// Shared mixin for validation state styling with feedback icon
.validation-state(@validation-color; @icon-content) {
.form-control-validation(@form-control-color-default; @validation-color; transparent);
.form-control-feedback-message {
&:before {
content: @icon-content;
}
}
}
// Shared mixin for form-block border line
.form-block-border-line() {
align-self: center;
flex: 1 1 auto;
border-top-width: 1px;
border-top-style: solid;
content: '';
opacity: 0.5;
}
// Normalize non-controls
fieldset {
margin: 0;
padding: 0;
min-width: 0;
border: 0;
}
fieldset.c8y-fieldset {
display: block;
margin: 1rem 0;
border: solid 1px @form-control-border-color-default;
border-radius: @size-8;
margin-inline-start: 2px;
margin-inline-end: 2px;
padding-block-start: 0.25rem;
padding-inline-end: 1.1428571429em;
padding-block-end: 0;
padding-inline-start: 1.1428571429em;
min-inline-size: 100%;
&--lg {
padding-block-start: 1rem;
padding-inline-end: 1.5em;
padding-block-end: 0;
padding-inline-start: 1.5em;
}
&.expanded {
margin: 1rem -1.15rem;
}
legend {
margin: 0;
width: auto;
text-transform: none;
padding-inline-start: @size-4;
padding-inline-end: @size-4;
min-height: @size-24;
display: flex;
align-items: center;
}
legend[align='left'] {
justify-self: left;
}
legend[align='center'] {
justify-self: center;
}
legend[align='right'] {
justify-self: right;
}
+ .c8y-fieldset {
margin-top: @size-24;
}
}
legend,
.legend {
display: block;
margin: @size-16 0 @size-8 0;
padding: 0;
width: 100%;
border: 0;
color: @form-legend-color;
text-transform: @form-legend-text-transform;
font-weight: @form-legend-font-weight;
font-size: @form-legend-font-size;
line-height: inherit;
&.form-block {
display: flex;
align-items: center;
flex-flow: row nowrap;
&:after {
.form-block-border-line();
margin-left: @size-8;
}
&.center {
&:before {
.form-block-border-line();
margin-right: @size-8;
}
}
&.last-record {
margin-right: auto;
margin-left: auto;
max-width: 180px;
> [class^='dlt-c8y-icon-'],
> [class*=' dlt-c8y-icon-'] {
font-size: 0.5rem;
}
}
}
> .dot {
margin-right: @size-5;
width: 30px;
height: 30px;
font-size: 14px;
line-height: 32px;
&--small {
width: @size-20;
height: @size-20;
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
}
}
}
label {
display: inline-block;
margin-bottom: @size-4;
max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)
color: @form-label-color;
text-transform: @form-label-text-transform;
font-weight: @form-label-font-weight;
font-size: @form-label-font-size;
font-family: @form-control-font-family;
> a {
display: inline-block;
font-size: inherit;
}
&[tooltip],
[tooltip],
[uib-tooltip] {
cursor: pointer;
}
.form-group & {
display: block;
}
fieldset[disabled] & {
&:not(.c8y-checkbox):not(.c8y-radio) {
opacity: @form-control-disabled-opacity;
}
}
&:has(.btn-help) {
display: flex;
align-items: center;
}
}
// Normalize form controls
// While most of our form styles require extra classes, some basic normalization
// is required to ensure optimum display with or without those classes to better address browser inconsistencies.
// Override content-box in Normalize (* isn't specific enough)
input[type='search'] {
.box-sizing(border-box);
}
// Position radios and checkboxes better
input[type='radio'],
input[type='checkbox'] {
margin: 1px 0 0;
margin-top: 1px \9; // IE8-9
font-size: 16px;
line-height: normal;
}
.plain input[type='checkbox'] {
margin: 3px 0 0;
}
input[type='file'] {
display: block;
}
// remove icon in chrome
input[type='date']::-webkit-inner-spin-button,
input[type='date']::-webkit-calendar-picker-indicator {
display: none;
-webkit-appearance: none;
}
// Make multiple select elements height not fixed
select[multiple],
select[size] {
height: auto;
}
// Adjust output element
output {
display: block;
color: @form-control-color-default;
font-size: @font-size-base;
line-height: inherit;
}
// Common form controls
// Shared size and type resets for form controls. Apply `.form-control` to any of the following form controls:
.form-control {
display: block;
padding: @form-control-padding-base-vertical @form-control-padding-base-horizontal;
width: 100%;
height: @form-control-height-base;
border: 0;
border-radius: @form-control-border-radius;
background-color: @form-control-background-default;
background-image: none; // Reset unusual Firefox-on-Android default style,see https://github.com/necolas/normalize.css/issues/214
box-shadow: inset 0 0 0 @form-control-border-width @form-control-border-color-default;
color: @form-control-color-default;
font-weight: @form-control-font-weight;
font-size: @font-size-base;
font-family: @form-control-font-family;
line-height: @form-control-line-height;
transition:
border-color 0.15s ease-in-out,
box-shadow 0.15s ease-in-out;
.form-control-focus();
.placeholder();
&:has(.c8y-colorpicker) {
width: auto;
}
&[disabled],
fieldset[disabled] & {
opacity: @form-control-disabled-opacity;
}
&[readonly],
&[readonly]:focus {
background-color: @form-control-background-default;
color: @text-muted;
opacity: 1;
}
&[disabled],
fieldset[disabled] & {
cursor: @cursor-disabled;
}
textarea & {
height: auto;
}
}
textarea.form-control {
min-height: @form-control-height-base;
height: auto;
resize: vertical;
.c8y-scrollbar();
&.no-resize {
resize: none;
}
}
// color picker
.c8y-colorpicker {
position: relative;
width: @size-20;
height: @size-20;
input {
position: absolute;
top: 0;
left: 0;
z-index: 10;
box-sizing: border-box;
width: @size-20;
height: @size-20;
opacity: 0;
cursor: pointer;
+ span {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 9;
border-radius: 50%;
border: 1px solid @form-control-border-color-default;
}
&:focus + span {
box-shadow: 0 0 0 2px @form-control-border-color-focus;
}
}
&--alarm, &--event{
input + span{
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: var(--component-background-default, var(--c8y-root-component-background-default, #fff));
> i{
transform: translateY(.3px);
}
}
}
}
// Search inputs in iOS
//
// This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.
input[type='search'] {
-webkit-appearance: none;
appearance: none;
}
select,
select.form-control {
// Form control base styles (from .form-control in forms.less)
display: block;
padding: @form-control-padding-base-vertical @form-control-padding-base-horizontal;
width: 100%;
height: @form-control-height-base;
border: 0;
border-radius: @form-control-border-radius;
background-color: @form-control-background-default;
box-shadow: inset 0 0 0 @form-control-border-width @form-control-border-color-default;
color: @form-control-color-default;
font-weight: @form-control-font-weight;
font-size: @font-size-base;
font-family: @form-control-font-family;
line-height: @form-control-line-height;
transition:
border-color 0.15s ease-in-out,
box-shadow 0.15s ease-in-out;
&[multiple],
&[size] {
height: auto;
background-image: none;
}
}
.c8y-select-wrapper {
position: relative;
select {
padding-right: @size-24;
background-image: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
&::-ms-expand {
display: none;
}
}
&:after {
.c8y-glyph();
position: absolute;
top: 50%;
right: @size-5;
z-index: 2;
color: @form-control-icon-color;
content: @c8y-glyph-caret;
font-size: 18px;
transform: translate(0, -50%);
pointer-events: none;
}
}
// Form groups
// Designed to help with the organization and spacing of vertical forms. For
// horizontal forms, wrap form-groups in the predefined grid classes.
.form-group {
display: block;
margin-bottom: @form-validation-bottom-margin;
}
td.form-group,
th.form-group {
margin-bottom: 0;
}
// Checkboxes and radios
label.c8y-checkbox,
label.c8y-radio {
position: relative;
display: flex;
align-items: center;
margin: 0;
color: @form-control-color-default;
text-transform: none;
font-weight: @form-control-font-weight;
font-size: inherit;
line-height: @form-control-height-base;
cursor: pointer;
input[type='checkbox'],
input[type='radio'] {
position: absolute;
top: 0;
left: 0;
z-index: 1;
margin: 0;
opacity: 0;
}
input + span {
position: relative;
z-index: 2;
display: inline-block;
}
input[type='checkbox'] + span,
input[type='radio'] + span {
position: relative;
display: inline-block;
flex-shrink: 0;
width: @checkbox-size;
height: @checkbox-size;
border-radius: @form-control-border-radius;
background-color: @form-control-background-default;
box-shadow: inset 0 0 0 1px @form-control-border-color-default;
transition:
border-color 0.15s ease-in-out,
box-shadow 0.15s ease-in-out;
margin: 2px 0;
+ span {
margin-left: @size-8;
line-height: @form-control-line-height;
}
}
input[type='radio'] + span {
border-radius: 50%;
}
&:hover,
input:focus {
+ span {
background-color: @form-control-background-focus;
box-shadow: inset 0 0 0 2px @form-control-border-color-focus;
color: @form-control-color-focus;
}
}
input[type='checkbox']:checked + span::after {
position: absolute;
top: 4.4px;
left: 3.7px;
display: block;
width: 9px;
height: 5px;
border-bottom: 2px solid;
border-left: 2px solid;
color: @form-control-border-color-focus;
content: '';
transform: rotate(-45deg);
}
input[type='radio']:checked + span::after {
position: absolute;
top: 50%;
left: 50%;
display: inline-block;
width: @size-8;
height: @size-8;
border-radius: 50%;
background-color: @form-control-border-color-focus;
content: '';
font-size: 10px;
line-height: inherit;
transform: translate(-50%, -50%);
pointer-events: none;
}
//checkbox indeterminate
input[type='checkbox']:indeterminate + span::after {
position: absolute;
top: 4.4px;
left: @size-4;
display: block;
width: @size-8;
height: 5px;
border-bottom: 2px solid;
border-left: 0;
color: @form-control-border-color-focus;
content: '';
}
//disabled
input[disabled],
input[disabled]:checked {
cursor: @cursor-disabled;
+ span {
background-color: @form-control-background-disabled;
opacity: @form-control-disabled-opacity;
cursor: @cursor-disabled;
}
~ span {
opacity: @form-control-disabled-opacity;
}
}
input[readonly],
input[readonly]:checked {
pointer-events: none;
~ span {
opacity: @form-control-disabled-opacity;
}
}
&.disabled,
[disabled] & {
cursor: @cursor-disabled;
span {
opacity: @form-control-disabled-opacity;
cursor: @cursor-disabled;
&::before {
opacity: 1;
}
}
}
&.checkbox-inline,
&.radio-inline {
display: inline-flex;
padding: 0;
&:not(:last-child) {
margin-right: @size-16;
}
}
&.has-error {
input + span {
box-shadow: inset 0 0 0 2px @form-control-validation-error;
}
}
}
.form-group {
> label + .c8y-checkbox,
> label + .c8y-radio {
margin-top: @size-8;
}
}
// Form control help & feedback states
// set feedback min height to avoid field jumping
c8y-error-feedback,
c8y-messages,
.c8y-messages {
display: block;
margin-bottom: calc(@form-validation-bottom-margin * -1);
min-height: @form-validation-bottom-margin;
.has-error.form-group--tooltip-validation &,
.input-group-array .has-error & {
display: none;
.form-control-feedback-message:not(.ng-inactive) {
padding-top: 0.25em;
margin-top: 0;
&::before {
color: @tooltip-color-default;
}
}
}
.has-error.form-group--tooltip-validation & {
.form-control-feedback-message:before {
color: var(--c8y-palette-high) ;
}
}
.has-error.form-group--tooltip-validation:hover &,
.input-group-array .has-error:hover & {
position: absolute;
bottom: 61px;
left: calc(20% - @size-16);
z-index: 10;
display: block;
padding: 0 @size-5;
max-width: calc(100% - @size-16);
border-radius: @tooltip-radius;
background-color: @form-control-validation-error;
color: @tooltip-color-default;
&:after {
position: absolute;
bottom: -5px;
left: 50%;
margin-top: 0;
width: 0;
height: 0;
border-width: @tooltip-arrow-width @tooltip-arrow-width 0;
border-style: solid;
border-color: transparent;
border-top-color: @form-control-validation-error;
content: '';
opacity: @tooltip-opacity;
}
}
}
.form-group .help-block,
.form-group .form-control-feedback-message {
position: relative;
display: block;
margin-top: 0;
min-height: @form-validation-bottom-margin;
font-size: @font-size-small;
line-height: 1.5;
&:empty {
display: none;
}
}
.help-block {
font-style: italic;
&.has-info,
.form-control-feedback-message:has(.help-block) & {
display: flex;
&:before {
font: normal normal normal 16px/1 '@{icon-font-family}';
font-size: 16px;
color: @form-control-validation-info;
content: @alert-info-icon;
margin-right: 2px;
}
}
}
body .form-control-feedback-message:has(.help-block) {
padding-left: 0;
}
// icon in feedback message
.form-control-feedback-message,
.input-group + .help-block,
select ~ .help-block,
c8y-field-input ~ .help-block,
textarea ~ .help-block,
input ~ .help-block,
file-picker ~ .help-block,
.form-control ~ .help-block {
&:before {
position: absolute;
top: 2px;
left: 1px;
display: inline-block;
font: normal normal normal 14px/1 '@{icon-font-family}';
font-size: 16px;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
}
// Apply contextual and semantic states to individual form controls.
.form-control-feedback-message:not(.ng-inactive),
.input-group + .help-block,
select ~ .help-block,
textarea ~ .help-block,
file-picker ~ .help-block,
.form-control ~ .help-block,
c8y-field-input ~ .help-block,
input ~ .help-block {
position: relative;
padding-top: calc(@size-base * 0.25);
padding-left: @size-20;
margin-top: 0;
}
file-picker ~ .help-block {
margin-top: calc(-1 * @size-24);
}
.has-success:not(.schema-form-text) {
.validation-state(@form-control-validation-success; @alert-success-icon);
}
.has-warning {
.validation-state(@form-control-validation-warning; @alert-warning-icon);
}
.has-error {
.validation-state(@form-control-validation-error; @alert-danger-icon);
}
.form-control-feedback-message.has-error {
margin-bottom: @size-8;
line-height: 1.2;
&:before {
color: @form-control-validation-error;
content: @alert-danger-icon;
}
.table-data-grid & {
display: none ;
}
&:has(formly-validation-message:empty) {
&::before {
display: none;
}
}
}
.has-info {
.validation-state(@form-control-validation-info; @alert-info-icon);
}
textarea ~ .help-block:not(:empty),
file-picker ~ .help-block:not(:empty),
select ~ .help-block:not(:empty),
input ~ .help-block:not(:empty),
c8y-field-input ~ .help-block:not(:empty),
.form-control ~ .help-block:not(:empty),
.input-group ~ .help-block:not(:empty) {
&:before {
color: @form-control-validation-info;
content: @alert-info-icon;
}
}
// legacy compliant
.form-control.ng-invalid.ng-invalid-required.ng-touched,
.form-control.ng-invalid.ng-touched {
box-shadow:
inset 1px 0 0 0 @form-control-border-color-default,
inset -1px 0 0 0 @form-control-border-color-default,
inset 0 1px 0 0 @form-control-border-color-default,
inset 0 -4px 0 @form-control-validation-error;
&:focus {
box-shadow:
inset 2px 0 0 0 @form-control-border-color-focus,
inset -2px 0 0 0 @form-control-border-color-focus,
inset 0 2px 0 0 @form-control-border-color-focus,
inset 0 -4px 0 @form-control-validation-error;
}
+ * > .form-control-feedback-message:not(:empty) {
&:before {
color: @form-control-validation-error;
content: @alert-danger-icon;
}
}
}
// error message for drop-zone
.drop-zone .has-errors .form-control-feedback-message {
font-size: @font-size-base;
&:not(:empty):before {
color: @form-control-validation-error;
content: @alert-danger-icon;
}
}
// Feedback icon
// hidden - it was deprecated
.form-control-feedback {
display: none ;
}
// Static form control text
//
// Apply class to a `p` element to make any string of text align with labels in
// a horizontal form layout.
.form-control-static {
display: flex;
align-items: center;
margin: 1px 0 0;
min-height: @form-control-height-base;
line-height: @form-control-line-height;
}
// Form control sizing
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
//
.form-group-sm {
.btn{
&:extend(.btn-sm);
}
> label {
margin-bottom: 0;
font-size: @font-size-small;
}
}
.form-group-sm .form-control,
.form-group-sm > .form-group .form-control,
.form-group-sm .form-control-static,
.input-sm , .input-group-sm .form-control {
&:not(.c8y-radio):not(.c8y-checkbox) {
padding: @form-control-padding-small-vertical @form-control-padding-small-horizontal;
height: @form-control-height-sm ;
font-size: @font-size-small;
line-height: @line-height-small;
}
}
.form-group-lg > label {
font-size: @font-size-large;
}
.form-group-lg .form-control,
.form-group-lg .form-control-static,
.input-lg, .input-group-lg .form-control {
&:not(.c8y-radio):not(.c8y-checkbox) {
padding: @form-control-padding-large-vertical @form-control-padding-large-horizontal;
max-height: unset ;
height: @form-control-height-lg ;
font-size: @font-size-large;
}
}
// disable editing in forms
.form-read-only {
position: relative;
// covers all inputs within the form
label {
pointer-events: none;
}
input,
select{
pointer-events: none;
}
// Removed unused modifier: &.hidden-labels
.form-group {
margin: 0;
label {
margin: 0;
color: @form-label-color ;
opacity: 1 ;
}
}
.form-control,
.form-control.input-sm,
.form-control.input-lg {
padding: 0;
background-color: transparent;
box-shadow: none;
opacity: 1 ;
resize: none;
&.ng-empty {
display: none;
}
}
textarea.form-control {
height: auto;
line-height: @form-control-line-height;
}
.btn:not(.form-edit-btn) {
display: none;
}
.form-edit-btn {
display: inline-block;
}
input[type='number'] {
-moz-appearance: textfield;
-webkit-appearance: none;
appearance: none;
}
}
// hide the .form-edit-btn outside a .form-read-only container
.form-edit-btn {
position: relative;
z-index: 1001;
display: none;
margin: 0;
padding: 0;
border: 0;
background: none;
color: @link-color;
font-size: @font-size-small;
cursor: pointer;
&:hover {
color: @link-color-hover;
text-decoration: none;
}
&:focus {
outline: none;
box-shadow: inset 0 -2px 0 @form-control-border-color-focus;
}
}
// Editable inputs
label.editable {
position: relative;
display: flex;
align-items: flex-start;
margin: 0;
padding: 0;
color: @form-control-color-default;
text-transform: none;
font-weight: inherit;
font-size: inherit;
cursor: pointer;
.form-control {
min-inline-size: 6ch;
max-inline-size: 100%;
max-block-size: 100%;
width: auto;
-moz-appearance: textfield;
appearance: textfield;
&::-webkit-inner-spin-button,
&::-webkit-outer-spin-button {
margin: 0;
-webkit-appearance: none;
}
&[c8y-textarea-autoresize] {
transition:
border-color 0.15s ease-in-out,
box-shadow 0.15s ease-in-out,
padding 0.35s ease ;
}
}
&:has(.ng-pristine):after {
.dlt-c8y-icon();
position: relative;
display: inline-block;
margin-top: 0.9rem;
color: @component-brand-primary;
content: @dlt-c8y-icon-pencil;
&:has(.input-sm) {
margin-top: 0.6rem;
}
}
&:has(.input-sm) {
&:has(.ng-pristine):after {
margin-top: 0.6rem;
}
}
.form-control + span {
display: none;
}
&:not(.updated) {
.form-control:not(.ng-dirty) {
position: relative;
z-index: 9;
transition: all 0.35s ease;
&[c8y-textarea-autoresize] {
transition:
border-color 0.15s ease-in-out,
box-shadow 0.15s ease-in-out,
padding 0.35s ease ;
}
&:not(:focus):not(:hover) {
z-index: 2;
overflow: hidden;
padding-right: 0;
padding-left: 0;
background-color: transparent;
box-shadow: none;
text-overflow: ellipsis;
}
}
}
&.updated {
width: 100%;
&:after {
display: none;
}
}
&.updated .form-control,
.form-control:focus,
.form-control.ng-dirty {
margin-right: calc(-1 * @size-24);
min-width: 100%;
opacity: 1;
transition: all 0.25s ease;
~ span {
display: none;
}
}
&:not(.updated):hover {
.form-control {
min-width: 100%;
}
&:after {
opacity: 0;
}
.form-control:not(:focus) {
background-color: transparent;
}
}
.form-control.ng-invalid-required + span,
.form-control.ng-invalid-required + span span {
color: @form-control-validation-error ;
&:after {
color: @form-control-validation-error ;
}
}
.has-error &,
.has-warning &,
.has-info &,
.has-success & {
&:after {
display: none;
}
.form-control {
padding: @form-control-padding-base-vertical @form-control-padding-base-horizontal ;
}
}
}
// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
// forms begin stacked on extra small (mobile) devices and then go inline when
// viewports reach <768px.
//
// Requires wrapping inputs and labels with `.form-group` for proper display of
// default HTML form controls and our custom form controls (e.g., input groups).
//
// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.
.form-inline {
@media (min-width: @screen-sm-min) {
.form-group {
display: inline-block;
margin-bottom: 0;
max-height: 32px ;
vertical-align: middle;
> label {
margin-right: @size-8;
}
+ .form-group, + .btn {
margin-left: @size-8;
}
}
label {
display: inline-block;
margin-bottom: 0;
}
.form-control {
display: inline-block;
width: auto;
vertical-align: middle;
}
.form-control-static {
display: inline-block;
}
.input-group {
display: inline-flex;
width: auto;
vertical-align: middle;
.input-group-addon,
.input-group-btn,
.form-control {
width: auto;
}
}
.control-label {
margin-bottom: 0;
vertical-align: middle;
}
.c8y-select-wrapper {
display: inline-block;
vertical-align: middle;
}
.radio,
.checkbox {
display: inline-block;
margin-top: 0;
margin-bottom: 0;
vertical-align: middle;
label {
padding-left: 0;
}
}
.radio input[type='radio'],
.checkbox input[type='checkbox'] {
position: relative;
margin-left: 0;
} // Re-override the feedback icon.
// Removed unused logic: .has-feedback
}
}
// Legacy radio and checkboxes
.radio,
.checkbox {
label {
display: inline-flex;
align-items: center;
margin: 0 0 @size-8 0;
padding-left: 0;
> input[type='radio'],
> input[type='checkbox'] {
flex-grow: 0;
margin: 0 @size-8 0 0;
height: 18px;
+ span {
flex-grow: 1;
font-weight: normal;
}
}
}
}
// Horizontal forms
// Horizontal forms are built on grid classes and allow you to create forms with labels on the left and inputs on the right.
.form-horizontal {
.radio,
.checkbox,
.radio-inline,
.checkbox-inline {
margin-top: 0;
margin-bottom: 0;
padding-top: calc(@component-padding-base-vertical + 1px);
}
.radio,
.checkbox {
min-height: calc(~'@{line-height-computed} + @{component-padding-base-vertical} + 1');
} // Make form groups behave like rows
.form-group {
.make-row();
.form-group {
position: relative;
margin-right: 0;
margin-left: 0;
.form-control-feedback {
right: @size-5;
}
}
}
@media (min-width: @screen-sm-min) {
.control-label {
margin-bottom: 0;
padding-top: calc(@component-padding-base-vertical + 2px);
}
}
// Validation states
//
// Reposition the icon because it's now within a grid column and columns have
// `position: relative;` on them. Also accounts for the grid gutter padding.
// Removed unused logic: .has-feedback .form-control-feedback
.form-group-lg {
@media (min-width: @screen-sm-min) {
.control-label {
padding-top: calc(~'@{component-padding-large-vertical} * @{line-height-large} + 1');
font-size: @font-size-large;
}
}
}
.form-group-sm {
@media (min-width: @screen-sm-min) {
.control-label {
padding-top: calc(~'@{component-padding-small-vertical} + 1');
font-size: @font-size-small;
}
}
}
}
// Removed unused form button wrapper class - verified 0 usages: .btn-save-wrapper