@dnb/eufemia
Version:
DNB Eufemia Design System UI Library
194 lines (193 loc) • 5.87 kB
JavaScript
"use client";
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
import _pushInstanceProperty from "core-js-pure/stable/instance/push.js";
import React, { useRef } from 'react';
import Input from "../Input.js";
import TextMask from "./TextMask.js";
import useHandleCursorPosition from "./hooks/useHandleCursorPosition.js";
import classnames from 'classnames';
import FormLabel from "../FormLabel.js";
import { createSpacingClasses } from "../space/SpacingHelper.js";
import { useMultiInputValue } from "./hooks/useMultiInputValues.js";
import useId from "../../shared/helpers/useId.js";
function MultiInputMask({
id,
label,
labelDirection = 'horizontal',
inputs,
delimiter,
onChange: onChangeExternal,
disabled,
status,
statusState,
values: defaultValues,
className,
stretch,
inputMode,
suffix,
onBlur,
onFocus,
...props
}) {
var _inputs$;
id = useId(id);
const [values, onChange] = useMultiInputValue({
inputs,
defaultValues,
callback: onChangeExternal
});
const inputRefs = useRef([]);
const areInputsInFocus = useRef(false);
const {
onKeyDown
} = useHandleCursorPosition(inputRefs.current, getKeysToHandle());
const WrapperElement = label ? 'fieldset' : 'div';
return React.createElement(WrapperElement, {
className: classnames('dnb-multi-input-mask__fieldset', createSpacingClasses(props), labelDirection === 'horizontal' && 'dnb-multi-input-mask__fieldset--horizontal')
}, React.createElement(Input, _extends({}, props, {
id: id,
label: label && React.createElement(FormLabel, {
element: "legend",
forId: `${id}-${(_inputs$ = inputs[0]) === null || _inputs$ === void 0 ? void 0 : _inputs$.id}`,
disabled: disabled,
labelDirection: labelDirection,
onClick: onLegendClick
}, label),
className: classnames('dnb-multi-input-mask', className),
label_direction: labelDirection,
disabled: disabled,
status: status,
status_state: statusState,
suffix: suffix,
stretch: stretch,
input_element: inputs.map(({
id: inputId,
...rest
}, index) => {
return React.createElement(MultiInputMaskInput, _extends({
key: inputId,
id: id,
inputId: inputId,
delimiter: index !== inputs.length - 1 ? delimiter : undefined,
disabled: disabled,
inputMode: inputMode,
onKeyDown: onKeyDown,
onChange: onChange,
onFocus: () => {
if (!areInputsInFocus.current) {
onFocus === null || onFocus === void 0 || onFocus(values);
}
areInputsInFocus.current = true;
},
onBlur: e => {
var _e$relatedTarget;
if (!((_e$relatedTarget = e.relatedTarget) !== null && _e$relatedTarget !== void 0 && (_e$relatedTarget = _e$relatedTarget.id) !== null && _e$relatedTarget !== void 0 && _e$relatedTarget.includes(id))) {
onBlur === null || onBlur === void 0 || onBlur(values);
areInputsInFocus.current = false;
}
},
getInputRef: getInputRef
}, rest, {
value: values[inputId]
}));
})
})));
function onLegendClick() {
if (disabled) {
return;
}
const firstInput = inputRefs.current[0].current;
firstInput.focus();
firstInput.setSelectionRange(0, 0);
}
function getInputRef(ref) {
const inputRef = ref === null || ref === void 0 ? void 0 : ref.inputRef;
if (inputRef && !inputRefs.current.includes(inputRef)) {
var _context;
_pushInstanceProperty(_context = inputRefs.current).call(_context, inputRef);
}
return inputRef;
}
function getKeysToHandle() {
const uniqueMasks = getUniqueMasks();
if (uniqueMasks.size === 1) {
const pattern = uniqueMasks.values().next().value.replace(/\//g, '');
return new RegExp(pattern);
}
return inputs.reduce((keys, {
id,
mask
}) => {
keys[id] = mask;
return keys;
}, {});
}
function getUniqueMasks() {
const masks = new Set();
inputs.forEach(input => {
input.mask.forEach(pattern => masks.add(String(pattern)));
});
return masks;
}
}
function MultiInputMaskInput({
id,
inputId,
label,
value,
mask,
placeholderCharacter,
delimiter,
disabled,
getInputRef,
onKeyDown,
onChange,
onBlur,
onFocus,
...attributes
}) {
const shouldHighlight = !disabled && /\w+/.test(value);
return React.createElement(React.Fragment, null, React.createElement(TextMask, _extends({
id: `${id}-${inputId}`,
"data-mask-id": inputId,
className: "dnb-input__input dnb-multi-input-mask__input" + (shouldHighlight ? " dnb-multi-input-mask__input--highlight" : ""),
disabled: disabled,
size: mask.length,
mask: mask,
value: value !== null && value !== void 0 ? value : '',
placeholderChar: placeholderCharacter,
guide: true,
showMask: true,
keepCharPositions: false,
"aria-label": label,
ref: getInputRef,
onKeyDown: onKeyDown,
onBlur: onBlur,
onFocus: ({
target,
...event
}) => {
target.focus();
target.select();
if (onFocus) {
onFocus({
target,
...event
});
}
},
onChange: event => {
onChange(inputId, removePlaceholder(event.target.value, placeholderCharacter));
}
}, attributes)), delimiter && React.createElement("span", {
"aria-hidden": true,
className: 'dnb-multi-input-mask__delimiter' + (shouldHighlight ? " dnb-multi-input-mask__delimiter--highlight" : "")
}, delimiter));
}
function removePlaceholder(value, placeholder) {
return value.replace(RegExp(placeholder, 'gm'), '');
}
export default MultiInputMask;
MultiInputMask._formElement = true;
MultiInputMask._supportsSpacingProps = true;
//# sourceMappingURL=MultiInputMask.js.map