KQ-917 · APPEAL/CARD

Appeal Card

A removed message asking for another look. The review's stages stamp in turn — the disc lands from 1.5 on recoil, the tick draws its pathLength on flick, and the rail down to the next stage fills on glide — and the decision slides in from 8px on snap inside a ResizeObserver-measured height that opens in flow rather than floating. Approval restores with a wash that sweeps the quote once on a slow tween while the strike lifts; a refusal gets no wash and no bounce. A real textarea sends the appeal, and a polite region speaks one frozen sentence per change, never before the host has answered.

KQ-917 · APPEAL/CARD

Appeal in Coldbrook

Removed

Rui Santos · removed under Room rule 3

Whoever packed this Waylight Pay box clearly could not care less about it.

  1. Step 1 of 3, appeal sent, waiting.
  2. Step 2 of 3, read by a moderator, waiting.
  3. Step 3 of 3, second moderator agrees, waiting.
Up to 180 characters.

Rui · step 0 of 3 · not sent

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/appeal-card

Props

author
string
default
Whose message is under appeal.
messageText
string
default
The removed line, quoted on the card.
room
string
default "Coldbrook"
The room the message was removed from.
reason
string
default "Room rule 3"
The house rule the removal cited.
steps
AppealStep[]
default
The review's stages: value, label and an optional note.
step / defaultStep
number
default 0
Controlled or initial count of stamped stages.
onStepChange
(step: number) => void
default
Fires when sending the appeal stamps the first stage.
note / defaultNote
string
default ""
Controlled or initial appeal note.
onNoteChange
(note: string) => void
default
Fires from every keystroke in the textarea.
onSubmit
(note: string) => void
default
Fires from Send appeal with the trimmed note.
maxLength
number
default 180
Cap on the note; the remainder reads beside the control.
decision
"pending" | "restored" | "upheld"
default "pending"
The outcome. Only the host sets it.
decisionNote
string
default
One line under the decision.
onDecisionShown
(decision: "restored" | "upheld") => void
default
Fires once when a decision first lands, after the state settles.
disabled
boolean
default false
Holds the textarea and the control.
className
string
default
Extra classes on the card.