Skip to content

@diginestai/ui — UI Component Library

@diginestai/ui provides the complete set of pre-built React controls, panels, and overlays for DigiNest Maps. All components are built with shadcn/ui primitives and CSS custom properties from @diginestai/theme.


Installation

bash
pnpm add @diginestai/ui

Quick Start

tsx
import { FloorSwitcher, SearchBar, WayfindingPanel } from '@diginestai/ui';
import { SpatialProvider, SpatialMap } from '@diginestai/core';

export default function App() {
  return (
    <SpatialProvider>
      <SpatialMap style="pmtiles://...">
        <FloorSwitcher position="top-right" />
        <SearchBar placeholder="Search spaces..." />
        <WayfindingPanel />
      </SpatialMap>
    </SpatialProvider>
  );
}

Component Catalogue

<FloorSwitcher>

Vertical list of floors for multi-storey buildings. Subscribes to useFloor() — no extra wiring needed.

PropTypeDefaultDescription
positionPosition'top-right'Map corner anchor ('top-left', 'top-right', 'bottom-left', 'bottom-right').
compactbooleanfalseRender a condensed single-button variant.
classNamestringExtra CSS class names.

Autocomplete search over IMDF unit names, amenity categories, and occupant records.

PropTypeDefaultDescription
placeholderstring'Search…'Input placeholder text.
onSelect(feature: UnitFeature) => voidFired when the user picks a suggestion.
maxSuggestionsnumber8Max suggestions shown in the dropdown.
debounceMsnumber200Input debounce delay.

<WayfindingPanel>

Origin/destination input panel that calls @diginestai/wayfinding to compute multi-floor routes.

PropTypeDefaultDescription
defaultOriginstringUnit ID to pre-fill as route origin.
defaultDestinationstringUnit ID to pre-fill as route destination.
accessiblebooleanfalseRestrict graph to accessible paths only.
onRouteComputed(route: NavigationRoute) => voidFired after a successful route is found.

<SpaceCard>

Rich floating detail card anchored to a selected space.

PropTypeDefaultDescription
spaceIdstringIMDF unit ID to display.
positionSpaceCardPosition'bottom-center'Screen anchor position.
onClose() => voidFired when the card is dismissed.
renderExtra(unit: UnitFeature) => ReactNodeSlot for custom content below the default fields.

<CategoryFilter>

Horizontal chip row for filtering visible units by amenity category.

PropTypeDefaultDescription
categoriesstring[]Ordered list of category labels.
selectedstring[][]Currently active categories.
onChange(selected: string[]) => voidFired on chip toggle.
multiSelectbooleantrueAllow selecting multiple categories simultaneously.

<KioskMode>

Full-screen kiosk layout wrapper with idle-reset timer. Wraps <SpatialMap> and overlays branding, a clock, and a "tap to start" prompt.

PropTypeDefaultDescription
idleTimeoutMsnumber60000Milliseconds of inactivity before reset.
logostringURL of the venue logo image.
venueNamestringVenue display name shown in the header.
onReset() => voidCalled when the idle reset triggers.

<MapTour>

Animated camera tour that steps through a sequence of keyframes.

PropTypeDefaultDescription
keyframesCameraKeyframe[]Ordered array of { center, zoom, pitch, bearing, durationMs }.
autoPlaybooleanfalseStart tour on mount.
loopbooleanfalseLoop back to first keyframe after last.
onStep(index: number) => voidFired on each keyframe transition.
refRef<MapTourHandle>Imperative handle with .play(), .pause(), .reset().

<Minimap>

Picture-in-picture overview map overlay.

PropTypeDefaultDescription
sizeMinimapSize'md''sm' (120 px), 'md' (180 px), or 'lg' (240 px).
positionPosition'bottom-right'Map corner anchor.
zoomnumberactive zoom − 4Override minimap zoom level.

<EmbedWidget>

iframe-safe <SpatialMap> wrapper with postMessage API. Relays host commands (floor switch, wayfinding, theme) and emits map events back to the parent frame.

PropTypeDefaultDescription
allowedOriginsstring[]['*']Origins from which postMessage commands are accepted.
stylestringPMTiles or MapLibre style URL.
initialFloorstringFloor ID to activate on load.

<PrintMapStyler>

Developer tool component for customising SVG/PNG print export appearance. Exposes colour pickers and layer toggles that feed into exportFloorSVG.

PropTypeDefaultDescription
floorIdstringTarget floor to export.
onExport(svg: string) => voidFired with the rendered SVG string.
defaultOptionsSVGExportOptionsPre-populate export options.


<WayfindingControl> (v2.16, #380)

Draggable start/end marker pair with live A* route overlay rendered directly on the map canvas. No separate panel required.

tsx
import { WayfindingControl, useWayfinding } from '@diginestai/ui';

export function MapView({ graph, obstacles }) {
  const { path, startCoord, stopCoord, reset } = useWayfinding(graph, obstacles);

  return (
    <SpatialMap buildings={buildings}>
      <WayfindingControl graph={graph} obstacles={obstacles} onPathChange={console.log} />
    </SpatialMap>
  );
}
PropTypeDefaultDescription
graphWayfindingGraphrequiredPre-built navigation graph from @diginestai/wayfinding.
obstaclesstring[][]Unit IDs to treat as blocked.
onPathChange(path: NavigationPath | null) => voidFired on each route recalculation.
startLabelstring'Start'Label shown on the start marker tooltip.
stopLabelstring'Stop'Label shown on the stop marker tooltip.

useWayfinding hook:

typescript
function useWayfinding(
  graph: WayfindingGraph,
  obstacles?: string[]
): {
  setStart: (coord: [number, number]) => void;
  setStop: (coord: [number, number]) => void;
  path: NavigationPath | null;
  startCoord: [number, number] | null;
  stopCoord: [number, number] | null;
  reset: () => void;
};

<FeaturePopup> + useFeatureClick (v2.16, #378)

Click-to-inspect popup anchored to any MapLibre feature.

tsx
import { FeaturePopup, useFeatureClick } from '@diginestai/ui';

function Overlay({ map }) {
  const { feature, lngLat, close } = useFeatureClick(map, ['floor-fill', 'poi-layer']);

  return feature ? (
    <FeaturePopup
      feature={feature}
      lngLat={lngLat}
      onClose={close}
    />
  ) : null;
}
PropTypeDescription
featuremaplibregl.MapGeoJSONFeatureThe clicked feature.
lngLatmaplibregl.LngLatClick coordinates for popup positioning.
onClose() => voidCalled when the close button is clicked.
renderContent(feature) => ReactNodeCustom content renderer (defaults to a property table).

useFeatureClick hook:

typescript
function useFeatureClick(
  map: maplibregl.Map | null,
  layerIds: string[]
): {
  feature: maplibregl.MapGeoJSONFeature | null;
  lngLat: maplibregl.LngLat | null;
  close: () => void;
};

<IndoorSearch> + useIndoorSearch (v2.16, #379)

Client-side room and POI search with fitBounds on selection.

tsx
import { IndoorSearch, useIndoorSearch } from '@diginestai/ui';

function SearchOverlay({ features }) {
  const { query, setQuery, results } = useIndoorSearch(features, ['name', 'category']);

  return (
    <IndoorSearch
      features={features}
      searchKeys={['name', 'category']}
      onSelect={(f) => map.fitBounds(bbox(f), { padding: 40 })}
    />
  );
}
PropTypeDefaultDescription
featuresGeoJSON.Feature[]requiredPool of IMDF features to search.
searchKeysstring[]['name']Property keys to match against.
onSelect(feature: GeoJSON.Feature) => voidFired on result selection.
placeholderstring'Search rooms…'Input placeholder text.
maxResultsnumber10Max results shown.

useIndoorSearch hook:

typescript
function useIndoorSearch(
  features: GeoJSON.Feature[],
  searchKeys: string[]
): {
  query: string;
  setQuery: (q: string) => void;
  results: GeoJSON.Feature[];
};

POI Symbol Layer (v2.16, #377, #385)

Adds inline SVG icon symbols for IMDF Point features. Zoom-scales between 0.6× and 1.0×; filters out wall and footway features automatically.

typescript
import {
  addPOISymbolLayer,
  updatePOISymbolLayer,
  removePOISymbolLayer,
  POI_SOURCE_ID,
  POI_LAYER_ID,
} from '@diginestai/core';

// Add on map load
addPOISymbolLayer(map, poiFeatureCollection);

// Update when features change
updatePOISymbolLayer(map, updatedFeatureCollection);

// Remove on unmount
removePOISymbolLayer(map);
ConstantValueDescription
POI_SOURCE_ID'bs-poi-source'MapLibre source ID for POI GeoJSON.
POI_LAYER_ID'bs-poi-layer'MapLibre layer ID for the symbol layer.

i18n Components

All UI text is internationalised via @diginestai/i18n (re-exported from this package). See /packages/i18n for locale and translation docs.

tsx
import { I18nProvider } from '@diginestai/ui';

<I18nProvider locale="fr">
  <App />
</I18nProvider>

Released under commercial licensing.