@accelint/map-toolkit 1.5.0 → 3.0.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 (224) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +8 -1
  3. package/catalog-info.yaml +9 -6
  4. package/dist/camera/events.js +1 -1
  5. package/dist/camera/index.d.ts +1 -1
  6. package/dist/camera/index.js +1 -1
  7. package/dist/camera/store.d.ts +1 -1
  8. package/dist/camera/store.js +3 -5
  9. package/dist/camera/store.js.map +1 -1
  10. package/dist/camera/types.d.ts +1 -1
  11. package/dist/camera/types.js +1 -1
  12. package/dist/cursor-coordinates/constants.js +1 -1
  13. package/dist/cursor-coordinates/index.d.ts +1 -1
  14. package/dist/cursor-coordinates/index.js +1 -1
  15. package/dist/cursor-coordinates/store.d.ts +1 -1
  16. package/dist/cursor-coordinates/store.js +1 -1
  17. package/dist/cursor-coordinates/types.d.ts +1 -1
  18. package/dist/cursor-coordinates/types.js +1 -1
  19. package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +1 -1
  20. package/dist/cursor-coordinates/use-cursor-coordinates.js +4 -9
  21. package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
  22. package/dist/deckgl/base-map/constants.js +1 -1
  23. package/dist/deckgl/base-map/controls.d.ts +1 -1
  24. package/dist/deckgl/base-map/controls.js +1 -1
  25. package/dist/deckgl/base-map/events.js +1 -1
  26. package/dist/deckgl/base-map/index.d.ts +3 -3
  27. package/dist/deckgl/base-map/index.js +1 -1
  28. package/dist/deckgl/base-map/provider.d.ts +1 -1
  29. package/dist/deckgl/base-map/provider.js +1 -1
  30. package/dist/deckgl/base-map/types.d.ts +1 -1
  31. package/dist/deckgl/base-map/types.js +1 -1
  32. package/dist/deckgl/extensions/coffin-corner/coffin-corner-extension.d.ts +144 -0
  33. package/dist/deckgl/extensions/coffin-corner/coffin-corner-extension.js +535 -0
  34. package/dist/deckgl/extensions/coffin-corner/coffin-corner-extension.js.map +1 -0
  35. package/dist/deckgl/extensions/coffin-corner/index.d.ts +17 -0
  36. package/dist/deckgl/extensions/coffin-corner/index.js +19 -0
  37. package/dist/deckgl/extensions/coffin-corner/store.d.ts +96 -0
  38. package/dist/deckgl/extensions/coffin-corner/store.js +173 -0
  39. package/dist/deckgl/extensions/coffin-corner/store.js.map +1 -0
  40. package/dist/deckgl/extensions/coffin-corner/types.d.ts +76 -0
  41. package/dist/deckgl/extensions/coffin-corner/types.js +27 -0
  42. package/dist/deckgl/extensions/coffin-corner/types.js.map +1 -0
  43. package/dist/deckgl/extensions/coffin-corner/use-coffin-corner.d.ts +81 -0
  44. package/dist/deckgl/extensions/coffin-corner/use-coffin-corner.js +75 -0
  45. package/dist/deckgl/extensions/coffin-corner/use-coffin-corner.js.map +1 -0
  46. package/dist/deckgl/extensions/index.d.ts +15 -0
  47. package/dist/deckgl/extensions/index.js +16 -0
  48. package/dist/deckgl/index.d.ts +9 -4
  49. package/dist/deckgl/index.js +6 -2
  50. package/dist/deckgl/saved-viewports/index.d.ts +1 -1
  51. package/dist/deckgl/saved-viewports/index.js +1 -1
  52. package/dist/deckgl/saved-viewports/storage.d.ts +1 -1
  53. package/dist/deckgl/saved-viewports/storage.js +5 -10
  54. package/dist/deckgl/saved-viewports/storage.js.map +1 -1
  55. package/dist/deckgl/shapes/display-shape-layer/constants.js +70 -26
  56. package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
  57. package/dist/deckgl/shapes/display-shape-layer/fiber.d.ts +1 -1
  58. package/dist/deckgl/shapes/display-shape-layer/fiber.js +1 -1
  59. package/dist/deckgl/shapes/display-shape-layer/index.d.ts +93 -38
  60. package/dist/deckgl/shapes/display-shape-layer/index.js +433 -187
  61. package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -1
  62. package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js +1 -1
  63. package/dist/deckgl/shapes/display-shape-layer/store.js +1 -1
  64. package/dist/deckgl/shapes/display-shape-layer/types.d.ts +116 -19
  65. package/dist/deckgl/shapes/display-shape-layer/types.js +1 -1
  66. package/dist/deckgl/shapes/display-shape-layer/use-select-shape.d.ts +1 -1
  67. package/dist/deckgl/shapes/display-shape-layer/use-select-shape.js +1 -1
  68. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +66 -36
  69. package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -1
  70. package/dist/deckgl/shapes/display-shape-layer/utils/elevation.js +407 -0
  71. package/dist/deckgl/shapes/display-shape-layer/utils/elevation.js.map +1 -0
  72. package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js +106 -0
  73. package/dist/deckgl/shapes/display-shape-layer/utils/icon-config.js.map +1 -0
  74. package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +1 -1
  75. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +28 -39
  76. package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -1
  77. package/dist/deckgl/shapes/display-shape-layer/utils/radius-label.js +53 -0
  78. package/dist/deckgl/shapes/display-shape-layer/utils/radius-label.js.map +1 -0
  79. package/dist/deckgl/shapes/draw-shape-layer/constants.js +1 -1
  80. package/dist/deckgl/shapes/draw-shape-layer/events.d.ts +1 -1
  81. package/dist/deckgl/shapes/draw-shape-layer/events.js +1 -1
  82. package/dist/deckgl/shapes/draw-shape-layer/fiber.js +1 -1
  83. package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +8 -4
  84. package/dist/deckgl/shapes/draw-shape-layer/index.js +11 -17
  85. package/dist/deckgl/shapes/draw-shape-layer/index.js.map +1 -1
  86. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +6 -5
  87. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -1
  88. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +4 -3
  89. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js.map +1 -1
  90. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +6 -20
  91. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -1
  92. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +6 -33
  93. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -1
  94. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +16 -12
  95. package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -1
  96. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js +2 -32
  97. package/dist/deckgl/shapes/draw-shape-layer/modes/index.js.map +1 -1
  98. package/dist/deckgl/shapes/draw-shape-layer/store.js +1 -1
  99. package/dist/deckgl/shapes/draw-shape-layer/types.d.ts +3 -3
  100. package/dist/deckgl/shapes/draw-shape-layer/types.js +1 -1
  101. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.d.ts +1 -1
  102. package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js +1 -1
  103. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js +3 -8
  104. package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js.map +1 -1
  105. package/dist/deckgl/shapes/edit-shape-layer/constants.js +17 -2
  106. package/dist/deckgl/shapes/edit-shape-layer/constants.js.map +1 -1
  107. package/dist/deckgl/shapes/edit-shape-layer/events.d.ts +1 -1
  108. package/dist/deckgl/shapes/edit-shape-layer/events.js +1 -1
  109. package/dist/deckgl/shapes/edit-shape-layer/fiber.d.ts +1 -1
  110. package/dist/deckgl/shapes/edit-shape-layer/fiber.js +1 -1
  111. package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +12 -6
  112. package/dist/deckgl/shapes/edit-shape-layer/index.js +72 -27
  113. package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -1
  114. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js +4 -1
  115. package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js.map +1 -1
  116. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +4 -3
  117. package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -1
  118. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +5 -3
  119. package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -1
  120. package/dist/deckgl/shapes/edit-shape-layer/modes/index.js +1 -1
  121. package/dist/deckgl/shapes/edit-shape-layer/modes/point-translate-mode.js +1 -1
  122. package/dist/deckgl/shapes/edit-shape-layer/modes/point-translate-mode.js.map +1 -1
  123. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js +1 -1
  124. package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js.map +1 -1
  125. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js +1 -1
  126. package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js.map +1 -1
  127. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js +1 -1
  128. package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js.map +1 -1
  129. package/dist/deckgl/shapes/edit-shape-layer/store.js +83 -14
  130. package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -1
  131. package/dist/deckgl/shapes/edit-shape-layer/types.d.ts +18 -4
  132. package/dist/deckgl/shapes/edit-shape-layer/types.js +1 -1
  133. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts +2 -2
  134. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js +8 -4
  135. package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js.map +1 -1
  136. package/dist/deckgl/shapes/index.d.ts +5 -4
  137. package/dist/deckgl/shapes/index.js +3 -2
  138. package/dist/deckgl/shapes/shared/constants.d.ts +4 -3
  139. package/dist/deckgl/shapes/shared/constants.js +51 -11
  140. package/dist/deckgl/shapes/shared/constants.js.map +1 -1
  141. package/dist/deckgl/shapes/shared/events.d.ts +5 -1
  142. package/dist/deckgl/shapes/shared/events.js +1 -1
  143. package/dist/deckgl/shapes/shared/events.js.map +1 -1
  144. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js +19 -16
  145. package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js.map +1 -1
  146. package/dist/deckgl/shapes/shared/types.d.ts +182 -54
  147. package/dist/deckgl/shapes/shared/types.js +155 -2
  148. package/dist/deckgl/shapes/shared/types.js.map +1 -1
  149. package/dist/deckgl/shapes/shared/utils/duplicate-shape.d.ts +56 -0
  150. package/dist/deckgl/shapes/shared/utils/duplicate-shape.js +131 -0
  151. package/dist/deckgl/shapes/shared/utils/duplicate-shape.js.map +1 -0
  152. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js +29 -24
  153. package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -1
  154. package/dist/deckgl/shapes/shared/utils/layer-config.js +15 -9
  155. package/dist/deckgl/shapes/shared/utils/layer-config.js.map +1 -1
  156. package/dist/deckgl/shapes/shared/utils/mode-utils.js +50 -20
  157. package/dist/deckgl/shapes/shared/utils/mode-utils.js.map +1 -1
  158. package/dist/deckgl/shapes/shared/utils/pick-filtering.js +22 -15
  159. package/dist/deckgl/shapes/shared/utils/pick-filtering.js.map +1 -1
  160. package/dist/deckgl/shapes/shared/utils/style-utils.d.ts +38 -14
  161. package/dist/deckgl/shapes/shared/utils/style-utils.js +43 -32
  162. package/dist/deckgl/shapes/shared/utils/style-utils.js.map +1 -1
  163. package/dist/deckgl/symbol-layer/fiber.d.ts +4 -2
  164. package/dist/deckgl/symbol-layer/fiber.js +1 -1
  165. package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
  166. package/dist/deckgl/symbol-layer/index.d.ts +1 -1
  167. package/dist/deckgl/symbol-layer/index.js +1 -1
  168. package/dist/deckgl/text-layer/character-sets.js +1 -1
  169. package/dist/deckgl/text-layer/default-settings.d.ts +1 -1
  170. package/dist/deckgl/text-layer/default-settings.js +1 -1
  171. package/dist/deckgl/text-layer/fiber.d.ts +1 -1
  172. package/dist/deckgl/text-layer/fiber.js +1 -1
  173. package/dist/deckgl/text-layer/index.d.ts +1 -1
  174. package/dist/deckgl/text-layer/index.js +1 -1
  175. package/dist/deckgl/text-settings.d.ts +3 -3
  176. package/dist/deckgl/text-settings.js +1 -1
  177. package/dist/map-cursor/events.js +1 -1
  178. package/dist/map-cursor/index.d.ts +1 -1
  179. package/dist/map-cursor/index.js +1 -1
  180. package/dist/map-cursor/store.d.ts +1 -1
  181. package/dist/map-cursor/store.js +1 -1
  182. package/dist/map-cursor/types.d.ts +1 -1
  183. package/dist/map-cursor/types.js +1 -1
  184. package/dist/map-cursor/use-map-cursor.d.ts +1 -1
  185. package/dist/map-cursor/use-map-cursor.js +1 -1
  186. package/dist/map-mode/events.js +1 -1
  187. package/dist/map-mode/index.d.ts +1 -1
  188. package/dist/map-mode/index.js +1 -1
  189. package/dist/map-mode/store.d.ts +1 -1
  190. package/dist/map-mode/store.js +3 -8
  191. package/dist/map-mode/store.js.map +1 -1
  192. package/dist/map-mode/types.d.ts +1 -1
  193. package/dist/map-mode/types.js +1 -1
  194. package/dist/map-mode/use-map-mode.d.ts +1 -1
  195. package/dist/map-mode/use-map-mode.js +1 -1
  196. package/dist/maplibre/hooks/use-maplibre.d.ts +1 -1
  197. package/dist/maplibre/hooks/use-maplibre.js +1 -1
  198. package/dist/maplibre/index.d.ts +1 -1
  199. package/dist/maplibre/index.js +1 -1
  200. package/dist/shared/cleanup.d.ts +1 -1
  201. package/dist/shared/cleanup.js +1 -1
  202. package/dist/shared/constants.js +1 -1
  203. package/dist/shared/create-map-store.d.ts +1 -1
  204. package/dist/shared/create-map-store.js +1 -1
  205. package/dist/shared/logger.js +31 -0
  206. package/dist/shared/logger.js.map +1 -0
  207. package/dist/shared/units.d.ts +15 -56
  208. package/dist/shared/units.js +2 -53
  209. package/dist/shared/units.js.map +1 -1
  210. package/dist/viewport/index.d.ts +3 -4
  211. package/dist/viewport/index.js +2 -3
  212. package/dist/viewport/store.d.ts +1 -1
  213. package/dist/viewport/store.js +1 -1
  214. package/dist/viewport/types.d.ts +9 -5
  215. package/dist/viewport/types.js +1 -1
  216. package/dist/viewport/utils.d.ts +4 -4
  217. package/dist/viewport/utils.js +17 -9
  218. package/dist/viewport/utils.js.map +1 -1
  219. package/dist/viewport/viewport-size.d.ts +7 -6
  220. package/dist/viewport/viewport-size.js +3 -3
  221. package/dist/viewport/viewport-size.js.map +1 -1
  222. package/package.json +29 -20
  223. package/dist/hotkey-manager/dist/react/use-hotkey.js +0 -39
  224. package/dist/hotkey-manager/dist/react/use-hotkey.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","names":["DEFAULT_EDITING_STATE: EditingState"],"sources":["../../../../src/deckgl/shapes/edit-shape-layer/store.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\n/**\n * Edit Shape Store\n *\n * Manages editing state for shape modification.\n *\n * @example\n * ```typescript\n * import { editStore } from '@accelint/map-toolkit/deckgl/shapes';\n *\n * function EditControls({ mapId }) {\n * const { state, edit, save, cancel } = editStore.use(mapId);\n *\n * return (\n * <div>\n * <p>Editing: {state.editingShape?.name ?? 'none'}</p>\n * <button onClick={save}>Save</button>\n * <button onClick={cancel}>Cancel</button>\n * </div>\n * );\n * }\n * ```\n */\n\nimport { Broadcast } from '@accelint/bus';\nimport { getLogger } from '@accelint/logger';\nimport { createMapStore } from '@/shared/create-map-store';\nimport { MapEvents } from '../../base-map/events';\nimport {\n isCircleShape,\n isEllipseShape,\n isPointShape,\n isRectangleShape,\n} from '../shared/types';\nimport {\n releaseModeAndCursor,\n requestCursorChange,\n requestModeChange,\n} from '../shared/utils/mode-utils';\nimport {\n EDIT_CURSOR_MAP,\n EDIT_SHAPE_LAYER_ID,\n EDIT_SHAPE_MODE,\n} from './constants';\nimport { EditShapeEvents } from './events';\nimport type { UniqueId } from '@accelint/core';\nimport type { Feature } from 'geojson';\nimport type { MapEventType } from '../../base-map/types';\nimport type { Shape } from '../shared/types';\nimport type {\n EditShapeEvent,\n ShapeEditCanceledEvent,\n ShapeEditingEvent,\n ShapeUpdatedEvent,\n} from './events';\nimport type {\n EditFunction,\n EditingState,\n EditMode,\n EditShapeOptions,\n} from './types';\n\nconst logger = getLogger({\n enabled:\n process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test',\n level: 'warn',\n prefix: '[EditShapeLayer]',\n pretty: true,\n});\n\n/**\n * Typed event bus instances\n */\nconst editShapeBus = Broadcast.getInstance<EditShapeEvent>();\nconst mapEventBus = Broadcast.getInstance<MapEventType>();\n\n/**\n * Default editing state\n */\nconst DEFAULT_EDITING_STATE: EditingState = {\n editingShape: null,\n editMode: 'view',\n featureBeingEdited: null,\n};\n\n/**\n * Actions for edit shape store\n */\ntype EditShapeActions = {\n /** Start editing a shape */\n edit: EditFunction;\n /** Save the current edits */\n save: () => void;\n /** Cancel editing */\n cancel: () => void;\n};\n\n/**\n * Determine the appropriate edit mode for a shape type\n *\n * @param shape - The shape to determine the edit mode for\n * @returns The edit mode to use for this shape type\n */\nfunction getEditModeForShape(shape: Shape): EditMode {\n if (isPointShape(shape)) {\n return 'point-translate';\n }\n if (isCircleShape(shape)) {\n return 'circle-transform';\n }\n if (isEllipseShape(shape) || isRectangleShape(shape)) {\n return 'bounding-transform';\n }\n return 'vertex-transform';\n}\n\n/**\n * Start editing a shape\n */\nfunction startEditing(\n mapId: UniqueId,\n state: EditingState,\n shape: Shape,\n options: EditShapeOptions | undefined,\n notify: () => void,\n setState: (updates: Partial<EditingState>) => void,\n): void {\n // Prevent editing locked shapes\n if (shape.locked) {\n logger.warn(`Cannot edit locked shape: \"${shape.name}\"`);\n return;\n }\n\n // Already editing - cancel first\n if (state.editingShape) {\n cancelEditingInternal(mapId, state, notify, setState);\n }\n\n // Determine edit mode (can be overridden via options)\n const editMode = options?.mode ?? getEditModeForShape(shape);\n\n // Update state with new object reference\n setState({\n editingShape: shape,\n editMode,\n featureBeingEdited: shape.feature,\n });\n\n // Request map mode and cursor\n requestModeChange(mapId, EDIT_SHAPE_MODE, EDIT_SHAPE_LAYER_ID);\n const cursor = EDIT_CURSOR_MAP[editMode];\n requestCursorChange(mapId, cursor, EDIT_SHAPE_LAYER_ID);\n\n // Disable map panning during editing\n mapEventBus.emit(MapEvents.disablePan, { id: mapId });\n\n // Emit editing started event\n editShapeBus.emit(EditShapeEvents.editing, {\n shape,\n mapId,\n } as unknown as ShapeEditingEvent['payload']);\n\n notify();\n}\n\n/**\n * Save editing and create updated shape\n */\nfunction saveEditingInternal(\n mapId: UniqueId,\n state: EditingState,\n notify: () => void,\n setState: (updates: Partial<EditingState>) => void,\n): Shape | null {\n if (!(state.editingShape && state.featureBeingEdited)) {\n return null;\n }\n\n const originalShape = state.editingShape;\n const updatedFeature = state.featureBeingEdited;\n\n // Create updated shape with new geometry\n const updatedShape = {\n ...originalShape,\n feature: {\n ...updatedFeature,\n properties: {\n ...originalShape.feature.properties,\n ...updatedFeature.properties,\n },\n },\n lastUpdated: Date.now(),\n } as Shape;\n\n // Reset state\n setState({\n editingShape: null,\n editMode: 'view',\n featureBeingEdited: null,\n });\n\n // Return to default mode and cursor\n releaseModeAndCursor(mapId, EDIT_SHAPE_LAYER_ID);\n\n // Re-enable map panning\n mapEventBus.emit(MapEvents.enablePan, { id: mapId });\n\n // Emit shape updated event\n editShapeBus.emit(EditShapeEvents.updated, {\n shape: updatedShape,\n mapId,\n } as unknown as ShapeUpdatedEvent['payload']);\n\n notify();\n\n return updatedShape;\n}\n\n/**\n * Cancel the current editing operation\n */\nfunction cancelEditingInternal(\n mapId: UniqueId,\n state: EditingState,\n notify: () => void,\n setState: (updates: Partial<EditingState>) => void,\n): void {\n if (!state.editingShape) {\n return; // Nothing to cancel\n }\n\n const originalShape = state.editingShape;\n\n // Reset state\n setState({\n editingShape: null,\n editMode: 'view',\n featureBeingEdited: null,\n });\n\n // Return to default mode and cursor\n releaseModeAndCursor(mapId, EDIT_SHAPE_LAYER_ID);\n\n // Re-enable map panning\n mapEventBus.emit(MapEvents.enablePan, { id: mapId });\n\n // Emit canceled event\n editShapeBus.emit(EditShapeEvents.canceled, {\n shape: originalShape,\n mapId,\n } as unknown as ShapeEditCanceledEvent['payload']);\n\n notify();\n}\n\n/**\n * Edit shape store\n */\nexport const editStore = createMapStore<EditingState, EditShapeActions>({\n defaultState: { ...DEFAULT_EDITING_STATE },\n\n actions: (mapId, { get, set, notify }) => ({\n edit: (shape: Shape, options?: EditShapeOptions) => {\n startEditing(mapId, get(), shape, options, notify, set);\n },\n\n save: () => {\n saveEditingInternal(mapId, get(), notify, set);\n },\n\n cancel: () => {\n cancelEditingInternal(mapId, get(), notify, set);\n },\n }),\n\n // Note: EditShapeLayer is \"neutral\" regarding mode change authorization.\n // It doesn't auto-cancel or reject mode changes - those decisions are\n // left to UI components that can prompt the user.\n\n onCleanup: (mapId, state) => {\n // Cancel any active editing before cleanup\n if (state.editingShape) {\n // Return to default mode and cursor\n releaseModeAndCursor(mapId, EDIT_SHAPE_LAYER_ID);\n\n // Re-enable map panning\n mapEventBus.emit(MapEvents.enablePan, { id: mapId });\n\n // Emit canceled event\n editShapeBus.emit(EditShapeEvents.canceled, {\n shape: state.editingShape,\n mapId,\n } as unknown as ShapeEditCanceledEvent['payload']);\n }\n },\n});\n\n// =============================================================================\n// Convenience exports\n// =============================================================================\n\n/**\n * Get the current editing state for a mapId\n * Returns null if no store instance exists\n */\nexport function getEditingState(mapId: UniqueId): EditingState | null {\n if (!editStore.exists(mapId)) {\n return null;\n }\n return editStore.get(mapId);\n}\n\n/**\n * Hook for editing state\n */\nexport function useEditingState(\n mapId: UniqueId,\n): { state: EditingState } & EditShapeActions {\n return editStore.use(mapId);\n}\n\n/**\n * Manually clear editing state for a specific mapId.\n */\nexport function clearEditingState(mapId: UniqueId): void {\n editStore.clear(mapId);\n}\n\n/**\n * Update feature from the layer component (called during drag operations)\n */\nexport function updateFeatureFromLayer(\n mapId: UniqueId,\n feature: Feature,\n): void {\n editStore.set(mapId, { featureBeingEdited: feature });\n}\n\n/**\n * Cancel editing (called by the layer component on ESC)\n */\nexport function cancelEditingFromLayer(mapId: UniqueId): void {\n editStore.actions(mapId).cancel();\n}\n\n/**\n * Save editing (called by the layer component on Enter)\n */\nexport function saveEditingFromLayer(mapId: UniqueId): void {\n editStore.actions(mapId).save();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"store.js","names":["DEFAULT_EDITING_STATE: EditingState"],"sources":["../../../../src/deckgl/shapes/edit-shape-layer/store.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\n/**\n * Edit Shape Store\n *\n * Manages editing state for shape modification.\n *\n * @example\n * ```typescript\n * import { editStore } from '@accelint/map-toolkit/deckgl/shapes';\n *\n * function EditControls({ mapId }) {\n * const { state, edit, save, cancel } = editStore.use(mapId);\n *\n * return (\n * <div>\n * <p>Editing: {state.editingShape?.name ?? 'none'}</p>\n * <button onClick={save}>Save</button>\n * <button onClick={cancel}>Cancel</button>\n * </div>\n * );\n * }\n * ```\n */\n\nimport { Broadcast } from '@accelint/bus';\nimport { createMapStore } from '@/shared/create-map-store';\nimport { createLoggerDomain } from '@/shared/logger';\nimport { MapEvents } from '../../base-map/events';\nimport {\n isCircleShape,\n isEllipseShape,\n isPointShape,\n isRectangleShape,\n} from '../shared/types';\nimport {\n releaseModeAndCursor,\n requestCursorChange,\n requestModeChange,\n} from '../shared/utils/mode-utils';\nimport {\n EDIT_CURSOR_MAP,\n EDIT_SHAPE_LAYER_ID,\n EDIT_SHAPE_MODE,\n} from './constants';\nimport { EditShapeEvents } from './events';\nimport type { UniqueId } from '@accelint/core';\nimport type { Feature } from 'geojson';\nimport type { MapEventType } from '../../base-map/types';\nimport type { Shape } from '../shared/types';\nimport type {\n EditShapeEvent,\n ShapeEditCanceledEvent,\n ShapeEditingEvent,\n ShapeUpdatedEvent,\n} from './events';\nimport type {\n EditFunction,\n EditingState,\n EditMode,\n EditShapeOptions,\n} from './types';\n\nconst logger = createLoggerDomain('[EditShapeLayer]');\n\n/**\n * Typed event bus instances\n */\nconst editShapeBus = Broadcast.getInstance<EditShapeEvent>();\nconst mapEventBus = Broadcast.getInstance<MapEventType>();\n\n/**\n * Default editing state\n */\nconst DEFAULT_EDITING_STATE: EditingState = {\n editingShape: null,\n editMode: 'view',\n featureBeingEdited: null,\n previousMode: null,\n};\n\n/**\n * Actions for edit shape store\n */\ntype EditShapeActions = {\n /** Start editing a shape */\n edit: EditFunction;\n /** Save the current edits */\n save: () => void;\n /** Cancel editing */\n cancel: () => void;\n};\n\n/**\n * Determine the appropriate edit mode for a shape type\n *\n * @param shape - The shape to determine the edit mode for\n * @returns The edit mode to use for this shape type\n */\nfunction getEditModeForShape(shape: Shape): EditMode {\n if (isPointShape(shape)) {\n return 'point-translate';\n }\n if (isCircleShape(shape)) {\n return 'circle-transform';\n }\n if (isEllipseShape(shape) || isRectangleShape(shape)) {\n return 'bounding-transform';\n }\n return 'vertex-transform';\n}\n\n/**\n * Start editing a shape\n */\nfunction startEditing(\n mapId: UniqueId,\n state: EditingState,\n shape: Shape,\n options: EditShapeOptions | undefined,\n notify: () => void,\n setState: (updates: Partial<EditingState>) => void,\n): void {\n // Prevent editing locked shapes\n if (shape.locked) {\n logger.warn(`Cannot edit locked shape: \"${shape.name}\"`);\n return;\n }\n\n // Already editing - cancel first\n if (state.editingShape) {\n cancelEditingInternal(mapId, state, notify, setState);\n }\n\n // Determine edit mode (can be overridden via options)\n const editMode = options?.mode ?? getEditModeForShape(shape);\n\n // Update state with new object reference\n setState({\n editingShape: shape,\n editMode,\n featureBeingEdited: shape.feature,\n });\n\n // Request map mode and cursor\n requestModeChange(mapId, EDIT_SHAPE_MODE, EDIT_SHAPE_LAYER_ID);\n const cursor = EDIT_CURSOR_MAP[editMode];\n requestCursorChange(mapId, cursor, EDIT_SHAPE_LAYER_ID);\n\n // Disable map panning during editing\n mapEventBus.emit(MapEvents.disablePan, { id: mapId });\n\n // Emit editing started event\n editShapeBus.emit(EditShapeEvents.editing, {\n shape,\n mapId,\n } as unknown as ShapeEditingEvent['payload']);\n\n notify();\n}\n\n/**\n * Save editing and create updated shape\n */\nfunction saveEditingInternal(\n mapId: UniqueId,\n state: EditingState,\n notify: () => void,\n setState: (updates: Partial<EditingState>) => void,\n): Shape | null {\n if (!(state.editingShape && state.featureBeingEdited)) {\n return null;\n }\n\n const originalShape = state.editingShape;\n const updatedFeature = state.featureBeingEdited;\n\n // Create updated shape with new geometry\n const updatedShape = {\n ...originalShape,\n feature: {\n ...updatedFeature,\n properties: {\n ...originalShape.feature.properties,\n ...updatedFeature.properties,\n },\n },\n lastUpdated: Date.now(),\n } as Shape;\n\n // Reset state\n setState({\n editingShape: null,\n editMode: 'view',\n featureBeingEdited: null,\n previousMode: null,\n });\n\n // Return to default mode and cursor\n releaseModeAndCursor(mapId, EDIT_SHAPE_LAYER_ID);\n\n // Re-enable map panning\n mapEventBus.emit(MapEvents.enablePan, { id: mapId });\n\n // Emit shape updated event\n editShapeBus.emit(EditShapeEvents.updated, {\n shape: updatedShape,\n mapId,\n } as unknown as ShapeUpdatedEvent['payload']);\n\n notify();\n\n return updatedShape;\n}\n\n/**\n * Cancel the current editing operation\n */\nfunction cancelEditingInternal(\n mapId: UniqueId,\n state: EditingState,\n notify: () => void,\n setState: (updates: Partial<EditingState>) => void,\n): void {\n if (!state.editingShape) {\n return; // Nothing to cancel\n }\n\n const originalShape = state.editingShape;\n\n // Reset state\n setState({\n editingShape: null,\n editMode: 'view',\n featureBeingEdited: null,\n previousMode: null,\n });\n\n // Return to default mode and cursor\n releaseModeAndCursor(mapId, EDIT_SHAPE_LAYER_ID);\n\n // Re-enable map panning\n mapEventBus.emit(MapEvents.enablePan, { id: mapId });\n\n // Emit canceled event\n editShapeBus.emit(EditShapeEvents.canceled, {\n shape: originalShape,\n mapId,\n } as unknown as ShapeEditCanceledEvent['payload']);\n\n notify();\n}\n\n/**\n * Edit shape store\n */\nexport const editStore = createMapStore<EditingState, EditShapeActions>({\n defaultState: { ...DEFAULT_EDITING_STATE },\n\n actions: (mapId, { get, set, notify }) => ({\n edit: (shape: Shape, options?: EditShapeOptions) => {\n startEditing(mapId, get(), shape, options, notify, set);\n },\n\n save: () => {\n saveEditingInternal(mapId, get(), notify, set);\n },\n\n cancel: () => {\n cancelEditingInternal(mapId, get(), notify, set);\n },\n }),\n\n // Note: EditShapeLayer is \"neutral\" regarding mode change authorization.\n // It doesn't auto-cancel or reject mode changes - those decisions are\n // left to UI components that can prompt the user.\n\n onCleanup: (mapId, state) => {\n // Cancel any active editing before cleanup\n if (state.editingShape) {\n // Return to default mode and cursor\n releaseModeAndCursor(mapId, EDIT_SHAPE_LAYER_ID);\n\n // Re-enable map panning\n mapEventBus.emit(MapEvents.enablePan, { id: mapId });\n\n // Emit canceled event\n editShapeBus.emit(EditShapeEvents.canceled, {\n shape: state.editingShape,\n mapId,\n } as unknown as ShapeEditCanceledEvent['payload']);\n }\n },\n});\n\n// =============================================================================\n// Convenience exports\n// =============================================================================\n\n/**\n * Get the current editing state for a mapId\n * Returns null if no store instance exists\n *\n * @param mapId - The map instance ID.\n * @returns The current editing state, or null if no store instance exists.\n */\nexport function getEditingState(mapId: UniqueId): EditingState | null {\n if (!editStore.exists(mapId)) {\n return null;\n }\n return editStore.get(mapId);\n}\n\n/**\n * Hook for editing state\n * @param mapId - The map instance ID.\n * @returns The current editing state and edit actions.\n *\n * @example\n * ```typescript\n * const { state, edit, save, cancel } = useEditingState(mapId);\n */\nexport function useEditingState(\n mapId: UniqueId,\n): { state: EditingState } & EditShapeActions {\n return editStore.use(mapId);\n}\n\n/**\n * Manually clear editing state for a specific mapId.\n * @param mapId - The map instance ID.\n */\nexport function clearEditingState(mapId: UniqueId): void {\n editStore.clear(mapId);\n}\n\n/**\n * Update the feature currently being edited.\n *\n * Called internally by the layer during drag operations, and also available\n * to consumers via the `useEditShape` hook for form-driven updates.\n *\n * @param mapId - The map instance ID.\n * @param feature - The updated GeoJSON feature to store as the live editing state.\n *\n * @example\n * ```typescript\n * // From a form input handler\n * const newGeometry = circle(center, radius, { units: 'kilometers' }).geometry;\n * updateFeature(mapId, { ...currentFeature, geometry: newGeometry });\n * ```\n */\nexport function updateFeature(mapId: UniqueId, feature: Feature): void {\n editStore.set(mapId, { featureBeingEdited: feature });\n}\n\n/**\n * Cancel editing (called by the layer component on ESC)\n * @param mapId - The map instance ID.\n */\nexport function cancelEditingFromLayer(mapId: UniqueId): void {\n editStore.actions(mapId).cancel();\n}\n\n/**\n * Save editing (called by the layer component on Enter)\n * @param mapId - The map instance ID.\n */\nexport function saveEditingFromLayer(mapId: UniqueId): void {\n editStore.actions(mapId).save();\n}\n\n/**\n * Enables map panning while editing by switching to view mode and storing the\n * current edit mode for restoration.\n *\n * No-op if no shape is currently being edited.\n *\n * @param mapId - The map instance ID.\n *\n * @example\n * ```typescript\n * enableEditPanning(mapId);\n * ```\n */\nexport function enableEditPanning(mapId: UniqueId): void {\n const state = editStore.get(mapId);\n if (state?.previousMode !== null || !state?.editingShape) {\n return;\n }\n\n editStore.set(mapId, { previousMode: state.editMode, editMode: 'view' });\n mapEventBus.emit(MapEvents.enablePan, { id: mapId });\n requestCursorChange(mapId, 'grab', EDIT_SHAPE_LAYER_ID);\n}\n\n/**\n * Disables map panning and restores the previous edit mode.\n *\n * If no shape is being edited, clears the stored `previousMode` and returns.\n * Otherwise, restores the edit mode from `previousMode`, re-disables panning,\n * and sets the cursor back to the shape-appropriate edit cursor.\n *\n * @param mapId - The map instance ID.\n *\n * @example\n * ```typescript\n * disableEditPanning(mapId);\n * ```\n */\nexport function disableEditPanning(mapId: UniqueId): void {\n const state = editStore.get(mapId);\n\n if (!state?.editingShape) {\n editStore.set(mapId, { previousMode: null });\n return;\n }\n\n const previousMode = state?.previousMode;\n if (!previousMode) {\n editStore.set(mapId, { previousMode: null });\n return;\n }\n\n editStore.set(mapId, { editMode: previousMode, previousMode: null });\n mapEventBus.emit(MapEvents.disablePan, { id: mapId });\n requestCursorChange(\n mapId,\n EDIT_CURSOR_MAP[previousMode],\n EDIT_SHAPE_LAYER_ID,\n );\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -10,10 +10,12 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { DistanceUnitAbbreviation } from "../../../shared/units.js";
14
13
  import { Shape } from "../shared/types.js";
15
14
  import { UniqueId } from "@accelint/core";
15
+ import { KeyOption } from "@accelint/hotkey-manager";
16
+ import { DistanceUnitSymbol } from "@accelint/constants/units";
16
17
  import { Feature } from "geojson";
18
+ import { NonEmptyArray } from "@accelint/hotkey-manager/types/non-empty-array";
17
19
 
18
20
  //#region src/deckgl/shapes/edit-shape-layer/types.d.ts
19
21
  /**
@@ -36,6 +38,8 @@ type EditingState = {
36
38
  editMode: EditMode;
37
39
  /** Live feature being edited (updates in real-time during drag) */
38
40
  featureBeingEdited: Feature | null;
41
+ /** Edit mode to restore after held panning hotkey is released. Null when not panning. */
42
+ previousMode: EditMode | null;
39
43
  };
40
44
  /**
41
45
  * Options for starting an edit operation
@@ -65,6 +69,8 @@ type UseEditShapeReturn = {
65
69
  save: () => void;
66
70
  /** Cancel editing and revert to original shape */
67
71
  cancel: () => void;
72
+ /** Update the feature being edited (e.g., from a form). No-op when not editing. */
73
+ updateFeature: (feature: Feature) => void;
68
74
  /** Whether currently in editing mode */
69
75
  isEditing: boolean;
70
76
  /** The shape currently being edited (null if not editing) */
@@ -83,12 +89,20 @@ type EditShapeLayerProps = {
83
89
  */
84
90
  mapId?: UniqueId;
85
91
  /** Distance unit for tooltip measurements (defaults to 'km') */
86
- unit?: DistanceUnitAbbreviation;
92
+ unit?: DistanceUnitSymbol;
93
+ /** Configuration for hotkeys in EditShapesLayer */
94
+ hotkeyConfig?: EditShapeHotkeyConfig;
87
95
  };
88
96
  /**
89
97
  * Function type for the edit action
90
98
  */
91
99
  type EditFunction = (shape: Shape, options?: EditShapeOptions) => void;
100
+ /**
101
+ * Type to define hotkey configurations for functions in EditShapeLayer
102
+ */
103
+ type EditShapeHotkeyConfig = {
104
+ panning: KeyOption | NonEmptyArray<KeyOption>;
105
+ };
92
106
  //#endregion
93
- export { EditFunction, EditMode, EditShapeLayerProps, EditShapeOptions, EditingState, UseEditShapeOptions, UseEditShapeReturn };
107
+ export { EditFunction, EditMode, EditShapeHotkeyConfig, EditShapeLayerProps, EditShapeOptions, EditingState, UseEditShapeOptions, UseEditShapeReturn };
94
108
  //# sourceMappingURL=types.d.ts.map
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -24,7 +24,7 @@ import { UniqueId } from "@accelint/core";
24
24
  *
25
25
  * @param mapId - Optional map instance ID. If not provided, will use the ID from `MapContext`.
26
26
  * @param options - Optional callbacks for onUpdate and onCancel events
27
- * @returns Editing state, edit/save/cancel functions, and convenience flags
27
+ * @returns Editing state, edit/save/cancel/updateFeature functions, and convenience flags
28
28
  * @throws Error if no `mapId` is provided and hook is used outside of `MapProvider`
29
29
  *
30
30
  * @example
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -14,7 +14,7 @@
14
14
  'use client';
15
15
 
16
16
  import { EditShapeEvents } from "./events.js";
17
- import { editStore } from "./store.js";
17
+ import { editStore, updateFeature } from "./store.js";
18
18
  import { MapContext } from "../../base-map/provider.js";
19
19
  import { useContext, useMemo } from "react";
20
20
  import { useBus } from "@accelint/bus/react";
@@ -29,7 +29,7 @@ import { useBus } from "@accelint/bus/react";
29
29
  *
30
30
  * @param mapId - Optional map instance ID. If not provided, will use the ID from `MapContext`.
31
31
  * @param options - Optional callbacks for onUpdate and onCancel events
32
- * @returns Editing state, edit/save/cancel functions, and convenience flags
32
+ * @returns Editing state, edit/save/cancel/updateFeature functions, and convenience flags
33
33
  * @throws Error if no `mapId` is provided and hook is used outside of `MapProvider`
34
34
  *
35
35
  * @example
@@ -99,13 +99,17 @@ function useEditShape(mapId, options) {
99
99
  edit,
100
100
  save,
101
101
  cancel,
102
+ updateFeature: (feature) => {
103
+ if (editingState?.editingShape) updateFeature(actualId, feature);
104
+ },
102
105
  isEditing: !!editingState?.editingShape,
103
106
  editingShape: editingState?.editingShape ?? null
104
107
  }), [
105
108
  editingState,
106
109
  edit,
107
110
  save,
108
- cancel
111
+ cancel,
112
+ actualId
109
113
  ]);
