Skip to content

About

Portable React map facade with explicitly selected Mapbox and MapLibre adapters.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

209 Commits

Folders and files

Repository files navigation

one-map-react

Acceptance is deferred until release preparation or an explicit owner request. The current handoff links the compact historical checkpoint and remaining release verification. Historical results do not certify the working checkout.

Working Images contract. Images is an intentional extension to react-map-gl: it has no Images component, while its renderers expose loadImage/addImage/removeImage. The small web polyfill registers named assets for symbol and pattern layers; native adapters delegate to their Images wrappers and retain normal SDK restoration/collision behavior. See named style images.

On web, before any mapStyle prop change or raw setStyle call, unmount Images and wait for its effect cleanup to finish in a separate committed step; only then replace the style, and mount fresh Images after readiness. An Images key change in onStyleLoad alone, or unmounting in the same update as the style change, is insufficient. A new keyed Map with reuseMaps={false} is an alternative that resets the camera. Initial usable-style waiting, individual updates/removals and pending-load release remain; automatic replay/retry does not. Existing web image names are conflicts: reserve distinct names and do not mutate owned registrations through raw APIs. Renderer verification remains open.

Working feature-click migration. The map-click migration uses Map.onClick with interactiveLayerIds for source activation. Source.onClick, SourceClickEvent, synthetic source bubbling, selected facade native source hitbox additions and UserLocation.onPress are removed. Raw native Wrapper source onPress/hitbox facilities, source refs/queries/state, live markers/portals and supplied location geometry/accuracy remain. Native filtered clicks retain queries at the actual logical map point, observable errors and stale-map callback protection. The future native focused source stop/bubbling probe is retired; historical scenario IDs and outcomes remain attached to their recorded artifacts. Renderer/query/touch behavior, Metro and native builds/installations remain unverified.

Working control layout uses ordinary application screen or DOM siblings. Common Control, its props, adapter field and selected facade aliases, web custom-control composition, native corner registration/measurement and automatic SDK ornament avoidance are removed. Applications own placement and overlap. Native live-marker hosts/portals, viewport layout, observed camera state and react-native-teleport remain, as do SDK ornament options/defaults, legal attribution/logos and RNMapbox scale-position/resize refresh. See layout migration guidance. New renderer layout, touches, assistive technology, Metro and native builds/installations remain unverified.

The new Expo/Vite example workspace is at its minimal checkpoint. See workspace setup and migration status. Native coexistence acceptance and migration of the legacy scenarios are pending.

one-map-react is being built as a thin React facade over RNMapbox, MapLibre React Native, and react-map-gl. Applications choose a backend at setup and use a shared map API, generally following react-map-gl. The archived rc.11 candidate retains its broader API. This README and its examples describe the working checkout's narrower scope and migration contract for the next incompatible release. The common runtime exports are MapSetup, Map, Source, Layer, Images, Marker, UserLocation and useMap. The working selected refs retain common portable operations and getWrapperMap; advanced calls use borrowed wrapper handles instead of selected method mirrors. Working common native markers reject draggable=true and any drag callback in both render modes; selected native Marker types permit draggable=false and omit drag callbacks. Web dragging and selected raw native annotation dragging remain available. Live native markers retain activation, interactive children, providers, offsets, refresh, coordinate updates, and cleanup. Touch acceptance for native marker changes remains unverified. Working native viewState is a changed camera target: movement from A to B persists while target A is unchanged, including equal-valued replacement objects. A changed target C or explicit jumpTo(A) requests navigation; removing viewState releases the target. Native events and readouts use observations; web controlled behavior remains delegated. Feature-state lifetime follows the selected renderer: explicit set/get/remove operations retain validation, current refs, immutable arguments and SDK errors, while applications own clearing and reapplication after source attachment. Same-ID source remounts and style changes provide no automatic clearing, replay or ordering guarantee. Renderer acceptance for these native changes is unverified; final surface and release verification remain separate. Working current-map capture uses selected wrapper access: RNMapbox takeSnap, MapLibre Native createStaticMapImage, or web getMap().getCanvas().toDataURL after application-selected drawing-buffer setup. MapRef.capture and Map.captureEnabled are removed. Applications own ref checks, readiness, output validation, errors, inclusion, dimensions, files, and bounded waiting. Working independent images use selected WrapperSnapshotManager and WrapperStaticMapImageManager. MapServices.staticMapImage and common capture/image-output types are removed; applications own inputs, output, errors, and waiting. Changed image routes have no renderer acceptance. Native offline operations use selected WrapperOfflineManager exports; common OfflineService, OfflinePack, and MapServices.offline are removed. Applications own metadata discovery, native operation keys, observers, errors, and recovery while preserving existing packs and imported aliases. Location acquisition belongs to the application; common services are removed. Live downloads, imports, cache/database operations and native execution remain unverified. See the offline migration and unit status for review and verification gates.

