@accelint/map-toolkit 1.2.0 → 1.3.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.
Files changed (131) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/catalog-info.yaml +3 -3
  3. package/dist/camera/events.d.ts +45 -0
  4. package/dist/camera/events.js +45 -0
  5. package/dist/camera/events.js.map +1 -1
  6. package/dist/camera/store.d.ts +47 -0
  7. package/dist/camera/store.js +81 -0
  8. package/dist/camera/store.js.map +1 -1
  9. package/dist/camera/types.d.ts +81 -0
  10. package/dist/cursor-coordinates/constants.d.ts +8 -0
  11. package/dist/cursor-coordinates/constants.js +22 -0
  12. package/dist/cursor-coordinates/constants.js.map +1 -0
  13. package/dist/cursor-coordinates/store.d.ts +1 -0
  14. package/dist/cursor-coordinates/store.js +1 -0
  15. package/dist/cursor-coordinates/store.js.map +1 -1
  16. package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +5 -0
  17. package/dist/cursor-coordinates/use-cursor-coordinates.js +23 -8
  18. package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
  19. package/dist/deckgl/base-map/constants.d.ts +12 -0
  20. package/dist/deckgl/base-map/constants.js +12 -0
  21. package/dist/deckgl/base-map/constants.js.map +1 -1
  22. package/dist/deckgl/base-map/controls.d.ts +11 -1
  23. package/dist/deckgl/base-map/controls.js +5 -0
  24. package/dist/deckgl/base-map/controls.js.map +1 -1
  25. package/dist/deckgl/base-map/events.d.ts +30 -0
  26. package/dist/deckgl/base-map/events.js +30 -0
  27. package/dist/deckgl/base-map/events.js.map +1 -1
  28. package/dist/deckgl/base-map/index.d.ts +2 -2
  29. package/dist/deckgl/base-map/index.js +33 -3
  30. package/dist/deckgl/base-map/index.js.map +1 -1
  31. package/dist/deckgl/base-map/provider.d.ts +2 -2
  32. package/dist/deckgl/index.js +1 -1
  33. package/dist/deckgl/saved-viewports/index.d.ts +75 -0
  34. package/dist/deckgl/saved-viewports/index.js +58 -0
  35. package/dist/deckgl/saved-viewports/index.js.map +1 -1
  36. package/dist/deckgl/saved-viewports/storage.d.ts +51 -0
  37. package/dist/deckgl/saved-viewports/storage.js +64 -0
  38. package/dist/deckgl/saved-viewports/storage.js.map +1 -1
  39. package/dist/deckgl/shapes/display-shape-layer/constants.js +18 -6
  40. package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
  41. package/dist/deckgl/shapes/display-shape-layer/fiber.d.ts +7 -0
  42. package/dist/deckgl/shapes/display-shape-layer/fiber.js.map +1 -1
  43. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +61 -4
  44. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -1
  45. package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +22 -8
  46. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +75 -4
  47. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -1
  48. package/dist/deckgl/shapes/draw-shape-layer/constants.js +30 -0
  49. package/dist/deckgl/shapes/draw-shape-layer/constants.js.map +1 -1
  50. package/dist/deckgl/shapes/draw-shape-layer/fiber.js +36 -0
  51. package/dist/deckgl/shapes/draw-shape-layer/fiber.js.map +1 -1
  52. package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +2 -2
  53. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +32 -1
  54. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -1
  55. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +37 -8
  56. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js.map +1 -1
  57. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +43 -1
  58. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -1
  59. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +44 -1
  60. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -1
  61. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +46 -3
  62. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -1
  63. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js +37 -1
  64. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js.map +1 -1
  65. package/dist/deckgl/shapes/draw-shape-layer/store.js +50 -2
  66. package/dist/deckgl/shapes/draw-shape-layer/store.js.map +1 -1
  67. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js +138 -17
  68. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js.map +1 -1
  69. package/dist/deckgl/shapes/edit-shape-layer/events.js +1 -1
  70. package/dist/deckgl/shapes/edit-shape-layer/events.js.map +1 -1
  71. package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +2 -2
  72. package/dist/deckgl/shapes/edit-shape-layer/index.js +14 -0
  73. package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -1
  74. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js +56 -8
  75. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js.map +1 -1
  76. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +26 -4
  77. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -1
  78. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +28 -3
  79. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -1
  80. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js +24 -0
  81. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js.map +1 -1
  82. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js +33 -4
  83. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js.map +1 -1
  84. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js +21 -2
  85. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js.map +1 -1
  86. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js +35 -11
  87. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js.map +1 -1
  88. package/dist/deckgl/shapes/edit-shape-layer/store.js +1 -1
  89. package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -1
  90. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js +12 -0
  91. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js.map +1 -1
  92. package/dist/deckgl/shapes/shared/types.d.ts +3 -3
  93. package/dist/deckgl/shapes/shared/types.js +2 -2
  94. package/dist/deckgl/shapes/shared/types.js.map +1 -1
  95. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js +3 -3
  96. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -1
  97. package/dist/deckgl/shapes/shared/utils/pick-filtering.js +1 -1
  98. package/dist/deckgl/shapes/shared/utils/pick-filtering.js.map +1 -1
  99. package/dist/deckgl/symbol-layer/fiber.d.ts +18 -0
  100. package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
  101. package/dist/deckgl/symbol-layer/index.d.ts +79 -1
  102. package/dist/deckgl/symbol-layer/index.js +72 -1
  103. package/dist/deckgl/symbol-layer/index.js.map +1 -1
  104. package/dist/deckgl/text-layer/character-sets.d.ts +30 -0
  105. package/dist/deckgl/text-layer/character-sets.js +26 -0
  106. package/dist/deckgl/text-layer/character-sets.js.map +1 -1
  107. package/dist/deckgl/text-layer/default-settings.d.ts +29 -0
  108. package/dist/deckgl/text-layer/default-settings.js +28 -0
  109. package/dist/deckgl/text-layer/default-settings.js.map +1 -1
  110. package/dist/deckgl/text-layer/index.d.ts +65 -0
  111. package/dist/deckgl/text-layer/index.js +56 -0
  112. package/dist/deckgl/text-layer/index.js.map +1 -1
  113. package/dist/map-cursor/events.d.ts +19 -0
  114. package/dist/map-cursor/events.js +19 -0
  115. package/dist/map-cursor/events.js.map +1 -1
  116. package/dist/map-cursor/store.d.ts +34 -2
  117. package/dist/map-cursor/store.js +44 -3
  118. package/dist/map-cursor/store.js.map +1 -1
  119. package/dist/map-mode/store.d.ts +43 -4
  120. package/dist/map-mode/store.js +56 -6
  121. package/dist/map-mode/store.js.map +1 -1
  122. package/dist/shared/create-map-store.d.ts +14 -0
  123. package/dist/shared/create-map-store.js +26 -2
  124. package/dist/shared/create-map-store.js.map +1 -1
  125. package/dist/shared/units.d.ts +24 -0
  126. package/dist/shared/units.js +24 -0
  127. package/dist/shared/units.js.map +1 -1
  128. package/dist/viewport/store.d.ts +1 -0
  129. package/dist/viewport/store.js +4 -0
  130. package/dist/viewport/store.js.map +1 -1
  131. package/package.json +3 -3
@@ -15,17 +15,92 @@ import { MapViewState } from "@deck.gl/core";
15
15
  import { RequireAllOrNone } from "type-fest";
16
16
 
17
17
  //#region src/deckgl/saved-viewports/index.d.ts
