Ir al contenido
Evaluar mi proyecto
Componentes · Componentes baseDisponible

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.

base-estado-vacio.tsx79 líneas
Descargar
"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.

terminal.sh1 líneas
npx shadcn@latest add https://www.gassierconsulting.com/r/base-estado-vacio

Ejemplo 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.

ejemplo.tsx5 líneas
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.

PropiedadTipoDescripción
title?stringOpcional.
description?stringOpcional.
label?stringOpcional.
onAction?() => voidOpcional.
className?stringOpcional.
style?CSSPropertiesOpcional.

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.

VariableValor 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".
Licencia
MIT
Dependencias
React >=18
Compatibilidad
React 18 y 19 · Next.js (componente de cliente)