diff --git a/src/client/components/forms/DraggableSection/ActionPanel/index.js b/src/client/components/forms/DraggableSection/ActionPanel/index.js index 7599539e84..d27399a0bc 100644 --- a/src/client/components/forms/DraggableSection/ActionPanel/index.js +++ b/src/client/components/forms/DraggableSection/ActionPanel/index.js @@ -23,95 +23,89 @@ const ActionPanel = (props) => { const classes = [ baseClass, - `${baseClass}--vertical-alignment-${verticalAlignment}`, ].filter(Boolean).join(' '); return (
-
-
+ + )} + > + Remove  + {singularLabel} + + + {blockType === 'blocks' + ? ( + + )} + render={({ close }) => ( + + )} + /> + ) + : ( )} > - Remove  + Add  {singularLabel} - - {blockType === 'blocks' - ? ( - - )} - render={({ close }) => ( - - )} - /> - ) - : ( - - )} - > - Add  - {singularLabel} - - )} -
-
+ )}
); }; ActionPanel.defaultProps = { singularLabel: 'Row', - verticalAlignment: 'center', blockType: null, isHovered: false, blocks: [], @@ -125,7 +119,6 @@ ActionPanel.propTypes = { blocks: PropTypes.arrayOf( PropTypes.shape({}), ), - verticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']), isHovered: PropTypes.bool, rowIndex: PropTypes.number.isRequired, }; diff --git a/src/client/components/forms/DraggableSection/ActionPanel/index.scss b/src/client/components/forms/DraggableSection/ActionPanel/index.scss index 0bb10dc109..d4b962ea01 100644 --- a/src/client/components/forms/DraggableSection/ActionPanel/index.scss +++ b/src/client/components/forms/DraggableSection/ActionPanel/index.scss @@ -1,43 +1,10 @@ @import '../../../../scss/styles'; .action-panel { - padding: 0 base(.5); - padding-left: base(.75); - margin-bottom: base(1); - &:hover { z-index: $z-nav; } - &__controls-container { - position: relative; - height: 100%; - } - - &__controls { - display: flex; - justify-content: center; - height: 100%; - flex-direction: column; - color: $color-gray; - opacity: 0; - visibility: hidden; - } - - &--vertical-alignment-top { - .action-panel__controls { - justify-content: flex-start; - } - } - - &--vertical-alignment-sticky { - .action-panel__controls { - position: sticky; - top: $top-header-offset; - height: unset; - } - } - &__remove-row { margin: 0 0 base(.3); } @@ -45,17 +12,4 @@ &__add-row { margin: base(.3) 0 0; } - - @include mid-break { - &__controls { - opacity: 1; - visibility: visible; - } - - &--vertical-alignment-sticky { - .action-panel__controls { - top: 100px; - } - } - } } diff --git a/src/client/components/forms/DraggableSection/PositionPanel/index.js b/src/client/components/forms/DraggableSection/PositionPanel/index.js index 8b8c54214b..0382c47f51 100644 --- a/src/client/components/forms/DraggableSection/PositionPanel/index.js +++ b/src/client/components/forms/DraggableSection/PositionPanel/index.js @@ -2,64 +2,53 @@ import React from 'react'; import PropTypes from 'prop-types'; import Button from '../../../elements/Button'; +import RenderFieldGutter from '../../RenderFieldGutter'; import './index.scss'; const baseClass = 'position-panel'; const PositionPanel = (props) => { - const { - dragHandleProps, moveRow, positionIndex, verticalAlignment, rowCount, - } = props; + const { moveRow, positionIndex, rowCount } = props; const adjustedIndex = positionIndex + 1; const classes = [ baseClass, - `${baseClass}--vertical-alignment-${verticalAlignment}`, ].filter(Boolean).join(' '); return ( -
-
-
+
+
-
+
); }; PositionPanel.defaultProps = { - verticalAlignment: 'center', + positionIndex: null, }; PositionPanel.propTypes = { - dragHandleProps: PropTypes.shape({}).isRequired, - positionIndex: PropTypes.number.isRequired, + positionIndex: PropTypes.number, moveRow: PropTypes.func.isRequired, - verticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']), rowCount: PropTypes.number.isRequired, }; diff --git a/src/client/components/forms/DraggableSection/PositionPanel/index.scss b/src/client/components/forms/DraggableSection/PositionPanel/index.scss index 7f3af35ff3..524800724e 100644 --- a/src/client/components/forms/DraggableSection/PositionPanel/index.scss +++ b/src/client/components/forms/DraggableSection/PositionPanel/index.scss @@ -1,39 +1,6 @@ @import '../../../../scss/styles'; -$controls-top-adjustment: base(.1); - .position-panel { - padding-right: base(1); - margin-bottom: base(1); - - &__controls-container { - position: relative; - min-height: 100%; - box-shadow: #{$style-stroke-width-s} 0px 0px 0px $color-light-gray; - } - - &__controls { - padding-right: base(.65); - display: flex; - flex-direction: column; - justify-content: center; - height: 100%; - } - - &--vertical-alignment-top { - .position-panel__controls { - justify-content: flex-start; - } - } - - &--vertical-alignment-sticky { - .position-panel__controls { - position: sticky; - top: $top-header-offset; - height: unset; - } - } - &__move-backward { transform: rotate(.5turn); margin: 0; @@ -51,24 +18,14 @@ $controls-top-adjustment: base(.1); } @include large-break { - padding-right: base(1); + padding-right: 0; &__controls { padding-right: base(.75); } } -} - -// External scopes -.field-type.blocks { - .position-panel { - &__controls-container { - min-height: calc(100% + #{$controls-top-adjustment}); - } - - &__controls { - margin-top: - $controls-top-adjustment; - } + @include mid-break { + padding-right: 0; } } diff --git a/src/client/components/forms/DraggableSection/SectionTitle/EditableBlockTitle/index.scss b/src/client/components/forms/DraggableSection/SectionTitle/EditableBlockTitle/index.scss index 45dd0f79b3..b9e20933b4 100644 --- a/src/client/components/forms/DraggableSection/SectionTitle/EditableBlockTitle/index.scss +++ b/src/client/components/forms/DraggableSection/SectionTitle/EditableBlockTitle/index.scss @@ -25,9 +25,7 @@ } input { - background: transparent; border: none; - border-radius: $style-radius-s; width: 100%; margin-left: base(.5); diff --git a/src/client/components/forms/DraggableSection/index.js b/src/client/components/forms/DraggableSection/index.js index 8b95ee9db2..522db3502f 100644 --- a/src/client/components/forms/DraggableSection/index.js +++ b/src/client/components/forms/DraggableSection/index.js @@ -6,10 +6,12 @@ import { Draggable } from 'react-beautiful-dnd'; import ActionPanel from './ActionPanel'; import SectionTitle from './SectionTitle'; import PositionPanel from './PositionPanel'; +import Button from '../../elements/Button'; +import RenderFieldGutter from '../RenderFieldGutter'; import RenderFields from '../RenderFields'; + import './index.scss'; -import Button from '../../elements/Button'; const baseClass = 'draggable-section'; @@ -60,13 +62,17 @@ const DraggableSection = (props) => { >
- + > + +
@@ -105,18 +111,23 @@ const DraggableSection = (props) => { />
- - {!readOnly && ( - - )} + + {!readOnly && ( + + )} +
)} diff --git a/src/client/components/forms/DraggableSection/index.scss b/src/client/components/forms/DraggableSection/index.scss index db0bca6131..f917b2e95d 100644 --- a/src/client/components/forms/DraggableSection/index.scss +++ b/src/client/components/forms/DraggableSection/index.scss @@ -5,26 +5,26 @@ ////////////////////// @mixin relatively-position-panels { - .position-panel { + .render-field-gutter { position: relative; right: 0; } - .action-panel { + .render-field-gutter.actions { position: relative; left: 0; } } @mixin absolutely-position-panels { - .position-panel { + .render-field-gutter { position: absolute; top: 0; right: 100%; bottom: 0; } - .action-panel { + .render-field-gutter.actions { position: absolute; - top: 0; bottom: 0; left: 100%; + top: 0; bottom: 0; left: 100%; right: unset; } } @@ -65,6 +65,10 @@ margin: 0 0 0 auto; transform: rotate(.5turn); + .btn__icon { + background-color: white; + } + &--is-closed { transform: rotate(0turn); } @@ -76,8 +80,13 @@ } &.is-hovered > div { - > .position-panel { - .position-panel__controls-container { + > .render-field-gutter { + &.actions { + .render-field-gutter__content-container { + box-shadow: none; + } + } + .render-field-gutter__content-container { box-shadow: #{$style-stroke-width-m} 0px 0px 0px $color-dark-gray; } @@ -157,6 +166,14 @@ @include relatively-position-panels(); } +.field-type.group { + @include absolutely-position-panels(); + + @include mid-break { + @include relatively-position-panels(); + } +} + // remove padding above array rows to level // the line with the top of the input label .field-type.array { diff --git a/src/client/components/forms/RenderFieldGutter/index.js b/src/client/components/forms/RenderFieldGutter/index.js new file mode 100644 index 0000000000..247e90e54e --- /dev/null +++ b/src/client/components/forms/RenderFieldGutter/index.js @@ -0,0 +1,42 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import './index.scss'; + +const baseClass = 'render-field-gutter'; + +const RenderFieldGutter = (props) => { + const { children, variant, verticalAlignment, className, dragHandleProps } = props; + + const classes = [ + baseClass, + `${baseClass}--${variant}`, + `${baseClass}--v-align-${verticalAlignment}`, + className && className + ].filter(Boolean).join(' '); + + return ( +
+
+
+ {children} +
+
+
+ ); +} + +const { oneOf } = PropTypes; + +RenderFieldGutter.defaultProps = { + variant: 'left', + verticalAlignment: 'sticky', + dragHandleProps: {}, +} + +RenderFieldGutter.propTypes = { + variant: oneOf(['left', 'right']), + verticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']), +} + +export default RenderFieldGutter; diff --git a/src/client/components/forms/RenderFieldGutter/index.scss b/src/client/components/forms/RenderFieldGutter/index.scss new file mode 100644 index 0000000000..ca8bac1e29 --- /dev/null +++ b/src/client/components/forms/RenderFieldGutter/index.scss @@ -0,0 +1,72 @@ +@import '../../../scss/styles.scss'; + +$controls-top-adjustment: base(.1); + +.render-field-gutter { + padding-right: base(1.25); + margin-bottom: base(1); + + &--right { + padding-right: 0; + padding-left: base(1.25); + + .render-field-gutter__content { + margin-bottom: base(1); + } + + .render-field-gutter__content-container { + padding-right: 0; + box-shadow: none; + } + } + + &--v-align-top { + .render-field-gutter__content { + justify-content: flex-start; + } + } + + &--v-align-sticky { + .render-field-gutter__content { + position: sticky; + top: $top-header-offset; + height: unset; + } + } + + &__content-container { + padding-right: base(.75); + position: relative; + min-height: 100%; + box-shadow: #{$style-stroke-width-s} 0px 0px 0px $color-light-gray; + } + + &__content { + display: flex; + flex-direction: column; + justify-content: center; + height: 100%; + } + + @include mid-break { + padding-right: base(1); + + &--right { + padding-right: 0; + } + } +} + + +// External scopes +.field-type.blocks { + .render-field-gutter { + &__content-container { + min-height: calc(100% + #{$controls-top-adjustment}); + } + + &__content { + margin-top: - $controls-top-adjustment; + } + } +} diff --git a/src/client/components/forms/field-types/Group/index.js b/src/client/components/forms/field-types/Group/index.js index ab11f5c47e..dc377a29d3 100644 --- a/src/client/components/forms/field-types/Group/index.js +++ b/src/client/components/forms/field-types/Group/index.js @@ -2,9 +2,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import RenderFields, { useRenderedFields } from '../../RenderFields'; import withCondition from '../../withCondition'; +import RenderFieldGutter from '../../RenderFieldGutter'; import './index.scss'; +const baseClass = 'group'; + const Group = (props) => { const { label, @@ -23,16 +26,19 @@ const Group = (props) => { return (
-

{label}

- ({ - ...subField, - path: `${path}${subField.name ? `.${subField.name}` : ''}`, - }))} - /> +

