Skip to content
This repository was archived by the owner on Jun 30, 2024. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: rpearce/react-expanding-textarea
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.3.4
Choose a base ref
...
head repository: rpearce/react-expanding-textarea
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v2.3.5
Choose a head ref

Commits on Dec 21, 2021

  1. Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    b58305a View commit details
  2. Keep pkgs up to date

    rpearce committed Dec 21, 2021
    Copy the full SHA
    03b5ad2 View commit details
  3. Merge pull request #79 from rpearce/deps

    Keep pkgs up to date
    rpearce authored Dec 21, 2021
    Copy the full SHA
    8afd4b1 View commit details

Commits on Dec 22, 2021

  1. Copy the full SHA
    e2e891e View commit details

Commits on Dec 23, 2021

  1. Copy the full SHA
    a0cc8bb View commit details

Commits on Dec 29, 2021

  1. update deps

    rpearce committed Dec 29, 2021
    Copy the full SHA
    719d997 View commit details
  2. Copy the full SHA
    3a9dde9 View commit details
  3. Copy the full SHA
    d1b7910 View commit details

Commits on Dec 30, 2021

  1. Copy the full SHA
    20fd96b View commit details
  2. Copy the full SHA
    8a7e559 View commit details

Commits on Dec 31, 2021

  1. fix linter error in stories

    rpearce committed Dec 31, 2021
    Copy the full SHA
    e0f17b2 View commit details

Commits on Jan 3, 2022

  1. Copy the full SHA
    afcbe8b View commit details
  2. Copy the full SHA
    73a6758 View commit details
  3. Copy the full SHA
    3267ad0 View commit details
  4. bump some dev deps

    rpearce committed Jan 3, 2022
    Copy the full SHA
    b9cae2b View commit details
  5. Merge pull request #78 from rpearce/fix/resize-scenarios

    Fix: Also resize via ResizeObserver and changes to additional props
    rpearce authored Jan 3, 2022
    Copy the full SHA
    a83373d View commit details
  6. Copy the full SHA
    142f500 View commit details
  7. Fix changelog date

    rpearce committed Jan 3, 2022
    Copy the full SHA
    c3f2d7a View commit details

Commits on Jan 5, 2022

  1. Copy the full SHA
    99dc5f5 View commit details

Commits on Mar 3, 2022

  1. Chore: upgrade dev deps

    rpearce committed Mar 3, 2022
    Copy the full SHA
    71f484d View commit details
  2. Merge pull request #83 from rpearce/chore/deps

    Chore: upgrade dev deps
    rpearce authored Mar 3, 2022
    Copy the full SHA
    fcc82ee View commit details
  3. Copy the full SHA
    9409eaf View commit details
  4. Merge pull request #84 from rpearce/fix/ssr-useLayoutEffect

    Fix: SSR useLayoutEffect warning in nextjs
    rpearce authored Mar 3, 2022
    Copy the full SHA
    1599310 View commit details
  5. v2.3.5

    rpearce committed Mar 3, 2022
    Copy the full SHA
    fd003c8 View commit details
