@uzmaps/ui
v0.1.1
Published
UzMap React components — map view, search box, route panel and place card.
Maintainers
Readme
@uzmaps/ui
React components for UzMap — a map view, search box, route panel, place card and map
controls, built on @uzmaps/engine.
npm install @uzmaps/ui @uzmaps/engine @uzmaps/api maplibre-gl react react-domThe shape of this library
MapView owns the map instance. Everything else is presentational and controlled — the components render
state and raise callbacks; they do not fetch. You keep the query, the results and the selection in your own
state and pass them down.
That is deliberate. Search-as-you-type, debouncing, cancellation, caching and result ranking all belong to your
application, and a component that quietly owned an API client would take those decisions away from you and be
almost impossible to compose. Use @uzmaps/api for the calls.
Usage
import { useState } from 'react';
import { MapView, SearchBox, ResultList, MapControls, useUzMap } from '@uzmaps/ui';
import { UzMapClient } from '@uzmaps/api';
import '@uzmaps/ui/styles.css';
const api = new UzMapClient({ baseUrl: 'https://uzmaps.ndc.uz', apiKey: KEY, language: 'uz' });
function Search() {
const map = useUzMap(); // the UzMap instance, or null before mount
const [q, setQ] = useState('');
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(false);
async function run() {
setLoading(true);
try {
setResults((await api.search(q)).results);
} finally {
setLoading(false);
}
}
return (
<>
<SearchBox value={q} onChange={setQ} onSubmit={run} loading={loading} language="uz" />
<ResultList
results={results}
language="uz"
onSelect={(r) => map?.selectPlace(r, { fly: true })}
/>
</>
);
}
function Controls({ theme, onTheme, language, onLanguage }) {
const map = useUzMap();
return (
<MapControls
theme={theme} onTheme={onTheme}
language={language} onLanguage={onLanguage}
onLocate={() => map?.userLocation.start()}
/>
);
}
export default function App() {
const [theme, setTheme] = useState('auto');
const [language, setLanguage] = useState('uz');
return (
<MapView serverUrl="https://uzmaps.ndc.uz" apiKey={KEY} language={language} theme={theme} zoom={12}>
<Search />
<Controls theme={theme} onTheme={setTheme} language={language} onLanguage={setLanguage} />
</MapView>
);
}Every sample here is compiled in CI (see
examples/in the repository), so it reflects the real API rather than a plausible-looking approximation of it.
MapView accepts every UzMap option except container, and provides the instance to descendants through
context — useUzMap() reaches it without prop drilling.
Components
| | |
|---|---|
| MapView | Hosts the map. Provides it via context. |
| useUzMap() | The UzMap instance, or null before mount. |
| SearchBox | Controlled text input with the search affordances. |
| ResultList | Renders results; onSelect per row. |
| CategoryChips | Category filter row. |
| PlaceCard | Place details, hours, photo. |
| RoutePanel | Route summary, mode switch and options. |
| MapControls | Zoom, compass, geolocate, 3D and terrain toggles. |
| BottomSheet | Draggable sheet for mobile layouts. |
| ScaleBar, PoiIcon, t / makeT | Scale bar, category icons, translation helpers. |
Styling
import '@uzmaps/ui/styles.css';A separate export rather than injected at import time, so you can order it against your own CSS and your bundler can extract it.
Peers
React 18 or 19. TypeScript users should also install @types/react.
Licence
MIT. Map data © OpenStreetMap contributors (ODbL).
