Implemented PasswordStrength Component
parent
e128009632
commit
d26626a969
|
@ -14,6 +14,7 @@
|
||||||
<router-link to="/inputswitch">● InputSwitch</router-link>
|
<router-link to="/inputswitch">● InputSwitch</router-link>
|
||||||
<router-link to="/inputtext">● InputText</router-link>
|
<router-link to="/inputtext">● InputText</router-link>
|
||||||
<router-link to="/listbox">● Listbox</router-link>
|
<router-link to="/listbox">● Listbox</router-link>
|
||||||
|
<router-link to="/password">● Password</router-link>
|
||||||
<router-link to="/radiobutton">● RadioButton</router-link>
|
<router-link to="/radiobutton">● RadioButton</router-link>
|
||||||
<router-link to="/rating">● Rating</router-link>
|
<router-link to="/rating">● Rating</router-link>
|
||||||
<router-link to="/selectbutton">● SelectButton</router-link>
|
<router-link to="/selectbutton">● SelectButton</router-link>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
@import '../../components/inputswitch/InputSwitch.css';
|
@import '../../components/inputswitch/InputSwitch.css';
|
||||||
@import '../../components/listbox/Listbox.css';
|
@import '../../components/listbox/Listbox.css';
|
||||||
@import '../../components/panel/Panel.css';
|
@import '../../components/panel/Panel.css';
|
||||||
|
@import '../../components/password/Password.css';
|
||||||
@import '../../components/progressbar/ProgressBar.css';
|
@import '../../components/progressbar/ProgressBar.css';
|
||||||
@import '../../components/radiobutton/RadioButton.css';
|
@import '../../components/radiobutton/RadioButton.css';
|
||||||
@import '../../components/rating/Rating.css';
|
@import '../../components/rating/Rating.css';
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
.p-password-panel {
|
||||||
|
padding: .25em .5em;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-password-panel .p-password-meter {
|
||||||
|
height: 10px;
|
||||||
|
background:transparent url("./images/password-meter.png") no-repeat left top;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-password-info {
|
||||||
|
margin-top: .25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-password-panel-overlay {
|
||||||
|
position: absolute;
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
<template>
|
||||||
|
<input ref="input" type="password" :class="['p-inputtext p-component', {'p-filled': filled}]" v-on="listeners" :value="value" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DomHandler from '../utils/DomHandler';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: String,
|
||||||
|
promptLabel: {
|
||||||
|
type: String,
|
||||||
|
default: 'Enter a password'
|
||||||
|
},
|
||||||
|
weakLabel: {
|
||||||
|
type: String,
|
||||||
|
default: 'Weak'
|
||||||
|
},
|
||||||
|
mediumLabel: {
|
||||||
|
type: String,
|
||||||
|
default: 'Medium'
|
||||||
|
},
|
||||||
|
strongLabel: {
|
||||||
|
type: String,
|
||||||
|
default: 'Strong'
|
||||||
|
},
|
||||||
|
feedback: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
panel: null,
|
||||||
|
meter: null,
|
||||||
|
info: null,
|
||||||
|
methods: {
|
||||||
|
testStrength(str) {
|
||||||
|
let grade = 0;
|
||||||
|
let val;
|
||||||
|
|
||||||
|
val = str.match('[0-9]');
|
||||||
|
grade += this.normalize(val ? val.length : 1/4, 1) * 25;
|
||||||
|
|
||||||
|
val = str.match('[a-zA-Z]');
|
||||||
|
grade += this.normalize(val ? val.length : 1/2, 3) * 10;
|
||||||
|
|
||||||
|
val = str.match('[!@#$%^&*?_~.,;=]');
|
||||||
|
grade += this.normalize(val ? val.length : 1/6, 1) * 35;
|
||||||
|
|
||||||
|
val = str.match('[A-Z]');
|
||||||
|
grade += this.normalize(val ? val.length : 1/6, 1) * 30;
|
||||||
|
|
||||||
|
grade *= str.length / 8;
|
||||||
|
|
||||||
|
return grade > 100 ? 100 : grade;
|
||||||
|
},
|
||||||
|
normalize(x, y) {
|
||||||
|
let diff = x - y;
|
||||||
|
|
||||||
|
if(diff <= 0)
|
||||||
|
return x / y;
|
||||||
|
else
|
||||||
|
return 1 + 0.5 * (x / (x + y/4));
|
||||||
|
},
|
||||||
|
createPanel() {
|
||||||
|
this.panel = document.createElement('div');
|
||||||
|
this.panel.className = 'p-password-panel p-component p-hidden p-password-panel-overlay p-input-overlay';
|
||||||
|
this.meter = document.createElement('div');
|
||||||
|
this.meter.className = 'p-password-meter';
|
||||||
|
this.info = document.createElement('div');
|
||||||
|
this.info.className = 'p-password-info';
|
||||||
|
this.info.textContent = this.promptLabel;
|
||||||
|
|
||||||
|
this.panel.style.minWidth = DomHandler.getOuterWidth(this.$refs.input) + 'px';
|
||||||
|
this.panel.appendChild(this.meter);
|
||||||
|
this.panel.appendChild(this.info);
|
||||||
|
document.body.appendChild(this.panel);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
listeners() {
|
||||||
|
return {
|
||||||
|
...this.$listeners,
|
||||||
|
input: event => this.$emit('input', event.target.value),
|
||||||
|
focus: event => {
|
||||||
|
if (this.feedback) {
|
||||||
|
if (!this.panel) {
|
||||||
|
this.createPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.panel.style.zIndex = String(DomHandler.generateZIndex());
|
||||||
|
this.panel.style.display = 'block';
|
||||||
|
setTimeout(() => {
|
||||||
|
DomHandler.addClass(this.panel, 'p-input-overlay-visible');
|
||||||
|
DomHandler.removeClass(this.panel, 'p-input-overlay-hidden');
|
||||||
|
}, 1);
|
||||||
|
DomHandler.absolutePosition(this.panel, this.$refs.input);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('focus', event);
|
||||||
|
},
|
||||||
|
blur: event => {
|
||||||
|
if (this.panel) {
|
||||||
|
DomHandler.addClass(this.panel, 'p-input-overlay-hidden');
|
||||||
|
DomHandler.removeClass(this.panel, 'p-input-overlay-visible');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.panel.style.display = 'none';
|
||||||
|
DomHandler.removeClass(this.panel, 'p-input-overlay-hidden');
|
||||||
|
}, 150);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('blur', event);
|
||||||
|
},
|
||||||
|
keyup: event => {
|
||||||
|
if(this.panel) {
|
||||||
|
let value = event.target.value;
|
||||||
|
let label = null;
|
||||||
|
let meterPos = null;
|
||||||
|
|
||||||
|
if (value.length === 0) {
|
||||||
|
label = this.promptLabel;
|
||||||
|
meterPos = '0px 0px';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let score = this.testStrength(value);
|
||||||
|
|
||||||
|
if (score < 30) {
|
||||||
|
label = this.weakLabel;
|
||||||
|
meterPos = '0px -10px';
|
||||||
|
}
|
||||||
|
else if (score >= 30 && score < 80) {
|
||||||
|
label = this.mediumLabel;
|
||||||
|
meterPos = '0px -20px';
|
||||||
|
}
|
||||||
|
else if (score >= 80) {
|
||||||
|
label = this.strongLabel;
|
||||||
|
meterPos = '0px -30px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.meter.style.backgroundPosition = meterPos;
|
||||||
|
this.info.textContent = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('keyup', event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
filled() {
|
||||||
|
return (this.value != null && this.value.toString().length > 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
Binary file not shown.
After Width: | Height: | Size: 118 B |
|
@ -13,6 +13,7 @@ import InputText from './components/inputtext/InputText';
|
||||||
import Fieldset from './components/fieldset/Fieldset';
|
import Fieldset from './components/fieldset/Fieldset';
|
||||||
import Listbox from './components/listbox/Listbox';
|
import Listbox from './components/listbox/Listbox';
|
||||||
import Panel from './components/panel/Panel';
|
import Panel from './components/panel/Panel';
|
||||||
|
import Password from './components/password/Password';
|
||||||
import ProgressBar from './components/progressbar/ProgressBar';
|
import ProgressBar from './components/progressbar/ProgressBar';
|
||||||
import Rating from './components/rating/Rating';
|
import Rating from './components/rating/Rating';
|
||||||
import RadioButton from './components/radiobutton/RadioButton';
|
import RadioButton from './components/radiobutton/RadioButton';
|
||||||
|
@ -44,6 +45,7 @@ Vue.component('p-inputtext', InputText);
|
||||||
Vue.component('p-listbox', Listbox);
|
Vue.component('p-listbox', Listbox);
|
||||||
Vue.component('p-fieldset', Fieldset);
|
Vue.component('p-fieldset', Fieldset);
|
||||||
Vue.component('p-panel', Panel);
|
Vue.component('p-panel', Panel);
|
||||||
|
Vue.component('p-password', Password);
|
||||||
Vue.component('p-progressBar', ProgressBar);
|
Vue.component('p-progressBar', ProgressBar);
|
||||||
Vue.component('p-radioButton', RadioButton);
|
Vue.component('p-radioButton', RadioButton);
|
||||||
Vue.component('p-rating', Rating);
|
Vue.component('p-rating', Rating);
|
||||||
|
|
|
@ -71,6 +71,11 @@ export default new Router({
|
||||||
name: 'panel',
|
name: 'panel',
|
||||||
component: () => import('./views/panel/PanelDemo.vue')
|
component: () => import('./views/panel/PanelDemo.vue')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/password',
|
||||||
|
name: 'password',
|
||||||
|
component: () => import('./views/password/PasswordDemo.vue')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/progressbar',
|
path: '/progressbar',
|
||||||
name: 'progressbar',
|
name: 'progressbar',
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="content-section introduction">
|
||||||
|
<div class="feature-intro">
|
||||||
|
<h1>Password</h1>
|
||||||
|
<p>Password displays strength indicator for password fields.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-section implementation">
|
||||||
|
<p-password v-model="value" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
</style>
|
Loading…
Reference in New Issue