@trackunit/react-map 0.1.31-alpha-6a85feaada3.0 → 0.1.31

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.
Files changed (2) hide show
  1. package/README.md +49 -51
  2. package/package.json +11 -11
package/README.md CHANGED
@@ -1,30 +1,59 @@
1
1
  # @trackunit/react-map
2
2
 
3
- Contains core map components.
3
+ Provider-agnostic, hook-first map library for React applications. Switch between Google Maps and Mapbox without touching your application code.
4
4
 
5
- Checklist:
6
- [x]Both Google Maps and Mapbox adapters are implemented.
5
+ ## Design principles
7
6
 
8
- -----
7
+ - **Provider behind an adapter.** Google Maps or Mapbox is passed in as adapter config. Swapping providers is a one-line change; your components, events, and tests are untouched.
8
+ - **Hook-first, TanStack-style.** State, actions, and the renderable component are co-located at the call site via `useMap(adapter)`. No context tree to set up; no provider-specific types leaking into your code.
9
+ - **Resolver props — you decide.** Where choices are genuinely the consumer's — which markers render as DOM vs symbol, what style a hovered shape gets — the library hands you a fully-described context object and takes a small decision back. It never makes the heuristic call behind your back.
10
+ - **Defaults, but always composable.** Every resolver ships a sensible default that is exported for composition. Use it as-is, wrap it, or replace it entirely.
11
+ - **Atomic components.** `MapMarker`, `ClusterMarker`, `MapMarkerIcon`, and `Panel` are usable stand-alone, even outside a map.
12
+ - **Strong types.** Discriminated unions, exhaustive switches, and typed resolver contracts catch mistakes at compile time.
13
+ - **No vendor leakage.** All provider-specific types and APIs belong inside adapters. Nothing outside an adapter may import from `mapbox-gl` or `@vis.gl/react-google-maps`.
14
+ - **Self-contained, portable layers.** A well-designed layer hook owns its own data loading, controls, and settings so it can be dropped into any map without surrounding setup. Concretely, layers should accept a pre-built `filters` object as a prop rather than fetching raw data — the hook owns the query internally and the caller owns the filter shape.
9
15
 
10
- Provider-agnostic map library for React applications. Switch between Google Maps and Mapbox seamlessly without code changes.
16
+ ## Three layers of abstraction
11
17
 
12
- ## Features
18
+ The library is intentionally split into three tiers. **Reach for the highest-level tier that satisfies your needs, and only drop down a layer when you need more control.** Starting at a lower tier than necessary means reinventing abstractions the higher tiers already provide.
13
19
 
14
- - **Provider Agnostic**: Use Google Maps or Mapbox with the same API
15
- - **Type Safe**: Full TypeScript support with zero type assertions
16
- - **Reactive**: Automatic state updates using `useSyncExternalStore`
17
- - **Accessible**: ARIA labels and keyboard navigation built-in
18
- - **Extensible**: Easy to add new map providers
20
+ ### Tier 1 `useMap` and `MapApi`
21
+
22
+ The foundation. Full control over camera, events, controls, panels, annotations, and the adapter surface. Maximum flexibility; you invent everything yourself.
23
+
24
+ Use this when you are building something structurally novel or need to escape a constraint in a higher-level hook.
25
+
26
+ ### Tier 2 — Layer hooks (`useMarkers`, `useShapes`, …)
27
+
28
+ The everyday workhorse. Layer hooks give a high-productivity path to common map features without giving anything away. They surface full library behaviour with sensible defaults you can override one decision at a time via resolver props.
29
+
30
+ The atomic building blocks these compose are exported for reuse too: the output components (`MapMarker`, `ClusterMarker`, `MapMarkerIcon`) and helper hooks (`useAdaptiveMarkerHelpers`, `useShapeLabelHelpers`, …) that surface the default resolver heuristics. This is where almost all map feature work should live.
31
+
32
+ ### Tier 3 — Your domain layer hooks
33
+
34
+ The top tier is your own domain hooks — built on top of Tier 2 primitives. Highly opinionated hooks that own data fetching, display logic, controls, and interaction end-to-end. Closed by design — no customization knobs. If you need something similar but with different behaviour, drop to Tier 2 and compose from the atomic pieces.
35
+
36
+ Every finished, map-ready layer is a Tier 3 hook, so the tier you pick is really your starting point: use a ready-made domain hook as-is, or assemble your own from Tier 2 primitives.
37
+
38
+ **This library exports generic primitives only.** Domain hooks belong in the domain library that serves them — not in `@trackunit/react-map`. Trackunit's own asset and site layer hooks are reference implementations that will be published separately. If you build a domain layer that would be valuable beyond your own app, consider publishing it as its own package too.
19
39
 
