Collapsible
Esconder detalle opcional (“cómo calculamos esto”).
Muestra u oculta un detalle secundario.
Instalación
shadcn
npx shadcn@latest add https://design.moodinary.com/r/collapsible.jsonimport
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "@moodinary/ui/components/collapsible";Ejemplos
Fila de card
Así se usa en Facturación: variant="row" en trigger y contenido, dentro de una Card sin padding. Plegado por defecto.
Código
plan-comparison.tsx
import { Card } from "@moodinary/ui/components/card";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@moodinary/ui/components/collapsible";
import { CheckIcon } from "@moodinary/ui/components/icons";
const plans = ["Basic", "Core", "Insight", "Horizon"];
const features: [string, number][] = [
["Exportar pulsos a CSV", 0],
["Moderación con IA", 1],
["Alertas inteligentes", 1],
["Calendario organizacional", 2],
["API de lectura", 3],
];
export default function CollapsiblePlanComparison() {
return (
<Card className="w-full p-0">
<Collapsible>
<CollapsibleTrigger variant="row">
Comparar todos los planes
</CollapsibleTrigger>
<CollapsibleContent variant="row">
<table className="w-full text-xs">
<thead>
<tr className="text-left text-ink-3">
<th className="px-5 py-2 font-normal">Función</th>
{plans.map((plan) => (
<th className="px-3 py-2 text-center font-medium" key={plan}>
{plan}
</th>
))}
</tr>
</thead>
<tbody>
{features.map(([label, from]) => (
<tr className="border-line border-t" key={label}>
<td className="px-5 py-2 text-ink-2">{label}</td>
{plans.map((plan, index) => (
<td className="px-3 py-2 text-center" key={plan}>
{index >= from ? (
<CheckIcon
aria-label="Incluido"
className="mx-auto size-3.5"
/>
) : (
<span className="text-ink-3">
<span aria-hidden>–</span>
<span className="sr-only">No incluido</span>
</span>
)}
</td>
))}
</tr>
))}
</tbody>
</table>
</CollapsibleContent>
</Collapsible>
</Card>
);
}Detalle
Cerrado por defecto, para explicaciones opcionales.
Código
detail.tsx
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@moodinary/ui/components/collapsible";
export default function CollapsibleDetail() {
return (
<Collapsible>
<CollapsibleTrigger>Cómo leer este gráfico</CollapsibleTrigger>
<CollapsibleContent>
Cada respuesta va de 1 a 5. El clima sale del promedio: desde 4,2 es
soleado, desde 3,5 parcial, desde 2,8 nublado y por debajo, tormenta.
Con menos de 8 pulsos en la semana aparece niebla. Los valores de los
gráficos de esta página son ilustrativos.
</CollapsibleContent>
</Collapsible>
);
}Estados
Abierto con defaultOpen y deshabilitado.
Este panel arranca abierto y se puede cerrar.
Código
states.tsx
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@moodinary/ui/components/collapsible";
export default function CollapsibleStates() {
return (
<div className="grid w-full gap-4">
<Collapsible defaultOpen>
<CollapsibleTrigger>Detalle abierto</CollapsibleTrigger>
<CollapsibleContent>
Este panel arranca abierto y se puede cerrar.
</CollapsibleContent>
</Collapsible>
<Collapsible disabled>
<CollapsibleTrigger>Detalle no disponible</CollapsibleTrigger>
<CollapsibleContent>El control está deshabilitado.</CollapsibleContent>
</Collapsible>
</div>
);
}Props
Collapsible
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| defaultOpen | boolean | false | Abierto al inicio. |
| open | boolean | - | Controlado. |
| onOpenChange | (open: boolean) => void | - | Se llama al cambiar. |
| disabled | boolean | false | Bloquea el control. |
| className | string | - | Clases extra. |
CollapsibleTrigger, CollapsibleContent
| Prop | Tipo | Default | Descripción |
|---|---|---|---|
| variant | "inline" | "row" | "inline" | inline: link chico con chevron a la izquierda. row: fila de card a todo el ancho, chevron a la derecha. |
| children | ReactNode | - | Disparador y contenido. |
| className | string | - | Clases extra. |
Cuándo sí y cuándo no
Hacé
- Usalo para detalles opcionales.
- Escribí el disparador como lo que muestra.
- Mantené el contenido breve.
Evitá
- No escondas errores ni avisos.
- No lo uses para navegación.
- No pongas formularios largos adentro.
Accesibilidad
- El disparador es un botón con
aria-expanded. - Enter y Espacio lo abren y cierran.