-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ReadMore): ReadMore Component refactored (#180)
- Loading branch information
1 parent
a4705cb
commit 4fb8b86
Showing
8 changed files
with
276 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,37 @@ | ||
Links are typically used as a means of navigation either within the application, to a place outside, or to a resource. For anything else, especially things that change data and actions, you should be using a button. | ||
|
||
Links can have the same properties as an `<a>`-Element. | ||
Using the **ReadMore** component is a simple way to keep longer content from cluttering up your page, giving you more control over how much content is displayed to visitors. | ||
|
||
### Use with react-router | ||
### Use with custom content for collapsed and expanded state | ||
|
||
Use the Link styling by adding the className `wfp--link` to `<NavLink />` | ||
The `collapsed` props content will be displayed if the content is collapsed. | ||
```js | ||
<ReadMore collapsed="Collapsed content"> | ||
Expanded content | ||
</ReadMore> | ||
``` | ||
### Truncate text | ||
|
||
Based on the type of content use [react-truncate](https://www.npmjs.com/package/react-truncate) or [react-truncate-html](https://www.npmjs.com/package/react-truncate-html) to truncate the collapsed content. | ||
|
||
```js | ||
<NavLink className="wfp--link">Link</NavLink> | ||
import Truncate from 'react-truncate'; | ||
``` | ||
|
||
```js | ||
<ReadMore | ||
collapsed={ | ||
<Truncate lines={1} ellipsis="...">{moreText}</Truncate> | ||
} | ||
> | ||
Expanded content | ||
</ReadMore> | ||
``` | ||
|
||
### Fade & animate | ||
|
||
The `maxHeight` prop will allow the content to be collapsed if it extends a specific height. It will only work without the `collapsed` prop. | ||
```js | ||
<ReadMore fade maxHeight={30}> | ||
The content | ||
</ReadMore> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,150 @@ | ||
import PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import React, { Component } from 'react'; | ||
import classnames from 'classnames'; | ||
|
||
import Truncate from 'react-truncate-html'; | ||
import Link from '../Link'; | ||
import { iconCaretUp, iconCaretDown } from '@wfp/icons'; | ||
import Icon from '../Icon'; | ||
import classNames from 'classnames'; | ||
import settings from '../../globals/js/settings'; | ||
|
||
class ReadMore extends React.Component { | ||
const { prefix } = settings; | ||
|
||
const MoreLink = ({ handleToggleClick, link, text, showMore }) => { | ||
if (link) { | ||
var clonedLink = React.cloneElement(link, { | ||
onClick: handleToggleClick, | ||
}); | ||
return clonedLink; | ||
} else { | ||
return ( | ||
<Link | ||
className={`${prefix}--read-more__trigger`} | ||
small | ||
onClick={handleToggleClick}> | ||
{text} | ||
<Icon | ||
icon={showMore ? iconCaretUp : iconCaretDown} | ||
width="10" | ||
height="10" | ||
description={showMore ? 'icon up' : 'icon down'} | ||
/> | ||
</Link> | ||
); | ||
} | ||
}; | ||
|
||
export default class ReadMore extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = { showMore: false }; | ||
this.state = { | ||
showMore: false, | ||
innerHeight: 0, | ||
}; | ||
} | ||
|
||
static propTypes = { | ||
/** | ||
* Specify an optional className to be applied to the wrapper node | ||
*/ | ||
className: PropTypes.string, | ||
/** | ||
* The content of the expanded element | ||
*/ | ||
children: PropTypes.node.isRequired, | ||
/** | ||
* The content of the collapsed content (optional) | ||
*/ | ||
collapsed: PropTypes.node, | ||
/** | ||
* A custom link for collapsing | ||
*/ | ||
collapseLink: PropTypes.node, | ||
/** | ||
* A custom link for expanding | ||
*/ | ||
expandLink: PropTypes.node, | ||
/** | ||
* Enables the fade effect when the content is collapsed (optional) when enabled collapsed will be ignored | ||
*/ | ||
fade: PropTypes.bool, | ||
/** | ||
* The maximum height when the content is collapsed (optional) | ||
*/ | ||
maxHeight: PropTypes.number, | ||
}; | ||
|
||
static defaultProps = { | ||
expandText: 'Read more', | ||
collapseText: 'Read less', | ||
}; | ||
|
||
handleToggleClick = e => { | ||
e.preventDefault(); | ||
const innerHeight = this.divElement.clientHeight; | ||
this.setState(prevState => ({ | ||
showMore: !prevState.showMore, | ||
innerHeight: innerHeight, | ||
})); | ||
}; | ||
|
||
render() { | ||
const { collapsed, className, expanded, moreText, html } = this.props; | ||
const { showMore } = this.state; | ||
const { | ||
collapseLink, | ||
collapseText, | ||
children, | ||
collapsed, | ||
className, | ||
expandLink, | ||
expandText, | ||
fade, | ||
maxHeight, | ||
} = this.props; | ||
const { innerHeight, showMore } = this.state; | ||
|
||
const classNames = classnames(className, { | ||
[`${prefix}--read-more`]: true, | ||
[`${prefix}--read-more--expanded`]: showMore, | ||
[`${prefix}--read-more--fade`]: fade, | ||
[`${prefix}--read-more--max-height`]: maxHeight, | ||
}); | ||
|
||
const contentStyle = !maxHeight | ||
? { | ||
undefined, | ||
} | ||
: maxHeight && !showMore | ||
? { | ||
maxHeight: maxHeight, | ||
} | ||
: { | ||
maxHeight: innerHeight + 20, | ||
}; | ||
|
||
const classNames = classnames('wfp--readmore', className); | ||
const collapseStyle = showMore | ||
? { | ||
display: 'none', | ||
} | ||
: { | ||
display: 'block', | ||
}; | ||
|
||
console.log('sss', collapseLink, expandLink); | ||
return ( | ||
<div className={classNames}> | ||
{showMore ? expanded : collapsed} | ||
<Link | ||
onClick={this.handleToggleClick} | ||
small | ||
style={{ marginTop: '0.9em' }}> | ||
{showMore ? 'Read less' : 'Read more'} | ||
</Link> | ||
<div className={`${prefix}--read-more__content`} style={contentStyle}> | ||
<div ref={divElement => (this.divElement = divElement)}> | ||
{(showMore || !collapsed) && children} | ||
{collapsed && <div style={collapseStyle}>{collapsed}</div>} | ||
</div> | ||
</div> | ||
<MoreLink | ||
handleToggleClick={this.handleToggleClick} | ||
showMore={showMore} | ||
link={showMore ? collapseLink : expandLink} | ||
text={showMore ? collapseText : expandText} | ||
/> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
ReadMore.propTypes = { | ||
children: PropTypes.node, | ||
className: PropTypes.string, | ||
html: PropTypes.string, | ||
}; | ||
|
||
export default ReadMore; |
Oops, something went wrong.