Skip to content

Instantly share code, notes, and snippets.

@piratus
Last active August 29, 2015 14:25
Show Gist options
  • Save piratus/6319f4a632f888cc2ea9 to your computer and use it in GitHub Desktop.
Save piratus/6319f4a632f888cc2ea9 to your computer and use it in GitHub Desktop.
Text truncating label
import React from 'react';
const STYLE = {
display: 'inline-block',
overflow: 'hidden',
whiteSpace: 'nowrap',
};
const MIN_TEXT_LENGHT = 6;
const MIN_LABEL_WIDTH = 40;
/**
* A text label that adapts to `width` by truncating
* the text from the middle.
* @class Label
* @extends React.Component
*/
export default class Label extends React.Component {
static propTypes = {
/** the text to display */
text: React.PropTypes.string.isRequired,
/** (optional) width of the label in pixels */
width: React.PropTypes.number,
/** (optional) extra styles */
style: React.PropTypes.object,
};
constructor(props) {
super(props);
this.state = {text: props.text};
}
componentDidMount() {
this.updateTextSize();
}
componentWillReceiveProps(nextProps) {
const text = nextProps.text || this.props.text;
this.setState({text});
}
componentDidUpdate() { this.updateTextSize(); }
updateTextSize() {
const props = this.props;
const node = React.findDOMNode(this);
const width = props.width && props.width || node.offsetWidth;
if (props.text.length > MIN_TEXT_LENGHT && width > MIN_LABEL_WIDTH) {
if (width < node.scrollWidth) {
const {text} = this.state;
const chunk = text.length / 2;
this.setState({
text: text.substring(0, chunk - 1) + '…' + text.substring(chunk + 1)
});
}
}
}
render() {
const {width, style, text: title, ...props} = this.props;
return (
<span {...props}
style={{...STYLE, width, ...style}}
title={title}>
{this.state.text}
</span>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment