@elliemae/ds-controlled-form 2.3.0-next.16 → 2.3.0-next.17
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/cjs/controlled-mask-hook/hooks/index.js +10 -0
- package/cjs/controlled-mask-hook/hooks/usePhoneMask.js +72 -0
- package/cjs/controlled-mask-hook/index.js +10 -0
- package/cjs/controlled-mask-hook/react-desc-prop-types.js +19 -0
- package/cjs/controlled-mask-hook/utils/addSpecialCharacters.js +50 -0
- package/cjs/controlled-mask-hook/utils/getPartialMaskedPos.js +15 -0
- package/cjs/controlled-mask-hook/utils/index.js +13 -0
- package/cjs/controlled-mask-hook/utils/setCursorPosition.js +9 -0
- package/cjs/controlled-text-input/DSInputText.js +89 -0
- package/cjs/controlled-text-input/config/useInputText.js +54 -0
- package/cjs/controlled-text-input/exported-related/data-test-ids.js +10 -0
- package/cjs/controlled-text-input/exported-related/index.js +12 -0
- package/cjs/controlled-text-input/exported-related/theming.js +13 -0
- package/cjs/controlled-text-input/index.js +15 -0
- package/cjs/controlled-text-input/react-desc-prop-types.js +45 -0
- package/cjs/controlled-text-input/styled/borders.js +33 -0
- package/cjs/controlled-text-input/styled/components.js +38 -0
- package/cjs/index.js +17 -6
- package/esm/controlled-mask-hook/hooks/index.js +1 -0
- package/esm/controlled-mask-hook/hooks/usePhoneMask.js +67 -0
- package/esm/controlled-mask-hook/index.js +1 -0
- package/esm/controlled-mask-hook/react-desc-prop-types.js +14 -0
- package/esm/controlled-mask-hook/utils/addSpecialCharacters.js +46 -0
- package/esm/controlled-mask-hook/utils/getPartialMaskedPos.js +11 -0
- package/esm/controlled-mask-hook/utils/index.js +3 -0
- package/esm/controlled-mask-hook/utils/setCursorPosition.js +5 -0
- package/esm/controlled-text-input/DSInputText.js +78 -0
- package/esm/controlled-text-input/config/useInputText.js +50 -0
- package/esm/controlled-text-input/exported-related/data-test-ids.js +6 -0
- package/esm/controlled-text-input/exported-related/index.js +2 -0
- package/esm/controlled-text-input/exported-related/theming.js +8 -0
- package/esm/controlled-text-input/index.js +3 -0
- package/esm/controlled-text-input/react-desc-prop-types.js +36 -0
- package/esm/controlled-text-input/styled/borders.js +24 -0
- package/esm/controlled-text-input/styled/components.js +28 -0
- package/esm/index.js +6 -2
- package/package.json +79 -10
- package/types/controlled-autocomplete/parts/controls/styled.d.ts +1 -1
- package/types/controlled-combobox/parts/controls/styled.d.ts +2 -2
- package/types/controlled-combobox/parts/dropdown-indicator/styled.d.ts +1 -1
- package/types/controlled-date-time-picker/parts/Pickers/Calendar/Styleds.d.ts +4 -4
- package/types/controlled-date-time-picker/parts/Pickers/CalendarWithTimeWheel/Styleds.d.ts +1 -1
- package/types/controlled-date-time-picker/parts/Pickers/TimeWheel/Styleds.d.ts +4 -4
- package/types/controlled-date-time-picker/parts/Styleds.d.ts +6 -6
- package/types/controlled-mask-hook/hooks/index.d.ts +1 -0
- package/types/controlled-mask-hook/hooks/usePhoneMask.d.ts +3 -0
- package/types/controlled-mask-hook/index.d.ts +2 -0
- package/types/controlled-mask-hook/react-desc-prop-types.d.ts +17 -0
- package/types/controlled-mask-hook/tests/usePhoneMask.test.d.ts +1 -0
- package/types/controlled-mask-hook/utils/addSpecialCharacters.d.ts +9 -0
- package/types/controlled-mask-hook/utils/getPartialMaskedPos.d.ts +1 -0
- package/types/controlled-mask-hook/utils/index.d.ts +3 -0
- package/types/controlled-mask-hook/utils/setCursorPosition.d.ts +1 -0
- package/types/controlled-text-input/DSInputText.d.ts +4 -0
- package/types/controlled-text-input/config/useInputText.d.ts +434 -0
- package/types/controlled-text-input/exported-related/data-test-ids.d.ts +4 -0
- package/types/controlled-text-input/exported-related/index.d.ts +2 -0
- package/types/controlled-text-input/exported-related/theming.d.ts +6 -0
- package/types/controlled-text-input/index.d.ts +2 -0
- package/types/controlled-text-input/react-desc-prop-types.d.ts +20 -0
- package/types/controlled-text-input/styled/borders.d.ts +10 -0
- package/types/controlled-text-input/styled/components.d.ts +3 -0
- package/types/controlled-text-input/tests/DSInput.events.test.d.ts +1 -0
- package/types/controlled-text-input/tests/DSInput.keyboard.test.d.ts +1 -0
- package/types/controlled-text-input/tests/DSInput.test.d.ts +1 -0
- package/types/index.d.ts +4 -2
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var usePhoneMask = require('./usePhoneMask.js');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
exports.UsePhoneMaskWithSchema = usePhoneMask.UsePhoneMaskWithSchema;
|
|
10
|
+
exports.usePhoneMask = usePhoneMask.usePhoneMask;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('core-js/modules/esnext.async-iterator.filter.js');
|
|
6
|
+
require('core-js/modules/esnext.iterator.constructor.js');
|
|
7
|
+
require('core-js/modules/esnext.iterator.filter.js');
|
|
8
|
+
require('core-js/modules/web.dom-collections.iterator.js');
|
|
9
|
+
var React = require('react');
|
|
10
|
+
var dsPropsHelpers = require('@elliemae/ds-props-helpers');
|
|
11
|
+
var dsUtilities = require('@elliemae/ds-utilities');
|
|
12
|
+
var addSpecialCharacters = require('../utils/addSpecialCharacters.js');
|
|
13
|
+
var getPartialMaskedPos = require('../utils/getPartialMaskedPos.js');
|
|
14
|
+
var setCursorPosition = require('../utils/setCursorPosition.js');
|
|
15
|
+
var reactDescPropTypes = require('../react-desc-prop-types.js');
|
|
16
|
+
|
|
17
|
+
const phoneSpecialChars = [['(', 0], [') ', 4], ['-', 9]];
|
|
18
|
+
|
|
19
|
+
const conformValue = (rawValue, cursorPos, lastKeyCode) => {
|
|
20
|
+
// Work with digits only
|
|
21
|
+
let maskedValue = rawValue.split('').filter(char => char >= '0' && char <= '9'); // We can't have zeros at the start of the array
|
|
22
|
+
|
|
23
|
+
while (maskedValue.length && maskedValue[0] === '0') maskedValue.splice(0, 1); // We only consider first 10 digits
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
maskedValue = maskedValue.slice(0, 10);
|
|
27
|
+
const maskedPos = getPartialMaskedPos.getPartialMaskedPos(rawValue, maskedValue, cursorPos);
|
|
28
|
+
return addSpecialCharacters.addSpecialCharacters(maskedValue, phoneSpecialChars, maskedPos, lastKeyCode);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const usePhoneMask = props => {
|
|
32
|
+
const propsWithDefault = dsPropsHelpers.useMemoMergePropsWithDefault(props, reactDescPropTypes.DSMaskHookDefaultProps);
|
|
33
|
+
dsPropsHelpers.useValidateTypescriptPropTypes(propsWithDefault, reactDescPropTypes.DSMaskHookPropsTypes);
|
|
34
|
+
const {
|
|
35
|
+
valueSetter,
|
|
36
|
+
onChange: userOnChange,
|
|
37
|
+
onKeyDown: userOnKeyDown
|
|
38
|
+
} = propsWithDefault;
|
|
39
|
+
const lastKeyCode = React.useRef('Unidentified');
|
|
40
|
+
const scheduleAfterRender = dsUtilities.useCallbackAfterRender(); // Some times, the value of the mask is not gonna change (user types invalid char for example)
|
|
41
|
+
// This makes the input to go from "correct" -> "incorrect" -> "correct"
|
|
42
|
+
// But since the input is controlled, the input does not re-render
|
|
43
|
+
// This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async
|
|
44
|
+
// Solution for this is to trigger a re-render, we do this with a set state call in the on change event
|
|
45
|
+
|
|
46
|
+
const [, setKey] = React.useState(0);
|
|
47
|
+
const onKeyDown = React.useCallback(e => {
|
|
48
|
+
lastKeyCode.current = e.code;
|
|
49
|
+
if (userOnKeyDown) userOnKeyDown(e);
|
|
50
|
+
}, [userOnKeyDown]);
|
|
51
|
+
const onChange = React.useCallback(e => {
|
|
52
|
+
var _e$target$selectionEn;
|
|
53
|
+
|
|
54
|
+
const [mask, cursorPos] = conformValue(e.target.value, (_e$target$selectionEn = e.target.selectionEnd) !== null && _e$target$selectionEn !== void 0 ? _e$target$selectionEn : 0, lastKeyCode.current);
|
|
55
|
+
valueSetter(prevMask => {
|
|
56
|
+
// Here we need to update the key
|
|
57
|
+
if (mask === prevMask) setKey(key => key + 1);
|
|
58
|
+
return mask;
|
|
59
|
+
});
|
|
60
|
+
if (userOnChange) userOnChange(e, mask);
|
|
61
|
+
scheduleAfterRender(() => setCursorPosition.setCursorPosition(e.target, cursorPos));
|
|
62
|
+
}, [valueSetter, scheduleAfterRender, userOnChange]);
|
|
63
|
+
return {
|
|
64
|
+
onKeyDown,
|
|
65
|
+
onChange
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
const UsePhoneMaskWithSchema = dsPropsHelpers.describe(usePhoneMask);
|
|
69
|
+
UsePhoneMaskWithSchema.propTypes = reactDescPropTypes.DSMaskHookPropsTypes;
|
|
70
|
+
|
|
71
|
+
exports.UsePhoneMaskWithSchema = UsePhoneMaskWithSchema;
|
|
72
|
+
exports.usePhoneMask = usePhoneMask;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var usePhoneMask = require('./hooks/usePhoneMask.js');
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
exports.UsePhoneMaskWithSchema = usePhoneMask.UsePhoneMaskWithSchema;
|
|
10
|
+
exports.usePhoneMask = usePhoneMask.usePhoneMask;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var dsPropsHelpers = require('@elliemae/ds-props-helpers');
|
|
6
|
+
|
|
7
|
+
const DSMaskHookDefaultProps = {
|
|
8
|
+
onChange: () => null,
|
|
9
|
+
onKeyDown: () => null,
|
|
10
|
+
onBlur: () => null
|
|
11
|
+
};
|
|
12
|
+
const DSMaskHookPropsTypes = {
|
|
13
|
+
valueSetter: dsPropsHelpers.PropTypes.func.description('React set state function for the value').isRequired,
|
|
14
|
+
onChange: dsPropsHelpers.PropTypes.func.description('Callback for onChange'),
|
|
15
|
+
onKeyDown: dsPropsHelpers.PropTypes.func.description('Callback for onKeyDown')
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
exports.DSMaskHookDefaultProps = DSMaskHookDefaultProps;
|
|
19
|
+
exports.DSMaskHookPropsTypes = DSMaskHookPropsTypes;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('core-js/modules/esnext.async-iterator.for-each.js');
|
|
6
|
+
require('core-js/modules/esnext.iterator.constructor.js');
|
|
7
|
+
require('core-js/modules/esnext.iterator.for-each.js');
|
|
8
|
+
require('core-js/modules/web.dom-collections.iterator.js');
|
|
9
|
+
|
|
10
|
+
/* eslint-disable max-params */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @param {string[]} maskWithoutSpecialChars An array of characters with the unfinished mask
|
|
15
|
+
* @param {[string, number][]} specialCharsDescr An array of tuples. Each tuple contains a string and a position (What string to add in a particular position)
|
|
16
|
+
* @param {number} maskedPos Current masked position
|
|
17
|
+
* @param {string} lastKeyCode Last key code of the user
|
|
18
|
+
* @returns {[string, number]} A tuple containing the final mask and the final masked position
|
|
19
|
+
*/
|
|
20
|
+
const addSpecialCharacters = (maskWithoutSpecialChars, specialCharsDescr, maskedPos, lastKeyCode) => {
|
|
21
|
+
const finalMask = maskWithoutSpecialChars;
|
|
22
|
+
let finalMaskedPos = maskedPos; // We insert the special chars in the respective positions, tweaking the masked pos
|
|
23
|
+
|
|
24
|
+
specialCharsDescr.forEach(_ref => {
|
|
25
|
+
let [chars, pos] = _ref;
|
|
26
|
+
|
|
27
|
+
if (finalMask.length > pos) {
|
|
28
|
+
finalMask.splice(pos, 0, ...chars);
|
|
29
|
+
if (finalMaskedPos >= pos) finalMaskedPos += chars.length;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (lastKeyCode !== 'Backspace' && finalMaskedPos < finalMask.length) {
|
|
34
|
+
// If not erasing, move the cursor forward if we are in a special chars area
|
|
35
|
+
specialCharsDescr.forEach(_ref2 => {
|
|
36
|
+
let [chars, pos] = _ref2;
|
|
37
|
+
if (finalMaskedPos === pos) finalMaskedPos += chars.length;
|
|
38
|
+
});
|
|
39
|
+
} else if (lastKeyCode === 'Backspace' && finalMaskedPos) {
|
|
40
|
+
// If erasing, move the cursor back if we are in a special chars area
|
|
41
|
+
specialCharsDescr.forEach(_ref3 => {
|
|
42
|
+
let [chars, pos] = _ref3;
|
|
43
|
+
if (pos + 1 <= finalMaskedPos && finalMaskedPos <= pos + chars.length) finalMaskedPos = pos;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return [finalMask.join(''), finalMaskedPos];
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
exports.addSpecialCharacters = addSpecialCharacters;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const getPartialMaskedPos = (rawValue, maskWithoutSpecialChars, cursorPos) => {
|
|
6
|
+
let maskedPos = 0;
|
|
7
|
+
|
|
8
|
+
for (let i = 0; i < cursorPos; i += 1) {
|
|
9
|
+
if (maskWithoutSpecialChars[maskedPos] === rawValue[i]) maskedPos += 1;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return maskedPos;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
exports.getPartialMaskedPos = getPartialMaskedPos;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var addSpecialCharacters = require('./addSpecialCharacters.js');
|
|
6
|
+
var getPartialMaskedPos = require('./getPartialMaskedPos.js');
|
|
7
|
+
var setCursorPosition = require('./setCursorPosition.js');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
exports.addSpecialCharacters = addSpecialCharacters.addSpecialCharacters;
|
|
12
|
+
exports.getPartialMaskedPos = getPartialMaskedPos.getPartialMaskedPos;
|
|
13
|
+
exports.setCursorPosition = setCursorPosition.setCursorPosition;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('core-js/modules/esnext.async-iterator.filter.js');
|
|
6
|
+
require('core-js/modules/esnext.iterator.constructor.js');
|
|
7
|
+
require('core-js/modules/esnext.iterator.filter.js');
|
|
8
|
+
require('core-js/modules/esnext.async-iterator.for-each.js');
|
|
9
|
+
require('core-js/modules/esnext.iterator.for-each.js');
|
|
10
|
+
var _jsx = require('@babel/runtime/helpers/jsx');
|
|
11
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
12
|
+
var _objectWithoutProperties = require('@babel/runtime/helpers/objectWithoutProperties');
|
|
13
|
+
require('react');
|
|
14
|
+
var dsIcons = require('@elliemae/ds-icons');
|
|
15
|
+
var dsIcon = require('@elliemae/ds-icon');
|
|
16
|
+
var dsPropsHelpers = require('@elliemae/ds-props-helpers');
|
|
17
|
+
var useInputText = require('./config/useInputText.js');
|
|
18
|
+
var dataTestIds = require('./exported-related/data-test-ids.js');
|
|
19
|
+
var reactDescPropTypes = require('./react-desc-prop-types.js');
|
|
20
|
+
var components = require('./styled/components.js');
|
|
21
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
22
|
+
|
|
23
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
24
|
+
|
|
25
|
+
var _jsx__default = /*#__PURE__*/_interopDefaultLegacy(_jsx);
|
|
26
|
+
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
|
|
27
|
+
var _objectWithoutProperties__default = /*#__PURE__*/_interopDefaultLegacy(_objectWithoutProperties);
|
|
28
|
+
|
|
29
|
+
const _excluded = ["className"];
|
|
30
|
+
|
|
31
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
32
|
+
|
|
33
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
34
|
+
const DSInputText = props => {
|
|
35
|
+
const _useInputText = useInputText.useInputText(props),
|
|
36
|
+
{
|
|
37
|
+
globalAttributes: {
|
|
38
|
+
className
|
|
39
|
+
},
|
|
40
|
+
hasFocus,
|
|
41
|
+
handlers,
|
|
42
|
+
propsWithDefault,
|
|
43
|
+
xstyledProps
|
|
44
|
+
} = _useInputText,
|
|
45
|
+
otherGlobalAttributes = _objectWithoutProperties__default["default"](_useInputText.globalAttributes, _excluded);
|
|
46
|
+
|
|
47
|
+
const {
|
|
48
|
+
clearable,
|
|
49
|
+
disabled,
|
|
50
|
+
hasError,
|
|
51
|
+
innerRef,
|
|
52
|
+
placeholder,
|
|
53
|
+
readOnly,
|
|
54
|
+
inputSize,
|
|
55
|
+
onClear,
|
|
56
|
+
value
|
|
57
|
+
} = propsWithDefault;
|
|
58
|
+
const shouldDisplayClearButton = clearable && value !== '';
|
|
59
|
+
return /*#__PURE__*/jsxRuntime.jsxs(components.StyledInputWrapper, _objectSpread(_objectSpread({
|
|
60
|
+
className: className,
|
|
61
|
+
cols: shouldDisplayClearButton ? ['auto', 'min-content'] : ['auto'],
|
|
62
|
+
isDisabled: disabled,
|
|
63
|
+
isReadOnly: readOnly,
|
|
64
|
+
hasError: hasError,
|
|
65
|
+
hasFocus: hasFocus,
|
|
66
|
+
inputSize: inputSize
|
|
67
|
+
}, xstyledProps), {}, {
|
|
68
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(components.StyledInput, _objectSpread(_objectSpread({
|
|
69
|
+
"data-testid": dataTestIds.DSInputTextDataTestIds.INPUT,
|
|
70
|
+
disabled: disabled,
|
|
71
|
+
placeholder: placeholder,
|
|
72
|
+
readOnly: readOnly,
|
|
73
|
+
ref: innerRef,
|
|
74
|
+
value: value
|
|
75
|
+
}, handlers), otherGlobalAttributes)), shouldDisplayClearButton && /*#__PURE__*/_jsx__default["default"](components.StyledClearButton, {
|
|
76
|
+
"aria-label": "Clear input value",
|
|
77
|
+
buttonType: "icon",
|
|
78
|
+
"data-testid": dataTestIds.DSInputTextDataTestIds.CLEAR_BUTTON,
|
|
79
|
+
onClick: onClear
|
|
80
|
+
}, void 0, /*#__PURE__*/_jsx__default["default"](dsIcons.CloseMedium, {
|
|
81
|
+
color: dsIcon.DSIconColors.PRIMARY
|
|
82
|
+
}))]
|
|
83
|
+
}));
|
|
84
|
+
};
|
|
85
|
+
const DSInputTextWithSchema = dsPropsHelpers.describe(DSInputText);
|
|
86
|
+
DSInputTextWithSchema.propTypes = reactDescPropTypes.DSInputTextPropTypes;
|
|
87
|
+
|
|
88
|
+
exports.DSInputText = DSInputText;
|
|
89
|
+
exports.DSInputTextWithSchema = DSInputTextWithSchema;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('core-js/modules/web.dom-collections.iterator.js');
|
|
6
|
+
var dsPropsHelpers = require('@elliemae/ds-props-helpers');
|
|
7
|
+
var React = require('react');
|
|
8
|
+
var reactDescPropTypes = require('../react-desc-prop-types.js');
|
|
9
|
+
|
|
10
|
+
const useInputText = props => {
|
|
11
|
+
const propsWithDefault = dsPropsHelpers.useMemoMergePropsWithDefault(props, reactDescPropTypes.defaultProps);
|
|
12
|
+
dsPropsHelpers.useValidateTypescriptPropTypes(props, reactDescPropTypes.DSInputTextPropTypes);
|
|
13
|
+
const {
|
|
14
|
+
onValueChange
|
|
15
|
+
} = propsWithDefault; // =============================================================================
|
|
16
|
+
// INTERNAL STATE
|
|
17
|
+
// =============================================================================
|
|
18
|
+
|
|
19
|
+
const [hasFocus, setHasFocus] = React.useState(false); // ===========================================================================
|
|
20
|
+
// INTERNAL HANDLERS
|
|
21
|
+
// ===========================================================================
|
|
22
|
+
|
|
23
|
+
const handleOnChange = React.useCallback(e => {
|
|
24
|
+
onValueChange(e.target.value, e);
|
|
25
|
+
}, [onValueChange]);
|
|
26
|
+
const handleOnFocus = React.useCallback(() => {
|
|
27
|
+
setHasFocus(true);
|
|
28
|
+
}, []);
|
|
29
|
+
const handleOnBlur = React.useCallback(() => {
|
|
30
|
+
setHasFocus(false);
|
|
31
|
+
}, []); // =============================================================================
|
|
32
|
+
// GLOBAL ATTRIBUTES & XSTYLED PROPS
|
|
33
|
+
// =============================================================================
|
|
34
|
+
|
|
35
|
+
const globalAttributes = dsPropsHelpers.useGetGlobalAttributes(propsWithDefault, {
|
|
36
|
+
onChange: handleOnChange,
|
|
37
|
+
onFocus: handleOnFocus,
|
|
38
|
+
onBlur: handleOnBlur
|
|
39
|
+
});
|
|
40
|
+
const xstyledProps = dsPropsHelpers.useGetXstyledProps(propsWithDefault);
|
|
41
|
+
return React.useMemo(() => ({
|
|
42
|
+
globalAttributes,
|
|
43
|
+
hasFocus,
|
|
44
|
+
handlers: {
|
|
45
|
+
onChange: handleOnChange,
|
|
46
|
+
onFocus: handleOnFocus,
|
|
47
|
+
onBlur: handleOnBlur
|
|
48
|
+
},
|
|
49
|
+
propsWithDefault,
|
|
50
|
+
xstyledProps
|
|
51
|
+
}), [globalAttributes, handleOnBlur, handleOnChange, handleOnFocus, hasFocus, propsWithDefault, xstyledProps]);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
exports.useInputText = useInputText;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const DSInputTextDataTestIds = {
|
|
6
|
+
INPUT: 'ds-input-text-input',
|
|
7
|
+
CLEAR_BUTTON: 'ds-input-text-clear-button'
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
exports.DSInputTextDataTestIds = DSInputTextDataTestIds;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var dataTestIds = require('./data-test-ids.js');
|
|
6
|
+
var theming = require('./theming.js');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
exports.DSInputTextDataTestIds = dataTestIds.DSInputTextDataTestIds;
|
|
11
|
+
exports.DSInputTextName = theming.DSInputTextName;
|
|
12
|
+
exports.DSInputTextSlots = theming.DSInputTextSlots;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const DSInputTextName = 'ds-input-text';
|
|
6
|
+
const DSInputTextSlots = {
|
|
7
|
+
INPUT_WRAPPER: 'root',
|
|
8
|
+
INPUT: 'input',
|
|
9
|
+
CLEAR_BUTTON: 'input-clear-button'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
exports.DSInputTextName = DSInputTextName;
|
|
13
|
+
exports.DSInputTextSlots = DSInputTextSlots;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var DSInputText = require('./DSInputText.js');
|
|
6
|
+
var dataTestIds = require('./exported-related/data-test-ids.js');
|
|
7
|
+
var theming = require('./exported-related/theming.js');
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
exports.DSInputText = DSInputText.DSInputText;
|
|
12
|
+
exports.DSInputTextWithSchema = DSInputText.DSInputTextWithSchema;
|
|
13
|
+
exports.DSInputTextDataTestIds = dataTestIds.DSInputTextDataTestIds;
|
|
14
|
+
exports.DSInputTextName = theming.DSInputTextName;
|
|
15
|
+
exports.DSInputTextSlots = theming.DSInputTextSlots;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
require('core-js/modules/esnext.async-iterator.filter.js');
|
|
6
|
+
require('core-js/modules/esnext.iterator.constructor.js');
|
|
7
|
+
require('core-js/modules/esnext.iterator.filter.js');
|
|
8
|
+
require('core-js/modules/esnext.async-iterator.for-each.js');
|
|
9
|
+
require('core-js/modules/esnext.iterator.for-each.js');
|
|
10
|
+
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
11
|
+
var dsPropsHelpers = require('@elliemae/ds-props-helpers');
|
|
12
|
+
|
|
13
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
14
|
+
|
|
15
|
+
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
|
|
16
|
+
|
|
17
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
18
|
+
|
|
19
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
20
|
+
const defaultProps = {
|
|
21
|
+
value: '',
|
|
22
|
+
onValueChange: () => null,
|
|
23
|
+
onClear: () => null,
|
|
24
|
+
placeholder: 'Hint Text',
|
|
25
|
+
disabled: false,
|
|
26
|
+
readOnly: false,
|
|
27
|
+
hasError: false,
|
|
28
|
+
innerRef: () => null,
|
|
29
|
+
inputSize: 'm',
|
|
30
|
+
clearable: false
|
|
31
|
+
};
|
|
32
|
+
const DSInputTextPropTypes = _objectSpread(_objectSpread(_objectSpread({}, dsPropsHelpers.globalAttributesPropTypes), dsPropsHelpers.xstyledPropTypes), {}, {
|
|
33
|
+
value: dsPropsHelpers.PropTypes.oneOfType([dsPropsHelpers.PropTypes.string, dsPropsHelpers.PropTypes.number, dsPropsHelpers.PropTypes.arrayOf(dsPropsHelpers.PropTypes.string)]).description('Value of the input').defaultValue(''),
|
|
34
|
+
onChange: dsPropsHelpers.PropTypes.func.description('onChange event handler').defaultValue(() => null),
|
|
35
|
+
placeholder: dsPropsHelpers.PropTypes.string.description('Value of the placeholder').defaultValue(''),
|
|
36
|
+
innerRef: dsPropsHelpers.PropTypes.oneOfType([dsPropsHelpers.PropTypes.object, dsPropsHelpers.PropTypes.func]).description('Reference to the input').defaultValue(null),
|
|
37
|
+
disabled: dsPropsHelpers.PropTypes.bool.description('Whether the input is disabled').defaultValue(false),
|
|
38
|
+
readOnly: dsPropsHelpers.PropTypes.bool.description('Whether the input is readonly').defaultValue(false),
|
|
39
|
+
hasError: dsPropsHelpers.PropTypes.bool.description('Whether the input has error').defaultValue(false),
|
|
40
|
+
inputSize: dsPropsHelpers.PropTypes.oneOf(['s', 'm']).description('Size of the input').defaultValue('m'),
|
|
41
|
+
clearable: dsPropsHelpers.PropTypes.bool.description('Whether the input is clearable').defaultValue(false)
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
exports.DSInputTextPropTypes = DSInputTextPropTypes;
|
|
45
|
+
exports.defaultProps = defaultProps;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _taggedTemplateLiteral = require('@babel/runtime/helpers/taggedTemplateLiteral');
|
|
6
|
+
var dsSystem = require('@elliemae/ds-system');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
|
+
|
|
10
|
+
var _taggedTemplateLiteral__default = /*#__PURE__*/_interopDefaultLegacy(_taggedTemplateLiteral);
|
|
11
|
+
|
|
12
|
+
var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5;
|
|
13
|
+
const commonBorderCss = dsSystem.css(_templateObject || (_templateObject = _taggedTemplateLiteral__default["default"](["\n border: 1px solid ", ";\n"])), dsSystem.th.color('neutral-400'));
|
|
14
|
+
const readOnlyBorderCss = dsSystem.css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral__default["default"](["\n border: 1px solid transparent;\n border-top-color: ", ";\n"])), dsSystem.th.color('neutral-400'));
|
|
15
|
+
const disabledBorderCss = commonBorderCss;
|
|
16
|
+
const hasErrorBorderCss = dsSystem.css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral__default["default"](["\n border: 1px solid ", ";\n"])), dsSystem.th.color('danger-900'));
|
|
17
|
+
const hoverBorderCss = dsSystem.css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral__default["default"](["\n border: 1px solid ", ";\n"])), dsSystem.th.color('brand-700'));
|
|
18
|
+
const focusBorderCss = dsSystem.css(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral__default["default"](["\n border: 1px solid transparent;\n outline: 2px solid ", ";\n outline-offset: -1px;\n"])), dsSystem.th.color('brand-700'));
|
|
19
|
+
const getBorderCss = props => {
|
|
20
|
+
if (props.isDisabled) return disabledBorderCss;
|
|
21
|
+
if (props.hasFocus) return focusBorderCss;
|
|
22
|
+
if (props.hasError) return hasErrorBorderCss;
|
|
23
|
+
if (props.isReadOnly) return readOnlyBorderCss;
|
|
24
|
+
return commonBorderCss;
|
|
25
|
+
};
|
|
26
|
+
const getHoverBorderCss = props => {
|
|
27
|
+
if (props.isDisabled) return disabledBorderCss;
|
|
28
|
+
if (props.hasFocus) return focusBorderCss;
|
|
29
|
+
return hoverBorderCss;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
exports.getBorderCss = getBorderCss;
|
|
33
|
+
exports.getHoverBorderCss = getHoverBorderCss;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _taggedTemplateLiteral = require('@babel/runtime/helpers/taggedTemplateLiteral');
|
|
6
|
+
var DSButton = require('@elliemae/ds-button');
|
|
7
|
+
var dsGrid = require('@elliemae/ds-grid');
|
|
8
|
+
var dsSystem = require('@elliemae/ds-system');
|
|
9
|
+
var styledComponents = require('@xstyled/styled-components');
|
|
10
|
+
var theming = require('../exported-related/theming.js');
|
|
11
|
+
var borders = require('./borders.js');
|
|
12
|
+
|
|
13
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
14
|
+
|
|
15
|
+
var _taggedTemplateLiteral__default = /*#__PURE__*/_interopDefaultLegacy(_taggedTemplateLiteral);
|
|
16
|
+
|
|
17
|
+
var _templateObject, _templateObject2, _templateObject3;
|
|
18
|
+
const StyledInputWrapper = dsSystem.styled(dsGrid.Grid, {
|
|
19
|
+
name: theming.DSInputTextName,
|
|
20
|
+
slot: theming.DSInputTextSlots.INPUT_WRAPPER
|
|
21
|
+
})(_templateObject || (_templateObject = _taggedTemplateLiteral__default["default"](["\n height: ", ";\n\n ", "\n border-radius: 2px;\n\n :hover {\n ", "\n }\n\n ", "\n ", "\n ", "\n"])), _ref => {
|
|
22
|
+
let {
|
|
23
|
+
inputSize
|
|
24
|
+
} = _ref;
|
|
25
|
+
return inputSize === 'm' ? '28px' : '24px';
|
|
26
|
+
}, borders.getBorderCss, borders.getHoverBorderCss, styledComponents.layout, styledComponents.space, styledComponents.sizing);
|
|
27
|
+
const StyledInput = dsSystem.styled('input', {
|
|
28
|
+
name: theming.DSInputTextName,
|
|
29
|
+
slot: theming.DSInputTextSlots.INPUT
|
|
30
|
+
})(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral__default["default"](["\n padding: 0 ", ";\n border: none;\n outline: none;\n border-radius: 2px;\n\n width: 100%;\n height: 100%;\n font-size: 13px;\n\n ::placeholder {\n font-weight: ", ";\n font-style: italic;\n color: ", ";\n }\n\n :disabled {\n background-color: ", ";\n color: #616b7f;\n cursor: not-allowed;\n }\n"])), dsSystem.th.space('xxs'), dsSystem.th.fontWeight('regular'), dsSystem.th.color('neutral-500'), dsSystem.th.color('neutral-080'));
|
|
31
|
+
const StyledClearButton = dsSystem.styled(DSButton.DSButtonV2, {
|
|
32
|
+
name: theming.DSInputTextName,
|
|
33
|
+
slot: theming.DSInputTextSlots.CLEAR_BUTTON
|
|
34
|
+
})(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral__default["default"](["\n height: 100%;\n min-width: 20px;\n width: 20px;\n &:after {\n border-top-left-radius: 0px !important;\n border-bottom-left-radius: 0px !important;\n }\n :focus {\n border-width: 0px;\n }\n"])));
|
|
35
|
+
|
|
36
|
+
exports.StyledClearButton = StyledClearButton;
|
|
37
|
+
exports.StyledInput = StyledInput;
|
|
38
|
+
exports.StyledInputWrapper = StyledInputWrapper;
|
package/cjs/index.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var Autocomplete = require('./controlled-autocomplete/Autocomplete.js');
|
|
5
6
|
var ControlledCheckbox = require('./controlled-checkbox/ControlledCheckbox.js');
|
|
7
|
+
var ComboBox = require('./controlled-combobox/ComboBox.js');
|
|
6
8
|
var ControlledDateRangePicker = require('./controlled-date-range-picker/ControlledDateRangePicker.js');
|
|
7
9
|
var ControlledDateRangePickerDatatestid = require('./controlled-date-range-picker/ControlledDateRangePickerDatatestid.js');
|
|
8
10
|
var ControlledDateRangePickerTypes = require('./controlled-date-range-picker/ControlledDateRangePickerTypes.js');
|
|
@@ -13,14 +15,20 @@ var stringHelpers = require('./controlled-date-time-picker/utils/stringHelpers.j
|
|
|
13
15
|
var dateTimeHelpers = require('./controlled-date-time-picker/utils/dateTimeHelpers.js');
|
|
14
16
|
var dateHelpers = require('./controlled-date-time-picker/utils/dateHelpers.js');
|
|
15
17
|
var timeHelpers = require('./controlled-date-time-picker/utils/timeHelpers.js');
|
|
18
|
+
var usePhoneMask = require('./controlled-mask-hook/hooks/usePhoneMask.js');
|
|
19
|
+
var DSInputText = require('./controlled-text-input/DSInputText.js');
|
|
20
|
+
var dataTestIds = require('./controlled-text-input/exported-related/data-test-ids.js');
|
|
21
|
+
var theming = require('./controlled-text-input/exported-related/theming.js');
|
|
16
22
|
var ControlledToggle = require('./controlled-toggle/ControlledToggle.js');
|
|
17
|
-
var Autocomplete = require('./controlled-autocomplete/Autocomplete.js');
|
|
18
|
-
var ComboBox = require('./controlled-combobox/ComboBox.js');
|
|
19
23
|
|
|
20
24
|
|
|
21
25
|
|
|
26
|
+
exports.DSAutocomplete = Autocomplete.DSAutocomplete;
|
|
27
|
+
exports.DSAutocompleteWithSchema = Autocomplete.DSAutocompleteWithSchema;
|
|
22
28
|
exports.DSControlledCheckbox = ControlledCheckbox.DSControlledCheckbox;
|
|
23
29
|
exports.DSControlledCheckboxWithSchema = ControlledCheckbox.DSControlledCheckboxWithSchema;
|
|
30
|
+
exports.DSComboBox = ComboBox.DSComboBox;
|
|
31
|
+
exports.DSComboBoxWithSchema = ComboBox.DSComboBoxWithSchema;
|
|
24
32
|
exports.DSControlledDateRangePicker = ControlledDateRangePicker.DSControlledDateRangePicker;
|
|
25
33
|
exports.DSControlledDateRangePickerWithSchema = ControlledDateRangePicker.DSControlledDateRangePickerWithSchema;
|
|
26
34
|
exports.ControlledDateRangePickerDatatestid = ControlledDateRangePickerDatatestid.ControlledDateRangePickerDatatestid;
|
|
@@ -37,9 +45,12 @@ exports.getDateValuesFromDate = dateHelpers.getDateValuesFromDate;
|
|
|
37
45
|
exports.getDayFromDateString = dateHelpers.getDayFromDateString;
|
|
38
46
|
exports.getValidationDateStringMetaInfo = dateHelpers.getValidationDateStringMetaInfo;
|
|
39
47
|
exports.getValidationTimeStringMetaInfo = timeHelpers.getValidationTimeStringMetaInfo;
|
|
48
|
+
exports.UsePhoneMaskWithSchema = usePhoneMask.UsePhoneMaskWithSchema;
|
|
49
|
+
exports.usePhoneMask = usePhoneMask.usePhoneMask;
|
|
50
|
+
exports.DSInputText = DSInputText.DSInputText;
|
|
51
|
+
exports.DSInputTextWithSchema = DSInputText.DSInputTextWithSchema;
|
|
52
|
+
exports.DSInputTextDataTestIds = dataTestIds.DSInputTextDataTestIds;
|
|
53
|
+
exports.DSInputTextName = theming.DSInputTextName;
|
|
54
|
+
exports.DSInputTextSlots = theming.DSInputTextSlots;
|
|
40
55
|
exports.DSControlledToggle = ControlledToggle.DSControlledToggle;
|
|
41
56
|
exports.DSControlledToggleWithSchema = ControlledToggle.DSControlledToggleWithSchema;
|
|
42
|
-
exports.DSAutocomplete = Autocomplete.DSAutocomplete;
|
|
43
|
-
exports.DSAutocompleteWithSchema = Autocomplete.DSAutocompleteWithSchema;
|
|
44
|
-
exports.DSComboBox = ComboBox.DSComboBox;
|
|
45
|
-
exports.DSComboBoxWithSchema = ComboBox.DSComboBoxWithSchema;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { UsePhoneMaskWithSchema, usePhoneMask } from './usePhoneMask.js';
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import 'core-js/modules/esnext.async-iterator.filter.js';
|
|
2
|
+
import 'core-js/modules/esnext.iterator.constructor.js';
|
|
3
|
+
import 'core-js/modules/esnext.iterator.filter.js';
|
|
4
|
+
import 'core-js/modules/web.dom-collections.iterator.js';
|
|
5
|
+
import { useRef, useState, useCallback } from 'react';
|
|
6
|
+
import { describe, useMemoMergePropsWithDefault, useValidateTypescriptPropTypes } from '@elliemae/ds-props-helpers';
|
|
7
|
+
import { useCallbackAfterRender } from '@elliemae/ds-utilities';
|
|
8
|
+
import { addSpecialCharacters } from '../utils/addSpecialCharacters.js';
|
|
9
|
+
import { getPartialMaskedPos } from '../utils/getPartialMaskedPos.js';
|
|
10
|
+
import { setCursorPosition } from '../utils/setCursorPosition.js';
|
|
11
|
+
import { DSMaskHookPropsTypes, DSMaskHookDefaultProps } from '../react-desc-prop-types.js';
|
|
12
|
+
|
|
13
|
+
const phoneSpecialChars = [['(', 0], [') ', 4], ['-', 9]];
|
|
14
|
+
|
|
15
|
+
const conformValue = (rawValue, cursorPos, lastKeyCode) => {
|
|
16
|
+
// Work with digits only
|
|
17
|
+
let maskedValue = rawValue.split('').filter(char => char >= '0' && char <= '9'); // We can't have zeros at the start of the array
|
|
18
|
+
|
|
19
|
+
while (maskedValue.length && maskedValue[0] === '0') maskedValue.splice(0, 1); // We only consider first 10 digits
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
maskedValue = maskedValue.slice(0, 10);
|
|
23
|
+
const maskedPos = getPartialMaskedPos(rawValue, maskedValue, cursorPos);
|
|
24
|
+
return addSpecialCharacters(maskedValue, phoneSpecialChars, maskedPos, lastKeyCode);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const usePhoneMask = props => {
|
|
28
|
+
const propsWithDefault = useMemoMergePropsWithDefault(props, DSMaskHookDefaultProps);
|
|
29
|
+
useValidateTypescriptPropTypes(propsWithDefault, DSMaskHookPropsTypes);
|
|
30
|
+
const {
|
|
31
|
+
valueSetter,
|
|
32
|
+
onChange: userOnChange,
|
|
33
|
+
onKeyDown: userOnKeyDown
|
|
34
|
+
} = propsWithDefault;
|
|
35
|
+
const lastKeyCode = useRef('Unidentified');
|
|
36
|
+
const scheduleAfterRender = useCallbackAfterRender(); // Some times, the value of the mask is not gonna change (user types invalid char for example)
|
|
37
|
+
// This makes the input to go from "correct" -> "incorrect" -> "correct"
|
|
38
|
+
// But since the input is controlled, the input does not re-render
|
|
39
|
+
// This makes the input go mumbo-jumbo and places the cursor in the end, because we kinda changed the value async
|
|
40
|
+
// Solution for this is to trigger a re-render, we do this with a set state call in the on change event
|
|
41
|
+
|
|
42
|
+
const [, setKey] = useState(0);
|
|
43
|
+
const onKeyDown = useCallback(e => {
|
|
44
|
+
lastKeyCode.current = e.code;
|
|
45
|
+
if (userOnKeyDown) userOnKeyDown(e);
|
|
46
|
+
}, [userOnKeyDown]);
|
|
47
|
+
const onChange = useCallback(e => {
|
|
48
|
+
var _e$target$selectionEn;
|
|
49
|
+
|
|
50
|
+
const [mask, cursorPos] = conformValue(e.target.value, (_e$target$selectionEn = e.target.selectionEnd) !== null && _e$target$selectionEn !== void 0 ? _e$target$selectionEn : 0, lastKeyCode.current);
|
|
51
|
+
valueSetter(prevMask => {
|
|
52
|
+
// Here we need to update the key
|
|
53
|
+
if (mask === prevMask) setKey(key => key + 1);
|
|
54
|
+
return mask;
|
|
55
|
+
});
|
|
56
|
+
if (userOnChange) userOnChange(e, mask);
|
|
57
|
+
scheduleAfterRender(() => setCursorPosition(e.target, cursorPos));
|
|
58
|
+
}, [valueSetter, scheduleAfterRender, userOnChange]);
|
|
59
|
+
return {
|
|
60
|
+
onKeyDown,
|
|
61
|
+
onChange
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
const UsePhoneMaskWithSchema = describe(usePhoneMask);
|
|
65
|
+
UsePhoneMaskWithSchema.propTypes = DSMaskHookPropsTypes;
|
|
66
|
+
|
|
67
|
+
export { UsePhoneMaskWithSchema, usePhoneMask };
|