diff --git a/src/components/__tests__/advanced-marker.test.tsx b/src/components/__tests__/advanced-marker.test.tsx
index e6727436..92bdbc24 100644
--- a/src/components/__tests__/advanced-marker.test.tsx
+++ b/src/components/__tests__/advanced-marker.test.tsx
@@ -253,6 +253,54 @@ describe('map and marker-library loaded', () => {
(google.maps as any).version = '3.62.9';
});
+ // Regression test for issue #867: when the consumer provides only
+ // `anchorTop` (or only `anchorLeft`), the library must not assign
+ // `undefined` to the unspecified side. Doing so clobbers the
+ // default value the Google Maps JS API sets up, and combined with
+ // `gmpDraggable = true` the API subsequently throws
+ // `TypeError: Failed to execute 'appendChild' on 'Node'` while
+ // wiring up the drag handle.
+ test('only the provided anchor prop is assigned, the other side is left untouched (#867)', async () => {
+ // The mock AdvancedMarkerElement is a plain class extending the
+ // jest-mocks HTMLElement; it does not pre-define `anchorLeft` /
+ // `anchorTop` on instances. Therefore, when the library assigns
+ // `undefined` to the unprovided side, an own property with
+ // value `undefined` is created. After the fix, that own property
+ // must NOT exist because the library must not touch the side the
+ // consumer did not provide.
+ const {unmount} = render(
+
+
+
+ );
+
+ const marker = await waitForMockInstance(
+ google.maps.marker.AdvancedMarkerElement
+ );
+ expect(marker.anchorTop).toBe('-90%');
+ // After the fix: anchorLeft must remain unset (no own property).
+ expect(
+ Object.getOwnPropertyDescriptor(marker, 'anchorLeft')
+ ).toBeUndefined();
+
+ unmount();
+
+ render(
+
+
+
+ );
+
+ const marker2 = await waitForMockInstance(
+ google.maps.marker.AdvancedMarkerElement
+ );
+ expect(marker2.anchorLeft).toBe('10px');
+ // After the fix: anchorTop must remain unset (no own property).
+ expect(
+ Object.getOwnPropertyDescriptor(marker2, 'anchorTop')
+ ).toBeUndefined();
+ });
+
test('anchorLeft/anchorTop should have precedence over anchorPoint', async () => {
const consoleWarnSpy = jest
.spyOn(console, 'warn')
diff --git a/src/components/advanced-marker.tsx b/src/components/advanced-marker.tsx
index 66133a50..3d9efa4f 100644
--- a/src/components/advanced-marker.tsx
+++ b/src/components/advanced-marker.tsx
@@ -365,8 +365,14 @@ function useAdvancedMarkerAnchoring(
);
}
- marker.anchorLeft = anchorLeft;
- marker.anchorTop = anchorTop;
+ // Only assign properties that were actually provided by the consumer.
+ // Assigning `undefined` to `anchorLeft`/`anchorTop` would clobber the
+ // element's default value, and the Google Maps JS API can subsequently
+ // fail with a `TypeError: Failed to execute 'appendChild' on 'Node'`
+ // when it later reads these properties while setting up drag handles
+ // (see issue #867).
+ if (anchorLeft !== undefined) marker.anchorLeft = anchorLeft;
+ if (anchorTop !== undefined) marker.anchorTop = anchorTop;
// when anchorLeft and/or anchorTop are set, we'll ignore the anchorPoint
if (anchorPoint !== undefined) {