Skip to content

Commit a0340d4

Browse files
committed
Merge pull request #14 from raymondlukanta/master
add textTruncateChild
2 parents ceb99fa + 153bf86 commit a0340d4

File tree

3 files changed

+209
-4
lines changed

3 files changed

+209
-4
lines changed

lib/index.js

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; }
2+
3+
define(['module', 'exports', 'react'], function (module, exports, _react) {
4+
'use strict';
5+
6+
Object.defineProperty(exports, "__esModule", {
7+
value: true
8+
});
9+
10+
var _react2 = _interopRequireDefault(_react);
11+
12+
function _interopRequireDefault(obj) {
13+
return obj && obj.__esModule ? obj : {
14+
default: obj
15+
};
16+
}
17+
18+
function _classCallCheck(instance, Constructor) {
19+
if (!(instance instanceof Constructor)) {
20+
throw new TypeError("Cannot call a class as a function");
21+
}
22+
}
23+
24+
var _createClass = (function () {
25+
function defineProperties(target, props) {
26+
for (var i = 0; i < props.length; i++) {
27+
var descriptor = props[i];
28+
descriptor.enumerable = descriptor.enumerable || false;
29+
descriptor.configurable = true;
30+
if ("value" in descriptor) descriptor.writable = true;
31+
Object.defineProperty(target, descriptor.key, descriptor);
32+
}
33+
}
34+
35+
return function (Constructor, protoProps, staticProps) {
36+
if (protoProps) defineProperties(Constructor.prototype, protoProps);
37+
if (staticProps) defineProperties(Constructor, staticProps);
38+
return Constructor;
39+
};
40+
})();
41+
42+
function _possibleConstructorReturn(self, call) {
43+
if (!self) {
44+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
45+
}
46+
47+
return call && ((typeof call === 'undefined' ? 'undefined' : _typeof(call)) === "object" || typeof call === "function") ? call : self;
48+
}
49+
50+
function _inherits(subClass, superClass) {
51+
if (typeof superClass !== "function" && superClass !== null) {
52+
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
53+
}
54+
55+
subClass.prototype = Object.create(superClass && superClass.prototype, {
56+
constructor: {
57+
value: subClass,
58+
enumerable: false,
59+
writable: true,
60+
configurable: true
61+
}
62+
});
63+
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
64+
}
65+
66+
var TextTruncate = (function (_Component) {
67+
_inherits(TextTruncate, _Component);
68+
69+
function TextTruncate() {
70+
_classCallCheck(this, TextTruncate);
71+
72+
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(TextTruncate).call(this));
73+
74+
_this.onResize = _this.onResize.bind(_this);
75+
return _this;
76+
}
77+
78+
_createClass(TextTruncate, [{
79+
key: 'componentWillMount',
80+
value: function componentWillMount() {
81+
var canvas = document.createElement('canvas');
82+
var docFragment = document.createDocumentFragment();
83+
docFragment.appendChild(canvas);
84+
this.canvas = canvas.getContext('2d');
85+
}
86+
}, {
87+
key: 'componentDidMount',
88+
value: function componentDidMount() {
89+
var style = window.getComputedStyle(this.refs.scope);
90+
var font = [];
91+
font.push(style['font-weight']);
92+
font.push(style['font-style']);
93+
font.push(style['font-size']);
94+
font.push(style['font-family']);
95+
this.canvas.font = font.join(' ');
96+
this.forceUpdate();
97+
window.addEventListener('resize', this.onResize);
98+
}
99+
}, {
100+
key: 'componentWillUnmount',
101+
value: function componentWillUnmount() {
102+
window.removeEventListener('resize', this.onResize);
103+
}
104+
}, {
105+
key: 'onResize',
106+
value: function onResize() {
107+
this.forceUpdate();
108+
}
109+
}, {
110+
key: 'measureWidth',
111+
value: function measureWidth(text) {
112+
return this.canvas.measureText(text).width;
113+
}
114+
}, {
115+
key: 'getRenderText',
116+
value: function getRenderText() {
117+
var textWidth = this.measureWidth(this.props.text);
118+
var ellipsisWidth = this.measureWidth(this.props.truncateText);
119+
var scopeWidth = this.refs.scope.offsetWidth;
120+
121+
if (scopeWidth >= textWidth) {
122+
return this.props.text;
123+
} else {
124+
var n = 0;
125+
var max = this.props.text.length;
126+
var text = '';
127+
var splitPos = 0;
128+
var startPos = 0;
129+
var line = this.props.line;
130+
while (line--) {
131+
var ext = line ? '' : this.props.truncateText;
132+
while (n <= max) {
133+
n++;
134+
text = this.props.text.substr(startPos, n);
135+
if (this.measureWidth(text + ext) > scopeWidth) {
136+
splitPos = text.lastIndexOf(' ');
137+
if (splitPos === -1) {
138+
splitPos = n - 1;
139+
}
140+
startPos += splitPos;
141+
break;
142+
}
143+
}
144+
if (n >= max) {
145+
startPos = max;
146+
break;
147+
}
148+
n = 0;
149+
}
150+
return startPos === max ? this.props.text : this.props.text.substr(0, startPos - 1) + this.props.truncateText;
151+
}
152+
}
153+
}, {
154+
key: 'render',
155+
value: function render() {
156+
var text = '';
157+
if (this.refs.scope) {
158+
text = this.getRenderText();
159+
}
160+
var attrs = {
161+
ref: 'scope'
162+
};
163+
if (this.props.showTitle) {
164+
attrs.title = this.props.text;
165+
}
166+
167+
return _react2.default.createElement(
168+
'div',
169+
null,
170+
_react2.default.createElement(
171+
'div',
172+
attrs,
173+
text
174+
),
175+
this.props.textTruncateChild
176+
);
177+
}
178+
}]);
179+
180+
return TextTruncate;
181+
})(_react.Component);
182+
183+
TextTruncate.propTypes = {
184+
text: _react2.default.PropTypes.string,
185+
truncateText: _react2.default.PropTypes.string,
186+
line: _react2.default.PropTypes.number,
187+
showTitle: _react2.default.PropTypes.bool,
188+
textTruncateChild: _react2.default.PropTypes.node
189+
};
190+
TextTruncate.defaultProps = {
191+
text: '',
192+
truncateText: '…',
193+
line: 1,
194+
showTitle: true
195+
};
196+
exports.default = TextTruncate;
197+
;
198+
module.exports = exports['default'];
199+
});

