How to use Font Awesome with Polymer LitElement - font-awesome

I can't get the Font Awesome icons to work with LitElement, because CSS styles don't pierce the shadow boundaries of custom elements.
Is it possible to use Font Awesome or other icons with LitElement?

There is material icons in Polymer material library and the solutions used there helped me to solve the font awesome problem.
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script type="module" src="./src/components/fa-icon.js"></script>
<title>Font Awesome test</title>
</head>
<body>
<h1>Hello world! <fa-icon iclass="far fa-thumbs-up"></fa-icon>
</body>
</html>
fa-icon.js:
import { LitElement, html } from '#polymer/lit-element';
import { FaStyles } from './css/fontawesome-all.css.js';
export class FaIcon extends LitElement {
static get properties() {
return {
iclass: String
}
}
constructor() {
super();
this.iclass="";
const fontEl = document.createElement('link');
fontEl.rel = 'stylesheet';
fontEl.href = 'https://use.fontawesome.com/releases/v5.0.13/css/all.css';
document.head.appendChild(fontEl);
}
_render({ iclass }) {
return html`${FaStyles}<i class$="${iclass}"></i>`;
}
}
customElements.define('fa-icon', FaIcon);
And then you need to customize font awesome css-file. Download the css and rename it with ".js". Modify the file.
css/fontawesome-all.css.js:
import { LitElement, html } from '#polymer/lit-element';
export const FaStyles = html`
<style>
... the file's original content here ...
</style>
`;
And then you must replace all '\' with '\\'. Example:
.fa-yahoo:before {
content: "\f19e"; }
after replacement:
.fa-yahoo:before {
content: "\\f19e"; }

try https://www.npmjs.com/package/fa-icons , this module is based in LitElement

if someone is still having this issue this is very helpful
https://www.npmjs.com/package/fa-icons
npm install fa-icons
and then in your code, import the library, and use the icons with:
<fa-icons> </fa-icons>
example below
import { LitElement, html} from 'lit-element';
import 'fa-icons';
class SomeClass extends LitElement {
render() {
return html`
<div>
<fa-icon class="fas fa-address-card" color="#2980B9" size="2em"></fa-icon>
</div>
`;
}
}
customElements.define('custom-component', SomeClass );

Another way I have used for LitElement is as follows:
import { LitElement, html, customElement } from 'lit-element'
#customElement('font-awesomeness')
export class FontAwesomeness extends LitElement {
render() {
return html `
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css"
integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf"
crossorigin="anonymous"/>
<i class="far fa-thumbs-up"></i>
`
}
}

You can import an external style sheet by adding a <link> element to your template.
Here's my runnable snippet.
index.html
<html>
<head>
<title>Use Font Awesome 5 with LitElement</title>
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css">
<script type="module" src="./my-element.js"></script>
</head>
<body>
<my-element></my-element>
</body>
</html>
my-element.js
import { LitElement, html, css } from 'lit-element';
class MyElement extends LitElement {
render() {
return html`
<link rel="stylesheet" href="./app-styles.css">
<div>
<i class="icon hat-wizard"></i>Hat Wizard
</div>
`;
}
}
customElements.define('my-element', MyElement);
app-styles.css
You can use Unicode for this in CSS.
See here for the official list of Unicode character codes in Font Awesome.
Note: Make sure to include the correct weight and Unicode value for
the icon.
/* Step 1: Common Properties: All required to make icons render reliably */
.icon::before {
display: inline-block;
font-style: normal;
font-variant: normal;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
}
/* Step 2: Reference Individual Icons */
.hat-wizard::before {
font-family: 'Font Awesome 5 Free';
content: '\f6e8';
display: inline-block;
vertical-align: middle;
font-weight: 900;
}

install fontawesome-free & fa-icons
npm i #fortawesome/fontawesome-free
npm i fa-icons
my-element.js
import { LitElement, html, css } from 'lit-element';
import 'fa-icons';
class MyElement extends LitElement {
render() {
return html`
<div>
<fa-icon class="fas fa-camera" color="#2980B9" size="2em"></fa-icon>
</div>
`;
}
}
customElements.define('my-element', MyElement);

Related

Why is my React stylesheet media query not working?

I am connecting an external stylesheet to my React component, and I have a media query and I intend the logo to have a height of 100vh when the screen width is less than 300px. However this media query is ignored and only the original styles apply. I tried adding the css directly in the HTML file using the style tag. Here is the relevant code:
Logo.js
import React from "react";
import "./Logo.css";
export default class Logo extends React.Component {
render() {
return (
<img
alt=""
className="Logo"
src="../logo.png"
/>
);
};
};
Logo.css
.Logo {
position: absolute;
left: 42vw;
bottom: calc(50vh + 4vw);
height: 16vw;
};
#media screen and (max-width: 300px) {
.Logo {
height: 100vh;
};
};
Using hooks in react:
import React from "react";
import { useMediaQuery } from "react-responsive";
export default function Logo() {
const isDesktop = useMediaQuery({
query: '(min-aspect-ratio: 1/1)'
});
let logo = {};
if (isDesktop) {
logo = {
position: "absolute",
left: "42vw",
bottom: "calc(50vh + 4vw)",
height: "16vw"
};
} else {
logo = {
position: "absolute",
left: "38vw",
bottom: "calc(50vh + 6vw)",
height: "24vw",
};
};
return (
<img
alt=""
style={logo}
src="../logo.png"
/>
);
};
Remember to download useMediaQuery by typing
npm install react-responsive --save
into the command line.
Please try adding this to the head section of your code.
<meta name="viewport" content="width=device-width,initial-scale=1">

