@planetaexo/design-system 0.9.3 → 0.9.5

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.d.cts CHANGED
@@ -515,24 +515,23 @@ interface BookingConfirmationEmailProps {
515
515
  }
516
516
  declare function BookingConfirmationEmail({ recipientName, addTravellersUrl, logoUrl, bookingNumber, activity, adventure, startingDate, numberOfPeople, host, labels, className, }: BookingConfirmationEmailProps): react_jsx_runtime.JSX.Element;
517
517
 
518
- interface BookingOtpEmailLabels {
519
- bodyMessage: string;
520
- expiryMessage: string;
521
- logoAlt?: string;
522
- }
523
518
  interface BookingOtpEmailProps {
524
- /** Mensagem principal com código incluído (ex: "Seu código para reserva #42 é: 123456") */
525
- bodyMessage: string;
526
- /** Mensagem de expiração (ex: "Este código expira em breve.") */
519
+ /** Saudação (ex.: "Hello!" / "Olá!"). */
520
+ greeting: string;
521
+ /** Intro curta com bookingId embutido (ex.: "Here is your verification code for booking #42."). */
522
+ intro: string;
523
+ /** Código OTP renderizado em destaque. Não é sanitizado — passe só dígitos. */
524
+ code: string;
525
+ /** Mensagem de expiração (ex.: "This code expires shortly."). */
527
526
  expiryMessage: string;
528
- /** URL da logo. Default: data URI embutido no pacote. */
527
+ /** Assinatura do time (ex.: "PlanetaEXO Team"). */
528
+ teamSignature: string;
529
+ /** URL da logo. Default: data URI embutido. */
529
530
  logoUrl?: string;
530
- /** Labels opcionais para i18n (não usado diretamente — bodyMessage já é traduzida) */
531
- labels?: Partial<BookingOtpEmailLabels>;
532
- /** className extra no container (para uso no styleguide) */
531
+ /** className extra no container (uso no styleguide). */
533
532
  className?: string;
534
533
  }
535
- declare function BookingOtpEmail({ bodyMessage, expiryMessage, logoUrl, className, }: BookingOtpEmailProps): react_jsx_runtime.JSX.Element;
534
+ declare function BookingOtpEmail({ greeting, intro, code, expiryMessage, teamSignature, logoUrl, className, }: BookingOtpEmailProps): react_jsx_runtime.JSX.Element;
536
535
 
