Skip to content

Commit

Permalink
chore: slate config
Browse files Browse the repository at this point in the history
  • Loading branch information
giuliaghisini committed Sep 26, 2023
1 parent d4e4a71 commit 5018988
Show file tree
Hide file tree
Showing 6 changed files with 348 additions and 1 deletion.
141 changes: 141 additions & 0 deletions src/config/Slate/Alignment/AlignMenu.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
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 './utils';

import { Icon } from '@plone/volto/components';
import { ToolbarButton } from '@plone/volto-slate/editor/ui';

import alignCenterSVG from '@plone/volto/icons/align-center.svg';
import alignLeftSVG from '@plone/volto/icons/align-left.svg';
import alignRightSVG from '@plone/volto/icons/align-right.svg';
import alignJustifySVG from '@plone/volto/icons/align-justify.svg';

import '../dropdownStyle.scss';

const ALIGN_OPTIONS = [
{
cssClass: 'text-left',
text: 'Allinea a sinistra',
icon: alignLeftSVG,
},
{
cssClass: 'text-center',
text: 'Allinea al centro',
icon: alignCenterSVG,
},
{
cssClass: 'text-right',
text: 'Allinea a destra',
icon: alignRightSVG,
},
{
cssClass: 'text-justify',
text: 'Allinea il testo giustificato',
icon: alignJustifySVG,
},
];

const messages = defineMessages({
align: {
id: 'Allineamento',
defaultMessage: 'Allineamento',
},
});

const AlignMenuButton = ({ icon, active, ...props }) => (
<ToolbarButton {...props} icon={icon} active={active} />
);

const MenuOpts = ({ editor, toSelect, option, type }) => {
const isActive = toSelect.includes(option);

return (
<Dropdown.Item
as="span"
active={isActive}
className={cx(`${type}-${option.value}`, { active: isActive })}
{...omit(option, ['isBlock'])}
data-isblock={option.isBlock}
onClick={(event, selItem) => {
toggleStyle(editor, {
cssClass: selItem.value,
isBlock: selItem.isBlock,
oneOfType: 'align',
});
}}
/>
);
};

const AlignButton = (props) => {
const editor = useSlate();
const intl = useIntl();

const blockOpts = ALIGN_OPTIONS.map((def) => {
return {
value: def.cssClass,
text: def.label,
icon: (props) => <Icon name={def.icon} size="24px" />,
isBlock: true,
originalIcon: def.icon,
};
});

// Calculating the initial selection.
const toSelect = [];
let selectedIcon = ALIGN_OPTIONS[0].icon;

// block styles
for (const val of blockOpts) {
const ia = isBlockStyleActive(editor, val.value);

if (ia) {
toSelect.push(val);
selectedIcon = val.originalIcon;
}
}

const menuItemProps = {
toSelect,
editor,
};

const showMenu = blockOpts.length;

return showMenu ? (
<Dropdown
id="align-menu"
pointing="top left"
multiple
value={toSelect}
additionLabel={intl.formatMessage(messages.align)}
trigger={
<AlignMenuButton
title={intl.formatMessage(messages.align)}
icon={selectedIcon}
active={toSelect.length > 0}
/>
}
>
<Dropdown.Menu>
{blockOpts.length &&
blockOpts.map((option, index) => (
<MenuOpts
{...menuItemProps}
type="block-align"
option={option}
key={index}
/>
))}
</Dropdown.Menu>
</Dropdown>
) : (
''
);
};

export default AlignButton;
23 changes: 23 additions & 0 deletions src/config/Slate/Alignment/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import AlignMenu from './AlignMenu';
//import '@plone/volto-slate/editor/plugins/StyleMenu/style.less';

export const AlignElement = ({ attributes, children, element }) => {
console.log(attributes, element);
return <p {...attributes} /*className="callout"*/>aaaa{children}</p>;
};

export default function install(config) {
const { slate } = config.settings;

slate.buttons.align = (props) => (
<AlignMenu {...props} title="Allineamento" />
);

slate.elements['align'] = AlignElement;
slate.toolbarButtons.push('align');
slate.expandedToolbarButtons.push('align');
console.log(slate);

return config;
}
166 changes: 166 additions & 0 deletions src/config/Slate/Alignment/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/* eslint no-console: ["error", { allow: ["warn", "error"] }] */
import { Editor, Transforms } from 'slate';
import { isBlockActive } from '@plone/volto-slate/utils';
import config from '@plone/volto/registry';

/**
* Toggles a style (e.g. in the StyleMenu plugin).
* @param {Editor} editor
* @param {object} options
* @param {boolean} options.oneOfType Whether the given type is admitted once
*/
export const toggleStyle = (editor, { cssClass, isBlock, oneOfType }) => {
if (isBlock) {
toggleBlockStyle(editor, cssClass, oneOfType);
} else {
toggleInlineStyle(editor, cssClass);
}
};

export const toggleBlockStyle = (editor, style, oneOfType) => {
// We have 6 boolean variables which need to be accounted for.
// See https://docs.google.com/spreadsheets/d/1mVeMuqSTMABV2BhoHPrPAFjn7zUksbNgZ9AQK_dcd3U/edit?usp=sharing
const { slate } = config.settings;

const isListItem = isBlockActive(editor, slate.listItemType);
const isActive = isBlockStyleActive(editor, style);
const wantsList = false;

if (isListItem && !wantsList) {
toggleBlockStyleAsListItem(editor, style);
} else if (isListItem && wantsList && !isActive) {
// switchListType(editor, format); // this will deconstruct to Volto blocks
} else if (!isListItem && wantsList) {
// changeBlockToList(editor, format);
} else if (!isListItem && !wantsList) {
internalToggleBlockStyle(editor, style);
} else {
console.warn('toggleBlockStyle case not covered, please examine:', {
wantsList,
isActive,
isListItem,
});
}
};

export const toggleInlineStyle = (editor, style) => {
// We have 6 boolean variables which need to be accounted for.
// See https://docs.google.com/spreadsheets/d/1mVeMuqSTMABV2BhoHPrPAFjn7zUksbNgZ9AQK_dcd3U/edit?usp=sharing
const { slate } = config.settings;

const isListItem = isBlockActive(editor, slate.listItemType);
const isActive = isInlineStyleActive(editor, style);
const wantsList = false;

if (isListItem && !wantsList) {
toggleInlineStyleAsListItem(editor, style);
} else if (isListItem && wantsList && !isActive) {
// switchListType(editor, format); // this will deconstruct to Volto blocks
} else if (!isListItem && wantsList) {
// changeBlockToList(editor, format);
} else if (!isListItem && !wantsList) {
internalToggleInlineStyle(editor, style);
} else {
console.warn('toggleInlineStyle case not covered, please examine:', {
wantsList,
isActive,
isListItem,
});
}
};

export const isBlockStyleActive = (editor, style) => {
const keyName = `style-${style}`;
const sn = Array.from(
Editor.nodes(editor, {
match: (n) => {
const isStyle = typeof n.styleName === 'string' || n[keyName];
return !Editor.isEditor(n) && isStyle;
},
mode: 'all',
}),
);

for (const [n] of sn) {
if (typeof n.styleName === 'string') {
if (n.styleName.split(' ').filter((x) => x === style).length > 0) {
return true;
}
} else if (
n[keyName] &&
keyName.split('style-').filter((x) => x === style).length > 0
)
return true;
}
return false;
};

export const isInlineStyleActive = (editor, style) => {
const m = Editor.marks(editor);
const keyName = `style-${style}`;
if (m && m[keyName]) {
return true;
}
return false;
};

export const internalToggleBlockStyle = (editor, style) => {
toggleBlockStyleInSelection(editor, style);
};

export const internalToggleInlineStyle = (editor, style) => {
toggleInlineStyleInSelection(editor, style);
};

/*
* Applies a block format unto a list item. Will split the list and deconstruct the
* block
*/
export const toggleBlockStyleAsListItem = (editor, style) => {
toggleBlockStyleInSelection(editor, style);
};

/*
* Applies an inline style unto a list item.
*/
export const toggleInlineStyleAsListItem = (editor, style) => {
toggleInlineStyleInSelection(editor, style);
};

function toggleInlineStyleInSelection(editor, style) {
const m = Editor.marks(editor);
const keyName = 'style-' + style;

if (m && m[keyName]) {
Editor.removeMark(editor, keyName);
} else {
Editor.addMark(editor, keyName, true);
}
}

function toggleBlockStyleInSelection(editor, style) {
const sn = Array.from(
Editor.nodes(editor, {
mode: 'highest',
match: (n) => {
return !Editor.isEditor(n);
},
}),
);

for (const [n, p] of sn) {
let cn = n.styleName;
if (typeof n.styleName !== 'string') {
cn = style;
} else if (n.styleName.split(' ').filter((x) => x === style).length > 0) {
cn = cn
.split(' ')
.filter((x) => x !== style)
.join(' ');
} else {
// the style is not set but other styles are set
cn = cn.split(' ').concat(style).join(' ');
}
Transforms.setNodes(editor, { styleName: cn }, { at: p });
}
}
6 changes: 6 additions & 0 deletions src/config/Slate/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//config.settings.slate.contextToolbarButtons
import installAlignment from 'design-comuni-plone-theme/config/Slate/Alignment';

export default function applyItaliaSlateConfig(config) {
installAlignment(config);
}
9 changes: 9 additions & 0 deletions src/config/Slate/dropdownStyle.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.cms-ui .slate-inline-toolbar .ui.dropdown .menu > .item {
&.active {
color: #007eb1;
background-color: lighten(#007eb1, 60);
}
> .icon {
margin-right: 0;
}
}
4 changes: 3 additions & 1 deletion src/config/italiaConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import bandoSVG from 'design-comuni-plone-theme/icons/bando.svg';
import logSVG from 'design-comuni-plone-theme/icons/log.svg';

import applyRichTextConfig from 'design-comuni-plone-theme/config/RichTextEditor/config';
import applyItaliaSlateConfig from 'design-comuni-plone-theme/config/Slate/config';

import gdprPrivacyPanelConfig from 'design-comuni-plone-theme/config/volto-gdpr-privacy-defaultPanelConfig.js';

Expand All @@ -70,7 +71,8 @@ const ReleaseLog = loadable(() =>
);

export default function applyConfig(voltoConfig) {
let config = applyRichTextConfig(voltoConfig);
let config = applyRichTextConfig(voltoConfig); //[ToDO]: da rimuovere in favore di slate?
applyItaliaSlateConfig(config);

/******************************************************************************
* SETTINGS
Expand Down

0 comments on commit 5018988

Please sign in to comment.