style changes to the repeater

This commit is contained in:
Jarrod Flesch
2020-03-16 18:45:58 -04:00
parent 0c9fb098e0
commit 8aca26ff88
14 changed files with 231 additions and 179 deletions

View File

@@ -0,0 +1,46 @@
import React from 'react';
import PropTypes from 'prop-types';
import Button from '../Button';
import Crosshair from '../../graphics/Crosshair';
import Arrow from '../../graphics/Arrow';
import './index.scss';
const baseClass = 'icon-button';
const IconButton = ({ iconName, className, ...rest }) => {
const classes = [
baseClass,
className && className,
`${baseClass}--${iconName}`,
].filter(Boolean).join(' ');
const icons = {
crosshair: Crosshair,
crossOut: Crosshair,
arrow: Arrow,
};
const Icon = icons[iconName] || icons.arrow;
return (
<Button
className={classes}
{...rest}
>
<Icon />
</Button>
);
};
IconButton.defaultProps = {
className: '',
};
IconButton.propTypes = {
iconName: PropTypes.oneOf(['arrow', 'crossOut', 'crosshair']).isRequired,
className: PropTypes.string,
};
export default IconButton;

View File

@@ -0,0 +1,27 @@
@import '../../../scss/styles.scss';
.icon-button {
line-height: 0;
background: transparent;
border: 1px solid $black;
&:hover {
background: lighten($black, 50%);
border-color: lighten($black, .2%);
@include color-svg(lighten($black, 5%));
}
&.btn {
padding: 5px;
}
.icon {
@include color-svg($black);
}
&--crossOut {
svg {
transform: rotate(45deg);
}
}
}

View File

@@ -1,27 +0,0 @@
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

