Components
Skeleton
A pulsing placeholder for loading content. Purely presentational.
Installation
npx kosmesis add skeletonpnpm dlx kosmesis add skeletonyarn dlx kosmesis add skeletonbunx kosmesis add skeletonCopy and paste the following code into your project.
import { StatelessComponent } from "@praxisjs/core";import { Component } from "@praxisjs/decorators";import { cn } from "@/lib/utils";export interface SkeletonProps { class?: string; id?: string;}/** Purely presentational — no Morphos equivalent, same as upstream shadcn/ui. */@Component()export class Skeleton extends StatelessComponent<SkeletonProps> { render() { const { class: cls, id } = this.props; return <div id={id} data-slot="skeleton" class={cn("animate-pulse rounded-md bg-accent", cls)} />; }}Install the following dependencies:
npm install @praxisjs/csspnpm add @praxisjs/cssyarn add @praxisjs/cssbun add @praxisjs/cssCopy and paste the following code into your project.
import { StatelessComponent } from "@praxisjs/core";import { cx, keyframes, Stylesheet, Styled, tokenVars } from "@praxisjs/css";import { Component } from "@praxisjs/decorators";import { KosmesisTokens } from "@/lib/kosmesis-theme";const t = tokenVars(KosmesisTokens);/** `keyframes()` is content-hash-deduplicated, so calling this with the same definition in more than one file (see `spinner.tsx`) still injects a single shared `@keyframes` rule. */const pulse = keyframes("kosmesis-pulse", { "0%, 100%": { opacity: "1" }, "50%": { opacity: "0.5" } });class SkeletonStyles extends Stylesheet { $root = this.css({ borderRadius: `calc(${t.radius} - 2px)`, backgroundColor: t.accent, animation: `${pulse} 2s cubic-bezier(0.4, 0, 0.6, 1) infinite`, });}export interface SkeletonProps { class?: string; id?: string;}/** Purely presentational — no Morphos equivalent, same as upstream shadcn/ui. */@Component()export class Skeleton extends StatelessComponent<SkeletonProps> { @Styled(SkeletonStyles) $s!: SkeletonStyles; render() { const { class: cls, id } = this.props; return <div id={id} data-slot="skeleton" class={cx(this.$s.$root, cls)} />; }}Examples
Usage
import { Skeleton } from "@/components/ui/skeleton";
<div class="flex items-center gap-4">
<Skeleton class="size-12 rounded-full" />
<div class="flex flex-col gap-2">
<Skeleton class="h-4 w-48" />
<Skeleton class="h-4 w-32" />
</div>
</div>