How to Use Table.ShowAction, Table.EditAction, and Table.DeleteAction in refine-shadcn
Use Table.ShowAction, Table.EditAction, and Table.DeleteAction inside Table.Actions to add permission-aware row-level actions to any refine-shadcn table; these components automatically handle URL generation, access control via useCan, and delete confirmations through DeleteProvider.
The refine-shadcn library provides a composable Table component that simplifies building data grids with integrated CRUD operations. These action sub-components abstract away routing logic and permission checks, letting you declare row actions declaratively while the library handles navigation, disabling unauthorized actions, and modal confirmations.
Understanding the Action Components
The Table component exposes three specialized action wrappers that render as dropdown menu items. Each wraps the shared RowAction UI element and integrates with Refine’s access-control system.
Table.ShowAction
Table.ShowAction generates a navigation link to the resource’s show page. In packages/theme/src/table/actions/show.tsx, the component calls the useGetShowUrl hook to construct the URL and check permissions via Refine’s useCan. If the user lacks view permission, the button disables automatically and displays the restriction reason as a tooltip.
Table.EditAction
Table.EditAction functions identically to ShowAction but targets the edit route. Located in packages/theme/src/table/actions/edit.tsx, it uses useGetEditUrl to generate the edit path (e.g., /users/edit/:id) and applies the same permission-based disabling logic.
Table.DeleteAction
Table.DeleteAction differs from the navigation actions—it triggers a confirmation modal rather than a route change. Implemented in packages/theme/src/table/actions/delete.tsx, it leverages useDeleteHelper to verify delete permissions and communicates with DeleteProvider (defined in packages/theme/src/providers/deleteProvider.tsx) to open the confirmation dialog. Upon confirmation, it executes the delete request and optionally runs an onAfterHandle callback.
RowAction Shared UI
All three actions render through RowAction, defined in packages/theme/src/table/actions/index.tsx. This component renders a DropdownMenuItem that adapts based on props: it renders as a <Link> when a to URL is provided (Show/Edit) or as a button with an onClick handler (Delete).
Basic Implementation
Import Table from @ferdiunal/refine-shadcn and render the actions inside a column’s cell function wrapped by Table.Actions.
import { ListPage, Table } from "@ferdiunal/refine-shadcn";
import { Eye, Edit, Trash2 } from "lucide-react";
export const UserList = () => (
<ListPage>
<Table enableSorting enableFilters>
<Table.Column
accessorKey="id"
header="Actions"
cell={({ row: { original } }) => (
<Table.Actions>
<Table.ShowAction
title="View Details"
row={original}
resource="users"
icon={<Eye size={16} />}
/>
<Table.EditAction
title="Edit User"
row={original}
resource="users"
icon={<Edit size={16} />}
/>
<Table.DeleteAction
title="Delete User"
row={original}
resource="users"
icon={<Trash2 size={16} />}
/>
</Table.Actions>
)}
/>
</Table>
</ListPage>
);
The row prop receives the current row data, and resource specifies the Refine resource name for URL generation and permission checks.
Permission Handling and Architecture
Each action follows a consistent three-step flow defined in the source hooks:
- Permission check –
useGetShowUrl,useGetEditUrl, anduseDeleteHelper(located inpackages/theme/src/hooks/) internally calluseCanto verify access. - Conditional rendering – The hook returns
{ can, reason, url }. Ifcanisfalse, RowAction receivesdisabled={true}and displaysreasonas a tooltip. - Navigation or modal – Show and Edit actions render as links to the generated
url. DeleteAction callsDeleteContext.updateDatato open the modal fromDeleteProvider.
The Table component automatically wraps its children with DeleteProvider (see lines 166-168 of packages/theme/src/table/index.tsx), so you do not need to manually provide the context to use Table.DeleteAction.
Advanced Usage Patterns
Custom Post-Delete Callbacks
Pass onAfterHandle to Table.DeleteAction to run logic after successful deletion, such as invalidating queries or showing toast notifications.
<Table.DeleteAction
title="Remove Comment"
row={original}
resource="comments"
icon={<Trash2 size={16} />}
onAfterHandle={() => {
toast.success("Comment deleted successfully");
queryClient.invalidateQueries({ queryKey: ["comments"] });
}}
/>
Overriding Default Icons and Labels
Each action accepts standard props to customize appearance. The title prop sets the tooltip text and accessible label, while icon accepts any React element.
<Table.ShowAction
title="Preview"
row={original}
resource="posts"
icon={<EyeOff size={16} />} // Custom icon
/>
Key Source Files
Reference these locations in the ferdiunal/refine-shadcn repository for implementation details:
packages/theme/src/table/index.tsx– Core Table component exposingTable.Actionsand action sub-components.packages/theme/src/table/actions/show.tsx– ShowAction implementation usinguseGetShowUrl.packages/theme/src/table/actions/edit.tsx– EditAction implementation usinguseGetEditUrl.packages/theme/src/table/actions/delete.tsx– DeleteAction implementation usinguseDeleteHelper.packages/theme/src/table/actions/index.tsx– RowAction shared UI component.packages/theme/src/providers/deleteProvider.tsx– Modal context provider for delete confirmations.templates/vite-react/src/pages/users/list.tsx– Complete working example demonstrating all three actions.
Summary
- Table.ShowAction and Table.EditAction generate permission-aware navigation links to show and edit routes using
useGetShowUrlanduseGetEditUrl. - Table.DeleteAction triggers a confirmation modal via
DeleteProviderand handles deletion throughuseDeleteHelper. - All actions disable automatically when the user lacks permission, showing the restriction reason as a tooltip.
- Wrap actions inside
Table.Actionswithin aTable.Columncell to render a dropdown menu of row operations. - The
DeleteProvidercontext is included automatically in theTablecomponent, requiring no manual setup.
Frequently Asked Questions
How do I disable an action manually regardless of permissions?
Pass the disabled prop directly to any action component. While the components automatically disable based on useCan results, you can force a disabled state by setting disabled={true}, which takes precedence in the RowAction component.
Why is my DeleteAction not opening a modal?
Ensure you are using the Table component from @ferdiunal/refine-shadcn and not a raw table. The Table component internally renders DeleteProvider (as seen in packages/theme/src/table/index.tsx). If you extract the actions for use outside of Table, you must manually wrap your application with DeleteProvider from the same package.
Can I use these actions outside of a Table component?
Technically yes, but you lose automatic context integration. The actions expect a row object and resource name. For standalone usage, import RowAction directly from packages/theme/src/table/actions/index.tsx and provide your own onClick or to props, though you must manually handle permission checks using Refine’s useCan hook.
How do I customize the delete confirmation modal text?
The modal content is controlled by DeleteProvider in packages/theme/src/providers/deleteProvider.tsx. To customize the confirmation text, you would need to shadow or fork the provider component, as the current implementation does not expose props for modal text customization through the action components themselves.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →