Giter Club home page Giter Club logo

rpearce / react-expanding-textarea Goto Github PK

View Code? Open in Web Editor NEW
90.0 3.0 13.0 14.05 MB

React textarea component to automatically expand and contract your textareas.

Home Page: http://rpearce.github.io/react-expanding-textarea/

License: BSD 3-Clause "New" or "Revised" License

JavaScript 7.06% CSS 2.61% TypeScript 90.33%
reactjs textarea textarea-component autosize textarea-autoresize react react-component text-resize expanding-textarea typescript

react-expanding-textarea's Introduction

⚠️ Retired

Please consider using https://github.com/Andarist/react-textarea-autosize. There's an insurmountable issue with this approach in #82 that is solved by react-textarea-autosize.

react-expanding-textarea

All Contributors npm version npm downloads bundlephobia size

React textarea component to automatically expand and contract your textareas.

You can view the demo here.

Links

Installation

npm i react-expanding-textarea

Usage

Use this exactly like you would a normal <textarea>; the only difference is that it is doing some simple expanding work behind the scenes for you!

import React, { useCallback, useEffect, useRef } from 'react'
import Textarea from 'react-expanding-textarea'

const MyTextarea = () => {
  const textareaRef = useRef(null)

  const handleChange = useCallback(e => {
    console.log('Changed value to: ', e.target.value)
  }, [])

  useEffect(() => {
    textareaRef.current.focus()
  }, [])

  return (
    <>
      <label htmlFor="my-textarea">
        Please Enter Some Details:
      </label>
      <Textarea
        className="textarea"
        defaultValue="Lorem ipsum dolor sit amet, ..."
        id="my-textarea"
        maxLength="3000"
        name="pet[notes]"
        onChange={handleChange}
        placeholder="Enter additional notes..."
        ref={textareaRef}
      />
    </>
  )
}

Using The rows Prop

If you pass a rows prop, then this component will perform a calculation based on computed lineHeight, borderTopWidth, borderBottomWidth, paddingTop and paddingBottom to deduce what the minimum height-in-rows the component should be.

Manually Calling resize

If for some reason you need to manually resize a <textarea>, this package exports a resize function that has the following type:

interface Resize {
  (rows: number, el: HTMLTextAreaElement | null): void
}

And you can use it like this:

import { resize } from 'react-expanding-textarea'

// resize based on 3 minimum rows
// and using a React ref
resize(3, refTextarea.current)

// or

// resize based on no minimum rows
// and using a regular DOM Node
resize(0, document.querySelector('textarea'))

Contributors

Thanks goes to these wonderful people (emoji key):


Robert Pearce

💻 📖 💡 🤔 ⚠️

Anuj

🐛

Lloyd Watkin

🤔

Jordan Hornblow

🐛

visgotti

🤔

Thomas Sunde Nielsen

🐛 🤔

cibulka

🐛 🤔

Brett Smith

🐛

Rauno Freiberg

🐛 💻

Thomas Kristiansen

🤔

Puspender

🐛

Mark Thomas

🐛

Artem

🐛

Eva Raymond

🐛

Chris Drackett

🐛

Simon Smith

🐛 🤔 👀

jordie23

🐛 🤔

Mat Sz

🐛 💻

crtl

🐛 🤔

Jonathan Wan

🐛 💻

James Moss

🐛 🤔

SunnyAureliusRichard

🐛

Magoz

🤔

jeffreystorer

🐛

This project follows the all-contributors specification. Contributions of any kind welcome!

react-expanding-textarea's People

Contributors

dependabot[bot] avatar jnthnwn avatar mat-sz avatar raunofreiberg avatar rpearce avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

react-expanding-textarea's Issues

auto adjusting Issues with Firefox

In Firefox with react version 16.9.0 or greater, the focus while typing is lost. On mobile firefox, TextArea is not maintaining the text state.
Chrome is working fine. Here is a screen recording for reference.
Video on youtube

useLayoutEffect warning in nextjs

Hi,

Is it possible to have a setting that switches between useEffect and useLayoutEffect? I can see it was introduced in #77 .

