Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Icons as web components, example #34

Merged
merged 3 commits into from
Aug 12, 2024
Merged
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
136 changes: 136 additions & 0 deletions src/alpaca-map-icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { LitElement, html, css, svg } from "lit";

export default class AlpacaMapIcon extends LitElement {
static properties = {
icon: { type: String },
};

static styles = [
css`
.icon {
width: 1em;
height: 1em;

font-size: 1.5em;
fill: currentcolor;

padding: 0 0.1em 0 0.1em;
}

.private {
fill: var(--private-farm);
}

.public {
fill: var(--public-farm);
}
`,
];

constructor() {
super();
this.icon;
}

// When element is connected to the DOM connectedCallback() is called.
// This is needed in order to know the value of this.key which is passed in from the attribute

connectedCallback() {
super.connectedCallback();
}

_iconBed() {
const path = svg`<path d="M32 32c17.7 0 32 14.3 32 32V320H288V160c0-17.7 14.3-32 32-32H544c53 0 96 43 96 96V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V416H352 320 64v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V64C0 46.3 14.3 32 32 32zm144 96a80 80 0 1 1 0 160 80 80 0 1 1 0-160z"/>`;

return html`<svg class="icon" viewBox="0 0 640 512">${path}</svg>`;
}

_iconCalendarCheck() {
const path = svg`<path d="M128 0c17.7 0 32 14.3 32 32V64H288V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H0V112C0 85.5 21.5 64 48 64H96V32c0-17.7 14.3-32 32-32zM0 192H448V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V192zM329 305c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-95 95-47-47c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l64 64c9.4 9.4 24.6 9.4 33.9 0L329 305z"/>`;

return html`<svg class="icon" viewBox="0 0 640 512">${path}</svg>`;
}

_iconHandshake() {
const path = svg`<path d="M323.4 85.2l-96.8 78.4c-16.1 13-19.2 36.4-7 53.1c12.9 17.8 38 21.3 55.3 7.8l99.3-77.2c7-5.4 17-4.2 22.5 2.8s4.2 17-2.8 22.5l-20.9 16.2L512 316.8V128h-.7l-3.9-2.5L434.8 79c-15.3-9.8-33.2-15-51.4-15c-21.8 0-43 7.5-60 21.2zm22.8 124.4l-51.7 40.2C263 274.4 217.3 268 193.7 235.6c-22.2-30.5-16.6-73.1 12.7-96.8l83.2-67.3c-11.6-4.9-24.1-7.4-36.8-7.4C234 64 215.7 69.6 200 80l-72 48V352h28.2l91.4 83.4c19.6 17.9 49.9 16.5 67.8-3.1c5.5-6.1 9.2-13.2 11.1-20.6l17 15.6c19.5 17.9 49.9 16.6 67.8-2.9c4.5-4.9 7.8-10.6 9.9-16.5c19.4 13 45.8 10.3 62.1-7.5c17.9-19.5 16.6-49.9-2.9-67.8l-134.2-123zM16 128c-8.8 0-16 7.2-16 16V352c0 17.7 14.3 32 32 32H64c17.7 0 32-14.3 32-32V128H16zM48 320a16 16 0 1 1 0 32 16 16 0 1 1 0-32zM544 128V352c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V144c0-8.8-7.2-16-16-16H544zm32 208a16 16 0 1 1 32 0 16 16 0 1 1 -32 0z"/>`;

return html`<svg class="icon" viewBox="0 0 640 512">${path}</svg>`;
}

_iconHouseFlag() {
const path = svg`<path d="M480 0c-17.7 0-32 14.3-32 32V192 512h64V192H624c8.8 0 16-7.2 16-16V48c0-8.8-7.2-16-16-16H512c0-17.7-14.3-32-32-32zM416 159L276.8 39.7c-12-10.3-29.7-10.3-41.7 0l-224 192C1 240.4-2.7 254.5 2 267.1S18.6 288 32 288H64V480c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V384c0-17.7 14.3-32 32-32h64c17.7 0 32 14.3 32 32v96c0 17.7 14.3 32 32 32h64.7l.2 0h-1V159z" />`;

return html`<svg class="icon public" viewBox="0 0 640 512">${path}</svg>`;
}

_iconKey() {
const path = svg`<path d="M336 352c97.2 0 176-78.8 176-176S433.2 0 336 0S160 78.8 160 176c0 18.7 2.9 36.8 8.3 53.7L7 391c-4.5 4.5-7 10.6-7 17v80c0 13.3 10.7 24 24 24h80c13.3 0 24-10.7 24-24V448h40c13.3 0 24-10.7 24-24V384h40c6.4 0 12.5-2.5 17-7l33.3-33.3c16.9 5.4 35 8.3 53.7 8.3zM376 96a40 40 0 1 1 0 80 40 40 0 1 1 0-80z"/>`;

return html`<svg class="icon private" viewBox="0 0 640 512">${path}</svg>`;
}

_iconMars() {
const path = svg`<path d="M289.8 46.8c3.7-9 12.5-14.8 22.2-14.8H424c13.3 0 24 10.7 24 24V168c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-33.4-33.4L321 204.2c19.5 28.4 31 62.7 31 99.8c0 97.2-78.8 176-176 176S0 401.2 0 304s78.8-176 176-176c37 0 71.4 11.4 99.8 31l52.6-52.6L295 73c-6.9-6.9-8.9-17.2-5.2-26.2zM400 80l0 0h0v0zM176 416a112 112 0 1 0 0-224 112 112 0 1 0 0 224z"/>`;

return html`<svg class="icon" viewBox="0 0 640 512">${path}</svg>`;
}

_iconPersonHiking() {
const path = svg`<path d="M192 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm51.3 182.7L224.2 307l49.7 49.7c9 9 14.1 21.2 14.1 33.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V397.3l-73.9-73.9c-15.8-15.8-22.2-38.6-16.9-60.3l20.4-84c8.3-34.1 42.7-54.9 76.7-46.4c19 4.8 35.6 16.4 46.4 32.7L305.1 208H336V184c0-13.3 10.7-24 24-24s24 10.7 24 24v55.8c0 .1 0 .2 0 .2s0 .2 0 .2V488c0 13.3-10.7 24-24 24s-24-10.7-24-24V272H296.6c-16 0-31-8-39.9-21.4l-13.3-20zM81.1 471.9L117.3 334c3 4.2 6.4 8.2 10.1 11.9l41.9 41.9L142.9 488.1c-4.5 17.1-22 27.3-39.1 22.8s-27.3-22-22.8-39.1zm55.5-346L101.4 266.5c-3 12.1-14.9 19.9-27.2 17.9l-47.9-8c-14-2.3-22.9-16.3-19.2-30L31.9 155c9.5-34.8 41.1-59 77.2-59h4.2c15.6 0 27.1 14.7 23.3 29.8z"/>`;

return html`<svg class="icon" viewBox="0 0 640 512">${path}</svg>`;
}

_iconStore() {
const path = svg`<path d="M547.6 103.8L490.3 13.1C485.2 5 476.1 0 466.4 0H109.6C99.9 0 90.8 5 85.7 13.1L28.3 103.8c-29.6 46.8-3.4 111.9 51.9 119.4c4 .5 8.1 .8 12.1 .8c26.1 0 49.3-11.4 65.2-29c15.9 17.6 39.1 29 65.2 29c26.1 0 49.3-11.4 65.2-29c15.9 17.6 39.1 29 65.2 29c26.2 0 49.3-11.4 65.2-29c16 17.6 39.1 29 65.2 29c4.1 0 8.1-.3 12.1-.8c55.5-7.4 81.8-72.5 52.1-119.4zM499.7 254.9l-.1 0c-5.3 .7-10.7 1.1-16.2 1.1c-12.4 0-24.3-1.9-35.4-5.3V384H128V250.6c-11.2 3.5-23.2 5.4-35.6 5.4c-5.5 0-11-.4-16.3-1.1l-.1 0c-4.1-.6-8.1-1.3-12-2.3V384v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V384 252.6c-4 1-8 1.8-12.3 2.3z"/>`;

return html`<svg class="icon" viewBox="0 0 640 512">${path}</svg>`;
}

_iconStore() {
const path = svg`<path d="M547.6 103.8L490.3 13.1C485.2 5 476.1 0 466.4 0H109.6C99.9 0 90.8 5 85.7 13.1L28.3 103.8c-29.6 46.8-3.4 111.9 51.9 119.4c4 .5 8.1 .8 12.1 .8c26.1 0 49.3-11.4 65.2-29c15.9 17.6 39.1 29 65.2 29c26.1 0 49.3-11.4 65.2-29c15.9 17.6 39.1 29 65.2 29c26.2 0 49.3-11.4 65.2-29c16 17.6 39.1 29 65.2 29c4.1 0 8.1-.3 12.1-.8c55.5-7.4 81.8-72.5 52.1-119.4zM499.7 254.9l-.1 0c-5.3 .7-10.7 1.1-16.2 1.1c-12.4 0-24.3-1.9-35.4-5.3V384H128V250.6c-11.2 3.5-23.2 5.4-35.6 5.4c-5.5 0-11-.4-16.3-1.1l-.1 0c-4.1-.6-8.1-1.3-12-2.3V384v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V384 252.6c-4 1-8 1.8-12.3 2.3z"/>`;

return html`<svg class="icon" viewBox="0 0 640 512">${path}</svg>`;
}

render() {
let icon;
switch (this.icon) {
case "bed":
icon = this._iconBed();
break;
case "calendarCheck":
icon = this._iconCalendarCheck();
break;
case "handShake":
icon = this._iconHandshake();
break;
case "houseFlag":
icon = this._iconHouseFlag();
break;
case "key":
icon = this._iconKey();
break;
case "mars":
icon = this._iconMars();
break;
case "personHiking":
icon = this._iconPersonHiking();
break;
case "store":
icon = this._iconStore();
break;
case "store":
icon = this._iconStore();
break;
default:
return "";
}

return icon;
}
}

