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