FE-847: Input formatters (#28)

This commit is contained in:
Rinat Arsaev 2019-06-03 17:12:27 +03:00 committed by GitHub
parent f25fc8a6d6
commit 013427a69b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 649 additions and 61 deletions

133
package-lock.json generated
View File

@ -137,7 +137,7 @@
"dependencies": {
"source-map": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
"resolved": "http://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=",
"dev": true
}
@ -456,7 +456,7 @@
},
"load-json-file": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
"dev": true,
"requires": {
@ -518,7 +518,7 @@
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
@ -1543,7 +1543,7 @@
},
"@types/q": {
"version": "0.0.32",
"resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz",
"resolved": "http://registry.npmjs.org/@types/q/-/q-0.0.32.tgz",
"integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=",
"dev": true
},
@ -1857,6 +1857,14 @@
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
},
"angular2-text-mask": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/angular2-text-mask/-/angular2-text-mask-9.0.0.tgz",
"integrity": "sha512-iALcnhJPS1zvX48d86rgUgDe/crX6XfhZrXC4Gdlo2/YwZW7u7KJZY6/b3ieSCIWVq/E6p+wDCzeo3E6leRjDA==",
"requires": {
"text-mask-core": "^5.0.0"
}
},
"ansi-colors": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
@ -2058,7 +2066,7 @@
},
"util": {
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
"resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz",
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
"dev": true,
"requires": {
@ -2133,7 +2141,7 @@
},
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
},
@ -2213,7 +2221,7 @@
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@ -2610,7 +2618,7 @@
},
"browserify-aes": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"dev": true,
"requires": {
@ -2657,7 +2665,7 @@
},
"browserify-rsa": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true,
"requires": {
@ -2719,7 +2727,7 @@
},
"buffer": {
"version": "4.9.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"dev": true,
"requires": {
@ -2806,7 +2814,7 @@
},
"cacache": {
"version": "10.0.4",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
"resolved": "http://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
"integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
"dev": true,
"requires": {
@ -2857,7 +2865,7 @@
},
"camelcase-keys": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
"dev": true,
"optional": true,
@ -3101,7 +3109,7 @@
},
"colors": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
"resolved": "http://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
"integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
"dev": true
},
@ -3391,7 +3399,7 @@
},
"create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true,
"requires": {
@ -3404,7 +3412,7 @@
},
"create-hmac": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true,
"requires": {
@ -3752,7 +3760,7 @@
"dependencies": {
"globby": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"dev": true,
"requires": {
@ -3765,7 +3773,7 @@
"dependencies": {
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
}
@ -3851,7 +3859,7 @@
},
"diffie-hellman": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"dev": true,
"requires": {
@ -4026,7 +4034,7 @@
},
"engine.io-client": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz",
"resolved": "http://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz",
"integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==",
"dev": true,
"requires": {
@ -4122,7 +4130,7 @@
},
"es6-promisify": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
"dev": true,
"requires": {
@ -4560,7 +4568,7 @@
},
"finalhandler": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"dev": true,
"requires": {
@ -4744,7 +4752,7 @@
},
"fs-access": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz",
"resolved": "http://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz",
"integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=",
"dev": true,
"requires": {
@ -5403,7 +5411,7 @@
},
"get-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
"dev": true
},
@ -5711,7 +5719,7 @@
},
"http-errors": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
"dev": true,
"requires": {
@ -5761,7 +5769,7 @@
},
"http-proxy-middleware": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz",
"resolved": "http://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz",
"integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==",
"dev": true,
"requires": {
@ -6488,7 +6496,7 @@
},
"fast-deep-equal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"resolved": "http://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
"integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
"dev": true
},
@ -6740,7 +6748,7 @@
},
"jsesc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
"dev": true
},
@ -7051,7 +7059,7 @@
},
"load-json-file": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"dev": true,
"optional": true,
@ -7065,7 +7073,7 @@
"dependencies": {
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true,
"optional": true
@ -7378,7 +7386,7 @@
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
"dev": true
},
@ -7405,7 +7413,7 @@
},
"meow": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
"dev": true,
"optional": true,
@ -7631,7 +7639,7 @@
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
@ -8402,7 +8410,7 @@
"dependencies": {
"semver": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
"integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
"dev": true,
"optional": true
@ -8494,7 +8502,7 @@
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"optional": true,
@ -8841,13 +8849,13 @@
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
"dev": true
},
"os-locale": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
"dev": true,
"optional": true,
@ -8857,7 +8865,7 @@
},
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
"dev": true
},
@ -9155,7 +9163,7 @@
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
@ -9440,7 +9448,7 @@
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
@ -9468,7 +9476,7 @@
},
"globby": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
"resolved": "http://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
"integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
"dev": true,
"requires": {
@ -9482,7 +9490,7 @@
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
@ -9748,7 +9756,7 @@
"dependencies": {
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
}
@ -9780,7 +9788,7 @@
},
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true,
"optional": true
@ -9823,7 +9831,7 @@
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "~1.0.0",
@ -9912,13 +9920,13 @@
},
"regjsgen": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
"resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
"integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
"dev": true
},
"regjsparser": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
"resolved": "http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
"integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
"dev": true,
"requires": {
@ -9927,7 +9935,7 @@
"dependencies": {
"jsesc": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
"resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
"integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
"dev": true
}
@ -10129,7 +10137,7 @@
},
"safe-regex": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"dev": true,
"requires": {
@ -10184,7 +10192,7 @@
},
"sax": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz",
"resolved": "http://registry.npmjs.org/sax/-/sax-0.5.8.tgz",
"integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=",
"dev": true
},
@ -10212,7 +10220,7 @@
"dependencies": {
"source-map": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true,
"optional": true,
@ -10395,7 +10403,7 @@
},
"sha.js": {
"version": "2.4.11",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dev": true,
"requires": {
@ -10656,7 +10664,7 @@
},
"socket.io-parser": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz",
"resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz",
"integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==",
"dev": true,
"requires": {
@ -11178,7 +11186,7 @@
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
@ -11197,7 +11205,7 @@
},
"strip-eof": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
"dev": true
},
@ -11251,7 +11259,7 @@
},
"source-map": {
"version": "0.1.43",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
"resolved": "http://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
"integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
"dev": true,
"requires": {
@ -11307,7 +11315,7 @@
},
"tar": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
"resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
"integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
"dev": true,
"optional": true,
@ -11538,9 +11546,14 @@
}
}
},
"text-mask-core": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/text-mask-core/-/text-mask-core-5.1.2.tgz",
"integrity": "sha1-gN1evgSCV1fkZhnmkUB6n4s8G28="
},
"through": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
"resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
"through2": {
@ -12191,7 +12204,7 @@
},
"source-map": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"resolved": "http://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true,
"requires": {
@ -12632,7 +12645,7 @@
},
"wrap-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"dev": true,
"requires": {
@ -12677,7 +12690,7 @@
},
"xmlbuilder": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
"dev": true
},

View File

@ -28,6 +28,7 @@
"@angular/platform-browser": "~7.2.14",
"@angular/platform-browser-dynamic": "~7.2.14",
"@angular/router": "~7.2.14",
"angular2-text-mask": "^9.0.0",
"core-js": "^2.5.4",
"d3-axis": "^1.0.12",
"d3-scale": "^2.1.2",

View File

@ -5,6 +5,7 @@
<button routerLink="/analytics">Графики</button>
<button routerLink="/table">Таблица</button>
<button routerLink="/buttons">Кнопки</button>
<button routerLink="/inputs">Поля ввода</button>
</div>
<div class="content">
<ng-content></ng-content>

View File

@ -0,0 +1,6 @@
import { TextMaskConfig } from 'angular2-text-mask';
export const binMask: TextMaskConfig = {
mask: [/\d/, /\d/, /\d/, /\d/, ' ', /\d/, /\d/, /\d/, /\d/],
guide: false
};

View File

@ -0,0 +1,8 @@
<input
class="dsh-bin-input-element"
[formControl]="formControl"
size="9"
placeholder="0000&nbsp;0000"
[textMask]="mask"
/>
<span class="dsh-bin-input-spacer">&nbsp;****&nbsp;****</span>

View File

@ -0,0 +1,29 @@
:host {
display: flex;
}
.dsh-bin-input-element {
border: none;
background: none;
padding: 0;
outline: none;
font: inherit;
}
.dsh-bin-input-element::placeholder {
opacity: 0;
}
:host.floating .dsh-bin-input-element::placeholder {
opacity: 1;
}
.dsh-bin-input-spacer {
opacity: 0;
user-select: none;
transition: opacity 200ms;
}
:host.floating .dsh-bin-input-spacer {
opacity: 1;
}

View File

@ -0,0 +1,110 @@
import { FocusMonitor } from '@angular/cdk/a11y';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Component, ElementRef, Input, OnDestroy, HostBinding } from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatFormFieldControl } from '@angular/material';
import { Subject } from 'rxjs';
import { binMask } from './bin-input-mask';
@Component({
selector: 'dsh-bin-input',
templateUrl: 'bin-input.component.html',
styleUrls: ['bin-input.component.scss'],
providers: [{ provide: MatFormFieldControl, useExisting: BINInputComponent }]
})
export class BINInputComponent implements MatFormFieldControl<number>, OnDestroy {
static nextId = 0;
@HostBinding('class.floating')
get shouldLabelFloat() {
return this.focused || !this.empty;
}
@HostBinding('id')
id = `dsh-bin-input-${BINInputComponent.nextId++}`;
@HostBinding('attr.aria-describedby')
describedBy = '';
formControl: FormControl;
stateChanges = new Subject<void>();
focused = false;
ngControl = null;
errorState = false;
controlType = 'dsh-bin-input';
get empty() {
return !this.formControl.value;
}
@Input()
get placeholder(): string {
return this._placeholder;
}
set placeholder(value: string) {
this._placeholder = value;
this.stateChanges.next();
}
private _placeholder: string;
@Input()
get required(): boolean {
return this._required;
}
set required(value: boolean) {
this._required = coerceBooleanProperty(value);
this.stateChanges.next();
}
private _required = false;
@Input()
get disabled(): boolean {
return this._disabled;
}
set disabled(value: boolean) {
this._disabled = coerceBooleanProperty(value);
this._disabled ? this.formControl.disable() : this.formControl.enable();
this.stateChanges.next();
}
private _disabled = false;
@Input()
get value(): number {
return this.formControl.value.replace(/\D/g, '');
}
set value(v: number) {
this.formControl.setValue(v);
this.stateChanges.next();
}
get mask() {
return binMask;
}
constructor(private fm: FocusMonitor, private elRef: ElementRef<HTMLElement>) {
this.formControl = new FormControl();
fm.monitor(elRef, true).subscribe(origin => {
this.focused = !!origin;
this.stateChanges.next();
});
}
ngOnDestroy() {
this.stateChanges.complete();
this.fm.stopMonitoring(this.elRef);
}
setDescribedByIds(ids: string[]) {
this.describedBy = ids.join(' ');
}
onContainerClick(event: MouseEvent) {
if ((event.target as Element).tagName.toLowerCase() !== 'input') {
const input = this.elRef.nativeElement.querySelector('input');
if (input) {
input.focus();
}
}
}
}

View File

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { A11yModule } from '@angular/cdk/a11y';
import { TextMaskModule } from 'angular2-text-mask';
import { BINInputComponent } from './bin-input.component';
@NgModule({
imports: [FormsModule, ReactiveFormsModule, A11yModule, TextMaskModule],
entryComponents: [BINInputComponent],
declarations: [BINInputComponent],
exports: [BINInputComponent]
})
export class BinInputModule {}

View File

@ -0,0 +1,6 @@
import { TextMaskConfig } from 'angular2-text-mask';
export const cardMask: TextMaskConfig = {
mask: [/\d/, /\d/, /\d/, /\d/],
guide: false
};

View File

@ -0,0 +1,2 @@
<span class="dsh-card-input-spacer">****&nbsp;****&nbsp;****&nbsp;</span>
<input class="dsh-card-input-element" [formControl]="formControl" size="4" placeholder="0000" [textMask]="mask" />

