This repository has been archived by the owner on Apr 25, 2024. It is now read-only.
generated from eea/volto-addon-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #39 from eea/develop
Custom Block & add stretch class in block wrapper
- Loading branch information
Showing
10 changed files
with
631 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
216 changes: 216 additions & 0 deletions
216
src/customizations/volto/components/manage/Blocks/Block/BlocksForm.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
import React from 'react'; | ||
import EditBlock from './Edit'; | ||
import { DragDropList } from '@plone/volto/components'; | ||
import { getBlocks } from '@plone/volto/helpers'; | ||
import { | ||
addBlock, | ||
insertBlock, | ||
changeBlock, | ||
deleteBlock, | ||
moveBlock, | ||
mutateBlock, | ||
nextBlockId, | ||
previousBlockId, | ||
} from '@plone/volto/helpers'; | ||
import EditBlockWrapper from './EditBlockWrapper'; | ||
import { setSidebarTab } from '@plone/volto/actions'; | ||
import { useDispatch } from 'react-redux'; | ||
import { useDetectClickOutside } from '@plone/volto/helpers'; | ||
import config from '@plone/volto/registry'; | ||
|
||
const BlocksForm = (props) => { | ||
const { | ||
pathname, | ||
onChangeField, | ||
properties, | ||
onChangeFormData, | ||
selectedBlock, | ||
multiSelected, | ||
onSelectBlock, | ||
allowedBlocks, | ||
showRestricted, | ||
title, | ||
description, | ||
metadata, | ||
manage, | ||
children, | ||
isMainForm = true, | ||
blocksConfig = config.blocks.blocksConfig, | ||
editable = true, | ||
} = props; | ||
|
||
const blockList = getBlocks(properties); | ||
|
||
const dispatch = useDispatch(); | ||
|
||
const ClickOutsideListener = () => { | ||
onSelectBlock(null); | ||
dispatch(setSidebarTab(0)); | ||
}; | ||
|
||
const ref = useDetectClickOutside({ | ||
onTriggered: ClickOutsideListener, | ||
triggerKeys: ['Escape'], | ||
// Disabled feature for now https://github.com/plone/volto/pull/2389#issuecomment-830027413 | ||
disableClick: true, | ||
disableKeys: !isMainForm, | ||
}); | ||
|
||
const handleKeyDown = ( | ||
e, | ||
index, | ||
block, | ||
node, | ||
{ | ||
disableEnter = false, | ||
disableArrowUp = false, | ||
disableArrowDown = false, | ||
} = {}, | ||
) => { | ||
const isMultipleSelection = e.shiftKey; | ||
if (e.key === 'ArrowUp' && !disableArrowUp) { | ||
onFocusPreviousBlock(block, node, isMultipleSelection); | ||
e.preventDefault(); | ||
} | ||
if (e.key === 'ArrowDown' && !disableArrowDown) { | ||
onFocusNextBlock(block, node, isMultipleSelection); | ||
e.preventDefault(); | ||
} | ||
if (e.key === 'Enter' && !disableEnter) { | ||
onAddBlock(config.settings.defaultBlockType, index + 1); | ||
e.preventDefault(); | ||
} | ||
}; | ||
|
||
const onFocusPreviousBlock = ( | ||
currentBlock, | ||
blockNode, | ||
isMultipleSelection, | ||
) => { | ||
const prev = previousBlockId(properties, currentBlock); | ||
if (prev === null) return; | ||
|
||
blockNode.blur(); | ||
|
||
onSelectBlock(prev, isMultipleSelection); | ||
}; | ||
|
||
const onFocusNextBlock = (currentBlock, blockNode, isMultipleSelection) => { | ||
const next = nextBlockId(properties, currentBlock); | ||
if (next === null) return; | ||
|
||
blockNode.blur(); | ||
|
||
onSelectBlock(next, isMultipleSelection); | ||
}; | ||
|
||
const onMutateBlock = (id, value) => { | ||
const newFormData = mutateBlock(properties, id, value); | ||
onChangeFormData(newFormData); | ||
}; | ||
|
||
const onInsertBlock = (id, value) => { | ||
const [newId, newFormData] = insertBlock(properties, id, value); | ||
onChangeFormData(newFormData); | ||
return newId; | ||
}; | ||
|
||
const onAddBlock = (type, index) => { | ||
if (editable) { | ||
const [id, newFormData] = addBlock(properties, type, index); | ||
onChangeFormData(newFormData); | ||
return id; | ||
} | ||
}; | ||
|
||
const onChangeBlock = (id, value) => { | ||
const newFormData = changeBlock(properties, id, value); | ||
onChangeFormData(newFormData); | ||
}; | ||
|
||
const onDeleteBlock = (id, selectPrev) => { | ||
const previous = previousBlockId(properties, id); | ||
|
||
const newFormData = deleteBlock(properties, id); | ||
onChangeFormData(newFormData); | ||
|
||
onSelectBlock(selectPrev ? previous : null); | ||
}; | ||
|
||
const onMoveBlock = (dragIndex, hoverIndex) => { | ||
const newFormData = moveBlock(properties, dragIndex, hoverIndex); | ||
onChangeFormData(newFormData); | ||
}; | ||
|
||
const defaultBlockWrapper = ({ draginfo }, editBlock, blockProps) => ( | ||
<EditBlockWrapper draginfo={draginfo} blockProps={blockProps}> | ||
{editBlock} | ||
</EditBlockWrapper> | ||
); | ||
|
||
const editBlockWrapper = children || defaultBlockWrapper; | ||
|
||
return ( | ||
<div className="blocks-form" ref={ref}> | ||
<fieldset className="invisible" disabled={!editable}> | ||
<DragDropList | ||
childList={blockList} | ||
onMoveItem={(result) => { | ||
const { source, destination } = result; | ||
if (!destination) { | ||
return; | ||
} | ||
const newFormData = moveBlock( | ||
properties, | ||
source.index, | ||
destination.index, | ||
); | ||
onChangeFormData(newFormData); | ||
return true; | ||
}} | ||
> | ||
{(dragProps) => { | ||
const { child, childId, index } = dragProps; | ||
const blockProps = { | ||
allowedBlocks, | ||
showRestricted, | ||
block: childId, | ||
data: child, | ||
handleKeyDown, | ||
id: childId, | ||
formTitle: title, | ||
formDescription: description, | ||
index, | ||
manage, | ||
onAddBlock, | ||
onInsertBlock, | ||
onChangeBlock, | ||
onChangeField, | ||
onDeleteBlock, | ||
onFocusNextBlock, | ||
onFocusPreviousBlock, | ||
onMoveBlock, | ||
onMutateBlock, | ||
onSelectBlock, | ||
pathname, | ||
metadata, | ||
properties, | ||
blocksConfig, | ||
selected: selectedBlock === childId, | ||
multiSelected: multiSelected?.includes(childId), | ||
type: child['@type'], | ||
editable, | ||
}; | ||
return editBlockWrapper( | ||
dragProps, | ||
<EditBlock key={childId} {...blockProps} />, | ||
blockProps, | ||
); | ||
}} | ||
</DragDropList> | ||
</fieldset> | ||
</div> | ||
); | ||
}; | ||
|
||
export default BlocksForm; |
Oops, something went wrong.