import * as react_jsx_runtime from 'react/jsx-runtime'; import React$1 from 'react'; type ResponseMode = 'feedback' | 'vote' | 'poll' | 'nps'; type VoteType = 'up' | 'down'; interface GotchaUser { id?: string; [key: string]: string | number | boolean | null | undefined; } type Position = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'inline'; type Size = 'sm' | 'md' | 'lg'; type Theme = 'light' | 'dark' | 'auto' | 'custom'; type TouchBehavior = 'always-visible' | 'tap-to-reveal'; interface GotchaStyles { button?: React.CSSProperties; modal?: React.CSSProperties; input?: React.CSSProperties; submitButton?: React.CSSProperties; title?: React.CSSProperties; closeButton?: React.CSSProperties; starRating?: React.CSSProperties; star?: React.CSSProperties; voteButton?: React.CSSProperties; voteButtonSelected?: React.CSSProperties; pollOption?: React.CSSProperties; pollOptionSelected?: React.CSSProperties; npsButton?: React.CSSProperties; npsButtonSelected?: React.CSSProperties; npsLabels?: React.CSSProperties; successMessage?: React.CSSProperties; successIcon?: React.CSSProperties; errorMessage?: React.CSSProperties; bugFlag?: React.CSSProperties; backdrop?: React.CSSProperties; spinner?: React.CSSProperties; } interface SubmissionContext { url?: string; userAgent?: string; viewport?: { width: number; height: number; }; language?: string; timezone?: string; screenResolution?: { width: number; height: number; }; recentErrors?: Array<{ message: string; source?: string; timestamp: number; }>; } interface SubmitResponsePayload { elementId: string; mode: ResponseMode; content?: string; title?: string; rating?: number; vote?: VoteType; pollOptions?: string[]; pollSelected?: string[]; isBug?: boolean; screenshot?: string; user?: GotchaUser; userEmail?: string; context?: SubmissionContext; } interface GotchaResponse { id: string; status: 'created' | 'duplicate' | 'updated' | 'queued'; createdAt: string; results?: PollResults; /** Lets this browser amend the response for 24 hours (servers from October 2026) */ editToken?: string; } /** What the server reveals about an earlier answer: only that it exists, and when */ interface PreviousAnswer { createdAt: string; } interface PollResults { [option: string]: number; } interface GotchaError { code: ErrorCode; message: string; status: number; } type ErrorCode = 'INVALID_API_KEY' | 'ORIGIN_NOT_ALLOWED' | 'RATE_LIMITED' | 'QUOTA_EXCEEDED' | 'INVALID_REQUEST' | 'USER_NOT_FOUND' | 'INTERNAL_ERROR' | 'PARSE_ERROR'; interface ScoreData { elementId: string; averageRating: number | null; totalResponses: number; ratingCount: number; voteCount: { up: number; down: number; }; positiveRate: number | null; npsScore: number | null; } declare function getQueueLength(): number; interface GotchaThemeColors { primary: string; primaryHover: string; primaryText: string; background: string; backgroundGradient: string; surface: string; surfaceHover: string; text: string; textSecondary: string; textDisabled: string; border: string; borderFocus: string; success: string; successSurface: string; error: string; errorSurface: string; errorBorder: string; warning: string; warningActive: string; warningSurface: string; warningBorder: string; starFilled: string; starEmpty: string; voteUp: string; voteUpSurface: string; voteUpBorder: string; voteDown: string; voteDownSurface: string; voteDownBorder: string; npsColors: string[]; buttonBackground: string; buttonBackgroundHover: string; buttonBackgroundDisabled: string; buttonColor: string; buttonColorDisabled: string; buttonBorder: string; buttonShadow: string; backdropColor: string; closeButton: string; closeButtonHover: string; closeButtonBg: string; glassBackground: string; glassBorder: string; glassColor: string; glassShadow: string; glassHoverShadow: string; inputBackground: string; inputBackgroundFocus: string; inputBorder: string; inputBorderFocus: string; inputFocusRing: string; pollBorder: string; pollSelectedBorder: string; pollBackground: string; pollSelectedBackground: string; pollColor: string; pollSelectedColor: string; pollCheckBorder: string; pollCheckSelectedBorder: string; pollCheckSelectedBg: string; } interface GotchaThemeTypography { fontFamily: string; fontFamilyDisplay: string; fontSize: { xs: number; sm: number; md: number; lg: number; }; fontWeight: { normal: number; medium: number; semibold: number; bold: number; }; } interface GotchaThemeBorders { radius: { sm: number; md: number; lg: number; full: string; }; width: number; } interface GotchaThemeShadows { sm: string; md: string; lg: string; modal: string; button: string; } interface GotchaThemeAnimation { duration: { fast: string; normal: string; slow: string; }; easing: { default: string; spring: string; }; } interface GotchaThemeConfig { colors?: Partial; typography?: Partial; borders?: Partial; shadows?: Partial; animation?: Partial; } /** Create a custom theme by merging partial overrides onto a preset */ declare function createTheme(base: "light" | "dark", overrides: GotchaThemeConfig): GotchaThemeConfig; interface GotchaProviderProps { /** Your Gotcha API key */ apiKey: string; /** React children */ children: React$1.ReactNode; /** Override the API base URL (for testing/staging) */ baseUrl?: string; /** Enable debug logging */ debug?: boolean; /** Disable all Gotcha buttons globally */ disabled?: boolean; /** Default user metadata applied to all submissions */ defaultUser?: GotchaUser; /** * Default submitter email applied to all instances under this * provider. Per-instance `userEmail` prop wins when both are set. Used * by the dashboard to send "we shipped what you asked for" notify-back. */ defaultUserEmail?: string; /** Theme configuration overrides applied to all instances */ themeConfig?: GotchaThemeConfig; /** * Listen for window errors and attach the last 10 messages to each * submission as `context.recentErrors` (default: true). Set false to * install no listeners and send no error messages. */ captureErrors?: boolean; } declare function GotchaProvider({ apiKey, children, baseUrl, debug, disabled, defaultUser, defaultUserEmail, themeConfig, captureErrors, }: GotchaProviderProps): react_jsx_runtime.JSX.Element; interface GotchaProps { /** Unique identifier for this element */ elementId: string; /** User metadata for segmentation */ user?: GotchaUser; /** * Submitter's email address. When set, the dashboard can email the user * a "we shipped what you asked for" note when their feedback hits the * SHIPPED status. Pass only with explicit user consent — store no other * PII in this field. */ userEmail?: string; /** Feedback mode */ mode?: ResponseMode; /** Show the text input in feedback mode (default: true) */ showText?: boolean; /** Show the star rating in feedback mode (default: true) */ showRating?: boolean; /** Custom labels for vote buttons (default: Like/Dislike) */ voteLabels?: { up: string; down: string; }; /** Required if mode is 'poll' (2-6 options) */ options?: string[]; /** Allow selecting multiple options */ allowMultiple?: boolean; /** Custom NPS question (default: "How likely are you to recommend us?") */ npsQuestion?: string; /** Show follow-up textarea after score selection (default: true) */ npsFollowUp?: boolean; /** Placeholder for NPS follow-up textarea */ npsFollowUpPlaceholder?: string; /** Label for low end of NPS scale (default: "Not likely") */ npsLowLabel?: string; /** Label for high end of NPS scale (default: "Very likely") */ npsHighLabel?: string; /** Button position relative to parent */ position?: Position; /** Button size */ size?: Size; /** Color theme */ theme?: Theme; /** Custom style overrides */ customStyles?: GotchaStyles; /** Control visibility programmatically */ visible?: boolean; /** Only show when parent is hovered (default: true) */ showOnHover?: boolean; /** Mobile behavior (default: 'always-visible') */ touchBehavior?: TouchBehavior; /** * Render no floating button (default: false). The host opens the widget * with `useGotchaTrigger(elementId).open()`; the modal centres in the * viewport because there is no button to anchor to. */ headless?: boolean; /** * Path sent as `context.url` in place of `location.pathname`, e.g. a route * template like "/accounts/[id]" so real record IDs never leave the page. * The origin is still prepended. Default: the real pathname. */ contextPath?: string; /** Custom prompt text */ promptText?: string; /** Input placeholder text */ placeholder?: string; /** Submit button text */ submitText?: string; /** Post-submission message */ thankYouMessage?: string; /** * Permanent hint shown under the feedback textarea and linked to it with * `aria-describedby`, so it stays visible and is read by screen readers * after the placeholder disappears. Default: none. */ hintText?: string; /** Visible on-brand focus ring on the open button and modal fields (default: false) */ focusRing?: boolean; /** * Where focus lands when the modal opens. "input" focuses the feedback * textarea, falling back to the close button when there is none * (default: "close"). */ initialFocus?: "close" | "input"; /** * Keep text, rating, bug flag and screenshot when the modal is closed * without submitting, and restore them on reopen. Held in memory only; * cleared on submit (default: false). */ keepDraft?: boolean; /** * Show plain-English failure messages ("Couldn't connect. Check your * internet connection and try again.") instead of the raw error. * `onError` still receives the original error (default: false). */ plainErrors?: boolean; /** Show "Report an issue" toggle in feedback form (default: false) */ enableBugFlag?: boolean; /** Custom label for the bug flag toggle (default: "Report an issue") */ bugFlagLabel?: string; /** Label shown while the bug flag is on (default: "Reported as an issue") */ bugFlagActiveLabel?: string; /** Enable screenshot capture when bug flag is toggled (uses modern-screenshot, bundled — no extra install needed) */ enableScreenshot?: boolean; /** When true and user has already responded, show submitted state and allow review/edit instead of new submission */ onePerUser?: boolean; /** When onePerUser is true, allow a new submission after this many days. Has no effect without onePerUser. */ cooldownDays?: number; /** After submission, hide the widget for this many days (client-side, localStorage). * Independent of cooldownDays — the widget stays hidden for the full duration even if cooldown expires sooner. */ hideAfterSubmitDays?: number; /** Delay showing widget by N seconds after page load */ showAfterSeconds?: number; /** Show widget after user scrolls past this percentage (0-100) */ showAfterScrollPercent?: number; /** Show widget after user has visited N times (uses localStorage) */ showAfterVisits?: number; /** Show a follow-up question after low rating or negative vote */ followUp?: { /** Rating threshold (inclusive) — e.g., 2 means ratings 1-2 trigger follow-up */ ratingThreshold?: number; /** Also trigger on negative vote */ onNegativeVote?: boolean; /** The prompt text shown */ promptText: string; /** Placeholder for the follow-up textarea */ placeholder?: string; }; /** Enable entrance animations on the button and modal (default: true) */ animated?: boolean; /** Called after successful submission */ onSubmit?: (response: GotchaResponse) => void; /** Called when modal opens */ onOpen?: () => void; /** Called when the user closes the modal */ onClose?: () => void; /** * Called when the success screen closes itself after submitting. Not * called for user dismissal (that is `onClose`). Pass the same handler * to both to hear about every close. */ onAutoClose?: () => void; /** Called on error */ onError?: (error: GotchaError) => void; } declare function Gotcha({ elementId, user, userEmail, mode, showText, showRating, voteLabels, options, allowMultiple, npsQuestion, npsFollowUp, npsFollowUpPlaceholder, npsLowLabel, npsHighLabel, enableBugFlag, bugFlagLabel, bugFlagActiveLabel, enableScreenshot, onePerUser, cooldownDays, hideAfterSubmitDays, showAfterSeconds, showAfterScrollPercent, showAfterVisits, followUp, animated, position, size, theme, customStyles, visible, showOnHover, touchBehavior, headless, contextPath, promptText, placeholder, submitText, thankYouMessage, hintText, focusRing, initialFocus, keepDraft, plainErrors, onSubmit, onOpen, onClose, onAutoClose, onError, }: GotchaProps): react_jsx_runtime.JSX.Element | null; type ScoreVariant = 'stars' | 'number' | 'compact' | 'votes'; interface GotchaScoreProps { elementId: string; variant?: ScoreVariant; showCount?: boolean; size?: Size; theme?: Theme; refreshInterval?: number; style?: React$1.CSSProperties; } declare function GotchaScore({ elementId, variant, showCount, size, theme, refreshInterval, style, }: GotchaScoreProps): react_jsx_runtime.JSX.Element | null; /** * Hook to access Gotcha context * Must be used within a GotchaProvider */ declare function useGotcha(): { /** The API client for manual submissions */ client: { submitResponse(payload: Omit, options?: { contextPath?: string; }): Promise; checkExistingResponse(elementId: string, userId: string): Promise; updateResponse(id: string, payload: { content?: string; title?: string; rating?: number; vote?: VoteType; pollSelected?: string[]; }, auth?: string | { editToken?: string; userId?: string; }): Promise; getScore(elementId: string): Promise; flagAsBug(responseId: string, options?: { editToken?: string; }): Promise<{ ticketId: string; status: string; }>; flushQueue(): Promise; getQueueLength: typeof getQueueLength; getBaseUrl(): string; }; /** Whether Gotcha is globally disabled */ disabled: boolean; /** Default user metadata */ defaultUser: GotchaUser; /** Whether debug mode is enabled */ debug: boolean; /** Submit feedback programmatically */ submitFeedback: (payload: Omit, options?: { contextPath?: string; }) => Promise; /** Open a specific Gotcha modal by elementId */ openModal: (elementId: string) => void; /** Close the currently open modal */ closeModal: () => void; /** The currently open modal's elementId, or null */ activeModalId: string | null; }; /** * Hook to programmatically open/close a specific Gotcha widget. * The corresponding must be mounted for the modal to render. */ declare function useGotchaTrigger(elementId: string): { open: () => void; close: () => void; isOpen: boolean; }; export { Gotcha, type GotchaError, type GotchaProps, GotchaProvider, type GotchaProviderProps, type GotchaResponse, GotchaScore, type GotchaScoreProps, type GotchaStyles, type GotchaThemeConfig, type GotchaUser, type Position, type PreviousAnswer, type ResponseMode, type ScoreData, type Size, type SubmissionContext, type Theme, type TouchBehavior, type VoteType, createTheme, useGotcha, useGotchaTrigger };