@dynamic-framework/ui-react 1.19.1 → 1.20.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.js CHANGED
@@ -479,7 +479,7 @@ function DDatePickerTime(_a) {
479
479
  }
480
480
 
481
481
  function DDatePickerInput(_a, ref) {
482
- var { value, onClick, id, iconEnd, className, style, inputLabel } = _a, props = tslib.__rest(_a, ["value", "onClick", "id", "iconEnd", "className", "style", "inputLabel"]);
482
+ var { value, onClick, id, iconEnd, className, style, inputLabel, readOnly: ignored } = _a, props = tslib.__rest(_a, ["value", "onClick", "id", "iconEnd", "className", "style", "inputLabel", "readOnly"]);
483
483
  return (jsxRuntime.jsx(DInput$1, Object.assign({ ref: ref, onClick: onClick, readOnly: true, type: "text", id: id, value: value, onIconEndClick: onClick, iconEnd: iconEnd, className: className, style: style, label: inputLabel }, props)));
484
484
  }
485
485
  const ForwardedDDatePickerInput = React.forwardRef(DDatePickerInput);
@@ -631,7 +631,7 @@ function DDatePickerHeader({ date, changeYear, changeMonth, decreaseMonth, incre
631
631
  }
632
632
 
633
633
  function DDatePicker(_a) {
634
- var { date, selectsRange = false, inputLabel, inputAriaLabel, inputActionAriaLabel = 'open calendar', inputId = 'input-calendar', timeId = 'input-time', timeLabel, iconInput: iconInputProp, iconHeaderPrevMonth: iconHeaderPrevMonthProp, iconHeaderNextMonth: iconHeaderNextMonthProp, iconMaterialStyle: iconMaterialStyleProp, iconFamilyClass, iconFamilyPrefix, minYearSelect = 1900, maxYearSelect = 2100, iconHeaderSize = 'sm', headerPrevMonthAriaLabel = 'decrease month', headerNextMonthAriaLabel = 'increase month', headerButtonVariant = 'link', headerButtonTheme = 'dark', locale, className, formatWeekDay: formatWeekDayProp, style } = _a, props = tslib.__rest(_a, ["date", "selectsRange", "inputLabel", "inputAriaLabel", "inputActionAriaLabel", "inputId", "timeId", "timeLabel", "iconInput", "iconHeaderPrevMonth", "iconHeaderNextMonth", "iconMaterialStyle", "iconFamilyClass", "iconFamilyPrefix", "minYearSelect", "maxYearSelect", "iconHeaderSize", "headerPrevMonthAriaLabel", "headerNextMonthAriaLabel", "headerButtonVariant", "headerButtonTheme", "locale", "className", "formatWeekDay", "style"]);
634
+ var { date, selectsRange = false, inputLabel, inputHint, inputAriaLabel, inputActionAriaLabel = 'open calendar', inputId = 'input-calendar', timeId = 'input-time', timeLabel, iconInput: iconInputProp, iconHeaderPrevMonth: iconHeaderPrevMonthProp, iconHeaderNextMonth: iconHeaderNextMonthProp, iconMaterialStyle: iconMaterialStyleProp, iconFamilyClass, iconFamilyPrefix, minYearSelect = 1900, maxYearSelect = 2100, iconHeaderSize = 'sm', headerPrevMonthAriaLabel = 'decrease month', headerNextMonthAriaLabel = 'increase month', headerButtonVariant = 'link', headerButtonTheme = 'dark', invalid = false, valid = false, locale, className, formatWeekDay: formatWeekDayProp, style } = _a, props = tslib.__rest(_a, ["date", "selectsRange", "inputLabel", "inputHint", "inputAriaLabel", "inputActionAriaLabel", "inputId", "timeId", "timeLabel", "iconInput", "iconHeaderPrevMonth", "iconHeaderNextMonth", "iconMaterialStyle", "iconFamilyClass", "iconFamilyPrefix", "minYearSelect", "maxYearSelect", "iconHeaderSize", "headerPrevMonthAriaLabel", "headerNextMonthAriaLabel", "headerButtonVariant", "headerButtonTheme", "invalid", "valid", "locale", "className", "formatWeekDay", "style"]);
635
635
  const { iconMap: { calendar, chevronLeft, chevronRight, }, } = useDContext();
636
636
  const selected = React.useMemo(() => (date ? dateFns.parseISO(date) : null), [date]);
637
637
  const iconInput = React.useMemo(() => iconInputProp || calendar, [calendar, iconInputProp]);
@@ -653,7 +653,7 @@ function DDatePicker(_a) {
653
653
  minYearSelect,
654
654
  maxYearSelect,
655
655
  ]);
656
- return (jsxRuntime.jsx(DatePicker, Object.assign({ selected: selected, calendarClassName: "d-date-picker", renderCustomHeader: (headerProps) => jsxRuntime.jsx(DatePickerHeader, Object.assign({}, headerProps)), selectsRange: selectsRange, formatWeekDay: handleFormatWeekDay, customInput: (jsxRuntime.jsx(DDatePickerInput$1, { id: inputId, "aria-label": inputAriaLabel, iconEndAriaLabel: inputActionAriaLabel, iconMaterialStyle: iconMaterialStyleProp, iconEnd: iconInput, inputLabel: inputLabel, className: className, style: style })), customTimeInput: (jsxRuntime.jsx(DDatePickerTime, { id: timeId, label: timeLabel })) }, locale && { locale }, props)));
656
+ return (jsxRuntime.jsx(DatePicker, Object.assign({ selected: selected, calendarClassName: "d-date-picker", renderCustomHeader: (headerProps) => jsxRuntime.jsx(DatePickerHeader, Object.assign({}, headerProps)), selectsRange: selectsRange, formatWeekDay: handleFormatWeekDay, customInput: (jsxRuntime.jsx(DDatePickerInput$1, { id: inputId, "aria-label": inputAriaLabel, iconEndAriaLabel: inputActionAriaLabel, iconMaterialStyle: iconMaterialStyleProp, iconEnd: iconInput, inputLabel: inputLabel, className: className, style: style, invalid: invalid, valid: valid, hint: inputHint })), customTimeInput: (jsxRuntime.jsx(DDatePickerTime, { id: timeId, label: timeLabel })) }, locale && { locale }, props)));
657
657
  }
