import 'rollup-plugin-inject-process-env'; import React, { FC } from "react"; import { FormStep, MultistepForm } from "stentor-models"; import { FormNextData, FormStepUpdateDisplay } from "."; /** * Shown on the step whose FORM_SUBMIT dispatch failed. That dispatch is the request * that creates the lead, so a silent failure loses it -- the user must be told rather * than left believing they submitted (issue #1373). */ export declare const SUBMIT_ERROR_MESSAGE = "We couldn't submit your information. Please check your connection and try again."; /** * How long the handoff step waits for the FORM_SUBMIT response before injecting the partner * script with only the static config. * * The handoff is reached by a submit, and FormWidget dispatches FORM_SUBMIT fire-and-forget so the * UI is not blocked -- the step goes active before the response lands. The per-submission values * (zipCode, name, trade) only exist in that response, and a partner script that reads its config * global once at load will never see them if we inject first. CostGuide does exactly that: it read * the static config, found no zip, and asked the visitor for one we already had. * * Waiting is bounded so a failed or slow submit still reaches the partner's form. That is degraded * -- no prefill -- rather than broken. */ export declare const EXTERNAL_WIDGET_CONFIG_WAIT_MS = 5000; /** * Extended FormStep interface to support additional per-step properties not yet in stentor-models. */ export interface ExtendedFormStep extends FormStep { /** * If true, shows a browser warning dialog when the user attempts to leave the page. * Useful for confirmation steps where the user hasn't submitted yet. */ warnBeforeUnload?: boolean; /** * Optional message to display in a visual warning banner. * The browser's beforeunload dialog will show a generic message (browsers ignore custom messages for security). * This message is displayed in a yellow warning banner for better visibility, especially on mobile. */ warnBeforeUnloadMessage?: string; /** * When true, fires a FORM_NEXT server callback before advancing past this step. * The server can return a FORM_STEP_UPDATE display to dynamically replace the next step's fields. * If the call fails or exceeds 3 seconds, the widget proceeds with the existing client-side fields. */ serverCallback?: boolean; } export interface FormDisplayProps { readonly form: MultistepForm; readonly loading: boolean; /** * Zero-based step to open on, instead of the first. * * For previews that want to show a particular step -- the booking preview on * get.xapp.ai opens on the date and time step, because the calendar is the * part worth showing. Applied once, when the form first arrives with steps, * so navigating away from it sticks. An index the form has no step for is * ignored and the form opens where it always would. */ readonly initialStep?: number; /** * Open the date/time step on the soonest day that has times, rather than on * "Select a date to see the available times." * * For a preview that lands straight on that step: an empty column beside a * calendar reads as a form with nothing to offer. Off by default -- on a real * booking page a preselected date is one the customer never chose. */ readonly preselectFirstAvailableDate?: boolean; /** * Fired with the step index when {@link FormDisplayProps.initialStep} is * actually applied, and not at all when it is ignored. * * FormWidget keeps its own `currentStepRef` and only ever writes it from the * next/previous tracking callbacks, so a form that jumps straight to a step * without saying so leaves that ref on 0 -- and every abandonment path (close, * the beforeunload beacon, the tab-hidden timeout) reads it for lastStepIndex * and completionPercentage. This keeps the two in step. */ onTrackInitialStep?: (stepIndex: number) => void; /** * Dispatches the form action. For FORM_SUBMIT this is the request that creates the * lead, so the returned promise is awaited and a rejection is surfaced to the user * -- see onSubmitForm. Implementations that return void keep the old fire-and-forget * behaviour. */ onActionResponse(data: unknown, action: string): void | Promise; isShowCase?: boolean; /** * Callback to track next_step event */ onTrackNextStep?: (stepName: string, stepIndex: number, stepData: Record, isLastStep: boolean) => void; /** * Callback to track previous_step event */ onTrackPreviousStep?: (fromStepName: string, fromStepIndex: number, toStepName: string, toStepIndex: number) => void; /** * Callback to track submit event */ onTrackSubmit?: (stepName: string, stepIndex: number, completedData: Record, totalSteps: number) => void; /** * Callback to track a FORM_SUBMIT dispatch that failed outright. onTrackSubmit fires * on a different endpoint before the dispatch, so without this a lost lead leaves a * submit event behind and no counter-signal at all. */ onTrackSubmitFailure?: (stepName: string, stepIndex: number, totalSteps: number, reason: string) => void; /** * Ref to sync current step data for tracking purposes */ currentStepDataRef?: React.MutableRefObject>; /** * When provided, fires a FORM_NEXT request before advancing to the next step. * The server can return a FORM_STEP_UPDATE display to replace the next step's fields. * If the call fails or exceeds 3 seconds, the widget proceeds with the existing fields. */ onFormNext?: (data: FormNextData) => Promise; /** * A FORM_STEP_UPDATE display extracted from the (fire-and-forget) FORM_SUBMIT * response, forwarded down from FormWidget. A new object reference triggers * applying the update to the named step's overrides -- see the effect below. */ stepUpdate?: FormStepUpdateDisplay; /** * Callback to track a booking-widget handoff step's anchor gaining content * within its render timeout */ onTrackHandoffRendered?: (stepName: string, provider: string) => void; /** * Callback to track a booking-widget handoff step's render timeout elapsing * with an empty anchor */ onTrackHandoffNoRender?: (stepName: string, provider: string) => void; /** * Callback to track the partner script invoking the configured success callback */ onTrackHandoffScheduled?: (stepName: string, provider: string, payload?: unknown) => void; /** * Callback to track a booking-widget handoff step's script failing to load */ onTrackHandoffError?: (stepName: string, provider: string) => void; } export declare const FormDisplay: FC;