Обзор
Компоненты
- Accordion
- Alert
- Alert Dialog
- Autocomplete
- Auth Surface
- Avatar
- Badge
- Browse Catalog Dialog
- Button
- Card
- Checkbox
- Checkbox Group
- Collapsible
- Combobox
- Command
- Connector Setup Dialog
- Cookie Banner
- Dialog
- Directory Card
- Directory Detail
- Directory Skeleton
- DrawerНовое
- Token Parts Input
- Empty
- Field
- Fieldset
- File Preview Modal
- File Preview Skeleton
- Form
- Frame
- Group
- Icon
- Input
- Input Group
- Kbd
- Label
- Legal Shell
- Menu
- Mermaid Diagram
- Mind Map Diagram
- Not Found Screen
- Onboarding Frame
- Popover
- PDF Thumbnail
- Personalization Landing
- Preview Card
- Pricing Page
- Progress
- Radio Group
- Ring Spinner
- Scroll Area
- Select
- Separator
- Settings Page
- Settings Skills
- Settings Connectors
- Settings Capabilities
- Settings Usage
- Settings Account
- Settings Billing
- Sheet
- Sidebar
- Skeleton
- Skill Create Dialog
- Slider
- Spinner
- Stat
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Tooltip
AI-компоненты
- Компоненты AI
- Chat Conversation
- Chat Message
- Chat Response
- Chat Suggestion
- Chat Prompt Input
- Slash Highlighted Textarea
- Chat Search Dialog
- Chat Skill Doc
- Chat Connector Detail
- Chat Attachments
- Chat File Card
- Chat Token Chip
- Chat Code Block
- Chat Image
- Chat Inline Citation
- Chat Sources
- Chat Web Search
- Chat Research
- Chat Source
- Chat Actions
- Chat Context
- Chat Loader
- Chat Compaction
- Chat Timeline
- Chat Snippet
- Chat Terminal
- Chat Stack Trace
- Chat Test Results
- Chat File Tree
- Chat Environment Variables
- Chat Audio Player
- Chat Transcription
- Chat Speech Input
- Chat Mic Selector
- Chat Voice Selector
- Chat Agent
- Chat Persona
- Chat Connection
- Chat Connector Suggestion
- Chat Queue
- Chat Checkpoint
- Chat Confirmation
- Chat Artifact
- Chat JSX Preview
- Chat Schema Display
- Chat Package Info
- Chat Commit
- Chat Plan
- Chat Open In Chat
- Chat Sandbox
- Chat Model Selector
- Chat Canvas
- Chat Node
- Chat Edge
Ресурсы
Skeleton
Скелетон состояния загрузки для ваших компонентов.
"use client";
import { IconUserPlus, IconUsersGroup } from "@tabler/icons-react";
import { useEffect, useState } from "react";
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "@/components/ui/avatar";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
const users = [
{
delay: 3000,
fallback: "SJ",
followers: "15k",
image:
"https://images.unsplash.com/photo-1494790108377-be9c29b29330?w=80&h=80&dpr=2&q=80",
name: "Сара Джонсон",
role: "Дизайн-инженер",
},
{
delay: 4000,
fallback: "MA",
followers: "8k",
image:
"https://images.unsplash.com/photo-1543610892-0b1f7e6d8ac1?w=80&h=80&dpr=2&q=80",
name: "Марк Беннетт Андерссон",
role: "Продуктовый дизайнер",
},
{
delay: 3400,
fallback: "AR",
followers: "12k",
image:
"https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=80&h=80&dpr=2&q=80",
name: "Алекс Ривера",
role: "UI/UX-дизайнер",
},
];
function UserCard({ delay, user }: { delay: number; user: (typeof users)[0] }) {
const [isLoaded, setIsLoaded] = useState(false);
useEffect(() => {
const timer = setTimeout(() => {
setIsLoaded(true);
}, delay);
return () => clearTimeout(timer);
}, [delay]);
if (!isLoaded) {
return <UserCardSkeleton />;
}
return (
<>
<Avatar className="size-10">
<AvatarImage alt={user.name} src={user.image} />
<AvatarFallback>{user.fallback}</AvatarFallback>
</Avatar>
<div className="flex min-w-0 flex-1 flex-col gap-1">
<h4 className="line-clamp-1 font-medium text-sm">{user.name}</h4>
<div className="flex items-center gap-3 text-muted-foreground text-xs">
<span className="truncate">{user.role}</span>
<div className="flex min-w-0 items-center gap-1">
<IconUsersGroup className="size-3 shrink-0" stroke={1.5} />
<span className="truncate">
{user.followers}
<span className="max-sm:hidden"> подписчиков</span>
</span>
</div>
</div>
</div>
<Button size="xs">
<IconUserPlus stroke={1.5} />
Подписаться
</Button>
</>
);
}
function UserCardSkeleton() {
return (
<>
<Skeleton className="size-10 rounded-full" />
<div className="flex flex-1 flex-col">
<Skeleton className="my-0.5 h-4 max-w-54" />
<div className="flex max-w-54 items-center gap-1">
<Skeleton className="my-0.5 h-4 w-1/2" />
<Skeleton className="my-0.5 h-4 w-1/2" />
</div>
</div>
<Skeleton className="h-7 w-19 sm:h-6 sm:w-17" />
</>
);
}
export default function Particle() {
return (
<div className="flex w-full max-w-92 flex-col gap-6">
{users.map((user) => (
<div className="flex items-center gap-4" key={user.fallback}>
<UserCard delay={user.delay} user={user} />
</div>
))}
</div>
);
}
Установка
pnpm dlx shadcn@latest add @oracul/skeleton
Использование
import { Skeleton } from "@/components/ui/skeleton"<Skeleton className="size-10 rounded-full" />Справочник API
Это пользовательский компонент, а не обёртка Base UI.
Skeleton
Простой div с анимацией пульсации для состояний загрузки. Задавайте размер и форму через className.
Примеры
Только скелетон
import { Skeleton } from "@/components/ui/skeleton";
export default function Particle() {
return (
<div className="flex w-full max-w-92 items-center gap-4">
<Skeleton className="size-10 rounded-full" />
<div className="flex flex-1 flex-col">
<Skeleton className="my-0.5 h-4 max-w-54" />
<div className="flex max-w-54 items-center gap-1">
<Skeleton className="my-0.5 h-4 w-1/2" />
<Skeleton className="my-0.5 h-4 w-1/2" />
</div>
</div>
<Skeleton className="h-6 w-17" />
</div>
);
}