Skip to content

Commit

Permalink
Merge pull request #23 from andrewgryan/feature/divicon
Browse files Browse the repository at this point in the history
DivIcon
  • Loading branch information
andrewgryan authored Jul 14, 2024
2 parents 11fc14b + 00220f3 commit b100f3e
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 0 deletions.
77 changes: 77 additions & 0 deletions docs/content/articles/divicon.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
+++
title = "Div icons"
+++

A customisable icon using a single `<div/>` and CSS.
For inspiration to style a single div, visit [https://a.singlediv.com/](https://a.singlediv.com/)

<style>
.icon {
border: none;
border-radius: 1000px;
}

.pink {
background-color: hotpink;
}

.blue {
background-color: cadetblue;
}
</style>

<l-map zoom="5" center="[45, 0]">
<l-tile-layer
url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
></l-tile-layer>
<l-marker lat-lng="[45, 1]">
<l-div-icon class-name="icon pink"></l-div-icon>
</l-marker>
<l-marker lat-lng="[45, -1]">
<l-div-icon class-name="icon blue"></l-div-icon>
</l-marker>
</l-map>
## Styling

If custom styles are to be applied,
it is best to use the JS attribute `className` by using the `class-name` equivalent HTML attribute.

```css
.icon {
border: none;
border-radius: 1000px;
}

.pink {
background-color: hotpink;
}

.blue {
background-color: cadetblue;
}
```

## Mark-up

The usual rules for converting from JS to HTML apply.

```html,hl_lines=6 9,linenos
<l-map zoom="5" center="[45, 0]">
<l-tile-layer
url-template="https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
></l-tile-layer>
<l-marker lat-lng="[45, 1]">
<l-div-icon class-name="icon pink"></l-div-icon>
</l-marker>
<l-marker lat-lng="[45, -1]">
<l-div-icon class-name="icon blue"></l-div-icon>
</l-marker>
</l-map>
```

Line 6 and 9 above show how to use a div icon to create a pink and blue circle icon.

# Conclusion

Div icons enable a front-end developer to craft amazing visualisations.
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import LImageOverlay from "./l-image-overlay.js";
import LVideoOverlay from "./l-video-overlay.js";
import LGeoJSON from "./l-geojson.js";
import LIcon from "./l-icon.js";
import LDivIcon from "./l-div-icon.js";
import LTooltip from "./l-tooltip.js";
import LPane from "./l-pane.js";
import generator from "./generator.js";
Expand All @@ -38,6 +39,7 @@ const init = (() => {
customElements.define("l-polygon", generator(polygon, "polygon"));
customElements.define("l-rectangle", generator(rectangle, "rectangle"));
customElements.define("l-tooltip", LTooltip);
customElements.define("l-div-icon", LDivIcon);
})();

export default init;
31 changes: 31 additions & 0 deletions src/l-div-icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { divIcon } from "leaflet";
import { iconConnected } from "./events";

export default class CustomElement extends HTMLElement {
constructor() {
super();
this.icon = null;
}

connectedCallback() {
// Leaflet JS DivIcon options
const options = {
html: this.innerHTML,
};
const className = this.getAttribute("class-name");
if (className !== null) {
options["className"] = className;
}

this.icon = divIcon(options);
this.dispatchEvent(
new CustomEvent(iconConnected, {
bubbles: true,
cancelable: true,
detail: {
icon: this.icon,
},
})
);
}
}
23 changes: 23 additions & 0 deletions src/l-div-icon.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// @vitest-environment happy-dom
import { divIcon, DivIcon } from "leaflet";
import { it, expect } from "vitest";
import "./index.js";

it("should render a div icon", () => {
const el = document.createElement("l-div-icon");
el.innerHTML = "Hello, World!";
document.body.appendChild(el);
expect(el.icon).toBeInstanceOf(DivIcon);
expect(el.icon).toEqual(divIcon({ html: "Hello, World!" }));
});

it("should attach div icon to marker", () => {
const icon = document.createElement("l-div-icon");
const marker = document.createElement("l-marker");
marker.setAttribute("lat-lng", "[0,0]");
marker.appendChild(icon);
document.body.appendChild(marker);

const actual = marker.layer.getIcon();
expect(icon.icon).toEqual(marker.layer.getIcon());
});

0 comments on commit b100f3e

Please sign in to comment.