-
Notifications
You must be signed in to change notification settings - Fork 386
feat(Highlight): support array of strings #715
Conversation
Deploy preview ready! Built with commit 268a5ac |
docgen/plugins/rev-assets.js
Outdated
string | ||
>): Promise<*> { | ||
function computeFiles( | ||
[filesGlob, replaceFilesGlob]: Array<string, string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like a different version of prettier was run over the code base
Highlighter.defaultProps = { | ||
tagName: 'em', | ||
nonHighlightedTagName: 'span', | ||
separator: ',', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default should be ,<space>
e0fd5c4
to
8d838d2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work @marielaures! 🙂
I left few comments, but no blockers for me.
@@ -1,35 +1,75 @@ | |||
import PropTypes from 'prop-types'; | |||
import React from 'react'; | |||
import classNames from './classNames.js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need the .js
at the end of the import.
@@ -11,4 +11,6 @@ Highlight.propTypes = { | |||
attributeName: PropTypes.string.isRequired, | |||
highlight: PropTypes.func.isRequired, | |||
tagName: PropTypes.string, | |||
nonHighlightedTagName: PropTypes.string, | |||
separator: PropTypes.string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should match the PropTypes
on Highlighter
(aka: node
). We also should rename separator
for separatorComponent
. For example in SearchBox
all custom components are prefix with Component
(ex: ResetComponent
, SubmitComponent
). And finally we need to replicate the props
on the Snippet
component.
<span key={`split-${i}-${hit[attributeName][i]}`}> | ||
{item.map((element, index) => ( | ||
<Highlight | ||
key={`split-${index}-${element.value}`} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can extract the key generation in a function since we use it tree times.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The key generation is slightly different, since in one case we're accessing an element of an array (hit[attributeName][i]
) and for the case where attributeName
is a string, we do element.value
. Do I do a function a maybe pass an attribute which will be a Boolean to specify whether it is an array and return either the first option or the second or leave it as is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, you can simply create function that takes (index, value)
as parameters. Then you called it with the according values (ex: element.value
, hit[attributeName][i]
).
@@ -14,7 +14,7 @@ import { get } from 'lodash'; | |||
* @param {string} highlightProperty - the property that contains the highlight structure in the results | |||
* @param {string} attributeName - the highlighted attribute to look for | |||
* @param {object} hit - the actual hit returned by Algolia. | |||
* @return {object[]} - An array of {value: string, isDefined: boolean}. | |||
* @return {object[]} - An array of {value: string, isDefined: boolean}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can update the documentation, it's isHighlighted
instead of isDefined
.
postTag, | ||
highlightedValue: item.value, | ||
}) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ternary complicate a bit the comprehension of the function. We can revert back to a simpler if
statement.
8fd36cc
to
ae8418a
Compare
return `split-${i}-${value}`; | ||
} | ||
|
||
export const Highlight = ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we export this as a component and then test the rendering out of it? So we freeze the implementation. Right now we are only testing that Highlight is called with some props, not the actual rendering of it (because it's shallow rendered in Highlighter.test.js)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by freezing the implementation? Highlight
is tested separately so we don't need to do a full DOM rendering in Highlighter
. We can just test that the the correct props are applied on the component. I think it's easier to reason about unit, rather than the all implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I meant is that right no there's no test ensuring that the output of this single Highlight component is some specific DOM.
Which means that if we change the output without even touching the props being passed, nothing will break, while the public API contract will break (DOM will change).
If that's not clear still let me know
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope perfectly clear! But we already test the output of the Highlight
component.
react-instantsearch/packages/react-instantsearch/src/components/Highlighter.test.js
Lines 11 to 39 in f3522ad
describe('Highlighter - Highlight', () => { | |
const defaultProps = { | |
value: 'test', | |
highlightedTagName: 'em', | |
isHighlighted: false, | |
nonHighlightedTagName: 'div', | |
}; | |
it('renders a highlight', () => { | |
const props = { | |
...defaultProps, | |
isHighlighted: true, | |
}; | |
const wrapper = shallow(<Highlight {...props} />); | |
expect(wrapper).toMatchSnapshot(); | |
}); | |
it('renders a nonhighlight', () => { | |
const props = { | |
...defaultProps, | |
}; | |
const wrapper = shallow(<Highlight {...props} />); | |
expect(wrapper).toMatchSnapshot(); | |
}); | |
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
return `split-${i}-${value}`; | ||
} | ||
|
||
export const Highlight = ({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One last thing, we can update the connectHighlight
documentation. First we can add attributeName
, hit
, highlightProperty
to the section "Exposed Props". They are required since the provided prop highlight
doesn't work without them. We can also rewrite the example because it's a bit complicated to understand how it works with the current code snippet.
Last, we can also precise that the highlight
prop can now return a nested array depending on the shape of the highlighted property.
7f7bb50
to
c8be162
Compare
<a name="4.3.0"></a> * reset page with multi index ([#665](#665)) ([865b7dc](865b7dc)) * **SearchBox:** use hidden over style to hide loader ([#714](#714)) ([ed5eb77](ed5eb77)) * test recipes ([#740](#740)) ([de2cc37](de2cc37)) * track all index in the manager ([#660](#660)) ([793502b](793502b)) * loading indicator ([#544](#544)) ([189659e](189659e)) * **Highlight:** support array of strings ([#715](#715)) ([8e93c6a](8e93c6a))
Summary
This PR fixes #22.
Before this, the Highlight widget was only compatible with strings.
Now we've added support for arrays of strings.
Result
The
Highlight
widget is used in the same way for attribute names that point to either a string or an array of strings.In the following example we have two Highlight widgets, the first one for
attributeName="name"
wherehit.name
is a string, and the second one forattributeName="tags"
wherehit.tags
is an array of strings (tags: ["Ancient Egypt", "Online Course", "History"]
):