Krizaka UI
Krizaka UI
Components

Map

Maps that cost nothing per view — MapLibre (open source) over Protomaps tiles on the Krizaka CDN, painted from the tokens in dark or light and in the product's accent — with markers, clusters, the person's position, a radius and a location picker.

Web + MobileBetaData display

Web and mobile — the same component for React and React Native. Beta: its API may still change in a minor version.

Why it is here. Used by krizaka.com.

When to use

  • To show where things are: pick-up points, creators near you, an event's venue.
  • Cluster for many points (dozens to thousands): they group while close and open by zooming in.
  • LocationPicker to choose a place: a meeting point, a delivery address, the centre of a search with its radius.
  • StaticMap where a live map is too much (a card, a list, an e-mail) and as the fallback of every Map.

When not to use

  • For an address typed or searched: a text field (geocoding is a server's job — Nominatim or Photon self-hosted later), the map only confirms it.Use instead: Field
  • For figures by country or region (a choropleth): a chart.Use instead: Stat

Installation

Install

npm install @krizaka/ui @krizaka/tailwind @krizaka/tokens tailwindcss

Styles

@import "tailwindcss";
@import "@krizaka/tailwind";
@import "@krizaka/ui/tailwind.css";

Import

import { Map, Marker, Cluster, UserPosition, RadiusCircle, LocationPicker, StaticMap, mapStyle, distanceMeters, formatDistance } from "@krizaka/ui/map";

Examples

Places

Pick-up points in Montréal: markers are buttons, the chosen one shows its name.

Cluster

Sixty creators grouped while they are close; a group opens by zooming in.

Location picker

A meeting point under the pin, its distance from the person, a 1-km zone and Near me.

Protomaps · © OpenStreetMap contributors

1 km from you

Static map

The places on the map's paper, without an engine: a card, a list item, a fallback.

Props

LocationPicker

A position picked by moving the map under a pin; its distance from the person; "near me" on request.

PropTypeDefaultDescription
labelrequiredstring—The picker's accessible name ("Meeting point"), passed translated.
localerequiredstring—The BCP 47 locale of the distance.
onValueChangerequired(value: LngLat) => void—Called when the map rests on a new position.
valuerequiredLngLat—The chosen position (controlled): the centre of the map.
brandBrandId—The product whose accent the map carries. Default krizaka.
classNamestring—Classes merged on the root (its height: h-80, aspect-video).
fallbackReactNode—Shown in place of the map while its engine loads, and for good without WebGL: a StaticMap, a picture.
labelsPartial<LocationPickerLabels>—The words, passed translated; English by default.
langstring—The language of the labels (fr, en). Default en.
originLngLat | nullnullWhere the person is, when the app already knows it (the distance chip shows at once).
radiusnumber—A radius in metres drawn around the chosen position (a delivery zone, a search radius).
regionMapRegion | null—The detailed region (PMTiles) drawn from zoom 6.5. Default: our Montréal–Québec extract (to zoom 14).
scheme"light" | "dark"—The scheme. Default: the page's (html.light), followed.
worldMapRegion | null—The world's low zooms (PMTiles). Default: our world extract (to zoom 6).
zoomnumber14The zoom at first. Default 14.

Cluster

Many points grouped while they are close: a disc with the count, opened by zooming in; each point is listed for screen readers.

PropTypeDefaultDescription
pointsrequiredreadonly ClusterPoint[]—The points: many of them (creators, pick-up points, events).
onPointPress((point: ClusterPoint) => void)—Pressing a single point. A group zooms in to open itself.
radiusnumber48The radius, in pixels, within which points group. Default 48.

Map

A map: MapLibre over our Protomaps tiles, styled from the tokens, with its places as a list for screen readers.

PropTypeDefaultDescription
centerrequiredLngLat—Where the map looks at first: longitude, latitude.
labelrequiredstring—The map's accessible name ("Pick-up points near you"), passed translated.
brandBrandId—The product whose accent the map carries. Default krizaka.
childrenReactNode—Markers, circles, clusters, the user's position — and anything drawn over the map.
classNamestring—Classes merged on the root (its height: h-80, aspect-video).
controlledboolean—The camera follows center and zoom when they change (flies, or jumps under reduced motion).
controlsbooleantrueThe zoom buttons (default) — the keyboard also zooms with + and − on the focused map.
fallbackReactNode—Shown in place of the map while its engine loads, and for good without WebGL: a StaticMap, a picture.
interactivebooleantrueMoves with the hand (default); false makes a still picture of a place.
labelsPartial<MapLabels>—The words, passed translated; English by default.
langstring—The language of the labels (fr, en). Default en.
onMoveEnd((view: { center: LngLat; zoom: number; }) => void)—Called when the camera rests: its centre and zoom.
onPress((position: LngLat) => void)—Called with the position pressed on the map (not on a marker).
regionMapRegion | null—The detailed region (PMTiles) drawn from zoom 6.5. Default: our Montréal–Québec extract (to zoom 14).
scheme"light" | "dark"—The scheme. Default: the page's (html.light), followed.
worldMapRegion | null—The world's low zooms (PMTiles). Default: our world extract (to zoom 6).
zoomnumber12The zoom at first (0 the world, 12 a city, 16 a street). Default 12.

Marker

A place on the map: an accent dot (or your content) that is a button when it does something.

PropTypeDefaultDescription
labelrequiredstring—Its words: the place's name, read in the list of places and as the button's name ("Café Olimpico, 350 m").
positionrequiredLngLat—Where it stands.
childrenReactNode—What it draws instead of the accent dot (an avatar, an icon).
onPress(() => void)—Pressing it (details in a panel, a sheet): the marker becomes a button.
selectedboolean—The chosen one: larger, its label shown above it.
sizenumber18Its size in pixels. Default 18.

RadiusCircle

A circle on the ground: a delivery zone, a search radius — filled with the accent, its edge drawn.

PropTypeDefaultDescription
centerrequiredLngLat—Its centre.
radiusrequirednumber—Its radius in metres.
tone"accent" | "soft"accentaccent (a zone that matters: a delivery area, a search radius) or soft (an accuracy).

UserPosition

The person's position: a dot that pulses (still under reduced motion), its accuracy as a soft disc.

PropTypeDefaultDescription
labelrequiredstring—Its words ("You are here"), read in the list of places.
positionrequiredLngLat—Where the person is.
accuracynumber—The accuracy in metres: a soft disc around the dot.

StaticMap

A still map: the places on the map's paper (or on a snapshot), named in words.

PropTypeDefaultDescription
centerrequiredLngLat—The centre of the picture.
labelrequiredstring—What the picture shows, in words ("Three pick-up points in the Plateau"), passed translated: its accessible name.
classNamestring—Classes merged on the root (its size).
imagestring—A snapshot of the real map of the area (same centre and zoom), drawn under the places; the attribution then shows.
placesreadonly StaticMapPlace[][]The places drawn on it (an accent dot each), listed in its name.
zoomnumber12The zoom of the picture. Default 12.

Accessibility

  • The canvas is hidden from assistive technologies: the places are read as a list (each Marker, Cluster point and the person's position by its label).
  • A marker with onPress is a button named by its label (aria-pressed when it can be chosen); the chosen one shows its name above it.
  • Under reduced motion the camera jumps instead of flying and the position's pulse stands still.
  • Colours come from the tokens: the water is the accent softened, roads and labels the text roles — readable in both schemes.

Keyboard

KeysAction
TabThe map (a region named by label), then its buttons: zoom, the markers that do something, Near me.
Arrow keysPan the focused map.
+ / −Zoom the focused map in or out.

Best practices

  • Give every map a label and every marker a label: they are read as the list of places in place of the map.
  • Always pass a fallback (StaticMap with the same centre and places): it shows while the engine loads and for good without WebGL.
  • Ask for the position only on a press (LocationPicker's Near me), never on load; every refusal has its words.
  • Keep the attribution visible (OpenStreetMap's licence, the ODbL, asks for it): the components draw it.
  • Install the engine only where a map is shown: maplibre-gl (web) or @maplibre/maplibre-react-native (Expo) — optional peers.

Generated from the code of @krizaka/ui 3.8.0: its meta.ts, its examples and its types.Edit this documentation on GitHub

On this page