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
6 changes: 6 additions & 0 deletions packages/ra-ui-materialui/src/input/BooleanInput.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { ResourceContextProvider, testDataProvider } from 'ra-core';
import { AdminContext } from '../AdminContext';
import { SimpleForm } from '../form';
import { BooleanInput } from './BooleanInput';
import { Themed } from './BooleanInput.stories';

describe('<BooleanInput />', () => {
const defaultProps = {
Expand Down Expand Up @@ -185,4 +186,9 @@ describe('<BooleanInput />', () => {
expect(screen.queryByText('ra.validation.error')).not.toBeNull();
});
});

it('should be customized by a theme', async () => {
render(<Themed />);
await screen.findByTestId('themed');
});
});
25 changes: 24 additions & 1 deletion packages/ra-ui-materialui/src/input/BooleanInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import polyglotI18nProvider from 'ra-i18n-polyglot';
import englishMessages from 'ra-language-english';
import { useFormContext } from 'react-hook-form';
import FavoriteIcon from '@mui/icons-material/Favorite';
import { createTheme } from '@mui/material/styles';

import { AdminContext } from '../AdminContext';
import { Create } from '../detail';
Expand Down Expand Up @@ -44,10 +45,11 @@ export const Dark = () => (

const i18nProvider = polyglotI18nProvider(() => englishMessages);

const Wrapper = ({ children, defaultTheme = 'light' }) => (
const Wrapper = ({ children, defaultTheme = 'light', theme = undefined }) => (
<AdminContext
i18nProvider={i18nProvider}
defaultTheme={defaultTheme as any}
theme={theme}
>
<Create resource="posts">
<SimpleForm>{children}</SimpleForm>
Expand All @@ -73,3 +75,24 @@ export const SetFocus = () => (
</Create>
</AdminContext>
);

export const Themed = () => (
<Wrapper
theme={createTheme({
components: {
RaBooleanInput: {
defaultProps: {
'data-testid': 'themed',
} as any,
styleOverrides: {
root: {
color: 'red',
},
},
},
},
})}
>
<BooleanInput source="published" />
</Wrapper>
);
40 changes: 37 additions & 3 deletions packages/ra-ui-materialui/src/input/BooleanInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import FormHelperText from '@mui/material/FormHelperText';
import FormGroup, { FormGroupProps } from '@mui/material/FormGroup';
import Switch, { SwitchProps } from '@mui/material/Switch';
import { FieldTitle, useInput } from 'ra-core';
import {
ComponentsOverrides,
styled,
useThemeProps,
} from '@mui/material/styles';

import { CommonInputProps } from './CommonInputProps';
import { sanitizeInputRestProps } from './sanitizeInputRestProps';
Expand All @@ -32,7 +37,10 @@ export const BooleanInput = (props: BooleanInputProps) => {
options = defaultOptions,
sx,
...rest
} = props;
} = useThemeProps({
props: props,
name: PREFIX,
});
const {
id,
field,
Expand Down Expand Up @@ -65,7 +73,7 @@ export const BooleanInput = (props: BooleanInputProps) => {
const renderHelperText = helperText !== false || invalid;

return (
<FormGroup
<StyledFormGroup
className={clsx('ra-input', `ra-input-${source}`, className)}
row={row}
sx={sx}
Expand Down Expand Up @@ -102,7 +110,7 @@ export const BooleanInput = (props: BooleanInputProps) => {
/>
</FormHelperText>
) : null}
</FormGroup>
</StyledFormGroup>
);
};

Expand All @@ -113,3 +121,29 @@ export type BooleanInputProps = CommonInputProps &
};

const defaultOptions = {};

const PREFIX = 'RaBooleanInput';

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

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

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

interface Components {
[PREFIX]?: {
defaultProps?: ComponentsPropsList[typeof PREFIX];
styleOverrides?: ComponentsOverrides<
Omit<Theme, 'components'>
>[typeof PREFIX];
};
}
}
11 changes: 11 additions & 0 deletions packages/ra-ui-materialui/src/input/DatagridInput.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import { render, screen } from '@testing-library/react';

import { Themed } from './DatagridInput.stories';

describe('<DatagridInput />', () => {
it('should be customized by a theme', async () => {
render(<Themed />);
await screen.findByTestId('themed');
});
});
28 changes: 28 additions & 0 deletions packages/ra-ui-materialui/src/input/DatagridInput.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { Admin } from 'react-admin';
import { Resource, TestMemoryRouter } from 'ra-core';
import { createTheme } from '@mui/material/styles';

import { Edit } from '../detail';
import { SimpleForm } from '../form';
Expand Down Expand Up @@ -157,3 +158,30 @@ export const InsideReferenceInput = () => (
</Admin>
</TestMemoryRouter>
);

export const Themed = () => (
<TestMemoryRouter initialEntries={['/books/1']}>
<Admin
dataProvider={dataProvider}
theme={createTheme({
components: {
RaDatagridInput: {
defaultProps: {
'data-testid': 'themed',
} as any,
styleOverrides: {
root: {
['& .MuiTypography-root']: {
color: 'red',
fontWeight: 'bold',
},
},
},
},
},
})}
>
<Resource name="books" edit={BookEdit} />
</Admin>
</TestMemoryRouter>
);
56 changes: 49 additions & 7 deletions packages/ra-ui-materialui/src/input/DatagridInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@ import {
useChoicesContext,
useInput,
} from 'ra-core';
import {
ComponentsOverrides,
styled,
useThemeProps,
} from '@mui/material/styles';

