Files
DiceCloud/app/public/custom_components/paper-stepper/paper-step.html
2018-05-21 14:21:07 +02:00

425 lines
11 KiB
HTML

<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: 0;
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>