Skip to content

Commit 8c47e31

Browse files
authored
Fixed an issue with resize not happening after form being reset (#409)
* Fixed an issue with resize not happening after form being reset * improve the fix * Create friendly-masks-rescue.md * non-null assertion
1 parent ae64b9f commit 8c47e31

File tree

9 files changed

+4555
-8982
lines changed

9 files changed

+4555
-8982
lines changed

.changeset/friendly-masks-rescue.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-textarea-autosize": patch
3+
---
4+
5+
Fixed an issue with resize not happening after the containing form being reset

example/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@
2323
<body>
2424
<h1>React &lt;TextareaAutosize /&gt; component</h1>
2525
<div id="main"></div>
26-
<script src="./index.tsx"></script>
26+
<script type="module" src="./index.tsx"></script>
2727
</body>

example/index.tsx

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import * as ReactDOM from 'react-dom';
2+
import { createRoot } from 'react-dom/client';
33
import TextareaAutosize from '../src';
44

55
const range = (n: number): number[] => Array.from({ length: n }, (_, i) => i);
@@ -202,6 +202,36 @@ const WithCustomFont = () => {
202202
);
203203
};
204204

205+
const WithFormReset = () => {
206+
const ref = React.useRef<HTMLFormElement>(null);
207+
return (
208+
<div>
209+
<h2>{'Resettable form.'}</h2>
210+
<div>{'Resizes once the form gets reset.'}</div>
211+
<form ref={ref}>
212+
<TextareaAutosize />
213+
<input type="reset" />
214+
</form>
215+
</div>
216+
);
217+
};
218+
219+
const WithManualFormReset = () => {
220+
const ref = React.useRef<HTMLFormElement>(null);
221+
return (
222+
<div>
223+
<h2>{'Resettable form via manual reset call.'}</h2>
224+
<div>{'Resizes once the form gets reset.'}</div>
225+
<form ref={ref}>
226+
<TextareaAutosize />
227+
<button type="button" onClick={() => ref.current?.reset()}>
228+
{'Reset'}
229+
</button>
230+
</form>
231+
</div>
232+
);
233+
};
234+
205235
const Demo = () => {
206236
return (
207237
<div>
@@ -215,8 +245,10 @@ const Demo = () => {
215245
<OnHeightChangeCallback />
216246
<MultipleTextareas />
217247
<WithCustomFont />
248+
<WithFormReset />
249+
<WithManualFormReset />
218250
</div>
219251
);
220252
};
221253

222-
ReactDOM.render(<Demo />, document.getElementById('main'));
254+
createRoot(document.getElementById('main')!).render(<Demo />);

example/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"private": true,
3+
"type": "module",
34
"scripts": {
4-
"dev": "parcel ./index.html --open",
5-
"build": "parcel build ./index.html --dist-dir ./dist --public-url ."
5+
"dev": "vite",
6+
"build": "vite build"
67
}
78
}

example/vite.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { defineConfig } from 'vite';
2+
import react from '@vitejs/plugin-react';
3+
4+
export default defineConfig({
5+
plugins: [react()],
6+
});

package.json

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,10 @@
7676
"Mateusz Burzyński <[email protected]> (https://github.com/Andarist)"
7777
],
7878
"scripts": {
79-
"prebuild": "npm run clean",
8079
"build": "preconstruct build",
8180
"docs:dev": "npm run dev --prefix example",
8281
"docs:build": "npm run build --prefix example",
8382
"docs:publish": "npm run docs:build && cd ./example/dist && git init && git commit --allow-empty -m 'update docs' && git checkout -b gh-pages && touch .nojekyll && git add . && git commit -am 'update docs' && git push [email protected]:Andarist/react-textarea-autosize gh-pages --force",
84-
"clean": "rimraf dist",
8583
"lint": "eslint --ext .js,.ts,.tsx src",
8684
"prepare": "npm run build",
8785
"changeset": "changeset",
@@ -110,10 +108,11 @@
110108
"@preconstruct/cli": "^2.8.1",
111109
"@testing-library/jest-dom": "^5.16.5",
112110
"@testing-library/react": "^10.4.9",
113-
"@types/react": "^16.14.35",
114-
"@types/react-dom": "^16.9.17",
111+
"@types/react": "^18",
112+
"@types/react-dom": "^18",
115113
"@typescript-eslint/eslint-plugin": "^5.51.0",
116114
"@typescript-eslint/parser": "^5.51.0",
115+
"@vitejs/plugin-react": "^4.3.4",
117116
"babel-eslint": "11.0.0-beta.2",
118117
"bytes": "^3.1.0",
119118
"cross-env": "^7.0.2",
@@ -125,13 +124,12 @@
125124
"jest": "^29.4.2",
126125
"jest-environment-jsdom": "^29.4.2",
127126
"lint-staged": "^10.2.8",
128-
"parcel": "2.0.0-nightly.454",
129127
"prettier": "^2.8.4",
130-
"react": "^16.13.1",
131-
"react-dom": "^16.13.1",
128+
"react": "^18.2.0",
129+
"react-dom": "^18.2.0",
132130
"rimraf": "^3.0.2",
133-
"terser": "^4.7.0",
134-
"typescript": "^5.1.3"
131+
"typescript": "^5.1.3",
132+
"vite": "^6.0.7"
135133
},
136134
"engines": {
137135
"node": ">=10"

src/hooks.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,26 @@ function useListener<
3535
const latestListener = useLatest(listener);
3636
React.useLayoutEffect(() => {
3737
const handler: typeof listener = (ev) => latestListener.current(ev);
38-
3938
// might happen if document.fonts is not defined, for instance
4039
if (!target) {
4140
return;
4241
}
43-
4442
target.addEventListener(type, handler);
4543
return () => target.removeEventListener(type, handler);
4644
}, []);
4745
}
4846

47+
export const useFormResetListener = (
48+
libRef: React.MutableRefObject<HTMLTextAreaElement | null>,
49+
listener: (event: Event) => any,
50+
) => {
51+
useListener(document.body, 'reset', (ev) => {
52+
if (libRef.current!.form === ev.target) {
53+
listener(ev);
54+
}
55+
});
56+
};
57+
4958
export const useWindowResizeListener = (listener: (event: UIEvent) => any) => {
5059
useListener(window, 'resize', listener);
5160
};

src/index.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
useComposedRef,
88
useWindowResizeListener,
99
useFontsLoadedListener,
10+
useFormResetListener,
1011
} from './hooks';
1112
import { noop } from './utils';
1213

@@ -98,6 +99,17 @@ const TextareaAutosize: React.ForwardRefRenderFunction<
9899

99100
if (isBrowser) {
100101
React.useLayoutEffect(resizeTextarea);
102+
useFormResetListener(libRef, () => {
103+
if (!isControlled) {
104+
const node = libRef.current!;
105+
const currentValue = node.value;
106+
requestAnimationFrame(() => {
107+
if (currentValue !== node.value) {
108+
resizeTextarea();
109+
}
110+
});
111+
}
112+
});
101113
useWindowResizeListener(resizeTextarea);
102114
useFontsLoadedListener(resizeTextarea);
103115
return <textarea {...props} onChange={handleChange} ref={ref} />;

0 commit comments

Comments
 (0)