Attributes in Web Components do not show up

This is my HTML with a custom web component.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Advanced ToDo App with Web Components</title>
</head>
<body>
<todo-item todo="Walk the dog" data-id="1"></todo-item>
<script src="../static/listItems.js"></script>
</body>
</html>
This is my JS file where I set up the component.
const template = document.createElement("template");
template.innerHTML = `<style>
h4 {
color: white;
font-size: 14px;
display: block;
padding: 10px 5px;
background: orange;
}
</style>
<div class="todo-item">
<h4></h4>
</div>
`;
class TodoItem extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.shadowRoot.querySelector("h4").innerText = this.getAttribute("todo");
}
connectedCallback() {
this.shadowRoot
.querySelector(".todo-item")
.addEventListener("click", () => {
console.log(this.getAttribute("data-id"));
});
}
}
window.customElements.define("todo-item", TodoItem);
// Über Daten iterieren
const body = document.querySelector("body");
const dummydata = [
{ id: 1, description: "Walk the dog" },
{ id: 2, description: "Play football" }
];
for (item of dummydata) {
console.log(item.description);
todoItem = document.createElement("todo-item");
todoItem.setAttribute("todo", item.description); # Does not work!
todoItem.setAttribute("data-id", item.id);
body.appendChild(todoItem);
}
The component in the HTML works perfectly fine, but when I try to create them dynamically with JavaScript setting the attributes seem not to work. The "todo"-text does not get displayed. Is setting this "todo" attribute invalid?
Got it - the attribute has to be set inside the connectedCallBack function. When doing it before the attribute valu will be null
connectedCallback() {
this.shadowRoot
.querySelector(".todo-item")
.addEventListener("click", () => {
console.log(this.getAttribute("data-id"));
});
this.shadowRoot.querySelector("h4").innerText = this.getAttribute("todo");
}

paper-icon-button image is not seen

I have created a component with 2 paper-icon-buttons. This also include iron-icons. However when I click though ripple is seen. The icon image itself is missing.
Here is the code
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/iron-image/iron-image.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
<dom-module id="lightbox-app">
<template>
<style >
:host {
display: block;
position: fixed;
background: rgba(247, 245, 245, 0.8);
width: 100%;
height: 100%;
}
</style>
<paper-icon-button icon="favorite"style="color: red;" title="heart"></paper-icon-button>
<paper-icon-button icon="arrow-back" style="color: rgb(10, 10, 10);"></paper-icon-button>
<iron-image sizing = "cover" style = "width:calc(100% - 4px); height:180px; background-color: lightgray;"
preload fade src="https://firebasestorage.googleapis.com/v0/b/wishpix-5fff8.appspot.com/o/gn-01.jpg?alt=media&token=dd1a1f47-a2f8-464a-bb3c-0581ea7613d0"></iron-image>
</template>
<script>
/**
* #customElement
* #polymer
*/
class LightboxApp extends Polymer.Element {
static get is() { return 'lightbox-app'; }
static get properties() {
return {
prop1: {
type: String,
value: 'lightbox-app'
}
};
}
ready ()
{
super.ready();
}
}
window.customElements.define(LightboxApp.is, LightboxApp);
</script>
</dom-module>
As mentioned above while the ripple is seen on click, image is not seen

Polymer 2.0 using Shady DOM document.getElementByID()

