geoproject-app/public/site/plugins/map-editor/index.css

2 lines
70 KiB
CSS
Raw Normal View History

refactor: comprehensive map-editor plugin refactoring (phases 1-3) This commit implements a complete refactoring of the map-editor plugin to improve code organization, reusability, and maintainability. ## Phase 1: Extraction of composables and factory functions **New composables:** - `useMarkers.js`: Centralized marker state and CRUD operations - Exports: markers, selectedMarkerId, editingMarker refs - Computed: canAddMarker, hasMarkers, selectedMarker - Methods: addMarker, updateMarker, deleteMarker, selectMarker, etc. - Includes createMarker() factory to eliminate code duplication - `useMapData.js`: Map data persistence (YAML load/save) - Exports: center, zoom refs - Methods: loadMapData, saveMapData, debouncedSave - Handles lifecycle cleanup of debounce timeouts **Benefits:** - Eliminated code duplication (2 identical marker creation blocks) - Separated business logic from UI concerns - Improved testability with pure functions - Added JSDoc documentation throughout ## Phase 2: Component extraction **New components:** - `MarkerList.vue`: Extracted sidebar UI from MapEditor.vue - Props: markers, selectedMarkerId, maxMarkers - Emits: add-marker, select-marker, edit-marker, delete-marker, select-location - Includes integrated GeocodeSearch component - Self-contained styles with scoped CSS **Benefits:** - MapEditor.vue reduced from 370 → 230 lines (-40%) - Clear separation of concerns (orchestration vs presentation) - Reusable component for potential future use - Easier to test and maintain ## Phase 3: Utils restructuring with JSDoc **New structure:** ``` utils/ ├── constants.js # NOMINATIM_API, MAP_DEFAULTS, DEBOUNCE_DELAYS ├── api/ │ └── nominatim.js # geocode() with full JSDoc typedefs └── helpers/ └── debounce.js # Generic debounce utility ``` **Removed:** - `utils/geocoding.js` (replaced by modular structure) **Benefits:** - Constants centralized for easy configuration - API layer separated from helpers - Complete JSDoc type annotations for better IDE support - Better organization following standard patterns ## Updated components **MapEditor.vue:** - Now uses useMarkers and useMapData composables - Uses MarkerList component instead of inline template - Cleaner setup function with better separation - Reduced from 537 → 256 lines (CSS moved to MarkerList) **GeocodeSearch.vue:** - Updated imports to use new utils structure - Uses DEBOUNCE_DELAYS constant instead of hardcoded value ## Build verification - ✅ npm run build successful - ✅ Bundle size unchanged (806.10 kB / 223.46 KiB gzipped) - ✅ All functionality preserved - ✅ No breaking changes ## Documentation - Added comprehensive README.md with: - Architecture overview - Composables usage examples - Component API documentation - Data flow diagrams - Development guide Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-28 16:29:15 +01:00
.maplibregl-map{-webkit-tap-highlight-color:rgb(0 0 0/0);font:12px/20px Helvetica Neue,Arial,Helvetica,sans-serif;overflow:hidden;position:relative}.maplibregl-canvas{left:0;position:absolute;top:0}.maplibregl-map:fullscreen{height:100%;width:100%}.maplibregl-ctrl-group button.maplibregl-ctrl-compass{touch-action:none}.maplibregl-canvas-container.maplibregl-interactive,.maplibregl-ctrl-group button.maplibregl-ctrl-compass{cursor:grab;-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.maplibregl-canvas-container.maplibregl-interactive.maplibregl-track-pointer{cursor:pointer}.maplibregl-canvas-container.maplibregl-interactive:active,.maplibregl-ctrl-group button.maplibregl-ctrl-compass:active{cursor:grabbing}.maplibregl-canvas-container.maplibregl-touch-zoom-rotate,.maplibregl-canvas-container.maplibregl-touch-zoom-rotate .maplibregl-canvas{touch-action:pan-x pan-y}.maplibregl-canvas-container.maplibregl-touch-drag-pan,.maplibregl-canvas-container.maplibregl-touch-drag-pan .maplibregl-canvas{touch-action:pinch-zoom}.maplibregl-canvas-container.maplibregl-touch-zoom-rotate.maplibregl-touch-drag-pan,.maplibregl-canvas-container.maplibregl-touch-zoom-rotate.maplibregl-touch-drag-pan .maplibregl-canvas{touch-action:none}.maplibregl-canvas-container.maplibregl-touch-drag-pan.maplibregl-cooperative-gestures,.maplibregl-canvas-container.maplibregl-touch-drag-pan.maplibregl-cooperative-gestures .maplibregl-canvas{touch-action:pan-x pan-y}.maplibregl-ctrl-bottom-left,.maplibregl-ctrl-bottom-right,.maplibregl-ctrl-top-left,.maplibregl-ctrl-top-right{pointer-events:none;position:absolute;z-index:2}.maplibregl-ctrl-top-left{left:0;top:0}.maplibregl-ctrl-top-right{right:0;top:0}.maplibregl-ctrl-bottom-left{bottom:0;left:0}.maplibregl-ctrl-bottom-right{bottom:0;right:0}.maplibregl-ctrl{clear:both;pointer-events:auto;transform:translate(0)}.maplibregl-ctrl-top-left .maplibregl-ctrl{float:left;margin:10px 0 0 10px}.maplibregl-ctrl-top-right .maplibregl-ctrl{float:right;margin:10px 10px 0 0}.maplibregl-ctrl-bottom-left .maplibregl-ctrl{float:left;margin:0 0 10px 10px}.maplibregl-ctrl-bottom-right .maplibregl-ctrl{float:right;margin:0 10px 10px 0}.maplibregl-ctrl-group{background:#fff;border-radius:4px}.maplibregl-ctrl-group:not(:empty){box-shadow:0 0 0 2px #0000001a}@media(-ms-high-contrast:active){.maplibregl-ctrl-group:not(:empty){box-shadow:0 0 0 2px ButtonText}}.maplibregl-ctrl-group button{background-color:transparent;border:0;box-sizing:border-box;cursor:pointer;display:block;height:29px;outline:none;padding:0;width:29px}.maplibregl-ctrl-group button+button{border-top:1px solid #ddd}.maplibregl-ctrl button .maplibregl-ctrl-icon{background-position:50%;background-repeat:no-repeat;display:block;height:100%;width:100%}@media(-ms-high-contrast:active){.maplibregl-ctrl-icon{background-color:transparent}.maplibregl-ctrl-group button+button{border-top:1px solid ButtonText}}.maplibregl-ctrl button::-moz-focus-inner{border:0;padding:0}.maplibregl-ctrl-attrib-button:focus,.maplibregl-ctrl-group button:focus{box-shadow:0 0 2px 2px #0096ff}.maplibregl-ctrl button:disabled{cursor:not-allowed}.maplibregl-ctrl button:disabled .maplibregl-ctrl-icon{opacity:.25}.maplibregl-ctrl button:not(:disabled):hover{background-color:#0000000d}.maplibregl-ctrl-group button:focus:focus-visible{box-shadow:0 0 2px 2px #0096ff}.maplibregl-ctrl-group button:focus:not(:focus-visible){box-shadow:none}.maplibregl-ctrl-group button:focus:first-child{border-radius:4px 4px 0 0}.maplibregl-ctrl-group button:focus:last-child{border-radius:0 0 4px 4px}.maplibregl-ctrl-group button:focus:only-child{border-radius:inherit}.maplibregl-ctrl button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23333' viewBox='0 0 29 29'%3E%3Cpath d='M10 13c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h9c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-9z'/%3E%3C/svg%3E")}.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon{background-image:u