leaflet-anvil 0.2.2 → 0.2.3
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/README.md +25 -0
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +36 -23
- package/dist/index.mjs +36 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,6 +94,7 @@ Activation via `anvil.enable(AnvilMode.Name)` or through the UI toolbar:
|
|
|
94
94
|
| `modeStyles` | `object` | `{}` | Per-mode style overrides for drawing, handles and active selection/highlight states. |
|
|
95
95
|
| `controlPosition` | `string` | `'topleft'` | Determines the position of the toolbar on the map (e.g., `'topright'`). |
|
|
96
96
|
| `modes` | `Array` | `All` | Defines which buttons appear in the toolbar. Supports nested arrays for button groups (blocks). |
|
|
97
|
+
| `modeTooltips` | `object \\| function` | `Defaults` | Overrides toolbar button tooltips. Missing values keep the built-in defaults. Use a function if translations can change after initialization. |
|
|
97
98
|
|
|
98
99
|
### Mode-Specific Styles
|
|
99
100
|
|
|
@@ -170,6 +171,30 @@ const anvil = new Anvil(map, {
|
|
|
170
171
|
If you want to style the active highlight of interaction modes, use `selectionPathOptions`.
|
|
171
172
|
That is what controls the temporary emphasis color when a geometry is selected in modes such as `Edit` or while actively transforming it in `Drag`, `Scale`, `Rotate`, `Union` or `Subtract`.
|
|
172
173
|
|
|
174
|
+
### Custom Toolbar Tooltips
|
|
175
|
+
|
|
176
|
+
For simple overrides, pass a static map:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
const anvil = new Anvil(map, {
|
|
180
|
+
modeTooltips: {
|
|
181
|
+
[AnvilMode.Edit]: 'Edit geometry',
|
|
182
|
+
[AnvilMode.Delete]: 'Remove geometry',
|
|
183
|
+
[AnvilMode.Off]: 'Disable tools',
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
If your app language can change after `Anvil` has been created, pass a resolver instead.
|
|
189
|
+
The toolbar re-reads the tooltip when a button is focused or hovered, so the next interaction uses the current language without recreating the control.
|
|
190
|
+
The second argument is the built-in default tooltip, so you can preserve defaults without duplicating them.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
const anvil = new Anvil(map, {
|
|
194
|
+
modeTooltips: (mode, fallback) => i18n.t(`mapTools.${mode}`, fallback),
|
|
195
|
+
});
|
|
196
|
+
```
|
|
197
|
+
|
|
173
198
|
### Events (`ANVIL_EVENTS`)
|
|
174
199
|
|
|
175
200
|
All events are fired on the Leaflet map:
|
package/dist/index.d.mts
CHANGED
|
@@ -25,6 +25,8 @@ interface Mode {
|
|
|
25
25
|
enable(): void;
|
|
26
26
|
disable(): void;
|
|
27
27
|
}
|
|
28
|
+
type AnvilModeTooltips = Partial<Record<AnvilMode, string>>;
|
|
29
|
+
type AnvilModeTooltipResolver = (mode: AnvilMode, defaultTooltip: string) => string | null | undefined;
|
|
28
30
|
interface AnvilOptions {
|
|
29
31
|
layerGroup?: L.FeatureGroup;
|
|
30
32
|
snapping?: boolean;
|
|
@@ -38,6 +40,7 @@ interface AnvilOptions {
|
|
|
38
40
|
modeStyles?: AnvilModeStyles;
|
|
39
41
|
controlPosition?: L.ControlPosition;
|
|
40
42
|
modes?: (AnvilMode | AnvilMode[])[];
|
|
43
|
+
modeTooltips?: AnvilModeTooltips | AnvilModeTooltipResolver;
|
|
41
44
|
}
|
|
42
45
|
interface AnvilModeStyleOptions {
|
|
43
46
|
pathOptions?: L.PathOptions;
|
|
@@ -72,6 +75,7 @@ declare const ANVIL_EVENTS: {
|
|
|
72
75
|
interface AnvilControlOptions extends L.ControlOptions {
|
|
73
76
|
position?: L.ControlPosition;
|
|
74
77
|
modes?: (AnvilMode | AnvilMode[])[];
|
|
78
|
+
modeTooltips?: AnvilModeTooltips | AnvilModeTooltipResolver;
|
|
75
79
|
}
|
|
76
80
|
declare class AnvilControl extends L.Control {
|
|
77
81
|
private _btns;
|
|
@@ -82,4 +86,4 @@ declare class AnvilControl extends L.Control {
|
|
|
82
86
|
}
|
|
83
87
|
declare function anvilControl(anvil: Anvil, options?: AnvilControlOptions): AnvilControl;
|
|
84
88
|
|
|
85
|
-
export { ANVIL_EVENTS, Anvil, AnvilControl, type AnvilControlOptions, AnvilMode, type AnvilModeStyleOptions, type AnvilModeStyles, type AnvilOptions, type Mode, anvilControl };
|
|
89
|
+
export { ANVIL_EVENTS, Anvil, AnvilControl, type AnvilControlOptions, AnvilMode, type AnvilModeStyleOptions, type AnvilModeStyles, type AnvilModeTooltipResolver, type AnvilModeTooltips, type AnvilOptions, type Mode, anvilControl };
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ interface Mode {
|
|
|
25
25
|
enable(): void;
|
|
26
26
|
disable(): void;
|
|
27
27
|
}
|
|
28
|
+
type AnvilModeTooltips = Partial<Record<AnvilMode, string>>;
|
|
29
|
+
type AnvilModeTooltipResolver = (mode: AnvilMode, defaultTooltip: string) => string | null | undefined;
|
|
28
30
|
interface AnvilOptions {
|
|
29
31
|
layerGroup?: L.FeatureGroup;
|
|
30
32
|
snapping?: boolean;
|
|
@@ -38,6 +40,7 @@ interface AnvilOptions {
|
|
|
38
40
|
modeStyles?: AnvilModeStyles;
|
|
39
41
|
controlPosition?: L.ControlPosition;
|
|
40
42
|
modes?: (AnvilMode | AnvilMode[])[];
|
|
43
|
+
modeTooltips?: AnvilModeTooltips | AnvilModeTooltipResolver;
|
|
41
44
|
}
|
|
42
45
|
interface AnvilModeStyleOptions {
|
|
43
46
|
pathOptions?: L.PathOptions;
|
|
@@ -72,6 +75,7 @@ declare const ANVIL_EVENTS: {
|
|
|
72
75
|
interface AnvilControlOptions extends L.ControlOptions {
|
|
73
76
|
position?: L.ControlPosition;
|
|
74
77
|
modes?: (AnvilMode | AnvilMode[])[];
|
|
78
|
+
modeTooltips?: AnvilModeTooltips | AnvilModeTooltipResolver;
|
|
75
79
|
}
|
|
76
80
|
declare class AnvilControl extends L.Control {
|
|
77
81
|
private _btns;
|
|
@@ -82,4 +86,4 @@ declare class AnvilControl extends L.Control {
|
|
|
82
86
|
}
|
|
83
87
|
declare function anvilControl(anvil: Anvil, options?: AnvilControlOptions): AnvilControl;
|
|
84
88
|
|
|
85
|
-
export { ANVIL_EVENTS, Anvil, AnvilControl, type AnvilControlOptions, AnvilMode, type AnvilModeStyleOptions, type AnvilModeStyles, type AnvilOptions, type Mode, anvilControl };
|
|
89
|
+
export { ANVIL_EVENTS, Anvil, AnvilControl, type AnvilControlOptions, AnvilMode, type AnvilModeStyleOptions, type AnvilModeStyles, type AnvilModeTooltipResolver, type AnvilModeTooltips, type AnvilOptions, type Mode, anvilControl };
|
package/dist/index.js
CHANGED
|
@@ -2216,25 +2216,26 @@ var L21 = __toESM(require("leaflet"));
|
|
|
2216
2216
|
var import_lucide = require("lucide");
|
|
2217
2217
|
var ANVIL_TOOLBAR_STYLE_ID = "anvil-toolbar-styles";
|
|
2218
2218
|
var MODE_CONFIGS = [
|
|
2219
|
-
{ id: "marker" /* Marker */,
|
|
2220
|
-
{ id: "polyline" /* Polyline */,
|
|
2221
|
-
{ id: "polygon" /* Polygon */,
|
|
2222
|
-
{ id: "rectangle" /* Rectangle */,
|
|
2223
|
-
{ id: "square" /* Square */,
|
|
2224
|
-
{ id: "triangle" /* Triangle */,
|
|
2225
|
-
{ id: "circle" /* Circle */,
|
|
2226
|
-
{ id: "freehand" /* Freehand */,
|
|
2227
|
-
{ id: "cut" /* Cut */,
|
|
2228
|
-
{ id: "split" /* Split */,
|
|
2229
|
-
{ id: "union" /* Union */,
|
|
2230
|
-
{ id: "subtract" /* Subtract */,
|
|
2231
|
-
{ id: "drag" /* Drag */,
|
|
2232
|
-
{ id: "scale" /* Scale */,
|
|
2233
|
-
{ id: "rotate" /* Rotate */,
|
|
2234
|
-
{ id: "edit" /* Edit */,
|
|
2235
|
-
{ id: "delete" /* Delete */,
|
|
2236
|
-
{ id: "off" /* Off */,
|
|
2219
|
+
{ id: "marker" /* Marker */, defaultTooltip: "Marker", icon: import_lucide.MapPin },
|
|
2220
|
+
{ id: "polyline" /* Polyline */, defaultTooltip: "Line", icon: import_lucide.Waypoints },
|
|
2221
|
+
{ id: "polygon" /* Polygon */, defaultTooltip: "Polygon", icon: import_lucide.Pentagon },
|
|
2222
|
+
{ id: "rectangle" /* Rectangle */, defaultTooltip: "Rectangle", icon: import_lucide.RectangleHorizontal },
|
|
2223
|
+
{ id: "square" /* Square */, defaultTooltip: "Square", icon: import_lucide.Square },
|
|
2224
|
+
{ id: "triangle" /* Triangle */, defaultTooltip: "Triangle", icon: import_lucide.Triangle },
|
|
2225
|
+
{ id: "circle" /* Circle */, defaultTooltip: "Circle", icon: import_lucide.Circle },
|
|
2226
|
+
{ id: "freehand" /* Freehand */, defaultTooltip: "Freehand", icon: import_lucide.Hand },
|
|
2227
|
+
{ id: "cut" /* Cut */, defaultTooltip: "Cut", icon: import_lucide.Scissors },
|
|
2228
|
+
{ id: "split" /* Split */, defaultTooltip: "Split", icon: import_lucide.Split },
|
|
2229
|
+
{ id: "union" /* Union */, defaultTooltip: "Union", icon: import_lucide.SquaresUnite },
|
|
2230
|
+
{ id: "subtract" /* Subtract */, defaultTooltip: "Subtract", icon: import_lucide.SquaresSubtract },
|
|
2231
|
+
{ id: "drag" /* Drag */, defaultTooltip: "Drag", icon: import_lucide.Move },
|
|
2232
|
+
{ id: "scale" /* Scale */, defaultTooltip: "Scale", icon: import_lucide.Scaling },
|
|
2233
|
+
{ id: "rotate" /* Rotate */, defaultTooltip: "Rotate", icon: import_lucide.RotateCw },
|
|
2234
|
+
{ id: "edit" /* Edit */, defaultTooltip: "Edit", icon: import_lucide.SquarePen },
|
|
2235
|
+
{ id: "delete" /* Delete */, defaultTooltip: "Delete", icon: import_lucide.Trash2 },
|
|
2236
|
+
{ id: "off" /* Off */, defaultTooltip: "Turn Off", icon: import_lucide.Power }
|
|
2237
2237
|
];
|
|
2238
|
+
var MODE_CONFIGS_BY_ID = new Map(MODE_CONFIGS.map((config) => [config.id, config]));
|
|
2238
2239
|
function ensureToolbarStyles() {
|
|
2239
2240
|
if (typeof document === "undefined" || document.getElementById(ANVIL_TOOLBAR_STYLE_ID)) return;
|
|
2240
2241
|
const style = document.createElement("style");
|
|
@@ -2304,6 +2305,12 @@ function buildIcon(iconNode) {
|
|
|
2304
2305
|
focusable: "false"
|
|
2305
2306
|
});
|
|
2306
2307
|
}
|
|
2308
|
+
function resolveModeTooltip(config, modeTooltips) {
|
|
2309
|
+
if (typeof modeTooltips === "function") {
|
|
2310
|
+
return modeTooltips(config.id, config.defaultTooltip) ?? config.defaultTooltip;
|
|
2311
|
+
}
|
|
2312
|
+
return modeTooltips?.[config.id] ?? config.defaultTooltip;
|
|
2313
|
+
}
|
|
2307
2314
|
var AnvilControl = class extends L21.Control {
|
|
2308
2315
|
constructor(anvil, options) {
|
|
2309
2316
|
super(L21.Util.extend({ position: "topleft" }, options));
|
|
@@ -2321,11 +2328,16 @@ var AnvilControl = class extends L21.Control {
|
|
|
2321
2328
|
const createButton = (group, config) => {
|
|
2322
2329
|
const btn = L21.DomUtil.create("a", "anvil-control-btn", group);
|
|
2323
2330
|
btn.href = "#";
|
|
2324
|
-
btn.title = config.title;
|
|
2325
2331
|
btn.setAttribute("role", "button");
|
|
2326
|
-
btn.setAttribute("aria-label", config.title);
|
|
2327
2332
|
btn.appendChild(buildIcon(config.icon));
|
|
2333
|
+
const syncTooltip = () => {
|
|
2334
|
+
const tooltip = resolveModeTooltip(config, this._options.modeTooltips);
|
|
2335
|
+
btn.title = tooltip;
|
|
2336
|
+
btn.setAttribute("aria-label", tooltip);
|
|
2337
|
+
};
|
|
2338
|
+
syncTooltip();
|
|
2328
2339
|
L21.DomEvent.disableClickPropagation(btn);
|
|
2340
|
+
L21.DomEvent.on(btn, "mouseover focus", syncTooltip);
|
|
2329
2341
|
L21.DomEvent.on(btn, "click", (e) => {
|
|
2330
2342
|
L21.DomEvent.preventDefault(e);
|
|
2331
2343
|
if (config.id === "off" /* Off */) {
|
|
@@ -2339,12 +2351,12 @@ var AnvilControl = class extends L21.Control {
|
|
|
2339
2351
|
blocks.forEach((block, index) => {
|
|
2340
2352
|
const group = L21.DomUtil.create("div", "leaflet-bar anvil-toolbar-group", container);
|
|
2341
2353
|
block.forEach((modeId) => {
|
|
2342
|
-
const config =
|
|
2354
|
+
const config = MODE_CONFIGS_BY_ID.get(modeId);
|
|
2343
2355
|
if (!config) return;
|
|
2344
2356
|
createButton(group, config);
|
|
2345
2357
|
});
|
|
2346
2358
|
if (index === blocks.length - 1 && !this._btns["off" /* Off */]) {
|
|
2347
|
-
createButton(group,
|
|
2359
|
+
createButton(group, MODE_CONFIGS_BY_ID.get("off" /* Off */));
|
|
2348
2360
|
}
|
|
2349
2361
|
});
|
|
2350
2362
|
const updateFn = (mode) => {
|
|
@@ -2440,7 +2452,8 @@ var Anvil = class {
|
|
|
2440
2452
|
});
|
|
2441
2453
|
this.control = anvilControl(this, {
|
|
2442
2454
|
position: this.options.controlPosition,
|
|
2443
|
-
modes: modesFromOptions
|
|
2455
|
+
modes: modesFromOptions,
|
|
2456
|
+
modeTooltips: this.options.modeTooltips
|
|
2444
2457
|
});
|
|
2445
2458
|
this.control?.addTo(this.map);
|
|
2446
2459
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -2200,25 +2200,26 @@ import {
|
|
|
2200
2200
|
} from "lucide";
|
|
2201
2201
|
var ANVIL_TOOLBAR_STYLE_ID = "anvil-toolbar-styles";
|
|
2202
2202
|
var MODE_CONFIGS = [
|
|
2203
|
-
{ id: "marker" /* Marker */,
|
|
2204
|
-
{ id: "polyline" /* Polyline */,
|
|
2205
|
-
{ id: "polygon" /* Polygon */,
|
|
2206
|
-
{ id: "rectangle" /* Rectangle */,
|
|
2207
|
-
{ id: "square" /* Square */,
|
|
2208
|
-
{ id: "triangle" /* Triangle */,
|
|
2209
|
-
{ id: "circle" /* Circle */,
|
|
2210
|
-
{ id: "freehand" /* Freehand */,
|
|
2211
|
-
{ id: "cut" /* Cut */,
|
|
2212
|
-
{ id: "split" /* Split */,
|
|
2213
|
-
{ id: "union" /* Union */,
|
|
2214
|
-
{ id: "subtract" /* Subtract */,
|
|
2215
|
-
{ id: "drag" /* Drag */,
|
|
2216
|
-
{ id: "scale" /* Scale */,
|
|
2217
|
-
{ id: "rotate" /* Rotate */,
|
|
2218
|
-
{ id: "edit" /* Edit */,
|
|
2219
|
-
{ id: "delete" /* Delete */,
|
|
2220
|
-
{ id: "off" /* Off */,
|
|
2203
|
+
{ id: "marker" /* Marker */, defaultTooltip: "Marker", icon: MapPin },
|
|
2204
|
+
{ id: "polyline" /* Polyline */, defaultTooltip: "Line", icon: Waypoints },
|
|
2205
|
+
{ id: "polygon" /* Polygon */, defaultTooltip: "Polygon", icon: Pentagon },
|
|
2206
|
+
{ id: "rectangle" /* Rectangle */, defaultTooltip: "Rectangle", icon: RectangleHorizontal },
|
|
2207
|
+
{ id: "square" /* Square */, defaultTooltip: "Square", icon: Square },
|
|
2208
|
+
{ id: "triangle" /* Triangle */, defaultTooltip: "Triangle", icon: Triangle },
|
|
2209
|
+
{ id: "circle" /* Circle */, defaultTooltip: "Circle", icon: Circle6 },
|
|
2210
|
+
{ id: "freehand" /* Freehand */, defaultTooltip: "Freehand", icon: Hand },
|
|
2211
|
+
{ id: "cut" /* Cut */, defaultTooltip: "Cut", icon: Scissors },
|
|
2212
|
+
{ id: "split" /* Split */, defaultTooltip: "Split", icon: Split },
|
|
2213
|
+
{ id: "union" /* Union */, defaultTooltip: "Union", icon: SquaresUnite },
|
|
2214
|
+
{ id: "subtract" /* Subtract */, defaultTooltip: "Subtract", icon: SquaresSubtract },
|
|
2215
|
+
{ id: "drag" /* Drag */, defaultTooltip: "Drag", icon: Move },
|
|
2216
|
+
{ id: "scale" /* Scale */, defaultTooltip: "Scale", icon: Scaling },
|
|
2217
|
+
{ id: "rotate" /* Rotate */, defaultTooltip: "Rotate", icon: RotateCw },
|
|
2218
|
+
{ id: "edit" /* Edit */, defaultTooltip: "Edit", icon: SquarePen },
|
|
2219
|
+
{ id: "delete" /* Delete */, defaultTooltip: "Delete", icon: Trash2 },
|
|
2220
|
+
{ id: "off" /* Off */, defaultTooltip: "Turn Off", icon: Power }
|
|
2221
2221
|
];
|
|
2222
|
+
var MODE_CONFIGS_BY_ID = new Map(MODE_CONFIGS.map((config) => [config.id, config]));
|
|
2222
2223
|
function ensureToolbarStyles() {
|
|
2223
2224
|
if (typeof document === "undefined" || document.getElementById(ANVIL_TOOLBAR_STYLE_ID)) return;
|
|
2224
2225
|
const style = document.createElement("style");
|
|
@@ -2288,6 +2289,12 @@ function buildIcon(iconNode) {
|
|
|
2288
2289
|
focusable: "false"
|
|
2289
2290
|
});
|
|
2290
2291
|
}
|
|
2292
|
+
function resolveModeTooltip(config, modeTooltips) {
|
|
2293
|
+
if (typeof modeTooltips === "function") {
|
|
2294
|
+
return modeTooltips(config.id, config.defaultTooltip) ?? config.defaultTooltip;
|
|
2295
|
+
}
|
|
2296
|
+
return modeTooltips?.[config.id] ?? config.defaultTooltip;
|
|
2297
|
+
}
|
|
2291
2298
|
var AnvilControl = class extends L21.Control {
|
|
2292
2299
|
constructor(anvil, options) {
|
|
2293
2300
|
super(L21.Util.extend({ position: "topleft" }, options));
|
|
@@ -2305,11 +2312,16 @@ var AnvilControl = class extends L21.Control {
|
|
|
2305
2312
|
const createButton = (group, config) => {
|
|
2306
2313
|
const btn = L21.DomUtil.create("a", "anvil-control-btn", group);
|
|
2307
2314
|
btn.href = "#";
|
|
2308
|
-
btn.title = config.title;
|
|
2309
2315
|
btn.setAttribute("role", "button");
|
|
2310
|
-
btn.setAttribute("aria-label", config.title);
|
|
2311
2316
|
btn.appendChild(buildIcon(config.icon));
|
|
2317
|
+
const syncTooltip = () => {
|
|
2318
|
+
const tooltip = resolveModeTooltip(config, this._options.modeTooltips);
|
|
2319
|
+
btn.title = tooltip;
|
|
2320
|
+
btn.setAttribute("aria-label", tooltip);
|
|
2321
|
+
};
|
|
2322
|
+
syncTooltip();
|
|
2312
2323
|
L21.DomEvent.disableClickPropagation(btn);
|
|
2324
|
+
L21.DomEvent.on(btn, "mouseover focus", syncTooltip);
|
|
2313
2325
|
L21.DomEvent.on(btn, "click", (e) => {
|
|
2314
2326
|
L21.DomEvent.preventDefault(e);
|
|
2315
2327
|
if (config.id === "off" /* Off */) {
|
|
@@ -2323,12 +2335,12 @@ var AnvilControl = class extends L21.Control {
|
|
|
2323
2335
|
blocks.forEach((block, index) => {
|
|
2324
2336
|
const group = L21.DomUtil.create("div", "leaflet-bar anvil-toolbar-group", container);
|
|
2325
2337
|
block.forEach((modeId) => {
|
|
2326
|
-
const config =
|
|
2338
|
+
const config = MODE_CONFIGS_BY_ID.get(modeId);
|
|
2327
2339
|
if (!config) return;
|
|
2328
2340
|
createButton(group, config);
|
|
2329
2341
|
});
|
|
2330
2342
|
if (index === blocks.length - 1 && !this._btns["off" /* Off */]) {
|
|
2331
|
-
createButton(group,
|
|
2343
|
+
createButton(group, MODE_CONFIGS_BY_ID.get("off" /* Off */));
|
|
2332
2344
|
}
|
|
2333
2345
|
});
|
|
2334
2346
|
const updateFn = (mode) => {
|
|
@@ -2424,7 +2436,8 @@ var Anvil = class {
|
|
|
2424
2436
|
});
|
|
2425
2437
|
this.control = anvilControl(this, {
|
|
2426
2438
|
position: this.options.controlPosition,
|
|
2427
|
-
modes: modesFromOptions
|
|
2439
|
+
modes: modesFromOptions,
|
|
2440
|
+
modeTooltips: this.options.modeTooltips
|
|
2428
2441
|
});
|
|
2429
2442
|
this.control?.addTo(this.map);
|
|
2430
2443
|
}
|