if (!customElements.get("alpaca-map-icon")) {
customElements.define("alpaca-map-icon", AlpacaMapIcon);
}
19 changes: 4 additions & 15 deletions src/alpaca-map-marker.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { LitElement, html, css } from "lit";
import { iconStyles, iconHouseFlag, iconKey } from "./svg-icons";
import "./alpaca-map-icon";

export default class AlpacaMapMarker extends LitElement {
static properties = {
Expand All @@ -22,7 +22,6 @@ export default class AlpacaMapMarker extends LitElement {
};

static styles = [
iconStyles,
css`
/********* Farm styles in unhighlighted state *********/
/* Ref: https://developers.google.com/maps/documentation/javascript/advanced-markers/html-markers#maps_advanced_markers_html-css */
Expand Down Expand Up @@ -107,14 +106,6 @@ export default class AlpacaMapMarker extends LitElement {
.farm.public::after {
border-top: 9px solid var(--public-farm);
}

.farm.private .icon svg {
fill: var(--private-farm);
}

.farm.public .icon svg {
fill: var(--public-farm);
}
`,
];

Expand All @@ -139,11 +130,9 @@ export default class AlpacaMapMarker extends LitElement {
render() {
return html` <div class="farm ${this.category} ${this.highlight}">
<div class="summary">
<div class="icon">
${this.category === "private"
? iconKey().htmlObject
: iconHouseFlag().htmlObject}
</div>
<alpaca-map-icon
icon="${this.category === "private" ? "key" : "houseFlag"}"
></alpaca-map-icon>
<div class="count">${this.count} 🦙</div>
</div>

Expand Down
50 changes: 18 additions & 32 deletions src/alpaca-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,8 @@ import { LitElement, html, css } from "lit";
import { MarkerClusterer } from "@googlemaps/markerclusterer";
import STYLED_MAP_TYPE from "./styles-map";
import stylesGoogle from "./styles-google";
import {
iconStyles,
iconBed,
iconCalendarCheck,
iconHandshake,
iconHouseFlag,
iconKey,
iconMars,
iconPersonHiking,
iconStore,
} from "./svg-icons";
import "./alpaca-map-marker";
import "./alpaca-map-icon";

export default class AlpacaMap extends LitElement {
static properties = {
Expand All @@ -25,7 +15,6 @@ export default class AlpacaMap extends LitElement {

static styles = [
stylesGoogle,
iconStyles,
css`
/********* Overall layout *********/

Expand Down Expand Up @@ -155,18 +144,6 @@ export default class AlpacaMap extends LitElement {
justify-content: center;
}

.icon {
padding: 0 0.1em 0 0.1em;
}

svg {
font-size: 1.5em;

path {
fill: currentcolor;
}
}

input[type="checkbox"] {
margin: 0em 0.4em 0em 0.1em;
width: 1.5em;
Expand Down Expand Up @@ -406,21 +383,24 @@ export default class AlpacaMap extends LitElement {
<span class="toggle">
<input type="checkbox" id="public" name="public" checked />
<label for="public">
${iconHouseFlag().htmlObject}Public farms</label
<alpaca-map-icon icon="houseFlag"></alpaca-map-icon>Public
farms</label
>
</span>

<span class="toggle">
<input type="checkbox" id="private" name="private" checked />
<label for="private"
>${iconKey().htmlObject}Private farms</label
><alpaca-map-icon icon="key"></alpaca-map-icon>Private
farms</label
>
</span>

<span class="toggle">
<input type="checkbox" id="alpacaSales" name="alpacaSales" />
<label for="alpacaSales"
>${iconHandshake().htmlObject}Alpaca sales</label
><alpaca-map-icon icon="handShake"></alpaca-map-icon>Alpaca
sales</label
>
</span>

Expand All @@ -431,20 +411,24 @@ export default class AlpacaMap extends LitElement {
name="alpacaWalking"
/>
<label for="alpacaWalking"
>${iconPersonHiking().htmlObject}Alpaca walking</label
><alpaca-map-icon icon="personHiking"></alpaca-map-icon>Alpaca
walking</label
>
</span>

<span class="toggle">
<input type="checkbox" id="bookable" name="bookable" />
<label for="bookable"
>${iconCalendarCheck().htmlObject}Bookable</label
><alpaca-map-icon icon="calendarCheck"></alpaca-map-icon
>Bookable</label
>
</span>

<span class="toggle">
<input type="checkbox" id="shop" name="shop" />
<label for="shop">${iconStore().htmlObject}Shop</label>
<label for="shop"
><alpaca-map-icon icon="store"></alpaca-map-icon>Shop</label
>
</span>

<span class="toggle">
Expand All @@ -454,14 +438,16 @@ export default class AlpacaMap extends LitElement {
name="overnightStay"
/>
<label for="overnightStay"
>${iconBed().htmlObject}Overnight stay</label
><alpaca-map-icon icon="bed"></alpaca-map-icon>Overnight
stay</label
>
</span>

<span class="toggle">
<input type="checkbox" id="studServices" name="studServices" />
<label for="studServices"
>${iconMars().htmlObject}Stud services</label
><alpaca-map-icon icon="mars"></alpaca-map-icon>Stud
services</label
>
</span>
</div>
Expand Down
Loading