@@ -1,28 +0,0 @@
@import '../../../scss/styles.scss';
.repeat-field-button {
width: calc(100% + #{base(2)});
margin-left: base(-1);
padding: base(1.25) 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

@@ -1,7 +1,6 @@
@import '../../../scss/styles.scss';
.form {
@include row;
> * {
width: 100%;

View File

@@ -4,9 +4,8 @@ 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 IconButton from '../../../controls/IconButton';
import Pill from '../../../modules/Pill';
import './index.scss';
@@ -24,7 +23,7 @@ const Repeater = (props) => {
defaultValue,
} = props;
const addNewRow = (rowIndex) => {
const addRow = (rowIndex) => {
dispatchFields({
type: 'ADD_ROW', rowIndex, name, fields,
});
@@ -50,37 +49,50 @@ const Repeater = (props) => {
heading={label}
className="repeater"
>
{rowCount === 0
&& (
<RepeatFieldButton onClick={() => addNewRow(0)} />
)}
{Array.from(Array(rowCount).keys()).map((_, rowIndex) => {
return (
<React.Fragment key={rowIndex}>
<div className={`${baseClass}__section-inner`}>
<Button
className="delete"
onClick={() => removeRow(rowIndex)}
type="error"
>
<X />
</Button>
<h2>{`${label} - Item ${rowIndex}`}</h2>
<div className={`${baseClass}__section`}>
<div className={`${baseClass}__section-header`}>
<Pill>
{name}
</Pill>
<h4 className={`${baseClass}__section-header__heading`}>Title Goes Here</h4>
<RenderFields
fields={fields.map((field) => {
const fieldName = `${name}.${rowIndex}.${field.name}`;
return ({
...field,
name: fieldName,
defaultValue: fieldState?.[fieldName]?.value,
});
})}
/>
<div className={`${baseClass}__section-header__controls`}>
<IconButton
iconName="crosshair"
onClick={() => addRow(rowIndex)}
size="small"
/>
<IconButton
iconName="crossOut"
onClick={() => removeRow(rowIndex)}
size="small"
/>
<IconButton
iconName="arrow"
// onClick={() => removeRow(rowIndex)}
size="small"
/>
</div>
</div>
<div className={`${baseClass}__section-content`}>
<RenderFields
fields={fields.map((field) => {
const fieldName = `${name}.${rowIndex}.${field.name}`;
return ({
...field,
name: fieldName,
defaultValue: fieldState?.[fieldName]?.value,
});
})}
/>
</div>
</div>
<RepeatFieldButton onClick={() => addNewRow(rowIndex)} />
</React.Fragment>
);
})}

View File

@@ -1,16 +1,70 @@
@import '../../../../scss/styles.scss';
.field-repeater {
.content {
flex-direction: column;
}
&__section-inner {
padding: base(1);
&__section {
margin-right: base(1);
background: $light-gray;
flex-direction: column;
position: relative;
+ .field-repeater__section {
margin-top: base(.5);
}
}
&__section-header {
padding: base(.75) base(1);
display: flex;
align-items: center;
border-bottom: 1px solid white;
.pill {
margin-right: base(.5);
}
&__heading {
font-family: $font-body;
margin: 0;
font-size: base(.65);
}
&__controls {
margin-left: auto;
.btn {
margin-top: 0;
margin-bottom: 0;
}
.icon-button--crossOut,
.icon-button--crosshair {
margin-right: base(.25);
}
.icon-button--crosshair {
border-color: $primary;
@include color-svg($primary);
&:hover {
background: lighten($primary, 50%);
}
}
.icon-button--arrow {
svg {
transform: rotate(-90deg);
}
}
}
}
&__section-content {
padding: base(.75) base(1);
}
.repeat-field-button {
@@ -26,10 +80,6 @@
align-items: center;
justify-content: center;
&:hover {
@include color-svg(white);
}
.crosshair {
padding: 3px;
}
@@ -37,21 +87,13 @@
}
.btn.delete {
position: absolute;
height: 20px;
width: 20px;
margin: 0;
top: base(1);
right: base(1);
padding: 0;
display: flex;
align-items: center;
justify-content: center;
line-height: 0;
padding: base(.15);
.x {
padding: 1px;
@include color-svg($error);
height: 100%;
padding: 3px;
}
}
}

View File

@@ -1,7 +1,6 @@
@import '../../../scss/styles.scss';
.field-type {
@include gutter;
margin-bottom: base(.5);
position: relative;
width: 100%;

View File

@@ -3,12 +3,12 @@ import React from 'react';
const Crosshair = () => {
return (
<svg
width="20px"
height="20px"
viewBox="0 0 20 20"
width="10px"
height="10px"
viewBox="0 0 10 10"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
className="crosshair"
className="icon crosshair"
>
<g
stroke="none"
@@ -16,27 +16,20 @@ const Crosshair = () => {
fill="none"
fillRule="evenodd"
strokeLinecap="square"
className="stroke"
>
<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>
<line
x1="-1.11022302e-16"
y1="5"
x2="10"
y2="5"
/>
<line
x1="5"
y1="0"
x2="5"
y2="10"
/>
</g>
</svg>
);

View File

@@ -1,47 +0,0 @@
import React from 'react';
import './index.scss';
const X = () => {
return (
<svg
width="15px"
height="16px"
viewBox="0 0 15 16"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
className="x"
>
<g
stroke="none"
strokeWidth="1"
fill="none"
fillRule="evenodd"
strokeLinecap="square"
>
<g
transform="translate(7.000000, 8.000000) rotate(-315.000000) translate(-7.000000, -8.000000) translate(-3.500000, -2.500000)"
className="stroke"
>
<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 X;

View File

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

View File

@@ -0,0 +1,31 @@
import React from 'react';
import PropTypes from 'prop-types';
import './index.scss';
const baseClass = 'pill';
const Pill = ({ children, className }) => {
const classes = [
baseClass,
className && className,
].filter(Boolean).join(' ');
return (
<div className={classes}>
{children}
</div>
);
};
Pill.defaultProps = {
children: undefined,
className: '',
};
Pill.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
};
export default Pill;

View File

@@ -0,0 +1,9 @@
@import '../../../scss/styles.scss';
.pill {
@extend %uppercase-label;
color: $black;
border: 1px solid $gray;
border-radius: 3px;
padding: 0 base(.25);
}

View File

@@ -1,7 +1,6 @@
@import '../../../scss/styles.scss';
.sticky-header {
@include gutter;
.sticky-header-wrap {
display: flex;