Introduction
Installation
Next.jsViteLaravelReact RouterRemixAstroTanStack StartTanStack RouterManual InstallationMCP
All componentsTheme
FieldFormInputText FieldTextareaSearch FieldInput OTPNumber FieldNumber FormatSliderCheckboxSwitchRadioSelectCombo BoxList BoxChoice BoxMulti SelectToken FieldNewTag FieldTag GroupCalendarDate FieldDate PickerDate Range PickerRange CalendarTime FieldColor PickerColor FieldColor AreaColor SliderColor SwatchColor Swatch PickerColor ThumbColor WheelDrop ZoneFile Trigger
ButtonButton GroupToggleToggle GroupPreskok Auth Button
EditorHeadingLinkTextKeyboard
CardContainerGrid ListResizableTableTreeSeparatorDescription ListScroll AreaShow MoreToolbar
BreadcrumbsNavbarPaginationTabsSidebar
DialogModalDrawerPopoverPreview TriggerNewSheetTooltipContext MenuDropdownCommandCommand MenuDisclosureMenu
ToastProgress BarProgress CircleMeterLoaderSkeletonNoteBadge
Chart (helpers)Area ChartBar ChartLine ChartPie ChartExperimental ChartsNewExperimental Radial ChartNewExperimental Radar ChartNewBar ListTracker
Async ImageAvatarCarouselPreskok Icon
Media

Async Image

Compound async image with lazy loading, skeleton placeholder, and error fallback.

View as MarkdownAsk ChatGPT

Installation

npx shadcn@latest add @preskok/async-image

Usage

Basic usage with default loading skeleton and error fallback:

import { AsyncImage } from "@/components/ui/preskok-ui/async-image"

export function AsyncImageExample() {
  return (
    <AsyncImage.Root
      src="https://example.com/image.jpg"
      alt="Description"
      width={300}
      height={200}
    />
  )
}

With custom slots:

<AsyncImage.Root src="/photo.jpg" alt="Photo" width={400} height={300}>
  <AsyncImage.Loading className="bg-muted flex items-center justify-center">
    <span>Loading...</span>
  </AsyncImage.Loading>
  <AsyncImage.Error>Failed to load image</AsyncImage.Error>
</AsyncImage.Root>

Disable lazy loading (load immediately):

<AsyncImage.Root
  src="/hero.jpg"
  alt="Hero"
  width={800}
  height={400}
  lazyLoad={false}
/>

Props

AsyncImage.Root

PropTypeDefaultDescription
srcstring—Image URL. Empty string triggers error state.
altstring""Accessible alt text for the image.
widthnumber | string—Width of the container and image.
heightnumber | string—Height of the container and image.
imgPropsOmit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "alt" | "width" | "height">—Props passed to the underlying <img> when loaded.
loadingDelayMsnumber0Optional delay in ms before transitioning from loading to loaded (e.g. to avoid flicker).
lazyLoadfalse | IntersectionObserverInit{ threshold: 0.01, rootMargin: "75%" }Lazy load when in view. Set to false to load immediately.
onLoadingEnd() => void—Called when the image has loaded successfully.
onErrorFallback() => void—Called when the image fails to load.
childrenReact.ReactNode—Optional compound slots: AsyncImage.Loading, AsyncImage.Error, AsyncImage.Content.

All other div props (e.g. className, style) are forwarded to the root container.

Slots

  • AsyncImage.Loading — Rendered while status === "loading". Default: skeleton placeholder.
  • AsyncImage.Error — Rendered when status === "error". Default: icon + "Image unavailable".
  • AsyncImage.Content — Rendered when status === "loaded". Default: the <img> element. Override to customize the loaded image element.

Tracker

Visualize data over time with tooltips.

Avatar

User avatar component with images or initials, sizes, and square/round styles.

On this page

Installation
Usage
Props
AsyncImage.Root
Slots

Default (skeleton to image, lazy-loaded)

Custom loading slot

Loading...

Error fallback (invalid src)

Grid (lazy load as you scroll)