componente · @solu30/ui-kit/navigation
ViewModeToggle
Par de botones de ícono para alternar la vista de un listado entre grilla y lista.
Seguir leyendo — 3 párrafos más
Icon-button group for switching between view modes (e.g. grid vs list).
Generic over the mode string — by default works for 'grid' | 'list' but accepts any string union via the options prop.
Uses design tokens:
- Active:
bg-ui-accent text-ui-content-inverse - Inactive:
bg-ui-bg-subtle text-ui-content-muted hover:bg-ui-bg-raised
10 sitios de import en 4 de 15 verticales — un archivo que la importa cuenta una vez, monte una instancia o veinte.
- TheCharterPanel
- cmp-packages
- dietaly
- luigi
El componente, montado
Cargando el espécimen…
export function SegmentedControlMatrix() {
const [range, setRange] = useState('mes')
const [tone, setTone] = useState('lista')
const [view, setView] = useState<'grid' | 'list'>('grid')
return (
<Stage label="SegmentedControl · modo valor / modo navegación — y ViewModeToggle, la misma idea otra vez" tall wide>
<div className="flex w-full flex-col gap-5">
<div className="flex flex-wrap items-center gap-4">
<SegmentedControl
value={range}
onChange={setRange}
size="sm"
tone="default"
options={[
{ value: 'semana', label: 'Semana' },
{ value: 'mes', label: 'Mes' },
{ value: 'temporada', label: 'Temporada' },
]}
/>
<SegmentedControl
value={tone}
onChange={setTone}
size="sm"
tone="accent"
options={[
{ value: 'lista', label: 'Lista' },
{ value: 'calendario', label: 'Calendario' },
]}
/>
<ViewModeToggle
value={view}
onChange={setView}
ariaLabel="Vista de la flota"
options={[
{ value: 'grid', icon: <IconGrid className="h-4 w-4" />, title: 'Grilla' },
{ value: 'list', icon: <IconMenu className="h-4 w-4" />, title: 'Lista' },
]}
/>
</div>
<div className="flex flex-col gap-1.5">
<span className="text-[10px] uppercase tracking-wide text-content/50">
modo navegación — options con href, sin renderLink degrada a <a href="#"> (inerte a propósito)
</span>
<SegmentedControl
value="reservas"
onChange={() => {}}
size="sm"
options={[
{ value: 'reservas', label: 'Reservas', href: '#' },
{ value: 'clientes', label: 'Clientes', href: '#' },
{ value: 'facturacion', label: 'Facturación', href: '#' },
]}
/>
</div>
</div>
</Stage>
)
}De specimens/navigation.tsx · SegmentedControlMatrix: 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 { ViewModeToggle } from '@solu30/ui-kit/navigation'Props
| Prop | Requerida | Tipo | Qué hace |
|---|---|---|---|
| value | sí | T | Current active mode |
| onChange | sí | (mode: T) => void | Called when the user selects a different mode |
| options | opcional | ViewModeOption<T>[] | Options to render (defaults to grid + list if omitted) |
| ariaLabel | opcional | string | Accessible group label |
| className | opcional | string | Additional CSS class |
Ejemplo del paquete
import { LayoutGrid, LayoutList } from 'lucide-react'
<ViewModeToggle
value={viewMode}
onChange={setViewMode}
options={[
{ value: 'grid', icon: <LayoutGrid className="h-4 w-4" />, title: 'Vista cuadrícula' },
{ value: 'list', icon: <LayoutList className="h-4 w-4" />, title: 'Vista lista' },
]}
/>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.