@mapka/maplibre-gl-sdk 0.12.0 → 0.13.1

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.
Files changed (41) hide show
  1. package/README.md +330 -4
  2. package/lib/.buildInfo.json +1 -1
  3. package/lib/components/DownloadIcon.d.ts +4 -0
  4. package/lib/components/DownloadIcon.d.ts.map +1 -0
  5. package/lib/components/DownloadIcon.js +10 -0
  6. package/lib/components/PopupContent.d.ts.map +1 -1
  7. package/lib/components/ProgressDownIcon.d.ts +4 -0
  8. package/lib/components/ProgressDownIcon.d.ts.map +1 -0
  9. package/lib/components/ProgressDownIcon.js +14 -0
  10. package/lib/constants/styles.d.ts +5 -0
  11. package/lib/constants/styles.d.ts.map +1 -0
  12. package/lib/constants/styles.js +3 -0
  13. package/lib/controls/MapkaExportControl.d.ts +21 -0
  14. package/lib/controls/MapkaExportControl.d.ts.map +1 -0
  15. package/lib/controls/MapkaExportControl.js +76 -0
  16. package/lib/index.d.ts +3 -0
  17. package/lib/index.d.ts.map +1 -1
  18. package/lib/index.js +3 -0
  19. package/lib/map.d.ts +11 -2
  20. package/lib/map.d.ts.map +1 -1
  21. package/lib/map.js +10 -5
  22. package/lib/modules/export.d.ts +4 -0
  23. package/lib/modules/export.d.ts.map +1 -0
  24. package/lib/modules/export.js +40 -0
  25. package/lib/modules/popup.d.ts +2 -2
  26. package/lib/modules/popup.d.ts.map +1 -1
  27. package/lib/modules/popup.js +19 -6
  28. package/lib/types/export.d.ts +7 -0
  29. package/lib/types/export.d.ts.map +1 -0
  30. package/lib/types/export.js +1 -0
  31. package/package.json +3 -2
  32. package/src/components/DownloadIcon.tsx +25 -0
  33. package/src/components/PopupContent.tsx +1 -0
  34. package/src/components/ProgressDownIcon.tsx +29 -0
  35. package/src/constants/styles.ts +5 -0
  36. package/src/controls/MapkaExportControl.tsx +111 -0
  37. package/src/index.ts +6 -0
  38. package/src/map.ts +17 -4
  39. package/src/modules/export.ts +55 -0
  40. package/src/modules/popup.tsx +26 -24
  41. package/src/types/export.ts +6 -0
