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