Skip to content

Commit 0366cb5

Browse files
authored
refactor(react-message): 重构message组件 (#880#845)
1 parent e6a8a8f commit 0366cb5

File tree

2 files changed

+216
-7
lines changed

2 files changed

+216
-7
lines changed

packages/react-message/src/index.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react';
22
import { CSSTransition } from 'react-transition-group';
33
import Icon, { IconProps } from '@uiw/react-icon';
4-
import Button from '@uiw/react-button';
5-
import './style/index.less';
4+
// import './style/index.less';
65
import { IProps, HTMLDivProps } from '@uiw/utils';
76

7+
import { MessageDivWrap, MessageTitleSpan, MessageDescriptionSpan, MessageButtonWarp } from './style';
88
export interface MessageProps extends IProps, Omit<HTMLDivProps, 'title'> {
99
title?: React.ReactNode;
1010
icon?: IconProps['type'];
@@ -85,13 +85,20 @@ export default class Message extends React.Component<MessageProps, IMessageState
8585
.filter(Boolean)
8686
.join(' ')
8787
.trim();
88+
8889
const Child = (
89-
<div className={cls} {...elementProps}>
90-
{isCloseButtonShown && <Button basic onClick={this.handleClosed} icon="close" type="light" />}
90+
<MessageDivWrap params={{ rounded, type, title, children, showIcon, icon }} className={cls} {...elementProps}>
91+
{isCloseButtonShown && (
92+
<MessageButtonWarp basic onClick={this.handleClosed} icon={<Icon type="close" />} type="light" />
93+
)}
9194
{showIcon && <Icon type={this.renderIcon()} />}
92-
<span className={`${prefixCls}-title`}>{title}</span>
93-
<span className={`${prefixCls}-description`}>{children}</span>
94-
</div>
95+
<MessageTitleSpan params={{ showIcon, title, children }} className={`${prefixCls}-title`}>
96+
{title}
97+
</MessageTitleSpan>
98+
<MessageDescriptionSpan params={{ showIcon, title, children }} className={`${prefixCls}-description`}>
99+
{children}
100+
</MessageDescriptionSpan>
101+
</MessageDivWrap>
95102
);
96103
if (!isCloseButtonShown) {
97104
return Child;
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
import styled, { css } from 'styled-components';
2+
import { IconBase, IconBaseProps } from '@uiw/react-icon';
3+
import { getThemeVariantValue, ThemeVariantValueOptions } from '@uiw/utils';
4+
import Button, { ButtonProps } from '@uiw/react-button';
5+
6+
interface divWrapProps
7+
extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>,
8+
ThemeVariantValueOptions {
9+
params: {
10+
rounded: boolean | undefined;
11+
type: 'success' | 'warning' | 'info' | 'error' | undefined;
12+
children: any;
13+
showIcon: boolean | undefined;
14+
icon: any;
15+
title: React.ReactNode;
16+
};
17+
}
18+
19+
export const MessageWrap = styled.div`
20+
padding: 10px 15px;
21+
position: relative;
22+
font-size: 14px;
23+
`;
24+
// 最外层div
25+
export const MessageDivWrap = styled(MessageWrap)<divWrapProps>`
26+
margin-top: 10px;
27+
${(props) => {
28+
if (props.params?.showIcon) {
29+
if (props.params?.children && props.params?.title) {
30+
return css`
31+
> .w-icon {
32+
font-size: 24px;
33+
}
34+
`;
35+
}
36+
if (props.params?.children) {
37+
return css`
38+
display: block;
39+
color: rgba(0, 0, 0, 0.65);
40+
`;
41+
}
42+
if (props.params?.title) {
43+
return css`
44+
display: block;
45+
color: rgba(0, 0, 0, 0.85);
46+
`;
47+
}
48+
}
49+
}}
50+
${(props) =>
51+
props.params?.rounded &&
52+
css`
53+
border-radius: 5px;
54+
`}
55+
56+
${(props) =>
57+
props.params?.showIcon &&
58+
css`
59+
padding-left: 34px;
60+
`}
61+
62+
${(props) => {
63+
//
64+
switch (props.params.type) {
65+
case 'success':
66+
return css`
67+
background: ${getThemeVariantValue(props, 'backgroundMessageSuccess')};
68+
color: ${getThemeVariantValue(props, 'colorMessageSuccess')};
69+
`;
70+
case 'warning':
71+
return css`
72+
background: ${getThemeVariantValue(props, 'backgroundMessageWarning')};
73+
color: ${getThemeVariantValue(props, 'colorMessageWarning')};
74+
`;
75+
case 'info':
76+
return css`
77+
background: ${getThemeVariantValue(props, 'backgroundMessageInfo')};
78+
color: ${getThemeVariantValue(props, 'colorMessageInfo')};
79+
`;
80+
case 'error':
81+
return css`
82+
background: ${getThemeVariantValue(props, 'backgroundMessageError')};
83+
color: ${getThemeVariantValue(props, 'colorMessageError')};
84+
`;
85+
default:
86+
return css``;
87+
}
88+
}}
89+
> .w-icon {
90+
top: 14px;
91+
left: 14px;
92+
position: absolute;
93+
}
94+
/* CSSTransition */
95+
&.w-message-enter {
96+
transform: scaleY(0.5);
97+
opacity: 0;
98+
}
99+
&.w-message-enter-active {
100+
opacity: 1;
101+
transform: scaleY(1);
102+
transition: transform 300ms ease, opacity 300ms ease;
103+
}
104+
&.w-message-exit {
105+
opacity: 1;
106+
transform: scaleY(1);
107+
transition: transform 300ms ease, opacity 300ms ease;
108+
}
109+
&.w-message-exit-active {
110+
transform: scaleY(0.5);
111+
opacity: 0;
112+
}
113+
`;
114+
115+
interface spanPeops extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> {
116+
params: {
117+
children: React.ReactNode;
118+
showIcon: boolean | undefined;
119+
title: React.ReactNode;
120+
};
121+
}
122+
// 原始span
123+
export const MessageSpanWrap = styled.span`
124+
display: block;
125+
`;
126+
// 详情description
127+
export const MessageDescriptionSpan = styled(MessageSpanWrap)<spanPeops>`
128+
color: rgba(0, 0, 0, 0.65);
129+
${(props) =>
130+
props.params.showIcon &&
131+
props.params.title &&
132+
props.params.children &&
133+
css`
134+
padding-left: 16px;
135+
`}
136+
`;
137+
// 标题title
138+
export const MessageTitleSpan = styled(MessageDescriptionSpan)<spanPeops>`
139+
color: rgba(0, 0, 0, 0.85);
140+
${(props) =>
141+
props.params.showIcon &&
142+
props.params.title &&
143+
props.params.children &&
144+
css`
145+
font-size: 16px;
146+
`}
147+
`;
148+
149+
interface MessageIconWarpProps extends IconBaseProps, ThemeVariantValueOptions {
150+
params: {
151+
children: React.ReactNode;
152+
showIcon: boolean | undefined;
153+
title: React.ReactNode;
154+
};
155+
}
156+
// icon
157+
export const MessageIconWarp = styled.span<MessageIconWarpProps>`
158+
${(props) =>
159+
props.params?.showIcon &&
160+
props.params.title &&
161+
props.params.children &&
162+
css`
163+
font-size: 24px;
164+
`}
165+
top: 14px;
166+
left: 14px;
167+
position: absolute;
168+
`;
169+
170+
interface messageButtonProps extends ButtonProps {}
171+
172+
export const MessageButtonWarp = styled(Button)<messageButtonProps>`
173+
position: absolute;
174+
right: 10px;
175+
top: 10px;
176+
padding: 2px;
177+
min-width: 16px;
178+
min-height: 16px;
179+
color: rgba(0, 0, 0, 0.38);
180+
&:hover {
181+
background-color: rgba(255, 255, 255, 0.21) !important;
182+
}
183+
&:active {
184+
background-color: rgba(0, 0, 0, 0.1) !important;
185+
}
186+
`;
187+
188+
MessageDivWrap.defaultProps = {
189+
defaultTheme: {
190+
backgroundMessageSuccess: '#afecbd',
191+
colorMessageSuccess: '#28a745',
192+
193+
backgroundMessageWarning: '#fff4d3',
194+
colorMessageWarning: '#ffc107',
195+
196+
backgroundMessageInfo: '#bde4ff',
197+
colorMessageInfo: '#008ef0',
198+
199+
backgroundMessageError: '#fae3e5',
200+
colorMessageError: '#dc3545',
201+
},
202+
};

0 commit comments

Comments
 (0)