<commit_before>import React, {PropTypes} from 'react'
import FormBuilderPropTypes from '../../../FormBuilderPropTypes'
import SearchableSelect from 'part:@sanity/components/selects/searchable'
import Preview from '../../../Preview'

export default class ReferenceSearchableSelect extends React.Component {
  static propTypes = {
    type: FormBuilderPropTypes.type.isRequired,
    value: PropTypes.object,
    searchFn: PropTypes.func,
    valueToString: PropTypes.func,
    onChange: PropTypes.func
  };

  static defaultProps = {
    onChange() {
    }
  }

  static contextTypes = {
    formBuilder: PropTypes.object
  }

  state = {
    fetching: false,
    query: null,
    hits: [],
    materializedValue: null
  }

  materializeValue(value) {
    const {valueToString, type} = this.props
    if (value.isEmpty()) {
      return
    }
    const serialized = value.serialize()
    valueToString(serialized, type)
      .then(materializedValue => {
        this.setState({materializedValue})
      })
  }

  componentDidMount() {
    this.materializeValue(this.props.value)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.value != this.props.value) {
      this.materializeValue(nextProps.value)
    }
  }

  getMemberFieldForType(typeName) {
    const {type} = this.props
    return type.to.find(ofType => ofType.type.name === typeName)
  }

  fetchAll() {
    const {searchFn, type} = this.props

    searchFn('*', type)
      .then(items => {
        this._isFetching = false

        const updatedCache = items.reduce((cache, item) => {
          cache[item._id] = item
          return cache
        }, Object.assign({}, this.state.refCache))

        this.setState({
          items: items,
          hits: items,
          fetching: false,
          refCache: updatedCache
        })
      })
  }

  handleFocus = () => {
    this.fetchAll()
  }

  handleChange = item => {
    const patch = {
      type: 'set',
      value: {
        _type: 'reference',
        _ref: item._id
      }
    }
    this.props.onChange({patch: patch})
  }

  handleSearch = query => {
    const {type, searchFn} = this.props

    if (query === '') {
      this.fetchAll()
      return
    }

    if (this._currentQuery === query) {
      return
    }

    this._currentQuery = query

    if (!query) {
      return
    }

    this.setState({
      fetching: true
    })

    searchFn(query, type)
      .then(hits => {
        if (this._currentQuery !== query) {
          return // ignore
        }

        const nextRefCache = hits.reduce((cache, hit) => {
          cache[hit._id] = hit
          return cache
        }, Object.assign({}, this.state.refCache))

        this.setState({
          fetching: false,
          hits: hits,
          refCache: nextRefCache,
          query: query
        })
      })
  }

  renderItem = item => {
    const type = this.getMemberFieldForType(item._type)
    return (
      <Preview
        type={type}
        value={item}
        layout="default"
      />
    )
  }

  render() {
    const {type} = this.props
    const {materializedValue, fetching, hits} = this.state

    const value = hits.find(item => {
      return item._id === this.props.value.value._ref
    })

    return (
      <SearchableSelect
        label={type.title}
        description={type.description}
        placeholder="Type to search…"
        onBlur={this.handleBlur}
        onFocus={this.handleFocus}
        onSearch={this.handleSearch}
        onChange={this.handleChange}
        value={value || this.props.value}
        valueAsString={materializedValue}
        renderItem={this.renderItem}
        loading={fetching}
        items={hits}
      />
    )
  }
}
<commit_msg>fixing clearbutton on searchable select reference<commit_after>import React, {PropTypes} from 'react'
import FormBuilderPropTypes from '../../../FormBuilderPropTypes'
import SearchableSelect from 'part:@sanity/components/selects/searchable'
import Preview from '../../../Preview'


const getInitialState = () => {
  return {
    fetching: false,
    query: null,
    hits: [],
    materializedValue: null
  }
}

export default class ReferenceSearchableSelect extends React.Component {
  static propTypes = {
    type: FormBuilderPropTypes.type.isRequired,
    value: PropTypes.object,
    searchFn: PropTypes.func,
    valueToString: PropTypes.func,
    onChange: PropTypes.func
  };

  static defaultProps = {
    onChange() {
    }
  }

  static contextTypes = {
    formBuilder: PropTypes.object
  }

  state = getInitialState()


  materializeValue(value) {
    const {valueToString, type} = this.props
    if (value.isEmpty()) {
      return
    }
    const serialized = value.serialize()
    valueToString(serialized, type)
      .then(materializedValue => {
        this.setState({materializedValue})
      })
  }

  componentDidMount() {
    this.materializeValue(this.props.value)
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.value != this.props.value) {
      this.setState(getInitialState())
      this.materializeValue(nextProps.value)
    }
  }

  getMemberFieldForType(typeName) {
    const {type} = this.props
    return type.to.find(ofType => ofType.type.name === typeName)
  }

  fetchAll() {
    const {searchFn, type} = this.props

    searchFn('*', type)
      .then(items => {
        this._isFetching = false

        const updatedCache = items.reduce((cache, item) => {
          cache[item._id] = item
          return cache
        }, Object.assign({}, this.state.refCache))

        this.setState({
          items: items,
          hits: items,
          fetching: false,
          refCache: updatedCache
        })
      })
  }

  handleFocus = () => {
    this.fetchAll()
  }

  handleChange = item => {
    const patch = {
      type: 'set',
      value: {
        _type: 'reference',
        _ref: item._id
      }
    }
    this.props.onChange({patch: patch})
  }

  handleSearch = query => {
    const {type, searchFn} = this.props

    if (query === '') {
      this.fetchAll()
      return
    }

    if (this._currentQuery === query) {
      return
    }

    this._currentQuery = query

    if (!query) {
      return
    }

    this.setState({
      fetching: true
    })

    searchFn(query, type)
      .then(hits => {
        if (this._currentQuery !== query) {
          return // ignore
        }

        const nextRefCache = hits.reduce((cache, hit) => {
          cache[hit._id] = hit
          return cache
        }, Object.assign({}, this.state.refCache))

        this.setState({
          fetching: false,
          hits: hits,
          refCache: nextRefCache,
          query: query
        })
      })
  }

  renderItem = item => {
    const type = this.getMemberFieldForType(item._type)
    return (
      <Preview
        type={type}
        value={item}
        layout="default"
      />
    )
  }

  handleClear = item => {
    const patch = {
      type: 'unset'
    }
    this.props.onChange({patch: patch})
  }

  render() {
    const {type} = this.props
    const {materializedValue, fetching, hits} = this.state

    const value = hits.find(item => {
      return item._id === this.props.value.value._ref
    })

    return (
      <SearchableSelect
        label={type.title}
        description={type.description}
        placeholder="Type to search…"
        onBlur={this.handleBlur}
        onFocus={this.handleFocus}
        onSearch={this.handleSearch}
        onChange={this.handleChange}
        onClear={this.handleClear}
        value={value || this.props.value}
        valueAsString={materializedValue}
        renderItem={this.renderItem}
        loading={fetching}
        items={hits}
      />
    )
  }
}

{'fraction_non_alphanumeric': 0.12572909915748542, 'fraction_numerical': 0.0, 'mean_word_length': 2.1416938110749184, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 31, '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': '5941106', 'n_tokens_mistral': 2334, 'n_tokens_neox': 2313, 'n_words': 449}