FluiKit
FluiKit is the main component for rendering a VibeFlui resource schema.
It accepts a public FluiKitConfig, normalizes it before rendering, reads runtime context from FluiKitProvider, and coordinates table, dashboard, actions, forms, detail surfaces, provider loading, feedback, lifecycle hooks, and events.
Props
type FluiKitProps = {
schema: FluiKitConfig;
data?: Record<string, unknown>[];
response?: unknown;
loading?: boolean;
error?: unknown;
className?: string;
onCreate?: (values, context) => unknown | Promise<unknown>;
onUpdate?: (values, context) => unknown | Promise<unknown>;
onDelete?: (row) => unknown | Promise<unknown>;
onView?: (row) => void | Promise<void>;
onRowAction?: (action, row) => unknown | Promise<unknown>;
onBulkAction?: (action, rows) => unknown | Promise<unknown>;
onTableQueryChange?: (query) => void;
};Minimal example
schemas/users/users.schema.ts
export const usersSchema = {
version: "1.0.0",
resource: "users",
identity: { key: "id", param: "id" },
table: {
columns: ["name", "email", "status"]
},
form: {
mode: "modal",
fields: ["name", "email", "status"]
},
detail: {
enabled: true,
fields: ["name", "email", "status"]
},
actions: true
} as const;app/users/page.tsx
"use client";
import { FluiKit } from "@vibeflui/core";
import { usersSchema } from "@/schemas/users/users.schema";
const users = [
{ id: "usr_1", name: "Ada Lovelace", email: "ada@example.test", status: "active" },
{ id: "usr_2", name: "Grace Hopper", email: "grace@example.test", status: "pending" }
];
export default function UsersPage() {
return <FluiKit schema={usersSchema} data={users} />;
}This one schema drives every surface FluiKit coordinates: the table, the create/edit modal form, the detail view, and the built-in actions. The rest of this page reuses usersSchema from this file.
Default behavior
FluiKit renders in this order:
- root container with resolved theme class names
- title and description
- toolbar actions
- feedback
- dashboard, when configured and no page-style form/detail surface is active
- table, when no page-style form/detail surface is active
- modal, drawer, inline, or page surface for create, edit, or view
If schema.resources contains child resources, FluiKit renders those children instead of a single table/form resource. layout.type: "sections" and layout.type: "page" stack child resources. Other layouts render child resources as tabs.
Data modes
Use data when rows are already available as an array.
<FluiKit schema={usersSchema} data={users} />Use response when rows live inside a response object and table.dataPath or table.totalPath tells VibeFlui where to read them.
const usersResponse = {
data: [
{ id: "usr_1", name: "Ada Lovelace", email: "ada@example.test", status: "active" }
],
meta: { total: 1 }
};<FluiKit schema={usersSchema} response={usersResponse} />This pairs with table: { dataPath: "data", totalPath: "meta.total" } on usersSchema.
When both data and response are absent and either table.enabled or dashboard.enabled is true, FluiKit attempts to load list data through the configured provider or endpoint.
Operation handlers
The external callbacks are override points:
onCreatehandles create form submit.onUpdatehandles edit form submit.onDeletehandles delete after the action result is available.onRowActionhandles custom row actions.onBulkActionhandles bulk actions.onTableQueryChangereceives server-mode query state.
When an external callback exists for create, update, delete, row action, or bulk action, FluiKit uses callback execution according to the component that triggers the action:
- create and update use the callback instead of
executeOperation - delete, row action, and bulk action callbacks are passed to
FluiKitTable;FluiKitdisables the matching table execution flag when those callbacks are provided - when composing
FluiKitTabledirectly, the table execution flags can be enabled so callbacks receive the built-in action result
Form and detail surfaces
Create and edit open FluiKitForm.
View opens FluiKitDetail only when detail is enabled and the view action is enabled.
The active surface is selected from:
schema.form.modefor create and editschema.detail.modefor view
Supported modes are modal, drawer, page, and inline.
Readonly mode
When uiMode is readonly, FluiKit blocks create, edit, delete, row action, bulk action, and toolbar action behavior. The table can still render read-only data.
Viewing is the one exception, since it isn't a mutation: set actions.view.enabled: true to keep the view/detail action — and the ability to open it — available even under readonly. Without that explicit opt-in, view also defaults to disabled like the other actions.