<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>CodePen</title>
</head>
<body>
  <div id="container"></div>
</body>
</html>
class TweetBox extends React.Component {
  constructor(props) {
    super(props);
 
    this.state = {
      text: '',
      photoAdded: false,
    };
  }
  
  handleChange = (e) => {
    this.setState({ text: e.target.value });
  };

  togglePhoto = () => {
    this.setState((prevState) => ({ photoAdded: !prevState.photoAdded }));
  }
  
  getRemainingChars = () => {
    let chars = 280 - this.state.text.length;
    if (this.state.photoAdded) chars = chars - 23;
    return chars;
  }
  
  renderOverflowAlert = () => {
    if (this.getRemainingChars() < 0) {
      const imageLength = this.state.photoAdded ? 23 : 0;
      const beforeOverflowText = this.state.text.substring(
        280 - imageLength - 10,
        280 - imageLength,
      );
      const overflowText = this.state.text.substring(280 - imageLength);

      return (
        <div className="alert alert-warning text-left">
          <strong>Oops! Too Long:</strong>
          &nbsp; &#8230;
          {beforeOverflowText}
          <strong className="bg-danger text-light">{overflowText}</strong>
        </div>
      );
    }
    return '';
  };

  render() {
    const isTweetButtonDisabled = this.state.text.length === 0 && !this.state.photoAdded;
  
    return (
      <div className="card bg-light">
        <div className="card-body text-right">
          {this.renderOverflowAlert()}
          <textarea className="form-control" onChange={this.handleChange}></textarea>
          <br/>
          <span>{this.getRemainingChars()}</span>
          
          <button className="btn btn-primary" disabled={isTweetButtonDisabled}>Tweet</button>
          
          <button className="btn btn-secondary" onClick={this.togglePhoto}>
            {this.state.photoAdded ? "✓ Photo Added" : "Add Photo" }
          </button>
        </div>
      </div>
    );
  }
};

ReactDOM.render(
  <TweetBox />,
  document.getElementById("container")
);
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/react/16.7.0/umd/react.production.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.7.0/umd/react-dom.production.min.js