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