@road-labs/map-sdk 0.0.28-rc.7 → 0.0.28-rc.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -31,7 +31,8 @@ The `App` component accepts the following props:
31
31
  | `height` | Yes | Both | Both | Height of the map container in pixels. | `-` |
32
32
  | `gestureHandling` | Yes | Both | Both | Google Maps SDK parameter controlling how gestures (scroll, pinch, etc.) interact with the map. Allowed values: `greedy`, `cooperative`, `none`, `auto`. We suggest a default value of `greedy`. | `-` |
33
33
  | `authorization` | Yes | v2 | Both | The public map key. Besides granting access it decides what kind of map this is: its remote configuration carries the context (`cpo` or `msp`), the operators, publishing modes and Google Maps key. The context is never passed as a prop. On `cpo` maps the widget uses the `/1/map/cpo/*` endpoints, draws locations individually while the view holds at most 1000 of them, and colours pins and filters by the OCPP status the station reports (Faulted red, Unavailable amber, in-session blue, Available green, no report grey, a fault outranking everything else on a pin). `msp` maps keep the clustering, filters and colours the mobile apps use. | `-` |
34
- | `version` | No | Both | Both | Which version of the map SDK do you wish to use. | `v1` |
34
+ | `version` | No | Both | Both | Which behaviour set the widget runs. `v1` is the legacy widget. `v2` authenticates with the map key, loads its remote configuration and shows the v2 details view. `v3` keeps everything in `v2` and draws the redesigned pins described under [Pins](#pins-v3); it also sends `version: v3` to the API, which then counts a bucket's statuses per EVSE (per connector on `cpo` maps) instead of per location and returns the cheapest current energy price per kWh for each bucket. | `v1` |
35
+ | `currency` | No | v3 | Both | ISO 4217 code of the currency prices per kWh are shown in on the pins and filtered in. Sent as `currency` on every search and analytics request; a location publishing its tariff in another currency shows no price. A `currency` in the map key's remote configuration is used when the prop is not set. | `EUR` |
35
36
  | `language` | No | Both | Both | Language of the widget. Supported values: `en`, `nl`, `de`, `fr`, `it`, `es` and their regional variants (e.g. `nl-NL`, `de-AT`), matched case-insensitively. Unsupported values fall back to `en`. If nothing is set, the browser language is used. | Browser language |
36
37
  | `position {lat,lng}` | No | Both | Both | Initial latitude/longitude to center the map on load. If not provided, defaults to visitor's IP-based location. | Visitor IP location |
37
38
  | `useBrowserLocation` | No | Both | Both | Use the browser location to center the map. | `false` |
@@ -51,7 +52,8 @@ The `App` component accepts the following props:
51
52
  | `showNoAdditionalFeeFilter` | No | v2 | msp | Used to configure whether we enable the user to filter out stations that come with additional fees. | `false` |
52
53
  | `showPublishingModeFilter` | No | v2 | cpo | Used to configure whether we enable the user to filter out public or private stations. | `false` |
53
54
  | `showOperatorOnly` | No | v2 | both | String value representing the operator name. Include a quick filter option to find a specific operator. | `-` |
54
- | `showAnalytics` | No | v2 | Both | Shows status pills next to the filter toggle for the current view and filters: EVSEs by roaming status, and on `cpo` maps a second pill with connectors by the OCPP status the station reports. Clicking a status toggles the matching status filter (the OCPP pill on `cpo` maps, the roaming pill on `msp` maps) and the selected statuses are highlighted; the roaming pill on a `cpo` map is read-only because the CPO search filters on OCPP status. The counts ignore the status selection so every status in the view stays listed; all other filters apply. Fetched from `/1/map/analytics` (`/1/map/cpo/analytics` on `cpo` maps) whenever the view or filters change. Hidden on screens narrower than 768px. | `false` |
55
+ | `showPriceFilter` | No | v3 | Both | Shows a `Max. price per kWh` slider in the filters panel. While a limit is set the search sends `maxEnergyPrice` and only locations whose cheapest current energy price, including VAT, is at or below it are drawn; with `Fast Chargers` on, only DC connectors count towards that price. Locations the API has no price for are excluded while a limit is set, so enable this once the pricing backfill has run for the map's data. The `Any` step lifts the limit. | `false` |
56
+ | `showAnalytics` | No | v2 | Both | Shows a status pill next to the filter toggle for the current view and filters. On `msp` maps it lists EVSEs by roaming status. On `cpo` maps it defaults to connectors by the OCPP status the station reports, with an `EVSE Status \| Roaming Status` switch under the pill to flip to the roaming breakdown; only one shows at a time. Clicking a status toggles the matching status filter (the OCPP view on `cpo` maps, the roaming view on `msp` maps) and the selected statuses are highlighted; the roaming view on a `cpo` map is read-only because the CPO search filters on OCPP status. The counts ignore the status selection so every status in the view stays listed; all other filters apply. Fetched from `/1/map/analytics` (`/1/map/cpo/analytics` on `cpo` maps) whenever the view or filters change. Hidden on screens narrower than 768px. | `false` |
55
57
  | `onMarkerClicked` | No | Both | Both | Callback function that is called when a marker is clicked. Receives an object with `ids` property containing the location IDs. | `-` |
56
58
 
57
59
  ### Example
@@ -84,6 +86,27 @@ function MyMap() {
84
86
 
85
87
  **Note**: The `height`, `gestureHandling` and `authorization` props are required. All other props are optional. The map context (`cpo` or `msp`) is not a prop; it comes from the map key's remote configuration.
86
88
 
89
+ ### Pins (v3)
90
+
91
+ With `version: "v3"` every location is a white teardrop anchored on its tail tip. Colour carries availability only and every state also has its own glyph, so the map still reads in greyscale:
92
+
93
+ | Pin | `msp` maps (EVSEs) | `cpo` maps (connectors) |
94
+ | :-- | :-- | :-- |
95
+ | Green ring, bolt | every EVSE free | every connector free |
96
+ | Green ring, `free/total` | some free, the rest out of order | some free, the rest unknown |
97
+ | Any ring, `free/total` | whatever else is going on, a free unit is always shown as a count | same |
98
+ | Amber ring, `free/total` | a session is running on at least one EVSE; the digits say how many are still free | at least one connector is taken out of service (`Unavailable`) |
99
+ | Blue ring, `free/total` | not used | a session is running (`Preparing`, `Charging`, `Suspended`, `Finishing`, `Reserved`) |
100
+ | Red ring, `free/total` or `!` | not used | at least one connector reports `Faulted`; the digits stay while anything is free, the `!` shows when nothing is |
101
+ | Grey ring, dash | nothing usable (`Inoperative`, `Out of order`, `Blocked`, `Closed`) or nothing reported | nothing reported |
102
+ | Dashed grey, `+` | every EVSE is `Planned` | not used |
103
+
104
+ Every single-location pin that shows a glyph (zoom 12 and up) also carries a price tag under its tail tip: white digits on a dark grey tag, e.g. `€0.42`, the current price per kWh including VAT in the map `currency`. When the API has no price for the location, or the price is zero because the tariff charges by time or session rather than energy, the tag reads `…` instead, so a pin never claims to be free. The pin above it is unchanged, so colour still carries availability only and the price is text, never a colour. The tag stays put when the pin grows on selection. Clusters and the dots below zoom 12 carry no tag.
105
+
106
+ The pin of the location open in the sidebar grows to 52px with a halo; the tail tip stays put. Below zoom 12 single pins shrink to a 26px dot without a glyph. Clusters of up to nine locations are a pin with two ghost pins behind it and the count as glyph; larger clusters are a circle with the count and a caption. A cluster whose locations are not all in the same state gets a ring split by that state, in proportion. On `msp` maps a cluster is green as soon as anything inside it is free; on `cpo` maps the operator priority above applies (fault, unavailable, in session, free).
107
+
108
+ The status pills and the status filter use the same colours as the pins on a `v3` map. With `showPriceFilter` the filters panel gains the price slider described in the props table. Clustering and the sidebar are unchanged.
109
+
87
110
  ### Theming with Shadow DOM
88
111
 
89
112
  The theming options (`brandColor`, `backgroundColor`, `textColor`, `borderColor`, `fontFamily`) require the SDK to be rendered within a Shadow DOM context. This provides style encapsulation, preventing the map's styles from conflicting with your application's styles and vice versa.
@@ -0,0 +1,17 @@
1
+ import { default as React } from 'react';
2
+ import { GeohashItem, MapKind } from '../../types';
3
+ export declare const pinStylesheet = "\n.roadmap-pin {\n position: absolute;\n left: 0;\n top: 0;\n display: block;\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0;\n background: none;\n -webkit-appearance: none;\n appearance: none;\n cursor: pointer;\n font-family: var(--roadmap-font-family, Inter), system-ui, -apple-system, sans-serif;\n animation: roadmap-pin-in 0.18s ease-out both;\n}\n.roadmap-pin:focus-visible {\n outline: none;\n}\n.roadmap-pin-body {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n border-radius: 50% 50% 50% 0;\n border: 3px solid currentColor;\n background: #fff;\n transform: rotate(-45deg);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.12s ease, box-shadow 0.12s ease;\n}\n.roadmap-pin:hover .roadmap-pin-body {\n transform: rotate(-45deg) scale(1.06);\n}\n.roadmap-pin-ghost {\n position: absolute;\n box-sizing: border-box;\n border-radius: 50% 50% 50% 0;\n border: 2px solid;\n transform: rotate(-45deg);\n}\n.roadmap-pin-glyph {\n display: flex;\n align-items: center;\n justify-content: center;\n transform: rotate(45deg);\n line-height: 1;\n white-space: nowrap;\n font-family: \"IBM Plex Mono\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-weight: 500;\n}\n.roadmap-pin-circle,\n.roadmap-pin-ring {\n position: absolute;\n inset: 0;\n box-sizing: border-box;\n border-radius: 50%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n line-height: 1;\n transition: transform 0.12s ease;\n}\n.roadmap-pin-circle {\n background: #fff;\n border: 3px solid currentColor;\n}\n.roadmap-pin:hover .roadmap-pin-circle,\n.roadmap-pin:hover .roadmap-pin-ring {\n transform: scale(1.06);\n}\n.roadmap-pin-ring-inner {\n width: calc(100% - 12px);\n height: calc(100% - 12px);\n border-radius: 50%;\n background: #fff;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.roadmap-pin-count {\n font-family: \"IBM Plex Mono\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-weight: 500;\n line-height: 1;\n}\n.roadmap-pin-label {\n margin-top: 2px;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n line-height: 1;\n}\n.roadmap-pin-tag {\n position: absolute;\n transform: translateX(-50%);\n box-sizing: border-box;\n padding: 2px 6px;\n border-radius: 4px;\n background: #383c43;\n color: #fdfcf9;\n font-family: \"IBM Plex Mono\", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 11px;\n font-weight: 500;\n line-height: 13px;\n white-space: nowrap;\n pointer-events: none;\n}\n@keyframes roadmap-pin-in {\n from { opacity: 0; transform: translateY(4px); }\n to { opacity: 1; transform: none; }\n}\n";
4
+ export declare function PinStyles(): import("react/jsx-runtime").JSX.Element;
5
+ interface Props {
6
+ data: GeohashItem;
7
+ map?: google.maps.Map;
8
+ kind: MapKind;
9
+ onClick: (payload: GeohashItem) => void;
10
+ selected?: boolean;
11
+ compact?: boolean;
12
+ price?: string;
13
+ priceLabel?: string;
14
+ sitesLabel: string;
15
+ }
16
+ declare const Pin: React.FC<Props>;
17
+ export default Pin;
@@ -26,6 +26,7 @@ export type MapContextType = {
26
26
  searchBounds?: SearchBounds;
27
27
  setSearchBounds?: (bounds: SearchBounds) => void;
28
28
  mapKind: MapKind;
29
+ currency: string;
29
30
  fetchLocations?: ({ ids }: {
30
31
  ids: any;
31
32
  }) => Promise<any>;
@@ -52,6 +53,7 @@ export type MapContextType = {
52
53
  isSearching?: boolean;
53
54
  setIsSearching?: (isSearching: boolean) => void;
54
55
  };
56
+ export declare const defaultCurrency = "EUR";
55
57
  export declare const MapContext: React.Context<MapContextType>;
56
58
  interface Props {
57
59
  children: React.ReactNode;
package/dist/i18n.d.ts CHANGED
@@ -55,8 +55,12 @@ export type LabelsType = {
55
55
  "ocpp.statusSuspendedEv": string;
56
56
  "ocpp.statusFinishing": string;
57
57
  "ocpp.statusFaulted": string;
58
- "analytics.roaming": string;
59
- "analytics.ocpp": string;
58
+ "analytics.evseStatus": string;
59
+ "analytics.roamingStatus": string;
60
+ "pin.sites": string;
61
+ "filters.maxEnergyPrice": string;
62
+ "filters.anyPrice": string;
63
+ "pin.pricePerKwh": string;
60
64
  "filters.chargingAccessibility": string;
61
65
  "filters.accessibilityAll": string;
62
66
  "filters.accessibilityTesla": string;