From 63daa86b61f4011c62b8796db72af18bb2bd4052 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Fri, 27 Sep 2024 11:39:42 +0200 Subject: [PATCH] Fix crash when using `instanceof HTMLElement` in some environments (#3494) This PR fixes an issue where in some environments where `HTMLElement` is not available (on the server) and AG Grid is used, we crashed. This happens because the `HTMLElement` is polyfilled to an empty object. This means that the `typeof HTMLElement !== 'undefined'` check passed, but the `v instanceof HTMLElement` translated to `v instanceof {}` which is invalid and resulted in a crash... This PR solves it by checking for exactly what we need, in this case whether the `outerHTML` property is available. Alternatively, we could use `return v?.outerHTML ?? v`, but not sure if that's always safe to do. Fixes: #3471 --- packages/@headlessui-react/CHANGELOG.md | 1 + .../src/internal/floating.tsx | 19 ++++++++----------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/packages/@headlessui-react/CHANGELOG.md b/packages/@headlessui-react/CHANGELOG.md index f2a1259..349f117 100644 --- a/packages/@headlessui-react/CHANGELOG.md +++ b/packages/@headlessui-react/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Ensure `Element` is available before polyfilling to prevent crashes in non-browser environments ([#3493](https://github.com/tailwindlabs/headlessui/pull/3493)) +- Fix crash when using `instanceof HTMLElement` in some environments ([#3494](https://github.com/tailwindlabs/headlessui/pull/3494)) ## [2.1.8] - 2024-09-12 diff --git a/packages/@headlessui-react/src/internal/floating.tsx b/packages/@headlessui-react/src/internal/floating.tsx index 216e1f9..cc611d6 100644 --- a/packages/@headlessui-react/src/internal/floating.tsx +++ b/packages/@headlessui-react/src/internal/floating.tsx @@ -133,17 +133,14 @@ export function useFloatingPanel( let stablePlacement = useMemo( () => placement, [ - JSON.stringify( - placement, - typeof HTMLElement !== 'undefined' - ? (_, v) => { - if (v instanceof HTMLElement) { - return v.outerHTML - } - return v - } - : undefined - ), + JSON.stringify(placement, (_, v) => { + // When we are trying to stringify a DOM element, we want to return the + // `outerHTML` of the element. In all other cases, we want to return the + // value as-is. + // It's not safe enough to check whether `v` is an instanceof + // `HTMLElement` because some tools (like AG Grid) polyfill it to be `{}`. + return v?.outerHTML ?? v + }), ] ) useIsoMorphicEffect(() => {