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