Merge branch 'master' of github.com:keen-studio/payload

This commit is contained in:
James
2020-03-31 15:46:25 -04:00
9 changed files with 183 additions and 105 deletions

View File

@@ -5,6 +5,8 @@ import { Draggable } from 'react-beautiful-dnd';
import RenderFields from '../RenderFields'; // eslint-disable-line import/no-cycle
import IconButton from '../../controls/IconButton';
import Pill from '../../modules/Pill';
import Chevron from '../../graphics/Chevron';
import './index.scss';
@@ -21,6 +23,7 @@ const DraggableSection = (props) => {
dispatchCollapsibleStates,
collapsibleStates,
singularLabel,
useHeadingPill,
} = props;
const handleCollapseClick = () => {
@@ -44,15 +47,18 @@ const DraggableSection = (props) => {
>
<div className={`${baseClass}__header`}>
<div
className={`${baseClass}__header__drag-handle`}
{...providedDrag.dragHandleProps}
className={`${baseClass}__header__drag-handle`}
onClick={handleCollapseClick}
role="button"
tabIndex={0}
/>
<div className={`${baseClass}__header__row-index`}>
{`${singularLabel} ${rowIndex + 1}`}
<div className={`${baseClass}__header__row-name`}>
{useHeadingPill
? <Pill>{singularLabel}</Pill>
: `${singularLabel} ${rowIndex + 1}`
}
</div>
<div className={`${baseClass}__header__controls`}>
@@ -68,6 +74,8 @@ const DraggableSection = (props) => {
onClick={removeRow}
size="small"
/>
<Chevron isOpen={collapsibleStates[rowIndex]} />
</div>
</div>
@@ -100,6 +108,7 @@ DraggableSection.defaultProps = {
defaultValue: null,
collapsibleStates: [],
singularLabel: '',
useHeadingPill: false,
};
DraggableSection.propTypes = {
@@ -113,6 +122,7 @@ DraggableSection.propTypes = {
defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.shape({})]),
dispatchCollapsibleStates: PropTypes.func.isRequired,
collapsibleStates: PropTypes.arrayOf(PropTypes.bool),
useHeadingPill: PropTypes.bool,
};
export default DraggableSection;

View File

@@ -51,8 +51,9 @@
z-index: 2;
}
&__row-index {
&__row-name {
font-family: $font-body;
font-weight: bold;
font-size: base(.5);
}
@@ -94,6 +95,14 @@
@include color-svg(white);
}
}
.chevron {
margin-left: base(.5);
&__is--open {
transform: rotate(180deg);
}
}
}
}

View File

