Merged in fix/loy-514-fix-validation-tracking-in-signup-form (pull request #3445)
fix(LOY-514): Fix validation error tracking in SignupForm * Fix issue with form submit handling * Fix * Remove browser validation * Add automatic tracking of validatione rrors Approved-by: Rasmus Langvad Approved-by: Matilda Landström
This commit is contained in:
-2
@@ -146,7 +146,6 @@ export default function ChildInfoSelector({
|
||||
<div key={index} className={styles.childInfoContainer}>
|
||||
<div ref={ageSelectRef}>
|
||||
<Select
|
||||
isRequired
|
||||
items={ageList}
|
||||
name={ageFieldName}
|
||||
label={ageLabel}
|
||||
@@ -161,7 +160,6 @@ export default function ChildInfoSelector({
|
||||
<div ref={bedPrefSelectRef}>
|
||||
{child.age >= 0 ? (
|
||||
<Select
|
||||
isRequired
|
||||
items={getAvailableBeds(child.age)}
|
||||
name={bedFieldName}
|
||||
label={bedLabel}
|
||||
|
||||
@@ -85,7 +85,6 @@ export default function CountryCombobox({
|
||||
className={styles.select}
|
||||
data-testid={name}
|
||||
isDisabled={disabled}
|
||||
isRequired={Boolean(registerOptions?.required)}
|
||||
isInvalid={fieldState.invalid}
|
||||
name={name}
|
||||
onBlur={field.onBlur}
|
||||
|
||||
@@ -54,7 +54,6 @@ export default function CountrySelect({
|
||||
items={items}
|
||||
label={label}
|
||||
isDisabled={disabled}
|
||||
isRequired={Boolean(registerOptions?.required)}
|
||||
isInvalid={fieldState.invalid}
|
||||
name={name}
|
||||
onBlur={field.onBlur}
|
||||
|
||||
@@ -127,7 +127,6 @@ export default function DateSelect({
|
||||
label={labels.day}
|
||||
name={DateName.day}
|
||||
onSelectionChange={(key) => setValue(DateName.day, Number(key))}
|
||||
isRequired
|
||||
enableFiltering={isDesktop}
|
||||
isInvalid={fieldState.invalid}
|
||||
onBlur={field.onBlur}
|
||||
@@ -142,7 +141,6 @@ export default function DateSelect({
|
||||
label={labels.month}
|
||||
name={DateName.month}
|
||||
onSelectionChange={(key) => setValue(DateName.month, Number(key))}
|
||||
isRequired
|
||||
enableFiltering={isDesktop}
|
||||
isInvalid={fieldState.invalid}
|
||||
onBlur={field.onBlur}
|
||||
@@ -156,7 +154,6 @@ export default function DateSelect({
|
||||
label={labels.year}
|
||||
name={DateName.year}
|
||||
onSelectionChange={(key) => setValue(DateName.year, Number(key))}
|
||||
isRequired
|
||||
enableFiltering={isDesktop}
|
||||
isInvalid={fieldState.invalid}
|
||||
onBlur={field.onBlur}
|
||||
|
||||
@@ -78,7 +78,6 @@ export const FormInput = forwardRef<HTMLInputElement, FormInputProps>(
|
||||
isDisabled={isDisabled}
|
||||
isReadOnly={readOnly}
|
||||
isInvalid={fieldState.invalid}
|
||||
isRequired={!!registerOptions.required}
|
||||
>
|
||||
<Input
|
||||
{...props}
|
||||
|
||||
@@ -59,7 +59,6 @@ export const FormTextArea = forwardRef<HTMLTextAreaElement, FormTextAreaProps>(
|
||||
isDisabled={isDisabled}
|
||||
isReadOnly={readOnly}
|
||||
isInvalid={fieldState.invalid}
|
||||
isRequired={!!registerOptions.required}
|
||||
>
|
||||
<TextArea
|
||||
{...props}
|
||||
|
||||
@@ -131,7 +131,6 @@ export default function Phone({
|
||||
aria-label={ariaLabel}
|
||||
isDisabled={disabled || registerOptions.disabled}
|
||||
isInvalid={fieldState.invalid}
|
||||
isRequired={!!registerOptions?.required}
|
||||
name={name}
|
||||
type="tel"
|
||||
value={phoneNumber}
|
||||
|
||||
@@ -89,7 +89,6 @@ const InputComponent = forwardRef(function AriaInputWithLabelComponent(
|
||||
<AriaInput
|
||||
{...props}
|
||||
id={inputId}
|
||||
required={required}
|
||||
// Avoid duplicating label text in placeholder when label is positioned above
|
||||
// Screen readers would announce the label twice (once as label, once as placeholder)
|
||||
// Only use placeholder if explicitly provided, otherwise use empty string
|
||||
@@ -140,7 +139,6 @@ const InputComponent = forwardRef(function AriaInputWithLabelComponent(
|
||||
<AriaInput
|
||||
{...props}
|
||||
id={id}
|
||||
required={required}
|
||||
// For floating labels, only set placeholder if explicitly provided
|
||||
// The label itself acts as the placeholder, so we don't want to duplicate it
|
||||
// This ensures the label only floats when focused or has value
|
||||
|
||||
@@ -84,7 +84,6 @@ export const PasswordInput = ({
|
||||
aria-describedby={describedBy}
|
||||
isDisabled={field.disabled}
|
||||
isInvalid={fieldState.invalid}
|
||||
isRequired={!!registerOptions.required}
|
||||
name={field.name}
|
||||
onBlur={field.onBlur}
|
||||
onChange={field.onChange}
|
||||
|
||||
@@ -13,8 +13,11 @@ import {
|
||||
trackFormAbandonment,
|
||||
trackFormCompletion,
|
||||
trackFormInputStarted,
|
||||
trackFormValidationError,
|
||||
} from "./form"
|
||||
|
||||
import type { FieldErrors } from "react-hook-form"
|
||||
|
||||
export function useFormTracking<T extends FieldValues>(
|
||||
formType: FormType,
|
||||
subscribe: UseFormSubscribe<T>,
|
||||
@@ -66,6 +69,13 @@ export function useFormTracking<T extends FieldValues>(
|
||||
}
|
||||
}, [formStarted, formType, nameSuffix, formState.isValid])
|
||||
|
||||
useEffect(() => {
|
||||
if (formState.submitCount === 0) return
|
||||
if (formState.isValid) return
|
||||
|
||||
trackErrors(formState.errors, formType, nameSuffix)
|
||||
}, [formState.submitCount, formState.errors, formType, nameSuffix])
|
||||
|
||||
const trackFormSubmit = useCallback(() => {
|
||||
if (formState.isValid) {
|
||||
trackFormCompletion(formType, nameSuffix)
|
||||
@@ -76,3 +86,24 @@ export function useFormTracking<T extends FieldValues>(
|
||||
trackFormSubmit,
|
||||
}
|
||||
}
|
||||
|
||||
function trackErrors<T extends FieldValues>(
|
||||
errors: FieldErrors<T>,
|
||||
formType: FormType,
|
||||
nameSuffix: string
|
||||
) {
|
||||
const errorKeys = Object.getOwnPropertyNames(errors)
|
||||
|
||||
errorKeys.forEach((key) => {
|
||||
const msg = errors[key]?.message
|
||||
if (!msg) {
|
||||
// Handle nested errors
|
||||
trackErrors(errors[key] as FieldErrors<T>, formType, nameSuffix)
|
||||
return
|
||||
}
|
||||
|
||||
if (!msg || typeof msg !== "string") return
|
||||
|
||||
trackFormValidationError(formType, nameSuffix, msg)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user