Added basic onboarding steps
This commit is contained in:
@@ -191,6 +191,7 @@ Schemas.Character = new SimpleSchema({
|
|||||||
"settings.exportFeatures": {type: Boolean, defaultValue: true},
|
"settings.exportFeatures": {type: Boolean, defaultValue: true},
|
||||||
"settings.exportAttacks": {type: Boolean, defaultValue: true},
|
"settings.exportAttacks": {type: Boolean, defaultValue: true},
|
||||||
"settings.exportDescription": {type: Boolean, defaultValue: true},
|
"settings.exportDescription": {type: Boolean, defaultValue: true},
|
||||||
|
"settings.newUserExperience": {type: Boolean, optional: true},
|
||||||
});
|
});
|
||||||
|
|
||||||
Characters.attachSchema(Schemas.Character);
|
Characters.attachSchema(Schemas.Character);
|
||||||
@@ -554,6 +555,10 @@ if (Meteor.isServer){
|
|||||||
});
|
});
|
||||||
Characters.before.insert(function(userId, doc) {
|
Characters.before.insert(function(userId, doc) {
|
||||||
doc.urlName = getSlug(doc.name, {maintainCase: true}) || "-";
|
doc.urlName = getSlug(doc.name, {maintainCase: true}) || "-";
|
||||||
|
// The first character a user creates should have the new user experience
|
||||||
|
if (!Characters.find({owner: userId}).count()){
|
||||||
|
doc.settings.newUserExperience = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
rpg-docs/client/style/bounce.css
Normal file
17
rpg-docs/client/style/bounce.css
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
@keyframes bounce {
|
||||||
|
from {
|
||||||
|
transform: translate(0px,0px);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: translate(0px,-16px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bounce{
|
||||||
|
animation-name: bounce;
|
||||||
|
animation-duration: 0.3s;
|
||||||
|
animation-direction: alternate;
|
||||||
|
animation-timing-function: cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||||
|
animation-delay: 0s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
}
|
||||||
@@ -44,17 +44,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div bottom-item>
|
<div bottom-item>
|
||||||
<paper-tabs id="characterSheetTabs" selected={{selectedTab}} class="{{colorClass}}">
|
<paper-tabs id="characterSheetTabs" selected={{selectedTab}} class="{{colorClass}}">
|
||||||
<paper-tab name="stats">Stats</paper-tab>
|
<paper-tab name="stats" class="{{#if shouldBounce 0}}bounce{{/if}}">Stats</paper-tab>
|
||||||
<paper-tab name="features">Features</paper-tab>
|
<paper-tab name="features" class="{{#if shouldBounce 1}}bounce{{/if}}">Features</paper-tab>
|
||||||
<paper-tab name="inventory">Inventory</paper-tab>
|
<paper-tab name="inventory">Inventory</paper-tab>
|
||||||
{{#unless hideSpellcasting}}
|
{{#unless hideSpellcasting}}
|
||||||
<paper-tab name="spells">Spells</paper-tab>
|
<paper-tab name="spells">Spells</paper-tab>
|
||||||
{{/unless}}
|
{{/unless}}
|
||||||
<paper-tab name="persona">Persona</paper-tab>
|
<paper-tab name="persona">Persona</paper-tab>
|
||||||
<paper-tab name="journal">Journal</paper-tab>
|
<paper-tab name="journal" class="{{#if shouldBounce 5}}bounce{{/if}}">Journal</paper-tab>
|
||||||
</paper-tabs>
|
</paper-tabs>
|
||||||
</div>
|
</div>
|
||||||
</app-toolbar>
|
</app-toolbar>
|
||||||
|
{{#if session "showNewUserExperience"}}{{> newUserStepper}}{{/if}}
|
||||||
</app-header>
|
</app-header>
|
||||||
<div class="flex" style="position: relative;">
|
<div class="flex" style="position: relative;">
|
||||||
<iron-pages id="tabPages" class="fit" selected={{selectedTab}}>
|
<iron-pages id="tabPages" class="fit" selected={{selectedTab}}>
|
||||||
|
|||||||
@@ -29,7 +29,17 @@ Template.characterSheet.onRendered(function() {
|
|||||||
tabFabMenus = _.times(6, (n) =>
|
tabFabMenus = _.times(6, (n) =>
|
||||||
tabPages[n].find(".mini-holder")
|
tabPages[n].find(".mini-holder")
|
||||||
);
|
);
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// New user experience starts on the features tab
|
||||||
|
var settings = Characters.findOne(this.data._id, {
|
||||||
|
fields: {settings: 1}
|
||||||
|
}).settings;
|
||||||
|
if (settings && settings.newUserExperience){
|
||||||
|
Session.set(this.data._id + ".selectedTab", "1");
|
||||||
|
Session.set("showNewUserExperience", true);
|
||||||
|
Session.set("newUserExperienceStep", 0);
|
||||||
|
}
|
||||||
|
|
||||||
//watch this character and make sure their encumbrance is updated
|
//watch this character and make sure their encumbrance is updated
|
||||||
//trackEncumbranceConditions(this.data._id, this);
|
//trackEncumbranceConditions(this.data._id, this);
|
||||||
@@ -172,6 +182,20 @@ Template.characterSheet.helpers({
|
|||||||
var char = Characters.findOne(this._id);
|
var char = Characters.findOne(this._id);
|
||||||
return char && char.settings.hideSpellcasting;
|
return char && char.settings.hideSpellcasting;
|
||||||
},
|
},
|
||||||
|
newUserExperience: function(){
|
||||||
|
var char = Characters.findOne(this._id);
|
||||||
|
return char && char.settings.newUserExperience;
|
||||||
|
},
|
||||||
|
shouldBounce: function(tab){
|
||||||
|
console.log(this._id);
|
||||||
|
const selected = Session.get(this._id + ".selectedTab")
|
||||||
|
const step = Session.get("newUserExperienceStep");
|
||||||
|
console.log({selected, step, tab});
|
||||||
|
if (selected == tab) return false;
|
||||||
|
return (tab === 1 && step === 0) ||
|
||||||
|
(tab === 5 && step === 1) ||
|
||||||
|
(tab === 0 && step === 2);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.characterSheet.events({
|
Template.characterSheet.events({
|
||||||
|
|||||||
@@ -42,9 +42,20 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template name="featureEdit">
|
<template name="featureEdit">
|
||||||
|
{{#if showNewUserExperience}}
|
||||||
|
{{# infoBox}}
|
||||||
|
<p>
|
||||||
|
Features represent all the permanent things your character can do.
|
||||||
|
</p><p>
|
||||||
|
A feature can change a character's stats with effects,
|
||||||
|
or give the character proficiencies, attacks, and buffs.
|
||||||
|
</p><p>
|
||||||
|
Give the feature a name, and close it to continue.
|
||||||
|
</p>
|
||||||
|
{{/infoBox}}
|
||||||
|
{{/if}}
|
||||||
<!--name-->
|
<!--name-->
|
||||||
<paper-input id="featureNameInput" class="fullwidth" label="Name" value={{name}}></paper-input>
|
<paper-input id="featureNameInput" class="fullwidth" label="Name" value={{name}}></paper-input>
|
||||||
|
|
||||||
<div class="layout horizontal center wrap justified">
|
<div class="layout horizontal center wrap justified">
|
||||||
<paper-dropdown-menu class=flex label="Enable Feature" style="flex-basis: 150px; max-width: 200px;">
|
<paper-dropdown-menu class=flex label="Enable Feature" style="flex-basis: 150px; max-width: 200px;">
|
||||||
<dicecloud-selector selected={{enabledSelection}} class="dropdown-content enabled-dropdown">
|
<dicecloud-selector selected={{enabledSelection}} class="dropdown-content enabled-dropdown">
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ Template.featureDetails.events({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Template.featureEdit.helpers({
|
Template.featureEdit.helpers({
|
||||||
|
showNewUserExperience: function(){
|
||||||
|
return Session.get("newUserExperienceStep") === 0;
|
||||||
|
},
|
||||||
usesSet: function(){
|
usesSet: function(){
|
||||||
return _.isString(this.uses);
|
return _.isString(this.uses);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -102,7 +102,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{{#if canEditCharacter _id}}
|
{{#if canEditCharacter _id}}
|
||||||
<paper-fab id="addFeature"
|
<paper-fab id="addFeature"
|
||||||
class="floatyButton"
|
class="floatyButton {{#if shouldFloatyButtonBounce}}bounce{{/if}}"
|
||||||
icon="add">
|
icon="add">
|
||||||
<paper-tooltip position="left">Add Feature</paper-tooltip>
|
<paper-tooltip position="left">Add Feature</paper-tooltip>
|
||||||
</paper-fab>
|
</paper-fab>
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ Template.features.helpers({
|
|||||||
hasCharacters: function(string){
|
hasCharacters: function(string){
|
||||||
return string && string.match(/\S/);
|
return string && string.match(/\S/);
|
||||||
},
|
},
|
||||||
|
shouldFloatyButtonBounce: function(){
|
||||||
|
const step = Session.get("newUserExperienceStep");
|
||||||
|
return step === 0 && Features.find({charId: this._id}).count() <= 1;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.features.events({
|
Template.features.events({
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="bottom list">
|
<div class="bottom list">
|
||||||
<div class="item-slot">
|
<div class="item-slot">
|
||||||
<div class="item race layout horizontal center">
|
<div class="item race layout horizontal center {{#if shouldRaceBounce}}bounce{{/if}}">
|
||||||
{{race}}
|
{{race}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ Template.journal.helpers({
|
|||||||
var char = Characters.findOne(this._id, {fields: {race: 1}});
|
var char = Characters.findOne(this._id, {fields: {race: 1}});
|
||||||
return char && char.race;
|
return char && char.race;
|
||||||
},
|
},
|
||||||
|
shouldRaceBounce: function(){
|
||||||
|
return Session.get("newUserExperienceStep") === 1;
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.journal.events({
|
Template.journal.events({
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
.newUserStepper {
|
||||||
|
height: 300px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newUserStepper paper-step .invalid-step-message {
|
||||||
|
color: #d13b2e;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newUserStepper paper-step[invalid] .invalid-step-message {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<template name="newUserStepper">
|
||||||
|
<paper-stepper linear selected="0" class="newUserStepper">
|
||||||
|
<paper-step id="step0" label="Add a feature">
|
||||||
|
<p>
|
||||||
|
To get started, add a feature
|
||||||
|
</p>
|
||||||
|
</paper-step>
|
||||||
|
<paper-step id="step1" label="Add an effect">
|
||||||
|
<p>
|
||||||
|
Add a racial effect to set your speed
|
||||||
|
</p>
|
||||||
|
</paper-step>
|
||||||
|
<paper-step id="step2" label="See the effect in action">
|
||||||
|
<p>
|
||||||
|
View your speed stat
|
||||||
|
</p>
|
||||||
|
</paper-step>
|
||||||
|
<paper-step id="step3" label="Finish">
|
||||||
|
If you get stuck, be sure to check out the guide, or ask for help using the feedback form.
|
||||||
|
</paper-step>
|
||||||
|
</paper-stepper>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="newUserStepperPlaceholder">
|
||||||
|
<div style="height: 300px"></div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
Template.newUserStepper.onRendered(function(){
|
||||||
|
let stepper = this.find("paper-stepper");
|
||||||
|
this.autorun((c) => {
|
||||||
|
var step = Session.get("newUserExperienceStep");
|
||||||
|
var hasFeatures = Features.find({charId: this.data._id}).count() > 1
|
||||||
|
if (step === 0 && hasFeatures){
|
||||||
|
stepper.continue();
|
||||||
|
c.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.autorun((c) => {
|
||||||
|
var step = Session.get("newUserExperienceStep");
|
||||||
|
var hasEffect = !!Effects.find({
|
||||||
|
charId: this.data._id,
|
||||||
|
stat: "speed",
|
||||||
|
}).count();
|
||||||
|
if (step === 1 && hasEffect){
|
||||||
|
stepper.continue();
|
||||||
|
c.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.autorun((c) => {
|
||||||
|
var step = Session.get("newUserExperienceStep");
|
||||||
|
if (step === 2 && Session.get("viewedSpeed")){
|
||||||
|
stepper.continue();
|
||||||
|
c.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.newUserStepper.events({
|
||||||
|
"paper-stepper-progressed paper-stepper": function(event, template){
|
||||||
|
const step = template.find("paper-stepper").selected;
|
||||||
|
Session.set("newUserExperienceStep", step);
|
||||||
|
},
|
||||||
|
"paper-stepper-completed paper-stepper": function(event, template){
|
||||||
|
Session.set("newUserExperienceStep", undefined);
|
||||||
|
Session.set("showNewUserExperience", undefined);
|
||||||
|
Characters.update(this._id, {$unset: {"settings.newUserExperience": 1}});
|
||||||
|
},
|
||||||
|
});
|
||||||
15
rpg-docs/client/views/paperTemplates/infoBox/infoBox.css
Normal file
15
rpg-docs/client/views/paperTemplates/infoBox/infoBox.css
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
.infoBox iron-icon {
|
||||||
|
color: #747474;
|
||||||
|
color: rgba(0,0,0,0.54);
|
||||||
|
height: 32px;
|
||||||
|
width: 32px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoBox > div > p {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoBox > div > p + p {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
10
rpg-docs/client/views/paperTemplates/infoBox/infoBox.html
Normal file
10
rpg-docs/client/views/paperTemplates/infoBox/infoBox.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<template name="infoBox">
|
||||||
|
<div class="layout horizontal center infoBox">
|
||||||
|
<div>
|
||||||
|
<iron-icon icon="info-outline"></iron-icon>
|
||||||
|
</div>
|
||||||
|
<div class="flex">
|
||||||
|
{{> Template.contentBlock}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -49,6 +49,7 @@
|
|||||||
"/custom_components/dicecloud-wrapper/dicecloud-wrapper.html",
|
"/custom_components/dicecloud-wrapper/dicecloud-wrapper.html",
|
||||||
"/custom_components/paper-checkbox/paper-checkbox.html",
|
"/custom_components/paper-checkbox/paper-checkbox.html",
|
||||||
"/custom_components/paper-diff-slider/paper-diff-slider.html",
|
"/custom_components/paper-diff-slider/paper-diff-slider.html",
|
||||||
|
"/custom_components/paper-stepper/paper-stepper.html",
|
||||||
"/custom_components/app-theme.html"
|
"/custom_components/app-theme.html"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ AccountsTemplates.configure({
|
|||||||
//behaviour
|
//behaviour
|
||||||
confirmPassword: true,
|
confirmPassword: true,
|
||||||
enablePasswordChange: true,
|
enablePasswordChange: true,
|
||||||
enforceEmailVerification: true,
|
enforceEmailVerification: false,
|
||||||
overrideLoginErrors: false,
|
overrideLoginErrors: false,
|
||||||
sendVerificationEmail: true,
|
sendVerificationEmail: true,
|
||||||
lowercaseUsername: true,
|
lowercaseUsername: true,
|
||||||
@@ -21,35 +21,35 @@ AccountsTemplates.configure({
|
|||||||
|
|
||||||
AccountsTemplates.configureRoute("changePwd", {
|
AccountsTemplates.configureRoute("changePwd", {
|
||||||
template: "titledAtForm",
|
template: "titledAtForm",
|
||||||
layoutTemplate: 'layout',
|
layoutTemplate: "layout",
|
||||||
});
|
});
|
||||||
AccountsTemplates.configureRoute("enrollAccount", {
|
AccountsTemplates.configureRoute("enrollAccount", {
|
||||||
template: "titledAtForm",
|
template: "titledAtForm",
|
||||||
layoutTemplate: 'layout',
|
layoutTemplate: "layout",
|
||||||
});
|
});
|
||||||
AccountsTemplates.configureRoute("forgotPwd", {
|
AccountsTemplates.configureRoute("forgotPwd", {
|
||||||
template: "titledAtForm",
|
template: "titledAtForm",
|
||||||
layoutTemplate: 'layout',
|
layoutTemplate: "layout",
|
||||||
});
|
});
|
||||||
AccountsTemplates.configureRoute("resetPwd", {
|
AccountsTemplates.configureRoute("resetPwd", {
|
||||||
template: "titledAtForm",
|
template: "titledAtForm",
|
||||||
layoutTemplate: 'layout',
|
layoutTemplate: "layout",
|
||||||
});
|
});
|
||||||
AccountsTemplates.configureRoute("signIn", {
|
AccountsTemplates.configureRoute("signIn", {
|
||||||
template: "titledAtForm",
|
template: "titledAtForm",
|
||||||
layoutTemplate: 'layout',
|
layoutTemplate: "layout",
|
||||||
});
|
});
|
||||||
AccountsTemplates.configureRoute("signUp", {
|
AccountsTemplates.configureRoute("signUp", {
|
||||||
template: "titledAtForm",
|
template: "titledAtForm",
|
||||||
layoutTemplate: 'layout',
|
layoutTemplate: "layout",
|
||||||
});
|
});
|
||||||
AccountsTemplates.configureRoute("verifyEmail", {
|
AccountsTemplates.configureRoute("verifyEmail", {
|
||||||
template: "titledAtForm",
|
template: "titledAtForm",
|
||||||
layoutTemplate: 'layout',
|
layoutTemplate: "layout",
|
||||||
});
|
});
|
||||||
AccountsTemplates.configureRoute("resendVerificationEmail", {
|
AccountsTemplates.configureRoute("resendVerificationEmail", {
|
||||||
template: "titledAtForm",
|
template: "titledAtForm",
|
||||||
layoutTemplate: 'layout',
|
layoutTemplate: "layout",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Meteor.isServer){
|
if (Meteor.isServer){
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<!--
|
||||||
|
@license
|
||||||
|
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
||||||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||||
|
Code distributed by Google as part of the polymer project is also
|
||||||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||||
|
-->
|
||||||
|
|
||||||
|
<link rel="import" href="../../../components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../../../components/neon-animation/neon-animation-behavior.html">
|
||||||
|
<link rel="import" href="../../../components/neon-animation/web-animations.html">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
|
||||||
|
is: 'fade-in-slide-from-left-animation',
|
||||||
|
|
||||||
|
behaviors: [
|
||||||
|
Polymer.NeonAnimationBehavior
|
||||||
|
],
|
||||||
|
|
||||||
|
configure: function(config) {
|
||||||
|
var node = config.node;
|
||||||
|
|
||||||
|
this._effect = new KeyframeEffect(node, [
|
||||||
|
{'transform': 'translateX(-100%)', 'opacity': '0'},
|
||||||
|
{'transform': 'translateX(-50%)', 'opacity': '0'},
|
||||||
|
{'transform': 'none', 'opacity': '1'}
|
||||||
|
], this.timingFromConfig(config));
|
||||||
|
|
||||||
|
if (config.transformOrigin) {
|
||||||
|
this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
|
||||||
|
} else {
|
||||||
|
this.setPrefixedProperty(node, 'transformOrigin', '0 50%');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<!--
|
||||||
|
@license
|
||||||
|
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
||||||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||||
|
Code distributed by Google as part of the polymer project is also
|
||||||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||||
|
-->
|
||||||
|
|
||||||
|
<link rel="import" href="../../../components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../../../components/neon-animation/neon-animation-behavior.html">
|
||||||
|
<link rel="import" href="../../../components/neon-animation/web-animations.html">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
|
||||||
|
is: 'fade-in-slide-from-right-animation',
|
||||||
|
|
||||||
|
behaviors: [
|
||||||
|
Polymer.NeonAnimationBehavior
|
||||||
|
],
|
||||||
|
|
||||||
|
configure: function(config) {
|
||||||
|
var node = config.node;
|
||||||
|
|
||||||
|
this._effect = new KeyframeEffect(node, [
|
||||||
|
{'transform': 'translateX(100%)', 'opacity': '0'},
|
||||||
|
{'transform': 'translateX(50%)', 'opacity': '0'},
|
||||||
|
{'transform': 'none', 'opacity': '1'}
|
||||||
|
], this.timingFromConfig(config));
|
||||||
|
|
||||||
|
if (config.transformOrigin) {
|
||||||
|
this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
|
||||||
|
} else {
|
||||||
|
this.setPrefixedProperty(node, 'transformOrigin', '0 50%');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<!--
|
||||||
|
@license
|
||||||
|
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
||||||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||||
|
Code distributed by Google as part of the polymer project is also
|
||||||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||||
|
-->
|
||||||
|
|
||||||
|
<link rel="import" href="../../../components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../../../components/neon-animation/neon-animation-behavior.html">
|
||||||
|
<link rel="import" href="../../../components/neon-animation/web-animations.html">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
|
||||||
|
is: 'fade-out-slide-left-animation',
|
||||||
|
|
||||||
|
behaviors: [
|
||||||
|
Polymer.NeonAnimationBehavior
|
||||||
|
],
|
||||||
|
|
||||||
|
configure: function(config) {
|
||||||
|
var node = config.node;
|
||||||
|
|
||||||
|
this._effect = new KeyframeEffect(node, [
|
||||||
|
{'transform': 'none', 'opacity': '1'},
|
||||||
|
{'transform': 'translateX(-50%)', 'opacity': '0'},
|
||||||
|
{'transform': 'translateX(-100%)', 'opacity': '0'},
|
||||||
|
], this.timingFromConfig(config));
|
||||||
|
|
||||||
|
if (config.transformOrigin) {
|
||||||
|
this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
|
||||||
|
} else {
|
||||||
|
this.setPrefixedProperty(node, 'transformOrigin', '0 50%');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<!--
|
||||||
|
@license
|
||||||
|
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
|
||||||
|
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
|
||||||
|
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
|
||||||
|
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
|
||||||
|
Code distributed by Google as part of the polymer project is also
|
||||||
|
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
|
||||||
|
-->
|
||||||
|
|
||||||
|
<link rel="import" href="../../../components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../../../components/neon-animation/neon-animation-behavior.html">
|
||||||
|
<link rel="import" href="../../../components/neon-animation/web-animations.html">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
|
||||||
|
is: 'fade-out-slide-right-animation',
|
||||||
|
|
||||||
|
behaviors: [
|
||||||
|
Polymer.NeonAnimationBehavior
|
||||||
|
],
|
||||||
|
|
||||||
|
configure: function(config) {
|
||||||
|
var node = config.node;
|
||||||
|
|
||||||
|
this._effect = new KeyframeEffect(node, [
|
||||||
|
{'transform': 'none', 'opacity': '1'},
|
||||||
|
{'transform': 'translateX(50%)', 'opacity': '1'},
|
||||||
|
{'transform': 'translateX(100%)', 'opacity': '0'}
|
||||||
|
], this.timingFromConfig(config));
|
||||||
|
|
||||||
|
if (config.transformOrigin) {
|
||||||
|
this.setPrefixedProperty(node, 'transformOrigin', config.transformOrigin);
|
||||||
|
} else {
|
||||||
|
this.setPrefixedProperty(node, 'transformOrigin', '0 50%');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
48
rpg-docs/public/custom_components/paper-stepper/bower.json
Normal file
48
rpg-docs/public/custom_components/paper-stepper/bower.json
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"name": "paper-stepper",
|
||||||
|
"version": "2.0-beta.5",
|
||||||
|
"authors": [
|
||||||
|
"Zecat <jullienfelix@gmail.com>"
|
||||||
|
],
|
||||||
|
"description": "Material paper-stepper element.",
|
||||||
|
"keywords": [
|
||||||
|
"web-component",
|
||||||
|
"polymer",
|
||||||
|
"seed"
|
||||||
|
],
|
||||||
|
"main": "paper-stepper.html",
|
||||||
|
"license": "http://polymer.github.io/LICENSE.txt",
|
||||||
|
"homepage": "https://github.com/zecat/paper-stepper/",
|
||||||
|
"ignore": [
|
||||||
|
"/.*",
|
||||||
|
"/test/"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"polymer": "Polymer/polymer#^1.2.0",
|
||||||
|
"paper-button": "PolymerElements/paper-button#^1.0.11",
|
||||||
|
"iron-icons": "PolymerElements/iron-icons#^1.1.3",
|
||||||
|
"paper-styles": "PolymerElements/paper-styles#^1.1.4",
|
||||||
|
"paper-ripple": "PolymerElements/paper-ripple#^1.0.5",
|
||||||
|
"iron-selector": "PolymerElements/iron-selector#^1.3.0",
|
||||||
|
"iron-icon": "PolymerElements/iron-icon#^1.0.8",
|
||||||
|
"iron-flex-layout": "PolymerElements/iron-flex-layout#^1.3.1",
|
||||||
|
"neon-animation": "PolymerElements/neon-animation#^1.1.1",
|
||||||
|
"iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.5",
|
||||||
|
"iron-collapse": "PolymerElements/iron-collapse#^1.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"paper-input": "PolymerElements/paper-input#^1.1.10",
|
||||||
|
"paper-material": "PolymerElements/paper-material#^1.0.6",
|
||||||
|
"iron-component-page": "PolymerElements/iron-component-page#^1.0.0",
|
||||||
|
"web-component-tester": "*",
|
||||||
|
"iron-form": "PolymerElements/iron-form#^1.0.16",
|
||||||
|
"iron-demo-helpers": "PolymerElements/iron-demo-helpers#^1.2.2",
|
||||||
|
"paper-toggle-button": "PolymerElements/paper-toggle-button#^1.2.0",
|
||||||
|
"app-layout": "PolymerElements/app-layout#^0.10.2",
|
||||||
|
"paper-menu": "PolymerElements/paper-menu#^1.2.2",
|
||||||
|
"iron-scroll-spy": "Zecat/iron-scroll-spy#^2.1.0",
|
||||||
|
"paper-item": "PolymerElements/paper-item#^1.2.1",
|
||||||
|
"paper-toast": "PolymerElements/paper-toast#^1.3.0",
|
||||||
|
"paper-checkbox": "PolymerElements/paper-checkbox#^1.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
27
rpg-docs/public/custom_components/paper-stepper/hero.svg
Normal file
27
rpg-docs/public/custom_components/paper-stepper/hero.svg
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 225 126" enable-background="new 0 0 225 126" xml:space="preserve">
|
||||||
|
<g id="background" display="none">
|
||||||
|
<rect display="inline" fill="#B0BEC5" width="225" height="126"/>
|
||||||
|
</g>
|
||||||
|
<g id="label">
|
||||||
|
</g>
|
||||||
|
<g id="art">
|
||||||
|
<g id="ic_x5F_add_x0D_">
|
||||||
|
</g>
|
||||||
|
<circle cx="78" cy="98" r="4"/>
|
||||||
|
<circle cx="171" cy="90" r="4"/>
|
||||||
|
<circle cx="132" cy="61" r="4"/>
|
||||||
|
<circle cx="53" cy="61" r="4"/>
|
||||||
|
<circle cx="126" cy="28" r="4"/>
|
||||||
|
<circle cx="91" cy="67" r="4"/>
|
||||||
|
<circle cx="132" cy="90" r="4"/>
|
||||||
|
<circle cx="65" cy="32" r="4"/>
|
||||||
|
<path d="M77.7,99.4L51.9,61.1L64.3,31l64.1-4.2L92.6,66.7l16.1,9l23.3-16L174,91h-42.3l-23-12.9L77.7,99.4z M54.1,60.9l24.1,35.7
|
||||||
|
L106.8,77l-17.4-9.8l34.2-38.1L65.7,33L54.1,60.9z M132.3,89H168l-36-26.8l-21.4,14.6L132.3,89z"/>
|
||||||
|
</g>
|
||||||
|
<g id="Guides">
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
424
rpg-docs/public/custom_components/paper-stepper/paper-step.html
Normal file
424
rpg-docs/public/custom_components/paper-stepper/paper-step.html
Normal file
@@ -0,0 +1,424 @@
|
|||||||
|
<link rel="import" href="../../components/iron-validatable-behavior/iron-validatable-behavior.html">
|
||||||
|
<link rel="import" href="../../components/paper-item/paper-item-behavior.html">
|
||||||
|
<link rel="import" href="../../components/paper-behaviors/paper-ripple-behavior.html">
|
||||||
|
<link rel="import" href="../../components/neon-animation/neon-animatable-behavior.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/default-theme.html">
|
||||||
|
<link rel="import" href="step-horizontal-label.html">
|
||||||
|
<link rel="import" href="step-vertical.html">
|
||||||
|
<link rel="import" href="../../components/polymer/polymer.html">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Missing Doc
|
||||||
|
@element paper-step
|
||||||
|
@demo demo/index.html
|
||||||
|
@hero hero.svg
|
||||||
|
-->
|
||||||
|
<dom-module id="paper-step">
|
||||||
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
:host(:not([vertical])) {
|
||||||
|
overflow: hidden;
|
||||||
|
@apply(--layout);
|
||||||
|
@apply(--layout-flex);
|
||||||
|
}
|
||||||
|
:host(:not([vertical])[opened]){
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
:host(:not([opened]):not(.neon-animating)) #slideshowViewport{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#slideshowViewport {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 42px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#contentWrapper {
|
||||||
|
padding: 16px 0 16px 16px;
|
||||||
|
@apply(--layout-scroll);
|
||||||
|
@apply(--layout-fit);
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
:host(:focus:not([opened]):not([saved])) step-horizontal-label ::content #badge {
|
||||||
|
background: var(--paper-step-selectable-hovered-badge-background, --paper-grey-500);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- horizontal step layout -->
|
||||||
|
|
||||||
|
<template is="dom-if" if="[[!vertical]]">
|
||||||
|
<step-horizontal-label id="horizontalStepLabel" editable="[[editable]]" label="[[label]]"
|
||||||
|
alternative-label="[[_alternativeLabel]]" optional="[[optional]]"
|
||||||
|
opened="[[opened]]" selectable="[[selectable]]" index="[[index]]"
|
||||||
|
saved="[[saved]]" stepper-data="[[_stepperData]]">
|
||||||
|
</step-horizontal-label>
|
||||||
|
<div id="slideshowViewport">
|
||||||
|
<div id="contentWrapper">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- vertical step layout -->
|
||||||
|
|
||||||
|
<template is="dom-if" if="[[vertical]]">
|
||||||
|
<step-vertical id="verticalStepLabel" editable="[[editable]]" label="[[label]]"
|
||||||
|
optional="[[optional]]" opened="[[opened]]"
|
||||||
|
selectable="[[selectable]]" stepper-data="[[_stepperData]]" index="[[index]]"
|
||||||
|
saved="[[saved]]" _attr-for-primary-button-text="[[_attrForPrimaryButtonText]]"
|
||||||
|
can-skip="[[_canSkip]]" has-back-step="[[_hasBackStep]]">
|
||||||
|
</step-vertical>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
|
||||||
|
is: 'paper-step',
|
||||||
|
|
||||||
|
behaviors: [
|
||||||
|
Polymer.IronValidatableBehavior,
|
||||||
|
Polymer.NeonAnimatableBehavior,
|
||||||
|
Polymer.PaperItemBehavior,
|
||||||
|
Polymer.PaperRippleBehavior
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when the step has been saved.
|
||||||
|
*
|
||||||
|
* @event paper-step-saved
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Fired when the step has been updated
|
||||||
|
*
|
||||||
|
* @event paper-step-updated
|
||||||
|
*/
|
||||||
|
properties: {
|
||||||
|
/**
|
||||||
|
* MISSING Doc
|
||||||
|
*/
|
||||||
|
saved: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
notify: true,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
editable: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
index: {
|
||||||
|
type: Number,
|
||||||
|
notify: true,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
_previousSaved: {
|
||||||
|
type: Boolean,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
optional: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
selectable: {
|
||||||
|
type: Boolean,
|
||||||
|
computed: '_computeSelectable(_stepperData.linear, saved, editable, _previousSaved)',
|
||||||
|
reflectToAttribute: true,
|
||||||
|
notify: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
disabled: {
|
||||||
|
computed: '_computeDisabled(selectable)'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
value: ''
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
opened: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
animationConfig: {
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
entryAnimation: {
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
exitAnimation: {
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
vertical: {
|
||||||
|
type: Boolean,
|
||||||
|
readOnly: true,
|
||||||
|
reflectToAttribute: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
horizontalHigherEntryAnimation: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
horizontalHigherExitAnimation: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
horizontalLowerEntryAnimation: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
horizontalLowerExitAnimation: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
_alternativeLabel: {
|
||||||
|
type: Boolean,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
_optionalText: {
|
||||||
|
type: Boolean,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
_attrForPrimaryButtonText: {
|
||||||
|
type: String,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* A reference to the parent stepper
|
||||||
|
*/
|
||||||
|
_stepper: {
|
||||||
|
type: Object,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
_stepperData: {
|
||||||
|
type: Object,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
_canSkip: {
|
||||||
|
type: Boolean,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
_hasBackStep: {
|
||||||
|
type: Boolean,
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
listeners: {
|
||||||
|
'paper-step-vertical-skip-tapped': 'skip',
|
||||||
|
'paper-step-vertical-back-tapped': 'back',
|
||||||
|
'paper-step-vertical-continue-tapped': 'continue',
|
||||||
|
'tap': '_tapHandler'
|
||||||
|
},
|
||||||
|
|
||||||
|
observers: [
|
||||||
|
'_toggleClassPosition(index, _stepperData.stepNumber, vertical)',
|
||||||
|
'_updateSlideshowViewportTop(optional, _alternativeLabel, vertical)',
|
||||||
|
'_verticalChange(vertical)',
|
||||||
|
'_focusedChanged(receivedFocusFromKeyboard)',
|
||||||
|
'_labelElementChanged(_labelElement)'
|
||||||
|
],
|
||||||
|
|
||||||
|
_focusedChanged: function(receivedFocusFromKeyboard) {
|
||||||
|
if (receivedFocusFromKeyboard) {
|
||||||
|
this.ensureRipple();
|
||||||
|
// generate a ripple effect from the center of the badge
|
||||||
|
var badge = Polymer.dom(this._rippleContainer).querySelector('#badge');
|
||||||
|
var badgePos = badge.getBoundingClientRect();
|
||||||
|
var rippleX = badgePos.left + 12;
|
||||||
|
var rippleY = badgePos.top + 12;
|
||||||
|
this._ripple.downAction({detail: {x: rippleX, y: rippleY}});
|
||||||
|
}
|
||||||
|
if (this.hasRipple()) {
|
||||||
|
this._ripple.holdDown = receivedFocusFromKeyboard;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_tapHandler: function(e) {
|
||||||
|
var rootTarget = Polymer.dom(e).rootTarget;
|
||||||
|
if (rootTarget !== this && rootTarget !== this._rippleContainer) {
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
skip: function() {
|
||||||
|
// would it be better to send an event?
|
||||||
|
this._stepper.progress();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
back: function() {
|
||||||
|
// would it be better to send an event?
|
||||||
|
this._stepper.back();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the step as saved and fire `paper-step-saved` if it is valid.
|
||||||
|
* @return {Boolean} True if the step has been saved.
|
||||||
|
*/
|
||||||
|
save: function() {
|
||||||
|
if ((!this.saved || this.editable) && this.validate()) {
|
||||||
|
if (this.saved) {
|
||||||
|
this.fire('paper-step-updated');
|
||||||
|
} else {
|
||||||
|
this._setSaved(true);
|
||||||
|
this.fire('paper-step-saved');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Atempte to save the step and select and to progress into the stepper.
|
||||||
|
* @return {Boolean} True if the step is valid for saving.
|
||||||
|
*/
|
||||||
|
continue: function() {
|
||||||
|
if (this.save()) {
|
||||||
|
// would it be better to send an event?
|
||||||
|
this._stepper.progress();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_removeAnimatingClass: function() {
|
||||||
|
if (this._animationCanceled) {
|
||||||
|
this._set_animationCanceled(false);
|
||||||
|
} else {
|
||||||
|
this.toggleClass('neon-animating', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_cancelAnimation: function() {
|
||||||
|
this._set_animationCanceled(true);
|
||||||
|
this.toggleClass('neon-animating', false);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateSlideshowViewportTop: function(optional, _alternativeLabel, vertical) {
|
||||||
|
if (!vertical) {
|
||||||
|
this.async(function() {
|
||||||
|
this.$$('#slideshowViewport').style.top = this.clientHeight+'px';
|
||||||
|
this.fire('step-horizontal-label-resize');
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_toggleClassPosition: function(index, stepNumber, vertical) {
|
||||||
|
this.async(function() {
|
||||||
|
var stepLabel = this.$$(vertical ? '#verticalStepLabel' : '#horizontalStepLabel');
|
||||||
|
this.toggleClass('first-step', (index == 1), stepLabel);
|
||||||
|
this.toggleClass('last-step', (index == stepNumber), stepLabel);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateAnimationConfig: function() {
|
||||||
|
/* TODO: call this method when horizontalHigher/LowerEntry/ExitAnimation change */
|
||||||
|
var animatedNode = this.$$('#contentWrapper');
|
||||||
|
this._setAnimationConfig({
|
||||||
|
'higher-step-entry': {
|
||||||
|
node: animatedNode,
|
||||||
|
name: this.horizontalHigherEntryAnimation
|
||||||
|
},
|
||||||
|
'higher-step-exit': {
|
||||||
|
node: animatedNode,
|
||||||
|
name: this.horizontalHigherExitAnimation
|
||||||
|
},
|
||||||
|
'lower-step-entry': {
|
||||||
|
node: animatedNode,
|
||||||
|
name: this.horizontalLowerEntryAnimation
|
||||||
|
},
|
||||||
|
'lower-step-exit': {
|
||||||
|
node: animatedNode,
|
||||||
|
name: this.horizontalLowerExitAnimation
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_verticalChange: function(vertical) {
|
||||||
|
this.async(function() {
|
||||||
|
// move or create the content tag
|
||||||
|
Polymer.dom(this.$$(vertical ? '#verticalStepLabel' : '#contentWrapper')).appendChild(this.$$('content') || this.create('content'));
|
||||||
|
// reset the ripple
|
||||||
|
this._ripple = false;
|
||||||
|
this._rippleContainer = vertical ? this.$$('#verticalStepLabel').$.label : this.$$('#horizontalStepLabel').$.label;
|
||||||
|
if (!vertical) {
|
||||||
|
this._updateAnimationConfig();
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeSelectable: function(linear, saved, editable, previousSaved) {
|
||||||
|
// TODO: factorize the expression
|
||||||
|
return (!linear || previousSaved) && (!saved || editable) || (editable && saved);
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeDisabled: function(selectable) {
|
||||||
|
// disabled is used by IronMenuBehavior in paper-stepper
|
||||||
|
// TODO: remove selectable attribute and use disabled instead
|
||||||
|
return !selectable;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
@@ -0,0 +1,735 @@
|
|||||||
|
<link rel="import" href="../../components/iron-flex-layout/iron-flex-layout.html">
|
||||||
|
<link rel="import" href="../../components/iron-selector/iron-selectable.html">
|
||||||
|
<link rel="import" href="../../components/iron-menu-behavior/iron-menu-behavior.html">
|
||||||
|
<link rel="import" href="../../components/neon-animation/neon-animation-runner-behavior.html">
|
||||||
|
<link rel="import" href="../../components/paper-button/paper-button.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/default-theme.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/shadow.html">
|
||||||
|
<link rel="import" href="../../components/iron-collapse/iron-collapse.html">
|
||||||
|
<link rel="import" href="../../components/iron-resizable-behavior/iron-resizable-behavior.html">
|
||||||
|
<link rel="import" href="../../components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="animations/fade-in-slide-from-right-animation.html">
|
||||||
|
<link rel="import" href="animations/fade-out-slide-right-animation.html">
|
||||||
|
<link rel="import" href="animations/fade-in-slide-from-left-animation.html">
|
||||||
|
<link rel="import" href="animations/fade-out-slide-left-animation.html">
|
||||||
|
<link rel="import" href="paper-step.html">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Missing Doc
|
||||||
|
|
||||||
|
|
||||||
|
## Styling
|
||||||
|
|
||||||
|
The default color values respect the material specifications. For basic configuration, just defines the `--primary-color` for your app.
|
||||||
|
|
||||||
|
The stepper has a complexe interface so many custom properties are available, use them this way :
|
||||||
|
|
||||||
|
```html
|
||||||
|
<style is="custom-style">
|
||||||
|
|
||||||
|
paper-stepper {
|
||||||
|
--paper-stepper-custom-property: value;
|
||||||
|
}
|
||||||
|
|
||||||
|
paper-step {
|
||||||
|
--paper-step-custom-property: value;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<paper-stepper>
|
||||||
|
<paper-step></paper-step>
|
||||||
|
<paper-step></paper-step>
|
||||||
|
</paper-stepper>
|
||||||
|
```
|
||||||
|
|
||||||
|
Note, for sizing the stepper and steps depending on the layout, use the following instead of setting 'height' and 'max-height' :
|
||||||
|
- `--paper-stepper-horizontal-opened-height`
|
||||||
|
- `--paper-stepper-vertical-max-height`
|
||||||
|
- `--paper-vertical-step-max-height`
|
||||||
|
|
||||||
|
### Stepper
|
||||||
|
|
||||||
|
Custom property | Description | Default
|
||||||
|
------|-------------|----------
|
||||||
|
`--paper-stepper-horizontal-opened-height` | The horizontal opened stepper height | 450px
|
||||||
|
`--paper-stepper-horizontal-opening-transition-duration`| The horizontal stepper opening transition duration (ms) | 500
|
||||||
|
`--paper-stepper-vertical-max-height`| The vertical stepper max height so it has a scrollable area | undefined
|
||||||
|
|
||||||
|
### Step
|
||||||
|
|
||||||
|
Custom property | Description | Default
|
||||||
|
------|-------------|----------
|
||||||
|
`--paper-step-connector-line-background` | The connector lines background color. | `--divider-color`
|
||||||
|
`--paper-step-label-hover-background` | The steps label background when hovered. | rgba(0,0,0,0.04)
|
||||||
|
`--paper-step-ink-color` | The steps ripple effect ink color. | `--divider-color`
|
||||||
|
|
||||||
|
### Step text label
|
||||||
|
|
||||||
|
Custom property | Description | Default
|
||||||
|
------|-------------|----------
|
||||||
|
`--paper-step-disabled-label-text-color` | The no-selectable steps label text color. | `--paper-grey-400`
|
||||||
|
`--paper-step-selectable-label-text-color` | The selectable steps label text color. | `--paper-grey-600`
|
||||||
|
`--paper-step-opened-label-text-color` | The opened steps label text color. | `--light-theme-text-color`
|
||||||
|
`--paper-step-label-text-font-size` | The steps label text font size. | 14px
|
||||||
|
`--paper-step-label-optional-text-font-size` | The steps label optional text font size. | 12px
|
||||||
|
|
||||||
|
### Step badge
|
||||||
|
|
||||||
|
Custom property | Description | Default
|
||||||
|
------|-------------|----------
|
||||||
|
`--paper-step-badge-background` | The badge background. | `--paper-grey-300`
|
||||||
|
`--paper-step-badge-color` | The badge color. | `--dark-theme-text-color`
|
||||||
|
`--paper-step-badge-icon-width` | The badge icon width. | 16px
|
||||||
|
`--paper-step-badge-icon-height` | The badge icon height. | 16px
|
||||||
|
`--paper-step-opened-badge-background` | The opened steps badge background. | `--primary-color`
|
||||||
|
`--paper-step-saved-badge-background` | The saved steps badge background. | `--primary-color`
|
||||||
|
`--paper-step-selectable-hovered-badge-background` | The no-opened no-saved selectable steps badge background. | `--paper-grey-500`
|
||||||
|
|
||||||
|
### Vertical step
|
||||||
|
|
||||||
|
Custom property | Description | Default
|
||||||
|
------|-------------|----------
|
||||||
|
`--paper-vertical-step-continue-button-background` | The continue button background. | `--primary-color`
|
||||||
|
`--paper-vertical-step-continue-button-color` | The continue button background. | `--dark-theme-text-color`
|
||||||
|
`--paper-vertical-step-max-height` | The unrolled step content max-height. | 400px
|
||||||
|
`--paper-vertical-step-transition-duration` | The step opening transition duration | 500ms
|
||||||
|
|
||||||
|
|
||||||
|
@element paper-stepper
|
||||||
|
@demo demo/index.html
|
||||||
|
@hero hero.svg
|
||||||
|
-->
|
||||||
|
<dom-module id="paper-stepper">
|
||||||
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
@apply(--layout-vertical);
|
||||||
|
@apply(--shadow-elevation-2dp);
|
||||||
|
background: white;
|
||||||
|
border-radius: 1px;
|
||||||
|
}
|
||||||
|
#verticalResponsiveWidth {
|
||||||
|
width: var(--paper-stepper-vertical-responsive-width, 0px);
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Horizontal layout styles */
|
||||||
|
|
||||||
|
:host([vertical]) {
|
||||||
|
padding: 4px 0;
|
||||||
|
@apply(--layout-scroll);
|
||||||
|
max-height: var(--paper-stepper-vertical-max-height);
|
||||||
|
}
|
||||||
|
:host(:not([vertical])) {
|
||||||
|
position: relative;
|
||||||
|
/* Note: this variable is updated by the stepper itself, don't use it on user side */
|
||||||
|
height: var(--label-wrapper-height);
|
||||||
|
max-height: var(--label-wrapper-height);
|
||||||
|
transition: max-height var(--paper-stepper-horizontal-opening-transition-duration, 300ms), box-shadow 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
:host(:not([vertical]):not([opened]):not(.collapsing)) {
|
||||||
|
@apply(--shadow-none);
|
||||||
|
}
|
||||||
|
:host(:not([vertical])[opened]) {
|
||||||
|
max-height: var(--paper-stepper-horizontal-opened-height, 450px);
|
||||||
|
}
|
||||||
|
:host(:not([vertical])[opened]), :host(:not([vertical]).collapsing) {
|
||||||
|
height: var(--paper-stepper-horizontal-opened-height, 450px);
|
||||||
|
}
|
||||||
|
:host(:not([vertical])) #content-wrapper {
|
||||||
|
@apply(--shadow-elevation-2dp);
|
||||||
|
@apply(--layout-horizontal);
|
||||||
|
@apply(--layout-flex-none);
|
||||||
|
@apply(--layout-justified);
|
||||||
|
background: var(--paper-stepper-horizontal-label-wrapper-background, --primary-background-color);
|
||||||
|
border-radius: 1px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.flex {
|
||||||
|
@apply(--layout-flex);
|
||||||
|
}
|
||||||
|
#buttonsWrapper {
|
||||||
|
@apply(--layout-horizontal);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#continueButton:not([disabled]) {
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
paper-button[disabled] {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
:host(:not[vertical]) #content-wrapper ::content paper-step[opened] {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- Hidden block with width equals to the responsive threshold -->
|
||||||
|
<div id="verticalResponsiveWidth"></div>
|
||||||
|
|
||||||
|
<!-- This wrapper contains the horizontal stepper header or the full vertical stepper -->
|
||||||
|
<div id="content-wrapper">
|
||||||
|
<content select="[[selectable]]"></content>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Slideshow and buttons area for horizontal layout -->
|
||||||
|
<template is="dom-if" if="[[!vertical]]">
|
||||||
|
<div class="flex"></div>
|
||||||
|
<div id="buttonsWrapper">
|
||||||
|
<paper-button hidden$="[[!hasBackButton]]" disabled=[[!_hasBackStep]] on-tap="back">[[backText]]</paper-button>
|
||||||
|
<span class="flex"></span>
|
||||||
|
<paper-button hidden$="[[!hasSkipButton]]" disabled="[[!_canSkip]]" on-tap="progress">[[skipText]]</paper-button>
|
||||||
|
<!--
|
||||||
|
<paper-button id="continueButton" on-tap="continue">{{_choosePrimaryButtonText(_attrForSelectedStepPrimaryButtonText, finishText, continueText, updateText)}}</paper-button>
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
Polymer({
|
||||||
|
|
||||||
|
is: 'paper-stepper',
|
||||||
|
|
||||||
|
behaviors: [
|
||||||
|
Polymer.IronMenuBehavior,
|
||||||
|
Polymer.NeonAnimationRunnerBehavior,
|
||||||
|
Polymer.IronResizableBehavior
|
||||||
|
],
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when the stepper progress.
|
||||||
|
*
|
||||||
|
* @event paper-stepper-progressed
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Fired when all the steps are saved.
|
||||||
|
*
|
||||||
|
* @event paper-stepper-completed
|
||||||
|
*/
|
||||||
|
properties: {
|
||||||
|
opened: {
|
||||||
|
type: Boolean,
|
||||||
|
computed: '_computeOpened(_selectedIndex)',
|
||||||
|
observer: '_openedChanged',
|
||||||
|
notify: true,
|
||||||
|
reflectToAttribute: true
|
||||||
|
},
|
||||||
|
alternativeLabel: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
vertical: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
reflectToAttribute: true
|
||||||
|
},
|
||||||
|
backText: {
|
||||||
|
type: String,
|
||||||
|
value: 'BACK'
|
||||||
|
},
|
||||||
|
finishText: {
|
||||||
|
type: String,
|
||||||
|
value: 'FINISH'
|
||||||
|
},
|
||||||
|
continueText: {
|
||||||
|
type: String,
|
||||||
|
value: 'CONTINUE'
|
||||||
|
},
|
||||||
|
skipText: {
|
||||||
|
type: String,
|
||||||
|
value: 'SKIP'
|
||||||
|
},
|
||||||
|
optionalText: {
|
||||||
|
type: String,
|
||||||
|
value: 'Optional'
|
||||||
|
},
|
||||||
|
updateText: {
|
||||||
|
type: String,
|
||||||
|
value: 'UPDATE'
|
||||||
|
},
|
||||||
|
linear: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
completed: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
notify: true,
|
||||||
|
computed: '_computeCompleted(stepNumber, savedStepNumber)'
|
||||||
|
},
|
||||||
|
hasSkipButton: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
hasBackButton: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
stepNumber: {
|
||||||
|
type: Number,
|
||||||
|
notify: true,
|
||||||
|
computed: '_computeStepNumber(items.length)'
|
||||||
|
},
|
||||||
|
savedStepNumber: {
|
||||||
|
type: Number,
|
||||||
|
notify: true,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
selectedAttribute: {
|
||||||
|
value: 'opened',
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Note: if you decide to change this attribute, take care to only include `<paper-step>` elements in your `<paper-stepper>`
|
||||||
|
*/
|
||||||
|
selectable: {
|
||||||
|
value: 'paper-step'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Multi mode is not allowed for now in paper-stepper.
|
||||||
|
*/
|
||||||
|
mutli: {
|
||||||
|
value: false,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
responsiveCheckFrequence: {
|
||||||
|
type: Number,
|
||||||
|
value: 200
|
||||||
|
},
|
||||||
|
animateInitialSelection: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
horizontalHigherEntryAnimation: {
|
||||||
|
type: String,
|
||||||
|
value: 'fade-in-slide-from-right-animation'
|
||||||
|
},
|
||||||
|
horizontalHigherExitAnimation: {
|
||||||
|
type: String,
|
||||||
|
value: 'fade-out-slide-right-animation'
|
||||||
|
},
|
||||||
|
horizontalLowerEntryAnimation: {
|
||||||
|
type: String,
|
||||||
|
value: 'fade-in-slide-from-left-animation'
|
||||||
|
},
|
||||||
|
horizontalLowerExitAnimation: {
|
||||||
|
type: String,
|
||||||
|
value: 'fade-out-slide-left-animation'
|
||||||
|
},
|
||||||
|
_skipStepIndex: {
|
||||||
|
type: Number,
|
||||||
|
computed: '_compute_skipStepIndex(_selectedIndex)'
|
||||||
|
},
|
||||||
|
_canSkip: {
|
||||||
|
type: Boolean,
|
||||||
|
notify: true,
|
||||||
|
computed: '_isntNull(_skipStepIndex)'
|
||||||
|
},
|
||||||
|
_backStepIndex: {
|
||||||
|
type: Number,
|
||||||
|
computed: '_compute_backStepIndex(_selectedIndex)'
|
||||||
|
},
|
||||||
|
_hasBackStep: {
|
||||||
|
type: Boolean,
|
||||||
|
computed: '_isntNull(_backStepIndex)'
|
||||||
|
},
|
||||||
|
_selectedIndex: {
|
||||||
|
type: Number,
|
||||||
|
observer: '_selectedIndexChanged',
|
||||||
|
readOnly: true,
|
||||||
|
value: -1
|
||||||
|
},
|
||||||
|
_attrForSelectedStepPrimaryButtonText: {
|
||||||
|
type: String,
|
||||||
|
computed: '_compute__attrForSelectedStepPrimaryButtonText(_selectedIndex, stepNumber)'
|
||||||
|
},
|
||||||
|
_previousAnimatedStep: {
|
||||||
|
type: Object,
|
||||||
|
value: null,
|
||||||
|
readOnly: true
|
||||||
|
},
|
||||||
|
_previousSelected: {
|
||||||
|
type: Object,
|
||||||
|
readOnly: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
keyBindings: {
|
||||||
|
'left': '_onLeftKey',
|
||||||
|
'right': '_onRightKey'
|
||||||
|
},
|
||||||
|
|
||||||
|
listeners: {
|
||||||
|
'iron-items-changed': '_initializeSteps',
|
||||||
|
'paper-step-saved': '_stepSaved',
|
||||||
|
'transitionend': '_transitionEnd',
|
||||||
|
'step-horizontal-label-resize': '_updateStepperClosedMaxHeight',
|
||||||
|
'iron-resize': '_resizeHandler',
|
||||||
|
'neon-animation-finish': '_onNeonAnimationFinish'
|
||||||
|
},
|
||||||
|
|
||||||
|
observers: [
|
||||||
|
'_forwardCanSkip(_canSkip, selectedItem)',
|
||||||
|
'_forwardHasBackStep(_hasBackStep, selectedItem)',
|
||||||
|
'_forwardVertical(vertical)',
|
||||||
|
'_forwardAlternativeLabel(alternativeLabel)',
|
||||||
|
'_forwardStepperData(linear, backText, optionalText, finishText, continueText, skipText, updateText, hasSkipButton, hasBackButton)'
|
||||||
|
],
|
||||||
|
|
||||||
|
attached: function() {
|
||||||
|
this._responsiveCheck();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Missing Doc
|
||||||
|
*/
|
||||||
|
back: function() {
|
||||||
|
this.selectIndex(this._backStepIndex);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {Boolean} Try to continue the current step (if no step opened, use the first one).
|
||||||
|
*/
|
||||||
|
continue: function() {
|
||||||
|
if (this.selectedItem) {
|
||||||
|
if (this.selectedItem.save()) {
|
||||||
|
this.progress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loops around the steps from the current (if no step opened, from the first one)
|
||||||
|
* in order to open the next selectable unsaved step. Returns true if a step has been opened.
|
||||||
|
*/
|
||||||
|
progress: function() {
|
||||||
|
if (!this.stepNumber) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.completed) {
|
||||||
|
this.selected = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (var i = (this._selectedIndex+1)%this.stepNumber; i != this._selectedIndex; i = (i+1)%this.stepNumber) {
|
||||||
|
if (this.items[i].selectable && !this.items[i].saved) {
|
||||||
|
this.selectIndex(i);
|
||||||
|
this.fire('paper-stepper-progressed');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/* Deselect and set the steps as unsaved*/
|
||||||
|
reset: function() {
|
||||||
|
this._setSavedStepNumber(0);
|
||||||
|
this.selected = null;
|
||||||
|
if (!this.items.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.items.map(function(step) {
|
||||||
|
step._setSaved(false);
|
||||||
|
step._set_previousSaved(false);
|
||||||
|
});
|
||||||
|
this.items[0]._set_previousSaved(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
get _isRTL() {
|
||||||
|
return window.getComputedStyle(this)['direction'] === 'rtl';
|
||||||
|
},
|
||||||
|
|
||||||
|
_onLeftKey: function(event) {
|
||||||
|
if (this._isRTL) {
|
||||||
|
this._focusNext();
|
||||||
|
} else {
|
||||||
|
this._focusPrevious();
|
||||||
|
}
|
||||||
|
event.detail.keyboardEvent.preventDefault();
|
||||||
|
},
|
||||||
|
|
||||||
|
_onRightKey: function(event) {
|
||||||
|
if (this._isRTL) {
|
||||||
|
this._focusPrevious();
|
||||||
|
} else {
|
||||||
|
this._focusNext();
|
||||||
|
}
|
||||||
|
event.detail.keyboardEvent.preventDefault();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Work around: Override the method from IronSelectableBehavior to only allow the selection of selectable step. https://github.com/PolymerElements/iron-selector/issues/99
|
||||||
|
*/
|
||||||
|
_selectSelected: function(selected) {
|
||||||
|
var item = this._valueToItem(this.selected);
|
||||||
|
if (item) {
|
||||||
|
var selectable = item.selectable;
|
||||||
|
if (selectable == undefined) {
|
||||||
|
// if selectable isn't define it means the step is not yet ready for selection
|
||||||
|
// and this method will be recalled by the initialization method.
|
||||||
|
return;
|
||||||
|
} else if (!selectable) {
|
||||||
|
//reset previous selected if non null and selectable or deselect
|
||||||
|
if (this._previousSelected && this._previousSelected.selectable) {
|
||||||
|
this.selected = this._valueForItem(this.previousSelected);
|
||||||
|
} else {
|
||||||
|
this.selected = null;
|
||||||
|
}
|
||||||
|
this._set_previousSelected(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._selection.select(item);
|
||||||
|
this._set_previousSelected(item);
|
||||||
|
this._set_selectedIndex(this.indexOf(item));
|
||||||
|
// Check for items, since this array is populated only when attached
|
||||||
|
// Since Number(0) is falsy, explicitly check for undefined
|
||||||
|
if (this.fallbackSelection && this.items.length && (this._selection.get() === undefined)) {
|
||||||
|
this.selected = this.fallbackSelection;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateStepperClosedMaxHeight: function() {
|
||||||
|
this.debounce('updateStepperClosedMaxHeight', function() {
|
||||||
|
this.customStyle['--label-wrapper-height'] = this.$$('#content-wrapper').clientHeight + 'px';
|
||||||
|
this.updateStyles('--label-wrapper-height');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_openedChanged: function(newValue, oldValue) {
|
||||||
|
if (!this.vertical && oldValue != undefined) {
|
||||||
|
this.toggleClass('collapsing', true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_transitionEnd: function(e) {
|
||||||
|
// check to ignore event fired by paper-ripple
|
||||||
|
if (e.propertyName == 'max-height') {
|
||||||
|
this.toggleClass('collapsing', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeOpened: function(_selectedIndex) {
|
||||||
|
return _selectedIndex >= 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
_stepSaved: function(e) {
|
||||||
|
var previousStep = this.items[this.indexOf(e.target)+1];
|
||||||
|
if (previousStep) {
|
||||||
|
previousStep._set_previousSaved(true);
|
||||||
|
}
|
||||||
|
this._setSavedStepNumber(this.savedStepNumber+1);
|
||||||
|
},
|
||||||
|
|
||||||
|
_forwardVertical: function(vertical) {
|
||||||
|
if (this.stepNumber) {
|
||||||
|
this.items.map(function(step) {
|
||||||
|
step._setVertical(vertical);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.setAttribute('role', vertical ? 'menu': 'menubar');
|
||||||
|
},
|
||||||
|
|
||||||
|
_forwardStepperData: function(linear, backText, optionalText, finishText, continueText, skipText, updateText, hasSkipButton, hasBackButton) {
|
||||||
|
if (this.stepNumber) {
|
||||||
|
this.items.map(function(step) {
|
||||||
|
step._set_stepperData({
|
||||||
|
linear: linear,
|
||||||
|
backText: backText,
|
||||||
|
optionalText: optionalText,
|
||||||
|
finishText: finishText,
|
||||||
|
continueText: continueText,
|
||||||
|
skipText: skipText,
|
||||||
|
updateText: updateText,
|
||||||
|
hasSkipButton: hasSkipButton,
|
||||||
|
hasBackButton: hasBackButton,
|
||||||
|
stepNumber: this.stepNumber
|
||||||
|
});
|
||||||
|
}.bind(this));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_forwardAlternativeLabel: function(alternativeLabel) {
|
||||||
|
if (this.stepNumber) {
|
||||||
|
this.items.map(function(step) {
|
||||||
|
step._set_alternativeLabel(alternativeLabel);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeStepNumber: function(length) {
|
||||||
|
return length;
|
||||||
|
},
|
||||||
|
|
||||||
|
_selectedIndexChanged: function(newValue, oldValue) {
|
||||||
|
if (!this.vertical && newValue >=0 && oldValue >= 0) {
|
||||||
|
var oldStep = this.items[oldValue], newStep = this.items[newValue];
|
||||||
|
if (newStep.classList.contains('neon-animating')) {
|
||||||
|
this.cancelAnimation();
|
||||||
|
}
|
||||||
|
if (this._previousAnimatedStep && this._previousAnimatedStep.classList.contains('neon-animating')) {
|
||||||
|
this.cancelAnimation();
|
||||||
|
this.toggleClass('neon-animating', false, this._previousAnimatedStep);
|
||||||
|
}
|
||||||
|
var forward = newValue - oldValue > 0;
|
||||||
|
|
||||||
|
this.animationConfig = {
|
||||||
|
'new-step-entry': {
|
||||||
|
animatable: newStep,
|
||||||
|
type: forward ?
|
||||||
|
newStep.horizontalHigherEntryAnimation && 'higher-step-entry' :
|
||||||
|
newStep.horizontalLowerEntryAnimation && 'lower-step-entry'
|
||||||
|
},
|
||||||
|
'old-step-exit': {
|
||||||
|
animatable: oldStep,
|
||||||
|
type: forward ?
|
||||||
|
oldStep.horizontalLowerExitAnimation && 'lower-step-exit' :
|
||||||
|
oldStep.horizontalHigherExitAnimation && 'higher-step-exit'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (this.animationConfig['new-step-entry'].type) {
|
||||||
|
this.playAnimation('new-step-entry', {step: newStep});
|
||||||
|
this.toggleClass('neon-animating', true, newStep);
|
||||||
|
}
|
||||||
|
if (this.animationConfig['old-step-exit'].type) {
|
||||||
|
this.playAnimation('old-step-exit', {step: oldStep});
|
||||||
|
this.toggleClass('neon-animating', true, oldStep);
|
||||||
|
}
|
||||||
|
|
||||||
|
this._set_previousAnimatedStep(oldStep);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_onNeonAnimationFinish: function(event) {
|
||||||
|
var step = event.detail.step;
|
||||||
|
if (step) {
|
||||||
|
this.toggleClass('neon-animating', false, step);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_forwardCanSkip: function(_canSkip, selectedItem) {
|
||||||
|
selectedItem._set_canSkip(_canSkip);
|
||||||
|
},
|
||||||
|
|
||||||
|
_forwardHasBackStep: function(_hasBackStep, selectedItem) {
|
||||||
|
selectedItem._set_hasBackStep(_hasBackStep);
|
||||||
|
},
|
||||||
|
|
||||||
|
_compute__attrForSelectedStepPrimaryButtonText: function(selectedIndex) {
|
||||||
|
/* TODO: compute from selectedItem when https://github.com/PolymerElements/iron-selector/issues/118 is fixed*/
|
||||||
|
if (selectedIndex < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
var _attrForPrimaryButtonText = this.selectedItem.saved ? 'updateText' :
|
||||||
|
( (this.stepNumber - this.savedStepNumber) == 1 ? 'finishText' : 'continueText' );
|
||||||
|
this.selectedItem._set_attrForPrimaryButtonText(_attrForPrimaryButtonText);
|
||||||
|
return _attrForPrimaryButtonText;
|
||||||
|
},
|
||||||
|
|
||||||
|
_initializeSteps: function() {
|
||||||
|
var savedStepNumber = 0;
|
||||||
|
var data = {
|
||||||
|
linear: this.linear,
|
||||||
|
backText: this.backText,
|
||||||
|
optionalText: this.optionalText,
|
||||||
|
finishText: this.finishText,
|
||||||
|
continueText: this.continueText,
|
||||||
|
skipText: this.skipText,
|
||||||
|
updateText: this.updateText,
|
||||||
|
hasSkipButton: this.hasSkipButton,
|
||||||
|
hasBackButton: this.hasBackButton,
|
||||||
|
stepNumber: this.stepNumber
|
||||||
|
};
|
||||||
|
this.items.map(function(step, i) {
|
||||||
|
if (this.horizontalHigherEntryAnimation && !step.horizontalHigherEntryAnimation) {
|
||||||
|
step.horizontalHigherEntryAnimation = this.horizontalHigherEntryAnimation;
|
||||||
|
}
|
||||||
|
if (this.horizontalHigherExitAnimation && !step.horizontalHigherExitAnimation) {
|
||||||
|
step.horizontalHigherExitAnimation = this.horizontalHigherExitAnimation;
|
||||||
|
}
|
||||||
|
if (this.horizontalLowerEntryAnimation && !step.horizontalLowerEntryAnimation) {
|
||||||
|
step.horizontalLowerEntryAnimation = this.horizontalLowerEntryAnimation;
|
||||||
|
}
|
||||||
|
if (this.horizontalLowerExitAnimation && !step.horizontalLowerExitAnimation) {
|
||||||
|
step.horizontalLowerExitAnimation = this.horizontalLowerExitAnimation;
|
||||||
|
}
|
||||||
|
step._setIndex(i + 1);
|
||||||
|
step._set_stepper(this);
|
||||||
|
step._setVertical(this.vertical);
|
||||||
|
step._set_alternativeLabel(this.alternativeLabel);
|
||||||
|
step._set_stepperData(data);
|
||||||
|
// true for index 0
|
||||||
|
step._set_previousSaved(!i);
|
||||||
|
if (step.saved) {
|
||||||
|
savedStepNumber++;
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
this._setSavedStepNumber(savedStepNumber);
|
||||||
|
// method from IronSelectableBehavior
|
||||||
|
this._updateSelected();
|
||||||
|
},
|
||||||
|
|
||||||
|
_compute_skipStepIndex: function(_selectedIndex) {
|
||||||
|
if (_selectedIndex >= 0 && !this.completed) {
|
||||||
|
for (var i=(_selectedIndex+1)%this.stepNumber; i!=_selectedIndex; i=(i+1)%this.stepNumber) {
|
||||||
|
if (this.items[i].selectable && !this.items[i].saved) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_compute_backStepIndex: function(_selectedIndex) {
|
||||||
|
if (_selectedIndex >= 0) {
|
||||||
|
for (var i=_selectedIndex - 1; i >= 0; i--) {
|
||||||
|
if (this.items[i].selectable) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
},
|
||||||
|
|
||||||
|
_isntNull: function(n) {
|
||||||
|
return n != null;
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeCompleted: function(savedStepNumber, stepNumber) {
|
||||||
|
var completed = stepNumber == savedStepNumber;
|
||||||
|
if (completed) {
|
||||||
|
this.fire('paper-stepper-completed');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_choosePrimaryButtonText: function(_attrForSelectedStepPrimaryButtonText) {
|
||||||
|
return this[_attrForSelectedStepPrimaryButtonText];
|
||||||
|
},
|
||||||
|
|
||||||
|
_resizeHandler: function() {
|
||||||
|
this.debounce('paper-stepper-responsive-check', function() {
|
||||||
|
this._responsiveCheck();
|
||||||
|
}, this.responsiveCheckFrequence);
|
||||||
|
},
|
||||||
|
|
||||||
|
_responsiveCheck: function() {
|
||||||
|
var verticalResponsiveWidth = this.$.verticalResponsiveWidth.clientWidth;
|
||||||
|
if (verticalResponsiveWidth) {
|
||||||
|
this.vertical = !(this.clientWidth > verticalResponsiveWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
<link rel="import" href="../../components/iron-flex-layout/iron-flex-layout.html">
|
||||||
|
<link rel="import" href="../../components/iron-icons/iron-icons.html">
|
||||||
|
<link rel="import" href="../../components/iron-icons/editor-icons.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/color.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/typography.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/default-theme.html">
|
||||||
|
<link rel="import" href="../../components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="step-label-behavior.html">
|
||||||
|
<link rel="import" href="step-label-shared-styles.html">
|
||||||
|
|
||||||
|
<dom-module id="step-horizontal-label">
|
||||||
|
<template>
|
||||||
|
<style include="step-label-shared-styles">
|
||||||
|
:host{
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
:host([alternative-label]) {
|
||||||
|
@apply(--layout);
|
||||||
|
}
|
||||||
|
#textWrapper {
|
||||||
|
@apply(--layout-vertical);
|
||||||
|
padding-right: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#textLabel, #optional {
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#badge {
|
||||||
|
margin: 0 8px;
|
||||||
|
}
|
||||||
|
#badgeWrapper, #textWrapper {
|
||||||
|
pointer-events: none;
|
||||||
|
/* to be above paper-ripple*/
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
:host(:not([alternative-label])) #label {
|
||||||
|
@apply(--layout-horizontal);
|
||||||
|
@apply(--layout-center);
|
||||||
|
height: 72px;
|
||||||
|
}
|
||||||
|
:host(.firstStep:not([alternative-label])) #badge {
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
:host(.lastStep:not([alternative-label])) #textWrapper {
|
||||||
|
padding-right: 24px;
|
||||||
|
}
|
||||||
|
:host(:not([alternative-label]):not(.first-step)) #label::before,
|
||||||
|
:host(:not([alternative-label]):not(.last-step)) #label::after,
|
||||||
|
:host([alternative-label]) #badgeWrapper::before,
|
||||||
|
:host([alternative-label]) #badgeWrapper::after {
|
||||||
|
height: 1px;
|
||||||
|
min-width: 16px;
|
||||||
|
background: var(--paper-step-connector-line-color, --divider-color);
|
||||||
|
@apply(--layout-flex);
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
|
:host([alternative-label].first-step) #badgeWrapper::before,
|
||||||
|
:host([alternative-label].last-step) #badgeWrapper::after {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
:host([alternative-label]) #textWrapper{
|
||||||
|
padding: 0 16px;
|
||||||
|
@apply(--layout-vertical);
|
||||||
|
@apply(--layout-center);
|
||||||
|
}
|
||||||
|
:host([alternative-label]) #textLabel, :host([alternative-label]) #optional{
|
||||||
|
text-align: center;
|
||||||
|
@apply(--layout-self-stretch);
|
||||||
|
}
|
||||||
|
:host([alternative-label]) #label{
|
||||||
|
@apply(--layout-vertical);
|
||||||
|
@apply(--layout-self-stretch);
|
||||||
|
padding: 24px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
:host([alternative-label]) #badgeWrapper {
|
||||||
|
@apply(--layout-horizontal);
|
||||||
|
@apply(--layout-center);
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
:host(.first-step:not([alternative-label])) #label {
|
||||||
|
padding-left: 16px;
|
||||||
|
}
|
||||||
|
:host(.last-step:not([alternative-label])) #label {
|
||||||
|
padding-right: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<!-- use a "label" wrapper to use the same shared css rules with step-vertical -->
|
||||||
|
<div id="label">
|
||||||
|
<div id="badgeWrapper">
|
||||||
|
<div id="badge">
|
||||||
|
<iron-icon hidden$="{{!_computeIsIconBadge(icon)}}" icon="{{icon}}"></iron-icon>
|
||||||
|
<span hidden$="{{_computeIsIconBadge(icon)}}">{{index}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="textWrapper">
|
||||||
|
<span id="textLabel">[[label]]</span>
|
||||||
|
<template is="dom-if" if="[[optional]]">
|
||||||
|
<span id="optional">[[stepperData.optionalText]]</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'step-horizontal-label',
|
||||||
|
|
||||||
|
behaviors: [
|
||||||
|
Stepper.StepLabelBehavior
|
||||||
|
],
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
alternativeLabel: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
reflectToAttribute: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
<link rel="import" href="../../components/polymer/polymer.html">
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
window.Stepper = window.Stepper || {};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @polymerBehavior Stepper.StepLabelBehavior
|
||||||
|
*/
|
||||||
|
Stepper.StepLabelBehavior = {
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
computed: '_computeIcon(saved, editable)'
|
||||||
|
},
|
||||||
|
opened: {
|
||||||
|
type: Boolean,
|
||||||
|
reflectToAttribute: true
|
||||||
|
},
|
||||||
|
selectable: {
|
||||||
|
type: Boolean,
|
||||||
|
reflectToAttribute: true
|
||||||
|
},
|
||||||
|
editable: {
|
||||||
|
type: Boolean,
|
||||||
|
reflectToAttribute: true,
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
notify: true
|
||||||
|
},
|
||||||
|
optional: {
|
||||||
|
type: Boolean,
|
||||||
|
notify: true
|
||||||
|
},
|
||||||
|
saved: {
|
||||||
|
type: Boolean,
|
||||||
|
reflectToAttribute: true
|
||||||
|
},
|
||||||
|
index: {
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
stepperData: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeIcon: function(saved, editable) {
|
||||||
|
return saved ? ( editable ? 'editor:mode-edit' : 'done' ) : '';
|
||||||
|
},
|
||||||
|
|
||||||
|
_computeIsIconBadge: function(icon) {
|
||||||
|
return icon.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<link rel="import" href="../../components/iron-flex-layout/iron-flex-layout.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/default-theme.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/color.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/typography.html">
|
||||||
|
<link rel="import" href="../../components/polymer/polymer.html">
|
||||||
|
|
||||||
|
<dom-module id="step-label-shared-styles">
|
||||||
|
<template>
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
@apply(--paper-font-common-base);
|
||||||
|
@apply(--layout-flex);
|
||||||
|
}
|
||||||
|
#textWrapper {
|
||||||
|
color: var(--paper-step-disabled-label-text-color, --paper-grey-400);
|
||||||
|
}
|
||||||
|
#textLabel {
|
||||||
|
font-size: var(--paper-step-label-text-font-size, 14px);
|
||||||
|
}
|
||||||
|
#optional{
|
||||||
|
font-size: var(--paper-step-label-optional-text-font-size, 12px);
|
||||||
|
}
|
||||||
|
:host([selectable]) #textWrapper {
|
||||||
|
color: var(--paper-step-selectable-label-text-color, --paper-grey-600);
|
||||||
|
}
|
||||||
|
:host([opened]) #textLabel {
|
||||||
|
color: var(--paper-step-opened-label-text-color, --light-theme-text-color);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
#label {
|
||||||
|
cursor: default;
|
||||||
|
pointer-events: none;
|
||||||
|
/* For paper-ripple */
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
:host([selectable]) #label {
|
||||||
|
cursor: pointer;
|
||||||
|
pointer-events: auto;
|
||||||
|
}
|
||||||
|
#label:hover {
|
||||||
|
/* using alpha chanel for .connectorLine to grow dark */
|
||||||
|
background: var(--paper-step-label-hover-background, rgba(0,0,0,0.04));
|
||||||
|
}
|
||||||
|
#badge {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background: var(--paper-step-badge-background, --paper-grey-300);
|
||||||
|
border-radius: 50%;
|
||||||
|
color: var(--paper-step-badge-color, --dark-theme-text-color);
|
||||||
|
font-size: 12px;
|
||||||
|
@apply(--layout);
|
||||||
|
@apply(--layout-center-center);
|
||||||
|
}
|
||||||
|
#badge iron-icon {
|
||||||
|
--iron-icon-height: var(--paper-step-badge-icon-width, 16px);
|
||||||
|
--iron-icon-width: var(--paper-step-badge-icon-height, 16px);
|
||||||
|
}
|
||||||
|
:host([opened]) #badge {
|
||||||
|
background: var(--paper-step-opened-badge-background, --primary-color);
|
||||||
|
}
|
||||||
|
:host([saved]) #badge {
|
||||||
|
background: var(--paper-step-saved-badge-background, --primary-color);
|
||||||
|
}
|
||||||
|
:host([selectable]:not([opened]):not([saved])) #label:hover #badge {
|
||||||
|
background: var(--paper-step-selectable-hovered-badge-background, --paper-grey-500);
|
||||||
|
}
|
||||||
|
paper-ripple {
|
||||||
|
color: var(--paper-step-ink-color, --paper-grey-400);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</template>
|
||||||
|
</dom-module>
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
<link rel="import" href="../../components/iron-flex-layout/iron-flex-layout.html">
|
||||||
|
<link rel="import" href="../../components/paper-button/paper-button.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/color.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/default-theme.html">
|
||||||
|
<link rel="import" href="../../components/paper-styles/typography.html">
|
||||||
|
<link rel="import" href="../../components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../../components/iron-icons/iron-icons.html">
|
||||||
|
<link rel="import" href="../../components/iron-icon/iron-icon.html">
|
||||||
|
<link rel="import" href="../../components/iron-icons/editor-icons.html">
|
||||||
|
<link rel="import" href="../../components/iron-collapse/iron-collapse.html">
|
||||||
|
<link rel="import" href="step-label-behavior.html">
|
||||||
|
<link rel="import" href="step-label-shared-styles.html">
|
||||||
|
|
||||||
|
<dom-module id="step-vertical">
|
||||||
|
<template>
|
||||||
|
<style include="step-label-shared-styles">
|
||||||
|
:host {
|
||||||
|
@apply(--layout-vertical);
|
||||||
|
}
|
||||||
|
#connectedBadge, #textWrapper {
|
||||||
|
pointer-events: none;
|
||||||
|
/* to be above paper-ripple*/
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
#collapse {
|
||||||
|
--iron-collapse-transition-duration: var(--paper-vertical-step-transition-duration, 500ms);
|
||||||
|
@apply(--layout-horizontal);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Content
|
||||||
|
*/
|
||||||
|
#connectedStep {
|
||||||
|
@apply(--layout-horizontal);
|
||||||
|
}
|
||||||
|
#contentConnectorLine {
|
||||||
|
width: 1px;
|
||||||
|
background: var(--divider-color, --paper-grey-300);
|
||||||
|
margin-left: 36px;
|
||||||
|
margin-right: 24px;
|
||||||
|
}
|
||||||
|
#stepWrapper {
|
||||||
|
@apply(--layout-flex);
|
||||||
|
/*should be 48px on large screen?*/
|
||||||
|
padding-right: 24px;
|
||||||
|
}
|
||||||
|
#paperStepWrapper {
|
||||||
|
max-height: calc(var(--paper-vertical-step-max-height, 400px) - 92px);
|
||||||
|
@apply(--layout-scroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Buttons
|
||||||
|
*/
|
||||||
|
#buttonsWrapper {
|
||||||
|
height: 48px;
|
||||||
|
@apply(--layout-horizontal);
|
||||||
|
@apply(--layout-center);
|
||||||
|
@apply(--layout-flex-none);
|
||||||
|
}
|
||||||
|
#buttonsWrapper > paper-button {
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
#continueButton {
|
||||||
|
--paper-button: {
|
||||||
|
background: var(--paper-vertical-step-continue-button-background, --primary-color);
|
||||||
|
color: var(--paper-vertical-step-continue-button-color, --dark-theme-text-color);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Label
|
||||||
|
*/
|
||||||
|
#textWrapper {
|
||||||
|
@apply(--layout-vertical);
|
||||||
|
padding: 8px 0 8px 8px;
|
||||||
|
}
|
||||||
|
#label {
|
||||||
|
@apply(--layout-horizontal);
|
||||||
|
}
|
||||||
|
#connectedBadge {
|
||||||
|
@apply(--layout-vertical);
|
||||||
|
@apply(--layout-center);
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
#beforeConnectorLine, #afterConnectorLine {
|
||||||
|
width: 1px;
|
||||||
|
background: var(--paper-step-connector-line-color, --divider-color);
|
||||||
|
}
|
||||||
|
#beforeConnectorLine {
|
||||||
|
height: 10px;
|
||||||
|
}
|
||||||
|
#afterConnectorLine {
|
||||||
|
@apply(--layout-flex);
|
||||||
|
}
|
||||||
|
#badge {
|
||||||
|
margin: 8px 0;
|
||||||
|
}
|
||||||
|
:host(.first-step) #beforeConnectorLine, :host(.lastStep) #contentConnectorLine{
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
:host(.last-step:not([opened])) #afterConnectorLine {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="label">
|
||||||
|
<div id="connectedBadge">
|
||||||
|
<div id="beforeConnectorLine"></div>
|
||||||
|
<div id="badge">
|
||||||
|
<iron-icon hidden$="{{!_computeIsIconBadge(icon)}}" icon="{{icon}}"></iron-icon>
|
||||||
|
<span hidden$="{{_computeIsIconBadge(icon)}}">{{index}}</span>
|
||||||
|
</div>
|
||||||
|
<div id="afterConnectorLine" class="connectorLine"></div>
|
||||||
|
</div>
|
||||||
|
<div id="textWrapper">
|
||||||
|
<span id="textLabel">[[label]]</span>
|
||||||
|
<template is="dom-if" if="[[optional]]">
|
||||||
|
<span id="optional">[[stepperData.optionalText]]</span>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<iron-collapse id="collapse" opened="[[opened]]">
|
||||||
|
<div id="contentConnectorLine"></div>
|
||||||
|
<div id="stepWrapper">
|
||||||
|
<div id="paperStepWrapper">
|
||||||
|
<content></content>
|
||||||
|
</div>
|
||||||
|
<div id="buttonsWrapper">
|
||||||
|
<paper-button id="continueButton" on-tap="continue">{{choosePrimaryButtonText(_attrForPrimaryButtonText, stepperData.continueText, stepperData.finishText, stepperData.updateText)}}</paper-button>
|
||||||
|
<paper-button id="backButton" disabled="[[!hasBackStep]]" on-tap="back" hidden$="[[!stepperData.hasBackButton]]">
|
||||||
|
[[stepperData.backText]]
|
||||||
|
</paper-button>
|
||||||
|
<paper-button id="skipButton" disabled="[[!canSkip]]" on-tap="skip" hidden$="[[!stepperData.hasSkipButton]]">
|
||||||
|
[[stepperData.skipText]]
|
||||||
|
</paper-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</iron-collapse>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
Polymer({
|
||||||
|
is: 'step-vertical',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
canSkip: {
|
||||||
|
type: Boolean
|
||||||
|
},
|
||||||
|
_attrForPrimaryButtonText: {
|
||||||
|
type: String,
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
hasBackStep: Boolean
|
||||||
|
},
|
||||||
|
|
||||||
|
behaviors: [
|
||||||
|
Stepper.StepLabelBehavior
|
||||||
|
],
|
||||||
|
|
||||||
|
skip: function() {
|
||||||
|
this.fire('paper-step-vertical-skip-tapped');
|
||||||
|
},
|
||||||
|
|
||||||
|
back: function() {
|
||||||
|
this.fire('paper-step-vertical-back-tapped');
|
||||||
|
},
|
||||||
|
|
||||||
|
continue: function() {
|
||||||
|
this.fire('paper-step-vertical-continue-tapped');
|
||||||
|
},
|
||||||
|
|
||||||
|
choosePrimaryButtonText: function(_attrForPrimaryButtonText) {
|
||||||
|
return this.stepperData[_attrForPrimaryButtonText];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</dom-module>
|
||||||
Reference in New Issue
Block a user