src/App.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ export class App extends Component {
88
text: 'Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.',
99
line: 2,
1010
truncateText: '…',
11-
showTitle: true
11+
showTitle: true,
12+
textTruncateChild: <a className='pull-right'>show more</a>
1213
};
1314
}
1415
handleChange = (e) => {
1516
this.setState({
1617
line: this.refs.line.value << 0,
1718
text: this.refs.text.value,
1819
truncateText: this.refs.truncateText.value,
19-
showTitle: this.refs.showTitle.checked
20+
showTitle: this.refs.showTitle.checked,
21+
2022
});
2123
};
2224
render() {

src/TextTruncate.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ export default class TextTruncate extends Component {
55
text: React.PropTypes.string,
66
truncateText: React.PropTypes.string,
77
line: React.PropTypes.number,
8-
showTitle: React.PropTypes.bool
8+
showTitle: React.PropTypes.bool,
9+
textTruncateChild: React.PropTypes.node
910
};
1011

1112
static defaultProps = {
@@ -97,7 +98,10 @@ export default class TextTruncate extends Component {
9798
}
9899

99100
return (
100-
<div {...attrs}>{text}</div>
101+
<div>
102+
<div {...attrs}>{text}</div>
103+
{this.props.textTruncateChild}
104+
</div>
101105
);
102106
}
103107
};

0 commit comments

Comments
 (0)