VVibeFlui

Registry Keys

Registry keys keep schemas JSON-friendly.

Instead of putting functions inside a schema, the schema references string keys. Runtime code registers the actual functions, components, renderers, validators, option loaders, message resolvers, and handlers.

Schema declaration

The registry block can list the keys used by a schema.

schemas/users/users.schema.ts

TS
export const usersSchema = {
  version: "1.0.0",
  resource: "users",
  registry: {
    components: ["feedback.inlineAlert"],
    renderers: ["users.statusBadge"],
    fieldAdapters: ["react-select"],
    validators: ["users.email"],
    transformers: ["users.trimStrings"],
    actionHandlers: ["users.create"],
    permissionResolvers: ["users.canCreate"],
    optionLoaders: ["roles.options"],
    hooks: ["users.beforeSubmit"],
    events: ["users.formSubmitSucceeded"],
    classNameResolvers: ["users.rowClassName"],
    messageResolvers: ["users.messages"],
    computedResolvers: ["users.fullName"]
  }
} as const;

Runtime registry

components/vibeflui/renderers/users/UserStatusBadge.tsx

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

lib/vibeflui/registry.tsx

TSX
import { createRegistry } from "@vibeflui/core";
import { UserStatusBadge } from "@/components/vibeflui/renderers/users/UserStatusBadge";

export const registry = createRegistry({
  renderers: {
    "users.statusBadge": UserStatusBadge
  },
  validators: {
    "users.email": (value) => {
      return /@/.test(String(value)) ? undefined : "Enter a valid email address.";
    }
  },
  optionLoaders: {
    "roles.options": async () => {
      return [
        { label: "Admin", value: "admin" },
        { label: "Editor", value: "editor" }
      ];
    }
  },
  actionHandlers: {
    "users.create": async ({ values }) => {
      const name = String(values?.name ?? "User");

      return {
        status: true,
        code: 200,
        message: `${name} created`
      };
    }
  },
  permissionResolvers: {
    "users.canCreate": async () => true
  }
});

Key naming

Use stable namespaced keys:

TXT
users.create
users.update
users.delete
users.statusBadge
users.email
roles.options
feedback.inlineAlert

Avoid vague keys:

TXT
save
handler1
custom
validate

No inline functions in schema

Do not write this:

schemas/users/bad-user.schema.ts

TS
export const badSchema = {
  resource: "users",
  form: {
    fields: [
      {
        name: "email",
        validator: (value: string) => value.includes("@")
      }
    ]
  }
};

Write this instead:

schemas/users/good-user.schema.ts

TS
export const goodSchema = {
  version: "1.0.0",
  resource: "users",
  form: {
    fields: [
      {
        name: "email",
        validator: "users.email"
      }
    ]
  }
} as const;