So let’s look at the effect

Features of wechat chat input box

  1. As the text input increases, the number of lines in the input box increases
  2. The input box has a maximum of 5 lines
  3. Beyond 5 lines, the scroll begins

implementation

Use the TextaREA tag to change the number of input rows by setting the Rows property

The difficulties in analysis

  1. How to detect the arrival of a text boundary and change the Rows property of a textarea

How to solve

Use a TextaREA of the same width, set the TextaREA to invisible, rows to 1, readonly.

The number of rows is determined by the clientHeight and ScrollHeight of the textarea.

Other Points of attention

  1. Remove whitespace characters at the beginning and end of the text
  2. If there are no other characters after whitespace characters are removed, the message cannot be sent

Code implementation

// InputArea.js

import React, { useState, useMemo, useRef, useEffect } from 'react'

import './InputArea.scss'

export default function InputArea(props) {
  const [content, setContent] = useState(' ')

  // The maximum number of lines for the default textarea
  const [defaultMaxRows] = useState(5)

  const [rows, setRows] = useState(1)

  const hiddenTextarea = useRef(null)

  const maxRows = useMemo((a)= > props.maxRows || defaultMaxRows, [props.maxRows])

  useEffect((a)= > {
    return (a)= > {
      let r = hiddenTextarea.current.scrollHeight / hiddenTextarea.current.clientHeight
      if (r > maxRows) r = maxRows
      setRows(r)
    }
  }, [maxRows, content])

  // Whether the user input can be sent
  // Remove trailing whitespace from input
  const disable = useMemo((a)= > content.replace(/(^\s+)|(\s+$)/g.' ') = = =' ', [content])

  // Send a message
  function sendMessage() {
    // Call the interface to send the message
    props.sendMessage && props.sendMessage()

    // After sending successfully
    setContent(' ')}function onChange(e) {
    // console.log('onchange', e.target.value)
    setContent(e.target.value)
  }

  function onBlur(e) {
    // Put the keyboard away
    setTimeout((a)= > {
      // safari on ios9 does not support window.scrollto
      window.scrollTo && window.scrollTo(0.99999999)},100)}function onFocus(e) {
    // The keyboard pops up
    setTimeout((a)= > {
      // safari on ios9 does not support window.scrollto
      window.scrollTo && window.scrollTo(0.99999999)},100)}return( <div className="m-input-area__wrapper"> <div className="m-input-area__content"> <textarea spellCheck={false} Placeholder =" Input chat content..." Rows ={rows} value={content} onChange={onChange} onBlur={onBlur} onFocus={onFocus} /> {/* Invisible input box */} <textarea readOnly rows={1} value={content} ref={hiddenTextarea} /> </div> <input className={`m-input-area__btn ${disable ? Disabled ={disable} onClick={sendMessage} /> </div>)}Copy the code
.m-input-area__wrapper {
  display: flex;
  justify-content: space-between;
  background: #F6F6F6;
  padding: 3px 6px 4px 6px;
  // border-top: solid 1px #f1f1f1;
  box-shadow: 0 -1px 4px #ddd;
}

.m-input-area__content {
  flex-grow: 1;
  position: relative;
  // height: fit-content;
  border-radius: 2px;
  margin-right: 6px;
  padding: 4px 6px;
  background: #fff;
  // font-size: 0; // Resolve the textarea by adding whitespace characters causing height to unintentionally open 3px other solutions look at notes

  textarea {
    display: block; // Resolve the textarea by adding whitespace characters causing height to unintentionally open 3px other solutions look at notes
    font-size: 14px;
    padding: 0;
    border: 0;
    line-height: 22px;
    color: #71777c;
    resize: none; // Element sizing is not allowed
    width: 100%;
    outline: none;

    &::placeholder {
      color: #CECECE;
    }

    &:nth-child(2) {
      visibility: hidden;
      position: absolute;
      left: 0;
      top: 0;
      padding: 0 6px;
      box-sizing: border-box; }}}.m-input-area__btn {
  width: 60px;
  height: 30px;
  font-size: 14px;
  // text-align: center;
  color: #fff;
  background: #007fff;
  // border: solid 1px #007fff;
  border: none;
  border-radius: 2px;
  font-weight: 600;
  cursor: pointer;
  letter-spacing: 4px;
  text-indent: 4px;

  &.disable {
    // border-color: #CECECE;
    background: #cecece;
    color: #fff; }}Copy the code