From 7914b2d04f59fd3a31fdc5fd27ea4165eb7e3675 Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Mon, 29 Jun 2026 00:43:55 -0700 Subject: [PATCH] fix: guard inert feature detection against undefined HTMLElement.prototype --- .../src/overlays/ariaHideOutside.ts | 5 +++- .../test/overlays/ariaHideOutside.test.js | 26 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/react-aria/src/overlays/ariaHideOutside.ts b/packages/react-aria/src/overlays/ariaHideOutside.ts index fe2b0ca4670..c2270e7e059 100644 --- a/packages/react-aria/src/overlays/ariaHideOutside.ts +++ b/packages/react-aria/src/overlays/ariaHideOutside.ts @@ -16,7 +16,10 @@ import {getOwnerDocument, getOwnerWindow} from '../utils/domHelpers'; import {nodeContains} from '../utils/shadowdom/DOMFunctions'; import {shadowDOM} from 'react-stately/private/flags/flags'; -const supportsInert = typeof HTMLElement !== 'undefined' && 'inert' in HTMLElement.prototype; +const supportsInert = + typeof HTMLElement !== 'undefined' && + HTMLElement.prototype != null && + 'inert' in HTMLElement.prototype; function isAlwaysVisibleNode(node: HTMLElement | SVGElement): boolean { return node.dataset.liveAnnouncer === 'true' || node.dataset.reactAriaTopLayer !== undefined; diff --git a/packages/react-aria/test/overlays/ariaHideOutside.test.js b/packages/react-aria/test/overlays/ariaHideOutside.test.js index 7c9e343b5fd..689e1e2dc03 100644 --- a/packages/react-aria/test/overlays/ariaHideOutside.test.js +++ b/packages/react-aria/test/overlays/ariaHideOutside.test.js @@ -914,3 +914,29 @@ describe('ariaHideOutside with shadow DOM', function () { }); }); }); + +describe('ariaHideOutside inert feature detection', function () { + let originalHTMLElement = global.HTMLElement; + + afterEach(function () { + global.HTMLElement = originalHTMLElement; + jest.resetModules(); + }); + + it('does not throw at import time when HTMLElement.prototype is undefined', function () { + // Simulate bundler/SSR environments where HTMLElement is defined but its prototype is not. + let FakeHTMLElement = function () {}; + FakeHTMLElement.prototype = undefined; + global.HTMLElement = FakeHTMLElement; + + jest.resetModules(); + expect(() => require('../../src/overlays/ariaHideOutside')).not.toThrow(); + }); + + it('does not throw at import time when HTMLElement is undefined (non-DOM SSR)', function () { + global.HTMLElement = undefined; + + jest.resetModules(); + expect(() => require('../../src/overlays/ariaHideOutside')).not.toThrow(); + }); +});