Moodinary/UI

Empty state

Cuando no hay nada todavía. Explicá por qué y dá un solo paso siguiente.

Explica por qué no hay contenido y propone un solo paso siguiente.

Instalación

shadcn
npx shadcn@latest add https://design.moodinary.com/r/empty.json
import
import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyScene, EmptyTitle } from "@moodinary/ui/components/empty";

Ejemplos

Sin datos todavía

La versión chica con ícono va dentro de secciones.

Todavía no hay acciones
Cuando un equipo necesite atención, registrá qué van a hacer para acompañarlo.
Código
actions.tsx
import { Button } from "@moodinary/ui/components/button";
import {
	Empty,
	EmptyContent,
	EmptyDescription,
	EmptyHeader,
	EmptyMedia,
	EmptyTitle,
} from "@moodinary/ui/components/empty";
import { PlusIcon } from "@moodinary/ui/components/icons";

export default function EmptyActions() {
	return (
		<Empty size="sm">
			<EmptyHeader>
				<EmptyMedia variant="icon">
					<PlusIcon />
				</EmptyMedia>
				<EmptyTitle>Todavía no hay acciones</EmptyTitle>
				<EmptyDescription>
					Cuando un equipo necesite atención, registrá qué van a hacer para
					acompañarlo.
				</EmptyDescription>
			</EmptyHeader>
			<EmptyContent>
				<Button render={<a href="/components/button" />} size="sm">
					<PlusIcon />
					Nueva acción
				</Button>
			</EmptyContent>
		</Empty>
	);
}

Mostrá la búsqueda y una forma de limpiarla.

Sin resultados para “Equipo Norte”
Revisá el nombre o probá con otro equipo.
Código
search.tsx
import { Button } from "@moodinary/ui/components/button";
import {
	Empty,
	EmptyContent,
	EmptyDescription,
	EmptyHeader,
	EmptyMedia,
	EmptyTitle,
} from "@moodinary/ui/components/empty";
import { SearchIcon } from "@moodinary/ui/components/icons";
import { Input } from "@moodinary/ui/components/input";
import { Label } from "@moodinary/ui/components/label";
import { useState } from "react";

export default function EmptySearch() {
	const [query, setQuery] = useState("Equipo Norte");
	return (
		<div className="grid w-full gap-3">
			<Label htmlFor="empty-query">Buscar equipo</Label>
			<Input
				id="empty-query"
				onChange={(event) => setQuery(event.target.value)}
				value={query}
			/>
			<Empty size="sm">
				<EmptyHeader>
					<EmptyMedia variant="icon">
						<SearchIcon />
					</EmptyMedia>
					<EmptyTitle>
						{query ? `Sin resultados para “${query}”` : "Buscá un equipo"}
					</EmptyTitle>
					<EmptyDescription>
						{query
							? "Revisá el nombre o probá con otro equipo."
							: "Escribí el nombre del equipo que querés encontrar."}
					</EmptyDescription>
				</EmptyHeader>
				{query ? (
					<EmptyContent>
						<Button onClick={() => setQuery("")} size="sm" variant="secondary">
							Limpiar búsqueda
						</Button>
					</EmptyContent>
				) : null}
			</Empty>
		</div>
	);
}

Con escena

La escena empty-chart acompaña el primer estado sin pulsos. En widgets y gráficos usá el vacío chico con ícono.

Todavía no hay pulsos
Compartí el código QR con tu comunidad para empezar a medir el clima emocional de la organización.
Código
scene.tsx
import { Button } from "@moodinary/ui/components/button";
import {
	Empty,
	EmptyContent,
	EmptyDescription,
	EmptyHeader,
	EmptyScene,
	EmptyTitle,
} from "@moodinary/ui/components/empty";
import { QrCodeIcon } from "@moodinary/ui/components/icons";

export default function EmptyWithScene() {
	return (
		<Empty className="py-20">
			<EmptyHeader>
				<EmptyScene scene="empty-chart" />
				<EmptyTitle>Todavía no hay pulsos</EmptyTitle>
				<EmptyDescription>
					Compartí el código QR con tu comunidad para empezar a medir el clima
					emocional de la organización.
				</EmptyDescription>
			</EmptyHeader>
			<EmptyContent>
				<Button
					render={<a href="/components/qr" />}
					size="sm"
					variant="secondary"
				>
					<QrCodeIcon aria-hidden className="size-4" />
					Generar QR
				</Button>
			</EmptyContent>
		</Empty>
	);
}

Props

Empty

PropTipoDefaultDescripción
size"default" | "sm""default"Escala del bloque.
classNamestring-Clases extra.

EmptyMedia

PropTipoDefaultDescripción
variant"default" | "icon""default"Fondo para el ícono.

EmptyScene

PropTipoDefaultDescripción
sceneSceneName"empty-chart"Escena pixel.

Cuándo sí y cuándo no

Hacé
  • Explicá por qué está vacío.
  • Ofrecé una sola acción.
  • Usá escena solo en un vacío principal.
Evitá
  • No culpes al usuario.
  • No pongas varias acciones primarias.
  • No uses escenas en tablas o gráficos.

Accesibilidad

  • El título resume el estado.
  • La acción usa texto concreto.
  • EmptyScene es decorativa; el título y la descripción explican el estado.