Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export Workflow from '@plone/volto/components/manage/Workflow/Workflow';
export Messages from '@plone/volto/components/manage/Messages/Messages';
export BlockChooser from '@plone/volto/components/manage/BlockChooser/BlockChooser';
export BlockChooserButton from '@plone/volto/components/manage/BlockChooser/BlockChooserButton';
export BlockToolbarItem from '@plone/volto/components/manage/Blocks/Block/BlockToolbarItem';
export Toolbar from '@plone/volto/components/manage/Toolbar/Toolbar';
export Sidebar from '@plone/volto/components/manage/Sidebar/Sidebar';
export SidebarPopup from '@plone/volto/components/manage/Sidebar/SidebarPopup';
Expand Down
4 changes: 2 additions & 2 deletions src/components/manage/BlockChooser/BlockChooserButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ const BlockChooserButton = (props) => {

return (
<>
{!disableNewBlocks && !blockHasValue(data) && (
{!disableNewBlocks && !blockHasValue(data) ? (
<Component
{...props}
onShowBlockChooser={() => setAddNewBlockOpened(true)}
/>
)}
) : null}
{addNewBlockOpened && (
<BlockChooser
onMutateBlock={
Expand Down
25 changes: 25 additions & 0 deletions src/components/manage/Blocks/Block/BlockToolbarItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* A Quanta toolbar entry button that can render itself either as
* a Dropdown.Item (in the more menu) or a simple Button.
*
*/

import React from 'react';
import { Dropdown, Button } from 'semantic-ui-react';
import { Icon } from '@plone/volto/components';

const BlockToolbarItem = (props) => {
const { isMenuShape = false, icon, label, onClick } = props;
return isMenuShape ? (
<Dropdown.Item onClick={onClick}>
<Icon name={icon} size="18px" />
{label}
</Dropdown.Item>
) : (
<Button icon basic onClick={onClick} title={label}>
<Icon name={icon} size="18px" />
</Button>
);
};

export default BlockToolbarItem;
58 changes: 58 additions & 0 deletions src/components/manage/Blocks/Block/BlockToolbarItem.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import Wrapper from '@plone/volto/storybook';
import BlockToolbarItem from './BlockToolbarItem';
import { PluggablesProvider } from '@plone/volto/components/manage/Pluggable';
import trashSVG from '@plone/volto/icons/delete.svg';
import hideSVG from '@plone/volto/icons/hide.svg';
import showSVG from '@plone/volto/icons/show.svg';

const icons = {
showSVG,
hideSVG,
trashSVG,
};

const BlockToolbarItemStory = (args) => {
return (
<Wrapper>
<PluggablesProvider>
<BlockToolbarItem {...args} icon={icons[args.icon]} />
</PluggablesProvider>
</Wrapper>
);
};

export const Default = BlockToolbarItemStory.bind({});

Default.args = {
id: 'field-default',
label: 'Sample entry',
icon: 'trashSVG',
isMenuShape: false,
};

export default {
title: 'Quanta/BlockToolbaritem',
component: BlockToolbarItem,
decorators: [
(Story) => (
<div style={{ width: '400px' }}>
<Story />
</div>
),
],
argTypes: {
// controlled value prop
icon: {
// control: {
// disable: true,
// },
control: {
type: 'select',
options: ['showSVG', 'hideSVG', 'trashSVG'],
},
},
},
// excludeStories: ['searchResults'],
// subcomponents: { ArgsTable },
};
33 changes: 24 additions & 9 deletions src/components/manage/Blocks/Block/BlocksForm.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import EditBlock from './Edit';
import WrapperlessBlockEdit from './Edit';
import { DragDropList } from '@plone/volto/components';
import { getBlocks } from '@plone/volto/helpers';
import {
Expand All @@ -16,8 +16,25 @@ import EditBlockWrapper from './EditBlockWrapper';
import { setSidebarTab } from '@plone/volto/actions';
import { useDispatch } from 'react-redux';
import { useDetectClickOutside } from '@plone/volto/helpers';
import QuantaEditBlockWrapper from './QuantaEditBlockWrapper';
import config from '@plone/volto/registry';

const topLevelBlockWrapper = ({ draginfo }, editBlock, blockProps) => {
return (
<QuantaEditBlockWrapper draginfo={draginfo} blockProps={blockProps}>
{editBlock}
</QuantaEditBlockWrapper>
);
};

const defaultBlockWrapper = ({ draginfo }, editBlock, blockProps) => {
return (
<EditBlockWrapper draginfo={draginfo} blockProps={blockProps}>
{editBlock}
</EditBlockWrapper>
);
};

const BlocksForm = (props) => {
const {
pathname,
Expand Down Expand Up @@ -142,13 +159,11 @@ const BlocksForm = (props) => {
onChangeFormData(newFormData);
};

const defaultBlockWrapper = ({ draginfo }, editBlock, blockProps) => (
<EditBlockWrapper draginfo={draginfo} blockProps={blockProps}>
{editBlock}
</EditBlockWrapper>
);

const editBlockWrapper = children || defaultBlockWrapper;
const editBlockWrapper =
children ||
(props.isMainForm && config.settings.useQuantaToolbar
? topLevelBlockWrapper
: defaultBlockWrapper);

return (
<div className="blocks-form" ref={ref}>
Expand Down Expand Up @@ -204,7 +219,7 @@ const BlocksForm = (props) => {
};
return editBlockWrapper(
dragProps,
<EditBlock key={childId} {...blockProps} />,
<WrapperlessBlockEdit key={childId} {...blockProps} />,
blockProps,
);
}}
Expand Down
145 changes: 69 additions & 76 deletions src/components/manage/Blocks/Block/Edit.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,84 +131,77 @@ export class Edit extends Component {
const blockHasOwnFocusManagement =
blocksConfig?.[type]?.['blockHasOwnFocusManagement'] || null;

return (
<>
{Block !== null ? (
<div
role="presentation"
onClick={(e) => {
const isMultipleSelection = e.shiftKey || e.ctrlKey || e.metaKey;
!this.props.selected &&
this.props.onSelectBlock(
this.props.id,
this.props.selected ? false : isMultipleSelection,
return Block !== null ? (
<div
role="presentation"
onClick={(e) => {
const isMultipleSelection = e.shiftKey || e.ctrlKey || e.metaKey;
!this.props.selected &&
this.props.onSelectBlock(
this.props.id,
this.props.selected ? false : isMultipleSelection,
e,
);
}}
onKeyDown={
!(blockHasOwnFocusManagement || disableNewBlocks)
? (e) =>
this.props.handleKeyDown(
e,
);
}}
onKeyDown={
!(blockHasOwnFocusManagement || disableNewBlocks)
? (e) =>
this.props.handleKeyDown(
e,
this.props.index,
this.props.id,
this.blockNode.current,
)
: null
}
className={cx(`block ${type}`, {
selected: this.props.selected || this.props.multiSelected,
multiSelected: this.props.multiSelected,
})}
style={{ outline: 'none' }}
ref={this.blockNode}
// The tabIndex is required for the keyboard navigation
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
tabIndex={!blockHasOwnFocusManagement ? -1 : null}
>
<Block
{...this.props}
blockNode={this.blockNode}
data={applyBlockDefaults(this.props)}
/>
{this.props.manage && (
<SidebarPortal
selected={this.props.selected}
tab="sidebar-settings"
>
<BlockSettingsSidebar {...this.props} schema={schema} />
</SidebarPortal>
)}
</div>
) : (
<div
role="presentation"
onClick={() =>
!this.props.selected && this.props.onSelectBlock(this.props.id)
}
onKeyDown={
!(blockHasOwnFocusManagement || disableNewBlocks)
? (e) =>
this.props.handleKeyDown(
e,
this.props.index,
this.props.id,
this.blockNode.current,
)
: null
}
className={cx(`block ${type}`, { selected: this.props.selected })}
style={{ outline: 'none' }}
ref={this.blockNode}
// The tabIndex is required for the keyboard navigation
tabIndex={-1}
>
{this.props.intl.formatMessage(messages.unknownBlock, {
block: type,
})}
</div>
this.props.index,
this.props.id,
this.blockNode.current,
)
: null
}
className={cx(`block ${type}`, {
selected: this.props.selected || this.props.multiSelected,
multiSelected: this.props.multiSelected,
})}
style={{ outline: 'none' }}
ref={this.blockNode}
// The tabIndex is required for the keyboard navigation
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
tabIndex={!blockHasOwnFocusManagement ? -1 : null}
>
<Block
{...this.props}
blockNode={this.blockNode}
data={applyBlockDefaults(this.props)}
/>
{this.props.manage && (
<SidebarPortal selected={this.props.selected} tab="sidebar-settings">
<BlockSettingsSidebar {...this.props} schema={schema} />
</SidebarPortal>
)}
</>
</div>
) : (
<div
role="presentation"
onClick={() =>
!this.props.selected && this.props.onSelectBlock(this.props.id)
}
onKeyDown={
!(blockHasOwnFocusManagement || disableNewBlocks)
? (e) =>
this.props.handleKeyDown(
e,
this.props.index,
this.props.id,
this.blockNode.current,
)
: null
}
className={cx(`block ${type}`, { selected: this.props.selected })}
style={{ outline: 'none' }}
ref={this.blockNode}
// The tabIndex is required for the keyboard navigation
tabIndex={-1}
>
{this.props.intl.formatMessage(messages.unknownBlock, {
block: type,
})}
</div>
);
}
}
Expand Down
10 changes: 7 additions & 3 deletions src/components/manage/Blocks/Block/EditBlockWrapper.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
/** This is the classic block wrapper. The BlocksForm uses either this one or
* the QuantaEditBlockWrapper
*/

import React from 'react';
import { Icon } from '@plone/volto/components';
import { blockHasValue } from '@plone/volto/helpers';
import dragSVG from '@plone/volto/icons/drag.svg';
import { injectIntl, defineMessages } from 'react-intl';

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 config from '@plone/volto/registry';

import trashSVG from '@plone/volto/icons/delete.svg';

const messages = defineMessages({
Expand Down
Loading