@searchstax-inc/searchstudio-ux-react 0.0.11 → 0.2.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.
- package/README.md +378 -156
- package/dist/@searchstax-inc/components/SearchstaxInputWidget.d.ts +5 -7
- package/dist/@searchstax-inc/components/SearchstaxOverviewWidget.d.ts +5 -0
- package/dist/@searchstax-inc/components/SearchstaxPaginationWidget.d.ts +5 -0
- package/dist/@searchstax-inc/components/SearchstaxResultWidget.d.ts +3 -3
- package/dist/@searchstax-inc/components/SearchstaxSortingWidget.d.ts +5 -0
- package/dist/@searchstax-inc/components/SearchstaxWrapper.d.ts +7 -2
- package/dist/@searchstax-inc/main.d.ts +4 -1
- package/dist/@searchstax-inc/searchstudio-ux-react.cjs +224 -70
- package/dist/@searchstax-inc/searchstudio-ux-react.d.cts +4 -1
- package/dist/@searchstax-inc/searchstudio-ux-react.iife.js +224 -70
- package/dist/@searchstax-inc/searchstudio-ux-react.mjs +2569 -1027
- package/package.json +3 -3
- package/dist/main.d.ts +0 -4
package/README.md
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
Library to build searchstudio search page
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
|
-
npm install following
|
|
6
|
+
npm install following package
|
|
7
7
|
`npm install --save @searchstax-inc/searchstudio-ux-react`
|
|
8
|
-
`npm install --save @searchstax-inc/searchstudio-ux-js`
|
|
9
8
|
|
|
10
9
|
Add following code to `<head>`
|
|
11
10
|
|
|
@@ -22,90 +21,144 @@ Add following code to `<head>`
|
|
|
22
21
|
})();
|
|
23
22
|
</script>
|
|
24
23
|
```
|
|
24
|
+
## Usage
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
types can be imported from
|
|
28
|
-
|
|
29
|
-
`import type { ISearchstaxParsedResult, ISearchstaxSearchProps, ISearchstaxSuggestProps, ISearchstaxSuggestResponse, Searchstax } from '@searchstax-inc/searchstudio-ux-js'`
|
|
26
|
+
After importing SearchstaxWrapper component needs to wrap all other components:
|
|
30
27
|
|
|
31
|
-
|
|
28
|
+
```
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
<SearchstaxWrapper
|
|
31
|
+
searchURL={config.searchURL}
|
|
32
|
+
suggesterURL={config.suggesterURL}
|
|
33
|
+
trackApiKey={config.trackApiKey}
|
|
34
|
+
searchAuth={config.searchAuth}
|
|
35
|
+
initialized={initialized}
|
|
36
|
+
beforeSearch={beforeSearch}
|
|
37
|
+
afterSearch={afterSearch}
|
|
38
|
+
authType="basic"
|
|
39
|
+
language="en"
|
|
40
|
+
>
|
|
41
|
+
// other components will go there
|
|
42
|
+
|
|
43
|
+
</SearchstaxWrapper>
|
|
44
|
+
```
|
|
35
45
|
|
|
36
|
-
|
|
46
|
+
## Initialization
|
|
47
|
+
Initialization object needs to be of type: [ISearchstaxConfig](https://github.com/searchstax/searchstudio-ux-js/blob/main/src/interfaces/connector.interface.ts#L5)
|
|
37
48
|
|
|
49
|
+
Initialization example
|
|
38
50
|
```
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
sampleConfig = {
|
|
52
|
+
language: "en",
|
|
53
|
+
searchURL: "",
|
|
54
|
+
suggesterURL: "",
|
|
55
|
+
trackApiKey: "",
|
|
56
|
+
searchAuth: "",
|
|
57
|
+
authType: "basic",
|
|
58
|
+
router: {
|
|
59
|
+
enabled: true,
|
|
60
|
+
routeName: "searchstax",
|
|
61
|
+
title: (result: ISearchObject) => {
|
|
62
|
+
return "Search results for: " + result.query;
|
|
63
|
+
},
|
|
64
|
+
ignoredKeys: [],
|
|
65
|
+
},
|
|
66
|
+
hooks: {
|
|
67
|
+
beforeSearch: function (props: ISearchObject) {
|
|
68
|
+
const propsCopy = { ...props };
|
|
69
|
+
return propsCopy;
|
|
70
|
+
},
|
|
71
|
+
afterSearch: function (results: ISearchstaxParsedResult[]) {
|
|
72
|
+
const copy = [...results];
|
|
73
|
+
return copy;
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
};
|
|
42
77
|
```
|
|
43
78
|
|
|
44
|
-
##
|
|
45
|
-
|
|
79
|
+
## Initial layout
|
|
80
|
+
Our base theme is designed with this layout in mind but it is optional as all widgets have id parameters and can be attached to any element.
|
|
81
|
+
```
|
|
82
|
+
<SearchstaxWrapper
|
|
83
|
+
searchURL={sampleConfig.searchURL}
|
|
84
|
+
suggesterURL={sampleConfig.suggesterURL}
|
|
85
|
+
trackApiKey={sampleConfig.trackApiKey}
|
|
86
|
+
searchAuth={sampleConfig.searchAuth}
|
|
87
|
+
beforeSearch={sampleConfig.hooks.beforeSearch}
|
|
88
|
+
afterSearch={sampleConfig.hooks.afterSearch}
|
|
89
|
+
authType="basic"
|
|
90
|
+
language="en"
|
|
91
|
+
>
|
|
92
|
+
<div className="searchstax-page-layout-container">
|
|
93
|
+
<SearchstaxInputWidget
|
|
94
|
+
afterAutosuggest={afterAutosuggest}
|
|
95
|
+
beforeAutosuggest={beforeAutosuggest}
|
|
96
|
+
inputTemplate={InputTemplate}
|
|
97
|
+
></SearchstaxInputWidget>
|
|
98
|
+
|
|
99
|
+
<div className="search-details-container">
|
|
100
|
+
<div id="search-feedback-container"></div>
|
|
101
|
+
<div id="search-sorting-container"></div>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<div className="searchstax-page-layout-facet-result-container">
|
|
105
|
+
<div className="searchstax-page-layout-facet-container">
|
|
106
|
+
<div id="searchstax-facets-container"></div>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<div className="searchstax-page-layout-result-container">
|
|
110
|
+
<div id="searchstax-external-promotions-layout-container"></div>
|
|
111
|
+
<SearchstaxResultWidget
|
|
112
|
+
afterLinkClick={afterLinkClick}
|
|
113
|
+
noResultTemplate={noResultTemplate}
|
|
114
|
+
resultsTemplate={resultsTemplate}
|
|
115
|
+
></SearchstaxResultWidget>
|
|
116
|
+
<div id="searchstax-related-searches-container"></div>
|
|
117
|
+
<div id="searchstax-pagination-container"></div>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</SearchstaxWrapper>
|
|
46
122
|
```
|
|
47
|
-
const config = {
|
|
48
|
-
searchURL: '', // - SeachStudio select endpoint
|
|
49
|
-
suggesterURL: '', // - SeachStudio suggest endpoint
|
|
50
|
-
trackApiKey: '', // - Api key used for tracking events
|
|
51
|
-
searchAuth: '', // - Authentication value. based on authType it's either a token value or basic auth value
|
|
52
|
-
authType: '', // - Type of authentication
|
|
53
|
-
}
|
|
54
123
|
|
|
124
|
+
### widgets
|
|
125
|
+
Following widgets are available:
|
|
55
126
|
|
|
56
|
-
|
|
127
|
+
[Input Widget](#input-widget)
|
|
57
128
|
|
|
58
|
-
|
|
59
|
-
|
|
129
|
+
[Result Widget](#result-widget)
|
|
130
|
+
|
|
131
|
+
[Facets Widget](#facets-widget)
|
|
60
132
|
|
|
61
|
-
|
|
133
|
+
[Pagination Widget](#pagination-widget)
|
|
134
|
+
|
|
135
|
+
[SearchFeedback Widget](#searchfeedback-widget)
|
|
136
|
+
|
|
137
|
+
[RelatedSearches Widget](#relatedsearches-widget)
|
|
138
|
+
|
|
139
|
+
[ExternalPromotions Widget](#externalpromotions-widget)
|
|
140
|
+
|
|
141
|
+
[sorting Widget](#sorting-widget)
|
|
142
|
+
|
|
143
|
+
### Input Widget ###
|
|
144
|
+
|
|
145
|
+
example of input widget initialization with minimum options
|
|
146
|
+
```
|
|
147
|
+
<SearchstaxInputWidget
|
|
148
|
+
afterAutosuggest={afterAutosuggest}
|
|
149
|
+
beforeAutosuggest={beforeAutosuggest}
|
|
150
|
+
></SearchstaxInputWidget>
|
|
62
151
|
```
|
|
63
152
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
// other widgets go here
|
|
74
|
-
</SearchstaxWrapper>
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
## Input widget
|
|
79
|
-
JS
|
|
80
|
-
```
|
|
81
|
-
function beforeSearch(props: ISearchstaxSearchProps) {
|
|
82
|
-
// - this function gets called before firing search. searchProps are being passed as a property and can be modified, if passed along further search will execute with modified properties, if null is returned then event gets canceled and search never fires.
|
|
83
|
-
const propsCopy = { ...props }
|
|
84
|
-
return propsCopy
|
|
85
|
-
}
|
|
86
|
-
function afterSearch(results: ISearchstaxParsedResult[]) {
|
|
87
|
-
//- this function gets called after firing search and before rendering. It needs to return array of results that are either modified or untouched.
|
|
88
|
-
const copy = [...results]
|
|
89
|
-
return copy
|
|
90
|
-
}
|
|
91
|
-
function afterAutosuggest(result: ISearchstaxSuggestResponse) {
|
|
92
|
-
// - this function gets called before firing autosuggest. autosuggestProps are being passed as a property and can be modified, if passed along further search will execute with modified properties, if null is returned then event gets canceled and search never fires.
|
|
93
|
-
const copy = { ...result }
|
|
94
|
-
return copy
|
|
95
|
-
}
|
|
96
|
-
function beforeAutosuggest(props: ISearchstaxSuggestProps) {
|
|
97
|
-
// - this function gets called after autosuggest has values but before rendering. It needs to return same type of data but it can be modified.
|
|
98
|
-
const propsCopy = { ...props }
|
|
99
|
-
return propsCopy
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const suggestAfterMinChars = 3; // - controls how many characters the UI should accept at the minimum before showing suggestions
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
JSX Input template sample
|
|
106
|
-
|
|
107
|
-
```
|
|
108
|
-
function InputTemplate(): React.ReactElement {
|
|
153
|
+
|
|
154
|
+
example of input widget initialization with template override
|
|
155
|
+
```
|
|
156
|
+
function InputTemplate(
|
|
157
|
+
suggestions: ISearchstaxSuggestion[],
|
|
158
|
+
onMouseLeave: () => void,
|
|
159
|
+
onMouseOver: (suggestion: ISearchstaxSuggestion) => void,
|
|
160
|
+
onMouseClick: () => void
|
|
161
|
+
): React.ReactElement {
|
|
109
162
|
return (
|
|
110
163
|
<div className="searchstax-search-input-wrapper">
|
|
111
164
|
<input
|
|
@@ -114,55 +167,63 @@ function InputTemplate(): React.ReactElement {
|
|
|
114
167
|
className="searchstax-search-input"
|
|
115
168
|
placeholder="SEARCH FOR..."
|
|
116
169
|
/>
|
|
117
|
-
<
|
|
118
|
-
className=
|
|
119
|
-
|
|
120
|
-
|
|
170
|
+
<div
|
|
171
|
+
className={`searchstax-autosuggest-container ${suggestions.length === 0 ? "hidden" : ""}`}
|
|
172
|
+
onMouseLeave={onMouseLeave}
|
|
173
|
+
>
|
|
174
|
+
{suggestions.map(function (suggestion) {
|
|
175
|
+
return (
|
|
176
|
+
<div className="searchstax-autosuggest-item" key={suggestion.term}>
|
|
177
|
+
<div
|
|
178
|
+
className="searchstax-autosuggest-item-term-container"
|
|
179
|
+
dangerouslySetInnerHTML={{ __html: suggestion.term }}
|
|
180
|
+
onMouseOver={() => {
|
|
181
|
+
onMouseOver(suggestion);
|
|
182
|
+
}}
|
|
183
|
+
onClick={() => {
|
|
184
|
+
onMouseClick();
|
|
185
|
+
}}
|
|
186
|
+
></div>
|
|
187
|
+
</div>
|
|
188
|
+
);
|
|
189
|
+
})}
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<button className="searchstax-spinner-icon" id="searchstax-search-input-action-button"></button>
|
|
121
193
|
</div>
|
|
122
194
|
);
|
|
123
195
|
}
|
|
124
|
-
```
|
|
125
196
|
|
|
126
|
-
HTML example with input override
|
|
127
197
|
|
|
128
|
-
```
|
|
129
198
|
<SearchstaxInputWidget
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
inputTemplate={InputTemplate}
|
|
135
|
-
></SearchstaxInputWidget>
|
|
199
|
+
afterAutosuggest={afterAutosuggest}
|
|
200
|
+
beforeAutosuggest={beforeAutosuggest}
|
|
201
|
+
inputTemplate={InputTemplate}
|
|
202
|
+
></SearchstaxInputWidget>
|
|
136
203
|
```
|
|
137
|
-
|
|
204
|
+
### Result Widget ###
|
|
138
205
|
|
|
139
|
-
|
|
206
|
+
example of results widget initialization with minimum options
|
|
140
207
|
```
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return propsCopy
|
|
146
|
-
}
|
|
208
|
+
<SearchstaxResultWidget
|
|
209
|
+
afterLinkClick={afterLinkClick}
|
|
210
|
+
></SearchstaxResultWidget>
|
|
147
211
|
```
|
|
148
212
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
searchTerm: string,
|
|
153
|
-
searchSuggestion: string
|
|
154
|
-
): React.ReactElement {
|
|
213
|
+
example of result widget initialization with template override
|
|
214
|
+
```
|
|
215
|
+
function noResultTemplate(searchTerm: string, metaData: ISearchstaxSearchMetadata | null): React.ReactElement {
|
|
155
216
|
return (
|
|
156
217
|
<div>
|
|
157
218
|
<div className="searchstax-no-results">
|
|
158
|
-
|
|
159
|
-
<strong>"{searchTerm}"</strong>
|
|
219
|
+
{" "}
|
|
220
|
+
Showing <strong>no results</strong> for <strong>"{searchTerm}"</strong>
|
|
160
221
|
<br />
|
|
161
|
-
{
|
|
222
|
+
{metaData?.spellingSuggestion && (
|
|
162
223
|
<span>
|
|
163
|
-
Did you mean
|
|
224
|
+
Did you mean{" "}
|
|
164
225
|
<a href="#" className="searchstax-suggestion-term">
|
|
165
|
-
{
|
|
226
|
+
{metaData?.spellingSuggestion}
|
|
166
227
|
</a>
|
|
167
228
|
?
|
|
168
229
|
</span>
|
|
@@ -170,71 +231,51 @@ JSX no results emplate sample
|
|
|
170
231
|
</div>
|
|
171
232
|
<div>
|
|
172
233
|
<p>
|
|
173
|
-
|
|
174
|
-
variety of content to help you get the
|
|
234
|
+
{" "}
|
|
235
|
+
Try searching for search related terms or topics. We offer a wide variety of content to help you get the
|
|
236
|
+
information you need.{" "}
|
|
175
237
|
</p>
|
|
176
238
|
<p>Lost? Click on the ‘X” in the Search Box to reset your search.</p>
|
|
177
239
|
</div>
|
|
178
240
|
</div>
|
|
179
241
|
);
|
|
180
242
|
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
JSX results template sample
|
|
184
|
-
|
|
185
|
-
```
|
|
186
243
|
|
|
187
|
-
function resultsTemplate(
|
|
244
|
+
function resultsTemplate(
|
|
188
245
|
searchResults: ISearchstaxParsedResult[],
|
|
189
|
-
|
|
190
|
-
results: ISearchstaxParsedResult[],
|
|
191
|
-
event: any
|
|
192
|
-
) => ISearchstaxParsedResult[]
|
|
246
|
+
resultClicked: (results: ISearchstaxParsedResult, event: any) => ISearchstaxParsedResult[]
|
|
193
247
|
): React.ReactElement {
|
|
194
248
|
return (
|
|
195
249
|
<div className="searchstax-search-results">
|
|
196
250
|
{searchResults !== null &&
|
|
197
|
-
searchResults.map(function (searchResult
|
|
251
|
+
searchResults.map(function (searchResult) {
|
|
198
252
|
return (
|
|
199
253
|
<div
|
|
200
|
-
className=
|
|
254
|
+
className={`searchstax-search-result ${searchResult.thumbnail ? "has-thumbnail" : ""}`}
|
|
201
255
|
key={searchResult.uniqueId}
|
|
202
256
|
>
|
|
257
|
+
{searchResult.promoted && <div className="searchstax-search-result-promoted"></div>}
|
|
258
|
+
|
|
203
259
|
{searchResult.url && (
|
|
204
260
|
<a
|
|
205
261
|
href={searchResult.url}
|
|
206
262
|
data-searchstax-unique-result-id={searchResult.uniqueId}
|
|
207
263
|
onClick={(event) => {
|
|
208
|
-
|
|
264
|
+
resultClicked(searchResult, event);
|
|
209
265
|
}}
|
|
210
266
|
className="searchstax-result-item-link"
|
|
211
267
|
></a>
|
|
212
268
|
)}
|
|
213
269
|
|
|
214
|
-
{searchResult.ribbon &&
|
|
215
|
-
<div className="searchstax-search-result-ribbon">
|
|
216
|
-
{searchResult.ribbon}
|
|
217
|
-
</div>
|
|
218
|
-
)}
|
|
270
|
+
{searchResult.ribbon && <div className="searchstax-search-result-ribbon">{searchResult.ribbon}</div>}
|
|
219
271
|
|
|
220
|
-
{searchResult.thumbnail &&
|
|
221
|
-
<img
|
|
222
|
-
src={searchResult.thumbnail}
|
|
223
|
-
className="searchstax-thumbnail"
|
|
224
|
-
/>
|
|
225
|
-
)}
|
|
272
|
+
{searchResult.thumbnail && <img src={searchResult.thumbnail} className="searchstax-thumbnail" />}
|
|
226
273
|
|
|
227
274
|
<div className="searchstax-search-result-title-container">
|
|
228
|
-
<span className="searchstax-search-result-title">
|
|
229
|
-
{searchResult.title}
|
|
230
|
-
</span>
|
|
275
|
+
<span className="searchstax-search-result-title">{searchResult.title}</span>
|
|
231
276
|
</div>
|
|
232
277
|
|
|
233
|
-
{searchResult.paths &&
|
|
234
|
-
<p className="searchstax-search-result-common">
|
|
235
|
-
{searchResult.paths}
|
|
236
|
-
</p>
|
|
237
|
-
)}
|
|
278
|
+
{searchResult.paths && <p className="searchstax-search-result-common">{searchResult.paths}</p>}
|
|
238
279
|
|
|
239
280
|
{searchResult.description && (
|
|
240
281
|
<p className="searchstax-search-result-description searchstax-search-result-common">
|
|
@@ -244,21 +285,16 @@ function resultsTemplate(
|
|
|
244
285
|
|
|
245
286
|
{searchResult.unmappedFields.map(function (unmappedField: any) {
|
|
246
287
|
return (
|
|
247
|
-
<div key={unmappedField.
|
|
248
|
-
{unmappedField.isImage && (
|
|
288
|
+
<div key={unmappedField.key}>
|
|
289
|
+
{unmappedField.isImage && typeof unmappedField.value === "string" && (
|
|
249
290
|
<div className="searchstax-search-result-image-container">
|
|
250
|
-
<img
|
|
251
|
-
src={unmappedField.value}
|
|
252
|
-
className="searchstax-result-image"
|
|
253
|
-
/>
|
|
291
|
+
<img src={unmappedField.value} className="searchstax-result-image" />
|
|
254
292
|
</div>
|
|
255
293
|
)}
|
|
256
294
|
|
|
257
295
|
{!unmappedField.isImage && (
|
|
258
296
|
<div>
|
|
259
|
-
<p className="searchstax-search-result-common">
|
|
260
|
-
{unmappedField.value}
|
|
261
|
-
</p>
|
|
297
|
+
<p className="searchstax-search-result-common">{unmappedField.value}</p>
|
|
262
298
|
</div>
|
|
263
299
|
)}
|
|
264
300
|
</div>
|
|
@@ -267,29 +303,215 @@ function resultsTemplate(
|
|
|
267
303
|
</div>
|
|
268
304
|
);
|
|
269
305
|
})}
|
|
306
|
+
</div>
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
<SearchstaxResultWidget
|
|
312
|
+
afterLinkClick={afterLinkClick}
|
|
313
|
+
noResultTemplate={noResultTemplate}
|
|
314
|
+
resultsTemplate={resultsTemplate}
|
|
315
|
+
></SearchstaxResultWidget>
|
|
316
|
+
```
|
|
270
317
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
318
|
+
### Pagination Widget ###
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
example of pagination widget initialization with minimum options
|
|
322
|
+
```
|
|
323
|
+
<SearchstaxPaginationWidget></SearchstaxPaginationWidget>
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
example of pagination widget initialization with various options
|
|
327
|
+
```
|
|
328
|
+
function paginationTemplate(
|
|
329
|
+
paginationData: IPaginationData | null,
|
|
330
|
+
nextPage: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void,
|
|
331
|
+
previousPage: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void
|
|
332
|
+
) {
|
|
333
|
+
return (
|
|
334
|
+
<>
|
|
335
|
+
{paginationData && paginationData?.totalResults !== 0 && (
|
|
336
|
+
<div className="searchstax-pagination-container">
|
|
337
|
+
<div className="searchstax-pagination-content">
|
|
338
|
+
<a
|
|
339
|
+
className="searchstax-pagination-previous"
|
|
340
|
+
style={paginationData?.isFirstPage ? { pointerEvents: "none" } : {}}
|
|
341
|
+
onClick={(e) => {
|
|
342
|
+
previousPage(e);
|
|
343
|
+
}}
|
|
344
|
+
id="searchstax-pagination-previous"
|
|
345
|
+
>
|
|
346
|
+
{" "}
|
|
347
|
+
< Previous{" "}
|
|
348
|
+
</a>
|
|
349
|
+
<div className="searchstax-pagination-details">
|
|
350
|
+
{" "}
|
|
351
|
+
{paginationData?.startResultIndex} - {paginationData?.endResultIndex} of {paginationData?.totalResults}
|
|
352
|
+
</div>
|
|
353
|
+
<a
|
|
354
|
+
className="searchstax-pagination-next"
|
|
355
|
+
style={paginationData?.isLastPage ? { pointerEvents: "none" } : {}}
|
|
356
|
+
onClick={(e) => {
|
|
357
|
+
nextPage(e);
|
|
358
|
+
}}
|
|
359
|
+
id="searchstax-pagination-next"
|
|
360
|
+
>
|
|
361
|
+
Next >
|
|
362
|
+
</a>
|
|
363
|
+
</div>
|
|
274
364
|
</div>
|
|
275
365
|
)}
|
|
276
|
-
|
|
366
|
+
</>
|
|
277
367
|
);
|
|
278
368
|
}
|
|
279
369
|
|
|
370
|
+
<SearchstaxPaginationWidget paginationTemplate={paginationTemplate}></SearchstaxPaginationWidget>
|
|
280
371
|
```
|
|
281
372
|
|
|
373
|
+
### Facets Widget ###
|
|
282
374
|
|
|
283
|
-
|
|
375
|
+
example of facets widget initialization with minimum options
|
|
376
|
+
```
|
|
284
377
|
|
|
285
378
|
```
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
example of facets widget initialization with template overrides
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### SearchFeedback Widget ###
|
|
387
|
+
|
|
388
|
+
example of search feedback widget initialization with minimum options
|
|
389
|
+
```
|
|
390
|
+
<SearchstaxOverviewWidget></SearchstaxOverviewWidget>
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
example of search feedback widget initialization with template overrides
|
|
395
|
+
```
|
|
396
|
+
function searchOverviewTemplate(
|
|
397
|
+
searchFeedbackData: null | ISearchstaxSearchFeedbackData,
|
|
398
|
+
onOriginalQueryClick: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void
|
|
399
|
+
) {
|
|
400
|
+
return (
|
|
401
|
+
<>
|
|
402
|
+
{searchFeedbackData && searchFeedbackData?.searchExecuted && searchFeedbackData?.totalResults && (
|
|
403
|
+
<>
|
|
404
|
+
Showing{" "}
|
|
405
|
+
<b>
|
|
406
|
+
{searchFeedbackData.startResultIndex} - {searchFeedbackData.endResultIndex}
|
|
407
|
+
</b>{" "}
|
|
408
|
+
of
|
|
409
|
+
<b> {searchFeedbackData.totalResults}</b> results
|
|
410
|
+
{searchFeedbackData.searchTerm && (
|
|
411
|
+
<span>
|
|
412
|
+
for "<b>{searchFeedbackData.searchTerm}</b>"{" "}
|
|
413
|
+
</span>
|
|
414
|
+
)}
|
|
415
|
+
<div className="searchstax-feedback-container-suggested">
|
|
416
|
+
{searchFeedbackData.autoCorrectedQuery && (
|
|
417
|
+
<div>
|
|
418
|
+
{" "}
|
|
419
|
+
Search instead for{" "}
|
|
420
|
+
<a
|
|
421
|
+
href="#"
|
|
422
|
+
onClick={(e) => {
|
|
423
|
+
onOriginalQueryClick(e);
|
|
424
|
+
}}
|
|
425
|
+
className="searchstax-feedback-original-query"
|
|
426
|
+
>
|
|
427
|
+
{searchFeedbackData.originalQuery}
|
|
428
|
+
</a>
|
|
429
|
+
</div>
|
|
430
|
+
)}
|
|
431
|
+
</div>
|
|
432
|
+
</>
|
|
433
|
+
)}
|
|
434
|
+
</>
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
<SearchstaxOverviewWidget searchOverviewTemplate={searchOverviewTemplate}></SearchstaxOverviewWidget>
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## RelatedSearches widget
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
example of search feedback widget initialization with minimum options
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
example of search feedback widget initialization with template overrides
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### ExternalPromotions widget ###
|
|
456
|
+
|
|
457
|
+
example of search feedback widget initialization with minimum options
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
example of search feedback widget initialization with template overrides
|
|
464
|
+
```
|
|
465
|
+
|
|
291
466
|
```
|
|
292
467
|
|
|
468
|
+
|
|
469
|
+
### Sorting Widget ###
|
|
470
|
+
|
|
471
|
+
example of sorting widget initialization with minimum options
|
|
472
|
+
```
|
|
473
|
+
<SearchstaxSortingWidget></SearchstaxSortingWidget>
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
example of sorting widget initialization with template override
|
|
478
|
+
```
|
|
479
|
+
function searchSortingTemplate(
|
|
480
|
+
sortingData: null | ISearchstaxSearchSortingData,
|
|
481
|
+
orderChange: (value: string) => void,
|
|
482
|
+
selectedSorting: string
|
|
483
|
+
) {
|
|
484
|
+
return (
|
|
485
|
+
<>
|
|
486
|
+
{sortingData && sortingData?.searchExecuted && sortingData?.hasResultsOrExternalPromotions && (
|
|
487
|
+
<div className="searchstax-sorting-container">
|
|
488
|
+
<label className="searchstax-sorting-label" htmlFor="sort-by">
|
|
489
|
+
Sort By
|
|
490
|
+
</label>
|
|
491
|
+
<select
|
|
492
|
+
id="searchstax-search-order-select"
|
|
493
|
+
className="searchstax-search-order-select"
|
|
494
|
+
value={selectedSorting}
|
|
495
|
+
onChange={(e) => {
|
|
496
|
+
orderChange(e.target.value);
|
|
497
|
+
}}
|
|
498
|
+
>
|
|
499
|
+
<option value=""> Relevance </option>
|
|
500
|
+
<option value="date desc"> Newest Content </option>
|
|
501
|
+
<option value="date asc"> Oldest Content </option>
|
|
502
|
+
</select>
|
|
503
|
+
</div>
|
|
504
|
+
)}
|
|
505
|
+
</>
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
<SearchstaxSortingWidget searchSortingTemplate={searchSortingTemplate}></SearchstaxSortingWidget>
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
## Template overrides
|
|
513
|
+
Templates use vue slots.
|
|
514
|
+
|
|
293
515
|
## STYLING
|
|
294
516
|
|
|
295
517
|
scss styles can be imported from searchstudio-ux-js
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ISearchstaxSuggestProps, ISearchstaxSuggestResponse, ISearchstaxSuggestion } from "@searchstax-inc/searchstudio-ux-js";
|
|
2
2
|
declare function SearchstaxInputWidget(props: {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
afterAutosuggest: (result: ISearchstaxSuggestResponse) => ISearchstaxSuggestResponse;
|
|
6
|
-
beforeAutosuggest: (props: ISearchstaxSuggestProps) => ISearchstaxSuggestProps | null;
|
|
3
|
+
afterAutosuggest?: (result: ISearchstaxSuggestResponse) => ISearchstaxSuggestResponse;
|
|
4
|
+
beforeAutosuggest?: (props: ISearchstaxSuggestProps) => ISearchstaxSuggestProps | null;
|
|
7
5
|
searchInputId?: string;
|
|
8
6
|
suggestAfterMinChars?: number;
|
|
9
|
-
inputTemplate?: () => React.ReactElement;
|
|
10
|
-
}): JSX.Element;
|
|
7
|
+
inputTemplate?: (suggestions: ISearchstaxSuggestion[], onMouseLeave: () => void, onMouseOver: (suggestion: ISearchstaxSuggestion) => void, onMouseClick: () => void) => React.ReactElement;
|
|
8
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
11
9
|
export default SearchstaxInputWidget;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ISearchstaxSearchFeedbackData } from "@searchstax-inc/searchstudio-ux-js";
|
|
2
|
+
declare function SearchstaxOverviewWidget(props: {
|
|
3
|
+
searchOverviewTemplate?: (searchFeedbackData: null | ISearchstaxSearchFeedbackData, onOriginalQueryClick: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void) => React.ReactElement;
|
|
4
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export default SearchstaxOverviewWidget;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IPaginationData } from "@searchstax-inc/searchstudio-ux-js";
|
|
2
|
+
declare function SearchstaxPaginationWidget(props: {
|
|
3
|
+
paginationTemplate?: (paginationData: IPaginationData | null, nextPage: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void, previousPage: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void) => React.ReactElement;
|
|
4
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export default SearchstaxPaginationWidget;
|