537
536
  interface TravellerFormInviteLink {
538
537
  adventureName?: string;
@@ -1623,4 +1622,4 @@ declare function LeadCapturePopup({ config: _config, }: {
1623
1622
  config: LeadCapturePopupConfig;
1624
1623
  }): react_jsx_runtime.JSX.Element | null;
1625
1624
 
1626
- export { ActivityCard, type ActivityCardProps, type ActivityCardSize, Alert, type AlertProps, type AlertVariant, BirthDateField, type BirthDateFieldProps, type BookingAdventure, BookingConfirmation, BookingConfirmationEmail, type BookingConfirmationEmailLabels, type BookingConfirmationEmailProps, type BookingConfirmationLabels, type BookingConfirmationProps, BookingConfirmedCard, type BookingConfirmedCardProps, type BookingContact, type BookingDepositInfo, BookingDetails, type BookingDetailsProps, BookingForm, type BookingFormProps, type BookingFormValues, BookingOtpEmail, type BookingOtpEmailLabels, type BookingOtpEmailProps, BookingShell, type BookingShellProps, type BookingStatus, type BookingSummaryLineItem, type BookingTraveller, Button, type ButtonProps, COUNTRIES, type ConfirmationAdventure, type ConfirmationDepositInfo, type ConfirmationLineItem, type ConfirmationTraveller, CounterField, type CounterFieldProps, type CountryOption, CountrySearchField, type CountrySearchFieldProps, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, DatePickerField, type DatePickerFieldProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, type EmailTokens, type FilterGroup, type FilterItem, FilterPanel, type FilterPanelProps, FloatingInput, type FloatingInputProps, FloatingSelect, type FloatingSelectProps, Itinerary, type ItineraryProps, type ItineraryRoute, type ItineraryStop, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, type LeadCapturePopupConfig, MenuTrip, type MenuTripProps, type MenuTripSection, type MenuTripVariant, OTPCodeInput, type OTPCodeInputProps, Offer, OfferAdventureCard, type OfferAdventureItem, type OfferAgentInfo, type OfferDepositInfo, type OfferOptionalItem, type OfferProps, type OfferSummaryLineItem, PaymentAmountSelector, type PaymentAmountSelectorProps, type PaymentMethodOption, PaymentMethodSelector, type PaymentMethodSelectorProps, PaymentModalShell, type PaymentModalShellProps, PhoneCountrySelect, PhotoGallery, type PhotoGalleryPhoto, type PhotoGalleryProps, type PhotoGalleryVariant, type PricingOption, PricingTrip, type PricingTripProps, type PricingTripVariant, type RegistrationAdventure, type RegistrationBooking, type RegistrationEmergencyContactValue, type RegistrationField, type RegistrationFieldOption, type RegistrationFieldType, type RegistrationFieldValue, RegistrationForm, type RegistrationFormLabels, type RegistrationFormProps, type RegistrationFormValues, type RegistrationNameValue, type RegistrationPhoneValue, RegistrationSuccessCard, type RegistrationSuccessCardProps, type RegistrationTerms, type RegistrationTraveller, SiteHeader, type SiteHeaderLanguage, type SiteHeaderLink, type SiteHeaderProps, type SiteHeaderSubItem, type SiteHeaderVariant, type StripeAppearance, type SuggestedTraveller, TERMS_ACCEPT_KEY, TermsSection, type TermsSectionProps, ThemeToggle, Toast, type ToastProps, type ToastVariant, type TravellerFormConfig, type TravellerFormData, TravellerFormInviteEmail, type TravellerFormInviteEmailLabels, type TravellerFormInviteEmailProps, type TravellerFormInviteLink, type TravellerFormLabels, TripCard, type TripCardCta, type TripCardProps, type TripCardSize, type TripCardStatus, type TripDuration, type TripFaq, TripHeader, type TripHeaderProps, type TripHighlight, type TripInfoGroup, type TripItineraryStep, type TripMeetingPoint, TripPage, type TripPageProps, type TripPricingOption, type TripReview, buttonVariants, cn, emailTokens, getStripeAppearance, stripeAppearance, wrapEmailHtml };
1625
+ export { ActivityCard, type ActivityCardProps, type ActivityCardSize, Alert, type AlertProps, type AlertVariant, BirthDateField, type BirthDateFieldProps, type BookingAdventure, BookingConfirmation, BookingConfirmationEmail, type BookingConfirmationEmailLabels, type BookingConfirmationEmailProps, type BookingConfirmationLabels, type BookingConfirmationProps, BookingConfirmedCard, type BookingConfirmedCardProps, type BookingContact, type BookingDepositInfo, BookingDetails, type BookingDetailsProps, BookingForm, type BookingFormProps, type BookingFormValues, BookingOtpEmail, type BookingOtpEmailProps, BookingShell, type BookingShellProps, type BookingStatus, type BookingSummaryLineItem, type BookingTraveller, Button, type ButtonProps, COUNTRIES, type ConfirmationAdventure, type ConfirmationDepositInfo, type ConfirmationLineItem, type ConfirmationTraveller, CounterField, type CounterFieldProps, type CountryOption, CountrySearchField, type CountrySearchFieldProps, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, DatePickerField, type DatePickerFieldProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, type EmailTokens, type FilterGroup, type FilterItem, FilterPanel, type FilterPanelProps, FloatingInput, type FloatingInputProps, FloatingSelect, type FloatingSelectProps, Itinerary, type ItineraryProps, type ItineraryRoute, type ItineraryStop, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, type LeadCapturePopupConfig, MenuTrip, type MenuTripProps, type MenuTripSection, type MenuTripVariant, OTPCodeInput, type OTPCodeInputProps, Offer, OfferAdventureCard, type OfferAdventureItem, type OfferAgentInfo, type OfferDepositInfo, type OfferOptionalItem, type OfferProps, type OfferSummaryLineItem, PaymentAmountSelector, type PaymentAmountSelectorProps, type PaymentMethodOption, PaymentMethodSelector, type PaymentMethodSelectorProps, PaymentModalShell, type PaymentModalShellProps, PhoneCountrySelect, PhotoGallery, type PhotoGalleryPhoto, type PhotoGalleryProps, type PhotoGalleryVariant, type PricingOption, PricingTrip, type PricingTripProps, type PricingTripVariant, type RegistrationAdventure, type RegistrationBooking, type RegistrationEmergencyContactValue, type RegistrationField, type RegistrationFieldOption, type RegistrationFieldType, type RegistrationFieldValue, RegistrationForm, type RegistrationFormLabels, type RegistrationFormProps, type RegistrationFormValues, type RegistrationNameValue, type RegistrationPhoneValue, RegistrationSuccessCard, type RegistrationSuccessCardProps, type RegistrationTerms, type RegistrationTraveller, SiteHeader, type SiteHeaderLanguage, type SiteHeaderLink, type SiteHeaderProps, type SiteHeaderSubItem, type SiteHeaderVariant, type StripeAppearance, type SuggestedTraveller, TERMS_ACCEPT_KEY, TermsSection, type TermsSectionProps, ThemeToggle, Toast, type ToastProps, type ToastVariant, type TravellerFormConfig, type TravellerFormData, TravellerFormInviteEmail, type TravellerFormInviteEmailLabels, type TravellerFormInviteEmailProps, type TravellerFormInviteLink, type TravellerFormLabels, TripCard, type TripCardCta, type TripCardProps, type TripCardSize, type TripCardStatus, type TripDuration, type TripFaq, TripHeader, type TripHeaderProps, type TripHighlight, type TripInfoGroup, type TripItineraryStep, type TripMeetingPoint, TripPage, type TripPageProps, type TripPricingOption, type TripReview, buttonVariants, cn, emailTokens, getStripeAppearance, stripeAppearance, wrapEmailHtml };
package/dist/index.d.ts CHANGED
@@ -515,24 +515,23 @@ interface BookingConfirmationEmailProps {
515
515
  }
516
516
  declare function BookingConfirmationEmail({ recipientName, addTravellersUrl, logoUrl, bookingNumber, activity, adventure, startingDate, numberOfPeople, host, labels, className, }: BookingConfirmationEmailProps): react_jsx_runtime.JSX.Element;
517
517
 
518
- interface BookingOtpEmailLabels {
519
- bodyMessage: string;
520
- expiryMessage: string;
521
- logoAlt?: string;
522
- }
523
518
  interface BookingOtpEmailProps {
524
- /** Mensagem principal com código incluído (ex: "Seu código para reserva #42 é: 123456") */
525
- bodyMessage: string;
526
- /** Mensagem de expiração (ex: "Este código expira em breve.") */
519
+ /** Saudação (ex.: "Hello!" / "Olá!"). */
520
+ greeting: string;
521
+ /** Intro curta com bookingId embutido (ex.: "Here is your verification code for booking #42."). */
522
+ intro: string;
523
+ /** Código OTP renderizado em destaque. Não é sanitizado — passe só dígitos. */
524
+ code: string;
525
+ /** Mensagem de expiração (ex.: "This code expires shortly."). */
527
526
  expiryMessage: string;
528
- /** URL da logo. Default: data URI embutido no pacote. */
527
+ /** Assinatura do time (ex.: "PlanetaEXO Team"). */
528
+ teamSignature: string;
529
+ /** URL da logo. Default: data URI embutido. */
529
530
  logoUrl?: string;
530
- /** Labels opcionais para i18n (não usado diretamente — bodyMessage já é traduzida) */
531
- labels?: Partial<BookingOtpEmailLabels>;
532
- /** className extra no container (para uso no styleguide) */
531
+ /** className extra no container (uso no styleguide). */
533
532
  className?: string;
534
533
  }
535
- declare function BookingOtpEmail({ bodyMessage, expiryMessage, logoUrl, className, }: BookingOtpEmailProps): react_jsx_runtime.JSX.Element;
534
+ declare function BookingOtpEmail({ greeting, intro, code, expiryMessage, teamSignature, logoUrl, className, }: BookingOtpEmailProps): react_jsx_runtime.JSX.Element;
536
535
 
537
536
  interface TravellerFormInviteLink {
538
537
  adventureName?: string;
@@ -1623,4 +1622,4 @@ declare function LeadCapturePopup({ config: _config, }: {
1623
1622
  config: LeadCapturePopupConfig;
1624
1623
  }): react_jsx_runtime.JSX.Element | null;
1625
1624
 
1626
- export { ActivityCard, type ActivityCardProps, type ActivityCardSize, Alert, type AlertProps, type AlertVariant, BirthDateField, type BirthDateFieldProps, type BookingAdventure, BookingConfirmation, BookingConfirmationEmail, type BookingConfirmationEmailLabels, type BookingConfirmationEmailProps, type BookingConfirmationLabels, type BookingConfirmationProps, BookingConfirmedCard, type BookingConfirmedCardProps, type BookingContact, type BookingDepositInfo, BookingDetails, type BookingDetailsProps, BookingForm, type BookingFormProps, type BookingFormValues, BookingOtpEmail, type BookingOtpEmailLabels, type BookingOtpEmailProps, BookingShell, type BookingShellProps, type BookingStatus, type BookingSummaryLineItem, type BookingTraveller, Button, type ButtonProps, COUNTRIES, type ConfirmationAdventure, type ConfirmationDepositInfo, type ConfirmationLineItem, type ConfirmationTraveller, CounterField, type CounterFieldProps, type CountryOption, CountrySearchField, type CountrySearchFieldProps, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, DatePickerField, type DatePickerFieldProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, type EmailTokens, type FilterGroup, type FilterItem, FilterPanel, type FilterPanelProps, FloatingInput, type FloatingInputProps, FloatingSelect, type FloatingSelectProps, Itinerary, type ItineraryProps, type ItineraryRoute, type ItineraryStop, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, type LeadCapturePopupConfig, MenuTrip, type MenuTripProps, type MenuTripSection, type MenuTripVariant, OTPCodeInput, type OTPCodeInputProps, Offer, OfferAdventureCard, type OfferAdventureItem, type OfferAgentInfo, type OfferDepositInfo, type OfferOptionalItem, type OfferProps, type OfferSummaryLineItem, PaymentAmountSelector, type PaymentAmountSelectorProps, type PaymentMethodOption, PaymentMethodSelector, type PaymentMethodSelectorProps, PaymentModalShell, type PaymentModalShellProps, PhoneCountrySelect, PhotoGallery, type PhotoGalleryPhoto, type PhotoGalleryProps, type PhotoGalleryVariant, type PricingOption, PricingTrip, type PricingTripProps, type PricingTripVariant, type RegistrationAdventure, type RegistrationBooking, type RegistrationEmergencyContactValue, type RegistrationField, type RegistrationFieldOption, type RegistrationFieldType, type RegistrationFieldValue, RegistrationForm, type RegistrationFormLabels, type RegistrationFormProps, type RegistrationFormValues, type RegistrationNameValue, type RegistrationPhoneValue, RegistrationSuccessCard, type RegistrationSuccessCardProps, type RegistrationTerms, type RegistrationTraveller, SiteHeader, type SiteHeaderLanguage, type SiteHeaderLink, type SiteHeaderProps, type SiteHeaderSubItem, type SiteHeaderVariant, type StripeAppearance, type SuggestedTraveller, TERMS_ACCEPT_KEY, TermsSection, type TermsSectionProps, ThemeToggle, Toast, type ToastProps, type ToastVariant, type TravellerFormConfig, type TravellerFormData, TravellerFormInviteEmail, type TravellerFormInviteEmailLabels, type TravellerFormInviteEmailProps, type TravellerFormInviteLink, type TravellerFormLabels, TripCard, type TripCardCta, type TripCardProps, type TripCardSize, type TripCardStatus, type TripDuration, type TripFaq, TripHeader, type TripHeaderProps, type TripHighlight, type TripInfoGroup, type TripItineraryStep, type TripMeetingPoint, TripPage, type TripPageProps, type TripPricingOption, type TripReview, buttonVariants, cn, emailTokens, getStripeAppearance, stripeAppearance, wrapEmailHtml };
1625
+ export { ActivityCard, type ActivityCardProps, type ActivityCardSize, Alert, type AlertProps, type AlertVariant, BirthDateField, type BirthDateFieldProps, type BookingAdventure, BookingConfirmation, BookingConfirmationEmail, type BookingConfirmationEmailLabels, type BookingConfirmationEmailProps, type BookingConfirmationLabels, type BookingConfirmationProps, BookingConfirmedCard, type BookingConfirmedCardProps, type BookingContact, type BookingDepositInfo, BookingDetails, type BookingDetailsProps, BookingForm, type BookingFormProps, type BookingFormValues, BookingOtpEmail, type BookingOtpEmailProps, BookingShell, type BookingShellProps, type BookingStatus, type BookingSummaryLineItem, type BookingTraveller, Button, type ButtonProps, COUNTRIES, type ConfirmationAdventure, type ConfirmationDepositInfo, type ConfirmationLineItem, type ConfirmationTraveller, CounterField, type CounterFieldProps, type CountryOption, CountrySearchField, type CountrySearchFieldProps, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, DatePickerField, type DatePickerFieldProps, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, type EmailTokens, type FilterGroup, type FilterItem, FilterPanel, type FilterPanelProps, FloatingInput, type FloatingInputProps, FloatingSelect, type FloatingSelectProps, Itinerary, type ItineraryProps, type ItineraryRoute, type ItineraryStop, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, type LeadCapturePopupConfig, MenuTrip, type MenuTripProps, type MenuTripSection, type MenuTripVariant, OTPCodeInput, type OTPCodeInputProps, Offer, OfferAdventureCard, type OfferAdventureItem, type OfferAgentInfo, type OfferDepositInfo, type OfferOptionalItem, type OfferProps, type OfferSummaryLineItem, PaymentAmountSelector, type PaymentAmountSelectorProps, type PaymentMethodOption, PaymentMethodSelector, type PaymentMethodSelectorProps, PaymentModalShell, type PaymentModalShellProps, PhoneCountrySelect, PhotoGallery, type PhotoGalleryPhoto, type PhotoGalleryProps, type PhotoGalleryVariant, type PricingOption, PricingTrip, type PricingTripProps, type PricingTripVariant, type RegistrationAdventure, type RegistrationBooking, type RegistrationEmergencyContactValue, type RegistrationField, type RegistrationFieldOption, type RegistrationFieldType, type RegistrationFieldValue, RegistrationForm, type RegistrationFormLabels, type RegistrationFormProps, type RegistrationFormValues, type RegistrationNameValue, type RegistrationPhoneValue, RegistrationSuccessCard, type RegistrationSuccessCardProps, type RegistrationTerms, type RegistrationTraveller, SiteHeader, type SiteHeaderLanguage, type SiteHeaderLink, type SiteHeaderProps, type SiteHeaderSubItem, type SiteHeaderVariant, type StripeAppearance, type SuggestedTraveller, TERMS_ACCEPT_KEY, TermsSection, type TermsSectionProps, ThemeToggle, Toast, type ToastProps, type ToastVariant, type TravellerFormConfig, type TravellerFormData, TravellerFormInviteEmail, type TravellerFormInviteEmailLabels, type TravellerFormInviteEmailProps, type TravellerFormInviteLink, type TravellerFormLabels, TripCard, type TripCardCta, type TripCardProps, type TripCardSize, type TripCardStatus, type TripDuration, type TripFaq, TripHeader, type TripHeaderProps, type TripHighlight, type TripInfoGroup, type TripItineraryStep, type TripMeetingPoint, TripPage, type TripPageProps, type TripPricingOption, type TripReview, buttonVariants, cn, emailTokens, getStripeAppearance, stripeAppearance, wrapEmailHtml };
package/dist/index.js CHANGED
@@ -3873,8 +3873,11 @@ function BookingConfirmationEmail({
3873
3873
  );
3874
3874
  }
3875
3875
  function BookingOtpEmail({
3876
- bodyMessage,
3876
+ greeting,
3877
+ intro,
3878
+ code,
3877
3879
  expiryMessage,
3880
+ teamSignature,
3878
3881
  logoUrl,
3879
3882
  className
3880
3883
  }) {
@@ -3894,15 +3897,44 @@ function BookingOtpEmail({
3894
3897
  className,
3895
3898
  children: [
3896
3899
  /* @__PURE__ */ jsx(EmailLogo, { src: logoUrl }),
3900
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "16px", lineHeight: "1.5", margin: "0 0 12px" }, children: greeting }),
3901
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "15px", lineHeight: "1.5", margin: "0 0 24px" }, children: intro }),
3897
3902
  /* @__PURE__ */ jsx(
3898
- "p",
3903
+ "table",
3899
3904
  {
3900
- style: {
3901
- fontSize: "16px",
3902
- lineHeight: "1.6",
3903
- margin: "0 0 16px"
3904
- },
3905
- children: bodyMessage
3905
+ role: "presentation",
3906
+ cellPadding: 0,
3907
+ cellSpacing: 0,
3908
+ border: 0,
3909
+ style: { width: "100%", borderCollapse: "collapse", margin: "0 0 24px" },
3910
+ children: /* @__PURE__ */ jsx("tbody", { children: /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx(
3911
+ "td",
3912
+ {
3913
+ align: "center",
3914
+ style: {
3915
+ backgroundColor: emailTokens.primaryLight,
3916
+ border: `1px solid ${emailTokens.border}`,
3917
+ borderRadius: "12px",
3918
+ padding: "24px 16px"
3919
+ },
3920
+ children: /* @__PURE__ */ jsx(
3921
+ "div",
3922
+ {
3923
+ style: {
3924
+ fontFamily: emailTokens.fontFamily,
3925
+ fontSize: "36px",
3926
+ fontWeight: 700,
3927
+ letterSpacing: "0.3em",
3928
+ color: emailTokens.foreground,
3929
+ lineHeight: 1,
3930
+ // Padding esquerdo compensa letter-spacing final, mantendo visualmente centralizado.
3931
+ paddingLeft: "0.3em"
3932
+ },
3933
+ children: code
3934
+ }
3935
+ )
3936
+ }
3937
+ ) }) })
3906
3938
  }
