TailAdmin
Users
| # | Actions | Name | Status | |
|---|---|---|---|---|
| 1 | Ada Lovelace | ada@example.test | active | |
| 2 | Grace Hopper | grace@example.test | pending | |
| 3 | Alan Turing | alan@example.test | active |
Status renders through the tailAdminPlugin's StatusBadge renderer; edit a row to see the Switch field adapter it also registers.
Install:
npm install @vibeflui/tailadmin@vibeflui/tailadmin is Tailwind-only — no external UI runtime library to install. It registers a tailadmin theme preset, a StatusBadge renderer, and a Switch field adapter. The package exports ./tailadmin.css; import it once for the TailAdmin color palette.
File structure
schemas/
users/
tailadmin-users.schema.ts
lib/
vibeflui/
examples/
tailadmin-user-actions.ts
registry.tsx
app/
users/
page.tsxSchema file
schemas/users/tailadmin-users.schema.ts
export const tailAdminUsersSchema = {
resource: "users",
adapter: "tailadmin",
theme: {
preset: "tailadmin"
},
identity: { key: "id", param: "id" },
table: {
columns: [
{ key: "name", label: "Name" },
{ key: "email", label: "Email", type: "email" },
{ key: "status", label: "Status", type: "custom", renderer: "StatusBadge" }
]
},
actions: {
create: { enabled: false },
edit: { enabled: true, label: "Edit", display: "icon", icon: "mdi:pencil-outline", handler: "users.update" },
delete: { enabled: false }
},
form: {
mode: "modal",
fields: [
{ name: "name", label: "Name", required: true },
{ name: "email", label: "Email", type: "email", required: true },
{ name: "enabled", label: "Enabled", type: "switch", adapter: "Switch" }
]
},
registry: {
renderers: ["StatusBadge"],
fieldAdapters: ["Switch"],
actionHandlers: ["users.update"]
}
} as const;StatusBadge and Switch both come from tailAdminPlugin itself — the schema only needs to reference them by key.
Actions file
lib/vibeflui/examples/tailadmin-user-actions.ts
import type { Dispatch, SetStateAction } from "react";
import type { FluiKitActionExecutionContext } from "@vibeflui/core";
export type TailAdminUserRow = { id: string; name: string; email: string; status: string; enabled: boolean };
export const initialTailAdminUsers: TailAdminUserRow[] = [
{ id: "usr_1", name: "Ada Lovelace", email: "ada@example.test", status: "active", enabled: true },
{ id: "usr_2", name: "Grace Hopper", email: "grace@example.test", status: "pending", enabled: false }
];
export function createTailAdminUserActions(setUsers: Dispatch<SetStateAction<TailAdminUserRow[]>>) {
return {
"users.update": async ({ row, values }: FluiKitActionExecutionContext) => {
const id = String(row?.id ?? "");
const nextUser: TailAdminUserRow = {
id,
name: String(values?.name ?? ""),
email: String(values?.email ?? ""),
status: String(row?.status ?? "active"),
enabled: Boolean(values?.enabled)
};
setUsers((current) => current.map((user) => (user.id === id ? nextUser : user)));
return { status: true, code: 200, message: "User updated" };
}
};
}Registry file
lib/vibeflui/registry.tsx
import type { Dispatch, SetStateAction } from "react";
import { createRegistry } from "@vibeflui/core";
import { createTailAdminUserActions, type TailAdminUserRow } from "@/lib/vibeflui/examples/tailadmin-user-actions";
export function createVibefluiRegistry(setUsers: Dispatch<SetStateAction<TailAdminUserRow[]>>) {
return createRegistry({
actionHandlers: createTailAdminUserActions(setUsers)
});
}Page file
app/users/page.tsx
"use client";
import { useMemo, useState } from "react";
import { FluiKit, FluiKitProvider } from "@vibeflui/core";
import { tailAdminPlugin } from "@vibeflui/tailadmin";
import "@vibeflui/tailadmin/tailadmin.css";
import { createVibefluiRegistry } from "@/lib/vibeflui/registry";
import { initialTailAdminUsers } from "@/lib/vibeflui/examples/tailadmin-user-actions";
import { tailAdminUsersSchema } from "@/schemas/users/tailadmin-users.schema";
export default function UsersPage() {
const [users, setUsers] = useState(initialTailAdminUsers);
const registry = useMemo(() => createVibefluiRegistry(setUsers), []);
return (
<FluiKitProvider plugins={[tailAdminPlugin]} registry={registry}>
<FluiKit schema={tailAdminUsersSchema} data={users} />
</FluiKitProvider>
);
}plugins={[tailAdminPlugin]} registers the theme preset, StatusBadge renderer, and Switch field adapter this page uses.
Exports include createTailAdminPlugin, tailAdminPlugin, TailAdminStatusBadge, and TailAdminSwitch.