@factor_ec/ui 1.0.11 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/.browserslistrc +16 -0
  2. package/karma.conf.js +44 -0
  3. package/ng-package.json +7 -0
  4. package/package.json +3 -23
  5. package/src/lib/display/avatar/avatar.component.html +1 -0
  6. package/src/lib/display/avatar/avatar.component.scss +20 -0
  7. package/src/lib/display/avatar/avatar.component.spec.ts +23 -0
  8. package/src/lib/display/avatar/avatar.component.ts +69 -0
  9. package/src/lib/display/content/content.component.html +4 -0
  10. package/src/lib/display/content/content.component.scss +0 -0
  11. package/src/lib/display/content/content.component.spec.ts +23 -0
  12. package/src/lib/display/content/content.component.ts +15 -0
  13. package/src/lib/display/display.module.ts +41 -0
  14. package/src/lib/display/icon/icon.component.html +4 -0
  15. package/src/lib/display/icon/icon.component.scss +47 -0
  16. package/src/lib/display/icon/icon.component.spec.ts +23 -0
  17. package/src/lib/display/icon/icon.component.ts +88 -0
  18. package/src/lib/display/image/image.component.html +2 -0
  19. package/src/lib/display/image/image.component.scss +53 -0
  20. package/src/lib/display/image/image.component.spec.ts +23 -0
  21. package/src/lib/display/image/image.component.ts +71 -0
  22. package/src/lib/display/message/message.component.html +33 -0
  23. package/src/lib/display/message/message.component.scss +25 -0
  24. package/src/lib/display/message/message.component.spec.ts +23 -0
  25. package/src/lib/display/message/message.component.ts +24 -0
  26. package/src/lib/display/message.service.spec.ts +16 -0
  27. package/src/lib/display/message.service.ts +58 -0
  28. package/src/lib/display/observe-intersecting.directive.spec.ts +8 -0
  29. package/src/lib/display/observe-intersecting.directive.ts +34 -0
  30. package/src/lib/display/progress/progress.component.html +6 -0
  31. package/src/lib/display/progress/progress.component.scss +121 -0
  32. package/src/lib/display/progress/progress.component.spec.ts +23 -0
  33. package/src/lib/display/progress/progress.component.ts +36 -0
  34. package/src/lib/display/progress.service.spec.ts +16 -0
  35. package/src/lib/display/progress.service.ts +51 -0
  36. package/src/lib/inputs/inputs.module.ts +17 -0
  37. package/src/lib/inputs/rating/rating.component.html +13 -0
  38. package/src/lib/inputs/rating/rating.component.scss +61 -0
  39. package/src/lib/inputs/rating/rating.component.spec.ts +25 -0
  40. package/src/lib/inputs/rating/rating.component.ts +66 -0
  41. package/src/lib/models/action-group.ts +9 -0
  42. package/{lib/models/action.d.ts → src/lib/models/action.ts} +1 -1
  43. package/{lib/models/content.d.ts → src/lib/models/content.ts} +1 -1
  44. package/{lib/models/icon.d.ts → src/lib/models/icon.ts} +1 -1
  45. package/{lib/models/message-options.d.ts → src/lib/models/message-options.ts} +2 -1
  46. package/src/lib/models/module-configuration.ts +6 -0
  47. package/src/lib/models/ui-configuration.ts +7 -0
  48. package/src/lib/navigation/list/list.component.html +52 -0
  49. package/src/lib/navigation/list/list.component.scss +93 -0
  50. package/src/lib/navigation/list/list.component.spec.ts +23 -0
  51. package/src/lib/navigation/list/list.component.ts +56 -0
  52. package/src/lib/navigation/navbar/navbar.component.html +23 -0
  53. package/src/lib/navigation/navbar/navbar.component.scss +202 -0
  54. package/src/lib/navigation/navbar/navbar.component.spec.ts +23 -0
  55. package/src/lib/navigation/navbar/navbar.component.ts +57 -0
  56. package/src/lib/navigation/navigation.module.ts +34 -0
  57. package/src/lib/navigation/searchbox/searchbox.component.html +34 -0
  58. package/src/lib/navigation/searchbox/searchbox.component.scss +37 -0
  59. package/src/lib/navigation/searchbox/searchbox.component.spec.ts +23 -0
  60. package/src/lib/navigation/searchbox/searchbox.component.ts +94 -0
  61. package/src/lib/navigation/toolbar/toolbar.component.html +43 -0
  62. package/src/lib/navigation/toolbar/toolbar.component.scss +29 -0
  63. package/src/lib/navigation/toolbar/toolbar.component.spec.ts +23 -0
  64. package/src/lib/navigation/toolbar/toolbar.component.ts +43 -0
  65. package/src/lib/scss/breakpoints.scss +123 -0
  66. package/src/lib/scss/variables.scss +8 -0
  67. package/src/lib/ui.module.ts +34 -0
  68. package/{public-api.d.ts → src/public-api.ts} +4 -0
  69. package/src/test.ts +27 -0
  70. package/tsconfig.lib.json +15 -0
  71. package/tsconfig.lib.prod.json +10 -0
  72. package/tsconfig.spec.json +17 -0
  73. package/esm2020/factor_ec-ui.mjs +0 -5
  74. package/esm2020/lib/display/avatar/avatar.component.mjs +0 -74
  75. package/esm2020/lib/display/content/content.component.mjs +0 -19
  76. package/esm2020/lib/display/display.module.mjs +0 -66
  77. package/esm2020/lib/display/icon/icon.component.mjs +0 -97
  78. package/esm2020/lib/display/image/image.component.mjs +0 -80
  79. package/esm2020/lib/display/message/message.component.mjs +0 -30
  80. package/esm2020/lib/display/message.service.mjs +0 -58
  81. package/esm2020/lib/display/observe-intersecting.directive.mjs +0 -43
  82. package/esm2020/lib/display/progress/progress.component.mjs +0 -42
  83. package/esm2020/lib/display/progress.service.mjs +0 -50
  84. package/esm2020/lib/inputs/inputs.module.mjs +0 -24
  85. package/esm2020/lib/inputs/rating/rating.component.mjs +0 -73
  86. package/esm2020/lib/models/action.mjs +0 -2
  87. package/esm2020/lib/models/content.mjs +0 -2
  88. package/esm2020/lib/models/icon.mjs +0 -2
  89. package/esm2020/lib/models/message-options.mjs +0 -2
  90. package/esm2020/lib/models/module-configuration.mjs +0 -2
  91. package/esm2020/lib/models/ui-configuration.mjs +0 -2
  92. package/esm2020/lib/navigation/list/list.component.mjs +0 -69
  93. package/esm2020/lib/navigation/navbar/navbar.component.mjs +0 -74
  94. package/esm2020/lib/navigation/navigation.module.mjs +0 -55
  95. package/esm2020/lib/navigation/searchbox/searchbox.component.mjs +0 -109
  96. package/esm2020/lib/navigation/toolbar/toolbar.component.mjs +0 -53
  97. package/esm2020/lib/ui.module.mjs +0 -47
  98. package/esm2020/public-api.mjs +0 -22
  99. package/fesm2015/factor_ec-ui.mjs +0 -1000
  100. package/fesm2015/factor_ec-ui.mjs.map +0 -1
  101. package/fesm2020/factor_ec-ui.mjs +0 -992
  102. package/fesm2020/factor_ec-ui.mjs.map +0 -1
  103. package/index.d.ts +0 -5
  104. package/lib/display/avatar/avatar.component.d.ts +0 -22
  105. package/lib/display/content/content.component.d.ts +0 -7
  106. package/lib/display/display.module.d.ts +0 -17
  107. package/lib/display/icon/icon.component.d.ts +0 -24
  108. package/lib/display/image/image.component.d.ts +0 -15
  109. package/lib/display/message/message.component.d.ts +0 -11
  110. package/lib/display/message.service.d.ts +0 -15
  111. package/lib/display/observe-intersecting.directive.d.ts +0 -16
  112. package/lib/display/progress/progress.component.d.ts +0 -15
  113. package/lib/display/progress.service.d.ts +0 -15
  114. package/lib/inputs/inputs.module.d.ts +0 -8
  115. package/lib/inputs/rating/rating.component.d.ts +0 -23
  116. package/lib/models/module-configuration.d.ts +0 -6
  117. package/lib/models/ui-configuration.d.ts +0 -7
  118. package/lib/navigation/list/list.component.d.ts +0 -21
  119. package/lib/navigation/navbar/navbar.component.d.ts +0 -23
  120. package/lib/navigation/navigation.module.d.ts +0 -15
  121. package/lib/navigation/searchbox/searchbox.component.d.ts +0 -34
  122. package/lib/navigation/toolbar/toolbar.component.d.ts +0 -18
  123. package/lib/ui.module.d.ts +0 -13
