Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Material UI next version #11

Open
ferarnoled opened this issue Jan 19, 2018 · 3 comments
Open

Material UI next version #11

ferarnoled opened this issue Jan 19, 2018 · 3 comments

Comments

@ferarnoled
Copy link

ferarnoled commented Jan 19, 2018

Here is a modified version for the new version of Material UI based on
this example

Might be useful.

import React from 'react';
import PropTypes from 'prop-types';
import Autosuggest from 'react-autosuggest';
import match from 'autosuggest-highlight/match';
import parse from 'autosuggest-highlight/parse';
import TextField from 'material-ui/TextField';
import Paper from 'material-ui/Paper';
import { MenuItem } from 'material-ui/Menu';
import { withStyles } from 'material-ui/styles';

function renderInput(inputProps) {
  const { classes, autoFocus, value, ref, ...other } = inputProps;

  return (
      <TextField
          autoFocus={autoFocus}
          className={classes.textField}
          value={value}
          inputRef={ref}
          InputProps={{
            classes: {
              input: classes.input,
            },
            ...other,
          }}
      />
  );
}

function renderSuggestion(suggestion, { query, isHighlighted }) {
  const matches = match(suggestion.description, query);
  const parts = parse(suggestion.description, matches);

  return (
      <MenuItem selected={isHighlighted} component="div">
        <div>
          {parts.map((part, index) => {
            return part.highlight ? (
                <span key={String(index)} style={{ fontWeight: 300 }}>
              {part.text}
            </span>
            ) : (
                <strong key={String(index)} style={{ fontWeight: 500 }}>
                  {part.text}
                </strong>
            );
          })}
        </div>
      </MenuItem>
  );
}

function renderSuggestionsContainer(options) {
  const { containerProps, children } = options;

  return (
      <Paper {...containerProps} square>
        {children}
      </Paper>
  );
}

function getSuggestionValue(suggestion) {
  return suggestion.description;
}

const styles = theme => ({
  container: {
    flexGrow: 1,
    position: 'relative',
    height: 200,
  },
  suggestionsContainerOpen: {
    position: 'absolute',
    marginTop: theme.spacing.unit,
    marginBottom: theme.spacing.unit * 3,
    left: 0,
    right: 0,
  },
  suggestion: {
    display: 'block',
  },
  suggestionsList: {
    margin: 0,
    padding: 0,
    listStyleType: 'none',
  },
  textField: {
    width: '100%',
  },
});

class GMapsAutocomplete extends React.Component {

  constructor(props) {
    super(props);
    this.autocompleteService = new google.maps.places.AutocompleteService();
    this.state = {
      value: props.selectedValue ? props.selectedValue : '',
      suggestions: []
    };
  }

  updateDataSource = (data) => {
    if (!data || !data.length) {
      return false;
    }

    if (this.state.suggestions) {
      this.previousData = { ...this.state.suggestions };
    }
    this.setState({
      suggestions: data
    });
  };

  getBounds = () => {
    if (!this.props.bounds || (!this.props.bounds.ne && !this.props.bounds.south)) {
      return undefined;
    }

    if (this.props.bounds.ne && this.props.bounds.sw) {
      return new google.maps.LatLngBounds(this.props.bounds.sw, this.props.bounds.ne);
    }

    return {
      ...this.props.bounds
    };
  };

  getSuggestions = (searchText) => {
    if (!searchText.length || !this.autocompleteService) {
      return false;
    }

    let request = {
      input: searchText,
      location: new google.maps.LatLng(this.props.location.lat, this.props.location.lng),
      radius: this.props.radius,
      types: this.props.types,
      bounds: this.getBounds()
    };

    if (this.props.restrictions) {
      request.componentRestrictions = { ...this.props.restrictions };
    }

    this.autocompleteService.getPlacePredictions(request, data => this.updateDataSource(data));
  }

  handleSuggestionsFetchRequested = ({ value }) => {
    this.getSuggestions(value);
  };

  handleSuggestionsClearRequested = () => {
    this.setState({
      suggestions: []
    });
  };

  handleChange = (event, { newValue }) => {
    this.setState({
      value: newValue,
    });
  };

  handleSuggestionSelected = (event, { suggestion, suggestionValue, suggestionIndex, sectionIndex, method }) => {
    console.log(suggestionValue);
    this.props.onSuggestionSelected(suggestion, suggestionValue);
  }

  render() {
    const { classes, placeholder } = this.props;

    return (
        <Autosuggest
            theme={{
              container: classes.container,
              suggestionsContainerOpen: classes.suggestionsContainerOpen,
              suggestionsList: classes.suggestionsList,
              suggestion: classes.suggestion,
            }}
            renderInputComponent={renderInput}
            suggestions={this.state.suggestions}
            onSuggestionsFetchRequested={this.handleSuggestionsFetchRequested}
            onSuggestionsClearRequested={this.handleSuggestionsClearRequested}
            renderSuggestionsContainer={renderSuggestionsContainer}
            getSuggestionValue={getSuggestionValue}
            renderSuggestion={renderSuggestion}
            onSuggestionSelected={this.handleSuggestionSelected}
            inputProps={{
              autoFocus: true,
              classes,
              placeholder: placeholder,
              value: this.state.value,
              onChange: this.handleChange,
            }}
        />
    );
  }
}

GMapsAutocomplete.propTypes = {
  classes: PropTypes.object.isRequired,
  placeholder: PropTypes.string.isRequired,
  selectedValue: PropTypes.string,
  onSuggestionSelected: PropTypes.func,
  //Google maps parameters,
  location: PropTypes.object,
  radius: PropTypes.number,
  restrictions: PropTypes.shape({
    country: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.arrayOf(PropTypes.string)
    ])
  })
};

GMapsAutocomplete.defaultProps = {
  location: {lat: 0, lng: 0},
  radius: 0
};

export default withStyles(styles)(GMapsAutocomplete);
@ydeshayes
Copy link
Owner

Hello!

I will create a branch and test that soon.

Thanks!

@robinknox
Copy link

Hi @ydeshayes. First thanks very much for this component. It has been very useful. I've recently upgraded to material UI's next version and am currently using both versions so that I can use autocomplete. Do you have an estimate on when you'll be able to look at updating this to the next version of MUI?

@zwhitchcox
Copy link

Any movement on this? I upgraded to @material-ui/core, which is now the standard, and this lists material-ui as a dependency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants