Polymer Page with different app-header on home page - polymer-2.x

i'm trying to make difference between home page and other page in polymer 2.0
Home page = With big header and condensed
Other Page = just as usual app-header with small header on the top
what i try to do is using dom-if, i create dom-if with 2 kind of app-header
_isHome(page) {
return page === "view1";
}
app-header#homeHeader {
color: #fff;
height: 500px;
--app-header-background-front-layer: {
background-image: url(../images/Digital-Signage-Slider3a.jpg);
background-size: cover;
background-repeat: no-repeat;
}
;
}
app-header#defaultHeader {
color: #fff;
background-color: var(--app-primary-color);
}
<app-header-layout>
<template is="dom-if" if="[[_isHome(page)]]">
<app-header id="homeHeader" slot="header" condenses reveals effects="parallax-background" style="height: 500px">
<app-toolbar>
<div main-title>My App</div>
<paper-icon-button icon="my-icons:menu" drawer-toggle></paper-icon-button>
</app-toolbar>
</app-header>
</template>
<template is="dom-if" if="[[!_isHome(page)]]">
<app-header id="defaultHeader" slot="header" condenses reveals effects="material">
<app-toolbar>
<div main-title>My App</div>
<paper-icon-button icon="my-icons:menu" drawer-toggle></paper-icon-button>
</app-toolbar>
</app-header>
</template>
<iron-pages selected="[[page]]" attr-for-selected="name" fallback-selection="view404" role="main">
<my-view1 name="view1"></my-view1>
<my-view2 name="view2"></my-view2>
<my-view3 name="view3"></my-view3>
<my-view404 name="view404"></my-view404>
</iron-pages>
</app-header-layout>
and guess what? it worked, but with some space after it, but the space is gone after refreshed hmm..
Home Page with large image condensed header
After click on the 2nd page
After refreshed
any idea?

Revised Solution
I had another go at this because on an app I started yesterday. I think I've a simplier solution, with only one app-header and one app-toolbar.
First I replace the app-header#... styles with these:
.main-title {
color: #fff;
height: 500px;
--app-header-background-front-layer: {
background-image: url(../images/Digital-Signage-Slider3a.jpg);
background-size: cover;
background-repeat: no-repeat;
}
;
}
.condensed-title {
color: #fff;
background-color: var(--app-primary-color);
}
The header and toolbar are now
<app-header-layout id="header" has-scrolling-region>
<app-header class$=[[_getHeaderClass(page)]] slot="header" fixed effects="waterfall">
<app-toolbar>
<template is="dom-if" if=[[_isHome(page)]]>
<div main-title>My App 1</div>
</template>
<template is="dom-if" if=[[!_isHome(page)]]>
<div condensed-title>My App 2 & 3</div>
</template>
<paper-icon-button icon="my-icons:menu" drawer-toggle></paper-icon-button>
</app-toolbar>
</app-header>
...
The function called to set app-header's class is
_getHeaderClass(page) {
return (page === "view1") ? 'main-title' : 'condensed-title';
}
Note that you must still call this.$.header.notifyResize() in _routePageChanged(page).
I've put up a gist of the complete file at my-app-revised.html.
----- former solution -----
Call notifyResize() on the app-header-layout.
If you look at the polymer-starter-kit, give the app-header-layout an id, like id="header":
<app-header-layout id="header" has-scrolling-region>
Then call this.$.header.notifyResize() in _routePageChanged(page):
_routePageChanged(page) {
// If no page was found in the route data, page will be an empty stri.
// Default to 'view1' in that case.
this.page = page || 'view1';
this.$.header.notifyResize();
// Close a non-persistent drawer when the page & route are changed.
if (!this.$.drawer.persistent) {
this.$.drawer.close();
}
}

Related

Navbar transparent in buefy

I am creating a landpaging and I am facing some style difficulties due to lack of practice.
I want to modify the backgroud of the navbar, so I wanted to make the background transparent so that the bottom of the page appears. How can I do this?
enter image description here
<template>
<div class="Shellhub-LP-1280">
<div class="textura Nuvem">
<b-navbar>
<template slot="brand">
<b-navbar-item tag="router-link" :to="{ path: '/' }" transparent="true">
<img
src="https://raw.githubusercontent.com/buefy/buefy/dev/static/img/buefy-logo.png"
alt="Lightweight UI components for Vue.js based on Bulma"
>
<!-- <img src="#/static/logo-inverted.png"> -->
</b-navbar-item>
</template>
...
</b-navbar>
</div>
</div>
</template>
<style>
.Shellhub-LP-1280 {
/* width: 100%; */
height: 2283px;
background-color: #333640;
}
.textura {
/* width: 100%; */
height: 771px;
}
.Nuvem {
width: 100%;
height: 755px;
object-fit: contain;
opacity: 0.9;
float: right;
background: url('../static/nuvem.png');
background-repeat: no-repeat;
background-position: right;
}
Thanks
buefy navbar API:
https://buefy.org/documentation/navbar/#api-view
Passing this props:
<b-navbar :fixed-top="true" :transparent="true" >
Vue docs - components props (recommend to read):
https://v2.vuejs.org/v2/guide/components-props.html
transparent "bug":
Open github issue:
BUG: navbar is-transparent not working .
IMPORTANT: transparent affect navbar items (Not the navbar wrapper himself).
Remove any hover or active background from the navbar items
So add simple CSS styling:
nav.navbar.is-fixed-top {
background: transparent;
}
body top padding issue
I won't find a way to remove body top padding. I added this style:
body{
padding-top: 0px!important;
}
Basic example:
const app = new Vue()
app.$mount('#app')
img.responsive_img{
width: 100%;
height: auto;
}
body{
padding-top: 0px!important;
}
/* change navbar background color */
nav.navbar.is-fixed-top {
background: transparent;
}
<link href="https://unpkg.com/buefy/dist/buefy.min.css" rel="stylesheet"/>
<div id="app">
<b-navbar class="is-link" :fixed-top="true" :transparent="true">
<template slot="brand">
<b-navbar-item tag="router-link" :to="{ path: '/' }">
<img
src="https://raw.githubusercontent.com/buefy/buefy/dev/static/img/buefy-logo.png"
alt="Lightweight UI components for Vue.js based on Bulma"
>
</b-navbar-item>
</template>
<template slot="start">
<b-navbar-item href="#">
Home
</b-navbar-item>
<b-navbar-item href="#">
Documentation
</b-navbar-item>
<b-navbar-dropdown label="Info">
<b-navbar-item href="#">
About
</b-navbar-item>
<b-navbar-item href="#">
Contact
</b-navbar-item>
</b-navbar-dropdown>
</template>
<template slot="end">
<b-navbar-item tag="div">
<div class="buttons">
<a class="button is-primary">
<strong>Sign up</strong>
</a>
<a class="button is-light">
Log in
</a>
</div>
</b-navbar-item>
</template>
</b-navbar>
<header style="min-height: 200vh;">
<img class="responsive_img" src="https://picsum.photos/2000/600"/>
</header>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script src="https://unpkg.com/buefy/dist/buefy.min.js"></script>
Change navbar background color on scroll
only by custom code
See this codepen (I added a class on scroll):
https://codepen.io/ezra_siton/pen/jOPZgmR
Change the background color on scroll her:
nav.navbar.is-fixed-top.isActive{
transition: background-color 0.5s ease;
background: red; /* change color on scroll */
}
Change navbar links color to white (For dark hero) - add "is-link" modifier:
https://bulma.io/documentation/components/navbar/#colors
<b-navbar class="is-link" :fixed-top="true" :transparent="true" >
Remove hover/active
:transparent="true"
Remove any hover or active background from the navbar items.

Why does my v-if not fire when using modals with Vue?

I'm using v-if to control the display of pages in my Vue app. the 'page' data property keeps track of the current page and is updated by button clicks. This works beautifully until I introduce modals, as now when I open a modal and navigate back a couple of pages (using my app's navigation buttons) the page fails to display despite the property being updated correctly.
Here's a simplified example - navigate to page B then C then display Modal 2. Cancel Modal 2, then navigate to Page B and nothing displays (despite the header indicating that the page property is B).
https://jsfiddle.net/fLmq0dxn/1/
I've tried this approach with both bootstrap modals and native js modals but the same problem occurs. No errors reported in the console. I thought it might be wrongly nested divs but I've checked these and put it through a validator.
I realise that my navigation methods are primitive and that the modals probably should be components, but I'm a newbie to Vue, and as far as I understand it my approach 'should' work. Can anyone explain why it doesn't please?
HTML:
<div id="app">
<p>(app.page = {{page}})</p>
<br/>
<div class="page" id="A" v-if="page=='A'">
Page A
<br/>
<button v-on:click="pager('B')">To B</button>
</div>
<div class="page" id="B" v-if="page=='B'">
Page B
<br/>
<button v-on:click="pager('C')">To C</button>
<button v-on:click="modalOpen('mod1')">Modal</button>
</div>
<!-- ************ Modal 1 ************************************ -->
<div id="mod1" class="mod">
<div class="mod-content">
<span class="mod-close" v-on:click="modalClose">×</span>
<h1>Modal 1</h1>
<button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
</div>
</div>
<div class="page" id="C" v-if="page=='C'">
Page C
<br/>
<button v-on:click="pager('B')">To B</button>
<button v-on:click="modalOpen('mod2')">Modal</button>
</div>
<!-- ************ Modal 2 ************************************ -->
<div id="mod2" class="mod">
<div class="mod-content">
<span class="mod-close" v-on:click="modalClose">×</span>
<h1>Modal 2</h1>
<button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
</div>
</div>
</div>
CSS:
/* The Modal (background) */
.mod {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
/* Modal Content/Box */
.mod-content {
background-color: #fefefe;
margin: 20% auto;
padding: 20px;
border: 1px solid #888;
border-radius:8px;
width: 90%;
max-width:800px;
}
/* The Close Button */
.mod-close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.mod-close:hover,
.mod-close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
Javascript:
new Vue({
el: "#app",
data: {
page: "A"
},
methods: {
pager: function(target){
this.page=target;
},
modalOpen: function(modID) {
$('#'+ modID).css('display','block');
},
modalClose: function(){
$('.mod').css('display','none');
}
}
})
Combining Vue with jQuery is risky unfortunately.
In your specific case, it seems like when you try closing your modal, jQuery looks for all elements with "mod" class, but when hiding them, the selection is tampered by Vue and you end up with incorrect elements being hidden (in your case, the content of your page B). Vue is not designed to have another library fiddling with the DOM.
You can "easily" achieve your goal using Vue only. Since you manage your modal by changing their style, you can do something similar with Vue class and/or style binding.
E.g. you could have a class that overrides your display: none, and you conditionally apply that class based on a data, very similarly as you do for your pages. And you could even probably manage your modal with v-if, exactly like you did with your pages.
Example with conditional class: https://jsfiddle.net/jfx8mbya/
Example with modal managed by v-if:
new Vue({
el: "#app",
data: {
page: "A",
modal: null
},
methods: {
pager: function(target) {
this.page = target;
},
modalOpen: function(modID) {
this.modal = modID;
},
modalClose: function() {
this.modal = null;
}
}
})
/* The Modal (background) */
.mod {
/*display: none;*/
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 1;
/* Sit on top */
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: rgb(0, 0, 0);
/* Fallback color */
background-color: rgba(0, 0, 0, 0.4);
/* Black w/ opacity */
}
/* Modal Content/Box */
.mod-content {
background-color: #fefefe;
margin: 20% auto;
padding: 20px;
border: 1px solid #888;
border-radius: 8px;
width: 90%;
max-width: 800px;
}
/* The Close Button */
.mod-close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.mod-close:hover,
.mod-close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<p>(app.page = {{page}})</p>
<br/>
<div class="page" id="A" v-if="page=='A'">
Page A
<br/>
<button v-on:click="pager('B')">To B</button>
</div>
<div class="page" id="B" v-if="page=='B'">
Page B
<br/>
<button v-on:click="pager('C')">To C</button>
<button v-on:click="modalOpen('mod1')">Modal</button>
</div>
<!-- ************ Modal 1 ************************************ -->
<div id="mod1" class="mod" v-if="modal === 'mod1'">
<div class="mod-content">
<span class="mod-close" v-on:click="modalClose">×</span>
<h1>Modal 1</h1>
<button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
</div>
</div>
<div class="page" id="C" v-if="page=='C'">
Page C
<br/>
<button v-on:click="pager('B')">To B</button>
<button v-on:click="modalOpen('mod2')">Modal</button>
</div>
<!-- ************ Modal 2 ************************************ -->
<div id="mod2" class="mod" v-if="modal === 'mod2'">
<div class="mod-content">
<span class="mod-close" v-on:click="modalClose">×</span>
<h1>Modal 2</h1>
<button v-on:click="modalClose" class="btn btn-secondary">Cancel</button>
</div>
</div>
</div>

Can I use Bulma dropdown in Bulma tabs?

I'm using Nuxt.js and Bulma. I'm making navigation using Bulma tabs(https://bulma.io/documentation/components/tabs/).
I wanna insert Bulma dropdown(https://bulma.io/documentation/components/dropdown/#hoverable-or-toggable). But it doesn't work in middle of Tabs.
I know who wanna use Bulma dropdown needs to use javascript, so I use it. But it doesn't work.
How can i fix it?
To get a dropdown working inside Bulma's tabs, you need to adjust the overflow CSS in the tabs div. I'm not sure why I had to set overflow-x and overflow-y to get this working properly, but I did.
When the dropdown is active:
overflow-x : visible;
overflow-y : visible;
When the dropdown is not active, reset to their defaults:
overflow-y : hidden;
overflow-x : auto;
Yes you can with a little amount of fiddling
There are mainly 2 problems :-
Problem 1
As bulma tabs container is flexbox, and the list of tabs are child of this flexbox, the dropdown will not be visible as it overflows out of flexbox container.
If you add overflow-y:visible to tabs container div, scrolling will happen which is not the behaviour we need
Solution
To fix this, the contents to be shown on tab selection should also come inside the tabs container as second child, so that dropdown button/link in list of
tabs has the space to show the dropdown when clicked/hovered.
#tab-container {
flex-direction: column;
height: 500px;
width: 100%
}
#content-child {
flex-grow: 1;
width: 100%
}
#list-child {
flex-grow: 0; //should be set to 0 as it will take up vertical space (it is set to 1 in bulma)
width: 100%;
}
Problem 2
When dropdown is used within bulma tabs, the anchor tags in dropdown gets styled by those specified for anchor tags in tabs.This is one of the main issue.
The dropdown shown thus will be styled very differently.
Solution
Bulma dropdown also allows us to insert div inside.
We can make use of this to overcome problem 1.
Just add this css for divs inside dropdown so as to make it behave like links.
div.dropdown-item.is-active {
background-color: rgba(55, 122, 195, 0.95);
color: #fff;
}
div.dropdown-item {
padding-right: 3rem;
text-align: left;
white-space: nowrap;
width: 100%;
cursor: pointer;
text-decoration: none;
}
div.dropdown-item:hover {
background-color: whitesmoke;
color: #0a0a0a;
}
Complete solution can be seen below and you can change as required for your use case.
div.dropdown-item.is-active {
background-color: rgba(55, 122, 195, 0.95);
color: #fff;
}
div.dropdown-item {
padding-right: 3rem;
text-align: left;
white-space: nowrap;
width: 100%;
cursor: pointer;
text-decoration: none;
}
div.dropdown-item:hover {
background-color: whitesmoke;
color: #0a0a0a;
}
#content-child {
flex-grow: 1;
width: 100%
}
#tab-container {
flex-direction: column;
height: 500px;
width: 100%
}
#list-child {
flex-grow: 0;
width: 100%;
}
<link href="https://cdn.jsdelivr.net/npm/bulma#0.8.1/css/bulma.min.css" rel="stylesheet" />
<div class="tabs is-boxed" id="tab-container">
<ul id="list-child">
<li><a>Pictures</a></li>
<li><a>Music</a></li>
<li><a>Videos</a></li>
<li><a>Documents</a></li>
<li class="dropdown is-active">
<div class="dropdown-trigger">
<a class="has-text-right custom-padding" aria-haspopup="true" aria-controls="dropdown-menu">
Drop Down
</a>
</div>
<div class="dropdown-menu" id="dropdown-menu" role="menu">
<div class="dropdown-content">
<div class="dropdown-item">Dropdown item</div>
<div class=" dropdown-item">Other dropdown item</div>
<div class=" dropdown-item is-active">Active dropdown item</div>
<div class=" dropdown-item">Other dropdown item</div>
<hr class="dropdown-divider" />
<div class=" dropdown-item">With a divider</div>
</div>
</div>
</li>
</ul>
<div id="content-child">
content
</div>
</div>

