├── .gitignore
├── LICENSE.md
├── README.md
├── package.json
├── rollup.config.js
├── use-masked-input.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | *.tmp
4 | .DS_Store
5 | use-masked-input.cjs.js
6 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | LICENSE BSD-3-Clause
2 |
3 | Copyright 2019 UXtemple Ltd
4 |
5 | Redistribution and use in source and binary forms, with or without modification,
6 | are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this
9 | list of conditions and the following disclaimer.
10 |
11 | 2. Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 |
15 | 3. Neither the name of the copyright holder nor the names of its contributors
16 | may be used to endorse or promote products derived from this software without
17 | specific prior written permission.
18 |
19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # useMaskedInput
2 |
3 | A React hook to mask an input using [text-mask](https://github.com/text-mask/text-mask).
4 |
5 | This component needs React 16.8 or greater because it uses hooks.
6 |
7 | ## Installation
8 |
9 | With NPM:
10 | ```
11 | npm install @viewstools/use-masked-input
12 | ```
13 |
14 | With Yarn:
15 | ```
16 | yarn add @viewstools/use-masked-input
17 | ```
18 |
19 | ## Usage
20 |
21 | ```js
22 | import React, { useRef } from 'react'
23 | import useMaskedInput from '@viewstools/use-masked-input'
24 |
25 | let PhoneInput = props => {
26 | let input = useRef(null)
27 |
28 | let onChange = useMaskedInput({
29 | input,
30 | mask: ['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/],
31 | onChange: props.onChange,
32 | })
33 |
34 | return
35 | }
36 |
37 | export default PhoneInput
38 | ```
39 |
40 | `useMaskedInput` takes an object as its parameter and returns an `onChange`
41 | function you need to pass onto your input as a prop. The hook will manage the value of the input.
42 |
43 | Here are the possible configuration values:
44 | - `input`. *Required*. A reference created by `React.createRef` or `useRef` to the `input` element rendered by React.
45 | - `mask`. *Required*. An array or a function that defines how the user input is going to be masked. [See more](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#mask).
46 | - `onChange`. A function to be called when the input changes.
47 | - `guide`. A boolean that tells the component whether to be in guide or no guide mode. [See more](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#guide).
48 | - `keepCharPositions`. A boolean that when true, adding or deleting characters affects won't affect the position of other characters, if false, it pushes them. _Defaults to `false`_. [See more](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#keepcharpositions).
49 | - `pipe`. A function to modify the conformed value before it is displayed on the screen. [See more](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#pipe).
50 | - `placeholderChar`. A string representing the fillable spot in the mask. Defaults to an underscore (`_`). [See more](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#placeholderchar).
51 | - `showMask`. A boolean that tells the component to display the mask as a placeholder in place of the regular placeholder when the input element value is empty. _Defaults to `false`_. [See more](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#showmask).
52 | - `value`. A string with the value. Defaults to ``.
53 | ```
54 |
55 | ## Known issues
56 | [There are some known issues on text-mask](https://github.com/text-mask/text-mask/blob/master/componentDocumentation.md#known-issues).
57 |
58 | ### Supported types
59 | Please note that Text Mask supports input type of text, tel, url, password, and search. Due to a limitation in browser API, other input types, such as email or number, cannot be supported. However, it is normal to let the user enter an email or a number in an input type text combined the appropriate input mask.
60 |
61 | License BSD-Clause-3
62 |
63 | by UXtemple
64 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@viewstools/use-masked-input",
3 | "description": "A React hook to mask an input using text-mask.",
4 | "version": "2.0.1",
5 | "main": "use-masked-input.cjs.js",
6 | "private": false,
7 | "license": "BSD-3-Clause",
8 | "author": "Darío Javier Cravero ",
9 | "bugs": {
10 | "url": "https://github.com/viewstools/use-masked-input/issues"
11 | },
12 | "homepage": "https://github.com/viewstools/use-masked-input#readme",
13 | "scripts": {
14 | "prepare": "rollup --config rollup.config.js"
15 | },
16 | "devDependencies": {
17 | "rollup": "^1.2.3"
18 | },
19 | "peerDependencies": {
20 | "react": "^16.8.3"
21 | },
22 | "dependencies": {
23 | "text-mask-core": "^5.1.2"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | input: 'use-masked-input.js',
3 | output: {
4 | file: 'use-masked-input.cjs.js',
5 | format: 'cjs',
6 | },
7 | }
8 |
--------------------------------------------------------------------------------
/use-masked-input.js:
--------------------------------------------------------------------------------
1 | import { createTextMaskInputElement } from 'text-mask-core'
2 | import { useLayoutEffect, useRef } from 'react'
3 |
4 | export default function useMaskedInput({
5 | guide,
6 | input,
7 | keepCharPositions,
8 | mask,
9 | onChange,
10 | pipe,
11 | placeholderChar,
12 | showMask,
13 | value = '',
14 | }) {
15 | let textMask = useRef()
16 |
17 | function init() {
18 | if (!input.current) return
19 |
20 | textMask.current = createTextMaskInputElement({
21 | guide,
22 | inputElement: input.current,
23 | keepCharPositions,
24 | mask,
25 | pipe,
26 | placeholderChar,
27 | showMask,
28 | })
29 |
30 | textMask.current.update(value)
31 | }
32 |
33 | useLayoutEffect(init, [
34 | guide,
35 | keepCharPositions,
36 | mask,
37 | pipe,
38 | placeholderChar,
39 | showMask,
40 | ])
41 |
42 | useLayoutEffect(() => {
43 | if (value === input.current.value) return
44 |
45 | init()
46 | }, [value])
47 |
48 | return event => {
49 | if (textMask.current) {
50 | textMask.current.update()
51 | }
52 |
53 | if (typeof onChange === 'function') {
54 | onChange(event)
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@types/estree@0.0.39":
6 | version "0.0.39"
7 | resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
8 | integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
9 |
10 | "@types/node@*":
11 | version "11.9.5"
12 | resolved "https://registry.yarnpkg.com/@types/node/-/node-11.9.5.tgz#011eece9d3f839a806b63973e228f85967b79ed3"
13 | integrity sha512-vVjM0SVzgaOUpflq4GYBvCpozes8OgIIS5gVXVka+OfK3hvnkC1i93U8WiY2OtNE4XUWyyy/86Kf6e0IHTQw1Q==
14 |
15 | acorn@^6.1.0:
16 | version "6.1.0"
17 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.0.tgz#b0a3be31752c97a0f7013c5f4903b71a05db6818"
18 | integrity sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==
19 |
20 | rollup@^1.2.3:
21 | version "1.2.3"
22 | resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.2.3.tgz#450bbbd9d3c2c9a17d23c9165cab7a659f91095a"
23 | integrity sha512-hTWFogj/Z077imG9XRM1i43ffarWNToDgsqkU62eJRX4rJE213/c8+gUIf4xacfzytl0sjJZfCzzPQfZN7oIQg==
24 | dependencies:
25 | "@types/estree" "0.0.39"
26 | "@types/node" "*"
27 | acorn "^6.1.0"
28 |
29 | text-mask-core@^5.1.2:
30 | version "5.1.2"
31 | resolved "https://registry.yarnpkg.com/text-mask-core/-/text-mask-core-5.1.2.tgz#80dd5ebe04825757e46619e691407a9f8b3c1b6f"
32 | integrity sha1-gN1evgSCV1fkZhnmkUB6n4s8G28=
33 |
--------------------------------------------------------------------------------