Ir al contenido
Evaluar mi proyecto
Componentes · IADisponible

Tarjetas de sugerencias para empezar

Cuatro sugerencias con icono, descripción y flecha que aparece al apuntarlas; la elegida queda marcada con el acento azul.

¿En qué te ayudo hoy?

Código completo

Es exactamente el archivo que se descarga. Cópialo a tu proyecto y úsalo.

ai-sugerencias.tsx68 líneas
Descargar
"use client";

import { useState, type CSSProperties, type ReactNode } from "react";

/** Tarjetas de sugerencias para empezar una conversación con un asistente. Superficie oscura, bordes finos y un solo acento azul. React + TypeScript, sin dependencias. Personaliza con --gcai-*. */
export type AiSugerenciasItem = { id: string; title: string; hint: string; icon?: ReactNode };

export type AiSugerenciasProps = {
  title?: string;
  items?: AiSugerenciasItem[];
  onPick?: (item: AiSugerenciasItem) => void;
  className?: string;
  style?: CSSProperties;
};

const CSS = `
.gcaisg-root { box-sizing: border-box; width: 100%; max-width: 620px; color: var(--gcai-ink, #ededee); font: 400 15px/1.5 ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif; }
.gcaisg-root *, .gcaisg-root *::before, .gcaisg-root *::after { box-sizing: border-box; }
.gcaisg-root button { font: inherit; -webkit-tap-highlight-color: transparent; }
.gcaisg-root :focus-visible { outline: 2px solid var(--gcai-accent, #84b3ff); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) { .gcaisg-root * { transition-duration: .01ms !important; } }
.gcaisg-title { margin: 0 0 16px; font-size: 22px; font-weight: 600; letter-spacing: -.02em; }
.gcaisg-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.gcaisg-card { position: relative; display: grid; gap: 4px; align-content: start; min-height: 96px; padding: 14px 16px; text-align: left; color: inherit; border: 1px solid var(--gcai-line, #26272c); border-radius: 12px; background: var(--gcai-surface, #111113); cursor: pointer; transition: border-color .15s, background .15s; }
.gcaisg-card:hover { border-color: #3a3b42; background: #151518; }
.gcaisg-card[aria-pressed="true"] { border-color: var(--gcai-accent, #84b3ff); }
.gcaisg-ico { display: grid; place-items: center; width: 28px; height: 28px; margin-bottom: 6px; border-radius: 8px; background: var(--gcai-well, #1a1b1e); color: var(--gcai-accent, #84b3ff); }
.gcaisg-name { font-weight: 600; }
.gcaisg-hint { font-size: 13px; color: var(--gcai-muted, #9b9ca3); }
.gcaisg-arrow { position: absolute; right: 14px; top: 14px; color: var(--gcai-muted, #9b9ca3); opacity: 0; transform: translate(-4px, 4px); transition: opacity .15s, transform .2s cubic-bezier(.16, 1, .3, 1); }
.gcaisg-card:hover .gcaisg-arrow, .gcaisg-card:focus-visible .gcaisg-arrow { opacity: 1; transform: none; }
.gcaisg-status { min-height: 20px; margin: 12px 2px 0; font-size: 13px; color: var(--gcai-muted, #9b9ca3); }
@media (max-width: 520px) { .gcaisg-grid { grid-template-columns: 1fr; } }`;

const Icon = ({ d }: { d: string }) => (
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
    <path d={d} />
  </svg>
);

const DEFAULT_ITEMS: AiSugerenciasItem[] = [
  { id: "resumen", title: "Resume este documento", hint: "Puntos clave y decisiones pendientes", icon: <Icon d="M5 6h14M5 12h14M5 18h9" /> },
  { id: "correo", title: "Redacta una respuesta", hint: "En tono claro y directo", icon: <Icon d="M4 6h16v12H4zM4 7l8 6 8-6" /> },
  { id: "datos", title: "Analiza una tabla", hint: "Detecta tendencias y valores atípicos", icon: <Icon d="M5 20V10M12 20V4M19 20v-7" /> },
  { id: "codigo", title: "Revisa este código", hint: "Errores probables y mejoras", icon: <Icon d="m8 8-4 4 4 4M16 8l4 4-4 4M13.5 5l-3 14" /> },
];

export function AiSugerencias({ title = "¿En qué te ayudo hoy?", items = DEFAULT_ITEMS, onPick, className = "", style }: AiSugerenciasProps) {
  const [picked, setPicked] = useState<string | null>(null);
  return (
    <div className={`gcaisg-root ${className}`} style={style}>
      <style>{CSS}</style>
      <h2 className="gcaisg-title">{title}</h2>
      <div className="gcaisg-grid">
        {items.map((item) => (
          <button key={item.id} className="gcaisg-card" type="button" aria-pressed={picked === item.id} onClick={() => { setPicked(item.id); onPick?.(item); }}>
            <span className="gcaisg-ico" aria-hidden="true">{item.icon}</span>
            <span className="gcaisg-name">{item.title}</span>
            <span className="gcaisg-hint">{item.hint}</span>
            <svg className="gcaisg-arrow" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M7 17 17 7M8 7h9v9" /></svg>
          </button>
        ))}
      </div>
      <p className="gcaisg-status" role="status">{picked ? `Sugerencia elegida: ${items.find((item) => item.id === picked)?.title}.` : ""}</p>
    </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/ai-sugerencias

Ejemplo de uso de Tarjetas de sugerencias para empezar

Después de copiar ai-sugerencias.tsx a tu proyecto, impórtalo y colócalo donde lo necesites.

ejemplo.tsx5 líneas
import { AiSugerencias } from "./ai-sugerencias";

export default function Ejemplo() {
  return <AiSugerencias title="Ejemplo" />;
}

Propiedades de AiSugerencias

AiSugerencias acepta 5 propiedades: todas son opcionales y tienen un valor por defecto, así que funciona sin configurar nada.

PropiedadTipoDescripción
title?stringOpcional.
items?AiSugerenciasItem[]Opcional.
onPick?(item: AiSugerenciasItem) => voidOpcional.
className?stringOpcional.
style?CSSPropertiesOpcional.

Personaliza Tarjetas de sugerencias para empezar 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
--gcai-ink#ededee
--gcai-accent#84b3ff
--gcai-line#26272c
--gcai-surface#111113
--gcai-well#1a1b1e
--gcai-muted#9b9ca3

Accesibilidad y rendimiento

El archivo tiene 68 líneas (5 KB) y no necesita @keyframes. Esto es lo que hace Tarjetas de sugerencias para empezar 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)