@pie-lib/editable-html 9.1.2 → 9.1.3
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 +11 -0
- package/lib/editor.js +19 -2
- package/lib/editor.js.map +1 -1
- package/lib/plugins/characters/{custom-popover.js → custom-popper.js} +9 -6
- package/lib/plugins/characters/custom-popper.js.map +1 -0
- package/lib/plugins/characters/index.js +61 -42
- package/lib/plugins/characters/index.js.map +1 -1
- package/lib/plugins/characters/utils.js +1 -2
- package/lib/plugins/characters/utils.js.map +1 -1
- package/lib/plugins/toolbar/default-toolbar.js +5 -2
- package/lib/plugins/toolbar/default-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/editor-and-toolbar.js +3 -0
- package/lib/plugins/toolbar/editor-and-toolbar.js.map +1 -1
- package/lib/plugins/toolbar/toolbar.js +10 -0
- package/lib/plugins/toolbar/toolbar.js.map +1 -1
- package/package.json +5 -5
- package/src/editor.jsx +20 -3
- package/src/plugins/characters/{custom-popover.js → custom-popper.js} +8 -5
- package/src/plugins/characters/index.jsx +68 -44
- package/src/plugins/characters/utils.js +1 -2
- package/src/plugins/toolbar/default-toolbar.jsx +12 -2
- package/src/plugins/toolbar/editor-and-toolbar.jsx +3 -0
- package/src/plugins/toolbar/toolbar.jsx +8 -0
- package/lib/plugins/characters/custom-popover.js.map +0 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { withStyles } from '@material-ui/core/styles';
|
|
3
|
-
import
|
|
3
|
+
import Popper from '@material-ui/core/Popper';
|
|
4
4
|
import Typography from '@material-ui/core/Typography';
|
|
5
5
|
|
|
6
6
|
const styles = () => ({
|
|
7
7
|
popover: {
|
|
8
|
+
background: '#fff',
|
|
9
|
+
padding: '10px',
|
|
8
10
|
pointerEvents: 'none',
|
|
9
11
|
zIndex: 99999
|
|
10
12
|
},
|
|
@@ -19,8 +21,8 @@ const styles = () => ({
|
|
|
19
21
|
}
|
|
20
22
|
});
|
|
21
23
|
|
|
22
|
-
const
|
|
23
|
-
<
|
|
24
|
+
const CustomPopper = withStyles(styles)(({ classes, children, ...props }) => (
|
|
25
|
+
<Popper
|
|
24
26
|
id="mouse-over-popover"
|
|
25
27
|
open
|
|
26
28
|
className={classes.popover}
|
|
@@ -36,10 +38,11 @@ const CustomPopOver = withStyles(styles)(({ classes, children, ...props }) => (
|
|
|
36
38
|
horizontal: 'left'
|
|
37
39
|
}}
|
|
38
40
|
disableRestoreFocus
|
|
41
|
+
disableAutoFocus
|
|
39
42
|
{...props}
|
|
40
43
|
>
|
|
41
44
|
<Typography classes={{ root: classes.typography }}>{children}</Typography>
|
|
42
|
-
</
|
|
45
|
+
</Popper>
|
|
43
46
|
));
|
|
44
47
|
|
|
45
|
-
export default
|
|
48
|
+
export default CustomPopper;
|
|
@@ -5,18 +5,11 @@ import get from 'lodash/get';
|
|
|
5
5
|
|
|
6
6
|
import { PureToolbar } from '@pie-lib/math-toolbar';
|
|
7
7
|
|
|
8
|
-
import
|
|
8
|
+
import CustomPopper from './custom-popper';
|
|
9
9
|
import { insertSnackBar } from '../respArea/utils';
|
|
10
10
|
import { characterIcons, spanishConfig, specialConfig } from './utils';
|
|
11
11
|
const log = debug('@pie-lib:editable-html:plugins:characters');
|
|
12
12
|
|
|
13
|
-
const removeDialogs = () => {
|
|
14
|
-
const prevDialogs = document.querySelectorAll('.insert-character-dialog');
|
|
15
|
-
|
|
16
|
-
log('[characters:removeDialogs]');
|
|
17
|
-
prevDialogs.forEach(s => s.remove());
|
|
18
|
-
};
|
|
19
|
-
|
|
20
13
|
const removePopOvers = () => {
|
|
21
14
|
const prevPopOvers = document.querySelectorAll('#mouse-over-popover');
|
|
22
15
|
|
|
@@ -24,16 +17,22 @@ const removePopOvers = () => {
|
|
|
24
17
|
prevPopOvers.forEach(s => s.remove());
|
|
25
18
|
};
|
|
26
19
|
|
|
27
|
-
const
|
|
20
|
+
export const removeDialogs = () => {
|
|
21
|
+
const prevDialogs = document.querySelectorAll('.insert-character-dialog');
|
|
22
|
+
|
|
23
|
+
log('[characters:removeDialogs]');
|
|
24
|
+
prevDialogs.forEach(s => s.remove());
|
|
25
|
+
removePopOvers();
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const insertDialog = ({ editorDOM, value, callback, opts }) => {
|
|
28
29
|
const newEl = document.createElement('div');
|
|
29
|
-
const initialBodyOverflow = document.body.style.overflow;
|
|
30
30
|
|
|
31
31
|
log('[characters:insertDialog]');
|
|
32
32
|
|
|
33
33
|
removeDialogs();
|
|
34
34
|
|
|
35
35
|
newEl.className = 'insert-character-dialog';
|
|
36
|
-
document.body.style.overflow = 'hidden';
|
|
37
36
|
|
|
38
37
|
let configToUse;
|
|
39
38
|
|
|
@@ -85,33 +84,48 @@ const insertDialog = ({ value, callback, opts }) => {
|
|
|
85
84
|
|
|
86
85
|
popoverEl = document.createElement('div');
|
|
87
86
|
ReactDOM.render(
|
|
88
|
-
<
|
|
87
|
+
<CustomPopper onClose={closePopOver} anchorEl={event.currentTarget}>
|
|
89
88
|
<div>{el.label}</div>
|
|
90
89
|
|
|
91
90
|
<div style={infoStyle}>{el.description}</div>
|
|
92
91
|
|
|
93
92
|
<div style={infoStyle}>{el.unicode}</div>
|
|
94
|
-
</
|
|
93
|
+
</CustomPopper>,
|
|
95
94
|
popoverEl
|
|
96
95
|
);
|
|
97
96
|
|
|
98
97
|
document.body.appendChild(newEl);
|
|
99
98
|
};
|
|
100
99
|
|
|
100
|
+
let firstCallMade = false;
|
|
101
|
+
|
|
102
|
+
const listener = e => {
|
|
103
|
+
// this will be triggered right after setting it because
|
|
104
|
+
// this toolbar is added on the mousedown event
|
|
105
|
+
// so right after mouseup, the click will be triggered
|
|
106
|
+
if (firstCallMade) {
|
|
107
|
+
const focusIsInModals =
|
|
108
|
+
newEl.contains(e.target) || (popoverEl && popoverEl.contains(e.target));
|
|
109
|
+
const focusIsInEditor = editorDOM.contains(e.target);
|
|
110
|
+
|
|
111
|
+
if (!(focusIsInModals || focusIsInEditor)) {
|
|
112
|
+
handleClose();
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
firstCallMade = true;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
101
119
|
const handleClose = () => {
|
|
120
|
+
callback(undefined, true);
|
|
102
121
|
newEl.remove();
|
|
103
122
|
closePopOver();
|
|
104
|
-
document.body.
|
|
105
|
-
callback(undefined, true);
|
|
123
|
+
document.body.removeEventListener('click', listener);
|
|
106
124
|
};
|
|
107
125
|
|
|
108
126
|
const handleChange = val => {
|
|
109
127
|
if (typeof val === 'string') {
|
|
110
|
-
callback(val);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (configToUse.autoClose) {
|
|
114
|
-
handleClose();
|
|
128
|
+
callback(val, true);
|
|
115
129
|
}
|
|
116
130
|
};
|
|
117
131
|
|
|
@@ -158,31 +172,40 @@ const insertDialog = ({ value, callback, opts }) => {
|
|
|
158
172
|
const cursorItem = document.querySelector(`[data-key="${value.anchorKey}"]`);
|
|
159
173
|
|
|
160
174
|
if (cursorItem) {
|
|
175
|
+
const bodyRect = document.body.getBoundingClientRect();
|
|
161
176
|
const boundRect = cursorItem.getBoundingClientRect();
|
|
162
177
|
|
|
163
178
|
document.body.appendChild(newEl);
|
|
164
|
-
newEl.style.position = '
|
|
165
|
-
newEl.style.top = `${boundRect.top - newEl.offsetHeight - 10}px`;
|
|
166
|
-
newEl.style.left = `${boundRect.left + cursorItem.offsetWidth + 10}px`;
|
|
179
|
+
newEl.style.position = 'absolute';
|
|
180
|
+
newEl.style.top = `${boundRect.top + Math.abs(bodyRect.top) - newEl.offsetHeight - 10}px`;
|
|
167
181
|
newEl.style.zIndex = 99999;
|
|
168
182
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
const leftValue = `${boundRect.left +
|
|
184
|
+
Math.abs(bodyRect.left) +
|
|
185
|
+
cursorItem.offsetWidth +
|
|
186
|
+
10}px`;
|
|
187
|
+
|
|
188
|
+
const rightValue = `${boundRect.x}px`;
|
|
189
|
+
|
|
190
|
+
newEl.style.left = leftValue;
|
|
191
|
+
|
|
192
|
+
const leftAlignedWidth = newEl.offsetWidth;
|
|
193
|
+
|
|
194
|
+
newEl.style.left = 'unset';
|
|
195
|
+
newEl.style.right = rightValue;
|
|
196
|
+
|
|
197
|
+
const rightAlignedWidth = newEl.offsetWidth;
|
|
198
|
+
|
|
199
|
+
newEl.style.left = 'unset';
|
|
200
|
+
newEl.style.right = 'unset';
|
|
201
|
+
|
|
202
|
+
if (leftAlignedWidth >= rightAlignedWidth) {
|
|
203
|
+
newEl.style.left = leftValue;
|
|
204
|
+
} else {
|
|
205
|
+
newEl.style.right = rightValue;
|
|
185
206
|
}
|
|
207
|
+
|
|
208
|
+
document.body.addEventListener('click', listener);
|
|
186
209
|
}
|
|
187
210
|
});
|
|
188
211
|
};
|
|
@@ -201,12 +224,15 @@ const CharacterIcon = ({ letter }) => (
|
|
|
201
224
|
export default function CharactersPlugin(opts) {
|
|
202
225
|
removeDialogs();
|
|
203
226
|
return {
|
|
204
|
-
name: '
|
|
227
|
+
name: 'characters',
|
|
205
228
|
toolbar: {
|
|
206
229
|
icon: <CharacterIcon letter={opts.characterIcon || characterIcons[opts.language] || 'ñ'} />,
|
|
207
|
-
onClick: (value, onChange) => {
|
|
230
|
+
onClick: (value, onChange, getFocusedValue) => {
|
|
231
|
+
const editorDOM = document.querySelector(`[data-key="${value.document.key}"]`);
|
|
208
232
|
let valueToUse = value;
|
|
209
233
|
const callback = (char, focus) => {
|
|
234
|
+
valueToUse = getFocusedValue();
|
|
235
|
+
|
|
210
236
|
if (char) {
|
|
211
237
|
const change = valueToUse
|
|
212
238
|
.change()
|
|
@@ -220,15 +246,13 @@ export default function CharactersPlugin(opts) {
|
|
|
220
246
|
log('[characters:click]');
|
|
221
247
|
|
|
222
248
|
if (focus) {
|
|
223
|
-
const editorDOM = document.querySelector(`[data-key="${valueToUse.document.key}"]`);
|
|
224
|
-
|
|
225
249
|
if (editorDOM) {
|
|
226
250
|
editorDOM.focus();
|
|
227
251
|
}
|
|
228
252
|
}
|
|
229
253
|
};
|
|
230
254
|
|
|
231
|
-
insertDialog({ value: valueToUse, callback, opts });
|
|
255
|
+
insertDialog({ editorDOM, value: valueToUse, callback, opts });
|
|
232
256
|
}
|
|
233
257
|
},
|
|
234
258
|
|
|
@@ -40,7 +40,7 @@ export const ToolbarButton = props => {
|
|
|
40
40
|
<Button
|
|
41
41
|
active={isActive}
|
|
42
42
|
disabled={disabled}
|
|
43
|
-
onClick={() => props.onClick(props.value, props.onChange)}
|
|
43
|
+
onClick={() => props.onClick(props.value, props.onChange, props.getFocusedValue)}
|
|
44
44
|
extraStyles={props.buttonStyles}
|
|
45
45
|
>
|
|
46
46
|
{props.icon}
|
|
@@ -60,6 +60,7 @@ export const DefaultToolbar = ({
|
|
|
60
60
|
pluginProps,
|
|
61
61
|
value,
|
|
62
62
|
onChange,
|
|
63
|
+
getFocusedValue,
|
|
63
64
|
onDone,
|
|
64
65
|
classes,
|
|
65
66
|
showDone,
|
|
@@ -71,7 +72,15 @@ export const DefaultToolbar = ({
|
|
|
71
72
|
<div className={classes.defaultToolbar}>
|
|
72
73
|
<div className={classes.buttonsContainer}>
|
|
73
74
|
{filtered.map((p, index) => {
|
|
74
|
-
return
|
|
75
|
+
return (
|
|
76
|
+
<ToolbarButton
|
|
77
|
+
{...p}
|
|
78
|
+
key={index}
|
|
79
|
+
value={value}
|
|
80
|
+
onChange={onChange}
|
|
81
|
+
getFocusedValue={getFocusedValue}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
75
84
|
})}
|
|
76
85
|
</div>
|
|
77
86
|
{showDone && !deletable && <DoneButton onClick={onDone} />}
|
|
@@ -85,6 +94,7 @@ DefaultToolbar.propTypes = {
|
|
|
85
94
|
pluginProps: PropTypes.object,
|
|
86
95
|
value: SlatePropTypes.value.isRequired,
|
|
87
96
|
onChange: PropTypes.func.isRequired,
|
|
97
|
+
getFocusedValue: PropTypes.func.isRequired,
|
|
88
98
|
onDone: PropTypes.func.isRequired,
|
|
89
99
|
showDone: PropTypes.bool,
|
|
90
100
|
addArea: PropTypes.bool,
|
|
@@ -17,6 +17,7 @@ export class EditorAndToolbar extends React.Component {
|
|
|
17
17
|
value: SlatePropTypes.value.isRequired,
|
|
18
18
|
plugins: PropTypes.array.isRequired,
|
|
19
19
|
onChange: PropTypes.func.isRequired,
|
|
20
|
+
getFocusedValue: PropTypes.func.isRequired,
|
|
20
21
|
onDone: PropTypes.func.isRequired,
|
|
21
22
|
onDataChange: PropTypes.func,
|
|
22
23
|
toolbarRef: PropTypes.func,
|
|
@@ -49,6 +50,7 @@ export class EditorAndToolbar extends React.Component {
|
|
|
49
50
|
value,
|
|
50
51
|
plugins,
|
|
51
52
|
onChange,
|
|
53
|
+
getFocusedValue,
|
|
52
54
|
onDone,
|
|
53
55
|
focusedNode,
|
|
54
56
|
autoWidth,
|
|
@@ -113,6 +115,7 @@ export class EditorAndToolbar extends React.Component {
|
|
|
113
115
|
value={value}
|
|
114
116
|
isFocused={inFocus}
|
|
115
117
|
onChange={onChange}
|
|
118
|
+
getFocusedValue={getFocusedValue}
|
|
116
119
|
onDone={onDone}
|
|
117
120
|
onDataChange={onDataChange}
|
|
118
121
|
toolbarRef={toolbarRef}
|
|
@@ -13,6 +13,7 @@ import { DoneButton } from './done-button';
|
|
|
13
13
|
import { findSingleNode, findParentNode } from '../utils';
|
|
14
14
|
import { withStyles } from '@material-ui/core/styles';
|
|
15
15
|
import DefaultToolbar from './default-toolbar';
|
|
16
|
+
import { removeDialogs as removeCharacterDialogs } from '../characters';
|
|
16
17
|
|
|
17
18
|
const log = debug('@pie-lib:editable-html:plugins:toolbar');
|
|
18
19
|
|
|
@@ -50,6 +51,7 @@ export class Toolbar extends React.Component {
|
|
|
50
51
|
isFocused: PropTypes.bool,
|
|
51
52
|
autoWidth: PropTypes.bool,
|
|
52
53
|
onChange: PropTypes.func.isRequired,
|
|
54
|
+
getFocusedValue: PropTypes.func.isRequired,
|
|
53
55
|
pluginProps: PropTypes.object,
|
|
54
56
|
toolbarOpts: PropTypes.shape({
|
|
55
57
|
position: PropTypes.oneOf(['bottom', 'top']),
|
|
@@ -68,6 +70,10 @@ export class Toolbar extends React.Component {
|
|
|
68
70
|
};
|
|
69
71
|
}
|
|
70
72
|
|
|
73
|
+
componentWillUnmount() {
|
|
74
|
+
removeCharacterDialogs();
|
|
75
|
+
}
|
|
76
|
+
|
|
71
77
|
hasMark = type => {
|
|
72
78
|
const { value } = this.props;
|
|
73
79
|
return value.marks.some(mark => mark.type == type);
|
|
@@ -136,6 +142,7 @@ export class Toolbar extends React.Component {
|
|
|
136
142
|
value,
|
|
137
143
|
autoWidth,
|
|
138
144
|
onChange,
|
|
145
|
+
getFocusedValue,
|
|
139
146
|
isFocused,
|
|
140
147
|
onDone,
|
|
141
148
|
toolbarRef
|
|
@@ -248,6 +255,7 @@ export class Toolbar extends React.Component {
|
|
|
248
255
|
pluginProps={pluginProps}
|
|
249
256
|
value={value}
|
|
250
257
|
onChange={onChange}
|
|
258
|
+
getFocusedValue={getFocusedValue}
|
|
251
259
|
showDone={defaultToolbarShowDone}
|
|
252
260
|
onDone={handleDone}
|
|
253
261
|
deletable={deletable}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/plugins/characters/custom-popover.js"],"names":["styles","popover","pointerEvents","zIndex","paper","padding","height","width","typography","fontSize","textAlign","CustomPopOver","classes","children","props","vertical","horizontal","root"],"mappings":";;;;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;;;AAEA,IAAMA,MAAM,GAAG,SAATA,MAAS;AAAA,SAAO;AACpBC,IAAAA,OAAO,EAAE;AACPC,MAAAA,aAAa,EAAE,MADR;AAEPC,MAAAA,MAAM,EAAE;AAFD,KADW;AAKpBC,IAAAA,KAAK,EAAE;AACLC,MAAAA,OAAO,EAAE,EADJ;AAELC,MAAAA,MAAM,EAAE,MAFH;AAGLC,MAAAA,KAAK,EAAE;AAHF,KALa;AAUpBC,IAAAA,UAAU,EAAE;AACVC,MAAAA,QAAQ,EAAE,EADA;AAEVC,MAAAA,SAAS,EAAE;AAFD;AAVQ,GAAP;AAAA,CAAf;;AAgBA,IAAMC,aAAa,GAAG,wBAAWX,MAAX,EAAmB;AAAA,MAAGY,OAAH,QAAGA,OAAH;AAAA,MAAYC,QAAZ,QAAYA,QAAZ;AAAA,MAAyBC,KAAzB;AAAA,sBACvC,gCAAC,mBAAD;AACE,IAAA,EAAE,EAAC,oBADL;AAEE,IAAA,IAAI,MAFN;AAGE,IAAA,SAAS,EAAEF,OAAO,CAACX,OAHrB;AAIE,IAAA,OAAO,EAAE;AACPG,MAAAA,KAAK,EAAEQ,OAAO,CAACR;AADR,KAJX;AAOE,IAAA,YAAY,EAAE;AACZW,MAAAA,QAAQ,EAAE,QADE;AAEZC,MAAAA,UAAU,EAAE;AAFA,KAPhB;AAWE,IAAA,eAAe,EAAE;AACfD,MAAAA,QAAQ,EAAE,KADK;AAEfC,MAAAA,UAAU,EAAE;AAFG,KAXnB;AAeE,IAAA,mBAAmB;AAfrB,KAgBMF,KAhBN,gBAkBE,gCAAC,sBAAD;AAAY,IAAA,OAAO,EAAE;AAAEG,MAAAA,IAAI,EAAEL,OAAO,CAACJ;AAAhB;AAArB,KAAoDK,QAApD,CAlBF,CADuC;AAAA,CAAnB,CAAtB;eAuBeF,a","sourcesContent":["import React from 'react';\nimport { withStyles } from '@material-ui/core/styles';\nimport Popover from '@material-ui/core/Popover';\nimport Typography from '@material-ui/core/Typography';\n\nconst styles = () => ({\n popover: {\n pointerEvents: 'none',\n zIndex: 99999\n },\n paper: {\n padding: 20,\n height: 'auto',\n width: 'auto'\n },\n typography: {\n fontSize: 50,\n textAlign: 'center'\n }\n});\n\nconst CustomPopOver = withStyles(styles)(({ classes, children, ...props }) => (\n <Popover\n id=\"mouse-over-popover\"\n open\n className={classes.popover}\n classes={{\n paper: classes.paper\n }}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'left'\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'left'\n }}\n disableRestoreFocus\n {...props}\n >\n <Typography classes={{ root: classes.typography }}>{children}</Typography>\n </Popover>\n));\n\nexport default CustomPopOver;\n"],"file":"custom-popover.js"}
|