This is the warning I'm getting:

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
    at ExpandingTextarea (web\node_modules\react-expanding-textarea\dist\cjs\index.js:54:27)
    at withForwardedRef(ExpandingTextarea)
    at Textarea (webpack-internal:///./src/components/atoms/inputs/Textarea.tsx:15:11)

Thanks!

Default value isn't resizing

So when I give a default value into the text box it doesnt auto resize to it, is there a property I'm missing?

don't expand if value does not change based on input

I'm trying to create a text area that will resize if it overflows, but submits when the user presses enter. I'm trying the following code:

<Textarea
  value={props.value}
  onInput={({target: { value: text }}) => {
    if (text.substr(text.length - 1, 1) === '\n') {
      console.log('submit function here!')
    } else {
      onInput(text)
    }
  }
/>

this is mostly working, however I'm running into an issue where the text area will grow when I press enter.

Cannot use with typescript

Attempting to use with typescript via the following declaration:

import * as React from 'react';
import Textarea from 'react-expanding-textarea';

                        <Textarea
                            name='statement'
                            value={this.state.statement}
                            onChange={this.handleChange}
                            margin="normal"
                            variant="outlined"
                            required={false}
                            style={{ width: '100%' }}
                        />

and receiving the following error:

TS2339: Property 'name' does not exist on type 'IntrinsicAttributes & TextareaProps & RefAttributes '.

Use useLayoutEffect instead of useEffect

This change will prevent some flickering that I've seen, Kent describes it well here https://kentcdodds.com/blog/useeffect-vs-uselayouteffect:

However, if your effect is mutating the DOM (via a DOM node ref) and the DOM mutation will change the appearance of the DOM node between the time that it is rendered and your effect mutates it, then you don't want to use useEffect. You'll want to use useLayoutEffect. Otherwise the user could see a flicker when your DOM mutations take effect.

I'd say this is the perfect use case.

onChange should be hinted with ChangeEvent instead of FormEvent

Currently onChange handler is wrongly typed with FormEvent<HtmlTextareaElement> instead of ChangeEvent<HtmlTextaraeElement> in TextareaProps

FormEvent.target does not have value property and will cause error in strict environments.

function onChange(e: FormEvent<HtmlTextareaElement>) {
  setContent(e.target.value); //TS2339: Property 'value' does not exist on type 'EventTarget'.
}

Workaround is to explicitly convert type:

setContent((e.target as HTMLTextAreaElement).value);
// or
setContent(e.currentTarget.value);

Allow updating of textarea height on initial render

Hey,

I'm building a feature where I restore text to the textarea from sessionStorage on render and I note that it doesn't update the height when I refresh the page and set the value:

2021-06-14 10 36 32

Could the textarea detect this on initial render or perhaps provide an API for this?

Cheers!

Textarea height as a fractional value instead of an integer (more precision)

The textarea css height value is always an integer, regardless of the true height of the textarea.
I'm assuming this is because Element.scrollHeight always rounds the value to an integer.

From mdn (source):

Note: This property will round the value to an integer. If you need a fractional value, use Element.getBoundingClientRect().

I have a use case where I need subpixel precision.

Would you be open to adding support for it?
Happy to help to implement it.

ref as a function breaks resizing

Hello,

If I pass a function as the ref the resizing breaks, and I presume this is because the textarea relies on the ref.current to be an element. However libraries like react-hook-form pass a register function as the ref which gets the element as the only argument.

Thanks

maxHeight no scrollbar

When adding maxHeight and text has many lines - scroll bar in textarea is not appears because overflow-y: hidden; added to textarea.

Textarea does not automatically recalculate size if it's parent container changes size

If the textarea is 100% width and it's parent container changes size, the height of the text area is not re-calculated.

I've put together an example here https://codesandbox.io/s/cool-estrela-7wq7f?file=/src/App.js

By toggling the textarea to the wider size, there's loads of whitespace below the last line, once you focus in the field and start typing this gets correctly removed.

This needs to use ResizeObserver to monitor for changes to the size of the textarea.

Comment height = 0

Why? target.style.height = 0 before target.style.height = ${target.scrollHeight}px``

Demo not working

Hi there! I was looking to try out our library but the demo link isn't working. Could you please take a look?

Thanks!

Scrollbar is not taken into consideration

Consider the example in http://rpearce.github.io/react-expanding-textarea/

The textarea grows in height, even though the text can still fit on one line.

image

This happens because the textarea has a scrollbar on it, that is not shown because there isn't a max height on the textarea. It is possible to set overflow: hidden to make the textarea grow in height by not taking the scrollbar into consideration. Although, in this case, the scrollable functionality is lost.

Dependency Conflict With React 18.1.0

I am getting a error message from npm audit fix:
npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR! react@"^18.1.0" from the root project
npm ERR! peer react@">=18" from @chakra-ui/[email protected]
npm ERR! node_modules/@chakra-ui/accordion
npm ERR! @chakra-ui/accordion@"2.0.1" from @chakra-ui/[email protected]
npm ERR! node_modules/@chakra-ui/react
npm ERR! @chakra-ui/react@"^2.1.0" from the root project
npm ERR! 70 more (@chakra-ui/alert, @chakra-ui/avatar, ...)
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.0 || ^17.0.0" from [email protected]
npm ERR! node_modules/react-expanding-textarea
npm ERR! react-expanding-textarea@"^2.3.5" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/react
npm ERR! peer react@"^16.8.0 || ^17.0.0" from [email protected]
npm ERR! node_modules/react-expanding-textarea
npm ERR! react-expanding-textarea@"^2.3.5" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\jstor\AppData\Local\npm-cache\eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\jstor\AppData\Local\npm-cache_logs\2022-05-23T20_37_15_086Z-debug-0.log

"dependencies": {
"@chakra-ui/icons": "^2.0.0",
"@chakra-ui/react": "^2.1.0",
"@chakra-ui/theme-tools": "^2.0.0",
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^10.4.9",
"@testing-library/user-event": "^12.8.3",
"firebase": "^9.8.1",
"framer-motion": "^4.1.17",
"lodash": "^4.17.21",
"preval.macro": "^5.0.0",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-expanding-textarea": "^2.3.5",
"react-firebase-hooks": "^5.0.3",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"recoil": "^0.7.2",
"spinner-favicon": "^1.0.0",
"use-visibility-change": "^0.5.0",
"uuid": "^8.3.2",
"web-vitals": "^0.2.4"
},

Any suggestions?

Issue testing with enzyme

Issue is here https://github.com/rpearce/react-expanding-textarea/blob/master/src/ExpandingTextarea.js#L20-L21

In tests if you do something like:

_component.find(Textarea).simulate('change', { target: { value: '1.21 gigawatts?!?' } })

Error message returned is 'Attempted to assign to readonly property' (techincally these properties should be read only https://developer.mozilla.org/en-US/docs/Web/API/Event, but obviously that isn't happening in browsers since the property is mutable.

I did have a short term hack which was

  component.find(Textarea).simulate('change', { hack: '1.21 gigawatts?!?' })

and then in my onChange I referenced the textarea's value as such:

const body = event.target.value || event.hack

However, I've found a nicer work around. Enzyme merges that data value into the event object, so we can overwrite the style property as such:

  component.find(Textarea).simulate(
    'change',
    { target: { value: '1.21 gigawatts?!?', style: {} } }
  )

Which works just great! Might be something for the README :)

Default number of rows?

Is there a recommended way how to set the minimum number of rows for react-expanding-textarea? Settings attribute rows does not seem to work.

import Textarea from 'react-expanding-textarea';
// render
<Textarea rows="3" />

Thanks in advance!

The size should change when the textarea value is changed

We're using react-expanding-textarea as an input field to a chat. We empty the textarea by setting value to an empty string on submit. This does not resize the textarea back to the initial size.

Our current workaround is to save a ref to the component and call this.textarea._adjustTextarea(this.textarea);, which is not optimal and depends on an internal function not changing.

Exposing ref

We need to be able to access "ref" on the textarea to be able to set focues() on the textarea from the parent.

Or you could expose a "SetFocus" prop :-)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.