Components & Hooks
Complete API reference for all Ghostly React components and hooks.
<Ghostly>
The primary component. Wraps any content to display skeleton loaders while data is loading.
import { Ghostly } from '@ghostly-ui/react'Props
Prop
Type
Behavior
When loading={true}:
- Sets
data-ghostly="{animation}"on the wrapper element - Sets
aria-busy="true"for screen readers - Sets CSS custom properties for radius, speed, color, and shine
- All descendant text/media become skeleton blocks via CSS
When loading={false}:
- Removes all skeleton attributes
- Children render normally with zero overhead
- If
smoothis true, elements fade out gracefully
Examples
// Basic
<Ghostly loading={isLoading}>
<UserCard user={data} />
</Ghostly>
// All options
<Ghostly
loading={isLoading}
animation="pulse"
radius="lg"
speed="fast"
as="article"
smooth
>
<BlogPost post={data} />
</Ghostly>
// Custom colors via props (no CSS needed)
<Ghostly
loading={true}
color="hsl(260 30% 88%)"
shine="hsl(260 30% 94%)"
>
<HeroSection data={data} />
</Ghostly><GhostlyList>
Skeleton loader for lists and grids. Clones a template element N times during loading.
import { GhostlyList } from '@ghostly-ui/react'Props
Prop
Type
Example
// Basic grid
<GhostlyList
loading={isLoading}
count={8}
item={<ProductCard />}
className="grid grid-cols-2 gap-4 md:grid-cols-4"
>
{products?.map(p => <ProductCard key={p.id} product={p} />)}
</GhostlyList>
// Semantic list with custom colors
<GhostlyList
loading={isLoading}
count={5}
item={<TodoItem />}
as="ul"
color="hsl(200 50% 85%)"
className="space-y-2"
>
{todos?.map(t => <TodoItem key={t.id} todo={t} />)}
</GhostlyList><GhostlySuspense>
Suspense-powered skeleton loader. Automatically shows a skeleton of your fallback component while children are suspended. No manual loading state needed.
import { GhostlySuspense } from '@ghostly-ui/react'Props
Prop
Type
How it works
GhostlySuspense wraps React's <Suspense> and automatically:
- Renders your
fallbackcomponent inside<Ghostly loading={true}>as the Suspense fallback - When children resolve, shows them normally
This is the recommended approach for apps using React Server Components, use(), or any data-fetching library that integrates with Suspense.
Examples
// Basic — zero loading state management
<GhostlySuspense fallback={<ProductCard />}>
<AsyncProductCard id={123} />
</GhostlySuspense>
// With options
<GhostlySuspense
fallback={<UserProfile />}
animation="pulse"
radius="lg"
smooth
className="p-4"
>
<AsyncUserProfile userId={456} />
</GhostlySuspense>
// Multiple boundaries
<div className="grid grid-cols-2 gap-6">
<GhostlySuspense fallback={<Chart />} animation="shimmer">
<AsyncChart />
</GhostlySuspense>
<GhostlySuspense fallback={<Feed />} animation="wave">
<AsyncFeed />
</GhostlySuspense>
</div><GhostlyProvider>
Sets default configuration for all Ghostly descendants. Nested providers inherit from their parent — only override what you specify.
import { GhostlyProvider } from '@ghostly-ui/react'Props
Prop
Type
Priority: Instance props > Nearest GhostlyProvider > Parent GhostlyProvider > Built-in defaults
Nested providers
<GhostlyProvider animation="wave" radius="lg">
{/* animation="wave", radius="lg", speed="normal" */}
<GhostlyProvider speed="fast">
{/* animation="wave" (inherited), radius="lg" (inherited), speed="fast" */}
<App />
</GhostlyProvider>
</GhostlyProvider>useGhostly()
Hook to read the nearest Ghostly context and get spreadable skeleton props.
import { useGhostly } from '@ghostly-ui/react'Return value
Prop
Type
getGhostlyProps()
Returns an object you can spread onto any HTML element to apply skeleton styles manually — useful for custom components that don't use <Ghostly>.
function CustomSkeleton() {
const { loading, getGhostlyProps } = useGhostly()
return (
<div {...getGhostlyProps()}>
<h2>Title placeholder</h2>
<p>Description placeholder</p>
</div>
)
}
// Usage: inside a Ghostly or GhostlyProvider tree
<Ghostly loading={isLoading}>
<CustomSkeleton />
</Ghostly>The returned object contains:
data-ghostly— animation value (only when loading)aria-busy— true (only when loading)aria-live— "polite" (always)style— CSS variables for radius and speed (only when loading)
Types
All types are exported from both @ghostly-ui/core and @ghostly-ui/react.
type GhostlyAnimation = 'shimmer' | 'pulse' | 'wave' | 'none'
type GhostlyRadius = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'full'
type GhostlySpeed = 'slow' | 'normal' | 'fast'
interface GhostlyConfig {
animation?: GhostlyAnimation
radius?: GhostlyRadius
speed?: GhostlySpeed
color?: string // Custom skeleton base color
shine?: string // Custom shimmer highlight color
}Radius values
| Prop | CSS Output |
|---|---|
none | 0px |
xs | 2px |
sm | 4px |
md | 8px |
lg | 12px |
full | 9999px |
Speed values
| Prop | CSS Output |
|---|---|
slow | 2s |
normal | 1.5s |
fast | 0.8s |