MUI textfield multline detect and prevent line break on mobile

Viewed 35

I have created input tag component using mui Textfield component, when you type something and press enter it should create a tag and allow to enter new tag which works fine in chrome browser, but when opened in chrome mobile, instead of creating tag, it goes to new line and I am unable to find solution around it

import React, { useState, useEffect } from 'react'
import { TextField, Chip } from '@mui/material'
import { useField } from 'formik'
import { useTheme } from '@mui/material/styles'

interface IInputTagsProps {
  label?: string
  placeholder?: string
  variant?: 'standard' | 'filled' | 'outlined' | undefined
  type?: string
  id: string
  style?: {
    [key: string]: string
  }
  inputBaseStyle?: {
    [key: string]: string
  }
  autoComplete?: 'on' | 'off'
  name: string
  fullWidth?: boolean
  formik: any
  [key: string]: any
}

const InputTags = ({
  label,
  variant,
  type,
  id,
  style,
  inputBaseStyle,
  autoComplete,
  name,
  fullWidth,
  formik,
  placeholder,
  ...rest
}: IInputTagsProps) => {
  const theme = useTheme()
  const [, meta] = useField({ name })
  const [inputValue, setInputValue] = useState<string>('')
  const [items, setItems] = useState<string[]>([])
  const [shrink, setShrink] = useState<boolean>(false)

  const renderHelperText = () => {
    const { touched, error } = meta
    if (touched && error) {
      return error
    }
    return null
  }

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setInputValue(e.target.value)
    formik.setFieldError(name, '')
  }

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      const duplicatedValues = items.indexOf(inputValue)

      if (duplicatedValues !== -1) {
        setInputValue('')
        e.preventDefault()
        return
      }
      if (!inputValue.replace(/\s/g, '').length) return

      setItems([...items, inputValue])
      setInputValue('')
      e.preventDefault()
    }
  }

  const handleDelete = (itemIndex: number) => {
    const newItems = items.filter(
      (_item: string, index: number) => itemIndex !== index
    )
    setItems(newItems)
  }

  useEffect(() => {
    if (items.length === 0) {
      setShrink(false)
    }
    formik.setFieldValue(name, items)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [items, name])

  return (
    <TextField
      id={id}
      label={label || ''}
      variant={variant || 'outlined'}
      type={type || 'text'}
      error={meta.touched && Boolean(meta.error) && true}
      helperText={renderHelperText()}
      autoComplete={autoComplete || 'on'}
      fullWidth={fullWidth || false}
      sx={{
        mb: 6,
        '& .MuiInputBase-root': {
          borderRadius: theme.spacing(2),
          flexWrap: 'wrap',
          gap: theme.spacing(2),
          ...inputBaseStyle,
        },
        '& .MuiInputBase-inputMultiline': {
          width: 'fit-content',
        },
        ...style,
      }}
      value={inputValue}
      onChange={handleChange}
      onFocus={() => setShrink(true)}
      onBlur={() => !items.length && setShrink(false)}
      onKeyDown={handleKeyDown}
      placeholder={placeholder || ''}
      multiline
      InputLabelProps={{ shrink }}
      InputProps={{
        startAdornment: formik.values[name].map(
          (item: string, index: number) => (
            <Chip
              key={item}
              tabIndex={-1}
              label={item}
              color="primary"
              onDelete={() => handleDelete(index)}
              sx={{
                borderRadius: theme.spacing(1),
                fontWeight: '500',
                fontSize: '1rem',
                '& .MuiChip-deleteIcon': {
                  color: theme.palette.common.white,
                },
              }}
            />
          )
        ),
      }}
      {...rest}
    />
  )
}

export default InputTags

enter image description here

If pressed 2 times the blue icon at bottom right, then it creates tag.

0 Answers
Related