@eeacms/volto-eea-website-theme 1.7.0 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -2
- package/package.json +1 -1
- package/src/customizations/@eeacms/volto-block-style/StyleWrapper/schema.js +0 -20
- package/src/customizations/@plone/volto-slate/editor/README.txt +2 -0
- package/src/customizations/@plone/volto-slate/editor/render.jsx +165 -0
- package/src/customizations/volto/components/manage/Sidebar/ObjectBrowserNav.jsx +1 -0
- package/src/index.js +2 -141
- package/src/slate.js +323 -0
package/CHANGELOG.md
CHANGED
@@ -4,7 +4,21 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
4
4
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
6
6
|
|
7
|
-
### [1.
|
7
|
+
### [1.8.0](https://github.com/eea/volto-eea-website-theme/compare/1.7.0...1.8.0) - 8 February 2023
|
8
|
+
|
9
|
+
#### :rocket: New Features
|
10
|
+
|
11
|
+
- feat(align): Move text align to slate buttons - refs 160747 [Alin Voinea - [`24d8fe5`](https://github.com/eea/volto-eea-website-theme/commit/24d8fe5a74afc2b61dc622b368d3fe5b8b422390)]
|
12
|
+
|
13
|
+
#### :nail_care: Enhancements
|
14
|
+
|
15
|
+
- change(object-browser): Popup is hoverable in object browser nav #99 from eea/object_browser_nav_popup_hoverable [ichim-david - [`205c2c4`](https://github.com/eea/volto-eea-website-theme/commit/205c2c48803ce5814f71aea932038bf72272459e)]
|
16
|
+
|
17
|
+
#### :hammer_and_wrench: Others
|
18
|
+
|
19
|
+
- Release 1.8.0 [Alin Voinea - [`f15437f`](https://github.com/eea/volto-eea-website-theme/commit/f15437f9c9fd978431d3af48410d3ab9746be9fb)]
|
20
|
+
- Popup is hoverable in object browser nav [andreiggr - [`a944bff`](https://github.com/eea/volto-eea-website-theme/commit/a944bff8026b40c481bec474f2b509dc5c8b044a)]
|
21
|
+
### [1.7.0](https://github.com/eea/volto-eea-website-theme/compare/1.6.4...1.7.0) - 8 February 2023
|
8
22
|
|
9
23
|
#### :rocket: New Features
|
10
24
|
|
@@ -25,7 +39,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
25
39
|
|
26
40
|
#### :hammer_and_wrench: Others
|
27
41
|
|
28
|
-
- Release 1.7.0 [Alin Voinea - [`065c0d0`](https://github.com/eea/volto-eea-website-theme/commit/065c0d05cb43458463e3ca293bd51b32d2e89f34)]
|
29
42
|
- Use scale for img in obj browser and preview in popup [andreiggr - [`e78e21d`](https://github.com/eea/volto-eea-website-theme/commit/e78e21d0b35d69242833914ff41455f24d31927b)]
|
30
43
|
### [1.6.4](https://github.com/eea/volto-eea-website-theme/compare/1.6.3...1.6.4) - 31 January 2023
|
31
44
|
|
package/package.json
CHANGED
@@ -12,32 +12,12 @@ export const StyleSchema = () => {
|
|
12
12
|
title: 'Preset styles',
|
13
13
|
fields: ['style_name'],
|
14
14
|
},
|
15
|
-
{
|
16
|
-
id: 'text',
|
17
|
-
title: 'Text',
|
18
|
-
fields: ['textAlign', 'fontWeight'],
|
19
|
-
},
|
20
15
|
],
|
21
16
|
properties: {
|
22
17
|
style_name: {
|
23
18
|
title: 'Style',
|
24
19
|
widget: 'style_select',
|
25
20
|
},
|
26
|
-
textAlign: {
|
27
|
-
title: 'Text align',
|
28
|
-
widget: 'style_text_align',
|
29
|
-
},
|
30
|
-
fontWeight: {
|
31
|
-
title: 'Font weight',
|
32
|
-
description: 'The weight (or boldness) of the font',
|
33
|
-
choices: [
|
34
|
-
['300', 'Light'],
|
35
|
-
['400', 'Regular'],
|
36
|
-
['500', 'Medium'],
|
37
|
-
['600', 'SemiBold'],
|
38
|
-
['700', 'Bold'],
|
39
|
-
],
|
40
|
-
},
|
41
21
|
},
|
42
22
|
required: [],
|
43
23
|
};
|
@@ -0,0 +1,165 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { renderToStaticMarkup } from 'react-dom/server';
|
3
|
+
import { Node, Text } from 'slate';
|
4
|
+
import cx from 'classnames';
|
5
|
+
import { isEmpty, isEqual, omit } from 'lodash';
|
6
|
+
import config from '@plone/volto/registry';
|
7
|
+
|
8
|
+
const OMITTED = ['editor', 'path'];
|
9
|
+
|
10
|
+
// TODO: read, see if relevant
|
11
|
+
// https://reactjs.org/docs/higher-order-components.html#dont-use-hocs-inside-the-render-method
|
12
|
+
export const Element = ({ element, attributes = {}, extras, ...rest }) => {
|
13
|
+
const { slate } = config.settings;
|
14
|
+
const { elements } = slate;
|
15
|
+
const El = elements[element.type] || elements['default'];
|
16
|
+
|
17
|
+
// CUSTOMIZATION Code fix
|
18
|
+
const attrs = Object.keys(attributes || {}).reduce(
|
19
|
+
(acc, k) => {
|
20
|
+
if (!isEmpty(attributes[k])) {
|
21
|
+
if (k === 'className') {
|
22
|
+
acc.className = cx(attributes.className, acc.className);
|
23
|
+
} else {
|
24
|
+
acc[k] = attributes[k];
|
25
|
+
}
|
26
|
+
}
|
27
|
+
return acc;
|
28
|
+
},
|
29
|
+
element.styleName ? { className: element.styleName } : {},
|
30
|
+
);
|
31
|
+
// END CUSTOMIZATION
|
32
|
+
|
33
|
+
attrs.ref = attributes?.ref; // never remove the ref
|
34
|
+
|
35
|
+
return (
|
36
|
+
<El
|
37
|
+
element={element}
|
38
|
+
{...omit(rest, OMITTED)}
|
39
|
+
attributes={attrs}
|
40
|
+
extras={extras}
|
41
|
+
/>
|
42
|
+
);
|
43
|
+
};
|
44
|
+
|
45
|
+
export const Leaf = ({ children, ...rest }) => {
|
46
|
+
const { attributes, leaf, mode } = rest;
|
47
|
+
let { leafs } = config.settings.slate;
|
48
|
+
|
49
|
+
children = Object.keys(leafs).reduce((acc, name) => {
|
50
|
+
return Object.keys(leaf).includes(name)
|
51
|
+
? leafs[name]({ children: acc })
|
52
|
+
: acc;
|
53
|
+
}, children);
|
54
|
+
|
55
|
+
const classNames = {
|
56
|
+
[`highlight-${leaf.highlightType}`]: mode !== 'view' && leaf.highlightType,
|
57
|
+
'highlight-selection': mode !== 'view' && leaf.isSelection,
|
58
|
+
};
|
59
|
+
|
60
|
+
// stylemenu support
|
61
|
+
for (const prop in leaf) {
|
62
|
+
if (prop.startsWith('style-')) {
|
63
|
+
classNames[prop.substring(6)] = true;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
const klass = cx(classNames);
|
68
|
+
|
69
|
+
return mode === 'view' ? (
|
70
|
+
typeof children === 'string' ? (
|
71
|
+
children.split('\n').map((t, i) => {
|
72
|
+
// Softbreak support. Should do a plugin?
|
73
|
+
return (
|
74
|
+
<React.Fragment key={`${i}`}>
|
75
|
+
{children.indexOf('\n') > -1 &&
|
76
|
+
children.split('\n').length - 1 > i ? (
|
77
|
+
<>
|
78
|
+
{klass ? <span className={klass}>{t}</span> : t}
|
79
|
+
<br />
|
80
|
+
</>
|
81
|
+
) : klass ? (
|
82
|
+
<span className={klass}>{t}</span>
|
83
|
+
) : (
|
84
|
+
t
|
85
|
+
)}
|
86
|
+
</React.Fragment>
|
87
|
+
);
|
88
|
+
})
|
89
|
+
) : (
|
90
|
+
<span className={klass}>{children}</span>
|
91
|
+
)
|
92
|
+
) : (
|
93
|
+
<span {...attributes} className={klass}>
|
94
|
+
{children}
|
95
|
+
</span>
|
96
|
+
);
|
97
|
+
};
|
98
|
+
|
99
|
+
const serializeData = (node) => {
|
100
|
+
return JSON.stringify({ type: node.type, data: node.data });
|
101
|
+
};
|
102
|
+
|
103
|
+
export const serializeNodes = (nodes, getAttributes, extras = {}) => {
|
104
|
+
const editor = { children: nodes || [] };
|
105
|
+
|
106
|
+
const _serializeNodes = (nodes) => {
|
107
|
+
return (nodes || []).map(([node, path], i) => {
|
108
|
+
return Text.isText(node) ? (
|
109
|
+
<Leaf path={path} leaf={node} text={node} mode="view" key={path}>
|
110
|
+
{node.text}
|
111
|
+
</Leaf>
|
112
|
+
) : (
|
113
|
+
<Element
|
114
|
+
path={path}
|
115
|
+
element={node}
|
116
|
+
mode="view"
|
117
|
+
key={path}
|
118
|
+
data-slate-data={node.data ? serializeData(node) : null}
|
119
|
+
attributes={
|
120
|
+
isEqual(path, [0])
|
121
|
+
? getAttributes
|
122
|
+
? getAttributes(node, path)
|
123
|
+
: null
|
124
|
+
: null
|
125
|
+
}
|
126
|
+
extras={extras}
|
127
|
+
>
|
128
|
+
{_serializeNodes(Array.from(Node.children(editor, path)))}
|
129
|
+
</Element>
|
130
|
+
);
|
131
|
+
});
|
132
|
+
};
|
133
|
+
|
134
|
+
return _serializeNodes(Array.from(Node.children(editor, [])));
|
135
|
+
};
|
136
|
+
|
137
|
+
/**
|
138
|
+
* Get the concatenated text string of a node's content.
|
139
|
+
*
|
140
|
+
* Note that this WILL include spaces between block node leafs in contrary to
|
141
|
+
* the original slate method. This function joins text of nodes with
|
142
|
+
* separating spaces to produce a string for indexing purposes.
|
143
|
+
*
|
144
|
+
*/
|
145
|
+
const ConcatenatedString = (node) => {
|
146
|
+
if (Text.isText(node)) {
|
147
|
+
return node.text.trim();
|
148
|
+
} else {
|
149
|
+
return node.children.map(ConcatenatedString).join(' ');
|
150
|
+
}
|
151
|
+
};
|
152
|
+
|
153
|
+
/**
|
154
|
+
* @function serializeNodesToText
|
155
|
+
*
|
156
|
+
* @param {Array[Node]} nodes
|
157
|
+
*
|
158
|
+
* @returns {string}
|
159
|
+
*/
|
160
|
+
export const serializeNodesToText = (nodes) => {
|
161
|
+
return nodes.map(ConcatenatedString).join('\n');
|
162
|
+
};
|
163
|
+
|
164
|
+
export const serializeNodesToHtml = (nodes) =>
|
165
|
+
renderToStaticMarkup(serializeNodes(nodes));
|
package/src/index.js
CHANGED
@@ -8,14 +8,9 @@ import SubsiteClass from './components/theme/SubsiteClass';
|
|
8
8
|
import HomePageView from '@eeacms/volto-eea-website-theme/components/theme/Homepage/HomePageView';
|
9
9
|
import HomePageInverseView from '@eeacms/volto-eea-website-theme/components/theme/Homepage/HomePageInverseView';
|
10
10
|
import { Icon } from '@plone/volto/components';
|
11
|
-
import { MarkElementButton } from '@plone/volto-slate/editor/ui';
|
12
|
-
import installCallout from '@plone/volto-slate/editor/plugins/Callout';
|
13
|
-
import paintSVG from '@plone/volto/icons/paint.svg';
|
14
11
|
import contentBoxSVG from './icons/content-box.svg';
|
15
|
-
import lightIcon from './icons/light.svg';
|
16
|
-
import smallIcon from './icons/small.svg';
|
17
12
|
import voltoCustomMiddleware from './middleware/voltoCustom';
|
18
|
-
import
|
13
|
+
import installSlate from './slate';
|
19
14
|
|
20
15
|
const applyConfig = (config) => {
|
21
16
|
// EEA specific settings
|
@@ -111,141 +106,7 @@ const applyConfig = (config) => {
|
|
111
106
|
},
|
112
107
|
];
|
113
108
|
|
114
|
-
|
115
|
-
// Callout slate button
|
116
|
-
config = installCallout(config);
|
117
|
-
|
118
|
-
// Remove blockquote, italic, strikethrough slate button from toolbarButtons
|
119
|
-
config.settings.slate.toolbarButtons = config.settings.slate.toolbarButtons.filter(
|
120
|
-
(item) => !['blockquote', 'italic', 'strikethrough'].includes(item),
|
121
|
-
);
|
122
|
-
|
123
|
-
// Remove blockquote, italic, strikethrough slate button from expandedToolbarButtons
|
124
|
-
config.settings.slate.expandedToolbarButtons = config.settings.slate.expandedToolbarButtons.filter(
|
125
|
-
(item) => !['blockquote', 'italic', 'strikethrough'].includes(item),
|
126
|
-
);
|
127
|
-
|
128
|
-
// Remove 'underline' and 'italic' hotkeys
|
129
|
-
config.settings.slate.hotkeys = Object.keys(config.settings.slate.hotkeys)
|
130
|
-
.filter((item) => !['mod+u', 'mod+i'].includes(item))
|
131
|
-
.reduce((out, key) => {
|
132
|
-
out[key] = config.settings.slate.hotkeys[key];
|
133
|
-
return out;
|
134
|
-
}, {});
|
135
|
-
|
136
|
-
// Small button
|
137
|
-
if (!config.settings.slate.toolbarButtons.includes('small')) {
|
138
|
-
config.settings.slate.elements.small = ({ children }) => (
|
139
|
-
<small>{children}</small>
|
140
|
-
);
|
141
|
-
|
142
|
-
config.settings.slate.buttons.small = (props) => (
|
143
|
-
<MarkElementButton
|
144
|
-
title="Small"
|
145
|
-
format="small"
|
146
|
-
icon={smallIcon}
|
147
|
-
{...props}
|
148
|
-
/>
|
149
|
-
);
|
150
|
-
|
151
|
-
config.settings.slate.inlineElements = [
|
152
|
-
...config.settings.slate.inlineElements,
|
153
|
-
'small',
|
154
|
-
];
|
155
|
-
|
156
|
-
config.settings.slate.toolbarButtons = [
|
157
|
-
...config.settings.slate.toolbarButtons.slice(0, 1),
|
158
|
-
'small',
|
159
|
-
...config.settings.slate.toolbarButtons.slice(1),
|
160
|
-
];
|
161
|
-
|
162
|
-
config.settings.slate.hotkeys['mod+s'] = {
|
163
|
-
format: 'small',
|
164
|
-
type: 'inline',
|
165
|
-
};
|
166
|
-
}
|
167
|
-
|
168
|
-
// Light button
|
169
|
-
if (!config.settings.slate.toolbarButtons.includes('light')) {
|
170
|
-
config.settings.slate.elements.light = ({ children }) => (
|
171
|
-
<span className="fw-light">{children}</span>
|
172
|
-
);
|
173
|
-
|
174
|
-
config.settings.slate.buttons.light = (props) => (
|
175
|
-
<MarkElementButton
|
176
|
-
title="Light"
|
177
|
-
format="light"
|
178
|
-
icon={lightIcon}
|
179
|
-
{...props}
|
180
|
-
/>
|
181
|
-
);
|
182
|
-
|
183
|
-
config.settings.slate.inlineElements = [
|
184
|
-
...config.settings.slate.inlineElements,
|
185
|
-
'light',
|
186
|
-
];
|
187
|
-
|
188
|
-
config.settings.slate.toolbarButtons = [
|
189
|
-
...config.settings.slate.toolbarButtons.slice(0, 1),
|
190
|
-
'light',
|
191
|
-
...config.settings.slate.toolbarButtons.slice(1),
|
192
|
-
];
|
193
|
-
|
194
|
-
config.settings.slate.hotkeys['mod+l'] = {
|
195
|
-
format: 'light',
|
196
|
-
type: 'inline',
|
197
|
-
};
|
198
|
-
}
|
199
|
-
|
200
|
-
// Clear formatting
|
201
|
-
if (!config.settings.slate.toolbarButtons.includes('clearformatting')) {
|
202
|
-
config.settings.slate.toolbarButtons = [
|
203
|
-
...config.settings.slate.toolbarButtons,
|
204
|
-
'clearformatting',
|
205
|
-
];
|
206
|
-
}
|
207
|
-
|
208
|
-
// Align Slate Lists to EEA Design System
|
209
|
-
config.settings.slate.elements.ul = ({ attributes, children }) => (
|
210
|
-
<List bulleted as="ul" {...attributes}>
|
211
|
-
{children}
|
212
|
-
</List>
|
213
|
-
);
|
214
|
-
|
215
|
-
config.settings.slate.elements.ol = ({ attributes, children }) => (
|
216
|
-
<List ordered as="ol" {...attributes}>
|
217
|
-
{children}
|
218
|
-
</List>
|
219
|
-
);
|
220
|
-
|
221
|
-
config.settings.slate.elements.li = ({ attributes, children }) => (
|
222
|
-
<List.Item as="li" {...attributes}>
|
223
|
-
{children}
|
224
|
-
</List.Item>
|
225
|
-
);
|
226
|
-
|
227
|
-
// Slate StyleMenu configuration
|
228
|
-
config.settings.slate.styleMenu = {
|
229
|
-
...(config.settings.slate.styleMenu || {}),
|
230
|
-
blockStyles: [
|
231
|
-
{
|
232
|
-
cssClass: 'primary',
|
233
|
-
label: 'Primary',
|
234
|
-
icon: () => <Icon name={paintSVG} size="18px" />,
|
235
|
-
},
|
236
|
-
{
|
237
|
-
cssClass: 'secondary',
|
238
|
-
label: 'Secondary',
|
239
|
-
icon: () => <Icon name={paintSVG} size="18px" />,
|
240
|
-
},
|
241
|
-
{
|
242
|
-
cssClass: 'tertiary',
|
243
|
-
label: 'Tertiary',
|
244
|
-
icon: () => <Icon name={paintSVG} size="18px" />,
|
245
|
-
},
|
246
|
-
],
|
247
|
-
};
|
248
|
-
}
|
109
|
+
config = installSlate(config);
|
249
110
|
|
250
111
|
// Custom block-style colors
|
251
112
|
config.settings.available_colors = eea.colors;
|
package/src/slate.js
ADDED
@@ -0,0 +1,323 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { List } from 'semantic-ui-react';
|
3
|
+
import { MarkElementButton, ToolbarButton } from '@plone/volto-slate/editor/ui';
|
4
|
+
import installCallout from '@plone/volto-slate/editor/plugins/Callout';
|
5
|
+
import { Icon } from '@plone/volto/components';
|
6
|
+
import { Editor, Transforms } from 'slate';
|
7
|
+
import { useSlate } from 'slate-react';
|
8
|
+
|
9
|
+
import formatClearIcon from '@plone/volto/icons/format-clear.svg';
|
10
|
+
import paintSVG from '@plone/volto/icons/paint.svg';
|
11
|
+
import alignLeftIcon from '@plone/volto/icons/align-left.svg';
|
12
|
+
import alignRightIcon from '@plone/volto/icons/align-right.svg';
|
13
|
+
import alignCenterIcon from '@plone/volto/icons/align-center.svg';
|
14
|
+
import alignJustifyIcon from '@plone/volto/icons/align-justify.svg';
|
15
|
+
import lightIcon from './icons/light.svg';
|
16
|
+
import smallIcon from './icons/small.svg';
|
17
|
+
|
18
|
+
const toggleBlockClassFormat = (editor, format) => {
|
19
|
+
const levels = Array.from(Editor.levels(editor, editor.selection));
|
20
|
+
const [, [, path]] = levels;
|
21
|
+
Transforms.setNodes(
|
22
|
+
editor,
|
23
|
+
{ styleName: format },
|
24
|
+
{
|
25
|
+
at: path,
|
26
|
+
},
|
27
|
+
);
|
28
|
+
return;
|
29
|
+
};
|
30
|
+
|
31
|
+
const isBlockClassActive = (editor, format) => {
|
32
|
+
if (!editor.selection) return false;
|
33
|
+
const levels = Array.from(Editor.levels(editor, editor.selection));
|
34
|
+
const [, [node]] = levels;
|
35
|
+
return node.styleName === format;
|
36
|
+
};
|
37
|
+
|
38
|
+
function BlockClassButton({ format, icon, ...props }) {
|
39
|
+
const editor = useSlate();
|
40
|
+
|
41
|
+
const isActive = isBlockClassActive(editor, format);
|
42
|
+
|
43
|
+
const handleMouseDown = React.useCallback(
|
44
|
+
(event) => {
|
45
|
+
event.preventDefault();
|
46
|
+
toggleBlockClassFormat(editor, format);
|
47
|
+
},
|
48
|
+
[editor, format], // , isActive
|
49
|
+
);
|
50
|
+
|
51
|
+
return (
|
52
|
+
<ToolbarButton
|
53
|
+
{...props}
|
54
|
+
active={isActive}
|
55
|
+
onMouseDown={handleMouseDown}
|
56
|
+
icon={icon}
|
57
|
+
/>
|
58
|
+
);
|
59
|
+
}
|
60
|
+
|
61
|
+
const clearFormatting = (editor) => {
|
62
|
+
Transforms.setNodes(editor, {
|
63
|
+
type: 'p',
|
64
|
+
styleName: null,
|
65
|
+
});
|
66
|
+
Transforms.unwrapNodes(editor, {
|
67
|
+
match: (n) => n.type && n.type !== 'p',
|
68
|
+
mode: 'all',
|
69
|
+
split: false,
|
70
|
+
});
|
71
|
+
};
|
72
|
+
|
73
|
+
const ClearFormattingButton = ({ icon, ...props }) => {
|
74
|
+
const editor = useSlate();
|
75
|
+
|
76
|
+
const handleMouseDown = React.useCallback(
|
77
|
+
(event) => {
|
78
|
+
event.preventDefault();
|
79
|
+
clearFormatting(editor);
|
80
|
+
},
|
81
|
+
[editor],
|
82
|
+
);
|
83
|
+
|
84
|
+
return <ToolbarButton {...props} onMouseDown={handleMouseDown} icon={icon} />;
|
85
|
+
};
|
86
|
+
|
87
|
+
export default function installSlate(config) {
|
88
|
+
if (config.settings.slate) {
|
89
|
+
// Callout slate button
|
90
|
+
config = installCallout(config);
|
91
|
+
|
92
|
+
config.settings.slate.buttons.clearformatting = (props) => (
|
93
|
+
<ClearFormattingButton title="Clear formatting" icon={formatClearIcon} />
|
94
|
+
);
|
95
|
+
|
96
|
+
// Remove blockquote, italic, strikethrough slate button from toolbarButtons
|
97
|
+
config.settings.slate.toolbarButtons = config.settings.slate.toolbarButtons.filter(
|
98
|
+
(item) => !['blockquote', 'italic', 'strikethrough'].includes(item),
|
99
|
+
);
|
100
|
+
|
101
|
+
// Remove blockquote, italic, strikethrough slate button from expandedToolbarButtons
|
102
|
+
config.settings.slate.expandedToolbarButtons = config.settings.slate.expandedToolbarButtons.filter(
|
103
|
+
(item) => !['blockquote', 'italic', 'strikethrough'].includes(item),
|
104
|
+
);
|
105
|
+
|
106
|
+
// Remove 'underline' and 'italic' hotkeys
|
107
|
+
config.settings.slate.hotkeys = Object.keys(config.settings.slate.hotkeys)
|
108
|
+
.filter((item) => !['mod+u', 'mod+i'].includes(item))
|
109
|
+
.reduce((out, key) => {
|
110
|
+
out[key] = config.settings.slate.hotkeys[key];
|
111
|
+
return out;
|
112
|
+
}, {});
|
113
|
+
|
114
|
+
// Small button
|
115
|
+
if (!config.settings.slate.toolbarButtons.includes('small')) {
|
116
|
+
config.settings.slate.elements.small = ({ children }) => (
|
117
|
+
<small>{children}</small>
|
118
|
+
);
|
119
|
+
|
120
|
+
config.settings.slate.buttons.small = (props) => (
|
121
|
+
<MarkElementButton
|
122
|
+
title="Small"
|
123
|
+
format="small"
|
124
|
+
icon={smallIcon}
|
125
|
+
{...props}
|
126
|
+
/>
|
127
|
+
);
|
128
|
+
|
129
|
+
config.settings.slate.inlineElements = [
|
130
|
+
...config.settings.slate.inlineElements,
|
131
|
+
'small',
|
132
|
+
];
|
133
|
+
|
134
|
+
config.settings.slate.toolbarButtons = [
|
135
|
+
...config.settings.slate.toolbarButtons.slice(0, 1),
|
136
|
+
'small',
|
137
|
+
...config.settings.slate.toolbarButtons.slice(1),
|
138
|
+
];
|
139
|
+
|
140
|
+
config.settings.slate.hotkeys['mod+s'] = {
|
141
|
+
format: 'small',
|
142
|
+
type: 'inline',
|
143
|
+
};
|
144
|
+
}
|
145
|
+
|
146
|
+
// Light button
|
147
|
+
if (!config.settings.slate.toolbarButtons.includes('light')) {
|
148
|
+
config.settings.slate.elements.light = ({ children }) => (
|
149
|
+
<span className="fw-light">{children}</span>
|
150
|
+
);
|
151
|
+
|
152
|
+
config.settings.slate.buttons.light = (props) => (
|
153
|
+
<MarkElementButton
|
154
|
+
title="Light"
|
155
|
+
format="light"
|
156
|
+
icon={lightIcon}
|
157
|
+
{...props}
|
158
|
+
/>
|
159
|
+
);
|
160
|
+
|
161
|
+
config.settings.slate.inlineElements = [
|
162
|
+
...config.settings.slate.inlineElements,
|
163
|
+
'light',
|
164
|
+
];
|
165
|
+
|
166
|
+
config.settings.slate.toolbarButtons = [
|
167
|
+
...config.settings.slate.toolbarButtons.slice(0, 1),
|
168
|
+
'light',
|
169
|
+
...config.settings.slate.toolbarButtons.slice(1),
|
170
|
+
];
|
171
|
+
|
172
|
+
config.settings.slate.hotkeys['mod+l'] = {
|
173
|
+
format: 'light',
|
174
|
+
type: 'inline',
|
175
|
+
};
|
176
|
+
}
|
177
|
+
|
178
|
+
// Align Slate Lists to EEA Design System
|
179
|
+
config.settings.slate.elements.ul = ({ attributes, children }) => (
|
180
|
+
<List bulleted as="ul" {...attributes}>
|
181
|
+
{children}
|
182
|
+
</List>
|
183
|
+
);
|
184
|
+
|
185
|
+
config.settings.slate.elements.ol = ({ attributes, children }) => (
|
186
|
+
<List ordered as="ol" {...attributes}>
|
187
|
+
{children}
|
188
|
+
</List>
|
189
|
+
);
|
190
|
+
|
191
|
+
config.settings.slate.elements.li = ({ attributes, children }) => (
|
192
|
+
<List.Item as="li" {...attributes}>
|
193
|
+
{children}
|
194
|
+
</List.Item>
|
195
|
+
);
|
196
|
+
|
197
|
+
// Slate StyleMenu configuration
|
198
|
+
config.settings.slate.styleMenu = {
|
199
|
+
...(config.settings.slate.styleMenu || {}),
|
200
|
+
blockStyles: [
|
201
|
+
{
|
202
|
+
cssClass: 'primary',
|
203
|
+
label: 'Primary',
|
204
|
+
icon: () => <Icon name={paintSVG} size="18px" />,
|
205
|
+
},
|
206
|
+
{
|
207
|
+
cssClass: 'secondary',
|
208
|
+
label: 'Secondary',
|
209
|
+
icon: () => <Icon name={paintSVG} size="18px" />,
|
210
|
+
},
|
211
|
+
{
|
212
|
+
cssClass: 'tertiary',
|
213
|
+
label: 'Tertiary',
|
214
|
+
icon: () => <Icon name={paintSVG} size="18px" />,
|
215
|
+
},
|
216
|
+
],
|
217
|
+
};
|
218
|
+
|
219
|
+
// Text Align buttons
|
220
|
+
|
221
|
+
// Align left
|
222
|
+
if (!config.settings.slate.toolbarButtons.includes('text-left')) {
|
223
|
+
config.settings.slate.buttons['text-left'] = (props) => (
|
224
|
+
<BlockClassButton
|
225
|
+
format="text-left"
|
226
|
+
icon={alignLeftIcon}
|
227
|
+
title="Align left"
|
228
|
+
{...props}
|
229
|
+
/>
|
230
|
+
);
|
231
|
+
|
232
|
+
config.settings.slate.toolbarButtons = [
|
233
|
+
...config.settings.slate.toolbarButtons,
|
234
|
+
'separator',
|
235
|
+
'text-left',
|
236
|
+
];
|
237
|
+
|
238
|
+
config.settings.slate.expandedToolbarButtons = [
|
239
|
+
...config.settings.slate.expandedToolbarButtons,
|
240
|
+
'separator',
|
241
|
+
'text-left',
|
242
|
+
];
|
243
|
+
}
|
244
|
+
|
245
|
+
// Align center
|
246
|
+
if (!config.settings.slate.toolbarButtons.includes('text-center')) {
|
247
|
+
config.settings.slate.buttons['text-center'] = (props) => (
|
248
|
+
<BlockClassButton
|
249
|
+
format="text-center"
|
250
|
+
icon={alignCenterIcon}
|
251
|
+
title="Align center"
|
252
|
+
{...props}
|
253
|
+
/>
|
254
|
+
);
|
255
|
+
|
256
|
+
config.settings.slate.toolbarButtons = [
|
257
|
+
...config.settings.slate.toolbarButtons,
|
258
|
+
'text-center',
|
259
|
+
];
|
260
|
+
|
261
|
+
config.settings.slate.expandedToolbarButtons = [
|
262
|
+
...config.settings.slate.expandedToolbarButtons,
|
263
|
+
'text-center',
|
264
|
+
];
|
265
|
+
}
|
266
|
+
|
267
|
+
// Align right
|
268
|
+
if (!config.settings.slate.toolbarButtons.includes('text-right')) {
|
269
|
+
config.settings.slate.buttons['text-right'] = (props) => (
|
270
|
+
<BlockClassButton
|
271
|
+
format="text-right"
|
272
|
+
icon={alignRightIcon}
|
273
|
+
title="Align right"
|
274
|
+
{...props}
|
275
|
+
/>
|
276
|
+
);
|
277
|
+
|
278
|
+
config.settings.slate.toolbarButtons = [
|
279
|
+
...config.settings.slate.toolbarButtons,
|
280
|
+
'text-right',
|
281
|
+
];
|
282
|
+
|
283
|
+
config.settings.slate.expandedToolbarButtons = [
|
284
|
+
...config.settings.slate.expandedToolbarButtons,
|
285
|
+
'text-right',
|
286
|
+
];
|
287
|
+
}
|
288
|
+
|
289
|
+
// Align justify
|
290
|
+
if (!config.settings.slate.toolbarButtons.includes('text-justify')) {
|
291
|
+
config.settings.slate.buttons['text-justify'] = (props) => (
|
292
|
+
<BlockClassButton
|
293
|
+
format="text-justify"
|
294
|
+
icon={alignJustifyIcon}
|
295
|
+
title="Align justify"
|
296
|
+
{...props}
|
297
|
+
/>
|
298
|
+
);
|
299
|
+
|
300
|
+
config.settings.slate.toolbarButtons = [
|
301
|
+
...config.settings.slate.toolbarButtons,
|
302
|
+
'text-justify',
|
303
|
+
'separator',
|
304
|
+
];
|
305
|
+
|
306
|
+
config.settings.slate.expandedToolbarButtons = [
|
307
|
+
...config.settings.slate.expandedToolbarButtons,
|
308
|
+
'text-justify',
|
309
|
+
'separator',
|
310
|
+
];
|
311
|
+
}
|
312
|
+
|
313
|
+
// Clear formatting
|
314
|
+
if (!config.settings.slate.toolbarButtons.includes('clearformatting')) {
|
315
|
+
config.settings.slate.toolbarButtons = [
|
316
|
+
...config.settings.slate.toolbarButtons,
|
317
|
+
'clearformatting',
|
318
|
+
];
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
return config;
|
323
|
+
}
|