Password Strength Meter (Mobx + React)

HTML

<script src="https://npmcdn.com/[email protected]/lib/mobx.umd.js"></script>
<script src="https://npmcdn.com/[email protected]/index.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.14.3/react-dom.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div class="container" id="main">
  <div class="row">
    <div class="col-xs-12 col-md-6">
      <div id="app"></div>
    </div>
  </div>
</div>

CSS

#main {
  margin-top: 20px;
}

.list-group-item {
  border-radius: 0px !important;
}

.form-control {
  border-radius: 0px !important;
}

.constraint .edit,
.constraint .delete {
  visibility: hidden;
}

.constraint:hover .edit,
.constraint:hover .delete {
  visibility: visible;
}

.constraint {}

.tweet-editor {
  resize: vertical;
}

.tweet-actions {
  margin-top: 10px;
}

.feedback {
  margin-top: 20px;
}

.green {
  color: darkgreen;
}

.red {
  color: darkred;
}

.passwordmeter li {
  margin-left: -20px;
}

Babel + JSX

const {observable, computed, extendObservable} = mobx;
const {observer} = mobxReact;
const {Component} = React;
const {render} = ReactDOM

const rules = [
  {
    test: (d) => d.length > 6,
    feedback: "6+ characters"
  },
  {
    test: (d) => /\d/.test(d),
    feedback: "with at least one digit"
  },
  {
    test: (d) => /[^a-zA-Z0-9]/.test(d),
    feedback: "with at least one special character"
  }
]

class Store {
  @observable password = ""
  @computed get pctMet(){
    let x = this.rules.map((d) => d.test(this.password))
    let isTrue = (d) => d === true
    return x.filter(isTrue).length/3*100 + "%"
  }
  constructor(rules){
    this.rules = rules
  }
}

const newStore = new Store(rules)
console.log(newStore)

const PasswordField = observer(({store}) => {
  return(
    <input 
      type="text" 
      className="form-control" 
      defaultValue={store.password}
      onChange={(e) => store.password = e.target.value}
    />
  )
})

const ProgressBar = observer(({store}) => {
  return(
    <div className="progress" style={{height: 10}}>
      <div 
        className="progress-bar progress-bar-default"
        style={{width: store.pctMet}}
      />
    </div>
  )
})

const Panel = (props) => {
  return(
    <div className="feedback">
      <div className = "panel panel-default">
        <div className="panel-body">
          {props.children}
        </div>
      </div>
    </div>  
  )
}

const PasswordFeedbackText = observer(({store}) => {
  let item = (d, i) => {
    return (
      <li key={i} 
        className={d.test(store.password) ? 'green' : 'red'}>
        {d.feedback}
      </li>
    )
  }
  return(
    <ul>
      {store.rules.map(item)}
    </ul>
  )
})


const PasswordFeedback = observer(({store}) => {
  return(
    <Panel>
      <ProgressBar store={store}/>
      <PasswordFeedbackText store={store}/>
    </Panel>
  )
})




const App = observer(({store}) => {
  return(
    <div className="well clearfix passwordmeter">
      <h4>Password...