import { CommonInputProps } from './CommonInputProps';
import { InputHelperText } from './InputHelperText';
import { SupportCreateSuggestionOptions } from './useSupportCreateSuggestion';
import { Datagrid, DatagridProps } from '../list/datagrid';
import { FilterButton, FilterForm } from '../list/filter';
import { FilterContext } from '../list/FilterContext';
import {
Datagrid,
DatagridProps,
FilterButton,
FilterForm,
FilterContext,
} from '../list';
import { Pagination as DefaultPagination } from '../list/pagination';
import { sanitizeInputRestProps } from './sanitizeInputRestProps';

const defaultPagination = <DefaultPagination />;

Expand Down Expand Up @@ -49,7 +60,12 @@ const defaultPagination = <DefaultPagination />;
* </Edit>
* );
*/
export const DatagridInput = (props: DatagridInputProps) => {
export const DatagridInput = (inProps: DatagridInputProps) => {
const props = useThemeProps({
props: inProps,
name: PREFIX,
});

const {
choices,
className,
Expand Down Expand Up @@ -121,7 +137,7 @@ export const DatagridInput = (props: DatagridInputProps) => {
]
);
return (
<div className={clsx('ra-input', `ra-input-${source}`, className)}>
<Root className={clsx('ra-input', `ra-input-${source}`, className)}>
{/* @ts-ignore FIXME cannot find another way to fix this error: "Types of property 'isPending' are incompatible: Type 'boolean' is not assignable to type 'false'." */}
<ListContextProvider value={listContext}>
{filters ? (
Expand All @@ -145,15 +161,15 @@ export const DatagridInput = (props: DatagridInputProps) => {
) : null}
{!fieldState.error && !fetchError && (
<>
<Datagrid {...rest} />
<Datagrid {...sanitizeInputRestProps(rest)} />
{pagination !== false && pagination}
</>
)}
<InputHelperText
error={fieldState.error?.message || fetchError?.message}
/>
</ListContextProvider>
</div>
</Root>
);
};

Expand All @@ -169,3 +185,29 @@ export type DatagridInputProps = Omit<
filters?: ReactElement | ReactElement[];
pagination?: ReactElement | false;
};

const PREFIX = 'RaDatagridInput';

const Root = styled('div', {
name: PREFIX,
overridesResolver: (props, styles) => styles.root,
})({});

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

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

interface Components {
[PREFIX]?: {
defaultProps?: ComponentsPropsList[typeof PREFIX];
styleOverrides?: ComponentsOverrides<
Omit<Theme, 'components'>
>[typeof PREFIX];
};
}
}
6 changes: 6 additions & 0 deletions packages/ra-ui-materialui/src/input/DateInput.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
ExternalChanges,
ExternalChangesWithParse,
Parse,
Themed,
} from './DateInput.stories';

describe('<DateInput />', () => {
Expand Down Expand Up @@ -319,4 +320,9 @@ describe('<DateInput />', () => {
await screen.findByText('Required');
});
});

it('should be customized by a theme', async () => {
render(<Themed />);
await screen.findByTestId('themed');
});
});
41 changes: 39 additions & 2 deletions packages/ra-ui-materialui/src/input/DateInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import polyglotI18nProvider from 'ra-i18n-polyglot';
import englishMessages from 'ra-language-english';
import { minValue, useRecordContext } from 'ra-core';
import { useFormContext, useWatch } from 'react-hook-form';
import { Box, Button, Typography } from '@mui/material';
import { Box, Button, createTheme, Typography } from '@mui/material';
import { ThemeOptions } from '@mui/material/styles';
import get from 'lodash/get';

import { AdminContext } from '../AdminContext';
Expand Down Expand Up @@ -141,16 +142,52 @@ export const ExternalChangesWithParse = ({
</Wrapper>
);

export const Themed = ({
dateInputProps,
simpleFormProps,
}: {
dateInputProps?: Partial<DateInputProps>;
simpleFormProps?: Partial<SimpleFormProps>;
}) => (
<Wrapper
simpleFormProps={simpleFormProps}
theme={createTheme({
components: {
RaDateInput: {
defaultProps: {
'data-testid': 'themed',
} as any,
styleOverrides: {
root: {
['& input']: {
color: 'red',
},
},
},
},
},
})}
>
<DateInput source="publishedAt" {...dateInputProps} />
</Wrapper>
);

const i18nProvider = polyglotI18nProvider(() => englishMessages);

const Wrapper = ({
children,
simpleFormProps,
theme = undefined,
}: {
children: React.ReactNode;
simpleFormProps?: Partial<SimpleFormProps>;
theme?: ThemeOptions;
}) => (
<AdminContext i18nProvider={i18nProvider} defaultTheme="light">
<AdminContext
i18nProvider={i18nProvider}
defaultTheme="light"
theme={theme}
>
<Create resource="posts">
<SimpleForm {...simpleFormProps}>
{children}
Expand Down
Loading
Loading