From 8c47e314bc96077fba62505e71fbcd55a7b9a485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 9 Jan 2025 14:01:14 +0100 Subject: [PATCH] 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 --- .changeset/friendly-masks-rescue.md | 5 + example/index.html | 2 +- example/index.tsx | 36 +- example/package.json | 5 +- example/vite.config.ts | 6 + package.json | 16 +- src/hooks.ts | 13 +- src/index.tsx | 12 + yarn.lock | 13442 +++++++++----------------- 9 files changed, 4555 insertions(+), 8982 deletions(-) create mode 100644 .changeset/friendly-masks-rescue.md create mode 100644 example/vite.config.ts diff --git a/.changeset/friendly-masks-rescue.md b/.changeset/friendly-masks-rescue.md new file mode 100644 index 00000000..2b52a4f0 --- /dev/null +++ b/.changeset/friendly-masks-rescue.md @@ -0,0 +1,5 @@ +--- +"react-textarea-autosize": patch +--- + +Fixed an issue with resize not happening after the containing form being reset diff --git a/example/index.html b/example/index.html index bbf44787..d925a80b 100644 --- a/example/index.html +++ b/example/index.html @@ -23,5 +23,5 @@

React <TextareaAutosize /> component

- + diff --git a/example/index.tsx b/example/index.tsx index 0725562b..b4d8a733 100644 --- a/example/index.tsx +++ b/example/index.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import * as ReactDOM from 'react-dom'; +import { createRoot } from 'react-dom/client'; import TextareaAutosize from '../src'; const range = (n: number): number[] => Array.from({ length: n }, (_, i) => i); @@ -202,6 +202,36 @@ const WithCustomFont = () => { ); }; +const WithFormReset = () => { + const ref = React.useRef(null); + return ( +
+

{'Resettable form.'}

+
{'Resizes once the form gets reset.'}
+
+ + + +
+ ); +}; + +const WithManualFormReset = () => { + const ref = React.useRef(null); + return ( +
+

{'Resettable form via manual reset call.'}

+
{'Resizes once the form gets reset.'}
+
+ + + +
+ ); +}; + const Demo = () => { return (
@@ -215,8 +245,10 @@ const Demo = () => { + +
); }; -ReactDOM.render(, document.getElementById('main')); +createRoot(document.getElementById('main')!).render(); diff --git a/example/package.json b/example/package.json index 1a8685ae..9ef448d3 100644 --- a/example/package.json +++ b/example/package.json @@ -1,7 +1,8 @@ { "private": true, + "type": "module", "scripts": { - "dev": "parcel ./index.html --open", - "build": "parcel build ./index.html --dist-dir ./dist --public-url ." + "dev": "vite", + "build": "vite build" } } diff --git a/example/vite.config.ts b/example/vite.config.ts new file mode 100644 index 00000000..0466183a --- /dev/null +++ b/example/vite.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react'; + +export default defineConfig({ + plugins: [react()], +}); diff --git a/package.json b/package.json index 1afc28cb..68334f4c 100644 --- a/package.json +++ b/package.json @@ -76,12 +76,10 @@ "Mateusz BurzyƄski (https://github.com/Andarist)" ], "scripts": { - "prebuild": "npm run clean", "build": "preconstruct build", "docs:dev": "npm run dev --prefix example", "docs:build": "npm run build --prefix example", "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 git@github.com:Andarist/react-textarea-autosize gh-pages --force", - "clean": "rimraf dist", "lint": "eslint --ext .js,.ts,.tsx src", "prepare": "npm run build", "changeset": "changeset", @@ -110,10 +108,11 @@ "@preconstruct/cli": "^2.8.1", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^10.4.9", - "@types/react": "^16.14.35", - "@types/react-dom": "^16.9.17", + "@types/react": "^18", + "@types/react-dom": "^18", "@typescript-eslint/eslint-plugin": "^5.51.0", "@typescript-eslint/parser": "^5.51.0", + "@vitejs/plugin-react": "^4.3.4", "babel-eslint": "11.0.0-beta.2", "bytes": "^3.1.0", "cross-env": "^7.0.2", @@ -125,13 +124,12 @@ "jest": "^29.4.2", "jest-environment-jsdom": "^29.4.2", "lint-staged": "^10.2.8", - "parcel": "2.0.0-nightly.454", "prettier": "^2.8.4", - "react": "^16.13.1", - "react-dom": "^16.13.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", "rimraf": "^3.0.2", - "terser": "^4.7.0", - "typescript": "^5.1.3" + "typescript": "^5.1.3", + "vite": "^6.0.7" }, "engines": { "node": ">=10" diff --git a/src/hooks.ts b/src/hooks.ts index 98296459..b022fecf 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -35,17 +35,26 @@ function useListener< const latestListener = useLatest(listener); React.useLayoutEffect(() => { const handler: typeof listener = (ev) => latestListener.current(ev); - // might happen if document.fonts is not defined, for instance if (!target) { return; } - target.addEventListener(type, handler); return () => target.removeEventListener(type, handler); }, []); } +export const useFormResetListener = ( + libRef: React.MutableRefObject, + listener: (event: Event) => any, +) => { + useListener(document.body, 'reset', (ev) => { + if (libRef.current!.form === ev.target) { + listener(ev); + } + }); +}; + export const useWindowResizeListener = (listener: (event: UIEvent) => any) => { useListener(window, 'resize', listener); }; diff --git a/src/index.tsx b/src/index.tsx index 7ebd1080..c43c3514 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,6 +7,7 @@ import { useComposedRef, useWindowResizeListener, useFontsLoadedListener, + useFormResetListener, } from './hooks'; import { noop } from './utils'; @@ -98,6 +99,17 @@ const TextareaAutosize: React.ForwardRefRenderFunction< if (isBrowser) { React.useLayoutEffect(resizeTextarea); + useFormResetListener(libRef, () => { + if (!isControlled) { + const node = libRef.current!; + const currentValue = node.value; + requestAnimationFrame(() => { + if (currentValue !== node.value) { + resizeTextarea(); + } + }); + } + }); useWindowResizeListener(resizeTextarea); useFontsLoadedListener(resizeTextarea); return