diff --git a/packages/ra-ui-materialui/src/button/DeleteButton.tsx b/packages/ra-ui-materialui/src/button/DeleteButton.tsx index 02508b7b6da..45c82fbb132 100644 --- a/packages/ra-ui-materialui/src/button/DeleteButton.tsx +++ b/packages/ra-ui-materialui/src/button/DeleteButton.tsx @@ -52,9 +52,10 @@ import { * return } {...props} />; * }; */ -export const DeleteButton = React.forwardRef(function DeleteButton< - RecordType extends RaRecord = any, ->( +export const DeleteButton: React.ForwardRefExoticComponent< + React.PropsWithoutRef & + React.RefAttributes +> = React.forwardRef(function DeleteButton( inProps: DeleteButtonProps, ref: React.ForwardedRef ) { diff --git a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.spec.tsx b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.spec.tsx index a40bc94e396..291e8e50d76 100644 --- a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.spec.tsx +++ b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.spec.tsx @@ -26,6 +26,7 @@ import { NoRecordRepresentation, Themed, WithCustomTitleAndContent, + WithComponent, WithDefaultTranslation, } from './DeleteWithConfirmButton.stories'; import { Label } from './DeleteButton.stories'; @@ -408,6 +409,18 @@ describe('', () => { await screen.findByText('Please confirm the deletion'); }); + it('should allow to render the button with a custom component', async () => { + render(); + const button = within( + (await screen.findByText('War and Peace')).closest( + 'tr' + ) as HTMLElement + ).getByText('Delete'); + expect(button.closest('a')).not.toBeNull(); + fireEvent.click(button); + await screen.findByText('Delete the book "War and Peace"?'); + }); + it('should use the record representation in the confirmation title and content with a resource specific translation', async () => { render(); fireEvent.click( diff --git a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.stories.tsx b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.stories.tsx index 69d6e05316b..e83455aeb5c 100644 --- a/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.stories.tsx +++ b/packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.stories.tsx @@ -210,6 +210,23 @@ export const Basic = () => ( ); +export const WithComponent = () => ( + + + + + + + } + /> + + + +); + export const WithDefaultTranslation = () => ( ( + props: DeleteWithConfirmButtonProps< + RecordType, + MutationOptionsError, + RootComponent + > & + React.RefAttributes +) => React.ReactElement | null; + export const DeleteWithConfirmButton = React.forwardRef( - function DeleteWithConfirmButton( - inProps: DeleteWithConfirmButtonProps, - ref: React.ForwardedRef + function DeleteWithConfirmButton< + RecordType extends RaRecord = any, + RootComponent extends React.ElementType = 'button', + >( + inProps: DeleteWithConfirmButtonProps< + RecordType, + unknown, + RootComponent + >, + ref: React.ForwardedRef ) { const props = useThemeProps({ props: inProps, @@ -219,28 +239,29 @@ export const DeleteWithConfirmButton = React.forwardRef( ); } -); +) as DeleteWithConfirmButtonComponent; const defaultIcon = ; -export interface DeleteWithConfirmButtonProps< +export type DeleteWithConfirmButtonProps< RecordType extends RaRecord = any, MutationOptionsError = unknown, -> extends ButtonProps, - UseDeleteControllerParams { - confirmTitle?: React.ReactNode; - confirmContent?: React.ReactNode; - icon?: React.ReactNode; - confirmColor?: 'primary' | 'warning'; - onClick?: ReactEventHandler; - // May be injected by Toolbar - sanitized in Button - /** - * @deprecated use `titleTranslateOptions` and `contentTranslateOptions` instead - */ - translateOptions?: object; - titleTranslateOptions?: object; - contentTranslateOptions?: object; -} + RootComponent extends React.ElementType = 'button', +> = ButtonProps & + UseDeleteControllerParams & { + confirmTitle?: React.ReactNode; + confirmContent?: React.ReactNode; + icon?: React.ReactNode; + confirmColor?: 'primary' | 'warning'; + onClick?: ReactEventHandler; + // May be injected by Toolbar - sanitized in Button + /** + * @deprecated use `titleTranslateOptions` and `contentTranslateOptions` instead + */ + translateOptions?: object; + titleTranslateOptions?: object; + contentTranslateOptions?: object; + }; const PREFIX = 'RaDeleteWithConfirmButton';