View File

@ -0,0 +1,30 @@
:host {
display: flex;
}
.dsh-card-input-element {
border: none;
background: none;
padding: 0;
outline: none;
font: inherit;
text-align: right;
}
.dsh-card-input-element::placeholder {
opacity: 0;
}
:host.floating .dsh-card-input-element::placeholder {
opacity: 1;
}
.dsh-card-input-spacer {
opacity: 0;
user-select: none;
transition: opacity 200ms;
}
:host.floating .dsh-card-input-spacer {
opacity: 1;
}

View File

@ -0,0 +1,110 @@
import { FocusMonitor } from '@angular/cdk/a11y';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Component, ElementRef, Input, OnDestroy, HostBinding } from '@angular/core';
import { FormControl } from '@angular/forms';
import { MatFormFieldControl } from '@angular/material';
import { Subject } from 'rxjs';
import { cardMask } from './card-input-mask';
@Component({
selector: 'dsh-card-input',
templateUrl: 'card-input.component.html',
styleUrls: ['card-input.component.scss'],
providers: [{ provide: MatFormFieldControl, useExisting: CardInputComponent }]
})
export class CardInputComponent implements MatFormFieldControl<number>, OnDestroy {
static nextId = 0;
@HostBinding('class.floating')
get shouldLabelFloat() {
return this.focused || !this.empty;
}
@HostBinding('id')
id = `dsh-card-input-${CardInputComponent.nextId++}`;
@HostBinding('attr.aria-describedby')
describedBy = '';
formControl: FormControl;
stateChanges = new Subject<void>();
focused = false;
ngControl = null;
errorState = false;
controlType = 'dsh-card-input';
get empty() {
return !this.formControl.value;
}
@Input()
get placeholder(): string {
return this._placeholder;
}
set placeholder(value: string) {
this._placeholder = value;
this.stateChanges.next();
}
private _placeholder: string;
@Input()
get required(): boolean {
return this._required;
}
set required(value: boolean) {
this._required = coerceBooleanProperty(value);
this.stateChanges.next();
}
private _required = false;
@Input()
get disabled(): boolean {
return this._disabled;
}
set disabled(value: boolean) {
this._disabled = coerceBooleanProperty(value);
this._disabled ? this.formControl.disable() : this.formControl.enable();
this.stateChanges.next();
}
private _disabled = false;
@Input()
get value(): number {
return this.formControl.value.replace(/\D/g, '');
}
set value(v: number) {
this.formControl.setValue(v);
this.stateChanges.next();
}
get mask() {
return cardMask;
}
constructor(private fm: FocusMonitor, private elRef: ElementRef<HTMLElement>) {
this.formControl = new FormControl();
fm.monitor(elRef, true).subscribe(origin => {
this.focused = !!origin;
this.stateChanges.next();
});
}
ngOnDestroy() {
this.stateChanges.complete();
this.fm.stopMonitoring(this.elRef);
}
setDescribedByIds(ids: string[]) {
this.describedBy = ids.join(' ');
}
onContainerClick(event: MouseEvent) {
if ((event.target as Element).tagName.toLowerCase() !== 'input') {
const input = this.elRef.nativeElement.querySelector('input');
if (input) {
input.focus();
}
}
}
}

View File

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { A11yModule } from '@angular/cdk/a11y';
import { TextMaskModule } from 'angular2-text-mask';
import { CardInputComponent } from './card-input.component';
@NgModule({
imports: [FormsModule, ReactiveFormsModule, A11yModule, TextMaskModule],
entryComponents: [CardInputComponent],
declarations: [CardInputComponent],
exports: [CardInputComponent]
})
export class CardInputModule {}

View File

@ -0,0 +1,11 @@
import { NgModule } from '@angular/core';
import { TextMaskModule } from 'angular2-text-mask';
import { BinInputModule } from './bin-input/bin-input.module';
import { CardInputModule } from './card-input/card-input.module';
@NgModule({
imports: [BinInputModule, CardInputModule, TextMaskModule],
exports: [BinInputModule, CardInputModule, TextMaskModule]
})
export class FormControlsModule {}