{label}

+
+ + ({ + ...subField, + path: `${path}${subField.name ? `.${subField.name}` : ''}`, + }))} + /> +
); }; diff --git a/src/client/components/forms/field-types/Group/index.scss b/src/client/components/forms/field-types/Group/index.scss index 8d255db8b7..d22ee639d0 100644 --- a/src/client/components/forms/field-types/Group/index.scss +++ b/src/client/components/forms/field-types/Group/index.scss @@ -1,3 +1,28 @@ -.field-group { +@import '../../../../scss/styles.scss'; +.group { + &:hover { + .render-field-gutter__content-container { + box-shadow: #{$style-stroke-width-m} 0px 0px 0px $color-dark-gray; + } + } + + &__fields-wrapper { + position: relative; + } + + .render-fields { + width: 100%; + } + + @include mid-break { + &__fields-wrapper { + display: flex; + } + + .render-field-gutter__content-container { + padding-right: 0; + padding-left: 2px; + } + } } diff --git a/src/client/scss/vars.scss b/src/client/scss/vars.scss index de3f83d948..2c11430d73 100644 --- a/src/client/scss/vars.scss +++ b/src/client/scss/vars.scss @@ -54,6 +54,12 @@ $style-stroke-width : 1px; $style-stroke-width-s : 1px; $style-stroke-width-m : 2px; + +////////////////////////////// +// MISC +////////////////////////////// +$top-header-offset: 120px; + ////////////////////////////// // MISC //////////////////////////////