@maptiler/sdk 3.8.0-rc8 → 3.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
@@ -451,7 +451,145 @@ const map = new Map({
451
451
  })
452
452
  ```
453
453
 
454
+ # 🧩 Custom Controls
454
455
 
456
+ MapTiler SDK JS supports two flexible ways to add custom controls to your map interface. Whether you're building a dynamic application or integrating with static HTML, there's a matching approach for both.
457
+
458
+ ## Programmatic Controls
459
+
460
+ Use `map.addControl()` with `MaptilerExternalControl` to register custom UI elements manually. This approach is ideal for dynamic logic, event-driven behavior, or integration with frameworks like React. The control element can be provided either as a reference to the **element itself**, or as its **CSS selector**. Optionally, two callback functions can be provided:
461
+
462
+ * `onClick` function that is called when the element is clicked, and
463
+ * `onRender` function that is called every time the map renders a new state.
464
+
465
+ Both callbacks receive the active `Map` instance, the associated control element itself, and an event object associated with the original event (`PointerEvent` and `MapLibreEvent` respectively).
466
+
467
+ ### Example
468
+
469
+ ```ts
470
+ const panControl = new maptilersdk.MaptilerExternalControl(
471
+ ".pan-control",
472
+ (map) => map.panBy([10, 10]), // Move southeast on click
473
+ (map, el) => el.classList.toggle( // Style based on hemisphere
474
+ "northern-hemisphere", map.getCenter().lat > 0
475
+ )
476
+ );
477
+ map.addControl(panControl);
478
+
479
+ const element = document.createElement("button");
480
+ element.textContent = "Pan NW";
481
+ map.addControl(
482
+ new maptilersdk.MaptilerExternalControl(
483
+ element,
484
+ (map) => map.panBy([-10, -10]) // Move northwest
485
+ ),
486
+ "top-left"
487
+ );
488
+ ```
489
+
490
+ ### Behavior Overview
491
+
492
+ - On add, control element is moved into the map UI
493
+ - `onClick` binds user interaction
494
+ - `onRender` enables state-based styling or logic
495
+ - Control maintains its own DOM context
496
+ - On removal, element is returned to its original DOM position (if any) to not interfere with DOM handling of frameworks like React
497
+
498
+ ## Declarative Controls
499
+
500
+ Add controls using HTML attributes – no JavaScript required. This is perfect for simple UI setups.
501
+
502
+ ### Enabling Detection
503
+
504
+ ```ts
505
+ const map = new maptilersdk.Map({
506
+ container: "map",
507
+ customControls: true, // or ".custom-ui"
508
+ });
509
+ ```
510
+
511
+ You can pass `true` to enable detection globally, or a CSS selector to scope it.
512
+
513
+ ### Declaring Controls
514
+
515
+ Use `data-maptiler-control` attribute:
516
+
517
+ ```html
518
+ <button data-maptiler-control="zoom-in">+</button>
519
+ ```
520
+
521
+ Supported values:
522
+
523
+ | Value | Description |
524
+ |---------------------|--------------------------------------------------|
525
+ | `zoom-in` | Zooms in |
526
+ | `zoom-out` | Zooms out |
527
+ | `toggle-projection` | Switches Mercator ↔ Globe |
528
+ | `toggle-terrain` | Toggles terrain layer |
529
+ | `reset-view` | Resets bearing, pitch, and roll |
530
+ | `reset-bearing` | Resets bearing only |
531
+ | `reset-pitch` | Resets pitch only |
532
+ | `reset-roll` | Resets roll only |
533
+ | *(empty)* | Registers control without built-in functionality |
534
+
535
+ > ⚠️ An error is thrown if an unrecognized value is used.
536
+
537
+ ### Grouping Controls
538
+
539
+ Use `data-maptiler-control-group` to group buttons:
540
+
541
+ ```html
542
+ <div data-maptiler-control-group>
543
+ <button data-maptiler-control="zoom-in">+</button>
544
+ <button data-maptiler-control="zoom-out">−</button>
545
+ </div>
546
+ ```
547
+
548
+ Groups are styled and positioned together but don't add functionality themselves. Functional behavior is attached to valid descendant elements.
549
+
550
+ ### Positioning Controls
551
+
552
+ Use `data-maptiler-position` to set placement:
553
+
554
+ ```html
555
+ <button data-maptiler-control="reset-view" data-maptiler-position="top-left">↻</button>
556
+ <div data-maptiler-control-group data-maptiler-position="bottom-right">
557
+ <button data-maptiler-control="zoom-in">+</button>
558
+ <button data-maptiler-control="zoom-out">−</button>
559
+ </div>
560
+ ```
561
+
562
+ Valid positions: `'top-left'`, `'top-right'`, `'bottom-left'`, `'bottom-right'`
563
+
564
+ ## Styling with CSS Variables
565
+
566
+ When declarative controls are enabled, the map container exposes dynamic CSS variables:
567
+
568
+ | Variable | Description | Type |
569
+ |----------------------------------|--------------------------------------------------|-----------------|
570
+ | `--maptiler-center-lng` | Longitude of center | unitless number |
571
+ | `--maptiler-center-lat` | Latitude of center | unitless number |
572
+ | `--maptiler-zoom` | Zoom level | unitless number |
573
+ | `--maptiler-bearing` | Map rotation | unitless number |
574
+ | `--maptiler-pitch` | Pitch angle | unitless number |
575
+ | `--maptiler-roll` | Roll angle | unitless number |
576
+ | `--maptiler-is-globe-projection` | `true` if globe is active<br>`false` otherwise | string |
577
+ | `--maptiler-has-terrain` | `true` if terrain is active<br>`false` otherwise | string |
578
+
579
+ ### Example
580
+
581
+ ```css
582
+ .compass-icon {
583
+ transform: rotateX(calc(var(--maptiler-pitch) * 1deg))
584
+ rotateZ(calc(var(--maptiler-bearing) * -1deg));
585
+ }
586
+
587
+ @container style(--maptiler-is-globe-projection: true) {
588
+ .projection-icon {
589
+ content: "globe";
590
+ }
591
+ }
592
+ ```
455
593
 
456
594
  # 3D terrain in one call
457
595
  <p align="center">
@@ -592,6 +730,13 @@ map.on("load", () => {
592
730
  });
593
731
  });
594
732
  ```
733
+
734
+ To disable state transitions for halo or space:
735
+ ```ts
736
+ map.disableHaloAnimations();
737
+ map.disableSpaceAnimations();
738
+ ```
739
+
595
740
  ## `space` (Background Environment)
596
741
 
597
742
  The space option allows customizing the background environment of the globe, simulating deep space or skybox effects.
@@ -677,7 +822,7 @@ Further code examples can be found in `~/demos/`
677
822
 
678
823
  # `ImageViewer`
679
824
 
680
- MapTiler's `ImageViewer` component allows you to display tiled, non-georeferenced images but interact with them the same way you would if you were displaying map. These can be handy for zoomable non-georeferenced, geographically "inaccurate" maps such as hotel maps, golf courses, theme parks etc. Think pixels instead of lattitudes and longtidues.
825
+ MapTiler's `ImageViewer` component allows you to display tiled, non-georeferenced images but interact with them in almost the same way you would if you were displaying map. These can be handy for zoomable non-georeferenced, geographically "inaccurate" maps such as hotel maps, golf courses, theme parks etc. Think pixels instead of lattitudes and longtidues.
681
826
 
682
827
  ```ts
683
828
  export type ImageViewerConstructorOptions = {