1- import { ChangeEventHandler , FC , useEffect , useState } from 'react'
1+ import { ChangeEventHandler , FC , useEffect , useRef , useState } from 'react'
22import { css } from 'styled-components/macro'
33
44import { Input } from '@/components/Input'
55import { Button } from '@/components/Button'
66import ErrorToolTip from '@/components/ErrorToolTip'
7+ import { rotate360Deg } from '@/components/animation'
78
89interface EditorProps {
910 text ?: string
1011 onSave ?: ( text : string ) => void | Promise < void >
1112 onCancel ?: ( ...arg : any ) => void
1213}
1314
15+ const Loading = ( ) => {
16+ return (
17+ < div
18+ css = { css `
19+ border-radius : 50% ;
20+ background : linear-gradient (
21+ to right,
22+ # fff 10% ,
23+ rgba (128 , 0 , 255 , 0 ) 42%
24+ );
25+ position : relative;
26+ transform : translateZ (0 );
27+ height : 16px ;
28+ width : 16px ;
29+ animation : ${ rotate360Deg } 0.2s infinite linear;
30+ & ::before {
31+ width : 50% ;
32+ height : 50% ;
33+ background : # fff ;
34+ border-radius : 100% 0 0 0 ;
35+ position : absolute;
36+ top : 0 ;
37+ left : 0 ;
38+ content : '' ;
39+ }
40+ & ::after {
41+ background-color : ${ props => props . theme . palette . button . disable } ;
42+ width : 75% ;
43+ height : 75% ;
44+ border-radius : 50% ;
45+ content : '' ;
46+ margin : auto;
47+ position : absolute;
48+ top : 0 ;
49+ left : 0 ;
50+ bottom : 0 ;
51+ right : 0 ;
52+ }
53+ ` }
54+ />
55+ )
56+ }
57+
1458const Editor : FC < EditorProps > = ( { text : initText = '' , onSave, onCancel } ) => {
1559 const [ text , setText ] = useState ( initText )
1660 const [ error , setError ] = useState ( { message : '' , show : false } )
61+ const [ loading , setLoading ] = useState ( false )
62+ // 判断当前组件是否挂载,还是已被卸载
63+ const isMount = useRef < boolean > ( )
1764
65+ useEffect ( ( ) => {
66+ isMount . current = true
67+ return ( ) => {
68+ isMount . current = false
69+ }
70+ } , [ ] )
1871 useEffect ( ( ) => {
1972 if ( error . show ) {
2073 setTimeout ( ( ) => {
@@ -28,14 +81,16 @@ const Editor: FC<EditorProps> = ({ text: initText = '', onSave, onCancel }) => {
2881 }
2982
3083 const handleSave = async ( ) => {
84+ setLoading ( true )
3185 if ( typeof onSave === 'function' ) {
3286 try {
3387 await onSave ( text )
34- // setText('')
88+ if ( isMount . current ) setText ( '' )
3589 } catch ( error : any ) {
3690 setError ( { message : error . message , show : true } )
3791 }
3892 }
93+ if ( isMount . current ) setLoading ( false )
3994 }
4095 const handleCancel = ( ) => {
4196 if ( typeof onCancel === 'function' ) {
@@ -45,7 +100,7 @@ const Editor: FC<EditorProps> = ({ text: initText = '', onSave, onCancel }) => {
45100
46101 return (
47102 < div
48- css = { css `
103+ css = { `
49104 width: 100%;
50105 ` }
51106 >
@@ -63,14 +118,14 @@ const Editor: FC<EditorProps> = ({ text: initText = '', onSave, onCancel }) => {
63118 />
64119 </ ErrorToolTip >
65120 < div
66- css = { css `
121+ css = { `
67122 display: flex;
68123 justify-content: space-around;
69124 margin-top: 6px;
70125 ` }
71126 >
72127 < Button
73- css = { css `
128+ css = { `
74129 && {
75130 height: 24px;
76131 background-color: #555;
@@ -83,8 +138,12 @@ const Editor: FC<EditorProps> = ({ text: initText = '', onSave, onCancel }) => {
83138 >
84139 取消
85140 </ Button >
86- < Button style = { { height : 24 } } disabled = { ! text } onClick = { handleSave } >
87- 保存
141+ < Button
142+ style = { { height : 24 } }
143+ disabled = { ! text || loading }
144+ onClick = { handleSave }
145+ >
146+ { loading ? < Loading /> : '保存' }
88147 </ Button >
89148 </ div >
90149 </ div >
0 commit comments