Estado vacío con acción
Estado vacío con explicación y acción principal conectable; la demo muestra una transición real a un proyecto de muestra.
Tu próxima idea empieza aquí
Crea tu primer proyecto para reunir notas, archivos y personas.
Código completo
Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.
"use client";
import { useState, type CSSProperties } from "react";
/** Estado vacío con acción. React + TypeScript, sin dependencias. Personaliza con variables --gcxv-*. */
export type BaseEstadoVacioProps = {
title?: string;
description?: string;
label?: string;
onAction?: () => void;
className?: string;
style?: CSSProperties;
};
const CSS = `
.gcxv-root { box-sizing: border-box; min-width: 0; max-width: 100%; color: var(--gcxv-fg, #202421); font: 400 15px/1.5 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
.gcxv-root *, .gcxv-root *::before, .gcxv-root *::after { box-sizing: border-box; }
.gcxv-root button, .gcxv-root input, .gcxv-root textarea, .gcxv-root select { font: inherit; }
.gcxv-root button, .gcxv-root a { -webkit-tap-highlight-color: transparent; }
.gcxv-root :focus-visible { outline: 2px solid var(--gcxv-accent, #25724b); outline-offset: 4px; }
.gcxv-root ::selection { background: var(--gcxv-accent, #25724b); color: #fff; }
.gcxv-root button:disabled { opacity: .5; cursor: not-allowed; }
.gcxv-root svg { flex-shrink: 0; }
@media (prefers-reduced-motion: reduce) { .gcxv-root *, .gcxv-root *::before, .gcxv-root *::after { animation: none !important; transition-duration: .01ms !important; scroll-behavior: auto !important; } }
.gcxv-root { width:420px; text-align:center; padding:32px 20px; }
.gcxv-symbol { color:#728468; margin:0 auto 20px; }
.gcxv-root h3 { font-size:25px; letter-spacing:-.02em; line-height:1.2; margin:0 0 12px; font-weight:600; }
.gcxv-root p { color:#5d6858; font-size:14px; margin:0 auto 24px; max-width:32ch; }
.gcxv-root button { min-height:44px; padding:10px 20px; background:var(--gcxv-accent,#355331); color:#fff; border:0; border-radius:7px; cursor:pointer; transition:background .2s; }
.gcxv-root button:hover { background:#243c21; }
.gcxv-status { position:absolute; width:1px; height:1px; clip-path:inset(50%); overflow:hidden; }`;
export function BaseEstadoVacio({
title = "Tu próxima idea empieza aquí",
description = "Crea tu primer proyecto para reunir notas, archivos y personas.",
label = "Crear proyecto",
onAction,
className = "",
style,
}: BaseEstadoVacioProps) {
const [created, setCreated] = useState(false);
return (
<div className={`gcxv-root ${className}`} style={style}>
<style>{CSS}</style>
<svg
className="gcxv-symbol"
width="64"
height="64"
viewBox="0 0 64 64"
fill="none"
stroke="currentColor"
strokeWidth="1.3"
aria-hidden="true"
>
<rect x="10" y="12" width="44" height="40" rx="5" />
<path d="M10 23h44M22 35h20M22 42h12" />
</svg>
<h3>{created ? "Proyecto de muestra creado" : title}</h3>
<p>
{created
? "Conecta onAction para abrir tu flujo de creación."
: description}
</p>
<button
type="button"
onClick={() => {
if (onAction) onAction();
else setCreated(!created);
}}
>
{created ? "Volver al estado vacío" : label}
</button>
<span role="status" className="gcxv-status">
{created ? "La demostración creó un proyecto de muestra." : ""}
</span>
</div>
);
}
Úsalo en tu proyecto
Instálalo con la CLI de shadcn.
npx shadcn@latest add https://www.gassierconsulting.com/r/base-estado-vacioEjemplo de uso de Estado vacío con acción
Después de copiar base-estado-vacio.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.
import { BaseEstadoVacio } from "./base-estado-vacio";
export default function Ejemplo() {
return <BaseEstadoVacio title="Ejemplo" />;
}Propiedades de BaseEstadoVacio
BaseEstadoVacio acepta 6 propiedades: todas son opcionales y tienen un valor por defecto, así que funciona sin configurar nada.
| Propiedad | Tipo | Descripción |
|---|---|---|
title? | string | Opcional. |
description? | string | Opcional. |
label? | string | Opcional. |
onAction? | () => void | Opcional. |
className? | string | Opcional. |
style? | CSSProperties | Opcional. |
Personaliza Estado vacío con acción con variables CSS
Define estas variables en el contenedor o en tu hoja de estilos para cambiar los colores sin tocar el componente. Si no las defines, se usa el valor por defecto.
| Variable | Valor por defecto |
|---|---|
--gcxv-fg | #202421 |
--gcxv-accent | #25724b |
Accesibilidad y rendimiento
El archivo tiene 79 líneas (3 KB) y no necesita @keyframes. Esto es lo que hace Estado vacío con acción por quien lo usa:
- Detecta prefers-reduced-motion y baja o quita el movimiento cuando la persona lo pide.
- Muestra un anillo de foco visible al navegar con teclado (:focus-visible).
- Declara roles ARIA para lectores de pantalla: status.
- Es un componente de cliente de Next.js: incluye la directiva "use client".