DEV Community

Cover image for Password Creation in Svelte
CodeCadim by Brahim Hamdouni
CodeCadim by Brahim Hamdouni

Posted on • Edited on

Password Creation in Svelte

So, a few days ago, I saw a video showing a password creation form.

Password chooser UI

Each time the user types anything, there is an instant validation with icons indicating which constraint is fulfilled.

I thought it was a nice way to give instant feedback to the user. But can I reproduce this behaviour using Svelte ? Let's see !

First, let's setup a new Svelte project using esbuild. You can follow instructions in my post Setup a Svelte project using ESBuild

We'll start with one rule : the password length is 8 characters minimum. This way, we can "feel" how we can solve the problem for all the controls, setup all needed elements, without having too much in our plate. Change the app.svelte file as below :

<svelte:options customElement="app-input" />

<script>
let pass = "";
let validLength = false;

function check() {
   validLength = (pass.length >= 8);
}
$: check(pass);
</script>

<input bind:value={pass} type="password">
<span class:valid={validLength}> 8+ </span>

<style>
.valid {background-color: green;}
</style>
Enter fullscreen mode Exit fullscreen mode

If we try this, we can see that nothing happens if we type a password until it reaches 8 characters length : then the 8+ background changes to green !

Let's review the code to understand what is happening here.

In the script section, we start by declaring two variables :

pass will contain the user input

validLength will indicate if the length rule is respected or not

Then, we define the check function : a straight forward validation of the password length.

The next line is more interesting. We use the $: directive to monitor any change to the password and check its validity.

$: check(pass);
Enter fullscreen mode Exit fullscreen mode

So now, every time the variable pass is changed, Svelte will invoke the check function.

Below the script section, we define the html part by declaring the input field.
It will be automatically bound to the pass variable.

<input bind:value={pass} type="password">
Enter fullscreen mode Exit fullscreen mode

So, when the user enters characters in the input field, Svelte takes care of updating the pass variable.

In Svelte, we can also bind a css class to an element. Here, the span tag will be assigned the css class valid only if the validLengh variable is true.

<span class:valid={validLength}> 8+ </span>
Enter fullscreen mode Exit fullscreen mode

The valid class is defined in the style section : just a green background.

.valid {background-color: green;}
Enter fullscreen mode Exit fullscreen mode

This is roughly all we need : the mechanism to live check the password for every keystroke and changing dynamically the style. So for the other controls, we'll apply the same logic.

To check if the password contains lower and upper case characters, we'll declare a new variable validCase :

let validCase = false;
Enter fullscreen mode Exit fullscreen mode

Then we'll add the html part :

<span class:valid={validCase}> a..Z </span>
Enter fullscreen mode Exit fullscreen mode

Finally, we'll complete our check function to add the control :

validCase = pass.toUpperCase() != pass && pass.toLowerCase() != pass;
Enter fullscreen mode Exit fullscreen mode

The trick here is to compare the password to its upper and lower case versions.
The control fails if it is the same as one of them.

OK, for the last control, the presence of a special character, we'll add this html :

<span class:valid={validSpecial}>~&#</span>
Enter fullscreen mode Exit fullscreen mode

And we'll apply a regular expression in the check function :

validSpecial = pass.replaceAll(/\w/g, "").length > 0;
Enter fullscreen mode Exit fullscreen mode

This will remove all non-special characters and if it remains something, then there is at least one special character.

That is all, folks ! We have now a complete password creation form with live checking controls and instant feedback, with Svelte in one web component !

You can find the complete code in my repo Tuto Svelte Password.

Top comments (10)

Collapse
 
artxe2 profile image
Yeom suyun

I think I would write the check function like this.

<script>
let pass = ""
let is_valid_length
let is_valid_case
let is_valid_special

const invalid_word_regex = /[\s<>]/g
const check_case_regex = /(?=.*[a-z])(?=.*[A-Z])/
const check_special_regex = /\W/

$: {
  pass = pass.replace(invalid_word_regex, "")
  is_valid_length = pass.length >= 8
  is_valid_case = check_case_regex.test(pass)
  is_valid_special = check_special_regex.test(pass)
}
</script>
<style>
  .valid {
    color: green
  }
</style>

<input bind:value={pass}>

<span class:valid={is_valid_length}>+8</span>
<span class:valid={is_valid_case}>a..Z</span>
<span class:valid={is_valid_special}>~&#</span>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
barim profile image
CodeCadim by Brahim Hamdouni

Totally valid way of using regex :-)

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

The individual check UI elements should be in their own component. Either make specialized components that know the rule to apply and then simply pass the password, or make a general component that receives either the validation function or the result of said validation function and then simply change in color.

Still, it is a nice UI for password setting.

Collapse
 
barim profile image
CodeCadim by Brahim Hamdouni

I'm not sure it's worth it to separate in individual components for each check for such a small piece of code : we loose the global readability of the rules to apply to the password.

Collapse
 
webjose profile image
José Pablo Ramírez Vargas

Separating them provides the ability to create different rules for different passwords. Most systems require only one password, but a few might require different passwords with different restrictions. Furthermore, if this ultimately were encapsulated in a library, for it to be the most effective cannot impose a fixed set of password rules. It needs to be versatile.

Thread Thread
 
barim profile image
CodeCadim by Brahim Hamdouni

totally agree for this contexts it makes sense :)

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
webjose profile image
José Pablo Ramírez Vargas

Not the place for this. I recommend deleting and posting in, say, stackoverflow.com.

Collapse
 
artxe2 profile image
Yeom suyun

I'm not sure why this question was posted here, but React Router has changed its usage since v6, but it seems like you've installed v6 and written a v5 syntax.

Collapse
 
logan1o1 profile image
Saswat Mahapatra

ok thank you and I'll delete it didn't know sorry