Transform Based Animation using Vue Transition Wrapper

I'm trying to port some animation implemented mostly through css and little javascript to a Vue component. The animation is simple - user clicks a button and a little panel opens from the bottom of his browser and slides upwards.
I have a working Vue component implemented using the same css and no javascript.
Now, I'm aware of the transition wrapper that Vue provides. But I'm unable to figure out how to get similar functionality using the transition wrapper (if at all).
Can someone help me out here?
// register modal component
Vue.component('modal', {
template: '#modal-template',
props: ['show']
})
// start app
new Vue({
el: '#app',
data: {
showModal: false
}
})
.drawer-wrapper {
position: fixed;
top: 100%;
left: 0;
right: 0;
height: 50%;
z-index: 9998;
transition: transform .3s ease-out;
}
.drawer-wrapper.open {
transform: translateY(-100%);
}
.drawer-container {
height: 100%;
width: 100%;
background-color: white;
}
.drawer-header h3 {
margin-top: 0;
color: #42b983;
}
.drawer-body {
margin: 20px 0;
}
.drawer-default-button {
float: right;
}
<script src="https://unpkg.com/vue#latest/dist/vue.js"></script>
<!-- template for the modal component -->
<script type="text/x-template" id="modal-template">
<div class="drawer-wrapper" :class="{ open: show }">
<div class="drawer-container">
<div class="drawer-header">
<slot name="header">
default header
</slot>
</div>
<div class="drawer-body">
<slot name="body">
default body
</slot>
</div>
<div class="drawer-footer">
<slot name="footer">
default footer
<button class="drawer-default-button" #click="$emit('close')">
OK
</button>
</slot>
</div>
</div>
</div>
</script>
<!-- app -->
<div id="app">
<button id="show-modal" #click="showModal = true">Show Modal</button>
<!-- use the modal component, pass in the prop -->
<modal #close="showModal = false" :show="showModal">
<!--
you can use custom content here to overwrite
default content
-->
<h3 slot="header">custom header</h3>
</modal>
</div>
I got this to work using a transition wrapper, but the code isn't as elegant as I'd expected. Particularly the use of the following attributes in the drawer-wrapper class:
top: 100%;
transform: translateY(-100%);
Fiddle is here
If anyone can simplify the code further, I'd really appreciate it.

Aurelia event bubbling issue (?), behavior different since 1.0

Reproducible via au new (Aurelia CLI), code below.
It worked perfectly before the update to 1.0.
The problem: When hitting the "Close" button, closePopup() is called but immediately afterwards openPopup() as well. The result is, that the popup does not close. Even click.trigger which shouldn't bubble up the event does not solve the problem.
How to solve this? Why has that behavior changed?
app.html
<template>
<div click.delegate="openPopup()" style="border: 1px solid black; width: 100px; height: 100px">
<div show.bind="_expanded">
Foo <button click.trigger="closePopup()">Close</button>
</div>
</div>
</template>
app.ts
export class App {
_expanded;
openPopup() {
this._expanded = true;
console.log("Opened");
}
closePopup() {
this._expanded = false;
console.log("Closed");
}
}
Solution (event.stopPropagation()):
app.html
<template>
<div click.delegate="openPopup()" style="border: 1px solid black; width: 100px; height: 100px">
<div show.bind="_expanded">
Foo <button click.trigger="closePopup($event)">Close</button>
</div>
</div>
</template>
app.ts
// ...
closePopup(event) {
event.stopPropagation();
this._expanded = false;
console.log("Closed");
}
// ...