Preview
Nothing here yet
Your data will show up once available.
Nothing here yet
Your data will show up once available.
No results found
Try a different search or adjust your filters.
Inbox empty
You have no messages yet.
No favorites
You have nothing on your list yet.
Cart empty
Start adding items to enjoy shopping.
No notifications
You have no notifications yet. Please come back later.
No pictures
Capture new moments or upload your favorite images.
No connection
It looks like you're currently offline.
404
The page you're looking for can't be found.
Enable location
For personalized recommendations, please enable location services.
Something went wrong
Please try again in a moment.
Custom
Bring your own icon + copy.
No results found
Try a different search or adjust your filters.
Inbox empty
You have no messages yet.
Inbox empty
You have no messages yet.
Inbox empty
You have no messages yet.
Size xs
Same content across the size axis.
Size s
Same content across the size axis.
Size m
Same content across the size axis.
Size l
Same content across the size axis.
Size mobile
Same content across the size axis.
Installation
Install the runtime packages:
pnpm add @oshon-ai/components @oshon-ai/tokens @oshon-ai/primitives
Or scaffold the component source directly into your codebase (shadcn-style):
pnpm dlx @oshon-ai/cli add emptystate
Wire the tokens into your Tailwind v4 stylesheet:
/* app/globals.css */ @import 'tailwindcss'; @import '@oshon-ai/tokens/css'; @import '@oshon-ai/tokens/tailwind';
New here? Walk through the full setup — prereqs, theming, your first render.
Usage
Import the component and render it. Every component supports the standard tier, size, and disabled props where applicable.
'use client';
import { EmptyState } from '@oshon-ai/components';
export default function Example() {
return <EmptyState />;
}Styling
Three layers of customization, in order of escape-hatch strength: className overrides → data-attribute targeting → CSS custom properties.
Passing Tailwind classes
Every Oshon component accepts a className prop merged AFTER the component's default classes. Use it to override spacing, color, or size without forking the component.
<EmptyState className="ring-2 ring-offset-2 ring-blue-500" />
Data attributes
Oshon components expose their internal state as data-oshon-* attributes so you can target them from CSS without coupling to internal class names. The most common attributes are listed below — see the component's source for the full set.
| Attribute | Values | Description |
|---|---|---|
data-oshon-size | xs · s · m · l · mobile | Visual size axis. Mirrors the `size` prop. |
data-oshon-tier | primary · secondary · tertiary | Visual emphasis tier (Button family). Mirrors the `tier` prop. |
data-oshon-state | enabled · active · error · disabled | Component surface state. Set automatically based on props. |
data-disabled | true · (omitted) | Set when `disabled` is true. Pair with `:disabled` CSS for native input components. |
data-state | open · closed · checked · unchecked · … | Radix-derived state for overlay components (Dialog, Tabs, Toggle, etc.). |
/* Target the secondary tier specifically */
[data-oshon-tier="secondary"] {
--oshon-color-primary-700: var(--my-brand-color);
}Interactive states
Every interactive component supports the standard CSS pseudo- classes plus Tailwind's state variants. Focus rings always use :focus-visible so keyboard users see them but mouse users don't.
:hover/hover:*— pointer hover:focus-visible/focus-visible:*— keyboard focus:active/active:*— pressed:disabled/disabled:*— set via thedisabledprop