@@ -5,6 +5,8 @@ interface InlineEditState {
5
5
view : { }
6
6
edit : { }
7
7
loading : { }
8
+ saved : { }
9
+ error : { }
8
10
}
9
11
}
10
12
@@ -15,22 +17,25 @@ type InlineEditEvent =
15
17
| { type : 'ESC' ; value : string }
16
18
| { type : 'ENTER' ; value : string }
17
19
| { type : 'BLUR' ; value : string }
20
+ | { type : 'SAVED' ; value : string }
18
21
19
22
interface InlineEditContext {
20
23
value : string
21
24
newValue : string
22
- isDisabled : boolean
23
- allowEditWhileLoading : boolean
25
+ oldValue : string
24
26
isValid : boolean
25
27
}
26
28
27
29
interface InlineEditMachineProps {
28
30
value : string
31
+ onChange : ( value : string ) => void
29
32
isDisabled : boolean
30
33
allowEditWhileLoading : boolean
31
34
optimisticUpdate : boolean
32
35
validate ?: ( value : string ) => boolean
33
- onChange : ( value : string ) => Promise < any >
36
+ saveTimeout : number
37
+ savedDuration : number
38
+ errorDuration : number
34
39
}
35
40
36
41
const getInlineEditMachine = ( {
@@ -40,6 +45,9 @@ const getInlineEditMachine = ({
40
45
optimisticUpdate,
41
46
validate,
42
47
onChange,
48
+ saveTimeout,
49
+ savedDuration,
50
+ errorDuration
43
51
} : InlineEditMachineProps ) =>
44
52
Machine < InlineEditContext , InlineEditState , InlineEditEvent > (
45
53
{
@@ -48,8 +56,7 @@ const getInlineEditMachine = ({
48
56
context : {
49
57
value,
50
58
newValue : '' ,
51
- isDisabled,
52
- allowEditWhileLoading,
59
+ oldValue : '' ,
53
60
isValid :
54
61
validate && typeof validate === 'function' ? validate ( value ) : true ,
55
62
} ,
@@ -59,6 +66,7 @@ const getInlineEditMachine = ({
59
66
on : {
60
67
CLICK : { target : 'edit' , cond : 'isEnabled' } ,
61
68
FOCUS : { target : 'edit' , cond : 'isEnabled' } ,
69
+ SAVED : { target : 'saved' , actions : 'commitChange' }
62
70
} ,
63
71
} ,
64
72
edit : {
@@ -67,27 +75,46 @@ const getInlineEditMachine = ({
67
75
CHANGE : { target : 'edit' , actions : 'change' } ,
68
76
ESC : 'view' ,
69
77
ENTER : [
70
- { target : 'loading' , cond : 'shouldCommit ' } ,
78
+ { target : 'loading' , cond : 'shouldSend ' } ,
71
79
{ target : 'view' } ,
72
80
] ,
73
81
BLUR : [
74
- { target : 'loading' , cond : 'shouldCommit ' } ,
82
+ { target : 'loading' , cond : 'shouldSend ' } ,
75
83
{ target : 'view' } ,
76
84
] ,
77
85
} ,
78
86
} ,
79
87
loading : {
80
- invoke : {
81
- id : 'commitChange' ,
82
- src : 'commitChange' ,
83
- onDone : { target : 'view' , actions : optimisticUpdate ? 'optimisticUpdate' : '' } ,
84
- onError : { target : 'view' } ,
85
- } ,
88
+ entry : [ optimisticUpdate ? 'optimisticUpdate' : 'noAction' , 'sendChange' ] ,
86
89
on : {
87
90
CLICK : { target : 'edit' , cond : 'canEditWhileLoading' } ,
88
91
FOCUS : { target : 'edit' , cond : 'canEditWhileLoading' } ,
92
+ SAVED : { target : 'saved' , actions : 'commitChange' }
89
93
} ,
94
+ after : {
95
+ SAVE_TIMEOUT : { target : 'error' , actions : 'cancelChange' }
96
+ }
90
97
} ,
98
+ saved : {
99
+ on : {
100
+ CLICK : { target : 'edit' , cond : 'isEnabled' } ,
101
+ FOCUS : { target : 'edit' , cond : 'isEnabled' } ,
102
+ SAVED : { target : 'saved' , actions : 'commitChange' }
103
+ } ,
104
+ after : {
105
+ SAVED_DURATION : { target : 'view' }
106
+ }
107
+ } ,
108
+ error : {
109
+ on : {
110
+ CLICK : { target : 'edit' , cond : 'isEnabled' } ,
111
+ FOCUS : { target : 'edit' , cond : 'isEnabled' } ,
112
+ SAVED : { target : 'saved' , actions : 'commitChange' }
113
+ } ,
114
+ after : {
115
+ ERROR_DURATION : { target : 'view' }
116
+ }
117
+ }
91
118
} ,
92
119
} ,
93
120
{
@@ -99,8 +126,19 @@ const getInlineEditMachine = ({
99
126
newValue : context => context . value ,
100
127
} ) ,
101
128
optimisticUpdate : assign ( {
129
+ oldValue : context => context . value ,
102
130
value : context => context . newValue ,
103
131
} ) ,
132
+ noAction : ( ) => { } ,
133
+ sendChange : ( context : InlineEditContext ) => {
134
+ onChange ( context . newValue )
135
+ } ,
136
+ commitChange : assign ( {
137
+ value : ( _ , event ) => event . value ,
138
+ } ) ,
139
+ cancelChange : assign ( {
140
+ value : context => context . oldValue ,
141
+ } ) ,
104
142
validate :
105
143
validate && typeof validate === 'function'
106
144
? assign ( {
@@ -109,17 +147,17 @@ const getInlineEditMachine = ({
109
147
: ( ) => { } ,
110
148
} ,
111
149
guards : {
112
- shouldCommit : context =>
150
+ shouldSend : context =>
113
151
context . isValid && context . newValue !== context . value ,
114
- isEnabled : context => ! context . isDisabled ,
115
- canEditWhileLoading : context =>
116
- ! context . isDisabled && context . allowEditWhileLoading ,
117
- } ,
118
- services : {
119
- commitChange : context => {
120
- return onChange ( context . newValue )
121
- } ,
152
+ isEnabled : ( ) => ! isDisabled ,
153
+ canEditWhileLoading : ( ) =>
154
+ ! isDisabled && allowEditWhileLoading ,
122
155
} ,
156
+ delays : {
157
+ SAVE_TIMEOUT : saveTimeout ,
158
+ SAVED_DURATION : savedDuration ,
159
+ ERROR_DURATION : errorDuration
160
+ }
123
161
}
124
162
)
125
163
0 commit comments