JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://fb.me/JSXTransformer-0.5.1.js"></script>
<script src="http://fb.me/react-with-addons-0.5.1.js"></script>
<script src="http://fb.me/react-js-fiddle-integration.js"></script>

    <div id="container">
      <p>
        If you can see this, React is not working right. This is probably because you&apos;re viewing
        this on your file system instead of a web server. Try running
        <pre>
          python -m SimpleHTTPServer
        </pre>
        and going to <a href="http://localhost:8000/">http://localhost:8000/</a>.
      </p>
    </div>
    <div id="text1" style="display:none">
      Michael! Across from where? We just call it a sausage. We just call it a sausage. Bad news. Andy Griffith turned us down. He didn't like his trailer. As you may or may not know, Lindsay and I have hit a bit of a rough patch.
 
Whoa, this guy's straight? I'm half machine. I'm a monster. Across from where?
 
Not tricks, Michael, illusions. First place chick is hot, but has an attitude, doesn't date magicians. Guy's a pro.
 
That's why you always leave a note! Army had half a day. Get me a vodka rocks. And a piece of toast. Army had half a day.
 
Well, what do you expect, mother? I don't criticize you! And if you're worried about criticism, sometimes a diet is the best defense. Oh, you're gonna be in a coma, all right. Across from where? He'll want to use your yacht, and I don't want this thing smelling like fish.
 
I care deeply for nature. No! I was ashamed to be SEEN with you. I like being with you. I'm a monster. It's called 'taking advantage.' It's what gets you ahead in life.
 
I don't criticize you! And if you're worried about criticism, sometimes a diet is the best defense. Not tricks, Michael, illusions. Say goodbye to these, because it's the last time! I care deeply for nature.
 
I'm afraid I just blue myself. I'm afraid I just blue myself. Across from where?
 
I'm a monster. It's a hug, Michael. I'm hugging you. Say goodbye to these, because it's...

CSS

span:hover { background-color: yellow; cursor: pointer; }

JavaScript 1.7

/**
 * @jsx React.DOM
 */
 
var text1 = document.getElementById('text1').textContent;
var text2 = document.getElementById('text2').textContent;
 
var LinksDemo = React.createClass({
  getInitialState: function() {
    return {text: text1};
  },
 
  switchText: function() {
    var newText = this.state.text === text1 ? text2 : text1;
    this.setState({text: newText})
  },
 
  render: function() {
    return (
      <div>
        <button onClick={this.switchText}>Switch</button>
        <LinkedText text={this.state.text} />
      </div>
    );
  }
});
 
var LinkedText = React.createClass({
  render: function() {
    var text = this.props.text;
    var lines = this.props.text.split(/\n/g).map(function(line) {
      return <Line line={line} />
    });
 
    return (
      <div>
        {lines}
      </div>
    );
  }
});
 
var Line = React.createClass({
  getInitialState: function() {
    return {hasHovered: false};
  },
 
  mouseEnter: function() {
    this.setState({hasHovered: true});
  },
 
  componentWillReceiveProps: function() {
    this.setState({hasHovered: false});
  },
 
  render: function() {
    if (!this.state.hasHovered) {
      return <div onMouseEnter={this.mouseEnter}>{this.props.line}</div>
    }
 
    var words = this.props.line.split(/\s+/g).filter(function(word) { return !!word; }).map(function(word) {
      return <span onClick={alert.bind(null, word)} href="#">{word + ' '}</span>;
    });
 
    return (
      <div>
        {words}
      </div>
    );
  }
});
 
React.renderComponent(
  <LinksDemo />,
  document.getElementById('container')
);