react-contenteditable 3.3.1 → 3.3.5
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +21 -0
- package/lib/react-contenteditable.d.ts +11 -10
- package/lib/react-contenteditable.js +24 -21
- package/package.json +6 -6
package/README.md
CHANGED
@@ -4,6 +4,10 @@ react-contenteditable
|
|
4
4
|
React component for a div with editable contents
|
5
5
|
|
6
6
|
[![Build Status](https://travis-ci.org/lovasoa/react-contenteditable.svg?branch=master)](https://travis-ci.org/lovasoa/react-contenteditable)
|
7
|
+
[![download count](https://img.shields.io/npm/dm/react-contenteditable.svg)](https://www.npmjs.com/package/react-contenteditable)
|
8
|
+
[![bundle size](https://img.shields.io/bundlephobia/minzip/react-contenteditable.svg)](https://www.npmjs.com/package/react-contenteditable)
|
9
|
+
[![license](https://img.shields.io/github/license/lovasoa/react-contenteditable.svg)](https://github.com/lovasoa/react-contenteditable/blob/master/LICENSE)
|
10
|
+
|
7
11
|
|
8
12
|
## Install
|
9
13
|
|
@@ -48,11 +52,28 @@ class MyComponent extends React.Component {
|
|
48
52
|
|disabled|use true to disable editing|Boolean|
|
49
53
|
|onChange|called whenever `innerHTML` changes|Function|
|
50
54
|
|onBlur|called whenever the html element is [blurred](https://developer.mozilla.org/en-US/docs/Web/Events/blur)|Function|
|
55
|
+
|onFocus|event fires when an element has received [focus](https://developer.mozilla.org/en-US/docs/Web/API/Element/focus_event)|Function|
|
51
56
|
|onKeyUp|called whenever a key is released|Function|
|
52
57
|
|onKeyDown|called whenever a key is pressed |Function|
|
53
58
|
|className|the element's [CSS class](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class)|String|
|
54
59
|
|style|a collection of CSS properties to apply to the element|Object|
|
55
60
|
|
61
|
+
## Known Issues
|
62
|
+
If you are using hooks, please see [this issue](https://github.com/lovasoa/react-contenteditable/issues/161). Using this component with [`useState`](https://reactjs.org/docs/hooks-reference.html#usestate) doesn't work, but you can still use [`useRef`](https://reactjs.org/docs/hooks-reference.html#useref) :
|
63
|
+
|
64
|
+
```js
|
65
|
+
const text = useRef('');
|
66
|
+
|
67
|
+
const handleChange = evt => {
|
68
|
+
text.current = evt.target.value;
|
69
|
+
};
|
70
|
+
|
71
|
+
const handleBlur = () => {
|
72
|
+
console.log(text.current);
|
73
|
+
};
|
74
|
+
|
75
|
+
return <ContentEditable html={text.current} onBlur={handleBlur} onChange={handleChange} />
|
76
|
+
```
|
56
77
|
|
57
78
|
## Examples
|
58
79
|
|
@@ -25,22 +25,21 @@ export default class ContentEditable extends React.Component<Props> {
|
|
25
25
|
slot?: string | undefined;
|
26
26
|
title?: string | undefined;
|
27
27
|
color?: string | undefined;
|
28
|
-
key?: string | number | undefined;
|
29
28
|
children?: React.ReactNode;
|
29
|
+
key?: string | number | undefined;
|
30
30
|
defaultChecked?: boolean | undefined;
|
31
|
-
defaultValue?: string | string[] | undefined;
|
31
|
+
defaultValue?: string | number | readonly string[] | undefined;
|
32
32
|
suppressContentEditableWarning?: boolean | undefined;
|
33
33
|
suppressHydrationWarning?: boolean | undefined;
|
34
34
|
accessKey?: string | undefined;
|
35
35
|
contextMenu?: string | undefined;
|
36
|
-
draggable?: boolean | undefined;
|
36
|
+
draggable?: boolean | "false" | "true" | undefined;
|
37
37
|
id?: string | undefined;
|
38
38
|
lang?: string | undefined;
|
39
39
|
placeholder?: string | undefined;
|
40
|
-
spellCheck?: boolean | undefined;
|
40
|
+
spellCheck?: boolean | "false" | "true" | undefined;
|
41
41
|
tabIndex?: number | undefined;
|
42
|
-
|
43
|
-
is?: string | undefined;
|
42
|
+
translate?: "yes" | "no" | undefined;
|
44
43
|
radioGroup?: string | undefined;
|
45
44
|
role?: string | undefined;
|
46
45
|
about?: string | undefined;
|
@@ -62,9 +61,11 @@ export default class ContentEditable extends React.Component<Props> {
|
|
62
61
|
results?: number | undefined;
|
63
62
|
security?: string | undefined;
|
64
63
|
unselectable?: "on" | "off" | undefined;
|
64
|
+
inputMode?: "search" | "none" | "text" | "numeric" | "tel" | "url" | "email" | "decimal" | undefined;
|
65
|
+
is?: string | undefined;
|
65
66
|
'aria-activedescendant'?: string | undefined;
|
66
67
|
'aria-atomic'?: boolean | "false" | "true" | undefined;
|
67
|
-
'aria-autocomplete'?: "
|
68
|
+
'aria-autocomplete'?: "both" | "none" | "inline" | "list" | undefined;
|
68
69
|
'aria-busy'?: boolean | "false" | "true" | undefined;
|
69
70
|
'aria-checked'?: boolean | "mixed" | "false" | "true" | undefined;
|
70
71
|
'aria-colcount'?: number | undefined;
|
@@ -253,8 +254,8 @@ export default class ContentEditable extends React.Component<Props> {
|
|
253
254
|
onGotPointerCaptureCapture?: ((event: React.PointerEvent<HTMLDivElement>) => void) | undefined;
|
254
255
|
onLostPointerCapture?: ((event: React.PointerEvent<HTMLDivElement>) => void) | undefined;
|
255
256
|
onLostPointerCaptureCapture?: ((event: React.PointerEvent<HTMLDivElement>) => void) | undefined;
|
256
|
-
onScroll?: ((event: React.UIEvent<HTMLDivElement>) => void) | undefined;
|
257
|
-
onScrollCapture?: ((event: React.UIEvent<HTMLDivElement>) => void) | undefined;
|
257
|
+
onScroll?: ((event: React.UIEvent<HTMLDivElement, UIEvent>) => void) | undefined;
|
258
|
+
onScrollCapture?: ((event: React.UIEvent<HTMLDivElement, UIEvent>) => void) | undefined;
|
258
259
|
onWheel?: ((event: React.WheelEvent<HTMLDivElement>) => void) | undefined;
|
259
260
|
onWheelCapture?: ((event: React.WheelEvent<HTMLDivElement>) => void) | undefined;
|
260
261
|
onAnimationStart?: ((event: React.AnimationEvent<HTMLDivElement>) => void) | undefined;
|
@@ -269,7 +270,7 @@ export default class ContentEditable extends React.Component<Props> {
|
|
269
270
|
}, string | ((props: any) => React.ReactElement<any, string | any | (new (props: any) => React.Component<any, any, any>)> | null) | (new (props: any) => React.Component<any, any, any>)>;
|
270
271
|
shouldComponentUpdate(nextProps: Props): boolean;
|
271
272
|
componentDidUpdate(): void;
|
272
|
-
emitChange: (originalEvt: React.SyntheticEvent<any
|
273
|
+
emitChange: (originalEvt: React.SyntheticEvent<any>) => void;
|
273
274
|
static propTypes: {
|
274
275
|
html: PropTypes.Validator<string>;
|
275
276
|
onChange: PropTypes.Requireable<(...args: any[]) => any>;
|
@@ -23,6 +23,25 @@ var __assign = (this && this.__assign) || function () {
|
|
23
23
|
};
|
24
24
|
return __assign.apply(this, arguments);
|
25
25
|
};
|
26
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
27
|
+
if (k2 === undefined) k2 = k;
|
28
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
29
|
+
}) : (function(o, m, k, k2) {
|
30
|
+
if (k2 === undefined) k2 = k;
|
31
|
+
o[k2] = m[k];
|
32
|
+
}));
|
33
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
34
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
35
|
+
}) : function(o, v) {
|
36
|
+
o["default"] = v;
|
37
|
+
});
|
38
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
39
|
+
if (mod && mod.__esModule) return mod;
|
40
|
+
var result = {};
|
41
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
42
|
+
__setModuleDefault(result, mod);
|
43
|
+
return result;
|
44
|
+
};
|
26
45
|
var __rest = (this && this.__rest) || function (s, e) {
|
27
46
|
var t = {};
|
28
47
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
@@ -34,13 +53,6 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
34
53
|
}
|
35
54
|
return t;
|
36
55
|
};
|
37
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
38
|
-
if (mod && mod.__esModule) return mod;
|
39
|
-
var result = {};
|
40
|
-
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
41
|
-
result["default"] = mod;
|
42
|
-
return result;
|
43
|
-
};
|
44
56
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
45
57
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
46
58
|
};
|
@@ -51,20 +63,10 @@ var PropTypes = __importStar(require("prop-types"));
|
|
51
63
|
function normalizeHtml(str) {
|
52
64
|
return str && str.replace(/ |\u202F|\u00A0/g, ' ');
|
53
65
|
}
|
54
|
-
function findLastTextNode(node) {
|
55
|
-
if (node.nodeType === Node.TEXT_NODE)
|
56
|
-
return node;
|
57
|
-
var children = node.childNodes;
|
58
|
-
for (var i = children.length - 1; i >= 0; i--) {
|
59
|
-
var textNode = findLastTextNode(children[i]);
|
60
|
-
if (textNode !== null)
|
61
|
-
return textNode;
|
62
|
-
}
|
63
|
-
return null;
|
64
|
-
}
|
65
66
|
function replaceCaret(el) {
|
66
67
|
// Place the caret at the end of the element
|
67
|
-
var target =
|
68
|
+
var target = document.createTextNode('');
|
69
|
+
el.appendChild(target);
|
68
70
|
// do not move caret if element was not focused
|
69
71
|
var isTargetFocused = document.activeElement === el;
|
70
72
|
if (target !== null && target.nodeValue !== null && isTargetFocused) {
|
@@ -112,7 +114,7 @@ var ContentEditable = /** @class */ (function (_super) {
|
|
112
114
|
ContentEditable.prototype.render = function () {
|
113
115
|
var _this = this;
|
114
116
|
var _a = this.props, tagName = _a.tagName, html = _a.html, innerRef = _a.innerRef, props = __rest(_a, ["tagName", "html", "innerRef"]);
|
115
|
-
return React.createElement(tagName || 'div', __assign({}, props, { ref: typeof innerRef === 'function' ? function (current) {
|
117
|
+
return React.createElement(tagName || 'div', __assign(__assign({}, props), { ref: typeof innerRef === 'function' ? function (current) {
|
116
118
|
innerRef(current);
|
117
119
|
_this.el.current = current;
|
118
120
|
} : innerRef || this.el, onInput: this.emitChange, onBlur: this.props.onBlur || this.emitChange, onKeyUp: this.props.onKeyUp || this.emitChange, onKeyDown: this.props.onKeyDown || this.emitChange, contentEditable: !this.props.disabled, dangerouslySetInnerHTML: { __html: html } }), this.props.children);
|
@@ -143,8 +145,9 @@ var ContentEditable = /** @class */ (function (_super) {
|
|
143
145
|
// Perhaps React (whose VDOM gets outdated because we often prevent
|
144
146
|
// rerendering) did not update the DOM. So we update it manually now.
|
145
147
|
if (this.props.html !== el.innerHTML) {
|
146
|
-
el.innerHTML = this.
|
148
|
+
el.innerHTML = this.props.html;
|
147
149
|
}
|
150
|
+
this.lastHtml = this.props.html;
|
148
151
|
replaceCaret(el);
|
149
152
|
};
|
150
153
|
ContentEditable.propTypes = {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "react-contenteditable",
|
3
|
-
"version": "3.3.
|
3
|
+
"version": "3.3.5",
|
4
4
|
"description": "React component representing an element with editable contents",
|
5
5
|
"main": "./lib/react-contenteditable.js",
|
6
6
|
"types": "./lib/react-contenteditable.d.ts",
|
@@ -8,7 +8,7 @@
|
|
8
8
|
"react": ">=16.3"
|
9
9
|
},
|
10
10
|
"author": "Ophir LOJKINE (original code posted by Sebastien Lorber on stackoverflow)",
|
11
|
-
"license": "
|
11
|
+
"license": "Apache-2.0",
|
12
12
|
"keywords": [
|
13
13
|
"react-component",
|
14
14
|
"contenteditable",
|
@@ -21,9 +21,9 @@
|
|
21
21
|
"url": "https://github.com/lovasoa/react-contenteditable.git"
|
22
22
|
},
|
23
23
|
"devDependencies": {
|
24
|
-
"@types/react": "^16.
|
25
|
-
"react": "^16.
|
26
|
-
"typescript": "^3.5
|
24
|
+
"@types/react": "^16.9.37",
|
25
|
+
"react": "^16.13.1",
|
26
|
+
"typescript": "^3.9.5"
|
27
27
|
},
|
28
28
|
"scripts": {
|
29
29
|
"compile": "tsc",
|
@@ -31,7 +31,7 @@
|
|
31
31
|
"prepare": "npm run compile"
|
32
32
|
},
|
33
33
|
"dependencies": {
|
34
|
-
"
|
34
|
+
"prop-types": "^15.7.1",
|
35
35
|
"fast-deep-equal": "^2.0.1"
|
36
36
|
}
|
37
37
|
}
|