@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,6 @@
1
+ export interface ModuleConfiguration {
2
+ icon?: {
3
+ path?: string,
4
+ collection?: string
5
+ }
6
+ }
@@ -0,0 +1,7 @@
1
+ export interface UiConfiguration {
2
+ icon: {
3
+ mode: 'external' | null,
4
+ collection: string,
5
+ path: string
6
+ }
7
+ }
@@ -0,0 +1,52 @@
1
+ <ng-container *ngTemplateOutlet="switch; context: { children: items }"></ng-container>
2
+ <ng-template #switch let-children="children" let-level="level">
3
+ <ng-container *ngFor="let item of children" [ngSwitch]="item.type">
4
+ <ng-container *ngSwitchCase="'collapsible'">
5
+ <ng-container *ngTemplateOutlet="collapsible; context: { item: item }"></ng-container>
6
+ </ng-container>
7
+ <ng-container *ngSwitchCase="'header'">
8
+ <ng-container *ngTemplateOutlet="header; context: { item: item }"></ng-container>
9
+ </ng-container>
10
+ <ng-container *ngSwitchDefault>
11
+ <ng-container *ngTemplateOutlet="action; context: { item: item }"></ng-container>
12
+ </ng-container>
13
+ </ng-container>
14
+ </ng-template>
15
+ <ng-template #action let-item="item">
16
+ <ng-container [ngSwitch]="getComponentType(item)">
17
+ <button *ngSwitchCase="'button'" type="button" matRipple class="ft-list__item" [ngClass]="item.class"
18
+ (click)="setItem(item)">
19
+ <ng-container *ngTemplateOutlet="text; context: { item: item }"></ng-container>
20
+ </button>
21
+ <a *ngSwitchCase="'link'" [routerLink]="item.url" routerLinkActive="ft-active" matRipple class="ft-list__item"
22
+ [ngClass]="item.class" (click)="setItem(item)">
23
+ <ng-container *ngTemplateOutlet="text; context: { item: item }"></ng-container>
24
+ </a>
25
+ </ng-container>
26
+ </ng-template>
27
+ <ng-template #collapsible let-item="item">
28
+ <button type="button" matRipple class="ft-collapsible-header ft-list__item"
29
+ [ngClass]="{ 'ft-show': item.metadata?.show }" (click)="toggleCollapsible(item)">
30
+ <div>
31
+ <ft-icon class="ft-item__icon" *ngIf="item[iconNameField]" [name]="item[iconNameField]"
32
+ [collection]="iconCollection" [path]="iconPath"></ft-icon>
33
+ <div class="ft-item__label">{{ item[labelField] }}</div>
34
+ <ft-icon class="ft-item__toggle" name="angle-right" size="1"></ft-icon>
35
+ </div>
36
+ </button>
37
+ <div class="ft-collapsible" [ngClass]="{ 'ft-show': item.metadata?.show }" *ngIf="item.children">
38
+ <ng-container *ngTemplateOutlet="switch; context: { children: item.children }"></ng-container>
39
+ </div>
40
+ </ng-template>
41
+ <ng-template #header let-item="item">
42
+ <div class="header" [ngClass]="item.class">
43
+ {{ item[labelField] }}
44
+ </div>
45
+ </ng-template>
46
+ <ng-template #text let-item="item">
47
+ <div class="d-flex align-items-center">
48
+ <ft-icon class="item__icon" *ngIf="item[iconNameField]" [name]="item[iconNameField]" [collection]="iconCollection"
49
+ [path]="iconPath"></ft-icon>
50
+ <div class="item__label">{{ item[labelField] }}</div>
51
+ </div>
52
+ </ng-template>
@@ -0,0 +1,93 @@
1
+ :host {
2
+ --ft-background-color: var(--ft-background-color, #f8f9fa);
3
+ --ft-background-color-hover: rgba(0, 0, 0, 0.03);
4
+ --ft-background-color-active: rgba(var(--ft-primary-color-rgb), 0.1);
5
+ --ft-text-color: #333;
6
+ --ft-text-color-hover: var(--ft-primary-color);
7
+ --ft-text-color-active: var(--ft-primary-color);
8
+ display: block;
9
+ overflow: auto;
10
+ }
11
+ .ft-list {
12
+ &__item {
13
+ border: 0;
14
+ box-sizing: border-box;
15
+ color: var(--text-color);
16
+ background-color: var(--ft-background-color);
17
+ cursor: pointer;
18
+ display: flex;
19
+ outline: none;
20
+ transition: background-color 0.3s, color 0.3s;
21
+ text-align: left;
22
+ padding: 0.75rem 1.5rem;
23
+ width: 100%;
24
+ &:hover {
25
+ text-decoration: none;
26
+ &:not(.active) {
27
+ --ft-background-color: var(--ft-background-color-hover);
28
+ --text-color: var(--text-color-hover);
29
+ }
30
+ }
31
+ &.ft-active,
32
+ &:active {
33
+ --ft-background-color: var(--ft-background-color-active);
34
+ --text-color: var(--text-color-active);
35
+ }
36
+ > div {
37
+ max-width: 100%;
38
+ }
39
+ .ft-item {
40
+ &__icon {
41
+ font-size: 1.5rem;
42
+ }
43
+ &__icon + .ft-item__label {
44
+ display: block;
45
+ margin-left: 0.5rem;
46
+ white-space: nowrap;
47
+ overflow: hidden;
48
+ text-overflow: ellipsis;
49
+ }
50
+ &__icon,
51
+ &__label {
52
+ transition: margin-left 0.3s;
53
+ }
54
+ &__toggle {
55
+ transition: transform 0.2s;
56
+ }
57
+ &__label {
58
+ flex-grow: 1;
59
+ }
60
+ }
61
+ }
62
+ }
63
+ .ft-collapsible {
64
+ overflow: hidden;
65
+ transition: max-height 0.2s;
66
+ max-height: 100vh;
67
+ background-color: rgba(0, 0, 0, 0.01);
68
+ box-shadow: inset 0 4px 9px -7px rgba(0, 0, 0, 0.4);
69
+ &-header {
70
+ font-weight: 500;
71
+ > div {
72
+ display: flex;
73
+ align-items: center;
74
+ flex-grow: 1;
75
+ }
76
+ &.ft-show {
77
+ .ft-item__toggle {
78
+ transform: rotate(90deg);
79
+ }
80
+ }
81
+ }
82
+ &:not(.ft-show) {
83
+ max-height: 0;
84
+ background-color: transparent;
85
+ }
86
+ }
87
+ .ft-header {
88
+ text-transform: uppercase;
89
+ font-weight: 700;
90
+ padding: 0.75rem 1.5rem 0.25rem;
91
+ font-size: 0.75rem;
92
+ opacity: 0.3;
93
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { ListComponent } from './list.component';
4
+
5
+ describe('ListComponent', () => {
6
+ let component: ListComponent;
7
+ let fixture: ComponentFixture<ListComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ ListComponent ]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(ListComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,56 @@
1
+ import { Component, EventEmitter, Output, Input, HostBinding } from '@angular/core';
2
+ import { Router } from '@angular/router';
3
+
4
+ import { Action } from '../../models/action';
5
+
6
+ @Component({
7
+ selector: 'ft-list',
8
+ templateUrl: './list.component.html',
9
+ styleUrls: ['./list.component.scss']
10
+ })
11
+ export class ListComponent {
12
+ @Output() change = new EventEmitter<Action>();
13
+ @Input() iconCollection!: string;
14
+ @Input() iconNameField: string = 'iconName';
15
+ @Input() iconPath!: string;
16
+ @Input() labelField: string = 'label';
17
+ @Input() items!: Action[];
18
+
19
+ @Input() class: string = '';
20
+ @HostBinding('class') get hostClasses(): string {
21
+ return [
22
+ 'ft-list',
23
+ this.class
24
+ ].join(' ');
25
+ };
26
+
27
+ constructor(
28
+ private router: Router
29
+ ) { }
30
+
31
+ getComponentType(item: Action): string {
32
+ let type: string = 'text';
33
+ if (!item.url || item.url.match(/^(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/)) {
34
+ type = 'button';
35
+ } else {
36
+ type = 'link';
37
+ }
38
+ return type;
39
+ }
40
+ setItem(item: Action): void {
41
+ if (item.url) {
42
+ if (item.url.match(/^(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/)) {
43
+ window.location.href = item.url;
44
+ }
45
+ } else if (item.click) {
46
+ item.click();
47
+ }
48
+ }
49
+ toggleCollapsible(action: Action): void {
50
+ action.metadata = action.metadata || {};
51
+ action.metadata.show = !action.metadata?.show;
52
+ this.change.emit(action);
53
+ }
54
+
55
+ }
56
+
@@ -0,0 +1,23 @@
1
+ <ng-content select="[ftStart]"></ng-content>
2
+ <div class="list" *ngIf="items">
3
+ <ng-container *ngFor="let item of items; trackBy: trackByItem">
4
+ <ng-container *ngTemplateOutlet="actionTemplate; context: { item: item }"></ng-container>
5
+ </ng-container>
6
+ </div>
7
+ <ng-content select="[ftEnd]"></ng-content>
8
+ <ng-template #actionTemplate let-item="item">
9
+ <ng-container [ngSwitch]="getComponentType(item)">
10
+ <button *ngSwitchCase="'button'" type="button" matRipple class="list__item" [ngClass]="[labelPlacement, item.class || '' ]" (click)="setItem(item)">
11
+ <ng-container *ngTemplateOutlet="textTemplate; context: { item: item }"></ng-container>
12
+ </button>
13
+ <a *ngSwitchCase="'link'" [routerLink]="item.url" routerLinkActive="active" matRipple class="list__item" [ngClass]="[labelPlacement, item.class || '' ]" (click)="setItem(item)">
14
+ <ng-container *ngTemplateOutlet="textTemplate; context: { item: item }"></ng-container>
15
+ </a>
16
+ </ng-container>
17
+ </ng-template>
18
+ <ng-template #textTemplate let-item="item">
19
+ <div class="item">
20
+ <ft-icon class="item__icon" *ngIf="item[iconNameField]" [name]="item[iconNameField]" [collection]="iconCollection" [title]="labelPlacement === 'none' ? item[labelField] : '' "></ft-icon>
21
+ <div class="item__label" *ngIf="labelPlacement !== 'none'">{{ item[labelField] }}</div>
22
+ </div>
23
+ </ng-template>
@@ -0,0 +1,202 @@
1
+ @import '../../scss/variables';
2
+ @import '../../scss/breakpoints';
3
+
4
+ :host {
5
+ --min-width: 4rem;
6
+ --min-height: 3.5rem;
7
+ --background-color: #FFF;
8
+ --background-color-hover: rgba(0, 0, 0, .10);
9
+ --background-color-active: rgba(0, 0, 0, .10);
10
+ --text-color: #333;
11
+ --text-color-hover: #333;
12
+ --text-color-active: #FFF;
13
+ background-color: var(--background-color);
14
+ position: fixed;
15
+ transition: transform 0.3s ease-in-out, width 0.3s, color 0.3s, background-color 0.3s;
16
+ z-index: var(--z-index, 990);
17
+ font-size: 0.875rem;
18
+ display: flex;
19
+
20
+ @include media-breakpoint-up(sm) {
21
+ --min-width: 13.75rem;
22
+ }
23
+
24
+ &.left,
25
+ &.right {
26
+ top: 0;
27
+ bottom: 0;
28
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .14), 0 1px 3px 0 rgba(0, 0, 0, .12);
29
+ min-width: var(--min-width);
30
+ }
31
+
32
+ &.left {
33
+ left: 0;
34
+ }
35
+
36
+ &.right {
37
+ right: 0;
38
+ }
39
+
40
+ &.bottom,
41
+ &.top {
42
+ left: 0;
43
+ right: 0;
44
+ min-height: var(--min-height);
45
+
46
+ .list {
47
+ display: flex;
48
+
49
+ &__item {
50
+ flex-grow: 1;
51
+ justify-content: center;
52
+ }
53
+ }
54
+ }
55
+
56
+ &.bottom {
57
+ bottom: 0;
58
+ box-shadow: 0 0 1px 0 rgba(0, 0, 0, .14), 0 -1px 3px 0 rgba(0, 0, 0, .12);
59
+ }
60
+
61
+ &.top {
62
+ top: 0;
63
+ box-shadow: 0 0 1px 0 rgba(0, 0, 0, .14), 0 1px 3px 0 rgba(0, 0, 0, .12);
64
+ }
65
+
66
+ &.auto {
67
+ @include media-breakpoint-up(md) {
68
+ left: 0;
69
+ top: 0;
70
+ bottom: 0;
71
+ box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .14), 0 1px 3px 0 rgba(0, 0, 0, .12);
72
+ min-width: var(--min-width);
73
+ flex-direction: column;
74
+ }
75
+
76
+ @include media-breakpoint-down(sm) {
77
+ bottom: 0;
78
+ left: 0;
79
+ right: 0;
80
+ box-shadow: 0 0 1px 0 rgba(0, 0, 0, .14), 0 -1px 3px 0 rgba(0, 0, 0, .12);
81
+ min-height: var(--min-height);
82
+
83
+ .list {
84
+ display: flex;
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ .list {
91
+ display: block;
92
+ flex-grow: 1;
93
+ overflow: auto;
94
+
95
+ &__item {
96
+ border: 0;
97
+ box-sizing: border-box;
98
+ color: var(--text-color);
99
+ cursor: pointer;
100
+ outline: none;
101
+ transition: background-color 0.3s, color 0.3s;
102
+ display: flex;
103
+ align-items: center;
104
+ padding: 0.75rem 1rem;
105
+ width: 100%;
106
+
107
+ &:hover {
108
+ text-decoration: none;
109
+
110
+ &:not(.active) {
111
+ background: var(--hover-background-color);
112
+ color: var(--hover-text-color);
113
+ }
114
+ }
115
+
116
+ &.active {
117
+ background: var(--active-background-color);
118
+ color: var(--active-text-color);
119
+ }
120
+
121
+ &.left {
122
+ justify-content: flex-start;
123
+
124
+ .item {
125
+ &__icon {
126
+ margin-right: 0.5rem;
127
+ }
128
+ }
129
+ }
130
+
131
+ &.right {
132
+ justify-content: flex-end;
133
+
134
+ .item {
135
+ flex-direction: row-reverse;
136
+
137
+ &__icon {
138
+ margin-left: 0.5rem;
139
+ }
140
+ }
141
+ }
142
+
143
+ &.top {
144
+ justify-content: center;
145
+ flex-grow: 1;
146
+ padding: .5rem;
147
+
148
+ .item {
149
+ flex-direction: column-reverse;
150
+ }
151
+ }
152
+
153
+ &.bottom {
154
+ justify-content: center;
155
+ flex-grow: 1;
156
+ padding: .5rem;
157
+
158
+ .item {
159
+ flex-direction: column;
160
+ }
161
+ }
162
+
163
+ &.auto {
164
+ @include media-breakpoint-up(md) {
165
+ .item {
166
+ flex-direction: row;
167
+
168
+ &__icon {
169
+ margin-right: 0.5rem;
170
+ }
171
+ }
172
+ }
173
+
174
+ @include media-breakpoint-down(sm) {
175
+ justify-content: center;
176
+ flex-grow: 1;
177
+ padding: .5rem;
178
+
179
+ .item {
180
+ flex-direction: column;
181
+ font-size: 0.6875rem;
182
+ }
183
+ }
184
+ }
185
+
186
+ .item {
187
+ display: flex;
188
+ align-items: center;
189
+
190
+ &__icon {
191
+ font-size: 1.5rem;
192
+ }
193
+
194
+ &__label {
195
+ display: block;
196
+ white-space: nowrap;
197
+ overflow: hidden;
198
+ text-overflow: ellipsis;
199
+ }
200
+ }
201
+ }
202
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { NavbarComponent } from './navbar.component';
4
+
5
+ describe('NavbarComponent', () => {
6
+ let component: NavbarComponent;
7
+ let fixture: ComponentFixture<NavbarComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ NavbarComponent ]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(NavbarComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,57 @@
1
+ import { Component, OnInit, Input, HostBinding } from '@angular/core';
2
+ import { Router } from '@angular/router';
3
+ import { Action } from '../../models/action';
4
+
5
+ @Component({
6
+ selector: 'ft-navbar',
7
+ templateUrl: './navbar.component.html',
8
+ styleUrls: ['./navbar.component.scss']
9
+ })
10
+ export class NavbarComponent implements OnInit {
11
+ @Input() iconCollection!: string;
12
+ @Input() iconNameField: string = 'iconName';
13
+ @Input() labelField: string = 'label';
14
+ @Input() labelPlacement: 'top' | 'right' | 'bottom' | 'left' | 'auto' | 'none' = 'auto';
15
+ @Input() items!: Action[];
16
+ @Input() position: 'top' | 'right' | 'bottom' | 'left' | 'auto' = 'auto';
17
+
18
+ @Input() class: string = '';
19
+ @HostBinding('class') get hostClasses(): string {
20
+ return [
21
+ 'ft-navbar',
22
+ this.class,
23
+ this.position
24
+ ].join(' ');
25
+ };
26
+
27
+ constructor(
28
+ private router: Router
29
+ ) { }
30
+
31
+ ngOnInit() { }
32
+ getComponentType(item: Action): string {
33
+ let type: string = 'text';
34
+ if (!item.url || item.url.match(/^(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/)) {
35
+ type = 'button';
36
+ } else {
37
+ type = 'link';
38
+ }
39
+ return type;
40
+ }
41
+ setItem(item: Action): void {
42
+ if (item.url) {
43
+ if (item.url.match(/^(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/)) {
44
+ window.location.href = item.url;
45
+ }
46
+ } else if (item.click) {
47
+ item.click();
48
+ }
49
+ }
50
+ toggleCollapsible(action: Action): void {
51
+ action.metadata.show = !action.metadata.show;
52
+ }
53
+ trackByItem(index: number, item: Action): string {
54
+ return `${item.label} ${item.url}`;
55
+ }
56
+
57
+ }
@@ -0,0 +1,34 @@
1
+ import { NgModule } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { MatMenuModule } from '@angular/material/menu';
4
+ import { MatButtonModule } from '@angular/material/button';
5
+
6
+ import { ListComponent } from './list/list.component';
7
+ import { NavbarComponent } from './navbar/navbar.component';
8
+ import { ToolbarComponent } from './toolbar/toolbar.component';
9
+ import { SearchboxComponent } from './searchbox/searchbox.component';
10
+ import { DisplayModule } from '../display/display.module';
11
+ import { RouterModule } from '@angular/router';
12
+
13
+ @NgModule({
14
+ declarations: [
15
+ ListComponent,
16
+ NavbarComponent,
17
+ ToolbarComponent,
18
+ SearchboxComponent
19
+ ],
20
+ exports: [
21
+ ListComponent,
22
+ NavbarComponent,
23
+ ToolbarComponent,
24
+ SearchboxComponent
25
+ ],
26
+ imports: [
27
+ CommonModule,
28
+ DisplayModule,
29
+ RouterModule,
30
+ MatMenuModule,
31
+ MatButtonModule
32
+ ]
33
+ })
34
+ export class NavigationModule { }
@@ -0,0 +1,34 @@
1
+ <form (submit)="onSearch($event)" class="container p-2 p-sm-3 pb-md-3 pt-md-5 px-md-3 px-lg-5">
2
+ <div class="d-flex align-items-center">
3
+ <button type="button" mat-icon-button class="p-2 mr-2" (click)="closeSearch()">
4
+ <ft-icon name="arrow-left" size="2"></ft-icon>
5
+ </button>
6
+ <input
7
+ #input
8
+ type="search"
9
+ matInput
10
+ class="flex-grow-1"
11
+ i18n-placeholder
12
+ placeholder="Search criteria"
13
+ [disabled]="disabled"
14
+ (change)="updateValue($event)"
15
+ (keyup)="updateValue($event)"
16
+ *ngIf="!placeholder"
17
+ />
18
+ <input
19
+ #inputPlaceholder
20
+ type="search"
21
+ matInput
22
+ class="flex-grow-1"
23
+ [placeholder]="placeholder"
24
+ [disabled]="disabled"
25
+ (change)="updateValue($event)"
26
+ (keyup)="updateValue($event)"
27
+ *ngIf="placeholder"
28
+ />
29
+ <button type="submit" mat-icon-button class="p-2 ml-2">
30
+ <ft-icon name="search" size="2"></ft-icon>
31
+ </button>
32
+ </div>
33
+ </form>
34
+
@@ -0,0 +1,37 @@
1
+ @import '../../scss/variables';
2
+ @import '../../scss/breakpoints';
3
+
4
+ :host {
5
+ z-index: var(--z-index, 980);
6
+ background-color: var(--background-color, #FFF);
7
+ display: block;
8
+ transition: background-color 0.2s, box-shadow 0.2s;
9
+ position: sticky;
10
+ top: -1px;
11
+ margin-top: -3.5rem;
12
+ opacity: 0;
13
+ visibility: hidden;
14
+ transition: opacity .3s, visibility .3s;
15
+ &.show {
16
+ opacity: 1;
17
+ visibility: visible;
18
+ }
19
+ @include media-breakpoint-up(sm) {
20
+ margin-top: -4.5rem;
21
+ }
22
+ @include media-breakpoint-up(md) {
23
+ top: -2rem;
24
+ margin-top: -6.5rem;
25
+ }
26
+ button {
27
+ min-width: 0;
28
+ line-height: inherit;
29
+ }
30
+ input {
31
+ border: 0;
32
+ background-color: transparent;
33
+ &:focus {
34
+ outline: none;
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { SearchboxComponent } from './searchbox.component';
4
+
5
+ describe('SearchboxComponent', () => {
6
+ let component: SearchboxComponent;
7
+ let fixture: ComponentFixture<SearchboxComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ SearchboxComponent ]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(SearchboxComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });