@moda/om 21.8.0 → 21.9.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/index.cjs.js +268 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +268 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/src/components/OtpInput/OtpInput.d.ts +14 -0
- package/dist/src/components/OtpInput/OtpInput.stories.d.ts +7 -0
- package/dist/src/components/OtpInput/OtpInput.test.d.ts +1 -0
- package/dist/src/components/OtpInput/index.d.ts +1 -0
- package/dist/src/components/index.d.ts +1 -0
- package/dist/styles.css +1 -1
- package/package.json +4 -3
- package/src/components/OtpInput/OtpInput.scss +24 -0
- package/src/components/OtpInput/OtpInput.stories.tsx +26 -0
- package/src/components/OtpInput/OtpInput.test.tsx +45 -0
- package/src/components/OtpInput/OtpInput.tsx +95 -0
- package/src/components/OtpInput/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/global.d.ts +9 -0
package/dist/index.cjs.js
CHANGED
|
@@ -12338,6 +12338,273 @@ var Paginator = function Paginator(_ref) {
|
|
|
12338
12338
|
})));
|
|
12339
12339
|
};
|
|
12340
12340
|
|
|
12341
|
+
var isStyleObject = function isStyleObject(obj) {
|
|
12342
|
+
return _typeof$1(obj) === 'object' && obj !== null;
|
|
12343
|
+
};
|
|
12344
|
+
var OTPInput = function OTPInput(_a) {
|
|
12345
|
+
var _b = _a.value,
|
|
12346
|
+
value = _b === void 0 ? '' : _b,
|
|
12347
|
+
_c = _a.numInputs,
|
|
12348
|
+
numInputs = _c === void 0 ? 4 : _c,
|
|
12349
|
+
onChange = _a.onChange,
|
|
12350
|
+
onPaste = _a.onPaste,
|
|
12351
|
+
renderInput = _a.renderInput,
|
|
12352
|
+
_d = _a.shouldAutoFocus,
|
|
12353
|
+
shouldAutoFocus = _d === void 0 ? false : _d,
|
|
12354
|
+
_e = _a.inputType,
|
|
12355
|
+
inputType = _e === void 0 ? 'text' : _e,
|
|
12356
|
+
renderSeparator = _a.renderSeparator,
|
|
12357
|
+
placeholder = _a.placeholder,
|
|
12358
|
+
containerStyle = _a.containerStyle,
|
|
12359
|
+
inputStyle = _a.inputStyle,
|
|
12360
|
+
_f = _a.skipDefaultStyles,
|
|
12361
|
+
skipDefaultStyles = _f === void 0 ? false : _f;
|
|
12362
|
+
var _g = React.useState(0),
|
|
12363
|
+
activeInput = _g[0],
|
|
12364
|
+
setActiveInput = _g[1];
|
|
12365
|
+
var inputRefs = React.useRef([]);
|
|
12366
|
+
var getOTPValue = function getOTPValue() {
|
|
12367
|
+
return value ? value.toString().split('') : [];
|
|
12368
|
+
};
|
|
12369
|
+
var isInputNum = inputType === 'number' || inputType === 'tel';
|
|
12370
|
+
React.useEffect(function () {
|
|
12371
|
+
inputRefs.current = inputRefs.current.slice(0, numInputs);
|
|
12372
|
+
}, [numInputs]);
|
|
12373
|
+
React.useEffect(function () {
|
|
12374
|
+
var _a;
|
|
12375
|
+
if (shouldAutoFocus) {
|
|
12376
|
+
(_a = inputRefs.current[0]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
12377
|
+
}
|
|
12378
|
+
}, [shouldAutoFocus]);
|
|
12379
|
+
var getPlaceholderValue = function getPlaceholderValue() {
|
|
12380
|
+
if (typeof placeholder === 'string') {
|
|
12381
|
+
if (placeholder.length === numInputs) {
|
|
12382
|
+
return placeholder;
|
|
12383
|
+
}
|
|
12384
|
+
if (placeholder.length > 0) {
|
|
12385
|
+
console.error('Length of the placeholder should be equal to the number of inputs.');
|
|
12386
|
+
}
|
|
12387
|
+
}
|
|
12388
|
+
return undefined;
|
|
12389
|
+
};
|
|
12390
|
+
var isInputValueValid = function isInputValueValid(value) {
|
|
12391
|
+
var isTypeValid = isInputNum ? !isNaN(Number(value)) : typeof value === 'string';
|
|
12392
|
+
return isTypeValid && value.trim().length === 1;
|
|
12393
|
+
};
|
|
12394
|
+
var handleChange = function handleChange(event) {
|
|
12395
|
+
var value = event.target.value;
|
|
12396
|
+
if (isInputValueValid(value)) {
|
|
12397
|
+
changeCodeAtFocus(value);
|
|
12398
|
+
focusInput(activeInput + 1);
|
|
12399
|
+
}
|
|
12400
|
+
};
|
|
12401
|
+
var handleInputChange = function handleInputChange(event) {
|
|
12402
|
+
var nativeEvent = event.nativeEvent;
|
|
12403
|
+
var value = event.target.value;
|
|
12404
|
+
if (!isInputValueValid(value)) {
|
|
12405
|
+
// Pasting from the native autofill suggestion on a mobile device can pass
|
|
12406
|
+
// the pasted string as one long input to one of the cells. This ensures
|
|
12407
|
+
// that we handle the full input and not just the first character.
|
|
12408
|
+
if (value.length === numInputs) {
|
|
12409
|
+
var hasInvalidInput = value.split('').some(function (cellInput) {
|
|
12410
|
+
return !isInputValueValid(cellInput);
|
|
12411
|
+
});
|
|
12412
|
+
if (!hasInvalidInput) {
|
|
12413
|
+
handleOTPChange(value.split(''));
|
|
12414
|
+
focusInput(numInputs - 1);
|
|
12415
|
+
}
|
|
12416
|
+
}
|
|
12417
|
+
// @ts-expect-error - This was added previously to handle and edge case
|
|
12418
|
+
// for dealing with keyCode "229 Unidentified" on Android. Check if this is
|
|
12419
|
+
// still needed.
|
|
12420
|
+
if (nativeEvent.data === null && nativeEvent.inputType === 'deleteContentBackward') {
|
|
12421
|
+
event.preventDefault();
|
|
12422
|
+
changeCodeAtFocus('');
|
|
12423
|
+
focusInput(activeInput - 1);
|
|
12424
|
+
}
|
|
12425
|
+
// Clear the input if it's not valid value because firefox allows
|
|
12426
|
+
// pasting non-numeric characters in a number type input
|
|
12427
|
+
event.target.value = '';
|
|
12428
|
+
}
|
|
12429
|
+
};
|
|
12430
|
+
var handleFocus = function handleFocus(event) {
|
|
12431
|
+
return function (index) {
|
|
12432
|
+
setActiveInput(index);
|
|
12433
|
+
event.target.select();
|
|
12434
|
+
};
|
|
12435
|
+
};
|
|
12436
|
+
var handleBlur = function handleBlur() {
|
|
12437
|
+
setActiveInput(activeInput - 1);
|
|
12438
|
+
};
|
|
12439
|
+
var handleKeyDown = function handleKeyDown(event) {
|
|
12440
|
+
var otp = getOTPValue();
|
|
12441
|
+
if ([event.code, event.key].includes('Backspace')) {
|
|
12442
|
+
event.preventDefault();
|
|
12443
|
+
changeCodeAtFocus('');
|
|
12444
|
+
focusInput(activeInput - 1);
|
|
12445
|
+
} else if (event.code === 'Delete') {
|
|
12446
|
+
event.preventDefault();
|
|
12447
|
+
changeCodeAtFocus('');
|
|
12448
|
+
} else if (event.code === 'ArrowLeft') {
|
|
12449
|
+
event.preventDefault();
|
|
12450
|
+
focusInput(activeInput - 1);
|
|
12451
|
+
} else if (event.code === 'ArrowRight') {
|
|
12452
|
+
event.preventDefault();
|
|
12453
|
+
focusInput(activeInput + 1);
|
|
12454
|
+
}
|
|
12455
|
+
// React does not trigger onChange when the same value is entered
|
|
12456
|
+
// again. So we need to focus the next input manually in this case.
|
|
12457
|
+
else if (event.key === otp[activeInput]) {
|
|
12458
|
+
event.preventDefault();
|
|
12459
|
+
focusInput(activeInput + 1);
|
|
12460
|
+
} else if (event.code === 'Spacebar' || event.code === 'Space' || event.code === 'ArrowUp' || event.code === 'ArrowDown') {
|
|
12461
|
+
event.preventDefault();
|
|
12462
|
+
}
|
|
12463
|
+
};
|
|
12464
|
+
var focusInput = function focusInput(index) {
|
|
12465
|
+
var _a, _b;
|
|
12466
|
+
var activeInput = Math.max(Math.min(numInputs - 1, index), 0);
|
|
12467
|
+
if (inputRefs.current[activeInput]) {
|
|
12468
|
+
(_a = inputRefs.current[activeInput]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
12469
|
+
(_b = inputRefs.current[activeInput]) === null || _b === void 0 ? void 0 : _b.select();
|
|
12470
|
+
setActiveInput(activeInput);
|
|
12471
|
+
}
|
|
12472
|
+
};
|
|
12473
|
+
var changeCodeAtFocus = function changeCodeAtFocus(value) {
|
|
12474
|
+
var otp = getOTPValue();
|
|
12475
|
+
otp[activeInput] = value[0];
|
|
12476
|
+
handleOTPChange(otp);
|
|
12477
|
+
};
|
|
12478
|
+
var handleOTPChange = function handleOTPChange(otp) {
|
|
12479
|
+
var otpValue = otp.join('');
|
|
12480
|
+
onChange(otpValue);
|
|
12481
|
+
};
|
|
12482
|
+
var handlePaste = function handlePaste(event) {
|
|
12483
|
+
var _a;
|
|
12484
|
+
event.preventDefault();
|
|
12485
|
+
var otp = getOTPValue();
|
|
12486
|
+
var nextActiveInput = activeInput;
|
|
12487
|
+
// Get pastedData in an array of max size (num of inputs - current position)
|
|
12488
|
+
var pastedData = event.clipboardData.getData('text/plain').slice(0, numInputs - activeInput).split('');
|
|
12489
|
+
// Prevent pasting if the clipboard data contains non-numeric values for number inputs
|
|
12490
|
+
if (isInputNum && pastedData.some(function (value) {
|
|
12491
|
+
return isNaN(Number(value));
|
|
12492
|
+
})) {
|
|
12493
|
+
return;
|
|
12494
|
+
}
|
|
12495
|
+
// Paste data from focused input onwards
|
|
12496
|
+
for (var pos = 0; pos < numInputs; ++pos) {
|
|
12497
|
+
if (pos >= activeInput && pastedData.length > 0) {
|
|
12498
|
+
otp[pos] = (_a = pastedData.shift()) !== null && _a !== void 0 ? _a : '';
|
|
12499
|
+
nextActiveInput++;
|
|
12500
|
+
}
|
|
12501
|
+
}
|
|
12502
|
+
focusInput(nextActiveInput);
|
|
12503
|
+
handleOTPChange(otp);
|
|
12504
|
+
};
|
|
12505
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
12506
|
+
style: Object.assign({
|
|
12507
|
+
display: 'flex',
|
|
12508
|
+
alignItems: 'center'
|
|
12509
|
+
}, isStyleObject(containerStyle) && containerStyle),
|
|
12510
|
+
className: typeof containerStyle === 'string' ? containerStyle : undefined,
|
|
12511
|
+
onPaste: onPaste
|
|
12512
|
+
}, Array.from({
|
|
12513
|
+
length: numInputs
|
|
12514
|
+
}, function (_, index) {
|
|
12515
|
+
return index;
|
|
12516
|
+
}).map(function (index) {
|
|
12517
|
+
var _a, _b, _c;
|
|
12518
|
+
return /*#__PURE__*/React.createElement(React.Fragment, {
|
|
12519
|
+
key: index
|
|
12520
|
+
}, renderInput({
|
|
12521
|
+
value: (_a = getOTPValue()[index]) !== null && _a !== void 0 ? _a : '',
|
|
12522
|
+
placeholder: (_c = (_b = getPlaceholderValue()) === null || _b === void 0 ? void 0 : _b[index]) !== null && _c !== void 0 ? _c : undefined,
|
|
12523
|
+
ref: function ref(element) {
|
|
12524
|
+
return inputRefs.current[index] = element;
|
|
12525
|
+
},
|
|
12526
|
+
onChange: handleChange,
|
|
12527
|
+
onFocus: function onFocus(event) {
|
|
12528
|
+
return handleFocus(event)(index);
|
|
12529
|
+
},
|
|
12530
|
+
onBlur: handleBlur,
|
|
12531
|
+
onKeyDown: handleKeyDown,
|
|
12532
|
+
onPaste: handlePaste,
|
|
12533
|
+
autoComplete: 'off',
|
|
12534
|
+
'aria-label': "Please enter OTP character ".concat(index + 1),
|
|
12535
|
+
style: Object.assign(!skipDefaultStyles ? {
|
|
12536
|
+
width: '1em',
|
|
12537
|
+
textAlign: 'center'
|
|
12538
|
+
} : {}, isStyleObject(inputStyle) ? inputStyle : {}),
|
|
12539
|
+
className: typeof inputStyle === 'string' ? inputStyle : undefined,
|
|
12540
|
+
type: inputType,
|
|
12541
|
+
inputMode: isInputNum ? 'numeric' : 'text',
|
|
12542
|
+
onInput: handleInputChange
|
|
12543
|
+
}, index), index < numInputs - 1 && (typeof renderSeparator === 'function' ? renderSeparator(index) : renderSeparator));
|
|
12544
|
+
}));
|
|
12545
|
+
};
|
|
12546
|
+
|
|
12547
|
+
var getInputAriaLabel = function getInputAriaLabel(index, inputCount, ariaLabel, label) {
|
|
12548
|
+
var baseLabel = ariaLabel || label || 'One-time password digit';
|
|
12549
|
+
return "".concat(baseLabel, " ").concat(index + 1, " of ").concat(inputCount);
|
|
12550
|
+
};
|
|
12551
|
+
var OtpInput = function OtpInput(_ref) {
|
|
12552
|
+
var ariaDescribedBy = _ref['aria-describedby'],
|
|
12553
|
+
ariaLabel = _ref['aria-label'],
|
|
12554
|
+
_ref$autoComplete = _ref.autoComplete,
|
|
12555
|
+
autoComplete = _ref$autoComplete === void 0 ? 'one-time-code' : _ref$autoComplete,
|
|
12556
|
+
className = _ref.className,
|
|
12557
|
+
disabled = _ref.disabled,
|
|
12558
|
+
error = _ref.error,
|
|
12559
|
+
focus = _ref.focus,
|
|
12560
|
+
id = _ref.id,
|
|
12561
|
+
inputClassName = _ref.inputClassName,
|
|
12562
|
+
_ref$inputType = _ref.inputType,
|
|
12563
|
+
inputType = _ref$inputType === void 0 ? 'tel' : _ref$inputType,
|
|
12564
|
+
label = _ref.label,
|
|
12565
|
+
name = _ref.name,
|
|
12566
|
+
_ref$numInputs = _ref.numInputs,
|
|
12567
|
+
numInputs = _ref$numInputs === void 0 ? 4 : _ref$numInputs,
|
|
12568
|
+
onChange = _ref.onChange,
|
|
12569
|
+
onPaste = _ref.onPaste,
|
|
12570
|
+
placeholder = _ref.placeholder,
|
|
12571
|
+
renderSeparator = _ref.renderSeparator,
|
|
12572
|
+
required = _ref.required,
|
|
12573
|
+
shouldAutoFocus = _ref.shouldAutoFocus,
|
|
12574
|
+
_ref$value = _ref.value,
|
|
12575
|
+
value = _ref$value === void 0 ? '' : _ref$value;
|
|
12576
|
+
return /*#__PURE__*/React.createElement(OTPInput, {
|
|
12577
|
+
containerStyle: classNames('OtpInput', className),
|
|
12578
|
+
inputType: inputType,
|
|
12579
|
+
numInputs: numInputs,
|
|
12580
|
+
onChange: onChange,
|
|
12581
|
+
onPaste: onPaste,
|
|
12582
|
+
placeholder: placeholder,
|
|
12583
|
+
renderSeparator: renderSeparator,
|
|
12584
|
+
shouldAutoFocus: shouldAutoFocus,
|
|
12585
|
+
skipDefaultStyles: true,
|
|
12586
|
+
value: value,
|
|
12587
|
+
renderInput: function renderInput(inputProps, index) {
|
|
12588
|
+
return /*#__PURE__*/React.createElement("input", _extends$1({}, inputProps, {
|
|
12589
|
+
id: id ? "".concat(id, "-").concat(index + 1) : undefined,
|
|
12590
|
+
autoComplete: autoComplete,
|
|
12591
|
+
"aria-describedby": ariaDescribedBy,
|
|
12592
|
+
"aria-invalid": error ? true : undefined,
|
|
12593
|
+
"aria-label": getInputAriaLabel(index, numInputs, ariaLabel, label),
|
|
12594
|
+
className: classNames(inputProps.className, 'OtpInput__input', inputClassName, {
|
|
12595
|
+
'OtpInput__input--disabled': disabled,
|
|
12596
|
+
'OtpInput__input--error': error,
|
|
12597
|
+
'OtpInput__input--focus': focus
|
|
12598
|
+
}),
|
|
12599
|
+
disabled: disabled,
|
|
12600
|
+
name: name,
|
|
12601
|
+
required: required
|
|
12602
|
+
}));
|
|
12603
|
+
}
|
|
12604
|
+
});
|
|
12605
|
+
};
|
|
12606
|
+
OtpInput.displayName = 'OtpInput';
|
|
12607
|
+
|
|
12341
12608
|
var PasswordInput = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
12342
12609
|
var rest = _extends$1({}, (_objectDestructuringEmpty(_ref), _ref));
|
|
12343
12610
|
var _useState = React.useState(false),
|
|
@@ -12891,6 +13158,7 @@ exports.Modal = Modal;
|
|
|
12891
13158
|
exports.ModalOverlay = ModalOverlay;
|
|
12892
13159
|
exports.MultiSelect = MultiSelect;
|
|
12893
13160
|
exports.NoLineDivider = NoLineDivider;
|
|
13161
|
+
exports.OtpInput = OtpInput;
|
|
12894
13162
|
exports.Oval = Oval;
|
|
12895
13163
|
exports.Overlay = Overlay;
|
|
12896
13164
|
exports.POPOVER_MOUSEOUT_DELAY_MS = POPOVER_MOUSEOUT_DELAY_MS;
|