20
40
  ## Installation
21
41
 
22
- The library is part of the monorepo. Dependencies are:
23
- - `@vis.gl/react-google-maps` - Google Maps integration
24
- - `mapbox-gl` - Mapbox GL JS integration
25
- - `@trackunit/geo-json-utils` - GeoJSON type definitions
42
+ ```bash
43
+ npm install @trackunit/react-map
44
+ ```
45
+
46
+ Map providers live in separate adapter packages — install whichever one(s) you use alongside it:
47
+
48
+ ```bash
49
+ # Google Maps
50
+ npm install @trackunit/react-map-adapter-google
51
+
52
+ # Mapbox
53
+ npm install @trackunit/react-map-adapter-mapbox
54
+ ```
26
55
 
27
- Import map providers from the adapter packages, not from `@trackunit/react-map`:
56
+ Always import providers from the adapter package, never from `@trackunit/react-map`:
28
57
  - Google Maps: `@trackunit/react-map-adapter-google` (`googleMapsAdapter`, `GoogleApiProvider`, …)
29
58
  - Mapbox: `@trackunit/react-map-adapter-mapbox` (`mapboxAdapter`, …)
30
59
 
@@ -229,42 +258,11 @@ Maps include built-in accessibility features:
229
258
 
230
259
  ## Architecture
231
260
 
232
- For the high-level architecture, motivation, design principles, and rollout strategy, see the **[Map 2026 Design Doc](https://github.com/niceideas/design-docs/blob/main/docs/202602-Manager-Map2026/202602-Manager-Map2026.md)** in the design-docs repo.
233
-
234
- Implementation detail in this repo is split between **[CONTEXT.md](CONTEXT.md)** (domain language and how concepts relate) and **[docs/adr/](docs/adr/)** (short architecture decision records).
235
-
236
- | Document | What it covers |
237
- |----------|---------------|
238
- | [CONTEXT.md](CONTEXT.md) | Glossary: Adapter, Layer Hook, Layer Handle, Layer Port, Entity, Control Config, Annotation, Decoration, and relationships between them |
239
- | [ADR 0001 — Hook-first map API](docs/adr/0001-hook-first-api.md) | `useMap(adapter)` tuple as the primary API; tuple vs object vs component-first |
240
- | [ADR 0002 — Adapter factory pattern](docs/adr/0002-adapter-factory-pattern.md) | Adapter factories, `defineAdapter`, `derive`, keeping provider knowledge at the call site |
241
- | [ADR 0003 — Controls as data](docs/adr/0003-controls-as-data.md) | Control configs as data, discriminated union, middleware pipeline, presentational renderers |
242
- | [ADR 0004 — Declarative LayerPort snapshot](docs/adr/0004-layer-port-declarative-snapshot.md) | `LayerPort.setSnapshot`, single write path, adapter-owned diffing |
243
- | [ADR 0005 — Annotation store on MapApi](docs/adr/0005-annotation-store-on-map-api.md) | `MapApi.annotations`, explicit `api` at call sites, renderer claims |
244
- | [ADR 0006 — Adapters own DOM marker positioning](docs/adr/0006-marker-anchor-ownership.md) | Marker anchors owned by the adapter; no competing transforms in DOM content |
245
- | [ADR 0007 — Antimeridian shapes merged in adapters](docs/adr/0007-antimeridian-merge-in-adapters.md) | Merging split GeoJSON at render time inside adapters, not in app state |
246
- | [ADR 0008 — Map panel store on MapApi](docs/adr/0008-map-panel-store-on-map-api.md) | `MapApi.panels`, `usePanel`, `PanelOrchestrator`, menu presentation via panels |
247
- | [ADR 0009 — Declarative MarkerState](docs/adr/0009-declarative-marker-state.md) | State-driven union prop over imperative marker API |
248
- | [ADR 0010 — Unified marker render tree](docs/adr/0010-unified-marker-render-tree.md) | Always-mounted slots animated via CSS; no separate circle/pill components |
249
- | [ADR 0011 — Stick mode anchor-zero + transform animation](docs/adr/0011-stick-anchor-zero-transform-animation.md) | Zero-size anchor container; CSS three-function transform; no JS width measurement |
250
- | [ADR 0012 — Fixed size ladder with locked pill tier](docs/adr/0012-marker-size-ladder-fixed-pill-tier.md) | Five-tier `MarkerDomSize` enum; pill layout fixed to `md` tier |
251
- | [ADR 0013 — GpsArrowNorth icon](docs/adr/0013-gps-arrow-north-icon.md) | North-facing SVG variant eliminates `heading - 45` magic offset at call sites |
252
- | [ADR 0020 — Map state is split by update frequency](docs/adr/0020-map-state-channels.md) | `MapStatus` on `api.state`, `CameraState` via `useCameraState(api)`, and separate adapter notification channels |
253
- | [@trackunit/react-map-adapter-google README](../map-adapter-google/README.md) | Google Maps adapter: exports, `GoogleApiProvider`, multiple maps |
254
- | [@trackunit/react-map-adapter-mapbox README](../map-adapter-mapbox/README.md) | Mapbox adapter: exports, configuration, typical usage |
255
-
256
- ## Testing
257
-
258
- ```bash
259
- # Run all tests
260
- yarn nx test react-map
261
+ `@trackunit/react-map` is built in independently-useful layers: provider **adapters**, the **`useMap`** foundation and `MapApi`, **layer hooks** (`useMarkers`, `useShapes`, …), and **atomic components** (`MapMarker`, `ClusterMarker`, …). Each tier is usable and testable on its own — see the design principles and three-tier model above.
261
262
 
262
- # Run type checking
263
- yarn nx run react-map:tsc-validate
264
-
265
- # Run linting
266
- yarn nx lint react-map
267
- ```
263
+ Provider integrations ship as separate packages:
264
+ - `@trackunit/react-map-adapter-google` — Google Maps
265
+ - `@trackunit/react-map-adapter-mapbox` — Mapbox
268
266
 
269
267
  ## Adding New Providers
270
268
 
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@trackunit/react-map",
3
- "version": "0.1.31-alpha-6a85feaada3.0",
3
+ "version": "0.1.31",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
7
7
  "node": ">=24.x"
8
8
  },
