@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.esm.js CHANGED
@@ -477,7 +477,7 @@ function DDatePickerTime(_a) {
477
477
  }
478
478
 
479
479
  function DDatePickerInput(_a, ref) {
480
- var { value, onClick, id, iconEnd, className, style, inputLabel } = _a, props = __rest(_a, ["value", "onClick", "id", "iconEnd", "className", "style", "inputLabel"]);
480
+ var { value, onClick, id, iconEnd, className, style, inputLabel, readOnly: ignored } = _a, props = __rest(_a, ["value", "onClick", "id", "iconEnd", "className", "style", "inputLabel", "readOnly"]);
481
481
  return (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)));
482
482
  }
483
483
  const ForwardedDDatePickerInput = forwardRef(DDatePickerInput);
@@ -629,7 +629,7 @@ function DDatePickerHeader({ date, changeYear, changeMonth, decreaseMonth, incre
629
629
  }
630
630
 
631
631
  function DDatePicker(_a) {
632
- 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 = __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"]);
632
+ 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 = __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"]);
633
633
  const { iconMap: { calendar, chevronLeft, chevronRight, }, } = useDContext();
634
634
  const selected = useMemo(() => (date ? parseISO(date) : null), [date]);
635
635
  const iconInput = useMemo(() => iconInputProp || calendar, [calendar, iconInputProp]);
@@ -651,7 +651,7 @@ function DDatePicker(_a) {
651
651
  minYearSelect,
652
652
  maxYearSelect,
653
653
  ]);
654
- return (jsx(DatePicker, Object.assign({ selected: selected, calendarClassName: "d-date-picker", renderCustomHeader: (headerProps) => jsx(DatePickerHeader, Object.assign({}, headerProps)), selectsRange: selectsRange, formatWeekDay: handleFormatWeekDay, customInput: (jsx(DDatePickerInput$1, { id: inputId, "aria-label": inputAriaLabel, iconEndAriaLabel: inputActionAriaLabel, iconMaterialStyle: iconMaterialStyleProp, iconEnd: iconInput, inputLabel: inputLabel, className: className, style: style })), customTimeInput: (jsx(DDatePickerTime, { id: timeId, label: timeLabel })) }, locale && { locale }, props)));
654
+ return (jsx(DatePicker, Object.assign({ selected: selected, calendarClassName: "d-date-picker", renderCustomHeader: (headerProps) => jsx(DatePickerHeader, Object.assign({}, headerProps)), selectsRange: selectsRange, formatWeekDay: handleFormatWeekDay, customInput: (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: (jsx(DDatePickerTime, { id: timeId, label: timeLabel })) }, locale && { locale }, props)));
655
655
  }
656
656
 
657
657
  function DInputMask(props, ref) {
@@ -822,17 +822,37 @@ var DInputPassword$1 = ForwardedDInputPassword;
822
822
 
823
823
  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, }) {
824
824
  const [pattern, setPattern] = useState('');
825
+ const [activeInput, setActiveInput] = useState(Array.from({ length: characters }).fill(''));
826
+ const isInputNum = useMemo(() => type === 'number' || type === 'tel', [type]);
825
827
  useEffect(() => {
826
828
  setPattern(type === 'number' ? '[0-9]+' : '^[a-zA-Z0-9]+$');
827
829
  }, [type]);
828
- const nextInput = useCallback((event) => {
830
+ const handleOTPChange = useCallback((otp) => {
831
+ const otpValue = otp.join('');
832
+ onChange === null || onChange === void 0 ? void 0 : onChange(otpValue);
833
+ }, [onChange]);
834
+ const handlePaste = useCallback((event) => {
835
+ event.preventDefault();
836
+ const pastedData = event.clipboardData.getData('text/plain');
837
+ const cleanData = isInputNum ? pastedData.replace(/[^0-9]/gmi, '') : pastedData;
838
+ const newInput = Array.from({ length: characters }).map((_, index) => cleanData[index] || '');
839
+ setActiveInput(newInput);
840
+ handleOTPChange(newInput);
841
+ event.currentTarget.blur();
842
+ }, [characters, handleOTPChange, isInputNum]);
843
+ const nextInput = useCallback((event, index) => {
829
844
  var _a;
830
- const input = event.target;
831
845
  const regex = new RegExp(pattern);
846
+ const input = event.currentTarget;
832
847
  if (!regex.test(input.value)) {
833
848
  input.value = '';
834
849
  }
835
850
  if (input.value !== '') {
851
+ setActiveInput((prev) => {
852
+ const newValue = prev.with(index, input.value);
853
+ handleOTPChange(newValue);
854
+ return newValue;
855
+ });
836
856
  if (input.nextSibling) {
837
857
  (_a = input.nextSibling) === null || _a === void 0 ? void 0 : _a.focus();
838
858
  }
@@ -840,43 +860,39 @@ function DInputPin({ id, label = '', labelIcon, labelIconFamilyClass, labelIconF
840
860
  input.blur();
841
861
  }
842
862
  }
843
- }, [pattern]);
844
- const prevInput = useCallback((event) => {
863
+ }, [handleOTPChange, pattern]);
864
+ const prevInput = useCallback(({ key, currentTarget }, index) => {
845
865
  var _a;
846
- if (event.key === 'Backspace') {
847
- const { value } = event.currentTarget;
848
- if (event.currentTarget.previousSibling && value === '') {
849
- (_a = event.currentTarget.previousSibling) === null || _a === void 0 ? void 0 : _a.focus();
866
+ if (key === 'Backspace') {
867
+ const { value } = currentTarget;
868
+ setActiveInput((prev) => {
869
+ const newVal = prev.with(index, '');
870
+ handleOTPChange(newVal);
871
+ return newVal;
872
+ });
873
+ if (currentTarget.previousSibling && value === '') {
874
+ (_a = currentTarget.previousSibling) === null || _a === void 0 ? void 0 : _a.focus();
850
875
  }
851
876
  else {
852
- event.currentTarget.blur();
853
- event.currentTarget.focus();
877
+ currentTarget.blur();
878
+ currentTarget.focus();
854
879
  }
855
880
  }
856
- }, []);
857
- const focusInput = useCallback((event) => {
858
- // eslint-disable-next-line no-param-reassign
859
- event.currentTarget.value = '';
881
+ }, [handleOTPChange]);
882
+ const focusInput = useCallback((index) => {
883
+ setActiveInput((prev) => prev.with(index, ''));
860
884
  }, []);
861
885
  const wheelInput = useCallback((event) => {
862
886
  event.currentTarget.blur();
863
887
  }, []);
864
- const formChange = useCallback((event) => {
865
- const formData = new FormData(event.currentTarget);
866
- const values = Array.from(formData.values()).join('');
867
- onChange === null || onChange === void 0 ? void 0 : onChange(values);
868
- }, [onChange]);
869
- const preventDefaultEvent = useCallback((event) => {
870
- event.preventDefault();
871
- }, []);
872
888
  const { iconMap: { input } } = useDContext();
873
889
  const invalidIcon = useMemo(() => invalidIconProp || input.invalid, [input.invalid, invalidIconProp]);
874
890
  const validIcon = useMemo(() => validIconProp || input.valid, [input.valid, validIconProp]);
875
- return (jsxs("div", { className: classNames('d-input-pin', className), style: style, children: [label && (jsxs("label", { htmlFor: "pinIndex0", children: [label, labelIcon && (jsx(DIcon, { icon: labelIcon, size: `var(--${PREFIX_BS}input-label-font-size)`, familyClass: labelIconFamilyClass, familyPrefix: labelIconFamilyPrefix }))] })), jsxs("form", { id: id, onInput: formChange, onSubmit: preventDefaultEvent, children: [Array.from({ length: characters }).map((_, index) => (jsx("input", Object.assign({ className: classNames({
891
+ return (jsxs("div", { className: classNames('d-input-pin', className), style: style, children: [label && (jsxs("label", { htmlFor: "pinIndex0", children: [label, labelIcon && (jsx(DIcon, { icon: labelIcon, size: `var(--${PREFIX_BS}input-label-font-size)`, familyClass: labelIconFamilyClass, familyPrefix: labelIconFamilyPrefix }))] })), jsxs("div", { className: "d-input-pin-group", id: id, children: [Array.from({ length: characters }).map((_, index) => (jsx("input", Object.assign({ className: classNames({
876
892
  'form-control': true,
877
893
  'is-invalid': invalid,
878
894
  'is-valid': valid,
879
- }), 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 && (jsx("span", { className: "input-group-text", id: `${id}State`, children: jsx(DIcon, { className: "input-group-validation-icon", icon: invalid ? invalidIcon : validIcon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix }) })), loading && (jsx("div", { className: "input-group-text", children: jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsx("span", { className: "visually-hidden", children: "Loading..." }) }) }))] }), hint && (jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] }));
895
+ }), 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 && (jsx("span", { className: "input-group-text", id: `${id}State`, children: jsx(DIcon, { className: "input-group-validation-icon", icon: invalid ? invalidIcon : validIcon, familyClass: iconFamilyClass, familyPrefix: iconFamilyPrefix }) })), loading && (jsx("div", { className: "input-group-text", children: jsx("span", { className: "spinner-border spinner-border-sm", role: "status", "aria-hidden": "true", children: jsx("span", { className: "visually-hidden", children: "Loading..." }) }) }))] }), hint && (jsx("div", { className: "form-text", id: `${id}Hint`, children: hint }))] }));
880
896
  }
881
897
 
882
898
  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, }) {