View File

@ -0,0 +1,2 @@
export * from './form-controls.module';
export * from './masks';

View File

@ -0,0 +1,150 @@
import { TextMaskConfig } from 'angular2-text-mask';
const dollarSign = '$';
const emptyString = '';
const comma = ',';
const period = '.';
const minus = '-';
const minusRegExp = /-/;
const nonDigitsRegExp = /\D+/g;
const number = 'number';
const digitRegExp = /\d/;
const caretTrap = '[]';
type Mask = Array<RegExp | string>;
export function createNumberMask({
prefix = dollarSign,
suffix = emptyString,
includeThousandsSeparator = true,
thousandsSeparatorSymbol = comma,
allowDecimal = false,
decimalSymbol = period,
decimalLimit = 2,
decimalSuffixMask = [' '],
requireDecimal = false,
allowNegative = false,
allowLeadingZeroes = false,
integerLimit = null
} = {}): TextMaskConfig {
const prefixLength = (prefix && prefix.length) || 0;
const suffixLength = (suffix && suffix.length) || 0;
const thousandsSeparatorSymbolLength = (thousandsSeparatorSymbol && thousandsSeparatorSymbol.length) || 0;
function numberMask(rawValue = emptyString) {
const rawValueLength = rawValue.length;
if (rawValue === emptyString || (rawValue[0] === prefix[0] && rawValueLength === 1)) {
return [...prefix.split(emptyString), digitRegExp, ...suffix.split(emptyString)];
} else if (rawValue === decimalSymbol && allowDecimal) {
return [
...prefix.split(emptyString),
'0',
decimalSymbol,
...decimalSuffixMask,
digitRegExp,
...suffix.split(emptyString)
];
}
const isNegative = rawValue[0] === minus && allowNegative;
//If negative remove "-" sign
if (isNegative) {
rawValue = rawValue.toString().substr(1);
}
const indexOfLastDecimal = rawValue.lastIndexOf(decimalSymbol);
const hasDecimal = indexOfLastDecimal !== -1;
let integer;
let fraction;
let mask;
// remove the suffix
if (rawValue.slice(suffixLength * -1) === suffix) {
rawValue = rawValue.slice(0, suffixLength * -1);
}
if (hasDecimal && (allowDecimal || requireDecimal)) {
integer = rawValue.slice(rawValue.slice(0, prefixLength) === prefix ? prefixLength : 0, indexOfLastDecimal);
fraction = rawValue.slice(indexOfLastDecimal + 1, rawValueLength);
fraction = convertToMask(fraction.replace(nonDigitsRegExp, emptyString));
} else {
if (rawValue.slice(0, prefixLength) === prefix) {
integer = rawValue.slice(prefixLength);
} else {
integer = rawValue;
}
}
if (integerLimit && typeof integerLimit === number) {
const thousandsSeparatorRegex = thousandsSeparatorSymbol === '.' ? '[.]' : `${thousandsSeparatorSymbol}`;
const numberOfThousandSeparators = (integer.match(new RegExp(thousandsSeparatorRegex, 'g')) || []).length;
integer = integer.slice(0, integerLimit + numberOfThousandSeparators * thousandsSeparatorSymbolLength);
}
integer = integer.replace(nonDigitsRegExp, emptyString);
if (!allowLeadingZeroes) {
integer = integer.replace(/^0+(0$|[^0])/, '$1');
}
integer = includeThousandsSeparator ? addThousandsSeparator(integer, thousandsSeparatorSymbol) : integer;
mask = convertToMask(integer);
if ((hasDecimal && allowDecimal) || requireDecimal) {
if (rawValue[indexOfLastDecimal - 1] !== decimalSymbol) {
mask.push(caretTrap);
}
mask.push(decimalSymbol, caretTrap, ...decimalSuffixMask);
if (fraction) {
if (typeof decimalLimit === number) {
fraction = fraction.slice(0, decimalLimit);
}
mask = mask.concat(fraction);
}
if (requireDecimal === true && rawValue[indexOfLastDecimal - 1] === decimalSymbol) {
mask.push(digitRegExp);
}
}
if (prefixLength > 0) {
mask = prefix.split(emptyString).concat(mask);
}
if (isNegative) {
// If user is entering a negative number, add a mask placeholder spot to attract the caret to it.
if (mask.length === prefixLength) {
mask.push(digitRegExp);
}
mask = [minusRegExp].concat(mask);
}
if (suffix.length > 0) {
mask = mask.concat(suffix.split(emptyString));
}
return mask;
}
numberMask.instanceOf = 'createNumberMask';
return { mask: numberMask, guide: false };
}
function convertToMask(strNumber) {
return strNumber.split(emptyString).map(char => (digitRegExp.test(char) ? digitRegExp : char));
}
// http://stackoverflow.com/a/10899795/604296
function addThousandsSeparator(n, thousandsSeparatorSymbol) {
return n.replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparatorSymbol);
}

