Custom controls overview
OpenModalForm row actions and feature-specific modals
Custom controls are React forms opened when a row action uses action_type: "custom_control" and the API returns onSuccess: "OpenModalForm".
There is no dynamic registry — each form is a component in ./ApiTables/table-modals/custom-controls/, wired manually in ./ApiTables/table-modals/ApiTablesModals.tsx by URL substring match.
Flow
Prefetch POST loads form defaults (fields, options) into customControlAction before the popup renders.
State field
rowActions.customControlAction — cleared by handleCloseModal → _getCustomControlRequest(null).
Popup container
<Popup isVisible={!!customControlAction} containerClass="lg:min-w-4xl">
{/* URL includes checks */}
</Popup>First matching includes() wins — order matters if URLs overlap.
Typical control component props
interface Props {
action: CustomControlAction; // server payload + metadata
closeModal: () => void;
rowRefetch?: (row: Row) => void; // optional local row patch
}Read form data from action.payload or legacy action_payload. Submit via useUtilsProvider() handlers.
String customElement (related but different)
Structure can pass customElement: "withdrawal_requests" (string) into tableCore:
- Not a modal — injects
CalculateWithdrawalAmountin./ApiTables/core/TableBody.tsxvia./ApiTables/core/TableCustomElements.tsx - React node
customElementprop renders above table in./ApiTables/ApiTablesComponent.tsx
Unwired files
Several components exist under ./ApiTables/table-modals/custom-controls/ but are not imported in ./ApiTables/table-modals/ApiTablesModals.tsx (e.g. EditUser, EditPendingOrder, LinkSlotToProduct). See Wired controls.