KQ-1765 · BEFORE/YOU/SEND

Before You Send

A contact form that searches the help articles as the subject is typed and slides the matches up between the subject and the rest of the form: the panel's measured height opens on springs.glide, each answer rises 8px in cascade order and its relevance bar grows on glide a beat later, and a changing query re-ranks them in place on glide. Choosing one opens it in the panel, and This solved it folds the form down to a thank-you on glide — a ring landing on springs.recoil, a check drawn on springs.flick — instead of a ticket. The subject is a combobox: Down and Up walk the answers, Enter opens one, Escape hides them, and a failed search never blocks Send.

KQ-1765 · BEFORE/YOU/SEND

Contact Fieldline support

We reply within a day. Answers show up as you type.

Topic

Might answer it

    type a subject · fieldline support

    Install

    One command — the source lands in your repo. Or copy it from the Code tab.

    $ pnpm dlx shadcn@latest add @kinetiq/before-you-send

    Props

    resultStyle
    "cards" | "rows" | "wash"
    default "cards"
    How the answers are drawn: a row of cards, hairline rows with a meter and percentage, or rows whose relevance is a wash behind the title.
    density
    "compact" | "cozy" | "roomy"
    default "cozy"
    Control heights, type and gaps.
    accent
    "cobalt" | "jade" | "amber" | "mono"
    default "cobalt"
    Relevance bars, the active answer, Send and the thank-you ring.
    articles
    HelpArticle[]
    default defaultHelpArticles
    The help articles searched: title, summary, steps, topic, keywords, read time and href.
    topics
    ContactTopic[]
    default defaultContactTopics
    The topics offered as a radiogroup above the subject.
    value / defaultValue
    ContactDraft / Partial<ContactDraft>
    default — / { topic: "billing", email: "jun@coldbrook.studio" }
    The draft (topic, subject, details, email), controlled or initial.
    onValueChange
    (draft: ContactDraft) => void
    default —
    Fires from every edit with the whole draft.
    onSearch
    (query, topic) => ArticleMatch[] | Promise<ArticleMatch[]> | void
    default —
    A settled search. Return matches to replace the built-in scoring; a rejection shows a quiet note and never blocks Send.
    onSolved
    (article: HelpArticle, query: string) => void
    default —
    This solved it was chosen: the form closes with a thank-you and nothing is sent.
    onSend
    (draft: ContactDraft) => { reference? } | Promise<{ reference? }> | void
    default —
    The form was sent after validation. A promise holds Send; resolve a reference to show it, reject to keep everything and offer Try again.
    onOpenArticle
    (article: HelpArticle) => void
    default —
    Full article was pressed in a preview.
    company
    string
    default "Fieldline"
    Whose support this is.
    responseTime
    string
    default "within a day"
    How soon a message is answered, in words.
    maxResults
    number
    default 3
    The most answers shown.
    minRelevance
    number
    default 0.25
    Answers below this relevance (0 to 1) are not shown.
    searchDelay
    number
    default 160
    Quiet time after typing before a search runs, ms.
    height
    number
    default 540
    The tallest the surface grows, px; past it the form scrolls inside.
    disabled
    boolean
    default false
    Nothing can be typed, chosen or sent.
    className
    string
    default —
    Classes for the outer surface.