Nxar UI library
Dentro de un Visual Component tenés la misma librería de componentes que usa el admin, precargada como window.Nxar, más la hoja de estilos del tema (clases Tailwind y tokens). No hay nada que importar ni reimplementar: tu componente se ve como el resto de Nxar, en claro y en oscuro, y recibe las mejoras de la librería automáticamente.
Si todavía no escribiste un Visual Component, empezá por Visual Components. Para ver cada componente en vivo con sus props, la Component Library.
Cómo se usan
export default function Summary({ record }) {
return (
<Nxar.PageCard>
<Nxar.PageCardHeader title="Contratos" icon={<Nxar.Icon name="scroll-text" size="xs" />} count={3} />
<div className="flex flex-col gap-3 p-4">
<Nxar.Alert><Nxar.AlertTitle>Atención</Nxar.AlertTitle><Nxar.AlertDescription>Vence en 7 días.</Nxar.AlertDescription></Nxar.Alert>
<Nxar.Button variant="brand" size="sm" onClick={() => sdk.toast.success("Listo")}>Renovar</Nxar.Button>
</div>
</Nxar.PageCard>
);
}Catálogo
| Categoría | Componentes |
|---|---|
| Cards | PageCard, PageCardHeader, PageCardHeaderAction, PageCardLoadMore · Card (+ CardHeader, CardTitle, CardDescription, CardContent, CardFooter, CardAction) |
| Settings | SettingsSection, SettingsRow — la forma canónica de armar la pantalla de configuración de un paquete (label + hint + control por fila) |
| Formulario | Button, Input, Textarea, Label |
| Iconos | Icon (+ ICON_NAMES) |
| Display | Badge, Avatar (+ AvatarImage, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarBadge), Skeleton, Spinner, Kbd, Progress, Separator |
| Feedback | Alert (+ AlertTitle, AlertDescription), EmptyState |
| Overlays | Dialog (+ partes), Popover (+ partes), Tooltip |
| Selects | Select (+ SelectTrigger, SelectValue, SelectContent, SelectItem), Combobox, MultiSelect |
| Navegación | Tabs, TabsList, TabsTrigger, TabsContent |
| Layout | ScrollArea |
| Utilidades | cn (unir clases), formatCurrency(amount, code?), convertCurrency, resolveRecordCurrency, useIsMobile |
Los componentes del shell que dependen del esquema o del chrome (Sidebar, ViewLayout, SettingsListView, ConditionBuilder, RelationField, FieldRenderer, RichTextEditor) no están en el iframe. ConfirmDialog y Toaster se usan a través de sdk.confirm() y sdk.toast() (SDK). El set es curado para mantener liviano el bundle; si te falta algo recurrente, pedilo.
Monedas
Nxar.formatCurrency(monto, codigo) formatea con el símbolo y el locale correctos. Sin código, usa la moneda corporativa que llega en ctx.defaultCurrency; en multi-moneda, pasá record.currency_code. convertCurrency y resolveRecordCurrency aplican las cotizaciones de ctx.currencies. Ver Monedas.
Iconos
Sin import, los iconos van por nombre (los de lucide , en kebab-case):
<Nxar.Icon name="circle-check" /> // 16px, hereda el color
<Nxar.Icon name="triangle-alert" size="sm" className="text-destructive" />Tamaños: xs 12 · sm 14 · md 16 (default) · lg 20 · xl 24. Usá size, no className="size-4" (ver la nota de Tailwind). En el slot de icono de una card va size="xs".
Set disponible
También expuesto en Nxar.ICON_NAMES:
| Grupo | Nombres |
|---|---|
| Navegación | arrow-down · arrow-left · arrow-right · arrow-up · chevron-down · chevron-left · chevron-right · chevron-up · chevrons-up-down · external-link |
| Acciones | copy · download · filter · more-horizontal · more-vertical · pause · pencil · play · plus · refresh-cw · save · search · send · settings · share-2 · trash-2 · upload · x |
| Estado | check · circle-alert · circle-check · circle-dashed · circle-help · circle-x · info · lock · shield · shield-check · star · triangle-alert · zap |
| Objetos | bell · book-open · briefcase · building-2 · calendar · clipboard-list · clock · credit-card · database · eye · eye-off · file · file-text · folder · folder-tree · history · inbox · key-round · link · mail · package · package-open · paperclip · phone · receipt · scroll-text · sticky-note · tag · user · user-check · user-plus · users |
| Datos y layout | activity · chart-pie · gauge · hash · layout-dashboard · layout-grid · list · sparkles · square-kanban · table-2 · trending-down · trending-up |
Un nombre que no existe renderiza circle-dashed en vez de romper el componente. Como el nombre es un string, puede venir de tus datos:
const STATUS_ICON = { active: "circle-check", pending: "circle-dashed", expired: "triangle-alert" };
<Nxar.Icon name={STATUS_ICON[record.status] ?? "circle-help"} size="sm" />Tailwind classes
El CSS del iframe trae todas las clases que usa la librería: bg-card, text-muted-foreground, border, rounded-md, flex flex-col gap-3, p-4, text-sm, font-semibold…
El CSS se genera escaneando el código de la librería, no el tuyo. Una clase que ningún componente use (mt-7, grid-cols-5) puede no existir y no aplicar nada. Si una clase no surte efecto, usá style={{ … }} o quedate con las que ves en la Component Library.
Tokens del tema (CSS vars): --background / --foreground · --card · --popover · --primary · --secondary / --muted / --accent · --destructive · --border / --input / --ring · --brand / --brand-soft / --brand-hover. Siguen el tema claro/oscuro del usuario; no hardcodees colores.
Limitaciones
- Overlays con portal (
Dialog,Popover,Tooltip) se dibujan dentro del iframe, que crece para mostrarlos; unDialogde pantalla completa queda atrapado. Para modales reales,sdk.openDialog/sdk.confirm. - Callbacks en props de
sdk.*no cruzan al shell. - Formularios: acciones con
onClick, nuncaonSubmit.
Migración desde 0.1.x
| Antes | Ahora |
|---|---|
className="nxar-stack nxar-gap-3" | className="flex flex-col gap-3" |
<Nxar.Card title="X" subtitle="Y"> | <Nxar.PageCard><Nxar.PageCardHeader title="X" /> … </Nxar.PageCard> |
<Nxar.Button loading> | <Nxar.Button disabled><Nxar.Spinner size="sm" /> …</Nxar.Button> |
<Nxar.Tooltip content="X">trigger</Nxar.Tooltip> | <Nxar.Tooltip><Nxar.TooltipTrigger asChild>…</Nxar.TooltipTrigger><Nxar.TooltipContent>X</Nxar.TooltipContent></Nxar.Tooltip> |
size="md" | size="default" |