diff --git a/.gitignore b/.gitignore index 32dd1191..d6bafd75 100644 --- a/.gitignore +++ b/.gitignore @@ -41,3 +41,4 @@ bun.lockb es docs-dist .vercel +.vscode diff --git a/src/pickAttrs.ts b/src/pickAttrs.ts index 70dea0b9..f683b251 100644 --- a/src/pickAttrs.ts +++ b/src/pickAttrs.ts @@ -17,7 +17,12 @@ const eventsName = `onCopy onCut onPaste onCompositionEnd onCompositionStart onC onMouseEnter onMouseLeave onMouseMove onMouseOut onMouseOver onMouseUp onSelect onTouchCancel onTouchEnd onTouchMove onTouchStart onScroll onWheel onAbort onCanPlay onCanPlayThrough onDurationChange onEmptied onEncrypted onEnded onError onLoadedData onLoadedMetadata - onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting onLoad onError`; + onLoadStart onPause onPlay onPlaying onProgress onRateChange onSeeked onSeeking onStalled onSuspend onTimeUpdate onVolumeChange onWaiting onLoad + onPointerDown onPointerMove onPointerUp onPointerCancel onPointerEnter onPointerLeave onPointerOver onPointerOut onGotPointerCapture onLostPointerCapture + onAnimationStart onAnimationEnd onAnimationIteration + onTransitionEnd onTransitionRun onTransitionStart onTransitionCancel + onBeforeInput onReset onInvalid + onAuxClick onToggle onBeforeToggle onCancel onClose onResize onScrollEnd`; const propList = `${attributes} ${eventsName}`.split(/[\s\n]+/); diff --git a/tests/utils.test.ts b/tests/utils.test.ts index 580c303c..842c172d 100644 --- a/tests/utils.test.ts +++ b/tests/utils.test.ts @@ -1,3 +1,5 @@ +import { readFileSync } from 'fs'; +import { join, dirname } from 'path'; import pickAttrs from '../src/pickAttrs'; import get from '../src/utils/get'; import set, { mergeWith, merge } from '../src/utils/set'; @@ -330,5 +332,26 @@ describe('utils', () => { role: 'button', }); }); + + it('forwards every React DOM event handler', () => { + const dts = readFileSync( + join( + dirname(require.resolve('@types/react/package.json')), + 'index.d.ts', + ), + 'utf8', + ); + + const isCapturePhase = (n: string) => + n.endsWith('Capture') && !/^on(Got|Lost)PointerCapture$/.test(n); + const reactEvents = [...dts.matchAll(/\bon[A-Z]\w*(?=\?:)/g)] + .map(m => m[0]) + .filter(n => !isCapturePhase(n)); + + const dropped = reactEvents.filter( + e => pickAttrs({ [e]: 1 }, { attr: true })[e] === undefined, + ); + expect(dropped).toEqual([]); + }); }); });