@jobber/components 6.52.0 → 6.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/InputPhoneNumber/InputMask.d.ts +7 -0
- package/dist/InputPhoneNumber/InputPhoneNumber.d.ts +2 -19
- package/dist/InputPhoneNumber/InputPhoneNumber.rebuilt.d.ts +3 -0
- package/dist/InputPhoneNumber/InputPhoneNumber.types.d.ts +56 -0
- package/dist/InputPhoneNumber/hooks/useInputPhoneActions.d.ts +16 -0
- package/dist/InputPhoneNumber/hooks/useInputPhoneFormField.d.ts +71 -0
- package/dist/InputPhoneNumber/index.cjs +247 -11
- package/dist/InputPhoneNumber/index.d.ts +5 -1
- package/dist/InputPhoneNumber/index.mjs +250 -10
- package/dist/InputPhoneNumber/useInputMask.d.ts +48 -0
- package/dist/index.cjs +2 -2
- package/dist/index.mjs +1 -1
- package/dist/styles.css +2452 -2447
- package/package.json +2 -2
- package/dist/InputPhoneNumber-cjs.js +0 -100
- package/dist/InputPhoneNumber-es.js +0 -98
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.53.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -534,5 +534,5 @@
|
|
|
534
534
|
"> 1%",
|
|
535
535
|
"IE 10"
|
|
536
536
|
],
|
|
537
|
-
"gitHead": "
|
|
537
|
+
"gitHead": "4c1a525d9fcbe458181296b921a52fd3cacea52e"
|
|
538
538
|
}
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var tslib_es6 = require('./tslib.es6-cjs.js');
|
|
4
|
-
var React = require('react');
|
|
5
|
-
var reactHookForm = require('react-hook-form');
|
|
6
|
-
var FormField = require('./FormField-cjs.js');
|
|
7
|
-
require('classnames');
|
|
8
|
-
require('framer-motion');
|
|
9
|
-
require('@jobber/design');
|
|
10
|
-
require('./Button-cjs.js');
|
|
11
|
-
|
|
12
|
-
var styles = {"mask":"_78-Lxj78xPg-","hiddenValue":"GoiXVXaU1Qs-","spinning":"T3VvmDmzs-4-"};
|
|
13
|
-
|
|
14
|
-
function InputMask({ children, delimiter = "*", pattern, strict = true, }) {
|
|
15
|
-
const { value: inputValue, onChange } = children.props;
|
|
16
|
-
const [isMasking, setIsMasking] = React.useState(!inputValue);
|
|
17
|
-
const stringifiedValue = String(inputValue || "");
|
|
18
|
-
const placeholderValue = pattern
|
|
19
|
-
.replace(new RegExp(`\\${delimiter}`, "g"), "_")
|
|
20
|
-
.slice(stringifiedValue.length);
|
|
21
|
-
const inputMask = (React.createElement("div", { className: styles.mask, "aria-hidden": "true" },
|
|
22
|
-
React.createElement("span", { className: styles.hiddenValue }, stringifiedValue),
|
|
23
|
-
React.createElement("span", null, placeholderValue)));
|
|
24
|
-
return React.cloneElement(children, {
|
|
25
|
-
onChange: handleChange,
|
|
26
|
-
children: isMasking && inputMask,
|
|
27
|
-
});
|
|
28
|
-
function handleChange(value) {
|
|
29
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(formatValue(value));
|
|
30
|
-
}
|
|
31
|
-
function formatValue(value) {
|
|
32
|
-
const { cleanValueChars, patternChars, specialChars, isOverCharLimit } = getMaskingInfo(value);
|
|
33
|
-
if (!strict && isOverCharLimit) {
|
|
34
|
-
setIsMasking(false);
|
|
35
|
-
return cleanValueChars.join("");
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
setIsMasking(true);
|
|
39
|
-
return patternChars.reduce(getMaskedValue(cleanValueChars, specialChars), "");
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function getMaskingInfo(value) {
|
|
43
|
-
const patternChars = pattern.split("");
|
|
44
|
-
const specialChars = patternChars.filter(char => char !== delimiter);
|
|
45
|
-
const cleanValueChars = value
|
|
46
|
-
.split("")
|
|
47
|
-
.filter(char => !specialChars.includes(char))
|
|
48
|
-
// Since this is only used in InputPhoneNumber, we can restrict it to
|
|
49
|
-
// just numbers for now.
|
|
50
|
-
.map(Number)
|
|
51
|
-
.filter(num => !isNaN(num));
|
|
52
|
-
const isOverCharLimit = cleanValueChars.length > patternChars.length - specialChars.length;
|
|
53
|
-
return { cleanValueChars, patternChars, specialChars, isOverCharLimit };
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
function getMaskedValue(cleanVal, specialChars) {
|
|
57
|
-
return (result, nextCharacter) => {
|
|
58
|
-
if (!cleanVal.length)
|
|
59
|
-
return result;
|
|
60
|
-
if (specialChars.includes(nextCharacter))
|
|
61
|
-
return result + nextCharacter;
|
|
62
|
-
const nextValue = cleanVal.shift();
|
|
63
|
-
return result + nextValue;
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function InputPhoneNumber(_a) {
|
|
68
|
-
var { required } = _a, props = tslib_es6.__rest(_a, ["required"]);
|
|
69
|
-
const { placeholder, validations, pattern = "(***) ***-****" } = props;
|
|
70
|
-
const errorSubject = placeholder || "Phone number";
|
|
71
|
-
const { getValues } = reactHookForm.useFormContext() != undefined
|
|
72
|
-
? reactHookForm.useFormContext()
|
|
73
|
-
: // If there isn't a Form Context being provided, get a form for this field.
|
|
74
|
-
reactHookForm.useForm({ mode: "onTouched" });
|
|
75
|
-
return (React.createElement(InputMask, { pattern: pattern, strict: false },
|
|
76
|
-
React.createElement(FormField.FormField, Object.assign({}, props, { type: "tel", pattern: pattern, validations: Object.assign(Object.assign({ required: {
|
|
77
|
-
value: Boolean(required),
|
|
78
|
-
message: `${errorSubject} is required`,
|
|
79
|
-
} }, validations), { validate: getPhoneNumberValidation }) }))));
|
|
80
|
-
function getPhoneNumberValidation(value) {
|
|
81
|
-
// Get unique characters that aren't * in the pattern
|
|
82
|
-
const patternNonDelimterCharacters = pattern
|
|
83
|
-
.split("")
|
|
84
|
-
.filter(char => char !== "*")
|
|
85
|
-
.filter((char, index, arr) => arr.indexOf(char) === index);
|
|
86
|
-
const specialCharacters = patternNonDelimterCharacters.join(" ");
|
|
87
|
-
// Remove special characters from pattern
|
|
88
|
-
const cleanValue = value.replace(new RegExp(`[${specialCharacters}]`, "g"), "");
|
|
89
|
-
const cleanValueRequiredLength = (pattern.match(/\*/g) || []).length;
|
|
90
|
-
if (cleanValue.length > 0 && cleanValue.length < cleanValueRequiredLength) {
|
|
91
|
-
return `${errorSubject} must contain ${cleanValueRequiredLength} or more digits`;
|
|
92
|
-
}
|
|
93
|
-
if (typeof (validations === null || validations === void 0 ? void 0 : validations.validate) === "function") {
|
|
94
|
-
return validations.validate(value, getValues);
|
|
95
|
-
}
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
exports.InputPhoneNumber = InputPhoneNumber;
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { _ as __rest } from './tslib.es6-es.js';
|
|
2
|
-
import React__default, { useState, cloneElement } from 'react';
|
|
3
|
-
import { useFormContext, useForm } from 'react-hook-form';
|
|
4
|
-
import { k as FormField } from './FormField-es.js';
|
|
5
|
-
import 'classnames';
|
|
6
|
-
import 'framer-motion';
|
|
7
|
-
import '@jobber/design';
|
|
8
|
-
import './Button-es.js';
|
|
9
|
-
|
|
10
|
-
var styles = {"mask":"_78-Lxj78xPg-","hiddenValue":"GoiXVXaU1Qs-","spinning":"T3VvmDmzs-4-"};
|
|
11
|
-
|
|
12
|
-
function InputMask({ children, delimiter = "*", pattern, strict = true, }) {
|
|
13
|
-
const { value: inputValue, onChange } = children.props;
|
|
14
|
-
const [isMasking, setIsMasking] = useState(!inputValue);
|
|
15
|
-
const stringifiedValue = String(inputValue || "");
|
|
16
|
-
const placeholderValue = pattern
|
|
17
|
-
.replace(new RegExp(`\\${delimiter}`, "g"), "_")
|
|
18
|
-
.slice(stringifiedValue.length);
|
|
19
|
-
const inputMask = (React__default.createElement("div", { className: styles.mask, "aria-hidden": "true" },
|
|
20
|
-
React__default.createElement("span", { className: styles.hiddenValue }, stringifiedValue),
|
|
21
|
-
React__default.createElement("span", null, placeholderValue)));
|
|
22
|
-
return cloneElement(children, {
|
|
23
|
-
onChange: handleChange,
|
|
24
|
-
children: isMasking && inputMask,
|
|
25
|
-
});
|
|
26
|
-
function handleChange(value) {
|
|
27
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(formatValue(value));
|
|
28
|
-
}
|
|
29
|
-
function formatValue(value) {
|
|
30
|
-
const { cleanValueChars, patternChars, specialChars, isOverCharLimit } = getMaskingInfo(value);
|
|
31
|
-
if (!strict && isOverCharLimit) {
|
|
32
|
-
setIsMasking(false);
|
|
33
|
-
return cleanValueChars.join("");
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
setIsMasking(true);
|
|
37
|
-
return patternChars.reduce(getMaskedValue(cleanValueChars, specialChars), "");
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
function getMaskingInfo(value) {
|
|
41
|
-
const patternChars = pattern.split("");
|
|
42
|
-
const specialChars = patternChars.filter(char => char !== delimiter);
|
|
43
|
-
const cleanValueChars = value
|
|
44
|
-
.split("")
|
|
45
|
-
.filter(char => !specialChars.includes(char))
|
|
46
|
-
// Since this is only used in InputPhoneNumber, we can restrict it to
|
|
47
|
-
// just numbers for now.
|
|
48
|
-
.map(Number)
|
|
49
|
-
.filter(num => !isNaN(num));
|
|
50
|
-
const isOverCharLimit = cleanValueChars.length > patternChars.length - specialChars.length;
|
|
51
|
-
return { cleanValueChars, patternChars, specialChars, isOverCharLimit };
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
function getMaskedValue(cleanVal, specialChars) {
|
|
55
|
-
return (result, nextCharacter) => {
|
|
56
|
-
if (!cleanVal.length)
|
|
57
|
-
return result;
|
|
58
|
-
if (specialChars.includes(nextCharacter))
|
|
59
|
-
return result + nextCharacter;
|
|
60
|
-
const nextValue = cleanVal.shift();
|
|
61
|
-
return result + nextValue;
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function InputPhoneNumber(_a) {
|
|
66
|
-
var { required } = _a, props = __rest(_a, ["required"]);
|
|
67
|
-
const { placeholder, validations, pattern = "(***) ***-****" } = props;
|
|
68
|
-
const errorSubject = placeholder || "Phone number";
|
|
69
|
-
const { getValues } = useFormContext() != undefined
|
|
70
|
-
? useFormContext()
|
|
71
|
-
: // If there isn't a Form Context being provided, get a form for this field.
|
|
72
|
-
useForm({ mode: "onTouched" });
|
|
73
|
-
return (React__default.createElement(InputMask, { pattern: pattern, strict: false },
|
|
74
|
-
React__default.createElement(FormField, Object.assign({}, props, { type: "tel", pattern: pattern, validations: Object.assign(Object.assign({ required: {
|
|
75
|
-
value: Boolean(required),
|
|
76
|
-
message: `${errorSubject} is required`,
|
|
77
|
-
} }, validations), { validate: getPhoneNumberValidation }) }))));
|
|
78
|
-
function getPhoneNumberValidation(value) {
|
|
79
|
-
// Get unique characters that aren't * in the pattern
|
|
80
|
-
const patternNonDelimterCharacters = pattern
|
|
81
|
-
.split("")
|
|
82
|
-
.filter(char => char !== "*")
|
|
83
|
-
.filter((char, index, arr) => arr.indexOf(char) === index);
|
|
84
|
-
const specialCharacters = patternNonDelimterCharacters.join(" ");
|
|
85
|
-
// Remove special characters from pattern
|
|
86
|
-
const cleanValue = value.replace(new RegExp(`[${specialCharacters}]`, "g"), "");
|
|
87
|
-
const cleanValueRequiredLength = (pattern.match(/\*/g) || []).length;
|
|
88
|
-
if (cleanValue.length > 0 && cleanValue.length < cleanValueRequiredLength) {
|
|
89
|
-
return `${errorSubject} must contain ${cleanValueRequiredLength} or more digits`;
|
|
90
|
-
}
|
|
91
|
-
if (typeof (validations === null || validations === void 0 ? void 0 : validations.validate) === "function") {
|
|
92
|
-
return validations.validate(value, getValues);
|
|
93
|
-
}
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export { InputPhoneNumber as I };
|