Working popups use selected web WrapperPopup directly and application-owned native bubbles inside retained Marker children. Common Popup, PopupProps, Adapter.Popup and selected facade Popup aliases are removed. The application owns its close action and lifetime; old common automatic dismissal, focus and maxWidth guarantees are excluded. Native marker hosts, portals and raw annotations/Callout remain. See popup migration guidance and U13 status. Routine checks do not establish renderer interaction or native bubble touch/provider/state retention acceptance.

TF10 prepares the expanded peer ranges, reconciled inventory and package candidate. Its release record distinguishes routine checks from the still-open renderer/native acceptance gates. The package README contains installation, shared map, selected extensions and native patch instructions. Exact current host versions and patch identities live in the support matrix.

TF02–TF09 historical acceptance remains valid only for its recorded artifacts and exercised scope. It does not certify this candidate. Native Mapbox Maps SDK 11.23.1 is now pinned exactly on both platforms; RNMapbox wrapper10.3.x is a separate version.

Working navigation and fullscreen UI uses selected web WrapperNavigationControl and WrapperFullscreenControl. Native camera buttons are ordinary application screen UI; the application chooses activation, unavailable-map handling, errors, and camera commands. Common NavigationControl, FullscreenControl, their props, adapter fields and selected facade aliases are removed. Camera methods/getters, native SDK compass options, and raw selected web controls remain. See control migration guidance. Renderer interaction and native screen button touches remain unverified.

Working scale and attribution UI uses selected web WrapperScaleControl and WrapperAttributionControl, or selected native SDK ornament options. Common ScaleControl, AttributionControl, their props, adapter fields and selected facade aliases are removed. Native scale units and placement follow the selected wrapper; there is no common native width or units policy. SDK defaults, explicit selected positions, legal attribution and logos remain. Native compass options, live-marker hosts/portals and the RNMapbox scale-position/resize workaround remain. See ornament migration guidance. Renderer integration remains unverified.

Working geolocation UI uses raw selected web WrapperGeolocateControl or a native application button with its chosen location integration. Common GeolocateControl, its props, adapter field, selected facade aliases and common following are removed. The raw web control retains upstream geolocation behavior. UserLocation still displays supplied geometry and accuracy; GeolocationPosition, raw SDK pucks and selected follow options remain. Native viewState and locationOptions follow remain mutually exclusive camera owners. Library location services, useMapServices, MapServices, MapSetup.locationProvider, Adapter.services, service contexts/scoping and acquisition-only types/factories are removed. Applications own permissions, acquisition and cleanup through selected SDK or browser facilities; UserLocation is display-only; source activation uses Map.onClick with interactiveLayerIds. See location migration guidance. Browser geolocation, native location button interaction, sensors, Metro and native builds/installations remain unverified.

Development

Use Bun 1.4.1 and Node.js 24.11 or newer on the 24.x line, or Node.js 26 or newer. Vite+ 1.1.0 supplies formatting, linting, unit/web tests, web example builds, and the unbundled library build. TypeScript 7.0.2 checks the four explicit library, test, web-example, and native-example configurations. Wrapper packages are root development dependencies so the library typechecks against real declarations; they remain optional peers of the published package.

bun install --frozen-lockfile
bun run validate

validate checks formatting, documentation links, inventory consistency, types, Vitest unit/web tests, native Jest Testing Library mounts, standalone regression scripts, the library build, and packed-package selection without installing wrapper peers into consumers. bun run test:peers is the checkpoint isolation check that installs one selected peer set into OS-temp consumers; it is not part of validate. Neither command launches a browser, Metro session, simulator, or native build. bun run pack builds an archive in artifacts/.

