VVibeFlui

FluiKitProvider

FluiKitProvider supplies runtime context for VibeFlui components.

It can be nested. A child provider merges parent context with plugin output and direct provider props.

Props

FluiKitProviderProps extends the runtime registry shape and adds:

TS
type FluiKitProviderProps = FluiKitRuntimeRegistry & {
  children: ReactNode;
  plugins?: FluiKitPlugin[];
  registry?: FluiKitRuntimeRegistry;
  providers?: Record<string, FluiKitDataProvider>;
  messages?: Record<string, string>;
  permissionContext?: FluiKitPermissionContext;
};

Context value

The context value contains:

KeyPurpose
registryMerged runtime registry.
providersNamed data providers.
messagesDefault messages plus parent, plugin, and local messages.
permissionContextPermission context object used by permission resolvers.
pluginsApplied plugin metadata.
pluginWarningsPlugin conflict warnings.
pluginThemesTheme presets contributed by plugins.
pluginAdaptersAdapter presets contributed by plugins.
inspectorPanelsInspector panels contributed by plugins.

Merge order

The provider resolves runtime context in this practical order:

  1. parent provider context
  2. applied plugins
  3. registry prop
  4. direct registry slot props such as components, renderers, fieldAdapters, and actionHandlers

Messages follow:

  1. default VibeFlui messages
  2. parent messages
  3. plugin messages
  4. local messages prop

Providers follow:

  1. parent providers
  2. plugin providers
  3. local providers prop

Basic setup

lib/vibeflui/registry.ts

TS
import { createRegistry } from "@vibeflui/core";

export const registry = createRegistry({
  actionHandlers: {
    "users.archive": async ({ row }) => ({
      status: true,
      code: 200,
      message: `${String(row?.name ?? "User")} archived`
    })
  }
});

app/providers.tsx

TSX
"use client";

import { FluiKitProvider } from "@vibeflui/core";
import { registry } from "@/lib/vibeflui/registry";

export function AppProviders({ children }: { children: React.ReactNode }) {
  return (
    <FluiKitProvider registry={registry}>
      {children}
    </FluiKitProvider>
  );
}

Direct slot props

Direct slot props are convenient for small examples. Keep the renderer component and the schema in their own files even here — only the registry step is skipped.

components/vibeflui/renderers/status/StatusCell.tsx

TSX
export function StatusCell({ value }: { value?: unknown }) {
  return <span>{String(value ?? "-")}</span>;
}

schemas/users/users.schema.ts

TS
export const usersSchema = {
  version: "1.0.0",
  resource: "users",
  table: {
    columns: [
      { key: "name", label: "Name" },
      { key: "status", label: "Status", type: "custom", renderer: "StatusCell" }
    ]
  },
  registry: {
    renderers: ["StatusCell"]
  }
} as const;

app/users/page.tsx

TSX
"use client";

import { FluiKit, FluiKitProvider } from "@vibeflui/core";
import { StatusCell } from "@/components/vibeflui/renderers/status/StatusCell";
import { usersSchema } from "@/schemas/users/users.schema";

const users = [{ id: "usr_1", name: "Ada Lovelace", status: "active" }];

export default function UsersPage() {
  return (
    <FluiKitProvider renderers={{ StatusCell }}>
      <FluiKit schema={usersSchema} data={users} />
    </FluiKitProvider>
  );
}

For production examples, prefer createRegistry so registry setup can be shared across pages.