npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-mechanic-map

v0.7.0

Published

React Native wrapper for Mechanic Map

Readme

react-native-mechanic-map

npm version CircleCI Commitizen friendly license

React Native WebView wrapper for Mechanic Map: interactive floors, navigation, highlights, and imperative APIs from JavaScript.

Showcase

Table of contents

Requirements

Installation

npm install react-native-mechanic-map

Native setup

Android

In android/app/build.gradle (not the root android/build.gradle), add:

apply from: "../../node_modules/react-native-mechanic-map/react.gradle"

Rebuild the app. This wires the bundled HTML asset the WebView loads.

iOS

No extra steps beyond react-native-webview setup.

Usage

Quick start

payload is an array of MechanicMapPayload (floors: size, SVG map, locations). The map auto-initializes when the WebView finishes loading unless you set disableAutoInit and call ref.current?.init(...) yourself.

import * as React from 'react';
import MechanicMap, {
  type MechanicMapHandle,
  type MechanicMapPayload,
} from 'react-native-mechanic-map';

const levels: MechanicMapPayload[] = [
  /* id, no, mapWidth, mapHeight, title, map (SVG), locations */
];

const App = () => {
  const mapRef = React.useRef<MechanicMapHandle>(null);

  return (
    <MechanicMap
      ref={mapRef}
      languageCode="en"
      payload={levels}
      options={{
        rotate: 90,
        initialScaleFactor: 1.25,
      }}
      onMapLoaded={() => {
        mapRef.current?.setFloor(0);
      }}
      onLevelSwitched={(level) => {}}
      onLocationOpened={(location) => {}}
      onLocationClosed={() => {}}
      onNavigationCancelled={() => {}}
      onLocationHighlighted={() => {}}
      onMapError={(data) => {}}
    />
  );
};

All WebView props are supported and forwarded. onMapError also receives bridge/WebView failures (bad messages, load/HTTP errors, Android render-process loss) in addition to map script errors.

Props

| Prop | Description | | --- | --- | | payload | MechanicMapPayload[] — levels to show | | languageCode | Map language (default en) | | options | MechanicMapOptions — rotation, zoom, tooltips, colors, etc. | | disableAutoInit | If true, skip auto INIT; call ref.current.init({ payload, options, languageCode }) | | onEvent | Optional catch-all: discriminated union of all map → RN events | | onMapLoaded, onLevelSwitched, … | See Events | | onMapError | Script errors and WebView/bridge failures (MapScriptErrorData) |

Tooltip props (optional): onTooltipNavigationClick, onTooltipDetailClick, onTooltipEnterBuildingClick, onTooltipCloseClick.

Events

| Callback | When | | --- | --- | | onMapLoaded | Map finished loading | | onLevelSwitched | Floor changed (LevelSwitchedData) | | onLevelsReady | All floors processed — floor list ready (LevelsReadyPayload) | | onLevelReady | One floor SVG loaded (LevelReadyPayload) | | onNavigationState | During routing — prev/next floor & multi-building flags (NavigationStatePayload) | | onLocationOpened / onLocationClosed | Location panel opened/closed | | onLocationHighlighted | Batch highlight finished (locationsHighlighted) | | onSingleLocationHighlighted | One location highlighted (locationHighlighted in core) | | onBeaconClicked | Beacon marker tapped (beaconMode) | | onPositionChanged | Map pan/zoom position update | | onNavigationCancelled | User cancelled navigation | | onMapError | Map script or WebView/bridge error |

Use onEvent if you prefer a single handler with a typed EventPayload union (includes bridgeResult for async query replies if you handle promises manually).

Imperative API

Use React.useRef<MechanicMapHandle>(null) and call mapRef.current after onMapLoaded (or whenever the ref is set). Signatures below match src/types.ts.

Floors and lifecycle

mapRef.current?.setFloor(1, { resetZoom: true, hideLocation: true });
mapRef.current?.addLevel(newLevel); // MechanicMapPayload — same shape as `payload[]` items
mapRef.current?.resetLevel();
mapRef.current?.reload();
mapRef.current?.init({ payload: levels, languageCode: 'en', options: {} });

Navigation

import type { Route } from 'react-native-mechanic-map';

const route = {} as Route; // from your pathfinding / backend

mapRef.current?.showNavigation(route, {
  autoMode: true,
  zoomEnabled: true,
  showPins: true,
});
mapRef.current?.closeNavigation(true);

Multi-floor programs, building transitions, and related helpers (mirrors the API on the embedded map instance):

