Git Product home page Git Product logo

use-mask-input's Introduction

🥸 use-mask-input

A React Hook for build elegant and simple input masks.

npm npm package minimized gzipped size (select exports) npm

Table of Contents

Features

Install

npm i use-mask-input

Quickstart

import React from 'react'
import { withMask } from 'use-mask-input';

const App = () => {
  return (
    <input type="text" ref={withMask('9999-9999')} />
  )
}

Usage with React Hook Forms

import React from 'react';
import { useForm } from 'react-hook-form';
import { useHookFormMask } from 'use-mask-input';

function App() {
  const { register, handleSubmit } = useForm();
  const registerWithMask = useHookFormMask(register);

  ...

  return (
    <form onSubmit={onSubmit}>
      <input
        {...registerWithMask("phone", ['99 9999-9999', '99999-9999'], {
          required: true
        })}
        type="text"
      />
      <button type="submit">Submit</button>
    </form>
  );
}

Usage with React Final Form

Just use withMask normaly.

import React from 'react';
import { Form, Field } from 'react-final-form';
import { withMask } from 'use-mask-input';

function App() {
  ...
  return (
    <Form
      onSubmit={onSubmit}
      render={({ handleSubmit }) => (
        <form onSubmit={handleSubmit}>
          <Field
            name="phone"
            render={({ input, meta }) => (
              <input ref={withMask('9999-9999')} {...input} />
            )}
          />
          <button type="submit">Submit</button>
        </form>
      )}
    />
  );
}

Masking types

The mask params cabe be

Static Masking Type

These are the very basics of masking. The mask is defined and will not change during the input.

<input
  {...registerWithMask("phone", '99 9999-9999')}
  type="text"
/>

Optional Masking Type

It is possible to define some parts in the mask as optional. This is done by using [ ]. By example:

<input
  {...registerWithMask("phone", '99 [9]9999-9999')}
  type="text"
/>

This mask will allow input like (99) 99999-9999 or (99) 9999-9999.

Dynamic Masking Type

Dynamic masks can change during input. To define a dynamic part use { }.

{n} => n repeats {n|j} => n repeats, with j jitmasking {n,m} => from n to m repeats {n,m|j} => from n to m repeats, with j jitmasking

Also {+} and {} is allowed. + start from 1 and start from 0.

By example:

//static mask with dynamic syntax
<input
  {...registerWithMask("phone", "aa-9{4}")}
  type="text"
/>

// dynamic mask ~ the 9 def can be occur 1 to 4 times
<input
  {...registerWithMask("phone", "aa-9{4}")}
  type="text"
/>

// dynamic mask ~ email
<input
  {...registerWithMask("phone", "*{1,20}[.*{1,20}][.*{1,20}][.*{1,20}]@*{1,20}[.*{2,6}][.*{1,2}]")}
  type="text"
/>

Alias Masking Type

A Lot of common default "alises" presets, you can use like that:

<input                         // the alias
  {...registerWithMask("date", "datetime", {
    inputFormat: "yyyy-mm-dd",
  })}
  type="text"
/>

You can use together with options like inputFormat, prefix, sufix, etc. Checkout API docs

The avaliable ones is:

  • datetime
  • email
  • ip
  • datetime
  • cpf
  • email
  • numeric
  • currency
  • decimal
  • integer
  • percentage
  • url
  • ip
  • mac
  • ssn

Alternator Masking Type

The alternator syntax is like an OR statement. The mask can be one of the 3 choices specified in the alternator.

To define an alternator use the |. ex: "a|9" => a or 9 "(aaa)|(999)" => aaa or 999 "(aaa|999|9AA)" => aaa or 999 or 9AA "aaaa|9999" => aaa a or 9 999

<input
  {...registerWithMask("phone", "9999-9999|99999-9999")}
  type="text"
/>

// or just passing an array
<input
  {...registerWithMask("phone", ["9999-9999", "99999-9999"])}
  type="text"