658
658
 
659
659
  function DInputMask(props, ref) {
@@ -824,17 +824,37 @@ var DInputPassword$1 = ForwardedDInputPassword;
824
824
 
825
825
  function DInputPin({ id, label = '', labelIcon, labelIconFamilyClass, labelIconFamilyPrefix, placeholder, type = 'text', disabled = false, loading = false, secret = false, iconFamilyClass, iconFamilyPrefix, characters = 4, invalidIcon: invalidIconProp, validIcon: validIconProp, innerInputMode = 'text', hint, invalid = false, valid = false, className, style, onChange, }) {
826
826
  const [pattern, setPattern] = React.useState('');
827
+ const [activeInput, setActiveInput] = React.useState(Array.from({ length: characters }).fill(''));
828
+ const isInputNum = React.useMemo(() => type === 'number' || type === 'tel', [type]);
827
829
  React.useEffect(() => {
828
830
  setPattern(type === 'number' ? '[0-9]+' : '^[a-zA-Z0-9]+$');
829
831
  }, [type]);
830
- const nextInput = React.useCallback((event) => {
832
+ const handleOTPChange = React.useCallback((otp) => {
833
+ const otpValue = otp.join('');
834
+ onChange === null || onChange === void 0 ? void 0 : onChange(otpValue);
835
+ }, [onChange]);
836
+ const handlePaste = React.useCallback((event) => {
837
+ event.preventDefault();
838
+ const pastedData = event.clipboardData.getData('text/plain');
839
+ const cleanData = isInputNum ? pastedData.replace(/[^0-9]/gmi, '') : pastedData;
840
+ const newInput = Array.from({ length: characters }).map((_, index) => cleanData[index] || '');
841
+ setActiveInput(newInput);
842
+ handleOTPChange(newInput);
843
+ event.currentTarget.blur();
844
+ }, [characters, handleOTPChange, isInputNum]);
845
+ const nextInput = React.useCallback((event, index) => {
831
846
  var _a;
832
- const input = event.target;
833
847
  const regex = new RegExp(pattern);
848
+ const input = event.currentTarget;
834
849
  if (!regex.test(input.value)) {
835
850
  input.value = '';
836
851
  }
837
852
  if (input.value !== '') {
853
+ setActiveInput((prev) => {
854
+ const newValue = prev.with(index, input.value);
855
+ handleOTPChange(newValue);
856
+ return newValue;
857
+ });
838
858
  if (input.nextSibling) {
839
859
  (_a = input.nextSibling) === null || _a === void 0 ? void 0 : _a.focus();
840
860
  }
@@ -842,43 +862,39 @@ function DInputPin({ id, label = '', labelIcon, labelIconFamilyClass, labelIconF
842
862
  input.blur();
843
863
  }
844
864
  }
845
- }, [pattern]);
846
- const prevInput = React.useCallback((event) => {
865
+ }, [handleOTPChange, pattern]);
866
+ const prevInput = React.useCallback(({ key, currentTarget }, index) => {
847
867
  var _a;
848
- if (event.key === 'Backspace') {
849
- const { value } = event.currentTarget;
850
- if (event.currentTarget.previousSibling && value === '') {
851
- (_a = event.currentTarget.previousSibling) === null || _a === void 0 ? void 0 : _a.focus();
868
+ if (key === 'Backspace') {
869
+ const { value } = currentTarget;
870
+ setActiveInput((prev) => {
871
+ const newVal = prev.with(index, '');
872
+ handleOTPChange(newVal);
873
+ return newVal;
874
+ });
875
+ if (currentTarget.previousSibling && value === '') {
876
+ (_a = currentTarget.previousSibling) === null || _a === void 0 ? void 0 : _a.focus();
852
877
  }
853
878
  else {
854
- event.currentTarget.blur();
855
- event.currentTarget.focus();
879
+ currentTarget.blur();
880
+ currentTarget.focus();
856
881
  }
857
882
  }
858
- }, []);
859
- const focusInput = React.useCallback((event) => {
860
- // eslint-disable-next-line no-param-reassign
861
- event.currentTarget.value = '';
883
+ }, [handleOTPChange]);
884
+ const focusInput = React.useCallback((index) => {
885
+ setActiveInput((prev) => prev.with(index, ''));
862
886
  }, []);
863
887
  const wheelInput = React.useCallback((event) => {
864
888
  event.currentTarget.blur();
865
889
  }, []);
866
- const formChange = React.useCallback((event) => {
867
- const formData = new FormData(event.currentTarget);
868
- const values = Array.from(formData.values()).join('');
869
- onChange === null || onChange === void 0 ? void 0 : onChange(values);
870
- }, [onChange]);
871
- const preventDefaultEvent = React.useCallback((event) => {
872
- event.preventDefault();
873
- }, []);
874
890
  const { iconMap: { input } } = useDContext();
875
891
  const invalidIcon = React.useMemo(() => invalidIconProp || input.invalid, [input.invalid, invalidIconProp]);
876
892
  const validIcon = React.useMemo(() => validIconProp || input.valid, [input.valid, validIconProp]);
877
- return (jsxRuntime.jsxs("div", { className: classNames('d-input-pin', className), style: style, children: [label && (jsxRuntime.jsxs("label", { htmlFor: "pinIndex0", children: [label, labelIcon && (jsxRuntime.jsx(DIcon, { icon: labelIcon, size: `var(--${PREFIX_BS}input-label-font-size)`, familyClass: labelIconFamilyClass, familyPrefix: labelIconFamilyPrefix }))] })), jsxRuntime.jsxs("form", { id: id, onInput: formChange, onSubmit: preventDefaultEvent, children: [Array.from({ length: characters }).map((_, index) => (jsxRuntime.jsx("input", Object.assign({ className: classNames({
893
+ return (jsxRuntime.jsxs("div", { className: classNames('d-input-pin', className), style: style, children: [label && (jsxRuntime.jsxs("label", { htmlFor: "pinIndex0", children: [label, labelIcon && (jsxRuntime.jsx(DIcon, { icon: labelIcon, size: `var(--${PREFIX_BS}input-label-font-size)`, familyClass: labelIconFamilyClass, familyPrefix: labelIconFamilyPrefix }))] })), jsxRuntime.jsxs("div", { className: "d-input-pin-group", id: id, children: [Array.from({ length: characters }).map((_, index) => (jsxRuntime.jsx("input", Object.assign({ className: classNames({
878
894
  'form-control': true,
879
895
  'is-invalid': invalid,
880
896
  'is-valid': valid,
881
- }), type: secret ? 'password' : type, "aria-describedby": `${id}State`, inputMode: innerInputMode, id: `pinIndex${index}`, name: `pin-${index}`, maxLength: 1, onChange: nextInput, onKeyDown: prevInput, onFocus: focusInput, onWheel: wheelInput, onClick: preventDefaultEvent, autoComplete: "off", placeholder: placeholder, disabled: disabled || loading, required: true }, type === 'number' && ({ min: 0, max: 9 })), index))), (invalid || valid) && !loading && (jsxRuntime.jsx("span", { className: "input-group-text", id: `${id}State`, children: jsxRuntime.jsx(DIcon, { className: "input-group-validation-icon", icon: invalid ? invalidIcon : validIcon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix }) })), loading && (jsxRuntime.jsx("div", { className: "input-group-text", children: jsxRuntime.jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsxRuntime.jsx("span", { className: "visually-hidden", children: "Loading..." }) }) }))] }), hint && (jsxRuntime.jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] }));
897
+ }), value: activeInput[index], type: secret ? 'password' : type, "aria-describedby": `${id}State`, inputMode: innerInputMode, id: `pinIndex${index}`, name: `pin-${index}`, maxLength: 1, onInput: (event) => nextInput(event, index), onKeyDown: (event) => prevInput(event, index), onFocus: () => focusInput(index), onWheel: wheelInput, onClick: (event) => event.preventDefault(), onPaste: (event) => handlePaste(event), autoComplete: "off", placeholder: placeholder, disabled: disabled || loading, required: true }, type === 'number' && ({ min: 0, max: 9 })), index))), (invalid || valid) && !loading && (jsxRuntime.jsx("span", { className: "input-group-text", id: `${id}State`, children: jsxRuntime.jsx(DIcon, { className: "input-group-validation-icon", icon: invalid ? invalidIcon : validIcon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix }) })), loading && (jsxRuntime.jsx("div", { className: "input-group-text", children: jsxRuntime.jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsxRuntime.jsx("span", { className: "visually-hidden", children: "Loading..." }) }) }))] }), hint && (jsxRuntime.jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] }));
882
898
  }
883
899
 
884
900
  function DInputSelect({ id, name, label = '', className, style, options = [], labelIcon, labelIconFamilyClass, labelIconFamilyPrefix, disabled = false, loading = false, iconStart, iconStartFamilyClass, iconStartFamilyPrefix, iconStartAriaLabel, iconEnd, iconEndFamilyClass, iconEndFamilyPrefix, iconEndAriaLabel, hint, value, floatingLabel = false, valueExtractor, labelExtractor, onChange, onBlur, onIconStartClick, onIconEndClick, }) {