@mapmap/maps 0.7.0 → 0.8.0

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
@@ -751,13 +751,29 @@ actionable `console.error` per issue per page, each with a docs link:
751
751
 
752
752
  `runMapDiagnostics(…)` is exported for apps wrapping a raw `maplibregl.Map`.
753
753
 
754
- ## The MapMap mark
754
+ ## The MapMap mark and the attribution
755
755
 
756
756
  Maps render a small MapMap wordmark bottom-right (the same convention as
757
757
  Google Maps and Mapbox). It links to mapmap.ai, needs no network fetch,
758
- and is on by default: pass `logo: false` to `createMap` to remove it, or
759
- `logo: { position, href }` to customise. Attribution is separate and not
760
- removable.
758
+ and is always on: pass `logo: { position, href }` to `createMap` to move
759
+ or relink it.
760
+
761
+ Neither the mark nor the attribution can be switched off:
762
+
763
+ - **The MapMap mark.** Every displayed MapMap map carries it, which is a
764
+ condition of the `@mapmap/maps` licence (the same model as Mapbox GL JS
765
+ v2+). `logo: false` still type-checks, so nothing stops compiling, but
766
+ it is ignored and the SDK logs one `console.warn` per map.
767
+ - **The OpenStreetMap attribution.** The credit is a condition of the ODbL
768
+ that the map data is served under, for MapMap and for you.
769
+ `mapOptions: { attributionControl: false }` is ignored the same way.
770
+ Everything else MapLibre offers still works:
771
+ `attributionControl: { compact: true }` collapses it, and
772
+ `attributionControl: { customAttribution: "© Your Co" }` adds your own
773
+ credit alongside the OSM one.
774
+
775
+ In a bottom corner the mark sits above the attribution: MapLibre prepends
776
+ controls in the bottom corners, so the control added last is the highest.
761
777
 
762
778
  ## Turn-by-turn guidance
763
779
 
