Following the release of Polymer 1.0, I have tried to update an application I was working on. Despite the quite complete doc provided: https://www.polymer-project.org/1.0/docs/migration.html, I am still encountering some issues, in particular the following one.
I am using paper-menu element along side with the paper-menu-button one.
The goal is to have a standard menu with on each paper-item a paper-menu-button allowing me to customize the corresponding section.
As code is always clearer here an example of what I am trying to achieve (I simplified it by using basic demo from polymer site)
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
<title>paper-menu demo</title>
<script src="./bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="./bower_components/paper-item/paper-item.html">
<link rel="import" href="./bower_components/paper-menu/paper-menu.html">
<link rel="import" href="./bower_components/paper-menu-button/paper-menu-button.html">
<link rel="import" href="./bower_components/paper-menu/paper-submenu.html">
<link rel="import" href="./bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="./bower_components/paper-styles/demo-pages.html">
<style is="custom-style">
paper-item {
--paper-item: {
cursor: pointer;
}
;
}
paper-icon-button{
height: 20px;
width: 20px;
background-color: black;
}
.sublist {
padding-left: 20px;
padding-right: 20px;
}
</style>
</head>
<body unresolved>
<template id="Demo" is="dom-bind">
<h4>Sub-menu</h4>
<div class="horizontal-section">
<paper-menu>
<paper-submenu>
<paper-item class="menu-trigger">
Topics
<span class="flex layout horizontal end-justified">
<paper-menu-button on-tap="test">
<paper-icon-button icon="menu" class="dropdown-trigger"></paper-icon-button>
<paper-menu class="dropdown-content">
<template is="dom-repeat" items="[[letters]]" as="letter">
<paper-item>[[letter]]</paper-item>
</template>
</paper-menu>
</paper-menu-button>
</span>
</paper-item>
<paper-menu class="menu-content sublist">
<paper-item>Topic 1</paper-item>
<paper-item>Topic 2</paper-item>
<paper-item>Topic 3</paper-item>
</paper-menu>
</paper-submenu><paper-item class="menu-trigger">
Faves
<span class="flex layout horizontal end-justified">
<paper-menu-button on-tap="test">
<paper-icon-button icon="menu" class="dropdown-trigger"></paper-icon-button>
<paper-menu class="dropdown-content">
<template is="dom-repeat" items="[[letters]]" as="letter">
<paper-item>[[letter]]</paper-item>
</template>
</paper-menu>
</paper-menu-button>
</span>
</paper-item>
</paper-menu>
</div>
</template>
</body>
<script>
Demo.letters = [
'alpha',
'beta',
'gamma',
'delta',
'epsilon'
];
Demo.test = function(event){
event.stopPropagation();
}
</script>
</html>
Here goes the problem: paper-menu-button does not react anymore as soon as the corresponding paper-item is focused (appears in gray).
I do not understand why the fact to be focused affect the inner paper-menu-button.
I have tried to stop the event bubbling but it does not change anything.
I am not even sure where the problem comes from, paper-menu behavior? Javascript event handling?
If anyone as a clue about what is the problem I could be great! Hoping to have been clear enough.
Finally found the answer: on focus a pseudo element after is displayed on the top of the item.
Once disabled through the --paper-menu-focused-item-after mixin, I can interact normally with my paper-menu-button
Related
I have a side navigation bar with a button to toggle showing just the icons or to show the icons and the text. There are multiple different HTML pages that share this nav bar, so I needed to save the nav bar's state for when you switch to each (Dashboard to Items, Contacts to Dashboard, etc). I do this using the follow code:
var navBar = document.querySelector(".side-bar");
var toggle = document.querySelector(".nav-toggle");
window.onload = () =>
{
let isClosed = localStorage.getItem("navState");
navBar.classList.toggle("nav-is-closed", isClosed);
}
toggle.addEventListener("click", () =>
{
let isClosed = navBar.classList.toggle("nav-is-closed");
localStorage.setItem("navState", isClosed);
});
.side-bar {
position: relative;
background-color: var(--default-back-color);
min-width: 200px;
}
.nav-is-closed {
min-width: inherit;
}
.nav-is-closed a h2 {
display: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="resources/css/styles.css">
<!--Google Fonts-->
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Neucha&family=Poppins:wght#300&display=swap" rel="stylesheet">
<title>Rucksack</title>
</head>
<body>
<header>
<div>
<img src="resources/images/rucksack.png" alt="">
<h1 class="title">Rucksack</h1>
</div>
<div>
<a class="smaller-icon" href="#"><img src="resources/images/gear.png" alt=""></a>
<img src="resources/images/blue-profile.png" alt="">
</div>
</header>
<main>
<section id="main-section">
<nav class="side-bar">
<a class="selected-nav" href="dashboard"><img src="resources/images/house-icon.png" alt=""><h2>Dashboard</h2></a>
<img src="resources/images/item-icon.png" alt=""><h2>Items</h2>
<hr class="nav-break">
<img src="resources/images/contacts-icon.png" alt=""><h2>Contacts</h2>
<hr class="nav-break">
<img src="resources/images/reports-icon.png" alt=""><h2>Reports</h2>
<div class="nav-toggle"><img src="resources/images/arrow-icon.png" alt=""></div>
</nav>
<div class="content">
<strong>Content</strong>
</div>
</section>
</main>
<script src="shell-controls.js"></script>
</body>
</html>
Everything works fine, except when you move to a new page while the nav is open. It closes even though in window.onload, isClosed is false. As far as I know, toggle with force set to false removes the class, but in this case it's still adding it.
As Kaiido said, isClosed was being pulled from localStorage as a string, which caused toggleClass to think the string of "false" was truthy, therefore still adding the 'nav-is-closed' class. Adding JSON.parse when getting isClosed and adding JSON.stringify when setting isClosed in localStorage solves the problem.
I'm trying to use get this tab bar from Material Components: https://material.io/develop/web/components/tabs/tab-bar/
I'm having trouble following the installation steps. This is what I have so far:
tab.html:
<html lang="en">
<head>
<!-- Required meta tags always come first -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="tab.css">
</head>
<body>
<div class="mdc-tab-bar" role="tablist">
<div class="mdc-tab-scroller">
<div class="mdc-tab-scroller__scroll-area">
<div class="mdc-tab-scroller__scroll-content">
<button class="mdc-tab mdc-tab--active" role="tab" aria-selected="true" tabindex="0">
<span class="mdc-tab__content">
<span class="mdc-tab__icon material-icons" aria-hidden="true">favorite</span>
<span class="mdc-tab__text-label">Favorites</span>
<span class="mdc-tab__text-label">Favorites2</span>
<span class="mdc-tab__text-label">Favorites3</span>
</span>
<span class="mdc-tab-indicator mdc-tab-indicator--active">
<span class="mdc-tab-indicator__content mdc-tab-indicator__content--underline"></span>
</span>
<span class="mdc-tab__ripple"></span>
</button>
</div>
</div>
</div>
</div>
</body>
</html>
tab.css:
<style lang="scss">
#import "#material/tab-bar/mdc-tab-bar";
#import "#material/tab-scroller/mdc-tab-scroller";
#import "#material/tab-indicator/mdc-tab-indicator";
#import "#material/tab/mdc-tab";
body{
background-color: blue;
}
#app
{
main
{
margin-top:65px;
}
div.mdc-layout-app--main-container{ display: block !important;}
div.mdc-layout-app
{
max-width: 1000px;
background-color: white !important;
margin: 0 auto;
}
header.mdc-top-app-bar
{
max-width: 1000px;
}
}
</style>
import {MDCTabBar} from '#material/tab-bar';
const tabBar = new MDCTabBar(document.querySelector('.mdc-tab-bar'));
I want it to look like the demo, but right now it looks like something completely different. I was wondering if someone could break down these steps more for me as I'm extremely confused. Thanks. All help is appreciated.
This is what it looks like: enter image description here
I wanted it to look like this: enter image description here
Are you trying to run SCSS in the browser? If so, this is the problem. The "CSS" portion of your code is actually SCSS, a nested syntax that needs to be compiled down to regular CSS in order for the browser to be able to read it. For example:
SCSS (Browser cannot read)
#app {
main {
margin-top: 65px;
}
}
CSS (Works fine)
#app main {
margin-top: 65px;
}
Material should provide plain CSS version for you, otherwise you will need to use a compiler.
To add on Simran his answer:
I see no <script src="app.js"></script> in your HTML.
You need to compile the code below using babel and include the output file in your HTML.
import {MDCTabBar} from '#material/tab-bar';
const tabBar = new MDCTabBar(document.querySelector('.mdc-tab-bar'));
If it is unclear how you do this re-read the Getting started
Step 3: Webpack with ES2015 is about compiling JavaScript using Babel
I am using the js-mindmap library for a different kind of use, I need to allow a selection to link to extrenal/internal pages on some links but need others to bubble into a bullet list (preferably withing the same css shape as the rest of the mindmap.) I was initially looking at getting the content for the alert from the title or alt tags but not sure if they will retain the ul and li needed without defaulting to the mindmap format...
I'm searching for more of a more simplistic way to accomplish this. I'm sure css is most likely the best practice and I need to pull the content from the html for ease of creating different modles.
here is JSFiddle MindMp
html:
<!DOCTYPE html>
<html>
<head>
<!-- Computer Medic 2016
NOTE: http://stackoverflow.com/questions/15352556/links-not-working-on-js-mindmap
-->
<title>ALS Mindmap</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" type="text/css" href="mindmap/js-mindmap.css" />
<link href="mindmap/style.css" type="text/css" rel="stylesheet"/>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<!-- UI, for draggable nodes -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js"></script>
<!-- Raphael for SVG support (won't work on android) -->
<script type="text/javascript" src="mindmap/raphael-min.js"></script>
<!-- Mindmap -->
<script type="text/javascript" src="mindmap/js-mindmap.js"></script>
<!-- Kick everything off -->
<script src="mindmap/script.js" type="text/javascript"></script>
<style>
.alert {
padding: 20px;
background-color: #f44336;
color: white;
}
.closebtn {
margin-left: 15px;
color: white;
font-weight: bold;
float: right;
font-size: 22px;
line-height: 20px;
cursor: pointer;
transition: 0.3s;
}
.closebtn:hover {
color: black;
}
</style>
</head>
<body>
<ul>
<li>ALS
<ul>
<li>Chest Pain</li>
<li>Shortness of Breath</li>
<li>Allergic Reaction</li>
<li>Diabetic</li>
<li>STEMI
<ul>
<li>ACS</li>
<li>STEMI
<ul>
<li>Treatment</li>
<li>Protocol</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<div class="alert">
<span class="closebtn" onclick="this.parentElement.style.display='none';">×</span>
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
</div>
</body>
</html>
Here you go my friend, it's a bit hacky but it works. I made several modifications to the plugin itself as well as your styles and html.
The plugin was taking your anchor tags, stripping everything and creating them anew. I had to make sure my new attribute data-content was being preserved. Now the plugin checks if a link has this attribute and if it does, it doesn't fire the click event.
Then, I assigned my own click handler to replace content of the alert div and subsequently show it:
$('a').click(function(e){
var tag = $(this).attr('data-content');
if(tag)
{
$('.alert .content').html(content[tag]).parent().show();
}
});
If you have any questions, let me know.
https://jsfiddle.net/x8826shn/7/
I want to create quick prototypes of Polymer elements in a sandbox like JSFiddle or JavaScript Bin, but I can't get it working!
Yes, you can, thanks to polygit.
Here's a boilerplate example you can fork: https://jsfiddle.net/kaycebasques/2q3fqehz/
HTML:
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<dom-module id="x-example">
<template>
<style>
:host {
display: block;
}
</style>
<h1>polyfiddle</h1>
</template>
</dom-module>
<x-example></x-example>
JS:
// only need this when in the main document and on non-Chrome
addEventListener('WebComponentsReady', function() {
Polymer({
is: 'x-example'
});
});
I have created one simple polymer custom element for menu.
I know, already polymer is having element for creating menu, but I am creating one component which will show menu on your website.
Now, here is my menu.html (custom element)
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-header-panel/core-header-panel.html">
<link rel="import" href="../bower_components/core-toolbar/core-toolbar.html">
<link rel="import" href="../bower_components/core-menu/core-menu.html">
<link rel="import" href="../bower_components/core-item/core-item.html">
<link rel="import" href="../bower_components/core-header-panel/core-header-panel.html">
<link rel="import" href="../bower_components/core-drawer-panel/core-drawer-panel.html">
<link rel="import" href="../bower_components/core-icons/core-icons.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<polymer-element name="my-menu">
<template>
<style>
core-header-panel {
background: white;
}
core-toolbar {
background-color: #03A9F4;
}
#navheader {
background-color: #56BA89;
}
.content {
padding: 20px;
}
/* drawer is always visible on a wide screen
so menu button isn't required */
core-drawer-panel:not([narrow]) #navicon {
display: none;
}
</style>
<core-drawer-panel id="drawerPanel">
<core-header-panel drawer>
<core-toolbar id="navheader">
<span>Menu</span>
</core-toolbar>
<core-menu>
<core-item label="One"></core-item>
<core-item label="Two"></core-item>
</core-menu>
</core-header-panel>
<core-header-panel main>
<core-toolbar id="mainheader">
<paper-icon-button id="navicon" icon="menu" on-click="{{togglemenu}}"></paper-icon-button>
<span flex>Title</span>
</core-toolbar>
<div class="content">
If drawer is hidden, press button to display drawer.
</div>
</core-header-panel>
</core-drawer-panel>
</template>
<script>
Polymer('my-menu', {
ready: function () {
// alert("hello");
},
togglemenu: function () {
var drawerPanel = document.getElementById('drawerPanel');
// drawerPanel.togglePanel();
console.log(drawerPanel);
}
});
</script>
</polymer-element>
Now,
As you can seen till now, that when togglemenu function is called, i want to togglepanel, but i am not able to do that.
anyway to achieve this ?
when you are working inside a custom element you can use the polymer selector to select the element in the shadow dom. that would make your togglemenu function look more like
togglemenu: function () {
var drawerPanel = this.$.drawerPanel;
drawerPanel.togglePanel();
}
in this function this.$.drawerPanel is selecting the same way as document.getElementById('drawerPanel') except getElementById is looking on the document level and not this elements shadow dom.