X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fsass%2Finclude%2F_mixins.scss;h=317781e0e9755ad077db1f27d205a1f1a6e3cd1a;hb=fa12eacc014aae8094d108634371640f2695bf9f;hp=fdf5e3f67995bc62c8b39700727415b99dec7cac;hpb=15ca2e871aa069e596baf9da22b3d2a1ab1a0b1a;p=github%2FChocobozzz%2FPeerTube.git diff --git a/client/src/sass/include/_mixins.scss b/client/src/sass/include/_mixins.scss index fdf5e3f67..bf7504d91 100644 --- a/client/src/sass/include/_mixins.scss +++ b/client/src/sass/include/_mixins.scss @@ -1,80 +1,331 @@ -@import '_variables'; +@use '_variables'; @mixin disable-default-a-behaviour { - &:hover, &:focus, &:active { + &:hover, + &:focus, + &:active { text-decoration: none !important; outline: none !important; } } +@mixin disable-outline { + &:focus:not(.focus-visible) { + outline: none; + } +} + +@mixin ellipsis { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +@mixin ellipsis-multiline($font-size: 16px, $number-of-lines: 2) { + display: block; + /* Fallback for non-webkit */ + display: -webkit-box; /* stylelint-disable-line value-no-vendor-prefix */ + -webkit-line-clamp: $number-of-lines; + /* Fallback for non-webkit */ + font-size: $font-size; + line-height: $font-size; + overflow: hidden; + text-overflow: ellipsis; + max-height: $font-size * $number-of-lines; +} + +@mixin fade-text ($fade-after, $background-color) { + position: relative; + overflow: hidden; + + &::after { + content: ''; + pointer-events: none; + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + background: linear-gradient(transparent $fade-after, $background-color); + } +} + +@mixin peertube-word-wrap ($with-hyphen: true) { + word-break: break-word; + word-wrap: break-word; + overflow-wrap: break-word; + + @if $with-hyphen { + hyphens: auto; + } +} + +@mixin apply-svg-color ($color) { + ::ng-deep .feather, + ::ng-deep .material, + ::ng-deep .misc { + color: $color; + } +} + +@mixin fill-svg-color ($color) { + ::ng-deep svg { + path { + fill: $color; + } + } +} + +@mixin button-focus($color) { + &:focus, + &.focus-visible { + box-shadow: #{$focus-box-shadow-form} $color; + } +} + @mixin peertube-input-text($width) { + padding: 0 15px; display: inline-block; height: $button-height; width: $width; - background: #fff; + color: pvar(--inputForegroundColor); + background-color: pvar(--inputBackgroundColor); border: 1px solid #C6C6C6; border-radius: 3px; - padding-left: 15px; - padding-right: 15px; + font-size: 15px; &::placeholder { - color: #585858; + color: pvar(--inputPlaceholderColor); + } + + &[readonly] { + opacity: 0.7; + } + + @media screen and (max-width: calc(#{$width} + 40px)) { + width: 100%; } } +@mixin peertube-input-group($width) { + width: $width; + min-height: $button-height; + padding-top: 0; + padding-bottom: 0; + flex-wrap: nowrap; + + .input-group-text { + font-size: 14px; + color: #808080; + } +} + +@mixin peertube-textarea ($width, $height) { + @include peertube-input-text($width); + + color: pvar(--textareaForegroundColor); + background-color: pvar(--textareaBackgroundColor); + height: $height; + padding: 5px 15px; + font-size: 15px; +} + @mixin orange-button { - color: #fff; - background-color: $orange-color; + @include button-focus(pvar(--mainColorLightest)); - &:hover, &:active, &:focus { + &, + &:active, + &:focus { color: #fff; - background-color: $orange-hoover-color; + background-color: pvar(--mainColor); } - &[disabled], &.disabled { + &:hover { + color: #fff; + background-color: pvar(--mainHoverColor); + } + + &[disabled], + &.disabled { cursor: default; color: #fff; background-color: #C6C6C6; } + + my-global-icon { + @include apply-svg-color(#fff); + } +} + +@mixin orange-button-inverted { + @include button-focus(pvar(--mainColorLightest)); + + border: 2px solid pvar(--mainColor); + font-weight: $font-semibold; + + &, + &:active, + &:focus { + color: pvar(--mainColor); + background-color: pvar(--mainBackgroundColor); + } + + &:hover { + color: pvar(--mainColor); + background-color: pvar(--mainColorLightest); + } + + &[disabled], + &.disabled { + cursor: default; + color: pvar(--mainColor); + background-color: #C6C6C6; + } + + my-global-icon { + @include apply-svg-color(pvar(--mainColor)); + } +} + +@mixin tertiary-button { + @include button-focus($grey-button-outline-color); + + color: pvar(--greyForegroundColor); + background-color: transparent; + + &[disabled], + .disabled { + cursor: default; + } + + my-global-icon { + @include apply-svg-color(transparent); + } } @mixin grey-button { - background-color: $grey-color; - color: #585858; + @include button-focus($grey-button-outline-color); - &:hover, &:active, &:focus, &[disabled], &.disabled { - color: #585858; - background-color: $grey-hoover-color; + background-color: $grey-background-color; + color: pvar(--greyForegroundColor); + + &:hover, + &:active, + &:focus, + &[disabled], + &.disabled { + color: pvar(--greyForegroundColor); + background-color: $grey-background-hover-color; } - &[disabled], &.disabled { + &[disabled], + &.disabled { cursor: default; } + + my-global-icon { + @include apply-svg-color(pvar(--greyForegroundColor)); + } +} + +@mixin danger-button { + $color: lighten($color: #c54130, $amount: 10); + $text: #fff6f5; + + @include button-focus(scale-color($color, $alpha: -95%)); + + background-color: $color; + color: $text; + + &:hover, + &:active, + &:focus, + &[disabled], + &.disabled { + background-color: lighten($color: $color, $amount: 10); + } + + &[disabled], + &.disabled { + cursor: default; + } + + my-global-icon { + @include apply-svg-color($text); + } } @mixin peertube-button { - border: none; + @include padding(0, 17px, 0, 13px); + + border: 0; font-weight: $font-semibold; font-size: 15px; height: $button-height; line-height: $button-height; - border-radius: 3px; + // FIXME: because of primeng that redefines border-radius of all input[type="..."] + border-radius: 3px !important; text-align: center; - padding: 0 17px 0 13px; cursor: pointer; - outline: 0; } @mixin peertube-button-link { + @include disable-default-a-behaviour; + @include peertube-button; + display: inline-block; +} +@mixin peertube-button-outline { @include disable-default-a-behaviour; @include peertube-button; + + display: inline-block; + border: 1px solid; } -@mixin avatar ($size) { - width: $size; - height: $size; +@mixin button-with-icon($width: 20px, $margin-right: 3px, $top: -1px) { + display: inline-flex; + align-items: center; + line-height: normal !important; + + my-global-icon { + @include margin-right($margin-right); + + position: relative; + width: $width; + top: $top; + } +} + +@mixin peertube-file { + position: relative; + overflow: hidden; + display: inline-block; + min-height: 30px; + + input[type=file] { + position: absolute; + top: 0; + right: 0; + width: 100%; + height: 100%; + font-size: 100px; + text-align: end; + filter: alpha(opacity=0); + opacity: 0; + outline: none; + background: #fff; + cursor: inherit; + display: block; + } +} + +@mixin peertube-button-file ($width) { + @include peertube-file; + @include peertube-button; + + width: $width; } @mixin icon ($size) { @@ -87,13 +338,670 @@ cursor: pointer; } +@mixin responsive-width ($width) { + width: $width; -@mixin peertube-select ($width) { - background-color: #fff; - border: 1px solid #C6C6C6; - height: $button-height; + @media screen and (max-width: $width) { + width: 100%; + } +} + +@mixin peertube-select-container ($width) { + padding: 0; + margin: 0; width: $width; border-radius: 3px; - padding-left: 15px; - padding-right: 15px; + color: pvar(--inputForegroundColor); + background: pvar(--inputBackgroundColor); + position: relative; + font-size: 15px; + + &.disabled { + background-color: #E5E5E5; + + select { + cursor: default; + } + } + + @media screen and (max-width: $width) { + width: 100%; + } + + &::after { + top: 50%; + right: calc(0% + 15px); + content: ' '; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border: 5px solid rgba(0, 0, 0, 0); + border-top-color: #000; + margin-top: -2px; + z-index: 100; + } + + select { + padding: 0 35px 0 12px; + position: relative; + border: 1px solid #C6C6C6; + background: transparent none; + appearance: none; + cursor: pointer; + height: $button-height; + text-overflow: ellipsis; + color: pvar(--mainForegroundColor); + + &:focus { + outline: none; + } + + &:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #000; + } + + option { + color: #000; + } + } + + &.peertube-select-button { + @include grey-button; + + select, + option { + font-weight: $font-semibold; + color: pvar(--greyForegroundColor); + border: 0; + } + } +} + +// Thanks: https://codepen.io/triss90/pen/XNEdRe/ +@mixin peertube-radio-container { + input[type=radio] { + display: none; + + + label { + font-weight: $font-regular; + cursor: pointer; + + &::before { + @include margin-right(10px); + + position: relative; + top: -2px; + content: ''; + background: #fff; + border-radius: 100%; + border: 1px solid #000; + display: inline-block; + width: 15px; + height: 15px; + vertical-align: middle; + cursor: pointer; + text-align: center; + } + } + + &:checked + label::before { + background-color: #000; + box-shadow: inset 0 0 0 4px #fff; + } + + &:focus + label::before { + outline: none; + border-color: #000; + } + } +} + +@mixin peertube-checkbox ($border-width) { + opacity: 0; + position: absolute; + + &:focus + span { + box-shadow: #{$focus-box-shadow-form} pvar(--mainColorLightest); + } + + + span { + position: relative; + width: 18px; + min-width: 18px; + height: 18px; + border: $border-width solid #C6C6C6; + border-radius: 3px; + vertical-align: middle; + cursor: pointer; + + &::after { + content: ''; + position: absolute; + top: calc(2px - #{$border-width}); + left: 5px; + width: 5px; + height: 12px; + opacity: 0; + transform: rotate(45deg) scale(0); + border-right: 2px solid $bg-color; + border-bottom: 2px solid $bg-color; + } + } + + &:checked + span { + border-color: transparent; + background: pvar(--mainColor); + animation: jelly 0.6s ease; + + &::after { + opacity: 1; + transform: rotate(45deg) scale(1); + } + } + + + span + span { + @include margin-left(5px); + + font-size: 15px; + font-weight: $font-regular; + cursor: pointer; + display: inline; + } + + &[disabled] + span, + &[disabled] + span + span { + opacity: 0.5; + cursor: default; + } +} + +@mixin table-badge { + border-radius: 2px; + padding: 1/4em 1/2em; + text-transform: uppercase; + font-weight: $font-bold; + font-size: 12px; + letter-spacing: 1/3px; + + &.badge-banned, + &.badge-red { + background-color: #ffcdd2; + color: #c63737; + } + + &.badge-banned { + text-decoration: line-through; + } + + &.badge-yellow { + background-color: #feedaf; + color: #8a5340; + } + + &.badge-brown { + background-color: #ffd8b2; + color: #805b36; + } + + &.badge-green { + background-color: #c8e6c9; + color: #256029; + } + + &.badge-blue { + background-color: #b3e5fc; + color: #23547b; + } + + &.badge-purple { + background-color: #eccfff; + color: #694382; + } +} + +@mixin actor-avatar-size ($size) { + display: inline-block; + width: $size; + height: $size; + min-width: $size; + min-height: $size; +} + +@mixin actor-counters ($separator-margin: 10px) { + color: pvar(--greyForegroundColor); + font-size: 16px; + display: flex; + align-items: center; + + > *:not(:last-child)::after { + content: '•'; + margin: 0 $separator-margin; + color: pvar(--mainColor); + } +} + +@mixin chevron ($size, $border-width) { + border-style: solid; + border-width: $border-width $border-width 0 0; + content: ''; + display: inline-block; + transform: rotate(-45deg); + height: $size; + width: $size; +} + +@mixin chevron-right ($size, $border-width) { + @include chevron($size, $border-width); + + left: 0; + transform: rotate(45deg); +} + +@mixin chevron-left ($size, $border-width) { + @include chevron($size, $border-width); + + left: 0.25em; + transform: rotate(-135deg); +} + +@mixin in-content-small-title { + text-transform: uppercase; + color: pvar(--mainColor); + font-weight: $font-bold; + font-size: 13px; +} + +@mixin settings-big-title { + text-transform: uppercase; + color: pvar(--mainColor); + font-weight: $font-bold; + font-size: 110%; + margin-bottom: 10px; +} + +@mixin create-button { + @include peertube-button-link; + @include orange-button; + @include button-with-icon(20px, 5px, -1px); +} + +@mixin row-blocks ($column-responsive: true) { + display: flex; + min-height: 130px; + padding-bottom: 20px; + margin-bottom: 20px; + border-bottom: 1px solid #C6C6C6; + + @media screen and (max-width: $small-view) { + @if $column-responsive { + flex-direction: column; + height: auto; + align-items: center; + } @else { + min-height: initial; + padding-bottom: 10px; + margin-bottom: 10px; + } + } +} + +@mixin dropdown-with-icon-item { + padding: 6px 15px; + + my-global-icon { + @include margin-right(10px); + + width: 22px; + opacity: .7; + position: relative; + top: -2px; + } +} + +@mixin progressbar($small: false) { + background-color: $grey-background-color; + display: flex; + height: 1rem; + overflow: hidden; + font-size: 0.75rem; + border-radius: 0.25rem; + position: relative; + + span { + position: absolute; + color: $grey-foreground-color; + @if $small { + top: -1px; + } + + &:nth-of-type(1) { + left: .2rem; + } + &:nth-of-type(2) { + right: .2rem; + } + } + + .progress-bar { + color: pvar(--mainBackgroundColor); + background-color: pvar(--mainColor); + display: flex; + flex-direction: column; + justify-content: center; + text-align: center; + white-space: nowrap; + transition: width 0.6s ease; + + &.secondary { + background-color: pvar(--secondaryColor); + } + + &.red { + background-color: lighten($color: #c54130, $amount: 10); + } + } +} + +@mixin breadcrumb { + display: flex; + flex-wrap: wrap; + padding: 0.75rem 1rem; + margin-bottom: 1rem; + list-style: none; + background-color: pvar(--submenuBackgroundColor); + border-radius: 0.25rem; + + .breadcrumb-item { + display: flex; + + a { + color: pvar(--mainColor); + } + + + .breadcrumb-item { + @include padding-left(0.5rem); + + &::before { + @include padding-right(0.5rem); + + display: inline-block; + color: #6c757d; + content: '/'; + } + } + + &.active { + color: #6c757d; + } + } +} + +@mixin dashboard { + display: flex; + flex-wrap: wrap; + margin: 0 -5px; + + > div { + box-sizing: border-box; + flex: 0 0 percentage(1/3); + padding: 0 5px; + margin-bottom: 10px; + + > a { + @include disable-default-a-behaviour; + + text-decoration: none; + color: inherit; + display: block; + font-size: 18px; + + &:active, + &:focus, + &:hover { + opacity: .8; + } + } + + > a, + > div { + padding: 20px; + background: pvar(--submenuBackgroundColor); + border-radius: 4px; + box-sizing: border-box; + height: 100%; + } + } + + .dashboard-num, + .dashboard-text { + text-align: center; + font-size: 130%; + color: pvar(--mainForegroundColor); + line-height: 30px; + margin-bottom: 20px; + } + + .dashboard-label { + font-size: 90%; + color: pvar(--inputPlaceholderColor); + text-align: center; + } +} + +@mixin divider($color: pvar(--submenuBackgroundColor), $background: pvar(--mainBackgroundColor)) { + width: 95%; + border-top: .05rem solid $color; + height: .05rem; + text-align: center; + display: block; + position: relative; + + &[data-content] { + margin: .8rem 0; + + &::after { + background: $background; + color: $color; + content: attr(data-content); + display: inline-block; + font-size: .7rem; + padding: 0 .4rem; + transform: translateY(-.65rem); + } + } +} + +@mixin chip { + --chip-radius: 5rem; + --chip-padding: .2rem .4rem; + $avatar-height: 1.2rem; + + align-items: center; + border-radius: var(--chip-radius); + display: inline-flex; + font-size: 90%; + color: pvar(--mainForegroundColor); + height: $avatar-height; + line-height: 1rem; + margin: .1rem; + max-width: 320px; + overflow: hidden; + padding: var(--chip-padding); + text-decoration: none; + text-overflow: ellipsis; + vertical-align: middle; + white-space: nowrap; + + &.rectangular { + --chip-radius: .2rem; + --chip-padding: .2rem .3rem; + } + + my-actor-avatar { + @include margin-left(-.4rem); + @include margin-right(.2rem); + } + + &.two-lines { + $avatar-height: 2rem; + + height: $avatar-height; + + my-actor-avatar { + @include actor-avatar-size($avatar-height); + } + + div { + margin: 0 .1rem; + + display: flex; + flex-direction: column; + height: $avatar-height; + justify-content: center; + } + } +} + +// applies ratio (default to 16:9) to a child element (using $selector) only using +// an immediate's parent size. This allows to set a ratio without explicit +// dimensions, as width/height cannot be computed from each other. +@mixin block-ratio ($selector: 'div', $inverted-ratio: 9/16) { + $padding-percent: percentage($inverted-ratio); + + position: relative; + height: 0; + width: 100%; + padding-top: $padding-percent; + + #{$selector} { + position: absolute; + width: 100%; + height: 100%; + top: 0; + + @content; + } +} + +@mixin sub-menu-h1 { + ::ng-deep h1 { + font-size: 1.3rem; + border-bottom: 2px solid $grey-background-color; + padding-bottom: 15px; + margin-bottom: $sub-menu-margin-bottom; + + > span > my-global-icon, + > my-global-icon { + @include margin-right(10px); + width: 24px; + height: 24px; + vertical-align: top; + } + + .badge { + @include margin-left(7px); + vertical-align: top; + } + } +} + +@mixin play-icon ($width, $height) { + width: 0; + height: 0; + + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%) scale(0.5); + + border-top: ($height / 2) solid transparent; + border-bottom: ($height / 2) solid transparent; + + border-left: $width solid rgba(255, 255, 255, 0.95); +} + +@mixin on-small-main-col () { + :host-context(.main-col:not(.expanded)) { + @media screen and (max-width: $small-view + $menu-width) { + @content; + } + } + + :host-context(.main-col.expanded) { + @media screen and (max-width: $small-view) { + @content; + } + } +} + +@mixin on-mobile-main-col () { + :host-context(.main-col:not(.expanded)) { + @media screen and (max-width: $mobile-view + $menu-width) { + @content; + } + } + + :host-context(.main-col.expanded) { + @media screen and (max-width: $mobile-view) { + @content; + } + } +} + +@mixin margin ($block-start, $inline-end, $block-end, $inline-start) { + @include margin-left($inline-start); + @include margin-right($inline-end); + + margin-top: $block-start; + margin-bottom: $block-end; +} + +@mixin padding ($block-start, $inline-end, $block-end, $inline-start) { + @include padding-left($inline-start); + @include padding-right($inline-end); + + padding-top: $block-start; + padding-bottom: $block-end; +} + +@mixin margin-left ($value) { + @supports (margin-inline-start: $value) { + margin-inline-start: $value; + } + + @supports not (margin-inline-start: $value) { + margin-left: $value; + } +} + +@mixin margin-right ($value) { + @supports (margin-inline-end: $value) { + margin-inline-end: $value; + } + + @supports not (margin-inline-end: $value) { + margin-right: $value; + } +} + +@mixin padding-left ($value) { + @supports (padding-inline-start: $value) { + padding-inline-start: $value; + } + + @supports not (padding-inline-start: $value) { + padding-left: $value; + } +} + +@mixin padding-right ($value) { + @supports (padding-inline-end: $value) { + padding-inline-end: $value; + } + + @supports not (padding-inline-end: $value) { + padding-right: $value; + } }