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;