@@ -18,41 +18,107 @@ export function ElementButton(
18
18
const clientContext = useContentKitClientContext ( ) ;
19
19
20
20
const [ loading , setLoading ] = React . useState ( false ) ;
21
+ const [ confirm , setConfirm ] = React . useState < boolean > ( false ) ;
21
22
22
- // TODO:
23
- // - confirm dialog
23
+ const wrapLoading = React . useCallback ( async < T , > ( fn : Promise < T > | ( ( ) => Promise < T > ) ) => {
24
+ setLoading ( true ) ;
25
+ try {
26
+ return fn instanceof Promise ? await fn : await fn ( ) ;
27
+ } finally {
28
+ setLoading ( false ) ;
29
+ }
30
+ } , [ ] ) ;
24
31
25
32
return (
26
- < button
27
- title = { element . tooltip }
28
- className = { classNames (
29
- 'contentkit-button' ,
30
- `contentkit-button-style-${ element . style ?? 'secondary' } `
31
- ) }
32
- onClick = { ( event ) => {
33
- if ( element . disabled || loading ) {
34
- return ;
35
- }
36
-
37
- event . stopPropagation ( ) ;
38
-
39
- setLoading ( true ) ;
40
- clientContext . dispatchAction ( element . onPress ) . finally ( ( ) => {
41
- setLoading ( false ) ;
42
- } ) ;
43
- } }
44
- >
45
- { loading ? (
46
- < Icon icon = "spinner" className = "contentkit-button-loading" />
47
- ) : (
48
- < >
49
- { icon }
50
- { element . label ? (
51
- < span className = "contentkit-button-label" > { element . label } </ span >
52
- ) : null }
53
- { trailingIcon }
54
- </ >
55
- ) }
56
- </ button >
33
+ < >
34
+ < button
35
+ type = "button"
36
+ title = { element . tooltip }
37
+ className = { classNames (
38
+ 'contentkit-button' ,
39
+ `contentkit-button-style-${ element . style ?? 'secondary' } `
40
+ ) }
41
+ onClick = { ( event ) => {
42
+ if ( element . disabled || loading ) {
43
+ return ;
44
+ }
45
+
46
+ event . stopPropagation ( ) ;
47
+ event . preventDefault ( ) ;
48
+
49
+ if ( element . confirm && ! confirm ) {
50
+ setConfirm ( true ) ;
51
+ return ;
52
+ }
53
+
54
+ wrapLoading ( async ( ) => await clientContext . dispatchAction ( element . onPress ) ) ;
55
+ } }
56
+ >
57
+ { loading ? (
58
+ < Icon icon = "spinner" className = "contentkit-button-loading" />
59
+ ) : (
60
+ < >
61
+ { icon }
62
+ { element . label ? (
63
+ < span className = "contentkit-button-label" > { element . label } </ span >
64
+ ) : null }
65
+ { trailingIcon }
66
+ </ >
67
+ ) }
68
+ </ button >
69
+ { element . confirm && confirm ? (
70
+ < ConfirmDialog
71
+ open = { confirm }
72
+ { ...element . confirm }
73
+ onConfirm = { ( ) => {
74
+ setConfirm ( false ) ;
75
+ wrapLoading (
76
+ async ( ) => await clientContext . dispatchAction ( element . onPress )
77
+ ) ;
78
+ } }
79
+ onCancel = { ( ) => setConfirm ( false ) }
80
+ />
81
+ ) : null }
82
+ </ >
83
+ ) ;
84
+ }
85
+
86
+ function ConfirmDialog ( { open, onCancel, onConfirm, style, title, text, confirm } : any ) {
87
+ return (
88
+ < div className = "contentkit-modal-backdrop" onClick = { onCancel } >
89
+ < div
90
+ className = { classNames (
91
+ 'contentkit-modal contentkit-modal-confirm' ,
92
+ open ? 'contentkit-modal-opened' : null
93
+ ) }
94
+ onClick = { ( event ) => {
95
+ event . stopPropagation ( ) ;
96
+ } }
97
+ >
98
+ < div className = "contentkit-modal-header" >
99
+ { title ? < h1 className = "contentkit-modal-title" > { title } </ h1 > : null }
100
+ { text ? < div className = "contentkit-modal-subtitle" > { text } </ div > : null }
101
+ </ div >
102
+ < div className = "contentkit-modal-footer" >
103
+ < button
104
+ type = "button"
105
+ className = "contentkit-button contentkit-button-confirm contentkit-button-style-secondary"
106
+ onClick = { onCancel }
107
+ >
108
+ Cancel
109
+ </ button >
110
+ < button
111
+ type = "button"
112
+ className = { classNames (
113
+ 'contentkit-button contentkit-button-confirm' ,
114
+ `contentkit-button-style-${ style ?? 'primary' } `
115
+ ) }
116
+ onClick = { onConfirm }
117
+ >
118
+ { confirm ?? 'OK' }
119
+ </ button >
120
+ </ div >
121
+ </ div >
122
+ </ div >
57
123
) ;
58
124
}
0 commit comments