@mirrormedia/lilith-draft-editor 2.2.1 → 3.0.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/README.md +3 -9
- package/lib/draft-js/buttons/selector/video-selector.js +1 -2
- package/lib/hooks.js +34 -0
- package/lib/website/mirrordaily/README.md +3 -0
- package/lib/website/mirrordaily/block-renderer/background-image-block.js +93 -0
- package/lib/website/mirrordaily/block-renderer/background-video-block.js +93 -0
- package/lib/website/mirrordaily/block-renderer/color-box-block.js +86 -0
- package/lib/website/mirrordaily/block-renderer/embedded-code-block.js +88 -0
- package/lib/website/mirrordaily/block-renderer/image-block.js +108 -0
- package/lib/website/mirrordaily/block-renderer/info-box-block.js +86 -0
- package/lib/website/mirrordaily/block-renderer/side-index-block.js +90 -0
- package/lib/website/mirrordaily/block-renderer/slideshow-block.js +150 -0
- package/lib/website/mirrordaily/block-renderer/table-block.js +408 -0
- package/lib/website/mirrordaily/block-renderer-fn.js +151 -0
- package/lib/website/mirrordaily/draft-editor.js +972 -0
- package/lib/website/mirrordaily/entity-decorator.js +27 -0
- package/lib/website/mirrordaily/index.js +16 -0
- package/lib/website/mirrordaily/selector/align-selector.js +71 -0
- package/lib/website/mirrordaily/selector/audio-selector.js +283 -0
- package/lib/website/mirrordaily/selector/image-selector.js +451 -0
- package/lib/website/mirrordaily/selector/pagination.js +82 -0
- package/lib/website/mirrordaily/selector/post-selector.js +321 -0
- package/lib/website/mirrordaily/selector/search-box.js +46 -0
- package/lib/website/mirrordaily/selector/video-selector.js +326 -0
- package/lib/website/mirrordaily/shared-style/index.js +17 -0
- package/lib/website/mirrordaily/theme/index.js +28 -0
- package/lib/website/mirrormedia/draft-editor.js +1 -5
- package/lib/website/readr/draft-editor.js +126 -92
- package/lib/website/readr/selector/align-selector.js +3 -3
- package/lib/website/readr/selector/audio-selector.js +4 -2
- package/lib/website/readr/selector/image-selector.js +16 -9
- package/lib/website/readr/selector/post-selector.js +4 -2
- package/lib/website/readr/selector/video-selector.js +4 -2
- package/package.json +3 -2
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SideIndexEditorBlock = SideIndexEditorBlock;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
11
|
+
|
|
12
|
+
var _sideIndex = require("../../../draft-js/buttons/side-index");
|
|
13
|
+
|
|
14
|
+
var _mirrormedia = _interopRequireDefault(require("@mirrormedia/lilith-draft-renderer/lib/website/mirrormedia"));
|
|
15
|
+
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
|
|
18
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
19
|
+
|
|
20
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
21
|
+
|
|
22
|
+
const {
|
|
23
|
+
SideIndexBlock
|
|
24
|
+
} = _mirrormedia.default.blockRenderers;
|
|
25
|
+
const SideIndexBlockButton = _styledComponents.default.div`
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
margin-left: 20px;
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
function SideIndexEditorBlock(props) {
|
|
31
|
+
const [toShowInput, setToShowInput] = (0, _react.useState)(false);
|
|
32
|
+
const {
|
|
33
|
+
block,
|
|
34
|
+
blockProps,
|
|
35
|
+
contentState
|
|
36
|
+
} = props;
|
|
37
|
+
const {
|
|
38
|
+
onEditStart,
|
|
39
|
+
onEditFinish
|
|
40
|
+
} = blockProps;
|
|
41
|
+
const entityKey = block.getEntityAt(0);
|
|
42
|
+
const entity = contentState.getEntity(entityKey);
|
|
43
|
+
const {
|
|
44
|
+
h2Text,
|
|
45
|
+
sideIndexText,
|
|
46
|
+
sideIndexUrl,
|
|
47
|
+
sideIndexImage
|
|
48
|
+
} = entity.getData();
|
|
49
|
+
|
|
50
|
+
const onChange = ({
|
|
51
|
+
h2Text,
|
|
52
|
+
sideIndexText,
|
|
53
|
+
sideIndexUrl,
|
|
54
|
+
sideIndexImage
|
|
55
|
+
}) => {
|
|
56
|
+
// close `SideIndexInput`
|
|
57
|
+
setToShowInput(false);
|
|
58
|
+
onEditFinish({
|
|
59
|
+
entityKey,
|
|
60
|
+
entityData: {
|
|
61
|
+
h2Text,
|
|
62
|
+
sideIndexText,
|
|
63
|
+
sideIndexUrl,
|
|
64
|
+
sideIndexImage
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_sideIndex.SideIndexInput, {
|
|
70
|
+
h2Text: h2Text,
|
|
71
|
+
sideIndexText: sideIndexText,
|
|
72
|
+
sideIndexUrl: sideIndexUrl,
|
|
73
|
+
sideIndexImage: sideIndexImage,
|
|
74
|
+
onChange: onChange,
|
|
75
|
+
onCancel: () => {
|
|
76
|
+
onEditFinish({});
|
|
77
|
+
setToShowInput(false);
|
|
78
|
+
},
|
|
79
|
+
isOpen: toShowInput
|
|
80
|
+
}), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(SideIndexBlock, props), /*#__PURE__*/_react.default.createElement(SideIndexBlockButton, {
|
|
81
|
+
onClick: () => {
|
|
82
|
+
// call `onEditStart` prop as we are trying to update the SideIndex entity
|
|
83
|
+
onEditStart(); // open `SideIndexInput`
|
|
84
|
+
|
|
85
|
+
setToShowInput(true);
|
|
86
|
+
}
|
|
87
|
+
}, /*#__PURE__*/_react.default.createElement("i", {
|
|
88
|
+
className: "fa-solid fa-pen"
|
|
89
|
+
}), /*#__PURE__*/_react.default.createElement("span", null, "Modify"))));
|
|
90
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SlideshowEditBlock = SlideshowEditBlock;
|
|
7
|
+
exports.SlideshowEditBlockV2 = SlideshowEditBlockV2;
|
|
8
|
+
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
|
|
11
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
12
|
+
|
|
13
|
+
var _imageSelector = require("../selector/image-selector");
|
|
14
|
+
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
+
|
|
17
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
18
|
+
|
|
19
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
20
|
+
|
|
21
|
+
const Image = _styledComponents.default.img`
|
|
22
|
+
width: 100%;
|
|
23
|
+
`;
|
|
24
|
+
const SlideshowCount = _styledComponents.default.div`
|
|
25
|
+
position: absolute;
|
|
26
|
+
top: 50%;
|
|
27
|
+
left: 50%;
|
|
28
|
+
border-radius: 100%;
|
|
29
|
+
border: black 1px solid;
|
|
30
|
+
transform: translate(-50%, -50%);
|
|
31
|
+
background-color: white;
|
|
32
|
+
display: flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
justify-content: center;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
aspect-ratio: 1;
|
|
37
|
+
min-height: 66px;
|
|
38
|
+
padding: 10px;
|
|
39
|
+
`;
|
|
40
|
+
const Figure = _styledComponents.default.figure`
|
|
41
|
+
position: relative;
|
|
42
|
+
margin-block: unset;
|
|
43
|
+
margin-inline: unset;
|
|
44
|
+
margin: 0 10px;
|
|
45
|
+
`;
|
|
46
|
+
const SlideshowEditButton = _styledComponents.default.span`
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
background-color: white;
|
|
49
|
+
padding: 6px;
|
|
50
|
+
border-radius: 6px;
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
// support old version of slideshow without delay propertiy
|
|
54
|
+
function SlideshowEditBlock(props) {
|
|
55
|
+
var _images$, _images$$resized;
|
|
56
|
+
|
|
57
|
+
const {
|
|
58
|
+
block,
|
|
59
|
+
contentState
|
|
60
|
+
} = props;
|
|
61
|
+
const entityKey = block.getEntityAt(0);
|
|
62
|
+
const entity = contentState.getEntity(entityKey);
|
|
63
|
+
const images = entity.getData();
|
|
64
|
+
return /*#__PURE__*/_react.default.createElement(Figure, null, /*#__PURE__*/_react.default.createElement(Image, {
|
|
65
|
+
src: images === null || images === void 0 ? void 0 : (_images$ = images[0]) === null || _images$ === void 0 ? void 0 : (_images$$resized = _images$.resized) === null || _images$$resized === void 0 ? void 0 : _images$$resized.original,
|
|
66
|
+
onError: e => {
|
|
67
|
+
var _images$2, _images$2$imageFile;
|
|
68
|
+
|
|
69
|
+
return e.currentTarget.src = images === null || images === void 0 ? void 0 : (_images$2 = images[0]) === null || _images$2 === void 0 ? void 0 : (_images$2$imageFile = _images$2.imageFile) === null || _images$2$imageFile === void 0 ? void 0 : _images$2$imageFile.url;
|
|
70
|
+
}
|
|
71
|
+
}), /*#__PURE__*/_react.default.createElement(SlideshowCount, null, "+", images.length));
|
|
72
|
+
} // 202206 latest version of slideshow, support delay property
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
function SlideshowEditBlockV2(props) {
|
|
76
|
+
var _images$3, _images$3$resized;
|
|
77
|
+
|
|
78
|
+
const {
|
|
79
|
+
block,
|
|
80
|
+
blockProps,
|
|
81
|
+
contentState
|
|
82
|
+
} = props;
|
|
83
|
+
const {
|
|
84
|
+
onEditStart,
|
|
85
|
+
onEditFinish
|
|
86
|
+
} = blockProps;
|
|
87
|
+
const entityKey = block.getEntityAt(0);
|
|
88
|
+
const entity = contentState.getEntity(entityKey);
|
|
89
|
+
const {
|
|
90
|
+
images,
|
|
91
|
+
delay
|
|
92
|
+
} = entity.getData();
|
|
93
|
+
const initialSelected = images.map(image => ({
|
|
94
|
+
desc: image.desc,
|
|
95
|
+
image: {
|
|
96
|
+
id: image.id,
|
|
97
|
+
name: image.name,
|
|
98
|
+
imageFile: image.imageFile,
|
|
99
|
+
resized: image.resized,
|
|
100
|
+
resizedWebp: image.resizedWebp
|
|
101
|
+
}
|
|
102
|
+
}));
|
|
103
|
+
const [toShowImageSelector, setToShowImageSelector] = (0, _react.useState)(false);
|
|
104
|
+
|
|
105
|
+
const onImageSelectorChange = (selected, align, delay) => {
|
|
106
|
+
if (selected.length === 0) {
|
|
107
|
+
onEditFinish({});
|
|
108
|
+
} else {
|
|
109
|
+
onEditFinish({
|
|
110
|
+
entityKey,
|
|
111
|
+
entityData: {
|
|
112
|
+
alignment: align,
|
|
113
|
+
delay,
|
|
114
|
+
images: selected.map(ele => {
|
|
115
|
+
return { ...(ele === null || ele === void 0 ? void 0 : ele.image),
|
|
116
|
+
desc: ele === null || ele === void 0 ? void 0 : ele.desc
|
|
117
|
+
};
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
setToShowImageSelector(false);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, toShowImageSelector && /*#__PURE__*/_react.default.createElement(_imageSelector.ImageSelector, {
|
|
127
|
+
onChange: onImageSelectorChange,
|
|
128
|
+
enableCaption: true,
|
|
129
|
+
enableDelay: true,
|
|
130
|
+
enableMultiSelect: true,
|
|
131
|
+
initialSelected: initialSelected,
|
|
132
|
+
initialDelay: delay
|
|
133
|
+
}), /*#__PURE__*/_react.default.createElement(Figure, null, /*#__PURE__*/_react.default.createElement(Image, {
|
|
134
|
+
src: images === null || images === void 0 ? void 0 : (_images$3 = images[0]) === null || _images$3 === void 0 ? void 0 : (_images$3$resized = _images$3.resized) === null || _images$3$resized === void 0 ? void 0 : _images$3$resized.original,
|
|
135
|
+
onError: e => {
|
|
136
|
+
var _images$4, _images$4$imageFile;
|
|
137
|
+
|
|
138
|
+
return e.currentTarget.src = images === null || images === void 0 ? void 0 : (_images$4 = images[0]) === null || _images$4 === void 0 ? void 0 : (_images$4$imageFile = _images$4.imageFile) === null || _images$4$imageFile === void 0 ? void 0 : _images$4$imageFile.url;
|
|
139
|
+
}
|
|
140
|
+
}), /*#__PURE__*/_react.default.createElement(SlideshowCount, null, /*#__PURE__*/_react.default.createElement("div", null, "+", images.length), delay && /*#__PURE__*/_react.default.createElement("div", null, `${delay}s`))), /*#__PURE__*/_react.default.createElement(SlideshowEditButton, {
|
|
141
|
+
onClick: () => {
|
|
142
|
+
// call `onEditStart` prop as we are trying to update the BGImage entity
|
|
143
|
+
onEditStart(); // open `BGImageInput`
|
|
144
|
+
|
|
145
|
+
setToShowImageSelector(true);
|
|
146
|
+
}
|
|
147
|
+
}, /*#__PURE__*/_react.default.createElement("i", {
|
|
148
|
+
className: "fa-solid fa-pen"
|
|
149
|
+
}), /*#__PURE__*/_react.default.createElement("span", null, "Modify")));
|
|
150
|
+
}
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.TableEditorBlock = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _styledComponents = _interopRequireDefault(require("styled-components"));
|
|
11
|
+
|
|
12
|
+
var _draftJs = require("draft-js");
|
|
13
|
+
|
|
14
|
+
var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
|
|
15
|
+
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
|
|
18
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
19
|
+
|
|
20
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
21
|
+
|
|
22
|
+
const _ = {
|
|
23
|
+
cloneDeep: _cloneDeep.default
|
|
24
|
+
};
|
|
25
|
+
var ActionType;
|
|
26
|
+
|
|
27
|
+
(function (ActionType) {
|
|
28
|
+
ActionType["Insert"] = "insert";
|
|
29
|
+
ActionType["Delete"] = "delete";
|
|
30
|
+
ActionType["Update"] = "update";
|
|
31
|
+
})(ActionType || (ActionType = {}));
|
|
32
|
+
|
|
33
|
+
var TableEnum;
|
|
34
|
+
|
|
35
|
+
(function (TableEnum) {
|
|
36
|
+
TableEnum["Row"] = "row";
|
|
37
|
+
TableEnum["Column"] = "column";
|
|
38
|
+
})(TableEnum || (TableEnum = {}));
|
|
39
|
+
|
|
40
|
+
function createEmptyRow(colLen = 0, emptyValue) {
|
|
41
|
+
const rtn = [];
|
|
42
|
+
|
|
43
|
+
for (let i = 0; i < colLen; i++) {
|
|
44
|
+
rtn.push(emptyValue);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return rtn;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function resolveTableStyles(action, tableStyles) {
|
|
51
|
+
switch (action === null || action === void 0 ? void 0 : action.type) {
|
|
52
|
+
case ActionType.Insert:
|
|
53
|
+
{
|
|
54
|
+
if (action.target === TableEnum.Row) {
|
|
55
|
+
const rows = [...tableStyles.rows.slice(0, action.index), {}, ...tableStyles.rows.slice(action.index)];
|
|
56
|
+
return Object.assign({}, tableStyles, {
|
|
57
|
+
rows
|
|
58
|
+
});
|
|
59
|
+
} // TODO: handle target === TableEnum.Column if needed
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
return tableStyles;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
case ActionType.Delete:
|
|
66
|
+
{
|
|
67
|
+
if (action.target === TableEnum.Row) {
|
|
68
|
+
const rows = [...tableStyles.rows.slice(0, action.index), ...tableStyles.rows.slice(action.index + 1)];
|
|
69
|
+
return Object.assign({}, tableStyles, {
|
|
70
|
+
rows
|
|
71
|
+
});
|
|
72
|
+
} // TODO: handle target === TableEnum.Column if needed
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
return tableStyles;
|
|
76
|
+
}
|
|
77
|
+
// TODO: handle action.type === ActionType.Update if needed
|
|
78
|
+
|
|
79
|
+
default:
|
|
80
|
+
{
|
|
81
|
+
return tableStyles;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function resolveTableData(action, tableData) {
|
|
87
|
+
switch (action === null || action === void 0 ? void 0 : action.type) {
|
|
88
|
+
case ActionType.Insert:
|
|
89
|
+
{
|
|
90
|
+
var _tableData$;
|
|
91
|
+
|
|
92
|
+
if (typeof (action === null || action === void 0 ? void 0 : action.index) !== 'number') {
|
|
93
|
+
return tableData;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if ((action === null || action === void 0 ? void 0 : action.target) === TableEnum.Column) {
|
|
97
|
+
// add the new column at specific position in each row
|
|
98
|
+
return tableData.map(r => [...r.slice(0, action === null || action === void 0 ? void 0 : action.index), _draftJs.EditorState.createEmpty(), ...r.slice(action === null || action === void 0 ? void 0 : action.index)]);
|
|
99
|
+
} // add the new row
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
return [...tableData.slice(0, action === null || action === void 0 ? void 0 : action.index), createEmptyRow(tableData === null || tableData === void 0 ? void 0 : (_tableData$ = tableData[0]) === null || _tableData$ === void 0 ? void 0 : _tableData$.length, _draftJs.EditorState.createEmpty()), ...tableData.slice(action === null || action === void 0 ? void 0 : action.index)];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
case ActionType.Delete:
|
|
106
|
+
{
|
|
107
|
+
if (typeof (action === null || action === void 0 ? void 0 : action.index) !== 'number') {
|
|
108
|
+
return tableData;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if ((action === null || action === void 0 ? void 0 : action.target) === 'column') {
|
|
112
|
+
// delete the column at specific position in each row
|
|
113
|
+
return tableData.map(r => [...r.slice(0, action.index), ...r.slice(action.index + 1)]);
|
|
114
|
+
} // delete the column
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
return [...tableData.slice(0, action.index), ...tableData.slice(action.index + 1)];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
case ActionType.Update:
|
|
121
|
+
{
|
|
122
|
+
// The reason we copy the array is to make sure
|
|
123
|
+
// that React component re-renders.
|
|
124
|
+
const copiedData = [...tableData];
|
|
125
|
+
|
|
126
|
+
if (typeof (action === null || action === void 0 ? void 0 : action.rIndex) !== 'number' || typeof (action === null || action === void 0 ? void 0 : action.cIndex) !== 'number') {
|
|
127
|
+
return copiedData;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
copiedData[action.rIndex][action.cIndex] = action === null || action === void 0 ? void 0 : action.value;
|
|
131
|
+
return copiedData;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
default:
|
|
135
|
+
{
|
|
136
|
+
return tableData;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function convertTableDataFromRaw(rawTableData) {
|
|
142
|
+
return rawTableData.map(rowData => {
|
|
143
|
+
return rowData.map(colData => {
|
|
144
|
+
const contentState = (0, _draftJs.convertFromRaw)(colData);
|
|
145
|
+
return _draftJs.EditorState.createWithContent(contentState);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function convertTableDataToRaw(tableData) {
|
|
151
|
+
return tableData.map(rowData => {
|
|
152
|
+
return rowData.map(colData => {
|
|
153
|
+
return (0, _draftJs.convertToRaw)(colData.getCurrentContent());
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const Table = _styledComponents.default.div`
|
|
159
|
+
display: table;
|
|
160
|
+
width: 95%;
|
|
161
|
+
border-collapse: collapse;
|
|
162
|
+
`;
|
|
163
|
+
const Tr = _styledComponents.default.div`
|
|
164
|
+
display: table-row;
|
|
165
|
+
`;
|
|
166
|
+
const Td = _styledComponents.default.div`
|
|
167
|
+
display: table-cell;
|
|
168
|
+
border-width: 1px;
|
|
169
|
+
min-width: 100px;
|
|
170
|
+
min-height: 40px;
|
|
171
|
+
padding: 10px;
|
|
172
|
+
`;
|
|
173
|
+
const StyledFirstRow = _styledComponents.default.div`
|
|
174
|
+
display: table-row;
|
|
175
|
+
height: 10px;
|
|
176
|
+
|
|
177
|
+
div {
|
|
178
|
+
display: table-cell;
|
|
179
|
+
position: relative;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
span {
|
|
183
|
+
cursor: pointer;
|
|
184
|
+
line-height: 10px;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
span:first-child {
|
|
188
|
+
position: absolute;
|
|
189
|
+
right: 50%;
|
|
190
|
+
transform: translateX(50%);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
span:first-child:before {
|
|
194
|
+
content: '•';
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
span:first-child:hover:before {
|
|
198
|
+
content: '➖';
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
span:last-child {
|
|
202
|
+
position: absolute;
|
|
203
|
+
right: -5px;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
span:last-child:before {
|
|
207
|
+
content: '•';
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
span:last-child:hover:before {
|
|
211
|
+
content: '➕';
|
|
212
|
+
}
|
|
213
|
+
`;
|
|
214
|
+
const StyledFirstColumn = _styledComponents.default.div`
|
|
215
|
+
display: table-cell;
|
|
216
|
+
width: 10px;
|
|
217
|
+
position: relative;
|
|
218
|
+
|
|
219
|
+
span {
|
|
220
|
+
cursor: pointer;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
span:first-child {
|
|
224
|
+
position: absolute;
|
|
225
|
+
bottom: 50%;
|
|
226
|
+
right: 0px;
|
|
227
|
+
transform: translateY(50%);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
span:first-child:before {
|
|
231
|
+
content: '•';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
span:first-child:hover:before {
|
|
235
|
+
content: '➖';
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
span:last-child {
|
|
239
|
+
position: absolute;
|
|
240
|
+
bottom: -10px;
|
|
241
|
+
right: 0px;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
span:last-child:before {
|
|
245
|
+
content: '•';
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
span:last-child:hover:before {
|
|
249
|
+
content: '➕';
|
|
250
|
+
}
|
|
251
|
+
`;
|
|
252
|
+
const TableBlockContainer = _styledComponents.default.div`
|
|
253
|
+
margin: 15px 0;
|
|
254
|
+
position: relative;
|
|
255
|
+
overflow: scroll;
|
|
256
|
+
padding: 15px;
|
|
257
|
+
`;
|
|
258
|
+
|
|
259
|
+
const TableEditorBlock = props => {
|
|
260
|
+
var _tableData$2;
|
|
261
|
+
|
|
262
|
+
const {
|
|
263
|
+
block,
|
|
264
|
+
blockProps,
|
|
265
|
+
contentState
|
|
266
|
+
} = props;
|
|
267
|
+
const {
|
|
268
|
+
onEditStart,
|
|
269
|
+
onEditFinish,
|
|
270
|
+
getMainEditorReadOnly
|
|
271
|
+
} = blockProps;
|
|
272
|
+
const entityKey = block.getEntityAt(0);
|
|
273
|
+
const entity = contentState.getEntity(entityKey);
|
|
274
|
+
const {
|
|
275
|
+
tableData: rawTableData,
|
|
276
|
+
tableStyles: _tableStyles
|
|
277
|
+
} = entity.getData();
|
|
278
|
+
const [tableData, setTableData] = (0, _react.useState)(convertTableDataFromRaw(rawTableData)); // deep clone `_tableStyles` to prevent updating the entity data directly
|
|
279
|
+
|
|
280
|
+
const [tableStyles, setTableStyles] = (0, _react.useState)(_.cloneDeep(_tableStyles));
|
|
281
|
+
const tableRef = (0, _react.useRef)(null); // `TableBlock` will render other inner/nested DraftJS Editors inside the main Editor.
|
|
282
|
+
// However, main Editor's `readOnly` needs to be mutually exclusive with nested Editors' `readOnly`.
|
|
283
|
+
// If the main Editor and nested Editor are editable (`readOnly={false}`) at the same time,
|
|
284
|
+
// there will be a DraftJS Edtior Selection bug.
|
|
285
|
+
|
|
286
|
+
const [cellEditorReadOnly, setCellEditorReadOnly] = (0, _react.useState)(!getMainEditorReadOnly()); // The user clicks the table for editing
|
|
287
|
+
|
|
288
|
+
const onTableClick = () => {
|
|
289
|
+
// call `onEditStart` function to tell the main DraftJS Editor
|
|
290
|
+
// that we are going to interact with the custom atomic block.
|
|
291
|
+
onEditStart(); // make nested DraftJS Editors editable
|
|
292
|
+
|
|
293
|
+
setCellEditorReadOnly(false);
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
(0, _react.useEffect)(() => {
|
|
297
|
+
// The user clicks other places except the table,
|
|
298
|
+
// so we think he/she doesn't want to edit the table anymore.
|
|
299
|
+
// Therefore, we call `onEditFinish` function to pass modified table data
|
|
300
|
+
// back to the main DraftJS Edtior.
|
|
301
|
+
function handleClickOutside(event) {
|
|
302
|
+
// `!cellEditorReadOnly` condition is needed.
|
|
303
|
+
// If there are two tables in the main Editor,
|
|
304
|
+
// this `handleClickOutside` will only handle the just updated one.
|
|
305
|
+
if (tableRef.current && !tableRef.current.contains(event.target) && !cellEditorReadOnly) {
|
|
306
|
+
// make inner DraftJS Editors NOT editable
|
|
307
|
+
setCellEditorReadOnly(true); // call `onEditFinish` function tell the main DraftJS Editor
|
|
308
|
+
// that we are finishing interacting with the custom atomic block.
|
|
309
|
+
|
|
310
|
+
onEditFinish({
|
|
311
|
+
entityKey,
|
|
312
|
+
entityData: {
|
|
313
|
+
tableData: convertTableDataToRaw(tableData),
|
|
314
|
+
tableStyles
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
console.debug('(rich-text-editor/table): add click outside event listener');
|
|
321
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
322
|
+
return () => {
|
|
323
|
+
// Unbind the event listener on clean up
|
|
324
|
+
console.debug('(rich-text-editor/table): remove click outside event listener');
|
|
325
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
326
|
+
};
|
|
327
|
+
}, // Skip running effect if `tableData` and `cellEditorReadOnly` are not changed.
|
|
328
|
+
[tableData, cellEditorReadOnly]);
|
|
329
|
+
return /*#__PURE__*/_react.default.createElement(TableBlockContainer, null, /*#__PURE__*/_react.default.createElement(Table, {
|
|
330
|
+
key: entityKey,
|
|
331
|
+
onClick: onTableClick,
|
|
332
|
+
ref: tableRef
|
|
333
|
+
}, /*#__PURE__*/_react.default.createElement(StyledFirstRow, null, /*#__PURE__*/_react.default.createElement("div", null), tableData === null || tableData === void 0 ? void 0 : (_tableData$2 = tableData[0]) === null || _tableData$2 === void 0 ? void 0 : _tableData$2.map((colData, cIndex) => {
|
|
334
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
335
|
+
key: `col_${cIndex + 1}`
|
|
336
|
+
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
337
|
+
onClick: () => {
|
|
338
|
+
const deleteColumn = {
|
|
339
|
+
type: ActionType.Delete,
|
|
340
|
+
target: TableEnum.Column,
|
|
341
|
+
index: cIndex
|
|
342
|
+
};
|
|
343
|
+
const updatedTableData = resolveTableData(deleteColumn, tableData);
|
|
344
|
+
setTableData(updatedTableData);
|
|
345
|
+
}
|
|
346
|
+
}), /*#__PURE__*/_react.default.createElement("span", {
|
|
347
|
+
onClick: () => {
|
|
348
|
+
const insertColumn = {
|
|
349
|
+
type: ActionType.Insert,
|
|
350
|
+
target: TableEnum.Column,
|
|
351
|
+
index: cIndex + 1
|
|
352
|
+
};
|
|
353
|
+
const updatedTableData = resolveTableData(insertColumn, tableData);
|
|
354
|
+
setTableData(updatedTableData);
|
|
355
|
+
}
|
|
356
|
+
}));
|
|
357
|
+
})), tableData.map((rowData, rIndex) => {
|
|
358
|
+
var _tableStyles$rows;
|
|
359
|
+
|
|
360
|
+
const colsJsx = rowData.map((colData, cIndex) => {
|
|
361
|
+
return /*#__PURE__*/_react.default.createElement(Td, {
|
|
362
|
+
key: `col_${cIndex}`
|
|
363
|
+
}, /*#__PURE__*/_react.default.createElement(_draftJs.Editor, {
|
|
364
|
+
onChange: editorState => {
|
|
365
|
+
const updateAction = {
|
|
366
|
+
type: ActionType.Update,
|
|
367
|
+
cIndex,
|
|
368
|
+
rIndex,
|
|
369
|
+
value: editorState
|
|
370
|
+
};
|
|
371
|
+
const updatedTableData = resolveTableData(updateAction, tableData);
|
|
372
|
+
setTableData(updatedTableData);
|
|
373
|
+
},
|
|
374
|
+
editorState: colData,
|
|
375
|
+
readOnly: cellEditorReadOnly
|
|
376
|
+
}));
|
|
377
|
+
});
|
|
378
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, {
|
|
379
|
+
key: `row_${rIndex}`
|
|
380
|
+
}, /*#__PURE__*/_react.default.createElement(Tr, {
|
|
381
|
+
style: tableStyles === null || tableStyles === void 0 ? void 0 : (_tableStyles$rows = tableStyles.rows) === null || _tableStyles$rows === void 0 ? void 0 : _tableStyles$rows[rIndex]
|
|
382
|
+
}, /*#__PURE__*/_react.default.createElement(StyledFirstColumn, null, /*#__PURE__*/_react.default.createElement("span", {
|
|
383
|
+
onClick: () => {
|
|
384
|
+
const deleteRowAction = {
|
|
385
|
+
type: ActionType.Delete,
|
|
386
|
+
target: TableEnum.Row,
|
|
387
|
+
index: rIndex
|
|
388
|
+
};
|
|
389
|
+
const updatedTableData = resolveTableData(deleteRowAction, tableData);
|
|
390
|
+
setTableData(updatedTableData);
|
|
391
|
+
setTableStyles(resolveTableStyles(deleteRowAction, tableStyles));
|
|
392
|
+
}
|
|
393
|
+
}), /*#__PURE__*/_react.default.createElement("span", {
|
|
394
|
+
onClick: () => {
|
|
395
|
+
const addRowAction = {
|
|
396
|
+
type: ActionType.Insert,
|
|
397
|
+
target: TableEnum.Row,
|
|
398
|
+
index: rIndex + 1
|
|
399
|
+
};
|
|
400
|
+
const updatedTableData = resolveTableData(addRowAction, tableData);
|
|
401
|
+
setTableData(updatedTableData);
|
|
402
|
+
setTableStyles(resolveTableStyles(addRowAction, tableStyles));
|
|
403
|
+
}
|
|
404
|
+
})), colsJsx));
|
|
405
|
+
})));
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
exports.TableEditorBlock = TableEditorBlock;
|