aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/shared/shared-main/buttons
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/shared/shared-main/buttons')
-rw-r--r--client/src/app/shared/shared-main/buttons/action-dropdown.component.html55
-rw-r--r--client/src/app/shared/shared-main/buttons/action-dropdown.component.scss72
-rw-r--r--client/src/app/shared/shared-main/buttons/action-dropdown.component.ts52
-rw-r--r--client/src/app/shared/shared-main/buttons/button.component.html6
-rw-r--r--client/src/app/shared/shared-main/buttons/button.component.scss46
-rw-r--r--client/src/app/shared/shared-main/buttons/button.component.ts20
-rw-r--r--client/src/app/shared/shared-main/buttons/delete-button.component.html6
-rw-r--r--client/src/app/shared/shared-main/buttons/delete-button.component.ts20
-rw-r--r--client/src/app/shared/shared-main/buttons/edit-button.component.html6
-rw-r--r--client/src/app/shared/shared-main/buttons/edit-button.component.ts12
-rw-r--r--client/src/app/shared/shared-main/buttons/index.ts4
11 files changed, 299 insertions, 0 deletions
diff --git a/client/src/app/shared/shared-main/buttons/action-dropdown.component.html b/client/src/app/shared/shared-main/buttons/action-dropdown.component.html
new file mode 100644
index 000000000..12933d4ca
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/action-dropdown.component.html
@@ -0,0 +1,55 @@
1<div class="dropdown-root" ngbDropdown [placement]="placement" [container]="container" *ngIf="areActionsDisplayed(actions, entry)">
2 <button
3 class="action-button" [ngClass]="{ small: buttonSize === 'small', grey: theme === 'grey', orange: theme === 'orange', 'button-styled': buttonStyled }"
4 ngbDropdownToggle role="button"
5 >
6 <my-global-icon *ngIf="!label && buttonDirection === 'horizontal'" class="more-icon" iconName="more-horizontal"></my-global-icon>
7 <my-global-icon *ngIf="!label && buttonDirection === 'vertical'" class="more-icon" iconName="more-vertical"></my-global-icon>
8
9 <span *ngIf="label" class="dropdown-toggle">{{ label }}</span>
10</button>
11
12 <div ngbDropdownMenu class="dropdown-menu">
13 <ng-container *ngFor="let actions of getActions()">
14
15 <ng-container *ngFor="let action of actions">
16 <ng-container *ngIf="action.isDisplayed === undefined || action.isDisplayed(entry) === true">
17
18 <ng-template #templateActionLabel let-action>
19 <my-global-icon *ngIf="action.iconName" [iconName]="action.iconName" [ngClass]="'icon-' + action.iconName" aria-hidden="true"></my-global-icon>
20
21 <div class="d-flex flex-column">
22 <span i18n>{{ action.label }}</span>
23 <small class="text-muted" *ngIf="action.description">{{ action.description }}</small>
24 </div>
25 </ng-template>
26
27 <a
28 *ngIf="action.linkBuilder && !action.isHeader" [ngClass]="{ 'with-icon': !!action.iconName }"
29 class="dropdown-item" [routerLink]="action.linkBuilder(entry)" [title]="action.title || ''"
30 >
31 <ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container>
32 </a>
33
34 <span
35 *ngIf="!action.linkBuilder && !action.isHeader" [ngClass]="{ 'with-icon': !!action.iconName }"
36 class="custom-action dropdown-item" tabindex="0" role="button" [title]="action.title || ''" (click)="action.handler(entry)" (keyup.enter)="action.handler(entry)"
37 >
38 <ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container>
39 </span>
40
41 <h6
42 *ngIf="!action.linkBuilder && action.isHeader" [ngClass]="{ 'with-icon': !!action.iconName }"
43 class="dropdown-header" tabindex="0" role="button" [title]="action.title || ''" (click)="action.handler(entry)" (keyup.enter)="action.handler(entry)"
44 >
45 <ng-container *ngTemplateOutlet="templateActionLabel; context:{ $implicit: action }"></ng-container>
46 </h6>
47
48 </ng-container>
49 </ng-container>
50
51 <div *ngIf="areActionsDisplayed(actions, entry)" class="dropdown-divider"></div>
52
53 </ng-container>
54 </div>
55</div>
diff --git a/client/src/app/shared/shared-main/buttons/action-dropdown.component.scss b/client/src/app/shared/shared-main/buttons/action-dropdown.component.scss
new file mode 100644
index 000000000..724a04efc
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/action-dropdown.component.scss
@@ -0,0 +1,72 @@
1@import '_variables';
2@import '_mixins';
3
4.dropdown-divider:last-child {
5 display: none;
6}
7
8.action-button {
9 @include peertube-button;
10
11 &.button-styled {
12
13 &.grey {
14 @include grey-button;
15 }
16
17 &.orange {
18 @include orange-button;
19 }
20
21 &:hover, &:active, &:focus {
22 background-color: $grey-background-color;
23 }
24 }
25
26 display: inline-block;
27 padding: 0 10px;
28
29 &::after {
30 display: none;
31 }
32
33 .more-icon {
34 width: 21px;
35
36 ::ng-deep {
37 @include apply-svg-color(pvar(--actionButtonColor));
38 }
39 }
40
41 &.small {
42 font-size: 14px;
43 height: 20px;
44 line-height: 20px;
45 }
46}
47
48.dropdown-toggle::after {
49 position: relative;
50 top: 1px;
51}
52
53.dropdown-menu {
54 .dropdown-header {
55 padding: 0.2rem 1rem;
56 }
57
58 .dropdown-item {
59 display: flex;
60 cursor: pointer;
61 color: #000 !important;
62
63 &.with-icon {
64 @include dropdown-with-icon-item;
65 }
66
67 a, span {
68 display: block;
69 width: 100%;
70 }
71 }
72}
diff --git a/client/src/app/shared/shared-main/buttons/action-dropdown.component.ts b/client/src/app/shared/shared-main/buttons/action-dropdown.component.ts
new file mode 100644
index 000000000..36d7d6229
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/action-dropdown.component.ts
@@ -0,0 +1,52 @@
1import { Component, Input } from '@angular/core'
2import { GlobalIconName } from '@app/shared/shared-icons'
3
4export type DropdownAction<T> = {
5 label?: string
6 iconName?: GlobalIconName
7 description?: string
8 title?: string
9 handler?: (a: T) => any
10 linkBuilder?: (a: T) => (string | number)[]
11 isDisplayed?: (a: T) => boolean
12 isHeader?: boolean
13}
14
15export type DropdownButtonSize = 'normal' | 'small'
16export type DropdownTheme = 'orange' | 'grey'
17export type DropdownDirection = 'horizontal' | 'vertical'
18
19@Component({
20 selector: 'my-action-dropdown',
21 styleUrls: [ './action-dropdown.component.scss' ],
22 templateUrl: './action-dropdown.component.html'
23})
24
25export class ActionDropdownComponent<T> {
26 @Input() actions: DropdownAction<T>[] | DropdownAction<T>[][] = []
27 @Input() entry: T
28
29 @Input() placement = 'bottom-left auto'
30 @Input() container: null | 'body'
31
32 @Input() buttonSize: DropdownButtonSize = 'normal'
33 @Input() buttonDirection: DropdownDirection = 'horizontal'
34 @Input() buttonStyled = true
35
36 @Input() label: string
37 @Input() theme: DropdownTheme = 'grey'
38
39 getActions (): DropdownAction<T>[][] {
40 if (this.actions.length !== 0 && Array.isArray(this.actions[0])) return this.actions as DropdownAction<T>[][]
41
42 return [ this.actions as DropdownAction<T>[] ]
43 }
44
45 areActionsDisplayed (actions: Array<DropdownAction<T> | DropdownAction<T>[]>, entry: T): boolean {
46 return actions.some(a => {
47 if (Array.isArray(a)) return this.areActionsDisplayed(a, entry)
48
49 return a.isDisplayed === undefined || a.isDisplayed(entry)
50 })
51 }
52}
diff --git a/client/src/app/shared/shared-main/buttons/button.component.html b/client/src/app/shared/shared-main/buttons/button.component.html
new file mode 100644
index 000000000..d2b0eb81a
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/button.component.html
@@ -0,0 +1,6 @@
1<span class="action-button" [ngClass]="className" [title]="getTitle()">
2 <my-global-icon *ngIf="!loading" [iconName]="icon"></my-global-icon>
3 <my-small-loader [loading]="loading"></my-small-loader>
4
5 <span class="button-label">{{ label }}</span>
6</span>
diff --git a/client/src/app/shared/shared-main/buttons/button.component.scss b/client/src/app/shared/shared-main/buttons/button.component.scss
new file mode 100644
index 000000000..3ccfefd7e
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/button.component.scss
@@ -0,0 +1,46 @@
1@import '_variables';
2@import '_mixins';
3
4my-small-loader ::ng-deep .root {
5 display: inline-block;
6 margin: 0 3px 0 0;
7 width: 20px;
8}
9
10.action-button {
11 @include peertube-button-link;
12 @include button-with-icon(21px, 0, -2px);
13}
14
15.orange-button {
16 @include peertube-button;
17 @include orange-button;
18}
19
20.orange-button-link {
21 @include peertube-button-link;
22 @include orange-button;
23}
24
25.grey-button {
26 @include peertube-button;
27 @include grey-button;
28}
29
30.grey-button-link {
31 @include peertube-button-link;
32 @include grey-button;
33}
34
35// In a table, try to minimize the space taken by this button
36@media screen and (max-width: 1400px) {
37 :host-context(td) {
38 .action-button {
39 padding: 0 13px;
40 }
41
42 .button-label {
43 display: none;
44 }
45 }
46}
diff --git a/client/src/app/shared/shared-main/buttons/button.component.ts b/client/src/app/shared/shared-main/buttons/button.component.ts
new file mode 100644
index 000000000..e23b90945
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/button.component.ts
@@ -0,0 +1,20 @@
1import { Component, Input } from '@angular/core'
2import { GlobalIconName } from '@app/shared/shared-icons'
3
4@Component({
5 selector: 'my-button',
6 styleUrls: ['./button.component.scss'],
7 templateUrl: './button.component.html'
8})
9
10export class ButtonComponent {
11 @Input() label = ''
12 @Input() className = 'grey-button'
13 @Input() icon: GlobalIconName = undefined
14 @Input() title: string = undefined
15 @Input() loading = false
16
17 getTitle () {
18 return this.title || this.label
19 }
20}
diff --git a/client/src/app/shared/shared-main/buttons/delete-button.component.html b/client/src/app/shared/shared-main/buttons/delete-button.component.html
new file mode 100644
index 000000000..398b6db1e
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/delete-button.component.html
@@ -0,0 +1,6 @@
1<span class="action-button action-button-delete grey-button" [title]="title" role="button">
2 <my-global-icon iconName="delete" aria-hidden="true"></my-global-icon>
3
4 <span class="button-label" *ngIf="label">{{ label }}</span>
5 <span class="button-label" i18n *ngIf="!label">Delete</span>
6</span>
diff --git a/client/src/app/shared/shared-main/buttons/delete-button.component.ts b/client/src/app/shared/shared-main/buttons/delete-button.component.ts
new file mode 100644
index 000000000..39e31900f
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/delete-button.component.ts
@@ -0,0 +1,20 @@
1import { Component, Input, OnInit } from '@angular/core'
2import { I18n } from '@ngx-translate/i18n-polyfill'
3
4@Component({
5 selector: 'my-delete-button',
6 styleUrls: [ './button.component.scss' ],
7 templateUrl: './delete-button.component.html'
8})
9
10export class DeleteButtonComponent implements OnInit {
11 @Input() label: string
12
13 title: string
14
15 constructor (private i18n: I18n) { }
16
17 ngOnInit () {
18 this.title = this.label || this.i18n('Delete')
19 }
20}
diff --git a/client/src/app/shared/shared-main/buttons/edit-button.component.html b/client/src/app/shared/shared-main/buttons/edit-button.component.html
new file mode 100644
index 000000000..b852bb38a
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/edit-button.component.html
@@ -0,0 +1,6 @@
1<a class="action-button action-button-edit grey-button" [routerLink]="routerLink" i18n-title title="Edit">
2 <my-global-icon iconName="edit" aria-hidden="true"></my-global-icon>
3
4 <span class="button-label" *ngIf="label">{{ label }}</span>
5 <span i18n class="button-label" *ngIf="!label">Edit</span>
6</a>
diff --git a/client/src/app/shared/shared-main/buttons/edit-button.component.ts b/client/src/app/shared/shared-main/buttons/edit-button.component.ts
new file mode 100644
index 000000000..9cfe1a3bb
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/edit-button.component.ts
@@ -0,0 +1,12 @@
1import { Component, Input } from '@angular/core'
2
3@Component({
4 selector: 'my-edit-button',
5 styleUrls: [ './button.component.scss' ],
6 templateUrl: './edit-button.component.html'
7})
8
9export class EditButtonComponent {
10 @Input() label: string
11 @Input() routerLink: string[] | string = []
12}
diff --git a/client/src/app/shared/shared-main/buttons/index.ts b/client/src/app/shared/shared-main/buttons/index.ts
new file mode 100644
index 000000000..775a47a39
--- /dev/null
+++ b/client/src/app/shared/shared-main/buttons/index.ts
@@ -0,0 +1,4 @@
1export * from './action-dropdown.component'
2export * from './button.component'
3export * from './delete-button.component'
4export * from './edit-button.component'