Marketing Showcase Blocks

Prompt Showcase

A self-playing prompt box React component for marketing pages. A glowing pill types out a prompt, a fake cursor glides in and clicks send, and a result card pops up, on loop, pausing on hover.

A "watch it run itself" showcase for product heroes and feature sections. You provide a script (each item is a prompt string plus the content of a result card) and the component performs it in order: a pill with a glowing border types the prompt out character by character with a blinking caret; then a fake cursor glides in from outside the bottom-right, clicks the send button, which squishes and turns into a small spinner; a result card springs up from below, holds for a while, fades out, and the next item begins. The component is display-only and cannot be typed into; it only plays while in view and pauses when the pointer hovers it.

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add prompt-showcase.en

New project or installation trouble? Start here →

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

40
0.6
2600
Active edited usageDefault props
<PromptShowcase/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

Installation

npx webberui@latest add https://webberui.com/r/prompt-showcase.en.json

Or, once registries are configured in components.json, install it as @webberui/prompt-showcase.

Usage

import { PromptShowcase } from "@/components/ui/prompt-showcase";

<PromptShowcase
  script={[
    {
      prompt: "幫我把這週的會議紀錄整理成三點重點",
      result: (
        <ol className="list-decimal pl-5">
          <li>官網改版延到 11 月中上線</li>
          <li>客服回覆時間目標縮短為 4 小時</li>
          <li>下週三前確認秋季活動預算</li>
        </ol>
      ),
    },
    {
      prompt: "為手作甜點店寫一句秋季新品標語",
      result: <p>「栗子落下的季節,甜一口剛剛好。」</p>,
      delayMs: 3200,
    },
  ]}
  placeholder="問小幫手任何事…"
/>

Props

PropTypeDefaultDescription
scriptPromptShowcaseItem[]—The script: each prompt/result pair is played in order
valuenumber—Controlled index of the current script item; when omitted the component manages it (uncontrolled)
defaultValuenumber0Starting script index in uncontrolled mode
onChange(index: number) => void—Called when moving to the next script item, with the new index
charMsnumber40Typing interval per character (ms)
delayMsnumber2600Default result card hold time (ms); a script item's delayMs overrides it
glownumber0.6Opacity of the outer glow layer (0–1)
loopbooleantrueWhether to start over after the last item; when false it stops on the last result
autoPlaybooleantrueWhether to auto-play; only plays while in view. When false the current item's full result is shown
pauseOnHoverbooleantruePause the show while the pointer hovers
placeholderstring"Ask anything…"Grey placeholder shown before typing starts
sendLabelstring"Send"Accessible name of the send button
labelstring"Prompt showcase"Accessible name of the whole showcase (figure)
classNamestring—Forwarded to the outer figure

PromptShowcaseItem

FieldTypeDefaultDescription
promptstring—Prompt text typed out character by character
resultReactNode—Content of the result card that pops up after sending
delayMsnumber—How long the result card stays (ms); falls back to the component's delayMs

How it works

  • One round: the pill rests for 300ms → the prompt is typed out (charMs per character) → a 250ms pause → the fake cursor glides to the send button over 600ms with cubic-bezier(0.23,1,0.32,1) → a 160ms click squish, and the send button shows a spinner for 400ms → the result card springs in (stiffness 320, damping 26) → it holds for delayMs → a 200ms fade-out, then the next item.
  • Typing splits characters with Array.from, so each CJK character is one step and emoji are never cut in half.
  • The glowing border registers an angle variable with CSS @property --wb-ps-angle, so keyframes can rotate the conic-gradient start angle; browsers without @property fall back to a static gradient border.
  • Override the look with CSS variables: --wb-ps-glow-1 (default #60a5fa), --wb-ps-glow-2 (default #a78bfa), --wb-ps-glow-period (one full rotation, default 3s) and --wb-ps-fade (text fade-out, default 200ms); the component also writes charMs to --wb-ps-char-ms for your own styles to reference.
  • The result area stacks invisible copies of every result in one grid cell to reserve the tallest height, so the layout never jumps while looping.
  • Pausing (hover or scrolling out of view) only halts the scheduler; on resume it continues from the current stage instead of retyping from the start.

Accessibility

  • The outer element is a figure with an aria-label (not role="img"), so the result card content stays readable by screen readers
  • The text being typed is hidden from assistive technology; the full prompt is provided as sr-only text, so it is not read out one character at a time
  • The result area is aria-live="polite", so each new result card is announced
  • The attachment icon, send button and fake cursor are decorative: aria-hidden and tabIndex={-1}, they never take focus and cannot be clicked; the pointer is only used to trigger pausing
  • When the user has reduce motion enabled at the system level, nothing is typed, the cursor does not move and the border does not rotate; the current item's full prompt and result card are shown directly, with no looping