Moodinary/UI

Button

Una acción por botón. Un solo primario por vista (org color); el resto secundario o ghost.

Botón sobre @base-ui/react/button. El primario usa el color de la organización (--org): navy en el panel y el color de la institución en el formulario público.

Instalación

shadcn
npx shadcn@latest add https://design.moodinary.com/r/button.json
import
import { Button } from "@moodinary/ui/components/button";

Ejemplos

Variantes

Un solo primary por vista. secondary para acciones de apoyo, ghost para cancelar o acciones de barra, danger solo para borrar.

Código
variants.tsx
import { Button } from "@moodinary/ui/components/button";

export default function ButtonVariants() {
	return (
		<>
			<Button>Nueva acción</Button>
			<Button variant="secondary">Exportar CSV</Button>
			<Button variant="outline">Filtrar</Button>
			<Button variant="ghost">Cancelar</Button>
			<Button variant="danger">Eliminar equipo</Button>
			<Button variant="link">Ver todas las acciones</Button>
		</>
	);
}

Tamaños e íconos

sm en tablas y toolbars, default en el resto, lg en formularios públicos. Los botones de solo ícono llevan aria-label.

Código
sizes.tsx
import { Button } from "@moodinary/ui/components/button";
import {
	MoreHorizontalIcon,
	PlusIcon,
	XIcon,
} from "@moodinary/ui/components/icons";

export default function ButtonSizes() {
	return (
		<>
			<Button size="xs">Mínimo</Button>
			<Button size="sm">Pequeño</Button>
			<Button>Mediano</Button>
			<Button size="lg">Grande</Button>
			<Button variant="secondary">
				<PlusIcon />
				Nueva acción
			</Button>
			<Button aria-label="Más opciones" size="icon" variant="secondary">
				<MoreHorizontalIcon />
			</Button>
			<Button aria-label="Cerrar" size="icon-xs" variant="ghost">
				<XIcon />
			</Button>
			<Button aria-label="Cerrar" size="icon-sm" variant="ghost">
				<XIcon />
			</Button>
			<Button aria-label="Agregar" size="icon-lg" variant="secondary">
				<PlusIcon />
			</Button>
		</>
	);
}

Estados

Deshabilitado baja la opacidad a 45%. Mientras carga, mantené el ancho y cambiá el texto a lo que está pasando.

Código
states.tsx
import { Button } from "@moodinary/ui/components/button";
import { Spinner } from "@moodinary/ui/components/spinner";

export default function ButtonStates() {
	return (
		<>
			<Button>Guardar</Button>
			<Button disabled>Guardar</Button>
			<Button aria-busy disabled variant="secondary">
				<Spinner />
				Generando PDF…
			</Button>
		</>
	);
}

Props

Button

PropTipoDefaultDescripción
variant"primary" | "secondary" | "ghost" | "danger" | "link" | "outline""primary"Peso visual. default y destructive quedan como alias de primary y danger.
size"xs" | "sm" | "default" | "lg" | "icon" | "icon-sm" | "icon-xs" | "icon-lg""default"Alto: 24, 28, 32 y 38 px.
renderReactElement-Renderiza otro elemento (por ejemplo un <a>) con los estilos del botón.
disabledbooleanfalseBloquea la interacción y baja la opacidad.
classNamestring-Clases extra, se combinan con tailwind-merge.

Cuándo sí y cuándo no

Hacé
  • Usá verbos concretos: Nueva acción, Exportar CSV.
  • Un primario por vista; el resto secondary o ghost.
  • Para links con forma de botón, usá render={<a href />}.
Evitá
  • No uses danger para acciones que se pueden deshacer.
  • No pongas dos primarios lado a lado.
  • No escribas Click acá ni un Enviar genérico.

Accesibilidad

  • Foco visible con outline de 2 px en el color de la organización.
  • Los botones de solo ícono necesitan aria-label o un Tooltip.