diff --git a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts index fe94a0e20b..74188ef1ff 100644 --- a/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts +++ b/packages/react-native-gesture-handler/src/web/handlers/GestureHandler.ts @@ -64,6 +64,7 @@ export default abstract class GestureHandler implements IGestureHandler { private _activeCursor?: ActiveCursor | undefined = undefined; private _touchAction?: TouchAction | undefined = undefined; private _userSelect?: UserSelect | undefined = undefined; + private needsDOMUpdate = false; // Orchestrator properties private _activationIndex = 0; @@ -833,29 +834,29 @@ export default abstract class GestureHandler implements IGestureHandler { this._activeCursor = config.activeCursor; } - let shouldUpdateDOM = false; - if (config.enableContextMenu !== undefined) { this.enableContextMenu = config.enableContextMenu; - shouldUpdateDOM = true; + this.needsDOMUpdate = true; } if (config.touchAction !== undefined) { this._touchAction = config.touchAction; - shouldUpdateDOM = true; + this.needsDOMUpdate = true; } if (config.userSelect !== undefined) { this._userSelect = config.userSelect; - shouldUpdateDOM = true; + this.needsDOMUpdate = true; } if (enabledChanged) { this.delegate.onEnabledChange(); - } else if (shouldUpdateDOM) { + } else if (this.needsDOMUpdate) { this.delegate.updateDOM(); } + this.needsDOMUpdate = false; + if (this.enabled) { return; } @@ -960,6 +961,7 @@ export default abstract class GestureHandler implements IGestureHandler { this._activeCursor = undefined; this._touchAction = undefined; this._userSelect = undefined; + this.needsDOMUpdate = true; } public onDestroy(): void { diff --git a/packages/react-native-gesture-handler/src/web/handlers/__tests__/GestureHandler.test.ts b/packages/react-native-gesture-handler/src/web/handlers/__tests__/GestureHandler.test.ts index 42656cf598..f5115ee52b 100644 --- a/packages/react-native-gesture-handler/src/web/handlers/__tests__/GestureHandler.test.ts +++ b/packages/react-native-gesture-handler/src/web/handlers/__tests__/GestureHandler.test.ts @@ -1,6 +1,7 @@ import type { Config } from '../../interfaces'; import EventManager from '../../tools/EventManager'; import type { GestureHandlerDelegate } from '../../tools/GestureHandlerDelegate'; +import { GestureHandlerWebDelegate } from '../../tools/GestureHandlerWebDelegate'; import GestureHandler from '../GestureHandler'; import type IGestureHandler from '../IGestureHandler'; @@ -34,6 +35,26 @@ describe('GestureHandler web config reset', () => { expect(handler.enabled).toBe(true); }); + + test('a config without touchAction refreshes the DOM', () => { + const delegate = { + onEnabledChange: jest.fn(), + updateDOM: jest.fn(), + }; + const handler = new TestGestureHandler( + delegate as unknown as GestureHandlerDelegate + ); + handler.setGestureConfig({ enabled: true, touchAction: 'pan-y' }); + + handler.setGestureConfig({ enabled: true }); + + expect(handler.touchAction).toBeUndefined(); + expect(delegate.updateDOM).toHaveBeenCalledTimes(1); + }); + + test('the web delegate ignores DOM updates before init', () => { + expect(() => new GestureHandlerWebDelegate().updateDOM()).not.toThrow(); + }); }); describe('GestureHandler web event manager attachment', () => { diff --git a/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts b/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts index edce77d9a8..1271cd7abc 100644 --- a/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts +++ b/packages/react-native-gesture-handler/src/web/tools/GestureHandlerWebDelegate.ts @@ -76,9 +76,9 @@ export class GestureHandlerWebDelegate this.gestureHandler.attachEventManager(manager) ); - this.updateDOM(); - this.isInitialized = true; + + this.updateDOM(); } detach(): void { @@ -110,6 +110,10 @@ export class GestureHandlerWebDelegate } updateDOM(): void { + if (!this.isInitialized) { + return; + } + this.setUserSelect(); this.setTouchAction(); this.setContextMenu();