@sourceloop/search-client 9.0.1 → 11.0.0

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.
@@ -0,0 +1,191 @@
1
+ <ng-container *ngIf="!showOnlySearchResultOverlay()">
2
+ <div
3
+ fxLayout
4
+ fxLayoutAlign="start center"
5
+ class="toolbar-search"
6
+ *ngIf="cfg()"
7
+ >
8
+ <mat-form-field appearance="outline" class="toolbar-search-input">
9
+ <input
10
+ matInput
11
+ autocomplete="off"
12
+ type="text"
13
+ [placeholder]="
14
+ cfg().placeholderFunction?.(searchInput.value, category)
15
+ ?? cfg().placeholder ?? 'Search'
16
+ "
17
+ #searchInput
18
+ name="searchInput"
19
+ (focus)="showSuggestions()"
20
+ (blur)="hideSuggestions()"
21
+ [(ngModel)]="searchBoxInput"
22
+ (keyup)="hitSearchApi($event)"
23
+ placeholder="Search"
24
+ (ngModelChange)="onChange(this.searchBoxInput)"
25
+ [disabled]="disabled"
26
+ />
27
+ <mat-icon matPrefix [className]="cfg().searchIconClass"></mat-icon>
28
+ <mat-icon
29
+ *ngIf="searchBoxInput"
30
+ matSuffix
31
+ [className]="cfg().crossIconClass"
32
+ (click)="resetInput()"
33
+ ></mat-icon>
34
+ </mat-form-field>
35
+
36
+ <mat-form-field appearance="outline" class="toolbar-search-select">
37
+ <mat-icon
38
+ matSuffix
39
+ [className]="cfg().dropDownButtonIconClass"
40
+ ></mat-icon>
41
+ <mat-select
42
+ [value]="category"
43
+ (selectionChange)="setCategory($event.value)"
44
+ panelClass="search-select"
45
+ >
46
+ <mat-option [value]="model.name" *ngFor="let model of cfg().models">
47
+ {{ model.displayName }}
48
+ </mat-option>
49
+ </mat-select>
50
+ </mat-form-field>
51
+ </div>
52
+ </ng-container>
53
+
54
+ <div class="search-container">
55
+ <div
56
+ *ngIf="suggestionsDisplay && (recentSearches.length || suggestions.length)"
57
+ class="search-popup"
58
+ >
59
+ <ng-container *ngIf="searchBoxInput">
60
+ <span *ngIf="suggestions.length === 0" class="search-message">
61
+ <ng-container *ngIf="searching"> searching... </ng-container>
62
+ <ng-container *ngIf="!searching">
63
+ {{ cfg().noResultMessage }}
64
+ </ng-container>
65
+ </span>
66
+ <ng-container *ngIf="cfg().categorizeResults && suggestions.length">
67
+ <div
68
+ class="search-result"
69
+ *ngFor="let modelWithSuggestions of getModelsWithSuggestions()"
70
+ >
71
+ <h3 class="suggestions-heading">
72
+ <img
73
+ *ngIf="modelWithSuggestions.model.imageUrl"
74
+ [src]="modelWithSuggestions.model.imageUrl"
75
+ [alt]="modelWithSuggestions.model.displayName"
76
+ />
77
+ {{ modelWithSuggestions.model.displayName }} ({{
78
+ modelWithSuggestions.items.length
79
+ }})
80
+ </h3>
81
+ <ul>
82
+ <li
83
+ *ngFor="let suggestion of modelWithSuggestions.items"
84
+ (mousedown)="populateValue(suggestion, $event)"
85
+ class="suggestions"
86
+ >
87
+ <ng-container *ngIf="subtitleTemplate()">
88
+ <ng-container
89
+ *ngTemplateOutlet="
90
+ subtitleTemplate();
91
+ context: {$implicit: suggestion}
92
+ "
93
+ >
94
+ </ng-container>
95
+ </ng-container>
96
+ <p
97
+ *ngIf="!titleTemplate()"
98
+ [innerHTML]="
99
+ boldString(
100
+ suggestion[cfg().displayPropertyName],
101
+ searchBoxInput
102
+ )
103
+ "
104
+ style="display: inline"
105
+ ></p>
106
+ <ng-container *ngIf="titleTemplate()">
107
+ <ng-container
108
+ *ngTemplateOutlet="
109
+ titleTemplate();
110
+ context: {$implicit: suggestion}
111
+ "
112
+ >
113
+ </ng-container>
114
+ </ng-container>
115
+ </li>
116
+ </ul>
117
+ </div>
118
+ </ng-container>
119
+ <ng-container *ngIf="!cfg().categorizeResults">
120
+ <div class="search-result">
121
+ <ul>
122
+ <li
123
+ *ngFor="let suggestion of suggestions"
124
+ (mousedown)="populateValue(suggestion, $event)"
125
+ >
126
+ <!--Need to call fetchModelImageUrlFromSuggestion as each suggestion can come from different model-->
127
+ <img
128
+ *ngIf="
129
+ !titleTemplate() &&
130
+ fetchModelImageUrlFromSuggestion(suggestion)
131
+ "
132
+ class="suggestions-categorize-false"
133
+ [src]="fetchModelImageUrlFromSuggestion(suggestion)"
134
+ style="margin-right: 5px"
135
+ alt="Img"
136
+ />
137
+ <ng-container *ngIf="subtitleTemplate()">
138
+ <ng-container
139
+ *ngTemplateOutlet="
140
+ subtitleTemplate();
141
+ context: {$implicit: suggestion}
142
+ "
143
+ >
144
+ </ng-container>
145
+ </ng-container>
146
+ <p
147
+ *ngIf="!titleTemplate()"
148
+ [innerHTML]="
149
+ boldString(
150
+ suggestion[cfg().displayPropertyName],
151
+ searchBoxInput
152
+ )
153
+ "
154
+ style="display: inline"
155
+ ></p>
156
+ <ng-container *ngIf="titleTemplate()">
157
+ <ng-container
158
+ *ngTemplateOutlet="
159
+ titleTemplate();
160
+ context: {$implicit: suggestion}
161
+ "
162
+ >
163
+ </ng-container>
164
+ </ng-container>
165
+ </li>
166
+ </ul>
167
+ </div>
168
+ </ng-container>
169
+ </ng-container>
170
+
171
+ <ng-container *ngIf="!cfg().hideRecentSearch && recentSearches.length > 0">
172
+ <div class="recent-searches">
173
+ <h3 class="suggestions-heading">Recent Searches</h3>
174
+ <ul>
175
+ <li
176
+ *ngFor="let recentSearch of recentSearches"
177
+ class="suggestions"
178
+ (mousedown)="populateValueRecentSearch(recentSearch, $event)"
179
+ >
180
+ <mat-icon
181
+ matPrefix
182
+ [className]="cfg().recentSearchIconClass"
183
+ ></mat-icon>
184
+
185
+ <span>&nbsp;{{ recentSearch.match }}</span>
186
+ </li>
187
+ </ul>
188
+ </div>
189
+ </ng-container>
190
+ </div>
191
+ </div>
@@ -0,0 +1,339 @@
1
+ $search-width: 86%;
2
+
3
+ :host {
4
+ ::ng-deep .mat-form-field-wrapper {
5
+ padding: 0;
6
+ .mat-form-field-prefix {
7
+ margin-right: 12px;
8
+ }
9
+ }
10
+ }
11
+
12
+ .toolbar-search-input {
13
+ width: $search-width;
14
+ ::ng-deep input {
15
+ margin: 0;
16
+ }
17
+ ::ng-deep {
18
+ .mat-form-field-flex {
19
+ .mat-form-field-outline:first-child {
20
+ .mat-form-field-outline-start {
21
+ border-color: transparent;
22
+ }
23
+ .mat-form-field-outline-end {
24
+ border: none;
25
+ border-radius: 0;
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ .icomoon {
32
+ &.Search,
33
+ &.close {
34
+ height: 1rem;
35
+ width: 1rem;
36
+ font-size: 1rem;
37
+ color: #33333380;
38
+ padding-bottom: 4px;
39
+ }
40
+ &.close {
41
+ cursor: pointer;
42
+ }
43
+ }
44
+
45
+ .toolbar-search-select {
46
+ width: calc(100% - #{$search-width});
47
+ ::ng-deep .mat-select-arrow {
48
+ opacity: 0;
49
+ }
50
+ ::ng-deep {
51
+ .mat-select-arrow-wrapper {
52
+ display: inline-block;
53
+ width: 1px;
54
+ }
55
+ .mat-select-value-text {
56
+ font-size: 9px;
57
+ }
58
+ .mat-form-field-suffix .mat-icon {
59
+ width: 12px;
60
+ font-size: 14px;
61
+ }
62
+ .mat-form-field-flex {
63
+ .mat-form-field-outline:first-child {
64
+ .mat-form-field-outline-start {
65
+ border-color: transparent;
66
+ border-radius: 0;
67
+ }
68
+ .mat-form-field-outline-end {
69
+ border: none;
70
+ }
71
+ }
72
+ .mat-form-field-infix {
73
+ //chrome specific only.
74
+ -webkit-padding-before: 0.7em ;
75
+ }
76
+ }
77
+ }
78
+ }
79
+ .toolbar-search {
80
+ width: 515px;
81
+ background-color: #f7f7f7;
82
+ border-radius: 0 0 4px 4px;
83
+
84
+ ::ng-deep {
85
+ .mat-form-field-appearance-outline .mat-form-field-flex {
86
+ height: 39px;
87
+ align-items: center ;
88
+ }
89
+
90
+ .mat-form-field-appearance-outline .mat-form-field-wrapper {
91
+ margin: 0;
92
+ }
93
+ }
94
+
95
+ ::ng-deep .mat-form-field-infix {
96
+ height: auto ;
97
+ }
98
+ }
99
+
100
+ .search-container {
101
+ position: relative;
102
+ width: 515px;
103
+
104
+ .search-popup {
105
+ padding: 0 15px 15px;
106
+ margin: 0;
107
+ max-height: 80vh;
108
+ overflow-x: hidden;
109
+ overflow-y: auto;
110
+ position: absolute;
111
+ top: 100%;
112
+ left: 0px;
113
+ right: 0px;
114
+ z-index: 9999;
115
+ background-color: #fff;
116
+ box-shadow: 0 5px 4px #0003;
117
+ border-radius: 0 0 4px 4px;
118
+ hr {
119
+ border: 0;
120
+ border-top: 1px solid #ebebeb;
121
+ margin: 0;
122
+ position: sticky;
123
+ top: 0;
124
+ padding: 0 0 15px;
125
+ z-index: 1;
126
+ }
127
+ .search-message {
128
+ display: inline-block;
129
+ width: 100%;
130
+ text-align: center;
131
+ font-size: 16px;
132
+ padding-top: 12px;
133
+ }
134
+ .search-item-info {
135
+ color: #91263b;
136
+ text-align: center;
137
+ font-size: 12px;
138
+ margin-bottom: 15px;
139
+ padding-top: 12px;
140
+ }
141
+ ul {
142
+ padding: 0;
143
+ margin: 0;
144
+
145
+ li {
146
+ list-style: none;
147
+ font-size: 1rem;
148
+ font-weight: 400;
149
+ line-height: 1.5;
150
+ color: #333;
151
+
152
+ &.suggestions {
153
+ font-size: 15px;
154
+ line-height: 36px;
155
+ padding: 0 15px 0 44px;
156
+ // display: flex; causes words to join if bold and also causes ellipsis to not work
157
+ align-items: center;
158
+ white-space: nowrap;
159
+ overflow: hidden;
160
+ text-overflow: ellipsis;
161
+ cursor: pointer;
162
+
163
+ &:hover {
164
+ background-color: #fee8e8;
165
+ }
166
+
167
+ svg {
168
+ margin-right: 5px;
169
+ }
170
+ }
171
+
172
+ &.suggestions-categorize-false:hover {
173
+ background-color: #fee8e8;
174
+ }
175
+ }
176
+ }
177
+ .search-result {
178
+ padding: 10px 0 0;
179
+ margin: 0 -15px;
180
+
181
+ &.no-categorize-result {
182
+ ul {
183
+ width: 100%;
184
+ padding: 0;
185
+ margin: 0 0 10px;
186
+
187
+ li {
188
+ font-size: 15px;
189
+ line-height: 36px;
190
+ padding: 0 15px 0 31px;
191
+ display: flex;
192
+ align-items: center;
193
+ cursor: pointer;
194
+
195
+ &:hover {
196
+ background-color: #fee8e8;
197
+ }
198
+
199
+ img {
200
+ width: 18px;
201
+ margin-right: 9px;
202
+ }
203
+ }
204
+ }
205
+ }
206
+ }
207
+ .suggestions-heading {
208
+ color: #9c9c9c;
209
+ font-size: 14px;
210
+ font-weight: normal;
211
+ margin: 0 0 10px 17px;
212
+ display: flex;
213
+ align-items: center;
214
+ position: relative;
215
+
216
+ .show-more {
217
+ position: absolute;
218
+ right: 20px;
219
+ color: #d1d1d1;
220
+ font-size: 12px;
221
+ cursor: pointer;
222
+ text-decoration: none;
223
+
224
+ :hover {
225
+ text-decoration: underline;
226
+ }
227
+ }
228
+ img {
229
+ width: 18px;
230
+ margin-right: 9px;
231
+ }
232
+ }
233
+ .recent-searches {
234
+ padding: 10px 0 0;
235
+ margin: 0 -15px;
236
+
237
+ ul {
238
+ display: inline-block;
239
+ width: 100%;
240
+ li.suggestions {
241
+ display: flex;
242
+ span {
243
+ width: 100%;
244
+ overflow: hidden;
245
+ text-overflow: ellipsis;
246
+ }
247
+ }
248
+ }
249
+
250
+ .suggestions {
251
+ display: flex;
252
+ }
253
+
254
+ .suggestions-heading {
255
+ margin-left: 30px;
256
+ }
257
+ li.suggestions {
258
+ padding-left: 31px;
259
+ }
260
+ }
261
+ }
262
+ }
263
+
264
+ @mixin toolbar-search-mixin($width, $color) {
265
+ .toolbar-search-input {
266
+ &.mat-form-field:not(.mat-form-field-disabled) {
267
+ .mat-form-field-outline {
268
+ .mat-form-field-outline-start {
269
+ border-width: $width ;
270
+ border-color: $color ;
271
+ }
272
+ .mat-form-field-outline-end {
273
+ border: $width solid $color ;
274
+ border-left-style: none ;
275
+ border-right-style: none ;
276
+ border-top-right-radius: 0 ;
277
+ border-bottom-right-radius: 0 ;
278
+ }
279
+ }
280
+ }
281
+ }
282
+ .toolbar-search-select {
283
+ &.mat-form-field:not(.mat-form-field-disabled) {
284
+ .mat-form-field-outline {
285
+ .mat-form-field-outline-start {
286
+ border-radius: 0;
287
+ border-color: transparent ;
288
+ background-color: $color ;
289
+ }
290
+ .mat-form-field-outline-end {
291
+ border-width: $width ;
292
+ border-color: $color ;
293
+ background-color: $color ;
294
+ }
295
+ }
296
+ .mat-select {
297
+ color: white ;
298
+ }
299
+ .icomoon.arrow_down {
300
+ color: white;
301
+ }
302
+ }
303
+ }
304
+ }
305
+
306
+ ::ng-deep {
307
+ .search-select.mat-select-panel {
308
+ margin-top: 30px;
309
+ margin-left: 10px;
310
+ }
311
+ .search-select .mat-option-text {
312
+ display: contents ;
313
+ }
314
+ .toolbar-search {
315
+ $size: 14px;
316
+ .mat-form-field-infix {
317
+ font-size: $size;
318
+ }
319
+ input {
320
+ line-height: $size;
321
+ }
322
+ .mat-form-field-outline:first-child {
323
+ .mat-form-field-outline-start,
324
+ .mat-form-field-outline-end {
325
+ background-color: #f1f3f4;
326
+ }
327
+ }
328
+ // Hover
329
+ &:hover {
330
+ @include toolbar-search-mixin(1px, #a53159);
331
+ }
332
+ &:focus-within {
333
+ @include toolbar-search-mixin(2px, #90003b);
334
+ }
335
+ .mat-select-arrow {
336
+ opacity: 0;
337
+ }
338
+ }
339
+ }