]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame_incremental - client/src/sass/include/_mixins.scss
Fix basic linter issues
[github/Chocobozzz/PeerTube.git] / client / src / sass / include / _mixins.scss
... / ...
CommitLineData
1@use 'sass:math';
2@use '_variables' as *;
3
4@import '_bootstrap-mixins';
5
6
7@mixin disable-default-a-behaviour {
8 &:hover,
9 &:focus,
10 &:active {
11 text-decoration: none !important;
12 outline: none !important;
13 }
14}
15
16@mixin disable-outline {
17 &:focus:not(.focus-visible) {
18 outline: none;
19 }
20}
21
22@mixin ellipsis {
23 white-space: nowrap;
24 overflow: hidden;
25 text-overflow: ellipsis;
26}
27
28@mixin ellipsis-multiline($font-size: 16px, $number-of-lines: 2) {
29 display: block;
30 /* Fallback for non-webkit */
31 display: -webkit-box; /* stylelint-disable-line value-no-vendor-prefix */
32 -webkit-line-clamp: $number-of-lines;
33 -webkit-box-orient: vertical;
34 /* Fallback for non-webkit */
35 font-size: $font-size;
36 line-height: $font-size;
37 overflow: hidden;
38 text-overflow: ellipsis;
39 max-height: $font-size * $number-of-lines;
40}
41
42@mixin muted {
43 color: pvar(--greyForegroundColor) !important;
44}
45
46@mixin fade-text ($fade-after, $background-color) {
47 position: relative;
48 overflow: hidden;
49
50 &::after {
51 content: '';
52 pointer-events: none;
53 width: 100%;
54 height: 100%;
55 position: absolute;
56 left: 0;
57 top: 0;
58 background: linear-gradient(transparent $fade-after, $background-color);
59 }
60}
61
62@mixin peertube-word-wrap ($with-hyphen: true) {
63 word-break: break-word;
64 word-wrap: break-word;
65 overflow-wrap: break-word;
66
67 @if $with-hyphen {
68 hyphens: auto;
69 }
70}
71
72@mixin apply-svg-color ($color) {
73 ::ng-deep .feather,
74 ::ng-deep .material,
75 ::ng-deep .misc {
76 color: $color;
77 }
78}
79
80@mixin fill-svg-color ($color) {
81 ::ng-deep svg {
82 path {
83 fill: $color;
84 }
85 }
86}
87
88@mixin button-focus($color) {
89 &:focus,
90 &.focus-visible {
91 box-shadow: #{$focus-box-shadow-form} $color;
92 }
93}
94
95@mixin peertube-input-text($width) {
96 padding: 4px 15px;
97 display: inline-block;
98 width: $width;
99 max-width: $width;
100 color: pvar(--inputForegroundColor);
101 background-color: pvar(--inputBackgroundColor);
102 border: 1px solid pvar(--inputBorderColor);
103 border-radius: 3px;
104 font-size: $form-input-font-size;
105 line-height: $form-input-line-height;
106
107 &::placeholder {
108 color: pvar(--inputPlaceholderColor);
109 }
110
111 &[readonly] {
112 opacity: 0.7;
113 }
114
115 @media screen and (max-width: calc(#{$width} + 40px)) {
116 width: 100%;
117 }
118}
119
120@mixin peertube-textarea ($width, $height) {
121 @include peertube-input-text($width);
122
123 color: pvar(--textareaForegroundColor) !important;
124 background-color: pvar(--textareaBackgroundColor) !important;
125 height: $height;
126 padding: 5px 15px;
127}
128
129@mixin orange-button {
130 @include button-focus(pvar(--mainColorLightest));
131
132 &,
133 &:active,
134 &:focus {
135 color: #fff;
136 background-color: pvar(--mainColor);
137 }
138
139 &:hover {
140 color: #fff;
141 background-color: pvar(--mainHoverColor);
142 }
143
144 &[disabled],
145 &.disabled {
146 cursor: default;
147 color: #fff;
148 background-color: pvar(--inputBorderColor);
149 }
150
151 my-global-icon {
152 @include apply-svg-color(#fff);
153 }
154}
155
156@mixin orange-button-inverted {
157 @include button-focus(pvar(--mainColorLightest));
158
159 border: 2px solid pvar(--mainColor);
160 font-weight: $font-semibold;
161
162 &,
163 &:active,
164 &:focus {
165 color: pvar(--mainColor);
166 background-color: pvar(--mainBackgroundColor);
167 }
168
169 &:hover {
170 color: pvar(--mainColor);
171 background-color: pvar(--mainColorLightest);
172 }
173
174 &[disabled],
175 &.disabled {
176 cursor: default;
177 color: pvar(--mainColor);
178 background-color: pvar(--inputBorderColor);
179 }
180
181 my-global-icon {
182 @include apply-svg-color(pvar(--mainColor));
183 }
184}
185
186@mixin tertiary-button {
187 @include button-focus($grey-button-outline-color);
188
189 color: pvar(--greyForegroundColor);
190 background-color: transparent;
191
192 &[disabled],
193 .disabled {
194 cursor: default;
195 }
196
197 my-global-icon {
198 @include apply-svg-color(transparent);
199 }
200}
201
202@mixin grey-button {
203 @include button-focus($grey-button-outline-color);
204
205 background-color: pvar(--greyBackgroundColor);
206 color: pvar(--greyForegroundColor);
207
208 &:hover,
209 &:active,
210 &:focus,
211 &[disabled],
212 &.disabled {
213 color: pvar(--greyForegroundColor);
214 background-color: pvar(--greySecondaryBackgroundColor);
215 }
216
217 &[disabled],
218 &.disabled {
219 cursor: default;
220 }
221
222 my-global-icon {
223 @include apply-svg-color(pvar(--greyForegroundColor));
224 }
225}
226
227@mixin danger-button {
228 $color: lighten($color: #c54130, $amount: 10);
229 $text: #fff6f5;
230
231 @include button-focus(scale-color($color, $alpha: -95%));
232
233 background-color: $color;
234 color: $text;
235
236 &:hover,
237 &:active,
238 &:focus,
239 &[disabled],
240 &.disabled {
241 background-color: lighten($color: $color, $amount: 10);
242 }
243
244 &[disabled],
245 &.disabled {
246 cursor: default;
247 }
248
249 my-global-icon {
250 @include apply-svg-color($text);
251 }
252}
253
254@mixin peertube-button {
255 padding: 4px 13px;
256
257 border: 0;
258 font-weight: $font-semibold;
259
260 // Because of primeng that redefines border-radius of all input[type="..."]
261 border-radius: 3px !important;
262
263 text-align: center;
264 cursor: pointer;
265
266 font-size: $button-font-size;
267
268 my-global-icon + * {
269 @include margin-right(4px);
270 @include margin-left(4px);
271 }
272}
273
274@mixin peertube-button-big {
275 height: auto;
276 padding: 10px 25px;
277 font-size: 18px;
278 line-height: 1.2;
279 border: 0;
280 font-weight: $font-semibold;
281
282 // Because of primeng that redefines border-radius of all input[type="..."]
283 border-radius: 3px !important;
284}
285
286@mixin peertube-button-link {
287 @include disable-default-a-behaviour;
288 @include peertube-button;
289
290 display: inline-block;
291}
292
293@mixin peertube-button-big-link {
294 @include disable-default-a-behaviour;
295 @include peertube-button-big;
296
297 display: inline-block;
298}
299
300@mixin peertube-button-outline {
301 @include disable-default-a-behaviour;
302 @include peertube-button;
303
304 display: inline-block;
305 border: 1px solid;
306}
307
308@mixin button-with-icon($width: 20px, $margin-right: 3px, $top: -1px) {
309 my-global-icon {
310 @include margin-right($margin-right);
311
312 position: relative;
313 width: $width;
314 top: $top;
315 }
316}
317
318@mixin peertube-file {
319 position: relative;
320 overflow: hidden;
321 display: inline-block;
322
323 input[type=file] {
324 position: absolute;
325 top: 0;
326 right: 0;
327 width: 100%;
328 height: 100%;
329 font-size: 100px;
330 text-align: end;
331 filter: alpha(opacity=0);
332 opacity: 0;
333 outline: none;
334 background: pvar(--mainBackgroundColor);
335 cursor: inherit;
336 display: block;
337 }
338}
339
340@mixin peertube-button-file ($width) {
341 @include peertube-file;
342 @include peertube-button;
343
344 width: $width;
345}
346
347@mixin icon ($size) {
348 display: inline-block;
349 background-repeat: no-repeat;
350 background-size: contain;
351 width: $size;
352 height: $size;
353 vertical-align: middle;
354 cursor: pointer;
355}
356
357@mixin responsive-width ($width) {
358 width: $width;
359
360 @media screen and (max-width: $width) {
361 width: 100%;
362 }
363}
364
365@mixin peertube-select-container ($width) {
366 padding: 0;
367 margin: 0;
368 width: $width;
369 border-radius: 3px;
370 color: pvar(--inputForegroundColor);
371 background: pvar(--inputBackgroundColor);
372 position: relative;
373 height: min-content;
374
375 &.disabled {
376 background-color: #E5E5E5;
377
378 select {
379 cursor: default;
380 }
381 }
382
383 select[disabled] {
384 background-color: #f9f9f9;
385 }
386
387 @media screen and (max-width: $width) {
388 width: 100%;
389 }
390
391 &::after {
392 top: 50%;
393 right: calc(0% + 15px);
394 content: ' ';
395 height: 0;
396 width: 0;
397 position: absolute;
398 pointer-events: none;
399 border: 5px solid rgba(0, 0, 0, 0);
400 border-top-color: pvar(--mainForegroundColor);
401 margin-top: -2px;
402 z-index: 100;
403 }
404
405 select {
406 padding: 4px 35px 4px 12px;
407 position: relative;
408 border: 1px solid pvar(--inputBorderColor);
409 background: transparent none;
410 appearance: none;
411 text-overflow: ellipsis;
412 color: pvar(--mainForegroundColor);
413 font-size: $form-input-font-size;
414 line-height: $form-input-line-height;
415
416 &:focus {
417 outline: none;
418 }
419
420 &:-moz-focusring {
421 color: transparent;
422 text-shadow: 0 0 0 #000;
423 }
424
425 option {
426 color: #000;
427
428 &[value=undefined] {
429 font-weight: $font-semibold;
430 }
431 }
432 }
433
434 &.peertube-select-button {
435 @include grey-button;
436
437 select {
438 font-weight: $font-semibold;
439 color: pvar(--greyForegroundColor);
440 border: 0;
441 }
442 }
443}
444
445// Thanks: https://codepen.io/manabox/pen/raQmpL
446@mixin peertube-radio-container {
447 label {
448 font-size: $form-input-font-size;
449 }
450
451 [type=radio]:checked,
452 [type=radio]:not(:checked) {
453 position: absolute;
454 opacity: 0;
455 cursor: pointer;
456 height: 0;
457 width: 0;
458 }
459
460 [type=radio]:checked + label,
461 [type=radio]:not(:checked) + label {
462 position: relative;
463 padding-left: 28px;
464 cursor: pointer;
465 line-height: 20px;
466 display: inline-block;
467 font-weight: $font-regular;
468 }
469
470 [type=radio]:checked + label::before,
471 [type=radio]:not(:checked) + label::before {
472 content: '';
473 position: absolute;
474 left: 0;
475 top: 0;
476 width: 18px;
477 height: 18px;
478 border: 1px solid pvar(--inputBorderColor);
479 border-radius: 100%;
480 background: #fff;
481 }
482
483 [type=radio]:checked + label::after,
484 [type=radio]:not(:checked) + label::after {
485 content: '';
486 width: 10px;
487 height: 10px;
488 background: pvar(--mainColor);
489 position: absolute;
490 top: 4px;
491 left: 4px;
492 border-radius: 100%;
493 transition: all 0.2s ease;
494 }
495 [type=radio]:not(:checked) + label::after {
496 opacity: 0;
497 transform: scale(0);
498 }
499 [type=radio]:checked + label::after {
500 opacity: 1;
501 transform: scale(1);
502 }
503
504 .form-group-description {
505 display: block;
506 margin-top: -7px;
507 margin-bottom: 10px;
508 margin-left: 29px;
509 }
510}
511
512@mixin peertube-checkbox ($border-width) {
513 opacity: 0;
514 position: absolute;
515
516 &:focus + span {
517 box-shadow: #{$focus-box-shadow-form} pvar(--mainColorLightest);
518 }
519
520 + span {
521 position: relative;
522 width: 18px;
523 min-width: 18px;
524 height: 18px;
525 border: $border-width solid pvar(--inputBorderColor);
526 border-radius: 3px;
527 vertical-align: middle;
528 cursor: pointer;
529
530 &::after {
531 content: '';
532 position: absolute;
533 top: calc(2px - #{$border-width});
534 left: 5px;
535 width: 5px;
536 height: 12px;
537 opacity: 0;
538 transform: rotate(45deg) scale(0);
539 border-right: 2px solid pvar(--mainBackgroundColor);
540 border-bottom: 2px solid pvar(--mainBackgroundColor);
541 }
542 }
543
544 &:checked + span {
545 border-color: transparent;
546 background: pvar(--mainColor);
547 animation: jelly 0.6s ease;
548
549 &::after {
550 opacity: 1;
551 transform: rotate(45deg) scale(1);
552 }
553 }
554
555 + span + span {
556 @include margin-left(5px);
557
558 font-weight: $font-regular;
559 cursor: pointer;
560 display: inline;
561 }
562
563 &[disabled] + span,
564 &[disabled] + span + span {
565 opacity: 0.5;
566 cursor: default;
567 }
568}
569
570@mixin actor-avatar-size ($size) {
571 display: inline-block;
572 width: $size;
573 height: $size;
574 min-width: $size;
575 min-height: $size;
576}
577
578@mixin actor-counters ($separator-margin: 10px) {
579 color: pvar(--greyForegroundColor);
580 display: flex;
581 align-items: center;
582
583 > *:not(:last-child)::after {
584 content: '•';
585 margin: 0 $separator-margin;
586 color: pvar(--mainColor);
587 }
588}
589
590@mixin in-content-small-title {
591 text-transform: uppercase;
592 color: pvar(--mainColor);
593 font-weight: $font-bold;
594 font-size: 13px;
595}
596
597@mixin settings-big-title {
598 text-transform: uppercase;
599 color: pvar(--mainColor);
600 font-weight: $font-bold;
601 font-size: 1rem;
602 margin-bottom: 10px;
603}
604
605@mixin create-button {
606 @include peertube-button-link;
607 @include orange-button;
608 @include button-with-icon(20px, 5px, -1px);
609}
610
611@mixin row-blocks ($column-responsive: true, $min-height: 130px, $separator: true) {
612 display: flex;
613 min-height: $min-height;
614 padding-bottom: 20px;
615 margin-bottom: 20px;
616
617 @if $separator {
618 border-bottom: 1px solid pvar(--inputBorderColor);
619 }
620
621 @media screen and (max-width: $small-view) {
622 @if $column-responsive {
623 flex-direction: column;
624 height: auto;
625 align-items: center;
626 } @else {
627 min-height: initial;
628 padding-bottom: 10px;
629 margin-bottom: 10px;
630 }
631 }
632}
633
634@mixin dropdown-with-icon-item {
635 padding: 6px 15px;
636
637 my-global-icon {
638 @include margin-right(10px);
639
640 width: 22px;
641 opacity: .7;
642 position: relative;
643 top: -2px;
644 }
645}
646
647@mixin progressbar($small: false) {
648 background-color: pvar(--greyBackgroundColor);
649 display: flex;
650 height: 1rem;
651 overflow: hidden;
652 font-size: 0.75rem;
653 border-radius: 0.25rem;
654 position: relative;
655
656 span {
657 position: absolute;
658 color: pvar(--greyForegroundColor);
659
660 @if $small {
661 top: -1px;
662 }
663
664 &:nth-of-type(1) {
665 left: .2rem;
666 }
667 &:nth-of-type(2) {
668 right: .2rem;
669 }
670 }
671
672 .progress-bar {
673 color: pvar(--mainBackgroundColor);
674 background-color: pvar(--mainColor);
675 display: flex;
676 flex-direction: column;
677 justify-content: center;
678 text-align: center;
679 white-space: nowrap;
680 transition: width 0.6s ease;
681
682 &.red {
683 background-color: lighten($color: #c54130, $amount: 10);
684 }
685 }
686}
687
688@mixin breadcrumb {
689 display: flex;
690 flex-wrap: wrap;
691 padding: 0;
692 margin-bottom: 1rem;
693 list-style: none;
694 font-weight: $font-semibold;
695
696 .breadcrumb-item {
697 display: flex;
698
699 a {
700 color: pvar(--mainColor);
701 }
702
703 + .breadcrumb-item {
704 @include padding-left(0.5rem);
705
706 &::before {
707 @include padding-right(0.5rem);
708
709 display: inline-block;
710 color: #6c757d;
711 content: '/';
712 }
713 }
714
715 &.active {
716 color: #6c757d;
717 }
718 }
719}
720
721@mixin dashboard {
722 display: flex;
723 flex-wrap: wrap;
724 margin: 0 -5px;
725
726 > div {
727 box-sizing: border-box;
728 flex: 0 0 percentage(math.div(1, 3));
729 padding: 0 5px;
730 margin-bottom: 10px;
731
732 > a {
733 @include disable-default-a-behaviour;
734
735 text-decoration: none;
736 color: inherit;
737 display: block;
738 font-size: 18px;
739
740 &:active,
741 &:focus,
742 &:hover {
743 opacity: .8;
744 }
745 }
746
747 > a,
748 > div {
749 padding: 20px;
750 background: pvar(--submenuBackgroundColor);
751 border-radius: 4px;
752 box-sizing: border-box;
753 height: 100%;
754 }
755 }
756
757 .dashboard-num,
758 .dashboard-text {
759 text-align: center;
760 font-size: 130%;
761 color: pvar(--mainForegroundColor);
762 line-height: 30px;
763 margin-bottom: 20px;
764 }
765
766 .dashboard-label {
767 font-size: 90%;
768 color: pvar(--inputPlaceholderColor);
769 text-align: center;
770 }
771}
772
773@mixin divider($color: pvar(--submenuBackgroundColor), $background: pvar(--mainBackgroundColor)) {
774 width: 95%;
775 border-top: .05rem solid $color;
776 height: .05rem;
777 text-align: center;
778 display: block;
779 position: relative;
780
781 &[data-content] {
782 margin: .8rem 0;
783
784 &::after {
785 background: $background;
786 color: $color;
787 content: attr(data-content);
788 display: inline-block;
789 font-size: .7rem;
790 padding: 0 .4rem;
791 transform: translateY(-.65rem);
792 }
793 }
794}
795
796@mixin chip {
797 --avatar-size: 1.2rem;
798
799 display: inline-flex;
800 color: pvar(--mainForegroundColor);
801 height: var(--avatar-size);
802 max-width: 320px;
803 overflow: hidden;
804 text-decoration: none;
805 text-overflow: ellipsis;
806 vertical-align: middle;
807 white-space: nowrap;
808
809 my-actor-avatar {
810 @include margin-right(.2rem);
811
812 border-radius: 5rem;
813 width: var(--avatar-size);
814 height: var(--avatar-size);
815 }
816
817 &.two-lines {
818 --avatar-size: 2rem;
819
820 font-size: 14px;
821 line-height: 1rem;
822
823 my-actor-avatar {
824 display: inline-block;
825 }
826
827 > div {
828 display: flex;
829 flex-direction: column;
830 justify-content: center;
831 }
832 }
833}
834
835// applies ratio (default to 16:9) to a child element (using $selector) only using
836// an immediate's parent size. This allows to set a ratio without explicit
837// dimensions, as width/height cannot be computed from each other.
838@mixin block-ratio ($selector: 'div', $inverted-ratio: math.div(9, 16)) {
839 $padding-percent: percentage($inverted-ratio);
840
841 position: relative;
842 height: 0;
843 width: 100%;
844 padding-top: $padding-percent;
845
846 #{$selector} {
847 position: absolute;
848 width: 100%;
849 height: 100%;
850 top: 0;
851
852 @content;
853 }
854}
855
856@mixin sub-menu-h1 {
857 ::ng-deep h1 {
858 font-size: 1.3rem;
859 border-bottom: 2px solid $grey-background-color;
860 padding-bottom: 15px;
861 margin-bottom: $sub-menu-margin-bottom;
862
863 > span > my-global-icon,
864 > my-global-icon {
865 @include margin-right(10px);
866 width: 24px;
867 height: 24px;
868 vertical-align: top;
869 }
870
871 .pt-badge {
872 @include margin-left(7px);
873
874 vertical-align: top;
875 }
876 }
877}
878
879@mixin play-icon ($width, $height) {
880 width: 0;
881 height: 0;
882
883 position: absolute;
884 left: 50%;
885 top: 50%;
886 transform: translate(-50%, -50%) scale(0.5);
887
888 border-top: #{math.div($height, 2)} solid transparent;
889 border-bottom: #{math.div($height, 2)} solid transparent;
890
891 border-left: $width solid rgba(255, 255, 255, 0.95);
892}
893
894@mixin on-small-main-col () {
895 :host-context(.main-col:not(.expanded)) {
896 @media screen and (max-width: $small-view + $menu-width) {
897 @content;
898 }
899 }
900
901 :host-context(.main-col.expanded) {
902 @media screen and (max-width: $small-view) {
903 @content;
904 }
905 }
906}
907
908@mixin on-mobile-main-col () {
909 :host-context(.main-col:not(.expanded)) {
910 @media screen and (max-width: $mobile-view + $menu-width) {
911 @content;
912 }
913 }
914
915 :host-context(.main-col.expanded) {
916 @media screen and (max-width: $mobile-view) {
917 @content;
918 }
919 }
920}
921
922@mixin margin ($block-start, $inline-end, $block-end, $inline-start) {
923 @include margin-left($inline-start);
924 @include margin-right($inline-end);
925 @include margin-top($block-start);
926 @include margin-bottom($block-end);
927}
928
929@mixin padding ($block-start, $inline-end, $block-end, $inline-start) {
930 @include padding-left($inline-start);
931 @include padding-right($inline-end);
932 @include padding-top($block-start);
933 @include padding-bottom($block-end);
934}
935
936@mixin margin-left ($value) {
937 @supports (margin-inline-start: $value) {
938 @include rfs($value, margin-inline-start);
939 }
940
941 @supports not (margin-inline-start: $value) {
942 @include rfs($value, margin-left);
943 }
944}
945
946@mixin margin-right ($value) {
947 @supports (margin-inline-end: $value) {
948 @include rfs($value, margin-inline-end);
949 }
950
951 @supports not (margin-inline-end: $value) {
952 @include rfs($value, margin-right);
953 }
954}
955
956@mixin padding-left ($value) {
957 @supports (padding-inline-start: $value) {
958 @include rfs($value, padding-inline-start);
959 }
960
961 @supports not (padding-inline-start: $value) {
962 @include rfs($value, padding-left);
963 }
964}
965
966@mixin padding-right ($value) {
967 @supports (padding-inline-end: $value) {
968 @include rfs($value, padding-inline-end);
969 }
970
971 @supports not (padding-inline-end: $value) {
972 @include rfs($value, padding-right);
973 }
974}