adds horizontal alignment to popup component, fixes sidebar mobile hard width

This commit is contained in:
Jarrod Flesch
2020-06-29 17:53:45 -04:00
parent 992c3edc69
commit 482bceaf22
14 changed files with 168 additions and 45 deletions

View File

@@ -12,7 +12,7 @@ const baseClass = 'popup';
const Popup = (props) => {
const {
render, align, size, color, pointerAlignment, button, buttonType, children, showOnHover,
render, align, size, color, button, buttonType, children, showOnHover, horizontalAlign,
} = props;
const [active, setActive] = useState(false);
@@ -60,8 +60,8 @@ const Popup = (props) => {
`${baseClass}--align-${align}`,
`${baseClass}--size-${size}`,
`${baseClass}--color-${color}`,
`${baseClass}--pointer-alignment-${pointerAlignment}`,
`${baseClass}--vertical-align-${verticalAlign}`,
`${baseClass}--v-align-${verticalAlign}`,
`${baseClass}--h-align-${horizontalAlign}`,
active && `${baseClass}--active`,
].filter(Boolean).join(' ');
@@ -116,19 +116,19 @@ Popup.defaultProps = {
align: 'center',
size: 'small',
color: 'light',
pointerAlignment: 'left',
children: undefined,
render: undefined,
buttonType: 'default',
button: undefined,
showOnHover: false,
horizontalAlign: 'left',
};
Popup.propTypes = {
render: PropTypes.func,
children: PropTypes.node,
align: PropTypes.oneOf(['left', 'center', 'right']),
pointerAlignment: PropTypes.oneOf(['left', 'center', 'right']),
horizontalAlign: PropTypes.oneOf(['left', 'center', 'right']),
size: PropTypes.oneOf(['small', 'large', 'wide']),
color: PropTypes.oneOf(['light', 'dark']),
buttonType: PropTypes.oneOf(['default', 'custom']),

View File

@@ -14,6 +14,8 @@
content: ' ';
position: absolute;
top: calc(100% - 1px);
border: 12px solid transparent;
border-top-color: white;
}
}
@@ -22,7 +24,7 @@
}
&__scroll {
width: calc(100% + #{$baseline});
padding: base(1);
overflow-y: scroll;
}
@@ -32,21 +34,12 @@
}
////////////////////////////////
// SIZES
// SIZE
////////////////////////////////
&--size-small {
.popup__content {
@include shadow-sm;
&:after {
border: 12px solid transparent;
border-top-color: white;
}
}
.popup__scroll {
padding: base(1) base(2) base(1) base(1);
}
&.popup--align-left {
@@ -60,6 +53,16 @@
}
}
&--size-large {
.popup__content {
@include shadow-lg;
}
.popup__scroll {
padding: base(1) base(1.5);
}
}
&--size-wide {
.popup__content {
@include shadow-sm;
@@ -85,29 +88,55 @@
}
}
&--color-dark {
////////////////////////////////
// HORIZONTAL ALIGNMENT
////////////////////////////////
&--h-align-left {
.popup__content {
background: $color-dark-gray;
color: white;
left: - base(1.75);
&:after {
border-top-color: $color-dark-gray;
left: base(1.75);
}
}
}
&--h-align-center {
.popup__content {
left: 50%;
transform: translateX(-50%);
&:after {
left: 50%;
transform: translateX(-50%);
}
}
}
&--h-align-right {
.popup__content {
right: - base(1.75);
&:after {
right: base(1.75);
}
}
}
////////////////////////////////
// VERTICAL ALIGNMENTS
// VERTICAL ALIGNMENT
////////////////////////////////
&--vertical-align-top {
&--v-align-top {
.popup__content {
bottom: calc(100% + #{$baseline});
}
}
&--vertical-align-bottom {
&--v-align-bottom {
.popup__content {
@include shadow-lg-top;
top: calc(100% + #{$baseline});
&:after {
@@ -120,16 +149,16 @@
}
////////////////////////////////
// POINTER POSITION
// COLOR
////////////////////////////////
&--pointer-alignment-center {
&--color-dark {
.popup__content {
left: 50%;
transform: translateX(-50%);
background: $color-dark-gray;
color: white;
&:after {
left: 50%;
transform: translateX(-50%);
border-top-color: $color-dark-gray;
}
}
}
@@ -144,4 +173,43 @@
visibility: visible;
}
}
@include mid-break {
&__scroll,
&--size-large .popup__scroll{
padding: base(.75);
}
&--h-align-left {
.popup__content {
left: - base(.5);
&:after {
left: base(.5);
}
}
}
&--h-align-center {
.popup__content {
left: 50%;
transform: translateX(-50%);
&:after {
left: 50%;
transform: translateX(-50%);
}
}
}
&--h-align-right {
.popup__content {
right: - base(.5);
&:after {
right: base(.5);
}
}
}
}
}

View File

@@ -11,11 +11,16 @@ const baseClass = 'action-panel';
const ActionPanel = (props) => {
const {
addRow, removeRow, singularLabel, verticalAlignment, useFlexibleBlockSelection, blocks, rowIndex,
addRow,
removeRow,
singularLabel,
verticalAlignment,
useFlexibleBlockSelection,
blocks,
rowIndex,
isHovered,
} = props;
console.log(blocks);
const classes = [
baseClass,
`${baseClass}--vertical-alignment-${verticalAlignment}`,
@@ -29,7 +34,7 @@ const ActionPanel = (props) => {
showOnHover
size="wide"
color="dark"
pointerAlignment="center"
horizontalAlign="center"
buttonType="custom"
button={(
<Button
@@ -51,6 +56,8 @@ const ActionPanel = (props) => {
? (
<Popup
buttonType="custom"
size="large"
horizontalAlign="right"
button={(
<Button
className={`${baseClass}__add-row`}
@@ -67,6 +74,8 @@ const ActionPanel = (props) => {
addRow={addRow}
addRowIndex={rowIndex}
close={close}
parentIsHovered={isHovered}
watchParentHover
/>
)}
/>
@@ -76,7 +85,7 @@ const ActionPanel = (props) => {
showOnHover
size="wide"
color="dark"
pointerAlignment="center"
horizontalAlign="right"
buttonType="custom"
button={(
<Button
@@ -105,6 +114,7 @@ ActionPanel.defaultProps = {
singularLabel: 'Row',
verticalAlignment: 'center',
useFlexibleBlockSelection: false,
isHovered: false,
};
ActionPanel.propTypes = {
@@ -113,6 +123,7 @@ ActionPanel.propTypes = {
removeRow: PropTypes.func.isRequired,
useFlexibleBlockSelection: PropTypes.bool,
verticalAlignment: PropTypes.oneOf(['top', 'center', 'sticky']),
isHovered: PropTypes.bool,
};
export default ActionPanel;

View File

@@ -8,15 +8,17 @@
&__controls-container {
position: relative;
height: 100%;
z-index: $z-nav;
}
&__controls {
z-index: $z-nav;
display: flex;
justify-content: center;
height: 100%;
flex-direction: column;
color: $color-gray;
opacity: 0;
visibility: hidden;
}
&--vertical-alignment-top {
@@ -35,11 +37,9 @@
&__remove-row {
margin: 0 0 base(.3);
opacity: 0;
}
&__add-row {
margin: base(.3) 0 0;
opacity: 0;
}
}

View File

@@ -13,7 +13,7 @@ $controls-top-adjustment: base(.1);
}
&__controls {
padding-right: base(.75);
padding-right: base(1.25);
display: flex;
flex-direction: column;
justify-content: center;

View File

@@ -31,8 +31,6 @@ const DraggableSection = (props) => {
positionPanelVerticalAlignment,
actionPanelVerticalAlignment,
toggleRowCollapse,
blocks,
useCustomBlockSelection,
} = props;
const [isHovered, setIsHovered] = useState(false);
@@ -112,6 +110,7 @@ const DraggableSection = (props) => {
addRow={addRow}
singularLabel={singularLabel}
verticalAlignment={actionPanelVerticalAlignment}
isHovered={isHovered}
{...props}
/>
</div>

View File

@@ -41,6 +41,10 @@
margin-bottom: base(.5);
}
.draggable-section__content-wrapper {
margin-bottom: 0;
}
&.is-closed {
.draggable-section__content-wrapper {
margin-bottom: base(1.75);
@@ -81,9 +85,9 @@
}
> .action-panel {
.action-panel__add-row,
.action-panel__remove-row {
.action-panel__controls {
opacity: 1;
visibility: visible;
}
}

View File

@@ -21,4 +21,10 @@ $icon-margin: base(.25);
width: $icon-width;
margin: 0 $icon-margin;
}
@include mid-break {
&__input {
margin-bottom: 0;
}
}
}

View File

@@ -17,6 +17,7 @@ const BlockSelection = (props) => {
} = block;
const handleBlockSelection = () => {
console.log('adding');
close();
addRow(addRowIndex, slug);
};

View File

@@ -7,6 +7,7 @@
display: flex;
flex-wrap: wrap;
align-items: center;
min-width: 300px;
max-width: 450px;
max-height: 300px;
position: relative;

View File

@@ -7,10 +7,13 @@ import BlocksContainer from './BlocksContainer';
const baseClass = 'block-selector';
const BlockSelector = (props) => {
const { blocks, ...remainingProps } = props;
const {
blocks, close, parentIsHovered, watchParentHover, ...remainingProps
} = props;
const [searchTerm, setSearchTerm] = useState('');
const [filteredBlocks, setFilteredBlocks] = useState(blocks);
const [isBlockSelectorHovered, setBlockSelectorHovered] = useState(false);
useEffect(() => {
const matchingBlocks = blocks.reduce((matchedBlocks, block) => {
@@ -21,21 +24,37 @@ const BlockSelector = (props) => {
setFilteredBlocks(matchingBlocks);
}, [searchTerm, blocks]);
useEffect(() => {
if (!parentIsHovered && !isBlockSelectorHovered && close && watchParentHover) close();
}, [isBlockSelectorHovered, parentIsHovered, close, watchParentHover]);
return (
<div className={baseClass}>
<div
className={baseClass}
onMouseEnter={() => setBlockSelectorHovered(true)}
onMouseLeave={() => setBlockSelectorHovered(false)}
>
<BlockSearch setSearchTerm={setSearchTerm} />
<BlocksContainer
blocks={filteredBlocks}
close={close}
{...remainingProps}
/>
</div>
);
};
BlockSelector.defaultProps = {};
BlockSelector.defaultProps = {
close: null,
parentIsHovered: false,
watchParentHover: false,
};
BlockSelector.propTypes = {
blocks: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
close: PropTypes.func,
watchParentHover: PropTypes.bool,
parentIsHovered: PropTypes.bool,
};
export default BlockSelector;

View File

@@ -199,6 +199,8 @@ const Flexible = (props) => {
<div className={`${baseClass}__add-button-wrap`}>
<Popup
buttonType="custom"
size="large"
horizontalAlign="left"
button={(
<Button
buttonStyle="icon-label"

View File

@@ -136,6 +136,10 @@
}
@include mid-break {
&__sidebar {
width: unset;
}
&__form {
display: block;
}

View File

@@ -61,6 +61,14 @@ $style-stroke-width-m : 2px;
box-shadow: 0 2px 3px 0 rgba(0, 2, 4, 0.1), 0 6px 4px -4px rgba(0, 2, 4, 0.02);
}
@mixin shadow-lg {
box-shadow: 0 2px 20px 7px rgba(0, 2, 4, 0.1), 0 6px 4px -4px rgba(0, 2, 4, 0.02);
}
@mixin shadow-lg-top {
box-shadow: 0 -2px 20px 7px rgba(0, 2, 4, 0.1), 0 6px 4px -4px rgba(0, 2, 4, 0.02);
}
@mixin shadow {
box-shadow: 0 12px 45px rgba(0,0,0,.03);