Skip to content

Commit

Permalink
feat: support styles (#367)
Browse files Browse the repository at this point in the history
* feat: support styles

* feat: support styles

* Update src/Dialog/index.tsx

Co-authored-by: MadCcc <1075746765@qq.com>

---------

Co-authored-by: MadCcc <1075746765@qq.com>
  • Loading branch information
kiner-tang and MadCcc committed Sep 22, 2023
1 parent 194476a commit 0d367ae
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 9 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,9 @@ ReactDOM.render(
| prefixCls | String | rc-dialog | The dialog dom node's prefixCls | |
| className | String | | additional className for dialog | |
| classNames | { mask?: string; wrapper?: string; header?: string; body?: string; footer?: string} | | pass className to target area | |
| styles | { mask?: CSSProperties; wrapper?: CSSProperties; header?: CSSProperties; body?: CSSProperties; footer?: CSSProperties} | | pass styles to target area | |
| style | Object | {} | Root style for dialog element.Such as width, height | |
| zIndex | Number | | | |
| bodyStyle | Object | {} | body style for dialog body element.Such as height | |
| maskStyle | Object | {} | style for mask element | |
| visible | Boolean | false | current dialog's visible status | |
| animation | String | | part of dialog animation css class name | |
| maskAnimation | String | | part of dialog's mask animation css class name | |
Expand Down
7 changes: 4 additions & 3 deletions src/Dialog/Content/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const Panel = React.forwardRef<ContentRef, PanelProps>((props, ref) => {
width,
height,
classNames: modalClassNames,
styles: modalStyles,
} = props;

// ================================= Refs =================================
Expand Down Expand Up @@ -79,13 +80,13 @@ const Panel = React.forwardRef<ContentRef, PanelProps>((props, ref) => {
// ================================ Render ================================
let footerNode: React.ReactNode;
if (footer) {
footerNode = <div className={classNames(`${prefixCls}-footer`, modalClassNames?.footer)}>{footer}</div>;
footerNode = <div className={classNames(`${prefixCls}-footer`, modalClassNames?.footer)} style={{...modalStyles?.footer}}>{footer}</div>;
}

let headerNode: React.ReactNode;
if (title) {
headerNode = (
<div className={classNames(`${prefixCls}-header`, modalClassNames?.header)}>
<div className={classNames(`${prefixCls}-header`, modalClassNames?.header)} style={{...modalStyles?.header}}>
<div className={`${prefixCls}-title`} id={ariaId}>
{title}
</div>
Expand All @@ -106,7 +107,7 @@ const Panel = React.forwardRef<ContentRef, PanelProps>((props, ref) => {
<div className={`${prefixCls}-content`}>
{closer}
{headerNode}
<div className={classNames(`${prefixCls}-body`, modalClassNames?.body)} style={bodyStyle} {...bodyProps}>
<div className={classNames(`${prefixCls}-body`, modalClassNames?.body)} style={{...bodyStyle, ...modalStyles?.body}} {...bodyProps}>
{children}
</div>
{footerNode}
Expand Down
15 changes: 14 additions & 1 deletion src/Dialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { getMotionName } from '../util';
import Content from './Content';
import type { ContentRef } from './Content/Panel';
import Mask from './Mask';
import { warning } from 'rc-util';

This comment has been minimized.

Copy link
@afc163

afc163 Oct 20, 2023

Member

export default function Dialog(props: IDialogPropTypes) {
const {
Expand Down Expand Up @@ -42,8 +43,19 @@ export default function Dialog(props: IDialogPropTypes) {
maskProps,
rootClassName,
classNames: modalClassNames,
styles: modalStyles,
} = props;

if (process.env.NODE_ENV !== 'production') {
["wrapStyle", "bodyStyle", "maskStyle"].forEach((prop) => {
// (prop in props) && console.error(`Warning: ${prop} is deprecated, please use styles instead.`)
warning(!(prop in props), `${prop} is deprecated, please use styles instead.`)
});
if ("wrapClassName" in props) {
warning(false, `wrapClassName is deprecated, please use classNames instead.`)
}
}

const lastOutSideActiveElementRef = useRef<HTMLElement>();
const wrapperRef = useRef<HTMLDivElement>();
const contentRef = useRef<ContentRef>();
Expand Down Expand Up @@ -168,6 +180,7 @@ export default function Dialog(props: IDialogPropTypes) {
style={{
zIndex,
...maskStyle,
...modalStyles?.mask,
}}
maskProps={maskProps}
className={modalClassNames?.mask}
Expand All @@ -178,7 +191,7 @@ export default function Dialog(props: IDialogPropTypes) {
className={classNames(`${prefixCls}-wrap`, wrapClassName, modalClassNames?.wrapper)}
ref={wrapperRef}
onClick={onWrapperClick}
style={{ zIndex, ...wrapStyle, display: !animatedVisible ? 'none' : null }}
style={{ zIndex, ...wrapStyle, ...modalStyles?.wrapper, display: !animatedVisible ? 'none' : null }}
{...wrapProps}
>
<Content
Expand Down
9 changes: 9 additions & 0 deletions src/IDialogPropTypes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ export interface ModalClassNames {
wrapper?: string;
}

export interface ModalStyles {
header?: CSSProperties;
body?: CSSProperties;
footer?: CSSProperties;
mask?: CSSProperties;
wrapper?: CSSProperties;
}

export type IDialogPropTypes = {
className?: string;
keyboard?: boolean;
Expand Down Expand Up @@ -44,6 +52,7 @@ export type IDialogPropTypes = {
maskProps?: any;
rootClassName?: string;
classNames?: ModalClassNames;
styles?: ModalStyles;
wrapProps?: any;
getContainer?: GetContainer | false;
closeIcon?: ReactNode;
Expand Down
70 changes: 69 additions & 1 deletion tests/__snapshots__/index.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ exports[`dialog should support classNames 1`] = `
/>
<div
class="rc-dialog-wrap custom-wrapper"
style="font-size: 10px;"
tabindex="-1"
>
<div
Expand Down Expand Up @@ -171,3 +170,72 @@ exports[`dialog should support classNames 1`] = `
</div>
</div>
`;

exports[`dialog should support styles 1`] = `
<div
class="rc-dialog-root"
>
<div
class="rc-dialog-mask"
style="background: yellow;"
/>
<div
class="rc-dialog-wrap"
style="background: pink;"
tabindex="-1"
>
<div
aria-labelledby="test-id"
aria-modal="true"
class="rc-dialog"
role="dialog"
style="width: 600px; height: 903px;"
>
<div
aria-hidden="true"
style="width: 0px; height: 0px; overflow: hidden; outline: none;"
tabindex="0"
/>
<div
class="rc-dialog-content"
>
<button
aria-label="Close"
class="rc-dialog-close"
type="button"
>
<span
class="rc-dialog-close-x"
/>
</button>
<div
class="rc-dialog-header"
style="background: red;"
>
<div
class="rc-dialog-title"
id="test-id"
>
Default
</div>
</div>
<div
class="rc-dialog-body"
style="background: green;"
/>
<div
class="rc-dialog-footer"
style="background: blue;"
>
Footer
</div>
</div>
<div
aria-hidden="true"
style="width: 0px; height: 0px; overflow: hidden; outline: none;"
tabindex="0"
/>
</div>
</div>
</div>
`;
56 changes: 54 additions & 2 deletions tests/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ describe('dialog', () => {
});

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

expect(wrapper.render()).toMatchSnapshot();
expect(spy).toHaveBeenCalledWith(`Warning: wrapStyle is deprecated, please use styles instead.`);
expect(wrapper.find('.customize-root-class').length).toBeTruthy();
expect(wrapper.find('.rc-dialog-wrap').props().style.fontSize).toBe(10);
expect(wrapper.find('.rc-dialog').props().style.height).toEqual(903);
Expand Down Expand Up @@ -564,18 +566,68 @@ describe('dialog', () => {
}}
style={{ width: 600 }}
height={903}
wrapStyle={{ fontSize: 10 }}
/>,
);
jest.runAllTimers();
wrapper.update();

expect(wrapper.render()).toMatchSnapshot();
console.log(wrapper.find('.rc-dialog-wrap').html())
expect(wrapper.find('.rc-dialog-wrap').props().className).toContain('custom-wrapper');
expect(wrapper.find('.rc-dialog-body').props().className).toContain('custom-body');
expect(wrapper.find('.rc-dialog-header').props().className).toContain('custom-header');
expect(wrapper.find('.rc-dialog-footer').props().className).toContain('custom-footer');
expect(wrapper.find('.rc-dialog-mask').props().className).toContain('custom-mask');
});

it('should support styles', () => {
const wrapper = mount(
<Dialog
visible
title='Default'
footer='Footer'
styles={{
header: { background: 'red' },
body: { background: 'green' },
footer: { background: 'blue' },
mask: { background: 'yellow' },
wrapper: { background: 'pink' },
}}
style={{ width: 600 }}
height={903}
/>,
);
jest.runAllTimers();
wrapper.update();

expect(wrapper.render()).toMatchSnapshot();
expect(wrapper.find('.rc-dialog-wrap').props().style.background).toBe('pink');
expect(wrapper.find('.rc-dialog-body').props().style.background).toBe('green');
expect(wrapper.find('.rc-dialog-header').props().style.background).toBe('red');
expect(wrapper.find('.rc-dialog-footer').props().style.background).toBe('blue');
expect(wrapper.find('.rc-dialog-mask').props().style.background).toBe('yellow');
});
it('should warning', () => {
const spy = jest.spyOn(console, 'error').mockImplementation(() => {});
const wrapper = mount(
<Dialog
visible
title='Default'
footer='Footer'
bodyStyle={{ background: 'green' }}
maskStyle={{ background: 'yellow' }}
wrapClassName='custom-wrapper'
style={{ width: 600 }}
height={903}
/>,
);
jest.runAllTimers();
wrapper.update();

expect(spy).toHaveBeenCalledWith(`Warning: bodyStyle is deprecated, please use styles instead.`);
expect(spy).toHaveBeenCalledWith(`Warning: maskStyle is deprecated, please use styles instead.`);
expect(spy).toHaveBeenCalledWith(
`Warning: wrapClassName is deprecated, please use classNames instead.`,
);
spy.mockRestore();
});
});

0 comments on commit 0d367ae

Please sign in to comment.