119 lines
3.2 KiB
JavaScript
119 lines
3.2 KiB
JavaScript
import React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import AnimateHeight from 'react-animate-height';
|
|
import { Draggable } from 'react-beautiful-dnd';
|
|
|
|
import RenderFields from '../RenderFields'; // eslint-disable-line import/no-cycle
|
|
import IconButton from '../../controls/IconButton';
|
|
|
|
import './index.scss';
|
|
|
|
const baseClass = 'draggable-section';
|
|
|
|
const DraggableSection = (props) => {
|
|
const {
|
|
addRow,
|
|
removeRow,
|
|
rowIndex,
|
|
parentName,
|
|
renderFields,
|
|
defaultValue,
|
|
dispatchCollapsibleStates,
|
|
collapsibleStates,
|
|
singularLabel,
|
|
} = props;
|
|
|
|
const handleCollapseClick = () => {
|
|
dispatchCollapsibleStates({
|
|
type: 'UPDATE_COLLAPSIBLE_STATUS',
|
|
collapsibleIndex: rowIndex,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<Draggable
|
|
draggableId={`row-${rowIndex}`}
|
|
index={rowIndex}
|
|
>
|
|
{(providedDrag) => {
|
|
return (
|
|
<div
|
|
ref={providedDrag.innerRef}
|
|
className={baseClass}
|
|
{...providedDrag.draggableProps}
|
|
>
|
|
<div className={`${baseClass}__header`}>
|
|
<div
|
|
className={`${baseClass}__header__drag-handle`}
|
|
{...providedDrag.dragHandleProps}
|
|
onClick={handleCollapseClick}
|
|
role="button"
|
|
tabIndex={0}
|
|
/>
|
|
|
|
<div className={`${baseClass}__header__row-index`}>
|
|
{`${singularLabel} ${rowIndex + 1}`}
|
|
</div>
|
|
|
|
<div className={`${baseClass}__header__controls`}>
|
|
|
|
<IconButton
|
|
iconName="crosshair"
|
|
onClick={addRow}
|
|
size="small"
|
|
/>
|
|
|
|
<IconButton
|
|
iconName="crossOut"
|
|
onClick={removeRow}
|
|
size="small"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<AnimateHeight
|
|
className={`${baseClass}__content`}
|
|
height={collapsibleStates[rowIndex] ? 'auto' : 0}
|
|
duration={0}
|
|
>
|
|
<RenderFields
|
|
key={rowIndex}
|
|
fields={renderFields.map((field) => {
|
|
const fieldName = `${parentName}.${rowIndex}.${field.name}`;
|
|
return ({
|
|
...field,
|
|
name: fieldName,
|
|
defaultValue: defaultValue?.[field.name],
|
|
});
|
|
})}
|
|
/>
|
|
</AnimateHeight>
|
|
</div>
|
|
);
|
|
}}
|
|
</Draggable>
|
|
);
|
|
};
|
|
|
|
DraggableSection.defaultProps = {
|
|
rowCount: null,
|
|
defaultValue: null,
|
|
collapsibleStates: [],
|
|
singularLabel: '',
|
|
};
|
|
|
|
DraggableSection.propTypes = {
|
|
addRow: PropTypes.func.isRequired,
|
|
removeRow: PropTypes.func.isRequired,
|
|
rowIndex: PropTypes.number.isRequired,
|
|
parentName: PropTypes.string.isRequired,
|
|
singularLabel: PropTypes.string,
|
|
renderFields: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
|
|
rowCount: PropTypes.number,
|
|
defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.shape({})]),
|
|
dispatchCollapsibleStates: PropTypes.func.isRequired,
|
|
collapsibleStates: PropTypes.arrayOf(PropTypes.bool),
|
|
};
|
|
|
|
export default DraggableSection;
|