]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - client/src/sass/include/_mixins.scss
Fix button 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 padding: 2px 13px;
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 line-height: $button-font-size + math.round(math.div($button-font-size, 2));
268
269 my-global-icon + * {
270 @include margin-right(4px);
271 @include margin-left(4px);
272 }
273 }
274
275 @mixin peertube-button-big {
276 height: auto;
277 padding: 10px 25px;
278 font-size: 18px;
279 line-height: 1.2;
280 border: 0;
281 font-weight: $font-semibold;
282
283 // Because of primeng that redefines border-radius of all input[type="..."]
284 border-radius: 3px !important;
285 }
286
287 @mixin peertube-button-link {
288 @include disable-default-a-behaviour;
289 @include peertube-button;
290
291 display: inline-block;
292 }
293
294 @mixin peertube-button-big-link {
295 @include disable-default-a-behaviour;
296 @include peertube-button-big;
297
298 display: inline-block;
299 }
300
301 @mixin peertube-button-outline {
302 @include disable-default-a-behaviour;
303 @include peertube-button;
304
305 display: inline-block;
306 border: 1px solid;
307 }
308
309 @mixin button-with-icon($width: 20px, $margin-right: 3px, $top: -1px) {
310 my-global-icon {
311 @include margin-right($margin-right);
312
313 position: relative;
314 width: $width;
315 top: $top;
316 }
317
318 span {
319 vertical-align: middle;
320 }
321 }
322
323 @mixin peertube-file {
324 position: relative;
325 overflow: hidden;
326 display: inline-block;
327
328 input[type=file] {
329 position: absolute;
330 top: 0;
331 right: 0;
332 width: 100%;
333 height: 100%;
334 font-size: 100px;
335 text-align: end;
336 filter: alpha(opacity=0);
337 opacity: 0;
338 outline: none;
339 background: pvar(--mainBackgroundColor);
340 cursor: inherit;
341 display: block;
342 }
343 }
344
345 @mixin peertube-button-file ($width) {
346 @include peertube-file;
347 @include peertube-button;
348
349 width: $width;
350 }
351
352 @mixin icon ($size) {
353 display: inline-block;
354 background-repeat: no-repeat;
355 background-size: contain;
356 width: $size;
357 height: $size;
358 vertical-align: middle;
359 cursor: pointer;
360 }
361
362 @mixin responsive-width ($width) {
363 width: $width;
364
365 @media screen and (max-width: $width) {
366 width: 100%;
367 }
368 }
369
370 @mixin peertube-select-container ($width) {
371 padding: 0;
372 margin: 0;
373 width: $width;
374 border-radius: 3px;
375 color: pvar(--inputForegroundColor);
376 background: pvar(--inputBackgroundColor);
377 position: relative;
378 height: min-content;
379
380 &.disabled {
381 background-color: #E5E5E5;
382
383 select {
384 cursor: default;
385 }
386 }
387
388 select[disabled] {
389 background-color: #f9f9f9;
390 }
391
392 @media screen and (max-width: $width) {
393 width: 100%;
394 }
395
396 &::after {
397 top: 50%;
398 right: calc(0% + 15px);
399 content: ' ';
400 height: 0;
401 width: 0;
402 position: absolute;
403 pointer-events: none;
404 border: 5px solid rgba(0, 0, 0, 0);
405 border-top-color: pvar(--mainForegroundColor);
406 margin-top: -2px;
407 z-index: 100;
408 }
409
410 select {
411 padding: 4px 35px 4px 12px;
412 position: relative;
413 border: 1px solid pvar(--inputBorderColor);
414 background: transparent none;
415 appearance: none;
416 text-overflow: ellipsis;
417 color: pvar(--mainForegroundColor);
418 font-size: $form-input-font-size;
419 line-height: $form-input-line-height;
420
421 &:focus {
422 outline: none;
423 }
424
425 &:-moz-focusring {
426 color: transparent;
427 text-shadow: 0 0 0 #000;
428 }
429
430 option {
431 color: #000;
432
433 &[value=undefined] {
434 font-weight: $font-semibold;
435 }
436 }
437 }
438
439 &.peertube-select-button {
440 @include grey-button;
441
442 select {
443 font-weight: $font-semibold;
444 color: pvar(--greyForegroundColor);
445 border: 0;
446 }
447 }
448 }
449
450 // Thanks: https://codepen.io/manabox/pen/raQmpL
451 @mixin peertube-radio-container {
452 label {
453 font-size: $form-input-font-size;
454 }
455
456 [type=radio]:checked,
457 [type=radio]:not(:checked) {
458 position: absolute;
459 opacity: 0;
460 cursor: pointer;
461 height: 0;
462 width: 0;
463 }
464
465 [type=radio]:checked + label,
466 [type=radio]:not(:checked) + label {
467 position: relative;
468 padding-left: 28px;
469 cursor: pointer;
470 line-height: 20px;
471 display: inline-block;
472 font-weight: $font-regular;
473 }
474
475 [type=radio]:checked + label::before,
476 [type=radio]:not(:checked) + label::before {
477 content: '';
478 position: absolute;
479 left: 0;
480 top: 0;
481 width: 18px;
482 height: 18px;
483 border: 1px solid pvar(--inputBorderColor);
484 border-radius: 100%;
485 background: #fff;
486 }
487
488 [type=radio]:checked + label::after,
489 [type=radio]:not(:checked) + label::after {
490 content: '';
491 width: 10px;
492 height: 10px;
493 background: pvar(--mainColor);
494 position: absolute;
495 top: 4px;
496 left: 4px;
497 border-radius: 100%;
498 transition: all 0.2s ease;
499 }
500 [type=radio]:not(:checked) + label::after {
501 opacity: 0;
502 transform: scale(0);
503 }
504 [type=radio]:checked + label::after {
505 opacity: 1;
506 transform: scale(1);
507 }
508
509 .form-group-description {
510 display: block;
511 margin-top: -7px;
512 margin-bottom: 10px;
513 margin-left: 29px;
514 }
515 }
516
517 @mixin peertube-checkbox ($border-width) {
518 opacity: 0;
519 position: absolute;
520
521 &:focus + span {
522 box-shadow: #{$focus-box-shadow-form} pvar(--mainColorLightest);
523 }
524
525 + span {
526 position: relative;
527 width: 18px;
528 min-width: 18px;
529 height: 18px;
530 border: $border-width solid pvar(--inputBorderColor);
531 border-radius: 3px;
532 vertical-align: middle;
533 cursor: pointer;
534
535 &::after {
536 content: '';
537 position: absolute;
538 top: calc(2px - #{$border-width});
539 left: 5px;
540 width: 5px;
541 height: 12px;
542 opacity: 0;
543 transform: rotate(45deg) scale(0);
544 border-right: 2px solid pvar(--mainBackgroundColor);
545 border-bottom: 2px solid pvar(--mainBackgroundColor);
546 }
547 }
548
549 &:checked + span {
550 border-color: transparent;
551 background: pvar(--mainColor);
552 animation: jelly 0.6s ease;
553
554 &::after {
555 opacity: 1;
556 transform: rotate(45deg) scale(1);
557 }
558 }
559
560 + span + span {
561 @include margin-left(5px);
562
563 font-weight: $font-regular;
564 cursor: pointer;
565 display: inline;
566 }
567
568 &[disabled] + span,
569 &[disabled] + span + span {
570 opacity: 0.5;
571 cursor: default;
572 }
573 }
574
575 @mixin actor-avatar-size ($size) {
576 display: inline-block;
577 width: $size;
578 height: $size;
579 min-width: $size;
580 min-height: $size;
581 }
582
583 @mixin actor-counters ($separator-margin: 10px) {
584 color: pvar(--greyForegroundColor);
585 display: flex;
586 align-items: center;
587
588 > *:not(:last-child)::after {
589 content: '•';
590 margin: 0 $separator-margin;
591 color: pvar(--mainColor);
592 }
593 }
594
595 @mixin in-content-small-title {
596 text-transform: uppercase;
597 color: pvar(--mainColor);
598 font-weight: $font-bold;
599 font-size: 13px;
600 }
601
602 @mixin settings-big-title {
603 text-transform: uppercase;
604 color: pvar(--mainColor);
605 font-weight: $font-bold;
606 font-size: 1rem;
607 margin-bottom: 10px;
608 }
609
610 @mixin create-button {
611 @include peertube-button-link;
612 @include orange-button;
613 @include button-with-icon(20px, 5px, -1px);
614 }
615
616 @mixin row-blocks ($column-responsive: true, $min-height: 130px, $separator: true) {
617 display: flex;
618 min-height: $min-height;
619 padding-bottom: 20px;
620 margin-bottom: 20px;
621
622 @if $separator {
623 border-bottom: 1px solid pvar(--inputBorderColor);
624 }
625
626 @media screen and (max-width: $small-view) {
627 @if $column-responsive {
628 flex-direction: column;
629 height: auto;
630 align-items: center;
631 } @else {
632 min-height: initial;
633 padding-bottom: 10px;
634 margin-bottom: 10px;
635 }
636 }
637 }
638
639 @mixin dropdown-with-icon-item {
640 padding: 6px 15px;
641
642 my-global-icon {
643 @include margin-right(10px);
644
645 width: 22px;
646 opacity: .7;
647 position: relative;
648 top: -2px;
649 }
650 }
651
652 @mixin progressbar($small: false) {
653 background-color: pvar(--greyBackgroundColor);
654 display: flex;
655 height: 1rem;
656 overflow: hidden;
657 font-size: 0.75rem;
658 border-radius: 0.25rem;
659 position: relative;
660
661 span {
662 position: absolute;
663 color: pvar(--greyForegroundColor);
664
665 @if $small {
666 top: -1px;
667 }
668
669 &:nth-of-type(1) {
670 left: .2rem;
671 }
672 &:nth-of-type(2) {
673 right: .2rem;
674 }
675 }
676
677 .progress-bar {
678 color: pvar(--mainBackgroundColor);
679 background-color: pvar(--mainColor);
680 display: flex;
681 flex-direction: column;
682 justify-content: center;
683 text-align: center;
684 white-space: nowrap;
685 transition: width 0.6s ease;
686
687 &.red {
688 background-color: lighten($color: #c54130, $amount: 10);
689 }
690 }
691 }
692
693 @mixin breadcrumb {
694 display: flex;
695 flex-wrap: wrap;
696 padding: 0;
697 margin-bottom: 1rem;
698 list-style: none;
699 font-weight: $font-semibold;
700
701 .breadcrumb-item {
702 display: flex;
703
704 a {
705 color: pvar(--mainColor);
706 }
707
708 + .breadcrumb-item {
709 @include padding-left(0.5rem);
710
711 &::before {
712 @include padding-right(0.5rem);
713
714 display: inline-block;
715 color: #6c757d;
716 content: '/';
717 }
718 }
719
720 &.active {
721 color: #6c757d;
722 }
723 }
724 }
725
726 @mixin dashboard {
727 display: flex;
728 flex-wrap: wrap;
729 margin: 0 -5px;
730
731 > div {
732 box-sizing: border-box;
733 flex: 0 0 percentage(math.div(1, 3));
734 padding: 0 5px;
735 margin-bottom: 10px;
736
737 > a {
738 @include disable-default-a-behaviour;
739
740 text-decoration: none;
741 color: inherit;
742 display: block;
743 font-size: 18px;
744
745 &:active,
746 &:focus,
747 &:hover {
748 opacity: .8;
749 }
750 }
751
752 > a,
753 > div {
754 padding: 20px;
755 background: pvar(--submenuBackgroundColor);
756 border-radius: 4px;
757 box-sizing: border-box;
758 height: 100%;
759 }
760 }
761
762 .dashboard-num,
763 .dashboard-text {
764 text-align: center;
765 font-size: 130%;
766 color: pvar(--mainForegroundColor);
767 line-height: 30px;
768 margin-bottom: 20px;
769 }
770
771 .dashboard-label {
772 font-size: 90%;
773 color: pvar(--inputPlaceholderColor);
774 text-align: center;
775 }
776 }
777
778 @mixin divider($color: pvar(--submenuBackgroundColor), $background: pvar(--mainBackgroundColor)) {
779 width: 95%;
780 border-top: .05rem solid $color;
781 height: .05rem;
782 text-align: center;
783 display: block;
784 position: relative;
785
786 &[data-content] {
787 margin: .8rem 0;
788
789 &::after {
790 background: $background;
791 color: $color;
792 content: attr(data-content);
793 display: inline-block;
794 font-size: .7rem;
795 padding: 0 .4rem;
796 transform: translateY(-.65rem);
797 }
798 }
799 }
800
801 @mixin chip {
802 --avatar-size: 1.2rem;
803
804 display: inline-flex;
805 color: pvar(--mainForegroundColor);
806 height: var(--avatar-size);
807 max-width: 320px;
808 overflow: hidden;
809 text-decoration: none;
810 text-overflow: ellipsis;
811 vertical-align: middle;
812 white-space: nowrap;
813
814 my-actor-avatar {
815 @include margin-right(.2rem);
816
817 border-radius: 5rem;
818 width: var(--avatar-size);
819 height: var(--avatar-size);
820 }
821
822 &.two-lines {
823 --avatar-size: 2rem;
824
825 font-size: 14px;
826 line-height: 1rem;
827
828 my-actor-avatar {
829 display: inline-block;
830 }
831
832 > div {
833 display: flex;
834 flex-direction: column;
835 justify-content: center;
836 }
837 }
838 }
839
840 // applies ratio (default to 16:9) to a child element (using $selector) only using
841 // an immediate's parent size. This allows to set a ratio without explicit
842 // dimensions, as width/height cannot be computed from each other.
843 @mixin block-ratio ($selector: 'div', $inverted-ratio: math.div(9, 16)) {
844 $padding-percent: percentage($inverted-ratio);
845
846 position: relative;
847 height: 0;
848 width: 100%;
849 padding-top: $padding-percent;
850
851 #{$selector} {
852 position: absolute;
853 width: 100%;
854 height: 100%;
855 top: 0;
856
857 @content;
858 }
859 }
860
861 @mixin sub-menu-h1 {
862 ::ng-deep h1 {
863 font-size: 1.3rem;
864 border-bottom: 2px solid $grey-background-color;
865 padding-bottom: 15px;
866 margin-bottom: $sub-menu-margin-bottom;
867
868 > span > my-global-icon,
869 > my-global-icon {
870 @include margin-right(10px);
871 width: 24px;
872 height: 24px;
873 vertical-align: top;
874 }
875
876 .pt-badge {
877 @include margin-left(7px);
878
879 vertical-align: top;
880 }
881 }
882 }
883
884 @mixin play-icon ($width, $height) {
885 width: 0;
886 height: 0;
887
888 position: absolute;
889 left: 50%;
890 top: 50%;
891 transform: translate(-50%, -50%) scale(0.5);
892
893 border-top: #{math.div($height, 2)} solid transparent;
894 border-bottom: #{math.div($height, 2)} solid transparent;
895
896 border-left: $width solid rgba(255, 255, 255, 0.95);
897 }
898
899 @mixin on-small-main-col () {
900 :host-context(.main-col:not(.expanded)) {
901 @media screen and (max-width: $small-view + $menu-width) {
902 @content;
903 }
904 }
905
906 :host-context(.main-col.expanded) {
907 @media screen and (max-width: $small-view) {
908 @content;
909 }
910 }
911 }
912
913 @mixin on-mobile-main-col () {
914 :host-context(.main-col:not(.expanded)) {
915 @media screen and (max-width: $mobile-view + $menu-width) {
916 @content;
917 }
918 }
919
920 :host-context(.main-col.expanded) {
921 @media screen and (max-width: $mobile-view) {
922 @content;
923 }
924 }
925 }
926
927 @mixin margin ($arg1: null, $arg2: null, $arg3: null, $arg4: null) {
928 @if $arg2 == null and $arg3 == null and $arg4 == null {
929 @include margin-original($arg1, $arg1, $arg1, $arg1);
930 } @else if $arg3 == null and $arg4 == null {
931 @include margin-original($arg1, $arg2, $arg1, $arg2);
932 } @else if $arg4 == null {
933 @include margin-original($arg1, $arg2, $arg3, $arg2);
934 } @else {
935 @include margin-original($arg1, $arg2, $arg3, $arg4);
936 }
937 }
938
939 @mixin margin-original ($block-start, $inline-end, $block-end, $inline-start) {
940 @include margin-left($inline-start);
941 @include margin-right($inline-end);
942 @include margin-top($block-start);
943 @include margin-bottom($block-end);
944 }
945
946 @mixin margin-left ($value) {
947 @supports (margin-inline-start: $value) {
948 @include rfs($value, margin-inline-start);
949 }
950
951 @supports not (margin-inline-start: $value) {
952 @include rfs($value, margin-left);
953 }
954 }
955
956 @mixin margin-right ($value) {
957 @supports (margin-inline-end: $value) {
958 @include rfs($value, margin-inline-end);
959 }
960
961 @supports not (margin-inline-end: $value) {
962 @include rfs($value, margin-right);
963 }
964 }
965
966 @mixin padding-original ($block-start, $inline-end, $block-end, $inline-start) {
967 @include padding-left($inline-start);
968 @include padding-right($inline-end);
969 @include padding-top($block-start);
970 @include padding-bottom($block-end);
971 }
972
973
974 @mixin padding ($arg1: null, $arg2: null, $arg3: null, $arg4: null) {
975 @if $arg2 == null and $arg3 == null and $arg4 == null {
976 @include padding-original($arg1, $arg1, $arg1, $arg1);
977 } @else if $arg3 == null and $arg4 == null {
978 @include padding-original($arg1, $arg2, $arg1, $arg2);
979 } @else if $arg4 == null {
980 @include padding-original($arg1, $arg2, $arg3, $arg2);
981 } @else {
982 @include padding-original($arg1, $arg2, $arg3, $arg4);
983 }
984 }
985
986 @mixin padding-left ($value) {
987 @supports (padding-inline-start: $value) {
988 @include rfs($value, padding-inline-start);
989 }
990
991 @supports not (padding-inline-start: $value) {
992 @include rfs($value, padding-left);
993 }
994 }
995
996 @mixin padding-right ($value) {
997 @supports (padding-inline-end: $value) {
998 @include rfs($value, padding-inline-end);
999 }
1000
1001 @supports not (padding-inline-end: $value) {
1002 @include rfs($value, padding-right);
1003 }
1004 }