Showing with 3,586 additions and 4,549 deletions.
  1. +1 −0 .eslintignore
  2. +1 −0 .eslintrc.js
  3. +22 −0 CHANGELOG.md
  4. +1 −1 README.md
  5. +3,410 −4,523 package-lock.json
  6. +16 −16 package.json
  7. +43 −2 source/index.tsx
  8. +84 −6 source/stories.tsx
  9. +3 −0 source/types/fast-shallow-equal.d.ts
  10. +5 −1 tsconfig.base.json
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -3,3 +3,4 @@
!.storybook/
dist/
docs/
source/types/
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@ module.exports = {
'@typescript-eslint',
'react',
'react-hooks',
'jest',
'jsx-a11y',
],
rules: {
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [2.3.5] - 2022-03-02

### Fixed

* Fix SSR useLayoutEffect warning in
nextjs (https://github.com/rpearce/react-expanding-textarea/pull/84)

## [2.3.4] - 2022-01-03

### Changed

* "Use useLayoutEffect instead of useEffect" (#72)

### Fixed

* "Textarea does not automatically recalculate size if it's parent container
changes size" (#71). This adds a tiny dependency on
[`fast-shallow-equal`](https://www.npmjs.com/package/fast-shallow-equal) and
pairs it with a custom hook to be able to detect shallow changes to a `style`
object if it gets passed. We also are now resizing using a `ResizeObserver`,
if it's supported, as well as if a provided `className` changes.

## [2.3.3] - 2021-10-28

### Fixed
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# react-expanding-textarea

[![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-) [![npm version](https://img.shields.io/npm/v/react-expanding-textarea.svg?style=flat-square)](https://www.npmjs.com/package/react-expanding-textarea) [![npm downloads](https://img.shields.io/npm/dm/react-expanding-textarea.svg?style=flat-square)](https://www.npmjs.com/package/react-expanding-textarea) [![bundlephobia size](https://flat.badgen.net/bundlephobia/minzip/react-expanding-textarea)](https://bundlephobia.com/result?p=react-expanding-textarea)
[![All Contributors](https://img.shields.io/badge/all_contributors-21-orange.svg?style=flat-square)](#contributors-) [![npm version](https://img.shields.io/npm/v/react-expanding-textarea.svg?style=flat-square)](https://www.npmjs.com/package/react-expanding-textarea) [![npm downloads](https://img.shields.io/npm/dm/react-expanding-textarea.svg?style=flat-square)](https://www.npmjs.com/package/react-expanding-textarea) [![bundlephobia size](https://flat.badgen.net/bundlephobia/minzip/react-expanding-textarea)](https://bundlephobia.com/result?p=react-expanding-textarea)

React textarea component to automatically expand and contract your textareas.

7,933 changes: 3,410 additions & 4,523 deletions package-lock.json

Large diffs are not rendered by default.

32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-expanding-textarea",
"version": "2.3.3",
"version": "2.3.5",
"description": "React textarea component to automatically expand and contract your textareas",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
@@ -43,7 +43,6 @@
"react-component"
],
"files": [
"AUTHORS",
"LICENSE",
"README.md",
"dist/"
@@ -64,34 +63,35 @@
"test": "jest"
},
"devDependencies": {
"@storybook/addon-a11y": "^6.3.12",
"@storybook/addon-a11y": "^6.4.19",
"@storybook/addon-knobs": "^6.3.1",
"@storybook/react": "^6.3.12",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.1.2",
"@types/jest": "^27.0.2",
"@types/node": "^17.0.1",
"@types/react": "^17.0.33",
"@storybook/react": "^6.4.19",
"@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.3",
"@types/jest": "^27.4.1",
"@types/node": "^17.0.21",
"@types/react": "^17.0.39",
"@types/react-dom": "^17.0.10",
"@typescript-eslint/eslint-plugin": "^5.2.0",
"@typescript-eslint/parser": "^5.2.0",
"@typescript-eslint/eslint-plugin": "^5.9.0",
"@typescript-eslint/parser": "^5.13.0",
"all-contributors-cli": "^6.20.0",
"eslint": "^8.1.0",
"eslint-plugin-jest": "^25.2.2",
"eslint": "^8.10.0",
"eslint-plugin-jest": "^26.1.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.26.1",
"eslint-plugin-react": "^7.29.2",
"eslint-plugin-react-hooks": "^4.2.0",
"jest": "^27.3.1",
"npm-run-all": "^4.1.5",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"ts-jest": "^27.0.7",
"typescript": "^4.4.4"
"ts-jest": "^27.1.3",
"typescript": "^4.6.2"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0"
},
"dependencies": {
"fast-shallow-equal": "^1.0.0",
"react-with-forwarded-ref": "^0.3.3",
"tslib": "^2.0.3"
}
45 changes: 43 additions & 2 deletions source/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import React, {
CSSProperties,
ChangeEvent,
FC,
MutableRefObject,
RefObject,
TextareaHTMLAttributes,
useCallback,
useLayoutEffect,
useMemo,
useRef,
} from 'react'
import withForwardedRef from 'react-with-forwarded-ref'
import { equal as isShallowEqual } from 'fast-shallow-equal'

// =============================================================================
export interface GetHeight {
(rows: number, el: HTMLTextAreaElement): number
}
@@ -46,6 +50,7 @@ export const getHeight: GetHeight = (rows, el) => {
return Math.max(rowHeight, scrollHeight)
}

// =============================================================================
export interface Resize {
(rows: number, el: HTMLTextAreaElement | null): void
}
@@ -69,6 +74,25 @@ export const resize: Resize = (rows, el) => {
}
}

// =============================================================================
const useShallowObjectMemo = <A,>(obj: A): A => {
const refObject = useRef<A>(obj)
const refCounter = useRef(0)

if (!isShallowEqual(obj, refObject.current)) {
refObject.current = obj
refCounter.current += 1
}

// eslint-disable-next-line react-hooks/exhaustive-deps
return useMemo(() => refObject.current, [refCounter.current])
}

// =============================================================================
const useSSRLayoutEffect =
typeof window === 'undefined' ? Function.prototype : useLayoutEffect

// =============================================================================
type RefFn = (node: HTMLTextAreaElement) => void

export interface TextareaProps
@@ -85,16 +109,33 @@ const ExpandingTextarea: FC<TextareaProps> = ({
...props
}: TextareaProps) => {
const isForwardedRefFn = typeof forwardedRef === 'function'
const style = useShallowObjectMemo<CSSProperties | undefined>(props.style)
const internalRef = useRef<HTMLTextAreaElement>()
const ref = (
isForwardedRefFn || !forwardedRef ? internalRef : forwardedRef
) as MutableRefObject<HTMLTextAreaElement>
const rows = props.rows ? parseInt('' + props.rows, 10) : 0
const { onChange, onInput, ...rest } = props

useLayoutEffect(() => {
useSSRLayoutEffect(() => {
resize(rows, ref.current)
}, [ref, rows, props.value])
}, [props.className, props.value, ref, rows, style])

useSSRLayoutEffect(() => {
if (!window.ResizeObserver) {
return
}

const observer = new ResizeObserver(() => {
resize(rows, ref.current)
})

observer.observe(ref.current)

return () => {
observer.disconnect()
}
}, [ref, rows])

const handleInput = useCallback(
(e) => {
90 changes: 84 additions & 6 deletions source/stories.tsx
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import React, {
useCallback,
useEffect,
useRef,
useState,
} from 'react'
import { number, text } from '@storybook/addon-knobs'
import '../.storybook/base.css'
@@ -77,7 +78,7 @@ export const RegularTextarea: FC = () => {
)
}

export const WithMinimum3Rows: FC = () => {
export const Minimum3Rows: FC = () => {
const textareaRef = useRef<HTMLTextAreaElement>()

const handleChange = useCallback((e) => {
@@ -107,7 +108,7 @@ export const WithMinimum3Rows: FC = () => {
)
}

export const WithMaxHeight: FC = () => {
export const MaxHeight: FC = () => {
const textareaRef = useRef<HTMLTextAreaElement>()

const handleChange = useCallback((e) => {
@@ -144,7 +145,7 @@ interface FunctionRefState {
value: string
}

class FunctionRef extends Component<FunctionRefProps, FunctionRefState> {
class FunctionRefComp extends Component<FunctionRefProps, FunctionRefState> {
el: HTMLTextAreaElement | null = null

constructor(props: FunctionRefProps) {
@@ -184,11 +185,11 @@ class FunctionRef extends Component<FunctionRefProps, FunctionRefState> {
}
}

export const WithFunctionRef: FC = () => {
return <FunctionRef />
export const FunctionRef: FC = () => {
return <FunctionRefComp />
}

export const WithValueFromProps: FC = () => {
export const ValueFromProps: FC = () => {
const textareaRef = useRef<HTMLTextAreaElement>()

useEffect(() => {
@@ -213,3 +214,80 @@ export const WithValueFromProps: FC = () => {
</main>
)
}

export const StyleChanges: FC = () => {
const [isWide0, setIsWide0] = useState(false)
const [isWide1, setIsWide1] = useState(false)
const [, setCounter0] = useState(0)
const [, setCounter1] = useState(0)

const handleClickToggle0 = useCallback(() => {
setIsWide0(x => !x)
}, [])

const handleClickToggle1 = useCallback(() => {
setIsWide1(x => !x)
}, [])

const handleClickCounter0 = useCallback(() => {
setCounter0(x => x + 1)
}, [])

const handleClickCounter1 = useCallback(() => {
setCounter1(x => x + 1)
}, [])

return (
<main>
<h1>Textarea&apos;s width / style changes</h1>
<section>
<h2>Toggling the parent&apos;s width</h2>
<p>
When it goes from smaller to larger, there should not be any extra
whitespace leftover at the bottom from its height when it was small.
This will only work if <code>ResizeObserver</code> is available in
your browser.
</p>
<button onClick={handleClickToggle0} type="button">
Toggle textarea parent&apos;s width
</button>
<button onClick={handleClickCounter0} type="button">
Force a state update (for testing)
</button>
<div>
<label htmlFor="my-textarea0">Please Enter Some Details:</label>
<div style={{ width: isWide0 ? 400 : 200 }}>
<Textarea
defaultValue="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dsa
das
d
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est labor"
id="my-textarea0"
style={{ display: 'block', width: '100%' }}
/>
</div>
</div>
</section>
<section>
<h2>Toggling the textarea&apos;s width</h2>
<button onClick={handleClickToggle1} type="button">
Toggle textarea width
</button>
<button onClick={handleClickCounter1} type="button">
Force a state update (for testing)
</button>
<div>
<label htmlFor="my-textarea1">Please Enter Some Details:</label>
<Textarea
defaultValue="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dsa
das
d
dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est labor"
id="my-textarea1"
style={{ display: 'block', width: isWide1 ? 400 : 200 }}
/>
</div>
</section>
</main>
)
}
3 changes: 3 additions & 0 deletions source/types/fast-shallow-equal.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module "fast-shallow-equal" {
export function equal(a: unknown, b: unknown): boolean
}
6 changes: 5 additions & 1 deletion tsconfig.base.json
Original file line number Diff line number Diff line change
@@ -9,8 +9,12 @@
"lib": ["es2020", "dom"],
"moduleResolution": "node",
"noImplicitAny": true,
"paths": {
"*": ["./source/types/*"]
},
"sourceMap": false,
"strict": true,
"target": "es5"
}
},
"exclude": ["./source/types/*"]
}