Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { Notification } from '../layout';
import {
Basic,
NoRecordRepresentation,
Themed,
WithCustomTitleAndContent,
WithDefaultTranslation,
} from './DeleteWithConfirmButton.stories';
Expand Down Expand Up @@ -395,4 +396,10 @@ describe('<DeleteWithConfirmButton />', () => {
await screen.findByText('Delete author #1');
await screen.findByText('Are you sure you want to delete this author?');
});

it('should be customized by a theme', async () => {
render(<Themed />);
const buttons = await screen.findAllByTestId('themed');
expect(buttons[0].classList).toContain('MuiButton-outlined');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import englishMessages from 'ra-language-english';
import frenchMessages from 'ra-language-french';
import { Resource, TestMemoryRouter } from 'ra-core';
import fakeRestDataProvider from 'ra-data-fakerest';
import { Alert } from '@mui/material';
import { Alert, createTheme, ThemeOptions } from '@mui/material';

import { DeleteWithConfirmButton } from './DeleteWithConfirmButton';
import { AdminContext } from '../AdminContext';
import { AdminUI } from '../AdminUI';
import { List, Datagrid } from '../list';
import { TextField } from '../field';
import { deepmerge } from '@mui/utils';

export default { title: 'ra-ui-materialui/button/DeleteWithConfirmButton' };

Expand Down Expand Up @@ -300,3 +301,38 @@ export const WithCustomDialogContent = () => (
</AdminContext>
</TestMemoryRouter>
);

export const Themed = () => (
<TestMemoryRouter initialEntries={['/books']}>
<AdminContext
dataProvider={dataProvider}
i18nProvider={i18nProvider}
theme={deepmerge(createTheme(), {
components: {
RaDeleteWithConfirmButton: {
defaultProps: {
variant: 'outlined',
'data-testid': 'themed',
},
styleOverrides: {
root: {
color: 'hotpink',
},
},
},
},
} as ThemeOptions)}
>
<AdminUI>
<Resource
name="books"
list={
<BookList>
<DeleteWithConfirmButton />
</BookList>
}
/>
</AdminUI>
</AdminContext>
</TestMemoryRouter>
);
42 changes: 39 additions & 3 deletions packages/ra-ui-materialui/src/button/DeleteWithConfirmButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import React, { Fragment, isValidElement, ReactEventHandler } from 'react';
import ActionDelete from '@mui/icons-material/Delete';
import {
ComponentsOverrides,
styled,
useThemeProps,
} from '@mui/material/styles';
import clsx from 'clsx';

import { UseMutationOptions } from '@tanstack/react-query';
Expand All @@ -20,8 +25,13 @@ import { Button, ButtonProps } from './Button';
import { humanize, singularize } from 'inflection';

export const DeleteWithConfirmButton = <RecordType extends RaRecord = any>(
props: DeleteWithConfirmButtonProps<RecordType>
inProps: DeleteWithConfirmButtonProps<RecordType>
) => {
const props = useThemeProps({
props: inProps,
name: PREFIX,
});

const {
className,
confirmTitle: confirmTitleProp,
Expand Down Expand Up @@ -80,7 +90,7 @@ export const DeleteWithConfirmButton = <RecordType extends RaRecord = any>(

return (
<Fragment>
<Button
<StyledButton
onClick={handleDialogOpen}
label={label}
className={clsx('ra-delete-button', className)}
Expand All @@ -89,7 +99,7 @@ export const DeleteWithConfirmButton = <RecordType extends RaRecord = any>(
{...rest}
>
{icon}
</Button>
</StyledButton>
<Confirm
isOpen={open}
loading={isPending}
Expand Down Expand Up @@ -158,3 +168,29 @@ export interface DeleteWithConfirmButtonProps<
resource?: string;
successMessage?: string;
}

const PREFIX = 'RaDeleteWithConfirmButton';

const StyledButton = styled(Button, {
name: PREFIX,
overridesResolver: (props, styles) => styles.root,
})({});

declare module '@mui/material/styles' {
interface ComponentNameToClassKey {
[PREFIX]: 'root';
}

interface ComponentsPropsList {
[PREFIX]: Partial<DeleteWithConfirmButtonProps>;
}

interface Components {
[PREFIX]?: {
defaultProps?: ComponentsPropsList[typeof PREFIX];
styleOverrides?: ComponentsOverrides<
Omit<Theme, 'components'>
>[typeof PREFIX];
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Toolbar, SimpleForm } from '../form';
import { Edit } from '../detail';
import { TextInput } from '../input';
import { DeleteWithUndoButton } from './DeleteWithUndoButton';
import { Themed } from './DeleteWithUndoButton.stories';

const theme = createTheme();

Expand Down Expand Up @@ -161,4 +162,10 @@ describe('<DeleteWithUndoButton />', () => {
]);
});
});

it('should be customized by a theme', async () => {
render(<Themed />);
const buttons = await screen.findAllByTestId('themed');
expect(buttons[0].classList).toContain('MuiButton-outlined');
});
});
209 changes: 209 additions & 0 deletions packages/ra-ui-materialui/src/button/DeleteWithUndoButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import { Resource, TestMemoryRouter } from 'ra-core';
import { AdminContext } from '../AdminContext';
import { deepmerge } from '@mui/utils';
import { createTheme, ThemeOptions } from '@mui/material';
import { AdminUI } from '../AdminUI';
import { DeleteWithUndoButton } from './DeleteWithUndoButton';
import * as React from 'react';
import polyglotI18nProvider from 'ra-i18n-polyglot';
import frenchMessages from 'ra-language-french';
import englishMessages from 'ra-language-english';
import fakeRestDataProvider from 'ra-data-fakerest';
import { Datagrid, List } from '../list';
import { TextField } from '../field';

export default { title: 'ra-ui-materialui/button/DeleteWithUndoButton' };

const i18nProvider = polyglotI18nProvider(
locale =>
locale === 'fr'
? {
...frenchMessages,
resources: {
books: {
name: 'Livre |||| Livres',
fields: {
id: 'Id',
title: 'Titre',
author: 'Auteur',
year: 'Année',
},
message: {
delete_title:
'Supprimer le livre "%{recordRepresentation}" ?',
delete_content:
'Souhaitez-vous vraiment supprimer le livre "%{recordRepresentation}" ?',
},
},
},
}
: {
...englishMessages,
resources: {
books: {
message: {
delete_title:
'Delete the book "%{recordRepresentation}"?',
delete_content:
'Do you really want to delete the book "%{recordRepresentation}"?',
},
},
},
},
// Default locale
'en',
[
{ locale: 'en', name: 'English' },
{ locale: 'fr', name: 'Français' },
]
);

const dataProvider = fakeRestDataProvider({
books: [
{
id: 1,
title: 'War and Peace',
author: 'Leo Tolstoy',
year: 1869,
},
{
id: 2,
title: 'Pride and Predjudice',
author: 'Jane Austen',
year: 1813,
},
{
id: 3,
title: 'The Picture of Dorian Gray',
author: 'Oscar Wilde',
year: 1890,
},
{
id: 4,
title: 'Le Petit Prince',
author: 'Antoine de Saint-Exupéry',
year: 1943,
},
{
id: 5,
title: "Alice's Adventures in Wonderland",
author: 'Lewis Carroll',
year: 1865,
},
{
id: 6,
title: 'Madame Bovary',
author: 'Gustave Flaubert',
year: 1856,
},
{
id: 7,
title: 'The Lord of the Rings',
author: 'J. R. R. Tolkien',
year: 1954,
},
{
id: 8,
title: "Harry Potter and the Philosopher's Stone",
author: 'J. K. Rowling',
year: 1997,
},
{
id: 9,
title: 'The Alchemist',
author: 'Paulo Coelho',
year: 1988,
},
{
id: 10,
title: 'A Catcher in the Rye',
author: 'J. D. Salinger',
year: 1951,
},
{
id: 11,
title: 'Ulysses',
author: 'James Joyce',
year: 1922,
},
],
authors: [
{ id: 1, fullName: 'Leo Tolstoy' },
{ id: 2, fullName: 'Jane Austen' },
{ id: 3, fullName: 'Oscar Wilde' },
{ id: 4, fullName: 'Antoine de Saint-Exupéry' },
{ id: 5, fullName: 'Lewis Carroll' },
{ id: 6, fullName: 'Gustave Flaubert' },
{ id: 7, fullName: 'J. R. R. Tolkien' },
{ id: 8, fullName: 'J. K. Rowling' },
{ id: 9, fullName: 'Paulo Coelho' },
{ id: 10, fullName: 'J. D. Salinger' },
{ id: 11, fullName: 'James Joyce' },
],
});

const BookList = ({ children }) => {
return (
<List>
<Datagrid>
<TextField source="id" />
<TextField source="title" />
<TextField source="author" />
<TextField source="year" />
{children}
</Datagrid>
</List>
);
};

export const Basic = () => (
<TestMemoryRouter initialEntries={['/books']}>
<AdminContext dataProvider={dataProvider} i18nProvider={i18nProvider}>
<AdminUI>
<Resource
name="books"
list={
<BookList>
<DeleteWithUndoButton />
</BookList>
}
/>
</AdminUI>
</AdminContext>
</TestMemoryRouter>
);

export const Themed = () => (
<TestMemoryRouter initialEntries={['/books']}>
<AdminContext
dataProvider={dataProvider}
i18nProvider={i18nProvider}
theme={deepmerge(createTheme(), {
components: {
RaDeleteWithUndoButton: {
defaultProps: {
variant: 'outlined',
'data-testid': 'themed',
},
styleOverrides: {
root: {
color: 'hotpink',
},
},
},
},
} as ThemeOptions)}
>
<AdminUI>
<Resource
name="books"
list={
<BookList>
<DeleteWithUndoButton />
</BookList>
}
/>
</AdminUI>
</AdminContext>
</TestMemoryRouter>
);
Loading
Loading