@sourceloop/search-client 1.1.2

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,183 @@
1
+ <div
2
+ class="search-container"
3
+ [ngClass]="suggestionsDisplay ? 'search-focus-in' : 'search-focus-out'"
4
+ >
5
+ <form>
6
+ <div class="flex-box align-items-center justify-content-between">
7
+ <div class="search-column-left">
8
+ <div class="flex-box align-items-center justify-content-between">
9
+ <svg
10
+ width="16"
11
+ height="16"
12
+ viewBox="0 0 16 16"
13
+ fill="none"
14
+ xmlns="http://www.w3.org/2000/svg"
15
+ >
16
+ <path
17
+ fill-rule="evenodd"
18
+ clip-rule="evenodd"
19
+ d="M2 6.5C2 8.981 4.0185 11 6.5 11C8.981 11 11 8.981 11 6.5C11 4.0185 8.981 2 6.5 2C4.0185 2 2 4.0185 2 6.5ZM1 6.5C1 3.4625 3.4625 1 6.5 1C9.5375 1 12 3.4625 12 6.5C12 9.5375 9.5375 12 6.5 12C3.4625 12 1 9.5375 1 6.5ZM10.7236 11.4306C10.9771 11.2131 11.2131 10.9771 11.4306 10.7236L15.0001 14.2926L14.2931 15.0001L10.7236 11.4306Z"
20
+ fill="#9C9C9C"
21
+ />
22
+ </svg>
23
+ <input
24
+ class="search-input"
25
+ autocomplete="off"
26
+ type="text"
27
+ [placeholder]="config.placeholder"
28
+ #searchInput
29
+ name="searchInput"
30
+ (focus)="showSuggestions()"
31
+ (blur)="hideSuggestions()"
32
+ [(ngModel)]="searchBoxInput"
33
+ (keyup)="hitSearchApi($event)"
34
+ placeholder="Search"
35
+ (ngModelChange)="onChange(this.searchBoxInput)"
36
+ [disabled]="disabled"
37
+ />
38
+ </div>
39
+ </div>
40
+ <div class="search-column-right">
41
+ <button
42
+ *ngIf="searchBoxInput"
43
+ type="button"
44
+ class="clear-button"
45
+ id="clear-button"
46
+ (click)="resetInput()"
47
+ >
48
+ Clear x
49
+ </button>
50
+ <ng-container *ngIf="!config.hideCategorizeButton">
51
+ <button class="category-button" (click)="showCategory()">
52
+ {{ category !== 'All' ? category.displayName : category }}
53
+ <svg height="14" viewBox="0 0 14 14" width="14">
54
+ <polygon
55
+ [attr.points]="
56
+ categoryDisplay
57
+ ? '0,14 7,6, 14,14, 7,6, 0,14'
58
+ : '0,6 7,14, 14,6, 7,14, 0,6'
59
+ "
60
+ style="stroke: 'inherit'; fill: 'inherit'"
61
+ ></polygon>
62
+ </svg>
63
+ </button>
64
+ <ng-container *ngIf="categoryDisplay">
65
+ <div class="category-overlay" (click)="hideCategory()"></div>
66
+ <div class="category-popup">
67
+ <ul>
68
+ <li (click)="setCategory('All', $event)" class="category">
69
+ All
70
+ </li>
71
+ <li
72
+ *ngFor="let model of config.models"
73
+ (click)="setCategory(model, $event)"
74
+ class="category"
75
+ >
76
+ {{ model.displayName }}
77
+ </li>
78
+ </ul>
79
+ </div>
80
+ </ng-container>
81
+ </ng-container>
82
+ </div>
83
+ </div>
84
+ </form>
85
+
86
+ <div *ngIf="suggestionsDisplay" class="search-popup">
87
+ <ng-container *ngIf="config.categorizeResults">
88
+ <div class="search-item-info" *ngIf="category === 'All'">
89
+ You are searching on {{ category }}
90
+ </div>
91
+ <div class="search-item-info" *ngIf="category !== 'All'">
92
+ You are searching on {{ category.displayName }}
93
+ </div>
94
+ </ng-container>
95
+ <ng-container *ngIf="searchBoxInput">
96
+ <ng-container *ngIf="config.categorizeResults">
97
+ <div class="search-result" *ngFor="let model of config.models">
98
+ <h3
99
+ *ngIf="getSuggestionsFromModelName(model.name)"
100
+ class="suggestions-heading"
101
+ >
102
+ <img
103
+ *ngIf="model.imageUrl"
104
+ [src]="model.imageUrl"
105
+ [alt]="model.displayName"
106
+ />
107
+ {{ model.displayName }}({{ relevantSuggestions?.length }})
108
+ </h3>
109
+ <ul>
110
+ <li
111
+ *ngFor="let suggestion of relevantSuggestions"
112
+ (mousedown)="populateValue(suggestion, $event)"
113
+ class="suggestions"
114
+ [innerHTML]="
115
+ boldString(
116
+ suggestion[config.displayPropertyName],
117
+ searchBoxInput
118
+ )
119
+ "
120
+ ></li>
121
+ </ul>
122
+ </div>
123
+ </ng-container>
124
+ <ng-container *ngIf="!config.categorizeResults">
125
+ <div class="search-result">
126
+ <ul>
127
+ <li
128
+ *ngFor="let suggestion of suggestions"
129
+ (mousedown)="populateValue(suggestion, $event)"
130
+ >
131
+ <!--Need to call fetchModelImageUrlFromSuggestion as each suggestion can come from different model-->
132
+ <img
133
+ *ngIf="fetchModelImageUrlFromSuggestion(suggestion)"
134
+ class="suggestions-categorize-false"
135
+ [src]="fetchModelImageUrlFromSuggestion(suggestion)"
136
+ style="margin-right: 5px"
137
+ alt="Img"
138
+ />
139
+ <p
140
+ [innerHTML]="
141
+ boldString(
142
+ suggestion[config.displayPropertyName],
143
+ searchBoxInput
144
+ )
145
+ "
146
+ style="display: inline"
147
+ ></p>
148
+ </li>
149
+ </ul>
150
+ </div>
151
+ </ng-container>
152
+ </ng-container>
153
+
154
+ <ng-container *ngIf="!config.hideRecentSearch && recentSearches.length > 0">
155
+ <div class="recent-searches">
156
+ <h3 class="suggestions-heading">Recent Searches</h3>
157
+ <ul>
158
+ <li
159
+ *ngFor="let recentSearch of recentSearches"
160
+ class="suggestions"
161
+ (mousedown)="populateValueRecentSearch(recentSearch, $event)"
162
+ >
163
+ <svg
164
+ width="16"
165
+ height="16"
166
+ viewBox="0 0 16 16"
167
+ fill="none"
168
+ xmlns="http://www.w3.org/2000/svg"
169
+ >
170
+ <path
171
+ fill-rule="evenodd"
172
+ clip-rule="evenodd"
173
+ d="M2 6.5C2 8.981 4.0185 11 6.5 11C8.981 11 11 8.981 11 6.5C11 4.0185 8.981 2 6.5 2C4.0185 2 2 4.0185 2 6.5ZM1 6.5C1 3.4625 3.4625 1 6.5 1C9.5375 1 12 3.4625 12 6.5C12 9.5375 9.5375 12 6.5 12C3.4625 12 1 9.5375 1 6.5ZM10.7236 11.4306C10.9771 11.2131 11.2131 10.9771 11.4306 10.7236L15.0001 14.2926L14.2931 15.0001L10.7236 11.4306Z"
174
+ fill="#9C9C9C"
175
+ />
176
+ </svg>
177
+ <span>{{ recentSearch.match }}</span>
178
+ </li>
179
+ </ul>
180
+ </div>
181
+ </ng-container>
182
+ </div>
183
+ </div>
@@ -0,0 +1,301 @@
1
+ .search-container {
2
+ border: 1px solid transparent;
3
+ border-radius: 4px;
4
+ background-color: #f7f7f7;
5
+ padding: 0 15px;
6
+ position: relative;
7
+ width: inherit;
8
+
9
+ &:hover {
10
+ outline: 2px solid #91263b;
11
+
12
+ &.search-focus-in {
13
+ outline: none;
14
+ }
15
+ }
16
+
17
+ &.search-focus-in {
18
+ outline: none;
19
+ box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2);
20
+ background-color: #fff;
21
+ border-bottom: 0;
22
+ border-radius: 4px 4px 0 0;
23
+
24
+ &:hover {
25
+ outline: 0;
26
+ }
27
+ }
28
+ .flex-box {
29
+ display: flex;
30
+ }
31
+ .align-items-center {
32
+ align-items: center;
33
+ }
34
+ .justify-content-between {
35
+ justify-content: space-between;
36
+ }
37
+ .search-column-left {
38
+ flex-direction: column;
39
+ width: 100%;
40
+ }
41
+ .search-column-right {
42
+ flex-direction: column;
43
+ text-align: right;
44
+ select {
45
+ border: 0;
46
+ outline: 0;
47
+ width: 60px;
48
+ background-color: transparent;
49
+ margin-left: 10px;
50
+ font-size: 12px;
51
+ color: #333333;
52
+ border-left: 1px solid #d1d1d1;
53
+ padding-left: 4px;
54
+ }
55
+ }
56
+ .search-symbol {
57
+ color: #d1d1d1;
58
+ font-size: 12px;
59
+ display: inline-block;
60
+ }
61
+ .search-input {
62
+ padding: 0 0.75rem;
63
+ font-size: 14px;
64
+ font-weight: 400;
65
+ line-height: 1.5;
66
+ color: #333333;
67
+ background-color: transparent;
68
+ border: 0;
69
+ border-radius: 0;
70
+ width: 100%;
71
+ box-sizing: border-box;
72
+ height: 38px;
73
+ display: inline-block;
74
+ }
75
+ .search-input::placeholder {
76
+ color: #d1d1d1;
77
+ }
78
+ .search-input:focus {
79
+ outline: none;
80
+ }
81
+ .clear-button {
82
+ background-color: transparent;
83
+ border: 0 solid #ced4da;
84
+ color: #d1d1d1;
85
+ font-size: 12px;
86
+ cursor: pointer;
87
+
88
+ span {
89
+ display: inline-block;
90
+ margin-left: 5px;
91
+ font-size: 14px;
92
+ }
93
+ }
94
+ .category-button {
95
+ padding: 0 0.75rem;
96
+ font-size: 14px;
97
+ font-weight: 400;
98
+ line-height: 1.5;
99
+ color: #d1d1d1;
100
+ cursor: pointer;
101
+ border: none;
102
+ background: transparent;
103
+ user-select: none;
104
+ svg {
105
+ stroke: #d1d1d1;
106
+ }
107
+ }
108
+ .category-overlay {
109
+ top: 0;
110
+ left: 0;
111
+ position: fixed;
112
+ z-index: 9998;
113
+ background-color: transparent;
114
+ width: 100%;
115
+ height: 100%;
116
+ }
117
+ .category-popup {
118
+ overflow-x: hidden;
119
+ overflow-y: auto;
120
+ position: absolute;
121
+ top: 100%;
122
+ right: 0px;
123
+ z-index: 9999;
124
+ background-color: #fff;
125
+ box-shadow: 0 5px 4px #0003;
126
+ border-radius: 0 0 4px 4px;
127
+ width: max-content;
128
+ font-size: 11.2px !important;
129
+ ul {
130
+ padding: 0;
131
+ margin: 0;
132
+
133
+ li {
134
+ list-style: none;
135
+ font-size: 1rem;
136
+ font-weight: 400;
137
+ line-height: 1.5;
138
+ color: #333;
139
+ user-select: none;
140
+
141
+
142
+ &.category {
143
+ // display: flex; causes words to join if bold
144
+ align-items: center;
145
+ display: flex;
146
+ cursor: pointer;
147
+ padding: 0 16px;
148
+ border-bottom: 1px solid #f2f2f2;
149
+ font-family: "Rakuten Sans", sans-serif;
150
+ font-size: 12.8px;
151
+ line-height: 32px;
152
+ letter-spacing: 0px;
153
+ text-align: left;
154
+
155
+ &:hover {
156
+ background-color: #fee8e8;
157
+ }
158
+
159
+ svg {
160
+ margin-right: 5px;
161
+ }
162
+ }
163
+
164
+ &.suggestions-categorize-false:hover {
165
+ background-color: #fee8e8;
166
+ }
167
+ }
168
+ }
169
+ }
170
+ .search-popup {
171
+ padding: 0 15px 15px;
172
+ margin: 0;
173
+ max-height: 80vh;
174
+ overflow-x: hidden;
175
+ overflow-y: auto;
176
+ position: absolute;
177
+ top: calc(100% - 2px);
178
+ left: -1px;
179
+ right: -1px;
180
+ z-index: 9999;
181
+ background-color: #fff;
182
+ box-shadow: 0 5px 4px #0003;
183
+ border-radius: 0 0 4px 4px;
184
+ hr {
185
+ border: 0;
186
+ border-top: 1px solid #ebebeb;
187
+ margin: 0;
188
+ position: sticky;
189
+ top: 0;
190
+ padding: 0 0 15px;
191
+ z-index: 1;
192
+ }
193
+ .search-item-info {
194
+ color: #91263b;
195
+ text-align: center;
196
+ font-size: 12px;
197
+ margin-bottom: 15px;
198
+ }
199
+ ul {
200
+ padding: 0;
201
+ margin: 0;
202
+
203
+ li {
204
+ list-style: none;
205
+ font-size: 1rem;
206
+ font-weight: 400;
207
+ line-height: 1.5;
208
+ color: #333;
209
+
210
+ &.suggestions {
211
+ font-size: 15px;
212
+ line-height: 36px;
213
+ padding: 0 15px 0 44px;
214
+ // display: flex; causes words to join if bold
215
+ align-items: center;
216
+ display: flex;
217
+ cursor: pointer;
218
+
219
+ &:hover {
220
+ background-color: #fee8e8;
221
+ }
222
+
223
+ svg {
224
+ margin-right: 5px;
225
+ }
226
+ }
227
+
228
+ &.suggestions-categorize-false:hover {
229
+ background-color: #fee8e8;
230
+ }
231
+ }
232
+ }
233
+ .search-result {
234
+ padding: 10px 0 0;
235
+ margin: 0 -15px;
236
+
237
+ &.no-categorize-result {
238
+ ul {
239
+ width: 100%;
240
+ padding: 0;
241
+ margin: 0 0 10px;
242
+
243
+ li {
244
+ font-size: 15px;
245
+ line-height: 36px;
246
+ padding: 0 15px 0 31px;
247
+ display: flex;
248
+ align-items: center;
249
+ cursor: pointer;
250
+
251
+ &:hover {
252
+ background-color: #fee8e8;
253
+ }
254
+
255
+ img {
256
+ width: 18px;
257
+ margin-right: 9px;
258
+ }
259
+ }
260
+ }
261
+ }
262
+ }
263
+ .suggestions-heading {
264
+ color: #9c9c9c;
265
+ font-size: 14px;
266
+ font-weight: normal;
267
+ margin: 0 0 10px 17px;
268
+ display: flex;
269
+ align-items: center;
270
+ position: relative;
271
+
272
+ .show-more {
273
+ position: absolute;
274
+ right: 20px;
275
+ color: #d1d1d1;
276
+ font-size: 12px;
277
+ cursor: pointer;
278
+ text-decoration: none;
279
+
280
+ :hover {
281
+ text-decoration: underline;
282
+ }
283
+ }
284
+ img {
285
+ width: 18px;
286
+ margin-right: 9px;
287
+ }
288
+ }
289
+ .recent-searches {
290
+ padding: 10px 0 0;
291
+ margin: 0 -15px;
292
+
293
+ .suggestions-heading {
294
+ margin-left: 30px;
295
+ }
296
+ li.suggestions {
297
+ padding-left: 31px;
298
+ }
299
+ }
300
+ }
301
+ }