View File

@ -0,0 +1,8 @@
import { createNumberMask } from './create-number-mask';
export const currencyMask = createNumberMask({
prefix: '',
thousandsSeparatorSymbol: ' ',
allowDecimal: true,
decimalSymbol: ','
});

View File

@ -0,0 +1 @@
export * from './currency';

View File

@ -0,0 +1,18 @@
<dsh-card>
<dsh-card-content fxLayout="column" [formGroup]="formGroup">
<mat-form-field>
<mat-label>BIN банка-эмитента карты</mat-label>
<dsh-bin-input></dsh-bin-input>
<mat-hint>Первые 4-8 цифр</mat-hint>
</mat-form-field>
<mat-form-field>
<mat-label>Последние цифры номера карты</mat-label>
<dsh-card-input></dsh-card-input>
<mat-hint>Последние 2-4 цифр</mat-hint>
</mat-form-field>
<mat-form-field>
<mat-label>Сумма платежа</mat-label>
<input matInput formControlName="sum" [textMask]="currencyMask" placeholder="0, 00" />
</mat-form-field>
</dsh-card-content>
</dsh-card>

View File

@ -0,0 +1,25 @@
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { currencyMask } from '../../form-controls';
@Component({
templateUrl: 'inputs.component.html',
styleUrls: ['inputs.component.scss'],
providers: []
})
export class InputsComponent {
formGroup: FormGroup;
get currencyMask() {
return currencyMask;
}
constructor(fb: FormBuilder) {
this.formGroup = fb.group({
bin: '',
card: '',
sum: ''
});
}
}

View File

@ -0,0 +1,22 @@
import { NgModule } from '@angular/core';
import { MatFormFieldModule, MatInputModule } from '@angular/material';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { InputsComponent } from './inputs.component';
import { FormControlsModule } from '../../form-controls/form-controls.module';
import { LayoutModule } from 'src/app/layout';
import { FlexLayoutModule } from '@angular/flex-layout';
@NgModule({
imports: [
MatFormFieldModule,
FormsModule,
ReactiveFormsModule,
MatInputModule,
FormControlsModule,
LayoutModule,
FlexLayoutModule
],
declarations: [InputsComponent]
})
export class InputsModule {}

View File

@ -7,6 +7,7 @@ import { AnalyticsComponent } from './analytics';
import { TableComponent } from './table';
import { routes as onboargindRoutes } from './onboarding';
import { ButtonsComponent } from './buttons';
import { InputsComponent } from './inputs/inputs.component';
const routes: Routes = [
{
@ -26,6 +27,10 @@ const routes: Routes = [
path: 'buttons',
component: ButtonsComponent
},
{
path: 'inputs',
component: InputsComponent
},
{
path: '**',
component: PageNotFoundComponent

View File

@ -7,6 +7,7 @@ import { PageNotFoundModule } from './page-not-found';
import { TableModule } from './table';
import { OnboardingModule } from './onboarding';
import { ButtonsModule } from './buttons';
import { InputsModule } from './inputs/inputs.module';
@NgModule({
imports: [
@ -16,7 +17,8 @@ import { ButtonsModule } from './buttons';
PageNotFoundModule,
TableModule,
OnboardingModule,
ButtonsModule
ButtonsModule,
InputsModule
],
declarations: [],
entryComponents: [],