@accelint/map-toolkit 0.6.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/catalog-info.yaml +7 -6
- package/dist/camera/events.js.map +1 -1
- package/dist/camera/index.d.ts +2 -2
- package/dist/camera/index.js +2 -2
- package/dist/camera/store.d.ts +120 -0
- package/dist/camera/store.js +279 -0
- package/dist/camera/store.js.map +1 -0
- package/dist/cursor-coordinates/index.d.ts +4 -2
- package/dist/cursor-coordinates/index.js +3 -2
- package/dist/cursor-coordinates/store.d.ts +48 -0
- package/dist/cursor-coordinates/store.js +92 -0
- package/dist/cursor-coordinates/store.js.map +1 -0
- package/dist/cursor-coordinates/types.d.ts +87 -0
- package/dist/cursor-coordinates/types.js +12 -0
- package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +41 -37
- package/dist/cursor-coordinates/use-cursor-coordinates.js +131 -202
- package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
- package/dist/deckgl/base-map/constants.d.ts +1 -6
- package/dist/deckgl/base-map/constants.js +1 -6
- package/dist/deckgl/base-map/constants.js.map +1 -1
- package/dist/deckgl/base-map/controls.js +2 -0
- package/dist/deckgl/base-map/controls.js.map +1 -1
- package/dist/deckgl/base-map/events.js.map +1 -1
- package/dist/deckgl/base-map/index.d.ts +2 -2
- package/dist/deckgl/base-map/index.js +10 -11
- package/dist/deckgl/base-map/index.js.map +1 -1
- package/dist/deckgl/base-map/provider.d.ts +2 -2
- package/dist/deckgl/base-map/provider.js +1 -1
- package/dist/deckgl/base-map/provider.js.map +1 -1
- package/dist/deckgl/index.d.ts +4 -4
- package/dist/deckgl/index.js +4 -4
- package/dist/deckgl/saved-viewports/index.js.map +1 -1
- package/dist/deckgl/saved-viewports/storage.js +10 -2
- package/dist/deckgl/saved-viewports/storage.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/constants.js +5 -8
- package/dist/deckgl/shapes/display-shape-layer/constants.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/fiber.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/index.d.ts +18 -14
- package/dist/deckgl/shapes/display-shape-layer/index.js +63 -30
- package/dist/deckgl/shapes/display-shape-layer/index.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js +2 -16
- package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/store.js +58 -272
- package/dist/deckgl/shapes/display-shape-layer/store.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/types.d.ts +22 -11
- package/dist/deckgl/shapes/display-shape-layer/{use-shape-selection.d.ts → use-select-shape.d.ts} +9 -9
- package/dist/deckgl/shapes/display-shape-layer/{use-shape-selection.js → use-select-shape.js} +12 -12
- package/dist/deckgl/shapes/display-shape-layer/use-select-shape.js.map +1 -0
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js +5 -66
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.js.map +1 -1
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.d.ts +2 -65
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.js +3 -121
- package/dist/deckgl/shapes/display-shape-layer/utils/labels.js.map +1 -1
- package/dist/deckgl/shapes/draw-shape-layer/constants.js +46 -0
- package/dist/deckgl/shapes/draw-shape-layer/constants.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/events.d.ts +92 -0
- package/dist/deckgl/shapes/draw-shape-layer/events.js +56 -0
- package/dist/deckgl/shapes/draw-shape-layer/events.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/fiber.d.ts +11 -0
- package/dist/{maplibre/constants.js → deckgl/shapes/draw-shape-layer/fiber.js} +6 -12
- package/dist/deckgl/shapes/draw-shape-layer/fiber.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/index.d.ts +53 -0
- package/dist/deckgl/shapes/draw-shape-layer/index.js +95 -0
- package/dist/deckgl/shapes/draw-shape-layer/index.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js +51 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-circle-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js +73 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-ellipse-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js +87 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-line-string-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js +88 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-polygon-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js +77 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/draw-rectangle-mode-with-tooltip.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/index.js +64 -0
- package/dist/deckgl/shapes/draw-shape-layer/modes/index.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/store.js +175 -0
- package/dist/deckgl/shapes/draw-shape-layer/store.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/types.d.ts +86 -0
- package/dist/{viewport/constants.js → deckgl/shapes/draw-shape-layer/types.js} +1 -12
- package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.d.ts +82 -0
- package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js +112 -0
- package/dist/deckgl/shapes/draw-shape-layer/use-draw-shape.js.map +1 -0
- package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js +147 -0
- package/dist/deckgl/shapes/draw-shape-layer/utils/feature-conversion.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/constants.js +41 -0
- package/dist/deckgl/shapes/edit-shape-layer/constants.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/events.d.ts +92 -0
- package/dist/deckgl/shapes/edit-shape-layer/events.js +56 -0
- package/dist/deckgl/shapes/edit-shape-layer/events.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/fiber.d.ts +13 -0
- package/dist/deckgl/shapes/edit-shape-layer/fiber.js +14 -0
- package/dist/deckgl/shapes/edit-shape-layer/index.d.ts +63 -0
- package/dist/deckgl/shapes/edit-shape-layer/index.js +162 -0
- package/dist/deckgl/shapes/edit-shape-layer/index.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js +154 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/base-transform-mode.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js +147 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/bounding-transform-mode.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js +87 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/circle-transform-mode.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/index.js +61 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/index.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js +109 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/rotate-mode-with-snap.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js +289 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/scale-mode-with-free-transform.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js +121 -0
- package/dist/deckgl/shapes/edit-shape-layer/modes/vertex-transform-mode.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/store.js +194 -0
- package/dist/deckgl/shapes/edit-shape-layer/store.js.map +1 -0
- package/dist/deckgl/shapes/edit-shape-layer/types.d.ts +93 -0
- package/dist/deckgl/shapes/edit-shape-layer/types.js +14 -0
- package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts +82 -0
- package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js +114 -0
- package/dist/deckgl/shapes/edit-shape-layer/use-edit-shape.js.map +1 -0
- package/dist/deckgl/shapes/index.d.ts +15 -6
- package/dist/deckgl/shapes/index.js +12 -5
- package/dist/deckgl/shapes/shared/constants.d.ts +27 -32
- package/dist/deckgl/shapes/shared/constants.js +189 -25
- package/dist/deckgl/shapes/shared/constants.js.map +1 -1
- package/dist/deckgl/shapes/shared/events.d.ts +1 -20
- package/dist/deckgl/shapes/shared/events.js +1 -31
- package/dist/deckgl/shapes/shared/events.js.map +1 -1
- package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js +84 -0
- package/dist/deckgl/shapes/shared/hooks/use-shift-zoom-disable.js.map +1 -0
- package/dist/deckgl/shapes/shared/types.d.ts +187 -28
- package/dist/deckgl/shapes/shared/types.js +55 -1
- package/dist/deckgl/shapes/shared/types.js.map +1 -1
- package/dist/deckgl/shapes/shared/utils/geometry-measurements.js +128 -0
- package/dist/deckgl/shapes/shared/utils/geometry-measurements.js.map +1 -0
- package/dist/deckgl/shapes/shared/utils/layer-config.js +50 -0
- package/dist/deckgl/shapes/shared/utils/layer-config.js.map +1 -0
- package/dist/deckgl/shapes/shared/utils/mode-utils.js +113 -0
- package/dist/deckgl/shapes/shared/utils/mode-utils.js.map +1 -0
- package/dist/deckgl/shapes/shared/utils/pick-filtering.js +57 -0
- package/dist/deckgl/shapes/shared/utils/pick-filtering.js.map +1 -0
- package/dist/deckgl/shapes/shared/utils/style-utils.d.ts +64 -0
- package/dist/deckgl/shapes/shared/utils/style-utils.js +101 -0
- package/dist/deckgl/shapes/shared/utils/style-utils.js.map +1 -0
- package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
- package/dist/deckgl/symbol-layer/index.js.map +1 -1
- package/dist/deckgl/text-layer/character-sets.js.map +1 -1
- package/dist/deckgl/text-layer/default-settings.js +4 -24
- package/dist/deckgl/text-layer/default-settings.js.map +1 -1
- package/dist/deckgl/text-layer/fiber.js.map +1 -1
- package/dist/deckgl/text-layer/index.js.map +1 -1
- package/dist/deckgl/text-settings.d.ts +77 -0
- package/dist/deckgl/text-settings.js +83 -0
- package/dist/deckgl/text-settings.js.map +1 -0
- package/dist/map-cursor/events.js.map +1 -1
- package/dist/map-cursor/index.d.ts +2 -2
- package/dist/map-cursor/index.js +2 -2
- package/dist/map-cursor/store.d.ts +32 -61
- package/dist/map-cursor/store.js +165 -294
- package/dist/map-cursor/store.js.map +1 -1
- package/dist/map-cursor/use-map-cursor.d.ts +5 -2
- package/dist/map-cursor/use-map-cursor.js +33 -15
- package/dist/map-cursor/use-map-cursor.js.map +1 -1
- package/dist/map-mode/events.js.map +1 -1
- package/dist/map-mode/index.d.ts +2 -2
- package/dist/map-mode/index.js +2 -2
- package/dist/map-mode/store.d.ts +36 -37
- package/dist/map-mode/store.js +131 -237
- package/dist/map-mode/store.js.map +1 -1
- package/dist/map-mode/use-map-mode.js +6 -5
- package/dist/map-mode/use-map-mode.js.map +1 -1
- package/dist/maplibre/hooks/use-maplibre.js.map +1 -1
- package/dist/maplibre/index.d.ts +2 -2
- package/dist/maplibre/index.js +2 -2
- package/dist/shared/constants.d.ts +19 -0
- package/dist/shared/constants.js +33 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/create-map-store.d.ts +202 -0
- package/dist/shared/create-map-store.js +223 -0
- package/dist/shared/create-map-store.js.map +1 -0
- package/dist/shared/units.d.ts +39 -0
- package/dist/shared/units.js +49 -0
- package/dist/shared/units.js.map +1 -0
- package/dist/viewport/index.d.ts +3 -3
- package/dist/viewport/index.js +3 -3
- package/dist/viewport/store.d.ts +69 -0
- package/dist/viewport/store.js +125 -0
- package/dist/viewport/store.js.map +1 -0
- package/dist/viewport/types.d.ts +2 -2
- package/dist/viewport/utils.js +2 -2
- package/dist/viewport/utils.js.map +1 -1
- package/dist/viewport/viewport-size.d.ts +2 -2
- package/dist/viewport/viewport-size.js +2 -2
- package/dist/viewport/viewport-size.js.map +1 -1
- package/package.json +39 -19
- package/dist/camera/use-camera-state.d.ts +0 -153
- package/dist/camera/use-camera-state.js +0 -418
- package/dist/camera/use-camera-state.js.map +0 -1
- package/dist/deckgl/shapes/display-shape-layer/constants.d.ts +0 -44
- package/dist/deckgl/shapes/display-shape-layer/shape-label-layer.d.ts +0 -66
- package/dist/deckgl/shapes/display-shape-layer/store.d.ts +0 -87
- package/dist/deckgl/shapes/display-shape-layer/use-shape-selection.js.map +0 -1
- package/dist/deckgl/shapes/display-shape-layer/utils/display-style.d.ts +0 -61
- package/dist/maplibre/constants.d.ts +0 -13
- package/dist/maplibre/constants.js.map +0 -1
- package/dist/viewport/constants.d.ts +0 -11
- package/dist/viewport/constants.js.map +0 -1
- package/dist/viewport/use-viewport-state.d.ts +0 -100
- package/dist/viewport/use-viewport-state.js +0 -222
- package/dist/viewport/use-viewport-state.js.map +0 -1
|
@@ -0,0 +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 * ```tsx\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 */\nfunction getEditModeForShape(shape: Shape): EditMode {\n if (isPointShape(shape)) {\n return '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"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2EA,MAAM,SAAS,UAAU;CACvB,SACE,QAAQ,IAAI,aAAa,gBAAgB,QAAQ,IAAI,aAAa;CACpE,OAAO;CACP,QAAQ;CACR,QAAQ;CACT,CAAC;;;;AAKF,MAAM,eAAe,UAAU,aAA6B;AAC5D,MAAM,cAAc,UAAU,aAA2B;;;;AAKzD,MAAMA,wBAAsC;CAC1C,cAAc;CACd,UAAU;CACV,oBAAoB;CACrB;;;;AAiBD,SAAS,oBAAoB,OAAwB;AACnD,KAAI,aAAa,MAAM,CACrB,QAAO;AAET,KAAI,cAAc,MAAM,CACtB,QAAO;AAET,KAAI,eAAe,MAAM,IAAI,iBAAiB,MAAM,CAClD,QAAO;AAET,QAAO;;;;;AAMT,SAAS,aACP,OACA,OACA,OACA,SACA,QACA,UACM;AAEN,KAAI,MAAM,QAAQ;AAChB,SAAO,KAAK,8BAA8B,MAAM,KAAK,GAAG;AACxD;;AAIF,KAAI,MAAM,aACR,uBAAsB,OAAO,OAAO,QAAQ,SAAS;CAIvD,MAAM,WAAW,SAAS,QAAQ,oBAAoB,MAAM;AAG5D,UAAS;EACP,cAAc;EACd;EACA,oBAAoB,MAAM;EAC3B,CAAC;AAGF,mBAAkB,OAAO,iBAAiB,oBAAoB;CAC9D,MAAM,SAAS,gBAAgB;AAC/B,qBAAoB,OAAO,QAAQ,oBAAoB;AAGvD,aAAY,KAAK,UAAU,YAAY,EAAE,IAAI,OAAO,CAAC;AAGrD,cAAa,KAAK,gBAAgB,SAAS;EACzC;EACA;EACD,CAA4C;AAE7C,SAAQ;;;;;AAMV,SAAS,oBACP,OACA,OACA,QACA,UACc;AACd,KAAI,EAAE,MAAM,gBAAgB,MAAM,oBAChC,QAAO;CAGT,MAAM,gBAAgB,MAAM;CAC5B,MAAM,iBAAiB,MAAM;CAG7B,MAAM,eAAe;EACnB,GAAG;EACH,SAAS;GACP,GAAG;GACH,YAAY;IACV,GAAG,cAAc,QAAQ;IACzB,GAAG,eAAe;IACnB;GACF;EACD,aAAa,KAAK,KAAK;EACxB;AAGD,UAAS;EACP,cAAc;EACd,UAAU;EACV,oBAAoB;EACrB,CAAC;AAGF,sBAAqB,OAAO,oBAAoB;AAGhD,aAAY,KAAK,UAAU,WAAW,EAAE,IAAI,OAAO,CAAC;AAGpD,cAAa,KAAK,gBAAgB,SAAS;EACzC,OAAO;EACP;EACD,CAA4C;AAE7C,SAAQ;AAER,QAAO;;;;;AAMT,SAAS,sBACP,OACA,OACA,QACA,UACM;AACN,KAAI,CAAC,MAAM,aACT;CAGF,MAAM,gBAAgB,MAAM;AAG5B,UAAS;EACP,cAAc;EACd,UAAU;EACV,oBAAoB;EACrB,CAAC;AAGF,sBAAqB,OAAO,oBAAoB;AAGhD,aAAY,KAAK,UAAU,WAAW,EAAE,IAAI,OAAO,CAAC;AAGpD,cAAa,KAAK,gBAAgB,UAAU;EAC1C,OAAO;EACP;EACD,CAAiD;AAElD,SAAQ;;;;;AAMV,MAAa,YAAY,eAA+C;CACtE,cAAc,EAAE,GAAG,uBAAuB;CAE1C,UAAU,OAAO,EAAE,KAAK,KAAK,cAAc;EACzC,OAAO,OAAc,YAA+B;AAClD,gBAAa,OAAO,KAAK,EAAE,OAAO,SAAS,QAAQ,IAAI;;EAGzD,YAAY;AACV,uBAAoB,OAAO,KAAK,EAAE,QAAQ,IAAI;;EAGhD,cAAc;AACZ,yBAAsB,OAAO,KAAK,EAAE,QAAQ,IAAI;;EAEnD;CAMD,YAAY,OAAO,UAAU;AAE3B,MAAI,MAAM,cAAc;AAEtB,wBAAqB,OAAO,oBAAoB;AAGhD,eAAY,KAAK,UAAU,WAAW,EAAE,IAAI,OAAO,CAAC;AAGpD,gBAAa,KAAK,gBAAgB,UAAU;IAC1C,OAAO,MAAM;IACb;IACD,CAAiD;;;CAGvD,CAAC;;;;AAoCF,SAAgB,uBACd,OACA,SACM;AACN,WAAU,IAAI,OAAO,EAAE,oBAAoB,SAAS,CAAC;;;;;AAMvD,SAAgB,uBAAuB,OAAuB;AAC5D,WAAU,QAAQ,MAAM,CAAC,QAAQ"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { DistanceUnitAbbreviation } from "../../../shared/units.js";
|
|
14
|
+
import { Shape } from "../shared/types.js";
|
|
15
|
+
import { UniqueId } from "@accelint/core";
|
|
16
|
+
import { Feature } from "geojson";
|
|
17
|
+
|
|
18
|
+
//#region src/deckgl/shapes/edit-shape-layer/types.d.ts
|
|
19
|
+
/**
|
|
20
|
+
* Edit mode for shape editing
|
|
21
|
+
* - 'view': Not editing, shape is viewable only
|
|
22
|
+
* - 'bounding-transform': Scale/rotate/translate via bounding box handles (ellipses, rectangles)
|
|
23
|
+
* - 'vertex-transform': Drag vertices OR scale/rotate/translate (polygons, lines)
|
|
24
|
+
* - 'circle-transform': Drag edge to resize, drag body to translate (circles)
|
|
25
|
+
* - 'translate': Drag to move the shape (points)
|
|
26
|
+
*/
|
|
27
|
+
type EditMode = 'view' | 'bounding-transform' | 'vertex-transform' | 'circle-transform' | 'translate';
|
|
28
|
+
/**
|
|
29
|
+
* State for the editing store
|
|
30
|
+
*/
|
|
31
|
+
type EditingState = {
|
|
32
|
+
/** Shape currently being edited */
|
|
33
|
+
editingShape: Shape | null;
|
|
34
|
+
/** Current edit mode */
|
|
35
|
+
editMode: EditMode;
|
|
36
|
+
/** Live feature being edited (updates in real-time during drag) */
|
|
37
|
+
featureBeingEdited: Feature | null;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Options for starting an edit operation
|
|
41
|
+
*/
|
|
42
|
+
type EditShapeOptions = {
|
|
43
|
+
/** Override the default edit mode (auto-detected from shape type by default) */
|
|
44
|
+
mode?: 'bounding-transform' | 'vertex-transform' | 'circle-transform' | 'translate';
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Options for the useEditShape hook
|
|
48
|
+
*/
|
|
49
|
+
type UseEditShapeOptions = {
|
|
50
|
+
/** Callback when a shape edit is saved */
|
|
51
|
+
onUpdate?: (shape: Shape) => void;
|
|
52
|
+
/** Callback when editing is canceled */
|
|
53
|
+
onCancel?: (shape: Shape) => void;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Return type for the useEditShape hook
|
|
57
|
+
*/
|
|
58
|
+
type UseEditShapeReturn = {
|
|
59
|
+
/** Current editing state (null when not editing) */
|
|
60
|
+
editingState: EditingState | null;
|
|
61
|
+
/** Start editing a shape with optional mode override */
|
|
62
|
+
edit: (shape: Shape, options?: EditShapeOptions) => void;
|
|
63
|
+
/** Save the current edits and emit updated event */
|
|
64
|
+
save: () => void;
|
|
65
|
+
/** Cancel editing and revert to original shape */
|
|
66
|
+
cancel: () => void;
|
|
67
|
+
/** Whether currently in editing mode */
|
|
68
|
+
isEditing: boolean;
|
|
69
|
+
/** The shape currently being edited (null if not editing) */
|
|
70
|
+
editingShape: Shape | null;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Props for the EditShapeLayer component
|
|
74
|
+
*/
|
|
75
|
+
type EditShapeLayerProps = {
|
|
76
|
+
/** Layer ID (defaults to 'edit-shape-layer') */
|
|
77
|
+
id?: string;
|
|
78
|
+
/**
|
|
79
|
+
* Map instance ID for multi-map isolation.
|
|
80
|
+
* Optional when used inside a MapProvider (uses context).
|
|
81
|
+
* Required when used outside a MapProvider.
|
|
82
|
+
*/
|
|
83
|
+
mapId?: UniqueId;
|
|
84
|
+
/** Distance unit for tooltip measurements (defaults to 'km') */
|
|
85
|
+
unit?: DistanceUnitAbbreviation;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Function type for the edit action
|
|
89
|
+
*/
|
|
90
|
+
type EditFunction = (shape: Shape, options?: EditShapeOptions) => void;
|
|
91
|
+
//#endregion
|
|
92
|
+
export { EditFunction, EditMode, EditShapeLayerProps, EditShapeOptions, EditingState, UseEditShapeOptions, UseEditShapeReturn };
|
|
93
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
'use client';
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { UseEditShapeOptions, UseEditShapeReturn } from "./types.js";
|
|
14
|
+
import { UniqueId } from "@accelint/core";
|
|
15
|
+
|
|
16
|
+
//#region src/deckgl/shapes/edit-shape-layer/use-edit-shape.d.ts
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Hook to access the shape editing state and actions.
|
|
20
|
+
*
|
|
21
|
+
* This hook uses `useSyncExternalStore` to subscribe to editing state changes,
|
|
22
|
+
* providing concurrent-safe state updates. Uses a fan-out pattern where
|
|
23
|
+
* a single bus listener per map instance notifies N React component subscribers.
|
|
24
|
+
*
|
|
25
|
+
* @param mapId - Optional map instance ID. If not provided, will use the ID from `MapContext`.
|
|
26
|
+
* @param options - Optional callbacks for onUpdate and onCancel events
|
|
27
|
+
* @returns Editing state, edit/save/cancel functions, and convenience flags
|
|
28
|
+
* @throws Error if no `mapId` is provided and hook is used outside of `MapProvider`
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* // Inside MapProvider (within BaseMap children) - uses context
|
|
33
|
+
* function ShapeEditor() {
|
|
34
|
+
* const { edit, save, cancel, isEditing, editingShape } = useEditShape(undefined, {
|
|
35
|
+
* onUpdate: (shape) => {
|
|
36
|
+
* console.log('Shape updated:', shape);
|
|
37
|
+
* setShapes(prev => prev.map(s => s.id === shape.id ? shape : s));
|
|
38
|
+
* },
|
|
39
|
+
* onCancel: (shape) => {
|
|
40
|
+
* console.log('Editing canceled:', shape.name);
|
|
41
|
+
* },
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* return (
|
|
45
|
+
* <div>
|
|
46
|
+
* {selectedShape && !isEditing && (
|
|
47
|
+
* <button onClick={() => edit(selectedShape)}>
|
|
48
|
+
* Edit Shape
|
|
49
|
+
* </button>
|
|
50
|
+
* )}
|
|
51
|
+
* {isEditing && (
|
|
52
|
+
* <>
|
|
53
|
+
* <button onClick={save}>Save</button>
|
|
54
|
+
* <button onClick={cancel}>Cancel</button>
|
|
55
|
+
* </>
|
|
56
|
+
* )}
|
|
57
|
+
* </div>
|
|
58
|
+
* );
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```tsx
|
|
64
|
+
* // Outside MapProvider - pass mapId directly
|
|
65
|
+
* function ExternalEditControl({ mapId, shape }: { mapId: UniqueId; shape: Shape }) {
|
|
66
|
+
* const { edit, isEditing } = useEditShape(mapId);
|
|
67
|
+
*
|
|
68
|
+
* return (
|
|
69
|
+
* <button
|
|
70
|
+
* onClick={() => edit(shape)}
|
|
71
|
+
* disabled={isEditing}
|
|
72
|
+
* >
|
|
73
|
+
* Edit
|
|
74
|
+
* </button>
|
|
75
|
+
* );
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
declare function useEditShape(mapId?: UniqueId, options?: UseEditShapeOptions): UseEditShapeReturn;
|
|
80
|
+
//#endregion
|
|
81
|
+
export { useEditShape };
|
|
82
|
+
//# sourceMappingURL=use-edit-shape.d.ts.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
|
|
3
|
+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License. You may obtain a copy
|
|
5
|
+
* of the License at https://www.apache.org/licenses/LICENSE-2.0
|
|
6
|
+
*
|
|
7
|
+
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
8
|
+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
|
9
|
+
* OF ANY KIND, either express or implied. See the License for the specific language
|
|
10
|
+
* governing permissions and limitations under the License.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
'use client';
|
|
15
|
+
|
|
16
|
+
import { MapContext } from "../../base-map/provider.js";
|
|
17
|
+
import { EditShapeEvents } from "./events.js";
|
|
18
|
+
import { editStore } from "./store.js";
|
|
19
|
+
import { useContext, useMemo } from "react";
|
|
20
|
+
import { useBus } from "@accelint/bus/react";
|
|
21
|
+
|
|
22
|
+
//#region src/deckgl/shapes/edit-shape-layer/use-edit-shape.ts
|
|
23
|
+
/**
|
|
24
|
+
* Hook to access the shape editing state and actions.
|
|
25
|
+
*
|
|
26
|
+
* This hook uses `useSyncExternalStore` to subscribe to editing state changes,
|
|
27
|
+
* providing concurrent-safe state updates. Uses a fan-out pattern where
|
|
28
|
+
* a single bus listener per map instance notifies N React component subscribers.
|
|
29
|
+
*
|
|
30
|
+
* @param mapId - Optional map instance ID. If not provided, will use the ID from `MapContext`.
|
|
31
|
+
* @param options - Optional callbacks for onUpdate and onCancel events
|
|
32
|
+
* @returns Editing state, edit/save/cancel functions, and convenience flags
|
|
33
|
+
* @throws Error if no `mapId` is provided and hook is used outside of `MapProvider`
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```tsx
|
|
37
|
+
* // Inside MapProvider (within BaseMap children) - uses context
|
|
38
|
+
* function ShapeEditor() {
|
|
39
|
+
* const { edit, save, cancel, isEditing, editingShape } = useEditShape(undefined, {
|
|
40
|
+
* onUpdate: (shape) => {
|
|
41
|
+
* console.log('Shape updated:', shape);
|
|
42
|
+
* setShapes(prev => prev.map(s => s.id === shape.id ? shape : s));
|
|
43
|
+
* },
|
|
44
|
+
* onCancel: (shape) => {
|
|
45
|
+
* console.log('Editing canceled:', shape.name);
|
|
46
|
+
* },
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* return (
|
|
50
|
+
* <div>
|
|
51
|
+
* {selectedShape && !isEditing && (
|
|
52
|
+
* <button onClick={() => edit(selectedShape)}>
|
|
53
|
+
* Edit Shape
|
|
54
|
+
* </button>
|
|
55
|
+
* )}
|
|
56
|
+
* {isEditing && (
|
|
57
|
+
* <>
|
|
58
|
+
* <button onClick={save}>Save</button>
|
|
59
|
+
* <button onClick={cancel}>Cancel</button>
|
|
60
|
+
* </>
|
|
61
|
+
* )}
|
|
62
|
+
* </div>
|
|
63
|
+
* );
|
|
64
|
+
* }
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* // Outside MapProvider - pass mapId directly
|
|
70
|
+
* function ExternalEditControl({ mapId, shape }: { mapId: UniqueId; shape: Shape }) {
|
|
71
|
+
* const { edit, isEditing } = useEditShape(mapId);
|
|
72
|
+
*
|
|
73
|
+
* return (
|
|
74
|
+
* <button
|
|
75
|
+
* onClick={() => edit(shape)}
|
|
76
|
+
* disabled={isEditing}
|
|
77
|
+
* >
|
|
78
|
+
* Edit
|
|
79
|
+
* </button>
|
|
80
|
+
* );
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
function useEditShape(mapId, options) {
|
|
85
|
+
const contextId = useContext(MapContext);
|
|
86
|
+
const actualId = mapId ?? contextId;
|
|
87
|
+
if (!actualId) throw new Error("useEditShape requires either a mapId parameter or to be used within a MapProvider");
|
|
88
|
+
const { onUpdate, onCancel } = options ?? {};
|
|
89
|
+
const { state: editingState, edit, save, cancel } = editStore.use(actualId);
|
|
90
|
+
const { useOn: useOn$1 } = useBus();
|
|
91
|
+
useOn$1(EditShapeEvents.updated, (event) => {
|
|
92
|
+
if (event.payload.mapId === actualId && onUpdate) onUpdate(event.payload.shape);
|
|
93
|
+
});
|
|
94
|
+
useOn$1(EditShapeEvents.canceled, (event) => {
|
|
95
|
+
if (event.payload.mapId === actualId && onCancel) onCancel(event.payload.shape);
|
|
96
|
+
});
|
|
97
|
+
return useMemo(() => ({
|
|
98
|
+
editingState,
|
|
99
|
+
edit,
|
|
100
|
+
save,
|
|
101
|
+
cancel,
|
|
102
|
+
isEditing: !!editingState?.editingShape,
|
|
103
|
+
editingShape: editingState?.editingShape ?? null
|
|
104
|
+
}), [
|
|
105
|
+
editingState,
|
|
106
|
+
edit,
|
|
107
|
+
save,
|
|
108
|
+
cancel
|
|
109
|
+
]);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//#endregion
|
|
113
|
+
export { useEditShape };
|
|
114
|
+
//# sourceMappingURL=use-edit-shape.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -10,11 +10,20 @@
|
|
|
10
10
|
* governing permissions and limitations under the License.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import { CircleProperties, CircleRadius,
|
|
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";
|
|
14
14
|
import { CardinalLabelCoordinateAnchor, LabelHorizontalPosition, LabelPosition2d, LabelPositionOptions, LabelVerticalPosition } from "./display-shape-layer/utils/labels.js";
|
|
15
|
-
import { DisplayShapeLayerProps, StyledFeature, StyledFeatureProperties } from "./display-shape-layer/types.js";
|
|
15
|
+
import { DisplayShapeLayerProps, ShowLabelsMode, StyledFeature, StyledFeatureProperties } from "./display-shape-layer/types.js";
|
|
16
16
|
import { DisplayShapeLayer } from "./display-shape-layer/index.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
|
|
17
|
+
import { UseSelectShapeReturn, useSelectShape } from "./display-shape-layer/use-select-shape.js";
|
|
18
|
+
import { DrawShapeEvent, DrawShapeEventType, DrawShapeEvents, ShapeDrawCanceledEvent, ShapeDrawingEvent, ShapeDrawnEvent } from "./draw-shape-layer/events.js";
|
|
19
|
+
import { DrawShapeLayerProps, DrawShapeOptions, DrawingState, UseDrawShapeOptions, UseDrawShapeReturn } from "./draw-shape-layer/types.js";
|
|
20
|
+
import { DrawShapeLayer } from "./draw-shape-layer/index.js";
|
|
21
|
+
import { useDrawShape } from "./draw-shape-layer/use-draw-shape.js";
|
|
22
|
+
import { EditShapeEvent, EditShapeEventType, EditShapeEvents, ShapeEditCanceledEvent, ShapeEditingEvent, ShapeUpdatedEvent } from "./edit-shape-layer/events.js";
|
|
23
|
+
import { EditMode, EditShapeLayerProps, EditShapeOptions, EditingState, UseEditShapeOptions, UseEditShapeReturn } from "./edit-shape-layer/types.js";
|
|
24
|
+
import { EditShapeLayer } from "./edit-shape-layer/index.js";
|
|
25
|
+
import { useEditShape } from "./edit-shape-layer/use-edit-shape.js";
|
|
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
|
+
import { ShapeEventType, ShapeEvents } from "./shared/events.js";
|
|
28
|
+
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 };
|
|
@@ -11,10 +11,17 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
import { BASE_FILL_OPACITY, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STYLE_PROPERTIES,
|
|
15
|
-
import {
|
|
14
|
+
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";
|
|
15
|
+
import { ShapeEvents } from "./shared/events.js";
|
|
16
|
+
import { getDashArray, getFillColor, getLineColor, getLineWidth, normalizeColor } from "./shared/utils/style-utils.js";
|
|
17
|
+
import { ShapeFeatureType, isCircleShape, isEllipseShape, isLineStringShape, isPointShape, isPolygonShape, isRectangleShape } from "./shared/types.js";
|
|
16
18
|
import { DisplayShapeLayer } from "./display-shape-layer/index.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
+
import { useSelectShape } from "./display-shape-layer/use-select-shape.js";
|
|
20
|
+
import { DrawShapeEvents } from "./draw-shape-layer/events.js";
|
|
21
|
+
import { DrawShapeLayer } from "./draw-shape-layer/index.js";
|
|
22
|
+
import { useDrawShape } from "./draw-shape-layer/use-draw-shape.js";
|
|
23
|
+
import { EditShapeEvents } from "./edit-shape-layer/events.js";
|
|
24
|
+
import { EditShapeLayer } from "./edit-shape-layer/index.js";
|
|
25
|
+
import { useEditShape } from "./edit-shape-layer/use-edit-shape.js";
|
|
19
26
|
|
|
20
|
-
export { BASE_FILL_OPACITY, DASH_ARRAYS, DEFAULT_COLORS, DEFAULT_STYLE_PROPERTIES, DisplayShapeLayer,
|
|
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 };
|
|
@@ -23,56 +23,51 @@ declare const SHAPE_LAYER_IDS: {
|
|
|
23
23
|
readonly DISPLAY_LABELS: "DISPLAY_SHAPES::Labels";
|
|
24
24
|
};
|
|
25
25
|
/**
|
|
26
|
-
* Base fill opacity multiplier
|
|
26
|
+
* Base fill opacity multiplier for standard semi-transparent look.
|
|
27
|
+
* Multiplies alpha by 0.2 (reduces to 20% of original opacity).
|
|
27
28
|
*/
|
|
28
29
|
declare const BASE_FILL_OPACITY = 0.2;
|
|
29
30
|
/**
|
|
30
|
-
* Default
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* Additional pixels added to stroke width on hover
|
|
35
|
-
*/
|
|
36
|
-
declare const HOVER_WIDTH_INCREASE = 2;
|
|
37
|
-
/**
|
|
38
|
-
* Additional pixels added to stroke width for selection highlight
|
|
39
|
-
*/
|
|
40
|
-
declare const HIGHLIGHT_WIDTH_INCREASE = 5;
|
|
41
|
-
/**
|
|
42
|
-
* Fixed opacity for label background (0-255)
|
|
43
|
-
*/
|
|
44
|
-
declare const LABEL_BACKGROUND_OPACITY = 200;
|
|
45
|
-
/**
|
|
46
|
-
* Fixed opacity for label border (0-255)
|
|
47
|
-
*/
|
|
48
|
-
declare const LABEL_BORDER_OPACITY = 255;
|
|
49
|
-
/**
|
|
50
|
-
* Default colors as RGBA arrays for DeckGL layers
|
|
31
|
+
* Default colors as RGBA arrays for DeckGL layers.
|
|
32
|
+
*
|
|
33
|
+
* These are the canonical color values used throughout the shapes system.
|
|
34
|
+
* All other color constants should derive from these to maintain consistency.
|
|
51
35
|
*/
|
|
52
36
|
declare const DEFAULT_COLORS: {
|
|
53
|
-
/** Default fill color (
|
|
37
|
+
/** Default fill color (white at full alpha) */
|
|
54
38
|
readonly fill: Color;
|
|
55
|
-
/** Default
|
|
56
|
-
readonly
|
|
39
|
+
/** Default border/outline color (outline-interactive-hover: #888a8f) */
|
|
40
|
+
readonly line: Color;
|
|
57
41
|
/** Highlight/selection color (turquoise at ~39% alpha) */
|
|
58
42
|
readonly highlight: Color;
|
|
59
43
|
};
|
|
60
44
|
/**
|
|
61
|
-
* Default style properties for
|
|
45
|
+
* Default style properties for saved shapes.
|
|
46
|
+
*
|
|
47
|
+
* These are applied when a shape is completed/saved.
|
|
48
|
+
* Can be overridden via styleDefaults in draw options.
|
|
62
49
|
*/
|
|
63
50
|
declare const DEFAULT_STYLE_PROPERTIES: StyleProperties;
|
|
64
51
|
/**
|
|
65
|
-
*
|
|
52
|
+
* Border/outline width options (in pixels)
|
|
66
53
|
*/
|
|
67
|
-
declare const
|
|
54
|
+
declare const LINE_WIDTHS: readonly [1, 2, 4, 8];
|
|
68
55
|
/**
|
|
69
|
-
*
|
|
56
|
+
* Border/outline pattern options
|
|
70
57
|
*/
|
|
71
|
-
declare const
|
|
58
|
+
declare const LINE_PATTERNS: readonly ["solid", "dashed", "dotted"];
|
|
72
59
|
/**
|
|
73
|
-
* Dash array patterns for
|
|
60
|
+
* Dash array patterns for border/outline rendering
|
|
74
61
|
*/
|
|
75
62
|
declare const DASH_ARRAYS: Record<'solid' | 'dashed' | 'dotted', [number, number] | null>;
|
|
63
|
+
/**
|
|
64
|
+
* Default edit handle color (white) - used by both draw and edit layers
|
|
65
|
+
*/
|
|
66
|
+
declare const DEFAULT_EDIT_HANDLE_COLOR: Color;
|
|
67
|
+
/**
|
|
68
|
+
* Edit handle outline color (dark for contrast)
|
|
69
|
+
*/
|
|
70
|
+
declare const DEFAULT_EDIT_HANDLE_OUTLINE_COLOR: Color;
|
|
76
71
|
//#endregion
|
|
77
|
-
export { BASE_FILL_OPACITY, DASH_ARRAYS, DEFAULT_COLORS,
|
|
72
|
+
export { 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 };
|
|
78
73
|
//# sourceMappingURL=constants.d.ts.map
|