taiga-family / maskito

Collection of libraries to create an input mask which ensures that user types value according to predefined format.
https://maskito.dev
Apache License 2.0
1.36k stars 32 forks source link

🚀 - `Email` mask (recipe or kit) #200

Open nsbarsukov opened 1 year ago

nsbarsukov commented 1 year ago

Which package(s) are relevant/related to the feature request?

Don't known / other

Description

TODO: create a good spec for this task

Possible solutions:

waterplea commented 1 year ago

Possible feature - drop mailto: if it starts with it, for the case when you use "Copy link" on an email link.

pinetree commented 1 year ago

Hi!

How can I use a maskito for email-type input masking?

Let`s imagine I have a simple valid mask, i.e.

/^[a-zA-Z]+[^\s]{0,}@[a-zA-Z]+\.[a-zA-Z]{2,}/

(simplified deliberately)

Maskito doesn`t work with such a regex. It disallows to input nothing into the field. When I change mask to /^[a-zA-Z]+$/ (or any simple expression) - it allows to enter latin characters.

nsbarsukov commented 1 year ago

@pinetree Hi!

Let's imagine I have a simple valid mask, i.e. [...] Maskito doesn`t work with such a regex

Your mask should work with any of intermediate states, not just the final value.

Learn more: https://maskito.dev/core-concepts/mask-expression

warn
pinetree commented 1 year ago

Your mask should work with any of intermediate states, not just the final value.

So, as I understand there is no chances to implement "email mask" with just one "common" regex? The problem is: I need to disallow to start an email with non-latin characters (!@.- is prohibited). Also I need to disallow to type a "space". And the email should ends with a "domain" part with its own rules.

Yes, I can use a "common", not very strict regex and treat exceptions in a validation step. But maybe it`s possible)

Maybe the solution is to use "Dynamic mask expression"? What can you advice?

JavierLopezSCG commented 6 months ago

Hi taiga family! I'm too struggling to use the library to mask emails and I'm well aware you guys backlogged the recipe. In the meantime, is it that you guys can offer an example on how to implement Dynamic mask expression for emails as its such a common use case.. Thanks in advance

waterplea commented 6 months ago

I think you are conflating masking and validation. The point of mask library is to guide user input into a specific format. Validation is a separate concern. What I can suggest is make a loose mask with regex, use processors to disallow entering second @ symbol and then add a validator to check the value against your original strict regex. Depending on your framework you can use its validation techniques or this: https://developer.mozilla.org/en-US/docs/Web/API/HTMLObjectElement/setCustomValidity

Maybe you also should be using input type="email", I don't have much experience with it and what it brings to the table, other than specific keyboard on phones. However email inputs do not allow caret position manipulation, so Maskito currently doesn't work with it. This is a native limitation so while we might look into workarounds later, for now it is impossible.

JavierLopezSCG commented 6 months ago

Hi @waterplea, thanks for such answer. I'll be exploring more into processors. You're completely right in terms of what masks do, they're a guide after all. I don't intend to conflate both mask and validation, but yet I couldn't find much about Dynamic mask expression and/or non numerical examples. Can you illustrate this, maybe providing an additional example?

waterplea commented 6 months ago

@nsbarsukov do you have a good example for dynamic mask expression from which people can draw inspiration in this case?

nsbarsukov commented 6 months ago

@JavierLopezSCG

I've create oversimplified example for Google emails. https://stackblitz.com/edit/maskito-gmail

maskito@gmai| => Type 'm' => 'maskito@gmail.com|'
Empty textfile => Type '@' => Empty textfield
maskito@ => Type '@' => Textfield still equals to 'maskito@'

__

I can't give guarantees that my draft is bug-free solution! It is just a working proof of concept . If you find any bugs, you should complete this mask by yourself! Feel free to share your final solution with community and attach it to this issue.

waterplea commented 6 months ago

@nsbarsukov Here you are using processors, but what about dynamic form expression example?

nsbarsukov commented 6 months ago

@nsbarsukov Here you are using processors, but what about dynamic form expression example?

I've tried to use Dynamic mask expression to build draft of email mask. https://stackblitz.com/edit/maskito-gmail-dynamic-mask

Hovewer, I think the previous solution is better and more robust.

waterplea commented 6 months ago

Right. Anyway, the point of dynamic mask expression is instead of a static mask you have a function that takes ElementState as an argument each time a value is changed so you can return the correct expression for your particular state. I think email mask is not a good case for dynamic expression. Probably an IP mask is a good one: https://github.com/taiga-family/maskito/issues/252

It's pretty predictable and has a strict format, for example if you have first letter as 3-9 you are sure that the first block is a two digit number since the max is 255, therefore you can alter the mask accordingly. If you entered 35 you can auto insert a . symbol etc.