@@ -18,41 +18,107 @@ export function ElementButton(
1818 const clientContext = useContentKitClientContext ( ) ;
1919
2020 const [ loading , setLoading ] = React . useState ( false ) ;
21+ const [ confirm , setConfirm ] = React . useState < boolean > ( false ) ;
2122
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+ } , [ ] ) ;
2431
2532 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 >
57123 ) ;
58124}
0 commit comments