/** @TODO: use JS Toolkit to create individual SASS files for *** existing PS components **/ @use "sass:math" as math; /// FormInput ///----------------------------------------------------------------------------- .b-form-input { &[type=password] { letter-spacing: space-x(1); font-weight: 700; } } /// Modal ///----------------------------------------------------------------------------- .b-modal { $self: &; $wrapper-margin: 1.75rem; // from "_modal.scss" &__content { background-color: $modal-content-bg; margin-left: $wrapper-margin; margin-right: $wrapper-margin; } &__header { background-color: $card-cap-bg; &__title { color: $primary; font-size: 21px; } } // @XXX Bootstrap not removing some modal elements on "hide" method // Adding an overlay that the user could click to synchronise the hide // cinematic // @https://stackoverflow.com/questions/50168312/bootstrap-4-close-modal-backdrop-doesnt-disappear &__overlay { width: 100%; height: 100%; position: absolute; } } /// Spinner ///----------------------------------------------------------------------------- .b-spinner { // regarding sizing, Bootstrap set a default `2rem ^ 2rem` // (cf. "_spinners.scss") font-size: inherit; } /// Button ///----------------------------------------------------------------------------- .b-button { $spinner-size: 20px; $self: &; @include clickable(); position: relative; // (!) `translate` CSS modifiers won't work with bootstrap spinner &__spinner { position: absolute; left: calc(50% - #{ math.div($spinner-size, 2) }); top: calc(50% - #{ math.div($spinner-size, 2) }); width: $spinner-size; height: $spinner-size; } &--disabled, &--deferred, &--idled { @include unclickable(); } &--deferred { #{ $self }__inner { visibility: hidden; } } // icon alignement .b-icon::before { line-height: $btn-line-height; } } /// Icon Button ///----------------------------------------------------------------------------- .b-icon-button { $self: &; $overlay-offset-y: -6px; $overlay-offset-x: -10px; transition: color 0.2s; position: relative; transition: color 150ms ease-in-out; &__inner { // (due to overlay via pseudo element) z-index: 1; position: relative; } // overlay preparation &::before { left: $overlay-offset-x; right: $overlay-offset-x; top: $overlay-offset-y; bottom: $overlay-offset-y; border-radius: $overlay-radius; position: absolute; transition: background-color 150ms ease-in-out, box-shadow 150ms ease-in-out; } &--overlay::before { content: ""; } // elevation levels &--level-1:hover::before { background-color: $gray-100; } &--level-2::before { background-color: $gray-100; } &--level-2:hover::before { background-color: darken($gray-100, 10%); } // component status UI changes &--enabled, &--muted, &--idled { @include clickable; &#{ $self }--warning { color: $warning; } &#{ $self }--success { color: $success; } &#{ $self }--danger { color: $danger; } &#{ $self }--info { color: $info; } &#{ $self }--primary { color: $primary; } &#{ $self }--secondary { color: $secondary; } &#{ $self }--dark { color: $body-color; } } &--enabled, &--muted { &#{ $self }--warning:hover { color: darken($warning, 10%); } &#{ $self }--success:hover { color: darken($success, 10%); } &#{ $self }--danger:hover { color: darken($danger, 10%); } &#{ $self }--info:hover { color: darken($info, 10%); } &#{ $self }--primary:hover { color: darken($primary, 10%); } &#{ $self }--secondary:hover { color: darken($secondary, 10%); } &#{ $self }--dark:hover { color: darken($body-color, 10%); } // active effect &#{ $self }:active, &#{ $self }--active { &::before { box-shadow: 0 0 0 0.2rem mix-alpha($gray-200, 50%); } } } &--idled:hover { @include unclickable(); } &--disabled, &--deferred { @include unclickable(); &#{ $self }--warning { color: lighten($warning, 15%); } &#{ $self }--success { color: lighten($success, 15%); } &#{ $self }--danger { color: lighten($danger, 15%); } &#{ $self }--info { color: lighten($info, 15%); } &#{ $self }--primary { color: lighten($primary, 15%); } &#{ $self }--secondary { color: lighten($secondary, 15%); } &#{ $self }--dark { color: lighten($body-color, 15%); } } } /// Fieldset ///----------------------------------------------------------------------------- .b-fieldset { $margin: space-x(2); position: relative; border: $card-border-width solid $card-border-color; border-radius: $card-border-radius; padding-left: $margin; padding-right: $margin; padding-bottom: $margin; padding-top: calc( #{ $margin } + #{ $headings-margin-bottom } ); background-color: inherit; &__legend { position: absolute; top: 0; font-size: $headings-font-family; font-weight: $headings-font-weight; color: $gray-600; line-height: $headings-line-height; margin: #{ - $headings-margin-bottom } 0 0; padding-left: $margin / 2; padding-right: $margin / 2; background-color: inherit; } } /// PhyloExplorer.ConfigForm ///----------------------------------------------------------------------------- .phylo-config-form { &__row { position: relative; display: flex; flex-wrap: wrap; } &__group { margin-bottom: $form-group-margin-bottom; } .b-fieldset { margin-left: $card-spacer-x; margin-right: $card-spacer-x; } &__col { width: 50%; &:first-child { padding-right: space-x(1); } &:last-child { padding-left: space-x(1); } } &__submit { text-align: center; } } /// Tabs ///----------------------------------------------------------------------------- .b-tabs { .nav-item:first-child { margin-left: space-x(2); } .nav-item:last-child { margin-right: space-x(2); } } /// Ripple ///----------------------------------------------------------------------------- .b-ripple { @include fit-positions; position: absolute; overflow: hidden; &:after { @include fit-positions; content: ""; position: absolute; pointer-events: none; background-image: radial-gradient( circle, #000 10%, transparent 10% ); background-repeat: no-repeat; background-position: 50%; opacity: 0; transition: transform 0.6s, opacity 0.6s; transform: scale(10); } &:active:after { transform: scale(0); opacity: 0.2; transition: transform 0s, opacity 0s; } @each $name, $value in $palette-semantic { &--#{ $name }:after { background-image: radial-gradient( circle, #{ $value } 10%, transparent 10% ); } } &--disabled:after, &--deferred:after, &--muted:after { content: none; } } /// Preloader ///----------------------------------------------------------------------------- .b-preloader { width: 100%; height: 100%; &__spinner { $size: 100px; $weight: 6px; position: absolute; font-size: $weight; height: $size; width: $size; // (?) `centered` mixin will not work here, due to Bootstrap process // interfering with the transform rule top: calc( 50% - #{ $size / 2 } ); left: calc( 50% - #{ $size / 2 } ); } } /// Context Menu ///----------------------------------------------------------------------------- .b-context-menu { $minimum-width: 280px; @include fit-positions(); position: fixed; z-index: z-index('main', 'floaty'); background-color: transparent; &__inner { position: fixed; box-shadow: $box-shadow-lg; border: 1px solid $gray-100; word-wrap: break-word; background-color: $body-bg; border-radius: $card-border-radius; min-width: $minimum-width; } } .b-context-menu-item { @include clickable(); position: relative; background-color: $body-bg; padding: $list-group-item-padding-y $list-group-item-padding-x; font-size: 15px; &--disabled, &--deferred, &--idled { @include unclickable(); color: $list-group-disabled-color; } &--enabled:hover, &--muted:hover { background-color: $list-group-hover-bg; } } /// Button Group ///----------------------------------------------------------------------------- .b-button-group { $gutter: 2px; &--no-collapse { .btn:not(:first-child) { margin-left: calc( #{ $gutter } / 2 ); } .btn:not(:last-child) { margin-right: calc( #{ $gutter } / 2 ); } } }