I am using the Shady DOM in Polymer 2.0 by using the following script
<script>window.ShadyDOM = {force:true};</script>
I have created three custom element logon-email, logon-password and logon-button. When the paper-button is clicked I would like to get the values of the paper-inputs of logon-email and login-password. Using Polymer 1.0 I have used document.getElementById('#emailLogon').value to get the value from another custom element but this returns null in Polymer 2.0 using Shady DOM.
If what I am doing is now not possible what is the alternative to retrieving values from external custom elements from another custom element.
<link rel="import" href="../bower_components/polymer/polymer-element.html">
<link rel="import" href="shared-styles.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<dom-module id="logon-email">
<template>
<style include="shared-styles">
:host {
display: block;
padding: 10px;
}
paper-input {
--paper-input-container-input-color: white;
--paper-input-container-label: { color: white; font-size: 12px};
}
.email_label {
font-family: 'Roboto', 'Noto', sans-serif;
font-size: 12px;
color: white;
}
</style>
<div class="email_label">Email</div>
<paper-input label="Please enter your email address" no-label-float></paper-input>
</template>
<script>
class LogonEmail extends Polymer.Element {
static get is() { return 'logon-email'; }
}
window.customElements.define(LogonEmail.is, LogonEmail);
</script>
</dom-module>
<dom-module id="logon-password">
<template>
<style include="shared-styles">
:host {
display: block;
padding: 10px;
}
paper-input {
--paper-input-container-input-color: white;
--paper-input-container-label: { color: white; font-size: 12px; };
}
.password_label {
font-family: 'Roboto', 'Noto', sans-serif;
font-size: 12px;
color: white;
}
</style>
<div class="password_label">Password</div>
<paper-input id="logonPassword" label="Please enter your password" type="password" no-label-float></paper-input>
</template>
<script>
class LogonPassword extends Polymer.Element {
static get is() { return 'logon-password'; }
}
window.customElements.define(LogonPassword.is, LogonPassword);
</script>
</dom-module>
<link rel="import" href="../bower_components/polymer/polymer-element.html">
<link rel="import" href="shared-styles.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
<link rel="import" href="../bower_components/paper-styles/color.html">
<dom-module id="logon-button">
<template>
<style include="shared-styles">
:host {
display: block;
padding: 10px;
}
paper-button {
font-family: 'Roboto', 'Noto', sans-serif;
font-weight: normal;
font-size: 14px;
-webkit-font-smoothing: antialiased;
}
paper-button.green {
background-color: var(--paper-green-500);
color: white;
margin: auto;
width: 100%;
}
</style>
<paper-button on-click="handleLoginClick" raised class="green">Login</paper-button
</template>
<script>
class LogonButton extends Polymer.Element {
static get is() { return 'logon-button'; }
connectedCallback() {
super.connectedCallback();
}
handleLoginClick(){
console.log('Login button clicked');
var loginEmail = document.getElementById('#logonEmail');
console.log('logonEmail ' + loginEmail);
}
}
window.customElements.define(LogonButton.is, LogonButton);
</script>
</dom-module>
This is the most easy approach at polymer to pass value between elements. So just define the property and set it notify:true to reflect at other elements as fallow :
<paper-input label="Please enter your email address" no-label-float value="{{emailVal}}"></paper-input>
At main document pass emailVal property to your custom elements so you have property in all 3 element like this.emailVal
<logon-email email-val="{{emailVal}}"></logon-email>
<logon-password email-val="{{emailVal}}"></logon-password>
<logon-button email-val="{{emailVal}}"></logon-button>
And define this property in logon-email element and set it notify : true to reflect all property in any changes.
at logon-email
static get properties() { return {
emailVal:{
type:String,
notify:true
},...
and at logon-button element:
handleLoginClick(){
console.log('Login button clicked');
console.log('logonEmail ', this.emailVal);
}
Hope clear .

Remove checkbox from LayerList widget (ArcGIS JavaScript)

Is it possible to change the design of the LayerList widget in this ESRI tutorial ?
I would like the LayerList with no checkboxes and to select one layer at a time just by clicking it’s name.
I know you can hide the checkboxes with display: none but how do you select the layers?
Michelle.
Well, Here is the working solution for this-
Use selection color to select/Unselect the layerList Items:-
JSFiddle:- https://jsfiddle.net/vikash2402/5dcLh450/3/
Below is the working code for this-
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Layer List Dijit</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.20/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.20/esri/css/esri.css">
<style>
html, body, .container, #map {
height:100%;
width:100%;
margin:0;
padding:0;
margin:0;
font-family: "Open Sans";
}
#map {
padding:0;
}
#layerListPane{
width:25%;
}
.esriLayer{
background-color: #fff;
}
.esriLayerList .esriList{
border-top:none;
}
.esriLayerList .esriTitle {
background-color: #fff;
border-bottom:none;
}
.esriLayerList .esriList ul{
}
/* ****** Here you can change the selection color ******* */
.esriListVisible label{
background-color: aqua !important;
}
.esriCheckbox{
display: none !important;
}
</style>
<script>var dojoConfig = { parseOnLoad: true };</script>
<script src="https://js.arcgis.com/3.20/"></script>
<script>
require([
"esri/arcgis/utils",
"esri/dijit/LayerList",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dojo/domReady!"
], function(
arcgisUtils,
LayerList
) {
//Create a map based on an ArcGIS Online web map id
arcgisUtils.createMap("f63fed3f87fc488489e27c026fa5d434", "map").then(function(response){
var myWidget = new LayerList({
map: response.map,
layers: arcgisUtils.getLayerList(response)
},"layerList");
myWidget.startup();
});
});
</script>
</head>
<body class="claro">
<div class="container" data-dojo-type="dijit/layout/BorderContainer"
data-dojo-props="design:'headline',gutters:false">
<div id="layerListPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'right'">
<div id="layerList"></div>
</div>
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
</div>
</body>
</html>
Hoping this will help you :)