Skip to content

Commit 6f45456

Browse files
committed
Customizable rich text field and improve stories to test it.
1 parent a431d43 commit 6f45456

File tree

2 files changed

+63
-20
lines changed

2 files changed

+63
-20
lines changed

packages/ra-ui-materialui/src/field/RichTextField.stories.tsx

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import dompurify from 'dompurify';
44

55
import { RichTextField, RichTextFieldProps } from './RichTextField';
66
import { SimpleShowLayout } from '../detail/SimpleShowLayout';
7+
import { AdminContext } from '../AdminContext';
78

89
export default {
910
title: 'ra-ui-materialui/fields/RichTextField',
@@ -24,23 +25,23 @@ It is regarded as one of Tolstoy's finest literary achievements and remains a cl
2425
};
2526

2627
export const Basic = () => (
27-
<RecordContextProvider value={record}>
28+
<Wrapper record={record}>
2829
<RichTextField source="body" />
29-
</RecordContextProvider>
30+
</Wrapper>
3031
);
3132

3233
export const StripTags = () => (
33-
<RecordContextProvider value={record}>
34+
<Wrapper record={record}>
3435
<RichTextField source="body" stripTags />
35-
</RecordContextProvider>
36+
</Wrapper>
3637
);
3738

3839
export const InSimpleShowLayout = () => (
39-
<RecordContextProvider value={record}>
40+
<Wrapper record={record}>
4041
<SimpleShowLayout>
4142
<RichTextField source="body" />
4243
</SimpleShowLayout>
43-
</RecordContextProvider>
44+
</Wrapper>
4445
);
4546

4647
const DomPurifyInspector = () => {
@@ -57,8 +58,8 @@ const DomPurifyInspector = () => {
5758
};
5859

5960
export const Secure = () => (
60-
<RecordContextProvider
61-
value={{
61+
<Wrapper
62+
record={{
6263
id: 1,
6364
body: `
6465
<p>
@@ -80,7 +81,7 @@ It is regarded as one of Tolstoy's finest literary achievements and remains a cl
8081
<h4>Stolen data:</h4>
8182
<input id="stolendata" defaultValue="none" />
8283
</div>
83-
</RecordContextProvider>
84+
</Wrapper>
8485
);
8586

8687
const TargetBlankEnabledRichTextField = (props: RichTextFieldProps) => {
@@ -95,8 +96,8 @@ const TargetBlankEnabledRichTextField = (props: RichTextFieldProps) => {
9596
};
9697

9798
export const TargetBlank = () => (
98-
<RecordContextProvider
99-
value={{
99+
<Wrapper
100+
record={{
100101
id: 1,
101102
body: `
102103
<p>
@@ -111,12 +112,12 @@ It is regarded as one of Tolstoy's finest literary achievements and remains a cl
111112
}}
112113
>
113114
<TargetBlankEnabledRichTextField source="body" />
114-
</RecordContextProvider>
115+
</Wrapper>
115116
);
116117

117118
export const PurifyOptions = () => (
118-
<RecordContextProvider
119-
value={{
119+
<Wrapper
120+
record={{
120121
id: 1,
121122
body: `
122123
<p>
@@ -131,13 +132,19 @@ It is regarded as one of Tolstoy's finest literary achievements and remains a cl
131132
}}
132133
>
133134
<RichTextField source="body" purifyOptions={{ ADD_ATTR: ['target'] }} />
134-
</RecordContextProvider>
135+
</Wrapper>
136+
);
137+
138+
const Wrapper = ({ children, record, defaultTheme = 'light' }) => (
139+
<AdminContext defaultTheme={defaultTheme as any}>
140+
<RecordContextProvider value={record}>{children}</RecordContextProvider>
141+
</AdminContext>
135142
);
136143

137144
export const Empty = ({ emptyText, body }) => (
138-
<RecordContextProvider value={{ id: 1, body }}>
145+
<Wrapper record={{ id: 1, body }}>
139146
<RichTextField source="body" emptyText={emptyText} />
140-
</RecordContextProvider>
147+
</Wrapper>
141148
);
142149
Empty.args = {
143150
emptyText: 'empty',

packages/ra-ui-materialui/src/field/RichTextField.tsx

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import purify from 'dompurify';
66
import { sanitizeFieldRestProps } from './sanitizeFieldRestProps';
77
import { FieldProps } from './types';
88
import { genericMemo } from './genericMemo';
9+
import {
10+
ComponentsOverrides,
11+
styled,
12+
useThemeProps,
13+
} from '@mui/material/styles';
914

1015
/**
1116
* Render an HTML string as rich text
@@ -25,8 +30,13 @@ import { genericMemo } from './genericMemo';
2530
const RichTextFieldImpl = <
2631
RecordType extends Record<string, any> = Record<string, any>,
2732
>(
28-
props: RichTextFieldProps<RecordType>
33+
inProps: RichTextFieldProps<RecordType>
2934
) => {
35+
const props = useThemeProps({
36+
props: inProps,
37+
name: PREFIX,
38+
});
39+
3040
const {
3141
className,
3242
emptyText,
@@ -38,7 +48,7 @@ const RichTextFieldImpl = <
3848
const translate = useTranslate();
3949

4050
return (
41-
<Typography
51+
<StyledTypography
4252
className={className}
4353
variant="body2"
4454
component="span"
@@ -55,7 +65,7 @@ const RichTextFieldImpl = <
5565
}}
5666
/>
5767
)}
58-
</Typography>
68+
</StyledTypography>
5969
);
6070
};
6171
RichTextFieldImpl.displayName = 'RichTextFieldImpl';
@@ -80,3 +90,29 @@ export interface RichTextFieldProps<
8090

8191
export const removeTags = (input: string) =>
8292
input ? input.replace(/<[^>]+>/gm, '') : '';
93+
94+
const PREFIX = 'RaRichTextField';
95+
96+
const StyledTypography = styled(Typography, {
97+
name: PREFIX,
98+
overridesResolver: (props, styles) => styles.root,
99+
})({});
100+
101+
declare module '@mui/material/styles' {
102+
interface ComponentNameToClassKey {
103+
[PREFIX]: 'root';
104+
}
105+
106+
interface ComponentsPropsList {
107+
[PREFIX]: Partial<RichTextFieldProps>;
108+
}
109+
110+
interface Components {
111+
[PREFIX]?: {
112+
defaultProps?: ComponentsPropsList[typeof PREFIX];
113+
styleOverrides?: ComponentsOverrides<
114+
Omit<Theme, 'components'>
115+
>[typeof PREFIX];
116+
};
117+
}
118+
}

0 commit comments

Comments
 (0)