{
  "name": "@valu/react-valu-search",
  "version": "21.1.1",
  "description": "Valu Search React UI",
  "main": "dist/valu-search.js",
  "typings": "dist/index.d.ts",
  "files": [
    "dist",
    "loader.js",
    "loader.d.ts",
    "polyfill.js",
    "polyfill.d.ts",
    "lazy"
  ],
  "author": "Valu Digital Oy",
  "browserslist": [
    "last 1 chrome version",
    "IE 11"
  ],
  "peerDependencies": {
    "react": "16.x ||  17.x || 18.x"
  },
  "devDependencies": {
    "@babel/core": "^7.16.7",
    "@babel/preset-env": "^7.16.7",
    "@babel/preset-typescript": "^7.16.7",
    "@cypress/webpack-preprocessor": "^4.1.5",
    "@findkit/dev": "0.0.0",
    "@findkit/eslint-config": "^0.0.0",
    "@jest/globals": "^27.4.4",
    "@testing-library/dom": "^7.31.2",
    "@testing-library/user-event": "^12.8.3",
    "@types/jest": "^26.0.24",
    "@types/mocha": "^7.0.2",
    "@types/node": "^14.18.4",
    "@types/react": "^17.0.38",
    "@types/react-dom": "^17.0.11",
    "@types/react-redux": "^7.1.21",
    "@typescript-eslint/eslint-plugin": "5.10.1",
    "@typescript-eslint/parser": "^5.10.1",
    "@valu/npm-tools": "^1.0.0",
    "@valu/webpack-config": "^0.15.3",
    "babel-jest": "^26.6.3",
    "concurrently": "^6.5.1",
    "core-js": "^3.20.2",
    "cypress": "^8.7.0",
    "eslint": "8.7.0",
    "eslint-plugin-react": "^7.28.0",
    "eslint-plugin-react-hooks": "^4.3.0",
    "husky": "^3.1.0",
    "jake": "^10.8.2",
    "jest": "^26.6.3",
    "microbundle": "^0.14.2",
    "prettier": "2.5.1",
    "react": "^16.14.0",
    "react-dom": "^16.14.0",
    "sh-thunk": "^0.3.2",
    "ts-loader": "^6.2.2",
    "typescript": "4.5.5",
    "unfetch": "^4.2.0",
    "webpack": "^4.46.0"
  },
  "dependencies": {
    "@epeli/redux-stack": "^0.8.2",
    "@findkit/fetch": "1.1.0",
    "@types/node-fetch": "^2.5.12",
    "@valu/focus-trap": "^0.0.13",
    "immer": "^9.0.7",
    "immer-reducer": "^0.7.13",
    "react-bemed": "^1.0.5",
    "react-redux": "^7.2.6",
    "redux": "^4.1.2"
  },
  "license": "ISC",
  "volta": {
    "node": "14.19.2"
  },
  "scripts": {
    "dev": "jake dev-test-app",
    "watch": "jake watch",
    "test": "findkit-tsc && jest && findkit-eslint",
    "build": "jake build",
    "release": "valu-npm-release",
    "prerelease": "valu-npm-prerelease",
    "cypress": "cypress open",
    "seed": "jake seed",
    "prettier-write": "findkit-prettier-write",
    "prettier-check": "findkit-prettier-check",
    "tsc": "findkit-tsc",
    "eslint": "findkit-eslint",
    "jest": "findkit-jest",
    "turbo-build": "findkit-turbo-build",
    "publish-build": "findkit-turbo-build"
  },
  "readme": "# React Valu Search UI\n\nThe npm package `@valu/react-valu-search`.\n\n## API\n\n[Valu Search Config Interface](https://github.com/valu-digital/valu-search/blob/master/packages/react-ui/src/config.ts)\n\n[Valu Search Event types used](https://github.com/valu-digital/valu-search/blob/master/packages/react-ui/src/events.ts)\n\nSlotRendered types used\n\n```ts\ninterface SlotRenderer<Params = {}> {\n    (context: {\n        params: Params;\n        original: React.ReactNode;\n        config: ValuSearchConfig;\n    }): any;\n}\n```\n\n### API Usage Example\n\n```ts\n// You can subscribe to events with a callback function passed to renderMultiSearchResults\n// Here we add/remove search-open from body class on open/close event\nfunction handleValuSearchEvent(event: ValuSearchEvent) {\n    if (event.name === \"closed\") {\n        document.body.classList.remove(\"search-open\");\n    } else if (event.name === \"opened\") {\n        document.body.classList.add(\"search-open\");\n    }\n}\n\nrenderMultiSearchResults({\n    searchEndpoint: \"https://search-enpoint.example\",\n    apiKey: \"exampleapikey\",\n    orderBy: \"score\",\n    mode: \"fullScreen\",\n    tagGroups: [\n        {\n            // tagGroupIds can be used in slotOverrides for displaying different hit components in different groups\n            tagGroupId: \"AdditionalUniqueIdentifier\",\n            title: \"Demoting group position\",\n            // scoreBoost should be positive number, it is multiplied with score so values < 1 demote content\n            scoreBoost: 0.01,\n            filters: {\n                tagQuery: [[\"pdf\"]],\n            },\n        }\n        {\n            title: \"Boosting group position\",\n            // scoreBoost > 1 boost content\n            scoreBoost: 100,\n            filters: {\n                tagQuery: [[\"pdf\"]],\n            },\n        },\n        {\n            title: \"OR-Query\",\n            filters: {\n                // [[stringA, stringB]] ==> \"stringA\" OR \"stringB\"\n                tagQuery: [[\"wp_post_type/post\", \"wp_post_type/page\"]],\n            },\n        },\n        {\n            title: \"AND-Query\",\n            filters: {\n                // [[stringA],[stringB]] ==> \"stringA\" AND \"stringB\"\n                tagQuery: [[\"wp_post_type/post\"], [\"wp_post_type/page\"]],\n            },\n        },\n        {\n            title: \"Decay old posts\",\n            filters: {\n                // \"Posts created 7 days ago are half as relevant\"\n                // Posts's relevancy gets multiplied by value from exponential curve\n                tagQuery: [[\"wp_post_type/post\"]],\n                createdDecay: 0.5,\n                decayScale: \"7d\",\n            },\n        },\n                {\n            title: \"Decay stagnant posts\",\n            filters: {\n                // \"Posts modified 7 days ago are half as relevant\"\n                // Posts's relevancy gets multiplied by value from exponential curve\n                tagQuery: [[\"wp_post_type/post\"]],\n                modifiedDecay: 0.5,\n                decayScale: \"7d\",\n            },\n        },\n    ],\n    // Passing an empty string removes the text from UI\n    uiStrings: {\n        moreResults: \"Näytä lisää hakutuloksia\",\n        allShown: \"Kaikki tulokset esitetty\",\n        back: \"Takaisin\",\n        noResults: \"Ei hakutuloksia\",\n        close: \"\",\n    },\n    // Defining the callback function and passing the event\n    onEvent: (event: ValuSearchEvent) => handleValuSearchEvent(event),\n    // slotOverrides allows for customizable UI on a block level, this needs to be in react syntax\n    // Passing context is always required\n    slotOverrides: {\n        // define slot to modify\n        hit(context) {\n            // using tagGroupId for making different search result components\n            if(context.params.tagGroupId === \"foo\"){\n                return (\n                    <div className=\"SearchResult\">\n                        // ready made helper components for easier modification\n                        <SearchResultDate date={context.params.created} />\n                        <SearchResultTitle\n                            title={context.params.title}\n                            url={context.params.url}\n                        />\n                        <SearchResultExcerpt highlight={context.params.highlight} />\n                        <SearchResultUrl\n                            title={context.params.title}\n                            url={context.params.url}\n                        />\n                    </div>\n                );\n            } else {\n                <Hit {...context.params} date={context.params.modified}></Hit>\n            }\n\n        },\n        mainWrap(context) {\n            // You can wrap and replace different slots of the UI. Even the whole UI\n            return (\n                <div className=\"ResultUi\">\n                    <div className=\"ResultUi__Header bemed\"></div>\n                    <div className=\"ResultUi__Original\">{context.original}</div>\n                    <div className=\"ResultUi__Footer bemed\"></div>\n                </div>\n            );\n        },\n    },\n});\n```\n\n## Local hacking and Cypress testing\n\nInstall deps in repository root\n\n    pnpm install\n\nInstall deps for Valu Search backend too and make sure Elasticsearch is running\n\nSeed the index\n\n    pnpm run seed\n\nStart all tools\n\n    pnpm run dev\n\nOpen <http://localhost:8080/> and hack on src\n\nTo run Cypress tests hit \"Run all specs\" from the UI.\n\n## Event hacking and testing\n\nListen to events with\n\n```ts\ndocument.addEventListener(\"valu-search-event\", (e) => {\n    console.log(e.valuSearchEvent);\n});\n```\n\nThe available event types are defined in the `ValuSearchEvent` union.\n\n<https://github.com/valu-digital/valu-search/blob/master/frontend/npm/src/events.ts>\n\n## Hacking with an external project\n\n    npm ci\n    npm link\n    npm run watch-build\n\nand in your project\n\n    npm link @valu/react-valu-search\n\nSometimes this causes errors, (react being imported multiple times)\nEdit project webpack.config.js to include\n\n```\nconst path = require(\"path\")\n...\n    config => {\n        config.resolve.alias = {\n            jquery: __dirname + \"/assets/scripts/lib/jquery.js\",\n            react: path.resolve(\"./node_modules/react\"),\n            \"react-dom\": path.resolve(\"./node_modules/react-dom\"),\n        };\n    },\n```\n\n## Making new npm releases\n\nOn clean master branch run\n\n    pnpm run release\n\nThis will ask for a new version number, commits it to package.json, runs\nbuild and tests, pushes to the master branch and a Github Action will make a\nnpm release automatically from it.\n\nYou can see the release process here <https://github.com/valu-digital/valu-search/actions>\n"
}