Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions apps/docs/app/components/preview/ComponentPreview.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.hui-preview-container {
border: 1px solid var(--hui-color-border);
border-radius: var(--hui-radius-lg);
overflow: hidden;
background-color: var(--hui-color-background);
}

.hui-preview-content {
padding: var(--hui-spacing-6);
}

/* Fumadocs Tabs trigger cursor fix */
[role="tab"] {
cursor: pointer;
}
30 changes: 30 additions & 0 deletions apps/docs/app/components/preview/ComponentPreview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use client';

import { Suspense } from 'react';
import { demos } from './demo-registry';
import './ComponentPreview.css';

interface ComponentPreviewProps {
name: string;
}

export function ComponentPreview({ name }: ComponentPreviewProps) {
const Demo = demos[name];
if (!Demo) {
return (
<div className="hui-preview-container">
<p>Demo &quot;{name}&quot; not found.</p>
</div>
);
}

return (
<div className="hui-preview-container">
<div className="hui-root hui-preview-content">
<Suspense fallback={<div style={{ padding: '1rem' }}>Loading preview...</div>}>
<Demo />
</Suspense>
</div>
</div>
);
}
10 changes: 10 additions & 0 deletions apps/docs/app/components/preview/demo-registry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { type ComponentType, lazy } from 'react';

export const demos: Record<string, ComponentType> = {
'button-variants': lazy(() => import('./demos/button-variants')),
'card-demo': lazy(() => import('./demos/card-demo')),
'dialog-demo': lazy(() => import('./demos/dialog-demo')),
'input-demo': lazy(() => import('./demos/input-demo')),
'badge-demo': lazy(() => import('./demos/badge-demo')),
'tabs-demo': lazy(() => import('./demos/tabs-demo')),
};
14 changes: 14 additions & 0 deletions apps/docs/app/components/preview/demos/badge-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
'use client';

import { Badge } from '@hareru/ui';

export default function BadgeDemo() {
return (
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem' }}>
<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
</div>
);
}
23 changes: 23 additions & 0 deletions apps/docs/app/components/preview/demos/button-variants.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use client';

import { Button } from '@hareru/ui';

export default function ButtonVariantsDemo() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', alignItems: 'center' }}>
<Button>Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
</div>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.5rem', alignItems: 'center' }}>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
</div>
</div>
);
}
29 changes: 29 additions & 0 deletions apps/docs/app/components/preview/demos/card-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
'use client';

