123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896 |
- /*!
- * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
- * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
- @use 'variables';
- @use 'sass:color';
- @import 'functions';
- /* Specifically override browser styles */
- input, textarea, select, button, div[contenteditable=true], div[contenteditable=false] {
- font-family: var(--font-face);
- }
- .select2-container-multi .select2-choices .select2-search-field input, .select2-search input, .ui-widget {
- font-family: var(--font-face) !important;
- }
- .select2-container.select2-drop-above .select2-choice {
- background-image: unset !important;
- }
- $opacity-disabled: .7;
- /* Simple selector to allow easy overriding */
- select,
- button:not(
- .button-vue,
- /* "vs__" class prefix is used in the vue-select lib */
- [class^="vs__"]
- ),
- input,
- textarea,
- div[contenteditable=true],
- div[contenteditable=false] {
- width: 130px;
- min-height: var(--default-clickable-area);
- box-sizing: border-box;
- }
- /**
- * color-main-text normal state
- * color-main-text active state
- * color-text-maxcontrast disabled state
- */
- button:not(.button-vue),
- input:not([type='range']),
- textarea {
- &:disabled {
- cursor: default;
- color: var(--color-text-maxcontrast);
- border-color: var(--color-border-dark);
- opacity: $opacity-disabled;
- }
- }
- input:not([type="range"]) {
- outline: none;
- }
- /* Default global values */
- div.select2-drop .select2-search input, // TODO: REMOVE WHEN DROPPING SELECT2
- input[type='submit'],
- input[type='button'],
- input[type='reset'],
- button:not(
- .button-vue,
- [class^="vs__"]
- ),
- .button,
- .pager li a {
- padding: 7px 14px;
- font-size: 13px;
- background-color: var(--color-main-background);
- color: var(--color-main-text);
- border: 1px solid var(--color-border-dark);
- font-size: var(--default-font-size);
- outline: none;
- border-radius: var(--border-radius);
- cursor: text;
- &:not(.app-navigation-entry-button) {
- margin: 3px;
- margin-inline-start: 0;
- }
- &:not(
- :disabled,
- .primary
- ) {
- &:not(.app-navigation-entry-button) {
- &:hover,
- &:focus,
- &.active {
- /* active class used for multiselect */
- border-color: var(--color-main-text);
- outline: none;
- }
- &:active {
- outline: none;
- background-color: var(--color-main-background);
- color: var(--color-main-text);
- }
- }
- &:focus-visible {
- box-shadow: 0 0 0 4px var(--color-main-background) !important;
- outline: 2px solid var(--color-main-text) !important;
- }
- }
- &:disabled {
- background-color: var(--color-background-dark);
- color: var(--color-main-text);
- cursor: default;
- opacity: 0.5;
- }
- &:required {
- box-shadow: none;
- }
- &:user-invalid {
- box-shadow: 0 0 0 2px var(--color-error) !important;
- }
- /* Primary action button, use sparingly */
- &.primary {
- background-color: var(--color-primary-element);
- border-color: var(--color-primary-element);
- color: var(--color-primary-element-text);
- cursor: pointer;
- /* Apply border to primary button if on log in page (and not in a dark container) or if in header */
- #body-login :not(.body-login-container) &,
- #header & {
- border-color: var(--color-primary-element-text);
- }
- &:not(:disabled) {
- &:hover,
- &:focus,
- &:active {
- background-color: var(--color-primary-element-hover);
- border-color: var(--color-primary-element-hover);
- }
- &:focus,
- &:focus-visible {
- box-shadow: 0 0 0 2px var(--color-main-text);
- }
- &:active {
- color: var(--color-primary-element-text-dark);
- }
- }
- &:disabled {
- // opacity is already defined to .5 if disabled
- background-color: var(--color-primary-element);
- color: var(--color-primary-element-text-dark);
- cursor: default;
- }
- }
- }
- div[contenteditable=false] {
- margin: 3px;
- margin-inline-start: 0;
- padding: 7px 6px;
- font-size: 13px;
- background-color: var(--color-main-background);
- color: var(--color-text-maxcontrast);
- border: 1px solid var(--color-background-darker);
- outline: none;
- border-radius: var(--border-radius);
- background-color: var(--color-background-dark);
- color: var(--color-text-maxcontrast);
- cursor: default;
- opacity: 0.5;
- }
- /* Specific override */
- input {
- &:not([type='radio']):not([type='checkbox']):not([type='range']):not([type='submit']):not([type='button']):not([type='reset']):not([type='color']):not([type='file']):not([type='image']) {
- -webkit-appearance: textfield;
- -moz-appearance: textfield;
- appearance: textfield;
- // force height for inline elements like inputs (not textarea, contenteditable...)
- height: var(--default-clickable-area);
- }
- &[type='radio'],
- &[type='checkbox'],
- &[type='file'],
- &[type='image'] {
- height: auto;
- width: auto;
- }
- /* Color input doesn't respect the initial height
- so we need to set a custom one */
- &[type='color'] {
- margin: 3px;
- padding: 0 2px;
- min-height: 30px;
- width: 40px;
- cursor: pointer;
- }
- &[type='hidden'] {
- height: 0;
- width: 0;
- }
- &[type='time'] {
- width: initial;
- }
- }
- /* 'Click' inputs */
- select,
- button:not(
- .button-vue,
- [class^="vs__"]
- ),
- .button,
- input[type='button'],
- input[type='submit'],
- input[type='reset'] {
- padding: calc((var(--default-clickable-area) - 1lh) / 2) calc(3 * var(--default-grid-baseline));
- font-size: var(--default-font-size);
- width: auto;
- min-height: var(--default-clickable-area);
- cursor: pointer;
- box-sizing: border-box;
- color: var(--color-primary-element-light-text);
- background-color: var(--color-primary-element-light);
- border: none;
- &:hover,
- &:focus {
- background-color: var(--color-primary-element-light-hover);
- }
- &:disabled {
- cursor: default;
- }
- }
- input:not(
- [type='range'],
- .input-field__input,
- [type='submit'],
- [type='button'],
- [type='reset'],
- .multiselect__input,
- .select2-input,
- .action-input__input,
- [class^="vs__"]
- ),
- select,
- div[contenteditable=true],
- textarea {
- margin: 3px;
- margin-inline-start: 0;
- padding: 0 12px;
- font-size: var(--default-font-size);
- background-color: var(--color-main-background);
- color: var(--color-main-text);
- border: 2px solid var(--color-border-maxcontrast);
- height: 36px;
- outline: none;
- border-radius: var(--border-radius-large);
- text-overflow: ellipsis;
- cursor: pointer;
- &:not(:disabled):hover, &:not(:disabled):focus, &:not(:disabled):active {
- border-color: 2px solid var(--color-main-text);
- box-shadow: 0 0 0 2px var(--color-main-background);
- }
- &:not(:disabled):focus {
- cursor: text;
- }
- }
- .multiselect__input, .select2-input {
- background-color: var(--color-main-background);
- color: var(--color-main-text);
- }
- textarea, div[contenteditable=true] {
- padding: 12px;
- height: auto;
- }
- /* Override the ugly select arrow */
- select {
- background: var(--icon-triangle-s-dark) no-repeat;
- appearance: none;
- background-color: var(--color-main-background);
- padding-inline-end: 28px !important;
- }
- body[dir='ltr'] select {
- background-position: right 8px center;
- }
- body[dir='rtl'] select {
- background-position: left 8px center;
- }
- select,
- button:not(
- .button-vue,
- [class^="vs__"]
- ),
- .button {
- * {
- cursor: pointer;
- }
- &:disabled {
- * {
- cursor: default;
- }
- }
- }
- /* Buttons */
- button:not(
- .button-vue,
- [class^="vs__"]
- ),
- .button,
- input[type='button'],
- input[type='submit'],
- input[type='reset'] {
- font-weight: bold;
- border-radius: var(--border-radius-element);
- /* Get rid of the inside dotted line in Firefox */
- &::-moz-focus-inner {
- border: 0;
- }
- &.error {
- background-color: var(--color-error) !important;
- border-color: var(--color-error) !important;
- color: #fff !important;
- &:hover{
- background-color: var(--color-error-hover) !important;
- border-color: var(--color-main-text) !important;
- }
- }
- }
- button:not(
- .button-vue,
- .action-button,
- [class^="vs__"]
- ),
- .button {
- > span {
- /* icon position inside buttons */
- &[class^='icon-'],
- &[class*=' icon-'] {
- display: inline-block;
- vertical-align: text-bottom;
- opacity: 0.5;
- }
- }
- }
- /* Confirm inputs */
- input {
- &[type='text'],
- &[type='password'],
- &[type='email'] {
- + .icon-confirm {
- margin-inline-start: -13px !important;
- border-inline-start-color: transparent !important;
- border-radius: 0 var(--border-radius-large) var(--border-radius-large) 0 !important;
- border-width: 2px;
- background-clip: padding-box;
- /* Avoid background under border */
- background-color: var(--color-main-background) !important;
- opacity: 1;
- height: var(--default-clickable-area);
- width: var(--default-clickable-area);
- padding: 7px 6px;
- cursor: pointer;
- margin-inline-end: 0;
- &:disabled {
- cursor: default;
- @include icon-color('confirm-fade', 'actions', variables.$color-black, 2, true);
- }
- }
- /* only show confirm borders if input is not focused */
- &:not(:active):not(:hover):not(:focus){
- &:invalid {
- + .icon-confirm {
- border-color: var(--color-error);
- }
- }
- + .icon-confirm {
- &:active,
- &:hover,
- &:focus {
- border-color: var(--color-primary-element) !important;
- border-radius: var(--border-radius) !important;
- &:disabled {
- border-color: var(--color-background-darker) !important;
- }
- }
- }
- }
- &:active,
- &:hover,
- &:focus {
- + .icon-confirm {
- border-color: var(--color-primary-element) !important;
- border-inline-start-color: transparent !important;
- /* above previous input */
- z-index: 2;
- }
- }
- }
- }
- /* Various Fixes */
- button img,
- .button img {
- cursor: pointer;
- }
- select,
- .button.multiselect {
- font-weight: normal;
- }
- /* Radio & Checkboxes */
- $checkbox-radio-size: 14px;
- $color-checkbox-radio-white: #fff;
- input {
- &[type='checkbox'],
- &[type='radio'] {
- &.radio,
- &.checkbox {
- position: absolute;
- inset-inline-start: -10000px;
- top: auto;
- width: 1px;
- height: 1px;
- overflow: hidden;
- + label {
- user-select: none;
- }
- &:disabled + label,
- &:disabled + label:before {
- cursor: default;
- }
- + label:before {
- content: '';
- display: inline-block;
- height: $checkbox-radio-size;
- width: $checkbox-radio-size;
- vertical-align: middle;
- border-radius: 50%;
- margin: 0 3px;
- margin-inline: 3px 6px;
- border: 1px solid var(--color-text-maxcontrast);
- }
- &:not(:disabled):not(:checked) + label:hover:before,
- &:focus + label:before {
- border-color: var(--color-primary-element);
- }
- &:focus-visible + label {
- outline-style: solid;
- outline-color: var(--color-main-text);
- outline-width: 1px;
- outline-offset: 2px;
- }
- &:checked + label:before,
- &.checkbox:indeterminate + label:before {
- /* ^ :indeterminate have a strange behavior on radio,
- so we respecified the checkbox class again to be safe */
- box-shadow: inset 0px 0px 0px 2px var(--color-main-background);
- background-color: var(--color-primary-element);
- border-color: var(--color-primary-element);
- }
- &:disabled + label:before {
- border: 1px solid var(--color-text-maxcontrast);
- background-color: var(--color-text-maxcontrast) !important; /* override other status */
- }
- &:checked:disabled + label:before {
- background-color: var(--color-text-maxcontrast);
- }
- // Detail description below label of checkbox or radio button
- & + label ~ em {
- display: inline-block;
- margin-inline-start: 25px;
- }
- & + label ~ em:last-of-type {
- margin-bottom: $checkbox-radio-size;
- }
- }
- &.checkbox {
- + label:before {
- border-radius: 1px;
- height: $checkbox-radio-size;
- width: $checkbox-radio-size;
- box-shadow: none !important;
- background-position: center;
- }
- &:checked + label:before {
- background-image: url('../img/actions/checkbox-mark.svg');
- }
- &:indeterminate + label:before {
- background-image: url('../img/actions/checkbox-mixed.svg');
- }
- }
- /* We do not use the variables as we keep the colours as white for this variant */
- &.radio--white,
- &.checkbox--white {
- + label:before,
- &:focus + label:before {
- border-color: color.adjust($color-checkbox-radio-white, $lightness: -27%, $space: hsl);
- }
- &:not(:disabled):not(:checked) + label:hover:before {
- border-color: $color-checkbox-radio-white;
- }
- &:checked + label:before {
- box-shadow: inset 0px 0px 0px 2px var(--color-main-background);
- background-color: color.adjust($color-checkbox-radio-white, $lightness: -14%, $space: hsl);
- border-color: color.adjust($color-checkbox-radio-white, $lightness: -14%, $space: hsl);
- }
- &:disabled + label:before {
- background-color: color.adjust($color-checkbox-radio-white, $lightness: -27%, $space: hsl) !important; /* override other status */
- border-color: rgba($color-checkbox-radio-white, 0.4) !important; /* override other status */
- }
- &:checked:disabled + label:before {
- box-shadow: inset 0px 0px 0px 2px var(--color-main-background);
- border-color: rgba($color-checkbox-radio-white, 0.4) !important; /* override other status */
- background-color: color.adjust($color-checkbox-radio-white, $lightness: -27%, $space: hsl);
- }
- }
- &.checkbox--white {
- &:checked + label:before,
- &:indeterminate + label:before {
- background-color: transparent !important; /* Override default checked */
- border-color: $color-checkbox-radio-white !important; /* Override default checked */
- background-image: url('../img/actions/checkbox-mark-white.svg');
- }
- &:indeterminate + label:before {
- background-image: url('../img/actions/checkbox-mixed-white.svg');
- }
- &:disabled + label:before {
- opacity: 0.7; /* No other choice for white background image */
- }
- }
- }
- }
- /* Select2 overriding. Merged to core with vendor stylesheet */
- div.select2-drop {
- margin-top: -2px;
- background-color: var(--color-main-background);
- &.select2-drop-active {
- border-color: var(--color-border-dark);
- }
- .avatar {
- display: inline-block;
- margin-inline-end: 8px;
- vertical-align: middle;
- img {
- cursor: pointer;
- }
- }
- .select2-search input {
- min-height: auto;
- background: var(--icon-search-dark) no-repeat !important;
- background-origin: content-box !important;
- }
- .select2-results {
- max-height: 250px;
- margin: 0;
- padding: 0;
- .select2-result-label {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- span {
- cursor: pointer;
- em {
- cursor: inherit;
- background: unset;
- }
- }
- }
- .select2-result,
- .select2-no-results,
- .select2-searching {
- position: relative;
- display: list-item;
- padding: 12px;
- background-color: transparent;
- cursor: pointer;
- color: var(--color-text-maxcontrast);
- }
- .select2-result {
- &.select2-selected {
- background-color: var(--color-background-dark);
- }
- }
- .select2-highlighted {
- background-color: var(--color-background-dark);
- color: var(--color-main-text);
- }
- }
- }
- body[dir='ltr'] div.select2-drop .select2-search input {
- background-position: right center !important;
- }
- body[dir='rtl'] div.select2-drop .select2-search input {
- background-position: left center !important;
- }
- .select2-chosen,
- #select2-drop {
- .avatar,
- .avatar img {
- cursor: pointer;
- }
- }
- div.select2-container-multi {
- .select2-choices,
- &.select2-container-active .select2-choices {
- box-shadow: none;
- white-space: nowrap;
- text-overflow: ellipsis;
- background: var(--color-main-background);
- color: var(--color-text-maxcontrast) !important;
- box-sizing: content-box;
- border-radius: var(--border-radius-large);
- border: 2px solid var(--color-border-dark);
- margin: 0;
- padding: 6px;
- min-height: 44px;
- &:focus-within {
- border-color: var(--color-primary-element)
- }
- .select2-search-choice {
- line-height: 20px;
- padding-inline-start: 5px;
- &.select2-search-choice-focus,
- &:hover,
- &:active,
- & {
- background-image: none;
- background-color: var(--color-main-background);
- color: var(--color-text-maxcontrast);
- border: 1px solid var(--color-border-dark);
- }
- .select2-search-choice-close {
- display: none;
- }
- }
- .select2-search-field input {
- line-height: 20px;
- min-height: 28px;
- max-height: 28px;
- color: var(--color-main-text);
- &.select2-active {
- background: none !important;
- }
- }
- }
- }
- div.select2-container {
- margin: 3px;
- margin-inline-start: 0;
- &.select2-container-multi .select2-choices {
- display: flex;
- flex-wrap: wrap;
- li {
- float: none;
- }
- }
- a.select2-choice {
- box-shadow: none;
- white-space: nowrap;
- text-overflow: ellipsis;
- background: var(--color-main-background);
- color: var(--color-text-maxcontrast) !important;
- box-sizing: content-box;
- border-radius: var(--border-radius-large);
- border: 2px solid var(--color-border-dark);
- margin: 0;
- padding: 6px 12px;
- min-height: 44px;
- &:focus-within {
- border-color: var(--color-primary-element)
- }
- .select2-search-choice {
- line-height: 20px;
- padding-inline-start: 5px;
- background-image: none;
- background-color: var(--color-background-dark);
- border-color: var(--color-background-dark);
- .select2-search-choice-close {
- display: none;
- }
- &.select2-search-choice-focus,
- &:hover {
- background-color: var(--color-border);
- border-color: var(--color-border);
- }
- }
- .select2-arrow {
- background: none;
- border-radius: 0;
- border: none;
- b {
- background: var(--icon-triangle-s-dark) no-repeat center !important;
- opacity: .5;
- }
- }
- &:hover .select2-arrow b,
- &:focus .select2-arrow b,
- &:active .select2-arrow b {
- opacity: .7;
- }
- .select2-search-field input {
- line-height: 20px;
- }
- }
- }
- /* Vue v-select */
- .v-select {
- margin: 3px;
- margin-inline-start: 0;
- display: inline-block;
- .dropdown-toggle {
- display: flex !important;
- flex-wrap: wrap;
- .selected-tag {
- line-height: 20px;
- padding-inline-start: 5px;
- background-image: none;
- background-color: var(--color-main-background);
- color: var(--color-text-maxcontrast);
- border: 1px solid var(--color-border-dark);
- display: inline-flex;
- align-items: center;
- .close {
- margin-inline-start: 3px;
- }
- }
- }
- .dropdown-menu {
- padding: 0;
- li {
- padding: 5px;
- position: relative;
- display: list-item;
- background-color: transparent;
- cursor: pointer;
- color: var(--color-text-maxcontrast);
- a {
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- height: 25px;
- padding-block: 3px 4px;
- padding-inline: 2px 7px;
- margin: 0;
- cursor: pointer;
- min-height: 1em;
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- display: inline-flex;
- align-items: center;
- background-color: transparent !important;
- color: inherit !important;
- &::before {
- content: ' ';
- background-image: var(--icon-checkmark-dark);
- background-repeat: no-repeat;
- background-position: center;
- min-width: 16px;
- min-height: 16px;
- display: block;
- opacity: 0.5;
- margin-inline-end: 5px;
- visibility: hidden;
- }
- }
- &.highlight {
- color: var(--color-main-text);
- }
- &.active > a {
- background-color: var(--color-background-dark);
- color: var(--color-main-text);
- &::before {
- visibility: visible;
- }
- }
- }
- }
- }
- /* Progressbar */
- progress:not(.vue) {
- display: block;
- width: 100%;
- padding: 0;
- border: 0 none;
- background-color: var(--color-background-dark);
- border-radius: var(--border-radius);
- flex-basis: 100%;
- height: 5px;
- overflow: hidden;
- &.warn {
- &::-moz-progress-bar {
- background: var(--color-error);
- }
- &::-webkit-progress-value {
- background: var(--color-error);
- }
- }
- &::-webkit-progress-bar {
- background: transparent;
- }
- &::-moz-progress-bar {
- border-radius: var(--border-radius);
- background: var(--color-primary-element);
- transition: 250ms all ease-in-out;
- }
- &::-webkit-progress-value {
- border-radius: var(--border-radius);
- background: var(--color-primary-element);
- transition: 250ms all ease-in-out;
- }
- }
- /* Animation */
- @keyframes shake {
- 10%,
- 90% {
- transform: translate(-1px);
- }
- 20%,
- 80% {
- transform: translate(2px);
- }
- 30%,
- 50%,
- 70% {
- transform: translate(-4px);
- }
- 40%,
- 60% {
- transform: translate(4px);
- }
- }
- .shake {
- animation-name: shake;
- animation-duration: .7s;
- animation-timing-function: ease-out;
- }
- // Keep the labels for screen readers but hide them since we use placeholders
- // Same as .hidden-visually
- label.infield {
- position: absolute;
- inset-inline-start: -10000px;
- top: -10000px;
- width: 1px;
- height: 1px;
- overflow: hidden;
- }
- // when rules are grouped using the comma operator and one selector is invalid / unknown then the whole group is invalidated.
- // https://www.w3.org/TR/selectors-3/#grouping
- // In this case `::-ms-input-placeholder` is unknown to Firefox and Chrome
- @mixin placeholder-style {
- color: var(--color-text-maxcontrast);
- font-size: var(--default-font-size);
- }
- ::placeholder {
- @include placeholder-style;
- }
- ::-ms-input-placeholder {
- @include placeholder-style;
- }
- ::-webkit-input-placeholder {
- @include placeholder-style;
- }
|