"use client"
/**
* Design reference previews for the Ask Leo button family.
*
* Previews pass a no-op `onClick` so browsing the catalog does not open the
* real Ask Leo sidebar. The launcher keeps its live behavior because it is the
* shell's own control, mounted here rather than rebuilt.
*/
import * as React from "react"
import { AskLeoLauncher } from "@exxatdesignux/ui/components/shell/ask-leo-launcher"
import { cn } from "@/lib/utils"
import { AskLeoButton } from "@/components/ask-leo-button"
import { AskLeoShortcutKbds, useAskLeo } from "@/components/ask-leo-context"
import { Button } from "@/components/ui/button"
import { LeoIcon, type LeoIconMotionState } from "@/components/ui/leo-icon"
const noop = () => {}
function PreviewRow({
label,
children,
}: {
label: string
children: React.ReactNode
}) {
return (
{label}
{children}
)
}
export function AskLeoButtonSizePreview() {
return (
)
}
export function AskLeoButtonStarPreview() {
return (
)
}
export function AskLeoButtonIconOnlyPreview() {
return (
)
}
export function AskLeoButtonStatePreview() {
return (
)
}
export function AskLeoButtonRouteActionPreview() {
return (
)
}
const MOTION_STATES: { state: LeoIconMotionState; hint: string }[] = [
{ state: "rest", hint: "Still — chrome does not loop" },
{ state: "invited", hint: "Hover or focus, one-shot" },
{ state: "working", hint: "Loops while Leo answers" },
{ state: "answered", hint: "Resolution beat, one-shot" },
]
export function LeoMotionStatePreview() {
const [state, setState] = React.useState("rest")
// Bumped on every press so re-selecting the current state replays it —
// `invited` and `answered` are one-shots and hold their final frame.
const [replay, setReplay] = React.useState(0)
const active = MOTION_STATES.find(s => s.state === state)!
// Remounting is what replays the gesture: a fresh mount starts from
// `initial="rest"` and animates into `state`.
const runKey = `${state}-${replay}`
return (
{MOTION_STATES.map(({ state: value }) => (
))}
{active.hint}
)
}
/**
* The real control, not a rebuild of it. `AskLeoLauncher` is the launcher, so the
* preview shows the same markup, arrival, and wash the shell renders — the
* hand-assembled version this replaced could drift from the bar, and did.
*
* `introId={null}` is the one difference: the arrival replays whenever the
* preview mounts. In the shell a replay would be noise; on a page documenting the
* animation, one that finished before you scrolled to it documents nothing.
*/
function LauncherPreview({ showLabel }: { showLabel?: boolean }) {
const { open, busy, toggle } = useAskLeo()
return (
}
introId={null}
/>
)
}
export function AskLeoTogglePreview() {
return (