import type {
  MultipleNavigationSegment,
  StartNavigationProgram,
  UpdateLocalizedParams,
} from 'react-native-mechanic-map';

const segment: MultipleNavigationSegment = {
  type: 'outdoor', // or a `building` id for your data
  navigation: route,
};

mapRef.current?.showNavigationWithMultiple([segment, { navigation: otherRoute }], {
  autoMode: false,
  zoomEnabled: true,
  showPins: true,
  groupIndex: 0,
});

const program: StartNavigationProgram = route; // or an array of `MultipleNavigationSegment`
mapRef.current?.startNavigation(program, {
  autoMode: true,
  zoomEnabled: true,
  showPins: true,
});

mapRef.current?.restartNavigation();
mapRef.current?.prevNavigate();
mapRef.current?.nextNavigate();
mapRef.current?.prevBuildingNavigate();
mapRef.current?.nextBuildingNavigate();
mapRef.current?.enterBuilding('building-id');
mapRef.current?.exitBuilding();
mapRef.current?.updateLocalized({
  youAreHereText: 'You are here',
} as UpdateLocalizedParams);
mapRef.current?.changeNavigationPins({ startPin: 'https://.../a.png' });
mapRef.current?.resetNavigationPins();

Shortest-path & data queries (core parity)

These return Promises that resolve when the WebView posts bridgeResult (same helpers as map.calculateSP, map.getLevels(), … in web):

const route = await mapRef.current?.calculateSP('K0_kiosk_01', 'K1_store_50', 'auto');
const routeV2 = await mapRef.current?.calculateSP_v2('KE1_kiosk_09', 'KE7_parkingspot_01', 'auto');

const levels = await mapRef.current?.getLevels();
const nodes = await mapRef.current?.getNodes();
const paths = await mapRef.current?.getPaths();
const multi = await mapRef.current?.isMultiBuilding();

const segment = await mapRef.current?.getNavigationDetails(0);
const prevId = await mapRef.current?.prevLevelId();
const canPrev = await mapRef.current?.hasPrevNavigate();

Floor by level id & single highlight

mapRef.current?.setFloorById('level-uuid', {
  resetZoom: true,
  hideLocation: true,
  autoMode: false,
  willSwitchLevel: true,
});
mapRef.current?.highlightLocation('store-id', {
  zoomEnabled: true,
  duration: 800,
});

Locations

import { LocationTypes } from 'react-native-mechanic-map';

mapRef.current?.showLocation({
  id: 'store-1',
  type: LocationTypes.STORE,
  duration: true,
  closeNavigation: true,
  moveAndZoom: true,
});
mapRef.current?.hideLocation();
mapRef.current?.highlightLocations(['id-a', 'id-b'], {
  type: LocationTypes.STORE,
  zoomEnabled: true,
  duration: 2000,
});

User pin (“current location”)

mapRef.current?.setCurrentLocation(120, 340, { floorNo: 0 });
mapRef.current?.showCurrentLocation();
mapRef.current?.moveCurrentLocation(
  [
    { x: 100, y: 200 },
    { x: 150, y: 220 },
  ],
  { floorNo: 0 }
);
mapRef.current?.removeCurrentLocation();
mapRef.current?.setCurrentLocationFromBlock('anchor-location-id');

Viewport

mapRef.current?.zoomIn();
mapRef.current?.zoomOut();
mapRef.current?.zoomTo(200, 300, { scale: 2, duration: 400, easing: 'easeOut' });
mapRef.current?.moveTo(200, 300, { scale: 1.5, duration: 300 });

Appearance

mapRef.current?.changeColors({
  activeStores: '#22c55e',
  inactiveStores: '#94a3b8',
  background: '#0f172a',
});

Low-level

import { MapActions, type PostMessagePayload } from 'react-native-mechanic-map';

const msg: PostMessagePayload = { action: MapActions.ZOOM_IN };
mapRef.current?.postMessage(msg);

Prefer the typed methods above; postMessage is for advanced or future map actions.

Types

Exported from the package (see src/types.ts / lib/typescript):

| Name | Role | | --- | --- | | MechanicMapPayload | One floor: id, no, mapWidth, mapHeight, title, map (SVG), locations | | MechanicMapOptions | Passed as options; aligns with the embedded Mechanic Map initialization shape — see MechanicMapOptions | | MechanicMapHandle | Ref methods | | Route | Navigation path for showNavigation | | Location, LocationTypes, Color, ColorParams | Locations and theming | | MechanicMapTooltipOptions, MechanicMapTextOnRectMode | Tooltip and rect-label config | | MultipleNavigationSegment, StartNavigationProgram | Multi-leg navigation programs | | UpdateLocalizedParams, NavigateStepOptions | Localization and nav-step options | | EventPayload, LevelsReadyPayload, NavigationStatePayload, BridgeResultPayload, LevelSwitchedData, … | Event typing with onEvent |

