Moodinary/UI

Tabs

Vistas hermanas del mismo objeto. Subrayado para páginas, segmentado para vistas de un gráfico.

Cambia entre vistas del mismo contenido sin salir de la página.

Instalación

shadcn
npx shadcn@latest add https://design.moodinary.com/r/tabs.json
import
import { Tabs, useTabs } from "@moodinary/ui/components/tabs";
import { MotionProvider } from "@moodinary/ui/components/motion-provider";

Ejemplos

Tabs en card (Analíticas)

La variante por defecto encierra tabs y panel en una card. Es la que usa Analíticas en el panel; una tab bloqueada por plan va deshabilitada con hint. Los paneles usan m.div: envolvé la app con MotionProvider (LazyMotion + domMax, como el dashboard) o quedan invisibles.

Datos ilustrativos. Promedio 3,4 en el período elegido.
Código
card.tsx
import { Tabs } from "@moodinary/ui/components/tabs";

export default function TabsCard() {
	return (
		<Tabs
			className="w-full"
			defaultValue="periodo"
			items={[
				{ label: "Periodo", value: "periodo" },
				{ label: "Semana", value: "semana" },
				{
					disabled: true,
					hint: "Disponible en Horizon",
					label: "Simulador",
					value: "simulador",
				},
				{ label: "Informe", value: "informe" },
				{ label: "Ayuda", value: "ayuda" },
			]}
			label="Secciones de Analíticas"
			panelClassName="p-4"
			panels={{
				ayuda: "Cómo leer las analíticas.",
				informe: "Informe del período elegido, listo para descargar.",
				periodo: "Datos ilustrativos. Promedio 3,4 en el período elegido.",
				semana: "Datos ilustrativos. Cómo viene la semana actual.",
			}}
		/>
	);
}

Tabs de página

variant="line" va sobre el lienzo. Una tab deshabilitada puede llevar hint.

Datos ilustrativos. Promedio 3,4 en el período elegido.
Código
line.tsx
import { Tabs } from "@moodinary/ui/components/tabs";

export default function TabsLine() {
	return (
		<Tabs
			className="w-full"
			items={[
				{ label: "Resumen", value: "summary" },
				{ label: "Por equipo", value: "teams" },
				{ label: "Por día", value: "days" },
				{
					disabled: true,
					hint: "Opción deshabilitada en este ejemplo.",
					label: "Predicción (pronto)",
					value: "forecast",
				},
			]}
			label="Analíticas de ejemplo"
			panels={{
				days: "Datos ilustrativos. Comparación entre los días del período.",
				summary: "Datos ilustrativos. Promedio 3,4 en el período elegido.",
				teams:
					"Datos ilustrativos. 4.º A y Equipo Ventas son grupos de ejemplo.",
			}}
			variant="line"
		/>
	);
}

Segmented

Para filtros cortos de 2 a 4 opciones, como el rango de un gráfico, combiná Segmented con useTabs.

Código
segmented.tsx
import { Segmented, SegmentedItem } from "@moodinary/ui/components/segmented";
import { useTabs } from "@moodinary/ui/components/tabs";

const items = [
	{ label: "Semana", value: "week" },
	{ label: "Mes", value: "month" },
	{ label: "Trimestre", value: "quarter" },
];

export default function TabsSegmented() {
	const range = useTabs({ items });
	return (
		<Segmented aria-label="Rango del gráfico">
			{items.map((item) => (
				<SegmentedItem
					active={range.value === item.value}
					key={item.value}
					onClick={() => range.select(item.value)}
				>
					{item.label}
				</SegmentedItem>
			))}
		</Segmented>
	);
}

Props

Tabs

PropTipoDefaultDescripción
itemsTabItem[]-value, label, disabled y hint.
variant"card" | "line""card"Con card o sobre el lienzo.
defaultValuestring-Tab inicial sin controlar.
valuestring-Tab controlada.
onValueChange(value: string) => void-Se llama al cambiar.
activation"automatic" | "manual""automatic"Con manual, las flechas mueven el foco y Enter selecciona.
panelsRecord<string, ReactNode>-Paneles por value.
renderPanel(value: string) => ReactNode-Alternativa a panels.
labelstring-aria-label del tablist.
panelClassNamestring-Clases del panel.
classNamestring-Clases extra.

Cuándo sí y cuándo no

Hacé
  • Usá etiquetas de una o dos palabras.
  • Explicá con hint por qué una tab está deshabilitada.
  • Usá segmented para cambiar el rango de un gráfico.
Evitá
  • No uses tabs para pasos de un flujo.
  • No pongas más de 6 tabs.
  • No escondas información crítica en una tab secundaria.

Accesibilidad

  • Flechas izquierda y derecha, Home y End recorren las tabs.
  • Cada tab controla su panel con aria-controls.