18
+ /**
19
+ * Base options required for saved viewport functionality.
20
+ */
18
21
  type BaseOptions = {
22
+ /** Optional identifier to namespace saved viewports for multiple map instances */
19
23
  uniqueIdentifier?: string;
24
+ /** Milliseconds to hold a key before saving (default: 1000) */
20
25
  threshold?: number;
26
+ /** Function that returns the current map viewport state */
21
27
  getCurrentViewport: () => MapViewState;
28
+ /** Function that receives a viewport state and applies it to the map */
22
29
  setCurrentViewport: (viewport: MapViewState) => void;
23
30
  };
31
+ /**
32
+ * Optional custom storage functions for persisting viewports.
33
+ * Both functions must be provided together or omitted entirely.
34
+ */
24
35
  type PersistOptions = RequireAllOrNone<{
36
+ /** Custom function to retrieve saved viewports from storage */
25
37
  getSavedViewport: (id: KeyCombinationId, uniqueIdentifier?: string) => MapViewState;
38
+ /** Custom function to persist saved viewports to storage */
26
39
  setSavedViewport: (id: KeyCombinationId, viewport: MapViewState, uniqueIdentifier?: string) => void;
27
40
  }>;
41
+ /**
42
+ * Configuration options for creating a saved viewport hotkey system.
43
+ * Combines hotkey options with viewport management callbacks and optional custom storage.
44
+ */
28
45
  type SavedViewportOptions = Partial<HotkeyOptions> & BaseOptions & PersistOptions;
46
+ /**
47
+ * Creates a React hook that registers hotkeys for saving and restoring map viewports.
48
+ *
49
+ * By default, uses number keys 0-9 where:
50
+ * - **Hold** a key for the threshold duration (default 1s) to save the current viewport
51
+ * - **Tap** a key to restore the saved viewport
52
+ *
53
+ * Viewports are persisted to localStorage by default but can be customized with
54
+ * `getSavedViewport` and `setSavedViewport` options.
55
+ *
56
+ * @param options - Configuration for viewport saving behavior and storage
57
+ * @returns A React hook function that must be called within a component to activate hotkeys
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * import { Broadcast } from '@accelint/bus';
62
+ * import { useOn } from '@accelint/bus/react';
63
+ * import { uuid } from '@accelint/core';
64
+ * import { BaseMap } from '@accelint/map-toolkit/deckgl';
65
+ * import { MapEvents } from '@accelint/map-toolkit/deckgl/base-map';
66
+ * import { CameraEventTypes } from '@accelint/map-toolkit/camera';
67
+ * import { createSavedViewport } from '@accelint/map-toolkit/deckgl/saved-viewports';
68
+ * import { globalBind } from '@accelint/hotkey-manager';
69
+ * import type { MapViewState } from '@deck.gl/core';
70
+ * import type { CameraEvent } from '@accelint/map-toolkit/camera';
71
+ * import type { MapViewportEvent, MapViewportPayload } from '@accelint/map-toolkit/deckgl/base-map';
72
+ *
73
+ * globalBind();
74
+ *
75
+ * const MAP_ID = uuid();
76
+ * const cameraBus = Broadcast.getInstance<CameraEvent>();
77
+ * let currentViewport: MapViewportPayload;
78
+ *
79
+ * const useSavedViewportHotkey = createSavedViewport({
80
+ * threshold: 1000,
81
+ * getCurrentViewport: () => currentViewport,
82
+ * setCurrentViewport: (newState: MapViewState) => {
83
+ * currentViewport = { ...currentViewport, ...newState };
84
+ * cameraBus.emit(CameraEventTypes.setCenter, {
85
+ * id: MAP_ID,
86
+ * latitude: newState.latitude ?? currentViewport.latitude,
87
+ * longitude: newState.longitude ?? currentViewport.longitude,
88
+ * zoom: newState.zoom,
89
+ * });
90
+ * },
91
+ * });
92
+ *
93
+ * export function MapView() {
94
+ * useSavedViewportHotkey();
95
+ *
96
+ * useOn<MapViewportEvent>(MapEvents.viewport, (event) => {
97
+ * currentViewport = { ...currentViewport, ...event.payload };
98
+ * });
99
+ *
100
+ * return <BaseMap id={MAP_ID} className="w-full h-full" />;
101
+ * }
102
+ * ```
103
+ */
29
104
  declare const createSavedViewport: (options: SavedViewportOptions) => ReturnType<typeof registerHotkey>;
30
105
  //#endregion
31
106
  export { SavedViewportOptions, createSavedViewport };
@@ -15,6 +15,64 @@ import { STORAGE_ID, persist, retrieve } from "./storage.js";
15
15
  import { Keycode, registerHotkey } from "@accelint/hotkey-manager";
16
16
 
17
17
  //#region src/deckgl/saved-viewports/index.ts
