@trackunit/react-map-adapter-shared 0.0.4-alpha-9d327375fc1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,36 @@
1
+ import { type Point2D } from "./polygon";
2
+ /**
3
+ * Filter `rects` to those on the "cursor side" of an opposing rect, preventing
4
+ * the safe-area polygon from extending into a corridor the cursor has clearly
5
+ * turned away from.
6
+ *
7
+ * For every pair of rects (R, S) in the input where the cursor is NOT inside R:
8
+ * if the cursor is on the opposite side of S from R (along the S→R axis,
9
+ * tested via the sign of `dot(cursor − centerS, centerR − centerS)`), R is
10
+ * dropped. Concretely: when cursor is at the entry-rect side of the marker and
11
+ * moving away from the floating live-rect (e.g. stick-marker pill), the live
12
+ * rect is dropped so the polygon does not include it. Rects the cursor is
13
+ * inside are always kept.
14
+ *
15
+ * Pure function. Returns the filtered list in the original order.
16
+ */
17
+ export declare const filterRectsByCursorDirection: (rects: ReadonlyArray<DOMRect | null>, cursorX: number, cursorY: number) => ReadonlyArray<DOMRect | null>;
18
+ /**
19
+ * Build a hover-safe convex-hull polygon spanning every input rect. Each
20
+ * non-null rect contributes its four corners (outward-buffered by `bufferPx`)
21
+ * and the result is the convex hull of all collected corners.
22
+ *
23
+ * Inspired by Floating UI's `safePolygon` middleware (used by `useHover` to
24
+ * keep menus open while the cursor travels toward them). The difference: that
25
+ * implementation builds a pointer-to-single-rect triangle for the standard
26
+ * trigger ↔ floating-element relationship; this one accepts an arbitrary list
27
+ * of rects so a single safe area can span N visible targets — e.g. a stick
28
+ * marker's pill at the tip, an entry-time snapshot of the same pill (used as
29
+ * an animation grace area), and the geographic anchor at the stick's base.
30
+ *
31
+ * The hull is angle-agnostic: it hugs the visible elements at any layout and
32
+ * naturally excludes the dead corners that an axis-aligned bounding box would
33
+ * include. Returns an empty polygon when no rects were provided; callers
34
+ * should treat that as "no safe area" (any cursor position is outside).
35
+ */
36
+ export declare const safePolygon: (rects: ReadonlyArray<DOMRect | null>, bufferPx: number) => ReadonlyArray<Point2D>;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Generate a unique id for one active hover instance. Exposed so callers that
3
+ * orchestrate multiple watchers (e.g. {@link ./attachSafeAreaHoverListeners})
4
+ * can pre-allocate one id and pass it in, so the debug overlay shows a single
5
+ * polygon entry across the listener's lifecycle.
6
+ */
7
+ export declare const allocSafeAreaDebugId: (label: string) => string;
8
+ /**
9
+ * Listen for genuine pointer departure from a DOM marker's safe area. The
10
+ * watcher consults `getHitSurfaceRect` on every pointermove; when the inner
11
+ * query returns nothing transiently (mid-mount, mid-collapse), it falls back
12
+ * to the most recent non-empty rect seen.
13
+ *
14
+ * `entryRect` is the hit-surface rect captured at `mouseenter` time. It acts
15
+ * as a second stable reference so that when the element animates away from a
16
+ * stationary cursor (e.g. stick marker expanding from anchor to tip), the
17
+ * watcher does not fire `onLeave` while the cursor is still inside the
18
+ * original entry area.
19
+ *
20
+ * Returns a cancel function. Caller is responsible for invoking it on
21
+ * hover-end and on cleanup.
22
+ */
23
+ export declare const watchSafeAreaLeave: (host: HTMLElement, onLeave: () => void, entryRect?: DOMRect | null, debugId?: string) => (() => void);
@@ -0,0 +1,45 @@
1
+ import type { MapTheme } from "./primitiveMapTypes";
2
+ import type { ShapeType } from "./interactionTypes";
3
+ import type { ShapeStyle, ShapeStyleOverrides } from "./layerApiTypes";
4
+ export declare const SHAPE_STYLE_DEFAULTS: {
5
+ readonly polygon: {
6
+ readonly fillOpacity: 0.05;
7
+ readonly strokeWidth: 1;
8
+ readonly strokeOpacity: 1;
9
+ };
10
+ readonly line: {
11
+ readonly strokeWidth: 1;
12
+ readonly strokeOpacity: 1;
13
+ };
14
+ readonly point: {
15
+ readonly fillOpacity: 0.2;
16
+ readonly strokeWidth: 1;
17
+ readonly strokeOpacity: 1;
18
+ readonly pointRadius: 5;
19
+ };
20
+ };
21
+ /**
22
+ * Resolve the visual style for a hovered shape.
23
+ *
24
+ * User-provided `base.hovered` overrides take priority; missing properties
25
+ * fall back to auto-computed defaults (darkened/lightened stroke based on theme).
26
+ */
27
+ export declare const resolveHoveredStyle: (base: ShapeStyle, _shapeType: ShapeType, theme: MapTheme) => ShapeStyleOverrides;
28
+ /**
29
+ * Resolve the visual style for a selected shape.
30
+ *
31
+ * User-provided `base.selected` overrides take priority; missing properties
32
+ * fall back to auto-computed defaults (darkened/lightened stroke based on theme,
33
+ * stronger shift than hover).
34
+ */
35
+ export declare const resolveSelectedStyle: (base: ShapeStyle, _shapeType: ShapeType, theme: MapTheme) => ShapeStyleOverrides;
36
+ /**
37
+ * Returns the base, hovered, and selected stroke colors for a shape in one call.
38
+ * Backed by the module-level color cache in colorUtils, so repeated calls with
39
+ * the same inputs are cheap Map lookups.
40
+ */
41
+ export declare const resolveStrokeColors: (style: ShapeStyle, shapeType: ShapeType, theme: MapTheme) => Readonly<{
42
+ base: string;
43
+ hovered: string;
44
+ selected: string;
45
+ }>;
package/src/types.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ import type { GeoJsonBbox } from "@trackunit/geo-json-utils";
2
+ import type { AdapterRendererProps } from "./adapterContract";
3
+ import type { InitialViewport, MapTheme } from "./primitiveMapTypes";
4
+ type CSSProperties = import("react").CSSProperties;
5
+ type ReactNode = import("react").ReactNode;
6
+ /**
7
+ * Unified coordinate format used by both adapters
8
+ * Since these are objects (not tuples), property order doesn't matter in TypeScript
9
+ */
10
+ export type MapCoordinates = Readonly<{
11
+ lat: number;
12
+ lng: number;
13
+ }>;
14
+ /**
15
+ * Base adapter configuration shared by all adapters
16
+ * Each adapter extends this with their specific authentication/config
17
+ */
18
+ export type BaseAdapterConfig = Readonly<{
19
+ /** Language for map labels */
20
+ language?: string;
21
+ /**
22
+ * Region code (ISO 3166-1 alpha-2) that controls how disputed borders and territories
23
+ * are rendered. For example, setting `"MA"` displays Western Sahara as part of Morocco.
24
+ *
25
+ * - Google Maps: passed as the `region` parameter to the Maps JavaScript API.
26
+ * - Mapbox: passed as the `worldview` option to the Mapbox GL JS map constructor.
27
+ *
28
+ * When omitted, each provider uses its default (typically an international/neutral view).
29
+ *
30
+ * @see https://developers.google.com/maps/documentation/javascript/localization
31
+ */
32
+ region?: string;
33
+ /** Map theme - light or dark */
34
+ theme?: MapTheme;
35
+ /** Initial viewport: either center+zoom or bounds */
36
+ initialViewport?: InitialViewport;
37
+ /**
38
+ * Bounds to restrict panning/zoom. GeoJSON format: [minLng, minLat, maxLng, maxLat].
39
+ * - `undefined` (default): no restriction (infinite horizontal scroll)
40
+ * - `null`: no restriction (infinite horizontal scroll)
41
+ * - `GeoJsonBbox`: restrict to custom region (e.g. Europe only)
42
+ * Invalid bboxes are validated with geoJsonBboxSchema; on failure, console.warn is emitted
43
+ * and null (no restriction) is used as fallback.
44
+ */
45
+ restrictBounds?: GeoJsonBbox | null;
46
+ }>;
47
+ /**
48
+ * Base renderer internal props shared by all adapter renderers
49
+ * Each adapter extends this with their specific props (like accessToken, apiKey, etc.)
50
+ */
51
+ export type BaseRendererInternalProps = Readonly<{
52
+ children?: ReactNode;
53
+ className?: string;
54
+ style?: CSSProperties;
55
+ "data-testid"?: string;
56
+ "aria-label"?: string;
57
+ "aria-describedby"?: string;
58
+ theme: MapTheme;
59
+ initialViewport?: InitialViewport;
60
+ }>;
61
+ /**
62
+ * Helper type to create adapter-specific renderer props
63
+ * Combines AdapterRendererProps with BaseRendererInternalProps
64
+ */
65
+ export type AdapterSpecificRendererProps<TAdapterInstance> = Readonly<AdapterRendererProps & BaseRendererInternalProps & {
66
+ adapterInstance: TAdapterInstance;
67
+ }>;
68
+ export {};