Action Schema
Action schema describes user commands. Actions can appear as toolbar actions, row actions, bulk actions, built-in CRUD actions, endpoint actions, or registry handler actions.
This page defines action schema shape. Detailed action behavior is documented later in Actions.
Actions container
actions can be a boolean or an object.
schemas/users/user-actions.schema.ts
TS
export const automaticActionsSchema = {
version: "1.0.0",
resource: "users",
actions: true
} as const;schemas/users/user-actions.schema.ts
TS
export const customActionsSchema = {
version: "1.0.0",
resource: "users",
actions: {
create: { enabled: true, label: "Create user", icon: "lucide:plus", handler: "users.create" },
edit: { enabled: true, label: "Edit", icon: "lucide:pencil", handler: "users.update" },
delete: { enabled: true, label: "Delete", icon: "lucide:trash-2", variant: "danger", handler: "users.delete" },
view: { enabled: true, label: "View", icon: "lucide:eye", handler: "users.view" },
row: [
{ key: "archive", label: "Archive", icon: "lucide:archive", handler: "users.archive" }
],
bulk: [
{ key: "bulk-delete", label: "Delete selected", icon: "lucide:trash-2", variant: "danger", handler: "users.bulkDelete" }
],
toolbar: [
{ key: "export", label: "Export", icon: "lucide:download", handler: "users.export" }
]
}
} as const;Action properties
| Property | Type | Purpose |
|---|---|---|
key | string | Stable action identifier. |
enabled | boolean | Enables or disables the action. |
label | string | Visible label or accessible label source. |
icon | string | Iconify icon key. |
tooltip | string | Tooltip text. |
ariaLabel | string | Accessible label for icon-only actions. |
display | "button" | "icon" | Preferred action display. |
iconOnly | boolean | Renders an icon-only control when supported. |
variant | "default" | "primary" | "secondary" | "danger" | "ghost" | Visual tone. |
confirm | boolean | object | Confirmation dialog configuration. |
endpoint | string | object | Endpoint request for this action. |
method | HTTP method | Method for endpoint action. |
handler | string | Registry action handler key. |
permission | string | string[] | Permission key or keys. |
visibleWhen | object | Condition for visibility. |
disabledWhen | object | Condition for disabled state. |
refreshOnSuccess | boolean | Refreshes data after success. |
className | string | Styling hook. |
Confirm dialog
schemas/users/user-actions.ts
TS
export const deleteAction = {
key: "delete",
label: "Delete",
icon: "lucide:trash-2",
variant: "danger",
handler: "users.delete",
confirm: {
title: "Delete user?",
description: "This action cannot be undone.",
confirmLabel: "Delete",
cancelLabel: "Cancel",
icon: "lucide:triangle-alert",
secondConfirm: {
title: "Confirm permanent delete",
description: "The backend must still authorize this action.",
confirmLabel: "Delete permanently",
cancelLabel: "Cancel",
icon: "lucide:trash-2"
}
}
} as const;Handler action
schemas/users/user-actions.ts
TS
export const handlerAction = {
key: "invite",
label: "Invite",
icon: "lucide:send",
handler: "users.invite"
} as const;Endpoint action
schemas/users/user-actions.ts
TS
export const endpointAction = {
key: "archive",
label: "Archive",
icon: "lucide:archive",
endpoint: { url: "/api/users/:id/archive", method: "POST" },
refreshOnSuccess: true
} as const;Registry rule
handler must be a string key. The actual function lives in the registry.
lib/vibeflui/registry.ts
TS
import { createRegistry } from "@vibeflui/core";
export const registry = createRegistry({
actionHandlers: {
"users.invite": async ({ row }) => {
const email = String(row?.email ?? "user@example.com");
return {
status: true,
code: 200,
message: `${email} invited`
};
}
}
});