import {
Button,
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from '@hareru/ui';

export default function CardDemo() {
return (
<Card style={{ maxWidth: '24rem' }}>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description with supporting text.</CardDescription>
</CardHeader>
<CardContent>
<p>This is the main content area of the card component.</p>
</CardContent>
<CardFooter style={{ display: 'flex', gap: '0.5rem' }}>
<Button>Save</Button>
<Button variant="outline">Cancel</Button>
</CardFooter>
</Card>
);
}
38 changes: 38 additions & 0 deletions apps/docs/app/components/preview/demos/dialog-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
'use client';

import {
Button,
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@hareru/ui';

export default function DialogDemo() {
return (
<Dialog>
<DialogTrigger asChild>
<Button variant="outline">Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog Title</DialogTitle>
<DialogDescription>
This is a dialog description. It provides context for the dialog content.
</DialogDescription>
</DialogHeader>
<p>Dialog body content goes here.</p>
<DialogFooter>
<DialogClose asChild>
<Button variant="outline">Cancel</Button>
</DialogClose>
<Button>Confirm</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
18 changes: 18 additions & 0 deletions apps/docs/app/components/preview/demos/input-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use client';

import { Input, Label } from '@hareru/ui';

export default function InputDemo() {
return (
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem', maxWidth: '20rem' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem' }}>
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="you@example.com" />
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem' }}>
<Label htmlFor="disabled">Disabled</Label>
<Input id="disabled" placeholder="Disabled input" disabled />
</div>
</div>
);
}
24 changes: 24 additions & 0 deletions apps/docs/app/components/preview/demos/tabs-demo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use client';

import { Tabs, TabsContent, TabsList, TabsTrigger } from '@hareru/ui';

export default function TabsDemo() {
return (
<Tabs defaultValue="account" style={{ maxWidth: '24rem' }}>
<TabsList>
<TabsTrigger value="account">Account</TabsTrigger>
<TabsTrigger value="password">Password</TabsTrigger>
<TabsTrigger value="settings">Settings</TabsTrigger>
</TabsList>
<TabsContent value="account">
<p>Manage your account settings and preferences.</p>
</TabsContent>
<TabsContent value="password">
<p>Change your password and security options.</p>
</TabsContent>
<TabsContent value="settings">
<p>Configure application settings.</p>
</TabsContent>
</Tabs>
);
}
1 change: 1 addition & 0 deletions apps/docs/app/components/preview/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ComponentPreview } from './ComponentPreview';
12 changes: 11 additions & 1 deletion apps/docs/app/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ComponentPreview } from '@/app/components/preview';
import { RegistryA11y, RegistrySlots, RegistryStates } from '@/app/components/registry';
import { source } from '@/lib/source';
import { Tab, Tabs } from 'fumadocs-ui/components/tabs';
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from 'fumadocs-ui/layouts/notebook/page';
import defaultMdxComponents from 'fumadocs-ui/mdx';
import { notFound } from 'next/navigation';
Expand All @@ -20,7 +22,15 @@ export default async function Page(props: {
<DocsDescription>{page.data.description}</DocsDescription>
<DocsBody>
<MDX
components={{ ...defaultMdxComponents, RegistryStates, RegistryA11y, RegistrySlots }}
components={{
...defaultMdxComponents,
RegistryStates,
RegistryA11y,
RegistrySlots,
ComponentPreview,
Tabs,
Tab,
}}
/>
</DocsBody>
</DocsPage>
Expand Down
5 changes: 4 additions & 1 deletion apps/docs/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { RootProvider } from 'fumadocs-ui/provider/next';
import 'fumadocs-ui/style.css';
import '@hareru/tokens/css';
import '@hareru/ui/styles/components.layer.css';
import '@hareru/ui/styles/scope.css';
import type { ReactNode } from 'react';

export const metadata = {
Expand All @@ -20,7 +23,7 @@ export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<RootProvider>{children}</RootProvider>
<RootProvider theme={{ attribute: ['class', 'data-theme'] }}>{children}</RootProvider>
</body>
</html>
);
Expand Down
18 changes: 18 additions & 0 deletions apps/docs/content/docs/components/badge.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ description: Compact status label with semantic color variants.

**Category:** Data Display / Standalone

## Preview

<Tabs items={['Preview', 'Code']}>
<Tab value="Preview">
<ComponentPreview name="badge-demo" />
</Tab>
<Tab value="Code">
```tsx
import { Badge } from "@hareru/ui"

<Badge>Default</Badge>
<Badge variant="secondary">Secondary</Badge>
<Badge variant="destructive">Destructive</Badge>
<Badge variant="outline">Outline</Badge>
```
</Tab>
</Tabs>

## Import

```tsx
Expand Down
20 changes: 20 additions & 0 deletions apps/docs/content/docs/components/button.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,26 @@ description: Interactive button element with variant and size support via CVA.

**Category:** Form / Standalone

## Preview

<Tabs items={['Preview', 'Code']}>
<Tab value="Preview">
<ComponentPreview name="button-variants" />
</Tab>
<Tab value="Code">
```tsx
import { Button } from "@hareru/ui"

<Button>Default</Button>
<Button variant="secondary">Secondary</Button>
<Button variant="destructive">Destructive</Button>
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>
```
</Tab>
</Tabs>

## Import

```tsx
Expand Down
27 changes: 27 additions & 0 deletions apps/docs/content/docs/components/card.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,33 @@ description: Semantic content container using article, header, and footer HTML e

**Category:** Layout / Composite

## Preview

<Tabs items={['Preview', 'Code']}>
<Tab value="Preview">
<ComponentPreview name="card-demo" />
</Tab>
<Tab value="Code">
```tsx
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, Button } from "@hareru/ui"

<Card>
<CardHeader>
<CardTitle>Card Title</CardTitle>
<CardDescription>Card description with supporting text.</CardDescription>
</CardHeader>
<CardContent>
<p>Main content area of the card.</p>
</CardContent>
<CardFooter>
<Button>Save</Button>
<Button variant="outline">Cancel</Button>
</CardFooter>
</Card>
```
</Tab>
</Tabs>

## Import

```tsx
Expand Down
30 changes: 30 additions & 0 deletions apps/docs/content/docs/components/dialog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,36 @@ description: Accessible modal dialog built on Base UI Dialog primitives.

**Dependency:** `@base-ui-components/react/dialog`

## Preview

<Tabs items={['Preview', 'Code']}>
<Tab value="Preview">
<ComponentPreview name="dialog-demo" />
</Tab>
<Tab value="Code">
```tsx
import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, DialogClose, Button } from "@hareru/ui"

<Dialog>
<DialogTrigger asChild>
<Button variant="outline">Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Dialog Title</DialogTitle>
<DialogDescription>Dialog description text.</DialogDescription>
</DialogHeader>
<p>Dialog body content.</p>
<DialogFooter>
<DialogClose asChild><Button variant="outline">Cancel</Button></DialogClose>
<Button>Confirm</Button>
</DialogFooter>
</DialogContent>
</Dialog>
```
</Tab>
</Tabs>

## Import

```tsx
Expand Down
Loading
Loading