/>

Preprocessing Masking Type

You can define the mask as a function that can allow you to preprocess the resulting mask. Example sorting for multiple masks or retrieving mask definitions dynamically through ajax. The preprocessing fn should return a valid mask definition.

<input
  {...registerWithMask("phone", function () {
    /* do stuff */ return ["[1-]AAA-999", "[1-]999-AAA"];
  })}
  type="text"
/>

API

(TODO)

use-mask-input's People

Contributors

dependabot[bot] avatar eduardoborges avatar rafma0 avatar rickcardoso avatar semantic-release-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

use-mask-input's Issues

TypeError: Inputmask is not a function

Estou utilizando o hook em uma aplicação que usa Next 13.

A implementação segue o exemplo mostrado no readme.

import { useForm } from 'react-hook-form';
import { useHookFormMask } from 'use-mask-input';

type FormType = {
  guest: any;
  cpf: string;
};

type FormProps = {
  submit: (data: FormType) => void;
};

const Form: FC<FormProps> = ({ submit, ...props }) => {
  const { register, handleSubmit } = useForm<FormType>({
    defaultValues: {
      guest: '',
      cpf: ''
    }
  });
  const registerWithMask = useHookFormMask(register);

  const onSubmit = (data: FormType) => {
    submit(data);
  };
  return (
    <div {...props}>
      <h3>titulo</h3>
      <form onSubmit={handleSubmit(data => onSubmit(data))}>
        <TextInput
          {...registerWithMask('cpf', 'cpf')}
          label='CPF'
        />
...

Rodando localmente, ao carregar a página, o erro recebido é:
image
image

API-Options -> availability for "decimal"-mask?

Hi,

thanks for your great work so far! I used to build my own input masks due to the lack of good third-party options, but it seems that this library could change this! However, when playing around with it, I stumbled across some issues, that I could not resolve myself:

I want to build a decimal-mask that has a decimal-limit of 2, a thousands-separator of " " and a thousands-separator-limit of 3.
Is this possible with the most recent version of the library or are these features that are yet to be implemented in the future?

Here is my code example:

import { useForm } from "react-hook-form";
import { useHookFormMask } from "use-mask-input";

const LoanCreateUpdateDeleteForm = (props) => {
  const { loan, isRevolver, budgetId } = props;

  const { register, handleSubmit, errors } = useForm();
  const registerWithMask = useHookFormMask(register);

  const onSubmit = (data) => {};

  const maskOptions = {
    prefix: "EUR ",
    // how to add the options below?
    decimalLimit: 2,
    thousandsSeparatorSymbol: " ",
    thousandsSeparatorLimit: 3,
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="test">Test</label>
      <input
        {...registerWithMask("test", "decimal", maskOptions)}
        type="text"
        autoComplete="off"
      />
    </form>
  );
};

export default LoanCreateUpdateDeleteForm;

Thanks for your help!

error - ReferenceError: self is not defined

Estou recebendo este erro no terminal

error - ReferenceError: self is not defined.

"dependencies": {
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "^7.41.5",
"use-mask-input": "^3.0.1",
"yup": "^0.32.11"
},

A esse WARN npm WARN deprecated [email protected]: This package is discontinued. Use lodash.flowright@^3.0.0.

Missing type=module in package.json

I ran into a problem with the library in my setup...

It appears to be caused by a missing type="module" in the package.json, because "main: "./dist/index.js" points to a file of type mjs. After adding the missing type, everything works as it should :)

What are your thoughts? Could you add this to package.json?

'Usage with React Hook Forms' correction

Hello! My name is Bernardo. I'm from Brazil.

First of all, I would like to thank you. Honestly, this library was exactly what I was looking for... and it really does work like a charm with react-hook-form.

There is only one extremely small issue, in the documentation, that I felt the need to point out. I may be mistaken, but my code only worked after I made the following correction:

  • The import of use-mask-input shown below is incorrect. Instead of { withHookFormMask}, it should be {useHookFormMask}. If this correction isn't made, the hook is not correctly imported ;)
import React from 'react';
import { useForm } from 'react-hook-form';
import { withHookFormMask } from 'use-mask-input';

function App() {
  const { register, handleSubmit } = useForm();
  const registerWithMask = useHookFormMask(register);

  ...

docs: datetime year autofill disable

Felt like a bug until I tracked it down to an option to disable. Consider adding this to the docs in the description so others know what options are available.

Version of this lib used at the time: "use-mask-input": "^3.3.6",

Options from this lib

prefillYear?: boolean | undefined;

Options from inputmask:

For this particular autofill fix I found it via RobinHerbots/Inputmask#2266 (comment), and via the prefillYea option at https://robinherbots.github.io/Inputmask/#/documentation/datetime#prefillyear.

Snippet:

      options: {
        inputFormat: 'mm/dd/yyyy',
        prefillYear: false,
      },

prevents the autofill for the year which may feel like unexpected behavior in some cases, e.g. data of birth which should not autofill to current year.

Type error when using the lib with @types/[email protected] and @types/[email protected]

I recently updated react and react-dom to their latest versions, and I ran into the following error when compiling my project:
Type '(input: HTMLInputElement | null) => HTMLInputElement | null | undefined' is not assignable to type '((instance: HTMLInputElement | null) => void | (() => VoidOrUndefinedOnly)) | RefObject<HTMLInputElement> | null | undefined'.

I went into the .d.ts file to investigate, and I was able to solve the problem by changing the withMask type from:

declare const withMask: (mask: Mask, options?: Options) => (input: Input) => Input;

to:

declare const withMask: (mask: Mask, options?: Options) => (input: Input) => void;

Heavy library

Your library fits perfectly into my stack, and is the best library that I have tested, but it's a heavy library. Maybe adding a .min.js version would solve this.

Screenshot 2024-04-20 at 5 22 35 PM

Component unmount

Hi!

I'm using withHookFormMask function and got some problem with component unmount. Is there any way to destroy inputmask on component unmount? I tried to call input.inputmask.remove() manually, but it is not solve the issue.

image

Still don't get auto completion for options after last update (?)

This is just weird, after updating my use-mask-input to 3.3.4, TS still can't figure options types for registerWithMask if I do

import { useHookFormMask } from 'use-mask-input'

image

but with my cloned updated repo, if I do npx rollup -c --watch and then

import { useHookFormMask } from '/local/path/to/use-mask-input/dist'

image

any ideas?

Unable to resolve dependency tree

Thanks for the library. Still getting the error below when I try npm install:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"18.2.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^17.x" from [email protected]
npm ERR! node_modules/use-mask-input
npm ERR!   use-mask-input@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\aksha\AppData\Local\npm-cache\eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\aksha\AppData\Local\npm-cache\_logs\2022-11-19T04_24_51_387Z-debug-0.log

Dynamic mask

Hi, congratulations on the amazing library first!

Is there a way to apply dynamic masking? I could not make it work with the examples provided on the doc. I am using react-hook-form as the form manager. The input is abstracted away using the withHookFormMask under the hood and I tried to experiment with the options from the third argument of this function with no success, though.

The same input could be either an email or a telephone number and I wanted to show the mask if the input is a telephone.

Thanks again!

Failed to resolve entry for package.

I get this error whenever I tries this package. Any hint on this one?

11:17:53 AM [vite] Internal server error: Failed to resolve entry for package "use-mask-input". The package may have incorrect main/module/exports specified in its package.json.

To reproduce:

npm create vite@latest my-react-app -- --template react-ts
npm install react-hook-form use-mask-input 

Create a test file, say Hello.tsx

import { useForm } from "react-hook-form";
import { withHookFormMask } from "use-mask-input";

export default function Hello() {
  const { register, control, watch } = useForm({
    defaultValues: {
      phone: "",
    },
  });
  const onSubmit = (data: any) => {
    console.log(data);
  };
  return (
    <form onSubmit={onSubmit}>
      <input
        type="text"
        {...withHookFormMask(register("phone"), [
          "(99) 9999 9999",
          "(99) 9 9999 9999",
        ])}
      />
      <button type="submit">Submit</button>
    </form>
  );
}

next.js - self is not defined

Hey nice work,

I try to use use-mask-inputwith react-hook-form and next.js, sadly I get this reference error, since Web-APIs are not available on the server side.

ReferenceError: self is not defined
    at eval (webpack-internal:///(sc_client)/./node_modules/use-mask-input/node_modules/inputmask/dist/inputmask.js:10:3)
    at (sc_client)/./node_modules/use-mask-input/node_modules/inputmask/dist/inputmask.js

Any plans to make it compatible with next.js?

Thank you

PS: If somebody wants to use it , but has the same error, just load your form with next/dynamic and ssr: false.

unable to resolve dependency tree

Hi there, this looks like an interesting project but it looks like its stuck on React v16

$ npm install use-mask-input --save
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: @mona-health-app/client@undefined
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"17.0.2" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.13.1" from [email protected]
npm ERR! node_modules/use-mask-input
npm ERR!   use-mask-input@"*" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 

Thanks for this package! 🙏 🎉

Hi Eduardo!

Just wanted to thank you for the lib - it seems to work very well (currently testing with 3.2.0 on Next.js), and I really think it's answering a need in the React ecosystem, where I searched for a while for a solution for input masking integrated with RHF.

It seems to work great both with uncontrolled inputs (using withHookFormMask) and controlled inputs (using RHF's Controller and ref={withMask(...))).

Thanks again!! 🙏

Accessing unmasked value from event

Does the library support accesing unmasked value from event target? I have put onChange event on form tag to get any form change and event.target.value shows value with mask applied. My workaround to that is the code below but maybe library already allows that without accesing inputmask.

if (target.inputmask) {
    value = target.inputmask.unmaskedvalue()
}

removeMaskOnSubmit doesn't seem to work on react-hook-form

I'm trying to remove masks on form submit. I don't know if there's a better way to do it, but reading the types I found removeMaskOnSubmit, but unfortunately doesn't work too.

<Input
  {...field}  // react-hook-form field props
  {...registerWithMask("phone", ["(999) 999-9999"], {
    removeMaskOnSubmit: true,
  })}
  type="text"
/>

What is the right way to do it?

Destructing isDirty from formState causing error with cursor-position in masked input

Hi,

i just bumped into the following bug: Destructing formState: {isDirty} from react hook form's useForm leads to an unexpected left-jump of the cursor position when entering the first value into a masked input, eg. typing 123456 will lead to a value of 234561.

Here is a codesandbox with the error replicated: https://codesandbox.io/p/sandbox/friendly-galois-tzw59m

Please let me know if you need any further information!

Update: I just realized that the same bug occus after a yup validation error was triggered: So if I type something in the masked input, which has a .required() yup-validation rule and then delete the input, when the error is triggered, the cursor-position jumps unexpectedly one to the left.

Remove 'mask trace'

Hello! How are you?

Is there a way to remove the mask trace from the input?

I want the text to adapt to the mask as the user types in.

image

Hide the mask

Is there any way to hide the mask and only show it when typing is in the right place?

Example with cleave.js (that's what I want):
cleave

With use-mask-input:
rut

I want to thank you for the lib. It's perfect.

Uncaught TypeError: inputmask$1 is not a function

I'm consuming this in a component library that is published as a package. When using it in an app directly, it works as implemented. However, when this is used within a published package, then the following error is thrown in the console for any app consuming that package:

Uncaught TypeError: inputmask$1 is not a function

This is being thrown from the effect:

const maskInput = Inputmask({
      mask,
      ...options
    })

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.