# Filament Actions UX Standard > Canonical rules for row actions, bulk actions, header actions, and inspect affordances on all Filament table surfaces. > This standard consolidates the Action Surface Contract from the constitution and `docs/ui/action-surface-contract.md`. **Last reviewed**: 2026-03-30 --- ## Governing Principle **Filament-native first.** Action patterns use native Filament action APIs. The constitution's Action Surface Contract (in `.specify/memory/constitution.md`) is the authoritative source for safety and RBAC rules. This document provides the quick-reference standard for implementation. --- ## Required Surfaces Every list/table must define: - **Header Actions** — primary CTA (create, sync, etc.) - **Row Actions** — inspect + contextual operations - **Bulk Actions** — where batch operations exist - **Empty-State CTA** — exactly 1 primary action, RBAC-gated --- ## Inspect Affordance (Required) Every list-style surface must provide a way to open a record. ### Default: clickable rows for list-first and registry surfaces ```php $table->recordUrl(fn ($record) => /* route to view/edit */) ``` Use this default for: - CRUD / List-first resources - Read-only registries / reports - Reporting and evidence registers such as Review Register and Evidence Overview ### Explicit inspect for queue and audit surfaces Use an `Inspect` row action or equivalent same-page selected detail when chronology or queue context must remain visible. - Audit / history pages use explicit inspect - Queue / review pages use explicit inspect - These surfaces should not also expose row click as a competing open path ### Alternative: primary link column Use only when clickable rows are impractical on a clickable-row surface. - `PrimaryLinkColumn` requires a non-empty declaration reason - It is not a fallback for queue / review or audit surfaces ### Rule: no lone "View" button If an open action is the only row action on a clickable-row surface, prefer row click and set `actions([])` to avoid an unnecessary Actions column. --- ## Row Action Limits - **Max 2 visible** row actions (typically View/Edit or Edit/Delete) - Everything else goes into an `ActionGroup` labeled "More" - Destructive actions must never be the primary visible action - On clickable-row surfaces, prefer zero inline row actions unless a single justified shortcut materially improves the workflow --- ## Bulk Actions - Bulk actions must be grouped via `BulkActionGroup` - Destructive bulk actions require confirmation - Typed confirmation may be required for large/bulk changes - Do not leave an empty `BulkActionGroup` placeholder visible once filters, record state, or RBAC remove every effective action --- ## Destructive Action Safety - All destructive actions must use `->requiresConfirmation()` - Destructive actions must not be styled as primary - Confirmation text must clearly describe the consequence - Server-side authorization must still enforce the action regardless of UI confirmation This is a constitution-level non-negotiable (RBAC-UX-005). --- ## Action Consistency ### Standard action labels | Action | Label | Icon guidance | |---|---|---| | Inspect record | "Inspect" | heroicon-o-eye | | Edit record | "Edit" | heroicon-o-pencil-square | | Delete record | "Delete" | heroicon-o-trash | | Archive record | "Archive" | heroicon-o-archive-box | | Restore record | "Restore" | heroicon-o-arrow-uturn-left | | Force delete | "Force Delete" | heroicon-o-trash | Notes: - Clickable-row surfaces normally do not render a `View` or `Inspect` row action at all. - Reporting/evidence registers keep row click primary and should not add a duplicate `View review`-style action. ### Action ordering in "More" group 1. Navigation or inspect helpers first 2. Non-destructive workflow or lifecycle actions next 3. Destructive actions last 4. Do not render an empty `ActionGroup` placeholder Representative expectations: - `Policies`: `Export`, then `Sync`, then destructive ignore/delete actions - `Backup schedules`: `Run now` / `Retry` before archive or force delete - `Workspaces`: row click stays primary and the secondary `Edit` shortcut lives under `More` --- ## RBAC Enforcement - Non-member access: abort(404), do not leak existence - Member without capability: visible but disabled with tooltip - Server-side must enforce via `Gate::authorize(...)` or Policy method - Missing server-side authorization is a P0 security bug --- ## Spec / DoD Gate Every spec with UI changes must include a **UI Action Matrix** listing: - Which actions exist on which surfaces - Which are destructive and how confirmation is handled - Which capabilities gate each action A change is not "Done" unless the Action Surface Contract is met. --- ## Canonical Sources - Constitution: `.specify/memory/constitution.md` → "Filament UI — Action Surface Contract" - Detailed reference: `docs/ui/action-surface-contract.md`