9
9
  "dependencies": {
10
- "@trackunit/react-components": "2.1.40-alpha-6a85feaada3.0",
11
- "@trackunit/css-class-variance-utilities": "1.13.44-alpha-6a85feaada3.0",
12
- "@trackunit/react-form-components": "2.1.42-alpha-6a85feaada3.0",
13
- "@trackunit/react-core-hooks": "1.17.53-alpha-6a85feaada3.0",
14
- "@trackunit/geo-json-utils": "1.14.47-alpha-6a85feaada3.0",
15
- "@trackunit/i18n-library-translation": "2.0.41-alpha-6a85feaada3.0",
16
- "@trackunit/react-modal": "2.1.44-alpha-6a85feaada3.0",
10
+ "@trackunit/react-components": "2.1.40",
11
+ "@trackunit/css-class-variance-utilities": "1.13.43",
12
+ "@trackunit/react-form-components": "2.1.42",
13
+ "@trackunit/react-core-hooks": "1.17.53",
14
+ "@trackunit/geo-json-utils": "1.14.46",
15
+ "@trackunit/i18n-library-translation": "2.0.41",
16
+ "@trackunit/react-modal": "2.1.44",
17
17
  "react-minimal-pie-chart": "^8.4.0",
18
- "@trackunit/react-map-adapter-shared": "0.0.28-alpha-6a85feaada3.0",
19
- "@trackunit/react-map-color-utils": "0.0.13-alpha-6a85feaada3.0",
20
- "@trackunit/ui-design-tokens": "1.13.44-alpha-6a85feaada3.0",
18
+ "@trackunit/react-map-adapter-shared": "0.0.27",
19
+ "@trackunit/react-map-color-utils": "0.0.12",
20
+ "@trackunit/ui-design-tokens": "1.13.43",
21
21
  "@floating-ui/react": "^0.26.25",
22
22
  "es-toolkit": "^1.39.10",
23
23
  "tailwind-merge": "^2.0.0",