@pie-lib/editable-html 11.1.1 → 11.2.0-beta.1
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 +43 -167
- package/NEXT.CHANGELOG.json +1 -0
- package/lib/block-tags.js +25 -0
- package/lib/block-tags.js.map +1 -0
- package/lib/constants.js +16 -0
- package/lib/constants.js.map +1 -0
- package/lib/editor.js +348 -87
- package/lib/editor.js.map +1 -1
- package/lib/index.js +25 -9
- package/lib/index.js.map +1 -1
- package/lib/plugins/characters/index.js +8 -3
- package/lib/plugins/characters/index.js.map +1 -1
- package/lib/plugins/characters/utils.js +12 -12
- package/lib/plugins/characters/utils.js.map +1 -1
- package/lib/plugins/css/icons/index.js +37 -0
- package/lib/plugins/css/icons/index.js.map +1 -0
- package/lib/plugins/css/index.js +397 -0
- package/lib/plugins/css/index.js.map +1 -0
- package/lib/plugins/customPlugin/index.js +114 -0
- package/lib/plugins/customPlugin/index.js.map +1 -0
- package/lib/plugins/html/index.js +11 -7
- package/lib/plugins/html/index.js.map +1 -1
- package/lib/plugins/image/index.js +2 -1
- package/lib/plugins/image/index.js.map +1 -1
- package/lib/plugins/image/insert-image-handler.js +13 -4
- package/lib/plugins/image/insert-image-handler.js.map +1 -1
- package/lib/plugins/index.js +270 -11
- package/lib/plugins/index.js.map +1 -1
- package/lib/plugins/list/index.js +130 -0
- package/lib/plugins/list/index.js.map +1 -1
- package/lib/plugins/math/index.js +91 -56
- package/lib/plugins/math/index.js.map +1 -1
- package/lib/plugins/media/index.js +5 -2
- package/lib/plugins/media/index.js.map +1 -1
- package/lib/plugins/media/media-dialog.js +98 -57
- package/lib/plugins/media/media-dialog.js.map +1 -1
- package/lib/plugins/rendering/index.js +46 -0
- package/lib/plugins/rendering/index.js.map +1 -0
- package/lib/plugins/respArea/drag-in-the-blank/choice.js +5 -2
- package/lib/plugins/respArea/drag-in-the-blank/choice.js.map +1 -1
- package/lib/plugins/respArea/explicit-constructed-response/index.js +11 -9
- package/lib/plugins/respArea/explicit-constructed-response/index.js.map +1 -1
- package/lib/plugins/respArea/index.js +69 -21
- package/lib/plugins/respArea/index.js.map +1 -1
- package/lib/plugins/respArea/inline-dropdown/index.js +10 -5
- package/lib/plugins/respArea/inline-dropdown/index.js.map +1 -1
- package/lib/plugins/respArea/math-templated/index.js +130 -0
- package/lib/plugins/respArea/math-templated/index.js.map +1 -0
- package/lib/plugins/respArea/utils.js +16 -1
- package/lib/plugins/respArea/utils.js.map +1 -1
- package/lib/plugins/table/CustomTablePlugin.js +133 -0
- package/lib/plugins/table/CustomTablePlugin.js.map +1 -0
- package/lib/plugins/table/index.js +43 -59
- package/lib/plugins/table/index.js.map +1 -1
- package/lib/plugins/table/table-toolbar.js +33 -4
- package/lib/plugins/table/table-toolbar.js.map +1 -1
- package/lib/plugins/textAlign/icons/index.js +226 -0
- package/lib/plugins/textAlign/icons/index.js.map +1 -0
- package/lib/plugins/textAlign/index.js +34 -0
- package/lib/plugins/textAlign/index.js.map +1 -0
- package/lib/plugins/toolbar/default-toolbar.js +82 -27
- package/lib/plugins/toolbar/default-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/done-button.js +5 -2
- package/lib/plugins/toolbar/done-button.js.map +1 -1
- package/lib/plugins/toolbar/editor-and-toolbar.js +18 -19
- package/lib/plugins/toolbar/editor-and-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/toolbar-buttons.js +44 -11
- package/lib/plugins/toolbar/toolbar-buttons.js.map +1 -1
- package/lib/plugins/toolbar/toolbar.js +35 -11
- package/lib/plugins/toolbar/toolbar.js.map +1 -1
- package/lib/serialization.js +233 -44
- package/lib/serialization.js.map +1 -1
- package/package.json +11 -6
- package/src/__tests__/editor.test.jsx +363 -0
- package/src/__tests__/serialization.test.js +291 -0
- package/src/__tests__/utils.js +36 -0
- package/src/block-tags.js +17 -0
- package/src/constants.js +7 -0
- package/src/editor.jsx +303 -49
- package/src/index.jsx +19 -10
- package/src/plugins/characters/index.jsx +11 -3
- package/src/plugins/characters/utils.js +12 -12
- package/src/plugins/css/icons/index.jsx +17 -0
- package/src/plugins/css/index.jsx +346 -0
- package/src/plugins/customPlugin/index.jsx +85 -0
- package/src/plugins/html/index.jsx +9 -6
- package/src/plugins/image/__tests__/__snapshots__/component.test.jsx.snap +51 -0
- package/src/plugins/image/__tests__/__snapshots__/image-toolbar-logic.test.jsx.snap +27 -0
- package/src/plugins/image/__tests__/__snapshots__/image-toolbar.test.jsx.snap +44 -0
- package/src/plugins/image/__tests__/component.test.jsx +41 -0
- package/src/plugins/image/__tests__/image-toolbar-logic.test.jsx +42 -0
- package/src/plugins/image/__tests__/image-toolbar.test.jsx +11 -0
- package/src/plugins/image/__tests__/index.test.js +95 -0
- package/src/plugins/image/__tests__/insert-image-handler.test.js +113 -0
- package/src/plugins/image/__tests__/mock-change.js +15 -0
- package/src/plugins/image/index.jsx +2 -1
- package/src/plugins/image/insert-image-handler.js +13 -6
- package/src/plugins/index.jsx +248 -5
- package/src/plugins/list/__tests__/index.test.js +54 -0
- package/src/plugins/list/index.jsx +130 -0
- package/src/plugins/math/__tests__/__snapshots__/index.test.jsx.snap +48 -0
- package/src/plugins/math/__tests__/index.test.jsx +245 -0
- package/src/plugins/math/index.jsx +87 -56
- package/src/plugins/media/__tests__/index.test.js +75 -0
- package/src/plugins/media/index.jsx +3 -2
- package/src/plugins/media/media-dialog.js +106 -57
- package/src/plugins/rendering/index.js +31 -0
- package/src/plugins/respArea/drag-in-the-blank/choice.jsx +4 -1
- package/src/plugins/respArea/explicit-constructed-response/index.jsx +10 -8
- package/src/plugins/respArea/index.jsx +53 -7
- package/src/plugins/respArea/inline-dropdown/index.jsx +13 -6
- package/src/plugins/respArea/math-templated/index.jsx +104 -0
- package/src/plugins/respArea/utils.jsx +11 -0
- package/src/plugins/table/CustomTablePlugin.js +113 -0
- package/src/plugins/table/__tests__/__snapshots__/table-toolbar.test.jsx.snap +44 -0
- package/src/plugins/table/__tests__/index.test.jsx +401 -0
- package/src/plugins/table/__tests__/table-toolbar.test.jsx +42 -0
- package/src/plugins/table/index.jsx +46 -59
- package/src/plugins/table/table-toolbar.jsx +39 -2
- package/src/plugins/textAlign/icons/index.jsx +139 -0
- package/src/plugins/textAlign/index.jsx +23 -0
- package/src/plugins/toolbar/__tests__/__snapshots__/default-toolbar.test.jsx.snap +923 -0
- package/src/plugins/toolbar/__tests__/__snapshots__/editor-and-toolbar.test.jsx.snap +20 -0
- package/src/plugins/toolbar/__tests__/__snapshots__/toolbar-buttons.test.jsx.snap +36 -0
- package/src/plugins/toolbar/__tests__/__snapshots__/toolbar.test.jsx.snap +46 -0
- package/src/plugins/toolbar/__tests__/default-toolbar.test.jsx +94 -0
- package/src/plugins/toolbar/__tests__/editor-and-toolbar.test.jsx +37 -0
- package/src/plugins/toolbar/__tests__/toolbar-buttons.test.jsx +51 -0
- package/src/plugins/toolbar/__tests__/toolbar.test.jsx +106 -0
- package/src/plugins/toolbar/default-toolbar.jsx +82 -20
- package/src/plugins/toolbar/done-button.jsx +3 -1
- package/src/plugins/toolbar/editor-and-toolbar.jsx +18 -13
- package/src/plugins/toolbar/toolbar-buttons.jsx +52 -11
- package/src/plugins/toolbar/toolbar.jsx +31 -8
- package/src/serialization.jsx +213 -38
- package/README.md +0 -45
- package/deploy.sh +0 -16
- package/playground/image/data.js +0 -59
- package/playground/image/index.html +0 -22
- package/playground/image/index.jsx +0 -81
- package/playground/index.html +0 -25
- package/playground/mathquill/index.html +0 -22
- package/playground/mathquill/index.jsx +0 -155
- package/playground/package.json +0 -15
- package/playground/prod-test/index.html +0 -22
- package/playground/prod-test/index.jsx +0 -28
- package/playground/schema-override/data.js +0 -29
- package/playground/schema-override/image-plugin.jsx +0 -41
- package/playground/schema-override/index.html +0 -21
- package/playground/schema-override/index.jsx +0 -97
- package/playground/serialization/data.js +0 -29
- package/playground/serialization/image-plugin.jsx +0 -41
- package/playground/serialization/index.html +0 -22
- package/playground/serialization/index.jsx +0 -12
- package/playground/static.json +0 -3
- package/playground/table-examples.html +0 -70
- package/playground/webpack.config.js +0 -42
- package/static.json +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import EditTable from 'slate-edit-table';
|
|
3
2
|
import { Block } from 'slate';
|
|
4
3
|
import debug from 'debug';
|
|
5
4
|
import GridOn from '@material-ui/icons/GridOn';
|
|
@@ -9,6 +8,7 @@ import SlatePropTypes from 'slate-prop-types';
|
|
|
9
8
|
import { withStyles } from '@material-ui/core/styles';
|
|
10
9
|
import convert from 'react-attr-converter';
|
|
11
10
|
import { object as toStyleObject } from 'to-style';
|
|
11
|
+
import CustomTablePlugin from './CustomTablePlugin';
|
|
12
12
|
|
|
13
13
|
const log = debug('@pie-lib:editable-html:plugins:table');
|
|
14
14
|
|
|
@@ -93,9 +93,7 @@ export const moveFocusToBeginningOfTable = (change) => {
|
|
|
93
93
|
};
|
|
94
94
|
|
|
95
95
|
export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
96
|
-
const core =
|
|
97
|
-
typeContent: 'div',
|
|
98
|
-
});
|
|
96
|
+
const core = CustomTablePlugin(opts);
|
|
99
97
|
|
|
100
98
|
// fix outdated schema
|
|
101
99
|
|
|
@@ -142,7 +140,9 @@ export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
|
142
140
|
};
|
|
143
141
|
|
|
144
142
|
core.toolbar = {
|
|
143
|
+
type: 'table',
|
|
145
144
|
icon: <GridOn />,
|
|
145
|
+
ariaLabel: 'Insert Table',
|
|
146
146
|
onClick: (value, onChange) => {
|
|
147
147
|
log('insert table');
|
|
148
148
|
const change = value.change();
|
|
@@ -162,7 +162,7 @@ export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
|
162
162
|
/**
|
|
163
163
|
* Note - the node may not be a table node - it may be a node inside a table.
|
|
164
164
|
*/
|
|
165
|
-
customToolbar: (node, value, onToolbarDone) => {
|
|
165
|
+
customToolbar: (node, value, onToolbarDone, getFocusedValue) => {
|
|
166
166
|
log('[customToolbar] node.data: ', node.data);
|
|
167
167
|
|
|
168
168
|
const tableBlock = core.utils.getTableBlock(value.document, node?.key);
|
|
@@ -209,6 +209,7 @@ export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
|
209
209
|
|
|
210
210
|
const Tb = () => (
|
|
211
211
|
<TableToolbar
|
|
212
|
+
getFocusedValue={getFocusedValue}
|
|
212
213
|
plugins={toolbarPlugins}
|
|
213
214
|
onChange={(c) => onToolbarDone(c, false)}
|
|
214
215
|
value={value}
|
|
@@ -222,6 +223,7 @@ export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
|
222
223
|
onDone={onDone}
|
|
223
224
|
/>
|
|
224
225
|
);
|
|
226
|
+
|
|
225
227
|
return Tb;
|
|
226
228
|
},
|
|
227
229
|
};
|
|
@@ -243,74 +245,59 @@ export default (opts, toolbarPlugins /* : {toolbar: {}}[] */) => {
|
|
|
243
245
|
};
|
|
244
246
|
|
|
245
247
|
core.normalizeNode = (node) => {
|
|
246
|
-
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
248
|
+
const addNodeBeforeArray = [];
|
|
249
249
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
if (!tableAdded) {
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
250
|
+
if (node.object !== 'document') return;
|
|
255
251
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
252
|
+
node.findDescendant((d) => {
|
|
253
|
+
if (d.type === 'table') {
|
|
254
|
+
const tablePath = node.getPath(d.key);
|
|
255
|
+
const prevNode = node.getPreviousNode(tablePath);
|
|
256
|
+
const nextNode = node.getNextNode(tablePath);
|
|
260
257
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
258
|
+
if (!prevNode || !nextNode) {
|
|
259
|
+
addNodeBeforeArray.push({
|
|
260
|
+
node: d,
|
|
261
|
+
prevNode,
|
|
262
|
+
nextNode,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
});
|
|
265
267
|
|
|
266
|
-
if (!
|
|
268
|
+
if (!addNodeBeforeArray.length) {
|
|
267
269
|
return;
|
|
268
270
|
}
|
|
269
271
|
|
|
270
272
|
return (change) => {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
// we need a block that contains text in order to do it
|
|
276
|
-
change.removeNodeByKey(tableAdded.key);
|
|
273
|
+
const newBlock = {
|
|
274
|
+
object: 'block',
|
|
275
|
+
type: 'div',
|
|
276
|
+
};
|
|
277
277
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
// we get the text previous to the new block added
|
|
291
|
-
const prevText = change.value.document.getPreviousText(newBlock.key);
|
|
292
|
-
|
|
293
|
-
if (prevText) {
|
|
294
|
-
// we move focus to the previous text
|
|
295
|
-
change.moveFocusTo(prevText.key, prevText.text?.length).moveAnchorTo(prevText.key, prevText.text?.length);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// we insert the table block between the first block with text and the last block with text
|
|
299
|
-
change.insertBlock({
|
|
300
|
-
...tableJSON,
|
|
301
|
-
data: {
|
|
302
|
-
...tableJSON.data,
|
|
303
|
-
newTable: true,
|
|
304
|
-
},
|
|
305
|
-
});
|
|
278
|
+
addNodeBeforeArray.forEach((n) => {
|
|
279
|
+
const tablePath = change.value.document.getPath(n.node.key).toJSON();
|
|
280
|
+
// removing tableIndex
|
|
281
|
+
let indexToAdd = tablePath.splice(-1)[0];
|
|
282
|
+
|
|
283
|
+
if (!n.prevNode) {
|
|
284
|
+
// inserting block key before table
|
|
285
|
+
change.insertNodeByPath(tablePath, indexToAdd, newBlock);
|
|
286
|
+
// this will trigger another normalization, which will figure out if there's not
|
|
287
|
+
// a block after the table and add it, so we exit for now
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
306
290
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
291
|
+
if (!n.nextNode) {
|
|
292
|
+
// inserting block key after table
|
|
293
|
+
change.insertNodeByPath(tablePath, indexToAdd + 1, newBlock);
|
|
294
|
+
}
|
|
295
|
+
});
|
|
310
296
|
};
|
|
311
297
|
};
|
|
312
298
|
|
|
313
299
|
core.renderNode = Node;
|
|
300
|
+
core.name = 'table';
|
|
314
301
|
|
|
315
302
|
return core;
|
|
316
303
|
};
|
|
@@ -41,6 +41,7 @@ export class TableToolbar extends React.Component {
|
|
|
41
41
|
|
|
42
42
|
render() {
|
|
43
43
|
const {
|
|
44
|
+
getFocusedValue,
|
|
44
45
|
plugins,
|
|
45
46
|
value,
|
|
46
47
|
onChange,
|
|
@@ -55,6 +56,27 @@ export class TableToolbar extends React.Component {
|
|
|
55
56
|
} = this.props;
|
|
56
57
|
log('[render] hasBorder:', hasBorder);
|
|
57
58
|
|
|
59
|
+
// we're separating the response area plugin because we want to display it next to the done button
|
|
60
|
+
const filteredPlugins = (plugins || []).reduce(
|
|
61
|
+
(acc, plugin) => {
|
|
62
|
+
if (plugin.name === 'response_area') {
|
|
63
|
+
return {
|
|
64
|
+
...acc,
|
|
65
|
+
respAreaPlugin: plugin,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return {
|
|
70
|
+
...acc,
|
|
71
|
+
otherPlugins: [...acc.otherPlugins, plugin],
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
respAreaPlugin: null,
|
|
76
|
+
otherPlugins: [],
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
|
|
58
80
|
return (
|
|
59
81
|
<div className={classes.tableToolbar}>
|
|
60
82
|
<div className={classes.toolbarButtons}>
|
|
@@ -73,13 +95,28 @@ export class TableToolbar extends React.Component {
|
|
|
73
95
|
<Button onClick={onRemoveTable}>
|
|
74
96
|
<RemoveTable />
|
|
75
97
|
</Button>
|
|
76
|
-
{
|
|
77
|
-
<ToolbarButton
|
|
98
|
+
{(filteredPlugins.otherPlugins || []).map((p, index) => (
|
|
99
|
+
<ToolbarButton
|
|
100
|
+
key={`plugin-${index}`}
|
|
101
|
+
{...p.toolbar}
|
|
102
|
+
value={value}
|
|
103
|
+
onChange={onChange}
|
|
104
|
+
getFocusedValue={getFocusedValue}
|
|
105
|
+
/>
|
|
78
106
|
))}
|
|
79
107
|
<Button onClick={onToggleBorder} active={hasBorder}>
|
|
80
108
|
<BorderAll />
|
|
81
109
|
</Button>
|
|
82
110
|
</div>
|
|
111
|
+
{filteredPlugins.respAreaPlugin && (
|
|
112
|
+
<ToolbarButton
|
|
113
|
+
key={'plugin-response-area'}
|
|
114
|
+
{...filteredPlugins.respAreaPlugin.toolbar}
|
|
115
|
+
value={value}
|
|
116
|
+
onChange={onChange}
|
|
117
|
+
getFocusedValue={getFocusedValue}
|
|
118
|
+
/>
|
|
119
|
+
)}
|
|
83
120
|
<DoneButton onClick={this.onDone} />
|
|
84
121
|
</div>
|
|
85
122
|
);
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import Collapse from '@material-ui/core/Collapse';
|
|
3
|
+
import List from '@material-ui/core/List';
|
|
4
|
+
import ListItem from '@material-ui/core/ListItem';
|
|
5
|
+
|
|
6
|
+
export const AlignLeft = () => (
|
|
7
|
+
<svg width="20" height="20" viewBox="0 0 66 66" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
8
|
+
<path
|
|
9
|
+
d="M42.1875 4.75C42.1875 7.38672 39.9902 9.4375 37.5 9.4375H4.6875C2.05078 9.4375 0 7.38672 0 4.75C0 2.25977 2.05078 0.0625 4.6875 0.0625H37.5C39.9902 0.0625 42.1875 2.25977 42.1875 4.75ZM42.1875 42.25C42.1875 44.8867 39.9902 46.9375 37.5 46.9375H4.6875C2.05078 46.9375 0 44.8867 0 42.25C0 39.7598 2.05078 37.5625 4.6875 37.5625H37.5C39.9902 37.5625 42.1875 39.7598 42.1875 42.25ZM0 23.5C0 21.0098 2.05078 18.8125 4.6875 18.8125H60.9375C63.4277 18.8125 65.625 21.0098 65.625 23.5C65.625 26.1367 63.4277 28.1875 60.9375 28.1875H4.6875C2.05078 28.1875 0 26.1367 0 23.5ZM65.625 61C65.625 63.6367 63.4277 65.6875 60.9375 65.6875H4.6875C2.05078 65.6875 0 63.6367 0 61C0 58.5098 2.05078 56.3125 4.6875 56.3125H60.9375C63.4277 56.3125 65.625 58.5098 65.625 61Z"
|
|
10
|
+
fill="currentColor"
|
|
11
|
+
/>
|
|
12
|
+
</svg>
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
export const AlignRight = () => (
|
|
16
|
+
<svg width="20" height="20" viewBox="0 0 66 66" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
17
|
+
<path
|
|
18
|
+
d="M65.625 4.75C65.625 7.38672 63.4277 9.4375 60.9375 9.4375H28.125C25.4883 9.4375 23.4375 7.38672 23.4375 4.75C23.4375 2.25977 25.4883 0.0625 28.125 0.0625H60.9375C63.4277 0.0625 65.625 2.25977 65.625 4.75ZM65.625 42.25C65.625 44.8867 63.4277 46.9375 60.9375 46.9375H28.125C25.4883 46.9375 23.4375 44.8867 23.4375 42.25C23.4375 39.7598 25.4883 37.5625 28.125 37.5625H60.9375C63.4277 37.5625 65.625 39.7598 65.625 42.25ZM0 23.5C0 21.0098 2.05078 18.8125 4.6875 18.8125H60.9375C63.4277 18.8125 65.625 21.0098 65.625 23.5C65.625 26.1367 63.4277 28.1875 60.9375 28.1875H4.6875C2.05078 28.1875 0 26.1367 0 23.5ZM65.625 61C65.625 63.6367 63.4277 65.6875 60.9375 65.6875H4.6875C2.05078 65.6875 0 63.6367 0 61C0 58.5098 2.05078 56.3125 4.6875 56.3125H60.9375C63.4277 56.3125 65.625 58.5098 65.625 61Z"
|
|
19
|
+
fill="currentColor"
|
|
20
|
+
/>
|
|
21
|
+
</svg>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export const AlignCenter = () => (
|
|
25
|
+
<svg width="20" height="20" viewBox="0 0 66 66" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
26
|
+
<path
|
|
27
|
+
d="M51.5625 4.75C51.5625 7.38672 49.3652 9.4375 46.875 9.4375H18.75C16.1133 9.4375 14.0625 7.38672 14.0625 4.75C14.0625 2.25977 16.1133 0.0625 18.75 0.0625H46.875C49.3652 0.0625 51.5625 2.25977 51.5625 4.75ZM65.625 23.5C65.625 26.1367 63.4277 28.1875 60.9375 28.1875H4.6875C2.05078 28.1875 0 26.1367 0 23.5C0 21.0098 2.05078 18.8125 4.6875 18.8125H60.9375C63.4277 18.8125 65.625 21.0098 65.625 23.5ZM0 61C0 58.5098 2.05078 56.3125 4.6875 56.3125H60.9375C63.4277 56.3125 65.625 58.5098 65.625 61C65.625 63.6367 63.4277 65.6875 60.9375 65.6875H4.6875C2.05078 65.6875 0 63.6367 0 61ZM51.5625 42.25C51.5625 44.8867 49.3652 46.9375 46.875 46.9375H18.75C16.1133 46.9375 14.0625 44.8867 14.0625 42.25C14.0625 39.7598 16.1133 37.5625 18.75 37.5625H46.875C49.3652 37.5625 51.5625 39.7598 51.5625 42.25Z"
|
|
28
|
+
fill="currentColor"
|
|
29
|
+
/>
|
|
30
|
+
</svg>
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export const AlignJustify = () => (
|
|
34
|
+
<svg width="20" height="20" viewBox="0 0 66 66" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
35
|
+
<path
|
|
36
|
+
d="M65.625 4.75C65.625 7.38672 63.4277 9.4375 60.9375 9.4375H4.6875C2.05078 9.4375 0 7.38672 0 4.75C0 2.25977 2.05078 0.0625 4.6875 0.0625H60.9375C63.4277 0.0625 65.625 2.25977 65.625 4.75ZM65.625 42.25C65.625 44.8867 63.4277 46.9375 60.9375 46.9375H4.6875C2.05078 46.9375 0 44.8867 0 42.25C0 39.7598 2.05078 37.5625 4.6875 37.5625H60.9375C63.4277 37.5625 65.625 39.7598 65.625 42.25ZM0 23.5C0 21.0098 2.05078 18.8125 4.6875 18.8125H60.9375C63.4277 18.8125 65.625 21.0098 65.625 23.5C65.625 26.1367 63.4277 28.1875 60.9375 28.1875H4.6875C2.05078 28.1875 0 26.1367 0 23.5ZM65.625 61C65.625 63.6367 63.4277 65.6875 60.9375 65.6875H4.6875C2.05078 65.6875 0 63.6367 0 61C0 58.5098 2.05078 56.3125 4.6875 56.3125H60.9375C63.4277 56.3125 65.625 58.5098 65.625 61Z"
|
|
37
|
+
fill="currentColor"
|
|
38
|
+
/>
|
|
39
|
+
</svg>
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export default ({ getValue, onChange }) => {
|
|
43
|
+
const [open, setOpen] = useState(false);
|
|
44
|
+
const value = getValue();
|
|
45
|
+
const text = value.texts.get(0);
|
|
46
|
+
|
|
47
|
+
let type;
|
|
48
|
+
|
|
49
|
+
if (text) {
|
|
50
|
+
const blockParent = value.document.getParent(text.key);
|
|
51
|
+
const data = blockParent.data.toJSON();
|
|
52
|
+
|
|
53
|
+
if (data?.attributes?.align) {
|
|
54
|
+
type = data?.attributes?.align;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
let icon;
|
|
59
|
+
|
|
60
|
+
switch (type) {
|
|
61
|
+
case 'right':
|
|
62
|
+
icon = <AlignRight />;
|
|
63
|
+
break;
|
|
64
|
+
case 'center':
|
|
65
|
+
icon = <AlignCenter />;
|
|
66
|
+
break;
|
|
67
|
+
case 'justify':
|
|
68
|
+
icon = <AlignJustify />;
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
icon = <AlignLeft />;
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const applyAlignment = (event) => {
|
|
76
|
+
if (value.texts.size) {
|
|
77
|
+
const alignType = event.target?.closest('div')?.getAttribute('value');
|
|
78
|
+
|
|
79
|
+
if (alignType) {
|
|
80
|
+
let c = value.change();
|
|
81
|
+
|
|
82
|
+
value.texts.forEach((text) => {
|
|
83
|
+
const blockParent = value.document.getParent(text.key);
|
|
84
|
+
|
|
85
|
+
c = c.setNodeByKey(blockParent.key, {
|
|
86
|
+
data: { ...blockParent.data, attributes: { ...blockParent.data?.attributes, align: alignType } },
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
onChange(c);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
setOpen(false);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const onMouseDown = (event) => {
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
event.stopPropagation();
|
|
100
|
+
setOpen(!open);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<div>
|
|
105
|
+
<div style={{ display: 'flex', alignItems: 'center' }} onClick={onMouseDown}>
|
|
106
|
+
{icon}
|
|
107
|
+
<span style={{ marginLeft: '5px', fontSize: '8px' }}>▼</span>
|
|
108
|
+
</div>
|
|
109
|
+
<Collapse in={open} timeout="auto" unmountOnExit style={{ position: 'absolute' }}>
|
|
110
|
+
<List
|
|
111
|
+
component="div"
|
|
112
|
+
disablePadding
|
|
113
|
+
style={{
|
|
114
|
+
background: '#fff',
|
|
115
|
+
display: 'flex',
|
|
116
|
+
flexDirection: 'row',
|
|
117
|
+
padding: 0,
|
|
118
|
+
}}
|
|
119
|
+
>
|
|
120
|
+
<ListItem button type="submit" value="left" aria-label="Align text left" onClick={applyAlignment}>
|
|
121
|
+
<AlignLeft />
|
|
122
|
+
</ListItem>
|
|
123
|
+
|
|
124
|
+
<ListItem button type="submit" value="center" aria-label="Align text center" onClick={applyAlignment}>
|
|
125
|
+
<AlignCenter />
|
|
126
|
+
</ListItem>
|
|
127
|
+
|
|
128
|
+
<ListItem button type="submit" value="right" aria-label="Align text right" onClick={applyAlignment}>
|
|
129
|
+
<AlignRight />
|
|
130
|
+
</ListItem>
|
|
131
|
+
|
|
132
|
+
<ListItem button type="submit" value="justify" aria-label="Justify text" onClick={applyAlignment}>
|
|
133
|
+
<AlignJustify />
|
|
134
|
+
</ListItem>
|
|
135
|
+
</List>
|
|
136
|
+
</Collapse>
|
|
137
|
+
</div>
|
|
138
|
+
);
|
|
139
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import debug from 'debug';
|
|
3
|
+
import TextAlignIcon from './icons';
|
|
4
|
+
|
|
5
|
+
const log = debug('@pie-lib:editable-html:plugins:characters');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Plugin in order to be able to change alignment for the selected text(s) element(s).
|
|
9
|
+
* @param opts
|
|
10
|
+
* @constructor
|
|
11
|
+
*/
|
|
12
|
+
export default function TextAlign(opts) {
|
|
13
|
+
const plugin = {
|
|
14
|
+
name: 'textAlign',
|
|
15
|
+
toolbar: {
|
|
16
|
+
icon: <TextAlignIcon {...opts} />,
|
|
17
|
+
ariaLabel: 'Text Align',
|
|
18
|
+
onClick: () => {},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return plugin;
|
|
23
|
+
}
|