@@ -0,0 +1,4 @@
1
+ /** biome-ignore-all lint/correctness/noUnusedImports: <explanation> */
2
+ import { h } from "preact";
3
+ export declare const DownloadIcon: () => h.JSX.Element;
4
+ //# sourceMappingURL=DownloadIcon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DownloadIcon.d.ts","sourceRoot":"","sources":["../../src/components/DownloadIcon.tsx"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,eAAO,MAAM,YAAY,qBAqBxB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /** biome-ignore-all lint/correctness/noUnusedImports: <explanation> */
2
+ import { h } from "preact";
3
+ export const DownloadIcon = () => {
4
+ return (h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-label": "Download" },
5
+ h("title", null, "Download"),
6
+ h("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
7
+ h("path", { d: "M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2" }),
8
+ h("path", { d: "M7 11l5 5l5 -5" }),
9
+ h("path", { d: "M12 4l0 12" })));
10
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"PopupContent.d.ts","sourceRoot":"","sources":["../../src/components/PopupContent.tsx"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAE,CAAC,EAAY,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,UAAU,UAAW,SAAQ,iBAAiB;IAC5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA8LD,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,UAAU,EACV,OAAO,GACR,EAAE,UAAU,iBAqBZ"}
1
+ {"version":3,"file":"PopupContent.d.ts","sourceRoot":"","sources":["../../src/components/PopupContent.tsx"],"names":[],"mappings":"AAAA,uEAAuE;AAEvE,OAAO,EAAE,CAAC,EAAY,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,UAAU,UAAW,SAAQ,iBAAiB;IAC5C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA8LD,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,WAAW,EACX,WAAW,EACX,SAAS,EACT,UAAU,EACV,OAAO,GACR,EAAE,UAAU,iBAqBZ"}
@@ -0,0 +1,4 @@
1
+ /** biome-ignore-all lint/correctness/noUnusedImports: <explanation> */
2
+ import { h } from "preact";
3
+ export declare const ProgressDownIcon: () => h.JSX.Element;
4
+ //# sourceMappingURL=ProgressDownIcon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProgressDownIcon.d.ts","sourceRoot":"","sources":["../../src/components/ProgressDownIcon.tsx"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,eAAO,MAAM,gBAAgB,qBAyB5B,CAAC"}
@@ -0,0 +1,14 @@
1
+ /** biome-ignore-all lint/correctness/noUnusedImports: <explanation> */
2
+ import { h } from "preact";
3
+ export const ProgressDownIcon = () => {
4
+ return (h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", class: "icon icon-tabler icons-tabler-outline icon-tabler-progress-down" },
5
+ h("title", null, "Progress Download"),
6
+ h("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
7
+ h("path", { d: "M10 20.777a8.942 8.942 0 0 1 -2.48 -.969" }),
8
+ h("path", { d: "M14 3.223a9.003 9.003 0 0 1 0 17.554" }),
9
+ h("path", { d: "M4.579 17.093a8.961 8.961 0 0 1 -1.227 -2.592" }),
10
+ h("path", { d: "M3.124 10.5c.16 -.95 .468 -1.85 .9 -2.675l.169 -.305" }),
11
+ h("path", { d: "M6.907 4.579a8.954 8.954 0 0 1 3.093 -1.356" }),
12
+ h("path", { d: "M12 9v6" }),
13
+ h("path", { d: "M15 12l-3 3l-3 -3" })));
14
+ };
@@ -0,0 +1,5 @@
1
+ export declare const MapStyle: {
2
+ readonly MaputnikOSMLiberty: "https://api.mapka.dev/v1/maputnik/styles/osm-liberty.json";
3
+ };
4
+ export type MapStyle = (typeof MapStyle)[keyof typeof MapStyle];
5
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../src/constants/styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ;;CAEX,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export const MapStyle = {
2
+ MaputnikOSMLiberty: `https://api.mapka.dev/v1/maputnik/styles/osm-liberty.json`,
3
+ };
@@ -0,0 +1,21 @@
1
+ import type { IControl } from "maplibre-gl";
2
+ import type { MapkaMap } from "../map.js";
3
+ import type { MapkaExportOptions } from "../types/export.js";
4
+ export interface MapkaExportControlOptions extends MapkaExportOptions {
5
+ filename?: string;
6
+ }
7
+ export declare class MapkaExportControl implements IControl {
8
+ private map;
9
+ private container;
10
+ private options;
11
+ private isExporting;
12
+ constructor(options?: MapkaExportControlOptions);
13
+ private downloadImage;
14
+ private handleError;
15
+ private onClick;
16
+ private render;
17
+ private unmount;
18
+ onAdd(map: MapkaMap): HTMLElement;
19
+ onRemove(): void;
20
+ }
21
+ //# sourceMappingURL=MapkaExportControl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MapkaExportControl.d.ts","sourceRoot":"","sources":["../../src/controls/MapkaExportControl.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAiBD,qBAAa,kBAAmB,YAAW,QAAQ;IACjD,OAAO,CAAC,GAAG,CAAuB;IAClC,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,GAAE,yBAA8B;IAOnD,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,OAAO,CAmBb;IAEF,OAAO,CAAC,MAAM;IAQd,OAAO,CAAC,OAAO;IAQR,KAAK,CAAC,GAAG,EAAE,QAAQ,GAAG,WAAW;IAWjC,QAAQ,IAAI,IAAI;CAQxB"}
@@ -0,0 +1,76 @@
1
+ // biome-ignore lint/correctness/noUnusedImports: preact jsx
2
+ import { h } from "preact";
3
+ import { render } from "preact";
4
+ import { DownloadIcon } from "../components/DownloadIcon.js";
5
+ import { ProgressDownIcon } from "../components/ProgressDownIcon.js";
6
+ const Button = ({ isExporting, onClick }) => {
7
+ return (h("button", { type: "button", className: "maplibregl-ctrl maplibregl-ctrl-group", title: "Export map as PNG", "aria-label": "Export map as PNG", disabled: isExporting, onClick: onClick }, isExporting ? h(ProgressDownIcon, null) : h(DownloadIcon, null)));
8
+ };
9
+ export class MapkaExportControl {
10
+ map;
11
+ container;
12
+ options;
13
+ isExporting = false;
14
+ constructor(options = {}) {
15
+ this.options = {
16
+ filename: "map-export",
17
+ ...options,
18
+ };
19
+ }
20
+ downloadImage(img) {
21
+ const link = document.createElement("a");
22
+ link.download = `${this.options.filename}.png`;
23
+ link.href = img.src;
24
+ link.click();
25
+ link.remove();
26
+ }
27
+ handleError(error) {
28
+ this.map?.logger.error(error, "Failed to export map image");
29
+ }
30
+ onClick = async () => {
31
+ if (!this.map || this.isExporting)
32
+ return;
33
+ this.isExporting = true;
34
+ this.render();
35
+ this.map
36
+ .export({
37
+ hideControls: true,
38
+ hideMarkers: false,
39
+ hidePopups: false,
40
+ ...this.options,
41
+ })
42
+ .then((img) => this.downloadImage(img))
43
+ .catch((error) => this.handleError(error))
44
+ .finally(() => {
45
+ this.isExporting = false;
46
+ this.render();
47
+ });
48
+ };
49
+ render() {
50
+ if (!this.container) {
51
+ this.map?.logger.error("Export control container not found for rendering");
52
+ return;
53
+ }
54
+ render(h(Button, { isExporting: this.isExporting, onClick: this.onClick }), this.container);
55
+ }
56
+ unmount() {
57
+ if (!this.container) {
58
+ this.map?.logger.error("Export control container not found during unmount");
59
+ return;
60
+ }
61
+ render(null, this.container);
62
+ }
63
+ onAdd(map) {
64
+ this.map = map;
65
+ this.container = document.createElement("div");
66
+ this.container.className = "mapka-export-control";
67
+ this.render();
68
+ return this.container;
69
+ }
70
+ onRemove() {
71
+ this.unmount();
72
+ this.container?.remove?.();
73
+ this.container = undefined;
74
+ this.map = undefined;
75
+ }
76
+ }
package/lib/index.d.ts CHANGED
@@ -2,6 +2,9 @@ export * from "maplibre-gl";
2
2
  export * from "./types/layer.js";
3
3
  export * from "./types/marker.js";
4
4
  export * from "./types/style.js";
5
+ export * from "./types/export.js";
6
+ export * from "./constants/styles.js";
5
7
  export { MapkaMap as Map } from "./map.js";
6
8
  export { MapkaMapOptions as MapOptions } from "./map.js";
9
+ export { MapkaExportControl, MapkaExportControlOptions, } from "./controls/MapkaExportControl.js";
7
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,eAAe,IAAI,UAAU,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AAEtC,OAAO,EAAE,QAAQ,IAAI,GAAG,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,eAAe,IAAI,UAAU,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,kCAAkC,CAAC"}
package/lib/index.js CHANGED
@@ -2,4 +2,7 @@ export * from "maplibre-gl";
2
2
  export * from "./types/layer.js";
3
3
  export * from "./types/marker.js";
4
4
  export * from "./types/style.js";
5
+ export * from "./types/export.js";
6
+ export * from "./constants/styles.js";
5
7
  export { MapkaMap as Map } from "./map.js";
8
+ export { MapkaExportControl, } from "./controls/MapkaExportControl.js";
package/lib/map.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as maplibregl from "maplibre-gl";
2
2
  import type { Marker, Popup, MapOptions, StyleSwapOptions, StyleOptions, StyleSpecification } from "maplibre-gl";
3
3
  import type { MapkaMarkerOptions, MapkaPopupOptions } from "./types/marker.js";
4
+ import type { MapkaExportOptions } from "./types/export.js";
4
5
  export interface MapkaMapOptions extends MapOptions {
5
6
  maxPopups?: number;
6
7
  apiKey: string;
@@ -17,8 +18,14 @@ export type MapMapkaMarker = {
17
18
  options: MapkaMarkerOptions;
18
19
  marker: Marker;
19
20
  };
21
+ interface Logger {
22
+ log: (...args: unknown[]) => void;
23
+ warn: (...args: unknown[]) => void;
24
+ error: (...args: unknown[]) => void;
25
+ }
20
26
  export declare class MapkaMap extends maplibregl.Map {
21
27
  static env: string;
28
+ logger: Logger;
22
29
  markers: MapMapkaMarker[];
23
30
  maxPopups: number;
24
31
  popups: MapMapkaPopup[];
@@ -27,9 +34,11 @@ export declare class MapkaMap extends maplibregl.Map {
27
34
  addMarkers(markers: MapkaMarkerOptions[]): void;
28
35
  updateMarkers(markers: MapkaMarkerOptions[]): void;
29
36
  removeMarkers(): void;
30
- openPopup(popup: MapkaPopupOptions, id?: string): string;
37
+ openPopup(popup: MapkaPopupOptions): string;
31
38
  closePopup(id: string): void;
32
- updatePopup(popup: MapkaPopupOptions, id?: string): void;
39
+ updatePopup(popup: MapkaPopupOptions): void;
33
40
  removePopups(): void;
41
+ export(options?: MapkaExportOptions): Promise<HTMLImageElement>;
34
42
  }
43
+ export {};
35
44
  //# sourceMappingURL=map.d.ts.map
package/lib/map.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;AAiB1C,OAAO,KAAK,EACV,MAAM,EACN,KAAK,EAGL,UAAU,EAEV,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAE/E,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;CAChC;AA0BD,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,qBAAa,QAAS,SAAQ,UAAU,CAAC,GAAG;IAC1C,MAAM,CAAC,GAAG,EAAE,MAAM,CAAU;IAErB,OAAO,EAAE,cAAc,EAAE,CAAM;IAE/B,SAAS,EAAE,MAAM,CAAK;IACtB,MAAM,EAAE,aAAa,EAAE,CAAM;gBAEjB,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAa,EAAE,GAAG,OAAO,EAAE,EAAE,eAAe;IAoBpF,QAAQ,CACb,KAAK,EAAE,MAAM,GAAG,kBAAkB,EAClC,OAAO,GAAE,gBAAgB,GAAG,YAAiB;IAexC,UAAU,CAAC,OAAO,EAAE,kBAAkB,EAAE;IAIxC,aAAa,CAAC,OAAO,EAAE,kBAAkB,EAAE;IAI3C,aAAa;IAIb,SAAS,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,GAAE,MAA0B;IAIlE,UAAU,CAAC,EAAE,EAAE,MAAM;IAIrB,WAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,GAAE,MAA0B;IAIpE,YAAY;CAGpB"}
1
+ {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,aAAa,CAAC;AAiB1C,OAAO,KAAK,EACV,MAAM,EACN,KAAK,EAGL,UAAU,EAEV,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;CAChC;AA0BD,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,WAAW,CAAC;IACvB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,KAAK,EAAE,KAAK,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,kBAAkB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,UAAU,MAAM;IACd,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACrC;AAED,qBAAa,QAAS,SAAQ,UAAU,CAAC,GAAG;IAC1C,MAAM,CAAC,GAAG,EAAE,MAAM,CAAU;IAErB,MAAM,EAAE,MAAM,CAAW;IACzB,OAAO,EAAE,cAAc,EAAE,CAAM;IAE/B,SAAS,EAAE,MAAM,CAAK;IACtB,MAAM,EAAE,aAAa,EAAE,CAAM;gBAEjB,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAa,EAAE,GAAG,OAAO,EAAE,EAAE,eAAe;IAoBpF,QAAQ,CACb,KAAK,EAAE,MAAM,GAAG,kBAAkB,EAClC,OAAO,GAAE,gBAAgB,GAAG,YAAiB;IAexC,UAAU,CAAC,OAAO,EAAE,kBAAkB,EAAE;IAIxC,aAAa,CAAC,OAAO,EAAE,kBAAkB,EAAE;IAI3C,aAAa;IAIb,SAAS,CAAC,KAAK,EAAE,iBAAiB;IAIlC,UAAU,CAAC,EAAE,EAAE,MAAM;IAIrB,WAAW,CAAC,KAAK,EAAE,iBAAiB;IAIpC,YAAY;IAIN,MAAM,CAAC,OAAO,CAAC,EAAE,kBAAkB;CAGjD"}
package/lib/map.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as maplibregl from "maplibre-gl";
2
2
  import { loadLayersIcons } from "./modules/icons.js";
3
- import { closeOnMapClickPopups, closePopupsById, getPopupId, openPopup, removePopups, updatePopup, } from "./modules/popup.js";
3
+ import { closeOnMapClickPopups, closePopupsById, openPopup, removePopups, updatePopup, } from "./modules/popup.js";
4
4
  import { addMarkers, addStyleDiffMarkers, addStyleMarkers, removeMarkers, updateMarkers, } from "./modules/markers.js";
5
+ import { exportMap } from "./modules/export.js";
5
6
  const noopTransformRequest = (url) => {
6
7
  return {
7
8
  url,
@@ -23,6 +24,7 @@ const noopTransformStyle = (_, next) => {
23
24
  };
24
25
  export class MapkaMap extends maplibregl.Map {
25
26
  static env = "prod";
27
+ logger = console;
26
28
  markers = [];
27
29
  maxPopups = 1;
28
30
  popups = [];
@@ -62,16 +64,19 @@ export class MapkaMap extends maplibregl.Map {
62
64
  removeMarkers() {
63
65
  removeMarkers(this);
64
66
  }
65
- openPopup(popup, id = getPopupId(popup)) {
66
- return openPopup(this, popup, id);
67
+ openPopup(popup) {
68
+ return openPopup(this, popup);
67
69
  }
68
70
  closePopup(id) {
69
71
  closePopupsById(this, id);
70
72
  }
71
- updatePopup(popup, id = getPopupId(popup)) {
72
- return updatePopup(this, popup, id);
73
+ updatePopup(popup) {
74
+ return updatePopup(this, popup);
73
75
  }
74
76
  removePopups() {
75
77
  removePopups(this);
76
78
  }
79
+ async export(options) {
80
+ return exportMap(this, options);
81
+ }
77
82
  }
@@ -0,0 +1,4 @@
1
+ import type { MapkaMap } from "../map.js";
2
+ import type { MapkaExportOptions } from "../types/export.js";
3
+ export declare function exportMap(map: MapkaMap, options?: MapkaExportOptions): Promise<HTMLImageElement>;
4
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/modules/export.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,wBAAsB,SAAS,CAC7B,GAAG,EAAE,QAAQ,EACb,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CA+C3B"}
@@ -0,0 +1,40 @@
1
+ import { toPng } from "html-to-image";
2
+ export async function exportMap(map, options = {}) {
3
+ const { hideControls = false, hideMarkers = false, hidePopups = false, bbox } = options;
4
+ const container = map.getContainer();
5
+ const originalBounds = map.getBounds();
6
+ if (bbox) {
7
+ map.fitBounds(bbox, { padding: 20, animate: false });
8
+ }
9
+ return new Promise((resolve, reject) => {
10
+ map.once("render", () => {
11
+ toPng(container, {
12
+ skipFonts: navigator.userAgent.includes("Firefox"),
13
+ filter: (node) => {
14
+ if (node.classList) {
15
+ const isControlsVisibleOrNotControl = !hideControls || !node.classList.contains("maplibregl-control-container");
16
+ const isMarkersVisibleOrNotMarker = !hideMarkers || !node.classList.contains("maplibregl-marker");
17
+ const isPopupsVisibleOrNotPopup = !hidePopups || !node.classList.contains("maplibregl-popup");
18
+ return (isControlsVisibleOrNotControl &&
19
+ isMarkersVisibleOrNotMarker &&
20
+ isPopupsVisibleOrNotPopup);
21
+ }
22
+ return true;
23
+ },
24
+ })
25
+ .then((dataUrl) => {
26
+ const img = new Image();
27
+ img.src = dataUrl;
28
+ img.onload = () => resolve(img);
29
+ img.onerror = reject;
30
+ })
31
+ .catch(reject)
32
+ .finally(() => {
33
+ if (bbox) {
34
+ map.fitBounds(originalBounds, { animate: false });
35
+ }
36
+ });
37
+ });
38
+ map.triggerRepaint();
39
+ });
40
+ }
@@ -6,9 +6,9 @@ export declare function getPopupId(popup: {
6
6
  }): string;
7
7
  export declare function getOnClose(map: MapkaMap, id: string): () => void;
8
8
  export declare function enforceMaxPopups(map: MapkaMap): void;
9
- export declare function openPopup(map: MapkaMap, options: MapkaPopupOptions, id: string): string;
9
+ export declare function openPopup(map: MapkaMap, options: MapkaPopupOptions): string;
10
10
  export declare function updatePopupBaseOptions(popup: Popup, options: MapkaPopupOptions, newOptions: Omit<MapkaPopupOptions, "content">): Popup;
11
- export declare function updatePopup(map: MapkaMap, { content, ...newOptions }: MapkaPopupOptions, id: string): void;
11
+ export declare function updatePopup(map: MapkaMap, { content, ...newOptions }: MapkaPopupOptions): void;
12
12
  export declare function closeOnMapClickPopups(map: MapkaMap): void;
13
13
  export declare function closePopupsById(map: MapkaMap, id: string): void;
14
14
  export declare function removePopups(map: MapkaMap): void;
@@ -1 +1 @@
1
- {"version":3,"file":"popup.d.ts","sourceRoot":"","sources":["../../src/modules/popup.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAIpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG1C,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,UAEhD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,cAEnD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,QAM7C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,UAyD9E;AAID,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,SAY/C;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,QAAQ,EACb,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,EAAE,iBAAiB,EAC7C,EAAE,EAAE,MAAM,QA6BX;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,QAQlD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QAMxD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ,QAMzC"}
1
+ {"version":3,"file":"popup.d.ts","sourceRoot":"","sources":["../../src/modules/popup.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAIpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG1C,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,UAEhD;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,cAEnD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,QAS7C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,UAqDlE;AAID,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,SAY/C;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,GAAG,UAAU,EAAE,EAAE,iBAAiB,QA0BvF;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,QAAQ,QAWlD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,QASxD;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ,QASzC"}
@@ -4,7 +4,7 @@ import { Popup } from "maplibre-gl";
4
4
  import { PopupContent } from "../components/PopupContent.js";
5
5
  import { render } from "preact";
6
6
  import { remove } from "es-toolkit/array";
7
- import { isEqual } from "es-toolkit";
7
+ import { isEqual, isPlainObject } from "es-toolkit";
8
8
  export function getPopupId(popup) {
9
9
  return popup.id ?? `popup-${crypto.randomUUID()}`;
10
10
  }
@@ -15,11 +15,14 @@ export function enforceMaxPopups(map) {
15
15
  if (map.popups.length > map.maxPopups) {
16
16
  const popupToRemove = map.popups.shift();
17
17
  popupToRemove?.popup.remove();
18
+ if (isPlainObject(popupToRemove?.options.content)) {
19
+ render(null, popupToRemove.container);
20
+ }
18
21
  popupToRemove?.container.remove();
19
22
  }
20
23
  }
21
- export function openPopup(map, options, id) {
22
- const { lngLat, content, closeButton, ...popupOptions } = options;
24
+ export function openPopup(map, options) {
25
+ const { lngLat, content, closeButton, id = getPopupId(options), ...popupOptions } = options;
23
26
  if (content instanceof HTMLElement) {
24
27
  const popup = new Popup({
25
28
  ...popupOptions,
@@ -65,7 +68,7 @@ export function openPopup(map, options, id) {
65
68
  return openPopup(map, {
66
69
  ...options,
67
70
  content: newContent,
68
- }, id);
71
+ });
69
72
  }
70
73
  throw new Error("Invalid popup content");
71
74
  }
@@ -82,7 +85,8 @@ export function updatePopupBaseOptions(popup, options, newOptions) {
82
85
  }
83
86
  return popup;
84
87
  }
85
- export function updatePopup(map, { content, ...newOptions }, id) {
88
+ export function updatePopup(map, { content, ...newOptions }) {
89
+ const id = getPopupId(newOptions);
86
90
  if (content instanceof HTMLElement) {
87
91
  const mapkaPopups = map.popups.filter((popup) => popup.id === id);
88
92
  for (const { popup, options } of mapkaPopups) {
@@ -105,13 +109,16 @@ export function updatePopup(map, { content, ...newOptions }, id) {
105
109
  return updatePopup(map, {
106
110
  ...newOptions,
107
111
  content: newContent,
108
- }, id);
112
+ });
109
113
  }
110
114
  }
111
115
  export function closeOnMapClickPopups(map) {
112
116
  const popupsToCloseOnMapClick = remove(map.popups, (popup) => Boolean(popup.options.closeOnClick));
113
117
  for (const popup of popupsToCloseOnMapClick) {
114
118
  popup.popup.remove();
119
+ if (isPlainObject(popup.options.content)) {
120
+ render(null, popup.container);
121
+ }
115
122
  popup.container.remove();
116
123
  }
117
124
  }
@@ -119,12 +126,18 @@ export function closePopupsById(map, id) {
119
126
  const removedPopups = remove(map.popups, (popup) => popup.id === id);
120
127
  for (const popup of removedPopups) {
121
128
  popup.popup.remove();
129
+ if (isPlainObject(popup.options.content)) {
130
+ render(null, popup.container);
131
+ }
122
132
  popup.container.remove();
123
133
  }
124
134
  }
125
135
  export function removePopups(map) {
126
136
  for (const popup of map.popups) {
127
137
  popup.popup.remove();
138
+ if (isPlainObject(popup.options.content)) {
139
+ render(null, popup.container);
140
+ }
128
141
  popup.container.remove();
129
142
  }
130
143
  map.popups = [];
@@ -0,0 +1,7 @@
1
+ export type MapkaExportOptions = {
2
+ hideControls?: boolean;
3
+ hideMarkers?: boolean;
4
+ hidePopups?: boolean;
5
+ bbox?: [number, number, number, number];
6
+ };
7
+ //# sourceMappingURL=export.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../src/types/export.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mapka/maplibre-gl-sdk",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "type": "module",
5
5
  "description": "Mapka JS SDK",
6
6
  "sideEffects": false,
@@ -24,6 +24,7 @@
24
24
  "license": "Apache-2.0",
25
25
  "dependencies": {
26
26
  "es-toolkit": "^1.43.0",
27
+ "html-to-image": "^1.11.13",
27
28
  "maplibre-gl": "^5.15.0",
28
29
  "preact": "^10.28.0"
29
30
  },
@@ -34,5 +35,5 @@
34
35
  "!**/__tests__/",
35
36
  "!lib/buildInfo.json"
36
37
  ],
37
- "gitHead": "b69a4f7130ea4d7d9d6c3a16ef26308cb39e1555"
38
+ "gitHead": "6171bb48248e226a92663f5ac7f6f2823b413e6b"
38
39
  }
@@ -0,0 +1,25 @@
1
+ /** biome-ignore-all lint/correctness/noUnusedImports: <explanation> */
2
+ import { h } from "preact";
3
+
4
+ export const DownloadIcon = () => {
5
+ return (
6
+ <svg
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ width="24"
9
+ height="24"
10
+ viewBox="0 0 24 24"
11
+ fill="none"
12
+ stroke="currentColor"
13
+ stroke-width="2"
14
+ stroke-linecap="round"
15
+ stroke-linejoin="round"
16
+ aria-label="Download"
17
+ >
18
+ <title>Download</title>
19
+ <path stroke="none" d="M0 0h24v24H0z" fill="none" />
20
+ <path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2" />
21
+ <path d="M7 11l5 5l5 -5" />
22
+ <path d="M12 4l0 12" />
23
+ </svg>
24
+ );
25
+ };
@@ -1,4 +1,5 @@
1
1
  /** biome-ignore-all lint/correctness/noUnusedImports: <explanation> */
2
+
2
3
  import { h, Fragment } from "preact";
3
4
  import { useState } from "preact/hooks";
4
5
  import type { MapkaPopupContent } from "../types/marker.js";
@@ -0,0 +1,29 @@
1
+ /** biome-ignore-all lint/correctness/noUnusedImports: <explanation> */
2
+ import { h } from "preact";
3
+
4
+ export const ProgressDownIcon = () => {
5
+ return (
6
+ <svg
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ width="24"
9
+ height="24"
10
+ viewBox="0 0 24 24"
11
+ fill="none"
12
+ stroke="currentColor"
13
+ stroke-width="2"
14
+ stroke-linecap="round"
15
+ stroke-linejoin="round"
16
+ class="icon icon-tabler icons-tabler-outline icon-tabler-progress-down"
17
+ >
18
+ <title>Progress Download</title>
19
+ <path stroke="none" d="M0 0h24v24H0z" fill="none" />
20
+ <path d="M10 20.777a8.942 8.942 0 0 1 -2.48 -.969" />
21
+ <path d="M14 3.223a9.003 9.003 0 0 1 0 17.554" />
22
+ <path d="M4.579 17.093a8.961 8.961 0 0 1 -1.227 -2.592" />
23
+ <path d="M3.124 10.5c.16 -.95 .468 -1.85 .9 -2.675l.169 -.305" />
24
+ <path d="M6.907 4.579a8.954 8.954 0 0 1 3.093 -1.356" />
25
+ <path d="M12 9v6" />
26
+ <path d="M15 12l-3 3l-3 -3" />
27
+ </svg>
28
+ );
29
+ };
@@ -0,0 +1,5 @@
1
+ export const MapStyle = {
2
+ MaputnikOSMLiberty: `https://api.mapka.dev/v1/maputnik/styles/osm-liberty.json`,
3
+ } as const;
4
+
5
+ export type MapStyle = (typeof MapStyle)[keyof typeof MapStyle];