UNPKG

@gravityforms/components

Version:

UI components for use in Gravity Forms development. Both React and vanilla js flavors.

240 lines (228 loc) 6.75 kB
import { React, PropTypes, classnames } from '@gravityforms/libraries'; import { spacerClasses } from '@gravityforms/utils'; import Heading from '../Heading'; import DescriptionListItem from '../../utils/description-list-item'; const { Fragment, forwardRef } = React; /** * @module DescriptionList * @description A Description List component. * * @since 3.4.0 * * @param {object} props Component props. * @param {object} props.customAttributes Custom attributes for the component. * @param {string|Array|object} props.customClasses Custom classes for the component. * @param {Array} props.groups Array of groups of terms and descriptions. * @param {string} props.id The ID of the component. * @param {string|number|Array|object} props.spacing The spacing for the component, as a string, number, array, or object. * @param {string} props.title The title for the component. * @param {object} props.titleAttributes Custom attributes for the title. * @param {string|Array|object} props.titleClasses Custom classes for the title. * @param {string} props.type The type of description list, one of `default` or `list`. * @param {object|null} ref Ref to the component. * * @return {JSX.Element} The description list component. * * @example * import DescriptionList from '@gravityforms/components/react/admin/elements/DescriptionList'; * * const groups = [ * { * terms: { * component: 'Text', * props: { * content: 'Chrome', * size: 'text-sm', * weight: 'semibold', * }, * }, * descriptions: { * component: 'Text', * props: { * content: 'A cross-platform web browser developed by Google.', * size: 'text-sm', * }, * }, * wrapper: true, * }, * { * terms: { * component: 'Text', * props: { * content: 'Firefox', * size: 'text-sm', * weight: 'semibold', * }, * }, * descriptions: [ * { * component: 'Text', * props: { * content: 'A free, open source, cross-platform, graphical web browser developed by the Mozilla Corporation and hundreds of volunteers.', * size: 'text-sm', * }, * }, * { * component: 'Text', * props: { * content: 'The Red Panda also known as the Lesser Panda, Wah, Bear Cat or Firefox, is a mostly herbivorous mammal, slightly larger than a domestic cat (60 cm long).', * size: 'text-sm', * }, * }, * ], * }, * { * terms: [ * { * component: 'Text', * props: { * content: 'Internet Explorer', * size: 'text-sm', * weight: 'semibold', * }, * }, * { * component: 'Text', * props: { * content: 'Netscape', * size: 'text-sm', * weight: 'semibold', * }, * }, * ], * descriptions: { * component: 'Text', * props: { * content: 'Browsers that have been discontinued.', * size: 'text-sm', * }, * }, * }, * ]; * * return <DescriptionList groups={ groups } />; * */ const DescriptionList = forwardRef( ( { customAttributes = {}, customClasses = [], groups = [], id = '', spacing = '', title = null, titleAttributes = {}, titleClasses = [], type = 'default', }, ref ) => { const componentProps = { className: classnames( { 'gform-description-list': true, [ `gform-description-list--${ type }` ]: true, ...spacerClasses( spacing ), }, customClasses ), ref, ...customAttributes, }; const titleProps = { customClasses: classnames( { 'gform-description-list__title': true, }, titleClasses ), size: 'text-lg', tagName: 'h2', weight: 'medium', ...titleAttributes, }; const ListElement = 'default' === type ? 'div' : 'dl'; const TermElement = 'default' === type ? 'div' : 'dt'; const DescElement = 'default' === type ? 'div' : 'dd'; return ( <div { ...componentProps }> { title && <Heading { ...titleProps }>{ title }</Heading> } <ListElement className="gform-description-list__list"> { groups.map( ( group, index ) => { let terms = null; if ( Array.isArray( group.terms ) ) { terms = group.terms.map( ( term, termIndex ) => ( <TermElement key={ `${ id }-group-${ index }-term-${ termIndex }` } className="gform-description-list__term" > <DescriptionListItem data={ term } /> </TermElement> ) ); } else { terms = ( <TermElement className="gform-description-list__term" > <DescriptionListItem data={ group.terms } /> </TermElement> ); } let descriptions = null; if ( Array.isArray( group.descriptions ) ) { descriptions = group.descriptions.map( ( description, descIndex ) => ( <DescElement key={ `${ id }-group-${ index }-description-${ descIndex }` } className="gform-description-list__description" > <DescriptionListItem data={ description } /> </DescElement> ) ); } else { descriptions = ( <DescElement className="gform-description-list__description" > <DescriptionListItem data={ group.descriptions } /> </DescElement> ); } if ( group.wrapper ) { return ( <div key={ `${ id }-group-${ index }-group` } className="gform-description-list__group" > { terms } { descriptions } </div> ); } return ( <Fragment key={ `${ id }-group-${ index }` }> { terms } { descriptions } </Fragment> ); } ) } </ListElement> </div> ); } ); DescriptionList.propTypes = { customAttributes: PropTypes.object, customClasses: PropTypes.oneOfType( [ PropTypes.string, PropTypes.array, PropTypes.object, ] ), groups: PropTypes.arrayOf( PropTypes.object ), id: PropTypes.string.isRequired, spacing: PropTypes.oneOfType( [ PropTypes.string, PropTypes.number, PropTypes.array, PropTypes.object, ] ), title: PropTypes.string, titleAttributes: PropTypes.object, titleClasses: PropTypes.oneOfType( [ PropTypes.string, PropTypes.array, PropTypes.object, ] ), type: PropTypes.oneOf( [ 'default', 'list' ] ), }; DescriptionList.displayName = 'DescriptionList'; export default DescriptionList;