How to add new gridstackitem with directive? - gridstack

Using gridstack.io, I want to dynamially have a button that can "add a widget" into a specific area. I have a component "" that I want to add dynamically into the grid.
Given my following definition for my gridstack, How can I make it such that if I add a button that when you click on it, adds a new directive in the top-left corner, how do I accomplish that?
I have the following directive:
grid-stack-directive.ts:
import { Directive, OnInit, Input, ElementRef, Renderer } from '#angular/core';
declare var $: any; // JQuery
#Directive({
selector: '[gridStack]'
})
export class GridStackDirective implements OnInit {
#Input() w: number;
#Input() animate: boolean;
constructor(
private el: ElementRef,
private renderer: Renderer
) {
renderer.setElementAttribute(el.nativeElement, "class", "grid-stack");
}
ngOnInit() {
let renderer = this.renderer;
let nativeElement = this.el.nativeElement;
let animate: string = this.animate ? "yes" : "no";
renderer.setElementAttribute(nativeElement, "data-gs-width", String(this.w));
if(animate == "yes") {
renderer.setElementAttribute(nativeElement, "data-gs-animate", animate);
}
let options = {
cellHeight: 80,
verticalMargin: 10
};
// TODO: listen to an event here instead of just waiting for the time to expire
setTimeout(function () {
$('.grid-stack').gridstack(options);
}, 300);
}
}
grid-stack-item-directive.ts:
import { Directive, ElementRef, Input, Renderer, OnInit } from '#angular/core';
#Directive({
selector: '[gridStackItem]'
})
export class GridStackItemDirective {
#Input() x: number;
#Input() y: number;
#Input() w: number;
#Input() h: number;
#Input() minWidth: number;
#Input() canResize: boolean;
constructor(
private el: ElementRef,
private renderer: Renderer
) {
renderer.setElementAttribute(el.nativeElement, "class", "grid-stack-item");
}
ngOnInit(): void {
let renderer = this.renderer;
let nativeElement = this.el.nativeElement;
let cannotResize: string = this.canResize ? "yes" : "no";
let elementText: string = '<div class="grid-stack-item-content">' + nativeElement.innerHTML + '</div>';
// TODO: Find the Angular(tm) way to do this ...
nativeElement.innerHTML = elementText;
renderer.setElementAttribute(nativeElement, "data-gs-x", String(this.x));
renderer.setElementAttribute(nativeElement, "data-gs-y", String(this.y));
renderer.setElementAttribute(nativeElement, "data-gs-width", String(this.w));
renderer.setElementAttribute(nativeElement, "data-gs-height", String(this.h));
if(this.minWidth) {
renderer.setElementAttribute(nativeElement, "data-gs-min-width", String(this.minWidth));
}
if(cannotResize == "yes") {
renderer.setElementAttribute(nativeElement, "data-gs-no-resize", cannotResize);
}
}
}
app.component.html:
<h1>My First Grid Stack Angular 2 App</h1>
<section id="demo" class="darklue">
<div class="container">
<div class="row">
<div class="col-lg-12 text-center">
<h2>Demo</h2>
<hr class="star-light">
</div>
</div>
<div gridStack w="12" animate="true">
<div gridStackItem x="0" y="0" w="4" h="2">1</div>
<div gridStackItem x="4" y="0" w="4" h="4">2</div>
<div gridStackItem x="8" y="0" w="2" h="2" canResize="false" minWidth="2">
<span class="fa fa-hand-o-up"></span> Drag me!
</div>
<div gridStackItem x="10" y="0" w="2" h="2">4</div>
<div gridStackItem x="0" y="2" w="2" h="2">5</div>
<div gridStackItem x="2" y="2" w="2" h="4">6</div>
<div gridStackItem x="8" y="2" w="4" h="2">7</div>
<div gridStackItem x="0" y="4" w="2" h="2">8</div>
<div gridStackItem x="4" y="4" w="4" h="2">9</div>
<div gridStackItem x="8" y="4" w="2" h="2">10</div>
<div gridStackItem x="10" y="4" w="2" h="2">11</div>
</div>
</div>
</section>
index.html:
<html>
<head>
<title>Angular QuickStart</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="node_modules/font-awesome/css/font-awesome.min.css">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Indie+Flower" rel='stylesheet' type='text/css'>
<!-- 1. Load libraries -->
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/core-js/client/shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<!-- 2. Configure SystemJS -->
<script src="systemjs.config.js"></script>
<script>
System.import('app').catch(function(err){ console.error(err); });
</script>
<!-- jquery -->
<script src="node_modules/jquery/dist/jquery.js"></script>
<script src="node_modules/jquery-ui-dist/jquery-ui.min.js"></script>
<script src="node_modules/jquery-ui-touch-punch/jquery.ui.touch-punch.min.js"></script>
<script src="node_modules/jquery-easing/dist/jquery.easing.1.3.umd.min.js"></script>
<!-- underscore and gridstack -->
<script src="node_modules/underscore/underscore-min.js"></script>
<script src="node_modules/gridstack/dist/gridstack.js"></script>
<link rel="stylesheet" href="node_modules/gridstack/dist/gridstack.min.css">
<link rel="stylesheet" href="node_modules/gridstack/dist/gridstack-extra.min.css">
<link rel="stylesheet" href="app/css/gridstack-demo.css">
<!-- bootstrap -->
<script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css">
<!-- freelancer stuff -->
<script src="app/js/freelancer.js"></script>
<link rel="stylesheet" href="app/css/freelancer.css">
</head>
<!-- 3. Display the application -->
<body>
<my-app>Loading...</my-app>
</body>
</html>

you can make a "router" inside your gridStack directive - it will get a string represent the type of the desired component and load the it with ngIf
<div customGridStackItem1 *ngIf="itemType == 'stackItem1'"></div>
<div customGridStackItem2 *ngIf="itemType == 'stackItem2'"></div>
<div anotherGridStackItem *ngIf="itemType == 'anotherStackItem'"></div>
that way you will only load the component you need in each grid item

Related

Bot framework Task modules takes a lot of time for first load

I am invoking the task module from the bot. It takes a lot of time around 15 seconds for the first load. Although the subsequent loads are faster.
Is there a way to make the first load faster ?
My code looks like this
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Reserve a Space</title>
<link rel="stylesheet" href="/css/msteams-16.css" />
<link rel="stylesheet" href="/css/Custom.css" />
<link rel="stylesheet" href="/css/Site.css" />
<script src="./js/react.js"></script>
<script src="./js/react-dom.js"></script>
<script src="./js/babel.js"></script>
<script src="./js/microsoftTeams.js"></script>
</head>
<body class="surface theme-light">
<div id="reserveSpace" class="panel panel-override"></div>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
reservableBuildings: [],
};
this.makeReservation = this.makeReservation.bind(this);
}
async componentDidMount() {
const {
instanceURL,
} = this.state;
microsoftTeams.initialize();
}
async makeReservation() {
microsoftTeams.tasks.submitTask(
reservationResponse,
"app Id"
);
return true;
}
render() {
return (
<div>
Some code
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("reserveSpace"));
</script>
</body>
</html>
Anything i make to optimize the first load.

render does not return anything

The above query has been solved but there is a new problem. I am using materialize.css for using modal and slider. Now whenever I go to the adminpage they are not working. I just show a grey screen in the slider and the modal is not getting activated. The js initialization is in my index.html which i am sharing below and the admin page which contains the modal and slider code.
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">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See
https://developers.google.com/web/fundamentals/engage-and-retain/web-app-
manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.3/css/materialize.min.css">
<title>React App</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root">
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-
2.1.1.min.js">
</script>
<script type="text/javascript"src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.3/js/materialize.min.js">
</script>
<script>
$(document).ready(function () {
// the "href " attribute of .modal-trigger must specify the modal ID that wants to be triggered
$(".sidenav-trigger").sideNav();
$(".carousel").carousel();
$(".modal-trigger").leanModal();
$('.slider').slider({ full_width: true });
})
</script>
</body>
</html>
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { withRouter } from "react-router-dom";
import { connect } from "react-redux";
import BillForm from "./BillForm";
import { addBill } from "../actions/Bill";
import AddBillerForm from "./AddBillerForm";
import { addBiller } from "../actions/Biller";
import Image from "../images/main.jpg";
import Image3 from "../images/Photo3.jpg";
import Footer from "./Footer";
import { fetchAdmin, adminLogout } from "../actions/Admin";
import Slider from "./Slider";
class AdminPage extends Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.dispatch(fetchAdmin());
}
onLogout() {
this.props.dispatch(adminLogout());
this.props.history.push("/");
}
render() {
if (this.props.Admin.length < 1) {
return <div>No data</div>;
}
if (this.props.Admin.length >= 1) {
if (!this.props.Admin[0].Login) {
return <div>Not logged in as admin</div>;
}
if (this.props.Admin[0].Login) {
return (
<div>
<nav>
<div className="nav-wrapper">
<Link to="/adminpage">
<h3 className="left brand-logo">Bill Payment</h3>
</Link>
<ul className="right">
<li>
<Link className="btn-small" to="viewbiller">
View Biller
</Link>
</li>
<li>
<Link className="btn-small modal-trigger" to="#modal2">
Add Biller
</Link>
</li>
<li>
<Link className="btn-small" to="/generatedbills">
Generated Bills List
</Link>
</li>
<li>
<Link className="btn-small modal-trigger" to="#modal1">
Generate New Bill
</Link>
</li>
<li>
<button className="btn-small btn-flat teal">
Top Bill Payments
</button>
</li>
<li>
<button
className="btn-small btn-flat white-text"
onClick={e => this.onLogout()}
>
Logout
</button>
</li>
</ul>
</div>
</nav>
<div id="modal1" className="modal">
<div className="modal-content">
<div>
<p>Generate New Bill for User</p>
<BillForm
onSubmit={(bill = {}) => {
this.props.dispatch(addBill(bill));
this.props.history.push("/adminpage");
}}
/>
</div>
</div>
<div className="modal-footer red lighten-2">
<Link
to="#!"
className=" modal-action modal-close waves-effect waves-green
btn-flat"
>
Close
</Link>
</div>
</div>
<div id="modal2" className="modal">
<div className="modal-content">
<div className="">
<div className="green white-text">
<h3>Add Biller</h3>
</div>
<AddBillerForm
onSubmit={(biller = {}) => {
this.props.dispatch(addBiller(biller));
}}
/>
</div>
</div>
<div className="modal-footer red lighten-2">
<a
href="#!"
className=" modal-action modal-close waves-effect waves-green
btn-flat"
>
Close
</a>
</div>
</div>
<div>
<Slider />
</div>
<Footer />
</div>
);
}
}
}
}
const mapStateToProps = state => {
return { Admin: state.Admin };
};
export default withRouter(connect(mapStateToProps)(AdminPage));
All of your return statement are in if-statements at the moment. React always expects a return statement in the render. When none of your if-statement return true you don't have any return statement. You should add a return statement at the end of your component which returns an empty jsx element or a loading icon.
Try adding the following code on the end of your render method(should be line 127, not 100% sure): return <span> ...loading </span>

Bootstrap Modal Windows in NodeJS

I am developing a dashboard website in NodeJS and MongoDB. In one of the page, I have to open an image in the modal window. Following is the code of that page.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tor Modal Check</title>
<link rel="stylesheet" href="css/style.default.css" type="text/css" />
<link rel="stylesheet" href="css/responsive-tables.css">
<script type="text/javascript" src="js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="js/jquery-migrate-1.1.1.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<script type="text/javascript" src="js/jquery-ui-1.9.2.min.js"></script>
<script type="text/javascript" src="js/modernizr.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/jquery.bxSlider.min.js"></script>
<script type="text/javascript" src="js/jquery.cookie.js"></script>
<script type="text/javascript" src="js/jquery.uniform.min.js"></script>
<script type="text/javascript" src="js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="js/flot/jquery.flot.min.js"></script>
<script type="text/javascript" src="js/jquery.slimscroll.js"></script>
<script type="text/javascript" src="js/flot/jquery.flot.pie.min.js"></script>
<script type="text/javascript" src="js/flot/jquery.flot.resize.min.js"></script>
<script type="text/javascript" src="js/responsive-tables.js"></script>
<script type="text/javascript" src="js/custom.js"></script>
<style type="text/css">
body .modal {
width: 650px;
margin-left: -325px;
}
</style>
</head>
<body>
<div class="mainwrapper">
<div class="rightpanel">
<ul class="commentlist">
<% tor.forEach(function(t){ %>
<li>
<img src="images/screenshot/<%= t.screenshot %>" alt="" style="width: 60px;" class="pull-left" />
<div class="comment-info">
<h4><%= t.url %></h4>
<p><strong>Comments: </strong><%= t.comments %></p>
<div class="container">
<!-- Trigger the modal with a button -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#<%= t.modalid %>">Show Screenshot</button>
<!-- Modal -->
<div class="modal fade" id="<%= t.modalid %>" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title"><%= t.url %></h4>
</div>
<div class="modal-body">
<img src="images/screenshot/<%= t.screenshot %>" height="100%" width="100%">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</li>
<% }) %>
</ul>
</div>
</div>
</body>
The problem that I am facing is that not all "View Screenshot" are clickable. After digging a lot, I figure it's because of "rightpanel" div class.
/*** MAIN PANEL ***/
.rightpanel { margin-left: 260px; background: #f7f7f7; }
.rightpanel:after { clear: both; content: ''; display: block; }
If I remove margin-left: 260px; everything works as expected.
Any idea why this is happening and how to overcome it?
PS. This is not the complete code. Only the code that is significant for this question.
EDIT 1:
It works perfectly fine when i change margin-left: 260px to margin-left: 150px.
Bootstrap modals are already centered and have three sizes (300px for .modal-sm, 600px (default) and 900px for .modal-lg). But, if you need the width to be exactly 650px, you should set the width of .modal-dialog, not .modal. For example:
#media (min-width: 768px)
.modal-dialog {
width: 650px;
}

iron-pages: Page Changed Event

Is there any event that can be captured by a web component when the page is changed, or even a lifecycle callback?
I tried using the attached callback but it doesn't being fired again..
From the parent element of <iron-pages>, you could observe changes to <iron-pages>.selected to monitor the page index/name:
<head>
<base href="https://polygit.org/polymer+1.9.3/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-button/paper-button.html">
<link rel="import" href="iron-pages/iron-pages.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<iron-pages id="pages" selected="{{selected}}">
<div>One</div>
<div>Two</div>
<div>Three</div>
</iron-pages>
<paper-button on-tap="_prev">Prev</paper-button>
<paper-button on-tap="_next">Next</paper-button>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
properties : {
selected: {
type: Number,
value: 0,
observer: '_selectedChanged'
}
},
_selectedChanged: function(newPage, oldPage) {
console.log('<iron-pages>.selected', 'new', newPage, 'old', oldPage);
},
_prev: function() {
this.$.pages.selectPrevious();
},
_next: function() {
this.$.pages.selectNext();
}
});
});
</script>
</dom-module>
</body>
codepen
Or you could setup an event listener for the <iron-pages>.iron-select and <iron-pages>.iron-deselect events in order to watch the selected and deselected elements.
<head>
<base href="https://polygit.org/polymer+1.9.3/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-button/paper-button.html">
<link rel="import" href="iron-pages/iron-pages.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<iron-pages id="pages" selected="0"
on-iron-select="_pageSelected"
on-iron-deselect="_pageDeselected">
<div>One</div>
<div>Two</div>
<div>Three</div>
</iron-pages>
<paper-button on-tap="_prev">Prev</paper-button>
<paper-button on-tap="_next">Next</paper-button>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
_pageSelected: function(e) {
var page = e.detail.item;
console.log('page selected', page);
},
_pageDeselected: function(e) {
var page = e.detail.item;
console.log('page deselected', page);
},
_prev: function() {
this.$.pages.selectPrevious();
},
_next: function() {
this.$.pages.selectNext();
}
});
});
</script>
</dom-module>
</body>
codepen
Or you could configure <iron-pages>.selectedAttribute so that it sets an attribute on the newly and previously selected pages, which you could observe from within the page itself. When the page selection changes, the previously selected page's attribute is set to false, and the newly selected to true.
<head>
<base href="https://polygit.org/polymer+1.9.3/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-button/paper-button.html">
<link rel="import" href="iron-pages/iron-pages.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<iron-pages id="pages" selected="0" selected-attribute="selected">
<x-page data-name="p1">One</x-page>
<x-page data-name="p2">Two</x-page>
<x-page data-name="p3">Three</x-page>
</iron-pages>
<paper-button on-tap="_prev">Prev</paper-button>
<paper-button on-tap="_next">Next</paper-button>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
_prev: function() {
this.$.pages.selectPrevious();
},
_next: function() {
this.$.pages.selectNext();
}
});
});
</script>
</dom-module>
<dom-module id="x-page">
<template>
<content id="content"></content>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-page',
properties: {
selected: {
type: Boolean,
value: false,
observer: '_selectedChanged'
}
},
_selectedChanged: function(selected) {
console.log('<x-page>.sel', this.dataset.name, selected);
}
});
});
</script>
</dom-module>
</body>
codepen
Yes there's the 'iron-select' event. You can create a listener on an element and have it listen for this event.
'iron-activate' is triggered right before the item changes, if you prefer.
Here's the link to all the iron-pages events: https://elements.polymer-project.org/elements/iron-pages#event-iron-activate

Polymer paper-dialog backdrop opacity?

I have a paper-dialog in my Polymer element. I want to make the backdrop opaque, right now it is semi-transparent. I would also like to change the color.
Does anyone know how to do it. I have already tried this css in my custom element:
<style is="custom-style">
--iron-overlay-backdrop-opacity:1;
</style>
<paper-dialog modal></paper-dialog>
But it had no effect.
I also tried
<style is="custom-style">
:host {
--iron-overlay-backdrop-opacity:1;
}
</style>
<paper-dialog modal></paper-dialog>
The iron-overlay-backdrop is appended directly to the document body, outside of your custom element, and due to Polymer's CSS encapsulation, you can't style the backdrop with a <style> from within the element.
However, your element could imperatively style the backdrop with Polymer.updateStyles(...), which updates the styles for all custom elements, including the iron-overlay-backdrop outside your element:
Polymer.updateStyles({
'--iron-overlay-backdrop-background-color': 'red',
'--iron-overlay-backdrop-opacity': '1'
});
<head>
<base href="https://polygit.org/polymer+1.11.1/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-button/paper-button.html">
<link rel="import" href="paper-dialog/paper-dialog.html">
</head>
<body>
<div>Click button for dialog</div>
<x-demo></x-demo>
<dom-module id="x-demo">
<template>
<x-dialog id="blue" backdrop-color="blue" backdrop-opacity="1"></x-dialog>
<x-dialog id="red" backdrop-color="red" backdrop-opacity="0.2"></x-dialog>
<x-dialog id="green" backdrop-color="green" backdrop-opacity="0.5"></x-dialog>
<paper-button on-tap="_openDialog" data-dialog="blue">Blue (opacity 100%)</paper-button>
<paper-button on-tap="_openDialog" data-dialog="red">Red (opacity 20%)</paper-button>
<paper-button on-tap="_openDialog" data-dialog="green">Green (opacity 50%)</paper-button>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-demo',
_openDialog: function(e) {
var dialog = e.target.dataset.dialog;
this.$[dialog].opened = true;
}
})
});
</script>
</dom-module>
<dom-module id="x-dialog">
<template>
<paper-dialog modal with-backdrop opened="{{opened}}">
<div class="buttons">
<paper-button dialog-dismiss>Close</paper-button>
</div>
</paper-dialog>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-dialog',
properties: {
backdropColor: {
type: String,
value: 'green'
},
backdropOpacity: {
type: String,
value: '0.6'
},
opened: {
type: Boolean,
value: false
}
},
observers: ['_updateBackdrop(opened, backdropColor, backdropOpacity)'],
_updateBackdrop: function(opened, color, opacity) {
if (opened && color && opacity) {
Polymer.RenderStatus.afterNextRender(this, function() {
this._setBackdropStyles(color, opacity);
});
}
},
_setBackdropStyles: function(color, opacity) {
Polymer.updateStyles({
'--iron-overlay-backdrop-background-color': color,
'--iron-overlay-backdrop-opacity': opacity
});
}
});
});
</script>
</dom-module>
</body>
codepen
Or to set a fixed static style for all backdrops, use <style is="custom-style"> from the body:
<body>
<style is="custom-style">
iron-overlay-backdrop {
--iron-overlay-backdrop-opacity: 1;
--iron-overlay-backdrop-background-color: green;
}
</style>
<x-dialog></x-dialog>
</body>
<head>
<base href="https://polygit.org/polymer+1.11.1/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="paper-button/paper-button.html">
<link rel="import" href="paper-dialog/paper-dialog.html">
</head>
<body>
<style is="custom-style">
iron-overlay-backdrop {
--iron-overlay-backdrop-opacity: 1;
--iron-overlay-backdrop-background-color: green;
}
</style>
<div>Hello world</div>
<x-dialog></x-dialog>
<dom-module id="x-dialog">
<template>
<paper-dialog modal with-backdrop opened>
<div class="buttons">
<paper-button dialog-dismiss>Close</paper-button>
</div>
</paper-dialog>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({ is: 'x-dialog' });
});
</script>
</dom-module>
</body>
codepen

Resources