package/dist/index.d.ts CHANGED
@@ -258,9 +258,10 @@ declare function createRouteEffect(name: RouteEffectName, geometry: RouteGeometr
258
258
 
259
259
  /**
260
260
  * The MapMap logo control: a small wordmark on the map, the same
261
- * convention as Google Maps' and Mapbox's marks. On by default in
262
- * {@link MapMapMap}; positionable, and removable with `logo: false`
263
- * (attribution itself is separate and never removable).
261
+ * convention as Google Maps' and Mapbox's marks. Always on in
262
+ * {@link MapMapMap} and positionable with `logo: { position }`; it cannot
263
+ * be removed (carrying the mark is a condition of the SDK licence), and
264
+ * the OpenStreetMap attribution is a separate, equally permanent control.
264
265
  *
265
266
  * The mark is an inline SVG (no network fetch, works offline and under
266
267
  * strict CSPs): the MapMap brand lockup — the three-colour route mark
@@ -271,7 +272,15 @@ declare function createRouteEffect(name: RouteEffectName, geometry: RouteGeometr
271
272
  type LogoPosition = "bottom-right" | "bottom-left" | "top-right" | "top-left";
272
273
  /** Options for {@link LogoControl}. */
273
274
  interface LogoOptions {
274
- /** Corner to render in. Default `bottom-right`, above the attribution. */
275
+ /**
276
+ * Corner to render in. Default `bottom-right`.
277
+ *
278
+ * In a bottom corner the mark sits ABOVE the attribution, despite being
279
+ * added after it: MapLibre prepends controls in the bottom corners
280
+ * (`insertBefore(container.firstChild)`) and the corner is anchored to
281
+ * the bottom edge, so the control added last is the one that ends up
282
+ * highest. Verified against maplibre-gl 5's `addControl`.
283
+ */
275
284
  position?: LogoPosition;
276
285
  /** Link target when clicked. Default the MapMap site. */
277
286
  href?: string;
@@ -1046,8 +1055,18 @@ declare function registerPmtilesProtocol(gl?: typeof maplibregl): void;
1046
1055
  interface MapMapOptions {
1047
1056
  /**
1048
1057
  * The MapMap wordmark on the map (like the Google Maps / Mapbox marks).
1049
- * Default on at bottom-right, above the attribution; `false` removes
1050
- * it, or pass `{ position, href }` to customise.
1058
+ * Always on, at bottom-right above the attribution by default; pass
1059
+ * `{ position, href }` to move or relink it.
1060
+ *
1061
+ * The mark cannot be taken off. Every displayed MapMap map carries it,
1062
+ * which is a condition of the SDK licence, the same model as Mapbox GL
1063
+ * JS v2+. `false` (and `true`) are still accepted so existing code keeps
1064
+ * compiling: passing `false` is ignored, the mark is added anyway, and
1065
+ * the SDK logs one `console.warn` for that map.
1066
+ *
1067
+ * `false` is soft-deprecated: it does nothing and will be dropped from
1068
+ * the type in the next major. Use `{ position }` to get the mark out of
1069
+ * the way instead.
1051
1070
  */
1052
1071
  logo?: boolean | LogoOptions;
1053
1072
  /** The container element or its id. */
@@ -1071,6 +1090,13 @@ interface MapMapOptions {
1071
1090
  /**
1072
1091
  * Extra MapLibre `MapOptions` merged last (escape hatch for hash, bearing,
1073
1092
  * maxBounds, etc.). `container` and `style` here are ignored.
1093
+ *
1094
+ * `attributionControl` is honoured but never allowed to remove the
1095
+ * credit: `{ compact }` and `{ customAttribution }` work as MapLibre
1096
+ * documents them, while `attributionControl: false` is ignored (the
1097
+ * attribution stays, and the SDK logs one `console.warn` for that map).
1098
+ * The OpenStreetMap credit is a condition of the ODbL the map data is
1099
+ * served under, for MapMap and for you.
1074
1100
  */
1075
1101
  mapOptions?: Partial<Omit<MapOptions, "container" | "style">>;
1076
1102
  }
@@ -1114,7 +1140,15 @@ declare class MapMapMap {
1114
1140
  private effectWaiting;
1115
1141
  private destroyed;
1116
1142
  private readonly pendingWaits;
1143
+ private readonly notices;
1117
1144
  constructor(options: MapMapOptions);
1145
+ /**
1146
+ * Log an enforcement notice at most once for this map. A warning, not
1147
+ * an error and never a throw: `logo: false` and
1148
+ * `attributionControl: false` are published, documented options, and a
1149
+ * hard failure would break a customer's build on a patch upgrade.
1150
+ */
1151
+ private notice;
1118
1152
  /**
1119
1153
  * Run `action` as soon as the style can take layer edits, or now if it
1120
1154
  * already can.
package/dist/index.js CHANGED
@@ -1891,6 +1891,12 @@ var MapMapMap = class {
1891
1891
  // style load, and the cleanups let it detach those listeners.
1892
1892
  this.destroyed = false;
1893
1893
  this.pendingWaits = /* @__PURE__ */ new Set();
1894
+ // Enforcement notices already logged for THIS map. Per instance, not
1895
+ // per page (diagnostics.ts dedups per page because a duplicated
1896
+ // maplibre-gl is one page-level fault): each map that asks for a
1897
+ // removal is its own licence problem and deserves its own line, but a
1898
+ // theme swap or re-render must never repeat one.
1899
+ this.notices = /* @__PURE__ */ new Set();
1894
1900
  this.handleStyleLoadForEffects = () => {
1895
1901
  if (this.destroyed) return;
1896
1902
  if (!this.effectExplicit) {
@@ -1908,21 +1914,36 @@ var MapMapMap = class {
1908
1914
  this.navDesign = navDesignFromTheme(theme);
1909
1915
  this.poiDesign = poiDesignFromTheme(theme);
1910
1916
  const style = resolveStyle(options.style, options.territoryTilesUrl);
1917
+ const requestedAttribution = options.mapOptions?.attributionControl;
1918
+ if (requestedAttribution === false) {
1919
+ this.notice(
1920
+ "attribution-removal",
1921
+ "mapOptions.attributionControl: false is ignored - the OpenStreetMap attribution stays on. The credit is a condition of the ODbL that the map data is served under, for MapMap and for you. Pass { compact: true } to collapse it, or { customAttribution } to add your own credit alongside it."
1922
+ );
1923
+ }
1924
+ const attributionControl = {
1925
+ compact: false,
1926
+ ...requestedAttribution === false ? void 0 : requestedAttribution
1927
+ };
1911
1928
  this.map = new maplibregl.Map({
1912
1929
  container: options.container,
1913
1930
  style,
1914
1931
  center: options.center ?? DEFAULT_CENTER,
1915
1932
  zoom: options.zoom ?? DEFAULT_ZOOM,
1916
- attributionControl: { compact: false },
1917
- ...options.mapOptions
1933
+ ...options.mapOptions,
1934
+ attributionControl
1918
1935
  });
1919
- if (options.logo !== false) {
1920
- const logoOptions = options.logo === true ? {} : options.logo ?? {};
1921
- this.map.addControl(
1922
- new LogoControl(logoOptions),
1923
- logoOptions.position ?? "bottom-right"
1936
+ if (options.logo === false) {
1937
+ this.notice(
1938
+ "logo-removal",
1939
+ "logo: false is ignored - the MapMap mark stays on the map. Carrying the mark is a condition of the @mapmap/maps licence. Pass logo: { position } to move it to another corner."
1924
1940
  );
1925
1941
  }
1942
+ const logoOptions = typeof options.logo === "object" && options.logo !== null ? options.logo : {};
1943
+ this.map.addControl(
1944
+ new LogoControl(logoOptions),
1945
+ logoOptions.position ?? "bottom-right"
1946
+ );
1926
1947
  this.map.on("style.load", this.handleStyleLoadForEffects);
1927
1948
  runMapDiagnostics({
1928
1949
  container: options.container,
@@ -1931,6 +1952,17 @@ var MapMapMap = class {
1931
1952
  apiKey: this.apiKey
1932
1953
  });
1933
1954
  }
1955
+ /**
1956
+ * Log an enforcement notice at most once for this map. A warning, not
1957
+ * an error and never a throw: `logo: false` and
1958
+ * `attributionControl: false` are published, documented options, and a
1959
+ * hard failure would break a customer's build on a patch upgrade.
1960
+ */
1961
+ notice(notice, message) {
1962
+ if (this.notices.has(notice)) return;
1963
+ this.notices.add(notice);
1964
+ console.warn(`MapMap [${notice}]: ${message}`);
1965
+ }
1934
1966
  /**
1935
1967
  * Run `action` as soon as the style can take layer edits, or now if it
1936
1968
  * already can.