├── .all-contributorsrc
├── .gitignore
├── .npmrc
├── .prettierrc
├── LICENSE
├── README.md
├── docs
├── Currency.js
├── Currency.mdx
├── Date.js
├── Date.mdx
└── Home.mdx
├── doczrc.js
├── now.json
├── package.json
└── src
├── index.js
└── useInputMask.js
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "use-input-mask",
3 | "projectOwner": "elsangedy",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": [
7 | "README.md"
8 | ],
9 | "imageSize": 100,
10 | "commit": true,
11 | "commitConvention": "none",
12 | "contributors": [
13 | {
14 | "login": "elsangedy",
15 | "name": "Munir Ahmed Elsangedy",
16 | "avatar_url": "https://avatars3.githubusercontent.com/u/5339664?v=4",
17 | "profile": "https://munir.dev",
18 | "contributions": [
19 | "code",
20 | "doc"
21 | ]
22 | },
23 | {
24 | "login": "renatorib",
25 | "name": "Renato Ribeiro",
26 | "avatar_url": "https://avatars2.githubusercontent.com/u/3277185?v=4",
27 | "profile": "http://twitter.com/renatorib_",
28 | "contributions": [
29 | "doc"
30 | ]
31 | }
32 | ],
33 | "contributorsPerLine": 7
34 | }
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (https://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # TypeScript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 | # next.js build output
61 | .next
62 | .docz
63 | dist
64 | build
65 |
66 | .DS_Store
67 | package-lock.json
68 | yarn.lock
69 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | registry=http://registry.npmjs.org/
2 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "semi": false,
6 | "singleQuote": true,
7 | "trailingComma": "all",
8 | "bracketSpacing": true,
9 | "jsxBracketSameLine": false,
10 | "proseWrap": "always"
11 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2019 Kent C. Dodds
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # use-input-mask
2 | ![MIT License][license-badge]
3 | [![downloads][downloads-badge]][npmcharts]
4 | [![PRs Welcome][prs-badge]][prs]
5 | [](#contributors)
6 |
7 | ## Installation
8 |
9 | ```bash
10 | $ yarn add use-input-mask
11 | # or
12 | $ npm i use-input-mask
13 | ```
14 |
15 | ## Usage
16 |
17 | ```jsx
18 | import React from 'react'
19 |
20 | import useInputMask from 'use-input-mask'
21 |
22 | import { createAutoCorrectedDatePipe } from "text-mask-addons";
23 |
24 | const MyDateInput = props => {
25 | const input = useRef(null);
26 |
27 | const autoCorrectedDatePipe = createAutoCorrectedDatePipe("dd/mm/yyyy HH:MM");
28 |
29 | const onChange = useInputMask({
30 | input,
31 | onChange: props.onChange,
32 | mask: [/\d/, /\d/, "/", /\d/, /\d/, "/", /\d/, /\d/, /\d/, /\d/],
33 | pipe: autoCorrectedDatePipe,
34 | keepCharPositions: true
35 | });
36 |
37 | return ;
38 | };
39 |
40 | export default MyDateInput
41 | ```
42 |
43 | ## Roadmap
44 | * [ ] tests
45 | * [ ] ci/cd
46 | * [ ] semantic-release
47 | * [ ] docs
48 | * [x] all-contributors
49 |
50 | ## Inspiration
51 |
52 | [text-mask](https://github.com/text-mask/text-mask)
53 |
54 | ## Contributors
55 |
56 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
57 |
58 |
59 |
60 |
61 |
67 |
68 |
69 |
70 |
71 |
72 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
73 |
74 | ## LIENSE
75 |
76 | MIT
77 |
78 | [license-badge]: https://img.shields.io/npm/l/use-input-mask.svg?style=flat-square
79 | [downloads-badge]: https://img.shields.io/npm/dm/use-input-mask.svg?style=flat-square
80 | [prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
81 | [prs]: http://makeapullrequest.com
82 | [npmcharts]: http://npmcharts.com/compare/use-input-mask
83 |
--------------------------------------------------------------------------------
/docs/Currency.js:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react'
2 |
3 | import useInputMask from '../src'
4 |
5 | import { createNumberMask } from 'text-mask-addons'
6 |
7 | const CurrencyInput = props => {
8 | const input = useRef(null)
9 |
10 | const maskMoney = createNumberMask({
11 | prefix: 'R$ ',
12 | includeThousandsSeparator: true,
13 | thousandsSeparatorSymbol: '.',
14 | allowDecimal: true,
15 | integerLimit: 9,
16 | decimalSymbol: ',',
17 | requireDecimal: true,
18 | })
19 |
20 | const onChange = useInputMask({
21 | input,
22 | onChange: props.onChange,
23 | mask: value => {
24 | const mask = maskMoney(value)
25 |
26 | const decimalsRegex = /,([0-9]{1,2})/
27 | const result = decimalsRegex.exec(value)
28 |
29 | if (!!result && result[1].length < 2) {
30 | mask.push('0')
31 | } else if (!result) {
32 | mask.push('00')
33 | }
34 |
35 | return mask
36 | },
37 | })
38 |
39 | return
40 | }
41 |
42 | export default CurrencyInput
43 |
--------------------------------------------------------------------------------
/docs/Currency.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | name: Currency
3 | menu: Examples
4 | ---
5 |
6 | import { Playground } from 'docz'
7 |
8 | import CurrencyInput from './Currency'
9 |
10 | # Currency
11 |
12 |
13 | console.log(e.target.value)}
15 | placeholder="Currency input"
16 | />
17 |
18 |
19 | ## Code
20 |
21 | ```js
22 | import React, { useRef } from 'react'
23 |
24 | import useInputMask from 'use-input-mask'
25 |
26 | import { createNumberMask } from 'text-mask-addons'
27 |
28 | const CurrencyInput = props => {
29 | const input = useRef(null)
30 |
31 | const maskMoney = createNumberMask({
32 | prefix: 'R$ ',
33 | includeThousandsSeparator: true,
34 | thousandsSeparatorSymbol: '.',
35 | allowDecimal: true,
36 | integerLimit: 9,
37 | decimalSymbol: ',',
38 | requireDecimal: true,
39 | })
40 |
41 | const onChange = useInputMask({
42 | input,
43 | onChange: props.onChange,
44 | mask: value => {
45 | const mask = maskMoney(value)
46 |
47 | const decimalsRegex = /,([0-9]{1,2})/
48 | const result = decimalsRegex.exec(value)
49 |
50 | if (!!result && result[1].length < 2) {
51 | mask.push('0')
52 | } else if (!result) {
53 | mask.push('00')
54 | }
55 |
56 | return mask
57 | },
58 | })
59 |
60 | return
61 | }
62 |
63 | export default CurrencyInput
64 | ```
65 |
--------------------------------------------------------------------------------
/docs/Date.js:
--------------------------------------------------------------------------------
1 | import React, { useRef } from 'react'
2 |
3 | import useInputMask from '../src'
4 |
5 | import { createAutoCorrectedDatePipe } from 'text-mask-addons'
6 |
7 | const DateInput = props => {
8 | const input = useRef(null)
9 |
10 | const autoCorrectedDatePipe = createAutoCorrectedDatePipe('dd/mm/yyyy HH:MM')
11 |
12 | const onChange = useInputMask({
13 | input,
14 | onChange: props.onChange,
15 | mask: [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/],
16 | pipe: autoCorrectedDatePipe,
17 | placeholder: 'Please enter a date',
18 | keepCharPositions: true,
19 | })
20 |
21 | return
22 | }
23 |
24 | export default DateInput
25 |
--------------------------------------------------------------------------------
/docs/Date.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | name: Date
3 | menu: Examples
4 | ---
5 |
6 | import { Playground } from 'docz'
7 |
8 | import DateInput from './Date'
9 |
10 | # Date
11 |
12 |
13 | console.log(e.target.value)}
15 | placeholder="Date input"
16 | />
17 |
18 |
19 | ## Code
20 |
21 | ```js
22 | import React, { useRef } from 'react'
23 |
24 | import useInputMask from 'use-input-mask'
25 |
26 | import { createAutoCorrectedDatePipe } from 'text-mask-addons'
27 |
28 | const DateInput = props => {
29 | const input = useRef(null)
30 |
31 | const autoCorrectedDatePipe = createAutoCorrectedDatePipe('dd/mm/yyyy HH:MM')
32 |
33 | const onChange = useInputMask({
34 | input,
35 | onChange: props.onChange,
36 | mask: [/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/],
37 | pipe: autoCorrectedDatePipe,
38 | placeholder: 'Please enter a date',
39 | keepCharPositions: true,
40 | })
41 |
42 | return
43 | }
44 |
45 | export default DateInput
46 | ```
47 |
--------------------------------------------------------------------------------
/docs/Home.mdx:
--------------------------------------------------------------------------------
1 | ---
2 | name: Home
3 | route: /
4 | ---
5 |
6 | # Getting Started
7 |
8 | https://github.com/elsangedy/use-input-mask
9 |
10 | https://github.com/text-mask/text-mask
11 |
12 | ## Install
13 |
14 | ```bash
15 | yarn add use-input-mask
16 | ```
17 |
18 | ## Hook
19 |
20 | ```js
21 | import useInputMask from 'use-input-mask'
22 |
23 | const onChange = useInputMask({
24 | input,
25 | onChange,
26 | guide,
27 | keepCharPositions,
28 | mask,
29 | pipe,
30 | placeholderChar,
31 | showMask,
32 | initialValue,
33 | })
34 | ```
35 |
--------------------------------------------------------------------------------
/doczrc.js:
--------------------------------------------------------------------------------
1 | export default {
2 | dest: '/dist',
3 | codeSandbox: false,
4 | repository: 'https://github.com/elsangedy/use-input-mask',
5 | menu: [
6 | 'Home',
7 | {
8 | name: 'Examples',
9 | menu: ['Date', 'Currency'],
10 | },
11 | ],
12 | }
13 |
--------------------------------------------------------------------------------
/now.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "name": "use-input-mask",
4 | "alias": "use-input-mask.now.sh",
5 | "public": true,
6 | "builds": [
7 | { "src": "package.json", "use": "@now/static-build" }
8 | ]
9 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "use-input-mask",
3 | "version": "1.0.0",
4 | "license": "MIT",
5 | "author": {
6 | "name": "Munir Ahmed Elsangedy",
7 | "email": "elsangedy@gmail.com",
8 | "url": "https://munir.dev"
9 | },
10 | "homepage": "https://use-input-mask.now.sh",
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/elsangedy/use-input-mask.git"
14 | },
15 | "bugs": {
16 | "url": "https://github.com/elsangedy/use-input-mask/issues"
17 | },
18 | "main": "dist/use-input-mask.cjs.js",
19 | "module": "dist/use-input-mask.esm.js",
20 | "files": [
21 | "dist"
22 | ],
23 | "scripts": {
24 | "now-build": "yarn build:docs",
25 | "dev": "docz dev",
26 | "build:docs": "docz build",
27 | "build": "kcd-scripts build --bundle",
28 | "add-contributor": "all-contributors add"
29 | },
30 | "dependencies": {
31 | "@babel/runtime": "^7.5.5",
32 | "text-mask-core": "^5.1.2"
33 | },
34 | "peerDependencies": {
35 | "react": ">=16.8"
36 | },
37 | "devDependencies": {
38 | "all-contributors-cli": "^6.8.1",
39 | "docz": "^1.2.0",
40 | "docz-theme-default": "^1.2.0",
41 | "kcd-scripts": "^1.4.0",
42 | "react": "^16.8.6",
43 | "react-dom": "^16.8.6",
44 | "text-mask-addons": "^3.8.0"
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | export { default } from './useInputMask'
2 |
--------------------------------------------------------------------------------
/src/useInputMask.js:
--------------------------------------------------------------------------------
1 | import { useLayoutEffect, useRef } from 'react'
2 |
3 | const { createTextMaskInputElement } = require('text-mask-core')
4 |
5 | function useInputMask({
6 | guide,
7 | input: inputRef,
8 | keepCharPositions,
9 | mask,
10 | onChange,
11 | pipe,
12 | placeholderChar,
13 | showMask,
14 | initialValue = '',
15 | }) {
16 | const textMaskRef = useRef(null)
17 |
18 | useLayoutEffect(() => {
19 | if (!inputRef.current) {
20 | return
21 | }
22 |
23 | textMaskRef.current = createTextMaskInputElement({
24 | guide,
25 | inputElement: inputRef.current,
26 | keepCharPositions,
27 | mask,
28 | pipe,
29 | placeholderChar,
30 | showMask,
31 | })
32 |
33 | textMaskRef.current.update(initialValue)
34 | }, [
35 | inputRef,
36 | guide,
37 | keepCharPositions,
38 | mask,
39 | pipe,
40 | placeholderChar,
41 | showMask,
42 | initialValue,
43 | ])
44 |
45 | return event => {
46 | if (textMaskRef.current) {
47 | textMaskRef.current.update()
48 | }
49 |
50 | if (typeof onChange === 'function') {
51 | onChange(event)
52 | }
53 | }
54 | }
55 |
56 | export default useInputMask
57 |
--------------------------------------------------------------------------------