diff --git a/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx b/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx
index 931ccb92bd3..3e1dea27c67 100644
--- a/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx
+++ b/packages/ra-ui-materialui/src/button/SaveButton.spec.tsx
@@ -20,6 +20,11 @@ import {
NumberInput,
} from '../input';
import { AdminContext } from '../AdminContext';
+import {
+ AlwaysEnable,
+ Basic,
+ EnabledWhenFormIsPrefilled,
+} from './SaveButton.stories';
const invalidButtonDomProps = {
disabled: true,
@@ -64,13 +69,7 @@ describe('', () => {
});
it('should render as submit type by default', async () => {
- render(
-
-
-
- );
+ render();
await waitFor(() =>
expect(
screen.getByLabelText('ra.action.save').getAttribute('type')
@@ -388,13 +387,16 @@ describe('', () => {
});
it('should render enabled if alwaysEnable is true', async () => {
- render(
-
-
-
+ render();
+ await waitFor(() =>
+ expect(screen.getByLabelText('ra.action.save')['disabled']).toEqual(
+ false
+ )
);
+ });
+
+ it('should render enabled if the form is prefilled', async () => {
+ render();
await waitFor(() =>
expect(screen.getByLabelText('ra.action.save')['disabled']).toEqual(
false
diff --git a/packages/ra-ui-materialui/src/button/SaveButton.stories.tsx b/packages/ra-ui-materialui/src/button/SaveButton.stories.tsx
index 64fd6caab25..760d3819675 100644
--- a/packages/ra-ui-materialui/src/button/SaveButton.stories.tsx
+++ b/packages/ra-ui-materialui/src/button/SaveButton.stories.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { Form } from 'ra-core';
+import { Form, TestMemoryRouter } from 'ra-core';
import { Paper } from '@mui/material';
import { SaveButton } from './SaveButton';
@@ -29,33 +29,55 @@ const MakeFormChange = () => {
};
export const Dirty = () => (
-
-
-
-
-
+
+
+
+
+
+
+
+);
+
+export const EnabledWhenFormIsPrefilled = () => (
+
+
+
+
+
+
+
);
export const AlwaysEnable = () => (
-
-
-
-
-
+
+
+
+
+
+
+
);
export const Submitting = () => (
-
-
-
-
-
+
+
+
+
+
+
+
);
diff --git a/packages/ra-ui-materialui/src/button/SaveButton.tsx b/packages/ra-ui-materialui/src/button/SaveButton.tsx
index 80a351597e4..735012c4a3e 100644
--- a/packages/ra-ui-materialui/src/button/SaveButton.tsx
+++ b/packages/ra-ui-materialui/src/button/SaveButton.tsx
@@ -18,6 +18,7 @@ import {
useTranslate,
warning,
setSubmissionErrors,
+ useRecordFromLocation,
} from 'ra-core';
/**
@@ -75,12 +76,16 @@ export const SaveButton = (
// useFormState().isDirty might differ from useFormState().dirtyFields (https://github.com/react-hook-form/react-hook-form/issues/4740)
const isDirty = Object.keys(dirtyFields).length > 0;
// Use form isDirty, isValidating and form context saving to enable or disable the save button
- // if alwaysEnable is undefined
+ // if alwaysEnable is undefined and the form wasn't prefilled
+ const recordFromLocation = useRecordFromLocation();
const disabled = valueOrDefault(
alwaysEnable === false || alwaysEnable === undefined
? undefined
: !alwaysEnable,
- disabledProp || !isDirty || isValidating || isSubmitting
+ disabledProp ||
+ (!isDirty && recordFromLocation == null) ||
+ isValidating ||
+ isSubmitting
);
warning(