3907
3939
  ),
3908
3940
  /* @__PURE__ */ jsx(
@@ -3912,11 +3944,12 @@ function BookingOtpEmail({
3912
3944
  color: emailTokens.mutedForeground,
3913
3945
  fontSize: "14px",
3914
3946
  lineHeight: "1.5",
3915
- margin: "0"
3947
+ margin: "0 0 24px"
3916
3948
  },
3917
3949
  children: expiryMessage
3918
3950
  }
3919
- )
3951
+ ),
3952
+ /* @__PURE__ */ jsx("p", { style: { fontSize: "14px", lineHeight: "1.5", margin: "0" }, children: teamSignature })
3920
3953
  ]
3921
3954
  }
3922
3955
  );
@@ -5642,66 +5675,19 @@ var OTPCodeInput = ({
5642
5675
  required
5643
5676
  }) => {
5644
5677
  const baseId = id != null ? id : React22.useId();
5645
- const inputRefs = React22.useRef([]);
5678
+ const inputRef = React22.useRef(null);
5679
+ const [focused, setFocused] = React22.useState(false);
5646
5680
  const digits = React22.useMemo(() => {
5647
5681
  const arr = value.split("").slice(0, length);
5648
5682
  while (arr.length < length) arr.push("");
5649
5683
  return arr;
5650
5684
  }, [value, length]);
5651
- const updateValue = (newDigits) => {
5652
- onChange(newDigits.join(""));
5653
- };
5654
- const focusedIndexRef = React22.useRef(0);
5655
- const focusSlot = (index) => {
5656
- var _a;
5657
- if (index >= 0 && index < length) {
5658
- (_a = inputRefs.current[index]) == null ? void 0 : _a.focus();
5659
- }
5660
- };
5661
- const handleChange = (index, raw) => {
5662
- const numeric = raw.replace(/\D/g, "");
5663
- if (!numeric) return;
5664
- const newDigits = [...digits];
5665
- newDigits[index] = numeric[numeric.length - 1];
5666
- updateValue(newDigits);
5667
- if (index < length - 1) {
5668
- focusSlot(index + 1);
5669
- }
5670
- };
5671
- const handleKeyDown = (index, e) => {
5672
- if (e.key === "Backspace") {
5673
- e.preventDefault();
5674
- const newDigits = [...digits];
5675
- if (newDigits[index]) {
5676
- newDigits[index] = "";
5677
- updateValue(newDigits);
5678
- } else if (index > 0) {
5679
- newDigits[index - 1] = "";
5680
- updateValue(newDigits);
5681
- focusSlot(index - 1);
5682
- }
5683
- } else if (e.key === "ArrowLeft") {
5684
- e.preventDefault();
5685
- focusSlot(index - 1);
5686
- } else if (e.key === "ArrowRight") {
5687
- e.preventDefault();
5688
- focusSlot(index + 1);
5689
- } else if (e.key === "Tab") ; else if (!/^\d$/.test(e.key) && e.key.length === 1) {
5690
- e.preventDefault();
5691
- }
5692
- };
5693
- const handlePaste = (e, startIndex) => {
5694
- e.preventDefault();
5695
- const pasted = e.clipboardData.getData("text").replace(/\D/g, "").slice(0, length);
5696
- if (!pasted) return;
5697
- const newDigits = [...digits];
5698
- for (let i = 0; i < pasted.length && startIndex + i < length; i++) {
5699
- newDigits[startIndex + i] = pasted[i];
5700
- }
5701
- updateValue(newDigits);
5702
- const lastFilled = Math.min(startIndex + pasted.length, length) - 1;
5703
- focusSlot(lastFilled < length - 1 ? lastFilled + 1 : lastFilled);
5685
+ const handleChange = (e) => {
5686
+ const numeric = e.target.value.replace(/\D/g, "").slice(0, length);
5687
+ onChange(numeric);
5704
5688
  };
5689
+ const activeIndex = Math.min(value.length, length - 1);
5690
+ const errorId = error ? `${baseId}-error` : void 0;
5705
5691
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center", className), children: [
5706
5692
  /* @__PURE__ */ jsx(
5707
5693
  "label",
@@ -5714,50 +5700,71 @@ var OTPCodeInput = ({
5714
5700
  children: label
5715
5701
  }
5716
5702
  ),
5717
- /* @__PURE__ */ jsx(
5703
+ /* @__PURE__ */ jsxs(
5718
5704
  "div",
5719
5705
  {
5720
5706
  className: cn(
5721
- "flex justify-center gap-2",
5707
+ "relative",
5722
5708
  disabled && "opacity-50 pointer-events-none"
5723
5709
  ),
5724
- role: "group",
5725
- "aria-label": label,
5726
- children: digits.map((digit, index) => /* @__PURE__ */ jsx(
5727
- "input",
5728
- {
5729
- ref: (el) => {
5730
- inputRefs.current[index] = el;
5731
- },
5732
- id: index === 0 ? baseId : `${baseId}-${index}`,
5733
- type: "text",
5734
- inputMode: "numeric",
5735
- pattern: "\\d*",
5736
- maxLength: 1,
5737
- value: digit,
5738
- autoComplete: index === 0 ? "one-time-code" : "off",
5739
- "aria-label": `${label} d\xEDgito ${index + 1} de ${length}`,
5740
- disabled,
5741
- onChange: (e) => handleChange(index, e.target.value),
5742
- onKeyDown: (e) => handleKeyDown(index, e),
5743
- onPaste: (e) => handlePaste(e, index),
5744
- onFocus: (e) => {
5745
- focusedIndexRef.current = index;
5746
- e.target.select();
5747
- },
5748
- className: cn(
5749
- "w-11 h-14 text-center text-lg rounded-lg border font-ui",
5750
- "bg-background text-foreground border-border",
5751
- "transition-colors",
5752
- "focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
5753
- error && "border-destructive focus:border-destructive focus:ring-destructive"
5754
- )
5755
- },
5756
- index
5757
- ))
5710
+ children: [
5711
+ /* @__PURE__ */ jsx(
5712
+ "input",
5713
+ {
5714
+ ref: inputRef,
5715
+ id: baseId,
5716
+ type: "text",
5717
+ inputMode: "numeric",
5718
+ pattern: "\\d*",
5719
+ maxLength: length,
5720
+ value,
5721
+ autoComplete: "one-time-code",
5722
+ "aria-label": label,
5723
+ "aria-describedby": errorId,
5724
+ "aria-invalid": !!error,
5725
+ disabled,
5726
+ required,
5727
+ onChange: handleChange,
5728
+ onFocus: () => setFocused(true),
5729
+ onBlur: () => setFocused(false),
5730
+ className: "absolute inset-0 w-full h-full opacity-0 cursor-text outline-none"
5731
+ }
5732
+ ),
5733
+ /* @__PURE__ */ jsx(
5734
+ "div",
5735
+ {
5736
+ className: "flex justify-center gap-2 pointer-events-none",
5737
+ role: "group",
5738
+ "aria-hidden": "true",
5739
+ children: digits.map((digit, i) => {
5740
+ const isActive = focused && i === activeIndex;
5741
+ return /* @__PURE__ */ jsx(
5742
+ "div",
5743
+ {
5744
+ className: cn(
5745
+ "w-11 h-14 flex items-center justify-center text-lg rounded-lg border font-ui",
5746
+ "bg-background text-foreground border-border transition-colors",
5747
+ isActive && "border-primary ring-1 ring-primary",
5748
+ error && "border-destructive"
5749
+ ),
5750
+ children: digit
5751
+ },
5752
+ i
5753
+ );
5754
+ })
5755
+ }
5756
+ )
5757
+ ]
5758
5758
  }
5759
5759
  ),
5760
- error && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-destructive font-ui self-start", children: error })
5760
+ error && /* @__PURE__ */ jsx(
5761
+ "p",
5762
+ {
5763
+ id: errorId,
5764
+ className: "mt-1 text-xs text-destructive font-ui self-start",
5765
+ children: error
5766
+ }
5767
+ )
5761
5768
  ] });
5762
5769
  };
5763
5770
  OTPCodeInput.displayName = "OTPCodeInput";