Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
252 changes: 0 additions & 252 deletions examples/class/edit-control.js

This file was deleted.

112 changes: 112 additions & 0 deletions examples/class/edit-control.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import React, { Component, createRef } from 'react';
import { MapContainer, TileLayer, FeatureGroup } from 'react-leaflet';
import * as L from 'leaflet';
import { EditControl } from '../../src';

delete (L.Icon.Default.prototype as any)._getIconUrl;
L.Icon.Default.mergeOptions({
iconRetinaUrl:
'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0/images/marker-icon.png',
iconUrl:
'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0/images/marker-icon.png',
shadowUrl:
'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.0/images/marker-shadow.png',
});

export default class EditControlExample extends Component<{ onChange?: (g: any) => void }> {
featureGroupRef = createRef<L.FeatureGroup>();

_onEdited = (e: L.DrawEvents.Edited) => {
let numEdited = 0;
e.layers.eachLayer(() => {
numEdited += 1;
});
// eslint-disable-next-line no-console
console.log(`_onEdited: edited ${numEdited} layers`, e);
this._onChange();
};

_onCreated = (e: L.DrawEvents.Created) => {
const type = e.layerType;
// eslint-disable-next-line no-console
console.log('_onCreated:', type, e);
this._onChange();
};

_onDeleted = (e: L.DrawEvents.Deleted) => {
let numDeleted = 0;
e.layers.eachLayer(() => {
numDeleted += 1;
});
// eslint-disable-next-line no-console
console.log(`onDeleted: removed ${numDeleted} layers`, e);
this._onChange();
};

_onMounted = (drawControl: L.Control.Draw) => {
// eslint-disable-next-line no-console
console.log('_onMounted', drawControl);
};

_onEditStart = (e: L.DrawEvents.EditStart) => {
// eslint-disable-next-line no-console
console.log('_onEditStart', e);
};

_onEditStop = (e: L.DrawEvents.EditStop) => {
// eslint-disable-next-line no-console
console.log('_onEditStop', e);
};

_onDeleteStart = (e: L.DrawEvents.DeleteStart) => {
// eslint-disable-next-line no-console
console.log('_onDeleteStart', e);
};

_onDeleteStop = (e: L.DrawEvents.DeleteStop) => {
// eslint-disable-next-line no-console
console.log('_onDeleteStop', e);
};

render() {
const fgInstance = this.featureGroupRef.current as unknown as L.FeatureGroup | undefined;
Copy link

Copilot AI Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type assertion as unknown as L.FeatureGroup | undefined is overly broad and unsafe. Consider using a more specific type assertion or checking the actual type at runtime to ensure type safety.

Suggested change
const fgInstance = this.featureGroupRef.current as unknown as L.FeatureGroup | undefined;
const fgInstance = (this.featureGroupRef.current instanceof L.FeatureGroup)
? this.featureGroupRef.current
: undefined;

Copilot uses AI. Check for mistakes.
return (
<MapContainer center={[37.8189, -122.4786]} zoom={13} zoomControl={false}>
<TileLayer
attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
/>
<FeatureGroup ref={this.featureGroupRef as any}>
Copy link

Copilot AI Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using as any defeats the purpose of TypeScript type checking. Consider using a properly typed ref or a more specific type assertion to maintain type safety.

Suggested change
<FeatureGroup ref={this.featureGroupRef as any}>
<FeatureGroup
ref={(ref) => {
// Assign both the class ref and _editableFG for compatibility
(this.featureGroupRef as React.MutableRefObject<L.FeatureGroup | null>).current = ref;
this._editableFG = ref;
}}
>

Copilot uses AI. Check for mistakes.
{fgInstance && (fgInstance as any)._leaflet_id && (
Copy link

Copilot AI Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using (fgInstance as any)._leaflet_id to access private Leaflet properties is fragile and defeats TypeScript's type safety. Consider using a proper type guard or checking if the instance has the expected properties through a safer approach.

Suggested change
{fgInstance && (fgInstance as any)._leaflet_id && (
{fgInstance && '_leaflet_id' in fgInstance && (

Copilot uses AI. Check for mistakes.
<EditControl
position="topright"
onEdited={this._onEdited}
onCreated={this._onCreated}
onDeleted={this._onDeleted}
onMounted={this._onMounted}
onEditStart={this._onEditStart}
onEditStop={this._onEditStop}
onDeleteStart={this._onDeleteStart}
onDeleteStop={this._onDeleteStop}
draw={{
rectangle: false,
}}
featureGroup={fgInstance}
/>
)}
</FeatureGroup>
</MapContainer>
);
}

_editableFG: L.FeatureGroup | null = null;

_onChange = () => {
const { onChange } = this.props;
if (!this._editableFG || !onChange) return;
const geojsonData = (this._editableFG as any).toGeoJSON();
Copy link

Copilot AI Aug 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using as any to access the toGeoJSON() method bypasses TypeScript's type checking. Consider properly typing _editableFG or using a type assertion that maintains some level of type safety.

Suggested change
const geojsonData = (this._editableFG as any).toGeoJSON();
const geojsonData = (this._editableFG as L.FeatureGroup).toGeoJSON();

Copilot uses AI. Check for mistakes.
onChange(geojsonData);
};
}


9 changes: 5 additions & 4 deletions examples/class/index.js → examples/class/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ const example = (
</div>
);

function onChange(geojson) {
function onChange(geojson: unknown) {
// eslint-disable-next-line no-console
console.log('geojson changed', geojson);
}

createRoot(document.getElementById('app')).render(
example
);
createRoot(document.getElementById('app') as HTMLElement).render(example);


17 changes: 17 additions & 0 deletions examples/class/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "node",
"target": "ES2020",
"jsx": "react-jsx",
"strict": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true
},
"include": ["./**/*"],
"exclude": ["dist", "node_modules"]
}


Loading