design-comuni-plone-theme
Version:
Volto Theme for Italia design guidelines
152 lines (134 loc) • 3.83 kB
JSX
import React from 'react';
import { useSlate } from 'slate-react';
import { Dropdown } from 'semantic-ui-react';
import { useIntl, defineMessages } from 'react-intl';
import cx from 'classnames';
import { omit } from 'lodash';
import {
isBlockStyleActive,
toggleStyle,
} from 'design-comuni-plone-theme/config/Slate/dropdownUtils';
import { Icon } from '@plone/volto/components';
import { ToolbarButton } from '@plone/volto-slate/editor/ui';
import blockquoteSimpleIcon from 'design-comuni-plone-theme/icons/blockquote-simple.svg';
import blockquoteCardIcon from 'design-comuni-plone-theme/icons/blockquote-card.svg';
import blockquoteCardDarkIcon from 'design-comuni-plone-theme/icons/blockquote-card-dark.svg';
import 'design-comuni-plone-theme/config/Slate/dropdownStyle.scss';
const OPTIONS = [
{
title: 'Blockquote semplice',
format: 'blockquote',
icon: blockquoteSimpleIcon,
cssClass: 'blockquote',
},
{
title: 'Blockquote card',
format: 'blockquote',
icon: blockquoteCardIcon,
cssClass: 'blockquote-card',
},
{
title: 'Blockquote card scuro',
format: 'blockquote',
icon: blockquoteCardDarkIcon,
cssClass: 'blockquote-card dark',
},
];
const messages = defineMessages({
blockquote: {
id: 'Blockquote',
defaultMessage: 'Blockquote',
},
});
const BlockquoteMenuButton = ({ icon, active, ...props }) => (
<ToolbarButton {...props} icon={icon} active={active} />
);
const MenuOpts = ({ editor, toSelect, option, type, ...props }) => {
const isActive = toSelect.includes(option);
return (
<Dropdown.Item
as="span"
active={isActive}
className={cx(`${type}-${option.value}`, { active: isActive })}
{...omit(option, ['isBlock', 'originalIcon'])}
data-isblock={option.isBlock}
onClick={(event, selItem) => {
toggleStyle(editor, {
cssClass: selItem.value,
isBlock: true,
format: selItem.format,
allowedChildren: props.allowedChildren,
oneOf: OPTIONS.reduce((acc, o) => [...acc, o.cssClass], []),
});
}}
/>
);
};
const BlockquoteButton = (props) => {
const editor = useSlate();
const intl = useIntl();
const blockOpts = OPTIONS.map((def) => {
return {
value: def.cssClass,
text: def.text,
title: def.title,
format: def.format,
icon: (props) => <Icon name={def.icon} size="24px" />,
isBlock: true,
originalIcon: def.icon,
};
});
// Calculating the initial selection.
const toSelect = [];
let selectedIcon = blockquoteCardIcon;
const oneOf = OPTIONS.reduce((acc, o) => [...acc, o.cssClass], []);
// block styles
for (const val of blockOpts) {
const ia = isBlockStyleActive(editor, val.value, oneOf);
if (ia) {
toSelect.push(val);
selectedIcon = val.originalIcon;
}
}
const menuItemProps = {
toSelect,
editor,
...props,
};
const showMenu = blockOpts.length;
return showMenu ? (
<Dropdown
id="blockquote-menu"
pointing="top left"
multiple
value={toSelect}
additionLabel={intl.formatMessage(messages.blockquote)}
trigger={
<BlockquoteMenuButton
title={intl.formatMessage(messages.blockquote)}
icon={selectedIcon}
active={toSelect.length > 0}
/>
}
onMouseDown={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<Dropdown.Menu>
{blockOpts.length &&
blockOpts.map((option, index) => (
<MenuOpts
{...menuItemProps}
type="block-blockquote"
option={option}
key={index}
/>
))}
</Dropdown.Menu>
</Dropdown>
) : (
''
);
};
export default BlockquoteButton;