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