@@ -0,0 +1,25 @@
1
+ .mat-dialog-title {
2
+ display: flex;
3
+ align-items: center;
4
+
5
+ ft-icon {
6
+ margin-right: 0.5rem;
7
+ }
8
+ }
9
+
10
+ .mat-dialog-content {
11
+ display: flex;
12
+ align-items: center;
13
+ margin-bottom: 0.5rem;
14
+
15
+ ft-icon {
16
+ margin-right: 0.5rem;
17
+ }
18
+ }
19
+
20
+ .mat-dialog-actions {
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: flex-end;
24
+ padding-bottom: 1.5rem;
25
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { MessageComponent } from './message.component';
4
+
5
+ describe('MessageComponent', () => {
6
+ let component: MessageComponent;
7
+ let fixture: ComponentFixture<MessageComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ MessageComponent ]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(MessageComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,24 @@
1
+ import { Component, EventEmitter, Inject, OnInit, Output } from '@angular/core';
2
+ import { MAT_DIALOG_DATA } from '@angular/material/dialog';
3
+
4
+ @Component({
5
+ selector: 'ft-message',
6
+ templateUrl: './message.component.html',
7
+ styleUrls: ['./message.component.scss']
8
+ })
9
+ export class MessageComponent implements OnInit {
10
+ @Output()
11
+ beforeSelect: EventEmitter<any> = new EventEmitter();
12
+
13
+ constructor(
14
+ @Inject(MAT_DIALOG_DATA) public data: any
15
+ ) { }
16
+
17
+ ngOnInit() {
18
+ }
19
+ select(value: string) {
20
+ this.beforeSelect.emit(value);
21
+ }
22
+
23
+
24
+ }
@@ -0,0 +1,16 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+
3
+ import { MessageService } from './message.service';
4
+
5
+ describe('MessageService', () => {
6
+ let service: MessageService;
7
+
8
+ beforeEach(() => {
9
+ TestBed.configureTestingModule({});
10
+ service = TestBed.inject(MessageService);
11
+ });
12
+
13
+ it('should be created', () => {
14
+ expect(service).toBeTruthy();
15
+ });
16
+ });
@@ -0,0 +1,58 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { ReplaySubject, Observable } from "rxjs";
3
+ import { MatSnackBar } from '@angular/material/snack-bar';
4
+ import { MatDialog } from '@angular/material/dialog';
5
+
6
+ import { MessageComponent } from './message/message.component';
7
+ import { Content } from '../models/content';
8
+ import { ContentComponent } from './content/content.component';
9
+ import { MessageOptions } from '../models/message-options';
10
+
11
+ @Injectable({
12
+ providedIn: 'root'
13
+ })
14
+ export class MessageService {
15
+ element: any;
16
+
17
+ constructor(
18
+ private snackBar: MatSnackBar,
19
+ private dialog: MatDialog
20
+ ) { }
21
+
22
+ show(message: string | Content, options?: MessageOptions): Observable<any> {
23
+ let selectionSource: ReplaySubject<string> = new ReplaySubject<string>(undefined);
24
+ let selection: Observable<string> = selectionSource.asObservable();
25
+ const defaults: MessageOptions = {
26
+ type: 'notification',
27
+ duration: 2000,
28
+ actionsVisible: true
29
+ };
30
+ options = Object.assign(defaults, options);
31
+ const data = { message: typeof message === 'string' ? { content: message, type: 'text' } : message, options };
32
+ switch (options.type) {
33
+ default:
34
+ case 'notification':
35
+ this.snackBar.openFromComponent(ContentComponent, {
36
+ data,
37
+ panelClass: ['ft-message', 'ft-message--notification'],
38
+ duration: options.duration || 2000,
39
+ });
40
+ break;
41
+ case 'modal':
42
+ const dialogRef = this.dialog.open(MessageComponent, {
43
+ width: options.width || '350px',
44
+ data,
45
+ panelClass: ['ft-message', 'ft-message--modal'],
46
+ autoFocus: false,
47
+ disableClose: true
48
+ });
49
+ dialogRef.componentInstance.beforeSelect.subscribe(response => {
50
+ selectionSource.next(response);
51
+ dialogRef.close();
52
+ });
53
+ this.snackBar.dismiss();
54
+ break;
55
+ }
56
+ return selection;
57
+ }
58
+ }
@@ -0,0 +1,8 @@
1
+ import { ObserveIntersectingDirective } from './observe-intersecting.directive';
2
+
3
+ describe('ObserveIntersectingDirective', () => {
4
+ it('should create an instance', () => {
5
+ const directive = new ObserveIntersectingDirective();
6
+ expect(directive).toBeTruthy();
7
+ });
8
+ });
@@ -0,0 +1,34 @@
1
+ import { Directive, EventEmitter, OnInit, Output, Input, ElementRef, Inject, PLATFORM_ID } from '@angular/core';
2
+ import { isPlatformBrowser } from '@angular/common';
3
+
4
+ declare var window: any;
5
+ @Directive({
6
+ selector: '[ftObserveIntersecting]'
7
+ })
8
+ export class ObserveIntersectingDirective implements OnInit {
9
+ @Input('ftObserveIntersectingOptions')
10
+ options!: { root: any, rootMargin: any, threshold: any };
11
+ @Output('ftObserveIntersecting')
12
+ event: EventEmitter<boolean> = new EventEmitter();
13
+
14
+ constructor(
15
+ private element: ElementRef,
16
+ @Inject(PLATFORM_ID) private platformId: Object
17
+ ) { }
18
+
19
+ ngOnInit() {
20
+ if (isPlatformBrowser(this.platformId)) {
21
+ if ("IntersectionObserver" in window) {
22
+ const elementObserver = new IntersectionObserver((entries, observer) => {
23
+ entries.forEach((entry) => {
24
+ this.event.emit(entry.isIntersecting);
25
+ });
26
+ }, this.options);
27
+ elementObserver.observe(this.element.nativeElement);
28
+ } else {
29
+ console.error('ftObserveIntersecting not available in this browser.');
30
+ }
31
+ }
32
+ }
33
+
34
+ }
@@ -0,0 +1,6 @@
1
+ <svg [ngStyle]="{'--bar-color': color}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid">
2
+ <circle class="track" cx="50" cy="50" r="40" />
3
+ <circle class="bar" [ngClass]="mode" cx="50" cy="50" r="40"
4
+ [ngStyle]="{'stroke-dashoffset': mode=='determinate'? 'calc((3.14159265 * 40 * 2 * (100 - '+value+')) / 100)' : null}">
5
+ </circle>
6
+ </svg>
@@ -0,0 +1,121 @@
1
+ :host {
2
+ --track-color: rgba(0, 0, 0, 0.08);
3
+ --bar-color: var(--primary);
4
+ line-height: 0;
5
+ display: inline-block;
6
+
7
+ &.ft-progress--1 {
8
+ font-size: 1rem;
9
+ }
10
+
11
+ &.ft-progress--2 {
12
+ font-size: 1.5rem;
13
+ }
14
+
15
+ &.ft-progress--3 {
16
+ font-size: 2rem;
17
+ }
18
+
19
+ &.ft-progress--4 {
20
+ font-size: 3rem;
21
+ }
22
+
23
+ &.ft-progress--5 {
24
+ font-size: 4.5rem;
25
+ }
26
+
27
+ &.ft-progress--6 {
28
+ font-size: 8rem;
29
+ }
30
+
31
+ &.ft-progress--7 {
32
+ font-size: 16rem;
33
+ }
34
+
35
+ &.ft-progress--8 {
36
+ font-size: 32rem;
37
+ }
38
+
39
+ &.ft-progress--overlay {
40
+ position: fixed;
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ pointer-events: none;
45
+ z-index: var(--z-index-modal, 1000);
46
+ top: 0;
47
+ left: 0;
48
+ right: 0;
49
+ bottom: 0;
50
+ font-size: 42px;
51
+
52
+ svg {
53
+ background: rgba(255, 255, 255, 0.6);
54
+ backdrop-filter: saturate(50%) blur(3px);
55
+ box-shadow: 0 3px 3px -2px rgba(0, 0, 0, 0.2), 0 3px 4px 0 rgba(0, 0, 0, 0.14), 0 1px 8px 0 rgba(0, 0, 0, 0.12);
56
+ border-radius: 100vh;
57
+ padding: 0.3125rem;
58
+ animation: progress-reveal 0.2s;
59
+ animation-fill-mode: forwards;
60
+
61
+ .track {
62
+ display: none;
63
+ }
64
+ }
65
+ }
66
+ }
67
+
68
+ svg {
69
+ width: 1em;
70
+ height: 1em;
71
+ vertical-align: middle;
72
+
73
+ .track {
74
+ fill: none;
75
+ stroke-width: 10;
76
+ stroke: var(--track-color);
77
+ }
78
+
79
+ .bar {
80
+ fill: none;
81
+ stroke-opacity: 0.9;
82
+ stroke-width: 6;
83
+ stroke: var(--bar-color);
84
+
85
+ &.indeterminate {
86
+ animation: progress-rotation 2s infinite linear;
87
+ }
88
+
89
+ &.determinate {
90
+ stroke-dasharray: calc(2 * 3.1415926536 * 40);
91
+ }
92
+ }
93
+ }
94
+
95
+ @keyframes progress-reveal {
96
+ 0% {
97
+ transform: translateY(-100%);
98
+ opacity: 0;
99
+ }
100
+
101
+ 100% {
102
+ transform: translateY(0);
103
+ opacity: 1;
104
+ }
105
+ }
106
+
107
+ @keyframes progress-rotation {
108
+ 0% {
109
+ stroke-dashoffset: 0;
110
+ stroke-dasharray: 150.6 100.4;
111
+ }
112
+
113
+ 50% {
114
+ stroke-dasharray: 1 250;
115
+ }
116
+
117
+ 100% {
118
+ stroke-dashoffset: 502;
119
+ stroke-dasharray: 150.6 100.4;
120
+ }
121
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ProgressComponent } from './progress.component';
4
+
5
+ describe('ProgressComponent', () => {
6
+ let component: ProgressComponent;
7
+ let fixture: ComponentFixture<ProgressComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ ProgressComponent ]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(ProgressComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,36 @@
1
+ import { Component, OnInit, Input, HostBinding } from '@angular/core';
2
+
3
+ @Component({
4
+ selector: 'ft-progress',
5
+ templateUrl: './progress.component.html',
6
+ styleUrls: ['./progress.component.scss']
7
+ })
8
+ export class ProgressComponent implements OnInit {
9
+ @Input()
10
+ class: string = '';
11
+ @Input()
12
+ color!: string;
13
+ @Input()
14
+ mode: 'determinate' | 'indeterminate' = 'indeterminate';
15
+ @Input()
16
+ overlay: boolean = false;
17
+ @Input()
18
+ size!: number;
19
+ @Input()
20
+ value!: number;
21
+
22
+ constructor() { }
23
+
24
+ ngOnInit() {
25
+ this.value = 0;
26
+ }
27
+ @HostBinding('class')
28
+ get hostClasses(): string {
29
+ return [
30
+ 'ft-progress',
31
+ this.overlay ? 'ft-progress--overlay' : '',
32
+ this.class
33
+ ].join(' ');
34
+ }
35
+
36
+ }
@@ -0,0 +1,16 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+
3
+ import { ProgressService } from './progress.service';
4
+
5
+ describe('ProgressService', () => {
6
+ let service: ProgressService;
7
+
8
+ beforeEach(() => {
9
+ TestBed.configureTestingModule({});
10
+ service = TestBed.inject(ProgressService);
11
+ });
12
+
13
+ it('should be created', () => {
14
+ expect(service).toBeTruthy();
15
+ });
16
+ });
@@ -0,0 +1,51 @@
1
+ import { ComponentFactoryResolver, EmbeddedViewRef, Injector, Injectable, ComponentRef, ApplicationRef } from '@angular/core';
2
+
3
+ import { ProgressComponent } from './progress/progress.component';
4
+
5
+ @Injectable({
6
+ providedIn: 'root'
7
+ })
8
+ export class ProgressService {
9
+ appRef!: ApplicationRef;
10
+ componentRef!: ComponentRef<ProgressComponent> | null;
11
+ domElem!: HTMLElement;
12
+
13
+ constructor(
14
+ private componentFactoryResolver: ComponentFactoryResolver,
15
+ private injector: Injector
16
+ ) { }
17
+
18
+ show(): boolean {
19
+ if (!this.componentRef) {
20
+ this.appRef = this.injector.get(ApplicationRef);
21
+ // 1. Create a component reference from the component
22
+ this.componentRef = this.componentFactoryResolver
23
+ .resolveComponentFactory(ProgressComponent)
24
+ .create(this.injector);
25
+
26
+ // 2. Attach component to the appRef so that it's inside the ng component tree
27
+ this.appRef.attachView(this.componentRef.hostView);
28
+ this.componentRef.instance.overlay = true;
29
+
30
+ // 3. Get DOM element from component
31
+ const domElem = (this.componentRef.hostView as EmbeddedViewRef<any>)
32
+ .rootNodes[0] as HTMLElement;
33
+
34
+ // 4. Append DOM element to the body
35
+ document.body.appendChild(domElem);
36
+ return true;
37
+ } else {
38
+ return false;
39
+ }
40
+ }
41
+ hide(): boolean {
42
+ if (this.componentRef) {
43
+ this.appRef.detachView(this.componentRef.hostView);
44
+ this.componentRef.destroy();
45
+ this.componentRef = null;
46
+ return true;
47
+ } else {
48
+ return false;
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,17 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+
4
+ import { RatingComponent } from './rating/rating.component';
5
+
6
+ @NgModule({
7
+ declarations: [
8
+ RatingComponent
9
+ ],
10
+ exports: [
11
+ RatingComponent
12
+ ],
13
+ imports: [
14
+ CommonModule
15
+ ]
16
+ })
17
+ export class InputsModule { }
@@ -0,0 +1,13 @@
1
+ <ng-container *ngFor="let star of stars">
2
+ <ng-container *ngTemplateOutlet="!readOnly? buttonTemplate : starTemplate; context:{star:star}"></ng-container>
3
+ </ng-container>
4
+ <ng-template #buttonTemplate let-star="star">
5
+ <button type="button" *ngIf="!readOnly; else starTemplate" [disabled]="disabled" (mouseover)="setRate(star.value, true)" (focus)="setRate(star.value, true)" (blur)="setRate(0, true)" (mouseout)="setRate(0, true)" (click)="setRate(star.value)">
6
+ <ng-container *ngTemplateOutlet="starTemplate; context:{star:star}"></ng-container>
7
+ </button>
8
+ </ng-template>
9
+ <ng-template #starTemplate let-star="star">
10
+ <svg [ngClass]="{hover: hoverValue >= star.value, active: value >= star.value}" viewBox="0 0 24 24">
11
+ <path d="M17.93 21.315c-.534.408-5.22-3.186-5.881-3.181-.663 0-5.307 3.656-5.846 3.254-.537-.403 1.29-6.165 1.081-6.822-.209-.656-4.972-4.138-4.772-4.796.201-.658 6.015-.627 6.55-1.036.533-.41 2.233-6.215 2.895-6.219.663 0 2.43 5.779 2.968 6.182.539.403 6.352.297 6.56.953.21.656-4.513 4.197-4.714 4.856-.2.658 1.692 6.398 1.159 6.808z" />
12
+ </svg>
13
+ </ng-template>
@@ -0,0 +1,61 @@
1
+ :host {
2
+ line-height: 0;
3
+ display: inline-flex;
4
+ &:hover {
5
+ button {
6
+ color: var(--primary);
7
+ & svg:not(.hover) {
8
+ color: var(--gray);
9
+ }
10
+ }
11
+ }
12
+ &[size="1"] {
13
+ font-size: 1rem;
14
+ }
15
+ &[size="2"] {
16
+ font-size: 1.5rem;
17
+ }
18
+ &[size="3"] {
19
+ font-size: 2rem;
20
+ }
21
+ &[size="4"] {
22
+ font-size: 3rem;
23
+ }
24
+ &[size="5"] {
25
+ font-size: 4.5rem;
26
+ }
27
+ &[size="6"] {
28
+ font-size: 8rem;
29
+ }
30
+ &[size="7"] {
31
+ font-size: 16rem;
32
+ }
33
+ &[size="8"] {
34
+ font-size: 32rem;
35
+ }
36
+ }
37
+ svg {
38
+ width: 1em;
39
+ height: 1em;
40
+ display: block;
41
+ path {
42
+ fill: none;
43
+ stroke-width: 1;
44
+ stroke: currentColor;
45
+ }
46
+ &.hover,
47
+ &.active {
48
+ path {
49
+ fill: currentColor;
50
+ }
51
+ }
52
+ }
53
+ button {
54
+ border: 0;
55
+ background: transparent;
56
+ padding: 0;
57
+ &:focus,
58
+ &:active {
59
+ outline: none;
60
+ }
61
+ }
@@ -0,0 +1,25 @@
1
+ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2
+
3
+ import { RatingComponent } from './rating.component';
4
+
5
+ describe('RatingComponent', () => {
6
+ let component: RatingComponent;
7
+ let fixture: ComponentFixture<RatingComponent>;
8
+
9
+ beforeEach(waitForAsync(() => {
10
+ TestBed.configureTestingModule({
11
+ declarations: [ RatingComponent ]
12
+ })
13
+ .compileComponents();
14
+ }));
15
+
16
+ beforeEach(() => {
17
+ fixture = TestBed.createComponent(RatingComponent);
18
+ component = fixture.componentInstance;
19
+ fixture.detectChanges();
20
+ });
21
+
22
+ it('should create', () => {
23
+ expect(component).toBeTruthy();
24
+ });
25
+ });
@@ -0,0 +1,66 @@
1
+ import { Component, OnInit, forwardRef, Input } from '@angular/core';
2
+ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
3
+
4
+ @Component({
5
+ selector: 'ft-rating',
6
+ templateUrl: './rating.component.html',
7
+ styleUrls: ['./rating.component.scss'],
8
+ providers: [
9
+ {
10
+ provide: NG_VALUE_ACCESSOR,
11
+ useExisting: forwardRef(() => RatingComponent),
12
+ multi: true
13
+ }
14
+ ]
15
+ })
16
+ export class RatingComponent implements OnInit, ControlValueAccessor {
17
+ disabled: boolean = false;
18
+ hoverValue!: number;
19
+ propagateChange = (_: any) => { };
20
+ @Input()
21
+ readOnly: boolean = false;
22
+ stars: any[] = [
23
+ { value: 1 },
24
+ { value: 2 },
25
+ { value: 3 },
26
+ { value: 4 },
27
+ { value: 5 }
28
+ ];
29
+ _value!: number;
30
+
31
+ constructor() { }
32
+
33
+ ngOnInit() {
34
+ }
35
+ get value() {
36
+ return this._value;
37
+ }
38
+ @Input()
39
+ set value(value: any) {
40
+ this._value = value;
41
+ this.propagateChange(this._value);
42
+ }
43
+ registerOnChange(fn: (_: any) => void) {
44
+ this.propagateChange = fn;
45
+ }
46
+ registerOnTouched(fn: (_: any) => void) {
47
+ //this.propagateChange = fn;
48
+ }
49
+ setDisabledState(isDisabled: boolean): void {
50
+ this.disabled = isDisabled;
51
+ }
52
+ setRate(value: number, isHover?: boolean) {
53
+ if (isHover) {
54
+ this.hoverValue = value;
55
+ } else {
56
+ this.value = value;
57
+ }
58
+ }
59
+ updateValue(event: any) {
60
+ this.value = event.target.value;
61
+ }
62
+ writeValue(value: string) {
63
+ this.value = value;
64
+ }
65
+
66
+ }
@@ -0,0 +1,9 @@
1
+ import { Action } from './action';
2
+
3
+ export interface ActionGroup {
4
+ children?: Action[];
5
+ iconNameField?: string;
6
+ iconCollection?: string;
7
+ labelField?: string;
8
+ type?: string;
9
+ }
@@ -12,4 +12,4 @@ export interface Action {
12
12
  metadata?: any;
13
13
  value?: any;
14
14
  color?: string;
15
- }
15
+ }
@@ -1,4 +1,4 @@
1
1
  export interface Content {
2
2
  content: string;
3
3
  type: 'text' | 'html';
4
- }
4
+ }
@@ -3,4 +3,4 @@ export interface Icon {
3
3
  collection?: string;
4
4
  class?: string;
5
5
  size?: number;
6
- }
6
+ }
@@ -1,5 +1,6 @@
1
1
  import { Action } from "./action";
2
2
  import { Icon } from "./icon";
3
+
3
4
  export interface MessageOptions {
4
5
  type?: 'modal' | 'notification';
5
6
  actions?: Action[];
@@ -10,4 +11,4 @@ export interface MessageOptions {
10
11
  titleIcon?: Icon;
11
12
  icon?: Icon;
12
13
  width?: string;
13
- }
14
+ }