@aspprev/versi-ds 0.2.0 → 0.4.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.
@@ -2,7 +2,7 @@ import {
2
2
  Tooltip_default,
3
3
  getFloatingLayerClass,
4
4
  mergeAriaDescribedBy
5
- } from "./chunk-ET2BGHTO.js";
5
+ } from "./chunk-FTRF27XF.js";
6
6
  import {
7
7
  COUNTRY_OPTIONS,
8
8
  PHONE_COUNTRY_OPTIONS,
@@ -199,7 +199,7 @@ var Input = (_a) => {
199
199
  const isPasswordType = type === "password";
200
200
  const [showPassword, setShowPassword] = useState(false);
201
201
  const currentType = isPasswordType ? showPassword ? "text" : "password" : type;
202
- const hasError = Boolean(meta.touched && meta.error);
202
+ const hasError = Boolean(meta.touched && meta.error || error);
203
203
  const inputId = (_a2 = rest.id) != null ? _a2 : name;
204
204
  const errorId = `${inputId}-error`;
205
205
  const ariaDescribedBy = mergeAriaDescribedBy(
@@ -2159,7 +2159,14 @@ import {
2159
2159
  } from "date-fns";
2160
2160
  import { ptBR } from "date-fns/locale/pt-BR";
2161
2161
  import { FormikContext, getIn } from "formik";
2162
- import { useContext, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef5, useState as useState4 } from "react";
2162
+ import {
2163
+ useContext,
2164
+ useEffect as useEffect3,
2165
+ useId as useId3,
2166
+ useMemo as useMemo2,
2167
+ useRef as useRef5,
2168
+ useState as useState4
2169
+ } from "react";
2163
2170
  import { createPortal as createPortal3 } from "react-dom";
2164
2171
  import { MdCalendarMonth, MdChevronLeft, MdChevronRight } from "react-icons/md";
2165
2172
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
@@ -2223,10 +2230,12 @@ var UnifiedDatePicker = ({
2223
2230
  name = "data",
2224
2231
  error,
2225
2232
  errorText,
2233
+ helperText,
2226
2234
  defaultView = "days",
2227
2235
  navigationVariant = "drilldown",
2228
2236
  selectionMode = "day",
2229
2237
  showAdjacentDays = true,
2238
+ ariaLabel,
2230
2239
  className
2231
2240
  }) => {
2232
2241
  const formik = useContext(
@@ -2253,10 +2262,19 @@ var UnifiedDatePicker = ({
2253
2262
  const containerRef = useRef5(null);
2254
2263
  const inputRef = useRef5(null);
2255
2264
  const dropdownRef = useRef5(null);
2265
+ const calendarId = `date-picker-${useId3()}`;
2266
+ const wasOpenRef = useRef5(false);
2256
2267
  const rafRef = useRef5(null);
2257
2268
  const [isMounted, setIsMounted] = useState4(false);
2258
2269
  const [panelNeedsScroll, setPanelNeedsScroll] = useState4(false);
2259
2270
  const [dropdownStyle, setDropdownStyle] = useState4({});
2271
+ useEffect3(() => {
2272
+ var _a, _b;
2273
+ if (wasOpenRef.current && !isOpen && ((_a = dropdownRef.current) == null ? void 0 : _a.contains(document.activeElement))) {
2274
+ (_b = inputRef.current) == null ? void 0 : _b.focus();
2275
+ }
2276
+ wasOpenRef.current = isOpen;
2277
+ }, [isOpen]);
2260
2278
  useEffect3(() => {
2261
2279
  setIsMounted(true);
2262
2280
  }, []);
@@ -2278,7 +2296,7 @@ var UnifiedDatePicker = ({
2278
2296
  }
2279
2297
  };
2280
2298
  const onKeyDown = (event) => {
2281
- if (event.key === "Escape") setIsOpen(false);
2299
+ if (event.key === "Escape") closeCalendar();
2282
2300
  };
2283
2301
  document.addEventListener("mousedown", onMouseDown);
2284
2302
  document.addEventListener("keydown", onKeyDown);
@@ -2359,6 +2377,11 @@ var UnifiedDatePicker = ({
2359
2377
  setIsOpen(true);
2360
2378
  (_a = inputRef.current) == null ? void 0 : _a.focus();
2361
2379
  };
2380
+ const closeCalendar = () => {
2381
+ var _a;
2382
+ setIsOpen(false);
2383
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
2384
+ };
2362
2385
  const getDaysInView = () => {
2363
2386
  const start = startOfWeek(startOfMonth(viewDate), { weekStartsOn: 0 });
2364
2387
  const end = endOfWeek(endOfMonth(viewDate), { weekStartsOn: 0 });
@@ -2373,7 +2396,7 @@ var UnifiedDatePicker = ({
2373
2396
  setInputError(null);
2374
2397
  setViewDate(day);
2375
2398
  touchField();
2376
- setIsOpen(false);
2399
+ closeCalendar();
2377
2400
  };
2378
2401
  const handleMonthClick = (monthIndex) => {
2379
2402
  const candidate = new Date(viewDate.getFullYear(), monthIndex, 1);
@@ -2385,7 +2408,7 @@ var UnifiedDatePicker = ({
2385
2408
  setDraftValue(formatDateForInput(nextDate, selectionMode));
2386
2409
  setInputError(null);
2387
2410
  touchField();
2388
- setIsOpen(false);
2411
+ closeCalendar();
2389
2412
  return;
2390
2413
  }
2391
2414
  setViewDate((currentDate) => {
@@ -2412,7 +2435,7 @@ var UnifiedDatePicker = ({
2412
2435
  setDraftValue(formatDateForInput(nextDate, selectionMode));
2413
2436
  setInputError(null);
2414
2437
  touchField();
2415
- setIsOpen(false);
2438
+ closeCalendar();
2416
2439
  return;
2417
2440
  }
2418
2441
  setViewDate((currentDate) => {
@@ -2436,6 +2459,36 @@ var UnifiedDatePicker = ({
2436
2459
  return nextDate;
2437
2460
  });
2438
2461
  };
2462
+ const moveCalendarFocus = (event, columns) => {
2463
+ var _a, _b;
2464
+ const movement = {
2465
+ ArrowLeft: -1,
2466
+ ArrowRight: 1,
2467
+ ArrowUp: -columns,
2468
+ ArrowDown: columns
2469
+ };
2470
+ const buttons = Array.from(
2471
+ (_b = (_a = dropdownRef.current) == null ? void 0 : _a.querySelectorAll(
2472
+ '[data-calendar-option="true"]:not(:disabled)'
2473
+ )) != null ? _b : []
2474
+ );
2475
+ const currentIndex = buttons.indexOf(event.currentTarget);
2476
+ if (currentIndex < 0) return;
2477
+ let nextIndex;
2478
+ if (event.key in movement) {
2479
+ nextIndex = currentIndex + movement[event.key];
2480
+ } else if (event.key === "Home") {
2481
+ nextIndex = currentIndex - currentIndex % columns;
2482
+ } else if (event.key === "End") {
2483
+ nextIndex = currentIndex - currentIndex % columns + columns - 1;
2484
+ } else {
2485
+ return;
2486
+ }
2487
+ const nextButton = buttons[nextIndex];
2488
+ if (!nextButton) return;
2489
+ event.preventDefault();
2490
+ nextButton.focus();
2491
+ };
2439
2492
  const commitDraftValue = (rawValue) => {
2440
2493
  const normalizedValue = formatInputValue(rawValue, selectionMode);
2441
2494
  setDraftValue(normalizedValue);
@@ -2515,6 +2568,8 @@ var UnifiedDatePicker = ({
2515
2568
  ref: containerRef,
2516
2569
  label,
2517
2570
  labelFor: name,
2571
+ description: helperText,
2572
+ descriptionId: `${name}-description`,
2518
2573
  invalid: hasError,
2519
2574
  message: resolvedErrorText,
2520
2575
  messageId: errorId,
@@ -2538,8 +2593,16 @@ var UnifiedDatePicker = ({
2538
2593
  ref: inputRef,
2539
2594
  id: name,
2540
2595
  name,
2596
+ "aria-label": ariaLabel != null ? ariaLabel : !label ? "Data" : void 0,
2597
+ role: "combobox",
2541
2598
  "aria-invalid": hasError || void 0,
2542
- "aria-describedby": hasError && resolvedErrorText ? errorId : void 0,
2599
+ "aria-describedby": mergeAriaDescribedBy(
2600
+ !hasError && helperText !== void 0 ? `${name}-description` : void 0,
2601
+ hasError && resolvedErrorText ? errorId : void 0
2602
+ ),
2603
+ "aria-haspopup": "dialog",
2604
+ "aria-expanded": isOpen,
2605
+ "aria-controls": isOpen ? calendarId : void 0,
2543
2606
  type: "text",
2544
2607
  inputMode: "numeric",
2545
2608
  autoComplete: "off",
@@ -2571,7 +2634,7 @@ var UnifiedDatePicker = ({
2571
2634
  onKeyDown: (event) => {
2572
2635
  if (event.key === "Enter") {
2573
2636
  commitDraftValue(draftValue);
2574
- setIsOpen(false);
2637
+ closeCalendar();
2575
2638
  }
2576
2639
  },
2577
2640
  className: FIELD_INPUT_CLASS
@@ -2603,10 +2666,13 @@ var UnifiedDatePicker = ({
2603
2666
  "div",
2604
2667
  {
2605
2668
  ref: dropdownRef,
2669
+ id: calendarId,
2670
+ role: "dialog",
2671
+ "aria-label": selectionMode === "year" ? "Selecionar ano" : selectionMode === "month" ? "Selecionar m\xEAs" : "Selecionar data",
2606
2672
  style: dropdownStyle,
2607
2673
  className: classNames6(
2608
2674
  getFloatingLayerClass(containerRef.current, "popover"),
2609
- "rounded-sm border border-border-default bg-white shadow-md transition-all duration-150",
2675
+ "rounded-sm border border-border-default bg-white shadow-md transition-all duration-150 motion-reduce:transition-none",
2610
2676
  panelNeedsScroll ? "overflow-y-auto overscroll-contain" : "overflow-visible",
2611
2677
  "py-3"
2612
2678
  ),
@@ -2692,100 +2758,141 @@ var UnifiedDatePicker = ({
2692
2758
  )
2693
2759
  ] }),
2694
2760
  mode === "days" && /* @__PURE__ */ jsxs6("div", { className: "px-3", children: [
2695
- /* @__PURE__ */ jsx6("div", { className: "grid grid-cols-7 gap-x-1", children: WEEKDAYS.map((weekday) => /* @__PURE__ */ jsx6(
2761
+ /* @__PURE__ */ jsx6("div", { className: "grid grid-cols-7 gap-x-1", role: "row", children: WEEKDAYS.map((weekday) => /* @__PURE__ */ jsx6(
2696
2762
  "div",
2697
2763
  {
2764
+ role: "columnheader",
2698
2765
  className: "select-none py-0.5 text-center text-2xs font-semibold text-content-muted",
2699
2766
  children: weekday
2700
2767
  },
2701
2768
  weekday
2702
2769
  )) }),
2703
- /* @__PURE__ */ jsx6("div", { className: "grid grid-cols-7 gap-x-1", children: getDaysInView().map((day, index) => {
2704
- const selected = selectedDate ? isSameDay(day, selectedDate) : false;
2705
- const currentDay = isToday(day);
2706
- const inMonth = isSameMonth(day, viewDate);
2707
- const dayDisabled = isBefore(day, startOfDay(minDate)) || isAfter(day, startOfDay(maxDate));
2708
- if (!showAdjacentDays && !inMonth) {
2709
- return /* @__PURE__ */ jsx6(
2710
- "span",
2711
- {
2712
- "aria-hidden": "true",
2713
- className: "h-7"
2714
- },
2715
- `${day.toISOString()}-${index}`
2716
- );
2717
- }
2718
- return /* @__PURE__ */ jsx6(
2719
- "button",
2720
- {
2721
- type: "button",
2722
- onClick: () => handleDayClick(day),
2723
- disabled: dayDisabled,
2724
- className: classNames6(
2725
- "group flex h-7 w-full items-center justify-center text-xs transition-colors",
2726
- {
2727
- "opacity-30 cursor-not-allowed": dayDisabled,
2728
- "cursor-pointer": !dayDisabled
2729
- }
2730
- ),
2731
- children: /* @__PURE__ */ jsx6(
2732
- "span",
2770
+ /* @__PURE__ */ jsx6(
2771
+ "div",
2772
+ {
2773
+ className: "grid grid-cols-7 gap-x-1",
2774
+ role: "grid",
2775
+ "aria-label": `Dias de ${headerLabel}`,
2776
+ children: getDaysInView().map((day, index) => {
2777
+ const selected = selectedDate ? isSameDay(day, selectedDate) : false;
2778
+ const currentDay = isToday(day);
2779
+ const inMonth = isSameMonth(day, viewDate);
2780
+ const dayDisabled = isBefore(day, startOfDay(minDate)) || isAfter(day, startOfDay(maxDate));
2781
+ if (!showAdjacentDays && !inMonth) {
2782
+ return /* @__PURE__ */ jsx6(
2783
+ "span",
2784
+ {
2785
+ "aria-hidden": "true",
2786
+ className: "h-7"
2787
+ },
2788
+ `${day.toISOString()}-${index}`
2789
+ );
2790
+ }
2791
+ return /* @__PURE__ */ jsx6(
2792
+ "button",
2733
2793
  {
2794
+ type: "button",
2795
+ "data-calendar-option": "true",
2796
+ "aria-label": format(day, "dd/MM/yyyy"),
2797
+ "aria-current": currentDay ? "date" : void 0,
2798
+ "aria-pressed": selected,
2799
+ onKeyDown: (event) => moveCalendarFocus(event, 7),
2800
+ onClick: () => handleDayClick(day),
2801
+ disabled: dayDisabled,
2734
2802
  className: classNames6(
2735
- "flex h-6 w-6 items-center justify-center rounded-sm transition-colors",
2803
+ "group flex h-7 w-full items-center justify-center text-xs transition-colors",
2736
2804
  {
2737
- "border border-selection-border bg-selection-background font-semibold text-selection-content": selected,
2738
- "border border-primary-1 text-primary-1 font-semibold group-hover:bg-primary-1/10": currentDay && inMonth && !selected,
2739
- "text-content-primary group-hover:bg-primary-1/10": inMonth && !selected && !currentDay,
2740
- "text-content-muted": !inMonth
2805
+ "opacity-30 cursor-not-allowed": dayDisabled,
2806
+ "cursor-pointer": !dayDisabled
2741
2807
  }
2742
2808
  ),
2743
- children: format(day, "d")
2744
- }
2745
- )
2746
- },
2747
- `${day.toISOString()}-${index}`
2748
- );
2749
- }) })
2809
+ children: /* @__PURE__ */ jsx6(
2810
+ "span",
2811
+ {
2812
+ className: classNames6(
2813
+ "flex h-6 w-6 items-center justify-center rounded-sm transition-colors",
2814
+ {
2815
+ "border border-selection-border bg-selection-background font-semibold text-selection-content": selected,
2816
+ "border border-primary-1 text-primary-1 font-semibold group-hover:bg-primary-1/10": currentDay && inMonth && !selected,
2817
+ "text-content-primary group-hover:bg-primary-1/10": inMonth && !selected && !currentDay,
2818
+ "text-content-muted": !inMonth
2819
+ }
2820
+ ),
2821
+ children: format(day, "d")
2822
+ }
2823
+ )
2824
+ },
2825
+ `${day.toISOString()}-${index}`
2826
+ );
2827
+ })
2828
+ }
2829
+ )
2750
2830
  ] }),
2751
- mode === "months" && /* @__PURE__ */ jsx6("div", { className: "grid grid-cols-3 gap-1 px-3", children: MONTHS.map((month, index) => {
2752
- const selected = index === viewDate.getMonth();
2753
- return /* @__PURE__ */ jsx6(
2754
- "button",
2755
- {
2756
- type: "button",
2757
- onClick: () => handleMonthClick(index),
2758
- className: classNames6(
2759
- "rounded-sm py-1 text-xs capitalize transition-colors",
2831
+ mode === "months" && /* @__PURE__ */ jsx6(
2832
+ "div",
2833
+ {
2834
+ className: "grid grid-cols-3 gap-1 px-3",
2835
+ role: "group",
2836
+ "aria-label": "Meses do calend\xE1rio",
2837
+ children: MONTHS.map((month, index) => {
2838
+ const selected = index === viewDate.getMonth();
2839
+ const monthDate = new Date(viewDate.getFullYear(), index, 1);
2840
+ const monthDisabled = isBefore(endOfMonth(monthDate), startOfDay(minDate)) || isAfter(startOfMonth(monthDate), startOfDay(maxDate));
2841
+ return /* @__PURE__ */ jsx6(
2842
+ "button",
2760
2843
  {
2761
- "border border-selection-border bg-selection-background font-semibold text-selection-content": selected,
2762
- "text-content-primary hover:bg-primary-1/10": !selected
2763
- }
2764
- ),
2765
- children: month.slice(0, 3)
2766
- },
2767
- month
2768
- );
2769
- }) }),
2770
- mode === "years" && /* @__PURE__ */ jsx6("div", { className: "grid grid-cols-3 gap-1 px-3", children: years.map((year) => {
2771
- const selected = year === viewDate.getFullYear();
2772
- return /* @__PURE__ */ jsx6(
2773
- "button",
2774
- {
2775
- type: "button",
2776
- onClick: () => handleYearClick(year),
2777
- className: classNames6(
2778
- "rounded-sm py-1 text-xs transition-colors",
2844
+ type: "button",
2845
+ "data-calendar-option": "true",
2846
+ "aria-pressed": selected,
2847
+ disabled: monthDisabled,
2848
+ onKeyDown: (event) => moveCalendarFocus(event, 3),
2849
+ onClick: () => handleMonthClick(index),
2850
+ className: classNames6(
2851
+ "rounded-sm py-1 text-xs capitalize transition-colors",
2852
+ {
2853
+ "border border-selection-border bg-selection-background font-semibold text-selection-content": selected,
2854
+ "text-content-primary hover:bg-primary-1/10": !selected
2855
+ }
2856
+ ),
2857
+ children: month.slice(0, 3)
2858
+ },
2859
+ month
2860
+ );
2861
+ })
2862
+ }
2863
+ ),
2864
+ mode === "years" && /* @__PURE__ */ jsx6(
2865
+ "div",
2866
+ {
2867
+ className: "grid grid-cols-3 gap-1 px-3",
2868
+ role: "group",
2869
+ "aria-label": "Anos do calend\xE1rio",
2870
+ children: years.map((year) => {
2871
+ const selected = year === viewDate.getFullYear();
2872
+ const yearDisabled = year < minYear || year > maxYear;
2873
+ return /* @__PURE__ */ jsx6(
2874
+ "button",
2779
2875
  {
2780
- "border border-selection-border bg-selection-background font-semibold text-selection-content": selected,
2781
- "text-content-primary hover:bg-primary-1/10": !selected
2782
- }
2783
- ),
2784
- children: year
2785
- },
2786
- year
2787
- );
2788
- }) })
2876
+ type: "button",
2877
+ "data-calendar-option": "true",
2878
+ "aria-pressed": selected,
2879
+ disabled: yearDisabled,
2880
+ onKeyDown: (event) => moveCalendarFocus(event, 3),
2881
+ onClick: () => handleYearClick(year),
2882
+ className: classNames6(
2883
+ "rounded-sm py-1 text-xs transition-colors",
2884
+ {
2885
+ "border border-selection-border bg-selection-background font-semibold text-selection-content": selected,
2886
+ "text-content-primary hover:bg-primary-1/10": !selected
2887
+ }
2888
+ ),
2889
+ children: year
2890
+ },
2891
+ year
2892
+ );
2893
+ })
2894
+ }
2895
+ )
2789
2896
  ]
2790
2897
  }
2791
2898
  ),
@@ -2806,7 +2913,7 @@ var datePicker_default = DatePicker;
2806
2913
  import cs from "classnames";
2807
2914
  import {
2808
2915
  useEffect as useEffect4,
2809
- useId as useId3,
2916
+ useId as useId4,
2810
2917
  useRef as useRef6,
2811
2918
  useState as useState5
2812
2919
  } from "react";
@@ -2818,7 +2925,7 @@ function SelectMultiView(props) {
2818
2925
  const containerRef = useRef6(null);
2819
2926
  const triggerRef = useRef6(null);
2820
2927
  const groupRef = useRef6(null);
2821
- const baseId = useId3();
2928
+ const baseId = useId4();
2822
2929
  const triggerId = `${baseId}-trigger`;
2823
2930
  const labelId = `${baseId}-label`;
2824
2931
  const groupId = `${baseId}-options`;
@@ -3147,7 +3254,7 @@ var SelectCountry_default = SelectCountry;
3147
3254
 
3148
3255
  // src/components/radio-group/radio-group.tsx
3149
3256
  import { useField as useField5 } from "formik";
3150
- import { useId as useId4 } from "react";
3257
+ import { useId as useId5 } from "react";
3151
3258
  import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
3152
3259
  function RadioGroup(_a) {
3153
3260
  var _b = _a, {
@@ -3163,7 +3270,7 @@ function RadioGroup(_a) {
3163
3270
  ]);
3164
3271
  const [field, meta] = useField5(name);
3165
3272
  const hasError = Boolean(meta.touched && meta.error);
3166
- const errorId = `${useId4()}-error`;
3273
+ const errorId = `${useId5()}-error`;
3167
3274
  return /* @__PURE__ */ jsxs9(
3168
3275
  "fieldset",
3169
3276
  {
@@ -3214,7 +3321,7 @@ import classNames7 from "classnames";
3214
3321
  import { FormikContext as FormikContext2, getIn as getIn2 } from "formik";
3215
3322
  import {
3216
3323
  useContext as useContext2,
3217
- useId as useId5,
3324
+ useId as useId6,
3218
3325
  useMemo as useMemo3,
3219
3326
  useState as useState6
3220
3327
  } from "react";
@@ -3237,7 +3344,7 @@ function RadioCardGroup({
3237
3344
  const formikContext = useContext2(
3238
3345
  FormikContext2
3239
3346
  );
3240
- const generatedName = useId5();
3347
+ const generatedName = useId6();
3241
3348
  const errorId = `${generatedName}-error`;
3242
3349
  const [internalValue, setInternalValue] = useState6(defaultValue);
3243
3350
  const hasFormikBinding = Boolean(name) && isFormikContext(formikContext);
@@ -3337,7 +3444,7 @@ import classNames8 from "classnames";
3337
3444
  import {
3338
3445
  forwardRef as forwardRef2,
3339
3446
  useEffect as useEffect5,
3340
- useId as useId6,
3447
+ useId as useId7,
3341
3448
  useImperativeHandle,
3342
3449
  useRef as useRef7,
3343
3450
  useState as useState7
@@ -3346,7 +3453,10 @@ import { jsx as jsx12 } from "react/jsx-runtime";
3346
3453
  import { createElement } from "react";
3347
3454
  var normalizeMask = (value, mask) => {
3348
3455
  if (typeof mask === "function") return mask(value).slice(0, 1);
3349
- if (mask instanceof RegExp) return mask.test(value) ? value.slice(0, 1) : "";
3456
+ if (mask instanceof RegExp) {
3457
+ const stableMask = new RegExp(mask.source, mask.flags.replace(/[gy]/g, ""));
3458
+ return stableMask.test(value) ? value.slice(0, 1) : "";
3459
+ }
3350
3460
  if (mask === "alphanumeric") return value.replace(/[^a-z\d]/gi, "").slice(0, 1);
3351
3461
  return value.replace(/\D/g, "").slice(0, 1);
3352
3462
  };
@@ -3375,6 +3485,8 @@ var OtpCodeInput = forwardRef2(
3375
3485
  inputMode = "numeric",
3376
3486
  mask = "numeric",
3377
3487
  name,
3488
+ onFocus: onInputFocus,
3489
+ onKeyDown: onInputKeyDown,
3378
3490
  className
3379
3491
  } = _b, inputProps = __objRest(_b, [
3380
3492
  "length",
@@ -3392,10 +3504,12 @@ var OtpCodeInput = forwardRef2(
3392
3504
  "inputMode",
3393
3505
  "mask",
3394
3506
  "name",
3507
+ "onFocus",
3508
+ "onKeyDown",
3395
3509
  "className"
3396
3510
  ]);
3397
- const safeLength = Math.max(1, Math.floor(length));
3398
- const groupId = useId6();
3511
+ const safeLength = Math.max(1, Number.isFinite(length) ? Math.floor(length) : 6);
3512
+ const groupId = useId7();
3399
3513
  const errorId = `${groupId}-error`;
3400
3514
  const helperId = `${groupId}-helper`;
3401
3515
  const inputRefs = useRef7([]);
@@ -3406,9 +3520,12 @@ var OtpCodeInput = forwardRef2(
3406
3520
  const currentValues = isControlled ? normalizeValues(values != null ? values : value, safeLength, mask) : internalValues;
3407
3521
  useEffect5(() => {
3408
3522
  if (!isControlled) {
3409
- setInternalValues(
3410
- (previous) => previous.length === safeLength ? previous : normalizeValues(previous, safeLength, mask)
3411
- );
3523
+ setInternalValues((previous) => {
3524
+ const normalized = normalizeValues(previous, safeLength, mask);
3525
+ return previous.length === normalized.length && previous.every(
3526
+ (item, index) => item === normalized[index]
3527
+ ) ? previous : normalized;
3528
+ });
3412
3529
  }
3413
3530
  }, [isControlled, mask, safeLength]);
3414
3531
  useImperativeHandle(ref, () => ({
@@ -3433,8 +3550,9 @@ var OtpCodeInput = forwardRef2(
3433
3550
  const normalized = normalizeValues(next, safeLength, mask);
3434
3551
  if (!isControlled) setInternalValues(normalized);
3435
3552
  const nextValue = normalized.join("");
3553
+ const wasComplete = currentValues.every(Boolean) && currentValues.length === safeLength;
3436
3554
  onChange == null ? void 0 : onChange(nextValue, normalized);
3437
- if (normalized.every(Boolean) && nextValue.length === safeLength) {
3555
+ if (!wasComplete && normalized.every(Boolean) && nextValue.length === safeLength) {
3438
3556
  onComplete == null ? void 0 : onComplete(nextValue);
3439
3557
  }
3440
3558
  if (focusIndex !== void 0) (_a2 = inputRefs.current[focusIndex]) == null ? void 0 : _a2.focus();
@@ -3529,8 +3647,14 @@ var OtpCodeInput = forwardRef2(
3529
3647
  emit(next, nextValue && index < safeLength - 1 ? index + 1 : void 0);
3530
3648
  },
3531
3649
  onPaste: (event) => handlePaste(event, index),
3532
- onKeyDown: (event) => handleKeyDown(event, index),
3533
- onFocus: (event) => event.currentTarget.select(),
3650
+ onKeyDown: (event) => {
3651
+ onInputKeyDown == null ? void 0 : onInputKeyDown(event);
3652
+ if (!event.defaultPrevented) handleKeyDown(event, index);
3653
+ },
3654
+ onFocus: (event) => {
3655
+ onInputFocus == null ? void 0 : onInputFocus(event);
3656
+ if (!event.defaultPrevented) event.currentTarget.select();
3657
+ },
3534
3658
  className: classNames8(
3535
3659
  "h-11 w-11 rounded-sm border bg-field-surface text-center text-lg font-bold text-field-content outline-none transition-colors focus-visible:border-field-border-active focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-focus-ring disabled:cursor-not-allowed disabled:bg-field-surface-disabled",
3536
3660
  hasError ? "border-field-border-error" : "border-field-border-default"
@@ -3565,4 +3689,4 @@ export {
3565
3689
  RadioCardGroup,
3566
3690
  OtpCodeInput_default
3567
3691
  };
3568
- //# sourceMappingURL=chunk-FR5W52XU.js.map
3692
+ //# sourceMappingURL=chunk-LPLXAKPJ.js.map