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