@@ -5,6 +5,7 @@ import PropTypes from 'prop-types';
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import { ModalContext } from '@trbl/react-modal';
import Button from '../../../controls/Button';
import FormContext from '../../Form/Context';
import Section from '../../../layout/Section';
import AddRowModal from './AddRowModal';
@@ -21,6 +22,7 @@ const Flexible = (props) => {
name,
blocks,
defaultValue,
singularLabel,
} = props;
const { toggle: toggleModal, closeAll: closeAllModals } = useContext(ModalContext);
@@ -102,17 +104,26 @@ const Flexible = (props) => {
<Section
heading={label}
className="flexible"
rowCount={rowCount}
addRow={() => openAddRowModal(0)}
useAddRowButton
>
<Droppable droppableId="flexible-drop">
{provided => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
>
{rowCount !== 0
{(rowCount === 0
? (
<div className={`${baseClass}__add-button-wrap`}>
<Button
onClick={() => openAddRowModal(0)}
type="secondary"
>
{`Add ${singularLabel}`}
</Button>
</div>
)
: (
<Droppable droppableId="flexible-drop">
{provided => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
>
{rowCount !== 0
&& Array.from(Array(rowCount).keys()).map((_, rowIndex) => {
let blockType = fieldState[`${name}.${rowIndex}.blockType`]?.value;
@@ -141,9 +152,11 @@ const Flexible = (props) => {
type: 'hidden',
},
]}
singularLabel={blockType}
defaultValue={hasModifiedRows ? undefined : defaultValue[rowIndex]}
dispatchCollapsibleStates={dispatchCollapsibleStates}
collapsibleStates={collapsibleStates}
useHeadingPill
/>
);
}
@@ -151,10 +164,11 @@ const Flexible = (props) => {
return null;
})
}
{provided.placeholder}
</div>
)}
</Droppable>
{provided.placeholder}
</div>
)}
</Droppable>
))}
</Section>
</div>
</DragDropContext>
@@ -172,6 +186,7 @@ const Flexible = (props) => {
Flexible.defaultProps = {
label: '',
defaultValue: [],
singularLabel: 'Block',
};
Flexible.propTypes = {
@@ -182,6 +197,7 @@ Flexible.propTypes = {
PropTypes.shape({}),
).isRequired,
label: PropTypes.string,
singularLabel: PropTypes.string,
name: PropTypes.string.isRequired,
};

View File

@@ -2,6 +2,14 @@
.field-type.flexible {
&__add-button-wrap {
@include gutter;
.btn {
margin: 0 0 base(.5);
}
}
.section .section {
margin-top: 0;
}

View File

@@ -4,6 +4,7 @@ import React, {
import PropTypes from 'prop-types';
import { DragDropContext, Droppable } from 'react-beautiful-dnd';
import Button from '../../../controls/Button';
import FormContext from '../../Form/Context';
import Section from '../../../layout/Section';
import DraggableSection from '../../DraggableSection'; // eslint-disable-line import/no-cycle
@@ -86,42 +87,49 @@ const Repeater = (props) => {
return (
<DragDropContext onDragEnd={onDragEnd}>
<div className={baseClass}>
<Section
heading={label}
rowCount={rowCount}
addRow={() => addRow(0)}
useAddRowButton
>
<Droppable droppableId="repeater-drop">
{provided => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
>
{rowCount !== 0
&& Array.from(Array(rowCount).keys()).map((_, rowIndex) => {
return (
<DraggableSection
key={rowIndex}
parentName={name}
singularLabel={singularLabel}
addRow={() => addRow(rowIndex)}
removeRow={() => removeRow(rowIndex)}
rowIndex={rowIndex}
fieldState={fieldState}
renderFields={fields}
rowCount={rowCount}
defaultValue={hasModifiedRows ? undefined : defaultValue[rowIndex]}
dispatchCollapsibleStates={dispatchCollapsibleStates}
collapsibleStates={collapsibleStates}
/>
);
})
}
{provided.placeholder}
<Section heading={label}>
{(rowCount === 0
? (
<div className={`${baseClass}__add-button-wrap`}>
<Button
onClick={() => addRow(0)}
type="secondary"
>
{`Add ${singularLabel}`}
</Button>
</div>
)}
</Droppable>
)
: (
<Droppable droppableId="repeater-drop">
{provided => (
<div
ref={provided.innerRef}
{...provided.droppableProps}
>
{rowCount !== 0
&& Array.from(Array(rowCount).keys()).map((_, rowIndex) => {
return (
<DraggableSection
key={rowIndex}
parentName={name}
singularLabel={singularLabel}
addRow={() => addRow(rowIndex)}
removeRow={() => removeRow(rowIndex)}
rowIndex={rowIndex}
fieldState={fieldState}
renderFields={fields}
defaultValue={hasModifiedRows ? undefined : defaultValue[rowIndex]}
dispatchCollapsibleStates={dispatchCollapsibleStates}
collapsibleStates={collapsibleStates}
/>
);
})
}
{provided.placeholder}
</div>
)}
</Droppable>
))}
</Section>
</div>
@@ -131,7 +139,7 @@ const Repeater = (props) => {
Repeater.defaultProps = {
label: '',
singularLabel: '',
singularLabel: 'Row',
defaultValue: [],
};

View File

@@ -3,6 +3,14 @@
.field-type.repeater {
background: white;
&__add-button-wrap {
@include gutter;
.btn {
margin: 0 0 base(.5);
}
}
.section .section {
margin-top: 0;
}

View File

@@ -0,0 +1,61 @@
import React from 'react';
import PropTypes from 'prop-types';
const baseClass = 'chevron';
const Chevron = ({ isOpen, className }) => {
const classes = [
'icon',
baseClass,
className && className,
isOpen && `${baseClass}--is-${isOpen ? 'open' : 'closed'}`,
].filter(Boolean).join(' ');
return (
<svg
className={classes}
width="21px"
height="10px"
viewBox="0 0 21 10"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
>
<g
stroke="none"
strokeWidth="1"
fill="none"
fillRule="evenodd"
strokeLinecap="square"
>
<g transform="translate(10.146447, 9.267767) rotate(45.000000) translate(-10.146447, -9.267767) translate(3.146447, 2.267767)">
<line
className="stroke"
x1="1"
y1="0.5"
x2="14"
y2="0.5"
/>
<line
className="stroke"
x1="1"
y1="0.5"
x2="1"
y2="13.5"
/>
</g>
</g>
</svg>
);
};
Chevron.defaultProps = {
isOpen: false,
className: '',
};
Chevron.propTypes = {
isOpen: PropTypes.bool,
className: PropTypes.string,
};
export default Chevron;

View File

@@ -1,15 +1,15 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import AnimateHeight from 'react-animate-height';
import Chevron from '../../graphics/Chevron';
import './index.scss';
import Button from '../../controls/Button';
const baseClass = 'section';
const Section = (props) => {
const {
className, heading, children, rowCount, addRow, useAddRowButton,
className, heading, children,
} = props;
const classes = [
@@ -19,11 +19,6 @@ const Section = (props) => {
const [isSectionOpen, setIsSectionOpen] = useState(true);
const addInitialRow = () => {
addRow();
setIsSectionOpen(true);
};
return (
<section className={classes}>
{heading
@@ -35,6 +30,8 @@ const Section = (props) => {
tabIndex={0}
>
<h2 className={`${baseClass}__heading`}>{heading}</h2>
<Chevron isOpen={isSectionOpen} />
</header>
)}
{children
@@ -44,17 +41,6 @@ const Section = (props) => {
height={isSectionOpen ? 'auto' : 0}
duration={0}
>
{(rowCount === 0 && useAddRowButton)
&& (
<div className={`${baseClass}__add-button-wrap`}>
<Button
onClick={addInitialRow}
type="secondary"
>
Add Row
</Button>
</div>
)}
{children}
</AnimateHeight>
)}
@@ -66,18 +52,12 @@ Section.defaultProps = {
className: '',
heading: '',
children: undefined,
rowCount: 0,
addRow: undefined,
useAddRowButton: false,
};
Section.propTypes = {
className: PropTypes.string,
heading: PropTypes.string,
children: PropTypes.node,
rowCount: PropTypes.number,
addRow: PropTypes.func,
useAddRowButton: PropTypes.bool,
};
export default Section;

View File

@@ -25,38 +25,16 @@
margin-right: base(1);
}
.section__add-button-wrap {
@include gutter;
.btn {
margin: 0 0 base(.5);
}
}
&__controls {
.chevron {
margin-left: auto;
}
&__collapse-icon {
svg {
transition: 150ms linear;
&--is-open {
transform: rotate(180deg);
}
&--open {
svg {
transform: rotate(90deg);
}
&--is-closed {
transform: rotate(0deg);
}
&--closed {
svg {
transform: rotate(-90deg);
}
}
}
&__add-row-button {
margin-right: base(.5);
}
&__content {