UNPKG

ndla-ui

Version:

UI component library for NDLA.

140 lines (125 loc) 3.69 kB
import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import BEMHelper from 'react-bem-helper'; import { Forward } from 'ndla-icons/common'; import { Cross } from 'ndla-icons/action'; import SafeLink from '../common/SafeLink'; import SectionHeading from '../SectionHeading'; const classes = BEMHelper('c-subject-archive'); class SubjectArchive extends Component { constructor(props) { super(props); this.state = { archiveOpen: false, minHeight: null, }; this.handleToggleArchive = this.handleToggleArchive.bind(this); this.wrapperRef = null; } handleToggleArchive() { this.setState(prevState => { const newState = { archiveOpen: !prevState.archiveOpen, }; if (!prevState.minHeight) { newState.minHeight = this.wrapperRef.offsetHeight; } return newState; }); } render() { const { fixedWidth, featuringArticle, messages, sectionHeading, archiveArticles, } = this.props; const archiveId = 'subject-archive'; const section = this.state.archiveOpen ? ( <nav id={archiveId} {...classes('archive')}> <ul {...classes('archive-articles')}> {archiveArticles.map(article => ( <li key={article.heading}> <SafeLink to={article.url}>{article.heading}</SafeLink> </li> ))} </ul> </nav> ) : ( <section {...classes('featuring')}> <div {...classes('media-wrapper')}>{featuringArticle.media}</div> <div {...classes('content')}> <h1 {...classes('heading')}> <SafeLink to={featuringArticle.url}> {featuringArticle.heading} </SafeLink> </h1> <p {...classes('description')}>{featuringArticle.description}</p> </div> </section> ); const wrapperStyles = this.state.minHeight ? { minHeight: this.state.minHeight, } : null; return ( <section style={wrapperStyles} {...classes('', { fixedWidth, animate: this.state.minHeight, })} ref={ref => { this.wrapperRef = ref; }}> <SectionHeading large className={classes('section-heading').className}> {sectionHeading} </SectionHeading> <div {...classes('wrapper')}> {section} <button type="button" aria-expanded={this.state.archiveOpen} aria-controls={archiveId} className={classes('archive-button').className} onClick={this.handleToggleArchive}> {this.state.archiveOpen ? ( <Fragment> <Cross /> <span>{messages.close}</span> </Fragment> ) : ( <Fragment> <Forward /> <span>{messages.archive}</span> </Fragment> )} </button> </div> </section> ); } } SubjectArchive.propTypes = { featuringArticle: PropTypes.shape({ media: PropTypes.node.isRequired, heading: PropTypes.string.isRequired, description: PropTypes.string.isRequired, url: PropTypes.string.isRequired, }).isRequired, archiveArticles: PropTypes.arrayOf( PropTypes.shape({ url: PropTypes.string.isRequired, heading: PropTypes.string.isRequired, }), ).isRequired, sectionHeading: PropTypes.string.isRequired, fixedWidth: PropTypes.bool, messages: PropTypes.shape({ archive: PropTypes.string.isRequired, }), }; SubjectArchive.defaultProps = { fixedWidth: false, }; export default SubjectArchive;