Skip to content

React

Terminal window
npm install @aortl/admin-react@0.20.1 react react-dom

Package page: @aortl/admin-react on npm.

import "@aortl/admin-react/styles.css";
import { AdminRoot, Button, Card, Input } from "@aortl/admin-react";
export function SignIn() {
return (
<AdminRoot>
<Card>
<Card.Body>
<Card.Title>Sign in</Card.Title>
<Input placeholder="Email" />
<Input type="password" placeholder="Password" />
<Card.Actions>
<Button variant="primary">Sign in</Button>
<Button variant="ghost">Cancel</Button>
</Card.Actions>
</Card.Body>
</Card>
</AdminRoot>
);
}

Two things that example is doing:

  • <AdminRoot> is required. Components emit _ao--prefixed class names that only match inside @scope (._ao-admin-root), and <AdminRoot> is the <div> that opens that scope. Mount it once near the top of your tree: at the app root for a full-page admin app, or around each embedded admin surface inside a host app. It also publishes itself as the portal container, so Select and Tooltip popups land inside the scope instead of on document.body.
  • You supply 'use client' yourself. The package ships no directive of its own, so under React Server Components every module rendering an interactive component needs it at the top, or must be reached from one that has it. The stylesheet import has no such constraint.

Beyond the standard <div> attributes — all forwarded, including style and ref — two typed shortcuts:

Prop Type Effect
theme "light" | "dark" Sets data-theme to force a color scheme on this subtree. Omit to follow the OS.
systemAccent string (CSS color) Sets --color-system-accent inline — see Theming › System accent.
<AdminRoot theme="dark" systemAccent="var(--color-purple-600)">
{/* ... */}
</AdminRoot>

A plain <div className="_ao-admin-root"> opens the scope too, but you write the prefix yourself and lose the portal container.

Import the stylesheet once in the root layout — a server component, where CSS imports are fine — and render <AdminRoot> from a small client wrapper:

app/providers.tsx
"use client";
import { AdminRoot } from "@aortl/admin-react";
export function AdminProviders({ children }: { children: React.ReactNode }) {
return <AdminRoot>{children}</AdminRoot>;
}
app/layout.tsx
import "@aortl/admin-react/styles.css";
import { AdminProviders } from "./providers";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<AdminProviders>{children}</AdminProviders>
</body>
</html>
);
}

Import the stylesheet in the entry and wrap the app once:

src/main.tsx
import "@aortl/admin-react/styles.css";
import { AdminRoot } from "@aortl/admin-react";
import { createRoot } from "react-dom/client";
import { App } from "./App";
createRoot(document.getElementById("root")!).render(
<AdminRoot>
<App />
</AdminRoot>,
);
  • Icons — install @tabler/icons-react and pass a component to any icon prop.
  • ConventionsclassName, classNames, sizes, tones, and the .Container escape hatch, which hold for every component.
  • Tailwind — needed for the bare utility classes (flex-1, gap-2) that layout examples use.
  • Theming — brand accent, dark mode, token overrides.