diff --git a/examples/ra-offline/package.json b/examples/ra-offline/package.json index f2adee64883..c878f93bfbe 100644 --- a/examples/ra-offline/package.json +++ b/examples/ra-offline/package.json @@ -42,4 +42,4 @@ "vite-plugin-pwa": "^1.2.0" }, "name": "ra-offline" -} \ No newline at end of file +} diff --git a/packages/ra-ui-materialui/src/input/SelectArrayInput.spec.tsx b/packages/ra-ui-materialui/src/input/SelectArrayInput.spec.tsx index 82d9b948775..716d88a1d63 100644 --- a/packages/ra-ui-materialui/src/input/SelectArrayInput.spec.tsx +++ b/packages/ra-ui-materialui/src/input/SelectArrayInput.spec.tsx @@ -31,6 +31,31 @@ describe('', () => { ], }; + it('should render emptyText as a disabled MenuItem when provided', () => { + render( + + + + + + + + ); + fireEvent.mouseDown( + screen.getByLabelText('resources.posts.fields.categories') + ); + // The emptyText should be rendered as a disabled MenuItem + const emptyMenuItem = screen.getByText('No selection available'); + expect(emptyMenuItem).toBeInTheDocument(); + expect(emptyMenuItem.closest('li')).toHaveAttribute( + 'aria-disabled', + 'true' + ); + }); + it('should use a mui Select', () => { render( diff --git a/packages/ra-ui-materialui/src/input/SelectArrayInput.tsx b/packages/ra-ui-materialui/src/input/SelectArrayInput.tsx index 544c3a63172..33195a977cd 100644 --- a/packages/ra-ui-materialui/src/input/SelectArrayInput.tsx +++ b/packages/ra-ui-materialui/src/input/SelectArrayInput.tsx @@ -89,6 +89,14 @@ import { Labeled } from '../Labeled'; * { id: 'lifestyle', name: 'myroot.tags.lifestyle' }, * { id: 'photography', name: 'myroot.tags.photography' }, * ]; + * + * You can provide an `emptyText` prop to display a disabled placeholder at the top of the dropdown: + * @example + * */ export const SelectArrayInput = (inProps: SelectArrayInputProps) => { const props = useThemeProps({ @@ -102,6 +110,7 @@ export const SelectArrayInput = (inProps: SelectArrayInputProps) => { createLabel, createValue, disableValue = 'disabled', + emptyText, // <-- Add emptyText prop format, helperText, label, @@ -360,6 +369,11 @@ export const SelectArrayInput = (inProps: SelectArrayInputProps) => { value={finalValue} {...outlinedInputProps} > + {emptyText !== undefined && ( + + {emptyText} + + )} {finalChoices.map(renderMenuItem)} {renderHelperText ? ( @@ -384,6 +398,11 @@ export type SelectArrayInputProps = ChoicesProps & InputLabelProps?: Omit; source?: string; onChange?: (event: ChangeEvent | RaRecord) => void; + /** + * If provided, displays this text as a disabled MenuItem at the top of the dropdown. + * Useful for showing a placeholder or empty state. + */ + emptyText?: React.ReactNode; }; const sanitizeRestProps = ({