React Valu Search UI
The npm package @valu/react-valu-search
.
API
SlotRendered types used
interface SlotRenderer<Params = {}> {
(context: {
params: Params;
original: React.ReactNode;
config: ValuSearchConfig;
}): any;
}
API Usage Example
// You can subscribe to events with a callback function passed to renderMultiSearchResults
// Here we add/remove search-open from body class on open/close event
function handleValuSearchEvent(event: ValuSearchEvent) {
if (event.name === "closed") {
document.body.classList.remove("search-open");
} else if (event.name === "opened") {
document.body.classList.add("search-open");
}
}
renderMultiSearchResults({
searchEndpoint: "https://search-enpoint.example",
apiKey: "exampleapikey",
orderBy: "score",
mode: "fullScreen",
tagGroups: [
{
// tagGroupIds can be used in slotOverrides for displaying different hit components in different groups
tagGroupId: "AdditionalUniqueIdentifier",
title: "Demoting group position",
// scoreBoost should be positive number, it is multiplied with score so values < 1 demote content
scoreBoost: 0.01,
filters: {
tagQuery: [["pdf"]],
},
}
{
title: "Boosting group position",
// scoreBoost > 1 boost content
scoreBoost: 100,
filters: {
tagQuery: [["pdf"]],
},
},
{
title: "OR-Query",
filters: {
// [[stringA, stringB]] ==> "stringA" OR "stringB"
tagQuery: [["wp_post_type/post", "wp_post_type/page"]],
},
},
{
title: "AND-Query",
filters: {
// [[stringA],[stringB]] ==> "stringA" AND "stringB"
tagQuery: [["wp_post_type/post"], ["wp_post_type/page"]],
},
},
{
title: "Decay old posts",
filters: {
// "Posts created 7 days ago are half as relevant"
// Posts's relevancy gets multiplied by value from exponential curve
tagQuery: [["wp_post_type/post"]],
createdDecay: 0.5,
decayScale: "7d",
},
},
{
title: "Decay stagnant posts",
filters: {
// "Posts modified 7 days ago are half as relevant"
// Posts's relevancy gets multiplied by value from exponential curve
tagQuery: [["wp_post_type/post"]],
modifiedDecay: 0.5,
decayScale: "7d",
},
},
],
// Passing an empty string removes the text from UI
uiStrings: {
moreResults: "Näytä lisää hakutuloksia",
allShown: "Kaikki tulokset esitetty",
back: "Takaisin",
noResults: "Ei hakutuloksia",
close: "",
},
// Defining the callback function and passing the event
onEvent: (event: ValuSearchEvent) => handleValuSearchEvent(event),
// slotOverrides allows for customizable UI on a block level, this needs to be in react syntax
// Passing context is always required
slotOverrides: {
// define slot to modify
hit(context) {
// using tagGroupId for making different search result components
if(context.params.tagGroupId === "foo"){
return (
<div className="SearchResult">
// ready made helper components for easier modification
<SearchResultDate date={context.params.created} />
<SearchResultTitle
title={context.params.title}
url={context.params.url}
/>
<SearchResultExcerpt highlight={context.params.highlight} />
<SearchResultUrl
title={context.params.title}
url={context.params.url}
/>
</div>
);
} else {
<Hit {...context.params} date={context.params.modified}></Hit>
}
},
mainWrap(context) {
// You can wrap and replace different slots of the UI. Even the whole UI
return (
<div className="ResultUi">
<div className="ResultUi__Header bemed"></div>
<div className="ResultUi__Original">{context.original}</div>
<div className="ResultUi__Footer bemed"></div>
</div>
);
},
},
});
Local hacking and Cypress testing
Install deps in repository root
pnpm install
Install deps for Valu Search backend too and make sure Elasticsearch is running
Seed the index
pnpm run seed
Start all tools
pnpm run dev
Open http://localhost:8080/ and hack on src
To run Cypress tests hit "Run all specs" from the UI.
Event hacking and testing
Listen to events with
document.addEventListener("valu-search-event", (e) => {
console.log(e.valuSearchEvent);
});
The available event types are defined in the ValuSearchEvent
union.
https://github.com/valu-digital/valu-search/blob/master/frontend/npm/src/events.ts
Hacking with an external project
npm ci
npm link
npm run watch-build
and in your project
npm link @valu/react-valu-search
Sometimes this causes errors, (react being imported multiple times) Edit project webpack.config.js to include
const path = require("path")
...
config => {
config.resolve.alias = {
jquery: __dirname + "/assets/scripts/lib/jquery.js",
react: path.resolve("./node_modules/react"),
"react-dom": path.resolve("./node_modules/react-dom"),
};
},
Making new npm releases
On clean master branch run
pnpm run release
This will ask for a new version number, commits it to package.json, runs build and tests, pushes to the master branch and a Github Action will make a npm release automatically from it.
You can see the release process here https://github.com/valu-digital/valu-search/actions