🎨 Recherche : surlignage fuzzy matching

pull/878/head
Loïc Guillois 2020-02-10 18:42:21 +01:00
parent d18cdd5205
commit 130b2c06d9
4 changed files with 99 additions and 34 deletions

View File

@ -40,8 +40,8 @@
"react-color": "^2.14.0",
"react-dom": "npm:@hot-loader/react-dom",
"react-easy-emoji": "^1.2.0",
"react-fuzzy-highlighter": "^0.3.1",
"react-helmet": "6.0.0-beta",
"react-highlight-words": "^0.11.0",
"react-i18next": "^11.0.0",
"react-loading-skeleton": "^1.1.2",
"react-markdown": "^4.1.0",

View File

@ -2,7 +2,7 @@ import { SitePathsContext } from 'Components/utils/withSitePaths'
import { parentName } from 'Engine/rules.js'
import { pick, sortBy, take } from 'ramda'
import React, { useContext, useEffect, useState } from 'react'
import Highlighter from 'react-highlight-words'
import FuzzyHighlighter, { Highlighter } from 'react-fuzzy-highlighter'
import { useTranslation } from 'react-i18next'
import { Link, Redirect, useHistory } from 'react-router-dom'
import { Rule } from 'Types/rule'
@ -59,6 +59,12 @@ export default function SearchBar({
let renderOption = (option: Option) => {
let { title, dottedName, name } = option
let espace = parentName(dottedName)
? parentName(dottedName)
.split(' . ')
.map(capitalise0)
.join(' - ')
: ''
return (
<li
key={dottedName}
@ -82,24 +88,76 @@ export default function SearchBar({
lineHeight: '.9em'
}}
>
<Highlighter
searchWords={[input]}
textToHighlight={
parentName(dottedName)
? parentName(dottedName)
.split(' . ')
.map(capitalise0)
.join(' - ')
: ''
}
/>
<FuzzyHighlighter
query={input}
data={[
{
title: espace
}
]}
options={{
includeMatches: true,
threshold: 0.2,
minMatchCharLength: 1,
keys: ['title']
}}
>
{({ results, formattedResults, timing }) => {
return (
<>
{formattedResults.length === 0 && <span>{espace}</span>}
{formattedResults.map((formattedResult, resultIndex) => {
if (formattedResult.formatted.title === undefined) {
return null
}
return (
<span key={resultIndex}>
<Highlighter text={formattedResult.formatted.title} />
</span>
)
})}
</>
)
}}
</FuzzyHighlighter>
</div>
<Link to={sitePaths.documentation.rule(dottedName)}>
<Highlighter
searchWords={[input]}
textToHighlight={title || capitalise0(name) || ''}
/>
</Link>
<FuzzyHighlighter
query={input}
data={[{ title: title || capitalise0(name) || '' }]}
options={{
includeMatches: true,
threshold: 0.3,
keys: ['title', 'name']
}}
>
{({ results, formattedResults, timing }) => {
return (
<>
{formattedResults.length === 0 && (
<Link to={sitePaths.documentation.rule(dottedName)}>
{title || capitalise0(name) || ''}
</Link>
)}
{formattedResults.map((formattedResult, resultIndex) => {
if (formattedResult.formatted.title === undefined) {
return null
}
return (
<Link
to={sitePaths.documentation.rule(dottedName)}
key={resultIndex}
>
<Highlighter text={formattedResult.formatted.title} />
</Link>
)
})}
</>
)
}}
</FuzzyHighlighter>
</li>
)
}

View File

@ -22,7 +22,6 @@ export default function SearchButton({ invisibleButton }: SearchButtonProps) {
return false
}
window.addEventListener('keydown', handleKeyDown)
return () => {
window.removeEventListener('keydown', handleKeyDown)
}

View File

@ -4835,7 +4835,7 @@ functions-have-names@^1.2.0:
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.0.tgz#83da7583e4ea0c9ac5ff530f73394b033e0bf77d"
integrity sha512-zKXyzksTeaCSw5wIX79iCA40YAa6CJMJgNg9wdkU/ERBrIdPSimPICYiLp65lRbSBqtiHql/HZfS2DyI/AH6tQ==
fuse.js@^3.4.2:
fuse.js@^3.4.2, fuse.js@^3.4.5:
version "3.4.6"
resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.6.tgz#545c3411fed88bf2e27c457cab6e73e7af697a45"
integrity sha512-H6aJY4UpLFwxj1+5nAvufom5b2BT2v45P1MkPvdGIK8fWjQx/7o6tTT1+ALV0yawQvbmvCF0ufl2et8eJ7v7Cg==
@ -5190,11 +5190,6 @@ he@1.2.x, he@^1.1.0, he@^1.1.1:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
highlight-words-core@^1.2.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/highlight-words-core/-/highlight-words-core-1.2.2.tgz#1eff6d7d9f0a22f155042a00791237791b1eeaaa"
integrity sha512-BXUKIkUuh6cmmxzi5OIbUJxrG8OAk2MqoL1DtO3Wo9D2faJg2ph5ntyuQeLqaHJmzER6H5tllCDA9ZnNe9BVGg==
highlight.js@~9.13.0:
version "9.13.1"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.13.1.tgz#054586d53a6863311168488a0f58d6c505ce641e"
@ -8867,6 +8862,15 @@ react-fast-compare@^2.0.2:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
react-fuzzy-highlighter@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/react-fuzzy-highlighter/-/react-fuzzy-highlighter-0.3.1.tgz#8359e0298e12203a39ecd954ffce3679b7a67190"
integrity sha512-s+HSr8/tZdDXprkxEBi80O0dFFPkO/d4RUFKaiw9FE4oV6hfnj/pFvFuyqGhnUS0AeTMj36WUCKdMlsq/jtyyQ==
dependencies:
fuse.js "^3.4.5"
set-value "^3.0.1"
strind "^0.3.0"
react-helmet@6.0.0-beta:
version "6.0.0-beta"
resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.0.0-beta.tgz#1f2ac04521951486e4fce3296d0c88aae8cabd5c"
@ -8877,14 +8881,6 @@ react-helmet@6.0.0-beta:
react-fast-compare "^2.0.2"
react-side-effect "^1.1.0"
react-highlight-words@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/react-highlight-words/-/react-highlight-words-0.11.0.tgz#4f3c2039a8fd275f3ab795e59946b0324d8e6bee"
integrity sha512-b+fgdQXNjX6RwHfiBYn6qH2D2mJEDNLuxdsqRseIiQffoCAoj7naMQ5EktUkmo9Bh1mXq/aMpJbdx7Lf2PytcQ==
dependencies:
highlight-words-core "^1.2.0"
prop-types "^15.5.8"
react-hot-loader@^4.12.15:
version "4.12.18"
resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.18.tgz#a9029e34af2690d76208f9a35189d73c2dfea6a7"
@ -9825,6 +9821,13 @@ set-value@^2.0.0, set-value@^2.0.1:
is-plain-object "^2.0.3"
split-string "^3.0.1"
set-value@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/set-value/-/set-value-3.0.1.tgz#52c82af7653ba69eb1db92e81f5cdb32739b9e95"
integrity sha512-w6n3GUPYAWQj4ZyHWzD7K2FnFXHx9OTwJYbWg+6nXjG8sCLfs9DGv+KlqglKIIJx+ks7MlFuwFW2RBPb+8V+xg==
dependencies:
is-plain-object "^2.0.4"
setimmediate@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@ -10145,6 +10148,11 @@ strict-uri-encode@^1.0.0:
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=
strind@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/strind/-/strind-0.3.1.tgz#1971292da9c45caeac1a4d86324da20f4a417cda"
integrity sha512-GDpPHZTkWMZcYesCF5MoUR38mQa6n0oo6V8ZBoIeU5pCJevbxmHISFRWy1qheVPZhNm3syOG2m0Hn9QMuIugHg==
string-length@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed"