UNPKG

@c8y/style

Version:

Styles for Cumulocity IoT applications

1,173 lines (1,091 loc) • 26.5 kB
// 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: @margin-8; margin-inline-start: 2px; margin-inline-end: 2px; padding-block-start: 0.25rem; padding-inline-end: 0.75em; padding-block-end: 0; padding-inline-start: 0.75em; 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: 4px; padding-inline-end: 4px; min-height: 24px; 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: @margin-24; } } legend, .legend { display: block; margin: @margin-16 0 @margin-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 { align-self: center; flex: 1 1 auto; margin-left: 8px; border-top-width: 1px; border-top-style: solid; content: ''; opacity: 0.5; } &.center { &:before { align-self: center; flex: 1 1 auto; margin-right: 8px; border-top-width: 1px; border-top-style: solid; content: ''; opacity: 0.5; } } &.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: 5px; width: 30px; height: 30px; font-size: 14px; line-height: 32px; } } label { display: inline-block; margin-bottom: @margin-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: 20px; height: 20px; input { position: absolute; top: 0; left: 0; z-index: 10; box-sizing: border-box; width: 20px; height: 20px; 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(); &[multiple], &[size] { height: auto; background-image: none; } } .c8y-select-wrapper { position: relative; select { padding-right: 24px !important; background-image: none; -webkit-appearance: none; -moz-appearance: none; appearance: none; &::-ms-expand { display: none; } } &:after { .c8y-glyph(); position: absolute; top: 50%; right: 5px; 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: 8px; 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: 8px; height: 8px; 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: 4px; display: block; width: 8px; 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: @margin-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: @margin-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) !important; } } .has-error.form-group--tooltip-validation:hover &, .input-group-array .has-error:hover & { position: absolute; bottom: 61px; left: calc(20% - @margin-16); z-index: 10; display: block; padding: 0 5px; max-width: calc(100% - @margin-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; } } } .form-control-feedback-message:has(.help-block) { padding-left: 0 !important; } // 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(@margin-base * 0.25); padding-left: 20px; margin-top: 0; } file-picker ~ .help-block { margin-top: -24px; } .has-success:not(.schema-form-text) { .form-control-validation(@form-control-color-default; @form-control-validation-success; transparent); .form-control-feedback-message { &:before { content: @alert-success-icon; } } } .has-warning { .form-control-validation(@form-control-color-default; @form-control-validation-warning;transparent); .form-control-feedback-message { &:before { content: @alert-warning-icon; } } } .has-error { .form-control-validation(@form-control-color-default; @form-control-validation-error;transparent); .form-control-feedback-message { &:before { content: @alert-danger-icon; } } } .form-control-feedback-message.has-error { margin-bottom: 8px; line-height: 1.2; &:before { color: @form-control-validation-error; content: @alert-danger-icon; } .table-data-grid & { display: none !important; } } .has-info { .form-control-validation(@form-control-color-default; @form-control-validation-info;transparent); .form-control-feedback-message { &:before { content: @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 !important; } // 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 > 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 { &:not(.c8y-radio):not(.c8y-checkbox) { padding: @form-control-padding-small-vertical @form-control-padding-small-horizontal; height: @form-control-height-sm!important; 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 { &:not(.c8y-radio):not(.c8y-checkbox) { padding: @form-control-padding-large-vertical @form-control-padding-large-horizontal; max-height: unset !important; height: @form-control-height-lg!important; 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; } &.hidden-labels { .form-group > label { display: none; } } .form-group { margin: 0; label { margin: 0; color: @form-label-color!important; opacity: 1 !important; } } .form-control, .form-control.input-sm, .form-control.input-lg { padding: 0; background-color: transparent; box-shadow: none; opacity: 1 !important; 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-width: 4ch; max-width: 100%; -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 !important; } } &:has(.ng-pristine):after { position: relative; display: inline-block; margin-top: 0.9rem; color: @component-brand-primary; .dlt-c8y-icon(); content: @dlt-c8y-icon-pencil; } .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 !important; } &: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: -24px; 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!important; &:after { color: @form-control-validation-error!important; } } .has-error &, .has-warning &, .has-info &, .has-success & { &:after { display: none; } .form-control { padding: @form-control-padding-base-vertical @form-control-padding-base-horizontal!important; } } } // 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 !important; vertical-align: middle; > label { margin-right: @margin-8; } + .form-group, + .btn { margin-left: @margin-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. .has-feedback .form-control-feedback { top: 0; } .has-feedback .form-control-feedback-message { top: @form-control-height-base; } } } // Legacy radio and checkboxes .radio, .checkbox { label { display: inline-flex; align-items: center; margin: 0 0 8px 0; padding-left: 0; > input[type='radio'], > input[type='checkbox'] { flex-grow: 0; margin: 0 8px 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: 5px; } } } @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. .has-feedback .form-control-feedback { right: calc(@grid-gutter-width * 0.5 + 5); } .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; } } } } // Slide form action buttons into the viewport on long forms .btn-save-wrapper { animation-duration: 0.5s; &.changed-remove-active { animation-duration: 0; } } .btn-save-wrapper.changed { position: fixed; right: 0; bottom: 0; left: 0; z-index: (@zindex-navbar-fixed - 1); padding: 16px 48px; background-color: @component-background-default; transition: left 0.4s ease-in-out; //horizontal tabs .mcontainerHorizontal & { left: 0; padding: 10px 15px; } .open & { left: @navigatorWidth; } } .open { .has-tabs.page-tabs-vertical + .container-fluid { .btn-save-wrapper.changed { left: calc(@navigatorWidth + @nav-tabs-vertical-width); } } }