<commit_before>import React, { Component } from 'react'
import { View, Animated } from 'react-native'
import PropTypes from 'prop-types'

export default class extends Component {
  static propTypes = {
    underlineDuration: PropTypes.number,
    underlineHeight: PropTypes.number,
    underlineColor: PropTypes.string,
    underlineActiveColor: PropTypes.string
  }

  static defaultProps = {
    underlineDuration: 200,
    underlineHeight: 1,
    underlineColor: 'gray',
    underlineActiveColor: '#3f51b5'
  }
  constructor(props) {
    super(props)

    this.state = {
      width: 0,
      animatedWidth: new Animated.Value(0)
    }
  }

  componentDidMount() {
    requestAnimationFrame(() => {
      const container = this.refs.underline
      container.measure((left, top, width, height) => {
        this.setState({ width })
      })
    })
  }

  render() {
    let { activeColor, underlineHeight, underlineColor, underlineActiveColor, error, errorColor } = this.props
    let { animatedWidth } = this.state

    return (
      <View
        style={{
          alignItems: 'center',
          borderColor: error ? errorColor : underlineColor,
          borderBottomWidth: error ? underlineHeight + 1 : underlineHeight
        }}
        ref="underline">
        <Animated.View
          style={{
            bottom: -underlineHeight - 1,
            width: animatedWidth,
            borderColor: error ? errorColor : activeColor ? activeColor : underlineActiveColor,
            borderBottomWidth: underlineHeight + 1
          }}
        />
      </View>
    )
  }

  _handleAnimated = flag => {
    let { underlineDuration } = this.props
    let { width, animatedWidth } = this.state

    Animated.timing(animatedWidth, {
      toValue: flag ? width : 0,
      duration: underlineDuration
    }).start()
  }
}
}<commit_msg>Refactor Underline to track props instead of being called a function directly. Use native animations.<commit_after>import React, { Component } from 'react'
import { View, Animated } from 'react-native'
import PropTypes from 'prop-types'

export default class extends Component {
  static propTypes = {
    underlineDuration: PropTypes.number,
    underlineHeight: PropTypes.number,
    underlineColor: PropTypes.string,
    underlineActiveColor: PropTypes.string
  }

  static defaultProps = {
    underlineDuration: 200,
    underlineHeight: 1,
    underlineColor: 'gray',
    underlineActiveColor: '#3f51b5'
  }

  state = {
    animatedScaleX: new Animated.Value(0)
  }

  componentWillReceiveProps = nextProps => {
    const { animatedScaleX } = this.state
    const { focused, underlineDuration } = nextProps

    if (this.props.focused !== focused) {
      Animated.timing(animatedScaleX, {
        toValue: focused ? 1 : 0,
        duration: underlineDuration,
        useNativeDriver: true
      }).start()
    }
  }

  render() {
    let { activeColor, underlineHeight, underlineColor, underlineActiveColor, error, errorColor } = this.props
    let { animatedScaleX } = this.state

    return (
      <View
        style={{
          borderColor: error ? errorColor : underlineColor,
          borderBottomWidth: error ? underlineHeight + 1 : underlineHeight
        }}>
        <Animated.View
          style={{
            bottom: -underlineHeight - 1,
            transform: [{ scaleX: animatedScaleX }],
            borderColor: error ? errorColor : activeColor || underlineActiveColor,
            borderBottomWidth: underlineHeight + 1
          }}
        />
      </View>
    )
  }
}
{'fraction_non_alphanumeric': 0.09951936669493922, 'fraction_numerical': 0.00791631325982471, 'mean_word_length': 2.6028513238289204, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2079848', 'n_tokens_mistral': 1011, 'n_tokens_neox': 973, 'n_words': 239}