From 4233de7c71fb9b78a0883fcefb0b352cf4f82a6b Mon Sep 17 00:00:00 2001 From: TayfurYldz <238304586+TayfurYldz@users.noreply.github.com> Date: Wed, 16 Sep 2026 17:55:50 +0300 Subject: [PATCH] feat: expose markerColor and zIndex on Marker --- README.md | 2 + package/src/hooks/useCollectedOverlays.ts | 36 ++---------- package/src/native/specs/overlays.ts | 6 +- .../__tests__/collectMarkerOverlay.test.ts | 57 +++++++++++++++++++ package/src/overlays/collectMarkerOverlay.ts | 42 ++++++++++++++ package/src/types/overlays.ts | 6 ++ 6 files changed, 116 insertions(+), 33 deletions(-) create mode 100644 package/src/overlays/__tests__/collectMarkerOverlay.test.ts create mode 100644 package/src/overlays/collectMarkerOverlay.ts diff --git a/README.md b/README.md index 2ab31d1..14e8d61 100644 --- a/README.md +++ b/README.md @@ -351,6 +351,8 @@ Additional props: | `rotation` | `0` | Clockwise rotation in degrees | | `flat` | `false` | Rotate with map plane (Google Maps; MapKit approximates via view transform) | | `opacity` | `1` | Marker opacity from 0 to 1 | +| `markerColor` | — | Color applied to the default marker | +| `zIndex` | — | Drawing order relative to other map overlays | Platform notes: diff --git a/package/src/hooks/useCollectedOverlays.ts b/package/src/hooks/useCollectedOverlays.ts index 8c43536..836521b 100644 --- a/package/src/hooks/useCollectedOverlays.ts +++ b/package/src/hooks/useCollectedOverlays.ts @@ -19,6 +19,7 @@ import { Marker } from '../components/Marker'; import { Polygon } from '../components/Polygon'; import { Polyline } from '../components/Polyline'; import { collectGeojsonOverlays } from '../overlays/collectGeojsonOverlays'; +import { collectMarkerOverlay } from '../overlays/collectMarkerOverlay'; import { resolveOverlayId, tappableFromPress, @@ -31,7 +32,6 @@ import type { } from '../overlays/overlayType'; import { OverlayType, overlayCallbackKey } from '../overlays/overlayType'; import { resolveMarkerImage } from '../overlays/resolveMarkerImage'; -import { normalizeEnteringAnimation } from '../utils/enteringAnimation'; export interface CollectedOverlays { markers: MarkerDescriptor[]; @@ -72,35 +72,11 @@ const overlayCollectors: OverlayCollector[] = [ overlayType: OverlayType.Marker, component: Marker, collect: (child, state) => { - const props = child.props as MarkerProps; - const id = resolveOverlayId(props.id, 'marker', state.markerIndex); - state.markerIndex += 1; - - state.markers.push({ - id, - coordinate: props.coordinate, - title: props.title, - subtitle: props.subtitle, - draggable: props.draggable, - clusterable: props.clusterable, - image: resolveMarkerImage(props.image), - anchor: props.anchor, - centerOffset: props.centerOffset, - rotation: props.rotation, - flat: props.flat, - opacity: props.opacity, - enteringAnimation: normalizeEnteringAnimation(props.enteringAnimation), - }); - state.registry.set(overlayCallbackKey(OverlayType.Marker, id), { - onPress: props.onPress, - onDragEnd: props.onDragEnd, - }); - if (props.onPress != null) { - state.hasMarkerPress = true; - } - if (props.onDragEnd != null) { - state.hasMarkerDragEnd = true; - } + collectMarkerOverlay( + child.props as MarkerProps, + state, + resolveMarkerImage, + ); }, }, { diff --git a/package/src/native/specs/overlays.ts b/package/src/native/specs/overlays.ts index fe516c1..c05a4c6 100644 --- a/package/src/native/specs/overlays.ts +++ b/package/src/native/specs/overlays.ts @@ -74,6 +74,9 @@ export interface MarkerDescriptor { /** Color applied to the default marker when no custom image is set. */ markerColor?: string; + /** Drawing order relative to other map overlays. */ + zIndex?: number; + /** Anchor point on the image relative to the coordinate (default bottom-center). */ anchor?: MarkerAnchor; @@ -89,9 +92,6 @@ export interface MarkerDescriptor { /** Opacity from 0 to 1. */ opacity?: number; - /** Drawing order relative to other map overlays. */ - zIndex?: number; - /** Entering animation override for this marker. */ enteringAnimation?: OverlayEnteringAnimationDescriptor; } diff --git a/package/src/overlays/__tests__/collectMarkerOverlay.test.ts b/package/src/overlays/__tests__/collectMarkerOverlay.test.ts new file mode 100644 index 0000000..f7169d0 --- /dev/null +++ b/package/src/overlays/__tests__/collectMarkerOverlay.test.ts @@ -0,0 +1,57 @@ +import { describe, expect, test } from 'bun:test'; +import type { MarkerProps } from '../../types/overlays'; +import type { OverlayCollectorState } from '../overlayCollect'; + +import { collectMarkerOverlay } from '../collectMarkerOverlay'; + +const resolveMarkerImage = () => undefined; + +function createState(): OverlayCollectorState { + return { + registry: new Map(), + markers: [], + polylines: [], + polygons: [], + circles: [], + markerIndex: 0, + polylineIndex: 0, + polygonIndex: 0, + circleIndex: 0, + geojsonIndex: 0, + hasMarkerPress: false, + hasMarkerDragEnd: false, + hasPolylinePress: false, + hasPolygonPress: false, + hasCirclePress: false, + }; +} + +describe('collectMarkerOverlay', () => { + test('forwards markerColor and zIndex to the descriptor', () => { + const state = createState(); + const props: MarkerProps = { + id: 'styled', + coordinate: { latitude: 52.2297, longitude: 21.0122 }, + markerColor: '#FF9500', + zIndex: 5, + }; + + collectMarkerOverlay(props, state, resolveMarkerImage); + + expect(state.markers[0]?.markerColor).toBe('#FF9500'); + expect(state.markers[0]?.zIndex).toBe(5); + }); + + test('leaves markerColor and zIndex unset when omitted', () => { + const state = createState(); + + collectMarkerOverlay( + { coordinate: { latitude: 52.2297, longitude: 21.0122 } }, + state, + resolveMarkerImage, + ); + + expect(state.markers[0]?.markerColor).toBeUndefined(); + expect(state.markers[0]?.zIndex).toBeUndefined(); + }); +}); diff --git a/package/src/overlays/collectMarkerOverlay.ts b/package/src/overlays/collectMarkerOverlay.ts new file mode 100644 index 0000000..6553c4d --- /dev/null +++ b/package/src/overlays/collectMarkerOverlay.ts @@ -0,0 +1,42 @@ +import type { MarkerImage, MarkerImageSource } from '../native/specs/overlays'; +import type { MarkerProps } from '../types/overlays'; +import { normalizeEnteringAnimation } from '../utils/enteringAnimation'; +import { resolveOverlayId, type OverlayCollectorState } from './overlayCollect'; +import { OverlayType, overlayCallbackKey } from './overlayType'; + +export type MarkerImageResolver = ( + source: MarkerImageSource | undefined, +) => MarkerImage | undefined; + +export function collectMarkerOverlay( + props: MarkerProps, + state: OverlayCollectorState, + resolveMarkerImage: MarkerImageResolver, +): void { + const id = resolveOverlayId(props.id, 'marker', state.markerIndex); + state.markerIndex += 1; + + state.markers.push({ + id, + coordinate: props.coordinate, + title: props.title, + subtitle: props.subtitle, + draggable: props.draggable, + clusterable: props.clusterable, + image: resolveMarkerImage(props.image), + markerColor: props.markerColor, + zIndex: props.zIndex, + anchor: props.anchor, + centerOffset: props.centerOffset, + rotation: props.rotation, + flat: props.flat, + opacity: props.opacity, + enteringAnimation: normalizeEnteringAnimation(props.enteringAnimation), + }); + state.registry.set(overlayCallbackKey(OverlayType.Marker, id), { + onPress: props.onPress, + onDragEnd: props.onDragEnd, + }); + if (props.onPress != null) state.hasMarkerPress = true; + if (props.onDragEnd != null) state.hasMarkerDragEnd = true; +} diff --git a/package/src/types/overlays.ts b/package/src/types/overlays.ts index b64333f..5759396 100644 --- a/package/src/types/overlays.ts +++ b/package/src/types/overlays.ts @@ -106,6 +106,12 @@ export interface MarkerProps { /** Custom marker image. */ image?: MarkerImageSource; + /** Color applied to the default marker when no custom image is set. */ + markerColor?: string; + + /** Drawing order relative to other map overlays. */ + zIndex?: number; + /** Anchor point on the image relative to the coordinate (default bottom-center). */ anchor?: MarkerAnchor;