MechanicMapOptions

These fields are merged into the embedded map’s runtime configuration (the same keys the bundled map script consumes on init). Use the top-level languageCode prop for locale as well; you can still pass locale here (e.g. availableLanguages) if needed.

Locale & mode

| Field | Notes | | --- | --- | | locale | { language?, availableLanguages? } — unsupported language values fall back to the default | | mode | MapModes.DEFAULT | PICKER (selection / backend mode) | | locationCannotBeSelected | Opaque value from backend when a location must not be selectable | | helperTexts | e.g. { youAreHere: 'You are here' } |

Viewport, scale, rotation

| Field | Notes | | --- | --- | | rotate | 0 | 90 | 180 | 270 — non-multiples of 90 become 0 at runtime | | rotatable | Rotate map content with the SVG | | initialScaleFactor, maxScale | Initial zoom cap and max pinch scale | | zoomLimit | If set, maxScale is derived from parseFloat(zoomLimit) while level data is processed | | animationScale | Scales navigation path animation relative to the map | | height | Container height (px) for the map element | | zoom, zoomToSelected, draggable | Interaction toggles | | mouseWheel | Mouse wheel zoom (mainly relevant in WebView / desktop) |

Selectors (CSS selectors into the SVG; defaults match the bundled plugin)

| Field | | --- | | selector, serviceSelector, rectSelector, noPointerGroupSelector | | rotatable90PathSelector, rotatable180PathSelector, rotatable270TextSelector, rotatable180TextSelector | | rotateServices |

Appearance & layers

| Field | Notes | | --- | --- | | hoverTip, mapFill, landmark, developer | Feature flags | | fillColor | Global fill string consumed by the map script | | strokeOptions | { width?, color? } for navigation stroke | | colors | ColorParams — passed through init; combine with changeColors for runtime updates | | cssAnimation, cssAnimationTime | CSS transition for navigation line; time is a base duration (ms) |

Tooltips

tooltip is a MechanicMapTooltipOptions object:

| Field | Notes | | --- | --- | | enabled | Master switch | | navigation | true / false or { image?, text? } for custom nav button | | detail | true / false or { text? } | | enterBuilding | For multi-building maps: true / false or { text? } | | renderTemplate | Custom tooltip HTML (string) or false (default layout) |

Rect labels (textOnRect)

Can be true / false or an object: enabled, fontFamily, fillColor, fontSize, maxFontSize, minFontSize, mode (MechanicMapTextOnRectMode: 'static' | 'dynamic'), availableModes.

Animation & stack mode

| Field | Notes | | --- | --- | | animation | mode, speedFactor, frequencyFactor, stackAnimation, debugContainer, availableModes, pointModesstackAnimation requires an enabled stackMode or init will not complete | | stackMode | true / false or { enabled?, offset?, switchFloorTime? } (ms) — must be on when animation.stackAnimation is true |

Other

| Field | Notes | | --- | --- | | action | MapActionModes — click behavior (tooltip, zoom, …) | | servicesEnabled | When false, service POIs/layers are not wired (default in the bundled RN HTML is true; override to hide services) | | smartip, beaconMode | Smart / beacon behaviors in the embedded map |

Example app

Screenshots in Showcase are from the example/ app. Open Map options for MechanicMapOptions, and Floor, highlight, showLocation for basic ref calls plus an Extended ref API (bridge) block (setFloorById, startNavigation, showNavigationWithMultiple, building helpers, etc.).

Local library (file:..)

The example pins "react-native-mechanic-map": "file:.." in example/package.json. After editing library src/, run yarn prepare at the package root so lib/ stays current for consumers. TS paths in example/tsconfig.json point at ../src/index.tsx for local types; if editors or Metro act stale, reinstall in example/:

cd example
npm install react-native-mechanic-map   # or: yarn add react-native-mechanic-map

Run

git clone https://github.com/ridvanaltun/react-native-mechanic-map.git
cd react-native-mechanic-map/example
npm install
npm run android
# iOS:
cd ios && pod install && cd ..
npm run ios

Published npm version

To run the example against the registry instead of the parent folder, set a semver range in example/package.json (e.g. "react-native-mechanic-map": "^0.6.0") and npm install in example/.

Contributing

See CONTRIBUTING.md.

License

MIT