componente · @solu30/ui-kit/input
CollapsibleSection
Sección plegable ya armada, con título, ícono o número, badge y acciones en el encabezado.
Seguir leyendo — 3 párrafos más
Collapsible section with chevron animation, optional icon/number and badge.
Supports controlled mode (isOpen + onToggle) and uncontrolled mode (defaultOpen).
Uses CSS variables for theming:
--ui-borderfor section border--ui-bg-raisedfor background--ui-content-primaryfor title text--ui-content-secondaryfor icon and chevron--ui-accentfor default badge--ui-warning,--ui-success,--ui-info,--ui-content-mutedfor semantic badges
161 sitios de import en 9 de 15 verticales — un archivo que la importa cuenta una vez, monte una instancia o veinte.
- EasyYachts
- TheCharterPanel
- cmp-packages
- dietaly
- easycharter
- elliot
- gestorsalon
- luigi
- prepchat
El componente, montado
Cargando el espécimen…
export function CollapsibleSectionSpecimen() {
const [forzarAjustes, setForzarAjustes] = useState(false)
return (
<Stage label="CollapsibleSection · tesorería y la ficha de producto de GestorSalon" tall wide>
<div className="flex w-full max-w-[520px] flex-col gap-3 px-1 py-1">
<CollapsibleSection
title="Desglose por medio"
subtitle="De qué medios de pago se compone el saldo"
defaultOpen={false}
>
<div className="flex flex-col gap-1.5 py-1 text-xs text-content/70">
<span>Efectivo · $ 412.300</span>
<span>Transferencia · $ 1.845.000</span>
<span>Tarjeta de débito · $ 233.900</span>
</div>
</CollapsibleSection>
<CollapsibleSection title="Administrar ubicación" subtitle="Caja Salón Jardín" defaultOpen={false}>
<div className="flex flex-wrap items-center gap-2 px-1 pb-2 pt-1">
<Button variant="outline" size="sm" icon={IconPencil}>
Editar nombre / tipo
</Button>
<Button variant="outline" size="sm">
Archivar
</Button>
</div>
</CollapsibleSection>
<CollapsibleSection
title="Ajustes de stock"
icon={<IconSettings className="h-4 w-4" />}
defaultOpen={false}
forceOpen={forzarAjustes}
>
<div className="flex flex-col gap-1.5 py-1 text-xs text-content/70">
<span>Unidad · kilogramo</span>
<span>Stock mínimo · 12</span>
<span className="text-red">Existencias · el valor no puede ser negativo</span>
</div>
</CollapsibleSection>
<button
type="button"
onClick={() => setForzarAjustes((v) => !v)}
className="self-start rounded-md border border-content/10 bg-inner px-2.5 py-1 font-mono text-[11px] text-content/60 transition-colors hover:text-content"
>
↻ simular error de validación (forceOpen={String(!forzarAjustes)})
</button>
<p className="text-[11px] text-content/60">
`forceOpen` es lo que usa la ficha de producto para reabrir la sección cuando un campo de
adentro falla la validación: sin eso, el error queda escondido detrás de un plegado.
</p>
</div>
</Stage>
)
}De specimens/input.tsx · CollapsibleSectionSpecimen: el espécimen del Muestrario, no un ejemplo oficial del paquete. Muestra cómo se usa la pieza de verdad, montada contra los tipos instalados —eso es lo que vale— pero no es documentación del kit.
Cómo se usa
import { CollapsibleSection } from '@solu30/ui-kit/input'Props
| Prop | Requerida | Tipo | Qué hace |
|---|---|---|---|
| title | sí | string | Section title |
| subtitle | opcional | string | Secondary text after title |
| icon | opcional | ReactNode | Optional icon to display before the title |
| number | opcional | number | Numbered circle that replaces icon |
| badge | opcional | string | CollapsibleBadge | Optional badge — string for accent pill, object for semantic colors |
| defaultOpen | opcional | boolean | Whether the section is open by default (uncontrolled mode) |
| isOpen | opcional | boolean | Controlled open state — if provided, component is controlled |
| onToggle | opcional | () => void | Callback when toggle is clicked (required for controlled mode) |
| allowOverflow | opcional | boolean | Allow content to overflow (useful for dropdowns inside) |
| disableCollapse | opcional | boolean | Disable collapsing — always open, no chevron |
| forceOpen | opcional | boolean | Imperative open via useEffect |
| actions | opcional | ReactNode | Right-side interactive slot (before chevron) |
| mobileActionsInContent | opcional | boolean | Move actions to content area on mobile screens |
| rightInfo | opcional | ReactNode | Right-side read-only info |
| compact | opcional | boolean | Smaller padding and font |
| children | sí | ReactNode | Section content |
| className | opcional | string | Additional CSS class for the wrapper |
| headerClassName | opcional | string | Additional CSS class for the header row |
| contentClassName | opcional | string | Additional CSS class for the content wrapper |
Ejemplo del paquete
// Uncontrolled
<CollapsibleSection title="Advanced Options" defaultOpen>
<p>Content here</p>
</CollapsibleSection>
// Controlled
<CollapsibleSection title="Filters" isOpen={open} onToggle={() => setOpen(!open)}>
<FilterForm />
</CollapsibleSection>
// With semantic badge
<CollapsibleSection title="Alerts" badge={{ type: 'warning', text: '3 issues' }}>
<AlertList />
</CollapsibleSection>
// Numbered, compact, with actions
<CollapsibleSection title="Step 1" number={1} compact actions={<Button size="sm">Edit</Button>}>
<StepForm />
</CollapsibleSection>Del @example del JSDoc de @solu30/ui-kit, sin editar: son 65 de los 541 símbolos. La sangría y los renglones en blanco son los del paquete.