18
+ /**
19
+ * Creates a React hook that registers hotkeys for saving and restoring map viewports.
20
+ *
21
+ * By default, uses number keys 0-9 where:
22
+ * - **Hold** a key for the threshold duration (default 1s) to save the current viewport
23
+ * - **Tap** a key to restore the saved viewport
24
+ *
25
+ * Viewports are persisted to localStorage by default but can be customized with
26
+ * `getSavedViewport` and `setSavedViewport` options.
27
+ *
28
+ * @param options - Configuration for viewport saving behavior and storage
29
+ * @returns A React hook function that must be called within a component to activate hotkeys
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * import { Broadcast } from '@accelint/bus';
34
+ * import { useOn } from '@accelint/bus/react';
35
+ * import { uuid } from '@accelint/core';
36
+ * import { BaseMap } from '@accelint/map-toolkit/deckgl';
37
+ * import { MapEvents } from '@accelint/map-toolkit/deckgl/base-map';
38
+ * import { CameraEventTypes } from '@accelint/map-toolkit/camera';
39
+ * import { createSavedViewport } from '@accelint/map-toolkit/deckgl/saved-viewports';
40
+ * import { globalBind } from '@accelint/hotkey-manager';
41
+ * import type { MapViewState } from '@deck.gl/core';
42
+ * import type { CameraEvent } from '@accelint/map-toolkit/camera';
43
+ * import type { MapViewportEvent, MapViewportPayload } from '@accelint/map-toolkit/deckgl/base-map';
44
+ *
45
+ * globalBind();
46
+ *
47
+ * const MAP_ID = uuid();
48
+ * const cameraBus = Broadcast.getInstance<CameraEvent>();
49
+ * let currentViewport: MapViewportPayload;
50
+ *
51
+ * const useSavedViewportHotkey = createSavedViewport({
52
+ * threshold: 1000,
53
+ * getCurrentViewport: () => currentViewport,
54
+ * setCurrentViewport: (newState: MapViewState) => {
55
+ * currentViewport = { ...currentViewport, ...newState };
56
+ * cameraBus.emit(CameraEventTypes.setCenter, {
57
+ * id: MAP_ID,
58
+ * latitude: newState.latitude ?? currentViewport.latitude,
59
+ * longitude: newState.longitude ?? currentViewport.longitude,
60
+ * zoom: newState.zoom,
61
+ * });
62
+ * },
63
+ * });
64
+ *
65
+ * export function MapView() {
66
+ * useSavedViewportHotkey();
67
+ *
68
+ * useOn<MapViewportEvent>(MapEvents.viewport, (event) => {
69
+ * currentViewport = { ...currentViewport, ...event.payload };
70
+ * });
71
+ *
72
+ * return <BaseMap id={MAP_ID} className="w-full h-full" />;
73
+ * }
74
+ * ```
75
+ */
18
76
  const createSavedViewport = (options) => {
19
77
  const setFn = options.setSavedViewport ?? persist;
20
78
  const getFn = options.getSavedViewport ?? retrieve;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/deckgl/saved-viewports/index.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n type HotkeyOptions,\n type KeyCombination,\n type KeyCombinationId,\n Keycode,\n registerHotkey,\n} from '@accelint/hotkey-manager';\nimport { persist, retrieve, STORAGE_ID } from './storage';\nimport type { MapViewState } from '@deck.gl/core';\nimport type { RequireAllOrNone } from 'type-fest';\n\ntype BaseOptions = {\n uniqueIdentifier?: string;\n threshold?: number;\n getCurrentViewport: () => MapViewState;\n setCurrentViewport: (viewport: MapViewState) => void;\n};\n\ntype PersistOptions = RequireAllOrNone<{\n getSavedViewport: (\n id: KeyCombinationId,\n uniqueIdentifier?: string,\n ) => MapViewState;\n setSavedViewport: (\n id: KeyCombinationId,\n viewport: MapViewState,\n uniqueIdentifier?: string,\n ) => void;\n}>;\n\nexport type SavedViewportOptions = Partial<HotkeyOptions> &\n BaseOptions &\n PersistOptions;\n\nexport const createSavedViewport = (\n options: SavedViewportOptions,\n): ReturnType<typeof registerHotkey> => {\n const setFn = options.setSavedViewport ?? persist;\n const getFn = options.getSavedViewport ?? retrieve;\n\n return registerHotkey({\n id: STORAGE_ID,\n heldThresholdMs: options.threshold,\n key: options.key ?? [\n {\n code: Keycode.Digit0,\n },\n {\n code: Keycode.Digit1,\n },\n {\n code: Keycode.Digit2,\n },\n {\n code: Keycode.Digit3,\n },\n {\n code: Keycode.Digit4,\n },\n {\n code: Keycode.Digit5,\n },\n {\n code: Keycode.Digit6,\n },\n {\n code: Keycode.Digit7,\n },\n {\n code: Keycode.Digit8,\n },\n {\n code: Keycode.Digit9,\n },\n ],\n onKeyHeld: (e: KeyboardEvent, key: KeyCombination) => {\n e.preventDefault();\n const viewport = options.getCurrentViewport();\n setFn(key.id, viewport, options.uniqueIdentifier);\n },\n onKeyUp: (e: KeyboardEvent, key: KeyCombination) => {\n e.preventDefault();\n const viewport = getFn(key.id, options.uniqueIdentifier);\n if (viewport) {\n options.setCurrentViewport(viewport);\n }\n },\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;AA8CA,MAAa,uBACX,YACsC;CACtC,MAAM,QAAQ,QAAQ,oBAAoB;CAC1C,MAAM,QAAQ,QAAQ,oBAAoB;AAE1C,QAAO,eAAe;EACpB,IAAI;EACJ,iBAAiB,QAAQ;EACzB,KAAK,QAAQ,OAAO;GAClB,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACF;EACD,YAAY,GAAkB,QAAwB;AACpD,KAAE,gBAAgB;GAClB,MAAM,WAAW,QAAQ,oBAAoB;AAC7C,SAAM,IAAI,IAAI,UAAU,QAAQ,iBAAiB;;EAEnD,UAAU,GAAkB,QAAwB;AAClD,KAAE,gBAAgB;GAClB,MAAM,WAAW,MAAM,IAAI,IAAI,QAAQ,iBAAiB;AACxD,OAAI,SACF,SAAQ,mBAAmB,SAAS;;EAGzC,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/deckgl/saved-viewports/index.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n type HotkeyOptions,\n type KeyCombination,\n type KeyCombinationId,\n Keycode,\n registerHotkey,\n} from '@accelint/hotkey-manager';\nimport { persist, retrieve, STORAGE_ID } from './storage';\nimport type { MapViewState } from '@deck.gl/core';\nimport type { RequireAllOrNone } from 'type-fest';\n\n/**\n * Base options required for saved viewport functionality.\n */\ntype BaseOptions = {\n /** Optional identifier to namespace saved viewports for multiple map instances */\n uniqueIdentifier?: string;\n /** Milliseconds to hold a key before saving (default: 1000) */\n threshold?: number;\n /** Function that returns the current map viewport state */\n getCurrentViewport: () => MapViewState;\n /** Function that receives a viewport state and applies it to the map */\n setCurrentViewport: (viewport: MapViewState) => void;\n};\n\n/**\n * Optional custom storage functions for persisting viewports.\n * Both functions must be provided together or omitted entirely.\n */\ntype PersistOptions = RequireAllOrNone<{\n /** Custom function to retrieve saved viewports from storage */\n getSavedViewport: (\n id: KeyCombinationId,\n uniqueIdentifier?: string,\n ) => MapViewState;\n /** Custom function to persist saved viewports to storage */\n setSavedViewport: (\n id: KeyCombinationId,\n viewport: MapViewState,\n uniqueIdentifier?: string,\n ) => void;\n}>;\n\n/**\n * Configuration options for creating a saved viewport hotkey system.\n * Combines hotkey options with viewport management callbacks and optional custom storage.\n */\nexport type SavedViewportOptions = Partial<HotkeyOptions> &\n BaseOptions &\n PersistOptions;\n\n/**\n * Creates a React hook that registers hotkeys for saving and restoring map viewports.\n *\n * By default, uses number keys 0-9 where:\n * - **Hold** a key for the threshold duration (default 1s) to save the current viewport\n * - **Tap** a key to restore the saved viewport\n *\n * Viewports are persisted to localStorage by default but can be customized with\n * `getSavedViewport` and `setSavedViewport` options.\n *\n * @param options - Configuration for viewport saving behavior and storage\n * @returns A React hook function that must be called within a component to activate hotkeys\n *\n * @example\n * ```tsx\n * import { Broadcast } from '@accelint/bus';\n * import { useOn } from '@accelint/bus/react';\n * import { uuid } from '@accelint/core';\n * import { BaseMap } from '@accelint/map-toolkit/deckgl';\n * import { MapEvents } from '@accelint/map-toolkit/deckgl/base-map';\n * import { CameraEventTypes } from '@accelint/map-toolkit/camera';\n * import { createSavedViewport } from '@accelint/map-toolkit/deckgl/saved-viewports';\n * import { globalBind } from '@accelint/hotkey-manager';\n * import type { MapViewState } from '@deck.gl/core';\n * import type { CameraEvent } from '@accelint/map-toolkit/camera';\n * import type { MapViewportEvent, MapViewportPayload } from '@accelint/map-toolkit/deckgl/base-map';\n *\n * globalBind();\n *\n * const MAP_ID = uuid();\n * const cameraBus = Broadcast.getInstance<CameraEvent>();\n * let currentViewport: MapViewportPayload;\n *\n * const useSavedViewportHotkey = createSavedViewport({\n * threshold: 1000,\n * getCurrentViewport: () => currentViewport,\n * setCurrentViewport: (newState: MapViewState) => {\n * currentViewport = { ...currentViewport, ...newState };\n * cameraBus.emit(CameraEventTypes.setCenter, {\n * id: MAP_ID,\n * latitude: newState.latitude ?? currentViewport.latitude,\n * longitude: newState.longitude ?? currentViewport.longitude,\n * zoom: newState.zoom,\n * });\n * },\n * });\n *\n * export function MapView() {\n * useSavedViewportHotkey();\n *\n * useOn<MapViewportEvent>(MapEvents.viewport, (event) => {\n * currentViewport = { ...currentViewport, ...event.payload };\n * });\n *\n * return <BaseMap id={MAP_ID} className=\"w-full h-full\" />;\n * }\n * ```\n */\nexport const createSavedViewport = (\n options: SavedViewportOptions,\n): ReturnType<typeof registerHotkey> => {\n const setFn = options.setSavedViewport ?? persist;\n const getFn = options.getSavedViewport ?? retrieve;\n\n return registerHotkey({\n id: STORAGE_ID,\n heldThresholdMs: options.threshold,\n key: options.key ?? [\n {\n code: Keycode.Digit0,\n },\n {\n code: Keycode.Digit1,\n },\n {\n code: Keycode.Digit2,\n },\n {\n code: Keycode.Digit3,\n },\n {\n code: Keycode.Digit4,\n },\n {\n code: Keycode.Digit5,\n },\n {\n code: Keycode.Digit6,\n },\n {\n code: Keycode.Digit7,\n },\n {\n code: Keycode.Digit8,\n },\n {\n code: Keycode.Digit9,\n },\n ],\n onKeyHeld: (e: KeyboardEvent, key: KeyCombination) => {\n e.preventDefault();\n const viewport = options.getCurrentViewport();\n setFn(key.id, viewport, options.uniqueIdentifier);\n },\n onKeyUp: (e: KeyboardEvent, key: KeyCombination) => {\n e.preventDefault();\n const viewport = getFn(key.id, options.uniqueIdentifier);\n if (viewport) {\n options.setCurrentViewport(viewport);\n }\n },\n });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyHA,MAAa,uBACX,YACsC;CACtC,MAAM,QAAQ,QAAQ,oBAAoB;CAC1C,MAAM,QAAQ,QAAQ,oBAAoB;AAE1C,QAAO,eAAe;EACpB,IAAI;EACJ,iBAAiB,QAAQ;EACzB,KAAK,QAAQ,OAAO;GAClB,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACD,EACE,MAAM,QAAQ,QACf;GACF;EACD,YAAY,GAAkB,QAAwB;AACpD,KAAE,gBAAgB;GAClB,MAAM,WAAW,QAAQ,oBAAoB;AAC7C,SAAM,IAAI,IAAI,UAAU,QAAQ,iBAAiB;;EAEnD,UAAU,GAAkB,QAAwB;AAClD,KAAE,gBAAgB;GAClB,MAAM,WAAW,MAAM,IAAI,IAAI,QAAQ,iBAAiB;AACxD,OAAI,SACF,SAAQ,mBAAmB,SAAS;;EAGzC,CAAC"}
@@ -13,8 +13,59 @@
13
13
  import { MapViewState } from "@deck.gl/core";
14
14
 
15
15
  //#region src/deckgl/saved-viewports/storage.d.ts
16
+ /**
17
+ * Base storage key for saved viewports in localStorage.
18
+ */
16
19
  declare const STORAGE_ID = "deckgl-saved-viewports";
20
+ /**
21
+ * Persists a viewport state to localStorage.
22
+ *
23
+ * Saves the viewport under the given ID within a namespaced container.
24
+ * If the container doesn't exist, creates it. If the ID already exists, overwrites it.
25
+ *
26
+ * @param id - Unique identifier for this viewport (typically a key combination ID)
27
+ * @param obj - The MapViewState to persist
28
+ * @param uniqueIdentifier - Optional namespace for multiple map instances
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * import { persist } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';
33
+ *
34
+ * const viewport = {
35
+ * latitude: 38.9072,
36
+ * longitude: -77.0369,
37
+ * zoom: 10,
38
+ * pitch: 0,
39
+ * bearing: 0,
40
+ * };
41
+ *
42
+ * persist('Digit1', viewport);
43
+ * persist('Digit2', viewport, 'main-map');
44
+ * ```
45
+ */
17
46
  declare const persist: (id: string, obj: MapViewState, uniqueIdentifier?: string) => void;
47
+ /**
48
+ * Retrieves a saved viewport state from localStorage.
49
+ *
50
+ * Returns the viewport associated with the given ID, or undefined if not found.
51
+ * Logs a warning if the viewport doesn't exist.
52
+ *
53
+ * @param id - Unique identifier for the viewport to retrieve
54
+ * @param uniqueIdentifier - Optional namespace for multiple map instances
55
+ * @returns The saved MapViewState or undefined if not found
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * import { retrieve } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';
60
+ *
61
+ * const viewport = retrieve('Digit1');
62
+ * if (viewport) {
63
+ * console.log('Restored viewport:', viewport);
64
+ * }
65
+ *
66
+ * const mainMapViewport = retrieve('Digit1', 'main-map');
67
+ * ```
68
+ */
18
69
  declare const retrieve: (id: string, uniqueIdentifier?: string) => any;
19
70
  //#endregion
20
71
  export { STORAGE_ID, persist, retrieve };
@@ -20,8 +20,24 @@ const logger = getLogger({
20
20
  prefix: "[SavedViewports]",
21
21
  pretty: true
22
22
  });
23
+ /**
24
+ * Base storage key for saved viewports in localStorage.
25
+ */
23
26
  const STORAGE_ID = "deckgl-saved-viewports";
27
+ /**
28
+ * Generates a storage key, optionally namespaced by unique identifier.
29
+ *
30
+ * @param uniqueIdentifier - Optional namespace for multiple map instances
31
+ * @returns Storage key string
32
+ */
24
33
  const getContainerKey = (uniqueIdentifier) => uniqueIdentifier ? `${STORAGE_ID}-${uniqueIdentifier}` : STORAGE_ID;
34
+ /**
35
+ * Retrieves the storage container from localStorage.
36
+ * Returns empty object if parsing fails or key doesn't exist.
37
+ *
38
+ * @param containerKey - The storage key to retrieve
39
+ * @returns Parsed storage container object
40
+ */
25
41
  const getContainer = (containerKey) => {
26
42
  try {
27
43
  return JSON.parse(localStorage.getItem(containerKey) ?? "{}");
@@ -30,12 +46,60 @@ const getContainer = (containerKey) => {
30
46
  return {};
31
47
  }
32
48
  };
49
+ /**
50
+ * Persists a viewport state to localStorage.
51
+ *
52
+ * Saves the viewport under the given ID within a namespaced container.
53
+ * If the container doesn't exist, creates it. If the ID already exists, overwrites it.
54
+ *
55
+ * @param id - Unique identifier for this viewport (typically a key combination ID)
56
+ * @param obj - The MapViewState to persist
57
+ * @param uniqueIdentifier - Optional namespace for multiple map instances
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * import { persist } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';
62
+ *
63
+ * const viewport = {
64
+ * latitude: 38.9072,
65
+ * longitude: -77.0369,
66
+ * zoom: 10,
67
+ * pitch: 0,
68
+ * bearing: 0,
69
+ * };
70
+ *
71
+ * persist('Digit1', viewport);
72
+ * persist('Digit2', viewport, 'main-map');
73
+ * ```
74
+ */
33
75
  const persist = (id, obj, uniqueIdentifier) => {
34
76
  const containerKey = getContainerKey(uniqueIdentifier);
35
77
  const container = getContainer(containerKey);
36
78
  container[id] = obj;
37
79
  localStorage.setItem(containerKey, JSON.stringify(container));
38
80
  };
81
+ /**
82
+ * Retrieves a saved viewport state from localStorage.
83
+ *
84
+ * Returns the viewport associated with the given ID, or undefined if not found.
85
+ * Logs a warning if the viewport doesn't exist.
86
+ *
87
+ * @param id - Unique identifier for the viewport to retrieve
88
+ * @param uniqueIdentifier - Optional namespace for multiple map instances
89
+ * @returns The saved MapViewState or undefined if not found
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * import { retrieve } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';
94
+ *
95
+ * const viewport = retrieve('Digit1');
96
+ * if (viewport) {
97
+ * console.log('Restored viewport:', viewport);
98
+ * }
99
+ *
100
+ * const mainMapViewport = retrieve('Digit1', 'main-map');
101
+ * ```
102
+ */
39
103
  const retrieve = (id, uniqueIdentifier) => {
40
104
  const obj = getContainer(getContainerKey(uniqueIdentifier))[id];
41
105
  if (!obj) logger.warn(`Object with id: ${id} does not exist`);
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","names":[],"sources":["../../../src/deckgl/saved-viewports/storage.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { getLogger } from '@accelint/logger';\nimport type { MapViewState } from '@deck.gl/core';\n\nconst logger = getLogger({\n enabled:\n process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test',\n level: 'warn',\n prefix: '[SavedViewports]',\n pretty: true,\n});\n\nexport const STORAGE_ID = 'deckgl-saved-viewports';\n\nconst getContainerKey = (uniqueIdentifier?: string) =>\n uniqueIdentifier ? `${STORAGE_ID}-${uniqueIdentifier}` : STORAGE_ID;\n\nconst getContainer = (containerKey: string) => {\n try {\n return JSON.parse(localStorage.getItem(containerKey) ?? '{}');\n } catch {\n logger.warn(\n `Failed to parse storage container for key: ${containerKey}, returning empty container.`,\n );\n return {};\n }\n};\n\nexport const persist = (\n id: string,\n obj: MapViewState,\n uniqueIdentifier?: string,\n) => {\n const containerKey = getContainerKey(uniqueIdentifier);\n const container = getContainer(containerKey);\n container[id] = obj;\n localStorage.setItem(containerKey, JSON.stringify(container));\n};\n\nexport const retrieve = (id: string, uniqueIdentifier?: string) => {\n const containerKey = getContainerKey(uniqueIdentifier);\n const container = getContainer(containerKey);\n const obj = container[id];\n if (!obj) {\n logger.warn(`Object with id: ${id} does not exist`);\n }\n return obj;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,SAAS,UAAU;CACvB,SACE,QAAQ,IAAI,aAAa,gBAAgB,QAAQ,IAAI,aAAa;CACpE,OAAO;CACP,QAAQ;CACR,QAAQ;CACT,CAAC;AAEF,MAAa,aAAa;AAE1B,MAAM,mBAAmB,qBACvB,mBAAmB,GAAG,WAAW,GAAG,qBAAqB;AAE3D,MAAM,gBAAgB,iBAAyB;AAC7C,KAAI;AACF,SAAO,KAAK,MAAM,aAAa,QAAQ,aAAa,IAAI,KAAK;SACvD;AACN,SAAO,KACL,8CAA8C,aAAa,8BAC5D;AACD,SAAO,EAAE;;;AAIb,MAAa,WACX,IACA,KACA,qBACG;CACH,MAAM,eAAe,gBAAgB,iBAAiB;CACtD,MAAM,YAAY,aAAa,aAAa;AAC5C,WAAU,MAAM;AAChB,cAAa,QAAQ,cAAc,KAAK,UAAU,UAAU,CAAC;;AAG/D,MAAa,YAAY,IAAY,qBAA8B;CAGjE,MAAM,MADY,aADG,gBAAgB,iBAAiB,CACV,CACtB;AACtB,KAAI,CAAC,IACH,QAAO,KAAK,mBAAmB,GAAG,iBAAiB;AAErD,QAAO"}
1
+ {"version":3,"file":"storage.js","names":[],"sources":["../../../src/deckgl/saved-viewports/storage.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { getLogger } from '@accelint/logger';\nimport type { MapViewState } from '@deck.gl/core';\n\nconst logger = getLogger({\n enabled:\n process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test',\n level: 'warn',\n prefix: '[SavedViewports]',\n pretty: true,\n});\n\n/**\n * Base storage key for saved viewports in localStorage.\n */\nexport const STORAGE_ID = 'deckgl-saved-viewports';\n\n/**\n * Generates a storage key, optionally namespaced by unique identifier.\n *\n * @param uniqueIdentifier - Optional namespace for multiple map instances\n * @returns Storage key string\n */\nconst getContainerKey = (uniqueIdentifier?: string) =>\n uniqueIdentifier ? `${STORAGE_ID}-${uniqueIdentifier}` : STORAGE_ID;\n\n/**\n * Retrieves the storage container from localStorage.\n * Returns empty object if parsing fails or key doesn't exist.\n *\n * @param containerKey - The storage key to retrieve\n * @returns Parsed storage container object\n */\nconst getContainer = (containerKey: string) => {\n try {\n return JSON.parse(localStorage.getItem(containerKey) ?? '{}');\n } catch {\n logger.warn(\n `Failed to parse storage container for key: ${containerKey}, returning empty container.`,\n );\n return {};\n }\n};\n\n/**\n * Persists a viewport state to localStorage.\n *\n * Saves the viewport under the given ID within a namespaced container.\n * If the container doesn't exist, creates it. If the ID already exists, overwrites it.\n *\n * @param id - Unique identifier for this viewport (typically a key combination ID)\n * @param obj - The MapViewState to persist\n * @param uniqueIdentifier - Optional namespace for multiple map instances\n *\n * @example\n * ```typescript\n * import { persist } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';\n *\n * const viewport = {\n * latitude: 38.9072,\n * longitude: -77.0369,\n * zoom: 10,\n * pitch: 0,\n * bearing: 0,\n * };\n *\n * persist('Digit1', viewport);\n * persist('Digit2', viewport, 'main-map');\n * ```\n */\nexport const persist = (\n id: string,\n obj: MapViewState,\n uniqueIdentifier?: string,\n) => {\n const containerKey = getContainerKey(uniqueIdentifier);\n const container = getContainer(containerKey);\n container[id] = obj;\n localStorage.setItem(containerKey, JSON.stringify(container));\n};\n\n/**\n * Retrieves a saved viewport state from localStorage.\n *\n * Returns the viewport associated with the given ID, or undefined if not found.\n * Logs a warning if the viewport doesn't exist.\n *\n * @param id - Unique identifier for the viewport to retrieve\n * @param uniqueIdentifier - Optional namespace for multiple map instances\n * @returns The saved MapViewState or undefined if not found\n *\n * @example\n * ```typescript\n * import { retrieve } from '@accelint/map-toolkit/deckgl/saved-viewports/storage';\n *\n * const viewport = retrieve('Digit1');\n * if (viewport) {\n * console.log('Restored viewport:', viewport);\n * }\n *\n * const mainMapViewport = retrieve('Digit1', 'main-map');\n * ```\n */\nexport const retrieve = (id: string, uniqueIdentifier?: string) => {\n const containerKey = getContainerKey(uniqueIdentifier);\n const container = getContainer(containerKey);\n const obj = container[id];\n if (!obj) {\n logger.warn(`Object with id: ${id} does not exist`);\n }\n return obj;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAeA,MAAM,SAAS,UAAU;CACvB,SACE,QAAQ,IAAI,aAAa,gBAAgB,QAAQ,IAAI,aAAa;CACpE,OAAO;CACP,QAAQ;CACR,QAAQ;CACT,CAAC;;;;AAKF,MAAa,aAAa;;;;;;;AAQ1B,MAAM,mBAAmB,qBACvB,mBAAmB,GAAG,WAAW,GAAG,qBAAqB;;;;;;;;AAS3D,MAAM,gBAAgB,iBAAyB;AAC7C,KAAI;AACF,SAAO,KAAK,MAAM,aAAa,QAAQ,aAAa,IAAI,KAAK;SACvD;AACN,SAAO,KACL,8CAA8C,aAAa,8BAC5D;AACD,SAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8Bb,MAAa,WACX,IACA,KACA,qBACG;CACH,MAAM,eAAe,gBAAgB,iBAAiB;CACtD,MAAM,YAAY,aAAa,aAAa;AAC5C,WAAU,MAAM;AAChB,cAAa,QAAQ,cAAc,KAAK,UAAU,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;AAyB/D,MAAa,YAAY,IAAY,qBAA8B;CAGjE,MAAM,MADY,aADG,gBAAgB,iBAAiB,CACV,CACtB;AACtB,KAAI,CAAC,IACH,QAAO,KAAK,mBAAmB,GAAG,iBAAiB;AAErD,QAAO"}
@@ -17,8 +17,10 @@ import { DEFAULT_COLORS } from "../shared/constants.js";
17
17
 
18
18
  //#region src/deckgl/shapes/display-shape-layer/constants.ts
19
19
  /**
20
- * Map interaction constants
21
- * Values derived from ngc2 for consistency
20
+ * Map interaction constants.
21
+ *
22
+ * Values derived from ngc2 for consistency with existing UI patterns.
23
+ * Controls sizing and interaction feedback for shape rendering.
22
24
  */
23
25
  const MAP_INTERACTION = {
24
26
  LINE_WIDTH_MIN_PIXELS: 1,
@@ -26,15 +28,21 @@ const MAP_INTERACTION = {
26
28
  ICON_HOVER_SIZE_INCREASE: 5
27
29
  };
28
30
  /**
29
- * Selection highlight configuration
31
+ * Selection highlight configuration.
32
+ *
33
+ * Controls the appearance of selected shapes, including highlight color
34
+ * and icon size adjustments for Point shapes.
30
35
  */
31
36
  const SELECTION_HIGHLIGHT = {
32
37
  COLOR: DEFAULT_COLORS.highlight,
33
38
  ICON_SIZE_INCREASE: 8
34
39
  };
35
40
  /**
36
- * Coffin corners configuration for Point selection/hover feedback
37
- * Coffin corners are bracket-like corners that appear around points
41
+ * Coffin corners configuration for Point selection/hover feedback.
42
+ *
43
+ * Coffin corners are bracket-like corners that appear around Point shapes
44
+ * with icons to indicate hover and selection states. They provide visual
45
+ * feedback without obscuring the icon itself.
38
46
  */
39
47
  const COFFIN_CORNERS = {
40
48
  HOVER_ICON: "coffin-corners-hover",
@@ -43,7 +51,11 @@ const COFFIN_CORNERS = {
43
51
  SIZE: 38
44
52
  };
45
53
  /**
46
- * Default props for DisplayShapeLayer
54
+ * Default props for DisplayShapeLayer.
55
+ *
56
+ * Provides sensible defaults for interactive shape display with labels,
57
+ * standard opacity handling, and minimal visual feedback. These can be
58
+ * overridden via layer props.
47
59
  */
48
60
  const DEFAULT_DISPLAY_PROPS = {
49
61
  pickable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":[],"sources":["../../../../src/deckgl/shapes/display-shape-layer/constants.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport { DEFAULT_COLORS } from '../shared/constants';\n\n/**\n * Map interaction constants\n * Values derived from ngc2 for consistency\n */\nexport const MAP_INTERACTION = {\n LINE_WIDTH_MIN_PIXELS: 1, // Minimum line width in pixels\n ICON_SIZE: 38, // Size of shape icons\n ICON_HOVER_SIZE_INCREASE: 5, // Additional pixels added on hover\n} as const;\n\n/**\n * Selection highlight configuration\n */\nexport const SELECTION_HIGHLIGHT = {\n /** Uses DEFAULT_COLORS.highlight from shared constants */\n COLOR: DEFAULT_COLORS.highlight,\n ICON_SIZE_INCREASE: 8, // Additional pixels for highlight icon\n} as const;\n\n/**\n * Coffin corners configuration for Point selection/hover feedback\n * Coffin corners are bracket-like corners that appear around points\n */\nexport const COFFIN_CORNERS = {\n /** Icon name for hover state (white corners with background fill) */\n HOVER_ICON: 'coffin-corners-hover',\n /** Icon name for selected state (blue corners, no fill) */\n SELECTED_ICON: 'coffin-corners-selected',\n /** Icon name for selected+hover state (blue corners with background fill) */\n SELECTED_HOVER_ICON: 'coffin-corners-selected-hover',\n /** Size of the coffin corners icon */\n SIZE: 38,\n} as const;\n\n/**\n * Default props for DisplayShapeLayer\n */\nexport const DEFAULT_DISPLAY_PROPS = {\n pickable: true,\n showLabels: 'always' as const,\n showHighlight: false,\n applyBaseOpacity: true,\n highlightColor: SELECTION_HIGHLIGHT.COLOR,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAoBA,MAAa,kBAAkB;CAC7B,uBAAuB;CACvB,WAAW;CACX,0BAA0B;CAC3B;;;;AAKD,MAAa,sBAAsB;CAEjC,OAAO,eAAe;CACtB,oBAAoB;CACrB;;;;;AAMD,MAAa,iBAAiB;CAE5B,YAAY;CAEZ,eAAe;CAEf,qBAAqB;CAErB,MAAM;CACP;;;;AAKD,MAAa,wBAAwB;CACnC,UAAU;CACV,YAAY;CACZ,eAAe;CACf,kBAAkB;CAClB,gBAAgB,oBAAoB;CACrC"}
1
+ {"version":3,"file":"constants.js","names":[],"sources":["../../../../src/deckgl/shapes/display-shape-layer/constants.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport { DEFAULT_COLORS } from '../shared/constants';\n\n/**\n * Map interaction constants.\n *\n * Values derived from ngc2 for consistency with existing UI patterns.\n * Controls sizing and interaction feedback for shape rendering.\n */\nexport const MAP_INTERACTION = {\n LINE_WIDTH_MIN_PIXELS: 1, // Minimum line width in pixels\n ICON_SIZE: 38, // Size of shape icons\n ICON_HOVER_SIZE_INCREASE: 5, // Additional pixels added on hover\n} as const;\n\n/**\n * Selection highlight configuration.\n *\n * Controls the appearance of selected shapes, including highlight color\n * and icon size adjustments for Point shapes.\n */\nexport const SELECTION_HIGHLIGHT = {\n /** Uses DEFAULT_COLORS.highlight from shared constants */\n COLOR: DEFAULT_COLORS.highlight,\n ICON_SIZE_INCREASE: 8, // Additional pixels for highlight icon\n} as const;\n\n/**\n * Coffin corners configuration for Point selection/hover feedback.\n *\n * Coffin corners are bracket-like corners that appear around Point shapes\n * with icons to indicate hover and selection states. They provide visual\n * feedback without obscuring the icon itself.\n */\nexport const COFFIN_CORNERS = {\n /** Icon name for hover state (white corners with background fill) */\n HOVER_ICON: 'coffin-corners-hover',\n /** Icon name for selected state (blue corners, no fill) */\n SELECTED_ICON: 'coffin-corners-selected',\n /** Icon name for selected+hover state (blue corners with background fill) */\n SELECTED_HOVER_ICON: 'coffin-corners-selected-hover',\n /** Size of the coffin corners icon */\n SIZE: 38,\n} as const;\n\n/**\n * Default props for DisplayShapeLayer.\n *\n * Provides sensible defaults for interactive shape display with labels,\n * standard opacity handling, and minimal visual feedback. These can be\n * overridden via layer props.\n */\nexport const DEFAULT_DISPLAY_PROPS = {\n pickable: true,\n showLabels: 'always' as const,\n showHighlight: false,\n applyBaseOpacity: true,\n highlightColor: SELECTION_HIGHLIGHT.COLOR,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,kBAAkB;CAC7B,uBAAuB;CACvB,WAAW;CACX,0BAA0B;CAC3B;;;;;;;AAQD,MAAa,sBAAsB;CAEjC,OAAO,eAAe;CACtB,oBAAoB;CACrB;;;;;;;;AASD,MAAa,iBAAiB;CAE5B,YAAY;CAEZ,eAAe;CAEf,qBAAqB;CAErB,MAAM;CACP;;;;;;;;AASD,MAAa,wBAAwB;CACnC,UAAU;CACV,YAAY;CACZ,eAAe;CACf,kBAAkB;CAClB,gBAAgB,oBAAoB;CACrC"}
@@ -17,6 +17,13 @@ declare global {
17
17
  namespace React {
18
18
  namespace JSX {
19
19
  interface IntrinsicElements {
20
+ /**
21
+ * A read-only Deck.gl Fiber layer for displaying geographic shapes with interactive features.
22
+ *
23
+ * Supports Point, LineString, Polygon, and Circle geometries with customizable styling,
24
+ * icons, labels, selection, and hover effects. Ideal for rendering shapes from external
25
+ * APIs or displaying geographic data without editing capabilities.
26
+ */
20
27
  displayShapeLayer: DisplayShapeLayerProps;
21
28
  }
22
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fiber.js","names":[],"sources":["../../../../src/deckgl/shapes/display-shape-layer/fiber.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { extend } from '@deckgl-fiber-renderer/dom';\nimport { DisplayShapeLayer } from './index';\nimport type { DisplayShapeLayerProps } from './types';\n\nextend({ DisplayShapeLayer });\n\ndeclare global {\n namespace React {\n // biome-ignore lint/style/useNamingConvention: Built-in React namespace.\n namespace JSX {\n interface IntrinsicElements {\n displayShapeLayer: DisplayShapeLayerProps;\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,OAAO,EAAE,mBAAmB,CAAC"}
1
+ {"version":3,"file":"fiber.js","names":[],"sources":["../../../../src/deckgl/shapes/display-shape-layer/fiber.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport { extend } from '@deckgl-fiber-renderer/dom';\nimport { DisplayShapeLayer } from './index';\nimport type { DisplayShapeLayerProps } from './types';\n\nextend({ DisplayShapeLayer });\n\ndeclare global {\n namespace React {\n // biome-ignore lint/style/useNamingConvention: Built-in React namespace.\n namespace JSX {\n interface IntrinsicElements {\n /**\n * A read-only Deck.gl Fiber layer for displaying geographic shapes with interactive features.\n *\n * Supports Point, LineString, Polygon, and Circle geometries with customizable styling,\n * icons, labels, selection, and hover effects. Ideal for rendering shapes from external\n * APIs or displaying geographic data without editing capabilities.\n */\n displayShapeLayer: DisplayShapeLayerProps;\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,OAAO,EAAE,mBAAmB,CAAC"}
@@ -18,15 +18,53 @@ import { getLineWidth, normalizeColor } from "../../shared/utils/style-utils.js"
18
18
 
19
19
  //#region src/deckgl/shapes/display-shape-layer/utils/display-style.ts
20
20
  /**
21
- * Get hover-enhanced border/outline width
21
+ * Get hover-enhanced border/outline width.
22
+ *
23
+ * Calculates the line width for a feature, increasing it when hovered to provide
24
+ * visual feedback. The hover effect adds a fixed pixel increase to the base width.
25
+ *
26
+ * @param feature - The styled feature to calculate width for
27
+ * @param isHovered - Whether the feature is currently being hovered
28
+ * @returns The calculated line width in pixels
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * import { getHoverLineWidth } from '@accelint/map-toolkit/deckgl/shapes/display-shape-layer/utils/display-style';
33
+ * import type { StyledFeature } from '@accelint/map-toolkit/deckgl/shapes/shared/types';
34
+ *
35
+ * const feature: StyledFeature = {
36
+ * properties: { styleProperties: { lineWidth: 2 } }
37
+ * };
38
+ *
39
+ * const width = getHoverLineWidth(feature, true);
40
+ * // Returns: 2 + HOVER_WIDTH_INCREASE (typically 4 pixels total)
41
+ * ```
22
42
  */
23
43
  function getHoverLineWidth(feature, isHovered) {
24
44
  const baseWidth = getLineWidth(feature);
25
45
  return isHovered ? baseWidth + HOVER_WIDTH_INCREASE : baseWidth;
26
46
  }
27
47
  /**
28
- * Get selection highlight color
29
- * Returns the default highlight color or allows custom opacity override
48
+ * Get selection highlight color.
49
+ *
50
+ * Returns the default highlight color with optional custom opacity override.
51
+ * The highlight color is used to indicate selected features on the map.
52
+ *
53
+ * @param opacity - Optional opacity value (0-1 range), overrides default opacity
54
+ * @returns RGBA color array [red, green, blue, alpha] with values 0-255
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * import { getHighlightColor } from '@accelint/map-toolkit/deckgl/shapes/display-shape-layer/utils/display-style';
59
+ *
60
+ * // Use default highlight color with default opacity
61
+ * const defaultColor = getHighlightColor();
62
+ * // Returns: [r, g, b, a] from DEFAULT_COLORS.highlight
63
+ *
64
+ * // Use custom opacity (50% transparent)
65
+ * const semiTransparent = getHighlightColor(0.5);
66
+ * // Returns: [r, g, b, 127]
67
+ * ```
30
68
  */
31
69
  function getHighlightColor(opacity) {
32
70
  const rgba = normalizeColor(DEFAULT_COLORS.highlight);
@@ -39,7 +77,26 @@ function getHighlightColor(opacity) {
39
77
  return rgba;
40
78
  }
41
79
  /**
42
- * Get highlight border/outline width (base width + increase)
80
+ * Get highlight border/outline width.
81
+ *
82
+ * Calculates the line width for a selected/highlighted feature by adding a fixed
83
+ * pixel increase to the base width. This makes selected features more prominent.
84
+ *
85
+ * @param feature - The styled feature to calculate width for
86
+ * @returns The calculated line width in pixels (base width + HIGHLIGHT_WIDTH_INCREASE)
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * import { getHighlightLineWidth } from '@accelint/map-toolkit/deckgl/shapes/display-shape-layer/utils/display-style';
91
+ * import type { StyledFeature } from '@accelint/map-toolkit/deckgl/shapes/shared/types';
92
+ *
93
+ * const feature: StyledFeature = {
94
+ * properties: { styleProperties: { lineWidth: 2 } }
95
+ * };
96
+ *
97
+ * const width = getHighlightLineWidth(feature);
98
+ * // Returns: 2 + HIGHLIGHT_WIDTH_INCREASE (typically 5 pixels total)
99
+ * ```
43
100
  */
44
101
  function getHighlightLineWidth(feature) {
45
102
  return getLineWidth(feature) + HIGHLIGHT_WIDTH_INCREASE;
@@ -1 +1 @@
1
- {"version":3,"file":"display-style.js","names":[],"sources":["../../../../../src/deckgl/shapes/display-shape-layer/utils/display-style.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport {\n DEFAULT_COLORS,\n HIGHLIGHT_WIDTH_INCREASE,\n HOVER_WIDTH_INCREASE,\n} from '../../shared/constants';\nimport { getLineWidth, normalizeColor } from '../../shared/utils/style-utils';\nimport type { StyledFeature } from '../../shared/types';\n\n/**\n * Get hover-enhanced border/outline width\n */\nexport function getHoverLineWidth(\n feature: StyledFeature,\n isHovered: boolean,\n): number {\n const baseWidth = getLineWidth(feature);\n return isHovered ? baseWidth + HOVER_WIDTH_INCREASE : baseWidth;\n}\n\n/**\n * Get selection highlight color\n * Returns the default highlight color or allows custom opacity override\n */\nexport function getHighlightColor(\n opacity?: number,\n): [number, number, number, number] {\n const rgba = normalizeColor(DEFAULT_COLORS.highlight);\n\n if (opacity !== undefined) {\n return [rgba[0], rgba[1], rgba[2], Math.round(opacity * 255)];\n }\n\n return rgba;\n}\n\n/**\n * Get highlight border/outline width (base width + increase)\n */\nexport function getHighlightLineWidth(feature: StyledFeature): number {\n const baseWidth = getLineWidth(feature);\n return baseWidth + HIGHLIGHT_WIDTH_INCREASE;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,kBACd,SACA,WACQ;CACR,MAAM,YAAY,aAAa,QAAQ;AACvC,QAAO,YAAY,YAAY,uBAAuB;;;;;;AAOxD,SAAgB,kBACd,SACkC;CAClC,MAAM,OAAO,eAAe,eAAe,UAAU;AAErD,KAAI,YAAY,OACd,QAAO;EAAC,KAAK;EAAI,KAAK;EAAI,KAAK;EAAI,KAAK,MAAM,UAAU,IAAI;EAAC;AAG/D,QAAO;;;;;AAMT,SAAgB,sBAAsB,SAAgC;AAEpE,QADkB,aAAa,QAAQ,GACpB"}
1
+ {"version":3,"file":"display-style.js","names":[],"sources":["../../../../../src/deckgl/shapes/display-shape-layer/utils/display-style.ts"],"sourcesContent":["/*\n * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport {\n DEFAULT_COLORS,\n HIGHLIGHT_WIDTH_INCREASE,\n HOVER_WIDTH_INCREASE,\n} from '../../shared/constants';\nimport { getLineWidth, normalizeColor } from '../../shared/utils/style-utils';\nimport type { StyledFeature } from '../../shared/types';\n\n/**\n * Get hover-enhanced border/outline width.\n *\n * Calculates the line width for a feature, increasing it when hovered to provide\n * visual feedback. The hover effect adds a fixed pixel increase to the base width.\n *\n * @param feature - The styled feature to calculate width for\n * @param isHovered - Whether the feature is currently being hovered\n * @returns The calculated line width in pixels\n *\n * @example\n * ```typescript\n * import { getHoverLineWidth } from '@accelint/map-toolkit/deckgl/shapes/display-shape-layer/utils/display-style';\n * import type { StyledFeature } from '@accelint/map-toolkit/deckgl/shapes/shared/types';\n *\n * const feature: StyledFeature = {\n * properties: { styleProperties: { lineWidth: 2 } }\n * };\n *\n * const width = getHoverLineWidth(feature, true);\n * // Returns: 2 + HOVER_WIDTH_INCREASE (typically 4 pixels total)\n * ```\n */\nexport function getHoverLineWidth(\n feature: StyledFeature,\n isHovered: boolean,\n): number {\n const baseWidth = getLineWidth(feature);\n return isHovered ? baseWidth + HOVER_WIDTH_INCREASE : baseWidth;\n}\n\n/**\n * Get selection highlight color.\n *\n * Returns the default highlight color with optional custom opacity override.\n * The highlight color is used to indicate selected features on the map.\n *\n * @param opacity - Optional opacity value (0-1 range), overrides default opacity\n * @returns RGBA color array [red, green, blue, alpha] with values 0-255\n *\n * @example\n * ```typescript\n * import { getHighlightColor } from '@accelint/map-toolkit/deckgl/shapes/display-shape-layer/utils/display-style';\n *\n * // Use default highlight color with default opacity\n * const defaultColor = getHighlightColor();\n * // Returns: [r, g, b, a] from DEFAULT_COLORS.highlight\n *\n * // Use custom opacity (50% transparent)\n * const semiTransparent = getHighlightColor(0.5);\n * // Returns: [r, g, b, 127]\n * ```\n */\nexport function getHighlightColor(\n opacity?: number,\n): [number, number, number, number] {\n const rgba = normalizeColor(DEFAULT_COLORS.highlight);\n\n if (opacity !== undefined) {\n return [rgba[0], rgba[1], rgba[2], Math.round(opacity * 255)];\n }\n\n return rgba;\n}\n\n/**\n * Get highlight border/outline width.\n *\n * Calculates the line width for a selected/highlighted feature by adding a fixed\n * pixel increase to the base width. This makes selected features more prominent.\n *\n * @param feature - The styled feature to calculate width for\n * @returns The calculated line width in pixels (base width + HIGHLIGHT_WIDTH_INCREASE)\n *\n * @example\n * ```typescript\n * import { getHighlightLineWidth } from '@accelint/map-toolkit/deckgl/shapes/display-shape-layer/utils/display-style';\n * import type { StyledFeature } from '@accelint/map-toolkit/deckgl/shapes/shared/types';\n *\n * const feature: StyledFeature = {\n * properties: { styleProperties: { lineWidth: 2 } }\n * };\n *\n * const width = getHighlightLineWidth(feature);\n * // Returns: 2 + HIGHLIGHT_WIDTH_INCREASE (typically 5 pixels total)\n * ```\n */\nexport function getHighlightLineWidth(feature: StyledFeature): number {\n const baseWidth = getLineWidth(feature);\n return baseWidth + HIGHLIGHT_WIDTH_INCREASE;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,kBACd,SACA,WACQ;CACR,MAAM,YAAY,aAAa,QAAQ;AACvC,QAAO,YAAY,YAAY,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;AAyBxD,SAAgB,kBACd,SACkC;CAClC,MAAM,OAAO,eAAe,eAAe,UAAU;AAErD,KAAI,YAAY,OACd,QAAO;EAAC,KAAK;EAAI,KAAK;EAAI,KAAK;EAAI,KAAK,MAAM,UAAU,IAAI;EAAC;AAG/D,QAAO;;;;;;;;;;;;;;;;;;;;;;;;AAyBT,SAAgB,sBAAsB,SAAgC;AAEpE,QADkB,aAAa,QAAQ,GACpB"}
@@ -14,7 +14,10 @@ import "../../shared/types.js";
14
14
 
15
15
  //#region src/deckgl/shapes/display-shape-layer/utils/labels.d.ts
16
16
  /**
17
- * Label positioning information including coordinates and screen-space offsets
17
+ * Label positioning information including coordinates and screen-space offsets.
18
+ *
19
+ * Defines where a label should be positioned on the map, combining geographic coordinates
20
+ * with text alignment and pixel-level offsets for precise placement.
18
21
  */
19
22
  interface LabelPosition2d {
20
23
  /** Geographic coordinates [longitude, latitude] */
@@ -27,19 +30,30 @@ interface LabelPosition2d {
27
30
  pixelOffset: [number, number];
28
31
  }
29
32
  /**
30
- * Vertical label position relative to anchor point
33
+ * Vertical label position relative to anchor point.
34
+ *
35
+ * Controls how the label aligns vertically with its anchor coordinate:
36
+ * - `'top'`: Label text appears below the anchor point
37
+ * - `'middle'`: Label text is vertically centered on the anchor point
38
+ * - `'bottom'`: Label text appears above the anchor point
31
39
  */
32
40
  type LabelVerticalPosition = 'top' | 'middle' | 'bottom';
33
41
  /**
34
- * Horizontal label position relative to anchor point
42
+ * Horizontal label position relative to anchor point.
43
+ *
44
+ * Controls how the label aligns horizontally with its anchor coordinate:
45
+ * - `'left'`: Label text appears to the right of the anchor point
46
+ * - `'center'`: Label text is horizontally centered on the anchor point
47
+ * - `'right'`: Label text appears to the left of the anchor point
35
48
  */
36
49
  type LabelHorizontalPosition = 'left' | 'center' | 'right';
37
50
  /**
38
- * Cardinal direction anchor for positioning labels on geometry edges
39
- * Uses edge positions relative to the geometry's bounding box
40
- * Works for LineString, Polygon, and Circle geometries
41
- * - 'center': centroid/midpoint of the geometry
42
- * - 'top'/'right'/'bottom'/'left': edge positions
51
+ * Cardinal direction anchor for positioning labels on geometry edges.
52
+ *
53
+ * Uses edge positions relative to the geometry's bounding box.
54
+ * Works for LineString, Polygon, and Circle geometries:
55
+ * - `'center'`: centroid/midpoint of the geometry
56
+ * - `'top'`/`'right'`/`'bottom'`/`'left'`: edge positions based on bounding box
43
57
  */
44
58
  type CardinalLabelCoordinateAnchor = 'center' | 'top' | 'right' | 'bottom' | 'left';
45
59
  /**