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