react-show-more-text 1.6.2 → 1.7.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 -3
- package/lib/ShowMoreText.js +77 -103
- package/lib/Truncate.js +197 -202
- package/package.json +2 -3
- package/lib/ShowMoreText.css +0 -8
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# React Show More Text 1.
|
|
1
|
+
# React Show More Text 1.7.0
|
|
2
2
|
|
|
3
3
|
[![NPM version][npm-image]][npm-url]
|
|
4
4
|
[![Downloads][downloads-image]][npm-url]
|
|
5
5
|
[![Build status][travis-image]][travis-url]
|
|
6
6
|
|
|
7
|
-
The text surrounded by the component will be truncated. Anything surrounded by the component could be evaluated as text. The component react-show-more-text/ShowMoreText is fork of react-show-more/ShowMore, applied improvements, works with React 16.x.x, React 18.x.x
|
|
7
|
+
The text surrounded by the component will be truncated. Anything surrounded by the component could be evaluated as text. The component react-show-more-text/ShowMoreText is fork of react-show-more/ShowMore, applied improvements, added onClick event, works with React 16.x.x, React 18.x.x, Next.Js 13.3.x and upper.
|
|
8
8
|
|
|
9
9
|
## Demo
|
|
10
10
|
|
|
@@ -83,7 +83,7 @@ class Foo extends Component {
|
|
|
83
83
|
| more | string, React node | 'Show more' | The text to display in the anchor element to show more. | `'Show more'`, `<span>Show more</span>` |
|
|
84
84
|
| less | string, React node | 'Show less' | The text to display in the anchor element to show less. | `'Show less'`, `<span>Show less</span>` |
|
|
85
85
|
| className | string | '' | Class name(s) to add on component content wrapper div. | `'wrapper-class'`, `'wrapper-class-1 wrapper-class-2'` |
|
|
86
|
-
| anchorClass | string | '' | Class name(s) to add to the anchor elements. | `'my-anchor-class'`, `'class-1 class-2'` |
|
|
86
|
+
| anchorClass | string | 'show-more-less-clickable' | Class name(s) to add to the anchor elements. Should be the name of a css class defined globally by you. | `'my-anchor-class'`, `'class-1 class-2'` |
|
|
87
87
|
| onClick | Function | | Function executed on click on 'Show more' or 'Show less' | `onClick={this.executeOnClick}` |
|
|
88
88
|
| expanded | boolean | 'false' | Control the text to be shown as expanded | `expanded={true}` |
|
|
89
89
|
| expandByClick | boolean | 'true' | Cancel the default anchor click expand behavior | `expandByClick={false}` |
|
package/lib/ShowMoreText.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
4
3
|
Object.defineProperty(exports, "__esModule", {
|
|
5
4
|
value: true
|
|
6
5
|
});
|
|
@@ -8,141 +7,116 @@ exports.default = void 0;
|
|
|
8
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
8
|
var _propTypes = require("prop-types");
|
|
10
9
|
var _Truncate = _interopRequireDefault(require("./Truncate"));
|
|
11
|
-
require("./ShowMoreText.css");
|
|
12
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function
|
|
14
|
-
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null ||
|
|
15
|
-
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
16
|
-
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
17
|
-
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
18
|
-
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
19
|
-
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
20
|
-
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
21
|
-
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
|
22
|
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
23
|
-
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
24
|
-
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
11
|
+
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); }
|
|
12
|
+
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; }
|
|
25
13
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
_defineProperty(_assertThisInitialized(_this), "handleTruncate", function (truncated) {
|
|
35
|
-
if (_this._isMounted && truncated !== _this.state.truncated) {
|
|
36
|
-
_this.setState({
|
|
37
|
-
truncated: truncated
|
|
14
|
+
class ShowMoreText extends _react.Component {
|
|
15
|
+
constructor(props) {
|
|
16
|
+
super(props);
|
|
17
|
+
_defineProperty(this, "_isMounted", false);
|
|
18
|
+
_defineProperty(this, "handleTruncate", truncated => {
|
|
19
|
+
if (this._isMounted && truncated !== this.state.truncated) {
|
|
20
|
+
this.setState({
|
|
21
|
+
truncated
|
|
38
22
|
});
|
|
39
23
|
if (truncated) {
|
|
40
|
-
|
|
24
|
+
this.truncateRef.onResize();
|
|
41
25
|
}
|
|
42
|
-
|
|
26
|
+
this.props.onTruncate && this.props.onTruncate();
|
|
43
27
|
}
|
|
44
28
|
});
|
|
45
|
-
_defineProperty(
|
|
29
|
+
_defineProperty(this, "toggleLines", event => {
|
|
46
30
|
event.preventDefault();
|
|
47
|
-
var _self =
|
|
31
|
+
var _self = this;
|
|
48
32
|
if (!_self.props.expandByClick) {
|
|
49
33
|
if (_self.props.onClick) {
|
|
50
34
|
_self.props.onClick(_self.state.expanded, event);
|
|
51
35
|
}
|
|
52
36
|
return;
|
|
53
37
|
}
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
expanded: !
|
|
57
|
-
},
|
|
38
|
+
if (this._isMounted) {
|
|
39
|
+
this.setState({
|
|
40
|
+
expanded: !this.state.expanded
|
|
41
|
+
}, () => {
|
|
58
42
|
if (_self.props.onClick) {
|
|
59
43
|
_self.props.onClick(_self.state.expanded, event);
|
|
60
44
|
}
|
|
61
45
|
});
|
|
62
46
|
}
|
|
63
47
|
});
|
|
64
|
-
|
|
48
|
+
this.state = {
|
|
65
49
|
expanded: false,
|
|
66
50
|
truncated: false
|
|
67
51
|
};
|
|
68
|
-
return _this;
|
|
69
52
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
expanded: _self.props.expanded
|
|
78
|
-
});
|
|
79
|
-
}
|
|
53
|
+
componentDidMount() {
|
|
54
|
+
this._isMounted = true;
|
|
55
|
+
var _self = this;
|
|
56
|
+
if (this._isMounted) {
|
|
57
|
+
this.setState({
|
|
58
|
+
expanded: _self.props.expanded
|
|
59
|
+
});
|
|
80
60
|
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
lines: !expanded && lines,
|
|
109
|
-
ellipsis: /*#__PURE__*/_react.default.createElement("span", null, truncatedEndingComponent, /*#__PURE__*/_react.default.createElement("span", {
|
|
110
|
-
className: anchorClass,
|
|
111
|
-
onClick: this.toggleLines
|
|
112
|
-
}, more)),
|
|
113
|
-
onTruncate: this.handleTruncate,
|
|
114
|
-
ref: function ref(_ref) {
|
|
115
|
-
return _this2.truncateRef = _ref;
|
|
116
|
-
}
|
|
117
|
-
}, keepNewLines ? children.split('\n').map(function (line, i, arr) {
|
|
118
|
-
line = /*#__PURE__*/_react.default.createElement("span", {
|
|
119
|
-
key: i
|
|
120
|
-
}, line);
|
|
121
|
-
if (i === arr.length - 1) {
|
|
122
|
-
return line;
|
|
123
|
-
} else {
|
|
124
|
-
return [line, /*#__PURE__*/_react.default.createElement("br", {
|
|
125
|
-
key: i + 'br'
|
|
126
|
-
})];
|
|
127
|
-
}
|
|
128
|
-
}) : children), !truncated && expanded && /*#__PURE__*/_react.default.createElement("span", null, ' ', /*#__PURE__*/_react.default.createElement("span", {
|
|
61
|
+
}
|
|
62
|
+
componentWillUnmount() {
|
|
63
|
+
this._isMounted = false;
|
|
64
|
+
}
|
|
65
|
+
render() {
|
|
66
|
+
const {
|
|
67
|
+
children,
|
|
68
|
+
more,
|
|
69
|
+
less,
|
|
70
|
+
lines,
|
|
71
|
+
anchorClass,
|
|
72
|
+
className,
|
|
73
|
+
width,
|
|
74
|
+
keepNewLines,
|
|
75
|
+
truncatedEndingComponent,
|
|
76
|
+
onTruncate
|
|
77
|
+
} = this.props;
|
|
78
|
+
const {
|
|
79
|
+
expanded,
|
|
80
|
+
truncated
|
|
81
|
+
} = this.state;
|
|
82
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
83
|
+
className: className
|
|
84
|
+
}, /*#__PURE__*/_react.default.createElement(_Truncate.default, {
|
|
85
|
+
width: width,
|
|
86
|
+
lines: !expanded && lines,
|
|
87
|
+
ellipsis: /*#__PURE__*/_react.default.createElement("span", null, truncatedEndingComponent, /*#__PURE__*/_react.default.createElement("span", {
|
|
129
88
|
className: anchorClass,
|
|
130
89
|
onClick: this.toggleLines
|
|
131
|
-
},
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
90
|
+
}, more)),
|
|
91
|
+
onTruncate: this.handleTruncate,
|
|
92
|
+
ref: ref => this.truncateRef = ref
|
|
93
|
+
}, keepNewLines ? children.split("\n").map((line, i, arr) => {
|
|
94
|
+
line = /*#__PURE__*/_react.default.createElement("span", {
|
|
95
|
+
key: i
|
|
96
|
+
}, line);
|
|
97
|
+
if (i === arr.length - 1) {
|
|
98
|
+
return line;
|
|
99
|
+
} else {
|
|
100
|
+
return [line, /*#__PURE__*/_react.default.createElement("br", {
|
|
101
|
+
key: i + "br"
|
|
102
|
+
})];
|
|
103
|
+
}
|
|
104
|
+
}) : children), !truncated && expanded && /*#__PURE__*/_react.default.createElement("span", null, " ", /*#__PURE__*/_react.default.createElement("span", {
|
|
105
|
+
className: anchorClass,
|
|
106
|
+
onClick: this.toggleLines
|
|
107
|
+
}, less)));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
136
110
|
_defineProperty(ShowMoreText, "defaultProps", {
|
|
137
111
|
lines: 3,
|
|
138
|
-
more:
|
|
139
|
-
less:
|
|
140
|
-
anchorClass:
|
|
112
|
+
more: "Show more",
|
|
113
|
+
less: "Show less",
|
|
114
|
+
anchorClass: "show-more-less-clickable",
|
|
141
115
|
onClick: undefined,
|
|
142
116
|
expanded: false,
|
|
143
117
|
width: 0,
|
|
144
118
|
keepNewLines: false,
|
|
145
|
-
truncatedEndingComponent:
|
|
119
|
+
truncatedEndingComponent: "... ",
|
|
146
120
|
expandByClick: true,
|
|
147
121
|
onTruncate: undefined
|
|
148
122
|
});
|
package/lib/Truncate.js
CHANGED
|
@@ -1,150 +1,139 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
|
4
3
|
Object.defineProperty(exports, "__esModule", {
|
|
5
4
|
value: true
|
|
6
5
|
});
|
|
7
6
|
exports.default = void 0;
|
|
8
7
|
var _react = _interopRequireDefault(require("react"));
|
|
9
8
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
10
|
-
var _excluded = ["children", "ellipsis", "lines"];
|
|
11
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
10
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
13
|
-
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
14
|
-
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
15
|
-
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
16
|
-
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
|
17
|
-
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
18
|
-
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
19
|
-
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
20
|
-
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
21
|
-
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
|
22
|
-
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
23
|
-
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
24
|
-
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
25
11
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
var _super = _createSuper(Truncate);
|
|
29
|
-
function Truncate() {
|
|
30
|
-
var _this;
|
|
12
|
+
class Truncate extends _react.default.Component {
|
|
13
|
+
constructor() {
|
|
31
14
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
32
15
|
args[_key] = arguments[_key];
|
|
33
16
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
_defineProperty(
|
|
37
|
-
|
|
38
|
-
var _self = _assertThisInitialized(_this),
|
|
17
|
+
super(...args);
|
|
18
|
+
_defineProperty(this, "state", {});
|
|
19
|
+
_defineProperty(this, "extractReplaceLinksKeys", content => {
|
|
20
|
+
var _self = this,
|
|
39
21
|
i = 0;
|
|
40
|
-
|
|
22
|
+
this.replacedLinks = [];
|
|
41
23
|
content.replace(/(<a[\s]+([^>]+)>((?:.(?!\<\/a\>))*.)<\/a>)/g, function () {
|
|
42
|
-
|
|
43
|
-
item.key =
|
|
24
|
+
const item = Array.prototype.slice.call(arguments, 1, 4);
|
|
25
|
+
item.key = "[" + "@".repeat(item[2].length - 1) + "=" + i++ + "]";
|
|
44
26
|
_self.replacedLinks.push(item);
|
|
45
27
|
content = content.replace(item[0], item.key);
|
|
46
28
|
});
|
|
47
29
|
return content;
|
|
48
30
|
});
|
|
49
|
-
_defineProperty(
|
|
50
|
-
|
|
31
|
+
_defineProperty(this, "restoreReplacedLinks", content => {
|
|
32
|
+
this.replacedLinks.forEach(item => {
|
|
51
33
|
content = content.replace(item.key, item[0]);
|
|
52
34
|
});
|
|
53
|
-
return
|
|
35
|
+
return this.createMarkup(content);
|
|
54
36
|
});
|
|
55
|
-
_defineProperty(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
div.innerHTML =
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
test.innerHTML =
|
|
63
|
-
if (test[contentKey].replace(/\r\n|\r/g,
|
|
64
|
-
div.innerHTML = div.innerHTML.replace(/<br.*?[\/]?>/gi,
|
|
37
|
+
_defineProperty(this, "innerText", node => {
|
|
38
|
+
const div = document.createElement("div");
|
|
39
|
+
const contentKey = "innerText" in window.HTMLElement.prototype ? "innerText" : "textContent";
|
|
40
|
+
const content = node.innerHTML.replace(/\r\n|\r|\n/g, " ");
|
|
41
|
+
div.innerHTML = this.extractReplaceLinksKeys(content);
|
|
42
|
+
let text = div[contentKey];
|
|
43
|
+
const test = document.createElement("div");
|
|
44
|
+
test.innerHTML = "foo<br/>bar";
|
|
45
|
+
if (test[contentKey].replace(/\r\n|\r/g, "\n") !== "foo\nbar") {
|
|
46
|
+
div.innerHTML = div.innerHTML.replace(/<br.*?[\/]?>/gi, "\n");
|
|
65
47
|
text = div[contentKey];
|
|
66
48
|
}
|
|
67
49
|
return text;
|
|
68
50
|
});
|
|
69
|
-
_defineProperty(
|
|
70
|
-
|
|
51
|
+
_defineProperty(this, "onResize", () => {
|
|
52
|
+
this.calcTargetWidth();
|
|
71
53
|
});
|
|
72
|
-
_defineProperty(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
54
|
+
_defineProperty(this, "onTruncate", didTruncate => {
|
|
55
|
+
const {
|
|
56
|
+
onTruncate
|
|
57
|
+
} = this.props;
|
|
58
|
+
if (typeof onTruncate === "function") {
|
|
59
|
+
this.timeout = window.requestAnimationFrame(() => {
|
|
76
60
|
onTruncate(didTruncate);
|
|
77
61
|
});
|
|
78
62
|
}
|
|
79
63
|
});
|
|
80
|
-
_defineProperty(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
64
|
+
_defineProperty(this, "calcTargetWidth", callback => {
|
|
65
|
+
const {
|
|
66
|
+
elements: {
|
|
67
|
+
target
|
|
68
|
+
},
|
|
69
|
+
calcTargetWidth,
|
|
70
|
+
canvasContext,
|
|
71
|
+
props: {
|
|
72
|
+
width
|
|
73
|
+
}
|
|
74
|
+
} = this;
|
|
86
75
|
|
|
87
76
|
// Calculation is no longer relevant, since node has been removed
|
|
88
77
|
if (!target) {
|
|
89
78
|
return;
|
|
90
79
|
}
|
|
91
|
-
|
|
80
|
+
const targetWidth = width ||
|
|
92
81
|
// Floor the result to deal with browser subpixel precision
|
|
93
82
|
Math.floor(target.parentNode.getBoundingClientRect().width);
|
|
94
83
|
|
|
95
84
|
// Delay calculation until parent node is inserted to the document
|
|
96
85
|
// Mounting order in React is ChildComponent, ParentComponent
|
|
97
86
|
if (!targetWidth) {
|
|
98
|
-
return window.requestAnimationFrame(
|
|
99
|
-
return calcTargetWidth(callback);
|
|
100
|
-
});
|
|
87
|
+
return window.requestAnimationFrame(() => calcTargetWidth(callback));
|
|
101
88
|
}
|
|
102
|
-
|
|
103
|
-
|
|
89
|
+
const style = window.getComputedStyle(target);
|
|
90
|
+
const font = [style["font-weight"], style["font-style"], style["font-size"], style["font-family"]].join(" ");
|
|
104
91
|
canvasContext.font = font;
|
|
105
|
-
|
|
106
|
-
targetWidth
|
|
92
|
+
this.setState({
|
|
93
|
+
targetWidth
|
|
107
94
|
}, callback);
|
|
108
95
|
});
|
|
109
|
-
_defineProperty(
|
|
110
|
-
return
|
|
96
|
+
_defineProperty(this, "measureWidth", text => {
|
|
97
|
+
return this.canvasContext.measureText(text).width;
|
|
111
98
|
});
|
|
112
|
-
_defineProperty(
|
|
99
|
+
_defineProperty(this, "ellipsisWidth", node => {
|
|
113
100
|
return node.offsetWidth;
|
|
114
101
|
});
|
|
115
|
-
_defineProperty(
|
|
116
|
-
return text.replace(/\s+$/,
|
|
102
|
+
_defineProperty(this, "trimRight", text => {
|
|
103
|
+
return text.replace(/\s+$/, "");
|
|
117
104
|
});
|
|
118
|
-
_defineProperty(
|
|
105
|
+
_defineProperty(this, "createMarkup", str => {
|
|
119
106
|
return /*#__PURE__*/_react.default.createElement("span", {
|
|
120
107
|
dangerouslySetInnerHTML: {
|
|
121
108
|
__html: str
|
|
122
109
|
}
|
|
123
110
|
});
|
|
124
111
|
});
|
|
125
|
-
_defineProperty(
|
|
126
|
-
|
|
127
|
-
elements
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
112
|
+
_defineProperty(this, "getLines", () => {
|
|
113
|
+
const {
|
|
114
|
+
elements,
|
|
115
|
+
props: {
|
|
116
|
+
lines: numLines,
|
|
117
|
+
ellipsis,
|
|
118
|
+
trimWhitespace
|
|
119
|
+
},
|
|
120
|
+
state: {
|
|
121
|
+
targetWidth
|
|
122
|
+
},
|
|
123
|
+
innerText,
|
|
124
|
+
measureWidth,
|
|
125
|
+
onTruncate,
|
|
126
|
+
trimRight,
|
|
127
|
+
renderLine,
|
|
128
|
+
restoreReplacedLinks
|
|
129
|
+
} = this;
|
|
130
|
+
const lines = [];
|
|
131
|
+
const text = innerText(elements.text);
|
|
132
|
+
const textLines = text.split("\n").map(line => line.split(" "));
|
|
133
|
+
let didTruncate = true;
|
|
134
|
+
const ellipsisWidth = this.ellipsisWidth(this.elements.ellipsis);
|
|
135
|
+
for (let line = 1; line <= numLines; line++) {
|
|
136
|
+
const textWords = textLines[0];
|
|
148
137
|
|
|
149
138
|
// Handle newline
|
|
150
139
|
if (textWords.length === 0) {
|
|
@@ -153,7 +142,7 @@ var Truncate = /*#__PURE__*/function (_React$Component) {
|
|
|
153
142
|
line--;
|
|
154
143
|
continue;
|
|
155
144
|
}
|
|
156
|
-
|
|
145
|
+
let resultLine = textWords.join(" ");
|
|
157
146
|
if (measureWidth(resultLine) <= targetWidth) {
|
|
158
147
|
if (textLines.length === 1) {
|
|
159
148
|
// Line is end of text and fits without truncating
|
|
@@ -165,72 +154,71 @@ var Truncate = /*#__PURE__*/function (_React$Component) {
|
|
|
165
154
|
}
|
|
166
155
|
if (line === numLines) {
|
|
167
156
|
// Binary search determining the longest possible line inluding truncate string
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
157
|
+
const textRest = textWords.join(" ");
|
|
158
|
+
let lower = 0;
|
|
159
|
+
let upper = textRest.length - 1;
|
|
171
160
|
while (lower <= upper) {
|
|
172
|
-
|
|
173
|
-
|
|
161
|
+
const middle = Math.floor((lower + upper) / 2);
|
|
162
|
+
const testLine = textRest.slice(0, middle + 1);
|
|
174
163
|
if (measureWidth(testLine) + ellipsisWidth <= targetWidth) {
|
|
175
164
|
lower = middle + 1;
|
|
176
165
|
} else {
|
|
177
166
|
upper = middle - 1;
|
|
178
167
|
}
|
|
179
168
|
}
|
|
180
|
-
|
|
169
|
+
let lastLineText = textRest.slice(0, lower);
|
|
181
170
|
if (trimWhitespace) {
|
|
182
171
|
lastLineText = trimRight(lastLineText);
|
|
183
172
|
|
|
184
173
|
// Remove blank lines from the end of text
|
|
185
174
|
while (!lastLineText.length && lines.length) {
|
|
186
|
-
|
|
175
|
+
const prevLine = lines.pop();
|
|
187
176
|
lastLineText = trimRight(prevLine);
|
|
188
177
|
}
|
|
189
178
|
}
|
|
190
|
-
if (lastLineText.substr(lastLineText.length - 2) ===
|
|
179
|
+
if (lastLineText.substr(lastLineText.length - 2) === "][") {
|
|
191
180
|
lastLineText = lastLineText.substring(0, lastLineText.length - 1);
|
|
192
181
|
}
|
|
193
|
-
;
|
|
194
|
-
lastLineText = lastLineText.replace(/\[@+$/, '');
|
|
182
|
+
lastLineText = lastLineText.replace(/\[@+$/, "");
|
|
195
183
|
lastLineText = restoreReplacedLinks(lastLineText);
|
|
196
184
|
resultLine = /*#__PURE__*/_react.default.createElement("span", null, lastLineText, ellipsis);
|
|
197
185
|
} else {
|
|
198
186
|
// Binary search determining when the line breaks
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
while (
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
if (measureWidth(
|
|
205
|
-
|
|
187
|
+
let lower = 0;
|
|
188
|
+
let upper = textWords.length - 1;
|
|
189
|
+
while (lower <= upper) {
|
|
190
|
+
const middle = Math.floor((lower + upper) / 2);
|
|
191
|
+
const testLine = textWords.slice(0, middle + 1).join(" ");
|
|
192
|
+
if (measureWidth(testLine) <= targetWidth) {
|
|
193
|
+
lower = middle + 1;
|
|
206
194
|
} else {
|
|
207
|
-
|
|
195
|
+
upper = middle - 1;
|
|
208
196
|
}
|
|
209
197
|
}
|
|
210
198
|
|
|
211
199
|
// The first word of this line is too long to fit it
|
|
212
|
-
if (
|
|
200
|
+
if (lower === 0) {
|
|
213
201
|
// Jump to processing of last line
|
|
214
202
|
line = numLines - 1;
|
|
215
203
|
continue;
|
|
216
204
|
}
|
|
217
|
-
resultLine = textWords.slice(0,
|
|
205
|
+
resultLine = textWords.slice(0, lower).join(" ");
|
|
218
206
|
resultLine = restoreReplacedLinks(resultLine);
|
|
219
|
-
textLines[0].splice(0,
|
|
207
|
+
textLines[0].splice(0, lower);
|
|
220
208
|
}
|
|
221
209
|
lines.push(resultLine);
|
|
222
210
|
}
|
|
223
211
|
onTruncate(didTruncate);
|
|
224
212
|
return lines.map(renderLine);
|
|
225
213
|
});
|
|
226
|
-
_defineProperty(
|
|
214
|
+
_defineProperty(this, "renderLine", (line, i, arr) => {
|
|
227
215
|
if (i === arr.length - 1) {
|
|
228
216
|
return /*#__PURE__*/_react.default.createElement("span", {
|
|
229
217
|
key: i
|
|
230
218
|
}, line);
|
|
231
219
|
} else {
|
|
232
|
-
|
|
233
|
-
key: i +
|
|
220
|
+
const br = /*#__PURE__*/_react.default.createElement("br", {
|
|
221
|
+
key: i + "br"
|
|
234
222
|
});
|
|
235
223
|
if (line) {
|
|
236
224
|
return [/*#__PURE__*/_react.default.createElement("span", {
|
|
@@ -241,102 +229,110 @@ var Truncate = /*#__PURE__*/function (_React$Component) {
|
|
|
241
229
|
}
|
|
242
230
|
}
|
|
243
231
|
});
|
|
244
|
-
_defineProperty(
|
|
232
|
+
_defineProperty(this, "styles", {
|
|
245
233
|
ellipsis: {
|
|
246
|
-
position:
|
|
247
|
-
visibility:
|
|
234
|
+
position: "fixed",
|
|
235
|
+
visibility: "hidden",
|
|
248
236
|
top: 0,
|
|
249
237
|
left: 0
|
|
250
238
|
}
|
|
251
239
|
});
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return _this;
|
|
240
|
+
this.elements = {};
|
|
241
|
+
this.replacedLinks = [];
|
|
255
242
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
window.addEventListener('resize', onResize);
|
|
271
|
-
}
|
|
272
|
-
}, {
|
|
273
|
-
key: "componentDidUpdate",
|
|
274
|
-
value: function componentDidUpdate(prevProps) {
|
|
275
|
-
// Render was based on outdated refs and needs to be rerun
|
|
276
|
-
if (this.props.children !== prevProps.children) {
|
|
277
|
-
this.forceUpdate();
|
|
243
|
+
componentDidMount() {
|
|
244
|
+
const {
|
|
245
|
+
elements: {
|
|
246
|
+
text
|
|
247
|
+
},
|
|
248
|
+
calcTargetWidth,
|
|
249
|
+
onResize
|
|
250
|
+
} = this;
|
|
251
|
+
const canvas = document.createElement("canvas");
|
|
252
|
+
this.canvasContext = canvas.getContext("2d");
|
|
253
|
+
calcTargetWidth(() => {
|
|
254
|
+
// Node not needed in document tree to read its content
|
|
255
|
+
if (text && text.parentNode) {
|
|
256
|
+
text.parentNode.removeChild(text);
|
|
278
257
|
}
|
|
258
|
+
});
|
|
259
|
+
window.addEventListener("resize", onResize);
|
|
260
|
+
}
|
|
261
|
+
componentDidUpdate(prevProps) {
|
|
262
|
+
// Render was based on outdated refs and needs to be rerun
|
|
263
|
+
if (this.props.children !== prevProps.children) {
|
|
264
|
+
this.forceUpdate();
|
|
265
|
+
}
|
|
279
266
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
}
|
|
267
|
+
// If the width prop has changed, recalculate size of contents
|
|
268
|
+
if (this.props.width !== prevProps.width) {
|
|
269
|
+
this.calcTargetWidth();
|
|
284
270
|
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
271
|
+
}
|
|
272
|
+
componentWillUnmount() {
|
|
273
|
+
const {
|
|
274
|
+
elements: {
|
|
275
|
+
ellipsis
|
|
276
|
+
},
|
|
277
|
+
onResize,
|
|
278
|
+
timeout
|
|
279
|
+
} = this;
|
|
280
|
+
if (ellipsis.parentNode) {
|
|
281
|
+
ellipsis.parentNode.removeChild(ellipsis);
|
|
296
282
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
283
|
+
window.removeEventListener("resize", onResize);
|
|
284
|
+
window.cancelAnimationFrame(timeout);
|
|
285
|
+
}
|
|
286
|
+
render() {
|
|
287
|
+
const {
|
|
288
|
+
elements: {
|
|
289
|
+
target
|
|
290
|
+
},
|
|
291
|
+
props: {
|
|
292
|
+
children,
|
|
293
|
+
ellipsis,
|
|
294
|
+
lines,
|
|
295
|
+
...spanProps
|
|
296
|
+
},
|
|
297
|
+
state: {
|
|
298
|
+
targetWidth
|
|
299
|
+
},
|
|
300
|
+
getLines,
|
|
301
|
+
onTruncate
|
|
302
|
+
} = this;
|
|
303
|
+
let text;
|
|
304
|
+
const mounted = !!(target && targetWidth);
|
|
305
|
+
if (typeof window !== "undefined" && mounted) {
|
|
306
|
+
if (lines > 0) {
|
|
307
|
+
text = getLines();
|
|
308
|
+
} else {
|
|
309
|
+
text = children;
|
|
310
|
+
onTruncate(false);
|
|
319
311
|
}
|
|
320
|
-
delete spanProps.onTruncate;
|
|
321
|
-
delete spanProps.trimWhitespace;
|
|
322
|
-
return /*#__PURE__*/_react.default.createElement("span", _extends({}, spanProps, {
|
|
323
|
-
ref: function ref(targetEl) {
|
|
324
|
-
_this2.elements.target = targetEl;
|
|
325
|
-
}
|
|
326
|
-
}), /*#__PURE__*/_react.default.createElement("span", null, text), /*#__PURE__*/_react.default.createElement("span", {
|
|
327
|
-
ref: function ref(textEl) {
|
|
328
|
-
_this2.elements.text = textEl;
|
|
329
|
-
}
|
|
330
|
-
}, children), /*#__PURE__*/_react.default.createElement("span", {
|
|
331
|
-
ref: function ref(ellipsisEl) {
|
|
332
|
-
_this2.elements.ellipsis = ellipsisEl;
|
|
333
|
-
},
|
|
334
|
-
style: this.styles.ellipsis
|
|
335
|
-
}, ellipsis));
|
|
336
312
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
313
|
+
delete spanProps.onTruncate;
|
|
314
|
+
delete spanProps.trimWhitespace;
|
|
315
|
+
return /*#__PURE__*/_react.default.createElement("span", _extends({}, spanProps, {
|
|
316
|
+
ref: targetEl => {
|
|
317
|
+
this.elements.target = targetEl;
|
|
318
|
+
}
|
|
319
|
+
}), /*#__PURE__*/_react.default.createElement("span", {
|
|
320
|
+
style: {
|
|
321
|
+
display: "block",
|
|
322
|
+
maxWidth: "".concat(spanProps.width, "px")
|
|
323
|
+
}
|
|
324
|
+
}, text), /*#__PURE__*/_react.default.createElement("span", {
|
|
325
|
+
ref: textEl => {
|
|
326
|
+
this.elements.text = textEl;
|
|
327
|
+
}
|
|
328
|
+
}, children), /*#__PURE__*/_react.default.createElement("span", {
|
|
329
|
+
ref: ellipsisEl => {
|
|
330
|
+
this.elements.ellipsis = ellipsisEl;
|
|
331
|
+
},
|
|
332
|
+
style: this.styles.ellipsis
|
|
333
|
+
}, ellipsis));
|
|
334
|
+
}
|
|
335
|
+
}
|
|
340
336
|
exports.default = Truncate;
|
|
341
337
|
_defineProperty(Truncate, "propTypes", {
|
|
342
338
|
children: _propTypes.default.node,
|
|
@@ -347,10 +343,9 @@ _defineProperty(Truncate, "propTypes", {
|
|
|
347
343
|
onTruncate: _propTypes.default.func
|
|
348
344
|
});
|
|
349
345
|
_defineProperty(Truncate, "defaultProps", {
|
|
350
|
-
children:
|
|
351
|
-
ellipsis:
|
|
346
|
+
children: "",
|
|
347
|
+
ellipsis: "…",
|
|
352
348
|
lines: 1,
|
|
353
349
|
trimWhitespace: false,
|
|
354
350
|
width: 0
|
|
355
|
-
});
|
|
356
|
-
;
|
|
351
|
+
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-show-more-text",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "The text surrounded by the component will be truncated. Anything surrounded by the component could be evaluated as text. The component react-show-more-text/ShowMoreText is fork of react-show-more/ShowMore, applied improvements, works with React 16.x.x, added onClick event.",
|
|
5
5
|
"main": "lib/ShowMoreText.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"lib"
|
|
8
8
|
],
|
|
9
9
|
"scripts": {
|
|
10
|
-
"compile": "./node_modules/.bin/babel src/ShowMoreText.js src/Truncate.js --out-dir lib
|
|
10
|
+
"compile": "./node_modules/.bin/babel src/ShowMoreText.js src/Truncate.js --out-dir lib",
|
|
11
11
|
"compile:watch": "onchange \"src/**/*.js\" -- npm run compile --silent --source-maps",
|
|
12
12
|
"coverage": "nyc npm test && nyc report --reporter=text-lcov",
|
|
13
13
|
"lint": "eslint .",
|
|
@@ -83,7 +83,6 @@
|
|
|
83
83
|
"react-dom": "^16.14.0"
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@babel/polyfill": "^7.12.1",
|
|
87
86
|
"prop-types": "^15.7.2"
|
|
88
87
|
},
|
|
89
88
|
"browserslist": "> 0.25%, not dead"
|