Skip to content

Instantly share code, notes, and snippets.

@jacobmoyle
Last active May 24, 2019 00:28
Show Gist options
  • Select an option

  • Save jacobmoyle/51e4a515cd20e47740b472ed027ef3e9 to your computer and use it in GitHub Desktop.

Select an option

Save jacobmoyle/51e4a515cd20e47740b472ed027ef3e9 to your computer and use it in GitHub Desktop.
WIP
import React from 'react'
import PropTypes from 'prop-types'
import Chip from '@material-ui/core/Chip'
import TextField from '@material-ui/core/TextField'
// import InputAdornment from '@material-ui/core/InputAdornment'
import { withStyles } from '@material-ui/core/styles'
// const DEFAULT_BORDER_COLOR = '#859198'
// const DEFAULT_LABEL_COLOR = '#859198'
const INPUT_BG_COLOR = '#F5F8FA'
// const ERROR_COLOR = '#D31315'
// const DISABLED_COLOR = '#C2CBCC'
// const CLEAR_ICON_COLOR = '#97999A'
const styles = theme => ({
filled: {
borderRadius: 4,
color: '#000000',
fontSize: 16,
backgroundColor: `${INPUT_BG_COLOR} !important`,
'&:hover': {
borderBottom: 'none !important'
}
},
textFieldRoot: {
display: 'flex',
flexWrap: 'wrap',
maxWidth: 500,
minWidth: 300
},
inputRoot: {
minWidth: '30%',
width: 'inherit'
},
chipContainer: {
marginTop: '600',
borderBottom: 'none !important'
},
chip: {}
})
// TODO: Hide Label accessibly
// TODO: Handle paste with regex and splitting?
// TODO: Provide regex hook for delimeters
const ENTER = 'Enter'
const COMMA = ','
const SPACE = ' '
const DELETE = 'Backspace'
const EMPTY = ''
function ChipConfig(label, hasError) {
this.hasError = hasError
this.label = label
}
class ChipInput extends React.Component {
state = {
chipConfigs: [],
inputValue: EMPTY
}
static defaultProps = {
syntheticDelimeters: [ENTER, COMMA, SPACE],
onValidate: () => false
}
static propTypes = {
syntheticDelimeters: PropTypes.arrayOf(PropTypes.string),
// Requires a callback that returns True or False
onValidate: PropTypes.func.isRequired
}
handleChipUpdate = e => {
const { syntheticDelimeters } = this.props
const { inputValue, chipConfigs } = this.state
const value = e.target.value
// Create Chip
if (syntheticDelimeters.includes(e.key) && inputValue !== EMPTY) {
this.handleChipAdd(value)
}
// Delete Chip
if (e.key === DELETE && inputValue === EMPTY) {
this.handleChipDelete(chipConfigs.length - 1)
}
}
handleChipAdd = value => {
const { onValidate } = this.props
this.setState(prevState => ({
chipConfigs: prevState.chipConfigs.concat(new ChipConfig(value, onValidate(value))),
inputValue: EMPTY
}))
}
handleChipDelete = idx => {
const configCopy = this.state.chipConfigs.slice()
configCopy.splice(idx, 1)
this.setState({
chipConfigs: configCopy
})
}
handleInputUpdate = e => {
const { syntheticDelimeters } = this.props
const newInput = e.target.value
if (!syntheticDelimeters.includes(newInput)) {
this.setState({ inputValue: newInput })
}
}
render() {
const { children, classes, ...rest } = this.props
const { chipConfigs, inputValue } = this.state
const arrayOfChips = chipConfigs.map((config, index) => {
return <Chip key={index} onDelete={() => this.handleChipDelete(index)} {...config} />
})
return (
<TextField
value={inputValue}
onKeyDown={this.handleChipUpdate}
onChange={this.handleInputUpdate}
InputLabelProps={{ shrink: true }}
InputProps={{
classes: { root: classes.textFieldRoot, input: classes.inputRoot },
startAdornment: arrayOfChips
}}
{...rest}
/>
)
}
}
export default withStyles(styles)(ChipInput)
@jacobmoyle
Copy link
Author

Not complete until further refactored into multiple files

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment