diff --git a/docs/Upgrade.md b/docs/Upgrade.md index fdf69d89adc..83c652f94c7 100644 --- a/docs/Upgrade.md +++ b/docs/Upgrade.md @@ -932,6 +932,37 @@ The `BulkActionProps` has been removed as it did not contain any prop. You can s The `data-generator-retail` package has been updated to provide types for all its records. In the process, we renamed the `commands` resource to `orders`. Accordingly, the `nb_commands` property of the `customers` resource has been renamed to `nb_orders` and the `command_id` property of the `invoices` and `reviews` resources has been renamed to `order_id`. +## `` No Longer Clones Its Buttons + +`` used to clones the add, remove and reorder buttons and inject some props to them such as `onClick` and `className`. +If you relied on those props in your custom buttons, you should now leverage the following hooks: + +- `useSimpleFormIterator` for buttons that are not tied to an item such as the add button. + +```diff +- import { Button, ButtonProps } from 'react-admin'; ++ import { Button, ButtonProps, useSimpleFormIterator } from 'react-admin'; + +export const MyAddButton = (props: ButtonProps) => { ++ const { add } = useSimpleFormIterator(); +- return ; ++ return ; +} +``` + +- `useSimpleFormIteratorItem` for buttons that are tied to an item such as the remove and reorder buttons. + +```diff +- import { Button, ButtonProps } from 'react-admin'; ++ import { Button, ButtonProps, useSimpleFormIteratorItem } from 'react-admin'; + +export const MyRemoveButton = (props: ButtonProps) => { ++ const { remove } = useSimpleFormIteratorItem(); +- return ; ++ return ; +} +``` + ## Upgrading to v4 If you are on react-admin v3, follow the [Upgrading to v4](https://marmelab.com/react-admin/doc/4.16/Upgrade.html) guide before upgrading to v5. diff --git a/packages/ra-ui-materialui/src/input/ArrayInput/AddItemButton.tsx b/packages/ra-ui-materialui/src/input/ArrayInput/AddItemButton.tsx index 6f2ae62e50a..dc259c67fc2 100644 --- a/packages/ra-ui-materialui/src/input/ArrayInput/AddItemButton.tsx +++ b/packages/ra-ui-materialui/src/input/ArrayInput/AddItemButton.tsx @@ -1,18 +1,20 @@ import * as React from 'react'; import AddIcon from '@mui/icons-material/AddCircleOutline'; +import clsx from 'clsx'; import { useSimpleFormIterator } from './useSimpleFormIterator'; - import { IconButtonWithTooltip, ButtonProps } from '../../button'; export const AddItemButton = (props: ButtonProps) => { - const { add } = useSimpleFormIterator(); + const { add, source } = useSimpleFormIterator(); + const { className, ...rest } = props; return ( add()} color="primary" - {...props} + className={clsx(`button-add button-add-${source}`, className)} + {...rest} > diff --git a/packages/ra-ui-materialui/src/input/ArrayInput/ReOrderButtons.tsx b/packages/ra-ui-materialui/src/input/ArrayInput/ReOrderButtons.tsx index c5a428aca0e..a45c10961b6 100644 --- a/packages/ra-ui-materialui/src/input/ArrayInput/ReOrderButtons.tsx +++ b/packages/ra-ui-materialui/src/input/ArrayInput/ReOrderButtons.tsx @@ -1,15 +1,22 @@ import * as React from 'react'; - +import clsx from 'clsx'; import { IconButtonWithTooltip } from '../../button'; import ArrowUpwardIcon from '@mui/icons-material/ArrowCircleUp'; import ArrowDownwardIcon from '@mui/icons-material/ArrowCircleDown'; import { useSimpleFormIteratorItem } from './useSimpleFormIteratorItem'; +import { useSimpleFormIterator } from './useSimpleFormIterator'; export const ReOrderButtons = ({ className }: { className?: string }) => { const { index, total, reOrder } = useSimpleFormIteratorItem(); + const { source } = useSimpleFormIterator(); return ( - + ) => { - const { remove } = useSimpleFormIteratorItem(); + const { remove, index } = useSimpleFormIteratorItem(); + const { source } = useSimpleFormIterator(); + const { className, ...rest } = props; return ( ) => { size="small" onClick={() => remove()} color="warning" - {...props} + className={clsx( + `button-remove button-remove-${source}-${index}`, + className + )} + {...rest} > diff --git a/packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIterator.tsx b/packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIterator.tsx index 685248af9aa..cfc110dd405 100644 --- a/packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIterator.tsx +++ b/packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIterator.tsx @@ -1,9 +1,6 @@ import * as React from 'react'; import { Children, - cloneElement, - MouseEvent, - MouseEventHandler, ReactElement, ReactNode, useCallback, @@ -125,16 +122,6 @@ export const SimpleFormIterator = (inProps: SimpleFormIteratorProps) => { [append, children, resetField, source, fields.length] ); - // add field and call the onClick event of the button passed as addButton prop - const handleAddButtonClick = ( - originalOnClickHandler: MouseEventHandler - ) => (event: MouseEvent) => { - addField(); - if (originalOnClickHandler) { - originalOnClickHandler(event); - } - }; - const handleReorder = useCallback( (origin: number, destination: number) => { move(origin, destination); @@ -197,15 +184,7 @@ export const SimpleFormIterator = (inProps: SimpleFormIteratorProps) => {
{!disableAdd && (
- {cloneElement(addButton, { - className: clsx( - 'button-add', - `button-add-${source}` - ), - onClick: handleAddButtonClick( - addButton.props.onClick - ), - })} + {addButton}
)} {fields.length > 0 && !disableClear && !disableRemove && ( diff --git a/packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIteratorItem.tsx b/packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIteratorItem.tsx index be8a6617aa2..a5f06bf1d65 100644 --- a/packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIteratorItem.tsx +++ b/packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIteratorItem.tsx @@ -1,12 +1,5 @@ import * as React from 'react'; -import { - cloneElement, - MouseEvent, - MouseEventHandler, - ReactElement, - ReactNode, - useMemo, -} from 'react'; +import { ReactElement, ReactNode, useMemo } from 'react'; import { Typography, Stack } from '@mui/material'; import clsx from 'clsx'; import { @@ -41,7 +34,6 @@ export const SimpleFormIteratorItem = React.forwardRef( record, removeButton = , reOrderButtons = , - source, } = props; const resource = useResourceContext(props); if (!resource) { @@ -61,17 +53,6 @@ export const SimpleFormIteratorItem = React.forwardRef( return disableRemove && disableRemove(record); }; - // remove field and call the onClick event of the button passed as removeButton prop - const handleRemoveButtonClick = ( - originalOnClickHandler: MouseEventHandler, - index: number - ) => (event: MouseEvent) => { - remove(index); - if (originalOnClickHandler) { - originalOnClickHandler(event); - } - }; - const context = useMemo( () => ({ index, @@ -138,28 +119,9 @@ export const SimpleFormIteratorItem = React.forwardRef( {!disabled && ( - {!disableReordering && - cloneElement(reOrderButtons, { - index, - max: total, - reOrder, - className: clsx( - 'button-reorder', - `button-reorder-${source}-${index}` - ), - })} + {!disableReordering && reOrderButtons} - {!disableRemoveField(record) && - cloneElement(removeButton, { - onClick: handleRemoveButtonClick( - removeButton.props.onClick, - index - ), - className: clsx( - 'button-remove', - `button-remove-${source}-${index}` - ), - })} + {!disableRemoveField(record) && removeButton} )}