@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
pnpm add @diginestai/uiQuick Start
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.
| Prop | Type | Default | Description |
|---|---|---|---|
position | Position | 'top-right' | Map corner anchor ('top-left', 'top-right', 'bottom-left', 'bottom-right'). |
compact | boolean | false | Render a condensed single-button variant. |
className | string | — | Extra CSS class names. |
<SearchBar>
Autocomplete search over IMDF unit names, amenity categories, and occupant records.
| Prop | Type | Default | Description |
|---|---|---|---|
placeholder | string | 'Search…' | Input placeholder text. |
onSelect | (feature: UnitFeature) => void | — | Fired when the user picks a suggestion. |
maxSuggestions | number | 8 | Max suggestions shown in the dropdown. |
debounceMs | number | 200 | Input debounce delay. |
<WayfindingPanel>
Origin/destination input panel that calls @diginestai/wayfinding to compute multi-floor routes.
| Prop | Type | Default | Description |
|---|---|---|---|
defaultOrigin | string | — | Unit ID to pre-fill as route origin. |
defaultDestination | string | — | Unit ID to pre-fill as route destination. |
accessible | boolean | false | Restrict graph to accessible paths only. |
onRouteComputed | (route: NavigationRoute) => void | — | Fired after a successful route is found. |
<SpaceCard>
Rich floating detail card anchored to a selected space.
| Prop | Type | Default | Description |
|---|---|---|---|
spaceId | string | — | IMDF unit ID to display. |
position | SpaceCardPosition | 'bottom-center' | Screen anchor position. |
onClose | () => void | — | Fired when the card is dismissed. |
renderExtra | (unit: UnitFeature) => ReactNode | — | Slot for custom content below the default fields. |
<CategoryFilter>
Horizontal chip row for filtering visible units by amenity category.
| Prop | Type | Default | Description |
|---|---|---|---|
categories | string[] | — | Ordered list of category labels. |
selected | string[] | [] | Currently active categories. |
onChange | (selected: string[]) => void | — | Fired on chip toggle. |
multiSelect | boolean | true | Allow 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.
| Prop | Type | Default | Description |
|---|---|---|---|
idleTimeoutMs | number | 60000 | Milliseconds of inactivity before reset. |
logo | string | — | URL of the venue logo image. |
venueName | string | — | Venue display name shown in the header. |
onReset | () => void | — | Called when the idle reset triggers. |
<MapTour>
Animated camera tour that steps through a sequence of keyframes.
| Prop | Type | Default | Description |
|---|---|---|---|
keyframes | CameraKeyframe[] | — | Ordered array of { center, zoom, pitch, bearing, durationMs }. |
autoPlay | boolean | false | Start tour on mount. |
loop | boolean | false | Loop back to first keyframe after last. |
onStep | (index: number) => void | — | Fired on each keyframe transition. |
ref | Ref<MapTourHandle> | — | Imperative handle with .play(), .pause(), .reset(). |
<Minimap>
Picture-in-picture overview map overlay.
| Prop | Type | Default | Description |
|---|---|---|---|
size | MinimapSize | 'md' | 'sm' (120 px), 'md' (180 px), or 'lg' (240 px). |
position | Position | 'bottom-right' | Map corner anchor. |
zoom | number | active zoom − 4 | Override 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.
| Prop | Type | Default | Description |
|---|---|---|---|
allowedOrigins | string[] | ['*'] | Origins from which postMessage commands are accepted. |
style | string | — | PMTiles or MapLibre style URL. |
initialFloor | string | — | Floor 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.
| Prop | Type | Default | Description |
|---|---|---|---|
floorId | string | — | Target floor to export. |
onExport | (svg: string) => void | — | Fired with the rendered SVG string. |
defaultOptions | SVGExportOptions | — | Pre-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.
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>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
graph | WayfindingGraph | required | Pre-built navigation graph from @diginestai/wayfinding. |
obstacles | string[] | [] | Unit IDs to treat as blocked. |
onPathChange | (path: NavigationPath | null) => void | — | Fired on each route recalculation. |
startLabel | string | 'Start' | Label shown on the start marker tooltip. |
stopLabel | string | 'Stop' | Label shown on the stop marker tooltip. |
useWayfinding hook:
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.
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;
}| Prop | Type | Description |
|---|---|---|
feature | maplibregl.MapGeoJSONFeature | The clicked feature. |
lngLat | maplibregl.LngLat | Click coordinates for popup positioning. |
onClose | () => void | Called when the close button is clicked. |
renderContent | (feature) => ReactNode | Custom content renderer (defaults to a property table). |
useFeatureClick hook:
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.
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 })}
/>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
features | GeoJSON.Feature[] | required | Pool of IMDF features to search. |
searchKeys | string[] | ['name'] | Property keys to match against. |
onSelect | (feature: GeoJSON.Feature) => void | — | Fired on result selection. |
placeholder | string | 'Search rooms…' | Input placeholder text. |
maxResults | number | 10 | Max results shown. |
useIndoorSearch hook:
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.
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);| Constant | Value | Description |
|---|---|---|
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.
import { I18nProvider } from '@diginestai/ui';
<I18nProvider locale="fr">
<App />
</I18nProvider>