styles repeater buttons, remove and duplicate

This commit is contained in:
Jarrod Flesch
2020-03-13 18:21:31 -04:00
parent 079e44497b
commit cbc68efbd7
9 changed files with 241 additions and 26 deletions

View File

@@ -32,6 +32,18 @@
}
}
&.btn-error {
border: $stroke-width solid $error;
color: $error;
background: none;
&:hover {
background: lighten($error, 22.5%);
border: $stroke-width solid $error;
color: $black;
}
}
&.btn-small {
padding: base(0) base(.25) base(.04);
border-radius: 3px;

View File

@@ -0,0 +1,27 @@
import React from 'react';
import PropTypes from 'prop-types';
import './index.scss';
import Button from '../Button';
import Crosshair from '../../graphics/Crosshair';
const baseClass = 'repeat-field-button';
const RepeatFieldButton = ({ onClick }) => {
return (
<div className={baseClass}>
<Button
onClick={onClick}
type="secondary"
>
<Crosshair />
</Button>
</div>
);
};
RepeatFieldButton.propTypes = {
onClick: PropTypes.func.isRequired,
};
export default RepeatFieldButton;

View File

@@ -0,0 +1,28 @@
@import '../../../scss/styles.scss';
.repeat-field-button {
width: calc(100% + #{base(2)});
margin-left: base(-1);
padding: base(1) 0;
position: relative;
&:before {
content: '';
position: absolute;
background: $light-gray;
height: 2px;
width: 100%;
left: 0;
bottom: 50%;
}
.btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
margin: 0;
padding: base(.25) base(.75);
}
}

View File

@@ -101,7 +101,7 @@ const Form = (props) => {
});
dispatchFields({
type: 'replace',
type,
value: {
...stateWithoutFields,
...reindexedRows,

View File

@@ -4,9 +4,15 @@ import PropTypes from 'prop-types';
import FormContext from '../../Form/Context';
import Section from '../../../layout/Section';
import RenderFields from '../../RenderFields';
import RepeatFieldButton from '../../../controls/RepeatFieldButton';
import Button from '../../../controls/Button';
import X from '../../../graphics/X';
import './index.scss';
const baseClass = 'field-repeater';
const Repeater = (props) => {
const formContext = useContext(FormContext);
const { adjustRows } = formContext;
@@ -47,36 +53,37 @@ const Repeater = (props) => {
const iterableInternalRowCount = Array.from(Array(internalRowCount).keys());
return (
<div className="field-repeater">
<Section heading={label}>
<div className={baseClass}>
<Section
heading={label}
className="repeater"
>
{iterableInternalRowCount.map((_, rowIndex) => {
return (
<React.Fragment key={rowIndex}>
<h2>{`Repeater Item ${rowIndex}`}</h2>
<div className={`${baseClass}__section-inner`}>
<Button
className="delete"
onClick={() => removeRow({ rowIndex })}
type="error"
>
<X />
</Button>
<h2>{`${label} - Item ${rowIndex}`}</h2>
<RenderFields
fields={fields.map((field) => {
return ({
...field,
name: `${name}.${rowIndex}.${field.name}`,
defaultValue: initialRows[rowIndex] ? initialRows[rowIndex][field.name] : null,
});
})}
/>
<RenderFields
fields={fields.map((field) => {
return ({
...field,
name: `${name}.${rowIndex}.${field.name}`,
defaultValue: initialRows[rowIndex] ? initialRows[rowIndex][field.name] : null,
});
})}
/>
</div>
<button
onClick={() => addNewRow({ rowIndex })}
type="button"
>
{`Add after ${rowIndex}`}
</button>
<button
onClick={() => removeRow({ rowIndex })}
type="button"
>
{`Remove ${rowIndex}`}
</button>
<RepeatFieldButton onClick={() => addNewRow({ rowIndex })} />
</React.Fragment>
);
})}

View File

@@ -1,3 +1,57 @@
@import '../../../../scss/styles.scss';
.field-repeater {
// background: red;
.content {
flex-direction: column;
}
&__section-inner {
padding: base(1);
margin-right: base(1);
background: $light-gray;
flex-direction: column;
position: relative;
}
.repeat-field-button {
.btn {
@include color-svg($primary);
height: 30px;
width: 30px;
top: 50%;
left: 50%;
padding: 0;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
&:hover {
@include color-svg(white);
}
.crosshair {
padding: 3px;
}
}
}
.btn.delete {
position: absolute;
height: 30px;
width: 30px;
margin: 0;
top: base(1);
right: base(1);
padding: 3px;
display: flex;
align-items: center;
justify-content: center;
.x {
@include color-svg($error);
height: 15px;
width: 15px;
}
}
}

View File

@@ -0,0 +1,45 @@
import React from 'react';
const Crosshair = () => {
return (
<svg
width="20px"
height="20px"
viewBox="0 0 20 20"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
className="crosshair"
>
<g
stroke="none"
strokeWidth="1"
fill="none"
fillRule="evenodd"
strokeLinecap="square"
>
<g
className="stroke"
transform="translate(-0.500000, -0.500000)"
>
<line
x1="11"
y1="1"
x2="11"
y2="20"
id="Line"
/>
<line
x1="10.5"
y1="0.5"
x2="10.5"
y2="19.5"
id="Line"
transform="translate(10.500000, 10.000000) rotate(90.000000) translate(-10.500000, -10.000000) "
/>
</g>
</g>
</svg>
);
};
export default Crosshair;

View File

@@ -0,0 +1,39 @@
import React from 'react';
import './index.scss';
const X = () => {
return (
<svg
width="22px"
height="20px"
viewBox="0 0 22 20"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
className="x"
>
<g
stroke="none"
strokeWidth="2"
fill="none"
fillRule="evenodd"
>
<g
className="stroke"
transform="translate(1.000000, 0.000000)"
>
<path
d="M0,0 C6.66666667,6.66666667 13.3333333,13.3333333 20,20"
/>
<path
d="M0,0 C6.66666667,6.66666667 13.3333333,13.3333333 20,20"
id="Path"
transform="translate(10.000000, 10.000000) scale(-1, 1) translate(-10.000000, -10.000000) "
/>
</g>
</g>
</svg>
);
};
export default X;

View File

@@ -0,0 +1,3 @@
.x {
}