UNPKG

@c8y/style

Version:

Styles for Cumulocity IoT applications

460 lines (390 loc) • 9.5 kB
@import "../../mixins/_clearfix.less"; @import "../../mixins/_opacity.less"; @import "../../mixins/_shadows-helper.less"; /** * Modals - Modal dialog component * * Note: Uses @size-*; @modal-*, and @form-control-* tokens. Already partially migrated. * * Intentionally hardcoded values: * - Component-specific dimensions (50px, 62px, 100px, 200px, 290px, 310px, 319px): Modal and content sizes * - Off-grid spacing (15px, 30px, 50px): Legacy spacing not in token system * - Typography sizes (15px, 16px, 30px, 5em): Font sizes * - Border widths (1px): Standard borders * - Transform percentages (-25%): Animation positioning * - Negative offsets (-1px, -2px): Fine-tuning * - Percentages (100%): Layout * - Animation duration (0.3s): Timing * - Opacity values (0, 0.9): Visual effects * - RGBA values: Transparency * - Z-index values: Stacking order * - Calc expressions: Complex computed values * - Box-shadow values: Shadow specifications */ // .modal-open - body class for killing the scroll // .modal - container to scroll within // .modal-dialog - positioning shell for the actual modal // .modal-content - actual modal w/ bg and corners and shit // Kill the scroll on the body .modal-open { overflow: hidden; } modal-container { background-color: #0008; transition: color 0.3s; } bs-modal-backdrop { opacity: 0 !important; } .modal { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: @zindex-modal - 2; display: none; overflow: hidden; -webkit-overflow-scrolling: touch; outline: 0; &.error-detail { z-index: @zindex-error-detail !important; } // When fading in the modal, animate it to slide down &.fade .modal-dialog { transform: translate(0, -25%); transition: transform 0.3s ease-out; } &.in .modal-dialog, &.show .modal-dialog { transform: translate(0, 0); } } .modal-open .modal { overflow-x: hidden; overflow-y: auto; } // Shell div to position the modal with bottom padding .modal-dialog { position: relative; margin: @size-10; width: auto; } // Actual modal .modal-content { position: relative; outline: 0; border-radius: @modal-border-radius; background-color: var(--c8y-modal-background-default; @component-background-default); background-clip: padding-box; color: var(--c8y-modal-color-default; @component-color-default); .boxShadowHelper(lg); .c8y-dark-theme & { --c8y-component-border-color: var(--c8y-palette-gray-60); } .c8y-system-theme & { @media (prefers-color-scheme: dark) { --c8y-component-border-color: var(--c8y-palette-gray-60); } } // limit the height of the modal to fit the viewport .viewport-modal { display: flex; flex-direction: column; max-height: calc(100vh - 100px); // when we need to display the asset selector in a dropdown menu &.has-asset-selector { max-height: calc(100vh - 290px); } } } // Modal background .modal-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: @zindex-modal-background; background-color: @modal-backdrop-background; &.fade { .opacity(0); } &.in, &.show { opacity: @modal-backdrop-opacity; } } // Modal header .modal-header { padding: @size-24; border-bottom: 0; &.separator { box-shadow: inset 0 -1px 0 @component-border-color; } .input-group-search { margin: @size-5 0 calc(-1 * @size-10); } &.dialog-header { background-color: var(--brand-20, var(--c8y-brand-20)); color: var(--brand-70, var(--c8y-brand-70)); text-align: center; > [class^='dlt-c8y-icon-'], > [class*=' dlt-c8y-icon-'], .c8y-icon { font-size: 62px; } > h4, > .modal-title { margin: @size-base 0 0; text-transform: uppercase; letter-spacing: 0.15em; } ~ * { .modal-inner-scroll, .table-data-grid-scroll { max-height: calc(100vh - 319px); &--fixed { height: calc(100vh - 319px); } } } } &.dialog-header, &.has-data-grid ~ .modal-inner-scroll{ max-height: calc(100vh - 319px); &--fixed { height: calc(100vh - 319px); } } ~ .modal-inner-scroll .table-data-grid-scroll { max-height: calc(100vh - 319px); tr { > td:first-child, th:first-child{ padding-left: @size-24; } > td:last-child, th:last-child{ padding-right: @size-24; } } } } // Close icon .modal-header .close { margin-top: -2px; } // Title text within header .modal-title, .modal-header h1, .modal-header h2, .modal-header h3, .modal-header h4 { margin: 0; line-height: @line-height-small; } .modal-title { margin-top: @size-base; font-size: @font-size-h4 !important; font-weight: @headings-font-weight; } .modal-subtitle { margin-bottom: 0; padding: @size-16 @size-24; background-color: @component-background-default; text-align: center; font-weight: @headings-font-weight; font-size: 16px; &:extend(.separator-bottom); } // Modal body // Where all modal content resides (sibling of .modal-header and .modal-footer) .modal-body { position: relative; padding: @size-24; c8y-modal & { padding: 0; } &.separator { box-shadow: 0 -1px 0 @component-border-color; } } .modal-header:not(.separator) + .modal-body { padding-top: 0; } // Footer (for actions) .modal-footer { padding: @size-24; box-shadow: inset 0 1px 0 @component-border-color; text-align: center; // center align buttons .clearfix(); // clear it in case folks use .pull-* classes on buttons > .btn { min-width: 100px; @media (max-width: @screen-xs-max) { min-width: 80px; } } // Properly space out buttons .btn + .btn { margin-bottom: 0; // account for input[type="submit"] which gets the bottom margin like all other inputs margin-left: var(--c8y-unit-base); } // but override that for button groups .btn-group .btn + .btn { margin-left: -1px; } // and override it for block buttons as well .btn-block + .btn-block { margin-left: 0; } } // Measure scrollbar width for padding body during modal show/hide .modal-scrollbar-measure { position: absolute; top: -9999px; overflow: scroll; width: 50px; height: 50px; } // Scale up the modal @media (min-width: @screen-sm-min) { // Automatically set modal's width for larger viewports .modal-dialog { margin: 30px auto; width: @modal-md; } // Modal sizes .modal-sm { max-width: @modal-sm; } } @media (min-width: @screen-md-min) { .modal-lg { width: calc(@modal-lg - 200px); } } @media (min-width: @screen-lg-min) { .modal-lg { width: @modal-lg; } } // c8y .modal-header { border: 0; &.modal-header-primary { color: var(--brand-primary, var(--c8y-brand-primary)); text-align: center; } &.modal-header-success { color: var(--palette-status-success, var(--c8y-palette-status-success)); text-align: center; } &.modal-header-info { color: var(--palette-status-info, var(--c8y-palette-status-info)); text-align: center; } &.modal-header-warning { color: var(--palette-status-warning, var(--c8y-palette-status-warning)); text-align: center; } &.modal-header-danger { color: var(--palette-status-danger, var(--c8y-palette-status-danger)); text-align: center; } } .c8y-prompt .modal-header { text-align: center; [class^='dlt-c8y-icon-'], [class*=' dlt-c8y-icon-'] { padding-top: 30px; font-size: 5em; } } .c8y-prompt .modal-footer { padding-bottom: calc(@size-base * 5); border: 0; } // Removed unused modal button class - verified 0 usages: .btn-modal-close .modal-status-icon { font-size: 30px; } @media (min-width: 768px) { .modal-dialog { margin: 50px auto; } } .modal-inner-scroll { overflow-x: hidden; overflow-y: auto; flex-grow: 1; margin: 0; max-height: calc(~'100vh - 310px'); &--fixed { height: calc(~'100vh - 310px'); } .modal-body & { margin: 0 calc(@size-base * -1) calc(@size-base * -1); } } .modal-inner-scroll-sm { overflow-x: hidden; overflow-y: auto; margin: 0; max-height: @modal-inner-scroll-sm-height; border-top: 1px solid @component-border-color; &--fixed { height: @modal-inner-scroll-sm-height; } .modal-body & { margin: 0 calc(@size-base * -1) calc(@size-base * -1); } } .modal-list-header { position: relative; &:after { position: absolute; top: 100%; left: 0; z-index: 10; display: block; margin-top: calc(-1 * @size-4); width: 100%; height: @size-4; box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1); content: ''; } .modal-body & { margin-right: calc(@size-24 * -1); margin-left: calc(@size-24 * -1); } + .modal-inner-scroll, + .modal-inner-scroll-sm { position: relative; padding-top: @size-4; &:before { position: absolute; top: 0; right: 0; left: 0; z-index: 10; width: 100%; height: @size-4; background-color: @component-background-default; content: ''; } } } .modal-map { position: relative; .angular-leaflet-map { width: calc(~'100% - 200px') !important; } .panel-map { position: absolute; top: 0; right: 0; bottom: 0; padding: 30px 15px; width: 200px; background-color: rgba(@component-background-default, 0.9); } }