# With progress

> Live import banner with a spinner and a progress bar.

A shadcn/ui block from the [@flx](https://ui.flexnative.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/flx/banner-14).

- Page, with a live preview: https://shadcn.exchange/r/flx/banner-14
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/flx/banner-14-light-9c7df7814d01dca8.png
- Registry item: https://ui.flexnative.com/r/banner-14.json
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://ui.flexnative.com/r/banner-14.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `button`, `progress`

## Files

### `registry/patterns/banner/banner-14.tsx`

```tsx
'use client'

import { useEffect, useState } from 'react'
import { CheckCircle2, Loader2, UploadCloud } from 'lucide-react'

import { Button } from '@/components/ui/button'
import { Progress } from '@/components/ui/progress'

export function Banner14() {
  const [value, setValue] = useState(12)

  useEffect(() => {
    if (value >= 100) return
    const timer = setTimeout(() => {
      setValue((prev) => Math.min(prev + 11, 100))
    }, 800)
    return () => clearTimeout(timer)
  }, [value])

  const done = value >= 100

  return (
    <div className="bg-card flex w-full flex-col gap-3 rounded-lg border px-4 py-3.5 shadow-sm">
      <div className="flex items-center gap-3">
        <span className="bg-primary/10 text-primary flex size-9 shrink-0 items-center justify-center rounded-full">
          {done ? (
            <CheckCircle2 className="size-5 text-emerald-600 dark:text-emerald-400" />
          ) : (
            <UploadCloud className="size-5" />
          )}
        </span>
        <div className="flex flex-1 flex-col gap-0.5">
          <p className="flex items-center gap-2 text-sm font-medium">
            {done ? 'Import complete' : 'Importing your data'}
            {!done && (
              <Loader2 className="text-muted-foreground size-3.5 animate-spin" />
            )}
          </p>
          <p className="text-muted-foreground text-sm">
            {done
              ? '1,284 records imported successfully.'
              : `Processing records — ${value}%`}
          </p>
        </div>
        {done && (
          <Button
            variant="outline"
            size="sm"
            onClick={() => setValue(12)}
            className="shrink-0"
          >
            Run again
          </Button>
        )}
      </div>
      <Progress value={value} className="h-1.5" />
    </div>
  )
}
```