Run bun run test or vp run test for the complete test chain; vp test run runs only unit/web Vitest tests, and bun run test:native runs native Jest tests. vp check runs formatting and linting; the separate typecheck script remains part of validate so all four TypeScript configurations are checked.

Library ownership and compilation

The common map owns map access, attachment, and common notifications. Map interactions own filtered map-click queries, current callback delivery and pending-result cleanup. Each native adapter provides its own presentation context for live-marker hosts and viewport layout. Native camera observations flow directly from changing and settled adapter callbacks into a separate camera context, which retained marker overlays read without invalidating map-access consumers. Callback guards protect retained web renderers, mutable wrapper callback storage, and facade-owned asynchronous work. Direct native events use wrapper forwarding where it already provides current callbacks. The callback guard audit records each decision and its wrapper source.

The library build runs React Compiler 1.0.0 on original source before TypeScript and JSX lowering. It targets React 19 and ships compiled ESM with the existing declarations and optional-peer boundaries. Consumers need no compiler configuration or additional runtime package. The build reports skipped functions; lifecycle guards and stabilization remain explicit where the compiler cannot optimize them. Context memoization also preserves isolation when tests load uncompiled source.

bun run test:compiled builds the package and runs the web and mocked native regressions against emitted modules, followed by component-specific compiler checks. It is a routine check and launches no real renderer. Source regressions remain under bun run test. Renderer acceptance requires separate authorization under the testing policy.

Selecting a backend

Application setup imports one explicit adapter and wraps the shared map. This excerpt omits the enclosing screen's emptyStyle, initialViewState and routes values:

import { Layer, Map as OneMap, MapSetup, Source } from "one-map-react";
import { adapter } from "one-map-react/mapbox-web";

<MapSetup adapter={adapter}>
  <OneMap mapStyle={emptyStyle} initialViewState={initialViewState}>
    <Source id="routes" type="geojson" data={routes}>
      <Layer
        id="route-line"
        type="line"
        paint={{ "line-color": "#2563eb", "line-width": 3 }}
        layout={{ "line-cap": "round" }}
      />
    </Source>
  </OneMap>
</MapSetup>
Entry Selected backend
one-map-react/mapbox-web react-map-gl with Mapbox GL JS
one-map-react/maplibre-web react-map-gl with MapLibre GL JS
one-map-react/mapbox-native RNMapbox on iOS or Android
one-map-react/maplibre-native MapLibre React Native on iOS or Android

The mapbox and maplibre aliases choose web under the browser condition, native under react-native, and web by default. Browser takes precedence when both conditions are enabled. Explicit paths avoid ambiguity when a tool does not apply those conditions. Mixed engines select different entries in web and native setup modules.

React is a required peer. Host runtimes, wrappers, and SDKs are optional peers so applications install only their chosen backend. Exact versions in the package manifest are candidates from the API research baseline.

Native applications also install react-native-teleport@1.2.1. Native live markers use its portals to retain nested React providers and child state while drawing above the map. The adapter provides the portal setup. Adding this native peer requires linking and rebuilding the application; TF07 portal drawing and touch acceptance passed for the recorded R16 artifact. See the control portal decision and TF07 runtime record.

Examples

Web shells in examples/web-mapbox and examples/web-maplibre need bun run build from the repository root, then bun install and bun run dev in the shell. Native shells in examples/native-mapbox and examples/native-maplibre commit the JavaScript app and Gemfile; build the package, then generate ios/ and android/ with bun scripts/setup-native-example.mjs. Mapbox shells read MAPBOX_ACCESS_TOKEN from the shell or a gitignored .env file. Those installs and launches are not part of validate. See examples/README.md and the TF02 record.

Project documents

Read the requirements, stage plan, and testing policy. The documentation index links the API research and style guides. The TF01 record describes the reset; the TF02 record describes the completed shared map.

The records/ directory preserves historical inventory and compact checkpoint evidence. No historical implementation code is required to develop this project.

License

MIT.

About

Portable React map facade with explicitly selected Mapbox and MapLibre adapters.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages