+ className={classNames(
+ 'children-container',
+ snapshot.isDraggingOver && 'is-dragging',
+ gutteredAdd && 'guttered-add')}>
{blocksIds.map(blockId => this.renderBlock(blockId, canAdd))}
diff --git a/src/StreamField.js b/src/StreamField.js
index e2357ad..3deef57 100644
--- a/src/StreamField.js
+++ b/src/StreamField.js
@@ -112,6 +112,7 @@ class StreamField extends React.Component {
duplicate: PropTypes.string,
delete: PropTypes.string,
}),
+ gutteredAdd: PropTypes.bool,
blockDefinitions: PropTypes.arrayOf(BlockDefinitionType).isRequired,
value: PropTypes.arrayOf(BlockValueType).isRequired,
};
@@ -145,15 +146,15 @@ class StreamField extends React.Component {
componentDidMount() {
const {
- initializeStreamField, required, minNum, maxNum, blockDefinitions, value,
+ initializeStreamField, required, minNum, maxNum, gutteredAdd,
+ blockDefinitions, value,
} = this.props;
const defaultProps = StreamFieldDefaultProps;
const icons = {...defaultProps.icons, ...this.props.icons};
const labels = {...defaultProps.labels, ...this.props.labels};
initializeStreamField({
- required, minNum, maxNum, icons, labels, blockDefinitions,
- isMobile: getIsMobile(),
- value,
+ required, minNum, maxNum, icons, labels, gutteredAdd,
+ blockDefinitions, isMobile: getIsMobile(), value,
});
window.addEventListener('resize', this.onWindowResize);
}
diff --git a/src/index.scss b/src/index.scss
index 64b32b7..64a242d 100644
--- a/src/index.scss
+++ b/src/index.scss
@@ -1,7 +1,7 @@
$grid-gutter-width: 30px;
$header-padding: 8px;
-$block-vertical-margin: 3px;
-$block-full-margin: $block-vertical-margin 0;
+$block-vertical-padding: 3px;
+$block-full-padding: $block-vertical-padding 0;
$add-button-size: 34px;
$add-button-font-size: 28px;
$children-container-padding: $add-button-size / 2;
@@ -21,18 +21,25 @@ $error-border-color: #dbc7c8;
$error-border-color-focus: #cdb2b3;
$error-background-color: #fbefef;
$screen-xs-max: 799px;
+$screen-sm-min: 800px;
.children-container {
position: relative;
padding: $children-container-padding 0
- $children-container-padding $add-button-size;
+ $children-container-padding 0;
transition: padding $hover-transition-duration ease-in-out;
- @media (max-width: $screen-xs-max) {
- padding-left: 0;
- padding-top: $children-container-padding + $add-button-size;
+ &.guttered-add {
+ @media (min-width: $screen-sm-min) {
+ padding-left: $add-button-size;
+ button.add {
+ position: absolute;
+ width: $add-button-size;
+ transform: translate(-100%, -50%);
+ }
+ }
}
&.is-dragging {
- > button.add.visible {
+ button.add.visible {
opacity: 0;
pointer-events: none;
}
@@ -40,10 +47,7 @@ $screen-xs-max: 799px;
.block {
position: relative;
display: flex;
- margin: $block-full-margin;
- @media (max-width: $screen-xs-max) {
- margin-bottom: $block-vertical-margin + $add-button-size;
- }
+ padding: $block-full-padding;
&.has-error {
> .block-container {
border-color: $error-border-color;
@@ -209,15 +213,13 @@ $screen-xs-max: 799px;
}
}
button.add {
- position: absolute;
- width: $add-button-size;
+ width: 100%;
height: $add-button-size;
appearance: none;
border: none;
color: $teal;
font-weight: bold;
background: none;
- transform: translate(-100%, -50%);
padding: 0;
cursor: pointer;
outline: none;
@@ -231,10 +233,6 @@ $screen-xs-max: 799px;
opacity: 1;
pointer-events: unset;
}
- @media (max-width: $screen-xs-max) {
- width: 100%;
- transform: translate(0, -100%);
- }
i {
display: block;
transition: transform $add-transition-duration $bounce-transition-timing;
diff --git a/src/reducer.js b/src/reducer.js
index b4a624d..fcbc8be 100644
--- a/src/reducer.js
+++ b/src/reducer.js
@@ -21,13 +21,14 @@ export default (state=initialState, action) => {
case 'INITIALIZE_STREAM_FIELD': {
const data = deepCopy(action.data);
const {
- required, minNum, maxNum, icons, labels, blockDefinitions, isMobile,
- value,
+ required, minNum, maxNum, icons, labels, gutteredAdd,
+ blockDefinitions, isMobile, value,
} = data;
state = {
...state,
[action.id]: {
- required, minNum, maxNum, icons, labels, blockDefinitions, isMobile,
+ required, minNum, maxNum, icons, labels, gutteredAdd,
+ blockDefinitions, isMobile,
},
};
return valueToState(state, action.id, value);