Skip to content

Commit

Permalink
feat(password): Add toggle for show / hide password and more events
Browse files Browse the repository at this point in the history
Added score event
Added feedback event
Added show event
Added hide event

BREAKING CHANGE
  • Loading branch information
apertureless committed Apr 9, 2018
1 parent c70e6f6 commit 5fa79e1
Show file tree
Hide file tree
Showing 3 changed files with 691 additions and 35 deletions.
55 changes: 49 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,53 @@ Interactive password strength meter based on [zxcvbn](https://github.com/dropbox
## 👈 Usage

```javascript

<template>
<password v-model="password"/>
</template>

<script>
import Password from 'vue-password-strength-meter'
export default {
components: { Password },
data () {
return {
password: null
}
}
data: () => ({
password: null
})
}
</script>

```
## 👈 With events

```javascript

<template>
<password v-model="password"></password>
<password
v-model="password"
:toggle="true"
@score="showScore"
@feedback="showFeedback"
/>
</template>

<script>
import Password from 'vue-password-strength-meter'
export default {
components: { Password },
data: () => ({
password: null
}),
methods: {
showFeedback ({suggestions, warning}) {
console.log('🙏', suggestions)
console.log('', warning)
},
showScore (score) {
console.log('💯', score)
}
}
}
</script>
```

## Props
Expand All @@ -49,12 +81,23 @@ Interactive password strength meter based on [zxcvbn](https://github.com/dropbox
| required | Boolean | true | input field required attribute |
| secureLength | Number | 7 | password min length |
| badge | Boolean | true | display password count badge |
| toggle | Boolean | false | show button to toggle password visibility |
| showPassword | Boolean | false | If you are not using the `toggle` button you can directly show / hide the password with this prop |
| defaultClass | String | Password__field | input field class |
| errorClass | String | Password__badge--error | error class for password count badge |
| successClass | String | Password__badge--success | success class for password count badge |
| strengthMeterClass | String | Password__strength-meter | strength-meter class |
| strengthMeterFillClass | String | Password__strength-meter--fill | strength-meter class for individual data fills |

## Events

### Show / Hide Password

- `@show` will be emitted if showing the password
- `@hide` will be emitted if hiding the password
- `@score` will return the zxcvbn score (Integer from 0-4) [] (https://github.com/dropbox/zxcvbn#usage)
- `@feedback` will return an zxcvbn feedback object with `suggestion` and `warning`

## 💅 Customizing

You can customize the styling of the input field, badge and strength-meter by passing your own css classes
Expand Down
120 changes: 106 additions & 14 deletions src/components/PasswordStrengthMeter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="Password">
<div class="Password__group">
<input
type="password"
:type="inputType"
ref="input"
v-bind:value="value"
v-on:input="emitValue($event.target.value)"
Expand All @@ -12,14 +12,31 @@
:placeholder="placeholder"
:required="required"
>

<div
class="Password__badge"
v-bind:class="[isSecure ? successClass : '', !isSecure && isActive ? errorClass : '' ]"
v-cloak
v-if="badge"
>
{{ passwordCount }}
<div class="Password__icons">
<div
v-if="badge"
v-bind:class="[isSecure ? successClass : '', !isSecure && isActive ? errorClass : '' ]"
class="Password__badge"
v-cloak
>
{{ passwordCount }}
</div>
<div
v-if="toggle"
class="Password__toggle">
<button
class="btn-clean"
@click="togglePassword()">
<svg v-if="this.$data._showPassword" version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>Show Password</title>
<path d="M12 9c1.641 0 3 1.359 3 3s-1.359 3-3 3-3-1.359-3-3 1.359-3 3-3zM12 17.016c2.766 0 5.016-2.25 5.016-5.016s-2.25-5.016-5.016-5.016-5.016 2.25-5.016 5.016 2.25 5.016 5.016 5.016zM12 4.5c5.016 0 9.281 3.094 11.016 7.5-1.734 4.406-6 7.5-11.016 7.5s-9.281-3.094-11.016-7.5c1.734-4.406 6-7.5 11.016-7.5z"></path>
</svg>
<svg v-else version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<title>Hide Password</title>
<path d="M11.859 9h0.141c1.641 0 3 1.359 3 3v0.188zM7.547 9.797c-0.328 0.656-0.563 1.406-0.563 2.203 0 2.766 2.25 5.016 5.016 5.016 0.797 0 1.547-0.234 2.203-0.563l-1.547-1.547c-0.188 0.047-0.422 0.094-0.656 0.094-1.641 0-3-1.359-3-3 0-0.234 0.047-0.469 0.094-0.656zM2.016 4.266l1.266-1.266 17.719 17.719-1.266 1.266c-1.124-1.11-2.256-2.213-3.375-3.328-1.359 0.563-2.813 0.844-4.359 0.844-5.016 0-9.281-3.094-11.016-7.5 0.797-1.969 2.109-3.656 3.75-4.969-0.914-0.914-1.812-1.844-2.719-2.766zM12 6.984c-0.656 0-1.266 0.141-1.828 0.375l-2.156-2.156c1.219-0.469 2.578-0.703 3.984-0.703 5.016 0 9.234 3.094 10.969 7.5-0.75 1.875-1.922 3.469-3.422 4.734l-2.906-2.906c0.234-0.563 0.375-1.172 0.375-1.828 0-2.766-2.25-5.016-5.016-5.016z"></path>
</svg>
</button>
</div>
</div>
</div>

Expand Down Expand Up @@ -93,6 +110,24 @@
type: Boolean,
default: true
},
/**
* Show password toggle:
* Show icon to toggle
* the password visibility
*/
toggle: {
type: Boolean,
default: false
},
/**
* Prop to toggle the
* cleartext password if
* toggle is disabled
*/
showPassword: {
type: Boolean,
default: false
},
/**
* CSS Class for the Input field
* @type {String}
Expand Down Expand Up @@ -144,7 +179,8 @@
},
data () {
return {
password: null
password: null,
_showPassword: false
}
},
Expand All @@ -156,6 +192,15 @@
emitValue (value) {
this.password = value
this.$emit('input', value)
},
togglePassword () {
if (this.$data._showPassword) {
this.$emit('hide')
this.$data._showPassword = false
} else {
this.$emit('show')
this.$data._showPassword = true
}
}
},
Expand Down Expand Up @@ -193,12 +238,26 @@
*/
passwordCount () {
return this.password && (this.password.length > this.secureLength ? `${this.secureLength}+` : this.password.length)
},
/**
* Changing the input type from password to text
* based on the local _showPassword data or the showPassword prop
*/
inputType () {
return this.$data._showPassword || this.showPassword ? 'text' : 'password'
}
},
watch: {
passwordStrength (score) {
this.$emit('score', score)
this.$emit('feedback', zxcvbn(this.password).feedback)
}
}
}
</script>

<style>
<style lang="scss">
[v-cloak] {
display: none;
}
Expand Down Expand Up @@ -285,18 +344,32 @@
width: 100%;
}
.Password__icons {
position: absolute;
top: 0;
right: 0;
height: 100%;
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
}
.Password__toggle {
line-height: 1.1;
margin-right: 13px;
}
.Password__badge {
float: right;
position: relative;
bottom: 33px;
right: 10px;
color: white;
border-radius: 6px;
padding: 3px;
width: 30px;
height: 15px;
font-size: 14px;
line-height: 1.1;
margin-right: 13px;
}
.Password__badge--error {
Expand All @@ -306,4 +379,23 @@
.Password__badge--success {
background: #1bbf1b;
}
.btn-clean {
appearance: none;
background: none;
border: none;
cursor: pointer;
outline: none;
color: #777777;
padding: 0;
svg {
fill: currentColor;
}
&:hover, &:focus {
color: #404B69;
}
}
</style>
Loading

0 comments on commit 5fa79e1

Please sign in to comment.