-
-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement highlightedtext component #1864
Changes from 3 commits
78d54eb
b5272d1
f82687b
341d18b
92080df
1eb1d94
8757dff
45634f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,3 +77,8 @@ | |
margin: 40px 20px 0 0; | ||
min-width: 330px; | ||
} | ||
|
||
.rsg--heading1-6 { | ||
font-size: 1.2rem; | ||
color: #061C3F; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import React from 'react'; | ||
import { mount } from 'enzyme'; | ||
import styled from 'styled-components'; | ||
import HighlightedText from '../'; | ||
|
||
describe('<HighlightedText />', () => { | ||
const parts = [ | ||
{ | ||
value: 'Apples', | ||
type: 'text', | ||
}, | ||
{ | ||
value: 'varieties', | ||
type: 'hit', | ||
}, | ||
{ | ||
value: 'Honeycrisp', | ||
type: 'text', | ||
}, | ||
]; | ||
it('should return 3 <span> with theirs respective values because the default wrapper is a span', () => { | ||
const component = mount(<HighlightedText parts={parts} />); | ||
const container = component.find('span'); | ||
expect( | ||
container | ||
.at(0) | ||
.html() | ||
.includes('Apples'), | ||
).toBe(true); | ||
expect( | ||
container | ||
.at(1) | ||
.html() | ||
.includes('varieties'), | ||
).toBe(true); | ||
expect( | ||
container | ||
.at(2) | ||
.html() | ||
.includes('Honeycrisp'), | ||
).toBe(true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be cleaner like this const component = mount(<HighlightedText parts={parts} />);
const container = component.find('span');
expect(container.length).toBe(3);
parts.forEach(({ value }, index) => {
expect(
container
.at(index)
.html()
.includes(value),
).toBe(true);
}); |
||
}); | ||
it('should return 3 custom <span> with theirs respective values because the custom wrapper is a span', () => { | ||
const TextContainer = styled.span` | ||
color: grey; | ||
`; | ||
|
||
const HitContainer = styled.span` | ||
color: #fff; | ||
`; | ||
|
||
const component = mount( | ||
<HighlightedText | ||
parts={parts} | ||
textComponent={TextContainer} | ||
hitComponent={HitContainer} | ||
/>, | ||
); | ||
const container = component.find('span'); | ||
expect( | ||
container | ||
.at(0) | ||
.html() | ||
.includes('Apples'), | ||
).toBe(true); | ||
expect( | ||
container | ||
.at(1) | ||
.html() | ||
.includes('varieties'), | ||
).toBe(true); | ||
expect( | ||
container | ||
.at(2) | ||
.html() | ||
.includes('Honeycrisp'), | ||
).toBe(true); | ||
}); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should change these tests to make clearer the difference between a hit and normal text There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this second test you can delete the first the third test all the code |
||
|
||
it('should return a custom <span> with id="hitText" in the container at(1) which corresponds to the text that has a type hit', () => { | ||
const TextContainer = styled.span` | ||
color: grey; | ||
`; | ||
|
||
const HitContainer = styled.span` | ||
color: #fff; | ||
`; | ||
|
||
// eslint-disable-next-line react/prop-types | ||
const hitComponent = ({ children }) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. capitalize the first letter HitComponent |
||
return <HitContainer id="hitText">{children}</HitContainer>; | ||
}; | ||
|
||
const component = mount( | ||
<HighlightedText | ||
parts={parts} | ||
textComponent={TextContainer} | ||
hitComponent={hitComponent} | ||
/>, | ||
); | ||
const container = component.find('span'); | ||
expect(container.at(1).prop('id')).toBe('hitText'); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
|
||
export default function HitText({ | ||
parts, | ||
hitComponent: HitComponent, | ||
textComponent: TextComponent, | ||
}) { | ||
return parts.map((part, index) => { | ||
const key = `part-${index}`; | ||
if (part.type === 'hit') { | ||
return <HitComponent key={key}>{part.value}</HitComponent>; | ||
} | ||
return <TextComponent key={key}>{part.value}</TextComponent>; | ||
}); | ||
} | ||
|
||
HitText.propTypes = { | ||
parts: PropTypes.arrayOf( | ||
PropTypes.exact({ | ||
value: PropTypes.string, | ||
type: PropTypes.string, | ||
}), | ||
), | ||
hitComponent: PropTypes.elementType, | ||
textComponent: PropTypes.elementType, | ||
}; | ||
|
||
HitText.defaultProps = { | ||
parts: undefined, | ||
hitComponent: undefined, | ||
textComponent: undefined, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { ComponentType } from 'react'; | ||
import { BaseProps } from '../types'; | ||
|
||
interface Part { | ||
value?: string; | ||
type?: string; | ||
} | ||
|
||
export interface HighlightedText extends BaseProps { | ||
hitComponent?: ComponentType<{ children?: string }>; | ||
textComponent?: ComponentType<{ children?: string }>; | ||
part?: Part[]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is parts: |
||
} | ||
|
||
export default function(props: HighlightedText): JSX.Element | null; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import HitText from './hitText'; | ||
import { DefaultHitContainer, DefaultTextContainer } from './styled/index'; | ||
|
||
/** | ||
* HighlightedText is a component that highlights a part of a text. | ||
*/ | ||
|
||
LeandroTorresSicilia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
function HighlightedText(props) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when using function declaration you can export directly here like: |
||
const { style, className, parts, hitComponent, textComponent } = props; | ||
const finalHitContainer = hitComponent || DefaultHitContainer; | ||
const finalTextContainer = textComponent || DefaultTextContainer; | ||
|
||
return ( | ||
<p className={className} style={style}> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We need to add a new prop There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add a new example using the |
||
<HitText | ||
parts={parts} | ||
hitComponent={finalHitContainer} | ||
textComponent={finalTextContainer} | ||
/> | ||
</p> | ||
); | ||
} | ||
|
||
export default HighlightedText; | ||
|
||
HighlightedText.propTypes = { | ||
/** The class of the component. */ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In order to be consistent, we should use the same description that we use in other components |
||
className: PropTypes.string, | ||
/** An object with the custom styles of the container. */ | ||
style: PropTypes.object, | ||
/** An array of objects with the text and the part to be highlighted */ | ||
parts: PropTypes.arrayOf( | ||
PropTypes.exact({ | ||
value: PropTypes.string, | ||
type: PropTypes.string, | ||
}), | ||
), | ||
/** | ||
* The component class or function that is going to be use to render | ||
* the highlighted text | ||
*/ | ||
hitComponent: PropTypes.elementType, | ||
/** | ||
* The component class or function that is going to be use to render | ||
* the text not highlighted | ||
*/ | ||
textComponent: PropTypes.elementType, | ||
LeandroTorresSicilia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}; | ||
|
||
HighlightedText.defaultProps = { | ||
className: undefined, | ||
style: undefined, | ||
parts: undefined, | ||
hitComponent: undefined, | ||
textComponent: undefined, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# HighlightedText base | ||
##### This example shows the style that is applied by default to the component. | ||
```js | ||
import React, { useState } from 'react'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. useState is not used in the example |
||
import { HighlightedText } from 'react-rainbow-components'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. identation |
||
|
||
const style = { | ||
maxWidth:"700px", | ||
textAlign:"center", | ||
padding:"20px", | ||
margin:"auto", | ||
LeandroTorresSicilia marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use single quotes and add a space after the : symbol like: |
||
}; | ||
|
||
const parts = [ | ||
{ | ||
"value" : "Apples come in several ", | ||
"type" : "text" | ||
}, | ||
{ | ||
"value" : "varieties", | ||
"type" : "hit" | ||
}, | ||
{ | ||
"value" : ", including Fuji, Granny Smith, and Honeycrisp.", | ||
"type" : "text" | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation |
||
]; | ||
|
||
<HighlightedText parts={parts} style={style} /> | ||
|
||
``` | ||
|
||
# HighlightedText with custom styles | ||
##### This example shows the component when custom styles are applied to it. | ||
|
||
```js | ||
import React, { useState } from 'react'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same before |
||
import styled from 'styled-components'; | ||
import { HighlightedText } from 'react-rainbow-components'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation |
||
|
||
const style = { | ||
maxWidth: '700px', | ||
textAlign: 'center', | ||
padding: '20px', | ||
margin: 'auto', | ||
}; | ||
|
||
const parts = [ | ||
{ | ||
"value" : "Apples come in several ", | ||
"type" : "text" | ||
}, | ||
{ | ||
"value" : "varieties", | ||
"type" : "hit" | ||
}, | ||
{ | ||
"value" : ", including Fuji, Granny Smith, and Honeycrisp.", | ||
"type" : "text" | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation |
||
]; | ||
|
||
const TextContainer = styled.span` | ||
color: gray; | ||
font-size: 1rem; | ||
`; | ||
|
||
const HitContainer = styled.span` | ||
background-color: #00a3dc; | ||
color: #fff; | ||
font-size: 1rem; | ||
`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be better to use the theme colors for this example |
||
|
||
<HighlightedText parts={parts} style={style} textComponent={TextContainer} hitComponent={HitContainer}/> | ||
|
||
``` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import styled from 'styled-components'; | ||
import attachThemeAttrs from '../../../styles/helpers/attachThemeAttrs'; | ||
|
||
export const DefaultHitContainer = attachThemeAttrs(styled.span)` | ||
LeandroTorresSicilia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
color: ${props => props.palette.text.main}; | ||
font-weight: bold; | ||
font-size: 1rem; | ||
LeandroTorresSicilia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
font-family: 'Lato Black'; | ||
`; | ||
|
||
export const DefaultTextContainer = attachThemeAttrs(styled.span)` | ||
LeandroTorresSicilia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
color: ${props => props.palette.text.main}; | ||
font-size: 1rem; | ||
`; |
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.
HighlightedText.spec.js change to highlightedText.spec.js