Skip to content

Commit 0d367ae

Browse files
kiner-tangMadCcc
andauthored
feat: support styles (#367)
* feat: support styles * feat: support styles * Update src/Dialog/index.tsx Co-authored-by: MadCcc <[email protected]> --------- Co-authored-by: MadCcc <[email protected]>
1 parent 194476a commit 0d367ae

File tree

6 files changed

+151
-9
lines changed

6 files changed

+151
-9
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,9 @@ ReactDOM.render(
5454
| prefixCls | String | rc-dialog | The dialog dom node's prefixCls | |
5555
| className | String | | additional className for dialog | |
5656
| classNames | { mask?: string; wrapper?: string; header?: string; body?: string; footer?: string} | | pass className to target area | |
57+
| styles | { mask?: CSSProperties; wrapper?: CSSProperties; header?: CSSProperties; body?: CSSProperties; footer?: CSSProperties} | | pass styles to target area | |
5758
| style | Object | {} | Root style for dialog element.Such as width, height | |
5859
| zIndex | Number | | | |
59-
| bodyStyle | Object | {} | body style for dialog body element.Such as height | |
60-
| maskStyle | Object | {} | style for mask element | |
6160
| visible | Boolean | false | current dialog's visible status | |
6261
| animation | String | | part of dialog animation css class name | |
6362
| maskAnimation | String | | part of dialog's mask animation css class name | |

src/Dialog/Content/Panel.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const Panel = React.forwardRef<ContentRef, PanelProps>((props, ref) => {
4343
width,
4444
height,
4545
classNames: modalClassNames,
46+
styles: modalStyles,
4647
} = props;
4748

4849
// ================================= Refs =================================
@@ -79,13 +80,13 @@ const Panel = React.forwardRef<ContentRef, PanelProps>((props, ref) => {
7980
// ================================ Render ================================
8081
let footerNode: React.ReactNode;
8182
if (footer) {
82-
footerNode = <div className={classNames(`${prefixCls}-footer`, modalClassNames?.footer)}>{footer}</div>;
83+
footerNode = <div className={classNames(`${prefixCls}-footer`, modalClassNames?.footer)} style={{...modalStyles?.footer}}>{footer}</div>;
8384
}
8485

8586
let headerNode: React.ReactNode;
8687
if (title) {
8788
headerNode = (
88-
<div className={classNames(`${prefixCls}-header`, modalClassNames?.header)}>
89+
<div className={classNames(`${prefixCls}-header`, modalClassNames?.header)} style={{...modalStyles?.header}}>
8990
<div className={`${prefixCls}-title`} id={ariaId}>
9091
{title}
9192
</div>
@@ -106,7 +107,7 @@ const Panel = React.forwardRef<ContentRef, PanelProps>((props, ref) => {
106107
<div className={`${prefixCls}-content`}>
107108
{closer}
108109
{headerNode}
109-
<div className={classNames(`${prefixCls}-body`, modalClassNames?.body)} style={bodyStyle} {...bodyProps}>
110+
<div className={classNames(`${prefixCls}-body`, modalClassNames?.body)} style={{...bodyStyle, ...modalStyles?.body}} {...bodyProps}>
110111
{children}
111112
</div>
112113
{footerNode}

src/Dialog/index.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { getMotionName } from '../util';
1010
import Content from './Content';
1111
import type { ContentRef } from './Content/Panel';
1212
import Mask from './Mask';
13+
import { warning } from 'rc-util';
1314

1415
export default function Dialog(props: IDialogPropTypes) {
1516
const {
@@ -42,8 +43,19 @@ export default function Dialog(props: IDialogPropTypes) {
4243
maskProps,
4344
rootClassName,
4445
classNames: modalClassNames,
46+
styles: modalStyles,
4547
} = props;
4648

49+
if (process.env.NODE_ENV !== 'production') {
50+
["wrapStyle", "bodyStyle", "maskStyle"].forEach((prop) => {
51+
// (prop in props) && console.error(`Warning: ${prop} is deprecated, please use styles instead.`)
52+
warning(!(prop in props), `${prop} is deprecated, please use styles instead.`)
53+
});
54+
if ("wrapClassName" in props) {
55+
warning(false, `wrapClassName is deprecated, please use classNames instead.`)
56+
}
57+
}
58+
4759
const lastOutSideActiveElementRef = useRef<HTMLElement>();
4860
const wrapperRef = useRef<HTMLDivElement>();
4961
const contentRef = useRef<ContentRef>();
@@ -168,6 +180,7 @@ export default function Dialog(props: IDialogPropTypes) {
168180
style={{
169181
zIndex,
170182
...maskStyle,
183+
...modalStyles?.mask,
171184
}}
172185
maskProps={maskProps}
173186
className={modalClassNames?.mask}
@@ -178,7 +191,7 @@ export default function Dialog(props: IDialogPropTypes) {
178191
className={classNames(`${prefixCls}-wrap`, wrapClassName, modalClassNames?.wrapper)}
179192
ref={wrapperRef}
180193
onClick={onWrapperClick}
181-
style={{ zIndex, ...wrapStyle, display: !animatedVisible ? 'none' : null }}
194+
style={{ zIndex, ...wrapStyle, ...modalStyles?.wrapper, display: !animatedVisible ? 'none' : null }}
182195
{...wrapProps}
183196
>
184197
<Content

src/IDialogPropTypes.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ export interface ModalClassNames {
99
wrapper?: string;
1010
}
1111

12+
export interface ModalStyles {
13+
header?: CSSProperties;
14+
body?: CSSProperties;
15+
footer?: CSSProperties;
16+
mask?: CSSProperties;
17+
wrapper?: CSSProperties;
18+
}
19+
1220
export type IDialogPropTypes = {
1321
className?: string;
1422
keyboard?: boolean;
@@ -44,6 +52,7 @@ export type IDialogPropTypes = {
4452
maskProps?: any;
4553
rootClassName?: string;
4654
classNames?: ModalClassNames;
55+
styles?: ModalStyles;
4756
wrapProps?: any;
4857
getContainer?: GetContainer | false;
4958
closeIcon?: ReactNode;

tests/__snapshots__/index.spec.tsx.snap

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ exports[`dialog should support classNames 1`] = `
116116
/>
117117
<div
118118
class="rc-dialog-wrap custom-wrapper"
119-
style="font-size: 10px;"
120119
tabindex="-1"
121120
>
122121
<div
@@ -171,3 +170,72 @@ exports[`dialog should support classNames 1`] = `
171170
</div>
172171
</div>
173172
`;
173+
174+
exports[`dialog should support styles 1`] = `
175+
<div
176+
class="rc-dialog-root"
177+
>
178+
<div
179+
class="rc-dialog-mask"
180+
style="background: yellow;"
181+
/>
182+
<div
183+
class="rc-dialog-wrap"
184+
style="background: pink;"
185+
tabindex="-1"
186+
>
187+
<div
188+
aria-labelledby="test-id"
189+
aria-modal="true"
190+
class="rc-dialog"
191+
role="dialog"
192+
style="width: 600px; height: 903px;"
193+
>
194+
<div
195+
aria-hidden="true"
196+
style="width: 0px; height: 0px; overflow: hidden; outline: none;"
197+
tabindex="0"
198+
/>
199+
<div
200+
class="rc-dialog-content"
201+
>
202+
<button
203+
aria-label="Close"
204+
class="rc-dialog-close"
205+
type="button"
206+
>
207+
<span
208+
class="rc-dialog-close-x"
209+
/>
210+
</button>
211+
<div
212+
class="rc-dialog-header"
213+
style="background: red;"
214+
>
215+
<div
216+
class="rc-dialog-title"
217+
id="test-id"
218+
>
219+
Default
220+
</div>
221+
</div>
222+
<div
223+
class="rc-dialog-body"
224+
style="background: green;"
225+
/>
226+
<div
227+
class="rc-dialog-footer"
228+
style="background: blue;"
229+
>
230+
Footer
231+
</div>
232+
</div>
233+
<div
234+
aria-hidden="true"
235+
style="width: 0px; height: 0px; overflow: hidden; outline: none;"
236+
tabindex="0"
237+
/>
238+
</div>
239+
</div>
240+
</div>
241+
`;

tests/index.spec.tsx

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ describe('dialog', () => {
3737
});
3838

3939
it('add rootClassName should render correct', () => {
40+
const spy = jest.spyOn(console, 'error').mockImplementation(() => {});
4041
const wrapper = mount(
4142
<Dialog
4243
visible
@@ -50,6 +51,7 @@ describe('dialog', () => {
5051
wrapper.update();
5152

5253
expect(wrapper.render()).toMatchSnapshot();
54+
expect(spy).toHaveBeenCalledWith(`Warning: wrapStyle is deprecated, please use styles instead.`);
5355
expect(wrapper.find('.customize-root-class').length).toBeTruthy();
5456
expect(wrapper.find('.rc-dialog-wrap').props().style.fontSize).toBe(10);
5557
expect(wrapper.find('.rc-dialog').props().style.height).toEqual(903);
@@ -564,18 +566,68 @@ describe('dialog', () => {
564566
}}
565567
style={{ width: 600 }}
566568
height={903}
567-
wrapStyle={{ fontSize: 10 }}
568569
/>,
569570
);
570571
jest.runAllTimers();
571572
wrapper.update();
572573

573574
expect(wrapper.render()).toMatchSnapshot();
574-
console.log(wrapper.find('.rc-dialog-wrap').html())
575575
expect(wrapper.find('.rc-dialog-wrap').props().className).toContain('custom-wrapper');
576576
expect(wrapper.find('.rc-dialog-body').props().className).toContain('custom-body');
577577
expect(wrapper.find('.rc-dialog-header').props().className).toContain('custom-header');
578578
expect(wrapper.find('.rc-dialog-footer').props().className).toContain('custom-footer');
579579
expect(wrapper.find('.rc-dialog-mask').props().className).toContain('custom-mask');
580580
});
581+
582+
it('should support styles', () => {
583+
const wrapper = mount(
584+
<Dialog
585+
visible
586+
title='Default'
587+
footer='Footer'
588+
styles={{
589+
header: { background: 'red' },
590+
body: { background: 'green' },
591+
footer: { background: 'blue' },
592+
mask: { background: 'yellow' },
593+
wrapper: { background: 'pink' },
594+
}}
595+
style={{ width: 600 }}
596+
height={903}
597+
/>,
598+
);
599+
jest.runAllTimers();
600+
wrapper.update();
601+
602+
expect(wrapper.render()).toMatchSnapshot();
603+
expect(wrapper.find('.rc-dialog-wrap').props().style.background).toBe('pink');
604+
expect(wrapper.find('.rc-dialog-body').props().style.background).toBe('green');
605+
expect(wrapper.find('.rc-dialog-header').props().style.background).toBe('red');
606+
expect(wrapper.find('.rc-dialog-footer').props().style.background).toBe('blue');
607+
expect(wrapper.find('.rc-dialog-mask').props().style.background).toBe('yellow');
608+
});
609+
it('should warning', () => {
610+
const spy = jest.spyOn(console, 'error').mockImplementation(() => {});
611+
const wrapper = mount(
612+
<Dialog
613+
visible
614+
title='Default'
615+
footer='Footer'
616+
bodyStyle={{ background: 'green' }}
617+
maskStyle={{ background: 'yellow' }}
618+
wrapClassName='custom-wrapper'
619+
style={{ width: 600 }}
620+
height={903}
621+
/>,
622+
);
623+
jest.runAllTimers();
624+
wrapper.update();
625+
626+
expect(spy).toHaveBeenCalledWith(`Warning: bodyStyle is deprecated, please use styles instead.`);
627+
expect(spy).toHaveBeenCalledWith(`Warning: maskStyle is deprecated, please use styles instead.`);
628+
expect(spy).toHaveBeenCalledWith(
629+
`Warning: wrapClassName is deprecated, please use classNames instead.`,
630+
);
631+
spy.mockRestore();
632+
});
581633
});

0 commit comments

Comments
 (0)