Skip to content

Commit

Permalink
Custom Edit Block Wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
avoinea committed Mar 23, 2021
1 parent a83216e commit 5b83746
Show file tree
Hide file tree
Showing 3 changed files with 274 additions and 2 deletions.
48 changes: 47 additions & 1 deletion src/components/manage/Blocks/Group/Edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { Icon } from '@plone/volto/components';
import delightedSVG from '@plone/volto/icons/delighted.svg';
import dissatisfiedSVG from '@plone/volto/icons/dissatisfied.svg';
import PropTypes from 'prop-types';
import { Button } from 'semantic-ui-react';
import EditBlockWrapper from './EditBlockWrapper';
import tuneSVG from '@plone/volto/icons/configuration.svg';
import helpSVG from '@plone/volto/icons/help.svg';

import './editor.less';

const Edit = (props) => {
Expand Down Expand Up @@ -130,7 +135,48 @@ const Edit = (props) => {
}
}}
pathname={pathname}
/>
>
{({ draginfo }, editBlock, blockProps) => (
<EditBlockWrapper
draginfo={draginfo}
blockProps={blockProps}
extraControls={
<>
{!data?.readOnlySettings && (
<>
{manage ? (
<Button
icon
basic
title="Group settings"
onClick={() => {
setSelectedBlock();
props.setSidebarTab(1);
}}
>
<Icon name={tuneSVG} className="" size="19px" />
</Button>
) : (
<Button
icon
basic
title="Help"
onClick={() => {
props.setSidebarTab(1);
}}
>
<Icon name={helpSVG} className="" size="19px" />
</Button>
)}
</>
)}
</>
}
>
{editBlock}
</EditBlockWrapper>
)}
</BlocksForm>

{counterComponent}
</section>
Expand Down
164 changes: 164 additions & 0 deletions src/components/manage/Blocks/Group/EditBlockWrapper.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import React from 'react';
import { Icon, BlockChooser } from '@plone/volto/components';
import { blockHasValue } from '@plone/volto/helpers';
import config from '@plone/volto/registry';
import { Button } from 'semantic-ui-react';
import includes from 'lodash/includes';
import isBoolean from 'lodash/isBoolean';
import { defineMessages, injectIntl } from 'react-intl';
import { doesNodeContainClick } from 'semantic-ui-react/dist/commonjs/lib';
import cx from 'classnames';

import dragSVG from '@plone/volto/icons/drag.svg';
import addSVG from '@plone/volto/icons/circle-plus.svg';
import trashSVG from '@plone/volto/icons/delete.svg';

const messages = defineMessages({
unknownBlock: {
id: 'Unknown Block',
defaultMessage: 'Unknown Block {block}',
},
delete: {
id: 'delete',
defaultMessage: 'delete',
},
});

class EditBlockWrapper extends React.Component {
constructor(props) {
super(props);
this.state = {
addNewBlockOpened: false,
};
}

componentDidMount() {
document.addEventListener('mousedown', this.handleClickOutside, false);
}

componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClickOutside);
}

handleClickOutside = (e) => {
if (
this.blockNode.current &&
doesNodeContainClick(this.blockNode.current, e)
)
return;

if (this.state.addNewBlockOpened) {
this.setState({
addNewBlockOpened: false,
});
return true;
}
};

blockNode = React.createRef();

render() {
const { intl, blockProps, draginfo, extraControls, children } = this.props;

const {
allowedBlocks,
block,
data,
onDeleteBlock,
onMutateBlock,
selected,
} = blockProps;
const type = data['@type'];
const { disableNewBlocks } = data;
const visible = !data.fixed;

const required = isBoolean(data.required)
? data.required
: includes(config.blocks.requiredBlocks, type);

return (
<div ref={this.blockNode}>
<div
ref={draginfo?.innerRef}
{...(selected ? draginfo?.draggableProps : null)}
className={`block-editor-${data['@type']}`}
>
{!selected && (
<div
style={{
display: 'none',
// keep react-beautiful-dnd happy
}}
{...draginfo.dragHandleProps}
></div>
)}
{selected && (
<div className="block-toolbar">
<div
style={{
display: visible ? 'inline-block' : 'none',
}}
{...draginfo.dragHandleProps}
className="drag handle wrapper-group-block"
>
<Button icon basic title="Drag and drop">
<Icon name={dragSVG} size="19px" />
</Button>
</div>

{extraControls}

{!disableNewBlocks && !blockHasValue(data) && (
<Button
icon
basic
title="Add block"
onClick={() => {
this.setState({
addNewBlockOpened: !this.state.addNewBlockOpened,
});
}}
className="group-block-add-button"
>
<Icon name={addSVG} className="" size="19px" />
</Button>
)}
{!required && (
<Button
icon
basic
title="Remove block"
onClick={() => onDeleteBlock(block)}
className="delete-button-group-block"
aria-label={intl.formatMessage(messages.delete)}
>
<Icon name={trashSVG} size="19px" />
</Button>
)}
{this.state.addNewBlockOpened && (
<BlockChooser
onMutateBlock={(id, value) => {
this.setState({ addNewBlockOpened: false });
onMutateBlock(id, value);
}}
currentBlock={block}
allowedBlocks={allowedBlocks}
/>
)}
</div>
)}

<div
className={cx('ui drag block wrapper inner', type, {
multiSelected: this.props.multiSelected,
})}
>
{children}
</div>
</div>
</div>
);
}
}

export default injectIntl(EditBlockWrapper);
64 changes: 63 additions & 1 deletion src/components/manage/Blocks/Group/editor.less
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,20 @@
margin: 0 0.1rem;
}

.selected {
.delete-button {
display: none !important;
}

.block-add-button {
display: none !important;
}
}

.block.group.selected::before,
.block.group:hover::before {
border-style: dashed;
border-radius: 1rem;
border-radius: .5rem;
}

.section-block {
Expand All @@ -24,4 +34,56 @@
grid-gap: 0.5em;
grid-template-columns: 98% auto;
}

.blocks-chooser {
margin-top: 50px;
left: auto;
right: 0;
}

.block-toolbar {
position: absolute;
z-index: 3;
right: -9px;
display: flex;
padding: 5px;
border: none;
border: 1px solid #78c0d7bf;
border-bottom: 1px solid #fff;
margin-top: -45px;
background-color: #fff;

.ui.basic.button {
padding: 3px;
padding-right: 0;
}

.wrapper-column-block {
> .ui.basic.button {
&:hover {
background-color: transparent !important;
}
}
}

> .ui.basic.button {
&:hover {
background-color: transparent !important;
}

svg {
color: #134448;
}
}

.drag.handle.wrapper-column-block {
position: initial;
left: initial;
min-height: 1em;
margin-left: initial !important;
font-size: 1rem;
line-height: 1em;
vertical-align: baseline;
}
}
}

0 comments on commit 5b83746

Please sign in to comment.