@vaadin/vaadin-login
Advanced tools
Comparing version 1.0.0-alpha5 to 1.0.0-alpha6
@@ -13,3 +13,3 @@ { | ||
"name": "@vaadin/vaadin-login", | ||
"version": "1.0.0-alpha5", | ||
"version": "1.0.0-alpha6", | ||
"main": "vaadin-login.js", | ||
@@ -40,3 +40,2 @@ "author": "Vaadin Ltd", | ||
"@vaadin/vaadin-button": "^2.1.0", | ||
"@polymer/iron-form": "^3.0.0-pre.18", | ||
"@vaadin/vaadin-overlay": "^3.2.1" | ||
@@ -43,0 +42,0 @@ }, |
@@ -10,3 +10,3 @@ /** | ||
*/ | ||
export const LoginMixin = subclass => class VaadinLoginMixin extends subclass { | ||
export const LoginMixin = superClass => class LoginMixin extends superClass { | ||
@@ -116,2 +116,52 @@ /** | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
this._handleInputKeydown = this._handleInputKeydown.bind(this); | ||
} | ||
submit() { | ||
if (this.disabled || !(LoginMixin.__isValid(this.$.username) && LoginMixin.__isValid(this.$.password))) { | ||
return; | ||
} | ||
this.error = false; | ||
this.disabled = true; | ||
const loginEventDetails = { | ||
bubbles: true, | ||
cancelable: true, | ||
detail: { | ||
username: this.$.username.value, | ||
password: this.$.password.value | ||
} | ||
}; | ||
const firedEvent = this.dispatchEvent(new CustomEvent('login', loginEventDetails)); | ||
if (this.action && firedEvent) { | ||
this.$.loginForm.submit(); | ||
} | ||
} | ||
static __isValid(input) { | ||
return (input.validate && input.validate()) || (input.checkValidity && input.checkValidity()); | ||
} | ||
static _isEnterKey(e) { | ||
return e.key === 'Enter' || e.keyCode === 13; | ||
} | ||
_handleInputKeydown(e) { | ||
if (LoginMixin._isEnterKey(e)) { | ||
const {currentTarget: inputActive} = e; | ||
const nextInput = inputActive.id === 'username' | ||
? this.$.password : this.$.username; | ||
if (LoginMixin.__isValid(inputActive)) { | ||
if (LoginMixin.__isValid(nextInput)) { | ||
this.submit(); | ||
} else { | ||
nextInput.focus(); | ||
} | ||
} | ||
} | ||
} | ||
}; |
@@ -13,3 +13,3 @@ /** | ||
import { LoginMixin } from './vaadin-login-mixin.js'; | ||
import './vaadin-login-overlay-element.js'; | ||
import './vaadin-login-overlay-wrapper.js'; | ||
import { html } from '@polymer/polymer/lib/utils/html-tag.js'; | ||
@@ -26,20 +26,33 @@ /** | ||
* @mixes Vaadin.ThemableMixin | ||
* @mixes Vaadin.LoginMixin | ||
* @mixes Vaadin.Login.LoginMixin | ||
* @demo demo/index.html | ||
*/ | ||
class VaadinLoginOverlay extends LoginMixin(ElementMixin(ThemableMixin(PolymerElement))) { | ||
class LoginOverlayElement extends LoginMixin(ElementMixin(ThemableMixin(PolymerElement))) { | ||
static get template() { | ||
return html` | ||
<vaadin-login-overlay-element id="overlay" opened="{{opened}}" focus-trap="" with-backdrop="" title="[[title]]" description="[[description]]"> | ||
<style> | ||
vaadin-text-field, | ||
vaadin-password-field, | ||
#submit { | ||
width: 100%; | ||
} | ||
</style> | ||
<vaadin-login-overlay-wrapper id="wrapper" opened="{{opened}}" focus-trap="" with-backdrop="" title="[[title]]" description="[[description]]" theme\$="[[theme]]"> | ||
<vaadin-login theme="with-overlay" id="login" action="{{action}}" disabled="{{disabled}}" error="{{error}}" no-forgot-password="{{noForgotPassword}}" i18n="{{i18n}}" on-login="_handleEvent" on-forgot-password="_handleEvent"> | ||
<vaadin-text-field slot="username" label="[[i18n.form.username]]" name="username" id="username" required=""> | ||
<input type="text" slot="input"> | ||
</vaadin-text-field> | ||
<vaadin-password-field slot="password" label="[[i18n.form.password]]" name="password" id="password" required=""> | ||
<input type="password" slot="input"> | ||
</vaadin-password-field> | ||
<form id="loginForm" method="POST" action\$="[[action]]" slot="form"> | ||
<vaadin-text-field label="[[i18n.form.username]]" id="username" required="" on-keydown="_handleInputKeydown"> | ||
<input name="username" type="text" slot="input"> | ||
</vaadin-text-field> | ||
<vaadin-password-field label="[[i18n.form.password]]" id="password" required="" on-keydown="_handleInputKeydown"> | ||
<input name="password" type="password" slot="input"> | ||
</vaadin-password-field> | ||
<vaadin-button id="submit" theme="primary contained" on-click="submit" disabled\$="[[disabled]]">[[i18n.form.submit]]</vaadin-button> | ||
</form> | ||
</vaadin-login> | ||
</vaadin-login-overlay-element> | ||
</vaadin-login-overlay-wrapper> | ||
`; | ||
@@ -73,2 +86,9 @@ } | ||
value: 'App name' | ||
}, | ||
/** | ||
* Defines the theme of the element. | ||
* The value is propagated to vaadin-login-overlay-wrapper element. | ||
*/ | ||
theme: { | ||
type: String | ||
} | ||
@@ -93,4 +113,4 @@ }; | ||
this.$.overlay.addEventListener('vaadin-overlay-outside-click', this._preventClosingLogin); | ||
this.$.overlay.addEventListener('vaadin-overlay-escape-press', this._preventClosingLogin); | ||
this.$.wrapper.addEventListener('vaadin-overlay-outside-click', this._preventClosingLogin); | ||
this.$.wrapper.addEventListener('vaadin-overlay-escape-press', this._preventClosingLogin); | ||
} | ||
@@ -101,5 +121,5 @@ | ||
this.$.overlay.removeEventListener('vaadin-overlay-outside-click', this._preventClosingLogin); | ||
this.$.overlay.removeEventListener('vaadin-overlay-escape-press', this._preventClosingLogin); | ||
this.$.overlay.opened = false; | ||
this.$.wrapper.removeEventListener('vaadin-overlay-outside-click', this._preventClosingLogin); | ||
this.$.wrapper.removeEventListener('vaadin-overlay-escape-press', this._preventClosingLogin); | ||
this.$.wrapper.opened = false; | ||
} | ||
@@ -148,3 +168,3 @@ | ||
// https://github.com/vaadin/vaadin-overlay/blob/041cde4481b6262eac68d3a699f700216d897373/src/vaadin-overlay.html#L660 | ||
document.body.style.pointerEvents = this.$.overlay._previousDocumentPointerEvents; | ||
document.body.style.pointerEvents = this.$.wrapper._previousDocumentPointerEvents; | ||
} | ||
@@ -154,7 +174,5 @@ } | ||
_teleport(elements) { | ||
const teleported = []; | ||
for (const e of elements) { | ||
this.$.overlay.appendChild(e); | ||
teleported.push(e); | ||
} | ||
const teleported = Array.from(elements).map(e => { | ||
return this.$.wrapper.appendChild(e); | ||
}); | ||
// Function to undo the teleport | ||
@@ -176,4 +194,4 @@ return () => { | ||
customElements.define(VaadinLoginOverlay.is, VaadinLoginOverlay); | ||
customElements.define(LoginOverlayElement.is, LoginOverlayElement); | ||
export { VaadinLoginOverlay }; | ||
export { LoginOverlayElement }; |
@@ -12,3 +12,2 @@ /** | ||
import { LoginMixin } from './vaadin-login-mixin.js'; | ||
import '@polymer/iron-form/iron-form.js'; | ||
import '@vaadin/vaadin-text-field/src/vaadin-text-field.js'; | ||
@@ -18,3 +17,2 @@ import '@vaadin/vaadin-text-field/src/vaadin-password-field.js'; | ||
import { html } from '@polymer/polymer/lib/utils/html-tag.js'; | ||
import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js'; | ||
@@ -31,6 +29,6 @@ /** | ||
* @mixes Vaadin.ThemableMixin | ||
* @mixes Vaadin.LoginMixin | ||
* @mixes Vaadin.Login.LoginMixin | ||
* @demo demo/index.html | ||
*/ | ||
class VaadinLogin extends LoginMixin(ElementMixin(ThemableMixin(PolymerElement))) { | ||
class LoginElement extends LoginMixin(ElementMixin(ThemableMixin(PolymerElement))) { | ||
static get template() { | ||
@@ -55,10 +53,7 @@ return html` | ||
[part="form"] h2 { | ||
[part="form-title"] { | ||
margin: 0; | ||
} | ||
vaadin-text-field, | ||
vaadin-password-field, | ||
[part="form"] form ::slotted(*), | ||
#submit { | ||
#loginForm * { | ||
width: 100%; | ||
@@ -72,27 +67,27 @@ } | ||
<section part="form"> | ||
<h2>[[i18n.form.title]]</h2> | ||
<h2 part="form-title">[[i18n.form.title]]</h2> | ||
<div part="error-message" hidden\$="[[!error]]"> | ||
<h5>[[i18n.errorMessage.title]]</h5> | ||
<p>[[i18n.errorMessage.message]]</p> | ||
<h5 part="error-message-title">[[i18n.errorMessage.title]]</h5> | ||
<p part="error-message-description">[[i18n.errorMessage.message]]</p> | ||
</div> | ||
<iron-form id="loginForm" allow-redirect=""> | ||
<form method="POST" action\$="[[action]]"> | ||
<slot name="username" id="usernameSlot"> | ||
<vaadin-text-field label="[[i18n.form.username]]" name="username" id="username" required="" on-keydown="_handleInputKeydown"> | ||
</vaadin-text-field> | ||
</slot> | ||
<slot name="password" id="passwordSlot"> | ||
<vaadin-password-field label="[[i18n.form.password]]" name="password" id="password" required="" on-keydown="_handleInputKeydown"> | ||
</vaadin-password-field> | ||
</slot> | ||
<slot name="form"> | ||
<form id="loginForm" method="POST" action\$="[[action]]"> | ||
<vaadin-text-field label="[[i18n.form.username]]" id="username" required="" on-keydown="_handleInputKeydown"> | ||
<input name="username" type="text" slot="input"> | ||
</vaadin-text-field> | ||
<vaadin-password-field label="[[i18n.form.password]]" id="password" required="" on-keydown="_handleInputKeydown"> | ||
<input name="password" type="password" slot="input"> | ||
</vaadin-password-field> | ||
<vaadin-button id="submit" theme="primary contained" on-click="submit" disabled\$="[[disabled]]">[[i18n.form.submit]]</vaadin-button> | ||
</form> | ||
</iron-form> | ||
</slot> | ||
<vaadin-button id="forgotPasswordButton" theme="tertiary small" on-click="_forgotPassword" hidden\$="[[noForgotPassword]]">[[i18n.form.forgotPassword]]</vaadin-button> | ||
<div part="footer"> | ||
<p>[[i18n.additionalInformation]]</p> | ||
</div> | ||
<slot name="footer"> | ||
<span>[[i18n.additionalInformation]]</span> | ||
</slot> | ||
</section> | ||
@@ -106,92 +101,12 @@ `; | ||
static get version() { | ||
return '1.0.0-alpha5'; | ||
return '1.0.0-alpha6'; | ||
} | ||
connectedCallback() { | ||
super.connectedCallback(); | ||
this._handleInputKeydown = this._handleInputKeydown.bind(this); | ||
this._usernameSlotObserver = this._createSlotObserver(this.$.usernameSlot, 'username'); | ||
this._passwordSlotObserver = this._createSlotObserver(this.$.passwordSlot, 'password'); | ||
} | ||
_createSlotObserver(slot, field) { | ||
return new FlattenedNodesObserver(slot, (info) => { | ||
const removedNodes = info.removedNodes.filter(node => node.nodeType === Node.ELEMENT_NODE); | ||
// look for slot=${field} | ||
const element = this.querySelector(`[slot=${field}]`); | ||
const fallbackElement = this.shadowRoot.querySelector(`:not(slot)[name=${field}]`); | ||
if (element) { | ||
fallbackElement.disabled = true; | ||
this.$[field] = element; | ||
this.$[field].addEventListener('keydown', this._handleInputKeydown); | ||
} | ||
if (removedNodes[0] === this.$[field]) { | ||
this.$[field] = fallbackElement; | ||
this.$[field].disabled = false; | ||
} | ||
}); | ||
} | ||
disconnectedCallback() { | ||
super.disconnectedCallback(); | ||
this._passwordSlotObserver && this._passwordSlotObserver.disconnect(); | ||
this._usernameSlotObserver && this._usernameSlotObserver.disconnect(); | ||
} | ||
submit() { | ||
if (this.disabled || !(this.__isValid(this.$.username) && this.__isValid(this.$.password))) { | ||
return; | ||
} | ||
this.error = false; | ||
this.disabled = true; | ||
const loginEventDetails = { | ||
bubbles: true, | ||
cancelable: true, | ||
detail: { | ||
username: this.$.username.value, | ||
password: this.$.password.value | ||
} | ||
}; | ||
const loginEvent = new CustomEvent('login', loginEventDetails); | ||
this.dispatchEvent(loginEvent); | ||
if (this.action && !loginEvent.defaultPrevented) { | ||
this.$.loginForm.submit(); | ||
} | ||
} | ||
_forgotPassword() { | ||
this.dispatchEvent(new CustomEvent('forgot-password')); | ||
} | ||
_handleInputKeydown(e) { | ||
if (this._isEnterKey(e)) { | ||
const {currentTarget: inputActive} = e; | ||
const nextInput = inputActive.slot === 'username' || inputActive.name === 'username' | ||
? this.$.password : this.$.username; | ||
if (this.__isValid(inputActive)) { | ||
if (this.__isValid(nextInput)) { | ||
this.submit(); | ||
} else { | ||
nextInput.focus(); | ||
} | ||
} | ||
} | ||
} | ||
__isValid(input) { | ||
return (input.validate && input.validate()) || (input.checkValidity && input.checkValidity()); | ||
} | ||
_isEnterKey(e) { | ||
return e.key === 'Enter' || e.keyCode === 13; | ||
} | ||
} | ||
customElements.define(VaadinLogin.is, VaadinLogin); | ||
customElements.define(LoginElement.is, LoginElement); | ||
export { VaadinLogin }; | ||
export { LoginElement }; |
@@ -8,3 +8,3 @@ import '@vaadin/vaadin-lumo-styles/color.js'; | ||
const $_documentContainer = html`<dom-module id="vaadin-login-overlay-element-lumo-styles" theme-for="vaadin-login-overlay-element"> | ||
const $_documentContainer = html`<dom-module id="vaadin-login-overlay-wrapper-lumo-styles" theme-for="vaadin-login-overlay-wrapper"> | ||
<template> | ||
@@ -55,3 +55,3 @@ <style include="lumo-color lumo-typography"> | ||
[part="brand"] p { | ||
[part="description"] { | ||
line-height: var(--lumo-line-height-s); | ||
@@ -195,4 +195,15 @@ color: var(--lumo-tint-70pct); | ||
</template> | ||
</dom-module>`; | ||
</dom-module><custom-style> | ||
<style> | ||
vaadin-login-overlay-wrapper vaadin-login #submit { | ||
margin-top: var(--lumo-space-l); | ||
margin-bottom: var(--lumo-space-s); | ||
} | ||
vaadin-login-overlay-wrapper vaadin-login #loginForm * { | ||
width: 100%; | ||
} | ||
</style> | ||
</custom-style>`; | ||
document.head.appendChild($_documentContainer.content); |
@@ -18,3 +18,3 @@ import '@vaadin/vaadin-lumo-styles/color.js'; | ||
[part="form"] h2 { | ||
[part="form-title"] { | ||
margin-top: calc(var(--lumo-font-size-xxxl) - var(--lumo-font-size-xxl)); | ||
@@ -55,3 +55,3 @@ } | ||
[part="error-message"] h5 { | ||
[part="error-message-title"] { | ||
margin: 0 0 0.25em; | ||
@@ -61,3 +61,3 @@ color: inherit; | ||
[part="error-message"] p { | ||
[part="error-message-description"] { | ||
font-size: var(--lumo-font-size-s); | ||
@@ -69,3 +69,3 @@ line-height: var(--lumo-line-height-s); | ||
[part="footer"] { | ||
[name="footer"] { | ||
font-size: var(--lumo-font-size-xs); | ||
@@ -72,0 +72,0 @@ line-height: var(--lumo-line-height-s); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
8
42736
791
- Removed@polymer/iron-form@^3.0.0-pre.18
- Removed@polymer/iron-ajax@3.0.1(transitive)
- Removed@polymer/iron-form@3.0.1(transitive)