110
114
  }
111
115
 
@@ -1 +1 @@
1
- {"version":3,"file":"use-edit-shape.js","names":[],"sources":["../../../../src/deckgl/shapes/edit-shape-layer/use-edit-shape.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 'client-only';\nimport { useBus } from '@accelint/bus/react';\nimport { useContext, useMemo } from 'react';\nimport { MapContext } from '../../base-map/provider';\nimport { EditShapeEvents } from './events';\nimport { editStore } from './store';\nimport type { UniqueId } from '@accelint/core';\nimport type { EditShapeEvent } from './events';\nimport type { UseEditShapeOptions, UseEditShapeReturn } from './types';\n\n/**\n * Hook to access the shape editing state and actions.\n *\n * This hook uses `useSyncExternalStore` to subscribe to editing state changes,\n * providing concurrent-safe state updates. Uses a fan-out pattern where\n * a single bus listener per map instance notifies N React component subscribers.\n *\n * @param mapId - Optional map instance ID. If not provided, will use the ID from `MapContext`.\n * @param options - Optional callbacks for onUpdate and onCancel events\n * @returns Editing state, edit/save/cancel functions, and convenience flags\n * @throws Error if no `mapId` is provided and hook is used outside of `MapProvider`\n *\n * @example\n * ```tsx\n * // Inside MapProvider (within BaseMap children) - uses context\n * function ShapeEditor() {\n * const { edit, save, cancel, isEditing, editingShape } = useEditShape(undefined, {\n * onUpdate: (shape) => {\n * console.log('Shape updated:', shape);\n * setShapes(prev => prev.map(s => s.id === shape.id ? shape : s));\n * },\n * onCancel: (shape) => {\n * console.log('Editing canceled:', shape.name);\n * },\n * });\n *\n * return (\n * <div>\n * {selectedShape && !isEditing && (\n * <button onClick={() => edit(selectedShape)}>\n * Edit Shape\n * </button>\n * )}\n * {isEditing && (\n * <>\n * <button onClick={save}>Save</button>\n * <button onClick={cancel}>Cancel</button>\n * </>\n * )}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Outside MapProvider - pass mapId directly\n * function ExternalEditControl({ mapId, shape }: { mapId: UniqueId; shape: Shape }) {\n * const { edit, isEditing } = useEditShape(mapId);\n *\n * return (\n * <button\n * onClick={() => edit(shape)}\n * disabled={isEditing}\n * >\n * Edit\n * </button>\n * );\n * }\n * ```\n */\nexport function useEditShape(\n mapId?: UniqueId,\n options?: UseEditShapeOptions,\n): UseEditShapeReturn {\n const contextId = useContext(MapContext);\n const actualId = mapId ?? contextId;\n\n if (!actualId) {\n throw new Error(\n 'useEditShape requires either a mapId parameter or to be used within a MapProvider',\n );\n }\n\n const { onUpdate, onCancel } = options ?? {};\n\n // Use the v2 store API directly\n const { state: editingState, edit, save, cancel } = editStore.use(actualId);\n\n // Listen for completion/cancellation events to trigger callbacks\n // useOn handles cleanup automatically and uses useEffectEvent for stable callbacks\n const { useOn } = useBus<EditShapeEvent>();\n\n useOn(EditShapeEvents.updated, (event) => {\n if (event.payload.mapId === actualId && onUpdate) {\n onUpdate(event.payload.shape);\n }\n });\n\n useOn(EditShapeEvents.canceled, (event) => {\n if (event.payload.mapId === actualId && onCancel) {\n onCancel(event.payload.shape);\n }\n });\n\n // Memoize the return value to prevent unnecessary re-renders\n return useMemo(\n () => ({\n editingState,\n edit,\n save,\n cancel,\n isEditing: !!editingState?.editingShape,\n editingShape: editingState?.editingShape ?? null,\n }),\n [editingState, edit, save, cancel],\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqFA,SAAgB,aACd,OACA,SACoB;CACpB,MAAM,YAAY,WAAW,WAAW;CACxC,MAAM,WAAW,SAAS;AAE1B,KAAI,CAAC,SACH,OAAM,IAAI,MACR,oFACD;CAGH,MAAM,EAAE,UAAU,aAAa,WAAW,EAAE;CAG5C,MAAM,EAAE,OAAO,cAAc,MAAM,MAAM,WAAW,UAAU,IAAI,SAAS;CAI3E,MAAM,EAAE,mBAAU,QAAwB;AAE1C,SAAM,gBAAgB,UAAU,UAAU;AACxC,MAAI,MAAM,QAAQ,UAAU,YAAY,SACtC,UAAS,MAAM,QAAQ,MAAM;GAE/B;AAEF,SAAM,gBAAgB,WAAW,UAAU;AACzC,MAAI,MAAM,QAAQ,UAAU,YAAY,SACtC,UAAS,MAAM,QAAQ,MAAM;GAE/B;AAGF,QAAO,eACE;EACL;EACA;EACA;EACA;EACA,WAAW,CAAC,CAAC,cAAc;EAC3B,cAAc,cAAc,gBAAgB;EAC7C,GACD;EAAC;EAAc;EAAM;EAAM;EAAO,CACnC"}
1
+ {"version":3,"file":"use-edit-shape.js","names":[],"sources":["../../../../src/deckgl/shapes/edit-shape-layer/use-edit-shape.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 'client-only';\nimport { useBus } from '@accelint/bus/react';\nimport { useContext, useMemo } from 'react';\nimport { MapContext } from '../../base-map/provider';\nimport { EditShapeEvents } from './events';\nimport { editStore, updateFeature as storeUpdateFeature } from './store';\nimport type { UniqueId } from '@accelint/core';\nimport type { EditShapeEvent } from './events';\nimport type { UseEditShapeOptions, UseEditShapeReturn } from './types';\n\n/**\n * Hook to access the shape editing state and actions.\n *\n * This hook uses `useSyncExternalStore` to subscribe to editing state changes,\n * providing concurrent-safe state updates. Uses a fan-out pattern where\n * a single bus listener per map instance notifies N React component subscribers.\n *\n * @param mapId - Optional map instance ID. If not provided, will use the ID from `MapContext`.\n * @param options - Optional callbacks for onUpdate and onCancel events\n * @returns Editing state, edit/save/cancel/updateFeature functions, and convenience flags\n * @throws Error if no `mapId` is provided and hook is used outside of `MapProvider`\n *\n * @example\n * ```tsx\n * // Inside MapProvider (within BaseMap children) - uses context\n * function ShapeEditor() {\n * const { edit, save, cancel, isEditing, editingShape } = useEditShape(undefined, {\n * onUpdate: (shape) => {\n * console.log('Shape updated:', shape);\n * setShapes(prev => prev.map(s => s.id === shape.id ? shape : s));\n * },\n * onCancel: (shape) => {\n * console.log('Editing canceled:', shape.name);\n * },\n * });\n *\n * return (\n * <div>\n * {selectedShape && !isEditing && (\n * <button onClick={() => edit(selectedShape)}>\n * Edit Shape\n * </button>\n * )}\n * {isEditing && (\n * <>\n * <button onClick={save}>Save</button>\n * <button onClick={cancel}>Cancel</button>\n * </>\n * )}\n * </div>\n * );\n * }\n * ```\n *\n * @example\n * ```tsx\n * // Outside MapProvider - pass mapId directly\n * function ExternalEditControl({ mapId, shape }: { mapId: UniqueId; shape: Shape }) {\n * const { edit, isEditing } = useEditShape(mapId);\n *\n * return (\n * <button\n * onClick={() => edit(shape)}\n * disabled={isEditing}\n * >\n * Edit\n * </button>\n * );\n * }\n * ```\n */\nexport function useEditShape(\n mapId?: UniqueId,\n options?: UseEditShapeOptions,\n): UseEditShapeReturn {\n const contextId = useContext(MapContext);\n const actualId = mapId ?? contextId;\n\n if (!actualId) {\n throw new Error(\n 'useEditShape requires either a mapId parameter or to be used within a MapProvider',\n );\n }\n\n const { onUpdate, onCancel } = options ?? {};\n\n // Use the v2 store API directly\n const { state: editingState, edit, save, cancel } = editStore.use(actualId);\n\n // Listen for completion/cancellation events to trigger callbacks\n // useOn handles cleanup automatically and uses useEffectEvent for stable callbacks\n const { useOn } = useBus<EditShapeEvent>();\n\n useOn(EditShapeEvents.updated, (event) => {\n if (event.payload.mapId === actualId && onUpdate) {\n onUpdate(event.payload.shape);\n }\n });\n\n useOn(EditShapeEvents.canceled, (event) => {\n if (event.payload.mapId === actualId && onCancel) {\n onCancel(event.payload.shape);\n }\n });\n\n // Memoize the return value to prevent unnecessary re-renders\n return useMemo(\n () => ({\n editingState,\n edit,\n save,\n cancel,\n updateFeature: (feature) => {\n if (editingState?.editingShape) {\n storeUpdateFeature(actualId, feature);\n }\n },\n isEditing: !!editingState?.editingShape,\n editingShape: editingState?.editingShape ?? null,\n }),\n [editingState, edit, save, cancel, actualId],\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqFA,SAAgB,aACd,OACA,SACoB;CACpB,MAAM,YAAY,WAAW,WAAW;CACxC,MAAM,WAAW,SAAS;AAE1B,KAAI,CAAC,SACH,OAAM,IAAI,MACR,oFACD;CAGH,MAAM,EAAE,UAAU,aAAa,WAAW,EAAE;CAG5C,MAAM,EAAE,OAAO,cAAc,MAAM,MAAM,WAAW,UAAU,IAAI,SAAS;CAI3E,MAAM,EAAE,mBAAU,QAAwB;AAE1C,SAAM,gBAAgB,UAAU,UAAU;AACxC,MAAI,MAAM,QAAQ,UAAU,YAAY,SACtC,UAAS,MAAM,QAAQ,MAAM;GAE/B;AAEF,SAAM,gBAAgB,WAAW,UAAU;AACzC,MAAI,MAAM,QAAQ,UAAU,YAAY,SACtC,UAAS,MAAM,QAAQ,MAAM;GAE/B;AAGF,QAAO,eACE;EACL;EACA;EACA;EACA;EACA,gBAAgB,YAAY;AAC1B,OAAI,cAAc,aAChB,eAAmB,UAAU,QAAQ;;EAGzC,WAAW,CAAC,CAAC,cAAc;EAC3B,cAAc,cAAc,gBAAgB;EAC7C,GACD;EAAC;EAAc;EAAM;EAAM;EAAQ;EAAS,CAC7C"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -10,9 +10,9 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { CircleFeatureProperties, CircleProperties, CircleRadius, CircleShape, EllipseFeatureProperties, EllipseProperties, EllipseShape, LineStringShape, PointShape, PolygonShape, RectangleShape, Shape, ShapeFeature, ShapeFeatureProperties, ShapeFeatureType, ShapeFeatureTypeValues, ShapeId, StyleProperties, Subscription, isCircleShape, isEllipseShape, isLineStringShape, isPointShape, isPolygonShape, isRectangleShape } from "./shared/types.js";
13
+ import { CircleFeatureProperties, CircleProperties, CircleRadius, CircleShape, EllipseFeatureProperties, EllipseProperties, EllipseShape, GeoPosition, LineStringShape, PointShape, PolygonShape, RectangleShape, Shape, ShapeFeature, ShapeFeatureProperties, ShapeFeatureType, ShapeId, StyleProperties, StyledFeature, StyledFeatureProperties, isCircleShape, isEllipseShape, isLineStringShape, isPointShape, isPolygonShape, isRectangleShape } from "./shared/types.js";
14
14
  import { CardinalLabelCoordinateAnchor, LabelHorizontalPosition, LabelPosition2d, LabelPositionOptions, LabelVerticalPosition } from "./display-shape-layer/utils/labels.js";
15
- import { DisplayShapeLayerProps, ShowLabelsMode, StyledFeature, StyledFeatureProperties } from "./display-shape-layer/types.js";
15
+ import { DisplayShapeLayerProps, ShowLabelsMode } from "./display-shape-layer/types.js";
16
16
  import { DisplayShapeLayer } from "./display-shape-layer/index.js";
17
17
  import { UseSelectShapeReturn, useSelectShape } from "./display-shape-layer/use-select-shape.js";
18
18
  import { DrawShapeEvent, DrawShapeEventType, DrawShapeEvents, ShapeDrawCanceledEvent, ShapeDrawingEvent, ShapeDrawnEvent } from "./draw-shape-layer/events.js";
@@ -25,5 +25,6 @@ import { EditShapeLayer } from "./edit-shape-layer/index.js";
25
25
  import { useEditShape } from "./edit-shape-layer/use-edit-shape.js";
26
26
  import { BASE_FILL_OPACITY, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_EDIT_HANDLE_COLOR, DEFAULT_EDIT_HANDLE_OUTLINE_COLOR, DEFAULT_STYLE_PROPERTIES, LINE_PATTERNS, LINE_WIDTHS, SHAPE_LAYER_IDS } from "./shared/constants.js";
27
27
  import { ShapeEventType, ShapeEvents } from "./shared/events.js";
28
+ import { DuplicateShapeOptions, duplicateShape } from "./shared/utils/duplicate-shape.js";
28
29
  import { getDashArray, getFillColor, getLineColor, getLineWidth, normalizeColor } from "./shared/utils/style-utils.js";
29
- export { BASE_FILL_OPACITY, type CardinalLabelCoordinateAnchor, type CircleFeatureProperties, type CircleProperties, type CircleRadius, type CircleShape, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_EDIT_HANDLE_COLOR, DEFAULT_EDIT_HANDLE_OUTLINE_COLOR, DEFAULT_STYLE_PROPERTIES, DisplayShapeLayer, type DisplayShapeLayerProps, type DrawShapeEvent, type DrawShapeEventType, DrawShapeEvents, DrawShapeLayer, type DrawShapeLayerProps, type DrawShapeOptions, type DrawingState, type EditMode, type EditShapeEvent, type EditShapeEventType, EditShapeEvents, EditShapeLayer, type EditShapeLayerProps, type EditShapeOptions, type EditingState, type EllipseFeatureProperties, type EllipseProperties, type EllipseShape, LINE_PATTERNS, LINE_WIDTHS, type LabelHorizontalPosition, type LabelPosition2d, type LabelPositionOptions, type LabelVerticalPosition, type LineStringShape, type PointShape, type PolygonShape, type RectangleShape, SHAPE_LAYER_IDS, type Shape, type ShapeDrawCanceledEvent, type ShapeDrawingEvent, type ShapeDrawnEvent, type ShapeEditCanceledEvent, type ShapeEditingEvent, type ShapeEventType, ShapeEvents, type ShapeFeature, type ShapeFeatureProperties, ShapeFeatureType, type ShapeFeatureTypeValues, type ShapeId, type ShapeUpdatedEvent, type ShowLabelsMode, type StyleProperties, type StyledFeature, type StyledFeatureProperties, type Subscription, type UseDrawShapeOptions, type UseDrawShapeReturn, type UseEditShapeOptions, type UseEditShapeReturn, type UseSelectShapeReturn, getDashArray, getFillColor, getLineColor, getLineWidth, isCircleShape, isEllipseShape, isLineStringShape, isPointShape, isPolygonShape, isRectangleShape, normalizeColor, useDrawShape, useEditShape, useSelectShape };
30
+ export { BASE_FILL_OPACITY, type CardinalLabelCoordinateAnchor, type CircleFeatureProperties, type CircleProperties, type CircleRadius, type CircleShape, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_EDIT_HANDLE_COLOR, DEFAULT_EDIT_HANDLE_OUTLINE_COLOR, DEFAULT_STYLE_PROPERTIES, DisplayShapeLayer, type DisplayShapeLayerProps, type DrawShapeEvent, type DrawShapeEventType, DrawShapeEvents, DrawShapeLayer, type DrawShapeLayerProps, type DrawShapeOptions, type DrawingState, type DuplicateShapeOptions, type EditMode, type EditShapeEvent, type EditShapeEventType, EditShapeEvents, EditShapeLayer, type EditShapeLayerProps, type EditShapeOptions, type EditingState, type EllipseFeatureProperties, type EllipseProperties, type EllipseShape, type GeoPosition, LINE_PATTERNS, LINE_WIDTHS, type LabelHorizontalPosition, type LabelPosition2d, type LabelPositionOptions, type LabelVerticalPosition, type LineStringShape, type PointShape, type PolygonShape, type RectangleShape, SHAPE_LAYER_IDS, type Shape, type ShapeDrawCanceledEvent, type ShapeDrawingEvent, type ShapeDrawnEvent, type ShapeEditCanceledEvent, type ShapeEditingEvent, type ShapeEventType, ShapeEvents, type ShapeFeature, type ShapeFeatureProperties, ShapeFeatureType, type ShapeId, type ShapeUpdatedEvent, type ShowLabelsMode, type StyleProperties, type StyledFeature, type StyledFeatureProperties, type UseDrawShapeOptions, type UseDrawShapeReturn, type UseEditShapeOptions, type UseEditShapeReturn, type UseSelectShapeReturn, duplicateShape, getDashArray, getFillColor, getLineColor, getLineWidth, isCircleShape, isEllipseShape, isLineStringShape, isPointShape, isPolygonShape, isRectangleShape, normalizeColor, useDrawShape, useEditShape, useSelectShape };
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -23,5 +23,6 @@ import { DrawShapeLayer } from "./draw-shape-layer/index.js";
23
23
  import { useDrawShape } from "./draw-shape-layer/use-draw-shape.js";
24
24
  import { EditShapeLayer } from "./edit-shape-layer/index.js";
25
25
  import { useEditShape } from "./edit-shape-layer/use-edit-shape.js";
26
+ import { duplicateShape } from "./shared/utils/duplicate-shape.js";
26
27
 
27
- export { BASE_FILL_OPACITY, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_EDIT_HANDLE_COLOR, DEFAULT_EDIT_HANDLE_OUTLINE_COLOR, DEFAULT_STYLE_PROPERTIES, DisplayShapeLayer, DrawShapeEvents, DrawShapeLayer, EditShapeEvents, EditShapeLayer, LINE_PATTERNS, LINE_WIDTHS, SHAPE_LAYER_IDS, ShapeEvents, ShapeFeatureType, getDashArray, getFillColor, getLineColor, getLineWidth, isCircleShape, isEllipseShape, isLineStringShape, isPointShape, isPolygonShape, isRectangleShape, normalizeColor, useDrawShape, useEditShape, useSelectShape };
28
+ export { BASE_FILL_OPACITY, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_EDIT_HANDLE_COLOR, DEFAULT_EDIT_HANDLE_OUTLINE_COLOR, DEFAULT_STYLE_PROPERTIES, DisplayShapeLayer, DrawShapeEvents, DrawShapeLayer, EditShapeEvents, EditShapeLayer, LINE_PATTERNS, LINE_WIDTHS, SHAPE_LAYER_IDS, ShapeEvents, ShapeFeatureType, duplicateShape, getDashArray, getFillColor, getLineColor, getLineWidth, isCircleShape, isEllipseShape, isLineStringShape, isPointShape, isPolygonShape, isRectangleShape, normalizeColor, useDrawShape, useEditShape, useSelectShape };
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -10,7 +10,7 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import { StyleProperties } from "./types.js";
13
+ import { LinePattern, StyleProperties } from "./types.js";
14
14
  import { Color } from "@deck.gl/core";
15
15
 
16
16
  //#region src/deckgl/shapes/shared/constants.d.ts
@@ -21,6 +21,7 @@ declare const SHAPE_LAYER_IDS: {
21
21
  readonly DISPLAY: "DISPLAY_SHAPES";
22
22
  readonly DISPLAY_HIGHLIGHT: "DISPLAY_SHAPES::Highlight";
23
23
  readonly DISPLAY_LABELS: "DISPLAY_SHAPES::Labels";
24
+ readonly DISPLAY_SELECTION: "DISPLAY_SHAPES::Selection";
24
25
  };
25
26
  /**
26
27
  * Base fill opacity multiplier for standard semi-transparent look.
@@ -59,7 +60,7 @@ declare const LINE_PATTERNS: readonly ["solid", "dashed", "dotted"];
59
60
  /**
60
61
  * Dash array patterns for border/outline rendering
61
62
  */
62
- declare const DASH_ARRAYS: Record<'solid' | 'dashed' | 'dotted', [number, number] | null>;
63
+ declare const DASH_ARRAYS: Record<LinePattern, [number, number] | null>;
63
64
  /**
64
65
  * Default edit handle color (white) - used by both draw and edit layers
65
66
  */
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -22,7 +22,8 @@ import { DEFAULT_TEXT_STYLE } from "../../text-settings.js";
22
22
  const SHAPE_LAYER_IDS = {
23
23
  DISPLAY: "DISPLAY_SHAPES",
24
24
  DISPLAY_HIGHLIGHT: "DISPLAY_SHAPES::Highlight",
25
- DISPLAY_LABELS: "DISPLAY_SHAPES::Labels"
25
+ DISPLAY_LABELS: "DISPLAY_SHAPES::Labels",
26
+ DISPLAY_SELECTION: "DISPLAY_SHAPES::Selection"
26
27
  };
27
28
  /**
28
29
  * Base fill opacity multiplier for standard semi-transparent look.
@@ -92,7 +93,7 @@ const DEFAULT_TENTATIVE_COLORS = {
92
93
  const DEFAULT_STYLE_PROPERTIES = {
93
94
  fillColor: DEFAULT_COLORS.fill,
94
95
  lineColor: DEFAULT_COLORS.line,
95
- lineWidth: 2,
96
+ lineWidth: DEFAULT_LINE_WIDTH,
96
97
  linePattern: "solid"
97
98
  };
98
99
  /**
@@ -141,10 +142,11 @@ const DEFAULT_EDIT_HANDLE_OUTLINE_COLOR = [
141
142
  /**
142
143
  * Empty feature collection for initializing editable layers
143
144
  */
144
- const EMPTY_FEATURE_COLLECTION = {
145
+ const EMPTY_FEATURE_COLLECTION = Object.freeze({
145
146
  type: "FeatureCollection",
146
- features: []
147
- };
147
+ features: Object.freeze([])
148
+ });
149
+ const ASCII_RANGE = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€";
148
150
  /**
149
151
  * Custom character set for deck.gl TextLayer used by tooltip rendering.
150
152
  *
@@ -153,8 +155,11 @@ const EMPTY_FEATURE_COLLECTION = {
153
155
  * like degree symbol (°) and superscript 2 (²) must be explicitly included
154
156
  * for tooltip text like "100.5 km²" to render correctly.
155
157
  */
156
- const TOOLTIP_CHARACTER_SET = ["°", "²"];
157
- for (let i = 32; i <= 128; i++) TOOLTIP_CHARACTER_SET.push(String.fromCharCode(i));
158
+ const TOOLTIP_CHARACTER_SET = [
159
+ "°",
160
+ "²",
161
+ ...ASCII_RANGE.split("")
162
+ ];
158
163
  /**
159
164
  * Sublayer props for tooltip text rendering.
160
165
  * Used by both draw-shape-layer and edit-shape-layer for area/distance tooltips.
@@ -195,6 +200,10 @@ const EDITABLE_LAYER_SUBLAYER_PROPS = {
195
200
  *
196
201
  * @param value - The distance value to format
197
202
  * @returns The formatted string with 2 decimal places
203
+ * @example
204
+ * ```typescript
205
+ * formatDistance(3.14159); // → "3.14"
206
+ * ```
198
207
  */
199
208
  function formatDistance(value) {
200
209
  return value.toFixed(2);
@@ -206,11 +215,28 @@ function formatDistance(value) {
206
215
  * @param area - Circle area in the specified units squared
207
216
  * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')
208
217
  * @returns Formatted tooltip text: "r: {radius} {unit}\n{area} {unit}²"
218
+ * @example
219
+ * ```typescript
220
+ * formatCircleTooltip(12.5, 490.87, 'km');
221
+ * // → "r: 12.50 km\n490.87 km²"
222
+ * ```
209
223
  */
210
224
  function formatCircleTooltip(radius, area, unitAbbrev) {
211
225
  return `r: ${formatDistance(radius)} ${unitAbbrev}\n${formatDistance(area)} ${unitAbbrev}²`;
212
226
  }
213
227
  /**
228
+ * Format a "{dim1} {unit} x {dim2} {unit}\n{area} {unit}²" tooltip string.
229
+ *
230
+ * @param dim1 - First dimension value
231
+ * @param dim2 - Second dimension value
232
+ * @param area - Area value
233
+ * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')
234
+ * @returns Formatted tooltip text
235
+ */
236
+ function formatDimensionsTooltip(dim1, dim2, area, unitAbbrev) {
237
+ return `${formatDistance(dim1)} ${unitAbbrev} x ${formatDistance(dim2)} ${unitAbbrev}\n${formatDistance(area)} ${unitAbbrev}²`;
238
+ }
239
+ /**
214
240
  * Format rectangle tooltip text showing dimensions and area.
215
241
  *
216
242
  * @param width - Rectangle width in the specified units
@@ -218,9 +244,14 @@ function formatCircleTooltip(radius, area, unitAbbrev) {
218
244
  * @param area - Rectangle area in the specified units squared
219
245
  * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')
220
246
  * @returns Formatted tooltip text: "{width} {unit} x {height} {unit}\n{area} {unit}²"
247
+ * @example
248
+ * ```typescript
249
+ * formatRectangleTooltip(5.0, 3.2, 16.0, 'km');
250
+ * // → "5.00 km x 3.20 km\n16.00 km²"
251
+ * ```
221
252
  */
222
253
  function formatRectangleTooltip(width, height, area, unitAbbrev) {
223
- return `${formatDistance(width)} ${unitAbbrev} x ${formatDistance(height)} ${unitAbbrev}\n${formatDistance(area)} ${unitAbbrev}²`;
254
+ return formatDimensionsTooltip(width, height, area, unitAbbrev);
224
255
  }
225
256
  /**
226
257
  * Format ellipse tooltip text showing axes and area.
@@ -230,9 +261,14 @@ function formatRectangleTooltip(width, height, area, unitAbbrev) {
230
261
  * @param area - Ellipse area in the specified units squared
231
262
  * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')
232
263
  * @returns Formatted tooltip text: "{major} {unit} x {minor} {unit}\n{area} {unit}²"
264
+ * @example
265
+ * ```typescript
266
+ * formatEllipseTooltip(10.0, 6.0, 47.12, 'km');
267
+ * // → "10.00 km x 6.00 km\n47.12 km²"
268
+ * ```
233
269
  */
234
270
  function formatEllipseTooltip(majorAxis, minorAxis, area, unitAbbrev) {
235
- return `${formatDistance(majorAxis)} ${unitAbbrev} x ${formatDistance(minorAxis)} ${unitAbbrev}\n${formatDistance(area)} ${unitAbbrev}²`;
271
+ return formatDimensionsTooltip(majorAxis, minorAxis, area, unitAbbrev);
236
272
  }
237
273
  /**
238
274
  * Format simple distance tooltip text.
@@ -240,6 +276,10 @@ function formatEllipseTooltip(majorAxis, minorAxis, area, unitAbbrev) {
240
276
  * @param distance - Distance value in the specified units
241
277
  * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')
242
278
  * @returns Formatted tooltip text: "{distance} {unit}"
279
+ * @example
280
+ * ```typescript
281
+ * formatDistanceTooltip(42.5, 'km'); // → "42.50 km"
282
+ * ```
243
283
  */
244
284
  function formatDistanceTooltip(distance, unitAbbrev) {
245
285
  return `${formatDistance(distance)} ${unitAbbrev}`;
@@ -269,5 +309,5 @@ const COMPLETION_EDIT_TYPES = new Set([
269
309
  ]);
270
310
 
271
311
  //#endregion
272
- export { BASE_FILL_OPACITY, COMPLETION_EDIT_TYPES, CONTINUOUS_EDIT_TYPES, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_EDIT_HANDLE_COLOR, DEFAULT_EDIT_HANDLE_OUTLINE_COLOR, DEFAULT_LINE_WIDTH, DEFAULT_STYLE_PROPERTIES, DEFAULT_TENTATIVE_COLORS, EDITABLE_LAYER_SUBLAYER_PROPS, EMPTY_FEATURE_COLLECTION, HIGHLIGHT_WIDTH_INCREASE, HOVER_WIDTH_INCREASE, LINE_PATTERNS, LINE_WIDTHS, SHAPE_LAYER_IDS, formatCircleTooltip, formatDistanceTooltip, formatEllipseTooltip, formatRectangleTooltip };
312
+ export { BASE_FILL_OPACITY, COMPLETION_EDIT_TYPES, CONTINUOUS_EDIT_TYPES, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_EDIT_HANDLE_COLOR, DEFAULT_EDIT_HANDLE_OUTLINE_COLOR, DEFAULT_LINE_WIDTH, DEFAULT_STYLE_PROPERTIES, DEFAULT_TENTATIVE_COLORS, EDITABLE_LAYER_SUBLAYER_PROPS, EMPTY_FEATURE_COLLECTION, HIGHLIGHT_WIDTH_INCREASE, HOVER_WIDTH_INCREASE, LINE_PATTERNS, LINE_WIDTHS, SHAPE_LAYER_IDS, formatCircleTooltip, formatDistance, formatDistanceTooltip, formatEllipseTooltip, formatRectangleTooltip };
273
313
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":["DEFAULT_STYLE_PROPERTIES: StyleProperties","DASH_ARRAYS: Record<\n 'solid' | 'dashed' | 'dotted',\n [number, number] | null\n>","DEFAULT_EDIT_HANDLE_COLOR: Color","DEFAULT_EDIT_HANDLE_OUTLINE_COLOR: Color","EMPTY_FEATURE_COLLECTION: import('geojson').FeatureCollection","TOOLTIP_CHARACTER_SET: string[]"],"sources":["../../../../src/deckgl/shapes/shared/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_TEXT_STYLE } from '../../text-settings';\nimport type { Color } from '@deck.gl/core';\nimport type { StyleProperties } from './types';\n\n/**\n * Layer IDs for shape layers\n */\nexport const SHAPE_LAYER_IDS = {\n DISPLAY: 'DISPLAY_SHAPES',\n DISPLAY_HIGHLIGHT: 'DISPLAY_SHAPES::Highlight',\n DISPLAY_LABELS: 'DISPLAY_SHAPES::Labels',\n} as const;\n\n/**\n * Base fill opacity multiplier for standard semi-transparent look.\n * Multiplies alpha by 0.2 (reduces to 20% of original opacity).\n */\nexport const BASE_FILL_OPACITY = 0.2;\n\n/**\n * Default border/outline width in pixels when not specified in styleProperties\n */\nexport const DEFAULT_LINE_WIDTH = 2;\n\n/**\n * Additional pixels added to border/outline width on hover\n */\nexport const HOVER_WIDTH_INCREASE = 2;\n\n/**\n * Additional pixels added to border/outline width for selection highlight\n */\nexport const HIGHLIGHT_WIDTH_INCREASE = 5;\n\n/**\n * Fixed opacity for label background (0-255)\n */\nexport const LABEL_BACKGROUND_OPACITY = 200;\n\n/**\n * Fixed opacity for label border (0-255)\n */\nexport const LABEL_BORDER_OPACITY = 255;\n\n/**\n * Default colors as RGBA arrays for DeckGL layers.\n *\n * These are the canonical color values used throughout the shapes system.\n * All other color constants should derive from these to maintain consistency.\n */\nexport const DEFAULT_COLORS = {\n /** Default fill color (white at full alpha) */\n fill: [255, 255, 255, 255] as Color,\n /** Default border/outline color (outline-interactive-hover: #888a8f) */\n line: [136, 138, 143, 255] as Color,\n /** Highlight/selection color (turquoise at ~39% alpha) */\n highlight: [40, 245, 190, 100] as Color,\n} as const;\n\n/**\n * Tentative (during-drawing) colors.\n *\n * These colors are used for the shape preview while drawing.\n * Fill is semi-transparent (8% opacity) to not obscure underlying features.\n * Border/outline uses the same color as saved shapes for consistency.\n */\nexport const DEFAULT_TENTATIVE_COLORS = {\n /** Tentative fill color (white at 8% opacity: 0.08 * 255 ≈ 20) */\n fill: [255, 255, 255, 20] as Color,\n /** Tentative border/outline color (same as saved shapes for consistency) */\n line: DEFAULT_COLORS.line,\n} as const;\n\n/**\n * Default style properties for saved shapes.\n *\n * These are applied when a shape is completed/saved.\n * Can be overridden via styleDefaults in draw options.\n */\nexport const DEFAULT_STYLE_PROPERTIES: StyleProperties = {\n fillColor: DEFAULT_COLORS.fill,\n lineColor: DEFAULT_COLORS.line,\n lineWidth: 2,\n linePattern: 'solid',\n};\n\n/**\n * Border/outline width options (in pixels)\n */\nexport const LINE_WIDTHS = [1, 2, 4, 8] as const;\n\n/**\n * Border/outline pattern options\n */\nexport const LINE_PATTERNS = ['solid', 'dashed', 'dotted'] as const;\n\n/**\n * Dash array patterns for border/outline rendering\n */\nexport const DASH_ARRAYS: Record<\n 'solid' | 'dashed' | 'dotted',\n [number, number] | null\n> = {\n solid: null,\n dashed: [8, 4],\n dotted: [2, 4],\n};\n\n/**\n * Default tentative fill color (white at 8% opacity - rgba(255, 255, 255, 0.08))\n * Used when drawing new shapes before they're completed.\n * 0.08 * 255 ≈ 20\n */\nexport const DEFAULT_TENTATIVE_FILL_COLOR: Color = [255, 255, 255, 20];\n\n/**\n * Default tentative border/outline color (outline-interactive-hover: #888a8f)\n * Used when drawing new shapes before they're completed.\n */\nexport const DEFAULT_TENTATIVE_LINE_COLOR: Color = [136, 138, 143, 255];\n\n/**\n * Default edit handle color (white) - used by both draw and edit layers\n */\nexport const DEFAULT_EDIT_HANDLE_COLOR: Color = [255, 255, 255, 255];\n\n/**\n * Edit handle outline color (dark for contrast)\n */\nexport const DEFAULT_EDIT_HANDLE_OUTLINE_COLOR: Color = [0, 0, 0, 200];\n\n/**\n * Empty feature collection for initializing editable layers\n */\nexport const EMPTY_FEATURE_COLLECTION: import('geojson').FeatureCollection = {\n type: 'FeatureCollection',\n features: [],\n};\n\n/**\n * Custom character set for deck.gl TextLayer used by tooltip rendering.\n *\n * deck.gl's TextLayer uses SDF (Signed Distance Field) font rendering which\n * by default only supports basic ASCII characters (32-128). Special characters\n * like degree symbol (°) and superscript 2 (²) must be explicitly included\n * for tooltip text like \"100.5 km²\" to render correctly.\n */\nexport const TOOLTIP_CHARACTER_SET: string[] = ['°', '²'];\n\n// Add standard ASCII characters (space through tilde + DEL)\nfor (let i = 32; i <= 128; i++) {\n TOOLTIP_CHARACTER_SET.push(String.fromCharCode(i));\n}\n\n/**\n * Sublayer props for tooltip text rendering.\n * Used by both draw-shape-layer and edit-shape-layer for area/distance tooltips.\n */\nexport const TOOLTIP_SUBLAYER_PROPS = {\n tooltips: {\n ...DEFAULT_TEXT_STYLE,\n fontFamily: 'Roboto MonoVariable, monospace',\n characterSet: TOOLTIP_CHARACTER_SET,\n getTextAnchor: 'start',\n getAlignmentBaseline: 'bottom',\n getPixelOffset: [8, 0],\n },\n};\n\n/**\n * Shared edit handle sublayer props for EditableGeoJsonLayer.\n * Used by both draw-shape-layer and edit-shape-layer.\n */\nexport const EDIT_HANDLE_SUBLAYER_PROPS = {\n editHandlePointOutline: {\n getFillColor: DEFAULT_EDIT_HANDLE_COLOR,\n getRadius: 6,\n },\n editHandlePoint: {\n getFillColor: DEFAULT_EDIT_HANDLE_COLOR,\n getRadius: 4,\n },\n};\n\n/**\n * Combined sublayer props for EditableGeoJsonLayer with tooltips and edit handles.\n * Used by both draw-shape-layer and edit-shape-layer.\n */\nexport const EDITABLE_LAYER_SUBLAYER_PROPS = {\n ...TOOLTIP_SUBLAYER_PROPS,\n ...EDIT_HANDLE_SUBLAYER_PROPS,\n};\n\n/**\n * Format a distance value for tooltip display.\n * Used by draw and edit mode tooltips for consistent formatting.\n *\n * @param value - The distance value to format\n * @returns The formatted string with 2 decimal places\n */\nexport function formatDistance(value: number): string {\n return value.toFixed(2);\n}\n\n// =============================================================================\n// Tooltip Text Formatters\n// =============================================================================\n// These functions generate consistent tooltip text for both draw and edit modes.\n\n/**\n * Format circle tooltip text showing radius and area.\n *\n * @param radius - Circle radius in the specified units\n * @param area - Circle area in the specified units squared\n * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')\n * @returns Formatted tooltip text: \"r: {radius} {unit}\\n{area} {unit}²\"\n */\nexport function formatCircleTooltip(\n radius: number,\n area: number,\n unitAbbrev: string,\n): string {\n return `r: ${formatDistance(radius)} ${unitAbbrev}\\n${formatDistance(area)} ${unitAbbrev}²`;\n}\n\n/**\n * Format rectangle tooltip text showing dimensions and area.\n *\n * @param width - Rectangle width in the specified units\n * @param height - Rectangle height in the specified units\n * @param area - Rectangle area in the specified units squared\n * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')\n * @returns Formatted tooltip text: \"{width} {unit} x {height} {unit}\\n{area} {unit}²\"\n */\nexport function formatRectangleTooltip(\n width: number,\n height: number,\n area: number,\n unitAbbrev: string,\n): string {\n return `${formatDistance(width)} ${unitAbbrev} x ${formatDistance(height)} ${unitAbbrev}\\n${formatDistance(area)} ${unitAbbrev}²`;\n}\n\n/**\n * Format ellipse tooltip text showing axes and area.\n *\n * @param majorAxis - Ellipse major axis (full length) in the specified units\n * @param minorAxis - Ellipse minor axis (full length) in the specified units\n * @param area - Ellipse area in the specified units squared\n * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')\n * @returns Formatted tooltip text: \"{major} {unit} x {minor} {unit}\\n{area} {unit}²\"\n */\nexport function formatEllipseTooltip(\n majorAxis: number,\n minorAxis: number,\n area: number,\n unitAbbrev: string,\n): string {\n return `${formatDistance(majorAxis)} ${unitAbbrev} x ${formatDistance(minorAxis)} ${unitAbbrev}\\n${formatDistance(area)} ${unitAbbrev}²`;\n}\n\n/**\n * Format simple distance tooltip text.\n *\n * @param distance - Distance value in the specified units\n * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')\n * @returns Formatted tooltip text: \"{distance} {unit}\"\n */\nexport function formatDistanceTooltip(\n distance: number,\n unitAbbrev: string,\n): string {\n return `${formatDistance(distance)} ${unitAbbrev}`;\n}\n\n// =============================================================================\n// Edit Event Type Classification\n// =============================================================================\n\n/**\n * Continuous edit event types that fire during dragging.\n * These are emitted repeatedly while the user drags during an edit operation.\n */\nexport const CONTINUOUS_EDIT_TYPES = new Set([\n 'movePosition',\n 'unionGeometry',\n 'scaling',\n 'rotating',\n 'translating',\n]);\n\n/**\n * Completion edit event types that fire when dragging ends.\n * These are emitted once when the user finishes an edit action.\n */\nexport const COMPLETION_EDIT_TYPES = new Set([\n 'finishMovePosition',\n 'addPosition',\n 'removePosition',\n 'scaled',\n 'rotated',\n 'translated',\n]);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,kBAAkB;CAC7B,SAAS;CACT,mBAAmB;CACnB,gBAAgB;CACjB;;;;;AAMD,MAAa,oBAAoB;;;;AAKjC,MAAa,qBAAqB;;;;AAKlC,MAAa,uBAAuB;;;;AAKpC,MAAa,2BAA2B;;;;;;;AAkBxC,MAAa,iBAAiB;CAE5B,MAAM;EAAC;EAAK;EAAK;EAAK;EAAI;CAE1B,MAAM;EAAC;EAAK;EAAK;EAAK;EAAI;CAE1B,WAAW;EAAC;EAAI;EAAK;EAAK;EAAI;CAC/B;;;;;;;;AASD,MAAa,2BAA2B;CAEtC,MAAM;EAAC;EAAK;EAAK;EAAK;EAAG;CAEzB,MAAM,eAAe;CACtB;;;;;;;AAQD,MAAaA,2BAA4C;CACvD,WAAW,eAAe;CAC1B,WAAW,eAAe;CAC1B,WAAW;CACX,aAAa;CACd;;;;AAKD,MAAa,cAAc;CAAC;CAAG;CAAG;CAAG;CAAE;;;;AAKvC,MAAa,gBAAgB;CAAC;CAAS;CAAU;CAAS;;;;AAK1D,MAAaC,cAGT;CACF,OAAO;CACP,QAAQ,CAAC,GAAG,EAAE;CACd,QAAQ,CAAC,GAAG,EAAE;CACf;;;;AAkBD,MAAaC,4BAAmC;CAAC;CAAK;CAAK;CAAK;CAAI;;;;AAKpE,MAAaC,oCAA2C;CAAC;CAAG;CAAG;CAAG;CAAI;;;;AAKtE,MAAaC,2BAAgE;CAC3E,MAAM;CACN,UAAU,EAAE;CACb;;;;;;;;;AAUD,MAAaC,wBAAkC,CAAC,KAAK,IAAI;AAGzD,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,IACzB,uBAAsB,KAAK,OAAO,aAAa,EAAE,CAAC;;;;;AAOpD,MAAa,yBAAyB,EACpC,UAAU;CACR,GAAG;CACH,YAAY;CACZ,cAAc;CACd,eAAe;CACf,sBAAsB;CACtB,gBAAgB,CAAC,GAAG,EAAE;CACvB,EACF;;;;;AAMD,MAAa,6BAA6B;CACxC,wBAAwB;EACtB,cAAc;EACd,WAAW;EACZ;CACD,iBAAiB;EACf,cAAc;EACd,WAAW;EACZ;CACF;;;;;AAMD,MAAa,gCAAgC;CAC3C,GAAG;CACH,GAAG;CACJ;;;;;;;;AASD,SAAgB,eAAe,OAAuB;AACpD,QAAO,MAAM,QAAQ,EAAE;;;;;;;;;;AAgBzB,SAAgB,oBACd,QACA,MACA,YACQ;AACR,QAAO,MAAM,eAAe,OAAO,CAAC,GAAG,WAAW,IAAI,eAAe,KAAK,CAAC,GAAG,WAAW;;;;;;;;;;;AAY3F,SAAgB,uBACd,OACA,QACA,MACA,YACQ;AACR,QAAO,GAAG,eAAe,MAAM,CAAC,GAAG,WAAW,KAAK,eAAe,OAAO,CAAC,GAAG,WAAW,IAAI,eAAe,KAAK,CAAC,GAAG,WAAW;;;;;;;;;;;AAYjI,SAAgB,qBACd,WACA,WACA,MACA,YACQ;AACR,QAAO,GAAG,eAAe,UAAU,CAAC,GAAG,WAAW,KAAK,eAAe,UAAU,CAAC,GAAG,WAAW,IAAI,eAAe,KAAK,CAAC,GAAG,WAAW;;;;;;;;;AAUxI,SAAgB,sBACd,UACA,YACQ;AACR,QAAO,GAAG,eAAe,SAAS,CAAC,GAAG;;;;;;AAWxC,MAAa,wBAAwB,IAAI,IAAI;CAC3C;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;AAMF,MAAa,wBAAwB,IAAI,IAAI;CAC3C;CACA;CACA;CACA;CACA;CACA;CACD,CAAC"}
1
+ {"version":3,"file":"constants.js","names":["DEFAULT_STYLE_PROPERTIES: StyleProperties","DASH_ARRAYS: Record<LinePattern, [number, number] | null>","DEFAULT_EDIT_HANDLE_COLOR: Color","DEFAULT_EDIT_HANDLE_OUTLINE_COLOR: Color","EMPTY_FEATURE_COLLECTION: FeatureCollection","TOOLTIP_CHARACTER_SET: string[]"],"sources":["../../../../src/deckgl/shapes/shared/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_TEXT_STYLE } from '../../text-settings';\nimport type { Color } from '@deck.gl/core';\nimport type { FeatureCollection } from 'geojson';\nimport type { LinePattern, StyleProperties } from './types';\n\n/**\n * Layer IDs for shape layers\n */\nexport const SHAPE_LAYER_IDS = {\n DISPLAY: 'DISPLAY_SHAPES',\n DISPLAY_HIGHLIGHT: 'DISPLAY_SHAPES::Highlight',\n DISPLAY_LABELS: 'DISPLAY_SHAPES::Labels',\n DISPLAY_SELECTION: 'DISPLAY_SHAPES::Selection',\n} as const;\n\n/**\n * Base fill opacity multiplier for standard semi-transparent look.\n * Multiplies alpha by 0.2 (reduces to 20% of original opacity).\n */\nexport const BASE_FILL_OPACITY = 0.2;\n\n/**\n * Default border/outline width in pixels when not specified in styleProperties\n */\nexport const DEFAULT_LINE_WIDTH = 2;\n\n/**\n * Additional pixels added to border/outline width on hover\n */\nexport const HOVER_WIDTH_INCREASE = 2;\n\n/**\n * Additional pixels added to border/outline width for selection highlight\n */\nexport const HIGHLIGHT_WIDTH_INCREASE = 5;\n\n/**\n * Fixed opacity for label background (0-255)\n */\nexport const LABEL_BACKGROUND_OPACITY = 200;\n\n/**\n * Fixed opacity for label border (0-255)\n */\nexport const LABEL_BORDER_OPACITY = 255;\n\n/**\n * Default colors as RGBA arrays for DeckGL layers.\n *\n * These are the canonical color values used throughout the shapes system.\n * All other color constants should derive from these to maintain consistency.\n */\nexport const DEFAULT_COLORS = {\n /** Default fill color (white at full alpha) */\n fill: [255, 255, 255, 255] as Color,\n /** Default border/outline color (outline-interactive-hover: #888a8f) */\n line: [136, 138, 143, 255] as Color,\n /** Highlight/selection color (turquoise at ~39% alpha) */\n highlight: [40, 245, 190, 100] as Color,\n} as const;\n\n/**\n * Tentative (during-drawing) colors.\n *\n * These colors are used for the shape preview while drawing.\n * Fill is semi-transparent (8% opacity) to not obscure underlying features.\n * Border/outline uses the same color as saved shapes for consistency.\n */\nexport const DEFAULT_TENTATIVE_COLORS = {\n /** Tentative fill color (white at 8% opacity: 0.08 * 255 ≈ 20) */\n fill: [255, 255, 255, 20] as Color,\n /** Tentative border/outline color (same as saved shapes for consistency) */\n line: DEFAULT_COLORS.line,\n} as const;\n\n/**\n * Default style properties for saved shapes.\n *\n * These are applied when a shape is completed/saved.\n * Can be overridden via styleDefaults in draw options.\n */\nexport const DEFAULT_STYLE_PROPERTIES: StyleProperties = {\n fillColor: DEFAULT_COLORS.fill,\n lineColor: DEFAULT_COLORS.line,\n lineWidth: DEFAULT_LINE_WIDTH,\n linePattern: 'solid',\n};\n\n/**\n * Border/outline width options (in pixels)\n */\nexport const LINE_WIDTHS = [1, 2, 4, 8] as const;\n\n/**\n * Border/outline pattern options\n */\nexport const LINE_PATTERNS = ['solid', 'dashed', 'dotted'] as const;\n\n/**\n * Dash array patterns for border/outline rendering\n */\nexport const DASH_ARRAYS: Record<LinePattern, [number, number] | null> = {\n solid: null,\n dashed: [8, 4],\n dotted: [2, 4],\n};\n\n/**\n * Default edit handle color (white) - used by both draw and edit layers\n */\nexport const DEFAULT_EDIT_HANDLE_COLOR: Color = [255, 255, 255, 255];\n\n/**\n * Edit handle outline color (dark for contrast)\n */\nexport const DEFAULT_EDIT_HANDLE_OUTLINE_COLOR: Color = [0, 0, 0, 200];\n\n/**\n * Empty feature collection for initializing editable layers\n */\nexport const EMPTY_FEATURE_COLLECTION: FeatureCollection = Object.freeze({\n type: 'FeatureCollection',\n features: Object.freeze([]),\n}) as unknown as FeatureCollection;\n\nconst ASCII_RANGE =\n ' !\"#$%&\\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\x7f\\x80';\n\n/**\n * Custom character set for deck.gl TextLayer used by tooltip rendering.\n *\n * deck.gl's TextLayer uses SDF (Signed Distance Field) font rendering which\n * by default only supports basic ASCII characters (32-128). Special characters\n * like degree symbol (°) and superscript 2 (²) must be explicitly included\n * for tooltip text like \"100.5 km²\" to render correctly.\n */\nexport const TOOLTIP_CHARACTER_SET: string[] = [\n '°',\n '²',\n ...ASCII_RANGE.split(''),\n];\n\n/**\n * Sublayer props for tooltip text rendering.\n * Used by both draw-shape-layer and edit-shape-layer for area/distance tooltips.\n */\nexport const TOOLTIP_SUBLAYER_PROPS = {\n tooltips: {\n ...DEFAULT_TEXT_STYLE,\n fontFamily: 'Roboto MonoVariable, monospace',\n characterSet: TOOLTIP_CHARACTER_SET,\n getTextAnchor: 'start',\n getAlignmentBaseline: 'bottom',\n getPixelOffset: [8, 0],\n },\n};\n\n/**\n * Shared edit handle sublayer props for EditableGeoJsonLayer.\n * Used by both draw-shape-layer and edit-shape-layer.\n */\nexport const EDIT_HANDLE_SUBLAYER_PROPS = {\n editHandlePointOutline: {\n getFillColor: DEFAULT_EDIT_HANDLE_COLOR,\n getRadius: 6,\n },\n editHandlePoint: {\n getFillColor: DEFAULT_EDIT_HANDLE_COLOR,\n getRadius: 4,\n },\n};\n\n/**\n * Combined sublayer props for EditableGeoJsonLayer with tooltips and edit handles.\n * Used by both draw-shape-layer and edit-shape-layer.\n */\nexport const EDITABLE_LAYER_SUBLAYER_PROPS = {\n ...TOOLTIP_SUBLAYER_PROPS,\n ...EDIT_HANDLE_SUBLAYER_PROPS,\n};\n\n/**\n * Format a distance value for tooltip display.\n * Used by draw and edit mode tooltips for consistent formatting.\n *\n * @param value - The distance value to format\n * @returns The formatted string with 2 decimal places\n * @example\n * ```typescript\n * formatDistance(3.14159); // → \"3.14\"\n * ```\n */\nexport function formatDistance(value: number): string {\n return value.toFixed(2);\n}\n\n// =============================================================================\n// Tooltip Text Formatters\n// =============================================================================\n// These functions generate consistent tooltip text for both draw and edit modes.\n\n/**\n * Format circle tooltip text showing radius and area.\n *\n * @param radius - Circle radius in the specified units\n * @param area - Circle area in the specified units squared\n * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')\n * @returns Formatted tooltip text: \"r: {radius} {unit}\\n{area} {unit}²\"\n * @example\n * ```typescript\n * formatCircleTooltip(12.5, 490.87, 'km');\n * // → \"r: 12.50 km\\n490.87 km²\"\n * ```\n */\nexport function formatCircleTooltip(\n radius: number,\n area: number,\n unitAbbrev: string,\n): string {\n return `r: ${formatDistance(radius)} ${unitAbbrev}\\n${formatDistance(area)} ${unitAbbrev}²`;\n}\n\n/**\n * Format a \"{dim1} {unit} x {dim2} {unit}\\n{area} {unit}²\" tooltip string.\n *\n * @param dim1 - First dimension value\n * @param dim2 - Second dimension value\n * @param area - Area value\n * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')\n * @returns Formatted tooltip text\n */\nfunction formatDimensionsTooltip(\n dim1: number,\n dim2: number,\n area: number,\n unitAbbrev: string,\n): string {\n return `${formatDistance(dim1)} ${unitAbbrev} x ${formatDistance(dim2)} ${unitAbbrev}\\n${formatDistance(area)} ${unitAbbrev}²`;\n}\n\n/**\n * Format rectangle tooltip text showing dimensions and area.\n *\n * @param width - Rectangle width in the specified units\n * @param height - Rectangle height in the specified units\n * @param area - Rectangle area in the specified units squared\n * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')\n * @returns Formatted tooltip text: \"{width} {unit} x {height} {unit}\\n{area} {unit}²\"\n * @example\n * ```typescript\n * formatRectangleTooltip(5.0, 3.2, 16.0, 'km');\n * // → \"5.00 km x 3.20 km\\n16.00 km²\"\n * ```\n */\nexport function formatRectangleTooltip(\n width: number,\n height: number,\n area: number,\n unitAbbrev: string,\n): string {\n return formatDimensionsTooltip(width, height, area, unitAbbrev);\n}\n\n/**\n * Format ellipse tooltip text showing axes and area.\n *\n * @param majorAxis - Ellipse major axis (full length) in the specified units\n * @param minorAxis - Ellipse minor axis (full length) in the specified units\n * @param area - Ellipse area in the specified units squared\n * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')\n * @returns Formatted tooltip text: \"{major} {unit} x {minor} {unit}\\n{area} {unit}²\"\n * @example\n * ```typescript\n * formatEllipseTooltip(10.0, 6.0, 47.12, 'km');\n * // → \"10.00 km x 6.00 km\\n47.12 km²\"\n * ```\n */\nexport function formatEllipseTooltip(\n majorAxis: number,\n minorAxis: number,\n area: number,\n unitAbbrev: string,\n): string {\n return formatDimensionsTooltip(majorAxis, minorAxis, area, unitAbbrev);\n}\n\n/**\n * Format simple distance tooltip text.\n *\n * @param distance - Distance value in the specified units\n * @param unitAbbrev - Unit abbreviation (e.g., 'km', 'mi')\n * @returns Formatted tooltip text: \"{distance} {unit}\"\n * @example\n * ```typescript\n * formatDistanceTooltip(42.5, 'km'); // → \"42.50 km\"\n * ```\n */\nexport function formatDistanceTooltip(\n distance: number,\n unitAbbrev: string,\n): string {\n return `${formatDistance(distance)} ${unitAbbrev}`;\n}\n\n// =============================================================================\n// Edit Event Type Classification\n// =============================================================================\n\n/**\n * Continuous edit event types that fire during dragging.\n * These are emitted repeatedly while the user drags during an edit operation.\n */\nexport const CONTINUOUS_EDIT_TYPES = new Set([\n 'movePosition',\n 'unionGeometry',\n 'scaling',\n 'rotating',\n 'translating',\n]);\n\n/**\n * Completion edit event types that fire when dragging ends.\n * These are emitted once when the user finishes an edit action.\n */\nexport const COMPLETION_EDIT_TYPES = new Set([\n 'finishMovePosition',\n 'addPosition',\n 'removePosition',\n 'scaled',\n 'rotated',\n 'translated',\n]);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,kBAAkB;CAC7B,SAAS;CACT,mBAAmB;CACnB,gBAAgB;CAChB,mBAAmB;CACpB;;;;;AAMD,MAAa,oBAAoB;;;;AAKjC,MAAa,qBAAqB;;;;AAKlC,MAAa,uBAAuB;;;;AAKpC,MAAa,2BAA2B;;;;;;;AAkBxC,MAAa,iBAAiB;CAE5B,MAAM;EAAC;EAAK;EAAK;EAAK;EAAI;CAE1B,MAAM;EAAC;EAAK;EAAK;EAAK;EAAI;CAE1B,WAAW;EAAC;EAAI;EAAK;EAAK;EAAI;CAC/B;;;;;;;;AASD,MAAa,2BAA2B;CAEtC,MAAM;EAAC;EAAK;EAAK;EAAK;EAAG;CAEzB,MAAM,eAAe;CACtB;;;;;;;AAQD,MAAaA,2BAA4C;CACvD,WAAW,eAAe;CAC1B,WAAW,eAAe;CAC1B,WAAW;CACX,aAAa;CACd;;;;AAKD,MAAa,cAAc;CAAC;CAAG;CAAG;CAAG;CAAE;;;;AAKvC,MAAa,gBAAgB;CAAC;CAAS;CAAU;CAAS;;;;AAK1D,MAAaC,cAA4D;CACvE,OAAO;CACP,QAAQ,CAAC,GAAG,EAAE;CACd,QAAQ,CAAC,GAAG,EAAE;CACf;;;;AAKD,MAAaC,4BAAmC;CAAC;CAAK;CAAK;CAAK;CAAI;;;;AAKpE,MAAaC,oCAA2C;CAAC;CAAG;CAAG;CAAG;CAAI;;;;AAKtE,MAAaC,2BAA8C,OAAO,OAAO;CACvE,MAAM;CACN,UAAU,OAAO,OAAO,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,cACJ;;;;;;;;;AAUF,MAAaC,wBAAkC;CAC7C;CACA;CACA,GAAG,YAAY,MAAM,GAAG;CACzB;;;;;AAMD,MAAa,yBAAyB,EACpC,UAAU;CACR,GAAG;CACH,YAAY;CACZ,cAAc;CACd,eAAe;CACf,sBAAsB;CACtB,gBAAgB,CAAC,GAAG,EAAE;CACvB,EACF;;;;;AAMD,MAAa,6BAA6B;CACxC,wBAAwB;EACtB,cAAc;EACd,WAAW;EACZ;CACD,iBAAiB;EACf,cAAc;EACd,WAAW;EACZ;CACF;;;;;AAMD,MAAa,gCAAgC;CAC3C,GAAG;CACH,GAAG;CACJ;;;;;;;;;;;;AAaD,SAAgB,eAAe,OAAuB;AACpD,QAAO,MAAM,QAAQ,EAAE;;;;;;;;;;;;;;;AAqBzB,SAAgB,oBACd,QACA,MACA,YACQ;AACR,QAAO,MAAM,eAAe,OAAO,CAAC,GAAG,WAAW,IAAI,eAAe,KAAK,CAAC,GAAG,WAAW;;;;;;;;;;;AAY3F,SAAS,wBACP,MACA,MACA,MACA,YACQ;AACR,QAAO,GAAG,eAAe,KAAK,CAAC,GAAG,WAAW,KAAK,eAAe,KAAK,CAAC,GAAG,WAAW,IAAI,eAAe,KAAK,CAAC,GAAG,WAAW;;;;;;;;;;;;;;;;AAiB9H,SAAgB,uBACd,OACA,QACA,MACA,YACQ;AACR,QAAO,wBAAwB,OAAO,QAAQ,MAAM,WAAW;;;;;;;;;;;;;;;;AAiBjE,SAAgB,qBACd,WACA,WACA,MACA,YACQ;AACR,QAAO,wBAAwB,WAAW,WAAW,MAAM,WAAW;;;;;;;;;;;;;AAcxE,SAAgB,sBACd,UACA,YACQ;AACR,QAAO,GAAG,eAAe,SAAS,CAAC,GAAG;;;;;;AAWxC,MAAa,wBAAwB,IAAI,IAAI;CAC3C;CACA;CACA;CACA;CACA;CACD,CAAC;;;;;AAMF,MAAa,wBAAwB,IAAI,IAAI;CAC3C;CACA;CACA;CACA;CACA;CACA;CACD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -26,19 +26,23 @@ declare const ShapeEvents: {
26
26
  /** Shape hovered (for cursor changes) */
27
27
  readonly hovered: "shapes:hovered";
28
28
  };
29
+ /** Union of all shape event string literals */
29
30
  type ShapeEventType = (typeof ShapeEvents)[keyof typeof ShapeEvents];
30
31
  /**
31
32
  * Event payload types (all payloads are serializable)
32
33
  */
34
+ /** Event payload emitted when a shape is selected */
33
35
  type ShapeSelectedEvent = Payload<'shapes:selected', {
34
36
  shapeId: ShapeId;
35
37
  /** Map instance ID for multi-map event isolation */
36
38
  mapId: UniqueId;
37
39
  }>;
40
+ /** Event payload emitted when a shape selection is cleared */
38
41
  type ShapeDeselectedEvent = Payload<'shapes:deselected', {
39
42
  /** Map instance ID for multi-map event isolation */
40
43
  mapId: UniqueId;
41
44
  }>;
45
+ /** Event payload emitted when a shape is hovered or hover ends */
42
46
  type ShapeHoveredEvent = Payload<'shapes:hovered', {
43
47
  /** Shape ID being hovered, or null when hover ends */
44
48
  shapeId: ShapeId | null;
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
2
+ * Copyright 2026 Hypergiant Galactic Systems Inc. All rights reserved.
3
3
  * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
4
  * you may not use this file except in compliance with the License. You may obtain a copy
5
5
  * of the License at https://www.apache.org/licenses/LICENSE-2.0
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","names":[],"sources":["../../../../src/deckgl/shapes/shared/events.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 type { Payload } from '@accelint/bus';\nimport type { UniqueId } from '@accelint/core';\nimport type { ShapeId } from './types';\n\n/**\n * Shape interaction events for DisplayShapeLayer\n */\nexport const ShapeEvents = {\n /** Shape selected */\n selected: 'shapes:selected',\n /** Selection cleared */\n deselected: 'shapes:deselected',\n /** Shape hovered (for cursor changes) */\n hovered: 'shapes:hovered',\n} as const;\n\nexport type ShapeEventType = (typeof ShapeEvents)[keyof typeof ShapeEvents];\n\n/**\n * Event payload types (all payloads are serializable)\n */\n\nexport type ShapeSelectedEvent = Payload<\n 'shapes:selected',\n {\n shapeId: ShapeId;\n /** Map instance ID for multi-map event isolation */\n mapId: UniqueId;\n }\n>;\n\nexport type ShapeDeselectedEvent = Payload<\n 'shapes:deselected',\n {\n /** Map instance ID for multi-map event isolation */\n mapId: UniqueId;\n }\n>;\n\nexport type ShapeHoveredEvent = Payload<\n 'shapes:hovered',\n {\n /** Shape ID being hovered, or null when hover ends */\n shapeId: ShapeId | null;\n /** Map instance ID for multi-map event isolation */\n mapId: UniqueId;\n }\n>;\n\n/**\n * Union of all shape event types\n */\nexport type ShapeEvent =\n | ShapeSelectedEvent\n | ShapeDeselectedEvent\n | ShapeHoveredEvent;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqBA,MAAa,cAAc;CAEzB,UAAU;CAEV,YAAY;CAEZ,SAAS;CACV"}
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../../../src/deckgl/shapes/shared/events.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 type { Payload } from '@accelint/bus';\nimport type { UniqueId } from '@accelint/core';\nimport type { ShapeId } from './types';\n\n/**\n * Shape interaction events for DisplayShapeLayer\n */\nexport const ShapeEvents = {\n /** Shape selected */\n selected: 'shapes:selected',\n /** Selection cleared */\n deselected: 'shapes:deselected',\n /** Shape hovered (for cursor changes) */\n hovered: 'shapes:hovered',\n} as const;\n\n/** Union of all shape event string literals */\nexport type ShapeEventType = (typeof ShapeEvents)[keyof typeof ShapeEvents];\n\n/**\n * Event payload types (all payloads are serializable)\n */\n\n/** Event payload emitted when a shape is selected */\nexport type ShapeSelectedEvent = Payload<\n 'shapes:selected',\n {\n shapeId: ShapeId;\n /** Map instance ID for multi-map event isolation */\n mapId: UniqueId;\n }\n>;\n\n/** Event payload emitted when a shape selection is cleared */\nexport type ShapeDeselectedEvent = Payload<\n 'shapes:deselected',\n {\n /** Map instance ID for multi-map event isolation */\n mapId: UniqueId;\n }\n>;\n\n/** Event payload emitted when a shape is hovered or hover ends */\nexport type ShapeHoveredEvent = Payload<\n 'shapes:hovered',\n {\n /** Shape ID being hovered, or null when hover ends */\n shapeId: ShapeId | null;\n /** Map instance ID for multi-map event isolation */\n mapId: UniqueId;\n }\n>;\n\n/**\n * Union of all shape event types\n */\nexport type ShapeEvent =\n | ShapeSelectedEvent\n | ShapeDeselectedEvent\n | ShapeHoveredEvent;\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqBA,MAAa,cAAc;CAEzB,UAAU;CAEV,YAAY;CAEZ,SAAS;CACV"}