UNPKG

@modernpoacher/sprockets

Version:
125 lines (104 loc) 2.91 kB
/** * @typedef {SprocketsTypes.ErrorDefinitionType} ErrorDefinitionType * @typedef {SprocketsTypes.Super.Components.Group.GroupProps} GroupProps * @typedef {SprocketsTypes.Super.Components.Group.GroupState} GroupState * @typedef {SprocketsTypes.Sprockets.ErrorSummary.Group.ErrorSummaryProps} ErrorSummaryProps * @typedef {SprocketsTypes.Sprockets.ErrorSummary.Group.ErrorSummaryState} ErrorSummaryState */ /** * ErrorSummaryGroup component */ import React from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' import equal from 'fast-deep-equal' import debug from 'debug' import Group from '#sprockets/super/components/group' import { getKey } from '#sprockets/transformers/common' import TextContent from '#sprockets/components/common/text-content' /** * @type {ErrorDefinitionType[]} */ const DEFAULT_ERROR_SUMMARY = [] const log = debug('@modernpoacher/sprockets/sprockets/error-summary/group') /** * @param {ErrorDefinitionType} error * @param {number} index * @returns {React.JSX.Element} */ function render ({ href, text }, index) { log('render') return ( <li key={getKey(href, text, index)} className='error'> <a href={href}> <TextContent textContent={text} /> </a> </li> ) } /** * @extends {Group<GroupProps & ErrorSummaryProps, GroupState & ErrorSummaryState>} */ export default class ErrorSummaryGroup extends Group { /** * @type {ErrorSummaryState} */ state = {} getClassName () { return classnames(super.getClassName(), 'error-summary') } /** * Compare latest 'props' with 'state' for changes to 'errorSummary' * * @param {ErrorSummaryProps} props Latest props * @param {ErrorSummaryState} state Current state * @returns {ErrorSummaryState} */ static getDerivedStateFromProps ({ errorSummary: e }, { errorSummary: E }) { return { errorSummary: (e === E || equal(e, E)) ? E : e } } /** * Compare latest 'props' with 'state' for changes to 'errorSummary' * * @param {ErrorSummaryProps} props Latest props * @param {ErrorSummaryState} state Current state * @returns {boolean} */ shouldComponentUpdate (props, state) { const { errorSummary: e = DEFAULT_ERROR_SUMMARY } = this.state const { errorSummary: E = DEFAULT_ERROR_SUMMARY } = state return !(e === E || equal(e, E)) } render () { const { errorSummary = DEFAULT_ERROR_SUMMARY } = this.props if (errorSummary.length) { const { groupRef } = this.props return ( <ul className={this.getClassName()} ref={groupRef}> {errorSummary.map(render)} </ul> ) } return null } } ErrorSummaryGroup.propTypes = { ...Group.propTypes, errorSummary: PropTypes.arrayOf(PropTypes.shape({})) }